snort-2.9.15.1/0000755000000000000000000000000013571426536010077 500000000000000snort-2.9.15.1/Makefile.in0000644000000000000000000007246713571425502012074 00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 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@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd 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 = . DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/configure $(am__configure_deps) \ $(srcdir)/config.h.in $(srcdir)/snort.pc.in COPYING ChangeLog \ config.guess config.sub install-sh missing ltmain.sh ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = snort.pc CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = depcomp = am__depfiles_maybe = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man8dir = $(mandir)/man8 am__installdirs = "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(pkgconfigdir)" NROFF = nroff MANS = $(man_MANS) DATA = $(pkgconfig_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope distdir dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ $(LISP)config.h.in # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags CSCOPE = cscope DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CCONFIGFLAGS = @CCONFIGFLAGS@ CFLAGS = @CFLAGS@ CONFIGFLAGS = @CONFIGFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ ICONFIGFLAGS = @ICONFIGFLAGS@ INCLUDES = @INCLUDES@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LUA_CFLAGS = @LUA_CFLAGS@ LUA_LIBS = @LUA_LIBS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIGNAL_SNORT_DUMP_STATS = @SIGNAL_SNORT_DUMP_STATS@ SIGNAL_SNORT_READ_ATTR_TBL = @SIGNAL_SNORT_READ_ATTR_TBL@ SIGNAL_SNORT_RELOAD = @SIGNAL_SNORT_RELOAD@ SIGNAL_SNORT_ROTATE_STATS = @SIGNAL_SNORT_ROTATE_STATS@ STRIP = @STRIP@ VERSION = @VERSION@ XCCFLAGS = @XCCFLAGS@ YACC = @YACC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ 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@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luajit_CFLAGS = @luajit_CFLAGS@ luajit_LIBS = @luajit_LIBS@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign no-dependencies SUBDIRS = src doc etc templates rpm m4 preproc_rules tools EXTRA_DIST = ChangeLog snort.8 LICENSE verstuff.pl RELEASE.NOTES snort.pc.in VERSION man_MANS = snort.8 DISTCLEANFILES = stamp-h.in cflags.out cppflags.out pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = snort.pc all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am--refresh: Makefile @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): config.h: stamp-h1 @if test ! -f $@; then rm -f stamp-h1; else :; fi @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 snort.pc: $(top_builddir)/config.status $(srcdir)/snort.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool config.lt install-man8: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man8dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.8[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \ done; } uninstall-man8: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man8dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.8[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir) install-pkgconfigDATA: $(pkgconfig_DATA) @$(NORMAL_INSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ done uninstall-pkgconfigDATA: @$(NORMAL_UNINSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile $(MANS) $(DATA) config.h installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(pkgconfigdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) 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-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr \ distclean-libtool distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-man install-pkgconfigDATA install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-man8 install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-man uninstall-pkgconfigDATA uninstall-man: uninstall-man8 .MAKE: $(am__recursive_targets) all install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--refresh check check-am clean clean-cscope clean-generic \ clean-libtool cscope cscopelist-am ctags ctags-am dist \ dist-all dist-bzip2 dist-gzip dist-hook dist-lzip dist-shar \ dist-tarZ dist-xz dist-zip distcheck distclean \ distclean-generic distclean-hdr distclean-libtool \ distclean-tags distcleancheck distdir distuninstallcheck dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-man8 \ install-pdf install-pdf-am install-pkgconfigDATA install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-man uninstall-man8 \ uninstall-pkgconfigDATA dist-hook: # always ensure that the win32 build is in sync perl $(distdir)/verstuff.pl $(distdir) # work around a horrible doc/Makefile.am rm -rf $(distdir)/doc/signatures/CVS # 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: snort-2.9.15.1/Makefile.am0000444000175200017520000000102113571422606012073 00000000000000## $Id$ AUTOMAKE_OPTIONS=foreign no-dependencies SUBDIRS = src doc etc templates rpm m4 preproc_rules tools INCLUDES = @INCLUDES@ EXTRA_DIST = ChangeLog snort.8 LICENSE verstuff.pl RELEASE.NOTES snort.pc.in VERSION man_MANS = snort.8 DISTCLEANFILES=stamp-h.in cflags.out cppflags.out dist-hook: # always ensure that the win32 build is in sync perl $(distdir)/verstuff.pl $(distdir) # work around a horrible doc/Makefile.am rm -rf $(distdir)/doc/signatures/CVS pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = snort.pc snort-2.9.15.1/configure0000755000000000000000000220045213571425507011730 00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for snort 2.9.15.1. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" SHELL=${CONFIG_SHELL-/bin/sh} test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='snort' PACKAGE_TARNAME='snort' PACKAGE_VERSION='2.9.15.1' PACKAGE_STRING='snort 2.9.15.1' PACKAGE_BUGREPORT='' PACKAGE_URL='' ac_unique_file="src/snort.c" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS ICONFIGFLAGS CCONFIGFLAGS CONFIGFLAGS INCLUDES LUA_LIBS LUA_CFLAGS luajit_LIBS luajit_CFLAGS PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG FEAT_OPEN_APPID_FALSE FEAT_OPEN_APPID_TRUE FEAT_FILE_INSPECT_FALSE FEAT_FILE_INSPECT_TRUE HAVE_SHARED_REP_FALSE HAVE_SHARED_REP_TRUE HAVE_INTEL_SOFT_CPM_FALSE HAVE_INTEL_SOFT_CPM_TRUE BUILD_RESPOND3_FALSE BUILD_RESPOND3_TRUE BUILD_REACT_FALSE BUILD_REACT_TRUE BUILD_BUFFER_DUMP_FALSE BUILD_BUFFER_DUMP_TRUE BUILD_HA_FALSE BUILD_HA_TRUE BUILD_SNORT_RELOAD_FALSE BUILD_SNORT_RELOAD_TRUE BUILD_PROCPIDSTATS_FALSE BUILD_PROCPIDSTATS_TRUE HAVE_TARGET_BASED_FALSE HAVE_TARGET_BASED_TRUE HAVE_LZMA_FALSE HAVE_LZMA_TRUE BUILD_DYNAMIC_EXAMPLES_FALSE BUILD_DYNAMIC_EXAMPLES_TRUE BUILD_SIDE_CHANNEL_FALSE BUILD_SIDE_CHANNEL_TRUE BUILD_CONTROL_SOCKET_FALSE BUILD_CONTROL_SOCKET_TRUE SO_WITH_STATIC_LIB_FALSE SO_WITH_STATIC_LIB_TRUE SIGNAL_SNORT_READ_ATTR_TBL SIGNAL_SNORT_ROTATE_STATS SIGNAL_SNORT_DUMP_STATS SIGNAL_SNORT_RELOAD BUILD_OPENSSL_SHA_FALSE BUILD_OPENSSL_SHA_TRUE BUILD_OPENSSL_MD5_FALSE BUILD_OPENSSL_MD5_TRUE BUILD_SNPRINTF_FALSE BUILD_SNPRINTF_TRUE LEX YACC XCCFLAGS extra_incl CPP OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB ac_ct_AR AR DLLTOOL OBJDUMP LN_S NM ac_ct_DUMPBIN DUMPBIN LD FGREP EGREP GREP SED host_os host_vendor host_cpu host build_os build_vendor build_cpu build LIBTOOL am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_silent_rules enable_dependency_tracking enable_shared enable_static with_pic enable_fast_install with_gnu_ld with_sysroot enable_libtool_lock enable_64bit_gcc with_libpcap_includes with_libpcap_libraries with_libpfring_includes with_libpfring_libraries with_daq_includes with_daq_libraries with_libpcre_includes with_libpcre_libraries with_openssl_includes with_openssl_libraries enable_so_with_static_lib enable_control_socket enable_side_channel with_dnet_includes with_dnet_libraries enable_static_daq enable_build_dynamic_examples enable_dlclose enable_lzma with_lzma_includes with_lzma_libraries enable_gre enable_mpls enable_targetbased enable_ppm enable_perfprofiling enable_linux_smp_stats enable_inline_init_failopen enable_pthread enable_debug_msgs enable_debug enable_gdb enable_profile enable_test_coverage enable_ppm_test enable_sourcefire enable_corefiles enable_active_response enable_normalizer enable_reload enable_reload_error_restart enable_ha enable_buffer_dump enable_non_ether_decoders enable_react enable_flexresp3 enable_intel_soft_cpm with_intel_soft_cpm_includes with_intel_soft_cpm_libraries enable_shared_rep enable_large_pcap enable_file_inspect enable_open_appid with_libnghttp2_includes with_libnghttp2_libraries ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP SIGNAL_SNORT_RELOAD SIGNAL_SNORT_DUMP_STATS SIGNAL_SNORT_ROTATE_STATS SIGNAL_SNORT_READ_ATTR_TBL PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR luajit_CFLAGS luajit_LIBS' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures snort 2.9.15.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/snort] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of snort 2.9.15.1:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --enable-shared[=PKGS] build shared libraries [default=yes] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) --enable-64bit-gcc Try to compile 64bit (only tested on Sparc Solaris 9 and 10). --enable-so-with-static-lib Enable linking of dynamically loaded preprocessors with a static preprocessor library --enable-control-socket Enable the control socket --enable-side-channel Enable the side channel (Experimental) --disable-static-daq Link static DAQ modules. --enable-build-dynamic-examples Enable building of example dynamically loaded preprocessor and rule (off by default) --disable-dlclose Only use if you are developing dynamic preprocessors or shared object rules. Disable (--disable-dlclose) for testing valgrind leaks in dynamic libraries so a usable backtrace is reported. Enabled by default. --disable-lzma Disable LZMA Decompression --disable-gre Disable GRE and IP in IP encapsulation support --disable-mpls Disable MPLS support --disable-targetbased Disable Target-Based Support in Stream, Frag, and Rules (adds pthread support implicitly) --disable-ppm Disable packet/rule performance monitor --disable-perfprofiling Disable preprocessor and rule performance profiling --enable-linux-smp-stats Enable statistics reporting through proc --enable-inline-init-failopen Enable Fail Open during initialization for Inline Mode (adds pthread support implicitly) --disable-pthread Disable pthread support --enable-debug-msgs Enable debug printing options (bugreports and developers only) --enable-debug Enable debugging options (bugreports and developers only) --enable-gdb Enable gdb debugging information --enable-profile Enable profiling options (developers only) --enable-test-coverage Enable gcov test coverage tracking (developers only) --disable-ppm-test Disable packet/rule performance monitor --enable-sourcefire Enable Sourcefire specific build options, encompasing --enable-perfprofiling and --enable-ppm --disable-corefiles Prevent Snort from generating core files --disable-active-response Disable reject injection --disable-normalizer Disable packet/stream normalizations --disable-reload Disable reloading a configuration without restarting --disable-reload-error-restart Disable restarting on reload error --enable-ha Enable high-availability state sharing (Experimental) --enable-buffer-dump Enable Buffer dump utility to dump packet buffers --enable-non-ether-decoders Enable non Ethernet decoders. --disable-react Disable interception and termination of offending HTTP accesses --disable-flexresp3 Disable flexible responses (v3) on hostile connection attempts --enable-intel-soft-cpm Enable Intel Soft CPM support --enable-shared-rep Enable use of Shared Memory for Reputation (Linux only) --enable-large-pcap Enable support for pcaps larger than 2 GB --enable-file-inspect Build with extended file inspection features. (Experimental) --disable-open-appid Disable application identification support. Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot=DIR Search for dependent libraries within DIR (or the compiler's sysroot if not specified). --with-libpcap-includes=DIR libpcap include directory --with-libpcap-libraries=DIR libpcap library directory --with-libpfring-includes=DIR libpfring include directory --with-libpfring-libraries=DIR libpfring library directory --with-daq-includes=DIR DAQ include directory --with-daq-libraries=DIR DAQ library directory --with-libpcre-includes=DIR libpcre include directory --with-libpcre-libraries=DIR libpcre library directory --with-openssl-includes=DIR openssl include directory --with-openssl-libraries=DIR openssl library directory --with-dnet-includes=DIR libdnet include directory --with-dnet-libraries=DIR libdnet library directory --with-lzma-includes=DIR liblzma include directory --with-lzma-libraries=DIR liblzma library directory --with-intel-soft-cpm-includes=DIR Intel Soft CPM include directory --with-intel-soft-cpm-libraries=DIR Intel Soft CPM library directory --with-libnghttp2-includes=DIR libnghttp2 include directory --with-libnghttp2-libraries=DIR libnghttp2 library directory Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor SIGNAL_SNORT_RELOAD set the SIGNAL_SNORT_RELOAD value SIGNAL_SNORT_DUMP_STATS set the SIGNAL_SNORT_DUMP_STATS value SIGNAL_SNORT_ROTATE_STATS set the SIGNAL_SNORT_ROTATE_STATS value SIGNAL_SNORT_READ_ATTR_TBL set the SIGNAL_SNORT_READ_ATTR_TBL value PKG_CONFIG path to pkg-config utility PKG_CONFIG_PATH directories to add to pkg-config's search path PKG_CONFIG_LIBDIR path overriding pkg-config's built-in search path luajit_CFLAGS C compiler flags for luajit, overriding pkg-config luajit_LIBS linker flags for luajit, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF snort configure 2.9.15.1 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_compute_int LINENO EXPR VAR INCLUDES # -------------------------------------------- # Tries to find the compile-time value of EXPR in a program that includes # INCLUDES, setting VAR accordingly. Returns whether the value could be # computed ac_fn_c_compute_int () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=0 ac_mid=0 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid; break else as_fn_arith $ac_mid + 1 && ac_lo=$as_val if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) < 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=-1 ac_mid=-1 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=$ac_mid; break else as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid else as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in #(( ?*) eval "$3=\$ac_lo"; ac_retval=0 ;; '') ac_retval=1 ;; esac else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 static long int longval () { return $2; } static unsigned long int ulongval () { return $2; } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (($2) < 0) { long int i = longval (); if (i != ($2)) return 1; fprintf (f, "%ld", i); } else { unsigned long int i = ulongval (); if (i != ($2)) return 1; fprintf (f, "%lu", i); } /* Do not output a trailing newline, as this causes \r\n confusion on some platforms. */ return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : echo >>conftest.val; read $3 &5 $as_echo_n "checking whether $as_decl_name is declared... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { #ifndef $as_decl_name #ifdef __cplusplus (void) $as_decl_use; #else (void) $as_decl_name; #endif #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_decl # ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES # ---------------------------------------------------- # Tries to find if the field MEMBER exists in type AGGR, after including # INCLUDES, setting cache variable VAR accordingly. ac_fn_c_check_member () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 $as_echo_n "checking for $2.$3... " >&6; } if eval \${$4+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int main () { static $2 ac_aggr; if (ac_aggr.$3) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$4=yes" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int main () { static $2 ac_aggr; if (sizeof ac_aggr.$3) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$4=yes" else eval "$4=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$4 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_member cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by snort $as_me 2.9.15.1, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers config.h" # When changing the snort version, please also update the VERSION # definition in "src/win32/WIN32-Includes/config.h" am__api_version='1.13' ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=1;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE=snort VERSION=2.9.15.1 cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar pax cpio none' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' NO_OPTIMIZE="no" DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi case $ac_cv_prog_cc_stdc in #( no) : ac_cv_prog_cc_c99=no; ac_cv_prog_cc_c89=no ;; #( *) : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5 $as_echo_n "checking for $CC option to accept ISO C99... " >&6; } if ${ac_cv_prog_cc_c99+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c99=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include #include // Check varargs macros. These examples are taken from C99 6.10.3.5. #define debug(...) fprintf (stderr, __VA_ARGS__) #define showlist(...) puts (#__VA_ARGS__) #define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) static void test_varargs_macros (void) { int x = 1234; int y = 5678; debug ("Flag"); debug ("X = %d\n", x); showlist (The first, second, and third items.); report (x>y, "x is %d but y is %d", x, y); } // Check long long types. #define BIG64 18446744073709551615ull #define BIG32 4294967295ul #define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) #if !BIG_OK your preprocessor is broken; #endif #if BIG_OK #else your preprocessor is broken; #endif static long long int bignum = -9223372036854775807LL; static unsigned long long int ubignum = BIG64; struct incomplete_array { int datasize; double data[]; }; struct named_init { int number; const wchar_t *name; double average; }; typedef const char *ccp; static inline int test_restrict (ccp restrict text) { // See if C++-style comments work. // Iterate through items via the restricted pointer. // Also check for declarations in for loops. for (unsigned int i = 0; *(text+i) != '\0'; ++i) continue; return 0; } // Check varargs and va_copy. static void test_varargs (const char *format, ...) { va_list args; va_start (args, format); va_list args_copy; va_copy (args_copy, args); const char *str; int number; float fnumber; while (*format) { switch (*format++) { case 's': // string str = va_arg (args_copy, const char *); break; case 'd': // int number = va_arg (args_copy, int); break; case 'f': // float fnumber = va_arg (args_copy, double); break; default: break; } } va_end (args_copy); va_end (args); } int main () { // Check bool. _Bool success = false; // Check restrict. if (test_restrict ("String literal") == 0) success = true; char *restrict newvar = "Another string"; // Check varargs. test_varargs ("s, d' f .", "string", 65, 34.234); test_varargs_macros (); // Check flexible array members. struct incomplete_array *ia = malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); ia->datasize = 10; for (int i = 0; i < ia->datasize; ++i) ia->data[i] = i * 1.234; // Check named initializers. struct named_init ni = { .number = 34, .name = L"Test wide string", .average = 543.34343, }; ni.number = 58; int dynamic_array[ni.number]; dynamic_array[ni.number - 1] = 543; // work around unused variable warnings return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x' || dynamic_array[ni.number - 1] != 543); ; return 0; } _ACEOF for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99 do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c99=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c99" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c99" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c99" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 $as_echo "$ac_cv_prog_cc_c99" >&6; } ;; esac if test "x$ac_cv_prog_cc_c99" != xno; then : ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 else ac_cv_prog_cc_stdc=no fi fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO Standard C" >&5 $as_echo_n "checking for $CC option to accept ISO Standard C... " >&6; } if ${ac_cv_prog_cc_stdc+:} false; then : $as_echo_n "(cached) " >&6 fi case $ac_cv_prog_cc_stdc in #( no) : { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; #( '') : { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; #( *) : { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_stdc" >&5 $as_echo "$ac_cv_prog_cc_stdc" >&6; } ;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi case `pwd` in *\ * | *\ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 $as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.4.2' macro_revision='1.3337' ltmain="$ac_aux_dir/ltmain.sh" # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac # Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\(["`$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 $as_echo_n "checking how to print strings... " >&6; } # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "" } case "$ECHO" in printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 $as_echo "printf" >&6; } ;; print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 $as_echo "print -r" >&6; } ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 $as_echo "cat" >&6; } ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 $as_echo "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } if ${ac_cv_path_FGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then ac_path_FGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_FGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 $as_echo "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 $as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if ${lt_cv_path_NM+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 $as_echo "$lt_cv_path_NM" >&6; } if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else if test -n "$ac_tool_prefix"; then for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 $as_echo "$DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 $as_echo "$ac_ct_DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols" ;; *) DUMPBIN=: ;; esac fi if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 $as_echo_n "checking the name lister ($NM) interface... " >&6; } if ${lt_cv_nm_interface+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 $as_echo "$lt_cv_nm_interface" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi # find the maximum length of command line arguments { $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 $as_echo_n "checking the maximum length of command line arguments... " >&6; } if ${lt_cv_sys_max_cmd_len+:} false; then : $as_echo_n "(cached) " >&6 else i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac fi if test -n $lt_cv_sys_max_cmd_len ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 $as_echo "$lt_cv_sys_max_cmd_len" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 $as_echo "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 $as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,b/c, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 $as_echo "$xsi_shell" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 $as_echo_n "checking whether the shell understands \"+=\"... " >&6; } lt_shell_append=no ( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 $as_echo "$lt_shell_append" >&6; } if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 $as_echo_n "checking how to convert $build file names to $host format... " >&6; } if ${lt_cv_to_host_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 $as_echo "$lt_cv_to_host_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 $as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } if ${lt_cv_to_tool_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 $as_echo "$lt_cv_to_tool_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 $as_echo_n "checking for $LD option to reload object files... " >&6; } if ${lt_cv_ld_reload_flag+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_reload_flag='-r' fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 $as_echo "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) if test "$GCC" != yes; then reload_cmds=false fi ;; darwin*) if test "$GCC" = yes; then reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 $as_echo_n "checking how to recognize dependent libraries... " >&6; } if ${lt_cv_deplibs_check_method+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # `unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # which responds to the $file_magic_cmd with a given extended regex. # If you have `file' or equivalent on your system and you're not sure # whether `pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; gnu*) lt_cv_deplibs_check_method=pass_all ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[3-9]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) lt_cv_deplibs_check_method=pass_all ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 $as_echo "$lt_cv_deplibs_check_method" >&6; } file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 $as_echo "$DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 $as_echo "$ac_ct_DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi test -z "$DLLTOOL" && DLLTOOL=dlltool { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 $as_echo_n "checking how to associate runtime and link libraries... " >&6; } if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh # decide which to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd="$ECHO" ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 $as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO if test -n "$ac_tool_prefix"; then for ac_prog in ar do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} : ${AR_FLAGS=cru} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 $as_echo_n "checking for archiver @FILE support... " >&6; } if ${lt_cv_ar_at_file+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -ne 0; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 $as_echo "$lt_cv_ar_at_file" >&6; } if test "x$lt_cv_ar_at_file" = xno; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 $as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } if ${lt_cv_sys_global_symbol_pipe+:} false; then : $as_echo_n "(cached) " >&6 else # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then nm_file_list_spec='@' fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 $as_echo_n "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. if test "${with_sysroot+set}" = set; then : withval=$with_sysroot; else with_sysroot=no fi lt_sysroot= case ${with_sysroot} in #( yes) if test "$GCC" = yes; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 $as_echo "${with_sysroot}" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 $as_echo "${lt_sysroot:-no}" >&6; } # Check whether --enable-libtool-lock was given. if test "${enable_libtool_lock+set}" = set; then : enableval=$enable_libtool_lock; fi test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; ppc64-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; ppc*-*linux*|powerpc*-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } if ${lt_cv_cc_needs_belf+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_cc_needs_belf=yes else lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 $as_echo "$lt_cv_cc_needs_belf" >&6; } if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; *-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD="${LD-ld}_sol2" fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. set dummy ${ac_tool_prefix}mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 $as_echo "$MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_MANIFEST_TOOL"; then ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL # Extract the first word of "mt", so it can be a program name with args. set dummy mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 $as_echo "$ac_ct_MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then MANIFEST_TOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL fi else MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 $as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } if ${lt_cv_path_mainfest_tool+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 $as_echo "$lt_cv_path_mainfest_tool" >&6; } if test "x$lt_cv_path_mainfest_tool" != xyes; then MANIFEST_TOOL=: fi case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 $as_echo "$DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 $as_echo "$ac_ct_DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 $as_echo "$NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 $as_echo "$ac_ct_NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 $as_echo "$LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 $as_echo "$ac_ct_LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 $as_echo "$OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 $as_echo "$ac_ct_OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 $as_echo "$OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 $as_echo "$ac_ct_OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 $as_echo_n "checking for -single_module linker flag... " >&6; } if ${lt_cv_apple_cc_single_mod+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test $_lt_result -eq 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 $as_echo "$lt_cv_apple_cc_single_mod" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } if ${lt_cv_ld_exported_symbols_list+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_ld_exported_symbols_list=yes else lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 $as_echo_n "checking for -force_load linker flag... " >&6; } if ${lt_cv_ld_force_load+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 echo "$AR cru libconftest.a conftest.o" >&5 $AR cru libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then lt_cv_ld_force_load=yes else cat conftest.err >&5 fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 $as_echo "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[91]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[012]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in dlfcn.h do : ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " if test "x$ac_cv_header_dlfcn_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLFCN_H 1 _ACEOF fi done # Set options enable_dlopen=no enable_win32_dll=no # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac else enable_shared=yes fi # Check whether --enable-static was given. if test "${enable_static+set}" = set; then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac else enable_static=yes fi # Check whether --with-pic was given. if test "${with_pic+set}" = set; then : withval=$with_pic; lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for lt_pkg in $withval; do IFS="$lt_save_ifs" if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS="$lt_save_ifs" ;; esac else pic_mode=default fi test -z "$pic_mode" && pic_mode=default # Check whether --enable-fast-install was given. if test "${enable_fast_install+set}" = set; then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac else enable_fast_install=yes fi # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 $as_echo_n "checking for objdir... " >&6; } if ${lt_cv_objdir+:} false; then : $as_echo_n "(cached) " >&6 else rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 $as_echo "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir cat >>confdefs.h <<_ACEOF #define LT_OBJDIR "$lt_cv_objdir/" _ACEOF case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 $as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/${ac_tool_prefix}file; then lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 $as_echo_n "checking for file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/file; then lt_cv_path_MAGIC_CMD="$ac_dir/file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC="$CC" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test "$GCC" = yes; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; *) lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= if test "$GCC" = yes; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 lt_prog_compiler_wl='-Xlinker ' if test -n "$lt_prog_compiler_pic"; then lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; *Sun\ F* | *Sun*Fortran*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Intel*\ [CF]*Compiler*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; *Portland\ Group*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if ${lt_cv_prog_compiler_pic+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic=$lt_prog_compiler_pic fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 $as_echo "$lt_cv_prog_compiler_pic" >&6; } lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if ${lt_cv_prog_compiler_pic_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; } if test x"$lt_cv_prog_compiler_pic_works" = xyes; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 $as_echo "$lt_cv_prog_compiler_static_works" >&6; } if test x"$lt_cv_prog_compiler_static_works" = xyes; then : else lt_prog_compiler_static= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test "$hard_links" = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; esac ld_shlibs=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test "$with_gnu_ld" = yes; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; *\ \(GNU\ Binutils\)\ [3-9]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test "$lt_use_gnu_ld_interface" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' export_dynamic_flag_spec='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' export_dynamic_flag_spec='${wl}--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' link_all_deplibs=yes ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test "$ld_shlibs" = no; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global # defined symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi export_dynamic_flag_spec='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' ${wl}-bernotok' allow_undefined_flag=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes file_list_spec='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' enable_shared_with_static_runtimes=yes ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported if test "$lt_cv_ld_force_load" = "yes"; then whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes allow_undefined_flag="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test "$GCC" = yes; then archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='${wl}-E' ;; hpux10*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 $as_echo_n "checking if $CC understands -b... " >&6; } if ${lt_cv_prog_compiler__b+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler__b=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler__b=yes fi else lt_cv_prog_compiler__b=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 $as_echo "$lt_cv_prog_compiler__b" >&6; } if test x"$lt_cv_prog_compiler__b" = xyes; then archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi ;; esac fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 $as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } if ${lt_cv_irix_exported_symbol+:} false; then : $as_echo_n "(cached) " >&6 else save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_irix_exported_symbol=yes else lt_cv_irix_exported_symbol=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 $as_echo "$lt_cv_irix_exported_symbol" >&6; } if test "$lt_cv_irix_exported_symbol" = yes; then archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' fi else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' else case $host_os in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-R$libdir' ;; *) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; esac fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='${wl}-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='${wl}-z,text' allow_undefined_flag='${wl}-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='${wl}-Blargedynsym' ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 $as_echo "$ld_shlibs" >&6; } test "$ld_shlibs" = no && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } if ${lt_cv_archive_cmds_need_lc+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc=no else lt_cv_archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 $as_echo "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; *) lt_sed_strip_eq="s,=/,/,g" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's,/\([A-Za-z]:\),\1,g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Add ABI-specific directories to the system library path. sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test "X$hardcode_automatic" = "Xyes" ; then # We can hardcode non-existent directories. if test "$hardcode_direct" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && test "$hardcode_minus_L" != no; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 $as_echo "$hardcode_action" >&6; } if test "$hardcode_action" = relink || test "$inherit_rpath" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes; then : lt_cv_dlopen="shl_load" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } if ${ac_cv_lib_dld_shl_load+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_shl_load=yes else ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes; then : lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" else ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes; then : lt_cv_dlopen="dlopen" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } if ${ac_cv_lib_svld_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_svld_dlopen=yes else ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } if ${ac_cv_lib_dld_dld_link+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dld_link (); int main () { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_dld_link=yes else ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes; then : lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" fi fi fi fi fi fi ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 $as_echo_n "checking whether a program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 $as_echo "$lt_cv_dlopen_self" >&6; } if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self_static+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 $as_echo "$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 $as_echo_n "checking whether stripping libraries is possible... " >&6; } if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; esac fi # Report which library types will actually be built { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 $as_echo_n "checking if libtool supports shared libraries... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 $as_echo "$can_build_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 $as_echo_n "checking whether to build shared libraries... " >&6; } test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 $as_echo "$enable_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 $as_echo_n "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 $as_echo "$enable_static" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC="$lt_save_CC" ac_config_commands="$ac_config_commands libtool" # Only expand once: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 $as_echo_n "checking whether byte ordering is bigendian... " >&6; } if ${ac_cv_c_bigendian+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_bigendian=unknown # See if we're dealing with a universal compiler. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __APPLE_CC__ not a universal capable compiler #endif typedef int dummy; _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # Check for potential -arch flags. It is not universal unless # there are at least two -arch flags with different values. ac_arch= ac_prev= for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do if test -n "$ac_prev"; then case $ac_word in i?86 | x86_64 | ppc | ppc64) if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then ac_arch=$ac_word else ac_cv_c_bigendian=universal break fi ;; esac ac_prev= elif test "x$ac_word" = "x-arch"; then ac_prev=arch fi done fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_c_bigendian = unknown; then # See if sys/param.h defines the BYTE_ORDER macro. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { #if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ && LITTLE_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # It does; now see whether it defined to BIG_ENDIAN or not. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_bigendian=yes else ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # It does; now see whether it defined to _BIG_ENDIAN or not. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #ifndef _BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_bigendian=yes else ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # Compile a test program. if test "$cross_compiling" = yes; then : # Try to guess by grepping values from an object file. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; int use_ascii (int i) { return ascii_mm[i] + ascii_ii[i]; } short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; int use_ebcdic (int i) { return ebcdic_mm[i] + ebcdic_ii[i]; } extern int foo; int main () { return use_ascii (foo) == use_ebcdic (foo); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then ac_cv_c_bigendian=yes fi if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then if test "$ac_cv_c_bigendian" = unknown; then ac_cv_c_bigendian=no else # finding both strings is unlikely to happen, but who knows? ac_cv_c_bigendian=unknown fi fi fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { /* Are we little or big endian? From Harbison&Steele. */ union { long int l; char c[sizeof (long int)]; } u; u.l = 1; return u.c[sizeof (long int) - 1] == 1; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_c_bigendian=no else ac_cv_c_bigendian=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 $as_echo "$ac_cv_c_bigendian" >&6; } case $ac_cv_c_bigendian in #( yes) $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h ;; #( no) ;; #( universal) $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h ;; #( *) as_fn_error $? "unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; esac # AC_C_BIGENDIAN implicitly defines WORDS_BIGENDIAN, but the CCONFIGFLAGS also needs to be affected. if test "x$ac_cv_c_bigendian" = "xyes"; then CCONFIGFLAGS="${CCONFIGFLAGS} -DSF_BIGENDIAN" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 $as_echo_n "checking for inline... " >&6; } if ${ac_cv_c_inline+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; static $ac_kw foo_t static_foo () {return 0; } $ac_kw foo_t foo () {return 0; } #endif _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_inline=$ac_kw fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_inline" != no && break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 $as_echo "$ac_cv_c_inline" >&6; } case $ac_cv_c_inline in inline | yes) ;; *) case $ac_cv_c_inline in no) ac_val=;; *) ac_val=$ac_cv_c_inline;; esac cat >>confdefs.h <<_ACEOF #ifndef __cplusplus #define inline $ac_val #endif _ACEOF ;; esac #AC_CANONICAL_HOST linux="no" sunos4="no" macos="no" so_with_static_lib="yes" case "$host" in *-openbsd2.6|*-openbsd2.5|*-openbsd2.4|*-openbsd2.3*) $as_echo "#define OPENBSD 1" >>confdefs.h $as_echo "#define BROKEN_SIOCGIFMTU 1" >>confdefs.h so_with_static_lib="no" ;; *-openbsd*) $as_echo "#define OPENBSD 1" >>confdefs.h so_with_static_lib="no" ;; *-sgi-irix5*) $as_echo "#define IRIX 1" >>confdefs.h no_libsocket="yes" no_libnsl="yes" if test -z "$GCC"; then sgi_cc="yes" fi LDFLAGS="${LDFLAGS} -L/usr/local/lib" extra_incl="-I/usr/local/include" ;; *-sgi-irix6*) $as_echo "#define IRIX 1" >>confdefs.h no_libsocket="yes" no_libnsl="yes" if test -z "$GCC"; then sgi_cc="yes" fi LDFLAGS="${LDFLAGS} -L/usr/local/lib" extra_incl="-I/usr/local/include" ;; *-solaris*) $as_echo "#define SOLARIS 1" >>confdefs.h CONFIGFLAGS="${CONFIGFLAGS} -DBSD_COMP -D_REENTRANT" rt_nanosleep="yes" ;; *-sunos*) $as_echo "#define SUNOS 1" >>confdefs.h sunos4="yes" ;; *-linux*) linux="yes" $as_echo "#define LINUX 1" >>confdefs.h extra_incl="-I/usr/include/pcap" ;; *-hpux10*|*-hpux11*) $as_echo "#define HPUX 1" >>confdefs.h if test "x$ac_cv_c_bigendian" = "xno"; then # exception to AC_C_BIGENDIAN and test "x$ac_cv_c_bigendian" = "xyes" above # causes the need for next three lines. { $as_echo "$as_me:${as_lineno-$LINENO}: bigendian byte-order not detected but asserted for $host" >&5 $as_echo "$as_me: bigendian byte-order not detected but asserted for $host" >&6;} $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h CCONFIGFLAGS="${CCONFIGFLAGS} -DSF_BIGENDIAN" fi extra_incl="-I/usr/local/include" ;; *-freebsd*) $as_echo "#define FREEBSD 1" >>confdefs.h ;; *-bsdi*) $as_echo "#define BSDI 1" >>confdefs.h ;; *-aix*) $as_echo "#define AIX 1" >>confdefs.h ;; *-osf4*) $as_echo "#define OSF1 1" >>confdefs.h CONFIGFLAGS="${CONFIGFLAGS} -DOSF1" ;; *-osf5.1*) $as_echo "#define OSF1 1" >>confdefs.h CONFIGFLAGS="${CONFIGFLAGS} -DOSF1" ;; *-tru64*) $as_echo "#define OSF1 1" >>confdefs.h CONFIGFLAGS="${CONFIGFLAGS} -DOSF1" ;; # it is actually -apple-darwin1.2 or -apple-rhapsody5.x but lets stick with this for the moment *-apple*) macos="yes" $as_echo "#define MACOS 1" >>confdefs.h $as_echo "#define BROKEN_SIOCGIFMTU 1" >>confdefs.h esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5 $as_echo_n "checking for stdbool.h that conforms to C99... " >&6; } if ${ac_cv_header_stdbool_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifndef bool "error: bool is not defined" #endif #ifndef false "error: false is not defined" #endif #if false "error: false is not 0" #endif #ifndef true "error: true is not defined" #endif #if true != 1 "error: true is not 1" #endif #ifndef __bool_true_false_are_defined "error: __bool_true_false_are_defined is not defined" #endif struct s { _Bool s: 1; _Bool t; } s; char a[true == 1 ? 1 : -1]; char b[false == 0 ? 1 : -1]; char c[__bool_true_false_are_defined == 1 ? 1 : -1]; char d[(bool) 0.5 == true ? 1 : -1]; /* See body of main program for 'e'. */ char f[(_Bool) 0.0 == false ? 1 : -1]; char g[true]; char h[sizeof (_Bool)]; char i[sizeof s.t]; enum { j = false, k = true, l = false * true, m = true * 256 }; /* The following fails for HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */ _Bool n[m]; char o[sizeof n == m * sizeof n[0] ? 1 : -1]; char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1]; /* Catch a bug in an HP-UX C compiler. See http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html */ _Bool q = true; _Bool *pq = &q; int main () { bool e = &s; *pq |= q; *pq |= ! q; /* Refer to every declared value, to avoid compiler optimizations. */ return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l + !m + !n + !o + !p + !q + !pq); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdbool_h=yes else ac_cv_header_stdbool_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5 $as_echo "$ac_cv_header_stdbool_h" >&6; } ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default" if test "x$ac_cv_type__Bool" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE__BOOL 1 _ACEOF fi if test $ac_cv_header_stdbool_h = yes; then $as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h fi # ICC stuff ICC=no if eval "echo $CC | grep icc > /dev/null" ; then if eval "$CC -help | grep libcxa > /dev/null" ; then CFLAGS="$CFLAGS -static-libcxa" LDFLAGS="$LDFLAGS -static-libcxa" XCCFLAGS="-XCClinker -static-libcxa" else CFLAGS="$CFLAGS -static-intel" LDFLAGS="$LDFLAGS -static-intel" XCCFLAGS="-XCClinker -static-intel" fi #CFLAGS=`echo $CFLAGS | sed 's/-O2/-O3/'` CFLAGS="$CFLAGS -O3 -ip -w1" ICC=yes fi # This is really meant for Solaris Sparc v9 where it has 32bit and 64bit # capability but builds 32bit by default # Check whether --enable-64bit-gcc was given. if test "${enable_64bit_gcc+set}" = set; then : enableval=$enable_64bit_gcc; enable_64bit_gcc="$enableval" else enable_64bit_gcc="no" fi if test "x$enable_64bit_gcc" = "xyes"; then CFLAGS="$CFLAGS -m64" fi # AC_PROG_YACC defaults to "yacc" when not found # this check defaults to "none" for ac_prog in bison yacc do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_YACC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$YACC"; then ac_cv_prog_YACC="$YACC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_YACC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi YACC=$ac_cv_prog_YACC if test -n "$YACC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $YACC" >&5 $as_echo "$YACC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$YACC" && break done test -n "$YACC" || YACC="none" # AC_PROG_YACC includes the -y arg if bison is found if test "x$YACC" = "xbison"; then YACC="$YACC -y" fi # AC_PROG_LEX defaults to ":" when not found # this check defaults to "none" # We're using flex specific options so we don't support lex for ac_prog in flex do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LEX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LEX"; then ac_cv_prog_LEX="$LEX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LEX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LEX=$ac_cv_prog_LEX if test -n "$LEX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LEX" >&5 $as_echo "$LEX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$LEX" && break done test -n "$LEX" || LEX="none" # for ac_header in \ inttypes.h \ math.h \ paths.h \ stdlib.h \ string.h \ strings.h \ unistd.h \ wchar.h \ sys/sockio.h \ do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done if test "x$ac_cv_header_wchar_h" = "xyes"; then CONFIGFLAGS="${CONFIGFLAGS} -DSF_WCHAR" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for floor in -lm" >&5 $as_echo_n "checking for floor in -lm... " >&6; } if ${ac_cv_lib_m_floor+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char floor (); int main () { return floor (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_floor=yes else ac_cv_lib_m_floor=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_floor" >&5 $as_echo "$ac_cv_lib_m_floor" >&6; } if test "x$ac_cv_lib_m_floor" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ceil in -lm" >&5 $as_echo_n "checking for ceil in -lm... " >&6; } if ${ac_cv_lib_m_ceil+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char ceil (); int main () { return ceil (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_ceil=yes else ac_cv_lib_m_ceil=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_ceil" >&5 $as_echo "$ac_cv_lib_m_ceil" >&6; } if test "x$ac_cv_lib_m_ceil" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi for ac_header in uuid/uuid.h do : ac_fn_c_check_header_mongrel "$LINENO" "uuid/uuid.h" "ac_cv_header_uuid_uuid_h" "$ac_includes_default" if test "x$ac_cv_header_uuid_uuid_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UUID_UUID_H 1 _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_parse in -luuid" >&5 $as_echo_n "checking for uuid_parse in -luuid... " >&6; } if ${ac_cv_lib_uuid_uuid_parse+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-luuid $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char uuid_parse (); int main () { return uuid_parse (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_uuid_uuid_parse=yes else ac_cv_lib_uuid_uuid_parse=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_parse" >&5 $as_echo "$ac_cv_lib_uuid_uuid_parse" >&6; } if test "x$ac_cv_lib_uuid_uuid_parse" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBUUID 1 _ACEOF LIBS="-luuid $LIBS" fi fi done if test "x$rt_nanosleep" = "xyes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nanosleep in -lrt" >&5 $as_echo_n "checking for nanosleep in -lrt... " >&6; } if ${ac_cv_lib_rt_nanosleep+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lrt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char nanosleep (); int main () { return nanosleep (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_rt_nanosleep=yes else ac_cv_lib_rt_nanosleep=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_nanosleep" >&5 $as_echo "$ac_cv_lib_rt_nanosleep" >&6; } if test "x$ac_cv_lib_rt_nanosleep" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBRT 1 _ACEOF LIBS="-lrt $LIBS" fi fi if test -z "$no_libnsl"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntoa in -lnsl" >&5 $as_echo_n "checking for inet_ntoa in -lnsl... " >&6; } if ${ac_cv_lib_nsl_inet_ntoa+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char inet_ntoa (); int main () { return inet_ntoa (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nsl_inet_ntoa=yes else ac_cv_lib_nsl_inet_ntoa=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_inet_ntoa" >&5 $as_echo "$ac_cv_lib_nsl_inet_ntoa" >&6; } if test "x$ac_cv_lib_nsl_inet_ntoa" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBNSL 1 _ACEOF LIBS="-lnsl $LIBS" fi fi if test -z "$no_libsocket"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lsocket" >&5 $as_echo_n "checking for socket in -lsocket... " >&6; } if ${ac_cv_lib_socket_socket+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char socket (); int main () { return socket (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_socket_socket=yes else ac_cv_lib_socket_socket=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_socket" >&5 $as_echo "$ac_cv_lib_socket_socket" >&6; } if test "x$ac_cv_lib_socket_socket" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBSOCKET 1 _ACEOF LIBS="-lsocket $LIBS" fi fi # SunOS4 has several things `broken' if test "$sunos4" != "no"; then for ac_func in vsnprintf do : ac_fn_c_check_func "$LINENO" "vsnprintf" "ac_cv_func_vsnprintf" if test "x$ac_cv_func_vsnprintf" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_VSNPRINTF 1 _ACEOF else LIBS="$LIBS -ldb" fi done for ac_func in strtoul do : ac_fn_c_check_func "$LINENO" "strtoul" "ac_cv_func_strtoul" if test "x$ac_cv_func_strtoul" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRTOUL 1 _ACEOF else LIBS="$LIBS -l44bsd" fi done fi # some funky macro to be backwards compatible with earlier autoconfs # in current they have AC_CHECK_DECLS # some stuff for declarations which were missed on sunos4 platform too. # # add `#undef NEED_DECL_FUNCTIONAME to acconfig.h` because autoheader # fails to work properly with custom macroses. # you will see also #undef for each SN_CHECK_DECLS macros invocation # because autoheader doesn't execute shell script commands. # it is possible to make loops using m4 but the code would look even # more confusing.. for sn_decl in printf fprintf syslog puts fputs fputc fopen \ fclose fwrite fflush getopt bzero bcopy memset strtol \ strcasecmp strncasecmp strerror perror socket sendto \ vsnprintf snprintf strtoul do sn_def_decl=`echo $sn_decl | tr a-z A-Z` { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $sn_decl must be declared" >&5 $as_echo_n "checking whether $sn_decl must be declared... " >&6; } if eval \${sn_cv_decl_needed_$sn_decl+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_STRINGS_H #include #endif #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #include #include #include int main () { char *(*pfn); pfn = (char *(*)) $sn_decl; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "sn_cv_decl_needed_$sn_decl=no" else eval "sn_cv_decl_needed_$sn_decl=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if eval "test \"`echo '$sn_cv_decl_needed_'$sn_decl`\" != no"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } cat >>confdefs.h <<_ACEOF #define NEED_DECL_$sn_def_decl 1 _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi done for ac_func in sigaction strlcpy strlcat strerror vswprintf wprintf memrchr inet_ntop gettid do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_c_check_func "$LINENO" "snprintf" "ac_cv_func_snprintf" if test "x$ac_cv_func_snprintf" = xyes; then : have_snprintf="yes" else have_snprintf="no" fi if test "x$have_snprintf" != "xyes"; then BUILD_SNPRINTF_TRUE= BUILD_SNPRINTF_FALSE='#' else BUILD_SNPRINTF_TRUE='#' BUILD_SNPRINTF_FALSE= fi if test "x$have_snprintf" = "xyes"; then $as_echo "#define HAVE_SNPRINTF /**/" >>confdefs.h fi for ac_func in malloc_trim mallinfo do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of char" >&5 $as_echo_n "checking size of char... " >&6; } if ${ac_cv_sizeof_char+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (char))" "ac_cv_sizeof_char" "$ac_includes_default"; then : else if test "$ac_cv_type_char" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (char) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_char=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_char" >&5 $as_echo "$ac_cv_sizeof_char" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_CHAR $ac_cv_sizeof_char _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of short" >&5 $as_echo_n "checking size of short... " >&6; } if ${ac_cv_sizeof_short+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (short))" "ac_cv_sizeof_short" "$ac_includes_default"; then : else if test "$ac_cv_type_short" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (short) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_short=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" >&5 $as_echo "$ac_cv_sizeof_short" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_SHORT $ac_cv_sizeof_short _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 $as_echo_n "checking size of int... " >&6; } if ${ac_cv_sizeof_int+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default"; then : else if test "$ac_cv_type_int" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (int) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_int=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 $as_echo "$ac_cv_sizeof_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_INT $ac_cv_sizeof_int _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long int" >&5 $as_echo_n "checking size of long int... " >&6; } if ${ac_cv_sizeof_long_int+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long int))" "ac_cv_sizeof_long_int" "$ac_includes_default"; then : else if test "$ac_cv_type_long_int" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (long int) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_long_int=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_int" >&5 $as_echo "$ac_cv_sizeof_long_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG_INT $ac_cv_sizeof_long_int _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long int" >&5 $as_echo_n "checking size of long long int... " >&6; } if ${ac_cv_sizeof_long_long_int+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long int))" "ac_cv_sizeof_long_long_int" "$ac_includes_default"; then : else if test "$ac_cv_type_long_long_int" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (long long int) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_long_long_int=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long_int" >&5 $as_echo "$ac_cv_sizeof_long_long_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG_LONG_INT $ac_cv_sizeof_long_long_int _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned int" >&5 $as_echo_n "checking size of unsigned int... " >&6; } if ${ac_cv_sizeof_unsigned_int+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned int))" "ac_cv_sizeof_unsigned_int" "$ac_includes_default"; then : else if test "$ac_cv_type_unsigned_int" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (unsigned int) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_unsigned_int=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_int" >&5 $as_echo "$ac_cv_sizeof_unsigned_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_UNSIGNED_INT $ac_cv_sizeof_unsigned_int _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long int" >&5 $as_echo_n "checking size of unsigned long int... " >&6; } if ${ac_cv_sizeof_unsigned_long_int+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long int))" "ac_cv_sizeof_unsigned_long_int" "$ac_includes_default"; then : else if test "$ac_cv_type_unsigned_long_int" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (unsigned long int) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_unsigned_long_int=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long_int" >&5 $as_echo "$ac_cv_sizeof_unsigned_long_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_UNSIGNED_LONG_INT $ac_cv_sizeof_unsigned_long_int _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long long int" >&5 $as_echo_n "checking size of unsigned long long int... " >&6; } if ${ac_cv_sizeof_unsigned_long_long_int+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long long int))" "ac_cv_sizeof_unsigned_long_long_int" "$ac_includes_default"; then : else if test "$ac_cv_type_unsigned_long_long_int" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (unsigned long long int) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_unsigned_long_long_int=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long_long_int" >&5 $as_echo "$ac_cv_sizeof_unsigned_long_long_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_UNSIGNED_LONG_LONG_INT $ac_cv_sizeof_unsigned_long_long_int _ACEOF # Check for int types ac_fn_c_check_type "$LINENO" "u_int8_t" "ac_cv_type_u_int8_t" "$ac_includes_default" if test "x$ac_cv_type_u_int8_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_U_INT8_T 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "u_int16_t" "ac_cv_type_u_int16_t" "$ac_includes_default" if test "x$ac_cv_type_u_int16_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_U_INT16_T 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "u_int32_t" "ac_cv_type_u_int32_t" "$ac_includes_default" if test "x$ac_cv_type_u_int32_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_U_INT32_T 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "u_int64_t" "ac_cv_type_u_int64_t" "$ac_includes_default" if test "x$ac_cv_type_u_int64_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_U_INT64_T 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "uint8_t" "ac_cv_type_uint8_t" "$ac_includes_default" if test "x$ac_cv_type_uint8_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UINT8_T 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "uint16_t" "ac_cv_type_uint16_t" "$ac_includes_default" if test "x$ac_cv_type_uint16_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UINT16_T 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "uint32_t" "ac_cv_type_uint32_t" "$ac_includes_default" if test "x$ac_cv_type_uint32_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UINT32_T 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "uint64_t" "ac_cv_type_uint64_t" "$ac_includes_default" if test "x$ac_cv_type_uint64_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UINT64_T 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "int8_t" "ac_cv_type_int8_t" "$ac_includes_default" if test "x$ac_cv_type_int8_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_INT8_T 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "int16_t" "ac_cv_type_int16_t" "$ac_includes_default" if test "x$ac_cv_type_int16_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_INT16_T 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "int32_t" "ac_cv_type_int32_t" "$ac_includes_default" if test "x$ac_cv_type_int32_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_INT32_T 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "int64_t" "ac_cv_type_int64_t" "$ac_includes_default" if test "x$ac_cv_type_int64_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_INT64_T 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "boolean" "ac_cv_type_boolean" "$ac_includes_default" if test "x$ac_cv_type_boolean" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_BOOLEAN 1 _ACEOF fi # In case INADDR_NONE is not defined (like on Solaris) have_inaddr_none="no" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for INADDR_NONE" >&5 $as_echo_n "checking for INADDR_NONE... " >&6; } if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { if (inet_addr("10,5,2") == INADDR_NONE); return 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : have_inaddr_none="yes" else have_inaddr_none="no" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_inaddr_none" >&5 $as_echo "$have_inaddr_none" >&6; } if test "x$have_inaddr_none" = "xno"; then $as_echo "#define INADDR_NONE -1" >>confdefs.h fi cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { const char *foo; foo = sys_errlist[0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define ERRLIST_PREDEFINED 1" >>confdefs.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __FUNCTION__" >&5 $as_echo_n "checking for __FUNCTION__... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { printf ("%s", __FUNCTION__); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sn_cv_have___FUNCTION__=yes else sn_cv__have___FUNCTION__=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test "x$sn_cv_have___FUNCTION__" = "xyes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HAVE___FUNCTION__ 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __func__" >&5 $as_echo_n "checking for __func__... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { printf ("%s", __func__); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sn_cv_have___func__=yes else sn_cv__have___func__=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test "x$sn_cv_have___func__" = "xyes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HAVE___func__ 1" >>confdefs.h $as_echo "#define __FUNCTION__ __func__" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "#define __FUNCTION__ \"mystery function\"" >>confdefs.h fi fi # Check whether --with-libpcap_includes was given. if test "${with_libpcap_includes+set}" = set; then : withval=$with_libpcap_includes; with_libpcap_includes="$withval" else with_libpcap_includes="no" fi # Check whether --with-libpcap_libraries was given. if test "${with_libpcap_libraries+set}" = set; then : withval=$with_libpcap_libraries; with_libpcap_libraries="$withval" else with_libpcap_libraries="no" fi if test "x$with_libpcap_includes" != "xno"; then CPPFLAGS="${CPPFLAGS} -I${with_libpcap_includes}" fi if test "x$with_libpcap_libraries" != "xno"; then LDFLAGS="${LDFLAGS} -L${with_libpcap_libraries}" fi # --with-libpfring-* options # Check whether --with-libpfring_includes was given. if test "${with_libpfring_includes+set}" = set; then : withval=$with_libpfring_includes; with_libpfring_includes="$withval" else with_libpfring_includes="no" fi # Check whether --with-libpfring_libraries was given. if test "${with_libpfring_libraries+set}" = set; then : withval=$with_libpfring_libraries; with_libpfring_libraries="$withval" else with_libpfring_libraries="no" fi if test "x$with_libpfring_includes" != "xno"; then CPPFLAGS="${CPPFLAGS} -I${with_libpfring_includes}" fi if test "x$with_libpfring_libraries" != "xno"; then LDFLAGS="${LDFLAGS} -L${with_libpfring_libraries}" fi # Check whether --with-daq_includes was given. if test "${with_daq_includes+set}" = set; then : withval=$with_daq_includes; with_daq_includes="$withval" else with_daq_includes="no" fi # Check whether --with-daq_libraries was given. if test "${with_daq_libraries+set}" = set; then : withval=$with_daq_libraries; with_daq_libraries="$withval" else with_daq_libraries="no" fi if test "x$with_daq_includes" != "xno"; then CPPFLAGS="${CPPFLAGS} -I${with_daq_includes}" fi if test "x$with_daq_libraries" != "xno"; then LDFLAGS="${LDFLAGS} -L${with_daq_libraries}" fi if test "x$enable_control_socket" = "xyes"; then LSFBPF="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sfbpf_compile in -lsfbpf" >&5 $as_echo_n "checking for sfbpf_compile in -lsfbpf... " >&6; } if ${ac_cv_lib_sfbpf_sfbpf_compile+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsfbpf $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char sfbpf_compile (); int main () { return sfbpf_compile (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_sfbpf_sfbpf_compile=yes else ac_cv_lib_sfbpf_sfbpf_compile=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sfbpf_sfbpf_compile" >&5 $as_echo "$ac_cv_lib_sfbpf_sfbpf_compile" >&6; } if test "x$ac_cv_lib_sfbpf_sfbpf_compile" = xyes; then : LIBS="${LIBS} -lsfbpf" else LSFBPF="no" fi if test "x$LSFBPF" = "xno"; then echo echo " ERROR! sfbpf library not found, go get it from" echo " http://www.snort.org/." #AC_MSG_ERROR("Fatal!") exit 1 fi fi LPCAP="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pcap_datalink in -lpcap" >&5 $as_echo_n "checking for pcap_datalink in -lpcap... " >&6; } if ${ac_cv_lib_pcap_pcap_datalink+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpcap $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pcap_datalink (); int main () { return pcap_datalink (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pcap_pcap_datalink=yes else ac_cv_lib_pcap_pcap_datalink=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pcap_pcap_datalink" >&5 $as_echo "$ac_cv_lib_pcap_pcap_datalink" >&6; } if test "x$ac_cv_lib_pcap_pcap_datalink" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBPCAP 1 _ACEOF LIBS="-lpcap $LIBS" else LPCAP="no" fi # If the normal AC_CHECK_LIB for pcap fails then check to see if we are # using a pfring-enabled pcap. if test "x$LPCAP" = "xno"; then PFRING_H="" for ac_header in pfring.h do : ac_fn_c_check_header_mongrel "$LINENO" "pfring.h" "ac_cv_header_pfring_h" "$ac_includes_default" if test "x$ac_cv_header_pfring_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_PFRING_H 1 _ACEOF else PFRING_H="no" fi done # It is important to have the AC_CHECK_LIB for the pfring library BEFORE # the one for pfring-enabled pcap. When the Makefile is created, all the # libraries used during linking are added to the LIBS variable in the # Makefile in the opposite order that their AC_CHECK_LIB macros appear # in configure.in. Durring linking, the pfring library (-lpfring) MUST come # _after_ the libpcap library (-lpcap) or linking will fail. PFRING_L="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pfring_open in -lpfring" >&5 $as_echo_n "checking for pfring_open in -lpfring... " >&6; } if ${ac_cv_lib_pfring_pfring_open+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpfring $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pfring_open (); int main () { return pfring_open (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pfring_pfring_open=yes else ac_cv_lib_pfring_pfring_open=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pfring_pfring_open" >&5 $as_echo "$ac_cv_lib_pfring_pfring_open" >&6; } if test "x$ac_cv_lib_pfring_pfring_open" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBPFRING 1 _ACEOF LIBS="-lpfring $LIBS" else PFRING_L="no" fi LPFRING_PCAP="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pfring_open in -lpcap" >&5 $as_echo_n "checking for pfring_open in -lpcap... " >&6; } if ${ac_cv_lib_pcap_pfring_open+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpcap -lpfring $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pfring_open (); int main () { return pfring_open (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pcap_pfring_open=yes else ac_cv_lib_pcap_pfring_open=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pcap_pfring_open" >&5 $as_echo "$ac_cv_lib_pcap_pfring_open" >&6; } if test "x$ac_cv_lib_pcap_pfring_open" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBPCAP 1 _ACEOF LIBS="-lpcap $LIBS" else LPFRING_PCAP="no" fi fi # If both the AC_CHECK_LIB for normal pcap and pfring-enabled pcap fail then exit. if test "x$LPCAP" = "xno"; then if test "x$LPFRING_PCAP" = "xno"; then echo echo " ERROR! Libpcap library/headers (libpcap.a (or .so)/pcap.h)" echo " not found, go get it from http://www.tcpdump.org" echo " or use the --with-libpcap-* options, if you have it installed" echo " in unusual place. Also check if your libpcap depends on another" echo " shared library that may be installed in an unusual place" exit 1 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pcap_lex_destroy" >&5 $as_echo_n "checking for pcap_lex_destroy... " >&6; } if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { pcap_lex_destroy(); ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : have_pcap_lex_destroy="yes" else have_pcap_lex_destroy="no" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_pcap_lex_destroy" >&5 $as_echo "$have_pcap_lex_destroy" >&6; } if test "x$have_pcap_lex_destroy" = "xyes"; then $as_echo "#define HAVE_PCAP_LEX_DESTROY 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pcap_lib_version" >&5 $as_echo_n "checking for pcap_lib_version... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { pcap_lib_version(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : have_pcap_lib_version="yes" else have_pcap_lib_version="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_pcap_lib_version" >&5 $as_echo "$have_pcap_lib_version" >&6; } if test "x$have_pcap_lib_version" = "xyes"; then $as_echo "#define HAVE_PCAP_LIB_VERSION 1" >>confdefs.h fi # Check whether --with-libpcre_includes was given. if test "${with_libpcre_includes+set}" = set; then : withval=$with_libpcre_includes; with_libpcre_includes="$withval" else with_libpcre_includes="no" fi # Check whether --with-libpcre_libraries was given. if test "${with_libpcre_libraries+set}" = set; then : withval=$with_libpcre_libraries; with_libpcre_libraries="$withval" else with_libpcre_libraries="no" fi if test "x$with_libpcre_includes" != "xno"; then CPPFLAGS="${CPPFLAGS} -I${with_libpcre_includes}" ICONFIGFLAGS="${ICONFIGFLAGS} -I${with_libpcre_includes}" else CPPFLAGS="${CPPFLAGS} `pcre-config --cflags`" fi if test "x$with_libpcre_libraries" != "xno"; then LDFLAGS="${LDFLAGS} -L${with_libpcre_libraries}" else LDFLAGS="${LDFLAGS} `pcre-config --libs`" fi # PCRE configuration (required) # Verify that we have the headers PCRE_H="" for ac_header in pcre.h do : ac_fn_c_check_header_mongrel "$LINENO" "pcre.h" "ac_cv_header_pcre_h" "$ac_includes_default" if test "x$ac_cv_header_pcre_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_PCRE_H 1 _ACEOF else PCRE_H="no" fi done if test "x$PCRE_H" = "xno"; then echo echo " ERROR! Libpcre header not found." echo " Get it from http://www.pcre.org" exit 1 fi # Verify that we have the library PCRE_L="" pcre_version_six="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pcre_compile in -lpcre" >&5 $as_echo_n "checking for pcre_compile in -lpcre... " >&6; } if ${ac_cv_lib_pcre_pcre_compile+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpcre $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pcre_compile (); int main () { return pcre_compile (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pcre_pcre_compile=yes else ac_cv_lib_pcre_pcre_compile=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pcre_pcre_compile" >&5 $as_echo "$ac_cv_lib_pcre_pcre_compile" >&6; } if test "x$ac_cv_lib_pcre_pcre_compile" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBPCRE 1 _ACEOF LIBS="-lpcre $LIBS" else PCRE_L="no" fi if test "x$PCRE_L" = "xno"; then echo echo " ERROR! Libpcre library not found." echo " Get it from http://www.pcre.org" echo exit 1 else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libpcre version 6.0 or greater" >&5 $as_echo_n "checking for libpcre version 6.0 or greater... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #if (PCRE_MAJOR < 6) #error "Version failure" #else int a, b = 0, c = 0, d = 0; pcre *tmp = NULL; a = pcre_copy_named_substring(tmp, "", &b, c, "", "", d); #endif ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : pcre_version_six="yes" else pcre_version_six="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi if test "x$pcre_version_six" != "xyes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } echo echo " ERROR! Libpcre library version >= 6.0 not found." echo " Get it from http://www.pcre.org" echo exit 1 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi # OPENSSL SHA configuration (optional) # Check whether --with-openssl_includes was given. if test "${with_openssl_includes+set}" = set; then : withval=$with_openssl_includes; with_openssl_includes="$withval" else with_openssl_includes="no" fi # Check whether --with-openssl_libraries was given. if test "${with_openssl_libraries+set}" = set; then : withval=$with_openssl_libraries; with_openssl_libraries="$withval" else with_openssl_libraries="no" fi if test "x$with_openssl_includes" != "xno"; then CPPFLAGS="${CPPFLAGS} -I${with_openssl_includes}" ICONFIGFLAGS="${ICONFIGFLAGS} -I${with_openssl_includes}" fi if test "x$with_openssl_libraries" != "xno"; then LDFLAGS="${LDFLAGS} -L${with_openssl_libraries}" fi # Verify that we have the headers { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SHA256_Init in -lcrypto" >&5 $as_echo_n "checking for SHA256_Init in -lcrypto... " >&6; } if ${ac_cv_lib_crypto_SHA256_Init+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypto $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char SHA256_Init (); int main () { return SHA256_Init (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_crypto_SHA256_Init=yes else ac_cv_lib_crypto_SHA256_Init=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_SHA256_Init" >&5 $as_echo "$ac_cv_lib_crypto_SHA256_Init" >&6; } if test "x$ac_cv_lib_crypto_SHA256_Init" = xyes; then : $as_echo "#define HAVE_OPENSSL_SHA 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for MD5_Init in -lcrypto" >&5 $as_echo_n "checking for MD5_Init in -lcrypto... " >&6; } if ${ac_cv_lib_crypto_MD5_Init+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypto $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char MD5_Init (); int main () { return MD5_Init (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_crypto_MD5_Init=yes else ac_cv_lib_crypto_MD5_Init=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_MD5_Init" >&5 $as_echo "$ac_cv_lib_crypto_MD5_Init" >&6; } if test "x$ac_cv_lib_crypto_MD5_Init" = xyes; then : $as_echo "#define HAVE_OPENSSL_MD5 1" >>confdefs.h fi if test "$ac_cv_lib_crypto_MD5_Init" != "yes" ; then BUILD_OPENSSL_MD5_TRUE= BUILD_OPENSSL_MD5_FALSE='#' else BUILD_OPENSSL_MD5_TRUE='#' BUILD_OPENSSL_MD5_FALSE= fi if test "$ac_cv_lib_crypto_SHA256_Init" != "yes" ; then BUILD_OPENSSL_SHA_TRUE= BUILD_OPENSSL_SHA_FALSE='#' else BUILD_OPENSSL_SHA_TRUE='#' BUILD_OPENSSL_SHA_FALSE= fi if test "$ac_cv_lib_crypto_MD5_Init" = "yes"; then LIBS="${LIBS} -lcrypto" fi if test "x$SIGNAL_SNORT_RELOAD" != "x" ; then cat >>confdefs.h <<_ACEOF #define SIGNAL_SNORT_RELOAD $SIGNAL_SNORT_RELOAD _ACEOF fi if test "x$SIGNAL_SNORT_DUMP_STATS" != "x" ; then cat >>confdefs.h <<_ACEOF #define SIGNAL_SNORT_DUMP_STATS $SIGNAL_SNORT_DUMP_STATS _ACEOF fi if test "x$SIGNAL_SNORT_ROTATE_STATS" != "x" ; then cat >>confdefs.h <<_ACEOF #define SIGNAL_SNORT_ROTATE_STATS $SIGNAL_SNORT_ROTATE_STATS _ACEOF fi if test "x$SIGNAL_SNORT_READ_ATTR_TBL" != "x" ; then cat >>confdefs.h <<_ACEOF #define SIGNAL_SNORT_READ_ATTR_TBL $SIGNAL_SNORT_READ_ATTR_TBL _ACEOF fi # Check whether --enable-so_with_static_lib was given. if test "${enable_so_with_static_lib+set}" = set; then : enableval=$enable_so_with_static_lib; enable_so_with_static_lib="$enableval" else enable_so_with_static_lib=$so_with_static_lib fi if test "x$enable_so_with_static_lib" = "xyes"; then SO_WITH_STATIC_LIB_TRUE= SO_WITH_STATIC_LIB_FALSE='#' else SO_WITH_STATIC_LIB_TRUE='#' SO_WITH_STATIC_LIB_FALSE= fi # Check whether --enable-control_socket was given. if test "${enable_control_socket+set}" = set; then : enableval=$enable_control_socket; enable_control_socket="$enableval" else enable_control_socket="no" fi os=`(uname -s)` if test "x$linux" != "xyes"; then if test "$OSTYPE" != "FreeBSD" && "$os" != "FreeBSD"; then if test "x$enable_control_socket" = "xyes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: The control socket is only supported on Linux or FreeBSD systems." >&5 $as_echo "$as_me: WARNING: The control socket is only supported on Linux or FreeBSD systems." >&2;} enable_control_socket="no" fi fi fi if test "x$enable_control_socket" = "xyes"; then BUILD_CONTROL_SOCKET_TRUE= BUILD_CONTROL_SOCKET_FALSE='#' else BUILD_CONTROL_SOCKET_TRUE='#' BUILD_CONTROL_SOCKET_FALSE= fi if test "x$enable_control_socket" = "xyes"; then CONFIGFLAGS="$CONFIGFLAGS -DCONTROL_SOCKET" fi # Check whether --enable-side_channel was given. if test "${enable_side_channel+set}" = set; then : enableval=$enable_side_channel; enable_side_channel="$enableval" else enable_side_channel="no" fi if test "x$linux" != "xyes"; then if test "$OSTYPE" != "FreeBSD" && "$os" != "FreeBSD"; then if test "x$enable_side_channel" = "xyes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: The side channel is only supported on Linux or FreeBSD systems." >&5 $as_echo "$as_me: WARNING: The side channel is only supported on Linux or FreeBSD systems." >&2;} enable_side_channel="no" fi fi fi if test "x$enable_side_channel" = "xyes"; then BUILD_SIDE_CHANNEL_TRUE= BUILD_SIDE_CHANNEL_FALSE='#' else BUILD_SIDE_CHANNEL_TRUE='#' BUILD_SIDE_CHANNEL_FALSE= fi if test "x$enable_side_channel" = "xyes"; then CONFIGFLAGS="$CONFIGFLAGS -DSIDE_CHANNEL" fi # check for dnet first since some DAQs need it # Check whether --with-dnet_includes was given. if test "${with_dnet_includes+set}" = set; then : withval=$with_dnet_includes; with_dnet_includes="$withval" else with_dnet_includes="no" fi # Check whether --with-dnet_libraries was given. if test "${with_dnet_libraries+set}" = set; then : withval=$with_dnet_libraries; with_dnet_libraries="$withval" else with_dnet_libraries="no" fi if test "x$with_dnet_includes" != "xno"; then CPPFLAGS="${CPPFLAGS} -I${with_dnet_includes}" ICONFIGFLAGS="${ICONFIGFLAGS} -I${with_dnet_includes}" else CPPFLAGS="${CPPFLAGS} `dnet-config --cflags 2>/dev/null`" fi if test "x$with_dnet_libraries" != "xno"; then LDFLAGS="${LDFLAGS} -L${with_dnet_libraries}" else LDFLAGS="${LDFLAGS} `dnet-config --libs 2>/dev/null`" fi for ac_header in dnet.h do : ac_fn_c_check_header_mongrel "$LINENO" "dnet.h" "ac_cv_header_dnet_h" "$ac_includes_default" if test "x$ac_cv_header_dnet_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DNET_H 1 _ACEOF else DNET_H="no" fi done for ac_header in dumbnet.h do : ac_fn_c_check_header_mongrel "$LINENO" "dumbnet.h" "ac_cv_header_dumbnet_h" "$ac_includes_default" if test "x$ac_cv_header_dumbnet_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DUMBNET_H 1 _ACEOF else DUMBNET_H="no" fi done if test "x$DNET_H" = "xno" -a "x$DUMBNET_H" = "xno"; then echo echo " ERROR! dnet header not found, go get it from" echo " http://code.google.com/p/libdnet/ or use the --with-dnet-*" echo " options, if you have it installed in an unusual place" exit fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for eth_set in -ldnet" >&5 $as_echo_n "checking for eth_set in -ldnet... " >&6; } if ${ac_cv_lib_dnet_eth_set+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldnet $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char eth_set (); int main () { return eth_set (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dnet_eth_set=yes else ac_cv_lib_dnet_eth_set=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_eth_set" >&5 $as_echo "$ac_cv_lib_dnet_eth_set" >&6; } if test "x$ac_cv_lib_dnet_eth_set" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBDNET 1 _ACEOF LIBS="-ldnet $LIBS" else DNET="no" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for eth_set in -ldumbnet" >&5 $as_echo_n "checking for eth_set in -ldumbnet... " >&6; } if ${ac_cv_lib_dumbnet_eth_set+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldumbnet $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char eth_set (); int main () { return eth_set (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dumbnet_eth_set=yes else ac_cv_lib_dumbnet_eth_set=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dumbnet_eth_set" >&5 $as_echo "$ac_cv_lib_dumbnet_eth_set" >&6; } if test "x$ac_cv_lib_dumbnet_eth_set" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBDUMBNET 1 _ACEOF LIBS="-ldumbnet $LIBS" else DUMBNET="no" fi if test "x$DNET" = "xno" -a "x$DUMBNET" = "xno"; then echo echo " ERROR! dnet library not found, go get it from" echo " http://code.google.com/p/libdnet/ or use the --with-dnet-*" echo " options, if you have it installed in an unusual place" exit fi # Check whether --enable-static_daq was given. if test "${enable_static_daq+set}" = set; then : enableval=$enable_static_daq; enable_static_daq="$enableval" else enable_static_daq="yes" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlsym in -ldl" >&5 $as_echo_n "checking for dlsym in -ldl... " >&6; } if ${ac_cv_lib_dl_dlsym+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlsym (); int main () { return dlsym (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlsym=yes else ac_cv_lib_dl_dlsym=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlsym" >&5 $as_echo "$ac_cv_lib_dl_dlsym" >&6; } if test "x$ac_cv_lib_dl_dlsym" = xyes; then : DLLIB="yes" else DLLIB="no" fi if test "$DLLIB" != "no"; then LIBS="${LIBS} -ldl" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlsym in -lc" >&5 $as_echo_n "checking for dlsym in -lc... " >&6; } if ${ac_cv_lib_c_dlsym+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlsym (); int main () { return dlsym (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_c_dlsym=yes else ac_cv_lib_c_dlsym=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_dlsym" >&5 $as_echo "$ac_cv_lib_c_dlsym" >&6; } if test "x$ac_cv_lib_c_dlsym" = xyes; then : DLLIB="yes" else DLLIB="no" fi if test "$DLLIB" = "no"; then echo echo " ERROR! programmatic interface to dynamic link loader" echo " not found. Cannot build Snort." echo exit 1 fi fi if test "x$enable_static_daq" = "xyes"; then LDAQ="" LIBS="${LIBS} `daq-modules-config --static --libs`" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for daq_load_modules in -ldaq_static" >&5 $as_echo_n "checking for daq_load_modules in -ldaq_static... " >&6; } if ${ac_cv_lib_daq_static_daq_load_modules+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldaq_static $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char daq_load_modules (); int main () { return daq_load_modules (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_daq_static_daq_load_modules=yes else ac_cv_lib_daq_static_daq_load_modules=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_daq_static_daq_load_modules" >&5 $as_echo "$ac_cv_lib_daq_static_daq_load_modules" >&6; } if test "x$ac_cv_lib_daq_static_daq_load_modules" = xyes; then : LIBS="-ldaq_static ${LIBS}" else LDAQ="no" fi if test "x$LDAQ" = "xno"; then echo echo " ERROR! daq_static library not found, go get it from" echo " http://www.snort.org/." #AC_MSG_ERROR("Fatal!") # FIXTHIS switch over to this macro exit 1 # instead of raw exits! fi else LDAQ="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for daq_load_modules in -ldaq" >&5 $as_echo_n "checking for daq_load_modules in -ldaq... " >&6; } if ${ac_cv_lib_daq_daq_load_modules+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldaq $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char daq_load_modules (); int main () { return daq_load_modules (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_daq_daq_load_modules=yes else ac_cv_lib_daq_daq_load_modules=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_daq_daq_load_modules" >&5 $as_echo "$ac_cv_lib_daq_daq_load_modules" >&6; } if test "x$ac_cv_lib_daq_daq_load_modules" = xyes; then : LIBS="${LIBS} -ldaq" else LDAQ="no" fi if test "x$LDAQ" = "xno"; then echo echo " ERROR! daq library not found, go get it from" echo " http://www.snort.org/." #AC_MSG_ERROR("Fatal!") exit 1 fi fi for ac_func in daq_hup_apply daq_acquire_with_meta daq_dp_add_dc do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for daq real addresses" >&5 $as_echo_n "checking for daq real addresses... " >&6; } if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { DAQ_PktHdr_t hdr; hdr.n_real_dPort = 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : have_daq_real_addresses="yes" else have_daq_real_addresses="no" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_daq_real_addresses" >&5 $as_echo "$have_daq_real_addresses" >&6; } if test "x$have_daq_real_addresses" = "xyes"; then $as_echo "#define HAVE_DAQ_REAL_ADDRESSES 1" >>confdefs.h fi ac_fn_c_check_decl "$LINENO" "DAQ_PKT_FLAG_DECRYPTED_SSL" "ac_cv_have_decl_DAQ_PKT_FLAG_DECRYPTED_SSL" "#include " if test "x$ac_cv_have_decl_DAQ_PKT_FLAG_DECRYPTED_SSL" = xyes; then : have_daq_decrypted_ssl="yes" else have_daq_decrypted_ssl="no" fi if test "x$have_daq_decrypted_ssl" = "xyes"; then $as_echo "#define HAVE_DAQ_DECRYPTED_SSL 1" >>confdefs.h fi ac_fn_c_check_decl "$LINENO" "DAQ_PKT_FLAG_LOCALLY_ORIGINATED" "ac_cv_have_decl_DAQ_PKT_FLAG_LOCALLY_ORIGINATED" "#include " if test "x$ac_cv_have_decl_DAQ_PKT_FLAG_LOCALLY_ORIGINATED" = xyes; then : have_daq_locally_originated="yes" else have_daq_locally_originated="no" fi if test "x$have_daq_locally_originated" = "xyes"; then $as_echo "#define HAVE_DAQ_LOCALLY_ORIGINATED 1" >>confdefs.h fi ac_fn_c_check_decl "$LINENO" "DAQ_PKT_FLAG_LOCALLY_DESTINED" "ac_cv_have_decl_DAQ_PKT_FLAG_LOCALLY_DESTINED" "#include " if test "x$ac_cv_have_decl_DAQ_PKT_FLAG_LOCALLY_DESTINED" = xyes; then : have_daq_locally_destined="yes" else have_daq_locally_destined="no" fi if test "x$have_daq_locally_destined" = "xyes"; then $as_echo "#define HAVE_DAQ_LOCALLY_DESTINED 1" >>confdefs.h fi if test "x$ac_cv_func_daq_dp_add_dc" = "xyes"; then ac_fn_c_check_member "$LINENO" "struct _DAQ_DP_key_t" "sa.src_ip4" "ac_cv_member_struct__DAQ_DP_key_t_sa_src_ip4" "#include " if test "x$ac_cv_member_struct__DAQ_DP_key_t_sa_src_ip4" = xyes; then : else DAQ_C99_STRUCT="no" fi if test "x$DAQ_C99_STRUCT" = "xno" ; then echo echo " ERROR! daq library missing C99 patch, upgrade to >=2.0.4, go get it from" echo " http://www.snort.org/." exit 1 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for daq address space ID" >&5 $as_echo_n "checking for daq address space ID... " >&6; } if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { DAQ_PktHdr_t hdr; hdr.address_space_id = 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : have_daq_address_space_id="yes" else have_daq_address_space_id="no" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_daq_address_space_id" >&5 $as_echo "$have_daq_address_space_id" >&6; } if test "x$have_daq_address_space_id" = "xyes"; then $as_echo "#define HAVE_DAQ_ADDRESS_SPACE_ID 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for daq flow ID" >&5 $as_echo_n "checking for daq flow ID... " >&6; } if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { DAQ_PktHdr_t hdr; hdr.flow_id = 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : have_daq_flow_id="yes" else have_daq_flow_id="no" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_daq_flow_id" >&5 $as_echo "$have_daq_flow_id" >&6; } if test "x$have_daq_flow_id" = "xyes"; then $as_echo "#define HAVE_DAQ_FLOW_ID 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for daq extended flow modifiers" >&5 $as_echo_n "checking for daq extended flow modifiers... " >&6; } if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { DAQ_ModFlow_t mod; mod.type = 0; mod.length = 0; mod.value = NULL; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : have_daq_ext_modflow="yes" else have_daq_ext_modflow="no" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_daq_ext_modflow" >&5 $as_echo "$have_daq_ext_modflow" >&6; } if test "x$have_daq_ext_modflow" = "xyes"; then CCONFIGFLAGS="${CCONFIGFLAGS} -DHAVE_DAQ_EXT_MODFLOW" $as_echo "#define HAVE_DAQ_EXT_MODFLOW 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for daq query flow" >&5 $as_echo_n "checking for daq query flow... " >&6; } if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { DAQ_QueryFlow_t mod; mod.type = 0; mod.length = 0; mod.value = NULL; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : have_daq_queryflow="yes" else have_daq_queryflow="no" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_daq_queryflow" >&5 $as_echo "$have_daq_queryflow" >&6; } if test "x$have_daq_queryflow" = "xyes"; then CCONFIGFLAGS="${CCONFIGFLAGS} -DHAVE_DAQ_QUERYFLOW" $as_echo "#define HAVE_DAQ_QUERYFLOW 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for daq data channel flags" >&5 $as_echo_n "checking for daq data channel flags... " >&6; } if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { DAQ_Data_Channel_Params_t params; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : have_daq_data_channel_flags="yes" else have_daq_data_channel_flags="no" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_daq_data_channel_flags" >&5 $as_echo "$have_daq_data_channel_flags" >&6; } if test "x$have_daq_data_channel_flags" = "xyes"; then CCONFIGFLAGS="${CCONFIGFLAGS} -DHAVE_DAQ_DATA_CHANNEL_PARAMS" $as_echo "#define HAVE_DAQ_DATA_CHANNEL_PARAMS 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for separate IP versions on pinhole endpoints" >&5 $as_echo_n "checking for separate IP versions on pinhole endpoints... " >&6; } if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { DAQ_DP_key_t dpKey; dpKey.src_af = 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : have_daq_data_channel_separate_ip_versions="yes" else have_daq_data_channel_separate_ip_versions="no" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_daq_data_channel_separate_ip_versions" >&5 $as_echo "$have_daq_data_channel_separate_ip_versions" >&6; } if test "x$have_daq_data_channel_separate_ip_versions" = "xyes"; then CCONFIGFLAGS="${CCONFIGFLAGS} -DHAVE_DAQ_DATA_CHANNEL_SEPARATE_IP_VERSIONS" $as_echo "#define HAVE_DAQ_DATA_CHANNEL_SEPARATE_IP_VERSIONS 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DAQ_VERDICT_RETRY" >&5 $as_echo_n "checking for DAQ_VERDICT_RETRY... " >&6; } if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { DAQ_Verdict verdict; verdict = DAQ_VERDICT_RETRY; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : have_daq_verdict_retry="yes" else have_daq_verdict_retry="no" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_daq_verdict_retry" >&5 $as_echo "$have_daq_verdict_retry" >&6; } if test "x$have_daq_verdict_retry" = "xyes"; then $as_echo "#define HAVE_DAQ_VERDICT_RETRY 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for daq packet trace" >&5 $as_echo_n "checking for daq packet trace... " >&6; } if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { DAQ_PktHdr_t hdr; hdr.flags = DAQ_PKT_FLAG_TRACE_ENABLED; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : have_daq_packet_trace="yes" else have_daq_packet_trace="no" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_daq_packet_trace" >&5 $as_echo "$have_daq_packet_trace" >&6; } if test "x$have_daq_packet_trace" = "xyes"; then $as_echo "#define HAVE_DAQ_PKT_TRACE 1" >>confdefs.h else echo "DAQ version doesn't support packet trace." fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for daq verdict reason" >&5 $as_echo_n "checking for daq verdict reason... " >&6; } if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { DAQ_ModFlow_t fl; fl.type = DAQ_MODFLOW_TYPE_VER_REASON; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : have_daq_verdict_reason="yes" else have_daq_verdict_reason="no" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_daq_verdict_reason" >&5 $as_echo "$have_daq_verdict_reason" >&6; } if test "x$have_daq_verdict_reason" = "xyes"; then $as_echo "#define HAVE_DAQ_VERDICT_REASON 1" >>confdefs.h else echo "DAQ version doesn't support tracing verdict reason." fi # any sparc platform has to have this one defined. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sparc" >&5 $as_echo_n "checking for sparc... " >&6; } if eval "echo $host_cpu|grep -i sparc >/dev/null"; then $as_echo "#define WORDS_MUSTALIGN 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } # gcc, sparc and optimization not so good if test -n "$GCC"; then NO_OPTIMIZE="yes" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # check for sparc %time register if eval "echo $host_cpu|grep -i sparc >/dev/null"; then OLD_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -mcpu=v9 " { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sparc %time register" >&5 $as_echo_n "checking for sparc %time register... " >&6; } if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { int val; __asm__ __volatile__("rd %%tick, %0" : "=r"(val)); ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : sparcv9="yes" else sparcv9="no" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sparcv9" >&5 $as_echo "$sparcv9" >&6; } if test "x$sparcv9" = "xyes"; then $as_echo "#define SPARCV9 1" >>confdefs.h else CFLAGS="$OLD_CFLAGS" fi fi # modified from gnulib/m4/visibility.m4 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for visibility support" >&5 $as_echo_n "checking for visibility support... " >&6; } if ${gl_cv_cc_visibility+:} false; then : $as_echo_n "(cached) " >&6 else gl_save_CFLAGS="$CFLAGS" # Add -Werror flag since some compilers, e.g. icc 7.1, don't support it, # but only warn about it instead of compilation failing CFLAGS="$CFLAGS -Werror -fvisibility=hidden" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ extern __attribute__((__visibility__("hidden"))) int hiddenvar; extern __attribute__((__visibility__("default"))) int exportedvar; extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void); extern __attribute__((__visibility__("default"))) int exportedfunc (void); int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : gl_cv_cc_visibility="yes" else gl_cv_cc_visibility="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_cc_visibility" >&5 $as_echo "$gl_cv_cc_visibility" >&6; } CFLAGS="$gl_save_CFLAGS" if test "x$gl_cv_cc_visibility" = "xyes"; then CFLAGS="${CFLAGS} -DSF_VISIBILITY -fvisibility=hidden" $as_echo "#define HAVE_VISIBILITY 1" >>confdefs.h fi # Check whether --enable-build-dynamic-examples was given. if test "${enable_build_dynamic_examples+set}" = set; then : enableval=$enable_build_dynamic_examples; build_dynamic_examples="$enableval" else build_dynamic_examples="no" fi if test "x$build_dynamic_examples" = "xyes"; then BUILD_DYNAMIC_EXAMPLES_TRUE= BUILD_DYNAMIC_EXAMPLES_FALSE='#' else BUILD_DYNAMIC_EXAMPLES_TRUE='#' BUILD_DYNAMIC_EXAMPLES_FALSE= fi # Check whether --enable-dlclose was given. if test "${enable_dlclose+set}" = set; then : enableval=$enable_dlclose; enable_dlclose="$enableval" else enable_dlclose="yes" fi if test "x$enable_dlclose" = "xno"; then $as_echo "#define DISABLE_DLCLOSE_FOR_VALGRIND_TESTING 1" >>confdefs.h fi ################################################## # Fedora 28+ does not have inbuilt SunRPC support# # in glibc and is separately availble in tirpc # # package. Make sure we've got the library and # # link it # ################################################## if test -f /etc/fedora-release ; then DISTRO_VERSION=$(awk '{ print $3 }' /etc/fedora-release) if test $DISTRO_VERSION -ge 28 ; then TIRPC="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for bindresvport in -ltirpc" >&5 $as_echo_n "checking for bindresvport in -ltirpc... " >&6; } if ${ac_cv_lib_tirpc_bindresvport+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ltirpc $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char bindresvport (); int main () { return bindresvport (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_tirpc_bindresvport=yes else ac_cv_lib_tirpc_bindresvport=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tirpc_bindresvport" >&5 $as_echo "$ac_cv_lib_tirpc_bindresvport" >&6; } if test "x$ac_cv_lib_tirpc_bindresvport" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBTIRPC 1 _ACEOF LIBS="-ltirpc $LIBS" else TIRPC="no" fi echo "$TIRPC" if test "x$TIRPC" = "xno"; then echo echo " ERROR! tirpc not found, get it by running " echo " yum install libtirpc-devel " exit fi LIBS="${LIBS} -ltirpc" extra_incl="-I/usr/include/tirpc" fi fi Z_LIB="" for ac_header in zlib.h do : ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" if test "x$ac_cv_header_zlib_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_ZLIB_H 1 _ACEOF else Z_LIB="no" fi done if test "x$Z_LIB" = "xno"; then echo echo " ERROR! zlib header not found, go get it from" echo " http://www.zlib.net" exit fi Z_LIB="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inflate in -lz" >&5 $as_echo_n "checking for inflate in -lz... " >&6; } if ${ac_cv_lib_z_inflate+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lz $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char inflate (); int main () { return inflate (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_z_inflate=yes else ac_cv_lib_z_inflate=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_inflate" >&5 $as_echo "$ac_cv_lib_z_inflate" >&6; } if test "x$ac_cv_lib_z_inflate" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBZ 1 _ACEOF LIBS="-lz $LIBS" else Z_LIB="no" fi if test "x$Z_LIB" = "xno"; then echo echo " ERROR! zlib library not found, go get it from" echo " http://www.zlib.net" exit fi LIBS="$LIBS -lz" # Check whether --enable-lzma was given. if test "${enable_lzma+set}" = set; then : enableval=$enable_lzma; enable_lzma="$enableval" else enable_lzma="yes" fi # Check whether --with-lzma_includes was given. if test "${with_lzma_includes+set}" = set; then : withval=$with_lzma_includes; with_lzma_includes="$withval" else with_lzma_includes="no" fi # Check whether --with-lzma_libraries was given. if test "${with_lzma_libraries+set}" = set; then : withval=$with_lzma_libraries; with_lzma_libraries="$withval" else with_lzma_libraries="no" fi if test "x$enable_lzma" = "xyes"; then HAVE_LZMA_TRUE= HAVE_LZMA_FALSE='#' else HAVE_LZMA_TRUE='#' HAVE_LZMA_FALSE= fi if test "x$enable_lzma" = "xyes"; then if test "x$with_lzma_includes" != "xno"; then CPPFLAGS="${CPPFLAGS} -I${with_lzma_includes}" LZMA_HEADERS="yes" else for ac_header in lzma.h do : ac_fn_c_check_header_mongrel "$LINENO" "lzma.h" "ac_cv_header_lzma_h" "$ac_includes_default" if test "x$ac_cv_header_lzma_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LZMA_H 1 _ACEOF LZMA_HEADERS="yes" else LZMA_HEADERS="no" fi done fi if test "x$with_lzma_libraries" != "xno"; then LDFLAGS="${LDFLAGS} -L${with_lzma_libraries}" LZMA_LIB="yes" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lzma_stream_decoder in -llzma" >&5 $as_echo_n "checking for lzma_stream_decoder in -llzma... " >&6; } if ${ac_cv_lib_lzma_lzma_stream_decoder+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-llzma $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char lzma_stream_decoder (); int main () { return lzma_stream_decoder (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_lzma_lzma_stream_decoder=yes else ac_cv_lib_lzma_lzma_stream_decoder=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lzma_lzma_stream_decoder" >&5 $as_echo "$ac_cv_lib_lzma_lzma_stream_decoder" >&6; } if test "x$ac_cv_lib_lzma_lzma_stream_decoder" = xyes; then : LZMA_LIB="yes" else LZMA_LIB="no" fi fi if test "x$LZMA_LIB" != "xno"; then if test "x$LZMA_HEADERS" != "xno"; then CPPFLAGS="$CPPFLAGS -DLZMA" LIBS="$LIBS -llzma" fi fi fi # Check whether --enable-gre was given. if test "${enable_gre+set}" = set; then : enableval=$enable_gre; enable_gre="$enableval" else enable_gre="yes" fi if test "x$enable_gre" = "xyes"; then CPPFLAGS="$CPPFLAGS -DGRE" fi # Check whether --enable-mpls was given. if test "${enable_mpls+set}" = set; then : enableval=$enable_mpls; enable_mpls="$enableval" else enable_mpls="yes" fi if test "x$enable_mpls" = "xyes"; then CPPFLAGS="$CPPFLAGS -DMPLS" fi # Check whether --enable-targetbased was given. if test "${enable_targetbased+set}" = set; then : enableval=$enable_targetbased; enable_targetbased="$enableval" else enable_targetbased="yes" fi if test "x$enable_targetbased" = "xyes"; then HAVE_TARGET_BASED_TRUE= HAVE_TARGET_BASED_FALSE='#' else HAVE_TARGET_BASED_TRUE='#' HAVE_TARGET_BASED_FALSE= fi if test "x$enable_targetbased" = "xyes"; then CONFIGFLAGS="$CONFIGFLAGS -DTARGET_BASED" LIBS="$LIBS -lpthread" if test "$LEX" = "none"; then echo echo " ERROR! flex not found." echo " Get it from http://flex.sourceforge.net/" echo " (You may also try lex instead.)" echo exit 1 fi if test "$YACC" = "none"; then echo echo " ERROR! bison not found." echo " Get it from http://www.gnu.org/software/bison/" echo " (You may also try byacc or yacc instead.)" echo exit 1 fi fi # Check whether --enable-ppm was given. if test "${enable_ppm+set}" = set; then : enableval=$enable_ppm; enable_ppm="$enableval" else enable_ppm="yes" fi if test "x$enable_ppm" = "xyes"; then CPPFLAGS="$CPPFLAGS -DPPM_MGR" fi # Check whether --enable-perfprofiling was given. if test "${enable_perfprofiling+set}" = set; then : enableval=$enable_perfprofiling; enable_perfprofiling="$enableval" else enable_perfprofiling="yes" fi if test "x$enable_perfprofiling" = "xyes"; then CONFIGFLAGS="$CONFIGFLAGS -DPERF_PROFILING" fi # Check whether --enable-linux-smp-stats was given. if test "${enable_linux_smp_stats+set}" = set; then : enableval=$enable_linux_smp_stats; enable_linux_smp_stats="$enableval" else enable_linux_smp_stats="no" fi if test "x$enable_linux_smp_stats" = "xyes"; then BUILD_PROCPIDSTATS_TRUE= BUILD_PROCPIDSTATS_FALSE='#' else BUILD_PROCPIDSTATS_TRUE='#' BUILD_PROCPIDSTATS_FALSE= fi if test "x$enable_linux_smp_stats" = "xyes"; then CPPFLAGS="$CPPFLAGS -DLINUX_SMP" fi # Check whether --enable-inline-init-failopen was given. if test "${enable_inline_init_failopen+set}" = set; then : enableval=$enable_inline_init_failopen; enable_inline_init_failopen="$enableval" else enable_inline_init_failopen="no" fi if test "x$enable_inline_init_failopen" = "xyes"; then CPPFLAGS="$CPPFLAGS -DINLINE_FAILOPEN" LIBS="$LIBS -lpthread" fi # Check whether --enable-pthread was given. if test "${enable_pthread+set}" = set; then : enableval=$enable_pthread; enable_pthread="$enableval" else enable_pthread="yes" fi if test "x$enable_pthread" = "xyes"; then LIBS="$LIBS -lpthread" for ac_func in pthread_tryjoin_np do : ac_fn_c_check_func "$LINENO" "pthread_tryjoin_np" "ac_cv_func_pthread_tryjoin_np" if test "x$ac_cv_func_pthread_tryjoin_np" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_PTHREAD_TRYJOIN_NP 1 _ACEOF fi done fi # Check whether --enable-debug-msgs was given. if test "${enable_debug_msgs+set}" = set; then : enableval=$enable_debug_msgs; enable_debug_msgs="$enableval" else enable_debug_msgs="no" fi if test "x$enable_debug_msgs" = "xyes"; then CPPFLAGS="$CPPFLAGS -DDEBUG_MSGS" fi # Check whether --enable-debug was given. if test "${enable_debug+set}" = set; then : enableval=$enable_debug; enable_debug="$enableval" else enable_debug="no" fi if test "x$enable_debug" = "xyes"; then NO_OPTIMIZE="yes" # in case user override doesn't include -g if echo $CFLAGS | grep -qve -g ; then CFLAGS="$CFLAGS -g" fi CPPFLAGS="$CPPFLAGS -DDEBUG" else # disable assert()ions CPPFLAGS="$CPPFLAGS -DNDEBUG" fi # Check whether --enable-gdb was given. if test "${enable_gdb+set}" = set; then : enableval=$enable_gdb; enable_gdb="$enableval" else enable_gdb="no" fi if test "x$enable_gdb" = "xyes"; then CFLAGS="$CFLAGS -g -ggdb" fi # Check whether --enable-profile was given. if test "${enable_profile+set}" = set; then : enableval=$enable_profile; enable_profile="$enableval" else enable_profile="no" fi if test "x$enable_profile" = "xyes"; then if test -n "$GCC"; then CPPFLAGS="$CPPFLAGS -DPROFILE" CFLAGS="$CFLAGS -pg" else CPPFLAGS="$CPPFLAGS -DPROFILE" fi fi # Check whether --enable-test-coverage was given. if test "${enable_test_coverage+set}" = set; then : enableval=$enable_test_coverage; enable_test_coverage="$enableval" else enable_test_coverage="no" fi if test "x$enable_test_coverage" = "xyes"; then CFLAGS=`echo $CFLAGS | sed 's/-O\d/-O0/g'` CFLAGS="$CFLAGS -fprofile-arcs -ftest-coverage -O0" fi # Check whether --enable-ppm-test was given. if test "${enable_ppm_test+set}" = set; then : enableval=$enable_ppm_test; enable_ppm_test="$enableval" else enable_ppm_test="no" fi if test "x$enable_ppm_test" = "xyes"; then CPPFLAGS="$CPPFLAGS -DPPM_TEST" fi # Check whether --enable-sourcefire was given. if test "${enable_sourcefire+set}" = set; then : enableval=$enable_sourcefire; enable_sourcefire="$enableval" else enable_sourcefire="no" fi if test "x$enable_sourcefire" = "xyes"; then CPPFLAGS="$CPPFLAGS -DSOURCEFIRE -DPPM_MGR" CONFIGFLAGS="$CONFIGFLAGS -DPERF_PROFILING" fi # Check whether --enable-corefiles was given. if test "${enable_corefiles+set}" = set; then : enableval=$enable_corefiles; enable_corefiles="$enableval" else enable_corefiles="yes" fi if test "x$enable_corefiles" = "xno"; then CPPFLAGS="$CPPFLAGS -DNOCOREFILE" fi # Check whether --enable-active-response was given. if test "${enable_active_response+set}" = set; then : enableval=$enable_active_response; enable_active_response="$enableval" else enable_active_response="yes" fi # Check whether --enable-normalizer was given. if test "${enable_normalizer+set}" = set; then : enableval=$enable_normalizer; enable_normalizer="$enableval" else enable_normalizer="yes" fi # Check whether --enable-reload was given. if test "${enable_reload+set}" = set; then : enableval=$enable_reload; enable_reload="$enableval" else enable_reload="yes" fi # Check whether --enable-reload-error-restart was given. if test "${enable_reload_error_restart+set}" = set; then : enableval=$enable_reload_error_restart; enable_reload_error_restart="$enableval" else enable_reload_error_restart="yes" fi if test "x$enable_reload" = "xyes"; then BUILD_SNORT_RELOAD_TRUE= BUILD_SNORT_RELOAD_FALSE='#' else BUILD_SNORT_RELOAD_TRUE='#' BUILD_SNORT_RELOAD_FALSE= fi if test "x$enable_reload" = "xyes"; then if test "x$enable_reload_error_restart" = "xyes"; then CONFIGFLAGS="$CONFIGFLAGS -DSNORT_RELOAD" else CONFIGFLAGS="$CONFIGFLAGS -DSNORT_RELOAD -DRELOAD_ERROR_FATAL" fi LIBS="$LIBS -lpthread" fi # Check whether --enable-ha was given. if test "${enable_ha+set}" = set; then : enableval=$enable_ha; enable_ha="$enableval" else enable_ha="no" fi if test "x$enable_ha" = "xyes"; then BUILD_HA_TRUE= BUILD_HA_FALSE='#' else BUILD_HA_TRUE='#' BUILD_HA_FALSE= fi if test "x$enable_ha" = "xyes"; then CONFIGFLAGS="$CONFIGFLAGS -DENABLE_HA" fi # Check whether --enable-buffer-dump was given. if test "${enable_buffer_dump+set}" = set; then : enableval=$enable_buffer_dump; enable_buffer_dump="$enableval" else enable_buffer_dump="no" fi if test "x$enable_buffer_dump" = "xyes"; then BUILD_BUFFER_DUMP_TRUE= BUILD_BUFFER_DUMP_FALSE='#' else BUILD_BUFFER_DUMP_TRUE='#' BUILD_BUFFER_DUMP_FALSE= fi if test "x$enable_buffer_dump" = "xyes"; then CONFIGFLAGS="$CONFIGFLAGS -DDUMP_BUFFER" fi # define NO_NON_ETHER_DECODERS by default # Check whether --enable-non-ether-decoders was given. if test "${enable_non_ether_decoders+set}" = set; then : enableval=$enable_non_ether_decoders; enable_non_ether_decoders="$enableval" else enable_non_ether_decoders="no" fi if test "x$enable_non_ether_decoders" = "xno"; then CONFIGFLAGS="$CONFIGFLAGS -DNO_NON_ETHER_DECODER" fi # Check whether --enable-react was given. if test "${enable_react+set}" = set; then : enableval=$enable_react; enable_react="$enableval" else enable_react="yes" fi # Check whether --enable-flexresp3 was given. if test "${enable_flexresp3+set}" = set; then : enableval=$enable_flexresp3; enable_flexresp3="$enableval" else enable_flexresp3="yes" fi # test for invalid configurations here after all AC_ARG_ENABLEs if test "x$enable_flexresp3" = "xyes"; then # flexresp3 options are a union of flexresp (deleted) and flexresp2 # options so we assume flexresp3 if multiple are enabled. if test "x$enable_flexresp2" = "xyes"; then echo "WARNING: multiple flexresp versions enabled; using flexresp3." enable_flexresp2="no" fi fi if test "x$enable_react" = "xyes"; then BUILD_REACT_TRUE= BUILD_REACT_FALSE='#' else BUILD_REACT_TRUE='#' BUILD_REACT_FALSE= fi if test "x$enable_react" = "xyes"; then CPPFLAGS="${CPPFLAGS} -DENABLE_REACT" fi if test "x$enable_flexresp3" = "xyes"; then BUILD_RESPOND3_TRUE= BUILD_RESPOND3_FALSE='#' else BUILD_RESPOND3_TRUE='#' BUILD_RESPOND3_FALSE= fi if test "x$enable_flexresp3" = "xyes"; then CPPFLAGS="${CPPFLAGS} -DENABLE_RESPOND -DENABLE_RESPONSE3" fi if test "x$enable_normalizer" = "xyes" \ -o "x$enable_sourcefire" = "xyes" ; \ then CONFIGFLAGS="${CONFIGFLAGS} -DNORMALIZER" fi if test "x$enable_active_response" = "xyes" \ -o "x$enable_flexresp3" = "xyes" \ -o "x$enable_react" = "xyes" \ -o "x$enable_sourcefire" = "xyes" ; \ then CONFIGFLAGS="${CONFIGFLAGS} -DACTIVE_RESPONSE" fi # Check whether --enable-intel_soft_cpm was given. if test "${enable_intel_soft_cpm+set}" = set; then : enableval=$enable_intel_soft_cpm; enable_intel_soft_cpm="$enableval" else enable_intel_soft_cpm="no" fi # Check whether --with-intel_soft_cpm_includes was given. if test "${with_intel_soft_cpm_includes+set}" = set; then : withval=$with_intel_soft_cpm_includes; with_intel_soft_cpm_includes="$withval" else with_intel_soft_cpm_includes="no" fi # Check whether --with-intel_soft_cpm_libraries was given. if test "${with_intel_soft_cpm_libraries+set}" = set; then : withval=$with_intel_soft_cpm_libraries; with_intel_soft_cpm_libraries="$withval" else with_intel_soft_cpm_libraries="no" fi if test "x$with_intel_soft_cpm_includes" != "xno"; then enable_intel_soft_cpm="yes" CPPFLAGS="${CPPFLAGS} -I${with_intel_soft_cpm_includes}" fi if test "x$with_intel_soft_cpm_libraries" != "xno"; then enable_intel_soft_cpm="yes" LDFLAGS="${LDFLAGS} -L${with_intel_soft_cpm_libraries}" LIBS="${LIBS} -lpm" fi if test "x$enable_intel_soft_cpm" = "xyes"; then HAVE_INTEL_SOFT_CPM_TRUE= HAVE_INTEL_SOFT_CPM_FALSE='#' else HAVE_INTEL_SOFT_CPM_TRUE='#' HAVE_INTEL_SOFT_CPM_FALSE= fi if test "x$enable_intel_soft_cpm" = "xyes"; then CPPFLAGS="${CPPFLAGS} -DINTEL_SOFT_CPM" fi # Check whether --enable-shared_rep was given. if test "${enable_shared_rep+set}" = set; then : enableval=$enable_shared_rep; enable_shared_rep="$enableval" else enable_shared_rep="no" fi if test "x$enable_shared_rep" = "xyes"; then if test "x$linux" = "xyes"; then CPPFLAGS="${CPPFLAGS} -DSHARED_REP" LIBS="$LIBS -lrt" else echo "WARNING: shared reputation is only available on linux." enable_shared_rep="no" fi fi if test "x$enable_shared_rep" = "xyes"; then HAVE_SHARED_REP_TRUE= HAVE_SHARED_REP_FALSE='#' else HAVE_SHARED_REP_TRUE='#' HAVE_SHARED_REP_FALSE= fi # Define PKG_CHECK_MODULES if it doesnt already exist. #file_ This prevents './configure' from erroring on machines that dont have # 'pkgconfig' installed. #m4_ifdef([PKG_CHECK_MODULES],[], [m4_define([PKG_CHECK_MODULES], # [echo "PKG_CHECK_MODULES not defined"])]) # Check whether --enable-large-pcap was given. if test "${enable_large_pcap+set}" = set; then : enableval=$enable_large_pcap; enable_large_pcap="$enableval" else enable_large_pcap="no" fi if test "x$enable_large_pcap" = "xyes"; then CPPFLAGS="${CPPFLAGS} -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64" fi ################################################### ## [!] File Type Inspection (Experimental) ## ################################################### # Check whether --enable-file-inspect was given. if test "${enable_file_inspect+set}" = set; then : enableval=$enable_file_inspect; enable_file_inspect=$enableval else enable_file_inspect=no fi if test x$enable_file_inspect = xyes; then : $as_echo "#define FEAT_FILE_INSPECT 1" >>confdefs.h fi if test x$enable_file_inspect = xyes; then FEAT_FILE_INSPECT_TRUE= FEAT_FILE_INSPECT_FALSE='#' else FEAT_FILE_INSPECT_TRUE='#' FEAT_FILE_INSPECT_FALSE= fi export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH ###### Start OpenAppId # Check whether --enable-open-appid was given. if test "${enable_open_appid+set}" = set; then : enableval=$enable_open_appid; enable_open_appid="$enableval" else enable_open_appid="yes" fi if test "x$enable_open_appid" = "xyes"; then FEAT_OPEN_APPID_TRUE= FEAT_OPEN_APPID_FALSE='#' else FEAT_OPEN_APPID_TRUE='#' FEAT_OPEN_APPID_FALSE= fi if test "x$enable_open_appid" = "xyes"; then $as_echo "#define FEAT_OPEN_APPID 1" >>confdefs.h CONFIGFLAGS="$CONFIGFLAGS -DFEAT_OPEN_APPID" if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 $as_echo "$PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_PKG_CONFIG"; then ac_pt_PKG_CONFIG=$PKG_CONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG if test -n "$ac_pt_PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 $as_echo "$ac_pt_PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_PKG_CONFIG" = x; then PKG_CONFIG="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PKG_CONFIG=$ac_pt_PKG_CONFIG fi else PKG_CONFIG="$ac_cv_path_PKG_CONFIG" fi fi if test -n "$PKG_CONFIG"; then _pkg_min_version=0.9.0 { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 $as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } PKG_CONFIG="" fi fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for luajit" >&5 $as_echo_n "checking for luajit... " >&6; } if test -n "$luajit_CFLAGS"; then pkg_cv_luajit_CFLAGS="$luajit_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"luajit\""; } >&5 ($PKG_CONFIG --exists --print-errors "luajit") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_luajit_CFLAGS=`$PKG_CONFIG --cflags "luajit" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$luajit_LIBS"; then pkg_cv_luajit_LIBS="$luajit_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"luajit\""; } >&5 ($PKG_CONFIG --exists --print-errors "luajit") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_luajit_LIBS=`$PKG_CONFIG --libs "luajit" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then luajit_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "luajit" 2>&1` else luajit_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "luajit" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$luajit_PKG_ERRORS" >&5 LLUAJIT="no" elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } LLUAJIT="no" else luajit_CFLAGS=$pkg_cv_luajit_CFLAGS luajit_LIBS=$pkg_cv_luajit_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } LLUAJIT="yes" fi if test "x$LLUAJIT" = "xyes"; then CONFIGFLAGS="$CONFIGFLAGS -DHAVE_LIBLUAJIT" LUA_CFLAGS="$luajit_CFLAGS" LUA_LIBS="$luajit_LIBS" if test "x$macos" != "xno"; then LDFLAGS="${LDFLAGS} -pagezero_size 10000 -image_base 100000000" fi else echo echo " ERROR! LuaJIT library not found. Go get it from http://www.luajit.org/ (or)" echo " Try compiling without openAppId using '--disable-open-appid'" as_fn_error $? "\"Fatal!\"" "$LINENO" 5 fi ac_fn_c_check_header_mongrel "$LINENO" "openssl/x509.h" "ac_cv_header_openssl_x509_h" "$ac_includes_default" if test "x$ac_cv_header_openssl_x509_h" = xyes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for d2i_X509 in -lcrypto" >&5 $as_echo_n "checking for d2i_X509 in -lcrypto... " >&6; } if ${ac_cv_lib_crypto_d2i_X509+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypto $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char d2i_X509 (); int main () { return d2i_X509 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_crypto_d2i_X509=yes else ac_cv_lib_crypto_d2i_X509=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_d2i_X509" >&5 $as_echo "$ac_cv_lib_crypto_d2i_X509" >&6; } if test "x$ac_cv_lib_crypto_d2i_X509" = xyes; then : openssl_x509=yes else openssl_x509=no fi else openssl_x509=no fi if test "x$openssl_x509" = "xno"; then echo echo " ERROR! openssl/x509.h or openssl library not found." echo " Try compiling without openAppId using '--disable-open-appid'" as_fn_error $? "\"Fatal!\"" "$LINENO" 5 fi fi ###### End OpenAppId #include nghttp2 libs # Check whether --with-libnghttp2_includes was given. if test "${with_libnghttp2_includes+set}" = set; then : withval=$with_libnghttp2_includes; with_libnghttp2_includes="$withval" else with_libnghttp2_includes="no" fi # Check whether --with-libnghttp2_libraries was given. if test "${with_libnghttp2_libraries+set}" = set; then : withval=$with_libnghttp2_libraries; with_libnghttp2_libraries="$withval" else with_libnghttp2_libraries="no" fi if test "x$with_libnghttp2_includes" != "xno"; then CPPFLAGS="${CPPFLAGS} -I${with_libnghttp2_includes}" ICONFIGFLAGS="${ICONFIGFLAGS} -I${with_libnghttp2_includes}" fi if test "x$with_libnghttp2_libraries" != "xno"; then LDFLAGS="${LDFLAGS} -L${with_libnghttp2_libraries}" fi # Verify that we have the library NGHTTP_L="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nghttp2_option_new in -lnghttp2" >&5 $as_echo_n "checking for nghttp2_option_new in -lnghttp2... " >&6; } if ${ac_cv_lib_nghttp2_nghttp2_option_new+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnghttp2 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char nghttp2_option_new (); int main () { return nghttp2_option_new (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nghttp2_nghttp2_option_new=yes else ac_cv_lib_nghttp2_nghttp2_option_new=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nghttp2_nghttp2_option_new" >&5 $as_echo "$ac_cv_lib_nghttp2_nghttp2_option_new" >&6; } if test "x$ac_cv_lib_nghttp2_nghttp2_option_new" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBNGHTTP2 1 _ACEOF LIBS="-lnghttp2 $LIBS" else NGHTTP_L="no" fi if test "x$NGHTTP_L" = "xno"; then echo echo " Libnghttp2 library not found." echo " Get it from https://nghttp2.org/" echo fi CFLAGS="${CFLAGS} ${CCONFIGFLAGS}" CFLAGS=`echo $CFLAGS | sed -e 's/-I\/usr\/include //g'` CPPFLAGS="${CPPFLAGS} ${CONFIGFLAGS}" CPPFLAGS=`echo $CPPFLAGS | sed -e 's/-I\/usr\/include //g'` if test "x$GCC" = "xyes" ; then echo `$CC -v 2>&1` | grep "version 4" > /dev/null if test $? = 0 ; then CFLAGS="$CFLAGS -fno-strict-aliasing" fi fi if test "x$linux" = "xyes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for linuxthreads" >&5 $as_echo_n "checking for linuxthreads... " >&6; } tstr=`getconf GNU_LIBPTHREAD_VERSION 2>&1` if test $? = 0; then # GNU_LIBPTHREAD_VERSION is a valid system variable echo $tstr | grep -i linuxthreads > /dev/null 2>&1 if test $? = 0; then $as_echo "#define HAVE_LINUXTHREADS 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else # Use libc.so to see if linuxthreads is being used $( ldd `which --skip-alias ls` | grep libc.so | awk '{print $3}' ) | grep -i linuxthreads > /dev/null 2>&1 if test $? = 0; then $as_echo "#define HAVE_LINUXTHREADS 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test "$LEX" != "none"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for yylex_destroy support" >&5 $as_echo_n "checking for yylex_destroy support... " >&6; } version=`$LEX --version | awk '{print $3}'` if test -z $version; then version=`$LEX --version | awk '{print $2}'` fi have_yylex_destroy="no" if test $version; then major=`echo $version | awk -F. '{ print $1 }'` minor=`echo $version | awk -F. '{ print $2 }'` subminor=`echo $version | awk -F. '{ print $3 }'` if test $major -a $minor -a $subminor; then if test $major -gt 2; then have_yylex_destroy="yes" else if test $major -eq 2; then if test $minor -gt 5; then have_yylex_destroy="yes" else if test $minor -eq 5; then if test $subminor -ge 9; then have_yylex_destroy="yes" fi fi fi fi fi fi fi if test "x$have_yylex_destroy" = "xyes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HAVE_YYLEX_DESTROY 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi # Set to no optimization regardless of what user or autostuff set if test "x$NO_OPTIMIZE" = "xyes"; then CFLAGS=`echo $CFLAGS | sed -e "s/-O./-O0/"` # in case user override doesn't include -O if echo $CFLAGS | grep -qve -O0 ; then CFLAGS="$CFLAGS -O0" fi fi # Question: Does ICC not support -Wall (VJR - Jan 14, 2015) if test "$ICC" = "no"; then CFLAGS="$CFLAGS -Wall" fi echo $CFLAGS > cflags.out echo $CPPFLAGS > cppflags.out INCLUDES='-I$(top_srcdir) -I$(top_srcdir)/src -I$(top_srcdir)/src/sfutil $(extra_incl) -I$(top_srcdir)/src/output-plugins -I$(top_srcdir)/src/detection-plugins -I$(top_srcdir)/src/dynamic-plugins -I$(top_srcdir)/src/preprocessors -I$(top_srcdir)/src/preprocessors/portscan -I$(top_srcdir)/src/preprocessors/HttpInspect/include -I$(top_srcdir)/src/preprocessors/Session -I$(top_srcdir)/src/preprocessors/Stream6 -I$(top_srcdir)/src/target-based -I$(top_srcdir)/src/control -I$(top_srcdir)/src/file-process -I$(top_srcdir)/src/file-process/libs -I$(top_srcdir)/src/side-channel -I$(top_srcdir)/src/side-channel/plugins -I$(top_srcdir)/src/reload-adjust' ac_config_files="$ac_config_files snort.pc Makefile src/Makefile src/sfutil/Makefile src/control/Makefile src/file-process/Makefile src/file-process/libs/Makefile src/side-channel/Makefile src/side-channel/dynamic-plugins/Makefile src/side-channel/dynamic-plugins/snort_side_channel.pc src/side-channel/plugins/Makefile src/detection-plugins/Makefile src/dynamic-examples/Makefile src/dynamic-examples/dynamic-preprocessor/Makefile src/dynamic-examples/dynamic-rule/Makefile src/dynamic-plugins/Makefile src/dynamic-plugins/sf_engine/Makefile src/dynamic-plugins/sf_engine/examples/Makefile src/dynamic-plugins/sf_preproc_example/Makefile src/dynamic-preprocessors/Makefile src/dynamic-preprocessors/libs/Makefile src/dynamic-preprocessors/libs/snort_preproc.pc src/dynamic-preprocessors/ftptelnet/Makefile src/dynamic-preprocessors/smtp/Makefile src/dynamic-preprocessors/ssh/Makefile src/dynamic-preprocessors/sip/Makefile src/dynamic-preprocessors/reputation/Makefile src/dynamic-preprocessors/gtp/Makefile src/dynamic-preprocessors/dcerpc2/Makefile src/dynamic-preprocessors/pop/Makefile src/dynamic-preprocessors/imap/Makefile src/dynamic-preprocessors/sdf/Makefile src/dynamic-preprocessors/dns/Makefile src/dynamic-preprocessors/ssl/Makefile src/dynamic-preprocessors/modbus/Makefile src/dynamic-preprocessors/dnp3/Makefile src/dynamic-preprocessors/file/Makefile src/dynamic-preprocessors/appid/Makefile src/dynamic-output/Makefile src/dynamic-output/plugins/Makefile src/dynamic-output/libs/Makefile src/dynamic-output/libs/snort_output.pc src/output-plugins/Makefile src/preprocessors/Makefile src/preprocessors/HttpInspect/Makefile src/preprocessors/HttpInspect/include/Makefile src/preprocessors/HttpInspect/utils/Makefile src/preprocessors/HttpInspect/anomaly_detection/Makefile src/preprocessors/HttpInspect/client/Makefile src/preprocessors/HttpInspect/files/Makefile src/preprocessors/HttpInspect/event_output/Makefile src/preprocessors/HttpInspect/mode_inspection/Makefile src/preprocessors/HttpInspect/normalization/Makefile src/preprocessors/HttpInspect/server/Makefile src/preprocessors/HttpInspect/session_inspection/Makefile src/preprocessors/HttpInspect/user_interface/Makefile src/preprocessors/Session/Makefile src/preprocessors/Stream6/Makefile src/parser/Makefile src/target-based/Makefile doc/Makefile rpm/Makefile preproc_rules/Makefile m4/Makefile etc/Makefile templates/Makefile tools/Makefile tools/control/Makefile tools/u2boat/Makefile tools/u2spewfoo/Makefile tools/u2openappid/Makefile tools/u2streamer/Makefile tools/file_server/Makefile src/win32/Makefile src/reload-adjust/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs { $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 $as_echo_n "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 $as_echo "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_SNPRINTF_TRUE}" && test -z "${BUILD_SNPRINTF_FALSE}"; then as_fn_error $? "conditional \"BUILD_SNPRINTF\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_OPENSSL_MD5_TRUE}" && test -z "${BUILD_OPENSSL_MD5_FALSE}"; then as_fn_error $? "conditional \"BUILD_OPENSSL_MD5\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_OPENSSL_SHA_TRUE}" && test -z "${BUILD_OPENSSL_SHA_FALSE}"; then as_fn_error $? "conditional \"BUILD_OPENSSL_SHA\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${SO_WITH_STATIC_LIB_TRUE}" && test -z "${SO_WITH_STATIC_LIB_FALSE}"; then as_fn_error $? "conditional \"SO_WITH_STATIC_LIB\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_CONTROL_SOCKET_TRUE}" && test -z "${BUILD_CONTROL_SOCKET_FALSE}"; then as_fn_error $? "conditional \"BUILD_CONTROL_SOCKET\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_SIDE_CHANNEL_TRUE}" && test -z "${BUILD_SIDE_CHANNEL_FALSE}"; then as_fn_error $? "conditional \"BUILD_SIDE_CHANNEL\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_DYNAMIC_EXAMPLES_TRUE}" && test -z "${BUILD_DYNAMIC_EXAMPLES_FALSE}"; then as_fn_error $? "conditional \"BUILD_DYNAMIC_EXAMPLES\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_LZMA_TRUE}" && test -z "${HAVE_LZMA_FALSE}"; then as_fn_error $? "conditional \"HAVE_LZMA\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_TARGET_BASED_TRUE}" && test -z "${HAVE_TARGET_BASED_FALSE}"; then as_fn_error $? "conditional \"HAVE_TARGET_BASED\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_PROCPIDSTATS_TRUE}" && test -z "${BUILD_PROCPIDSTATS_FALSE}"; then as_fn_error $? "conditional \"BUILD_PROCPIDSTATS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_SNORT_RELOAD_TRUE}" && test -z "${BUILD_SNORT_RELOAD_FALSE}"; then as_fn_error $? "conditional \"BUILD_SNORT_RELOAD\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_HA_TRUE}" && test -z "${BUILD_HA_FALSE}"; then as_fn_error $? "conditional \"BUILD_HA\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_BUFFER_DUMP_TRUE}" && test -z "${BUILD_BUFFER_DUMP_FALSE}"; then as_fn_error $? "conditional \"BUILD_BUFFER_DUMP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_REACT_TRUE}" && test -z "${BUILD_REACT_FALSE}"; then as_fn_error $? "conditional \"BUILD_REACT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_RESPOND3_TRUE}" && test -z "${BUILD_RESPOND3_FALSE}"; then as_fn_error $? "conditional \"BUILD_RESPOND3\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_INTEL_SOFT_CPM_TRUE}" && test -z "${HAVE_INTEL_SOFT_CPM_FALSE}"; then as_fn_error $? "conditional \"HAVE_INTEL_SOFT_CPM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_SHARED_REP_TRUE}" && test -z "${HAVE_SHARED_REP_FALSE}"; then as_fn_error $? "conditional \"HAVE_SHARED_REP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${FEAT_FILE_INSPECT_TRUE}" && test -z "${FEAT_FILE_INSPECT_FALSE}"; then as_fn_error $? "conditional \"FEAT_FILE_INSPECT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${FEAT_OPEN_APPID_TRUE}" && test -z "${FEAT_OPEN_APPID_FALSE}"; then as_fn_error $? "conditional \"FEAT_OPEN_APPID\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by snort $as_me 2.9.15.1, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ snort config.status 2.9.15.1 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } # Quote evaled strings. for var in SHELL \ ECHO \ PATH_SEPARATOR \ SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ OBJDUMP \ deplibs_check_method \ file_magic_cmd \ file_magic_glob \ want_nocaseglob \ DLLTOOL \ sharedlib_from_linklib_cmd \ AR \ AR_FLAGS \ archiver_list_spec \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ nm_file_list_spec \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ lt_prog_compiler_wl \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ MANIFEST_TOOL \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_separator \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ install_override_mode \ finish_eval \ old_striplib \ striplib; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postlink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ sys_lib_dlsearch_path_spec; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done ac_aux_dir='$ac_aux_dir' xsi_shell='$xsi_shell' lt_shell_append='$lt_shell_append' # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "snort.pc") CONFIG_FILES="$CONFIG_FILES snort.pc" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "src/sfutil/Makefile") CONFIG_FILES="$CONFIG_FILES src/sfutil/Makefile" ;; "src/control/Makefile") CONFIG_FILES="$CONFIG_FILES src/control/Makefile" ;; "src/file-process/Makefile") CONFIG_FILES="$CONFIG_FILES src/file-process/Makefile" ;; "src/file-process/libs/Makefile") CONFIG_FILES="$CONFIG_FILES src/file-process/libs/Makefile" ;; "src/side-channel/Makefile") CONFIG_FILES="$CONFIG_FILES src/side-channel/Makefile" ;; "src/side-channel/dynamic-plugins/Makefile") CONFIG_FILES="$CONFIG_FILES src/side-channel/dynamic-plugins/Makefile" ;; "src/side-channel/dynamic-plugins/snort_side_channel.pc") CONFIG_FILES="$CONFIG_FILES src/side-channel/dynamic-plugins/snort_side_channel.pc" ;; "src/side-channel/plugins/Makefile") CONFIG_FILES="$CONFIG_FILES src/side-channel/plugins/Makefile" ;; "src/detection-plugins/Makefile") CONFIG_FILES="$CONFIG_FILES src/detection-plugins/Makefile" ;; "src/dynamic-examples/Makefile") CONFIG_FILES="$CONFIG_FILES src/dynamic-examples/Makefile" ;; "src/dynamic-examples/dynamic-preprocessor/Makefile") CONFIG_FILES="$CONFIG_FILES src/dynamic-examples/dynamic-preprocessor/Makefile" ;; "src/dynamic-examples/dynamic-rule/Makefile") CONFIG_FILES="$CONFIG_FILES src/dynamic-examples/dynamic-rule/Makefile" ;; "src/dynamic-plugins/Makefile") CONFIG_FILES="$CONFIG_FILES src/dynamic-plugins/Makefile" ;; "src/dynamic-plugins/sf_engine/Makefile") CONFIG_FILES="$CONFIG_FILES src/dynamic-plugins/sf_engine/Makefile" ;; "src/dynamic-plugins/sf_engine/examples/Makefile") CONFIG_FILES="$CONFIG_FILES src/dynamic-plugins/sf_engine/examples/Makefile" ;; "src/dynamic-plugins/sf_preproc_example/Makefile") CONFIG_FILES="$CONFIG_FILES src/dynamic-plugins/sf_preproc_example/Makefile" ;; "src/dynamic-preprocessors/Makefile") CONFIG_FILES="$CONFIG_FILES src/dynamic-preprocessors/Makefile" ;; "src/dynamic-preprocessors/libs/Makefile") CONFIG_FILES="$CONFIG_FILES src/dynamic-preprocessors/libs/Makefile" ;; "src/dynamic-preprocessors/libs/snort_preproc.pc") CONFIG_FILES="$CONFIG_FILES src/dynamic-preprocessors/libs/snort_preproc.pc" ;; "src/dynamic-preprocessors/ftptelnet/Makefile") CONFIG_FILES="$CONFIG_FILES src/dynamic-preprocessors/ftptelnet/Makefile" ;; "src/dynamic-preprocessors/smtp/Makefile") CONFIG_FILES="$CONFIG_FILES src/dynamic-preprocessors/smtp/Makefile" ;; "src/dynamic-preprocessors/ssh/Makefile") CONFIG_FILES="$CONFIG_FILES src/dynamic-preprocessors/ssh/Makefile" ;; "src/dynamic-preprocessors/sip/Makefile") CONFIG_FILES="$CONFIG_FILES src/dynamic-preprocessors/sip/Makefile" ;; "src/dynamic-preprocessors/reputation/Makefile") CONFIG_FILES="$CONFIG_FILES src/dynamic-preprocessors/reputation/Makefile" ;; "src/dynamic-preprocessors/gtp/Makefile") CONFIG_FILES="$CONFIG_FILES src/dynamic-preprocessors/gtp/Makefile" ;; "src/dynamic-preprocessors/dcerpc2/Makefile") CONFIG_FILES="$CONFIG_FILES src/dynamic-preprocessors/dcerpc2/Makefile" ;; "src/dynamic-preprocessors/pop/Makefile") CONFIG_FILES="$CONFIG_FILES src/dynamic-preprocessors/pop/Makefile" ;; "src/dynamic-preprocessors/imap/Makefile") CONFIG_FILES="$CONFIG_FILES src/dynamic-preprocessors/imap/Makefile" ;; "src/dynamic-preprocessors/sdf/Makefile") CONFIG_FILES="$CONFIG_FILES src/dynamic-preprocessors/sdf/Makefile" ;; "src/dynamic-preprocessors/dns/Makefile") CONFIG_FILES="$CONFIG_FILES src/dynamic-preprocessors/dns/Makefile" ;; "src/dynamic-preprocessors/ssl/Makefile") CONFIG_FILES="$CONFIG_FILES src/dynamic-preprocessors/ssl/Makefile" ;; "src/dynamic-preprocessors/modbus/Makefile") CONFIG_FILES="$CONFIG_FILES src/dynamic-preprocessors/modbus/Makefile" ;; "src/dynamic-preprocessors/dnp3/Makefile") CONFIG_FILES="$CONFIG_FILES src/dynamic-preprocessors/dnp3/Makefile" ;; "src/dynamic-preprocessors/file/Makefile") CONFIG_FILES="$CONFIG_FILES src/dynamic-preprocessors/file/Makefile" ;; "src/dynamic-preprocessors/appid/Makefile") CONFIG_FILES="$CONFIG_FILES src/dynamic-preprocessors/appid/Makefile" ;; "src/dynamic-output/Makefile") CONFIG_FILES="$CONFIG_FILES src/dynamic-output/Makefile" ;; "src/dynamic-output/plugins/Makefile") CONFIG_FILES="$CONFIG_FILES src/dynamic-output/plugins/Makefile" ;; "src/dynamic-output/libs/Makefile") CONFIG_FILES="$CONFIG_FILES src/dynamic-output/libs/Makefile" ;; "src/dynamic-output/libs/snort_output.pc") CONFIG_FILES="$CONFIG_FILES src/dynamic-output/libs/snort_output.pc" ;; "src/output-plugins/Makefile") CONFIG_FILES="$CONFIG_FILES src/output-plugins/Makefile" ;; "src/preprocessors/Makefile") CONFIG_FILES="$CONFIG_FILES src/preprocessors/Makefile" ;; "src/preprocessors/HttpInspect/Makefile") CONFIG_FILES="$CONFIG_FILES src/preprocessors/HttpInspect/Makefile" ;; "src/preprocessors/HttpInspect/include/Makefile") CONFIG_FILES="$CONFIG_FILES src/preprocessors/HttpInspect/include/Makefile" ;; "src/preprocessors/HttpInspect/utils/Makefile") CONFIG_FILES="$CONFIG_FILES src/preprocessors/HttpInspect/utils/Makefile" ;; "src/preprocessors/HttpInspect/anomaly_detection/Makefile") CONFIG_FILES="$CONFIG_FILES src/preprocessors/HttpInspect/anomaly_detection/Makefile" ;; "src/preprocessors/HttpInspect/client/Makefile") CONFIG_FILES="$CONFIG_FILES src/preprocessors/HttpInspect/client/Makefile" ;; "src/preprocessors/HttpInspect/files/Makefile") CONFIG_FILES="$CONFIG_FILES src/preprocessors/HttpInspect/files/Makefile" ;; "src/preprocessors/HttpInspect/event_output/Makefile") CONFIG_FILES="$CONFIG_FILES src/preprocessors/HttpInspect/event_output/Makefile" ;; "src/preprocessors/HttpInspect/mode_inspection/Makefile") CONFIG_FILES="$CONFIG_FILES src/preprocessors/HttpInspect/mode_inspection/Makefile" ;; "src/preprocessors/HttpInspect/normalization/Makefile") CONFIG_FILES="$CONFIG_FILES src/preprocessors/HttpInspect/normalization/Makefile" ;; "src/preprocessors/HttpInspect/server/Makefile") CONFIG_FILES="$CONFIG_FILES src/preprocessors/HttpInspect/server/Makefile" ;; "src/preprocessors/HttpInspect/session_inspection/Makefile") CONFIG_FILES="$CONFIG_FILES src/preprocessors/HttpInspect/session_inspection/Makefile" ;; "src/preprocessors/HttpInspect/user_interface/Makefile") CONFIG_FILES="$CONFIG_FILES src/preprocessors/HttpInspect/user_interface/Makefile" ;; "src/preprocessors/Session/Makefile") CONFIG_FILES="$CONFIG_FILES src/preprocessors/Session/Makefile" ;; "src/preprocessors/Stream6/Makefile") CONFIG_FILES="$CONFIG_FILES src/preprocessors/Stream6/Makefile" ;; "src/parser/Makefile") CONFIG_FILES="$CONFIG_FILES src/parser/Makefile" ;; "src/target-based/Makefile") CONFIG_FILES="$CONFIG_FILES src/target-based/Makefile" ;; "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; "rpm/Makefile") CONFIG_FILES="$CONFIG_FILES rpm/Makefile" ;; "preproc_rules/Makefile") CONFIG_FILES="$CONFIG_FILES preproc_rules/Makefile" ;; "m4/Makefile") CONFIG_FILES="$CONFIG_FILES m4/Makefile" ;; "etc/Makefile") CONFIG_FILES="$CONFIG_FILES etc/Makefile" ;; "templates/Makefile") CONFIG_FILES="$CONFIG_FILES templates/Makefile" ;; "tools/Makefile") CONFIG_FILES="$CONFIG_FILES tools/Makefile" ;; "tools/control/Makefile") CONFIG_FILES="$CONFIG_FILES tools/control/Makefile" ;; "tools/u2boat/Makefile") CONFIG_FILES="$CONFIG_FILES tools/u2boat/Makefile" ;; "tools/u2spewfoo/Makefile") CONFIG_FILES="$CONFIG_FILES tools/u2spewfoo/Makefile" ;; "tools/u2openappid/Makefile") CONFIG_FILES="$CONFIG_FILES tools/u2openappid/Makefile" ;; "tools/u2streamer/Makefile") CONFIG_FILES="$CONFIG_FILES tools/u2streamer/Makefile" ;; "tools/file_server/Makefile") CONFIG_FILES="$CONFIG_FILES tools/file_server/Makefile" ;; "src/win32/Makefile") CONFIG_FILES="$CONFIG_FILES src/win32/Makefile" ;; "src/reload-adjust/Makefile") CONFIG_FILES="$CONFIG_FILES src/reload-adjust/Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; "libtool":C) # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool 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. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # The names of the tagged configurations supported by this script. available_tags="" # ### BEGIN LIBTOOL CONFIG # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO # The PATH separator for the build system. PATH_SEPARATOR=$lt_PATH_SEPARATOR # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # convert \$build file names to \$host format. to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd # An object symbol dumper. OBJDUMP=$lt_OBJDUMP # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method = "file_magic". file_magic_cmd=$lt_file_magic_cmd # How to find potential files when deplibs_check_method = "file_magic". file_magic_glob=$lt_file_magic_glob # Find potential files using nocaseglob when deplibs_check_method = "file_magic". want_nocaseglob=$lt_want_nocaseglob # DLL creation program. DLLTOOL=$lt_DLLTOOL # Command to associate shared and link libraries. sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR # Flags to create an archive. AR_FLAGS=$lt_AR_FLAGS # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Whether to use a lock for old archive extraction. lock_old_archive_extraction=$lock_old_archive_extraction # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec # The root where to search for dependent libraries,and in which our libraries should be installed. lt_sysroot=$lt_sysroot # The name of the directory that contains temporary libtool files. objdir=$objdir # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Manifest tool. MANIFEST_TOOL=$lt_MANIFEST_TOOL # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Permission mode override for installation of shared libraries. install_override_mode=$lt_install_override_mode # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \${shlibpath_var} if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain="$ac_aux_dir/ltmain.sh" # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) if test x"$xsi_shell" = xyes; then sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ func_dirname ()\ {\ \ case ${1} in\ \ */*) func_dirname_result="${1%/*}${2}" ;;\ \ * ) func_dirname_result="${3}" ;;\ \ esac\ } # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_basename ()$/,/^} # func_basename /c\ func_basename ()\ {\ \ func_basename_result="${1##*/}"\ } # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ func_dirname_and_basename ()\ {\ \ case ${1} in\ \ */*) func_dirname_result="${1%/*}${2}" ;;\ \ * ) func_dirname_result="${3}" ;;\ \ esac\ \ func_basename_result="${1##*/}"\ } # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ func_stripname ()\ {\ \ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ \ # positional parameters, so assign one to ordinary parameter first.\ \ func_stripname_result=${3}\ \ func_stripname_result=${func_stripname_result#"${1}"}\ \ func_stripname_result=${func_stripname_result%"${2}"}\ } # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ func_split_long_opt ()\ {\ \ func_split_long_opt_name=${1%%=*}\ \ func_split_long_opt_arg=${1#*=}\ } # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ func_split_short_opt ()\ {\ \ func_split_short_opt_arg=${1#??}\ \ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ } # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ func_lo2o ()\ {\ \ case ${1} in\ \ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ \ *) func_lo2o_result=${1} ;;\ \ esac\ } # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_xform ()$/,/^} # func_xform /c\ func_xform ()\ {\ func_xform_result=${1%.*}.lo\ } # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_arith ()$/,/^} # func_arith /c\ func_arith ()\ {\ func_arith_result=$(( $* ))\ } # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_len ()$/,/^} # func_len /c\ func_len ()\ {\ func_len_result=${#1}\ } # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$lt_shell_append" = xyes; then sed -e '/^func_append ()$/,/^} # func_append /c\ func_append ()\ {\ eval "${1}+=\\${2}"\ } # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ func_append_quoted ()\ {\ \ func_quote_for_eval "${2}"\ \ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ } # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: # Save a `func_append' function call where possible by direct use of '+=' sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: else # Save a `func_append' function call even when '+=' is not available sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$_lt_function_replace_fail" = x":"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 $as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} fi mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi snort-2.9.15.1/configure.in0000444000175200017520000015136713571422606012373 00000000000000# $Id$ AC_INIT([snort], [m4_esyscmd_s([cat ./VERSION])]) AC_CONFIG_SRCDIR([src/snort.c]) AC_PREREQ(2.50) AM_CONFIG_HEADER(config.h) # When changing the snort version, please also update the VERSION # definition in "src/win32/WIN32-Includes/config.h" AM_INIT_AUTOMAKE(snort,2.9.15.1) NO_OPTIMIZE="no" AC_PROG_CC_STDC AC_PROG_CC AC_PROG_LIBTOOL AC_PROG_RANLIB AC_C_BIGENDIAN # AC_C_BIGENDIAN implicitly defines WORDS_BIGENDIAN, but the CCONFIGFLAGS also needs to be affected. if test "x$ac_cv_c_bigendian" = "xyes"; then CCONFIGFLAGS="${CCONFIGFLAGS} -DSF_BIGENDIAN" fi AC_C_INLINE #AC_CANONICAL_HOST linux="no" sunos4="no" macos="no" so_with_static_lib="yes" case "$host" in *-openbsd2.6|*-openbsd2.5|*-openbsd2.4|*-openbsd2.3*) AC_DEFINE([OPENBSD],[1],[Define if OpenBSD]) AC_DEFINE([BROKEN_SIOCGIFMTU],[1],[Define if BROKEN_SIOCGIFMTU]) so_with_static_lib="no" ;; *-openbsd*) AC_DEFINE([OPENBSD],[1],[Define if OpenBSD < 2.3]) so_with_static_lib="no" ;; *-sgi-irix5*) AC_DEFINE([IRIX],[1],[Define if Irix 5]) no_libsocket="yes" no_libnsl="yes" if test -z "$GCC"; then sgi_cc="yes" fi LDFLAGS="${LDFLAGS} -L/usr/local/lib" extra_incl="-I/usr/local/include" ;; *-sgi-irix6*) AC_DEFINE([IRIX],[1],[Define if Irix 6]) no_libsocket="yes" no_libnsl="yes" if test -z "$GCC"; then sgi_cc="yes" fi LDFLAGS="${LDFLAGS} -L/usr/local/lib" extra_incl="-I/usr/local/include" ;; *-solaris*) AC_DEFINE([SOLARIS],[1],[Define if Solaris]) CONFIGFLAGS="${CONFIGFLAGS} -DBSD_COMP -D_REENTRANT" rt_nanosleep="yes" ;; *-sunos*) AC_DEFINE([SUNOS],[1],[Define if SunOS]) sunos4="yes" ;; *-linux*) linux="yes" AC_DEFINE([LINUX],[1],[Define if Linux]) AC_SUBST(extra_incl) extra_incl="-I/usr/include/pcap" ;; *-hpux10*|*-hpux11*) AC_DEFINE([HPUX],[1],[Define if HP-UX 10 or 11]) if test "x$ac_cv_c_bigendian" = "xno"; then # exception to AC_C_BIGENDIAN and test "x$ac_cv_c_bigendian" = "xyes" above # causes the need for next three lines. AC_MSG_NOTICE([bigendian byte-order not detected but asserted for $host]) AC_DEFINE([WORDS_BIGENDIAN],[1],[Define if words are big endian]) CCONFIGFLAGS="${CCONFIGFLAGS} -DSF_BIGENDIAN" fi AC_SUBST(extra_incl) extra_incl="-I/usr/local/include" ;; *-freebsd*) AC_DEFINE([FREEBSD],[1],[Define if FreeBSD]) ;; *-bsdi*) AC_DEFINE([BSDI],[1],[Define if BSDi]) ;; *-aix*) AC_DEFINE([AIX],[1],[Define if AIX]) ;; *-osf4*) AC_DEFINE([OSF1],[1],[Define if OSF-4]) CONFIGFLAGS="${CONFIGFLAGS} -DOSF1" ;; *-osf5.1*) AC_DEFINE([OSF1],[1],[Define if OSF-5.1]) CONFIGFLAGS="${CONFIGFLAGS} -DOSF1" ;; *-tru64*) AC_DEFINE([OSF1],[1],[Define if Tru64]) CONFIGFLAGS="${CONFIGFLAGS} -DOSF1" ;; # it is actually -apple-darwin1.2 or -apple-rhapsody5.x but lets stick with this for the moment *-apple*) macos="yes" AC_DEFINE([MACOS],[1],[Define if MacOS]) AC_DEFINE([BROKEN_SIOCGIFMTU],[1],[Define if broken SIOCGIFMTU]) esac AC_HEADER_STDBOOL # ICC stuff ICC=no if eval "echo $CC | grep icc > /dev/null" ; then if eval "$CC -help | grep libcxa > /dev/null" ; then CFLAGS="$CFLAGS -static-libcxa" LDFLAGS="$LDFLAGS -static-libcxa" XCCFLAGS="-XCClinker -static-libcxa" else CFLAGS="$CFLAGS -static-intel" LDFLAGS="$LDFLAGS -static-intel" XCCFLAGS="-XCClinker -static-intel" fi #CFLAGS=`echo $CFLAGS | sed 's/-O2/-O3/'` CFLAGS="$CFLAGS -O3 -ip -w1" ICC=yes fi AC_SUBST(XCCFLAGS) # This is really meant for Solaris Sparc v9 where it has 32bit and 64bit # capability but builds 32bit by default AC_ARG_ENABLE(64bit-gcc, [ --enable-64bit-gcc Try to compile 64bit (only tested on Sparc Solaris 9 and 10).], enable_64bit_gcc="$enableval", enable_64bit_gcc="no") if test "x$enable_64bit_gcc" = "xyes"; then CFLAGS="$CFLAGS -m64" fi # AC_PROG_YACC defaults to "yacc" when not found # this check defaults to "none" AC_CHECK_PROGS(YACC,bison yacc,none) # AC_PROG_YACC includes the -y arg if bison is found if test "x$YACC" = "xbison"; then YACC="$YACC -y" fi # AC_PROG_LEX defaults to ":" when not found # this check defaults to "none" # We're using flex specific options so we don't support lex AC_CHECK_PROGS(LEX,flex,none) # dnl checking headers AC_CHECK_HEADERS([ \ inttypes.h \ math.h \ paths.h \ stdlib.h \ string.h \ strings.h \ unistd.h \ wchar.h \ sys/sockio.h \ ]) if test "x$ac_cv_header_wchar_h" = "xyes"; then CONFIGFLAGS="${CONFIGFLAGS} -DSF_WCHAR" fi AC_CHECK_LIB([m],[floor]) AC_CHECK_LIB([m],[ceil]) AC_CHECK_HEADERS(uuid/uuid.h, [AC_CHECK_LIB(uuid,uuid_parse)]) if test "x$rt_nanosleep" = "xyes"; then AC_CHECK_LIB([rt],[nanosleep]) fi dnl make sure we've got all our libraries if test -z "$no_libnsl"; then AC_CHECK_LIB(nsl, inet_ntoa) fi if test -z "$no_libsocket"; then AC_CHECK_LIB(socket, socket) fi # SunOS4 has several things `broken' if test "$sunos4" != "no"; then AC_CHECK_FUNCS(vsnprintf,, LIBS="$LIBS -ldb") AC_CHECK_FUNCS(strtoul,, LIBS="$LIBS -l44bsd") fi # some funky macro to be backwards compatible with earlier autoconfs # in current they have AC_CHECK_DECLS AC_DEFUN([SN_CHECK_DECL],[ AC_MSG_CHECKING([whether $1 must be declared]) AC_CACHE_VAL(sn_cv_decl_needed_$1, [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_STRINGS_H #include #endif #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #include #include #include ]], [[char *(*pfn); pfn = (char *(*)) $1;]])],[eval "sn_cv_decl_needed_$1=no"],[eval "sn_cv_decl_needed_$1=yes"]) ]) if eval "test \"`echo '$sn_cv_decl_needed_'$1`\" != no"; then AC_MSG_RESULT(yes) ifelse([$2], , :, [$2]) else AC_MSG_RESULT(no) ifelse([$3], , ,[$3]) fi ])dnl AC_DEFUN([SN_CHECK_DECLS], [for sn_decl in $1 do sn_def_decl=`echo $sn_decl | tr [a-z] [A-Z]` SN_CHECK_DECL($sn_decl, [ AC_DEFINE_UNQUOTED(NEED_DECL_$sn_def_decl, 1, [you have this cuz autoheader is dumb]) $2], $3)dnl done ]) # some stuff for declarations which were missed on sunos4 platform too. # # add `#undef NEED_DECL_FUNCTIONAME to acconfig.h` because autoheader # fails to work properly with custom macroses. # you will see also #undef for each SN_CHECK_DECLS macros invocation # because autoheader doesn't execute shell script commands. # it is possible to make loops using m4 but the code would look even # more confusing.. SN_CHECK_DECLS(printf fprintf syslog puts fputs fputc fopen \ fclose fwrite fflush getopt bzero bcopy memset strtol \ strcasecmp strncasecmp strerror perror socket sendto \ vsnprintf snprintf strtoul) AC_CHECK_FUNCS([sigaction strlcpy strlcat strerror vswprintf wprintf memrchr inet_ntop gettid]) AC_CHECK_FUNC([snprintf],[have_snprintf="yes"],[have_snprintf="no"]) AM_CONDITIONAL(BUILD_SNPRINTF, test "x$have_snprintf" != "xyes") if test "x$have_snprintf" = "xyes"; then AC_DEFINE([HAVE_SNPRINTF], [], [snprintf function is available]) fi AC_CHECK_FUNCS([malloc_trim mallinfo]) AC_CHECK_SIZEOF([char]) AC_CHECK_SIZEOF([short]) AC_CHECK_SIZEOF([int]) AC_CHECK_SIZEOF([long int]) AC_CHECK_SIZEOF([long long int]) AC_CHECK_SIZEOF([unsigned int]) AC_CHECK_SIZEOF([unsigned long int]) AC_CHECK_SIZEOF([unsigned long long int]) # Check for int types AC_CHECK_TYPES([u_int8_t,u_int16_t,u_int32_t,u_int64_t,uint8_t,uint16_t,uint32_t,uint64_t]) AC_CHECK_TYPES([int8_t,int16_t,int32_t,int64_t]) AC_CHECK_TYPES([boolean]) # In case INADDR_NONE is not defined (like on Solaris) have_inaddr_none="no" AC_MSG_CHECKING([for INADDR_NONE]) AC_RUN_IFELSE( [AC_LANG_PROGRAM( [[ #include #include #include ]], [[ if (inet_addr("10,5,2") == INADDR_NONE); return 0; ]])], [have_inaddr_none="yes"], [have_inaddr_none="no"]) AC_MSG_RESULT($have_inaddr_none) if test "x$have_inaddr_none" = "xno"; then AC_DEFINE([INADDR_NONE],[-1],[For INADDR_NONE definition]) fi AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[const char *foo; foo = sys_errlist[0];]])],[AC_DEFINE(ERRLIST_PREDEFINED,1,Define if errlist is predefined)],[]) AC_MSG_CHECKING(for __FUNCTION__) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[printf ("%s", __FUNCTION__);]])],[sn_cv_have___FUNCTION__=yes],[sn_cv__have___FUNCTION__=no]) if test "x$sn_cv_have___FUNCTION__" = "xyes"; then AC_MSG_RESULT(yes) AC_DEFINE([HAVE___FUNCTION__],[1],[Define if the compiler understands __FUNCTION__.]) else AC_MSG_RESULT(no) AC_MSG_CHECKING(for __func__) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[printf ("%s", __func__);]])],[sn_cv_have___func__=yes],[sn_cv__have___func__=no]) if test "x$sn_cv_have___func__" = "xyes"; then AC_MSG_RESULT(yes) AC_DEFINE([HAVE___func__],[1],[Define if the compiler understands __func__.]) AC_DEFINE([__FUNCTION__],[__func__],[Define __FUNCTION__ as required.]) else AC_MSG_RESULT(no) AC_DEFINE([__FUNCTION__],["mystery function"]) fi fi AC_ARG_WITH(libpcap_includes, [ --with-libpcap-includes=DIR libpcap include directory], [with_libpcap_includes="$withval"],[with_libpcap_includes="no"]) AC_ARG_WITH(libpcap_libraries, [ --with-libpcap-libraries=DIR libpcap library directory], [with_libpcap_libraries="$withval"],[with_libpcap_libraries="no"]) if test "x$with_libpcap_includes" != "xno"; then CPPFLAGS="${CPPFLAGS} -I${with_libpcap_includes}" fi if test "x$with_libpcap_libraries" != "xno"; then LDFLAGS="${LDFLAGS} -L${with_libpcap_libraries}" fi # --with-libpfring-* options AC_ARG_WITH(libpfring_includes, [ --with-libpfring-includes=DIR libpfring include directory], [with_libpfring_includes="$withval"],[with_libpfring_includes="no"]) AC_ARG_WITH(libpfring_libraries, [ --with-libpfring-libraries=DIR libpfring library directory], [with_libpfring_libraries="$withval"],[with_libpfring_libraries="no"]) if test "x$with_libpfring_includes" != "xno"; then CPPFLAGS="${CPPFLAGS} -I${with_libpfring_includes}" fi if test "x$with_libpfring_libraries" != "xno"; then LDFLAGS="${LDFLAGS} -L${with_libpfring_libraries}" fi AC_ARG_WITH(daq_includes, [ --with-daq-includes=DIR DAQ include directory], [with_daq_includes="$withval"],[with_daq_includes="no"]) AC_ARG_WITH(daq_libraries, [ --with-daq-libraries=DIR DAQ library directory], [with_daq_libraries="$withval"],[with_daq_libraries="no"]) if test "x$with_daq_includes" != "xno"; then CPPFLAGS="${CPPFLAGS} -I${with_daq_includes}" fi if test "x$with_daq_libraries" != "xno"; then LDFLAGS="${LDFLAGS} -L${with_daq_libraries}" fi if test "x$enable_control_socket" = "xyes"; then LSFBPF="" AC_CHECK_LIB([sfbpf], [sfbpf_compile], [LIBS="${LIBS} -lsfbpf"], [LSFBPF="no"], [ ]) if test "x$LSFBPF" = "xno"; then echo echo " ERROR! sfbpf library not found, go get it from" echo " http://www.snort.org/." #AC_MSG_ERROR("Fatal!") exit 1 fi fi LPCAP="" AC_CHECK_LIB(pcap, pcap_datalink,, LPCAP="no") # If the normal AC_CHECK_LIB for pcap fails then check to see if we are # using a pfring-enabled pcap. if test "x$LPCAP" = "xno"; then PFRING_H="" AC_CHECK_HEADERS(pfring.h,, PFRING_H="no") # It is important to have the AC_CHECK_LIB for the pfring library BEFORE # the one for pfring-enabled pcap. When the Makefile is created, all the # libraries used during linking are added to the LIBS variable in the # Makefile in the opposite order that their AC_CHECK_LIB macros appear # in configure.in. Durring linking, the pfring library (-lpfring) MUST come # _after_ the libpcap library (-lpcap) or linking will fail. PFRING_L="" AC_CHECK_LIB(pfring, pfring_open,, PFRING_L="no") LPFRING_PCAP="" AC_CHECK_LIB(pcap, pfring_open,, LPFRING_PCAP="no",-lpfring) fi # If both the AC_CHECK_LIB for normal pcap and pfring-enabled pcap fail then exit. if test "x$LPCAP" = "xno"; then if test "x$LPFRING_PCAP" = "xno"; then echo echo " ERROR! Libpcap library/headers (libpcap.a (or .so)/pcap.h)" echo " not found, go get it from http://www.tcpdump.org" echo " or use the --with-libpcap-* options, if you have it installed" echo " in unusual place. Also check if your libpcap depends on another" echo " shared library that may be installed in an unusual place" exit 1 fi fi AC_MSG_CHECKING([for pcap_lex_destroy]) AC_RUN_IFELSE( [AC_LANG_PROGRAM( [[ #include ]], [[ pcap_lex_destroy(); ]])], [have_pcap_lex_destroy="yes"], [have_pcap_lex_destroy="no"]) AC_MSG_RESULT($have_pcap_lex_destroy) if test "x$have_pcap_lex_destroy" = "xyes"; then AC_DEFINE([HAVE_PCAP_LEX_DESTROY],[1],[Can cleanup lex buffer stack created by pcap bpf filter]) fi AC_MSG_CHECKING([for pcap_lib_version]) AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[#include ]], [[pcap_lib_version();]] )], [have_pcap_lib_version="yes"], [have_pcap_lib_version="no"] ) AC_MSG_RESULT($have_pcap_lib_version) if test "x$have_pcap_lib_version" = "xyes"; then AC_DEFINE([HAVE_PCAP_LIB_VERSION],[1], [Can output the library version.]) fi AC_DEFUN([FAIL_MESSAGE],[ echo echo echo "**********************************************" echo " ERROR: unable to find" $1 echo " checked in the following places" for i in `echo $2`; do echo " $i" done echo "**********************************************" echo exit 1 ]) AC_ARG_WITH(libpcre_includes, [ --with-libpcre-includes=DIR libpcre include directory], [with_libpcre_includes="$withval"],[with_libpcre_includes="no"]) AC_ARG_WITH(libpcre_libraries, [ --with-libpcre-libraries=DIR libpcre library directory], [with_libpcre_libraries="$withval"],[with_libpcre_libraries="no"]) if test "x$with_libpcre_includes" != "xno"; then CPPFLAGS="${CPPFLAGS} -I${with_libpcre_includes}" ICONFIGFLAGS="${ICONFIGFLAGS} -I${with_libpcre_includes}" else CPPFLAGS="${CPPFLAGS} `pcre-config --cflags`" fi if test "x$with_libpcre_libraries" != "xno"; then LDFLAGS="${LDFLAGS} -L${with_libpcre_libraries}" else LDFLAGS="${LDFLAGS} `pcre-config --libs`" fi # PCRE configuration (required) # Verify that we have the headers PCRE_H="" AC_CHECK_HEADERS(pcre.h,, PCRE_H="no") if test "x$PCRE_H" = "xno"; then echo echo " ERROR! Libpcre header not found." echo " Get it from http://www.pcre.org" exit 1 fi # Verify that we have the library PCRE_L="" pcre_version_six="" AC_CHECK_LIB(pcre, pcre_compile, ,PCRE_L="no") if test "x$PCRE_L" = "xno"; then echo echo " ERROR! Libpcre library not found." echo " Get it from http://www.pcre.org" echo exit 1 else AC_MSG_CHECKING(for libpcre version 6.0 or greater) AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ #if (PCRE_MAJOR < 6) #error "Version failure" #else int a, b = 0, c = 0, d = 0; pcre *tmp = NULL; a = pcre_copy_named_substring(tmp, "", &b, c, "", "", d); #endif ]])],[pcre_version_six="yes"],[pcre_version_six="no"]) fi if test "x$pcre_version_six" != "xyes"; then AC_MSG_RESULT(no) echo echo " ERROR! Libpcre library version >= 6.0 not found." echo " Get it from http://www.pcre.org" echo exit 1 else AC_MSG_RESULT(yes) fi # OPENSSL SHA configuration (optional) AC_ARG_WITH(openssl_includes, [ --with-openssl-includes=DIR openssl include directory], [with_openssl_includes="$withval"],[with_openssl_includes="no"]) AC_ARG_WITH(openssl_libraries, [ --with-openssl-libraries=DIR openssl library directory], [with_openssl_libraries="$withval"],[with_openssl_libraries="no"]) if test "x$with_openssl_includes" != "xno"; then CPPFLAGS="${CPPFLAGS} -I${with_openssl_includes}" ICONFIGFLAGS="${ICONFIGFLAGS} -I${with_openssl_includes}" fi if test "x$with_openssl_libraries" != "xno"; then LDFLAGS="${LDFLAGS} -L${with_openssl_libraries}" fi # Verify that we have the headers AC_CHECK_LIB([crypto],[SHA256_Init],AC_DEFINE([HAVE_OPENSSL_SHA],[1],openssl SHA available),) AC_CHECK_LIB([crypto],[MD5_Init],AC_DEFINE([HAVE_OPENSSL_MD5],[1],openssl MD5 available),) AM_CONDITIONAL([BUILD_OPENSSL_MD5], test "$ac_cv_lib_crypto_MD5_Init" != "yes" ) AM_CONDITIONAL([BUILD_OPENSSL_SHA], test "$ac_cv_lib_crypto_SHA256_Init" != "yes" ) if test "$ac_cv_lib_crypto_MD5_Init" = "yes"; then LIBS="${LIBS} -lcrypto" fi AC_ARG_VAR(SIGNAL_SNORT_RELOAD, set the SIGNAL_SNORT_RELOAD value) if test "x$SIGNAL_SNORT_RELOAD" != "x" ; then AC_DEFINE_UNQUOTED([SIGNAL_SNORT_RELOAD], [$SIGNAL_SNORT_RELOAD], [Set by user]) fi AC_ARG_VAR(SIGNAL_SNORT_DUMP_STATS, set the SIGNAL_SNORT_DUMP_STATS value) if test "x$SIGNAL_SNORT_DUMP_STATS" != "x" ; then AC_DEFINE_UNQUOTED([SIGNAL_SNORT_DUMP_STATS], [$SIGNAL_SNORT_DUMP_STATS], [Set by user]) fi AC_ARG_VAR(SIGNAL_SNORT_ROTATE_STATS, set the SIGNAL_SNORT_ROTATE_STATS value) if test "x$SIGNAL_SNORT_ROTATE_STATS" != "x" ; then AC_DEFINE_UNQUOTED([SIGNAL_SNORT_ROTATE_STATS], [$SIGNAL_SNORT_ROTATE_STATS], [Set by user]) fi AC_ARG_VAR(SIGNAL_SNORT_READ_ATTR_TBL, set the SIGNAL_SNORT_READ_ATTR_TBL value) if test "x$SIGNAL_SNORT_READ_ATTR_TBL" != "x" ; then AC_DEFINE_UNQUOTED([SIGNAL_SNORT_READ_ATTR_TBL], [$SIGNAL_SNORT_READ_ATTR_TBL], [Set by user]) fi AC_ARG_ENABLE(so_with_static_lib, [ --enable-so-with-static-lib Enable linking of dynamically loaded preprocessors with a static preprocessor library], enable_so_with_static_lib="$enableval", enable_so_with_static_lib=$so_with_static_lib) AM_CONDITIONAL(SO_WITH_STATIC_LIB, test "x$enable_so_with_static_lib" = "xyes") AC_ARG_ENABLE(control_socket, [ --enable-control-socket Enable the control socket], enable_control_socket="$enableval", enable_control_socket="no") os=`(uname -s)` if test "x$linux" != "xyes"; then if test "$OSTYPE" != "FreeBSD" && "$os" != "FreeBSD"; then if test "x$enable_control_socket" = "xyes"; then AC_MSG_WARN([[The control socket is only supported on Linux or FreeBSD systems.]]) enable_control_socket="no" fi fi fi AM_CONDITIONAL(BUILD_CONTROL_SOCKET, test "x$enable_control_socket" = "xyes") if test "x$enable_control_socket" = "xyes"; then CONFIGFLAGS="$CONFIGFLAGS -DCONTROL_SOCKET" fi AC_ARG_ENABLE(side_channel, [ --enable-side-channel Enable the side channel (Experimental)], enable_side_channel="$enableval", enable_side_channel="no") if test "x$linux" != "xyes"; then if test "$OSTYPE" != "FreeBSD" && "$os" != "FreeBSD"; then if test "x$enable_side_channel" = "xyes"; then AC_MSG_WARN([[The side channel is only supported on Linux or FreeBSD systems.]]) enable_side_channel="no" fi fi fi AM_CONDITIONAL(BUILD_SIDE_CHANNEL, test "x$enable_side_channel" = "xyes") if test "x$enable_side_channel" = "xyes"; then CONFIGFLAGS="$CONFIGFLAGS -DSIDE_CHANNEL" fi # check for dnet first since some DAQs need it AC_ARG_WITH(dnet_includes, [ --with-dnet-includes=DIR libdnet include directory], [with_dnet_includes="$withval"],[with_dnet_includes="no"]) AC_ARG_WITH(dnet_libraries, [ --with-dnet-libraries=DIR libdnet library directory], [with_dnet_libraries="$withval"],[with_dnet_libraries="no"]) if test "x$with_dnet_includes" != "xno"; then CPPFLAGS="${CPPFLAGS} -I${with_dnet_includes}" ICONFIGFLAGS="${ICONFIGFLAGS} -I${with_dnet_includes}" else CPPFLAGS="${CPPFLAGS} `dnet-config --cflags 2>/dev/null`" fi if test "x$with_dnet_libraries" != "xno"; then LDFLAGS="${LDFLAGS} -L${with_dnet_libraries}" else LDFLAGS="${LDFLAGS} `dnet-config --libs 2>/dev/null`" fi AC_CHECK_HEADERS(dnet.h,,DNET_H="no") AC_CHECK_HEADERS(dumbnet.h,,DUMBNET_H="no") if test "x$DNET_H" = "xno" -a "x$DUMBNET_H" = "xno"; then echo echo " ERROR! dnet header not found, go get it from" echo " http://code.google.com/p/libdnet/ or use the --with-dnet-*" echo " options, if you have it installed in an unusual place" exit fi AC_CHECK_LIB(dnet, eth_set,,[DNET="no"]) AC_CHECK_LIB(dumbnet, eth_set,,[DUMBNET="no"]) if test "x$DNET" = "xno" -a "x$DUMBNET" = "xno"; then echo echo " ERROR! dnet library not found, go get it from" echo " http://code.google.com/p/libdnet/ or use the --with-dnet-*" echo " options, if you have it installed in an unusual place" exit fi AC_ARG_ENABLE(static_daq, [ --disable-static-daq Link static DAQ modules.], enable_static_daq="$enableval", enable_static_daq="yes") AC_CHECK_LIB(dl, dlsym, DLLIB="yes", DLLIB="no") if test "$DLLIB" != "no"; then LIBS="${LIBS} -ldl" else AC_CHECK_LIB(c, dlsym, DLLIB="yes", DLLIB="no") if test "$DLLIB" = "no"; then echo echo " ERROR! programmatic interface to dynamic link loader" echo " not found. Cannot build Snort." echo exit 1 fi fi if test "x$enable_static_daq" = "xyes"; then LDAQ="" LIBS="${LIBS} `daq-modules-config --static --libs`" AC_CHECK_LIB([daq_static], [daq_load_modules], [LIBS="-ldaq_static ${LIBS}"], [LDAQ="no"], [ ]) if test "x$LDAQ" = "xno"; then echo echo " ERROR! daq_static library not found, go get it from" echo " http://www.snort.org/." #AC_MSG_ERROR("Fatal!") # FIXTHIS switch over to this macro exit 1 # instead of raw exits! fi else LDAQ="" AC_CHECK_LIB([daq], [daq_load_modules], [LIBS="${LIBS} -ldaq"], [LDAQ="no"], [ ]) if test "x$LDAQ" = "xno"; then echo echo " ERROR! daq library not found, go get it from" echo " http://www.snort.org/." #AC_MSG_ERROR("Fatal!") exit 1 fi fi AC_CHECK_FUNCS([daq_hup_apply] [daq_acquire_with_meta] [daq_dp_add_dc]) AC_MSG_CHECKING([for daq real addresses]) AC_RUN_IFELSE( [AC_LANG_PROGRAM( [[ #include ]], [[ DAQ_PktHdr_t hdr; hdr.n_real_dPort = 0; ]])], [have_daq_real_addresses="yes"], [have_daq_real_addresses="no"]) AC_MSG_RESULT($have_daq_real_addresses) if test "x$have_daq_real_addresses" = "xyes"; then AC_DEFINE([HAVE_DAQ_REAL_ADDRESSES],[1], [DAQ version supports real addresses in header.]) fi AC_CHECK_DECL([DAQ_PKT_FLAG_DECRYPTED_SSL], [have_daq_decrypted_ssl="yes"], [have_daq_decrypted_ssl="no"], [#include ]) if test "x$have_daq_decrypted_ssl" = "xyes"; then AC_DEFINE([HAVE_DAQ_DECRYPTED_SSL],[1], [DAQ version supports decrypted ssl]) fi AC_CHECK_DECL([DAQ_PKT_FLAG_LOCALLY_ORIGINATED], [have_daq_locally_originated="yes"], [have_daq_locally_originated="no"], [#include ]) if test "x$have_daq_locally_originated" = "xyes"; then AC_DEFINE([HAVE_DAQ_LOCALLY_ORIGINATED],[1], [DAQ version defines flags for locally originated traffic]) fi AC_CHECK_DECL([DAQ_PKT_FLAG_LOCALLY_DESTINED], [have_daq_locally_destined="yes"], [have_daq_locally_destined="no"], [#include ]) if test "x$have_daq_locally_destined" = "xyes"; then AC_DEFINE([HAVE_DAQ_LOCALLY_DESTINED],[1], [DAQ version defines flags for locally destined traffic]) fi if test "x$ac_cv_func_daq_dp_add_dc" = "xyes"; then AC_CHECK_MEMBER([struct _DAQ_DP_key_t.sa.src_ip4],[],[DAQ_C99_STRUCT="no"],[#include ]) if test "x$DAQ_C99_STRUCT" = "xno" ; then echo echo " ERROR! daq library missing C99 patch, upgrade to >=2.0.4, go get it from" echo " http://www.snort.org/." exit 1 fi fi AC_MSG_CHECKING([for daq address space ID]) AC_RUN_IFELSE( [AC_LANG_PROGRAM( [[ #include ]], [[ DAQ_PktHdr_t hdr; hdr.address_space_id = 0; ]])], [have_daq_address_space_id="yes"], [have_daq_address_space_id="no"]) AC_MSG_RESULT($have_daq_address_space_id) if test "x$have_daq_address_space_id" = "xyes"; then AC_DEFINE([HAVE_DAQ_ADDRESS_SPACE_ID],[1], [DAQ version supports address space ID in header.]) fi AC_MSG_CHECKING([for daq flow ID]) AC_RUN_IFELSE( [AC_LANG_PROGRAM( [[ #include ]], [[ DAQ_PktHdr_t hdr; hdr.flow_id = 0; ]])], [have_daq_flow_id="yes"], [have_daq_flow_id="no"]) AC_MSG_RESULT($have_daq_flow_id) if test "x$have_daq_flow_id" = "xyes"; then AC_DEFINE([HAVE_DAQ_FLOW_ID],[1], [DAQ version supports flow ID in header.]) fi AC_MSG_CHECKING([for daq extended flow modifiers]) AC_RUN_IFELSE( [AC_LANG_PROGRAM( [[ #include ]], [[ DAQ_ModFlow_t mod; mod.type = 0; mod.length = 0; mod.value = NULL; ]])], [have_daq_ext_modflow="yes"], [have_daq_ext_modflow="no"]) AC_MSG_RESULT($have_daq_ext_modflow) if test "x$have_daq_ext_modflow" = "xyes"; then CCONFIGFLAGS="${CCONFIGFLAGS} -DHAVE_DAQ_EXT_MODFLOW" AC_DEFINE([HAVE_DAQ_EXT_MODFLOW],[1], [DAQ version supports extended flow modifiers.]) fi AC_MSG_CHECKING([for daq query flow]) AC_RUN_IFELSE( [AC_LANG_PROGRAM( [[ #include ]], [[ DAQ_QueryFlow_t mod; mod.type = 0; mod.length = 0; mod.value = NULL; ]])], [have_daq_queryflow="yes"], [have_daq_queryflow="no"]) AC_MSG_RESULT($have_daq_queryflow) if test "x$have_daq_queryflow" = "xyes"; then CCONFIGFLAGS="${CCONFIGFLAGS} -DHAVE_DAQ_QUERYFLOW" AC_DEFINE([HAVE_DAQ_QUERYFLOW],[1], [DAQ version supports query flow.]) fi AC_MSG_CHECKING([for daq data channel flags]) AC_RUN_IFELSE( [AC_LANG_PROGRAM( [[ #include ]], [[ DAQ_Data_Channel_Params_t params; ]])], [have_daq_data_channel_flags="yes"], [have_daq_data_channel_flags="no"]) AC_MSG_RESULT($have_daq_data_channel_flags) if test "x$have_daq_data_channel_flags" = "xyes"; then CCONFIGFLAGS="${CCONFIGFLAGS} -DHAVE_DAQ_DATA_CHANNEL_PARAMS" AC_DEFINE([HAVE_DAQ_DATA_CHANNEL_PARAMS],[1], [DAQ version supports data channel.]) fi AC_MSG_CHECKING([for separate IP versions on pinhole endpoints]) AC_RUN_IFELSE( [AC_LANG_PROGRAM( [[ #include ]], [[ DAQ_DP_key_t dpKey; dpKey.src_af = 0; ]])], [have_daq_data_channel_separate_ip_versions="yes"], [have_daq_data_channel_separate_ip_versions="no"]) AC_MSG_RESULT($have_daq_data_channel_separate_ip_versions) if test "x$have_daq_data_channel_separate_ip_versions" = "xyes"; then CCONFIGFLAGS="${CCONFIGFLAGS} -DHAVE_DAQ_DATA_CHANNEL_SEPARATE_IP_VERSIONS" AC_DEFINE([HAVE_DAQ_DATA_CHANNEL_SEPARATE_IP_VERSIONS],[1], [DAQ version supports separate IP versions on pinhole endpoints.]) fi AC_MSG_CHECKING([for DAQ_VERDICT_RETRY]) AC_RUN_IFELSE( [AC_LANG_PROGRAM( [[ #include ]], [[ DAQ_Verdict verdict; verdict = DAQ_VERDICT_RETRY; ]])], [have_daq_verdict_retry="yes"], [have_daq_verdict_retry="no"]) AC_MSG_RESULT($have_daq_verdict_retry) if test "x$have_daq_verdict_retry" = "xyes"; then AC_DEFINE([HAVE_DAQ_VERDICT_RETRY],[1], [DAQ version supports DAQ_VERDICT_RETRY in DAQ_Verdict.]) fi AC_MSG_CHECKING([for daq packet trace]) AC_RUN_IFELSE( [AC_LANG_PROGRAM( [[ #include ]], [[ DAQ_PktHdr_t hdr; hdr.flags = DAQ_PKT_FLAG_TRACE_ENABLED; ]])], [have_daq_packet_trace="yes"], [have_daq_packet_trace="no"]) AC_MSG_RESULT($have_daq_packet_trace) if test "x$have_daq_packet_trace" = "xyes"; then AC_DEFINE([HAVE_DAQ_PKT_TRACE],[1], [DAQ version supports packet trace.]) else echo "DAQ version doesn't support packet trace." fi AC_MSG_CHECKING([for daq verdict reason]) AC_RUN_IFELSE( [AC_LANG_PROGRAM( [[ #include ]], [[ DAQ_ModFlow_t fl; fl.type = DAQ_MODFLOW_TYPE_VER_REASON; ]])], [have_daq_verdict_reason="yes"], [have_daq_verdict_reason="no"]) AC_MSG_RESULT($have_daq_verdict_reason) if test "x$have_daq_verdict_reason" = "xyes"; then AC_DEFINE([HAVE_DAQ_VERDICT_REASON],[1], [DAQ version supports tracing verdict reason.]) else echo "DAQ version doesn't support tracing verdict reason." fi # any sparc platform has to have this one defined. AC_MSG_CHECKING(for sparc) if eval "echo $host_cpu|grep -i sparc >/dev/null"; then AC_DEFINE([WORDS_MUSTALIGN],[1],[Define if words must align]) AC_MSG_RESULT(yes) # gcc, sparc and optimization not so good if test -n "$GCC"; then NO_OPTIMIZE="yes" fi else AC_MSG_RESULT(no) fi # check for sparc %time register if eval "echo $host_cpu|grep -i sparc >/dev/null"; then OLD_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -mcpu=v9 " AC_MSG_CHECKING([for sparc %time register]) AC_RUN_IFELSE( [AC_LANG_PROGRAM( [[]], [[ int val; __asm__ __volatile__("rd %%tick, %0" : "=r"(val)); ]])], [sparcv9="yes"], [sparcv9="no"]) AC_MSG_RESULT($sparcv9) if test "x$sparcv9" = "xyes"; then AC_DEFINE([SPARCV9],[1],[For sparc v9 with %time register]) else CFLAGS="$OLD_CFLAGS" fi fi # modified from gnulib/m4/visibility.m4 AC_DEFUN([CC_VISIBILITY], [ AC_REQUIRE([AC_PROG_CC]) AC_MSG_CHECKING([for visibility support]) AC_CACHE_VAL(gl_cv_cc_visibility, [ gl_save_CFLAGS="$CFLAGS" # Add -Werror flag since some compilers, e.g. icc 7.1, don't support it, # but only warn about it instead of compilation failing CFLAGS="$CFLAGS -Werror -fvisibility=hidden" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ extern __attribute__((__visibility__("hidden"))) int hiddenvar; extern __attribute__((__visibility__("default"))) int exportedvar; extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void); extern __attribute__((__visibility__("default"))) int exportedfunc (void);]], [[]])], [gl_cv_cc_visibility="yes"], [gl_cv_cc_visibility="no"]) ]) AC_MSG_RESULT([$gl_cv_cc_visibility]) CFLAGS="$gl_save_CFLAGS" if test "x$gl_cv_cc_visibility" = "xyes"; then CFLAGS="${CFLAGS} -DSF_VISIBILITY -fvisibility=hidden" AC_DEFINE([HAVE_VISIBILITY],[1], [Define if the compiler supports visibility declarations.]) fi ]) CC_VISIBILITY() AC_ARG_ENABLE(build-dynamic-examples, [ --enable-build-dynamic-examples Enable building of example dynamically loaded preprocessor and rule (off by default)], build_dynamic_examples="$enableval", build_dynamic_examples="no") AM_CONDITIONAL(BUILD_DYNAMIC_EXAMPLES, test "x$build_dynamic_examples" = "xyes") AC_ARG_ENABLE(dlclose, [ --disable-dlclose Only use if you are developing dynamic preprocessors or shared object rules. Disable (--disable-dlclose) for testing valgrind leaks in dynamic libraries so a usable backtrace is reported. Enabled by default.], enable_dlclose="$enableval", enable_dlclose="yes") if test "x$enable_dlclose" = "xno"; then AC_DEFINE([DISABLE_DLCLOSE_FOR_VALGRIND_TESTING],[1],[Don't close opened shared objects for valgrind leak testing of dynamic libraries]) fi ################################################## # Fedora 28+ does not have inbuilt SunRPC support# # in glibc and is separately availble in tirpc # # package. Make sure we've got the library and # # link it # ################################################## if test -f /etc/fedora-release ; then DISTRO_VERSION=$(awk '{ print $3 }' /etc/fedora-release) if test $DISTRO_VERSION -ge 28 ; then TIRPC="" AC_CHECK_LIB(tirpc,bindresvport,, TIRPC="no") echo "$TIRPC" if test "x$TIRPC" = "xno"; then echo echo " ERROR! tirpc not found, get it by running " echo " yum install libtirpc-devel " exit fi LIBS="${LIBS} -ltirpc" extra_incl="-I/usr/include/tirpc" fi fi Z_LIB="" AC_CHECK_HEADERS(zlib.h,, Z_LIB="no") if test "x$Z_LIB" = "xno"; then echo echo " ERROR! zlib header not found, go get it from" echo " http://www.zlib.net" exit fi Z_LIB="" AC_CHECK_LIB(z, inflate,, Z_LIB="no") if test "x$Z_LIB" = "xno"; then echo echo " ERROR! zlib library not found, go get it from" echo " http://www.zlib.net" exit fi LIBS="$LIBS -lz" AC_ARG_ENABLE(lzma, [ --disable-lzma Disable LZMA Decompression], enable_lzma="$enableval", enable_lzma="yes") AC_ARG_WITH(lzma_includes, [ --with-lzma-includes=DIR liblzma include directory], [with_lzma_includes="$withval"],[with_lzma_includes="no"]) AC_ARG_WITH(lzma_libraries, [ --with-lzma-libraries=DIR liblzma library directory], [with_lzma_libraries="$withval"],[with_lzma_libraries="no"]) AM_CONDITIONAL(HAVE_LZMA, test "x$enable_lzma" = "xyes") if test "x$enable_lzma" = "xyes"; then if test "x$with_lzma_includes" != "xno"; then CPPFLAGS="${CPPFLAGS} -I${with_lzma_includes}" LZMA_HEADERS="yes" else AC_CHECK_HEADERS(lzma.h, LZMA_HEADERS="yes", LZMA_HEADERS="no") fi if test "x$with_lzma_libraries" != "xno"; then LDFLAGS="${LDFLAGS} -L${with_lzma_libraries}" LZMA_LIB="yes" else AC_CHECK_LIB(lzma, lzma_stream_decoder, LZMA_LIB="yes", LZMA_LIB="no") fi if test "x$LZMA_LIB" != "xno"; then if test "x$LZMA_HEADERS" != "xno"; then CPPFLAGS="$CPPFLAGS -DLZMA" LIBS="$LIBS -llzma" fi fi fi AC_ARG_ENABLE(gre, [ --disable-gre Disable GRE and IP in IP encapsulation support], enable_gre="$enableval", enable_gre="yes") if test "x$enable_gre" = "xyes"; then CPPFLAGS="$CPPFLAGS -DGRE" fi AC_ARG_ENABLE(mpls, [ --disable-mpls Disable MPLS support], enable_mpls="$enableval", enable_mpls="yes") if test "x$enable_mpls" = "xyes"; then CPPFLAGS="$CPPFLAGS -DMPLS" fi AC_ARG_ENABLE(targetbased, [ --disable-targetbased Disable Target-Based Support in Stream, Frag, and Rules (adds pthread support implicitly)], enable_targetbased="$enableval", enable_targetbased="yes") AM_CONDITIONAL(HAVE_TARGET_BASED, test "x$enable_targetbased" = "xyes") if test "x$enable_targetbased" = "xyes"; then CONFIGFLAGS="$CONFIGFLAGS -DTARGET_BASED" LIBS="$LIBS -lpthread" if test "$LEX" = "none"; then echo echo " ERROR! flex not found." echo " Get it from http://flex.sourceforge.net/" echo " (You may also try lex instead.)" echo exit 1 fi if test "$YACC" = "none"; then echo echo " ERROR! bison not found." echo " Get it from http://www.gnu.org/software/bison/" echo " (You may also try byacc or yacc instead.)" echo exit 1 fi fi AC_ARG_ENABLE(ppm, [ --disable-ppm Disable packet/rule performance monitor], enable_ppm="$enableval", enable_ppm="yes") if test "x$enable_ppm" = "xyes"; then CPPFLAGS="$CPPFLAGS -DPPM_MGR" fi AC_ARG_ENABLE(perfprofiling, [ --disable-perfprofiling Disable preprocessor and rule performance profiling], enable_perfprofiling="$enableval", enable_perfprofiling="yes") if test "x$enable_perfprofiling" = "xyes"; then CONFIGFLAGS="$CONFIGFLAGS -DPERF_PROFILING" fi AC_ARG_ENABLE(linux-smp-stats, [ --enable-linux-smp-stats Enable statistics reporting through proc], enable_linux_smp_stats="$enableval", enable_linux_smp_stats="no") AM_CONDITIONAL(BUILD_PROCPIDSTATS, test "x$enable_linux_smp_stats" = "xyes") if test "x$enable_linux_smp_stats" = "xyes"; then CPPFLAGS="$CPPFLAGS -DLINUX_SMP" fi AC_ARG_ENABLE(inline-init-failopen, [ --enable-inline-init-failopen Enable Fail Open during initialization for Inline Mode (adds pthread support implicitly)], enable_inline_init_failopen="$enableval", enable_inline_init_failopen="no") if test "x$enable_inline_init_failopen" = "xyes"; then CPPFLAGS="$CPPFLAGS -DINLINE_FAILOPEN" LIBS="$LIBS -lpthread" fi AC_ARG_ENABLE(pthread, [ --disable-pthread Disable pthread support], enable_pthread="$enableval", enable_pthread="yes") if test "x$enable_pthread" = "xyes"; then LIBS="$LIBS -lpthread" AC_CHECK_FUNCS([pthread_tryjoin_np]) fi AC_ARG_ENABLE(debug-msgs, [ --enable-debug-msgs Enable debug printing options (bugreports and developers only)], enable_debug_msgs="$enableval", enable_debug_msgs="no") if test "x$enable_debug_msgs" = "xyes"; then CPPFLAGS="$CPPFLAGS -DDEBUG_MSGS" fi AC_ARG_ENABLE(debug, [ --enable-debug Enable debugging options (bugreports and developers only)], enable_debug="$enableval", enable_debug="no") if test "x$enable_debug" = "xyes"; then NO_OPTIMIZE="yes" # in case user override doesn't include -g if echo $CFLAGS | grep -qve -g ; then CFLAGS="$CFLAGS -g" fi CPPFLAGS="$CPPFLAGS -DDEBUG" else # disable assert()ions CPPFLAGS="$CPPFLAGS -DNDEBUG" fi AC_ARG_ENABLE(gdb, [ --enable-gdb Enable gdb debugging information], enable_gdb="$enableval", enable_gdb="no") if test "x$enable_gdb" = "xyes"; then CFLAGS="$CFLAGS -g -ggdb" fi AC_ARG_ENABLE(profile, [ --enable-profile Enable profiling options (developers only)], enable_profile="$enableval", enable_profile="no") if test "x$enable_profile" = "xyes"; then if test -n "$GCC"; then CPPFLAGS="$CPPFLAGS -DPROFILE" CFLAGS="$CFLAGS -pg" else CPPFLAGS="$CPPFLAGS -DPROFILE" fi fi AC_ARG_ENABLE(test-coverage, [ --enable-test-coverage Enable gcov test coverage tracking (developers only)], enable_test_coverage="$enableval", enable_test_coverage="no") if test "x$enable_test_coverage" = "xyes"; then CFLAGS=`echo $CFLAGS | sed 's/-O\d/-O0/g'` CFLAGS="$CFLAGS -fprofile-arcs -ftest-coverage -O0" fi AC_ARG_ENABLE(ppm-test, [ --disable-ppm-test Disable packet/rule performance monitor], enable_ppm_test="$enableval", enable_ppm_test="no") if test "x$enable_ppm_test" = "xyes"; then CPPFLAGS="$CPPFLAGS -DPPM_TEST" fi AC_ARG_ENABLE(sourcefire, [ --enable-sourcefire Enable Sourcefire specific build options, encompasing --enable-perfprofiling and --enable-ppm], enable_sourcefire="$enableval", enable_sourcefire="no") if test "x$enable_sourcefire" = "xyes"; then CPPFLAGS="$CPPFLAGS -DSOURCEFIRE -DPPM_MGR" CONFIGFLAGS="$CONFIGFLAGS -DPERF_PROFILING" fi AC_ARG_ENABLE(corefiles, [ --disable-corefiles Prevent Snort from generating core files], enable_corefiles="$enableval", enable_corefiles="yes") if test "x$enable_corefiles" = "xno"; then CPPFLAGS="$CPPFLAGS -DNOCOREFILE" fi AC_ARG_ENABLE(active-response, [ --disable-active-response Disable reject injection], enable_active_response="$enableval", enable_active_response="yes") AC_ARG_ENABLE(normalizer, [ --disable-normalizer Disable packet/stream normalizations], enable_normalizer="$enableval", enable_normalizer="yes") AC_ARG_ENABLE(reload, [ --disable-reload Disable reloading a configuration without restarting], enable_reload="$enableval", enable_reload="yes") AC_ARG_ENABLE(reload-error-restart, [ --disable-reload-error-restart Disable restarting on reload error], enable_reload_error_restart="$enableval", enable_reload_error_restart="yes") AM_CONDITIONAL(BUILD_SNORT_RELOAD, test "x$enable_reload" = "xyes") if test "x$enable_reload" = "xyes"; then if test "x$enable_reload_error_restart" = "xyes"; then CONFIGFLAGS="$CONFIGFLAGS -DSNORT_RELOAD" else CONFIGFLAGS="$CONFIGFLAGS -DSNORT_RELOAD -DRELOAD_ERROR_FATAL" fi LIBS="$LIBS -lpthread" fi AC_ARG_ENABLE(ha, [ --enable-ha Enable high-availability state sharing (Experimental)], enable_ha="$enableval", enable_ha="no") AM_CONDITIONAL(BUILD_HA, test "x$enable_ha" = "xyes") if test "x$enable_ha" = "xyes"; then CONFIGFLAGS="$CONFIGFLAGS -DENABLE_HA" fi AC_ARG_ENABLE(buffer-dump, [ --enable-buffer-dump Enable Buffer dump utility to dump packet buffers], enable_buffer_dump="$enableval", enable_buffer_dump="no") AM_CONDITIONAL(BUILD_BUFFER_DUMP, test "x$enable_buffer_dump" = "xyes") if test "x$enable_buffer_dump" = "xyes"; then CONFIGFLAGS="$CONFIGFLAGS -DDUMP_BUFFER" fi # define NO_NON_ETHER_DECODERS by default AC_ARG_ENABLE(non-ether-decoders, [ --enable-non-ether-decoders Enable non Ethernet decoders.], enable_non_ether_decoders="$enableval", enable_non_ether_decoders="no") if test "x$enable_non_ether_decoders" = "xno"; then CONFIGFLAGS="$CONFIGFLAGS -DNO_NON_ETHER_DECODER" fi AC_ARG_ENABLE(react, [ --disable-react Disable interception and termination of offending HTTP accesses], enable_react="$enableval", enable_react="yes") AC_ARG_ENABLE(flexresp3, [ --disable-flexresp3 Disable flexible responses (v3) on hostile connection attempts], enable_flexresp3="$enableval", enable_flexresp3="yes") # test for invalid configurations here after all AC_ARG_ENABLEs if test "x$enable_flexresp3" = "xyes"; then # flexresp3 options are a union of flexresp (deleted) and flexresp2 # options so we assume flexresp3 if multiple are enabled. if test "x$enable_flexresp2" = "xyes"; then echo "WARNING: multiple flexresp versions enabled; using flexresp3." enable_flexresp2="no" fi fi AM_CONDITIONAL(BUILD_REACT, test "x$enable_react" = "xyes") if test "x$enable_react" = "xyes"; then CPPFLAGS="${CPPFLAGS} -DENABLE_REACT" fi AM_CONDITIONAL(BUILD_RESPOND3, test "x$enable_flexresp3" = "xyes") if test "x$enable_flexresp3" = "xyes"; then CPPFLAGS="${CPPFLAGS} -DENABLE_RESPOND -DENABLE_RESPONSE3" fi if test "x$enable_normalizer" = "xyes" \ -o "x$enable_sourcefire" = "xyes" ; \ then CONFIGFLAGS="${CONFIGFLAGS} -DNORMALIZER" fi if test "x$enable_active_response" = "xyes" \ -o "x$enable_flexresp3" = "xyes" \ -o "x$enable_react" = "xyes" \ -o "x$enable_sourcefire" = "xyes" ; \ then CONFIGFLAGS="${CONFIGFLAGS} -DACTIVE_RESPONSE" fi AC_ARG_ENABLE(intel_soft_cpm, [ --enable-intel-soft-cpm Enable Intel Soft CPM support], enable_intel_soft_cpm="$enableval", enable_intel_soft_cpm="no") AC_ARG_WITH(intel_soft_cpm_includes, [ --with-intel-soft-cpm-includes=DIR Intel Soft CPM include directory], [with_intel_soft_cpm_includes="$withval"],[with_intel_soft_cpm_includes="no"]) AC_ARG_WITH(intel_soft_cpm_libraries, [ --with-intel-soft-cpm-libraries=DIR Intel Soft CPM library directory], [with_intel_soft_cpm_libraries="$withval"],[with_intel_soft_cpm_libraries="no"]) if test "x$with_intel_soft_cpm_includes" != "xno"; then enable_intel_soft_cpm="yes" CPPFLAGS="${CPPFLAGS} -I${with_intel_soft_cpm_includes}" fi if test "x$with_intel_soft_cpm_libraries" != "xno"; then enable_intel_soft_cpm="yes" LDFLAGS="${LDFLAGS} -L${with_intel_soft_cpm_libraries}" LIBS="${LIBS} -lpm" fi AM_CONDITIONAL(HAVE_INTEL_SOFT_CPM, test "x$enable_intel_soft_cpm" = "xyes") if test "x$enable_intel_soft_cpm" = "xyes"; then CPPFLAGS="${CPPFLAGS} -DINTEL_SOFT_CPM" fi AC_ARG_ENABLE(shared_rep, [ --enable-shared-rep Enable use of Shared Memory for Reputation (Linux only)], enable_shared_rep="$enableval", enable_shared_rep="no") if test "x$enable_shared_rep" = "xyes"; then if test "x$linux" = "xyes"; then CPPFLAGS="${CPPFLAGS} -DSHARED_REP" LIBS="$LIBS -lrt" else echo "WARNING: shared reputation is only available on linux." enable_shared_rep="no" fi fi AM_CONDITIONAL(HAVE_SHARED_REP, test "x$enable_shared_rep" = "xyes") # Define PKG_CHECK_MODULES if it doesnt already exist. #file_ This prevents './configure' from erroring on machines that dont have # 'pkgconfig' installed. #m4_ifdef([PKG_CHECK_MODULES],[], [m4_define([PKG_CHECK_MODULES], # [echo "PKG_CHECK_MODULES not defined"])]) AC_ARG_ENABLE(large-pcap, [ --enable-large-pcap Enable support for pcaps larger than 2 GB], enable_large_pcap="$enableval", enable_large_pcap="no") if test "x$enable_large_pcap" = "xyes"; then CPPFLAGS="${CPPFLAGS} -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64" fi ################################################### ## [!] File Type Inspection (Experimental) ## ################################################### AC_ARG_ENABLE([file-inspect], [AS_HELP_STRING([--enable-file-inspect],[Build with extended file inspection features. (Experimental)])], [enable_file_inspect=$enableval],[enable_file_inspect=no]) AS_IF([test x$enable_file_inspect = xyes], [AC_DEFINE([FEAT_FILE_INSPECT],[1],[Build with extended file inspection features. (Experimental)]) ]) AM_CONDITIONAL([FEAT_FILE_INSPECT],[test x$enable_file_inspect = xyes]) export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH ###### Start OpenAppId AC_ARG_ENABLE([open-appid], [AS_HELP_STRING([--disable-open-appid],[Disable application identification support.])], [enable_open_appid="$enableval"],[enable_open_appid="yes"]) AM_CONDITIONAL([FEAT_OPEN_APPID],[test "x$enable_open_appid" = "xyes"]) if test "x$enable_open_appid" = "xyes"; then AC_DEFINE([FEAT_OPEN_APPID],[1],[Build with application identification support.]) CONFIGFLAGS="$CONFIGFLAGS -DFEAT_OPEN_APPID" PKG_CHECK_MODULES(luajit, luajit,LLUAJIT="yes",LLUAJIT="no") if test "x$LLUAJIT" = "xyes"; then CONFIGFLAGS="$CONFIGFLAGS -DHAVE_LIBLUAJIT" LUA_CFLAGS="$luajit_CFLAGS" LUA_LIBS="$luajit_LIBS" AC_SUBST(LUA_CFLAGS) AC_SUBST(LUA_LIBS) if test "x$macos" != "xno"; then LDFLAGS="${LDFLAGS} -pagezero_size 10000 -image_base 100000000" fi else echo echo " ERROR! LuaJIT library not found. Go get it from http://www.luajit.org/ (or)" echo " Try compiling without openAppId using '--disable-open-appid'" AC_MSG_ERROR("Fatal!") fi AC_CHECK_HEADER(openssl/x509.h, [AC_CHECK_LIB(crypto, d2i_X509, openssl_x509=yes, openssl_x509=no)],openssl_x509=no) if test "x$openssl_x509" = "xno"; then echo echo " ERROR! openssl/x509.h or openssl library not found." echo " Try compiling without openAppId using '--disable-open-appid'" AC_MSG_ERROR("Fatal!") fi fi ###### End OpenAppId #include nghttp2 libs AC_ARG_WITH(libnghttp2_includes, [ --with-libnghttp2-includes=DIR libnghttp2 include directory], [with_libnghttp2_includes="$withval"],[with_libnghttp2_includes="no"]) AC_ARG_WITH(libnghttp2_libraries, [ --with-libnghttp2-libraries=DIR libnghttp2 library directory], [with_libnghttp2_libraries="$withval"],[with_libnghttp2_libraries="no"]) if test "x$with_libnghttp2_includes" != "xno"; then CPPFLAGS="${CPPFLAGS} -I${with_libnghttp2_includes}" ICONFIGFLAGS="${ICONFIGFLAGS} -I${with_libnghttp2_includes}" fi if test "x$with_libnghttp2_libraries" != "xno"; then LDFLAGS="${LDFLAGS} -L${with_libnghttp2_libraries}" fi # Verify that we have the library NGHTTP_L="" AC_CHECK_LIB(nghttp2, nghttp2_option_new, ,NGHTTP_L="no") if test "x$NGHTTP_L" = "xno"; then echo echo " Libnghttp2 library not found." echo " Get it from https://nghttp2.org/" echo fi CFLAGS="${CFLAGS} ${CCONFIGFLAGS}" CFLAGS=`echo $CFLAGS | sed -e 's/-I\/usr\/include //g'` CPPFLAGS="${CPPFLAGS} ${CONFIGFLAGS}" CPPFLAGS=`echo $CPPFLAGS | sed -e 's/-I\/usr\/include //g'` if test "x$GCC" = "xyes" ; then echo `$CC -v 2>&1` | grep "version 4" > /dev/null if test $? = 0 ; then CFLAGS="$CFLAGS -fno-strict-aliasing" fi fi if test "x$linux" = "xyes"; then AC_MSG_CHECKING(for linuxthreads) tstr=`getconf GNU_LIBPTHREAD_VERSION 2>&1` if test $? = 0; then # GNU_LIBPTHREAD_VERSION is a valid system variable echo $tstr | grep -i linuxthreads > /dev/null 2>&1 if test $? = 0; then AC_DEFINE([HAVE_LINUXTHREADS],[1],[Define whether linuxthreads is being used]) AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi else # Use libc.so to see if linuxthreads is being used $( ldd `which --skip-alias ls` | grep libc.so | awk '{print $3}' ) | grep -i linuxthreads > /dev/null 2>&1 if test $? = 0; then AC_DEFINE([HAVE_LINUXTHREADS],[1],[Define whether linuxthreads is being used]) AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi fi fi if test "$LEX" != "none"; then AC_MSG_CHECKING(for yylex_destroy support) version=`$LEX --version | awk '{print $3}'` if test -z $version; then version=`$LEX --version | awk '{print $2}'` fi have_yylex_destroy="no" if test $version; then major=`echo $version | awk -F. '{ print $1 }'` minor=`echo $version | awk -F. '{ print $2 }'` subminor=`echo $version | awk -F. '{ print $3 }'` if test $major -a $minor -a $subminor; then if test $major -gt 2; then have_yylex_destroy="yes" else if test $major -eq 2; then if test $minor -gt 5; then have_yylex_destroy="yes" else if test $minor -eq 5; then if test $subminor -ge 9; then have_yylex_destroy="yes" fi fi fi fi fi fi fi if test "x$have_yylex_destroy" = "xyes"; then AC_MSG_RESULT(yes) AC_DEFINE([HAVE_YYLEX_DESTROY],[1],[Define whether yylex_destroy is supported in flex version]) else AC_MSG_RESULT(no) fi fi # Set to no optimization regardless of what user or autostuff set if test "x$NO_OPTIMIZE" = "xyes"; then CFLAGS=`echo $CFLAGS | sed -e "s/-O./-O0/"` # in case user override doesn't include -O if echo $CFLAGS | grep -qve -O0 ; then CFLAGS="$CFLAGS -O0" fi fi # Question: Does ICC not support -Wall (VJR - Jan 14, 2015) if test "$ICC" = "no"; then CFLAGS="$CFLAGS -Wall" fi echo $CFLAGS > cflags.out echo $CPPFLAGS > cppflags.out INCLUDES='-I$(top_srcdir) -I$(top_srcdir)/src -I$(top_srcdir)/src/sfutil $(extra_incl) -I$(top_srcdir)/src/output-plugins -I$(top_srcdir)/src/detection-plugins -I$(top_srcdir)/src/dynamic-plugins -I$(top_srcdir)/src/preprocessors -I$(top_srcdir)/src/preprocessors/portscan -I$(top_srcdir)/src/preprocessors/HttpInspect/include -I$(top_srcdir)/src/preprocessors/Session -I$(top_srcdir)/src/preprocessors/Stream6 -I$(top_srcdir)/src/target-based -I$(top_srcdir)/src/control -I$(top_srcdir)/src/file-process -I$(top_srcdir)/src/file-process/libs -I$(top_srcdir)/src/side-channel -I$(top_srcdir)/src/side-channel/plugins -I$(top_srcdir)/src/reload-adjust' AC_SUBST(INCLUDES) AC_SUBST(CONFIGFLAGS) AC_SUBST(CCONFIGFLAGS) AC_SUBST(ICONFIGFLAGS) AC_PROG_INSTALL AC_CONFIG_FILES([ \ snort.pc \ Makefile \ src/Makefile \ src/sfutil/Makefile \ src/control/Makefile \ src/file-process/Makefile \ src/file-process/libs/Makefile \ src/side-channel/Makefile \ src/side-channel/dynamic-plugins/Makefile \ src/side-channel/dynamic-plugins/snort_side_channel.pc \ src/side-channel/plugins/Makefile \ src/detection-plugins/Makefile \ src/dynamic-examples/Makefile \ src/dynamic-examples/dynamic-preprocessor/Makefile \ src/dynamic-examples/dynamic-rule/Makefile \ src/dynamic-plugins/Makefile \ src/dynamic-plugins/sf_engine/Makefile \ src/dynamic-plugins/sf_engine/examples/Makefile \ src/dynamic-plugins/sf_preproc_example/Makefile \ src/dynamic-preprocessors/Makefile \ src/dynamic-preprocessors/libs/Makefile \ src/dynamic-preprocessors/libs/snort_preproc.pc \ src/dynamic-preprocessors/ftptelnet/Makefile \ src/dynamic-preprocessors/smtp/Makefile \ src/dynamic-preprocessors/ssh/Makefile \ src/dynamic-preprocessors/sip/Makefile \ src/dynamic-preprocessors/reputation/Makefile \ src/dynamic-preprocessors/gtp/Makefile \ src/dynamic-preprocessors/dcerpc2/Makefile \ src/dynamic-preprocessors/pop/Makefile \ src/dynamic-preprocessors/imap/Makefile \ src/dynamic-preprocessors/sdf/Makefile \ src/dynamic-preprocessors/dns/Makefile \ src/dynamic-preprocessors/ssl/Makefile \ src/dynamic-preprocessors/modbus/Makefile \ src/dynamic-preprocessors/dnp3/Makefile \ src/dynamic-preprocessors/file/Makefile \ src/dynamic-preprocessors/appid/Makefile \ src/dynamic-output/Makefile \ src/dynamic-output/plugins/Makefile \ src/dynamic-output/libs/Makefile \ src/dynamic-output/libs/snort_output.pc \ src/output-plugins/Makefile \ src/preprocessors/Makefile \ src/preprocessors/HttpInspect/Makefile \ src/preprocessors/HttpInspect/include/Makefile \ src/preprocessors/HttpInspect/utils/Makefile \ src/preprocessors/HttpInspect/anomaly_detection/Makefile \ src/preprocessors/HttpInspect/client/Makefile \ src/preprocessors/HttpInspect/files/Makefile \ src/preprocessors/HttpInspect/event_output/Makefile \ src/preprocessors/HttpInspect/mode_inspection/Makefile \ src/preprocessors/HttpInspect/normalization/Makefile \ src/preprocessors/HttpInspect/server/Makefile \ src/preprocessors/HttpInspect/session_inspection/Makefile \ src/preprocessors/HttpInspect/user_interface/Makefile \ src/preprocessors/Session/Makefile \ src/preprocessors/Stream6/Makefile \ src/parser/Makefile \ src/target-based/Makefile \ doc/Makefile \ rpm/Makefile \ preproc_rules/Makefile \ m4/Makefile \ etc/Makefile \ templates/Makefile \ tools/Makefile \ tools/control/Makefile \ tools/u2boat/Makefile \ tools/u2spewfoo/Makefile \ tools/u2openappid/Makefile \ tools/u2streamer/Makefile \ tools/file_server/Makefile \ src/win32/Makefile \ src/reload-adjust/Makefile]) AC_OUTPUT snort-2.9.15.1/aclocal.m40000644000000000000000000126515413571425500011663 00000000000000# generated automatically by aclocal 1.13.4 -*- Autoconf -*- # Copyright (C) 1996-2013 Free Software Foundation, Inc. # This file 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. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file 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. m4_define([_LT_COPYING], [dnl # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool 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. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ]) # serial 57 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl _LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_CC_BASENAME(CC) # ------------------- # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. m4_defun([_LT_CC_BASENAME], [for cc_temp in $1""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl _LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PREPARE_SED_QUOTE_VARS # -------------------------- # Define a few sed substitution that help us do robust quoting. m4_defun([_LT_PREPARE_SED_QUOTE_VARS], [# Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ]) # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from `configure', and `config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # `config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain="$ac_aux_dir/ltmain.sh" ])# _LT_PROG_LTMAIN # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the `libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to `config.status' so that its # declaration there will have the same value as in `configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags="_LT_TAGS"dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the `libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into `config.status', and then the shell code to quote escape them in # for loops in `config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$[]1 _LTECHO_EOF' } # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done _LT_OUTPUT_LIBTOOL_INIT ]) # _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) # ------------------------------------ # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the # `#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). m4_ifdef([AS_INIT_GENERATED], [m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], [m4_defun([_LT_GENERATED_FILE_INIT], [m4_require([AS_PREPARE])]dnl [m4_pushdef([AS_MESSAGE_LOG_FD])]dnl [lt_write_fail=0 cat >$1 <<_ASEOF || lt_write_fail=1 #! $SHELL # Generated by $as_me. $2 SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$1 <<\_ASEOF || lt_write_fail=1 AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF test $lt_write_fail = 0 && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) _LT_GENERATED_FILE_INIT(["$CONFIG_LT"], [# Run this file to recreate a libtool stub with the current configuration.]) cat >>"$CONFIG_LT" <<\_LTEOF lt_cl_silent=false exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ \`$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test $[#] != 0 do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try \`$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try \`$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: test "$silent" = yes && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # _LT_COPYING _LT_LIBTOOL_TAGS # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) _LT_PROG_REPLACE_SHELLFNS mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Go], [_LT_LANG(GO)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG m4_ifndef([AC_PROG_GO], [ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_GO. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # m4_defun([AC_PROG_GO], [AC_LANG_PUSH(Go)dnl AC_ARG_VAR([GOC], [Go compiler command])dnl AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl _AC_ARG_VAR_LDFLAGS()dnl AC_CHECK_TOOL(GOC, gccgo) if test -z "$GOC"; then if test -n "$ac_tool_prefix"; then AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) fi fi if test -z "$GOC"; then AC_CHECK_PROG(GOC, gccgo, gccgo, false) fi ])#m4_defun ])#m4_ifndef # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([AC_PROG_GO], [LT_LANG(GO)], [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) dnl AC_DEFUN([AC_LIBTOOL_RC], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test $_lt_result -eq 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS="$save_LDFLAGS" ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[[012]]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES([TAG]) # --------------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test "$lt_cv_ld_force_load" = "yes"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" m4_if([$1], [CXX], [ if test "$lt_cv_apple_cc_single_mod" != "yes"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX([TAGNAME]) # ---------------------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. # Store the results from the different compilers for each TAGNAME. # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ lt_aix_libpath_sed='[ /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }]' _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [m4_divert_text([M4SH-INIT], [$1 ])])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start # of the generated configure script which will find a shell with a builtin # printf (which we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO AC_MSG_CHECKING([how to print strings]) # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $[]1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } case "$ECHO" in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; esac m4_ifdef([_AS_DETECT_SUGGESTED], [_AS_DETECT_SUGGESTED([ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test "X`printf %s $ECHO`" = "X$ECHO" \ || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], [AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [ --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified).], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= case ${with_sysroot} in #( yes) if test "$GCC" = yes; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) AC_MSG_RESULT([${with_sysroot}]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl [dependent libraries, and in which our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; ppc64-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; ppc*-*linux*|powerpc*-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; *-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD="${LD-ld}_sol2" fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" ])# _LT_ENABLE_LOCK # _LT_PROG_AR # ----------- m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} : ${AR_FLAGS=cru} _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) if test "$ac_status" -eq 0; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) if test "$ac_status" -ne 0; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a ]) ]) if test "x$lt_cv_ar_at_file" = xno; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi _LT_DECL([], [archiver_list_spec], [1], [How to feed a file listing to the archiver]) ])# _LT_PROG_AR # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [_LT_PROG_AR AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) _LT_DECL([], [lock_old_archive_extraction], [0], [Whether to use a lock for old archive extraction]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test x"[$]$2" = xyes; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" ]) if test x"[$]$2" = xyes; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n $lt_cv_sys_max_cmd_len ; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "$cross_compiling" = yes; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen="shl_load"], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen="dlopen"], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) ]) ]) ]) ]) ]) ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links="nottested" if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test "$hard_links" = no; then AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", [Define to the sub-directory in which libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then # We can hardcode non-existent directories. if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; *) lt_sed_strip_eq="s,=/,/,g" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[[4-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[23]].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[[3-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], [lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [lt_cv_shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir ]) shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Add ABI-specific directories to the system library path. sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[[89]] | openbsd2.[[89]].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [install_override_mode], [1], [Permission mode override for installation of shared libraries]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([], [sys_lib_dlsearch_path_spec], [2], [Run-time system search path for libraries]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program which can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$1; then lt_cv_path_MAGIC_CMD="$ac_dir/$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac]) MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program which can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test "$withval" = no || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; gnu*) lt_cv_deplibs_check_method=pass_all ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) lt_cv_deplibs_check_method=pass_all ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method = "file_magic"]) _LT_DECL([], [file_magic_glob], [1], [How to find potential files when deplibs_check_method = "file_magic"]) _LT_DECL([], [want_nocaseglob], [1], [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi]) if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols" ;; *) DUMPBIN=: ;; esac fi AC_SUBST([DUMPBIN]) if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # _LT_CHECK_SHAREDLIB_FROM_LINKLIB # -------------------------------- # how to determine the name of the shared library # associated with a specific link library. # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) m4_require([_LT_DECL_DLLTOOL]) AC_CACHE_CHECK([how to associate runtime and link libraries], lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh # decide which to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd="$ECHO" ;; esac ]) sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO _LT_DECL([], [sharedlib_from_linklib_cmd], [1], [Command to associate shared and link libraries]) ])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB # _LT_PATH_MANIFEST_TOOL # ---------------------- # locate the manifest tool m4_defun([_LT_PATH_MANIFEST_TOOL], [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], [lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&AS_MESSAGE_LOG_FD if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) if test "x$lt_cv_path_mainfest_tool" != xyes; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM="-lm") ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test "$GCC" = yes; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; *) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; esac _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else # define LT@&t@_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT@&t@_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then nm_file_list_spec='@' fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64 which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL 8.0, 9.0 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd*) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test "$GCC" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; *Sun\ F* | *Sun*Fortran*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Intel*\ [[CF]]*Compiler*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; *Portland\ Group*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_CACHE_CHECK([for $compiler option to produce PIC], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global defined # symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ;; esac ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test "$with_gnu_ld" = yes; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test "$lt_use_gnu_ld_interface" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global # defined symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; hpux10*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], [save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], [C++], [[int foo (void) { return 0; }]], [Fortran 77], [[ subroutine foo end]], [Fortran], [[ subroutine foo end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) LDFLAGS="$save_LDFLAGS"]) if test "$lt_cv_irix_exported_symbol" = yes; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' fi else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' else case $host_os in openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ;; esac fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_CACHE_CHECK([whether -lc should be explicitly linked in], [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), [$RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no else lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* ]) _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting ${shlibpath_var} if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [postlink_cmds], [2], [Commands necessary for finishing linking programs]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC="$CC" AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report which library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC="$lt_save_CC" ])# _LT_LANG_C_CONFIG # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_caught_CXX_error" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test "$GXX" = yes; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test "$with_gnu_ld" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='${wl}' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GXX" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared # libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ func_to_tool_file "$lt_outputfile"~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; gnu*) ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd2*) # C++ shared libraries are fairly broken _LT_TAGVAR(ld_shlibs, $1)=no ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(GCC, $1)="$GXX" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test "$_lt_caught_CXX_error" != yes AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_FUNC_STRIPNAME_CNF # ---------------------- # func_stripname_cnf prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # # This function is identical to the (non-XSI) version of func_stripname, # except this one can be used by m4 code that may be executed by configure, # rather than the libtool script. m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF package foo func foo() { } _LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case ${prev}${p} in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test $p = "-L" || test $p = "-R"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test "$pre_test_object_deps_done" = no; then case ${prev} in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)="${prev}${p}" else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test "$pre_test_object_deps_done" = no; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)="$p" else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)="$p" else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) if test -z "$F77" || test "X$F77" = "Xno"; then _lt_disable_F77=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_F77" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} CFLAGS=$FFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$G77" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC="$lt_save_CC" CFLAGS="$lt_save_CFLAGS" fi # test "$_lt_disable_F77" != yes AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) if test -z "$FC" || test "X$FC" = "Xno"; then _lt_disable_FC=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_FC" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} CFLAGS=$FCFLAGS compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test "$_lt_disable_FC" != yes AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_GO_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE # Source file extension for Go test sources. ac_ext=go # Object file extension for compiled Go test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="package main; func main() { }" # Code to be used in simple link tests lt_simple_link_test_code='package main; func main() { }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GO_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code="$lt_simple_compile_test_code" # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= CC=${RC-"windres"} CFLAGS= compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_GO # ---------- AC_DEFUN([LT_PROG_GO], [AC_CHECK_TOOL(GOC, gccgo,) ]) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_DLLTOOL # ---------------- # Ensure DLLTOOL variable is set. m4_defun([_LT_DECL_DLLTOOL], [AC_CHECK_TOOL(DLLTOOL, dlltool, false) test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # m4_defun([AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f $lt_ac_sed && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test $lt_ac_count -gt 10 && break lt_ac_count=`expr $lt_ac_count + 1` if test $lt_ac_count -gt $lt_ac_max; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [AC_MSG_CHECKING([whether the shell understands some XSI constructs]) # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,b/c, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes AC_MSG_RESULT([$xsi_shell]) _LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) AC_MSG_CHECKING([whether the shell understands "+="]) lt_shell_append=no ( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes AC_MSG_RESULT([$lt_shell_append]) _LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) # ------------------------------------------------------ # In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and # '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. m4_defun([_LT_PROG_FUNCTION_REPLACE], [dnl { sed -e '/^$1 ()$/,/^} # $1 /c\ $1 ()\ {\ m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) } # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: ]) # _LT_PROG_REPLACE_SHELLFNS # ------------------------- # Replace existing portable implementations of several shell functions with # equivalent extended shell implementations where those features are available.. m4_defun([_LT_PROG_REPLACE_SHELLFNS], [if test x"$xsi_shell" = xyes; then _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac]) _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl func_basename_result="${1##*/}"]) _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac func_basename_result="${1##*/}"]) _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary parameter first. func_stripname_result=${3} func_stripname_result=${func_stripname_result#"${1}"} func_stripname_result=${func_stripname_result%"${2}"}]) _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl func_split_long_opt_name=${1%%=*} func_split_long_opt_arg=${1#*=}]) _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl func_split_short_opt_arg=${1#??} func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl case ${1} in *.lo) func_lo2o_result=${1%.lo}.${objext} ;; *) func_lo2o_result=${1} ;; esac]) _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) fi if test x"$lt_shell_append" = xyes; then _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl func_quote_for_eval "${2}" dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) # Save a `func_append' function call where possible by direct use of '+=' sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: else # Save a `func_append' function call even when '+=' is not available sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$_lt_function_replace_fail" = x":"; then AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) fi ]) # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- # Determine which file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_MSG_CHECKING([how to convert $build file names to $host format]) AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac ]) to_host_file_cmd=$lt_cv_to_host_file_cmd AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) _LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], [0], [convert $build file names to $host format])dnl AC_MSG_CHECKING([how to convert $build file names to toolchain format]) AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac ]) to_tool_file_cmd=$lt_cv_to_tool_file_cmd AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], [0], [convert $build files to toolchain format])dnl ])# _LT_PATH_CONVERSION_FUNCTIONS # Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, # Inc. # Written by Gary V. Vaughan, 2004 # # This file 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. # serial 7 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option `$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl `shared' nor `disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) ]) ])# _LT_SET_OPTIONS # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the `shared' and # `disable-shared' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the `static' and # `disable-static' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the `fast-install' # and `disable-fast-install' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the `pic-only' and `no-pic' # LT_INIT options. # MODE is either `yes' or `no'. If omitted, it defaults to `both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for lt_pkg in $withval; do IFS="$lt_save_ifs" if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS="$lt_save_ifs" ;; esac], [pic_mode=default]) test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) # ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file 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. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59 which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) # ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file 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. # @configure_input@ # serial 3337 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.4.2]) m4_define([LT_PACKAGE_REVISION], [1.3337]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4.2' macro_revision='1.3337' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) # lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file 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. # serial 5 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) # pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- # serial 1 (pkg-config-0.24) # # Copyright © 2004 Scott James Remnant . # # 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. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # PKG_PROG_PKG_CONFIG([MIN-VERSION]) # ---------------------------------- AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) fi if test -n "$PKG_CONFIG"; then _pkg_min_version=m4_default([$1], [0.9.0]) AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) PKG_CONFIG="" fi fi[]dnl ])# PKG_PROG_PKG_CONFIG # PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) # # Check to see whether a particular set of modules exists. Similar # to PKG_CHECK_MODULES(), but does not set variables or print errors. # # Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) # only at the first occurence in configure.ac, so if the first place # it's called might be skipped (such as if it is within an "if", you # have to call PKG_CHECK_EXISTS manually # -------------------------------------------------------------- AC_DEFUN([PKG_CHECK_EXISTS], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl if test -n "$PKG_CONFIG" && \ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then m4_default([$2], [:]) m4_ifvaln([$3], [else $3])dnl fi]) # _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) # --------------------------------------------- m4_define([_PKG_CONFIG], [if test -n "$$1"; then pkg_cv_[]$1="$$1" elif test -n "$PKG_CONFIG"; then PKG_CHECK_EXISTS([$3], [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes ], [pkg_failed=yes]) else pkg_failed=untried fi[]dnl ])# _PKG_CONFIG # _PKG_SHORT_ERRORS_SUPPORTED # ----------------------------- AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], [AC_REQUIRE([PKG_PROG_PKG_CONFIG]) if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi[]dnl ])# _PKG_SHORT_ERRORS_SUPPORTED # PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], # [ACTION-IF-NOT-FOUND]) # # # Note that if there is a possibility the first call to # PKG_CHECK_MODULES might not happen, you should be sure to include an # explicit call to PKG_PROG_PKG_CONFIG in your configure.ac # # # -------------------------------------------------------------- AC_DEFUN([PKG_CHECK_MODULES], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no AC_MSG_CHECKING([for $1]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD m4_default([$4], [AC_MSG_ERROR( [Package requirements ($2) were not met: $$1_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then AC_MSG_RESULT([no]) m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. _PKG_TEXT To get pkg-config, see .])[]dnl ]) else $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS $1[]_LIBS=$pkg_cv_[]$1[]_LIBS AC_MSG_RESULT([yes]) $3 fi[]dnl ])# PKG_CHECK_MODULES # PKG_INSTALLDIR(DIRECTORY) # ------------------------- # Substitutes the variable pkgconfigdir as the location where a module # should install pkg-config .pc files. By default the directory is # $libdir/pkgconfig, but the default can be changed by passing # DIRECTORY. The user can override through the --with-pkgconfigdir # parameter. AC_DEFUN([PKG_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([pkgconfigdir], [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, [with_pkgconfigdir=]pkg_default) AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ]) dnl PKG_INSTALLDIR # PKG_NOARCH_INSTALLDIR(DIRECTORY) # ------------------------- # Substitutes the variable noarch_pkgconfigdir as the location where a # module should install arch-independent pkg-config .pc files. By # default the directory is $datadir/pkgconfig, but the default can be # changed by passing DIRECTORY. The user can override through the # --with-noarch-pkgconfigdir parameter. AC_DEFUN([PKG_NOARCH_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([noarch-pkgconfigdir], [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, [with_noarch_pkgconfigdir=]pkg_default) AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ]) dnl PKG_NOARCH_INSTALLDIR # Copyright (C) 2002-2013 Free Software Foundation, Inc. # # This file 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. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.13' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.13.4], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.13.4])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file 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. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2013 Free Software Foundation, Inc. # # This file 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. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file 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. # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file 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. # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each '.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file 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 macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file 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. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2013 Free Software Foundation, Inc. # # This file 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. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file 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. # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2013 Free Software Foundation, Inc. # # This file 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. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # -*- Autoconf -*- # Obsolete and "removed" macros, that must however still report explicit # error messages when used, to smooth transition. # # Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file 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. AC_DEFUN([AM_CONFIG_HEADER], [AC_DIAGNOSE([obsolete], ['$0': this macro is obsolete. You should use the 'AC][_CONFIG_HEADERS' macro instead.])dnl AC_CONFIG_HEADERS($@)]) AC_DEFUN([AM_PROG_CC_STDC], [AC_PROG_CC am_cv_prog_cc_stdc=$ac_cv_prog_cc_stdc AC_DIAGNOSE([obsolete], ['$0': this macro is obsolete. You should simply use the 'AC][_PROG_CC' macro instead. Also, your code should no longer depend upon 'am_cv_prog_cc_stdc', but upon 'ac_cv_prog_cc_stdc'.])]) AC_DEFUN([AM_C_PROTOTYPES], [AC_FATAL([automatic de-ANSI-fication support has been removed])]) AU_DEFUN([fp_C_PROTOTYPES], [AM_C_PROTOTYPES]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file 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. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file 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. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2009-2013 Free Software Foundation, Inc. # # This file 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. # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file 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. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2013 Free Software Foundation, Inc. # # This file 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. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004-2013 Free Software Foundation, Inc. # # This file 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. # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar # AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar], [# The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) if test $am_uid -le $am_max_uid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) if test $am_gid -le $am_max_gid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi], [pax], [], [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_$1-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR snort-2.9.15.1/config.h.in0000644000000000000000000002367413571425501012045 00000000000000/* config.h.in. Generated from configure.in by autoheader. */ /* Define if building universal (internal helper macro) */ #undef AC_APPLE_UNIVERSAL_BUILD /* Define if AIX */ #undef AIX /* Define if broken SIOCGIFMTU */ #undef BROKEN_SIOCGIFMTU /* Define if BSDi */ #undef BSDI /* Don't close opened shared objects for valgrind leak testing of dynamic libraries */ #undef DISABLE_DLCLOSE_FOR_VALGRIND_TESTING /* Define if errlist is predefined */ #undef ERRLIST_PREDEFINED /* Build with extended file inspection features. (Experimental) */ #undef FEAT_FILE_INSPECT /* Build with application identification support. */ #undef FEAT_OPEN_APPID /* Define if FreeBSD */ #undef FREEBSD /* Define to 1 if the system has the type `boolean'. */ #undef HAVE_BOOLEAN /* Define to 1 if you have the `daq_acquire_with_meta' function. */ #undef HAVE_DAQ_ACQUIRE_WITH_META /* DAQ version supports address space ID in header. */ #undef HAVE_DAQ_ADDRESS_SPACE_ID /* DAQ version supports data channel. */ #undef HAVE_DAQ_DATA_CHANNEL_PARAMS /* DAQ version supports separate IP versions on pinhole endpoints. */ #undef HAVE_DAQ_DATA_CHANNEL_SEPARATE_IP_VERSIONS /* DAQ version supports decrypted ssl */ #undef HAVE_DAQ_DECRYPTED_SSL /* Define to 1 if you have the `daq_dp_add_dc' function. */ #undef HAVE_DAQ_DP_ADD_DC /* DAQ version supports extended flow modifiers. */ #undef HAVE_DAQ_EXT_MODFLOW /* DAQ version supports flow ID in header. */ #undef HAVE_DAQ_FLOW_ID /* Define to 1 if you have the `daq_hup_apply' function. */ #undef HAVE_DAQ_HUP_APPLY /* DAQ version defines flags for locally destined traffic */ #undef HAVE_DAQ_LOCALLY_DESTINED /* DAQ version defines flags for locally originated traffic */ #undef HAVE_DAQ_LOCALLY_ORIGINATED /* DAQ version supports packet trace. */ #undef HAVE_DAQ_PKT_TRACE /* DAQ version supports query flow. */ #undef HAVE_DAQ_QUERYFLOW /* DAQ version supports real addresses in header. */ #undef HAVE_DAQ_REAL_ADDRESSES /* DAQ version supports tracing verdict reason. */ #undef HAVE_DAQ_VERDICT_REASON /* DAQ version supports DAQ_VERDICT_RETRY in DAQ_Verdict. */ #undef HAVE_DAQ_VERDICT_RETRY /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you have the header file. */ #undef HAVE_DNET_H /* Define to 1 if you have the header file. */ #undef HAVE_DUMBNET_H /* Define to 1 if you have the `gettid' function. */ #undef HAVE_GETTID /* Define to 1 if you have the `inet_ntop' function. */ #undef HAVE_INET_NTOP /* Define to 1 if the system has the type `int16_t'. */ #undef HAVE_INT16_T /* Define to 1 if the system has the type `int32_t'. */ #undef HAVE_INT32_T /* Define to 1 if the system has the type `int64_t'. */ #undef HAVE_INT64_T /* Define to 1 if the system has the type `int8_t'. */ #undef HAVE_INT8_T /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `dnet' library (-ldnet). */ #undef HAVE_LIBDNET /* Define to 1 if you have the `dumbnet' library (-ldumbnet). */ #undef HAVE_LIBDUMBNET /* Define to 1 if you have the `m' library (-lm). */ #undef HAVE_LIBM /* Define to 1 if you have the `nghttp2' library (-lnghttp2). */ #undef HAVE_LIBNGHTTP2 /* Define to 1 if you have the `nsl' library (-lnsl). */ #undef HAVE_LIBNSL /* Define to 1 if you have the `pcap' library (-lpcap). */ #undef HAVE_LIBPCAP /* Define to 1 if you have the `pcre' library (-lpcre). */ #undef HAVE_LIBPCRE /* Define to 1 if you have the `pfring' library (-lpfring). */ #undef HAVE_LIBPFRING /* Define to 1 if you have the `rt' library (-lrt). */ #undef HAVE_LIBRT /* Define to 1 if you have the `socket' library (-lsocket). */ #undef HAVE_LIBSOCKET /* Define to 1 if you have the `tirpc' library (-ltirpc). */ #undef HAVE_LIBTIRPC /* Define to 1 if you have the `uuid' library (-luuid). */ #undef HAVE_LIBUUID /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ /* Define whether linuxthreads is being used */ #undef HAVE_LINUXTHREADS /* Define to 1 if you have the header file. */ #undef HAVE_LZMA_H /* Define to 1 if you have the `mallinfo' function. */ #undef HAVE_MALLINFO /* Define to 1 if you have the `malloc_trim' function. */ #undef HAVE_MALLOC_TRIM /* Define to 1 if you have the header file. */ #undef HAVE_MATH_H /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the `memrchr' function. */ #undef HAVE_MEMRCHR /* openssl MD5 available */ #undef HAVE_OPENSSL_MD5 /* openssl SHA available */ #undef HAVE_OPENSSL_SHA /* Define to 1 if you have the header file. */ #undef HAVE_PATHS_H /* Can cleanup lex buffer stack created by pcap bpf filter */ #undef HAVE_PCAP_LEX_DESTROY /* Can output the library version. */ #undef HAVE_PCAP_LIB_VERSION /* Define to 1 if you have the header file. */ #undef HAVE_PCRE_H /* Define to 1 if you have the header file. */ #undef HAVE_PFRING_H /* Define to 1 if you have the `pthread_tryjoin_np' function. */ #undef HAVE_PTHREAD_TRYJOIN_NP /* Define to 1 if you have the `sigaction' function. */ #undef HAVE_SIGACTION /* snprintf function is available */ #undef HAVE_SNPRINTF /* Define to 1 if stdbool.h conforms to C99. */ #undef HAVE_STDBOOL_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strerror' function. */ #undef HAVE_STRERROR /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the `strlcat' function. */ #undef HAVE_STRLCAT /* Define to 1 if you have the `strlcpy' function. */ #undef HAVE_STRLCPY /* Define to 1 if you have the `strtoul' function. */ #undef HAVE_STRTOUL /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKIO_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if the system has the type `uint16_t'. */ #undef HAVE_UINT16_T /* Define to 1 if the system has the type `uint32_t'. */ #undef HAVE_UINT32_T /* Define to 1 if the system has the type `uint64_t'. */ #undef HAVE_UINT64_T /* Define to 1 if the system has the type `uint8_t'. */ #undef HAVE_UINT8_T /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the header file. */ #undef HAVE_UUID_UUID_H /* Define to 1 if the system has the type `u_int16_t'. */ #undef HAVE_U_INT16_T /* Define to 1 if the system has the type `u_int32_t'. */ #undef HAVE_U_INT32_T /* Define to 1 if the system has the type `u_int64_t'. */ #undef HAVE_U_INT64_T /* Define to 1 if the system has the type `u_int8_t'. */ #undef HAVE_U_INT8_T /* Define if the compiler supports visibility declarations. */ #undef HAVE_VISIBILITY /* Define to 1 if you have the `vsnprintf' function. */ #undef HAVE_VSNPRINTF /* Define to 1 if you have the `vswprintf' function. */ #undef HAVE_VSWPRINTF /* Define to 1 if you have the header file. */ #undef HAVE_WCHAR_H /* Define to 1 if you have the `wprintf' function. */ #undef HAVE_WPRINTF /* Define whether yylex_destroy is supported in flex version */ #undef HAVE_YYLEX_DESTROY /* Define to 1 if you have the header file. */ #undef HAVE_ZLIB_H /* Define to 1 if the system has the type `_Bool'. */ #undef HAVE__BOOL /* Define if the compiler understands __FUNCTION__. */ #undef HAVE___FUNCTION__ /* Define if the compiler understands __func__. */ #undef HAVE___func__ /* Define if HP-UX 10 or 11 */ #undef HPUX /* For INADDR_NONE definition */ #undef INADDR_NONE /* Define if Irix 6 */ #undef IRIX /* Define if Linux */ #undef LINUX /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Define if MacOS */ #undef MACOS /* Define if OpenBSD < 2.3 */ #undef OPENBSD /* Define if Tru64 */ #undef OSF1 /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Set by user */ #undef SIGNAL_SNORT_DUMP_STATS /* Set by user */ #undef SIGNAL_SNORT_READ_ATTR_TBL /* Set by user */ #undef SIGNAL_SNORT_RELOAD /* Set by user */ #undef SIGNAL_SNORT_ROTATE_STATS /* The size of `char', as computed by sizeof. */ #undef SIZEOF_CHAR /* The size of `int', as computed by sizeof. */ #undef SIZEOF_INT /* The size of `long int', as computed by sizeof. */ #undef SIZEOF_LONG_INT /* The size of `long long int', as computed by sizeof. */ #undef SIZEOF_LONG_LONG_INT /* The size of `short', as computed by sizeof. */ #undef SIZEOF_SHORT /* The size of `unsigned int', as computed by sizeof. */ #undef SIZEOF_UNSIGNED_INT /* The size of `unsigned long int', as computed by sizeof. */ #undef SIZEOF_UNSIGNED_LONG_INT /* The size of `unsigned long long int', as computed by sizeof. */ #undef SIZEOF_UNSIGNED_LONG_LONG_INT /* Define if Solaris */ #undef SOLARIS /* For sparc v9 with %time register */ #undef SPARCV9 /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define if SunOS */ #undef SUNOS /* Version number of package */ #undef VERSION /* Define if words are big endian */ #undef WORDS_BIGENDIAN /* Define if words must align */ #undef WORDS_MUSTALIGN /* Define __FUNCTION__ as required. */ #undef __FUNCTION__ /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus #undef inline #endif snort-2.9.15.1/snort.pc.in0000444000175200017520000000053613571422607012150 00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ bindir=@bindir@ libdir=@libdir@ includedir=@includedir@ datarootdir=@datarootdir@ datadir=@datadir@ mandir=@infodir@ infodir=@infodir@ Name: Snort Description: Snort dynamic plugins/detection/rules URL: www.snort.org Version: @VERSION@ Libs: -L${libdir} -lcurl @LDFLAGS@ @LIBS@ Cflags: @CFLAGS@ @CPPFLAGS@ snort-2.9.15.1/COPYING0000444000175200017520000005102313571422606011101 00000000000000***************************************************************************** The text that follows is the GNU General Public License, Version 2 (GPL V2) and governs your use, modification and/or distribution of SNORT. Section 9 of the GPL V2 acknowledges that the Free Software Foundation may publish revised and/or new versions of the GPL V2 from time to time. Section 9 further states that a licensee of a program subject to the GPL V2 could be free to use any such revised and/or new versions under two different scenarios: 1. "Failure to Specify." Section 9 of the GPL V2 allows a licensee of a program governed by an unspecified version of the General Public License to choose any version of the General Public License ever published by the Free Software Foundation to govern his or her use of such program. This provision is not applicable to your use of SNORT because we have expressly stated in a number of instances that any third party's use, modification or distribution of SNORT is governed by GPL V2. 2. "Any Later Version." At the end of the terms and condition of the GPL V2 is a section called "How to Apply these Terms to Your New Program," which provides guidance to a developer on how to apply the GPL V2 to a third party's use, modification and/or distribution of his/her program. Among other things, this guidance suggests that the developer attach certain notices to the program. Of particular importance is the following notice: "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." Thus if a developer follows strictly the guidance provided by the Free Software Foundation, Section 9 of the GPL V2 provides the licensee the option to either use, modify or distribute the program under GPL V2 or under any later version published by the Free Software Foundation. SNORT is an open source project that is governed exclusively by the GPL V2 and any third party desiring to use, modify or distribute SNORT must do so by strictly following the terms and conditions of GPL V2. Anyone using, modifying or distributing SNORT does not have the option to chose to use, modify or distribute SNORT under any revised or new version of the GPL, including without limitation, the GNU General Public License Version 3. For ease of reference, the comparable notice that is used with SNORT (contained in the 'README' file) is as follows: "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." If you have any questions about this statement, please feel free to email snort-info@snort.org. ***************************************************************************** GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. snort-2.9.15.1/ChangeLog0000444000175200017520000346566013571422610011636 000000000000002019-12-15 Hariharan Chandrashekar snort 2.9.15.1 * src/file-process/file_ss.c : Fixed the right order of precedence. Thanks to David Binderman for reporting this. * src/dynamic-preprocessors/ssl_common/ssl_config.c : Fixed snort core seen during ssl re-configuration. * src/fpdetect.c, src/log_text.c, src/profiler.h : Fixed compiler warnings. * src/file-process/file_segment_process.c : Fixed file access issues on files from SMB share. * configure.in, src/reload.c, src/side-channel/sidechannel.c, src/snort.c, src/target-based/sftarget_reader.c, src/util.h : Added support for glibc version 2.30. 2019-10-02 Hariharan Chandrashekar snort 2.9.15 * src/snort.c, src/control/sfcontrol.c, src/preprocessors/Session/stream5_ha.c, src/preprocessors/session_api.h, src/dynamic-plugins/sp_dynamic.c : Fixed a potential race condition. * src/detect.c : Fixed static analysis issues. * src/detect.c, src/detect.h, src/file-process/file_service.c, src/reload.c, src/sfdaq.h, src/snort.c, src/snort.h : Added new debugs to print detection, file_processing and Preproc time consumption info and verdict. * src/dynamic-preprocessors/appid/fw_appid.c : Added NULL check before dereferencing tcp_header. * src/file-process/libs/file_lib.h, src/sfdaq.h : Fix to make daq_pktHdr globally visible and removed the extra Packet variable from the FILE_PKT_DEBUG macro. * snort/etc/file_magic.conf : Added support to detect new Korean file formats .egg and .alz to the file preprocessor. * src/dynamic-preprocessors/gtp/gtp_parser.c, src/dynamic-preprocessors/gtp/spp_gtp.h : Fix to generate ALERT if TEID value is zero in GTP v1 and v2 packets. * src/detect.c : Added a check before printing the Packet latency trace when detection is enabled or not. * src/file-process/file_capture.c, src/file-process/file_mime_process.c, src/file-process/file_resume_block.c, src/file-process/file_segment_process.c, src/file-process/file_service.c, src/file-process/libs/file_lib.c, src/file-process/libs/file_lib.h, src/sfdaq.h : Added debug messages in file-process packet flow. * src/dynamic-plugins/sp_dynamic.c, src/reload.c, src/reload.h, src/snort.c : Fixed dynamic rules from getting disabled after multiple reloads. * src/pkt_tracer.c : Fix to print packet trace information in the direction of the packet on the wire. * etc/file_magic.conf : Added new file magic to detect RAR file-type. * src/dynamic-plugins/sf_dynamic_preprocessor.h : Updated preproc version. * src/dynamic-plugins/sf_dynamic_preprocessor.h : Provided an API to query non-flow related information from DAQ. * src/dynamic-plugins/sf_dynamic_plugins.c, src/dynamic-plugins/sf_dynamic_preprocessor.h, src/sfdaq.c, src/sfdaq.h : Added a generic api DAQ_Ioctl for dynamic preprocs to use for various daq clis. * src/dynamic-preprocessors/appid/Makefile_defs, src/dynamic-preprocessors/appid/detector_plugins/detector_imap.c, src/dynamic-preprocessors/appid/detector_plugins/detector_pop3.c, src/dynamic-preprocessors/appid/detector_plugins/detector_smtp.c, src/dynamic-preprocessors/appid/service_plugins/service_base.h, src/dynamic-preprocessors/appid/service_plugins/service_ftp.c, src/dynamic-preprocessors/appid/service_plugins/service_netbios.c, src/dynamic-preprocessors/appid/service_plugins/service_nntp.c : Fix to whitelist ftp data sessions when no file policy exists. * src/dynamic-preprocessors/appid/fw_appid.c : Fixed -Wparentheses warning. * src/dynamic-preprocessors/appid/fw_appid.c : Fixed the algorithm that triggers port only detection. * src/preprocessors/HttpInspect/client/hi_client.c, src/preprocessors/HttpInspect/include/hi_paf.h, src/preprocessors/HttpInspect/utils/hi_paf.c : Fixed an issue where HTTP was wrongly processing non HTTP traffic on port 443. * src/dynamic-preprocessors/appid/appIdConfig.h, src/dynamic-preprocessors/appid/fw_appid.c, src/dynamic-preprocessors/appid/service_plugins/service_base.c, src/dynamic-preprocessors/appid/service_plugins/service_base.h : Fixed IPS alerts generation for ICMP packets. * src/file-process/file_resume_block.c : Fixed signature lookup when the context is not present. * src/preprocessors/HttpInspect/utils/hi_paf.c : Added a new state to handle HTTP responses, having no status message followed by status code. * src/dynamic-plugins/sf_dynamic_plugins.c, src/dynamic-plugins/sf_dynamic_preprocessor.h, src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.h : Added DPD callbacks for receiving ftp transfer mode before generating file events. * snort/etc/file_magic.conf : Fixed RTF file magic to a more generic value to prevent evasions. * src/preprocessors/spp_httpinspect.c : Added debug logs during HTTP Reload. * src/dynamic-preprocessors/reputation/shmem/shmem_mgmt.c : Fix to bypass munmap if shmemSegptr points to zeroSegptr. * src/parser.c : Added rule SID check during Snort validation. * src/pkt_tracer.c : Corrected endianness representation for some of the parameters in the debug log. 2019-07-26 Hariharan Chandrashekar snort 2.9.14.1 * src/sfdaq.c : Fixed packet drop scenario. 2019-04-23 Hariharan Chandrashekar Snort 2.9.14.0 All files: updated copyright to 2019. * src/build.h : updating build number to 15003. * src/dynamic-preprocessors/appid/fw_appid.c : Fix to block https traffic going through proxy. * src/dynamic-preprocessors/appid/fw_appid.c : Reset navl packet counters when shifting to new req/resp. * src/file-process/file_ss.c : Fixed enabling side channel during some race conditions. * src/appIdApi.h, src/dynamic-preprocessors/appid/detector_plugins/detector_http.c, src/dynamic-preprocessors/appid/fw_appid.c, src/dynamic-preprocessors/appid/thirdparty_appid_types.h : Improving appId detection for proxied traffic. * src/control/sfcontrol.c, src/preprocessors/spp_httpinspect.c, src/detection-plugins/sp_isdataat.c, src/detection-plugins/sp_isdataat.h, src/preprocessors/HttpInspect/include/hi_eo_log.h, src/dynamic-preprocessors/appid/luaDetectorModule.c, src/dynamic-preprocessors/appid/detector_plugins/detector_cip.c, src/file-process/file_resume_block.c, src/file-process/file_service.h, src/file-process/file_service_config.c, src/file-process/file_ss.c, src/file-process/file_ss.h, src/file-process/libs/file_config.h, src/reload.c, src/snort.c : Fixed potential race conditions across snort code base. * src/dynamic-preprocessors/appid/hostPortAppCache.c : Added support for wild card port numbers in host cache and overwriting port service AppId. * src/preprocessors/HttpInspect/utils/hi_paf.c : Fixed the chunk extensions parsing in the HTTP responses leading to the correct construction of the PDU. * src/preprocessors/Stream6/snort_stream_tcp.c : Fixed missing inspection for out of order HTTP flows. * src/dynamic-preprocessors/appid/appInfoTable.c : Allow spaces in appid.conf and userappid.conf. * src/dynamic-preprocessors/appid/detector_plugins/detector_pop3.c : Added support for new STLS client patterns to help better detect POP3S over SSL. * src/dynamic-preprocessors/dcerpc2/dce2_smb2.c, src/file-process/file_segment_process.c : Fixed decrement of segment_mem_in_use counter when no pruning is done. * doc/README.http_inspect, etc/gen-msg.map, preproc_rules/preprocessor.rules, src/preprocessors/HttpInspect/event_output/hi_eo_log.c, src/preprocessors/HttpInspect/include/hi_eo_events.h, src/preprocessors/HttpInspect/utils/hi_paf.c : Fixed HTTP issue caused due to invalid versions. * src/parser.c : Fixed static analysis issues. * src/decode.c : Removed Duplicate length checks when decoding IPv6 Extensions. * src/preprocessors/sfprocpidstats.c : Changed the sfprocpidstat to calculate CPU statistics when --suppress-config-log option is not supplied. * src/file-process/libs/file_lib.h : Reset the max file id's default value. * src/dynamic-preprocessors/appid/appId_ss.c, src/dynamic-preprocessors/appid/appInfoTable.c : Logging the aggressiveness setting for BitTorrent, Ultrasurf, Psiphon & fixing paranthesis in 'If' condition. * src/dynamic-preprocessors/appid/service_plugins/service_ftp.c : Fixed FTP detection issues when a multi-line server response is split across multiple packets. * src/dynamic-preprocessors/appid/appIdConfig.c, src/dynamic-preprocessors/appid/appIdConfig.h, src/dynamic-preprocessors/appid/commonAppMatcher.c, src/dynamic-preprocessors/appid/spp_appid.c, src/dynamic-preprocessors/appid/thirdparty_appid_api.h, src/dynamic-preprocessors/appid/thirdparty_appid_utils.c : Added a new AppId preproc config option which specifies path to NAVL related cofiguration. * src/dynamic-preprocessors/appid/fw_appid.c : Fix to set TOR as payloadAppId if NAVL detects it over an HTTP SSL Tunnel. * src/dynamic-preprocessors/imap/imap_config.c, src/dynamic-preprocessors/pop/pop_config.c, src/dynamic-preprocessors/smtp/smtp_config.c, src/file-process/file_api.h, src/file-process/file_mime_config.c, src/file-process/file_mime_config.h, src/preprocessors/perf_indicators.h, src/preprocessors/snort_httpinspect.c, src/preprocessors/snort_httpinspect.h, src/preprocessors/spp_httpinspect.c : Fix Snort2 with a newer ICC without fixing the [bad] binary-crossing strtok assumptions. * src/preprocessors/spp_sfportscan.c : Fix for filling the ip4hdr in the port scan packet creation. * src/checksum.h, src/encode.c : Updated the checksum correctly for reset and locally modified packets for GRE flow. * src/preprocessors/Stream6/snort_stream_tcp.c : Fixed issue in handling TCP timestamp options in Snort. * src/dynamic-preprocessors/appid/fw_appid.c : Fixed compilation warning. * src/dynamic-plugins/sf_dynamic_preprocessor.h, src/dynamic-preprocessors/sdf/spp_sdf.c, src/dynamic-preprocessors/sdf/spp_sdf.h : Fixed Sensitive Data Threshold Configuration. * src/dynamic-preprocessors/appid/fw_appid.c, src/preprocessors/Session/session_expect.c : Fix for setting application_protocol_ordinal by the caller. * src/file-process/file_resume_block.c, src/file-process/file_ss.c : Removed unused variables. * src/dynamic-preprocessors/appid/detector_plugins/detector_smtp.c : Added support for detecting Mac based SMTP Microsoft Outlook client application * src/dynamic-preprocessors/sip/sip_config.c : Fixed policy deployment failure due to SIP preprocessor config validation. * src/dynamic-preprocessors/appid/luaDetectorApi.c : Including more informations for lua errors while loading patterns. * src/dynamic-preprocessors/sdf/sdf_credit_card.c, src/dynamic-preprocessors/sdf/sdf_pattern_match.c : Fix to treat any pii without following by non-digit as full pattern match and fire alert. * src/dynamic-preprocessors/reputation/shmem/shmem_lib.c : Fixed snort process exit when processing reputation and if another snort was launched that does the same work. * src/preprocessors/Stream6/snort_stream_tcp.c : Fix to not flush the urgent data to preprocs and the segment be trimmed. * src/dynamic-preprocessors/appid/appIdApi.c : Stop marking the HTTP inspection as done if the SSL detector is in progress and no URL is extracted. * src/dynamic-preprocessors/appid/service_plugins/service_rexec.c, src/dynamic-preprocessors/appid/service_plugins/service_rshell.c : Fix here is to set the AppId for rsh/rexec control sessions initially to allow the data session and doing the rest of the validation later. * src/control/sfcontrol.h, src/preprocessors/spp_perfmonitor.c : Fix for enabling flow profiling mode without restarting snort detection engine. * src/preprocessors/HttpInspect/client/hi_client.c, src/preprocessors/HttpInspect/include/hi_client.h : Fixed x-forward-for-like headers when there are multiple proxies. * src/file-process/file_service.c : Fix to update the file_config when we update the file_context. * src/dynamic-preprocessors/appid/service_plugins/service_base.c : Fix to prevent re-allocation of memory for SMB AppId data. * src/dynamic-preprocessors/Makefile.am : Add -f option to the mv command for fixing make distcheck failure during file overwrite. * doc/README.http_inspect, etc/gen-msg.map, preproc_rules/preprocessor.rules, src/preprocessors/HttpInspect/utils/hi_paf.c : A new preprocessor alert is added 120:27 to alert if there is no proper end of header. * src/preprocessors/Stream6/snort_stream_tcp.c : Fixed uninitialized members of StreamTracker for midstream sessions. * src/preprocessors/session_api.h, src/preprocessors/spp_session.c : Removal of Blocklist timeout code. * src/preprocessors/spp_session.c : Fix for snort to check for expired sessions and stop matching new packets with expired sessions. * src/dynamic-plugins/sf_dynamic_plugins.c, src/dynamic-plugins/sf_dynamic_preprocessor.h, src/snort.c : Fix to get daq capabilities for snort firewall in optimized way. * tools/appid_detector_builder.sh : Fixed API name used by OpenAppId LUA detector builder. * src/dynamic-preprocessors/appid/luaDetectorApi.c, src/dynamic-preprocessors/appid/luaDetectorModule.c : Locking LUA detectors during snort reload free. * src/dynamic-preprocessors/appid/luaDetectorApi.c, src/dynamic-preprocessors/appid/luaDetectorFlowApi.c, src/dynamic-preprocessors/appid/service_plugins/service_ssl.c : Setting AppId for RSHELL/REXEC stderr data sessions. * src/memory_stats.c, src/memory_stats.h, src/snort.c src/preprocessors/HttpInspect/client/hi_client.c, src/dynamic-preprocessors/appid/luaDetectorModule.c, src/dynamic-preprocessors/appid/service_plugins/service_rpc.c, src/dynamic-preprocessors/appid/spp_appid.c, src/dynamic-preprocessors/appid/service_plugins/service_base.c : Fixed issues reported by valgrind. * src/dynamic-preprocessors/appid/appIdApi.c, src/dynamic-preprocessors/appid/fw_appid.c : Fix for FTP Active detection issues in case of multi-line server responses. * src/dynamic-preprocessors/ftptelnet/ftpp_si.h, src/dynamic-preprocessors/ftptelnet/ftpp_ui_config.h, src/dynamic-preprocessors/ftptelnet/pp_ftp.c, src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, src/dynamic-preprocessors/ftptelnet/spp_ftptelnet.c, src/file-process/file_api.h, src/file-process/file_resume_block.c, src/file-process/file_resume_block.h, src/file-process/file_segment_process.c, src/file-process/file_service.c, src/preprocessors/Stream6/snort_stream_tcp.c : Fixed File policy with the rule block with reset that was not blocking the file upload. * src/dynamic-preprocessors/reputation/shmem/shmem_mgmt.c : Fixed snort process exit while processing Security Intelligence. 2019-03-21 Bhumika Sachdeva Snort 2.9.13.0 * src/dynamic-preprocessors/sip/sip_config.c : Changed number of max sessions SIP can handle. * src/dynamic-preprocessors/appid/luaDetectorModule.c : Fixed an issue in loading of bunch of lua detector. * src/dynamic-preprocessors/sdf/sdf_credit_card.c, src/dynamic-preprocessors/sdf/sdf_pattern_match.c : Fixed an issue with processing of pattern matching. * src/dynamic-preprocessors/appid/appIdApi.c : Fixed an issue with HTTP inspection in case SSL detector is in process and no URL has been extracted. * src/preprocessors/HttpInspect/client/hi_client.c, src/preprocessors/HttpInspect/include/hi_client.h : Fixing of x-forward-for-like headers in case of multiple proxies by snort. * src/preprocessors/Stream6/snort_stream_tcp.c : Blocking the flush of urgent data to preprocs and trimming of segment in case urgent flag is set and urgent pointer > 0. * src/dynamic-preprocessors/appid/service_plugins/service_rexec.c, src/dynamic-preprocessors/appid/service_plugins/service_rshell.c : Set the AppId for rsh/rexec control sessions initially to allow the data session and doing the rest of the validation. * src/file-process/file_service.c : Fixed the Snort process failure while processing file policy on SMB2 traffic. * src/dynamic-preprocessors/appid/service_plugins/service_base.c : Modified the prevention of re-allocation of memory for SMB AppId data. * src/dynamic-preprocessors/appid/luaDetectorModule.c, src/dynamic-preprocessors/appid/service_plugins/service_base.c : Fixed memory leak issues. * src/control/sfcontrol.c, src/detection-plugins/Makefile.am, src/dynamic-examples/Makefile.am, src/dynamic-plugins/Makefile.am, src/dynamic-plugins/sf_decompression_define.h, src/dynamic-plugins/sf_dynamic_decompression.c, src/dynamic-plugins/sf_dynamic_decompression.h, src/dynamic-plugins/sf_dynamic_detection.h, src/dynamic-plugins/sf_dynamic_engine.h, src/dynamic-plugins/sf_dynamic_meta.h, src/dynamic-plugins/sf_dynamic_plugins.c, src/dynamic-plugins/sf_dynamic_preprocessor.h, src/dynamic-plugins/sf_dynamic_side_channel.h, src/dynamic-plugins/sf_engine/bmh.c, src/dynamic-plugins/sf_engine/examples/12759.c, src/dynamic-plugins/sf_engine/examples/detection_lib_meta.h, src/dynamic-plugins/sf_engine/examples/rule_storeandforward.c, src/dynamic-plugins/sf_engine/examples/rule_storeandforward2.c, src/dynamic-plugins/sf_engine/sf_decompression.c, src/dynamic-plugins/sf_engine/sf_decompression.h, src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c, src/dynamic-plugins/sf_engine/sf_snort_plugin_api.c, src/dynamic-plugins/sf_engine/sf_snort_plugin_api.h, src/dynamic-plugins/so_rule_mem_adjust.h, src/dynamic-plugins/sp_dynamic.c, src/dynamic-preprocessors/Makefile.am, src/dynamic-preprocessors/appid/service_plugins/service_netbios.c, src/dynamic-preprocessors/appid/service_plugins/service_rpc.c, src/dynamic-preprocessors/appid/thirdparty_appid_utils.c, src/dynamic-preprocessors/dcerpc2/dce2_config.c, src/dynamic-preprocessors/dcerpc2/includes/smb.h, src/dynamic-preprocessors/sip/sip_dialog.c, src/dynamic-preprocessors/sip/sip_roptions.c, src/preprocessors/HttpInspect/utils/hi_util_hbm.c, src/preprocessors/spp_arpspoof.c, src/reload.c, src/snort.c, src/snort.h, snort_build/Makefile.common, snort_build/common-snort-opts.makefile : Snort now supports reload on snort rules update. * configure.in, src/control/sfcontrol.c : Addressed FreeBSD Build error. * src/preprocessors/perf-base.c : Fixed an issue with Inspection engine performance statistics showing 0 drops in case of non-zero drops. * src/control/sfcontrol.c : Fixed an issue where snort was stuck in cleanup. * preproc_rules/preprocessor.rules, src/preprocessors/HttpInspect/include/hi_eo_events.h, src/preprocessors/HttpInspect/utils/hi_paf.c : Handling of junk characters after chunk size in HTTP response. * src/detection-plugins/sp_byte_math.c : Handled a zero value case with division operator. * src/preprocessors/Stream6/snort_stream_tcp.c : Updated TCP policy for client and server session while flushing the client or server segment list. * doc/README.http_inspect, etc/gen-msg.map, preproc_rules/preprocessor.rules, src/preprocessors/HttpInspect/event_output/hi_eo_log.c, src/preprocessors/HttpInspect/include/hi_eo_events.h, src/preprocessors/HttpInspect/utils/hi_paf.c : Handled a new pre-processor alert in case of improper end of HTTP header. * src/dynamic-preprocessors/reputation/shmem/shmem_lib.c, src/detection-plugins/sp_isdataat.c, src/detection-plugins/sp_isdataat.h : Fixed a potential race condition. * src/dynamic-preprocessors/appid/appIdStats.c, src/dynamic-preprocessors/appid/appInfoTable.c, src/dynamic-preprocessors/appid/detector_plugins/detector_http.c, src/dynamic-preprocessors/appid/detector_plugins/detector_pop3.c, src/dynamic-preprocessors/appid/fw_appid.c, src/dynamic-preprocessors/appid/service_plugins/service_ssh.c, src/dynamic-preprocessors/appid/service_plugins/service_ssl.c, src/dynamic-preprocessors/appid/thirdparty_appid_utils.c, src/dynamic-preprocessors/dnp3/spp_dnp3.c, src/dynamic-preprocessors/ftptelnet/pp_ftp.c, src/sfutil/bnfa_search.c, src/sfutil/sf_textlog.c : Validation of malloc return values. * src/preprocessors/sfprocpidstats.c : Modified the sfprocpidstat to only calculate CPU statistics when --suppress-config-log option is not supplied. 2018-09-18 Puneeth Kumar C V Snort 2.9.12.0 * doc/README.http_inspect, etc/gen-msg.map, preproc_rules/preprocessor.rules, src/preprocessors/HttpInspect/event_output/hi_eo_log.c, src/preprocessors/HttpInspect/include/hi_eo_events.h, src/preprocessors/HttpInspect/server/hi_server.c, src/preprocessors/HttpInspect/utils/hi_paf.c : Fixed an issue where in if we have a junk line before HTTP response header, the header was wrongly parsed. A new preprocessor alert with gid:120 and sid:26 is alerted if any junk lines before HTTP response header is detected. * etc/gen-msg.map, preproc_rules/preprocessor.rules, src/preprocessors/HttpInspect/event_output/hi_eo_log.c, src/preprocessors/HttpInspect/include/hi_eo_events.h, src/preprocessors/HttpInspect/include/hi_server.h, src/preprocessors/HttpInspect/server/hi_server.c : If any of the standard header fields like Transfer-Encoding, content-encoding, content-length, content-type are preceded by \t, then a new alert is added with gid:120 and sid:25. * doc/README.http_inspect, doc/snort_manual.pdf, etc/gen-msg.map, preproc_rules/preprocessor.rules, src/preprocessors/snort_httpinspect.h, src/preprocessors/HttpInspect/event_output/hi_eo_log.c, src/preprocessors/HttpInspect/include/hi_eo_events.h, src/preprocessors/HttpInspect/server/hi_server.c, src/preprocessors/HttpInspect/utils/hi_paf.c : Fixed GZIP evasions wherein a HTTP response with content-encoding:gzip contains a body which has some gzip related anomaly. A new alert with gid:120 and sid:24 has been added to detect mixed gzip encode and plain text response. * src/preprocessors/HttpInspect/server/hi_server.c : Memory leak in decompression when using zlib version 1.2.11. Thanks Elof for reporting it and Thanks Anuj Patel for sending the patch. * src/: dynamic-preprocessors/dcerpc2/dce2_smb2.c, dynamic-preprocessors/dcerpc2/dce2_smb.h, dynamic-preprocessors/dcerpc2/dce2_smb2.c, dynamic-preprocessors/dcerpc2/dce2_smb2.h, dynamic-preprocessors/dcerpc2/dce2_paf.c, includes/smb.h, dynamic-preprocessors/dcerpc2/spp_dce2.c, file-process/file_api.h, file-process/file_segment_process.c, file-process/file_segment_process.h, SMB improvements for file processing. * src/dynamic-preprocessors/appid/: appInfoTable.h, fw_appid.c, fw_appid.h, hostPortAppCache.c, luaDetectorApi.c, luaDetectorApi.h, luaDetectorFlowApi.c, client_plugins/client_app_aim.c, client_plugins/client_app_api.h, client_plugins/client_app_base.c, client_plugins/client_app_base.h, client_plugins/client_app_bit.c, client_plugins/client_app_bit_tracker.c, client_plugins/client_app_msn.c, client_plugins/client_app_rtp.c, client_plugins/client_app_ssh.c, client_plugins/client_app_timbuktu.c, client_plugins/client_app_tns.c, client_plugins/client_app_vnc.c, client_plugins/client_app_ym.c, detector_plugins/detector_http.c, detector_plugins/detector_imap.c, detector_plugins/detector_kerberos.c, detector_plugins/detector_pattern.c, detector_plugins/detector_pop3.c, detector_plugins/detector_sip.c, detector_plugins/detector_smtp.c, service_plugins/service_api.h, service_plugins/service_base.c, service_plugins/service_base.h : Fixed an issue in a scenario where BitTorrent pattern is seen only on the 3rd packet of the session because of which we miss our client detection. * src/dynamic-preprocessors/appid/fw_appid.c : Re-enabling third party AppId detection for out-of-order/not-ok flows. * src/dynamic-preprocessors/appid/: flow.h, fw_appid.c : Added support for HTTP CONNECT command to handle BitTorrent connections over proxy. * src/encode.c, src/reload.h, src/sfdaq.c, src/dynamic-preprocessors/dcerpc2/dce2_co.c, src/dynamic-preprocessors/dcerpc2/dce2_config.c, src/dynamic-preprocessors/dcerpc2/dce2_smb.c, src/dynamic-preprocessors/dcerpc2/dce2_smb2.c, src/dynamic-preprocessors/dcerpc2/spp_dce2.c, src/dynamic-preprocessors/sdf/spp_sdf.c, src/preprocessors/spp_frag3.c, src/preprocessors/spp_session.c, src/preprocessors/spp_sfportscan.c, src/preprocessors/Stream6/snort_stream_ip.c, src/preprocessors/Stream6/snort_stream_tcp.c, src/sfutil/acsmx.c, src/sfutil/sfksearch.c, src/sfutil/sfportobject.c, tools/u2spewfoo/u2spewfoo.c : Fixed Snort warnings when compiled in OpenBSD with clang/llvm. Thanks to Markus for reporting this. * src/dynamic-preprocessors/file/spp_file.c : Fixed an issue where file inspect not working after reload. * src/dynamic-preprocessors/Makefile.am : Fixed an issue where snort was not coming up with AppId enabled on OpenBSD. * src/: snort.c, dynamic-plugins/sf_dynamic_preprocessor.h, preprocessors/perf.c, preprocessors/Stream6/snort_stream_icmp.c, preprocessors/Stream6/snort_stream_ip.c, preprocessors/Stream6/snort_stream_tcp.c, preprocessors/Stream6/snort_stream_udp.c : Fixed compilation issue with --disable-reload. * configure.in, doc/README.appid, doc/snort_manual.tex, rpm/README.build_rpms, rpm/generate-all-rpms, rpm/snort.spec, src/dynamic-preprocessors/appid/Makefile_defs : Compile AppID by default. * src/dynamic-preprocessors/appid/fw_appid.c : Changes to AppId to ignore malformed packets. * src/: dynamic-preprocessors/dcerpc2/dce2_smb2.c, file-process/file_segment_process.c, file-process/file_segment_process.h : Fix an issue where memory is over allocated due to SMB traffic. * src/dynamic-preprocessors/appid/: appIdApi.c, appIdConfig.h, appInfoTable.c, fw_appid.c, hostPortAppCache.c : Added support for wild card port numbers in host cache and overwriting port service AppId. * src/mstring.c : Fixed an issue with msplit() not behaving properly in some scenarios. * src/dynamic-preprocessors/appid/: fw_appid.c, test/appIdTests.c : Fixed an issue where retransmitted packet incorrectly treated as out of order. * src/preprocessors/spp_frag3.c : Fixed snort crash in some scenraios. * src/dynamic-preprocessors/appid/: fw_appid.c, service_plugins/service_ssl.c : Fixed an issue wherein if we have multiple ssl certificates, they were concatinated. * src/dynamic-preprocessors/appid/fw_appid.c : Using Inner IP header to determine the protocol & direction for AppId. * src/: reload.c, preprocessors/spp_normalize.c, preprocessors/Stream6/snort_stream_tcp.c : Fixed an issue where snort cores due to wrong/stale policy IDs in the flush path. * src/detection-plugins/sp_pattern_match.c : Fixed an issue with intrusion rule that was trigerring false negatives. * src/sfutil/sfportobject.c, src/decode.c, src/fpcreate.c, src/plugbase.c, src/util.c, src/dynamic-preprocessors/sdf/sdf_us_ssn.c : Fixed static analysis issues. * src/preprocessors/Stream6/: snort_stream_tcp.c, stream_common.c : Fixed early setting of PKT_STREAM_ORDER_BAD when out of order packet is seen. * src/preprocessors/: session_api.h, spp_session.c : This change will allow us to use the session stream key to lookup the session instead of directly storing the S pointer * src/: event_wrapper.c, event_wrapper.h, preprocessors/portscan.c : Fixed an issue where Port Scan doesn't block scans * src/: obfuscation.c, dynamic-preprocessors/appid/detector_plugins/detector_http.c, dynamic-preprocessors/file/file_agent.c, dynamic-preprocessors/file/file_inspect_config.c, dynamic-preprocessors/sdf/sdf_us_ssn.c, file-process/file_capture.c : Fixed bugs reported by open source community. Thanks for David Binderman for reporting this. * src/snort.c : Avoid possible double free and memory corruption in snortcleanup(). * doc/snort_manual.pdf, src/reg_test.h src/dynamic-preprocessors/reputation/spp_reputation.c : Prevent restart when Reputation memcap changes. * src/dynamic-preprocessors/appid/luaDetectorModule.c : Fixed an issue where AppId continues to try & load the remaining detectors instead of returning after finding an invalid one. * src/snort.c : Reduced the number of session prunings when snort is idle. * src/dynamic-preprocessors/ftptelnet/pp_ftp.c : Fixed an issue which can cause buffer overflow and memory corruption in FTP control path. * src/reload.c : Synchronise reload and restart in snort. * src/snort_bounds.h : Fixed possible buffer overrun. * src/dynamic-preprocessors/appid/: fw_appid.c, fw_appid.h, luaDetectorApi.c, spp_appid.c, client_plugins/client_app_base.c, service_plugins/service_base.c, test/Makefile.am : Remove misleading exit log about DetectorFini. * src/dynamic-preprocessors/appid/: client_plugins/client_app_rtp.c, client_plugins/client_app_rtp.h, test/Makefile.am, test/appIdTests.c, test/client_app_rtp_test.c, test/client_app_rtp_test.h : Fix for the issue where RTP doesn't get detected when there is SSRC switch. * src/dynamic-preprocessors/appid/: fw_appid.c, detector_plugins/detector_smtp.c, service_plugins/service_ftp.c : Fixed an issue where is SMTP is detected too late. * src/: dynamic-plugins/sf_dynamic_plugins.c, dynamic-preprocessors/appid/appIdConfig.h, dynamic-preprocessors/appid/fw_appid.c : Added mutex protections into the framework API to protect against some thread contention. * src/preprocessors/: session_api.h, spp_session.c, Session/session_expect.c : Changes to allow simulated packets to match an existing session. * src/: snort.c, dynamic-plugins/sf_dynamic_plugins.c, dynamic-plugins/sf_dynamic_preprocessor.h, dynamic-preprocessors/reputation/spp_reputation.c, preprocessors/session_api.h, preprocessors/spp_session.c, preprocessors/Session/session_common.h, sfutil/sfPolicyData.h : Re-evaluate IP reputation on all flows except black listed flows after reputation update. * doc/README.http_inspect, etc/gen-msg.map, preproc_rules/preprocessor.rules, src/preprocessors/HttpInspect/client/hi_client.c, src/preprocessors/HttpInspect/event_output/hi_eo_log.c, src/preprocessors/HttpInspect/include/hi_eo_events.h, src/preprocessors/HttpInspect/include/hi_paf.h, src/preprocessors/HttpInspect/server/hi_server.c, src/preprocessors/HttpInspect/utils/hi_paf.c : Added handling chunked encoding in HTTP1.0 request and response. * src/preprocessors/: snort_httpinspect.c, HttpInspect/client/hi_client.c, HttpInspect/include/hi_client.h, Stream6/snort_stream_tcp.c, Stream6/stream_paf.c : Fixed an issue where in HTTPS post file detection not working. * src/: parser.c, snort.h, detection-plugins/sp_pcre.c, dynamic-plugins/sf_convert_dynamic.c, dynamic-plugins/sf_dynamic_engine.h, dynamic-plugins/sf_dynamic_plugins.c, dynamic-plugins/sf_engine/sf_snort_plugin_pcre.c, output-plugins/spo_log_tcpdump.c, preprocessors/spp_normalize.c, preprocessors/Stream6/snort_stream_tcp.c : Fixed an issue with Snort using incorrect snort config in reload path. * src/: decode.c, preprocessors/portscan.c, preprocessors/spp_frag3.c : Fixed an issue with IP Protocol scanning not getting detected. * src/decode.c : Fixed heap out of bounds read in DecodeCiscoMeta(). * src/decode.c : Fixed 1 byte buffer overflow in CheckIPV6HopOptions. * src/dynamic-preprocessors/appid/: commonAppMatcher.c : Fix for the issue where hosts were not being discovered if the ND rule had IPv6 network and zone. * src/sfutil/Unified2_common.h : Fixed an issue with Unified2IDSEventIPv6 structure's app_name field has incorrect size. * src/util.c : Fixed an issue where logging packet can cause a segmentation fault in single-pcap mode when printing timestamp. Thanks to Stephan Zeisbarg for reporting this issue. * src/preprocessors/portscan.c : Fix Protocol sweep alert. 2017-12-06 Meghana R Snort 2.9.11.1 * sfeng/ims/sfsnort/snort/src/build.h : updating build number to 268 * sfeng/ims/sfsnort/snort/: src/encode.c, src/reload.h, src/sfdaq.c, src/dynamic-preprocessors/dcerpc2/dce2_co.c, src/dynamic-preprocessors/dcerpc2/dce2_config.c, src/dynamic-preprocessors/dcerpc2/dce2_smb.c, src/dynamic-preprocessors/dcerpc2/dce2_smb2.c, src/dynamic-preprocessors/dcerpc2/spp_dce2.c, src/dynamic-preprocessors/sdf/spp_sdf.c, src/preprocessors/spp_frag3.c, src/preprocessors/spp_session.c, src/preprocessors/spp_sfportscan.c, src/preprocessors/Stream6/snort_stream_ip.c, src/preprocessors/Stream6/snort_stream_tcp.c, src/sfutil/acsmx.c, src/sfutil/sfksearch.c, src/sfutil/sfportobject.c, tools/u2spewfoo/u2spewfoo.c : Fixed warnings when snort is compiled in OpenBSD with clang/llvm. Thanks to Markus Lude for noting the issue. * sfeng/ims/sfsnort/snort/src/dynamic-preprocessors/file/spp_file.c : Fixed issue of applying new configuration in file inspection after snort reload. * sfeng/ims/sfsnort/snort/src/preprocessors/spp_session.c : Added null check before accessing session cache. * sfeng/ims/sfsnort/snort/src/: appIdApi.h, dynamic-preprocessors/appid/appIdApi.c : Fixed issue where AppId was not setting HA flags correctly for unmonitored sessions. * sfeng/ims/sfsnort/snort/src/: snort.c, dynamic-plugins/sf_dynamic_preprocessor.h, preprocessors/perf.c, preprocessors/Stream6/snort_stream_icmp.c, preprocessors/Stream6/snort_stream_ip.c, preprocessors/Stream6/snort_stream_tcp.c, preprocessors/Stream6/snort_stream_udp.c : Fixed issue in compilation of snort with --disable-reload option. Thanks to BlueSky for noting the issue. * sfeng/ims/sfsnort/snort/src/dynamic-preprocessors/Makefile.am : Fixed AppID compilation failure in OpenBSD platform. * sfeng/ims/sfsnort/snort/src/dynamic-preprocessors/appid/fw_appid.c : Fixed issue to set correct flags when there is a need to ignore thirdparty detection for an SSL session. * sfeng/ims/sfsnort/snort/src/: event_wrapper.c, event_wrapper.h, preprocessors/portscan.c : Added support to block portscan. In addition to tracking the scanning packets, action(drop/sdrop/reject) will be taken for all the packets, which means snort will block the packet and generate logs. * sfeng/ims/sfsnort/snort/src/: obfuscation.c, dynamic-preprocessors/appid/detector_plugins/detector_http.c, dynamic-preprocessors/file/file_agent.c, dynamic-preprocessors/file/file_inspect_config.c, dynamic-preprocessors/sdf/sdf_us_ssn.c, file-process/file_capture.c : Fixed incorrect usage of bitwise-operator and removed dead code. Thanks to David Binderman for noting the issue and proposing the fix. * sfeng/ims/sfsnort/snort/: doc/snort_manual.pdf, src/snort.c, src/dynamic-plugins/sf_dynamic_plugins.c, src/dynamic-plugins/sf_dynamic_preprocessor.h, src/dynamic-preprocessors/reputation/spp_reputation.c, src/preprocessors/session_api.h, src/preprocessors/spp_session.c, src/preprocessors/Session/session_common.h, src/sfutil/sfPolicyData.h : Added support to re-evaluate reputation after reputation update for all flows except those that have already been blacklisted. * sfeng/ims/sfsnort/snort/src/dynamic-preprocessors/appid/: client_plugins/client_app_rtp.c, client_plugins/client_app_rtp.h : Fixed issue to detect RTP upto two SSRC switches in each traffic direction. * sfeng/ims/sfsnort/snort/src/snort.c : Added changes to reduce the number of session pruning when snort is idle. * sfeng/ims/sfsnort/snort/src/dynamic-preprocessors/ftptelnet/pp_ftp.c : Fixed an issue related to setting of directory path when handling FTP sessions. * sfeng/ims/sfsnort/snort/src/snort_bounds.h : Fixed an issue with the incorrect return in SafeSnprintf function. * sfeng/ims/sfsnort/snort/src/preprocessors/: snort_httpinspect.c, HttpInspect/client/hi_client.c, HttpInspect/include/hi_client.h, Stream6/snort_stream_tcp.c, Stream6/stream_paf.c : Fixed issues related to HTTP POST header flushing, calling file processing directly if it is not a multipart header and changes to avoid expensive copy of segment data by not splitting them when flushing headers. * sfeng/ims/sfsnort/snort/src/dynamic-preprocessors/appid/detector_plugins/detector_sip.c : Added changes to show missing session log message only when debugging mode is enabled. * sfeng/ims/sfsnort/snort/: doc/snort_manual.pdf, src/preprocessors/portscan.c : Fixed issue of triggering protocol sweep alert when there are multiple destinations from single source ip protocol scan. * sfeng/ims/sfsnort/snort/src/preprocessors/Stream6/snort_stream_tcp.c : Fixed issue of correct session matching for TCP SYN packets without window scale option so that FTP data channels match the same rule as FTP control channels. * sfeng/ims/sfsnort/snort/src/: decode.c, preprocessors/portscan.c, preprocessors/spp_frag3.c : Added changes to fix IP portscan for protocol other than ICMP and fixed issue of bad fragment size event not being generated for oversized packets. * sfeng/ims/sfsnort/snort/src/preprocessors/snort_httpinspect.c: Added changes to use raw data in case of PDF and SWF files during file processing for SHA calculation and Malware Cloud Lookup. 2017-09-05 Meghana R Snort 2.9.11 * src/build.h : updating build number to 125. * src/preprocessors/: spp_session.c, Stream6/snort_stream_tcp.c : Fixed issue with updation of global IPS id before packet processing. * src/output-plugins/spo_unified2.c : Added changes to display AppId for IPv6 unified events. * src/: dynamic-preprocessors/Makefile.am, reload-adjust/appdata_adjuster.c, sfutil/sfmemcap.c, sfutil/sfmemcap.h : Fixed dynamic preprocessor compilation failure in OpenBSD platform. * src/: parser.c, snort.h, detection-plugins/sp_replace.c : Fixed issues while parsing rules in snort reload path. * src/: appIdApi.h, dynamic-preprocessors/appid/appId.h, dynamic-preprocessors/appid/appIdApi.c, dynamic-preprocessors/appid/appIdConfig.h, dynamic-preprocessors/appid/appInfoTable.c, dynamic-preprocessors/appid/flow.h, dynamic-preprocessors/appid/fw_appid.c, dynamic-preprocessors/appid/hostPortAppCache.c, dynamic-preprocessors/appid/hostPortAppCache.h : Added implementation of hostPortCache versioning for unknown flows in AppID to detect and block BitTorrent. * src/preprocessors/spp_normalize.c : Fixed incorrect usage of snort configuration in snort reload path. * src/dynamic-preprocessors/appid/: flow.c, flow.h, fw_appid.c : Fixed issues with printing of messages for out-of-order packets. * src/: mempool.c, mempool.h, reg_test.h, reload.c, control/sfcontrol.c, control/sfcontrol.h, preprocessors/spp_session.c, preprocessors/Stream6/snort_stream_tcp.c : Added support for forced allocation of TCP protocol memory pool after maximum limit is reached. * src/reload.c : Fixed synchronisation issue during snort reload. * src/sfutil/: sf_ip.h, sf_ipvar.c, sf_ipvar.h : Added changes to improve performance of ipvar list comparison. * src/: dynamic-output/plugins/output_lib.h, dynamic-output/plugins/output_plugin.c, dynamic-preprocessors/dcerpc2/dce2_smb.c, dynamic-preprocessors/dcerpc2/dce2_smb.h, dynamic-preprocessors/dcerpc2/dce2_smb2.c, dynamic-preprocessors/dcerpc2/spp_dce2.c, dynamic-preprocessors/file/file_event_log.c, file-process/file_api.h, file-process/file_service.c, file-process/file_stats.c, file-process/file_stats.h, sfutil/sf_textlog.c, sfutil/sf_textlog.h : Added support for storing filenames in unicode format for SMB protocol. * src/dynamic-preprocessors/appid/detector_plugins/detector_smtp.c : Enhanced SMTP client detection by allowing line folding and all authentication methods. * src/: fpcreate.c, sfutil/sfthd.c, sfutil/sfxhash.c : Fixed issue in detection filter counter when rule is used in multiple configurations. 2017-06-19 Meghana R Snort 2.9.11 Beta *src/build.h : updating build number to 101 * configure.in : Control-socket and side-channel support for FreeBSD platform. * src/snort.c : Fixed an issue where snort did not exit gracefully on SIGHUP during the initialisation. * src/detect.c : Added a data length check before copying into memory during application detection. * doc/snort_manual.pdf, src/dynamic-preprocessors/appid/appIdConfig.h, src/dynamic-preprocessors/appid/appInfoTable.c, src/dynamic-preprocessors/appid/commonAppMatcher.c, src/dynamic-preprocessors/appid/fw_appid.c, src/dynamic-preprocessors/appid/fw_appid.h, src/dynamic-preprocessors/appid/hostPortAppCache.c, src/dynamic-preprocessors/appid/hostPortAppCache.h, src/dynamic-preprocessors/appid/luaDetectorApi.c : Added new hostPortCache which can maintain runtime AppId entries. * src/preprocessors/perf-flow.c : Added null check for individual sfFlow structure members. * doc/snort_manual.tex : Fixed syntax error in snort_maual.tex * src/dynamic-preprocessors/appid/test/Makefile.am, dynamic-preprocessors/dcerpc2/test/Makefile.am, sfutil/test/Makefile.am : Linked librt library in appidd and dcerpc2 modules. * doc/snort_manual.pdf, doc/snort_manual.tex, src/decode.c, src/decode.h, src/detect.c, src/encode.c, src/reg_test.h, src/snort.c, src/snort.h, src/util.c, src/reload.c src/detection-plugins/sp_byte_math.c, src/dynamic-plugins/sf_engine/sf_snort_plugin_byte.c, src/dynamic-preprocessors/appid/appIdConfig.h, src/dynamic-preprocessors/appid/appInfoTable.c, src/dynamic-preprocessors/appid/commonAppMatcher.c, src/dynamic-preprocessors/appid/fw_appid.c, src/dynamic-preprocessors/appid/fw_appid.h, src/dynamic-preprocessors/appid/hostPortAppCache.c, src/dynamic-preprocessors/appid/hostPortAppCache.h, src/dynamic-preprocessors/appid/luaDetectorApi.c, src/dynamic-preprocessors/appid/detector_plugins/detector_sip.c, src/dynamic-preprocessors/appid/test/Makefile.am, src/dynamic-preprocessors/dcerpc2/dce2_smb2.c, src/dynamic-preprocessors/dcerpc2/dce2_smb2.h, src/dynamic-preprocessors/dcerpc2/spp_dce2.c, src/dynamic-preprocessors/dcerpc2/test/Makefile.am, src/dynamic-preprocessors/ftptelnet/pp_ftp.c, src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, src/dynamic-preprocessors/reputation/spp_reputation.c, src/dynamic-preprocessors/imap/spp_imap.c, src/dynamic-preprocessors/pop/spp_pop.c, src/dynamic-preprocessors/smtp/spp_smtp.c, src/file-process/file_api.h, src/file-process/file_segment_process.c, src/file-process/file_segment_process.h, src/file-process/file_service.c, src/preprocessors/perf-base.c, src/preprocessors/perf-flow.c, src/preprocessors/perf_indicators.c, src/preprocessors/snort_httpinspect.c, src/preprocessors/spp_session.c, src/preprocessors/spp_stream6.c, src/preprocessors/HttpInspect/server/hi_server.c, src/preprocessors/HttpInspect/utils/hi_cmd_lookup.c, src/preprocessors/Session/session_expect.c, src/preprocessors/Stream6/snort_stream_tcp.c, src/reload-adjust/appdata_adjuster.c, src/sfutil/sfrf.c, src/sfutil/sfrf.h, src/sfutil/test/Makefile.am, src/sfutil/test/unit_hacks.c, src/target-based/sftarget_reader.c, src/target-based/sftarget_reader.h : Changes to eliminate Snort restart when there are changes to the memory allocated for preprocessors, by releasing unused or least recently used memory when needed. * src/encode.c, dynamic-plugins/sf_engine/sf_snort_plugin_byte.c, dynamic-preprocessors/ftptelnet/pp_ftp.c, dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, preprocessors/perf-base.c, preprocessors/perf_indicators.c, preprocessors/snort_httpinspect.c, preprocessors/HttpInspect/utils/hi_cmd_lookup.c : Fixed multiple issues reported by Coverity. * src/preprocessors/Stream6/: snort_stream_tcp.c : Added a null check before retrieving tcpssn for getting re-built packets. * src/dynamic-preprocessors/reputation/spp_reputation.c : Fixed double free issue in reputation module. * src/detection-plugins/sp_byte_math.c, file-process/file_service.c : Fixed Coverity Issue - added null check before usage. * src/dynamic-preprocessors/appid/fw_appid.c : Enhanced RTSP metadata parsing to match the user-agent field to detect RTSP traffic over Windows Media. * src/dynamic-preprocessors/appid/fw_appid.c : Added a null check to prevent copy unless debugHostIp is configured in AppId. * src/decode.c, decode.h, detect.c, snort.h, util.c, preprocessors/spp_session.c, preprocessors/Stream6/snort_stream_tcp.c, sfutil/sfrf.c, sfutil/sfrf.h : Performance improvement when SYN rate limit has reached and drop is configured as next action. * src/preprocessors/HttpInspect/server/hi_server.c : Fixed issue of uninitialised value before usage. * src/file-process/file_service.c : Fixed issue with SHA value display in File Events. * src/dynamic-preprocessors/appid/detector_plugins/detector_sip.c : Enhanced the processing of SIP/RTP future flows without ignoring them. * src/preprocessors/snort_httpinspect.c : Changes made in PDF/SWF decompression by adding boundary to the size of the decompressed data. * src/preprocessors/Stream6/snort_stream_tcp.c : Fixed stream5 to flush out ACK'ed segments using PAF when session is terminating. * src/preprocessors/spp_session.c : Fixed issue with associating router solicit/reply packets to a single session. * src/preprocessors/HttpInspect/server/hi_server_norm.c, sfutil/util_utf.c : Fixed issues with normalisation of unicode HTML pages that do not have unicode encoding specifiers. * src/appIdApi.h, dynamic-plugins/sf_dynamic_plugins.c, dynamic-preprocessors/appid/appIdApi.c, dynamic-preprocessors/appid/appIdConfig.h, dynamic-preprocessors/appid/commonAppMatcher.c, dynamic-preprocessors/appid/fw_appid.c, dynamic-preprocessors/appid/fw_appid.h, dynamic-preprocessors/appid/detector_plugins/detector_sip.c, dynamic-preprocessors/appid/service_plugins/service_base.h, dynamic-preprocessors/appid/service_plugins/service_ftp.c, dynamic-preprocessors/appid/service_plugins/service_rexec.c, dynamic-preprocessors/appid/service_plugins/service_rshell.c, dynamic-preprocessors/appid/service_plugins/service_snmp.c, dynamic-preprocessors/appid/service_plugins/service_tftp.c, dynamic-preprocessors/appid/test/appIdTests.c : Fixed the issue in FTP active traffic by copying the flags as is when expected flow is in the same direction as current flow, reversing the flags when expected flow is in opposite direction and not copying the flags when expected flow's direction is unknown. * src/dynamic-plugins/sf_dynamic_plugins.c, dynamic-preprocessors/dcerpc2/spp_dce2.c Fixed issue of multiple allocation of ada cache in dcerpc2 module. * src/preprocessors/spp_httpinspect.c : Made changes to take care of boundary conditions after mempool allocation. * src/dynamic-preprocessors/appid/luaDetectorModule.c : Fixed Coverity Issues - Removed logically dead duplicate code that does NULL check after creating a new luaState. * src/file-process/file_service.c, preprocessors/Stream6/snort_stream_tcp.c : Fixed issue in file signature lookup for retransmitted FTP packet. * src/output-plugins/spo_log_buffer_dump.c : Changes to free HTTP buffers not used during processing. * src/dynamic-plugins/sf_dynamic_plugins.c, dynamic-preprocessors/dcerpc2/spp_dce2.c, dynamic-preprocessors/dnp3/spp_dnp3.c, dynamic-preprocessors/sip/sip_config.c, dynamic-preprocessors/sip/spp_sip.c, reload-adjust/appdata_adjuster.c, reload-adjust/appdata_adjuster.h : Fixed issues in SIP related to reallocation of the same data structure multiple times and accessing numSessions which is asynchronously written by packet processing thread. * src/dynamic-preprocessors/dcerpc2/spp_dce2.c : Added multiple null checks in dcerpc2 module. * src/dynamic-preprocessors/dnp3/spp_dnp3.c, reload-adjust/appdata_adjuster.c, reload-adjust/appdata_adjuster.h : Added null pointer checks in DNP3CheckConfig. * src/preprocessors/spp_session.c : Fixed Coverity issue - added null check before usage. * src/build.h : updating build number to 42 * src/snort.c : Trigger Snort restart when `config disable-attribute-reload-thread` is turned on/off. * src/preprocessors/Stream6/snort_stream_tcp.c : Fixed detection issue where wrong file signature calculation was done for secure-ftp. * src/dynamic-preprocessors/ftptelnet/: ftpp_si.c, ftpp_si.h, pp_ftp.c : Fixed incorrect referencing of ftp_data_session after its pruned. * src/dynamic-preprocessors/appid/fw_appid.c : Stability improvement by resolving valgrind reported issues in AppId. * src/dynamic-preprocessors/ftptelnet/pp_ftp.c, file-process/file_api.h, file-process/file_resume_block.h, file-process/file_service.c, preprocessors/Session/session_common.h, Session/session_expect.c, Stream6/snort_stream_tcp.c, Stream6/snort_stream_tcp.h, Stream6/stream_common.h, parser.c, parser.h, snort.c, snort.h, dynamic-preprocessors/dcerpc2/dce2_smb.c, dynamic-preprocessors/ftptelnet/ftpp_si.h, dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, dynamic-preprocessors/ftptelnet/snort_ftptelnet.h, file-process/file_mime_process.c, file-process/libs/file_lib.c, preprocessors/snort_httpinspect.c, preprocessors/spp_normalize.c, preprocessors/spp_normalize.h, preprocessors/spp_stream6.c, preprocessors/stream_api.h, preprocessors/HttpInspect/client/hi_client.c : Fixed issue where FTP file type block doesn't work on retried download. * src/appIdApi.h, dynamic-plugins/sf_dynamic_plugins.c, dynamic-preprocessors/appid/appIdApi.c, dynamic-preprocessors/appid/flow.c, dynamic-preprocessors/appid/flow.h, dynamic-preprocessors/appid/fw_appid.c, dynamic-preprocessors/appid/fw_appid.h, dynamic-preprocessors/appid/detector_plugins/detector_sip.c : Fixed issue where Snort is inappropriately handling traffic for which AppId was creating future flow. * src/file-process/file_segment_process.c : Fixed issue of updating the file session information for SMB2 file transfer spanning multiple TCP sessions. * src/dynamic-preprocessors/appid/: flow.h, fw_appid.c, luaDetectorApi.c, service_state.c, service_state.h, detector_plugins/detector_dns.c, detector_plugins/detector_http.c, detector_plugins/detector_imap.c, detector_plugins/detector_kerberos.c, detector_plugins/detector_pattern.c, detector_plugins/detector_pop3.c, detector_plugins/detector_sip.c, detector_plugins/detector_smtp.c, service_plugins/service_MDNS.c, service_plugins/service_api.h, service_plugins/service_base.c, service_plugins/service_base.h, service_plugins/service_battle_field.c, service_plugins/service_bgp.c, service_plugins/service_bit.c, service_plugins/service_bootp.c, service_plugins/service_dcerpc.c, service_plugins/service_direct_connect.c, service_plugins/service_flap.c, service_plugins/service_ftp.c, service_plugins/service_irc.c, service_plugins/service_lpr.c, service_plugins/service_mysql.c, service_plugins/service_netbios.c, service_plugins/service_nntp.c, service_plugins/service_ntp.c, service_plugins/service_radius.c, service_plugins/service_rexec.c, service_plugins/service_rfb.c, service_plugins/service_rlogin.c, service_plugins/service_rpc.c, service_plugins/service_rshell.c, service_plugins/service_rsync.c, service_plugins/service_rtmp.c, service_plugins/service_snmp.c, service_plugins/service_ssh.c, service_plugins/service_ssl.c, service_plugins/service_telnet.c, service_plugins/service_tftp.c, service_plugins/service_timbuktu.c, service_plugins/service_tns.c, test/appIdTests.c, test/sessionFile.c : Changes in AppId discovery to address session and services related issues. * src/dynamic-preprocessors/appid/: appId.h, fw_appid.c : Performance improvements for SIP/RTP audio and video data flow in AppId . * src/dynamic-preprocessors/appid/: fw_appid.c, thirdparty_appid_utils.c, test/appIdTests.c, test/externalApis.c : Fixed an issue related to incorrect processing of XFF addresses during Snort reload. * src/dynamic-preprocessors/appid/luaDetectorModule.c : Improved error handling in luadetector when lua_State object is NULL. * src/preprocessors/snort_httpinspect.c : Improved flushing mechanism for HTTP POST header. * src/output-plugins/spo_log_buffer_dump.c : Fixed an issue where HTTP buffers were incorrectly dumped as DNS payload buffers. * src/preprocessors/Stream6/snort_stream_tcp.c : Prevent application preprocessors from processing packets having end_sequence numbers less than current TCP window base. 2016-11-07 Gagan Sachdeva Snort 2.9.9.0 * src/build.h : updating build number to 56. * tools/u2spewfoo/u2spewfoo.c : src/snort.c, win32/WIN32-Includes/config.h : Fixed Issue related to DLL-Load in Snort on Windows platforms For CVE-2016-1417, thanks to Secureworks for reporting this issue. * src/: detection_filter.c, detection_filter.h, fpdetect.c, detection-plugins/detection_options.c, detection-plugins/detection_options.h, sfutil/sfthd.c, sfutil/sfthd.h, sfutil/test/sfthd_test.c : Incrementing detection_filter count on either raw packets or re-assembled packets but not on both. * src/detection-plugins/sp_byte_jump.c : Fixed an issue where value present in the zero index of byte_extract array was incorrectly used when byte_extract rule option is not present. 2016-09-08 Seshaiah Erugu Snort 2.9.9 * src/build.h : Updated build number to 82. * src/dynamic-preprocessors/appid/: appId.h, fw_appid.c, spp_appid.c: Improved handling of HTTP tunneling in AppId. * src/detection-plugins/sp_byte_jump.c: Fixed a bug where byte_jump postoffset was incorrectly initialized leading to failure in rule matching in some scenarios. * src/detection-plugins/sp_rpc_check.c: Fixed RPC decode plugin issue where rule context was missing and RPC values were not read correctly. * sfeng/ims/sfsnort/snort/src/dynamic-preprocessors/smtp/snort_smtp.c : Fixed an issue in mime data processing in case of stateless inspection. * sfeng/ims/sfsnort/snort/src/preprocessors/: spp_session.c, Stream6/stream_paf.c : Addressed incorrect flushing of packets whose size is greater than MAXIMUM_PAF_MAX. * sfeng/ims/sfsnort/snort/src/output-plugins/spo_log_buffer_dump.c : Added banner message with packet timestamp for every buffer dump. * sfeng/ims/sfsnort/snort/src/: snort.h, dynamic-preprocessors/dcerpc2/dce2_paf.c, dynamic-preprocessors/dnp3/dnp3_paf.c, dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, dynamic-preprocessors/imap/imap_paf.c, dynamic-preprocessors/modbus/modbus_paf.c, dynamic-preprocessors/modbus/modbus_paf.h, dynamic-preprocessors/pop/pop_paf.c, dynamic-preprocessors/sip/sip_paf.c, dynamic-preprocessors/smtp/smtp_paf.c, preprocessors/snort_httpinspect.c, preprocessors/spp_stream6.c, preprocessors/stream_api.h, preprocessors/HttpInspect/client/hi_client.c, preprocessors/HttpInspect/utils/hi_paf.c, preprocessors/Stream6/snort_stream_tcp.c, preprocessors/Stream6/stream_paf.c, preprocessors/Stream6/stream_paf.h : Generating an event when content-length in a POST request is greater than Payload. * sfeng/ims/sfsnort/snort/src/decode.c : Decoding support for packets that contain VLAN and SGT. * sfeng/ims/sfsnort/snort/src/preprocessors/HttpInspect/client/hi_client.c : Fixed Coverity issue - added null check before usage. * sfeng/ims/sfsnort/snort/src/preprocessors/snort_httpinspect.c : Fixed Coverity issue - added null check for Field_Name. * sfeng/ims/sfsnort/snort/src/preprocessors/Stream6/snort_stream_tcp.c : Fixed an issue where out-of-bounds memory access (is possible) due to incorrect length argument in memcpy. * sfeng/ims/sfsnort/snort/src/preprocessors/spp_stream6.c : Resolved an issue where stream_config is not set (to) correct value in some cases after reload. * sfeng/ims/sfsnort/snort/src/file-process/: file_segment_process.c, file_service.c : Changes done to avoid memory allocation for each signature callback and handle segments properly when file session has not been created yet. * sfeng/ims/sfsnort/snort/preproc_rules/preprocessor.rules : Added new http prepreocessor alert for multiple content encoding. alert ( msg: "HI_SERVER_MULTIPLE_CONTENT_ENCODING"; sid:20; gid: 120; rev: 1; metadata: rule-type preproc ; classtype:unknown; ). * sfeng/ims/sfsnort/snort/src/dynamic-preprocessors/appid/fw_appid.c : Changes done to handle empty HTTP XFF field. * sfeng/ims/sfsnort/snort/src/dynamic-preprocessors/appid/service_plugins/service_base.c : Changed initiator_ip to be in sync with other ip's. * sfeng/ims/sfsnort/snort/src/dynamic-preprocessors/appid/fw_appid.c : Fixed an issue where AppId was skipping inspection of some HTTP requests. * sfeng/ims/sfsnort/snort/src/dynamic-plugins/sf_dynamic_plugins.c : Fixed compiler warning by changing the definition of dummyConsumeHAState() function. * sfeng/ims/sfsnort/snort/src/dynamic-preprocessors/appid/: fw_appid.c, detector_plugins/detector_smtp.c : Fixed AppId compilation warnings. * sfeng/ims/sfsnort/snort/src/: parser.c, parser.h, snort.c, snort.h, preprocessors/spp_normalize.c, preprocessors/spp_normalize.h, preprocessors/spp_stream6.c, preprocessors/stream_api.h, preprocessors/Session/session_common.h, preprocessors/Session/session_expect.c, preprocessors/Stream6/snort_stream_tcp.c : Fixed an issue where Malware files not getting dropped over FTP protocol. * sfeng/ims/sfsnort/snort/src/dynamic-preprocessors/appid/appInfoTable.c : Fixed issue with using dynamic app ID names (not in appMapping.data) in Snort rules. * sfeng/ims/sfsnort/snort/src/preprocessors/HttpInspect/utils/hi_paf.c : Handling HTTP header line containing \r or \r\r. * sfeng/ims/sfsnort/snort/src/dynamic-preprocessors/appid/: flow.h, fw_appid.c, thirdparty_appid_types.h : Performance improvement in Appid. * sfeng/ims/sfsnort/snort/src/: file-process/file_service.c, preprocessors/snort_httpinspect.c, preprocessors/snort_httpinspect.h : Added support to detect partial content when it starts in second reassembled packet. * sfeng/ims/sfsnort/snort/src/preprocessors/: snort_httpinspect.c, snort_httpinspect.h, HttpInspect/client/hi_client.c HTTP preprocessor enhanced to handle the split of chunk length itself across different packets. * sfeng/ims/sfsnort/snort/src/decode.c : Fixed an issue where single packet can cause a segmentation fault if there is a specific snort rule is in place. Thanks to Marcel da Silva for reporting this issue. * sfeng/ims/sfsnort/snort/src/decode.c : Fixed an issue where incorrect byte order was been used for comparision with hard coded value. Thanks to Al Lewis who reported this issue on open source. * sfeng/ims/sfsnort/snort/src/preprocessors/: spp_session.c, spp_stream6.c, Session/session_common.h, Stream6/snort_stream_tcp.c : This patch changes the logic in session to set a flag in the SCB for a flow on the first packet after a reload to indicate the stream config pointer is stale. Previously the pointer was set to NULL. Stream was changed to check this stale flag and, if true, the stream config pointer in the SCB is reinitialized. With this change the stream configuration pointer continues to point to the old configuration which will still be valid until the stream preproc runs. This ensures that the part of the SSL preproc that runs before Session/Stream have run will have a valid stream config pointer after a reload. In addition the StreamActivatePafTcp function, which is called by the SSL preproc and requires a valid stream configuration, was changed to check for the pointer being NULL and if it is it will reinitialize the pointer to valid value and log a warning message. * sfeng/ims/sfsnort/snort/doc/snort_manual.tex : Snort manual updated with Buffer dump feature. * sfeng/ims/sfsnort/snort/doc/snort_manual.tex : Snort manual changed with Rule Options Enhancement. * sfeng/ims/sfsnort/snort/src/sfutil/sfghash.c : Added NULL check for SFGHASH. * sfeng/ims/sfsnort/snort/etc/sf_rule_options : Error message is updated for byte_extract options. When creating a rule with byte_extract option an error message is sent when the rule doesn't include a variable name, which is mandatory. * sfeng/ims/sfsnort/snort/src/: encode.c, preprocids.h, detection-plugins/sp_byte_math.c, dynamic-output/plugins/output_lib.h, dynamic-preprocessors/ftptelnet/pp_ftp.c, preprocessors/perf-base.c, preprocessors/snort_httpinspect.c, preprocessors/spp_stream6.c, preprocessors/HttpInspect/server/hi_server.c, sfutil/sf_ip.h, win32/WIN32-Prj/snort.dsp : Addressed issues in Snort Windows build. * sfeng/ims/sfsnort/snort/src/detection-plugins/: sp_byte_check.c, sp_byte_jump.c, sp_byte_math.c : An error message is sent if string rule option is not present when bytes to grab are greater than 4 bytes in byte_math rule. * sfeng/ims/sfsnort/snort/src/preprocessors/Stream6/snort_stream_tcp.c : Resolved an incorrect logging of source and destination ip when TCP stream queue is full. * sfeng/ims/sfsnort/snort/src/detection-plugins/sp_byte_math.c : Error message is updated for byte_math options. When creating a rule with byte_math option an error message is sent when the rule doesn't include offset and rvalue. * sfeng/ims/sfsnort/snort/src/dynamic-preprocessors/appid/: Makefile_defs, fw_appid.c, client_plugins/client_app_base.c, client_plugins/client_app_smtp.c, client_plugins/client_app_smtp.h, detector_plugins/detector_base.c, detector_plugins/detector_smtp.c, service_plugins/service_base.c, service_plugins/service_smtp.c, service_plugins/service_smtp.h : Added SMTP detection to AppID, added detector_smtp.c file as part of this enhancement. 2016-05-12 Seshaiah Erugu Snort 2.9.9 Beta * src/build.h : Updated build number to 4065. * src/dynamic-preprocessors/appid/fw_appid.c : Fix for handling bogus client AppIds for AppleCoreMedia. * src/preprocessors/spp_arpspoof.c : Added 802.11/wifi header support in ARP Preprocessor. * src/: detect.c, dynamic-plugins/sf_engine/sf_snort_packet.h, preprocessors/session_api.h, preprocessors/Stream6/snort_stream_tcp.c : Changed RST handling on closed tcp connection. * src/dynamic-preprocessors/appid/appInfoTable.c : Fixed a compilation issue in AppId. * src/: appIdApi.h, dynamic-preprocessors/appid/appIdApi.c, dynamic-preprocessors/appid/flow.h, dynamic-preprocessors/appid/fw_appid.c, dynamic-preprocessors/appid/httpCommon.h, dynamic-preprocessors/appid/luaDetectorApi.c, dynamic-preprocessors/appid/thirdparty_appid_types.h, dynamic-preprocessors/appid/detector_plugins/detector_http.c, dynamic-preprocessors/appid/detector_plugins/detector_http.h : Added support for Host, User-Agent, and Referer fields to be rewritten. * src/dynamic-preprocessors/appid/: appIdApi.c, appInfoTable.h, fw_appid.c, luaDetectorApi.c, detector_plugins/detector_http.c, service_plugins/service_ftp.c, service_plugins/service_tftp.c : Fixed AppId compilation warnings. * src/preprocessors/Session/stream5_ha.c : Fix updates HA sf_base counters during failover. * src/dynamic-preprocessors/appid/fw_appid.c, src/dynamic-preprocessors/appid/: appId.h : Fix Reconstructed the call to port-service detection. * src/dynamic-preprocessors/appid/test/appIdTests.c : Fixed an AppId compilation issue. * src/dynamic-preprocessors/appid/appId.h : Revised appid.h to have APP_ID_ICMP and APP_ID_ICMPV6. * src/dynamic-preprocessors/appid/: httpCommon.h, luaDetectorApi.c, detector_plugins/detector_http.c : Added DEFER_TO_SIMPLE_DETECT action to CHPAddAction. * src/preprocessors/HttpInspect/: event_output/hi_eo_log.c, New HTTP prepocessor alert added for Multiple content encodings. * src/preprocessors/Stream6/snort_stream_tcp.c : Fix populates DAQ_PktHdr_t of the packet generated while flushing queued segments with src and dst IP's. * src/preprocessors/HttpInspect/: client/hi_client.c, event_output/hi_eo_log.c, include/hi_eo_events.h, server/hi_server.c : New HTTP preprocessor alert added for multiple content lengths. * src/dynamic-preprocessors/appid/: fw_appid.c, service_plugins/service_rshell.c : Fix reduces extra service discovery to improve performance. * src/preprocessors/HttpInspect/client/hi_client.c : Fix to handle chunk encoding followed by \r\r\r\n and \n\n\n\r\r\n. This issue was reported by Steffen Ullrich. * src/: detection_filter.c, detection_filter.h, fpdetect.c, detection-plugins/detection_options.c, detection-plugins/detection_options.h, sfutil/sfthd.c, sfutil/sfthd.h, sfutil/test/sfthd_test.c : Fix related to detection_options. Added a new variable detection_filter_count to detection_option_eval_data_t data structure and set it when detection_filter_test is called for first time. * src/dynamic-preprocessors/appid/: fw_appid.c, test/appIdTests.c : Fix picks last IP address in XFF address list. * src/decode.c : Added an additional check for divisibility of the length of the PGM header by 4. If it's not, then an error is returned instead of calculating the checksum. * src/dynamic-preprocessors/appid/fw_appid.c : Changed ignore tp appid logic. * src/preprocessors/HttpInspect/server/hi_server.c : File filled with delimiters now successfully gets detected. * src/dynamic-preprocessors/appid/service_plugins/service_ftp.c : Fix ignores text after FTP response codes. * src/preprocessors/HttpInspect/server/hi_server.c : Modified Http header parsing of multiline content-encoding header. * src/: appIdApi.h, dynamic-preprocessors/appid/appIdApi.c, dynamic-preprocessors/appid/appInfoTable.h, dynamic-preprocessors/appid/flow.h, dynamic-preprocessors/appid/fw_appid.c, dynamic-preprocessors/appid/luaDetectorApi.c, dynamic-preprocessors/appid/detector_plugins/detector_http.c : Made changes in getHttpSearch() to return value based on any payloadAppId match, not just CHP patterns. * src/preprocessors/: snort_httpinspect.c, HttpInspect/server/hi_server.c : Fixed Coverity issue - Unsigned compared against 0. * src/preprocessors/: snort_httpinspect.c, HttpInspect/server/hi_server.c : Improved chunked gzip content handling. * src/: dynamic-preprocessors/sdf/spp_sdf.c, obfuscation.c : Fix to mask sensitive data spanning multiple raw packets. * src/sfutil/sfghash.c : Added NULL pointer checks to all the functions in sfghash.c. * src/preprocessors/spp_httpinspect.c : Fix Sets file_depth after Snort reload. * src/dynamic-preprocessors/appid/: fw_appid.c, httpCommon.h, luaDetectorApi.c, detector_plugins/detector_http.c, detector_plugins/detector_http.h : Fix allows multiple key patterns per AppId instance in CHPMultiAddAction(). * src/preprocessors/HttpInspect/files/file_decomp_SWF.c : Fixed an issue with LZMA flash decompression. * etc/sf_rule_options, src/detection-plugins/sp_byte_extract.c, src/detection-plugins/sp_byte_extract.h : Changed code to allow 1 to 10 bytes (bytes_to_extract )values in byte_extract rule. * configure.in, doc/snort_manual.tex, etc/snort.conf, rpm/snort.spec, src/dynamic-plugins/sf_dynamic_meta.h, src/dynamic-plugins/sf_engine/examples/detection_lib_meta.h, src/win32/WIN32-Includes/config.h, src/win32/WIN32-Prj/snort_installer.nsi : API version updated. * src/dynamic-preprocessors/appid/fw_appid.c : Fix prevents bogus generic clients, and also prevents things like "MPEG" showing up as a client in case of AppleCoreMedia. * src/detection-plugins/sp_byte_jump.c : Now from_end option acccepts 0-10 bytes in byte_jump rule. * src/dynamic-preprocessors/appid/: fw_appid.c, httpCommon.h : Added more AppId instances for CHPMultixxx Lua api. * configure.in, src/appIdApi.h, src/sfdaq.c, src/sfdaq.h, src/tag.c, src/dynamic-plugins/sf_dynamic_plugins.c, src/dynamic-preprocessors/appid/appIdApi.c, src/dynamic-preprocessors/appid/flow.c, src/dynamic-preprocessors/appid/flow.h, src/dynamic-preprocessors/appid/fw_appid.c, src/dynamic-preprocessors/appid/fw_appid.h, src/dynamic-preprocessors/appid/luaDetectorApi.c, src/dynamic-preprocessors/appid/luaDetectorApi.h, src/dynamic-preprocessors/appid/luaDetectorFlowApi.c, src/dynamic-preprocessors/appid/client_plugins/client_app_aim.c, src/dynamic-preprocessors/appid/client_plugins/client_app_base.c, src/dynamic-preprocessors/appid/client_plugins/client_app_bit.c, src/dynamic-preprocessors/appid/client_plugins/client_app_bit_tracker.c, src/dynamic-preprocessors/appid/client_plugins/client_app_msn.c, src/dynamic-preprocessors/appid/client_plugins/client_app_rtp.c, src/dynamic-preprocessors/appid/client_plugins/client_app_smtp.c, src/dynamic-preprocessors/appid/client_plugins/client_app_ssh.c, src/dynamic-preprocessors/appid/client_plugins/client_app_timbuktu.c, src/dynamic-preprocessors/appid/client_plugins/client_app_tns.c, src/dynamic-preprocessors/appid/client_plugins/client_app_vnc.c, src/dynamic-preprocessors/appid/client_plugins/client_app_ym.c, src/dynamic-preprocessors/appid/detector_plugins/detector_dns.c, src/dynamic-preprocessors/appid/detector_plugins/detector_http.c, src/dynamic-preprocessors/appid/detector_plugins/detector_imap.c, src/dynamic-preprocessors/appid/detector_plugins/detector_kerberos.c, src/dynamic-preprocessors/appid/detector_plugins/detector_pattern.c, src/dynamic-preprocessors/appid/detector_plugins/detector_pop3.c, src/dynamic-preprocessors/appid/detector_plugins/detector_sip.c, src/dynamic-preprocessors/appid/service_plugins/service_MDNS.c, src/dynamic-preprocessors/appid/service_plugins/service_api.h, src/dynamic-preprocessors/appid/service_plugins/service_base.c, src/dynamic-preprocessors/appid/service_plugins/service_base.h, src/dynamic-preprocessors/appid/service_plugins/service_battle_field.c, src/dynamic-preprocessors/appid/service_plugins/service_bgp.c, src/dynamic-preprocessors/appid/service_plugins/service_bit.c, src/dynamic-preprocessors/appid/service_plugins/service_bootp.c, src/dynamic-preprocessors/appid/service_plugins/service_dcerpc.c, src/dynamic-preprocessors/appid/service_plugins/service_direct_connect.c, src/dynamic-preprocessors/appid/service_plugins/service_flap.c, src/dynamic-preprocessors/appid/service_plugins/service_ftp.c, src/dynamic-preprocessors/appid/service_plugins/service_irc.c, src/dynamic-preprocessors/appid/service_plugins/service_lpr.c, src/dynamic-preprocessors/appid/service_plugins/service_mysql.c, src/dynamic-preprocessors/appid/service_plugins/service_netbios.c, src/dynamic-preprocessors/appid/service_plugins/service_nntp.c, src/dynamic-preprocessors/appid/service_plugins/service_ntp.c, src/dynamic-preprocessors/appid/service_plugins/service_radius.c, src/dynamic-preprocessors/appid/service_plugins/service_rexec.c, src/dynamic-preprocessors/appid/service_plugins/service_rfb.c, src/dynamic-preprocessors/appid/service_plugins/service_rlogin.c, src/dynamic-preprocessors/appid/service_plugins/service_rpc.c, src/dynamic-preprocessors/appid/service_plugins/service_rshell.c, src/dynamic-preprocessors/appid/service_plugins/service_rsync.c, src/dynamic-preprocessors/appid/service_plugins/service_rtmp.c, src/dynamic-preprocessors/appid/service_plugins/service_smtp.c, src/dynamic-preprocessors/appid/service_plugins/service_snmp.c, src/dynamic-preprocessors/appid/service_plugins/service_ssh.c, src/dynamic-preprocessors/appid/service_plugins/service_ssl.c, src/dynamic-preprocessors/appid/service_plugins/service_telnet.c, src/dynamic-preprocessors/appid/service_plugins/service_tftp.c, src/dynamic-preprocessors/appid/service_plugins/service_timbuktu.c, src/dynamic-preprocessors/appid/service_plugins/service_tns.c, src/dynamic-preprocessors/appid/test/appIdTests.c, src/dynamic-preprocessors/appid/util/common_util.h, src/file-process/file_resume_block.c, src/preprocessors/Session/session_expect.c, src/preprocessors/Stream6/snort_stream_tcp.c : Added the flag to prevent third-party application identification to expected connections. Changed the internal and external flags field into one 64-bit flags field. Added address space and instance to AppID debug. Cleaned up some compiler warnings. Added the debugging flags and info to the service validator function to allow internal debugging. Fixed processing of packets without any payload. Fixed tftp and rshell detection. Fixed third-party application identification proto state for sessions after http. Fixed expected session allow for AppId continutation (tftp, snmp). * src/dynamic-preprocessors/appid/: appInfoTable.c, appInfoTable.h, fw_appid.h : Fixed the issue where AppId for Facebook over SPDY/HTTP 1.1 is incorrect. * src/dynamic-preprocessors/appid/fw_appid.c : Fixed Coverity warning for Uninitialized variable. * src/dynamic-preprocessors/appid/: httpCommon.h, luaDetectorApi.c, detector_plugins/detector_http.c : Changed code in CHPAddAction to REWRITE/INSERT side effect. * src/dynamic-preprocessors/appid/appInfoTable.c : Disabled internal AppID detectors for HTTP/2 by default. * src/preprocessors/HttpInspect/: include/h2_common.h, utils/h2_common.c, utils/h2_paf.c : Added support for HTTP/2. * src/dynamic-preprocessors/imap/imap_buffer_dump.c, src/dynamic-preprocessors/imap/imap_buffer_dump.h, src/dynamic-preprocessors/ftptelnet/ftptelnet_buffer_dump.c, src/dynamic-preprocessors/ftptelnet/ftptelnet_buffer_dump.h, src/dynamic-preprocessors/dcerpc2/dcerpc2_buffer_dump.c, src/dynamic-preprocessors/dcerpc2/dcerpc2_buffer_dump.h, src/dynamic-preprocessors/ssl/ssl_buffer_dump.c, src/dynamic-preprocessors/ssl/ssl_buffer_dump.h, src/dynamic-preprocessors/ssh/ssh_buffer_dump.c, src/dynamic-preprocessors/ssh/ssh_buffer_dump.h, src/dynamic-preprocessors/dns/dns_buffer_dump.c, src/dynamic-preprocessors/dns/dns_buffer_dump.h, src/dynamic-preprocessors/modbus/modbus_buffer_dump.c, src/dynamic-preprocessors/modbus/modbus_buffer_dump.h, src/preprocessors/HttpInspect/utils/hi_buffer_dump.c, src/preprocessors/HttpInspect/include/hi_buffer_dump.h, src/output-plugins/spo_log_buffer_dump.h, src/output-plugins/spo_log_buffer_dump.c, src/dynamic-preprocessors/smtp/smtp_buffer_dump.c, src/dynamic-preprocessors/smtp/smtp_buffer_dump.h, src/dynamic-preprocessors/sip/sip_buffer_dump.c, src/dynamic-preprocessors/sip/sip_buffer_dump.h, src/dynamic-preprocessors/pop/pop_buffer_dump.c, src/dynamic-preprocessors/pop/pop_buffer_dump.h, src/dynamic-preprocessors/dnp3/dnp3_buffer_dump.c, src/dynamic-preprocessors/dnp3/dnp3_buffer_dump.h, src/dynamic-preprocessors/gtp/gtp_buffer_dump.c, src/dynamic-preprocessors/gtp/gtp_buffer_dump.h, src/dynamic-preprocessors/imap/imap_buffer_dump.c : Added these files as part of Buffer-dump feature. * src/detection-plugins/sp_byte_math.c, src/detection-plugins/sp_byte_math.h : Added new rule option "byte_math". 2016-04-26 Rahul Burman Snort 2.9.8.3 * src/build.h: updating build number to 383 * configure.in, src/preprocessors/HttpInspect/server/hi_server.c: Modified Http header parsing of multiline content-encoding header. * src/preprocessors/: snort_httpinspect.c, HttpInspect/server/hi_server.c: Fixed an issue where file position pointer was incorrectly set for HTTP response containing chunked and gzip data. * src/preprocessors/Stream6/: snort_stream_tcp.c Added sanity check to TCP trimming in out-of-order FIN case. * src/parser.c: Disabled port groups that are not useful unless adapative profiling is enabled. * src/: dynamic-preprocessors/sdf/spp_sdf.c, obfuscation.c: Fixed an issue of incorrect masking of sensitive data. 2016-03-18 Gaurav Nagare Snort 2.9.8.2 * src/build.h: updating build number to 335 * src/dynamic-plugins/: sf_engine/examples/detection_lib_meta.h, sf_dynamic_meta.h: Updated detection API version to 2.6 to use the latest snort SO rules. * src/: dynamic-preprocessors/sdf/spp_sdf.c, preprocessors/Stream6/snort_stream_tcp.c, obfuscation.c: Fixed several issues with SDF and obfuscation. * src/: profiler.h, preprocessors/perf_indicators.c, preprocessors/perf_indicators.h: Resolved snort build issue with "--disable-perfprofiling" configure option. * src/: decode.c, decode.h: Added Double VLAN tagging support. * src/file-process/file_mime_process.c: Enhanced mime parsing by adding support for detecting files after unknown headers and no headers. * src/preprocessors/HttpInspect/server/hi_server.c: Fixed memory leak. * src/preprocessors/HttpInspect/utils/hi_paf.c: Fixed issue with gzip decompression. If the server response specifies Content-Encoding as GZIP, but no Content-Length field for HTTP version 1.0. * doc/snort_manual.pdf, src/preprocessors/snort_httpinspect.c, src/preprocessors/spp_httpinspect.c: Fixed Snort memory leak in parsing HTTP xff options. * src/preprocessors/spp_httpinspect.c: Fixed Coverity issues. * src/preprocessors/: snort_httpinspect.c, snort_httpinspect.h, HttpInspect/include/hi_paf.h, HttpInspect/server/hi_server.c, HttpInspect/utils/hi_paf.c: Improved End of Header(EOH) identification for response header spanning multiple reassembled packets. * src/preprocessors/: HttpInspect/utils/hi_paf.c, Stream6/snort_stream_tcp.c, Stream6/stream_paf.c: Improved packet reassembly for HTTP, added code to purge segment correctly when PAF decides to ignore packet upon reaching paf_max. * src/fpdetect.c: Fixed to use outer header callback functions when checking IP rule against outer IPs and inner header callback when checking against inner IPs. * src/preprocessors/spp_httpinspect.c: Fixed an issue where http_inspect current and default config had different file depth. * src/dynamic-preprocessors/appid/detector_plugins/detector_dns.c: Handled malformed DNS host in AppId. * src/file-process/: file_api.h, file_segment_process.c, file_service.c: Prevented access to file contexts which are pruned when memcap is reached. * src/dynamic-preprocessors/appid/: app_forecast.c, app_forecast.h, flow.h, fw_appid.c, spp_appid.c, thirdparty_appid_types.h: Performance improvements to AppID. * src/dynamic-preprocessors/appid/luaDetectorApi.c: Created a future-flow API for lua detector. Exposed DNS API to lua detector. * src/dynamic-preprocessors/ftptelnet/pp_ftp.c: Fixed an issue where unexpected SSL negotiation starts for FTP with explicit SSL. * src/preprocessors/HttpInspect/utils/hi_paf.c: Updated HTTP PAF to accept all tokens between method and version string in request URI. * src/preprocessors/HttpInspect/files/file_decomp_SWF.c: Fixed Flash LZMA decompression issue. * src/preprocessors/spp_httpinspect.c: Fixed file_depth intialization issue during Snort reload. 2015-11-18 Carter Waxman Snort 2.9.8.0 * src/build.h: updating build number to 229 * src/preprocessors/: session_api.h, spp_session.c, Session/session_expect.c, Session/session_expect.h: Added support for multiple expected sessions created for a single packet. * doc/: snort_manual.pdf, snort_manual.tex: Changed gtp ports in snort manual * src/: dynamic-preprocessors/ftptelnet/ftpp_si.c, dynamic-preprocessors/ftptelnet/ftpp_si.h, dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, preprocessors/spp_session.c: Change setAppProcolId to update SFAT for non-TCP traffic * src/dynamic-preprocessors/appid/spp_appid.c: Fixed reload issues * src/dynamic-preprocessors/appid/detector_plugins/detector_sip.c: Future flows are now created for both directions on SIP * src/dynamic-preprocessors/smtp/smtp_paf.c: Improved reliability of SMTP PAF * src/dynamic-preprocessors/appid/fw_appid.c: Bugs Fixed: Improved AppId detection on SSL/TLS protocols for decrypted * src/: dynamic-plugins/sf_engine/sf_snort_packet.h, dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, preprocessors/Stream6/snort_stream_tcp.c: Fixed FTP file detection where server SYNs data channel before responding to PORT on command channel. * src/dynamic-preprocessors/appid/: commonAppMatcher.c, fw_appid.c, fw_appid.h, service_plugins/service_ftp.c: Improved detection of data on FTPS data channel * src/: encode.c, util.h, dynamic-preprocessors/appid/test/sessionFile.h, preprocessors/spp_session.c, preprocessors/spp_stream6.c, preprocessors/Session/session_common.h: Added support for MPLS active responses * src/dynamic-preprocessors/appid/: detector_plugins/detector_pop3.c, service_plugins/service_ftp.c: Improved detection of POP3S * src/detection-plugins/sp_appid.c: Fixed reliability issue with client AppID IPS rules * preproc_rules/preprocessor.rules, src/dynamic-preprocessors/smtp/smtp_config.c, src/dynamic-preprocessors/smtp/smtp_config.h, src/dynamic-preprocessors/smtp/smtp_log.h, src/dynamic-preprocessors/smtp/smtp_paf.c: Added preproc alert for excessive data following "AUTH NTLM\r\n" "AUTH CRAM-MD5\r\n" * src/dynamic-preprocessors/reputation/: reputation_config.c, shmem/shmem_mgmt.c: Improved reliability of reputation shared memory on single-cpu systems * doc/: snort_manual.pdf, snort_manual.tex: Fix first/last typo in manual. Thanks Mohsen Abbaspour for reporting it. * src/dynamic-preprocessors/appid/spp_appid.c: Update AppID to use only global snort config and only process IP packets * src/dynamic-preprocessors/appid/service_plugins/service_tftp.c: Fixed reversal of TFTP detection had the source and destination address data * src/: detection-plugins/sp_byte_jump.c, dynamic-plugins/sf_convert_dynamic.c, dynamic-preprocessors/appid/appIdConfig.c, dynamic-preprocessors/appid/commonAppMatcher.c, dynamic-preprocessors/appid/fw_appid.c, dynamic-preprocessors/appid/luaDetectorApi.c, dynamic-preprocessors/appid/client_plugins/client_app_smtp.c, dynamic-preprocessors/appid/detector_plugins/detector_http.c, dynamic-preprocessors/appid/service_plugins/service_MDNS.c, dynamic-preprocessors/ftptelnet/hi_util_kmap.c, dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, dynamic-preprocessors/reputation/reputation_config.c, dynamic-preprocessors/sdf/sdf_detection_option.c, dynamic-preprocessors/ssl_common/ssl_config.c, dynamic-preprocessors/ssl_common/ssl_ha.c, output-plugins/spo_csv.c, preprocessors/spp_arpspoof.c, preprocessors/spp_session.c, preprocessors/HttpInspect/utils/hi_util_kmap.c, sfutil/ipobj.c, sfutil/sfghash.c: Added error checks to improve reliability * src/dynamic-preprocessors/appid/: flow.h, fw_appid.c, service_plugins/service_ssl.c, service_plugins/service_ssl.h: Fixed issue where appid info was not populated for ssl sessions on non-standard ports 2015-08-28 Rahul Burman Snort 2.9.8_rc * src/build.h: updating build number to 195 * src/preprocessors/HttpInspect/: client/hi_client.c, server/hi_server.c: NULL check added for call to strndup function. * src/output-plugins/spo_alert_unixsock.c: Resolved issue where output data is corrupted while writing to unix socket [reported by Alexander Bubnov]. * src/: dynamic-plugins/sf_dynamic_plugins.c, dynamic-plugins/sf_dynamic_preprocessor.h, dynamic-preprocessors/ftptelnet/ftpp_si.h, dynamic-preprocessors/ftptelnet/ftpp_ui_config.h, dynamic-preprocessors/ftptelnet/pp_ftp.c, dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: Improvements to FTP preprocessor to block malware when downloaded with a client that supports FTP REST. * src/dynamic-preprocessors/appid/fw_appid.c: Resolved issue where squid detector is not showing expected alerts. Reset app ID when SSL is identified on an FTP data channel. * src/preprocessors/spp_perfmonitor.c: Resolved snort output error issue in perfmonitor preprocessor * src/preprocessors/Stream6/snort_stream_tcp.c: Resolved issue where snort marks retransmitted packet as bad segment. Fixed issue where XFF/ExtraData is not always logged when 'drop' rules trigger [reported by Mike Cox]. * src/dynamic-preprocessors/reputation/reputation_config.c: Fixed unexpected behaviour in reputation config where blacklist is displayed in priority field even though whitelist option is set [reported by Mike Cox]. * src/: decode.h, snort.c, dynamic-plugins/sf_engine/sf_snort_packet.h, preprocessors/Stream6/snort_stream_tcp.c: Improvements done to avoid RETRY verdict for re-transmitted packet. * etc/gen-msg.map: Fixed a typo where ssp_ssl is renamed to spp_ssl * src/preprocessors/spp_session.c: Changes done to avoid memory allocation for default no. of sessions when session tracking is disabled. * doc/snort_manual.tex: Corrected errors in snort_manual.tex [reported by Gabriel Corre]. * src/dynamic-preprocessors/appid/: appId.h, appIdStats.c, service_plugins/service_ftp.c: Changes done to differentiate between active and passive FTP connections. * src/dynamic-preprocessors/appid/: appIdApi.c, appIdConfig.h, appInfoTable.c, flow.h, fw_appid.c, thirdparty_appid_api.h, thirdparty_appid_utils.c, detector_plugins/detector_http.c, detector_plugins/detector_sip.c: Fixed issues reported by valgrind in AppID. 2015-08-05 Victor Roemer Snort 2.9.8 Beta * src/build.h: Update build number to 176 * src/dynamic-preprocessors/appid/service_plugins/service_ftp.c: Snort to support EPRT command for active FTP on IPv4 and IPv6 * src/dynamic-preprocessors/ftptelnet/: ftpp_si.c, ftpp_si.h, pp_ftp.c: Some PDF files were not blocked by snort. * src/preprocessors/HttpInspect/client/hi_client.c: Check if packet has start of PDU before generating alert. * src/dynamic-preprocessors/smtp/smtp_util.c: SMTP preprocessor email log buffer length update before copying to avoid assert failure. * src/: active.c, decode.h, preprocids.h, detection-plugins/sp_react.c, dynamic-plugins/sf_engine/sf_snort_packet.h, dynamic-preprocessors/appid/spp_appid.c, dynamic-preprocessors/reputation/spp_reputation.c, preprocessors/spp_session.c: Sessions that are blocked and trusted. Fix sp_react when sending data. * src/dynamic-preprocessors/appid/: flow.h, fw_appid.c, detector_plugins/detector_http.c: Skip simple detection only for those CHP actions that could overrirde client ID, payload ID, etc. * doc/snort_manual.tex: Correct Unified2 Packet content. * etc/snort.conf, src/preprocessors/snort_httpinspect.c, src/preprocessors/snort_httpinspect.h, src/preprocessors/HttpInspect/client/hi_client.c, src/preprocessors/HttpInspect/server/hi_server.c, src/preprocessors/Stream6/stream_paf.c: Clear True-IP and XFF between HTTP transactions. Prevents Snort from logging extra data on transactions incorrectly. * src/sfutil/sf_ip.h: Treat 0.0.0.0/0 as "any" ipv4 address, fixing rule matches on ip header leaf node. * src/preprocessors/perf-base.c: Fixed macro usage to work with ICC and C89. * src/preprocessors/perf-base.c: Fixed erroneous performance values being generated when Snort is idle. * src/dynamic-preprocessors/appid/: service_plugins/service_api.h, util/NetworkSet.h: Fixed appid compilation issues for FreeBSD and OpenBSD. * tools/appid_detector_builder.sh: Fix script shortcomings for HTTP URL, Copyright, DetectorClean() stub. * src/decode.c: Snort min_ttl decoder rules drop regardless of alert/drop type. * src/dynamic-preprocessors/appid/luaDetectorApi.c: Set active flag for sandboxing for SSL Lua detectors. * src/: active.h, sfdaq.c, sfdaq.h, snort.c, dynamic-plugins/sf_dynamic_plugins.c, dynamic-plugins/sf_dynamic_preprocessor.h, file-process/file_service.c: Add support for DAQ Retry detection of the current packet. This change adds active response api function to request a packet retry (method added to dpd struct as well) and to query if the packet disposition is ACTIVE_RETRY. * src/preprocessors/: spp_session.c, Session/stream5_ha.c, Session/stream5_ha.h: preprocessors/Stream6/snort_stream_tcp.c: preprocessors/spp_session.c: If session lookup fails for a packet being processed by the Session preprocessor while DAQ HA is enabled and DAQ HA state is available for the packet, retrieve and process the HA state from the DAQ and retry the lookup. Do not store DAQ HA state when unsupported tunnel types are decoded that might make the underlying hardware's concept of flows not match Snort's. * src/dynamic-preprocessors/file/: file_agent.c, file_agent.h, spp_file.c: Support daemon option with file_inspect preprocessor. * src/preprocessors/Stream6/snort_stream_tcp.c: When processing asymmetric traffic, TCP segements are no longer queued indefinately, reducing session cache thrashing caused by excessive prunning. * src/preprocessors/HttpInspect/session_inspection/hi_si.c: Fix false positive on HI_ANOM_SERVER_ALERT. * src/dynamic-preprocessors/appid/: detector_plugins/detector_pattern.c, service_plugins/service_api.h, service_plugins/service_base.c: C detectors were not enabled when testing with a pcap. * src/: event.h, sfutil/Unified2_common.h: Increase max size for app ID names so they don't get truncated in alerts. * src/dynamic-preprocessors/appid/commonAppMatcher.c: Fix an issue with old/new config and AppID reload swap. * src/dynamic-preprocessors/appid/service_plugins/service_bootp.c: Fix in AppId bootp srevice plugin for packets without layer 2 header. * snort.8: Updated -q and -M switch description in snort manpage. * src/dynamic-preprocessors/appid/: flow.h, fw_appid.c, detector_plugins/detector_pattern.h, util/NetworkSet.h, util/OutputFile.c, util/sfutil.c: Fix Snort compilation issues on OSX when AppID is enabled. * src/: dynamic-plugins/sf_dynamic_define.h, dynamic-plugins/sf_engine/sf_snort_plugin_api.h, dynamic-plugins/sf_engine/examples/sfsnort_dynamic_detection_lib.h, dynamic-plugins/sf_preproc_example/sf_dynamic_preproc_lib.h, dynamic-preprocessors/appid/appId.h, dynamic-preprocessors/appid/flow.h, dynamic-preprocessors/appid/host_tracker.h, dynamic-preprocessors/appid/rna_flow.h, dynamic-preprocessors/appid/service_state.h, dynamic-preprocessors/appid/spp_appid.c, dynamic-preprocessors/appid/thirdparty_appid_api.h, dynamic-preprocessors/appid/client_plugins/client_app_api.h, dynamic-preprocessors/appid/client_plugins/client_app_bit.c, dynamic-preprocessors/appid/client_plugins/client_app_bit_tracker.c, dynamic-preprocessors/appid/client_plugins/client_app_rtp.c, dynamic-preprocessors/appid/client_plugins/client_app_ssh.c, dynamic-preprocessors/appid/client_plugins/client_app_timbuktu.c, dynamic-preprocessors/appid/client_plugins/client_app_tns.c, dynamic-preprocessors/appid/client_plugins/client_app_vnc.c, dynamic-preprocessors/appid/detector_plugins/detector_dns.c, dynamic-preprocessors/appid/detector_plugins/detector_imap.c, dynamic-preprocessors/appid/detector_plugins/detector_kerberos.c, dynamic-preprocessors/appid/detector_plugins/detector_pop3.c, dynamic-preprocessors/appid/detector_plugins/detector_sip.c, dynamic-preprocessors/appid/service_plugins/service_base.c, dynamic-preprocessors/appid/service_plugins/service_bit.c, dynamic-preprocessors/appid/service_plugins/service_timbuktu.c, dynamic-preprocessors/appid/service_plugins/service_tns.c, side-channel/dynamic-plugins/sf_dynamic_side_channel_lib.h: Rename SO_PUBLIC to SF_SO_PUBLIC. Removed unused appid/rna code. * doc/README.appid, rpm/snort.spec, tools/Makefile.am, tools/appid_detector_builder.sh: Added shell script to build simple LUA detectors for Snort. * src/dynamic-preprocessors/appid/: luaDetectorApi.c, client_plugins/client_app_base.c, client_plugins/client_app_base.h: Add sanity checks for lua client mod calls. Add function for service detectors to add clients. Open client-side API to allow clients to be added outside of client api. * configure.in, src/dynamic-output/plugins/output_lib.h: Don't export visibility hidden or invalid daq include path. * src/dynamic-preprocessors/appid/service_plugins/service_tftp.c: Switch source and destination when adding the expected flow. * doc/README.stream5, doc/snort_manual.tex, etc/snort.conf, src/preprocessors/Stream6/snort_stream_tcp.c: Added a new configure option "log_asymmetric_traffic" to turn on/off logging the message for asymmetric traffic. By default, it will be turned off. * src/detect.c: Call correct function to get app names for alerts. * configure.in, src/dynamic-preprocessors/appid/dns_defs.h, src/dynamic-preprocessors/appid/client_plugins/client_app_rtp.c, src/dynamic-preprocessors/appid/service_plugins/service_api.h, src/dynamic-preprocessors/appid/service_plugins/service_netbios.c: Replace use of __BYTE_ORDER with use of WORDS_BIGENDIAN or SF_BIGENDIAN. * src/dynamic-preprocessors/appid/fw_appid.c: Free http_session->new_uri and new_cookie before reassigning. * src/: preprocessors/spp_normalize.c, snort.h: When normaization is removed from snort conf, a reload would not disable it in Stream. * src/preprocessors/perf_indicators.h: Added a NULL check for a pointer argument in a perf_indicator utility inline function. * src/: parser.c, preprocessors/Stream6/snort_stream_tcp.c, sfutil/sfPolicyUserData.h: Fixed an issue where stream fails during multiple-policy configuration if stream_tcp configs are present in the default, but not child policies. * src/dynamic-preprocessors/appid/appInfoTable.c: App name(s) in Snort rules are now case insensitive. * doc/snort_manual.tex, src/preprocessors/snort_httpinspect.c, src/preprocessors/snort_httpinspect.h, src/preprocessors/spp_httpinspect.c, src/preprocessors/stream_api.h, src/preprocessors/HttpInspect/include/hi_si.h, src/preprocessors/HttpInspect/include/hi_ui_config.h, src/preprocessors/HttpInspect/server/hi_server.c, src/preprocessors/HttpInspect/session_inspection/hi_si.c, src/preprocessors/HttpInspect/utils/hi_paf.c, src/preprocessors/Session/session_common.h, src/preprocessors/Stream6/snort_stream_tcp.c, src/preprocessors/Stream6/stream_paf.c, src/preprocessors/Stream6/stream_paf.h: Stop reassembly if HTTP flow depth has been reached. * src/dynamic-preprocessors/appid/: fw_appid.c: Fix for core while processing SIP traffic from ignore sessions. * src/dynamic-preprocessors/appid/service_plugins/service_ssl.c: Fix for parsing SSL client hello packet (do not assume that this packet always contains extensions field). * src/: dynamic-preprocessors/dcerpc2/dce2_paf.c, dynamic-preprocessors/dnp3/dnp3_paf.c, dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, dynamic-preprocessors/imap/imap_paf.c, dynamic-preprocessors/pop/pop_paf.c, dynamic-preprocessors/sip/sip_paf.c, dynamic-preprocessors/smtp/smtp_paf.c, preprocessors/spp_stream6.c, preprocessors/stream_api.h, preprocessors/HttpInspect/utils/hi_paf.c, preprocessors/Session/session_common.h, preprocessors/Stream6/snort_stream_tcp.c, preprocessors/Stream6/snort_stream_tcp.h, preprocessors/Stream6/stream_paf.c, preprocessors/Stream6/stream_paf.h: Allow 2 PAF clients to be active at a time. * src/detection-plugins/detection_options.c: Detection_filter events incorrect both raw and reassembled packets used. Added a check that, if session is being reassembled, consider reassembled packet. Else, consider raw packet for count. When "no_stream" is present in the rule, need to consider raw packets only, even though session reassembly is happening. Took care of this case by adding OtnFlowIgnoreReassembled(otn) check. * src/sfutil/: sf_email_attach_decode.c, sf_email_attach_decode.h: Filename parsed from Mime body for UUencoded file. * src/: detect.c, detect.h, event_queue.c, event_queue.h, event_wrapper.c, event_wrapper.h, fpdetect.c, fpdetect.h, ppm.c, tag.c, tag.h, file-process/file_service.c, preprocessors/Stream6/snort_stream_tcp.c, sfutil/sfPolicyData.h, sfutil/sfrf.c: Internal (gid:135) rate filtering events now use runtime NAP instead of runtime IPS for rule tree lookups. * src/dynamic-preprocessors/Makefile.am: Fix for Snort compilation issue on OSX. * src/: appIdApi.h, decode.h, detect.c, snort.c, snort.h, dynamic-plugins/sf_dynamic_plugins.c, dynamic-plugins/sf_engine/sf_snort_packet.h, dynamic-preprocessors/appid/appIdApi.c, dynamic-preprocessors/appid/flow.c, dynamic-preprocessors/appid/flow.h, dynamic-preprocessors/appid/luaDetectorApi.c, dynamic-preprocessors/appid/luaDetectorApi.h, dynamic-preprocessors/appid/client_plugins/client_app_aim.c, dynamic-preprocessors/appid/client_plugins/client_app_api.h, dynamic-preprocessors/appid/client_plugins/client_app_base.c, dynamic-preprocessors/appid/client_plugins/client_app_base.h, dynamic-preprocessors/appid/client_plugins/client_app_bit.c, dynamic-preprocessors/appid/client_plugins/client_app_bit_tracker.c, dynamic-preprocessors/appid/client_plugins/client_app_msn.c, dynamic-preprocessors/appid/client_plugins/client_app_rtp.c, dynamic-preprocessors/appid/client_plugins/client_app_smtp.c, dynamic-preprocessors/appid/client_plugins/client_app_ssh.c, dynamic-preprocessors/appid/client_plugins/client_app_timbuktu.c, dynamic-preprocessors/appid/client_plugins/client_app_tns.c, dynamic-preprocessors/appid/client_plugins/client_app_vnc.c, dynamic-preprocessors/appid/client_plugins/client_app_ym.c, dynamic-preprocessors/appid/detector_plugins/detector_dns.c, dynamic-preprocessors/appid/detector_plugins/detector_imap.c, dynamic-preprocessors/appid/detector_plugins/detector_kerberos.c, dynamic-preprocessors/appid/detector_plugins/detector_pattern.c, dynamic-preprocessors/appid/detector_plugins/detector_pop3.c, dynamic-preprocessors/appid/detector_plugins/detector_sip.c, dynamic-preprocessors/appid/service_plugins/service_api.h, dynamic-preprocessors/appid/service_plugins/service_base.c, dynamic-preprocessors/appid/service_plugins/service_base.h, dynamic-preprocessors/appid/service_plugins/service_rpc.c, dynamic-preprocessors/ftptelnet/pp_ftp.c, dynamic-preprocessors/sip/sip_dialog.c, preprocessors/session_api.h, preprocessors/sip_common.h, preprocessors/spp_session.c, preprocessors/spp_session.h, preprocessors/spp_stream6.c, preprocessors/stream_api.h, preprocessors/Session/session_expect.c, preprocessors/Session/session_expect.h: Allow all preprocessors to create expected session calls. * src/dynamic-plugins/: sf_dynamic_plugins.c, sf_dynamic_preprocessor.h: Corrected function prototype definition for DP API method called to register an Active Response callback. * src/snort.c: Clean up the inline failopen thread before calling DAQ_Stop in SnortCleanup(). Prevent running in daemon mode from killing these threads. * src/preprocessors/: perf-base.h, perf.c: Don't clear procpidstats structure, so snort doesn't core. * src/dynamic-preprocessors/appid/: service_state.h, service_plugins/service_base.c: Restart service search state machine if previous session was only partial. * configure.in, src/sfdaq.c, src/sfdaq.h, src/dynamic-plugins/sf_dynamic_plugins.c, src/dynamic-plugins/sf_dynamic_preprocessor.h: Added accessor methods for DAQ query flow method. * src/preprocessors/snort_httpinspect.c: Added checks to prevent raw packets from being used for file process in HTTP. * src/dynamic-preprocessors/appid/: flow.h, fw_appid.c: Fix for processing HTTPS data to extract client app id. * src/preprocessors/: perf-base.c, Stream6/snort_stream_tcp.c: Prunes due to timouts will are now counted by perfmonitor as prunes. * doc/snort_manual.tex, src/parser.c, src/parser.h, src/snort.h, src/detection-plugins/detection_options.c: Introduced config option `disable_replace. * preproc_rules/preprocessor.rules, src/preprocessors/session_api.h, src/preprocessors/snort_httpinspect.c, src/preprocessors/HttpInspect/event_output/hi_eo_log.c, src/preprocessors/HttpInspect/include/hi_eo_events.h, src/preprocessors/Stream6/snort_stream_tcp.c etc/gen-msg.map: HI_EO_SERVER_PROTOCOL_OTHER alert is added to detect SSH tunneling over HTTP. * configure.in: Remove unused declaration of ADD_WERROR. * src/: active.c, detection-plugins/sp_react.c: Changed code to add FIN on last data packet and bump the seq for the FIN flag. * src/active.c: Added a FIN packet after the last data packet and before the reset. * src/dynamic-preprocessors/appid/fw_appid.c: Fixed HTTP header field offset calculation for fragmented HTTP headers. * doc/: snort_manual.pdf, snort_manual.tex: Added note about fast pattern matcher being case insensitive. * src/: dynamic-plugins/sf_dynamic_plugins.c, dynamic-plugins/sf_dynamic_preprocessor.h, dynamic-preprocessors/appid/spp_appid.c: Allow for multiple isAppIdRequired functions. * doc/snort_manual.tex: When not set by preprocessor, set file_data pointer to beg. of payload. Also fixed an issue when doe_ptr is moved to http buffers, the length for those buffers is incorrect. * src/: snort.c, preprocessors/perf.c, preprocessors/perf.h, preprocessors/spp_perfmonitor.c: Change the way perfmon dumps stats to ensure that multiple instances will dump stats at offsets from absolute time. This gives Snort the ability to dump stats asynchronously (when idle). * src/snort.c: Change the order of permissions drop and chroot so that we set the uid and gid before creating the pid file. * src/preprocessors/Stream6/snort_stream_tcp.c: Change PAF to handle full PDU in single tcp segment correctly. * src/decode.c: Prevent duplicate alerting of decoder rule 116:296. * src/dynamic-preprocessors/appid/fw_appid.c: Use memcpy instead of strdup. * src/dynamic-preprocessors/appid/detector_plugins/detector_http.c: Fixed the calculation of 'end' index in http_header_pattern_match when HTTP header does not have a properly terminated 'Server' field. * src/: log_text.c, log_text.h, output-plugins/spo_alert_fast.c, output-plugins/spo_alert_full.c: Add AppID to console alert logs. * src/dynamic-preprocessors/appid/: service_state.c, service_plugins/service_base.c: Don't fail adding a service if the id_state is already in the host cache. * src/dynamic-preprocessors/appid/fw_appid.c: Addressed pinhole issue not allowing FTP-Data sessions. * src/: decode.c, parser.c, sfdaq.c, sfdaq.h, snort.c, snort.h: Update snort to handle the DAQ flags to determine which tunnels it can render flow verdicts to hardware. * src/active.c: Included function for sending UDP response(s). * src/: sfutil/sfrt_flat.c, dynamic-preprocessors/reputation/reputation_config.c: Limit number of IP entries based on memcap. Avoiding issue of sfrt table not being created in the first place. * src/: tag.c, detection-plugins/detection_leaf_node.c, file-process/file_capture.c, file-process/file_mempool.c, file-process/file_resume_block.c, file-process/file_segment_process.c, file-process/file_segment_process.h, preprocessors/perf-flow.c, preprocessors/portscan.c, preprocessors/Session/session_expect.c, sfutil/sf_ip.h, sfutil/sfrf.c, sfutil/sfthd.c, sfutil/sfthd.h: Replaced all sfaddr_t occurrences in hash keys with struct in6_addr. * src/sfutil/sfdebug.h, tools/control/sfcontrol.c: Fixed ascii output of file data. * src/: profiler.h, snort.c, dynamic-plugins/sf_dynamic_plugins.c, dynamic-plugins/sf_dynamic_preprocessor.h, dynamic-preprocessors/Makefile.am, preprocessors/Makefile.am, preprocessors/perf_indicators.c, preprocessors/perf_indicators.h: New dynamic-preprocessor API hooks for fetching a set of snort performance indicators and the pcap readback mode bit. * src/sfutil/sfdebug.h, tools/control/sfcontrol.c: Fixed string termination to only dump values that have been initialized. * src/sfutil/: sfrt_flat.c, sfrt_flat.h, sfrt_flat_dir.c, sfrt_flat_dir.h: Memory optimizations for reputation preprocessor * src/: decode.h, detect.c, detection_util.c, plugbase.c, plugbase.h, preprocids.h, snort.h, dynamic-plugins/sf_engine/Makefile.am, dynamic-plugins/sf_engine/sf_snort_packet.h, preprocessors/spp_frag3.c, preprocessors/spp_session.c, sfutil/sf_ip.c, sfutil/sf_ip.h: Changed the preprocessor mask from 32-bit to 64-bit. Changed all declarations to use PreprocEnableMask as the type. * src/: file-process/file_resume_block.c, sfutil/sfxhash.c, sfutil/sfxhash.h: Added a memcap to sfxhash usage in file_resume_block. * src/dynamic-preprocessors/dcerpc2/: dce2_smb2.c, dce2_smb2.h, dce2_stats.h, spp_dce2.c: Currently, we use file size to avoid processing pipe and print share data because file size is 0 in that case. However, for smbclient, it sets file size to be zero which snort fails to identify those files correctly. * src/: dynamic-preprocessors/appid/commonAppMatcher.c, dynamic-preprocessors/appid/hostPortAppCache.c, dynamic-preprocessors/appid/lengthAppCache.c, dynamic-preprocessors/appid/service_state.c, dynamic-preprocessors/appid/util/NetworkSet.c, preprocessors/Session/session_expect.c, sfutil/sfxhash.c, sfutil/sfxhash.h: Create SFXHASH with non-negative sizes only. * doc/snort_manual.tex: Documentation for new Port Override feature. * src/dynamic-preprocessors/appid/: luaDetectorApi.c, luaDetectorApi.h, client_plugins/client_app_base.c, detector_plugins/detector_pattern.c, service_plugins/service_base.c: Fix memory leaks in detector_pattern. * src/dynamic-preprocessors/appid/service_plugins/service_dns.c, src/dynamic-preprocessors/appid/service_plugins/service_base.c, src/dynamic-preprocessors/appid/service_plugins/service_api.h, src/dynamic-preprocessors/appid/fw_appid.h, src/dynamic-preprocessors/appid/fw_appid.c, src/dynamic-preprocessors/appid/appIdApi.c, src/dynamic-plugins/sf_dynamic_plugins.c, src/appIdApi.h: Included 2 new Appid Api calls for DNS_QUERY and DNS_QUERY_LEN. * src/preprocessors/HttpInspect/client/hi_client.c: Enable publishing of host name from raw packets for Appid. * src/: post_detection.c, post_detection.h: Inline modifier removed from post detection initialization function. * src/post_detection.h: Remove static modifier from inline function definition. * src/decode.c: FabricPath decoding modified the packet data pointer and length fields used to caluclate ethernet header offesets incorrectly. * src/: Makefile.am, decode.h, detect.c, post_detection.c, post_detection.h, snort.c, dynamic-examples/Makefile.am, dynamic-plugins/sf_dynamic_plugins.c, dynamic-plugins/sf_dynamic_preprocessor.h, dynamic-plugins/sf_engine/sf_snort_packet.h, dynamic-preprocessors/Makefile.am: Provide an API method available to all preprocessors to register a callback function that is called post-detection processing of the packet on which the callback was registered. * src/dynamic-preprocessors/appid/: commonAppMatcher.c, thirdparty_appid_api.h, thirdparty_appid_utils.c: Use Snort's logging facility for 3rd party AppID impls. * src/: decode.c, decode.h, encode.c, generators.h, sf_protocols.h, dynamic-plugins/sf_engine/sf_snort_packet.h: Added a decoding for Cisco Metadata headers. * src/dynamic-preprocessors/appid/: commonAppMatcher.c, fw_appid.c, fw_appid.h, client_plugins/client_app_api.h, client_plugins/client_app_base.c, detector_plugins/detector_pattern.c, detector_plugins/detector_sip.c, service_plugins/service_api.h, service_plugins/service_base.c, service_plugins/service_base.h, util/sf_mlmp.c, util/sf_mlmp.h: Fixes for sandboxing sip and http. * src/dynamic-preprocessors/appid/: appIdConfig.c, luaDetectorApi.c, detector_plugins/detector_imap.c, detector_plugins/detector_kerberos.c, detector_plugins/detector_pop3.c, detector_plugins/detector_sip.c, service_plugins/service_MDNS.c, service_plugins/service_battle_field.c, service_plugins/service_bgp.c, service_plugins/service_bit.c, service_plugins/service_bootp.c, service_plugins/service_dcerpc.c, service_plugins/service_direct_connect.c, service_plugins/service_dns.c, service_plugins/service_flap.c, service_plugins/service_ftp.c, service_plugins/service_irc.c, service_plugins/service_lpr.c, service_plugins/service_mysql.c, service_plugins/service_netbios.c, service_plugins/service_nntp.c, service_plugins/service_ntp.c, service_plugins/service_radius.c, service_plugins/service_rexec.c, service_plugins/service_rfb.c, service_plugins/service_rlogin.c, service_plugins/service_rpc.c, service_plugins/service_rshell.c, service_plugins/service_rsync.c, service_plugins/service_rtmp.c, service_plugins/service_smtp.c, service_plugins/service_snmp.c, service_plugins/service_ssh.c, service_plugins/service_ssl.c, service_plugins/service_telnet.c, service_plugins/service_tftp.c, service_plugins/service_timbuktu.c, service_plugins/service_tns.c: Initialize current_ref_count for all service plugins. * src/: detection-plugins/sp_appid.c, dynamic-preprocessors/appid/fw_appid.c: Fixed AppID in snort rules, trim appNames. * src/dynamic-preprocessors/appid/: flow.h, fw_appid.c, host_tracker.h, service_state.h, client_plugins/client_app_base.c, service_plugins/service_base.c: Allow multiple service and client detectors to be evaluated on that same flow. * src/dynamic-preprocessors/appid/: Makefile.am, appIdConfig.h, commonAppMatcher.c, luaDetectorApi.c, luaDetectorApi.h, luaDetectorModule.c, client_plugins/client_app_base.c, client_plugins/client_app_base.h, detector_plugins/detector_base.c, detector_plugins/detector_pattern.c, detector_plugins/detector_pattern.h, service_plugins/service_api.h, service_plugins/service_base.c, service_plugins/service_base.h, service_plugins/service_pattern.c, service_plugins/service_pattern.h: Implemented new Lua API to inject pattern/port for client and server. * src/dynamic-preprocessors/: appid/fw_appid.h, appid/luaDetectorApi.c, appid/luaDetectorApi.h, appid/luaDetectorModule.c, appid/spp_appid.c, appid/service_plugins/service_MDNS.c, dcerpc2/spp_dce2.c, dnp3/spp_dnp3.c, dns/spp_dns.c, ftptelnet/spp_ftptelnet.c, gtp/spp_gtp.c, imap/spp_imap.c, isakmp/spp_isakmp.c, modbus/spp_modbus.c, pop/spp_pop.c, reputation/spp_reputation.c, sdf/spp_sdf.c, sip/spp_sip.c, smtp/spp_smtp.c, ssh/spp_ssh.c, ssl_common/ssl_config.c, ssl_common/ssl_ha.c: Implemented lua detector performance profiling. * src/generators.h, src/dynamic-preprocessors/dcerpc2/dce2_event.c, src/dynamic-preprocessors/dcerpc2/dce2_event.h, src/dynamic-preprocessors/dcerpc2/dce2_smb2.c, doc/README.dcerpc2, doc/snort_manual.tex, preproc_rules/preprocessor.rules, etc/gen-msg.map: SMBv2 and SMBv3 preprocessor alerts update. * src/encode.c: Use ip6h struct to reference the src/dst address bytes. * configure.in, src/file-process/file_segment_process.c, src/file-process/file_segment_process.h, src/file-process/file_service.c, src/file-process/file_stats.c, src/file-process/libs/file_lib.c, src/file-process/Makefile.am, src/file-process/file_api.h, src/dynamic-preprocessors/sip/sip_utils.h, src/dynamic-preprocessors/dcerpc2/Makefile.am, src/dynamic-preprocessors/dcerpc2/dce2_config.c, src/dynamic-preprocessors/dcerpc2/dce2_config.h, src/dynamic-preprocessors/dcerpc2/dce2_session.h, src/dynamic-preprocessors/dcerpc2/dce2_smb.c, src/dynamic-preprocessors/dcerpc2/dce2_smb.h, src/dynamic-preprocessors/dcerpc2/dce2_smb2.c, src/dynamic-preprocessors/dcerpc2/dce2_smb2.h, src/dynamic-preprocessors/dcerpc2/dce2_stats.h, src/dynamic-preprocessors/dcerpc2/sf_dce2.dsp, src/dynamic-preprocessors/dcerpc2/spp_dce2.c: doc/README.dcerpc2, doc/snort_manual.tex: SMBv2 and SMBv3 file inspection support. * src/: Makefile.am, appIdApi.h, detect.c, event.h, sf_sdlist.c, snort_debug.h, detection-plugins/sp_appid.c, detection-plugins/sp_appid.h, dynamic-plugins/sf_dynamic_plugins.c, dynamic-plugins/sf_dynamic_preprocessor.h, dynamic-plugins/sf_engine/sf_snort_plugin_api.c, dynamic-preprocessors/Makefile.am, dynamic-preprocessors/appid/Makefile.am, dynamic-preprocessors/appid/appId.c, dynamic-preprocessors/appid/appId.h, dynamic-preprocessors/appid/appIdApi.c, dynamic-preprocessors/appid/appIdConfig.c, dynamic-preprocessors/appid/appIdConfig.h, dynamic-preprocessors/appid/appIdStats.c, dynamic-preprocessors/appid/appInfoTable.c, dynamic-preprocessors/appid/appInfoTable.h, dynamic-preprocessors/appid/app_forecast.c, dynamic-preprocessors/appid/app_forecast.h, dynamic-preprocessors/appid/commonAppMatcher.c, dynamic-preprocessors/appid/commonAppMatcher.h, dynamic-preprocessors/appid/flow.c, dynamic-preprocessors/appid/flow.h, dynamic-preprocessors/appid/flow_error.h, dynamic-preprocessors/appid/fw_appid.c, dynamic-preprocessors/appid/fw_appid.h, dynamic-preprocessors/appid/hostPortAppCache.c, dynamic-preprocessors/appid/hostPortAppCache.h, dynamic-preprocessors/appid/host_tracker.h, dynamic-preprocessors/appid/httpCommon.h, dynamic-preprocessors/appid/lengthAppCache.c, dynamic-preprocessors/appid/lengthAppCache.h, dynamic-preprocessors/appid/luaDetectorApi.c, dynamic-preprocessors/appid/luaDetectorApi.h, dynamic-preprocessors/appid/luaDetectorFlowApi.c, dynamic-preprocessors/appid/luaDetectorFlowApi.h, dynamic-preprocessors/appid/luaDetectorModule.c, dynamic-preprocessors/appid/luaDetectorModule.h, dynamic-preprocessors/appid/rna_flow.h, dynamic-preprocessors/appid/service_state.c, dynamic-preprocessors/appid/service_state.h, dynamic-preprocessors/appid/spp_appid.c, dynamic-preprocessors/appid/thirdparty_appid_api.h, dynamic-preprocessors/appid/thirdparty_appid_types.h, dynamic-preprocessors/appid/thirdparty_appid_utils.c, dynamic-preprocessors/appid/thirdparty_appid_utils.h, dynamic-preprocessors/appid/client_plugins/clientAppConfig.h, dynamic-preprocessors/appid/client_plugins/client_app_aim.c, dynamic-preprocessors/appid/client_plugins/client_app_aim.h, dynamic-preprocessors/appid/client_plugins/client_app_api.h, dynamic-preprocessors/appid/client_plugins/client_app_base.c, dynamic-preprocessors/appid/client_plugins/client_app_base.h, dynamic-preprocessors/appid/client_plugins/client_app_bit.c, dynamic-preprocessors/appid/client_plugins/client_app_bit_tracker.c, dynamic-preprocessors/appid/client_plugins/client_app_msn.c, dynamic-preprocessors/appid/client_plugins/client_app_msn.h, dynamic-preprocessors/appid/client_plugins/client_app_rtp.c, dynamic-preprocessors/appid/client_plugins/client_app_smtp.c, dynamic-preprocessors/appid/client_plugins/client_app_smtp.h, dynamic-preprocessors/appid/client_plugins/client_app_ssh.c, dynamic-preprocessors/appid/client_plugins/client_app_timbuktu.c, dynamic-preprocessors/appid/client_plugins/client_app_tns.c, dynamic-preprocessors/appid/client_plugins/client_app_vnc.c, dynamic-preprocessors/appid/client_plugins/client_app_ym.c, dynamic-preprocessors/appid/client_plugins/client_app_ym.h, dynamic-preprocessors/appid/detector_plugins/detector_api.h, dynamic-preprocessors/appid/detector_plugins/detector_base.c, dynamic-preprocessors/appid/detector_plugins/detector_http.c, dynamic-preprocessors/appid/detector_plugins/detector_http.h, dynamic-preprocessors/appid/detector_plugins/detector_imap.c, dynamic-preprocessors/appid/detector_plugins/detector_kerberos.c, dynamic-preprocessors/appid/detector_plugins/detector_pop3.c, dynamic-preprocessors/appid/detector_plugins/detector_sip.c, dynamic-preprocessors/appid/detector_plugins/detector_sip.h, dynamic-preprocessors/appid/detector_plugins/http_url_patterns.c, dynamic-preprocessors/appid/detector_plugins/http_url_patterns.h, dynamic-preprocessors/appid/service_plugins/serviceConfig.h, dynamic-preprocessors/appid/service_plugins/service_MDNS.c, dynamic-preprocessors/appid/service_plugins/service_MDNS.h, dynamic-preprocessors/appid/service_plugins/service_api.h, dynamic-preprocessors/appid/service_plugins/service_base.c, dynamic-preprocessors/appid/service_plugins/service_base.h, dynamic-preprocessors/appid/service_plugins/service_battle_field.c, dynamic-preprocessors/appid/service_plugins/service_battle_field.h, dynamic-preprocessors/appid/service_plugins/service_bgp.c, dynamic-preprocessors/appid/service_plugins/service_bgp.h, dynamic-preprocessors/appid/service_plugins/service_bit.c, dynamic-preprocessors/appid/service_plugins/service_bootp.c, dynamic-preprocessors/appid/service_plugins/service_bootp.h, dynamic-preprocessors/appid/service_plugins/service_dcerpc.c, dynamic-preprocessors/appid/service_plugins/service_dcerpc.h, dynamic-preprocessors/appid/service_plugins/service_direct_connect.c, dynamic-preprocessors/appid/service_plugins/service_direct_connect.h, dynamic-preprocessors/appid/service_plugins/service_dns.c, dynamic-preprocessors/appid/service_plugins/service_dns.h, dynamic-preprocessors/appid/service_plugins/service_flap.c, dynamic-preprocessors/appid/service_plugins/service_flap.h, dynamic-preprocessors/appid/service_plugins/service_ftp.c, dynamic-preprocessors/appid/service_plugins/service_ftp.h, dynamic-preprocessors/appid/service_plugins/service_irc.c, dynamic-preprocessors/appid/service_plugins/service_irc.h, dynamic-preprocessors/appid/service_plugins/service_lpr.c, dynamic-preprocessors/appid/service_plugins/service_lpr.h, dynamic-preprocessors/appid/service_plugins/service_mysql.c, dynamic-preprocessors/appid/service_plugins/service_mysql.h, dynamic-preprocessors/appid/service_plugins/service_netbios.c, dynamic-preprocessors/appid/service_plugins/service_netbios.h, dynamic-preprocessors/appid/service_plugins/service_nntp.c, dynamic-preprocessors/appid/service_plugins/service_nntp.h, dynamic-preprocessors/appid/service_plugins/service_ntp.c, dynamic-preprocessors/appid/service_plugins/service_ntp.h, dynamic-preprocessors/appid/service_plugins/service_pattern.c, dynamic-preprocessors/appid/service_plugins/service_pattern.h, dynamic-preprocessors/appid/service_plugins/service_radius.c, dynamic-preprocessors/appid/service_plugins/service_radius.h, dynamic-preprocessors/appid/service_plugins/service_rexec.c, dynamic-preprocessors/appid/service_plugins/service_rexec.h, dynamic-preprocessors/appid/service_plugins/service_rfb.c, dynamic-preprocessors/appid/service_plugins/service_rfb.h, dynamic-preprocessors/appid/service_plugins/service_rlogin.c, dynamic-preprocessors/appid/service_plugins/service_rlogin.h, dynamic-preprocessors/appid/service_plugins/service_rpc.c, dynamic-preprocessors/appid/service_plugins/service_rpc.h, dynamic-preprocessors/appid/service_plugins/service_rshell.c, dynamic-preprocessors/appid/service_plugins/service_rshell.h, dynamic-preprocessors/appid/service_plugins/service_rsync.c, dynamic-preprocessors/appid/service_plugins/service_rsync.h, dynamic-preprocessors/appid/service_plugins/service_rtmp.c, dynamic-preprocessors/appid/service_plugins/service_rtmp.h, dynamic-preprocessors/appid/service_plugins/service_smtp.c, dynamic-preprocessors/appid/service_plugins/service_smtp.h, dynamic-preprocessors/appid/service_plugins/service_snmp.c, dynamic-preprocessors/appid/service_plugins/service_snmp.h, dynamic-preprocessors/appid/service_plugins/service_ssh.c, dynamic-preprocessors/appid/service_plugins/service_ssh.h, dynamic-preprocessors/appid/service_plugins/service_ssl.c, dynamic-preprocessors/appid/service_plugins/service_ssl.h, dynamic-preprocessors/appid/service_plugins/service_telnet.c, dynamic-preprocessors/appid/service_plugins/service_telnet.h, dynamic-preprocessors/appid/service_plugins/service_tftp.c, dynamic-preprocessors/appid/service_plugins/service_tftp.h, dynamic-preprocessors/appid/service_plugins/service_timbuktu.c, dynamic-preprocessors/appid/service_plugins/service_tns.c, dynamic-preprocessors/appid/util/NetworkSet.c, dynamic-preprocessors/appid/util/NetworkSet.h, dynamic-preprocessors/appid/util/common_util.h, dynamic-preprocessors/appid/util/fw_avltree.c, dynamic-preprocessors/appid/util/ip_funcs.c, dynamic-preprocessors/appid/util/ip_funcs.h, dynamic-preprocessors/appid/util/sf_mlmp.c, dynamic-preprocessors/appid/util/sfutil.c, dynamic-preprocessors/appid/util/sfutil.h, preprocessors/session_api.h, preprocessors/spp_session.c, sfutil/Unified2_common.h: Snort side changes to openAppid to support openAVC * src/dynamic-plugins/sf_dynamic_preprocessor.h, src/sfutil/sf_ip.h: Bump dpd version. * configure.in, src/parser.c, src/fpcreate.c, src/fpdetect.c, src/fpdetect, src/parser.c, src/pcrm.c, src/pcrm.h, src/signature.c, src/signature.h, src/detection-plugins/Makefile.am, src/detection-plugins/detection_leaf_node.c, src/detection-plugins/detection_options.c, src/sfutil/sfportobject.h: NEW FEATURE Port Override. Adds new metadata keywords "else-ports", "or-ports" and "and-ports". * src/sfdaq.c, src/sfdaq.h, src/dynamic-plugins/sf_dynamic_plugins.c, src/dynamic-plugins/sf_dynamic_preprocessor.h, src/dynamic-preprocessors/dcerpc2/dce2_config.c, src/preprocessors/HttpInspect/user_interface/hi_ui_server_lookup.c, src/sfutil/sfPolicy.c, src/target-based/sftarget_reader.c: Add a generic DAQ modify flow function to dpd. * configure.in, src/debug.c, src/decode.c, src/decode.h, src/detect.c, src/detection_filter.c, src/detection_filter.h, src/encode.c, src/fpcreate.c, src/fpdetect.c, src/ipv6_port.h, src/log.c, src/log_text.c, src/parser.c, src/ppm.c, src/rate_filter.c, src/sfdaq.c, src/sfdaq.h, src/sfthreshold.c, src/sfthreshold.h, src/snort.c, src/snort.h, src/snort_debug.h, src/tag.c, src/util.c, src/util.h, src/detection-plugins/sp_ftpbounce.c, src/detection-plugins/sp_session.c, src/dynamic-plugins/sf_dynamic_plugins.c, src/dynamic-plugins/sf_dynamic_preprocessor.h, src/dynamic-plugins/sf_engine/sf_snort_packet.h, src/dynamic-preprocessors/appid/flow.c, src/dynamic-preprocessors/appid/flow.h, src/dynamic-preprocessors/appid/fw_appid.c, src/dynamic-preprocessors/appid/fw_appid.h, src/dynamic-preprocessors/appid/hostPortAppCache.c, src/dynamic-preprocessors/appid/hostPortAppCache.h, src/dynamic-preprocessors/appid/luaDetectorApi.c, src/dynamic-preprocessors/appid/luaDetectorFlowApi.c, src/dynamic-preprocessors/appid/rna_flow.h, src/dynamic-preprocessors/appid/service_state.c, src/dynamic-preprocessors/appid/service_state.h, src/dynamic-preprocessors/appid/detector_plugins/detector_sip.c, src/dynamic-preprocessors/appid/service_plugins/service_api.h, src/dynamic-preprocessors/appid/service_plugins/service_base.c, src/dynamic-preprocessors/appid/service_plugins/service_ftp.c, src/dynamic-preprocessors/appid/service_plugins/service_rexec.c, src/dynamic-preprocessors/appid/service_plugins/service_rpc.c, src/dynamic-preprocessors/appid/service_plugins/service_rshell.c, src/dynamic-preprocessors/appid/service_plugins/service_snmp.c, src/dynamic-preprocessors/appid/service_plugins/service_ssl.c, src/dynamic-preprocessors/appid/service_plugins/service_tftp.c, src/dynamic-preprocessors/appid/util/ip_funcs.h, src/dynamic-preprocessors/dcerpc2/dce2_config.c, src/dynamic-preprocessors/dcerpc2/dce2_config.h, src/dynamic-preprocessors/ftptelnet/ftp_bounce_lookup.c, src/dynamic-preprocessors/ftptelnet/ftp_bounce_lookup.h, src/dynamic-preprocessors/ftptelnet/ftpp_si.c, src/dynamic-preprocessors/ftptelnet/ftpp_si.h, src/dynamic-preprocessors/ftptelnet/ftpp_ui_client_lookup.c, src/dynamic-preprocessors/ftptelnet/ftpp_ui_client_lookup.h, src/dynamic-preprocessors/ftptelnet/ftpp_ui_config.c, src/dynamic-preprocessors/ftptelnet/ftpp_ui_config.h, src/dynamic-preprocessors/ftptelnet/ftpp_ui_server_lookup.c, src/dynamic-preprocessors/ftptelnet/ftpp_ui_server_lookup.h, src/dynamic-preprocessors/ftptelnet/pp_ftp.c, src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, src/dynamic-preprocessors/imap/spp_imap.c, src/dynamic-preprocessors/reputation/reputation_config.c, src/dynamic-preprocessors/reputation/spp_reputation.c, src/dynamic-preprocessors/sip/sip_parser.c, src/dynamic-preprocessors/ssl_common/ssl_ha.c, src/dynamic-preprocessors/ssl_common/ssl_inspect.c, src/file-process/file_resume_block.c, src/output-plugins/spo_alert_sf_socket.c, src/output-plugins/spo_log_ascii.c, src/output-plugins/spo_unified2.c, src/preprocessors/perf-flow.c, src/preprocessors/perf-flow.h, src/preprocessors/portscan.c, src/preprocessors/portscan.h, src/preprocessors/session_api.h, src/preprocessors/sip_common.h, src/preprocessors/snort_httpinspect.c, src/preprocessors/snort_httpinspect.h, src/preprocessors/spp_arpspoof.c, src/preprocessors/spp_frag3.c, src/preprocessors/spp_session.c, src/preprocessors/spp_sfportscan.c, src/preprocessors/spp_stream6.c, src/preprocessors/stream_api.h, src/preprocessors/HttpInspect/client/hi_client.c, src/preprocessors/HttpInspect/files/file_decomp.c, src/preprocessors/HttpInspect/include/file_decomp.h, src/preprocessors/HttpInspect/include/hi_si.h, src/preprocessors/HttpInspect/include/hi_ui_config.h, src/preprocessors/HttpInspect/include/hi_ui_server_lookup.h, src/preprocessors/HttpInspect/session_inspection/hi_si.c, src/preprocessors/HttpInspect/user_interface/hi_ui_config.c, src/preprocessors/HttpInspect/user_interface/hi_ui_server_lookup.c, src/preprocessors/Session/session_common.h, src/preprocessors/Session/session_expect.c, src/preprocessors/Session/session_expect.h, src/preprocessors/Session/stream5_ha.c, src/preprocessors/Session/stream5_ha.h, src/preprocessors/Stream6/snort_stream_icmp.c, src/preprocessors/Stream6/snort_stream_icmp.h, src/preprocessors/Stream6/snort_stream_tcp.c, src/preprocessors/Stream6/snort_stream_tcp.h, src/preprocessors/Stream6/snort_stream_udp.c, src/preprocessors/Stream6/snort_stream_udp.h, src/preprocessors/Stream6/stream_paf.c, src/sfutil/ipobj.c, src/sfutil/ipobj.h, src/sfutil/sfPolicy.c, src/sfutil/sfPolicy.h, src/sfutil/sf_ip.c, src/sfutil/sf_ip.h, src/sfutil/sf_iph.c, src/sfutil/sf_iph.h, src/sfutil/sf_ipvar.c, src/sfutil/sf_ipvar.h, src/sfutil/sf_vartable.c, src/sfutil/sfrf.c, src/sfutil/sfrf.h, src/sfutil/sfrt.c, src/sfutil/sfrt.h, src/sfutil/sfrt_dir.c, src/sfutil/sfrt_dir.h, src/sfutil/sfrt_flat.c, src/sfutil/sfrt_flat.h, src/sfutil/sfrt_flat_dir.c, src/sfutil/sfrt_flat_dir.h, src/sfutil/sfthd.c, src/sfutil/sfthd.h, src/sfutil/util_net.c, src/sfutil/util_net.h, src/sfutil/test/sf_ip_test.c, src/sfutil/test/sfrf_test.c, src/sfutil/test/sfrt_test.c, src/sfutil/test/sfthd_test.c, src/side-channel/sidechannel.c, src/target-based/sftarget_reader.c, src/target-based/sftarget_reader.h: Refactor sfip_t/sfaddr_t code to be compatible with struct in6_addr. 2015-08-13 Rahul Burman Snort 2.9.7.6 * src/build.h: updating build number to 285 * src/dynamic-preprocessors/reputation/reputation_config.c: Fixed unexpected behaviour in reputation config where blacklist is displayed in priority field even though whitelist option is set [reported by Mike Cox]. * src/preprocessors/Stream6/snort_stream_tcp.c: Fixed issue where XFF/ExtraData is not always logged when 'drop' rules trigger [reported by Mike Cox]. Fixed issue in TCP session deletion when being called from Stream5 HA. * src/: active.h, file-process/file_service.c: ACTIVE_DROP is changed to ACTIVE_FORCE_DROP when file_verdict is pending. * src/dynamic-preprocessors/appid/fw_appid.c: Fixed issue where openappid does not provide the Content-Type field for use with CHPAddAction. * doc/snort_manual.tex: Corrected errors in snort_manual.tex [reported by Gabriel Corre]. * preproc_rules/preprocessor.rules src/preprocessors/: session_api.h, snort_httpinspect.c, HttpInspect/event_output/hi_eo_log.c, HttpInspect/include/hi_eo_events.h Stream6/snort_stream_tcp.c: Enhancement done to detect 'SSH tunneling over HTTP'. * src/sfutil/sfportobject.c: Fixed Memory leaks [reported by Bill Parker]. * doc/snort_manual.tex: Corrected the information about unified2 record structure [reported by Avery Rozar]. * etc/snort.conf, src/preprocessors/snort_httpinspect.c, src/preprocessors/snort_httpinspect.h, src/preprocessors/HttpInspect/client/hi_client.c, src/preprocessors/HttpInspect/server/hi_server.c, src/preprocessors/Stream6/stream_paf.c: Fixed issue where original client IP in intrusion event is incorrectly populated with XFF of the last GET request. * src/preprocessors/: snort_httpinspect.c, snort_httpinspect.h, HttpInspect/server/hi_server.c, snort_httpinspect.c, snort_httpinspect.h, HttpInspect/server/hi_server.c: Http unlimited decompression will now decompress the entire stream. * src/decode.c: Added a check so that min_ttl decoder do not drop packet in alert mode. * etc/snort.conf, src/preprocessors/snort_httpinspect.c, src/preprocessors/snort_httpinspect.h, src/preprocessors/HttpInspect/client/hi_client.c, src/preprocessors/HttpInspect/server/hi_server.c Fixed issue where original client IP in intrusion event is incorrectly populated with XFF of the last GET request. 2015-07-01 Carter Waxman Snort 2.9.7.5 * src/build.h: updating build number to 262 * src/preprocessors/Stream6/snort_stream_tcp.c: Improved handling of asymmetric traffic * src/active.c: Active responses no longer set the FIN flag on the last segment transmitted * src/dynamic-preprocessors/appid/luaDetectorApi.c: Added sanity checks to client api * doc/snort_manual.pdf, src/: dynamic-preprocessors/dcerpc2/dce2_paf.c, dynamic-preprocessors/dnp3/dnp3_paf.c, dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, dynamic-preprocessors/imap/imap_paf.c, dynamic-preprocessors/pop/pop_paf.c, dynamic-preprocessors/sip/sip_paf.c, dynamic-preprocessors/smtp/smtp_paf.c, preprocessors/session_api.h, preprocessors/spp_stream6.c, preprocessors/stream_api.h, preprocessors/HttpInspect/utils/hi_paf.c, preprocessors/Session/session_common.h, preprocessors/Stream6/snort_stream_tcp.c, preprocessors/Stream6/snort_stream_tcp.h, preprocessors/Stream6/stream_paf.c, preprocessors/Stream6/stream_paf.h: Multiple PAF clients can Read/Write to the same user data * src/: file-process/file_api.h, file-process/file_mail_common.h, file-process/file_mime_process.c, sfutil/sf_email_attach_decode.c, sfutil/sf_email_attach_decode.h: Fixed filename parsing from Mime body for UUencoded MIME * src/preprocessors/perf-base.c, src/preprocessors/Stream6/snort_stream_tcp.c: Prunes triggered by timeouts are now accounted by perfmonitor. * src/preprocessors/spp_session.c: Log warning instead of Fatal Error if a stream5_global config is in a non-default policy * src/detection-plugins/sp_base64_decode.c: Removed unused checks * src/snort.c: Improved reliability of configuration reloads * src/preprocessors/snort_httpinspect.c: Fixed issue in http file processing where SHAs may not always be correct. * doc/snort_manual.pdf, src/sfutil/sf_email_attach_decode.c: Fixed handling new line chars in QP encoding * src/preprocessors/snort_httpinspect.c: Fixed inconsistent behavior when configuring "max_gzip_mem -1" 2015-22-04 Joel Cornett Snort 2.9.7.3 * src/build.h: updating build number to 217 * src/: decode.h, detection-plugins/sp_clientserver.c, dynamic-plugins/sf_engine/sf_snort_packet.h, dynamic-plugins/sf_engine/sf_snort_plugin_api.c, dynamic-preprocessors/dcerpc2/dce2_session.h, dynamic-preprocessors/sdf/spp_sdf.c, preprocessors/HttpInspect/server/hi_server.c, preprocessors/Stream6/snort_stream_tcp.c, preprocessors/snort_httpinspect.c, preprocessors/spp_normalize.c: Added mode safety checks to normalization. Fixed an issue in PAF where the start of the PDU after flushing was not being set correctly in some case. Improved Stream reassembly of HTTPS sessions * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: Stability improvements for ftp_telnet preprocessor * doc/snort_manual.pdf, doc/snort_manual.tex, src/detection-plugins/sp_base64_decode.c, src/detection-plugins/sp_base64_decode.h, src/detection-plugins/sp_file_data.c: Improved performance for file preprocessor Documentation changes * src/dynamic-preprocessors/appid/: service_plugins/service_base.c, service_state.c: Various OpenAppId improvements * configure.in: Fixed issue with configure script handling of -Werror compiler flags * src/decode.c: Improved decoding of IPv6 extensions * src/detection-plugins/detection_options.c: Fixed an issue where the protected_content rule option was not backtracking correctly in some cases * src/snort.c: Fixed snort handling of PID files * tools/: u2openappid/u2openappid.c, u2spewfoo/u2spewfoo.c: Fixed usage info. * src/dynamic-preprocessors/sip/: Makefile.am, sf_sip.dsp, sip_dialog.c, sip_parser.c, spp_sip.c: Added PAF support for TCP traffic * src/: log_text.c, log_text.h, output-plugins/spo_alert_fast.c, output-plugins/spo_alert_full.c: Extended support for OpenAppId logging to cmg and console output loggers * src/dynamic-preprocessors/appid/service_plugins/service_ssl.c: Improved SSLv3 handling for OpenAppId 2014-24-12 Victor Roemer Snort 2.9.7.2 * src/build.h: updating build number to 177 * src/preprocessors/Stream6/snort_stream_tcp.c: Resolved an issue where the inline normalization preprocessor incorrectly resized packets when 'preprocessor normalize_tcp: trim' was enabled. * src/decode.c, src/encode.c: Added support for Cisco FabricPath decoding/encoding. Ensure flow_id is copied into the DAQ_PktHdr_t. * src/snort.h, src/sfutil/sfrt.c, src/sfutil/sfrt.h src/target-based/sftarget_reader.c: Moved ntohl conversion inside of the sfrt api for both IPv4 and IPv6. * src/target-based/sftarget_protocol_reference.c Lookup application protocol id only after the session is established. Assign application protocol id to the session when using host attribute table. * src/util.c: Changes for suppressing configuration logging. * src/file-process/file_service.c: Assign the file config to a file context prior to checking if HTTP continuation. 2014-10-10 Carter Waxman Snort 2.9.7.0 * src/build.h: updating build number to 149 * src/dynamic-preprocessors/appid/spp_appid.c: Fixed issue in which AppID would be disabled after a reload. * configure.in: Added dependency for OpenSSL when building with --enable-openappid * doc/: README.http_inspect, snort_manual.pdf, snort_manual.tex: Added documentation for the new Extended X-Forwarded-For capabilities * src/preprocessors/Stream6/snort_stream_tcp.c: Reused the TcpSessionCleanup logic to add a function to flush queued unacked segments. 2014-09-15 Joel Cornett Snort 2.9.7.0-rc * src/build.h: updating build number to 147 * configure.in, src/sfdaq.c: Fixed C99 compliance issue with DAQ. * src/preprocessors/: Stream6/snort_stream_tcp.c, spp_session.c: Improved stability of TCP session decoding. * tools/u2streamer/u2streamer.c: Improved stability of u2streamer tool. * src/snort.c: Fixed issue with daemonization mode. Thanks to Eugenio Perez for noting the issue and proposing a fix. * src/: dynamic-plugins/sf_dynamic_plugins.c, dynamic-plugins/sf_dynamic_preprocessor.h, preprocessor/Stream6/snort_stream_tcp.c, encode.c, encode.h, snort.c, snort.h: Added support to detect heartbleed attacks. * build/dobuild.sh, rpm/README.build_rpms, rpm/generate-all-rpms, rpm/snort.spec, src/dynamic-preprocessors/appid/Makefile.am: Added OpenAppID to snort RPM. * doc/: README.active, README.file_ips, INSTALL, snort_manual.tex: Updated documentation. * doc/INSTALL: Added common configuration mistakes and fixes to INSTALL. Thanks to Bill Parker for the documentation. * src/dynamic-preprocessors/ftptelnet/pp_ftp.c: Improved FTP traffic handling. * src/dynamic-preprocessors/appid/detector_plugins: detector_http.c, detector_imap.c, detector_pop3.c: Improved stability of OpenAppID preprocessor parsing HTTP headers. * src/: parser.c, snort.c, snort.h, util.c: Added a new option `--suppress-config-log` to Snort command line arguments. This option suppresses logging of configuration information to output. * src/: active.c, active.h, preprocessors/Stream6/snort_stream_ip.c, preprocessors/Stream6/snort_stream_tcp.c, preprocessors/Stream6/snort_stream_udp.c: Fixed issue with blacklisting of flow traffic. * src/preprocessors: spp_session.c, spp_stream6.c: Improved stability of Stream6 preprocessor. * configure.in, src/dynamic-preprocessors/ftptelnet/ftpp_si.c, src/dynamic-preprocessors/ftptelnet/ftpp_si.h, src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, src/dynamic-preprocessors/imap/snort_imap.c, src/dynamic-preprocessors/imap/snort_imap.h, src/dynamic-preprocessors/pop/snort_pop.c, src/dynamic-preprocessors/pop/snort_pop.h, src/dynamic-preprocessors/smtp/snort_smtp.c, src/dynamic-preprocessors/smtp/snort_smtp.h, src/dynamic-preprocessors/ssl_common/ssl_include.h, src/dynamic-preprocessors/ssl_common/ssl_inspect.c, src/dynamic-preprocessors/ssl_common/ssl_session.h, src/encode.c: Fixed encoding issue with DAQ packet headers. * doc/README.ssl, doc/snort_manual.pdf, doc/snort_manual.tex, etc/gen-msg.map, preproc_rules/preprocessor.rules, src/dynamic-preprocessors/ssl_common/ssl.c, src/dynamic-preprocessors/ssl_common/ssl.h, src/dynamic-preprocessors/ssl_common/ssl_config.c, src/dynamic-preprocessors/ssl_common/ssl_config.h, src/dynamic-preprocessors/ssl_common/ssl_inspect.c, src/dynamic-preprocessors/ssl_common/ssl_inspect.h, src/dynamic-preprocessors/ssl_common/ssl_session.h: Added support to detect heartbleed attacks. * doc/snort_manual.tex, src/dynamic-examples/dynamic-rule/detection_lib_meta.h, src/dynamic-plugins/sf_dynamic_engine.h, src/dynamic-plugins/sf_dynamic_meta.h, src/dynamic-plugins/sf_dynamic_preprocessor.h, src/dynamic-plugins/sf_engine/examples/detection_lib_meta.h, src/dynamic-plugins/sf_engine/sf_snort_packet.h, src/preprocessors/Stream6/snort_stream_tcp.c, src/decode.c, src/decode.h, src/encode.c, src/parser.c, src/parser.h, src/snort.c, src/snort.h: Added a new config option `max_ip6_extensions` to change the maximum number of IPv6 extension headers decoded. Thanks to Antonio Atlasis for providing data to the ChangeLog. * src/dynamic-preprocessors/modbus/: modbus_paf.h, modbus_roptions.c, spp_modbus.c: Improved traffic handling by modbus preprocessor * src/: dynamic-preprocessors/dns/spp_dns.c, dynamic-preprocessors/imap/spp_imap.c, dynamic-preprocessors/pop/spp_pop.c, dynamic-preprocessors/smtp/spp_smtp.c, dynamic-preprocessors/ssh/spp_ssh.c, preprocessors/spp_session.c: Fixed issue with stream configuration state changing across reloads. Thanks to Eugenio Perez for noting the issue. * src/dynamic-preprocessors/appid/Makefile.am: Fixed compilation issue with OpenAppID on OpenBSD. * src/plugbase.c: Improved implementation of plugin API. * src: detection-plugins/sp_ftpbounce.c, dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: Improved stability of FTP preprocessor. * configure.in, src/dynamic-preprocessors/appid/appIdConfig.c, src/dynamic-preprocessors/appid/appIdConfig.h, src/dynamic-preprocessors/appid/flow.h, src/dynamic-preprocessors/appid/fw_appid.c, src/dynamic-preprocessors/appid/fw_appid.h, src/dynamic-preprocessors/appid/luaDetectorApi.h: Fixed compilation issues with OpenAppID on Mac OS X. * src/preprocessors/: perf-flow.c, spp_perfmonitor.c: Minimum flow-ip-memcap changed to 8200. * src/sf_sdlist.c: Fixed implementation of `sf_sdlist`. Thanks to Yang Zhang for noting the issue. * src/: preprocessors/Stream6/snort_stream_tcp.c, preprocessors/spp_frag3.c, preprocessors/spp_normalize.c: active.h, decode.c, Check checksum configuration as well as na_policy_mode setting before drop. * src/preprocessors/snort_httpinspect.c: Improved handling in HTTPInspect preprocessor. * src/sfutil/mpse.c: Fixed building snort with --disable-perfprofiling. Thanks to Yonatan Ben-David for noting the issue. * src: encode.c, encode.h: Fixed ICMPv6 encoding issue. * etc/snort.conf, src/detection-plugins/sp_file_type.c, src/dynamic-preprocessors/Makefile.am, src/dynamic-preprocessors/ftptelnet/Makefile.am, src/dynamic-preprocessors/imap/Makefile.am, src/dynamic-preprocessors/pop/Makefile.am, src/dynamic-preprocessors/sf_dynamic_initialize/sf_dynamic_initialize.dsp, src/dynamic-preprocessors/smtp/Makefile.am, src/dynamic-preprocessors/ssl/Makefile.am, src/preprocessors/Session/Makefile.am, src/win32/WIN32-Prj/sf_engine.dsp, src/win32/WIN32-Prj/snort.dsp, src/win32/WIN32-Prj/snort.dsw, src/win32/WIN32-Prj/snort_installer.nsi: Fixed Win32 and distcheck build issues. * doc/OpenDetectorDeveloperGuide.docx, doc/OpenDetectorDeveloperGuide.pdf, src/dynamic-preprocessors/appid/Makefile.am, src/dynamic-preprocessors/appid/appInfoTable.c, src/dynamic-preprocessors/appid/detector_plugins/detector_http.c, src/dynamic-preprocessors/appid/detector_plugins/detector_http.h, src/dynamic-preprocessors/appid/fw_appid.c, src/dynamic-preprocessors/appid/httpCommon.h, src/dynamic-preprocessors/appid/luaDetectorApi.c, src/dynamic-preprocessors/appid/service_plugins/service_base.c, src/dynamic-preprocessors/appid/service_plugins/service_rtmp.c, src/dynamic-preprocessors/appid/service_plugins/service_rtmp.h: Added RTMP detector (w/ metadata) to OpenAppID and updated Lua API. 2014-06-04 Carter Waxman Snort 2.9.7.0.beta * src/build.h: updating build number to 109 * src/: detection-plugins/sp_base64_decode.c, dynamic-plugins/sf_engine/sf_snort_plugin_api.c: Use correct buffer size for base64 decoding. Fix the bound check for base64_decode rule. Thanks Joshua providing the patch. * src/: detect.c, dynamic-preprocessors/reputation/spp_reputation.c, dynamic-preprocessors/reputation/shmem/shmem_config.h, dynamic-preprocessors/reputation/shmem/shmem_mgmt.c, preprocessors/session_api.h, preprocessors/spp_session.c: Improved reputation performance by only checking IPs once per session. Changed control socket to respond 0 when reloading empty IP reputation lists. Avoid registering reputation preprocessor when there are no IP lists * src/: active.c, fpdetect.c, dynamic-preprocessors/dcerpc2/dce2_smb.c, file-process/file_resume_block.c: Fixed build issue when configuring with --disable-active-response --disable-react --disable-flexresp3 (Reported by Jeremy Hoel) * src/parser.c src/preprocessors/Session/stream5_ha.c, src/preprocessors/Stream6/snort_stream_icmp.c, src/preprocessors/Stream6/snort_stream_tcp.c, src/preprocessors/Stream6/snort_stream_udp.c, src/preprocessors/spp_session.c: Fixed configuration parsing issues. * src/: fpcreate.c, fpdetect.c: Fixed rule protocol mapping when using target-based detection. * src/preprocessors/perf-base.c: Added field in now files for number of normalizers used. * src/preprocessors/Stream6/snort_stream_tcp.c: Fix handling of data on syn for Mac OSX reassembly. * src/dynamic-plugins/sf_dynamic_plugins.c: Remove optional field check to improve compatiblity for DragonFlyBSD. Thanks Joshua Kinard providing patch. * src/detect.c: Fixed AppID not correctly handling packets without sessions (Discovered by James Lay) * src/preprocessors/snort_httpinspect.c: Fixed issue with HTTP session data handling. (Discovered by James Lay) * src/snort.c: Fixed parsing of custom rule types on reload. * src/util.c: Fixed timestamp arithmetic error (Reported by David Turnbull) * src/: sf_protocols.h, preprocessors/perf-base.c, preprocessors/perf-base.h, preprocessors/session_api.h, preprocessors/spp_session.c, preprocessors/spp_stream6.c, preprocessors/stream_api.h, preprocessors/Stream6/stream_common.c, preprocessors/Stream6/stream_common.h: Fixed IP protocol number type (Reported by Joshua Kinard) * src/: strlcatu.h, strlcpyu.h: Wrap function signatures for strlcat/strlcpy. Thanks to James Golab for reporting the issue. * doc/: snort_manual.pdf, snort_manual.tex: Typos fixed (Credit to Jenah J. Sigurdson) * src/: encode.h, parser.c, dynamic-preprocessors/imap/imap_paf.c, dynamic-preprocessors/pop/pop_paf.c, dynamic-preprocessors/smtp/smtp_paf.c, file-process/file_mail_common.h, preprocessors/stream_api.h, preprocessors/Stream6/stream_paf.c: Fixed PAF flushing behavior when encountering gaps. paf_max now has a hard flush limit of ~64,000. Email protocols will flush within 1500 characters of paf_max. * src/: dynamic-preprocessors/dns/spp_dns.c, dynamic-preprocessors/imap/snort_imap.c, dynamic-preprocessors/pop/snort_pop.c, preprocessors/session_api.h, preprocessors/spp_rpc_decode.c, preprocessors/spp_session.c, preprocessors/Stream6/snort_stream_tcp.c: Changed flushing to use receiver's flush policy in all functions. Updated POP, IMAP, DNS, RPC, and SSL to use the correct directions. Added SSN_TO_SERVER(SSN_FROM_CLIENT) and SSN_TO_CLIENT(SSN_FROM_SERVER) to make code more readable (Discovered by John Enure). * src/detection_util.c: Fixed Http buffer name initialization. * src/preprocessors/HttpInspect/normalization/hi_norm.c: Fixed URI parsing and normalization. * doc/README.file_ips, src/plugbase.c, src/rule_option_types.h, src/detection-plugins/Makefile.am, src/detection-plugins/detection_options.c, src/detection-plugins/sp_file_type.c, src/file-process/file_api.h, src/file-process/file_service.c, src/file-process/libs/file_config.c, src/file-process/libs/file_config.h, src/file-process/libs/file_identifier.c, src/file-process/libs/file_lib.c, src/file-process/libs/file_lib.h: Allow registration of the same file type callback. Harden file_type and file_group rule options. Fix file id to always use the matched file id. File identifier rule options 'type' and 'ver' no longer accept arbitrary ASCII characters as valid arguments, only permitting [A-Za-z0-9_.] characters. Snort's 'file_type' rule option now checks for trailing comma (,) and pipe (|) separators and other typo like mistakes. * configure.in, src/active.c, src/active.h, src/decode.c, src/detection-plugins/detection_options.c, src/detection-plugins/sp_replace.c, src/dynamic-plugins/sf_dynamic_plugins.c, src/parser.c, src/parser.h, src/preprocessors/Stream6/snort_stream_tcp.c, src/preprocessors/normalize.c, src/preprocessors/normalize.h, src/preprocessors/perf-base.c, src/preprocessors/perf-base.h, src/preprocessors/spp_normalize.c, src/preprocessors/spp_normalize.h, src/preprocessors/spp_session.c, src/snort.c, src/snort.h: Added would-normalize normalization statistics for inline_test mode. Normalization behavior now enabled / configured using na_policy_mode. Fix typos in spp_normalize.c (Thanks to Gregory S Thomas for mentioning). * doc/README.normalize, doc/snort_manual.pdf, doc/snort_manual.tex, src/preprocessors/normalize.c, src/preprocessors/perf-base.c, src/preprocessors/perf-base.h, src/preprocessors/spp_normalize.c, src/preprocessors/spp_normalize.h, src/preprocessors/Stream6/snort_stream_tcp.c: TCP normalization configurations have been split into more granular options. URP normalization is now ENABLED with the "urp" keyword instead of DISABLED. New performance monitor stats have been introduced for these changes. * src/decode.h, src/detect.c, src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, src/preprocessors/Session/session_expect.c, src/preprocessors/Stream6/snort_stream_tcp.c, src/preprocessors/spp_stream6.c, src/preprocessors/stream_api.h: Changed priority of ftp-telnet reassembly to improve performance. Process end of file data correctly for ftp data channel. * etc/file_magic.conf, src/sfutil/sf_email_attach_decode.c: File type UUENCODED is now all caps. Set file data pointer correctly after UU decoding ends. * src/: dynamic-preprocessors/imap/imap_config.c, dynamic-preprocessors/pop/pop_config.c, dynamic-preprocessors/smtp/smtp_config.c, file-process/file_mime_config.c, file-process/file_mime_config.h: +0 and -0 are no longer valid values for decoding depth. * src/dynamic-preprocessors/dnp3/spp_dnp3.c: Validate DNP3 packets before processing. * src/: snort.c, snort.h, sfutil/intel-soft-cpm.c, sfutil/intel-soft-cpm.h: Fixed issues during reload. * configure.in, doc/README.http_inspect, doc/snort_manual.pdf, doc/snort_manual.tex, etc/gen-msg.map, preproc_rules/preprocessor.rules, src/generators.h, src/preprocessors/HttpInspect/Makefile.am, src/preprocessors/HttpInspect/event_output/hi_eo_log.c, src/preprocessors/HttpInspect/files/Makefile.am, src/preprocessors/HttpInspect/files/file_decomp.c, src/preprocessors/HttpInspect/files/file_decomp_PDF.c, src/preprocessors/HttpInspect/files/file_decomp_SWF.c, src/preprocessors/HttpInspect/files/include/file_decomp.h, src/preprocessors/HttpInspect/files/include/file_decomp_PDF.h src/preprocessors/HttpInspect/include/Makefile.am, src/preprocessors/HttpInspect/include/file_decomp.h, src/preprocessors/HttpInspect/include/file_decomp_PDF.h, src/preprocessors/HttpInspect/include/file_decomp_SWF.h, src/preprocessors/HttpInspect/include/hi_eo_events.h, src/preprocessors/HttpInspect/include/hi_include.h, src/preprocessors/HttpInspect/include/hi_ui_config.h, src/preprocessors/HttpInspect/server/hi_server.cr, src/preprocessors/snort_httpinspect.c, src/preprocessors/snort_httpinspect.h, src/preprocessors/spp_httpinspect.c, src/util.c: Added ability for HttpInspect to decompress DEFLATE and LZMA encoded SWF content and DEFLATE encoded pdf content. * src/preprocessors/spp_perfmonitor.c: Fixed race condition in perf montitor during reload. * src/preprocessors/HttpInspect/client/hi_client.c, src/preprocessors/HttpInspect/include/hi_client.h, src/preprocessors/HttpInspect/include/hi_ui_config.h, src/preprocessors/HttpInspect/user_interface/hi_ui_config.c, src/preprocessors/snort_httpinspect.c: Added Enhanced XFF support to HttpInspect. * src/profiler.c: Fixed duplicate profiler entries when using multiple policies. * configure.in, src/Makefile.am, src/dump.c, src/dump.h, src/snort.c, src/control/sfcontrol.h, tools/control/Makefile.am, tools/control/README.snort_dump_packets_control, tools/control/sfcontrol.c, tools/control/snort_dump_packets.c: Added control socket command to dump packets. * src/: preprocessors/snort_httpinspect.c, preprocessors/snort_httpinspect.h, preprocessors/HttpInspect/client/hi_client.c, preprocessors/HttpInspect/include/hi_ui_config.h, preprocessors/HttpInspect/include/hi_ui_iis_unicode_map.h, preprocessors/HttpInspect/session_inspection/hi_si.c, preprocessors/HttpInspect/user_interface/hi_ui_config.c, preprocessors/HttpInspect/user_interface/hi_ui_iis_unicode_map.c, sfutil/util_jsnorm.c, sfutil/util_jsnorm.h: Removed dead max_pipeline and inspection_type configurations. Improved memory efficiency of unicode->ascii map. Expanded possible number of preprocessor alerts for HttpInspect from 31 to 63. * src/dynamic-preprocessors/sdf/sdf_pattern_match.c: Fixed FindPiiRecursively to better handle partial matches. * src/dynamic-preprocessors/sip/sip_parser.c: Fixed handling SDP when caller and callee have identical session ids. * src/: dynamic-preprocessors/Makefile.am, dynamic-preprocessors/sip/sip_config.h, dynamic-preprocessors/sip/sip_dialog.c, dynamic-preprocessors/sip/spp_sip.h, preprocessors/Makefile.am, preprocessors/sip_common.h, preprocessors/spp_stream6.c, preprocessors/stream_api.h: Support better SIP parsing and call handling. * Makefile.am, configure.in, doc/Makefile.am, doc/README, doc/README.frag3, doc/USAGE, doc/WISHLIST, doc/snort_manual.tex, dynamic-plugins/sf_dynamic_plugins.c, dynamic-plugins/sf_dynamic_preprocessor.h, dynamic-preprocessors/ftptelnet/ftpp_si.c, dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, dynamic-preprocessors/imap/snort_imap.c, dynamic-preprocessors/pop/snort_pop.c, dynamic-preprocessors/smtp/snort_smtp.c, dynamic-preprocessors/ssl_common/ssl_config.c, dynamic-preprocessors/ssl_common/ssl_include.h, dynamic-preprocessors/ssl_common/ssl_inspect.c, etc/Makefile.am, etc/gen-msg.map, libs/ssl_include.h, rpm/snort.spec, snort.8, src/Makefile.am, src/active.c, src/active.h, src/byte_extract.c, src/checksum.h, src/debug.c, src/decode.c, src/decode.h, src/detect.c, src/detect.h, src/detection-plugins/detection_options.c, src/detection-plugins/detection_options.h, src/detection-plugins/sp_asn1.c, src/detection-plugins/sp_asn1_detect.c, src/detection-plugins/sp_byte_check.c, src/detection-plugins/sp_byte_check.h, src/detection-plugins/sp_byte_jump.c, src/detection-plugins/sp_byte_jump.h, src/detection-plugins/sp_clientserver.c, src/detection-plugins/sp_clientserver.h, src/detection-plugins/sp_dsize_check.c, src/detection-plugins/sp_dsize_check.h, src/detection-plugins/sp_flowbits.c, src/detection-plugins/sp_flowbits.h, src/detection-plugins/sp_ftpbounce.c, src/detection-plugins/sp_ftpbounce.h, src/detection-plugins/sp_icmp_code_check.c, src/detection-plugins/sp_icmp_code_check.h, src/detection-plugins/sp_icmp_id_check.c, src/detection-plugins/sp_icmp_id_check.h, src/detection-plugins/sp_icmp_seq_check.c, src/detection-plugins/sp_icmp_seq_check.h, src/detection-plugins/sp_icmp_type_check.c, src/detection-plugins/sp_icmp_type_check.h, src/detection-plugins/sp_ip_fragbits.c, src/detection-plugins/sp_ip_fragbits.h, src/detection-plugins/sp_ip_id_check.c, src/detection-plugins/sp_ip_id_check.h, src/detection-plugins/sp_ip_proto.c, src/detection-plugins/sp_ip_proto.h, src/detection-plugins/sp_ip_same_check.c, src/detection-plugins/sp_ip_same_check.h, src/detection-plugins/sp_ip_tos_check.c, src/detection-plugins/sp_ip_tos_check.h, src/detection-plugins/sp_ipoption_check.c, src/detection-plugins/sp_ipoption_check.h, src/detection-plugins/sp_isdataat.c, src/detection-plugins/sp_isdataat.h, src/detection-plugins/sp_pattern_match.c, src/detection-plugins/sp_pattern_match.h, src/detection-plugins/sp_pcre.c, src/detection-plugins/sp_react.c, src/detection-plugins/sp_react.h, src/detection-plugins/sp_replace.c, src/detection-plugins/sp_replace.h, src/detection-plugins/sp_respond.h, src/detection-plugins/sp_respond3.c, src/detection-plugins/sp_rpc_check.c, src/detection-plugins/sp_rpc_check.h, src/detection-plugins/sp_session.c, src/detection-plugins/sp_session.h, src/detection-plugins/sp_tcp_ack_check.c, src/detection-plugins/sp_tcp_ack_check.h, src/detection-plugins/sp_tcp_flag_check.c, src/detection-plugins/sp_tcp_flag_check.h, src/detection-plugins/sp_tcp_seq_check.c, src/detection-plugins/sp_tcp_seq_check.h, src/detection-plugins/sp_tcp_win_check.c, src/detection-plugins/sp_tcp_win_check.h, src/detection-plugins/sp_ttl_check.c, src/detection-plugins/sp_ttl_check.h, src/detection_filter.c, src/detection_filter.h, src/detection_util.c, src/detection_util.h, src/dynamic-examples/Makefile.am, src/dynamic-plugins/sf_convert_dynamic.c, src/dynamic-plugins/sf_convert_dynamic.h, src/dynamic-plugins/sf_dynamic_plugins.c, src/dynamic-plugins/sf_dynamic_preprocessor.h, src/dynamic-plugins/sf_preproc_example/sf_dynamic_preproc_lib.c, src/dynamic-plugins/sf_preproc_example/sf_dynamic_preproc_lib.h, src/dynamic-plugins/sf_preproc_example/spp_nfs_setup.c, src/dynamic-plugins/sf_preproc_example/spp_nfs_setup.h, src/dynamic-plugins/sf_src/dynamic_plugins.c, src/dynamic-plugins/sf_src/dynamic_preprocessor.h, src/dynamic-plugins/sp_dynamic.c, src/dynamic-plugins/sp_dynamic.h, src/dynamic-plugins/sp_preprocopt.c, src/dynamic-plugins/sp_preprocopt.h, src/dynamic-preprocessors/Makefile.am, src/dynamic-preprocessors/ftptelnet/Makefile.am, src/dynamic-preprocessors/ftptelnet/ftpp_si.c, src/dynamic-preprocessors/ftptelnet/ftpp_si.h, src/dynamic-preprocessors/ftptelnet/pp_ftp.c, src/dynamic-preprocessors/ftptelnet/pp_telnet.c, src/dynamic-preprocessors/ftptelnet/sf_ftptelnet.dsp, src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, src/dynamic-preprocessors/imap/Makefile.am, src/dynamic-preprocessors/imap/imap_config.c, src/dynamic-preprocessors/imap/imap_config.h, src/dynamic-preprocessors/imap/imap_log.c, src/dynamic-preprocessors/imap/imap_log.h, src/dynamic-preprocessors/imap/imap_util.c, src/dynamic-preprocessors/imap/imap_util.h, src/dynamic-preprocessors/imap/sf_imap.dsp, src/dynamic-preprocessors/imap/snort_imap.c, src/dynamic-preprocessors/imap/snort_imap.h, src/dynamic-preprocessors/imap/spp_imap.c, src/dynamic-preprocessors/imap/spp_imap.h, src/dynamic-preprocessors/libs/Makefile.am, src/dynamic-preprocessors/libs/sfdynamic_preproc_libs.dsp, src/dynamic-preprocessors/libs/ssl.c, src/dynamic-preprocessors/libs/ssl.h, src/dynamic-preprocessors/libs/ssl_include.h, src/dynamic-preprocessors/pop/Makefile.am, src/dynamic-preprocessors/pop/pop_config.c, src/dynamic-preprocessors/pop/pop_config.h, src/dynamic-preprocessors/pop/pop_log.c, src/dynamic-preprocessors/pop/pop_log.h, src/dynamic-preprocessors/pop/pop_util.c, src/dynamic-preprocessors/pop/pop_util.h, src/dynamic-preprocessors/pop/sf_pop.dsp, src/dynamic-preprocessors/pop/snort_pop.c, src/dynamic-preprocessors/pop/snort_pop.h, src/dynamic-preprocessors/pop/spp_pop.c, src/dynamic-preprocessors/pop/spp_pop.h, src/dynamic-preprocessors/reputation/shmem/sflinux_helpers.c, src/dynamic-preprocessors/reputation/shmem/sflinux_helpers.h, src/dynamic-preprocessors/reputation/shmem/shmem_common.h, src/dynamic-preprocessors/reputation/shmem/shmem_config.c, src/dynamic-preprocessors/reputation/shmem/shmem_config.h, src/dynamic-preprocessors/reputation/shmem/shmem_datamgmt.c, src/dynamic-preprocessors/reputation/shmem/shmem_datamgmt.h, src/dynamic-preprocessors/reputation/shmem/shmem_lib.c, src/dynamic-preprocessors/reputation/shmem/shmem_lib.h, src/dynamic-preprocessors/reputation/shmem/shmem_mgmt.c, src/dynamic-preprocessors/reputation/shmem/shmem_mgmt.h, src/dynamic-preprocessors/sf_dynamic_initialize/sf_dynamic_initialize.dsp, src/dynamic-preprocessors/sip/sf_sip.dsp, src/dynamic-preprocessors/smtp/Makefile.am, src/dynamic-preprocessors/smtp/sf_smtp.dsp, src/dynamic-preprocessors/smtp/snort_smtp.c, src/dynamic-preprocessors/smtp/snort_smtp.h, src/dynamic-preprocessors/ssl/Makefile.am, src/dynamic-preprocessors/ssl/sf_ssl.dsp, src/dynamic-preprocessors/ssl_common/ssl.c, src/dynamic-preprocessors/ssl_common/ssl.h, src/dynamic-preprocessors/ssl_common/ssl_config.c, src/dynamic-preprocessors/ssl_common/ssl_config.h, src/dynamic-preprocessors/ssl_common/ssl_ha.c, src/dynamic-preprocessors/ssl_common/ssl_ha.h, src/dynamic-preprocessors/ssl_common/ssl_include.h, src/dynamic-preprocessors/ssl_common/ssl_inspect.c, src/dynamic-preprocessors/ssl_common/ssl_inspect.h, src/dynamic-preprocessors/ssl_common/ssl_session.h, src/encode.c, src/encode.h, src/event.h, src/event_queue.c, src/event_wrapper.c, src/fpcreate.c, src/fpcreate.h, src/fpdetect.c, src/fpdetect.h, src/generators.h, src/hashstring.c, src/hashstring.h, src/idle_processing.c, src/log.c, src/log.h, src/log_text.c, src/mempool.c, src/mempool.h, src/mstring.c, src/mstring.h, src/output-plugins/spo_alert_fast.c, src/output-plugins/spo_alert_fast.h, src/output-plugins/spo_alert_full.c, src/output-plugins/spo_alert_full.h, src/output-plugins/spo_alert_sf_socket.c, src/output-plugins/spo_alert_syslog.c, src/output-plugins/spo_alert_syslog.h, src/output-plugins/spo_alert_test.c, src/output-plugins/spo_alert_test.h, src/output-plugins/spo_alert_unixsock.c, src/output-plugins/spo_alert_unixsock.h, src/output-plugins/spo_csv.c, src/output-plugins/spo_csv.h, src/output-plugins/spo_log_ascii.c, src/output-plugins/spo_log_ascii.h, src/output-plugins/spo_log_null.c, src/output-plugins/spo_log_null.h, src/output-plugins/spo_log_tcpdump.c, src/output-plugins/spo_log_tcpdump.h, src/output-plugins/spo_unified2.h, src/packet_time.c, src/parser.c, src/parser.h, src/parser/IpAddrSet.c, src/parser/IpAddrSet.h, src/pcrm.c, src/pcrm.h, src/plugbase.c, src/plugbase.h, src/plugin_enum.h, src/ppm.c, src/preprocessors/HttpInspect/include/hi_client.h, src/preprocessors/HttpInspect/include/hi_paf.h, src/preprocessors/HttpInspect/utils/hi_paf.c, src/preprocessors/Session/stream5_ha.c, src/preprocessors/normalize.c, src/preprocessors/normalize.h, src/preprocessors/perf-base.c, src/preprocessors/perf-base.h, src/preprocessors/perf-event.c, src/preprocessors/perf-event.h, src/preprocessors/perf-flow.c, src/preprocessors/perf-flow.h, src/preprocessors/perf.c, src/preprocessors/perf.h, src/preprocessors/session_api.h src/preprocessors/sfprocpidstats.c, src/preprocessors/sfprocpidstats.h, src/preprocessors/spp_arpspoof.c, src/preprocessors/spp_arpspoof.h, src/preprocessors/spp_bo.c, src/preprocessors/spp_bo.h, src/preprocessors/spp_frag3.c, src/preprocessors/spp_frag3.h, src/preprocessors/spp_normalize.c, src/preprocessors/spp_normalize.h, src/preprocessors/spp_perfmonitor.c, src/preprocessors/spp_perfmonitor.h, src/preprocessors/spp_rpc_decode.c, src/preprocessors/spp_rpc_decode.h, src/preprocessors/spp_session.c, src/preprocessors/spp_stream5.c, src/preprocessors/spp_stream5.h, src/preprocessors/stream_api.c, src/preprocessors/stream_api.h, src/preprocessors/stream_expect.c, src/preprocessors/stream_expect.h, src/profiler.c, src/profiler.h, src/rate_filter.c, src/rate_filter.h, src/rules.h, src/sf_protocols.h, src/sf_sdlist.c, src/sf_sdlist.h, src/sf_sdlist_types.h, src/sfdaq.c, src/sfdaq.h, src/sfthreshold.c, src/sfutil/acsmx.c, src/sfutil/acsmx.h, src/sfutil/acsmx2.c, src/sfutil/bitop.h, src/sfutil/bitop_funcs.h, src/sfutil/getopt.h, src/sfutil/mpse.c, src/sfutil/mpse.h, src/sfutil/sf_email_attach_decode.c, src/sfutil/sf_email_attach_decode.h, src/sfutil/sf_ip.c, src/sfutil/sf_iph.c, src/sfutil/sf_sechash.c, src/sfutil/sf_sechash.h, src/sfutil/sha2.h, src/sfutil/util_jsnorm.c, src/sfutil/util_jsnorm.h, src/sfutil/util_unfold.c, src/sfutil/util_unfold.h, src/signature.h, src/snort.c, src/snort.h, src/snort_debug.h, src/spo_plugbase.h, src/tag.c, src/tag.h, src/util.c, src/util.h, src/win32/WIN32-Code/getopt.c, src/win32/WIN32-Code/inet_aton.c, src/win32/WIN32-Code/misc.c, src/win32/WIN32-Includes/config.h, src/win32/WIN32-Includes/getopt.h, src/win32/WIN32-Prj/snort_installer.nsi, ssl/ssl_setup.c, tools/control/sfcontrol.c: Refactor SSL code to make a library for state processing across non-native protocols that use SSL via STARTTLS. Update IMAP/POP/FTP/SSL preprocessors to use new SSL library, and activation of PAF for those protocols. Add ability to share basic state for SSL. * configure.in, doc/README.session, doc/README.stream5, doc/snort_manual.pdf, doc/snort_manual.tex, dynamic-preprocessors/dns/spp_dns.c, dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, dynamic-preprocessors/gtp/spp_gtp.c, dynamic-preprocessors/imap/spp_imap.c, dynamic-preprocessors/modbus/spp_modbus.c, dynamic-preprocessors/pop/spp_pop.c, dynamic-preprocessors/sip/spp_sip.c, dynamic-preprocessors/smtp/spp_smtp.c, dynamic-preprocessors/ssh/spp_ssh.c, etc/sf_rule_options, preprocessors/Session/session_common.c, preprocessors/Session/session_common.h, preprocessors/Session/session_expect.c, preprocessors/Stream6/snort_stream_ip.c, preprocessors/Stream6/snort_stream_tcp.c, preprocessors/Stream6/snort_stream_tcp.h, preprocessors/Stream6/snort_stream_udp.c, preprocessors/Stream6/stream_common.h, preprocessors/session_api.h, preprocessors/snort_httpinspect.c, preprocessors/spp_rpc_decode.c, preprocessors/spp_session.c, preprocessors/spp_stream6.c, preprocessors/stream_api.h, preprocids.h, src/Makefile.am, src/active.c, src/active.h, src/build.h, src/detect.c, src/detect.h, src/detection-plugins/Makefile.am, src/detection-plugins/sp_clientserver.c, src/detection-plugins/sp_flowbits.c, src/detection-plugins/sp_pattern_match.c, src/detection-plugins/sp_pattern_match.h, src/dynamic-examples/Makefile.am, src/dynamic-examples/dynamic-preprocessor/spp_example.c, src/dynamic-output/plugins/output_lib.h, src/dynamic-output/plugins/output_plugin.c, src/dynamic-plugins/sf_convert_dynamic.c, src/dynamic-plugins/sf_dynamic_plugins.c, src/dynamic-plugins/sf_dynamic_preprocessor.h, src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c, src/dynamic-plugins/sf_engine/sf_snort_packet.h, src/dynamic-plugins/sf_engine/sf_snort_plugin_api.h, src/dynamic-plugins/sf_engine/sf_snort_plugin_content.c, src/dynamic-plugins/sp_preprocopt.c, src/dynamic-preprocessors/Makefile.am, src/dynamic-preprocessors/dcerpc2/dce2_cl.c, src/dynamic-preprocessors/dcerpc2/dce2_config.c, src/dynamic-preprocessors/dcerpc2/dce2_config.h, src/dynamic-preprocessors/dcerpc2/dce2_paf.c, src/dynamic-preprocessors/dcerpc2/dce2_roptions.c, src/dynamic-preprocessors/dcerpc2/dce2_session.h, src/dynamic-preprocessors/dcerpc2/dce2_smb.c, src/dynamic-preprocessors/dcerpc2/snort_dce2.c, src/dynamic-preprocessors/dcerpc2/snort_dce2.h, src/dynamic-preprocessors/dcerpc2/spp_dce2.c, src/dynamic-preprocessors/dnp3/dnp3_roptions.c, src/dynamic-preprocessors/dnp3/spp_dnp3.c, src/dynamic-preprocessors/dnp3/spp_dnp3.h, src/dynamic-preprocessors/dns/spp_dns.c, src/dynamic-preprocessors/dns/spp_dns.h, src/dynamic-preprocessors/file/file_agent.c, src/dynamic-preprocessors/file/file_event_log.c, src/dynamic-preprocessors/file/spp_file.c, src/dynamic-preprocessors/ftptelnet/ftpp_si.c, src/dynamic-preprocessors/ftptelnet/ftpp_si.h, src/dynamic-preprocessors/ftptelnet/pp_ftp.c, src/dynamic-preprocessors/ftptelnet/pp_telnet.c, src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.h, src/dynamic-preprocessors/ftptelnet/spp_ftptelnet.c, src/dynamic-preprocessors/gtp/gtp_roptions.c, src/dynamic-preprocessors/gtp/spp_gtp.c, src/dynamic-preprocessors/imap/imap_config.c, src/dynamic-preprocessors/imap/imap_config.h, src/dynamic-preprocessors/imap/sf_imap.dsp, src/dynamic-preprocessors/imap/snort_imap.c, src/dynamic-preprocessors/imap/snort_imap.h, src/dynamic-preprocessors/imap/spp_imap.c, src/dynamic-preprocessors/libs/sfdynamic_preproc_libs.dsp, src/dynamic-preprocessors/modbus/modbus_decode.c, src/dynamic-preprocessors/modbus/modbus_roptions.c, src/dynamic-preprocessors/modbus/spp_modbus.c, src/dynamic-preprocessors/modbus/spp_modbus.h, src/dynamic-preprocessors/pop/pop_config.c, src/dynamic-preprocessors/pop/pop_config.h, src/dynamic-preprocessors/pop/pop_util.c, src/dynamic-preprocessors/pop/sf_pop.dsp, src/dynamic-preprocessors/pop/snort_pop.c, src/dynamic-preprocessors/pop/snort_pop.h, src/dynamic-preprocessors/pop/spp_pop.c, src/dynamic-preprocessors/reputation/spp_reputation.c, src/dynamic-preprocessors/sdf/spp_sdf.c, src/dynamic-preprocessors/sip/sip_dialog.c, src/dynamic-preprocessors/sip/sip_roptions.c, src/dynamic-preprocessors/sip/spp_sip.c, src/dynamic-preprocessors/smtp/sf_smtp.dsp, src/dynamic-preprocessors/smtp/smtp_config.c, src/dynamic-preprocessors/smtp/smtp_config.h, src/dynamic-preprocessors/smtp/smtp_util.c, src/dynamic-preprocessors/smtp/snort_smtp.c, src/dynamic-preprocessors/smtp/spp_smtp.c, src/dynamic-preprocessors/ssh/spp_ssh.c, src/encode.c, src/encode.h, src/event_queue.c, src/event_wrapper.c, src/file-process/file_api.h, src/file-process/file_mime_process.c, src/file-process/file_mime_process.h, src/file-process/file_service.c, src/file-process/file_stats.c, src/file-process/libs/file_config.c, src/file-process/libs/file_config.h, src/fpcreate.c, src/fpdetect.c, src/generators.h, src/parser.c, src/parser.h, src/plugbase.c, src/plugbase.h, src/ppm.c, src/preprocessors/HttpInspect/include/hi_ui_config.h, src/preprocessors/HttpInspect/session_inspection/hi_si.c, src/preprocessors/Makefile.am, src/preprocessors/Session/Makefile.am, src/preprocessors/Session/session_common.c, src/preprocessors/Session/session_common.h, src/preprocessors/Session/session_expect.c, src/preprocessors/Session/session_expect.h, src/preprocessors/Session/snort_session.c, src/preprocessors/Session/snort_session.h, src/preprocessors/Session/stream5_ha.c, src/preprocessors/Session/stream5_ha.h, src/preprocessors/Stream6/Makefile.am, src/preprocessors/Stream6/snort_stream_icmp.c, src/preprocessors/Stream6/snort_stream_icmp.h, src/preprocessors/Stream6/snort_stream_ip.c, src/preprocessors/Stream6/snort_stream_ip.h, src/preprocessors/Stream6/snort_stream_tcp.c, src/preprocessors/Stream6/snort_stream_tcp.h, src/preprocessors/Stream6/snort_stream_udp.c, src/preprocessors/Stream6/snort_stream_udp.h, src/preprocessors/Stream6/stream_common.c, src/preprocessors/Stream6/stream_common.h, src/preprocessors/Stream6/stream_paf.c, src/preprocessors/Stream6/stream_paf.h, src/preprocessors/perf-base.c, src/preprocessors/portscan.c, src/preprocessors/session_api.c, src/preprocessors/session_api.h, src/preprocessors/snort_httpinspect.c, src/preprocessors/snort_httpinspect.h, src/preprocessors/spp_arpspoof.c, src/preprocessors/spp_bo.c, src/preprocessors/spp_frag3.c, src/preprocessors/spp_httpinspect.c, src/preprocessors/spp_normalize.c, src/preprocessors/spp_perfmonitor.c, src/preprocessors/spp_rpc_decode.c, src/preprocessors/spp_session.c, src/preprocessors/spp_session.h, src/preprocessors/spp_sfportscan.c, src/preprocessors/spp_stream5.c, src/preprocessors/spp_stream5.h, src/preprocessors/spp_stream6.c, src/preprocessors/spp_stream6.h, src/preprocessors/stream_api.h, src/preprocessors/stream_expect.c, src/preprocessors/stream_expect.h, src/preprocids.h, src/sf_sdlist.c, src/sf_sdlist.h, src/sfdaq.c, src/sfdaq.h, src/sfutil/sfPolicy.c, src/sfutil/sfPolicy.h, src/sfutil/sfPolicyData.h, src/sfutil/sfPolicyUserData.h, src/sfutil/sf_email_attach_decode.h, src/sfutil/sfrf.c, src/sfutil/sfthd.c, src/sfutil/test/sf_ip_test.c, src/snort.c, src/snort.h, src/target-based/sftarget_protocol_reference.c, src/target-based/sftarget_reader.c, src/target-based/sftarget_reader.h, src/util.c, src/win32/WIN32-Prj/snort.dsp, tools/Makefile.a: Split the session tracking and reassembly functionality of Stream5 into new Session and Stream preprocessors. * configure.in, doc/INSTALL, doc/Makefile.am, doc/README.appid, doc/snort_manual.tex, src/detect.c, src/detection-plugins/Makefile.am, src/detection-plugins/detection_options.c, src/detection-plugins/sp_appid.c, src/detection-plugins/sp_appid.h src/dynamic-plugins/sf_dynamic_common.h, src/dynamic-plugins/sf_dynamic_define.h, src/dynamic-plugins/sf_dynamic_meta.h, src/dynamic-plugins/sf_dynamic_plugins.c, src/dynamic-plugins/sf_dynamic_preprocessor.h, src/dynamic-plugins/sf_engine/Makefile.am, src/dynamic-plugins/sf_engine/sf_snort_packet.h, src/dynamic-preprocessors/Makefile.am src/dynamic-preprocessors/Makefile.am, src/dynamic-preprocessors/appid/Makefile.am, src/dynamic-preprocessors/appid/appId.h, src/dynamic-preprocessors/appid/appIdConfig.c, src/dynamic-preprocessors/appid/appIdConfig.h, src/dynamic-preprocessors/appid/appIdStats.c, src/dynamic-preprocessors/appid/appIdStats.h, src/dynamic-preprocessors/appid/appInfoTable.c, src/dynamic-preprocessors/appid/appInfoTable.h, src/dynamic-preprocessors/appid/attribute.h, src/dynamic-preprocessors/appid/client_plugins/Makefile.am, src/dynamic-preprocessors/appid/client_plugins/client_app_aim.c, src/dynamic-preprocessors/appid/client_plugins/client_app_aim.h, src/dynamic-preprocessors/appid/client_plugins/client_app_api.h, src/dynamic-preprocessors/appid/client_plugins/client_app_base.c, src/dynamic-preprocessors/appid/client_plugins/client_app_base.h, src/dynamic-preprocessors/appid/client_plugins/client_app_bit.c, src/dynamic-preprocessors/appid/client_plugins/client_app_bit_tracker.c, src/dynamic-preprocessors/appid/client_plugins/client_app_msn.c, src/dynamic-preprocessors/appid/client_plugins/client_app_msn.h, src/dynamic-preprocessors/appid/client_plugins/client_app_rtp.c, src/dynamic-preprocessors/appid/client_plugins/client_app_sip.c, src/dynamic-preprocessors/appid/client_plugins/client_app_sip.h, src/dynamic-preprocessors/appid/client_plugins/client_app_smtp.c, src/dynamic-preprocessors/appid/client_plugins/client_app_smtp.h, src/dynamic-preprocessors/appid/client_plugins/client_app_ssh.c, src/dynamic-preprocessors/appid/client_plugins/client_app_template.c, src/dynamic-preprocessors/appid/client_plugins/client_app_timbuktu.c, src/dynamic-preprocessors/appid/client_plugins/client_app_tns.c, src/dynamic-preprocessors/appid/client_plugins/client_app_vnc.c, src/dynamic-preprocessors/appid/client_plugins/client_app_ym.c, src/dynamic-preprocessors/appid/client_plugins/client_app_ym.h, src/dynamic-preprocessors/appid/commonAppMatcher.c, src/dynamic-preprocessors/appid/commonAppMatcher.h, src/dynamic-preprocessors/appid/detector_plugins/Makefile.am, src/dynamic-preprocessors/appid/detector_plugins/detector_api.h, src/dynamic-preprocessors/appid/detector_plugins/detector_base.c, src/dynamic-preprocessors/appid/detector_plugins/detector_base.h, src/dynamic-preprocessors/appid/detector_plugins/detector_http.c, src/dynamic-preprocessors/appid/detector_plugins/detector_http.h, src/dynamic-preprocessors/appid/detector_plugins/detector_imap.c, src/dynamic-preprocessors/appid/detector_plugins/detector_kerberos.c, src/dynamic-preprocessors/appid/detector_plugins/detector_pop3.c, src/dynamic-preprocessors/appid/detector_plugins/detector_sip.c, src/dynamic-preprocessors/appid/detector_plugins/detector_sip.h, src/dynamic-preprocessors/appid/detector_plugins/http_url_patterns.c, src/dynamic-preprocessors/appid/detector_plugins/http_url_patterns.h, src/dynamic-preprocessors/appid/diffScript.sh, src/dynamic-preprocessors/appid/doxy_api.c, src/dynamic-preprocessors/appid/flow.c, src/dynamic-preprocessors/appid/flow.h, src/dynamic-preprocessors/appid/flow_error.h, src/dynamic-preprocessors/appid/fw_appid.c, src/dynamic-preprocessors/appid/fw_appid.h, src/dynamic-preprocessors/appid/hostPortAppCache.c, src/dynamic-preprocessors/appid/hostPortAppCache.h, src/dynamic-preprocessors/appid/host_tracker.h, src/dynamic-preprocessors/appid/httpCommon.h, src/dynamic-preprocessors/appid/luaDetectorApi.c, src/dynamic-preprocessors/appid/luaDetectorApi.h, src/dynamic-preprocessors/appid/luaDetectorFlowApi.c, src/dynamic-preprocessors/appid/luaDetectorFlowApi.h, src/dynamic-preprocessors/appid/luaDetectorModule.c, src/dynamic-preprocessors/appid/luaDetectorModule.h, src/dynamic-preprocessors/appid/rna_flow.h, src/dynamic-preprocessors/appid/service_plugins/Makefile.am, src/dynamic-preprocessors/appid/service_plugins/dcerpc.c, src/dynamic-preprocessors/appid/service_plugins/dcerpc.h, src/dynamic-preprocessors/appid/service_plugins/service_MDNS.c, src/dynamic-preprocessors/appid/service_plugins/service_MDNS.h, src/dynamic-preprocessors/appid/service_plugins/service_api.h, src/dynamic-preprocessors/appid/service_plugins/service_base.c, src/dynamic-preprocessors/appid/service_plugins/service_base.h, src/dynamic-preprocessors/appid/service_plugins/service_battle_field.c, src/dynamic-preprocessors/appid/service_plugins/service_battle_field.h, src/dynamic-preprocessors/appid/service_plugins/service_bgp.c, src/dynamic-preprocessors/appid/service_plugins/service_bgp.h, src/dynamic-preprocessors/appid/service_plugins/service_bit.c, src/dynamic-preprocessors/appid/service_plugins/service_bootp.c, src/dynamic-preprocessors/appid/service_plugins/service_bootp.h, src/dynamic-preprocessors/appid/service_plugins/service_dcerpc.c, src/dynamic-preprocessors/appid/service_plugins/service_dcerpc.h, src/dynamic-preprocessors/appid/service_plugins/service_direct_connect.c, src/dynamic-preprocessors/appid/service_plugins/service_direct_connect.h, src/dynamic-preprocessors/appid/service_plugins/service_dns.c, src/dynamic-preprocessors/appid/service_plugins/service_dns.h, src/dynamic-preprocessors/appid/service_plugins/service_flap.c, src/dynamic-preprocessors/appid/service_plugins/service_flap.h, src/dynamic-preprocessors/appid/service_plugins/service_ftp.c, src/dynamic-preprocessors/appid/service_plugins/service_ftp.h, src/dynamic-preprocessors/appid/service_plugins/service_irc.c, src/dynamic-preprocessors/appid/service_plugins/service_irc.h, src/dynamic-preprocessors/appid/service_plugins/service_lpr.c, src/dynamic-preprocessors/appid/service_plugins/service_lpr.h, src/dynamic-preprocessors/appid/service_plugins/service_mysql.c, src/dynamic-preprocessors/appid/service_plugins/service_mysql.h, src/dynamic-preprocessors/appid/service_plugins/service_netbios.c, src/dynamic-preprocessors/appid/service_plugins/service_netbios.h, src/dynamic-preprocessors/appid/service_plugins/service_nntp.c, src/dynamic-preprocessors/appid/service_plugins/service_nntp.h, src/dynamic-preprocessors/appid/service_plugins/service_ntp.c, src/dynamic-preprocessors/appid/service_plugins/service_ntp.h, src/dynamic-preprocessors/appid/service_plugins/service_pattern.c, src/dynamic-preprocessors/appid/service_plugins/service_pattern.h, src/dynamic-preprocessors/appid/service_plugins/service_radius.c, src/dynamic-preprocessors/appid/service_plugins/service_radius.h, src/dynamic-preprocessors/appid/service_plugins/service_rexec.c, src/dynamic-preprocessors/appid/service_plugins/service_rexec.h, src/dynamic-preprocessors/appid/service_plugins/service_rfb.c, src/dynamic-preprocessors/appid/service_plugins/service_rfb.h, src/dynamic-preprocessors/appid/service_plugins/service_rlogin.c, src/dynamic-preprocessors/appid/service_plugins/service_rlogin.h, src/dynamic-preprocessors/appid/service_plugins/service_rpc.c, src/dynamic-preprocessors/appid/service_plugins/service_rpc.h, src/dynamic-preprocessors/appid/service_plugins/service_rshell.c, src/dynamic-preprocessors/appid/service_plugins/service_rshell.h, src/dynamic-preprocessors/appid/service_plugins/service_rsync.c, src/dynamic-preprocessors/appid/service_plugins/service_rsync.h, src/dynamic-preprocessors/appid/service_plugins/service_sip.c, src/dynamic-preprocessors/appid/service_plugins/service_sip.h, src/dynamic-preprocessors/appid/service_plugins/service_smtp.c, src/dynamic-preprocessors/appid/service_plugins/service_smtp.h, src/dynamic-preprocessors/appid/service_plugins/service_snmp.c, src/dynamic-preprocessors/appid/service_plugins/service_snmp.h, src/dynamic-preprocessors/appid/service_plugins/service_ssh.c, src/dynamic-preprocessors/appid/service_plugins/service_ssh.h, src/dynamic-preprocessors/appid/service_plugins/service_ssl.c, src/dynamic-preprocessors/appid/service_plugins/service_ssl.h, src/dynamic-preprocessors/appid/service_plugins/service_telnet.c, src/dynamic-preprocessors/appid/service_plugins/service_telnet.h, src/dynamic-preprocessors/appid/service_plugins/service_template.c, src/dynamic-preprocessors/appid/service_plugins/service_tftp.c, src/dynamic-preprocessors/appid/service_plugins/service_tftp.h, src/dynamic-preprocessors/appid/service_plugins/service_timbuktu.c, src/dynamic-preprocessors/appid/service_plugins/service_tns.c, src/dynamic-preprocessors/appid/service_plugins/service_util.h, src/dynamic-preprocessors/appid/service_state.c, src/dynamic-preprocessors/appid/service_state.h, src/dynamic-preprocessors/appid/spp_appid.c, src/dynamic-preprocessors/appid/spp_appid.h, src/dynamic-preprocessors/appid/tools/u2openappid/Makefile.am, src/dynamic-preprocessors/appid/tools/u2streamer/Makefile.am, src/dynamic-preprocessors/appid/util/Makefile.am, src/dynamic-preprocessors/appid/util/OutputFile.c, src/dynamic-preprocessors/appid/util/OutputFile.h, src/dynamic-preprocessors/appid/util/acsmx.c, src/dynamic-preprocessors/appid/util/acsmx.h, src/dynamic-preprocessors/appid/util/acsmx2.c, src/dynamic-preprocessors/appid/util/acsmx2.h, src/dynamic-preprocessors/appid/util/bnfa_search.c, src/dynamic-preprocessors/appid/util/bnfa_search.h, src/dynamic-preprocessors/appid/util/common_util.h, src/dynamic-preprocessors/appid/util/fw_avltree.c, src/dynamic-preprocessors/appid/util/fw_avltree.h, src/dynamic-preprocessors/appid/util/ip_funcs.h, src/dynamic-preprocessors/appid/util/mpse.c, src/dynamic-preprocessors/appid/util/mpse.h, src/dynamic-preprocessors/appid/util/sf_error.h, src/dynamic-preprocessors/appid/util/sf_mlmp.c, src/dynamic-preprocessors/appid/util/sf_mlmp.h, src/dynamic-preprocessors/appid/util/sf_multi_mpse.c, src/dynamic-preprocessors/appid/util/sf_multi_mpse.h, src/dynamic-preprocessors/appid/util/sfghash.c, src/dynamic-preprocessors/appid/util/sfghash.h, src/dynamic-preprocessors/appid/util/sfhashfcn.c, src/dynamic-preprocessors/appid/util/sfhashfcn.h, src/dynamic-preprocessors/appid/util/sfksearch.c, src/dynamic-preprocessors/appid/util/sfksearch.h, src/dynamic-preprocessors/appid/util/sflsq.c, src/dynamic-preprocessors/appid/util/sflsq.h, src/dynamic-preprocessors/appid/util/sfmemcap.c, src/dynamic-preprocessors/appid/util/sfmemcap.h, src/dynamic-preprocessors/appid/util/sfutil.c, src/dynamic-preprocessors/appid/util/sfutil.h, src/dynamic-preprocessors/appid/util/sfxhash.c, src/dynamic-preprocessors/appid/util/sfxhash.h, src/dynamic-preprocessors/file/file_agent.c, src/dynamic-preprocessors/imap/spp_imap.c, src/event.h, src/event_wrapper.c, src/file-process/file_service.c, src/file-process/file_stats.c, src/file-process/file_stats.h, src/log.c, src/log.h, src/output-plugins/spo_alert_unixsock.c, src/output-plugins/spo_unified2.c, src/plugbase.c, src/plugin_enum.h, src/ppm.c, src/preprocessors/HttpInspect/client/hi_client.c, src/preprocessors/HttpInspect/include/hi_client.h, src/preprocessors/HttpInspect/include/hi_ui_config.h, src/preprocessors/HttpInspect/include/hi_util.h, src/preprocessors/HttpInspect/server/hi_server.c, src/preprocessors/perf-base.c, src/preprocessors/snort_httpinspect.c, src/preprocessors/spp_httpinspect.c, src/preprocessors/spp_sfportscan.c, src/preprocessors/spp_stream5.c, src/preprocessors/str_search.c, src/preprocessors/str_search.h, src/preprocessors/stream_api.h, src/preprocids.h, src/rule_option_types.h, src/sf_protocols.h, src/sfutil/Makefile.am, src/sfutil/Unified2_common.h, src/sfutil/acsmx.c, src/sfutil/acsmx2.c, src/sfutil/bnfa_search.c, src/sfutil/mpse.c, src/sfutil/mpse.h, src/sfutil/mpse_methods.h, src/sfutil/sfPolicy.h, src/sfutil/sf_ip.h, src/sfutil/sfdebug.h, src/sfutil/sfghash.c, src/sfutil/sfghash.h, src/sfutil/sfhashfcn.c, src/sfutil/sfksearch.c, src/sfutil/sflsq.c, src/sfutil/sflsq.h, src/sfutil/sfmemcap.c, src/sfutil/sfrt.h, src/sfutil/sfxhash.c, src/sfutil/sfxhash.h, src/signature.h, src/snort.c, src/snort.h, src/snort_debug.h, src/tag.c, src/target-based/sftarget_protocol_reference.c, src/target-based/sftarget_protocol_reference.h, src/util.c, tools/Makefile.am, tools/file_server/file_server.c, tools/u2openappid/Makefile.am, tools/u2openappid/u2openappid.c, tools/u2spewfoo/u2spewfoo.c tools/u2spewfoo/u2spewfoo.c, tools/u2streamer/Makefile.am, tools/u2streamer/SpoolFileIterator.c, tools/u2streamer/SpoolFileIterator.h, tools/u2streamer/TimestampedFile.c, tools/u2streamer/TimestampedFile.h, tools/u2streamer/Unified2.c, tools/u2streamer/Unified2.h, tools/u2streamer/Unified2File.c, tools/u2streamer/Unified2File.h, tools/u2streamer/UnifiedLog.c, tools/u2streamer/UnifiedLog.h, tools/u2streamer/sf_error.c, tools/u2streamer/sf_error.h, src/dynamic-preprocessors/appid/util/common_util.c, tools/u2streamer/u2streamer.c: Improved support for AppID preprocessor. Removed Lua dependency in favor of LuaJIT. Fixed appid with Lua/LuaBitOp (no LuaJIT), support FreeBSD Fixed OpenBSD, FreeBSD openAppId support, Removed support for Lua Added metadata extraction to SSL for AppID. Changed some Lua API names. Refactored to use common data structures. Fixed return value checks for fseek(), strdup, malloc(), and stat() and removed deprecated library calls (Thanks to Bill Parker for reporting the issues). 2014-02-21 Steven Sturges * configure.in, src/detect.c, src/event.h, src/event_wrapper.c, src/log.c, src/log.h, src/plugbase.c, src/plugin_enum.h, src/ppm.c, src/preprocids.h, src/rule_option_types.h, src/sf_protocols.h, src/signature.h, src/snort.c, src/snort.h, src/snort_debug.h, src/tag.c, src/detection-plugins/Makefile.am, src/detection-plugins/detection_options.c, src/dynamic-plugins/sf_dynamic_common.h, src/dynamic-plugins/sf_dynamic_define.h, src/dynamic-plugins/sf_dynamic_meta.h, src/dynamic-plugins/sf_dynamic_plugins.c, src/dynamic-plugins/sf_dynamic_preprocessor.h, src/dynamic-plugins/sf_engine/Makefile.am, src/dynamic-plugins/sf_engine/sf_snort_packet.h, src/dynamic-preprocessors/Makefile.am, src/output-plugins/spo_alert_unixsock.c, src/output-plugins/spo_unified2.c, src/preprocessors/snort_httpinspect.c, src/preprocessors/spp_httpinspect.c, src/preprocessors/spp_sfportscan.c, src/preprocessors/spp_stream5.c, src/preprocessors/stream_api.h, src/preprocessors/HttpInspect/client/hi_client.c, src/preprocessors/HttpInspect/include/hi_client.h, src/preprocessors/HttpInspect/include/hi_ui_config.h, src/preprocessors/HttpInspect/include/hi_util.h, src/preprocessors/HttpInspect/server/hi_server.c, src/preprocessors/Stream5/stream5_common.h, src/sfutil/Unified2_common.h, src/sfutil/sfPolicy.h, src/sfutil/sf_ip.h, src/sfutil/sfrt.h, src/target-based/sftarget_protocol_reference.c, src/target-based/sftarget_protocol_reference.h, tools/Makefile.am, tools/u2spewfoo/u2spewfoo.c, tools/: Makefile.am, u2spewfoo/u2spewfoo.c, u2openappid/Makefile.am, u2openappid/u2openappid.c, u2streamer/Makefile.am, u2streamer/SpoolFileIterator.c, u2streamer/SpoolFileIterator.h, u2streamer/TimestampedFile.c, u2streamer/TimestampedFile.h, u2streamer/Unified2.c, u2streamer/Unified2.h, u2streamer/Unified2File.c, u2streamer/Unified2File.h, u2streamer/UnifiedLog.c, u2streamer/UnifiedLog.h, u2streamer/sf_error.c, u2streamer/sf_error.h, u2streamer/u2streamer.c, src/dynamic-preprocessors/appid/: Makefile.am, appId.h, appIdConfig.c, appIdConfig.h, appIdStats.c, appIdStats.h, appInfoTable.c, appInfoTable.h, attribute.h, commonAppMatcher.c, commonAppMatcher.h, diffScript.sh, doxy_api.c, flow.c, flow.h, flow_error.h, fw_appid.c, fw_appid.h, hostPortAppCache.c, hostPortAppCache.h, host_tracker.h, httpCommon.h, luaDetectorApi.c, luaDetectorApi.h, luaDetectorFlowApi.c, luaDetectorFlowApi.h, luaDetectorModule.c, luaDetectorModule.h, rna_flow.h, service_state.c, service_state.h, spp_appid.c, spp_appid.h, detector_plugins/Makefile.am, detector_plugins/detector_api.h, detector_plugins/detector_base.c, detector_plugins/detector_base.h, detector_plugins/detector_imap.c, detector_plugins/detector_kerberos.c, detector_plugins/detector_pop3.c, detector_plugins/detector_http.c, detector_plugins/detector_http.h, detector_plugins/http_url_patterns.c, detector_plugins/http_url_patterns.h, util/Makefile.am, util/OutputFile.c, util/OutputFile.h, util/acsmx.c, util/acsmx.h, util/acsmx2.c, util/acsmx2.h, util/bnfa_search.c, util/bnfa_search.h, util/common_util.h, util/fw_avltree.c, util/fw_avltree.h, util/ip_funcs.h, util/mpse.c, util/mpse.h, util/sf_error.h, util/sf_mlmp.c, util/sf_mlmp.h, util/sf_multi_mpse.c, util/sf_multi_mpse.h, util/sfghash.c, util/sfghash.h, util/sfhashfcn.c, util/sfhashfcn.h, util/sfksearch.c, util/sfksearch.h, util/sflsq.c, util/sflsq.h, util/sfmemcap.c, util/sfmemcap.h, util/sfutil.c, util/sfutil.h, util/sfxhash.c, util/sfxhash.h, client_plugins/Makefile.am, client_plugins/client_app_aim.c, client_plugins/client_app_aim.h, client_plugins/client_app_api.h, client_plugins/client_app_base.c, client_plugins/client_app_base.h, client_plugins/client_app_bit.c, client_plugins/client_app_bit_tracker.c, client_plugins/client_app_msn.c, client_plugins/client_app_msn.h, client_plugins/client_app_rtp.c, client_plugins/client_app_sip.c, client_plugins/client_app_sip.h, client_plugins/client_app_smtp.c, client_plugins/client_app_smtp.h, client_plugins/client_app_ssh.c, client_plugins/client_app_template.c, client_plugins/client_app_timbuktu.c, client_plugins/client_app_tns.c, client_plugins/client_app_vnc.c, client_plugins/client_app_ym.c, client_plugins/client_app_ym.h, service_plugins/Makefile.am, service_plugins/dcerpc.c, service_plugins/dcerpc.h, service_plugins/service_MDNS.c, service_plugins/service_MDNS.h, service_plugins/service_api.h, service_plugins/service_base.c, service_plugins/service_base.h, service_plugins/service_battle_field.c, service_plugins/service_battle_field.h, service_plugins/service_bgp.c, service_plugins/service_bgp.h, service_plugins/service_bit.c, service_plugins/service_bootp.c, service_plugins/service_bootp.h, service_plugins/service_dcerpc.c, service_plugins/service_dcerpc.h, service_plugins/service_direct_connect.c, service_plugins/service_direct_connect.h, service_plugins/service_dns.c, service_plugins/service_dns.h, service_plugins/service_flap.c, service_plugins/service_flap.h, service_plugins/service_ftp.c, service_plugins/service_ftp.h, service_plugins/service_irc.c, service_plugins/service_irc.h, service_plugins/service_lpr.c, service_plugins/service_lpr.h, service_plugins/service_mysql.c, service_plugins/service_mysql.h, service_plugins/service_netbios.c, service_plugins/service_netbios.h, service_plugins/service_nntp.c, service_plugins/service_nntp.h, service_plugins/service_ntp.c, service_plugins/service_ntp.h, service_plugins/service_pattern.c, service_plugins/service_pattern.h, service_plugins/service_radius.c, service_plugins/service_radius.h, service_plugins/service_rexec.c, service_plugins/service_rexec.h, service_plugins/service_rfb.c, service_plugins/service_rfb.h, service_plugins/service_rlogin.c, service_plugins/service_rlogin.h, service_plugins/service_rpc.c, service_plugins/service_rpc.h, service_plugins/service_rshell.c, service_plugins/service_rshell.h, service_plugins/service_rsync.c, service_plugins/service_rsync.h, service_plugins/service_sip.c, service_plugins/service_sip.h, service_plugins/service_smtp.c, service_plugins/service_smtp.h, service_plugins/service_snmp.c, service_plugins/service_snmp.h, service_plugins/service_ssh.c, service_plugins/service_ssh.h, service_plugins/service_ssl.c, service_plugins/service_ssl.h, service_plugins/service_telnet.c, service_plugins/service_telnet.h, service_plugins/service_template.c, service_plugins/service_tftp.c, service_plugins/service_tftp.h, service_plugins/service_timbuktu.c, service_plugins/service_tns.c, service_plugins/service_util.h, src/detection-plugins/: sp_appid.c, sp_appid.h, doc/README.appid: New Open App ID feature to identify application protocol, client, server, and web application and be able to leverage that within Snort rules. 2014-02-19 Steven Sturges * doc/snort_manual.pdf, doc/snort_manual.tex, src/active.c, src/active.h, src/encode.h, src/detection-plugins/sp_react.c: Added Active_SendBigData to active.c for sending multi-packet react pages. Modified react.c to use Active_SendBigData to allow payload that spans a single TCP packet (1500+ bytes). * src/: preprocessors/Stream5/snort_stream5_tcp.c, preprocessors/Stream5/stream5_paf.c, preprocessors/Stream5/stream5_paf.h, dynamic-preprocessors/pop/Makefile.am, dynamic-preprocessors/pop/pop_config.c, dynamic-preprocessors/pop/pop_config.h, dynamic-preprocessors/pop/pop_log.c, dynamic-preprocessors/pop/pop_log.h, dynamic-preprocessors/pop/pop_paf.c, dynamic-preprocessors/pop/pop_paf.h, dynamic-preprocessors/pop/pop_util.c, dynamic-preprocessors/pop/sf_pop.dsp, dynamic-preprocessors/pop/snort_pop.c, dynamic-preprocessors/pop/snort_pop.h, dynamic-preprocessors/pop/spp_pop.c, dynamic-preprocessors/smtp/Makefile.am, dynamic-preprocessors/smtp/sf_smtp.dsp, dynamic-preprocessors/smtp/smtp_config.c, dynamic-preprocessors/smtp/smtp_config.h, dynamic-preprocessors/smtp/smtp_log.c, dynamic-preprocessors/smtp/smtp_log.h, dynamic-preprocessors/smtp/smtp_paf.c, dynamic-preprocessors/smtp/smtp_paf.h, dynamic-preprocessors/smtp/smtp_util.c, dynamic-preprocessors/smtp/smtp_util.h, dynamic-preprocessors/smtp/snort_smtp.c, dynamic-preprocessors/smtp/snort_smtp.h, dynamic-preprocessors/smtp/spp_smtp.c, file-process/Makefile.am, file-process/file_api.h, file-process/file_mail_common.h, file-process/file_mime_config.c, file-process/file_mime_config.h, file-process/file_mime_process.c, file-process/file_mime_process.h, file-process/file_service.c, dynamic-preprocessors/imap/Makefile.am, dynamic-preprocessors/imap/imap_config.c, dynamic-preprocessors/imap/imap_config.h, dynamic-preprocessors/imap/imap_log.c, dynamic-preprocessors/imap/imap_log.h, dynamic-preprocessors/imap/imap_paf.c, dynamic-preprocessors/imap/imap_paf.h, dynamic-preprocessors/imap/imap_util.c, dynamic-preprocessors/imap/sf_imap.dsp, dynamic-preprocessors/imap/snort_imap.c, dynamic-preprocessors/imap/snort_imap.h, dynamic-preprocessors/imap/spp_imap.c, preprocessors/snort_httpinspect.c, preprocessors/stream_api.h, preprocessors/HttpInspect/include/hi_ui_config.h, sfutil/sf_email_attach_decode.h, dynamic-preprocessors/Makefile.am, dynamic-preprocessors/file/file_agent.c: add paf support to smtp/impa/pop protocols. * src/dynamic-preprocessors/ssh/spp_ssh.c: count the max_client_bytes once the session is encrypted. Fix the ProcessSSHKeyExchange to parse server new keys * src/dynamic-preprocessors/ftptelnet/spp_ftptelnet.c: Fix ftp-data perfstats profiling. * configure.in, src/decode.h, src/sfdaq.c, src/sfdaq.h, src/dynamic-preprocessors/ftptelnet/pp_ftp.c, src/dynamic-preprocessors/sip/sip_dialog.c, src/dynamic-preprocessors/ssh/spp_ssh.c, src/preprocessors/spp_stream5.c, src/preprocessors/stream_api.h, src/preprocessors/stream_expect.c, src/preprocessors/stream_expect.h: Add ability to specify details about dynamic protocols/data channels via DAQ. * src/preprocessors/Stream5/snort_stream5_tcp.c: Checked for existence of policy_id parameter on Stream5 TCP policy. * src/preprocessors/perf-base.c: Ensure pkt_stats cannot go below zero * etc/sf_rule_options, src/Makefile.am, src/fpcreate.c, src/parser.c, src/parser.h, src/snort.c, src/snort.h, src/detection-plugins/sp_pattern_match.c, src/detection-plugins/sp_pattern_match.h, src/dynamic-plugins/sf_convert_dynamic.c, src/dynamic-plugins/sf_dynamic_define.h, src/dynamic-plugins/sf_dynamic_meta.h, src/dynamic-plugins/sf_engine/Makefile.am, src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c, src/dynamic-plugins/sf_engine/sf_snort_plugin_api.c, src/dynamic-plugins/sf_engine/sf_snort_plugin_api.h, src/dynamic-plugins/sf_engine/sf_snort_plugin_content.c, src/sfutil/Makefile.am, src/hashstring.c, src/hashstring.h, sfutil/sf_sechash.c, sfutil/sf_sechash.h, src/file-process/file_capture.c, src/file-process/file_resume_block.c, src/file-process/libs/Makefile.am, src/file-process/libs/file_lib.c, src/sfutil/Makefile.am, src/sfutil/md5.c, src/sfutil/md5.h, src/sfutil/sf_sechash.c, src/sfutil/sf_sechash.h, src/sfutil/sha2.c, src/sfutil/sha2.h, src/win32/WIN32-Prj/snort.dsp, configure.in, doc/snort_manual.pdf, doc/snort_manual.tex: Protected Rule Content feature. Updating the minor revision number for the engine API for share library rules. Augmented the logic in configure.in to force the -lcrypto library to be included in the link. Added implementations of SHA2 and MD5 algorithms to Snort to allow use with older versions of OpenSSL. * doc/: snort_manual.pdf, snort_manual.tex: Modified descriptions of urilen, dsize, and flags rule options. * doc/snort_manual.pdf, doc/snort_manual.tex, src/sfutil/sfPolicy.c: Added check in binding mappings to prevent Snort from loading binding policy_ids > 4095, having it reject the configuration on load. Updated documentation to include config binding policy_id. * src/preprocessors/spp_stream5.c: New minimum max_tcp sessions is now 2. * src/: dynamic-preprocessors/ftptelnet/pp_ftp.c, dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, dynamic-preprocessors/ftptelnet/spp_ftptelnet.c, preprocessors/spp_stream5.c, preprocessors/stream_api.h, preprocessors/stream_expect.c, preprocessors/stream_expect.h: Change preprocessor order for when FTP data is handled. * src/: dynamic-examples/dynamic-preprocessor/Makefile.am, dynamic-plugins/sf_engine/Makefile.am, dynamic-preprocessors/dcerpc2/Makefile.am, dynamic-preprocessors/dnp3/Makefile.am, dynamic-preprocessors/dns/Makefile.am, dynamic-preprocessors/file/Makefile.am, dynamic-preprocessors/ftptelnet/Makefile.am, dynamic-preprocessors/gtp/Makefile.am, dynamic-preprocessors/imap/Makefile.am, dynamic-preprocessors/modbus/Makefile.am, dynamic-preprocessors/pop/Makefile.am, dynamic-preprocessors/reputation/Makefile.am, dynamic-preprocessors/rzb_saac/Makefile.am, dynamic-preprocessors/sdf/Makefile.am, dynamic-preprocessors/sip/Makefile.am, dynamic-preprocessors/smtp/Makefile.am, dynamic-preprocessors/ssh/Makefile.am, dynamic-preprocessors/ssl/Makefile.am: Install libraries into user defined libdir. Thanks to cjgd7-facebook for reporting the issue. * src/: detection-plugins/detection_options.c, detection-plugins/sp_pattern_match.c, detection-plugins/sp_pattern_match.h, dynamic-plugins/sf_convert_dynamic.c: Update 'within' rule limits to handle extraction of a 0 via byte_extract. * src/detection-plugins/: sp_byte_check.c, sp_byte_extract.h, sp_byte_jump.c, sp_isdataat.c, sp_pattern_match.c: Modified error outputs to include the specific offending rule option. 2013-12-30 Steven Sturges Snort 2.9.6.0 * src/build.h: updating build number to 47 * doc/README.file, doc/README.file_ips, etc/file_magic.conf, etc/Makefile.am: Added file_magic.conf and fixed a few typos. Thanks to Joshua Kinard for pointing them out. * doc/snort_manual.tex: Update snort team members * src/detection-plugins/sp_file_type.h, src/dynamic-preprocessors/libs/sf_preproc_info.h, tools/file_server/file_server.c: Clean up copyright and attribution. * src/dynamic-preprocessors/sdf/spp_sdf.c: Fix seconndary check for reassembled packets. * doc/: README.GTP, README.PerfProfiling, README.dcerpc2, README.file, README.frag3, README.ftptelnet, README.http_inspect, README.imap, README.multipleconfigs, README.normalize, README.pop, README.reload, README.reputation, README.rpc_decode, README.sfportscan, README.sip, README.unified2, USAGE, WISHLIST, snort_manual.pdf, snort_manual.tex, README.SMTP, README.counts, README.asn1, README.active, README, NEWS, INSTALL: Corrected typos in documentation. Thanks to Mahendra Ladhe for pointing out the mistakes and providing a patch. * src/: file-process/file_capture.c, file-process/file_mime_process.c, dynamic-preprocessors/imap/snort_imap.c, dynamic-preprocessors/smtp/snort_smtp.c, dynamic-preprocessors/file/file_inspect_config.c, dynamic-preprocessors/pop/snort_pop.c, sfutil/sf_email_attach_decode.h: Enable detetion on all file data * src/sfutil/: sfxhash.c, sfxhash.h: Fix alignment of sfxhash node on sparc. Thanks to Markus Lude. * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: Identify EOF on single segment PDU transimssions. * src/dynamic-preprocessors/dcerpc2/dce2_memory.c: Avoid checking memcap for DCE/RPC configuration data. * src/preprocessors/Stream5/snort_stream5_tcp.c: Tweak retransmit handling to ensure full right overlap condition holds 2013-11-22 Steven Sturges Snort 2.9.6.0.rc * src/build.h: updating build number to 43 * configure.in, doc/README.ha, doc/snort_manual.pdf, doc/snort_manual.tex, doc/Makefile.am: Add Stream5 HA documentation and mark --enable-ha and --enable-side-channel as experimental. * rpm/snort.spec: Install snort_control, u2boat, u2spewfoo from spec file. Thanks to Bradley Turnbough for mentioning it. * src/preprocessors/Stream5/snort_stream5_tcp.c: using sequence number overlapping to trigger retransmission handler. This fixed issue on file blocking. * src/dynamic-preprocessors/: pop/pop_log.c, smtp/smtp_log.c, imap/imap_log.c: avoid mail decoding prepocessor alerts when they not enabled in config. * doc/snort_manual.tex, src/: active.c, active.h, decode.c, detect.c, fpdetect.c, detection-plugins/sp_react.c, dynamic-plugins/sf_dynamic_plugins.c, file-process/file_resume_block.c, file-process/file_service.c, output-plugins/spo_alert_fast.c, output-plugins/spo_unified2.c, preprocessors/spp_bo.c, preprocessors/spp_frag3.c, preprocessors/Stream5/snort_stream5_ip.c, preprocessors/Stream5/snort_stream5_tcp.c, preprocessors/Stream5/snort_stream5_udp.c: alerts get wdrop when active is suspended; code for cdrop is ready but disabled * src/: file-process/file_api.h, file-process/file_resume_block.c, file-process/file_service.c, file-process/libs/file_lib.h, dynamic-preprocessors/file/file_agent.c: Add file id to file API callbacks to support multiple file contexts. * preproc_rules/decoder.rules, src/decode.c, src/generators.h: Validate authentication headers. New decoder rules (116:465 and 116:466). * doc/snort_manual.pdf, doc/snort_manual.tex, src/detection-plugins/sp_icmp_code_check.c: Added data validation checks to the icode rule option. The parser phase will now throw fatal errors for illegal values. Update manual to reflect the additional data validation. * src/preprocessors/Stream5/: snort_stream5_ip.c, snort_stream5_udp.c: Force block for block rule in inline test mode. * src/: dynamic-preprocessors/imap/snort_imap.c, dynamic-preprocessors/pop/snort_pop.c, dynamic-preprocessors/smtp/snort_smtp.c, preprocessors/stream_api.h, preprocessors/Stream5/snort_stream5_tcp.c: Don't put gaps in reassembled packets * src/: preprocessors/Stream5/snort_stream5_session.c, side-channel/sidechannel.c: The global list in the session cache is ordered from MRU (head) to LRU (tail), so correctly walk backward rather than forward from the LRU looking for sessions to time out. Clean up compiler warning in Side Channel. * src/file-process/: libs/file_lib.c, file_api.h, file_capture.c, file_service.c, file_service.h: Add multiple file contexts support for file API. * src/: dynamic-preprocessors/ftptelnet/ftpp_si.c, dynamic-preprocessors/ftptelnet/ftpp_si.h, dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, dynamic-preprocessors/ftptelnet/snort_ftptelnet.h, preprocessors/Stream5/snort_stream5_tcp.c: Add EndOfFile stream event callback. Remove EOF logic from FTP/Preprocessor in lieu of new callback. * src/: file-process/file_service.c, file-process/file_service_config.c, file-process/file_service_config.h, snort.c: make sure file configuration is initialized during reload. 2013-10-18 Hui Cao Snort 2.9.6.0.beta * doc/: Makefile.am, README.file, README.file_ips: Add readme for experimental file type ips rule keywords. * src/detection-plugins/sp_icmp_code_check.c: Allow a negative value in the ICMP icode x<>y range check. This permits the rule to include a check for zero * src/preprocessors/Stream5/snort_stream5_tcp.c: Disable detection when the TCP connection was already closed. * src/: dynamic-preprocessors/ftptelnet/ftpp_si.h, dynamic-preprocessors/ftptelnet/pp_ftp.c, dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, file-process/file_api.h: Fix FTP-Data file processing. * src/snort_bounds.h: Avoid assertion for zero size memory copy * src/: dynamic-plugins/sf_dynamic_plugins.c, detection-plugins/sp_react.c: Only inject response page when session is established. * src/dynamic-preprocessors/smtp/smtp_log.h, src/dynamic-preprocessors/smtp/snort_smtp.c, src/dynamic-preprocessors/smtp/snort_smtp.h, preproc_rules/preprocessor.rules, etc/gen-msg.map: Add a new preprocessor alert to detect Cyrus SASL authentication attack. * src/dynamic-preprocessors/ssh/spp_ssh.c: Set_reassembly to ABSOLUTE only if the traffic is SSH. Statefully process ssh version/ssh key exchange init/key exchange and/or encrypted data within a single reassembled packet. Thanks to Florian Westphal for reporting this. * src/file-process/file_mime_process.c: For IMAP, the MIME and message will be inside fetch body, which will be end at ")". * src/: dynamic-preprocessors/dns/spp_dns.c, dynamic-preprocessors/ssh/spp_ssh.c, Change preprocessor reassembly policy; Changed SSH preprocessor state transition based on the dir rather than both. * src/: preprocessors/Stream5/snort_stream5_tcp.c: Ignore the gap when turning on reassembly dynamically on the very first packet of the session. * src/dynamic-preprocessors/dnp3/spp_dnp3.c: Fix the incorrect mempool warnings. Thanks to Bram for reporting this * doc/snort_manual.pdf, doc/snort_manual.tex, configure.in, src/snort.c, src/util.c: Trim freed memory before and after configuration reload. * src/: dynamic-preprocessors/imap/snort_imap.c, dynamic-preprocessors/pop/snort_pop.c, dynamic-preprocessors/smtp/snort_smtp.c, file-process/file_mime_process.c, sfutil/sf_email_attach_decode.c: Allow 7bit decoding of binary file attachments. * src/dynamic-preprocessors/sdf/: spp_sdf.c, spp_sdf.h: Avoid partial rule tree match during reload. * src/tag.c: Fix boundary check error so that the global tagged packet limit doesn't allow an extra tag. * src/: file-process/file_mime_process.h, file-process/file_api.h, file-process/file_mime_process.c, file-process/file_service.c, dynamic-preprocessors/imap/snort_imap.c, dynamic-preprocessors/imap/spp_imap.c, dynamic-preprocessors/smtp/snort_smtp.c, dynamic-preprocessors/pop/snort_pop.c, dynamic-preprocessors/pop/spp_pop.c: Add simple PAF support for POP and IMAP. * src/: util.c, util.h, sfutil/sf_ip.c, sfutil/sf_ip.h: Bugs Add sfip_convert_ip_text_to_binary() to enforce platform agnostic IPv4 syntax. Make sure xatou(), xatol(), and xatoup() return values within specified range * doc/snort_manual.tex: Update the document to include the '<=' and '>=' operators to the byte_test command * src/preprocessors/Stream5/snort_stream5_tcp.c: Make sure INTERNAL_EVENT_SESSION_ADD event only in the ESTABLISHED state. * src/sfutil/sf_email_attach_decode.c: Check the QP encoding string is valid to avoid decoding end of line incorrectly. * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: Tweak config output to correspond to config input. Thanks to Reinoud Koornstra for the suggestion. * src/preprocessors/Stream5/: snort_stream5_icmp.c, snort_stream5_ip.c, snort_stream5_tcp.c, snort_stream5_udp.c: dynamic-preprocessors/pop/snort_pop.c, dynamic-preprocessors/smtp/snort_smtp.c, dynamic-preprocessors/ssl/spp_ssl.c, encode.c, dynamic-preprocessors/dcerpc2/dce2_cl.c, dynamic-preprocessors/dcerpc2/dce2_session.h, dynamic-preprocessors/dcerpc2/snort_dce2.c, dynamic-preprocessors/dns/spp_dns.c, dynamic-preprocessors/imap/snort_imap.c: preprocessors/spp_rpc_decode.c, preprocessors/spp_stream5.c, preprocessors/stream_api.h, preprocessors/stream_expect.c: Handle out of order SSL handshake in SMTP. Thanks to Bram for the reporting this. * src/preprocessors/perf-base.c: Update the header printed at top of now file. * src/preprocessors/perf-base.c: Change name of stat from Blocked Packets to Block Verdicts. * src/preprocessors/Stream5/snort_stream5_session.c: Timeout a session when session timeout reaches instead of waiting for session nominal timeout. * configure.in, src/plugbase.c, src/rule_option_types.h, src/snort.c, src/detection-plugins/Makefile.am, src/detection-plugins/: sp_file_type.c, sp_file_type.h, src/detection-plugins/detection_options.c, src/dynamic-preprocessors/Makefile.am, src/file-process/Makefile.am, src/file-process/file_api.h, src/file-process/file_service.c, src/file-process/file_service_config.c, src/file-process/file_service_config.h, src/file-process/libs/Makefile.am, src/file-process/libs/file_config.c, src/file-process/libs/file_config.h, src/file-process/libs/file_lib.c, src/file-process/libs/file_lib.h, src/preprocessors/spp_stream5.c, tools/Makefile.am, doc/: README.file, README.file_ips, Makefile.am: File inspection keywords for IPS rules. * src/dynamic-preprocessors/sdf/: sdf_pattern_match.c, sdf_pattern_match.h, spp_sdf.c, spp_sdf.h: Add stateful pattern match of sdf patterns across packets. * mkinstalldirs, doc/snort_manual.tex, src/detect.c, src/detection_util.h, src/fpdetect.c, src/parser.c, src/tag.c, src/tag.h, src/target-based/sf_attribute_table.y, tools/u2spewfoo/u2spewfoo.c: Support single session capture via tag rule option. Log all packets to the same place as original alert. Enable tagging on pass rules. * src/: dynamic-preprocessors/imap/snort_imap.c, dynamic-preprocessors/imap/snort_imap.h, dynamic-preprocessors/pop/snort_pop.c, dynamic-preprocessors/pop/snort_pop.h, dynamic-preprocessors/smtp/snort_smtp.c, dynamic-preprocessors/smtp/snort_smtp.h, file-process/file_api.h, file-process/file_mime_process.c, preprocessors/str_search.c, preprocessors/str_search.h, sfutil/bnfa_search.c: Add Stateful mime boundary search when split between packets. * src/preprocessors/HttpInspect/client/hi_client.c: Change the uri search to start from method end instead of the start of payload. * configure.in, doc/README.file, doc/snort_manual.pdf, src/parser.c, src/preprocids.h, src/snort.c, src/util.c, src/detection-plugins/.cvsignore, src/dynamic-examples/Makefile.am, src/dynamic-plugins/sf_engine/.cvsignore, src/dynamic-preprocessors/Makefile.am, src/dynamic-preprocessors/file/Makefile.am, src/dynamic-preprocessors/file/file_agent.c, src/dynamic-preprocessors/file/file_agent.h, src/dynamic-preprocessors/file/file_event_log.c, src/dynamic-preprocessors/file/file_event_log.h, src/dynamic-preprocessors/file/file_inspect_config.c, src/dynamic-preprocessors/file/file_inspect_config.h, src/dynamic-preprocessors/file/file_sha.c, src/dynamic-preprocessors/file/file_sha.h, src/dynamic-preprocessors/file/sf_file.dsp, src/dynamic-preprocessors/file/spp_file.c, src/dynamic-preprocessors/file/spp_file.h, src/dynamic-preprocessors/sf_dynamic_initialize/sf_dynamic_initialize.dsp, src/file-process/Makefile.am, src/file-process/circular_buffer.c, src/file-process/circular_buffer.h, src/file-process/file_api.h, src/file-process/file_capture.c, src/file-process/file_capture.h, src/file-process/file_mempool.c, src/file-process/file_mempool.h, src/file-process/file_resume_block.c, src/file-process/file_service.c, src/file-process/file_service.h, src/file-process/file_service_config.c, src/file-process/file_service_config.h, src/file-process/file_stats.c, src/file-process/file_stats.h, src/file-process/libs/file_config.c, src/file-process/libs/file_config.h, src/file-process/libs/file_identifier.c, src/file-process/libs/file_identifier.h, src/file-process/libs/file_lib.c, src/file-process/libs/file_lib.h, src/file-process/libs/file_sha256.h, tools/Makefile.am, tools/file_server/Makefile.am, tools/file_server/README.file_server, tools/file_server/file_server.c: Add file capture feature and introduce file inspect preprocessor * src/preprocessors/Stream5/snort_stream5_tcp.c: Parse error if there are missing direction specifiers. Thanks to Bram Fabeg for the report. * src/ipv6_port.h: Remove duplicate macro for GET_ORIG_IPH_PROTO. * doc/: README.decode, README.gre, README.mpls, snort_manual.pdf, snort_manual.tex: Update manual and other docs related to tunneling. Thanks to Jason Poley for noting it. * src/parser.c: Not so silently skip duplicate service metadata. * src/: log.c, mempool.c, parser.c, snort.c, util.c, detection-plugins/sp_ip_tos_check.c, detection-plugins/sp_pattern_match.c, detection-plugins/sp_replace.c, detection-plugins/sp_session.c, detection-plugins/sp_tcp_win_check.c, dynamic-preprocessors/dns/spp_dns.c, dynamic-preprocessors/ftptelnet/pp_ftp.c, dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, dynamic-preprocessors/sdf/sdf_pattern_match.c, output-plugins/spo_log_ascii.c, output-plugins/spo_log_tcpdump.c, preprocessors/HttpInspect/utils/hi_paf.c, preprocessors/Stream5/snort_stream5_tcp.c: Replace obsolete bzero and index calls. Credits to Bill Parker * src/dynamic-preprocessors/: smtp/snort_smtp.c, ssl/spp_ssl.c, libs/ssl.c, libs/ssl.h: Check for SSL type only when the SSL handshake is not complete. Don't check for type in SSL data. Thanks to Bram Fabeg for reporting this. * src/preprocessors/: HttpInspect/server/hi_server.c, HttpInspect/server/hi_server_norm.c, Stream5/snort_stream5_tcp.c: Only check charset bom once per response body; Only set charset once per charset= * src/profiler.c: Fix issue when reading pcaps from command line and using multiple policies and --pcap-reset. * src/detection-plugins/detection_options.c: Don't count RTN perf time in OTN perf time. Credits to Reinoud for reporting this. * doc/README.flowbits: Fix typo in flowbits isnotset examples * src/snort.c, src/snort.h, src/util.c, snort.8, doc/snort_manual.pdf, doc/snort_manual.tex: Add a command line switch --no-interface-pidfile to snort. * src/preprocessors/: spp_stream5.c, Stream5/stream5_common.h: Updated Stream's exit stats to use 'filtered' instead of dropped. * src/: detection_util.h, dynamic-preprocessors/sip/spp_sip.c: Don't set sip/http buffers to null * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.c: Return mismatch if requested http buffer was not set * src/snort.c: Bugs Fixed: Capture packet data for sigabrt and sigbus * doc/README.dcerpc2, doc/snort_manual.pdf, doc/snort_manual.tex, etc/gen-msg.map, preproc_rules/preprocessor.rules, src/active.c, src/active.h, src/encode.c, src/encode.h, src/generators.h, src/dynamic-plugins/sf_dynamic_plugins.c, src/dynamic-plugins/sf_dynamic_preprocessor.h, src/dynamic-preprocessors/dcerpc2/dce2_co.c, src/dynamic-preprocessors/dcerpc2/dce2_config.c, src/dynamic-preprocessors/dcerpc2/dce2_config.h, src/dynamic-preprocessors/dcerpc2/dce2_event.c, src/dynamic-preprocessors/dcerpc2/dce2_event.h, src/dynamic-preprocessors/dcerpc2/dce2_memory.c, src/dynamic-preprocessors/dcerpc2/dce2_memory.h, src/dynamic-preprocessors/dcerpc2/dce2_smb.c, src/dynamic-preprocessors/dcerpc2/dce2_smb.h, src/dynamic-preprocessors/dcerpc2/dce2_stats.h, src/dynamic-preprocessors/dcerpc2/snort_dce2.c, src/dynamic-preprocessors/dcerpc2/snort_dce2.h, src/dynamic-preprocessors/dcerpc2/spp_dce2.c, src/dynamic-preprocessors/dcerpc2/spp_dce2.h, src/dynamic-preprocessors/dcerpc2/includes/smb.h, src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, src/dynamic-preprocessors/imap/snort_imap.c, src/dynamic-preprocessors/pop/snort_pop.c, src/dynamic-preprocessors/smtp/snort_smtp.c, src/file-process/file_api.h, src/file-process/file_mime_process.c, src/file-process/file_service.c, src/file-process/libs/file_identifier.c, src/file-process/libs/file_identifier.h, src/file-process/libs/file_lib.c, src/file-process/libs/file_lib.h, src/preprocessors/snort_httpinspect.c, src/preprocessors/Stream5/snort_stream5_tcp.c: Add SMB file support 2013-10-18 Steven Sturges Snort 2.9.5.6 * src/build.h: updating build number to 208 * src/preprocessors/Stream5/snort_stream5_tcp.c: add NULL check for preprocessors that check for PAF before they check for any actual tcp session * src/detection-plugins/: sp_byte_check.c, sp_byte_jump.c, sp_isdataat.c, sp_pattern_match.c: Test if the byte extracted distance and/or offset is within bounds of the search buffer. Thanks to Nathan Fowler for noting the issue. * src/preprocessors/HttpInspect/client/hi_client.c: clear cookie normalization buffer to avoid accidental null dereference in pipelined request. Thanks to Michael Galapchuk for reporting the problem. 2013-09-02 Steven Sturges Snort 2.9.5.5 * src/preprocessors/Stream5/snort_stream5_tcp.c: disable all detection (not just content-base) for packets on previously blocked sessions * src/preprocessors/perf.c: Write perfmon entry when both packet count and time conditions are met, rather than waiting for a multiple of the packet count after the time is reached. * src/dynamic-preprocessors/smtp/snort_smtp.c: Stop inspection of the entire session when TLS data is present with ignore_tls_data enabled in SMTP - Check for midstream pickups and gaps when we miss server hello, and stop inspection as soon as we get client hello when ignore_tls_data is turned on * src/dynamic-plugins/sf_engine/sf_snort_plugin_pcre.c: changed pcre relative match with HTTP buffers to be not allowed in .so rules (same as in text rules) 2013-07-03 Steven Sturges Snort 2.9.5.3 * src/preprocessors/Stream5/snort_stream5_tcp.c: Fixed handling of partial segment purging. Thanks to Lode Mertens for reporting the issue. * configure.in, src/active.c, src/decode.c, src/decode.h, src/detect.c, src/detection_util.c, src/detection_util.h, src/encode.c, src/encode.h, src/fpcreate.c, src/fpdetect.c, src/log_text.c, src/parser.c, src/plugbase.c, src/ppm.c, src/ppm.h, src/profiler.c, src/snort.c, src/util.c, src/util.h, src/detection-plugins/detection_options.c, src/detection-plugins/sp_byte_check.c, src/detection-plugins/sp_ftpbounce.c, src/detection-plugins/sp_pattern_match.c, src/detection-plugins/sp_pattern_match.h, src/detection-plugins/sp_pcre.c, src/detection-plugins/sp_pcre.h, src/detection-plugins/sp_replace.c, src/detection-plugins/sp_rpc_check.c, src/detection-plugins/sp_urilen_check.c, src/dynamic-examples/dynamic-preprocessor/spp_example.c, src/dynamic-plugins/sf_convert_dynamic.c, src/dynamic-plugins/sf_dynamic_common.h, src/dynamic-plugins/sf_dynamic_define.h, src/dynamic-plugins/sf_dynamic_engine.h, src/dynamic-plugins/sf_dynamic_meta.h, src/dynamic-plugins/sf_dynamic_plugins.c, src/dynamic-plugins/sf_dynamic_preprocessor.h, src/dynamic-plugins/sp_dynamic.c, src/dynamic-plugins/sf_engine/Makefile.am, src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c, src/dynamic-plugins/sf_engine/sf_snort_packet.h, src/dynamic-plugins/sf_engine/sf_snort_plugin_api.c, src/dynamic-plugins/sf_engine/sf_snort_plugin_api.h, src/dynamic-plugins/sf_engine/sf_snort_plugin_content.c, src/dynamic-plugins/sf_engine/sf_snort_plugin_pcre.c, src/dynamic-plugins/sf_engine/examples/bug26266.c, src/dynamic-plugins/sf_engine/examples/detection_lib_meta.h, src/dynamic-plugins/sf_engine/examples/fake_snort.c, src/dynamic-plugins/sf_preproc_example/spp_nfs_setup.c, src/dynamic-preprocessors/dcerpc2/dce2_http.h, src/dynamic-preprocessors/dcerpc2/spp_dce2.c, src/dynamic-preprocessors/dnp3/spp_dnp3.c, src/dynamic-preprocessors/dns/spp_dns.c, src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.h, src/dynamic-preprocessors/ftptelnet/spp_ftptelnet.c, src/dynamic-preprocessors/gtp/spp_gtp.c, src/dynamic-preprocessors/imap/snort_imap.c, src/dynamic-preprocessors/imap/spp_imap.c, src/dynamic-preprocessors/isakmp/spp_isakmp.c, src/dynamic-preprocessors/modbus/spp_modbus.c, src/dynamic-preprocessors/pop/snort_pop.c, src/dynamic-preprocessors/pop/spp_pop.c, src/dynamic-preprocessors/reputation/reputation_config.h, src/dynamic-preprocessors/reputation/spp_reputation.c, src/dynamic-preprocessors/rzb_saac/spp_rzb-saac.c, src/dynamic-preprocessors/sdf/spp_sdf.c, src/dynamic-preprocessors/sip/sip_dialog.c, src/dynamic-preprocessors/sip/sip_parser.c, src/dynamic-preprocessors/sip/spp_sip.c, src/dynamic-preprocessors/smtp/spp_smtp.c, src/dynamic-preprocessors/ssh/spp_ssh.c, src/dynamic-preprocessors/ssl/spp_ssl.c, src/file-process/file_service.c, src/file-process/libs/file_config.c, src/output-plugins/spo_unified2.c, src/preprocessors/portscan.c, src/preprocessors/snort_httpinspect.c, src/preprocessors/spp_arpspoof.c, src/preprocessors/spp_bo.c, src/preprocessors/spp_frag3.c, src/preprocessors/spp_httpinspect.c, src/preprocessors/spp_perfmonitor.c, src/preprocessors/spp_rpc_decode.c, src/preprocessors/spp_sfportscan.c, src/preprocessors/spp_stream5.c, src/preprocessors/stream_api.h, src/preprocessors/HttpInspect/client/hi_client.c, src/preprocessors/HttpInspect/normalization/hi_norm.c, src/preprocessors/Stream5/snort_stream5_tcp.c, src/preprocessors/Stream5/snort_stream5_udp.c, src/preprocessors/Stream5/stream5_common.h, src/sfutil/sf_iph.c, src/sfutil/sf_iph.h, src/sfutil/test/unit_hacks.c: Performance improvements and other refactorings. Notable changes include: improved HTTP buffer implementation and replaced run-time packet checks with assertions. * src/preprocessors/Stream5/snort_stream5_tcp.c: Ensure proper counting of sessions initializing. * doc/Makefile.am, doc/faq.pdf, doc/faq.tex: Remove Snort FAQ from source package since its now live on the web. * src/preprocessors/: spp_stream5.c, stream_expect.c, stream_expect.h: Add a memcap to expected session tracking. * src/sfutil/sfrt_flat.c: Check for memory allocation failure in both IPV4 and IPV6 tables. * src/control/sfcontrol.c: Do not timeout during shutdown and fix stop processing code in the control socket thread. Add the thread to the list before creation of the thread to prevent a race condition. 2013-06-04 Steven Sturges Snort 2.9.5 * src/: snort.c, preprocessors/spp_stream5.c: when block rules fire during shutdown, log them as alert instead of drop * src/: active.c, active.h, preprocessors/Stream5/snort_stream5_session.c: don't allow blocks or actions from pruned sessions (unrelated to current packet) * src/preprocessors/Stream5/snort_stream5_tcp.c: don't generate 129:1 in syn-sent * src/preprocessors/Stream5/: snort_stream5_tcp.c, snort_stream5_udp.c, stream5_common.h: don't apply window or mss on midstream pickups remove unused flags eliminate read-mode check when determining window * src/preprocessors/Stream5/snort_stream5_tcp.c: don't reassemble on the tracked whitelisted flows fix sequence number validation on ack to zero window syn+ack fix timestamp tracking to use window base instead of next expected * src/preprocessors/spp_stream5.c: when stream5 disables inspection, ensure non-content rules are not run * src/dynamic-preprocessors/dcerpc2/dce2_smb.c: When removing a pipe tracker, NULL out static request tracker's pipe tracker for pipe tracker that was dynamically allocated. * src/file-process/libs/file_identifier.c: Update some comments and avoid adding the same file magic * src/preprocessors/: spp_stream5.c, stream_api.h, Stream5/snort_stream5_tcp.c: swap client/server on midstream pickup if we identify server by service using client port * src/file-process/libs/file_identifier.c: Remove the code that parent file type might overwrite child file type. * preproc_rules/preprocessor.rules, src/generators.h, src/preprocessors/HttpInspect/event_output/hi_eo_log.c, src/preprocessors/HttpInspect/include/hi_eo_events.h, src/preprocessors/HttpInspect/utils/hi_paf.c, src/preprocessors/Stream5/snort_stream5_tcp.c: HTTP PAF abort improvements * doc/: README.frag3, snort_manual.pdf, snort_manual.tex: Added config event_trace description to Snort manual. Removed commas from Frag3 example configurations, thanks to Nicholas Horton for mentioning this. * src/: dynamic-preprocessors/reputation/reputation_config.c, sfutil/sfrt_flat.c, sfutil/sfrt_flat.h, sfutil/sfrt_flat_dir.c: Copy reputation info from another list when a duplicate address is inserted. * src/dynamic-preprocessors/smtp/snort_smtp.c: Fix issue when SMTP BDAT command specifies 0 length. * src/dynamic-preprocessors/reputation/shmem/shmem_datamgmt.c: Don't sort the manifest file. * src/: snort.h, util.c: Fix FatalError to actually exit when initializing in the failopen thread. * src/dynamic-preprocessors/reputation/reputation_config.c: Update to use more accurate ip list file parsing and validation. * src/: active.h, snort.c, dynamic-plugins/sf_dynamic_plugins.c, preprocessors/spp_stream5.c, preprocessors/stream_api.h, preprocessors/Stream5/snort_stream5_tcp.c: ensure that force blocks persist * src/dynamic-preprocessors/reputation/shmem/: shmem_config.c, shmem_config.h, shmem_datamgmt.c, shmem_datamgmt.h, shmem_mgmt.c: Refactor/cleanup of shared memory, data management logic. * src/: dynamic-examples/dynamic-rule/detection_lib_meta.h, dynamic-plugins/sf_dynamic_meta.h, dynamic-plugins/sf_engine/sf_snort_detection_engine.c, preprocessors/spp_stream5.c, preprocessors/stream_api.h: Add a stream API function to populate a session key given a packet. Also, export REQ_ENGINE_LIB_MAJOR and REQ_ENGINE_LIB_MINOR from snort * src/preprocessors/Stream5/snort_stream5_tcp.c: allow stream5 to track whitelisted sessions * src/: snort.c, dynamic-preprocessors/dnp3/spp_dnp3.c, preprocessors/Stream5/snort_stream5_tcp.c, preprocessors/Stream5/stream5_paf.c, sfutil/sfPolicy.c, sfutil/sfPolicy.h: disable config by vlan or net selection if -DPOLICY_BY_ID_ONLY * src/: snort.c, snort.h, dynamic-preprocessors/smtp/spp_smtp.c, preprocessors/Stream5/stream5_ha.c, preprocessors/Stream5/stream5_ha.h, win32/WIN32-Code/misc.c, win32/WIN32-Includes/config.h, win32/WIN32-Prj/snort.dsp: don't compile pcap reload for Win, add function for ffs() which is not defined in windows. * src/preprocessors/snort_httpinspect.c: Support large file processing in post raw data (not in MIME format) * src/: decode.c, decode.h, fpcreate.c, fpdetect.c, parser.c, parser.h, plugbase.c, plugbase.h, rate_filter.c, rate_filter.h, sfthreshold.c, sfthreshold.h, snort.c, snort.h, spo_plugbase.h, util.c, util.h, control/sfcontrol.c, control/sfcontrol.h, detection-plugins/detection_options.c, detection-plugins/detection_options.h, detection-plugins/sp_asn1.c, detection-plugins/sp_base64_data.c, detection-plugins/sp_base64_decode.c, detection-plugins/sp_byte_check.c, detection-plugins/sp_byte_extract.c, detection-plugins/sp_byte_jump.c, detection-plugins/sp_clientserver.c, detection-plugins/sp_cvs.c, detection-plugins/sp_dsize_check.c, detection-plugins/sp_file_data.c, detection-plugins/sp_flowbits.c, detection-plugins/sp_ftpbounce.c, detection-plugins/sp_icmp_code_check.c, detection-plugins/sp_icmp_id_check.c, detection-plugins/sp_icmp_seq_check.c, detection-plugins/sp_icmp_type_check.c, detection-plugins/sp_ip_fragbits.c, detection-plugins/sp_ip_id_check.c, detection-plugins/sp_ip_proto.c, detection-plugins/sp_ip_same_check.c, detection-plugins/sp_ip_tos_check.c, detection-plugins/sp_ipoption_check.c, detection-plugins/sp_isdataat.c, detection-plugins/sp_pattern_match.c, detection-plugins/sp_pattern_match.h, detection-plugins/sp_pcre.c, detection-plugins/sp_pcre.h, detection-plugins/sp_pkt_data.c, detection-plugins/sp_react.c, detection-plugins/sp_replace.c, detection-plugins/sp_replace.h, detection-plugins/sp_respond3.c, detection-plugins/sp_rpc_check.c, detection-plugins/sp_session.c, detection-plugins/sp_tcp_ack_check.c, detection-plugins/sp_tcp_flag_check.c, detection-plugins/sp_tcp_seq_check.c, detection-plugins/sp_tcp_win_check.c, detection-plugins/sp_ttl_check.c, detection-plugins/sp_urilen_check.c, dynamic-examples/dynamic-preprocessor/sf_preproc_info.h, dynamic-examples/dynamic-preprocessor/spp_example.c, dynamic-examples/dynamic-rule/detection_lib_meta.h, dynamic-output/libs/output_lib.c, dynamic-output/plugins/output_api.h, dynamic-output/plugins/output_common.h, dynamic-output/plugins/output_lib.h, dynamic-output/plugins/output_plugin.c, dynamic-plugins/sf_convert_dynamic.c, dynamic-plugins/sf_convert_dynamic.h, dynamic-plugins/sf_dynamic_detection.h, dynamic-plugins/sf_dynamic_engine.h, dynamic-plugins/sf_dynamic_plugins.c, dynamic-plugins/sf_dynamic_preprocessor.h, dynamic-plugins/sp_dynamic.c, dynamic-plugins/sp_dynamic.h, dynamic-plugins/sp_preprocopt.c, dynamic-plugins/sp_preprocopt.h, dynamic-plugins/sf_engine/sf_snort_detection_engine.c, dynamic-plugins/sf_engine/sf_snort_detection_engine.h, dynamic-plugins/sf_engine/sf_snort_plugin_api.h, dynamic-plugins/sf_engine/sf_snort_plugin_loop.c, dynamic-plugins/sf_engine/sf_snort_plugin_pcre.c, dynamic-plugins/sf_engine/examples/sfsnort_dynamic_detection_lib.c, dynamic-plugins/sf_preproc_example/sf_preproc_info.h, dynamic-preprocessors/dcerpc2/dce2_config.c, dynamic-preprocessors/dcerpc2/dce2_config.h, dynamic-preprocessors/dcerpc2/dce2_paf.c, dynamic-preprocessors/dcerpc2/dce2_paf.h, dynamic-preprocessors/dcerpc2/dce2_roptions.c, dynamic-preprocessors/dcerpc2/dce2_roptions.h, dynamic-preprocessors/dcerpc2/snort_dce2.c, dynamic-preprocessors/dcerpc2/spp_dce2.c, dynamic-preprocessors/dnp3/dnp3_paf.c, dynamic-preprocessors/dnp3/dnp3_paf.h, dynamic-preprocessors/dnp3/dnp3_roptions.c, dynamic-preprocessors/dnp3/dnp3_roptions.h, dynamic-preprocessors/dnp3/spp_dnp3.c, dynamic-preprocessors/dns/spp_dns.c, dynamic-preprocessors/ftptelnet/ftpp_ui_server_lookup.c, dynamic-preprocessors/ftptelnet/ftpp_ui_server_lookup.h, dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, dynamic-preprocessors/ftptelnet/snort_ftptelnet.h, dynamic-preprocessors/ftptelnet/spp_ftptelnet.c, dynamic-preprocessors/gtp/gtp_roptions.c, dynamic-preprocessors/gtp/gtp_roptions.h, dynamic-preprocessors/gtp/spp_gtp.c, dynamic-preprocessors/imap/imap_config.h, dynamic-preprocessors/imap/snort_imap.c, dynamic-preprocessors/imap/spp_imap.c, dynamic-preprocessors/modbus/modbus_paf.c, dynamic-preprocessors/modbus/modbus_paf.h, dynamic-preprocessors/modbus/modbus_roptions.c, dynamic-preprocessors/modbus/modbus_roptions.h, dynamic-preprocessors/modbus/spp_modbus.c, dynamic-preprocessors/pop/snort_pop.c, dynamic-preprocessors/pop/spp_pop.c, dynamic-preprocessors/reputation/reputation_config.c, dynamic-preprocessors/reputation/reputation_config.h, dynamic-preprocessors/reputation/spp_reputation.c, dynamic-preprocessors/reputation/shmem/shmem_common.h, dynamic-preprocessors/reputation/shmem/shmem_datamgmt.c, dynamic-preprocessors/reputation/shmem/shmem_datamgmt.h, dynamic-preprocessors/sdf/sdf_detection_option.c, dynamic-preprocessors/sdf/sdf_detection_option.h, dynamic-preprocessors/sdf/spp_sdf.c, dynamic-preprocessors/sdf/spp_sdf.h, dynamic-preprocessors/sip/sip_roptions.c, dynamic-preprocessors/sip/sip_roptions.h, dynamic-preprocessors/sip/spp_sip.c, dynamic-preprocessors/sip/spp_sip.h, dynamic-preprocessors/smtp/smtp_config.c, dynamic-preprocessors/smtp/snort_smtp.c, dynamic-preprocessors/smtp/spp_smtp.c, dynamic-preprocessors/ssh/spp_ssh.c, dynamic-preprocessors/ssl/spp_ssl.c, file-process/file_service.c, output-plugins/spo_alert_fast.c, output-plugins/spo_alert_full.c, output-plugins/spo_alert_sf_socket.c, output-plugins/spo_alert_syslog.c, output-plugins/spo_alert_test.c, output-plugins/spo_alert_unixsock.c, output-plugins/spo_csv.c, output-plugins/spo_log_ascii.c, output-plugins/spo_log_null.c, output-plugins/spo_log_tcpdump.c, output-plugins/spo_unified2.c, parser/IpAddrSet.c, parser/IpAddrSet.h, preprocessors/portscan.c, preprocessors/portscan.h, preprocessors/spp_arpspoof.c, preprocessors/spp_bo.c, preprocessors/spp_frag3.c, preprocessors/spp_httpinspect.c, preprocessors/spp_normalize.c, preprocessors/spp_perfmonitor.c, preprocessors/spp_rpc_decode.c, preprocessors/spp_sfportscan.c, preprocessors/spp_stream5.c, preprocessors/stream_api.h, preprocessors/HttpInspect/include/hi_paf.h, preprocessors/HttpInspect/include/hi_ui_server_lookup.h, preprocessors/HttpInspect/user_interface/hi_ui_server_lookup.c, preprocessors/HttpInspect/utils/hi_paf.c, preprocessors/Stream5/snort_stream5_session.h, preprocessors/Stream5/snort_stream5_tcp.c, preprocessors/Stream5/snort_stream5_tcp.h, preprocessors/Stream5/snort_stream5_udp.c, preprocessors/Stream5/snort_stream5_udp.h, preprocessors/Stream5/stream5_common.c, preprocessors/Stream5/stream5_common.h, preprocessors/Stream5/stream5_ha.c, preprocessors/Stream5/stream5_ha.h, preprocessors/Stream5/stream5_paf.c, preprocessors/Stream5/stream5_paf.h, sfutil/Makefile.am, sfutil/acsmx.c, sfutil/acsmx.h, sfutil/acsmx2.c, sfutil/acsmx2.h, sfutil/bnfa_search.c, sfutil/bnfa_search.h, sfutil/intel-soft-cpm.c, sfutil/intel-soft-cpm.h, sfutil/mpse.c, sfutil/mpse.h, sfutil/sfPolicy.c, sfutil/sfPolicy.h, sfutil/sfPolicyData.h, sfutil/sfPolicyUserData.c, sfutil/sfPolicyUserData.h, sfutil/sfksearch.c, sfutil/sfksearch.h, sfutil/sfrf.c, sfutil/sfrf.h, sfutil/sfrt.c, sfutil/sfrt.h, sfutil/sfthd.c, sfutil/sfthd.h, sfutil/test/sfrf_test.c, sfutil/test/sfthd_test.c, sfutil/test/unit_hacks.c, sfutil/test/unit_hacks.h, target-based/sftarget_reader.c, target-based/sftarget_reader.h: Add a control channel command that reloads the snort configuration. If a restart is needed, the command will return an error and the new configuration will be freed. Using this can replace the HUP signal, which does not have a means of feedback to the user. * preproc_rules/preprocessor.rules, src/generators.h, src/dynamic-preprocessors/imap/imap_log.c, src/dynamic-preprocessors/imap/imap_log.h, src/dynamic-preprocessors/pop/pop_log.c, src/dynamic-preprocessors/pop/pop_log.h, src/dynamic-preprocessors/smtp/smtp_log.c, src/dynamic-preprocessors/smtp/smtp_log.h, doc/README.imap, doc/README.pop: Removed the decoding failure alert for bitencoded/non-encoded attachments since it was invalid as we don't decoded these attachments. * src/preprocessors/spp_frag3.c: Continue to track fragments if rebuilt packet caused a drop. * src/preprocessors/Stream5/snort_stream5_tcp.c: Fixed POST_SESSION_CLEANUP() macro to not log messages when Stream5 is configured with "prune_log_max 0". Thanks to Gregory S Thomas for pointing out the issue. * src/preprocessors/Stream5/snort_stream5_tcp.c: Skip MAC address verification on packets being routed by a DAQ Module. * src/: decode.c, parser.c: Disallow rule-type decode rules with a sid that exceed DECODE_INDEX_MAX. * src/decode.c: Fixed MPLS header length check. Credits to Jacob Baines for the find. * src/fpdetect.c: When decoding Teredo and the inner IPv6 doesn't have any payload, reset do_detect_content to ensure content matches are checked when evaluating rules against the outer IPv4 'payload'. Thanks to Yun Zheng Hu & L0rd Ch0de1m0rt for reporting the issue & crafting traffic to reproduce. * doc/snort_manual.tex: Add reference 'msb' to the list of valid ones in the Snort manual. * src/preprocessors/Stream5/snort_stream5_tcp.c: flush and free application data on receipt of TCP RST in the close-wait state * src/: snort.c, preprocessors/spp_stream5.c, preprocessors/stream_api.h, preprocessors/stream_expect.c, preprocessors/Stream5/snort_stream5_icmp.c, preprocessors/Stream5/snort_stream5_ip.c, preprocessors/Stream5/snort_stream5_session.c, preprocessors/Stream5/snort_stream5_tcp.c, preprocessors/Stream5/snort_stream5_tcp.h, preprocessors/Stream5/snort_stream5_udp.c, preprocessors/Stream5/snort_stream5_udp.h, preprocessors/Stream5/stream5_common.c, preprocessors/Stream5/stream5_common.h, preprocessors/Stream5/stream5_ha.c, preprocessors/Stream5/stream5_ha.h, side-channel/Makefile.am, side-channel/dmq.c, side-channel/dmq.h, side-channel/rbmq.c, side-channel/rbmq.h, side-channel/sidechannel.c, side-channel/sidechannel_define.h, configure.in: Add the ability to share basic session state for Stream via a side channel * src/: fpdetect.c, parser.c, snort.c, snort.h, util.c, dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, dynamic-preprocessors/ftptelnet/snort_ftptelnet.h, dynamic-preprocessors/ftptelnet/spp_ftptelnet.c, preprocessors/Stream5/snort_stream5_tcp.c, preprocessors/Stream5/stream5_paf.c: Improve some processing performance for small packets * src/preprocessors/Stream5/snort_stream5_tcp.c: fix alerts on packets with same src/dst ports fix prior alert tracking to prevent redundant alerts fix missing u2 packets. * src/dynamic-preprocessors/smtp/snort_smtp.c: Copy remaining data to normalization buffer if already normalizing and in AUTH state. * src/ppm.c: Apply event filter support for PPM rules. * src/: preprocessors/snort_httpinspect.c, dynamic-preprocessors/dcerpc2/snort_dce2.c, dynamic-plugins/sf_engine/sf_snort_packet.h, detection-plugins/detection_options.c, detection-plugins/detection_options.h, decode.h, detection_util.c, encode.c, encode.h, fpdetect.c: update the packet number check in detection to include the rebuilt packet count. * doc/snort_manual.tex: Update description for rawbytes rule option * src/sfutil/sfrt_flat.c: correct return value for memory allocation failures * src/: file-process/file_mime_process.c, dynamic-preprocessors/imap/snort_imap.c, dynamic-preprocessors/pop/snort_pop.c, dynamic-preprocessors/smtp/snort_smtp.c: Check log_state in case of allocation failure * src/: file-process/file_mime_process.c, dynamic-preprocessors/imap/snort_imap.c, dynamic-preprocessors/smtp/snort_smtp.c, dynamic-preprocessors/pop/snort_pop.c: Processing each mime attachment after the boundary is found. * doc/README.http_inspect, doc/faq.pdf, doc/snort_manual.pdf, etc/gen-msg.map, preproc_rules/preprocessor.rules, src/generators.h, src/dynamic-preprocessors/dcerpc2/dce2_config.c, src/preprocessors/spp_stream5.c, src/preprocessors/HttpInspect/event_output/hi_eo_log.c, src/preprocessors/HttpInspect/include/hi_eo_events.h, src/preprocessors/HttpInspect/utils/hi_paf.c, src/preprocessors/Stream5/snort_stream5_tcp.c: Correct handling of head responses Flush extra line feeds with following PDUs (skipped over by http_inspect) add profiling for PAF Make PAF debug output more readable * src/: detect.c, detect.h, generators.h, snort.c, snort.h, util.c, output-plugins/spo_log_tcpdump.c, preprocessors/perf-base.c, preprocessors/perf-base.h: Add a new column for total_alert_pkts to permonitor stats. * src/preprocessors/: perf-base.c, perf.c: Fix insolent file handling in perfmonitor. * src/sfutil/sf_vartable.c: Free allocation on failure. * src/sfutil/sf_ipvar.c: Refactor sfip_node_t list freeing; Free sfip_node_t list on allocation failure. * snort.8: Update snort.8 * src/: dynamic-preprocessors/ftptelnet/hi_util_kmap.c, dynamic-preprocessors/ftptelnet/pp_ftp.c, dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, preprocessors/HttpInspect/utils/hi_util_kmap.c: Check for NULL parameter pointer before copying into file name. Alloc key node after checking for zero length. Remove unnecessary curr_ch NULL check. * src/control/sfcontrol.c: Fix error checks for CS_TYPE_MAX to be greater than or equal to. * src/dynamic-preprocessors/dcerpc2/: dce2_smb.c, dce2_smb.h: Remove unneccessary NULL check of session pointer. Fix set SMB fingerprint functions to just set flag and not return anything. * src/dynamic-preprocessors/sdf/sdf_us_ssn.c: Closed file before returning on error. NULL terminated string gotten from fread() before passing to strtok_r. Checked return value of fseek(), ftell() and fread(). Added log messages for errors. * src/preprocessors/Stream5/snort_stream5_tcp.c: don't do PAF on midstream pickup sessions do midstream pickup on SYN/ACK when packet is within require_3whs grace period. * src/preprocessors/Stream5/snort_stream5_tcp.c: fix midstream pickup when server data is seen before client. Thanks to John Eure for reporting the issue. * src/preprocessors/perf-flow.c: Don't skip logging of flows with 0 packet count for flow-ip tracking. * src/preprocessors/Stream5/snort_stream5_tcp.c: fix multi-pdu per segment flushing * src/preprocessors/snort_httpinspect.c: check http session tracker for file upload processing * src/: encode.c, preprocessors/snort_httpinspect.c, preprocessors/spp_frag3.c, preprocessors/Stream5/snort_stream5_tcp.c: Adjust stream reassembly for a few edge cases * src/preprocessors/snort_httpinspect.c: fix the parsing of max gzip mem * src/: snort.c, dynamic-output/plugins/output.h, dynamic-output/plugins/output_base.c: Print dynamic output modules with other plugins durring startup. * doc/snort_manual.pdf, etc/gen-msg.map, preproc_rules/decoder.rules, src/decode.c, src/decode.h, src/encode.c, src/generators.h, src/sf_protocols.h: Add decoding support for ERSpan type 2 and type 3 when ERSpan is inside GRE. * src/: snort.c, snort.h: Add --pcap-reload Snort flag to reload between pcap runs. * doc/README.daq, doc/faq.pdf, doc/snort_manual.pdf, doc/snort_manual.tex, src/decode.h, src/fpdetect.c, src/snort.c, src/dynamic-plugins/sf_engine/sf_snort_packet.h, src/dynamic-preprocessors/imap/snort_imap.c, src/dynamic-preprocessors/pop/snort_pop.c, src/dynamic-preprocessors/smtp/smtp_util.c, src/dynamic-preprocessors/smtp/snort_smtp.c, src/file-process/file_mime_process.c, src/output-plugins/spo_unified2.c, src/preprocessors/snort_httpinspect.c, src/preprocessors/snort_httpinspect.h, src/preprocessors/spp_stream5.c, src/preprocessors/stream_api.h, src/preprocessors/Stream5/snort_stream5_tcp.c, src/preprocessors/Stream5/snort_stream5_tcp.h: Ensure logging of extra data captured after alert * src/dynamic-preprocessors/reputation/shmem/shmem_mgmt.c: When a writer is in read mode, ensure the size is the shared memory segment size. * src/file-process/: libs/file_lib.c, file_service.c: Only display the file stats for types in the current configuration * src/: dynamic-preprocessors/ftptelnet/ftpp_si.h, preprocessors/spp_stream5.c, preprocessors/stream_api.h, preprocessors/Stream5/snort_stream5_session.c, control/sfcontrol.c: Add a stream api function to return the session key given a session pointer. Expose the SessionKey structure to dynamic preprocessors. For ICMP "sessions", include ICMP type as an element in the key, thereby making it a different "session" if the type varies. Echo replies are keyed the same as requests. * doc/snort_manual.pdf, doc/snort_manual.tex, src/parser.c, src/parser.h, src/snort.c, src/snort.h, doc/README.reload: Remove "config read_bin_file" documentation * src/: decode.c, decode.h, sfutil/sf_ip.h, sfutil/sf_iph.c, preprocessors/perf-base.c, dynamic-preprocessors/dcerpc2/snort_dce2.c, dynamic-plugins/sf_engine/sf_snort_packet.h, dynamic-preprocessors/sdf/spp_sdf.c: Update IP6RawHdr structure and fix version extraction for little endian machines. Reduce size of sfip_t by 4 bytes. * src/detection-plugins/sp_pattern_match.c: Error if relative rule option used after fast pattern only. * preproc_rules/decoder.rules, src/decode.c, src/generators.h: Add decoder alert for IPv6 Routing Type 0 headers. * src/encode.c: Replace usage of ScAdapterInlineMode() with DAQ_GetInterfaceMode(). * src/: rate_filter.h, dynamic-preprocessors/sdf/sdf_us_ssn.h, dynamic-preprocessors/sdf/spp_sdf.h, sfutil/sfrt_flat_dir.h: Cleanup recursive header inclusions. * src/decode.h: Fix macros for token ring header field extraction. * src/dynamic-preprocessors/sdf/sdf_us_ssn.c: Move SSN advertisement check before stricter validation. * doc/: README.dcerpc2, snort_manual.pdf, snort_manual.tex: Update dce_stub_data documentation. * src/parser.c: Cleanup function ValidateIPList(). * src/dynamic-output/plugins/output_base.c: Remove dead code path. * src/detection-plugins/sp_respond3.c: FatalError if Resp3_Parse() is called with bad parameters. * src/: snort_bounds.h, preprocessors/perf-base.c: Add error recovery to the perfstats logging code. * src/output-plugins/: spo_alert_fast.c, spo_alert_full.c: Add printing of GID:SID:Rev even if there is no msg in a rule. * src/dynamic-preprocessors/: smtp/spp_smtp.c, pop/spp_pop.c, imap/spp_imap.c: Initialize file depth to all the configurations, not just the default. * configure.in, src/decode.h, src/detection-plugins/sp_clientserver.c, src/dynamic-plugins/sf_engine/sf_snort_packet.h, src/dynamic-plugins/sf_engine/sf_snort_plugin_api.c, src/dynamic-preprocessors/dcerpc2/dce2_paf.c, src/dynamic-preprocessors/dcerpc2/dce2_paf.h, src/dynamic-preprocessors/dcerpc2/dce2_session.h, src/dynamic-preprocessors/dcerpc2/snort_dce2.c, src/dynamic-preprocessors/dcerpc2/spp_dce2.c, src/dynamic-preprocessors/dnp3/dnp3_paf.c, src/dynamic-preprocessors/dnp3/dnp3_paf.h, src/dynamic-preprocessors/dnp3/spp_dnp3.c, src/dynamic-preprocessors/ftptelnet/ftpp_si.c, src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.h, src/dynamic-preprocessors/ftptelnet/spp_ftptelnet.c, src/dynamic-preprocessors/modbus/modbus_paf.c, src/dynamic-preprocessors/modbus/modbus_paf.h, src/dynamic-preprocessors/modbus/spp_modbus.c, src/file-process/file_mime_process.c, src/preprocessors/snort_httpinspect.c, src/preprocessors/spp_httpinspect.c, src/preprocessors/spp_stream5.c, src/preprocessors/stream_api.h, src/preprocessors/HttpInspect/client/hi_client.c, src/preprocessors/HttpInspect/include/hi_paf.h, src/preprocessors/HttpInspect/mode_inspection/hi_mi.c, src/preprocessors/HttpInspect/server/hi_server.c, src/preprocessors/HttpInspect/utils/hi_paf.c, src/preprocessors/Stream5/snort_stream5_tcp.c, src/preprocessors/Stream5/snort_stream5_tcp.h, src/preprocessors/Stream5/stream5_paf.c, src/preprocessors/Stream5/stream5_paf.h: Add support for PAF activation by service and hardened PAF (removed --disable-paf from configure.in) * etc/gen-msg.map, src/decode.c, src/decode.h, src/generators.h, preproc_rules/decoder.rules: Support decoding of ICMPv6 Node Info Query and Node Info Response. Added decoder event for invalid codes therein. * src/preprocessors/: HttpInspect/mode_inspection/hi_mi.c, HttpInspect/client/hi_client.c, HttpInspect/include/hi_client.h, snort_httpinspect.h: Log XFF data on raw packet when reassembly is turned off. * src/dynamic-preprocessors/dcerpc2/dce2_smb.c: Refactor dead code path in DCE2_SmbTransactionGetName(). * src/dynamic-preprocessors/ftptelnet/ftpp_ui_client_lookup.c: Factor out dead code path in ftpp_ui_client_lookup_add(). * src/preprocessors/spp_bo.c: Remove redundant dereferences to array pointer. * src/sfutil/sfrf.c: Factor out dead code path in SFRF_ConfigAdd(). * src/preprocessors/Stream5/snort_stream5_tcp.c: Factor out dead code path in Stream5ProcessTcp(). * src/fpcreate.c: Factor out dead code path in fpCreatePortObject2PortGroup(). * src/dynamic-preprocessors/dcerpc2/dce2_roptions.c, src/dynamic-preprocessors/dcerpc2/dce2_config.c: Factor out dead code paths in DCE2 Preproc. * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.c: Factor out dead code paths in SetCursorInternal(). * src/dynamic-preprocessors/sip/: sip_roptions.c, spp_sip.c, spp_sip.h: add user defined SIP method to parsing policy instead of running policy * src/preprocessors/HttpInspect/include/hi_eo_events.h, src/preprocessors/HttpInspect/event_output/hi_eo_log.c, etc/gen-msg.map, src/generators.h, preproc_rules/preprocessor.rules, src/preprocessors/HttpInspect/client/hi_client.c: Add preprocessor alert when snort sees unescaped space within the URI Log IPs followed by portnum from the XFF header * src/preprocessors/Stream5/snort_stream5_tcp.c: Remove unnecessary check for NULL on array type. * src/preprocessors/spp_frag3.c: Remove unnecessary check for NULL on array type. * src/snort.c: Remove unnecessary check for NULL on array type. * tools/u2boat/u2boat.c: Make sure ConvertRecord func pointer is valid before called. * src/detection-plugins/sp_byte_extract.c: Fix value check for byte extract "multiplier" arg. * src/: util.c, util.h: Remove dead functions from util.c * tools/u2spewfoo/u2spewfoo.c: Check for error and prevent leaks with realloc in u2spewfoo. Thanks to William Parker for reporting it. * src/: parser.c, dynamic-plugins/sf_dynamic_plugins.c, dynamic-preprocessors/dcerpc2/dce2_config.c, dynamic-preprocessors/dns/spp_dns.c: Fix dead code paths * src/preprocessors/Stream5/snort_stream5_tcp.c: Reset overlap count when 129:7 is triggered to avoid repeated false positives * src/dynamic-preprocessors/smtp/: snort_smtp.c, snort_smtp.h: Handle 535 response codes - authentication failed. * doc/README.SMTP, doc/snort_manual.tex, src/dynamic-preprocessors/smtp/smtp_config.c, src/dynamic-preprocessors/smtp/smtp_config.h, src/dynamic-preprocessors/smtp/snort_smtp.c, src/dynamic-preprocessors/smtp/snort_smtp.h: Added new configuration options "data_cmds", "binary_data_cmds" and "auth_cmds" to the smtp preprocessor. * doc/README.reload, doc/snort_manual.tex, src/snort.c, src/preprocessors/perf-base.c, src/preprocessors/perf-base.h, src/preprocessors/perf-flow.c, src/preprocessors/perf-flow.h, src/preprocessors/perf.c, src/preprocessors/perf.h, src/preprocessors/spp_perfmonitor.c, src/preprocessors/Stream5/snort_stream5_tcp.c: Added "flow-file" configuration option and optional arguments to "atexitonly" for perfmonitor preprocessor. * src/: detection-plugins/sp_pattern_match.c, dynamic-plugins/sf_engine/sf_snort_plugin_content.c, Adjust detection option pointer and distance for content matches with negative distances that put pointer before start of buffer. * src/preprocessors/HttpInspect/session_inspection/hi_si.c: Ensure all request and response fields are reset * src/generators.h, preproc_rules/preprocessor.rules, src/preprocessors/spp_frag3.c: Remove dead preprocessor alerts from Frag3, GIDs 123:9, 123:10 that are covered by 116:458. * src/: dynamic-preprocessors/ftptelnet/ftpp_si.c, dynamic-preprocessors/ftptelnet/ftpp_si.h, dynamic-preprocessors/ftptelnet/pp_ftp.c, dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, dynamic-preprocessors/ftptelnet/snort_ftptelnet.h, dynamic-preprocessors/ftptelnet/spp_ftptelnet.c, preprocessors/stream_api.h, preprocessors/Stream5/snort_stream5_tcp.c: Set reassembly on ftp-data for file processing and file_data ptr for ftp-data channel. * src/: decode.c, decode.h, encode.c, sf_protocols.h, snort.c: Whitelist encrypted ESP tunnels if decoding ESP traffic. * src/detection-plugins/sp_react.c: Fix issue where react action was lost when Snort reloads. * src/dynamic-preprocessors/: imap/snort_imap.c, imap/spp_imap.c, smtp/snort_smtp.c, smtp/spp_smtp.c, pop/snort_pop.c, pop/spp_pop.c: Enforce target based config setting for file processing. * src/file-process/file_mime_process.c: Make sure signature context is created at any file position. * src/dynamic-preprocessors/: pop/snort_pop.c, pop/snort_pop.h, smtp/snort_smtp.c, smtp/snort_smtp.h: Using boundary to check end of file * src/: decode.h, dynamic-plugins/sf_engine/sf_snort_packet.h, output-plugins/spo_unified2.c, preprocessors/spp_sfportscan.c: Update portscan unified2 events to log type of portscan in protocol field instead of 0xFF. * doc/: README.asn1, snort_manual.pdf, snort_manual.tex: Update asn1 rule option documentation to remove reference to byte_test updating relative pointer. Thanks to Brandon Castel for bringing this to our attention. * src/: file-process/file_mime_process.c, file-process/file_mime_process.h, preprocessors/HttpInspect/client/hi_client.c, file-process/Makefile.am, file-process/file_api.h, file-process/file_mime_config.c, file-process/file_mime_config.h, file-process/file_resume_block.c, file-process/file_resume_block.h, file-process/file_service.c, file-process/file_service.h, file-process/file_service_config.c, preprocessors/snort_httpinspect.c, preprocessors/snort_httpinspect.h, preprocessors/spp_httpinspect.c, preprocessors/HttpInspect/include/hi_client.h, preprocessors/HttpInspect/include/hi_ui_config.h, dynamic-preprocessors/imap/spp_imap.c, file-process/libs/file_config.c, file-process/libs/file_config.h, sfutil/sf_email_attach_decode.c, snort.c: Add support for http file upload. * doc/: PROBLEMS, README.WIN32, README.daq, faq.tex, snort_manual.tex: Update READMEs and FAQ and Snort Manual to standardize the format of references to libpcap. Also update location of winpcap. Thanks to Joshua Kinard and Bryan Jones for pointing out the discrepancies. * src/preprocessors/spp_sfportscan.c: Fix portscan to only prep a pseudo-packet if actually generating an alert * src/file-process/: file_api.h, file_service.c: Add packet to file api calls to determine if the session is inline. * src/dynamic-preprocessors/sip/sip_config.c: Fatal error during SIP preprocessor configuration if a standard or user defined method cannot be allocated. * src/: file-process/file_resume_block.c, file-process/file_service.c, file-process/file_service.h, snort.c: Move file resume cache clean to restart or snort exit * src/file-process/: file_api.h, file_resume_block.c: File API change to support logging file resume blocking. * src/: preprocessors/Stream5/snort_stream5_tcp.c, file-process/Makefile.am, file-process/file_api.h, file-process/file_mime_process.c, file-process/file_mime_process.h, file-process/file_resume_block.c, file-process/file_resume_block.h, file-process/file_service.c, file-process/file_service_config.c, dynamic-preprocessors/pop/pop_config.c, dynamic-preprocessors/pop/pop_config.h, dynamic-preprocessors/pop/snort_pop.c, dynamic-preprocessors/pop/snort_pop.h, dynamic-preprocessors/pop/spp_pop.c, dynamic-preprocessors/smtp/smtp_config.c, dynamic-preprocessors/smtp/smtp_config.h, dynamic-preprocessors/smtp/smtp_util.c, dynamic-preprocessors/smtp/smtp_util.h, dynamic-preprocessors/smtp/snort_smtp.c, dynamic-preprocessors/smtp/snort_smtp.h, dynamic-preprocessors/smtp/spp_smtp.c, dynamic-preprocessors/imap/imap_config.c, dynamic-preprocessors/imap/imap_config.h, dynamic-preprocessors/imap/snort_imap.c, dynamic-preprocessors/imap/snort_imap.h, dynamic-preprocessors/imap/spp_imap.c, util.c, util.h, file-process/libs/file_config.c, file-process/libs/file_config.h, file-process/libs/file_lib.h, dynamic-plugins/sf_dynamic_plugins.c, dynamic-plugins/sf_dynamic_preprocessor.h: File blocking, http resume blocking, file statistics, and file name support for pop, imap. * src/output-plugins/spo_alert_unixsock.c: Update to use memset and memmove instead of bzero/bcopy. Thanks to Bill Parker for the suggestion. * doc/: README.dcerpc2, snort_manual.pdf, snort_manual.tex: Update dcerpc2 preprocessor documentation to remove -1 as a default and valid value to max_frag_len. * src/preprocessors/spp_perfmonitor.c: Make sure perfmonitor evaluation function is added to each policy's preprocessor evaluation list. * configure.in, doc/INSTALL, doc/README.reputation, doc/snort_manual.pdf, doc/snort_manual.tex, src/fpcreate.c, src/fpcreate.h, src/parser.c, src/parser.h, src/rule_option_types.h, src/snort.c, src/snort.h, src/detection-plugins/detection_options.c, src/dynamic-examples/Makefile.am, src/dynamic-output/Makefile.am, src/dynamic-output/libs/Makefile.am, src/dynamic-plugins/sf_convert_dynamic.c, src/dynamic-plugins/sf_dynamic_plugins.c, src/dynamic-plugins/sp_dynamic.c, src/dynamic-plugins/sp_preprocopt.c, src/dynamic-preprocessors/Makefile.am, src/dynamic-preprocessors/dcerpc2/sf_dce2.dsp, src/dynamic-preprocessors/dnp3/sf_dnp3.dsp, src/dynamic-preprocessors/dns/sf_dns.dsp, src/dynamic-preprocessors/ftptelnet/sf_ftptelnet.dsp, src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, src/dynamic-preprocessors/gtp/sf_gtp.dsp, src/dynamic-preprocessors/imap/sf_imap.dsp, src/dynamic-preprocessors/isakmp/sf_isakmp.dsp, src/dynamic-preprocessors/libs/Makefile.am, src/dynamic-preprocessors/libs/sfdynamic_preproc_libs.dsp, src/dynamic-preprocessors/modbus/sf_modbus.dsp, src/dynamic-preprocessors/pop/sf_pop.dsp, src/dynamic-preprocessors/reputation/sf_reputation.dsp, src/dynamic-preprocessors/sdf/sf_sdf.dsp, src/dynamic-preprocessors/sip/sf_sip.dsp, src/dynamic-preprocessors/smtp/sf_smtp.dsp, src/dynamic-preprocessors/ssh/sf_ssh.dsp, src/dynamic-preprocessors/ssl/sf_ssl.dsp, src/preprocessors/spp_httpinspect.c, src/preprocessors/Stream5/snort_stream5_tcp.c, src/preprocessors/Stream5/stream5_common.c, src/win32/WIN32-Prj/sf_engine.dsp, src/win32/WIN32-Prj/sf_testdetect.dsp, src/win32/WIN32-Prj/snort.dsp: Removed --disable-dynamicplugin configure option and hardened dynamic plugin code. * src/: dynamic-plugins/sf_engine/sf_snort_packet.h, dynamic-preprocessors/ftptelnet/ftpp_si.c, dynamic-preprocessors/ftptelnet/ftpp_si.h, dynamic-preprocessors/ftptelnet/ftpp_ui_config.h, dynamic-preprocessors/ftptelnet/pp_ftp.c, dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, preprocessors/spp_stream5.c, preprocessors/stream_api.h, preprocessors/Stream5/snort_stream5_tcp.c: File processing for ftp-data channel. * src/dynamic-preprocessors/dcerpc2/: dce2_smb.c, dce2_smb.h: Remove NetBIOS session state. * src/: plugbase.c, output-plugins/Makefile.am, output-plugins/spo_unified.c, output-plugins/spo_unified.h: Remove deprecated unified support. Same functionality is supported with unified2. * src/dynamic-preprocessors/dcerpc2/dce2_smb.c: Correct setting FID in reassembled packets on big endian systems. * doc/INSTALL, doc/snort_manual.pdf, doc/snort_manual.tex, src/output-plugins/spo_alert_unixsock.c: Update alert_unixsock output plugin and documentation for use on FreeBSD. * src/: decode.c, decode.h: Add RFC 5925 (The TCP Authentication Option) option as a valid TCP option and tag RFC 2385 (Protection of BGP Sessions via the TCP MD5 Signature Option) option as obsolete. * rpm/snort.spec, doc/snort_manual.tex, src/win32/WIN32-Prj/snort_installer.nsi, src/win32/WIN32-Includes/config.h: Set version to 2.9.5 2013-04-18 Steven Sturges Snort 2.9.4.6 * src/build.h: updating build number to 73 * doc/README.counts, doc/snort_manual.pdf, doc/snort_manual.tex, src/decode.c, src/parser.c, src/snort.h: Added config tunnel_verdicts and tunnel bypass for whitelist and blacklist verdicts for 6in4 or 4in6 encapsulated traffic. * src/preprocessors/spp_frag3.c: Don't update IP options length and count in frag3 after allocating option buffer when receiving duplicate 0 offset fragments with IP options. 2013-03-20 Steven Sturges Snort 2.9.4.5 * src/build.h: updating build number to 71 * src/preprocessors/Stream5/snort_stream5_tcp.c: prevent pruning when dup'ing a seglist node to avoid broken flushed packets * src/detection-plugins/detection_options.c: recursively search patterns within the HTTP uri buffers until the buffer ends. * src/preprocessors/HttpInspect/: client/hi_client.c, client/hi_client_norm.c, include/hi_client.h: Remove proxy information from the normalized URI buffer. Thanks to L0rd Ch0de1m0rt for reporting the issue. * src/: control/sfcontrol.c, preprocessors/Stream5/snort_stream5_tcp.c: fix logging of unified2 packet data when alerting on a packet containing multiple HTTP PDUs 2013-02-19 Bhagyashree Bantwal Snort 2.9.4.1 * src/build.h: updating build number to 69 * src/preprocessors/Stream5/snort_stream5_tcp.c: Only check for TCP Window Slam on client packets. * src/: control/sfcontrol.c, control/sfcontrol.h, preprocessors/spp_stream5.c, preprocessors/stream_api.h, preprocessors/Stream5/snort_stream5_session.c, preprocessors/Stream5/stream5_common.h Add a stream API function to return a session key given a session. Expose the session key * src/target-based/sftarget_reader.c: Change routing table layout for ip6 attribute lookups to be more space efficient * src/preprocessors/spp_frag3.c: Forcibly drop excessive overlaps * src/preprocessors/spp_frag3.c: Propagate address_space_id from raw packet to frag3 rebuilt packet DAQ header * src/: encode.c, encode.h, preprocessors/Stream5/snort_stream5_tcp.c: Update packet encoding to propagate the address_space_id in DAQ header * configure.in, src/decode.c: Define NO_NON_ETHER_DECODER by default in Snort builds. Add --enable-non-ether-decoders as a configure flag. * src/dynamic-preprocessors/: pop/snort_pop.c, pop/snort_pop.h, smtp/snort_smtp.c, smtp/snort_smtp.h: Use MIME boundary for end of file indication even for the last file * src/dynamic-preprocessors/reputation/spp_reputation.c: only inspect ingress zone for passive interface. * doc/README.reputation: * src/dynamic-preprocessors/reputation/shmem/shmem_mgmt.c: When a writer is in read mode, the size should be the shared memory segment size. * src/: control/sfcontrol.c, control/sfcontrol.h, dynamic-preprocessors/reputation/spp_reputation.c: Only decode outer header in main control section. Payload is handled by the handler. * src/dynamic-preprocessors/reputation/: spp_reputation.c shmem/shmem_mgmt.c: update share memory for snort readers that are idle. * src/parser.c: make sure otn is different from original and and that option functions weren't already freed before freeing the dup list. * src/dynamic-preprocessors/: smtp/spp_smtp.c, imap/spp_imap.c, pop/spp_pop.c: Initialize file depth to all the policies, not just default policy * src/dynamic-preprocessors/: pop/spp_pop.c, smtp/snort_smtp.c, imap/spp_imap.c: check whether mime decoding is disabled before allocating memory. * doc/: snort_manual.pdf, snort_manual.tex: changed doc default to 10 max_attribute_services_per_host. * src/: parser.c, parser.h, snort.c, snort.h, preprocessors/spp_frag3.c, preprocessors/Stream5/snort_stream5_tcp.c, target-based/sftarget_hostentry.c, target-based/sftarget_reader.c, target-based/sftarget_reader.h: remove unused AttributeData and change attribute table to use uints instead of AttributeData to reduce host/service from 5208/5192 to 80/16 bytes respectively. Add config max_attribute_services_per_host to change from default of 10. Unused AttributeData includes operating system, vendor, and version for host and application and version for service. Note that the data is still parsed from hosts.xml but not actually stored in memory. Also tweak some stream5 debug code that threw warnings. * src/: file-process/file_service.c, preprocessors/snort_httpinspect.c: avoid processing partial HTTP content. * src/: encode.c, encode.h, preprocessors/Stream5/snort_stream5_tcp.c: Make sure daq supports zones and interfaces in the daq header. * src/: encode.c, encode.h, preprocessors/Stream5/snort_stream5_tcp.c: Maintain ingress and egress interfaces and zones and daq flags in the tcp session to be used to populate reassembled packets correctly. 2012-10-30 Steven Sturges Snort 2.9.4 * src/build.h: updating build number to 37 * doc/README.counts, doc/snort_manual.tex, doc/snort_manual.pdf, src/active.c, src/active.h, src/decode.c, src/parser.c, src/parser.h, src/snort.c, src/snort.h, src/util.c: added config tunnel_verdicts and tunnel bypass for whitelist and blacklist verdicts for gtp or teredo encapsulated traffic. * src/dynamic-preprocessors/smtp/: snort_smtp.c, snort_smtp.h: Handle MS Exchange X-EXPS and XEXCH50 commands in the SMTP preprocessor. 2012-10-16 Steven Sturges Snort 2.9.4 RC * src/build.h: updating build number to 35 * src/file-process/libs/: file_identifier.c, file_identifier.h Fixed one issue when inserting a file magic in between another file magic. In addition, avoid cloning nodes which are not used by other node. This improves memory assuage (from 10M down to 4M) * src/: detect.c, plugbase.c, plugbase.h, snort.c, snort.h, dynamic-plugins/sf_dynamic_plugins.c, dynamic-plugins/sf_dynamic_preprocessor.h Added 2 new dpd functions. One turns off detection, the other re-enables a given preprocessor. After the preprocessors are configured, the preprocessor list is filtered if detection is off. * src/active.c : allow TCP RST response to segments w/o data * src/dynamic-plugins/sf_engine/: sf_snort_detection_engine.c, sf_snort_plugin_api.c, sf_snort_plugin_api.h, sf_snort_plugin_byte.c, sf_snort_plugin_content.c, sf_snort_plugin_hdropts.c, sf_snort_plugin_pcre.c Changed logic of option evaluations for SO rules that use a custom evaluation function to match that of the SO rule builtin logic when the NOT_FLAG is used. * src/detection-plugins/: sp_flowbits.c, sp_flowbits.h Use appropriate interger types and comparisons. * src/preprocessors/HttpInspect/: client/hi_client.c, server/hi_server.c fix win32 warnings * src/: active.c, fpdetect.c, preprocessors/spp_stream5.c don't enable active response unless configured * src/: dynamic-plugins/sf_engine/sf_snort_packet.h, preprocessors/spp_stream5.c, file-process/file_service.c, decode.h avoid logging incorrect file name/file size when multiple files within one packet. * src/dynamic-preprocessors/dcerpc2/dce2_smb.c: Fix Win32 build warnings. 2012-09-20 Steven Sturges Snort 2.9.4 Beta * configure.in, doc/snort_manual.pdf, src/parser.c, src/parser.h, src/sfdaq.h, src/snort.h, src/dynamic-preprocessors/sip/sip_dialog.c, src/preprocessors/spp_frag3.c, src/preprocessors/spp_stream5.c, src/preprocessors/stream_api.h, src/preprocessors/Stream5/snort_stream5_session.c, src/preprocessors/Stream5/snort_stream5_session.h, src/preprocessors/Stream5/stream5_common.h: Add use of address_space_id in stream & frag hash keys when DAQ provides it. * src/: dynamic-preprocessors/imap/snort_imap.c, dynamic-preprocessors/pop/snort_pop.c, dynamic-preprocessors/sf_dynamic_initialize/sf_dynamic_initialize.dsp, dynamic-preprocessors/smtp/snort_smtp.c, preprocessors/snort_httpinspect.c, preprocessors/Stream5/snort_stream5_tcp.c, sfutil/sf_email_attach_decode.h, win32/WIN32-Prj/sf_testdetect.dsp, win32/WIN32-Prj/snort.dsp, win32/WIN32-Prj/snort.dsw: Fix a few Win32 warnings. * src/preprocessors/Stream5/snort_stream5_tcp.c ensure that the LWS policy matches that of the server (instead of the dest) * COPYING, LICENSE, contrib/snortpp.c, doc/README, src/active.h, src/byte_extract.c, src/byte_extract.h, src/checksum.h, src/cpuclock.h, src/debug.c, src/decode.h, src/detect.c, src/detect.h, src/detection_filter.c, src/detection_filter.h, src/detection_util.c, src/detection_util.h, src/encode.c, src/encode.h, src/event.h, src/event_queue.c, src/event_queue.h, src/event_wrapper.c, src/event_wrapper.h, src/fpcreate.c, src/fpcreate.h, src/fpdetect.c, src/fpdetect.h, src/generators.h, src/idle_processing.c, src/idle_processing.h, src/idle_processing_funcs.h, src/ipv6_port.h, src/log.c, src/log.h, src/log_text.c, src/log_text.h, src/mempool.c, src/mempool.h, src/mstring.c, src/mstring.h, src/obfuscation.c, src/obfuscation.h, src/packet_time.c, src/packet_time.h, src/parser.c, src/parser.h, src/pcap_pkthdr32.h, src/pcrm.c, src/pcrm.h, src/plugbase.c, src/plugbase.h, src/plugin_enum.h, src/ppm.c, src/ppm.h, src/preprocids.h, src/profiler.c, src/profiler.h, src/rate_filter.c, src/rate_filter.h, src/rule_option_types.h, src/rules.h, src/sf_protocols.h, src/sf_sdlist.c, src/sf_sdlist.h, src/sf_sdlist_types.h, src/sf_types.h, src/sfdaq.c, src/sfdaq.h, src/sfthreshold.c, src/sfthreshold.h, src/signature.c, src/signature.h, src/snort.c, src/snort.h, src/snort_bounds.h, src/snort_debug.h, src/snprintf.c, src/snprintf.h, src/spo_plugbase.h, src/strlcatu.h, src/strlcpyu.h, src/tag.c, src/tag.h, src/treenodes.h, src/util.c, src/util.h, src/control/sfcontrol.c, src/control/sfcontrol.h, src/control/sfcontrol_funcs.h, src/detection-plugins/detection_options.h, src/detection-plugins/sp_asn1.c, src/detection-plugins/sp_asn1.h, src/detection-plugins/sp_asn1_detect.c, src/detection-plugins/sp_asn1_detect.h, src/detection-plugins/sp_base64_data.c, src/detection-plugins/sp_base64_data.h, src/detection-plugins/sp_base64_decode.c, src/detection-plugins/sp_base64_decode.h, src/detection-plugins/sp_byte_check.h, src/detection-plugins/sp_byte_extract.h, src/detection-plugins/sp_byte_jump.h, src/detection-plugins/sp_clientserver.c, src/detection-plugins/sp_clientserver.h, src/detection-plugins/sp_cvs.c, src/detection-plugins/sp_cvs.h, src/detection-plugins/sp_dsize_check.c, src/detection-plugins/sp_dsize_check.h, src/detection-plugins/sp_file_data.c, src/detection-plugins/sp_file_data.h, src/detection-plugins/sp_flowbits.c, src/detection-plugins/sp_flowbits.h, src/detection-plugins/sp_ftpbounce.c, src/detection-plugins/sp_ftpbounce.h, src/detection-plugins/sp_hdr_opt_wrap.c, src/detection-plugins/sp_hdr_opt_wrap.h, src/detection-plugins/sp_icmp_code_check.c, src/detection-plugins/sp_icmp_code_check.h, src/detection-plugins/sp_icmp_id_check.c, src/detection-plugins/sp_icmp_id_check.h, src/detection-plugins/sp_icmp_seq_check.c, src/detection-plugins/sp_icmp_seq_check.h, src/detection-plugins/sp_icmp_type_check.c, src/detection-plugins/sp_icmp_type_check.h, src/detection-plugins/sp_ip_fragbits.c, src/detection-plugins/sp_ip_fragbits.h, src/detection-plugins/sp_ip_id_check.c, src/detection-plugins/sp_ip_id_check.h, src/detection-plugins/sp_ip_proto.c, src/detection-plugins/sp_ip_proto.h, src/detection-plugins/sp_ip_same_check.c, src/detection-plugins/sp_ip_same_check.h, src/detection-plugins/sp_ip_tos_check.c, src/detection-plugins/sp_ip_tos_check.h, src/detection-plugins/sp_ipoption_check.c, src/detection-plugins/sp_ipoption_check.h, src/detection-plugins/sp_isdataat.c, src/detection-plugins/sp_isdataat.h, src/detection-plugins/sp_pattern_match.c, src/detection-plugins/sp_pattern_match.h, src/detection-plugins/sp_pcre.h, src/detection-plugins/sp_pkt_data.c, src/detection-plugins/sp_pkt_data.h, src/detection-plugins/sp_react.c, src/detection-plugins/sp_react.h, src/detection-plugins/sp_replace.c, src/detection-plugins/sp_replace.h, src/detection-plugins/sp_respond.h, src/detection-plugins/sp_respond3.c, src/detection-plugins/sp_rpc_check.c, src/detection-plugins/sp_rpc_check.h, src/detection-plugins/sp_session.c, src/detection-plugins/sp_session.h, src/detection-plugins/sp_tcp_ack_check.c, src/detection-plugins/sp_tcp_ack_check.h, src/detection-plugins/sp_tcp_flag_check.c, src/detection-plugins/sp_tcp_flag_check.h, src/detection-plugins/sp_tcp_seq_check.c, src/detection-plugins/sp_tcp_seq_check.h, src/detection-plugins/sp_tcp_win_check.c, src/detection-plugins/sp_tcp_win_check.h, src/detection-plugins/sp_ttl_check.c, src/detection-plugins/sp_ttl_check.h, src/detection-plugins/sp_urilen_check.c, src/detection-plugins/sp_urilen_check.h, src/dynamic-examples/dynamic-preprocessor/sf_preproc_info.h, src/dynamic-examples/dynamic-preprocessor/spp_example.c, src/dynamic-examples/dynamic-rule/detection_lib_meta.h, src/dynamic-examples/dynamic-rule/rules.c, src/dynamic-examples/dynamic-rule/sid109.c, src/dynamic-examples/dynamic-rule/sid637.c, src/dynamic-output/libs/output_lib.c, src/dynamic-output/plugins/output.h, src/dynamic-output/plugins/output_api.h, src/dynamic-output/plugins/output_base.c, src/dynamic-output/plugins/output_common.h, src/dynamic-output/plugins/output_lib.h, src/dynamic-output/plugins/output_plugin.c, src/dynamic-plugins/sf_convert_dynamic.h, src/dynamic-plugins/sf_dynamic_common.h, src/dynamic-plugins/sf_dynamic_define.h, src/dynamic-plugins/sf_dynamic_detection.h, src/dynamic-plugins/sf_dynamic_engine.h, src/dynamic-plugins/sf_dynamic_meta.h, src/dynamic-plugins/sp_dynamic.h, src/dynamic-plugins/sp_preprocopt.h, src/dynamic-plugins/sf_engine/bmh.c, src/dynamic-plugins/sf_engine/bmh.h, src/dynamic-plugins/sf_engine/sf_decompression.c, src/dynamic-plugins/sf_engine/sf_decompression.h, src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c, src/dynamic-plugins/sf_engine/sf_snort_detection_engine.h, src/dynamic-plugins/sf_engine/sf_snort_packet.h, src/dynamic-plugins/sf_engine/sf_snort_plugin_api.c, src/dynamic-plugins/sf_engine/sf_snort_plugin_api.h, src/dynamic-plugins/sf_engine/sf_snort_plugin_byte.c, src/dynamic-plugins/sf_engine/sf_snort_plugin_content.c, src/dynamic-plugins/sf_engine/sf_snort_plugin_hdropts.c, src/dynamic-plugins/sf_engine/sf_snort_plugin_loop.c, src/dynamic-plugins/sf_engine/sf_snort_plugin_pcre.c, src/dynamic-plugins/sf_engine/sf_snort_plugin_rc4.c, src/dynamic-plugins/sf_engine/examples/sfsnort_dynamic_detection_lib.c, src/dynamic-plugins/sf_engine/examples/sfsnort_dynamic_detection_lib.h, src/dynamic-plugins/sf_preproc_example/sf_dynamic_preproc_lib.c, src/dynamic-plugins/sf_preproc_example/sf_dynamic_preproc_lib.h, src/dynamic-plugins/sf_preproc_example/sf_preproc_info.h, src/dynamic-plugins/sf_preproc_example/spp_nfs_setup.c, src/dynamic-plugins/sf_preproc_example/spp_nfs_setup.h, src/dynamic-preprocessors/dcerpc2/dce2_cl.c, src/dynamic-preprocessors/dcerpc2/dce2_cl.h, src/dynamic-preprocessors/dcerpc2/dce2_co.c, src/dynamic-preprocessors/dcerpc2/dce2_co.h, src/dynamic-preprocessors/dcerpc2/dce2_config.c, src/dynamic-preprocessors/dcerpc2/dce2_config.h, src/dynamic-preprocessors/dcerpc2/dce2_debug.c, src/dynamic-preprocessors/dcerpc2/dce2_debug.h, src/dynamic-preprocessors/dcerpc2/dce2_event.c, src/dynamic-preprocessors/dcerpc2/dce2_event.h, src/dynamic-preprocessors/dcerpc2/dce2_http.c, src/dynamic-preprocessors/dcerpc2/dce2_http.h, src/dynamic-preprocessors/dcerpc2/dce2_list.c, src/dynamic-preprocessors/dcerpc2/dce2_list.h, src/dynamic-preprocessors/dcerpc2/dce2_memory.c, src/dynamic-preprocessors/dcerpc2/dce2_memory.h, src/dynamic-preprocessors/dcerpc2/dce2_paf.c, src/dynamic-preprocessors/dcerpc2/dce2_paf.h, src/dynamic-preprocessors/dcerpc2/dce2_roptions.c, src/dynamic-preprocessors/dcerpc2/dce2_roptions.h, src/dynamic-preprocessors/dcerpc2/dce2_session.h, src/dynamic-preprocessors/dcerpc2/dce2_smb.h, src/dynamic-preprocessors/dcerpc2/dce2_stats.c, src/dynamic-preprocessors/dcerpc2/dce2_stats.h, src/dynamic-preprocessors/dcerpc2/dce2_tcp.c, src/dynamic-preprocessors/dcerpc2/dce2_tcp.h, src/dynamic-preprocessors/dcerpc2/dce2_udp.c, src/dynamic-preprocessors/dcerpc2/dce2_udp.h, src/dynamic-preprocessors/dcerpc2/dce2_utils.c, src/dynamic-preprocessors/dcerpc2/snort_dce2.c, src/dynamic-preprocessors/dcerpc2/snort_dce2.h, src/dynamic-preprocessors/dcerpc2/spp_dce2.c, src/dynamic-preprocessors/dcerpc2/spp_dce2.h, src/dynamic-preprocessors/dcerpc2/includes/dcerpc.h, src/dynamic-preprocessors/dcerpc2/includes/smb.h, src/dynamic-preprocessors/dnp3/dnp3_map.h, src/dynamic-preprocessors/dnp3/dnp3_paf.c, src/dynamic-preprocessors/dnp3/dnp3_paf.h, src/dynamic-preprocessors/dnp3/dnp3_reassembly.c, src/dynamic-preprocessors/dnp3/dnp3_reassembly.h, src/dynamic-preprocessors/dnp3/dnp3_roptions.c, src/dynamic-preprocessors/dnp3/dnp3_roptions.h, src/dynamic-preprocessors/dnp3/spp_dnp3.c, src/dynamic-preprocessors/dnp3/spp_dnp3.h, src/dynamic-preprocessors/dns/spp_dns.c, src/dynamic-preprocessors/dns/spp_dns.h, src/dynamic-preprocessors/ftptelnet/ftp_bounce_lookup.c, src/dynamic-preprocessors/ftptelnet/ftp_bounce_lookup.h, src/dynamic-preprocessors/ftptelnet/ftp_client.h, src/dynamic-preprocessors/ftptelnet/ftp_cmd_lookup.c, src/dynamic-preprocessors/ftptelnet/ftp_cmd_lookup.h, src/dynamic-preprocessors/ftptelnet/ftp_server.h, src/dynamic-preprocessors/ftptelnet/ftpp_eo.h, src/dynamic-preprocessors/ftptelnet/ftpp_eo_events.h, src/dynamic-preprocessors/ftptelnet/ftpp_eo_log.c, src/dynamic-preprocessors/ftptelnet/ftpp_eo_log.h, src/dynamic-preprocessors/ftptelnet/ftpp_include.h, src/dynamic-preprocessors/ftptelnet/ftpp_return_codes.h, src/dynamic-preprocessors/ftptelnet/ftpp_si.c, src/dynamic-preprocessors/ftptelnet/ftpp_si.h, src/dynamic-preprocessors/ftptelnet/ftpp_ui_client_lookup.c, src/dynamic-preprocessors/ftptelnet/ftpp_ui_client_lookup.h, src/dynamic-preprocessors/ftptelnet/ftpp_ui_config.c, src/dynamic-preprocessors/ftptelnet/ftpp_ui_config.h, src/dynamic-preprocessors/ftptelnet/ftpp_ui_server_lookup.c, src/dynamic-preprocessors/ftptelnet/ftpp_ui_server_lookup.h, src/dynamic-preprocessors/ftptelnet/ftpp_util_kmap.h, src/dynamic-preprocessors/ftptelnet/hi_util_kmap.c, src/dynamic-preprocessors/ftptelnet/hi_util_kmap.h, src/dynamic-preprocessors/ftptelnet/hi_util_xmalloc.c, src/dynamic-preprocessors/ftptelnet/hi_util_xmalloc.h, src/dynamic-preprocessors/ftptelnet/pp_ftp.c, src/dynamic-preprocessors/ftptelnet/pp_ftp.h, src/dynamic-preprocessors/ftptelnet/pp_telnet.c, src/dynamic-preprocessors/ftptelnet/pp_telnet.h, src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.h, src/dynamic-preprocessors/ftptelnet/spp_ftptelnet.c, src/dynamic-preprocessors/ftptelnet/spp_ftptelnet.h, src/dynamic-preprocessors/gtp/gtp_config.c, src/dynamic-preprocessors/gtp/gtp_config.h, src/dynamic-preprocessors/gtp/gtp_debug.h, src/dynamic-preprocessors/gtp/gtp_parser.c, src/dynamic-preprocessors/gtp/gtp_parser.h, src/dynamic-preprocessors/gtp/gtp_roptions.c, src/dynamic-preprocessors/gtp/gtp_roptions.h, src/dynamic-preprocessors/gtp/spp_gtp.c, src/dynamic-preprocessors/gtp/spp_gtp.h, src/dynamic-preprocessors/imap/imap_config.c, src/dynamic-preprocessors/imap/imap_config.h, src/dynamic-preprocessors/imap/imap_log.c, src/dynamic-preprocessors/imap/imap_log.h, src/dynamic-preprocessors/imap/imap_util.c, src/dynamic-preprocessors/imap/imap_util.h, src/dynamic-preprocessors/imap/snort_imap.c, src/dynamic-preprocessors/imap/snort_imap.h, src/dynamic-preprocessors/imap/spp_imap.c, src/dynamic-preprocessors/imap/spp_imap.h, src/dynamic-preprocessors/isakmp/spp_isakmp.c, src/dynamic-preprocessors/isakmp/spp_isakmp.h, src/dynamic-preprocessors/libs/sf_preproc_info.h, src/dynamic-preprocessors/libs/sfcommon.h, src/dynamic-preprocessors/libs/sfparser.c, src/dynamic-preprocessors/libs/ssl.c, src/dynamic-preprocessors/libs/ssl.h, src/dynamic-preprocessors/modbus/modbus_decode.c, src/dynamic-preprocessors/modbus/modbus_decode.h, src/dynamic-preprocessors/modbus/modbus_paf.c, src/dynamic-preprocessors/modbus/modbus_paf.h, src/dynamic-preprocessors/modbus/modbus_roptions.c, src/dynamic-preprocessors/modbus/modbus_roptions.h, src/dynamic-preprocessors/modbus/spp_modbus.c, src/dynamic-preprocessors/modbus/spp_modbus.h, src/dynamic-preprocessors/pop/pop_config.c, src/dynamic-preprocessors/pop/pop_config.h, src/dynamic-preprocessors/pop/pop_log.c, src/dynamic-preprocessors/pop/pop_log.h, src/dynamic-preprocessors/pop/pop_util.c, src/dynamic-preprocessors/pop/pop_util.h, src/dynamic-preprocessors/pop/snort_pop.c, src/dynamic-preprocessors/pop/snort_pop.h, src/dynamic-preprocessors/pop/spp_pop.c, src/dynamic-preprocessors/pop/spp_pop.h, src/dynamic-preprocessors/reputation/reputation_config.h, src/dynamic-preprocessors/reputation/reputation_debug.h, src/dynamic-preprocessors/reputation/reputation_utils.c, src/dynamic-preprocessors/reputation/reputation_utils.h, src/dynamic-preprocessors/reputation/spp_reputation.c, src/dynamic-preprocessors/reputation/spp_reputation.h, src/dynamic-preprocessors/reputation/shmem/sflinux_helpers.c, src/dynamic-preprocessors/reputation/shmem/sflinux_helpers.h, src/dynamic-preprocessors/reputation/shmem/shmem_common.h, src/dynamic-preprocessors/reputation/shmem/shmem_config.c, src/dynamic-preprocessors/reputation/shmem/shmem_config.h, src/dynamic-preprocessors/reputation/shmem/shmem_datamgmt.c, src/dynamic-preprocessors/reputation/shmem/shmem_datamgmt.h, src/dynamic-preprocessors/reputation/shmem/shmem_lib.c, src/dynamic-preprocessors/reputation/shmem/shmem_lib.h, src/dynamic-preprocessors/reputation/shmem/shmem_mgmt.c, src/dynamic-preprocessors/reputation/shmem/shmem_mgmt.h, src/dynamic-preprocessors/rzb_saac/spp_rzb-saac.c, src/dynamic-preprocessors/sdf/sdf_credit_card.c, src/dynamic-preprocessors/sdf/sdf_credit_card.h, src/dynamic-preprocessors/sdf/sdf_detection_option.c, src/dynamic-preprocessors/sdf/sdf_detection_option.h, src/dynamic-preprocessors/sdf/sdf_pattern_match.c, src/dynamic-preprocessors/sdf/sdf_pattern_match.h, src/dynamic-preprocessors/sdf/sdf_us_ssn.c, src/dynamic-preprocessors/sdf/sdf_us_ssn.h, src/dynamic-preprocessors/sdf/spp_sdf.h, src/dynamic-preprocessors/sip/sip_config.h, src/dynamic-preprocessors/sip/sip_debug.h, src/dynamic-preprocessors/sip/sip_dialog.c, src/dynamic-preprocessors/sip/sip_dialog.h, src/dynamic-preprocessors/sip/sip_parser.c, src/dynamic-preprocessors/sip/sip_parser.h, src/dynamic-preprocessors/sip/sip_roptions.h, src/dynamic-preprocessors/sip/sip_utils.c, src/dynamic-preprocessors/sip/sip_utils.h, src/dynamic-preprocessors/sip/spp_sip.c, src/dynamic-preprocessors/sip/spp_sip.h, src/dynamic-preprocessors/sip/test/sip_test.c, src/dynamic-preprocessors/smtp/smtp_config.c, src/dynamic-preprocessors/smtp/smtp_config.h, src/dynamic-preprocessors/smtp/smtp_log.c, src/dynamic-preprocessors/smtp/smtp_log.h, src/dynamic-preprocessors/smtp/smtp_normalize.c, src/dynamic-preprocessors/smtp/smtp_normalize.h, src/dynamic-preprocessors/smtp/smtp_util.c, src/dynamic-preprocessors/smtp/smtp_util.h, src/dynamic-preprocessors/smtp/smtp_xlink2state.c, src/dynamic-preprocessors/smtp/smtp_xlink2state.h, src/dynamic-preprocessors/smtp/snort_smtp.c, src/dynamic-preprocessors/smtp/snort_smtp.h, src/dynamic-preprocessors/smtp/spp_smtp.h, src/dynamic-preprocessors/ssh/spp_ssh.c, src/dynamic-preprocessors/ssh/spp_ssh.h, src/dynamic-preprocessors/ssl/spp_ssl.c, src/dynamic-preprocessors/ssl/spp_ssl.h, src/output-plugins/spo_alert_fast.c, src/output-plugins/spo_alert_fast.h, src/output-plugins/spo_alert_full.c, src/output-plugins/spo_alert_full.h, src/output-plugins/spo_alert_sf_socket.c, src/output-plugins/spo_alert_sf_socket.h, src/output-plugins/spo_alert_syslog.c, src/output-plugins/spo_alert_syslog.h, src/output-plugins/spo_alert_test.c, src/output-plugins/spo_alert_test.h, src/output-plugins/spo_alert_unixsock.h, src/output-plugins/spo_csv.c, src/output-plugins/spo_csv.h, src/output-plugins/spo_log_ascii.c, src/output-plugins/spo_log_ascii.h, src/output-plugins/spo_log_null.c, src/output-plugins/spo_log_null.h, src/output-plugins/spo_log_tcpdump.c, src/output-plugins/spo_log_tcpdump.h, src/output-plugins/spo_unified.c, src/output-plugins/spo_unified.h, src/output-plugins/spo_unified2.c, src/output-plugins/spo_unified2.h, src/parser/IpAddrSet.c, src/parser/IpAddrSet.h, src/preprocessors/normalize.c, src/preprocessors/normalize.h, src/preprocessors/perf-base.c, src/preprocessors/perf-base.h, src/preprocessors/perf-event.c, src/preprocessors/perf-event.h, src/preprocessors/perf-flow.c, src/preprocessors/perf-flow.h, src/preprocessors/perf.c, src/preprocessors/perf.h, src/preprocessors/portscan.c, src/preprocessors/portscan.h, src/preprocessors/sfprocpidstats.c, src/preprocessors/sfprocpidstats.h, src/preprocessors/snort_httpinspect.c, src/preprocessors/snort_httpinspect.h, src/preprocessors/spp_arpspoof.c, src/preprocessors/spp_arpspoof.h, src/preprocessors/spp_bo.c, src/preprocessors/spp_bo.h, src/preprocessors/spp_frag3.c, src/preprocessors/spp_frag3.h, src/preprocessors/spp_httpinspect.h, src/preprocessors/spp_normalize.c, src/preprocessors/spp_normalize.h, src/preprocessors/spp_perfmonitor.h, src/preprocessors/spp_rpc_decode.c, src/preprocessors/spp_rpc_decode.h, src/preprocessors/spp_sfportscan.c, src/preprocessors/spp_sfportscan.h, src/preprocessors/spp_stream5.c, src/preprocessors/spp_stream5.h, src/preprocessors/str_search.c, src/preprocessors/str_search.h, src/preprocessors/stream_api.c, src/preprocessors/stream_api.h, src/preprocessors/stream_expect.c, src/preprocessors/stream_expect.h, src/preprocessors/HttpInspect/anomaly_detection/hi_ad.c, src/preprocessors/HttpInspect/client/hi_client_norm.c, src/preprocessors/HttpInspect/event_output/hi_eo_log.c, src/preprocessors/HttpInspect/include/hi_ad.h, src/preprocessors/HttpInspect/include/hi_client.h, src/preprocessors/HttpInspect/include/hi_client_norm.h, src/preprocessors/HttpInspect/include/hi_client_stateful.h, src/preprocessors/HttpInspect/include/hi_cmd_lookup.h, src/preprocessors/HttpInspect/include/hi_eo.h, src/preprocessors/HttpInspect/include/hi_eo_events.h, src/preprocessors/HttpInspect/include/hi_eo_log.h, src/preprocessors/HttpInspect/include/hi_include.h, src/preprocessors/HttpInspect/include/hi_mi.h, src/preprocessors/HttpInspect/include/hi_norm.h, src/preprocessors/HttpInspect/include/hi_paf.h, src/preprocessors/HttpInspect/include/hi_reqmethod_check.h, src/preprocessors/HttpInspect/include/hi_return_codes.h, src/preprocessors/HttpInspect/include/hi_server.h, src/preprocessors/HttpInspect/include/hi_server_norm.h, src/preprocessors/HttpInspect/include/hi_si.h, src/preprocessors/HttpInspect/include/hi_stateful_inspect.h, src/preprocessors/HttpInspect/include/hi_ui_config.h, src/preprocessors/HttpInspect/include/hi_ui_iis_unicode_map.h, src/preprocessors/HttpInspect/include/hi_ui_server_lookup.h, src/preprocessors/HttpInspect/include/hi_uri.h, src/preprocessors/HttpInspect/include/hi_urilen_check.h, src/preprocessors/HttpInspect/include/hi_util.h, src/preprocessors/HttpInspect/include/hi_util_hbm.h, src/preprocessors/HttpInspect/include/hi_util_kmap.h, src/preprocessors/HttpInspect/include/hi_util_xmalloc.h, src/preprocessors/HttpInspect/mode_inspection/hi_mi.c, src/preprocessors/HttpInspect/normalization/hi_norm.c, src/preprocessors/HttpInspect/server/hi_server_norm.c, src/preprocessors/HttpInspect/session_inspection/hi_si.c, src/preprocessors/HttpInspect/user_interface/hi_ui_config.c, src/preprocessors/HttpInspect/user_interface/hi_ui_iis_unicode_map.c, src/preprocessors/HttpInspect/user_interface/hi_ui_server_lookup.c, src/preprocessors/HttpInspect/utils/hi_cmd_lookup.c, src/preprocessors/HttpInspect/utils/hi_paf.c, src/preprocessors/HttpInspect/utils/hi_util_hbm.c, src/preprocessors/HttpInspect/utils/hi_util_kmap.c, src/preprocessors/HttpInspect/utils/hi_util_xmalloc.c, src/preprocessors/Stream5/snort_stream5_icmp.c, src/preprocessors/Stream5/snort_stream5_icmp.h, src/preprocessors/Stream5/snort_stream5_ip.c, src/preprocessors/Stream5/snort_stream5_ip.h, src/preprocessors/Stream5/snort_stream5_session.c, src/preprocessors/Stream5/snort_stream5_session.h, src/preprocessors/Stream5/snort_stream5_tcp.c, src/preprocessors/Stream5/snort_stream5_tcp.h, src/preprocessors/Stream5/snort_stream5_udp.c, src/preprocessors/Stream5/snort_stream5_udp.h, src/preprocessors/Stream5/stream5_common.c, src/preprocessors/Stream5/stream5_common.h, src/preprocessors/Stream5/stream5_paf.c, src/preprocessors/Stream5/stream5_paf.h, src/sfutil/Unified2_common.h, src/sfutil/acsmx.c, src/sfutil/acsmx.h, src/sfutil/acsmx2.h, src/sfutil/asn1.c, src/sfutil/asn1.h, src/sfutil/bitop.h, src/sfutil/bitop_funcs.h, src/sfutil/bnfa_search.h, src/sfutil/getopt.h, src/sfutil/intel-soft-cpm.c, src/sfutil/intel-soft-cpm.h, src/sfutil/ipobj.c, src/sfutil/ipobj.h, src/sfutil/mpse.c, src/sfutil/segment_mem.c, src/sfutil/segment_mem.h, src/sfutil/sfActionQueue.c, src/sfutil/sfActionQueue.h, src/sfutil/sfPolicy.c, src/sfutil/sfPolicy.h, src/sfutil/sfPolicyUserData.c, src/sfutil/sfPolicyUserData.h, src/sfutil/sf_base64decode.c, src/sfutil/sf_base64decode.h, src/sfutil/sf_email_attach_decode.c, src/sfutil/sf_email_attach_decode.h, src/sfutil/sf_ip.c, src/sfutil/sf_ip.h, src/sfutil/sf_iph.h, src/sfutil/sf_ipvar.c, src/sfutil/sf_ipvar.h, src/sfutil/sf_seqnums.h, src/sfutil/sf_textlog.c, src/sfutil/sf_textlog.h, src/sfutil/sf_vartable.c, src/sfutil/sf_vartable.h, src/sfutil/sfeventq.c, src/sfutil/sfeventq.h, src/sfutil/sfghash.c, src/sfutil/sfghash.h, src/sfutil/sfhashfcn.c, src/sfutil/sfhashfcn.h, src/sfutil/sfksearch.c, src/sfutil/sfksearch.h, src/sfutil/sflsq.c, src/sfutil/sflsq.h, src/sfutil/sfmemcap.c, src/sfutil/sfmemcap.h, src/sfutil/sfportobject.c, src/sfutil/sfportobject.h, src/sfutil/sfprimetable.c, src/sfutil/sfprimetable.h, src/sfutil/sfrf.c, src/sfutil/sfrf.h, src/sfutil/sfrim.c, src/sfutil/sfrt.c, src/sfutil/sfrt.h, src/sfutil/sfrt_dir.c, src/sfutil/sfrt_dir.h, src/sfutil/sfrt_flat.c, src/sfutil/sfrt_flat.h, src/sfutil/sfrt_flat_dir.c, src/sfutil/sfrt_flat_dir.h, src/sfutil/sfrt_lctrie.c, src/sfutil/sfrt_lctrie.h, src/sfutil/sfrt_trie.h, src/sfutil/sfsnprintfappend.c, src/sfutil/sfsnprintfappend.h, src/sfutil/sfthd.c, src/sfutil/sfthd.h, src/sfutil/sfxhash.c, src/sfutil/sfxhash.h, src/sfutil/strvec.c, src/sfutil/strvec.h, src/sfutil/util_jsnorm.c, src/sfutil/util_jsnorm.h, src/sfutil/util_math.c, src/sfutil/util_math.h, src/sfutil/util_net.c, src/sfutil/util_net.h, src/sfutil/util_str.c, src/sfutil/util_str.h, src/sfutil/util_unfold.c, src/sfutil/util_unfold.h, src/sfutil/util_utf.c, src/sfutil/util_utf.h, src/sfutil/test/sf_ip_test.c, src/sfutil/test/sfrf_test.c, src/sfutil/test/sfrt_test.c, src/sfutil/test/sfthd_test.c, src/sfutil/test/unit_hacks.c, src/sfutil/test/unit_hacks.h, src/target-based/sf_attribute_table.y, src/target-based/sftarget_hostentry.c, src/target-based/sftarget_hostentry.h, src/target-based/sftarget_protocol_reference.c, src/target-based/sftarget_protocol_reference.h, src/target-based/sftarget_reader.c, src/target-based/sftarget_reader.h, src/win32/WIN32-Code/getopt.c, src/win32/WIN32-Code/inet_aton.c, src/win32/WIN32-Code/misc.c, src/win32/WIN32-Code/name.h, src/win32/WIN32-Code/win32_service.c, src/win32/WIN32-Includes/config.h, src/win32/WIN32-Includes/getopt.h, src/win32/WIN32-Includes/inttypes.h, src/win32/WIN32-Includes/stdint.h, src/win32/WIN32-Includes/WinPCAP/pthread.h, src/win32/WIN32-Includes/WinPCAP/sched.h, src/win32/WIN32-Includes/WinPCAP/semaphore.h, tools/control/sfcontrol.c, tools/u2boat/u2boat.c, tools/u2boat/u2boat.h, tools/u2spewfoo/u2spewfoo.c: Updated the address of the Free Software Foundation. * src/dynamic-preprocessors/dnp3/spp_dnp3.c: Check default config before dereferencing memcap. * src/preprocessors/Stream5/snort_stream5_tcp.c: fix handling of gaps in PAF. * src/dynamic-preprocessors/smtp/: smtp_util.c, snort_smtp.c, snort_smtp.h: get individual file names for multiple file attachments within one smtp packet * src/dynamic-output/plugins/output_plugin.c: Don't change vlanId into network byte order in the dynamic output API. * src/dynamic-preprocessors/imap/: snort_imap.c, snort_imap.h: Add a flag to indicate end of MIME to avoid incorrect data end marker * src/sfutil/sf_email_attach_decode.h: change decode length calculation when file depth is larger than max int * src/: preprocessors/HttpInspect/include/hi_paf.h, sfutil/sf_email_attach_decode.h, preprocessors/HttpInspect/utils/hi_paf.c: auto enable http ports when file policy is enabled * src/sfutil/sfthd.c: Global thresholds can be disabled with count -1. * src/sfutil/sfthd.c: allow gen_id 0 sig_id 0 and gen_id X sig_id 0 together * src/: decode.h, preprocessors/snort_httpinspect.c: file data is only valid with PAF processing * src/preprocessors/Stream5/snort_stream5_tcp.c: don't flag missing packets when PAF flushing to allow better recovery from gaps * src/dynamic-preprocessors/: smtp/smtp_config.c, imap/imap_config.c, imap/spp_imap.c, pop/pop_config.c, pop/spp_pop.c: Enable file data configurations for preprocessors when file processing is enabled * src/preprocessors/Stream5/snort_stream5_tcp.c: fixed check for hole in seglist while PAF scanning * src/: snort.c, dynamic-examples/Makefile.am, dynamic-plugins/Makefile.am, dynamic-preprocessors/Makefile.am, dynamic-preprocessors/sf_dynamic_initialize/sf_dynamic_initialize.dsp, preprocessors/spp_stream5.c, target-based/Makefile.am, target-based/sftarget_reader.c, target-based/sftarget_reader.h: Add an API call to add a service to a host in the attribute table. Remove the unused live attribute table code. * doc/README.ppm, doc/snort_manual.tex, etc/gen-msg.map, preproc_rules/preprocessor.rules, src/detect.c, src/generators.h, src/parser.c, src/ppm.c, src/ppm.h: added 134:3 and IPs and ports to log messages for PPM packet events * src/snort.c: force drop TCP/UDP now gets DAQ blacklist instead of DAQ block verdict * doc/README.stream5, etc/gen-msg.map, preproc_rules/preprocessor.rules, src/generators.h, src/preprocessors/Stream5/snort_stream5_tcp.c: add 129:20 for midstream traffic we don't pick up. * src/preprocessors/Stream5/snort_stream5_tcp.c: fix normalize_tcp to not block duplicate SYNs * src/parser.c, src/snort.c, src/preprocessors/snort_httpinspect.c, src/preprocessors/snort_httpinspect.h, src/snort.h, src/dynamic-preprocessors/smtp/smtp_config.h, src/dynamic-preprocessors/smtp/snort_smtp.c, src/dynamic-preprocessors/imap/imap_config.h, src/dynamic-preprocessors/imap/snort_imap.c, src/dynamic-preprocessors/imap/spp_imap.c, src/dynamic-preprocessors/pop/pop_config.h, src/dynamic-preprocessors/pop/snort_pop.c, src/dynamic-preprocessors/pop/spp_pop.c, src/sfutil/sf_email_attach_decode.h, src/preprocessors/HttpInspect/include/hi_ui_config.h, configure.in, src/detection-plugins/sp_file_data.c: file_depth integration, openssl integration, reload configuration * src/dynamic-preprocessors/: libs/ssl.c, libs/ssl.h, ssl/spp_ssl.c: Add SSLv3/TLS backwards compatibiltiy with SSLv2 ClientHello in the ssl preprocessor. * src/: preprocessors/snort_httpinspect.c, src/dynamic-preprocessors/: imap/snort_imap.c, pop/snort_pop.c, smtp/snort_smtp.c: add file type id support for HTTP post, smtp, imap, and pop * src/: snort_debug.h, control/sfcontrol.c, preprocessors/Stream5/snort_stream5_tcp.c: Do not delete application session data on last ACK. * src/output-plugins/spo_unified.c: Add deprecated warning for unified output plugin. * src/decode.h: Add support for decoding PPP type 0x57 (IPv6) for PPPoE * src/Makefile.am, src/generators.h, src/parser.c, src/parser.h, src/preprocids.h, src/snort.c, src/snort_debug.h, configure.in, src/dynamic-preprocessors/Makefile.am, src/preprocessors/snort_httpinspect.c, src/detection-plugins/sp_file_data.c, src/dynamic-examples/Makefile.am: add file type identification and file signature sha256 calculation for HTTP. * src/: util.c, dynamic-preprocessors/dcerpc2/spp_dce2.c, dynamic-preprocessors/dnp3/spp_dnp3.c, dynamic-preprocessors/dns/spp_dns.c, dynamic-preprocessors/ftptelnet/spp_ftptelnet.c, dynamic-preprocessors/gtp/spp_gtp.c, dynamic-preprocessors/imap/spp_imap.c, dynamic-preprocessors/isakmp/spp_isakmp.c, dynamic-preprocessors/modbus/spp_modbus.c, dynamic-preprocessors/pop/spp_pop.c, dynamic-preprocessors/reputation/spp_reputation.c, dynamic-preprocessors/sip/spp_sip.c, dynamic-preprocessors/ssh/spp_ssh.c, dynamic-preprocessors/ssl/spp_ssl.c: Remove IPv6 tag from snort -V * configure.in, doc/README.ipv6, doc/README.unified2, doc/README.variables, doc/snort_manual.tex, src/decode.h, src/detect.c, src/detect.h, src/encode.c, src/fpdetect.c, src/ipv6_port.h, src/log.c, src/log_text.c, src/parser.c, src/sf_protocols.h, src/snort.c, src/snort.h, src/tag.c, src/util.c, src/util.h, src/detection-plugins/sp_ftpbounce.c, src/detection-plugins/sp_icmp_id_check.c, src/detection-plugins/sp_icmp_seq_check.c, src/detection-plugins/sp_ip_same_check.c, src/detection-plugins/sp_session.c, src/dynamic-plugins/sf_engine/sf_snort_packet.h, src/dynamic-preprocessors/dynamic_preprocessors.dsp, src/dynamic-preprocessors/dcerpc2/dce2_config.c, src/dynamic-preprocessors/dcerpc2/sf_dce2.dsp, src/dynamic-preprocessors/dcerpc2/snort_dce2.c, src/dynamic-preprocessors/dcerpc2/spp_dce2.c, src/dynamic-preprocessors/dnp3/sf_dnp3.dsp, src/dynamic-preprocessors/dnp3/spp_dnp3.c, src/dynamic-preprocessors/dns/sf_dns.dsp, src/dynamic-preprocessors/dns/spp_dns.c, src/dynamic-preprocessors/ftptelnet/ftpp_si.c, src/dynamic-preprocessors/ftptelnet/ftpp_ui_client_lookup.c, src/dynamic-preprocessors/ftptelnet/ftpp_ui_server_lookup.c, src/dynamic-preprocessors/ftptelnet/pp_ftp.c, src/dynamic-preprocessors/ftptelnet/sf_ftptelnet.dsp, src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, src/dynamic-preprocessors/ftptelnet/spp_ftptelnet.c, src/dynamic-preprocessors/gtp/sf_gtp.dsp, src/dynamic-preprocessors/gtp/spp_gtp.c, src/dynamic-preprocessors/imap/sf_imap.dsp, src/dynamic-preprocessors/imap/spp_imap.c, src/dynamic-preprocessors/isakmp/spp_isakmp.c, src/dynamic-preprocessors/libs/sfdynamic_preproc_libs.dsp, src/dynamic-preprocessors/modbus/sf_modbus.dsp, src/dynamic-preprocessors/modbus/spp_modbus.c, src/dynamic-preprocessors/pop/sf_pop.dsp, src/dynamic-preprocessors/pop/spp_pop.c, src/dynamic-preprocessors/reputation/sf_reputation.dsp, src/dynamic-preprocessors/reputation/spp_reputation.c, src/dynamic-preprocessors/sdf/sf_sdf.dsp, src/dynamic-preprocessors/sf_dynamic_initialize/sf_dynamic_initialize.dsp, src/dynamic-preprocessors/sip/sf_sip.dsp, src/dynamic-preprocessors/sip/sip_dialog.c, src/dynamic-preprocessors/sip/spp_sip.c, src/dynamic-preprocessors/smtp/sf_smtp.dsp, src/dynamic-preprocessors/ssh/sf_ssh.dsp, src/dynamic-preprocessors/ssh/spp_ssh.c, src/dynamic-preprocessors/ssl/sf_ssl.dsp, src/dynamic-preprocessors/ssl/spp_ssl.c, src/output-plugins/spo_alert_sf_socket.c, src/output-plugins/spo_log_ascii.c, src/output-plugins/spo_unified2.c, src/parser/IpAddrSet.c, src/parser/IpAddrSet.h, src/preprocessors/normalize.c, src/preprocessors/perf-base.c, src/preprocessors/perf-base.h, src/preprocessors/perf-flow.c, src/preprocessors/portscan.c, src/preprocessors/snort_httpinspect.c, src/preprocessors/spp_arpspoof.c, src/preprocessors/spp_frag3.c, src/preprocessors/spp_normalize.c, src/preprocessors/spp_normalize.h, src/preprocessors/spp_sfportscan.c, src/preprocessors/spp_stream5.c, src/preprocessors/stream_expect.c, src/preprocessors/HttpInspect/session_inspection/hi_si.c, src/preprocessors/HttpInspect/user_interface/hi_ui_server_lookup.c, src/preprocessors/Stream5/snort_stream5_icmp.c, src/preprocessors/Stream5/snort_stream5_session.c, src/preprocessors/Stream5/snort_stream5_tcp.c, src/preprocessors/Stream5/snort_stream5_udp.c, src/preprocessors/Stream5/stream5_common.c, src/preprocessors/Stream5/stream5_common.h, src/sfutil/ipobj.c, src/sfutil/ipobj.h, src/sfutil/sfPolicy.c, src/sfutil/sf_ip.h, src/sfutil/sf_iph.h, src/sfutil/sf_ipvar.h, src/sfutil/sfrf.c, src/sfutil/sfrt.c, src/sfutil/sfrt.h, src/sfutil/sfrt_dir.c, src/sfutil/sfrt_flat.c, src/sfutil/sfrt_flat.h, src/sfutil/sfrt_flat_dir.c, src/sfutil/sfthd.c, src/sfutil/util_net.c, src/sfutil/util_net.h, src/sfutil/test/Makefile.am, src/sfutil/test/sfrf_test.c, src/sfutil/test/sfthd_test.c, src/sfutil/test/unit_hacks.c, src/sfutil/test/unit_hacks.h, src/target-based/sf_attribute_table.y, src/target-based/sftarget_reader.c, src/target-based/sftarget_reader.h, src/win32/WIN32-Prj/build_all.dsp, src/win32/WIN32-Prj/sf_engine.dsp, src/win32/WIN32-Prj/sf_engine_initialize.dsp, src/win32/WIN32-Prj/snort.dsp, src/win32/WIN32-Prj/snort_initialize.dsp, src/win32/WIN32-Prj/snort_installer.nsi: Remove IPv4 only code paths 2012-07-30 Hui Cao Snort 2.9.3.1 * src/build.h: Updated build number to 40 * src/sfutil/acsmx2.c: Release memory during return. * src/dynamic-preprocessors/sip/sip_config.c: Free method struct when method->methodName is NULL. * src/: detection-plugins/detection_options.c, detection-plugins/sp_byte_check.c, detection-plugins/sp_byte_extract.c, detection-plugins/sp_byte_jump.c, dynamic-plugins/sp_dynamic.c, dynamic-plugins/sp_preprocopt.c: Fix constant expression in hashing routines for 64bit platforms. * src/dynamic-preprocessors/dcerpc2/dce2_smb.c: Fix Samba chained OpenAndX -> Write command handling. * src/active.c: Check for TCP RST flag regardless of other flags to block resetting resets. * src/: active.c, decode.c, detection-plugins/sp_pcre.c, dynamic-plugins/sf_convert_dynamic.c, dynamic-plugins/sf_dynamic_plugins.c, dynamic-plugins/sf_dynamic_preprocessor.h, dynamic-plugins/sp_dynamic.c, dynamic-preprocessors/dnp3/dnp3_map.c, dynamic-preprocessors/reputation/reputation_config.c, dynamic-preprocessors/sdf/spp_sdf.c, dynamic-preprocessors/sip/sip_config.c, dynamic-preprocessors/sip/sip_roptions.c, dynamic-preprocessors/smtp/spp_smtp.c, output-plugins/spo_alert_unixsock.c, preprocessors/spp_httpinspect.c, preprocessors/spp_perfmonitor.c, preprocessors/HttpInspect/client/hi_client.c, preprocessors/HttpInspect/server/hi_server.c, sfutil/bnfa_search.c, sfutil/sf_iph.c, target-based/sf_attribute_table_parser.l: Parse time memory cleanup * src/dynamic-preprocessors/dcerpc2/dce2_utils.h: Fixed issue on big endian systems where behaviour was incorrect. 2012-07-10 Todd Wease Snort 2.9.3 * src/build.h: Updated build number to 37 * src/preprocessors/HttpInspect/server/hi_server.c: When paf is turned on, the flow depth on raw packets should be checking if max_seq was set. * src/preprocessors/HttpInspect/client/hi_client.c: Rearranged check in hi_client_extract_header() to stop processing when there is no more data. * src/dynamic-preprocessors/smtp/: smtp_util.c, snort_smtp.c: Clear flags for filename logging if there are no ending quotes for MIME attachement filename. Thanks to Rick Chisholm for helping us track down the issue. * doc/CREDITS: Update rmkml's email address. * src/preprocessors/: snort_httpinspect.h, HttpInspect/server/hi_server.c: Fix application of flow_depth for transfers of files over 2GB. 2012-06-06 Russ Combs Snort 2.9.3 RC * src/build.h: updating build number to 33 * src/: checksum.h, decode.c, encode.c: Dropped dnets checksumming functionality. * src/: decode.h, encode.c, dynamic-plugins/sf_engine/sf_snort_packet.h: Remove unused policyEngineData. * src/preprocessors/: Stream5/snort_stream5_tcp.c, HttpInspect/utils/hi_paf.c: Need to check for NULL since a timeout can release proto specific data. Fix mid-stream pickup sequence tracking. * src/preprocessors/: snort_httpinspect.c, snort_httpinspect.h, HttpInspect/server/hi_server.c: Apply server flow depth to session when PAF is turned on. * src/preprocessors/Stream5/: snort_stream5_session.c, stream5_common.h: Change SessionKey to a SessionKey pointer. * src/dynamic-output/plugins/: output_lib.h, output_plugin.c: Add dynamic output API for DAQ interface mode. * src/: dynamic-output/plugins/output_base.c, plugbase.c, spo_plugbase.h: Remove older output plugin when new one is available. * src/dynamic-plugins/: sf_dynamic_plugins.c, sf_engine/sf_snort_detection_engine.c: Force exact versioning match of running dynamic engine and dynamic engine used to build SO rules. * src/: sfdaq.c, sfdaq.h, dynamic-plugins/sf_dynamic_plugins.c, dynamic-plugins/sf_dynamic_preprocessor.h: Add API for checking whether DAQ can whitelist. * src/: parser.c, parser.h, snort.c: Added config disable-attribute-reload-thread to snort.conf. Snort now provides snort.conf(line #) on errors durring parsing. * src/: parser.c, detection-plugins/sp_pattern_match.c, detection-plugins/sp_pattern_match.h: Warn users when rules contain relative options off of fast_pattern:only content matches. * src/dynamic-preprocessors/sdf/spp_sdf.c: SDF now only looks at rebuilt packets. * src/control/sfcontrol.c, src/dynamic-preprocessors/reputation/reputation_config.c, src/dynamic-preprocessors/reputation/reputation_config.h, src/dynamic-preprocessors/reputation/spp_reputation.c, src/dynamic-preprocessors/reputation/spp_reputation.h, src/dynamic-preprocessors/reputation/shmem/shmem_mgmt.c, src/dynamic-preprocessors/reputation/shmem/shmem_mgmt.h, tools/control/sfcontrol.c: Add ability to query reputation pp with control socket. User can now query reputation pp for routing table and management information. Fixed bug to prevent IP Reputation from trying to allocate too much memory. * doc/: Makefile.am, README.unified2, snort_manual.tex: Add README.unified2 to Makefile.am. Add documentation for unified2 file format. Add smb_fingerprint_policy documentation to snort manual. * src/preprocessors/Stream5/stream5_paf.c: Ensure PAF is configured on reload the same as it was on restart. * src/preprocessors/spp_stream5.c: Fix stream5 issue on reload were it wasn't validating or registering preprocessor function when new policy is added. * configure.in, doc/INSTALL, doc/README.decoder_preproc_rules, doc/snort_manual.pdf, doc/snort_manual.tex, etc/snort.conf, rpm/snort.spec, src/event_queue.c, src/event_queue.h, src/event_wrapper.c, src/fpcreate.c, src/fpcreate.h, src/fpdetect.c, src/fpdetect.h, src/parser.c, src/parser.h, src/ppm.c, src/signature.h, src/snort.h, src/detection-plugins/detection_options.c, src/detection-plugins/detection_options.h, src/preprocessors/spp_frag3.c, src/sfutil/sfeventq.c, src/sfutil/sfeventq.h, src/win32/WIN32-Prj/snort.dsp: Removed --enable-decoder-preprocessor-rules configure option and hardened preprocessor and decoder rule event code. To enable old behavior such that specific preprocessor and decoder rules don't have to be explicity added to snort.conf, add "config autogenerate_preprocessor_decoder_rules" to your snort.conf. * src/: profiler.h, dynamic-output/plugins/output_lib.h, dynamic-plugins/sf_dynamic_preprocessor.h, sfutil/sfPolicy.h, sfutil/sf_ip.h: Added a function, sfip_fast_equals_raw, that does the minimum needed to determine if 2 IPs are equal. Added profiler macros that allow for unique variable names. Moved GetPolicyFunc definition to sfPolicy.h. * src/: snort.c, detection-plugins/sp_flowbits.c, detection-plugins/sp_flowbits.h, dynamic-plugins/sp_dynamic.c: Fix flowbit group toggle. Fix issue with SO rules that reuse a flowbits structure when all stubs aren't enabled. * src/dynamic-preprocessors/smtp/: smtp_config.c, snort_smtp.c, snort_smtp.h, spp_smtp.c: SMTP PP now only allocates its mempools 1 time. Fix build on legacy systems that don't support c99 declarations. Fix memory leak on reload. * src/: detect.c, ppm.c: Fix PPM when PPM rules are dynamically generated and there are multiple policies. 2012-04-26 Russ Combs Snort 2.9.3 Beta * src/build.h: Updating build number to 22. * src/: snort.c, control/sfcontrol.c: Stop daq before tearing down control socket and freeing idle processors. * src/control/sfcontrol.c, src/control/sfcontrol.h, tools/control/sfcontrol.c: - Return the correct codes with responses. - Use macros to define the codes. - Update the client to receive multiple status (0x0009) messages followed by a success or error message. * doc/snort_manual.tex, src/preprocessors/Stream5/snort_stream5_session.c, src/preprocessors/Stream5/stream5_common.h, src/preprocessors/spp_stream5.c, src/detection-plugins/sp_flowbits.c, src/detection-plugins/sp_flowbits.h, src/parser.c, src/snort.h: - Flowbits can belong to multiple groups. - Restrict the syntax of flowbit name and group names to alphanumeric string including periods, dashes, and underscores. - Changed the maximal flowbit size to be 2048. - Changes the error syntax when maximum number of flowbit ID exceeds allowed value. - Thanks to Cees for providing information about the size bug. * src/: preprocessors/spp_stream5.c, preprocessors/stream_api.h, dynamic-preprocessors/sip/sip_dialog.c: Ignore sessions already started through updated stream API. * src/decode.h, src/dynamic-plugins/sf_engine/sf_snort_packet.h, src/output-plugins/spo_unified2.c, src/sfutil/Unified2_common.h, tools/u2spewfoo/u2spewfoo.c: - Remove *_NG logging from Unified2. - Snort unified2 doesn't log to *_NG formats anymore. * src/tag.c: Fix compiler warning on FreeBSD in mis-matched format string. * src/preprocessors/spp_arpspoof.c: - Fix handling when arpspoof_detect_host was set without arpspoof. - Fix compiler warnings on FreeBSD by utilizing modern ip6 code. - Verify snort works correctly, and doesn't cause warnings on FreeBSD. * src/: detection-plugins/Makefile.am, dynamic-plugins/sf_engine/sf_snort_plugin_hdropts.c: Remove unnecessary cruft. * src/output-plugins/spo_alert_unixsock.c: Don't rely on UNIX_PATH_MAX value being 108. * src/: active.c, encode.c, encode.h: Force drop/resets resulting in ICMP unreachables will have the code for administratively prohibited while ips ICMP unreachables remain port unreachable. * src/dynamic-output/: dynamic_output.dsp Makefile.am, src/dynamic-output/libs: Makefile.am output_lib.c snort_output.pc.in, src/dynamic-output/plugins: Makefile.am output_api.h output_base.c, output_common.h output.h output_lib.h output_plugin.c Added dynamic output plugin support. * configure.in, snort.8, contrib/Makefile.am, contrib/README, contrib/create_mssql, contrib/create_mysql, contrib/create_oracle.sql, contrib/create_postgresql, contrib/mysql.php3, contrib/pgsql.php3, contrib/snortdb-extra.gz, doc/INSTALL, doc/Makefile.am, doc/README.ARUBA, doc/README.database, doc/faq.tex, doc/snort_manual.tex, etc/snort.conf, m4/Makefile.am, m4/libprelude.m4, rpm/snort.spec, src/plugbase.c, src/snort.c, src/snort.h, src/output-plugins/Makefile.am, src/plugins/output_base.c, plugins/output_lib.h, src/plugins/output_plugin.c, src/output-plugins/spo_alert_arubaaction.c, src/output-plugins/spo_alert_arubaaction.h, src/output-plugins/spo_alert_prelude.c, src/output-plugins/spo_alert_prelude.h, src/output-plugins/spo_database.c, src/output-plugins/spo_database.h, src/win32/Makefile.am, src/win32/WIN32-Prj/snort_installer.nsi, win32/WIN32-Prj/snort.dsp, win32/WIN32-Prj/snort.dsw: win32/WIN32-Prj/snort_installer.nsi, win32/WIN32-Prj/snort_installer_options.ini: Remove deprecated output plugins aruba, prelude, mysql, oracle and mssql from Snort. * src/detection-plugins/sp_flowbits.c, src/detection-plugins/sp_flowbits.h, src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c, src/dynamic-plugins/sf_engine/sf_snort_plugin_api.c, src/dynamic-plugins/sf_engine/sf_snort_plugin_api.h, src/snort_debug.h, src/dynamic-plugins/sf_convert_dynamic.c, src/dynamic-plugins/sf_dynamic_engine.h, src/dynamic-plugins/sp_dynamic.c, src/dynamic-plugins/sp_dynamic.h, doc/README.flowbits, doc/snort_manual.tex, doc/snort_manual.pdf: Flowbit OR feature. Fixed the so_rules check issue and also the so stub file generated. * doc/README.SMTP, doc/README.imap, doc/README.pop, doc/snort_manual.tex, etc/gen-msg.map, src/dynamic-preprocessors/imap/imap_config.c, src/dynamic-preprocessors/imap/imap_log.h, src/dynamic-preprocessors/imap/imap_util.c, src/dynamic-preprocessors/imap/imap_util.h, src/dynamic-preprocessors/imap/snort_imap.c, src/dynamic-preprocessors/pop/pop_config.c, src/dynamic-preprocessors/pop/pop_log.h, src/dynamic-preprocessors/pop/pop_util.c, src/dynamic-preprocessors/pop/pop_util.h, src/dynamic-preprocessors/pop/snort_pop.c, src/dynamic-preprocessors/smtp/smtp_config.c, src/dynamic-preprocessors/smtp/smtp_log.h, src/dynamic-preprocessors/smtp/smtp_util.c, src/dynamic-preprocessors/smtp/smtp_util.h, src/dynamic-preprocessors/smtp/snort_smtp.c, src/dynamic-preprocessors/smtp/spp_smtp.c: - SMTP/IMAP/POP will now extract non-encoded attachments when content-type MIME headers are present. - SMTP will not decode when ignore_data is present. - Content-Transfer-Encoding should take precendence over Content-Type. - Content-type should first check if boundary in non MIME header state. - Fix SMTP stat msg. * doc/README.http_inspect, doc/faq.pdf, doc/snort_manual.pdf, doc/snort_manual.tex, src/preprocessors/snort_httpinspect.c, src/preprocessors/snort_httpinspect.h, src/preprocessors/spp_httpinspect.c, src/preprocessors/HttpInspect/server/hi_server.c: Update http_inspect decompression to not allocate compress/decompress buffers per session. * src/preprocessors/HttpInspect/normalization/hi_norm.c: - Fix the handling of % encoded ?. HI no longer treats % encoded ? as start of query string. * src/preprocessors/HttpInspect/: include/hi_paf.h, utils/hi_paf.c: Provide access method for HI main to handle simple responses. * src/preprocessors/HttpInspect/: server/hi_server.c, client/hi_client.c: - Fix extraction of Transfer-Encoding header. - Handle chunk extensions when de-chunking. - Fix handling of packets beyond flow depth when PAF is turned on. - Add code to handle simple responses and not generate false positive. * src/dynamic-plugins/sf_engine/sf_snort_packet.h: Frag related fixes: - Check ip6 extension order on frags, including inner on first frag. - Added 116:458 for no offset and no more. - Added 116:459 for frag w/o data. * src/: decode.c, decode.h: - Properly decode pflog version 4. - Salutations to Ryan McBride for the pflog v4 patch. * src/dynamic-preprocessors/sip/sip_parser.c: Add compact form support of VIA header to SIP. * src/dynamic-preprocessors/ftptelnet/pp_telnet.c: Don't presume 3 bytes of junk in a telnet stream is encryption unless midstream pickup. * src/: fpdetect.c, pcrm.c, pcrm.h: Process any->any rules even when a service matches in the attribute table * src/preprocessors/spp_frag3.c: - Drop bad fragments BEFORE inserting them into tracker. - Ensure that all fragments are dropped in inline mode when the first fragment is bad. * src/target-based/sftarget_reader_live.c: - Initialize the value of ret and fix some obscure formatting. - Thanks to William Parker for notifying us. * src/: debug.c, snort.c: Fix placement of int error to avoid warning. * doc/README.dcerpc2, doc/faq.pdf, doc/snort_manual.pdf, doc/snort_manual.tex, etc/gen-msg.map, preproc_rules/preprocessor.rules, src/generators.h, src/dynamic-preprocessors/Makefile.am, src/dynamic-preprocessors/dcerpc2/dce2_cl.c, src/dynamic-preprocessors/dcerpc2/dce2_co.c, src/dynamic-preprocessors/dcerpc2/dce2_co.h, src/dynamic-preprocessors/dcerpc2/dce2_config.c, src/dynamic-preprocessors/dcerpc2/dce2_config.h, src/dynamic-preprocessors/dcerpc2/dce2_debug.h, src/dynamic-preprocessors/dcerpc2/dce2_event.c, src/dynamic-preprocessors/dcerpc2/dce2_event.h, src/dynamic-preprocessors/dcerpc2/dce2_http.c, src/dynamic-preprocessors/dcerpc2/dce2_list.c, src/dynamic-preprocessors/dcerpc2/dce2_list.h, src/dynamic-preprocessors/dcerpc2/dce2_memory.c, src/dynamic-preprocessors/dcerpc2/dce2_memory.h, src/dynamic-preprocessors/dcerpc2/dce2_paf.c, src/dynamic-preprocessors/dcerpc2/dce2_roptions.c, src/dynamic-preprocessors/dcerpc2/dce2_session.h, src/dynamic-preprocessors/dcerpc2/dce2_smb.c, src/dynamic-preprocessors/dcerpc2/dce2_smb.h, src/dynamic-preprocessors/dcerpc2/dce2_stats.h, src/dynamic-preprocessors/dcerpc2/dce2_tcp.c, src/dynamic-preprocessors/dcerpc2/dce2_tcp.h, src/dynamic-preprocessors/dcerpc2/dce2_udp.c, src/dynamic-preprocessors/dcerpc2/dce2_utils.c, src/dynamic-preprocessors/dcerpc2/dce2_utils.h, src/dynamic-preprocessors/dcerpc2/snort_dce2.c, src/dynamic-preprocessors/dcerpc2/snort_dce2.h, src/dynamic-preprocessors/dcerpc2/spp_dce2.c, src/dynamic-preprocessors/dcerpc2/spp_dce2.h, src/dynamic-preprocessors/dcerpc2/includes/smb.h, src/dynamic-preprocessors/sf_dynamic_initialize/sf_dynamic_initialize.dsp, src/sfutil/Makefile.am, src/sfutil/sf_seqnums.h, src/win32/WIN32-Prj/snort.dsp: Update SMB request/response handling to handle server to client evasions where SMB header values aren't echoed in response. - Add support for SMB_COM_WRITE_ANDX "raw" mode. - Add support for additional commands for opening, reading from and writing to SMB named pipes - Update handling of SMB_COM_WRITE_RAW. - Add global configuration option for determining Windows/Samba policy on a per session basis and new preprocessor events. - Add tracking of named pipe state - byte or message mode. - Update SMB_COM_TRANSACTION handling to better support out of order displacements and parameters. - Updates to SMB ByteCount, data offset and data length handling. - Update for Transaction error, where Samba throws out transaction on error and correct data offset passed in to function. - Don't set dcerpc2 rule options and stop processing dcerpc data when server response indicates encrypted packet privacy. - Fix dcerpc2 PAF when target based is enabled to not abort if protocol undefined. - Added processing of chained SMB_COM_WRITE_ANDXs for Samba policies. * src/preprocessors/Stream5/snort_stream5_tcp.c: - Correctly log TCP segments to unified2 when there are multiple alerts on the same reassembled packet. - Purge after flush at session shutdown to avoid reprocessing it when the cache is freed causing strange dce2 alerts. * configure.in: If pkg-config macros do not exist then configure script would be invalid. If it does not exist define a macro that does nothing and continue. * configure.in, src/debug.c, src/decode.c, src/log.c, src/parser.c, src/snort_debug.h, src/util.c, src/dynamic-preprocessors/dnp3/spp_dnp3.c, src/dynamic-preprocessors/libs/ssl.c, src/dynamic-preprocessors/modbus/spp_modbus.c, src/sfutil/sf_ip.c, src/sfutil/sf_ip.h, tools/u2boat/u2boat.c, tools/u2spewfoo/u2spewfoo.c: Fix compilation warnings. * src/snort.c: Check return of DAQ_Acquire in failopen thread see description. * src/dynamic-preprocessors/reputation/shmem/: shmem_config.h, shmem_mgmt.c, shmem_mgmt.h, src/sfutil/sfrt_flat_dir.c: - Disable timeout for shared memory readers. - Readers and writer updates their own active flags. - Update the entry value along with length update. * src/Makefile.am, src/decode.h, src/parser.c, src/parser.h, src/snort.c, src/snort.h, src/dynamic-preprocessors/reputation/reputation_config.c, src/dynamic-preprocessors/reputation/reputation_config.h, src/dynamic-preprocessors/reputation/spp_reputation.c, src/dynamic-preprocessors/reputation/spp_reputation.h, src/dynamic-preprocessors/reputation/shmem/shmem_common.h, src/dynamic-preprocessors/reputation/shmem/shmem_datamgmt.c, src/dynamic-preprocessors/reputation/shmem/shmem_datamgmt.h, src/dynamic-output/libs/Makefile.am, src/dynamic-output/libs/output_lib.c, configure.in, src/sfutil/sfrt.h, src/sfutil/sfrt_flat.c, src/sfutil/sfrt_flat.h, src/sfutil/sfrt_flat_dir.c, src/sfutil/sfrt_flat_dir.h, src/dynamic-plugins/sf_dynamic_plugins.c, src/dynamic-plugins/sf_dynamic_preprocessor.h, src/dynamic-plugins/sf_engine/sf_snort_packet.h, doc/: README.reputation, snort_manual.pdf, snort_manual.tex: - Reputation preprocessor updates to support zones and handle ingress/egress groups and zone zero. - Enforce default policy for reputation preprocessor. - Check for NULL when servicing the shared memory. - Update documents for white action configuration, manifest file for reputation Preprocessor. * rpm/snort.spec: Remove all of the dead cruft from snort.spec. * src/parser.c: Fix a parsing memory leak scenario by freeing the tokens on failure. * preproc_rules/decoder.rules: Update decoder rules to have more accurate names. Same alert, new name. * src/output-plugins/spo_unified2.c: Set would drop when interface not inline. * src/: dynamic-preprocessors/imap/snort_imap.c, dynamic-preprocessors/pop/snort_pop.c, dynamic-preprocessors/smtp/snort_smtp.c, sfutil/sf_email_attach_decode.c, sfutil/sf_email_attach_decode.h, doc/: README.SMTP, README.imap, README.pop, snort_manual.tex: SMTP/POP/IMAP decoding changes: - Change the memory allocation for decoding. Allocate only when we see attachments. Do not allocate at the beginning of the session. - Apply the decoding depths to attachments instead of all attachments in a session. - Alert when decoding fails and not when decoding depths are exceeded. - Reset decode bytes read only after processing the entire attachment. Attachments can span multiple packets. 2012-3-17 Steven Sturges Snort 2.9.2.2 * src/build.h: Updated to build 121. * src/preprocessors/HttpInspect/normalization/hi_norm.c: Fix HTTP URI normalization when URI has more than 2k slashes. * src/preprocessors/Stream5/snort_stream5_tcp.c: Fixed split fin-ack tracking and flush/free app data on reset when listener is in fin-wait-1, fin-wait-2, or closing state. * src/: encode.c, encode.h, snort.c, snort.h, Fix generation of response packets on fragmented IPv6 packet by using the frag reassembled packet to encode. * src/preprocessors/Stream5/snort_stream5_tcp.c: Fix logical byte count and remove unreachable code * src/dynamic-plugins/sf_engine/sf_snort_plugin_hdropts.c: Update to handle IPv6 traffic for processing of IP header options within .so rules. * src/preprocessors/Stream5/snort_stream5_tcp.c: Expand slam threshold to <= 4 and fix for non-reassembled sessions. * src/preprocessors/Stream5/snort_stream5_tcp.c: Check seq within window relative to window base. * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.c: Fix flow flags for single segment PDUs from PAF. * doc/: faq.pdf, faq.tex, snort_manual.pdf, snort_manual.tex: Remove references to deprecated servers. * src/dynamic-preprocessors/sip/sip_parser.c: Unknown method alert is generated only after verifying the packet is SIP. Don't generate alerts for a. multiple SIP messages within one UDP packet (140:17) and b. mismatched content length (140:18) simultaneously. * doc/: INSTALL, snort_manual.pdf, snort_manual.tex: Updates to the manual to fix formatting, clarify detection_filter, and remove obsolete configure options. Thanks to Larry Hughes, Eoin Miller, Beenph and Joshua Kinard for reading it! * doc/README.sip, doc/snort_manual.pdf, doc/snort_manual.tex, src/dynamic-preprocessors/sip/sip_config.c, src/dynamic-preprocessors/sip/sip_config.h, src/dynamic-preprocessors/sip/sip_dialog.c, src/dynamic-preprocessors/sip/sip_dialog.h, src/dynamic-preprocessors/sip/spp_sip.c, src/dynamic-preprocessors/sip/spp_sip.h, etc/gen-msg.map: Limit number of dialogs within a stream session. Thanks to Filip Valder for providing the information. * src/active.c: Allow repeated responses to non-TCP/UDP traffic. * src/: sfdaq.c, sfdaq.h, output-plugins/spo_unified2.c: Correctly log blocked flag in unified2 events when an interface is passive. * doc/: README.filters, snort_manual.pdf, snort_manual.tex: Update README & manual to document -1 as acceptable value for event_filter. * src/: snort.c: Add stats output to dirty pig shutdown. * src/: preprocessors/Stream5/stream5_common.c: Update initialization for stream_ip. * doc/snort_manual.pdf, src/byte_extract.c, src/util.h, src/dynamic-plugins/sf_engine/sf_snort_plugin_byte.c: Make byte extraction of strings only allow for positive values. * src/preprocessors/HttpInspect/client/hi_client.c: Check for paf_max before marking a packet as request body. * doc/: README.SMTP, snort_manual.pdf, snort_manual.tex, preproc_rules/preprocessor.rules, src/generators.h, src/dynamic-preprocessors/smtp/smtp_config.h, src/dynamic-preprocessors/smtp/smtp_util.c, src/dynamic-preprocessors/smtp/snort_smtp.c, src/dynamic-preprocessors/smtp/spp_smtp.c: Added SMTP preproc shutdown stats. Remove the decoding memcap exceeded alert and displaying this info instead. * src/dynamic-preprocessors/ftptelnet/: snort_ftptelnet.c, spp_ftptelnet.c: Update parsing for ftptelnet config. * src/dynamic-preprocessors/modbus/spp_modbus.c: Update to free the modbus session data. * src/: snort_bounds.h, preprocessors/HttpInspect/server/hi_server_norm.c: Update javascript normalization to call a safeboundsmemmove function when the src and dst buffers overlap. * src/preprocessors/HttpInspect/client/hi_client.c: Change the code to not look for POST data (while parsing method) when PAF is enabled and process request packets when the method is undefined. * src/dynamic-preprocessors/pop/: snort_pop.c, snort_pop.h: Decode data following +OK response without the octets string. * src/dynamic-preprocessors/dcerpc2/dce2_utils.h: Made macro in dcerpc2 preprocessor used for progressing through data more robust. * src/preprocessors/: snort_httpinspect.h, HttpInspect/client/hi_client.c, HttpInspect/server/hi_server.c: Eliminate false positives (no content-length or transfer-encoding) when chunk size spans across multiple packets. Thanks to Daniel Dallmann for reporting the issue. * src/preprocessors/Stream5/snort_stream5_tcp.c: Update handling of retransmitted segments overlapping the window on the left * src/preprocessors/HttpInspect/server/hi_server.c: Set the file_data to the raw HTTP response body (de-chunked/ normalized) when decompression fails due to false GZIP headers. Set the inspect_body flag after resetting the decompress_data flag to allow extraction of HTTP response body across packets when decompression fails entirely. Thanks to Eoin Miller for reporting this issue. * doc/: README.http_inspect, snort_manual.pdf, snort_manual.tex, src/preprocessors/: snort_httpinspect.c, snort_httpinspect.h: Remove the Max on the gzip memcap. Thanks to Eoin Miller for the request. * src/dynamic-preprocessors/dcerpc2/: dce2_co.c, dce2_paf.c, dce2_session.h, dce2_smb.c, dce2_smb.h, snort_dce2.c, snort_dce2.h: State tracking improvements to SMB processing in the dcerpc2 preprocessor when missing packets on a session. * tools/u2spewfoo/u2spewfoo.c: Tweaks to dump u2 files in the presence of certain errors. * src/encode.c: Fix overhead calculation to ensure sufficient buffer space for defragging a maximum length IP datagram regardless of encapsulations. * src/preprocessors/Stream5/snort_stream5_tcp.c: Fix false positives on 129:16. * src/preprocessors/Stream5/snort_stream5_tcp.c: Fix stream5 to not purge too early when normalizing streams. * src/decode.c: Remove redundant clearing of pointer in error case. Thanks to Josh Kinard for pointing out the error. * src/preprocessors/spp_normalize.c: Change normalizer priority to ensure ahead of frag3 regardless of conf ordering. * src/detection-plugins/sp_react.c, doc/README.active, doc/snort_manual.pdf, doc/snort_manual.tex: Don't allow more than one % in a user-defined HTML page used for react rule options. Thanks to Cleber S. Brandão for reporting the issue. * configure.in: Update configure script to correctly display 'Disable' help verbage for the --disable-xxx options. Thanks to Kungu Panda for pointing it out. * src/: plugbase.c, plugbase.h, snort.c, output-plugins/spo_alert_arubaaction.c, output-plugins/spo_alert_fast.c, output-plugins/spo_alert_full.c, output-plugins/spo_alert_prelude.c, output-plugins/spo_alert_syslog.c, output-plugins/spo_alert_test.c, output-plugins/spo_alert_unixsock.c, output-plugins/spo_csv.c, output-plugins/spo_database.c, output-plugins/spo_log_ascii.c, output-plugins/spo_log_null.c, output-plugins/spo_log_tcpdump.c, output-plugins/spo_unified.c, output-plugins/spo_unified2.c: Update unified2 output to rotate the unified2 file on reload. * src/dynamic-preprocessors/smtp/smtp_util.c: Truncate the trailing end of the email id when the rcpt to or mail from addresses are too long. * doc/snort_manual.tex, doc/README.GTP, src/: dynamic-plugins/sf_dynamic_plugins.c, util.c, util.h: Throttle the so rules memcap error message. 2012-1-17 16:16 Hui Cao Snort 2.9.2.1 All files: updated copyright to 2012 * src/build.h: pdated build number to 107 * src/preprocessors/Stream5/snort_stream5_tcp.c: Fixed building when -DREG_TEST not used with --enable-debug. Tweaked r_win_base initialization upon midstream pickup to work with tighter sequence number validation. Updated TCP session tracking to avoid requeuing retransmitted data Add tweaks for paf_max flushing of chunked http data * src/dynamic-preprocessors/reputation/shmem/: shmem_config.c, shmem_config.h, shmem_mgmt.c, shmem_mgmt.h: Avoided writer updating reader's zero segment pointer. Changed shared memory update timeout to a larger value. * src/generators.h, src/preprocessors/HttpInspect/event_output/hi_eo_log.c, src/preprocessors/HttpInspect/include/hi_eo_events.h, src/preprocessors/HttpInspect/utils/hi_paf.c, doc/README.http_inspect, etc/gen-msg.map, preproc_rules/preprocessor.rules: Added an alert on http/0.9 simple requests (119:32) * preproc_rules/: decoder.rules, preprocessor.rules: Bump a few rule rev's that were out of sync w/ VRT * src/preprocessors/Stream5/snort_stream5_tcp.c: Changed Warning -> WARNING Don't attempt to flush if the grinder failed when pruning a session * src/: preprocessors/Stream5/snort_stream5_tcp.c, preprocessors/Stream5/stream5_common.h, sfutil/test/unit_hacks.c: Auto-disable stream reassembly on paf abort if auto-enabled * src/: detection-plugins/sp_dsize_check.c, dynamic-preprocessors/dnp3/spp_dnp3.c, preprocessors/Stream5/snort_stream5_tcp.c, preprocessors/Stream5/stream5_paf.c: Fixed handling PAF flushing anomalies but purging afflicted segments * src/sfutil/: sfrt_dir.c, sfrt_flat_dir.c, sfrt_flat_dir.h: Fixed the wrong value of calculating memory allocated. Changed sfrt length field from char to uint8_t * src/: decode.c, dynamic-preprocessors/gtp/gtp_parser.c: Added checking invalid extension header length for GTPv1 * src/: preprocessors/stream_expect.c, profiler.h: Fixed some compiler warnings * src/: decode.c, dynamic-preprocessors/gtp/gtp_parser.c Added checking invalid extension header length * doc/: README.GTP, snort_manual.pdf, snort_manual.tex: Added a simple user case to the GTP document. * src/dynamic-preprocessors/modbus/modbus_decode.c: Fixed a couple errors in modbus request/response length checking. * etc/reference.config: Added 'msb' to reference.conf for Microsoft Bulletin url * src/detection-plugins/sp_flowbits.c: When same flowbit is defined both in default group and user specified group, that flowbit will be changed to specified group. * src/dynamic-preprocessors/dnp3/: dnp3_paf.c, dnp3_reassembly.c, spp_dnp3.c, spp_dnp3.h: Added #define statements for several "magic numbers" in DNP3 code * src/dynamic-preprocessors/dnp3/dnp3_reassembly.c: Fixed a bug where the DNP3 preprocessor would generate alerts for "reserved function" on valid DNP3 functions. * src/dynamic-preprocessors/dnp3/dnp3_roptions.c: Added parser errors for missing dnp3_func and dnp3_ind arguments. * src/: generators.h, preprocessors/HttpInspect/client/hi_client.c, preprocessors/HttpInspect/event_output/hi_eo_log.c, preprocessors/HttpInspect/include/hi_eo_events.h: Added a preprocessor alert to alert when a HTTP method being parsed is not a GET or a POST or not defined by the user. * src/preprocessors/HttpInspect/: client/hi_client.c, server/hi_server.c: Added checking bounds before unfolding. * Makefile.am, configure.in: Cleanup very dated rules files. * src/: snort.c, win32/WIN32-Includes/stdint.h: Don't add handlers signal values that aren't supported on Windows. * src/dynamic-preprocessors/reputation/reputation_config.c: Corrected the variable name called to create IP talbe. 2011-12-14 Ryan Jordan Snort 2.9.2 * src/build.h: updating build number to 78 * snort.8: Fixed spelling errors. Thanks to Neline van Ginkel for the report. * src/: snort.c, preprocessors/spp_perfmonitor.c: Perfmonitor "now" files are created after Snort drops privileges. * src/output-plugins/spo_unified2.c: Only log IPv6 extra data when the packet is IPv6. * src/preprocessors/HttpInspect/: server/hi_server.c, client/hi_client.c: Fixed unfolding of HTTP Headers across packet boundaries. Thanks to Jim Hranicky for reporting this issue on the RC build. * src/preprocessors/spp_httpinspect.c: HTTP Inspect should check for hi_swap_config in HttpInspectInit() only when snort is compiled with --enable-reload. Fixed build errors on Win32. * src/preprocessors/Stream5/snort_stream5_tcp.c: When pruning a session, don't attempt to flush if the grinder failed to decode a TCP header. Thanks to Jim Hranicky for reporting this issue on the RC build. 2011-11-23 Ryan Jordan Snort 2.9.2 RC * src/build.h: updating build number to 75 * src/preprocessors/spp_httpinspect.c: Fixed an issue with HTTP Inspect server conf reload (when the HTTP Inspect is turned on from off between a reload) * src/preprocessors/spp_stream5.c: Fixed a memory leak caused by initializing the expected channel more than once. * src/dynamic-preprocessors/dcerpc2/spp_dce2.c: Fixed a segfault during dcerpc2 startup when stream5 is not enabled. * src/preprocessors/spp_normalize.c: Added support to turn normalization off or on during a Snort reload. * src/dynamic-preprocessors/modbus/spp_modbus.c: Moved the check for truncated PDUs past the port check, to avoid false positives. * src/sfutil/bitop_funcs.h: Fixed an error in the allocation of flowbit groups, where bytes were interpreted as bits. * src/detection-plugins/sp_flowbits.c: Fixed a flowbits issue where the "isset" operation failed when there was only a single flowbit in a group. Fixed the error message logged when the same flowbit is added to two groups. * src/ipv6_port.h: * src/: dynamic-preprocessors/gtp/gtp_parser.c, dynamic-preprocessors/gtp/gtp_roptions.c, dynamic-preprocessors/ftptelnet/pp_ftp.c, dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, dynamic-preprocessors/reputation/reputation_config.c, sfutil/segment_mem.c, encode.c: Compiler warning cleanup. * doc/: README.reload, snort_manual.pdf, snort_manual.tex: Updated the reload documentation to mention the caveat that exists with reload and fail-open in OpenBSD when Snort is run on primary network interface. * src/dynamic-preprocessors/dnp3/: dnp3_reassembly.c, dnp3_reassembly.h, dnp3_roptions.c, spp_dnp3.c: Added support for multiple DNP3 PDUs in a single DNP3 payload. Fixed an issue where the DNP3 preprocessor only identified the minimum reserved address, instead of all reserved addresses. * src/dynamic-preprocessors/dnp3/spp_dnp3.h: Updated an incorrect minimum DNP3 memcap to match the documented minimum of 4144 bytes. * src/output-plugins/spo_unified2.c: Snort will fatal error when the user configures the same filename for options "alert_unified2" and "log_unified2". * src/sfutil/: sfrt.c, sfrt.h, sfrt_dir.c, sfrt_dir.h: Added the ability to delete entries in the sfrt table. * src/preprocessors/snort_httpinspect.c, src/preprocessors/spp_frag3.c, src/preprocessors/spp_normalize.c, src/preprocessors/spp_stream5.c, src/preprocessors/Stream5/snort_stream5_tcp.c, src/preprocessors/Stream5/stream5_common.c, src/dynamic-preprocessors/reputation/reputation_config.c, etc/gen-msg.map, src/detection-plugins/sp_flowbits.c, src/detection-plugins/sp_replace.c, src/output-plugins/spo_alert_sf_socket.c, src/decode.c, src/detect.c, src/generators.h, src/sfdaq.c, src/snort.c, src/tag.c, src/util.c, src/dynamic-plugins/sf_dynamic_plugins.c, src/sfutil/acsmx2.c, configure.in, src/dynamic-preprocessors/dnp3/spp_dnp3.c, src/target-based/sftarget_protocol_reference.c: * src/dynamic-preprocessors/dnp3/dnp3_roptions.c: Made the format of warning messages consistent. * src/dynamic-preprocessors/: dnp3/spp_dnp3.c, modbus/spp_modbus.c: Providing an empty port list now causes a fatal error. * src/dynamic-preprocessors/dnp3/spp_dnp3.h: Fixed reserved address check on big-endian machines. * src/preprocessors/Stream5/snort_stream5_tcp.c: Changed identification of TCP retransmits by comparing payloads instead of TCP checksums. * src/decode.h, src/dynamic-plugins/sf_engine/sf_snort_packet.h, src/dynamic-preprocessors/imap/snort_imap.c, src/dynamic-preprocessors/pop/snort_pop.c, src/dynamic-preprocessors/smtp/smtp_util.c, src/dynamic-preprocessors/smtp/snort_smtp.c, src/output-plugins/spo_unified2.c, src/preprocessors/snort_httpinspect.c, src/preprocessors/snort_httpinspect.h, src/preprocessors/spp_httpinspect.c, src/preprocessors/spp_stream5.c, src/preprocessors/stream_api.h, src/preprocessors/HttpInspect/include/hi_ui_config.h, src/sfutil/Unified2_common.h, tools/u2spewfoo/u2spewfoo.c: Enable logging of normalized JavaScript to unified2 when built without --enable-sourcefire. - Changed extra data logging to log packet-specific data (gzip/normalized) after each packet. - Updated u2spewfoo to read the normalized JavaScript extra data. * src/dynamic-preprocessors/dnp3/dnp3_reassembly.c: Fixed a bug where "dnp3_data" rules would not work if the content was broken up by CRCs or split across multiple DNP3 segments. As a result, DNP3 rules that inspect the DNP3 headers now require "rawbytes" to work correctly, as the DNP3 reassembly buffer is inspected by default. * etc/gen-msg.map, preproc_rules/preprocessor.rules, src/dynamic-preprocessors/dnp3/spp_dnp3.h: Removed DNP3 rule 145:5, and decremented the SIDs of rules 145:6 and 145:7. The old 145:5 was never able to be triggered. Updated references for rules 119:15 and 137:1. * rpm/snort.spec: Updated the RPM spec file to use wildcards for linking and installing preprocessors. Thanks to Tim Brigham for the suggestion. * src/detection_util.h: Increased the URI buffer size from 4096 to 8192 to normalize and detect longer URIs. * src/preprocessors/: spp_frag3.c, spp_stream5.c, Stream5/snort_stream5_tcp.c, Stream5/snort_stream5_udp.c: Change the printing function of tracker/session sizes (TcpSession/UdpSession/StreamLWSession/FragTarcker) from fprintf to LogMessage. Fix handling of "first" and "vista" policies in stream5 that, under certain circumstances with overlaps and gaps, could cause the stream5 segmentation list to get out of order. * doc/snort_manual.pdf, doc/snort_manual.tex, src/detection-plugins/sp_dsize_check.c: Enable the "dsize" rule option with rebuilt packets, if it is the start of a PDU. Thanks to Dave Bertouille for reporting this problem. * src/dynamic-preprocessors/modbus/modbus_decode.c: Added length checking for Modbus "Read File Record" and "Write File Record" requests. * src/output-plugins/spo_unified2.c, src/sfutil/Unified2_common.h, tools/u2spewfoo/u2spewfoo.c: Added new Unified2 event structs with extra application ID data. Updated u2spewfoo to read these fields. * src/detection-plugins/: sp_asn1_detect.c, sp_byte_check.c, sp_byte_jump.c, sp_isdataat.c: Allow rule evaluation to continue if the doe_ptr reaches the end of a buffer, but a negative offset brings it back in-bounds. Thanks again to Dave Bertouille for the suggestion. * src/target-based/sf_attribute_table.y: Allow empty attribute_value in attribute table. * configure.in, src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: Added Protocol-Aware Flushing support for FTP. * snort.8: Updated the man page to include more signals that have been used. Made some format changes, thanks to Markus Lude. * doc/Makefile.am: Fixed an error while running "make distcleancheck". * doc/snort_manual.pdf, doc/snort_manual.tex, src/win32/WIN32-Includes/config.h, configure.in, src/snort.c, src/snort.h, src/util.c, src/control/sfcontrol.c, src/target-based/sftarget_reader.c: Redefined default signals, and added support for signal customization. 2011-10-28 Ryan Jordan Snort 2.9.2 Beta * src/build.h: updating build number to 64 * src/preprocessors/: snort_httpinspect.c, HttpInspect/include/hi_ui_config.h, HttpInspect/server/hi_server.c, HttpInspect/server/hi_server_norm.c, HttpInspect/user_interface/hi_ui_config.c: * src/sfutil/: util_jsnorm.c, util_jsnorm.h: Updated the HTTP preprocessor to normalize HTTP responses that include javascript escaped data in their bodies. This expands Snort's coverage in detecting HTTP client-side attacks. See the Snort Manual and README.http_inspect for configuration details. * doc/README.modbus: * src/dynamic-preprocessors/modbus/: Makefile.am, modbus_decode.c, modbus_decode.h, modbus_paf.c, modbus_paf.h, modbus_roptions.c, modbus_roptions.h, sf_modbus.dsp, spp_modbus.c, spp_modbus.h: Added the Modbus preprocessor, which decodes the Modbus protocol and provides new rule options for some protocol fields. See the Snort Manual and README.modbus for more details. * doc/README.dnp3: * src/dynamic-preprocessors/dnp3/: Makefile.am, dnp3_map.c, dnp3_map.h, dnp3_paf.c, dnp3_paf.h, dnp3_reassembly.c, dnp3_reassembly.h, dnp3_roptions.c, dnp3_roptions.h, sf_dnp3.dsp, spp_dnp3.c, spp_dnp3.h: Added the DNP3 preprocessor, which decodes the DNP3 protocol and provides new rule options for some protocol fields. The preprocessor also performs reassembly of segmented DNP3 traffic. See the Snort Manual and README.dnp3 for more details. * doc/README.gtp: * src/decode.c: * src/dynamic-preprocessors/gtp/: Makefile.am, gtp_config.c, gtp_config.h, gtp_debug.h, gtp_parser.c, gtp_parser.h, gtp_roptions.c, gtp_roptions.h, sf_gtp.dsp, spp_gtp.c, spp_gtp.h Added a packet decoder and preprocessor for the GTP protocol. These support detecting attacks over GTP (GPRS Tunneling Protocol). See the Snort Manual and README.gtp for more details. * doc/faq.pdf, doc/faq.tex, src/Makefile.am, src/debug.c, src/smalloc.h, src/snort_debug.h, src/dynamic-plugins/sf_dynamic_common.h, src/dynamic-preprocessors/dcerpc2/dce2_paf.c, src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, src/dynamic-preprocessors/gtp/gtp_debug.h, src/dynamic-preprocessors/sip/sip_debug.h, src/parser/IpAddrSet.c, src/preprocessors/HttpInspect/utils/hi_paf.c, src/preprocessors/Stream5/stream5_paf.c: Expanded the debug bits from 32 to 64 bits. * src/preprocessors/: spp_stream5.c, Stream5/snort_stream5_icmp.c, Stream5/snort_stream5_icmp.h, Stream5/snort_stream5_ip.c, Stream5/snort_stream5_ip.h, Stream5/snort_stream5_udp.c, Stream5/snort_stream5_udp.h: Cleaned up application data for non-TCP sessions after a block or timeout. * src/preprocessors/spp_sfportscan.c: Negative memcap numbers are no longer allowed. * src/preprocessors/HttpInspect/server/hi_server.c: HTTP responses with incorrect status messages are now inspected. * src/preprocessors/Stream5/stream5_paf.c: Fixed PAF callback registration during Snort reload. * src/parser.c: Fixed crash when setting HOME_NET to an empty variable. Thanks to Elof for reporting this issue. * src/preprocessors/spp_normalize.c: Don't register the packet callback if Snort is not inline. Fixed a crash in the normalizer during Snort reload. * src/: sfdaq.c, sfdaq.h, snort.c, snort.h, util.c: Fixed a possible segfault upon fatal error during Snort reload. * src/win32/WIN32-Prj/snort_installer.nsi: Updated Windows project files for new preprocessors. * doc/: snort_manual.pdf, snort_manual.tex: Updated the Snort manual for new features. Updated the names of contributors to match those found on snort.org. Updated the 'config cs_dir' path to be relative to pid-path. Described the FlowIP CSV file format. Thanks to Eoin Miller for pointing out the lack of documentation. * src/preprocessors/: perf-base.c, perf-base.h, perf.c, perf.h, spp_frag3.c, spp_frag3.h, Stream5/snort_stream5_tcp.c: Added frag3 and stream5 memory usage to perfmon output. * src/control/sfcontrol.c: Added counters to bypass the work queue mutex when nothing is queued. Cleaned up compiler warnings. * src/preprocessors/HttpInspect/client/hi_client.c: When the same IP is parsed multiple times for XFF/True-client-IP , the duplicate entries are freed from memory. * src/preprocessors/: stream_expect.c, spp_stream5.c, stream_api.h, stream_expect.h, Stream5/snort_stream5_session.c, Stream5/snort_stream5_session.h, Stream5/stream5_common.h: Changed instances of "char" to "uint8_t" when dealing with protocol numbers, preventing a potential issue when Snort supports protocols > 128. Thanks to Joshua Kinard for providing a patch for this issue. * src/detection-plugins/sp_react.c: Added a content-length header to the react responses. * src/: decode.h, dynamic-plugins/sf_engine/sf_snort_packet.h, dynamic-preprocessors/imap/snort_imap.c, dynamic-preprocessors/pop/snort_pop.c, dynamic-preprocessors/smtp/smtp_config.h, dynamic-preprocessors/smtp/smtp_util.c, dynamic-preprocessors/smtp/smtp_util.h, dynamic-preprocessors/smtp/snort_smtp.c, dynamic-preprocessors/smtp/snort_smtp.h, dynamic-preprocessors/smtp/spp_smtp.c, output-plugins/spo_unified2.c, preprocessors/snort_httpinspect.c, preprocessors/snort_httpinspect.h, preprocessors/spp_httpinspect.c, preprocessors/spp_stream5.c, preprocessors/stream_api.h, preprocessors/HttpInspect/include/hi_ui_config.h, preprocessors/Stream5/snort_stream5_tcp.c, preprocessors/Stream5/snort_stream5_tcp.h, preprocessors/Stream5/stream5_common.h: Reduced the memory usage per TCP session for extra data event logging. * src/dynamic-preprocessors/sip/spp_sip.c: Changed a description in the SIP exit stats. * configure.in, src/snort.c, src/util.c, src/target-based/sftarget_reader.c: Where possible, sigaction() is used instead of signal() to establish signal handlers. * src/util.c: Fixed an error in the calculation of dropped packets. Thanks to Will Metcalf for identifying the issue. * src/preprocessors/: perf-flow.c, perf-flow.h: Fixed a bug where packets longer than 4500 bytes were not logged in the perfmon flow stats. * src/: active.c, decode.c, decode.h, encode.c, parser.c, sf_protocols.h, snort.c: Fix PPPoE support and active responses to ICMP. Thanks to Eric Lauzon for identifying an issue with PPPoE traffic. * etc/gen-msg.map, preproc_rules/preprocessor.rules, src/generators.h, src/preprocessors/HttpInspect/client/hi_client.c, src/preprocessors/HttpInspect/event_output/hi_eo_log.c, src/preprocessors/HttpInspect/include/hi_client.h, src/preprocessors/HttpInspect/include/hi_eo_events.h: Added new preprocessor alerts: 1) Both true-client-ip and XFF headers exist in single packet 2) Multiple client-ips with different values in the same session * etc/gen-msg.map: Fixed an error with incorrect SID numbers for some SMTP preprocessor rules. Thanks to Eric Olsen for identifying the issue. * src/: decode.h, detect.c, encode.c, encode.h, plugbase.c, plugbase.h, snort.c, snort.h, detection-plugins/detection_options.c, dynamic-plugins/sf_dynamic_plugins.c, dynamic-plugins/sf_dynamic_preprocessor.h, dynamic-plugins/sf_engine/sf_snort_packet.h, dynamic-preprocessors/dcerpc2/snort_dce2.c, dynamic-preprocessors/sdf/spp_sdf.c, output-plugins/spo_alert_fast.c, preprocessors/spp_frag3.c, preprocessors/spp_rpc_decode.c, preprocessors/spp_sfportscan.c, preprocessors/stream_api.h, preprocessors/Stream5/snort_stream5_tcp.c, preprocessors/Stream5/stream5_common.c: Refactored packet flags. Added new packet flags for raw in-order stream segment discrimination. * src/preprocessors/snort_httpinspect.c: Fixed an issue where gzip logging code misinterpreted the data being passed to it. Increased max_method_len to 256. Thanks to rmkml for identifying the issue. * src/: preprocessors/spp_rpc_decode.c, dynamic-preprocessors/dcerpc2/dce2_roptions.c, dynamic-preprocessors/dcerpc2/dce2_smb.c: Fixed compiler warnings. * src/sfutil/bnfa_search.c: Fixed code defined by #ifdef ALLOW_NFA_FULL to compile and run. Thanks to Brian Hwang for reporting the issue. * src/: dynamic-plugins/sf_dynamic_plugins.c, dynamic-plugins/sf_dynamic_preprocessor.h, dynamic-plugins/sp_dynamic.h, dynamic-preprocessors/reputation/reputation_config.c, dynamic-preprocessors/reputation/shmem/shmem_datamgmt.c, dynamic-preprocessors/reputation/shmem/shmem_datamgmt.h: The paths to whitelist & blacklist files are now relative to the location of snort.conf. * src/preprocessors/Stream5/snort_stream5_session.c: Don't prune blocked sessions if pruning for memcap. * src/preprocessors/spp_stream5.c: Fixed session data lookup for meta data messages. * etc/: sf_rule_options, sf_rule_validation.conf: Updated rule validation files with new rule options. * configure.in, doc/INSTALL, doc/README.ARUBA, doc/README.database, doc/README.ipv6, doc/snort_manual.tex, src/output-plugins/spo_alert_arubaaction.c, src/output-plugins/spo_alert_prelude.c, src/output-plugins/spo_database.c: Added deprecation warnings for database, alert_aruba_action, and alert_prelude output plugins. These output plugins are considered deprecated with this release and will be removed in Snort 2.9.3. * src/: plugbase.c, plugbase.h, preprocids.h, profiler.c, sfdaq.c, sfdaq.h, snort.c, snort.h, dynamic-plugins/sf_dynamic_plugins.c, dynamic-plugins/sf_dynamic_preprocessor.h, preprocessors/spp_stream5.c, preprocessors/stream_api.h, preprocessors/Stream5/snort_stream5_icmp.c, preprocessors/Stream5/snort_stream5_ip.c, preprocessors/Stream5/snort_stream5_session.c, preprocessors/Stream5/snort_stream5_session.h: Added API and DAQ functions to get flow start and end events directly from the DAQ when no stream data is available. * src/sfdaq.c: Prevent underflow when calculating outstanding packets. Thanks to Hussein Bahaidarah for reporting this issue. Don't unload daq modules if --disable-dlclose was a configure option. * src/: active.c, dynamic-plugins/sf_dynamic_plugins.c, dynamic-plugins/sf_dynamic_preprocessor.h: Snort dynamic API changes to inject response packets. 2011-10-20 Ryan Jordan Snort 2.9.1.2 * configure.in, rpm/snort.spec, src/build.h, src/win32/WIN32-Includes/config.h, src/win32/WIN32-Prj/snort_installer.nsi: Incremented version numbers to Snort 2.9.1.2, Build 84. * src/preprocessors/snort_httpinspect.c, src/sfutil/util_utf.c: Fixed an issue where Snort would sometimes stop processing traffic in a persistent HTTP 1.1 connection with a UTF-32 encoded response followed by a UTF-16 encoded response. 2011-10-05 Ryan Jordan Snort 2.9.1.1 * src/decode.c: Fixed decode.c to allow building with --enable-debug. * src/: dynamic-plugins/sf_engine/sf_decompression.c, dynamic-plugins/sf_engine/sf_decompression.h, preprocessors/snort_httpinspect.h, preprocessors/HttpInspect/server/hi_server.c: Fixed http_inspect decompression and decompression API to decompress both raw and zlib deflated data. Support locating utf charset when spaces are present. * src/: preprocessors/HttpInspect/server/hi_server_norm.c, sfutil/util_utf.h: Added "Byte Order Mark" support for unicode in http_inspect. * src/detection-plugins/sp_urilen_check.c: Fixed potential false positives when using urilen detection option. * src/preprocessors/Stream5/stream5_paf.c: Fixed flushing beyond "paf_max". Verify paf configuration before enabling. * src/preprocessors/Stream5/snort_stream5_tcp.c: Free application and protocol state when a session is blocked. Ensure that seglist_next is NULL after being freed. * src/dynamic-preprocessors/smtp/smtp_util.c: Fixed an issue with SMTP logging while running in inline mode. * src/dynamic-preprocessors/reputation/Makefile.am, src/dynamic-preprocessors/reputation/reputation_config.c, src/dynamic-preprocessors/reputation/reputation_config.h, src/dynamic-preprocessors/reputation/spp_reputation.c, src/dynamic-preprocessors/reputation/spp_reputation.h, src/Makefile.am, src/idle_processing.c, src/idle_processing.h, src/idle_processing_funcs.h, src/plugbase.c, src/plugbase.h, src/snort.c, src/snort.h, src/util.c, src/util.h, src/dynamic-examples/Makefile.am, src/dynamic-preprocessors/reputation/shmem/shmem_config.c, src/dynamic-preprocessors/reputation/shmem/shmem_config.h, src/dynamic-preprocessors/reputation/shmem/shmem_datamgmt.h, src/dynamic-preprocessors/reputation/shmem/shmem_lib.c, src/dynamic-preprocessors/reputation/shmem/shmem_mgmt.c, src/dynamic-preprocessors/reputation/shmem/shmem_mgmt.h, src/control/Makefile.am, src/control/sfcontrol.c, src/control/sfcontrol.h, src/control/sfcontrol_funcs.h, src/dynamic-preprocessors/reputation/shmem/sflinux_helpers.c, src/dynamic-preprocessors/reputation/shmem/sflinux_helpers.h, src/dynamic-preprocessors/reputation/shmem/shmem_common.h, src/dynamic-preprocessors/reputation/shmem/shmem_datamgmt.c, src/dynamic-preprocessors/reputation/shmem/shmem_lib.h, src/sfutil/Makefile.am, src/sfutil/segment_mem.c, src/sfutil/segment_mem.h, src/sfutil/sfrt_flat.c, src/sfutil/sfrt_flat.h, src/sfutil/sfrt_flat_dir.c, src/sfutil/sfrt_flat_dir.h, src/dynamic-preprocessors/Makefile.am, tools/control/Makefile.am, tools/control/README.snort_control, tools/control/sfcontrol.c, src/dynamic-plugins/sf_dynamic_plugins.c, src/dynamic-plugins/sf_dynamic_preprocessor.h, configure.in, tools/Makefile.am: - Added support for shared memory between Snort processes. This is used in the IP Reputation preprocessor to share a single copy of IP whitelists & blacklists. - Added a control channel, so that commands may be issued to a running Snort process by way of a Unix socket. * src/preprocessors/HttpInspect/utils/hi_paf.c: Ensure HTTP 1.1 responses without length indicators (e.g. 304) are flushed at the end of the headers. Preprocessor rule 120:8 is fired at end of headers if content-length and transfer-encoding: chunked are not present, but not for response codes 1XX, 204, 304. * doc/README.reputation, doc/snort_manual.pdf, doc/snort_manual.tex: Updated Snort documentation, added documentation for Shared Memory and the Control Socket. * src/: dynamic-preprocessors/reputation/sf_reputation.dsp, dynamic-preprocessors/sf_dynamic_initialize/sf_dynamic_initialize.dsp, win32/WIN32-Includes/stdint.h, win32/WIN32-Prj/snort.dsp, win32/WIN32-Prj/snort.dsw: Updated Win32 build files. 2011-08-23 Ryan Jordan Snort 2.9.1 * src/build.h: Updated build number to 71. * etc/gen-msg.map, preproc_rules/decoder.rules, src/decode.c, src/decode.h, src/generators.h, src/snort.c, src/dynamic-plugins/sf_engine/sf_snort_packet.h: Fixed an issue with decoding large numbers of IPv6 extension headers. Added rule 116:456 to safeguard against too many IPv6 extension headers. Thanks to Martin Sch�tte for reporting the issue. * src/detection-plugins/sp_urilen_check.c, src/detection-plugins/sp_urilen_check.h: Fixed the urilen rule option to look at reassembled packets. Added an extra parameter to specify whether to check raw or normalized uri buffer. Will check raw uri buffer by default. * src/: dynamic-preprocessors/dcerpc2/sf_dce2.dsp, dynamic-preprocessors/dns/sf_dns.dsp, dynamic-preprocessors/ftptelnet/sf_ftptelnet.dsp, dynamic-preprocessors/imap/sf_imap.dsp, dynamic-preprocessors/isakmp/sf_isakmp.dsp, dynamic-preprocessors/pop/sf_pop.dsp, dynamic-preprocessors/reputation/sf_reputation.dsp, dynamic-preprocessors/sdf/sf_sdf.dsp, dynamic-preprocessors/sip/sf_sip.dsp, dynamic-preprocessors/smtp/sf_smtp.dsp, dynamic-preprocessors/ssh/sf_ssh.dsp, dynamic-preprocessors/ssl/sf_ssl.dsp, win32/WIN32-Prj/sf_engine.dsp: Fixed a bug where the sensitive_data preprocessor gave an error while loading sensitive data rules. * doc/README.http_inspect, etc/gen-msg.map, preproc_rules/preprocessor.rules, src/generators.h, src/preprocessors/snort_httpinspect.c, src/preprocessors/HttpInspect/event_output/hi_eo_log.c, src/preprocessors/HttpInspect/include/hi_eo_events.h, src/preprocessors/HttpInspect/utils/hi_paf.c: Added two HTTP Inspect preprocessor rules: 119:28 - post w/o content-length or transfer-encoding: chunked 120:8 - message with invalid content-length or chunk size * src/preprocessors/spp_httpinspect.c: Fixed a bug where Snort wouldn't reload, giving the error that "Changing decompress_depth requries a restart". * etc/gen-msg.map: Commented out four rules from gen-msg.map, 133:44 through 133:47, because they were not yet implemented. * preproc_rules/preprocessor.rules: Added a CVE reference for Rule 119:19. Added a reference to SMTP preprocessor rule 124:4. Added a preprocessor rule, 125:9, for an FTPTelnet preprocessor alert that was missing the corresponding rule. * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.c: PAF tweak for single-segment full PDUs matching only-stream * src/snort.c: Fixed a bug where Snort wouldn't reload on SIGHUP with OpenBSD. Set default paf_max to 16K. * doc/: README.reputation, snort_manual.pdf, snort_manual.tex: Added a use case in the IP Reputation preprocessor documentation. * src/: dynamic-preprocessors/reputation/reputation_config.c, dynamic-preprocessors/reputation/sf_reputation.dsp, win32/WIN32-Prj/snort.dsw, win32/WIN32-Prj/snort_installer.nsi: Fixed the IP Reputation preprocessor so that it would build on Windows. * src/preprocessors/HttpInspect: client/hi_client.c, include/hi_client.h, server/hi-server.c, utils/hi_paf.c: Support up to full 32-bit content-lengths * src/preprocessors/Stream5/stream5_paf.c: Fixed compilation with the options "--disable-target-based --enable-paf". * src/preprocessors/Stream5/snort_stream5_tcp.c: Fixed an error in IDS mode when segments overlap and the sequence number wraps. * tools/u2spewfoo/Makefile.am: Added the u2spewfoo Windows project file to the Snort source tarball. 2011-07-19 Ryan Jordan Snort 2.9.1 RC * doc/README.sip, doc/snort_manual.pdf, doc/snort_manual.tex, preproc_rules/preprocessor.rules, src/dynamic-preprocessors/sip/sip_parser.c, src/dynamic-preprocessors/sip/spp_sip.h, etc/gen-msg.map: Added three new SIP preprocessor alerts. * src/preprocessors/Stream5/: snort_stream5_tcp.c, stream5_paf.c, stream5_paf.h: Allow multiple preprocs to scan for PDUs on the same port. This fixes a problem with DCE autodetect using the same ports as HTTP. * src/build.h: Updated build number to 63. * src/: fpcreate.c, log.c, detection-plugins/sp_byte_extract.c, detection-plugins/sp_tcp_win_check.c, dynamic-plugins/sf_engine/sf_snort_plugin_content.c, dynamic-plugins/sf_engine/sf_snort_plugin_pcre.c, preprocessors/spp_normalize.c: Fixed some compiler warnings. * src/: detection-plugins/detection_options.c, detection-plugins/sp_flowbits.h, dynamic-plugins/sf_engine/sf_snort_detection_engine.c: Only set/clear/toggle/unset a flowbit when all of the rule matches, including the IPs and Ports. Thanks to Eoin Miller for reporting the issue. * src/dynamic-preprocessors/: Makefile.am, dcerpc2/Makefile.am, dns/Makefile.am, ftptelnet/Makefile.am, imap/Makefile.am, pop/Makefile.am, reputation/Makefile.am, rzb_saac/Makefile.am, sdf/Makefile.am, sip/Makefile.am, smtp/Makefile.am, ssh/Makefile.am, ssl/Makefile.am: Fixed dynamic preprocesor Makefiles so that they can be built in parallel. * doc/README.http_inspect, doc/snort_manual.pdf, doc/snort_manual.tex, etc/gen-msg.map, preproc_rules/preprocessor.rules, src/generators.h, src/preprocessors/snort_httpinspect.c, src/preprocessors/snort_httpinspect.h, src/preprocessors/HttpInspect/client/hi_client.c, src/preprocessors/HttpInspect/event_output/hi_eo_log.c, src/preprocessors/HttpInspect/include/hi_eo_events.h, src/preprocessors/HttpInspect/include/hi_ui_config.h, src/preprocessors/HttpInspect/include/hi_util.h, src/preprocessors/HttpInspect/user_interface/hi_ui_config.c, src/sfutil/util_unfold.c: Added a new HTTP Inspect preprocessor rule, GID 119 SID 26. This rule checks for 200+ whitespaces in a folded header line from an HTTP request. A new config option was added to configure the allowable amount whitespace. Added a new configuration option to http_inspect server configuration: "small_chunk_length { }", with preprocessor rules for both client and server. Consecutive chunk lengths less than or equal to will cause an event to be generated. See README.http_inspect for more information. * src/: dynamic-preprocessors/dcerpc2/sf_dce2.dsp, dynamic-preprocessors/dns/sf_dns.dsp, dynamic-preprocessors/ftptelnet/sf_ftptelnet.dsp, dynamic-preprocessors/imap/sf_imap.dsp, dynamic-preprocessors/isakmp/sf_isakmp.dsp, dynamic-preprocessors/sdf/sf_sdf.dsp, dynamic-preprocessors/sf_dynamic_initialize/sf_dynamic_initialize.dsp, dynamic-preprocessors/sip/sf_sip.dsp, dynamic-preprocessors/smtp/sf_smtp.dsp, dynamic-preprocessors/ssh/sf_ssh.dsp, dynamic-preprocessors/ssl/sf_ssl.dsp, win32/WIN32-Prj/sf_engine.dsp, win32/WIN32-Prj/sf_engine_initialize.dsp, win32/WIN32-Prj/sf_testdetect.dsp, win32/WIN32-Prj/snort.dsp: Fixed the Win32 build to (1) not use .pch, and (2) correct sed patterns on ipv6_port.h. * src/output-plugins/spo_alert_sf_socket.c: Fixed a problem where Snort's generic IP address structure was being sent by the socket output plugin. The output plugin now only generates events for IPv4 packets, and is guaranteed to use uint32_t IPv4 addresses for interoperability. * src/sfutil/: sfrt.c, sfrt.h: Optimized some memory usage. * configure.in: Add check for pkg-config and provide instructions to get it if pkg-config is not installed. * src/preprocessors/Stream5/: snort_stream5_tcp.c, stream5_common.h: Show single segment PAF packets and only short-circuit at correct sequence. When aborting PAF, flush at paf_max. Tweaked retransmission check to use actual sequence numbers instead of the adjusted sequence numbers. Changed the pseudo-random flush point after each flush. * src/snort.c: Fixed a compilation error when active response is disabled. * src/snort.h: Fixed a bug where Snort wouldn't daemonize on OpenBSD if the process was running as root. Thanks to Olaf Schreck for reporting this issue. * src/preprocessors/: perf-base.c, perf-base.h, perf-event.c, perf-event.h, perf-flow.c, perf-flow.h, perf.c, perf.h, spp_perfmonitor.c: Split out Perfmon submodule Init and Reset, so that everything is initialized when the Perfmonitor preprocessor is initialized. Previously, some data was initialized on the first packet. * src/detection-plugins/sp_tcp_flag_check.c: Fixed a couple spots where the "1" and "2" flags weren't renamed to "C" and "E". Thanks to Joshua Kinard for reporting the issue and supplying a patch. * doc/README.sip, doc/snort_manual.pdf, doc/snort_manual.tex, src/dynamic-preprocessors/sip/sip_parser.c, src/dynamic-preprocessors/sip/spp_sip.h, preproc_rules/preprocessor.rules, etc/gen-msg.map: Added a new SIP preprocessor alert for missing content type headers. Fixed an issue where the SIP preprocessor checked for Stream5 even if the SIP preprocessor was disabled. * etc/unicode.map: Updated unicode.map to match the unicode standard on Windows 7 SP1. * etc/snort.conf: Sync'ed to VRT's latest snort.conf. * src/: decode.c, detect.c: Tweaked the preprocessing loop to bypass app preprocs if no app data. * src/sfutil/sf_ip.c, src/sfutil/sf_ip.h, src/sfutil/sfrt_dir.c, src/dynamic-preprocessors/reputation/Makefile.am, src/dynamic-preprocessors/reputation/reputation_config.h, src/dynamic-preprocessors/reputation/reputation_utils.c, src/dynamic-preprocessors/reputation/sf_reputation.dsp, src/dynamic-preprocessors/reputation/spp_reputation.c, src/dynamic-preprocessors/reputation/spp_reputation.h, src/dynamic-preprocessors/reputation/reputation_config.c, src/dynamic-preprocessors/reputation/reputation_debug.h, src/dynamic-preprocessors/reputation/reputation_utils.h, doc/README.reputation, doc/Makefile.am, doc/snort_manual.pdf, doc/snort_manual.tex, preproc_rules/preprocessor.rules, src/dynamic-preprocessors/Makefile.am, configure.in, src/preprocids.h, etc/gen-msg.map: Added the IP Reputation preprocessor. This preprocessor provides the ability to whitelist and blacklist packets based on IP addresses. See README.reputation for more information. * src/: sf_types.h, dynamic-plugins/sf_dynamic_plugins.c, dynamic-preprocessors/dcerpc2/Makefile.am, dynamic-preprocessors/dcerpc2/dce2_config.c, dynamic-preprocessors/dcerpc2/dce2_debug.h, dynamic-preprocessors/dcerpc2/dce2_paf.c, dynamic-preprocessors/dcerpc2/dce2_paf.h, dynamic-preprocessors/dcerpc2/sf_dce2.dsp, dynamic-preprocessors/dcerpc2/snort_dce2.c: Added protocol-aware flushing support for the dcerpc2 preprocessor. * src/dynamic-plugins/sf_convert_dynamic.c: Added the ability to convert shared object rules that use the preprocessor rule option. * src/preprocessors/: snort_httpinspect.c, spp_httpinspect.c, HttpInspect/include/hi_paf.h, HttpInspect/utils/hi_paf.c, Stream5/snort_stream5_tcp.c: Don't enable paf unless stream ports configured for the given direction; add "(PAF)" to http inspect ports output to indicate when enabled; and only register port for given direction if corresponding flow depth is set. Support full 32-bit content-lengths and chunk sizes, and flush/abort when exceeded. * doc/README.SMTP, doc/snort_manual.tex, src/dynamic-preprocessors/smtp/smtp_config.h, src/dynamic-preprocessors/smtp/smtp_util.c, src/dynamic-preprocessors/smtp/snort_smtp.c, src/dynamic-preprocessors/smtp/snort_smtp.h, src/dynamic-preprocessors/smtp/spp_smtp.c: Fixed performance issue: allocate the buffers used for filename, mailfrom and rcptto logging using mempool ('memcap' used to allocate the mempool). Added a fatal error when b64_decode_depth is used with enable_mime_decoding. 2011-06-13 Ryan Jordan Snort 2.9.1 Beta * configure.in: Updates to configure.in. - Fix zlib checks to use correctly named variable for checking zlib header and library existence. - Enable IPv6 by default in builds. Can use --disable-ipv6 to turn it off. using --enable-zlib, configure should fail. snort -V should show IPv6 by default and VRT config should load without modification. - Added a new option, "--enable-large-pcap", which allows Snort to read pcap files that are larger than 2 GB. - Changed the default ./configure options to match the requirements for the bundled snort.conf * doc/: INSTALL, README.imap, README.pop, README.SMTP, README.stream5, README.sip, README.tag, README.http_inspect, README.counts, README.normalize, snort_manual.pdf, snort_manual.tex: Updated documentation for Snort 2.9.1: - Added documentation for new SIP, POP and IMAP preprocessors - Updated README.stream5 with documentation for Protocol Aware Flushing (PAF) - Updated README.http_inspect with memcap information, clarified "http_cookie" information, and documentation for "log_uri" and "log_hostname". - Fixed a typo in README.counts - Updated "byte_extract" section to reflect syntax changes - Improved the explanation of "max_queued_events" - Added documentation for the ESP decoder, which is now configurable - Improved the explanation of "rawbytes" - Fixed an incorrect example in README.tag. * etc/snort.conf: Synced snort.conf with VRT's latest version. Added configurations for new preprocessors. * preproc_rules/: decoder.rules, preprocessor.rules Added new preprocessor rules for SIP, SMTP, POP, and IMAP. Added decoder rules 116:453, 116:454, and 116:455. These rules were formerly covered by VRT rules. * src/build.h: Updated build number to 46 * src/decode.c: TCP and UDP decoder rules that require a fully-decoded packet will only fire if the checksum is correct and the port number is not ignored. ESP decoding is now configurable, and off by default. The "config enable_decode_oversized_alerts" option now applies to packets where the UDP header claims there is more data than actually exists. The Teredo decoder now only processes packets in the Teredo prefix (2001:0000::/32) or the link-local prefix (fe80::/16). * src/detection-plugins/sp_cvs.c: Fixed a false positive in the CVS detection plugin. * doc/snort_manual.tex, src/detection-plugins/sp_byte_extract.c: Made some changes to the byte_extract syntax: - Writing "string" without a number type defaults to decimal. - The "string" and "hex/dec/oct" options are now independent of each other, like in byte_test and byte_jump. You can write "string,dec", "hex,string", "string,relative,oct", etc. - Specifying one of "hex", "dec", and "oct" without using "string" results in an error. - byte_extract options can no longer be delimited by spaces. This does not affect "align " or "multiplier ". * src/: parser.c, util.c, util.h, detection-plugins/sp_base64_decode.c, dynamic-plugins/sf_dynamic_plugins.c, dynamic-plugins/sf_dynamic_preprocessor.h, dynamic-plugins/sp_dynamic.c, dynamic-preprocessors/smtp/smtp_util.c, preprocessors/HttpInspect/client/hi_client.c, preprocessors/HttpInspect/server/hi_server.c, sfutil/sf_base64decode.c, sfutil/sf_base64decode.h: Changes include the following: - Attempt dechunkind only when transfer-encoding: chunked is present. - Override the content length with transfer encoding - SnortStrcasestr uses slen now. - unfolding : trim spaces when required. * src/: pcap_pkthdr32.h, preprocessors/spp_frag3.c, preprocessors/Stream5/snort_stream5_tcp.c, preprocessors/Stream5/stream5_common.h, sfutil/sf_ipvar.c, sfutil/sf_ipvar.h, sfutil/sf_vartable.c: Update Frag3/Stream5 to print bound addresses, better descriptsions of detect anomalies and port lists. - Updated Frag3/Stream5 to print bound addresses for IPv6 enabled builds - Updated Frag3 to print meaningful detect anomalies configuration - Updated Stream5 to print that there are more ports than those printed. * src/dynamic-plugins/sf_engine/: Makefile.am, sf_decompression.c, sf_decompression.h, sf_snort_detection_engine.c, sf_snort_plugin_api.h: Added a Decompression API that wraps Zlib for use with dynamic plugins. See sf_decompression.h for more details. * src/: fpcreate.c, fpdetect.c, treenodes.h: Update pattern matcher and sort functions to correctly sort by priority as well as implement sorting by content_length (which was never done with 2.8.2 addition of rule option tree). Added a warning when max-pattern-len is defined twice. Packets will no longer be tagged or logged if they are filtered or passed. * src/preprocessors/Stream5: Ensured that reassembly doesn't require packet dropping in IPS mode. The message "additional ports configured but not printed" is only printed when that is actually the case. * src/snort.c: fix output of filename / shutdown alerts sequence when iterating over multiple pcaps with --pcap-show --pcap-reset and console alerts (eg -A cmg or -A console:test). Fixed an issue with reloading Snort while the default output options were used. When reading several pcap files with --pcap-dir, Snort will move on to the next file if one fails to load. * src/output-plugins/spo_alert_full.c: Update alert_full to print rule references, regardless of whether there is TCP/UDP/etc. * src/output-plugins/spo_log_tcpdump.c: convert DLT_IPV{4,6} to DLT_RAW for compatibility with libpcap 1.0.0 fix 'mixed decls and code' compiler warning * src/: decode.h, detect.c, detection_util.c, detection_util.h, fpcreate.c, fpdetect.c, log.c, log_text.c, parser.h, plugbase.c, rule_option_types.h, detection-plugins/Makefile.am, detection-plugins/detection_options.c, detection-plugins/sp_base64_data.c, detection-plugins/sp_byte_check.c, detection-plugins/sp_byte_extract.c, detection-plugins/sp_byte_jump.c, detection-plugins/sp_file_data.c, detection-plugins/sp_ftpbounce.c, detection-plugins/sp_isdataat.c, detection-plugins/sp_pattern_match.c, detection-plugins/sp_pcre.c, detection-plugins/sp_pkt_data.c, detection-plugins/sp_pkt_data.h, dynamic-plugins/sf_convert_dynamic.c, dynamic-plugins/sf_dynamic_common.h, dynamic-plugins/sf_dynamic_define.h, dynamic-plugins/sf_dynamic_engine.h, dynamic-plugins/sf_dynamic_plugins.c, dynamic-plugins/sf_dynamic_preprocessor.h, dynamic-plugins/sp_dynamic.c, dynamic-plugins/sp_dynamic.h, dynamic-plugins/sf_engine/sf_snort_detection_engine.c, dynamic-plugins/sf_engine/sf_snort_packet.h, dynamic-plugins/sf_engine/sf_snort_plugin_api.c, dynamic-plugins/sf_engine/sf_snort_plugin_content.c, dynamic-plugins/sf_engine/sf_snort_plugin_pcre.c, dynamic-preprocessors/ftptelnet/pp_ftp.c, dynamic-preprocessors/ftptelnet/pp_telnet.c, dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, dynamic-preprocessors/smtp/smtp_util.c, dynamic-preprocessors/smtp/snort_smtp.c, dynamic-preprocessors/smtp/snort_smtp.h, preprocessors/snort_httpinspect.c, preprocessors/snort_httpinspect.h, preprocessors/spp_rpc_decode.c, preprocessors/HttpInspect/server/hi_server.c, preprocessors/HttpInspect/server/hi_server_norm.c, preprocessors/Stream5/snort_stream5_tcp.c: The "file_data" and "base64_data" rule options now set the buffer for any rule options that follow them. This applies to both relative and non-relative rule options. The detection code now uses 3 separate buffers: - "Alt Detect": set by file_data, base64_data, etc. - "Alt Decode": set by preprocessor normalization, e.g. HTTP Inspect - Raw packet data The AltDetect buffer can also be set by custom .so rules. * src/parser.c, src/parser.h, src/snort.h, src/output-plugins/spo_unified2.c, src/sfutil/Unified2_common.h: IPv6 source and destination addresses are now logged in Unified2 as extra data events. This is configured with "config log_ipv6_extra_data". * src/dynamic-preprocessors/sip/Makefile.am, src/dynamic-preprocessors/sip/sf_sip.dsp, src/dynamic-preprocessors/sip/sip_config.c, src/dynamic-preprocessors/sip/sip_config.h, src/dynamic-preprocessors/sip/sip_debug.h, src/dynamic-preprocessors/sip/sip_dialog.c, src/dynamic-preprocessors/sip/sip_dialog.h, src/dynamic-preprocessors/sip/sip_parser.c, src/dynamic-preprocessors/sip/sip_parser.h, src/dynamic-preprocessors/sip/sip_roptions.c, src/dynamic-preprocessors/sip/spp_sip.c, src/dynamic-preprocessors/sip/spp_sip.h, src/dynamic-preprocessors/sip/sip_roptions.h, src/dynamic-preprocessors/sip/sip_utils.c, src/dynamic-preprocessors/sip/sip_utils.h, doc/README.sip, etc/gen-msg.map, src/dynamic-preprocessors/sip/test/Makefile.am, src/dynamic-preprocessors/sip/test/sip_test.c, configure.in, src/dynamic-preprocessors/Makefile.am: Added a new preprocessor for SIP traffic. See README.sip and the Snort Manual for more information. * src/: dynamic-preprocessors/dcerpc2/dce2_utils.c, dynamic-preprocessors/dcerpc2/spp_dce2.c, preprocessors/spp_frag3.c: Make Frag3 OpenBSD Vuln alert only happen if the frag policy is 'linux' (which includes OpenBSD). The 'bsd' policy is NOT used for OpenBSD, which is the only OS on which the vulnerability was present. This reduces false positives to only occur when frag3 policy is linux and its an actual linux system, rather than the alert occuring regardless of frag policy. * src/: detection-plugins/Makefile.am, detection-plugins/sp_byte_extract.c, detection-plugins/sp_byte_extract.h, dynamic-plugins/sf_convert_dynamic.c, dynamic-plugins/sf_engine/Makefile.am, dynamic-plugins/sf_engine/sf_snort_detection_engine.c, dynamic-plugins/sf_engine/sf_snort_detection_engine.h, dynamic-plugins/sf_engine/sf_snort_plugin_api.c, dynamic-plugins/sf_engine/sf_snort_plugin_api.h, dynamic-plugins/sf_engine/sf_snort_plugin_byte.c, dynamic-plugins/sf_engine/sf_snort_plugin_content.c, dynamic-plugins/sf_engine/sf_snort_plugin_hdropts.c, dynamic-plugins/sf_engine/sf_snort_plugin_loop.c, dynamic-plugins/sf_engine/sf_snort_plugin_pcre.c, Added support for ByteExtract variables to the .so rule versions of Content, ByteTest, ByteJump, and isdataat. * src/: encode.c, preprocessors/spp_normalize.c, preprocessors/Stream5/snort_stream5_tcp.c, preprocessors/Stream5/stream5_common.c: Fixed the TTL on encoded response packets. * src/: fpcreate.c, fpdetect.c, detection-plugins/sp_pattern_match.c, detection-plugins/sp_pattern_match.h, dynamic-plugins/sf_dynamic_define.h, dynamic-plugins/sf_engine/sf_snort_detection_engine.c, dynamic-plugins/sf_engine/sf_snort_plugin_api.h: Update to not inspect HTTP method buffer with Snort's fast pattern engine. Rules with only HTTP method content end up as non-content rules. This eliminates a short cycle of searches with fast pattern on every initial HTTP request. * src/dynamic-preprocessors/pop/: all files Added a new preprocessor for POP traffic. See README.pop for more information. * src/dynamic-preprocessors/imap/: all files Added a new preprocessor for IMAP traffic. See README.imap for more information. * src/sfutil/: sf_email_attach_decode.c, sf_email_attach_decode.h: Base64 decoding was moved to its own section in sfutil, for use by the new email preprocessors. Added support for uuencoded email attachments. * src/dynamic-preprocessors/sdf/spp_sdf.c: The Sensitive Data preprocessor now inspects the "file_data" buffer, used for HTTP response bodies & decoded email attachments. * src/: snort.c, preprocessors/spp_stream5.c, preprocessors/stream_api.h: Update Snort to return a DAQ verdict of whitelist (meaning don't send Snort any more packets) for sessions that are being ignored in both directions or ports that are configured to ignore. For DAQ modules and hardware that supports it, this should result in a performance gain because Snort no longer has to decode packets that are part of that connection. * src/util.c: Added an error message when opening a pid file fails. * src/preprocessors/HttpInspect/: client/hi_client.c, server/hi_server.c: The Set-Cookie: and Cookie: headers wont be included in the cookie buffers. * configure.in, src/active.c, src/active.h, src/decode.h, src/encode.c, src/encode.h, src/log_text.c, src/log_text.h, src/parser.c, src/parser.h, src/sf_types.h, src/sfdaq.c, src/sfdaq.h, src/snort.h, src/snort_debug.h, src/detection-plugins/sp_react.c, src/detection-plugins/sp_respond3.c, src/dynamic-plugins/sf_dynamic_define.h, src/dynamic-plugins/sf_engine/sf_snort_packet.h, src/preprocessors/snort_httpinspect.c, src/preprocessors/spp_httpinspect.c, src/preprocessors/spp_stream5.c, src/preprocessors/stream_api.h, src/preprocessors/HttpInspect/Makefile.am, src/preprocessors/HttpInspect/include/Makefile.am, src/preprocessors/HttpInspect/include/hi_paf.h, src/preprocessors/HttpInspect/mode_inspection/hi_mi.c, src/preprocessors/HttpInspect/server/hi_server.c, src/preprocessors/HttpInspect/utils/Makefile.am, src/preprocessors/HttpInspect/utils/hi_paf.c, src/preprocessors/Stream5/Makefile.am, src/preprocessors/Stream5/snort_stream5_icmp.c, src/preprocessors/Stream5/snort_stream5_session.c, src/preprocessors/Stream5/snort_stream5_tcp.c, src/preprocessors/Stream5/snort_stream5_tcp.h, src/preprocessors/Stream5/snort_stream5_udp.c, src/preprocessors/Stream5/stream5_common.c, src/preprocessors/Stream5/stream5_common.h, src/preprocessors/Stream5/stream5_paf.c, src/preprocessors/Stream5/stream5_paf.h, src/sfutil/sf_textlog.h: Added support in Stream5 for Protocol Aware Flushing (PAF). PAF allows Snort to statefully scan a stream and reassemble a complete PDU regardless of segmentation. Added PAF support to HTTP Inspect, allowing the preprocessor to determine when HTTP sessions are flushed by Stream5. See README.stream5 for more details. * src/preprocessors/: stream_ignore.h, stream_ignore.c, Stream5/snort_stream5_udp.c: added support for ignoring UDP channels. Light weight session will be created to track UDP channel, even ports are not monitored. * src/win32/: most files Updated Snort and its libraries to build/link against MFC. 2011-03-23 Steven Sturges * src/build.h: Increment Snort build number to 134 * src/: decode.h, encode.c: * src/dynamic-plugins/sf_engine/: sf_snort_packet.h: * src/preprocessors/: spp_sfportscan.c, spp_frag3.c: * src/output-plugins/: spo_alert_fast.c: * src/preprocessors/Stream5/: stream5_common.c: Updated portscan to set protocol correctly in raw packet for IPv6 and changed the encoder to recognize portscan packets as pseudo packets so that the checksum isn't calculated * src/: sfdaq.c, util.c: Improve handling of DAQ failure codes when Snort is shutting down. * src/preprocessors/spp_perfmonitor.c: Update perfmonitor to create now files prior to dropping privs 2011-03-16 Ryan Jordan Snort 2.9.0.5 * src/build.h: Increment Snort build number to 132 * src/snort.c: * src/preprocessors/: normalize.c, perf-base.c, perf-base.h, Stream5/snort_stream5_tcp.c: TCP timestamp options are only NOPed by the Normalization preprocessor if Stream5 has seen a full 3-way handshake, and timestamps weren't negotiated. The IPS mode reassembly policy has been refactored to do stream normalization within the first policy. Packets injected by the normalization preprocessor are now counted in the packet statistics. * doc/snort_manual.tex: * src/: parser.c, parser.h: * src/preprocessors/: spp_frag3.c, Stream5/snort_stream5_session.c: Added a "config vlan_agnostic" setting that globally disables Stream's use of vlan tag in session tracking. * src/: snort.c, preprocessors/normalize.c, preprocessors/spp_normalize.c, preprocessors/spp_normalize.h, preprocessors/perf-base.c, preprocessors/perf-base.h: * doc/: README.normalize, snort_manual.pdf, snort_manual.tex: Fixed the normalization preprocessor to call its post-initialization config functions during a policy reload. Packets can no longer be trimmed below the minimum ethernet frame length. Trimming is now configurable with the "normalize_ip4: trim;" option. TOS clearing is now configurable with "normalize_ip4: tos;". The "normalize_ip4: trim" option is automatically disabled if the DAQ can't inject packets. If the DAQ tries and fails to inject a given packet, the wire packet is not blocked. Updated documentation regarding these changes. * src/detection-plugins/sp_cvs.c: Fixed a false positive in the CVS detection plugin. It was incorrectly parsing CVS entries that had a '+' in between the 3rd and 4th slashes. * src/preprocessors/HttpInspect/: client/hi_client.c, server/hi_server.c: Changed a pointer comparison to a size check for code readability. Belated thanks to Dwane Atkins and Parker Crook for reporting a related issue that was fixed in Snort 2.9.0.4 build 111. Moved the zlib initialization such that gzipped responses are still inspected if the zipped data starts after the first Stream-reassembled packet is inspected. * src/decode.c: Fixed an issue with decoding too many IP layers in a single packet. The Teredo proto bit was not unset after hitting the limit on IP layers. Thanks to Dwane Atkins for reporting this issue. IPv6 fragmented packets are no longer inspected unless they have an offset of zero and the next layer is UDP. This behavior is consistent with IPv4 decoding. Thanks to Martin Sch�tte for reporting an issue where fragged ICMPv6 packets were being inspected. The decoder no longer attempts to decode Teredo packets inside of IPv4 fragments, instead waiting for the reassembled packet. * src/encode.c: Fixed a problem where encoded packets had their lengths calculated incorrectly. This caused the active response feature to generate incorrect RST packets if the original packet had a VLAN tag. * preproc_rules/preprocessor.rules: Updated references to rule 125:1:1 * src/preprocessors/spp_perfmonitor.c: Perfmonitor files are now created after Snort changes uid/gid. * src/dynamic-plugins/sf_preproc_example/sf_dynamic_preproc_lib.c: Fixed the size formatting of an error message argument when compiling with --enable-rzb-saac. Thanks to Cleber S. Brand�o for reporting this issue. * etc/snort.conf: Updated the default snort.conf with max compress and decompress depths to enable unlimited decompression of gzipped HTTP responses. * snort.8: Fixed the man page's URL regarding the location of Snort rules. Thanks to Michael Scheidell for reporting an out-of-date man page section. * doc/README.http_inspect, doc/snort_manual.tex, src/preprocessors/snort_httpinspect.c: HTTP Inspect's "unlimited_decompress" option now requires that "compress_depth" and "decompress_depth" are set to their max values. * src/: fpcreate.c, dynamic-plugins/sf_dynamic_define.h, dynamic-plugins/sf_dynamic_engine.h, preprocessors/Stream5/snort_stream5_tcp.c: Fixed an error that prevented compiling with --disable-dynamicplugin. Thanks to Jason Wallace for reporting this issue. * src/dynamic-preprocessors/ftptelnet/: snort_ftptelnet.c, snort_ftptelnet.h, spp_ftptelnet.c: Changed the names of ProcessGlobalConf() and PrintGlobalConf() inside the ftp_telnet preprocessor to avoid a naming conflict with similar functions in HTTP Inspect. Thanks to Bruce Corwin for reporting this issue. * src/preprocessors/: perf.c, perf-base.c, perf-base.h, perf-flow.c, perf-flow.h: Fixed comparisons between signed and unsigned int, which lead to a faulty length check. Thanks to Cihan Ayyildiz and Jason Wallace for helping us debug this issue. 2011-02-28 Ryan Jordan Snort 2.9.0.4 * src/build.h: Increment Snort build number to 111. * src/preprocessors/HttpInspect/client/hi_client.c: src/preprocessors/HttpInspect/server/hi_server.c: Fixed a bug in the way partial HTTP headers are handled. 2011-02-10 Ryan Jordan Snort 2.9.0.4 * src/build.h: Increment Snort build number to 110 * snort.8, src/snort.c: Updated Snort man page to match the output of "snort --help". Removed "-o" from the list of valid options, since it was removed a while ago. The verdict from defragged packets are no longer cleared, so that they can be applied to the raw packet. Thanks to Markus Lude for submitting a patch that fixed errors in the man page. * src/fpcreate.c: Deletec the call to fpDeletePortGroup() prior to calling FatalError(). * src/parser.c: Fixed portvar parsing code to correctly dislpay names of undefined portvars. * src/preprocessors/Stream5/snort_stream5_tcp.c: Fixed a FIN sequence number handling issue, where RST after FIN caused a false positive on Stream5 preprocessor rule 129:15. Thanks to Jason Wallace for pointing out the issue. * doc/: INSTALL, README.frag3, README.http_inspect, README.stream5, snort_manual.tex, snort_manual.pdf: Added documentation for the option "small-segments". Updated team members. Clarified some undocumented "flow" options. Minor edits to punctuation on "ssl_version" examples. Re-worded uricontent's description. Added missing semicolons to rule option examples. Updated "enable_cookie" documentation. Added documentation for "iis_encode" in http_encode keywords. Improved the description of the "disable" keyword. Added "--enable-sourcefire" description. Thanks to Joshua Kinard for sending in several patches to the manual. * doc/: Makefile.am, README.rzb_saac: Added SaaC readme. * configure.in, doc/Makefile.am, doc/README.rzb_saac, src/snort.c, src/util.c, src/util.h, src/dynamic-plugins/sf_engine/examples/Makefile.am, src/dynamic-preprocessors/Makefile.am, src/dynamic-preprocessors/dns/spp_dns.c, src/dynamic-preprocessors/rzb_saac/Makefile.am, src/dynamic-preprocessors/rzb_saac/rzb_debug.c, src/dynamic-preprocessors/rzb_saac/rzb_debug.h, src/dynamic-preprocessors/rzb_saac/rzb_http-client.c, src/dynamic-preprocessors/rzb_saac/rzb_http-client.h, src/dynamic-preprocessors/rzb_saac/rzb_http-collector.h, src/dynamic-preprocessors/rzb_saac/rzb_http-fileinfo.c, src/dynamic-preprocessors/rzb_saac/rzb_http-fileinfo.h, src/dynamic-preprocessors/rzb_saac/rzb_http-server.c, src/dynamic-preprocessors/rzb_saac/rzb_http-server.h, src/dynamic-preprocessors/rzb_saac/rzb_http.h, src/dynamic-preprocessors/rzb_saac/rzb_smtp-collector.c, src/dynamic-preprocessors/rzb_saac/rzb_smtp-collector.h, src/dynamic-preprocessors/rzb_saac/sf_preproc_info.h, src/dynamic-preprocessors/rzb_saac/spp_rzb-saac.c: Added Razorback SaaC to the dynamic-preprocessors. Use --enable-rzb-saac to build it. Moved the initgroups call to a separate function and call it from the main thread. * src/detection-plugins/sp_clientserver.c: Fixed an erroneous error check so that "no_frag" and "no_stream" can be used in the same "flow" rule option. * src/detection-plugins/sp_pattern_match.c: Rules that use a "depth" value lower than the length of their content now cause an error. Depth should be >= the content length. * src/detection-plugins/sp_tcp_flag_check.c: Changed the reserved bits flags "1, 2" to "C, E". The old values can still be used for backwards compatability. * preproc_rules/preprocessor.rules: Added references to FTP and SMTP preprocessor rules. * src/dynamic-plugins/sf_engine/examples/: detection_lib_meta.h: Removed extraneous ifdef * src/: preprocessors/spp_frag3.c, preprocessors/spp_sfportscan.c, dynamic-preprocessors/dcerpc2/dce2_config.c: Added startup log message to show that the preprocessors are inactive when added to snort.conf as "disabled". Updated frag3 startup log to indicate the memcap frmo which prealloc fragments were generated. * src/preprocessors/: spp_frag3.c, Stream5/snort_stream5_session.c: Updated the Frag3KeyCmp and Stream5KeyCmp functions to handle 32bit sparc platforms where 64bit pointer comparisons can cause bus errors. Thanks to Stephan for reporting this issue. * src/: preprocessors/portscan.c, win32/WIN32-Includes/config.h: Portscan preprocessor's hash table is now allocated based on the memcap, instead of being the same size. * src/dynamic-preprocessors/dcerpc2/: dce2_co.c, dce2_utils.c, dce2_smb.c: Fixed a bug that caused dcerpc2 to reassemble some segments incorrectly. If extra bytes at the end of a request corrupt the next request, they will be discarded. * src/dynamic-preprocessors/ssl/spp_ssl.c: Updated the SSL preproc to count the packets it processes, instead of counting all packets to enter the intiial function. * doc/: faq.tex, faq.pdf: Updated FAQ based on snort.org reorganization. * doc/: README.http_inspect, snort_manual.pdf, snort_manual.tex: Updated cookie documentation. Cookie buffer includes "Cookie" header name for HTTP requests and "Set-Cookie" for HTTP responses. When enable_cookie is disabled, cookie buffer points to the HTTP header * src/preprocessors/snort_httpinspect.c: Fixed the error message during parsing of HTTP inspect server config. Make it a warning. * src/: detection_util.h, preprocessors/snort_httpinspect.c, preprocessors/spp_httpinspect.c, preprocessors/HttpInspect/client/hi_client.c, preprocessors/HttpInspect/include/hi_client.h, preprocessors/HttpInspect/include/hi_norm.h, preprocessors/HttpInspect/include/hi_ui_config.h, preprocessors/HttpInspect/normalization/hi_norm.c, preprocessors/HttpInspect/server/hi_server.c: Fixed a false positive due to a large chunk length followed by a small packet. Moved the lookup table such that they are initialized only once. When de-chunking returns error, the data is now inspected as a normal body. Moved the Initialize function out of hi_ui_config.h. CRLFs are no longer placed in the status message buffer. * many files: Updated all Sourcefire copyright notices to the year 2011. 2010-12-20 Ryan Jordan Snort 2.9.0.3 * src/build.h: Increment Snort build number to 98 * doc/: snort_manual.tex, snort_manual.pdf: Fixed Snort manual descriptions of some rule options. Changed whitespace in several areas to be more consistent. Max mime mem example changed from 1000 to 4000. Updated manual for distance / within / offset / depth combos. Thanks to Joshua Kinard for submitting several fixes. * doc/INSTALL: Update doc/INSTALL with instructions for building on OpenBSD. * src/dynamic-preprocessors/smtp/smtp_config.c: Print alert_unknown_commands in SMTP config of snort output. Print the SMTP MIME config details with snort output. * src/: decode.c, decode.h, snort.c: discriminate between ip4 and ip6 raw packets Thanks to Gerald Maziarski for reporting this issue. * src/detection-plugins/: detection_options.c, sp_byte_jump.c, sp_pattern_match.c: restore doe flags along with doe pointer. * preproc_rules/preprocessor.rules: Updated preprocessor.rules references to match VRT. * src/dynamic-preprocessors/smtp/spp_smtp.c: When the SMTP preprocessor is started in a "disabled" state, it no longer requires Stream5. * src/decode.c: Truncated ESP traffic is now handled correctly. Thanks to rmkml for bringing the issue to our attention. * src/: decode.c, fpdetect.c: Fixed a problem with handling UDP/IPv6 over Teredo where the inner UDP header was malformed. * preproc_rules/preprocessor.rules: Added a reference to preprocessor.rules. * src/dynamic-preprocessors/smtp/spp_smtp.c: When the SMTP preprocessor is started in a "disabled" state, it no longer requires Stream5. * src/detection-plugins/: detection_options.c, sp_pattern_match.c: Update content to check for HTTP_RESP_BODY in packet flag if option is relative and not using rawbytes. * etc/snort.conf: Update with snort.conf from VRT * src/dynamic-plugins/sf_engine/examples/detection_lib_meta.h: Bumped minor version number in example detection lib. * src/preprocessors/spp_frag3.c: Fix memory leak when there are two zero offset fragments with different IP options. Previous code was blindly copying new IP options over top of existing ones. * src/dynamic-plugins/sf_engine/: sf_snort_detection_engine.c, sf_snort_plugin_api.h: Fixed overlaps in various flags in the Shared Object rule API. Shared Object rules from previous 2.9.0 versions need to be recompiled. * src/detection-plugins/sp_pattern_match.c: Moved non-zero initializations in the PatternMatchData struct to the NewNode() function. This fixes the use of depth, offset, distance, and within on uricontent options. Reject invalid combinations of distance/within and offset/depth including repeated keywords. Thanks to Dave Bertouille and Daniel Clemens for pointing out issues here. * src/: snort.c, util.c, util.h: write correct pid to file for glibc2.2 / linux threads * src/preprocessors/: snort_httpinspect.c, HttpInspect/mode_inspection/hi_mi.c: Fixed an instance where HTTP session data was not checked. DAQ 0.5 * daq/os-daq-modules/Makefile.am: The IPFW DAQ now builds on OpenBSD. Thanks to Ross Lawrie, Randall Rioux, and many others for reporting this. 2010-11-15 Ryan Jordan Snort 2.9.0.2 * preproc_rules/preprocessor.rules: Added a reference to an 0day ProFTP bug in a FTP preprocessor rule. * src/build.h: Increment Snort build number to 92 * src/preprocessors/Stream5/snort_stream5_tcp.c: Count only acked segs for flushing post-ack. Thanks to Eoin Miller for helping track this issue and provide test scenarios. * src/detection_util.h: * src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c: * src/preprocessors/Stream5/snort_stream5_tcp.c: fix file_data:mime in So rules. content matches following file_data:mime should not enter fast pattern matcher. Reset file_data_ptr once stream flush is done and stream reassembled packet is processed. * src/dynamic-preprocessors/ssl/spp_ssl.c: Fix return value for SSL rule options * src/: plugbase.h, preprocessors/snort_httpinspect.c: Set the dce preproc bit in HTTP only when server flow depth is -1 * src/dynamic-preprocessors/dcerpc2/: dce2_co.c, dce2_smb.c, dce2_utils.c, dce2_utils.h, includes/smb.h: use offset or remaining fields and overwrite as appropriate instead of always appending data * src/preprocessors/HttpInspect/server/hi_server.c: * src/preprocessors/HttpInspect/client/hi_client.c: Fixed a couple of memory leaks. * src/preprocessors/HttpInspect/mode_inspection/hi_mi.c: Fixed an error in the handling of HTTP Session Data. * doc/: README.http_inspect,snort_manual.pdf, snort_manual.tex: Update to the snort manual. remove the stream5 alerts. reference the gen-msg.map. * preprocessors/Stream5/snort_stream5_tcp.c: urgent pointer handling corrected for one byte of urgent data at the start of a segment. The general case of an N-byte urgent payload prefix would be handled here by removing the == 1 limit in urg_offset == 1 but that restrictio is not safe until we flush urgent data. As is, urgent data is never flushed in reassembled packets and can only be detected i raw packets. pointer handling. * src/: decode.h, detection_util.h, plugbase.h, preprocessors/snort_httpinspect.c, preprocessors/snort_httpinspect.h, preprocessors/HttpInspect/server/hi_server.c, Apply server flow depth on a session basis rather than per packet basis. This change improves the performance by disabling detect on packet when the packet is beyond the specified flow depth. server_flow_depth now takes values from -1 to 65535 * src/parser.c: Correct setting of dup_opt_func and cleanup existing opt_func list before hand to address parse-time leak. 2010-11-01 Ryan Jordan Snort 2.9.0.1 * doc/: snort_manual.pdf, snort_manual.tex: Added "flush_factor". Fixed incorrect line wrap (thx Shawn Thompson). values for within and depth updated * src/build.h: Increment Snort build number to 82. * src/preprocessors/HttpInspect/: client/hi_client.c, server/hi_server.c: HTTP header buffers (raw/normalized) now include the missing \n (of \r\n\r\n). * src/target-based/sf_attribute_table.y: Set YYMAXDEPTH to something that covers large number of services for a single host. * src/parser.c, src/preprocessors/spp_stream5.c, doc/snort_manual.pdf, doc/snort_manual.tex: Fix use of config flowbits_size and update default to 1024. * src/detection-plugins/sp_pcre.c: Correct calculation of offset to its original now that libpcre is fixed. * src/: detection-plugins/sp_pcre.c, win32/WIN32-Includes/pcre.h, win32/WIN32-Includes/pcreposix.h, win32/WIN32-Libraries/pcre.lib: Update Win32 libpcre to newer version and use --enable-newline-is-cr instead of --enable-newline-is-any. Also added comments to sp_pcre.c in terms of how Snort is interpreting the ovector from pcre_exec. * etc/gen-msg.map: Added rules 120:4 and 120:5 to gen-msg.map. * src/preprocessors/Stream5/snort_stream5_tcp.c: Fix issue when handling overlap limit enforcement. Thanks to rmkml and Miguel Alvarez for pointing out the issue. * src/preprocessors/Stream5/snort_stream5_tcp.c: fix flush after initial when acks are withheld conditional on NORMALIZER process stream after window slam unless normalizing fully separate pre-ack flush from post-ack flush to ensure switching on policy for listener direction; allow window limit greater than 16-bit; tweak flush point tracing. added preprocessor rule 129:19, window slam * src/preprocessors/Stream5/: snort_stream5_tcp.c, stream5_common.h: add stream5_tcp: flush_factor <#> * doc/snort_manual.tex, src/detection-plugins/sp_ttl_check.c: Allow >= and <= with ttl keyword. Also fix the parsing for ttl. Update manual * src/util.c: Make parent_wait variable volatile so it doesn't get optimized out. * src/decode.c: In CheckIPv4_MinTTL(), use the ttl passed as an argument instead of the packet's IP header. * preproc_rules/preprocessor.rules: adds preprocessor rule 129:19 * etc/gen-msg.map, preproc_rules/decoder.rules, src/decode.c, src/generators.h: Ported .so rule for ICMP DOS to decoder. * etc/gen-msg.map, src/generators.h, * src/: active.c, encode.c, detection-plugins/sp_react.c: set ack number appropriately * src/preprocessors/snort_httpinspect.c: file data ptr should be set to the decode buffer when the http response body is normalized. * src/preprocessors/HttpInspect/: client/hi_client.c, server/hi_server.c: inspect stream inserted packets to check if they have a valid HTTP response. When there is a single segment HTTP response inspect the body. Dont wait for the reassembled packet ( due to flush point issues) * src/: detection_util.h, fpdetect.c, detection-plugins/sp_byte_check.c, detection-plugins/sp_byte_extract.c, detection-plugins/sp_byte_jump.c, detection-plugins/sp_ftpbounce.c, detection-plugins/sp_isdataat.c, detection-plugins/sp_pattern_match.c, detection-plugins/sp_pcre.c, preprocessors/snort_httpinspect.c, preprocessors/HttpInspect/server/hi_server.c: When extended_response_inspection is not enabled check for "HTTP". If present, apply flow depth otherwise do not disable detect and dont apply flow depth. * doc/: README.http_inspect, snort_manual.pdf, snort_manual.tex: Update Manual and README.http_inspect * src/signature.c: remove commented out printfs * src/preprocessors/HttpInspect/server/hi_server.c: inspect stream reassembled packets only when stream reassembly is turned on. * tools/u2boat/Makefile.am: Update Makefile to include docdir * src/encode.c: don't calculate checksum for pseudo-packets * src/: decode.c, decode.h, detect.c, detection_util.c, detection_util.h, fpdetect.c, log.c, log_text.c, mstring.c, detection-plugins/detection_options.c, detection-plugins/sp_asn1.c, detection-plugins/sp_base64_data.c, detection-plugins/sp_base64_decode.c, detection-plugins/sp_byte_check.c, detection-plugins/sp_byte_extract.c, detection-plugins/sp_byte_jump.c, detection-plugins/sp_file_data.c, detection-plugins/sp_ftpbounce.c, detection-plugins/sp_isdataat.c, detection-plugins/sp_pattern_match.c, detection-plugins/sp_pcre.c, detection-plugins/sp_urilen_check.c, dynamic-plugins/sf_dynamic_common.h, dynamic-plugins/sf_dynamic_engine.h, dynamic-plugins/sf_dynamic_plugins.c, dynamic-plugins/sf_dynamic_preprocessor.h, dynamic-plugins/sf_engine/sf_snort_detection_engine.c, dynamic-plugins/sf_engine/sf_snort_plugin_api.c, dynamic-plugins/sf_engine/sf_snort_plugin_content.c, dynamic-plugins/sf_engine/sf_snort_plugin_pcre.c, dynamic-preprocessors/ftptelnet/pp_ftp.c, dynamic-preprocessors/ftptelnet/pp_telnet.c, dynamic-preprocessors/ftptelnet/snort_ftptelnet.c, dynamic-preprocessors/smtp/smtp_util.c, dynamic-preprocessors/smtp/snort_smtp.c, output-plugins/spo_unified2.c, preprocessors/snort_httpinspect.c, preprocessors/spp_httpinspect.c, preprocessors/spp_rpc_decode.c, preprocessors/HttpInspect/client/hi_client.c, preprocessors/HttpInspect/normalization/hi_norm.c, preprocessors/HttpInspect/server/hi_server.c, preprocessors/HttpInspect/server/hi_server_norm.c, preprocessors/Stream5/snort_stream5_tcp.c: add buffer length attribute to alt decode buffer and don't set alt decode flag for alt_dsize changes which are indicated by that value being non-zero. * src/preprocessors/Stream5/snort_stream5_tcp.c: purge listener for pre-ack Flip the direction to match that the configurations in stream5_tcp. * src/: decode.h, preprocessors/spp_httpinspect.c, preprocessors/HttpInspect/normalization/hi_norm.c: add new keyword to http_encode to detect ascii encoding * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.c: Propigate noalert back to detection option tree. * src/: parser.c, signature.c, signature.h: Allow multiple .so rules to reference a single soid metadata. * doc/: README.active, README.daq, snort_manual.pdf, snort_manual.tex: clarify use of multiple --daq and config daq. * src/parser.c: error on multiple --daq args 2010-10-04 Ryan Jordan Snort 2.9.0 * doc/Makefile.am: * doc/README.FLEXRESP: * doc/README.FLEXRESP2: * doc/README.http_inspect: * doc/README.INLINE: * doc/README.ipv6: * doc/README.stream5: * doc/README.wireless: * doc/snort_manual.tex: Removed obsolete README files. Updated README.ipv6. Documented other changes made below. * etc/gen-msg.map: * preproc_rules/preprocessor.rules: * src/generators.h: Added new preprocessor rules for HTTP Inspect and Frag3. Removed an old preprocessor rule for the already-removed dcerpc preprocessor. * rpm/snort.spec: * src/build.h: Updated version numbers. * src/dynamic-plugins/sp_dynamic.c: * src/fpcreate.c: Shared Object rules which use HTTP Content as their Fast Pattern should now work correctly. * src/decode.c: * src/decode.h: * src/detection-plugins/detection_options.c: * src/dynamic-plugins/sf_dynamic_engine.h: * src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c: * src/dynamic-plugins/sf_engine/sf_snort_packet.h: * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.h: * src/dynamic-plugins/sp_preprocopt.c: * src/dynamic-preprocessors/dcerpc2/dce2_roptions.c: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: * src/dynamic-preprocessors/sdf/sdf_detection_option.c: * src/dynamic-preprocessors/sdf/sdf_pattern_match.c: * src/dynamic-preprocessors/sdf/spp_sdf.c: * src/dynamic-preprocessors/ssl/spp_ssl.c: * src/parser.c: * src/ppm.c: * src/ppm.h: * src/profiler.c: * src/target-based/sf_attribute_table_parser.l: Miscellaneous code cleanup. Other preprocessor rules had to be modified as part of the new Stream5 rule option listed below. * src/preprocessors/HttpInspect/client/hi_client.c: * src/preprocessors/HttpInspect/event_output/hi_eo_log.c: * src/preprocessors/HttpInspect/include/hi_eo_events.h: * src/preprocessors/HttpInspect/include/hi_norm.h: * src/preprocessors/HttpInspect/include/hi_server_norm.h: * src/preprocessors/HttpInspect/include/hi_ui_config.h: * src/preprocessors/HttpInspect/normalization/hi_norm.c: * src/preprocessors/HttpInspect/server/hi_server.c: * src/preprocessors/HttpInspect/server/hi_server_norm.c: * src/preprocessors/HttpInspect/user_interface/hi_ui_config.c: * src/preprocessors/snort_httpinspect.c: * src/preprocessors/snort_httpinspect.h: * src/preprocessors/spp_httpinspect.c: * src/sfutil/util_utf.c: * src/sfutil/util_utf.h: * src/sfutil/Makefile.am: * snort_head/snort/src/win32/WIN32-Prj/snort.dsp: HTTP Inspect now handles "chunked" Transfer-Encoding for any Content-Encoding, not just for gzipped responses. HTTP Inspect now decompresses responses with "Content-Encoding: deflate". HTTP Inspect now normalizes server responses that use UTF-16 or UTF-32 charsets. * src/preprocessors/portscan.c: * src/preprocessors/spp_sfportscan.c: * src/preprocessors/Stream5/snort_stream5_tcp.c: Fixed an issue with some Stream5 sessions not being cleared until shutdown. Fixed a bug that caused false positives on Stream5 rule 129:4. Fixed a bug where Stream5 reassembled on all ports when sfportscan was in snort.conf, but in a "disabled" state. Added a preprocessor rule option, enabled by Stream5. The syntax is "reassembly: , [,noalert]". It enables/disables Stream reassembly for the session that matches the rule. 2010-09-03 Ryan Jordan Snort 2.9.0 RC * Fixed clean shutdown after reload. * Fixed tagging to log tagged packets regardless of filtering. * Fixed mempool initialization of free list count bug reported by zhangz@risinginfo.com. * Snort resized packets are now dropped and injected as required by DAQs. * Fixed Snort I/O Totals reporting injected packets with IPFW when NO packets are injected externally. * Tweaked Snort's dynamic preprocessor example. * More informative dynamic preprocessor loading error messages. * Added preprocessor alerts added to alert when Snort sees a client hello after a server hello or when Snort sees a server hello without a client hello when trustservers is disabled. * Documentation Updates: Updates to HTTP inspect README and Snort Manual. * Added parser error to fragoffset: Error when !, < and > operators are used with each other. * Updated README for daq with updated information on firewalls with FreeBSD and OpenBSD * Added more complete error checking to "byte_extract" rule option parsing. * The Sensitive Data preprocessor no longer searches HTTP headers for PII, as this introduced unnecessary false positives. In addition, the "us_social_nodashes" rule is now off by default to avoid false positives. * Added a new decoder alert for IPv6 extension headers that don't follow the RFC's recommended order. * Fixed a bug in the validation of IPv6 option lengths. * Fixed a bug in the normalization of HTTP responses with both gzipped Content-Encoding and chunked Transfer-Encoding. * Teredo packets with another layer of UDP on top will now display the correct port numbers in console output. * Reduced false positives on decoder alerts when "config deep_teredo_inspection" is enabled. * Fixed a problem with evaulating UDP rules on Teredo traffic, where the result of rule evaluation on the outer UDP * Changed the default search methond in snort.conf from "ac-bnfa" to "ac-split". 2010-06-23 Steven Sturges * doc/README.active: * doc/README.http_inspect: * doc/README.ssl: * doc/snort_manual.tex: Updated descripgions of rule options. * etc/gen-msg.map: Update messages for IPv6 decoder events. * src/win32/Makefile.am: * src/win32/WIN32-Includes/libnet/Devioctl.h: * src/win32/WIN32-Includes/libnet/gnuc.h: * src/win32/WIN32-Includes/libnet/ifaddrlist.h: * src/win32/WIN32-Includes/libnet/IPExport.h: * src/win32/WIN32-Includes/libnet/IPHlpApi.h: * src/win32/WIN32-Includes/libnet/IPTypes.h: * src/win32/WIN32-Includes/libnet/libnet-asn1.h: * src/win32/WIN32-Includes/libnet/libnet-functions.h: * src/win32/WIN32-Includes/libnet/libnet.h: * src/win32/WIN32-Includes/libnet/libnet-headers.h: * src/win32/WIN32-Includes/libnet/libnet-macros.h: * src/win32/WIN32-Includes/libnet/LibnetNT.h: * src/win32/WIN32-Includes/libnet/libnet-ospf.h: * src/win32/WIN32-Includes/libnet/libnet-structures.h: * src/win32/WIN32-Includes/libnet/Ntddpack.h: * src/win32/WIN32-Includes/libnet/packet_types.h: * src/win32/WIN32-Includes/libnet/NTDDNDIS.H: * src/win32/WIN32-Includes/libnet/PACKET32.H: * src/win32/WIN32-Includes/mysql/config-netware.h: * src/win32/WIN32-Includes/mysql/config-os2.h: * src/win32/WIN32-Includes/mysql/config-win.h: * src/win32/WIN32-Includes/mysql/libmysqld.def: * src/win32/WIN32-Includes/mysql/libmysql.def: * src/win32/WIN32-Includes/mysql/m_ctype.h: * src/win32/WIN32-Includes/mysql/m_string.h: * src/win32/WIN32-Includes/mysql/my_dbug.h: * src/win32/WIN32-Includes/mysql/my_getopt.h: * src/win32/WIN32-Includes/mysql/my_global.h * src/win32/WIN32-Includes/mysql/my_pthread.h: * src/win32/WIN32-Includes/mysql/mysqld_error.h: * src/win32/WIN32-Includes/mysql/mysql_embed.h: * src/win32/WIN32-Includes/mysql/my_sys.h: * src/win32/WIN32-Includes/mysql/raid.h: * src/win32/WIN32-Libraries/libnet/LibnetNT.lib: * src/inline.c: * src/inline.h: * src/detection-plugins/sp_respond.c: * src/detection-plugins/sp_respond2.c: Remove dead files. * src/active.c: * src/preprocessors/normalize.c: * src/preprocessors/spp_normalize.c: DAQ capability updates * src/decode.c: * src/decode.h: * src/generators.h: IPv6 decoding updates * src/decode.c: * src/log.c: * src/log.h: * src/log_text.c: * src/log_text.h: Improvement of packet output when obfuscating IP addresses. * src/detection-plugins/sp_byte_jump.c: Updates to multiplier parameter handling. * src/detection-plugins/sp_react.c: Added HTTP header to response payload. * src/dynamic-preprocessors/ftptelnet/pp_ftp.c: Update to handling string format detection. * src/dynamic-preprocessors/libs/ssl.c: * src/dynamic-preprocessors/libs/ssl.h: * src/dynamic-preprocessors/ssl/spp_ssl.c: Updates to handling of SSL rule options when handshake says SSLv2 but certificate is SSLv3 and interaction with Stream reassembled packets. * src/dynamic-preprocessors/sdf/spp_sdf.c: Display configuration information at startup. * src/fpdetect.c: Improved handling of gzip decoded buffer for fast pattern searches. * src/parser.c: Updates to parsing of IP variables with negated IP ranges. * src/preprocessors/HttpInspect/client/hi_client.c: * src/preprocessors/HttpInspect/server/hi_server.c: Chunk encoding processing updates. * src/preprocessors/HttpInspect/client/hi_client.c: * src/preprocessors/HttpInspect/include/hi_ui_config.h: * src/preprocessors/HttpInspect/include/Makefile.am: * src/preprocessors/HttpInspect/include/hi_cmd_lookup.h: * src/preprocessors/HttpInspect/Makefile.am: * src/preprocessors/HttpInspect/user_interface/hi_ui_config.c: * src/preprocessors/HttpInspect/user_interface/hi_ui_server_lookup.c: * src/preprocessors/HttpInspect/utils/Makefile.am: * src/preprocessors/HttpInspect/utils/hi_cmd_lookup.c: * src/preprocessors/snort_httpinspect.c: * src/preprocessors/snort_httpinspect.h: * src/preprocessors/spp_httpinspect.c: Use lookup for HTTP method validation. * src/preprocessors/Stream5/snort_stream5_tcp.c: Updated state tracking for FIN_WAIT_2 and LAST_ACK * src/sfdaq.c: * src/sfdaq.h: * src/snort.c: * src/util.c: Handle -g/-u limited with DAQ modules that require root privs. 2010-06-16 Ryan Jordan Snort 2.9.0 Beta * Snort uses the DAQ library for packet acquisition and injection. ./configure --enable-inline and --enable-ipfw are deleted. Just run ./snort -Q to activate inline mode for DAQs that support it. See the README.daq there for more. * A normalizer preprocessor has been added to help minimize evasion vectors. Use ./configure --enable-normalizer to build and config normalize_* to enable. See README.normalize for more. * Flexresp and flexresp2 have been replaced with a new flexresp3 module that supports the rule keywords from each. ./configure --enable-flexresp --enable-flexresp2 are deprecated. * The react rule option has been rewritten to correct a number of issues. You can also customize the injected content with config react. Use ./configure --enable-react to build. * config min_ttl is now policy specific. You can also set a normalization value with config new_ttl. * Snort has a new active response capability. Build it with ./configure --enable-active-response. This mode enables automatically sending TCP resets and ICMP unreachables. See README.active for more. * Passive mode Snort can now inject packets for drop, sdrop, and reject rules. In addition, block and sblock rules have been added as synonyms for drop and sdrop to help avoid confusion between dropped packets and blocked packets. Configure with config response. * Snort shutdown output now includes new counts so you can see if any events are not being reported due to event queue and pattern matching configurations. Also, ./configure --enable-timestats has been eliminated but the shutdown output of packet rates has been made standard. * BPFs can be written for IPv6. * ./snort -T has bee expanded to validate more than just the conf. For example, you can now validate BPFs. * Snort no longer depends on libnet and uses libdnet instead. * Added the "byte_extract" detection option. This saves bytes from the packet into variables for use by other options. * Added support for byte_extract variables in the following rule options * content (offset, depth, distance, within) * byte_test (offset, comparison value) * byte_jump (offset) * isdataat (offset) * Added decoder support for Teredo tunneling (IPv6 over UDP over IPv4). * Added decoder support for Encapsulated Security Payload (ESP) with NULL encryption. * Added 18 decoder rules for different types of malformed IPv6 headers. * Moved 24 content-less rules into the packet decoder. * The Sensitive Data preprocessor now prints its configuration on startup. * Fixed the Snort RPM so that it installs the Sensitive Data preprocessor. * Updated the description of the "-h" option in the Snort help output. * Added a tools directory, with "u2boat" and "u2spewfoo". These programs can be used to turn Unified2 files into pcaps and console output, respectively. * Replaced Unified with Unified2 in snort.conf. * Moved the rules/ directory into its own separate tarball. * Snort will print encapsulated layers in text output. * Initial iteration of DCE/RPC preprocessor removed. * SO rule updates. Updated storeRuleData() and getRuleData() API functions. Added dynamic allocation functions allocRuleData() and freeRuleData() mainly for data stored on a stream session and to utilize a new configuration option to put a memcap on the amount of data SO rules allocate. * Fixed possible non-runtime memory leak in SO rule preprocessor rule options. * Added negation support to SSL preprocessor rule options ssl_state and ssl_version * Added support for Intel's Soft CPM for use as a fast pattern matcher. * Fixed issue when specifying a --pcap-dir where Snort would fatal error if there was a broken symbolic link under the directory. * Fixed an issue where copying an SO rule stub to modify the rule action, IPs and/or ports didn't work as expected. * Set state in SSL preprocessor even if record is truncated. * Fixed inconsistency with flowbits behaviour if stream session timed out. stream5 now resets flowbits on a timeout. * Snort will now fatal error if adaptive profiles is enabled in any policy other than the default policy. * Fixed false positives caused by using the fast_pattern option with the "only" argument on an http content in a rule. * Fix OpenBSD compile with --enable-prelude. * Fixed issue in SO rules converted to text rules that were not setting mutliplier correctly. * Fixed inconsistencies in behaviour with user defined rule types. * Snort will now throw validation error for ipvar definition with negated ip list that is more general that other ip list in definition. * Added support for IP variable substitution. * Created new decoder event for ICMP PATH MTU denial of service attempt. * Fixed SSL preprocessor to potentially update state before reassmebled packet is decoded. * Added a new argument "mime" to the detection option "file_data". This argument will set the doe_ptr to the start of the base64 decoded MIME attachment. New config options "enable_mime_decoding", "max_mime_depth" and "max_mime_mem" are added to SMTP configuration to support this feature. * Added the "base64_decode" and "base64_data" detection option. The "base64_decode" decodes the base64 encoded data. The "base64_data" points the doe_ptr to the start of the base64 decoded buffer. * Added a new mode "inline-test". This mode simulates the inline mode of snort, allowing evaluation of inline behavior without affecting traffic. The command line option --enable-inline-test and snort config option policy_mode:inline_test added to support this feature. The drop rules will be loaded and will be triggered as a Wdrop (Would Drop) alert. * Added the support to extract the original client IP from the X-Forwarded-For or True-Client-IP headers. This client IP will now be logged to the unified2 output when HTTP Inspect is configured with enable_xff. * Added support to u2spewfoo to read the Orginal Client IP, Wdrop Alerts, Gzip decompressed Data. * Added support to print the Gzip decompressed data with cmg output. 2010-04-16 Ryan Jordan * doc/README.dcerpc: * doc/README.dcerpc2: * doc/README.flowbits: * doc/README.frag3: * doc/README.http_inspect: * doc/README.PerfProfiling: * doc/README.sensitive_data: * doc/README.sfportscan: * doc/README.stream5: * doc/snort_manual.tex: Updated Snort documentation * etc/classification.config: * etc/gen-msg.map: * etc/snort.conf: Replaced snort.conf with the version we ship in the rules tarball. Fixed a duplicate entry in gen-msg.map. * src/decode.c: * src/decode.h: Added alert for IPv6/UDP packets with zero checksum. * src/detection-plugins/detection_options.c: * src/detection-plugins/sp_byte_check.c: * src/detection-plugins/sp_byte_jump.c: * src/detection-plugins/sp_isdataat.c: For byte_test, byte_jump, and isdataat, only do an in bounds check of the doe_ptr if the rule option is relative and will be using the doe_ptr. * src/detection-plugins/sp_pattern_match.c: Fixed a valgrind error. * src/detection-plugins/sp_react.c: Removed instances of the word "porn" from Snort. * src/dynamic-plugins/sf_convert_dynamic.c: * src/dynamic-plugins/sf_engine/sf_snort_packet.h: * src/dynamic-plugins/sp_dynamic.c: Changed the parsing of dynamic detection plugins to register dynamic rules per policy. * src/dynamic-preprocessors/ftptelnet/pp_ftp.c: * src/dynamic-preprocessors/ftptelnet/spp_ftptelnet.c: * src/preprocessors/spp_stream5.c: * src/preprocessors/stream_api.h: * src/preprocessors/stream_ignore.h: * src/target-based/sftarget_protocol_reference.c: The FTP preprocessor now marks data channels with the "ftp-data" service identifier. Adaptive profiling must be turned on for this. * src/dynamic-preprocessors/sdf/sdf_credit_card.c: * src/dynamic-preprocessors/sdf/sdf_detection_option.c: * src/dynamic-preprocessors/sdf/sdf_pattern_match.c: * src/dynamic-preprocessors/sdf/sdf_pattern_match.h: * src/dynamic-preprocessors/sdf/sdf_us_ssn.c: * src/dynamic-preprocessors/sdf/spp_sdf.c: * src/dynamic-preprocessors/sdf/spp_sdf.h: * src/generators.h: Moved the sensitive data preprocessor's preproc rule to GID 139. Fixed the ability to reload Snort with sensitive_data turned on. Fixed bugs in the parsing of "sd_pattern" rules that overlapped. U.S. Social Security numbers are now required to have non-digits on either side in order to cause a match. * src/mempool.c: * src/preprocessors/HttpInspect/client/hi_client.c: * src/preprocessors/HttpInspect/include/hi_include.h: * src/preprocessors/HttpInspect/include/hi_mi.h: * src/preprocessors/HttpInspect/include/hi_server.h: * src/preprocessors/HttpInspect/include/hi_ui_config.h: * src/preprocessors/HttpInspect/include/hi_util.h: * src/preprocessors/HttpInspect/mode_inspection/hi_mi.c: * src/preprocessors/HttpInspect/normalization/hi_norm.c: * src/preprocessors/HttpInspect/server/hi_server.c: * src/preprocessors/HttpInspect/user_interface/hi_ui_config.c: * src/preprocessors/snort_httpinspect.c: * src/preprocessors/snort_httpinspect.h: Added a "max_gzip_mem" option to http_inspect. Use this to set the maximum amount of memory used for gzip decompression. The "+" sign is now normalized to a space. Added a "disable" option to http_inspect so that a memcap can be set without enabling http_inspect across all VLANs. * src/preprocessors/sfprocpidstats.c: * src/preprocessors/sfprocpidstats.h: * src/preprocessors/spp_perfmonitor.c: Fixed a memory leak. * src/preprocessors/Stream5/snort_stream5_session.c: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/preprocessors/Stream5/snort_stream5_udp.c: Fixed an issue that could cause Snort to take minutes to reload. * src/snort.c: Unblocked signals that Snort does not handle itself. * src/win32/Makefile.am: * src/win32/WIN32-Includes/config.h: * src/win32/WIN32-Includes/mysql/config-netware.h: * src/win32/WIN32-Includes/mysql/config-os2.h: * src/win32/WIN32-Includes/mysql/config-win.h: * src/win32/WIN32-Includes/mysql/errmsg.h: * src/win32/WIN32-Includes/mysql/libmysqld.def: * src/win32/WIN32-Includes/mysql/libmysql.def: * src/win32/WIN32-Includes/mysql/m_ctype.h: * src/win32/WIN32-Includes/mysql/m_string.h: * src/win32/WIN32-Includes/mysql/my_alloc.h: * src/win32/WIN32-Includes/mysql/my_dbug.h: * src/win32/WIN32-Includes/mysql/my_getopt.h: * src/win32/WIN32-Includes/mysql/my_global.h: * src/win32/WIN32-Includes/mysql/my_list.h: * src/win32/WIN32-Includes/mysql/my_pthread.h: * src/win32/WIN32-Includes/mysql/mysql_com.h: * src/win32/WIN32-Includes/mysql/mysqld_error.h: * src/win32/WIN32-Includes/mysql/mysql_embed.h: * src/win32/WIN32-Includes/mysql/mysql.h: * src/win32/WIN32-Includes/mysql/mysql_time.h: * src/win32/WIN32-Includes/mysql/mysql_version.h: * src/win32/WIN32-Includes/mysql/my_sys.h: * src/win32/WIN32-Includes/mysql/raid.h: * src/win32/WIN32-Includes/mysql/typelib.h: * src/win32/WIN32-Prj/snort.dsw: * src/win32/WIN32-Prj/snort_installer.nsi: Updated the MySQL client library in the Windows build. Fixed a conflict between MSSQL headers and the newer Windows Platform SDK. 2010-01-27 Ryan Jordan * doc/Makefile.am: Added README.sensitive_data * doc/README.dcerpc2: Removed "events" from default configuration. * doc/README.http_inspect: Added support for extended ascii codes in HTTP request URI using a new configurable option "extended_ascii_uri" Changed the pattern match to search only the HTTP response body when extended response inspection is enabled. Also copy only the decompressed data into the decode buffer. * doc/README.INLINE: Content replacement now allows replacement strings of varying sizes. * doc/README.multipleconfigs: Limit number of individual networks per line to 512. * doc/README.stream5: Removed "min_ttl" option, added the latest stream alerts. * doc/snort_manual.tex: Fixed typos, updated the Snort manual to match the README updates. Eliminated the kick-ass and the lotion. Updated with new PCRE options. * etc/classification.config: Cleaned up classification.config. Thanks to Guise McAllaster for reporting this issue. * etc/gen-msg.map: Added sig ID for http_inspect's chunk size mismatch. * etc/snort.conf: Fixed typos. Default "dynamicengine" entry is now specified by directory. * src/build.h: Updated build number. * src/checksum.h: checksum calculation for icmpv6 added . also fixed a warning in hi_client.c * src/configure.in: Updated makefile/configure script to optionally build dynamic examples. Thanks to Markus Lude for raising the issue. Fixed linker option on Solaris 10 to use nanosleep. Thanks to Randal T. Rioux for reporting this issue. * src/decode.c: checksum calculation for icmpv6 added . also fixed a warning in hi_client.c * src/decode.h: Change the pattern match to search only the HTTP response body when extended response inspection is enabled. Also copy only the decompressed data into the decode buffer. * src/detect.c: Formatting changes. * src/detection-plugins/sp_asn1.c: * src/detection-plugins/sp_byte_check.c: * src/detection-plugins/sp_ip_proto.c: Replaced strol and strtoul with inline functions that reset errno first. * src/detection-plugins/sp_pattern_match.c: Check if file_data is within the packet boundaries and set the search depth accordingly. * src/detection-plugins/sp_pcre.c: Pcre new options fix. Raw options and status options werent matching as expected. * src/detection-plugins/sp_replace.c: checksum calculation for icmpv6 added . also fixed a warning in hi_client.c * src/dynamic-examples/Makefile.am: * src/Makefile.am: Update makefile/configure script to optionally build dynamic examples. * src/dynamic-plugins/sf_dynamic_plugins.c: Replaced strol and strtoul with inline functions that reset errno first. * src/dynamic-plugins/sf_dynamic_preprocessor.h: * src/event_queue.c: * src/event_queue.h: * src/preprocessors/spp_frag3.c: * src/dynamic-preprocessors/dcerpc2/snort_dce2.c: * src/sfutil/sfeventq.h: * src/snort.c: * src/snort.h: Fixed a bug where Snort would log a packet other than the one triggering the alert. * src/dynamic-preprocessors/dcerpc2/dce2_debug.c: * src/dynamic-preprocessors/dcerpc2/dce2_roptions.c: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: * src/dynamic-preprocessors/libs/sfparser.c: * src/output-plugins/spo_unified2.c: * src/parser.c: * src/preprocessors/spp_perfmonitor.c: * src/preprocessors/Stream5/snort_stream5_tcp.c: Replaced strol and strtoul with inline functions that reset errno first. * src/dynamic-preprocessors/dcerpc2/sf_preproc_info.h: * src/dynamic-preprocessors/dns/sf_preproc_info.h: * src/dynamic-preprocessors/ftptelnet/sf_preproc_info.h: * src/dynamic-preprocessors/smtp/sf_preproc_info.h: * src/dynamic-preprocessors/ssh/sf_preproc_info.h: * src/dynamic-preprocessors/ssl/sf_preproc_info.h: Updated build version number. * src/dynamic-preprocessors/sdf/.cvsignore: Added .cvsignore file * src/dynamic-preprocessors/sdf/sdf_credit_card.c: * src/dynamic-preprocessors/sdf/sdf_credit_card.h: Added license text. Added check for the Issuer Number in credit card numbers. * src/dynamic-preprocessors/sdf/sdf_detection_option.c: * src/dynamic-preprocessors/sdf/sdf_detection_option.h: * src/dynamic-preprocessors/sdf/sdf_pattern_match.c: * src/dynamic-preprocessors/sdf/sdf_pattern_match.h: Added license text. Fixed error when using the same sensitive data rule in multiple policies. Sensitive data rules must use the preprocessor's generator ID. * src/dynamic-preprocessors/sdf/sdf_us_ssn.c: * src/dynamic-preprocessors/sdf/sdf_us_ssn.h: Added license text. * src/dynamic-preprocessors/sdf/spp_sdf.c: * src/dynamic-preprocessors/sdf/spp_sdf.h: Fixed double-free when the preprocessor was enabled in multiple policies. Added the ability to search HTTP Uri buffers for sensitive data. Fixed the pcap header for pseudo-packets generated by the preprocessor. * src/fpcreate.c: OpenBSD update * src/generators.h: Added alert for HTTP chunk size mismatch. * src/obfuscation.c: Made a debug message optionally compilable. * src/output-plugins/spo_log_tcpdump.c: Fix use of -L option to work correctly. Thanks to Allan Adkins for reporting this issue. * src/preprocessors/HttpInspect/client/hi_client.c: * src/preprocessors/HttpInspect/event_output/hi_eo_log.c: * src/preprocessors/HttpInspect/include/hi_eo_events.h: * src/preprocessors/HttpInspect/include/hi_ui_config.h: * src/preprocessors/HttpInspect/include/hi_include.h: * src/preprocessors/HttpInspect/include/hi_util.h: * src/preprocessors/HttpInspect/server/hi_server.c: Added http response stats. Added support for extended ascii codes in HTTP request URI using a new configurable option "extended_ascii_uri" Added an alert for incorrect chunk size fields. * src/preprocessors/perf.c: Fixed null deref when "rotate stats" signal was caught w/out perfmon enabled. * src/preprocessors/snort_httpinspect.c: Fixed a case where the HTTP Inspect preprocessor would disable the Sensitive Data preprocessor. * src/preprocessors/spp_httpinspect.c: Decompressed bytes read will now be based on the total out of zstream. * src/target-based/sftarget_reader.c: attribute table printing - converting to host order before printing the ip address * src/util.c: * src/util.h: adding zlib version information for snort -V * src/win32/Makefile.am: Add zlib 1.2.3 to Win32 build. * src/win32/WIN32-Includes/config.h: * src/win32/WIN32-Includes/zlib/zconf.h: * src/win32/WIN32-Includes/zlib/zlib.h: * src/win32/WIN32-Prj/snort.dsp: Add zlib 1.2.3 to Win32 build. * src/win32/WIN32-Prj/snort_installer.nsi: Added Sensitive Data preproc to Windows installer script. 2009-12-21 Ryan Jordan * doc/README.dcerpc: Added deprecation notice. * doc/README.dcerpc2: Added note about fast pattern contents. * doc/README.filters: Slight change to indicate that filters were introduced in 2.8.5, which is no longer the current version. * doc/README.flowbits: Added documentation for flowbit groups. * doc/README.http_inspect: Added documentation for new HTTP rule options. * doc/snort_manual.tex: Updated for HTTP rule options and other cleanup. * doc/TODO: Removed obfuscation code from the TODO. * etc/gen-msg.map: Added new Stream5 alert for the "TCP 4-way handshake" * etc/snort.conf: Fixed typos. Added examples for Unified2 output and Sensitive Data preprocessor config. * rpm/snort.spec: Updated version number. * src/bounds.h: Formatting change. Added "SafeMemCheck" function. Modified "SafeMemcpy" and "SafeMemset" to use it. * src/build.h: Updated build number. * src/debug.c: Moved definition for snort_conf. * src/decode.h: Made changes for HTTP response gzip support. * src/detect.c: Updated to use new Obfuscation API. * src/sfutil/mpse.c: * src/sfutil/mpse.h: * src/fpcreate.c: * src/fpcreate.h: * src/sfutil/acsmx2.c: * src/sfutil/acsmx2.h: Added support for ac "split" pattern matcher to use less memory with improved performance over ac-bnfa. Thanks to Charlie Lasswell for the ideas! * src/detect.h: * src/event_wrapper.c: * src/event_wrapper.h: * src/inline.c: * src/profiler.c: * src/rate_filter.h: * src/rules.h: * src/tag.c: * src/tag.h: * src/treenodes.h: OTNs and RTNs were moved to their own header file. * src/detection-plugins/detection_options.c: * src/detection-plugins/Makefile.am: * src/detection-plugins/sp_file_data.c: * src/detection-plugins/sp_file_data.h: New detection option "file_data" was added. * src/detection-plugins/detection_options.h: * src/rule_option_types.h: Moved option_type_t to its own header file. * src/detection-plugins/sp_flowbits.c: * src/detection-plugins/sp_flowbits.h: allowing flowbits group name only with set and toggle operations check if the content rules have http modifiers. * src/detection-plugins/sp_replace.c: need to check from the relative depth for bounds adjust the bounds while replacing to prevent buffer overflow. allow replace with different size strings. enhancement to replace. * src/detection-plugins/sp_isdataat.c: negated isdataat support. * src/detection-plugins/sp_pattern_match.c: * src/detection-plugins/sp_pattern_match.h: Update pattern match parsing to error on invalid rules. * src/detection-plugins/sp_asn1.c: * src/detection-plugins/sp_byte_check.c: * src/detection-plugins/sp_byte_jump.c: * src/detection-plugins/sp_clientserver.c: * src/detection-plugins/sp_cvs.c: * src/detection-plugins/sp_dsize_check.c: * src/detection-plugins/sp_ftpbounce.c: * src/detection-plugins/sp_icmp_code_check.c: * src/detection-plugins/sp_icmp_id_check.c: * src/detection-plugins/sp_icmp_seq_check.c: * src/detection-plugins/sp_icmp_type_check.c: * src/detection-plugins/sp_ip_fragbits.c: * src/detection-plugins/sp_ip_id_check.c: * src/detection-plugins/sp_ipoption_check.c: * src/detection-plugins/sp_ip_proto.c: * src/detection-plugins/sp_ip_proto.h: * src/detection-plugins/sp_ip_same_check.c: * src/detection-plugins/sp_ip_tos_check.c: * src/detection-plugins/sp_pcre.c: * src/detection-plugins/sp_pcre.h: * src/detection-plugins/sp_react.c: * src/detection-plugins/sp_respond2.c: * src/detection-plugins/sp_respond.c: * src/detection-plugins/sp_rpc_check.c: * src/detection-plugins/sp_session.c: * src/detection-plugins/sp_tcp_ack_check.c: * src/detection-plugins/sp_tcp_flag_check.c: * src/detection-plugins/sp_tcp_seq_check.c: * src/detection-plugins/sp_tcp_win_check.c: * src/detection-plugins/sp_ttl_check.c: * src/detection-plugins/sp_urilen_check.c: * src/dynamic-preprocessors/ftptelnet/spp_ftptelnet.c: * src/dynamic-preprocessors/ssl/spp_ssl.c: Updated calls to RegisterRuleOption() to match new definiton. * src/dynamic-plugins/sf_convert_dynamic.c: Updated conversion of Content and PCRE rule options to match HTTP changes. * src/dynamic-plugins/sf_dynamic_common.h: Updated HTTP flags. * src/dynamic-plugins/sf_dynamic_engine.h: * src/dynamic-plugins/sp_preprocopt.c: * src/dynamic-plugins/sp_preprocopt.h: Added definition of OTN Handler. A detection option or preprocessor can register one of these to get the OTN of any rule using its rule option. * src/dynamic-plugins/sf_dynamic_plugins.c: * src/dynamic-plugins/sf_dynamic_preprocessor.h: * src/dynamic-plugins/sf_preproc_example/sf_dynamic_preproc_lib.c: Added several items to DynamicPreprocessorData, to allow dynamic preprocessors to call more Snort functions. * src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.h: * src/dynamic-plugins/sf_engine/sf_snort_plugin_content.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_pcre.c: * src/dynamic-plugins/sp_dynamic.c: * src/dynamic-plugins/sp_dynamic.h: Check for HTTP modifiers to Content and PCRE options in shared object rules. * src/dynamic-plugins/sf_engine/sf_snort_packet.h: Added missing Packet member to SFSnortPacket. * src/dynamic-preprocessors/dcerpc/dcerpc.c: * src/dynamic-preprocessors/dcerpc/dcerpc.h: Moved DCERPC_FragType definition. * src/dynamic-preprocessors/dcerpc/dcerpc_config.c: * src/dynamic-preprocessors/dcerpc/snort_dcerpc.h: * src/dynamic-preprocessors/dcerpc/spp_dcerpc.c: * src/dynamic-preprocessors/dcerpc2/dce2_co.c: * src/dynamic-preprocessors/dcerpc2/dce2_config.c: * src/dynamic-preprocessors/dcerpc2/snort_dce2.c: * src/preprocessors/portscan.h: * src/preprocessors/spp_frag3.c: * src/preprocessors/spp_sfportscan.c: Added "disabled" option to frag3_global, stream5_global, portscan, dcerpc, and dcerpc2 preprocessor configurations so that memcaps can be specified in the default configuration w/o enabling that preprocessor. This allows specification of the preprocessors only in the desired configuration. * src/dynamic-preprocessors/dcerpc/Makefile.am: * src/dynamic-preprocessors/dcerpc2/Makefile.am: * src/dynamic-preprocessors/dns/Makefile.am: * src/dynamic-preprocessors/dns/sf_dns.dsp: * src/dynamic-preprocessors/ftptelnet/Makefile.am: * src/dynamic-preprocessors/ftptelnet/sf_ftptelnet.dsp: * src/dynamic-preprocessors/smtp/Makefile.am: * src/dynamic-preprocessors/ssh/Makefile.am: * src/dynamic-preprocessors/ssl/Makefile.am: * src/dynamic-preprocessors/smtp/sf_smtp.dsp: * src/dynamic-preprocessors/ssh/sf_ssh.dsp: * src/dynamic-preprocessors/ssl/sf_ssl.dsp: Fix make dist to include all required files. * src/dynamic-preprocessors/dcerpc2/dce2_event.c: * src/dynamic-preprocessors/dcerpc2/dce2_list.h: * src/dynamic-preprocessors/dcerpc2/dce2_utils.c: * src/dynamic-preprocessors/dcerpc2/dce2_utils.h: * src/dynamic-preprocessors/dcerpc2/includes/dcerpc.h: Changed use of some integers to enumerated types. * src/dynamic-preprocessors/dcerpc2/dce2_roptions.c: Added dce_iface options to the fast pattern matcher. * src/dynamic-preprocessors/dcerpc2/snort_dce2.h: * src/dynamic-preprocessors/dcerpc2/dce2_config.h: * src/dynamic-preprocessors/smtp/snort_smtp.c: Added sensitive data to the list of preprocs that get re-enabled after disabling detection. * src/dynamic-preprocessors/dcerpc2/spp_dce2.c: Removed config file/line from error message since not set at this point. Also removed redundant "dcerpc2 configuration" text. * src/dynamic-preprocessors/Makefile.am: * src/dynamic-preprocessors/treenodes.sed: Included more header files for use in dynamic preprocessors. * src/dynamic-preprocessors/sdf/Makefile.am: * src/dynamic-preprocessors/sdf/sdf_credit_card.c: * src/dynamic-preprocessors/sdf/sdf_credit_card.h: * src/dynamic-preprocessors/sdf/sdf_detection_option.c: * src/dynamic-preprocessors/sdf/sdf_detection_option.h: * src/dynamic-preprocessors/sdf/sdf_pattern_match.c: * src/dynamic-preprocessors/sdf/sdf_pattern_match.h: * src/dynamic-preprocessors/sdf/sdf_us_ssn.c: * src/dynamic-preprocessors/sdf/sdf_us_ssn.h: * src/dynamic-preprocessors/sdf/sf_preproc_info.h: * src/dynamic-preprocessors/sdf/sf_sdf.dsp: * src/dynamic-preprocessors/sdf/spp_sdf.c: * src/dynamic-preprocessors/sdf/spp_sdf.h: * src/dynamic-preprocessors/sf_dynamic_initialize/sf_dynamic_initialize.dsp: * src/preprocids.h: * doc/README.sensitive_data: * doc/snort_manual.tex: Added Sensitive Data preprocessor. It performs detection of Personally Identifiable Information, such as credit card numbers and U.S. Social Security numbers. * src/dynamic-preprocessors/ssh/spp_ssh.c: Formatting change. * src/fpcreate.c: * src/fpcreate.h: * src/fpdetect.c: Content rules with the new HTTP modifiers can use the fast pattern matcher. * src/generators.h: Added SIDs for new preprocessor alerts. * src/Makefile.am: Added new files to Makefile. * src/obfuscation.c: * src/obfuscation.h: * src/util.c: * src/util.h: Fixed output obfuscation, and added an Obfuscation API for use in preprocessors & output plugins. * src/log.c: * src/log.h: * src/log_text.c: * src/log_text.h: * src/output-plugins/spo_alert_fast.c: * src/output-plugins/spo_alert_full.c: * src/output-plugins/spo_alert_prelude.c: * src/output-plugins/spo_alert_sf_socket.c: * src/output-plugins/spo_alert_syslog.c: * src/output-plugins/spo_alert_test.c: * src/output-plugins/spo_alert_unixsock.c: * src/output-plugins/spo_csv.c: * src/output-plugins/spo_database.c: * src/output-plugins/spo_log_ascii.c: * src/output-plugins/spo_log_null.c: * src/output-plugins/spo_log_tcpdump.c: * src/output-plugins/spo_unified2.c: * src/output-plugins/spo_unified.c: Modified several output plugins to print obfuscated data using the new Obfuscation API. * src/parser.c: * src/parser.h: Added support for OTN handlers. Added support for using new http content options with the fast pattern matcher. * src/pcrm.c: * src/pcrm.h: Formatting changes. * src/plugbase.c: * src/plugbase.h: Added OTN handler argument to the RegisterRuleOption() function. Initialized the "file_data" rule option. * src/ppm.c: * src/ppm.h: Remove non-portlists code. * src/preprocessors/HttpInspect/client/hi_client.c: * src/preprocessors/HttpInspect/client/hi_client_norm.c: * src/preprocessors/HttpInspect/include/hi_client.h: * src/preprocessors/HttpInspect/include/hi_eo_events.h: * src/preprocessors/HttpInspect/include/hi_mi.h: * src/preprocessors/HttpInspect/include/hi_norm.h: * src/preprocessors/HttpInspect/include/hi_server.h: * src/preprocessors/HttpInspect/include/hi_server_norm.h: * src/preprocessors/HttpInspect/include/hi_ui_config.h: * src/preprocessors/HttpInspect/include/hi_util.h: * src/preprocessors/HttpInspect/include/Makefile.am: * src/preprocessors/HttpInspect/Makefile.am: * src/preprocessors/HttpInspect/mode_inspection/hi_mi.c: * src/preprocessors/HttpInspect/normalization/hi_norm.c: * src/preprocessors/HttpInspect/server/hi_server.c: * src/preprocessors/HttpInspect/server/hi_server_norm.c: * src/preprocessors/HttpInspect/server/Makefile.am: * src/preprocessors/HttpInspect/session_inspection/hi_si.c: * src/preprocessors/HttpInspect/user_interface/hi_ui_config.c: * src/preprocessors/snort_httpinspect.c: * src/preprocessors/snort_httpinspect.h: * src/preprocessors/spp_httpinspect.c: New feature for HTTP Inspect to split requests into 5 components - Method, URI, Header (non-cookie), Cookies, Body. Added HTTP server specific configurations to normalize HTTP header and/or cookie buffers. Provided content and PCRE modifiers to allow searches within one or more of those individual buffers. Added content modifier to allow rule writer to specify content to be used for fast pattern matcher. Updated dynamic rule API to allow searches within the new buffers. * src/preprocessors/perf.c: * src/preprocessors/spp_perfmonitor.c: * src/preprocessors/perf-flow.c: * src/preprocessors/perf-flow.h: * src/preprocessors/perf.h: * src/preprocessors/Stream5/snort_stream5_udp.c: Add Flow-IP stats to the Performance Monitor preprocessor. Write out a commented line to the now file the first time perfmon Reduce performance overhead when FlowIP stats aren't enabled. * src/preprocessors/sfprocpidstats.c: Changed GetCpuName() to catch errno when sscanf() sets it. * src/preprocessors/spp_rpc_decode.c: Fixed warnings when compiled in Win32. * src/preprocessors/spp_stream5.c: * src/preprocessors/Stream5/snort_stream5_session.h: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/preprocessors/Stream5/snort_stream5_tcp.h: * src/preprocessors/Stream5/stream5_common.c: * src/preprocessors/Stream5/stream5_common.h: * src/preprocessors/stream_api.h: Added detection of "4-way TCP Handshake" when require_3whs is enabled. Added "disabled" option so that memcaps can be configured in the default policy w/out enabling the preprocessor. Added support for output obfuscation. * src/prototypes.h: * src/sys_include.h: Removed more obsolete/unused files. * src/sfthreshold.c: * src/sfutil/acsmx2.c: * src/sfutil/acsmx2.h: * src/sfutil/bnfa_search.c: * src/sfutil/ipobj.c: * src/sfutil/ipobj.h: * src/sfutil/Makefile.am: * src/sfutil/mpse.c: * src/sfutil/mpse.h: * src/sfutil/sf_ip.c: * src/sfutil/sf_ip.h: * src/sfutil/sf_iph.c: * src/sfutil/sf_ipvar.c: * src/sfutil/sfksearch.c: * src/sfutil/sfPolicyUserData.c: * src/sfutil/sfPolicyUserData.h: * src/sfutil/sfportobject.c: * src/sfutil/sfxhash.c: * src/sfutil/sfrf.c: * src/sfutil/sfrt_trie.h: * src/sfutil/sf_vartable.c: Cleaned up warnings, especially when compiled with ICC. * src/sfutil/util_net.c: * src/sfutil/util_net.h: Fix ip obfuscation to not modify packet data and only obfuscate for text outputs. * src/signature.c: * src/signature.h: * src/snort.c: * src/snort.h: Remove non-portlists code. * src/target-based/sf_attribute_table_parser.l: * src/target-based/sftarget_reader.c: Use bison built in YYACCEPT and YYABORT so stack is cleaned up and freed. * src/win32/WIN32-Code/syslog.c: * src/win32/WIN32-Code/win32_service.c: * src/win32/WIN32-Includes/config.h: * src/win32/WIN32-Prj/snort.dsp: * src/win32/WIN32-Prj/snort.dsw: * src/win32/WIN32-Prj/snort_installer.nsi: Win32 project files updated to reflect Makefile changes. 2009-12-15 Ryan Jordan * doc/snort_manual.tex: Clarified the documentation for output plugins alert_fast, alert_full, log_tcpdump, and alert_csv. Added documentation for log limits. * etc/gen-msg.map: * src/generators.h: * src/preprocessors/HttpInspect/client/hi_client.c: * src/preprocessors/HttpInspect/event_output/hi_eo_log.c: * src/preprocessors/HttpInspect/include/hi_client.h: * src/preprocessors/HttpInspect/include/hi_eo_events.h: Changes to improve handling of pipelined requests and chunked encodings based on content length header field. * src/preprocessors/snort_httpinspect.c: Fix error message for validation of client_flow_depth. * src/build.h: Updated build number * src/codes.c: * src/codes.h: * src/detection-plugins/sp_respond2.h: Removed unused code. * src/dynamic-preprocessors/dcerpc2/dce2_smb.c: * src/dynamic-preprocessors/dcerpc2/snort_dce2.c: Set IPv6 UDP DCE/RPC reassembly headers. * src/dynamic-preprocessors/Makefile.am: Exported more files to allow re-building of some .so files on NetBSD. * src/dynamic-preprocessors/ssh/spp_ssh.c: * src/dynamic-preprocessors/ssh/spp_ssh.h: Fixed an issue where the SSH preprocessor would erroneously alert on "protocol mismatch" when autodetect was turned on. * src/log.h: * src/parser.c: Fixed reloading of auto-iface variables after privileges had been dropped. Thanks to Pablo Catalina for reporting this issue. * src/output-plugins/spo_alert_prelude.c: Fixed compiling on AIX 6, or with --enable-prelude and --enable-ipv6. Thanks to Rnadall Rioux for reporting the AIX issues. Thanks to Markus Lude for reporting the prelude & IPv6 issues. * src/preprocessors/spp_rpc_decode.c: * src/preprocessors/spp_stream5.c: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/preprocessors/Stream5/snort_stream5_tcp.h: * src/preprocessors/stream_api.h: Set smaller flush point appropriate for RPC header. * src/sfutil/Makefile.am: * src/sfutil/sf_ipvar.c: Fixed an error where negative IP lists were not always being checked. * src/sfutil/sfPolicy.c: * src/sfutil/sfPolicy.h: Fix to return correct vlan/ip id. * src/sfutil/sfrt.h: * src/sfutil/sfrt_trie.h: More compile fixes on AIX 6. * src/snort.c: * src/target-based/sftarget_reader.c: Fix issues at startup and perfstats rotation with old versions of libc (2.2, 2.3) & linux threads. * src/util.h: Added a function prototype for InitTimeStats. * src/win32/WIN32-Includes/config.h: Formatting changes. 2009-10-21 Ryan Jordan * doc/README.filters: added missing _. * doc/snort_manual.tex: Update to add PCRE modifiers that were left out of table 3.8. Fixed typos. * src/build.h: Updated build number. * src/codes.c: * src/codes.h: Removed unused code. * src/decode.c: When label > NUM_RESERVED_LABELS, iRet should be set based on the payload type * src/configure.in: * src/Makefile.am: * src/dynamic-examples/Makefile.am: * src/dynamic-examples/dynamic-preprocessor/Makefile.am: * src/dynamic-examples/dynamic-preprocessor/spp_example.c: Added the dynamic-examples back to the Makefile, and updated the example preprocessor to support multiple policies & config reloading. * src/detection-plugins/sp_pcre.c: fixed warning: ISO C90 forbids mixed declarations and code * src/detection-plugins/sp_respond2.h: separate flexresp interface from implementation Made react, resp, and resp2 independent except that libnet is only initialized/closed once regardless of build combinations. * src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c: Fixed a bug where dynamic rules were not initialized correctly after a snort.conf reload. * src/dynamic-preprocessors/dcerpc/spp_dcerpc.c: * src/dynamic-preprocessors/dcerpc2/dce2_config.c: * src/dynamic-preprocessors/dcerpc2/spp_dce2.c: * src/dynamic-preprocessors/dns/spp_dns.c: * src/dynamic-preprocessors/ftptelnet/spp_ftptelnet.c: * src/dynamic-preprocessors/smtp/spp_smtp.c: * src/dynamic-preprocessors/ssl/spp_ssl.c: * src/parser.c: * src/preprocessors/spp_httpinspect.c: * src/preprocessors/spp_rpc_decode.c: * src/preprocessors/spp_stream5.c: * src/preprocessors/Stream5/snort_stream5_session.c: * src/preprocessors/Stream5/snort_stream5_session.h: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/preprocessors/Stream5/snort_stream5_tcp.h: * src/preprocessors/Stream5/snort_stream5_udp.c: * src/preprocessors/Stream5/snort_stream5_udp.h: * src/preprocessors/Stream5/stream5_common.h: * src/preprocessors/stream_api.h: Fixed segfault when adding policies on reload Fixed potentially freed stream5 configuration being read on clean exit Fixed potentially wrong stream5 configuration being used during reload * src/dynamic-preprocessors/dcerpc2/dce2_co.c: Make log message a debug message * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: changing the return value * src/dynamic-preprocessors/ssh/spp_ssh.c: Fixed SSH preprocessor to use "FLPOLICY_IGNORE" when turning off Stream reassembly, as opposed to "FLPOLICY_NONE" * src/fpcreate.c: * src/profiler.c: Updated uses of IPPROTO_IP to ETHERNET_TYPE_IP * src/output-plugins/spo_alert_sf_socket.c: fixed otn lookup; due to not calling "first" function the configured gid/sids would not be found and so no no alerts would go out the socket and no errors reported. * src/log.c: use orig api and family for embedded icmp packet printing. Fixed out-of-bounds access when printing IPv6 packets using -v. * src/output-plugins/spo_database.c: Included missing "last_cid" column when inserting a new sensor into the table while "ignore_bpf" was turned on. * src/preprocessors/perf-base.c: Fixed inaccurate wire speed stats. * src/preprocessors/HttpInspect/client/hi_client.c: Updated previous bugfix to check for more possible return values. * src/preprocessors/spp_perfmonitor.c: Check if packet is stream rebuilt. Don't include in stats. * src/sfutil/sf_ip.h: processing of 0.0.0.0/x enabled. Only 0.0.0.0/32 is considered as "any". * src/sfutil/sfPolicy.c: fixed segfault when more than 10 policies were applied. * src/dynamic-preprocessors/sf_dynamic_initialize/sf_dynamic_initialize.dsp: * src/output-plugins/spo_alert_syslog.c: * src/win32/WIN32-Code/syslog.c: * src/win32/WIN32-Prj/sf_engine_initialize.dsp: * src/win32/WIN32-Prj/snort_initialize.dsp: Fix syslog output under Windows. * src/snort.c: enable -Q output with --help for !IPFW && !WIN32 builds; change text to be more accurrate. * src/snort.h: Handled MPLS BOS. * src/target-based/sf_attribute_table_parser.l: * src/target-based/sf_attribute_table.y: * src/target-based/sftarget_reader.c: Use bison built in YYACCEPT and YYABORT so stack is cleaned up and freed Free host entries that are not inserted into routing table due to max_attribute_hosts limit 2009-09-15 Ryan Jordan * doc/README.frag3: Removed ttl_limit option, as it has been deprecated. * doc/README.ftptelnet: Added the ignore_telnet_erase_cmds option. * doc/README.ssh: Fixed the documentation to reflect changes in SSH for 2.8.5. * doc/snort_manual.tex: Duplicated the above doc changes for the manual. Clarified order of rule actions. * etc/gen-msg.map: Punctuation changes. * etc/snort.conf: Fix the example SSH configuration, and turn it on by default. This should increase performance in situations where a lot of SSH traffic was inspected. * rpm/snort.spec: Updated version number. * src/build.h: Updated build number. * configure.in: Added configure switch to disable core files. * src/codes.c: * src/codes.h: Removed old/unused code. * src/debug.c: * src/sfutil/sfportobject.c: * src/snort.c: * src/snort.h: * src/util.c: redirect stdin/stdout/stderr to /dev/null for debug write to file and change ownership of file to dropped privs * src/decode.c: Allow support for label values of 0 or 2 at locations other than bottom of stack. * src/decode.h: * src/win32/WIN32-Prj/snort_installer.nsi: Moved a couple rules into the decoder. * src/detection-plugins/detection_options.c: * src/detection-plugins/detection_options.h: * src/detection-plugins/Makefile.am: * src/detection-plugins/sp_pattern_match.c: * src/detection-plugins/sp_pattern_match.h: * src/detection-plugins/sp_react.c: * src/detection-plugins/sp_react.h: * src/detection-plugins/sp_respond2.c: * src/detection-plugins/sp_respond2.h: * src/detection-plugins/sp_respond.c: * src/detection-plugins/sp_respond.h: * src/detection-plugins/sp_session.c: * src/win32/WIN32-Prj/snort.dsp: Made react, resp, and resp2 independent except that libnet is only initialized/closed once regardless of build combinations. * src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c: Added a new check to handle loading of older libraries. * src/dynamic-plugins/sf_dynamic_preprocessor.h: * src/dynamic-preprocessors/dcerpc/sf_preproc_info.h: * src/dynamic-preprocessors/dcerpc/snort_dcerpc.c: * src/dynamic-preprocessors/dcerpc2/sf_preproc_info.h: * src/dynamic-preprocessors/dcerpc2/snort_dce2.c: * src/dynamic-preprocessors/dcerpc2/spp_dce2.c: * src/dynamic-preprocessors/dns/sf_preproc_info.h: * src/dynamic-preprocessors/dns/spp_dns.c: * src/dynamic-preprocessors/ftptelnet/ftpp_si.c: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: * src/dynamic-preprocessors/ftptelnet/spp_ftptelnet.c: * src/dynamic-preprocessors/smtp/sf_preproc_info.h: * src/dynamic-preprocessors/ssh/sf_preproc_info.h: * src/dynamic-preprocessors/ssh/spp_ssh.h: * src/dynamic-preprocessors/ssl/sf_preproc_info.h: Changed the build numbers of preprocessors. * src/dynamic-preprocessors/dcerpc/spp_dcerpc.c: * src/preprocessors/spp_arpspoof.c: * src/preprocessors/spp_stream5.c: * src/sfutil/acsmx2.c: * src/sfutil/acsmx2.h: Fixed compile warnings. * src/preprocessors/spp_sfportscan.c: Don't include vlan header in portscan event/log packet. * src/preprocessors/Stream5/snort_stream5_tcp.c: Fix core by adjusting IPv6 buffer size * src/profiler.c: Clean up preprocessor profiler formatting. * src/dynamic-preprocessors/ssh/spp_ssh.c: Changed limit on max_server_version_len to 255. * src/dynamic-preprocessors/smtp/smtp_log.h: * src/dynamic-preprocessors/smtp/smtp_xlink2state.c: * src/dynamic-preprocessors/smtp/spp_smtp.c: * src/generators.h: Gave xlink2state smtp preprocessor alert a unique sid. * src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c: Fixed memory leaks. * src/fpcreate.c: Fixed potential segfault with multiplie policies. * src/fpdetect.c: * src/fpdetect.h: * src/preprocessors/perf-base.c: * src/preprocessors/perf.c: * src/preprocessors/perf-event.c: * src/preprocessors/perf-event.h: * src/preprocessors/perf-flow.c: * src/preprocessors/perf-flow.h: * src/preprocessors/spp_frag3.c: * src/preprocessors/spp_perfmonitor.c: * src/sfutil/sfActionQueue.c: IPv6-related changes. * src/mempool.c: Check return values from mempool_init and fatal if bad when freeing pools, set to NULL. * src/preprocessors/Stream5/snort_stream5_icmp.c: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/preprocessors/Stream5/snort_stream5_udp.c: * src/sfutil/sfPolicy.c: Added additional error-checking. * src/output-plugins/spo_unified.c: * src/parser.c: * src/parser.h: * src/signature.c: * src/signature.h: Fixed a couple invalid reads & writes. * src/plugbase.c: Check configuration for all policies. * snort_head/snort/snort.8: Updated man page to reflect doc changes. 2009-07-13 Ryan Jordan * src/win32/WIN32-Prj/sf_testdetect.dsp: * src/win32/WIN32-Prj/snort.dsp: * src/win32/WIN32-Prj/snort.dsw: Win32 updates. * configure.in: Update for module pack confliction. * snort.8: Removed obsolete option -o * doc/CREDITS: Updated credits to reflect Snort 2.8.5 work * doc/INSTALL: Indentation changes, update for Mac * doc/Makefile.am: Added README.filters * doc/README.filters: New README, describes the new filtering features in Snort 2.8.5 * doc/README.frag3: Added the overlap_limit and min_fragment_length options * doc/README.ftptelnet: Indentation changes * doc/README.http_inspect: Added post_depth option. * doc/README.INLINE: Changed "snort_inline" to "Snort Inline" * doc/README.PerfProfiling: Updated stats output to reflect "Rev" column * doc/README.reload: New README, describes how to reload a Snort configuration in 2.8.5 * doc/README.ssh: Updated the README to reflect changes in the SSH preprocessor for 2.8.5 * doc/README.thresholding: Updated to indicate that "threshold" is deprecated in favor of "event_filter". * doc/snort_manual.tex: Updated to include 2.8.5 features, formatting updates. Removed old references to Stream4. * etc/gen-msg.map: Moved XMAS attack handling to decoder. Gave xlink2state smtp preprocessor alert unique sid. * etc/threshold.conf: Updated with formatting changes, deprecation notice for "threshold" * src/build.h: New build number. * src/codes.c: * src/codes.h: Removed unused files. * src/decode.c: * src/decode.h: Made some options policy-specific. Removed a couple poorly-performing rules and made them into decoder checks instead. * src/detect.c: * src/ppm.h: Don't reset packet time * src/detection-plugins/sp_asn1.c: * src/detection-plugins/sp_asn1_detect.c: Removed redundant check. * src/detection-plugins/sp_isdataat.c: * src/detection-plugins/sp_isdataat.h: Moved flags & struct to header file. * src/detection-plugins/sp_pattern_match.c: * src/detection-plugins/sp_replace.c: * src/detection-plugins/sp_replace.h: Check for combination of "replace" and "http_*" options, which are incompatible. * src/detection-plugins/sp_respond2.c: * src/detection-plugins/sp_respond.c: Renamed respond's config so it didn't conflict with gloabl Snort config. * src/dynamic-plugins/sf_convert_dynamic.c: * src/dynamic-plugins/sf_convert_dynamic.h: Added a missing handler for "isdataat" options in .so rules. * src/dynamic-plugins/sf_dynamic_engine.h: * src/dynamic-plugins/sf_dynamic_plugins.c: * src/dynamic-plugins/sf_dynamic_preprocessor.h: * src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c: * src/dynamic-plugins/sf_engine/sf_snort_packet.h: * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.h: * src/dynamic-plugins/sf_engine/sf_snort_plugin_byte.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_content.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_hdropts.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_loop.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_pcre.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_rc4.c: * src/dynamic-plugins/sp_dynamic.c: * src/dynamic-plugins/sp_dynamic.h: * src/dynamic-plugins/sp_preprocopt.c: * src/dynamic-plugins/sp_preprocopt.h: * src/ipv6_port.h: * src/sfutil/sf_ip.c: * src/sfutil/sf_ip.h: Changed variables from "uintX_t" to "u_intX_t". * src/dynamic-preprocessors/dcerpc2/dce2_cl.c: * src/dynamic-preprocessors/dcerpc2/dce2_co.c: * src/dynamic-preprocessors/dcerpc2/dce2_co.h: * src/dynamic-preprocessors/dcerpc2/dce2_event.c: * src/dynamic-preprocessors/dcerpc2/dce2_smb.c: * src/dynamic-preprocessors/dcerpc2/dce2_smb.h: * src/dynamic-preprocessors/dcerpc2/dce2_stats.h: * src/dynamic-preprocessors/dcerpc2/snort_dce2.c: * src/dynamic-preprocessors/dcerpc2/spp_dce2.c: Added detection for DCE/RPC server->client attacks. * src/dynamic-preprocessors/ftptelnet/ftpp_ui_client_lookup.c: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_server_lookup.c: Fixed memory leak. * src/dynamic-preprocessors/ftptelnet/pp_ftp.c: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.h: * src/dynamic-preprocessors/ftptelnet/spp_ftptelnet.c: Fixed some FTP false positives. * src/dynamic-preprocessors/smtp/smtp_config.c: * src/dynamic-preprocessors/smtp/smtp_xlink2state.c: * src/dynamic-preprocessors/smtp/spp_smtp.c: * src/dynamic-preprocessors/ssh/spp_ssh.c: * src/dynamic-preprocessors/ssl/spp_ssl.c: Fixed multiple policy support in these preprocessors. * src/fpdetect.c: * src/rules.h: One rule can have different actions in different policies. * src/generators.h: Changed SSL preprocessor's ID to avoid conflict with DCE/RPC 2 * src/inline.c: Win32 updates * src/log.c: Fixed issue with verbose output while in IDS mode. * src/mempool.c: * src/mempool.h: * src/preprocessors/portscan.c: * src/sfutil/Makefile.am: * src/sfutil/sfActionQueue.c: * src/sfutil/sfActionQueue.h: Made several config options specific to bound policies. * src/output-plugins/spo_unified2.h: Used 104 and 105 for the VLAN+MPLS event records. * src/parser/IpAddrSet.c: * src/parser/IpAddrSet.h: Clean up IpAddrSet in rate filter and suppress * src/parser.c: * src/parser.h: Fixed warnings * src/preprocessors/HttpInspect/include/hi_ui_config.h: * src/preprocessors/HttpInspect/session_inspection/hi_si.c: * src/preprocessors/HttpInspect/user_interface/hi_ui_config.c: * src/preprocessors/snort_httpinspect.c: * src/preprocessors/spp_httpinspect.c: HTTP Inspect now allows 1024 server profiles. The storage size was reduced. * src/preprocessors/spp_frag3.c: Fixed problem where Snort wouldn't reload if prealloc_memcap was specified. * src/preprocessors/spp_perfmonitor.c: Fixed problem where "now" file stopped updating after a reload. * src/preprocessors/spp_sfportscan.c: * src/sfutil/sfportobject.c: * src/sfutil/sfrf.c: * src/sfutil/sfthd.c: * src/sfutil/sfthd.h: Fixed memory leaks. * src/preprocessors/spp_stream5.c: * src/sfutil/sfPolicyUserData.c: * src/sfutil/sfPolicyUserData.h: * src/target-based/sftarget_reader.c: * src/target-based/sftarget_reader.h: Update for linuxthreads. * src/preprocessors/Stream5/snort_stream5_tcp.c: Added -H command-line option. Uses 192 for all TCP flushpoints. Only useful for repeatability while testing Snort. * src/profiler.c: Added rule revision to profiling output. * src/rate_filter.c: * src/rate_filter.h: Automatically enable "session delete" events with "session add" events. * src/sf_sdlist.c: * src/sfutil/sf_ipvar.c: Formatting changes * src/sf_types.h: Win32 updates * src/snort.c: * src/snort.h: Several fixes involving policy reload * src/util.c: Formatting changes, updated references to snort.org. * src/util.h: Don't allow 0 for threshold count or seconds. 2009-05-06 Ryan Jordan * etc/gen-msg.map: Added new messages for MPLS and Frag3. * etc/snort.conf: Modified an example port number, and added overlap_limit to the default frag3_engine config. * src/detect.c: * src/detect.h: * src/detection_filter.c: * src/detection_filter.h: * src/rate_filter.c: * src/rate_filter.h: * src/sfthreshold.c: * src/sfthreshold.h: Added support for detection_filter, rate_filter, and event_filter. See doc/README.filters for more info. * src/detection-plugins/Makefile.am: * src/detection-plugins/sp_hdr_opt_wrap.c: * src/detection-plugins/sp_hdr_opt_wrap.h: * src/dynamic-plugins/Makefile.am: * src/dynamic-plugins/sf_convert_dynamic.c: * src/dynamic-plugins/sf_convert_dynamic.h: * src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c: Changed the way .so rules are handled, to take advantage of the Rule Option Tree. * src/detection-plugins/sp_byte_check.c: * src/detection-plugins/sp_byte_check.h: Added support for ">=" and "<=" test options. * src/detection-plugins/sp_flowbits.c: * src/detection-plugins/sp_flowbits.h: * src/dynamic-plugins/sp_dynamic.c: Flowbits are now part of the rule stub that gets generated when dumping dynamic rules. * src/detection-plugins/sp_pattern_match.c: * src/detection-plugins/sp_pattern_match.h: * src/detection-plugins/sp_replace.c: * src/detection-plugins/sp_replace.h: Content replacement code moved out to sp_replace.{c,h} * src/detection-plugins/sp_pcre.c: * src/detection-plugins/sp_pcre.h: PCRE matches are no lnoger repeated if anchored. * src/decode.h: * src/dynamic-plugins/sf_engine/sf_snort_packet.h: Packet structure re-arranged, and other code cleanup. * src/dynamic-preprocessors/ssh/Makefile.am: * src/dynamic-preprocessors/ssh/sf_preproc_info.h: * src/dynamic-preprocessors/ssh/sf_ssh.dsp: * src/dynamic-preprocessors/ssh/spp_ssh.c: * src/dynamic-preprocessors/ssh/spp_ssh.h: Updated SSH preprocessor. Config options have been modified, see README.ssh for details. * src/parser.c: Fixed handling of IP lists with mis-matched brackets. * src/output-plugins/spo_unified2.c: * src/output-plugins/spo_unified2.h: MPLS and VLAN records have been consolidated into Unified2Event_v2. * src/win32/Makefile.am: * src/win32/WIN32-Code/inet_aton.c: * src/win32/WIN32-Code/misc.c: * src/win32/WIN32-Code/syslog.c: * src/win32/WIN32-Code/win32_service.c: * src/win32/WIN32-Includes/config.h: * src/win32/WIN32-Includes/stdint.h: * src/win32/WIN32-Prj/build_all.dsp: * src/win32/WIN32-Prj/sf_engine_initialize.dsp: * src/win32/WIN32-Prj/snort.dsp: * src/win32/WIN32-Prj/snort.dsw: * src/win32/WIN32-Prj/snort_initialize.dsp: * src/win32/WIN32-Prj/snort_installer.nsi: Updated Win32 installer to include new Snort files. * rpm/snort.spec: Updated RPM to include new Snort files. * doc/CREDITS: * doc/README.filters: * doc/README.frag3: * doc/README.http_inspect: * doc/README.ssh: * doc/README.thresholding: * doc/snort_manual.tex: Documentation updates. In addition, the following files were modified to enable: - Reloading snort.conf without restarting Snort - Applying multiple snort.confs on a per-vlan or per-CIDR block basis - Compiler warning clean-up * src/bounds.h: * src/byte_extract.c: * src/byte_extract.h: * src/checksum.h: * src/cpuclock.h: * src/debug.c: * src/decode.c: * src/detection-plugins/detection_options.c: * src/detection-plugins/detection_options.h: * src/detection-plugins/sp_asn1.c: * src/detection-plugins/sp_asn1_detect.c: * src/detection-plugins/sp_asn1_detect.h: * src/detection-plugins/sp_asn1.h: * src/detection-plugins/sp_byte_jump.c: * src/detection-plugins/sp_byte_jump.h: * src/detection-plugins/sp_clientserver.c: * src/detection-plugins/sp_clientserver.h: * src/detection-plugins/sp_cvs.c: * src/detection-plugins/sp_cvs.h: * src/detection-plugins/sp_dsize_check.c: * src/detection-plugins/sp_dsize_check.h: * src/detection-plugins/sp_ftpbounce.c: * src/detection-plugins/sp_ftpbounce.h: * src/detection-plugins/sp_icmp_code_check.c: * src/detection-plugins/sp_icmp_code_check.h: * src/detection-plugins/sp_icmp_id_check.c: * src/detection-plugins/sp_icmp_id_check.h: * src/detection-plugins/sp_icmp_seq_check.c: * src/detection-plugins/sp_icmp_seq_check.h: * src/detection-plugins/sp_icmp_type_check.c: * src/detection-plugins/sp_icmp_type_check.h: * src/detection-plugins/sp_ip_fragbits.c: * src/detection-plugins/sp_ip_fragbits.h: * src/detection-plugins/sp_ip_id_check.c: * src/detection-plugins/sp_ip_id_check.h: * src/detection-plugins/sp_ipoption_check.c: * src/detection-plugins/sp_ipoption_check.h: * src/detection-plugins/sp_ip_proto.c: * src/detection-plugins/sp_ip_same_check.c: * src/detection-plugins/sp_ip_same_check.h: * src/detection-plugins/sp_ip_tos_check.c: * src/detection-plugins/sp_ip_tos_check.h: * src/detection-plugins/sp_isdataat.c: * src/detection-plugins/sp_isdataat.h: * src/detection-plugins/sp_react.c: * src/detection-plugins/sp_react.h: * src/detection-plugins/sp_respond2.c: * src/detection-plugins/sp_respond2.h: * src/detection-plugins/sp_respond.c: * src/detection-plugins/sp_respond.h: * src/detection-plugins/sp_rpc_check.c: * src/detection-plugins/sp_rpc_check.h: * src/detection-plugins/sp_session.c: * src/detection-plugins/sp_session.h: * src/detection-plugins/sp_tcp_ack_check.c: * src/detection-plugins/sp_tcp_ack_check.h: * src/detection-plugins/sp_tcp_flag_check.c: * src/detection-plugins/sp_tcp_flag_check.h: * src/detection-plugins/sp_tcp_seq_check.c: * src/detection-plugins/sp_tcp_seq_check.h: * src/detection-plugins/sp_tcp_win_check.c: * src/detection-plugins/sp_tcp_win_check.h: * src/detection-plugins/sp_ttl_check.c: * src/detection-plugins/sp_ttl_check.h: * src/detection-plugins/sp_urilen_check.c: * src/detection-plugins/sp_urilen_check.h: * src/dynamic-plugins/sf_dynamic_common.h: * src/dynamic-plugins/sf_dynamic_define.h: * src/dynamic-plugins/sf_dynamic_detection.h: * src/dynamic-plugins/sf_dynamic_engine.h: * src/dynamic-plugins/sf_dynamic_plugins.c: * src/dynamic-plugins/sf_dynamic_preprocessor.h: * src/dynamic-plugins/sf_engine/Makefile.am: * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.h: * src/dynamic-plugins/sf_engine/sf_snort_plugin_byte.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_content.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_hdropts.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_loop.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_pcre.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_rc4.c: * src/dynamic-plugins/sf_preproc_example/sf_dynamic_preproc_lib.c: * src/dynamic-plugins/sf_preproc_example/sf_dynamic_preproc_lib.h: * src/dynamic-plugins/sp_dynamic.h: * src/dynamic-plugins/sp_preprocopt.c: * src/dynamic-plugins/sp_preprocopt.h: * src/dynamic-preprocessors/dcerpc/dcerpc.c: * src/dynamic-preprocessors/dcerpc/dcerpc_config.c: * src/dynamic-preprocessors/dcerpc/dcerpc.h: * src/dynamic-preprocessors/dcerpc/dcerpc_util.c: * src/dynamic-preprocessors/dcerpc/dcerpc_util.h: * src/dynamic-preprocessors/dcerpc/Makefile.am: * src/dynamic-preprocessors/dcerpc/sf_dcerpc.dsp: * src/dynamic-preprocessors/dcerpc/sf_preproc_info.h: * src/dynamic-preprocessors/dcerpc/smb_andx_decode.c: * src/dynamic-preprocessors/dcerpc/smb_andx_decode.h: * src/dynamic-preprocessors/dcerpc/smb_andx_structs.h: * src/dynamic-preprocessors/dcerpc/smb_file_decode.c: * src/dynamic-preprocessors/dcerpc/smb_file_decode.h: * src/dynamic-preprocessors/dcerpc/smb_file_structs.h: * src/dynamic-preprocessors/dcerpc/smb_structs.h: * src/dynamic-preprocessors/dcerpc/snort_dcerpc.c: * src/dynamic-preprocessors/dcerpc/snort_dcerpc.h: * src/dynamic-preprocessors/dcerpc/spp_dcerpc.c: * src/dynamic-preprocessors/dcerpc/spp_dcerpc.h: * src/dynamic-preprocessors/dcerpc2/dce2_cl.c: * src/dynamic-preprocessors/dcerpc2/dce2_co.c: * src/dynamic-preprocessors/dcerpc2/dce2_config.c: * src/dynamic-preprocessors/dcerpc2/dce2_config.h: * src/dynamic-preprocessors/dcerpc2/dce2_debug.c: * src/dynamic-preprocessors/dcerpc2/dce2_debug.h: * src/dynamic-preprocessors/dcerpc2/dce2_event.c: * src/dynamic-preprocessors/dcerpc2/dce2_event.h: * src/dynamic-preprocessors/dcerpc2/dce2_http.c: * src/dynamic-preprocessors/dcerpc2/dce2_list.h: * src/dynamic-preprocessors/dcerpc2/dce2_roptions.c: * src/dynamic-preprocessors/dcerpc2/dce2_session.h: * src/dynamic-preprocessors/dcerpc2/dce2_smb.c: * src/dynamic-preprocessors/dcerpc2/dce2_stats.h: * src/dynamic-preprocessors/dcerpc2/dce2_tcp.c: * src/dynamic-preprocessors/dcerpc2/dce2_utils.h: * src/dynamic-preprocessors/dcerpc2/includes/dcerpc.h: * src/dynamic-preprocessors/dcerpc2/includes/smb.h: * src/dynamic-preprocessors/dcerpc2/Makefile.am: * src/dynamic-preprocessors/dcerpc2/sf_dce2.dsp: * src/dynamic-preprocessors/dcerpc2/snort_dce2.c: * src/dynamic-preprocessors/dcerpc2/snort_dce2.h: * src/dynamic-preprocessors/dcerpc2/spp_dce2.c: * src/dynamic-preprocessors/dns/Makefile.am: * src/dynamic-preprocessors/dns/sf_dns.dsp: * src/dynamic-preprocessors/dns/sf_preproc_info.h: * src/dynamic-preprocessors/dns/spp_dns.c: * src/dynamic-preprocessors/dns/spp_dns.h: * src/dynamic-preprocessors/dynamic_preprocessors.dsp: * src/dynamic-preprocessors/ftptelnet/ftpp_eo_log.c: * src/dynamic-preprocessors/ftptelnet/ftpp_eo_log.h: * src/dynamic-preprocessors/ftptelnet/ftpp_si.c: * src/dynamic-preprocessors/ftptelnet/ftpp_si.h: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_config.c: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_config.h: * src/dynamic-preprocessors/ftptelnet/hi_util_kmap.c: * src/dynamic-preprocessors/ftptelnet/hi_util_xmalloc.c: * src/dynamic-preprocessors/ftptelnet/hi_util_xmalloc.h: * src/dynamic-preprocessors/ftptelnet/Makefile.am: * src/dynamic-preprocessors/ftptelnet/pp_ftp.c: * src/dynamic-preprocessors/ftptelnet/pp_telnet.c: * src/dynamic-preprocessors/ftptelnet/pp_telnet.h: * src/dynamic-preprocessors/ftptelnet/sf_ftptelnet.dsp: * src/dynamic-preprocessors/ftptelnet/sf_preproc_info.h: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.h: * src/dynamic-preprocessors/ftptelnet/spp_ftptelnet.c: * src/dynamic-preprocessors/ftptelnet/spp_ftptelnet.h: * src/dynamic-preprocessors/libs/sfcommon.h: * src/dynamic-preprocessors/libs/sfdynamic_preproc_libs.dsp: * src/dynamic-preprocessors/libs/sfparser.c: * src/dynamic-preprocessors/libs/ssl.c: * src/dynamic-preprocessors/libs/ssl.h: * src/dynamic-preprocessors/Makefile.am: * src/dynamic-preprocessors/sf_dynamic_initialize/sf_dynamic_initialize.dsp: * src/dynamic-preprocessors/smtp/Makefile.am: * src/dynamic-preprocessors/smtp/sf_preproc_info.h: * src/dynamic-preprocessors/smtp/sf_smtp.dsp: * src/dynamic-preprocessors/smtp/smtp_config.c: * src/dynamic-preprocessors/smtp/smtp_config.h: * src/dynamic-preprocessors/smtp/smtp_log.c: * src/dynamic-preprocessors/smtp/smtp_normalize.c: * src/dynamic-preprocessors/smtp/smtp_normalize.h: * src/dynamic-preprocessors/smtp/smtp_util.c: * src/dynamic-preprocessors/smtp/smtp_util.h: * src/dynamic-preprocessors/smtp/smtp_xlink2state.c: * src/dynamic-preprocessors/smtp/smtp_xlink2state.h: * src/dynamic-preprocessors/smtp/snort_smtp.c: * src/dynamic-preprocessors/smtp/snort_smtp.h: * src/dynamic-preprocessors/smtp/spp_smtp.c: * src/dynamic-preprocessors/ssl/Makefile.am: * src/dynamic-preprocessors/ssl/sf_preproc_info.h: * src/dynamic-preprocessors/ssl/sf_ssl.dsp: * src/dynamic-preprocessors/ssl/spp_ssl.c: * src/dynamic-preprocessors/ssl/spp_ssl.h: * src/event.h: * src/event_queue.c: * src/event_queue.h: * src/event_wrapper.c: * src/event_wrapper.h: * src/fpcreate.c: * src/fpcreate.h: * src/fpdetect.c: * src/fpdetect.h: * src/generators.h: * src/inline.c: * src/inline.h: * src/ipv6_port.h: * src/log.c: * src/log.h: * src/log_text.c: * src/log_text.h: * src/Makefile.am: * src/mempool.c: * src/mstring.c: * src/mstring.h: * src/output-plugins/spo_alert_arubaaction.c: * src/output-plugins/spo_alert_fast.c: * src/output-plugins/spo_alert_full.c: * src/output-plugins/spo_alert_prelude.c: * src/output-plugins/spo_alert_sf_socket.c: * src/output-plugins/spo_alert_syslog.c: * src/output-plugins/spo_alert_test.c: * src/output-plugins/spo_alert_unixsock.c: * src/output-plugins/spo_alert_unixsock.h: * src/output-plugins/spo_csv.c: * src/output-plugins/spo_database.c: * src/output-plugins/spo_database.h: * src/output-plugins/spo_log_ascii.c: * src/output-plugins/spo_log_ascii.h: * src/output-plugins/spo_log_null.c: * src/output-plugins/spo_log_null.h: * src/output-plugins/spo_log_tcpdump.c: * src/output-plugins/spo_unified.c: * src/output-plugins/spo_unified.h: * src/parser/IpAddrSet.c: * src/parser/IpAddrSet.h: * src/parser.h: * src/pcap_pkthdr32.h: * src/pcrm.c: * src/pcrm.h: * src/plugbase.c: * src/plugbase.h: * src/ppm.c: * src/ppm.h: * src/preprocessors/HttpInspect/client/hi_client.c: * src/preprocessors/HttpInspect/include/hi_client_stateful.h: * src/preprocessors/HttpInspect/include/hi_include.h: * src/preprocessors/HttpInspect/include/hi_reqmethod_check.h: * src/preprocessors/HttpInspect/include/hi_si.h: * src/preprocessors/HttpInspect/include/hi_stateful_inspect.h: * src/preprocessors/HttpInspect/include/hi_ui_config.h: * src/preprocessors/HttpInspect/include/hi_uri.h: * src/preprocessors/HttpInspect/include/hi_urilen_check.h: * src/preprocessors/HttpInspect/include/hi_util_xmalloc.h: * src/preprocessors/HttpInspect/normalization/hi_norm.c: * src/preprocessors/HttpInspect/session_inspection/hi_si.c: * src/preprocessors/HttpInspect/user_interface/hi_ui_config.c: * src/preprocessors/HttpInspect/utils/hi_util_kmap.c: * src/preprocessors/HttpInspect/utils/hi_util_xmalloc.c: * src/preprocessors/perf-base.c: * src/preprocessors/perf-base.h: * src/preprocessors/perf.c: * src/preprocessors/perf-event.c: * src/preprocessors/perf-event.h: * src/preprocessors/perf-flow.c: * src/preprocessors/perf-flow.h: * src/preprocessors/perf.h: * src/preprocessors/portscan.c: * src/preprocessors/portscan.h: * src/preprocessors/sfprocpidstats.c: * src/preprocessors/snort_httpinspect.c: * src/preprocessors/snort_httpinspect.h: * src/preprocessors/spp_arpspoof.c: * src/preprocessors/spp_bo.c: * src/preprocessors/spp_bo.h: * src/preprocessors/spp_frag3.c: * src/preprocessors/spp_frag3.h: * src/preprocessors/spp_httpinspect.c: * src/preprocessors/spp_httpinspect.h: * src/preprocessors/spp_perfmonitor.c: * src/preprocessors/spp_perfmonitor.h: * src/preprocessors/spp_rpc_decode.c: * src/preprocessors/spp_sfportscan.c: * src/preprocessors/spp_sfportscan.h: * src/preprocessors/spp_stream5.c: * src/preprocessors/spp_stream5.h: * src/preprocessors/Stream5/snort_stream5_icmp.c: * src/preprocessors/Stream5/snort_stream5_icmp.h: * src/preprocessors/Stream5/snort_stream5_session.c: * src/preprocessors/Stream5/snort_stream5_session.h: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/preprocessors/Stream5/snort_stream5_tcp.h: * src/preprocessors/Stream5/snort_stream5_udp.c: * src/preprocessors/Stream5/snort_stream5_udp.h: * src/preprocessors/Stream5/stream5_common.c: * src/preprocessors/Stream5/stream5_common.h: * src/preprocessors/stream_api.h: * src/preprocessors/stream_ignore.c: * src/preprocessors/stream_ignore.h: * src/preprocessors/str_search.h: * src/preprocids.h: * src/profiler.c: * src/profiler.h: * src/rules.h: * src/sf_types.h: * src/sfutil/acsmx2.c: * src/sfutil/acsmx2.h: * src/sfutil/acsmx.c: * src/sfutil/acsmx.h: * src/sfutil/asn1.c: * src/sfutil/asn1.h: * src/sfutil/bnfa_search.c: * src/sfutil/ipobj.c: * src/sfutil/Makefile.am: * src/sfutil/mpse.c: * src/sfutil/mpse.h: * src/sfutil/sfeventq.c: * src/sfutil/sfeventq.h: * src/sfutil/sfghash.c: * src/sfutil/sfghash.h: * src/sfutil/sfhashfcn.c: * src/sfutil/sf_ip.c: * src/sfutil/sf_ip.h: * src/sfutil/sf_iph.c: * src/sfutil/sf_ipvar.c: * src/sfutil/sfksearch.c: * src/sfutil/sfksearch.h: * src/sfutil/sflsq.c: * src/sfutil/sflsq.h: * src/sfutil/sfPolicy.c: * src/sfutil/sfPolicy.h: * src/sfutil/sfPolicyUserData.c: * src/sfutil/sfPolicyUserData.h: * src/sfutil/sfportobject.c: * src/sfutil/sfportobject.h: * src/sfutil/sfrf.c: * src/sfutil/sfrf.h: * src/sfutil/sfrt.c: * src/sfutil/sfrt_dir.c: * src/sfutil/sfrt_dir.h: * src/sfutil/sfrt.h: * src/sfutil/sfrt_lctrie.c: * src/sfutil/sfrt_lctrie.h: * src/sfutil/sfrt_trie.h: * src/sfutil/sf_textlog.h: * src/sfutil/sfthd.c: * src/sfutil/sfthd.h: * src/sfutil/sf_vartable.c: * src/sfutil/sf_vartable.h: * src/sfutil/sfxhash.c: * src/sfutil/util_math.c: * src/sfutil/util_math.h: * src/sfutil/util_net.c: * src/sfutil/util_net.h: * src/signature.c: * src/signature.h: * src/snort.c: * src/snort.h: * src/snprintf.c: * src/spo_plugbase.h: * src/tag.c: * src/tag.h: * src/target-based/sf_attribute_table_parser.l: * src/target-based/sf_attribute_table.y: * src/target-based/sftarget_hostentry.c: * src/target-based/sftarget_hostentry.h: * src/target-based/sftarget_protocol_reference.c: * src/target-based/sftarget_protocol_reference.h: * src/target-based/sftarget_reader.c: * src/target-based/sftarget_reader.h: * src/util.c: * src/util.h: 2009-04-20 Ryan Jordan * src/dynamic-preprocessors/dcerpc2/dce2_config.c: * src/dynamic-preprocessors/dcerpc2/dce2_smb.c: * src/dynamic-preprocessors/dcerpc2/snort_dce2.c: Changed DCE2 configuration such that events are disabled by default. * src/dynamic-preprocessors/ftptelnet/pp_ftp.c: Fixed false positive when an additional /r/n followed the QUIT command. * src/dynamic-preprocessors/ssh/spp_ssh.c: Fixed infinite loop when parsing SSH configuration. * src/output-plugins/spo_database.c: Fixed an issue that prevented Snort from inserting records into the sensor table of a MySQL database. Thanks to David Cecchino for pointing out this issue. * src/parser.c: * src/sfutil/ipobj.c: Fixed handling of IP lists that begin with variables, when IPv6 was enabled. * src/preprocessors/Stream5/snort_stream5_tcp.c: Handle case where require_3whs is configured, no session has been created and an ACK is received with a RST flag. Thanks to Jeff Johnson for reporting the problem. * src/sfthreshold.c: * src/sfutil/sf_ipvar.c: * src/sfutil/sfportobject.c: * src/sfutil/sfthd.c: * src/sfutil/sf_vartable.c: * src/util.c: Fixed issues with use of IPv6 address variables. * rpm/snort.spec: Added DCE2 preprocessor to RPM spec file. Thanks to Scott Fabbri, c0uch, and Andrew Pendray for reporting this. * doc/snort_manual.tex: Updated to add Bhagyasree Bantwal, newest member of Snort Team. 2009-03-11 Steven Sturges * src/util.c: Fix for IPv6 on Win32 to define interface variables. * src/win32/WIN32-Prj/snort_installer_options.ini: Update for IPv6 intalls. 2009-03-10 Steven Sturges * src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c: Correctly pass operation to allow flowbits checked-but-not-set and set-but-not-checked validation to work between text and shared rules. * src/dynamic-plugins/sf_dynamic_define.h: * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.h: * src/dynamic-plugins/sf_engine/sf_snort_plugin_pcre.c: Handle relative PCREs the same as text rules. Fix misnamed macro. * src/dynamic-preprocessors/dcerpc2/dce2_co.c: * src/dynamic-preprocessors/dcerpc2/dce2_event.c: * src/dynamic-preprocessors/dcerpc2/dce2_smb.c: * src/dynamic-preprocessors/dcerpc2/snort_dce2.c: Address False positives seen in testing. * src/dynamic-preprocessors/ftptelnet/ftpp_si.c: Add missing attribute check when FTP traffic is picked up mid-TCP stream. * src/dynamic-preprocessors/ftptelnet/pp_ftp.c: Fix handling of EPRT command for IPv6. * src/output-plugins/spo_unified2.c: unlink output file in test mode. * src/fpcreate.c: * src/fpdetect.c: * src/parser.c: Fix logging to syslog for rule counts at startup. * src/generators.h: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/preprocessors/Stream5/stream5_common.h: * etc/gen-msg.map: Add stream5 option to restrict the number of consecutive small TCP segments inserted for reassembly without seeing an ACK. Generate alert (gid:129,sid:12) when that limit is exceeded. Allow overriding of this configuration on a port basis via an ignore_ports option. * src/sfutil/sf_ip.c: * src/sfutil/sf_ip.h: Fixed issues w/ IPv6 comparisons and /32 used with IPv6. Added and updated unit test code. Thanks to mamcmil on snort.org forums for pointing out the problem. * src/win32/WIN32-Prj/snort_installer.nsi: * src/win32/WIN32-Prj/snort_installer_options.ini: * src/win32/WIN32-Prj/sf_engine.dsp: * src/dynamic-preprocessors/dcerpc/sf_dcerpc.dsp: * src/dynamic-preprocessors/dcerpc2/sf_dce2.dsp: * src/dynamic-preprocessors/dns/sf_dns.dsp: * src/dynamic-preprocessors/ftptelnet/sf_ftptelnet.dsp: * src/dynamic-preprocessors/smtp/sf_smtp.dsp: * src/dynamic-preprocessors/ssh/sf_ssh.dsp: * src/dynamic-preprocessors/ssl/sf_ssl.dsp: * configure.in: * rpm/snort.spec: * src/win32/WIN32-Includes/config.h: 2.8.4 Final build changes. Allow IPv6 to be installed via windows installer. 2009-02-06 Todd Wease * snort.8: * src/parser.c: * src/snort.c: * src/snort.h: Added command line option "--require-rule-sid" to require every rule have an sid. * src/detection-plugins/detection_options.c: * src/detection-plugins/detection_options.h: Fix compilation issue with --disable-dynamicplugin. Thanks to Jason Wallace for bringing this to our attention. * src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c: Push dynamic engine minor version to 10 and build version to 16. * src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.h: Fix preprocessor rule option processing for dynamic detection rules. * src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c: Add checks for header and method buffers when fast pattern is not specified in dynamic detection rules. * src/dynamic-preprocessors/dcerpc/dcerpc_util.c: * src/dynamic-preprocessors/dcerpc/smb_andx_decode.c: * src/dynamic-preprocessors/dcerpc2/dce2_utils.c: * src/dynamic-preprocessors/ftptelnet/pp_ftp.c: * src/dynamic-preprocessors/smtp/smtp_util.c: * src/preprocessors/HttpInspect/client/hi_client_norm.c: * src/sfutil/acsmx2.c: * src/sfutil/bnfa_search.c: Update uses of isprint() to check for isascii() as well where only printable ascii characters are relevant. * src/dynamic-preprocessors/smtp/snort_smtp.c: Update smtp preprocessor to use stream5 direction data when determining if preprocessor is configured to process traffic. * doc/README.stream5: * doc/snort_manual.tex: * src/preprocessors/spp_stream5.c: * src/preprocessors/Stream5/snort_stream5_tcp.c: Add range checking in stream5 preprocessor for prune_log_max and update error messages to indicate 0 is a valid value for prune_log_max, max_queued_segs and max_queued_bytes. * src/preprocessors/Stream5/snort_stream5_tcp.c: Update to stream5 preprocessor to handle ECN and CWR bits in the SYN packet. Thanks to Lothar Braun for bringing this to our attention. * src/sfutil/sf_ip.c: * src/sfutil/sf_ip.h: Fix configuration parsing of IPv6 addresses to allow /32 cidr. * src/decode.c: * src/decode.h: * src/detect.c: * src/detect.h: * src/detection-plugins/sp_ip_proto.c: * src/detection-plugins/sp_ip_proto.h: * src/dynamic-plugins/sf_engine/sf_snort_packet.h: * src/dynamic-preprocessors/dcerpc/snort_dcerpc.c: * src/dynamic-preprocessors/dcerpc2/snort_dce2.c: * src/dynamic-preprocessors/dns/spp_dns.c: * src/dynamic-preprocessors/ftptelnet/spp_ftptelnet.c: * src/dynamic-preprocessors/smtp/spp_smtp.c: * src/dynamic-preprocessors/ssh/spp_ssh.c: * src/dynamic-preprocessors/ssl/spp_ssl.c: * src/fpcreate.c: * src/fpcreate.h: * src/fpdetect.h: * src/parser.c: * src/plugbase.c: * src/plugbase.h: * src/preprocessors/spp_arpspoof.c: * src/preprocessors/spp_bo.c: * src/preprocessors/spp_frag3.c: * src/preprocessors/spp_httpinspect.c: * src/preprocessors/spp_perfmonitor.c: * src/preprocessors/spp_rpc_decode.c: * src/preprocessors/spp_sfportscan.c: * src/preprocessors/spp_stream5.c: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/rules.h: * src/snort.c: Added rule and preprocessor filtering by protocol so that traffic will not be evaluated for which there are no rules or preprocessors interested in that traffic. * src/decode.c: Fixed IPv6 decoder for Sparc memory alignment in IPv6 enabled binary. * src/decode.h: * src/dynamic-plugins/sf_engine/sf_snort_packet.h: * src/log_text.c: * src/sfutil/sf_iph.c: Fixed issue in IPv6 enabled binary, where ICMP (not ICMP6) over IPv6 would cause a segfault. * src/detection-plugins/detection_options.c: * src/detection-plugins/detection_options.h: * src/profiler.c: * src/profiler.h: Fixed inconsistent results in rule profiling. Thanks to Geoff Whittington for bringing this to our attention. * src/detection-plugins/sp_byte_jump.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.h: * src/dynamic-plugins/sf_engine/sf_snort_plugin_byte.c: * src/dynamic-preprocessors/dcerpc2/dce2_roptions.c: * doc/snort_manual.tex: * doc/snort_manual.pdf: Added new "post_offset" argument to byte jump rule option to move some designated amount after the byte jump. * src/dynamic-plugins/sf_dynamic_plugins.c: * src/dynamic-plugins/sf_dynamic_preprocessor.h: * src/dynamic-plugins/sf_preproc_example/sf_dynamic_preproc_lib.c: * src/plugbase.c: * src/target-based/sftarget_reader.c: * src/target-based/sftarget_reader.h: Added functionality to the dynamic-plugin API to check whether adaptive profiles is configured and to check whether or not a preprocessor is configured. * src/dynamic-preprocessors/dcerpc/spp_dcerpc.c: * src/dynamic-preprocessors/dcerpc2/spp_dce2.c: Fatal error if both dcerpc and dcerpc2 preprocessors are configured. * src/dynamic-preprocessors/dcerpc/spp_dcerpc.c: * src/dynamic-preprocessors/dcerpc2/dce2_config.c: * src/dynamic-preprocessors/dcerpc2/spp_dce2.c: * src/dynamic-preprocessors/dns/spp_dns.c: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: * src/dynamic-preprocessors/smtp/spp_smtp.c: * src/dynamic-preprocessors/ssl/spp_ssl.c: * src/preprocessors/spp_httpinspect.c: * src/preprocessors/spp_rpc_decode.c: Updates to stream5 filtering so that stream5 does not track sessions for which there are no rules that could fire on that traffic or preprocessors that are interested in that traffic. * doc/README.dcerpc2: * doc/snort_manual.tex: * doc/snort_manual.pdf: * etc/gen-msg.map: * etc/snort.conf: Added dcerpc2 preprocessor documentation. * src/dynamic-preprocessors/dcerpc2/dce2_cl.c: * src/dynamic-preprocessors/dcerpc2/dce2_co.c: * src/dynamic-preprocessors/dcerpc2/dce2_smb.c: * src/dynamic-preprocessors/dcerpc2/snort_dce2.c: * src/dynamic-preprocessors/dcerpc2/spp_dce2.c: Added performance profiling statistics to the dcerpc2 preprocessor. * src/dynamic-preprocessors/dcerpc2/dce2_cl.c: * src/dynamic-preprocessors/dcerpc2/dce2_co.c: * src/dynamic-preprocessors/dcerpc2/dce2_roptions.c: * src/dynamic-preprocessors/dcerpc2/dce2_smb.c: * src/dynamic-preprocessors/dcerpc2/dce2_utils.c: * src/dynamic-preprocessors/dcerpc2/dce2_utils.h: * src/dynamic-preprocessors/dcerpc2/includes/dcerpc.h: * src/dynamic-preprocessors/dcerpc2/includes/smb.h: Fix for architectures requiring strict memory alignment such as Sparc in the dcerpc2 preprocessor. * src/dynamic-preprocessors/dcerpc2/dce2_config.c: * src/dynamic-preprocessors/dcerpc2/dce2_config.h: * src/dynamic-preprocessors/dcerpc2/dce2_roptions.c: * src/dynamic-preprocessors/dcerpc2/dce2_roptions.h: Updated configuration error reporting in the dcerpc2 preprocessor. * src/dynamic-preprocessors/dcerpc2/dce2_cl.c: * src/dynamic-preprocessors/dcerpc2/dce2_co.c: * src/dynamic-preprocessors/dcerpc2/dce2_co.h: * src/dynamic-preprocessors/dcerpc2/dce2_smb.c: * src/dynamic-preprocessors/dcerpc2/dce2_smb.h: * src/dynamic-preprocessors/dcerpc2/dce2_tcp.h: * src/dynamic-preprocessors/dcerpc2/dce2_udp.h: * src/dynamic-preprocessors/dcerpc2/dce2_session.h: * src/dynamic-preprocessors/dcerpc2/snort_dce2.c: * src/dynamic-preprocessors/dcerpc2/snort_dce2.h: Updated dcerpc2 preprocessor autodetection and handling of missed packets to limit false positives. * src/dynamic-preprocessors/dcerpc2/dce2_cl.c: * src/dynamic-preprocessors/dcerpc2/dce2_co.c: * src/dynamic-preprocessors/dcerpc2/dce2_config.c: * src/dynamic-preprocessors/dcerpc2/dce2_debug.c: * src/dynamic-preprocessors/dcerpc2/dce2_list.c: * src/dynamic-preprocessors/dcerpc2/dce2_memory.c: * src/dynamic-preprocessors/dcerpc2/dce2_roptions.c: * src/dynamic-preprocessors/dcerpc2/dce2_smb.c: * src/dynamic-preprocessors/dcerpc2/dce2_stats.c: * src/dynamic-preprocessors/dcerpc2/dce2_utils.c: * src/dynamic-preprocessors/dcerpc2/dce2_utils.h: * src/dynamic-preprocessors/dcerpc2/snort_dce2.c: * src/dynamic-preprocessors/dcerpc2/spp_dce2.c: Updated dcerpc2 preprocessor logging. * preproc_rules/preprocessor.rules: * src/dynamic-preprocessors/dcerpc2/dce2_co.c: * src/dynamic-preprocessors/dcerpc2/dce2_event.c: * src/dynamic-preprocessors/dcerpc2/dce2_event.h: * src/generators.h: Added new preprocessor event to the dcerpc2 preprocessor to alert on Bind or Alter Context PDUs that don't have any context items. * src/dynamic-preprocessors/ftptelnet/pp_ftp.c: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: Updated ftp_telnet preprocessor to consider the AUTH command as the beginning of a possibly encrypted session. * src/dynamic-preprocessors/ftptelnet/sf_preproc_info.h: Pushed the ftp_telnet preprocessor minor version to 2 and build version to 11. * src/decode.c: * src/snort.h: * src/util.c: Added additional ethertypes to Vlan decoder. * configure.in * src/output-plugins/spo_database.c: Added reconnect capability to MySQL database output plugin. Thanks to Ian Mitchell and other users on the lists for bringing this to our attention. * src/output-plugins/spo_unified2.c: * src/output-plugins/spo_unified2.h: Added code to better handle logging to an NFS mounted share. * src/parser.c: Command line BPF filter now overrides configuration in snort.conf. * src/parser.c: Command line log directory now overrides configuration in snort.conf. * src/parser.c: * src/snort.c: Fixed read back mode to reallow reading from stdin. Thanks to John Gerber for bringing this to our attention. * src/plugbase.c: * src/util.c: Fixed compilation on HPUX 11.11. Thanks to Lars Ebeling for bringing this to our attention. * src/preprocessors/spp_rpc_decode.c: Continue defragmentation even when alerting on fragmentation in the rpc_decode preprocessor. * src/preprocessors/spp_stream5.c: Stream5 will now fatal error if there isn't at least one of track tcp, track udp or track icmp. * src/sfthreshold.c: * src/sfutil/sfthd.c: * src/sfutil/sfthd.h: Allow a count of -1 to threshold configuration option to disable all thresholding for that object. * src/snort.c: Fixed issue with SIGHUP and handling of daemonize flag. * preproc_rules/decoder.rules: * preproc_rules/preprocessor.rules: Added decoder/preprocessor rules for MPLS and DCE/RPC. * snort.8: Update manpage for "-x", "--conf-error-out" and "--exit-check" command line options. 2008-12-30 Steven Sturges * src/output-plugins/spo_database.c: Update to check for a missing host name when connecting to a MySQL database and fail gracefully. Thanks to Chris Benedict for the report. * doc/README.stream5: * doc/snort_manual.pdf: * doc/snort_manual.tex: * src/preprocessors/spp_stream5.c: * src/preprocessors/stream_api.h: * src/preprocessors/Stream5/snort_stream5_session.c: * src/preprocessors/Stream5/snort_stream5_session.h: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/preprocessors/Stream5/stream5_common.h: Update Stream5 to better handle out-of-sequence server responses when not doing server-side reassembly. Add limits on number of bytes and segments queued to prevent one session from consuming all memory. * src/target-based/sf_attribute_table.y: Force bison to use malloc/free instead of alloca for older versions of bison. * src/target-based/sf_attribute_table_parser.l: * src/target-based/sftarget_reader.c: Don't fatal error when reloading an attribute table beyond the configured limit. Only display warning to syslog/console. 2008-10-03 Todd Wease * configure.in: * src/decode.c: * src/decode.h: * src/detection-plugins/sp_pattern_match.c: * src/dynamic-plugins/sf_dynamic_plugins.c: * src/dynamic-plugins/sf_dynamic_preprocessor.h: * src/dynamic-plugins/sf_engine/Makefile.am: * src/dynamic-plugins/sf_engine/sf_snort_packet.h: * src/dynamic-plugins/sf_engine/sf_snort_plugin_hdropts.c: * src/dynamic-preprocessors/dcerpc/snort_dcerpc.c: * src/dynamic-preprocessors/dns/spp_dns.c: * src/dynamic-preprocessors/ftptelnet/ftp_bounce_lookup.c: * src/dynamic-preprocessors/ftptelnet/ftp_bounce_lookup.h: * src/dynamic-preprocessors/ftptelnet/ftp_cmd_lookup.c: * src/dynamic-preprocessors/ftptelnet/ftp_cmd_lookup.h: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_config.h: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_config.h: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_server_lookup.c: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: * src/dynamic-preprocessors/ftptelnet/ftpp_si.c: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_server_lookup.c: * src/dynamic-preprocessors/ftptelnet/pp_ftp.c: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: * src/dynamic-preprocessors/libs/sfdynamic_preproc_libs.dsp: * src/dynamic-preprocessors/sf_dynamic_initialize/sf_dynamic_initialize.dsp: * src/fpdetect.c: * src/generators.h: * src/ipv6_port.h: * src/log.c: * src/log_text.c: * src/output-plugins/spo_alert_test.c: * src/output-plugins/spo_csv.c: * src/preprocessors/HttpInspect/session_inspection/hi_si.c: * src/preprocessors/snort_httpinspect.c: * src/preprocessors/spp_frag3.c: * src/preprocessors/spp_sfportscan.c: * src/preprocessors/Stream5/snort_stream5_session.c: * src/preprocessors/stream_ignore.c: * src/sfutil/ipobj.c: * src/sfutil/ipobj.h: * src/sfutil/sf_ip.c: * src/sfutil/sf_ip.h: * src/sfutil/sf_iph.c: * src/sfutil/sf_ipvar.c: * src/sfutil/sfrt.c: * src/sfutil/sfrt.h: * src/sfutil/sfrt_dir.c: * src/sfutil/sfrt_dir.h: * src/snort.c: * src/target-based/sf_attribute_table.y: * src/target-based/sftarget_reader.c: * src/target-based/sftarget_reader.h: * src/win32/WIN32-Prj/sf_engine.dsp: IPv6 updates and support for sfportscan, ftp_telnet, frag3 and dns preprocessors and adaptive IPS. * etc/gen-msg.map: * src/decode.h: * src/detect.c: * src/detection-plugins/sp_byte_check.c: * src/detection-plugins/sp_byte_jump.c: * src/dynamic-plugins/sf_engine/sf_snort_packet.h: * src/dynamic-preprocessors/dcerpc2/dce2_cl.c: * src/dynamic-preprocessors/dcerpc2/dce2_cl.h: * src/dynamic-preprocessors/dcerpc2/dce2_co.c: * src/dynamic-preprocessors/dcerpc2/dce2_co.h: * src/dynamic-preprocessors/dcerpc2/dce2_config.c: * src/dynamic-preprocessors/dcerpc2/dce2_config.h: * src/dynamic-preprocessors/dcerpc2/dce2_debug.c: * src/dynamic-preprocessors/dcerpc2/dce2_debug.h: * src/dynamic-preprocessors/dcerpc2/dce2_event.c: * src/dynamic-preprocessors/dcerpc2/dce2_event.h: * src/dynamic-preprocessors/dcerpc2/dce2_http.c: * src/dynamic-preprocessors/dcerpc2/dce2_http.h: * src/dynamic-preprocessors/dcerpc2/dce2_list.c: * src/dynamic-preprocessors/dcerpc2/dce2_list.h: * src/dynamic-preprocessors/dcerpc2/dce2_memory.c: * src/dynamic-preprocessors/dcerpc2/dce2_memory.h: * src/dynamic-preprocessors/dcerpc2/dce2_roptions.c: * src/dynamic-preprocessors/dcerpc2/dce2_roptions.h: * src/dynamic-preprocessors/dcerpc2/dce2_session.h: * src/dynamic-preprocessors/dcerpc2/dce2_smb.c: * src/dynamic-preprocessors/dcerpc2/dce2_smb.h: * src/dynamic-preprocessors/dcerpc2/dce2_stats.c: * src/dynamic-preprocessors/dcerpc2/dce2_stats.h: * src/dynamic-preprocessors/dcerpc2/dce2_tcp.c: * src/dynamic-preprocessors/dcerpc2/dce2_tcp.h: * src/dynamic-preprocessors/dcerpc2/dce2_udp.c: * src/dynamic-preprocessors/dcerpc2/dce2_udp.h: * src/dynamic-preprocessors/dcerpc2/dce2_utils.c: * src/dynamic-preprocessors/dcerpc2/dce2_utils.h: * src/dynamic-preprocessors/dcerpc2/includes/dcerpc.h: * src/dynamic-preprocessors/dcerpc2/includes/smb.h: * src/dynamic-preprocessors/dcerpc2/Makefile.am: * src/dynamic-preprocessors/dcerpc2/sf_dce2.dsp: * src/dynamic-preprocessors/dcerpc2/sf_preproc_info.h: * src/dynamic-preprocessors/dcerpc2/snort_dce2.c: * src/dynamic-preprocessors/dcerpc2/snort_dce2.h: * src/dynamic-preprocessors/dcerpc2/spp_dce2.c: * src/dynamic-preprocessors/dcerpc2/spp_dce2.h: * src/dynamic-preprocessors/Makefile.am: * src/generators.h: * src/output-plugins/spo_alert_fast.c: * src/preprocessors/snort_httpinspect.c: * src/sf_types.h: * src/sfutil/sfrt.c: * src/sfutil/sfrt.h: * src/util.c: * src/win32/WIN32-Prj/snort.dsp: * src/win32/WIN32-Prj/snort.dsw: Addition of dcerpc2 preprocessor. Addition of new rule options supported by preprocessor. * src/detect.c: * src/detect.h: * src/dynamic-plugins/sf_dynamic_plugins.c: * src/dynamic-plugins/sf_dynamic_preprocessor.h: * src/dynamic-plugins/sf_preproc_example/sf_dynamic_preproc_lib.c: * src/dynamic-preprocessors/dcerpc/dcerpc.c: * src/dynamic-preprocessors/dcerpc/dcerpc_config.c: * src/dynamic-preprocessors/dcerpc/snort_dcerpc.c: * src/dynamic-preprocessors/dcerpc/snort_dcerpc.h: * src/dynamic-preprocessors/dcerpc/spp_dcerpc.c: * src/dynamic-preprocessors/dns/spp_dns.c: * src/dynamic-preprocessors/ftptelnet/ftpp_si.c: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_config.h: * src/dynamic-preprocessors/ftptelnet/spp_ftptelnet.c: * src/dynamic-preprocessors/smtp/snort_smtp.c: * src/dynamic-preprocessors/smtp/snort_smtp.h: * src/dynamic-preprocessors/smtp/spp_smtp.c: * src/dynamic-preprocessors/ssh/spp_ssh.c: * src/dynamic-preprocessors/ssl/spp_ssl.c: * src/fpdetect.c: * src/parser.c: * src/preprocessors/HttpInspect/include/hi_si.h: * src/preprocessors/HttpInspect/include/hi_ui_config.h: * src/preprocessors/HttpInspect/session_inspection/hi_si.c: * src/preprocessors/spp_httpinspect.c: * src/preprocessors/spp_rpc_decode.c: * src/preprocessors/spp_stream5.c: * src/preprocessors/Stream5/snort_stream5_session.h: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/target-based/sftarget_protocol_reference.c: * src/target-based/sftarget_protocol_reference.h: Add adaptive support for http_inspect, rpc, smtp, dcerpc, dcerpc2, dns, ftp_telnet, ssh and ssl preprocessors. * configure.in: * src/detect.c: * src/detection-plugins/detection_options.c: * src/detection-plugins/sp_asn1.c: * src/detection-plugins/sp_asn1.h: * src/detection-plugins/sp_byte_check.c: * src/detection-plugins/sp_byte_check.h: * src/detection-plugins/sp_byte_jump.c: * src/detection-plugins/sp_byte_jump.h: * src/detection-plugins/sp_clientserver.c: * src/detection-plugins/sp_clientserver.h: * src/detection-plugins/sp_cvs.c: * src/detection-plugins/sp_cvs.h: * src/detection-plugins/sp_dsize_check.c: * src/detection-plugins/sp_dsize_check.h: * src/detection-plugins/sp_flowbits.c: * src/detection-plugins/sp_flowbits.h: * src/detection-plugins/sp_ftpbounce.c: * src/detection-plugins/sp_ftpbounce.h: * src/detection-plugins/sp_icmp_code_check.c: * src/detection-plugins/sp_icmp_code_check.h: * src/detection-plugins/sp_icmp_id_check.c: * src/detection-plugins/sp_icmp_id_check.h: * src/detection-plugins/sp_icmp_seq_check.c: * src/detection-plugins/sp_icmp_seq_check.h: * src/detection-plugins/sp_icmp_type_check.c: * src/detection-plugins/sp_icmp_type_check.h: * src/detection-plugins/sp_ip_fragbits.c: * src/detection-plugins/sp_ip_fragbits.h: * src/detection-plugins/sp_ip_id_check.c: * src/detection-plugins/sp_ip_id_check.h: * src/detection-plugins/sp_ipoption_check.c: * src/detection-plugins/sp_ipoption_check.h: * src/detection-plugins/sp_ip_proto.c: * src/detection-plugins/sp_ip_proto.h: * src/detection-plugins/sp_ip_same_check.c: * src/detection-plugins/sp_ip_same_check.h: * src/detection-plugins/sp_ip_tos_check.c: * src/detection-plugins/sp_ip_tos_check.h: * src/detection-plugins/sp_isdataat.c: * src/detection-plugins/sp_isdataat.h: * src/detection-plugins/sp_pattern_match.c: * src/detection-plugins/sp_pattern_match.h: * src/detection-plugins/sp_pcre.c: * src/detection-plugins/sp_pcre.h: * src/detection-plugins/sp_react.c: * src/detection-plugins/sp_react.h: * src/detection-plugins/sp_respond2.c: * src/detection-plugins/sp_respond2.h: * src/detection-plugins/sp_respond.c: * src/detection-plugins/sp_respond.h: * src/detection-plugins/sp_rpc_check.c: * src/detection-plugins/sp_rpc_check.h: * src/detection-plugins/sp_session.c: * src/detection-plugins/sp_session.h: * src/detection-plugins/sp_tcp_ack_check.c: * src/detection-plugins/sp_tcp_ack_check.h: * src/detection-plugins/sp_tcp_flag_check.c: * src/detection-plugins/sp_tcp_flag_check.h: * src/detection-plugins/sp_tcp_seq_check.c: * src/detection-plugins/sp_tcp_seq_check.h: * src/detection-plugins/sp_tcp_win_check.c: * src/detection-plugins/sp_tcp_win_check.h: * src/detection-plugins/sp_ttl_check.c: * src/detection-plugins/sp_ttl_check.h: * src/detection-plugins/sp_urilen_check.c: * src/detection-plugins/sp_urilen_check.h: * src/dynamic-plugins/sp_dynamic.c: * src/dynamic-plugins/sp_preprocopt.c: * src/dynamic-plugins/sp_preprocopt.h: * src/dynamic-preprocessors/dcerpc/sf_dcerpc.dsp: * src/dynamic-preprocessors/dns/sf_dns.dsp: * src/dynamic-preprocessors/ftptelnet/sf_ftptelnet.dsp: * src/dynamic-preprocessors/libs/sfdynamic_preproc_libs.dsp: * src/dynamic-preprocessors/smtp/sf_smtp.dsp: * src/dynamic-preprocessors/ssh/sf_ssh.dsp: * src/dynamic-preprocessors/ssl/sf_ssl.dsp: * src/fpcreate.c: * src/fpcreate.h: * src/fpdetect.c: * src/fpdetect.h: * src/parser.c: * src/pcrm.c: * src/pcrm.h: * src/plugbase.c: * src/ppm.c: * src/ppm.h: * src/preprocessors/spp_frag3.c: * src/preprocessors/spp_frag3.h: * src/preprocessors/str_search.c: * src/profiler.c: * src/profiler.h: * src/rules.h: * src/sfutil/acsmx2.c: * src/sfutil/acsmx2.h: * src/sfutil/acsmx.c: * src/sfutil/acsmx.h: * src/sfutil/bnfa_search.c: * src/sfutil/bnfa_search.h: * src/sfutil/mpse.c: * src/sfutil/mpse.h: * src/sfutil/sfksearch.c: * src/sfutil/sfksearch.h: * src/snort.c: * src/win32/WIN32-Prj/sf_engine.dsp: * src/win32/WIN32-Prj/snort.dsp: Harden rule option tree code. * configure.in: * doc/Makefile.am: * doc/snort_manual.tex: * doc/README.sfportscan: * src/detect.c: * src/detection-plugins/sp_clientserver.c: * src/detection-plugins/sp_flowbits.c: * src/fatal.h: * src/generators.h: * src/Makefile.am: * src/parser.c: * src/plugbase.c: * src/preprocessors/flow/common_defs.h (removed): * src/preprocessors/flow/flow.c (removed): * src/preprocessors/flow/flow_cache.c (removed): * src/preprocessors/flow/flow_cache.h (removed): * src/preprocessors/flow/flow_callback.c (removed): * src/preprocessors/flow/flow_callback.h (removed): * src/preprocessors/flow/flow_class.c (removed): * src/preprocessors/flow/flow_class.h (removed): * src/preprocessors/flow/flow_config.h (removed): * src/preprocessors/flow/flow_error.h (removed): * src/preprocessors/flow/flow.h (removed): * src/preprocessors/flow/flow_hash.c (removed): * src/preprocessors/flow/flow_hash.h (removed): * src/preprocessors/flow/flow_print.c (removed): * src/preprocessors/flow/flow_print.h (removed): * src/preprocessors/flow/flow_stat.c (removed): * src/preprocessors/flow/flow_stat.h (removed): * src/preprocessors/flow/int-snort (removed): * src/preprocessors/flow/Makefile.am (removed): * src/preprocessors/flow/portscan (removed): * src/preprocessors/Makefile.am: * src/preprocessors/portscan.c (removed): * src/preprocessors/snort_httpinspect.c: * src/preprocessors/snort_stream4_session.c (removed): * src/preprocessors/snort_stream4_session.h (removed): * src/preprocessors/snort_stream4_udp.c (removed): * src/preprocessors/snort_stream4_udp.h (removed): * src/preprocessors/spp_flow.c (removed): * src/preprocessors/spp_flow.h (removed): * src/preprocessors/spp_stream4.c (removed): * src/preprocessors/spp_stream4.h (removed): * src/preprocessors/stream.h (removed): * src/preprocids.h: * src/snort.c: * src/win32/WIN32-Prj/snort.dsp: Removal of stream4 and flow preprocessors from code base. * src/tag.c: * src/tag.h: * src/ubi_BinTree.c (removed): * src/ubi_BinTree.h (removed): * src/ubi_SplayTree.c (removed): * src/ubi_SplayTree.h (removed): Tagging now uses a hash table instead of a splay tree for data storage. * src/detection-plugins/detection_options.c: * src/detection-plugins/sp_pattern_match.c: * src/detection-plugins/sp_pattern_match.h: * src/dynamic-preprocessors/smtp/snort_smtp.c: * src/fpcreate.c: * src/fpcreate.h: * src/fpdetect.c: * src/fpdetect.h: * src/plugbase.c: * src/preprocessors/str_search.c: * src/preprocessors/str_search.h: * src/sfutil/acsmx2.c: * src/sfutil/acsmx2.h: * src/sfutil/acsmx.c: * src/sfutil/acsmx.h: * src/sfutil/bnfa_search.c: * src/sfutil/bnfa_search.h: * src/sfutil/mpse.c: * src/sfutil/mpse.h: * src/sfutil/sfksearch.c: * src/sfutil/sfksearch.h: Support rules with content rule options that are only not contents. * src/detection-plugins/detection_options.c: * src/detection-plugins/sp_asn1.c: * src/detection-plugins/sp_byte_check.c: * src/detection-plugins/sp_byte_jump.c: * src/detection-plugins/sp_clientserver.c: * src/detection-plugins/sp_cvs.c: * src/detection-plugins/sp_dsize_check.c: * src/detection-plugins/sp_flowbits.c: * src/detection-plugins/sp_ftpbounce.c: * src/detection-plugins/sp_icmp_code_check.c: * src/detection-plugins/sp_icmp_id_check.c: * src/detection-plugins/sp_icmp_seq_check.c: * src/detection-plugins/sp_icmp_type_check.c: * src/detection-plugins/sp_ip_fragbits.c: * src/detection-plugins/sp_ip_id_check.c: * src/detection-plugins/sp_ipoption_check.c: * src/detection-plugins/sp_ip_proto.c: * src/detection-plugins/sp_ip_same_check.c: * src/detection-plugins/sp_ip_tos_check.c: * src/detection-plugins/sp_isdataat.c: * src/detection-plugins/sp_pattern_match.c: * src/detection-plugins/sp_pcre.c: * src/detection-plugins/sp_react.c: * src/detection-plugins/sp_respond2.c: * src/detection-plugins/sp_respond.c: * src/detection-plugins/sp_rpc_check.c: * src/detection-plugins/sp_session.c: * src/detection-plugins/sp_tcp_ack_check.c: * src/detection-plugins/sp_tcp_flag_check.c: * src/detection-plugins/sp_tcp_seq_check.c: * src/detection-plugins/sp_tcp_win_check.c: * src/detection-plugins/sp_ttl_check.c: * src/detection-plugins/sp_urilen_check.c: * src/dynamic-plugins/sf_dynamic_plugins.c: * src/dynamic-plugins/sf_dynamic_preprocessor.h: * src/dynamic-plugins/sf_preproc_example/sf_dynamic_preproc_lib.c: * src/dynamic-plugins/sp_dynamic.c: * src/dynamic-plugins/sp_dynamic.h: * src/dynamic-plugins/sp_preprocopt.c: * src/dynamic-plugins/sp_preprocopt.h: * src/plugbase.c: * src/plugbase.h: * src/preprocessors/Stream5/snort_stream5_tcp.c: Add override keyword support. Argument to a rule option can be overriden and processed elsewhere. Added for support of new byte_test and byte_jump rule option argument "dce". * src/detection-plugins/detection_options.c: * src/dynamic-plugins/sf_dynamic_engine.h: * src/dynamic-plugins/sf_dynamic_common.h: * src/dynamic-plugins/sp_preprocopt.c: * src/dynamic-plugins/sp_preprocopt.h: Add hash and compare functions for preprocessors to rule option tree. * src/detection-plugins/sp_clientserver.c: * src/detection-plugins/sp_pattern_match.c: * src/preprocessors/snort_httpinspect.c: * src/preprocessors/spp_httpinspect.h: Make sure Stream5 is enabled when parsing most arguments to flow rule option. Make sure http_inspect is enabled when parsing uricontent or http content modifiers. * src/detection-plugins/sp_clientserver.c: Added no_frag and only_frag arguments to flow rule option. * src/dynamic-plugins/sf_dynamic_plugins.c: * src/dynamic-plugins/sf_dynamic_preprocessor.h: * src/dynamic-plugins/sf_preproc_example/sf_dynamic_preproc_lib.c: Added dynamic callbacks for logging and resetting event queue. * doc/README.stream5: * doc/snort_manual.tex: * src/dynamic-preprocessors/dcerpc/spp_dcerpc.c: * src/dynamic-preprocessors/dns/spp_dns.c: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: * src/dynamic-preprocessors/smtp/spp_smtp.c: * src/dynamic-preprocessors/ssh/spp_ssh.c: * src/dynamic-preprocessors/ssl/spp_ssl.c: * src/preprocessors/perf-base.c: * src/preprocessors/perf-base.h: * src/preprocessors/snort_httpinspect.c: * src/preprocessors/snort_httpinspect.h: * src/preprocessors/spp_httpinspect.c: * src/preprocessors/spp_rpc_decode.c: * src/preprocessors/spp_stream5.c: * src/preprocessors/Stream5/snort_stream5_session.h: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/preprocessors/Stream5/snort_stream5_tcp.h: * src/preprocessors/Stream5/snort_stream5_udp.c: * src/preprocessors/Stream5/snort_stream5_udp.h: * src/preprocessors/Stream5/stream5_common.c: * src/preprocessors/Stream5/stream5_common.h: * src/preprocessors/stream_api.h: Port and service based filtering to improve performance. Stream5 will ignore traffic (if it is configured to do so) for which there are no rules or preprocessors configured to look at this traffic. * src/dynamic-preprocessors/ftptelnet/ftpp_ui_client_lookup.c: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_client_lookup.h: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_config.c: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_config.h: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_server_lookup.c: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_server_lookup.h: * src/dynamic-preprocessors/ftptelnet/hi_util_kmap.h: * src/dynamic-preprocessors/ftptelnet/Makefile.am: * src/dynamic-preprocessors/ftptelnet/pp_ftp.c: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: ftp_telnet_protocol server configurations now support multiple IP addresses and netmasks. * src/preprocessors/HttpInspect/include/hi_ui_config.h: * src/preprocessors/HttpInspect/include/hi_ui_server_lookup.h: * src/preprocessors/HttpInspect/user_interface/hi_ui_server_lookup.c: * src/preprocessors/snort_httpinspect.c: * src/preprocessors/spp_httpinspect.c: http_inspect preprocessor server configurations now support multiple IP addresses and netmasks. * doc/README.http_inspect: * doc/snort_manual.tex: * src/generators.h: * src/preprocessors/HttpInspect/client/hi_client.c: * src/preprocessors/HttpInspect/event_output/hi_eo_log.c: * src/preprocessors/HttpInspect/include/hi_eo_events.h: * src/preprocessors/HttpInspect/user_interface/hi_ui_config.c: * src/preprocessors/snort_httpinspect.c: Add a "max_headers" and "max_header_length" options to http_inspect server configuration. * src/preprocessors/HttpInspect/client/hi_client.c: Fix to correctly identify end of http client body request. * src/profiler.c: * src/profiler.h: * src/ppm.c: * src/ppm.h: Update to handle rule latency threhsolding with rule option tree. * doc/README.ftptelnet: * doc/snort_manual.tex: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: Added "ignore_data_chan" option to ftp_telnet preprocessor to deprecate confusing "data_chan" option. * src/preprocessors/spp_stream5.c: Fix to alert on dropped packet in midstream session. * doc/CREDITS: * doc/snort_manual.tex: Update for new members of Snort team - Dilbagh Chahal and Ryan Jordan. * etc/snort.conf: Add "trustservers" do default ssl preprocessor configuration. * src/win32/WIN32-Includes/config.h: * src/win32/WIN32-Includes/WinPCAP/pcap-stdinc.h: Updates to compile in Visual Studio 2008. 2008-09-15 Todd Wease * src/detection-plugins/detection_options.c: * src/detection-plugins/detection_options.h: * src/fpcreate.c: * src/generators.h: * src/ppm.c: * src/ppm.h: * src/profiler.c: * src/rules.h: * etc/gen-msg.map: Update rule latency thresholding. * src/preprocessors/spp_flow.c: * src/preprocessors/spp_stream4.c: * doc/README.flow: * doc/README.flow-portscan: * doc/README.stream4: * doc/snort_manual.tex: * doc/snort_manual.pdf: The flow and stream4 preprocessors will be deprecated in a future release. 2008-08-12 Todd Wease * src/bounds.h: * src/dynamic-preprocessors/dcerpc/dcerpc.c: * src/dynamic-preprocessors/dcerpc/dcerpc.h: * src/dynamic-preprocessors/dcerpc/dcerpc_config.c: * src/dynamic-preprocessors/dcerpc/dcerpc_util.c: * src/dynamic-preprocessors/dcerpc/dcerpc_util.h: * src/dynamic-preprocessors/dcerpc/smb_andx_decode.c: * src/dynamic-preprocessors/dcerpc/smb_andx_decode.h: * src/dynamic-preprocessors/dcerpc/snort_dcerpc.c: * src/dynamic-preprocessors/dcerpc/snort_dcerpc.h: * src/dynamic-preprocessors/dcerpc/spp_dcerpc.c: * src/preprocessors/spp_stream5.c: * src/preprocessors/Stream5/snort_stream5_tcp.c: * doc/README.dcerpc: * doc/snort_manual.tex: DCE/RPC preprocessor changes to handle abnormal TCP segmentation. Added option to reassemble fragmentation buffers early. Updated documentation. * src/decode.c: * src/decode.h: * src/preprocessors/Stream5/snort_stream5_session.c: Fixed handling of MPLS label in checking Stream session uniqueness when IPv4 packets are received and build is IPv6. * src/preprocessors/perf-base.c: * src/preprocessors/perf-base.h: MPLS stats are now printed, whether compiled for MPLS or not. * src/detection-plugins/sp_pattern_match.c: Fixed checksum calculation for IPv6 case for 'replace' rule option. * src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c: Added check to not register so rule if it has already been registered. * src/dynamic-preprocessors/smtp/snort_smtp.c: * src/dynamic-preprocessors/smtp/snort_smtp.h: Added better handling of SMTP data header options to avoid false positives occuring with data header buffer overlflow smtp preprocessor event. Thanks to rmkml for bringing this to our attention. * src/event_queue.c: * src/signature.c: Added checks to only allow one rule without an SID defined. Thanks to Christian Mock for bringing this to our attention. * src/parser.c: * doc/README.PerfProfiling: Updated performance profiling README to document new 'filename' option. Fixed handling of 'filename' option in the rule profiling configuration. * src/plugbase.c: Changed plugins startup output to use log function instead of printf(). * src/preprocessors/HttpInspect/client/hi_client.c: Fixes to avoid false positives on http_inspect preprocessor events for bare byte encoding and oversize request-uri directory. * doc/CREDITS: Credits updates. * doc/README.decode: * doc/snort_manual.tex: Fixed some spelling errors and confusing syntax. Thanks to Hari Sekhon for pointing many of these out. 2008-07-18 Todd Wease * src/detection-plugins/sp_dsize_check.c: Fix issue with rule option "dsize" range check. Thanks to Bhadresh Patel for bringing this to our attention. * src/detection-plugins/sp_pcre.c: Fix issue with evaluating PCRE rule options with /U modifier that are followed by a relative content rule option. Many thanks to Bamm Visscher for doing the research, finding the offending rule and producing the test case necessary to track down and fix the issue. Also thanks to others on the snort users list - craig for starting a thread and JJ Cummings for confirming it was not a logging issue. 2008-07-11 Todd Wease * src/byte_extract.c: Added byte test for 3 bytes. * src/debug.c: * src/debug.h: * src/dynamic-preprocessors/libs/ssl.c: * src/dynamic-preprocessors/libs/ssl.h: * src/dynamic-preprocessors/ssl/sf_preproc_info.h: * src/dynamic-preprocessors/ssl/spp_ssl.c: * src/dynamic-preprocessors/ssl/spp_ssl.h: Updates to SSL preprocessor to make it work with stream reassembly, multiple handshake records and disabling detection. * src/decode.c: * src/preprocessors/spp_frag3.c: * src/parser.c: * src/snort.c: * src/snort.h: Fix MPLS fragmentation reassembly issue. * src/detection-plugins/detection_options.c: * src/detection-plugins/detection_options.h: * src/detection-plugins/sp_asn1.c: * src/detection-plugins/sp_byte_check.c: * src/detection-plugins/sp_byte_jump.c: * src/detection-plugins/sp_clientserver.c: * src/detection-plugins/sp_cvs.c: * src/detection-plugins/sp_dsize_check.c: * src/detection-plugins/sp_flowbits.c: * src/detection-plugins/sp_ftpbounce.c: * src/detection-plugins/sp_icmp_code_check.c: * src/detection-plugins/sp_icmp_id_check.c: * src/detection-plugins/sp_icmp_seq_check.c: * src/detection-plugins/sp_icmp_type_check.c: * src/detection-plugins/sp_ip_fragbits.c: * src/detection-plugins/sp_ip_id_check.c: * src/detection-plugins/sp_ipoption_check.c: * src/detection-plugins/sp_ip_proto.c: * src/detection-plugins/sp_ip_tos_check.c: * src/detection-plugins/sp_isdataat.c: * src/detection-plugins/sp_pattern_match.c: * src/detection-plugins/sp_pcre.c: * src/detection-plugins/sp_react.c: * src/detection-plugins/sp_respond2.c: * src/detection-plugins/sp_respond.c: * src/detection-plugins/sp_rpc_check.c: * src/detection-plugins/sp_session.c: * src/detection-plugins/sp_tcp_ack_check.c: * src/detection-plugins/sp_tcp_flag_check.c: * src/detection-plugins/sp_tcp_seq_check.c: * src/detection-plugins/sp_tcp_win_check.c: * src/detection-plugins/sp_ttl_check.c: * src/detection-plugins/sp_urilen_check.c: * src/dynamic-plugins/sp_dynamic.c: * src/dynamic-plugins/sp_preprocopt.c: * src/preprocessors/Stream5/snort_stream5_session.c: * src/sfutil/sfhashfcn.h: Move hash rot macros. * src/dynamic-preprocessors/dcerpc/sf_dcerpc.dsp: * src/dynamic-preprocessors/dns/sf_dns.dsp: * src/dynamic-preprocessors/ftptelnet/sf_ftptelnet.dsp: * src/dynamic-preprocessors/libs/sfdynamic_preproc_libs.dsp: * src/dynamic-preprocessors/smtp/sf_smtp.dsp: * src/dynamic-preprocessors/ssh/sf_ssh.dsp: * src/dynamic-preprocessors/ssl/sf_ssl.dsp: * src/win32/WIN32-Prj/sf_engine.dsp: * src/win32/WIN32-Prj/snort.dsp: Update Win32 project files to include MPLS. * src/util.c: For read mode, reset errno after gathering pcaps from a directory. * etc/sid-msg.map: Updates. 2008-06-16 Todd Wease * src/cpuclock.h: Fixed compilation issue on HPUX machines related to performance profiling and the assembly instructions used for getting cpu clock ticks. Thanks to Pavan Raj and Jaipal Reddy for pointing this out. * src/decode.c: * src/decode.h: * src/dynamic-plugins/sf_engine/sf_snort_packet.h: * src/generators.h: * src/log.c: * src/log.h: * src/output-plugins/spo_unified2.c: * src/parser.c: * src/preprocessors/perf-base.c: * src/preprocessors/perf-base.h: * src/preprocessors/spp_frag3.c: * src/preprocessors/Stream5/snort_stream5_session.c: * src/preprocessors/Stream5/stream5_common.h: * src/snort.c: * src/snort.h: * src/util.c: * configure.in: * doc/snort_manual.tex: * doc/snort_manual.pdf: * doc/README.mpls: Added MPLS decoding support. * src/decode.c: * src/generators.h: * etc/gen-msg.map: Fixed alert message for IP datagram being greater than captured length. * src/decode.h: * src/detection-plugins/sp_pattern_match.c: * src/detection-plugins/sp_pattern_match.h: * src/detection-plugins/sp_pcre.c: * src/dynamic-plugins/sf_dynamic_common.h: * src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.h: * src/dynamic-plugins/sf_engine/sf_snort_plugin_byte.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_content.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_loop.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_pcre.c: * src/fpcreate.c: * src/fpdetect.c: * src/preprocessors/HttpInspect/client/hi_client.c: * src/preprocessors/HttpInspect/client/hi_client_norm.c: * src/preprocessors/HttpInspect/include/hi_client.h: * src/preprocessors/HttpInspect/include/hi_include.h: * src/preprocessors/HttpInspect/include/hi_ui_config.h: * src/preprocessors/HttpInspect/server/hi_server.c: * src/preprocessors/HttpInspect/session_inspection/hi_si.c: * src/preprocessors/HttpInspect/user_interface/hi_ui_config.c: * src/preprocessors/snort_httpinspect.c: * src/preprocessors/spp_httpinspect.c: * src/sfutil/acsmx2.c: * src/sfutil/acsmx2.h: * src/sfutil/acsmx.c: * src/sfutil/acsmx.h: * src/sfutil/bnfa_search.c: * src/sfutil/bnfa_search.h: * src/sfutil/mpse.c: * src/sfutil/mpse.h: * src/sfutil/sfksearch.c: * src/sfutil/sfksearch.h: * src/util.c: * src/util.h: * doc/README.http_inspect: * doc/snort_manual.tex: * doc/snort_manual.pdf: New Feature for HTTP Inspect to split requests into 5 components - Method, URI, Header (non-cookie), Cookies, Body. Added HTTP server specific configurations to normalize HTTP header and/or cookie buffers. Provided content and PCRE modifiers to allow searches within one or more of those individual buffers. Added content modifier to allow rule writer to specify content to be used for fast pattern matcher. Updated dynamic rule API to allow searches within the new buffers. * src/detection-plugins/sp_flowbits.c: * src/dynamic-plugins/sp_dynamic.c: * src/parser.c: * src/snort.c: * src/snort.h: Provided command line switch to bail on rule parsing failure. * src/dynamic-preprocessors/ftptelnet/spp_ftptelnet.c: * src/preprocessors/spp_httpinspect.c: Fixed some configuration error checking. * src/dynamic-preprocessors/ssl/spp_ssl.c: Fixed false negative when using 'trustservers' option. * src/output-plugins/spo_database.c: Fixed issue where when using the 'ruletype' keyword with database output, events were getting logged using both the default log method and the ruletype log method. Thanks to Agent Smith for pointing this out. * src/output-plugins/spo_unified2.c: Fixed issue in unified2 code where the timestamp of an event on a stream reassembled packet was using the last stream segment instead of the first. * src/parser.c: * src/profiler.c: * src/snort.h: * doc/snort_manual.tex: * doc/snort_manual.pdf: Provided option to rule and preprocessor profiling configurations to log to file instead of syslog. * src/preprocessors/perf-flow.c: Packet size distribution reported by snort flow stats do not count reassmbled packets anymore. * src/preprocessors/Stream5/snort_stream5_tcp.c: Update Stream5 to flush bytes up to ACK if ACK falls in the middle of a segment instead of including entire segment in reassembled packet. * src/snort.c: Reset packet processor when reading multiple pcaps and pcap reset option is used. * doc/README.decode: Update GRE decoder alerts. 2008-06-04 Todd Wease * src/fpdetect.c: * src/detection-plugins/detection_options.c: Fix issue where pass rules weren't getting precedence over alert rules. Thanks to Jason Haar for pointing this out. * src/snort.c: Reset data link for new pcap when reading multiple pcaps. * etc/gen-msg.map: Add IPv6 decoder events. 2008-05-07 Todd Wease * src/decode.c: * src/decode.h: * src/dynamic-plugins/sf_engine/sf_snort_packet.h: Fix issue in ICMP6 code that made an incorrect calculation when the ICMP6 type was an echo or an echo reply. * src/detection-plugins/detection_options.c: * src/detection-plugins/detection_options.h: * src/profiler.c: * src/profiler.h: Pattern Matcher Caching & Rule Processing Performance Improvements. * src/dynamic-preprocessors/smtp/snort_smtp.c: Fix memory leak caused by missed or dropped traffic. * src/preprocessors/HttpInspect/include/hi_eo_events.h: Remove redundant macro. * doc/snort_manual.tex: * doc/snort_manual.pdf: * doc/README.decoder_preproc_rules: Add documentation on the use of decoder and preprocessor rules. 2008-04-30 Todd Wease * src/decode.c: * src/decode.h: * src/dynamic-plugins/sf_engine/sf_snort_packet.h: * src/fpcreate.c: * src/fpdetect.c: * src/profiler.c: Process IP rules by fast pattern searching payload of outer IP, then evaluating matching rules against IP header & payload of inner & outer IP. This is to address false positives and false negatives in IP rules. * src/detection-plugins/sp_cvs.c: * src/detection-plugins/sp_cvs.h: * src/preprocessors/spp_frag3.c: Fix typos. Thanks to rmkml for pointing this out. * src/ipv6_port.h: * src/log.c: * src/log_text.c: Update log to correct datagram length macro for IPv6. * src/detection-plugins/sp_pcre.c: * src/dynamic-plugins/sf_dynamic_define.h: * src/dynamic-plugins/sf_dynamic_engine.h: * src/dynamic-plugins/sf_dynamic_plugins.c: * src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.h: * src/dynamic-plugins/sf_engine/sf_snort_plugin_pcre.c: Expose a pcre wrapper function to detection library rules via plugin api. 2008-04-14 Todd Wease * configure.in: * src/detect.c: * src/detect.h: * src/detection-plugins/Makefile.am: * src/detection-plugins/detection_options.c: * src/detection-plugins/detection_options.h: * src/detection-plugins/sp_asn1.c: * src/detection-plugins/sp_asn1.h: * src/detection-plugins/sp_byte_check.c: * src/detection-plugins/sp_byte_check.h: * src/detection-plugins/sp_byte_jump.c: * src/detection-plugins/sp_byte_jump.h: * src/detection-plugins/sp_clientserver.c: * src/detection-plugins/sp_clientserver.h: * src/detection-plugins/sp_cvs.c: * src/detection-plugins/sp_cvs.h: * src/detection-plugins/sp_dsize_check.c: * src/detection-plugins/sp_dsize_check.h: * src/detection-plugins/sp_flowbits.c: * src/detection-plugins/sp_flowbits.h: * src/detection-plugins/sp_ftpbounce.c: * src/detection-plugins/sp_ftpbounce.h: * src/detection-plugins/sp_icmp_code_check.c: * src/detection-plugins/sp_icmp_code_check.h: * src/detection-plugins/sp_icmp_id_check.c: * src/detection-plugins/sp_icmp_id_check.h: * src/detection-plugins/sp_icmp_seq_check.c: * src/detection-plugins/sp_icmp_seq_check.h: * src/detection-plugins/sp_icmp_type_check.c: * src/detection-plugins/sp_icmp_type_check.h: * src/detection-plugins/sp_ip_fragbits.c: * src/detection-plugins/sp_ip_fragbits.h: * src/detection-plugins/sp_ip_id_check.c: * src/detection-plugins/sp_ip_id_check.h: * src/detection-plugins/sp_ipoption_check.c: * src/detection-plugins/sp_ipoption_check.h: * src/detection-plugins/sp_ip_proto.c: * src/detection-plugins/sp_ip_proto.h: * src/detection-plugins/sp_ip_same_check.c: * src/detection-plugins/sp_ip_same_check.h: * src/detection-plugins/sp_ip_tos_check.c: * src/detection-plugins/sp_ip_tos_check.h: * src/detection-plugins/sp_isdataat.c: * src/detection-plugins/sp_isdataat.h: * src/detection-plugins/sp_pattern_match.c: * src/detection-plugins/sp_pattern_match.h: * src/detection-plugins/sp_pcre.c: * src/detection-plugins/sp_pcre.h: * src/detection-plugins/sp_react.c: * src/detection-plugins/sp_react.h: * src/detection-plugins/sp_respond2.c: * src/detection-plugins/sp_respond2.h: * src/detection-plugins/sp_respond.c: * src/detection-plugins/sp_respond.h: * src/detection-plugins/sp_rpc_check.c: * src/detection-plugins/sp_rpc_check.h: * src/detection-plugins/sp_session.c: * src/detection-plugins/sp_session.h: * src/detection-plugins/sp_tcp_ack_check.c: * src/detection-plugins/sp_tcp_ack_check.h: * src/detection-plugins/sp_tcp_flag_check.c: * src/detection-plugins/sp_tcp_flag_check.h: * src/detection-plugins/sp_tcp_seq_check.c: * src/detection-plugins/sp_tcp_seq_check.h: * src/detection-plugins/sp_tcp_win_check.c: * src/detection-plugins/sp_tcp_win_check.h: * src/detection-plugins/sp_ttl_check.c: * src/detection-plugins/sp_ttl_check.h: * src/detection-plugins/sp_urilen_check.c: * src/detection-plugins/sp_urilen_check.h: * src/dynamic-plugins/sp_dynamic.c: * src/dynamic-plugins/sp_dynamic.h: * src/dynamic-plugins/sp_preprocopt.c: * src/dynamic-plugins/sp_preprocopt.h: * src/dynamic-preprocessors/smtp/snort_smtp.c: * src/event_queue.c: * src/fpcreate.c: * src/fpcreate.h: * src/fpdetect.c: * src/fpdetect.h: * src/parser.c: * src/pcrm.h: * src/plugbase.c: * src/plugbase.h: * src/ppm.c: * src/ppm.h: * src/preprocessors/spp_frag3.c: * src/preprocessors/spp_frag3.h: * src/preprocessors/str_search.c: * src/preprocessors/str_search.h: * src/rules.h: * src/sfutil/acsmx2.c: * src/sfutil/acsmx2.h: * src/sfutil/acsmx.c: * src/sfutil/acsmx.h: * src/sfutil/bnfa_search.c: * src/sfutil/bnfa_search.h: * src/sfutil/mpse.c: * src/sfutil/mpse.h: * src/sfutil/sfksearch.c: * src/sfutil/sfksearch.h: Pattern Matcher Caching & Rule Processing Performance Improvements. * configure.in: * src/dynamic-plugins/sf_dynamic_plugins.c: * src/event_wrapper.c: * src/fpcreate.c: * src/fpcreate.h: * src/fpdetect.c: * src/fpdetect.h: * src/parser/IpAddrSet.c: * src/parser.c: * src/parser.h: * src/pcrm.c: * src/plugbase.c: * src/plugbase.h: * src/preprocessors/spp_httpinspect.c: * src/preprocessors/spp_stream4.c: * src/preprocessors/spp_stream5.c: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/preprocessors/stream_ignore.c: * src/preprocessors/stream_ignore.h: * src/profiler.c: * src/sfthreshold.c: * src/sfthreshold.h: * src/sfutil/acsmx2.c: * src/sfutil/acsmx2.h: * src/sfutil/bnfa_search.c: * src/sfutil/bnfa_search.h: * src/sfutil/mpse.c: * src/sfutil/mpse.h: * src/sfutil/sfksearch.c: * src/sfutil/sfksearch.h: * src/sfutil/sfportobject.c: * src/sfutil/sfportobject.h: * src/sfutil/sfthd.c: * src/sfutil/sfthd.h: * src/sfutil/sf_vartable.c: * src/sfutil/sf_vartable.h: * src/signature.c: * src/signature.h: * src/snort.c: * src/spo_plugbase.h: * src/target-based/sftarget_protocol_reference.c: * src/target-based/sftarget_protocol_reference.h: * src/target-based/sftarget_reader.c: * src/win32/WIN32-Prj/sf_engine.dsp: * src/win32/WIN32-Prj/snort.dsp: Added configuration option to clean up all initialization memory at shutdown. * src/decode.h: * src/preprocessors/snort_httpinspect.c: Add counter for HTTP pipeline requests. * src/dynamic-preprocessors/ftptelnet/pp_ftp.c: Fixed issue where some FTP traffic was being labeled as encrypted when it was not. * src/output-plugins/spo_database.c: Free SQL statement. Thanks to Carter Browne for pointing this out. * snort.8: * doc/snort_manual.tex: * src/snort.c: * src/util.c: Update to indicate --pid-path specifies the directory for the PID file. Thanks to Lee Clemens for pointing out the ambiguity. * src/snort.c: For --pcap-show option, print to stdout instead of stderr. * doc/snort_manual.tex: * src/snort.h: Set minimum max attribute hosts to 32 instead of 8192. * src/target-based/sf_attribute_table_parser.l: Allow ! character in attribute table grammar for string values. * src/snort.c: * src/util.c: Print log message with BPF filter passed to Snort. * src/sfutil/mpse.c: Fix issue with default case (which isn't ever hit) of pattern matcher performance stats not being calculated correctly. Thanks to Wang Zhen for pointing this out. * src/parser.c: Fixed string comparison for "portvar" and "ipvar" to use correct string length. Thanks to Eric Duda for pointing this out. * doc/INSTALL: Update MAC OSX install notes. * doc/README.arpspoof: Update arpspoof documentation. * etc/snort.conf: Update frag3_global configuration example. 2008-04-03 Steven Sturges * rpm/snort.spec: Add ssl preprocessor. Thanks fo Andrew Pendray for noticing. 2008-03-12 Todd Wease * src/decode.c: * doc/README.gre: * doc/snort_manual.tex: * doc/snort_manual.pdf: * doc/Makefile.am: Disable PPP decoding if architecture requires word alignment, e.g. SPARC machines. * src/dynamic-preprocessors/dcerpc/smb_structs.h: Fix endian issue when determining if SMB is using unicode strings. * src/dynamic-preprocessors/ftptelnet/ftpp_si.c: Fix issue where FTPTelnet sometimes determines incorrect direction with midstream session. * src/generators.h: * src/preprocessors/spp_frag3.c: * doc/README.frag3: * doc/snort_manual.tex: * doc/snort_manual.pdf: * etc/gen-msg.map: Update frag3 to remove enforcement of ttl_limit. Add preprocessor alert for min_ttl anomaly. * doc/README.ipip: * doc/Makefile.am: Added README doc for IP in IP decoding. * doc/README.stream4: * etc/gen-msg.map: Fixed some typos. Thanks to rmkml for pointing this out. 2008-03-06 Steven Sturges * src/dynamic-preprocessors/ssl/spp_ssl.c: * doc/README.ssl: * doc/snort_manual.tex: * doc/snort_manual.pdf: Improve handling for change cipher records and rule options. Indicate that trustservers option only makes sense when noinspect_encrypted is used. 2008-03-05 Steven Sturges * doc/README.variables: * doc/snort_manual.tex: * doc/snort_manual.pdf: Fix a few misspellings. Thanks to Markus Lude for letting us know. 2008-03-04 Steven Sturges * configure.in: * src/win32/WIN32-Prj/snort_installer.nsi: * rpm/snort.spec: * src/win32/WIN32-Includes/config.h: 2.8.1 RC prep * doc/snort_manual.tex: * doc/snort_manual.pdf: * doc/README.arpspoof (added): * doc/README.pcap_readmode (added): * snort.8: Document new multiple pcap command line options and ARP Spoof preprocessor configuration. * doc/README.dcerpc: * doc/README.http_inspect: * doc/README.stream4: Update to include information about alerts generated from various preprocessors. * src/decode.c: * src/log_text.c: * src/parser.c: * src/profiler.c: * src/detection-plugins/sp_cvs.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_pcre.c: * src/dynamic-preprocessors/libs/sfcommon.h: * src/preprocessors/spp_frag3.c: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/sfutil/bitop_funcs.h: * src/sfutil/sf_iph.c: * src/sfutil/sfportobject.c: * src/target-based/sftarget_reader.c: * src/win32/WIN32-Includes/rpc/types.h: Win32 compiler warning cleanup. * src/decode.h: * src/dynamic-plugins/sf_engine/sf_snort_packet.h: * src/win32/WIN32-Prj/sf_engine.dsp: Reorganize to provide better compatibility with shared libraries. * src/detect.c: * src/detect.h: * src/plugbase.c: * src/plugbase.h: * src/dynamic-plugins/sf_dynamic_common.h: * src/dynamic-plugins/sf_dynamic_preprocessor.h: * src/dynamic-preprocessors/dcerpc/dcerpc.c: * src/dynamic-preprocessors/dcerpc/dcerpc.h: * src/dynamic-preprocessors/dcerpc/sf_dcerpc.dsp: * src/dynamic-preprocessors/dcerpc/smb_andx_decode.c: * src/dynamic-preprocessors/dcerpc/snort_dcerpc.c: * src/dynamic-preprocessors/dcerpc/snort_dcerpc.h: * src/dynamic-preprocessors/dcerpc/spp_dcerpc.c: * src/output-plugins/spo_alert_fast.c: * src/snort.c: * src/snort.h: Update to logging of DCE/RPC defragmented packets when using console/fast output modes. * src/preprocids.h: * src/dynamic-plugins/sf_dynamic_engine.h: * src/dynamic-plugins/sf_engine/Makefile.am: * src/dynamic-plugins/sf_dynamic_plugins.c: * src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.h: * src/dynamic-plugins/sf_preproc_example/sf_dynamic_preproc_lib.c: Add ability for dynamic rules to store and retrieve data on stream session. * src/detection-plugins/sp_pcre.c: Fix compile warning with older versions of PCRE library. * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: Update default configuration for FTP's STRU command. 2008-01-27 Todd Wease * src/decode.c: * src/decode.h: * src/dynamic-plugins/sf_engine/sf_snort_packet.h: * src/generators.h: * src/preprocessors/spp_frag3.c: * src/snort.c: * src/snort.h: * src/util.c: * etc/gen-msg.map: Added IP in IP encapsulation support for both IPv4 and IPv6. * src/dynamic-plugins/sf_dynamic_engine.h: * src/dynamic-plugins/sf_dynamic_plugins.c: * src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c: * src/snort.c: Enforce stricter versioning when loading shared objects. Vesions of shared libraries - engine and dynamic preprocessors - will not load if from an older version of Snort. * src/dynamic-preprocessors/ssl/spp_ssl.c: Fatal error if commas are not used in SSL dynamic preprocessor configuration. Thanks to Chris Rohlf for bringing this to our attention. * src/generators.h: * src/preprocessors/Stream5/snort_stream5_tcp.c: * etc/gen-msg.map: Update Stream5 to alert on data without TCP flags when non-linux policy. Thanks to Chris Eagle, Naval Postgraduate School, for bringing this to our attention. * src/parser.c: Generate a parsing error if an empty IP list is used (this is equivalent to !any). Thanks to Chris Rohlf for bring this to our attention. * src/parser.c: * src/sfutil/sfportobject.c: * src/sfutil/sfportobject.h: Various port object changes. Update to handle open port ranges (ie, 1024:) and print error lines from config file parsing. Added support for handling embedded lists with negations. Use more compatible strrchr() instead of rindex(). Add stricter configuration checks - thanks to Rmkml for bringing this to our attention. * src/target-based/sftarget_reader.c: Use inet_pton() instead of inet_aton. * src/target-based/sftarget_reader.c: * src/util.c: Set uid and gid of target-based thread if not already set. * doc/snort_manual.tex: * doc/snort_manual.pdf: Update to describe new pcre match limit options. * src/win32/WIN32-Prj/snort.dsp: Remove system dependent Oracle paths from project. * src/fpcreate.c: Correctly set the max_size when a longer pattern. * src/profiler.c: Add Percent of Total column to output. * src/sfutil/sf_textlog.c: Added format string to prevent messages with certain format from crashing Snort. 2007-12-10 Todd Wease * configure.in: Require PCRE version 6 or better * src/dynamic-preprocessors/smtp/Makefile.am: * src/dynamic-preprocessors/smtp/smtp_log.c: * src/dynamic-preprocessors/smtp/smtp_xlink2state.c: * src/dynamic-preprocessors/smtp/snort_smtp.c: * src/dynamic-preprocessors/smtp/snort_smtp.h: * src/dynamic-preprocessors/smtp/spp_smtp.c: * src/dynamic-preprocessors/smtp/sf_smtp.dsp * src/preprocessors/spp_stream4.c: * src/preprocessors/spp_stream5.c: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/preprocessors/Stream5/snort_stream5_tcp.h: * src/preprocessors/stream_api.h: Reduce command line and response line overflow false positives in SMTP preprocessor when Snort is missing packets. Only alert on one unique SMTP event per session. * configure.in: Add check for Phil Woods pcap so that pcap stats are computed correctly. Thanks to John Hally for bringing this to our attention. * doc/INSTALL: Update for building on Mac OSX 10.5. Thanks to Martin Fong for bringing this to our attention. * doc/README.asn1: * doc/README.dcerpc: * doc/README.dns: * doc/README.flow-portscan: * doc/README.frag3: * doc/README.ssh: * doc/README.stream5: Update to include information about alerts generated from various preprocessors. * doc/snort_manual.pdf: * doc/snort_manual.tex: Add info on stream_size option added with Stream5. * etc/gen-msg.map: Update to include GRE alerts * src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.h: Allow specifying metadata within a shared library rule. * src/decode.c: Update for decoding IP6 header lengths. * src/detect.c: * src/parser.c: Correctly handle rule-type keyword. Thanks to Tung Tran for bringing this to our attention. * src/log_text.c: * src/log.c: Fix issue with printing IPv6 addresses. * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: Update default configuration to allow optional string to STRU command. * src/dynamic-preprocessors/libs/sfparser.c: * src/dynamic-preprocessors/libs/ssl.c: * src/dynamic-preprocessors/libs/ssl.h: * src/dynamic-preprocessors/ssl/spp_ssl.c: Updates to better handle SSLv2 recognition. * src/preprocessors/snort_stream4_session.c: * src/preprocessors/stream.h: Fix misaligned structures for Sparc 64bit OpenBSD. Thanks to Markus Lude for helping us track down the problem. * src/preprocessors/spp_stream4.c: Warn if configured with stream4 & target-based attributes. * src/preprocessors/snort_httpinspect.c: * src/preprocessors/HttpInspect/client/hi_client.c: * src/preprocessors/HttpInspect/session_inspection/hi_si.c: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/sfutil/sf_ip.c: * src/sfutil/sf_ip.h: * src/sfutil/sf_iph.c: * src/sfutil/sf_ipvar.c: Code cleanup for IPv6 related changes. * src/preprocessors/Stream5/snort_stream5_tcp.c: Handle additional cases of multiple sequences of TCP SYN packets on a session that has previously been reset. * src/preprocessors/Stream5/snort_stream5_tcp.c: Add checks for missing packets in reassembly. * src/sfutil/sfportobject.c: * src/sfutil/sfxhash.c: Code cleanup. * src/target-based/sf_attribute_table_parser.l: * src/target-based/sftarget_reader.c: Better handling for starting attribute reload thread and logging parsing errors. * src/fpcreate.c: * src/fpdetect.c: * src/detection-plugins/sp_asn1.c: * src/detection-plugins/sp_byte_check.c: * src/detection-plugins/sp_byte_jump.c: * src/detection-plugins/sp_clientserver.c: * src/detection-plugins/sp_cvs.c: * src/detection-plugins/sp_dsize_check.c: * src/detection-plugins/sp_flowbits.c: * src/detection-plugins/sp_ftpbounce.c: * src/detection-plugins/sp_icmp_code_check.c: * src/detection-plugins/sp_icmp_id_check.c: * src/detection-plugins/sp_icmp_seq_check.c: * src/detection-plugins/sp_icmp_type_check.c: * src/detection-plugins/sp_ip_fragbits.c: * src/detection-plugins/sp_ip_id_check.c: * src/detection-plugins/sp_ip_proto.c: * src/detection-plugins/sp_ip_same_check.c: * src/detection-plugins/sp_ip_tos_check.c: * src/detection-plugins/sp_ipoption_check.c: * src/detection-plugins/sp_isdataat.c: * src/detection-plugins/sp_pattern_match.c: * src/detection-plugins/sp_pcre.c: * src/detection-plugins/sp_react.c: * src/detection-plugins/sp_respond.c: * src/detection-plugins/sp_respond2.c: * src/detection-plugins/sp_rpc_check.c: * src/detection-plugins/sp_session.c: * src/detection-plugins/sp_tcp_ack_check.c: * src/detection-plugins/sp_tcp_flag_check.c: * src/detection-plugins/sp_tcp_seq_check.c: * src/detection-plugins/sp_tcp_win_check.c: * src/detection-plugins/sp_ttl_check.c: * src/detection-plugins/sp_urilen_check.c: * src/dynamic-plugins/sp_dynamic.c: * src/dynamic-plugins/sp_preprocopt.c: * src/parser.c: * src/snort.c: * src/snort.h: Added performance profiling stats for rule option evaluation. Add limits to pcre matching that could affect performance. 2007-11-12 Todd Wease * src/byte_extract.c: * src/detection-plugins/sp_byte_check.c: * src/detection-plugins/sp_byte_jump.c: Allow byte_jump 'string' option to support variable-length numeric data. * src/cpuclock.h: * configure.in: Add support for rule and preprocessor profiling times for Sparc v9 processors. * src/decode.h: * src/decode.c: * doc/README.gre: * src/generators.h: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/snort.h: * src/util.c: * src/util.h: * configure.in: Update GRE decoder to support PPTP GRE v.1 header. Add new GRE decoder alerts and README. Integrate with IPv6 codebase. * src/decode.c: * src/decode.h: * src/dynamic-plugins/sf_engine/sf_snort_packet.h: Update decoder to work will all 3 versions of pflog files. Thanks to Ronaldo Maia for reporting this issue. * src/parser.c: * src/parser.h: * src/snort.c: * src/snort.h: * src/plugbase.c: * src/plugbase.h: * src/util.c: * src/util.h: * src/decode.c: * src/dynamic-preprocessors/dcerpc/spp_dcerpc.c: * src/dynamic-preprocessors/dns/spp_dns.c: * src/dynamic-preprocessors/ftptelnet/spp_ftptelnet.c: * src/dynamic-preprocessors/smtp/spp_smtp.c: * src/mempool.c: * src/preprocessors/perf.c: * src/preprocessors/perf-flow.c: * src/preprocessors/perf.h: * src/preprocessors/portscan.c: * src/preprocessors/portscan.h: * src/preprocessors/spp_flow.c: * src/preprocessors/spp_frag3.c: * src/preprocessors/spp_httpinspect.c: * src/preprocessors/spp_perfmonitor.c: * src/preprocessors/spp_sfportscan.c: * src/preprocessors/spp_stream4.c: * src/preprocessors/spp_stream5.c: * src/preprocessors/Stream5/snort_stream5_icmp.c: * src/preprocessors/Stream5/snort_stream5_icmp.h: * src/preprocessors/Stream5/snort_stream5_session.c: * src/preprocessors/Stream5/snort_stream5_session.h: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/preprocessors/Stream5/snort_stream5_tcp.h: * src/preprocessors/Stream5/snort_stream5_udp.c: * src/preprocessors/Stream5/snort_stream5_udp.h: * src/profiler.c: * src/profiler.h: * src/sfthreshold.c: * src/sfthreshold.h: * src/sfutil/sfxhash.c: * src/sfutil/sfxhash.h: * src/tag.c: * src/tag.h: Snort can now read multiple pcaps on the command line. The '-r' flag can be given multiple times, as well as options for reading a list of pcaps on the command line, a file containing pcaps to read and/or a directory to recurse through gathering pcaps. Multiple filters can be used and an option to reset Snort to a post initialization state for each pcap read can be given. * src/detect.c: * src/fpcreate.c: * src/fpcreate.h: * src/parser.c: * src/parser.h: * src/sfutil/sfportobject.c: * src/sfutil/sfportobject.h: * src/sfutil/sfrim.h: Portlists code consolidation and general cleanup. * src/detect.c: * src/detection-plugins/sp_respond2.c: * src/detection-plugins/sp_respond.c: * src/dynamic-plugins/sf_dynamic_preprocessor.h: * src/dynamic-preprocessors/ftptelnet/ftpp_si.h: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_client_lookup.c: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_client_lookup.h: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_config.c: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_config.h: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_server_lookup.h: * src/dynamic-preprocessors/ftptelnet/pp_ftp.c: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: * src/fpdetect.c: * src/ipv6_port.h: * src/output-plugins/spo_alert_sf_socket.c: * src/output-plugins/spo_log_ascii.c: * src/output-plugins/spo_unified2.c: * src/output-plugins/spo_unified.c: * src/preprocessors/HttpInspect/include/hi_si.h: * src/preprocessors/HttpInspect/include/hi_ui_config.h: * src/preprocessors/HttpInspect/include/hi_ui_server_lookup.h: * src/preprocessors/HttpInspect/user_interface/hi_ui_server_lookup.c: * src/preprocessors/portscan.c: * src/preprocessors/portscan.h: * src/preprocessors/snort_httpinspect.c: * src/preprocessors/snort_stream4_session.c: * src/preprocessors/spp_sfportscan.c: * src/preprocessors/spp_stream4.c: * src/preprocessors/spp_stream5.c: * src/preprocessors/Stream5/snort_stream5_icmp.c: * src/preprocessors/Stream5/snort_stream5_icmp.h: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/preprocessors/Stream5/snort_stream5_udp.c: * src/preprocessors/Stream5/snort_stream5_udp.h: * src/preprocessors/Stream5/stream5_common.h: * src/preprocessors/stream_api.h: * src/preprocessors/stream.h: * src/preprocessors/stream_ignore.c: * src/preprocessors/stream_ignore.h: * src/sfthreshold.c: * src/sfthreshold.h: * src/sfutil/sf_ip.c: * src/sfutil/sf_ip.h: * src/sfutil/sf_ipvar.c: * src/sfutil/sfthd.c: * src/sfutil/sfthd.h: * src/tag.c: IPv6 data type name changes to avoid library namespace conflicts. * src/detection-plugins/sp_pattern_match.c: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: * src/preprocessors/snort_stream4_udp.c: * src/rules.h: * src/sf_sdlist.c: * src/sf_types.h: Fix compiler warnings. * src/detection-plugins/sp_pcre.c: * src/fpdetect.c: Fixed issue where some rules will continue to match on a Uri, even after the first packet. * src/dynamic-plugins/Makefile.am: * src/dynamic-plugins/sf_dynamic_engine.h: * src/dynamic-plugins/sp_dynamic.c: * src/dynamic-plugins/sp_dynamic.h: * src/fpcreate.c: Enabled target-based code to properly assess dynamic rule flow. * src/dynamic-preprocessors/dcerpc/sf_dcerpc.dsp: * src/dynamic-preprocessors/dns/sf_dns.dsp: * src/dynamic-preprocessors/ftptelnet/sf_ftptelnet.dsp: * src/dynamic-preprocessors/sf_dynamic_initialize/sf_dynamic_initialize.dsp: * src/dynamic-preprocessors/smtp/sf_smtp.dsp: * src/dynamic-preprocessors/ssh/sf_ssh.dsp: Update Win32 project files to include target-based and GRE defines. * src/dynamic-preprocessors/ftptelnet/pp_ftp.c: Allow white space prior to FTP command. * src/preprocids.h: * doc/README.ssl: * doc/snort_manual.tex: * etc/snort.conf: * configure.in: * src/win32/WIN32-Prj/snort.dsw: * src/dynamic-preprocessors/ssl/Makefile.am: * src/dynamic-preprocessors/ssl/sf_preproc_info.h: * src/dynamic-preprocessors/ssl/sf_ssl.dsp: * src/dynamic-preprocessors/ssl/spp_ssl.c: * src/dynamic-preprocessors/ssl/spp_ssl.h: * src/win32/WIN32-Includes/config.h: Added SSL preprocessor. * src/ipv6_port.h: Update IP_CLEAR to clear all fields. Update IP_COPY_VALUE to copy each field individually. * src/log.c: * src/output-plugins/spo_alert_fast.c: * src/output-plugins/spo_alert_full.c: * src/log_text.h: * src/output-plugins/spo_csv.c: * src/output-plugins/spo_database.c: * src/output-plugins/spo_log_tcpdump.c: * src/win32/WIN32-Prj/snort.dsp: * src/log_text.c: * src/log_text.h: * src/sfutil/sf_textlog.c: * src/sfutil/sf_textlog.h: Added rollover of logs upon reaching configured limit - applies to alert_full, alert_fast, log_tcpdump, alert_csv. * src/log.c: Added IP obfuscation for IPv6 addresses. * src/plugbase.c: * src/preprocessors/spp_stream4.c: * src/preprocessors/Stream5/snort_stream5_tcp.c: * doc/README.stream4: * doc/README.stream5: * doc/snort_manual.tex: * etc/snort.conf: * src/win32/WIN32-Prj/snort.dsp: * src/detection-plugins/sp_cvs.c: * src/detection-plugins/sp_cvs.h: CVS detection plugin. Currently only looks for an invalid entry. Ports 514 and 2401 added to default ports for stream reassembly. * src/ppm.c: * src/ppm.h: * src/profiler.c: * doc/snort_manual.tex: Fix microseconds calculations. Add ability to use ppm with readback mode. Add documentation to Snort Manual. * src/preprocessors/HttpInspect/client/hi_client.c: * src/preprocessors/HttpInspect/event_output/hi_eo_log.c: * src/preprocessors/HttpInspect/include/hi_eo_events.h: * src/preprocessors/HttpInspect/include/hi_ui_config.h: * src/preprocessors/HttpInspect/user_interface/hi_ui_config.c: * src/preprocessors/snort_httpinspect.c: * doc/README.http_inspect: * doc/snort_manual.tex: * etc/gen-msg.map: Added overly long http header detection. * src/preprocessors/perf-base.c: * src/preprocessors/spp_perfmonitor.c: * src/snort.c: * src/snort.h: * src/util.c: Fixed issue where packets were being blocked when Snort, running in inline mode, was shutting down. * src/preprocessors/spp_frag3.c: Fixed issue where frag3 does not initialize correctly without any configuration arguments. Thanks to Jason Carr for reporting this. * src/preprocessors/spp_sfportscan.c: Fix endian issue in sfportscan when IP addresses are logged. Thanks to Jerry Litteer for reporting this. * src/preprocessors/spp_stream4.c: * src/preprocessors/spp_stream5.c: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/preprocessors/Stream5/snort_stream5_tcp.h: * src/preprocessors/stream_api.h: Added function to stream api for returning whether or not there are missing segments. Only supported in stream5. * src/preprocessors/str_search.c: * src/sfutil/mpse.c: * src/sfutil/mpse.h: Fixed issue where MPSE global counter was being reset by SMTP for each new pattern matcher it created. * src/sfutil/sf_vartable.c: * src/sfutil/sf_vartable.h: * doc/README.variables: * doc/snort_manual.tex: Fix segfault with duplicate variables in IPv6 code (enabled with --enable-ipv6). * src/target-based/Makefile.am: * src/target-based/sf_attribute_table_parser.l: * src/target-based/sftarget_reader.c: Target based cleanup. * src/util.c: Fixed incorrect calculation of pcap recevied and dropped. * src/win32/WIN32-Prj/sf_engine.dsp: * src/win32/WIN32-Prj/snort.dsp: Added GRE and target-based to default Win32 build. * doc/INSTALL: * doc/README.ftptelnet: * doc/README.http_inspect: * doc/README.sfportscan: * doc/README.stream4: * doc/README.stream5: * doc/README.variables: * doc/snort_manual.tex: Documentation updates. Thanks to Jeff Dell for pointing out unified/unified2 errors in Snort Manual and inconsistencies in sfportscan documentation. 2007-11-06 Steven Sturges * src/win32/WIN32-Includes/pcre.h: * src/win32/WIN32-Includes/pcreposix.h: * src/win32/WIN32-Libraries/pcre.lib: Update Win32 LibPCRE to version 7.4. 2007-11-05 Steven Sturges * src/preprocessors/Stream5/snort_stream5_tcp.c: Fix debug to correctly call inet_ntoa. Thanks to rmkml for reporting the problem. 2007-09-07 Steven Sturges * configure.in: * src/build.h: * src/win32/WIN32-Includes/config.h: * src/win32/WIN32-Prj/snort_installer.nsi: * rpm/snort.spec: * snort.8: 2.8.0 Final release prep. Update spec file to relocate installed schemas and be more consistent with location of docs. * src/parser.c: Initialize rule_count variables. Thanks to Ken Steele for pointing it out. * src/signature.c: * src/detection-plugins/sp_urilen_check.c: * src/plugbase.c: Fix typos in comments. Thanks rmkml for reviewing. * src/tag.c: * src/sfutil/sf_ip.c: * src/sfutil/sf_iph.c: Cleanup printing of IPv6 Addresses. * src/detection-plugins/sp_pcre.c: Initialize the found offset so that it contains correct value when not found. * src/dynamic-preprocessors/ftptelnet/pp_ftp.c: Improve checking on ftp commands from client. * src/dynamic-preprocessors/ftptelnet/spp_ftptelnet.c: Disable ftptelnet when compiled with IPv6. * src/decode.c: * src/snort.c: After logging alert for BSD IPv6 Fragmentation vulnerability, reset the pseudo packet that is used for logging purposes. * src/dynamic-preprocessors/smtp/snort_smtp.c: Memory cleanup of mime boundary regular expressions at Snort exit. * src/preprocessors/portscan.c: * src/preprocessors/portscan.h: * src/preprocessors/spp_sfportscan.c: Memory cleanup of portscan hash table at Snort exit. * src/output-plugins/spo_alert_prelude.c: Correctly get IP Header length for logging. * src/output-plugins/spo_alert_sf_socket.c: Complete initialization after rules are read for specific GID/SID alerts to log via sf socket. * src/output-plugins/spo_unified2.c: Code cleanup. * src/preprocessors/spp_frag3.c: Handle VLAN tags in fragmented traffic and include in rebuilt packets if part of original traffic. * src/preprocessors/spp_stream5.c: Initialize memory for flowbits after all configuration is processed, as config flowbitsize option might change default. Handle byte alignment issue on Solaris with the flowbits data structure used by Stream5. Thanks to JJC & Shane Castle for helping us troubleshoot these issues and testing the patches. * src/preprocessors/Stream5/snort_stream5_icmp.c: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/preprocessors/Stream5/snort_stream5_udp.c: * src/preprocessors/Stream5/stream5_common.c: * src/preprocessors/stream_api.h: Handle strange sequences of multiple TCP Reset packets on the same session when some of those Resets also contain other flags. Thanks to Siim Poder for reporting the problem. 2007-08-31 Steven Sturges * src/parser.c: Updates to prevent variable defintions of the same name as a portvar, var and ipvar. * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: Fix copying of IP address from packet when determining client config that resulted from IPv6 port. * src/output-plugins/spo_alert_prelude.c: Updates to write GID in alert data. Thanks to Yoann Vandoorselaere for the update. * src/output-plugins/spo_unified2.c: Don't write tagged packets the same as unified. Packets that are part of stream reassembly refer to the original event directly from the packet record header. * src/sfutil/sfportobject.c: * src/sfutil/sfportobject.h: Code cleanup and free data correctly on parsing errors. 2007-08-30 Steven Sturges * doc/Makefile.am: Include README.ipv6 & README.variables in the distribution tarball. Thanks to Jeff Dell for pointing out that it was missing. * RELEASE.NOTES: Fix some spelling errors. Thanks rmkml for pointing it out. * etc/snort.conf: Update to use new portvar syntax for HTTP_PORTS, ORACLE_PORTS, and SHELLCODE_PORTS. Thanks to rmkml for mentioning this. 2007-08-22 Steven Sturges * configure.in: * src/sf_types.h: * src/dynamic-preprocessors/smtp/snort_smtp.c: Fixes to build 2.8.0 Beta on OpenBSD. * doc/README.variables: * doc/snort_manual.tex: * doc/snort_manual.pdf: Update PortList documentation. 2007-08-20 Steven Sturges * configure.in: * src/build.h: * src/win32/WIN32-Includes/config.h: * src/win32/WIN32-Prj/snort_installer.nsi: * rpm/snort.spec: 2.8.0 Beta prep. * src/Makefile.am: * src/dynamic-preprocessors/Makefile.am: * src/dynamic-preprocessors/smtp/smtp_xlink2state.c: * src/event.h: * src/output-plugins/spo_log_tcpdump.c: * src/output-plugins/spo_unified.c: * src/output-plugins/spo_unified2.c: * src/pcap_pkthdr32.h (added): * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/preprocessors/flow/portscan/flowps_snort.c: * src/preprocessors/spp_frag3.c: * src/preprocessors/spp_sfportscan.c: * src/preprocessors/spp_stream4.c: * src/preprocessors/stream.h: * src/preprocessors/stream_api.h: * src/snort_packet_header.h (removed): * src/win32/WIN32-Prj/snort.dsp: * src/snort.c: Renamed snort_packet_header.h to pcap_pkthdr32.h and changed instances of SnortPktHdr with pcap_pkthdr except in Event struct and unified code where pcap_pkthdr32 is used because 32 bit timevals are required. * src/dynamic-plugins/sf_dynamic_plugins.c: * src/dynamic-plugins/sf_dynamic_preprocessor.h: * src/dynamic-plugins/sf_preproc_example/sf_dynamic_preproc_lib.c: * src/plugbase.c: * src/plugbase.h: * src/util.c: * src/preprocessors/snort_httpinspect.c: * src/preprocessors/spp_flow.c: * src/preprocessors/spp_frag3.c: * src/preprocessors/spp_httpinspect.c: * src/preprocessors/spp_httpinspect.h: * src/preprocessors/spp_stream4.c: * src/preprocessors/spp_stream5.c: * src/snort.c: Added framework for preprocessors to print stats at exit or USR1 signal. Preprocessors register a function that will print the stats and they will be printed when DropStats() is called. * src/detection-plugins/sp_pattern_match.c: Commented out 'content-list' rule option code since it is broken and there are no plans in the near future to fix it. * src/checksum.h: * src/decode.c: * src/decode.h: * src/detect.c: * src/detect.h: * src/detection-plugins/sp_icmp_id_check.c: * src/detection-plugins/sp_icmp_seq_check.c: * src/detection-plugins/sp_icmp_type_check.c: * src/detection-plugins/sp_ip_fragbits.c: * src/detection-plugins/sp_ip_id_check.c: * src/detection-plugins/sp_ip_proto.c: * src/detection-plugins/sp_ip_same_check.c: * src/detection-plugins/sp_ip_tos_check.c: * src/detection-plugins/sp_pattern_match.c: * src/detection-plugins/sp_respond.c: * src/detection-plugins/sp_respond2.c: * src/detection-plugins/sp_session.c: * src/detection-plugins/sp_ttl_check.c: * src/dynamic-plugins/sf_dynamic_plugins.c: * src/dynamic-plugins/sf_dynamic_preprocessor.h: * src/dynamic-plugins/sf_engine/Makefile.am: * src/dynamic-plugins/sf_engine/sf_snort_packet.h: * src/dynamic-preprocessors/dynamic_preprocessors.dsp: * src/dynamic-preprocessors/Makefile.am: * src/dynamic-preprocessors/sf_dynamic_initialize/sf_dynamic_initialize.dsp: * src/dynamic-preprocessors/Makefile.am: * src/dynamic-preprocessors/dcerpc/sf_dcerpc.dsp: * src/dynamic-preprocessors/dns/sf_dns.dsp: * src/dynamic-preprocessors/ftptelnet/sf_ftptelnet.dsp: * src/dynamic-preprocessors/ftptelnet/Makefile.am: * src/dynamic-preprocessors/smtp/sf_smtp.dsp: * src/dynamic-preprocessors/ssh/sf_ssh.dsp: * src/dynamic-preprocessors/ftptelnet/ftpp_include.h: * src/dynamic-preprocessors/ftptelnet/ftpp_si.c: * src/dynamic-preprocessors/ftptelnet/ftpp_si.h: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_client_lookup.c: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_client_lookup.h: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_config.c: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_config.h: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_server_lookup.c: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_server_lookup.h: * src/dynamic-preprocessors/ftptelnet/pp_ftp.c: * src/dynamic-preprocessors/ftptelnet/pp_telnet.c: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: * src/dynamic-preprocessors/ftptelnet/spp_ftptelnet.c: * src/fpdetect.c: * src/fpdetect.h: * src/generators.h: * src/ipv6.c (removed): * src/ipv6.h (removed): * src/ipv6_port.h (added): * src/log.c: * src/Makefile.am: * src/output-plugins/spo_alert_arubaaction.c: * src/output-plugins/spo_alert_fast.c: * src/output-plugins/spo_alert_full.c: * src/output-plugins/spo_alert_prelude.c: * src/output-plugins/spo_alert_sf_socket.c: * src/output-plugins/spo_alert_syslog.c: * src/output-plugins/spo_alert_unixsock.c: * src/output-plugins/spo_csv.c: * src/output-plugins/spo_database.c: * src/output-plugins/spo_log_ascii.c: * src/output-plugins/spo_log_tcpdump.c: * src/output-plugins/spo_unified.c: * src/output-plugins/spo_unified2.c: * src/parser/IpAddrSet.c: * src/parser/IpAddrSet.h: * src/parser.c: * src/parser.h: * src/plugbase.c: * src/preprocessors/flow/portscan/flowps_snort.c: * src/preprocessors/HttpInspect/include/hi_include.h: * src/preprocessors/HttpInspect/include/hi_si.h: * src/preprocessors/HttpInspect/include/hi_ui_config.h: * src/preprocessors/HttpInspect/include/hi_ui_server_lookup.h: * src/preprocessors/HttpInspect/session_inspection/hi_si.c: * src/preprocessors/HttpInspect/user_interface/hi_ui_config.c: * src/preprocessors/HttpInspect/user_interface/hi_ui_server_lookup.c: * src/preprocessors/portscan.c: * src/preprocessors/portscan.h: * src/preprocessors/snort_httpinspect.c: * src/preprocessors/snort_stream4_session.c: * src/preprocessors/snort_stream4_udp.c: * src/preprocessors/spp_frag3.c: * src/preprocessors/spp_httpinspect.c: * src/preprocessors/spp_sfportscan.c: * src/preprocessors/spp_stream4.c: * src/preprocessors/spp_stream5.c: * src/preprocessors/Stream5/snort_stream5_icmp.c: * src/preprocessors/Stream5/snort_stream5_icmp.h: * src/preprocessors/Stream5/snort_stream5_session.c: * src/preprocessors/Stream5/snort_stream5_session.h: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/preprocessors/Stream5/snort_stream5_tcp.h: * src/preprocessors/Stream5/snort_stream5_udp.c: * src/preprocessors/Stream5/snort_stream5_udp.h: * src/preprocessors/Stream5/stream5_common.h: * src/preprocessors/stream_api.h: * src/preprocessors/stream.h: * src/preprocessors/stream_ignore.c: * src/preprocessors/stream_ignore.h: * src/rules.h: * src/sfthreshold.c: * src/sfthreshold.h: * src/sfutil/ipobj.c: * src/sfutil/Makefile.am: * src/sfutil/sf_ip.c (added): * src/sfutil/sf_ip.h (added): * src/sfutil/sf_iph.c (added): * src/sfutil/sf_iph.h (added): * src/sfutil/sf_ipvar.c (added): * src/sfutil/sf_ipvar.h (added): * src/sfutil/sfthd.c: * src/sfutil/sfthd.h: * src/sfutil/sf_vartable.c (added): * src/sfutil/sf_vartable.h (added): * src/snort.c: * src/snort.h: * src/tag.c: * src/util.c: * src/win32/WIN32-Prj/build_all.dsp: * src/win32/WIN32-Prj/sf_engine.dsp: * src/win32/WIN32-Prj/snort.dsp: * src/win32/WIN32-Prj/snort.dsw: * src/win32/WIN32-Prj/snort_installer.nsi: * doc/README.ipv6: Added 1st phase of support for IPv6. Added support for ip variables and improved IP address list handling. See README.ipv6 for specifics on what portions of Snort fully support IPv6. Certain preprocessors are not supported -- and cannot be turned on with an IPv6 enabled snort. * src/output-plugins/spo_unified.c: Added configuration option to not append timestamps to unified log/alert files. * src/output-plugins/spo_unified2.c (added): * src/output-plugins/spo_unified2.h (added): * src/plugbase.c: * doc/snort_manual.tex: * doc/snort_manual.pdf: Added unified2 logging/output format. * src/cpuclock.h (added): * src/detect.c: * src/fpdetect.c: * src/fpdetect.h: * src/Makefile.am: * src/parser.c: * src/ppm.c (added): * src/ppm.h (added): * src/profiler.h: * src/rules.h: * src/snort.c: Added support for packet performance monitoring. Allows Snort to be configured to only spend a certain time period on a given packet and/or rule and automatically suspend performance-intensive rules. See README.ppm for details. * src/bounds.h: * src/byte_extract.c: * src/byte_extract.h: * src/debug.c: * src/debug.h: * src/decode.c: * src/decode.h: * src/detection-plugins/sp_asn1.c: * src/detection-plugins/sp_asn1_detect.c: * src/detection-plugins/sp_asn1_detect.h: * src/detection-plugins/sp_byte_check.c: * src/detection-plugins/sp_byte_jump.c: * src/detection-plugins/sp_clientserver.c: * src/detection-plugins/sp_flowbits.c: * src/detection-plugins/sp_isdataat.c: * src/detection-plugins/sp_pattern_match.c: * src/detection-plugins/sp_pattern_match.h: * src/detection-plugins/sp_pcre.c: * src/detection-plugins/sp_react.c: * src/detection-plugins/sp_respond.c: * src/detection-plugins/sp_respond2.c: * src/detection-plugins/sp_session.c: * src/dynamic-plugins/sf_dynamic_engine.h: * src/dynamic-plugins/sf_dynamic_preprocessor.h: * src/dynamic-plugins/sf_engine/bmh.c: * src/dynamic-plugins/sf_engine/bmh.h: * src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c: * src/dynamic-plugins/sf_engine/sf_snort_packet.h: * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.h: * src/dynamic-plugins/sf_engine/sf_snort_plugin_byte.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_content.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_loop.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_pcre.c: * src/dynamic-plugins/sf_preproc_example/sf_dynamic_preproc_lib.c: * src/dynamic-plugins/sp_dynamic.c: * src/dynamic-plugins/sp_dynamic.h: * src/dynamic-plugins/sp_preprocopt.c: * src/dynamic-preprocessors/dcerpc/dcerpc.c: * src/dynamic-preprocessors/dcerpc/dcerpc.h: * src/dynamic-preprocessors/dcerpc/dcerpc_util.c: * src/dynamic-preprocessors/dcerpc/dcerpc_util.h: * src/dynamic-preprocessors/dcerpc/smb_andx_decode.c: * src/dynamic-preprocessors/dcerpc/snort_dcerpc.c: * src/dynamic-preprocessors/dcerpc/spp_dcerpc.c: * src/dynamic-preprocessors/dns/spp_dns.c: * src/dynamic-preprocessors/ftptelnet/ftp_client.h: * src/dynamic-preprocessors/ftptelnet/ftp_cmd_lookup.c: * src/dynamic-preprocessors/ftptelnet/ftp_cmd_lookup.h: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_config.h: * src/dynamic-preprocessors/ftptelnet/pp_ftp.c: * src/dynamic-preprocessors/ftptelnet/pp_telnet.c: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.h: * src/dynamic-preprocessors/ftptelnet/spp_ftptelnet.c: * src/dynamic-preprocessors/ssh/spp_ssh.c: * src/log.c: * src/log.h: * src/mstring.c: * src/mstring.h: * src/preprocessors/HttpInspect/anomaly_detection/hi_ad.c: * src/preprocessors/HttpInspect/client/hi_client.c: * src/preprocessors/HttpInspect/client/hi_client_norm.c: * src/preprocessors/HttpInspect/include/hi_ad.h: * src/preprocessors/HttpInspect/include/hi_client.h: * src/preprocessors/HttpInspect/include/hi_include.h: * src/preprocessors/HttpInspect/include/hi_mi.h: * src/preprocessors/HttpInspect/include/hi_norm.h: * src/preprocessors/HttpInspect/include/hi_server.h: * src/preprocessors/HttpInspect/include/hi_util.h: * src/preprocessors/HttpInspect/mode_inspection/hi_mi.c: * src/preprocessors/HttpInspect/normalization/hi_norm.c: * src/preprocessors/HttpInspect/server/hi_server.c: * src/preprocessors/perf.c: * src/preprocessors/perf-flow.c: * src/preprocessors/perf-flow.h: * src/preprocessors/perf.h: * src/preprocessors/portscan.c: * src/preprocessors/spp_arpspoof.c: * src/preprocessors/spp_bo.c: * src/preprocessors/spp_flow.c: * src/preprocessors/spp_frag3.c: * src/preprocessors/spp_perfmonitor.c: * src/preprocessors/spp_rpc_decode.c: * src/preprocessors/spp_sfportscan.c: * src/preprocessors/spp_stream4.c: * src/preprocessors/spp_stream5.c: * src/preprocessors/Stream5/snort_stream5_icmp.c: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/preprocessors/Stream5/snort_stream5_udp.c: * src/preprocessors/str_search.c: * src/preprocessors/str_search.h: * src/sfutil/asn1.c: * src/sfutil/asn1.h: * src/sfutil/bitop_funcs.h: * src/sfutil/mpse.c: * src/sfutil/mpse.h: * src/snort.c: Changed packet payload pointers to use const qualifier to eliminate inadvertant writes to the packet buffer. * src/preprocessors/HttpInspect/include/hi_util_kmap.h: * src/preprocessors/HttpInspect/include/hi_util_xmalloc.h: * src/preprocessors/HttpInspect/util/hi_util_kmap.c: * src/preprocessors/spp_httpinspect.c: * src/dynamic-preprocessors/ftptelnet/hi_util_kmap.h: * src/dynamic-preprocessors/ftptelnet/hi_util_xmalloc.h: * src/dynamic-preprocessors/ftptelnet/hi_util_kmap.c: Cleanup memory at Snort exit from session & client configurations. * src/debug.h: * src/preprocids.h: * src/generators.h: Added defines for SKYPE. * src/dynamic-plugins/sf_engine/sf_snort_plugin_rc4.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_content.c: Fixed a few typos in comments. Thanks to rmkml for pointing them out. * doc/snort_manual.tex: * doc/snort_manual.pdf: Cleaned up a few typos in various sections. Thanks to rmkml, Joel Ebrahimi for pointing out the misspellings & errors. * src/decode.h: * src/detect.c: * src/fpcreate.c: * src/fpcreate.h: * src/fpdetect.c: * src/fpdetect.h: * src/parser.c: * src/preprocessors/perf-base.c: * src/preprocessors/perf-base.h: * src/preprocessors/spp_frag3.c: * src/preprocessors/spp_frag3.h: * src/preprocessors/spp_stream4.c: * src/preprocessors/spp_stream5.c: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/preprocessors/Stream5/snort_stream5_tcp.h: * src/preprocessors/Stream5/snort_stream5_udp.c: * src/preprocessors/Stream5/snort_stream5_udp.h: * src/preprocessors/Stream5/stream5_common.c: * src/preprocessors/Stream5/stream5_common.h: * src/preprocessors/stream_api.h: * src/rules.h: * src/sfutil/Makefile.am: * src/sfutil/sfrt.c (added): * src/sfutil/sfrt.h (added): * src/sfutil/sfrt_dir.c (added): * src/sfutil/sfrt_dir.h (added): * src/sfutil/sfrt_trie.h (added): * src/signature.c: * src/signature.h: * src/snort.c: * src/snort.h: * src/target-based/Makefile.am (added): * src/target-based/sf_attribute_table_parser.l (added): * src/target-based/sf_attribute_table.y (added): * src/target-based/sftarget_hostentry.c (added): * src/target-based/sftarget_hostentry.h (added): * src/target-based/sftarget_protocol_reference.c (added): * src/target-based/sftarget_protocol_reference.h (added): * src/target-based/sftarget_reader.c (added): * src/target-based/sftarget_reader.h (added): * src/util.c: Added experimental support for Target-Based processing for Stream reassembly, IP Frag reassembly, and rule processing. Enable via --enable-targetbased option to configure. A thread is created to reload the attribute table upon receipt of a signal 30. * src/detect.c: * src/detect.h: * src/detection-plugins/sp_clientserver.c: * src/detection-plugins/sp_clientserver.h: * src/fpcreate.c: * src/fpcreate.h: * src/fpdetect.c: * src/fpdetect.h: * src/parser.c: * src/parser.h: * src/pcrm.c: * src/pcrm.h: * src/preprocessors/Stream5/snort_stream5_udp.c: * src/rules.h: * src/sfutil/sfportobject.c (added): * src/sfutil/sfportobject.h (added): * src/sfutil/sfrim.c (added): * src/sfutil/sfrim.h (added): * src/signature.c: * src/signature.h: * src/snort.c: * src/util.c: Added Port Lists & Port Range functionality and added port variable handling. * preproc_rules/preprocessor.rules: * preproc_rules/decoder.rules: * preproc_rules/Makefile.am: * configure.in: * etc/snort.conf: * src/detection-plugins/sp_asn1.c: * src/detection-plugins/sp_byte_check.c: * src/detection-plugins/sp_byte_jump.c: * src/detection-plugins/sp_dsize_check.c: * src/detection-plugins/sp_flowbits.c: * src/detection-plugins/sp_icmp_code_check.c: * src/detection-plugins/sp_icmp_id_check.c: * src/detection-plugins/sp_icmp_seq_check.c: * src/detection-plugins/sp_icmp_type_check.c: * src/detection-plugins/sp_ip_fragbits.c: * src/detection-plugins/sp_ip_id_check.c: * src/detection-plugins/sp_ip_optioncheck.c: * src/detection-plugins/sp_ip_proto.c: * src/detection-plugins/sp_ip_same_check.c: * src/detection-plugins/sp_ip_tos_check.c: * src/detection-plugins/sp_isdataat.c: * src/detection-plugins/sp_pattern_match.c: * src/detection-plugins/sp_pcre.c: * src/detection-plugins/sp_react.c: * src/detection-plugins/sp_respond.c: * src/detection-plugins/sp_respond2.c: * src/detection-plugins/sp_rpc_check.c: * src/detection-plugins/sp_session.c: * src/detection-plugins/sp_tcp_ack_check.c: * src/detection-plugins/sp_tcp_flag_check.c: * src/detection-plugins/sp_tcp_seq_check.c: * src/detection-plugins/sp_tcp_win_check.c: * src/detection-plugins/sp_ttl_check.c: * src/detection-plugins/sp_urilen_check.c: * src/dynamic-plugins/sp_dynamic.c: * src/event_queue.c: * src/event_wrapper.c: * src/event_wrapper.h: * src/parser.c: * src/plugbase.c: * src/plugbase.h: Added support to provide action control (alert, drop, pass, etc) over preprocessor and decoder generated events, as well as references and classifications via a rule. These rules do not include IP addresses as the individual preprocessor/decoder configuration dictates the traffic to which an event applies. In conjunction with this, certain post-processing rule options (tag, logto, etc) may be added to those rules, while other options that relate to data inspection (content, byte_test, etc) may not. Enable via --enable-decoder-preprocessor-rules option to configure. * src/dynamic-plugins/sf_dynamic_plugins.c: Search for other shared library extensions on OpenBSD. Thanks to Nikns Siankin for the request. * src/dynamic-plugins/sf_engine/Makefile.am: * src/dynamic-preprocessors/dcerpc/Makefile.am: * src/dynamic-preprocessors/dns/Makefile.am: * src/dynamic-preprocessors/ftptelnet/Makefile.am: * src/dynamic-preprocessors/smtp/Makefile.am: * src/dynamic-preprocessors/ssh/Makefile.am: Fixes to correct shared library extension on MAC OS. * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/preprocessors/Stream5/snort_stream5_tcp.h: * src/preprocessors/Stream5/stream5_common.h: * src/generators.h: * doc/snort_manual.tex: * doc/snort_manual.pdf: Added basic TCP session hijacking detection. Detection based on MAC address used during TCP 3-way handshake and MAC address in subsequent packets. * src/preprocessors/Stream5/snort_stream5_tcp.c: * doc/README.stream5: * doc/snort_manual.tex: * doc/snort_manual.pdf: Added stream_size rule option (only supported by Stream5). * src/dynamic-preprocessors/ftptelnet/pp_ftp.c: * src/generators.h: Improved detection for encrypted ftp sessions, reducing false positives. Added detection of subnegotiation begin commands without matching subnegotiation end (evasion attempt). * src/dynamic-preprocessors/smtp/smtp_config.c: * src/dynamic-preprocessors/smtp/smtp_config.h: * src/dynamic-preprocessors/smtp/smtp_log.c: * src/dynamic-preprocessors/smtp/smtp_log.h: * src/dynamic-preprocessors/smtp/smtp_normalize.c: * src/dynamic-preprocessors/smtp/smtp_normalize.h: * src/dynamic-preprocessors/smtp/smtp_util.c: * src/dynamic-preprocessors/smtp/smtp_util.h: * src/dynamic-preprocessors/smtp/smtp_xlink2state.c: * src/dynamic-preprocessors/smtp/smtp_xlink2state.h: * src/dynamic-preprocessors/smtp/snort_smtp.c: * src/dynamic-preprocessors/smtp/snort_smtp.h: * src/dynamic-preprocessors/smtp/spp_smtp.c: * src/dynamic-preprocessors/smtp/spp_smtp.h: * doc/README.SMTP: * etc/snort.conf: * src/generators.h: Rework much of preprocessor to improve searches, additional vulnerability checks. Updates include changes to handle case insensitive searches. Alert on header name length (Exim exploit) and check for valid mime headers. Add port 587 (see RFC 2476) to default ports. Improved normalization to separate commands and data. Updates to config parsing and console startup output. * src/parser.c: Handle duplicate rules by using the newer revision or the earlier appearing rule (if same revision). * src/sf_types.h (added): * src/preprocessors/flow/flow_cache.c: * src/preprocessors/flow/flow_cache.h: * src/preprocessors/flow/portscan/flowps.c: * src/preprocessors/flow/portscan/flowps_snort.c: * src/preprocessors/flow/portscan/scoreboard.c: * src/preprocessors/flow/portscan/server_stats.c: * src/preprocessors/flow/portscan/unique_tracker.c: * src/preprocessors/perf-base.c: * src/preprocessors/perf.c: * src/preprocessors/perf-event.c: * src/preprocessors/perf-event.h: * src/profiler.c: * src/sfutil/util_math.c: * src/sfutil/util_math.h: * src/snort.h: * src/snprintf.h: * src/util.c: * src/util.h: * src/win32/WIN32-Includes/stdint.h: * src/win32/WIN32-Includes/WinPCAP/time_calls.h: Updated logging to print 64bit values on various platforms in a more portable manner. * configure.in: * src/decode.c: * src/preprocessors/perf-base.c: * src/preprocessors/spp_perfmonitor.c: * src/snort.c: * src/snort.h: * src/util.c: * src/util.h: * src/win32/WIN32-Includes/config.h: Fixed issue with various versions of pcap reporting received & dropped stats differently. Pcap versions 0.9 & higher accumulate stats, whereas earlier versions do not. * src/sfutil/acsmx2.c: * src/sfutil/acsmx2.h: * src/sfutil/acsmx.c: * src/sfutil/acsmx.h: * src/sfutil/bnfa_search.c: * src/sfutil/bnfa_search.h: * src/sfutil/sfghash.c: * src/sfutil/sfhashfcn.c: * src/sfutil/sfhashfcn.h: * src/sfutil/sfprimetable.c (added): * src/sfutil/sfprimetable.h (added): * src/sfutil/sfksearch.c: * src/sfutil/sfksearch.h: * src/sfutil/sfxhash.c: * src/sfutil/sfxhash.h: Improve performance of pattern match engines to not evaluate a rule with a pattern that has already been seen and the rule already processed. This changes takes into account if that rule fails because of an unset flowbit (which may have been set by another rule). Changed hash table hash functions to use power of two computations instead of prime numbers. * src/util.c: Added PCRE library version information to Snort startup banner. 2007-07-27 Steven Sturges * etc/snort.conf: Turn off flow since Stream5 is now enabled by default. * src/snort.c: Fix printing of threshold counts until after all rules are read. This issue did not affect thresholding, only display of thresholding. Thanks to Jeffrey Denton for reporting the problem. * src/sfutil/ipobj.c: Fix free of invalid pointer when using a negated IP list. This is used by sfportscan preprocessor configuration parsing. Thanks to Anders Ostrem for reporting the problem. * src/preprocessors/Stream5/snort_stream5_session.c: Fixed issue when experimental ICMP tracking is used without using the TCP or UDP session tracking. ICMP was attempting to lookup TCP or UDP sessions from uninitialized session cache. Thanks to Koji Shikata for reporting the problem. * src/preprocessors/Stream5/snort_stream5_tcp.c: Fixed invalid session pointer when rule tries to use flowbits after session ends. Thanks to rmkml for initially reporting the problem. 2007-07-06 Steven Sturges * src/preprocessors/Stream5/snort_stream5_tcp.c: Fixed potential invalid memory access when require 3whs option is used. 2007-06-28 Steven Sturges * src/sfutil/acsmx2.c: * src/sfutil/bnfa_search.c: Revert previous changes as they resulted in some false negatives with mixed case patterns and rules. Will address in a future release. * src/detection-plugins/sp_react.c: Fixed problem with segfault with flexresp. Thanks to Keith Pachulski for reporting the issue. 2007-06-20 Steven Sturges * src/sfutil/acsmx2.c: * src/sfutil/acsmx.h: * src/sfutil/bnfa_search.c: Performance improvement to track the last state of a pattern that match, so if it hits that state again immediately, don't go re-evaluate all of the same rules. * src/decode.c: * src/detect.c: * src/snort.h: * src/util.c: Properly handle UDP checksum if checksum value is 0 in header (do not calculate). Add stat that tracks number of failed checksums. * src/detection-plugins/sp_pcre.c: Add /P flag to PCRE detection to check HTTP inspect's normalized client request body. * src/dynamic-preprocessors/Makefile.am: * src/dynamic-examples/Makefile.am: Fix header file replication. * src/output-plugins/spo_alert_prelude.c: Update to write data at Snort exit. Thanks Yoann Vandoorselaere for the patch. * src/parser.c: Update to max line length. Mark 'stateless' option to be deprecated, use flow:stateless. 2007-06-19 Steven Sturges * src/byte_extract.h: * src/event_queue.h: * src/event_wrapper.h: * src/inline.h: * src/ipv6.c: * src/ipv6.h: * src/packet_time.h: * src/plugin_enum.h: * src/preprocids.h: * src/sfthreshold.h: * src/snort_packet_header.h: * src/detection-plugins/sp_asn1.h: * src/detection-plugins/sp_asn1_detect.h: * src/detection-plugins/sp_flowbits.h: * src/detection-plugins/sp_ip_proto.c: * src/dynamic-examples/Makefile.am: * src/dynamic-examples/dynamic-preprocessor/sf_preproc_info.h: * src/dynamic-examples/dynamic-preprocessor/spp_example.c: * src/dynamic-examples/dynamic-rule/detection_lib_meta.h: * src/dynamic-examples/dynamic-rule/rules.c: * src/dynamic-examples/dynamic-rule/sid109.c: * src/dynamic-examples/dynamic-rule/sid637.c: * src/dynamic-preprocessors/ftptelnet/hi_util_kmap.c: * src/dynamic-preprocessors/ftptelnet/hi_util_kmap.h: * src/dynamic-preprocessors/ftptelnet/hi_util_xmalloc.c: * src/dynamic-preprocessors/ftptelnet/sf_preproc_info.h: * src/dynamic-preprocessors/smtp/sf_preproc_info.h: * src/preprocessors/portscan.c: * src/preprocessors/portscan.h: * src/preprocessors/snort_httpinspect.c: * src/preprocessors/snort_httpinspect.h: * src/preprocessors/snort_stream4_session.h: * src/preprocessors/snort_stream4_udp.h: * src/preprocessors/spp_flow.h: * src/preprocessors/spp_httpinspect.c: * src/preprocessors/spp_httpinspect.h: * src/preprocessors/spp_sfportscan.c: * src/preprocessors/spp_sfportscan.h: * src/preprocessors/spp_stream5.c: * src/preprocessors/str_search.c: * src/preprocessors/str_search.h: * src/preprocessors/stream.h: * src/preprocessors/HttpInspect/anomaly_detection/hi_ad.c: * src/preprocessors/HttpInspect/client/hi_client.c: * src/preprocessors/HttpInspect/client/hi_client_norm.c: * src/preprocessors/HttpInspect/event_output/hi_eo_log.c: * src/preprocessors/HttpInspect/include/hi_ad.h: * src/preprocessors/HttpInspect/include/hi_client.h: * src/preprocessors/HttpInspect/include/hi_client_norm.h: * src/preprocessors/HttpInspect/include/hi_eo.h: * src/preprocessors/HttpInspect/include/hi_eo_events.h: * src/preprocessors/HttpInspect/include/hi_eo_log.h: * src/preprocessors/HttpInspect/include/hi_include.h: * src/preprocessors/HttpInspect/include/hi_mi.h: * src/preprocessors/HttpInspect/include/hi_norm.h: * src/preprocessors/HttpInspect/include/hi_return_codes.h: * src/preprocessors/HttpInspect/include/hi_server.h: * src/preprocessors/HttpInspect/include/hi_si.h: * src/preprocessors/HttpInspect/include/hi_ui_config.h: * src/preprocessors/HttpInspect/include/hi_ui_iis_unicode_map.h: * src/preprocessors/HttpInspect/include/hi_ui_server_lookup.h: * src/preprocessors/HttpInspect/include/hi_util.h: * src/preprocessors/HttpInspect/include/hi_util_hbm.h: * src/preprocessors/HttpInspect/include/hi_util_kmap.h: * src/preprocessors/HttpInspect/include/hi_util_xmalloc.h: * src/preprocessors/HttpInspect/mode_inspection/hi_mi.c: * src/preprocessors/HttpInspect/normalization/hi_norm.c: * src/preprocessors/HttpInspect/server/hi_server.c: * src/preprocessors/HttpInspect/session_inspection/hi_si.c: * src/preprocessors/HttpInspect/user_interface/hi_ui_config.c: * src/preprocessors/HttpInspect/user_interface/hi_ui_iis_unicode_map.c: * src/preprocessors/HttpInspect/user_interface/hi_ui_server_lookup.c: * src/preprocessors/HttpInspect/utils/hi_util_hbm.c: * src/preprocessors/HttpInspect/utils/hi_util_kmap.c: * src/preprocessors/HttpInspect/utils/hi_util_xmalloc.c: * src/preprocessors/Stream5/snort_stream5_icmp.c: * src/preprocessors/Stream5/snort_stream5_icmp.h: * src/preprocessors/Stream5/snort_stream5_session.h: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/preprocessors/Stream5/snort_stream5_tcp.h: * src/preprocessors/Stream5/snort_stream5_udp.c: * src/preprocessors/Stream5/snort_stream5_udp.h: * src/preprocessors/Stream5/stream5_common.c: * src/preprocessors/Stream5/stream5_common.h: * src/preprocessors/flow/common_defs.h: * src/preprocessors/flow/flow.c: * src/preprocessors/flow/flow.h: * src/preprocessors/flow/flow_cache.c: * src/preprocessors/flow/flow_cache.h: * src/preprocessors/flow/flow_callback.c: * src/preprocessors/flow/flow_callback.h: * src/preprocessors/flow/flow_class.c: * src/preprocessors/flow/flow_class.h: * src/preprocessors/flow/flow_config.h: * src/preprocessors/flow/flow_error.h: * src/preprocessors/flow/flow_hash.c: * src/preprocessors/flow/flow_hash.h: * src/preprocessors/flow/flow_print.c: * src/preprocessors/flow/flow_print.h: * src/preprocessors/flow/flow_stat.c: * src/preprocessors/flow/flow_stat.h: * src/preprocessors/flow/int-snort/flow_packet.c: * src/preprocessors/flow/int-snort/flow_packet.h: * src/preprocessors/flow/portscan/flowps.c: * src/preprocessors/flow/portscan/flowps.h: * src/preprocessors/flow/portscan/flowps_snort.c: * src/preprocessors/flow/portscan/flowps_snort.h: * src/preprocessors/flow/portscan/scoreboard.c: * src/preprocessors/flow/portscan/scoreboard.h: * src/preprocessors/flow/portscan/server_stats.c: * src/preprocessors/flow/portscan/server_stats.h: * src/preprocessors/flow/portscan/unique_tracker.c: * src/preprocessors/flow/portscan/unique_tracker.h: * src/sfutil/acsmx2.h: * src/sfutil/asn1.c: * src/sfutil/asn1.h: * src/sfutil/ipobj.c: * src/sfutil/ipobj.h: * src/sfutil/sfeventq.c: * src/sfutil/sfeventq.h: * src/sfutil/sfghash.c: * src/sfutil/sfghash.h: * src/sfutil/sfhashfcn.c: * src/sfutil/sfhashfcn.h: * src/sfutil/sflsq.c: * src/sfutil/sflsq.h: * src/sfutil/sfmemcap.c: * src/sfutil/sfmemcap.h: * src/sfutil/sfsnprintfappend.c: * src/sfutil/sfsnprintfappend.h: * src/sfutil/sfthd.c: * src/sfutil/sfthd.h: * src/sfutil/sfxhash.c: * src/sfutil/sfxhash.h: * src/sfutil/util_math.c: * src/sfutil/util_math.h: * src/sfutil/util_net.c: * src/sfutil/util_net.h: * src/sfutil/util_str.c: * src/sfutil/util_str.h: * src/win32/WIN32-Code/inet_aton.c: * src/win32/WIN32-Code/name.h: Update copyright dates & info and add GPL header. 2007-06-01 Steven Sturges * src/util.c: Update to hourly timestats from Bill Parker. 2007-06-01 Steven Sturges * src/preprocessors/spp_frag3.c: Fix configuration parsing to validate parameters for memcap, max_frags, prealloc_frags. Thanks to Joel Ebrahimi for pointing out the issue. 2007-05-30 Steven Sturges * src/dynamic-preprocessors/smtp/smtp_util.c: * src/dynamic-preprocessors/smtp/smtp_util.h: * src/dynamic-preprocessors/smtp/smtp_xlink2state.c: * src/dynamic-preprocessors/smtp/snort_smtp.c: Cleanup xlink2state processing and remove potential read beyond end of packet. * src/preprocessors/stream_api.h: * src/preprocessors/Stream5/snort_stream5_tcp.c: Update handling of timed out session cleanup when the 'same' (IPs/ports) session is picked up midstream. 2007-05-23 Steven Sturges * doc/snort_manual.tex: * doc/snort_manual.pdf: * doc/README.stream5: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/preprocessors/Stream5/stream5_common.h: Update Stream5 to use 65535 << 14 as max allowable value for the 'max_window' option. * src/decode.c: * src/detect.c: * src/snort.c: * src/snort.h: When checking for IPv6 BSD frag vulnerability, use a pseudo packet with false IPv4 headers for logging purposes rather than writing the IPv4 header within the original packet buffer. * src/preprocessors/spp_frag3.c: Update to not change original packet buffer when rebuilding fragments with IP options. * src/preprocessors/spp_rpc_decode.c: * src/preprocessors/spp_rpc_decode.h: Update to use the altdecode buffer for normalization. 2007-05-22 Steven Sturges * doc/snort_manual.tex: * doc/snort_manual.pdf: Update for 2.7.0. * configure.in: * src/debug.c: * src/debug.h: * src/dynamic-plugins/sf_dynamic_plugins.c: * src/dynamic-plugins/sf_dynamic_preprocessor.h: * src/dynamic-preprocessors/dcerpc/dcerpc.c: * src/dynamic-preprocessors/dcerpc/smb_andx_decode.c: * src/win32/WIN32-Includes/config.h: Check for wchar.h and don't try to use it if not present. Fixes builds on OpenBSD 3.5 and others. * src/dynamic-plugins/sf_dynamic_detection.h: * src/dynamic-plugins/sf_dynamic_plugins.c: * src/dynamic-plugins/sp_preprocopt.c: * src/dynamic-plugins/sp_preprocopt.h: * src/dynamic-preprocessors/ftptelnet/ftp_bounce_lookup.c: * src/dynamic-preprocessors/ftptelnet/ftp_cmd_lookup.c: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_client_lookup.c: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_server_lookup.c: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_config.c: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_config.h: * src/dynamic-preprocessors/ftptelnet/ppftp.c: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.h: * src/dynamic-preprocessors/ftptelnet/spp_ftptelnet.c: * src/dynamic-preprocessors/smtp/smtp_util.c: * src/dynamic-preprocessors/smtp/smtp_util.h: * src/dynamic-preprocessors/smtp/snort_smtp.c: * src/event_queue.c: * src/event_queue.h: * src/ipv6.c: * src/ipv6.h: * src/mempool.c: * src/parser.c: * src/preprocessors/spp_frag3.c: * src/preprocessors/spp_httpinspect.c: * src/preprocessors/Stream5/snort_stream5_icmp.c: * src/preprocessors/Stream5/snort_stream5_session.c: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/preprocessors/Stream5/snort_stream5_udp.c: * src/sfutil/asn1.c: * src/sfutil/asn1.h: * src/sfutil/sfeventq.c: * src/sfutil/sfeventq.h: * src/sfutil/sfksearch.c: * src/sfutil/sfksearch.h: * src/sfutil/sfxhash.c: * src/snort.c: Added code to cleanup memory at Snort exit/restart. * src/output-plugins/spo_log_tcpdump.c: Update to timestamp writing on 64bit platforms. * src/dynamic-preprocessors/smtp/smtp_normalize.c: Update normalization for postfix and sendmail servers that normalize any space except '\n'. * src/preprocessors/str_search.c: * src/sfutil/bnfa_search.c: * src/sfutil/mpse.c: Use BNFA, smaller memory footprint for searches from SMTP. * src/preprocessors/HttpInspect/client/hi_client.c: * src/preprocessors/HttpInspect/client/hi_client_norm.c: * src/preprocessors/HttpInspect/include/hi_eo_log.h: * src/preprocessors/HttpInspect/include/hi_si.h: * src/preprocessors/HttpInspect/normalization/hi_norm.c: Update way in which Body vs URI's are normalized, checked for anomalies and alerted on. * src/preprocessors/snort_stream4_udp.c: Fix use of ignore_any keyword when dealing with portscan and/or rules that have flow/flowbits. * src/preprocessors/Stream5/snort_stream5_tcp.c: Update to timestamp handling and anomaly detection with invalid timestamps on RST packets. * src/snort.c: * src/snort.h: Add --loop option to be used with -r for pcap readback mode. 2007-05-09 Adam Keeton * src/preprocessors/HttpInspect/client/hi_client_norm.c: * src/preprocessors/HttpInspect/include/hi_si.h: * src/preprocessors/HttpInspect/normalization/hi_norm.c: Added code to prevent URI-related alerts from firing when the body is being normalized. 2007-05-08 Adam Keeton * src/preprocessors/HttpInspect/client/hi_client.c: Fixed pointer initialization relating to POST normalization. 2007-04-27 Steven Sturges * src/decode.h: * src/detection-plugins/sp_pattern_match.c: * src/detection-plugins/sp_pattern_match.h: * src/dynamic-plugins/sf_dynamic_common.h: * src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.h: * src/dynamic-plugins/sf_engine/sf_snort_plugin_content.c: * doc/snort_manual.tex: * doc/snort_manual.pdf: Provide new rule keyword modifier for content option that allows a rule to search for a pattern in the body of an HTTP client request. * src/util.c: * src/preprocessors/snort_httpinspect.c: * src/preprocessors/spp_httpinspect.c: * src/preprocessors/HttpInspect/client/hi_client.c: * src/preprocessors/HttpInspect/client/hi_client_norm.c: * src/preprocessors/HttpInspect/include/hi_client.h: * src/preprocessors/HttpInspect/include/hi_include.h: * src/preprocessors/HttpInspect/include/hi_ui_config.h: * src/preprocessors/HttpInspect/include/hi_util_xmalloc.h: * src/preprocessors/HttpInspect/normalization/hi_norm.c: * src/preprocessors/HttpInspect/user_interface/hi_ui_config.c: * src/preprocessors/HttpInspect/user_interface/hi_ui_server_lookup.c: * src/preprocessors/HttpInspect/utils/hi_util_kmap.c: Update to normalize the body of a client request to allow rules to check specifically for parameters of a POST or GET request. Also add stats that are part of the hourly stats that track various HTTP encodings and normalizations that have occured. * src/preprocessors/spp_stream4.c: Fix potential memory leak. * doc/README.ipv6: Updates for clarity. * doc/faq.tex: * configure.in: Add minimal PCRE version. * etc/gen-msg.map: * src/decode.c: * src/generators.h: * src/preprocessors/Stream5/snort_stream5_tcp.c: Handle TCP window scale option that is > 14. Added decoder alert for this and adjust the scale per RFC 1323 in Stream5. * etc/snort.conf: Make Stream5 the default stream engine. * src/decode.c: Add alert for multiple GRE encapsulations. * src/ipv6.c: Additional structure name changes to avoid conflicts on Win32. * src/parser.c: Update the maximum number of entries in an IP List to 1024 (was 128). Added ability to configure Timestats interval, default is 3600 seconds (1 hour) when enabled via --enable-timestats. * src/snort.c: * src/snort.h: * src/util.h: Revised signal handler for Timestats. * src/util.c: Update Timestats to include Wifi, GRE, Frag & TCP Stream info. Thanks to Bill Parker for the update. * src/detection-plugins/sp_icmp_code_check.c: * src/detection-plugins/sp_icmp_type_check.c: Update to parsing of icmp rule options for better grammar enforcement. * src/detection-plugins/sp_respond.c: * src/detection-plugins/sp_respond2.c: Specify TCP window of 0 for RST packets that are sent. * src/dynamic-plugins/sf_dynamic_plugins.c: * src/dynamic-plugins/sf_dynamic_preprocessor.h: * src/dynamic-preprocessors/sf_dynamic_preproc_lib.c: Make Preprocess() function available to dynamic preprocessors. Thanks Vladimir Shcherbakov for the request. * src/dynamic-preprocessors/dcerpc/dcerpc.c: * src/dynamic-preprocessors/dcerpc/dcerpc.h: * src/dynamic-preprocessors/dcerpc/smb_andx_decode.c: * src/dynamic-preprocessors/dcerpc/snort_dcerpc.c: Code cleanup and a minor reorganization. * src/dynamic-preprocessors/smtp/snort_smtp.c: Fix truncated buffer in when compiled in debug mode. * src/preprocessors/perf-base.c: * src/preprocessors/perf-base.h: * src/preprocessors/snort_stream4_session.c: * src/preprocessors/spp_stream4.c: * src/preprocessors/stream_api.h: * src/preprocessors/Stream5/snort_stream5_session.c: * src/preprocessors/Stream5/snort_stream5_tcp.c: Update to track additional stats for TCP session cache and session states. * src/preprocessors/spp_perfmonitor.c: Fix behaviour of 'accumlate' option. * src/preprocessors/spp_stream4.c: * src/preprocessors/Stream5/snort_stream5_tcp.c: Update for 64bit platforms. * src/preprocessors/spp_stream5.c: * src/preprocessors/Stream5/snort_stream5_session.c: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/preprocessors/Stream5/snort_stream5_udp.c: * src/preprocessors/Stream5/snort_stream5_icmp.c: * doc/README.stream5: Updates to config validation. Code cleanup for readability. Update TCP Window Scale use and sequence validation to be RFC 1323 compliant. Document min/max values for parameters, etc. 2007-04-13 Steven Sturges * src/decode.h: * src/decode.c: * src/ipv6.c: Changed structure declaration and usage to not conflict with OpenBSD. 2007-03-28 Steven Sturges * rpm/snort.spec: Remove smp_flags from spec file to not parallelize building. * doc/README.ipv6 * etc/gen-msg.map: * src/Makefile.am: * src/decode.c: * src/decode.h: * src/generators.h: * src/ipv6.c (added): * src/ipv6.h (added): * src/parser.c: * src/snort.c: * src/snort.h: * src/win32/WIN32-Prj/snort.dsp: Added ability for Snort to track fragmented ICMPv6 to check for the remote BSD exploit (Bugtraq ID 22901, CVE-2007-1365). * src/win32/WIN32-Code/syslog.c: * src/win32/WIN32-Code/win32_service.c: * src/plugbase.c: * src/preprocessors/perf-base.c: * src/preprocessors/stream_ignore.c: * src/profiler.c: * src/snort.c: Cleanup to use safe snprintf and strncpy functions, check return values of SafeMemcpy, use calloc or SnortAlloc, and other static size buffer bounds checks. * src/parser.c: Fix issue with printing rule information twice. * src/profiler.h: * src/preprocessors/spp_flow.c: Fix miscalculation of processor time attributable to flow. * src/dynamic-plugins/sp_dynamic.c: * src/dynamic-plugins/sp_dynamic.h: * src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c: Added hasXXX functions for Content, ByteTest, and PCRE. * src/dynamic-preprocessors/dcerpc/dcerpc.c: * src/dynamic-preprocessors/dcerpc/dcerpc.h: * src/dynamic-preprocessors/dcerpc/dcerpc_config.c: * src/dynamic-preprocessors/dcerpc/dcerpc_util.c: * src/dynamic-preprocessors/dcerpc/dcerpc_util.h: * src/dynamic-preprocessors/dcerpc/sf_preproc_info.h: * src/dynamic-preprocessors/dcerpc/smb_andx_decode.c: * src/dynamic-preprocessors/dcerpc/smb_andx_decode.h: * src/dynamic-preprocessors/dcerpc/smb_andx_structs.h: * src/dynamic-preprocessors/dcerpc/smb_structs.h: * src/dynamic-preprocessors/dcerpc/snort_dcerpc.c: * src/dynamic-preprocessors/dcerpc/snort_dcerpc.h: * src/dynamic-preprocessors/dcerpc/spp_dcerpc.c: Code cleanup to perform bounds checking, validation of memcpy success, remove potential memory leak. Code readability improvements and update DCE endianness checks. * src/dynamic-preprocessors/dns/sf_preproc_info.h: * src/dynamic-preprocessors/dns/spp_dns.c: Code cleanup for initialization of memory allocations and add early termination when at end of packet payload. * src/dynamic-preprocessors/ftptelnet/ftpp_si.c: * src/dynamic-preprocessors/ftptelnet/ftpp_si.h: * src/dynamic-preprocessors/ftptelnet/hi_util_kmap.c: * src/dynamic-preprocessors/ftptelnet/hi_util_xmalloc.c: * src/dynamic-preprocessors/ftptelnet/pp_ftp.c: * src/dynamic-preprocessors/ftptelnet/sf_preproc_info.h: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: Code cleanup for initialization of memory allocations and remove dead/unused code for directory and user state tracking. * src/dynamic-preprocessors/smtp/sf_preproc_info.h: * src/dynamic-preprocessors/smtp/smtp_config.c: * src/dynamic-preprocessors/smtp/smtp_log.c: * src/dynamic-preprocessors/smtp/smtp_normalize.c: * src/dynamic-preprocessors/smtp/smtp_normalize.h: * src/dynamic-preprocessors/smtp/snort_smtp.c: Code cleanup for initialization of memory allocations, fix normalization to prevent read beyond packet payload. Generate SMTP command overflow even if packet payload doesn't contain complete command (missing LF). * src/preprocessors/spp_frag3.c: Further update to handle iptables (and other datalink layers) that do not have ethernet headers to be included in rebuilt fragment. * src/preprocessors/Stream5/snort_stream5_icmp.c: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/preprocessors/Stream5/snort_stream5_udp.c: * src/preprocessors/Stream5/stream5_common.c: * src/preprocessors/Stream5/stream5_common.h: * doc/README.stream5: * doc/snort_manual.tex: * doc/snort_manual.pdf: Add verification of options for ICMP, TCP, UDP configurations are within reasonable limits. Reorganize reassembly flush initialization. Print list of UDP rules that are effectively ignored with ignore_any_rules option. Update session timeout handling. * src/sfutil/sfxhash.c: * src/sfutil/sfxhash.h: * src/preprocessors/snort_stream4_session.c: * src/preprocessors/Stream5/snort_stream5_session.c: Allow use of limit on number of nodes in hash table instead of relying on memcap for limiting sessions. * src/bounds.h: * src/debug.c: * src/detect.c: * src/fpdetect.c: * src/log.c: * src/parser.c: * src/pcrm.c: * src/plugbase.c: * src/profiler.c: * src/sfthreshold.c: * src/snort.c: * src/ubi_BinTree.c: * src/util.c: * src/util.h: * src/detection-plugins/sp_pattern_match.c: * src/detection-plugins/sp_react.c: * src/detection-plugins/sp_session.c: * src/dynamic-plugins/sf_dynamic_engine.h: * src/dynamic-plugins/sf_dynamic_plugins.c: * src/dynamic-plugins/sf_dynamic_preprocessor.h: * src/dynamic-preprocessors/ssh/spp_ssh.c: * src/output-plugins/spo_alert_prelude.c: * src/output-plugins/spo_alert_syslog.c: * src/output-plugins/spo_alert_unixsock.c: * src/output-plugins/spo_database.c: * src/output-plugins/spo_log_ascii.c: * src/output-plugins/spo_log_tcpdump.c: * src/output-plugins/spo_unified.c: * src/parser/IpAddrSet.c: * src/preprocessors/perf-base.c: * src/preprocessors/perf.c: * src/preprocessors/snort_httpinspect.c: * src/preprocessors/HttpInspect/client/hi_client.c: * src/preprocessors/HttpInspect/event_output/hi_eo_log.c: * src/preprocessors/HttpInspect/utils/hi_util_kmap.c: * src/preprocessors/snort_stream4_session.c: * src/preprocessors/snort_stream4_udp.c: * src/preprocessors/spp_bo.c: * src/preprocessors/spp_frag3.c: * src/preprocessors/spp_perfmonitor.c: * src/preprocessors/spp_sfportscan.c: * src/preprocessors/spp_stream4.c: * src/preprocessors/spp_stream5.c: * src/preprocessors/stream_api.h: * src/preprocessors/stream_ignore.c: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/preprocessors/Stream5/snort_stream5_udp.c: * src/preprocessors/flow/flow_print.c: * src/preprocessors/flow/flow_print.h: * src/sfutil/acsmx2.c: * src/sfutil/ipobj.c: * src/sfutil/sfghash.c: * src/sfutil/sfmemcap.c: * src/sfutil/sfxhash.c: Cleanup to use safe snprintf and strncpy functions, check return values of SafeMemcpy, use calloc or SnortAlloc, and other static size buffer bounds checks. Add handling for FatalError not returning for static code analysis tools. * src/sfutil/sfthd.c: Fix memory leak in global config. Thanks Boris Lytochkin for pointing this out. 2007-02-20 Steven Sturges * src/util.c: Update copyright date to include 2007. 2007-02-17 Steven Sturges * src/parser.c: Code cleanup, remove tab characters going to syslog. * src/detection-plugins/sp_clientserver.c: Handle flow keyword with Stream5 UDP sessions. * src/dynamic-preprocessors/Makefile.am: * src/dynamic-preprocessors/dcerpc/dcerpc.c: * src/dynamic-preprocessors/dcerpc/smb_andx_decode.c: Add bounds checking to ReassembleSMBWriteX; use Safememcpy for calculated length buffer copies. 2007-02-09 Steven Sturges * configure.in: Added support for libpcap that depends on libpfring. Thanks to Jason Wallace for the patch. Also updated description as to why libpcap check might fail and what files might be missing, thanks to James Affeld for that suggestion. * src/preprocessors/spp_stream5.c: * src/preprocessors/Stream5/snort_stream5_tcp.c: Update configuration parsing and validation checks and fix issue with static flushpoints not really being static. * src/output-plugins/spo_database.c: Code cleanup to check that a query was not truncated when using snprintf and guarantee NULL terminated string. 2007-02-07 Steven Sturges * src/decode.c: * src/detection-plugins/sp_ip_same_check.c: * src/detection-plugins/sp_pattern_match.c: * src/detection-plugins/sp_react.c: * src/dynamic-plugins/sf_dynamic_plugins.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_loop.c: * src/dynamic-preprocessors/dcerpc/snort_dcerpc.c: * src/dynamic-preprocessors/dns/spp_dns.c: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: * src/dynamic-preprocessors/smtp/smtp_config.c: * src/dynamic-preprocessors/smtp/smtp_util.c: * src/dynamic-preprocessors/ssh/spp_ssh.c: * src/parser.c: * src/plugbase.c: * src/preprocessors/flow/flow_print.c: * src/preprocessors/flow/portscan/flowps_snort.c: * src/preprocessors/flow/portscan/scoreboard.c: * src/preprocessors/HttpInspect/event_output/hi_eo_log.c: * src/preprocessors/snort_httpinspect.c: * src/preprocessors/spp_bo.c: * src/preprocessors/spp_stream4.c: * src/snort.c: * src/tag.c: * src/win32/WIN32-Code/misc.c: Code & warning cleanup. * src/parser.c: Add file and line number to an error message. Thanks to rmkml for pointing out the omission. 2007-02-05 Steven Sturges * src/dynamic-plugins/sf_dynamic_engine.h: * src/dynamic-plugins/sf_dynamic_plugins.c: * src/dynamic-plugins/sf_dynamic_preprocessor.h: * src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.c: * src/dynamic-plugins/sp_preprocopt.c: * src/dynamic-preprocessors/ftptelnet/ftp_bounce_lookup.c: * src/dynamic-preprocessors/ftptelnet/ftp_cmd_lookup.c: * src/dynamic-preprocessors/ftptelnet/ftpp_si.c: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_client_lookup.c: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_config.c: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_server_lookup.c: * src/dynamic-preprocessors/ftptelnet/pp_ftp.c: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: * src/dynamic-preprocessors/ftptelnet/spp_ftptelnet.c: * src/dynamic-preprocessors/smtp/smtp_config.c: * src/fpdetect.c: * src/output-plugins/spo_csv.c: * src/output-plugins/spo_database.c: * src/output-plugins/spo_log_ascii.c: * src/parser/IpAddrSet.c: * src/parser.c: * src/plugbase.c: * src/preprocessors/HttpInspect/client/hi_client.c: * src/preprocessors/HttpInspect/client/hi_client_norm.c: * src/preprocessors/HttpInspect/event_output/hi_eo_log.c: * src/preprocessors/HttpInspect/mode_inspection/hi_mi.c: * src/preprocessors/HttpInspect/normalization/hi_norm.c: * src/preprocessors/HttpInspect/server/hi_server.c: * src/preprocessors/HttpInspect/session_inspection/hi_si.c: * src/preprocessors/HttpInspect/user_interface/hi_ui_config.c: * src/preprocessors/HttpInspect/user_interface/hi_ui_iis_unicode_map.c: * src/preprocessors/HttpInspect/user_interface/hi_ui_server_lookup.c: * src/preprocessors/snort_httpinspect.c: * src/preprocessors/spp_bo.c: * src/preprocessors/spp_httpinspect.c: * src/preprocessors/spp_sfportscan.c: * src/preprocessors/spp_stream4.c: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/sfutil/acsmx2.c: * src/sfutil/ipobj.c: * src/signature.c: * src/snort.c: * src/tag.c: * src/ubi_BinTree.c: * src/util.h: More code cleanup, eliminate warnings on Win32 platform. 2007-02-02 Steven Sturges * doc/README.stream5: Cleanup spelling, etc. * src/bounds.h: * src/preprocessors/spp_frag3.c: Fix issue when Snort is inline using iptables, without either the ipconntrack or NAT modules. This should not occur using the recommended snort inline configuration, since the OS is supposed to handle IP fragment reassembly. The Ethernet header doesn't exist in the packet received by Snort, causing snort to dereference an invalid pointer. Thanks to Panda Software and Joel Ebrahimi for reporting the issue." * src/parser.c: Fix benign warning when using -E on Win32. * src/plugbase.c: * src/preprocessors/spp_telnet_negotiation.c (removed): * src/preprocessors/spp_telnet_negotiation.h (removed): * src/preprocessors/Makefile.am: * src/win32/WIN32-Prj/snort.dsp: Removed deprecated telnet preprocessor. * src/profiler.c: * src/profiler.h: Added profiling code for 64 bit Intel and PPC platforms. * src/decode.h: * src/detect.c: * src/fpdetect.c: * src/log.c: * src/mstring.c: * src/parser.c: * src/plugbase.c: * src/profiler.c: * src/profiler.h: * src/sfthreshold.c: * src/signature.c: * src/snort.c: * src/strlcatu.c: * src/strlcpyu.c: * src/ubi_BinTree.c: * src/util.c: * src/util.h: * src/detection-plugins/sp_flowbits.c: * src/detection-plugins/sp_pattern_match.c: * src/detection-plugins/sp_pcre.c: * src/detection-plugins/sp_react.c: * src/detection-plugins/sp_respond.c: * src/detection-plugins/sp_ttl_check.c: * src/dynamic-plugins/sf_dynamic_engine.h: * src/dynamic-plugins/sf_dynamic_plugins.c: * src/dynamic-plugins/sf_dynamic_preprocessor.h: * src/dynamic-plugins/sp_dynamic.c: * src/dynamic-plugins/sp_preprocopt.c: * src/dynamic-plugins/sf_engine/bmh.c: * src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_loop.c: * src/dynamic-plugins/sf_preproc_example/sf_dynamic_preproc_lib.c: * src/dynamic-preprocessors/dns/spp_dns.c: * src/dynamic-preprocessors/ftptelnet/ftpp_si.c: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_config.c: * src/dynamic-preprocessors/ftptelnet/hi_util_kmap.c: * src/dynamic-preprocessors/ftptelnet/pp_ftp.c: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: * src/dynamic-preprocessors/ftptelnet/spp_ftptelnet.c: * src/dynamic-preprocessors/smtp/smtp_config.c: * src/dynamic-preprocessors/smtp/smtp_util.c: * src/dynamic-preprocessors/smtp/snort_smtp.c: * src/dynamic-preprocessors/ssh/spp_ssh.c: * src/output-plugins/spo_alert_fast.c: * src/output-plugins/spo_database.c: * src/output-plugins/spo_log_ascii.c: * src/output-plugins/spo_log_tcpdump.c: * src/output-plugins/spo_unified.c: * src/preprocessors/perf-base.c: * src/preprocessors/perf-flow.c: * src/preprocessors/perf.c: * src/preprocessors/portscan.c: * src/preprocessors/snort_httpinspect.c: * src/preprocessors/snort_stream4_udp.c: * src/preprocessors/spp_perfmonitor.c: * src/preprocessors/spp_sfportscan.c: * src/preprocessors/spp_stream5.c: * src/preprocessors/spp_stream4.c: * src/preprocessors/str_search.c: * src/preprocessors/stream.h: * src/preprocessors/HttpInspect/client/hi_client.c: * src/preprocessors/HttpInspect/event_output/hi_eo_log.c: * src/preprocessors/HttpInspect/user_interface/hi_ui_iis_unicode_map.c: * src/preprocessors/HttpInspect/utils/hi_util_kmap.c: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/preprocessors/flow/flow.h: * src/preprocessors/flow/int-snort/flow_packet.h: * src/preprocessors/flow/portscan/flowps.c: * src/preprocessors/flow/portscan/flowps_snort.c: * src/sfutil/acsmx.c: * src/sfutil/acsmx2.c: * src/sfutil/bitop_funcs.h: * src/sfutil/getopt_long.c: * src/sfutil/ipobj.c: * src/sfutil/sfghash.c: * src/sfutil/sflsq.c: * src/sfutil/sfsnprintfappend.c: * src/sfutil/sfxhash.c: * src/win32/WIN32-Code/misc.c: * src/win32/WIN32-Code/syslog.c: * src/win32/WIN32-Code/win32_service.c: Code cleanup, change malloc/calloc to SnortAlloc, use safer functions SnortSnprintf, SnortStrncpy, etc. Check pointers before use. * src/win32/WIN32-Code/win32_service.c: Fix issue with service initialization and parameter validation. Thanks Hideki Saito for pointing out the problem. * src/dynamic-preprocessors/dcerpc/dcerpc.c: * src/dynamic-preprocessors/dcerpc/dcerpc.h: * src/dynamic-preprocessors/dcerpc/dcerpc_config.c: * src/dynamic-preprocessors/dcerpc/dcerpc_util.c: * src/dynamic-preprocessors/dcerpc/dcerpc_util.h: * src/dynamic-preprocessors/dcerpc/smb_andx_decode.c: * src/dynamic-preprocessors/dcerpc/snort_dcerpc.c: * src/dynamic-preprocessors/dcerpc/spp_dcerpc.c: Code cleanup, update calculating for valid length to handle alternate padding. Update to use safer functions. * src/preprocessors/portscan.c: * src/preprocessors/portscan.h: * src/preprocessors/spp_stream4.c: * src/preprocessors/spp_stream5.c: * src/preprocessors/stream_api.h: * src/preprocessors/Stream5/snort_stream5_udp.c: Allow portscan to work with Stream5 UDP session tracking (because it replaces flow preprocessor). Added API function to get direction of packet (not supported in Stream4). * src/preprocessors/spp_stream5.c: * src/preprocessors/Stream5/snort_stream5_icmp.c: * src/preprocessors/Stream5/snort_stream5_icmp.h: * src/preprocessors/Stream5/snort_stream5_session.c: * src/preprocessors/Stream5/snort_stream5_session.h: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/preprocessors/Stream5/snort_stream5_udp.c: * src/preprocessors/Stream5/stream5_common.h: Stream5 config parsing improvements. Check option parameters for reasonable values (prevent huge memcaps, etc). 2007-01-29 Steven Sturges * src/debug.c: * configure.in: Handle platforms that don't support vswprintf and vwprintf. Thanks Nikns Siankin for pointing that out for OpenBSD. * src/profiler.h: * src/profiler.c: * src/rules.h: Use 64 bit values to store profiling counters. * doc/snort_manual.tex: * doc/snort_manual.pdf: Added a table for content modifiers and links to their respective sections. Removed old preprocessor sections and moved ASN.1 from preprocessor to detection plugins section. Added section for Stream5. * src/win32/WIN32-Prj/snort.dsp: Always use DYNAMIC_PLUGIN. * src/win32/WIN32-Includes/config.h: * src/win32/WIN32-Includes/LibnetNT.h: Code cleanup. * src/detection-plugins/sp_flowbits.c: * src/preprocessors/spp_stream5.c: Fix issue with flowbits for UDP streams. * src/detection-plugins/sp_flowbits.c: Add check when stream4 or stream5 are not enabled to still support flowbits. Will be removed when Flow preprocessor and Stream4 are deprecated. Thanks to Nathan Ching for pointing out the issue. * src/snort.c: Fix to allow dynamic rules to load correctly. * doc/README.stream4: * doc/README.stream5: Cleanup. 2007-01-18 Steven Sturges * etc/generators: * src/generators.h: Remove generator IDs that are no longer used. * doc/README.tag * doc/snort_manual.tex: * doc/snort_manual.pdf: Added info on snort.conf config option tagged_packet_limit and added README.tag info file for the tag option in rules. * doc/README.http_inspect: * doc/snort_manual.tex: * doc/snort_manual.pdf: Emphasized in httpinspect documentation that a flow_depth between 1 and 1460 will only inspect at most that many bytes of a server's response, stream reassembled or not and that rules written to inspect more than flow_depth bytes will be ineffective. Thanks to Christian Seifert for pointing this out. 2007-01-17 Steven Sturges * configure.in: * snort.8: * RELEASE.NOTES: * etc/snort.conf: * rpm/snort.spec: * src/win32/WIN32-Includes/config.h: * src/win32/WIN32-Prj/snort_installer.nsi: * doc/snort_manual.tex: * doc/snort_manual.pdf: Update for 2.7.0 Beta * src/dynamic-plugins/sf_engine/Makefile.am: * src/win32/Makefile.am: * src/win32/WIN32-Code/getopt.c: * src/win32/WIN32-Code/getopt_long.c: * src/win32/WIN32-Includes/config.h: * src/win32/WIN32-Includes/getopt.h: * src/win32/WIN32-Includes/getopt1.h: * src/win32/WIN32-Includes/stdint.h: * src/win32/WIN32-Prj/.cvsignore: * src/win32/WIN32-Prj/sf_engine.dsp: * src/win32/WIN32-Prj/snort.dsp: * src/win32/WIN32-Prj/snort.dsw: Update Win32 build enviornment for 2.7.0. * doc/README.stream5: * doc/README.ftptelnet: Fix a few typos and add better descriptions for alerts. * etc/gen-msg.map: * etc/generators.h: Add Stream5 alert. * etc/snort.conf: * src/preprocessors/spp_frag2.c (removed): * src/preprocessors/spp_frag2.h (removed): * src/preprocessors/Makefile.am: * src/plugbase.c: * src/plugbase.h: Remove deprecated Frag2. * src/sfutil/mwm.c (removed): * src/sfutil/mwm.h (removed): Remove deprecated mwm pattern matcher. * src/detection-plugins/sp_ipoption_check.c: * src/decode.h: * src/decode.c: * src/log.c: Add handling of IP Option ESEC (Extended Security). * src/debug.h: * src/bounds.h: * src/fpcreate.h: * src/fpdetect.h: * src/tag.c: * src/detection-plugins/sp_respond2.c: * src/dynamic-preprocessors/ftptelnet/ftpp_include.h: * src/preprocessors/portscan.h: * src/preprocessors/snort_stream4_udp.c: * src/preprocessors/spp_stream4.c: * src/preprocessors/HttpInspect/include/hi_include.h: * src/preprocessors/flow/common_defs.h: * src/sfutil/bitop_funcs.h: Move definition of INLINE for inline functions to a common place. * src/debug.c: * src/debug.h: * src/dynamic-plugins/sf_dynamic_preprocessor.h: Add DebugWideMessageFunc for use with Wide Character sets, however it does not write to syslog. * src/debug.c: * src/decode.c: * src/detect.c: * src/detect.h: * src/fpcreate.c: * src/fpdetect.c: * src/log.c: * src/mstring.c: * src/parser.c: * src/pcrm.c: * src/plugbase.c: * src/profiler.h: * src/sf_sdlist.c: * src/sfthreshold.c: * src/sfthreshold.h: * src/signature.c: * src/snort.c: * src/snort.h: * src/tag.c: * src/util.c: * src/util.h: * src/detection-plugins/sp_ip_fragbits.c: * src/detection-plugins/sp_pcre.c: * src/detection-plugins/sp_rpc_check.c: * src/dynamic-plugins/sf_dynamic_plugins.c: * src/dynamic-plugins/sp_preprocopt.c: * src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c: * src/dynamic-plugins/sf_engine/sf_snort_packet.h: * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.h: * src/dynamic-plugins/sf_engine/sf_snort_plugin_loop.c: * src/dynamic-preprocessors/dcerpc/dcerpc.c: * src/dynamic-preprocessors/dcerpc/dcerpc_util.c: * src/dynamic-preprocessors/dcerpc/smb_andx_decode.c: * src/dynamic-preprocessors/ftptelnet/ftpp_si.c: * src/dynamic-preprocessors/ftptelnet/pp_ftp.c: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: * src/dynamic-preprocessors/smtp/smtp_confic.c: * src/dynamic-preprocessors/ssh/spp_ssh.c: * src/dynamic-preprocessors/ssh/spp_ssh.h: * src/preprocessors/spp_arpspoof.c: * src/preprocessors/spp_flow.c: * src/preprocessors/spp_frag3.c: * src/preprocessors/spp_stream4.c: * src/preprocessors/str_search.c: * src/preprocessors/stream_ignore.c: * src/sfutil/acsmx.c: * src/sfutil/acsmx.h: * src/sfutil/acsmx2.c: * src/sfutil/acsmx2.h: * src/sfutil/asn1.c: * src/sfutil/asn1.h: * src/sfutil/bnfa_search.c: * src/sfutil/bnfa_search.h: * src/sfutil/ipobj.c: * src/sfutil/mpse.c: * src/sfutil/mpse.h: * src/sfutil/mwm.c: * src/sfutil/mwm.h: * src/sfutil/sfeventq.c: * src/sfutil/sfghash.c: * src/sfutil/sfghash.h: * src/sfutil/sfhashfcn.c: * src/sfutil/sfksearch.c: * src/sfutil/sfksearch.h: * src/sfutil/sflsq.c: * src/sfutil/sflsq.h: * src/sfutil/sfmemcap.c: * src/sfutil/sfsnprintfappend.c: * src/sfutil/sfthd.c: * src/sfutil/sfxhash.c: * src/sfutil/sfxhash.h: * src/sfutil/util_match.c: * src/sfutil/util_net.c: Code cleanup, change malloc to calloc, use safer functions SnortAlloc, SnortStrdup. Check pointers before use. * src/sfutil/acsmx.c: * src/sfutil/acsmx.h: * src/sfutil/acsmx2.c: * src/sfutil/acsmx2.h: * src/sfutil/bnfa_search.c: * src/sfutil/bnfa_search.h: * src/sfutil/mpse.c: * src/sfutil/mpse.h: * src/sfutil/mwm.c: * src/sfutil/mwm.h: Added caller usable state tracking to pattern matcher. * src/parser.c: * src/parser.h: * src/dynamic-plugins/sp_preprocopt.c: * src/dynamic-plugins/sp_preprocopt.h: To better handle rule options that are provided by dynamic preprocessors, make 2 passes through snort.conf at startup. * src/parser.c: * src/snort.c: Improve dynamicengine keyword and commandline option to allow for specifying directory or file. * src/detect.c: * src/event_queue.c: * src/event_queue.h: * src/event_wrapper.c: * src/event_wrapper.h: * src/fpcreate.c: * src/parser.c: * src/signature.c: * src/signature.h: Unify logging to a single code path and added ability to have rule stubs for preprocessor and decoder events. * src/snort.c: Fix code that looks for .snortrc. Thanks to Benjamin Bennett for pointing out the issue. * src/preprocessors/portscan.c: * src/preprocessors/spp_sfportscan.c: Fix false alert where destination IP was not in range reported by sfportscan alert. * src/preprocessors/spp_sfportscan.c: Reset threshold checking at end of portscan alerting so that other events generated for packet wouldn't use old value returned from testing portscan thresholding/suppression. Thanks to Andreas Ostling for pointing this out. * src/preprocessors/spp_frag3.c: Cleanup of GRE code for GRE nested fragments. * src/preprocessors/spp_stream5.c: * src/preprocessors/Stream5/snort_stream5_icmp.c: * src/preprocessors/Stream5/snort_stream5_icmp.h: * src/preprocessors/Stream5/snort_stream5_session.c: * src/preprocessors/Stream5/snort_stream5_session.h: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/preprocessors/Stream5/snort_stream5_tcp.h: * src/preprocessors/Stream5/snort_stream5_udp.c: * src/preprocessors/Stream5/snort_stream5_udp.h: * src/preprocessors/Stream5/stream5_common.c: * src/preprocessors/Stream5/stream5_common.h: Added memcap for TCP reassembly packet storage. Reduced memory consumption of session tracking data structures. Added target-based reassembly for HPUX 11, HPUX 10.2, Windows 2003, Windows Vista. Added target-based support for processing of TCP timestamps, TCP Resets, and repeated SYN packets. Improved Session cache management. Update flushpoint management. Improved handling of midstream session establishment. Code cleanup to use safe functions for memory allocation. Set tcp policy for both sides of session, rather that by first packet seen, correctly does target-based reassembly for each side. Simplify code handling sessions to ignore. 2007-01-07 Steven Sturges * src/decode.c: * src/decode.h: Fixed issue where GRE decoder was attempting to assign a potentially negative value to an unsigned integer. This value, which would then be positive, was then checked to see if it was less than zero, which would indicate whether the calculated length of the header was greater than the length of the rest of the packet capture. This would always return false and the assumed length of the packet would potentially be larger than the actual length, leading to a potential dereferning of invalid memory. Thanks to Chris Rohlf for pointing this out. 2006-12-04 Steven Sturges * src/dynamic-preprocessors/ftptelnet/ftpp_ui_config.c: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_config.h: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: Configuration validation update. * src/dynamic-preprocessors/dcerpc/dcerpc.c: * src/dynamic-preprocessors/dcerpc/sf_preproc_info.h: * src/dynamic-preprocessors/dcerpc/smb_andx_decode.c: Additional updates for bounds checking. * src/detection-plugins/sp_isdataat.c: * doc/snort_manual.tex: * doc/snort_manual.pdf: Added an option to specify rawbytes for the buffer. 2006-11-30 Steven Sturges * src/tag.c: Fix logging of tagged packets when -G (event source ID) is used. * src/event.h: * src/snort_packet_header.h: * src/output-plugins/spo_unified.c: Fix unified to work correctly on 64bit platforms. Thanks Nikns Siankin for the report. Nikns provides a patch to barnyard that may be required to use this functionality on a 64bit systems. Grab the patch from here: http://secure.lv/~nikns/stuff/barnyard_64bit.diff * src/snort.c: * src/snort.h: Reorganize code for inline fail-open to create pattern matcher rule groups in the thread. * src/util.c: Code cleanup * src/dynamic-preprocessors/dcerpc/dcerpc.c: * src/dynamic-preprocessors/dcerpc/dcerpc_util.c: * src/dynamic-preprocessors/dcerpc/sf_preproc_info.h: * src/dynamic-preprocessors/dcerpc/smb_andx_decode.c: * src/dynamic-preprocessors/dcerpc/snort_dcerpc.c: Fix segfault caused by integer overflow and add additional checks to protect against other underflow/overflow conditions. * src/preprocessors/spp_stream4.c: * src/preprocessors/stream.h: Add capability to have multiple application layer preprocessors store data within the stream to better handle autodetection and multi-protocol packets. Fix additional issue with high CPU and reprocessing rebuilt packets that are split across a sequence wrap. 2006-11-22 Steven Sturges * preprocessors/spp_stream4.c: Fix problem with snort using high CPU and reprocessing the same rebuilt packets at session end or ACK in middle of packet when there are gaps in the packet sequence. 2006-11-16 Andrew Mullican * etc/gen-msg.map: Add DCE/RPC preprocessor alert. 2006-11-07 Steven Sturges * src/dynamic-preprocessors/dcerpc/dcerpc.c: * src/dynamic-preprocessors/dcerpc/dcerpc_config.c: * src/dynamic-preprocessors/dcerpc/smb_andx_decode.c: * src/dynamic-preprocessors/dcerpc/snort_dcerpc.h: * src/dynamic-preprocessors/dcerpc/spp_dcerpc.c: Updates for printing of options and handling of memcap. * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: Add print for config option. * src/preprocessors/spp_stream5.c: * src/preprocessors/Stream5/snort_stream5_session.c: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/preprocessors/Stream5/snort_stream5_udp.c: Add UDP session tracking stats. Improved TCP Timestamp handling. Seperate MacOS policy from BSD, as they differ slightly. Improved performance of session pruning. * src/snort.c: Updates to inline thread initialization. 2006-10-30 Steven Sturges * src/dynamic-preprocessors/dcerpc/dcerpc.c: * src/dynamic-preprocessors/dcerpc/snort_dcerpc.c: Fix debug prints. * src/detection-plugins/sp_isdataat.c: Fix problem with this option not being marked as relative when 'relative' is used. This change should've been made with changes for not rechecking non-relative options on 2006-08-16. 2006-10-27 Steven Sturges * src/preprocessors/snort_httpinspect.c: * src/preprocessors/HttpInspect/include/hi_ui_config.h: Output user-selected server profile at startup. * src/parser.c: Detect corrupt files and handle mixed windows and unix line endings. * doc/README.dcerpc: Update description of DCE/RPC auto-detect. * src/dynamic-preprocessors/dcerpc/smb_andx_decode.c: * src/dynamic-preprocessors/dcerpc/smb_andx_decode.h: * src/dynamic-preprocessors/dcerpc/smb_andx_structs.h: * src/dynamic-preprocessors/dcerpc/smb_structs.h: * src/dynamic-preprocessors/dcerpc/snort_dcerpc.c: Fix various bugs relating to unicode, ntohs, bounds-checking, and SMB chained AndX commands. * src/dynamic-preprocessors/dcerpc/dcerpc_config.c: Print out mempcap and max_frag_size on startup. 2006-10-23 Steven Sturges * doc/snort_manual.tex: * doc/snort_manual.pdf: Updated stream4 documentation in the Snort manual to reflect new UDP options and inline option updates. Corrected error with event_queue parameter - changed max_events to max_queue. * doc/faq.tex: Updated FAQ to reflect disuse of ACID in favor of BASE. Added references to FLoP and Mudpit as output systems for Snort. Added references to two IDS books. * doc/README.decode: Added README file for the Snort decoder * doc/README.stream4: Made minor changes to language * etc/snort.conf: Added commented out decoder options with description - enable_decode_oversized_alerts and enable_decode_oversized_drops * doc/README.http_inspect: * src/preprocessors/HttpInspect/user_interface/hi_ui_config.c: Updated tab_uri_delimiter section in document to reflect deprecation. Removed the deprecated tab_uri_delimiter from server profiles since it's redundant with whitespace_chars. * src/preprocessors/snort_httpinspect.c: Allow user-specified ports to override internal defaults. * src/detection-plugins/sp_pattern_match.c: Fix error message with max pattern size. * src/dynamic-preprocessors/dns/spp_dns.c: * src/dynamic-preprocessors/dns/spp_dns.h: Fix spelling of obsolete in macros. * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: Fix spelling of DETECT_ANOMALIES macro. * src/profiler.c: Removed tabs from preprocessor stats output. Tabs aren't compliant with syslog RFC. * doc/README.ftptelnet: * doc/snort_manual.tex: * doc/snort_manual.pdf: Added documentation on Telnet configuration option detect_anomalies * src/preprocessors/spp_stream4.c: Fixed potential for infinite loop when only part of a packet being used in reassembly is ACK'd. * src/preprocessors/perf-base.c: Fixed packet count stats when in readback mode. 2006-10-13 Steven Sturges * src/detection-plugins/sp_flowbits.c: Fixed an off-by-one error message that prevented the maximum number of flowbits from being used. Include number of flowbits used in summary of flowbits usage. * src/dynamic-preprocessors/dns/spp_dns.c: * src/dynamic-preprocessors/dns/spp_dns.h: Fix parser to properly error if misconfigured ports. * src/decode.c: * src/decode.h: * src/parser.c: Added new config option "enable_decode_oversized_alerts" and "enable_decode_oversized_drops" to allow alerting on packets with extra bytes at the end of their payload 2006-10-12 Steven Sturges * doc/snort_manual.tex: * doc/snort_manual.pdf: * RELEASE.NOTES: Prepare for 2.6.1 RC. * configure.in: * src/parser.c: * src/snort.c: * src/snort.h: Start a thread if running in inline mode that passes traffic through once pcap is opened and snort is not ready to start inspection (ie, loading rules, creating pattern matcher, etc). Thread is terminated when snort is ready to process packets. Compiled in via --enable-inline-init-failopen option to configure script. Disable by --disable-inline-init-failopen commandline option or 'config disable_inline_init_failopen' in snort.conf/user.conf in the case that the interface is fail-closed. Requires libpthread. * src/parser.c: Require a sid for every rule. * src/dynamic-preprocessors/ssh/spp_ssh.c: Verifies that the stream preprocessor is enabled. Version string bounds checking now uses the length of the version string versus the length of the entire payload. * src/preprocessors/snort_stream4_udp.c: Update UDP session stats (packet count, start/end time, bytes, etc). * doc/README.stream4: * doc/Makefile.am: Finally a description for Stream4. Thanks Todd! * src/parser.c: * src/signature.c: Allow for variable metadata in rule options. Ignore unknown metadata fields. * etc/gen-msg.map: * src/decode.c: * src/generators.h: Added additional TCP length checking and UDP length checking and new decode alerts for anomalous lengths. 2006-10-09 Steven Sturges * src/preprocessors/spp_stream4.c: Fix problem with reassembly of server side traffic. Thanks rmkml and Crusoe Researchers for notifying us of the issue. * src/preprocessors/spp_stream4.c: * src/generators.h: * etc/gen-msg.map: Fix Stream4 to handle duplicate SYN packets by purging existing packets queued for reassembly after the seq of the SYN. Also, properly handle retransmitted data that is overlapping the current packet and when trimmed overlapping the next packet. 2006-10-04 Steven Sturges * src/decode.c: Fixed issue in GRE code where data could potentially be dereferenced past the end of the packet. * src/parser.c: Fix log message. * src/preprocessors/perf-base.c: * src/preprocessors/perf-base.h: * src/preprocessors/snort_stream4_session.c: * src/preprocessors/snort_stream4_session.h: * src/preprocessors/snort_stream4_udp.c: * src/preprocessors/spp_stream4.c: * src/preprocessors/stream.h: Add stats tracking for UDP sessions to perfmonitor and stream4's session stats (keepstats option). Update Stream4 to purge UDP session cache on a timeout basis, similar to the way TCP session cache is purged. Remove cache_clean_percent option. * src/dynamic-preprocessors/dcerpc/dcerpc.c: * src/dynamic-preprocessors/dcerpc/dcerpc.h: * src/dynamic-preprocessors/dcerpc/smb_andx_decode.c: * src/dynamic-preprocessors/dcerpc/snort_dcerpc.c: * src/dynamic-preprocessors/dcerpc/snort_dcerpc.h: * src/dynamic-preprocessors/dcerpc/spp_dcerpc.c: Fixes for CORE SMB fragmentation. Also, fix for perf-profiling. 2006-09-27 Steven Sturges * src/preprocessors/snort_stream4_session.c: * src/preprocessors/spp_stream4.c: * src/preprocessors/stream.h: * src/sfutil/sfxhash.c: * src/sfutil/sfxhash.h: Fix issue with use of Stream4 cache_clean_percent option that resulted in a segfault when the max session limit was reached. Thanks to Jason Ish for reporting the problem. * src/preprocessors/snort_httpinspect.c: * src/preprocessors/HttpInspect/include/hi_ui_config.h: * src/preprocessors/HttpInspect/user_interface/hi_ui_config.c: * doc/README.http_inspect: Split the IIS profile in the HTTP inspect preprocessor into IIS, ISS4, and ISS5_0. ISS 4.0 and ISS 5.0 both support double decoding, but ISS 5.1 and beyond do not. Double decoding alerts are now disabled in the ISS profile, but remain enabled for the IIS 4.0 and IIS 5.0 profiles. Thanks to Pratap Ramamurthy for pointing out that IIS 5.1 does not support double decoding * src/snort.c: * src/snort.h: * src/util.c: * src/util.h: Fixed issue where iface_ADDRESS variable wasn't getting set before configuration file was read. Now all up interfaces will get a variable created. Note that these will NOT get set if the readmode flag is set. Thanks to Paul Melson for reporting the problem. * src/preprocessors/spp_stream4.c: * src/preprocessors/stream.h: Handle reassembly of first packet for midstream pickups (first packet wasn't part of an established session at that point, so some rules might fail). * src/preprocessors/Stream5/snort_stream5_session.c: Fix handling of cache clean by percent. * src/detection-plugins/sp_pattern_match.c: * src/detection-plugins/sp_pattern_match.h: Fix problem with relative options not being marked as relative (for distance/within keywords). 2006-09-21 Steven Sturges * src/generators.h: * src/snort.c: * src/sfutil/bitop_funcs.h: * src/preprocessors/Stream5/snort_stream5_tcp.c: Update for GRE additions and compilation on Win32. * src/preprocessors/spp_stream4.c: Fix issue with alerts missing in DEBUG mode. * src/preprocessors/HttpInspect/client/hi_client.c: * src/preprocessors/HttpInspect/include/hi_ui_config.h: Fix signedness issue that caused HttpInspect to miss certain oversized chunk alerts. * src/sfutil/ipobj.c: Fix parsing that prevented multiple IP lists from being parsed correctly. This fixes a problem with sfportscan configuration when 'watch_ip', 'ignore_scanners', and 'ignore_scanned' options are used together. Thanks to Rob Sharp and Husnu Demir for reporting the bug. 2006-09-18 Steven Sturges * configure.in: * doc/INSTALL: * gen-msg.map: * src/decode.c: * src/decode.h: * src/generators.h: * src/snort.c: * src/snort.h: * src/util.c: * src/dynamic-plugins/sf_engine/sf_snort_packet.h: * src/preprocessors/spp_frag3.c: * src/preprocessors/spp_stream4.c: Added support to decode GRE encapsulated traffic. Only IP as transport protocol is supported and only one layer of encapsulation will be decoded - packets with multiple GRE headers will be discarded. Thanks Todd Wease (and welcome to the Snort team!) for this contribution. * configure.in: * doc/README.ARUBA: * doc/Makefile.am: * doc/snort_manual.tex: * src/plugbase.c: * src/output-plugins/Makefile.am: * src/output-plugins/spo_alert_arubaaction.c: * src/output-plugins/spo_alert_arubaaction.h: Added support for communcation with an Aruba Networks wireless mobility authentication/access control system. * configure.in: GCC 4.x.x has strict aliasing on by default with optimization level 2. However, Snort uses aliases in a number of places. configure now checks the gcc compiler version for 4 and disables strict aliasing with -fno-strict-aliasing. Thanks to Ronald Henderson and Keith Konecnik for simultaneously (and independently) discovering and reporting this issue. 2006-09-15 Steven Sturges * src/detection-plugins/sp_pattern_match.c: Cleanly fail with content patterns that are > 2048 bytes. * src/dynamic-preprocessors/dcerpc/dcerpc.c: * src/dynamic-preprocessors/dcerpc/dcerpc_config.c: * src/dynamic-preprocessors/dcerpc/dcerpc_util.c: * src/dynamic-preprocessors/dcerpc/dcerpc_util.h: * src/dynamic-preprocessors/dcerpc/smb_andx_decode.c: * src/dynamic-preprocessors/dcerpc/snort_dcerpc.c: * src/dynamic-preprocessors/dcerpc/snort_dcerpc.h: Fix memcap to be global. Turn off memcap alerts by default. Add config item to enable alerting on exceeded memcap. * src/sfutil/acsmx2.c: * src/sfutil/acsmx2.h: * src/sfutil/acsmx.c: * src/sfutil/mpse.c: Code cleanup 2006-09-13 Steven Sturges * src/decode.c: * src/decode.h: * src/log.c: * src/log.h: * src/generators.h: * etc/gen-msg.map: Added code to print original datagram for all ICMP error types if alerted on. Fix to print original datagram on alert if original datagram was ICMP. Thanks to John Papapanos for pointing out the above 2 issues. Added additional decoder alerts for ICMP error types. Removed fragtracking of ICMP original datagram - it never made sense since only an ICMP response to the first frag is ever returned. Fixed issue where data and size pointers were not set correctly for ICMP error types. * src/dynamic-preprocessors/ftptelnet/ftpp_si.c: * src/dynamic-preprocessors/ftptelnet/ftpp_si.h: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: Remove checks for duplicate alerts within a given session, as this is now handled within the general alerting mechanism and session tracking. * src/parser.c: When a variable was redefined, a call to LogMessage() was missing a parameter. Thanks to Greg Baran for pointing this out. 2006-09-11 Steven Sturges * src/dynamic-preprocessors/dcerpc/dcerpc.c: * src/dynamic-preprocessors/dcerpc/dcerpc.h: * src/dynamic-preprocessors/dcerpc/dcerpc_util.c: * src/dynamic-preprocessors/dcerpc/smb_andx_decode.c: * src/dynamic-preprocessors/dcerpc/snort_dcerpc.c: Fix to remove uses of strlen or wcslen. Properly validate andXOffset. Fix bug in DCE/RPC fragment reassembly. 2006-09-07 Steven Sturges * src/util.c: Fix output for the USR1 signal when calculating statistics for pcap counts. Keep a tally of packets seen/dropped/etc and use deltas, rather than the 'most recent' value when determining percentages after each USR1 signal. Thanks to Colin Grady for pointing out the issue. * src/parser.c: Allow for a line without an end of line marker in snort.conf. 2006-09-06 Steven Sturges * src/decode.c: * src/detect.c: * src/log.c: * src/snort.c: * src/detection-plugins/sp_respond.c: * src/detection-plugins/sp_respond2.c: * src/preprocessors/spp_frag2.c: * src/preprocessors/spp_frag3.c: * src/preprocessors/spp_stream4.c: * src/preprocessors/Stream5/snort_stream5_tcp.c: Fix memory leak in ascii and cmg output modules. Remove calls to ClearDumpBuf() from related calls PrintIPPkt() and PrintNetData(), as it is no longer needed. 2006-08-31 Steven Sturges * rpm/snort.spec: * etc/snort.conf: Add DNS preprocessor to packaging and config. * doc/Makefile.am: * doc/README.stream5: Add Stream5 README. 2006-08-30 Steven Sturges * src/sfutil/ipobj.c: Additional fix for parsing of IP lists that are not space separated. * src/dynamic-preprocessors/ftptelnet/pp_ftp.c: Treat spaces as part of a filename in 'string' parameter validation. Thanks Bamm Visscher for pointing out the issue. * src/preprocessors/spp_stream4.c: * src/preprocessors/stream.h: * src/preprocessors/snort_stream4_session.c: * src/preprocessors/snort_stream4_session.h: Remove the ifdef'd splay tree code for packet and session storage. It has been replaced by a hash table and is no longer needed. * src/preprocessors/spp_stream4.c: * src/preprocessors/stream.h: * src/preprocessors/stream_api.h: * src/preprocessors/spp_stream5.c: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/preprocessors/Stream5/snort_stream5_tcp.h: * src/preprocessors/Stream5/stream5_common.h: Add a few functions to the Stream API to allow a protocol analyzer to change the reassembly characteristics (direction, flush policy) for an individual session. * configure.in: * doc/Makefile.am: * doc/README.dns: * doc/snort_manual.tex: * doc/snort_manual.pdf: * etc/gen-msg.map: * src/build.h: * src/debug.h: * src/generators.h: * src/dynamic-preprocessors/Makefile.am: * src/dynamic-preprocessors/dns/Makefile.am: * src/dynamic-preprocessors/dns/sf_preproc_info.h: * src/dynamic-preprocessors/dns/spp_dns.c: * src/dynamic-preprocessors/dns/spp_dns.h: Add a dynamic preprocessor to decode and analyze DNS responses over TCP and UDP. The TCP portion is stateful and requires stream is enabled. 2006-08-29 Steven Sturges * src/detection-plugins/sp_pattern_match.c: Fix unchecked free. Thanks Krzysztof Burghardt for pointing out the problem. * src/sfutil/acsmx2.c: Fixed off by one to sparse index calculation and off by 2 ps increment for SparseBands. 200-08-24 Steven Sturges * src/fpcreate.c: * src/sfutil/mpse.c: * src/sfutil/Makefile.am: Fix issues with using lowmem. It was reporting an out of memory error. This was broken with the addition of the smaller memory Aho-Corasick pattern matcher. 2006-08-17 Steven Sturges * doc/README.dcerpc: * doc/snort_manual.tex: * doc/snort_manual.pdf: * etc/snort.conf: * src/dynamic-preprocessors/dcerpc/dcerpc_config.c: * src/dynamic-preprocessors/dcerpc/dcerpc_util.h: * src/dynamic-preprocessors/dcerpc/snort_dcerpc.h: Change config option max_memory to memcap for DCE/RPC. 2006-08-16 Steven Sturges * src/rules.h: * src/detection-plugins/sp_asn1.c: * src/detection-plugins/sp_byte_check.c: * src/detection-plugins/sp_byte_jump.c: * src/detection-plugins/sp_pattern_match.c: * src/detection-plugins/sp_pcre.c: Resolve issue with rechecking rule options that follow a content or PCRE that are relative. Only recheck if the next option is relative. Thanks to Randy Smith for pointing out the issue. * configure.in: Enable dynamicplugins by default. Can override with --disable-dynamicplugin. * snort.8: * doc/snort_manual.pdf: * doc/snort_manual.tex: * doc/Makefile.am: * doc/README.ssh: * doc/README.dcerpc: * etc/snort.conf: * src/win32/WIN32-Prj/snort_installer.nsi: Added SSH and DCE/RPC preprocessor sections and description of new command line options. 2006-08-15 Steven Sturges * src/dynamic-preprocessors/dcerpc/sf_dcerpc.dsp: Remove obsolete file. * src/preprocessors/Stream5/Makefile.am: Update to include header files. * src/preprocessors/Stream5/stream5_common.c: * src/preprocessors/flow/flow_cache.c: * src/sfutil/util_math.c: * src/sfutil/util_math.h: Cleanup Win32 warnings. * src/sfutil/mpse.c: * src/win32/WIN32-Prj/snort.dsp: * src/win32/WIN32-Prj/snort.dsw: Remove references to MWM and sfksearch. 2006-08-14 Steven Sturges * configure.in: * etc/gen-msg.map: * etc/snort.conf: * src/detection-plugins/sp_flowbits.c: * src/detection-plugins/sp_flowbits.h: * src/dynamic-plugins/sf_dynamic_engine.h: * src/dynamic-plugins/sp_dynamic.c: * src/dynamic-plugins/sp_dynamic.h: * src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c: * src/dynamic-preprocessors/sf_dynamic_initialize/sf_dynamic_initialize.dsp: * src/dynamic-preprocessors/Makefile.am: * src/preprocessors/Makefile.am: * src/preprocessors/spp_stream5.c: * src/preprocessors/spp_stream5.h: * src/preprocessors/Stream5/snort_stream5_tcp.c: * src/preprocessors/Stream5/snort_stream5_tcp.h: * src/preprocessors/Stream5/snort_stream5_udp.c: * src/preprocessors/Stream5/snort_stream5_udp.h: * src/preprocessors/Stream5/snort_stream5_icmp.c: * src/preprocessors/Stream5/snort_stream5_icmp.h: * src/preprocessors/Stream5/Makefile.am: * src/preprocessors/stream_api.h: * src/generators.h: * src/plugbase.h: * src/Makefile.am: * src/plugin_enum.h: New target-based Stream module. Moved flow & flowbits to be part of Stream API. * src/debug.h: * src/generators.h: * src/preprocids.h: * src/dynamic-preprocessors/Makefile.am: * src/dynamic-preprocessors/dcerpc/Makefile.am: * src/dynamic-preprocessors/dcerpc/dcerpc.c: * src/dynamic-preprocessors/dcerpc/dcerpc.h: * src/dynamic-preprocessors/dcerpc/dcerpc_util.c: * src/dynamic-preprocessors/dcerpc/dcerpc_util.h: * src/dynamic-preprocessors/dcerpc/dcerpc_config.c: * src/dynamic-preprocessors/dcerpc/sf_dcerpc.dsp: * src/dynamic-preprocessors/dcerpc/sf_preproc_info.h: * src/dynamic-preprocessors/dcerpc/smb_andx_decode.c: * src/dynamic-preprocessors/dcerpc/smb_andx_decode.h: * src/dynamic-preprocessors/dcerpc/smb_andx_structs.h: * src/dynamic-preprocessors/dcerpc/smb_file_decode.c: * src/dynamic-preprocessors/dcerpc/smb_file_decode.h: * src/dynamic-preprocessors/dcerpc/smb_file_structs.h: * src/dynamic-preprocessors/dcerpc/smb_structs.h: * src/dynamic-preprocessors/dcerpc/snort_dcerpc.c: * src/dynamic-preprocessors/dcerpc/snort_dcerpc.h: * src/dynamic-preprocessors/dcerpc/spp_dcerpc.c: * src/dynamic-preprocessors/dcerpc/spp_dcerpc.h: New dynamic DCE/RPC protocol normalizer. * src/dynamic-preprocessors/Makefile.am: * src/dynamic-preprocessors/ssh/sf_ssh.dsp: * src/dynamic-preprocessors/ssh/Makefile.am: * src/dynamic-preprocessors/ssh/spp_ssh.c: * src/dynamic-preprocessors/ssh/spp_ssh.h: * src/dynamic-preprocessors/ssh/sf_preproc_info.h: New dynamic ssh protocol normalizer. * src/detection-plugins/sp_clientserver.c: * src/preprocessors/Makefile.am: * src/preprocessors/snort_stream4_session.c: * src/preprocessors/snort_stream4_udp.c: * src/preprocessors/snort_stream4_udp.h: * src/preprocessors/spp_stream4.c: * src/preprocessors/stream.h: Stream4 UDP session tracking support. Reassembly performance improvements. Add ability to block TCP sessions. * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.h: * src/dynamic-plugins/sf_engine/sf_snort_plugin_rc4.c: Added RC4 dynamic rule option. * src/fpcreate.c: * src/fpcreate.h: * src/fpdetect.c: * src/pcrm.c: * src/sfutil/Makefile.am: * src/sfutil/bnfa_search.c: * src/sfutil/bnfa_search.h: * src/sfutil/mpse.c: * src/sfutil/mpse.h: Added smaller memory consumption pattern matcher. * src/decode.h: * src/fpdetect.c: * src/inline.c: Improved handling for stateless rules. * configure.in: * src/parser.c: * src/parser.h: * src/rules.h: * src/snort.c: * src/snort.h: Remove use of ifdefs for rule state. * src/parser.c: * src/snort.c: * src/snort.h: Add ability to give directory or specific library for dynamic engine. * src/dynamic-preprocessors/ftptelnet/ftpp_eo_events.h: * src/dynamic-preprocessors/ftptelnet/ftpp_eo_log.c: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_config.h: * src/dynamic-preprocessors/ftptelnet/pp_ftp.c: * src/dynamic-preprocessors/ftptelnet/pp_telnet.c: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: Add alerts and normalization for telnet subnegotiation begin that doesn't have a matching end. Could result in an evasion over the FTP command channel. * src/snort.c: * src/snort.h: * src/util.c: Added counter for segments queued for reassembly. * src/snort.c: * src/dynamic-plugins/sf_dynamic_detection.h: * src/dynamic-plugins/sf_dynamic_engine.h: * src/dynamic-plugins/sf_dynamic_plugins.c: * src/dynamic-plugins/sf_dynamic_preprocessor.h: Improved handling of different versions of same shared library. * src/detect.c: * src/dynamic-plugins/sf_engine/bmh.c: * src/dynamic-plugins/sf_engine/bmh.h: * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.c: * src/dynamic-preprocessors/smtp/smtp_xlink2state.c: * src/dynamic-preprocessors/smtp/snort_smtp.h: * src/output-plugins/spo_alert_fast.c: * src/preprocessors/spp_frag3.c: * src/preprocessors/spp_perfmonitor.c: * src/sfutil/acsmx.c: Code cleanup, 2.6.1 Beta prep. 2006-08-09 Steven Sturges * doc/faq.tex: * doc/faq.pdf: Add information on snort responding to kill signal. 2006-08-02 Steven Sturges * src/output-plugins/spo_alert_prelude.c: Update to provide links to Snort classification reference information. Thanks Yoann Vandoorselaere. * src/sfutil/ipobj.c: Fix parsing of IP lists that are not space separated. * src/configure.in: Update for HPUX 11. * src/snort.c: * src/util.c: Fix race condition with daemonization. * src/dynamic-plugins/sf_dynamic_plugins.c: Update for shared library extensions on HP & MAC. Thanks J. Aaron Pendergrass for raising the HP issues and testing. 2006-07-25 Andrew Mullican * src/preprocessors/HttpInspect/client/hi_client.c: Fix to HttpInspect to check for non-RFC whitespace (ie, CR) after URI. * src/preprocessors/spp_frag3.c: Eliminate spurious log messages. 2006-07-20 Steven Sturges * src/dynamic-preprocessors/smtp/snort_smtp.c: * src/dynamic-preprocessors/smtp/snort_smtp.h: No longer require HELO (or EHLO) first in an SMTP conversation. Some servers (such as ArGoSoft) don't require it. * src/dynamic-preprocessors/ftptelnet/pp_telnet.c: Handle normalization when Subnegotiation Begin doesn't have a matching Subnegotiation End command by normalizing just the begin. Thanks to Pratap Ramamurthy for pointing out the potential issue. 2006-07-14 Steven Sturges * src/decode.h: * src/detect.c: * src/fpdetect.c: Handle pass rule that hits a pipelined URI and an alert that matches a secondary pipelined URI. * src/preprocessors/spp_frag3.c: Fix issue with First policy when dealing with whole overlaps. Thanks Russ S for sending in the bug report. * src/preprocessors/spp_stream4.c: Performance improvement for logging tagged packets. Thanks Victor Julien for pointing out the area for improvement. * src/dynamic-preprocessors/smtp/snort_smtp.c: Fix potential access violation. 2006-07-12 Steven Sturges * src/output-plugins/spo_database.c: Update to gracefully disconnect from Oracle DB. Thanks to Nikns Siankin for the patch. * src/output-plugins/spo_csv.c: Fix issue with parsing config other than default. * src/decode.c: * src/parser.c: * src/snort.h: * doc/snort_manual.tex: * doc/snort_manual.pdf: Change default inline behaviour to not drop packets with decoder errors, invalid IP & TCP options and invalid checksums. Drop behaviour can be enabled by using new options, noted in the Snort Manual. 2006-06-30 Steven Sturges * schemas/Makefile.am: Add create_db2 srcipt to be included in distro. * src/mstring.c: Address potential read overflow. * src/sfthreshold.c: * src/tag.c: * src/win32/WIN32-Includes/stdint.h: * src/win32/WIN32-Includes/NETINET/IN_SYSTM.h: Code cleanup. * src/snort.c: * src/util.c: Fix issue with daemonization on MAC OSX and parent not exiting cleanly. * src/snort.c: * src/snort.h: * src/util.c: * src/util.h: * snort.8: * doc/snort_manual.tex: * doc/snort_manual.pdf: Provide support for locking the PID file so that no additional snort process is able to start using the same PID file. Can be overridden with --nolock-pidfile. * src/detection-plugins/sp_pattern_match.c: Fix issue with replace option and replaced data always being placed at the beginning of the packet. * src/dynamic-preprocessors/ftptelnet/pp_ftp.c: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: Fix issue with parsing default server configuration on Win32 platform. * src/dynamic-preprocessors/smtp/smtp_config.c: * src/dynamic-preprocessors/smtp/smtp_util.c: * src/dynamic-preprocessors/smtp/smtp_util.h: * src/dynamic-preprocessors/smtp/snort_smtp.c: * src/dynamic-preprocessors/smtp/snort_smtp.h: * src/preprocessors/str_search.c: * src/preprocessors/str_search.h: Fix potential read beyond end of buffer and update configuration to use less memory. * src/preprocessors/spp_stream4.c: Fix reassembly issue. * src/preprocessors/snort_httpinspect.c: * src/preprocessors/HttpInspect/client/hi_client.c: * src/preprocessors/HttpInspect/include/hi_ui_config.h: * src/preprocessors/HttpInspect/user_interface/hi_ui_config.c: Handle additional whitespace characters on a per server configured basis. Defaults are to treat Htab (\t, 9), VTab (\v, 11), Form Feed (\f, 12), and CR (\r, 13) as whitespace. * src/sfutil/ipobj.c: Revise IP list parsing code. 2006-05-31 Steven Sturges * src/inline.c: Update to handle signals received when no traffic is flowing when snort is compiled with inline ipq. Thanks Victor Julien for the patch. * configure.in: Fix issue with using postgresql and dynamic plugins. Thanks Nikns Siankin for pointing out the issue. * src/sfutil/ipobj.c: Fix problem when parsing multiple hosts in an IP list. 2006-05-24 Steven Sturges * etc/gen-msg.map: * src/generators.h: * src/preprocessors/spp_stream4.c: Fix potential evasion in Stream4. Thanks Brandon Franklin for the find. * src/snort.c: * src/parser.c: * src/dynamic-plugins/sf_engine/bmh.c: * src/preprocessors/HttpInspect/utils/hi_util_hbm.c: * src/preprocessors/flow/flow_cache.c: * src/preprocessors/flow/portscan/flowps_snort.c: * src/sfutil/acsmx2.c: * src/sfthreshold.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.c: * src/output-plugins/spo_log_tcpdump.c: * src/preprocessors/spp_perfmonitor.c: * src/preprocessors/spp_sfportscan.c: * src/preprocessors/spp_stream4.c: * src/preprocessors/flow/portscan/server_stats.c: * src/preprocessors/flow/portscan/server_stats.h: Further code review cleanup. Cleanup possible null pointer dereferences, memory leaks, etc. * src/preprocessors/HttpInspect/client/hi_client.c: Fix to HttpInspect to check for non-RFC whitespace (ie, CR) after URI. Thanks to Blake Hartstein for mentioning the problem. 2006-05-17 Steven Sturges * src/detection-plugins/sp_rpc_check.c: * src/dynamic-plugins/sf_engine/bmh.c: * src/dynamic-plugins/sf_engine/bmh.h: * src/preprocessors/spp_sfportscan.c: * src/preprocessors/HttpInspect/user_interface/hi_ui_iis_unicode_map.c: * src/preprocessors/HttpInspect/utils/hi_util_hbm.c: * src/sfutil/acsmx.c: * src/sfutil/event_wrapper.c: * src/sfutil/mwm.c: * src/sfutil/sfthd.c: Further code review cleanup. Cleanup possible null pointer dereferences, memory leaks, etc. * src/decode.h: * src/preprocessors/spp_frag2.c: * src/preprocessors/spp_frag3.c: * src/preprocessors/spp_sfportscan.c: * src/preprocessors/spp_stream4.c: Move SPARC_TWIDDLE to common place. 2006-05-12 Steven Sturges * doc/snort_manual.tex: * doc/snort_manual.pdf: * doc/README.sfportscan: Proofreading updates. * src/preprocessors/spp_perfmonitor.c: * src/preprocessors/perf.c: * src/preprocessors/perf.h: Correctly close performance stats file on HUP and exit. * src/snort.c: * src/snort.h: * configure.in: Signal handler updates for SEGV and HUP. Define CATCHSEGV in snort.c to trap segv signals. Can also define NOCOREFILE to prevent snort from leaving a core file on receipt of a segv. * src/parser.c: Fix variable definition parsing code to handle user supplied value if variable isn't defined. Thanks to Jeremey Hewlett for pointing out the problem. * src/snort.c: * src/detection-plugins/sp_session.c: * src/dynamic-preprocessors/ftptelnet/ftpp_si.c: * src/output-plugins/spo_csv.c: * src/output-plugins/spo_unified.c: * src/preprocessors/perf.c: * src/preprocessors/perf.h: * src/preprocessors/spp_frag3.c: * src/preprocessors/spp_perfmonitor.c: * src/preprocessors/spp_stream4.c: * src/preprocessors/HttpInspect/utils/hi_util_kmap.c: * src/sfutil/mwm.c: Further code review cleanup. Cleanup possible null pointer dereferences, memory leaks, etc. 2006-05-01 Steven Sturges * rpm/snort.spec: * etc/snort.conf: Include a default path for the dynamicpreprocessors and engine. * src/detect.c: * src/parser.c: * src/pcrm.c: * src/sfthreshold.c: * src/dynamic-preprocessors/ftptelnet/hi_util_kmap.c: * src/output-plugins/spo_csv.c: * src/output-plugins/spo_database.c: * src/output-plugins/spo_log_tcpdump.c: * src/output-plugins/spo_unified.c: * src/preprocessors/spp_perfmonitor.c: * src/preprocessors/spp_stream4.c: * src/preprocessors/HttpInspect/user_interface/hi_ui_iis_unicode_map.c: * src/preprocessors/HttpInspect/utils/hi_util_kmap.c: * src/preprocessors/flow/flow_cache.c: * src/preprocessors/flow/portscan/server_stats.c: * src/sfutil/ipobj.c: * src/sfutil/mpse.c: * src/sfutil/sfghash.c: * src/sfutil/sfksearch.c: * src/sfutil/sfxhash.c: Code review cleanup. Cleanup possible null pointer dereferences, memory leaks, etc. Thanks to Adam Keeton (and welcome to the project)! 2006-04-27 Steven Sturges * RELEASE.NOTES: Add information about memory consumption with pattern matching engines. * doc/snort_manual.tex: * doc/snort_manual.pdf: Update to list all options for pattern matching and note that Wu-Manber is going to be deprecated. * src/util.c: Update output info to account for packets buffered by pcap but not yet received by snort. Corrected protocol breakdown. * src/output-plugins/spo_database.c: Update to correctly strip timestamp precision for MySQL. Thanks Axton Grams for the patch and Nikns Siankin and Vlatko Kosturjak for testing. Update to handle when interface isn't specified in config or commandline (finial initialization done post PCAP initialization). Thanks Jonathan Miner for pointing out the problem. * schemas/create_db2: Updated to include gid in schema and version 107 to match the other schemas. Thanks Vlatko Kosturjak for the update. * src/preprocessors/str_search.c: * src/preprocessors/str_search.h: Fix compilation problems with Sun CC and others that support C99 standard. Thanks Chris Kern for noticing the problem. * src/preprocessors/spp_stream4.c: * src/sfutil/acsmx2.h: Fix compilation problems with Sun CC compiler. 2006-04-11 Steven Sturges * src/fpdetect.c: * src/profiler.h: * src/rules.h: * src/detection-plugins/sp_flowbits.c: Update rule performance profiling to handle flowbits:noalert option correctly (it is a match even though there wasn't an alert). * src/output-plugins/spo_database.c: Updates to be ANSI SQL compiliant. Thanks Vlatko Kosturjak for the updates. * src/preprocessors/spp_stream4.c: Fix incorrectly ignored Reset packets with overlapped/retransmitted data. * src/inline.c: * src/preprocessors/spp_stream4.c: * src/preprocessors/stream.h: * src/preprocessors/stream_api.h: Allow retransmitted packets through in inline mode if they have not been ACK'd by other side. 2006-03-29 Steven Sturges * src/dynamic-preprocessors/ftptelnet/pp_ftp.c: Do not check beyond 4 characters for an FTP command. * src/dynamic-preprocessors/smtp/snort_smtp.c: Free SMTP session memory. * src/preprocessors/spp_stream4.c: * src/preprocessors/stream.h: Updates to previous checks for duplicate alerts. Better performance. Fix cleanup when stream is flushed. 2006-03-24 Steven Sturges * src/snort.c: Update to fix signal handling issue with libprelude and to disable segv signal handler when compiled for Debug mode. * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: Display warnings with configurations that are required for other detection capabilities (ie, normalization is required for ayt threshold and encryption detection). * src/dynamic-preprocessors/smtp/smtp_config.c: Clear default ports if ports are specified. Correctly handle specifying valid commands as invalid. * src/dynamic-preprocessors/smtp/snort_smtp.c: Fix alerts possibly giving incorrect information. Move debug code inside DEBUG ifdef; fix possible SEGV in debug code. Disable detection for to-be-rebuilt packets. * src/preprocessors/spp_frag3.c: Correctly calculate the number of preallocated frags when preallocating based on a memory limit. * configure.in: * src/snort.c: Remove pcap_setnonblock() call. Was causing performance problems on certain OSs. Reverts change made with previous checkins. * src/preprocessors/spp_stream4.c: * src/preprocessors/stream.h: * src/preprocessors/stream_api.h: * src/fpdetect.c: Fix potential issue for duplicate alerts on the same data in the original packet and the Stream reassembled packet. * doc/snort_manual.tex: * doc/snort_manual.pdf: Proofreading... 2006-03-15 Steven Sturges * schemas/create_mssql: * schemas/create_mysql: * schemas/create_oracle.sql: * schemas/create_postgresql: Updated to include gid in schemas. Schema version 107. Thanks Nikns Siankin for the updates and all the testing. * src/profiler.h: Add support for AMD processor. Thanks Alex Kirk for trying this out. * configure.in: * src/snort.c: Use pcap_setnonblock() if available to help with snort exiting on SIGTERM (and others) when no traffic is flowing. * src/decode.c: Fix pflog decoding for OpenBSD platforms. * src/dynamic-plugins/sf_engine/Makefile.am: * doc/INSTALL: Updates for FreeBSD 6.x compilation. Thanks Richard Bejtlich for testing. * doc/snort_manual.tex: * doc/snort_manual.pdf: Fixed a few typos and added a warning about the to be deprecated telnet decode preprocessor. 2006-03-07 Steven Sturges * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: Fixed potential segfault condition in stateless mode. * src/preprocessors/spp_frag3.c: Added Fatal error messages for unknown config options. * src/snort.c: * src/preprocessors/spp_perfmonitor.c: Code cleanup 2006-03-02 Steven Sturges * configure.in: * src/output-plugins/spo_alert_prelude.c: Additional fixes from Yoann Vandoorselaere. Require libprelude version 0.9.6. * src/preprocessors/spp_perfmonitor.c: Initialize the pcap counters the first time we get a packet. * src/fpdetect.c: Fix leaking of classification info between rules and preprocessor/decoder alerts. 2006-02-28 Steven Sturges * src/dynamic-preprocessors/Makefile.am: Install required header files when --enable-dynamicplugin used with configure. * src/preprocessors/spp_stream4.c: If ignoring a packet because it is a duplicate (retransmitted), drop it if in inline mode. Original packet was either dropped or passed through. 2006-02-27 Steven Sturges * src/detection-plugion/sp_flowbits.c: Update parsing to handle spaces and correct keyword checking. 2006-02-23 Steven Sturges * src/snort.c: * src/snort.h: * src/fpdetect.c: * src/parser.c: * src/event_queue.h: * doc/README: * doc/snort_manual.tex: * doc/snort_manual.pdf: * snort.8: Changed command line options --flush-all-events to --process-all-events and --alert-on-drop to --treat-drop-as-alert. Updated docs/manpage. * src/output-plugins/spo_unified.c: Fix unified log file rollover to correctly write magic numbers. * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: * src/dynamic-preprocessors/ftptelnet/ftp_bounce_lookup.c: Update some comments relative to endianness. * src/dynamic-preprocessors/smtp/snort_smtp.c: * src/dynamic-preprocessors/smtp/spp_smtp.c: Fix issues with SMTP preprocessor causing rules to not fire. Thanks Andy Mullican for the fix. 2006-02-22 Steven Sturges * src/preprocessors/spp_frag3.c: * doc/README.frag3: Added option to preallocate frags based on a memcap (combination of memcap and prealloc_frags options). Perform preallocation post-pcap open because of memory issues with certain versions of pcap. 2006-02-21 Steven Sturges * src/output-plugins/spo_alert_prelude.c: packet_to_data() Standardize AdditionalData fields name. Support more packet fields, remove unused one. Send rule revision and TCP/IP options code/value as AdditionalData. Thanks Yoann Vandoorselaere for the updates. event_to_reference() Double check that system->url is not NULL. Support ICMP headers, patch from Andrea Barisani. * src/snort.c: * src/snort.h: * src/util.c: Updates to signal handlers to better deal with reentrant issues in syslog and libc. * src/dynamic-plugins/sf_dynamic_plugins.c: Print warning if dynamic library directory doesnt exist or is empty. Thanks Andy Mullican for the fix. 2006-02-20 Steven Sturges * src/sfutil/sfeventq.c: Fix issue when more than max events are added to event queue. * src/parser.c: * src/plugbase.c: * src/plugbase.h: * src/snort.c: * src/output-plugins/spo_unified.c: * src/output-plugins/spo_log_tcpdump.c: Fix issue with output plugins that depend on datalink and snaplen (which are set in OpenPcap). Caused by reordering of initialization on 2006-01-26. Thanks Matt Bedynek and Jeremy Hewlett for the find. 2006-02-17 Steven Sturges * doc/INSTALL: Updated to include current options and added a section for compilation on MAC OSX. * src/signature.c: Strip whitespaces from reference system and id. This fixes a reference lookup problem resulting in an invalid URL in case the reference begins with a space character (example: reference: x,y; would fail). Thanks Yoann Vandoorselaere for the patch. 2006-02-16 Steven Sturges * src/preprocessors/spp_frag3.c: Fix ip options handling. Thanks to Vyacheslav Burdjanadze for finding the issue. * src/dynamicpreprocessors/ftptelnet/snort_ftptelnet.c: Fix processing of configuration without options. * src/snort.c: Fix OpenPcap merge issue. 2006-02-15 Steven Sturges * doc/snort_manual.tex: * doc/snort_manual.pdf: Update perfmonitor section. Thanks to Passreality for pointing out the omissions. * src/preprocessors/spp_stream4.c: Only increment memory counter once per allocation. 2006-02-14 Steven Sturges * doc/snort_manual.tex: * doc/snort_manual.pdf: Updates to manual for 2.6.0 * src/win32/WIN32-Prj/snort.dsp: Added missing files. 2006-02-13 Steven Sturges * src/parser.c: Handle longer lines for config * src/sfutil/acsmx2.c: Change visual name of Aho-Corasick sparse bands. * src/preprocessors/spp_frag3.c: When a timeout occurs on a Fragmented session, purge the existing fragments and treat it as a new session. Allows for proper defragmentation, per OS target configuration. 2006-02-09 Steven Sturges * src/util.c: Fix -M flag to log Fatal and regular Error messages to syslog as well. Thanks Andy Mullican. * snort.8: * doc/README: * src/snort.c: Add info on additional commandline switches. * src/preprocessors/spp_stream4.c: Fix compilation issue on some platforms. 2006-02-08 Steven Sturges * src/parser.c: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: * src/dynamic-preprocessors/ftptelnet/spp_ftptelnet.c: Allow default configuration without options 2006-02-06 Steven Sturges * etc/snort.conf: * src/dynamic-examples/dynamic-preprocessor/Makefile.am: * src/dynamic-examples/dynamic-rule/Makefile.am: * src/dynamic-plugins/sf_engine/Makefile.am: * src/dynamic-preprocessors/ftptelnet/Makefile.am: * src/dynamic-preprocessors/smtp/Makefile.am: Add info to snort.conf on how to load dynamic libraries and update Makefiles to use path similar t othat of snort.conf. * src/parser.c: Fixed error message when dynamic token is used. 2006-02-03 Steven Sturges * src/dynamic-examples/dynamic-preprocessor/Makefile.am: * src/dynamic-examples/dynamic-rule/Makefile.am: * src/dynamic-plugins/sf_engine/Makefile.am: * src/dynamic-preprocessors/ftptelnet/Makefile.am: * src/dynamic-preprocessors/smtp/Makefile.am: * src/dynamic-plugins/sf_dynamic_plugins.c: Fix installation directories * src/preprocessors/Makefile.am: * src/preprocessors/stream_api.h: * src/preprocessors/stream_api.c: Fixes for MacOS X compilation. 2006-02-02 Steven Sturges * src/detect.c: * src/event_queue.c: * src/event_queue.h: * src/fpdetect.c: * src/parser.c: * src/snort.c: * src/snort.h: * src/sfutil/sfeventq.c: Changed rule ordering to better handle drop and pass rules when other alerts trigger on the same packet. Thanks Marc Norton for the changes. * src/profiler.c: * src/profiler.h: * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.h: Win32 fixes. * src/snort.c: Fix SigHup processing. * src/util.c: Code Cleanup. * src/detection-plugins/sp_pattern_match.c: Return non-zero when search goes out-of-bounds. * src/preprocessors/snort_httpinspect.c: Fix from Chris Sherwin for pipelined requests. * src/preprocessors/spp_frag3.c: Change noisy LogMessage to Debug. 2006-01-30 Steven Sturges * src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c: * src/dynamic-plugins/sf_engine/sf_snort_packet.h: * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.h: Include config.h if required. * configure.in: * src/Makefile.am: * src/dynamic-examples/.cvsignore: * src/dynamic-examples/Makefile.am: * src/dynamic-examples/dynamic-preprocessor/.cvsignore: * src/dynamic-examples/dynamic-preprocessor/Makefile.am: * src/dynamic-examples/dynamic-preprocessor/sf_preproc_info.h: * src/dynamic-examples/dynamic-preprocessor/spp_example.c: * src/dynamic-examples/dynamic-rule/.cvsignore: * src/dynamic-examples/dynamic-rule/Makefile.am: * src/dynamic-examples/dynamic-rule/detection_lib_meta.h: * src/dynamic-examples/dynamic-rule/rules.c: * src/dynamic-examples/dynamic-rule/sid109.c: * src/dynamic-examples/dynamic-rule/sid637.c: Added examples for manual of dynamic preprocessor and dynamic rule library. * src/dynamic-preprocessors/ftptelnet/Makefile.am: * src/dynamic-preprocessors/smtp/Makefile.am: More fixes to cleanup. 2006-01-26 Steven Sturges * src/preprocessors/spp_stream4.c: Fixed a few retranmission alerts that are not toggled off by diasble_evasion_alerts config. * src/parser.c: * src/snort.c: * src/snort.h: * src/util.c: * src/util.h: Addressed some startup issues when running daemon mode. Configuration is validated prior to daemonizing, therefore if config errors exist, snort will exit, returning error to initialization script/process. Parent process doesn't exit until config file is read and a child is forked and has created its pid file. Thanks to Marc Norton and Chris Sherwin for their work on this. Fixed issue with opening pcap prior to reading it from a config file. Thanks Martin Olsson for noting this. * src/dynamic-preprocessors/Makefile.am: * src/dynamic-preprocessors/smtp/Makefile.am: * src/dynamic-preprocessors/ftptelnet/Makefile.am: Fixed builds on FreeBSD. 2006-01-24 Steven Sturges * src/win32/Makefile.am: Win32 Updates. * doc/Makefile.am: Added files. * src/win32/WIN32-Prj/snort.dsp: Removed deprecated src files. * src/win32/WIN32-Prj/snort_installer.nsi: Added dynamic modules, updated version number. 2006-01-23 Steven Sturges * src/preprocessors/spp_flow.c: Fixed error message when parsing flow configuration. * src/snort.c: * src/snort.h: Fixed issue with creating PID files. * src/util.c: Fixed issue with DropStats and unopened pcap. * src/Makefile.am: * src/dynamic-plugins/Makefile.am: * src/dynamic-plugins/sf_engine/Makefile.am: * src/dynamic-preprocessors/Makefile.am: * src/dynamic-preprocessors/smtp/Makefile.am: * src/dynamic-preprocessors/ftptelnet/Makefile.am: * src/sfutil/Makefile.am: Updates to handle make dist and make distcheck. Win32 Updates. 2006-01-20 Steven Sturges * schemas/create_mysql: * src/output-plugins/spo_database.c: Updated to write GID when logging events. Thanks to Graham Keeling for the patch and Kevin Johnson for helping test. * src/snort.c: * doc/README: * snort.8: Added info on new command line options. * src/snort.c: Updated CreatePidFile to use interface name if available when in inline mode (and using a bridging interface). 2006-01-19 Steven Sturges * src/util.c: Updated Timestats to print packet stats per hour and breakdown per protocol. Thanks Bill Parker for the update. To use this feature, use --enable-timestats. * src/sfutil/sfthd.c: Fix parameter ordering in test routine. Thanks Yin Zhaohui for the find. * src/detect.c: Fixed DEBUG_WRAP statement. Thanks Yin Zhaohui for pointing this out. 2006-01-19 Steven Sturges * autojunk.sh: * configure.in: Added use of libtool to build dynamically loadable modules, --enable-dynamicplugin. Added performance profiling, --enable-perfprofiling. Added separation of rules being enabled from them appearing in snort.conf, --enable-rulestate. Added pthread linkage, --enable-pthread. * src/win32/WIN32-Prj/snort.dsp: * src/win32/WIN32-Prj/snort.dsw: * src/win32/WIN32-Prj/build_all.dsp: Added dynamically loadable modules and updated workspace for other project files (new preprocessors, DLLs, and utility project to build everything). * RELEASE.NOTES: * doc/Makefile.am: * doc/README: Updated for new files and 2.6.0 release preparation. * doc/README.PerfProfiling: * src/profiler.c: * src/profiler.h: Added performance profiling metrics. Can measure both rules and preprocessor performance. Enable via --enable-perfprofiling. See profiler.h for MACROs to use and various preprocessors for examples. * doc/README.SMTP: * src/dynamic-preprocessors/smtp/.cvsignore: * src/dynamic-preprocessors/smtp/Makefile.am: * src/dynamic-preprocessors/smtp/sf_preproc_info.h: * src/dynamic-preprocessors/smtp/sf_smtp.dsp: * src/dynamic-preprocessors/smtp/smtp_config.c: * src/dynamic-preprocessors/smtp/smtp_config.h: * src/dynamic-preprocessors/smtp/smtp_log.c: * src/dynamic-preprocessors/smtp/smtp_log.h: * src/dynamic-preprocessors/smtp/smtp_normalize.c: * src/dynamic-preprocessors/smtp/smtp_normalize.h: * src/dynamic-preprocessors/smtp/smtp_util.c: * src/dynamic-preprocessors/smtp/smtp_util.h: * src/dynamic-preprocessors/smtp/smtp_xlink2state.c: * src/dynamic-preprocessors/smtp/smtp_xlink2state.h: * src/dynamic-preprocessors/smtp/snort_smtp.c: * src/dynamic-preprocessors/smtp/snort_smtp.h: * src/dynamic-preprocessors/smtp/spp_smtp.c: * src/dynamic-preprocessors/smtp/spp_smtp.h: * src/preprocessors/spp_xlink2state.c (removed): * src/preprocessors/spp_xlink2state.h (removed): * src/preprocessors/xlink2state.c (removed): * src/preprocessors/xlink2state.h (removed): Added dynamically loadable SMTP preprocessor. Thanks Andy Mullican for the work and research. Renders xlink2state mini preprocessor defunct. * doc/README.ftptelnet: * src/dynamic-preprocessors/ftptelnet/.cvsignore: * src/dynamic-preprocessors/ftptelnet/Makefile.am: * src/dynamic-preprocessors/ftptelnet/ftp_bounce_lookup.c: * src/dynamic-preprocessors/ftptelnet/ftp_bounce_lookup.h: * src/dynamic-preprocessors/ftptelnet/ftp_client.h: * src/dynamic-preprocessors/ftptelnet/ftp_cmd_lookup.c: * src/dynamic-preprocessors/ftptelnet/ftp_cmd_lookup.h: * src/dynamic-preprocessors/ftptelnet/ftp_server.h: * src/dynamic-preprocessors/ftptelnet/ftpp_eo.h: * src/dynamic-preprocessors/ftptelnet/ftpp_eo_events.h: * src/dynamic-preprocessors/ftptelnet/ftpp_eo_log.c: * src/dynamic-preprocessors/ftptelnet/ftpp_eo_log.h: * src/dynamic-preprocessors/ftptelnet/ftpp_include.h: * src/dynamic-preprocessors/ftptelnet/ftpp_return_codes.h: * src/dynamic-preprocessors/ftptelnet/ftpp_si.c: * src/dynamic-preprocessors/ftptelnet/ftpp_si.h: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_client_lookup.c: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_client_lookup.h: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_config.c: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_config.h: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_server_lookup.c: * src/dynamic-preprocessors/ftptelnet/ftpp_ui_server_lookup.h: * src/dynamic-preprocessors/ftptelnet/ftpp_util_kmap.h: * src/dynamic-preprocessors/ftptelnet/hi_util_kmap.c: * src/dynamic-preprocessors/ftptelnet/hi_util_kmap.h: * src/dynamic-preprocessors/ftptelnet/hi_util_xmalloc.c: * src/dynamic-preprocessors/ftptelnet/hi_util_xmalloc.h: * src/dynamic-preprocessors/ftptelnet/pp_ftp.c: * src/dynamic-preprocessors/ftptelnet/pp_ftp.h: * src/dynamic-preprocessors/ftptelnet/pp_telnet.c: * src/dynamic-preprocessors/ftptelnet/pp_telnet.h: * src/dynamic-preprocessors/ftptelnet/sf_ftptelnet.dsp: * src/dynamic-preprocessors/ftptelnet/sf_preproc_info.h: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.c: * src/dynamic-preprocessors/ftptelnet/snort_ftptelnet.h: * src/dynamic-preprocessors/ftptelnet/spp_ftptelnet.c: * src/dynamic-preprocessors/ftptelnet/spp_ftptelnet.h: * src/preprocessors/spp_telnet_negotiation.c: Added dynamically loadable FTP/Telnet preprocessor. Thanks Steven Sturges for the work and research. Replaces telnet decoder. * doc/README.sfportscan: * src/preprocessors/spp_sfportscan.c: Updated for preprocessor protocol ordering. Added performance measurements. Added ACK scan detection and false positive prevention with sessions picked up midstream and dropped packets. * etc/gen-msg.map: * etc/generators: * src/generators.h: Added generator IDs for new preprocessors. * etc/snort.conf: Added examples for new preprocessors * src/Makefile.am: Added performance metric modules, new subdirs. * src/build.h: Seperated build version from snort.h. * src/debug.h: Added new preprocessors. * src/decode.c: * src/detect.c: Performance measurments of packet decoder, detection, rule evaluation and preprocessors. * src/decode.h: * src/detect.h Change to use dynamicly sized preprocessor array since more than 32 preprocessors may be loaded. * src/inline.c: * src/inline.h: Updated to always set drop flag for packets that are dropped for logging purposes. * src/plugbase.c: * src/plugbase.h: * src/plugin_enum.h: * src/preprocids.h: Support for new preprocessors, added checks to verify preprocessor configuration. Removed deprecated preprocessors. Added cleanup and shutdown functionality for preprocessors. Move preprocessor bitmasks from plugbase.h into preprocids.h. Added protocol stack based ordering of preprocessors, so that IP-layer preprocessors are run before TCP/UDP layer ones. * src/snort.c: * src/snort.h: Added longname option support. Added dynamic module commandline options, see README for details. Updated signal handling and exit/restart code. Switched to using pcap_dispatch from pcap_loop for better control of packet processing. Added performance measurements. Fixed -T flag and commandline help functionality. Added -M flag to write messages/warnings to syslog (doesn't write alert data there) when not in daemon mode. * src/tag.c: Put limit on tagging to alleviate overloaded databases that result in every packet being tagged on high bandwidth sensors. Prevents database DoS with tagging rules. * src/util.c: * src/util.h: Fixed issue with reentrant signal handlers. At exit because of signal, snort now logs to snort_exit file instead of syslog. Updated pid file creation when in Inline mode. * src/detection-plugins/Makefile.am: * src/detection-plugins/sp_asn1.c * src/detection-plugins/sp_asn1_detect.c: * src/detection-plugins/sp_asn1_detect.h: * src/detection-plugins/sp_urilen_check.c: * src/detection-plugins/sp_urilen_check.h: Modularized ASN1 detection code. Added URI Length check rule keyword. Thanks to Chris Sherwin for the new functionality. * src/dynamic-plugins/.cvsignore: * src/dynamic-plugins/Makefile.am: * src/dynamic-plugins/sf_dynamic_common.h: * src/dynamic-plugins/sf_dynamic_detection.h: * src/dynamic-plugins/sf_dynamic_engine.h: * src/dynamic-plugins/sf_dynamic_meta.h: * src/dynamic-plugins/sf_dynamic_plugins.c: * src/dynamic-plugins/sf_dynamic_preprocessor.h: * src/dynamic-plugins/sp_dynamic.c: * src/dynamic-plugins/sp_dynamic.h: * src/dynamic-plugins/sp_preprocopt.c: * src/dynamic-plugins/sp_preprocopt.h: * src/dynamic-plugins/sf_engine/.cvsignore: * src/dynamic-plugins/sf_engine/Makefile.am: * src/dynamic-plugins/sf_engine/bmh.c: * src/dynamic-plugins/sf_engine/bmh.h: * src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c: * src/dynamic-plugins/sf_engine/sf_snort_packet.h: * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_api.h: * src/dynamic-plugins/sf_engine/sf_snort_plugin_byte.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_content.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_hdropts.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_loop.c: * src/dynamic-plugins/sf_engine/sf_snort_plugin_pcre.c: * src/win32/WIN32-Prj/sf_engine.dsp: * src/rules.h: Added dynamically loadable rule detection capability. Can write compiled rules that are "blackboxed", yet still loaded at runtime. Thanks Andy Mullican, Steven Sturges and Marc Norton. * src/fpcreate.c: * src/fpcreate.h: * src/fpdetect.c: Performance measurments, added support for dynamic rule detection, and fix issue with non-content rules not being evaluated. * src/parser.c: * src/parser.h: Added dynamic rule and preprocessor parsing, rule state parsing, performance profiling parsing. * src/signature.c: * src/signature.h: Added 'gid' and 'metadata' fields to rules. * src/detection-plugins/sp_pcre.c: Provide ability to turn off PCRE checks via config nopcre. * src/dynamic-plugins/sf_preproc_example/sf_dynamic_preproc_lib.c: * src/dynamic-plugins/sf_preproc_example/sf_dynamic_preproc_lib.h: * src/dynamic-preprocessors/.cvsignore: * src/dynamic-preprocessors/Makefile.am: * src/dynamic-preprocessors/dynamic_preprocessors.dsp: * src/dynamic-preprocessors/initialize_headers.sh: * src/dynamic-preprocessors/sf_dynamic_initialize/.cvsignore: * src/dynamic-preprocessors/sf_dynamic_initialize/sf_dynamic_initialize.dsp: Added dynamically loadable preprocessor support. Simplifies development of preprocessors for quicker release of new preprocessor code. Thanks Andy Mullican, Steven Sturges and Marc Norton. * src/preprocessors/perf-base.c: * src/preprocessors/perf-base.h: * src/preprocessors/perf.c: Added metric for inline blocked packets. * src/preprocessors/perf-flow.c: * src/preprocessors/perf-flow.h: Added better performance tracking for flow data for ports under 1024 and those above. * src/preprocessors/portscan.c: Added code to ignore certain ports. Added performance measurements. * src/preprocessors/snort_httpinspect.c: Updated for stream API. Added performance measurements. * src/preprocessors/spp_frag2.c: Updated for preprocessor protocol ordering. To be deprecated in next release. Added performance measurements. * src/preprocessors/spp_arpspoof.c: * src/preprocessors/spp_bo.c: * src/preprocessors/spp_flow.c: * src/preprocessors/spp_frag3.c: * src/preprocessors/spp_httpinspect.c: * src/preprocessors/spp_perfmonitor.c: * src/preprocessors/spp_rpc_decode.c: * src/preprocessors/spp_sfportscan.c: Updated for preprocessor protocol ordering. Added performance measurements. * src/preprocessors/Makefile.am: * src/preprocessors/spp_portscan.c (removed): * src/preprocessors/spp_portscan.h (removed): * src/preprocessors/spp_portscan2.c (removed): * src/preprocessors/spp_portscan2.h (removed): * src/preprocessors/spp_conversation.c (removed): * src/preprocessors/spp_conversation.h (removed): Deprecated old portscan preprocessors. * src/preprocessors/str_search.c: * src/preprocessors/str_search.h: Modularized this code for use by the dynamic SMTP preprocessor. * src/detection-plugins/sp_flowbits.c: * src/detection-plugins/sp_flowbits.h: * src/event_wrapper.c: * src/output-plugins/spo_alert_sf_socket.c: * src/output-plugins/spo_log_tcpdump.c: * src/output-plugins/spo_unified.c: * src/preprocessors/stream.h: * src/preprocessors/stream_api.h: * src/preprocessors/stream_ignore.c: * src/preprocessors/stream_ignore.h: * src/preprocessors/snort_stream4_session.c: * src/preprocessors/spp_stream4.c: * src/preprocessors/spp_stream4.h: Added api for Stream4 to help with development of next generation Stream processing. Flowbits are now stored as part of the Stream. Updated output plugins to use Stream api for logging reassembled packets. Added performance measurements. * src/sfutil/Makefile.am: * src/sfutil/getopt.h: * src/sfutil/getopt1.h: * src/sfutil/getopt_long.c: Added longname commandline option support. * src/sfutil/ipobj.c: * src/sfutil/ipobj.h: Updated IP Set to include port sets. * src/sfutil/mpse.c: Added performance measurements. * src/snort_packet_header.h: * src/win32/WIN32-Includes/libnet/gnuc.h: * src/debug.c: * src/detection-plugins/sp_pattern_match.c: * src/output-plugins/spo_alert_prelude.c: * src/preprocessors/flow/flow_cache.c: * src/preprocessors/flow/portscan/flowps.c: * src/preprocessors/flow/portscan/flowps_snort.c: * src/preprocessors/flow/portscan/server_stats.c: * src/sfutil/bitop.h: * src/sfutil/bitop_funcs.h: * src/sfutil/mwm.h: * src/sfutil/sfghash.h: * src/sfutil/sfksearch.c: * src/sfutil/sfksearch.h: * src/.cvsignore: Misc code cleanup. 2006-01-09 Steven Sturges * src/sfutil/mwm.c: Fixed bug with multiple recurring patterns in Wu-Manbher implementation. Thanks to Evan Stawnyczy for pointing it out and Marc Norton for the fix. * src/parser/IpAddrSet.c: Fixed problem with parsing conf file and rules when DNS is not working. Thanks Martin Olsson for mentioning this and testing the fix. * src/preprocessors/spp_perfmonitor.c: * src/preprocessors/perf-base.c: Handle wrapping on 64-bit platforms 2005-11-17 Andrew Mullican * src/sfutil/sfxhash.c: * src/preprocessors/portscan.c: Add tracker without using bogus data, to avoid internal buffer overrun. Thanks Sandro Poppi for the find. 2005-11-11 Steven Sturges * src/snort.c: Allow value of 0 to be used with -G flag * src/preprocessors/spp_bo.c: Code Cleanup * src/preprocessors/spp_frag3.c: Fix memory leak and mishandling of IP Options. Thanks Yin Zhaohui for the find. 2005-10-16 Steven Sturges * etc/gen-msg.map: * etc/snort.conf: * src/generators.h: * src/preprocessors/spp_bo.c: Fixed potential buffer overflow in BackOrifice preprocessor and added an alert on attempt to overflow buffer in snort. Thanks Andy Mullican for the fix. 2005-10-11 Steven Sturges * src/win32/WIN32-Prj/snort_installer.nsi: Updated to mention WinPCAP 3.1 with correct website. Thanks Gianluca Varenni for mentioning the discrepancy. 2005-10-04 Steven Sturges * src/win32/WIN32-Libraries/libnet/LibnetNT.lib: * src/win32/WIN32-Prj/LibnetNT.dll: Rebuilt and updated LibnetNT linked with WinPCAP 3.1. 2005-09-23 Steven Sturges * src/output-plugins/spo_log_database.c: * schemas/create_mysql: Fixes to address schema being a keyword in MySQL 5.0. Thanks Wes Young, Adolfo Gomez, and Aleem Mawji for the updates. 2005-09-19 mfr * src/output-plugins/spo_log_tcpdump.c: don't try to actually open the log file when in test mode 2005-09-19 Steven Sturges * src/win32/WIN32-Includes/NETINET/IP.H: * src/win32/WIN32-Includes/NETINET/IP_VAR.H: * src/win32/WIN32-Includes/libnet/LibnetNT.h: Always use winsock2.h 2005-09-16 mfr * src/snort.c: New command line switch, -K, to explicitly set logging mode. Available arguments are "none", "pcap" and "ascii". Pcap mode is now the default logging mode of Snort. CheckLogDir() is no longer called in IDS mode until after reading in the snort.conf file to prevent unncessary exiting due to logdir being specified in snort.conf and inadvertantly checking for the existence of /var/log/snort. * src/util.c: Included CheckLogDir() call in CreatePidFile() on the off chance we have to fall back to using pv.log_dir which can happen due to the IDS mode logdir check being removed in src/snort.c * src/decode.c: Added check for bad length of TCP SACK option. * snort.8: Updated for -K command line switch * doc/README: Updated for new command line options and default logging mode. 2005-09-16 Steven Sturges * src/preprocessors/spp_frag3.c: Additional fixes to better handle various targets and extensions to the Shankar/Paxson model. Thanks Judy Novak for all of the OS testing & pcap work. 2005-09-14 Andrew Mullican * etc/gen-msg.map * src/generators.h * src/preprocessors/spp_rpc_decode.c: Added new alert on zero-length RPC fragment. 2005-09-14 Steven Sturges * src/win32/WIN32-Includes/pcap-namedb.h (removed): * src/win32/WIN32-Includes/pcap.h (removed): * src/win32/WIN32-Includes/WinPCAP/Devioctl.h: * src/win32/WIN32-Includes/WinPCAP/Gnuc.h: * src/win32/WIN32-Includes/WinPCAP/Ntddndis.h: * src/win32/WIN32-Includes/WinPCAP/Ntddpack.h: * src/win32/WIN32-Includes/WinPCAP/Packet32.h: * src/win32/WIN32-Includes/WinPCAP/Win32-Extensions.h: * src/win32/WIN32-Includes/WinPCAP/bittypes.h: * src/win32/WIN32-Includes/WinPCAP/bucket_lookup.h: * src/win32/WIN32-Includes/WinPCAP/count_packets.h: * src/win32/WIN32-Includes/WinPCAP/ip6_misc.h: * src/win32/WIN32-Includes/WinPCAP/memory_t.h: * src/win32/WIN32-Includes/WinPCAP/normal_lookup.h: * src/win32/WIN32-Includes/WinPCAP/pcap-bpf.h: * src/win32/WIN32-Includes/WinPCAP/pcap-int.h: * src/win32/WIN32-Includes/WinPCAP/pcap-stdinc.h: * src/win32/WIN32-Includes/WinPCAP/pcap.h: * src/win32/WIN32-Includes/WinPCAP/pthread.h: * src/win32/WIN32-Includes/WinPCAP/remote-ext.h: * src/win32/WIN32-Includes/WinPCAP/sched.h: * src/win32/WIN32-Includes/WinPCAP/semaphore.h: * src/win32/WIN32-Includes/WinPCAP/tcp_session.h: * src/win32/WIN32-Includes/WinPCAP/time_calls.h: * src/win32/WIN32-Includes/WinPCAP/tme.h: * src/win32/WIN32-Includes/mysql/Libmysql.def (removed): * src/win32/WIN32-Includes/mysql/config-netware.h: * src/win32/WIN32-Includes/mysql/config-os2.h: * src/win32/WIN32-Includes/mysql/config-win.h: * src/win32/WIN32-Includes/mysql/dbug.h (removed): * src/win32/WIN32-Includes/mysql/errmsg.h: * src/win32/WIN32-Includes/mysql/libmysql.def: * src/win32/WIN32-Includes/mysql/libmysqld.def: * src/win32/WIN32-Includes/mysql/m_ctype.h: * src/win32/WIN32-Includes/mysql/m_string.h: * src/win32/WIN32-Includes/mysql/my_alloc.h: * src/win32/WIN32-Includes/mysql/my_dbug.h: * src/win32/WIN32-Includes/mysql/my_getopt.h: * src/win32/WIN32-Includes/mysql/my_global.h: * src/win32/WIN32-Includes/mysql/my_list.h: * src/win32/WIN32-Includes/mysql/my_pthread.h: * src/win32/WIN32-Includes/mysql/my_sys.h: * src/win32/WIN32-Includes/mysql/mysql.h: * src/win32/WIN32-Includes/mysql/mysql_com.h: * src/win32/WIN32-Includes/mysql/mysql_embed.h: * src/win32/WIN32-Includes/mysql/mysql_time.h: * src/win32/WIN32-Includes/mysql/mysql_version.h: * src/win32/WIN32-Includes/mysql/mysqld_error.h: * src/win32/WIN32-Includes/mysql/raid.h: * src/win32/WIN32-Includes/mysql/typelib.h: * src/win32/WIN32-Libraries/Packet.lib: * src/win32/WIN32-Libraries/wpcap.lib: * src/win32/WIN32-Libraries/mysql/mysqlclient.lib: * src/win32/WIN32-Prj/snort.dsp: Updated to use WinPCAP 3.1 and MySql client 4.13. Preparation for Snort 2.4.1 release on Win32. 2005-09-14 Steven Sturges * src/snort.c: Mark -z option as to be deprecated. * src/preprocessors/spp_frag3.c: Fix issue with Teardrop alerts introduced with last update. 2005-09-01 Steven Sturges * src/decode.c: * src/decode.h: Fix snort decoder to correctly handle PPP over Ethernet decoding. Thanks Aristeu Gil Alves Jr for the pcap. * src/snort.c: * src/util.c: * configure.in: Added patch for time stats from Bill Parker. Enable with configure --enable-timestats. * src/snort.c: Do not allow -T (test mode) & -D (daemonize) together. * src/preprocessors/spp_frag3.c: Fix issue with Teardrop alerts. * src/preprocessors/spp_portscan.c: * src/preprocessors/spp_portscan2.c: Add deprecation warning. These will be deprecated in the next snort build. 2005-08-31 Steven Sturges * src/snort.c: * src/decode.c: * src/decode.h: Added decoder for IPEnc for Open BSD. Thanks Jason Ish for the patch (long time ago) and Chris Kuethe for reraising the issue. * src/snort.c: Allow snort to use usernames (-u) and groupnames (-g) that include numbers. Thanks to Shaick for the patch. 2005-08-29 Steven Sturges * src/preprocessors/spp_sfportscan.c: * etc/snort.conf: * doc/README.sfportscan: Change ip_proto to ip for portscan configuration. Thanks David Bianco for pointing this out and Andy Mullican for the updates. * src/snort.c: Fix broken -T option. Thanks Andy Mullican for the fix. * src/output-plugins/spo_alert_prelude.c: Fix for prelude initialization. Thanks Yoann Vandoorselaere for the update. * src/preprocessors/spp_frag3.c: * doc/README.frag3: Update to address Solaris reassembly issues. Update README to include info about new target-based policy. 2005-08-23 Steven Sturges * src/preprocessors/spp_frag3.c: Resolve some issues with handling of overlap conditions, multiple fragments with MoreFrags bit not set and added target based policies for windows and solaris (since they are actually different in certain cases). * src/preprocessors/stream.h: Added data structure padding to fix issues with 64bit Solaris. * src/log.c: Fix problem in sniffer mode when incomplete TCP option data is received. Thanks A Hernandez for the find. * src/decode.c: Set the source & dest ports used for logging before doing checksum verification. If invalid checksum, ports will be logged (even though they may be invalid). Wrapped alerts for same src/dst and loopback in mode==IDS & decoder alert checks. * src/plugbase.h: Use hex values for preprocessor bitmask constants instead of the decimal equivalent. * src/detection-plugins/sp_byte_jump.c: * src/detection-plugins/sp_byte_check.c: Allow for signed offset values to handle negative offset in rules. Fixes potential issue on 64-bit architectures. * src/detection-plugins/sp_pattern_match.c: * src/detection-plugins/sp_pattern_match.h: For content matches, when subsequent rule options fail, start searching again in correct location instead of again at end of the currently found pattern. * src/preprocessors/perf-base.c: * src/preprocessors/perf-base.h: * src/preprocessors/perf.h: * src/preprocessors/snort_httpinspect.c: * src/preprocessors/spp_frag2.c: * src/preprocessors/spp_perfmonitor.c: * src/preprocessors/spp_xlink2state.c: * src/preprocessors/str_search.c: * src/preprocessors/xlink2state.c: * src/sfutil/asn1.c: * src/sfutil/mpse.h: * src/plugbase.c: * src/snort.c: Code/compiler warning cleanup. 2005-08-15 Steven Sturges * src/decode.c: * src/win32/WIN32-Includes/NETINET/IN_SYSTM.H: Updated Win32 to handle pflog patch. 2005-08-15 Steven Sturges * src/output-plugins/spo_alert_prelude.c: * etc/snort.conf: Fix GCC4 warning, make the arguments parser more robust and less fault tolerant. Correct parsing of IDMEF severity mapping. Don't try to initialize Prelude support when 'output alert_prelude' is not specified. Removed deprecated documentation from the conf file. Thanks Yoann Vandoorselaere for the updates. * src/preprocessors/spp_stream4.c: * src/preprocessors/snort_stream4_session.c: * src/preprocessors/stream.h: Fixed problem on Solaris when reassembling at exit. Thanks Andrew Rucker Jones for identifying the issue. * src/decode.c: * src/decode.h: * src/snort.c: Added support for new OpenBSD pflog format. Older pflog format, OpenBSD 3.3 and earlier, is still supported. Thanks Breno Leitao and Christian Reis for the patch. * src/decode.c: * src/decode.h: * src/util.c: Added statistics counter for ETH_LOOPBACK packets. Thanks rmkml for the patch. 2005-07-29 mfr * rpm/snort.spec: Fix epoch inclusion for RPM generation 2005-07-29 Steven Sturges * src/preprocessors/spp_stream4.c: Fixed debug prints for new flush behavior changes. * src/detection-plugins/sp_pattern_match.c: Added checks to ensure some syntax correctness for content rules. Thanks Erik de Castro Lopo for the patch. 2005-07-27 mfr * etc/snort.conf: Changed snort.conf to reflect flush_behavior changes 2005-07-24 mfr * src/preprocessors/spp_stream4.c: Fix parsing problem in the flush_behavior config directive * etc/snort.conf: Turn perfmonitor off by default 2005-07-22 Steven Sturges * src/preprocessors/spp_stream4.c: Changed flush_behavior to use names instead of numeric value. New behaviors names are 'default', 'large_window', and 'random' 2005-07-22 Steven Sturges * src/win32/WIN32-Includes/config.h: Changed Snort version number * src/detection-plugins/sp_pattern_match.c: Fixed error message for replace 2005-07-22 mfr * src/preprocessors/HttpInspect/client/Makefile.am: * src/preprocessors/HttpInspect/event_output/Makefile.am: More cleanup 2005-07-22 mfr * src/preprocessors/HttpInspect/anomaly_detection/Makefile.am: * src/preprocessors/HttpInspect/mode_inspection/Makefile.am: * src/preprocessors/HttpInspect/normalization/Makefile.am: * src/preprocessors/HttpInspect/server/Makefile.am: * src/preprocessors/HttpInspect/session_inspection/Makefile.am: * src/preprocessors/HttpInspect/user_interface/Makefile.am: * src/preprocessors/HttpInspect/utils/Makefile.am: Remove references to files in other directories 2005-07-22 mfr * rpm/snort.spec: Fixup the spec file to reflect new method of rules distribution 2005-07-22 mfr * configure.in: Fix PostgreSQL support 2005-07-21 mfr * src/snort.h: Bump build number 2005-07-21 mfr * rpm/snort.spec: * rpm/generate-all-rpms: Setup for 2.4.0 release, removed inline build option from RPM generation for the time being * configure.in: * Makefile.am: * doc/Makefile.am: Updated for 2.4.0 release to remove references to sig docs and rules, which are now external to the distro * etc/snort.conf: Updated snort.conf for 2.4 release 2005-07-20 mfr * autojunk.sh: Added --copy switch to automake call, patch from Jeff Nathan * congfigure.in: Added maintainer mode call to prevent endless configure reruns. From Jeff Nathan 2005-07-20 Steven Sturges * src/preprocessors/perf-base.c: * src/preprocessors/perf.c: Improved file handling of perfmon stats file rollover. * src/preprocessors/spp_stream4.c: * src/preprocessors/stream.h: Provided ability to use 2 sets of static flushpoints as well as random flushpoints for reassembly. Thanks Jason Brvenik for the patch. * src/plugbase.c: * src/plugbase.h: * src/preprocessors/snort_stream4_session.h: * src/preprocessors/snort_stream4_session.c: * src/preprocessors/spp_stream4.c: * src/snort.c: * src/snort.h: Added code to process unflushed Streams at snort exit and when stream is purged from cache because of memory issues. * src/preprocessors/spp_telnet_negotiation.c: Small fix for normalization of subnegotiation options. 2005-07-19 mfr * doc/BUGS: Updated BUGS file for 2.4 release. * configure.in: Added PostgreSQL fixes and exit code patch from Javier Fernandez-Sanguino Pena 2005-07-18 mfr * doc/README: Updated the README file to reflect the current version of Snort and command line switches that are available (and the ones that no longer are available as well...) 2005-07-11 Steven Sturges * src/detection-plugins/sp_byte_jump.c: Fixed log message. * src/log.c: Convert ICMP Router Advertisement time to host byte order before printing. * src/snort.c: * src/snort.h: * src/preprocessors/perf.c: * src/preprocessors/perf.h: * src/preprocessors/spp_perfmonitor.c: Use singal to rollover perf stats file without having to restart snort. Thanks Andrew Mullican for the patch. * src/preprocessors/perf-base.c: * src/preprocessors/perf-base.h: * src/preprocessors/spp_frag3.c: Performance update for Frag3. Also added stats fields to Perfmon for Frag3. * src/sfutil/mwm.c: Fix to handle multiple instances (different case) of the same pattern when the matching one occurs later than the others. * src/snort.c: * src/output-plugins/spo_alert_prelude.c: * src/output-plugins/spo_alert_prelude.h: Fix to handle heartbeat and pthread issues with Prelude. Thanks Yoann Vandoorselaere for the patch. * src/sfutil/mwm.c: * src/preprocessor/spp_sfportscan.c: * src/preprocessor/HttpInspect/normalization/hi_norm.c: Data initialization fixes. Thanks Yoann Vandoorselaere for the patch. * src/output-plugins/spo_database.c: Update for Oracle output. Thanks Joel Esler for the fix. * src/output-plugins/spo_unified.c: Provide additional reliabilty for NT_SPECIAL_OUTPUT. Thanks Eric Lauzon for the fix. 2005-06-10 Jeremy Hewlett * src/output-plugins/spo_alert_prelude.c: Handle case when Packet pointer is NULL for Portscan alerts. * src/preprocessors/spp_frag3.c: * src/decode.c: Fixed processing of fragmented UDP traffic. 2005-05-20 Jeremy Hewlett * src/preprocessors/spp_perfmonitor.c: Fixed misprinted filename (mnorton). * src/snort.c: Allow -T flag when MUST_SPECIFY_DEVICE is enabled (mnorton). 2005-05-19 Jeremy Hewlett * src/parser/IpAddrSet.c: Fixed problem with parsing IP addresses of 255.255.255.255 for rules (ssturges). 2005-05-18 Jeremy Hewlett * src/decode.h: * src/decode.c: * src/generators.h: * src/preprocessors/spp_frag3.c: Added processing of IP Options in fragmented packets (ssturges). Thanks Brice Cotte for getting us discussing this topic. * src/preprocessors/snort_stream4_session.c: Fixed potential memory corruption (ssturges). 2005-05-09 Jeremy Hewlett * src/parser.c: Increase limit on number of rule options to 256 (was 64). Report error if limit is reached -- previously, extra options were ignored. Also increased max line length to 4096 chars, from 1024. 2005-05-09 Andrew Mullican * src/preprocessors/xlink2state.c: Bugfix for PowerPC architecture. 2005-05-05 Jeremy Hewlett * src/preprocessors/perf-base.c: Updated to better match true on the wire and user data values (Marc Norton). 2005-04-28 Jeremy Hewlett * src/snort.c: Added check for MUST_SPECIFY_DEVICE #ifdef, which if used, requires either a -i or -r commandline switch to start snort. If not used, current behavior remains (Marc Norton). * autojunk.sh: * configure.in: * Makefile.am: * etc/snort.conf: * m4/libprelude.m4: * m4/Makefile.am: * src/plugbase.c: * src/output-plugins/Makefile.am: * src/output-plugins/spo_alert_prelude.c: * src/output-plugins/spo_alert_prelude.h: Added support for prelude, enable with --enable-prelude. Thanks Yoann Vandoorselaere! 2005-04-26 Jeremy Hewlett * src/parser/IpAddrSet.c: Fixed Snort not resolving hostnames that start with a numeric and also parsing of invalid CIDR blocks (Daniel Cid). * src/plugbase.c: * src/plugbase.h: Remove unused functions str2s, hex2s, and int2s (Andy Mullican). Thanks Jeff Nathan for pointing this out. * src/preprocessors/spp_rpc_decode.c: Ignore multiple rpc requests if in a rebuilt packet (Thanks Andy Mullican). * src/inline.c: File descriptor clean up from Will Metcalf. 2005-04-22 Andrew Mullican * etc/gen-msg.map: * src/generators.h: * src/plugbase.c: * src/preprocessors/Makefile.am: * src/preprocessors/spp_stream4.c: * src/preprocessors/stream4.h: * src/preprocessors/spp_xlink2state.c: * src/preprocessors/spp_xlink2state.h: * src/preprocessors/xlink2state.c: * src/preprocessors/xlink2state.h: * src/preprocessors/str_search.c: * src/preprocessors/str_search.h: Added xlink2state mini-preprocessor to catch MS Exchange buffer X-Link2State data overflow. 2005-04-11 Jeremy Hewlett * src/detection-plugins/sp_byte_check.c: * src/detection-plugins/sp_byte_jump.c: Fixed error messages in byte_jump & byte_test rule options (Marc Norton). * detection_plugins/sp_byte_jump.c: Fixed issue with 'multiplier' option. It is now being done before the 'align' option. This helps with rules that look at SMB traffic (Steve Sturges). * src/preprocessors/flow/flow_cache.c: * src/preprocessors/Makefile.am: * src/preprocessors/snort_stream4_session.c: * src/preprocessors/snort_stream4_session.h: * src/preprocessors/spp_stream4.c: * src/preprocessors/stream4.h: * src/sfutil/sfxhash.c: * src/sfutil/sfxhash.h: * etc/snort.conf: Performance Improvements to Flow & Stream4 session management. Also added limit to number of active sessions for Stream4, default of 8192. Old memcap value now only applies to packets stored for reassembly. Configure using preprocessor stream4: max_sessions 16384 in snort.conf (Steve Sturges). * src/preprocessor/spp_perfmonitor.c: * src/preprocessor/spp_perfmonitor.h: * src/snort.c: Added -Z flag to set full path name to PerfMonitor stats file. This will override the file or snortfile configuration option (Marc Norton). 2005-04-05 Jeremy Hewlett * src/detect.c: * src/fpdetect.c: * src/log.c: * src/snort.c: * src/snort.h: * src/tag.c: * src/output-plugins/spo_unified.c: Added a -G flag that specifies an instance identifier for the event logs. Can be used when running multiple instances of snort, either on different CPUs or on same CPU but different interface. Each snort instance will use the value specified to generate unique event ids. Can specify either a decimal value (-G 1) or hex value preceeded by 0x (-G 0x11). Thanks Steve Sturges. * src/decode.h: * src/output-plugins/spo_csv.c: * src/output-plugins/spo_database.c: Fix to remove unnecessary ICMP echo extension, and update output plugins to use ICMP header info. Thanks Kevin Douglas for finding this and Andrew Mullican for the fix. * src/decode.h: * src/detect.c: * src/preprocessors/spp_stream4.c: * src/preprocessors/stream.h: * etc/snort.conf: Add option to Stream4 to limit server-side inspection for improved performance. Similar to HttpInspect's flow-depth, this option limits rule-inspection of server traffic to the set number of bytes (in 1 or more packets) until another client request is seen. Thanks Steve Sturges & Marc Norton * src/plugbase.c: Fix issue generating ascii strings. Thanks Sandro Poppi for the fix. 2005-04-01 Jeremy Hewlett * src/preprocessors/spp_sfportscan.c: Additional fixes for suppression issue with sfPortscan and Open Ports. Fix for packets logged with bogus ip lengths (related to Open Port alerts). Thanks Andy Mullican. 2005-03-25 Jeremy Hewlett * src/output-plugins/spo_alert_syslog.c: * src/snort.c: Add snort's PID to syslog. Thanks Steve Sturges. * src/preprocessors/spp_stream4.c: Added to default ports in Stream4 and cleaned up Stream4 configuration processing. Thanks Steve Sturges. * src/preprocessors/spp_frag3.c: Added packet dump (debug only) to Frag3. Patch from Steve Sturges. * src/sfthreshold.c: Added detail to config error messages for thresholding. Patch from Steve Sturges. * src/fpdetect.c: * src/plugbase.h: * src/detection-plugins/sp_flowbits.c: * src/preprocessors/spp_sfportscan.c: Code Cleanup (general), thanks Steve Sturges. * rpm/snort.org.spec: * rpm/snort.logrotate: Added schemas to distro, and 'sharedscripts' to logrotate. General clean up of spec file. Thanks Josh Kelley for pointing this out. 2005-03-25 Jeremy Hewlett * src/preprocessors/spp_sfportscan.c: Fixed suppression issue with sfPortscan and Open Ports. Patch from Andy Mullican. 2005-03-15 Jeremy Hewlett * src/decode.c: * src/parser/IpAddrSet.c: * src/parser/IpAddrSet.h: * src/preprocessors/spp_frag3.c: * etc/generators: Updates/Fixes to Frag3 IP reassembler (thanks ssturges): 1) Push first fragmented UDP packet through, but do not inspect other fragmented packets (until rebuilt). 2) Printing of Configuration Info 3) Code readability * src/parser.c: Removal of comment parsing code added for 2.3.1. * src/decode.c: * src/generators.h: Added support for detection of Lookback & Same src/dest attacks in the packet decoder. This obsoletes sids 527, 528. Thanks Marc Norton for the feature. * src/detection-plugins/Makefile.am: * src/plugbase.c: * src/detection-plugins/sp_ftpbounce.c: * src/detection-plugins/sp_ftpbounce.h: Added FTP Bounce detection Plugin. Thanks Steve Sturges. * src/detection-plugins/sp_flowbits.c: Increased Flowbits hash table size. Thanks Marc Norton. * src/fpcreate.c: Performance improvement in pattern matcher from Marc Norton. * src/decode.c: * src/decode.h: * src/fpdetect.c: * src/preprocessors/spp_frag2.c: * src/preprocessors/spp_frag3.c: * src/preprocessors/spp_frag3.h: * src/preprocessors/spp_stream4.c: * src/preprocessors/stream.h: * src/snort.c: * src/snort.h: Eliminate duplicate alerts on Rebuilt Streams/IP reassembled packets. Patch from Andy Mullican and Steve Sturges. * src/preprocessors/portscan.c: * src/preprocessors/sfportscan.c: * doc/README.sfportscan: * etc/generators: * etc/gen-msg.map: Added handling of midstream sessions in portscan preprocessors. Thanks Andy Mullican. * src/generators.h: * src/preprocessors/spp_stream4.c: * src/preprocessors/stream.h: * src/ubi_BinTree.c: * src/ubi_BinTree.h: * src/ubi_SplayTree.c: * src/ubi_SplayTree.h: * etc/gen-msg.map: * etc/snort.conf: Stream4 fixes - Handle PAWS, NULL TCP Flags in established session, limit overlaps in established session, update ACK when server sends RST. Performance changes for cleaning up session cache. Thanks Steve Sturges and Andy Mullican for the patches. * src/preprocessors/HttpInspect/include/hi_ui_config.h: * src/preprocessors/HttpInspect/user_interface/hi_ui_config.c: * src/preprocessors/snort_httpinspect.c: * doc/README.http_inspect: Added uri_tab_delimiter option to HttpInspect. Patch from Andy Mullican. * src/preprocessors/perf-base.c: Updates to PerfMon to handle multiple CPUs properly. Thanks Steve Sturges. * src/preprocessors/spp_telnet_negotiation.c: Fixed telnet decoder bug when ignoring Sub-negotiation end command. Thanks Steve Sturges. 2005-03-08 Jeremy Hewlett * src/preprocessors/spp_flow.c: * src/detection-plugins/sp_flowbits.c: Increased number of flowbits (mnorton) 2005-03-08 Steven Sturges * src/parser.c: Fixed parsing of comments at end of line in config file. In snort.conf, anything that follows a # on a line is considered a comment. 2005-03-04 Jeremy Hewlett * src/preprocessors/spp_sfportscan.c: Fixed alignment issue causing sfPortscan to crash on Solaris/HPUX. Thanks Andy Mullican for the fix. Thanks Senthil Prabu.S and Jonathan Miner for working with us on this. 2005-01-28 Jeremy Hewlett * src/decode.c: * src/decode.h: * src/output-plugins/spo_unified.c: * src/preprocessors/HttpInspect/utils/hi_util_kmap.c: * src/preprocessors/portscan.c: * src/preprocessors/portscan.h: * src/preprocessors/spp_rpc_decode.c: * src/preprocessors/spp_sfportscan.c: * src/sfthreshold.c: Fixed compiler warnings and code formatting (tabs to spaces). 2005-01-20 Andrew Mullican * src/generators.h: * src/preprocessors/spp_bo.c: Added 2 BackOrifice alerts (1 client, 1 server) so that some alerts can be suppressed. 2005-01-18 Steven Sturges * src/plugbase.c: * src/plugbase.h: * src/preprocessors/snort_httpinspect.c: * src/preprocessors/snort_httpinspect.h: * src/preprocessors/spp_frag3.c: * src/preprocessors/spp_httpinspect.c: * src/snort.c: Change to verify that preprocessors have sufficient configuration data to correctly operate. * src/preprocessors/spp_frag3.c: Fixes to Frag3 to only have one instance of preprocessor. Uses policy context internally based on destination address of packet. Previously, each Frag3 Policy would result in a separate preprocessor instance. Also fixed use of ttl_limit option. 2005-01-18 Andrew Mullican * src/decode.c: * src/decode.h: * src/parser.c: Added ability to ignore packets based on port. Syntax in snort.conf is config ignore_ports: where list of ports can also include port ranges (ports separated by :). 2005-01-17 Steven Sturges * src/inline.c: * src/preprocessors/perf-base.c: * src/preprocessors/perf-base.h: * src/preprocessors/perf.h: * src/preprocessors/sfprocpidstats.c: * src/preprocessors/spp_frag2.c: * src/preprocessors/spp_frag3.c: * src/preprocessors/spp_perfmonitor.c: * src/snort.c: * src/snort.h: * src/util.c: Performance fixes to get correct 'on-the-wire' statistics. Added 'atexitonly' option for perfmonitor that results in performance stats only being dumped when snort exits, rather than periodically throughout snort's lifetime. 2005-01-13 Steven Sturges * src/preprocessors/spp_frag3.c: Fixed parsing of frag3 options to use space delimited options to handle IP address lists correctly. * etc/snort.conf: Updated example options for frag3 2005-01-13 Marc Norton * src/preprocessors/spp_sfportscan.c: Fixed arithmetic to correctly set the ip packet length in the ip header prior to writing the portscan info to the packet. Thanks Jon Hart for the test case and finding the bug. 2004-12-23 Steven Sturges * src/detect.c: * src/detection-plugins/sp_byte_jump.c: * src/detection-plugins/sp_pattern_match.c: * src/parser.c: * src/plugbase.c: * src/preprocessors/perf-base.c: * src/preprocessors/snort_httpinspect.c: * src/preprocessors/spp_conversation.c: * src/preprocessors/spp_sfportscan.c: * src/preprocessors/spp_stream4.c: * src/sfthreshold.c: * src/snort.c: * src/util.c: * src/util.h: * src/sfutil/Makefile.am: * src/sfutil/sfsnprintfappend.c: * src/sfutil/sfsnprintfappend.h: Fixed problem with logging that appeared in Snort 2.3.0 RC2, where single lines were broken up when sent to syslog. Thanks Sekure for pointing out the problem with thresholding. * src/sfthreshold.c: Fixed xatou function to check for non-digit parameter. Thanks nnposter for submitting a patch! 2004-12-20 Jeremy Hewlett * src/decode.h: * src/win32/WIN32-Includes/config.h: * src/win32/WIN32-Includes/stdint.h: * src/win32/WIN32-Includes/syslog.h: Reduces the number of warning on MingW/gcc. Thanks Gisle Vanem for the patch! 2004-12-17 Jeremy Hewlett * src/decode.c: Fixed issue with snort not properly decoding ppp links on MacOS X. Thanks Allan Jensen for reporting this and working with us on the fix (Roelker). 2004-12-14 Jeremy Hewlett * doc/README.http_inspect: Updated documentation on flow_depth and HTTP headers per conversations with Joe Patterson. Thanks Joe! 2004-12-09 Jeremy Hewlett * src/preprocessors/spp_arpspoof.c: Added variable names to function prototypes and made cosmetic changes to debug messages. In ARPspoofHostInit() fixed a problem where the list of configured IP/MAC entries would contain only one entry and leaked memory. In DetectARPattacks() made a small performance improvement by eliminating a copy of the ARP source protocol (IP) address (Jeff Nathan). * src/snort.h: * src/snort.c: * src/parser.c: Fixed a problem affecting MacOS X where linking may fail with non-standard libraries when global symbols are encountered multiple times. Removed duplicate globals and externed globals in headers. Defined globals in source. Made sure frag2 is only linked once (Jeff Nathan). 2004-12-08 Daniel Roelker * src/detect.c: * src/detection-plugins/sp_pattern_match.c: * src/detection-plugins/sp_pattern_match.h: * src/fpdetect.c: * src/inline.c: * src/parser.c: * src/snort.c: * src/snort.h: If the 'Q' option (inline) is set, set a global variable that can be used externally. * src/preprocessors/snort_httpinspect.c: Update error message when IIS Unicode map file is not found. * src/preprocessors/spp_stream4.c: Ignore RST|ACK midstream pickup case so we don't get an evasive TCP alert. Thanks for the report, Sekure. * src/util.c: * src/util.h: * src/snort.c: Change SanityChecks() to CheckLogDir() so the function name now makes sense. Move CheckLogDir() to after parsing snort.conf (for IDS mode), so the logdir config will work if the default or command-line logdir does not exist on the system. 2004-11-19 Steven Sturges * src/preprocessors/spp_telnet_negotiation.c: Fixed issues with how telnet options are handled. 2004-11-18 Steve Sturges * src/detection-plugins/sp_pcre.c: Fixed bug when setting the doe_ptr on a successful pcre match. It is now set relative to base_ptr. * src/detection-plugins/sp_byte_jump.c: Added from_beginning and multiplier options for byte_jump. from_beginning skips bytes from the beginning of the content, instead of from the location immediately following the number of bytes to skip. multiplier takes a numeric argument, and skips x times that number of bytes. 2004-11-04 Andrew Mullican * src/detect.c: * src/detect.h: * src/log.c: In "fast" output, now log only actual packet contents when UDP data length is greater than actual data length. Thanks Brian Caswell for spotting this. 2004-11-04 Jeremy Hewlett * configure.in: Added --enable-64bit-gcc to set up the build environment for 64bit (tested only on Solaris9). Still are some memory alignment issues to work out before 64bit mode is fully functional, Patches are welcomed. Thanks Chris Baker for doing 64bit testing. * src/sfutil/sfmemcap.c: Better support for 64bit Snort (mnorton). 2004-11-04 Andrew Mullican * src/output-plugins/spo_unified.c: Fixed reference times to match log time for first packet, for an event generated by a reassembled packet. Incremented event ID to give unique ID for each packet. Also made unified logging compatible with Windows. 2004-11-02 Jeremy Hewlett * configure.in: Changed linking order of libmysqlclient. * src/detection-plugins/sp_rpc_check.c: * src/preprocessors/spp_frag2.c: * src/sfutil/acsmx2.c: Fixes for compilation on 64-bit Solaris. Snort 2_3 branch compiles cleanly (jhewlett, mnorton). Should be a few more changes coming shortly. * src/plugbase.c: Compilation fix for AIX. Thanks Markus Waldeck. * src/preprocessors/spp_perfmonitor.c: * src/preprocessors/perf-base.c: * src/preprocessors/perf-base.h: * src/preprocessors/perf.c: * src/preprocessors/perf.h: perfmonitor config line can now be configured with accumulate or reset. (mnorton). Thanks Barry Basselgia for pointing out the issue. Thanks Scott Dexter and Andreas Ostling for doing some initial testing. 2004-10-21 Daniel Roelker * src/preprocessors/HttpInspect/client/hi_client.c: Don't include the version string length as part of the directory length. Caused some false positives if the oversize directory length was set to small numbers. Thanks Jeremy Hewlett for catching this one. * src/preprocessors/HttpInspect/session_inspection/hi_si.c: * src/preprocessors/snort_httpinspect.c: Fix false positives that were occurring on some events. Thanks to Vjay Larosa for the report. * src/preprocessors/perf-base.c: * src/preprocessors/sfprocpidstats.c: Fix linux perfmonitoring stats for the 2.6 kernel. Thanks to everyone that reported this bug. * src/preprocessors/spp_stream4.c: * src/preprocessors/stream.h: Add an enforce_state keyword to stream4 so we won't pick up midstream sessions. This works well for asynchronous links and also for just monitoring legitimate traffic. 2004-10-13 Daniel Roelker * src/detect.c: Fix suppression/thresholding bug for non-rule alerts. Thanks to Alex Butcher for reporting it to us. 2004-10-11 mfr * src/util.c: Fix divide by zero bug in TimeStats() 2004-10-05 Daniel Roelker * src/parser.c: Fix bug in preprocessor error statement that referenced freed memory. Thanks to Dennis George for submitting fix. * src/detection-plugins/sp_pattern_match.c: Fix content option modifiers so that they check the option specified and not offset. Thanks to Petr Kurtin for pointing out this bug. 2004-10-04 Daniel Roelker * src/decode.c: Fix TCP/IP options print bug that was found by Marcin Zgorecki. * src/plugbase.c: Move portscan initialization into preprocessors, not plugins. * preprocessors/portscan.c: Inspect invalid TCP initiators that stream4 doesn't track for portscans. Log open ports on TCP portsweeps when we can. Thanks to #snort and SGUIL guys for their comments and feedback. Also, thanks to David Lowless for his portscan testing in the UK. 2004-10-04 mfr * src/preprocessor/spp_frag3.c: * src/preprocessor/spp_frag3.h: * src/generators.h: * src/plugbase.c: * src/plugbase.h: New target-based IP defragmenter for Snort. * src/parser/IpAddrSet.h: * src/parser/IpAddrSet.c: Added functions for improved set parsing, generation, finding * src/preprocessors/flow/flow_cache.c: Reformatted output printing for flowcache_stats() function * src/preprocessor/spp_arpspoof.c: * src/preprocessor/spp_bo.c: * src/preprocessor/spp_conversation.c: * src/preprocessor/spp_flow.c: * src/preprocessor/spp_frag2.c: * src/preprocessor/spp_httpinspect.c: * src/preprocessor/spp_perfmonitor.c: * src/preprocessor/spp_portscan.c: * src/preprocessor/spp_rpc_decode.c: * src/preprocessor/spp_stream4.c: * src/preprocessor/spp_telnet_negotiation.c: * src/preprocessor/spp_stream4.c: Added context pointer handling to PreprocessorFunctionNode calls * src/sfutil/sflsq.h: * src/sfutil/sflsq.c: Added a couple a list node delete and add function for the current ptr * src/sfutil/sfxhash.h: * src/sfutil/sfxhash.c: Exposed sfxhash_free_node() function as a public function * src/util.c: * src/snort.c: Added a modified version of Bill Parker's run timing patch 2004-09-20 Daniel Roelker * src/util.c: Fix ts_print to work correctly for localtime logging. * src/fpdetect.c: Thresholded drop/sdrop rules should still drop the packet, but we just won't alert on them. Thanks to Brian Starrfield for finding this bug. 2004-09-17 Daniel Roelker * src/detect.c: Fix tagging issue that would tag rebuilt TCP streams, which for most output plugins this means we just relog the packets that we've already logged. Thanks Jeremy Hewlett and Daniel Cid for finding this bug. * src/event_queue.c: * src/event_queue.h: Only flush a TCP stream on rule alerts and not on preprocessor alerts. Thanks Jeremy Hewlett and Daniel Cid for finding this bug. 2004-09-13 Jeremy Hewlett * src/detection_plugins/sp_react.c: * src/detection_plugins/sp_react.h: Wrap sp_react in #ifdef tests so it can be enabled concurrently with sp_respond2 (Jeff Nathan). * src/detection_plugins/sp_respond.c: * src/detection_plugins/sp_respond.h: Wrap sp_respond in #ifdef tests so it is mutually exclusive of sp_respond2 (Jeff Nathan). * configure.in: * doc/Makefile.am: * doc/README.FLEXRESP2: * src/parser.c: * src/snort.h: * src/detection_plugins/Makefile.am: * src/detection_plugins/sp_respond2.c: * src/detection_plugins/sp_respond2.h: Import version 2 of the flexible response system written by Jeff Nathan 2004-09-08 Daniel Roelker * src/decode.c: Drop bad checksums if we're in inline mode and we're doing checksums. Thanks to William Metcalf and Victor Julien for this patch. * doc/CREDITS: Updated CREDITS with some major SourceFire contributors that were not mentioned. 2004-09-07 Daniel Roelker * src/inline.c: * src/inline.h: * src/parser.c: * src/snort.c: * src/snort.h: Make reject rule type work with linux bridging. Added config option 'layer2resets', which by default uses the interface specified by the ipq packet. In addition, you can also specify a src mac address so the sensor interface information is not apparent. Thanks to William Metcalf and Victor Julien for this feature. 2004-09-02 Daniel Roelker * src/detect.c: * src/fpdetect.c: * src/preprocessors/spp_stream4.c: Add inline state configuration for stream4, so we will drop packets that are not part of an existing TCP session and are not valid TCP initiators. Thanks Will Metcalf and Victor Julien for the initial implementation. Add functionality for drop/sdrop rules that will still drop a packet if the rule specifies "flow: established". We silently drop the packet, so as not to be DOS'd by stick/snot attacks. If the user wants the alerts, then add in the stream4 configuration of 'midstream_drop_alerts'. * src/rules.h: * src/detection_plugins/sp_clientserver.c: Add not_established keyword to the flow detection option. This allows snort to do dynamic firewall rulesets. Experimental for now, so if any wants to try let me know. * src/preprocessors/snort_httpinspect.c: Fix conditions where snort would log double web alerts that contained only content options (no uricontents). Thanks to kawa for finding and reporting this bug. 2004-08-31 Daniel Roelker * src/fpdetect.c: If InlineMode() is set, than the flow: established check will also look to see if the TCP stream was picked up in midstream. If it was, then we assume it's established. This also blocks packets that are generated by stick/snot type attacks, whereas before these packets were just being passed through because flow: established was not valid. 2004-08-27 Daniel Roelker * src/sfutil/sfmemcap.c: Fix 64-bit bug found and tested by Ryan Matteson (matty91@bellsouth.net) and Clay McClure (clay@daemons.net). Thanks guys. * src/preprocessors/spp_stream4.c: * src/preprocessors/snort_httpinspect.c: When we pick up TCP sessions in midstream, don't use stream4 direction to tell us how to inspect client and server traffic. Performance enhancement for some sites. * src/preprocessors/portscan.c: Add more comments and make portscan detail printouts more readable. 2004-08-20 Daniel Roelker * src/util.c: Make ts_print work correctly with timezones. Thanks to Dagobert Kellner for the fix. 2004-08-19 Daniel Roelker * src/util.c: Log an error when the user tries to setuid/gid and snort is being run in inline. Thanks Matt Brannigan for finding this bug. 2004-08-13 Daniel Roelker * src/detection-plugins/sp_pattern_match.c: Ignore replace rule options when snort isn't in GIDS mode. (Roelker) * src/decode.h: * src/detect.h: Set a packet_flag for drop alerts. This lets the output plugins know that we just dropped the packet that we logged. (Roelker) 2004-08-11 Daniel Roelker * src/inline.c: * src/spo_unified.c: Make inline alerts work with unified output. Thanks for the help in unified format Andrew Baker. * src/util.c: Added ASCII pig (thanks Dug Song) and snort team to snort initialization printout. * src/output-plugins/spo_log_tcpdump.c: Check to make sure we have a pointer before we reference a structure element. 2004-08-05 Daniel Roelker * src/log.c: * src/detect.c: Make tagging work for more than 1 second. (Daniel Roelker) * src/detect.c: * src/fpdetect.c: Get thresholding/suppression to work for alerts that do not contain an iph header (primarily decode alerts). Thanks Brian Caswell. 2004-08-04 Daniel Roelker * src/snort.c: Fix inline printf's during initialize. Also fix return code on invalid input for startup. This helps scripts so it returns an error if the command line arguments in the script are wrong. Thank you Matt Brannigan for this fix. 2004-07-28 Daniel Roelker * configure.in: Added --include-pcre* configuration option to help cross compiling. Thanks Erik de Castro Lopo. * src/event_queue.c: Fix bug in multi-event logging when thresholding/suppression was enabled for events in the queue. Thanks once again to Andreas Ostling. * src/output-plugins/spo_log_tcpdump.c: When a rebuilt stream causes an alert, log out the original packets instead of the rebuilt packet. Thanks Marty Roesch. * src/preprocessors/HttpInspect/user_interface/hi_ui_config.c: Turn off some alerts in the profile that were causing false positives. * src/preprocessors/HttpInspect/normalization/hi_norm.c: Turn off encoding alerts in HTTP parameter field. The parameter field is still normalized, it just doesn't alert. This helps reduce alerts that are generated from complex parameter queries. 2004-07-08 Daniel Roelker * etc/gen-msg.map: * src/generators.h: * src/plugbase.c: * src/decode.h: * src/preprocessors/portscan.c: * src/preprocessors/portscan.h: * src/preprocessors/spp_sfportscan.c: * src/preprocessors/spp_sfportscan.h: * src/preprocessors/spp_stream4.c: * src/preprocessors/spp_flow.c: * src/preprocessors/flow/flow.h: Added new portscan detector. We now detect tcp, udp, icmp, and ip protocol scans. Along with the following scan types (using nmap terminology): portscan, decoy portscan, portsweep, and distributed portscan. The initial version will have three sensitivity levels, so if you want to change values manually go to portscan.c and change the values there. I don't want to confuse people out of the gate with lots of value configurations, so try these preset levels and give us feedback. (Daniel Roelker) 2004-07-06 Daniel Roelker * configure.in: * src/decode.c: * src/decode.h: * src/detect.c: * src/detect.h: * src/fpdetect.c: * src/inline.c: * src/inline.h: * src/mstring.c: * src/parser.c: * src/rules.h: * src/snort.c: * src/snort.h: * src/detection-plugins/sp_pattern_match.c: * src/detection-plugins/sp_pattern_match.h: * src/output-plugins/spo_database.c: * src/preprocessors/spp_stream4.c: Added IPS functionality from snort_inline. Thanks everyone that was involved in that project. For more info, go check out http://snort-inline.sourceforge.net. * src/log.c: Fixed memory leak in "fast" output. Thanks for your bug report sekure@gmail.com. 2004-06-22 Chris Reid * src/snort.c: Clear error code which under Windows was causing a subsequent false failure in parsing threshold rules. (thanks to Rich Adamson) 2004-06-16 Daniel Roelker * src/sfutil/asn1.c: * src/sfutil/asn1.h: * src/detection-plugins/sp_asn1.c: * src/detection-plugins/sp_asn1.h: * src/debug.h: * src/snort.c: Added ASN.1 parsing and detection functionality to snort. Please refer to README.asn1 for more information on rule usage. (Roelker) * src/parser.c: Added parsing check from Andreas Ostling so that users don't assume that destination port lists are allowed because no error is given. * src/preprocessors/spp_stream4.c: Fixed rebuilt TCP packet munging reported by Steve Halligan. Thanks a lot for getting this problem down to pcap so we could analyze the problem. * src/detect.c: * src/event_queue.c: * src/log.c: * src/preprocessors/spp_stream4.c: * src/sfutil/sfeventq.c: Improve TCP reassembly flushing for TCP streams that have already generated an alert. This was illustrated by Brian Bailey in his SANS GIAC practical examination. Thanks for working with us on this one. 2004-05-06 Daniel Roelker * src/detection-plugins/sp_pattern_match.c: Fixed rule read up error when parsing hexmode content options. Thanks for pointing it out Marty. (Roelker) * src/preprocessors/spp_stream4.c: Fixed null pointer dereference when detect_scans were enabled and creating a new session that had funky flags. Thanks to Chad Kreimendahl for reporting the bug and testing the fix. (Roelker) * src/snort.h: at build 28 2004-04-22 Daniel Roelker * src/decode.c: * src/detect.c: * src/event_queue.c: * src/event_queue.h: * src/event_wrapper.c: * src/event_wrapper.h: * src/fpcreate.c: * src/fpcreate.h: * src/parser.c: * src/preprocessors/spp_arpspoof.c: * src/preprocessors/spp_bo.c: * src/preprocessors/spp_conversation.c: * src/preprocessors/spp_frag2.c: * src/preprocessors/spp_rpc_decode.c: * src/preprocessors/spp_stream4.c * src/sfutil/sfeventq.c: * src/sfutil/sfeventq.h: * src/signature.c: * src/signature.h: * src/snort.c: Added new event queueing algorithm, so Snort logs multiple events per packet/stream. The algorithm uses two ordering methods: priority and content length. (Roelker) * src/fpcreate.c: * src/fpcreate.h: * src/sfutil/acsmx2.c: * src/sfutil/acsmx2.h: * src/sfutil/acsmx.c: * src/sfutil/acsmx.h: * src/sfutil/mpse.c: * src/sfutil/mpse.h: New Aho-Corasick pattern matchers (Norton). Added content length tracking on otnx structures. * src/preprocessors/HttpInspect/client/hi_client.c: * src/preprocessors/HttpInspect/normalization/hi_norm.c: * src/preprocessors/snort_httpinspect.c: Added webroot alert. This alert is generated when a URL directory traversal traverses past the webroot. Added new URI discovery technique pointed out by Kanatoko. * src/tag.c: Revert to old tagging behavior. Will add new functionality in a future version. * src/util.c: Changed Snort post-processing stats to unsigned so users won't get negative stats. Thanks to various people from the community for reporting this. 2004-03-22 Chris Reid * src/plugbase.c: * src/plugbase.h: * src/output-plugins/spo_database.c: Updated how current/utc times are calculated, as well as how they are formatted (thanks Marcus Janoski) 2004-03-18 mfr * src/sfutil/acsmx2.c: Fixed _toupper/_tolower calls on non-Win32 machines (again). * src/preprocessors/spp_stream4.c: Uncommented ssnptr set in BuildPacket() for Dan 2004-03-17 mfr * src/parser.c: Added FatalError() in ProcessIP if closing IP-list '[' isn't found * src/util.c: Revamped DropStats() function to use screen real estate more efficiently * src/event_wrapper.c: QueueEvent checks to see if we're in MODE_IDS before queuing events and ClearEventQueue() checks to make sure that the event_list has been initialized. * src/sfutil/acsmx2.c: Fixed _toupper/_tolower calls on non-Win32 machines. * src/sfutil/acsmx2.c: Fixed acsmx.h call to acsmx2.h. * doc/Makefile.am: Mark snort_manual.pdf for cleanup too. 2004-03-16 Jeremy Hewlett * src/snort.c: * src/sfutil/acsmx2.c: * src/sfutil/acsmx2.h: * src/sfutil/Makefile.am: New Aho-Corasick pattern matcher from Marc Norton - memory usage reduced by 75%. * src/snort.h: Build 26 2004-03-15 Jeremy Hewlett * src/parser.c: "config checksum_mode" now supports multiple arguments on one line instead of multiple lines. 2004-03-15 Daniel Roelker * src/util.c: Calculate dropped packets and received packets correctly. Thanks Yoann Vandoorselaere for pointing this out. 2004-03-08 Daniel Roelker * configure.in: Thanks to Erik de Castro Lopo for removing warnings. * src/decode.c: * src/decode.h: * src/detect.c: * src/event_wrapper.c: * src/event_wrapper.h: * src/snort.c: New event queuing and logging for decoder and stream4 events (Marty). * src/fpdetect.c: Return value for fpEvalPacket and reset BITOP array on HTTP pipelines (Marty/Roelker). * src/generators.h: * src/preprocessors/HttpInspect/client/hi_client.c: * src/preprocessors/HttpInspect/client/hi_client_norm.c: * src/preprocessors/HttpInspect/event_output/hi_eo_log.c: * src/preprocessors/HttpInspect/include/hi_eo_events.h: * src/preprocessors/HttpInspect/include/hi_ui_config.h: * src/preprocessors/HttpInspect/normalization/hi_norm.c: * src/preprocessors/HttpInspect/user_interface/hi_ui_config.c: Added non-rfc chunk length encoding support, thanks for pointing it out H.D. Moore, and added webroot alert which alerts on webroot directory traversals (Roelker). * src/debug.h: * src/preprocessors/Makefile.am: * src/preprocessors/spp_stream4.c: * src/preprocessors/spp_stream4.h: * src/preprocessors/stream.h: Added new TCP state engine (Marty). * src/output-plugins/spo_unified.c: Added stream packet logging for unified output, when alerting on rebuilt streams (Marty). * src/preprocessors/spp_conversation.c: Fixed conversation parsing faults so users can operate this preprocessor (Roelker). * src/snort_packet_header.h: Added for future support (Marty). * src/snort.h: Now on build 25. 2004-02-25 Jeremy Hewlett * src/output-plugins/spo_csv.c: Additional fixes from Alan Milligan with CSV output, thanks! * src/sfutil/bitop.h: Cleaning up unsigned/signed warnings * src/snort.h: Moving to build 24 2004-02-25 Chris Reid * src/output-plugins/spo_database.c: Removed escaping of '%' and '_' characters in MySQL (thanks Kristofer Karas). 2004-02-23 Jeremy Hewlett * snort.8: Updated -T info to include where snort looks for "snort.conf." Thanks Drew Smith for pointing that out. * doc/snort_manual.tex: Doc updates for thresholding - rule thresholds must contain a sid. * src/detect.c: * src/plugbase.c: Changed some startup messages from printf to LogMessage to be more consistent. Thanks for the patch, nnposter(at)users.sourceforge.net. * src/snort.h: Touched source code - bumping to 23 2004-02-17 Jeremy Hewlett * src/output-plugins/spo_csv.c: Fixed minor problems with CSV output not printing out src,srcport, dst,dstport properly. Thanks for the patch, Bill Guyton. Good spot! * src/snort.h: Now at build 22 2004-02-13 mfr * templates/sp_template.h: * templates/sp_template.c: * templates/spp_template.h: * templates/spp_template.c: Updated to match the current reality of Snort. 2004-02-10 Jeremy Hewlett * src/bounds.h: * src/event.h: * src/signature.h: Added fix for compiling on Tru64 - bitypes.h now wrapped in an ifdef. Thanks Hari Gopal and Darryl Cook for pointing out the problem and testing. * etc/snort.conf: * doc/snort_manual.tex: Various fixes pointed out by JP Vossen and Felipe Franciosi. 2004-02-09 Jeremy Hewlett * src/Makefile.am: Removed unnecessary libintsnort.a, which was causing problems for some trying to compile on Solaris without the default system tools (ie: the "ar" problem). 2004-02-05 Jeremy Hewlett * Makefile.am: Fixed tab vs space problem on Solaris. Thanks for the report, Chad Kreimendahl! 2004-02-05 Daniel Roelker * src/preprocessors/flow/portscan/flowps.c: * src/preprocessors/flow/portscan/flowps_snort.c: Fixed alert_once bug that was discovered by Kevin Amorin. Thanks for pointing out the particulars of the problem, so we could do a quick fix. 2004-01-30 Daniel Roelker * src/decode.h: * src/detection-plugins/Makefile.am: * src/detection-plugins/sp_flowbits.c: * src/detection-plugins/sp_flowbits.h: * src/parser.c: * src/plugbase.c: * src/preprocessors/flow/flow_cache.c: * src/preprocessors/flow/flow_cache.h: * src/preprocessors/flow/flow.h: * src/preprocessors/spp_flow.c: * src/preprocessors/spp_flow.h: * src/sfutil/bitop.h: * src/snort.c: Added Flowbits detection functionality. Thanks Brian Caswell for initial code prototype. * src/sys_include.h: * src/ubi_BinTree.c: * src/ubi_BinTree.h: * src/ubi_SplayTree.c: * src/ubi_SplayTree.h: No more Log variables. Die, die, die . . . 2004-01-21 Jeremy Hewlett * contrib/perfstats.c: Added utility to parse out perfmon stats * RELEASE.NOTES: Added file to keep track of release notes. ChangeLog will migrate to more detailed, code-oriented comments. 2004-01-20 Jeremy Hewlett * src/detect.c: Tagged Packets no longer have NULL msg name. * src/output-plugins/spo_csv.c: Minor CSV fixes from Elias Levy (Thanks Elias!) * doc/snort_manual.pdf: * doc/snort_manual.tex: Minor LaTeX fixes from Jen Harvey (Thanks Jen!) 2004-01-16 Jeremy Hewlett * src/decode.h: * src/preprocessors/spp_stream4.c: Fixed http_inspect double alerting on pkts and rebuilt streams. (Thanks Andreas Ostling) * src/detect.c: Fixed double incrementing of pc.log_pkts on non-rule events. * src/detect.h: Removed duplicated SnortEvent() function. * src/event_wrapper.c: Added additional checks to GenerateSnortEvent(). * src/preprocessors/HttpInspect/client/hi_client.c: * src/preprocessors/HttpInspect/include/hi_si.h: * src/preprocessors/HttpInspect/session_inspection/hi_si.c: * src/preprocessors/snort_httpinspect.c: http_inspect proxy_alert now supports normal proxy networks setups. http_inspect default server only valid if specified in config. (Thanks Brent Erickson) * src/snort.c: Error on multiple interfaces on command line. Corrected pcap_compile error. (Thanks Andreas Ostling). * src/output-plugins/spo_csv.c: Added string escaping for the msg. 2004-01-13 Chris Reid * Added Oracle support into Win32 version. Much appreciation to Adam Peterson and SPL Worldgroup Inc. for sponsoring this development! This option will now be available within the Win32 installer thanks to their contribution. 2004-1-13 Jeremy Hewlett * src/detection-plugins/sp_session.c: Fixed vague error message with directory creation problems (Thanks Kenneth Ingham) * src/event_wrapper.c: * src/event_wrapper.h: * src/preprocessors/flow/flow.c: * src/preprocessors/flow/flow_cache.h: * src/preprocessors/flow/flow_callback.h: * src/preprocessors/flow/flow.h: * src/preprocessors/flow/flow_stat.c: * src/preprocessors/flow/flow_stat.h: * src/preprocessors/flow/portscan/flowps.c: * src/preprocessors/flow/portscan/flowps.h: * src/preprocessors/flow/portscan/flowps_snort.c: * src/preprocessors/flow/portscan/scoreboard.c: * src/preprocessors/flow/portscan/scoreboard.h: * src/preprocessors/flow/portscan/server_stats.c: * src/preprocessors/flow/portscan/server_stats.h: * src/preprocessors/flow/portscan/unique_tracker.c: * src/sfutil/util_net.c: * src/sfutil/util_net.h: Fixed compilation problems on Solaris and some versions of BSD. Thanks to the Snort community for your support. These fixes change the variable type to u_int32 to remove the need for stdint.h * src/output-plugins/spo_alert_unixsock.c: Close Socket when Snort receives SIGHUP (Based on patch submitted by Neetu Nangia) * src/output-plugins/spo_csv.c: Added GID, SID, and Rev to csv output (Thanks Brennen Reynolds) * src/output-plugins/spo_log_tcpdump.c: * src/output-plugins/spo_unified.c: * src/preprocessors/perf-base.c: * src/preprocessors/spp_stream4.c: Fixed build warnings on FreeBSD 5.0 * src/parser.c: config chroot readded * src/parser.c: * src/parser.h: Added additional error checking for custom rules (Thanks Andreas Ostling) * src/preprocessors/flow/flow_print.c: Flow now honors -q (quiet) * src/preprocessors/HttpInspect/client/hi_client.c: * src/preprocessors/HttpInspect/normalization/hi_norm.c: Fixed issue with no_alert not quieting some alerts * src/preprocessors/HttpInspect/user_interface/hi_ui_config.c: Removed non_rfc_chars from default profiles * src/sfthreshold.c: * src/sfutil/sfthd.c: * src/sfutil/sfthd.h: Added suppression negation (Thanks Andreas Ostling) * src/sfthreshold.c: Fixed backwards display of IP addresses on Solaris * doc/FAQ: * doc/README.csv: * doc/README.http_inspect: * doc/README.thresholding: * doc/snort_manual.pdf: * doc/snort_manual.tex: Minor clarifications and additions. 2004-1-5 Daniel Roelker * src/fpdetect.c: Fixes the signature error that user's were getting after changes to the AddMatch and SelectEvent routines. Thanks Andreas Ostling, Ron Shuck, Jon Hart, and Chris Keladis. 2003-12-22 Daniel Roelker * src/parser.c: Andreas Ostling parser fixes and updated error messages. 2003-12-20 Chris Reid * Win32 version wouldn't run as a service. Thanks to Michael Steele for pointing this out. 2003-12-17 Chris Reid * Updated Win32 to 2.1. * src/output-plugins/spo_database.c: Better support for ODBC. Better memory management (thanks Jeff Nathan). Improved escaping of SQL strings. 2003-12-17 Daniel Roelker * Snort 2.1 Release * src/decode.h: Options struct element len, changed to octet. Thanks Andrew Rucker. * src/detection-plugins/sp_pattern_match.c: Infinite looping patch during specific recursion processing. Thanks Lawrence Reed. * src/detection-plugins/sp_pcre.c: Fixed pcre URI matching. Thanks Jeremy Hewlett. * sp_respond.c: Fixes to help respond actions to correlate more closely to RFCs and now doesn't allow users to shoot themselves in the foot. * src/preprocessors/HttpInspect/normalization/hi_norm.c: Only log DOUBLE DECODE alerts if it's in the URL and not the parameter section. * src/preprocessors/spp_stream4.c: Sync stream4 up with the various versions of it. Fix problem of out-of-order ACKS that was recognized by Andrew Rucker. Also fixed off-by-one bug on reassembled streams that was introduced by previous stream4 patch. * src/sfutil/mwm.c: * src/sfutil/mwm.h: Fixed memory access bug in mwm content matching that multiple users were able to reproduce. * src/tag.c: Pkt tagging configuration now works correctly. Thanks Jeremy Hewlett for pointing this out. 2003-12-08 Chris Reid * Updated Snort 2.1 Win32 installer * Updated spo_database.c to escape sensor name strings. This had been causing a problem under Windows with MySQL because of WinPcap sensor names having embedded backslashes. 2003-12-03 Chris Reid * Updated Snort 2.1 beta to support Win32 2003-11-18 Daniel Roelker * src/detection-plugins/sp_ip_proto.c: Re-added ip_proto structure to ds_list so that the high-speed detection engine once again optimizes on ip_proto rules. 2003-11-14 Chris Green * src/preprocessors/flow/portscan/flowps_snort.c: * when using pktkludge output format, make destination address the last one seen. 2003-11-07 Daniel Roelker * src/preprocessors/HttpInspect/user_interface/hi_ui_config.c: Added some additional config options to server profiles all and iis. * src/preprocessors/HttpInspect/client/hi_client.c: Return invalid URI for configs that don't allow a tab as a URI delimiter instead of processing. This helps reduce false positives for servers that won't accept tabs as valid. * autojunk.sh: Added --add-missing to automake so the flow dependencies get installed. * src/detection-plugins/sp_dsize_check.c: Validate dsize argument so that it is a decimal number and a positive integer. 2003-11-07 Martin Roesch * src/sfthreshold.c (print_thresholding): Cleaned up linewrapped separators, cosmetic cleanup for 80-col terminals 2003-11-06 Chris Green * src/detection-plugins/sp_pattern_match.c (CheckANDPatternMatch): Fixed a bug in sp_pattern_match that was introduced with the recursive processing in 2.0.3 that resulted in a core dump due to an OOB read 2003-11-04 Chris Green * src/log.c (PrintIPHeader): print frag size as the size of the datagram - header 2003-11-04 Marc Norton * src/snort.c (SnortMain): display thresholding information at start up 2003-10-30 Chris Green * src/log.c (PrintIPHeader): make fragsize print out the size of the payload rather than the size of the header 2003-10-28 Marc Norton * src/sfutil/mwm.c: fixed bug with search-method mwm resulting in retesting removing an active rule on occasion (Thanks to Raul Siles & David Perez for a reproducible test case!) 2003-10-28 Chris Green * src/util.c (read_infile): make snort FatalErrror on bpf filter problems (reported by Fran Loehmann) 2003-10-27 Chris Green * src/preprocessors/spp_flow.c (DEFAULT_MEMCAP): make default memcaps much smaller (FlowInit): display correct memcap 2003-10-20 Chris Green * configure.in: - removed smb alerting since it should be moved to barnyard Major 2.1 Features - Suppression/Thresholding by - HttpInspect replaces http_decode by Dan - Flow ( replaces spp_conversation ) - Flow-Portscan - PCRE (www.pcre.org) is now required to build - pcre keyword for regular expressions incorporated - isdataat keyword to help with rule writing See the doc/ subdirectory for more details 2003-10-02 Chris Green * src/parser.c (RuleType): func == NULL bug fix for Bart Haagdorens * Incorporated Steve Grubb's HUP fix for -u users that aren't doing Chroot. 2003-09-22 Chris Green * back from honeymoon * src/preprocessors/spp_stream4.c (BuildPacket): fixed DEBUG compilation/zero_flushed_buffers option 2003-09-10 Chris Green * Snort 2.0.2 * added flush_data_diff_size and zero_flushed_buffers for stream4_reassemble * added threhsolding (see doc/README.thresholding) from Sourcefire/Marc Norton 2003-09-02 Chris Reid * Updated Win32 code to properly support logging to the Windows Event Log without including the Microsoft- generated warning, as was previously observed. 2003-08-06 Chris Green * src/decode.c (DecodeTCP): fixed TCP_LARGE_OFFSET with patch from Bob Perkins 2003-07-28 Chris Reid * Updated sp_pattern_match.c and win32_service.c to play nice with Visual Studio .NET (thanks for feedback from Louis Jagoe). 2003-07-25 Chris Green * Makefile.am (dist-hook): - add signatures kludges to fix up official tarballs - fixed verstuff.pl to interpolate variables * spp_arpspoof patches from Jeff Nathan - Replaced unchecked malloc() calls with SnortAlloc - Changed the parameter name ipmel to ip_mac_entry_list in functions operating on this list for clarity - Re-ordered sanity tests in the preprocessor function to prevent a null pointer dereference and to identify early exit conditions - Minor optimization to the overwrite detection code: if the overwrite list hasn't been initialized return when entering the overwrite condition tests - Use FreeToks instead of for() and free() for mSplit tokens. - Implemented a CleanExit function suitable for CleanExit and Restart. - Added CallLogFuncs calls to accompany all CallAlertFuncs calls (previously CallLogFuncs was not used at all). * src/decode.c (DecodeVlan): - compile with --enable-debug 2003-07-22 Chris Green * Shortly after release: - added verstuff.pl - added dist-hook to run verstuff.pl to make the published tarballs up to date on snort version * Snort 2.0.1 Released 2003-07-18 Chris Green * src/decode.c (DecodeUDP): - fixed UDP checksums to not incorrectly calculate with a header in host byte order Thanks to Marc Norton & Jeremy Hewlett for helping * src/detect.c (Preprocess): - completely ignore invalid IP checksums throughout snort if we are checking them. 2003-07-09 Chris Green * src/decode.c (DecodeIEEE80211Pkt): - fixed vlan decoding on lots of advice + patch from Michael J. Pomraning over at SecurePipe. Thanks! 2003-07-03 Chris Green * src/decode.c (DecodeIP): - removed redundant flag setting operation 2003-07-01 Chris Green * src/preprocessors/http-resp.c (IsHttpServerData): - ensure TCP state on discarded traffic * src/preprocessors/spp_stream4.c (GetDirection): - switch to using IP addresses * src/preprocessors/spp_frag2.c (Frag2Defrag): - ignore packets with bad checksums 2003-06-09 Marc Norton * src/fpdetect.c: fixed pass not always superceding Alert when rule order was Pass-Alert-Log * src/fpcreate.c: This fixes an initialization problem with the iBirDirection flag. 2003-06-04 Chris Green * src/preprocessors/spp_bo.c: log packet data 2003-05-30 Chris Green * src/snort.c: removed obsolete global flow variable 2003-05-28 Chris Reid * Win32 patches from Fulvio Risso (of WinPcap) so -i parameter can support both "-i 1" format, and also support named interfaces like "-i \Device\Packet_{12345678-90AB-CDEF-1234567890AB}". Fulvio also provided a more streamlined Win32 print_interface(). 2003-05-27 Chris Green * src/output-plugins/spo_alert_sf_socket.c: - made compile w/ debug * src/detection-plugins/sp_session.c (OpenSessionFile): refactored to do fatal error inside the lower level function where filename is defined. Bug Reported by Jon Werrett. 2003-05-27 Andrew R. Baker * Changed evalIndex to give precendence to help work around problems with rule ordering when not using -o 2003-05-14 Andrew R. Baker * src/Makefile.in: * src/plugbase.h: * src/spo_plugbase.h: * src/output-plugins/spo_alert_fast.c: * src/output-plugins/spo_alert_full.c: * src/output-plugins/spo_alert_sf_socket.c: * src/output-plugins/spo_alert_smb.c: * src/output-plugins/spo_alert_syslog.c: * src/output-plugins/spo_alert_unixsock.c: * src/output-plugins/spo_csv.c: * src/output-plugins/spo_database.c: * src/output-plugins/spo_log_ascii.c: * src/output-plugins/spo_log_null.c: * src/output-plugins/spo_log_tcpdump.c: * src/output-plugins/spo_unified.c: Relocated Output Plugin API definitions to spo_plugbase.h * src/detect.c: * src/rules.h: added support for per OptTreeNode output functions * src/plugbase.c: * src/output-plugins/Makefile.in: * src/output-plugins/spo_alert_sf_socket.c: * src/output-plugins/spo_alert_sf_socket.h: Sourcefire UNIX datagram socket output plugin 2003-05-16 Chris Green * patches from jeff nathan - config.h before HAVE's in strc* - add OSX kludged support for /sw/include to libnet defaults * added doc/signatures to Makefile.am 2003-05-13 Chris Reid * Added sanity check in CleanExit() to prevent double-freeing of memory during recursive call to CleanExit(). (Mark Scott) 2003-05-13 Chris Green * patches from Jeff Nathan - calloc checks in detection-plugins - old version of autoheader doesn't like arguments to * add timersub.h to Makefile.am * src/detection-plugins/sp_byte_check.c (ByteTest): - FatalError if hex/oct are used w/o specifying the string parameter * src/detection-plugins/sp_byte_jump.c (ByteTest): - FatalError if hex/oct are used w/o specifying the string parameter * src/preprocessors/spp_frag2.c (RebuildFrag): fix integer wrap around on large packets resulting in invalid IP dgrm lengths with large packets for frag2. Thanks to Jason Royes for pointing it out. will truncate large packets so that the total resulting frame is less than 65535 unless you define DONT_TRUNCATE in config.h This is unfortunately required for compatiblity for other pcap applications. * src/decode.c (DecodeTCP): move port number assignment above option decoding so people don't complain about decoder events on port 0. 2003-05-02 Chris Reid * updated Win32 LibnetNT.dll (tested by Rich Adamson) 2003-04-28 Chris Green * updated create_postgresql (Frank Knobbe) * solaris forte C compiler patches from Taso Devetzis) 2003-04-25 Chris Green * src/detection-plugins/sp_tcp_win_check.c (SetupTcpWinCheck): - removed initialization message in debug 2003-04-24 Chris Green * src/decode.c (DecodeTCPOptions): - only alert on T/TCP if there is a CCECHO * src/detection-plugins/sp_byte_check.c: * src/detection-plugins/sp_byte_jump.c: * src/byte_extract.c: * src/byte_extract.h: - move the common extraction code to a single place - fix 2 byte extraction code on little endian architectures (Thanks to Jason Miller) * src/bounds.h (inBounds): - remove #include 2003-04-21 Chris Green * src/mwm.c (mwmPrepHashedPatternGroups): - upon a fatal error, yell about config detection: search-method lowmem 2003-04-16 Chris Green * src/detection-plugins/sp_pattern_match.c (ParsePattern): - u_int -> int for size check - (slightly) more readable string handling code * src/timersub.h: import timersub macro from glibc and upcased it * src/snort.c (InterfaceThread): - Use TIMERSUB * src/detect.c (AlertAction): AlertFlushStream takes one argument now * src/parser.c (ParseConfig): disable_tcpopt_ttcp_alerts parsing -- Thanks for pointing it out Jeff Dell * src/preprocessors/spp_stream4.c: - removed unused argument to DeleteSpd (AlertFlushStream): - get the ssnptr variable from the packet structure - unified logic for server and client side - removed memthresholding because of large delays * src/decode.h (_Stream): - get rid of dataPtr ( it's always the same thing as &s->data ) - add bytes_tracked variable for more memory protection * src/preprocessors/spp_stream4.c: - macroize sequence number type checks (StoreStreamPkt): - watch for how many packets we accept 2003-04-14 Chris Green * Snort 2.0.0 Released 2003-04-09 Chris Green * src/log.c,spo_database.c (PrintTcpOptions): (PrintIpOptions): - correctly print out * src/log.c,spo_database.c (PrintTcpOptions): (PrintIpOptions): - correctly print out * src/decode.c: Last bastions of ErrorMessage @ decode in non-verbose mode 2003-04-09 Chris Green * src/detection-plugins/sp_byte_jump.c: - another argument parsing bug ( Thanks Judy ) 2003-04-07 Chris Green * src/decode.c: Change all classifications to DECODE_CLASS * src/detection-plugins/sp_byte_check.c (ByteJump/ByteCheck) - do not SetUseDoe() for these functions. Doe is set automatically and use_doe is only needed to be set by people wishing to make the previous pattern match relative. Build 69 * src/decode.h - handle more FIN conditions * src/preprocessors/spp_stream4.c (ReassembleStream4): - adjusted established check * src/preprocessors/spp_stream4.c (NotForStream4): - refactoring 2003-04-04 Chris Green * src/detection-plugins/sp_byte_jump.c (ByteJump): - make offsets work for byte_test and byte_jump (Thanks Judy and Dan) 2003-04-03 Chris Green 2.0.0rc3 * etc/snort.conf: config detection: search-method lowmem Incorporates a lower memory pattern matcher from Marc Norton for people running into not being able to update to 2.0 due to memory issues. * src/snort.c (SnortMain): - move InitOutputPlugins down ( 1.9 forward fix from Nick ) 2003-04-01 Chris Green Build 67 * src/output-plugins/spo_alert_unixsock.c: - moved unix socket format to .h - moved default socket location to the logdir ( patches from Nick Zitzmann ) 2.0.0 RC2 2003-03-31 Chris Green * src/preprocessors/spp_stream4.c (CreateNewSession): - don't act like a happy wallaby if the IP transport doesn't support ECN but the reserved flags make it through crystal clear * src/preprocessors/spp_frag2.c (_FragTracker): only do 1 fragment tracker alert for things like teardrop * src/preprocessors/spp_stream4.c: - DisableDetect() instead of do_detect() - flush on write ssn stats (andrewb fix) * src/decode.c (DecodeUDP): - correctly decode UDP packets (andrewb fix) 2003-03-27 Chris Reid * src/tag.c #ifdef should have been #ifndef * src/acsmx.h Have WIN32 use definition of "inline" from config.h instead of a locally defined one * src/output-plugins/spo_alert_syslog.c * etc/snort.conf Changed Win32 default host to "127.0.0.1" (thanks to Rich Adamson) * src/win32/WIN32-Prj/snort_installer.nsi Added further installation instructions to help cut down on the number of 'newbie' questions. 2003-03-28 Chris Green * src/parser.c (ParseConfig): - make disable ipopt work (Thanks Tim Slighter) * src/tag.c (PrintTagNode): new f() - added static cling (ParseTag): fixed parser (AddTagNode): - fixed src/dst tagging - unified both tag cache logics * src/debug.h: * src/debug.c: added DebugThis() * etc/snort.conf make the config options do what they say * src/output-plugins/spo_alert_syslog.c (ParseSyslogArgs): - only warn if we are parsing snort.conf ( -s ) * src/tag.h (SetTags): - damn #if 0 * configure.in: - remove snmp/ssl 2003-03-27 Chris Reid Build 63 * src/snort.c * src/output-plugins/spo_alert_syslog.c Win32 '-s' now takes no arguments. Host/port info is configured only within snort.conf (output alert_syslog). 2003-03-27 Chris Green * configure.in: - changed to make DEBUG do -O0 and -g with gcc (-ggdb makes gdb confused. go fig.) * src/snort.c (ParseCmdLine): -s means syslog() not -s args on win32 * src/output-plugins/spo_alert_syslog.c (ParseSyslogArgs): - SnortAlloc - allow -s to work again 2003-03-26 Chris Green * src/decode.c (DecodeTCP): - bad format args (thanks Tim!) RC1 * Incorporated Patches from Jeff Nathan - libnet configure should work again - randomize flexible response ttls - add stop descriptor leaking * src/decode.c (DecodeIPOptions): truncation alerts for IP options too! (InitDecoderFlags): added decoder flags function * src/log.c (Print(I|Tc)cpOptions): - print out everything that I can 2003-03-25 Chris Green * src/signature.c (ReferenceSystemAdd): - fixed the dang linked list * rules/Makefile.in (EXTRA_DIST): added pop2.rules * src/decode.h (_Stream): - removed current_seq to save memory * src/preprocessors/spp_stream4.c - added isBetween inline function (UpdateState): - incorrect ACTION_ACK_CLIENT_DATA (StoreStreamPkt): - comment clarification * src/bounds.h: - added new file - moved standard bounds checking functions to this file * src/detection-plugins/sp_react.c (ParseReact): - give react a half a chance of working (SendTCP): - see above * src/detection-plugins/sp_clientserver.c (ParseFlowArgs): - fatal error on unknown option * src/output-plugins/spo_database.c (UpdateLastCid): - added missing free() (Database): - correctly write out the class_id junk * src/output-plugins/spo_alert_smb.c (AlertSmb): - print out the ports like was intended * src/preprocessors/spp_portscan2.c (SLog): - use fprintf for what it was designed for * src/preprocessors/spp_portscan.c (LogScanInfoToSeparateFile): - use fprintf for what it was designed for * src/log.c (PrintArpHeader): - wireless arp printing fix (PrintTcpOptions): - strncpy -> memcpy (PrintEapolKey): - aligned printf * src/decode.c (DecodeTRPkt): - more truncation style alerts 2003-03-24 mfr * src/preprocessors/spp_stream4.c: - changed PruneSessionCache() to only do timeout flushes if we're over 50% of the memcap (should help performance) * src/log.c: - fixed broken Frag Size calculation in IP header printout routine 2003-03-21 Chris Green * src/detection-plugins/sp_session.c: - fixed memory leak on filename creation * src/preprocessors/spp_stream4.c (Stream4InitReassembler): - make serveronly work * src/preprocessors/spp_telnet_negotiation.c (NormalizeTelnet): - check the byte, then increment * src/detection-plugins/sp_byte_check.c (ByteTestParse): more input validation for byte_check/byte_jump * src/log.c (PrintWifiHeader): - watch out for NULL bssid's * src/tag.c (TagHost): - removed redundant check (AddTagNode): - accumulate the tag seconds rather than the idx->seconds * src/detection-plugins/sp_pattern_match.c (PayloadSearchRegex): - actually die on a regex option ( might actually get it developed later ) * src/decode.c (DecodeIEEE80211Pkt): - more truncated packet alerts (DecodePPPoEPkt): - alert on truncated pppoe pkts - separate decoder for encapsulated PPP (DecodeVlan): - alert on truncated Vlan headers (DecodeUDP): - use the UDP header length field instead of capture length * src/detection-plugins/sp_byte_jump.c: src/detection-plugins/sp_byte_check.c: - protect against negative offsets ( don't rely on negative offsets working in the long term ) - don't continue when we can't parse string numbers * src/detection-plugins/sp_respond.c (Respond): - missing iph check * src/detection-plugins/sp_ip_proto.c (IpProtoDetectorFunction): - missing iph check * sspp_asn1, fnord, spo_xml, spo_SnmpTrap - removed ( will be available later as a contrib ) * src/preprocessors/spp_http_decode.c: - switch to using chars for lookup tables - removed extraneous sprintfing - removed old TBD feature code 2003-03-17 Chris Green * src/snort.c (FPUTS_WIN32): - changed to blank space rather than NULL Build 60 New Options added to snort.conf config: disable_tcpopt_experimental_alerts config: disable_tcpopt_obsolete_alerts config: disable_ttcp_alerts config: disable_tcpopt_alerts * src/preprocessors/spp_stream4.c (ReassembleStream4): - DisableDetect only if the emergency_status is NULL. (CreateNewSession): - fixed return logic with detect scans * etc/gen-msg.map: WARNINGS: -> snort_decoder: - new tcpopt events * src/preprocessors/spp_rpc_decode.c (PreprocRpcDecode): - change to use DisableDetect() instead of do_detect = 0; (disables futher preprocessors) (RPC_CLASS): Use the same classification as the other decoder alerts * src/snort.h (_progvars): - added DecoderFlags structure for enabling/disabling decoder alerts * src/snort.h (_progvars): - added tcpopt_alert_flag * src/decode.c (DecodeTCP): - print out warnings on bad header lengths in verbose mode (DecodeTCPOptions): - nearly complete rewrite to identify whizbang things like bubba and skeeter options! 2003-03-14 Chris Reid Build 59 (really this time) * src/detect.c - corrected un-initialized memory in CreateRuleType() * src/snort.c - rationalize Unix vs. Win32 command-line options - add optarg for Win32 syslog '-s' parameter - bugfix for Win32 syslog initialization - thanks to Rich Adamson and L. Christopher Luther for helping with the syslog fixes * src/util.c - provide Win32 fix for SetChroot() * many files - added missing CVS ID tags - added missing copyrights 2003-03-13 Chris Green Build 59 * src/preprocessors/spp_stream4.c(TcpActionAsync): - update server side seq numbers on Async State machine * src/preprocessors/spp_stream4.c (BuildPacket): - Use Constants for IP Lens - Move SPARC_TWIDDLE to only initialization * src/preprocessors/spp_frag2.c - removed killme variable from InsertFrag - untabified (RebuildFrag): - converted to creating fake packets the same way as stream4 2003-03-10 Chris Green Build 58 * src/util.c: - new functions SetChroot, CurrentWorkingDir, SigChrootHupHandler, GetAbsolutePath - Chroot + HUP == "tough luck for now * src/snort.c (SnortMain): - Chroot after parsing the rules file - use fully qualified pathname for logdir in chroot case * src/output-plugins/spo_unified.c (UnifiedInitAlertFile): - removed a printf 2003-03-05 Chris Green * src/detection-plugins/sp_byte_check.c (ByteTest): - never touch doe_ptr on a successful match - inBounds check off by one when seeing if enough to read * src/detection-plugins/sp_byte_jump.c (ByteJump): - inBounds check off by one when seeing if enough to read * src/detection-plugins/sp_pattern_match.c (uniSearchReal): - inBounds check off by one when seeing if enough to read 2003-03-04 Chris Green * src/util.h (inBounds): end is always dsize + len so it should be p < end * src/preprocessors/spp_stream4.c (UpdateState): - added return ACTION_ACK_CLIENT_DATA * src/detection-plugins/sp_pattern_match.h (_PatternMatchData): - changed check_distance to use_doe ( check_distance was not used ) * src/detection-plugins/sp_pattern_match.c (uniSearchReal): - new function to unify uniSearchCI & uniSearch - all "work" related to distance, within, depth, and offset done in one place now (CheckANDPatternMatch): - condensed this down to be a very small wrapper around uniSearch ( now !content will alert with offset on small packets) (CheckUriPatternMatch): - condensed this down to be a very small wrapper around uniSearch * src/detection-plugins/sp_byte_check.c: * src/detection-plugins/sp_byte_jump.c: - inBounds function - doe_ptr - SetUseDoe - TEXTLEN constant * src/generators.h (RPC_MULTIPLE_RECORD_STR): fixed cut and pasto * src/util.h (inBounds): added new inBounds function to check a ptr position against a known start and end location * src/mstring.c (mSearch): subsequent offsets adjusted correctly (Marty) * src/preprocessors/spp_rpc_decode.c - redefine MSB - write fraghdr back into pkt - removed extraneous printf * src/preprocessors/spp_rpc_decode.c: - readded config.h and strings.h (Thanks Chad) * src/preprocessors/spp_stream4.c - suspend renabling mode fixes 2003-03-03 Chris Green * src/preprocessors/spp_rpc_decode.c (PreprocRpcDecode): - alignment errors on non-x86 platforms - added new space delimited options alert_fragments no_alert_multiple_requests no_alert_large_fragments no_alert_incomplete - corrected buffer overflow in fragment normalization 2003-02-28 Daniel Roelker * src/bitop.h: * src/fpcreate.c: * src/fpdetect.c: - Fixed a problem when snort runs with only uricontent matches and no contents. In this case an element in the bitop structure never got initialized, so it's not good to reference that. Problem was caught by Chris Green doing some unit testing. 2003-02-27 Chris Reid * src/win32/WIN32-Prj/snort.dsp * src/win32/WIN32-Prj/snort.mak * src/win32/WIN32-Prj/snort.dep - Removed an unnecessary file from the project (name.mc) * src/win32/WIN32-Prj/build_releases.bat - Script to easily compile all configurations of snort. * src/win32/WIN32-Prj/snort_installer.nsi * src/win32/WIN32-Prj/snort_installer_options.ini - Scripts to build a Win32 installation program for snort. Thanks to Chris Green for suggesting we use NSIS! 2003-02-19 Chris Reid * src/snort.c - Win32 '-s' parameter wasn't configured to accept an optarg, but code expected one, causing null-pointer violation. 2003-02-16 Chris Green * src/preprocessors/spp_http_decode.c (PreprocUrlDecode): * remove broken checks. * src/preprocessors/spp_telnet_negotiation.c (NormalizeTelnet): * remove broken checks. 2003-02-15 bmc * src/preprocessors/spp_asn1.c - don't bother decodeing the packet if its 0 bytes * src/preprocessors/spp_fnord.c - don't bother decodeing the packet if its 0 bytes - set DEBUG to DEBUG_PLUGIN instead of DEBUG_STREAM * src/preprocessors/spp_http_decode.c - don't bother decodeing the packet if its 0 bytes - if stream4 is enabled, only decode if if is client data on an established session (This makes using internal_alerts useful) * src/preprocessors/spp_rpc_decode.c - don't bother decodeing the packet if its 0 bytes - if stream4 is enabled, only decode if if is client data on an established session * src/preprocessors/spp_telnet_negotiation.c - don't bother decodeing the packet if its 0 bytes - if stream4 is enabled, only decode if if is client data on an established session 2003-02-15 bmc * src/detection-plugins/sp_byte_jump.c actually verify that it needs aligning before aligning. (more than 0 doesn't need aligned) 2003-02-15 bmc * src/detection-plugins/sp_byte_jump.c 0 is already aligned to a 32-bit boundry... 2003-02-14 bmc * src/mstring.c Fix so --enable-debug actually compiles 2003-02-14 mfr * src/parser.c Fixed XferHeader() function to copy the not_*p_flag to the RTNs... * src/detection-plugins/sp_ip_proto.c ip_proto options can now be stacked 2003-02-14 mfr * src/fpdetect.c src/mstring.c src/detection-plugins/sp_byte_check.c src/detection-plugins/sp_byte_jump.c src/detection-plugins/sp_pattern_match.c Fixed distance/within/byte_test/byte_jump relative (stateful) pattern matching and the like. Complete reimplementation of payload position tracking. Tested with several different attack scenarios with 100% detection rate, please test! 2003-02-04 Chris Reid * src/snort.c Added sanity checks on command-line parameters, for whenever a user forgets to put spaces between (ie.) /SERVICE/INSTALL. This only applies to /SERVICE parameter for Win32. * src/util.c - Updated Win32 banner for version 2.0 - Modified FatalError to generate a Win32 EventLog entry if this is a Win32 Service build, otherwise no errors are ever presented to the user. * src/mwm.c - Added an include of config.h, for Windows build. - Changed variable names "small" and "large" into "small_value" and "large_value" to prevent compile errors under Visual C++. * src/mpse.c * src/pcrm.c - Added an include of config.h, for Windows build. * src/parser/IpAddrSet.c * src/preprocessors/perf-flow.c - Added ifndef/endif around non-Win32 header files. * src/preprocessors/perf-base.c - Added changes to allow it to compile under Win32. * src/preprocessors/perf.h - Prevent definition of UINT64 under Win32. * src/preprocessors/spp_asn1.c * src/preprocessors/spp_bo.c * src/preprocessors/spp_fnord.c - Added documentation. * src/win32/WIN32-Includes/config.h - Added definition for UINT64 and uint64 - Changed VERSION to '2.0.0beta' * src/win32/WIN32-Code/win32_service.c - Changed how Win32 registry is opened for reading (was KEY_ALL_ACCESS, now is KEY_READ). Problem (and patch) was reported by Michael Miller. * src/win32/WIN32-Prj/snort.dsp - Removed all references to SFStats compile options, since these stats provide little useful information under Win32 due to API differences between Win32 and Unix, specifically the lack of a native getrusage(). * src/win32/WIN32-Prj/snort.ncb src/win32/WIN32-Prj/snort.opt src/win32/WIN32-Prj/snort.plg - Truncated the contents of these files. 2003-01-26 Chris Green * src/preprocessors/spp_stream4.c (AlertFlushStream): - Fixed problem where an alert on a stream would update sequence numbers incorrenctly - moved StoreStreamPkt up to avoid crash Thanks to Lawrence Reed for pointing out problems and almost perfect solutions * src/detection-plugins/sp_clientserver.c (CheckForReassembled): missing return in opt node check affects only flow: only_stream 2002-1-17 Daniel Roelker * src/preprocessors/spp_perfmonitor.c: Added 'snortfile' parameter to perfmonitor so users can use the default snort directory to log performance statistics. Suggested by L. Reed. * src/preprocessors/spp_stream4.c: Fixed performance statistic counter for total stream4 sessions. When a new session is created, we make sure that it was created before incrementing the counter. Fixed by L. Reed. 2003-01-07 mfr * configure.in Added patch from Jeff Nathan to fix libnet detection 2003-01-05 mfr * src/util.h Added self preservation control struct for the new SPAlloc function. * src/util.c Added self preservation-aware memory allocator, this allows coders to add new subsystems requiring self preservation techniques using a single allocation interface and management mechanism. * src/detection-plugins Changed the URI and AND checking modules to use the context pointer on the fp_list struct instead of the ds_list. This will cause all content/uricontent checks to be checked in the sequence that they appear in a rule so that all the distance/within and relative byte_test/byte_jump stuff will work properly. Merry Xmas cazz! * src/preprocessors/spp_frag2.c Changed frag2 to use the new SPAlloc mechanism as a testing platform. If this works right I'll convert all the other stuff over to it as well. 2002-12-19 Andrew R. Baker * src/detect.c: * src/fpdetect.c: * src/fpdetect.h: * src/parser.h: * src/rules.h: * src/snort.c: * src/snort.h: Fix custom rule types and arbitrary rule ordering that were broken with the new detection engine. 2002-12-13 Chris Green * src/preprocessors/spp_frag2.c (Frag2Defrag): - added "state_protection" config mechanism to enable/disable the thresholding operations * src/preprocessors/spp_stream4.c: - mark sessions that have been picked up midstream - protect against people setting up snort behind a tap without setting asynchronous link - added "state_protection" config mechanism to enable/disable the thresholding operations * src/decode.h (SSNFLAG_MIDSTREAM): added a midstream pickup flag 2002-12-12 Daniel J. Roelker * src/fpcreate.c: * src/fpdetect.c: Fixed bi-directional rule functionality when unique port was the destination port in a bi-directional rule. Reported by Brian Caswell. 2002-11-26 Andrew R. Baker * src/parser.c: fixed argument handling bugs for snaplen and read_bin_file config directives in snort.conf * src/snort.c: * src/snort.h: * src/util.c: * src/util.h: Modifications to signal handling and CleanExit/Restart 2002-11-26 Daniel Roelker * src/checksum.h: Problem with ICMP checksum. Routine did not return the compliment of the checksum. Thanks to Del Armstrong for point this out. * src/decode.c: Also, UDP checksums are only done if the checksum is 0. Otherwise, we don't do them, even if the config is set for that. Again, thanks to Del Armstrong for pointing this out. 2002-11-26 Chris Green * src/output-plugins/spo_database.c (BeginTransaction): * removing BEGIN for oracle ( Chad Kreimendahl ) 2002-11-25 Chris Green * src/preprocessors/spp_stream4.c (TcpActionAsync): (TcpAction): -- removed extra decrements for last_ack was causing a high false alarm rate for new \r\n rules. Thanks to Jens Krabbenhoeft for helping on this one -- disable nmap scans from alerting when we don't use detect_scans. Thanks to Chad Kreimendahl for this one 2002-11-24 Chris Green * src/preprocessors/spp_stream4.c: - fix argument parsing for emergency modes * src/preprocessors/spp_frag2.c (ParseFrag2Args): - fix argument parsing for emergency modes 2002-11-19 Chris Green * src/preprocessors/spp_stream4.c: fixed a bug where we would shift to suspend mode if stream4_reassemble wasn't enabled 2002-11-18 Chris Green Merging in mfr/cmg mitigations for extreme bogus session loads * src/preprocessors/spp_stream4.c: self_preservation_threshold: self_preservation_period: suspend_threshold: suspend_period: emergency_ports: <-- port list that will be reassembled * src/preprocessors/spp_frag2.c: self_preservation_threshold: self_preservation_period: suspend_threshold: suspend_period: added Emergency / Suspend mode * src/generators.h: added Emergency / Suspend alerts to stream4/frag2 - in the future, these should not generate packet log alerts but they are required to for the current view of the world * src/detect.h (DisableDetect): added function 2002-11-16 Chris Green * src/snort.h: - added a define SNORT_20 so that code will be easier to merge around 2002-11-13 Andrew R. Baker * src/log.c: * src/parser.c: * src/snort.c: * src/snort.h: * src/util.c: * src/output-plugins/spo_log_ascii.c: * src/output-plugins/spo_log_tcdump.c: * src/output-plugins/spo_unified.c: * src/output-plugins/spo_xml.c: * src/preprocessors/spp_portscan.c: * src/preprocessors/spp_stream4.c: Changes to cleanup the chroot process 2002-11-12 Andrew R. Baker * src/output-plugins/spo_log_ascii.c: fixed output file issues for ascii logging 2002-11-11 Andrew R. Baker * src/log.h: * src/parser.c: * src/plugbase.c: * src/snort.c: * src/snort.h: Cleanup command line alert and log configuration * src/decode.c: * src/snort.c: * src/snort.h: updated run mode determination and representation relocated log_dir sanity check relocated test_mode_flag check to outside InterfaceThread moved global variable declarations into snort.c from snort.h * src/snort.c: replaced ReadConfFile with ConfigFileSearch. The configuration file is now only read in once place. * src/log.c: * src/parser.c: * src/snort.c: * src/snort.h: * src/output-plugins/spo_alert_fast.c: * src/output-plugins/spo_alert_full.c: * src/output-plugins/spo_alert_syslog.c: * src/output-plugins/spo_database.c: * src/output-plugins/spo_unified.c: * src/preprocessors/perf-base.c: * src/preprocessors/spp_portscan.c: removed more vestiges of the multiple interface pthread support 2002-11-10 Brian Caswell * src/detection_plugins/sp_byte_test.c: added support for & and ^ 2002-11-07 Daniel J. Roelker * src/preprocessors/spp_http_decode.c: Fixed an infinite loop bug that occurred in my last update to http_decode that dealt with an off-by-one bug. Fixed now. Pointed out by Jens Krabbenhoeft and Nathan Labadie. 2002-11-07 Andrew R. Baker * src/snort.c: * src/snort.h: Removed unused MTU support code 2002-11-06 Daniel J. Roelker * src/mwm.c: * src/mwm.h: Fixed another bug in mwm search routines when dealing with identical one byte patterns in multiple rules. There was a theoretical possibility of overwriting a one byte rule group (example: "~") with another rule group of ("|00 7e|"). This has now been fixed and should be the last of the one byte pattern problems. 2002-11-06 Daniel J. Roelker * src/mwm.c: * src/mwm.h: Fixed bug when comparing multiple one byte rules with the same one byte pattern. Problem pointed out by Brian Caswell. 2002-11-06 Andrew R. Baker * src/snort.c: * src/snort.h: * src/decode.c: * doc/README: removed -6 (show IPv6) and -x (show IPX) command line options (they never did much anyway) cleaned up ARP, IPv6, and IPX packet counting * src/preprocessors/Makefile.am: add missing header (perf-event.h) to libspp_a_SOURCES 2002-11-05 mfr * src/plugbase.c: * src/detection_plugins/sp_byte_jump.c: * src/detection_plugins/sp_byte_jump.h: Added byte_jump, we can now decode a length from the app layer and jump the detect_offset_end (last match pointer) up that number of bytes, great for decoding RPC with Snort rules 2002-11-04 mfr * src/detect.c: * src/fpdetect.c: fixed case where multiple rules can have partial matches on content and fuxor the detect_offset_end calculations (i.e. reset the offset for every OTN in the system) 2002-11-04 Chris Green * src/detection-plugins/sp_byte_check.c: Make big,little arguments actually interpret the data correctly 2002-11-04 Andrew R. Baker * src/parser.c: * src/rules.h: * src/snort.c: * src/snort.h: * snort.8: remove ghetto message reference option (it has not worked since May) * src/output-plugins/spo_alert_fast.c: * src/snort.c: added "-A cmg" alerting mode 2002-11-02 Chris Green * HAVE_STRINGS_H all over the place for bzero/Solaris first reported by John Whitson 2002-11-1 Daniel Roelker * src/preprocessors/spp_http_decode.c: Fixed potential off-by-one bugs. Also fixed %25xx encoding and %uxxxx encoding for ascii characters. Still much work to be done but most of this will be added in the next version. 2002-11-01 mfr * src/detection_plugins/sp_byte_test.c: fixed range checks, inclusion of strings.h, byte boundry checks 2002-11-01 mfr * src/detection_plugins/sp_byte_test.c: added test rules to the sp_byte_test.c header comment block 2002-11-01 mfr * src/detect.c: * src/mstring.c: * src/detection_plugins/sp_pattern_match.c: fixed various "issues" with the distance/within code, should work much better now also removed redundent calls to pattern matcher for rules with mlutiple content checks * src/plugbase.c: * src/plugbase.h: * src/plugin_enum.h: * src/detection_plguins/sp_byte_test.c: * src/detection_plguins/sp_byte_test.h: added sp_byte_test, detection plugin that let's us perform discrete value checks on numbers that are encoded in packet payloads, either in straight binary representation or as strings 2002-11-01 Andrew R. Baker * src/decode.c: fix logic for generating decoder alerts * src/decode.c: * src/parser.c: * src/snort.c: * src/snort.h: * doc/README: removed broken support for the "-a" (show arp) command line switch 2002-10-31 Andrew R. Baker * src/util.c (GenHomenet & GenObfuscationMask): fix invalid reference to optarg * configure.in: * src/snort.h: * src/snort.c: removed pthread support (still need to remove MAX_INTERFACES cruft) 2002-10-30 Chris Green * (Repository): removed autogenerated files use sh autojunk.sh to recreate them if you are using CVS to compile 2002-10-30 Andrew R. Baker * src/parser/IpAddrSet.c: * src/parser/IpAddrSet.h: add API for IpAddrSet data structure * removed "extern char *file_name" and "extern int file_line" from scattered places in the source 2002-10-29 Andrew R. Baker * src/detection-plugins/*.c: add multiple options checks for plugins 2002-10-23 Chris Green * src/log.c more output clean ups from James Hoagland 2002-10-22 Chris Green * strtol fixes ( Dave Ockwell-Jenner ) * Merged in Glenns changes for net-snmp port declartion * src/parser.c (ParseRuleOptions): threshold added back * src/preprocessors/spp_portscan2.c (DEFAULT_MAX_SCANNER): change defaults back down 2002-10-22 Daniel Roelker * src/fpdetect.c: Bogus port 0 initialization in fpEvalHeaderTcp/Udp. (Dirk Geschke) 2002-10-18 Chris Green * src/detection-plugins/sp_clientserver.c (CheckFromClient): hide this under a DEBUG_CS * src/preprocessors/spp_stream4.c (AlertFlushStream): make AlertFlushStream adjust the base_seq upon a flush point (Thanks so much to qru for a reproducable test case... this was a PITA) 2002-10-16 Chris Green * src/util.c (CreatePidFile): use pv.log_dir instead of local variable (Cameron Humpries) * src/log.c (PrintICMPHeader): Removed newline amidst a sea of complains from James Hoagland & other users :) 2002-10-16 Roman Danyliw * src/output-plugin/database.c: - escape the signature name before trying to write it to the signature.sig_name field (Dirk Geschke) 2002-10-16 Dan Roelker * src/fpdetect.c: - Reverted no content rule checks back to the original snort behavior. Reassembled packets are now inspected against no content rules. (Jens Krabbenhoeft) * src/preprocessors/spp_perfmonitor.c: - Adjusted newlines for console statistics prettiness. 2002-10-14 Roman Danyliw * src/output-plugin/database.c: - Transaction abstraction functions (Begin/Commit/Rollback) - Fixed transaction SQL for MS-SQL - Fixed incorrect return value for MS-SQL Insert() (Hans Nilsson) 2002-10-13 Chris Green * src/log.c (PrintXrefs): newlines on Xrefs... pointed out by too many people to count :) * src/preprocessors/spp_portscan2.c (targetCompareFunc): - target compare function incorrect logic (pointed out by Pat Gorman) 2002-10-12 Roman Danyliw * src/output-plugin/database.c: - Fixed (PostgreSQL) sensor initialization to the sensor table by setting a default last_cid value - Fixed schema detection bug on MS-SQL enabled builds 2002-10-09 Chris Green * changed FatalError/exit codes * merged Sourcefire modifications into snort-head * kick off of snort-2.0 dev cycle win32 probably doesn't work yet. :-) 2002-10-09 Marc Norton Daniel Roelker * src/decode.h: p->preprocessors for enable/disable status * src/fpcreate.c, src/fpcreate.h, src/fpdetect.c, src/fpdetect.h: Added new detection engine. fpcreate.* creates the new detection engine and intializes the detection engine components. fpdetect.* analyzes packets as they come in and decides what happens to them. * src/pcrm.c, src/pcrm.h: Added new signature detection classification. * src/mpse.c, src/mpse.h (Norton): Added an interface for multi-pattern match routines. * src/mwm.c, src/mwm.h (Norton): Added modified Wu-Manber style multi-pattern matcher. * src/acsmx.c, src/acsmx.h (Norton): Added Aho-Corasick state machine, using a deterministic finite automata. * src/bitop.h: Added inline functionality for bit operations. Used in the new detection engine. * src/preprocessors/spp_httpflow.*, src/preprocessors/http-resp.*: Added an http protocol flow preprocessor that analyzes client and server traffic. Useful for HTTP performance. * src/preprocessors/spp_perfmonitor.*, src/preprocessors/perf*.*: Added a performance monitor that keeps stats on snort. Some of those stats are Mbits/sec, Alerts/sec, TCP state information, network traffic flows and percentages, etc. * src/preprocessors/sfprocpidstats.c: Added functionality for multiple CPU stats on linux. For use in spp_perfmonitor, etc. * src/parser.c: Added a new config option, 'detection'. This option allows the user to configure certain aspects of the detection engine. * src/checksum.h: Added new optimized inline checksumming routines. * src/mstring.c: Optimized mSearch and mSearchCI. 2002-10-09 Chris Green * src/snort.c (ParseCmdLine): - syslog option on non-win32 does not take the extra argument (Andrea Barisani) * updated snort.dsp to not require getrusage 2002-10-01 Chris Green * Fixes from Chris Reid - varchar sql arguments for mssql - usertime -> systemtime misses - snort project file updates 2002-09-26 Chris Green * configure scripts updated to handle net-snmp as well as ucd (Glenn Mansfield Keeni and Abe Katsuhisa) 2002-09-25 Chris Green * src/preprocessors/spp_http_decode.c: moved setting the uri_count to this preprocessor to handle false alerts on reassembled packets. 2002-09-17 Roman Danyliw * src/output-plugin/spo_database.c - make sure that a packet payload larger than those supported in the SQL INSERT are properly terminated. 2002-09-12 Roman Danyliw * src/output-plugin/spo_database.c - made the updating of the sensor.last_cid more efficient by only storing the new cid value at shutdown - removed extranous CR/LF from sensor name 2002-09-05 Chris Green * src/log.c (PrintICMPHeader): off by one error in printing Thanks to Dave Goldsmith 2002-09-05 Roman Danyliw * src/output-plugin/spo_database.c: (DatabaseInit) - added ignore_bpf configuration option (from Michael Boman) ignore_bpf - Do we want to create a new sensor definition everytime the BPF filter is changed? The options are: [no|0]: (default) Create a new sensor definition if BPF filter has been modified [yes|1]: Ignore the BPF part when looking for the server definition 2002-09-03 Roman Danyliw * src/output-plugin/spo_database.c - DB schema v106 - Added the sensor.last_cid field to the schema so the database can store the last used cid for a given sensor. This field will ensure that a cid will never be reused. Upgrading from v105 -> v106 is as simple as: mysql> ALTER TABLE sensor ADD last_cid INT UNSIGNED NOT NULL; mysql> UPDATE schema SET vseq=106; psql> ALTER TABLE sensor ADD last_cid INT8; psql> UPDATE schema SET vseq=106; - Improved error messages 2002-09-02 Chris Green * configure.in: - cleaned up win32 source packaging 2002-08-27 Andrew R. Baker * src/preprocessors/spp_asn1.c: do not check fragments 2002-08-26 mfr * src/threshold.c src/threshold.h src/detect.c src/rules.h src/parser.c added thresholds to snort rules language, docs to come 2002-08-26 Andrew R. Baker * src/util.c: fix GenHomenet and GetObsfMask functions 2002-08-19 Chris Green * src/preprocessors/spp_perfmonitor.c (ParsePerfMonitorArgs): typo in fmt string 2002-08-18 Chris Green * src/preprocessors/spp_rpc_decode.c: Port changes from Andreas Ostling ( just like all the other ones now ) * win32/perf stuff from Chris Reid Will probably break again later the perf stuff is very highly subject to change * project fixes from Chris Reid 2002-08-16 Brian Caswell * src/util.c - allow daemon mode to dump stats to syslog 2002-08-15 Chris Green * src/preprocessors/spp_stream4.c (ParseStream4Args): - FatalError on unknown argument (ReassembleStream4): - Correctly mark sessigons as established with asynchronous_link enabled 2002-08-14 Chris Green * src/snort.c (ParseCmdLine): -R Include 'id' in snort_intf.pid file name (Phil Wood) * src/snort.c (ProcessPacket): reset uri_count (test case pointed out by Dan Roelker/Sourcefire) * src/preprocessors/spp_http_decode.c: uri_count set if not alerting. 2002-08-13 Chris Green * src/preprocessors/spp_conversation.c: new option alert_odd_protocols set allowed_ip_protocols to the numbers you like and it will alert on all bad protocols * src/detection-plugins/sp_session.c (LogSessionData): sp_session.c:221: warning: suggest parentheses around && within || * src/detection-plugins/sp_pattern_match.c (CheckANDPatternMatch): bug with mutliple decoded alternative contents 2002-08-13 Roman Danyliw * src/output-plugins/spo_database.c (CheckDBVersion): fixed logic to detect the DB schema version correctly when support for MS-SQL and another database are present 2002-08-13 Chris Green * src/preprocessors/spp_telnet_negotiation.c: - cleaner alt_dsize checks - make sure that we don't decode 1 byte past the end of the buffer -(SetTelnetPorts): preprocessor telnet_decode: 21 23 25 119 (now with port lists!) * src/detection-plugins/sp_pattern_match.c (PayloadSearchRawbytes): new pattern match option! rawbytes -- used to inspect the raw packet data instead of the alternatively decode application packet buffer * src/decode.h (DECODE_BLEN): my favorite constant typo. * src/preprocessors/spp_stream4.c (Stream4InitReassembler): turning off server side reassembly by default ( was what the default said it was ) * src/detection-plugins/sp_tcp_flag_check.c (ParseTCPFlags): adding mask bits to the flag checks (limitation pointed out by Dirk Mueller) example: flags: S,12 This checks the SYN flag is set regardless of the values of the ECN bits. tcp_flags & (0xFF ^ tcp_mask); for those of you that like to think in C * src/detection-plugins/sp_pattern_match.c (Check{AND|OR}PatternMatch): - normalization of telnet stuff into a separate buffer (this means logged packets will now look like they should on the wire) 2002-08-12 Chris Green * src/preprocessors/spp_telnet_negotiation.c (SetupTelNeg): - only allow this to be called telnet_decode - removing redundant function calls * src/perf-event.c (ProcessEventStats): - set to 0 (djr@sourcefire) 2002-08-12 Roman Danyliw * src/output-plugins/spo_database.c (Database) - Fixed length bug in code that generates the SQL INSERT statement into signature table 2002-08-08 Chris Green * src/preprocessors/spp_arpspoof.c (ARPspoofPreprocFunction): - include packet w/ alert (Jeff Nathan) 2002-08-07 Chris Green * preprocessor perfmonitor --enable-perfmonitor lots of statistics from Dan/Marc/Sourcefire 2002-08-06 Chris Green * src/checksum.h: Integrated fix from Marc Norton/Sourcefire occasional endianess bug in checksum routines inlined checksum 2002-08-05 Chris Green * src/preprocessors/spp_stream4.c (UpdateState): make session initiators more lenient 2002-08-04 Chris Green * src/preprocessors/spp_stream4.c (BuildPacket): - Session fix ( a different approach from Andreas Ostling ) (UpdateState) (UpdateStateAsync) - Move == TH_ACK checks to nearly the last of the checks and make catch all odder flag combinations - ttl_limit will only alert if the packet ttl is less than 10 (TcpAction*): - removed stream_pkt->packet_flag sets new ( makes no sense because we overwrite the packet_flags in BuildPacket ( pointed out by arron walters -- ended up being the source of a few other bugs ) 2002-07-30 Chris Green * src/preprocessors/spp_stream4.c (BuildPacket): - Mark the session direction establishments correctly (thanks to Andreas Ostling for noticing ) 2002-07-29 Chris Green * src/preprocessors/spp_stream4.c (ReassembleStream4): - make unestablished sessions and established sessions mutually exclusive - use & 2002-07-26 Chris Green * src/decode.c: added decode_alert_flag one may disable decoder alerts by using config disable_decode_alerts * src/preprocessors/spp_portscan2.c (PrunePortscanners): Portscan2 fixes from Jed Haile ( thanks :-) ) * src/decode.c (DecodeICMP): 8 bytes of extra info in a redirect, not 4 2002-07-23 Chris Green * Phil Wood ASN.1 fix * Phil Wood Classification fix * Andreas Ostling's BPF comment improvement * Just for the record, marty added distance/width as content options distance means there must be atleast N bytes between 2 matches width means that there must be a match within N bytes 2002-07-23 Andrew R. Baker * src/output-plugins/spo_SnmpTrap.c: - fix null pointer dereference for non-IP packets 2002-07-09 Chris Green * src/detection-plugins/sp_dsize_check.c (CheckDsizeRange): - changed dsize check to always return 0 on fake tcp pkts ( mirrors change made on all other functions .. ) 2002-07-08 Chris Green * Merged in win32 fixes from Chris Reid (thanks again!) 2002-07-05 Andrew R. Baker * src/preprocessors/spp_frag2.c: * src/preprocessors/spp_stream4.c: - fixed packet_flags problem with rebuilt packets 2002-07-03 Chris Green * src/output-plugins/spo_SnmpTrap.c: - lots of *nArgs = 0 instead of NULL - added prototype for ipv6_print_hashing 2002-07-02 Chris Green * src/preprocessors/spp_stream4.c (TcpAction): - switched to using psuedo random flush points * src/preprocessors/spp_portscan2.c (PrunePortscanners): - fixed double delete of a tree node * compilation fixes from Chris Reid for win32 (Thanks!) 2002-07-01 Chris Green * src/preprocessors/spp_conversation.c (ConvCompareFunc): - fixed session equalness bug ( portscan2 should actually seem reasonable now ) (ConvFunc): - changed to use conf_flags for session initiation 2002-06-28 Chris Green * src/preprocessors/spp_stream4.c * src/decode.h (PKT_STREAM_INSERT): added a packet marker for inserted stream packets 2002-06-27 Chris Green * src/util.c (FatalError): fflush(*) * src/detection-plugins/sp_dsize_check.c: dsize checks always will return 0 for rebuilt stream packets (CheckDsizeRange): added min<>max range support for dsize option Thanks to Andreas �stling * src/parser.c (ParseConfig): missing return for config daemon thanks to Bill McCarty 2002-06-26 Chris Green * From Jeff Nathan: Moved resp* stuff to the OTN instead of RTN * spp_conversation rewrite * portscan2 * SNMP updates from Glenn Mansfield Keeni 2002-06-24 Chris Green * src/detection-plugins/sp_icmp_seq_check.c (ParseIcmpSeq): htons(ds_ptr->icmp_seq) from Andereas Ostling 2002-06-20 Andrew R. Baker * src/detect.c: fix event reference time for unified output 2002-06-20 Chris Green * src/preprocessors/spp_portscan2.c - parsing fixes from Phil Wood * src/util.c: - FreeToks fixes from Phil Wood 2002-06-16 Chris Green * src/preprocessors/spp_stream4.c Andrew Hintz bug reports (BuildPacket): - reinjected packets are now marked as established as well as rebuilt (UpdateState): - Server initiated: APF -> AF -> A was not properly terminating session 2002-06-13 Chris Green * src/output-plugins/spo_log_tcpdump.c (LogTcpdump): fixed broken -b -l . mode ( assuming iph is set doesn't work ) 2002-06-12 Chris Green * src/util.c (read_infile): close fd for -F 2002-06-11 Chris Green * src/preprocessors/spp_arpspoof.c: Fixes from Jeff Nathan * src/preprocessors/spp_asn1.c (ASN1Decode): ASN1 fix from Chris Reid 2002-06-08 Chris Green * src/generators.h (FRAG2_TTL_EVASION_STR): changed TTL Limit exceeded message to make more clear 2002-06-08 Andrew R. Baker * src/output-plugins/spo_log_tcpdump.c: * src/detect.c: * src/decode.h: make obfuscation work for all output plugins 2002-06-07 Chris Green * src/preprocessors/spp_stream4.c (ReassembleStream4): - accidentally inverted logic for async/normal sessions - marking streams as established correctly 2002-06-05 Chris Green * src/generators.h (STREAM4_TTL_EVASION_STR): changed so that people recognize message as ttl_limit related and not message related 2002-06-04 Chris Green * src/preprocessors/spp_http_decode.c: - fixed include order ( fixes compile on FreeBSD ) * src/preprocessors/spp_frag2.c (InsertFrag): - allow duplicate first fragment to be disabled 2002-06-03 Chris Green * src/detection-plugins/sp_clientserver.c (ParseFlowArgs): - added {no_stream,only_stream} keywords to flow: used to suppress reassembled streams from being alerted on * src/plugbase.h: changed machine/param.h -> sys/param.h 2002-06-03 Andrew R. Baker * src/output-plugins/log_tcpdump.c: fix obfuscation 2002-06-02 Chris Green * src/Makefile.am: added plug_base.h ( pointed out by Jeff Nathan ) 2002-05-30 mfr * src/log.c src/decode.c: Fixed non-functional embedded packet decode and printout for ICMP UNREACH and REDIRECT packets 2002-05-30 Chris Green * src/preprocessors/spp_frag2.c (Frag2Init): - left frag2 alerts on by default by accident (diabled) 2002-05-28 Chris Green * src/detect.c (CallLogFuncs): moved the traversal of the plugins ahead of the setting the packet logged flag since both check ( should both check? ) 2002-05-28 Andrew R. Baker * src/log.c: fix NULL pointer deref problem printing priority/class info 2002-05-27 Chris Green * src/preprocessors/spp_http_decode.c (SetPorts): - fatal error on invalid port description * rules.c (VarGet): - fatal error if undefined variable is called (ExpandVars): - don't expand variables inside "'s 2002-05-21 Chris Green * src/preprocessors/spp_stream4.c (StoreStreamPkt): - sheltered fast restransmission under evasion_alerts - missing returns 2002-05-20 Chris Green * src/preprocessors/spp_http_decode.c: - added newer unidecode function from rfp - added "internal_alerts" keyword 2002-05-19 Andrew R. Baker * src/output-plugins/spo_log_ascii.c: * src/preprocessors/spp_conversation.c: * src/preprocessors/spp_conversation.h: * src/preprocessors/spp_portscan2.c: * src/preprocessors/spp_portscan2.h: - corrected some global namespace pollution 2002-05-15 mfr * looked over and indented the hell out of spp_conversation and spp_portscan2 * put a FreeToks() function into util.c to clean up after mSplit()'s * other sundry stuff, conversation and portscan2 should be ready for testing from what I can see now 2002-05-15 Andrew R. Baker * src/output-plugins/spo_SnmpTrap.c: * src/output-plugins/spo_alert_smb.c: * src/detections-plugins/sp_react.c: - fixes for new SigInfo system * src/output-plugins/spo_idmef.c: * src/output-plugins/spo_idmef.h: * doc/README.IDMEF: * src/plugbase.c: * src/plugin_enum.h: - remove IDMEF instead of leaving it in a broken state 2002-05-14 Chris Green * src/util.h (GenObfuscationMask): make compile on OS X 2002-05-14 Andrew R. Baker * *.[ch]: - proper implementation of priority and reference signature metadata - other work surrouding signature metadata 2002-05-14 Chris Green * templates/sp_template.[ch]: - updated template for plugbase and modularity * src/preprocessors/spp_stream4.c (CreateNewSession): - added SYN_SENT initialization state * src/preprocessors/spp_http_decode.c: - fixed includes for WIN32 (Chris Reid) * src/preprocessors/spp_stream4.c (_Stream4Data): - added asynchronous_link useful for places that only see one side of a conversation - (UpdateState): mark session as established on asynch links 2002-05-13 Chris Green * src/snort.c (ProcessPacket): - added min_ttl check in front of Preprocess Check * src/snort.h (_progvars): - added min_ttl as a snort-wide configuration option config min_ttl: 1 to drop all things less than 1 config min_ttl: 0 to have none (default) * src/decode.c (DecodeTCP): - fixed bug where we didn't just toss invalid packet after alerting on it in decoder (DecodeEapolKey): - removed CallLogPlugins redundant call * src/generators.h - moved all plugin alert descriptions here * src/plugin_enum.h: - moved all PLUGIN_ constants to a single header * src/detection-plugins/sp_pattern_match.h: - cleaned up commented define * src/preprocessors/spp_http_decode.c (PreprocUrlDecode): - commented out spurious debug code * src/preprocessors/spp_stream4.c (StoreStreamPkt): - disable evasion alerts 2002-05-12 Chris Green * src/preprocessors/spp_http_decode.c (PreprocUrlDecode): - more debug code - set p->uri_count * src/parser.c (ParseConfig): - cleaned up some NULL dereferences 2002-05-09 Chris Green * src/preprocessors/spp_stream4.c: - moved SSNFLAG defines to decode.h so that we have access to the Session data outside of spp_stream4 - added SSNFLAG_HTTP_1_1, SSNFLAG_SEEN_PMATCH - moved Session,Stream to decode.h (ReassembleStream4): session_flags converted to & check instead of == for establishment * src/decode.h - added HTTP version constants 2002-05-08 Chris Green * src/decode.h (_Packet): - removed URI - added uri_count (_HttpUri): - changed to added parameters (_UriParam): - added parameter datastructure (VTH_VLAN): - fixed missing paren * src/preprocessors/spp_http_decode.c (SetPorts): - removing strncasecmp (PreprocUrlDecode): - moved to using UriBufs * src/decode.c: Added UriBufs * src/decode.h: - changed to use TRH and VLAN macros bitpacked notation expunging should be done 2002-05-07 Chris Green * src/decode.h (_TCPHdr): - changed to use TCP_OFFSET, TCP_X2 Macros * src/parser.c (ParseConfig): * src/snort.c (ParseCmdLine): - Fixed notcp,noicmp,noudp,noip to only disable - strcasecmp instead of strncasecmp * src/preprocessors/spp_http_decode.c: integrated spp_http_decode.c from rfp new option set: * unicode: decode unicode * iis_alt_unicode: %u000 encoding * double_encode : detect IIS decoding * abort_invalid_hex: detect only up until the first broken encoding * drop_url_parm: don't decode the stuff following ? * iis_flip_slash: substitute / for \ ( C:\DOS\RUN ) * full_whitespace: treat \r and as 2002-05-06 Chris Green * src/preprocessors/spp_stream4.c: fixed retranmission checksum alerts to live under evasion * src/detection-plugins/sp_pattern_match.h: commented out PATTERN_FAST until it works * src/generators.h: internal alerts from spp_http_decode 2002-05-01 Andrew R. Baker * src/plugbase.c: * src/output-plugins/spo_unified.c: cleaned up startup message printing 2002-04-25 Chris Green * Introduced IP_VER, IP_HLEN, SET_IP_VER, SET_IP_HLEN after thinking about tcpdump and what Fyodor had talked to me about months ago regarding cross platform compatiblity. No more twiddling. Plugins that use ip_ver, ip_hlen should be tested. No more bit packed notation allowed in the source tree. * src/preprocessors/spp_stream4.c: separated evasion alerts from retransmission/state evasion alerts default to being on now disable with disable_evasion_alerts 2002-04-24 Chris Green * src/preprocessors/spp_frag2.c (Frag2Init): fixex argument parsing * src/preprocessors/spp_http_decode.c: don't process fragments * src/preprocessors/spp_frag2.c (InsertFrag): make sure that we don't run out of memory if someone sends us the same fragment over and over again duplicate first frag is a special case 2002-04-23 Chris Green * src/preprocessors/spp_frag2.c (InsertFrag): - adding detection of attack where we would start reassembling packet fully before the full fragtracker is there * src/detect.c (EvalPacket): - fixed alert ip rules (got clobbered when playing detection engine optimizations ) - generate proper events when decode errors happen * src/plugbase.c (InitPlugIns): SetupFragOffset() * src/detection-plugins/sp_ip_fragbits.c: - added fragoffset: fragoffset: [!<>] defined in fragbits so that I can backport it. * src/preprocessors/spp_frag2.c (InsertFrag): - alert on frag2 overlaps To do this requires keeping the packets around for a while longer to detect all the multiple fragments and overlaps Changed the PruneCache to notice when things are completed and prune them in addition to just by time. Frag mem faults are going to increase because of this but each time one occurs, there should be plenty to expire. 2002-04-22 Chris Green * src/preprocessors/spp_frag2.c (Frag2Defrag): Warn/Discard on fragments with IP Options set. (ParseFrag2Args): min_ttl ttl_limit detect_state_problems * src/debug.h DEBUG_FRAG2 * src/preprocessors/spp_stream4.c (TraverseFunc): - added next seq check on reassembly - added alerts on retransmitted sequences... its ugly as sin right now (_Stream): - next_seq added (StoreStreamPkt): - added check for restranmitting too fast w/ a different data size - added tcp checksum retransmission checking (how much do I need to worry about data with the same checksum and different payloads... just throw it away for the moment) 2002-04-19 Chris Green * More win32 Service patches from Chris Reid ( Thanks! ) 2002-04-18 Chris Green * src/preprocessors/spp_frag2.c (Frag2Defrag): added ttl_limit detection * src/generators.h (FRAG2_TTL_EVASION): added * src/preprocessors/spp_stream4.c (StoreStreamPkt): -- first cut at TTL evasion detection keyword: ttl_limit for TCP Sessions 2002-04-16 Andrew R. Baker * src/preprocessors/spp_stream4.c: * src/preprocessors/spp_frag2.c: * src/preprocessors/spp_asn1.c: * src/log.c: * src/detect.c: fix broken event reference info for unified output 2002-04-15 Chris Green * src/preprocessors/spp_stream4.c (ParseStream4Args): added missing parsing line back in 2002-04-10 Andrew R. Baker * src/output-plugins/spo_unified.c: fix unified brokeness 2002-04-10 Andrew R. Baker * src/plugbase.h: * src/plugbase.c: * src/parser.h: * src/parser.c: Plugin API cleanup * src/output-plugins/spo_log_tcpdump.c: make log file timestamps work the same as in unified 2002-04-09 Chris Green * src/spp_portscan2.c: new changes from Jed/Jason 2002-04-08 Andrew R. Baker * add profiling configuration option * src/parser.c: correct NULL pointer dereference 2002-04-08 Chris Green * src/debug.c (GetDebugLevel): accidenatlly returning debuglevel instead of debug_level * src/log.c (PrintIPHeader): Modified fragment offset calculation (reported by Judy Novak) 2002-04-07 Chris Green * Fixed --enable-debug * src/preprocessors/spp_asn1.c: Missing includes 2002-04-06 Chris Green * src/detect.c (EvalHeader): Corrected incorrect ignore with -z est and PKT_REBUILT_STREAM * src/detection-plugins/sp_tcp_ack_check.c (ParseTcpAck): * src/detection-plugins/sp_tcp_seq_check.c (ParseTcpSeq): Phil Wood's Parsing Change 2002-04-05 Martin Roesch * detection engine now walks RTN and OTN lists iteratively instead of recursively, I guess we should cowtow to the x86 crowd... * RTNs are now sorted by destination port number allowing for earlier exit from the detection engine in the average case and improving performance * destination port is now the first thing checked when an RTN is processed (for UDP/TCP traffic) 2002-04-05 Chris Green * Merged in Nick L. Petroni, Jr.'s 802.11b stuff * src/detection-plugins/sp_pattern_match.c: Integrated Mike Fisk's SetMatch stuff ( large performance increase -- thanks for being so patient with me ) 2002-04-04 Chris Green * src/snort.c (SnortMain): Extra call to initoutput plugins commented out.. * src/detect.c (CallAlertPlugins): DEBUG_WRAPPED Andrew's printfs' 2002-04-03 Chris Green * src/debug.h: DEBUG_WRAP defined DEBUG WRAP used everywhere... * src/preprocessors/spp_conversation.c: ignore rebuilt stream 2002-04-02 Andrew R. Baker * Modularization cleanup 2002-04-02 Chris Green * src/debug.c (GetDebugLevel): only initialize debug_level once ( now easier to use gdb set command ) * src/preprocessors/spp_portscan.c: No processing on reassembled stream packets * lots of compilation fixes * started added spp_conversation 2002-04-01 Andrew R. Baker * config.h should be included almost everywhere.... 2002-03-31 Chris Green * src/detection-plugins/sp_pattern_match.c (CheckUriPatternMatch): Check for URI.uri with a packet flag * src/preprocessors/spp_http_decode.c (PreprocUrlDecode): - Moved decode ignore check up ( I don't think this is actually used anywhere ) - Moved somefunctions into CheckHTTPDecode * decode.h: - Changed URI.uri to u_int_8t[URI_SIZE] - URI_SIZE is 512 (should create an alert when that size is exceeded) - Added PKT_HTTP_DECODE to show if URI was filled in 2002-03-31 Andrew R. Baker * start work on cleaning up the output API 2002-03-30 Chris Green * src/output-plugins/spo_alert_unixsock.c: lots more checking for valid packets on things like portscan alerts 2002-03-29 Andrew R. Baker * src/parser.c : Add support for "special" output plugins * src/output-plugins/spo_unified.h : * src/output-plugins/spo_unified.c : Initial work towards a true unified output. 2002-03-29 Chris Green * src/preprocessors/spp_stream4.c (ReassembleStream4): * src/snort.h: removed pv.fake_packet check (old stream stuff) 2002-03-27 Chris Green * src/preprocessors/spp_stream4.c : More debug messages in Stream4 * doc/PROBLEMS: Added file to document bugs that we really can't work around easily and aren't necessarily ours. * src/parser.c (ParseRuleOptions): filename -> file_name for compilation 2003-03-26 Andrew R. Baker * src/output-plugins/spo_unified.c: fix file rotation bug in spo_unified write IPs in host order like everything else is * src/parser.c: updates to the rule parser. now we only complain for unrecognized rule options. 2002-03-26 Chris Green * src/detect.c (DumpChain): DebugMessage stuff.. 2002-03-25 Chris Green * stop stream4 from clobbering itself (Pascal Bouchaeine) 2002-03-24 Chris Green * src/plugbase.c (RegisterPlugin): - allow multiple plugins to start with same prefix 2002-03-23 Brian Caswell * initial add of flow: to signatures 2002-03-21 Chris Green * Place IP checks after port checks for 1.9 (based on patch from Christian Mock) * Fixed test header checks (greatly responsible for slowness on multiple CIDR blocks) (Christian Mock) 2002-03-19 Chris Green * Fixed Teardrop detection in frag2 ( Forward bugfix from Marty ) * Replaced most instances of #ifdef DEBUG\nprintf(...) with DebugMessage 2002-03-11 bmc * readded this file :) * renabled udp portscan detection * updated ICMP text printing (few bugs, few new features) * updated BUGS for jackasses on Bugtraq * fixed a bunch of stream4 stuff * cleaned a ton of signatures (see signature CVS logs for info) * number of FAQ updates * removed unstable/orphaned/unmaintained/deprecated code as we get ready for 2.0 * massive directory structure reordering * frag2 options code cleanup (cmg) * fixed pattern match exit conditions (cmg) * improved stats calculation (phil wood) * tweaked decoder code * improved ICMP ASCII output * fixed no-packet bug in spo_unified * moved alert code in spp_frag2 so packet is logged for teardrop * many stream4 fixes * added sp_clientserver (to client, to server, from client, from server) * cleaned infinate loop in regex * fix double PID write (reported by phil wood) * updated docs * ton of new signatures * split rules.c into parser.c|h and detect.c|h * smarter pruning for segments that have only partially been streamed * ethernet headers are now filled in for rebuilt packets * added case for stream segments that hadn't been completely handled in previous flush * added another interface init call when entering daemon mode for linux boxen that lose promisc mode when the process forks * strncat in sp_reference * opts[1] fix to plugin args passing * updated changes to db stuff from Roman * removed $default_directory from mysql_directory definition to allow --with-mysql to work again and select a non-default installation * fixed calloc call for PPPoE debug #ifdef DEBUG * Fixed pointer math for Stream4 sesesion ( IOU: Phil Wood; 1 Bar tab ) * Fixed suicidal tree pruning * ifdef AF_INET6 for decode.c and removal of spp_asn1.h from plugbase.h * cleaned up decode.c indentation, etc * added classifications for spp_fnord * mods to icmp ASCII log code for more informational printouts * added enhanced conf file parsing for frag2 (Chris Green) * added pattern match fixes (Chris Green) * other stuff that escapes me right now * pflog decoder support from Robert Fleck added * cleaned up decode.c indentation, etc * added classifications for spp_fnord * mods to icmp ASCII log code for more informational printouts * added enhanced conf file parsing for frag2 (Chris Green) * added pattern match fixes (Chris Green) * added enhanced resolution of TCP retransmissions to stream4 * changed default behavior of frag2 to favor old data over new * fixed screwed up fragbits printout * Fixed pointer arithmetic in calls to PrintNetData (thanks to Andreas �stling bugreports) * ntohs(p->iph->ip_len) -- should we have a p->ip_len? * don't complain about NULL ptr if p->dsize == 0 * Still has one nit in that a badly framed packet is counted twice in -v mode2 2001-11-29 bmc * Fixed crash in frag2 under Linux * Fixed flexresp code, session sniping should work again and be faster to boot * Fixed ICMP decoder and printout routines for new ICMP header data structs in decode.h * Added -B command line switch to translate IP addresses in pcap files from one subnet to another (see the man page). * Added spo_log_null to give users an option to deactivate logging output from the snort.conf file. 2001-11-02 mfr * fixed UTC timestamps * fixed SIGUSR1 handling, should reset properly now after getting a signal * fixed PID path generation code, PID files go in the right place now * fixed stability problems in stream4 * fixed stability problems in frag2 * tweaks to spo_unified for better integration with barnyard * added -f switch to turn off fflush() calls in binary logging mode * added new config keyword to stream4, "log_flushed_streams", which causes all buffered packets in the stream reassembler for that session to be logged in the event of an event on that stream (must be used in conjunction with spo_log_tcpdump) * added packet precacheing for flexresp TCP packets, responses should be generated more quickly * fixed rules parser code for various failure modes * several new rules files and a new classification system 2001-08-14 mfr * SNMP alerting support added by Glenn Mansfield Keeni & K. Jayanthi * IDMEF output support compiled in by default now * regex keyword code repaired, limited wildcard regex now available * new packet counters added to Snort stats output for frags and streams * http_decode preprocessor modified to normalize %u encoding * new detection modes in frag2, Snort picks up fragmentation attacks (teardrop, etc) much better now * repaired frag2 IP defragmenter, now 100% stable and functional * tweaks made to stream4 TCP stream reassembler, now 100% stable * Win32 code integrated with main Snort source now * fix for -r mode crash when no other command line options specified * fix for logfile names using ":" under win32 * tag code repaired * spp_arpspoof repaired * stream4 alerts are now off by default * syslog alerts now support standard GEN:SID:REV data 2001-08-04 fy * A couple of coredump fixes from Phil Wood * Solaris compilation fixes (and other minor tweaks I don't remember) * Incorporated WIN32 patches (and fixes) from Chris Reid * ms-sql support from Chris Reid * contrib/create_mssql 2001-07-09 mfr * added new IP defragmenter, spp_frag2 * added new stateful inspection/tcp stream reassembly plugin, spp_stream4 * Snort can now statefully detect ECN traffic (less false alarms) * stream4 can now keep session statistics in a "session.log" file * added new high-speed unified binary output system, spo_unified * added new data structs/management for tag code * added -k switch to tune checksum verification behavior * added -z switch to provide stateful verification of alerts * modified bahavior of http_decode, now only alerts once per packet * added unique Snort ID's to every Snort rule, plus generator, revision and event ID info to each alert * detection engine only alerts once per packet now, tcp stream code doesn't generate another alert packet if a previous one already alerted for that stream * fixed signal handling on svr4 systems * added enhanced cross reference printout to full/fast/syslog alert modes * added new high speed checksum verification (on x86) routines * added new ARP spoof detection preprocessor from Jeff Nathan 2001-04-20 fy * a couple of fixes in spp_defrag.c * spelling fixes in 'classification.config' file 2001-04-19 bmc * added ability to tag sessions & hosts (By Seconds, Bytes, and Packets) * ip protocol rule support * added 802.1q VLAN support * extensive configuration file config options (you can put your commandline options in snort.conf now) * priority & classification plugin by Brian Caswell * output plugin support for priority, classification, and refs * rpc_decode plugin (Defeats attacks laid out by Robert Graham's SideStep) * telnet negotiation normalization plugin (Defeats attacks laid out by Robert Graham's SideStep) * BackOrifice plugin (Can bruteforce BO keys. Defeats attacks laid out by Robert Graham's SideStep) * uricontent keyword pattern match. (Now you can look at the URL instead of the entire packet) * added -T commandline option (Does entire setup process, but stops after its done setting up) great for snort.conf testing!! * added -L commandline option. Specify filename of the binary output log when combined with "-b" * added -G commandline option. Turn on "ghetto" backwards compatability for people that need references in the MSG field * added -I commandline option. Prints the interface that the alert was received on * added -y commandline option. Adds YEAR to the timestamps * Fixed timestamp output problem on some ARCHs * ability for non-root users to sniff. (If the user can usually sniff from pcap) By Brian Caswell * Improved UNICODE detection by Koji Shikata * added sp_tcp_win_check. TCP Window Size can be looked now * added CSV output (see README.csv for more information) By Brian Caswell * added sp_same_ip_check. Checks for the same SRC & DST (Usually sign of a DOS attack) by Phil Wood * added variable lookups for include directives (eg 'include $RULESPATH/myrules.rules') * linux_sll (interface 'any') support fixed (According to the new libpcap spec) By Fyodor * new debugging code. No more #ifdef DEBUG. (see debug.c for more info) Idea from Eugene Tsyrklevich * strl* family functions (mostly for future developers, we'd encourage these to be used) (original code also supplied by Eugene) * new tcp stream reassembly module by Chris Cramer * include directives now are relative to snort.conf file location (unless full path in a config file is given) * snort will look for /etc/snort.conf and ./snort.conf if no config is given on the commandline * minor null ptr fixes and patches there and here (thanks to all of you guys who helped tracking them down, really :-) - Fyodor) * optiomized database schema (Support for references, added signature normalization, ....) * UTC cleanup by Andrew Baker * http_ignorehosts added from Matt Wachinski 2001-03-14 fy * tcp stream reassembly updates by Chris Cramer * path fixes for include (now relative path'es will be substituted by path of the main file) * DLT_LINUX_SLL support fixes * strlcat/stlcpy functions are being incorporated * Attempt to support MacOS platform. * A bunch of fixes for MTU dicovery routine * New debugging routines. (see BUGS file for more info). 2001-01-02 mfr fy * tcp stream reassembly preprocessor (beta) by Chris Cramer * Defragmentation plugin is now fully functional on all architectures * SPADE (Statistical anomaly detection) preprocessor has been added by James Hoagland * Added IIS/UNICODE attack detection to HTTP decoder * Reference plugin has been added by Joe McAlerney * New active response module: sp_react * Added "any" keyword to IP options (ipopts) plugin * IP fragmentation bits detection plugin added * Added TOS detection plugin from Erich Meier * Database output plugin improved in many ways by Jed Pickel * Oracle support added to database output plugin * XML output plugin by Jed Pickel/Roman Danyliw/CERT * IP address list support added with lots of help from Phil Wood * _ADDRESS variable implementation, specifying an interface name in the rules file as part of this variable automatically sets the IP/mask as the IP address/netmask of the specified interface * Rule parser is more anal about rule verification now, doesn't crash as readily * Arbitrary output types support added by Andrew Baker * Activate/dynamic rules allow rules to turn on/off other rules! * ICMP unreach. printout dumps encapsulated headers now * Improved TCP/IP options printout code, doesn't flood on 0 length options * Packet checksumming implemented for all supported protocols by Chris Cramer * TCP flags now print out in proper (bitwise) order * Added new fields to the packet header dumps including IP header length, TCP/UDP header length, Urgent pointer printout, IP Reserved bit printout, ICMP Type/Code explicit value printout * -X switch dumps packet byte data for data link through application layer * -L switch to privde a filename for binary log files specified with the -b switch * Added -I switch to print interface name in Snort alerts (first i/f only) * Fixed -S command line switch so it isn't overridden by variables in the rules file * Corrected PID file misadventures * Added a bunch of new statistics to the packet stats printout * Added SIGUSR1 handler, Snort will dump packet stats to console/syslog when it receives a SIGUSR1 * Memory management cleaned up/lots more free()'s to match up with malloc()'s * Added snprintf code to the distro for safety * UID = 0 code added for sniffer mode * fixed default alert filename for daemon mode * Updated USAGE file to resemble Snort's current reality * Changed snort-lib to snort.conf, Jed Pickel added lots of documentation to the file as well (thanks Jed!) * Pid file will not be created if -D switch is not used. * chroot behaviour has been changed, now, if chroot is used, you have to have snort.conf file within chroot directory (and all the other relevant files as well). The only file which will be placed outside chroot directory is snort pid file. 2000-07-22 mfr * Fixed compilation problems on all non-BSD operating systems * Added better configuration support for locating libpcap * Fixed ICMP ping packet id/sequence printouts * Made allowances for 64-bit machines in the decoders * Updated the portscan detector to the latest version * Disabled the defragmenter by default (in the rules file) * Added a patch from Dave Dittrich to make daemon mode alerts filenames conform to the data in the documentation * Revamped the ICMP data structures to mimic those found in *BSD and provide for higher fidelity decoding/printout in the future * Repaired the output plugins so that they operate properly now * For the record, the payload dump conforms to the length of the IP datagram now and does not show pad bytes added by the minimum Ethernet frame size 2000-07-08 mfr * Fixed Tru64 u_int* type declarations * Added check for pcap.h into configuration script * Fixed timeval problems on Linux boxen 2000-07-06 mfr * New preprocessor plugin: IP defragmentation!! * New output plugins cover all old logging and alerting options * New output plugin now logs to MySQL, PostgreSQL, unixODBC databases * Updated portscan detection functionality * Added quote removal for most plugin parsers * -C crash bug fixed * PID/PATH_VARRUN file fixes * Converted many putc(3) calls to fputc(3) for portability * Transport layer decoders use ip_len field for length metric now * String tokenizer code modified for more reliable operation * Fixed flexible response code sequence prediction * Fixed DEBUG ifdef's so DEBUG mode code will compile correctly on all platforms * Set automake options so that people don't need gmake anymore to build Snort on BSD systems * Fixed SMB alert code large tmp file hole * Added sigsetmask code to fix SIGHUP weirdness * Added execvp option for SIGHUP restart code * Added ARP header printout validation * Added Session logging file integrity checking * Added -u/-g setuid/gid capability switches * Added -O IP address obfuscation switch * Added -t chroot switch * Fixed non-TCP/UDP/ICMP transport layer decoding & logging * Fixes and additions to the portscan preprocessor * Database logging plugin has been modified extensively, see the www.incident.org website for more information * Switched TCP flags printout routine to ensure proper RFP output scan output. ;) * Fixed default log/alert function code so that these functions are never NULL 2000-03-20 mfr * Version 1.6 released! 2000-03-18 mfr * Modified the PID write out code to work in all run modes, and made the system detect/verify the _PATH_VARRUN variable and define it if necessary. * Integrated a HUP patch from J Cheeseman to prevent the command line parser from screwing up the command line at HUP time. * Added a little tweak from Fyodor for Makefile.in * Made exit code delete the PID file in all run modes. 2000-03-16 mfr * Activated the BPF compiler optimization switch in snort.c * Added support for unconfigured/stealthed network interfaces * CP added a default definition for _PATH_VARRUN * CP added checks for paths.h existence 2000-03-15 mfr * Moved the "session" keyword code to a plugin * Added Postgres database logging module from Jed Pickel * Added Token Ring layer 2 printout routine * Added "-q" support to the output plugin modules * Revamped the output plugin subsystem so that it conforms to the API standards laid out in the rest of Snort * CP set defaults for the alerting and logging facilities * Added Tru64/Alpha support 2000-02-26 mfr * modified minfrag proprocessor to only catch tiny frags on the home net ("home" keyword) or any traffic ("any" keyword) * implemented command line override of output plugins, alert and log switches on the command line will disable output plugins in favor of their configured activity * added -C command line switch to print packet payloads as ASCII only, with no hexdump * fixed a stupid crash bug on the "logto" keyword parser * put in a couple of command line switch validators to catch potential invalid arguments * fixed a potential crash bug in the ClearDumpBuf() function 2000-02-07 mfr * Added INADDR_BROADCAST patch from Steve Beaty * Added syslog PID patch from Ralf Hildebrant * Added IPv6 counter from Erich Meier * Added SunOS patch from Denis Ducamp * Added content-list rules from 2000-01-17 cp * Update of Patrick's portscan preprocessor. (and apropriate fixes) * Minor fix to configure.in from Herb Commodore. 2000-01-12 cp * John Wilson's update to insensitive pattern match code added. * Patrick Mullen's patch to log.c applied. * Patrick Mullen's changes to rules.c added. * Source Port traffic rules ajusted not to pull alerts on 53<-->53 UDP traffic. * Changed name ParseFlags to --> ParseTCPFlags in sp_tcp_flag_check.* since that's what it really is. * Added RCS Id tags to all the files and libs. Once they are commited at md.prestige.net, they should take proper values. :) 2000-01-08 cp * Patch from Herb Commodore to configure applied * Imrovements to content-matching code and implementation of case-insensitive matching from John Wilson * fixed a problem with pass rules not being applied properly * fixed a #include ordering statement for Slackware 4.0 installs * fixed banner output for the -V option * Token Ring decoding is now fully functional * Added packet buffer cleanup code to all protocol decoders * fixed a problem with improper TCP option output * Added a Snort man page 1999-12-08 mfr * preprocessor plugins (major new functionality!) * detection plugins (major new functionality!) * variables can now be specified in the rules file * include files can now be specified in the rules file * Session recording capability * Rules may now contain multiple "content" match keywords * New IP options detection module, allows IP option inspection * New HTTP decoder preprocessor defeats evasive web scans (whisker.pl) * detection engine has been heavily modified to implement the new "linked-list-of-function-pointers" concept, which makes the detection engine more efficient, more flexible, and faster! * TCP options decoder split into decode/log modules and recoded * IP options decoder split into decode/log modules and recoded * Token Ring layer 2 decoder (still in development) * ISDN-Raw layer 2 decoder (I4L) * ISDN-IP layer 2 decode (I4L) * ISDN-Cisco layer 2 decode (I4L) * Fixed PPP layer 2 decoder * NULL/Loopback layer 2 decoder * daemon mode code cleanup * tcpdump readback mode code cleanup * experimental support for UNIX socket alerting * fixed C++ comments in snort.c * binary log files now update properly (fflush added) * internal rules list integrity testing * IP fragments are no longer sent to the detection engine, just the preprocessor's. This is incentive for me (or someone) to write an IP defragmentation preprocessor! * post-decode call function call sequence has been modified to go into the preprocessor system instead of the detection engine 1999-10-18 mfr * snort.c: * added session dump command line switch * log.c: * added sesion data logging functionsi: OpenSessionFile(), DumpSessionData(). * decode.c: * fixes snaplen issues with reading back tcpdump files. 1999-10-13 mfr * snort.c: * threw out tcpdump file readback code and implemented open_pcap_offline solution. Has addded benefit of allowing BPF filters to be used to modify file readback streams. * Fixed MTU snafu. * decode.c: * Rewrote ARP decoder. The decoder is much simpler (but the log routines are far more complex) * Horsed around with the TCP and IP option decoders. I think they work better now... * log.c: * Added ARP printout and logging routines. ARP is now handled in a much more consistent and correct manner. * Fixed stupid crash bug in LogPkt() * rules.c: * Added in greater-than and less-than modifiers for dsize option keyword. You now have another (cheap!) way to look for buffer overflows * Removed range checking for the ICMP icode and itype option keywords so that DoS attacks and covert activity could be more easily filtered/monitored 1999-09-26 mfr * snort.c: * new command line options -A, -F, -N, -p, -b * logging and alerting functions are now selected and assigned to function pointers for faster/more efficient logging * got rid of -f command line option (superceded by -b) * put in new cleanup code for readback mode * ripped read_infile from tcpdump to read BPF filter files * decode.c: * code cleanup in support of new functionality * rules.c: * added support for the exception operator to work for ports * fixed stupid pointer initialization bug in ProcessHeadNode() file, fixed crashes on non-PC arch. * new option keywords: dsize, offset, depth * cleaned up crappy logic around the logging functions with nice clean function pointers (aaaahhhh....) * added bidirectional rules functionality (now Snort goes both ways....) * log.c: * broke out alerting function into separate subfunctions * ditto logging functions * fixed string termination code in the SMB alerter so that it can now alert to more than one box at a time * cleaned up syslog messages * finally fixed the SMB "alert once" problem (kudos to Gandalf Schaufelberger for that one) 1999-08-06 mfr * log.c: * added code to AlertMsg to make sure that there was in fact an alert message to print out * libraries: * fixed the backdoor and scan libraries so they should flase alarm less often 1999-08-05 mfr * snort.c: * activated CyberPsychotic's daemon mode code (use the -D switch for daemon mode * default logging directory changed from "." to /var/log/snort * sanity checks performed on the default log dir now * decode.c: * changed the truncated Ethernet header notification to only go off in verbose mode * removed cruft * rules.c: * Added Ron Snyder's "address negation" patch. Rules may now contain "!" on the IP addresses to indicate anything BUT the given address * log.c: * added support for the new default logging directory * configure.in: * fixed some more sparc configuration problems * other: * CyberPsychotic sent a new ftp buffer overflow rule in 1999-08-04 mfr * snort.c: * fixed some DEBUG statements * enabled the daemon mode code (this is still experimental) * decode.c: * fixed various and sundry DEBUG code * fixed the TCP option decoder so it wouldn't overflow its prinout buffer and cleaned up the temp buffer * rules.c: * fixed some DEBUG code * log.c: * fixed a buffer copy problem with the daemon mode alert logging * fixed the SMB alerting code and the standard log output when in SMB alerting mode * cleaned up some of the fragment logging code * fixed the logto rules option coding to work properly * configure.in: * fixed a whole bunch of little problems that are screwing up big endian/non-PC machines. This version should work and compile much more cleanly on all architectures! * other: fixed a bad rule in the RULES.SAMPLE file and another bad one in the misc-lib file 1999-08-01 mfr * rules.c: Wrote brand new detection engine. The new engine uses a 2-dimensional linked list with recursive node walking. Rules are grouped by address/port commonality and then option chains are linked to common head blocks. This reduces the number of tests required to find a specific test to perform, and reduces the total number of tests performed on a given packet in all cases by 200-500% over version 1.1. * decode.c: Rewrote the packet decode engine. The new engine performs far fewer copies and tries to set pointers to defer expensive function calls as late as possible. The PrintIP and Net data structures have been eliminated so that there is no global data required to perform tests or log a given packet. This will make any future multi- threading efforts much easier. * log.c: * Much of the logging system was rewritten to take advantage of the new detection and decoding engines. * Made the SMB alerting a configure-time option. If you want to use the SMB alerting feature, you need to specify a "--enable-smbalerts" when you run configure. This is a safety measure, read the INSTALL file for the reasons why! * snort.c: Fixed a bug in the netmask generation code that wouldn't allow certain CIDR blocks to be represented. Thanks to Nick Rogness for the heads up on this one! 1999-06-21 mfr * snort.c: * Added new command line switches: -f, -M, -r. -f: Record fragmented packets in tcpdump format -M: Send alerts via WinPopup messages (requires Samba) -r: Read and process files generated by tcpdump * Fixed startup dumpout code to not drop people if they just want to log all packets to the system * Added static netmask generation, this rids Snort of the need to link to libm, which makes it more Trinux friendly. * rules.c: * Added new rule option types: logto: log packets matching this rule to the specified log file minfrag: set the minimum size of fragmented packets, which allows alerts to be generated for traffic coming from things like nmap or fragrouter tcp flags: Added the ability to include the reserved bits of the tcp flags into the rules set. These flags are specified with a "1" and "2. Inclusion of these flags allows Queso fingerprinting attempts to be detected. id: The IP ID field may be specified. This is nice for picking up handcrafted packets with recognizable ID fields, like 31337 or other "elite" numbers. ack: The TCP ack field. Using this, nmap tcp "pings" may be detected. seq: The TCP sequence number. This is provided for completeness (I figured since I was putting in the ack field, I may as well include the sequence as well) * Rewrote the content parser. It now accepts "\" as a literal character, so things like "\|" or "\~" will work properly. * fixed the parenthesis finder for the options code * adjusted the acceptable character range in the rule parsers * log.c: * fragment logging more descriptive and correct * fixed IP header logging for ICMP and fragmented packets * improved "bad packet" printing/logging * fixed IP option output code * IP packet ID field now displayed * decode.c: * fixed IP fragment decoders and logic streams. * fragments are now fed thru the rules set (sorta) 1999-05-17 mfr * snort.c: Added "-x" command line switch to explicitly activate IPX packet notification so people in mixed protocol environments can maintain sanity. Also added in the new packet counter to generate statistics on exit of the number/percentage of each type of packet that Snort sees. * decode.h: Removed the references to u_int16_t and u_int32_t and replaced them with u_short and u_long. The u_int*_t variables caused portability headaches. Also added in the new patch from Chris S. for the WORDS_MUSTALIGN definition for S/Linux version. * log.h: Fixed the LOG_AUTH/LOG_AUTHPRIV problem that Solaris users were having. * decode.c: Added the new packet statistics counters throughout the code. Cleaned up the IPX code a bit. * rules.c: Cleaned up the isspace(3) (et al) calls. * etc: Made lots of tweaks to the autoconf stuff to get the S/Linux and HP-UX versions to compile cleanly out of the box. 1999-04-28 mfr * rules.c: Added the code to change the order the rules are applied in. * snort.c: Added two new command line switches: "-o" and "-s". * decode.c: Added in new layer 2 decoding for SLIP and RAW packet types. * log.c: Added code to send alert notification to syslog. 1999-04-17 mfr * rules.c: Rewrote the rules option parser. It's now a much more consistant interface for both reading rules into the program and writing them as a user. Added in new rule types to alert on TTL values, and ICMP types/codes. * log.c: Most of the logging code has been dramatically rewritten as well, and it now works much better. * mstring.c: Added the notion of a meta character to mSplit() so that it was possible to not split on every single occurence of a character in a string. * decode.c: Smoothed out all the logging system calls to work nicely with the new log code. 1999-04-08 mfr * rules.c: Moved AlertPkt() and LogPkt() to log.c * log.c: Totally revamped the logging code to be more logical and have less duplication in the code. There are now separate logging functions for each of the layers of the packet. PrintIPPkt() has been totally rewritten, PrintFragHeader has been eliminated, and two functions have been moved over from rules.c and completely rewritten as well. * decode.c: Reworked the routines which called the logging functions. 1999-04-06 mfr * decode.c: added code to display/log the Fragment ID field of the IP header. Got a nice patch from Sebastian to add in TOS decoding as well. Added ethernet header logging and display code. * mstring.c: fixed the match() routine. It had a tendency to miss some things some of the time. (oops!) Content based matching should work all the time now. * log.c: added code to display some of the new stuff that's decoded. * snort.c: add a new command line switch: "-e". This will display the ethernet header data in both the log files and on the screen. 1999-03-24 mfr * decode.c: fixed the damned TCP and IP options decoders. These things were a friggin pain in the ass to program up properly. Recoding them stopped the huge loop that they had a bad tendancy to get stuck in, thereby making the rest of the program nigh infinitely more useful for just about any friggin problem under the friggin sun. Frig it. * log.c: Stopped the insanity of unnessary carriage returns in the log files and on screen printouts. Another PITA. * rules.c: Fixed output formatting yet again. 1999-03-21 mfr * snort.c: fixed a bug in the timestamp code so the month prints out right * decode.c: added code to detect and decode IP and TCP Options. Also added code to print packet fragments with truncated headers into a PACKET_FRAG file which gets dumped in the default log directory. * log.c: added code and data structures to print out IP and TCP Options plus I fixed the f'd up fragment print out logic. Changed OpenLogFile() to include a mode argument for packet fragment print out. * rules.c: rewired the entire rules test routine and added some long needed goto's into the program. I feel manly now. Also added a new rule field: TCP flags. This allows us to alert/log/pass on tcp flags. Also added in port range functionality, you can now specify a range of ports, or greater than/less than a specified port. 1999-03-08 mfr * snort.c: Ripped off the timestamp printout routines from tcpdump and stuffed them into snort.c, yum yum. This gives us millisecond timestamping on the packets for those of you interested in such things. 1999-03-06 mfr * mstring.c: mContainsSubstring has been replaced. mContainsSubstring is a brute force pattern matcher, and is therefore very slow and not too efficient. The new routine, match(), implements a Boyer-Moore string search algorithm and is much faster in the general case and much more tolerent of "poor" pattern selection. * log.c: PrintNetData has been completely rewritten. It should now be much faster and only needs to generate the print out buffer once per packet. This routine was a major source of slow down/dropped packets before. You still shouldn't use verbose mode with the "-d" command line switch if you're using Snort as an IDS, because it's still slow enough to drop some large packets. Packet print out has changed as well, with the different packet layers separated by onto their own lines (well, mostly). Fragmented packets are now recorded in a "FRAG" file. * decode.c: Snort now detects fragmented packets, plus the DF and MF bits, and decodes the fragment offset. * snort.c: Now displays packet collected/dropped statistics when shutting down. 1999-02-18 mfr * snort.c: Code cleanup and some error checking was added. The system now accepts the interface name you give it at the command line. Fixed a problem with underallocating the interface name buffer for names specified on the command line. Suprisingly, this only came to light when tested on the Sparc architecture. * log.c: ICMP logging now includes the ICMP code description in the filename. This makes it easier to see what you're interested in without having to go digging into the log files. * decode.c: Made the ICMP types and codes a little more compatible with being used as a filename. 1999-01-28 mfr * rules.c: Rules sorting is now implemented. There are actually three separate lists (Pass, Log, Alert) now, with the rules being placed on to the lists in the order they're read from the rules file. The rule execution order was changed, now Alert rules are applied first, then Pass Rules, the Log rules. Content based rules are available now, the actual application layer data can be searched, both binary and text, for a specific pattern to activate a rule on. * decode.c: Minor changes to reflect the new rules structure. 1999-01-19 mfr * snort.c: Modularized the code, big time! New source modules are log, rules, decode, and mstring. Dumped SetFlow() for now. * rules.c: Rules based packet logging now enabled! * log.c: Now keeps track of TCP/UDP conversations better! * decode.c: Enhanced decoding of packets, including ICMP ECHO seq and id! 1999-01-08 mfr * snort.c: Made a fix to SetFlow() so that it wouldn't dump the program if it got traffic from 0.0.0.0 or 255.255.255.255. * snort.h: Removed the "#define VERSION" since it's handled in config.h. * README: Proper README file included with this distro 1998-12-21 mfr * snort.c: Made this file, figured out autoconf snort-2.9.15.1/config.guess0000755000000000000000000013036113571425502012333 00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2013 Free Software Foundation, Inc. timestamp='2013-06-10' # This file 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 3 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, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD # # Please send patches with a ChangeLog entry to config-patches@gnu.org. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case "${UNAME_SYSTEM}" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu eval $set_cc_for_build cat <<-EOF > $dummy.c #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #else LIBC=gnu #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` ;; esac # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW64*:*) echo ${UNAME_MACHINE}-pc-mingw64 exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="gnulibc1" ; fi echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arc:Linux:*:* | arceb:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-${LIBC} else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi else echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; cris:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; hexagon:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:Linux:*:*) echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; or1k:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; or32:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; padre:Linux:*:*) echo sparc-unknown-linux-${LIBC} exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; *) echo hppa-unknown-linux-${LIBC} ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-${LIBC} exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-${LIBC} exit ;; ppc64le:Linux:*:*) echo powerpc64le-unknown-linux-${LIBC} exit ;; ppcle:Linux:*:*) echo powerpcle-unknown-linux-${LIBC} exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; x86_64:Haiku:*:*) echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown eval $set_cc_for_build if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi fi echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; esac eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: snort-2.9.15.1/config.sub0000755000000000000000000010531513571425502011777 00000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2013 Free Software Foundation, Inc. timestamp='2013-04-24' # This file 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 3 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, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches with a ChangeLog entry to config-patches@gnu.org. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze*) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 ;; -lynx*5) os=-lynxos5 ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ | be32 | be64 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | epiphany \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 \ | or1k | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze*) basic_machine=microblaze-xilinx ;; mingw64) basic_machine=x86_64-pc os=-mingw64 ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i386-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-* | ppc64p7-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos | rdos64) basic_machine=x86_64-pc os=-rdos ;; rdos32) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; hexagon-*) os=-elf ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or1k-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: snort-2.9.15.1/install-sh0000755000000000000000000003325513571425502012023 00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2011-11-20.07; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. nl=' ' IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} if test -z "$doit"; then doit_exec=exec else doit_exec=$doit fi # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_glob='?' initialize_posix_glob=' test "$posix_glob" != "?" || { if (set -f) 2>/dev/null; then posix_glob= else posix_glob=: fi } ' posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false no_target_directory= usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *' '* | *' '* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else # Prefer dirname, but fall back on a substitute if dirname fails. dstdir=` (dirname "$dst") 2>/dev/null || expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$dst" : 'X\(//\)[^/]' \| \ X"$dst" : 'X\(//\)$' \| \ X"$dst" : 'X\(/\)' \| . 2>/dev/null || echo X"$dst" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q' ` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac eval "$initialize_posix_glob" oIFS=$IFS IFS=/ $posix_glob set -f set fnord $dstdir shift $posix_glob set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && eval "$initialize_posix_glob" && $posix_glob set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && $posix_glob set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: snort-2.9.15.1/missing0000755000000000000000000001533113571425502011411 00000000000000#! /bin/sh # Common wrapper for a few potentially missing GNU programs. scriptversion=2012-06-26.16; # UTC # Copyright (C) 1996-2013 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try '$0 --help' for more information" exit 1 fi case $1 in --is-lightweight) # Used by our autoconf macros to check whether the available missing # script is modern enough. exit 0 ;; --run) # Back-compat with the calling convention used by older automake. shift ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal autoconf autoheader autom4te automake makeinfo bison yacc flex lex help2man Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 'g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: unknown '$1' option" echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac # Run the given program, remember its exit status. "$@"; st=$? # If it succeeded, we are done. test $st -eq 0 && exit 0 # Also exit now if we it failed (or wasn't found), and '--version' was # passed; such an option is passed most likely to detect whether the # program is present and works. case $2 in --version|--help) exit $st;; esac # Exit code 63 means version mismatch. This often happens when the user # tries to use an ancient version of a tool on a file that requires a # minimum version. if test $st -eq 63; then msg="probably too old" elif test $st -eq 127; then # Program was missing. msg="missing on your system" else # Program was found and executed, but failed. Give up. exit $st fi perl_URL=http://www.perl.org/ flex_URL=http://flex.sourceforge.net/ gnu_software_URL=http://www.gnu.org/software program_details () { case $1 in aclocal|automake) echo "The '$1' program is part of the GNU Automake package:" echo "<$gnu_software_URL/automake>" echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/autoconf>" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; autoconf|autom4te|autoheader) echo "The '$1' program is part of the GNU Autoconf package:" echo "<$gnu_software_URL/autoconf/>" echo "It also requires GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; esac } give_advice () { # Normalize program name to check for. normalized_program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` printf '%s\n' "'$1' is $msg." configure_deps="'configure.ac' or m4 files included by 'configure.ac'" case $normalized_program in autoconf*) echo "You should only need it if you modified 'configure.ac'," echo "or m4 files included by it." program_details 'autoconf' ;; autoheader*) echo "You should only need it if you modified 'acconfig.h' or" echo "$configure_deps." program_details 'autoheader' ;; automake*) echo "You should only need it if you modified 'Makefile.am' or" echo "$configure_deps." program_details 'automake' ;; aclocal*) echo "You should only need it if you modified 'acinclude.m4' or" echo "$configure_deps." program_details 'aclocal' ;; autom4te*) echo "You might have modified some maintainer files that require" echo "the 'automa4te' program to be rebuilt." program_details 'autom4te' ;; bison*|yacc*) echo "You should only need it if you modified a '.y' file." echo "You may want to install the GNU Bison package:" echo "<$gnu_software_URL/bison/>" ;; lex*|flex*) echo "You should only need it if you modified a '.l' file." echo "You may want to install the Fast Lexical Analyzer package:" echo "<$flex_URL>" ;; help2man*) echo "You should only need it if you modified a dependency" \ "of a man page." echo "You may want to install the GNU Help2man package:" echo "<$gnu_software_URL/help2man/>" ;; makeinfo*) echo "You should only need it if you modified a '.texi' file, or" echo "any other file indirectly affecting the aspect of the manual." echo "You might want to install the Texinfo package:" echo "<$gnu_software_URL/texinfo/>" echo "The spurious makeinfo call might also be the consequence of" echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" echo "want to install GNU make:" echo "<$gnu_software_URL/make/>" ;; *) echo "You might have modified some files without having the proper" echo "tools for further handling them. Check the 'README' file, it" echo "often tells you about the needed prerequisites for installing" echo "this package. You may also peek at any GNU archive site, in" echo "case some other package contains this missing '$1' program." ;; esac } give_advice "$1" | sed -e '1s/^/WARNING: /' \ -e '2,$s/^/ /' >&2 # Propagate the correct exit status (expected to be 127 for a program # not found, 63 for a program that failed due to version mismatch). exit $st # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: snort-2.9.15.1/ltmain.sh0000644000000000000000000105152213571425476011647 00000000000000 # libtool (GNU libtool) 2.4.2 # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, # 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool 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. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, # or obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Usage: $progname [OPTION]... [MODE-ARG]... # # Provide generalized library-building support services. # # --config show all configuration variables # --debug enable verbose shell tracing # -n, --dry-run display commands without modifying any files # --features display basic configuration information and exit # --mode=MODE use operation mode MODE # --preserve-dup-deps don't remove duplicate dependency libraries # --quiet, --silent don't print informational messages # --no-quiet, --no-silent # print informational messages (default) # --no-warn don't display warning messages # --tag=TAG use configuration variables from tag TAG # -v, --verbose print more informational messages than default # --no-verbose don't print the extra informational messages # --version print version information # -h, --help, --help-all print short, long, or detailed help message # # MODE must be one of the following: # # clean remove files from the build directory # compile compile a source file into a libtool object # execute automatically set library path, then run a program # finish complete the installation of libtool libraries # install install libraries or executables # link create a library or an executable # uninstall remove libraries from an installed directory # # MODE-ARGS vary depending on the MODE. When passed as first option, # `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. # Try `$progname --help --mode=MODE' for a more detailed description of MODE. # # When reporting a bug, please describe a test case to reproduce it and # include the following information: # # host-triplet: $host # shell: $SHELL # compiler: $LTCC # compiler flags: $LTCFLAGS # linker: $LD (gnu? $with_gnu_ld) # $progname: (GNU libtool) 2.4.2 # automake: $automake_version # autoconf: $autoconf_version # # Report bugs to . # GNU libtool home page: . # General help using GNU software: . PROGRAM=libtool PACKAGE=libtool VERSION=2.4.2 TIMESTAMP="" package_revision=1.3337 # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } # NLS nuisances: We save the old values to restore during execute mode. lt_user_locale= lt_safe_locale= for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${$lt_var+set}\" = set; then save_$lt_var=\$$lt_var $lt_var=C export $lt_var lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" fi" done LC_ALL=C LANGUAGE=C export LANGUAGE LC_ALL $lt_unset CDPATH # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath="$0" : ${CP="cp -f"} test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} : ${Xsed="$SED -e 1s/^X//"} # Global variables: EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. exit_status=$EXIT_SUCCESS # Make sure IFS has a sensible default lt_nl=' ' IFS=" $lt_nl" dirname="s,/[^/]*$,," basename="s,^.*/,," # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi } # func_dirname may be replaced by extended shell implementation # func_basename file func_basename () { func_basename_result=`$ECHO "${1}" | $SED "$basename"` } # func_basename may be replaced by extended shell implementation # func_dirname_and_basename file append nondir_replacement # perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. func_dirname_and_basename () { # Extract subdirectory from the argument. func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` } # func_dirname_and_basename may be replaced by extended shell implementation # func_stripname prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # func_strip_suffix prefix name func_stripname () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname may be replaced by extended shell implementation # These SED scripts presuppose an absolute path with a trailing slash. pathcar='s,^/\([^/]*\).*$,\1,' pathcdr='s,^/[^/]*,,' removedotparts=':dotsl s@/\./@/@g t dotsl s,/\.$,/,' collapseslashes='s@/\{1,\}@/@g' finalslash='s,/*$,/,' # func_normal_abspath PATH # Remove doubled-up and trailing slashes, "." path components, # and cancel out any ".." path components in PATH after making # it an absolute path. # value returned in "$func_normal_abspath_result" func_normal_abspath () { # Start from root dir and reassemble the path. func_normal_abspath_result= func_normal_abspath_tpath=$1 func_normal_abspath_altnamespace= case $func_normal_abspath_tpath in "") # Empty path, that just means $cwd. func_stripname '' '/' "`pwd`" func_normal_abspath_result=$func_stripname_result return ;; # The next three entries are used to spot a run of precisely # two leading slashes without using negated character classes; # we take advantage of case's first-match behaviour. ///*) # Unusual form of absolute path, do nothing. ;; //*) # Not necessarily an ordinary path; POSIX reserves leading '//' # and for example Cygwin uses it to access remote file shares # over CIFS/SMB, so we conserve a leading double slash if found. func_normal_abspath_altnamespace=/ ;; /*) # Absolute path, do nothing. ;; *) # Relative path, prepend $cwd. func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath ;; esac # Cancel out all the simple stuff to save iterations. We also want # the path to end with a slash for ease of parsing, so make sure # there is one (and only one) here. func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` while :; do # Processed it all yet? if test "$func_normal_abspath_tpath" = / ; then # If we ascended to the root using ".." the result may be empty now. if test -z "$func_normal_abspath_result" ; then func_normal_abspath_result=/ fi break fi func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$pathcar"` func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$pathcdr"` # Figure out what to do with it case $func_normal_abspath_tcomponent in "") # Trailing empty path component, ignore it. ;; ..) # Parent dir; strip last assembled component from result. func_dirname "$func_normal_abspath_result" func_normal_abspath_result=$func_dirname_result ;; *) # Actual path component, append it. func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent ;; esac done # Restore leading double-slash if one was found on entry. func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result } # func_relative_path SRCDIR DSTDIR # generates a relative path from SRCDIR to DSTDIR, with a trailing # slash if non-empty, suitable for immediately appending a filename # without needing to append a separator. # value returned in "$func_relative_path_result" func_relative_path () { func_relative_path_result= func_normal_abspath "$1" func_relative_path_tlibdir=$func_normal_abspath_result func_normal_abspath "$2" func_relative_path_tbindir=$func_normal_abspath_result # Ascend the tree starting from libdir while :; do # check if we have found a prefix of bindir case $func_relative_path_tbindir in $func_relative_path_tlibdir) # found an exact match func_relative_path_tcancelled= break ;; $func_relative_path_tlibdir*) # found a matching prefix func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" func_relative_path_tcancelled=$func_stripname_result if test -z "$func_relative_path_result"; then func_relative_path_result=. fi break ;; *) func_dirname $func_relative_path_tlibdir func_relative_path_tlibdir=${func_dirname_result} if test "x$func_relative_path_tlibdir" = x ; then # Have to descend all the way to the root! func_relative_path_result=../$func_relative_path_result func_relative_path_tcancelled=$func_relative_path_tbindir break fi func_relative_path_result=../$func_relative_path_result ;; esac done # Now calculate path; take care to avoid doubling-up slashes. func_stripname '' '/' "$func_relative_path_result" func_relative_path_result=$func_stripname_result func_stripname '/' '/' "$func_relative_path_tcancelled" if test "x$func_stripname_result" != x ; then func_relative_path_result=${func_relative_path_result}/${func_stripname_result} fi # Normalisation. If bindir is libdir, return empty string, # else relative path ending with a slash; either way, target # file name can be directly appended. if test ! -z "$func_relative_path_result"; then func_stripname './' '' "$func_relative_path_result/" func_relative_path_result=$func_stripname_result fi } # The name of this program: func_dirname_and_basename "$progpath" progname=$func_basename_result # Make sure we have an absolute path for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=$func_dirname_result progdir=`cd "$progdir" && pwd` progpath="$progdir/$progname" ;; *) save_IFS="$IFS" IFS=${PATH_SEPARATOR-:} for progdir in $PATH; do IFS="$save_IFS" test -x "$progdir/$progname" && break done IFS="$save_IFS" test -n "$progdir" || progdir=`pwd` progpath="$progdir/$progname" ;; esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed="${SED}"' -e 1s/^X//' sed_quote_subst='s/\([`"$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution that turns a string into a regex matching for the # string literally. sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' # Sed substitution that converts a w32 file name or path # which contains forward slashes, into one that contains # (escaped) backslashes. A very naive implementation. lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Re-`\' parameter expansions in output of double_quote_subst that were # `\'-ed in input to the same. If an odd number of `\' preceded a '$' # in input to double_quote_subst, that '$' was protected from expansion. # Since each input `\' is now two `\'s, look for any number of runs of # four `\'s followed by two `\'s and then a '$'. `\' that '$'. bs='\\' bs2='\\\\' bs4='\\\\\\\\' dollar='\$' sed_double_backslash="\ s/$bs4/&\\ /g s/^$bs2$dollar/$bs&/ s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g s/\n//g" # Standard options: opt_dry_run=false opt_help=false opt_quiet=false opt_verbose=false opt_warning=: # func_echo arg... # Echo program name prefixed message, along with the current mode # name if it has been set yet. func_echo () { $ECHO "$progname: ${opt_mode+$opt_mode: }$*" } # func_verbose arg... # Echo program name prefixed message in verbose mode only. func_verbose () { $opt_verbose && func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } # func_error arg... # Echo program name prefixed message to standard error. func_error () { $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 } # func_warning arg... # Echo program name prefixed warning message to standard error. func_warning () { $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 # bash bug again: : } # func_fatal_error arg... # Echo program name prefixed message to standard error, and exit. func_fatal_error () { func_error ${1+"$@"} exit $EXIT_FAILURE } # func_fatal_help arg... # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { func_error ${1+"$@"} func_fatal_error "$help" } help="Try \`$progname --help' for more information." ## default # func_grep expression filename # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $GREP "$1" "$2" >/dev/null 2>&1 } # func_mkdir_p directory-path # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { my_directory_path="$1" my_dir_list= if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then # Protect directory names starting with `-' case $my_directory_path in -*) my_directory_path="./$my_directory_path" ;; esac # While some portion of DIR does not yet exist... while test ! -d "$my_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. my_dir_list="$my_directory_path:$my_dir_list" # If the last portion added has no slash in it, the list is done case $my_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` done my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` save_mkdir_p_IFS="$IFS"; IFS=':' for my_dir in $my_dir_list; do IFS="$save_mkdir_p_IFS" # mkdir can fail with a `File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$my_dir" 2>/dev/null || : done IFS="$save_mkdir_p_IFS" # Bail out if we (or some other process) failed to create a directory. test -d "$my_directory_path" || \ func_fatal_error "Failed to create \`$1'" fi } # func_mktempdir [string] # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, STRING is the basename for that directory. func_mktempdir () { my_template="${TMPDIR-/tmp}/${1-$progname}" if test "$opt_dry_run" = ":"; then # Return a directory name, but don't create it in dry-run mode my_tmpdir="${my_template}-$$" else # If mktemp works, use that first and foremost my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` if test ! -d "$my_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race my_tmpdir="${my_template}-${RANDOM-0}$$" save_mktempdir_umask=`umask` umask 0077 $MKDIR "$my_tmpdir" umask $save_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$my_tmpdir" || \ func_fatal_error "cannot create temporary directory \`$my_tmpdir'" fi $ECHO "$my_tmpdir" } # func_quote_for_eval arg # Aesthetically quote ARG to be evaled later. # This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT # is double-quoted, suitable for a subsequent eval, whereas # FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters # which are still active within double quotes backslashified. func_quote_for_eval () { case $1 in *[\\\`\"\$]*) func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; *) func_quote_for_eval_unquoted_result="$1" ;; esac case $func_quote_for_eval_unquoted_result in # Double-quote args containing shell metacharacters to delay # word splitting, command substitution and and variable # expansion for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" ;; *) func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" esac } # func_quote_for_expand arg # Aesthetically quote ARG to be evaled later; same as above, # but do not quote variable references. func_quote_for_expand () { case $1 in *[\\\`\"]*) my_arg=`$ECHO "$1" | $SED \ -e "$double_quote_subst" -e "$sed_double_backslash"` ;; *) my_arg="$1" ;; esac case $my_arg in # Double-quote args containing shell metacharacters to delay # word splitting and command substitution for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") my_arg="\"$my_arg\"" ;; esac func_quote_for_expand_result="$my_arg" } # func_show_eval cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$my_cmd" my_status=$? if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_show_eval_locale cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$lt_user_locale $my_cmd" my_status=$? eval "$lt_safe_locale" if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_tr_sh # Turn $1 into a string suitable for a shell variable name. # Result is stored in $func_tr_sh_result. All characters # not in the set a-zA-Z0-9_ are replaced with '_'. Further, # if $1 begins with a digit, a '_' is prepended as well. func_tr_sh () { case $1 in [0-9]* | *[!a-zA-Z0-9_]*) func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` ;; * ) func_tr_sh_result=$1 ;; esac } # func_version # Echo version message to standard output and exit. func_version () { $opt_debug $SED -n '/(C)/!b go :more /\./!{ N s/\n# / / b more } :go /^# '$PROGRAM' (GNU /,/# warranty; / { s/^# // s/^# *$// s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ p }' < "$progpath" exit $? } # func_usage # Echo short help message to standard output and exit. func_usage () { $opt_debug $SED -n '/^# Usage:/,/^# *.*--help/ { s/^# // s/^# *$// s/\$progname/'$progname'/ p }' < "$progpath" echo $ECHO "run \`$progname --help | more' for full usage" exit $? } # func_help [NOEXIT] # Echo long help message to standard output and exit, # unless 'noexit' is passed as argument. func_help () { $opt_debug $SED -n '/^# Usage:/,/# Report bugs to/ { :print s/^# // s/^# *$// s*\$progname*'$progname'* s*\$host*'"$host"'* s*\$SHELL*'"$SHELL"'* s*\$LTCC*'"$LTCC"'* s*\$LTCFLAGS*'"$LTCFLAGS"'* s*\$LD*'"$LD"'* s/\$with_gnu_ld/'"$with_gnu_ld"'/ s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/ s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/ p d } /^# .* home page:/b print /^# General help using/b print ' < "$progpath" ret=$? if test -z "$1"; then exit $ret fi } # func_missing_arg argname # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { $opt_debug func_error "missing argument for $1." exit_cmd=exit } # func_split_short_opt shortopt # Set func_split_short_opt_name and func_split_short_opt_arg shell # variables after splitting SHORTOPT after the 2nd character. func_split_short_opt () { my_sed_short_opt='1s/^\(..\).*$/\1/;q' my_sed_short_rest='1s/^..\(.*\)$/\1/;q' func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` } # func_split_short_opt may be replaced by extended shell implementation # func_split_long_opt longopt # Set func_split_long_opt_name and func_split_long_opt_arg shell # variables after splitting LONGOPT at the `=' sign. func_split_long_opt () { my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' my_sed_long_arg='1s/^--[^=]*=//' func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` } # func_split_long_opt may be replaced by extended shell implementation exit_cmd=: magic="%%%MAGIC variable%%%" magic_exe="%%%MAGIC EXE variable%%%" # Global variables. nonopt= preserve_args= lo2o="s/\\.lo\$/.${objext}/" o2lo="s/\\.${objext}\$/.lo/" extracted_archives= extracted_serial=0 # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "${1}=\$${1}\${2}" } # func_append may be replaced by extended shell implementation # func_append_quoted var value # Quote VALUE and append to the end of shell variable VAR, separated # by a space. func_append_quoted () { func_quote_for_eval "${2}" eval "${1}=\$${1}\\ \$func_quote_for_eval_result" } # func_append_quoted may be replaced by extended shell implementation # func_arith arithmetic-term... func_arith () { func_arith_result=`expr "${@}"` } # func_arith may be replaced by extended shell implementation # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` } # func_len may be replaced by extended shell implementation # func_lo2o object func_lo2o () { func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` } # func_lo2o may be replaced by extended shell implementation # func_xform libobj-or-source func_xform () { func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` } # func_xform may be replaced by extended shell implementation # func_fatal_configuration arg... # Echo program name prefixed message to standard error, followed by # a configuration failure hint, and exit. func_fatal_configuration () { func_error ${1+"$@"} func_error "See the $PACKAGE documentation for more information." func_fatal_error "Fatal configuration error." } # func_config # Display the configuration for all the tags in this script. func_config () { re_begincf='^# ### BEGIN LIBTOOL' re_endcf='^# ### END LIBTOOL' # Default configuration. $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" # Now print the configurations for the tags. for tagname in $taglist; do $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" done exit $? } # func_features # Display the features supported by this script. func_features () { echo "host: $host" if test "$build_libtool_libs" = yes; then echo "enable shared libraries" else echo "disable shared libraries" fi if test "$build_old_libs" = yes; then echo "enable static libraries" else echo "disable static libraries" fi exit $? } # func_enable_tag tagname # Verify that TAGNAME is valid, and either flag an error and exit, or # enable the TAGNAME tag. We also add TAGNAME to the global $taglist # variable here. func_enable_tag () { # Global variable: tagname="$1" re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" sed_extractcf="/$re_begincf/,/$re_endcf/p" # Validate tagname. case $tagname in *[!-_A-Za-z0-9,/]*) func_fatal_error "invalid tag name: $tagname" ;; esac # Don't test for the "default" C tag, as we know it's # there but not specially marked. case $tagname in CC) ;; *) if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # func_check_version_match # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; esac # Option defaults: opt_debug=: opt_dry_run=false opt_config=false opt_preserve_dup_deps=false opt_features=false opt_finish=false opt_help=false opt_help_all=false opt_silent=: opt_warning=: opt_verbose=: opt_silent=false opt_verbose=false # Parse options once, thoroughly. This comes as soon as possible in the # script to make things like `--version' happen as quickly as we can. { # this just eases exit handling while test $# -gt 0; do opt="$1" shift case $opt in --debug|-x) opt_debug='set -x' func_echo "enabling shell trace mode" $opt_debug ;; --dry-run|--dryrun|-n) opt_dry_run=: ;; --config) opt_config=: func_config ;; --dlopen|-dlopen) optarg="$1" opt_dlopen="${opt_dlopen+$opt_dlopen }$optarg" shift ;; --preserve-dup-deps) opt_preserve_dup_deps=: ;; --features) opt_features=: func_features ;; --finish) opt_finish=: set dummy --mode finish ${1+"$@"}; shift ;; --help) opt_help=: ;; --help-all) opt_help_all=: opt_help=': help-all' ;; --mode) test $# = 0 && func_missing_arg $opt && break optarg="$1" opt_mode="$optarg" case $optarg in # Valid mode arguments: clean|compile|execute|finish|install|link|relink|uninstall) ;; # Catch anything else as an error *) func_error "invalid argument for $opt" exit_cmd=exit break ;; esac shift ;; --no-silent|--no-quiet) opt_silent=false func_append preserve_args " $opt" ;; --no-warning|--no-warn) opt_warning=false func_append preserve_args " $opt" ;; --no-verbose) opt_verbose=false func_append preserve_args " $opt" ;; --silent|--quiet) opt_silent=: func_append preserve_args " $opt" opt_verbose=false ;; --verbose|-v) opt_verbose=: func_append preserve_args " $opt" opt_silent=false ;; --tag) test $# = 0 && func_missing_arg $opt && break optarg="$1" opt_tag="$optarg" func_append preserve_args " $opt $optarg" func_enable_tag "$optarg" shift ;; -\?|-h) func_usage ;; --help) func_help ;; --version) func_version ;; # Separate optargs to long options: --*=*) func_split_long_opt "$opt" set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} shift ;; # Separate non-argument short options: -\?*|-h*|-n*|-v*) func_split_short_opt "$opt" set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} shift ;; --) break ;; -*) func_fatal_help "unrecognized option \`$opt'" ;; *) set dummy "$opt" ${1+"$@"}; shift; break ;; esac done # Validate options: # save first non-option argument if test "$#" -gt 0; then nonopt="$opt" shift fi # preserve --debug test "$opt_debug" = : || func_append preserve_args " --debug" case $host in *cygwin* | *mingw* | *pw32* | *cegcc*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps ;; esac $opt_help || { # Sanity checks first: func_check_version_match if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then func_fatal_configuration "not configured to build any kind of library" fi # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$opt_dlopen" && test "$opt_mode" != execute; then func_error "unrecognized option \`-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help="$help" help="Try \`$progname --help --mode=$opt_mode' for more information." } # Bail if the options were screwed $exit_cmd $EXIT_FAILURE } ## ----------- ## ## Main. ## ## ----------- ## # func_lalib_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null \ | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_unsafe_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if `file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case "$lalib_p_line" in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test "$lalib_p" = yes } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { func_lalib_p "$1" } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $opt_debug save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$save_ifs eval cmd=\"$cmd\" func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # `FILE.' does not work on cygwin managed mounts. func_source () { $opt_debug case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_resolve_sysroot PATH # Replace a leading = in PATH with a sysroot. Store the result into # func_resolve_sysroot_result func_resolve_sysroot () { func_resolve_sysroot_result=$1 case $func_resolve_sysroot_result in =*) func_stripname '=' '' "$func_resolve_sysroot_result" func_resolve_sysroot_result=$lt_sysroot$func_stripname_result ;; esac } # func_replace_sysroot PATH # If PATH begins with the sysroot, replace it with = and # store the result into func_replace_sysroot_result. func_replace_sysroot () { case "$lt_sysroot:$1" in ?*:"$lt_sysroot"*) func_stripname "$lt_sysroot" '' "$1" func_replace_sysroot_result="=$func_stripname_result" ;; *) # Including no sysroot. func_replace_sysroot_result=$1 ;; esac } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { $opt_debug if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case "$@ " in " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with \`--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=${1} if test "$build_libtool_libs" = yes; then write_lobj=\'${2}\' else write_lobj=none fi if test "$build_old_libs" = yes; then write_oldobj=\'${3}\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T </dev/null` if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | $SED -e "$lt_sed_naive_backslashify"` else func_convert_core_file_wine_to_w32_result= fi fi } # end: func_convert_core_file_wine_to_w32 # func_convert_core_path_wine_to_w32 ARG # Helper function used by path conversion functions when $build is *nix, and # $host is mingw, cygwin, or some other w32 environment. Relies on a correctly # configured wine environment available, with the winepath program in $build's # $PATH. Assumes ARG has no leading or trailing path separator characters. # # ARG is path to be converted from $build format to win32. # Result is available in $func_convert_core_path_wine_to_w32_result. # Unconvertible file (directory) names in ARG are skipped; if no directory names # are convertible, then the result may be empty. func_convert_core_path_wine_to_w32 () { $opt_debug # unfortunately, winepath doesn't convert paths, only file names func_convert_core_path_wine_to_w32_result="" if test -n "$1"; then oldIFS=$IFS IFS=: for func_convert_core_path_wine_to_w32_f in $1; do IFS=$oldIFS func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" if test -n "$func_convert_core_file_wine_to_w32_result" ; then if test -z "$func_convert_core_path_wine_to_w32_result"; then func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" else func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" fi fi done IFS=$oldIFS fi } # end: func_convert_core_path_wine_to_w32 # func_cygpath ARGS... # Wrapper around calling the cygpath program via LT_CYGPATH. This is used when # when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) # $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or # (2), returns the Cygwin file name or path in func_cygpath_result (input # file name or path is assumed to be in w32 format, as previously converted # from $build's *nix or MSYS format). In case (3), returns the w32 file name # or path in func_cygpath_result (input file name or path is assumed to be in # Cygwin format). Returns an empty string on error. # # ARGS are passed to cygpath, with the last one being the file name or path to # be converted. # # Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH # environment variable; do not put it in $PATH. func_cygpath () { $opt_debug if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` if test "$?" -ne 0; then # on failure, ensure result is empty func_cygpath_result= fi else func_cygpath_result= func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" fi } #end: func_cygpath # func_convert_core_msys_to_w32 ARG # Convert file name or path ARG from MSYS format to w32 format. Return # result in func_convert_core_msys_to_w32_result. func_convert_core_msys_to_w32 () { $opt_debug # awkward: cmd appends spaces to result func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` } #end: func_convert_core_msys_to_w32 # func_convert_file_check ARG1 ARG2 # Verify that ARG1 (a file name in $build format) was converted to $host # format in ARG2. Otherwise, emit an error message, but continue (resetting # func_to_host_file_result to ARG1). func_convert_file_check () { $opt_debug if test -z "$2" && test -n "$1" ; then func_error "Could not determine host file name corresponding to" func_error " \`$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_file_result="$1" fi } # end func_convert_file_check # func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH # Verify that FROM_PATH (a path in $build format) was converted to $host # format in TO_PATH. Otherwise, emit an error message, but continue, resetting # func_to_host_file_result to a simplistic fallback value (see below). func_convert_path_check () { $opt_debug if test -z "$4" && test -n "$3"; then func_error "Could not determine the host path corresponding to" func_error " \`$3'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This is a deliberately simplistic "conversion" and # should not be "improved". See libtool.info. if test "x$1" != "x$2"; then lt_replace_pathsep_chars="s|$1|$2|g" func_to_host_path_result=`echo "$3" | $SED -e "$lt_replace_pathsep_chars"` else func_to_host_path_result="$3" fi fi } # end func_convert_path_check # func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG # Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT # and appending REPL if ORIG matches BACKPAT. func_convert_path_front_back_pathsep () { $opt_debug case $4 in $1 ) func_to_host_path_result="$3$func_to_host_path_result" ;; esac case $4 in $2 ) func_append func_to_host_path_result "$3" ;; esac } # end func_convert_path_front_back_pathsep ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## # invoked via `$to_host_file_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # Result will be available in $func_to_host_file_result. # func_to_host_file ARG # Converts the file name ARG from $build format to $host format. Return result # in func_to_host_file_result. func_to_host_file () { $opt_debug $to_host_file_cmd "$1" } # end func_to_host_file # func_to_tool_file ARG LAZY # converts the file name ARG from $build format to toolchain format. Return # result in func_to_tool_file_result. If the conversion in use is listed # in (the comma separated) LAZY, no conversion takes place. func_to_tool_file () { $opt_debug case ,$2, in *,"$to_tool_file_cmd",*) func_to_tool_file_result=$1 ;; *) $to_tool_file_cmd "$1" func_to_tool_file_result=$func_to_host_file_result ;; esac } # end func_to_tool_file # func_convert_file_noop ARG # Copy ARG to func_to_host_file_result. func_convert_file_noop () { func_to_host_file_result="$1" } # end func_convert_file_noop # func_convert_file_msys_to_w32 ARG # Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_file_result. func_convert_file_msys_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_to_host_file_result="$func_convert_core_msys_to_w32_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_w32 # func_convert_file_cygwin_to_w32 ARG # Convert file name ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_file_cygwin_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then # because $build is cygwin, we call "the" cygpath in $PATH; no need to use # LT_CYGPATH in this case. func_to_host_file_result=`cygpath -m "$1"` fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_cygwin_to_w32 # func_convert_file_nix_to_w32 ARG # Convert file name ARG from *nix to w32 format. Requires a wine environment # and a working winepath. Returns result in func_to_host_file_result. func_convert_file_nix_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_file_wine_to_w32 "$1" func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_w32 # func_convert_file_msys_to_cygwin ARG # Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_file_msys_to_cygwin () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_cygpath -u "$func_convert_core_msys_to_w32_result" func_to_host_file_result="$func_cygpath_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_cygwin # func_convert_file_nix_to_cygwin ARG # Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed # in a wine environment, working winepath, and LT_CYGPATH set. Returns result # in func_to_host_file_result. func_convert_file_nix_to_cygwin () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. func_convert_core_file_wine_to_w32 "$1" func_cygpath -u "$func_convert_core_file_wine_to_w32_result" func_to_host_file_result="$func_cygpath_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_cygwin ############################################# # $build to $host PATH CONVERSION FUNCTIONS # ############################################# # invoked via `$to_host_path_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # The result will be available in $func_to_host_path_result. # # Path separators are also converted from $build format to $host format. If # ARG begins or ends with a path separator character, it is preserved (but # converted to $host format) on output. # # All path conversion functions are named using the following convention: # file name conversion function : func_convert_file_X_to_Y () # path conversion function : func_convert_path_X_to_Y () # where, for any given $build/$host combination the 'X_to_Y' value is the # same. If conversion functions are added for new $build/$host combinations, # the two new functions must follow this pattern, or func_init_to_host_path_cmd # will break. # func_init_to_host_path_cmd # Ensures that function "pointer" variable $to_host_path_cmd is set to the # appropriate value, based on the value of $to_host_file_cmd. to_host_path_cmd= func_init_to_host_path_cmd () { $opt_debug if test -z "$to_host_path_cmd"; then func_stripname 'func_convert_file_' '' "$to_host_file_cmd" to_host_path_cmd="func_convert_path_${func_stripname_result}" fi } # func_to_host_path ARG # Converts the path ARG from $build format to $host format. Return result # in func_to_host_path_result. func_to_host_path () { $opt_debug func_init_to_host_path_cmd $to_host_path_cmd "$1" } # end func_to_host_path # func_convert_path_noop ARG # Copy ARG to func_to_host_path_result. func_convert_path_noop () { func_to_host_path_result="$1" } # end func_convert_path_noop # func_convert_path_msys_to_w32 ARG # Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_path_result. func_convert_path_msys_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # Remove leading and trailing path separator characters from ARG. MSYS # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; # and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result="$func_convert_core_msys_to_w32_result" func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_msys_to_w32 # func_convert_path_cygwin_to_w32 ARG # Convert path ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_path_cygwin_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_cygwin_to_w32 # func_convert_path_nix_to_w32 ARG # Convert path ARG from *nix to w32 format. Requires a wine environment and # a working winepath. Returns result in func_to_host_file_result. func_convert_path_nix_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_nix_to_w32 # func_convert_path_msys_to_cygwin ARG # Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_path_msys_to_cygwin () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_msys_to_w32_result" func_to_host_path_result="$func_cygpath_result" func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_msys_to_cygwin # func_convert_path_nix_to_cygwin ARG # Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a # a wine environment, working winepath, and LT_CYGPATH set. Returns result in # func_to_host_file_result. func_convert_path_nix_to_cygwin () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" func_to_host_path_result="$func_cygpath_result" func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_nix_to_cygwin # func_mode_compile arg... func_mode_compile () { $opt_debug # Get the compilation command and the source file. base_compile= srcfile="$nonopt" # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal libobj= later= pie_flag= for arg do case $arg_mode in arg ) # do not "continue". Instead, add this to base_compile lastarg="$arg" arg_mode=normal ;; target ) libobj="$arg" arg_mode=normal continue ;; normal ) # Accept any command-line options. case $arg in -o) test -n "$libobj" && \ func_fatal_error "you cannot specify \`-o' more than once" arg_mode=target continue ;; -pie | -fpie | -fPIE) func_append pie_flag " $arg" continue ;; -shared | -static | -prefer-pic | -prefer-non-pic) func_append later " $arg" continue ;; -no-suppress) suppress_opt=no continue ;; -Xcompiler) arg_mode=arg # the next one goes into the "base_compile" arg list continue # The current "srcfile" will either be retained or ;; # replaced later. I would guess that would be a bug. -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result lastarg= save_ifs="$IFS"; IFS=',' for arg in $args; do IFS="$save_ifs" func_append_quoted lastarg "$arg" done IFS="$save_ifs" func_stripname ' ' '' "$lastarg" lastarg=$func_stripname_result # Add the arguments to base_compile. func_append base_compile " $lastarg" continue ;; *) # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # lastarg="$srcfile" srcfile="$arg" ;; esac # case $arg ;; esac # case $arg_mode # Aesthetically quote the previous argument. func_append_quoted base_compile "$lastarg" done # for arg case $arg_mode in arg) func_fatal_error "you must specify an argument for -Xcompile" ;; target) func_fatal_error "you must specify a target with \`-o'" ;; *) # Get the name of the library object. test -z "$libobj" && { func_basename "$srcfile" libobj="$func_basename_result" } ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo case $libobj in *.[cCFSifmso] | \ *.ada | *.adb | *.ads | *.asm | \ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) func_xform "$libobj" libobj=$func_xform_result ;; esac case $libobj in *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; *) func_fatal_error "cannot determine name of library object from \`$libobj'" ;; esac func_infer_tag $base_compile for arg in $later; do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no continue ;; -static) build_libtool_libs=no build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; esac done func_quote_for_eval "$libobj" test "X$libobj" != "X$func_quote_for_eval_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ && func_warning "libobj name \`$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname="$func_basename_result" xdir="$func_dirname_result" lobj=${xdir}$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. if test "$build_old_libs" = yes; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2* | cegcc*) pic_mode=default ;; esac if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test "$compiler_c_o" = no; then output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} lockfile="$output_obj.lock" else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test "$need_locks" = yes; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done elif test "$need_locks" = warn; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi func_append removelist " $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist func_append removelist " $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 srcfile=$func_to_tool_file_result func_quote_for_eval "$srcfile" qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. if test "$build_libtool_libs" = yes; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test "$pic_mode" != no; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir func_append command " -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test "$suppress_opt" = yes; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test "$build_old_libs" = yes; then if test "$pic_mode" != yes; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test "$compiler_c_o" = yes; then func_append command " -o $obj" fi # Suppress compiler output if we already did a PIC compilation. func_append command "$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test "$need_locks" != no; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test "$opt_mode" = compile && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $opt_mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $ECHO \ "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to build PIC objects only -prefer-non-pic try to build non-PIC objects only -shared do not build a \`.o' file suitable for static linking -static only build a \`.o' file suitable for static linking -Wc,FLAG pass FLAG directly to the compiler COMPILE-COMMAND is a command to be used in creating a \`standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix \`.c' with the library object suffix, \`.lo'." ;; execute) $ECHO \ "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to \`-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $ECHO \ "Usage: $progname [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the \`--dry-run' option if you just want to see what would be executed." ;; install) $ECHO \ "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the \`install' or \`cp' program. The following components of INSTALL-COMMAND are treated specially: -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -bindir BINDIR specify path to binaries directory (for systems where libraries must be found in the PATH setting at runtime) -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE Use a list of object files found in FILE to specify objects -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -static do not do any dynamic linking of uninstalled libtool libraries -static-libtool-libs do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) All other options (arguments beginning with \`-') are ignored. Every other argument is treated as a filename. Files ending in \`.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in \`.la', then a libtool library is created, only library objects (\`.lo' files) may be specified, and \`-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created using \`ar' and \`ranlib', or on Windows using \`lib'. If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $ECHO \ "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) func_fatal_help "invalid operation mode \`$opt_mode'" ;; esac echo $ECHO "Try \`$progname --help' for more information about other modes." } # Now that we've collected a possible --mode arg, show help if necessary if $opt_help; then if test "$opt_help" = :; then func_mode_help else { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do func_mode_help done } | sed -n '1p; 2,$s/^Usage:/ or: /p' { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do echo func_mode_help done } | sed '1d /^When reporting/,/^Report/{ H d } $x /information about other modes/d /more detailed .*MODE/d s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' fi exit $? fi # func_mode_execute arg... func_mode_execute () { $opt_debug # The first argument is the command name. cmd="$nonopt" test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $opt_dlopen; do test -f "$file" \ || func_fatal_help "\`$file' is not a file" dir= case $file in *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "\`$file' was not linked with \`-export-dynamic'" continue fi func_dirname "$file" "" "." dir="$func_dirname_result" if test -f "$dir/$objdir/$dlname"; then func_append dir "/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir="$func_dirname_result" ;; *) func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir="$absdir" # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic="$magic" # Check if any of the arguments is a wrapper script. args= for file do case $file in -* | *.la | *.lo ) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file="$progdir/$program" elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file="$progdir/$program" fi ;; esac # Quote arguments (to preserve shell metacharacters). func_append_quoted args "$file" done if test "X$opt_dry_run" = Xfalse; then if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${save_$lt_var+set}\" = set; then $lt_var=\$save_$lt_var; export $lt_var else $lt_unset $lt_var fi" done # Now prepare to actually exec the command. exec_cmd="\$cmd$args" else # Display what would be done. if test -n "$shlibpath_var"; then eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" echo "export $shlibpath_var" fi $ECHO "$cmd$args" exit $EXIT_SUCCESS fi } test "$opt_mode" = execute && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $opt_debug libs= libdirs= admincmds= for opt in "$nonopt" ${1+"$@"} do if test -d "$opt"; then func_append libdirs " $opt" elif test -f "$opt"; then if func_lalib_unsafe_p "$opt"; then func_append libs " $opt" else func_warning "\`$opt' is not a valid libtool archive" fi else func_fatal_error "invalid argument \`$opt'" fi done if test -n "$libs"; then if test -n "$lt_sysroot"; then sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" else sysroot_cmd= fi # Remove sysroot references if $opt_dry_run; then for lib in $libs; do echo "removing references to $lt_sysroot and \`=' prefixes from $lib" done else tmpdir=`func_mktempdir` for lib in $libs; do sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ > $tmpdir/tmp-la mv -f $tmpdir/tmp-la $lib done ${RM}r "$tmpdir" fi fi if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || func_append admincmds " $cmds" fi done fi # Exit here if they wanted silent mode. $opt_silent && exit $EXIT_SUCCESS if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then echo "----------------------------------------------------------------------" echo "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" echo "specify the full pathname of the library, or use the \`-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then echo " - add LIBDIR to the \`$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then echo " - add LIBDIR to the \`$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the \`$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" fi echo echo "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" echo "pages." ;; *) echo "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac echo "----------------------------------------------------------------------" fi exit $EXIT_SUCCESS } test "$opt_mode" = finish && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $opt_debug # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || # Allow the use of GNU shtool's install command. case $nonopt in *shtool*) :;; *) false;; esac; then # Aesthetically quote it. func_quote_for_eval "$nonopt" install_prog="$func_quote_for_eval_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_for_eval "$arg" func_append install_prog "$func_quote_for_eval_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; *) install_cp=false ;; esac # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=no stripme= no_mode=: for arg do arg2= if test -n "$dest"; then func_append files " $dest" dest=$arg continue fi case $arg in -d) isdir=yes ;; -f) if $install_cp; then :; else prev=$arg fi ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then if test "x$prev" = x-m && test -n "$install_override_mode"; then arg2=$install_override_mode no_mode=false fi prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_for_eval "$arg" func_append install_prog " $func_quote_for_eval_result" if test -n "$arg2"; then func_quote_for_eval "$arg2" fi func_append install_shared_prog " $func_quote_for_eval_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the \`$prev' option requires an argument" if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else func_quote_for_eval "$install_override_mode" func_append install_shared_prog " -m $func_quote_for_eval_result" fi fi if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=yes if test "$isdir" = yes; then destdir="$dest" destname= else func_dirname_and_basename "$dest" "" "." destdir="$func_dirname_result" destname="$func_basename_result" # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "\`$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "\`$destdir' must be an absolute directory name" ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. func_append staticlibs " $file" ;; *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) func_append current_libdirs " $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) func_append future_libdirs " $libdir" ;; esac fi func_dirname "$file" "/" "" dir="$func_dirname_result" func_append dir "$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi func_warning "relinking \`$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname="$1" shift srcname="$realname" test -n "$relink_command" && srcname="$realname"T # Install the shared library and build the symlinks. func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme="$stripme" case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) tstripme="" ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_eval "$striplib $destdir/$realname" 'exit $?' fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try `ln -sf' first, because the `ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib="$destdir/$realname" func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name="$func_basename_result" instname="$dir/$name"i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && func_append staticlibs " $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest="$destfile" destfile= ;; *) func_fatal_help "cannot copy a libtool object to \`$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test "$build_old_libs" = yes; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext="" case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=".exe" fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script \`$wrapper'" finalize=yes for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test if test -n "$libdir" && test ! -f "$libfile"; then func_warning "\`$lib' has not been installed in \`$libdir'" finalize=no fi done relink_command= func_source "$wrapper" outputname= if test "$fast_install" = no && test -n "$relink_command"; then $opt_dry_run || { if test "$finalize" = yes; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file="$func_basename_result" outputname="$tmpdir/$file" # Replace the output file specification. relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` $opt_silent || { func_quote_for_expand "$relink_command" eval "func_echo $func_quote_for_expand_result" } if eval "$relink_command"; then : else func_error "error: relink \`$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file="$outputname" else func_warning "cannot relink \`$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name="$func_basename_result" # Set up the ranlib parameters. oldlib="$destdir/$name" func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $tool_oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run \`$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test "$opt_mode" = install && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $opt_debug my_outputname="$1" my_originator="$2" my_pic_p="${3-no}" my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms="${my_outputname}S.c" else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist="$output_objdir/${my_outputname}.nm" func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif #if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" #endif /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif /* External symbol declarations for the compiler. */\ " if test "$dlself" = yes; then func_verbose "generating symbol list for \`$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` for progfile in $progfiles; do func_to_tool_file "$progfile" func_convert_file_msys_to_w32 func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols="$output_objdir/$outputname.exp" $opt_dry_run || { $RM $export_symbols eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from \`$dlprefile'" func_basename "$dlprefile" name="$func_basename_result" case $host in *cygwin* | *mingw* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" eval "curr_lafile=\$libfile_$func_tr_sh_result" dlprefile_dlbasename="" if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then # Use subshell, to avoid clobbering current variable values dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` if test -n "$dlprefile_dlname" ; then func_basename "$dlprefile_dlname" dlprefile_dlbasename="$func_basename_result" else # no lafile. user explicitly requested -dlpreopen . $sharedlib_from_linklib_cmd "$dlprefile" dlprefile_dlbasename=$sharedlib_from_linklib_result fi fi $opt_dry_run || { if test -n "$dlprefile_dlbasename" ; then eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' else func_warning "Could not compute DLL name from $name" eval '$ECHO ": $name " >> "$nlist"' fi func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" } else # not an import lib $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } fi ;; *) $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } ;; esac done $opt_dry_run || { # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $MV "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if $GREP -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else $GREP -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' else echo '/* NONE */' >> "$output_objdir/$my_dlsyms" fi echo >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; extern LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[]; LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = {\ { \"$my_originator\", (void *) 0 }," case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac echo >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) if test "X$my_pic_p" != Xno; then pic_flag_for_symtable=" $pic_flag" fi ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) func_append symtab_cflags " $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' # Transform the symbol file into the correct name. symfileobj="$output_objdir/${my_outputname}S.$objext" case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for \`$my_dlsyms'" ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` fi } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. # Despite the name, also deal with 64 bit binaries. func_win32_libid () { $opt_debug win32_libid_type="unknown" win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then func_to_tool_file "$1" func_convert_file_msys_to_w32 win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | $SED -n -e ' 1,100{ / I /{ s,.*,import, p q } }'` case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $ECHO "$win32_libid_type" } # func_cygming_dll_for_implib ARG # # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib () { $opt_debug sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` } # func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs # # The is the core of a fallback implementation of a # platform-specific function to extract the name of the # DLL associated with the specified import library LIBNAME. # # SECTION_NAME is either .idata$6 or .idata$7, depending # on the platform and compiler that created the implib. # # Echos the name of the DLL associated with the # specified import library. func_cygming_dll_for_implib_fallback_core () { $opt_debug match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` $OBJDUMP -s --section "$1" "$2" 2>/dev/null | $SED '/^Contents of section '"$match_literal"':/{ # Place marker at beginning of archive member dllname section s/.*/====MARK====/ p d } # These lines can sometimes be longer than 43 characters, but # are always uninteresting /:[ ]*file format pe[i]\{,1\}-/d /^In archive [^:]*:/d # Ensure marker is printed /^====MARK====/p # Remove all lines with less than 43 characters /^.\{43\}/!d # From remaining lines, remove first 43 characters s/^.\{43\}//' | $SED -n ' # Join marker and all lines until next marker into a single line /^====MARK====/ b para H $ b para b :para x s/\n//g # Remove the marker s/^====MARK====// # Remove trailing dots and whitespace s/[\. \t]*$// # Print /./p' | # we now have a list, one entry per line, of the stringified # contents of the appropriate section of all members of the # archive which possess that section. Heuristic: eliminate # all those which have a first or second character that is # a '.' (that is, objdump's representation of an unprintable # character.) This should work for all archives with less than # 0x302f exports -- but will fail for DLLs whose name actually # begins with a literal '.' or a single character followed by # a '.'. # # Of those that remain, print the first one. $SED -e '/^\./d;/^.\./d;q' } # func_cygming_gnu_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is a GNU/binutils-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_gnu_implib_p () { $opt_debug func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` test -n "$func_cygming_gnu_implib_tmp" } # func_cygming_ms_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is an MS-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_ms_implib_p () { $opt_debug func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` test -n "$func_cygming_ms_implib_tmp" } # func_cygming_dll_for_implib_fallback ARG # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # # This fallback implementation is for use when $DLLTOOL # does not support the --identify-strict option. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib_fallback () { $opt_debug if func_cygming_gnu_implib_p "$1" ; then # binutils import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` elif func_cygming_ms_implib_p "$1" ; then # ms-generated import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` else # unknown sharedlib_from_linklib_result="" fi } # func_extract_an_archive dir oldlib func_extract_an_archive () { $opt_debug f_ex_an_ar_dir="$1"; shift f_ex_an_ar_oldlib="$1" if test "$lock_old_archive_extraction" = yes; then lockfile=$f_ex_an_ar_oldlib.lock until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done fi func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ 'stat=$?; rm -f "$lockfile"; exit $stat' if test "$lock_old_archive_extraction" = yes; then $opt_dry_run || rm -f "$lockfile" fi if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $opt_debug my_gentop="$1"; shift my_oldlibs=${1+"$@"} my_oldobjs="" my_xlib="" my_xabs="" my_xdir="" for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" my_xlib="$func_basename_result" my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac done extracted_archives="$extracted_archives $my_xlib_u" my_xdir="$my_gentop/$my_xlib_u" func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` darwin_base_archive=`basename "$darwin_archive"` darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches ; do func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" func_extract_an_archive "`pwd`" "${darwin_base_archive}" cd "$darwin_curdir" $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` done func_extract_archives_result="$my_oldobjs" } # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory in which it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=${1-no} $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='$sed_quote_subst' # Be Bourne compatible if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variables: generated_by_libtool_version='$macro_version' notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$ECHO are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then file=\"\$0\"" qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` $ECHO "\ # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } ECHO=\"$qECHO\" fi # Very basic option parsing. These options are (a) specific to # the libtool wrapper, (b) are identical between the wrapper # /script/ and the wrapper /executable/ which is used only on # windows platforms, and (c) all begin with the string "--lt-" # (application programs are unlikely to have options which match # this pattern). # # There are only two supported options: --lt-debug and # --lt-dump-script. There is, deliberately, no --lt-help. # # The first argument to this parsing function should be the # script's $0 value, followed by "$@". lt_option_debug= func_parse_lt_options () { lt_script_arg0=\$0 shift for lt_opt do case \"\$lt_opt\" in --lt-debug) lt_option_debug=1 ;; --lt-dump-script) lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` cat \"\$lt_dump_D/\$lt_dump_F\" exit 0 ;; --lt-*) \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 exit 1 ;; esac done # Print the debug banner immediately: if test -n \"\$lt_option_debug\"; then echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 fi } # Used when --lt-debug. Prints its arguments to stdout # (redirection is the responsibility of the caller) func_lt_dump_args () { lt_dump_args_N=1; for lt_arg do \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` done } # Core function for launching the target application func_exec_program_core () { " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 } # A function to encapsulate launching the target application # Strips options in the --lt-* namespace from \$@ and # launches target application with the remaining arguments. func_exec_program () { case \" \$* \" in *\\ --lt-*) for lt_wr_arg do case \$lt_wr_arg in --lt-*) ;; *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; esac shift done ;; esac func_exec_program_core \${1+\"\$@\"} } # Parse options func_parse_lt_options \"\$0\" \${1+\"\$@\"} # Find the directory that this script lives in. thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` done # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test "$fast_install" = yes; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $MKDIR \"\$progdir\" else $RM \"\$progdir/\$file\" fi" $ECHO "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else $ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # fixup the dll searchpath if we need to. # # Fix the DLL searchpath if we need to. Do this before prepending # to shlibpath, because on Windows, both are PATH and uninstalled # libraries must come first. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi # Export our shlibpath_var if we have one. if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` export $shlibpath_var " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. func_exec_program \${1+\"\$@\"} fi else # The program doesn't exist. \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat < #include #ifdef _MSC_VER # include # include # include #else # include # include # ifdef __CYGWIN__ # include # endif #endif #include #include #include #include #include #include #include #include /* declarations of non-ANSI functions */ #if defined(__MINGW32__) # ifdef __STRICT_ANSI__ int _putenv (const char *); # endif #elif defined(__CYGWIN__) # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif /* #elif defined (other platforms) ... */ #endif /* portability defines, excluding path handling macros */ #if defined(_MSC_VER) # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv # define S_IXUSR _S_IEXEC # ifndef _INTPTR_T_DEFINED # define _INTPTR_T_DEFINED # define intptr_t int # endif #elif defined(__MINGW32__) # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv #elif defined(__CYGWIN__) # define HAVE_SETENV # define FOPEN_WB "wb" /* #elif defined (other platforms) ... */ #endif #if defined(PATH_MAX) # define LT_PATHMAX PATH_MAX #elif defined(MAXPATHLEN) # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif /* path handling portability macros */ #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ defined (__OS2__) # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free ((void *) stale); stale = 0; } \ } while (0) #if defined(LT_DEBUGWRAPPER) static int lt_debug = 1; #else static int lt_debug = 0; #endif const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_debugprintf (const char *file, int line, const char *fmt, ...); void lt_fatal (const char *file, int line, const char *message, ...); static const char *nonnull (const char *s); static const char *nonempty (const char *s); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); char **prepare_spawn (char **argv); void lt_dump_script (FILE *f); EOF cat <= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", nonempty (path)); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ char * find_executable (const char *wrapper) { int has_slash = 0; const char *p; const char *p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; int tmp_len; char *concat_name; lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", nonempty (wrapper)); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined (HAVE_DOS_BASED_FILE_SYSTEM) if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } #if defined (HAVE_DOS_BASED_FILE_SYSTEM) } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char *path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char *q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR (*q)) break; p_len = q - p; p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); return NULL; } char * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { lt_debugprintf (__FILE__, __LINE__, "checking path component for symlinks: %s\n", tmp_pathspec); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { lt_fatal (__FILE__, __LINE__, "error accessing file \"%s\": %s", tmp_pathspec, nonnull (strerror (errno))); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal (__FILE__, __LINE__, "could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } char * strendzap (char *str, const char *pat) { size_t len, patlen; assert (str != NULL); assert (pat != NULL); len = strlen (str); patlen = strlen (pat); if (patlen <= len) { str += len - patlen; if (strcmp (str, pat) == 0) *str = '\0'; } return str; } void lt_debugprintf (const char *file, int line, const char *fmt, ...) { va_list args; if (lt_debug) { (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } } static void lt_error_core (int exit_status, const char *file, int line, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *file, int line, const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); va_end (ap); } static const char * nonnull (const char *s) { return s ? s : "(null)"; } static const char * nonempty (const char *s) { return (s && !*s) ? "(empty)" : nonnull (s); } void lt_setenv (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_setenv) setting '%s' to '%s'\n", nonnull (name), nonnull (value)); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else int len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { int orig_value_len = strlen (orig_value); int add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } void lt_update_exe_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ int len = strlen (new_value); while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[len-1] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF case $host_os in mingw*) cat <<"EOF" /* Prepares an argument vector before calling spawn(). Note that spawn() does not by itself call the command interpreter (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&v); v.dwPlatformId == VER_PLATFORM_WIN32_NT; }) ? "cmd.exe" : "command.com"). Instead it simply concatenates the arguments, separated by ' ', and calls CreateProcess(). We must quote the arguments since Win32 CreateProcess() interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a special way: - Space and tab are interpreted as delimiters. They are not treated as delimiters if they are surrounded by double quotes: "...". - Unescaped double quotes are removed from the input. Their only effect is that within double quotes, space and tab are treated like normal characters. - Backslashes not followed by double quotes are not special. - But 2*n+1 backslashes followed by a double quote become n backslashes followed by a double quote (n >= 0): \" -> " \\\" -> \" \\\\\" -> \\" */ #define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" #define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" char ** prepare_spawn (char **argv) { size_t argc; char **new_argv; size_t i; /* Count number of arguments. */ for (argc = 0; argv[argc] != NULL; argc++) ; /* Allocate new argument vector. */ new_argv = XMALLOC (char *, argc + 1); /* Put quoted arguments into the new argument vector. */ for (i = 0; i < argc; i++) { const char *string = argv[i]; if (string[0] == '\0') new_argv[i] = xstrdup ("\"\""); else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) { int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); size_t length; unsigned int backslashes; const char *s; char *quoted_string; char *p; length = 0; backslashes = 0; if (quote_around) length++; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') length += backslashes + 1; length++; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) length += backslashes + 1; quoted_string = XMALLOC (char, length + 1); p = quoted_string; backslashes = 0; if (quote_around) *p++ = '"'; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') { unsigned int j; for (j = backslashes + 1; j > 0; j--) *p++ = '\\'; } *p++ = c; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) { unsigned int j; for (j = backslashes; j > 0; j--) *p++ = '\\'; *p++ = '"'; } *p = '\0'; new_argv[i] = quoted_string; } else new_argv[i] = (char *) string; } new_argv[argc] = NULL; return new_argv; } EOF ;; esac cat <<"EOF" void lt_dump_script (FILE* f) { EOF func_emit_wrapper yes | $SED -n -e ' s/^\(.\{79\}\)\(..*\)/\1\ \2/ h s/\([\\"]\)/\\\1/g s/$/\\n/ s/\([^\n]*\).*/ fputs ("\1", f);/p g D' cat <<"EOF" } EOF } # end: func_emit_cwrapperexe_src # func_win32_import_lib_p ARG # True if ARG is an import lib, as indicated by $file_magic_cmd func_win32_import_lib_p () { $opt_debug case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in *import*) : ;; *) false ;; esac } # func_mode_link arg... func_mode_link () { $opt_debug case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # which system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll which has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no bindir= dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=no prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= vinfo_number=no weak_libs= single_module="${wl}-single_module" func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; -static) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built ;; -static-libtool-libs) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; esac build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg="$1" shift func_quote_for_eval "$arg" qarg=$func_quote_for_eval_unquoted_result func_append libtool_args " $func_quote_for_eval_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) func_append compile_command " @OUTPUT@" func_append finalize_command " @OUTPUT@" ;; esac case $prev in bindir) bindir="$arg" prev= continue ;; dlfiles|dlprefiles) if test "$preload" = no; then # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" preload=yes fi case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test "$dlself" = no; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test "$prev" = dlprefiles; then dlself=yes elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test "$prev" = dlfiles; then func_append dlfiles " $arg" else func_append dlprefiles " $arg" fi prev= continue ;; esac ;; expsyms) export_symbols="$arg" test -f "$arg" \ || func_fatal_error "symbol file \`$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex="$arg" prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) func_append deplibs " $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir="$arg" prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # func_append moreargs " $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file \`$arg' does not exist" fi arg=$save_arg prev= continue ;; precious_regex) precious_files_regex="$arg" prev= continue ;; release) release="-$arg" prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac if test "$prev" = rpath; then case "$rpath " in *" $arg "*) ;; *) func_append rpath " $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) func_append xrpath " $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds="$arg" prev= continue ;; weak) func_append weak_libs " $arg" prev= continue ;; xcclinker) func_append linker_flags " $qarg" func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) func_append linker_flags " $qarg" func_append compiler_flags " $wl$qarg" prev= func_append compile_command " $wl$qarg" func_append finalize_command " $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg="$arg" case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. func_append compile_command " $link_static_flag" func_append finalize_command " $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "\`-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -bindir) prev=bindir continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test "X$arg" = "X-export-symbols"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) func_append compile_command " $arg" func_append finalize_command " $arg" ;; esac continue ;; -L*) func_stripname "-L" '' "$arg" if test -z "$func_stripname_result"; then if test "$#" -gt 0; then func_fatal_error "require no space between \`-L' and \`$1'" else func_fatal_error "need path for \`-L' option" fi fi func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of \`$dir'" dir="$absdir" ;; esac case "$deplibs " in *" -L$dir "* | *" $arg "*) # Will only happen for absolute or sysroot arguments ;; *) # Preserve sysroot, but never include relative directories case $dir in [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; *) func_append deplibs " -L$dir" ;; esac func_append lib_search_path " $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) func_append dllsearchpath ":$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac continue ;; -l*) if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test "X$arg" = "X-lc" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. test "X$arg" = "X-lc" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework func_append deplibs " System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test "X$arg" = "X-lc" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test "X$arg" = "X-lc" && continue ;; esac elif test "X$arg" = "X-lc_r"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi func_append deplibs " $arg" continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. -model|-arch|-isysroot|--sysroot) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) func_append new_inherited_linker_flags " $arg" ;; esac continue ;; -multi_module) single_module="${wl}-multi_module" continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "\`-no-install' is ignored for $host" func_warning "assuming \`-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) func_stripname '-R' '' "$arg" dir=$func_stripname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; =*) func_stripname '=' '' "$dir" dir=$lt_sysroot$func_stripname_result ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac continue ;; -shared) # The effects of -shared are defined in a previous loop. continue ;; -shrext) prev=shrext continue ;; -static | -static-libtool-libs) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -weak) prev=weak continue ;; -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" func_append arg " $func_quote_for_eval_result" func_append compiler_flags " $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Wl,*) func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" func_append arg " $wl$func_quote_for_eval_result" func_append compiler_flags " $wl$func_quote_for_eval_result" func_append linker_flags " $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; # Flags to be passed through unchanged, with rationale: # -64, -mips[0-9] enable 64-bit mode for the SGI compiler # -r[0-9][0-9]* specify processor for the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler # +DA*, +DD* enable 64-bit mode for the HP compiler # -q* compiler args for the IBM compiler # -m*, -t[45]*, -txscale* architecture-specific flags for GCC # -F/path path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* profiling flags for GCC # @file GCC response files # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ -O*|-flto*|-fwhopr*|-fuse-linker-plugin) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" func_append compile_command " $arg" func_append finalize_command " $arg" func_append compiler_flags " $arg" continue ;; # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; *.$objext) # A standard object. func_append objs " $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi ;; *.$libext) # An archive. func_append deplibs " $arg" func_append old_deplibs " $arg" continue ;; *.la) # A libtool-controlled library. func_resolve_sysroot "$arg" if test "$prev" = dlfiles; then # This library was specified with -dlopen. func_append dlfiles " $func_resolve_sysroot_result" prev= elif test "$prev" = dlprefiles; then # The library was specified with -dlpreopen. func_append dlprefiles " $func_resolve_sysroot_result" prev= else func_append deplibs " $func_resolve_sysroot_result" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then func_append compile_command " $arg" func_append finalize_command " $arg" fi done # argument parsing loop test -n "$prev" && \ func_fatal_help "the \`$prevarg' option requires an argument" if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" fi oldlibs= # calculate the name of the file, without its directory func_basename "$output" outputname="$func_basename_result" libobjs_save="$libobjs" if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" func_dirname "$output" "/" "" output_objdir="$func_dirname_result$objdir" func_to_tool_file "$output_objdir/" tool_output_objdir=$func_to_tool_file_result # Create the object directory. func_mkdir_p "$output_objdir" # Determine the type of output case $output in "") func_fatal_help "you must specify an output file" ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if $opt_preserve_dup_deps ; then case "$libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append libs " $deplib" done if test "$linkmode" = lib; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if $opt_duplicate_compiler_generated_deps; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; esac func_append pre_post_deps " $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv dlpreopen link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=no newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... if test "$linkmode,$pass" = "lib,link"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done deplibs="$tmp_deplibs" fi if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan"; then libs="$deplibs" deplibs= fi if test "$linkmode" = prog; then case $pass in dlopen) libs="$dlfiles" ;; dlpreopen) libs="$dlprefiles" ;; link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; esac fi if test "$linkmode,$pass" = "lib,dlpreopen"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= func_resolve_sysroot "$lib" case $lib in *.la) func_source "$func_resolve_sysroot_result" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do func_basename "$deplib" deplib_base=$func_basename_result case " $weak_libs " in *" $deplib_base "*) ;; *) func_append deplibs " $deplib" ;; esac done done libs="$dlprefiles" fi if test "$pass" = dlopen; then # Collect dlpreopened libraries save_deplibs="$deplibs" deplibs= fi for deplib in $libs; do lib= found=no case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append compiler_flags " $deplib" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -l*) if test "$linkmode" != lib && test "$linkmode" != prog; then func_warning "\`-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test "$linkmode" = lib; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" fi for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib="$searchdir/lib${name}${search_ext}" if test -f "$lib"; then if test "$search_ext" = ".la"; then found=yes else found=no fi break 2 fi done done if test "$found" != yes; then # deplib doesn't seem to be a libtool library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue else # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then library_names= old_library= func_source "$lib" for l in $old_library $library_names; do ll="$l" done if test "X$ll" = "X$old_library" ; then # only static version available found=no func_dirname "$lib" "" "." ladir="$func_dirname_result" lib=$ladir/$old_library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi fi ;; # -l *.ltframework) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test "$pass" = conv && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; prog) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi if test "$pass" = scan; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; *) func_warning "\`-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test "$pass" = link; then func_stripname '-R' '' "$deplib" func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) func_resolve_sysroot "$deplib" lib=$func_resolve_sysroot_result ;; *.$libext) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) # Linking convenience modules into shared libraries is allowed, # but linking other static libraries is non-portable. case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) valid_a_lib=no case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=yes fi ;; pass_all) valid_a_lib=yes ;; esac if test "$valid_a_lib" != yes; then echo $ECHO "*** Warning: Trying to link with static lib archive $deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because the file extensions .$libext of this argument makes me believe" echo "*** that it is just a static archive that I should not use here." else echo $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" fi ;; esac continue ;; prog) if test "$pass" != link; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test "$pass" = conv; then deplibs="$deplib $deplibs" elif test "$linkmode" = prog; then if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlopen support or we're linking statically, # we need to preload. func_append newdlprefiles " $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append newdlfiles " $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=yes continue ;; esac # case $deplib if test "$found" = yes || test -f "$lib"; then : else func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" fi # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ || func_fatal_error "\`$lib' is not a valid libtool archive" func_dirname "$lib" "" "." ladir="$func_dirname_result" dlname= dlopen= dlpreopen= libdir= library_names= old_library= inherited_linker_flags= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file func_source "$lib" # Convert "-framework foo" to "foo.ltframework" if test -n "$inherited_linker_flags"; then tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do case " $new_inherited_linker_flags " in *" $tmp_inherited_linker_flag "*) ;; *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan" || { test "$linkmode" != prog && test "$linkmode" != lib; }; then test -n "$dlopen" && func_append dlfiles " $dlopen" test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" fi if test "$pass" = conv; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # It is a libtool convenience library, so add in its objects. func_append convenience " $ladir/$objdir/$old_library" func_append old_convenience " $ladir/$objdir/$old_library" elif test "$linkmode" != prog && test "$linkmode" != lib; then func_fatal_error "\`$lib' is not a convenience library" fi tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done continue fi # $pass = conv # Get the name of the library we link against. linklib= if test -n "$old_library" && { test "$prefer_static_libs" = yes || test "$prefer_static_libs,$installed" = "built,no"; }; then linklib=$old_library else for l in $old_library $library_names; do linklib="$l" done fi if test -z "$linklib"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # This library was specified with -dlopen. if test "$pass" = dlopen; then if test -z "$libdir"; then func_fatal_error "cannot -dlopen a convenience library: \`$lib'" fi if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. func_append dlprefiles " $lib $dependency_libs" else func_append newdlfiles " $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then func_warning "cannot determine absolute directory name of \`$ladir'" func_warning "passing it literally to the linker, although it might fail" abs_ladir="$ladir" fi ;; esac func_basename "$lib" laname="$func_basename_result" # Find the relevant object directory and library name. if test "X$installed" = Xyes; then if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library \`$lib' was moved." dir="$ladir" absdir="$abs_ladir" libdir="$abs_ladir" else dir="$lt_sysroot$libdir" absdir="$lt_sysroot$libdir" fi test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir="$ladir" absdir="$abs_ladir" # Remove this search path later func_append notinst_path " $abs_ladir" else dir="$ladir/$objdir" absdir="$abs_ladir/$objdir" # Remove this search path later func_append notinst_path " $abs_ladir" fi fi # $installed = yes func_stripname 'lib' '.la' "$laname" name=$func_stripname_result # This library was specified with -dlpreopen. if test "$pass" = dlpreopen; then if test -z "$libdir" && test "$linkmode" = prog; then func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" fi case "$host" in # special handling for platforms with PE-DLLs. *cygwin* | *mingw* | *cegcc* ) # Linker will automatically link against shared library if both # static and shared are present. Therefore, ensure we extract # symbols from the import library if a shared library is present # (otherwise, the dlopen module name will be incorrect). We do # this by putting the import library name into $newdlprefiles. # We recover the dlopen module name by 'saving' the la file # name in a special purpose variable, and (later) extracting the # dlname from the la file. if test -n "$dlname"; then func_tr_sh "$dir/$linklib" eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" func_append newdlprefiles " $dir/$linklib" else func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" fi ;; * ) # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then func_append newdlprefiles " $dir/$dlname" else func_append newdlprefiles " $dir/$linklib" fi ;; esac fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test "$linkmode" = lib; then deplibs="$dir/$old_library $deplibs" elif test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test "$linkmode" = prog && test "$pass" != link; then func_append newlib_search_path " $ladir" deplibs="$lib $deplibs" linkalldeplibs=no if test "$link_all_deplibs" != no || test -z "$library_names" || test "$build_libtool_libs" = no; then linkalldeplibs=yes fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; esac # Need to link against all dependency_libs? if test "$linkalldeplibs" = yes; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done # for deplib continue fi # $linkmode = prog... if test "$linkmode,$pass" = "prog,link"; then if test -n "$library_names" && { { test "$prefer_static_libs" = no || test "$prefer_static_libs,$installed" = "built,yes"; } || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then # Make sure the rpath contains only unique directories. case "$temp_rpath:" in *"$absdir:"*) ;; *) func_append temp_rpath "$absdir:" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi # $linkmode,$pass = prog,link... if test "$alldeplibs" = yes && { test "$deplibs_check_method" = pass_all || { test "$build_libtool_libs" = yes && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs if test "$use_static_libs" = built && test "$installed" = yes; then use_static_libs=no fi if test -n "$library_names" && { test "$use_static_libs" = no || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc*) # No point in relinking DLLs because paths are not encoded func_append notinst_deplibs " $lib" need_relink=no ;; *) if test "$installed" = no; then func_append notinst_deplibs " $lib" need_relink=yes fi ;; esac # This is a shared library # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! dlopenmodule="" for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then dlopenmodule="$dlpremoduletest" break fi done if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then echo if test "$linkmode" = prog; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi if test "$linkmode" = lib && test "$hardcode_into_libs" = yes; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names shift realname="$1" shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname="$dlname" elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc*) func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; esac eval soname=\"$soname_spec\" else soname="$realname" fi # Make a new name for the extract_expsyms_cmds to use soroot="$soname" func_basename "$soroot" soname="$func_basename_result" func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else func_verbose "extracting exported symbol list from \`$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else func_verbose "generating import library for \`$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test "$linkmode" = prog || test "$opt_mode" != relink; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test "$hardcode_direct" = no; then add="$dir/$linklib" case $host in *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; *-*-sysv4*uw2*) add_dir="-L$dir" ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir="-L$dir" ;; *-*-darwin* ) # if the lib is a (non-dlopened) module then we can not # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null ; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" if test -z "$old_library" ; then echo echo "*** And there doesn't seem to be a static archive available" echo "*** The link will probably fail, sorry" else add="$dir/$old_library" fi elif test -n "$old_library"; then add="$dir/$old_library" fi fi esac elif test "$hardcode_minus_L" = no; then case $host in *-*-sunos*) add_shlibpath="$dir" ;; esac add_dir="-L$dir" add="-l$name" elif test "$hardcode_shlibpath_var" = no; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; relink) if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$dir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$absdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; *) lib_linked=no ;; esac if test "$lib_linked" != yes; then func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) func_append compile_shlibpath "$add_shlibpath:" ;; esac fi if test "$linkmode" = prog; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test "$hardcode_direct" != yes && test "$hardcode_minus_L" != yes && test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac fi fi fi if test "$linkmode" = prog || test "$opt_mode" = relink; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$libdir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$libdir" add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac add="-l$name" elif test "$hardcode_automatic" = yes; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib" ; then add="$inst_prefix_dir$libdir/$linklib" else add="$libdir/$linklib" fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir="-L$libdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" fi if test "$linkmode" = prog; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test "$linkmode" = prog; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test "$hardcode_direct" != unsupported; then test -n "$old_library" && linklib="$old_library" compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test "$build_libtool_libs" = yes; then # Not a shared library if test "$deplibs_check_method" != pass_all; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. echo $ECHO "*** Warning: This system can not link to static lib archive $lib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have." if test "$module" = yes; then echo "*** But as you try to build a module library, libtool will still create " echo "*** a static module, that should work as long as the dlopening application" echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using \`nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test "$linkmode" = lib; then if test -n "$dependency_libs" && { test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes || test "$link_static" = yes; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) func_stripname '-R' '' "$libdir" temp_xrpath=$func_stripname_result case " $xrpath " in *" $temp_xrpath "*) ;; *) func_append xrpath " $temp_xrpath";; esac;; *) func_append temp_deplibs " $libdir";; esac done dependency_libs="$temp_deplibs" fi func_append newlib_search_path " $absdir" # Link against this library test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result";; *) func_resolve_sysroot "$deplib" ;; esac if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $func_resolve_sysroot_result "*) func_append specialdeplibs " $func_resolve_sysroot_result" ;; esac fi func_append tmp_libs " $func_resolve_sysroot_result" done if test "$link_all_deplibs" != no; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in -L*) path="$deplib" ;; *.la) func_resolve_sysroot "$deplib" deplib=$func_resolve_sysroot_result func_dirname "$deplib" "" "." dir=$func_dirname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then func_warning "cannot determine absolute directory name of \`$dir'" absdir="$dir" fi ;; esac if $GREP "^installed=no" $deplib > /dev/null; then case $host in *-*-darwin*) depdepl= eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names" ; then for tmp in $deplibrary_names ; do depdepl=$tmp done if test -f "$absdir/$objdir/$depdepl" ; then depdepl="$absdir/$objdir/$depdepl" darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" path= fi fi ;; *) path="-L$absdir/$objdir" ;; esac else eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ func_warning "\`$deplib' seems to be moved" path="-L$absdir" fi ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test "$pass" = link; then if test "$linkmode" = "prog"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi dependency_libs="$newdependency_libs" if test "$pass" = dlpreopen; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test "$pass" != dlopen; then if test "$pass" != conv; then # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) func_append lib_search_path " $dir" ;; esac done newlib_search_path= fi if test "$linkmode,$pass" != "prog,link"; then vars="deplibs" else vars="compile_deplibs finalize_deplibs" fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) func_append tmp_libs " $deplib" ;; esac ;; *) func_append tmp_libs " $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs ; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i="" ;; esac if test -n "$i" ; then func_append tmp_libs " $i" fi done dependency_libs=$tmp_libs done # for pass if test "$linkmode" = prog; then dlfiles="$newdlfiles" fi if test "$linkmode" = prog || test "$linkmode" = lib; then dlprefiles="$newdlprefiles" fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for archives" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for archives" test -n "$xrpath" && \ func_warning "\`-R' is ignored for archives" test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for archives" test -n "$release" && \ func_warning "\`-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ func_warning "\`-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no oldlibs="$output" func_append objs "$old_deplibs" ;; lib) # Make sure we only generate libraries of the form `libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) test "$module" = no && \ func_fatal_help "libtool library \`$output' must begin with \`lib'" if test "$need_lib_prefix" != no; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else func_stripname '' '.la' "$outputname" libname=$func_stripname_result fi ;; esac if test -n "$objs"; then if test "$deplibs_check_method" != pass_all; then func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" else echo $ECHO "*** Warning: Linking the shared library $output against the non-libtool" $ECHO "*** objects $objs is not portable!" func_append libobjs " $objs" fi fi test "$dlself" != no && \ func_warning "\`-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test "$#" -gt 1 && \ func_warning "ignoring multiple \`-rpath's for a libtool library" install_libdir="$1" oldlibs= if test -z "$rpath"; then if test "$build_libtool_libs" = yes; then # Building a libtool convenience library. # Some compilers have problems with a `.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ func_warning "\`-release' is ignored for convenience libraries" else # Parse the version information argument. save_ifs="$IFS"; IFS=':' set dummy $vinfo 0 0 0 shift IFS="$save_ifs" test -n "$7" && \ func_fatal_help "too many parameters to \`-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major="$1" number_minor="$2" number_revision="$3" # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # which has an extra 1 added just for fun # case $version_type in # correct linux to gnu/linux during the next big refactor darwin|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_revision" ;; freebsd-aout|freebsd-elf|qnx|sunos) current="$number_major" revision="$number_minor" age="0" ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_minor" lt_irix_increment=no ;; esac ;; no) current="$1" revision="$2" age="$3" ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "CURRENT \`$current' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "REVISION \`$revision' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "AGE \`$age' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then func_error "AGE \`$age' is greater than the current interface number \`$current'" func_fatal_error "\`$vinfo' is not valid version information" fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; freebsd-aout) major=".$current" versuffix=".$current.$revision"; ;; freebsd-elf) major=".$current" versuffix=".$current" ;; irix | nonstopux) if test "X$lt_irix_increment" = "Xno"; then func_arith $current - $age else func_arith $current - $age + 1 fi major=$func_arith_result case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring="$verstring_prefix$major.$revision" # Add in all the interfaces that we are compatible with. loop=$revision while test "$loop" -ne 0; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring_prefix$major.$iface:$verstring" done # Before this point, $major must not contain `.'. major=.$major versuffix="$major.$revision" ;; linux) # correct to gnu/linux during the next big refactor func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" ;; osf) func_arith $current - $age major=.$func_arith_result versuffix=".$current.$age.$revision" verstring="$current.$age.$revision" # Add in all the interfaces that we are compatible with. loop=$age while test "$loop" -ne 0; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring:${iface}.0" done # Make executables depend on our current version. func_append verstring ":${current}.0" ;; qnx) major=".$current" versuffix=".$current" ;; sunos) major=".$current" versuffix=".$current.$revision" ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 filesystems. func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; *) func_fatal_configuration "unknown library version type \`$version_type'" ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring="0.0" ;; esac if test "$need_version" = no; then versuffix= else versuffix=".0.0" fi fi # Remove version info from name if versioning should be avoided if test "$avoid_version" = yes && test "$need_version" = no; then major= versuffix= verstring="" fi # Check to see if the archive will have undefined symbols. if test "$allow_undefined" = yes; then if test "$allow_undefined_flag" = unsupported; then func_warning "undefined symbols not allowed in $host shared libraries" build_libtool_libs=no build_old_libs=yes fi else # Don't allow undefined symbols. allow_undefined_flag="$no_undefined_flag" fi fi func_generate_dlsyms "$libname" "$libname" "yes" func_append libobjs " $symfileobj" test "X$libobjs" = "X " && libobjs= if test "$opt_mode" != relink; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$ECHO "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) if test "X$precious_files_regex" != "X"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi func_append removelist " $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then func_append oldlibs " $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` #done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do func_replace_sysroot "$libdir" func_append temp_xrpath " -R$func_replace_sysroot_result" case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles="$dlfiles" dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) func_append dlfiles " $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles="$dlprefiles" dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) func_append dlprefiles " $lib" ;; esac done if test "$build_libtool_libs" = yes; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework func_append deplibs " System.ltframework" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work ;; *) # Add libc to deplibs on all other systems if necessary. if test "$build_libtool_need_lc" = "yes"; then func_append deplibs " -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release="" versuffix="" major="" newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $opt_dry_run || $RM conftest.c cat > conftest.c </dev/null` $nocaseglob else potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` fi for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null | $GREP " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib="$potent_lib" while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a file magic. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" a_deplib="" ;; esac fi if test -n "$a_deplib" ; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib="$potent_lib" # see symlink-check above in file_magic test if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a regex pattern. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs="" tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then for i in $predeps $postdeps ; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` done fi case $tmp_deplibs in *[!\ \ ]*) echo if test "X$deplibs_check_method" = "Xnone"; then echo "*** Warning: inter-library dependencies are not supported in this platform." else echo "*** Warning: inter-library dependencies are not known to be supported." fi echo "*** All declared inter-library dependencies are being dropped." droppeddeps=yes ;; esac ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library with the System framework newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac if test "$droppeddeps" = yes; then if test "$module" = yes; then echo echo "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" echo "*** a static module, that should work as long as the dlopening" echo "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using \`nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else echo "*** The inter-library dependencies that have been dropped here will be" echo "*** automatically added whenever a program is linked with this library" echo "*** or is declared to -dlopen it." if test "$allow_undefined" = no; then echo echo "*** Since this library must not contain undefined symbols," echo "*** because either the platform does not support them or" echo "*** it was explicitly requested with -no-undefined," echo "*** libtool will only create a static version of it." if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" case $host in *-*-darwin*) newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done deplibs="$new_libs" # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test "$build_libtool_libs" = yes; then # Remove ${wl} instances when linking with ld. # FIXME: should test the right _cmds variable. case $archive_cmds in *\$LD\ *) wl= ;; esac if test "$hardcode_into_libs" = yes; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath="$finalize_rpath" test "$opt_mode" != relink && rpath="$compile_rpath$rpath" for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then func_replace_sysroot "$libdir" libdir=$func_replace_sysroot_result if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append dep_rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath="$finalize_shlibpath" test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names shift realname="$1" shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname="$realname" fi if test -z "$dlname"; then dlname=$soname fi lib="$output_objdir/$realname" linknames= for link do func_append linknames " $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` test "X$libobjs" = "X " && libobjs= delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols="$output_objdir/$libname.uexp" func_append delfiles " $export_symbols" fi orig_export_symbols= case $host_os in cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile if test "x`$SED 1q $export_symbols`" != xEXPORTS; then # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. orig_export_symbols="$export_symbols" export_symbols= always_export_symbols=yes fi fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs="$IFS"; IFS='~' for cmd1 in $cmds; do IFS="$save_ifs" # Take the normal branch if the nm_file_list_spec branch # doesn't work or if tool conversion is not needed. case $nm_file_list_spec~$to_tool_file_cmd in *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) try_normal_branch=yes eval cmd=\"$cmd1\" func_len " $cmd" len=$func_len_result ;; *) try_normal_branch=no ;; esac if test "$try_normal_branch" = yes \ && { test "$len" -lt "$max_cmd_len" \ || test "$max_cmd_len" -le -1; } then func_show_eval "$cmd" 'exit $?' skipped_export=false elif test -n "$nm_file_list_spec"; then func_basename "$output" output_la=$func_basename_result save_libobjs=$libobjs save_output=$output output=${output_objdir}/${output_la}.nm func_to_tool_file "$output" libobjs=$nm_file_list_spec$func_to_tool_file_result func_append delfiles " $output" func_verbose "creating $NM input file list: $output" for obj in $save_libobjs; do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > "$output" eval cmd=\"$cmd1\" func_show_eval "$cmd" 'exit $?' output=$save_output libobjs=$save_libobjs skipped_export=false else # The command line is too long to execute in one step. func_verbose "using reloadable object file for export list..." skipped_export=: # Break out early, otherwise skipped_export may be # set to false by a later but shorter cmd. break fi done IFS="$save_ifs" if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) func_append tmp_deplibs " $test_deplib" ;; esac done deplibs="$tmp_deplibs" if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test "$compiler_needs_object" = yes && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. whole_archive_flag_spec= fi if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $convenience func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" func_append linker_flags " $flag" fi # Make a backup of the uninstalled library when relinking if test "$opt_mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test "X$skipped_export" != "X:" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output func_basename "$output" output_la=$func_basename_result # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= last_robj= k=1 if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then output=${output_objdir}/${output_la}.lnkscript func_verbose "creating GNU ld script: $output" echo 'INPUT (' > $output for obj in $save_libobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done echo ')' >> $output func_append delfiles " $output" func_to_tool_file "$output" output=$func_to_tool_file_result elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then output=${output_objdir}/${output_la}.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test "$compiler_needs_object" = yes; then firstobj="$1 " shift fi for obj do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done func_append delfiles " $output" func_to_tool_file "$output" output=$firstobj\"$file_list_spec$func_to_tool_file_result\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-${k}.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 # Loop over the list of objects to be linked. for obj in $save_libobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result if test "X$objlist" = X || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test "$k" -eq 1 ; then # The first file doesn't have a previous command to add. reload_objs=$objlist eval concat_cmds=\"$reload_cmds\" else # All subsequent reloadable object files will link in # the last one created. reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-${k}.$objext func_arith $k + 1 k=$func_arith_result output=$output_objdir/$output_la-${k}.$objext objlist=" $obj" func_len " $last_robj" func_arith $len0 + $func_len_result len=$func_arith_result fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ reload_objs="$objlist $last_robj" eval concat_cmds=\"\${concat_cmds}$reload_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" fi func_append delfiles " $output" else output= fi if ${skipped_export-false}; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi fi test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs="$IFS"; IFS='~' for cmd in $concat_cmds; do IFS="$save_ifs" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$opt_mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi if ${skipped_export-false}; then if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi fi libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi fi if test -n "$delfiles"; then # Append the command to remove temporary files to $cmds. eval cmds=\"\$cmds~\$RM $delfiles\" fi # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$opt_mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" # Restore the uninstalled library and exit if test "$opt_mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then if test -z "$whole_archive_flag_spec"; then func_show_eval '${RM}r "$gentop"' fi fi exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' fi done # If -module or -export-dynamic was specified, set the dlname. if test "$module" = yes || test "$export_dynamic" = yes; then # On all known operating systems, these are identical. dlname="$soname" fi fi ;; obj) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for objects" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for objects" test -n "$xrpath" && \ func_warning "\`-R' is ignored for objects" test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for objects" test -n "$release" && \ func_warning "\`-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ func_fatal_error "cannot build library object \`$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" obj=$func_lo2o_result ;; *) libobj= obj="$output" ;; esac # Delete the old objects. $opt_dry_run || $RM $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # reload_cmds runs $LD directly, so let us get rid of # -Wl from whole_archive_flag_spec and hope we can get by with # turning comma into space.. wl= if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` else gentop="$output_objdir/${obj}x" func_append generated " $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # If we're not building shared, we need to use non_pic_objs test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" # Create the old-style object. reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test output="$obj" func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS fi if test "$build_libtool_libs" != yes; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS fi if test -n "$pic_flag" || test "$pic_mode" != default; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output="$libobj" func_execute_cmds "$reload_cmds" 'exit $?' fi if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for programs" test -n "$release" && \ func_warning "\`-release' is ignored for programs" test "$preload" = yes \ && test "$dlopen_support" = unknown \ && test "$dlopen_self" = unknown \ && test "$dlopen_self_static" = unknown && \ func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac case $host in *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). if test "$tagname" = CXX ; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) func_append compile_command " ${wl}-bind_at_load" func_append finalize_command " ${wl}-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $compile_deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done compile_deplibs="$new_libs" func_append compile_command " $compile_deplibs" func_append finalize_command " $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; *) func_append dllsearchpath ":$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath="$rpath" rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) func_append finalize_perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath="$rpath" if test -n "$libobjs" && test "$build_old_libs" = yes; then # Transform all the library objects into standard objects. compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" "no" # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=yes case $host in *cegcc* | *mingw32ce*) # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. wrappers_required=no ;; *cygwin* | *mingw* ) if test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; *) if test "$need_relink" = no || test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; esac if test "$wrappers_required" = no; then # Replace the output file specification. compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` link_command="$compile_command$compile_rpath" # We have no uninstalled library dependencies, so finalize right now. exit_status=0 func_show_eval "$link_command" 'exit_status=$?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Delete the generated files. if test -f "$output_objdir/${outputname}S.${objext}"; then func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' fi exit $exit_status fi if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do func_append rpath "$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test "$no_install" = yes; then # We don't need to create a wrapper script. link_command="$compile_var$compile_command$compile_rpath" # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi exit $EXIT_SUCCESS fi if test "$hardcode_action" = relink; then # Fast installation is not supported link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" func_warning "this platform does not like uninstalled shared libraries" func_warning "\`$output' will be relinked during installation" else if test "$fast_install" != no; then link_command="$finalize_var$compile_command$finalize_rpath" if test "$fast_install" = yes; then relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` else # fast_install is set to needless relink_command= fi else link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" fi fi # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output_objdir/$outputname" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Now create the wrapper script. func_verbose "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` fi # Only actually do things if not in dry run mode. $opt_dry_run || { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) func_stripname '' '.exe' "$output" output=$func_stripname_result ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result cwrappersource="$output_path/$objdir/lt-$output_name.c" cwrapper="$output_path/$output_name.exe" $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 func_emit_cwrapperexe_src > $cwrappersource # The wrapper executable is built using the $host compiler, # because it contains $host paths and files. If cross- # compiling, it, like the target executable, must be # executed on the $host or under an emulation environment. $opt_dry_run || { $LTCC $LTCFLAGS -o $cwrapper $cwrappersource $STRIP $cwrapper } # Now, create the wrapper script for func_source use: func_ltwrapper_scriptname $cwrapper $RM $func_ltwrapper_scriptname_result trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host" ; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result fi } ;; * ) $RM $output trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 func_emit_wrapper no > $output chmod +x $output ;; esac } exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do if test "$build_libtool_libs" = convenience; then oldobjs="$libobjs_save $symfileobj" addlibs="$convenience" build_libtool_libs=no else if test "$build_libtool_libs" = module; then oldobjs="$libobjs_save" build_libtool_libs=no else oldobjs="$old_deplibs $non_pic_objects" if test "$preload" = yes && test -f "$symfileobj"; then func_append oldobjs " $symfileobj" fi fi addlibs="$old_convenience" fi if test -n "$addlibs"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $addlibs func_append oldobjs " $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append oldobjs " $func_extract_archives_result" fi # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do func_basename "$obj" $ECHO "$func_basename_result" done | sort | sort -uc >/dev/null 2>&1); then : else echo "copying selected object files to avoid basename conflicts..." gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do func_basename "$obj" objbase="$func_basename_result" case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase func_arith $counter + 1 counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" func_append oldobjs " $gentop/$newobj" ;; *) func_append oldobjs " $obj" ;; esac done fi func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result eval cmds=\"$old_archive_cmds\" func_len " $cmds" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds elif test -n "$archiver_list_spec"; then func_verbose "using command file archive linking..." for obj in $oldobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > $output_objdir/$libname.libcmd func_to_tool_file "$output_objdir/$libname.libcmd" oldobjs=" $archiver_list_spec$func_to_tool_file_result" cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs oldobjs= # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done eval test_cmds=\"$old_archive_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 for obj in $save_oldobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result func_append objlist " $obj" if test "$len" -lt "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj" ; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist if test "X$oldobjs" = "X" ; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi func_execute_cmds "$cmds" 'exit $?' done test -n "$generated" && \ func_show_eval "${RM}r$generated" # Now create the libtool archive. case $output in *.la) old_library= test "$build_old_libs" = yes && old_library="$libname.$libext" func_verbose "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` if test "$hardcode_automatic" = yes ; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do if test "$installed" = yes; then if test -z "$install_libdir"; then break fi output="$output_objdir/$outputname"i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" name="$func_basename_result" func_resolve_sysroot "$deplib" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" ;; -L*) func_stripname -L '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -L$func_replace_sysroot_result" ;; -R*) func_stripname -R '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -R$func_replace_sysroot_result" ;; *) func_append newdependency_libs " $deplib" ;; esac done dependency_libs="$newdependency_libs" newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" ;; *) func_append newdlfiles " $lib" ;; esac done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in *.la) # Only pass preopened files to the pseudo-archive (for # eventual linking with the app. that links it) if we # didn't already link the preopened objects directly into # the library: func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" ;; esac done dlprefiles="$newdlprefiles" else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlfiles " $abs" done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlprefiles " $abs" done dlprefiles="$newdlprefiles" fi $RM $output # place dlname in correct position for cygwin # In fact, it would be nice if we could use this code for all target # systems that can't hard-code library paths into their executables # and that have no shared library path variable independent of PATH, # but it turns out we can't easily determine that from inspecting # libtool variables, so we have to hard-code the OSs to which it # applies here; at the moment, that means platforms that use the PE # object format with DLL files. See the long comment at the top of # tests/bindir.at for full details. tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) # If a -bindir argument was supplied, place the dll there. if test "x$bindir" != x ; then func_relative_path "$install_libdir" "$bindir" tdlname=$func_relative_path_result$dlname else # Otherwise fall back on heuristic. tdlname=../bin/$dlname fi ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Linker flags that can not go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Names of additional weak libraries provided by this library weak_library_names='$weak_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test "$installed" = no && test "$need_relink" = yes; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi done } # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' ;; esac exit $EXIT_SUCCESS } { test "$opt_mode" = link || test "$opt_mode" = relink; } && func_mode_link ${1+"$@"} # func_mode_uninstall arg... func_mode_uninstall () { $opt_debug RM="$nonopt" files= rmforce= exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" for arg do case $arg in -f) func_append RM " $arg"; rmforce=yes ;; -*) func_append RM " $arg" ;; *) func_append files " $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= for file in $files; do func_dirname "$file" "" "." dir="$func_dirname_result" if test "X$dir" = X.; then odir="$objdir" else odir="$dir/$objdir" fi func_basename "$file" name="$func_basename_result" test "$opt_mode" = uninstall && odir="$dir" # Remember odir for removal later, being careful to avoid duplicates if test "$opt_mode" = clean; then case " $rmdirs " in *" $odir "*) ;; *) func_append rmdirs " $odir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if { test -L "$file"; } >/dev/null 2>&1 || { test -h "$file"; } >/dev/null 2>&1 || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif test "$rmforce" = yes; then continue fi rmfiles="$file" case $name in *.la) # Possibly a libtool archive, so verify it. if func_lalib_p "$file"; then func_source $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do func_append rmfiles " $odir/$n" done test -n "$old_library" && func_append rmfiles " $odir/$old_library" case "$opt_mode" in clean) case " $library_names " in *" $dlname "*) ;; *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; esac test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if func_lalib_p "$file"; then # Read the .lo file func_source $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" && test "$pic_object" != none; then func_append rmfiles " $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test "$non_pic_object" != none; then func_append rmfiles " $dir/$non_pic_object" fi fi ;; *) if test "$opt_mode" = clean ; then noexename=$name case $file in *.exe) func_stripname '' '.exe' "$file" file=$func_stripname_result func_stripname '' '.exe' "$name" noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe func_append rmfiles " $file" ;; esac # Do a test to see if this is a libtool program. if func_ltwrapper_p "$file"; then if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result func_append rmfiles " $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename fi # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles func_append rmfiles " $odir/$name $odir/${name}S.${objext}" if test "$fast_install" = yes && test -n "$relink_command"; then func_append rmfiles " $odir/lt-$name" fi if test "X$noexename" != "X$name" ; then func_append rmfiles " $odir/lt-${noexename}.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done # Try to remove the ${objdir}s in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" fi done exit $exit_status } { test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && func_mode_uninstall ${1+"$@"} test -z "$opt_mode" && { help="$generic_help" func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode \`$opt_mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" exit $EXIT_FAILURE fi exit $exit_status # The TAGs below are defined such that we never get into a situation # in which we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: # vi:sw=2 snort-2.9.15.1/snort.80000444000175200017520000007447513571422607011325 00000000000000.\" Process this file with .\" groff -man -Tascii snort.8 .\" .\" $Id$ .TH SNORT 8 "December 2011" .SH NAME Snort \- open source network intrusion detection system .SH SYNOPSIS .B snort [-bCdDeEfHIMNOpqQsTUvVwWxXy?] [-A .I alert-mode .B ] [-B .I address-conversion-mask .B ] [-c .I rules-file .B ] [-F .I bpf-file .B ] [-g .I group-name .B ] [-G .I id .B ] [-h .I home-net .B ] [-i .I interface .B ] [-k .I checksum-mode .B ] [-K .I logging-mode .B ] [-l .I log-dir .B ] [-L .I bin-log-file .B ] [-m .I umask .B ] [-n .I packet-count .B ] [-P .I snap-length .B ] [-r .I tcpdump-file .B ] [-R .I name .B ] [-S .I variable=value .B ] [-t .I chroot_directory .B ] [-u .I user-name .B ] [-Z .I pathname .B ] [--logid .I id .B ] [--perfmon-file .I pathname .B ] [--pid-path .I pathname .B ] [--snaplen .I snap-length .B ] [--help .B ] [--version .B ] [--dynamic-engine-lib .I file .B ] [--dynamic-engine-lib-dir .I directory .B ] [--dynamic-detection-lib .I file .B ] [--dynamic-detection-lib-dir .I directory .B ] [--dump-dynamic-rules .I directory .B ] [--dynamic-preprocessor-lib .I file .B ] [--dynamic-preprocessor-lib-dir .I directory .B ] [--dynamic-output-lib .I file .B ] [--dynamic-output-lib-dir .I directory .B ] [--alert-before-pass .B ] [--treat-drop-as-alert .B ] [--treat-drop-as-ignore .B ] [--process-all-events .B ] [--enable-inline-test .B ] [--create-pidfile .B ] [--nolock-pidfile .B ] [--no-interface-pidfile .B ] [--disable-attribute-reload-thread .B ] [--pcap-single= .I tcpdump-file .B ] [--pcap-filter= .I filter .B ] [--pcap-list= .I list .B ] [--pcap-dir= .I directory .B ] [--pcap-file= .I file .B ] [--pcap-no-filter .B ] [--pcap-reset .B ] [--pcap-reload .B ] [--pcap-show .B ] [--exit-check .I count .B ] [--conf-error-out .B ] [--enable-mpls-multicast .B ] [--enable-mpls-overlapping-ip .B ] [--max-mpls-labelchain-len .B ] [--mpls-payload-type .B ] [--require-rule-sid .B ] [--daq .I type .B ] [--daq-mode .I mode .B ] [--daq-var .I name=value .B ] [--daq-dir .I dir .B ] [--daq-list .I [dir] .B ] [--dirty-pig .B ] [--cs-dir .I dir .B ] [--ha-peer .B ] [--ha-out .I file .B ] [--ha-in .I file .B ] .I expression .SH DESCRIPTION .B Snort is an open source network intrusion detection system, capable of performing real-time traffic analysis and packet logging on IP networks. It can perform protocol analysis, content searching/matching and can be used to detect a variety of attacks and probes, such as buffer overflows, stealth port scans, CGI attacks, SMB probes, OS fingerprinting attempts, and much more. Snort uses a flexible rules language to describe traffic that it should collect or pass, as well as a detection engine that utilizes a modular plugin architecture. Snort also has a modular real-time alerting capability, incorporating alerting and logging plugins for syslog, a ASCII text files, UNIX sockets or XML. .PP Snort has three primary uses. It can be used as a straight packet sniffer like .BR tcpdump (1), a packet logger (useful for network traffic debugging, etc), or as a full blown network intrusion detection system. .PP Snort logs packets in .BR tcpdump (1) binary format or in Snort's decoded ASCII format to a hierarchy of logging directories that are named based on the IP address of the "foreign" host. .SH OPTIONS .IP "-A alert-mode" Alert using the specified .I alert-mode. Valid alert modes include .B fast, full, none, and .B unsock. .B Fast writes alerts to the default "alert" file in a single-line, syslog style alert message. .B Full writes the alert to the "alert" file with the full decoded header as well as the alert message. .B None turns off alerting. .B Unsock is an experimental mode that sends the alert information out over a UNIX socket to another process that attaches to that socket. .IP -b Log packets in a .BR tcpdump (1) formatted file. All packets are logged in their native binary state to a tcpdump formatted log file named with the snort start timestamp and "snort.log". This option results in much faster operation of the program since it doesn't have to spend time in the packet binary->text converters. Snort can keep up pretty well with 100Mbps networks in '-b' mode. To choose an alternate name for the binary log file, use the '-L' switch. .IP "-B address-conversion-mask" Convert all IP addresses in .I home-net to addresses specified by .I address-conversion-mask. Used to obfuscate IP addresses within binary logs. Specify .I home-net with the '-h' switch. Note this is .B not the same as $HOME_NET. .IP "-c config-file" Use the rules located in file .I config-file. .IP -C Print the character data from the packet payload only (no hex). .IP -d Dump the application layer data when displaying packets in verbose or packet logging mode. .IP -D Run Snort in daemon mode. Alerts are sent to /var/log/snort/alert unless otherwise specified. .IP -e Display/log the link layer packet headers. .IP -E .B *WIN32 ONLY* Log alerts to the Windows Event Log. .IP -f Activate PCAP line buffering .IP "-F bpf-file" Read BPF filters from .I bpf-file. This is handy for people running Snort as a SHADOW replacement or with a love Of super complex BPF filters. See the "expressions" section of this man page for more info on writing BPF filters. .IP "-g group" Change the group/GID Snort runs under to .I group after initialization. This switch allows Snort to drop root privileges after it's initialization phase has completed as a security measure. .IP "-G id" Use id as a base event ID when logging events. .IP "-h home-net" Set the "home network" to .I home-net. The format of this address variable is a network prefix plus a CIDR block, such as 192.168.1.0/24. Once this variable is set, all decoded packet logging will be done relative to the home network address space. This is useful because of the way that Snort formats its ASCII log data. With this value set to the local network, all decoded output will be logged into decode directories with the address of the foreign computer as the directory name, which is very useful during traffic analysis. This option does not change "$HOME_NET" in IDS mode. .IP "-H" Force hash tables to be deterministic instead of using a random number generator for the seed & scale. Useful for testing and generating repeatable results with the same traffic. .IP "-i interface" Sniff packets on .I interface. .IP "-I" Print out the receiving interface name in alerts. .IP "-k checksum-mode" Tune the internal checksum verification functionality with .I alert-mode. Valid checksum modes include .B all, noip, notcp, noudp, noicmp, and .B none. .B All activates checksum verification for all supported protocols. .B Noip turns off IP checksum verification, which is handy if the gateway router is already dropping packets that fail their IP checksum checks. .B Notcp turns off TCP checksum verification, all other checksum modes are .B on. .B noudp turns off UDP checksum verification. .B Noicmp turns off ICMP checksum verification. .B None turns off the entire checksum verification subsystem. .IP "-K logging-mode" Select a packet logging mode. The default is pcap. .I logging-mode. Valid logging modes include .B pcap, ascii, and .B none. .B Pcap logs packets through the pcap library into pcap (tcpdump) format. .B Ascii logs packets in the old "directories and files" format with packet printouts in each file. .B None Turns off packet logging. .IP "-l log-dir" Set the output logging directory to .I log-dir. All plain text alerts and packet logs go into this directory. If this option is not specified, the default logging directory is set to /var/log/snort. .IP "-L binary-log-file" Set the filename of the binary log file to .I binary-log-file. If this switch is not used, the default name is a timestamp for the time that the file is created plus "snort.log". .IP "-m umask" Set the file mode creation mask to .I umask .IP "-M" Log console messages to syslog when not running daemon mode. Using both -D and -M will send all messages to syslog including e.g. SIGUSR1 dump packet stats. This switch has no impact on logging of alerts. .IP "-n packet-count" Process .I packet-count packets and exit. .IP -N Turn off packet logging. The program still generates alerts normally. .IP -O Obfuscate the IP addresses when in ASCII packet dump mode. This switch changes the IP addresses that get printed to the screen/log file to "xxx.xxx.xxx.xxx". If the homenet address switch is set (-h), only addresses on the homenet will be obfuscated while non- homenet IPs will be left visible. Perfect for posting to your favorite security mailing list! .IP -p Turn off promiscuous mode sniffing. .IP "-P snap-length" Set the packet snaplen to .I snap-length. By default, this is set to 1514. .IP "-q" Quiet operation. Don't display banner and initialization information. In daemon mode, banner and initialization information is not logged to syslog. .IP "-Q" Enable inline mode operation. .IP "-r tcpdump-file" Read the tcpdump-formatted file .I tcpdump-file. This will cause Snort to read and process the file fed to it. This is useful if, for instance, you've got a bunch of SHADOW files that you want to process for content, or even if you've got a bunch of reassembled packet fragments which have been written into a tcpdump formatted file. .IP "-R name" Use name as a suffix to the snort pidfile. .IP -s Send alert messages to syslog. On linux boxen, they will appear in /var/log/secure, /var/log/messages on many other platforms. .IP "-S variable=value" Set variable name "variable" to value "value". This is useful for setting the value of a defined variable name in a Snort rules file to a command line specified value. For instance, if you define a HOME_NET variable name inside of a Snort rules file, you can set this value from it's predefined value at the command line. .IP "-t chroot" Changes Snort's root directory to .I chroot after initialization. Please note that all log/alert filenames are relative to the chroot directory if chroot is used. .IP -T Snort will start up in self-test mode, checking all the supplied command line switches and rules files that are handed to it and indicating that everything is ready to proceed. This is a good switch to use if daemon mode is going to be used, it verifies that the Snort configuration that is about to be used is valid and won't fail at run time. Note, Snort looks for either /etc/snort.conf or ./snort.conf. If your config lives elsewhere, use the -c option to specify a valid .I config-file. .IP "-u user" Change the user/UID Snort runs under to .I user after initialization. .IP -U Changes the timestamp in all logs to be in UTC .IP -v Be verbose. Prints packets out to the console. There is one big problem with verbose mode: it's slow. If you are doing IDS work with Snort, .B don't use the '-v' switch, you .B WILL drop packets. .IP -V Show the version number and exit. .IP "-w" Show management frames if running on an 802.11 (wireless) network. .IP "-W" .B *WIN32 ONLY* Enumerate the network interfaces available. .IP "-x" Exit if Snort configuration problems occur such as duplicate gid/sid or flowbits without Stream5. .IP "-X" Dump the raw packet data starting at the link layer. This switch overrides the '-d' switch. .IP "-y" Include the year in alert and log files .IP "-Z pathname" Set the perfmonitor preprocessor path/filename to pathname. .IP -? Show the program usage statement and exit. .IP "--logid id" Same as -G. .IP "--perfmon-file pathname" Same as -Z. .IP "--pid-path directory" Specify the directory for the Snort PID file. .IP "--snaplen snap-length" Same as -P. .IP "--help" Same as -? .IP "--version" Same as -V .IP "--dynamic-engine-lib file" Load a dynamic detection engine shared library specified by file. .IP "--dynamic-engine-lib-dir directory" Load all dynamic detection engine shared libraries specified from directory. .IP "--dynamic-detection-lib file" Load a dynamic detection rules shared library specified by file. .IP "--dynamic-detection-lib-dir directory" Load all dynamic detection rules shared libraries specified from directory. .IP "--dump-dynamic-rules directory" Create stub rule files from all loaded dynamic detection rules libraries. Files will be created in directory. This is required to be done prior to running snort using those detection rules and the generated rules files must be included in snort.conf. .IP "--dynamic-preprocessor-lib file" Load a dynamic preprocessor shared library specified by file. .IP "--dynamic-preprocessor-lib-dir directory" Load all dynamic preprocessor shared libraries specified from directory. .IP "--alert-before-pass" Process alert, drop, sdrop, or reject before pass. Default is pass before alert, drop, etc. .IP "--treat-drop-as-alert" Converts drop, sdrop, and reject rules into alert rules during startup. .IP "--treat-drop-as-ignore" Use drop, sdrop, and reject rules to ignore session traffic when not inline. .IP "--process-all-events" Process all triggered events in group order, per Rule Ordering configuration. Default stops after first group. .IP "--enable-inline-test" Enable Inline-Test Mode Operation. .IP "--pid-path directory" Specify the path for Snort's PID file. .IP "--create-pidfile" Create PID file, even when not in Daemon mode. .IP "--nolock-pidfile" Do not try to lock Snort PID file. .IP "--no-interface-pidfile" Do not include the interface name in Snort PID file .IP "--pcap-single=\fItcpdump-file\fP" Same as -r. Added for completeness. .IP "--pcap-filter=\fIfilter\fP" Shell style filter to apply when getting pcaps from file or directory. This filter will apply to any --pcap-file or --pcap-dir arguments following. Use --pcap-no-filter to delete filter for following --pcap-file or --pcap-dir arguments or specify --pcap-filter again to forget previous filter and to apply to following --pcap-file or --pcap-dir arguments. .IP "--pcap-list=\fI""list""\fP" A space separated list of pcaps to read. .IP "--pcap-dir=\fIdirectory\fP" A directory to recurse to look for pcaps. Sorted in ascii order. .IP "--pcap-file=\fIfile\fP" File that contains a list of pcaps to read. Can specify path to pcap or directory to recurse to get pcaps. .IP "--pcap-no-filter" Reset to use no filter when getting pcaps from file or directory. .IP "--pcap-reset" If reading multiple pcaps, reset snort to post-configuration state before reading next pcap. The default, i.e. without this option, is not to reset state. .IP "--pcap-show" Print a line saying what pcap is currently being read. .IP "--exit-check=\fIcount\fP" Signal termination after callbacks from DAQ_Acquire(), showing the time it takes from signaling until DAQ_Stop() is called. .IP "--conf-error-out" Same as -x. .IP "--require-rule-sid" Require an SID for every rule to be correctly threshold all rules. .IP "--daq " Select packet acquisition module (default is pcap). .IP "--daq-mode " Select the DAQ operating mode. .IP "--daq-var " Specify extra DAQ configuration variable. .IP "--daq-dir " Tell Snort where to find desired DAQ. .IP "--daq-list []" List packet acquisition modules available in dir. .IP "--cs-dir " Tell Snort to use control socket and create the socket in dir. .IP "\fI expression\fP" .RS selects which packets will be dumped. If no \fIexpression\fP is given, all packets on the net will be dumped. Otherwise, only packets for which \fIexpression\fP is `true' will be dumped. .LP The \fIexpression\fP consists of one or more .I primitives. Primitives usually consist of an .I id (name or number) preceded by one or more qualifiers. There are three different kinds of qualifier: .IP \fItype\fP qualifiers say what kind of thing the id name or number refers to. Possible types are .BR host , .B net and .BR port . E.g., `host foo', `net 128.3', `port 20'. If there is no type qualifier, .B host is assumed. .IP \fIdir\fP qualifiers specify a particular transfer direction to and/or from .I id. Possible directions are .BR src , .BR dst , .B "src or dst" and .B "src and" .BR dst . E.g., `src foo', `dst net 128.3', `src or dst port ftp-data'. If there is no dir qualifier, .B "src or dst" is assumed. For `null' link layers (i.e. point to point protocols such as slip) the .B inbound and .B outbound qualifiers can be used to specify a desired direction. .IP \fIproto\fP qualifiers restrict the match to a particular protocol. Possible protos are: .BR ether , .BR fddi , .BR ip , .BR arp , .BR rarp , .BR decnet , .BR lat , .BR sca , .BR moprc , .BR mopdl , .B tcp and .BR udp . E.g., `ether src foo', `arp net 128.3', `tcp port 21'. If there is no proto qualifier, all protocols consistent with the type are assumed. E.g., `src foo' means `(ip or arp or rarp) src foo' (except the latter is not legal syntax), `net bar' means `(ip or arp or rarp) net bar' and `port 53' means `(tcp or udp) port 53'. .LP [`fddi' is actually an alias for `ether'; the parser treats them identically as meaning ``the data link level used on the specified network interface.'' FDDI headers contain Ethernet-like source and destination addresses, and often contain Ethernet-like packet types, so you can filter on these FDDI fields just as with the analogous Ethernet fields. FDDI headers also contain other fields, but you cannot name them explicitly in a filter expression.] .LP In addition to the above, there are some special `primitive' keywords that don't follow the pattern: .BR gateway , .BR broadcast , .BR less , .B greater and arithmetic expressions. All of these are described below. .LP More complex filter expressions are built up by using the words .BR and , .B or and .B not to combine primitives. E.g., `host foo and not port ftp and not port ftp-data'. To save typing, identical qualifier lists can be omitted. E.g., `tcp dst port ftp or ftp-data or domain' is exactly the same as `tcp dst port ftp or tcp dst port ftp-data or tcp dst port domain'. .LP Allowable primitives are: .IP "\fBdst host \fIhost\fR" True if the IP destination field of the packet is \fIhost\fP, which may be either an address or a name. .IP "\fBsrc host \fIhost\fR" True if the IP source field of the packet is \fIhost\fP. .IP "\fBhost \fIhost\fP" True if either the IP source or destination of the packet is \fIhost\fP. Any of the above host expressions can be prepended with the keywords, \fBip\fP, \fBarp\fP, or \fBrarp\fP as in: .in +.5i .nf \fBip host \fIhost\fR .fi .in -.5i which is equivalent to: .in +.5i .nf \fBether proto \fI\\ip\fB and host \fIhost\fR .fi .in -.5i If \fIhost\fR is a name with multiple IP addresses, each address will be checked for a match. .IP "\fBether dst \fIehost\fP" True if the ethernet destination address is \fIehost\fP. \fIEhost\fP may be either a name from /etc/ethers or a number (see .IR ethers (3N) for numeric format). .IP "\fBether src \fIehost\fP" True if the ethernet source address is \fIehost\fP. .IP "\fBether host \fIehost\fP" True if either the ethernet source or destination address is \fIehost\fP. .IP "\fBgateway\fP \fIhost\fP" True if the packet used \fIhost\fP as a gateway. I.e., the ethernet source or destination address was \fIhost\fP but neither the IP source nor the IP destination was \fIhost\fP. \fIHost\fP must be a name and must be found in both /etc/hosts and /etc/ethers. (An equivalent expression is .in +.5i .nf \fBether host \fIehost \fBand not host \fIhost\fR .fi .in -.5i which can be used with either names or numbers for \fIhost / ehost\fP.) .IP "\fBdst net \fInet\fR" True if the IP destination address of the packet has a network number of \fInet\fP. \fINet\fP may be either a name from /etc/networks or a network number (see \fInetworks(4)\fP for details). .IP "\fBsrc net \fInet\fR" True if the IP source address of the packet has a network number of \fInet\fP. .IP "\fBnet \fInet\fR" True if either the IP source or destination address of the packet has a network number of \fInet\fP. .IP "\fBnet \fInet\fR \fBmask \fImask\fR" True if the IP address matches \fInet\fR with the specific netmask. May be qualified with \fBsrc\fR or \fBdst\fR. .IP "\fBnet \fInet\fR/\fIlen\fR" True if the IP address matches \fInet\fR a netmask \fIlen\fR bits wide. May be qualified with \fBsrc\fR or \fBdst\fR. .IP "\fBdst port \fIport\fR" True if the packet is ip/tcp or ip/udp and has a destination port value of \fIport\fP. The \fIport\fP can be a number or a name used in /etc/services (see .IR tcp (4P) and .IR udp (4P)). If a name is used, both the port number and protocol are checked. If a number or ambiguous name is used, only the port number is checked (e.g., \fBdst port 513\fR will print both tcp/login traffic and udp/who traffic, and \fBport domain\fR will print both tcp/domain and udp/domain traffic). .IP "\fBsrc port \fIport\fR" True if the packet has a source port value of \fIport\fP. .IP "\fBport \fIport\fR" True if either the source or destination port of the packet is \fIport\fP. Any of the above port expressions can be prepended with the keywords, \fBtcp\fP or \fBudp\fP, as in: .in +.5i .nf \fBtcp src port \fIport\fR .fi .in -.5i which matches only tcp packets whose source port is \fIport\fP. .IP "\fBless \fIlength\fR" True if the packet has a length less than or equal to \fIlength\fP. This is equivalent to: .in +.5i .nf \fBlen <= \fIlength\fP. .fi .in -.5i .IP "\fBgreater \fIlength\fR" True if the packet has a length greater than or equal to \fIlength\fP. This is equivalent to: .in +.5i .nf \fBlen >= \fIlength\fP. .fi .in -.5i .IP "\fBip proto \fIprotocol\fR" True if the packet is an ip packet (see .IR ip (4P)) of protocol type \fIprotocol\fP. \fIProtocol\fP can be a number or one of the names \fIicmp\fP, \fIigrp\fP, \fIudp\fP, \fInd\fP, or \fItcp\fP. Note that the identifiers \fItcp\fP, \fIudp\fP, and \fIicmp\fP are also keywords and must be escaped via backslash (\\), which is \\\\ in the C-shell. .IP "\fBether broadcast\fR" True if the packet is an ethernet broadcast packet. The \fIether\fP keyword is optional. .IP "\fBip broadcast\fR" True if the packet is an IP broadcast packet. It checks for both the all-zeroes and all-ones broadcast conventions, and looks up the local subnet mask. .IP "\fBether multicast\fR" True if the packet is an ethernet multicast packet. The \fIether\fP keyword is optional. This is shorthand for `\fBether[0] & 1 != 0\fP'. .IP "\fBip multicast\fR" True if the packet is an IP multicast packet. .IP "\fBether proto \fIprotocol\fR" True if the packet is of ether type \fIprotocol\fR. \fIProtocol\fP can be a number or a name like \fIip\fP, \fIarp\fP, or \fIrarp\fP. Note these identifiers are also keywords and must be escaped via backslash (\\). [In the case of FDDI (e.g., `\fBfddi protocol arp\fR'), the protocol identification comes from the 802.2 Logical Link Control (LLC) header, which is usually layered on top of the FDDI header. \fITcpdump\fP assumes, when filtering on the protocol identifier, that all FDDI packets include an LLC header, and that the LLC header is in so-called SNAP format.] .IP "\fBdecnet src \fIhost\fR" True if the DECNET source address is .IR host , which may be an address of the form ``10.123'', or a DECNET host name. [DECNET host name support is only available on Ultrix systems that are configured to run DECNET.] .IP "\fBdecnet dst \fIhost\fR" True if the DECNET destination address is .IR host . .IP "\fBdecnet host \fIhost\fR" True if either the DECNET source or destination address is .IR host . .IP "\fBip\fR, \fBarp\fR, \fBrarp\fR, \fBdecnet\fR" Abbreviations for: .in +.5i .nf \fBether proto \fIp\fR .fi .in -.5i where \fIp\fR is one of the above protocols. .IP "\fBlat\fR, \fBmoprc\fR, \fBmopdl\fR" Abbreviations for: .in +.5i .nf \fBether proto \fIp\fR .fi .in -.5i where \fIp\fR is one of the above protocols. Note that \fISnort\fP does not currently know how to parse these protocols. .IP "\fBtcp\fR, \fBudp\fR, \fBicmp\fR" Abbreviations for: .in +.5i .nf \fBip proto \fIp\fR .fi .in -.5i where \fIp\fR is one of the above protocols. .IP "\fIexpr relop expr\fR" True if the relation holds, where \fIrelop\fR is one of >, <, >=, <=, =, !=, and \fIexpr\fR is an arithmetic expression composed of integer constants (expressed in standard C syntax), the normal binary operators [+, -, *, /, &, |], a length operator, and special packet data accessors. To access data inside the packet, use the following syntax: .in +.5i .nf \fIproto\fB [ \fIexpr\fB : \fIsize\fB ]\fR .fi .in -.5i \fIProto\fR is one of \fBether, fddi, ip, arp, rarp, tcp, udp, \fRor \fBicmp\fR, and indicates the protocol layer for the index operation. The byte offset, relative to the indicated protocol layer, is given by \fIexpr\fR. \fISize\fR is optional and indicates the number of bytes in the field of interest; it can be either one, two, or four, and defaults to one. The length operator, indicated by the keyword \fBlen\fP, gives the length of the packet. For example, `\fBether[0] & 1 != 0\fP' catches all multicast traffic. The expression `\fBip[0] & 0xf != 5\fP' catches all IP packets with options. The expression `\fBip[6:2] & 0x1fff = 0\fP' catches only unfragmented datagrams and frag zero of fragmented datagrams. This check is implicitly applied to the \fBtcp\fP and \fBudp\fP index operations. For instance, \fBtcp[0]\fP always means the first byte of the TCP \fIheader\fP, and never means the first byte of an intervening fragment. .LP Primitives may be combined using: .IP A parenthesized group of primitives and operators (parentheses are special to the Shell and must be escaped). .IP Negation (`\fB!\fP' or `\fBnot\fP'). .IP Concatenation (`\fB&&\fP' or `\fBand\fP'). .IP Alternation (`\fB||\fP' or `\fBor\fP'). .LP Negation has highest precedence. Alternation and concatenation have equal precedence and associate left to right. Note that explicit \fBand\fR tokens, not juxtaposition, are now required for concatenation. .LP If an identifier is given without a keyword, the most recent keyword is assumed. For example, .in +.5i .nf \fBnot host vs and ace\fR .fi .in -.5i is short for .in +.5i .nf \fBnot host vs and host ace\fR .fi .in -.5i which should not be confused with .in +.5i .nf \fBnot ( host vs or ace )\fR .fi .in -.5i .LP Expression arguments can be passed to Snort as either a single argument or as multiple arguments, whichever is more convenient. Generally, if the expression contains Shell metacharacters, it is easier to pass it as a single, quoted argument. Multiple arguments are concatenated with spaces before being parsed. .SH READING PCAPS Instead of having Snort listen on an interface, you can give it a packet capture to read. Snort will read and analyze the packets as if they came off the wire. This can be useful for testing and debugging Snort. \fBRead a single pcap\fR .RS 5 .PD 0 $ snort -r foo.pcap .PP $ snort --pcap-single=foo.pcap .RE 0 \fBRead pcaps from a file\fR .RS 5 $ cat foo.txt .PP foo1.pcap .PP foo2.pcap .PP /home/foo/pcaps $ snort --pcap-file=foo.txt This will read foo1.pcap, foo2.pcap and all files under /home/foo/pcaps. Note that Snort will not try to determine whether the files under that directory are really pcap files or not. .RE 0 \fBRead pcaps from a command line list\fR .RS 5 $ snort --pcap-list="foo1.pcap foo2.pcap foo3.pcap" This will read foo1.pcap, foo2.pcap and foo3.pcap. .RE 0 \fBRead pcaps under a directory\fR .RS 5 $ snort --pcap-dir="/home/foo/pcaps" This will include all of the files under /home/foo/pcaps. .RE 0 \fBUsing filters\fR .RS 5 $ cat foo.txt .PP foo1.pcap .PP foo2.pcap .PP /home/foo/pcaps $ snort --pcap-filter="*.pcap" --pcap-file=foo.txt .PP $ snort --pcap-filter="*.pcap" --pcap-dir=/home/foo/pcaps The above will only include files that match the shell pattern "*.pcap", in other words, any file ending in ".pcap". $ snort --pcap-filter="*.pcap --pcap-file=foo.txt \\ .PP > --pcap-filter="*.cap" --pcap-dir=/home/foo/pcaps In the above, the first filter "*.pcap" will only be applied to the pcaps in the file "foo.txt" (and any directories that are recursed in that file). The addition of the second filter "*.cap" will cause the first filter to be forgotten and then applied to the directory /home/foo/pcaps, so only files ending in ".cap" will be included from that directory. $ snort --pcap-filter="*.pcap --pcap-file=foo.txt \\ .PP > --pcap-no-filter --pcap-dir=/home/foo/pcaps In this example, the first filter will be applied to foo.txt, then no filter will be applied to the files found under /home/foo/pcaps, so all files found under /home/foo/pcaps will be included. $ snort --pcap-filter="*.pcap --pcap-file=foo.txt \\ .PP > --pcap-no-filter --pcap-dir=/home/foo/pcaps \\ .PP > --pcap-filter="*.cap" --pcap-dir=/home/foo/pcaps2 In this example, the first filter will be applied to foo.txt, then no filter will be applied to the files found under /home/foo/pcaps, so all files found under /home/foo/pcaps will be included, then the filter "*.cap" will be applied to files found under /home/foo/pcaps2. .RE 0 \fBResetting state\fR .RS 5 $ snort --pcap-dir=/home/foo/pcaps --pcap-reset The above example will read all of the files under /home/foo/pcaps, but after each pcap is read, Snort will be reset to a post-configuration state, meaning all buffers will be flushed, statistics reset, etc. For each pcap, it will be like Snort is seeing traffic for the first time. .RE 0 \fBPrinting the pcap\fR .RS 5 $ snort --pcap-dir=/home/foo/pcaps --pcap-show The above example will read all of the files under /home/foo/pcaps and will print a line indicating which pcap is currently being read. .RE 0 .PD .SH RULES Snort uses a simple but flexible rules language to describe network packet signatures and associate them with actions. The current rules document can be found at http://www.snort.org/snort-rules. .SH NOTES The following signals have the specified effect when sent to the daemon process using the \fBkill(1)\fR command: .PP .IP SIGHUP Causes the daemon to close all opened files and restart. Please \fBnote\fR that this will only work if the \fBfull\fR pathname is used to invoke snort in daemon mode, otherwise snort will just exit with an error message being sent to \fBsyslogd(8)\fR. .PP .IP SIGUSR1 Causes the program to dump its current packet statistical information to the console or \fBsyslogd(8)\fR if in daemon mode. .PP .IP SIGUSR2 Causes the program to rotate Perfmonitor statistical information to the console or \fBsyslogd(8)\fR if in daemon mode. .PP .IP SIGURG Causes the program to reload attribute table. .PP .IP SIGCHLD Used internally. .PP Please refer to manual for more details. Any other signal might cause the daemon to close all opened files and exit. .SH HISTORY .B Snort has been freely available under the GPL license since 1998. .SH DIAGNOSTICS .B Snort returns a 0 on a successful exit, 1 if it exits on an error. .SH BUGS After consulting the BUGS file included with the source distribution, send bug reports to snort-devel@lists.snort.org .SH AUTHOR Martin Roesch .SH "SEE ALSO" .BR tcpdump (1), .BR pcap (3) snort-2.9.15.1/LICENSE0000444000175200017520000005103113571422606011052 00000000000000***************************************************************************** The text that follows is the GNU General Public License, Version 2 (GPL V2) and governs your use, modification and/or distribution of SNORT. Section 9 of the GPL V2 acknowledges that the Free Software Foundation may publish revised and/or new versions of the GPL V2 from time to time. Section 9 further states that a licensee of a program subject to the GPL V2 could be free to use any such revised and/or new versions under two different scenarios: 1. "Failure to Specify." Section 9 of the GPL V2 allows a licensee of a program governed by an unspecified version of the General Public License to choose any version of the General Public License ever published by the Free Software Foundation to govern his or her use of such program. This provision is not applicable to your use of SNORT because we have expressly stated in a number of instances that any third party's use, modification or distribution of SNORT is governed by GPL V2. 2. "Any Later Version." At the end of the terms and condition of the GPL V2 is a section called "How to Apply these Terms to Your New Program," which provides guidance to a developer on how to apply the GPL V2 to a third party's use, modification and/or distribution of his/her program. Among other things, this guidance suggests that the developer attach certain notices to the program. Of particular importance is the following notice: "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." Thus if a developer follows strictly the guidance provided by the Free Software Foundation, Section 9 of the GPL V2 provides the licensee the option to either use, modify or distribute the program under GPL V2 or under any later version published by the Free Software Foundation. SNORT is an open source project that is governed exclusively by the GPL V2 and any third party desiring to use, modify or distribute SNORT must do so by strictly following the terms and conditions of GPL V2. Anyone using, modifying or distributing SNORT does not have the option to chose to use, modify or distribute SNORT under any revised or new version of the GPL, including without limitation, the GNU General Public License Version 3. For ease of reference, the comparable notice that is used with SNORT (contained in the 'README' file) is as follows: "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." If you have any questions about this statement, please feel free to email snort-info@snort.org. ***************************************************************************** GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. snort-2.9.15.1/verstuff.pl0000555000175200017520000000335213571422610012247 00000000000000#!/usr/bin/perl -w # $Id$ # Author: Chris Green # Purpose: make sure snort versions stay in sync # Created: Tue Jul 22 17:21:42 EDT 2003 use strict; my $version = "Unknown!"; if($#ARGV < 0) { die "bad args found!\n"; } my $prefix = $ARGV[0]; open(CONFIGURE,"$prefix/configure.in") or die "Can't open configure.in!\n"; while() { if($_ =~ m/^AM_INIT_AUTOMAKE\(snort,/) { chomp; $version = $_; $version =~ s/^AM_INIT_AUTOMAKE\(snort,([^\)]+)\)/$1/; last; } } close(CONFIGURE); # print "version is $version!\n"; open(WIN32CONFIG, "$prefix/src/win32/WIN32-Includes/config.h"); open(WIN32CONFIGNEW, ">$prefix/src/win32/WIN32-Includes/config.h.new"); while() { if($_ =~ m/^\#define VERSION "[^"]+"/) { $_ =~ s/^(\#define VERSION ")[^"]+(.*$)/${1}${version}${2}/; } print WIN32CONFIGNEW $_; } system("mv -f ${prefix}/src/win32/WIN32-Includes/config.h.new ${prefix}/src/win32/WIN32-Includes/config.h"); open(MANUAL, "<$prefix/doc/snort_manual.tex"); open(MANUALNEW, ">$prefix/doc/snort_manual.tex.new"); while() { s/(Snort\\texttrademark Users Manual\\\\ ).*?(\})/$1 $version $2/; print MANUALNEW $_; } system("mv -f $prefix/doc/snort_manual.tex.new $prefix/doc/snort_manual.tex"); open(MANUAL, "<$prefix/rpm/snort.spec"); open(MANUALNEW, ">$prefix/rpm/snort.spec.new"); while() { s/^Version: .*$/Version: $version/; print MANUALNEW $_; } system("mv -f $prefix/rpm/snort.spec.new $prefix/rpm/snort.spec"); open (CONF, "<$prefix/etc/snort.conf"); open (CONFNEW,">$prefix/etc/snort.conf.new"); while () { s/Snort .* Ruleset/Snort $version Ruleset/; print CONFNEW $_; } system("mv -f $prefix/etc/snort.conf.new $prefix/etc/snort.conf"); snort-2.9.15.1/RELEASE.NOTES0000444000175200017520000000033613571422606011741 000000000000002019-12-15 - Snort 2.9.15.1 [*] New Additions * Added support for glibc version 2.30. [*] Improvements / Fix * Fixed snort core seen during ssl re-configuration. * Fixed file access issues on files from SMB share. snort-2.9.15.1/VERSION0000444000175200017520000000001113571422606011105 000000000000002.9.15.1 snort-2.9.15.1/src/0000755000000000000000000000000013571426525010664 500000000000000snort-2.9.15.1/src/Makefile.in0000644000000000000000000006603613571425502012656 00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 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@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd 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@ bin_PROGRAMS = snort$(EXEEXT) @BUILD_CONTROL_SOCKET_TRUE@am__append_1 = dump.c dump.h @BUILD_SIDE_CHANNEL_TRUE@am__append_2 = \ @BUILD_SIDE_CHANNEL_TRUE@side-channel/libsidechannel.a \ @BUILD_SIDE_CHANNEL_TRUE@side-channel/plugins/libsscm.a @BUILD_SIDE_CHANNEL_TRUE@am__append_3 = side-channel @BUILD_SNORT_RELOAD_TRUE@am__append_4 = reload-adjust/libreload_adjust.a @BUILD_SNORT_RELOAD_TRUE@am__append_5 = reload-adjust subdir = src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am__snort_SOURCES_DIST = cdefs.h event.h generators.h sf_protocols.h \ plugin_enum.h rules.h treenodes.h checksum.h debug.c \ snort_debug.h decode.c decode.h encode.c encode.h active.c \ active.h log.c log.h mstring.c mstring.h hashstring.c \ hashstring.h parser.c parser.h profiler.c profiler.h \ plugbase.c plugbase.h preprocids.h snort.c snort.h build.h \ snprintf.c snprintf.h strlcatu.c strlcatu.h strlcpyu.c \ strlcpyu.h tag.c tag.h util.c util.h detect.c detect.h \ signature.c signature.h mempool.c mempool.h sf_sdlist.c \ sf_sdlist.h sf_sdlist_types.h fpcreate.c fpcreate.h fpdetect.c \ fpdetect.h pcrm.c pcrm.h snort_bounds.h byte_extract.c \ byte_extract.h timersub.h spo_plugbase.h sfthreshold.c \ sfthreshold.h packet_time.c packet_time.h event_wrapper.c \ event_wrapper.h event_queue.c event_queue.h ipv6_port.h ppm.c \ ppm.h pcap_pkthdr32.h cpuclock.h sf_types.h log_text.c \ log_text.h detection_filter.c detection_filter.h \ detection_util.c detection_util.h rate_filter.c rate_filter.h \ pkt_tracer.c pkt_tracer.h obfuscation.c obfuscation.h \ rule_option_types.h sfdaq.c sfdaq.h reload.c reload.h \ reload_api.h idle_processing.c idle_processing.h \ idle_processing_funcs.h appIdApi.h reg_test.h reg_test.c \ memory_stats.h memory_stats.c dump.c dump.h @BUILD_SNPRINTF_TRUE@am__objects_1 = snprintf.$(OBJEXT) @BUILD_CONTROL_SOCKET_TRUE@am__objects_2 = dump.$(OBJEXT) am_snort_OBJECTS = debug.$(OBJEXT) decode.$(OBJEXT) encode.$(OBJEXT) \ active.$(OBJEXT) log.$(OBJEXT) mstring.$(OBJEXT) \ hashstring.$(OBJEXT) parser.$(OBJEXT) profiler.$(OBJEXT) \ plugbase.$(OBJEXT) snort.$(OBJEXT) $(am__objects_1) \ strlcatu.$(OBJEXT) strlcpyu.$(OBJEXT) tag.$(OBJEXT) \ util.$(OBJEXT) detect.$(OBJEXT) signature.$(OBJEXT) \ mempool.$(OBJEXT) sf_sdlist.$(OBJEXT) fpcreate.$(OBJEXT) \ fpdetect.$(OBJEXT) pcrm.$(OBJEXT) byte_extract.$(OBJEXT) \ sfthreshold.$(OBJEXT) packet_time.$(OBJEXT) \ event_wrapper.$(OBJEXT) event_queue.$(OBJEXT) ppm.$(OBJEXT) \ log_text.$(OBJEXT) detection_filter.$(OBJEXT) \ detection_util.$(OBJEXT) rate_filter.$(OBJEXT) \ pkt_tracer.$(OBJEXT) obfuscation.$(OBJEXT) sfdaq.$(OBJEXT) \ reload.$(OBJEXT) idle_processing.$(OBJEXT) reg_test.$(OBJEXT) \ memory_stats.$(OBJEXT) $(am__objects_2) snort_OBJECTS = $(am_snort_OBJECTS) snort_DEPENDENCIES = output-plugins/libspo.a \ detection-plugins/libspd.a dynamic-plugins/libdynamic.a \ dynamic-output/plugins/liboutput.a preprocessors/libspp.a \ parser/libparser.a target-based/libtarget_based.a \ preprocessors/HttpInspect/libhttp_inspect.a \ preprocessors/Session/libsession.a \ preprocessors/Stream6/libstream6.a sfutil/libsfutil.a \ control/libsfcontrol.a file-process/libfileAPI.a \ file-process/libs/libfile.a $(am__append_2) $(am__append_4) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = am__depfiles_maybe = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(snort_SOURCES) DIST_SOURCES = $(am__snort_SOURCES_DIST) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = sfutil win32 output-plugins detection-plugins \ dynamic-plugins preprocessors parser dynamic-preprocessors \ dynamic-output target-based control file-process \ dynamic-examples side-channel reload-adjust DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CCONFIGFLAGS = @CCONFIGFLAGS@ CFLAGS = @CFLAGS@ CONFIGFLAGS = @CONFIGFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ ICONFIGFLAGS = @ICONFIGFLAGS@ INCLUDES = @INCLUDES@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LUA_CFLAGS = @LUA_CFLAGS@ LUA_LIBS = @LUA_LIBS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIGNAL_SNORT_DUMP_STATS = @SIGNAL_SNORT_DUMP_STATS@ SIGNAL_SNORT_READ_ATTR_TBL = @SIGNAL_SNORT_READ_ATTR_TBL@ SIGNAL_SNORT_RELOAD = @SIGNAL_SNORT_RELOAD@ SIGNAL_SNORT_ROTATE_STATS = @SIGNAL_SNORT_ROTATE_STATS@ STRIP = @STRIP@ VERSION = @VERSION@ XCCFLAGS = @XCCFLAGS@ YACC = @YACC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ 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@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luajit_CFLAGS = @luajit_CFLAGS@ luajit_LIBS = @luajit_LIBS@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign no-dependencies @BUILD_SNPRINTF_TRUE@SNPRINTF_SOURCES = snprintf.c snprintf.h snort_SOURCES = cdefs.h event.h generators.h sf_protocols.h \ plugin_enum.h rules.h treenodes.h checksum.h debug.c \ snort_debug.h decode.c decode.h encode.c encode.h active.c \ active.h log.c log.h mstring.c mstring.h hashstring.c \ hashstring.h parser.c parser.h profiler.c profiler.h \ plugbase.c plugbase.h preprocids.h snort.c snort.h build.h \ $(SNPRINTF_SOURCES) strlcatu.c strlcatu.h strlcpyu.c \ strlcpyu.h tag.c tag.h util.c util.h detect.c detect.h \ signature.c signature.h mempool.c mempool.h sf_sdlist.c \ sf_sdlist.h sf_sdlist_types.h fpcreate.c fpcreate.h fpdetect.c \ fpdetect.h pcrm.c pcrm.h snort_bounds.h byte_extract.c \ byte_extract.h timersub.h spo_plugbase.h sfthreshold.c \ sfthreshold.h packet_time.c packet_time.h event_wrapper.c \ event_wrapper.h event_queue.c event_queue.h ipv6_port.h ppm.c \ ppm.h pcap_pkthdr32.h cpuclock.h sf_types.h log_text.c \ log_text.h detection_filter.c detection_filter.h \ detection_util.c detection_util.h rate_filter.c rate_filter.h \ pkt_tracer.c pkt_tracer.h obfuscation.c obfuscation.h \ rule_option_types.h sfdaq.c sfdaq.h reload.c reload.h \ reload_api.h idle_processing.c idle_processing.h \ idle_processing_funcs.h appIdApi.h reg_test.h reg_test.c \ memory_stats.h memory_stats.c $(am__append_1) snort_LDADD = output-plugins/libspo.a detection-plugins/libspd.a \ dynamic-plugins/libdynamic.a \ dynamic-output/plugins/liboutput.a preprocessors/libspp.a \ parser/libparser.a target-based/libtarget_based.a \ preprocessors/HttpInspect/libhttp_inspect.a \ preprocessors/Session/libsession.a \ preprocessors/Stream6/libstream6.a sfutil/libsfutil.a \ control/libsfcontrol.a file-process/libfileAPI.a \ file-process/libs/libfile.a $(am__append_2) $(am__append_4) @BUILD_DYNAMIC_EXAMPLES_TRUE@EXAMPLES_DIR = dynamic-examples SUBDIRS = sfutil win32 output-plugins detection-plugins \ dynamic-plugins preprocessors parser dynamic-preprocessors \ dynamic-output target-based control file-process \ $(EXAMPLES_DIR) $(am__append_3) $(am__append_5) all: all-recursive .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/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: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list snort$(EXEEXT): $(snort_OBJECTS) $(snort_DEPENDENCIES) $(EXTRA_snort_DEPENDENCIES) @rm -f snort$(EXEEXT) $(AM_V_CCLD)$(LINK) $(snort_OBJECTS) $(snort_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c .c.o: $(AM_V_CC)$(COMPILE) -c $< .c.obj: $(AM_V_CC)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: $(AM_V_CC)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files 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)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(PROGRAMS) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_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-recursive clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-binPROGRAMS clean-generic clean-libtool \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-binPROGRAMS install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-binPROGRAMS # 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: snort-2.9.15.1/src/Makefile.am0000444000175200017520000000471513571422607012700 00000000000000## $Id$ AUTOMAKE_OPTIONS=foreign no-dependencies bin_PROGRAMS = snort if BUILD_SNPRINTF SNPRINTF_SOURCES = snprintf.c snprintf.h endif snort_SOURCES = cdefs.h \ event.h \ generators.h \ sf_protocols.h \ plugin_enum.h \ rules.h \ treenodes.h \ checksum.h \ debug.c snort_debug.h \ decode.c decode.h \ encode.c encode.h \ active.c active.h \ log.c log.h \ mstring.c mstring.h \ hashstring.c hashstring.h \ parser.c parser.h \ profiler.c profiler.h \ plugbase.c plugbase.h \ preprocids.h \ snort.c snort.h \ build.h \ $(SNPRINTF_SOURCES) \ strlcatu.c strlcatu.h \ strlcpyu.c strlcpyu.h \ tag.c tag.h \ util.c util.h \ detect.c detect.h \ signature.c signature.h \ mempool.c mempool.h \ sf_sdlist.c sf_sdlist.h sf_sdlist_types.h \ fpcreate.c fpcreate.h \ fpdetect.c fpdetect.h \ pcrm.c pcrm.h \ snort_bounds.h \ byte_extract.c \ byte_extract.h \ timersub.h \ spo_plugbase.h \ sfthreshold.c sfthreshold.h \ packet_time.c packet_time.h \ event_wrapper.c event_wrapper.h \ event_queue.c event_queue.h \ ipv6_port.h \ ppm.c ppm.h \ pcap_pkthdr32.h \ cpuclock.h \ sf_types.h \ log_text.c log_text.h \ detection_filter.c detection_filter.h \ detection_util.c detection_util.h \ rate_filter.c rate_filter.h \ pkt_tracer.c pkt_tracer.h \ obfuscation.c obfuscation.h \ rule_option_types.h \ sfdaq.c sfdaq.h \ reload.c reload.h reload_api.h \ idle_processing.c idle_processing.h idle_processing_funcs.h \ appIdApi.h \ reg_test.h reg_test.c \ memory_stats.h memory_stats.c if BUILD_CONTROL_SOCKET snort_SOURCES += dump.c dump.h endif snort_LDADD = output-plugins/libspo.a \ detection-plugins/libspd.a \ dynamic-plugins/libdynamic.a \ dynamic-output/plugins/liboutput.a \ preprocessors/libspp.a \ parser/libparser.a \ target-based/libtarget_based.a \ preprocessors/HttpInspect/libhttp_inspect.a \ preprocessors/Session/libsession.a \ preprocessors/Stream6/libstream6.a \ sfutil/libsfutil.a \ control/libsfcontrol.a \ file-process/libfileAPI.a \ file-process/libs/libfile.a if BUILD_DYNAMIC_EXAMPLES EXAMPLES_DIR = dynamic-examples endif SUBDIRS = sfutil win32 output-plugins detection-plugins dynamic-plugins preprocessors parser dynamic-preprocessors dynamic-output target-based control file-process $(EXAMPLES_DIR) INCLUDES = @INCLUDES@ if BUILD_SIDE_CHANNEL snort_LDADD += \ side-channel/libsidechannel.a \ side-channel/plugins/libsscm.a SUBDIRS += side-channel endif if BUILD_SNORT_RELOAD snort_LDADD += reload-adjust/libreload_adjust.a SUBDIRS += reload-adjust endif snort-2.9.15.1/src/cdefs.h0000644000175200017520000000676013571422607012105 00000000000000/* * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * * By using this file, you agree to the terms and conditions set * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. * * $Id$ * @(#)cdefs.h 8.8 (Berkeley) 1/9/95 */ #ifndef _CDEFS_H_ # define _CDEFS_H_ # if defined(__cplusplus) # define __BEGIN_DECLS extern "C" { # define __END_DECLS }; # else /* defined(__cplusplus) */ # define __BEGIN_DECLS # define __END_DECLS # endif /* defined(__cplusplus) */ /* * The __CONCAT macro is used to concatenate parts of symbol names, e.g. * with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo. * The __CONCAT macro is a bit tricky -- make sure you don't put spaces * in between its arguments. __CONCAT can also concatenate double-quoted * strings produced by the __STRING macro, but this only works with ANSI C. */ # if defined(__STDC__) || defined(__cplusplus) # define __P(protos) protos /* full-blown ANSI C */ # ifndef __CONCAT # define __CONCAT(x,y) x ## y # endif /* ! __CONCAT */ # define __STRING(x) #x # ifndef __const # define __const const /* define reserved names to standard */ # endif /* ! __const */ # define __signed signed # define __volatile volatile # if defined(__cplusplus) # define __inline inline /* convert to C++ keyword */ # else /* defined(__cplusplus) */ # ifndef __GNUC__ # define __inline /* delete GCC keyword */ # endif /* ! __GNUC__ */ # endif /* defined(__cplusplus) */ # else /* defined(__STDC__) || defined(__cplusplus) */ # define __P(protos) () /* traditional C preprocessor */ # ifndef __CONCAT # define __CONCAT(x,y) x/**/y # endif /* ! __CONCAT */ # define __STRING(x) "x" # ifndef __GNUC__ # define __const /* delete pseudo-ANSI C keywords */ # define __inline # define __signed # define __volatile /* * In non-ANSI C environments, new programs will want ANSI-only C keywords * deleted from the program and old programs will want them left alone. * When using a compiler other than gcc, programs using the ANSI C keywords * const, inline etc. as normal identifiers should define -DNO_ANSI_KEYWORDS. * When using "gcc -traditional", we assume that this is the intent; if * __GNUC__ is defined but __STDC__ is not, we leave the new keywords alone. */ # ifndef NO_ANSI_KEYWORDS # define const /* delete ANSI C keywords */ # define inline # define signed # define volatile # endif /* ! NO_ANSI_KEYWORDS */ # endif /* ! __GNUC__ */ # endif /* defined(__STDC__) || defined(__cplusplus) */ /* * GCC1 and some versions of GCC2 declare dead (non-returning) and * pure (no side effects) functions using "volatile" and "const"; * unfortunately, these then cause warnings under "-ansi -pedantic". * GCC2 uses a new, peculiar __attribute__((attrs)) style. All of * these work for GNU C++ (modulo a slight glitch in the C++ grammar * in the distribution version of 2.5.5). */ # if !defined(__GNUC__) || __GNUC__ < 2 || \ (__GNUC__ == 2 && __GNUC_MINOR__ < 5) # define __attribute__(x) /* delete __attribute__ if non-gcc or gcc1 */ # if defined(__GNUC__) && !defined(__STRICT_ANSI__) # define __dead __volatile # define __pure __const # endif /* defined(__GNUC__) && !defined(__STRICT_ANSI__) */ # endif /* !defined(__GNUC__) || __GNUC__ < 2 || \ */ /* Delete pseudo-keywords wherever they are not available or needed. */ # ifndef __dead # define __dead # define __pure # endif /* ! __dead */ #endif /* ! _CDEFS_H_ */ snort-2.9.15.1/src/event.h0000644000175200017520000000454013571422607012134 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* D E F I N E S ************************************************************/ #ifndef __EVENT_H__ #define __EVENT_H__ #ifdef OSF1 #include #endif #include #include "pcap_pkthdr32.h" #if defined(FEAT_OPEN_APPID) #define MAX_EVENT_APPNAME_LEN 64 #endif /* defined(FEAT_OPEN_APPID) */ typedef struct _Event { uint32_t sig_generator; /* which part of snort generated the alert? */ uint32_t sig_id; /* sig id for this generator */ uint32_t sig_rev; /* sig revision for this id */ uint32_t classification; /* event classification */ uint32_t priority; /* event priority */ uint32_t event_id; /* event ID */ uint32_t event_reference; /* reference to other events that have gone off, * such as in the case of tagged packets... */ struct sf_timeval32 ref_time; /* reference time for the event reference */ #if defined(FEAT_OPEN_APPID) char app_name[MAX_EVENT_APPNAME_LEN]; #endif /* defined(FEAT_OPEN_APPID) */ /* Don't add to this structure because this is the serialized data * struct for unified logging. */ } Event; #if 0 typedef struct _EventID { uint32_t sequence; uint32_t seconds; } EventID; typedef struct _Event { EventID id; uint32_t uSeconds; SigInfo sigInfo; } Event; #endif #endif /* __EVENT_H__ */ snort-2.9.15.1/src/generators.h0000644000175200017520000013206513571422607013170 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __GENERATORS_H__ #define __GENERATORS_H__ #define GENERATOR_SNORT_ENGINE 1 #define GENERATOR_TAG 2 #define TAG_LOG_PKT 1 #define GENERATOR_SPP_BO 105 #define BO_TRAFFIC_DETECT 1 #define BO_CLIENT_TRAFFIC_DETECT 2 #define BO_SERVER_TRAFFIC_DETECT 3 #define BO_SNORT_BUFFER_ATTACK 4 #define GENERATOR_SPP_RPC_DECODE 106 #define RPC_FRAG_TRAFFIC 1 #define RPC_MULTIPLE_RECORD 2 #define RPC_LARGE_FRAGSIZE 3 #define RPC_INCOMPLETE_SEGMENT 4 #define RPC_ZERO_LENGTH_FRAGMENT 5 #define GENERATOR_SPP_ARPSPOOF 112 #define ARPSPOOF_UNICAST_ARP_REQUEST 1 #define ARPSPOOF_ETHERFRAME_ARP_MISMATCH_SRC 2 #define ARPSPOOF_ETHERFRAME_ARP_MISMATCH_DST 3 #define ARPSPOOF_ARP_CACHE_OVERWRITE_ATTACK 4 #define GENERATOR_SNORT_DECODE 116 #define DECODE_NOT_IPV4_DGRAM 1 #define DECODE_IPV4_INVALID_HEADER_LEN 2 #define DECODE_IPV4_DGRAM_LT_IPHDR 3 #define DECODE_IPV4OPT_BADLEN 4 #define DECODE_IPV4OPT_TRUNCATED 5 #define DECODE_IPV4_DGRAM_GT_CAPLEN 6 #define DECODE_TCP_DGRAM_LT_TCPHDR 45 #define DECODE_TCP_INVALID_OFFSET 46 #define DECODE_TCP_LARGE_OFFSET 47 #define DECODE_TCPOPT_BADLEN 54 #define DECODE_TCPOPT_TRUNCATED 55 #define DECODE_TCPOPT_TTCP 56 #define DECODE_TCPOPT_OBSOLETE 57 #define DECODE_TCPOPT_EXPERIMENT 58 #define DECODE_TCPOPT_WSCALE_INVALID 59 #define DECODE_UDP_DGRAM_LT_UDPHDR 95 #define DECODE_UDP_DGRAM_INVALID_LENGTH 96 #define DECODE_UDP_DGRAM_SHORT_PACKET 97 #define DECODE_UDP_DGRAM_LONG_PACKET 98 #define DECODE_ICMP_DGRAM_LT_ICMPHDR 105 #define DECODE_ICMP_DGRAM_LT_TIMESTAMPHDR 106 #define DECODE_ICMP_DGRAM_LT_ADDRHDR 107 #define DECODE_ARP_TRUNCATED 109 #define DECODE_EAPOL_TRUNCATED 110 #define DECODE_EAPKEY_TRUNCATED 111 #define DECODE_EAP_TRUNCATED 112 #define DECODE_BAD_PPPOE 120 #define DECODE_BAD_VLAN 130 #define DECODE_BAD_VLAN_ETHLLC 131 #define DECODE_BAD_VLAN_OTHER 132 #define DECODE_BAD_80211_ETHLLC 133 #define DECODE_BAD_80211_OTHER 134 #define DECODE_BAD_TRH 140 #define DECODE_BAD_TR_ETHLLC 141 #define DECODE_BAD_TR_MR_LEN 142 #define DECODE_BAD_TRHMR 143 #define DECODE_BAD_TRAFFIC_LOOPBACK 150 #define DECODE_BAD_TRAFFIC_SAME_SRCDST 151 #ifdef GRE #define DECODE_GRE_DGRAM_LT_GREHDR 160 #define DECODE_GRE_MULTIPLE_ENCAPSULATION 161 #define DECODE_GRE_INVALID_VERSION 162 #define DECODE_GRE_INVALID_HEADER 163 #define DECODE_GRE_V1_INVALID_HEADER 164 #define DECODE_GRE_TRANS_DGRAM_LT_TRANSHDR 165 #endif /* GRE */ /** MPLS takes 170 block **/ #define DECODE_BAD_MPLS 170 #define DECODE_BAD_MPLS_LABEL0 171 #define DECODE_BAD_MPLS_LABEL1 172 #define DECODE_BAD_MPLS_LABEL2 173 #define DECODE_BAD_MPLS_LABEL3 174 #define DECODE_MPLS_RESERVED_LABEL 175 #define DECODE_MPLS_LABEL_STACK 176 #define DECODE_ICMP_ORIG_IP_TRUNCATED 250 #define DECODE_ICMP_ORIG_IP_VER_MISMATCH 251 #define DECODE_ICMP_ORIG_DGRAM_LT_ORIG_IP 252 #define DECODE_ICMP_ORIG_PAYLOAD_LT_64 253 #define DECODE_ICMP_ORIG_PAYLOAD_GT_576 254 #define DECODE_ICMP_ORIG_IP_WITH_FRAGOFFSET 255 #define DECODE_IPV6_MIN_TTL 270 #define DECODE_IPV6_IS_NOT 271 #define DECODE_IPV6_TRUNCATED_EXT 272 #define DECODE_IPV6_TRUNCATED 273 #define DECODE_IPV6_DGRAM_LT_IPHDR 274 #define DECODE_IPV6_DGRAM_GT_CAPLEN 275 #define DECODE_IPV6_DST_ZERO 276 #define DECODE_IPV6_SRC_MULTICAST 277 #define DECODE_IPV6_DST_RESERVED_MULTICAST 278 #define DECODE_IPV6_BAD_OPT_TYPE 279 #define DECODE_IPV6_BAD_MULTICAST_SCOPE 280 #define DECODE_IPV6_BAD_NEXT_HEADER 281 #define DECODE_IPV6_ROUTE_AND_HOPBYHOP 282 #define DECODE_IPV6_TWO_ROUTE_HEADERS 283 #define DECODE_ICMPV6_TOO_BIG_BAD_MTU 285 #define DECODE_ICMPV6_UNREACHABLE_NON_RFC_2463_CODE 286 #define DECODE_ICMPV6_SOLICITATION_BAD_CODE 287 #define DECODE_ICMPV6_ADVERT_BAD_CODE 288 #define DECODE_ICMPV6_SOLICITATION_BAD_RESERVED 289 #define DECODE_ICMPV6_ADVERT_BAD_REACHABLE 290 #define DECODE_IPV6_TUNNELED_IPV4_TRUNCATED 291 #define DECODE_IPV6_DSTOPTS_WITH_ROUTING 292 #define DECODE_IP_MULTIPLE_ENCAPSULATION 293 #define DECODE_ESP_HEADER_TRUNC 294 #define DECODE_IPV6_BAD_OPT_LEN 295 #define DECODE_IPV6_UNORDERED_EXTENSIONS 296 #define DECODE_GTP_MULTIPLE_ENCAPSULATION 297 #define DECODE_GTP_BAD_LEN 298 //----------------------------------------------------- // remember to add rules to preproc_rules/decoder.rules // add the new decoder rules to the following enum. #define DECODE_START_INDEX 400 enum { DECODE_TCP_XMAS = DECODE_START_INDEX, DECODE_TCP_NMAP_XMAS, DECODE_DOS_NAPTHA, DECODE_SYN_TO_MULTICAST, DECODE_ZERO_TTL, DECODE_BAD_FRAGBITS, DECODE_UDP_IPV6_ZERO_CHECKSUM, DECODE_IP4_LEN_OFFSET, DECODE_IP4_SRC_THIS_NET, DECODE_IP4_DST_THIS_NET, DECODE_IP4_SRC_MULTICAST, DECODE_IP4_SRC_RESERVED, DECODE_IP4_DST_RESERVED, DECODE_IP4_SRC_BROADCAST, DECODE_IP4_DST_BROADCAST, DECODE_ICMP4_DST_MULTICAST, DECODE_ICMP4_DST_BROADCAST, DECODE_ICMP4_TYPE_OTHER = 418, DECODE_TCP_BAD_URP, DECODE_TCP_SYN_FIN, DECODE_TCP_SYN_RST, DECODE_TCP_MUST_ACK, DECODE_TCP_NO_SYN_ACK_RST, DECODE_ETH_HDR_TRUNC, DECODE_IP4_HDR_TRUNC, DECODE_ICMP4_HDR_TRUNC, DECODE_ICMP6_HDR_TRUNC, DECODE_IP4_MIN_TTL, DECODE_IP6_ZERO_HOP_LIMIT, DECODE_IP4_DF_OFFSET, DECODE_ICMP6_TYPE_OTHER, DECODE_ICMP6_DST_MULTICAST, DECODE_TCP_SHAFT_SYNFLOOD, DECODE_ICMP_PING_NMAP, DECODE_ICMP_ICMPENUM, DECODE_ICMP_REDIRECT_HOST, DECODE_ICMP_REDIRECT_NET, DECODE_ICMP_TRACEROUTE_IPOPTS, DECODE_ICMP_SOURCE_QUENCH, DECODE_ICMP_BROADSCAN_SMURF_SCANNER, DECODE_ICMP_DST_UNREACH_ADMIN_PROHIBITED, DECODE_ICMP_DST_UNREACH_DST_HOST_PROHIBITED, DECODE_ICMP_DST_UNREACH_DST_NET_PROHIBITED, DECODE_IP_OPTION_SET, DECODE_UDP_LARGE_PACKET, DECODE_TCP_PORT_ZERO, DECODE_UDP_PORT_ZERO, DECODE_IP_RESERVED_FRAG_BIT, DECODE_IP_UNASSIGNED_PROTO, DECODE_IP_BAD_PROTO, DECODE_ICMP_PATH_MTU_DOS, DECODE_ICMP_DOS_ATTEMPT, DECODE_IPV6_ISATAP_SPOOF, DECODE_PGM_NAK_OVERFLOW, DECODE_IGMP_OPTIONS_DOS, DECODE_IP6_EXCESS_EXT_HDR, DECODE_ICMPV6_UNREACHABLE_NON_RFC_4443_CODE, DECODE_IPV6_BAD_FRAG_PKT, DECODE_ZERO_LENGTH_FRAG, DECODE_ICMPV6_NODE_INFO_BAD_CODE, DECODE_IPV6_ROUTE_ZERO, DECODE_ERSPAN_HDR_VERSION_MISMATCH, DECODE_ERSPAN2_DGRAM_LT_HDR, DECODE_ERSPAN3_DGRAM_LT_HDR, DECODE_AUTH_HDR_TRUNC, DECODE_AUTH_HDR_BAD_LEN, DECODE_FPATH_HDR_TRUNC, DECODE_CISCO_META_HDR_TRUNC, DECODE_CISCO_META_HDR_OPT_LEN, DECODE_CISCO_META_HDR_OPT_TYPE, DECODE_CISCO_META_HDR_SGT, DECODE_INDEX_MAX }; //----------------------------------------------------- /* ** HttpInspect Generator IDs ** ** IMPORTANT:: ** Whenever events are added to the internal HttpInspect ** event queue, you must also add the event here. The ** trick is that whatever the number is in HttpInspect, ** it must be +1 when you define it here. */ // these are client specific events #define GENERATOR_SPP_HTTP_INSPECT_CLIENT 119 #define HI_CLIENT_ASCII 1 /* done */ #define HI_CLIENT_DOUBLE_DECODE 2 /* done */ #define HI_CLIENT_U_ENCODE 3 /* done */ #define HI_CLIENT_BARE_BYTE 4 /* done */ /* Base 36 is deprecated and essentially a noop * Leaving here in case anyone out there has historical data with * alerts of this type */ #define HI_CLIENT_BASE36 5 /* done */ #define HI_CLIENT_UTF_8 6 /* done */ #define HI_CLIENT_IIS_UNICODE 7 /* done */ #define HI_CLIENT_MULTI_SLASH 8 /* done */ #define HI_CLIENT_IIS_BACKSLASH 9 /* done */ #define HI_CLIENT_SELF_DIR_TRAV 10 /* done */ #define HI_CLIENT_DIR_TRAV 11 /* done */ #define HI_CLIENT_APACHE_WS 12 /* done */ #define HI_CLIENT_IIS_DELIMITER 13 /* done */ #define HI_CLIENT_NON_RFC_CHAR 14 /* done */ #define HI_CLIENT_OVERSIZE_DIR 15 /* done */ #define HI_CLIENT_LARGE_CHUNK 16 /* done */ #define HI_CLIENT_PROXY_USE 17 /* done */ #define HI_CLIENT_WEBROOT_DIR 18 /* done */ #define HI_CLIENT_LONG_HDR 19 /* done */ #define HI_CLIENT_MAX_HEADERS 20 /* done */ #define HI_CLIENT_MULTIPLE_CONTLEN 21 #define HI_CLIENT_CHUNK_SIZE_MISMATCH 22 #define HI_CLIENT_INVALID_TRUEIP 23 #define HI_CLIENT_MULTIPLE_HOST_HDRS 24 #define HI_CLIENT_LONG_HOSTNAME 25 #define HI_CLIENT_EXCEEDS_SPACES 26 #define HI_CLIENT_CONSECUTIVE_SMALL_CHUNK_SIZES 27 #define HI_CLIENT_UNBOUNDED_POST 28 #define HI_CLIENT_MULTIPLE_TRUEIP_IN_SESSION 29 #define HI_CLIENT_BOTH_TRUEIP_XFF_HDRS 30 #define HI_CLIENT_UNKNOWN_METHOD 31 #define HI_CLIENT_SIMPLE_REQUEST 32 #define HI_CLIENT_UNESCAPED_SPACE_URI 33 #define HI_CLIENT_PIPELINE_MAX 34 // these are either server specific or both client / server #define GENERATOR_SPP_HTTP_INSPECT 120 #define HI_ANOM_SERVER_ALERT 1 /* done */ #define HI_SERVER_INVALID_STATCODE 2 #define HI_SERVER_NO_CONTLEN 3 #define HI_SERVER_UTF_NORM_FAIL 4 #define HI_SERVER_UTF7 5 #define HI_SERVER_DECOMPR_FAILED 6 #define HI_SERVER_CONSECUTIVE_SMALL_CHUNK_SIZES 7 #define HI_CLISRV_MSG_SIZE_EXCEPTION 8 #define HI_SERVER_JS_OBFUSCATION_EXCD 9 #define HI_SERVER_JS_EXCESS_WS 10 #define HI_SERVER_MIXED_ENCODINGS 11 #define HI_SERVER_SWF_ZLIB_FAILURE 12 #define HI_SERVER_SWF_LZMA_FAILURE 13 #define HI_SERVER_PDF_DEFLATE_FAILURE 14 #define HI_SERVER_PDF_UNSUP_COMP_TYPE 15 #define HI_SERVER_PDF_CASC_COMP 16 #define HI_SERVER_PDF_PARSE_FAILURE 17 #define GENERATOR_PSNG 122 #define PSNG_TCP_PORTSCAN 1 #define PSNG_TCP_DECOY_PORTSCAN 2 #define PSNG_TCP_PORTSWEEP 3 #define PSNG_TCP_DISTRIBUTED_PORTSCAN 4 #define PSNG_TCP_FILTERED_PORTSCAN 5 #define PSNG_TCP_FILTERED_DECOY_PORTSCAN 6 #define PSNG_TCP_PORTSWEEP_FILTERED 7 #define PSNG_TCP_FILTERED_DISTRIBUTED_PORTSCAN 8 #define PSNG_IP_PORTSCAN 9 #define PSNG_IP_DECOY_PORTSCAN 10 #define PSNG_IP_PORTSWEEP 11 #define PSNG_IP_DISTRIBUTED_PORTSCAN 12 #define PSNG_IP_FILTERED_PORTSCAN 13 #define PSNG_IP_FILTERED_DECOY_PORTSCAN 14 #define PSNG_IP_PORTSWEEP_FILTERED 15 #define PSNG_IP_FILTERED_DISTRIBUTED_PORTSCAN 16 #define PSNG_UDP_PORTSCAN 17 #define PSNG_UDP_DECOY_PORTSCAN 18 #define PSNG_UDP_PORTSWEEP 19 #define PSNG_UDP_DISTRIBUTED_PORTSCAN 20 #define PSNG_UDP_FILTERED_PORTSCAN 21 #define PSNG_UDP_FILTERED_DECOY_PORTSCAN 22 #define PSNG_UDP_PORTSWEEP_FILTERED 23 #define PSNG_UDP_FILTERED_DISTRIBUTED_PORTSCAN 24 #define PSNG_ICMP_PORTSWEEP 25 #define PSNG_ICMP_PORTSWEEP_FILTERED 26 #define PSNG_OPEN_PORT 27 #define GENERATOR_SPP_FRAG3 123 #define FRAG3_IPOPTIONS 1 #define FRAG3_TEARDROP 2 #define FRAG3_SHORT_FRAG 3 #define FRAG3_ANOMALY_OVERSIZE 4 #define FRAG3_ANOMALY_ZERO 5 #define FRAG3_ANOMALY_BADSIZE_SM 6 #define FRAG3_ANOMALY_BADSIZE_LG 7 #define FRAG3_ANOMALY_OVLP 8 /* 123:9, 123:10 are OBE w/ addition of 116:458 * (aka DECODE_IPV6_BAD_FRAG_PKT). * Leave these here so they are not reused. * ------ #define FRAG3_IPV6_BSD_ICMP_FRAG 9 #define FRAG3_IPV6_BAD_FRAG_PKT 10 * ------ */ #define FRAG3_MIN_TTL_EVASION 11 #define FRAG3_EXCESSIVE_OVERLAP 12 #define FRAG3_TINY_FRAGMENT 13 #define GENERATOR_SMTP 124 #define SMTP_COMMAND_OVERFLOW 1 #define SMTP_DATA_HDR_OVERFLOW 2 #define SMTP_RESPONSE_OVERFLOW 3 #define SMTP_SPECIFIC_CMD_OVERFLOW 4 #define SMTP_UNKNOWN_CMD 5 #define SMTP_ILLEGAL_CMD 6 #define SMTP_HEADER_NAME_OVERFLOW 7 #define SMTP_XLINK2STATE_OVERFLOW 8 /* This alert is obsolete. * * #define SMTP_DECODE_MEMCAP_EXCEEDED 9*/ #define SMTP_B64_DECODING_FAILED 10 #define SMTP_QP_DECODING_FAILED 11 /* Do not delete or reuse this SID. Commenting this SID as this alert is no longer valid.* * #define SMTP_BITENC_DECODING_FAILED 12 */ #define SMTP_UU_DECODING_FAILED 13 /* ** FTPTelnet Generator IDs ** ** IMPORTANT:: ** Whenever events are added to the internal FTP or Telnet ** event queues, you must also add the event here. The ** trick is that whatever the number is in FTPTelnet, ** it must be +1 when you define it here. */ #define GENERATOR_SPP_FTPP_FTP 125 #define FTPP_FTP_TELNET_CMD 1 #define FTPP_FTP_INVALID_CMD 2 #define FTPP_FTP_PARAMETER_LENGTH_OVERFLOW 3 #define FTPP_FTP_MALFORMED_PARAMETER 4 #define FTPP_FTP_PARAMETER_STR_FORMAT 5 #define FTPP_FTP_RESPONSE_LENGTH_OVERFLOW 6 #define FTPP_FTP_ENCRYPTED 7 #define FTPP_FTP_BOUNCE 8 #define GENERATOR_SPP_FTPP_TELNET 126 #define FTPP_TELNET_AYT_OVERFLOW 1 #define FTPP_TELNET_ENCRYPTED 2 #define FTPP_TELNET_SUBNEG_BEGIN_NO_END 3 #define GENERATOR_SPP_ISAKMP 127 #define GENERATOR_SPP_SSH 128 #define SSH_EVENT_RESPOVERFLOW 1 #define SSH_EVENT_CRC32 2 #define SSH_EVENT_SECURECRT 3 #define SSH_EVENT_PROTOMISMATCH 4 #define SSH_EVENT_WRONGDIR 5 #define SSH_EVENT_PAYLOAD_SIZE 6 #define SSH_EVENT_VERSION 7 #define GENERATOR_SPP_STREAM 129 #define STREAM_SYN_ON_EST 1 #define STREAM_DATA_ON_SYN 2 #define STREAM_DATA_ON_CLOSED 3 #define STREAM_BAD_TIMESTAMP 4 #define STREAM_BAD_SEGMENT 5 #define STREAM_WINDOW_TOO_LARGE 6 #define STREAM_EXCESSIVE_TCP_OVERLAPS 7 #define STREAM_DATA_AFTER_RESET 8 #define STREAM_SESSION_HIJACKED_CLIENT 9 #define STREAM_SESSION_HIJACKED_SERVER 10 #define STREAM_DATA_WITHOUT_FLAGS 11 #define STREAM_SMALL_SEGMENT 12 #define STREAM_4WAY_HANDSHAKE 13 #define STREAM_NO_TIMESTAMP 14 #define STREAM_BAD_RST 15 #define STREAM_BAD_FIN 16 #define STREAM_BAD_ACK 17 #define STREAM_DATA_AFTER_RST_RCVD 18 #define STREAM_WINDOW_SLAM 19 #define STREAM_NO_3WHS 20 #define GENERATOR_DNS 131 #define DNS_EVENT_OBSOLETE_TYPES 1 #define DNS_EVENT_EXPERIMENTAL_TYPES 2 #define DNS_EVENT_RDATA_OVERFLOW 3 #define GENERATOR_SKYPE 132 #define GENERATOR_DCE2 133 #define DCE2_EVENT__MEMCAP 1 #define DCE2_EVENT__SMB_BAD_NBSS_TYPE 2 #define DCE2_EVENT__SMB_BAD_TYPE 3 #define DCE2_EVENT__SMB_BAD_ID 4 #define DCE2_EVENT__SMB_BAD_WCT 5 #define DCE2_EVENT__SMB_BAD_BCC 6 #define DCE2_EVENT__SMB_BAD_FORMAT 7 #define DCE2_EVENT__SMB_BAD_OFF 8 #define DCE2_EVENT__SMB_TDCNT_ZERO 9 #define DCE2_EVENT__SMB_NB_LT_SMBHDR 10 #define DCE2_EVENT__SMB_NB_LT_COM 11 #define DCE2_EVENT__SMB_NB_LT_BCC 12 #define DCE2_EVENT__SMB_NB_LT_DSIZE 13 #define DCE2_EVENT__SMB_TDCNT_LT_DSIZE 14 #define DCE2_EVENT__SMB_DSENT_GT_TDCNT 15 #define DCE2_EVENT__SMB_BCC_LT_DSIZE 16 #define DCE2_EVENT__SMB_INVALID_DSIZE 17 #define DCE2_EVENT__SMB_EXCESSIVE_TREE_CONNECTS 18 #define DCE2_EVENT__SMB_EXCESSIVE_READS 19 #define DCE2_EVENT__SMB_EXCESSIVE_CHAINING 20 #define DCE2_EVENT__SMB_MULT_CHAIN_SS 21 #define DCE2_EVENT__SMB_MULT_CHAIN_TC 22 #define DCE2_EVENT__SMB_CHAIN_SS_LOGOFF 23 #define DCE2_EVENT__SMB_CHAIN_TC_TDIS 24 #define DCE2_EVENT__SMB_CHAIN_OPEN_CLOSE 25 #define DCE2_EVENT__SMB_INVALID_SHARE 26 #define DCE2_EVENT__CO_BAD_MAJ_VERSION 27 #define DCE2_EVENT__CO_BAD_MIN_VERSION 28 #define DCE2_EVENT__CO_BAD_PDU_TYPE 29 #define DCE2_EVENT__CO_FLEN_LT_HDR 30 #define DCE2_EVENT__CO_FLEN_LT_SIZE 31 #define DCE2_EVENT__CO_ZERO_CTX_ITEMS 32 #define DCE2_EVENT__CO_ZERO_TSYNS 33 #define DCE2_EVENT__CO_FRAG_LT_MAX_XMIT_FRAG 34 #define DCE2_EVENT__CO_FRAG_GT_MAX_XMIT_FRAG 35 #define DCE2_EVENT__CO_ALTER_CHANGE_BYTE_ORDER 36 #define DCE2_EVENT__CO_FRAG_DIFF_CALL_ID 37 #define DCE2_EVENT__CO_FRAG_DIFF_OPNUM 38 #define DCE2_EVENT__CO_FRAG_DIFF_CTX_ID 39 #define DCE2_EVENT__CL_BAD_MAJ_VERSION 40 #define DCE2_EVENT__CL_BAD_PDU_TYPE 41 #define DCE2_EVENT__CL_DATA_LT_HDR 42 #define DCE2_EVENT__CL_BAD_SEQ_NUM 43 #define DCE2_EVENT__SMB_V1 44 #define DCE2_EVENT__SMB_V2 45 #define DCE2_EVENT__SMB_INVALID_BINDING 46 #define DCE2_EVENT__SMB2_EXCESSIVE_COMPOUNDING 47 #define DCE2_EVENT__SMB_DCNT_ZERO 48 #define DCE2_EVENT__SMB_DCNT_MISMATCH 49 #define DCE2_EVENT__SMB_MAX_REQS_EXCEEDED 50 #define DCE2_EVENT__SMB_REQS_SAME_MID 51 #define DCE2_EVENT__SMB_DEPR_DIALECT_NEGOTIATED 52 #define DCE2_EVENT__SMB_DEPR_COMMAND_USED 53 #define DCE2_EVENT__SMB_UNUSUAL_COMMAND_USED 54 #define DCE2_EVENT__SMB_INVALID_SETUP_COUNT 55 #define DCE2_EVENT__SMB_MULTIPLE_NEGOTIATIONS 56 #define DCE2_EVENT__SMB_EVASIVE_FILE_ATTRS 57 #define DCE2_EVENT__SMB_INVALID_FILE_OFFSET 58 #define DCE2_EVENT__SMB_BAD_NEXT_COMMAND_OFFSET 59 #define GENERATOR_PPM 134 #define PPM_EVENT_RULE_TREE_DISABLED 1 #define PPM_EVENT_RULE_TREE_ENABLED 2 #define PPM_EVENT_PACKET_ABORTED 3 #define GENERATOR_INTERNAL 135 #define INTERNAL_EVENT_SYN_RECEIVED 1 #define INTERNAL_EVENT_SESSION_ADD 2 #define INTERNAL_EVENT_SESSION_DEL 3 #define GENERATOR_SPP_REPUTATION 136 #define GENERATOR_SPP_SSLPP 137 #define GENERATOR_SPP_SDF_RULES 138 #define GENERATOR_SPP_SDF_PREPROC 139 // #define GENERATOR_SPP_SIP 140 // Defined in spp_sip.h file, not here. // #define GENERATOR_SPP_IMAP 141 // Defined in imap_log.h file // #define GENERATOR_SPP_POP 142 // Defined in pop_log.h file. #define SDF_COMBO_ALERT 1 #define GENERATOR_SPP_GTP 143 #define GENERATOR_SPP_MODBUS 144 #define GENERATOR_SPP_DNP3 145 // #define GENERATOR_FILE_TYPE 146 //Defined in file_service.h // #define GENERATOR_FILE_SIGNATURE 147 //Defined in file_service.h #define GENERATOR_SPP_CIP 148 /* This is where all the alert messages will be archived for each internal alerts */ #define ARPSPOOF_UNICAST_ARP_REQUEST_STR "(spp_arpspoof) Unicast ARP request" #define ARPSPOOF_ETHERFRAME_ARP_MISMATCH_SRC_STR \ "(spp_arpspoof) Ethernet/ARP Mismatch request for Source" #define ARPSPOOF_ETHERFRAME_ARP_MISMATCH_DST_STR \ "(spp_arpspoof) Ethernet/ARP Mismatch request for Destination" #define ARPSPOOF_ARP_CACHE_OVERWRITE_ATTACK_STR \ "(spp_arpspoof) Attempted ARP cache overwrite attack" #define BO_TRAFFIC_DETECT_STR "(spo_bo) Back Orifice Traffic detected" #define BO_CLIENT_TRAFFIC_DETECT_STR "(spo_bo) Back Orifice Client Traffic detected" #define BO_SERVER_TRAFFIC_DETECT_STR "(spo_bo) Back Orifice Server Traffic detected" #define BO_SNORT_BUFFER_ATTACK_STR "(spo_bo) Back Orifice Snort buffer attack" /* FRAG3 strings */ #define FRAG3_IPOPTIONS_STR "(spp_frag3) Inconsistent IP Options on Fragmented Packets" #define FRAG3_TEARDROP_STR "(spp_frag3) Teardrop attack" #define FRAG3_SHORT_FRAG_STR "(spp_frag3) Short fragment, possible DoS attempt" #define FRAG3_ANOM_OVERSIZE_STR "(spp_frag3) Fragment packet ends after defragmented packet" #define FRAG3_ANOM_ZERO_STR "(spp_frag3) Zero-byte fragment packet" #define FRAG3_ANOM_BADSIZE_SM_STR "(spp_frag3) Bad fragment size, packet size is negative" #define FRAG3_ANOM_BADSIZE_LG_STR "(spp_frag3) Bad fragment size, packet size is greater than 65536" #define FRAG3_ANOM_OVLP_STR "(spp_frag3) Fragmentation overlap" /* 123:9, 123:10 are OBE w/ addition of 116:458 * (aka DECODE_IPV6_BAD_FRAG_PKT). * Leave these here so they are not reused. * ------ #define FRAG3_IPV6_BSD_ICMP_FRAG_STR "(spp_frag3) IPv6 BSD mbufs remote kernel buffer overflow" #define FRAG3_IPV6_BAD_FRAG_PKT_STR "(spp_frag3) Bogus fragmentation packet. Possible BSD attack" * ------ */ #define FRAG3_MIN_TTL_EVASION_STR "(spp_frag3) TTL value less than configured minimum, not using for reassembly" #define FRAG3_EXCESSIVE_OVERLAP_STR "(spp_frag3) Excessive fragment overlap" #define FRAG3_TINY_FRAGMENT_STR "(spp_frag3) Tiny fragment" /* Stream strings */ #define STREAM_SYN_ON_EST_STR "Syn on established session" #define STREAM_DATA_ON_SYN_STR "Data on SYN packet" #define STREAM_DATA_ON_CLOSED_STR "Data sent on stream not accepting data" #define STREAM_BAD_TIMESTAMP_STR "TCP Timestamp is outside of PAWS window" #define STREAM_BAD_SEGMENT_STR "Bad segment, adjusted size <= 0" #define STREAM_WINDOW_TOO_LARGE_STR "Window size (after scaling) larger than policy allows" #define STREAM_EXCESSIVE_TCP_OVERLAPS_STR "Limit on number of overlapping TCP packets reached" #define STREAM_DATA_AFTER_RESET_STR "Data sent on stream after TCP Reset sent" #define STREAM_SESSION_HIJACKED_CLIENT_STR "TCP Client possibly hijacked, different Ethernet Address" #define STREAM_SESSION_HIJACKED_SERVER_STR "TCP Server possibly hijacked, different Ethernet Address" #define STREAM_DATA_WITHOUT_FLAGS_STR "TCP Data with no TCP Flags set" #define STREAM_SMALL_SEGMENT_STR "Consecutive TCP small segments exceeding threshold" #define STREAM_4WAY_HANDSHAKE_STR "4-way handshake detected" #define STREAM_NO_TIMESTAMP_STR "TCP Timestamp is missing" #define STREAM_BAD_RST_STR "Reset outside window" #define STREAM_BAD_FIN_STR "FIN number is greater than prior FIN" #define STREAM_BAD_ACK_STR "ACK number is greater than prior FIN" #define STREAM_DATA_AFTER_RST_RCVD_STR "Data sent on stream after TCP Reset received" #define STREAM_WINDOW_SLAM_STR "TCP window closed before receiving data" #define STREAM_NO_3WHS_STR "TCP session without 3-way handshake" #define STREAM_INTERNAL_EVENT_STR "" /* PPM strings */ #define PPM_EVENT_RULE_TREE_DISABLED_STR "PPM Rule Options Disabled by Rule Latency" #define PPM_EVENT_RULE_TREE_ENABLED_STR "PPM Rule Options Re-enabled by Rule Latency" #define PPM_EVENT_PACKET_ABORTED_STR "PPM Packet Aborted due to Latency" /* Snort decoder strings */ #define DECODE_NOT_IPV4_DGRAM_STR "(snort_decoder) WARNING: Not IPv4 datagram" #define DECODE_IPV4_INVALID_HEADER_LEN_STR "(snort_decoder) WARNING: hlen < IP_HEADER_LEN" #define DECODE_IPV4_DGRAM_LT_IPHDR_STR "(snort_decoder) WARNING: IP dgm len < IP Hdr len" #define DECODE_IPV4OPT_BADLEN_STR "(snort_decoder) WARNING: Ipv4 Options found with bad lengths" #define DECODE_IPV4OPT_TRUNCATED_STR "(snort_decoder) WARNING: Truncated Ipv4 Options" #define DECODE_IPV4_DGRAM_GT_CAPLEN_STR "(snort_decoder) WARNING: IP dgm len > captured len" #define DECODE_NOT_IPV6_DGRAM_STR "(snort_decoder) WARNING: Not an IPv6 datagram" #define DECODE_TCP_DGRAM_LT_TCPHDR_STR "(snort_decoder) WARNING: TCP packet len is smaller than 20 bytes" #define DECODE_TCP_INVALID_OFFSET_STR "(snort_decoder) WARNING: TCP Data Offset is less than 5" #define DECODE_TCP_LARGE_OFFSET_STR "(snort_decoder) WARNING: TCP Header length exceeds packet length" #define DECODE_TCPOPT_BADLEN_STR "(snort_decoder) WARNING: Tcp Options found with bad lengths" #define DECODE_TCPOPT_TRUNCATED_STR "(snort_decoder) WARNING: Truncated Tcp Options" #define DECODE_TCPOPT_TTCP_STR "(snort_decoder) WARNING: T/TCP Detected" #define DECODE_TCPOPT_OBSOLETE_STR "(snort_decoder) WARNING: Obsolete TCP Options found" #define DECODE_TCPOPT_EXPERIMENT_STR "(snort_decoder) WARNING: Experimental Tcp Options found" #define DECODE_TCPOPT_WSCALE_INVALID_STR "(snort_decoder) WARNING: Tcp Window Scale Option found with length > 14" #define DECODE_UDP_DGRAM_LT_UDPHDR_STR "(snort_decoder) WARNING: Truncated UDP Header" #define DECODE_UDP_DGRAM_INVALID_LENGTH_STR "(snort_decoder) WARNING: Invalid UDP header, length field < 8" #define DECODE_UDP_DGRAM_SHORT_PACKET_STR "(snort_decoder) WARNING: Short UDP packet, length field > payload length" #define DECODE_UDP_DGRAM_LONG_PACKET_STR "(snort_decoder) WARNING: Long UDP packet, length field < payload length" #define DECODE_ICMP_DGRAM_LT_ICMPHDR_STR "(snort_decoder) WARNING: ICMP Header Truncated" #define DECODE_ICMP_DGRAM_LT_TIMESTAMPHDR_STR "(snort_decoder) WARNING: ICMP Timestamp Header Truncated" #define DECODE_ICMP_DGRAM_LT_ADDRHDR_STR "(snort_decoder) WARNING: ICMP Address Header Truncated" #define DECODE_IPV4_DGRAM_UNKNOWN_STR "(snort_decoder) WARNING: Unknown Datagram decoding problem" #define DECODE_ARP_TRUNCATED_STR "(snort_decoder) WARNING: Truncated ARP" #define DECODE_EAPOL_TRUNCATED_STR "(snort_decoder) WARNING: Truncated EAP Header" #define DECODE_EAPKEY_TRUNCATED_STR "(snort_decoder) WARNING: EAP Key Truncated" #define DECODE_EAP_TRUNCATED_STR "(snort_decoder) WARNING: EAP Header Truncated" #define DECODE_BAD_PPPOE_STR "(snort_decoder) WARNING: Bad PPPOE frame detected" #define DECODE_BAD_VLAN_STR "(snort_decoder) WARNING: Bad VLAN Frame" #define DECODE_BAD_VLAN_ETHLLC_STR "(snort_decoder) WARNING: Bad LLC header" #define DECODE_BAD_VLAN_OTHER_STR "(snort_decoder) WARNING: Bad Extra LLC Info" #define DECODE_BAD_80211_ETHLLC_STR "(snort_decoder) WARNING: Bad 802.11 LLC header" #define DECODE_BAD_80211_OTHER_STR "(snort_decoder) WARNING: Bad 802.11 Extra LLC Info" #define DECODE_BAD_TRH_STR "(snort_decoder) WARNING: Bad Token Ring Header" #define DECODE_BAD_TR_ETHLLC_STR "(snort_decoder) WARNING: Bad Token Ring ETHLLC Header" #define DECODE_BAD_TR_MR_LEN_STR "(snort_decoder) WARNING: Bad Token Ring MRLENHeader" #define DECODE_BAD_TRHMR_STR "(snort_decoder) WARNING: Bad Token Ring MR Header" #define DECODE_BAD_TRAFFIC_LOOPBACK_STR "(snort decoder) WARNING: Bad Traffic Loopback IP" #define DECODE_BAD_TRAFFIC_SAME_SRCDST_STR "(snort decoder) WARNING: Bad Traffic Same Src/Dst IP" #ifdef GRE #define DECODE_GRE_DGRAM_LT_GREHDR_STR "(snort decoder) WARNING: GRE header length > payload length" #define DECODE_GRE_MULTIPLE_ENCAPSULATION_STR "(snort decoder) WARNING: Multiple encapsulations in packet" #define DECODE_GRE_INVALID_VERSION_STR "(snort decoder) WARNING: Invalid GRE version" #define DECODE_GRE_INVALID_HEADER_STR "(snort decoder) WARNING: Invalid GRE header" #define DECODE_GRE_V1_INVALID_HEADER_STR "(snort decoder) WARNING: Invalid GRE v.1 PPTP header" #define DECODE_GRE_TRANS_DGRAM_LT_TRANSHDR_STR "(snort decoder) WARNING: GRE Trans header length > payload length" #endif /* GRE */ #define DECODE_ICMP_ORIG_IP_TRUNCATED_STR "(snort_decoder) WARNING: ICMP Original IP Header Truncated" #define DECODE_ICMP_ORIG_IP_VER_MISMATCH_STR "(snort_decoder) WARNING: ICMP version and Original IP Header versions differ" #define DECODE_ICMP_ORIG_DGRAM_LT_ORIG_IP_STR "(snort_decoder) WARNING: ICMP Original Datagram Length < Original IP Header Length" #define DECODE_ICMP_ORIG_PAYLOAD_LT_64_STR "(snort_decoder) WARNING: ICMP Original IP Payload < 64 bits" #define DECODE_ICMP_ORIG_PAYLOAD_GT_576_STR "(snort_decoder) WARNING: ICMP Origianl IP Payload > 576 bytes" #define DECODE_ICMP_ORIG_IP_WITH_FRAGOFFSET_STR "(snort_decoder) WARNING: ICMP Original IP Fragmented and Offset Not 0" #define DECODE_IPV6_MIN_TTL_STR "(snort decoder) WARNING: IPv6 packet below TTL limit" #define DECODE_IPV6_IS_NOT_STR "(snort decoder) WARNING: IPv6 header claims to not be IPv6" #define DECODE_IPV6_TRUNCATED_EXT_STR "(snort decoder) WARNING: IPV6 truncated extension header" #define DECODE_IPV6_TRUNCATED_STR "(snort decoder) WARNING: IPV6 truncated header" #define DECODE_IPV6_DGRAM_LT_IPHDR_STR "(snort_decoder) WARNING: IP dgm len < IP Hdr len" #define DECODE_IPV6_DGRAM_GT_CAPLEN_STR "(snort_decoder) WARNING: IP dgm len > captured len" #define DECODE_IPV6_DST_ZERO_STR "(snort_decoder) WARNING: IPv6 packet with destination address ::0" #define DECODE_IPV6_SRC_MULTICAST_STR "(snort_decoder) WARNING: IPv6 packet with multicast source address" #define DECODE_IPV6_DST_RESERVED_MULTICAST_STR "(snort_decoder) WARNING: IPv6 packet with reserved multicast destination address" #define DECODE_IPV6_BAD_OPT_TYPE_STR "(snort_decoder) WARNING: IPv6 header includes an undefined option type" #define DECODE_IPV6_BAD_MULTICAST_SCOPE_STR "(snort_decoder) WARNING: IPv6 address includes an unassigned multicast scope value" #define DECODE_IPV6_BAD_NEXT_HEADER_STR "(snort_decoder) WARNING: IPv6 header includes an invalid value for the \"next header\" field" #define DECODE_IPV6_ROUTE_AND_HOPBYHOP_STR "(snort_decoder) WARNING: IPv6 header includes a routing extension header followed by a hop-by-hop header" #define DECODE_IPV6_TWO_ROUTE_HEADERS_STR "(snort_decoder) WARNING: IPv6 header includes two routing extension headers" #define DECODE_IPV6_DSTOPTS_WITH_ROUTING_STR "(snort_decoder) WARNING: IPv6 header has destination options followed by a routing header" #define DECODE_ICMPV6_TOO_BIG_BAD_MTU_STR "(snort_decoder) WARNING: ICMPv6 packet of type 2 (message too big) with MTU field < 1280" #define DECODE_ICMPV6_UNREACHABLE_NON_RFC_2463_CODE_STR "(snort_decoder) WARNING: ICMPv6 packet of type 1 (destination unreachable) with non-RFC 2463 code" #define DECODE_ICMPV6_SOLICITATION_BAD_CODE_STR "(snort_decoder) WARNING: ICMPv6 router solicitation packet with a code not equal to 0" #define DECODE_ICMPV6_ADVERT_BAD_CODE_STR "(snort_decoder) WARNING: ICMPv6 router advertisement packet with a code not equal to 0" #define DECODE_ICMPV6_SOLICITATION_BAD_RESERVED_STR "(snort_decoder) WARNING: ICMPv6 router solicitation packet with the reserved field not equal to 0" #define DECODE_ICMPV6_ADVERT_BAD_REACHABLE_STR "(snort_decoder) WARNING: ICMPv6 router advertisement packet with the reachable time field set > 1 hour" #define DECODE_IPV6_TUNNELED_IPV4_TRUNCATED_STR "(snort_decoder) WARNING: IPV6 tunneled over IPv4, IPv6 header truncated, possible Linux Kernel attack" #define DECODE_IP_MULTIPLE_ENCAPSULATION_STR "(snort_decoder) WARNING: Two or more IP (v4 and/or v6) encapsulation layers present" #define DECODE_ESP_HEADER_TRUNC_STR "(snort_decoder) WARNING: truncated Encapsulated Security Payload (ESP) header" #define DECODE_IPV6_BAD_OPT_LEN_STR "(snort_decoder) WARNING: IPv6 header includes an option which is too big for the containing header" #define DECODE_IPV6_UNORDERED_EXTENSIONS_STR "(snort_decoder) WARNING: IPv6 packet includes out-of-order extension headers" #define DECODE_GTP_MULTIPLE_ENCAPSULATION_STR "(snort_decoder) WARNING: Two or more GTP encapsulation layers present" #define DECODE_GTP_BAD_LEN_STR "(snort_decoder) WARNING: GTP header length is invalid" #define DECODE_TCP_XMAS_STR "(snort_decoder) WARNING: XMAS Attack Detected" #define DECODE_TCP_NMAP_XMAS_STR "(snort_decoder) WARNING: Nmap XMAS Attack Detected" #define DECODE_DOS_NAPTHA_STR "(snort_decoder) WARNING: DOS NAPTHA Vulnerability Detected" #define DECODE_SYN_TO_MULTICAST_STR "(snort_decoder) WARNING: Bad Traffic SYN to multicast address" #define DECODE_ZERO_TTL_STR "(snort_decoder) WARNING: IPV4 packet with zero TTL" #define DECODE_BAD_FRAGBITS_STR "(snort_decoder) WARNING: IPV4 packet with bad frag bits (Both MF and DF set)" #define DECODE_UDP_IPV6_ZERO_CHECKSUM_STR "(snort_decoder) WARNING: Invalid IPv6 UDP packet, checksum zero" #define DECODE_IP4_LEN_OFFSET_STR "(snort_decoder) WARNING: IPV4 packet frag offset + length exceed maximum" #define DECODE_IP4_SRC_THIS_NET_STR "(snort_decoder) WARNING: IPV4 packet from 'current net' source address" #define DECODE_IP4_DST_THIS_NET_STR "(snort_decoder) WARNING: IPV4 packet to 'current net' dest address" #define DECODE_IP4_SRC_MULTICAST_STR "(snort_decoder) WARNING: IPV4 packet from multicast source address" #define DECODE_IP4_SRC_RESERVED_STR "(snort_decoder) WARNING: IPV4 packet from reserved source address" #define DECODE_IP4_DST_RESERVED_STR "(snort_decoder) WARNING: IPV4 packet to reserved dest address" #define DECODE_IP4_SRC_BROADCAST_STR "(snort_decoder) WARNING: IPV4 packet from broadcast source address" #define DECODE_IP4_DST_BROADCAST_STR "(snort_decoder) WARNING: IPV4 packet to broadcast dest address" #define DECODE_ICMP4_DST_MULTICAST_STR "(snort_decoder) WARNING: ICMP4 packet to multicast dest address" #define DECODE_ICMP4_DST_BROADCAST_STR "(snort_decoder) WARNING: ICMP4 packet to broadcast dest address" #define DECODE_ICMP4_TYPE_OTHER_STR "(snort_decoder) WARNING: ICMP4 type other" #define DECODE_TCP_BAD_URP_STR "(snort_decoder) WARNING: TCP urgent pointer exceeds payload length or no payload" #define DECODE_TCP_SYN_FIN_STR "(snort_decoder) WARNING: TCP SYN with FIN" #define DECODE_TCP_SYN_RST_STR "(snort_decoder) WARNING: TCP SYN with RST" #define DECODE_TCP_MUST_ACK_STR "(snort_decoder) WARNING: TCP PDU missing ack for established session" #define DECODE_TCP_NO_SYN_ACK_RST_STR "(snort_decoder) WARNING: TCP has no SYN, ACK, or RST" #define DECODE_ETH_HDR_TRUNC_STR "(snort_decoder) WARNING: truncated eth header" #define DECODE_IP4_HDR_TRUNC_STR "(snort_decoder) WARNING: truncated IP4 header" #define DECODE_ICMP4_HDR_TRUNC_STR "(snort_decoder) WARNING: truncated ICMP4 header" #define DECODE_ICMP6_HDR_TRUNC_STR "(snort_decoder) WARNING: truncated ICMP6 header" #define DECODE_IP4_MIN_TTL_STR "(snort decoder) WARNING: IPV4 packet below TTL limit" #define DECODE_IP6_ZERO_HOP_LIMIT_STR "(snort decoder) WARNING: IPV6 packet has zero hop limit" #define DECODE_IP4_DF_OFFSET_STR "(snort_decoder) WARNING: IPV4 packet both DF and offset set" #define DECODE_ICMP6_TYPE_OTHER_STR "(snort_decoder) WARNING: ICMP6 type not decoded" #define DECODE_ICMP6_DST_MULTICAST_STR "(snort_decoder) WARNING: ICMP6 packet to multicast address" #define DECODE_TCP_SHAFT_SYNFLOOD_STR "(snort_decoder) WARNING: DDOS shaft synflood" #define DECODE_ICMP_PING_NMAP_STR "(snort_decoder) WARNING: ICMP PING NMAP" #define DECODE_ICMP_ICMPENUM_STR "(snort_decoder) WARNING: ICMP icmpenum v1.1.1" #define DECODE_ICMP_REDIRECT_HOST_STR "(snort_decoder) WARNING: ICMP redirect host" #define DECODE_ICMP_REDIRECT_NET_STR "(snort_decoder) WARNING: ICMP redirect net" #define DECODE_ICMP_TRACEROUTE_IPOPTS_STR "(snort_decoder) WARNING: ICMP traceroute ipopts" #define DECODE_ICMP_SOURCE_QUENCH_STR "(snort_decoder) WARNING: ICMP Source Quench" #define DECODE_ICMP_BROADSCAN_SMURF_SCANNER_STR "(snort_decoder) WARNING: Broadscan Smurf Scanner" #define DECODE_ICMP_DST_UNREACH_ADMIN_PROHIBITED_STR "(snort_decoder) WARNING: ICMP Destination Unreachable Communication Administratively Prohibited" #define DECODE_ICMP_DST_UNREACH_DST_HOST_PROHIBITED_STR "(snort_decoder) WARNING: ICMP Destination Unreachable Communication with Destination Host is Administratively Prohibited" #define DECODE_ICMP_DST_UNREACH_DST_NET_PROHIBITED_STR "(snort_decoder) WARNING: ICMP Destination Unreachable Communication with Destination Network is Administratively Prohibited" #define DECODE_IP_OPTION_SET_STR "(snort_decoder) WARNING: MISC IP option set" #define DECODE_UDP_LARGE_PACKET_STR "(snort_decoder) WARNING: MISC Large UDP Packet" #define DECODE_TCP_PORT_ZERO_STR "(snort_decoder) WARNING: BAD-TRAFFIC TCP port 0 traffic" #define DECODE_UDP_PORT_ZERO_STR "(snort_decoder) WARNING: BAD-TRAFFIC UDP port 0 traffic" #define DECODE_IP_RESERVED_FRAG_BIT_STR "(snort_decoder) WARNING: BAD-TRAFFIC IP reserved bit set" #define DECODE_IP_UNASSIGNED_PROTO_STR "(snort_decoder) WARNING: BAD-TRAFFIC Unassigned/Reserved IP protocol" #define DECODE_IP_BAD_PROTO_STR "(snort_decoder) WARNING: BAD-TRAFFIC Bad IP protocol" #define DECODE_ICMP_PATH_MTU_DOS_STR "(snort_decoder) WARNING: ICMP PATH MTU denial of service attempt" #define DECODE_ICMP_DOS_ATTEMPT_STR "(snort_decoder) WARNING: BAD-TRAFFIC linux ICMP header dos attempt" #define DECODE_IPV6_ISATAP_SPOOF_STR "(snort_decoder) WARNING: BAD-TRAFFIC ISATAP-addressed IPv6 traffic spoofing attempt" #define DECODE_PGM_NAK_OVERFLOW_STR "(snort_decoder) WARNING: BAD-TRAFFIC PGM nak list overflow attempt" #define DECODE_IGMP_OPTIONS_DOS_STR "(snort_decoder) WARNING: DOS IGMP IP Options validation attempt" #define DECODE_IP6_EXCESS_EXT_HDR_STR "(snort_decoder) WARNING: too many IP6 extension headers" #define DECODE_ICMPV6_UNREACHABLE_NON_RFC_4443_CODE_STR "(snort_decoder) WARNING: ICMPv6 packet of type 1 (destination unreachable) with non-RFC 4443 code" #define DECODE_IPV6_BAD_FRAG_PKT_STR "(snort_decoder) WARNING: bogus fragmentation packet. Possible BSD attack" #define DECODE_ZERO_LENGTH_FRAG_STR "(snort_decoder) WARNING: fragment with zero length" #define DECODE_ICMPV6_NODE_INFO_BAD_CODE_STR "(snort_decoder) WARNING: ICMPv6 node info query/response packet with a code greater than 2" #define DECODE_IPV6_ROUTE_ZERO_STR "(snort decoder) WARNING: IPV6 routing type 0 extension header" #define DECODE_ERSPAN_HDR_VERSION_MISMATCH_STR "(snort_decoder) WARNING: ERSpan Header version mismatch" #define DECODE_ERSPAN2_DGRAM_LT_HDR_STR "(snort_decoder) WARNING: captured < ERSpan Type2 Header Length" #define DECODE_ERSPAN3_DGRAM_LT_HDR_STR "(snort_decoder) WARNING: captured < ERSpan Type3 Header Length" #define DECODE_AUTH_HDR_TRUNC_STR "(snort_decoder) WARNING: truncated authentication header" #define DECODE_AUTH_HDR_BAD_LEN_STR "(snort_decoder) WARNING: authentication header bad length" #define DECODE_FPATH_HDR_TRUNC_STR "(snort_decoder) WARNING: truncated FabricPath header" #define DECODE_CISCO_META_HDR_TRUNC_STR "(snort_decoder) WARNING: truncated Cisco Metadata header" #define DECODE_CISCO_META_HDR_OPT_LEN_STR "(snort_decoder) WARNING: Invalid Cisco Metadata option length" #define DECODE_CISCO_META_HDR_OPT_TYPE_STR "(snort_decoder) WARNING: Invalid Cisco Metadata option type" #define DECODE_CISCO_META_HDR_SGT_STR "(snort_decoder) WARNING: Invalid Cisco Metadata SGT" /* RPC decode preprocessor strings */ #define RPC_FRAG_TRAFFIC_STR "(spp_rpc_decode) Fragmented RPC Records" #define RPC_MULTIPLE_RECORD_STR "(spp_rpc_decode) Multiple RPC Records" #define RPC_LARGE_FRAGSIZE_STR "(spp_rpc_decode) Large RPC Record Fragment" #define RPC_INCOMPLETE_SEGMENT_STR "(spp_rpc_decode) Incomplete RPC segment" #define RPC_ZERO_LENGTH_FRAGMENT_STR "(spp_rpc_decode) Zero-length RPC Fragment" #define PSNG_TCP_PORTSCAN_STR "(portscan) TCP Portscan" #define PSNG_TCP_DECOY_PORTSCAN_STR "(portscan) TCP Decoy Portscan" #define PSNG_TCP_PORTSWEEP_STR "(portscan) TCP Portsweep" #define PSNG_TCP_DISTRIBUTED_PORTSCAN_STR "(portscan) TCP Distributed Portscan" #define PSNG_TCP_FILTERED_PORTSCAN_STR "(portscan) TCP Filtered Portscan" #define PSNG_TCP_FILTERED_DECOY_PORTSCAN_STR "(portscan) TCP Filtered Decoy Portscan" #define PSNG_TCP_FILTERED_DISTRIBUTED_PORTSCAN_STR "(portscan) TCP Filtered Distributed Portscan" #define PSNG_TCP_PORTSWEEP_FILTERED_STR "(portscan) TCP Filtered Portsweep" #define PSNG_IP_PORTSCAN_STR "(portscan) IP Protocol Scan" #define PSNG_IP_DECOY_PORTSCAN_STR "(portscan) IP Decoy Protocol Scan" #define PSNG_IP_PORTSWEEP_STR "(portscan) IP Protocol Sweep" #define PSNG_IP_DISTRIBUTED_PORTSCAN_STR "(portscan) IP Distributed Protocol Scan" #define PSNG_IP_FILTERED_PORTSCAN_STR "(portscan) IP Filtered Protocol Scan" #define PSNG_IP_FILTERED_DECOY_PORTSCAN_STR "(portscan) IP Filtered Decoy Protocol Scan" #define PSNG_IP_FILTERED_DISTRIBUTED_PORTSCAN_STR "(portscan) IP Filtered Distributed Protocol Scan" #define PSNG_IP_PORTSWEEP_FILTERED_STR "(portscan) IP Filtered Protocol Sweep" #define PSNG_UDP_PORTSCAN_STR "(portscan) UDP Portscan" #define PSNG_UDP_DECOY_PORTSCAN_STR "(portscan) UDP Decoy Portscan" #define PSNG_UDP_PORTSWEEP_STR "(portscan) UDP Portsweep" #define PSNG_UDP_DISTRIBUTED_PORTSCAN_STR "(portscan) UDP Distributed Portscan" #define PSNG_UDP_FILTERED_PORTSCAN_STR "(portscan) UDP Filtered Portscan" #define PSNG_UDP_FILTERED_DECOY_PORTSCAN_STR "(portscan) UDP Filtered Decoy Portscan" #define PSNG_UDP_FILTERED_DISTRIBUTED_PORTSCAN_STR "(portscan) UDP Filtered Distributed Portscan" #define PSNG_UDP_PORTSWEEP_FILTERED_STR "(portscan) UDP Filtered Portsweep" #define PSNG_ICMP_PORTSWEEP_STR "(portscan) ICMP Sweep" #define PSNG_ICMP_PORTSWEEP_FILTERED_STR "(portscan) ICMP Filtered Sweep" #define PSNG_OPEN_PORT_STR "(portscan) Open Port" #define DECODE_BAD_MPLS_STR "(snort_decoder) WARNING: Bad MPLS Frame" #define DECODE_BAD_MPLS_LABEL0_STR "(snort_decoder) WARNING: MPLS Label 0 Appears in Nonbottom Header" #define DECODE_BAD_MPLS_LABEL1_STR "(snort_decoder) WARNING: MPLS Label 1 Appears in Bottom Header" #define DECODE_BAD_MPLS_LABEL2_STR "(snort_decoder) WARNING: MPLS Label 2 Appears in Nonbottom Header" #define DECODE_BAD_MPLS_LABEL3_STR "(snort_decoder) WARNING: MPLS Label 3 Appears in Header" #define DECODE_MPLS_RESERVEDLABEL_STR "(snort_decoder) WARNING: MPLS Label 4, 5,.. or 15 Appears in Header" #define DECODE_MPLS_LABEL_STACK_STR "(snort_decoder) WARNING: Too Many MPLS headers" #define DECODE_MULTICAST_MPLS_STR "(snort_decoder) WARNING: Multicast MPLS traffic detected" #endif /* __GENERATORS_H__ */ snort-2.9.15.1/src/sf_protocols.h0000644000175200017520000001212113571422607013521 00000000000000/* $Id$ */ /**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2005-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #ifndef __SF_PROTOCOLS_H__ #define __SF_PROTOCOLS_H__ typedef uint8_t IpProto; typedef enum { PROTO_ETH, /* DecodeEthPkt */ PROTO_FPATH, /* FabricPath - handled by DecodeEthPkt */ PROTO_CISCO_META, /* Cisco Metadata - handled by DecodeEthPkt */ PROTO_IP4, /* DecodeIP */ /* DecodeIPOptions - handled with IP4 */ PROTO_ICMP4, /* DecodeICMP */ PROTO_ICMP_IP4, /* DecodeICMPEmbeddedIP */ PROTO_UDP, /* DecodeUDP */ PROTO_TCP, /* DecodeTCP */ /* DecodeTCPOptions - handled with TCP */ PROTO_IP6, /* DecodeIPV6 */ /* DecodeIPV6Extensions - nothing to do here, calls below */ PROTO_IP6_HOP_OPTS, /* DecodeIPV6Options - ip6 hop, dst, rte, and frag exts */ PROTO_IP6_DST_OPTS, PROTO_ICMP6, /* DecodeICMP6 */ PROTO_ICMP_IP6, /* DecodeICMPEmbeddedIP6 */ PROTO_VLAN, /* DecodeVlan */ #ifdef GRE PROTO_GRE, /* DecodeGRE */ /* DecodeTransBridging - basically same as DecodeEthPkt */ PROTO_ERSPAN, /* DecodeERSPANType2 and DecodeERSPANType3 */ #endif PROTO_PPPOE, /* DecodePPPoEPkt */ PROTO_PPP_ENCAP, /* DecodePppPktEncapsulated */ PROTO_MPLS, /* DecodeMPLS - decoder changes pkth len/caplen! */ /* DecodeEthOverMPLS - basically same as straight eth */ PROTO_ARP, /* DecodeARP */ PROTO_GTP, /* DecodeGTP */ PROTO_AH, /* DecodeAH - Authentication Header (IPSec stuff) */ #ifndef NO_NON_ETHER_DECODER PROTO_TR, /* DecodeTRPkt */ PROTO_FDDI, /* DecodeFDDIPkt */ PROTO_LSLL, /* DecodeLinuxSLLPkt sockaddr_ll for "any" device and */ /* certain misbehaving link layer encapsulations */ PROTO_80211, /* DecodeIEEE80211Pkt */ PROTO_SLIP, /* DecodeSlipPkt - actually, based on header size, this */ /* must be CSLIP (TCP/IP header compression) but all it */ /* does is skip over the presumed header w/o expanding */ /* and then jumps into IP4 decoding only; also, the actual */ /* esc/end sequences must already have been removed because */ /* there is no attempt to do that. */ PROTO_L2I4, /* DecodeI4LRawIPPkt - always skips 2 bytes and then does */ /* IP4 decoding only */ PROTO_L2I4C, /* DecodeI4LCiscoIPPkt -always skips 4 bytes and then does */ /* IP4 decoding only */ PROTO_CHDLC, /* DecodeChdlcPkt - skips 4 bytes and decodes IP4 only. */ PROTO_PFLOG, /* DecodePflog */ PROTO_OLD_PFLOG, /* DecodeOldPflog */ PROTO_PPP, /* DecodePppPkt - weird - optionally skips addr and cntl */ /* bytes; what about flag and protocol? */ /* calls only DecodePppPktEncapsulated. */ PROTO_PPP_SERIAL, /* DecodePppSerialPkt - also weird - requires addr, cntl, */ /* and proto (no flag) but optionally skips only 2 bytes */ /* (presumably the trailer w/chksum is already stripped) */ /* Calls either DecodePppPktEncapsulated or DecodeChdlcPkt. */ PROTO_ENC, /* DecodeEncPkt - skips 12 bytes and decodes IP4 only. */ /* (add family + "spi" + "flags" - don't know what this is) */ PROTO_EAP, /* DecodeEAP */ PROTO_EAPOL, /* DecodeEapol - leaf decoder */ PROTO_EAPOL_KEY, /* DecodeEapolKey - leaf decoder */ #endif /* NO_NON_ETHER_DECODER */ PROTO_MAX } PROTO_ID; /* DecodeIPX - just counts; no decoding */ /* DecodeEthLoopback - same as ipx */ /* DecodeRawPkt - jumps straight into IP4 decoding */ /* there is nothing to do */ /* DecodeNullPkt - same as DecodeRawPkt */ typedef struct { PROTO_ID proto; uint16_t length; uint8_t* start; } Layer; #endif /* __PROTOCOLS_H__ */ snort-2.9.15.1/src/plugin_enum.h0000644000175200017520000000421713571422607013336 00000000000000/* $Id$ */ /**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2003-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* Purpose: Enumerate all the various detection plugins entries for otn->ds_list[] No more grepping to make your own plugin! */ #ifndef _PLUGIN_ENUM_H #define _PLUGIN_ENUM_H enum { PLUGIN_CLIENTSERVER, PLUGIN_DSIZE_CHECK, PLUGIN_FRAG_BITS, PLUGIN_FRAG_OFFSET, PLUGIN_ICMP_CODE, PLUGIN_ICMP_ID_CHECK, PLUGIN_ICMP_SEQ_CHECK, PLUGIN_ICMP_TYPE, PLUGIN_IPOPTION_CHECK, PLUGIN_IP_ID_CHECK, PLUGIN_IP_PROTO_CHECK, PLUGIN_IP_SAME_CHECK, PLUGIN_IP_TOS_CHECK, PLUGIN_PATTERN_MATCH, /* AND match */ PLUGIN_PATTERN_MATCH_OR, PLUGIN_PATTERN_MATCH_URI, PLUGIN_RESPONSE, PLUGIN_RPC_CHECK, PLUGIN_SESSION, PLUGIN_TCP_ACK_CHECK, PLUGIN_TCP_FLAG_CHECK, PLUGIN_TCP_SEQ_CHECK, PLUGIN_TCP_WIN_CHECK, PLUGIN_TTL_CHECK, PLUGIN_BYTE_TEST, PLUGIN_PCRE, PLUGIN_URILEN_CHECK, PLUGIN_DYNAMIC, PLUGIN_FLOWBIT, PLUGIN_FILE_DATA, PLUGIN_BASE64_DECODE, #if defined(FEAT_OPEN_APPID) PLUGIN_APPID, #endif /* defined(FEAT_OPEN_APPID) */ PLUGIN_MAX /* sentinel value */ }; #endif /* _PLUGIN_ENUM_H */ snort-2.9.15.1/src/rules.h0000644000175200017520000001055413571422607012147 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifndef __RULES_H__ #define __RULES_H__ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "event.h" #include "decode.h" #include "signature.h" #include "parser/IpAddrSet.h" #include "spo_plugbase.h" #include "sf_vartable.h" #include "sf_types.h" #include "plugin_enum.h" #include "sfutil/sfportobject.h" #include "detection_options.h" #define EXCEPT_SRC_IP 0x01 #define EXCEPT_DST_IP 0x02 #define ANY_SRC_PORT 0x04 #define ANY_DST_PORT 0x08 #define ANY_FLAGS 0x10 #define EXCEPT_SRC_PORT 0x20 #define EXCEPT_DST_PORT 0x40 #define BIDIRECTIONAL 0x80 #define ANY_SRC_IP 0x100 #define ANY_DST_IP 0x200 #define EXCEPT_IP 0x01 #define R_FIN 0x01 #define R_SYN 0x02 #define R_RST 0x04 #define R_PSH 0x08 #define R_ACK 0x10 #define R_URG 0x20 #define R_ECE 0x40 /* ECN echo, RFC 3168 */ #define R_CWR 0x80 /* Congestion Window Reduced, RFC 3168 */ #define MODE_EXIT_ON_MATCH 0 #define MODE_FULL_SEARCH 1 #define CHECK_SRC_IP 0x01 #define CHECK_DST_IP 0x02 #define INVERSE 0x04 #define CHECK_SRC_PORT 0x08 #define CHECK_DST_PORT 0x10 #define SESSION_PRINTABLE 1 #define SESSION_ALL 2 #define MODE_EXIT_ON_MATCH 0 #define MODE_FULL_SEARCH 1 #define SRC 0 #define DST 1 #ifndef PARSERULE_SIZE #define PARSERULE_SIZE 65535 #endif /* D A T A S T R U C T U R E S *********************************************/ /* I'm forward declaring the rules structures so that the function pointer lists can reference them internally */ struct _ListHead; /* forward decleartion of ListHead data struct */ typedef enum _RuleType { RULE_TYPE__NONE = 0, RULE_TYPE__ALERT, RULE_TYPE__DROP, RULE_TYPE__LOG, RULE_TYPE__PASS, RULE_TYPE__REJECT, RULE_TYPE__SDROP, RULE_TYPE__MAX } RuleType; #ifndef f_ptr #define f_ptr fptr.fptr #endif #ifndef vf_ptr #define vf_ptr fptr.void_fptr #endif typedef struct _RspFpList { union { int (*fptr)(Packet*, void*); void *vfptr; } fptr; void *params; /* params for the plugin.. type defined by plugin */ struct _RspFpList *next; } RspFpList; typedef struct _TagData { int tag_type; /* tag type (session/host) */ int tag_seconds; /* number of "seconds" units to tag for */ int tag_packets; /* number of "packets" units to tag for */ int tag_bytes; /* number of "type" units to tag for */ int tag_metric; /* (packets | seconds | bytes) units */ int tag_direction; /* source or dest, used for host tagging */ } TagData; struct _RuleListNode; typedef struct _ListHead { struct _OutputFuncNode *LogList; struct _OutputFuncNode *AlertList; struct _RuleListNode *ruleListNode; } ListHead; typedef struct _RuleListNode { ListHead *RuleList; /* The rule list associated with this node */ RuleType mode; /* the rule mode */ int rval; /* 0 == no detection, 1 == detection event */ int evalIndex; /* eval index for this rule set */ char *name; /* name of this rule list (for debugging) */ struct _RuleListNode *next; /* the next RuleListNode */ } RuleListNode; typedef struct _RuleState { uint32_t sid; uint32_t gid; int state; RuleType action; struct _RuleState *next; } RuleState; #endif /* __RULES_H__ */ snort-2.9.15.1/src/treenodes.h0000644000175200017520000001227013571422607013002 00000000000000/**************************************************************************** * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2008-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* We moved the OptTreeNode and RuleTreeNode here to make them easier to include in dynamic preprocessors. */ #ifndef TREENODES_H #define TREENODES_H #include "rules.h" #include "plugin_enum.h" #include "rule_option_types.h" struct _OptTreeNode; /* forward declaration of OTN data struct */ struct _RuleTreeNode; /* forward declaration of RTN data struct */ /* same as the rule header FP list */ typedef struct _OptFpList { /* context data for this test */ void *context; int (*OptTestFunc)(void *option_data, Packet *p); struct _OptFpList *next; unsigned char isRelative; option_type_t type; } OptFpList; typedef struct _OptTreeNode { /* plugin/detection functions go here */ OptFpList *opt_func; RspFpList *rsp_func; /* response functions */ OutputFuncNode *outputFuncs; /* per sid enabled output functions */ /* the ds_list is absolutely essential for the plugin system to work, it allows the plugin authors to associate "dynamic" data structures with the rule system, letting them link anything they can come up with to the rules list */ void *ds_list[PLUGIN_MAX]; /* list of plugin data struct pointers */ int chain_node_number; int evalIndex; /* where this rule sits in the evaluation sets */ int proto; /* protocol, added for integrity checks during rule parsing */ int session_flag; /* record session data */ char *logto; /* log file in which to write packets which match this rule*/ /* metadata about signature */ SigInfo sigInfo; uint8_t stateless; /* this rule can fire regardless of session state */ uint8_t established; /* this rule can only fire if it is established */ uint8_t unestablished; Event event_data; void* detection_filter; /* if present, evaluated last, after header checks */ TagData *tag; /* stuff for dynamic rules activation/deactivation */ int active_flag; int activation_counter; int countdown; int activates; int activated_by; struct _OptTreeNode *OTN_activation_ptr; struct _RuleTreeNode *RTN_activation_ptr; struct _OptTreeNode *next; struct _OptTreeNode *nextSoid; /* ptr to list of RTNs (head part) */ struct _RuleTreeNode **proto_nodes; /**number of proto_nodes. */ unsigned short proto_node_num; uint8_t failedCheckBits; char generated; uint16_t longestPatternLen; int rule_state; /* Enabled or Disabled */ #ifdef PERF_PROFILING uint64_t ticks; uint64_t ticks_match; uint64_t ticks_no_match; uint64_t checks; uint64_t matches; uint64_t alerts; uint8_t noalerts; #endif int pcre_flag; /* PPM */ uint64_t ppm_suspend_time; /* PPM */ uint64_t ppm_disable_cnt; /*PPM */ uint32_t num_detection_opts; /**unique index generated in ruleIndexMap. */ int ruleIndex; /* List of preprocessor registered fast pattern contents */ void *preproc_fp_list; } OptTreeNode; /* function pointer list for rule head nodes */ typedef struct _RuleFpList { /* context data for this test */ void *context; /* rule check function pointer */ int (*RuleHeadFunc)(Packet *, struct _RuleTreeNode *, struct _RuleFpList *, int); /* pointer to the next rule function node */ struct _RuleFpList *next; } RuleFpList; typedef struct _RuleTreeNode { RuleFpList *rule_func; /* match functions.. (Bidirectional etc.. ) */ int head_node_number; RuleType type; IpAddrSet *sip; IpAddrSet *dip; int proto; PortObject * src_portobject; PortObject * dst_portobject; uint32_t flags; /* control flags */ #if 0 struct _RuleTreeNode *right; /* ptr to the next RTN in the list */ /** list of rule options to associate with this rule node */ OptTreeNode *down; #endif /**points to global parent RTN list (Drop/Alert) which contains this * RTN. */ struct _ListHead *listhead; /**reference count from otn. Multiple OTNs can reference this RTN with the same * policy. */ unsigned int otnRefCount; } RuleTreeNode; #endif /* TREENODES_H */ snort-2.9.15.1/src/checksum.h0000644000175200017520000002733013571422607012617 00000000000000/* $Id$ */ /* ** Copyright (C) 2000,2001 Christopher Cramer ** Snort is Copyright (C) 1998-2002 Martin Roesch ** ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Marc Norton ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** ** ** 7/2002 Marc Norton - added inline/optimized checksum routines ** these handle all hi/low endian issues ** 8/2002 Marc Norton - removed old checksum code and prototype ** */ #ifndef __CHECKSUM_H__ #define __CHECKSUM_H__ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "snort_debug.h" #include typedef struct { uint32_t sip[4], dip[4]; uint8_t zero; uint8_t protocol; uint16_t len; } pseudoheader6; typedef struct { uint32_t sip, dip; uint8_t zero; uint8_t protocol; uint16_t len; } pseudoheader; /* * checksum IP - header=20+ bytes * * w - short words of data * blen - byte length * */ static inline unsigned short in_chksum_ip( const unsigned short * w, int blen ) { unsigned int cksum; /* IP must be >= 20 bytes */ cksum = w[0]; cksum += w[1]; cksum += w[2]; cksum += w[3]; cksum += w[4]; cksum += w[5]; cksum += w[6]; cksum += w[7]; cksum += w[8]; cksum += w[9]; blen -= 20; w += 10; while( blen ) /* IP-hdr must be an integral number of 4 byte words */ { cksum += w[0]; cksum += w[1]; w += 2; blen -= 4; } cksum = (cksum >> 16) + (cksum & 0x0000ffff); cksum += (cksum >> 16); return (unsigned short) (~cksum); } /* * checksum tcp * * h - pseudo header - 12 bytes * d - tcp hdr + payload * dlen - length of tcp hdr + payload in bytes * */ static inline unsigned short in_chksum_tcp(pseudoheader *ph, unsigned short * d, int dlen ) { uint16_t *h = (uint16_t *)ph; unsigned int cksum; unsigned short answer=0; /* PseudoHeader must have 12 bytes */ cksum = h[0]; cksum += h[1]; cksum += h[2]; cksum += h[3]; cksum += h[4]; cksum += h[5]; /* TCP hdr must have 20 hdr bytes */ cksum += d[0]; cksum += d[1]; cksum += d[2]; cksum += d[3]; cksum += d[4]; cksum += d[5]; cksum += d[6]; cksum += d[7]; cksum += d[8]; cksum += d[9]; dlen -= 20; /* bytes */ d += 10; /* short's */ while(dlen >=32) { cksum += d[0]; cksum += d[1]; cksum += d[2]; cksum += d[3]; cksum += d[4]; cksum += d[5]; cksum += d[6]; cksum += d[7]; cksum += d[8]; cksum += d[9]; cksum += d[10]; cksum += d[11]; cksum += d[12]; cksum += d[13]; cksum += d[14]; cksum += d[15]; d += 16; dlen -= 32; } while(dlen >=8) { cksum += d[0]; cksum += d[1]; cksum += d[2]; cksum += d[3]; d += 4; dlen -= 8; } while(dlen > 1) { cksum += *d++; dlen -= 2; } if( dlen == 1 ) { /* printf("new checksum odd byte-packet\n"); */ *(unsigned char*)(&answer) = (*(unsigned char*)d); /* cksum += (uint16_t) (*(uint8_t*)d); */ cksum += answer; } cksum = (cksum >> 16) + (cksum & 0x0000ffff); cksum += (cksum >> 16); return (unsigned short)(~cksum); } /* * checksum tcp for IPv6. * * h - pseudo header - 12 bytes * d - tcp hdr + payload * dlen - length of tcp hdr + payload in bytes * */ static inline unsigned short in_chksum_tcp6(pseudoheader6 *ph, unsigned short * d, int dlen ) { uint16_t *h = (uint16_t *)ph; unsigned int cksum; unsigned short answer=0; /* PseudoHeader must have 36 bytes */ cksum = h[0]; cksum += h[1]; cksum += h[2]; cksum += h[3]; cksum += h[4]; cksum += h[5]; cksum += h[6]; cksum += h[7]; cksum += h[8]; cksum += h[9]; cksum += h[10]; cksum += h[11]; cksum += h[12]; cksum += h[13]; cksum += h[14]; cksum += h[15]; cksum += h[16]; cksum += h[17]; /* TCP hdr must have 20 hdr bytes */ cksum += d[0]; cksum += d[1]; cksum += d[2]; cksum += d[3]; cksum += d[4]; cksum += d[5]; cksum += d[6]; cksum += d[7]; cksum += d[8]; cksum += d[9]; dlen -= 20; /* bytes */ d += 10; /* short's */ while(dlen >=32) { cksum += d[0]; cksum += d[1]; cksum += d[2]; cksum += d[3]; cksum += d[4]; cksum += d[5]; cksum += d[6]; cksum += d[7]; cksum += d[8]; cksum += d[9]; cksum += d[10]; cksum += d[11]; cksum += d[12]; cksum += d[13]; cksum += d[14]; cksum += d[15]; d += 16; dlen -= 32; } while(dlen >=8) { cksum += d[0]; cksum += d[1]; cksum += d[2]; cksum += d[3]; d += 4; dlen -= 8; } while(dlen > 1) { cksum += *d++; dlen -= 2; } if( dlen == 1 ) { /* printf("new checksum odd byte-packet\n"); */ *(unsigned char*)(&answer) = (*(unsigned char*)d); /* cksum += (uint16_t) (*(uint8_t*)d); */ cksum += answer; } cksum = (cksum >> 16) + (cksum & 0x0000ffff); cksum += (cksum >> 16); return (unsigned short)(~cksum); } /* * checksum udp * * h - pseudo header - 12 bytes * d - udp hdr + payload * dlen - length of payload in bytes * */ static inline unsigned short in_chksum_udp6(pseudoheader6 *ph, unsigned short * d, int dlen ) { uint16_t *h = (uint16_t *)ph; unsigned int cksum; unsigned short answer=0; /* PseudoHeader must have 12 bytes */ cksum = h[0]; cksum += h[1]; cksum += h[2]; cksum += h[3]; cksum += h[4]; cksum += h[5]; cksum += h[6]; cksum += h[7]; cksum += h[8]; cksum += h[9]; cksum += h[10]; cksum += h[11]; cksum += h[12]; cksum += h[13]; cksum += h[14]; cksum += h[15]; cksum += h[16]; cksum += h[17]; /* UDP must have 8 hdr bytes */ cksum += d[0]; cksum += d[1]; cksum += d[2]; cksum += d[3]; dlen -= 8; /* bytes */ d += 4; /* short's */ while(dlen >=32) { cksum += d[0]; cksum += d[1]; cksum += d[2]; cksum += d[3]; cksum += d[4]; cksum += d[5]; cksum += d[6]; cksum += d[7]; cksum += d[8]; cksum += d[9]; cksum += d[10]; cksum += d[11]; cksum += d[12]; cksum += d[13]; cksum += d[14]; cksum += d[15]; d += 16; dlen -= 32; } while(dlen >=8) { cksum += d[0]; cksum += d[1]; cksum += d[2]; cksum += d[3]; d += 4; dlen -= 8; } while(dlen > 1) { cksum += *d++; dlen -= 2; } if( dlen == 1 ) { *(unsigned char*)(&answer) = (*(unsigned char*)d); cksum += answer; } cksum = (cksum >> 16) + (cksum & 0x0000ffff); cksum += (cksum >> 16); return (unsigned short)(~cksum); } static inline unsigned short in_chksum_udp(pseudoheader *ph, unsigned short * d, int dlen ) { uint16_t *h = (uint16_t *)ph; unsigned int cksum; unsigned short answer=0; /* PseudoHeader must have 36 bytes */ cksum = h[0]; cksum += h[1]; cksum += h[2]; cksum += h[3]; cksum += h[4]; cksum += h[5]; /* UDP must have 8 hdr bytes */ cksum += d[0]; cksum += d[1]; cksum += d[2]; cksum += d[3]; dlen -= 8; /* bytes */ d += 4; /* short's */ while(dlen >=32) { cksum += d[0]; cksum += d[1]; cksum += d[2]; cksum += d[3]; cksum += d[4]; cksum += d[5]; cksum += d[6]; cksum += d[7]; cksum += d[8]; cksum += d[9]; cksum += d[10]; cksum += d[11]; cksum += d[12]; cksum += d[13]; cksum += d[14]; cksum += d[15]; d += 16; dlen -= 32; } while(dlen >=8) { cksum += d[0]; cksum += d[1]; cksum += d[2]; cksum += d[3]; d += 4; dlen -= 8; } while(dlen > 1) { cksum += *d++; dlen -= 2; } if( dlen == 1 ) { *(unsigned char*)(&answer) = (*(unsigned char*)d); cksum += answer; } cksum = (cksum >> 16) + (cksum & 0x0000ffff); cksum += (cksum >> 16); return (unsigned short)(~cksum); } /* * checksum icmp */ static inline unsigned short in_chksum_icmp( unsigned short * w, int blen ) { unsigned short answer=0; unsigned int cksum = 0; while(blen >=32) { cksum += w[0]; cksum += w[1]; cksum += w[2]; cksum += w[3]; cksum += w[4]; cksum += w[5]; cksum += w[6]; cksum += w[7]; cksum += w[8]; cksum += w[9]; cksum += w[10]; cksum += w[11]; cksum += w[12]; cksum += w[13]; cksum += w[14]; cksum += w[15]; w += 16; blen -= 32; } while(blen >=8) { cksum += w[0]; cksum += w[1]; cksum += w[2]; cksum += w[3]; w += 4; blen -= 8; } while(blen > 1) { cksum += *w++; blen -= 2; } if( blen == 1 ) { *(unsigned char*)(&answer) = (*(unsigned char*)w); cksum += answer; } cksum = (cksum >> 16) + (cksum & 0x0000ffff); cksum += (cksum >> 16); return (unsigned short)(~cksum); } /* * checksum icmp6 */ static inline unsigned short in_chksum_icmp6(pseudoheader6 *ph, unsigned short *w, int blen ) { uint16_t *h = (uint16_t *)ph; unsigned short answer=0; unsigned int cksum = 0; /* PseudoHeader must have 36 bytes */ cksum = h[0]; cksum += h[1]; cksum += h[2]; cksum += h[3]; cksum += h[4]; cksum += h[5]; cksum += h[6]; cksum += h[7]; cksum += h[8]; cksum += h[9]; cksum += h[10]; cksum += h[11]; cksum += h[12]; cksum += h[13]; cksum += h[14]; cksum += h[15]; cksum += h[16]; cksum += h[17]; while(blen >=32) { cksum += w[0]; cksum += w[1]; cksum += w[2]; cksum += w[3]; cksum += w[4]; cksum += w[5]; cksum += w[6]; cksum += w[7]; cksum += w[8]; cksum += w[9]; cksum += w[10]; cksum += w[11]; cksum += w[12]; cksum += w[13]; cksum += w[14]; cksum += w[15]; w += 16; blen -= 32; } while(blen >=8) { cksum += w[0]; cksum += w[1]; cksum += w[2]; cksum += w[3]; w += 4; blen -= 8; } while(blen > 1) { cksum += *w++; blen -= 2; } if( blen == 1 ) { *(unsigned char*)(&answer) = (*(unsigned char*)w); cksum += answer; } cksum = (cksum >> 16) + (cksum & 0x0000ffff); cksum += (cksum >> 16); return (unsigned short)(~cksum); } static inline uint16_t ones_compl_checksum(const char *buf, unsigned size) { unsigned sum = 0; int i; /* Accumulate checksum */ for (i = 0; i < size - 1; i += 2) { uint16_t word16 = *(uint16_t *) &buf[i]; sum += word16; } /* Handle odd-sized case */ if (size & 1) { uint16_t word16 = (unsigned char) buf[i]; sum += word16; } /* Fold to get the ones-complement result */ while (sum >> 16) sum = (sum & 0xFFFF)+(sum >> 16); /* Invert to get the negative in ones-complement arithmetic */ return (uint16_t)(~sum); } #endif /* __CHECKSUM_H__ */ snort-2.9.15.1/src/debug.c0000644000175200017520000000726113571422607012077 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #ifndef __USE_ISOC95 # define __USE_ISOC95 # include # undef __USE_ISOC95 #else # include #endif #include #include #include #include "sf_types.h" #include "snort_debug.h" #include "snort.h" #ifdef DEBUG_MSGS char *DebugMessageFile = NULL; int DebugMessageLine = 0; int DebugThis(uint64_t level) { if (!(level & GetDebugLevel())) return 0; return 1; } uint64_t GetDebugLevel(void) { static int debug_init = 0; static uint64_t debug_level = 0; const char* key; if ( debug_init ) return debug_level; key = getenv(DEBUG_PP_VAR); if ( key ) debug_level = strtoul(key, NULL, 0); debug_level <<= 32; key = getenv(DEBUG_VARIABLE); if ( key ) debug_level |= strtoul(key, NULL, 0); debug_init = 1; return debug_level; } void DebugMessageFunc(uint64_t level, const char *fmt, ...) { va_list ap; if (!(level & GetDebugLevel())) return; va_start(ap, fmt); if ((snort_conf != NULL) && (ScDaemonMode() || ScLogSyslog())) { char buf[STD_BUF]; int buf_len = sizeof(buf); char *buf_ptr = buf; buf[buf_len - 1] = '\0'; /* filename and line number information */ if (DebugMessageFile != NULL) { snprintf(buf, buf_len - 1, "%s:%d: ", DebugMessageFile, DebugMessageLine); buf_ptr += strlen(buf); buf_len -= strlen(buf); } vsnprintf(buf_ptr, buf_len - 1, fmt, ap); syslog(LOG_DAEMON | LOG_DEBUG, "%s", buf); } else { if (DebugMessageFile != NULL) printf("%s:%d: ", DebugMessageFile, DebugMessageLine); vprintf(fmt, ap); } va_end(ap); } #ifdef SF_WCHAR void DebugWideMessageFunc(uint64_t level, const wchar_t *fmt, ...) { va_list ap; wchar_t buf[STD_BUF+1]; if (!(level & GetDebugLevel())) { return; } buf[STD_BUF]= (wchar_t)0; /* filename and line number information */ if (DebugMessageFile != NULL) printf("%s:%d: ", DebugMessageFile, DebugMessageLine); va_start(ap, fmt); if (ScDaemonMode()) { #ifdef WIN32 _vsnwprintf(buf, STD_BUF, fmt, ap); #else #ifdef HAVE_VSWPRINTF vswprintf(buf, STD_BUF, fmt, ap); #endif #endif //syslog(LOG_DAEMON | LOG_DEBUG, "%s", buf); } else { #ifdef HAVE_WPRINTF vwprintf(fmt, ap); #endif } va_end(ap); } #endif #else /* DEBUG_MSGS */ void DebugMessageFunc(uint64_t level, const char *fmt, ...) { } #ifdef SF_WCHAR void DebugWideMessageFunc(uint64_t level, const wchar_t *fmt, ...) { } #endif #endif /* DEBUG_MSGS */ snort-2.9.15.1/src/snort_debug.h0000644000175200017520000001042713571422607013327 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef DEBUG_H #define DEBUG_H #include #ifdef SF_WCHAR /* ISOC99 is defined to get required prototypes */ #ifndef __USE_ISOC99 #define __USE_ISOC99 #endif #include #endif /* this env var uses the lower 32 bits of the flags: */ #define DEBUG_VARIABLE "SNORT_DEBUG" #define DEBUG_INIT 0x0000000000000001LL #define DEBUG_PARSER 0x0000000000000002LL #define DEBUG_MSTRING 0x0000000000000004LL #define DEBUG_PORTLISTS 0x0000000000000008LL #define DEBUG_ATTRIBUTE 0x0000000000000010LL #define DEBUG_PLUGIN 0x0000000000000020LL #define DEBUG_PLUGBASE 0x0000000000000040LL #define DEBUG_DECODE 0x0000000000000080LL #define DEBUG_DATALINK 0x0000000000000100LL #define DEBUG_CONFIGRULES 0x0000000000000200LL #define DEBUG_RULES 0x0000000000000400LL #define DEBUG_DETECT 0x0000000000000800LL #define DEBUG_PATTERN_MATCH 0x0000000000001000LL #define DEBUG_FLOW 0x0000000000002000LL #define DEBUG_LOG 0x0000000000004000LL #define DEBUG_FLOWBITS 0x0000000000008000LL #define DEBUG_FILE 0x0000000000010000LL #define DEBUG_CONTROL 0x0000000000020000LL #define DEBUG_EXP 0x0000000080000000LL /* this env var uses the upper 32 bits of the flags: */ #define DEBUG_PP_VAR "SNORT_PP_DEBUG" #define DEBUG_FRAG 0x0000000100000000LL #define DEBUG_STREAM 0x0000000200000000LL #define DEBUG_STREAM_STATE 0x0000000400000000LL #define DEBUG_STREAM_PAF 0x0000000800000000LL #define DEBUG_HTTP_DECODE 0x0000001000000000LL #define DEBUG_HTTPINSPECT 0x0000002000000000LL #define DEBUG_ASN1 0x0000004000000000LL #define DEBUG_DNS 0x0000008000000000LL #define DEBUG_FTPTELNET 0x0000010000000000LL #define DEBUG_GTP 0x0000020000000000LL #define DEBUG_IMAP 0x0000040000000000LL #define DEBUG_POP 0x0000080000000000LL #define DEBUG_RPC 0x0000100000000000LL #define DEBUG_SIP 0x0000200000000000LL #define DEBUG_SKYPE 0x0000400000000000LL #define DEBUG_SSL 0x0000800000000000LL #define DEBUG_SMTP 0x0001000000000000LL #define DEBUG_APPID 0x0002000000000000LL #define DEBUG_PP_EXP 0x8000000000000000LL void DebugMessageFunc(uint64_t dbg, const char *fmt, ...); #ifdef SF_WCHAR void DebugWideMessageFunc(uint64_t dbg, const wchar_t *fmt, ...); #endif #ifdef DEBUG_MSGS extern char *DebugMessageFile; extern int DebugMessageLine; #define DebugMessage DebugMessageFile = __FILE__; DebugMessageLine = __LINE__; DebugMessageFunc #define DebugWideMessage DebugMessageFile = __FILE__; DebugMessageLine = __LINE__; DebugWideMessageFunc uint64_t GetDebugLevel (void); int DebugThis(uint64_t level); #else /* DEBUG_MSGS */ #ifdef WIN32 /* Visual C++ uses the keyword "__inline" rather than "__inline__" */ #define __inline__ __inline #endif #endif /* DEBUG_MSGS */ #ifdef DEBUG_MSGS #define DEBUG_WRAP(code) code void DebugMessageFunc(uint64_t dbg, const char *fmt, ...); #ifdef SF_WCHAR void DebugWideMessageFunc(uint64_t dbg, const wchar_t *fmt, ...); #endif #else /* DEBUG_MSGS */ #define DEBUG_WRAP(code) /* I would use DebugMessage(dbt,fmt...) but that only works with GCC */ #endif /* DEBUG_MSGS */ #endif /* DEBUG_H */ snort-2.9.15.1/src/decode.c0000644000175200017520000070632413571422607012242 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_STRINGS_H #include #endif #include #include #ifdef HAVE_DUMBNET_H #include #else #include #endif #include "decode.h" #include "snort.h" #include "snort_debug.h" #include "util.h" #include "detect.h" #include "checksum.h" #include "log.h" #include "generators.h" #include "event_queue.h" #include "active.h" #include "sfxhash.h" #include "snort_bounds.h" #include "strlcpyu.h" #include "sf_iph.h" #include "fpdetect.h" #include "profiler.h" #include "sfActionQueue.h" #include "mempool.h" #include "spp_normalize.h" #include "sfdaq.h" #include "sfrf.h" #ifdef REG_TEST #include "reg_test.h" #include #endif extern tSfActionQueueId decoderActionQ; extern MemPool decoderAlertMemPool; static IpAddrSet *SynToMulticastDstIp = NULL; static IpAddrSet *MulticastReservedIp = NULL; #ifdef PERF_PROFILING PreprocStats decodePerfStats; #endif // Array to check if the decoder rules are enabled in at least one policy static uint8_t decodeRulesArray[DECODE_INDEX_MAX]; //-------------------------------------------------------------------- // decode.c::event support //-------------------------------------------------------------------- #ifdef NORMALIZER static inline int ScNormalDrop (NormFlags nf) { return Normalize_GetMode(snort_conf, nf) == NORM_MODE_OFF; } #else #define ScNormalDrop(nf) 1 #endif static inline void queueExecDrop( void (*callback)(void *), Packet* p) { int ret = sfActionQueueAdd( decoderActionQ, callback, (void*)p); if (ret == -1) { ErrorMessage("Could not add drop event to decoderActionQ\n"); } } // no harm declaring the exec*Drop()s as inline, but since // the only use is via pointer, these won't get inlined. static inline void execDecoderDrop (void *data) { if ( ScDecoderAlerts() && ScDecoderDrops() ) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n");); Active_DropSession((Packet*)data); if (pkt_trace_enabled) addPktTraceData(VERDICT_REASON_SNORT, snprintf(trace_line, MAX_TRACE_LINE, "Snort: bad packet decode error, %s\n", getPktTraceActMsg())); else addPktTraceData(VERDICT_REASON_SNORT, 0); } } static inline void execIpOptDrop (void *data) { if ( ScDecoderIpOptDrops() ) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet (IP opts)\n");); Active_DropPacket((Packet*)data); if (pkt_trace_enabled) addPktTraceData(VERDICT_REASON_SNORT, snprintf(trace_line, MAX_TRACE_LINE, "Snort: IP options decode error, %s\n", getPktTraceActMsg())); else addPktTraceData(VERDICT_REASON_SNORT, 0); } } static inline void execMinTtlDrop (void *data) { if ( ScNormalDrop(NORM_IP4_TTL) && ScDecoderAlerts() && ScDecoderDrops() ) { Packet* p = (Packet*)data; DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet (IP4 min TTL)\n");); p->error_flags |= PKT_ERR_BAD_TTL; Active_DropPacket(p); if (pkt_trace_enabled) addPktTraceData(VERDICT_REASON_SNORT, snprintf(trace_line, MAX_TRACE_LINE, "Snort: IP4 min TTL error, %s\n", getPktTraceActMsg())); else addPktTraceData(VERDICT_REASON_SNORT, 0); } } static inline void execTtlDrop (void *data) { if ( ScNormalDrop(NORM_IP4_TTL) ) { Packet* p = (Packet*)data; DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet (IP4 zero TTL)\n");); p->error_flags |= PKT_ERR_BAD_TTL; Active_DropPacket(p); if (pkt_trace_enabled) addPktTraceData(VERDICT_REASON_SNORT, snprintf(trace_line, MAX_TRACE_LINE, "Snort: IP4 zero TTL error, %s\n", getPktTraceActMsg())); else addPktTraceData(VERDICT_REASON_SNORT, 0); } } static inline void execHopDrop (void *data) { if ( ScNormalDrop(NORM_IP6_TTL) ) { Packet* p = (Packet*)data; DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet (IP6 zero hop)\n");); p->error_flags |= PKT_ERR_BAD_TTL; Active_DropPacket(p); if (pkt_trace_enabled) addPktTraceData(VERDICT_REASON_SNORT, snprintf(trace_line, MAX_TRACE_LINE, "Snort: IP6 zero hop error, %s\n", getPktTraceActMsg())); else addPktTraceData(VERDICT_REASON_SNORT, 0); } } static inline void execIpv6MinTtlDrop (void *data) { if ( ScNormalDrop(NORM_IP6_TTL) && ScDecoderAlerts() && ScDecoderDrops() ) { Packet* p = (Packet*)data; DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet (IP6 hop limit)\n");); p->error_flags |= PKT_ERR_BAD_TTL; Active_DropPacket(p); if (pkt_trace_enabled) addPktTraceData(VERDICT_REASON_SNORT, snprintf(trace_line, MAX_TRACE_LINE, "Snort: IP6 hop limit error, %s\n", getPktTraceActMsg())); else addPktTraceData(VERDICT_REASON_SNORT, 0); } } static inline void execTcpOptDrop (void *data) { if ( ScDecoderTcpOptDrops() ) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet (TCP opts)\n");); Active_DropPacket((Packet*)data); if (pkt_trace_enabled) addPktTraceData(VERDICT_REASON_SNORT, snprintf(trace_line, MAX_TRACE_LINE, "Snort: TCP options decode error, %s\n", getPktTraceActMsg())); else addPktTraceData(VERDICT_REASON_SNORT, 0); } } static inline void execTcpOptExpDrop (void *data) { if ( ScDecoderTcpOptExpDrops() ) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet (TCP exp opts)\n");); Active_DropPacket((Packet*)data); if (pkt_trace_enabled) addPktTraceData(VERDICT_REASON_SNORT, snprintf(trace_line, MAX_TRACE_LINE, "Snort: TCP experimental options decode error, %s\n", getPktTraceActMsg())); else addPktTraceData(VERDICT_REASON_SNORT, 0); } } static inline void execTcpOptObsDrop (void *data) { if ( ScDecoderTcpOptObsDrops() ) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet (TCP obs opts)\n");); Active_DropPacket((Packet*)data); if (pkt_trace_enabled) addPktTraceData(VERDICT_REASON_SNORT, snprintf(trace_line, MAX_TRACE_LINE, "Snort: TCP obsolete options decode error, %s\n", getPktTraceActMsg())); else addPktTraceData(VERDICT_REASON_SNORT, 0); } } static inline void execTcpOptTTcpDrop (void *data) { if ( ScDecoderTcpOptTTcpDrops() ) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet (TTCP opts)\n");); Active_DropPacket((Packet*)data); if (pkt_trace_enabled) addPktTraceData(VERDICT_REASON_SNORT, snprintf(trace_line, MAX_TRACE_LINE, "Snort: Test TCP (TTCP) options decode error, %s\n", getPktTraceActMsg())); else addPktTraceData(VERDICT_REASON_SNORT, 0); } } static inline void execIpChksmDrop (void *data) { // TBD only set policy csum drop if policy inline // and delete this inline mode check if( ScNapInlineMode() && ScIpChecksumDrops() ) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet (IP checksum)\n");); Active_NapDropPacket((Packet*)data); if (pkt_trace_enabled) addPktTraceData(VERDICT_REASON_SNORT, snprintf(trace_line, MAX_TRACE_LINE, "Snort: IP checksum error, %s\n", getPktTraceActMsg())); else addPktTraceData(VERDICT_REASON_SNORT, 0); } } static inline void execTcpChksmDrop (void *data) { if( ScNapInlineMode() && ScTcpChecksumDrops() ) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet (TCP checksum)\n");); Active_NapDropPacket((Packet*)data); if (pkt_trace_enabled) addPktTraceData(VERDICT_REASON_SNORT, snprintf(trace_line, MAX_TRACE_LINE, "Snort: TCP checksum error, %s\n", getPktTraceActMsg())); else addPktTraceData(VERDICT_REASON_SNORT, 0); } } static inline void execUdpChksmDrop (void *data) { if( ScNapInlineMode() && ScUdpChecksumDrops() ) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet (UDP checksum)\n");); Active_NapDropPacket((Packet*)data); if (pkt_trace_enabled) addPktTraceData(VERDICT_REASON_SNORT, snprintf(trace_line, MAX_TRACE_LINE, "Snort: UDP checksum error, %s\n", getPktTraceActMsg())); else addPktTraceData(VERDICT_REASON_SNORT, 0); } } static inline void execIcmpChksmDrop (void *data) { if( ScNapInlineMode() && ScIcmpChecksumDrops() ) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet (ICMP checksum)\n");); Active_NapDropPacket((Packet*)data); if (pkt_trace_enabled) addPktTraceData(VERDICT_REASON_SNORT, snprintf(trace_line, MAX_TRACE_LINE, "Snort: ICMP checksum error, %s\n", getPktTraceActMsg())); else addPktTraceData(VERDICT_REASON_SNORT, 0); } } void execDecoderEvent(void *data) { MemBucket *alertBucket = (MemBucket *)data; EventNode *en = (EventNode *)alertBucket->data; int add; switch (en->sid) { case DECODE_IPV4OPT_BADLEN: case DECODE_IPV4OPT_TRUNCATED: add = ScDecoderIpOptAlerts(); break; case DECODE_TCPOPT_WSCALE_INVALID: case DECODE_TCPOPT_BADLEN: case DECODE_TCPOPT_TRUNCATED: add = ScDecoderTcpOptAlerts(); break; case DECODE_TCPOPT_EXPERIMENT: add = ScDecoderTcpOptExpAlerts(); break; case DECODE_TCPOPT_OBSOLETE: add = ScDecoderTcpOptObsAlerts(); break; case DECODE_TCPOPT_TTCP: add = ScDecoderTcpOptTTcpAlerts(); break; default: add = ScDecoderAlerts(); break; } if ( add ) { SnortEventqAdd(en->gid, en->sid, en->rev, en->classification, en->priority, en->msg, en->rule_info); } mempool_free(&decoderAlertMemPool, alertBucket); } void queueDecoderEvent( unsigned int gid, unsigned int sid, unsigned int rev, unsigned int classification, unsigned int pri, const char *msg, void *rule_info) { MemBucket *alertBucket; EventNode *en; int ret; alertBucket = (MemBucket *)mempool_alloc(&decoderAlertMemPool); if(!alertBucket) return; en = (EventNode *)alertBucket->data; en->gid = gid; en->sid = sid; en->rev = rev; en->classification = classification; en->priority = pri; en->msg = msg; en->rule_info = (OptTreeNode *) rule_info; ret = sfActionQueueAdd( decoderActionQ, execDecoderEvent, alertBucket); if (ret == -1) { ErrorMessage("Could not add event to decoderActionQ\n"); mempool_free(&decoderAlertMemPool, alertBucket); } } static inline void DecoderEvent ( Packet *p, int sid, const char *str, int event_flag, int drop_flag) { if ( ScLogVerbose() ) ErrorMessage("%s\n", str); if (ScIdsMode() && event_flag) { queueDecoderEvent(GENERATOR_SNORT_DECODE, sid, 1, DECODE_CLASS, 3, str, 0); if ( drop_flag ) { queueExecDrop(execDecoderDrop, p); if (pkt_trace_enabled) addPktTraceData(VERDICT_REASON_NO_BLOCK, snprintf(trace_line, MAX_TRACE_LINE, "Snort: gid %u, sid %u, bad packet queued for decoder drop\n", GENERATOR_SNORT_DECODE, sid)); } } } static inline void DecoderOptEvent ( Packet *p, int sid, char *str, int event_flag, int drop_flag, void (*callback)(void*) ) { if ( ScLogVerbose() ) ErrorMessage("%s\n", str); if (ScIdsMode() && event_flag) { queueDecoderEvent(GENERATOR_SNORT_DECODE, sid, 1, DECODE_CLASS, 3, str, 0); if ( drop_flag ) { queueExecDrop(callback, p); } } } static inline void DecoderEventDrop ( Packet *p, int sid, char *str, int event_flag, int drop_flag) { if ( ScLogVerbose() ) ErrorMessage("%s\n", str); if (ScIdsMode() && event_flag) { queueDecoderEvent(GENERATOR_SNORT_DECODE, sid, 1, DECODE_CLASS, 3, str, 0); if ( drop_flag ) { Active_DropPacket(p); if (pkt_trace_enabled) addPktTraceData(VERDICT_REASON_SNORT, snprintf(trace_line, MAX_TRACE_LINE, "Snort: decoder gid %u, sid %u, %s\n", GENERATOR_SNORT_DECODE, sid, getPktTraceActMsg())); else addPktTraceData(VERDICT_REASON_SNORT, 0); } } } void DecoderAlertEncapsulated( Packet *p, int type, const char *str, const uint8_t *pkt, uint32_t len) { DecoderEvent(p, type, str, 1, 1); p->data = pkt; p->dsize = (uint16_t)len; p->greh = NULL; } #define EVARGS(ID) DECODE_ ## ID, DECODE_ ## ID ## _STR static inline int Event_Enabled(int sid) { return ( decodeRulesArray[sid] ); } //-------------------------------------------------------------------- // decode.c::miscellaneous public methods and helper functions //-------------------------------------------------------------------- #if defined(WORDS_MUSTALIGN) && !defined(__GNUC__) uint32_t EXTRACT_32BITS (u_char *p) { uint32_t __tmp; memmove(&__tmp, p, sizeof(uint32_t)); return (uint32_t) ntohl(__tmp); } #endif /* WORDS_MUSTALIGN && !__GNUC__ */ void InitSynToMulticastDstIp( struct _SnortConfig *sc ) { // Multicast addresses pursuant to RFC 5771 SynToMulticastDstIp = IpAddrSetParse(sc, "[224.0.0.0/4]"); if( SynToMulticastDstIp == NULL ) { FatalError("Could not initialize SynToMulticastDstIp\n"); } } void InitMulticastReservedIp( struct _SnortConfig *sc ) { // Reserved addresses within multicast address space (See RFC 5771) MulticastReservedIp = IpAddrSetParse(sc, "[224.1.0.0/16,224.5.0.0/16,224.6.0.0/15,224.8.0.0/13,224.16.0.0/12," "224.32.0.0/11,224.64.0.0/10,224.128.0.0/9,225.0.0.0/8,226.0.0.0/7," "228.0.0.0/6,234.0.0.0/7,236.0.0.0/7,238.0.0.0/8]"); if( MulticastReservedIp == NULL ) { FatalError("Could not initialize MulticastReservedIp\n"); } } void SynToMulticastDstIpDestroy( void ) { if( SynToMulticastDstIp ) { IpAddrSetDestroy(SynToMulticastDstIp); } } void MulticastReservedIpDestroy( void ) { if( MulticastReservedIp ) { IpAddrSetDestroy(MulticastReservedIp); } } static inline void CheckIPv4_MinTTL(Packet *p, uint8_t ttl) { // this sequence of tests is best for the "normal" case where // the packet ttl is >= the configured min (the default is 1) if( ttl < ScMinTTL() ) { if ( Event_Enabled(DECODE_ZERO_TTL) && (ttl == 0) ) { DecoderOptEvent(p, DECODE_ZERO_TTL, DECODE_ZERO_TTL_STR, 1, 1, execTtlDrop); } else if ( Event_Enabled(DECODE_IP4_MIN_TTL) ) { DecoderOptEvent(p, DECODE_IP4_MIN_TTL, DECODE_IP4_MIN_TTL_STR, 1, 1, execMinTtlDrop); } } } static inline void CheckIPv6_MinTTL(Packet *p, uint8_t hop_limit) { // this sequence of tests is best for the "normal" case where // the packet ttl is >= the configured min (the default is 1) if( hop_limit < ScMinTTL() ) { if ( Event_Enabled(DECODE_IP6_ZERO_HOP_LIMIT) && (hop_limit == 0) ) { DecoderOptEvent(p, DECODE_IP6_ZERO_HOP_LIMIT, DECODE_IP6_ZERO_HOP_LIMIT_STR, 1, 1, execHopDrop); } else if ( Event_Enabled(DECODE_IPV6_MIN_TTL) ) { DecoderOptEvent(p, DECODE_IPV6_MIN_TTL, DECODE_IPV6_MIN_TTL_STR, 1, 1, execIpv6MinTtlDrop); } } } /* Decoding of ttl/hop_limit is based on the policy min_ttl */ static inline void DecodeIP_MinTTL(Packet *p) { switch(p->outer_family) { case AF_INET: CheckIPv4_MinTTL( p, p->outer_ip4h.ip_ttl); return; case AF_INET6: CheckIPv6_MinTTL( p, p->outer_ip6h.hop_lmt); return; default: break; } switch(p->family) { case AF_INET: CheckIPv4_MinTTL( p, p->ip4h->ip_ttl); return; case AF_INET6: CheckIPv6_MinTTL( p, p->ip6h->hop_lmt); return; default: break; } return; } /* Any policy specific decoding should be done in this function which is called by ProcessPacket*/ void DecodePolicySpecific(Packet *p) { DecodeIP_MinTTL(p); } /* This function enables or disables the decoder rule. value can only be 0 or 1*/ void UpdateDecodeRulesArray(uint32_t sid, int value, int all_rules) { int i; if ( all_rules ) { for( i = 0; i < DECODE_INDEX_MAX; i++ ) decodeRulesArray[i] = ( value != 0 ); } else if ( sid < DECODE_INDEX_MAX ) { decodeRulesArray[sid] = ( value != 0 ); } } // this must be called iff the layer is successfully decoded because, when // enabled, the normalizer assumes that the encoding is structurally sound static inline void PushLayer(PROTO_ID type, Packet* p, const uint8_t* hdr, uint32_t len) { if ( p->next_layer < LAYER_MAX ) { Layer* lyr = p->layers + p->next_layer++; lyr->proto = type; lyr->start = (uint8_t*)hdr; lyr->length = (uint16_t)len; } else { LogMessage("(snort_decoder) WARNING: decoder got too many layers;" " next proto is %u.\n", type); } } //-------------------------------------------------------------------- // decode.c::ARP //-------------------------------------------------------------------- /* * Function: DecodeARP(uint8_t *, uint32_t, Packet *) * * Purpose: Decode ARP stuff * * Arguments: pkt => ptr to the packet data * len => length from here to the end of the packet * p => pointer to decoded packet struct * * Returns: void function */ void DecodeARP(const uint8_t * pkt, uint32_t len, Packet * p) { pc.arp++; #ifdef GRE if (p->greh != NULL) pc.gre_arp++; #endif p->ah = (EtherARP *) pkt; if(len < sizeof(EtherARP)) { DecoderEvent(p, DECODE_ARP_TRUNCATED, DECODE_ARP_TRUNCATED_STR, 1, 1); pc.discards++; return; } p->proto_bits |= PROTO_BIT__ARP; PushLayer(PROTO_ARP, p, pkt, sizeof(*p->ah)); } //-------------------------------------------------------------------- // decode.c::NULL and Loopback //-------------------------------------------------------------------- /* * Function: DecodeNullPkt(Packet *, char *, DAQ_PktHdr_t*, uint8_t*) * * Purpose: Decoding on loopback devices. * * Arguments: p => pointer to decoded packet struct * user => Utility pointer, unused * pkthdr => ptr to the packet header * pkt => pointer to the real live packet data * * Returns: void function */ void DecodeNullPkt(Packet * p, const DAQ_PktHdr_t * pkthdr, const uint8_t * pkt) { uint32_t cap_len = pkthdr->caplen; PROFILE_VARS; PREPROC_PROFILE_START(decodePerfStats); pc.total_processed++; memset(p, 0, PKT_ZERO_LEN); p->pkth = pkthdr; p->pkt = pkt; DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n"); ); /* do a little validation */ if(cap_len < NULL_HDRLEN) { if (ScLogVerbose()) { ErrorMessage("NULL header length < captured len! (%d bytes)\n", cap_len); } PREPROC_PROFILE_END(decodePerfStats); return; } DecodeIP(p->pkt + NULL_HDRLEN, cap_len - NULL_HDRLEN, p); PREPROC_PROFILE_END(decodePerfStats); } /* * Function: DecodeEthLoopback(uint8_t *, uint32_t) * * Purpose: Just like IPX, it's just for counting. * * Arguments: pkt => ptr to the packet data * len => length from here to the end of the packet * * Returns: void function */ void DecodeEthLoopback(const uint8_t *pkt, uint32_t len, Packet *p) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "EthLoopback is not supported.\n");); pc.ethloopback++; #ifdef GRE if (p->greh != NULL) pc.gre_loopback++; #endif return; } //-------------------------------------------------------------------- // decode.c::Ethernet //-------------------------------------------------------------------- void DecodeEthTypes(Packet *p, const uint8_t *pkt, uint16_t ethtype, uint32_t cap_len, uint8_t linklen); void DecodeCiscoMeta(const uint8_t *pkt, uint32_t rem_len, Packet *p) { uint16_t real_len; uint16_t realeth; int16_t cmdh_rem_len; uint8_t i; if (rem_len < CISCO_META_PREHEADER_LEN) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "WARNING: Truncated Cisco Metadata header (%d bytes).\n", rem_len);); if ( Event_Enabled(DECODE_CISCO_META_HDR_TRUNC) ) DecoderEvent(p, EVARGS(CISCO_META_HDR_TRUNC), 1, 1); pc.discards++; return; } p->cmdh = (CiscoMetaHdr*)pkt; p->cmd_options = (CiscoMetaOpt*)(pkt + sizeof(CiscoMetaHdr)); cmdh_rem_len = p->cmdh->length << 3; /* validate CMD tag header */ if(rem_len < cmdh_rem_len || cmdh_rem_len == 0) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "WARNING: Truncated Cisco Metadata header (%d bytes).\n", rem_len);); if ( Event_Enabled(DECODE_CISCO_META_HDR_TRUNC) ) DecoderEvent(p, EVARGS(CISCO_META_HDR_TRUNC), 1, 1); pc.discards++; return; } /* validate options, lengths, and SGTs*/ cmdh_rem_len -= sizeof(CiscoMetaHdr) + sizeof(uint16_t); //2 octects for ethertype if(cmdh_rem_len == 0) p->cmd_options = NULL; for(i = 0; cmdh_rem_len > 0; i++) { CiscoMetaOpt *opt; uint8_t len; uint16_t type; /* Top 3 bits (length) must be equal to 0 or 4 */ /* Bottom 13 bits (type) must be 1 to indicate SGT*/ opt = &p->cmd_options[i]; len = ntohs(opt->opt_len_type) >> CISCO_META_OPT_LEN_SHIFT; type = ntohs(opt->opt_len_type) & CISCO_META_OPT_TYPE_MASK; /* 0 indicates 4 octets */ if(len != 0 && len != 4) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "WARNING: Invalid Cisco Metadata option length (%u bytes).\n", (uint32_t)len);); if ( Event_Enabled(DECODE_CISCO_META_HDR_OPT_LEN) ) DecoderEvent(p, EVARGS(CISCO_META_HDR_OPT_LEN), 1, 1); pc.discards++; return; } if(type != CISCO_META_OPT_TYPE_SGT) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "WARNING: Invalid Cisco Metadata option type (%u).\n", (uint32_t)len);); if ( Event_Enabled(DECODE_CISCO_META_HDR_OPT_TYPE) ) DecoderEvent(p, EVARGS(CISCO_META_HDR_OPT_TYPE), 1, 1); pc.discards++; return; } /* Tag value 0xFFFF is invalid */ if(opt->sgt == 0xFFFF) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "WARNING: Invalid Cisco Metadata SGT (0xFFFF).\n");); if ( Event_Enabled(DECODE_CISCO_META_HDR_SGT) ) DecoderEvent(p, EVARGS(CISCO_META_HDR_SGT), 1, 1); pc.discards++; return; } cmdh_rem_len -= sizeof(CiscoMetaOpt); } /* Move to next header */ real_len = p->cmdh->length << 3; realeth = ntohs(*((uint16_t*) (pkt + real_len - sizeof(uint16_t)))); //The last 2 octets of the header will be the real ethtype PushLayer(PROTO_CISCO_META, p, pkt, real_len); //Decode the real ethtype DecodeEthTypes(p, pkt, realeth, rem_len, real_len); } /* Handles ethtypes. Used for ethtypes that chain to other ethtypes */ void DecodeEthTypes(Packet *p, const uint8_t *pkt, uint16_t ethtype, uint32_t cap_len, uint8_t linklen) { /* grab out the network type */ switch(ethtype) { case ETHERNET_TYPE_IP: DEBUG_WRAP( DebugMessage(DEBUG_DECODE, "IP datagram size calculated to be %lu bytes\n", (unsigned long)(cap_len - linklen)); ); DecodeIP(pkt + linklen, cap_len - linklen, p); return; case ETHERNET_TYPE_ARP: case ETHERNET_TYPE_REVARP: DecodeARP(pkt + linklen, cap_len - linklen, p); return; case ETHERNET_TYPE_IPV6: DecodeIPV6(pkt + linklen, (cap_len - linklen), p); return; case ETHERNET_TYPE_PPPoE_DISC: case ETHERNET_TYPE_PPPoE_SESS: DecodePPPoEPkt(pkt + linklen, (cap_len - linklen), p); return; #ifndef NO_NON_ETHER_DECODER case ETHERNET_TYPE_IPX: DecodeIPX(pkt + linklen, (cap_len - linklen), p); return; #endif case ETHERNET_TYPE_LOOP: DecodeEthLoopback(pkt + linklen, (cap_len - linklen), p); return; case ETHERNET_TYPE_8021Q: case ETHERNET_TYPE_8021AD: case ETHERNET_TYPE_QINQ_NS1: case ETHERNET_TYPE_QINQ_NS2: DecodeVlan(pkt + linklen, cap_len - linklen, p); return; #ifdef MPLS case ETHERNET_TYPE_MPLS_MULTICAST: if(!ScMplsMulticast()) { //additional check for DecoderAlerts will be done now. DecoderEvent(p, DECODE_BAD_MPLS, DECODE_MULTICAST_MPLS_STR, 1, 1); } case ETHERNET_TYPE_MPLS_UNICAST: DecodeMPLS(pkt + linklen, cap_len - linklen, p); return; #endif case ETHERNET_TYPE_CISCO_META: DecodeCiscoMeta(pkt + linklen, cap_len - linklen, p); return; default: // TBD add decoder drop event for unknown eth type pc.other++; return; } } /* * Function: DecodeEthPkt(Packet *, char *, DAQ_PktHdr_t*, uint8_t*) * * Purpose: Decode those fun loving ethernet packets, one at a time! * * Arguments: p => pointer to the decoded packet struct * user => Utility pointer (unused) * pkthdr => ptr to the packet header * pkt => pointer to the real live packet data * * Returns: void function */ void DecodeEthPkt(Packet * p, const DAQ_PktHdr_t * pkthdr, const uint8_t * pkt) { uint32_t cap_len = pkthdr->caplen; uint32_t rem_len = cap_len; uint8_t linklen = ETHERNET_HEADER_LEN; PROFILE_VARS; PREPROC_PROFILE_START(decodePerfStats); pc.eth++; pc.total_processed++; memset(p, 0, PKT_ZERO_LEN); p->pkth = pkthdr; p->pkt = pkt; DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n"); DebugMessage(DEBUG_DECODE, "caplen: %lu pktlen: %lu\n", (unsigned long)cap_len, (unsigned long)pkthdr->pktlen); ); while(true) { /* do a little validation */ if(rem_len < ETHERNET_HEADER_LEN) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "WARNING: Truncated eth header (%d bytes).\n", rem_len);); if ( Event_Enabled(DECODE_ETH_HDR_TRUNC) ) DecoderEvent(p, EVARGS(ETH_HDR_TRUNC), 1, 1); pc.discards++; pc.ethdisc++; PREPROC_PROFILE_END(decodePerfStats); return; } /* lay the ethernet structure over the packet data */ p->eh = (EtherHdr *) pkt; /* check if this is a FabricPath header */ if(ntohs(p->eh->ether_type) == ETHERNET_TYPE_FPATH) { /* do a little validation */ if(rem_len < FABRICPATH_HEADER_LEN) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "WARNING: Truncated FabricPath header (%d bytes).\n", rem_len);); if ( Event_Enabled(DECODE_FPATH_HDR_TRUNC) ) DecoderEvent(p, EVARGS(FPATH_HDR_TRUNC), 1, 1); pc.discards++; PREPROC_PROFILE_END(decodePerfStats); return; } /* strip FabricPath header*/ PushLayer(PROTO_FPATH, p, pkt, FABRICPATH_HEADER_LEN); pkt += FABRICPATH_HEADER_LEN; linklen += FABRICPATH_HEADER_LEN; rem_len -= FABRICPATH_HEADER_LEN; } else break; } PushLayer(PROTO_ETH, p, pkt, sizeof(*p->eh)); DEBUG_WRAP( DebugMessage(DEBUG_DECODE, "%X:%X:%X:%X:%X:%X -> %X:%X:%X:%X:%X:%X\n", p->eh->ether_src[0], p->eh->ether_src[1], p->eh->ether_src[2], p->eh->ether_src[3], p->eh->ether_src[4], p->eh->ether_src[5], p->eh->ether_dst[0], p->eh->ether_dst[1], p->eh->ether_dst[2], p->eh->ether_dst[3], p->eh->ether_dst[4], p->eh->ether_dst[5]); ); DEBUG_WRAP( DebugMessage(DEBUG_DECODE, "type:0x%X len:0x%X\n", ntohs(p->eh->ether_type), p->pkth->pktlen) ); DecodeEthTypes(p, p->pkt, ntohs(p->eh->ether_type), cap_len, linklen); PREPROC_PROFILE_END(decodePerfStats); } #ifdef GRE /* * Function: DecodeTransBridging(uint8_t *, const uint32_t, Packet) * * Purpose: Decode Transparent Ethernet Bridging * * Arguments: pkt => pointer to the real live packet data * len => length of remaining data in packet * p => pointer to the decoded packet struct * * * Returns: void function * * Note: This is basically the code from DecodeEthPkt but the calling * convention needed to be changed and the stuff at the beginning * wasn't needed since we are already deep into the packet */ void DecodeTransBridging(const uint8_t *pkt, const uint32_t len, Packet *p) { pc.gre_eth++; if(len < ETHERNET_HEADER_LEN) { DecoderAlertEncapsulated(p, DECODE_GRE_TRANS_DGRAM_LT_TRANSHDR, DECODE_GRE_TRANS_DGRAM_LT_TRANSHDR_STR, pkt, len); return; } /* The Packet struct's ethernet header will now point to the inner ethernet * header of the packet */ p->eh = (EtherHdr *)pkt; PushLayer(PROTO_ETH, p, pkt, sizeof(*p->eh)); switch (ntohs(p->eh->ether_type)) { case ETHERNET_TYPE_IP: DecodeIP(pkt + ETHERNET_HEADER_LEN, len - ETHERNET_HEADER_LEN, p); return; case ETHERNET_TYPE_ARP: case ETHERNET_TYPE_REVARP: DecodeARP(pkt + ETHERNET_HEADER_LEN, len - ETHERNET_HEADER_LEN, p); return; case ETHERNET_TYPE_IPV6: DecodeIPV6(pkt + ETHERNET_HEADER_LEN, len - ETHERNET_HEADER_LEN, p); return; #ifndef NO_NON_ETHER_DECODER case ETHERNET_TYPE_IPX: DecodeIPX(pkt + ETHERNET_HEADER_LEN, len - ETHERNET_HEADER_LEN, p); return; #endif case ETHERNET_TYPE_LOOP: DecodeEthLoopback(pkt + ETHERNET_HEADER_LEN, len - ETHERNET_HEADER_LEN, p); return; case ETHERNET_TYPE_8021Q: DecodeVlan(pkt + ETHERNET_HEADER_LEN, len - ETHERNET_HEADER_LEN, p); return; default: // TBD add decoder drop event for unknown xbrdg/eth type pc.other++; p->data = pkt + ETHERNET_HEADER_LEN; p->dsize = (uint16_t)(len - ETHERNET_HEADER_LEN); return; } } #endif /* GRE */ //-------------------------------------------------------------------- // decode.c::MPLS //-------------------------------------------------------------------- #ifdef MPLS /* * check if reserved labels are used properly */ static int checkMplsHdr(uint32_t label, uint8_t exp, uint8_t bos, uint8_t ttl, Packet *p) { int iRet = 0; switch(label) { case 0: case 2: /* check if this label is the bottom of the stack */ if(bos) { if ( label == 0 ) iRet = MPLS_PAYLOADTYPE_IPV4; else if ( label == 2 ) iRet = MPLS_PAYLOADTYPE_IPV6; /* when label == 2, IPv6 is expected; * when label == 0, IPv4 is expected */ if((label&&(ScMplsPayloadType() != MPLS_PAYLOADTYPE_IPV6)) ||((!label)&&(ScMplsPayloadType() != MPLS_PAYLOADTYPE_IPV4))) { if( !label ) DecoderEvent(p, DECODE_BAD_MPLS_LABEL0, DECODE_BAD_MPLS_LABEL0_STR, 1, 1); else DecoderEvent(p, DECODE_BAD_MPLS_LABEL2, DECODE_BAD_MPLS_LABEL2_STR, 1, 1); } break; } #if 0 /* This is valid per RFC 4182. Just pop this label off, ignore it * and move on to the next one. */ if( !label ) DecoderEvent(p, DECODE_BAD_MPLS_LABEL0, DECODE_BAD_MPLS_LABEL0_STR, 1, 1); else DecoderEvent(p, DECODE_BAD_MPLS_LABEL2, DECODE_BAD_MPLS_LABEL2_STR, 1, 1); pc.discards++; p->iph = NULL; p->family = NO_IP; return(-1); #endif break; case 1: if(!bos) break; DecoderEvent(p, DECODE_BAD_MPLS_LABEL1, DECODE_BAD_MPLS_LABEL1_STR, 1, 1); pc.discards++; p->iph = NULL; p->family = NO_IP; iRet = MPLS_PAYLOADTYPE_ERROR; break; case 3: DecoderEvent(p, DECODE_BAD_MPLS_LABEL3, DECODE_BAD_MPLS_LABEL3_STR, 1, 1); pc.discards++; p->iph = NULL; p->family = NO_IP; iRet = MPLS_PAYLOADTYPE_ERROR; break; case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: DecoderEvent(p, DECODE_MPLS_RESERVED_LABEL, DECODE_MPLS_RESERVEDLABEL_STR, 1, 1); break; default: break; } if ( !iRet ) { iRet = ScMplsPayloadType(); } return iRet; } void DecodeMPLS(const uint8_t* pkt, const uint32_t len, Packet* p) { uint32_t* tmpMplsHdr; uint32_t mpls_h; uint32_t label; uint32_t mlen = 0; uint8_t exp; uint8_t bos = 0; uint8_t ttl; uint8_t chainLen = 0; uint32_t stack_len = len; int iRet = 0; pc.mpls++; UpdateMPLSStats(&sfBase, len, Active_PacketWasDropped()); tmpMplsHdr = (uint32_t *) pkt; p->mpls = NULL; while (!bos) { if(stack_len < MPLS_HEADER_LEN) { DecoderEvent(p, DECODE_BAD_MPLS, DECODE_BAD_MPLS_STR, 1, 1); pc.discards++; p->iph = NULL; p->family = NO_IP; return; } mpls_h = ntohl(*tmpMplsHdr); ttl = (uint8_t)(mpls_h & 0x000000FF); mpls_h = mpls_h>>8; bos = (uint8_t)(mpls_h & 0x00000001); exp = (uint8_t)(mpls_h & 0x0000000E); label = (mpls_h>>4) & 0x000FFFFF; if((labelmplsHdr.label = label; p->mplsHdr.exp = exp; p->mplsHdr.bos = bos; p->mplsHdr.ttl = ttl; /** p->mpls = &(p->mplsHdr); **/ p->mpls = tmpMplsHdr; if(!iRet) { iRet = ScMplsPayloadType(); } } tmpMplsHdr++; stack_len -= MPLS_HEADER_LEN; if ((ScMplsStackDepth() != -1) && (chainLen++ >= ScMplsStackDepth())) { DecoderEvent(p, DECODE_MPLS_LABEL_STACK, DECODE_MPLS_LABEL_STACK_STR, 1, 1); pc.discards++; p->iph = NULL; p->family = NO_IP; return; } } /* while bos not 1, peel off more labels */ mlen = (uint8_t*)tmpMplsHdr - pkt; PushLayer(PROTO_MPLS, p, pkt, mlen); mlen = len - mlen; if ( ScTunnelBypassEnabled(TUNNEL_MPLS) ) Active_SetTunnelBypass(); #ifdef MPLS_RFC4023_SUPPORT /* Currently, this additional check for MPLS payload type presumes: * Only IPv4 or IPv6 payloads are supported (based on code inspection). * * If MPLS payload type is Ethernet or PWE extensions, the following * functions: * * ScMplsPayloadCheck * checkMplsHdr and * ScMplsPayloadType * * must be revisited for performance and payload type checks as against, * static assignment from SnortConfig: sc->mpls_payload_type */ iRet = ScMplsPayloadCheck(*(uint8_t *)tmpMplsHdr, iRet); #endif switch (iRet) { case MPLS_PAYLOADTYPE_IPV4: DecodeIP((uint8_t *)tmpMplsHdr, mlen, p); break; case MPLS_PAYLOADTYPE_IPV6: DecodeIPV6((uint8_t *)tmpMplsHdr, mlen, p); break; case MPLS_PAYLOADTYPE_ETHERNET: DecodeEthOverMPLS((uint8_t *)tmpMplsHdr, mlen, p); break; default: break; } return; } void DecodeEthOverMPLS(const uint8_t* pkt, const uint32_t len, Packet* p) { /* do a little validation */ if(len < ETHERNET_HEADER_LEN) { if (ScLogVerbose()) { ErrorMessage("Captured data length < Ethernet header length!" " (%d bytes)\n", len); } p->iph = NULL; p->family = NO_IP; // TBD add decoder drop event for eth over MPLS cap len issue pc.discards++; pc.ethdisc++; return; } /* lay the ethernet structure over the packet data */ p->eh = (EtherHdr *) pkt; // FIXTHIS squashes outer eth! PushLayer(PROTO_ETH, p, pkt, sizeof(*p->eh)); DEBUG_WRAP( DebugMessage(DEBUG_DECODE, "%X %X\n", *p->eh->ether_src, *p->eh->ether_dst); ); /* grab out the network type */ switch(ntohs(p->eh->ether_type)) { case ETHERNET_TYPE_IP: DEBUG_WRAP( DebugMessage(DEBUG_DECODE, "IP datagram size calculated to be %lu bytes\n", (unsigned long)(len - ETHERNET_HEADER_LEN)); ); DecodeIP(p->pkt + ETHERNET_HEADER_LEN, len - ETHERNET_HEADER_LEN, p); return; case ETHERNET_TYPE_ARP: case ETHERNET_TYPE_REVARP: DecodeARP(p->pkt + ETHERNET_HEADER_LEN, len - ETHERNET_HEADER_LEN, p); return; case ETHERNET_TYPE_IPV6: DecodeIPV6(p->pkt + ETHERNET_HEADER_LEN, (len - ETHERNET_HEADER_LEN), p); return; case ETHERNET_TYPE_PPPoE_DISC: case ETHERNET_TYPE_PPPoE_SESS: DecodePPPoEPkt(p->pkt + ETHERNET_HEADER_LEN, (len - ETHERNET_HEADER_LEN), p); return; #ifndef NO_NON_ETHER_DECODER case ETHERNET_TYPE_IPX: DecodeIPX(p->pkt + ETHERNET_HEADER_LEN, (len - ETHERNET_HEADER_LEN), p); return; #endif case ETHERNET_TYPE_LOOP: DecodeEthLoopback(p->pkt + ETHERNET_HEADER_LEN, (len - ETHERNET_HEADER_LEN), p); return; case ETHERNET_TYPE_8021Q: DecodeVlan(p->pkt + ETHERNET_HEADER_LEN, len - ETHERNET_HEADER_LEN, p); return; default: // TBD add decoder drop event for unknown mpls/eth type pc.other++; return; } return; } int isPrivateIP(uint32_t addr) { switch (addr & 0xff) { case 0x0a: return 1; break; case 0xac: if ((addr & 0xf000) == 0x1000) return 1; break; case 0xc0: if (((addr & 0xff00) ) == 0xa800) return 1; break; } return 0; } #endif // MPLS //-------------------------------------------------------------------- // decode.c::VLAN //-------------------------------------------------------------------- #define LEN_VLAN_LLC_OTHER (sizeof(VlanTagHdr) + sizeof(EthLlc) + sizeof(EthLlcOther)) void DecodeVlan(const uint8_t * pkt, const uint32_t len, Packet * p) { VlanTagHdr* vh; pc.vlan++; #ifdef GRE if (p->greh != NULL) pc.gre_vlan++; #endif if(len < sizeof(VlanTagHdr)) { DecoderEvent(p, DECODE_BAD_VLAN, DECODE_BAD_VLAN_STR, 1, 1); // TBD add decoder drop event for VLAN hdr len issue pc.discards++; p->iph = NULL; p->family = NO_IP; return; } vh = (VlanTagHdr *) pkt; #ifdef HAVE_DAQ_REAL_ADDRESSES if (!(p->pkth->flags & DAQ_PKT_FLAG_IGNORE_VLAN)) #endif p->vh = vh; DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Vlan traffic:\n"); DebugMessage(DEBUG_DECODE, " Priority: %d(0x%X)\n", VTH_PRIORITY(vh), VTH_PRIORITY(vh)); DebugMessage(DEBUG_DECODE, " CFI: %d\n", VTH_CFI(vh)); DebugMessage(DEBUG_DECODE, " Vlan ID: %d(0x%04X)\n", VTH_VLAN(vh), VTH_VLAN(vh)); DebugMessage(DEBUG_DECODE, " Vlan Proto: 0x%04X\n", ntohs(vh->vth_proto)); ); /* check to see if we've got an encapsulated LLC layer * http://www.geocities.com/billalexander/ethernet.html */ if(ntohs(vh->vth_proto) <= ETHERNET_MAX_LEN_ENCAP) { if(len < sizeof(VlanTagHdr) + sizeof(EthLlc)) { DecoderEvent(p, DECODE_BAD_VLAN_ETHLLC, DECODE_BAD_VLAN_ETHLLC_STR, 1, 1); pc.discards++; p->iph = NULL; p->family = NO_IP; return; } p->ehllc = (EthLlc *) (pkt + sizeof(VlanTagHdr)); DEBUG_WRAP( DebugMessage(DEBUG_DECODE, "LLC Header:\n"); DebugMessage(DEBUG_DECODE, " DSAP: 0x%X\n", p->ehllc->dsap); DebugMessage(DEBUG_DECODE, " SSAP: 0x%X\n", p->ehllc->ssap); ); if(p->ehllc->dsap == ETH_DSAP_IP && p->ehllc->ssap == ETH_SSAP_IP) { if ( len < LEN_VLAN_LLC_OTHER ) { DecoderEvent(p, DECODE_BAD_VLAN_OTHER, DECODE_BAD_VLAN_OTHER_STR, 1, 1); pc.discards++; p->iph = NULL; p->family = NO_IP; return; } p->ehllcother = (EthLlcOther *) (pkt + sizeof(VlanTagHdr) + sizeof(EthLlc)); DEBUG_WRAP( DebugMessage(DEBUG_DECODE, "LLC Other Header:\n"); DebugMessage(DEBUG_DECODE, " CTRL: 0x%X\n", p->ehllcother->ctrl); DebugMessage(DEBUG_DECODE, " ORG: 0x%02X%02X%02X\n", p->ehllcother->org_code[0], p->ehllcother->org_code[1], p->ehllcother->org_code[2]); DebugMessage(DEBUG_DECODE, " PROTO: 0x%04X\n", ntohs(p->ehllcother->proto_id)); ); PushLayer(PROTO_VLAN, p, pkt, sizeof(*vh)); switch(ntohs(p->ehllcother->proto_id)) { case ETHERNET_TYPE_IP: DecodeIP(p->pkt + LEN_VLAN_LLC_OTHER, len - LEN_VLAN_LLC_OTHER, p); return; case ETHERNET_TYPE_ARP: case ETHERNET_TYPE_REVARP: DecodeARP(p->pkt + LEN_VLAN_LLC_OTHER, len - LEN_VLAN_LLC_OTHER, p); return; case ETHERNET_TYPE_IPV6: DecodeIPV6(p->pkt + LEN_VLAN_LLC_OTHER, len - LEN_VLAN_LLC_OTHER, p); return; case ETHERNET_TYPE_8021Q: case ETHERNET_TYPE_8021AD: case ETHERNET_TYPE_QINQ_NS1: case ETHERNET_TYPE_QINQ_NS2: pc.nested_vlan++; DecodeVlan(p->pkt + LEN_VLAN_LLC_OTHER, len - LEN_VLAN_LLC_OTHER, p); return; case ETHERNET_TYPE_LOOP: DecodeEthLoopback(p->pkt + LEN_VLAN_LLC_OTHER, len - LEN_VLAN_LLC_OTHER, p); return; #ifndef NO_NON_ETHER_DECODER case ETHERNET_TYPE_IPX: DecodeIPX(p->pkt + LEN_VLAN_LLC_OTHER, len - LEN_VLAN_LLC_OTHER, p); return; #endif case ETHERNET_TYPE_PPPoE_DISC: case ETHERNET_TYPE_PPPoE_SESS: DecodePPPoEPkt(p->pkt + LEN_VLAN_LLC_OTHER, len - LEN_VLAN_LLC_OTHER, p); return; #ifdef MPLS case ETHERNET_TYPE_MPLS_MULTICAST: if(!ScMplsMulticast()) { DecoderEvent(p, DECODE_BAD_MPLS, DECODE_MULTICAST_MPLS_STR, 1, 1); } /* Fall through */ case ETHERNET_TYPE_MPLS_UNICAST: DecodeMPLS(p->pkt + LEN_VLAN_LLC_OTHER, len - LEN_VLAN_LLC_OTHER, p); return; #endif default: // TBD add decoder drop event for unknown vlan/eth type pc.other++; return; } } } else { PushLayer(PROTO_VLAN, p, pkt, sizeof(*vh)); switch(ntohs(vh->vth_proto)) { case ETHERNET_TYPE_IP: DecodeIP(pkt + sizeof(VlanTagHdr), len - sizeof(VlanTagHdr), p); return; case ETHERNET_TYPE_ARP: case ETHERNET_TYPE_REVARP: DecodeARP(pkt + sizeof(VlanTagHdr), len - sizeof(VlanTagHdr), p); return; case ETHERNET_TYPE_IPV6: DecodeIPV6(pkt +sizeof(VlanTagHdr), len - sizeof(VlanTagHdr), p); return; case ETHERNET_TYPE_8021Q: case ETHERNET_TYPE_8021AD: case ETHERNET_TYPE_QINQ_NS1: case ETHERNET_TYPE_QINQ_NS2: pc.nested_vlan++; DecodeVlan(pkt + sizeof(VlanTagHdr), len - sizeof(VlanTagHdr), p); return; case ETHERNET_TYPE_LOOP: DecodeEthLoopback(pkt + sizeof(VlanTagHdr), len - sizeof(VlanTagHdr), p); return; #ifndef NO_NON_ETHER_DECODER case ETHERNET_TYPE_IPX: DecodeIPX(pkt + sizeof(VlanTagHdr), len - sizeof(VlanTagHdr), p); return; #endif case ETHERNET_TYPE_PPPoE_DISC: case ETHERNET_TYPE_PPPoE_SESS: DecodePPPoEPkt(pkt + sizeof(VlanTagHdr), len - sizeof(VlanTagHdr), p); return; #ifdef MPLS case ETHERNET_TYPE_MPLS_MULTICAST: if(!ScMplsMulticast()) { SnortEventqAdd(GENERATOR_SNORT_DECODE, DECODE_BAD_MPLS, 1, DECODE_CLASS, 3, DECODE_MULTICAST_MPLS_STR, 0); } case ETHERNET_TYPE_MPLS_UNICAST: DecodeMPLS(pkt + sizeof(VlanTagHdr), len - sizeof(VlanTagHdr), p); return; #endif case ETHERNET_TYPE_CISCO_META: DecodeCiscoMeta(pkt + sizeof(VlanTagHdr), len - sizeof(VlanTagHdr), p); return; default: // TBD add decoder drop event for unknown vlan/eth type pc.other++; return; } } // TBD add decoder drop event for unknown vlan/llc type pc.other++; return; } //-------------------------------------------------------------------- // decode.c::PPP related //-------------------------------------------------------------------- /* * Function: DecodePPPoEPkt(Packet *, char *, DAQ_PktHdr_t*, uint8_t*) * * Purpose: Decode those fun loving ethernet packets, one at a time! * * Arguments: p => pointer to the decoded packet struct * user => Utility pointer (unused) * pkthdr => ptr to the packet header * pkt => pointer to the real live packet data * * Returns: void function * * see http://www.faqs.org/rfcs/rfc2516.html * */ void DecodePPPoEPkt(const uint8_t* pkt, const uint32_t len, Packet* p) { //PPPoE_Tag *ppppoe_tag=0; //PPPoE_Tag tag; /* needed to avoid alignment problems */ DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "PPPoE with len: %lu\n", (unsigned long)len);); /* do a little validation */ if(len < PPPOE_HEADER_LEN) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Captured data length < PPPoE header length! " "(%d bytes)\n", len);); DecoderEvent(p, DECODE_BAD_PPPOE, DECODE_BAD_PPPOE_STR, 1, 1); return; } DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "%X %X\n", *p->eh->ether_src, *p->eh->ether_dst);); /* lay the PPP over ethernet structure over the packet data */ p->pppoeh = (PPPoEHdr *)pkt; /* grab out the network type */ switch(ntohs(p->eh->ether_type)) { case ETHERNET_TYPE_PPPoE_DISC: DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "(PPPOE Discovery) ");); break; case ETHERNET_TYPE_PPPoE_SESS: DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "(PPPOE Session) ");); break; default: return; } #ifdef DEBUG_MSGS switch(p->pppoeh->code) { case PPPoE_CODE_PADI: /* The Host sends the PADI packet with the DESTINATION_ADDR set * to the broadcast address. The CODE field is set to 0x09 and * the SESSION_ID MUST be set to 0x0000. * * The PADI packet MUST contain exactly one TAG of TAG_TYPE * Service-Name, indicating the service the Host is requesting, * and any number of other TAG types. An entire PADI packet * (including the PPPoE header) MUST NOT exceed 1484 octets so * as to leave sufficient room for a relay agent to add a * Relay-Session-Id TAG. */ DebugMessage(DEBUG_DECODE, "Active Discovery Initiation (PADI)\n"); break; case PPPoE_CODE_PADO: /* When the Access Concentrator receives a PADI that it can * serve, it replies by sending a PADO packet. The * DESTINATION_ADDR is the unicast address of the Host that * sent the PADI. The CODE field is set to 0x07 and the * SESSION_ID MUST be set to 0x0000. * * The PADO packet MUST contain one AC-Name TAG containing the * Access Concentrator's name, a Service-Name TAG identical to * the one in the PADI, and any number of other Service-Name * TAGs indicating other services that the Access Concentrator * offers. If the Access Concentrator can not serve the PADI * it MUST NOT respond with a PADO. */ DebugMessage(DEBUG_DECODE, "Active Discovery Offer (PADO)\n"); break; case PPPoE_CODE_PADR: /* Since the PADI was broadcast, the Host may receive more than * one PADO. The Host looks through the PADO packets it receives * and chooses one. The choice can be based on the AC-Name or * the Services offered. The Host then sends one PADR packet * to the Access Concentrator that it has chosen. The * DESTINATION_ADDR field is set to the unicast Ethernet address * of the Access Concentrator that sent the PADO. The CODE * field is set to 0x19 and the SESSION_ID MUST be set to 0x0000. * * The PADR packet MUST contain exactly one TAG of TAG_TYPE * Service-Name, indicating the service the Host is requesting, * and any number of other TAG types. */ DebugMessage(DEBUG_DECODE, "Active Discovery Request (PADR)\n"); break; case PPPoE_CODE_PADS: /* When the Access Concentrator receives a PADR packet, it * prepares to begin a PPP session. It generates a unique * SESSION_ID for the PPPoE session and replies to the Host with * a PADS packet. The DESTINATION_ADDR field is the unicast * Ethernet address of the Host that sent the PADR. The CODE * field is set to 0x65 and the SESSION_ID MUST be set to the * unique value generated for this PPPoE session. * * The PADS packet contains exactly one TAG of TAG_TYPE * Service-Name, indicating the service under which Access * Concentrator has accepted the PPPoE session, and any number * of other TAG types. * * If the Access Concentrator does not like the Service-Name in * the PADR, then it MUST reply with a PADS containing a TAG of * TAG_TYPE Service-Name-Error (and any number of other TAG * types). In this case the SESSION_ID MUST be set to 0x0000. */ DebugMessage(DEBUG_DECODE, "Active Discovery " "Session-confirmation (PADS)\n"); break; case PPPoE_CODE_PADT: /* This packet may be sent anytime after a session is established * to indicate that a PPPoE session has been terminated. It may * be sent by either the Host or the Access Concentrator. The * DESTINATION_ADDR field is a unicast Ethernet address, the * CODE field is set to 0xa7 and the SESSION_ID MUST be set to * indicate which session is to be terminated. No TAGs are * required. * * When a PADT is received, no further PPP traffic is allowed to * be sent using that session. Even normal PPP termination * packets MUST NOT be sent after sending or receiving a PADT. * A PPP peer SHOULD use the PPP protocol itself to bring down a * PPPoE session, but the PADT MAY be used when PPP can not be * used. */ DebugMessage(DEBUG_DECODE, "Active Discovery Terminate (PADT)\n"); break; case PPPoE_CODE_SESS: DebugMessage(DEBUG_DECODE, "Session Packet (SESS)\n"); break; default: DebugMessage(DEBUG_DECODE, "(Unknown)\n"); break; } #endif if (ntohs(p->eh->ether_type) != ETHERNET_TYPE_PPPoE_DISC) { PushLayer(PROTO_PPPOE, p, pkt, PPPOE_HEADER_LEN); DecodePppPktEncapsulated(pkt + PPPOE_HEADER_LEN, len - PPPOE_HEADER_LEN, p); return; } else { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Returning early on PPPOE discovery packet\n");); return; } #if 0 ppppoe_tag = (PPPoE_Tag *)(pkt + sizeof(PPPoEHdr)); while (ppppoe_tag < (PPPoE_Tag *)(pkt + len)) { if (((char*)(ppppoe_tag)+(sizeof(PPPoE_Tag)-1)) > (char*)(pkt + len)) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Not enough data in packet for PPPOE Tag\n");); break; } /* no guarantee in PPPoE spec that ppppoe_tag is aligned at all... */ memcpy(&tag, ppppoe_tag, sizeof(tag)); DEBUG_WRAP( DebugMessage(DEBUG_DECODE, "\tPPPoE tag:\ntype: %04x length: %04x ", ntohs(tag.type), ntohs(tag.length));); #ifdef DEBUG_MSGS switch(ntohs(tag.type)) { case PPPoE_TAG_END_OF_LIST: DebugMessage(DEBUG_DECODE, "(End of list)\n\t"); break; case PPPoE_TAG_SERVICE_NAME: DebugMessage(DEBUG_DECODE, "(Service name)\n\t"); break; case PPPoE_TAG_AC_NAME: DebugMessage(DEBUG_DECODE, "(AC Name)\n\t"); break; case PPPoE_TAG_HOST_UNIQ: DebugMessage(DEBUG_DECODE, "(Host Uniq)\n\t"); break; case PPPoE_TAG_AC_COOKIE: DebugMessage(DEBUG_DECODE, "(AC Cookie)\n\t"); break; case PPPoE_TAG_VENDOR_SPECIFIC: DebugMessage(DEBUG_DECODE, "(Vendor Specific)\n\t"); break; case PPPoE_TAG_RELAY_SESSION_ID: DebugMessage(DEBUG_DECODE, "(Relay Session ID)\n\t"); break; case PPPoE_TAG_SERVICE_NAME_ERROR: DebugMessage(DEBUG_DECODE, "(Service Name Error)\n\t"); break; case PPPoE_TAG_AC_SYSTEM_ERROR: DebugMessage(DEBUG_DECODE, "(AC System Error)\n\t"); break; case PPPoE_TAG_GENERIC_ERROR: DebugMessage(DEBUG_DECODE, "(Generic Error)\n\t"); break; default: DebugMessage(DEBUG_DECODE, "(Unknown)\n\t"); break; } #endif #ifdef DEBUG_MSGS if (ntohs(tag.length) > 0) { char *buf; int i; switch (ntohs(tag.type)) { case PPPoE_TAG_SERVICE_NAME: case PPPoE_TAG_AC_NAME: case PPPoE_TAG_SERVICE_NAME_ERROR: case PPPoE_TAG_AC_SYSTEM_ERROR: case PPPoE_TAG_GENERIC_ERROR: * ascii data * buf = (char *)SnortAlloc(ntohs(tag.length) + 1); strlcpy(buf, (char *)(ppppoe_tag+1), ntohs(tag.length)); DebugMessage(DEBUG_DECODE, "data (UTF-8): %s\n", buf); free(buf); break; case PPPoE_TAG_HOST_UNIQ: case PPPoE_TAG_AC_COOKIE: case PPPoE_TAG_RELAY_SESSION_ID: DebugMessage(DEBUG_DECODE, "data (bin): "); for (i = 0; i < ntohs(tag.length); i++) DebugMessage(DEBUG_DECODE, "%02x", *(((unsigned char *)ppppoe_tag) + sizeof(PPPoE_Tag) + i)); DebugMessage(DEBUG_DECODE, "\n"); break; default: DebugMessage(DEBUG_DECODE, "unrecognized data\n"); break; } } #endif ppppoe_tag = (PPPoE_Tag *)((char *)(ppppoe_tag+1)+ntohs(tag.length)); } #endif /* #if 0 */ return; } /* * Function: DecodePppPktEncapsulated(Packet *, const uint32_t len, uint8_t*) * * Purpose: Decode PPP traffic (RFC1661 framing). * * Arguments: p => pointer to decoded packet struct * len => length of data to process * pkt => pointer to the real live packet data * * Returns: void function */ void DecodePppPktEncapsulated(const uint8_t* pkt, const uint32_t len, Packet* p) { static int had_vj = 0; uint16_t protocol; uint32_t hlen = 1; /* HEADER - try 1 then 2 */ DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "PPP Packet!\n");); #ifdef WORDS_MUSTALIGN DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet with PPP header. " "PPP is only 1 or 2 bytes and will throw off " "alignment on this architecture when decoding IP, " "causing a bus error - stop decoding packet.\n");); p->data = pkt; p->dsize = (uint16_t)len; return; #endif /* WORDS_MUSTALIGN */ #ifdef GRE if (p->greh != NULL) pc.gre_ppp++; #endif /* GRE */ /* do a little validation: * */ if(len < 2) { if (ScLogVerbose()) { ErrorMessage("Length not big enough for even a single " "header or a one byte payload\n"); } return; } if(pkt[0] & 0x01) { /* Check for protocol compression rfc1661 section 5 * */ hlen = 1; protocol = pkt[0]; } else { protocol = ntohs(*((uint16_t *)pkt)); hlen = 2; } /* * We only handle uncompressed packets. Handling VJ compression would mean * to implement a PPP state machine. */ switch (protocol) { case PPP_VJ_COMP: if (!had_vj) ErrorMessage("PPP link seems to use VJ compression, " "cannot handle compressed packets!\n"); had_vj = 1; break; case PPP_VJ_UCOMP: /* VJ compression modifies the protocol field. It must be set * to tcp (only TCP packets can be VJ compressed) */ if(len < (hlen + IP_HEADER_LEN)) { if (ScLogVerbose()) ErrorMessage("PPP VJ min packet length > captured len! " "(%d bytes)\n", len); return; } ((IPHdr *)(pkt + hlen))->ip_proto = IPPROTO_TCP; /* fall through */ case PPP_IP: PushLayer(PROTO_PPP_ENCAP, p, pkt, hlen); DecodeIP(pkt + hlen, len - hlen, p); break; case PPP_IPV6: PushLayer(PROTO_PPP_ENCAP, p, pkt, hlen); DecodeIPV6(pkt + hlen, len - hlen, p); break; #ifndef NO_NON_ETHER_DECODER case PPP_IPX: PushLayer(PROTO_PPP_ENCAP, p, pkt, hlen); DecodeIPX(pkt + hlen, len - hlen, p); break; #endif } } //-------------------------------------------------------------------- // decode.c::Raw packets //-------------------------------------------------------------------- /* * Function: DecodeRawPkt(Packet *, char *, DAQ_PktHdr_t*, uint8_t*) * * Purpose: Decodes packets coming in raw on layer 2, like PPP. Coded and * in by Jed Pickle (thanks Jed!) and modified for a few little tweaks * by me. * * Arguments: p => pointer to decoded packet struct * pkthdr => ptr to the packet header * pkt => pointer to the real live packet data * * Returns: void function */ void DecodeRawPkt(Packet * p, const DAQ_PktHdr_t * pkthdr, const uint8_t * pkt) { PROFILE_VARS; PREPROC_PROFILE_START(decodePerfStats); pc.total_processed++; memset(p, 0, PKT_ZERO_LEN); p->pkth = pkthdr; p->pkt = pkt; DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Raw IP4 Packet!\n");); DecodeIP(pkt, p->pkth->caplen, p); PREPROC_PROFILE_END(decodePerfStats); return; } // raw packets are predetermined to be ip4 (above) or ip6 (below) by the DLT void DecodeRawPkt6(Packet * p, const DAQ_PktHdr_t * pkthdr, const uint8_t * pkt) { PROFILE_VARS; PREPROC_PROFILE_START(decodePerfStats); pc.total_processed++; memset(p, 0, PKT_ZERO_LEN); p->pkth = pkthdr; p->pkt = pkt; DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Raw IP6 Packet!\n");); DecodeIPV6(pkt, p->pkth->caplen, p); PREPROC_PROFILE_END(decodePerfStats); return; } //-------------------------------------------------------------------- // decode.c::IP4 misc //-------------------------------------------------------------------- /* * Some IP Header tests * Land Attack(same src/dst ip) * Loopback (src or dst in 127/8 block) * Modified: 2/22/05-man for High Endian Architecture. */ #define IP4_THIS_NET 0x00 // msb #define IP4_MULTICAST 0x0E // ms nibble #define IP4_RESERVED 0x0F // ms nibble #define IP4_LOOPBACK 0x7F // msb #define IP4_BROADCAST 0xffffffff void IP4AddrTests (Packet* p) { uint8_t msb_src, msb_dst; #ifdef DAQ_CAPA_VRF uint16_t sAsId; uint16_t dAsId; sAsId = DAQ_GetSourceAddressSpaceID(p->pkth); dAsId = DAQ_GetDestinationAddressSpaceID(p->pkth); // check all 32 bits ... if((p->iph->ip_src.s_addr == p->iph->ip_dst.s_addr) && (sAsId == dAsId)) { DecoderEvent(p, DECODE_BAD_TRAFFIC_SAME_SRCDST, DECODE_BAD_TRAFFIC_SAME_SRCDST_STR, 1, 1); if( pkt_trace_enabled ) { addPktTraceData(VERDICT_REASON_SNORT, snprintf(trace_line, MAX_TRACE_LINE, "Packet is blocked since same source and destination")); } } #else if(p->iph->ip_src.s_addr == p->iph->ip_dst.s_addr) { DecoderEvent(p, DECODE_BAD_TRAFFIC_SAME_SRCDST, DECODE_BAD_TRAFFIC_SAME_SRCDST_STR, 1, 1); } #endif // check all 32 bits ... if ( Event_Enabled(DECODE_IP4_SRC_BROADCAST ) ) if ( p->iph->ip_src.s_addr == IP4_BROADCAST ) DecoderEvent(p, EVARGS(IP4_SRC_BROADCAST), 1, 1); if ( Event_Enabled(DECODE_IP4_DST_BROADCAST ) ) if ( p->iph->ip_dst.s_addr == IP4_BROADCAST ) DecoderEvent(p, EVARGS(IP4_DST_BROADCAST), 1, 1); /* Loopback traffic - don't use htonl for speed reasons - * s_addr is always in network order */ #ifdef WORDS_BIGENDIAN msb_src = (p->iph->ip_src.s_addr >> 24); msb_dst = (p->iph->ip_dst.s_addr >> 24); #else msb_src = (uint8_t)(p->iph->ip_src.s_addr & 0xff); msb_dst = (uint8_t)(p->iph->ip_dst.s_addr & 0xff); #endif // check the msb ... if ( msb_src == IP4_LOOPBACK || msb_dst == IP4_LOOPBACK ) { DecoderEvent(p, DECODE_BAD_TRAFFIC_LOOPBACK, DECODE_BAD_TRAFFIC_LOOPBACK_STR, 1, 1); } // check the msb ... if ( Event_Enabled(DECODE_IP4_SRC_THIS_NET ) ) if ( msb_src == IP4_THIS_NET ) DecoderEvent(p, EVARGS(IP4_SRC_THIS_NET), 1, 1); if ( Event_Enabled(DECODE_IP4_DST_THIS_NET ) ) if ( msb_dst == IP4_THIS_NET ) DecoderEvent(p, EVARGS(IP4_DST_THIS_NET), 1, 1); // check the 'msn' (most significant nibble) ... msb_src >>= 4; msb_dst >>= 4; if ( Event_Enabled(DECODE_IP4_SRC_MULTICAST) ) if ( msb_src == IP4_MULTICAST ) DecoderEvent(p, EVARGS(IP4_SRC_MULTICAST), 1, 1); if ( Event_Enabled(DECODE_IP4_SRC_RESERVED) ) { if ( msb_src == IP4_RESERVED || IpAddrSetContains(MulticastReservedIp, GET_SRC_ADDR(p)) ) { DecoderEvent(p, EVARGS(IP4_SRC_RESERVED), 1, 1); } } if ( Event_Enabled(DECODE_IP4_DST_RESERVED) ) { if ( msb_dst == IP4_RESERVED || IpAddrSetContains(MulticastReservedIp, GET_DST_ADDR(p)) ) { DecoderEvent(p, EVARGS(IP4_DST_RESERVED), 1, 1); } } } static inline void ICMP4AddrTests (Packet* p) { uint8_t msb_dst; uint32_t dst = sfaddr_get_ip4_value(GET_DST_IP(p)); // check all 32 bits; all set so byte order is irrelevant ... if ( Event_Enabled(DECODE_ICMP4_DST_BROADCAST ) ) if ( dst == IP4_BROADCAST ) DecoderEvent(p, EVARGS(ICMP4_DST_BROADCAST), 1, 1); /* - don't use htonl for speed reasons - * s_addr is always in network order */ #ifdef WORDS_BIGENDIAN msb_dst = (uint8_t)(dst >> 24); #else msb_dst = (uint8_t)(dst & 0xff); #endif // check the 'msn' (most significant nibble) ... msb_dst >>= 4; if ( Event_Enabled(DECODE_ICMP4_DST_MULTICAST) ) if ( msb_dst == IP4_MULTICAST ) DecoderEvent(p, EVARGS(ICMP4_DST_MULTICAST), 1, 1); } static inline void ICMP4MiscTests (Packet *p) { if ( Event_Enabled(DECODE_ICMP_PING_NMAP) ) { if ((p->dsize == 0) && (p->icmph->type == ICMP_ECHO)) DecoderEvent(p, EVARGS(ICMP_PING_NMAP), 1, 1); } if ( Event_Enabled(DECODE_ICMP_ICMPENUM) ) { if ((p->dsize == 0) && (p->icmph->s_icmp_seq == 666)) DecoderEvent(p, EVARGS(ICMP_ICMPENUM), 1, 1); } if ( Event_Enabled(DECODE_ICMP_REDIRECT_HOST) ) { if ((p->icmph->code == 1) && (p->icmph->type == ICMP_REDIRECT)) DecoderEvent(p, EVARGS(ICMP_REDIRECT_HOST), 1, 1); } if ( Event_Enabled(DECODE_ICMP_REDIRECT_NET) ) { if ((p->icmph->type == ICMP_REDIRECT) && (p->icmph->code == 0)) DecoderEvent(p, EVARGS(ICMP_REDIRECT_NET), 1, 1); } if ( Event_Enabled(DECODE_ICMP_TRACEROUTE_IPOPTS) ) { if (p->icmph->type == ICMP_ECHOREPLY) { int i; for (i = 0; i < p->ip_option_count; i++) { if (p->ip_options[i].code == IPOPT_RR) DecoderEvent(p, EVARGS(ICMP_TRACEROUTE_IPOPTS), 1, 1); } } } if ( Event_Enabled(DECODE_ICMP_SOURCE_QUENCH) ) { if ((p->icmph->type == ICMP_SOURCE_QUENCH) && (p->icmph->code == 0)) DecoderEvent(p, DECODE_ICMP_SOURCE_QUENCH, DECODE_ICMP_SOURCE_QUENCH_STR, 1, 1); } if ( Event_Enabled(DECODE_ICMP_BROADSCAN_SMURF_SCANNER) ) { if ((p->dsize == 4) && (p->icmph->type == ICMP_ECHO) && (p->icmph->s_icmp_seq == 0) && (p->icmph->code == 0)) DecoderEvent(p, EVARGS(ICMP_BROADSCAN_SMURF_SCANNER), 1, 1); } if ( Event_Enabled(DECODE_ICMP_DST_UNREACH_ADMIN_PROHIBITED) ) { if ((p->icmph->type == ICMP_DEST_UNREACH) && (p->icmph->code == 13)) DecoderEvent(p, EVARGS(ICMP_DST_UNREACH_ADMIN_PROHIBITED), 1, 1); } if ( Event_Enabled(DECODE_ICMP_DST_UNREACH_DST_HOST_PROHIBITED) ) { if ((p->icmph->type == ICMP_DEST_UNREACH) && (p->icmph->code == 10)) DecoderEvent(p, EVARGS(ICMP_DST_UNREACH_DST_HOST_PROHIBITED), 1, 1); } if ( Event_Enabled(DECODE_ICMP_DST_UNREACH_DST_NET_PROHIBITED) ) { if ((p->icmph->type == ICMP_DEST_UNREACH) && (p->icmph->code == 9)) DecoderEvent(p, EVARGS(ICMP_DST_UNREACH_DST_NET_PROHIBITED), 1, 1); } } /* IPv4-layer decoder rules */ static inline void IPMiscTests(Packet *p) { if ( Event_Enabled(DECODE_ICMP_DOS_ATTEMPT) ) { /* Yes, it's an ICMP-related vuln in IP options. */ uint8_t i, length, pointer; /* Alert on IP packets with either 0x07 (Record Route) or 0x44 (Timestamp) options that are specially crafted. */ for (i = 0; i < p->ip_option_count; i++) { if (p->ip_options[i].data == NULL) continue; if (p->ip_options[i].code == IPOPT_RR) { length = p->ip_options[i].len; if (length < 1) continue; pointer = p->ip_options[i].data[0]; /* If the pointer goes past the end of the data, then the data is full. That's okay. */ if (pointer >= length + 2) continue; /* If the remaining space in the option isn't a multiple of 4 bytes, alert. */ if (((length + 3) - pointer) % 4) DecoderEvent(p, EVARGS(ICMP_DOS_ATTEMPT), 1, 1); } else if (p->ip_options[i].code == IPOPT_TS) { length = p->ip_options[i].len; if (length < 2) continue; pointer = p->ip_options[i].data[0]; /* If the pointer goes past the end of the data, then the data is full. That's okay. */ if (pointer >= length + 2) continue; /* If the remaining space in the option isn't a multiple of 4 bytes, alert. */ if (((length + 3) - pointer) % 4) DecoderEvent(p, EVARGS(ICMP_DOS_ATTEMPT), 1, 1); /* If there is a timestamp + address, we need a multiple of 8 bytes instead. */ if ((p->ip_options[i].data[1] & 0x01) && /* address flag */ (((length + 3) - pointer) % 8)) DecoderEvent(p, EVARGS(ICMP_DOS_ATTEMPT), 1, 1); } } } if ( Event_Enabled(DECODE_IP_OPTION_SET) ) { if (p->ip_option_count > 0) DecoderEvent(p, EVARGS(IP_OPTION_SET), 1, 1); } if ( Event_Enabled(DECODE_IP_RESERVED_FRAG_BIT) ) { if (p->rf) DecoderEvent(p, EVARGS(IP_RESERVED_FRAG_BIT), 1, 1); } } //-------------------------------------------------------------------- // decode.c::IP4 vulnerabilities //-------------------------------------------------------------------- /* This PGM NAK function started off as an SO rule, sid 8351. */ static inline int pgm_nak_detect (const uint8_t *data, uint16_t length) { uint16_t data_left; uint16_t checksum; const PGM_HEADER *header; if (NULL == data) { return PGM_NAK_ERR; } /* request must be bigger than 44 bytes to cause vuln */ if (length <= sizeof(PGM_HEADER) || (length % 4) != 0) { return PGM_NAK_ERR; } header = (PGM_HEADER *) data; if (8 != header->type) { return PGM_NAK_ERR; } if (2 != header->nak.opt.type) { return PGM_NAK_ERR; } /* * alert if the amount of data after the options is more than the length * specified. */ data_left = length - 36; if (data_left > header->nak.opt.len) { /* checksum is expensive... do that only if the length is bad */ if (header->checksum != 0) { checksum = in_chksum_ip((const unsigned short*)data, (int)length); if (checksum != 0) return PGM_NAK_ERR; } return PGM_NAK_VULN; } return PGM_NAK_OK; } static inline void CheckPGMVuln(Packet *p) { if ( pgm_nak_detect(p->data, p->dsize) == PGM_NAK_VULN ) DecoderEvent(p, EVARGS(PGM_NAK_OVERFLOW), 1, 1); } /* This function is a port of an old .so rule, sid 3:8092. */ static inline void CheckIGMPVuln(Packet *p) { int i, alert = 0; if (p->dsize >= 1 && p->data[0] == 0x11) { if (p->ip_options_data != NULL) { if (p->ip_options_len >= 2) { if (*(p->ip_options_data) == 0 && *(p->ip_options_data+1) == 0) { DecoderEvent(p, EVARGS(IGMP_OPTIONS_DOS), 1, 1); return; } } } for(i=0; i< (int) p->ip_option_count; i++) { /* All IGMPv2 packets contain IP option code 148 (router alert). This vulnerability only applies to IGMPv3, so return early. */ if (p->ip_options[i].code == 148) { return; /* No alert. */ } if (p->ip_options[i].len == 1) { alert++; } } if (alert > 0) DecoderEvent(p, EVARGS(IGMP_OPTIONS_DOS), 1, 1); } } //-------------------------------------------------------------------- // decode.c::IP4 decoder //-------------------------------------------------------------------- /* Function: DecodeIPv4Proto * * Gernalized IPv4 next protocol decoder dispatching. * * Arguments: proto => IPPROTO value of the next protocol * pkt => ptr to the packet data * len => length from here to the end of the packet * p => pointer to the packet decode struct * */ static inline void DecodeIPv4Proto(const uint8_t proto, const uint8_t *pkt, const uint32_t len, Packet *p) { switch(proto) { case IPPROTO_TCP: pc.tcp++; DecodeTCP(pkt, len, p); return; case IPPROTO_UDP: pc.udp++; DecodeUDP(pkt, len, p); return; case IPPROTO_ICMP: pc.icmp++; DecodeICMP(pkt, len, p); return; #ifdef MPLS_RFC4023_SUPPORT case IPPROTO_MPLS: /*MPLS IN IP (protocol number 137 */ DecodeMPLS(pkt, len, p); return; #endif #ifdef GRE case IPPROTO_IPV6: if (len < 40) { /* Insufficient size for IPv6 Header. */ /* This could be an attempt to exploit Linux kernel * vulnerability, so log an alert */ DecoderEvent(p, DECODE_IPV6_TUNNELED_IPV4_TRUNCATED, DECODE_IPV6_TUNNELED_IPV4_TRUNCATED_STR, 1, 1); } pc.ip4ip6++; if ( ScTunnelBypassEnabled(TUNNEL_6IN4) ) Active_SetTunnelBypass(); DecodeIPV6(pkt, len, p); return; case IPPROTO_GRE: pc.gre++; DecodeGRE(pkt, len, p); return; case IPPROTO_IPIP: pc.ip4ip4++; if ( ScTunnelBypassEnabled(TUNNEL_4IN4) ) Active_SetTunnelBypass(); DecodeIP(pkt, len, p); return; #endif case IPPROTO_ESP: if (ScESPDecoding()) DecodeESP(pkt, len, p); return; case IPPROTO_AH: DecodeAH(pkt, len, p); return; case IPPROTO_SWIPE: case IPPROTO_IP_MOBILITY: case IPPROTO_SUN_ND: case IPPROTO_PIM: if ( Event_Enabled(DECODE_IP_BAD_PROTO) ) DecoderEvent(p, EVARGS(IP_BAD_PROTO), 1, 1); pc.other++; p->data = pkt; p->dsize = (uint16_t)len; return; case IPPROTO_PGM: pc.other++; p->data = pkt; p->dsize = (uint16_t)len; if ( Event_Enabled(DECODE_PGM_NAK_OVERFLOW) ) CheckPGMVuln(p); return; case IPPROTO_IGMP: pc.other++; p->data = pkt; p->dsize = (uint16_t)len; if ( Event_Enabled(DECODE_IGMP_OPTIONS_DOS) ) CheckIGMPVuln(p); return; default: if ( Event_Enabled(DECODE_IP_UNASSIGNED_PROTO) ) { if (GET_IPH_PROTO(p) >= MIN_UNASSIGNED_IP_PROTO) DecoderEvent(p, EVARGS(IP_UNASSIGNED_PROTO), 1, 1); } pc.other++; p->data = pkt; p->dsize = (uint16_t)len; return; } } /* * Function: DecodeIP(uint8_t *, const uint32_t, Packet *) * * Purpose: Decode the IP network layer * * Arguments: pkt => ptr to the packet data * len => length from here to the end of the packet * p => pointer to the packet decode struct * * Returns: void function */ void DecodeIP(const uint8_t * pkt, const uint32_t len, Packet * p) { uint32_t ip_len; /* length from the start of the ip hdr to the pkt end */ uint32_t hlen; /* ip header length */ pc.ip++; #ifdef GRE if (p->greh != NULL) pc.gre_ip++; #endif DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n");); /* do a little validation */ if(len < IP_HEADER_LEN) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "WARNING: Truncated IP4 header (%d bytes).\n", len);); if ( Event_Enabled(DECODE_IP4_HDR_TRUNC) && ((p->packet_flags & PKT_UNSURE_ENCAP) == 0)) DecoderEvent(p, EVARGS(IP4_HDR_TRUNC), 1, 1); p->iph = NULL; p->family = NO_IP; pc.discards++; pc.ipdisc++; return; } if (p->family != NO_IP) { if (p->encapsulated) { DecoderAlertEncapsulated(p, DECODE_IP_MULTIPLE_ENCAPSULATION, DECODE_IP_MULTIPLE_ENCAPSULATION_STR, pkt, len); return; } else { p->encapsulated = 1; p->outer_iph = p->iph; p->outer_ip_data = p->ip_data; p->outer_ip_dsize = p->ip_dsize; } } /* lay the IP struct over the raw data */ p->inner_iph = p->iph = (IPHdr *)pkt; /* * with datalink DLT_RAW it's impossible to differ ARP datagrams from IP. * So we are just ignoring non IP datagrams */ if(IP_VER((IPHdr*)pkt) != 4) { if ((p->packet_flags & PKT_UNSURE_ENCAP) == 0) DecoderEvent(p, DECODE_NOT_IPV4_DGRAM, DECODE_NOT_IPV4_DGRAM_STR, 1, 1); p->iph = NULL; p->family = NO_IP; pc.discards++; pc.ipdisc++; return; } sfiph_build(p, p->iph, AF_INET); /* get the IP datagram length */ ip_len = ntohs(p->iph->ip_len); /* get the IP header length */ hlen = IP_HLEN(p->iph) << 2; /* header length sanity check */ if(hlen < IP_HEADER_LEN) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Bogus IP header length of %i bytes\n", hlen);); DecoderEvent(p, DECODE_IPV4_INVALID_HEADER_LEN, DECODE_IPV4_INVALID_HEADER_LEN_STR, 1, 1); p->iph = NULL; p->family = NO_IP; pc.discards++; pc.ipdisc++; return; } if (ip_len > len) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "IP Len field is %d bytes bigger than captured length.\n" " (ip.len: %lu, cap.len: %lu)\n", ip_len - len, ip_len, len);); DecoderEventDrop(p, DECODE_IPV4_DGRAM_GT_CAPLEN, DECODE_IPV4_DGRAM_GT_CAPLEN_STR, ScDecoderOversizedAlerts(), ScDecoderOversizedDrops()); p->iph = NULL; p->family = NO_IP; pc.discards++; pc.ipdisc++; return; } #if 0 // There is no need to alert when (ip_len < len). // Libpcap will capture more bytes than are part of the IP payload. // These could be Ethernet trailers, ESP trailers, etc. // This code is left in, commented, to keep us from re-writing it later. else if (ip_len < len) { if (ScLogVerbose()) ErrorMessage("IP Len field is %d bytes " "smaller than captured length.\n" " (ip.len: %lu, cap.len: %lu)\n", len - ip_len, ip_len, len); } #endif if(ip_len < hlen) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "IP dgm len (%d bytes) < IP hdr " "len (%d bytes), packet discarded\n", ip_len, hlen);); DecoderEvent(p, DECODE_IPV4_DGRAM_LT_IPHDR, DECODE_IPV4_DGRAM_LT_IPHDR_STR, 1, 1); p->iph = NULL; p->family = NO_IP; pc.discards++; pc.ipdisc++; return; } /* * IP Header tests: Land attack, and Loop back test */ if(ScIdsMode()) { IP4AddrTests(p); } #ifdef HAVE_DAQ_DECRYPTED_SSL if (!(p->pkth->flags & DAQ_PKT_FLAG_DECRYPTED_SSL) && ScIpChecksums()) #else if (ScIpChecksums()) #endif { /* routers drop packets with bad IP checksums, we don't really * need to check them (should make this a command line/config * option */ int16_t csum = in_chksum_ip((const unsigned short *)p->iph, hlen); if(csum) { p->error_flags |= PKT_ERR_CKSUM_IP; DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Bad IP checksum\n");); #ifdef REG_TEST if (getRegTestFlags() & REG_TEST_FLAG_STREAM_DECODE) printf("Bad IP checksum | "); #endif if ( ScIdsMode() ) queueExecDrop(execIpChksmDrop, p); } #ifdef DEBUG_MSGS else { DebugMessage(DEBUG_DECODE, "IP Checksum: OK\n"); } #endif /* DEBUG */ } PushLayer(PROTO_IP4, p, pkt, hlen); /* test for IP options */ p->ip_options_len = (uint16_t)(hlen - IP_HEADER_LEN); if(p->ip_options_len > 0) { p->ip_options_data = pkt + IP_HEADER_LEN; DecodeIPOptions((pkt + IP_HEADER_LEN), p->ip_options_len, p); } else { #ifdef GRE /* If delivery header for GRE encapsulated packet is IP and it * had options, the packet's ip options will be refering to this * outer IP's options * Zero these options so they aren't associated with this inner IP * since p->iph will be pointing to this inner IP */ if (p->encapsulated) { p->ip_options_data = NULL; p->ip_options_len = 0; } #endif p->ip_option_count = 0; } /* set the real IP length for logging */ p->actual_ip_len = (uint16_t) ip_len; /* set the remaining packet length */ ip_len -= hlen; /* check for fragmented packets */ p->frag_offset = ntohs(p->iph->ip_off); /* * get the values of the reserved, more * fragments and don't fragment flags */ p->rf = (uint8_t)((p->frag_offset & 0x8000) >> 15); p->df = (uint8_t)((p->frag_offset & 0x4000) >> 14); p->mf = (uint8_t)((p->frag_offset & 0x2000) >> 13); /* mask off the high bits in the fragment offset field */ p->frag_offset &= 0x1FFF; if ( Event_Enabled(DECODE_IP4_DF_OFFSET) ) if ( p->df && p->frag_offset ) DecoderEvent(p, EVARGS(IP4_DF_OFFSET), 1, 1); if ( Event_Enabled(DECODE_IP4_LEN_OFFSET) ) if ( p->frag_offset + p->actual_ip_len > IP_MAXPACKET ) DecoderEvent(p, EVARGS(IP4_LEN_OFFSET), 1, 1); if(p->frag_offset || p->mf) { if ( !ip_len && Event_Enabled(DECODE_ZERO_LENGTH_FRAG) ) { DecoderEvent(p, DECODE_ZERO_LENGTH_FRAG, DECODE_ZERO_LENGTH_FRAG_STR, 1, 1); p->frag_flag = 0; } else { /* set the packet fragment flag */ p->frag_flag = 1; p->ip_frag_start = pkt + hlen; p->ip_frag_len = (uint16_t)ip_len; pc.frags++; } } else { p->frag_flag = 0; } if(Event_Enabled(DECODE_BAD_FRAGBITS)) { if( p->mf && p->df ) { DecoderEvent(p, DECODE_BAD_FRAGBITS, DECODE_BAD_FRAGBITS_STR, 1, 1); } } /* Set some convienience pointers */ p->ip_data = pkt + hlen; p->ip_dsize = (u_short) ip_len; if (ScIdsMode()) { /* See if there are any ip_proto only rules that match */ fpEvalIpProtoOnlyRules(snort_conf->ip_proto_only_lists, p); p->proto_bits |= PROTO_BIT__IP; } IPMiscTests(p); /* if this packet isn't a fragment * or if it is, its a UDP packet and offset is 0 */ if(!(p->frag_flag) || (p->frag_flag && (p->frag_offset == 0) && (p->iph->ip_proto == IPPROTO_UDP))) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "IP header length: %lu\n", (unsigned long)hlen);); DecodeIPv4Proto(p->iph->ip_proto, pkt+hlen, ip_len, p); } else { /* set the payload pointer and payload size */ p->data = pkt + hlen; p->dsize = (u_short) ip_len; } } //-------------------------------------------------------------------- // decode.c::ICMP //-------------------------------------------------------------------- /* * Function: DecodeICMP(uint8_t *, const uint32_t, Packet *) * * Purpose: Decode the ICMP transport layer * * Arguments: pkt => ptr to the packet data * len => length from here to the end of the packet * p => pointer to the decoded packet struct * * Returns: void function */ void DecodeICMP(const uint8_t * pkt, const uint32_t len, Packet * p) { if(len < ICMP_HEADER_LEN) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "WARNING: Truncated ICMP4 header (%d bytes).\n", len);); if ( Event_Enabled(DECODE_ICMP4_HDR_TRUNC) ) DecoderEvent(p, EVARGS(ICMP4_HDR_TRUNC), 1, 1); p->icmph = NULL; pc.discards++; pc.icmpdisc++; return; } /* set the header ptr first */ p->icmph = (ICMPHdr *) pkt; switch (p->icmph->type) { // fall through ... case ICMP_SOURCE_QUENCH: case ICMP_DEST_UNREACH: case ICMP_REDIRECT: case ICMP_TIME_EXCEEDED: case ICMP_PARAMETERPROB: case ICMP_ECHOREPLY: case ICMP_ECHO: case ICMP_ROUTER_ADVERTISE: case ICMP_ROUTER_SOLICIT: case ICMP_INFO_REQUEST: case ICMP_INFO_REPLY: if (len < 8) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Truncated ICMP header(%d bytes)\n", len);); DecoderEvent(p, DECODE_ICMP_DGRAM_LT_ICMPHDR, DECODE_ICMP_DGRAM_LT_ICMPHDR_STR, 1, 1); p->icmph = NULL; pc.discards++; pc.icmpdisc++; return; } break; case ICMP_TIMESTAMP: case ICMP_TIMESTAMPREPLY: if (len < 20) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Truncated ICMP header(%d bytes)\n", len);); DecoderEvent(p, DECODE_ICMP_DGRAM_LT_TIMESTAMPHDR, DECODE_ICMP_DGRAM_LT_TIMESTAMPHDR_STR, 1, 1); p->icmph = NULL; pc.discards++; pc.icmpdisc++; return; } break; case ICMP_ADDRESS: case ICMP_ADDRESSREPLY: if (len < 12) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Truncated ICMP header(%d bytes)\n", len);); DecoderEvent(p, DECODE_ICMP_DGRAM_LT_ADDRHDR, DECODE_ICMP_DGRAM_LT_ADDRHDR_STR, 1, 1); p->icmph = NULL; pc.discards++; pc.icmpdisc++; return; } break; default: if ( Event_Enabled(DECODE_ICMP4_TYPE_OTHER) ) DecoderEvent(p, EVARGS(ICMP4_TYPE_OTHER), 1, 1); break; } if (ScIcmpChecksums()) { uint16_t csum = in_chksum_icmp((uint16_t *)p->icmph, len); if(csum) { p->error_flags |= PKT_ERR_CKSUM_ICMP; DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Bad ICMP Checksum\n");); if ( ScIdsMode() ) queueExecDrop(execIcmpChksmDrop, p); } else { DEBUG_WRAP(DebugMessage(DEBUG_DECODE,"ICMP Checksum: OK\n");); } } p->dsize = (u_short)(len - ICMP_HEADER_LEN); p->data = pkt + ICMP_HEADER_LEN; DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "ICMP type: %d code: %d\n", p->icmph->type, p->icmph->code);); switch(p->icmph->type) { case ICMP_ECHO: ICMP4AddrTests(p); // fall through ... case ICMP_ECHOREPLY: /* setup the pkt id and seq numbers */ p->dsize -= sizeof(struct idseq); /* add the size of the * echo ext to the data * ptr and subtract it * from the data size */ p->data += sizeof(struct idseq); PushLayer(PROTO_ICMP4, p, pkt, ICMP_NORMAL_LEN); break; case ICMP_DEST_UNREACH: if ((p->icmph->code == ICMP_FRAG_NEEDED) && (ntohs(p->icmph->s_icmp_nextmtu) < 576)) { if ( Event_Enabled(DECODE_ICMP_PATH_MTU_DOS) ) DecoderEvent(p, EVARGS(ICMP_PATH_MTU_DOS), 1, 1); } /* Fall through */ case ICMP_SOURCE_QUENCH: case ICMP_REDIRECT: case ICMP_TIME_EXCEEDED: case ICMP_PARAMETERPROB: /* account for extra 4 bytes in header */ p->dsize -= 4; p->data += 4; PushLayer(PROTO_ICMP4, p, pkt, ICMP_NORMAL_LEN); DecodeICMPEmbeddedIP(p->data, p->dsize, p); break; default: PushLayer(PROTO_ICMP4, p, pkt, ICMP_HEADER_LEN); break; } /* Run a bunch of ICMP decoder rules */ ICMP4MiscTests(p); p->proto_bits |= PROTO_BIT__ICMP; p->proto_bits &= ~(PROTO_BIT__UDP | PROTO_BIT__TCP); } /* * Function: DecodeICMPEmbeddedIP(uint8_t *, const uint32_t, Packet *) * * Purpose: Decode the ICMP embedded IP header + 64 bits payload * * Arguments: pkt => ptr to the packet data * len => length from here to the end of the packet * p => pointer to dummy packet decode struct * * Returns: void function */ void DecodeICMPEmbeddedIP(const uint8_t *pkt, const uint32_t len, Packet *p) { uint32_t ip_len; /* length from the start of the ip hdr to the * pkt end */ uint32_t hlen; /* ip header length */ uint16_t orig_frag_offset; /* do a little validation */ if(len < IP_HEADER_LEN) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "ICMP: IP short header (%d bytes)\n", len);); DecoderEvent(p, DECODE_ICMP_ORIG_IP_TRUNCATED, DECODE_ICMP_ORIG_IP_TRUNCATED_STR, 1, 1); p->orig_family = NO_IP; p->orig_iph = NULL; return; } /* lay the IP struct over the raw data */ sfiph_orig_build(p, pkt, AF_INET); p->orig_iph = (IPHdr *) pkt; DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "DecodeICMPEmbeddedIP: ip header" " starts at: %p, length is %lu\n", p->orig_iph, (unsigned long) len);); /* * with datalink DLT_RAW it's impossible to differ ARP datagrams from IP. * So we are just ignoring non IP datagrams */ if((GET_ORIG_IPH_VER(p) != 4) && !IS_IP6(p)) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "ICMP: not IPv4 datagram ([ver: 0x%x][len: 0x%x])\n", GET_ORIG_IPH_VER(p), GET_ORIG_IPH_LEN(p));); DecoderEvent(p, DECODE_ICMP_ORIG_IP_VER_MISMATCH, DECODE_ICMP_ORIG_IP_VER_MISMATCH_STR, 1, 1); p->orig_family = NO_IP; p->orig_iph = NULL; return; } /* set the IP datagram length */ ip_len = ntohs(GET_ORIG_IPH_LEN(p)); /* set the IP header length */ hlen = (p->orig_ip4h->ip_verhl & 0x0f) << 2; if(len < hlen) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "ICMP: IP len (%d bytes) < IP hdr len (%d bytes), packet discarded\n", ip_len, hlen);); DecoderEvent(p, DECODE_ICMP_ORIG_DGRAM_LT_ORIG_IP, DECODE_ICMP_ORIG_DGRAM_LT_ORIG_IP_STR, 1, 1); p->orig_family = NO_IP; p->orig_iph = NULL; return; } /* set the remaining packet length */ ip_len = len - hlen; orig_frag_offset = ntohs(GET_ORIG_IPH_OFF(p)); orig_frag_offset &= 0x1FFF; if (orig_frag_offset == 0) { /* Original IP payload should be 64 bits */ if (ip_len < 8) { DecoderEvent(p, DECODE_ICMP_ORIG_PAYLOAD_LT_64, DECODE_ICMP_ORIG_PAYLOAD_LT_64_STR, 1, 1); return; } /* ICMP error packets could contain as much of original payload * as possible, but not exceed 576 bytes */ else if (ntohs(GET_IPH_LEN(p)) > 576) { DecoderEvent(p, DECODE_ICMP_ORIG_PAYLOAD_GT_576, DECODE_ICMP_ORIG_PAYLOAD_GT_576_STR, 1, 1); } } else { /* RFC states that only first frag will get an ICMP response */ DecoderEvent(p, DECODE_ICMP_ORIG_IP_WITH_FRAGOFFSET, DECODE_ICMP_ORIG_IP_WITH_FRAGOFFSET_STR, 1, 1); return; } DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "ICMP Unreachable IP header length: " "%lu\n", (unsigned long)hlen);); switch(GET_ORIG_IPH_PROTO(p)) { case IPPROTO_TCP: /* decode the interesting part of the header */ p->orig_tcph = (TCPHdr *)(pkt + hlen); /* stuff more data into the printout data struct */ p->orig_sp = ntohs(p->orig_tcph->th_sport); p->orig_dp = ntohs(p->orig_tcph->th_dport); break; case IPPROTO_UDP: p->orig_udph = (UDPHdr *)(pkt + hlen); /* fill in the printout data structs */ p->orig_sp = ntohs(p->orig_udph->uh_sport); p->orig_dp = ntohs(p->orig_udph->uh_dport); break; case IPPROTO_ICMP: p->orig_icmph = (ICMPHdr *)(pkt + hlen); break; } return; } /* * Function: DecodeIPV6(uint8_t *, uint32_t) * * Purpose: Decoding IPv6 headers * * Arguments: pkt => ptr to the packet data * len => length from here to the end of the packet * * Returns: void function */ //-------------------------------------------------------------------- // decode.c::IP6 misc //-------------------------------------------------------------------- #define IP6_MULTICAST 0xFF // first/most significant octet #define IP6_MULTICAST_SCOPE_RESERVED 0x00 #define IP6_MULTICAST_SCOPE_INTERFACE 0x01 #define IP6_MULTICAST_SCOPE_LINK 0x02 #define IP6_MULTICAST_SCOPE_ADMIN 0x04 #define IP6_MULTICAST_SCOPE_SITE 0x05 #define IP6_MULTICAST_SCOPE_ORG 0x08 #define IP6_MULTICAST_SCOPE_GLOBAL 0x0E /* Check for multiple IPv6 Multicast-related alerts */ static void CheckIPV6Multicast(Packet *p) { IP6RawHdr* hdr6 = (IP6RawHdr*)p->iph; uint8_t multicast_scope; struct in6_addr* ip_dst; uint32_t h_ip_dst; if ( hdr6->ip6_src.s6_addr[0] == IP6_MULTICAST ) { DecoderEvent(p, DECODE_IPV6_SRC_MULTICAST, DECODE_IPV6_SRC_MULTICAST_STR, 1, 1); } ip_dst = &hdr6->ip6_dst; if ( ip_dst->s6_addr[0] != IP6_MULTICAST ) { return; } multicast_scope = ip_dst->s6_addr[1] & 0x0F; switch (multicast_scope) { case IP6_MULTICAST_SCOPE_RESERVED: case IP6_MULTICAST_SCOPE_INTERFACE: case IP6_MULTICAST_SCOPE_LINK: case IP6_MULTICAST_SCOPE_ADMIN: case IP6_MULTICAST_SCOPE_SITE: case IP6_MULTICAST_SCOPE_ORG: case IP6_MULTICAST_SCOPE_GLOBAL: break; default: DecoderEvent(p, DECODE_IPV6_BAD_MULTICAST_SCOPE, DECODE_IPV6_BAD_MULTICAST_SCOPE_STR, 1, 1); } /* Check against assigned multicast addresses. These are listed at: http://www.iana.org/assignments/ipv6-multicast-addresses/ */ /* Multicast addresses only specify the first 16 and last 40 bits. Others should be zero. */ if ((ip_dst->s6_addr16[1] != 0) || (ip_dst->s6_addr32[1] != 0) || (ip_dst->s6_addr16[4] != 0) || (ip_dst->s6_addr[10] != 0)) { DecoderEvent(p, DECODE_IPV6_DST_RESERVED_MULTICAST, DECODE_IPV6_DST_RESERVED_MULTICAST_STR, 1, 1); return; } if (ip_dst->s6_addr[1] == IP6_MULTICAST_SCOPE_INTERFACE) { // Node-local scope if ((ip_dst->s6_addr16[1] != 0) || (ip_dst->s6_addr32[1] != 0) || (ip_dst->s6_addr32[2] != 0) || (ip_dst->s6_addr16[6] != 0)) { DecoderEvent(p, DECODE_IPV6_DST_RESERVED_MULTICAST, DECODE_IPV6_DST_RESERVED_MULTICAST_STR, 1, 1); } else { switch (ntohl(ip_dst->s6_addr32[3])) { case 0x00000001: // All Nodes case 0x00000002: // All Routers case 0x000000FB: // mDNSv6 break; default: DecoderEvent(p, DECODE_IPV6_DST_RESERVED_MULTICAST, DECODE_IPV6_DST_RESERVED_MULTICAST_STR, 1, 1); } } } else if (ip_dst->s6_addr[1] == IP6_MULTICAST_SCOPE_LINK) { // Link-local scope switch (ntohl(ip_dst->s6_addr32[3])) { case 0x00000001: // All Nodes case 0x00000002: // All Routers case 0x00000004: // DVMRP Routers case 0x00000005: // OSPFIGP case 0x00000006: // OSPFIGP Designated Routers case 0x00000007: // ST Routers case 0x00000008: // ST Hosts case 0x00000009: // RIP Routers case 0x0000000A: // EIGRP Routers case 0x0000000B: // Mobile-Agents case 0x0000000C: // SSDP case 0x0000000D: // All PIMP Routers case 0x0000000E: // RSVP-ENCAPSULATION case 0x0000000F: // UPnP case 0x00000012: // VRRP case 0x00000016: // All MLDv2-capable routers case 0x0000006A: // All-Snoopers case 0x0000006B: // PTP-pdelay case 0x0000006C: // Saratoga case 0x0000006D: // LL-MANET-Routers case 0x0000006E: // IGRS case 0x0000006F: // iADT Discovery case 0x000000FB: // mDNSv6 case 0x00010001: // Link Name case 0x00010002: // All-dhcp-agents case 0x00010003: // Link-local Multicast Name Resolution case 0x00010004: // DTCP Announcement break; default: if ((ip_dst->s6_addr[11] == 1) && (ip_dst->s6_addr[12] == 0xFF)) { break; // Solicited-Node Address } if ((ip_dst->s6_addr[11] == 2) && (ip_dst->s6_addr[12] == 0xFF)) { break; // Node Information Queries } DecoderEvent(p, DECODE_IPV6_DST_RESERVED_MULTICAST, DECODE_IPV6_DST_RESERVED_MULTICAST_STR, 1, 1); } } else if (ip_dst->s6_addr[1] == IP6_MULTICAST_SCOPE_SITE) { // Site-local scope switch (ntohl(ip_dst->s6_addr32[3])) { case 0x00000002: // All Routers case 0x000000FB: // mDNSv6 case 0x00010003: // All-dhcp-servers case 0x00010004: // Deprecated case 0x00010005: // SL-MANET-ROUTERS break; default: DecoderEvent(p, DECODE_IPV6_DST_RESERVED_MULTICAST, DECODE_IPV6_DST_RESERVED_MULTICAST_STR, 1, 1); } } else if ((ip_dst->s6_addr[1] & 0xF0) == 0) { h_ip_dst = ntohl(ip_dst->s6_addr32[3]); // Variable scope switch (h_ip_dst) { case 0x0000000C: // SSDP case 0x000000FB: // mDNSv6 case 0x00000181: // PTP-primary case 0x00000182: // PTP-alternate1 case 0x00000183: // PTP-alternate2 case 0x00000184: // PTP-alternate3 case 0x0000018C: // All ACs multicast address case 0x00000201: // "rwho" Group (BSD) case 0x00000202: // SUN RPC PMAPPROC_CALLIT case 0x00000204: // All C1222 Nodes case 0x00000300: // Mbus/IPv6 case 0x00027FFE: // SAPv1 Announcements case 0x00027FFF: // SAPv0 Announcements break; default: if ((h_ip_dst >= 0x00000100) && (h_ip_dst <= 0x00000136)) { break; // Several addresses assigned in a contiguous block } if ((h_ip_dst >= 0x00000140) && (h_ip_dst <= 0x0000014F)) { break; // EPSON-disc-set } if ((h_ip_dst >= 0x00020000) && (h_ip_dst <= 0x00027FFD)) { break; // Multimedia Conference Calls } if ((h_ip_dst >= 0x00011000) && (h_ip_dst <= 0x000113FF)) { break; // Service Location, Version 2 } if ((h_ip_dst >= 0x00028000) && (h_ip_dst <= 0x0002FFFF)) { break; // SAP Dynamic Assignments } DecoderEvent(p, DECODE_IPV6_DST_RESERVED_MULTICAST, DECODE_IPV6_DST_RESERVED_MULTICAST_STR, 1, 1); } } else if ((ip_dst->s6_addr[1] & 0xF0) == 0x30) { h_ip_dst = ntohl(ip_dst->s6_addr32[3]); // Source-Specific Multicast block if ((h_ip_dst >= 0x40000001) && (h_ip_dst <= 0x7FFFFFFF)) { return; // IETF consensus } else if ((h_ip_dst >= 0x80000000) && (h_ip_dst <= 0xFFFFFFFF)) { return; // Dynamiclly allocated by hosts when needed } else { // Other addresses in this block are reserved. DecoderEvent(p, DECODE_IPV6_DST_RESERVED_MULTICAST, DECODE_IPV6_DST_RESERVED_MULTICAST_STR, 1, 1); } } else { /* Addresses not listed above are reserved. */ DecoderEvent(p, DECODE_IPV6_DST_RESERVED_MULTICAST, DECODE_IPV6_DST_RESERVED_MULTICAST_STR, 1, 1); } } /* Teredo packets need to have one of their IPs use either the Teredo prefix, or a link-local prefix (in the case of Router Solicitation messages) */ static inline int CheckTeredoPrefix(IP6RawHdr *hdr) { /* Check if src address matches 2001::/32 */ if ((hdr->ip6_src.s6_addr[0] == 0x20) && (hdr->ip6_src.s6_addr[1] == 0x01) && (hdr->ip6_src.s6_addr[2] == 0x00) && (hdr->ip6_src.s6_addr[3] == 0x00)) return 1; /* Check if src address matches fe80::/64 */ if ((hdr->ip6_src.s6_addr[0] == 0xfe) && (hdr->ip6_src.s6_addr[1] == 0x80) && (hdr->ip6_src.s6_addr[2] == 0x00) && (hdr->ip6_src.s6_addr[3] == 0x00) && (hdr->ip6_src.s6_addr[4] == 0x00) && (hdr->ip6_src.s6_addr[5] == 0x00) && (hdr->ip6_src.s6_addr[6] == 0x00) && (hdr->ip6_src.s6_addr[7] == 0x00)) return 1; /* Check if dst address matches 2001::/32 */ if ((hdr->ip6_dst.s6_addr[0] == 0x20) && (hdr->ip6_dst.s6_addr[1] == 0x01) && (hdr->ip6_dst.s6_addr[2] == 0x00) && (hdr->ip6_dst.s6_addr[3] == 0x00)) return 1; /* Check if dst address matches fe80::/64 */ if ((hdr->ip6_dst.s6_addr[0] == 0xfe) && (hdr->ip6_dst.s6_addr[1] == 0x80) && (hdr->ip6_dst.s6_addr[2] == 0x00) && (hdr->ip6_dst.s6_addr[3] == 0x00) && (hdr->ip6_dst.s6_addr[4] == 0x00) && (hdr->ip6_dst.s6_addr[5] == 0x00) && (hdr->ip6_dst.s6_addr[6] == 0x00) && (hdr->ip6_dst.s6_addr[7] == 0x00)) return 1; /* No Teredo prefix found. */ return 0; } /* Function: IPV6MiscTests(Packet *p) * * Purpose: A bunch of IPv6 decoder alerts * * Arguments: p => the Packet to check * * Returns: void function */ static inline void IPV6MiscTests(Packet *p) { IP6RawHdr* hdr6 = (IP6RawHdr*)p->iph; /* * Some IP Header tests * Land Attack(same src/dst ip) * Loopback (src or dst in 127/8 block) * Modified: 2/22/05-man for High Endian Architecture. * * some points in the code assume an IP of 0.0.0.0 matches anything, but * that is not so here. The sfip_compare makes that assumption for * compatibility, but sfip_contains does not. Hence, sfip_contains * is used here in the interrim. */ #ifdef DAQ_CAPA_VRF uint16_t sAsId; uint16_t dAsId; sAsId = DAQ_GetSourceAddressSpaceID(p->pkth); dAsId = DAQ_GetDestinationAddressSpaceID(p->pkth); if( sfip_fast_eq6((sfaddr_t*)&hdr6->ip6_src.s6_addr, (sfaddr_t*)&hdr6->ip6_dst.s6_addr) && (sAsId == dAsId)) { DecoderEvent(p, DECODE_BAD_TRAFFIC_SAME_SRCDST, DECODE_BAD_TRAFFIC_SAME_SRCDST_STR, 1, 1); if( pkt_trace_enabled ) { addPktTraceData(VERDICT_REASON_SNORT, snprintf(trace_line, MAX_TRACE_LINE, "Packet is blocked since same source and destination")); } } #else if( sfip_fast_eq6((sfaddr_t*)&hdr6->ip6_src.s6_addr, (sfaddr_t*)&hdr6->ip6_dst.s6_addr)) { DecoderEvent(p, DECODE_BAD_TRAFFIC_SAME_SRCDST, DECODE_BAD_TRAFFIC_SAME_SRCDST_STR, 1, 1); } #endif if(sfip_is_loopback((sfaddr_t*)&hdr6->ip6_src.s6_addr) || sfip_is_loopback((sfaddr_t*)&hdr6->ip6_dst.s6_addr)) { DecoderEvent(p, DECODE_BAD_TRAFFIC_LOOPBACK, DECODE_BAD_TRAFFIC_LOOPBACK_STR, 1,1); } /* Other decoder alerts for IPv6 addresses Added: 5/24/10 (Snort 2.9.0) */ if (!sfraw_is_set(&hdr6->ip6_dst)) { DecoderEvent(p, DECODE_IPV6_DST_ZERO, DECODE_IPV6_DST_ZERO_STR, 1, 1); } CheckIPV6Multicast(p); if ( Event_Enabled(DECODE_IPV6_ISATAP_SPOOF) ) { /* Only check for IPv6 over IPv4 */ if (p->outer_iph && p->outer_iph->ip_proto == IPPROTO_IPV6) { uint32_t isatap_interface_id = ntohl(hdr6->ip6_src.s6_addr32[2]) & 0xFCFFFFFF; /* ISATAP uses address with prefix fe80:0000:0000:0000:0200:5efe or fe80:0000:0000:0000:0000:5efe, followed by the IPv4 address. */ if (isatap_interface_id == 0x00005EFE) { if (p->outer_iph->ip_src.s_addr != hdr6->ip6_src.s6_addr32[3]) DecoderEvent(p, EVARGS(IPV6_ISATAP_SPOOF), 1, 1); } } } } //-------------------------------------------------------------------- // decode.c::IP6 extensions //-------------------------------------------------------------------- static inline int IPV6ExtensionOrder(uint8_t type) { switch (type) { case IPPROTO_HOPOPTS: return 1; case IPPROTO_DSTOPTS: return 2; case IPPROTO_ROUTING: return 3; case IPPROTO_FRAGMENT: return 4; case IPPROTO_AH: return 5; case IPPROTO_ESP: return 6; default: return 7; } } /* Check for out-of-order IPv6 Extension Headers */ static inline void CheckIPv6ExtensionOrder(Packet *p) { int routing_seen = 0; int current_type_order, next_type_order, i; if (Event_Enabled(DECODE_IPV6_UNORDERED_EXTENSIONS)) { if (p->ip6_extension_count > 0) current_type_order = IPV6ExtensionOrder(p->ip6_extensions[0].type); for (i = 1; i < (p->ip6_extension_count); i++) { next_type_order = IPV6ExtensionOrder(p->ip6_extensions[i].type); if (p->ip6_extensions[i].type == IPPROTO_ROUTING) routing_seen = 1; if (next_type_order <= current_type_order) { /* A second "Destination Options" header is allowed iff: 1) A routing header was already seen, and 2) The second destination header is the last one before the upper layer. */ if (!routing_seen || !(p->ip6_extensions[i].type == IPPROTO_DSTOPTS) || !(i+1 == p->ip6_extension_count)) { DecoderEvent(p, EVARGS(IPV6_UNORDERED_EXTENSIONS), 1, 1); } } current_type_order = next_type_order; } } } void DecodeIPV6Extensions(uint8_t next, const uint8_t *pkt, uint32_t len, Packet *p); static inline int CheckIPV6HopOptions(const uint8_t *pkt, uint32_t len, Packet *p) { IP6Extension *exthdr = (IP6Extension *)pkt; uint32_t total_octets = (exthdr->ip6e_len * 8) + 8; const uint8_t *hdr_end = pkt + total_octets; uint8_t type, oplen; if (len < total_octets) { DecoderEvent(p, EVARGS(IPV6_TRUNCATED_EXT), 1, 1); return -1; } /* Skip to the options */ pkt += 2; /* Iterate through the options, check for bad ones */ while (pkt < hdr_end) { type = *pkt; switch (type) { case IP6_OPT_PAD1: pkt++; break; case IP6_OPT_PADN: case IP6_OPT_JUMBO: case IP6_OPT_RTALERT: case IP6_OPT_TUNNEL_ENCAP: case IP6_OPT_QUICK_START: case IP6_OPT_CALIPSO: case IP6_OPT_HOME_ADDRESS: case IP6_OPT_ENDPOINT_IDENT: pkt++; if (pkt < hdr_end) { oplen = *pkt; if ((pkt + oplen + 1) > hdr_end) { DecoderEvent(p, EVARGS(IPV6_BAD_OPT_LEN), 1, 1); return -1; } pkt += oplen + 1; } break; default: DecoderEvent(p, EVARGS(IPV6_BAD_OPT_TYPE), 1, 1); return -1; } } return 0; } void DecodeIPV6Options(int type, const uint8_t *pkt, uint32_t len, Packet *p) { IP6Extension *exthdr; uint32_t hdrlen = 0; /* This should only be called by DecodeIPV6 or DecodeIPV6Extensions * so no validation performed. Otherwise, uncomment the following: */ /* if(IPH_IS_VALID(p)) return */ pc.ipv6opts++; /* Need at least two bytes, one for next header, one for len. */ /* But size is an integer multiple of 8 octets, so 8 is min. */ if(len < sizeof(IP6Extension)) { DecoderEvent(p, DECODE_IPV6_TRUNCATED_EXT, DECODE_IPV6_TRUNCATED_EXT_STR, 1, 1); return; } if ( p->ip6_extension_count >= ScMaxIP6Extensions() ) { DecoderEvent(p, DECODE_IP6_EXCESS_EXT_HDR, DECODE_IP6_EXCESS_EXT_HDR_STR, 1, 1); return; } exthdr = (IP6Extension *)pkt; p->ip6_extensions[p->ip6_extension_count].type = type; p->ip6_extensions[p->ip6_extension_count].data = pkt; // TBD add layers for other ip6 ext headers switch (type) { case IPPROTO_HOPOPTS: hdrlen = sizeof(IP6Extension) + (exthdr->ip6e_len << 3); if ( CheckIPV6HopOptions(pkt, len, p) == 0 ) PushLayer(PROTO_IP6_HOP_OPTS, p, pkt, hdrlen); break; case IPPROTO_DSTOPTS: if (exthdr->ip6e_nxt == IPPROTO_ROUTING) { DecoderEvent(p, DECODE_IPV6_DSTOPTS_WITH_ROUTING, DECODE_IPV6_DSTOPTS_WITH_ROUTING_STR, 1, 1); } hdrlen = sizeof(IP6Extension) + (exthdr->ip6e_len << 3); if ( CheckIPV6HopOptions(pkt, len, p) == 0 ) PushLayer(PROTO_IP6_DST_OPTS, p, pkt, hdrlen); break; case IPPROTO_ROUTING: /* Routing type 0 extension headers are evil creatures. */ { IP6Route *rte = (IP6Route *)exthdr; if (rte->ip6rte_type == 0) { DecoderEvent(p, DECODE_IPV6_ROUTE_ZERO, DECODE_IPV6_ROUTE_ZERO_STR, 1, 1); } } if (exthdr->ip6e_nxt == IPPROTO_HOPOPTS) { DecoderEvent(p, DECODE_IPV6_ROUTE_AND_HOPBYHOP, DECODE_IPV6_ROUTE_AND_HOPBYHOP_STR, 1, 1); } if (exthdr->ip6e_nxt == IPPROTO_ROUTING) { DecoderEvent(p, DECODE_IPV6_TWO_ROUTE_HEADERS, DECODE_IPV6_TWO_ROUTE_HEADERS_STR, 1, 1); } hdrlen = sizeof(IP6Extension) + (exthdr->ip6e_len << 3); break; case IPPROTO_FRAGMENT: if (len == sizeof(IP6Frag)) { DecoderEvent(p, DECODE_ZERO_LENGTH_FRAG, DECODE_ZERO_LENGTH_FRAG_STR, 1, 1); return; } else { IP6Frag *ip6frag_hdr = (IP6Frag *)pkt; /* If this is an IP Fragment, set some data... */ p->ip6_frag_index = p->ip6_extension_count; p->ip_frag_start = pkt + sizeof(IP6Frag); p->df = 0; p->rf = IP6F_RES(ip6frag_hdr); p->mf = IP6F_MF(ip6frag_hdr); p->frag_offset = IP6F_OFFSET(ip6frag_hdr); if ( p->frag_offset || p->mf ) { p->frag_flag = 1; pc.frag6++; } else { DecoderEvent(p, DECODE_IPV6_BAD_FRAG_PKT, DECODE_IPV6_BAD_FRAG_PKT_STR , 1, 1); } if ( !(p->frag_offset) && Event_Enabled(DECODE_IPV6_UNORDERED_EXTENSIONS) ) { // check header ordering of fragged (next) header if ( IPV6ExtensionOrder(ip6frag_hdr->ip6f_nxt) < IPV6ExtensionOrder(IPPROTO_FRAGMENT) ) DecoderEvent(p, EVARGS(IPV6_UNORDERED_EXTENSIONS), 1, 1); } } hdrlen = sizeof(IP6Frag); p->ip_frag_len = (uint16_t)(len - hdrlen); if ( p->frag_flag && ((p->frag_offset > 0) || (exthdr->ip6e_nxt != IPPROTO_UDP)) ) { //check header order up thru frag header p->ip6_extension_count++; CheckIPv6ExtensionOrder(p); /* For non-zero offset frags, we stop decoding after the Frag header. According to RFC 2460, the "Next Header" value may differ from that of the offset zero frag, but only the Next Header of the original frag is used. */ // check DecodeIP(); we handle frags the same way here return; } break; case IPPROTO_AH: /* Auth Headers work in both IPv4 & IPv6, and their lengths are given in 4-octet increments instead of 8-octet increments. */ hdrlen = sizeof(IP6Extension) + (exthdr->ip6e_len << 2); if (hdrlen <= len) PushLayer(PROTO_AH, p, pkt, hdrlen); break; default: hdrlen = sizeof(IP6Extension) + (exthdr->ip6e_len << 3); break; } p->ip6_extension_count++; if(hdrlen > len) { DecoderEvent(p, DECODE_IPV6_TRUNCATED_EXT, DECODE_IPV6_TRUNCATED_EXT_STR, 1, 1); return; } if ( hdrlen > 0 ) { DecodeIPV6Extensions(*pkt, pkt + hdrlen, len - hdrlen, p); } #ifdef DEBUG_MSGS else { DebugMessage(DEBUG_DECODE, "WARNING - no next ip6 header decoded\n"); } #endif } void DecodeIPV6Extensions(uint8_t next, const uint8_t *pkt, uint32_t len, Packet *p) { pc.ip6ext++; #ifdef GRE if (p->greh != NULL) pc.gre_ipv6ext++; #endif /* XXX might this introduce an issue if the "next" field is invalid? */ p->ip6h->next = next; if (ScIdsMode()) { /* See if there are any ip_proto only rules that match */ fpEvalIpProtoOnlyRules(snort_conf->ip_proto_only_lists, p); p->proto_bits |= PROTO_BIT__IP; } switch(next) { case IPPROTO_TCP: pc.tcp6++; CheckIPv6ExtensionOrder(p); DecodeTCP(pkt, len, p); return; case IPPROTO_UDP: pc.udp6++; CheckIPv6ExtensionOrder(p); DecodeUDP(pkt, len, p); return; case IPPROTO_ICMPV6: pc.icmp6++; CheckIPv6ExtensionOrder(p); DecodeICMP6(pkt , len, p); return; case IPPROTO_NONE: CheckIPv6ExtensionOrder(p); p->dsize = 0; return; case IPPROTO_HOPOPTS: case IPPROTO_DSTOPTS: case IPPROTO_ROUTING: case IPPROTO_FRAGMENT: case IPPROTO_AH: DecodeIPV6Options(next, pkt, len, p); // Anything special to do here? just return? return; #ifdef MPLS_RFC4023_SUPPORT case IPPROTO_MPLS: DecodeMPLS(pkt, len, p); return; #endif #ifdef GRE case IPPROTO_GRE: pc.gre++; CheckIPv6ExtensionOrder(p); DecodeGRE(pkt, len, p); return; case IPPROTO_IPIP: pc.ip6ip4++; if ( ScTunnelBypassEnabled(TUNNEL_4IN6) ) Active_SetTunnelBypass(); CheckIPv6ExtensionOrder(p); DecodeIP(pkt, len, p); return; case IPPROTO_IPV6: pc.ip6ip6++; if ( ScTunnelBypassEnabled(TUNNEL_6IN6) ) Active_SetTunnelBypass(); CheckIPv6ExtensionOrder(p); DecodeIPV6(pkt, len, p); return; case IPPROTO_ESP: CheckIPv6ExtensionOrder(p); if (ScESPDecoding()) DecodeESP(pkt, len, p); return; #endif default: CheckIPv6ExtensionOrder(p); // There may be valid headers after this unsupported one, // need to decode this header, set "next" and continue // looping. DecoderEvent(p, DECODE_IPV6_BAD_NEXT_HEADER, DECODE_IPV6_BAD_NEXT_HEADER_STR, 1, 1); pc.other++; p->data = pkt; p->dsize = (uint16_t)len; break; }; } //-------------------------------------------------------------------- // decode.c::IP6 decoder //-------------------------------------------------------------------- void DecodeIPV6(const uint8_t *pkt, uint32_t len, Packet *p) { IP6RawHdr *hdr; uint32_t payload_len; pc.ipv6++; #ifdef GRE if (p->greh != NULL) pc.gre_ipv6++; #endif hdr = (IP6RawHdr*)pkt; if(len < IP6_HDR_LEN) { if ((p->packet_flags & PKT_UNSURE_ENCAP) == 0) DecoderEvent(p, DECODE_IPV6_TRUNCATED, DECODE_IPV6_TRUNCATED_STR, 1, 1); goto decodeipv6_fail; } /* Verify version in IP6 Header agrees */ if(IPRAW_HDR_VER(hdr) != 6) { if ((p->packet_flags & PKT_UNSURE_ENCAP) == 0) DecoderEvent(p, DECODE_IPV6_IS_NOT, DECODE_IPV6_IS_NOT_STR, 1, 1); goto decodeipv6_fail; } if (p->family != NO_IP) { /* Snort currently supports only 2 IP layers. Any more will fail to be decoded. */ if (p->encapsulated) { DecoderAlertEncapsulated(p, DECODE_IP_MULTIPLE_ENCAPSULATION, DECODE_IP_MULTIPLE_ENCAPSULATION_STR, pkt, len); goto decodeipv6_fail; } else { p->encapsulated = 1; } } payload_len = ntohs(hdr->ip6plen) + IP6_HDR_LEN; if(payload_len != len) { if (payload_len > len) { if ((p->packet_flags & PKT_UNSURE_ENCAP) == 0) DecoderEvent(p, DECODE_IPV6_DGRAM_GT_CAPLEN, DECODE_IPV6_DGRAM_GT_CAPLEN_STR, ScDecoderOversizedAlerts(), ScDecoderOversizedDrops()); goto decodeipv6_fail; } } /* Teredo packets should always use the 2001:0000::/32 prefix, or in some cases the link-local prefix fe80::/64. Source: RFC 4380, section 2.6 & section 5.2.1 Checking the addresses will save us from numerous false positives when UDP clients use 3544 as their ephemeral port, or "Deep Teredo Inspection" is turned on. If we ever start decoding more than 2 layers of IP in a packet, this check against p->proto_bits will need to be refactored. */ if ((p->proto_bits & PROTO_BIT__TEREDO) && (CheckTeredoPrefix(hdr) == 0)) { goto decodeipv6_fail; } if (p->encapsulated) { p->outer_iph = p->iph; p->outer_ip_data = p->ip_data; p->outer_ip_dsize = p->ip_dsize; } /* lay the IP struct over the raw data */ // this is ugly but necessary to keep the rest of the code happy p->inner_iph = p->iph = (IPHdr *)pkt; /* Build Packet structure's version of the IP6 header */ sfiph_build(p, hdr, AF_INET6); #ifdef GRE /* Remove outer IP options */ if (p->encapsulated) { p->ip_options_data = NULL; p->ip_options_len = 0; } #endif p->ip_option_count = 0; /* set the real IP length for logging */ p->actual_ip_len = ntohs(p->ip6h->len); p->ip_data = pkt + IP6_HDR_LEN; p->ip_dsize = ntohs(p->ip6h->len); PushLayer(PROTO_IP6, p, pkt, sizeof(*hdr)); IPV6MiscTests(p); DecodeIPV6Extensions(GET_IPH_PROTO(p), pkt + IP6_HDR_LEN, ntohs(p->ip6h->len), p); return; decodeipv6_fail: /* If this was Teredo, back up and treat the packet as normal UDP. */ if (p->proto_bits & PROTO_BIT__TEREDO) { pc.ipv6--; pc.teredo--; p->proto_bits &= ~PROTO_BIT__TEREDO; #ifdef GRE if (p->greh != NULL) pc.gre_ipv6--; #endif if ( ScTunnelBypassEnabled(TUNNEL_TEREDO) ) Active_ClearTunnelBypass(); return; } pc.discards++; pc.ipv6disc++; } //-------------------------------------------------------------------- // decode.c::ICMP6 //-------------------------------------------------------------------- void DecodeICMP6(const uint8_t *pkt, const uint32_t len, Packet *p) { if(len < ICMP6_MIN_HEADER_LEN) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "WARNING: Truncated ICMP6 header (%d bytes).\n", len);); if ( Event_Enabled(DECODE_ICMP6_HDR_TRUNC) ) DecoderEvent(p, EVARGS(ICMP6_HDR_TRUNC), 1, 1); pc.discards++; return; } p->icmp6h = (ICMP6Hdr*)pkt; p->icmph = (ICMPHdr*)pkt; /* This is needed for icmp rules */ /* Do checksums */ if (ScIcmpChecksums()) { uint16_t csum; if(IS_IP4(p)) { csum = in_chksum_icmp((uint16_t *)(p->icmp6h), len); } /* IPv6 traffic */ else { IP6RawHdr* hdr6 = (IP6RawHdr*)p->iph; pseudoheader6 ph6; COPY4(ph6.sip, hdr6->ip6_src.s6_addr32); COPY4(ph6.dip, hdr6->ip6_dst.s6_addr32); ph6.zero = 0; ph6.protocol = GET_IPH_PROTO(p); ph6.len = htons((u_short)len); csum = in_chksum_icmp6(&ph6, (uint16_t *)(p->icmp6h), len); } if(csum) { p->error_flags |= PKT_ERR_CKSUM_ICMP; DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Bad ICMP Checksum\n");); if ( ScIdsMode() ) queueExecDrop(execIcmpChksmDrop, p); } else { DEBUG_WRAP(DebugMessage(DEBUG_DECODE,"ICMP Checksum: OK\n");); } } p->dsize = (u_short)(len - ICMP6_MIN_HEADER_LEN); p->data = pkt + ICMP6_MIN_HEADER_LEN; DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "ICMP type: %d code: %d\n", p->icmp6h->type, p->icmp6h->code);); switch(p->icmp6h->type) { case ICMP6_ECHO: case ICMP6_REPLY: if (p->dsize >= sizeof(struct idseq)) { IP6RawHdr* hdr6 = (IP6RawHdr*)p->iph; /* Set data pointer to that of the "echo message" */ /* add the size of the echo ext to the data * ptr and subtract it from the data size */ p->dsize -= sizeof(struct idseq); p->data += sizeof(struct idseq); if ( Event_Enabled(DECODE_ICMP6_DST_MULTICAST) ) if ( hdr6->ip6_dst.s6_addr[0] == IP6_MULTICAST ) DecoderEvent(p, EVARGS(ICMP6_DST_MULTICAST), 1, 1); PushLayer(PROTO_ICMP6, p, pkt, ICMP_NORMAL_LEN); } else { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "WARNING: Truncated ICMP Echo header (%d bytes).\n", len);); DecoderEvent(p, DECODE_ICMP_DGRAM_LT_ICMPHDR, DECODE_ICMP_DGRAM_LT_ICMPHDR_STR, 1, 1); p->icmph = NULL; p->icmp6h = NULL; pc.discards++; pc.icmpdisc++; return; } break; case ICMP6_BIG: if (p->dsize >= sizeof(ICMP6TooBig)) { ICMP6TooBig *too_big = (ICMP6TooBig *)pkt; /* Set data pointer past MTU */ p->data += 4; p->dsize -= 4; if (ntohl(too_big->mtu) < 1280) { DecoderEvent(p, DECODE_ICMPV6_TOO_BIG_BAD_MTU, DECODE_ICMPV6_TOO_BIG_BAD_MTU_STR, 1, 1); } PushLayer(PROTO_ICMP6, p, pkt, ICMP_NORMAL_LEN); DecodeICMPEmbeddedIP6(p->data, p->dsize, p); } else { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "WARNING: Truncated ICMP header (%d bytes).\n", len);); DecoderEvent(p, DECODE_ICMP_DGRAM_LT_ICMPHDR, DECODE_ICMP_DGRAM_LT_ICMPHDR_STR, 1, 1); p->icmph = NULL; p->icmp6h = NULL; pc.discards++; pc.icmpdisc++; return; } break; case ICMP6_TIME: case ICMP6_PARAMS: case ICMP6_UNREACH: if (p->dsize >= 4) { /* Set data pointer past the 'unused/mtu/pointer block */ p->data += 4; p->dsize -= 4; if (p->icmp6h->type == ICMP6_UNREACH) { if (p->icmp6h->code == 2) { DecoderEvent(p, DECODE_ICMPV6_UNREACHABLE_NON_RFC_2463_CODE, DECODE_ICMPV6_UNREACHABLE_NON_RFC_2463_CODE_STR, 1, 1); } else if (p->icmp6h->code > 6) { DecoderEvent(p, DECODE_ICMPV6_UNREACHABLE_NON_RFC_4443_CODE, DECODE_ICMPV6_UNREACHABLE_NON_RFC_4443_CODE_STR, 1, 1); } } PushLayer(PROTO_ICMP6, p, pkt, ICMP_NORMAL_LEN); DecodeICMPEmbeddedIP6(p->data, p->dsize, p); } else { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "WARNING: Truncated ICMP header (%d bytes).\n", len);); DecoderEvent(p, DECODE_ICMP_DGRAM_LT_ICMPHDR, DECODE_ICMP_DGRAM_LT_ICMPHDR_STR, 1, 1); p->icmph = NULL; p->icmp6h = NULL; pc.discards++; pc.icmpdisc++; return; } break; case ICMP6_ADVERTISEMENT: if (p->dsize >= (sizeof(ICMP6RouterAdvertisement) - ICMP6_MIN_HEADER_LEN)) { ICMP6RouterAdvertisement *ra = (ICMP6RouterAdvertisement *)pkt; if (p->icmp6h->code != 0) { DecoderEvent(p, DECODE_ICMPV6_ADVERT_BAD_CODE, DECODE_ICMPV6_ADVERT_BAD_CODE_STR, 1, 1); } if (ntohl(ra->reachable_time) > 3600000) { DecoderEvent(p, DECODE_ICMPV6_ADVERT_BAD_REACHABLE, DECODE_ICMPV6_ADVERT_BAD_REACHABLE_STR, 1, 1); } PushLayer(PROTO_ICMP6, p, pkt, ICMP_HEADER_LEN); } else { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "WARNING: Truncated ICMP header (%d bytes).\n", len);); DecoderEvent(p, DECODE_ICMP_DGRAM_LT_ICMPHDR, DECODE_ICMP_DGRAM_LT_ICMPHDR_STR, 1, 1); p->icmph = NULL; p->icmp6h = NULL; pc.discards++; pc.icmpdisc++; return; } break; case ICMP6_SOLICITATION: if (p->dsize >= (sizeof(ICMP6RouterSolicitation) - ICMP6_MIN_HEADER_LEN)) { ICMP6RouterSolicitation *rs = (ICMP6RouterSolicitation *)pkt; if (rs->code != 0) { DecoderEvent(p, DECODE_ICMPV6_SOLICITATION_BAD_CODE, DECODE_ICMPV6_SOLICITATION_BAD_CODE_STR, 1, 1); } if (ntohl(rs->reserved) != 0) { DecoderEvent(p, DECODE_ICMPV6_SOLICITATION_BAD_RESERVED, DECODE_ICMPV6_SOLICITATION_BAD_RESERVED_STR, 1, 1); } PushLayer(PROTO_ICMP6, p, pkt, ICMP_HEADER_LEN); } else { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "WARNING: Truncated ICMP header (%d bytes).\n", len);); DecoderEvent(p, DECODE_ICMP_DGRAM_LT_ICMPHDR, DECODE_ICMP_DGRAM_LT_ICMPHDR_STR, 1, 1); p->icmph = NULL; p->icmp6h = NULL; pc.discards++; pc.icmpdisc++; return; } break; case ICMP6_NODE_INFO_QUERY: case ICMP6_NODE_INFO_RESPONSE: if (p->dsize >= (sizeof(ICMP6NodeInfo) - ICMP6_MIN_HEADER_LEN)) { ICMP6NodeInfo *ni = (ICMP6NodeInfo *)pkt; if (ni->code > 2) { DecoderEvent(p, DECODE_ICMPV6_NODE_INFO_BAD_CODE, DECODE_ICMPV6_NODE_INFO_BAD_CODE_STR, 1, 1); } /* TODO: Add alert for INFO Response, code == 1 || code == 2) * and there is data. */ } else { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "WARNING: Truncated ICMP header (%d bytes).\n", len);); DecoderEvent(p, DECODE_ICMP_DGRAM_LT_ICMPHDR, DECODE_ICMP_DGRAM_LT_ICMPHDR_STR, 1, 1); p->icmph = NULL; p->icmp6h = NULL; pc.discards++; pc.icmpdisc++; return; } break; default: if ( Event_Enabled(DECODE_ICMP6_TYPE_OTHER) ) DecoderEvent(p, EVARGS(ICMP6_TYPE_OTHER), 1, 1); PushLayer(PROTO_ICMP6, p, pkt, ICMP_HEADER_LEN); break; } p->proto_bits |= PROTO_BIT__ICMP; p->proto_bits &= ~(PROTO_BIT__UDP | PROTO_BIT__TCP); } /* * Function: DecodeICMPEmbeddedIP6(uint8_t *, const uint32_t, Packet *) * * Purpose: Decode the ICMP embedded IP6 header + payload * * Arguments: pkt => ptr to the packet data * len => length from here to the end of the packet * p => pointer to dummy packet decode struct * * Returns: void function */ void DecodeICMPEmbeddedIP6(const uint8_t *pkt, const uint32_t len, Packet *p) { /* lay the IP struct over the raw data */ IP6RawHdr* hdr = (IP6RawHdr*)pkt; pc.embdip++; DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "DecodeICMPEmbeddedIP6: ip header" " starts at: %p, length is %lu\n", hdr, (unsigned long) len);); /* do a little validation */ if ( len < IP6_HDR_LEN ) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "ICMP6: IP short header (%d bytes)\n", len);); DecoderEvent(p, DECODE_ICMP_ORIG_IP_TRUNCATED, DECODE_ICMP_ORIG_IP_TRUNCATED_STR, 1, 1); pc.discards++; return; } /* * with datalink DLT_RAW it's impossible to differ ARP datagrams from IP. * So we are just ignoring non IP datagrams */ if(IPRAW_HDR_VER(hdr) != 6) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "ICMP: not IPv6 datagram ([ver: 0x%x][len: 0x%x])\n", IPRAW_HDR_VER(hdr), len);); DecoderEvent(p, DECODE_ICMP_ORIG_IP_VER_MISMATCH, DECODE_ICMP_ORIG_IP_VER_MISMATCH_STR, 1, 1); pc.discards++; return; } sfiph_orig_build(p, pkt, AF_INET6); // XXX NOT YET IMPLEMENTED - fragments inside ICMP payload DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "ICMP6 Unreachable IP6 header length: " "%lu\n", (unsigned long)IP6_HDR_LEN);); switch(GET_ORIG_IPH_PROTO(p)) { case IPPROTO_TCP: /* decode the interesting part of the header */ p->orig_tcph = (TCPHdr *)(pkt + IP6_HDR_LEN); /* stuff more data into the printout data struct */ p->orig_sp = ntohs(p->orig_tcph->th_sport); p->orig_dp = ntohs(p->orig_tcph->th_dport); break; case IPPROTO_UDP: p->orig_udph = (UDPHdr *)(pkt + IP6_HDR_LEN); /* fill in the printout data structs */ p->orig_sp = ntohs(p->orig_udph->uh_sport); p->orig_dp = ntohs(p->orig_udph->uh_dport); break; case IPPROTO_ICMP: p->orig_icmph = (ICMPHdr *)(pkt + IP6_HDR_LEN); break; } return; } //-------------------------------------------------------------------- // decode.c::Teredo //-------------------------------------------------------------------- /* Function: DecodeTeredo(uint8_t *, uint32_t, Packet *) * * Teredo is IPv6 layered over UDP, with optional "indicators" in between. * Decode these (if present) and go to DecodeIPv6. * */ void DecodeTeredo(const uint8_t *pkt, uint32_t len, Packet *p) { if (len < TEREDO_MIN_LEN) return; /* Decode indicators. If both are present, Auth always comes before Origin. */ if (ntohs(*(uint16_t *)pkt) == TEREDO_INDICATOR_AUTH) { uint8_t client_id_length, auth_data_length; if (len < TEREDO_INDICATOR_AUTH_MIN_LEN) return; client_id_length = *(pkt + 2); auth_data_length = *(pkt + 3); if (len < (uint32_t)(TEREDO_INDICATOR_AUTH_MIN_LEN + client_id_length + auth_data_length)) return; pkt += (TEREDO_INDICATOR_AUTH_MIN_LEN + client_id_length + auth_data_length); len -= (TEREDO_INDICATOR_AUTH_MIN_LEN + client_id_length + auth_data_length); } if (ntohs(*(uint16_t *)pkt) == TEREDO_INDICATOR_ORIGIN) { if (len < TEREDO_INDICATOR_ORIGIN_LEN) return; pkt += TEREDO_INDICATOR_ORIGIN_LEN; len -= TEREDO_INDICATOR_ORIGIN_LEN; } /* If this is an IPv6 datagram, the first 4 bits will be the number 6. */ if (( (*pkt & 0xF0) >> 4) == 6) { p->proto_bits |= PROTO_BIT__TEREDO; pc.teredo++; if ( ScTunnelBypassEnabled(TUNNEL_TEREDO) ) Active_SetTunnelBypass(); if (ScDeepTeredoInspection() && (p->sp != TEREDO_PORT) && (p->dp != TEREDO_PORT)) p->packet_flags |= PKT_UNSURE_ENCAP; DecodeIPV6(pkt, len, p); p->packet_flags &= ~PKT_UNSURE_ENCAP; } /* Otherwise, we treat this as normal UDP traffic. */ return; } //-------------------------------------------------------------------- // decode.c::ESP //-------------------------------------------------------------------- /* Function: DecodeAH * * Purpose: Decode Authentication Header * * NOTE: This is for IPv4 Auth Headers, we leave IPv6 to do its own * work. * */ void DecodeAH(const uint8_t *pkt, uint32_t len, Packet *p) { IP6Extension *ah = (IP6Extension *)pkt; unsigned extlen; if ( len < sizeof(*ah) ) { DecoderEvent(p, EVARGS(AUTH_HDR_TRUNC), 1, 1); pc.discards++; return; } extlen = sizeof(*ah) + (ah->ip6e_len << 2); if ( extlen > len ) { DecoderEvent(p, EVARGS(AUTH_HDR_BAD_LEN), 1, 1); pc.discards++; return; } PushLayer(PROTO_AH, p, pkt, extlen); DecodeIPv4Proto(ah->ip6e_nxt, pkt+extlen, len-extlen, p); } /* * Function: DecodeESP(const uint8_t *, uint32_t, Packet *) * * Purpose: Attempt to decode Encapsulated Security Payload. * The contents are probably encrypted, but ESP is sometimes used * with "null" encryption, solely for Authentication. * This is more of a heuristic -- there is no ESP field that specifies * the encryption type (or lack thereof). * * Arguments: pkt => ptr to the packet data * len => length from here to the end of the packet * p => ptr to the Packet struct being filled out * * Returns: void function */ void DecodeESP(const uint8_t *pkt, uint32_t len, Packet *p) { const uint8_t *esp_payload; uint8_t next_header; uint8_t pad_length; uint8_t save_layer = p->next_layer; /* The ESP header contains a crypto Initialization Vector (IV) and a sequence number. Skip these. */ if (len < (ESP_HEADER_LEN + ESP_AUTH_DATA_LEN + ESP_TRAILER_LEN)) { /* Truncated ESP traffic. Bail out here and inspect the rest as payload. */ DecoderEvent(p, EVARGS(ESP_HEADER_TRUNC), 1, 1); p->data = pkt; p->dsize = (uint16_t) len; return; } esp_payload = pkt + ESP_HEADER_LEN; /* The Authentication Data at the end of the packet is variable-length. RFC 2406 says that Encryption and Authentication algorithms MUST NOT both be NULL, so we assume NULL Encryption and some other Authentication. The mandatory algorithms for Authentication are HMAC-MD5-96 and HMAC-SHA-1-96, so we assume a 12-byte authentication data at the end. */ len -= (ESP_HEADER_LEN + ESP_AUTH_DATA_LEN + ESP_TRAILER_LEN); pad_length = *(esp_payload + len); next_header = *(esp_payload + len + 1); /* Adjust the packet length to account for the padding. If the padding length is too big, this is probably encrypted traffic. */ if (pad_length < len) { len -= (pad_length); } else { p->packet_flags |= PKT_TRUST; p->data = esp_payload; p->dsize = (u_short) len; return; } /* Attempt to decode the inner payload. There is a small chance that an encrypted next_header would become a different valid next_header. The PKT_UNSURE_ENCAP flag tells the next decoder stage to silently ignore invalid headers. */ p->packet_flags |= PKT_UNSURE_ENCAP; switch (next_header) { case IPPROTO_IPIP: DecodeIP(esp_payload, len, p); p->packet_flags &= ~PKT_UNSURE_ENCAP; break; case IPPROTO_IPV6: DecodeIPV6(esp_payload, len, p); p->packet_flags &= ~PKT_UNSURE_ENCAP; break; case IPPROTO_TCP: pc.tcp++; DecodeTCP(esp_payload, len, p); p->packet_flags &= ~PKT_UNSURE_ENCAP; break; case IPPROTO_UDP: pc.udp++; DecodeUDP(esp_payload, len, p); p->packet_flags &= ~PKT_UNSURE_ENCAP; break; case IPPROTO_ICMP: pc.icmp++; DecodeICMP(esp_payload, len, p); p->packet_flags &= ~PKT_UNSURE_ENCAP; break; #ifdef GRE case IPPROTO_GRE: pc.gre++; DecodeGRE(esp_payload, len, p); p->packet_flags &= ~PKT_UNSURE_ENCAP; break; #endif default: /* If we didn't get a valid next_header, this packet is probably encrypted. Start data here and treat it as an IP datagram. */ p->data = esp_payload; p->dsize = (u_short) len; p->packet_flags &= ~PKT_UNSURE_ENCAP; p->packet_flags |= PKT_TRUST; return; } /* If no protocol was added to the stack, than we assume its' * encrypted. */ if (save_layer == p->next_layer) p->packet_flags |= PKT_TRUST; } #ifdef GRE //-------------------------------------------------------------------- // decode.c::ERSPAN //-------------------------------------------------------------------- /* * Function: DecodeERSPANType2(uint8_t *, uint32_t, Packet *) * * Purpose: Decode Encapsulated Remote Switch Packet Analysis Type 2 * This will decode ERSPAN Type 2 Headers * * Arguments: pkt => ptr to the packet data * len => length from here to the end of the packet * p => pointer to decoded packet struct * * Returns: void function * */ void DecodeERSPANType2(const uint8_t *pkt, const uint32_t len, Packet *p) { uint32_t hlen = sizeof(ERSpanType2Hdr); uint32_t payload_len; ERSpanType2Hdr *erSpan2Hdr = (ERSpanType2Hdr *)pkt; if (len < sizeof(ERSpanType2Hdr)) { DecoderAlertEncapsulated(p, DECODE_ERSPAN2_DGRAM_LT_HDR, DECODE_ERSPAN2_DGRAM_LT_HDR_STR, pkt, len); return; } if (p->encapsulated) { /* discard packet - multiple encapsulation */ /* not sure if this is ever used but I am assuming it is not */ DecoderAlertEncapsulated(p, DECODE_IP_MULTIPLE_ENCAPSULATION, DECODE_IP_MULTIPLE_ENCAPSULATION_STR, pkt, len); return; } /* Check that this is in fact ERSpan Type 2. */ if (ERSPAN_VERSION(erSpan2Hdr) != 0x01) /* Type 2 == version 0x01 */ { DecoderAlertEncapsulated(p, DECODE_ERSPAN_HDR_VERSION_MISMATCH, DECODE_ERSPAN_HDR_VERSION_MISMATCH_STR, pkt, len); return; } PushLayer(PROTO_ERSPAN, p, pkt, hlen); payload_len = len - hlen; DecodeTransBridging(pkt + hlen, payload_len, p); } /* * Function: DecodeERSPANType3(uint8_t *, uint32_t, Packet *) * * Purpose: Decode Encapsulated Remote Switch Packet Analysis Type 3 * This will decode ERSPAN Type 3 Headers * * Arguments: pkt => ptr to the packet data * len => length from here to the end of the packet * p => pointer to decoded packet struct * * Returns: void function * */ void DecodeERSPANType3(const uint8_t *pkt, const uint32_t len, Packet *p) { uint32_t hlen = sizeof(ERSpanType3Hdr); uint32_t payload_len; ERSpanType3Hdr *erSpan3Hdr = (ERSpanType3Hdr *)pkt; if (len < sizeof(ERSpanType3Hdr)) { DecoderAlertEncapsulated(p, DECODE_ERSPAN3_DGRAM_LT_HDR, DECODE_ERSPAN3_DGRAM_LT_HDR_STR, pkt, len); return; } if (p->encapsulated) { /* discard packet - multiple encapsulation */ /* not sure if this is ever used but I am assuming it is not */ DecoderAlertEncapsulated(p, DECODE_IP_MULTIPLE_ENCAPSULATION, DECODE_IP_MULTIPLE_ENCAPSULATION_STR, pkt, len); return; } /* Check that this is in fact ERSpan Type 3. */ if (ERSPAN_VERSION(erSpan3Hdr) != 0x02) /* Type 3 == version 0x02 */ { DecoderAlertEncapsulated(p, DECODE_ERSPAN_HDR_VERSION_MISMATCH, DECODE_ERSPAN_HDR_VERSION_MISMATCH_STR, pkt, len); return; } PushLayer(PROTO_ERSPAN, p, pkt, hlen); payload_len = len - hlen; DecodeTransBridging(pkt + hlen, payload_len, p); } //-------------------------------------------------------------------- // decode.c::GRE //-------------------------------------------------------------------- /* * Function: DecodeGRE(uint8_t *, uint32_t, Packet *) * * Purpose: Decode Generic Routing Encapsulation Protocol * This will decode normal GRE and PPTP GRE. * * Arguments: pkt => ptr to the packet data * len => length from here to the end of the packet * p => pointer to decoded packet struct * * Returns: void function * * Notes: see RFCs 1701, 2784 and 2637 */ void DecodeGRE(const uint8_t *pkt, const uint32_t len, Packet *p) { uint32_t hlen; /* GRE header length */ uint32_t payload_len; if (len < GRE_HEADER_LEN) { DecoderAlertEncapsulated(p, DECODE_GRE_DGRAM_LT_GREHDR, DECODE_GRE_DGRAM_LT_GREHDR_STR, pkt, len); return; } if (p->encapsulated) { /* discard packet - multiple GRE encapsulation */ /* not sure if this is ever used but I am assuming it is not */ DecoderAlertEncapsulated(p, DECODE_IP_MULTIPLE_ENCAPSULATION, DECODE_IP_MULTIPLE_ENCAPSULATION_STR, pkt, len); return; } /* Note: Since GRE doesn't have a field to indicate header length and * can contain a few options, we need to walk through the header to * figure out the length */ p->greh = (GREHdr *)pkt; hlen = GRE_HEADER_LEN; switch (GRE_VERSION(p->greh)) { case 0x00: /* these must not be set */ if (GRE_RECUR(p->greh) || GRE_FLAGS(p->greh)) { DecoderAlertEncapsulated(p, DECODE_GRE_INVALID_HEADER, DECODE_GRE_INVALID_HEADER_STR, pkt, len); return; } if (GRE_CHKSUM(p->greh) || GRE_ROUTE(p->greh)) hlen += GRE_CHKSUM_LEN + GRE_OFFSET_LEN; if (GRE_KEY(p->greh)) hlen += GRE_KEY_LEN; if (GRE_SEQ(p->greh)) hlen += GRE_SEQ_LEN; /* if this flag is set, we need to walk through all of the * Source Route Entries */ if (GRE_ROUTE(p->greh)) { uint16_t sre_addrfamily; uint8_t sre_offset; uint8_t sre_length; const uint8_t *sre_ptr; sre_ptr = pkt + hlen; while (1) { hlen += GRE_SRE_HEADER_LEN; if (hlen > len) break; sre_addrfamily = ntohs(*((uint16_t *)sre_ptr)); sre_ptr += sizeof(sre_addrfamily); sre_offset = *((uint8_t *)sre_ptr); sre_ptr += sizeof(sre_offset); sre_length = *((uint8_t *)sre_ptr); sre_ptr += sizeof(sre_length); if ((sre_addrfamily == 0) && (sre_length == 0)) break; hlen += sre_length; sre_ptr += sre_length; } } break; /* PPTP */ case 0x01: /* these flags should never be present */ if (GRE_CHKSUM(p->greh) || GRE_ROUTE(p->greh) || GRE_SSR(p->greh) || GRE_RECUR(p->greh) || GRE_V1_FLAGS(p->greh)) { DecoderAlertEncapsulated(p, DECODE_GRE_V1_INVALID_HEADER, DECODE_GRE_V1_INVALID_HEADER_STR, pkt, len); return; } /* protocol must be 0x880B - PPP */ if (GRE_PROTO(p->greh) != GRE_TYPE_PPP) { DecoderAlertEncapsulated(p, DECODE_GRE_V1_INVALID_HEADER, DECODE_GRE_V1_INVALID_HEADER_STR, pkt, len); return; } /* this flag should always be present */ if (!(GRE_KEY(p->greh))) { DecoderAlertEncapsulated(p, DECODE_GRE_V1_INVALID_HEADER, DECODE_GRE_V1_INVALID_HEADER_STR, pkt, len); return; } hlen += GRE_KEY_LEN; if (GRE_SEQ(p->greh)) hlen += GRE_SEQ_LEN; if (GRE_V1_ACK(p->greh)) hlen += GRE_V1_ACK_LEN; break; default: DecoderAlertEncapsulated(p, DECODE_GRE_INVALID_VERSION, DECODE_GRE_INVALID_VERSION_STR, pkt, len); return; } if (hlen > len) { DecoderAlertEncapsulated(p, DECODE_GRE_DGRAM_LT_GREHDR, DECODE_GRE_DGRAM_LT_GREHDR_STR, pkt, len); return; } PushLayer(PROTO_GRE, p, pkt, hlen); payload_len = len - hlen; if ( ScTunnelBypassEnabled(TUNNEL_GRE) ) Active_SetTunnelBypass(); /* Send to next protocol decoder */ /* As described in RFC 2784 the possible protocols are listed in * RFC 1700 under "ETHER TYPES" * See also "Current List of Protocol Types" in RFC 1701 */ switch (GRE_PROTO(p->greh)) { case ETHERNET_TYPE_IP: DecodeIP(pkt + hlen, payload_len, p); return; case GRE_TYPE_TRANS_BRIDGING: DecodeTransBridging(pkt + hlen, payload_len, p); return; case ETHERNET_TYPE_ARP: case ETHERNET_TYPE_REVARP: /* clear outer IP headers */ p->iph = NULL; p->family = NO_IP; DecodeARP(pkt + hlen, payload_len, p); return; case ETHERNET_TYPE_IPV6: DecodeIPV6(pkt + hlen, payload_len, p); return; case GRE_TYPE_PPP: DecodePppPktEncapsulated(pkt + hlen, payload_len, p); return; case ETHERNET_TYPE_ERSPAN_TYPE2: DecodeERSPANType2(pkt + hlen, payload_len, p); return; case ETHERNET_TYPE_ERSPAN_TYPE3: DecodeERSPANType3(pkt + hlen, payload_len, p); return; #ifndef NO_NON_ETHER_DECODER case ETHERNET_TYPE_IPX: DecodeIPX(pkt + hlen, payload_len, p); return; #endif case ETHERNET_TYPE_LOOP: DecodeEthLoopback(pkt + hlen, payload_len, p); return; /* not sure if this occurs, but 802.1q is an Ether type */ case ETHERNET_TYPE_8021Q: DecodeVlan(pkt + hlen, payload_len, p); return; #ifdef MPLS_RFC4023_SUPPORT case ETHERNET_TYPE_MPLS_MULTICAST: if(!ScMplsMulticast()) { DecoderEvent(p, DECODE_BAD_MPLS, DECODE_MULTICAST_MPLS_STR, 1, 1); } /* Fall through */ case ETHERNET_TYPE_MPLS_UNICAST: DecodeMPLS(p->pkt + LEN_VLAN_LLC_OTHER, len - LEN_VLAN_LLC_OTHER, p); return; #endif default: // TBD add decoder drop event for unknown gre/eth type pc.other++; p->data = pkt + hlen; p->dsize = (uint16_t)payload_len; return; } } #endif // GRE //-------------------------------------------------------------------- // decode.c::GTP //-------------------------------------------------------------------- /* Function: DecodeGTP(uint8_t *, uint32_t, Packet *) * * GTP (GPRS Tunneling Protocol) is layered over UDP. * Decode these (if present) and go to DecodeIPv6/DecodeIP. * */ void DecodeGTP(const uint8_t *pkt, uint32_t len, Packet *p) { uint32_t header_len; uint8_t next_hdr_type; uint8_t version; uint8_t ip_ver; GTPHdr *hdr; DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Start GTP decoding.\n");); hdr = (GTPHdr *) pkt; if (p->GTPencapsulated) { DecoderAlertEncapsulated(p, DECODE_GTP_MULTIPLE_ENCAPSULATION, DECODE_GTP_MULTIPLE_ENCAPSULATION_STR, pkt, len); return; } else { p->GTPencapsulated = 1; } /*Check the length*/ if (len < GTP_MIN_LEN) return; /* We only care about PDU*/ if ( hdr->type != 255) return; /*Check whether this is GTP or GTP', Exit if GTP'*/ if (!(hdr->flag & 0x10)) return; /*The first 3 bits are version number*/ version = (hdr->flag & 0xE0) >> 5; switch (version) { case 0: /*GTP v0*/ DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "GTP v0 packets.\n");); header_len = GTP_V0_HEADER_LEN; /*Check header fields*/ if (len < header_len) { DecoderEvent(p, EVARGS(GTP_BAD_LEN), 1, 1); return; } p->proto_bits |= PROTO_BIT__GTP; /*Check the length field. */ if (len != ((unsigned int)ntohs(hdr->length) + header_len)) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Calculated length %d != %d in header.\n", len - header_len, ntohs(hdr->length));); DecoderEvent(p, EVARGS(GTP_BAD_LEN), 1, 1); return; } break; case 1: /*GTP v1*/ DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "GTP v1 packets.\n");); /*Check the length based on optional fields and extension header*/ if (hdr->flag & 0x07) { header_len = GTP_V1_HEADER_LEN; /*Check optional fields*/ if (len < header_len) { DecoderEvent(p, EVARGS(GTP_BAD_LEN), 1, 1); return; } next_hdr_type = *(pkt + header_len - 1); /*Check extension headers*/ while (next_hdr_type) { uint16_t ext_hdr_len; /*check length before reading data*/ if (len < header_len + 4) { DecoderEvent(p, EVARGS(GTP_BAD_LEN), 1, 1); return; } ext_hdr_len = *(pkt + header_len); if (!ext_hdr_len) { DecoderEvent(p, EVARGS(GTP_BAD_LEN), 1, 1); return; } /*Extension header length is a unit of 4 octets*/ header_len += ext_hdr_len * 4; /*check length before reading data*/ if (len < header_len) { DecoderEvent(p, EVARGS(GTP_BAD_LEN), 1, 1); return; } next_hdr_type = *(pkt + header_len - 1); } } else header_len = GTP_MIN_LEN; p->proto_bits |= PROTO_BIT__GTP; /*Check the length field. */ if (len != ((unsigned int)ntohs(hdr->length) + GTP_MIN_LEN)) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Calculated length %d != %d in header.\n", len - GTP_MIN_LEN, ntohs(hdr->length));); DecoderEvent(p, EVARGS(GTP_BAD_LEN), 1, 1); return; } break; default: DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Unknown protocol version.\n");); return; } PushLayer(PROTO_GTP, p, pkt, header_len); if ( ScTunnelBypassEnabled(TUNNEL_GTP) ) Active_SetTunnelBypass(); len -= header_len; if (len > 0) { ip_ver = *(pkt+header_len) & 0xF0; if (ip_ver == 0x40) DecodeIP(pkt+header_len, len, p); else if (ip_ver == 0x60) DecodeIPV6(pkt+header_len, len, p); p->packet_flags &= ~PKT_UNSURE_ENCAP; } } //-------------------------------------------------------------------- // decode.c::UDP //-------------------------------------------------------------------- /* UDP-layer decoder alerts */ static inline void UDPMiscTests(Packet *p) { if ( Event_Enabled(DECODE_UDP_LARGE_PACKET) ) { if (p->dsize > 4000) DecoderEvent(p, EVARGS(UDP_LARGE_PACKET), 1, 1); } if ( Event_Enabled(DECODE_UDP_PORT_ZERO) ) { if (p->udph->uh_sport == 0 || p->udph->uh_dport == 0) DecoderEvent(p, EVARGS(UDP_PORT_ZERO), 1, 1); } } /* * Function: DecodeUDP(uint8_t *, const uint32_t, Packet *) * * Purpose: Decode the UDP transport layer * * Arguments: pkt => ptr to the packet data * len => length from here to the end of the packet * p => pointer to decoded packet struct * * Returns: void function */ static inline void PopUdp (Packet* p) { p->udph = p->outer_udph; p->outer_udph = NULL; pc.discards++; pc.udisc++; // required for detect.c to short-circuit preprocessing if ( !p->dsize ) p->dsize = p->ip_dsize; } void DecodeUDP(const uint8_t * pkt, const uint32_t len, Packet * p) { uint16_t uhlen; u_char fragmented_udp_flag = 0; if (p->proto_bits & (PROTO_BIT__TEREDO | PROTO_BIT__GTP)) p->outer_udph = p->udph; if(len < sizeof(UDPHdr)) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Truncated UDP header (%d bytes)\n", len);); DecoderEvent(p, DECODE_UDP_DGRAM_LT_UDPHDR, DECODE_UDP_DGRAM_LT_UDPHDR_STR, 1, 1); PopUdp(p); return; } /* set the ptr to the start of the UDP header */ p->inner_udph = p->udph = (UDPHdr *) pkt; if (!p->frag_flag) { uhlen = ntohs(p->udph->uh_len); } else { if(IS_IP6(p)) { uint16_t ip_len = ntohs(GET_IPH_LEN(p)); /* subtract the distance from udp header to 1st ip6 extension */ /* This gives the length of the UDP "payload", when fragmented */ uhlen = ip_len - ((u_char *)p->udph - (u_char *)p->ip6_extensions[0].data); } else { uint16_t ip_len = ntohs(GET_IPH_LEN(p)); /* Don't forget, IP_HLEN is a word - multiply x 4 */ uhlen = ip_len - (GET_IPH_HLEN(p) * 4 ); } fragmented_udp_flag = 1; } /* verify that the header len is a valid value */ if(uhlen < UDP_HEADER_LEN) { DecoderEvent(p, DECODE_UDP_DGRAM_INVALID_LENGTH, DECODE_UDP_DGRAM_INVALID_LENGTH_STR, 1, 1); PopUdp(p); return; } /* make sure there are enough bytes as designated by length field */ if(uhlen > len) { DecoderEventDrop(p, DECODE_UDP_DGRAM_SHORT_PACKET, DECODE_UDP_DGRAM_SHORT_PACKET_STR, ScDecoderOversizedAlerts(), ScDecoderOversizedDrops()); PopUdp(p); return; } else if(uhlen < len) { DecoderEvent(p, DECODE_UDP_DGRAM_LONG_PACKET, DECODE_UDP_DGRAM_LONG_PACKET_STR, 1, 1); PopUdp(p); return; } if (ScUdpChecksums()) { /* look at the UDP checksum to make sure we've got a good packet */ uint16_t csum; if(IS_IP4(p)) { pseudoheader ph; ph.sip = p->iph->ip_src.s_addr; ph.dip = p->iph->ip_dst.s_addr; ph.zero = 0; ph.protocol = GET_IPH_PROTO(p); ph.len = p->udph->uh_len; /* Don't do checksum calculation if * 1) Fragmented, OR * 2) UDP header chksum value is 0. */ if( !fragmented_udp_flag && p->udph->uh_chk ) { csum = in_chksum_udp(&ph, (uint16_t *)(p->udph), uhlen); } else { csum = 0; } } else { IP6RawHdr* hdr6 = (IP6RawHdr*)p->iph; pseudoheader6 ph6; COPY4(ph6.sip, hdr6->ip6_src.s6_addr32); COPY4(ph6.dip, hdr6->ip6_dst.s6_addr32); ph6.zero = 0; ph6.protocol = GET_IPH_PROTO(p); ph6.len = htons((u_short)len); /* Alert on checksum value 0 for ipv6 packets */ if(!p->udph->uh_chk) { csum = 1; DecoderEvent(p, DECODE_UDP_IPV6_ZERO_CHECKSUM, DECODE_UDP_IPV6_ZERO_CHECKSUM_STR, 1, 1); } /* Don't do checksum calculation if * 1) Fragmented * (UDP checksum is not optional in IP6) */ else if( !fragmented_udp_flag ) { csum = in_chksum_udp6(&ph6, (uint16_t *)(p->udph), uhlen); } else { csum = 0; } } if(csum) { /* Don't drop the packet if this was ESP or Teredo. Just stop decoding. */ if (p->packet_flags & PKT_UNSURE_ENCAP) { PopUdp(p); return; } p->error_flags |= PKT_ERR_CKSUM_UDP; DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Bad UDP Checksum\n");); if ( ScIdsMode() ) queueExecDrop(execUdpChksmDrop, p); } else { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "UDP Checksum: OK\n");); } } /* fill in the printout data structs */ #ifdef HAVE_DAQ_REAL_ADDRESSES if (p->outer_iph || !(p->pkth->flags & DAQ_PKT_FLAG_REAL_ADDRESSES)) { #endif p->sp = ntohs(p->udph->uh_sport); p->dp = ntohs(p->udph->uh_dport); #ifdef HAVE_DAQ_REAL_ADDRESSES } else { p->sp = ntohs(p->pkth->n_real_sPort); p->dp = ntohs(p->pkth->n_real_dPort); } #endif DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "UDP header starts at: %p\n", p->udph);); PushLayer(PROTO_UDP, p, pkt, sizeof(*p->udph)); p->data = (uint8_t *) (pkt + UDP_HEADER_LEN); /* length was validated up above */ p->dsize = uhlen - UDP_HEADER_LEN; p->proto_bits |= PROTO_BIT__UDP; /* Drop packet if we ignore this port */ if (ScIgnoreUdpPort(p->sp) || ScIgnoreUdpPort(p->dp)) { /* Ignore all preprocessors for this packet */ p->packet_flags |= PKT_IGNORE; return; } UDPMiscTests(p); if (p->sp == TEREDO_PORT || p->dp == TEREDO_PORT || ScDeepTeredoInspection()) { if ( !p->frag_flag ) DecodeTeredo(pkt + sizeof(UDPHdr), len - sizeof(UDPHdr), p); } if (ScGTPDecoding() && (ScIsGTPPort(p->sp)||ScIsGTPPort(p->dp))) { if ( !p->frag_flag ) DecodeGTP(pkt + sizeof(UDPHdr), len - sizeof(UDPHdr), p); } } //-------------------------------------------------------------------- // decode.c::TCP //-------------------------------------------------------------------- /* TCP-layer decoder alerts */ static inline void TCPMiscTests(Packet *p) { if ( Event_Enabled(DECODE_TCP_SHAFT_SYNFLOOD) ) { if ( ((p->tcph->th_flags & TH_NORESERVED) == TH_SYN ) && (p->tcph->th_seq == htonl(674711609)) ) DecoderEvent(p, EVARGS(TCP_SHAFT_SYNFLOOD), 1, 1); } if ( Event_Enabled(DECODE_TCP_PORT_ZERO) ) { if (p->tcph->th_sport == 0 || p->tcph->th_dport == 0) DecoderEvent(p, EVARGS(TCP_PORT_ZERO), 1, 1); } } /* * Function: DecodeTCP(uint8_t *, const uint32_t, Packet *) * * Purpose: Decode the TCP transport layer * * Arguments: pkt => ptr to the packet data * len => length from here to the end of the packet * p => Pointer to packet decode struct * * Returns: void function */ void DecodeTCP(const uint8_t * pkt, const uint32_t len, Packet * p) { uint32_t hlen; /* TCP header length */ if(len < TCP_HEADER_LEN) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "TCP packet (len = %d) cannot contain " "20 byte header\n", len);); DecoderEvent(p, DECODE_TCP_DGRAM_LT_TCPHDR, DECODE_TCP_DGRAM_LT_TCPHDR_STR, 1, 1); p->tcph = NULL; pc.discards++; pc.tdisc++; return; } /* lay TCP on top of the data cause there is enough of it! */ p->tcph = (TCPHdr *) pkt; /* multiply the payload offset value by 4 */ hlen = TCP_OFFSET(p->tcph) << 2; DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "TCP th_off is %d, passed len is %lu\n", TCP_OFFSET(p->tcph), (unsigned long)len);); if(hlen < TCP_HEADER_LEN) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "TCP Data Offset (%d) < hlen (%d) \n", TCP_OFFSET(p->tcph), hlen);); DecoderEvent(p, DECODE_TCP_INVALID_OFFSET, DECODE_TCP_INVALID_OFFSET_STR, 1, 1); p->tcph = NULL; pc.discards++; pc.tdisc++; return; } if(hlen > len) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "TCP Data Offset(%d) < longer than payload(%d)!\n", TCP_OFFSET(p->tcph) << 2, len);); DecoderEventDrop(p, DECODE_TCP_LARGE_OFFSET, DECODE_TCP_LARGE_OFFSET_STR, ScDecoderOversizedAlerts(), ScDecoderOversizedDrops()); p->tcph = NULL; pc.discards++; pc.tdisc++; return; } /* Checksum code moved in front of the other decoder alerts. If it's a bad checksum (maybe due to encrypted ESP traffic), the other alerts could be false positives. */ #ifdef HAVE_DAQ_DECRYPTED_SSL if (!(p->pkth->flags & DAQ_PKT_FLAG_DECRYPTED_SSL) && ScTcpChecksums()) #else if (ScTcpChecksums()) #endif { uint16_t csum; if(IS_IP4(p)) { pseudoheader ph; ph.sip = p->iph->ip_src.s_addr; ph.dip = p->iph->ip_dst.s_addr; /* setup the pseudo header for checksum calculation */ ph.zero = 0; ph.protocol = GET_IPH_PROTO(p); ph.len = htons((u_short)len); /* if we're being "stateless" we probably don't care about the TCP * checksum, but it's not bad to keep around for shits and giggles */ /* calculate the checksum */ csum = in_chksum_tcp(&ph, (uint16_t *)(p->tcph), len); } /* IPv6 traffic */ else { IP6RawHdr* hdr6 = (IP6RawHdr*)p->iph; pseudoheader6 ph6; COPY4(ph6.sip, hdr6->ip6_src.s6_addr32); COPY4(ph6.dip, hdr6->ip6_dst.s6_addr32); ph6.zero = 0; ph6.protocol = GET_IPH_PROTO(p); ph6.len = htons((u_short)len); csum = in_chksum_tcp6(&ph6, (uint16_t *)(p->tcph), len); } if(csum) { /* Don't drop the packet if this is encapuslated in Teredo or ESP. Just get rid of the TCP header and stop decoding. */ if (p->packet_flags & PKT_UNSURE_ENCAP) { p->tcph = NULL; return; } p->error_flags |= PKT_ERR_CKSUM_TCP; DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Bad TCP checksum\n", "0x%x versus 0x%x\n", csum, ntohs(p->tcph->th_sum));); #ifdef REG_TEST if (getRegTestFlags() & REG_TEST_FLAG_STREAM_DECODE) printf("Bad TCP checksum\n"); #endif if ( ScIdsMode() ) queueExecDrop(execTcpChksmDrop, p); } else { DEBUG_WRAP(DebugMessage(DEBUG_DECODE,"TCP Checksum: OK\n");); } } if(Event_Enabled(DECODE_TCP_XMAS) || Event_Enabled(DECODE_TCP_NMAP_XMAS)) { if(TCP_ISFLAGSET(p->tcph, (TH_FIN|TH_PUSH|TH_URG))) { if(TCP_ISFLAGSET(p->tcph, (TH_SYN|TH_ACK|TH_RST))) { DecoderEvent(p, DECODE_TCP_XMAS, DECODE_TCP_XMAS_STR, 1, 1); } else { DecoderEvent(p, DECODE_TCP_NMAP_XMAS, DECODE_TCP_NMAP_XMAS_STR, 1, 1); } // Allowing this packet for further processing // (in case there is a valid data inside it). /*p->tcph = NULL; pc.discards++; pc.tdisc++; return;*/ } } if(TCP_ISFLAGSET(p->tcph, (TH_SYN))) { /* check if only SYN is set */ if( p->tcph->th_flags == TH_SYN ) { if( Event_Enabled(DECODE_DOS_NAPTHA) ) { if( ntohl(p->tcph->th_seq) == 6060842 ) { if( ntohs(GET_IPH_ID(p)) == 413 ) { DecoderEvent(p, DECODE_DOS_NAPTHA, DECODE_DOS_NAPTHA_STR, 1, 1); } } } if(InternalEventIsEnabled(snort_conf->rate_filter_config, INTERNAL_EVENT_SYN_RECEIVED)) { SFRF_InternalSynRecdEvent(p); } } if( Event_Enabled(DECODE_SYN_TO_MULTICAST) ) { if( IpAddrSetContains(SynToMulticastDstIp, GET_DST_ADDR(p)) ) { DecoderEvent(p, DECODE_SYN_TO_MULTICAST, DECODE_SYN_TO_MULTICAST_STR, 1, 1); } } if ( Event_Enabled(DECODE_TCP_SYN_RST) ) if ( (p->tcph->th_flags & TH_RST) ) DecoderEvent(p, EVARGS(TCP_SYN_RST), 1, 1); if ( Event_Enabled(DECODE_TCP_SYN_FIN) ) if ( (p->tcph->th_flags & TH_FIN) ) DecoderEvent(p, EVARGS(TCP_SYN_FIN), 1, 1); } else { // we already know there is no SYN if ( Event_Enabled(DECODE_TCP_NO_SYN_ACK_RST) ) if ( !(p->tcph->th_flags & (TH_ACK|TH_RST)) ) DecoderEvent(p, EVARGS(TCP_NO_SYN_ACK_RST), 1, 1); } if ( Event_Enabled(DECODE_TCP_MUST_ACK) ) if ( (p->tcph->th_flags & (TH_FIN|TH_PUSH|TH_URG)) && !(p->tcph->th_flags & TH_ACK) ) DecoderEvent(p, EVARGS(TCP_MUST_ACK), 1, 1); /* stuff more data into the printout data struct */ #ifdef HAVE_DAQ_REAL_ADDRESSES if (p->outer_iph || !(p->pkth->flags & DAQ_PKT_FLAG_REAL_ADDRESSES)) { #endif p->sp = ntohs(p->tcph->th_sport); p->dp = ntohs(p->tcph->th_dport); #ifdef HAVE_DAQ_REAL_ADDRESSES } else { p->sp = ntohs(p->pkth->n_real_sPort); p->dp = ntohs(p->pkth->n_real_dPort); } #endif DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "tcp header starts at: %p\n", p->tcph);); PushLayer(PROTO_TCP, p, pkt, hlen); /* if options are present, decode them */ p->tcp_options_len = (uint16_t)(hlen - TCP_HEADER_LEN); if(p->tcp_options_len > 0) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "%lu bytes of tcp options....\n", (unsigned long)(p->tcp_options_len));); p->tcp_options_data = pkt + TCP_HEADER_LEN; DecodeTCPOptions((uint8_t *) (pkt + TCP_HEADER_LEN), p->tcp_options_len, p); } else { p->tcp_option_count = 0; } /* set the data pointer and size */ p->data = (uint8_t *) (pkt + hlen); if(hlen < len) { p->dsize = (u_short)(len - hlen); } else { p->dsize = 0; } if ( Event_Enabled(DECODE_TCP_BAD_URP) ) if ( (p->tcph->th_flags & TH_URG) && (!p->dsize || ntohs(p->tcph->th_urp) > p->dsize) ) DecoderEvent(p, EVARGS(TCP_BAD_URP), 1, 1); p->proto_bits |= PROTO_BIT__TCP; /* Drop packet if we ignore this port */ if (ScIgnoreTcpPort(p->sp) || ScIgnoreTcpPort(p->dp)) { /* Ignore all preprocessors for this packet */ p->packet_flags |= PKT_IGNORE; return; } TCPMiscTests(p); } //-------------------------------------------------------------------- // decode.c::Option Handling //-------------------------------------------------------------------- /** * Validate that the length is an expected length AND that it's in bounds * * EOL and NOP are handled separately * * @param option_ptr current location * @param end the byte past the end of the decode list * @param len_ptr the pointer to the length field * @param expected_len the number of bytes we expect to see per rfc KIND+LEN+DATA, -1 means dynamic. * @param tcpopt options structure to populate * @param byte_skip distance to move upon completion * * @return returns 0 on success, < 0 on error */ static inline int OptLenValidate(const uint8_t *option_ptr, const uint8_t *end, const uint8_t *len_ptr, int expected_len, Options *tcpopt, uint8_t *byte_skip) { *byte_skip = 0; if(len_ptr == NULL) { return TCP_OPT_TRUNC; } if(*len_ptr == 0 || expected_len == 0 || expected_len == 1) { return TCP_OPT_BADLEN; } else if(expected_len > 1) { if((option_ptr + expected_len) > end) { /* not enough data to read in a perfect world */ return TCP_OPT_TRUNC; } if(*len_ptr != expected_len) { /* length is not valid */ return TCP_OPT_BADLEN; } } else /* expected_len < 0 (i.e. variable length) */ { if(*len_ptr < 2) { /* RFC sez that we MUST have atleast this much data */ return TCP_OPT_BADLEN; } if((option_ptr + *len_ptr) > end) { /* not enough data to read in a perfect world */ return TCP_OPT_TRUNC; } } tcpopt->len = *len_ptr - 2; if(*len_ptr == 2) { tcpopt->data = NULL; } else { tcpopt->data = option_ptr + 2; } *byte_skip = *len_ptr; return 0; } /* * Function: DecodeTCPOptions(uint8_t *, uint32_t, Packet *) * * Purpose: Fairly self explainatory name, don't you think? * * TCP Option Header length validation is left to the caller * * For a good listing of TCP Options, * http://www.iana.org/assignments/tcp-parameters * * ------------------------------------------------------------ * From: "Kastenholz, Frank" * Subject: Re: skeeter & bubba TCP options? * * ah, the sins of ones youth that never seem to be lost... * * it was something that ben levy and stev and i did at ftp many * many moons ago. bridgham and stev were the instigators of it. * the idea was simple, put a dh key exchange directly in tcp * so that all tcp sessions could be encrypted without requiring * any significant key management system. authentication was not * a part of the idea, it was to be provided by passwords or * whatever, which could now be transmitted over the internet * with impunity since they were encrypted... we implemented * a simple form of this (doing the math was non trivial on the * machines of the day). it worked. the only failure that i * remember was that it was vulnerable to man-in-the-middle * attacks. * * why "skeeter" and "bubba"? well, that's known only to stev... * ------------------------------------------------------------ * * 4.2.2.5 TCP Options: RFC-793 Section 3.1 * * A TCP MUST be able to receive a TCP option in any segment. A TCP * MUST ignore without error any TCP option it does not implement, * assuming that the option has a length field (all TCP options * defined in the future will have length fields). TCP MUST be * prepared to handle an illegal option length (e.g., zero) without * crashing; a suggested procedure is to reset the connection and log * the reason. * * Arguments: o_list => ptr to the option list * o_len => length of the option list * p => pointer to decoded packet struct * * Returns: void function */ void DecodeTCPOptions(const uint8_t *start, uint32_t o_len, Packet *p) { const uint8_t *option_ptr = start; const uint8_t *end_ptr = start + o_len; /* points to byte after last option */ const uint8_t *len_ptr; uint8_t opt_count = 0; u_char done = 0; /* have we reached TCPOPT_EOL yet?*/ u_char experimental_option_found = 0; /* are all options RFC compliant? */ u_char obsolete_option_found = 0; u_char ttcp_found = 0; int code = 2; uint8_t byte_skip; /* Here's what we're doing so that when we find out what these * other buggers of TCP option codes are, we can do something * useful * * 1) get option code * 2) check for enough space for current option code * 3) set option data ptr * 4) increment option code ptr * * TCP_OPTLENMAX = 40 because of * (((2^4) - 1) * 4 - TCP_HEADER_LEN) * */ if(o_len > TCP_OPTLENMAX) { /* This shouldn't ever alert if we are doing our job properly * in the caller */ p->tcph = NULL; /* let's just alert */ DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "o_len(%u) > TCP_OPTLENMAX(%u)\n", o_len, TCP_OPTLENMAX)); return; } while((option_ptr < end_ptr) && (opt_count < TCP_OPTLENMAX) && (code >= 0) && !done) { p->tcp_options[opt_count].code = *option_ptr; if((option_ptr + 1) < end_ptr) { len_ptr = option_ptr + 1; } else { len_ptr = NULL; } switch(*option_ptr) { case TCPOPT_EOL: done = 1; /* fall through to the NOP case */ case TCPOPT_NOP: p->tcp_options[opt_count].len = 0; p->tcp_options[opt_count].data = NULL; byte_skip = 1; code = 0; break; case TCPOPT_MAXSEG: code = OptLenValidate(option_ptr, end_ptr, len_ptr, TCPOLEN_MAXSEG, &p->tcp_options[opt_count], &byte_skip); break; case TCPOPT_SACKOK: code = OptLenValidate(option_ptr, end_ptr, len_ptr, TCPOLEN_SACKOK, &p->tcp_options[opt_count], &byte_skip); break; case TCPOPT_WSCALE: code = OptLenValidate(option_ptr, end_ptr, len_ptr, TCPOLEN_WSCALE, &p->tcp_options[opt_count], &byte_skip); if (code == 0) { if ( ((uint16_t) p->tcp_options[opt_count].data[0] > 14)) { /* LOG INVALID WINDOWSCALE alert */ if (ScDecoderTcpOptAlerts()) { DecoderOptEvent(p, DECODE_TCPOPT_WSCALE_INVALID, DECODE_TCPOPT_WSCALE_INVALID_STR, 1, 1, execTcpOptDrop); } } } break; case TCPOPT_ECHO: /* both use the same lengths */ case TCPOPT_ECHOREPLY: obsolete_option_found = 1; code = OptLenValidate(option_ptr, end_ptr, len_ptr, TCPOLEN_ECHO, &p->tcp_options[opt_count], &byte_skip); break; case TCPOPT_MD5SIG: /* RFC 5925 obsoletes this option (see below) */ obsolete_option_found = 1; code = OptLenValidate(option_ptr, end_ptr, len_ptr, TCPOLEN_MD5SIG, &p->tcp_options[opt_count], &byte_skip); break; case TCPOPT_AUTH: /* Has to have at least 4 bytes - see RFC 5925, Section 2.2 */ if ((len_ptr != NULL) && (*len_ptr < 4)) code = TCP_OPT_BADLEN; else code = OptLenValidate(option_ptr, end_ptr, len_ptr, -1, &p->tcp_options[opt_count], &byte_skip); break; case TCPOPT_SACK: code = OptLenValidate(option_ptr, end_ptr, len_ptr, -1, &p->tcp_options[opt_count], &byte_skip); if((code == 0) && (p->tcp_options[opt_count].data == NULL)) code = TCP_OPT_BADLEN; break; case TCPOPT_CC_ECHO: ttcp_found = 1; /* fall through */ case TCPOPT_CC: /* all 3 use the same lengths / T/TCP */ case TCPOPT_CC_NEW: code = OptLenValidate(option_ptr, end_ptr, len_ptr, TCPOLEN_CC, &p->tcp_options[opt_count], &byte_skip); break; case TCPOPT_TRAILER_CSUM: experimental_option_found = 1; code = OptLenValidate(option_ptr, end_ptr, len_ptr, TCPOLEN_TRAILER_CSUM, &p->tcp_options[opt_count], &byte_skip); break; case TCPOPT_TIMESTAMP: code = OptLenValidate(option_ptr, end_ptr, len_ptr, TCPOLEN_TIMESTAMP, &p->tcp_options[opt_count], &byte_skip); break; case TCPOPT_SKEETER: case TCPOPT_BUBBA: case TCPOPT_UNASSIGNED: obsolete_option_found = 1; code = OptLenValidate(option_ptr, end_ptr, len_ptr, -1, &p->tcp_options[opt_count], &byte_skip); break; default: case TCPOPT_SCPS: case TCPOPT_SELNEGACK: case TCPOPT_RECORDBOUND: case TCPOPT_CORRUPTION: case TCPOPT_PARTIAL_PERM: case TCPOPT_PARTIAL_SVC: case TCPOPT_ALTCSUM: case TCPOPT_SNAP: experimental_option_found = 1; code = OptLenValidate(option_ptr, end_ptr, len_ptr, -1, &p->tcp_options[opt_count], &byte_skip); break; } if(code < 0) { if(code == TCP_OPT_BADLEN) { DecoderOptEvent(p, DECODE_TCPOPT_BADLEN, DECODE_TCPOPT_BADLEN_STR, 1, 1, execTcpOptDrop); } else if(code == TCP_OPT_TRUNC) { DecoderOptEvent(p, DECODE_TCPOPT_TRUNCATED, DECODE_TCPOPT_TRUNCATED_STR, 1, 1, execTcpOptDrop); } /* set the option count to the number of valid * options found before this bad one * some implementations (BSD and Linux) ignore * the bad ones, but accept the good ones */ p->tcp_option_count = opt_count; return; } opt_count++; option_ptr += byte_skip; } p->tcp_option_count = opt_count; if (experimental_option_found) { DecoderOptEvent(p, DECODE_TCPOPT_EXPERIMENT, DECODE_TCPOPT_EXPERIMENT_STR, 1, 1, execTcpOptExpDrop); } else if (obsolete_option_found) { DecoderOptEvent(p, DECODE_TCPOPT_OBSOLETE, DECODE_TCPOPT_OBSOLETE_STR, 1, 1, execTcpOptObsDrop); } else if (ttcp_found) { DecoderOptEvent(p, DECODE_TCPOPT_TTCP, DECODE_TCPOPT_TTCP_STR, 1, 1, execTcpOptTTcpDrop); } return; } /* * Function: DecodeIPOptions(uint8_t *, uint32_t, Packet *) * * Purpose: Once again, a fairly self-explainatory name * * Arguments: o_list => ptr to the option list * o_len => length of the option list * p => pointer to decoded packet struct * * Returns: void function */ void DecodeIPOptions(const uint8_t *start, uint32_t o_len, Packet *p) { const uint8_t *option_ptr = start; u_char done = 0; /* have we reached IP_OPTEOL yet? */ const uint8_t *end_ptr = start + o_len; uint8_t opt_count = 0; /* what option are we processing right now */ uint8_t byte_skip; const uint8_t *len_ptr; int code = 0; /* negative error codes are returned from bad options */ DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Decoding %d bytes of IP options\n", o_len);); while((option_ptr < end_ptr) && (opt_count < IP_OPTMAX) && (code >= 0)) { p->ip_options[opt_count].code = *option_ptr; if((option_ptr + 1) < end_ptr) { len_ptr = option_ptr + 1; } else { len_ptr = NULL; } switch(*option_ptr) { case IPOPT_NOP: case IPOPT_EOL: /* if we hit an EOL, we're done */ if(*option_ptr == IPOPT_EOL) done = 1; p->ip_options[opt_count].len = 0; p->ip_options[opt_count].data = NULL; byte_skip = 1; break; default: /* handle all the dynamic features */ code = OptLenValidate(option_ptr, end_ptr, len_ptr, -1, &p->ip_options[opt_count], &byte_skip); } if(code < 0) { /* Yes, we use TCP_OPT_* for the IP option decoder. */ if(code == TCP_OPT_BADLEN) { DecoderOptEvent(p, DECODE_IPV4OPT_BADLEN, DECODE_IPV4OPT_BADLEN_STR, 1, 1, execIpOptDrop); } else if(code == TCP_OPT_TRUNC) { DecoderOptEvent(p, DECODE_IPV4OPT_TRUNCATED, DECODE_IPV4OPT_TRUNCATED_STR, 1, 1, execIpOptDrop); } return; } if(!done) opt_count++; option_ptr += byte_skip; } p->ip_option_count = opt_count; return; } //-------------------------------------------------------------------- // decode.c::NON-ETHER STUFF //-------------------------------------------------------------------- #ifndef NO_NON_ETHER_DECODER #ifdef DLT_IEEE802_11 /* * Function: DecodeIEEE80211Pkt(Packet *, char *, DAQ_PktHdr_t*, * uint8_t*) * * Purpose: Decode those fun loving wireless LAN packets, one at a time! * * Arguments: p => pointer to the decoded packet struct * user => Utility pointer (unused) * pkthdr => ptr to the packet header * pkt => pointer to the real live packet data * * Returns: void function */ void DecodeIEEE80211Pkt(Packet * p, const DAQ_PktHdr_t * pkthdr, const uint8_t * pkt) { uint32_t cap_len = pkthdr->caplen; PROFILE_VARS; PREPROC_PROFILE_START(decodePerfStats); pc.total_processed++; memset(p, 0, PKT_ZERO_LEN); p->pkth = pkthdr; p->pkt = pkt; DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n");); DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "caplen: %lu pktlen: %lu\n", (unsigned long)cap_len, (unsigned long)pkthdr->pktlen);); /* do a little validation */ if(cap_len < MINIMAL_IEEE80211_HEADER_LEN) { if (ScLogVerbose()) { ErrorMessage("Captured data length < IEEE 802.11 header length! " "(%d bytes)\n", cap_len); } PREPROC_PROFILE_END(decodePerfStats); return; } /* lay the wireless structure over the packet data */ p->wifih = (WifiHdr *) pkt; DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "%X %X\n", *p->wifih->addr1, *p->wifih->addr2);); /* determine frame type */ switch(p->wifih->frame_control & 0x00ff) { /* management frames */ case WLAN_TYPE_MGMT_ASREQ: case WLAN_TYPE_MGMT_ASRES: case WLAN_TYPE_MGMT_REREQ: case WLAN_TYPE_MGMT_RERES: case WLAN_TYPE_MGMT_PRREQ: case WLAN_TYPE_MGMT_PRRES: case WLAN_TYPE_MGMT_BEACON: case WLAN_TYPE_MGMT_ATIM: case WLAN_TYPE_MGMT_DIS: case WLAN_TYPE_MGMT_AUTH: case WLAN_TYPE_MGMT_DEAUTH: pc.wifi_mgmt++; break; /* Control frames */ case WLAN_TYPE_CONT_PS: case WLAN_TYPE_CONT_RTS: case WLAN_TYPE_CONT_CTS: case WLAN_TYPE_CONT_ACK: case WLAN_TYPE_CONT_CFE: case WLAN_TYPE_CONT_CFACK: pc.wifi_control++; break; /* Data packets without data */ case WLAN_TYPE_DATA_NULL: case WLAN_TYPE_DATA_CFACK: case WLAN_TYPE_DATA_CFPL: case WLAN_TYPE_DATA_ACKPL: pc.wifi_data++; break; case WLAN_TYPE_DATA_DTCFACK: case WLAN_TYPE_DATA_DTCFPL: case WLAN_TYPE_DATA_DTACKPL: case WLAN_TYPE_DATA_DATA: pc.wifi_data++; if(cap_len < IEEE802_11_DATA_HDR_LEN + sizeof(EthLlc)) { DecoderEvent(p, DECODE_BAD_80211_ETHLLC, DECODE_BAD_80211_ETHLLC_STR, 1, 1); PREPROC_PROFILE_END(decodePerfStats); return; } p->ehllc = (EthLlc *) (pkt + IEEE802_11_DATA_HDR_LEN); #ifdef DEBUG_MSGS PrintNetData(stdout,(uint8_t *) p->ehllc, sizeof(EthLlc), NULL); //ClearDumpBuf(); printf("LLC Header:\n"); printf(" DSAP: 0x%X\n", p->ehllc->dsap); printf(" SSAP: 0x%X\n", p->ehllc->ssap); #endif if(p->ehllc->dsap == ETH_DSAP_IP && p->ehllc->ssap == ETH_SSAP_IP) { if(cap_len < IEEE802_11_DATA_HDR_LEN + sizeof(EthLlc) + sizeof(EthLlcOther)) { DecoderEvent(p, DECODE_BAD_80211_OTHER, DECODE_BAD_80211_OTHER_STR, 1, 1); PREPROC_PROFILE_END(decodePerfStats); return; } p->ehllcother = (EthLlcOther *) (pkt + IEEE802_11_DATA_HDR_LEN + sizeof(EthLlc)); #ifdef DEBUG_MSGS PrintNetData(stdout,(uint8_t *) p->ehllcother, sizeof(EthLlcOther), NULL ); //ClearDumpBuf(); printf("LLC Other Header:\n"); printf(" CTRL: 0x%X\n", p->ehllcother->ctrl); printf(" ORG: 0x%02X%02X%02X\n", p->ehllcother->org_code[0], p->ehllcother->org_code[1], p->ehllcother->org_code[2]); printf(" PROTO: 0x%04X\n", ntohs(p->ehllcother->proto_id)); #endif switch(ntohs(p->ehllcother->proto_id)) { case ETHERNET_TYPE_IP: DecodeIP(p->pkt + IEEE802_11_DATA_HDR_LEN + sizeof(EthLlc) + sizeof(EthLlcOther), cap_len - IEEE802_11_DATA_HDR_LEN - sizeof(EthLlc) - sizeof(EthLlcOther), p); PREPROC_PROFILE_END(decodePerfStats); return; case ETHERNET_TYPE_ARP: case ETHERNET_TYPE_REVARP: DecodeARP(p->pkt + IEEE802_11_DATA_HDR_LEN + sizeof(EthLlc) + sizeof(EthLlcOther), cap_len - IEEE802_11_DATA_HDR_LEN - sizeof(EthLlc) - sizeof(EthLlcOther), p); PREPROC_PROFILE_END(decodePerfStats); return; case ETHERNET_TYPE_EAPOL: DecodeEapol(p->pkt + IEEE802_11_DATA_HDR_LEN + sizeof(EthLlc) + sizeof(EthLlcOther), cap_len - IEEE802_11_DATA_HDR_LEN - sizeof(EthLlc) - sizeof(EthLlcOther), p); PREPROC_PROFILE_END(decodePerfStats); return; case ETHERNET_TYPE_8021Q: DecodeVlan(p->pkt + IEEE802_11_DATA_HDR_LEN , cap_len - IEEE802_11_DATA_HDR_LEN , p); PREPROC_PROFILE_END(decodePerfStats); return; case ETHERNET_TYPE_IPV6: DecodeIPV6(p->pkt + IEEE802_11_DATA_HDR_LEN, cap_len - IEEE802_11_DATA_HDR_LEN, p); PREPROC_PROFILE_END(decodePerfStats); return; default: // TBD add decoder drop event for unknown wifi/eth type pc.other++; PREPROC_PROFILE_END(decodePerfStats); return; } } break; default: // TBD add decoder drop event for unknown wlan frame type pc.other++; break; } PREPROC_PROFILE_END(decodePerfStats); return; } #endif // DLT_IEEE802_11 /* * Function: DecodeTRPkt(Packet *, char *, DAQ_PktHdr_t*, uint8_t*) * * Purpose: Decode Token Ring packets! * * Arguments: p=> pointer to decoded packet struct * user => Utility pointer, unused * pkthdr => ptr to the packet header * pkt => pointer to the real live packet data * * Returns: void function */ void DecodeTRPkt(Packet * p, const DAQ_PktHdr_t * pkthdr, const uint8_t * pkt) { uint32_t cap_len = pkthdr->caplen; uint32_t dataoff; /* data offset is variable here */ PROFILE_VARS; PREPROC_PROFILE_START(decodePerfStats); pc.total_processed++; memset(p, 0, PKT_ZERO_LEN); p->pkth = pkthdr; p->pkt = pkt; DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n"); DebugMessage(DEBUG_DECODE, "caplen: %lu pktlen: %lu\n", (unsigned long)cap_len,(unsigned long) pkthdr->pktlen); ); if(cap_len < sizeof(Trh_hdr)) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Captured data length < Token Ring header length! " "(%d < %d bytes)\n", cap_len, TR_HLEN);); DecoderEvent(p, DECODE_BAD_TRH, DECODE_BAD_TRH_STR, 1, 1); PREPROC_PROFILE_END(decodePerfStats); return; } /* lay the tokenring header structure over the packet data */ p->trh = (Trh_hdr *) pkt; /* * according to rfc 1042: * * The presence of a Routing Information Field is indicated by the Most * Significant Bit (MSB) of the source address, called the Routing * Information Indicator (RII). If the RII equals zero, a RIF is * not present. If the RII equals 1, the RIF is present. * .. * However the MSB is already zeroed by this moment, so there's no * real way to figure out whether RIF is presented in packet, so we are * doing some tricks to find IPARP signature.. */ /* * first I assume that we have single-ring network with no RIF * information presented in frame */ if(cap_len < (sizeof(Trh_hdr) + sizeof(Trh_llc))) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Captured data length < Token Ring header length! " "(%d < %d bytes)\n", cap_len, (sizeof(Trh_hdr) + sizeof(Trh_llc)));); DecoderEvent(p, DECODE_BAD_TR_ETHLLC, DECODE_BAD_TR_ETHLLC_STR, 1, 1); PREPROC_PROFILE_END(decodePerfStats); return; } p->trhllc = (Trh_llc *) (pkt + sizeof(Trh_hdr)); if(p->trhllc->dsap != IPARP_SAP && p->trhllc->ssap != IPARP_SAP) { /* * DSAP != SSAP != 0xAA .. either we are having frame which doesn't * carry IP datagrams or has RIF information present. We assume * lattest ... */ if(cap_len < (sizeof(Trh_hdr) + sizeof(Trh_llc) + sizeof(Trh_mr))) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Captured data length < Token Ring header length! " "(%d < %d bytes)\n", cap_len, (sizeof(Trh_hdr) + sizeof(Trh_llc) + sizeof(Trh_mr)));); DecoderEvent(p, DECODE_BAD_TRHMR, DECODE_BAD_TRHMR_STR, 1, 1); PREPROC_PROFILE_END(decodePerfStats); return; } p->trhmr = (Trh_mr *) (pkt + sizeof(Trh_hdr)); if(cap_len < (sizeof(Trh_hdr) + sizeof(Trh_llc) + sizeof(Trh_mr) + TRH_MR_LEN(p->trhmr))) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Captured data length < Token Ring header length! " "(%d < %d bytes)\n", cap_len, (sizeof(Trh_hdr) + sizeof(Trh_llc) + sizeof(Trh_mr)));); DecoderEvent(p, DECODE_BAD_TR_MR_LEN, DECODE_BAD_TR_MR_LEN_STR, 1, 1); PREPROC_PROFILE_END(decodePerfStats); return; } p->trhllc = (Trh_llc *) (pkt + sizeof(Trh_hdr) + TRH_MR_LEN(p->trhmr)); dataoff = sizeof(Trh_hdr) + TRH_MR_LEN(p->trhmr) + sizeof(Trh_llc); } else { p->trhllc = (Trh_llc *) (pkt + sizeof(Trh_hdr)); dataoff = sizeof(Trh_hdr) + sizeof(Trh_llc); } /* * ideally we would need to check both SSAP, DSAP, and protoid fields: IP * datagrams and ARP requests and replies are transmitted in standard * 802.2 LLC Type 1 Unnumbered Information format, control code 3, with * the DSAP and the SSAP fields of the 802.2 header set to 170, the * assigned global SAP value for SNAP [6]. The 24-bit Organization Code * in the SNAP is zero, and the remaining 16 bits are the EtherType from * Assigned Numbers [7] (IP = 2048, ARP = 2054). .. but we would check * SSAP and DSAP and assume this would be enough to trust. */ if(p->trhllc->dsap != IPARP_SAP && p->trhllc->ssap != IPARP_SAP) { DEBUG_WRAP( DebugMessage(DEBUG_DECODE, "DSAP and SSAP arent set to SNAP\n"); ); p->trhllc = NULL; PREPROC_PROFILE_END(decodePerfStats); return; } switch(htons(p->trhllc->ethertype)) { case ETHERNET_TYPE_IP: DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Decoding IP\n");); DecodeIP(p->pkt + dataoff, cap_len - dataoff, p); PREPROC_PROFILE_END(decodePerfStats); return; case ETHERNET_TYPE_ARP: case ETHERNET_TYPE_REVARP: DEBUG_WRAP( DebugMessage(DEBUG_DECODE, "Decoding ARP\n"); ); pc.arp++; PREPROC_PROFILE_END(decodePerfStats); return; case ETHERNET_TYPE_8021Q: DecodeVlan(p->pkt + dataoff, cap_len - dataoff, p); PREPROC_PROFILE_END(decodePerfStats); return; default: DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Unknown network protocol: %d\n", htons(p->trhllc->ethertype))); // TBD add decoder drop event for unknown tr/eth type pc.other++; PREPROC_PROFILE_END(decodePerfStats); return; } PREPROC_PROFILE_END(decodePerfStats); return; } /* * Function: DecodeFDDIPkt(Packet *, char *, DAQ_PktHdr_t*, uint8_t*) * * Purpose: Mainly taken from CyberPsycotic's Token Ring Code -worm5er * * Arguments: p => pointer to decoded packet struct * user => Utility pointer, unused * pkthdr => ptr to the packet header * pkt => pointer to the real live packet data * * Returns: void function */ void DecodeFDDIPkt(Packet * p, const DAQ_PktHdr_t * pkthdr, const uint8_t * pkt) { uint32_t cap_len = pkthdr->caplen; uint32_t dataoff = sizeof(Fddi_hdr) + sizeof(Fddi_llc_saps); PROFILE_VARS; PREPROC_PROFILE_START(decodePerfStats); pc.total_processed++; memset(p, 0, PKT_ZERO_LEN); p->pkth = pkthdr; p->pkt = pkt; DEBUG_WRAP(DebugMessage(DEBUG_DECODE,"Packet!\n"); DebugMessage(DEBUG_DECODE, "caplen: %lu pktlen: %lu\n", (unsigned long) cap_len,(unsigned long) pkthdr->pktlen); ); /* Bounds checking (might not be right yet -worm5er) */ if(cap_len < dataoff) { if (ScLogVerbose()) { ErrorMessage("Captured data length < FDDI header length! " "(%d %d bytes)\n", cap_len, dataoff); PREPROC_PROFILE_END(decodePerfStats); return; } } /* let's put this in as the fddi header structure */ p->fddihdr = (Fddi_hdr *) pkt; p->fddisaps = (Fddi_llc_saps *) (pkt + sizeof(Fddi_hdr)); /* First we'll check and see if it's an IP/ARP Packet... */ /* Then we check to see if it's a SNA packet */ /* * Lastly we'll declare it none of the above and just slap something * generic on it to discard it with (I know that sucks, but heck we're * only looking for IP/ARP type packets currently... -worm5er */ if((p->fddisaps->dsap == FDDI_DSAP_IP) && (p->fddisaps->ssap == FDDI_SSAP_IP)) { dataoff += sizeof(Fddi_llc_iparp); if(cap_len < dataoff) { if (ScLogVerbose()) { ErrorMessage("Captured data length < FDDI header length! " "(%d %d bytes)\n", cap_len, dataoff); PREPROC_PROFILE_END(decodePerfStats); return; } } p->fddiiparp = (Fddi_llc_iparp *) (pkt + sizeof(Fddi_hdr) + sizeof(Fddi_llc_saps)); } else if((p->fddisaps->dsap == FDDI_DSAP_SNA) && (p->fddisaps->ssap == FDDI_SSAP_SNA)) { dataoff += sizeof(Fddi_llc_sna); if(cap_len < dataoff) { if (ScLogVerbose()) { ErrorMessage("Captured data length < FDDI header length! " "(%d %d bytes)\n", cap_len, dataoff); PREPROC_PROFILE_END(decodePerfStats); return; } } p->fddisna = (Fddi_llc_sna *) (pkt + sizeof(Fddi_hdr) + sizeof(Fddi_llc_saps)); } else { dataoff += sizeof(Fddi_llc_other); p->fddiother = (Fddi_llc_other *) (pkt + sizeof(Fddi_hdr) + sizeof(Fddi_llc_other)); if(cap_len < dataoff) { if (ScLogVerbose()) { ErrorMessage("Captured data length < FDDI header length! " "(%d %d bytes)\n", cap_len, dataoff); PREPROC_PROFILE_END(decodePerfStats); return; } } } /* * Now let's see if we actually care about the packet... If we don't, * throw it out!!! */ if((p->fddisaps->dsap != FDDI_DSAP_IP) || (p->fddisaps->ssap != FDDI_SSAP_IP)) { DEBUG_WRAP( DebugMessage(DEBUG_DECODE, "This FDDI Packet isn't an IP/ARP packet...\n"); ); PREPROC_PROFILE_END(decodePerfStats); return; } cap_len -= dataoff; switch(htons(p->fddiiparp->ethertype)) { case ETHERNET_TYPE_IP: DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Decoding IP\n");); DecodeIP(p->pkt + dataoff, cap_len, p); PREPROC_PROFILE_END(decodePerfStats); return; case ETHERNET_TYPE_ARP: case ETHERNET_TYPE_REVARP: DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Decoding ARP\n");); pc.arp++; PREPROC_PROFILE_END(decodePerfStats); return; case ETHERNET_TYPE_8021Q: DecodeVlan(p->pkt + dataoff, cap_len, p); PREPROC_PROFILE_END(decodePerfStats); return; default: DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Unknown network protocol: %d\n", htons(p->fddiiparp->ethertype)); ); // TBD add decoder drop event for unknown fddi/eth type pc.other++; PREPROC_PROFILE_END(decodePerfStats); return; } PREPROC_PROFILE_END(decodePerfStats); return; } #ifdef DLT_LINUX_SLL /* * Function: DecodeLinuxSLLPkt(Packet *, char *, DAQ_PktHdr_t*, uint8_t*) * * Purpose: Decode those fun loving LinuxSLL (linux cooked sockets) * packets, one at a time! * * Arguments: p => pointer to the decoded packet struct * user => Utility pointer (unused) * pkthdr => ptr to the packet header * pkt => pointer to the real live packet data * * Returns: void function */ void DecodeLinuxSLLPkt(Packet * p, const DAQ_PktHdr_t * pkthdr, const uint8_t * pkt) { uint32_t cap_len = pkthdr->caplen; PROFILE_VARS; PREPROC_PROFILE_START(decodePerfStats); pc.total_processed++; memset(p, 0, PKT_ZERO_LEN); p->pkth = pkthdr; p->pkt = pkt; DEBUG_WRAP(DebugMessage(DEBUG_DECODE,"Packet!\n"); DebugMessage(DEBUG_DECODE, "caplen: %lu pktlen: %lu\n", (unsigned long)cap_len, (unsigned long)pkthdr->pktlen);); /* do a little validation */ if(cap_len < SLL_HDR_LEN) { if (ScLogVerbose()) { ErrorMessage("Captured data length < SLL header length (your " "libpcap is broken?)! (%d bytes)\n", cap_len); } PREPROC_PROFILE_END(decodePerfStats); return; } /* lay the ethernet structure over the packet data */ p->sllh = (SLLHdr *) pkt; /* grab out the network type */ switch(ntohs(p->sllh->sll_protocol)) { case ETHERNET_TYPE_IP: DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "IP datagram size calculated to be %lu bytes\n", (unsigned long)(cap_len - SLL_HDR_LEN));); DecodeIP(p->pkt + SLL_HDR_LEN, cap_len - SLL_HDR_LEN, p); PREPROC_PROFILE_END(decodePerfStats); return; case ETHERNET_TYPE_ARP: case ETHERNET_TYPE_REVARP: DecodeARP(p->pkt + SLL_HDR_LEN, cap_len - SLL_HDR_LEN, p); PREPROC_PROFILE_END(decodePerfStats); return; case ETHERNET_TYPE_IPV6: DecodeIPV6(p->pkt + SLL_HDR_LEN, (cap_len - SLL_HDR_LEN), p); PREPROC_PROFILE_END(decodePerfStats); return; case ETHERNET_TYPE_IPX: DecodeIPX(p->pkt + SLL_HDR_LEN, (cap_len - SLL_HDR_LEN), p); PREPROC_PROFILE_END(decodePerfStats); return; case LINUX_SLL_P_802_3: DEBUG_WRAP(DebugMessage(DEBUG_DATALINK, "Linux SLL P 802.3 is not supported.\n");); // TBD add decoder drop event for unsupported linux sll p 802.3 pc.other++; PREPROC_PROFILE_END(decodePerfStats); return; case LINUX_SLL_P_802_2: DEBUG_WRAP(DebugMessage(DEBUG_DATALINK, "Linux SLL P 802.2 is not supported.\n");); // TBD add decoder drop event for unsupported linux sll p 802.2 pc.other++; PREPROC_PROFILE_END(decodePerfStats); return; case ETHERNET_TYPE_8021Q: DecodeVlan(p->pkt + SLL_HDR_LEN, cap_len - SLL_HDR_LEN, p); PREPROC_PROFILE_END(decodePerfStats); return; default: /* shouldn't go here unless pcap library changes again */ /* should be a DECODE generated alert */ DEBUG_WRAP(DebugMessage(DEBUG_DATALINK,"(Unknown) %X is not supported. " "(need tcpdump snapshots to test. Please contact us)\n", p->sllh->sll_protocol);); // TBD add decoder drop event for unknown sll encapsulation pc.other++; PREPROC_PROFILE_END(decodePerfStats); return; } PREPROC_PROFILE_END(decodePerfStats); return; } #endif /* DLT_LINUX_SLL */ /* * Function: DecodeOldPflog(Packet *, DAQ_PktHdr_t *, uint8_t *) * * Purpose: Pass old pflog format device packets off to IP or IP6 -fleck * * Arguments: p => pointer to the decoded packet struct * pkthdr => ptr to the packet header * pkt => pointer to the packet data * * Returns: void function * */ void DecodeOldPflog(Packet * p, const DAQ_PktHdr_t * pkthdr, const uint8_t * pkt) { uint32_t cap_len = pkthdr->caplen; PROFILE_VARS; PREPROC_PROFILE_START(decodePerfStats); pc.total_processed++; memset(p, 0, PKT_ZERO_LEN); p->pkth = pkthdr; p->pkt = pkt; DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n"); DebugMessage(DEBUG_DECODE, "caplen: %lu pktlen: %lu\n", (unsigned long)cap_len, (unsigned long)pkthdr->pktlen);); /* do a little validation */ if(cap_len < PFLOG1_HDRLEN) { if (ScLogVerbose()) { ErrorMessage("Captured data length < Pflog header length! " "(%d bytes)\n", cap_len); } PREPROC_PROFILE_END(decodePerfStats); return; } /* lay the pf header structure over the packet data */ p->pf1h = (Pflog1Hdr*)pkt; /* get the network type - should only be AF_INET or AF_INET6 */ switch(ntohl(p->pf1h->af)) { case AF_INET: /* IPv4 */ DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "IP datagram size calculated to be %lu " "bytes\n", (unsigned long)(cap_len - PFLOG1_HDRLEN));); DecodeIP(p->pkt + PFLOG1_HDRLEN, cap_len - PFLOG1_HDRLEN, p); PREPROC_PROFILE_END(decodePerfStats); return; #if defined(AF_INET6) case AF_INET6: /* IPv6 */ DecodeIPV6(p->pkt + PFLOG1_HDRLEN, cap_len - PFLOG1_HDRLEN, p); PREPROC_PROFILE_END(decodePerfStats); return; #endif default: /* To my knowledge, pflog devices can only * pass IP and IP6 packets. -fleck */ // TBD add decoder drop event for unknown old pflog network type pc.other++; PREPROC_PROFILE_END(decodePerfStats); return; } PREPROC_PROFILE_END(decodePerfStats); return; } /* * Function: DecodePflog(Packet *, DAQ_PktHdr_t *, uint8_t *) * * Purpose: Pass pflog device packets off to IP or IP6 -fleck * * Arguments: p => pointer to the decoded packet struct * pkthdr => ptr to the packet header * pkt => pointer to the packet data * * Returns: void function * */ void DecodePflog(Packet * p, const DAQ_PktHdr_t * pkthdr, const uint8_t * pkt) { uint32_t cap_len = pkthdr->caplen; uint8_t af, pflen; uint32_t hlen; uint32_t padlen = PFLOG_PADLEN; PROFILE_VARS; PREPROC_PROFILE_START(decodePerfStats); pc.total_processed++; memset(p, 0, PKT_ZERO_LEN); p->pkth = pkthdr; p->pkt = pkt; DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n"); DebugMessage(DEBUG_DECODE, "caplen: %lu pktlen: %lu\n", (unsigned long)cap_len, (unsigned long)pkthdr->pktlen);); /* do a little validation */ if(cap_len < PFLOG2_HDRMIN) { if (ScLogVerbose()) { ErrorMessage("Captured data length < minimum Pflog length! " "(%d < %lu)\n", cap_len, (unsigned long)PFLOG2_HDRMIN); } PREPROC_PROFILE_END(decodePerfStats); return; } /* lay the pf header structure over the packet data */ switch(*((uint8_t*)pkt)) { case PFLOG2_HDRMIN: p->pf2h = (Pflog2Hdr*)pkt; pflen = p->pf2h->length; hlen = PFLOG2_HDRLEN; af = p->pf2h->af; break; case PFLOG3_HDRMIN: p->pf3h = (Pflog3Hdr*)pkt; pflen = p->pf3h->length; hlen = PFLOG3_HDRLEN; af = p->pf3h->af; break; case PFLOG4_HDRMIN: p->pf4h = (Pflog4Hdr*)pkt; pflen = p->pf4h->length; hlen = PFLOG4_HDRLEN; af = p->pf4h->af; padlen = sizeof(p->pf4h->pad); break; default: if (ScLogVerbose()) { ErrorMessage("unrecognized pflog header length! (%d)\n", *((uint8_t*)pkt)); } pc.discards++; PREPROC_PROFILE_END(decodePerfStats); return; } /* now that we know a little more, do a little more validation */ if(cap_len < hlen) { if (ScLogVerbose()) { ErrorMessage("Captured data length < Pflog header length! " "(%d < %d)\n", cap_len, hlen); } pc.discards++; PREPROC_PROFILE_END(decodePerfStats); return; } /* note that the pflen may exclude the padding which is always present */ if(pflen < hlen - padlen || pflen > hlen) { if (ScLogVerbose()) { ErrorMessage("Bad Pflog header length! (%d bytes)\n", pflen); } pc.discards++; PREPROC_PROFILE_END(decodePerfStats); return; } DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "IP datagram size calculated to be " "%lu bytes\n", (unsigned long)(cap_len - hlen));); /* check the network type - should only be AF_INET or AF_INET6 */ switch(af) { case AF_INET: /* IPv4 */ DecodeIP(p->pkt + hlen, cap_len - hlen, p); PREPROC_PROFILE_END(decodePerfStats); return; #if defined(AF_INET6) case AF_INET6: /* IPv6 */ DecodeIPV6(p->pkt + hlen, cap_len - hlen, p); PREPROC_PROFILE_END(decodePerfStats); return; #endif default: /* To my knowledge, pflog devices can only * pass IP and IP6 packets. -fleck */ // TBD add decoder drop event for unknown pflog network type pc.other++; PREPROC_PROFILE_END(decodePerfStats); return; } PREPROC_PROFILE_END(decodePerfStats); return; } /* * Function: DecodePppPkt(Packet *, char *, DAQ_PktHdr_t*, uint8_t*) * * Purpose: Decode PPP traffic (either RFC1661 or RFC1662 framing). * This really is intended to handle IPCP * * Arguments: p => pointer to decoded packet struct * user => Utility pointer, unused * pkthdr => ptr to the packet header * pkt => pointer to the real live packet data * * Returns: void function */ // DecodePppPkt() and DecodePppSerialPkt() may be incorrect ... // both skip past 2 byte protocol and then call DecodePppPktEncapsulated() // which does the same thing. That one works inside DecodePPPoEPkt(); void DecodePppPkt(Packet * p, const DAQ_PktHdr_t * pkthdr, const uint8_t * pkt) { uint32_t cap_len = pkthdr->caplen; int hlen = 0; PROFILE_VARS; PREPROC_PROFILE_START(decodePerfStats); pc.total_processed++; memset(p, 0, PKT_ZERO_LEN); p->pkth = pkthdr; p->pkt = pkt; DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n");); if(cap_len < 2) { if (ScLogVerbose()) { ErrorMessage("Length not big enough for even a single " "header or a one byte payload\n"); } PREPROC_PROFILE_END(decodePerfStats); return; } if(pkt[0] == CHDLC_ADDR_BROADCAST && pkt[1] == CHDLC_CTRL_UNNUMBERED) { /* * Check for full HDLC header (rfc1662 section 3.2) */ hlen = 2; } DecodePppPktEncapsulated(p->pkt + hlen, cap_len - hlen, p); PREPROC_PROFILE_END(decodePerfStats); return; } /* * Function: DecodePppSerialPkt(Packet *, char *, DAQ_PktHdr_t*, uint8_t*) * * Purpose: Decode Mixed PPP/CHDLC traffic. The PPP frames will always have the * full HDLC header. * * Arguments: p => pointer to decoded packet struct * user => Utility pointer, unused * pkthdr => ptr to the packet header * pkt => pointer to the real live packet data * * Returns: void function */ void DecodePppSerialPkt(Packet * p, const DAQ_PktHdr_t * pkthdr, const uint8_t * pkt) { uint32_t cap_len = pkthdr->caplen; PROFILE_VARS; PREPROC_PROFILE_START(decodePerfStats); pc.total_processed++; memset(p, 0, PKT_ZERO_LEN); p->pkth = pkthdr; p->pkt = pkt; DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n");); if(cap_len < PPP_HDRLEN) { if (ScLogVerbose()) { ErrorMessage("Captured data length < PPP header length" " (%d bytes)\n", cap_len); } PREPROC_PROFILE_END(decodePerfStats); return; } if(pkt[0] == CHDLC_ADDR_BROADCAST && pkt[1] == CHDLC_CTRL_UNNUMBERED) { DecodePppPktEncapsulated(p->pkt + 2, cap_len - 2, p); } else { DecodeChdlcPkt(p, pkthdr, pkt); } PREPROC_PROFILE_END(decodePerfStats); return; } /* * Function: DecodeSlipPkt(Packet *, char *, DAQ_PktHdr_t*, uint8_t*) * * Purpose: Decode SLIP traffic * * Arguments: p => pointer to decoded packet struct * user => Utility pointer, unused * pkthdr => ptr to the packet header * pkt => pointer to the real live packet data * * Returns: void function */ void DecodeSlipPkt(Packet * p, const DAQ_PktHdr_t * pkthdr, const uint8_t * pkt) { uint32_t cap_len = pkthdr->caplen; PROFILE_VARS; PREPROC_PROFILE_START(decodePerfStats); pc.total_processed++; memset(p, 0, PKT_ZERO_LEN); p->pkth = pkthdr; p->pkt = pkt; DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n");); /* do a little validation */ if(cap_len < SLIP_HEADER_LEN) { ErrorMessage("SLIP header length < captured len! (%d bytes)\n", cap_len); PREPROC_PROFILE_END(decodePerfStats); return; } DecodeIP(p->pkt + SLIP_HEADER_LEN, cap_len - SLIP_HEADER_LEN, p); PREPROC_PROFILE_END(decodePerfStats); } /* * Function: DecodeI4LRawIPPkt(Packet *, char *, DAQ_PktHdr_t*, uint8_t*) * * Purpose: Decodes packets coming in raw on layer 2, like PPP. Coded and * in by Jed Pickle (thanks Jed!) and modified for a few little tweaks * by me. * * Arguments: p => pointer to decoded packet struct * user => Utility pointer, unused * pkthdr => ptr to the packet header * pkt => pointer to the real live packet data * * Returns: void function */ void DecodeI4LRawIPPkt(Packet * p, const DAQ_PktHdr_t * pkthdr, const uint8_t * pkt) { PROFILE_VARS; PREPROC_PROFILE_START(decodePerfStats); pc.total_processed++; memset(p, 0, PKT_ZERO_LEN); p->pkth = pkthdr; p->pkt = pkt; if(p->pkth->pktlen < 2) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "What the hell is this?\n");); // TBD add decoder drop event for bad i4l raw pkt pc.other++; PREPROC_PROFILE_END(decodePerfStats); return; } DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n");); DecodeIP(pkt + 2, p->pkth->pktlen - 2, p); PREPROC_PROFILE_END(decodePerfStats); return; } /* * Function: DecodeI4LCiscoIPPkt(Packet *, char *, * DAQ_PktHdr_t*, uint8_t*) * * Purpose: Decodes packets coming in raw on layer 2, like PPP. Coded and * in by Jed Pickle (thanks Jed!) and modified for a few little tweaks * by me. * * Arguments: p => pointer to decoded packet struct * user => Utility pointer, unused * pkthdr => ptr to the packet header * pkt => pointer to the real live packet data * * Returns: void function */ void DecodeI4LCiscoIPPkt(Packet *p, const DAQ_PktHdr_t *pkthdr, const uint8_t *pkt) { PROFILE_VARS; PREPROC_PROFILE_START(decodePerfStats); pc.total_processed++; memset(p, 0, PKT_ZERO_LEN); p->pkth = pkthdr; p->pkt = pkt; if(p->pkth->pktlen < 4) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "What the hell is this?\n");); // TBD add decoder drop event for bad i4l cisco pkt pc.other++; PREPROC_PROFILE_END(decodePerfStats); return; } DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n");); DecodeIP(pkt + 4, p->pkth->caplen - 4, p); PREPROC_PROFILE_END(decodePerfStats); return; } /* * Function: DecodeChdlcPkt(Packet *, char *, * DAQ_PktHdr_t*, uint8_t*) * * Purpose: Decodes Cisco HDLC encapsulated packets, f.ex. from SONET. * * Arguments: p => pointer to decoded packet struct * user => Utility pointer, unused * pkthdr => ptr to the packet header * pkt => pointer to the real live packet data * * Returns: void function */ void DecodeChdlcPkt(Packet *p, const DAQ_PktHdr_t *pkthdr, const uint8_t *pkt) { uint32_t cap_len = pkthdr->caplen; PROFILE_VARS; PREPROC_PROFILE_START(decodePerfStats); pc.total_processed++; memset(p, 0, PKT_ZERO_LEN); p->pkth = pkthdr; p->pkt = pkt; if(cap_len < CHDLC_HEADER_LEN) { if (ScLogVerbose()) { ErrorMessage("Captured data length < CHDLC header length" " (%d bytes)\n", cap_len); } PREPROC_PROFILE_END(decodePerfStats); return; } DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n");); if ((pkt[0] == CHDLC_ADDR_UNICAST || pkt[0] == CHDLC_ADDR_MULTICAST) && ntohs(*(uint16_t *)&pkt[2]) == ETHERNET_TYPE_IP) { DecodeIP(p->pkt + CHDLC_HEADER_LEN, cap_len - CHDLC_HEADER_LEN, p); } else { // TBD add decoder drop event for unsupported chdlc encapsulation pc.other++; } PREPROC_PROFILE_END(decodePerfStats); return; } /* * Function: DecodeEapol(uint8_t *, uint32_t, Packet *) * * Purpose: Decode 802.1x eapol stuff * * Arguments: pkt => ptr to the packet data * len => length from here to the end of the packet * p => pointer to decoded packet struct * * Returns: void function */ void DecodeEapol(const uint8_t * pkt, uint32_t len, Packet * p) { p->eplh = (EtherEapol *) pkt; pc.eapol++; if(len < sizeof(EtherEapol)) { DecoderEvent(p, DECODE_EAPOL_TRUNCATED, DECODE_EAPOL_TRUNCATED_STR, 1, 1); pc.discards++; return; } if (p->eplh->eaptype == EAPOL_TYPE_EAP) { DecodeEAP(pkt + sizeof(EtherEapol), len - sizeof(EtherEapol), p); } else if(p->eplh->eaptype == EAPOL_TYPE_KEY) { DecodeEapolKey(pkt + sizeof(EtherEapol), len - sizeof(EtherEapol), p); } return; } /* * Function: DecodeEapolKey(uint8_t *, uint32_t, Packet *) * * Purpose: Decode 1x key setup * * Arguments: pkt => ptr to the packet data * len => length from here to the end of the packet * p => pointer to decoded packet struct * * Returns: void function */ void DecodeEapolKey(const uint8_t * pkt, uint32_t len, Packet * p) { p->eapolk = (EapolKey *) pkt; if(len < sizeof(EapolKey)) { DecoderEvent(p, DECODE_EAPKEY_TRUNCATED, DECODE_EAPKEY_TRUNCATED_STR, 1, 1); pc.discards++; return; } return; } /* * Function: DecodeEAP(uint8_t *, uint32_t, Packet *) * * Purpose: Decode Extensible Authentication Protocol * * Arguments: pkt => ptr to the packet data * len => length from here to the end of the packet * p => pointer to decoded packet struct * * Returns: void function */ void DecodeEAP(const uint8_t * pkt, const uint32_t len, Packet * p) { p->eaph = (EAPHdr *) pkt; if(len < sizeof(EAPHdr)) { DecoderEvent(p, DECODE_EAP_TRUNCATED, DECODE_EAP_TRUNCATED_STR, 1, 1); pc.discards++; return; } if (p->eaph->code == EAP_CODE_REQUEST || p->eaph->code == EAP_CODE_RESPONSE) { p->eaptype = pkt + sizeof(EAPHdr); } return; } /* * Function: DecodeIPX(uint8_t *, uint32_t) * * Purpose: Well, it doesn't do much of anything right now... * * Arguments: pkt => ptr to the packet data * len => length from here to the end of the packet * * Returns: void function * */ void DecodeIPX(const uint8_t *pkt, uint32_t len, Packet *p) { DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "IPX is not supported.\n");); pc.ipx++; #ifdef GRE if (p->greh != NULL) pc.gre_ipx++; #endif return; } #ifdef DLT_ENC /* see http://sourceforge.net/mailarchive/message.php?msg_id=1000380 */ /* * Function: DecodeEncPkt(Packet *, DAQ_PktHdr_t *, uint8_t *) * * Purpose: Decapsulate packets of type DLT_ENC. * XXX Are these always going to be IP in IP? * * Arguments: p => pointer to decoded packet struct * pkthdr => pointer to the packet header * pkt => pointer to the real live packet data */ void DecodeEncPkt(Packet *p, const DAQ_PktHdr_t *pkthdr, const uint8_t *pkt) { uint32_t cap_len = pkthdr->caplen; struct enc_header *enc_h; PROFILE_VARS; PREPROC_PROFILE_START(decodePerfStats); pc.total_processed++; memset(p, 0, PKT_ZERO_LEN); p->pkth = pkthdr; p->pkt = pkt; if (cap_len < ENC_HEADER_LEN) { if (ScLogVerbose()) { ErrorMessage("Captured data length < Encap header length! (%d bytes)\n", cap_len); } PREPROC_PROFILE_END(decodePerfStats); return; } enc_h = (struct enc_header *)p->pkt; if (enc_h->af == AF_INET) { DecodeIP(p->pkt + ENC_HEADER_LEN + IP_HEADER_LEN, cap_len - ENC_HEADER_LEN - IP_HEADER_LEN, p); } else { ErrorMessage("WARNING: Unknown address family (af: 0x%x).\n", enc_h->af); } PREPROC_PROFILE_END(decodePerfStats); return; } #endif /* DLT_ENC */ #endif // NO_NON_ETHER_DECODER snort-2.9.15.1/src/decode.h0000644000175200017520000017676213571422607012256 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifndef __DECODE_H__ #define __DECODE_H__ /* I N C L U D E S **********************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #ifndef WIN32 #include #include #include #else /* !WIN32 */ #include #ifndef IFNAMSIZ #define IFNAMESIZ MAX_ADAPTER_NAME #endif /* !IFNAMSIZ */ #endif /* !WIN32 */ #include #include #include "bitop.h" #include "ipv6_port.h" #include "sf_ip.h" #include "sf_iph.h" #include "sf_protocols.h" #include "util.h" #include "sf_types.h" #include "sf_sdlist_types.h" #include "preprocids.h" struct _SnortConfig; /* D E F I N E S ************************************************************/ #define ETHERNET_MTU 1500 #define ETHERNET_TYPE_IP 0x0800 #define ETHERNET_TYPE_ARP 0x0806 #define ETHERNET_TYPE_REVARP 0x8035 #define ETHERNET_TYPE_EAPOL 0x888e #define ETHERNET_TYPE_IPV6 0x86dd #define ETHERNET_TYPE_IPX 0x8137 #define ETHERNET_TYPE_PPPoE_DISC 0x8863 /* discovery stage */ #define ETHERNET_TYPE_PPPoE_SESS 0x8864 /* session stage */ #define ETHERNET_TYPE_8021Q 0x8100 #define ETHERNET_TYPE_8021AD 0x88a8 #define ETHERNET_TYPE_QINQ_NS1 0x9100 /* Q-in-Q non standard */ #define ETHERNET_TYPE_QINQ_NS2 0x9200 /* Q-in-Q non standard */ #define ETHERNET_TYPE_LOOP 0x9000 #define ETHERNET_TYPE_MPLS_UNICAST 0x8847 #define ETHERNET_TYPE_MPLS_MULTICAST 0x8848 #define ETHERNET_TYPE_ERSPAN_TYPE2 0x88be #define ETHERNET_TYPE_ERSPAN_TYPE3 0x22eb #define ETHERNET_TYPE_FPATH 0x8903 #define ETHERNET_TYPE_CISCO_META 0x8909 #define ETH_DSAP_SNA 0x08 /* SNA */ #define ETH_SSAP_SNA 0x00 /* SNA */ #define ETH_DSAP_STP 0x42 /* Spanning Tree Protocol */ #define ETH_SSAP_STP 0x42 /* Spanning Tree Protocol */ #define ETH_DSAP_IP 0xaa /* IP */ #define ETH_SSAP_IP 0xaa /* IP */ #define ETH_ORG_CODE_ETHR 0x000000 /* Encapsulated Ethernet */ #define ETH_ORG_CODE_CDP 0x00000c /* Cisco Discovery Proto */ #define FABRICPATH_HEADER_LEN 16 #define ETHERNET_HEADER_LEN 14 #define ETHERNET_MAX_LEN_ENCAP 1518 /* 802.3 (+LLC) or ether II ? */ #define FABRICPATH_HEADER_LEN 16 #define CISCO_META_PREHEADER_LEN 2 #define CISCO_META_VALID_OPT_LEN 4 /* length of valid options */ #define CISCO_META_OPT_LEN_SHIFT 13 /* right shift opt_len_type to get option length */ #define CISCO_META_OPT_TYPE_MASK 0x1FFF /* mask opt_len_type to get option type */ #define CISCO_META_OPT_TYPE_SGT 1 #define PPPOE_HEADER_LEN 6 #define VLAN_HEADER_LEN 4 #ifndef NO_NON_ETHER_DECODER #define MINIMAL_TOKENRING_HEADER_LEN 22 #define MINIMAL_IEEE80211_HEADER_LEN 10 /* Ack frames and others */ #define IEEE802_11_DATA_HDR_LEN 24 /* Header for data packets */ #define TR_HLEN MINIMAL_TOKENRING_HEADER_LEN #define TOKENRING_LLC_LEN 8 #define SLIP_HEADER_LEN 16 /* Frame type/subype combinations with version = 0 */ /*** FRAME TYPE ***** HEX **** SUBTYPE TYPE DESCRIPT ********/ #define WLAN_TYPE_MGMT_ASREQ 0x0 /* 0000 00 Association Req */ #define WLAN_TYPE_MGMT_ASRES 0x10 /* 0001 00 Assocaition Res */ #define WLAN_TYPE_MGMT_REREQ 0x20 /* 0010 00 Reassoc. Req. */ #define WLAN_TYPE_MGMT_RERES 0x30 /* 0011 00 Reassoc. Resp. */ #define WLAN_TYPE_MGMT_PRREQ 0x40 /* 0100 00 Probe Request */ #define WLAN_TYPE_MGMT_PRRES 0x50 /* 0101 00 Probe Response */ #define WLAN_TYPE_MGMT_BEACON 0x80 /* 1000 00 Beacon */ #define WLAN_TYPE_MGMT_ATIM 0x90 /* 1001 00 ATIM message */ #define WLAN_TYPE_MGMT_DIS 0xa0 /* 1010 00 Disassociation */ #define WLAN_TYPE_MGMT_AUTH 0xb0 /* 1011 00 Authentication */ #define WLAN_TYPE_MGMT_DEAUTH 0xc0 /* 1100 00 Deauthentication*/ #define WLAN_TYPE_CONT_PS 0xa4 /* 1010 01 Power Save */ #define WLAN_TYPE_CONT_RTS 0xb4 /* 1011 01 Request to send */ #define WLAN_TYPE_CONT_CTS 0xc4 /* 1100 01 Clear to sene */ #define WLAN_TYPE_CONT_ACK 0xd4 /* 1101 01 Acknowledgement */ #define WLAN_TYPE_CONT_CFE 0xe4 /* 1110 01 Cont. Free end */ #define WLAN_TYPE_CONT_CFACK 0xf4 /* 1111 01 CF-End + CF-Ack */ #define WLAN_TYPE_DATA_DATA 0x08 /* 0000 10 Data */ #define WLAN_TYPE_DATA_DTCFACK 0x18 /* 0001 10 Data + CF-Ack */ #define WLAN_TYPE_DATA_DTCFPL 0x28 /* 0010 10 Data + CF-Poll */ #define WLAN_TYPE_DATA_DTACKPL 0x38 /* 0011 10 Data+CF-Ack+CF-Pl */ #define WLAN_TYPE_DATA_NULL 0x48 /* 0100 10 Null (no data) */ #define WLAN_TYPE_DATA_CFACK 0x58 /* 0101 10 CF-Ack (no data)*/ #define WLAN_TYPE_DATA_CFPL 0x68 /* 0110 10 CF-Poll (no data)*/ #define WLAN_TYPE_DATA_ACKPL 0x78 /* 0111 10 CF-Ack+CF-Poll */ /*** Flags for IEEE 802.11 Frame Control ***/ /* The following are designed to be bitwise-AND-d in an 8-bit u_char */ #define WLAN_FLAG_TODS 0x0100 /* To DS Flag 10000000 */ #define WLAN_FLAG_FROMDS 0x0200 /* From DS Flag 01000000 */ #define WLAN_FLAG_FRAG 0x0400 /* More Frag 00100000 */ #define WLAN_FLAG_RETRY 0x0800 /* Retry Flag 00010000 */ #define WLAN_FLAG_PWRMGMT 0x1000 /* Power Mgmt. 00001000 */ #define WLAN_FLAG_MOREDAT 0x2000 /* More Data 00000100 */ #define WLAN_FLAG_WEP 0x4000 /* Wep Enabled 00000010 */ #define WLAN_FLAG_ORDER 0x8000 /* Strict Order 00000001 */ /* IEEE 802.1x eapol types */ #define EAPOL_TYPE_EAP 0x00 /* EAP packet */ #define EAPOL_TYPE_START 0x01 /* EAPOL start */ #define EAPOL_TYPE_LOGOFF 0x02 /* EAPOL Logoff */ #define EAPOL_TYPE_KEY 0x03 /* EAPOL Key */ #define EAPOL_TYPE_ASF 0x04 /* EAPOL Encapsulated ASF-Alert */ /* Extensible Authentication Protocol Codes RFC 2284*/ #define EAP_CODE_REQUEST 0x01 #define EAP_CODE_RESPONSE 0x02 #define EAP_CODE_SUCCESS 0x03 #define EAP_CODE_FAILURE 0x04 /* EAP Types */ #define EAP_TYPE_IDENTITY 0x01 #define EAP_TYPE_NOTIFY 0x02 #define EAP_TYPE_NAK 0x03 #define EAP_TYPE_MD5 0x04 #define EAP_TYPE_OTP 0x05 #define EAP_TYPE_GTC 0x06 #define EAP_TYPE_TLS 0x0d #endif // NO_NON_ETHER_DECODER /* Cisco HDLC header values */ #define CHDLC_HEADER_LEN 4 #define CHDLC_ADDR_UNICAST 0x0f #define CHDLC_ADDR_MULTICAST 0x8f #define CHDLC_ADDR_BROADCAST 0xff #define CHDLC_CTRL_UNNUMBERED 0x03 /* Teredo values */ #define TEREDO_PORT 3544 #define TEREDO_INDICATOR_ORIGIN 0x00 #define TEREDO_INDICATOR_ORIGIN_LEN 8 #define TEREDO_INDICATOR_AUTH 0x01 #define TEREDO_INDICATOR_AUTH_MIN_LEN 13 #define TEREDO_MIN_LEN 2 /* GTP values */ #define GTP_MIN_LEN 8 #define GTP_V0_HEADER_LEN 20 #define GTP_V1_HEADER_LEN 12 /* ESP constants */ #define ESP_HEADER_LEN 8 #define ESP_AUTH_DATA_LEN 12 #define ESP_TRAILER_LEN 2 #define MAX_PORTS 65536 /* ppp header structure * * Actually, this is the header for RFC1332 Section 3 * IPCP Configuration Options for sending IP datagrams over a PPP link * */ struct ppp_header { unsigned char address; unsigned char control; unsigned short protocol; }; #ifndef PPP_HDRLEN #define PPP_HDRLEN sizeof(struct ppp_header) #endif #define PPP_IP 0x0021 /* Internet Protocol */ #define PPP_IPV6 0x0057 /* Internet Protocol v6 */ #define PPP_VJ_COMP 0x002d /* VJ compressed TCP/IP */ #define PPP_VJ_UCOMP 0x002f /* VJ uncompressed TCP/IP */ #define PPP_IPX 0x002b /* Novell IPX Protocol */ /* otherwise defined in /usr/include/ppp_defs.h */ #ifndef PPP_MTU #define PPP_MTU 1500 #endif /* NULL aka LoopBack interfaces */ #define NULL_HDRLEN 4 /* enc interface */ struct enc_header { uint32_t af; uint32_t spi; uint32_t flags; }; #define ENC_HEADER_LEN 12 /* otherwise defined in /usr/include/ppp_defs.h */ #define IP_HEADER_LEN 20 #define TCP_HEADER_LEN 20 #define UDP_HEADER_LEN 8 #define ICMP_HEADER_LEN 4 #define ICMP_NORMAL_LEN 8 #define IP_OPTMAX 40 #define TCP_OPTLENMAX 40 /* (((2^4) - 1) * 4 - TCP_HEADER_LEN) */ #define LOG_FUNC_MAX 32 #ifndef IP_MAXPACKET #define IP_MAXPACKET 65535 /* maximum packet size */ #endif /* IP_MAXPACKET */ /* http://www.iana.org/assignments/ipv6-parameters * * IPv6 Options (not Extension Headers) */ #define IP6_OPT_TUNNEL_ENCAP 0x04 #define IP6_OPT_QUICK_START 0x06 #define IP6_OPT_CALIPSO 0x07 #define IP6_OPT_HOME_ADDRESS 0xC9 #define IP6_OPT_ENDPOINT_IDENT 0x8A // these are bits in th_flags: #define TH_FIN 0x01 #define TH_SYN 0x02 #define TH_RST 0x04 #define TH_PUSH 0x08 #define TH_ACK 0x10 #define TH_URG 0x20 #define TH_ECE 0x40 #define TH_CWR 0x80 #define TH_RES2 TH_ECE // TBD TH_RES* should be deleted (see log.c) #define TH_RES1 TH_CWR #define TH_NORESERVED (TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG) // these are bits in th_offx2: #define TH_RSV 0x0E // reserved bits #define TH_NS 0x01 // ECN nonce bit /* http://www.iana.org/assignments/tcp-parameters * * tcp options stuff. used to be in but it breaks * things on AIX */ #define TCPOPT_EOL 0 /* End of Option List [RFC793] */ #define TCPOLEN_EOL 1 /* Always one byte */ #define TCPOPT_NOP 1 /* No-Option [RFC793] */ #define TCPOLEN_NOP 1 /* Always one byte */ #define TCPOPT_MAXSEG 2 /* Maximum Segment Size [RFC793] */ #define TCPOLEN_MAXSEG 4 /* Always 4 bytes */ #define TCPOPT_WSCALE 3 /* Window scaling option [RFC1323] */ #define TCPOLEN_WSCALE 3 /* 1 byte with logarithmic values */ #define TCPOPT_SACKOK 4 /* Experimental [RFC2018]*/ #define TCPOLEN_SACKOK 2 #define TCPOPT_SACK 5 /* Experimental [RFC2018] variable length */ #define TCPOPT_ECHO 6 /* Echo (obsoleted by option 8) [RFC1072] */ #define TCPOLEN_ECHO 6 /* 6 bytes */ #define TCPOPT_ECHOREPLY 7 /* Echo Reply (obsoleted by option 8)[RFC1072] */ #define TCPOLEN_ECHOREPLY 6 /* 6 bytes */ #define TCPOPT_TIMESTAMP 8 /* Timestamp [RFC1323], 10 bytes */ #define TCPOLEN_TIMESTAMP 10 #define TCPOPT_PARTIAL_PERM 9 /* Partial Order Permitted/ Experimental [RFC1693] */ #define TCPOLEN_PARTIAL_PERM 2 /* Partial Order Permitted/ Experimental [RFC1693] */ #define TCPOPT_PARTIAL_SVC 10 /* Partial Order Profile [RFC1693] */ #define TCPOLEN_PARTIAL_SVC 3 /* 3 bytes long -- Experimental */ /* atleast decode T/TCP options... */ #define TCPOPT_CC 11 /* T/TCP Connection count [RFC1644] */ #define TCPOPT_CC_NEW 12 /* CC.NEW [RFC1644] */ #define TCPOPT_CC_ECHO 13 /* CC.ECHO [RFC1644] */ #define TCPOLEN_CC 6 /* page 17 of rfc1644 */ #define TCPOLEN_CC_NEW 6 /* page 17 of rfc1644 */ #define TCPOLEN_CC_ECHO 6 /* page 17 of rfc1644 */ #define TCPOPT_ALTCSUM 15 /* TCP Alternate Checksum Data [RFC1146], variable length */ #define TCPOPT_SKEETER 16 /* Skeeter [Knowles] */ #define TCPOPT_BUBBA 17 /* Bubba [Knowles] */ #define TCPOPT_TRAILER_CSUM 18 /* Trailer Checksum Option [Subbu & Monroe] */ #define TCPOLEN_TRAILER_CSUM 3 #define TCPOPT_MD5SIG 19 /* MD5 Signature Option [RFC2385] */ #define TCPOLEN_MD5SIG 18 /* Space Communications Protocol Standardization */ #define TCPOPT_SCPS 20 /* Capabilities [Scott] */ #define TCPOPT_SELNEGACK 21 /* Selective Negative Acknowledgements [Scott] */ #define TCPOPT_RECORDBOUND 22 /* Record Boundaries [Scott] */ #define TCPOPT_CORRUPTION 23 /* Corruption experienced [Scott] */ #define TCPOPT_SNAP 24 /* SNAP [Sukonnik] -- anyone have info?*/ #define TCPOPT_UNASSIGNED 25 /* Unassigned (released 12/18/00) */ #define TCPOPT_COMPRESSION 26 /* TCP Compression Filter [Bellovin] */ /* http://www.research.att.com/~smb/papers/draft-bellovin-tcpcomp-00.txt*/ #define TCPOPT_AUTH 29 /* [RFC5925] - The TCP Authentication Option Intended to replace MD5 Signature Option [RFC2385] */ #define TCP_OPT_TRUNC -1 #define TCP_OPT_BADLEN -2 /* Why are these lil buggers here? Never Used. -- cmg */ #define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP+2) /* appendix A / rfc 1323 */ #define TCPOPT_TSTAMP_HDR \ (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP) /* * Default maximum segment size for TCP. * With an IP MSS of 576, this is 536, * but 512 is probably more convenient. * This should be defined as MIN(512, IP_MSS - sizeof (struct tcpiphdr)). */ #ifndef TCP_MSS #define TCP_MSS 512 #endif #ifndef TCP_MAXWIN #define TCP_MAXWIN 65535 /* largest value for (unscaled) window */ #endif #ifndef TCP_MAX_WINSHIFT #define TCP_MAX_WINSHIFT 14 /* maximum window shift */ #endif /* * User-settable options (used with setsockopt). */ #ifndef TCP_NODELAY #define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */ #endif #ifndef TCP_MAXSEG #define TCP_MAXSEG 0x02 /* set maximum segment size */ #endif #define SOL_TCP 6 /* TCP level */ #define L2TP_PORT 1701 #define DHCP_CLIENT_PORT 68 #define DHCP_SERVER_PORT 67 #ifndef NO_NON_ETHER_DECODER /* Start Token Ring */ #define TR_ALEN 6 /* octets in an Ethernet header */ #define IPARP_SAP 0xaa #define AC 0x10 #define LLC_FRAME 0x40 #define TRMTU 2000 /* 2000 bytes */ #define TR_RII 0x80 #define TR_RCF_DIR_BIT 0x80 #define TR_RCF_LEN_MASK 0x1f00 #define TR_RCF_BROADCAST 0x8000 /* all-routes broadcast */ #define TR_RCF_LIMITED_BROADCAST 0xC000 /* single-route broadcast */ #define TR_RCF_FRAME2K 0x20 #define TR_RCF_BROADCAST_MASK 0xC000 /* End Token Ring */ /* Start FDDI */ #define FDDI_ALLC_LEN 13 #define FDDI_ALEN 6 #define FDDI_MIN_HLEN (FDDI_ALLC_LEN + 3) #define FDDI_DSAP_SNA 0x08 /* SNA */ #define FDDI_SSAP_SNA 0x00 /* SNA */ #define FDDI_DSAP_STP 0x42 /* Spanning Tree Protocol */ #define FDDI_SSAP_STP 0x42 /* Spanning Tree Protocol */ #define FDDI_DSAP_IP 0xaa /* IP */ #define FDDI_SSAP_IP 0xaa /* IP */ #define FDDI_ORG_CODE_ETHR 0x000000 /* Encapsulated Ethernet */ #define FDDI_ORG_CODE_CDP 0x00000c /* Cisco Discovery * Proto(?) */ #define ETHERNET_TYPE_CDP 0x2000 /* Cisco Discovery Protocol */ /* End FDDI */ #endif // NO_NON_ETHER_DECODER #define ARPOP_REQUEST 1 /* ARP request */ #define ARPOP_REPLY 2 /* ARP reply */ #define ARPOP_RREQUEST 3 /* RARP request */ #define ARPOP_RREPLY 4 /* RARP reply */ /* PPPoE types */ #define PPPoE_CODE_SESS 0x00 /* PPPoE session */ #define PPPoE_CODE_PADI 0x09 /* PPPoE Active Discovery Initiation */ #define PPPoE_CODE_PADO 0x07 /* PPPoE Active Discovery Offer */ #define PPPoE_CODE_PADR 0x19 /* PPPoE Active Discovery Request */ #define PPPoE_CODE_PADS 0x65 /* PPPoE Active Discovery Session-confirmation */ #define PPPoE_CODE_PADT 0xa7 /* PPPoE Active Discovery Terminate */ /* PPPoE tag types */ #define PPPoE_TAG_END_OF_LIST 0x0000 #define PPPoE_TAG_SERVICE_NAME 0x0101 #define PPPoE_TAG_AC_NAME 0x0102 #define PPPoE_TAG_HOST_UNIQ 0x0103 #define PPPoE_TAG_AC_COOKIE 0x0104 #define PPPoE_TAG_VENDOR_SPECIFIC 0x0105 #define PPPoE_TAG_RELAY_SESSION_ID 0x0110 #define PPPoE_TAG_SERVICE_NAME_ERROR 0x0201 #define PPPoE_TAG_AC_SYSTEM_ERROR 0x0202 #define PPPoE_TAG_GENERIC_ERROR 0x0203 #define ICMP_ECHOREPLY 0 /* Echo Reply */ #define ICMP_DEST_UNREACH 3 /* Destination Unreachable */ #define ICMP_SOURCE_QUENCH 4 /* Source Quench */ #define ICMP_REDIRECT 5 /* Redirect (change route) */ #define ICMP_ECHO 8 /* Echo Request */ #define ICMP_ROUTER_ADVERTISE 9 /* Router Advertisement */ #define ICMP_ROUTER_SOLICIT 10 /* Router Solicitation */ #define ICMP_TIME_EXCEEDED 11 /* Time Exceeded */ #define ICMP_PARAMETERPROB 12 /* Parameter Problem */ #define ICMP_TIMESTAMP 13 /* Timestamp Request */ #define ICMP_TIMESTAMPREPLY 14 /* Timestamp Reply */ #define ICMP_INFO_REQUEST 15 /* Information Request */ #define ICMP_INFO_REPLY 16 /* Information Reply */ #define ICMP_ADDRESS 17 /* Address Mask Request */ #define ICMP_ADDRESSREPLY 18 /* Address Mask Reply */ #define NR_ICMP_TYPES 18 /* Codes for ICMP UNREACHABLES */ #define ICMP_NET_UNREACH 0 /* Network Unreachable */ #define ICMP_HOST_UNREACH 1 /* Host Unreachable */ #define ICMP_PROT_UNREACH 2 /* Protocol Unreachable */ #define ICMP_PORT_UNREACH 3 /* Port Unreachable */ #define ICMP_FRAG_NEEDED 4 /* Fragmentation Needed/DF set */ #define ICMP_SR_FAILED 5 /* Source Route failed */ #define ICMP_NET_UNKNOWN 6 #define ICMP_HOST_UNKNOWN 7 #define ICMP_HOST_ISOLATED 8 #define ICMP_PKT_FILTERED_NET 9 #define ICMP_PKT_FILTERED_HOST 10 #define ICMP_NET_UNR_TOS 11 #define ICMP_HOST_UNR_TOS 12 #define ICMP_PKT_FILTERED 13 /* Packet filtered */ #define ICMP_PREC_VIOLATION 14 /* Precedence violation */ #define ICMP_PREC_CUTOFF 15 /* Precedence cut off */ #define NR_ICMP_UNREACH 15 /* instead of hardcoding immediate * value */ #define ICMP_REDIR_NET 0 #define ICMP_REDIR_HOST 1 #define ICMP_REDIR_TOS_NET 2 #define ICMP_REDIR_TOS_HOST 3 #define ICMP_TIMEOUT_TRANSIT 0 #define ICMP_TIMEOUT_REASSY 1 #define ICMP_PARAM_BADIPHDR 0 #define ICMP_PARAM_OPTMISSING 1 #define ICMP_PARAM_BAD_LENGTH 2 /* ip option type codes */ #ifndef IPOPT_EOL #define IPOPT_EOL 0x00 #endif #ifndef IPOPT_NOP #define IPOPT_NOP 0x01 #endif #ifndef IPOPT_RR #define IPOPT_RR 0x07 #endif #ifndef IPOPT_RTRALT #define IPOPT_RTRALT 0x94 #endif #ifndef IPOPT_TS #define IPOPT_TS 0x44 #endif #ifndef IPOPT_SECURITY #define IPOPT_SECURITY 0x82 #endif #ifndef IPOPT_LSRR #define IPOPT_LSRR 0x83 #endif #ifndef IPOPT_LSRR_E #define IPOPT_LSRR_E 0x84 #endif #ifndef IPOPT_ESEC #define IPOPT_ESEC 0x85 #endif #ifndef IPOPT_SATID #define IPOPT_SATID 0x88 #endif #ifndef IPOPT_SSRR #define IPOPT_SSRR 0x89 #endif /* tcp option codes */ #define TOPT_EOL 0x00 #define TOPT_NOP 0x01 #define TOPT_MSS 0x02 #define TOPT_WS 0x03 #define TOPT_TS 0x08 #ifndef TCPOPT_WSCALE #define TCPOPT_WSCALE 3 /* window scale factor (rfc1072) */ #endif #ifndef TCPOPT_SACKOK #define TCPOPT_SACKOK 4 /* selective ack ok (rfc1072) */ #endif #ifndef TCPOPT_SACK #define TCPOPT_SACK 5 /* selective ack (rfc1072) */ #endif #ifndef TCPOPT_ECHO #define TCPOPT_ECHO 6 /* echo (rfc1072) */ #endif #ifndef TCPOPT_ECHOREPLY #define TCPOPT_ECHOREPLY 7 /* echo (rfc1072) */ #endif #ifndef TCPOPT_TIMESTAMP #define TCPOPT_TIMESTAMP 8 /* timestamps (rfc1323) */ #endif #ifndef TCPOPT_CC #define TCPOPT_CC 11 /* T/TCP CC options (rfc1644) */ #endif #ifndef TCPOPT_CCNEW #define TCPOPT_CCNEW 12 /* T/TCP CC options (rfc1644) */ #endif #ifndef TCPOPT_CCECHO #define TCPOPT_CCECHO 13 /* T/TCP CC options (rfc1644) */ #endif #define EXTRACT_16BITS(p) ((u_short) ntohs (*(u_short *)(p))) #ifdef WORDS_MUSTALIGN #if defined(__GNUC__) /* force word-aligned ntohl parameter */ #define EXTRACT_32BITS(p) ({ uint32_t __tmp; memmove(&__tmp, (p), sizeof(uint32_t)); (uint32_t) ntohl(__tmp);}) #endif /* __GNUC__ */ #else /* allows unaligned ntohl parameter - dies w/SIGBUS on SPARCs */ #define EXTRACT_32BITS(p) ((uint32_t) ntohl (*(uint32_t *)(p))) #endif /* WORDS_MUSTALIGN */ /* packet status flags */ #define PKT_REBUILT_FRAG 0x00000001 /* is a rebuilt fragment */ #define PKT_REBUILT_STREAM 0x00000002 /* is a rebuilt stream */ #define PKT_STREAM_UNEST_UNI 0x00000004 /* is from an unestablished stream and * we've only seen traffic in one direction */ #define PKT_STREAM_EST 0x00000008 /* is from an established stream */ #define PKT_STREAM_INSERT 0x00000010 /* this packet has been queued for stream reassembly */ #define PKT_STREAM_TWH 0x00000020 /* packet completes the 3-way handshake */ #define PKT_FROM_SERVER 0x00000040 /* this packet came from the server side of a connection (TCP) */ #define PKT_FROM_CLIENT 0x00000080 /* this packet came from the client side of a connection (TCP) */ #define PKT_PDU_HEAD 0x00000100 /* start of PDU */ #define PKT_PDU_TAIL 0x00000200 /* end of PDU */ #define PKT_UNSURE_ENCAP 0x00000400 /* packet may have incorrect encapsulation layer. */ /* don't alert if "next layer" is invalid. */ #define PKT_HTTP_DECODE 0x00000800 /* this packet has normalized http */ #define PKT_IGNORE 0x00001000 /* this packet should be ignored, based on port */ #define PKT_TRUST 0x00002000 /* this packet should fallback to being whitelisted if no other verdict was specified */ #define PKT_ALLOW_MULTIPLE_DETECT 0x00004000 /* packet has either pipelined mime attachements */ /* or pipeline http requests */ #define PKT_PAYLOAD_OBFUSCATE 0x00008000 #define PKT_STATELESS 0x00010000 /* Packet has matched a stateless rule */ #define PKT_PASS_RULE 0x00020000 /* this packet has matched a pass rule */ #define PKT_IP_RULE 0x00040000 /* this packet is being evaluated against an IP rule */ #define PKT_IP_RULE_2ND 0x00080000 /* this packet is being evaluated against an IP rule */ #define PKT_LOGGED 0x00100000 /* this packet has been logged */ #define PKT_PSEUDO 0x00200000 /* is a pseudo packet */ #define PKT_MODIFIED 0x00400000 /* packet had normalizations, etc. */ #ifdef NORMALIZER #define PKT_RESIZED 0x00800000 /* packet has new size; must set modified too */ #endif // neither of these flags will be set for (full) retransmissions or non-data segments // a partial overlap results in out of sequence condition // out of sequence condition is sticky #define PKT_STREAM_ORDER_OK 0x01000000 /* this segment is in order, w/o gaps */ #define PKT_STREAM_ORDER_BAD 0x02000000 /* this stream had at least one gap */ #define PKT_REASSEMBLED_OLD 0x04000000 /* for backwards compat with so rules */ #define PKT_IPREP_SOURCE_TRIGGERED 0x08000000 #define PKT_IPREP_DATA_SET 0x10000000 #define PKT_FILE_EVENT_SET 0x20000000 #define PKT_EARLY_REASSEMBLY 0x40000000 /* this packet. part of the expected stream, should have stream reassembly set */ #define PKT_RETRANSMIT 0x80000000 /* this packet is identified as re-transmitted one */ #define PKT_PURGE 0x0100000000 /* Stream will not flush the data */ #define PKT_H1_ABORT 0x0200000000 /* Used by H1 and H2 paf */ #define PKT_UPGRADE_PROTO 0x0400000000 /* Used by H1 paf */ #define PKT_PDU_FULL (PKT_PDU_HEAD | PKT_PDU_TAIL) #define REASSEMBLED_PACKET_FLAGS (PKT_REBUILT_STREAM|PKT_REASSEMBLED_OLD) typedef enum { PSEUDO_PKT_IP, PSEUDO_PKT_TCP, PSEUDO_PKT_DCE_RPKT, PSEUDO_PKT_SMB_SEG, PSEUDO_PKT_DCE_SEG, PSEUDO_PKT_DCE_FRAG, PSEUDO_PKT_SMB_TRANS, PSEUDO_PKT_PS, PSEUDO_PKT_SDF, PSEUDO_PKT_MAX } PseudoPacketType; /* error flags */ #define PKT_ERR_CKSUM_IP 0x01 #define PKT_ERR_CKSUM_TCP 0x02 #define PKT_ERR_CKSUM_UDP 0x04 #define PKT_ERR_CKSUM_ICMP 0x08 #define PKT_ERR_CKSUM_IGMP 0x10 #define PKT_ERR_CKSUM_ANY 0x1F #define PKT_ERR_BAD_TTL 0x20 #define PKT_ERR_SYN_RL_DROP 0x40 /* D A T A S T R U C T U R E S *********************************************/ typedef int (*LogFunction)(void *ssnptr, uint8_t **buf, uint32_t *len, uint32_t *type); #ifndef NO_NON_ETHER_DECODER /* Start Token Ring Data Structures */ #ifdef _MSC_VER /* Visual C++ pragma to disable warning messages about nonstandard bit field type */ #pragma warning( disable : 4214 ) #endif /* LLC structure */ typedef struct _Trh_llc { uint8_t dsap; uint8_t ssap; uint8_t protid[3]; uint16_t ethertype; } Trh_llc; /* RIF structure * Linux/tcpdump patch defines tokenring header in dump way, since not * every tokenring header with have RIF data... we define it separately, and * a bit more split up */ #ifdef _MSC_VER /* Visual C++ pragma to disable warning messages about nonstandard bit field type */ #pragma warning( disable : 4214 ) #endif /* These are macros to use the bitlevel accesses in the Trh_Mr header they haven't been tested and they aren't used much so here is a listing of what used to be there #if defined(WORDS_BIGENDIAN) uint16_t bcast:3, len:5, dir:1, lf:3, res:4; #else uint16_t len:5, length of RIF field, including RC itself bcast:3, broadcast indicator res:4, reserved lf:3, largest frame size dir:1; direction */ #define TRH_MR_BCAST(trhmr) ((ntohs((trhmr)->bcast_len_dir_lf_res) & 0xe000) >> 13) #define TRH_MR_LEN(trhmr) ((ntohs((trhmr)->bcast_len_dir_lf_res) & 0x1F00) >> 8) #define TRH_MR_DIR(trhmr) ((ntohs((trhmr)->bcast_len_dir_lf_res) & 0x0080) >> 7) #define TRH_MR_LF(trhmr) ((ntohs((trhmr)->bcast_len_dir_lf_res) & 0x0070) >> 4) #define TRH_MR_RES(trhmr) ((ntohs((trhmr)->bcast_len_dir_lf_res) & 0x000F)) typedef struct _Trh_mr { uint16_t bcast_len_dir_lf_res; /* broadcast/res/framesize/direction */ uint16_t rseg[8]; } Trh_mr; #ifdef _MSC_VER /* Visual C++ pragma to enable warning messages about nonstandard bit field type */ #pragma warning( default : 4214 ) #endif typedef struct _Trh_hdr { uint8_t ac; /* access control field */ uint8_t fc; /* frame control field */ uint8_t daddr[TR_ALEN]; /* src address */ uint8_t saddr[TR_ALEN]; /* dst address */ } Trh_hdr; #ifdef WIN32 /* Visual C++ pragma to enable warning messages about nonstandard bit field type */ #pragma warning( default : 4214 ) #endif /* End Token Ring Data Structures */ /* Start FDDI Data Structures */ /* FDDI header is always this: -worm5er */ typedef struct _Fddi_hdr { uint8_t fc; /* frame control field */ uint8_t daddr[FDDI_ALEN]; /* src address */ uint8_t saddr[FDDI_ALEN]; /* dst address */ } Fddi_hdr; /* splitting the llc up because of variable lengths of the LLC -worm5er */ typedef struct _Fddi_llc_saps { uint8_t dsap; uint8_t ssap; } Fddi_llc_saps; /* I've found sna frames have two addition bytes after the llc saps -worm5er */ typedef struct _Fddi_llc_sna { uint8_t ctrl_fld[2]; } Fddi_llc_sna; /* I've also found other frames that seem to have only one byte... We're only really intersted in the IP data so, until we want other, I'm going to say the data is one byte beyond this frame... -worm5er */ typedef struct _Fddi_llc_other { uint8_t ctrl_fld[1]; } Fddi_llc_other; /* Just like TR the ip/arp data is setup as such: -worm5er */ typedef struct _Fddi_llc_iparp { uint8_t ctrl_fld; uint8_t protid[3]; uint16_t ethertype; } Fddi_llc_iparp; /* End FDDI Data Structures */ /* 'Linux cooked captures' data * (taken from tcpdump source). */ #define SLL_HDR_LEN 16 /* total header length */ #define SLL_ADDRLEN 8 /* length of address field */ typedef struct _SLLHdr { uint16_t sll_pkttype; /* packet type */ uint16_t sll_hatype; /* link-layer address type */ uint16_t sll_halen; /* link-layer address length */ uint8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */ uint16_t sll_protocol; /* protocol */ } SLLHdr; /* * Snort supports 3 versions of the OpenBSD pflog header: * * Pflog1_Hdr: CVS = 1.3, DLT_OLD_PFLOG = 17, Length = 28 * Pflog2_Hdr: CVS = 1.8, DLT_PFLOG = 117, Length = 48 * Pflog3_Hdr: CVS = 1.12, DLT_PFLOG = 117, Length = 64 * Pflog3_Hdr: CVS = 1.172, DLT_PFLOG = 117, Length = 100 * * Since they have the same DLT, Pflog{2,3}Hdr are distinguished * by their actual length. The minimum required length excludes * padding. */ /* Old OpenBSD pf firewall pflog0 header * (information from pf source in kernel) * the rule, reason, and action codes tell why the firewall dropped it -fleck */ typedef struct _Pflog1_hdr { uint32_t af; char intf[IFNAMSIZ]; int16_t rule; uint16_t reason; uint16_t action; uint16_t dir; } Pflog1Hdr; #define PFLOG1_HDRLEN (sizeof(struct _Pflog1_hdr)) /* * Note that on OpenBSD, af type is sa_family_t. On linux, that's an unsigned * short, but on OpenBSD, that's a uint8_t, so we should explicitly use uint8_t * here. - ronaldo */ #define PFLOG_RULELEN 16 #define PFLOG_PADLEN 3 typedef struct _Pflog2_hdr { int8_t length; uint8_t af; uint8_t action; uint8_t reason; char ifname[IFNAMSIZ]; char ruleset[PFLOG_RULELEN]; uint32_t rulenr; uint32_t subrulenr; uint8_t dir; uint8_t pad[PFLOG_PADLEN]; } Pflog2Hdr; #define PFLOG2_HDRLEN (sizeof(struct _Pflog2_hdr)) #define PFLOG2_HDRMIN (PFLOG2_HDRLEN - PFLOG_PADLEN) typedef struct _Pflog3_hdr { int8_t length; uint8_t af; uint8_t action; uint8_t reason; char ifname[IFNAMSIZ]; char ruleset[PFLOG_RULELEN]; uint32_t rulenr; uint32_t subrulenr; uint32_t uid; uint32_t pid; uint32_t rule_uid; uint32_t rule_pid; uint8_t dir; uint8_t pad[PFLOG_PADLEN]; } Pflog3Hdr; #define PFLOG3_HDRLEN (sizeof(struct _Pflog3_hdr)) #define PFLOG3_HDRMIN (PFLOG3_HDRLEN - PFLOG_PADLEN) typedef struct _Pflog4_hdr { uint8_t length; uint8_t af; uint8_t action; uint8_t reason; char ifname[IFNAMSIZ]; char ruleset[PFLOG_RULELEN]; uint32_t rulenr; uint32_t subrulenr; uint32_t uid; uint32_t pid; uint32_t rule_uid; uint32_t rule_pid; uint8_t dir; uint8_t rewritten; uint8_t pad[2]; uint8_t saddr[16]; uint8_t daddr[16]; uint16_t sport; uint16_t dport; } Pflog4Hdr; #define PFLOG4_HDRLEN sizeof(struct _Pflog4_hdr) #define PFLOG4_HDRMIN sizeof(struct _Pflog4_hdr) /* * ssl_pkttype values. */ #define LINUX_SLL_HOST 0 #define LINUX_SLL_BROADCAST 1 #define LINUX_SLL_MULTICAST 2 #define LINUX_SLL_OTHERHOST 3 #define LINUX_SLL_OUTGOING 4 /* ssl protocol values */ #define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */ #define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */ #endif // NO_NON_ETHER_DECODER #ifdef _MSC_VER /* Visual C++ pragma to disable warning messages * about nonstandard bit field type */ #pragma warning( disable : 4214 ) #endif #define VTH_PRIORITY(vh) ((ntohs((vh)->vth_pri_cfi_vlan) & 0xe000) >> 13) #define VTH_CFI(vh) ((ntohs((vh)->vth_pri_cfi_vlan) & 0x1000) >> 12) #define VTH_VLAN(vh) ((uint16_t)(ntohs((vh)->vth_pri_cfi_vlan) & 0x0FFF)) typedef struct _VlanTagHdr { uint16_t vth_pri_cfi_vlan; uint16_t vth_proto; /* protocol field... */ } VlanTagHdr; #ifdef _MSC_VER /* Visual C++ pragma to enable warning messages about nonstandard bit field type */ #pragma warning( default : 4214 ) #endif typedef struct _EthLlc { uint8_t dsap; uint8_t ssap; } EthLlc; typedef struct _EthLlcOther { uint8_t ctrl; uint8_t org_code[3]; uint16_t proto_id; } EthLlcOther; /* We must twiddle to align the offset the ethernet header and align * the IP header on solaris -- maybe this will work on HPUX too. */ #if defined (SOLARIS) || defined (SUNOS) || defined (__sparc__) || defined(__sparc64__) || defined (HPUX) #define SPARC_TWIDDLE 2 #else #define SPARC_TWIDDLE 0 #endif /* * Cisco FabricPath / Data Center Ethernet header */ typedef struct _FPathHdr { uint8_t fpath_dst[6]; uint8_t fpath_src[6]; uint16_t fpath_type; uint16_t fptag_extra; /* 10-bit FTag + 6-bit TTL */ } FPathHdr; typedef struct _CiscoMetaHdr { uint8_t version; // This must be 1 uint8_t length; //This is the header size in bytes / 8 } CiscoMetaHdr; /* * Cisco MetaData header options */ typedef struct _CiscoMetaOpt { uint16_t opt_len_type; /* 3-bit length + 13-bit type. Length of 0 = 4. Type must be 1. */ uint16_t sgt; /* Can be any value except 0xFFFF */ } CiscoMetaOpt; /* * Ethernet header */ typedef struct _EtherHdr { uint8_t ether_dst[6]; uint8_t ether_src[6]; uint16_t ether_type; } EtherHdr; #ifndef NO_NON_ETHER_DECODER /* * Wireless Header (IEEE 802.11) */ typedef struct _WifiHdr { uint16_t frame_control; uint16_t duration_id; uint8_t addr1[6]; uint8_t addr2[6]; uint8_t addr3[6]; uint16_t seq_control; uint8_t addr4[6]; } WifiHdr; #endif // NO_NON_ETHER_DECODER /* Can't add any fields not in the real header here because of how the decoder uses structure overlaying */ #ifdef _MSC_VER /* Visual C++ pragma to disable warning messages * about nonstandard bit field type */ #pragma warning( disable : 4214 ) #endif /* tcpdump shows us the way to cross platform compatibility */ #define IP_VER(iph) (((iph)->ip_verhl & 0xf0) >> 4) #define IP_HLEN(iph) ((iph)->ip_verhl & 0x0f) /* we need to change them as well as get them */ #define SET_IP_VER(iph, value) ((iph)->ip_verhl = (unsigned char)(((iph)->ip_verhl & 0x0f) | (value << 4))) #define SET_IP_HLEN(iph, value) ((iph)->ip_verhl = (unsigned char)(((iph)->ip_verhl & 0xf0) | (value & 0x0f))) #define NUM_IP_PROTOS 256 /* Last updated 6/2/2010. Source: http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xml */ #define MIN_UNASSIGNED_IP_PROTO 143 #ifndef IPPROTO_SWIPE #define IPPROTO_SWIPE 53 #endif #ifndef IPPROTO_IP_MOBILITY #define IPPROTO_IP_MOBILITY 55 #endif #ifndef IPPROTO_SUN_ND #define IPPROTO_SUN_ND 77 #endif #ifndef IPPROTO_PIM #define IPPROTO_PIM 103 #endif #ifndef IPPROTO_PGM #define IPPROTO_PGM 113 #endif typedef struct _IPHdr { uint8_t ip_verhl; /* version & header length */ uint8_t ip_tos; /* type of service */ uint16_t ip_len; /* datagram length */ uint16_t ip_id; /* identification */ uint16_t ip_off; /* fragment offset */ uint8_t ip_ttl; /* time to live field */ uint8_t ip_proto; /* datagram protocol */ uint16_t ip_csum; /* checksum */ struct in_addr ip_src; /* source IP */ struct in_addr ip_dst; /* dest IP */ } IPHdr; typedef struct _IPAddresses { sfaddr_t ip_src; /* source IP */ sfaddr_t ip_dst; /* dest IP */ } IPAddresses; typedef struct _IPv4Hdr { uint8_t ip_verhl; /* version & header length */ uint8_t ip_tos; /* type of service */ uint16_t ip_len; /* datagram length */ uint16_t ip_id; /* identification */ uint16_t ip_off; /* fragment offset */ uint8_t ip_ttl; /* time to live field */ uint8_t ip_proto; /* datagram protocol */ uint16_t ip_csum; /* checksum */ IPAddresses* ip_addrs; /* IP addresses*/ } IP4Hdr; typedef struct _IPv6Hdr { uint32_t vcl; /* version, class, and label */ uint16_t len; /* length of the payload */ uint8_t next; /* next header * Uses the same flags as * the IPv4 protocol field */ uint8_t hop_lmt; /* hop limit */ IPAddresses* ip_addrs; /* IP addresses*/ } IP6Hdr; /* IPv6 address */ #ifndef s6_addr struct in6_addr { union { uint8_t u6_addr8[16]; uint16_t u6_addr16[8]; uint32_t u6_addr32[4]; } in6_u; #define s6_addr in6_u.u6_addr8 #define s6_addr16 in6_u.u6_addr16 #define s6_addr32 in6_u.u6_addr32 }; #endif typedef struct _IP6RawHdr { uint32_t ip6_vtf; /* 4 bits version, 8 bits TC, 20 bits flow-ID */ uint16_t ip6_payload_len; /* payload length */ uint8_t ip6_next; /* next header */ uint8_t ip6_hoplim; /* hop limit */ struct in6_addr ip6_src; /* source address */ struct in6_addr ip6_dst; /* destination address */ } IP6RawHdr; #define ip6flow ip6_vtf #define ip6plen ip6_payload_len #define ip6nxt ip6_next #define ip6hlim ip6_hoplim #define ip6hops ip6_hoplim #define IPRAW_HDR_VER(p_rawiph) \ (ntohl(p_rawiph->ip6_vtf) >> 28) #define IP6_HDR_LEN 40 #ifndef IP_PROTO_HOPOPTS # define IP_PROTO_HOPOPTS 0 #endif #define IP_PROTO_NONE 59 #define IP_PROTO_ROUTING 43 #define IP_PROTO_FRAGMENT 44 #define IP_PROTO_AH 51 #define IP_PROTO_DSTOPTS 60 #define IP_PROTO_ICMPV6 58 #define IP_PROTO_IPV6 41 #define IP_PROTO_IPIP 4 #define IP6F_OFFSET_MASK 0xfff8 /* mask out offset from _offlg */ #define IP6F_MF_MASK 0x0001 /* more-fragments flag */ #define IP6F_OFFSET(fh) ((ntohs((fh)->ip6f_offlg) & IP6F_OFFSET_MASK) >> 3) #define IP6F_RES(fh) (fh)->ip6f_reserved #define IP6F_MF(fh) (ntohs((fh)->ip6f_offlg) & IP6F_MF_MASK ) /* to store references to IP6 Extension Headers */ typedef struct _IP6Option { uint8_t type; const uint8_t *data; } IP6Option; /* Generic Extension Header */ typedef struct _IP6Extension { uint8_t ip6e_nxt; uint8_t ip6e_len; /* options follow */ uint8_t ip6e_pad[6]; } IP6Extension; typedef struct _IP6HopByHop { uint8_t ip6hbh_nxt; uint8_t ip6hbh_len; /* options follow */ uint8_t ip6hbh_pad[6]; } IP6HopByHop; typedef struct _IP6Dest { uint8_t ip6dest_nxt; uint8_t ip6dest_len; /* options follow */ uint8_t ip6dest_pad[6]; } IP6Dest; typedef struct _IP6Route { uint8_t ip6rte_nxt; uint8_t ip6rte_len; uint8_t ip6rte_type; uint8_t ip6rte_seg_left; /* type specific data follows */ } IP6Route; typedef struct _IP6Route0 { uint8_t ip6rte0_nxt; uint8_t ip6rte0_len; uint8_t ip6rte0_type; uint8_t ip6rte0_seg_left; uint8_t ip6rte0_reserved; uint8_t ip6rte0_bitmap[3]; struct in6_addr ip6rte0_addr[1]; /* Up to 23 IP6 addresses */ } IP6Route0; /* Fragment header */ typedef struct _IP6Frag { uint8_t ip6f_nxt; /* next header */ uint8_t ip6f_reserved; /* reserved field */ uint16_t ip6f_offlg; /* offset, reserved, and flag */ uint32_t ip6f_ident; /* identification */ } IP6Frag; typedef struct _ICMP6 { uint8_t type; uint8_t code; uint16_t csum; } ICMP6Hdr; typedef struct _ICMP6TooBig { uint8_t type; uint8_t code; uint16_t csum; uint32_t mtu; } ICMP6TooBig; typedef struct _ICMP6RouterAdvertisement { uint8_t type; uint8_t code; uint16_t csum; uint8_t num_addrs; uint8_t addr_entry_size; uint16_t lifetime; uint32_t reachable_time; uint32_t retrans_time; } ICMP6RouterAdvertisement; typedef struct _ICMP6RouterSolicitation { uint8_t type; uint8_t code; uint16_t csum; uint32_t reserved; } ICMP6RouterSolicitation; typedef struct _ICMP6NodeInfo { uint8_t type; uint8_t code; uint16_t csum; uint16_t qtype; uint16_t flags; uint64_t nonce; } ICMP6NodeInfo; #define ICMP6_UNREACH 1 #define ICMP6_BIG 2 #define ICMP6_TIME 3 #define ICMP6_PARAMS 4 #define ICMP6_ECHO 128 #define ICMP6_REPLY 129 #define ICMP6_SOLICITATION 133 #define ICMP6_ADVERTISEMENT 134 #define ICMP6_NODE_INFO_QUERY 139 #define ICMP6_NODE_INFO_RESPONSE 140 /* Minus 1 due to the 'body' field */ #define ICMP6_MIN_HEADER_LEN (sizeof(ICMP6Hdr) ) #ifdef _MSC_VER /* Visual C++ pragma to enable warning messages about nonstandard bit field type */ #pragma warning( default : 4214 ) #endif /* Can't add any fields not in the real header here because of how the decoder uses structure overlaying */ #ifdef _MSC_VER /* Visual C++ pragma to disable warning * messages about nonstandard bit field type */ #pragma warning( disable : 4214 ) #endif #ifndef IPPROTO_IPIP #define IPPROTO_IPIP 4 #endif /* GRE related stuff */ typedef struct _GREHdr { uint8_t flags; uint8_t version; uint16_t ether_type; } GREHdr; #ifdef GRE #ifndef IPPROTO_GRE #define IPPROTO_GRE 47 #endif #define GRE_TYPE_TRANS_BRIDGING 0x6558 #define GRE_TYPE_PPP 0x880B #define GRE_HEADER_LEN 4 #define GRE_CHKSUM_LEN 2 #define GRE_OFFSET_LEN 2 #define GRE_KEY_LEN 4 #define GRE_SEQ_LEN 4 #define GRE_SRE_HEADER_LEN 4 #define GRE_CHKSUM(x) (x->flags & 0x80) #define GRE_ROUTE(x) (x->flags & 0x40) #define GRE_KEY(x) (x->flags & 0x20) #define GRE_SEQ(x) (x->flags & 0x10) #define GRE_SSR(x) (x->flags & 0x08) #define GRE_RECUR(x) (x->flags & 0x07) #define GRE_VERSION(x) (x->version & 0x07) #define GRE_FLAGS(x) (x->version & 0xF8) #define GRE_PROTO(x) ntohs(x->ether_type) /* GRE version 1 used with PPTP */ #define GRE_V1_HEADER_LEN 8 #define GRE_V1_ACK_LEN 4 #define GRE_V1_FLAGS(x) (x->version & 0x78) #define GRE_V1_ACK(x) (x->version & 0x80) typedef struct _ERSpanType2Hdr { uint16_t ver_vlan; uint16_t flags_spanId; uint32_t pad; } ERSpanType2Hdr; typedef struct _ERSpanType3Hdr { uint16_t ver_vlan; uint16_t flags_spanId; uint32_t timestamp; uint16_t pad0; uint16_t pad1; uint32_t pad2; uint32_t pad3; } ERSpanType3Hdr; #define ERSPAN_VERSION(x) ((ntohs(x->ver_vlan) & 0xf000) >> 12) #define ERSPAN_VLAN(x) (ntohs(x->ver_vlan) & 0x0fff) #define ERSPAN_SPAN_ID(x) (ntohs(x->flags_spanId) & 0x03ff) #define ERSPAN3_TIMESTAMP(x) (x->timestamp) #endif /* GRE */ /* more macros for TCP offset */ #define TCP_OFFSET(tcph) (((tcph)->th_offx2 & 0xf0) >> 4) #define TCP_X2(tcph) ((tcph)->th_offx2 & 0x0f) #define TCP_ISFLAGSET(tcph, flags) (((tcph)->th_flags & (flags)) == (flags)) /* we need to change them as well as get them */ #define SET_TCP_OFFSET(tcph, value) ((tcph)->th_offx2 = (unsigned char)(((tcph)->th_offx2 & 0x0f) | (value << 4))) #define SET_TCP_X2(tcph, value) ((tcph)->th_offx2 = (unsigned char)(((tcph)->th_offx2 & 0xf0) | (value & 0x0f))) typedef struct _TCPHdr { uint16_t th_sport; /* source port */ uint16_t th_dport; /* destination port */ uint32_t th_seq; /* sequence number */ uint32_t th_ack; /* acknowledgement number */ uint8_t th_offx2; /* offset and reserved */ uint8_t th_flags; uint16_t th_win; /* window */ uint16_t th_sum; /* checksum */ uint16_t th_urp; /* urgent pointer */ } TCPHdr; #ifdef _MSC_VER /* Visual C++ pragma to enable warning messages * about nonstandard bit field type */ #pragma warning( default : 4214 ) #endif typedef struct _UDPHdr { uint16_t uh_sport; uint16_t uh_dport; uint16_t uh_len; uint16_t uh_chk; } UDPHdr; typedef struct _ICMPHdr { uint8_t type; uint8_t code; uint16_t csum; union { struct { uint8_t pptr; uint8_t pres1; uint16_t pres2; } param; struct in_addr gwaddr; struct idseq { uint16_t id; uint16_t seq; } idseq; uint32_t sih_void; struct pmtu { uint16_t ipm_void; uint16_t nextmtu; } pmtu; struct rtradv { uint8_t num_addrs; uint8_t wpa; uint16_t lifetime; } rtradv; } icmp_hun; #define s_icmp_pptr icmp_hun.param.pptr #define s_icmp_gwaddr icmp_hun.gwaddr #define s_icmp_id icmp_hun.idseq.id #define s_icmp_seq icmp_hun.idseq.seq #define s_icmp_void icmp_hun.sih_void #define s_icmp_pmvoid icmp_hun.pmtu.ipm_void #define s_icmp_nextmtu icmp_hun.pmtu.nextmtu #define s_icmp_num_addrs icmp_hun.rtradv.num_addrs #define s_icmp_wpa icmp_hun.rtradv.wpa #define s_icmp_lifetime icmp_hun.rtradv.lifetime union { /* timestamp */ struct ts { uint32_t otime; uint32_t rtime; uint32_t ttime; } ts; /* IP header for unreach */ struct ih_ip { IPHdr *ip; /* options and then 64 bits of data */ } ip; struct ra_addr { uint32_t addr; uint32_t preference; } radv; uint32_t mask; char data[1]; } icmp_dun; #define s_icmp_otime icmp_dun.ts.otime #define s_icmp_rtime icmp_dun.ts.rtime #define s_icmp_ttime icmp_dun.ts.ttime #define s_icmp_ip icmp_dun.ih_ip #define s_icmp_radv icmp_dun.radv #define s_icmp_mask icmp_dun.mask #define s_icmp_data icmp_dun.data } ICMPHdr; typedef struct _ARPHdr { uint16_t ar_hrd; /* format of hardware address */ uint16_t ar_pro; /* format of protocol address */ uint8_t ar_hln; /* length of hardware address */ uint8_t ar_pln; /* length of protocol address */ uint16_t ar_op; /* ARP opcode (command) */ } ARPHdr; typedef struct _EtherARP { ARPHdr ea_hdr; /* fixed-size header */ uint8_t arp_sha[6]; /* sender hardware address */ uint8_t arp_spa[4]; /* sender protocol address */ uint8_t arp_tha[6]; /* target hardware address */ uint8_t arp_tpa[4]; /* target protocol address */ } EtherARP; #ifndef NO_NON_ETHER_DECODER typedef struct _EtherEapol { uint8_t version; /* EAPOL proto version */ uint8_t eaptype; /* EAPOL Packet type */ uint16_t len; /* Packet body length */ } EtherEapol; typedef struct _EAPHdr { uint8_t code; uint8_t id; uint16_t len; } EAPHdr; typedef struct _EapolKey { uint8_t type; uint8_t length[2]; uint8_t counter[8]; uint8_t iv[16]; uint8_t index; uint8_t sig[16]; } EapolKey; #endif // NO_NON_ETHER_DECODER typedef struct _Options { uint8_t code; uint8_t len; /* length of the data section */ const uint8_t *data; } Options; /* PPPoEHdr Header; EtherHdr plus the PPPoE Header */ typedef struct _PPPoEHdr { unsigned char ver_type; /* pppoe version/type */ unsigned char code; /* pppoe code CODE_* */ unsigned short session; /* session id */ unsigned short length; /* payload length */ /* payload follows */ } PPPoEHdr; /* PPPoE tag; the payload is a sequence of these */ typedef struct _PPPoE_Tag { unsigned short type; /* tag type TAG_* */ unsigned short length; /* tag length */ /* payload follows */ } PPPoE_Tag; #define MPLS_HEADER_LEN 4 #define NUM_RESERVED_LABELS 16 #ifdef MPLS_RFC4023_SUPPORT #define IPPROTO_MPLS 137 #endif typedef struct _MplsHdr { uint32_t label; uint8_t exp; uint8_t bos; uint8_t ttl; } MplsHdr; typedef struct _H2PriSpec { uint32_t stream_id; uint32_t weight; uint8_t exclusive; } H2PriSpec; typedef struct _H2Hdr { uint32_t length; uint32_t stream_id; uint8_t type; uint8_t flags; uint8_t reserved; H2PriSpec pri; } H2Hdr; #define PGM_NAK_ERR -1 #define PGM_NAK_OK 0 #define PGM_NAK_VULN 1 typedef struct _PGM_NAK_OPT { uint8_t type; /* 02 = vuln */ uint8_t len; uint8_t res[2]; uint32_t seq[1]; /* could be many many more, but 1 is sufficient */ } PGM_NAK_OPT; typedef struct _PGM_NAK { uint32_t seqnum; uint16_t afil1; uint16_t res1; uint32_t src; uint16_t afi2; uint16_t res2; uint32_t multi; PGM_NAK_OPT opt; } PGM_NAK; typedef struct _PGM_HEADER { uint16_t srcport; uint16_t dstport; uint8_t type; uint8_t opt; uint16_t checksum; uint8_t gsd[6]; uint16_t length; PGM_NAK nak; } PGM_HEADER; /* GTP basic Header */ typedef struct _GTPHdr { uint8_t flag; /* flag: version (bit 6-8), PT (5), E (3), S (2), PN (1) */ uint8_t type; /* message type */ uint16_t length; /* length */ } GTPHdr; #define LAYER_MAX 32 // forward declaration for snort expected session created due to this packet. struct _ExpectNode; // REMEMBER match any changes you make here in: // dynamic-plugins/sf_engine/sf_snort_packet.h typedef struct _Packet { const DAQ_PktHdr_t *pkth; // packet meta data const uint8_t *pkt; // raw packet data //vvv------------------------------------------------ // TODO convenience stuff to be refactored for layers //^^^------------------------------------------------ //vvv----------------------------- EtherARP *ah; const EtherHdr *eh; /* standard TCP/IP/Ethernet/ARP headers */ const VlanTagHdr *vh; EthLlc *ehllc; EthLlcOther *ehllcother; const PPPoEHdr *pppoeh; /* Encapsulated PPP of Ether header */ const GREHdr *greh; uint32_t *mpls; const CiscoMetaHdr *cmdh; /* Cisco Metadata Header */ const IPHdr *iph, *orig_iph;/* and orig. headers for ICMP_*_UNREACH family */ const IPHdr *inner_iph; /* if IP-in-IP, this will be the inner IP header */ const IPHdr *outer_iph; /* if IP-in-IP, this will be the outer IP header */ const TCPHdr *tcph, *orig_tcph; const UDPHdr *udph, *orig_udph; const UDPHdr *inner_udph; /* if Teredo + UDP, this will be the inner UDP header */ const UDPHdr *outer_udph; /* if Teredo + UDP, this will be the outer UDP header */ const ICMPHdr *icmph, *orig_icmph; const uint8_t *data; /* packet payload pointer */ const uint8_t *ip_data; /* IP payload pointer */ const uint8_t *outer_ip_data; /* Outer IP payload pointer */ //^^^----------------------------- void *ssnptr; /* for tcp session tracking info... */ void *fragtracker; /* for ip fragmentation tracking info... */ //vvv----------------------------- IP4Hdr *ip4h, *orig_ip4h; IP6Hdr *ip6h, *orig_ip6h; ICMP6Hdr *icmp6h, *orig_icmp6h; IPH_API* iph_api; IPH_API* orig_iph_api; IPH_API* outer_iph_api; IPH_API* outer_orig_iph_api; int family; int orig_family; int outer_family; //^^^----------------------------- PreprocEnableMask preprocessor_bits; /* flags for preprocessors to check */ uint64_t packet_flags; /* special flags for the packet */ uint32_t xtradata_mask; uint16_t proto_bits; //vvv----------------------------- uint16_t dsize; /* packet payload size */ uint16_t ip_dsize; /* IP payload size */ uint16_t alt_dsize; /* the dsize of a packet before munging (used for log)*/ uint16_t actual_ip_len; /* for logging truncated pkts (usually by small snaplen)*/ uint16_t outer_ip_dsize; /* Outer IP payload size */ //^^^----------------------------- uint16_t frag_offset; /* fragment offset number */ uint16_t ip_frag_len; uint16_t ip_options_len; uint16_t tcp_options_len; //vvv----------------------------- uint16_t sp; /* source port (TCP/UDP) */ uint16_t dp; /* dest port (TCP/UDP) */ uint16_t orig_sp; /* source port (TCP/UDP) of original datagram */ uint16_t orig_dp; /* dest port (TCP/UDP) of original datagram */ //^^^----------------------------- // and so on ... int16_t application_protocol_ordinal; uint8_t frag_flag; /* flag to indicate a fragmented packet */ uint8_t mf; /* more fragments flag */ uint8_t df; /* don't fragment flag */ uint8_t rf; /* IP reserved bit */ uint8_t ip_option_count; /* number of options in this packet */ uint8_t tcp_option_count; uint8_t ip6_extension_count; uint8_t ip6_frag_index; uint8_t error_flags; /* flags indicate checksum errors, bad TTLs, etc. */ uint8_t encapsulated; uint8_t GTPencapsulated; uint8_t next_layer; /* index into layers for next encap */ #ifndef NO_NON_ETHER_DECODER const Fddi_hdr *fddihdr; /* FDDI support headers */ Fddi_llc_saps *fddisaps; Fddi_llc_sna *fddisna; Fddi_llc_iparp *fddiiparp; Fddi_llc_other *fddiother; const Trh_hdr *trh; /* Token Ring support headers */ Trh_llc *trhllc; Trh_mr *trhmr; Pflog1Hdr *pf1h; /* OpenBSD pflog interface header - version 1 */ Pflog2Hdr *pf2h; /* OpenBSD pflog interface header - version 2 */ Pflog3Hdr *pf3h; /* OpenBSD pflog interface header - version 3 */ Pflog4Hdr *pf4h; /* OpenBSD pflog interface header - version 4 */ #ifdef DLT_LINUX_SLL const SLLHdr *sllh; /* Linux cooked sockets header */ #endif #ifdef DLT_IEEE802_11 const WifiHdr *wifih; /* wireless LAN header */ #endif const EtherEapol *eplh; /* 802.1x EAPOL header */ const EAPHdr *eaph; const uint8_t *eaptype; EapolKey *eapolk; #endif // nothing after this point is zeroed ... Options ip_options[IP_OPTMAX]; /* ip options decode structure */ Options tcp_options[TCP_OPTLENMAX]; /* tcp options decode struct */ IP6Option *ip6_extensions; /* IPv6 Extension References */ CiscoMetaOpt *cmd_options; /* Cisco Metadata header options */ const uint8_t *ip_frag_start; const uint8_t *ip_options_data; const uint8_t *tcp_options_data; const IP6RawHdr* raw_ip6h; // innermost raw ip6 header Layer layers[LAYER_MAX]; /* decoded encapsulations */ IPAddresses inner_ips, inner_orig_ips; IP4Hdr inner_ip4h, inner_orig_ip4h; IP6Hdr inner_ip6h, inner_orig_ip6h; IPAddresses outer_ips, outer_orig_ips; IP4Hdr outer_ip4h, outer_orig_ip4h; IP6Hdr outer_ip6h, outer_orig_ip6h; MplsHdr mplsHdr; H2Hdr *h2Hdr; PseudoPacketType pseudo_type; // valid only when PKT_PSEUDO is set uint16_t max_dsize; /**policyId provided in configuration file. Used for correlating configuration * with event output */ uint16_t configPolicyId; uint32_t iplist_id; unsigned char iprep_layer; uint8_t ps_proto; // Used for portscan and unified2 logging uint8_t ips_os_selected; void *cur_pp; // Expected session created due to this packet. struct _ExpectNode* expectedSession; } Packet; #define PKT_ZERO_LEN offsetof(Packet, ip_options) #define PROTO_BIT__NONE 0x0000 #define PROTO_BIT__IP 0x0001 #define PROTO_BIT__ARP 0x0002 #define PROTO_BIT__TCP 0x0004 #define PROTO_BIT__UDP 0x0008 #define PROTO_BIT__ICMP 0x0010 #define PROTO_BIT__TEREDO 0x0020 #define PROTO_BIT__GTP 0x0040 #define PROTO_BIT__OTHER 0x8000 #define PROTO_BIT__ALL 0xffff #define IsIP(p) (IPH_IS_VALID(p)) #define IsTCP(p) (IsIP(p) && p->tcph) #define IsUDP(p) (IsIP(p) && p->udph) #define IsICMP(p) (IsIP(p) && p->icmph) #define GET_PKT_SEQ(p) (ntohl(p->tcph->th_seq)) /* Macros to deal with sequence numbers - p810 TCP Illustrated vol 2 */ #define SEQ_LT(a,b) ((int)((a) - (b)) < 0) #define SEQ_LEQ(a,b) ((int)((a) - (b)) <= 0) #define SEQ_GT(a,b) ((int)((a) - (b)) > 0) #define SEQ_GEQ(a,b) ((int)((a) - (b)) >= 0) #define SEQ_EQ(a,b) ((int)((a) - (b)) == 0) #define BIT(i) (0x1 << (i-1)) typedef struct s_pseudoheader { uint32_t sip, dip; uint8_t zero; uint8_t protocol; uint16_t len; } PSEUDO_HDR; /* Default classification for decoder alerts */ #define DECODE_CLASS 25 typedef struct _DecoderFlags { char decode_alerts; /* if decode.c alerts are going to be enabled */ char oversized_alert; /* alert if garbage after tcp/udp payload */ char oversized_drop; /* alert if garbage after tcp/udp payload */ char drop_alerts; /* drop alerts from decoder */ char tcpopt_experiment; /* TcpOptions Decoder */ char drop_tcpopt_experiment; /* Drop alerts from TcpOptions Decoder */ char tcpopt_obsolete; /* Alert on obsolete TCP options */ char drop_tcpopt_obsolete; /* Drop on alerts from obsolete TCP options */ char tcpopt_ttcp; /* Alert on T/TCP options */ char drop_tcpopt_ttcp; /* Drop on alerts from T/TCP options */ char tcpopt_decode; /* alert on decoder inconsistencies */ char drop_tcpopt_decode; /* Drop on alerts from decoder inconsistencies */ char ipopt_decode; /* alert on decoder inconsistencies */ char drop_ipopt_decode; /* Drop on alerts from decoder inconsistencies */ /* To be moved to the frag preprocessor once it supports IPv6 */ char ipv6_bad_frag_pkt; char bsd_icmp_frag; char drop_bad_ipv6_frag; } DecoderFlags; #define ALERTMSG_LENGTH 256 /* P R O T O T Y P E S ******************************************************/ // root decoders void DecodeEthPkt(Packet *, const DAQ_PktHdr_t*, const uint8_t *); void DecodeNullPkt(Packet *, const DAQ_PktHdr_t*, const uint8_t *); void DecodeRawPkt(Packet *, const DAQ_PktHdr_t*, const uint8_t *); void DecodeRawPkt6(Packet *, const DAQ_PktHdr_t*, const uint8_t *); // chained decoders void DecodeARP(const uint8_t *, uint32_t, Packet *); void DecodeEthLoopback(const uint8_t *, uint32_t, Packet *); void DecodeVlan(const uint8_t *, const uint32_t, Packet *); void DecodePppPktEncapsulated(const uint8_t *, const uint32_t, Packet *); void DecodePPPoEPkt(const uint8_t *, const uint32_t, Packet *); void DecodeIP(const uint8_t *, const uint32_t, Packet *); void DecodeIPV6(const uint8_t *, uint32_t, Packet *); void DecodeTCP(const uint8_t *, const uint32_t, Packet *); void DecodeUDP(const uint8_t *, const uint32_t, Packet *); void DecodeICMP(const uint8_t *, const uint32_t, Packet *); void DecodeICMP6(const uint8_t *, const uint32_t, Packet *); void DecodeICMPEmbeddedIP(const uint8_t *, const uint32_t, Packet *); void DecodeICMPEmbeddedIP6(const uint8_t *, const uint32_t, Packet *); void DecodeIPOptions(const uint8_t *, uint32_t, Packet *); void DecodeTCPOptions(const uint8_t *, uint32_t, Packet *); void DecodeTeredo(const uint8_t *, uint32_t, Packet *); void DecodeAH(const uint8_t *, uint32_t, Packet *); void DecodeESP(const uint8_t *, uint32_t, Packet *); void DecodeGTP(const uint8_t *, uint32_t, Packet *); #ifdef GRE void DecodeGRE(const uint8_t *, const uint32_t, Packet *); void DecodeTransBridging(const uint8_t *, const uint32_t, Packet *); #endif /* GRE */ void DecoderAlertEncapsulated(Packet *, int, const char *, const uint8_t *, uint32_t); #ifdef MPLS int isPrivateIP(uint32_t addr); void DecodeEthOverMPLS(const uint8_t*, const uint32_t, Packet*); void DecodeMPLS(const uint8_t*, const uint32_t, Packet*); #endif #ifndef NO_NON_ETHER_DECODER // root decoders void DecodeTRPkt(Packet *, const DAQ_PktHdr_t*, const uint8_t *); void DecodeFDDIPkt(Packet *, const DAQ_PktHdr_t*, const uint8_t *); void DecodeLinuxSLLPkt(Packet *, const DAQ_PktHdr_t*, const uint8_t *); void DecodeIEEE80211Pkt(Packet *, const DAQ_PktHdr_t*, const uint8_t *); void DecodeSlipPkt(Packet *, const DAQ_PktHdr_t*, const uint8_t *); void DecodeI4LRawIPPkt(Packet *, const DAQ_PktHdr_t*, const uint8_t *); void DecodeI4LCiscoIPPkt(Packet *, const DAQ_PktHdr_t*, const uint8_t *); void DecodeChdlcPkt(Packet *, const DAQ_PktHdr_t*, const uint8_t *); void DecodePflog(Packet *, const DAQ_PktHdr_t*, const uint8_t *); void DecodeOldPflog(Packet *, const DAQ_PktHdr_t*, const uint8_t *); void DecodePppPkt(Packet *, const DAQ_PktHdr_t*, const uint8_t *); void DecodePppSerialPkt(Packet *, const DAQ_PktHdr_t*, const uint8_t *); void DecodeEncPkt(Packet *, const DAQ_PktHdr_t*, const uint8_t *); // chained decoders void DecodeEAP(const uint8_t *, const uint32_t, Packet *); void DecodeEapol(const uint8_t *, uint32_t, Packet *); void DecodeEapolKey(const uint8_t *, uint32_t, Packet *); void DecodeIPX(const uint8_t *, uint32_t, Packet *); #endif // NO_NON_ETHER_DECODER void BsdFragHashInit(int max); void BsdFragHashCleanup(void); void BsdFragHashReset(void); #if defined(WORDS_MUSTALIGN) && !defined(__GNUC__) uint32_t EXTRACT_32BITS (u_char *); #endif /* WORDS_MUSTALIGN && !__GNUC__ */ extern void UpdateDecodeRulesArray(uint32_t sid, int bOn, int bAll); /*Decode functions that need to be called once the policies are set */ extern void DecodePolicySpecific(Packet *); /* XXX not sure where this guy needs to live at the moment */ typedef struct _PortList { int ports[32]; /* 32 is kind of arbitrary */ int num_entries; } PortList; void InitSynToMulticastDstIp( struct _SnortConfig * ); void SynToMulticastDstIpDestroy( void ); void InitMulticastReservedIp( struct _SnortConfig * ); void MulticastReservedIpDestroy( void ); #define SFTARGET_UNKNOWN_PROTOCOL -1 static inline int PacketWasCooked(Packet* p) { return ( p->packet_flags & PKT_PSEUDO ) != 0; } static inline bool IsPortscanPacket(const Packet *p) { return ((p->packet_flags & PKT_PSEUDO) && (p->pseudo_type == PSEUDO_PKT_PS)); } static inline uint8_t GetEventProto(const Packet *p) { if (IsPortscanPacket(p)) return p->ps_proto; return IPH_IS_VALID(p) ? GET_IPH_PROTO(p) : 0; } static inline bool PacketHasFullPDU (const Packet* p) { return ( (p->packet_flags & PKT_PDU_FULL) == PKT_PDU_FULL ); } static inline bool PacketHasStartOfPDU (const Packet* p) { return ( (p->packet_flags & PKT_PDU_HEAD) != 0 ); } static inline bool PacketHasPAFPayload (const Packet* p) { return ( (p->packet_flags & PKT_REBUILT_STREAM) || (p->packet_flags & PKT_PDU_TAIL) ); } static inline bool PacketIsRebuilt (const Packet* p) { return ( (p->packet_flags & (PKT_REBUILT_STREAM|PKT_REBUILT_FRAG)) != 0 ); } static inline void SetExtraData (Packet* p, uint32_t xid) { p->xtradata_mask |= BIT(xid); } #endif /* __DECODE_H__ */ snort-2.9.15.1/src/encode.c0000644000175200017520000014507413571422607012253 00000000000000/* $Id$ */ /**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2005-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ // @file encode.c // @author Russ Combs #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #ifdef HAVE_DUMBNET_H #include #else #include #endif #include "assert.h" #include "encode.h" #include "sfdaq.h" #include "sf_iph.h" #include "snort.h" #include "session_api.h" #include "stream_api.h" #include "checksum.h" #ifdef MPLS #include "preprocessors/Session/session_common.h" #endif #define GET_IP_HDR_LEN(h) (((h)->ip_verhl & 0x0f) << 2) #define GET_TCP_HDR_LEN(h) (((h)->th_offx2 & 0xf0) >> 2) #define SET_TCP_HDR_LEN(h, n) (h)->th_offx2 = ((n << 2) & 0xF0) #define MIN_TTL 64 #define MAX_TTL 255 #define ICMP_UNREACH_DATA 8 // (per RFC 792) #define IP_ID_COUNT 8192 static uint8_t* dst_mac = NULL; Packet* encode_pkt = NULL; uint64_t total_rebuilt_pkts = 0; //------------------------------------------------------------------------- // encoders operate layer by layer: // * base+off is start of packet // * base+end is start of current layer // * base+size-1 is last byte of packet (in) / buffer (out) typedef blob_t Buffer; typedef enum { ENC_OK, ENC_BAD_PROTO, ENC_BAD_OPT, ENC_OVERFLOW } ENC_STATUS; typedef struct { EncodeType type; EncodeFlags flags; uint8_t layer; const Packet* p; uint16_t ip_len; uint8_t* ip_hdr; const uint8_t* payLoad; uint32_t payLen; uint8_t proto; } EncState; #define FORWARD(e) (e->flags & ENC_FLAG_FWD) #define REVERSE(f) (!(f & ENC_FLAG_FWD)) // PKT_MAX is sized to ensure that any reassembled packet // can accommodate a full datagram at innermost layer #define PKT_MAX (ETHERNET_HEADER_LEN + VLAN_HEADER_LEN + ETHERNET_MTU + IP_MAXPACKET) // all layer encoders look like this: typedef ENC_STATUS (*Encoder)(EncState*, Buffer* in, Buffer* out); typedef ENC_STATUS (*Updater)(Packet*, Layer*, uint32_t* len); typedef void (*Formatter)(EncodeFlags, const Packet* p, Packet* c, Layer*); // TBD implement other encoder functions typedef struct { Encoder fencode; Updater fupdate; Formatter fformat; } EncoderFunctions; // forward declaration; definition at end of file static EncoderFunctions encoders[PROTO_MAX]; static void IpId_Init(); static void IpId_Term(); static const uint8_t* Encode_Packet( EncState* enc, const Packet* p, uint32_t* len); static ENC_STATUS UN6_ICMP6_Encode(EncState*, Buffer*, Buffer*); static ENC_STATUS UN6_UDP_Encode(EncState*, Buffer*, Buffer*); //------------------------------------------------------------------------- static inline PROTO_ID NextEncoder (EncState* enc) { if ( enc->layer < enc->p->next_layer ) { PROTO_ID next = enc->p->layers[enc->layer++].proto; if ( next < PROTO_MAX ) { if ( encoders[next].fencode ) return next; } } return PROTO_MAX; } //------------------------------------------------------------------------- // basic setup stuff //------------------------------------------------------------------------- void Encode_Init (void) { IpId_Init(); } void Encode_Term (void) { IpId_Term(); } //------------------------------------------------------------------------- // encoders: // - raw pkt data only, no need for Packet stuff except to facilitate // encoding // - don't include original options // - inner layer differs from original (eg tcp data segment becomes rst) // - must ensure proper ttl/hop limit for reverse direction // - sparc twiddle must be factored in packet start for transmission // // iterate over decoded layers and encode the response packet. actually // make nested calls. on the way in we setup invariant stuff and as we // unwind the stack we finish up encoding in a more normal fashion (now // the outer layer knows the length of the inner layer, etc.). // // when multiple responses are sent, both forwards and backwards directions, // or multiple ICMP types (unreachable port, host, net), it may be possible // to reuse the 1st encoding and just tweak it. optimization for later // consideration. // pci is copied from in to out // * addresses / ports are swapped if !fwd // * options, etc. are stripped // * checksums etc. are set // * if next layer is udp, it is set to icmp unreachable w/udp // * if next layer is tcp, it becomes a tcp rst or tcp fin w/opt data //------------------------------------------------------------------------- const uint8_t* Encode_Reject( EncodeType type, EncodeFlags flags, const Packet* p, uint32_t* len) { EncState enc; enc.type = type; enc.flags = flags; enc.payLoad = NULL; enc.payLen = 0; enc.ip_hdr = NULL; enc.ip_len = 0; enc.proto = 0; if ( encode_pkt ) p = encode_pkt; return Encode_Packet(&enc, p, len); } const uint8_t* Encode_Response( EncodeType type, EncodeFlags flags, const Packet* p, uint32_t* len, const uint8_t* payLoad, uint32_t payLen ) { EncState enc; enc.type = type; enc.flags = flags; enc.payLoad = payLoad; enc.payLen = payLen; enc.ip_hdr = NULL; enc.ip_len = 0; enc.proto = 0; if ( encode_pkt ) p = encode_pkt; return Encode_Packet(&enc, p, len); } //------------------------------------------------------------------------- // formatters: // - these packets undergo detection // - need to set Packet stuff except for frag3 which calls grinder // - include original options except for frag3 inner ip // - inner layer header is very similar but payload differs // - original ttl is always used //------------------------------------------------------------------------- #ifdef HAVE_DAQ_ADDRESS_SPACE_ID int Encode_Format_With_DAQ_Info ( EncodeFlags f, const Packet* p, Packet* c, PseudoPacketType type, const DAQ_PktHdr_t* phdr, uint32_t opaque) #elif defined(HAVE_DAQ_ACQUIRE_WITH_META) int Encode_Format_With_DAQ_Info ( EncodeFlags f, const Packet* p, Packet* c, PseudoPacketType type, uint32_t opaque) #else int Encode_Format (EncodeFlags f, const Packet* p, Packet* c, PseudoPacketType type) #endif { DAQ_PktHdr_t* pkth = (DAQ_PktHdr_t*)c->pkth; uint8_t* pkt = (uint8_t*)c->pkt; int i, next_layer = p->next_layer; Layer* lyr; size_t len; if ( next_layer < 1 ) return -1; memset(c, 0, PKT_ZERO_LEN); c->raw_ip6h = NULL; c->pkth = pkth; c->pkt = pkt; #ifdef HAVE_DAQ_ADDRESS_SPACE_ID pkth->ingress_index = phdr->ingress_index; pkth->ingress_group = phdr->ingress_group; pkth->egress_index = phdr->egress_index; pkth->egress_group = phdr->egress_group; pkth->flags = phdr->flags & (~DAQ_PKT_FLAG_HW_TCP_CS_GOOD); #ifdef DAQ_CAPA_VRF pkth->address_space_id_src = phdr->address_space_id_src; pkth->address_space_id_dst = phdr->address_space_id_dst; #else pkth->address_space_id = phdr->address_space_id; #endif pkth->opaque = opaque; if( type == PSEUDO_PKT_TCP || type == PSEUDO_PKT_IP ) pkth->priv_ptr = phdr->priv_ptr; #if defined(DAQ_VERSION) && DAQ_VERSION > 8 pkth->proto = phdr->proto; #endif #ifdef HAVE_DAQ_FLOW_ID pkth->flow_id = phdr->flow_id; #endif #elif defined(HAVE_DAQ_ACQUIRE_WITH_META) pkth->opaque = opaque; #endif #ifdef HAVE_DAQ_REAL_ADDRESSES if (pkth->flags & DAQ_PKT_FLAG_REAL_ADDRESSES) { pkth->n_real_sPort = phdr->n_real_sPort; pkth->n_real_dPort = phdr->n_real_dPort; pkth->real_sIP = phdr->real_sIP; pkth->real_dIP = phdr->real_dIP; } #endif if ( f & ENC_FLAG_NET ) { for ( i = next_layer-1; i >= 0; i-- ) if ( p->layers[i].proto == PROTO_IP4 || p->layers[i].proto == PROTO_IP6 ) break; if ( i < next_layer ) next_layer = i + 1; } // copy raw packet data to clone lyr = (Layer*)p->layers + next_layer - 1; len = lyr->start - p->pkt + lyr->length; memcpy((void*)c->pkt, p->pkt, len); // set up layers for ( i = 0; i < next_layer; i++ ) { const uint8_t* b = c->pkt + (p->layers[i].start - p->pkt); lyr = c->layers + i; lyr->proto = p->layers[i].proto; lyr->length = p->layers[i].length; lyr->start = (uint8_t*)b; if ( lyr->proto < PROTO_MAX ) encoders[lyr->proto].fformat(f, p, c, lyr); #ifdef DEBUG else FatalError("Encode_New() => unsupported proto = %d\n", lyr->proto); #endif } c->next_layer = next_layer; // setup payload info c->data = lyr->start + lyr->length; len = c->data - c->pkt; assert(len < PKT_MAX - IP_MAXPACKET); c->max_dsize = IP_MAXPACKET - len; c->proto_bits = p->proto_bits; c->packet_flags |= PKT_PSEUDO; c->pseudo_type = type; UpdateRebuiltPktCount(); switch ( type ) { case PSEUDO_PKT_SMB_SEG: case PSEUDO_PKT_DCE_SEG: case PSEUDO_PKT_DCE_FRAG: case PSEUDO_PKT_SMB_TRANS: c->packet_flags |= PKT_REASSEMBLED_OLD; break; default: break; } // setup pkt capture header pkth->caplen = pkth->pktlen = len; pkth->ts = p->pkth->ts; // cooked packet gets same policy as raw c->configPolicyId = p->configPolicyId; if ( !c->max_dsize ) return -1; return 0; } //------------------------------------------------------------------------- // formatters: // - these packets undergo detection // - need to set Packet stuff except for frag3 which calls grinder // - include original options except for frag3 inner ip // - inner layer header is very similar but payload differs // - original ttl is always used //------------------------------------------------------------------------- #ifdef HAVE_DAQ_ADDRESS_SPACE_ID int Encode_Format (EncodeFlags f, const Packet* p, Packet* c, PseudoPacketType type) { return Encode_Format_With_DAQ_Info(f, p, c, type, p->pkth, p->pkth->opaque); } #elif defined(HAVE_DAQ_ACQUIRE_WITH_META) int Encode_Format (EncodeFlags f, const Packet* p, Packet* c, PseudoPacketType type) { return Encode_Format_With_DAQ_Info(f, p, c, type, p->pkth->opaque); } #endif //------------------------------------------------------------------------- // updaters: these functions set length and checksum fields, only needed // when a packet is modified. some packets only have replacements so only // the checksums need to be updated. we always set the length rather than // checking each time if needed. //------------------------------------------------------------------------- void Encode_Update (Packet* p) { int i; uint32_t len = 0; DAQ_PktHdr_t* pkth = (DAQ_PktHdr_t*)p->pkth; p->actual_ip_len = 0; for ( i = p->next_layer - 1; i >= 0; i-- ) { Layer* lyr = p->layers + i; encoders[lyr->proto].fupdate(p, lyr, &len); } // see IP6_Update() for an explanation of this ... if ( !(p->packet_flags & PKT_MODIFIED) #ifdef NORMALIZER || (p->packet_flags & PKT_RESIZED) #endif ) pkth->caplen = pkth->pktlen = len; p->packet_flags &= ~PKT_LOGGED; } //------------------------------------------------------------------------- // internal packet support //------------------------------------------------------------------------- Packet* Encode_New () { Packet* p = SnortAlloc(sizeof(*p)); uint8_t* b = SnortAlloc(sizeof(*p->pkth) + PKT_MAX + SPARC_TWIDDLE); IP6Option* ip6_extensions = SnortAlloc(sizeof(IP6Option) * ScMaxIP6Extensions()); if ( !p || !b || !ip6_extensions ) FatalError("Encode_New() => Failed to allocate packet\n"); p->pkth = (void*)b; b += sizeof(*p->pkth); b += SPARC_TWIDDLE; p->pkt = b; p->ip6_extensions = ip6_extensions; return p; } void Encode_Delete (Packet* p) { free((void*)p->pkth); // cast away const! free(p->ip6_extensions); free(p); } /* Set the destination MAC address*/ void Encode_SetDstMAC(uint8_t *mac) { dst_mac = mac; } //------------------------------------------------------------------------- // private implementation stuff //------------------------------------------------------------------------- static uint8_t s_pkt[PKT_MAX]; static const uint8_t* Encode_Packet( EncState* enc, const Packet* p, uint32_t* len) { Buffer ibuf, obuf; ENC_STATUS status = ENC_BAD_PROTO; PROTO_ID next; ibuf.base = (uint8_t*)p->pkt; ibuf.off = ibuf.end = 0; ibuf.size = p->pkth->caplen; obuf.base = s_pkt; obuf.off = obuf.end = 0; obuf.size = sizeof(s_pkt); enc->layer = 0; enc->p = p; next = NextEncoder(enc); if ( next < PROTO_MAX ) { Encoder e = encoders[next].fencode; status = (*e)(enc, &ibuf, &obuf); } if ( status != ENC_OK || enc->layer != p->next_layer ) { *len = 0; return NULL; } *len = (uint32_t)obuf.end; return obuf.base + obuf.off; } //------------------------------------------------------------------------- // ip id considerations: // // we use dnet's rand services to generate a vector of random 16-bit values and // iterate over the vector as IDs are assigned. when we wrap to the beginning, // the vector is randomly reordered. //------------------------------------------------------------------------- static rand_t* s_rand = NULL; static uint16_t s_id_index = 0; static uint16_t s_id_pool[IP_ID_COUNT]; static void IpId_Init (void) { if ( s_rand ) rand_close(s_rand); s_rand = rand_open(); if ( !s_rand ) FatalError("encode::IpId_Init: rand_open() failed.\n"); rand_get(s_rand, s_id_pool, sizeof(s_id_pool)); } static void IpId_Term (void) { if ( s_rand ) rand_close(s_rand); s_rand = NULL; } static inline uint16_t IpId_Next () { #ifdef REG_TEST uint16_t id = htons(s_id_index + 1); #else uint16_t id = s_id_pool[s_id_index]; #endif s_id_index = (s_id_index + 1) % IP_ID_COUNT; if ( !s_id_index ) rand_shuffle(s_rand, s_id_pool, sizeof(s_id_pool), 1); return id; } //------------------------------------------------------------------------- // ttl considerations: // // we try to use the TTL captured for the session by the stream preprocessor // when the session started. if that is not available, we use the current // TTL for forward packets and use (maximum - current) TTL for reverse // packets. // // the reason we don't just force ttl to 255 (max) is to make it look a // little more authentic. // // for reference, flexresp used a const rand >= 64 in both directions (the // number was determined at startup and never changed); flexresp2 used the // next higher multiple of 64 in both directions; and react used a const // 64 in both directions. // // note that the ip6 hop limit field is entirely equivalent to the ip4 TTL. // hop limit is in fact a more accurrate name for the actual usage of this // field. //------------------------------------------------------------------------- static inline uint8_t GetTTL (const EncState* enc) { char dir; uint8_t ttl; int outer = !enc->ip_hdr; if ( !enc->p->ssnptr ) return 0; if ( enc->p->packet_flags & PKT_FROM_CLIENT ) dir = FORWARD(enc) ? SSN_DIR_FROM_CLIENT : SSN_DIR_FROM_SERVER; else dir = FORWARD(enc) ? SSN_DIR_FROM_SERVER : SSN_DIR_FROM_CLIENT; // outermost ip is considered to be outer here, // even if it is the only ip layer ... ttl = session_api->get_session_ttl(enc->p->ssnptr, dir, outer); // so if we don't get outer, we use inner if ( 0 == ttl && outer ) ttl = session_api->get_session_ttl(enc->p->ssnptr, dir, 0); return ttl; } static inline uint8_t FwdTTL (const EncState* enc, uint8_t ttl) { uint8_t new_ttl = GetTTL(enc); if ( !new_ttl ) new_ttl = ttl; return new_ttl; } static inline uint8_t RevTTL (const EncState* enc, uint8_t ttl) { uint8_t new_ttl = GetTTL(enc); if ( !new_ttl ) new_ttl = ( MAX_TTL - ttl ); if ( new_ttl < MIN_TTL ) new_ttl = MIN_TTL; return new_ttl; } //------------------------------------------------------------------------- // the if in UPDATE_BOUND can be defined out after testing because: // 1. the packet was already decoded in decode.c so is structurally sound; and // 2. encode takes at most the same space as decode. #define UPDATE_BOUND(buf, n) \ buf->end += n; \ if ( buf->end > buf->size ) \ return ENC_OVERFLOW //------------------------------------------------------------------------- // BUFLEN // Get the buffer length for a given protocol #define BUFF_DIFF(buf, ho) ((uint8_t*)(buf->base+buf->end)-(uint8_t*)ho) //------------------------------------------------------------------------- // ethernet //------------------------------------------------------------------------- static ENC_STATUS Eth_Encode (EncState* enc, Buffer* in, Buffer* out) { // not raw ip -> encode layer 2 int raw = ( enc->flags & ENC_FLAG_RAW ); EtherHdr* hi = (EtherHdr*)enc->p->layers[enc->layer-1].start; PROTO_ID next = NextEncoder(enc); // if not raw ip AND out buf is empty if ( !raw && (out->off == out->end) ) { // for alignment out->off = out->end = SPARC_TWIDDLE; } // if not raw ip OR out buf is not empty if ( !raw || (out->off != out->end) ) { // we get here for outer-most layer when not raw ip // we also get here for any encapsulated ethernet layer. EtherHdr* ho = (EtherHdr*)(out->base + out->end); UPDATE_BOUND(out, sizeof(*ho)); ho->ether_type = hi->ether_type; if ( FORWARD(enc) ) { memcpy(ho->ether_src, hi->ether_src, sizeof(ho->ether_src)); /*If user configured remote MAC address, use it*/ if (NULL != dst_mac) memcpy(ho->ether_dst, dst_mac, sizeof(ho->ether_dst)); else memcpy(ho->ether_dst, hi->ether_dst, sizeof(ho->ether_dst)); } else { memcpy(ho->ether_src, hi->ether_dst, sizeof(ho->ether_src)); /*If user configured remote MAC address, use it*/ if (NULL != dst_mac) memcpy(ho->ether_dst, dst_mac, sizeof(ho->ether_dst)); else memcpy(ho->ether_dst, hi->ether_src, sizeof(ho->ether_dst)); } } if ( next < PROTO_MAX ) return encoders[next].fencode(enc, in, out); return ENC_OK; } static ENC_STATUS Eth_Update (Packet* p, Layer* lyr, uint32_t* len) { *len += lyr->length; return ENC_OK; } static void Eth_Format (EncodeFlags f, const Packet* p, Packet* c, Layer* lyr) { EtherHdr* ch = (EtherHdr*)lyr->start; c->eh = ch; if ( REVERSE(f) ) { int i = lyr - c->layers; EtherHdr* ph = (EtherHdr*)p->layers[i].start; memcpy(ch->ether_dst, ph->ether_src, sizeof(ch->ether_dst)); memcpy(ch->ether_src, ph->ether_dst, sizeof(ch->ether_src)); } } //------------------------------------------------------------------------- // FabricPath //------------------------------------------------------------------------- static ENC_STATUS FPath_Encode (EncState* enc, Buffer* in, Buffer* out) { // not raw ip -> encode layer 2 int raw = ( enc->flags & ENC_FLAG_RAW ); FPathHdr* hi = (FPathHdr*)enc->p->layers[enc->layer-1].start; PROTO_ID next = NextEncoder(enc); // if not raw ip AND out buf is empty if ( !raw && (out->off == out->end) ) { // for alignment out->off = out->end = 0; } // if not raw ip OR out buf is not empty if ( !raw || (out->off != out->end) ) { // we get here for outer-most layer when not raw ip // we also get here for any encapsulated ethernet layer. FPathHdr* ho = (FPathHdr*)(out->base + out->end); UPDATE_BOUND(out, sizeof(*ho)); ho->fpath_type = hi->fpath_type; if ( FORWARD(enc) ) { memcpy(ho->fpath_src, hi->fpath_src, sizeof(ho->fpath_src)); memcpy(ho->fpath_dst, hi->fpath_dst, sizeof(ho->fpath_dst)); } else { memcpy(ho->fpath_src, hi->fpath_dst, sizeof(ho->fpath_src)); memcpy(ho->fpath_dst, hi->fpath_src, sizeof(ho->fpath_dst)); } } if ( next < PROTO_MAX ) return encoders[next].fencode(enc, in, out); return ENC_OK; } static ENC_STATUS FPath_Update (Packet* p, Layer* lyr, uint32_t* len) { *len += lyr->length; return ENC_OK; } static void FPath_Format (EncodeFlags f, const Packet* p, Packet* c, Layer* lyr) { FPathHdr* ch = (FPathHdr*)lyr->start; if ( REVERSE(f) ) { int i = lyr - c->layers; FPathHdr* ph = (FPathHdr*)p->layers[i].start; memcpy(ch->fpath_dst, ph->fpath_src, sizeof(ch->fpath_dst)); memcpy(ch->fpath_src, ph->fpath_dst, sizeof(ch->fpath_src)); } } //------------------------------------------------------------------------- // VLAN //------------------------------------------------------------------------- static void VLAN_Format (EncodeFlags f, const Packet* p, Packet* c, Layer* lyr) { #ifdef HAVE_DAQ_REAL_ADDRESSES if (!(p->pkth->flags & DAQ_PKT_FLAG_IGNORE_VLAN)) #endif c->vh = (VlanTagHdr*)lyr->start; } //------------------------------------------------------------------------- // GRE //------------------------------------------------------------------------- #ifdef GRE static void GRE_Format (EncodeFlags f, const Packet* p, Packet* c, Layer* lyr) { c->greh = (GREHdr*)lyr->start; } #endif //------------------------------------------------------------------------- // IP4 //------------------------------------------------------------------------- static ENC_STATUS IP4_Encode (EncState* enc, Buffer* in, Buffer* out) { int len; uint32_t start = out->end; IPHdr* hi = (IPHdr*)enc->p->layers[enc->layer-1].start; IPHdr* ho = (IPHdr*)(out->base + out->end); PROTO_ID next = NextEncoder(enc); UPDATE_BOUND(out, sizeof(*ho)); /* IPv4 encoded header is hardcoded 20 bytes */ ho->ip_verhl = 0x45; ho->ip_off = 0; ho->ip_id = IpId_Next(); ho->ip_tos = hi->ip_tos; ho->ip_proto = hi->ip_proto; if ( FORWARD(enc) ) { ho->ip_src.s_addr = hi->ip_src.s_addr; ho->ip_dst.s_addr = hi->ip_dst.s_addr; ho->ip_ttl = FwdTTL(enc, hi->ip_ttl); } else { ho->ip_src.s_addr = hi->ip_dst.s_addr; ho->ip_dst.s_addr = hi->ip_src.s_addr; ho->ip_ttl = RevTTL(enc, hi->ip_ttl); } enc->ip_hdr = (uint8_t*)hi; enc->ip_len = IP_HLEN(hi) << 2; if ( next < PROTO_MAX ) { ENC_STATUS err = encoders[next].fencode(enc, in, out); if ( ENC_OK != err ) return err; } if ( enc->proto ) { ho->ip_proto = enc->proto; enc->proto = 0; } len = out->end - start; ho->ip_len = htons((uint16_t)len); ho->ip_csum = 0; /* IPv4 encoded header is hardcoded 20 bytes, we save some * cycles and use the literal header size for checksum */ ho->ip_csum = in_chksum_ip((const uint16_t *)ho, sizeof *ho); return ENC_OK; } static ENC_STATUS IP4_Update (Packet* p, Layer* lyr, uint32_t* len) { IPHdr* h = (IPHdr*)(lyr->start); int i = lyr - p->layers; *len += GET_IP_HDR_LEN(h); if ( i + 1 == p->next_layer ) { *len += p->dsize; } h->ip_len = htons((uint16_t)*len); if ( !PacketWasCooked(p) || (p->packet_flags & PKT_REBUILT_FRAG) ) { h->ip_csum = 0; h->ip_csum = in_chksum_ip((const uint16_t *)h, GET_IP_HDR_LEN(h)); } return ENC_OK; } static void IP4_Format (EncodeFlags f, const Packet* p, Packet* c, Layer* lyr) { // TBD handle nested ip layers IPHdr* ch = (IPHdr*)lyr->start; c->iph = ch; if ( REVERSE(f) ) { int i = lyr - c->layers; IPHdr* ph = (IPHdr*)p->layers[i].start; ch->ip_src.s_addr = ph->ip_dst.s_addr; ch->ip_dst.s_addr = ph->ip_src.s_addr; } if ( f & ENC_FLAG_DEF ) { int i = lyr - c->layers; if ( i + 1 == p->next_layer ) { lyr->length = sizeof(*ch); ch->ip_len = htons(lyr->length); SET_IP_HLEN(ch, lyr->length >> 2); } } sfiph_build(c, c->iph, AF_INET); } //------------------------------------------------------------------------- // ICMP // UNR encoder creates ICMP unreachable //------------------------------------------------------------------------- static inline int IcmpCode (EncodeType et) { switch ( et ) { case ENC_UNR_NET: return ICMP_UNREACH_NET; case ENC_UNR_HOST: return ICMP_UNREACH_HOST; case ENC_UNR_PORT: return ICMP_UNREACH_PORT; case ENC_UNR_FW: return ICMP_UNREACH_FILTER_PROHIB; default: break; } return ICMP_UNREACH_PORT; } typedef struct { uint8_t type; uint8_t code; uint16_t cksum; uint32_t unused; } IcmpHdr; static ENC_STATUS UN4_Encode (EncState* enc, Buffer* in, Buffer* out) { uint8_t* p; uint8_t* hi = enc->p->layers[enc->layer-1].start; IcmpHdr* ho = (IcmpHdr*)(out->base + out->end); #ifdef DEBUG if ( enc->type < ENC_UNR_NET ) return ENC_BAD_OPT; #endif enc->proto = IPPROTO_ICMP; UPDATE_BOUND(out, sizeof(*ho)); ho->type = ICMP_UNREACH; ho->code = IcmpCode(enc->type); ho->cksum = 0; ho->unused = 0; // copy original ip header p = out->base + out->end; UPDATE_BOUND(out, enc->ip_len); memcpy(p, enc->ip_hdr, enc->ip_len); // copy first 8 octets of original ip data (ie udp header) p = out->base + out->end; UPDATE_BOUND(out, ICMP_UNREACH_DATA); memcpy(p, hi, ICMP_UNREACH_DATA); ho->cksum = in_chksum_icmp((uint16_t *)ho, BUFF_DIFF(out, ho)); return ENC_OK; } static ENC_STATUS ICMP4_Update (Packet* p, Layer* lyr, uint32_t* len) { IcmpHdr* h = (IcmpHdr*)(lyr->start); *len += lyr->length + p->dsize; if ( !PacketWasCooked(p) || (p->packet_flags & PKT_REBUILT_FRAG) ) { h->cksum = 0; h->cksum = in_chksum_icmp((uint16_t *)h, *len); } return ENC_OK; } static void ICMP4_Format (EncodeFlags f, const Packet* p, Packet* c, Layer* lyr) { // TBD handle nested icmp4 layers c->icmph = (ICMPHdr*)lyr->start; } //------------------------------------------------------------------------- // UDP //------------------------------------------------------------------------- static ENC_STATUS UDP_Encode (EncState* enc, Buffer* in, Buffer* out) { PROTO_ID next = PROTO_MAX; if ( enc->layer < enc->p->next_layer ) { next = enc->p->layers[enc->layer].proto; } if ( enc->type == ENC_UDP || ((PROTO_GTP == next) && (encoders[next].fencode)) ) { int len; ENC_STATUS err; uint32_t start = out->end; UDPHdr* hi = (UDPHdr*)enc->p->layers[enc->layer-1].start; UDPHdr* ho = (UDPHdr*)(out->base + out->end); UPDATE_BOUND(out, sizeof(*ho)); if ( FORWARD(enc) ) { ho->uh_sport = hi->uh_sport; ho->uh_dport = hi->uh_dport; } else { ho->uh_sport = hi->uh_dport; ho->uh_dport = hi->uh_sport; } if ( enc->type != ENC_UDP) { next = NextEncoder(enc); if ( next < PROTO_MAX ) { err = encoders[next].fencode(enc, in, out); if (ENC_OK != err ) return err; } len = out->end - start; } else { uint8_t* pdu = out->base + out->end; UPDATE_BOUND(out, enc->payLen); memcpy(pdu, enc->payLoad, enc->payLen); len = enc->payLen + sizeof(UDPHdr); } ho->uh_len = htons((uint16_t)len); ho->uh_chk = 0; if (IP_VER((IPHdr *)enc->ip_hdr) == 4) { pseudoheader ps; ps.sip = ((IPHdr *)enc->ip_hdr)->ip_src.s_addr; ps.dip = ((IPHdr *)enc->ip_hdr)->ip_dst.s_addr; ps.zero = 0; ps.protocol = IPPROTO_UDP; ps.len = ho->uh_len; ho->uh_chk = in_chksum_udp(&ps, (uint16_t *)ho, len); } else { pseudoheader6 ps6; memcpy(ps6.sip, ((IP6RawHdr *)enc->ip_hdr)->ip6_src.s6_addr, sizeof(ps6.sip)); memcpy(ps6.dip, ((IP6RawHdr *)enc->ip_hdr)->ip6_dst.s6_addr, sizeof(ps6.dip)); ps6.zero = 0; ps6.protocol = IPPROTO_UDP; ps6.len = ho->uh_len; ho->uh_chk = in_chksum_udp6(&ps6, (uint16_t *)ho, len); } return ENC_OK; } if ( IP_VER((IPHdr*)enc->ip_hdr) == 4 ) return UN4_Encode(enc, in, out); return UN6_UDP_Encode(enc, in, out); } static ENC_STATUS UDP_Update (Packet* p, Layer* lyr, uint32_t* len) { UDPHdr* h = (UDPHdr*)(lyr->start); *len += sizeof(*h) + p->dsize; h->uh_len = htons((uint16_t)*len); if ( !PacketWasCooked(p) || (p->packet_flags & PKT_REBUILT_FRAG) ) { h->uh_chk = 0; if (IS_IP4(p)) { pseudoheader ps; ps.sip = ((IPHdr *)(lyr-1)->start)->ip_src.s_addr; ps.dip = ((IPHdr *)(lyr-1)->start)->ip_dst.s_addr; ps.zero = 0; ps.protocol = IPPROTO_UDP; ps.len = htons((uint16_t)*len); h->uh_chk = in_chksum_udp(&ps, (uint16_t *)h, *len); } else { pseudoheader6 ps6; for (lyr--; lyr->proto != PROTO_IP6 && lyr != p->layers; lyr--); if (lyr->proto == PROTO_IP6) { memcpy(ps6.sip, ((IP6RawHdr *)lyr->start)->ip6_src.s6_addr, sizeof(ps6.sip)); memcpy(ps6.dip, ((IP6RawHdr *)lyr->start)->ip6_dst.s6_addr, sizeof(ps6.dip)); ps6.zero = 0; ps6.protocol = IPPROTO_UDP; ps6.len = htons((uint16_t)*len); h->uh_chk = in_chksum_udp6(&ps6, (uint16_t *)h, *len); } } } return ENC_OK; } static void UDP_Format (EncodeFlags f, const Packet* p, Packet* c, Layer* lyr) { UDPHdr* ch = (UDPHdr*)lyr->start; c->udph = ch; if ( REVERSE(f) ) { int i = lyr - c->layers; UDPHdr* ph = (UDPHdr*)p->layers[i].start; ch->uh_sport = ph->uh_dport; ch->uh_dport = ph->uh_sport; } c->sp = ntohs(ch->uh_sport); c->dp = ntohs(ch->uh_dport); } //------------------------------------------------------------------------- // TCP // encoder creates TCP RST // should always try to use acceptable ack since we send RSTs in a // stateless fashion ... from rfc 793: // // In all states except SYN-SENT, all reset (RST) segments are validated // by checking their SEQ-fields. A reset is valid if its sequence number // is in the window. In the SYN-SENT state (a RST received in response // to an initial SYN), the RST is acceptable if the ACK field // acknowledges the SYN. //------------------------------------------------------------------------- static ENC_STATUS TCP_Encode (EncState* enc, Buffer* in, Buffer* out) { int len, ctl; TCPHdr* hi = (TCPHdr*)enc->p->layers[enc->layer-1].start; TCPHdr* ho = (TCPHdr*)(out->base + out->end); UPDATE_BOUND(out, sizeof(*ho)); len = GET_TCP_HDR_LEN(hi) - sizeof(*hi); UPDATE_BOUND(in, len); ctl = (hi->th_flags & TH_SYN) ? 1 : 0; if ( FORWARD(enc) ) { ho->th_sport = hi->th_sport; ho->th_dport = hi->th_dport; // th_seq depends on whether the data passes or drops if ( DAQ_GetInterfaceMode(enc->p->pkth) != DAQ_MODE_INLINE ) ho->th_seq = htonl(ntohl(hi->th_seq) + enc->p->dsize + ctl); else ho->th_seq = hi->th_seq; ho->th_ack = hi->th_ack; } else { ho->th_sport = hi->th_dport; ho->th_dport = hi->th_sport; ho->th_seq = hi->th_ack; ho->th_ack = htonl(ntohl(hi->th_seq) + enc->p->dsize + ctl); } if ( enc->flags & ENC_FLAG_SEQ ) { uint32_t seq = ntohl(ho->th_seq); seq += (enc->flags & ENC_FLAG_VAL); ho->th_seq = htonl(seq); } ho->th_offx2 = 0; SET_TCP_OFFSET(ho, (TCP_HDR_LEN >> 2)); ho->th_win = ho->th_urp = 0; if ( enc->type == ENC_TCP_FIN || enc->type == ENC_TCP_PUSH ) { if ( enc->payLoad && enc->payLen > 0 ) { uint8_t* pdu = out->base + out->end; UPDATE_BOUND(out, enc->payLen); memcpy(pdu, enc->payLoad, enc->payLen); } ho->th_flags = TH_ACK; if ( enc->type == ENC_TCP_PUSH ) { ho->th_flags |= TH_PUSH; ho->th_win = htons(65535); } else { ho->th_flags |= TH_FIN; } } else { ho->th_flags = TH_RST | TH_ACK; } // in case of ip6 extension headers, this gets next correct enc->proto = IPPROTO_TCP; ho->th_sum = 0; if (IP_VER((IPHdr *)enc->ip_hdr) == 4) { pseudoheader ps; int len = BUFF_DIFF(out, ho); ps.sip = ((IPHdr *)(enc->ip_hdr))->ip_src.s_addr; ps.dip = ((IPHdr *)(enc->ip_hdr))->ip_dst.s_addr; ps.zero = 0; ps.protocol = IPPROTO_TCP; ps.len = htons((uint16_t)len); ho->th_sum = in_chksum_tcp(&ps, (uint16_t *)ho, len); } else { pseudoheader6 ps6; int len = BUFF_DIFF(out, ho); memcpy(ps6.sip, ((IP6RawHdr *)enc->ip_hdr)->ip6_src.s6_addr, sizeof(ps6.sip)); memcpy(ps6.dip, ((IP6RawHdr *)enc->ip_hdr)->ip6_dst.s6_addr, sizeof(ps6.dip)); ps6.zero = 0; ps6.protocol = IPPROTO_TCP; ps6.len = htons((uint16_t)len); ho->th_sum = in_chksum_tcp6(&ps6, (uint16_t *)ho, len); } return ENC_OK; } static ENC_STATUS TCP_Update (Packet* p, Layer* lyr, uint32_t* len) { TCPHdr* h = (TCPHdr*)(lyr->start); *len += GET_TCP_HDR_LEN(h) + p->dsize; if ( !PacketWasCooked(p) || (p->packet_flags & PKT_REBUILT_FRAG) ) { h->th_sum = 0; if (IS_IP4(p)) { pseudoheader ps; ps.sip = ((IPHdr *)(lyr-1)->start)->ip_src.s_addr; ps.dip = ((IPHdr *)(lyr-1)->start)->ip_dst.s_addr; ps.zero = 0; ps.protocol = IPPROTO_TCP; ps.len = htons((uint16_t)*len); h->th_sum = in_chksum_tcp(&ps, (uint16_t *)h, *len); } else { pseudoheader6 ps6; for (lyr--; lyr->proto != PROTO_IP6 && lyr != p->layers; lyr--); if (lyr->proto == PROTO_IP6) { memcpy(ps6.sip, ((IP6RawHdr *)lyr->start)->ip6_src.s6_addr, sizeof(ps6.sip)); memcpy(ps6.dip, ((IP6RawHdr *)lyr->start)->ip6_dst.s6_addr, sizeof(ps6.dip)); ps6.zero = 0; ps6.protocol = IPPROTO_TCP; ps6.len = htons((uint16_t)*len); h->th_sum = in_chksum_tcp6(&ps6, (uint16_t *)h, *len); } } } return ENC_OK; } static void TCP_Format (EncodeFlags f, const Packet* p, Packet* c, Layer* lyr) { TCPHdr* ch = (TCPHdr*)lyr->start; c->tcph = ch; if ( REVERSE(f) ) { int i = lyr - c->layers; TCPHdr* ph = (TCPHdr*)p->layers[i].start; ch->th_sport = ph->th_dport; ch->th_dport = ph->th_sport; } c->sp = ntohs(ch->th_sport); c->dp = ntohs(ch->th_dport); } //------------------------------------------------------------------------- // IP6 encoder //------------------------------------------------------------------------- static ENC_STATUS IP6_Encode (EncState* enc, Buffer* in, Buffer* out) { int len; uint32_t start = out->end; IP6RawHdr* hi = (IP6RawHdr*)enc->p->layers[enc->layer-1].start; IP6RawHdr* ho = (IP6RawHdr*)(out->base + out->end); PROTO_ID next = NextEncoder(enc); UPDATE_BOUND(out, sizeof(*ho)); ho->ip6flow = htonl(ntohl(hi->ip6flow) & 0xFFF00000); ho->ip6nxt = hi->ip6nxt; if ( FORWARD(enc) ) { memcpy(ho->ip6_src.s6_addr, hi->ip6_src.s6_addr, sizeof(ho->ip6_src.s6_addr)); memcpy(ho->ip6_dst.s6_addr, hi->ip6_dst.s6_addr, sizeof(ho->ip6_dst.s6_addr)); ho->ip6hops = FwdTTL(enc, hi->ip6hops); } else { memcpy(ho->ip6_src.s6_addr, hi->ip6_dst.s6_addr, sizeof(ho->ip6_src.s6_addr)); memcpy(ho->ip6_dst.s6_addr, hi->ip6_src.s6_addr, sizeof(ho->ip6_dst.s6_addr)); ho->ip6hops = RevTTL(enc, hi->ip6hops); } enc->ip_hdr = (uint8_t*)hi; enc->ip_len = sizeof(*hi); if ( next < PROTO_MAX ) { ENC_STATUS err = encoders[next].fencode(enc, in, out); if ( ENC_OK != err ) return err; } if ( enc->proto ) { ho->ip6nxt = enc->proto; enc->proto = 0; } len = out->end - start; ho->ip6plen = htons((uint16_t)(len - sizeof(*ho))); return ENC_OK; } static ENC_STATUS IP6_Update (Packet* p, Layer* lyr, uint32_t* len) { IP6RawHdr* h = (IP6RawHdr*)(lyr->start); int i = lyr - p->layers; // if we didn't trim payload or format this packet, // we may not know the actual lengths because not all // extension headers are decoded and we stop at frag6. // in such case we do not modify the packet length. if ( (p->packet_flags & PKT_MODIFIED) #ifdef NORMALIZER && !(p->packet_flags & PKT_RESIZED) #endif ) { *len = ntohs(h->ip6plen) + sizeof(*h); } else { if ( i + 1 == p->next_layer ) *len += lyr->length + p->dsize; // w/o all extension headers, can't use just the // fixed ip6 header length so we compute header delta else *len += lyr[1].start - lyr->start; // len includes header, remove for payload h->ip6plen = htons((uint16_t)(*len - sizeof(*h))); } return ENC_OK; } static void IP6_Format (EncodeFlags f, const Packet* p, Packet* c, Layer* lyr) { IP6RawHdr* ch = (IP6RawHdr*)lyr->start; if ( REVERSE(f) ) { int i = lyr - c->layers; IP6RawHdr* ph = (IP6RawHdr*)p->layers[i].start; memcpy(ch->ip6_src.s6_addr, ph->ip6_dst.s6_addr, sizeof(ch->ip6_src.s6_addr)); memcpy(ch->ip6_dst.s6_addr, ph->ip6_src.s6_addr, sizeof(ch->ip6_dst.s6_addr)); } if ( f & ENC_FLAG_DEF ) { int i = lyr - c->layers; if ( i + 1 == p->next_layer ) { uint8_t* b = (uint8_t*)p->ip6_extensions[p->ip6_frag_index].data; if ( b ) lyr->length = b - p->layers[i].start; } } sfiph_build(c, ch, AF_INET6); // set outer to inner so this will always wind pointing to inner c->raw_ip6h = ch; } //------------------------------------------------------------------------- // IP6 options functions //------------------------------------------------------------------------- static ENC_STATUS Opt6_Encode (EncState* enc, Buffer* in, Buffer* out) { // we don't encode ext headers PROTO_ID next = NextEncoder(enc); if ( next < PROTO_MAX ) { ENC_STATUS err = encoders[next].fencode(enc, in, out); if ( ENC_OK != err ) return err; } return ENC_OK; } static ENC_STATUS Opt6_Update (Packet* p, Layer* lyr, uint32_t* len) { int i = lyr - p->layers; *len += lyr->length; if ( i + 1 == p->next_layer ) *len += p->dsize; return ENC_OK; } //------------------------------------------------------------------------- // ICMP6 functions //------------------------------------------------------------------------- static inline int IcmpV6Code (EncodeType et) { switch ( et ) { case ENC_UNR_NET: return ICMP6_UNREACH_NET; case ENC_UNR_HOST: return ICMP6_UNREACH_HOST; case ENC_UNR_PORT: return ICMP6_UNREACH_PORT; case ENC_UNR_FW: return ICMP6_UNREACH_FILTER_PROHIB; default: break; } return ICMP6_UNREACH_PORT; } static inline ENC_STATUS UN6_Encode_Icmpv6Hdr( EncState *enc, IcmpHdr *ho, Buffer *out ) { enc->proto = IPPROTO_ICMPV6; UPDATE_BOUND(out, sizeof(*ho)); ho->type = 1; // dest unreachable ho->code = IcmpV6Code( enc->type ); ho->cksum = 0; ho->unused = 0; return ENC_OK; } static inline ENC_STATUS UN6_Encode_OrigIcmpV6( EncState *enc, Buffer *out ) { uint8_t* p; // copy original ip header p = out->base + out->end; UPDATE_BOUND(out, enc->ip_len); // TBD should be able to elminate enc->ip_hdr by using layer-2 memcpy(p, enc->ip_hdr, enc->ip_len); return ENC_OK; } static inline ENC_STATUS UN6_Encode_OrigUdp( EncState *enc, Buffer *out ) { uint8_t* p; uint8_t* hi = enc->p->layers[enc->layer-1].start; // copy original ip header p = out->base + out->end; UPDATE_BOUND(out, enc->ip_len); // TBD should be able to elminate enc->ip_hdr by using layer-2 memcpy(p, enc->ip_hdr, enc->ip_len); ((IP6RawHdr*)p)->ip6nxt = IPPROTO_UDP; // copy first 8 octets of original ip data (ie udp header) // TBD: copy up to minimum MTU worth of data p = out->base + out->end; UPDATE_BOUND(out, ICMP_UNREACH_DATA); memcpy(p, hi, ICMP_UNREACH_DATA); return ENC_OK; } static inline void UN6_Encode_Compute_Chksum( EncState *enc, IcmpHdr *ho, Buffer *out ) { pseudoheader6 ps6; int len; len = BUFF_DIFF(out, ho); memcpy(ps6.sip, ((IP6RawHdr *)enc->ip_hdr)->ip6_src.s6_addr, sizeof(ps6.sip)); memcpy(ps6.dip, ((IP6RawHdr *)enc->ip_hdr)->ip6_dst.s6_addr, sizeof(ps6.dip)); ps6.zero = 0; ps6.protocol = IPPROTO_ICMPV6; ps6.len = htons((uint16_t)(len)); ho->cksum = in_chksum_icmp6(&ps6, (uint16_t *)ho, len); } static ENC_STATUS UN6_ICMP6_Encode (EncState* enc, Buffer* in, Buffer* out) { IcmpHdr* ho = (IcmpHdr*)(out->base + out->end); #ifdef DEBUG if ( enc->type < ENC_UNR_NET ) return ENC_BAD_OPT; #endif UN6_Encode_Icmpv6Hdr( enc, ho, out); UN6_Encode_OrigIcmpV6( enc, out ); UN6_Encode_Compute_Chksum( enc, ho, out ); return ENC_OK; } static ENC_STATUS UN6_UDP_Encode(EncState* enc, Buffer* in, Buffer* out) { IcmpHdr* ho = (IcmpHdr*)(out->base + out->end); #ifdef DEBUG if ( enc->type < ENC_UNR_NET ) return ENC_BAD_OPT; #endif UN6_Encode_Icmpv6Hdr( enc, ho, out); UN6_Encode_OrigUdp( enc, out ); UN6_Encode_Compute_Chksum( enc, ho, out ); return ENC_OK; } static ENC_STATUS ICMP6_Update (Packet* p, Layer* lyr, uint32_t* len) { IcmpHdr* h = (IcmpHdr*)(lyr->start); *len += lyr->length + p->dsize; if ( !PacketWasCooked(p) || (p->packet_flags & PKT_REBUILT_FRAG) ) { pseudoheader6 ps6; for (lyr--; lyr->proto != PROTO_IP6 && lyr != p->layers; lyr--); if (lyr->proto == PROTO_IP6) { h->cksum = 0; memcpy(ps6.sip, ((IP6RawHdr *)lyr->start)->ip6_src.s6_addr, sizeof(ps6.sip)); memcpy(ps6.dip, ((IP6RawHdr *)lyr->start)->ip6_dst.s6_addr, sizeof(ps6.dip)); ps6.zero = 0; ps6.protocol = IPPROTO_ICMPV6; ps6.len = htons((uint16_t)*len); h->cksum = in_chksum_icmp6(&ps6, (uint16_t *)h, *len); } } return ENC_OK; } static void ICMP6_Format (EncodeFlags f, const Packet* p, Packet* c, Layer* lyr) { // TBD handle nested icmp6 layers c->icmp6h = (ICMP6Hdr*)lyr->start; } //------------------------------------------------------------------------- // GTP functions //------------------------------------------------------------------------- static ENC_STATUS update_GTP_length(GTPHdr* h, int gtp_total_len ) { /*The first 3 bits are version number*/ uint8_t version = (h->flag & 0xE0) >> 5; switch (version) { case 0: /*GTP v0*/ h->length = htons((uint16_t)(gtp_total_len - GTP_V0_HEADER_LEN)); break; case 1: /*GTP v1*/ h->length = htons((uint16_t)(gtp_total_len - GTP_MIN_LEN)); break; default: return ENC_BAD_PROTO; } return ENC_OK; } static ENC_STATUS GTP_Encode (EncState* enc, Buffer* in, Buffer* out) { int n = enc->p->layers[enc->layer-1].length; int len; GTPHdr* hi = (GTPHdr*) (enc->p->layers[enc->layer-1].start); GTPHdr* ho = (GTPHdr*)(out->base + out->end); uint32_t start = out->end; PROTO_ID next = NextEncoder(enc); UPDATE_BOUND(out, n); memcpy(ho, hi, n); if ( next < PROTO_MAX ) { ENC_STATUS err = encoders[next].fencode(enc, in, out); if (ENC_OK != err ) return err; } len = out->end - start; return( update_GTP_length(ho,len)); } static ENC_STATUS GTP_Update (Packet* p, Layer* lyr, uint32_t* len) { GTPHdr* h = (GTPHdr*)(lyr->start); *len += lyr->length; return( update_GTP_length(h,*len)); } //------------------------------------------------------------------------- // PPPoE functions //------------------------------------------------------------------------- static ENC_STATUS PPPoE_Encode (EncState* enc, Buffer* in, Buffer* out) { int n = enc->p->layers[enc->layer-1].length; int len; PPPoEHdr* hi = (PPPoEHdr*)(enc->p->layers[enc->layer-1].start); PPPoEHdr* ho = (PPPoEHdr*)(out->base + out->end); uint32_t start; PROTO_ID next = NextEncoder(enc); UPDATE_BOUND(out, n); memcpy(ho, hi, n); start = out->end; if ( next < PROTO_MAX ) { ENC_STATUS err = encoders[next].fencode(enc, in, out); if (ENC_OK != err ) return err; } len = out->end - start; ho->length = htons((uint16_t)len); return ENC_OK; } //------------------------------------------------------------------------- // MPLS functions //------------------------------------------------------------------------- static ENC_STATUS MPLS_Encode (EncState* enc, Buffer* in, Buffer* out) { uint16_t n; uint8_t* hi = NULL; uint8_t* ho; PROTO_ID next; SessionControlBlock* scb = (SessionControlBlock*)(enc->p->ssnptr); if ( FORWARD(enc) ) { if( scb != NULL && scb->clientMplsHeader != NULL ) { n = scb->clientMplsHeader->length; hi = scb->clientMplsHeader->start; } } else { if( scb != NULL && scb->serverMplsHeader != NULL ) { n = scb->serverMplsHeader->length; hi = scb->serverMplsHeader->start; } } if(!(hi) ) { n = enc->p->layers[enc->layer-1].length; hi = enc->p->layers[enc->layer-1].start; } ho = (uint8_t*)(out->base + out->end); next = NextEncoder(enc); UPDATE_BOUND(out, n); memcpy(ho, hi, n); if ( next < PROTO_MAX ) { ENC_STATUS err = encoders[next].fencode(enc, in, out); if (ENC_OK != err ) return err; } return ENC_OK; } //------------------------------------------------------------------------- // XXX (generic) functions //------------------------------------------------------------------------- static ENC_STATUS XXX_Encode (EncState* enc, Buffer* in, Buffer* out) { int n = enc->p->layers[enc->layer-1].length; uint8_t* hi = enc->p->layers[enc->layer-1].start; uint8_t* ho = (uint8_t*)(out->base + out->end); PROTO_ID next = NextEncoder(enc); UPDATE_BOUND(out, n); memcpy(ho, hi, n); if ( next < PROTO_MAX ) { ENC_STATUS err = encoders[next].fencode(enc, in, out); if (ENC_OK != err ) return err; } return ENC_OK; } // for general cases, may need to move dsize out of top, tcp, and // udp and put in Encode_Update() (then this can be eliminated and // xxx called instead). (another thought is to add data as a "layer"). #if 0 static ENC_STATUS Top_Update (Packet* p, Layer* lyr, uint32_t* len) { *len += lyr->length + p->dsize; return ENC_OK; } #endif static ENC_STATUS XXX_Update (Packet* p, Layer* lyr, uint32_t* len) { *len += lyr->length; return ENC_OK; } static ENC_STATUS GRE_Update (Packet* p, Layer* lyr, uint32_t* len) { GREHdr* h = (GREHdr*)(lyr->start); *len += lyr->length; if(GRE_CHKSUM(h)) { if(lyr->length >= 6) { uint16_t *csum = (uint16_t *) (lyr->start + 4); *csum = 0; *csum = ones_compl_checksum((const char *)h, *len); } } return ENC_OK; } static void XXX_Format (EncodeFlags f, const Packet* p, Packet* c, Layer* lyr) { // nop } static ENC_STATUS GRE_Encode (EncState* enc, Buffer* in, Buffer* out) { int n = enc->p->layers[enc->layer-1].length; GREHdr* hi = (GREHdr *)enc->p->layers[enc->layer-1].start; GREHdr* ho = (GREHdr *)(out->base + out->end); PROTO_ID next = NextEncoder(enc); UPDATE_BOUND(out, n); memcpy(ho, hi, n); if ( next < PROTO_MAX ) { ENC_STATUS err = encoders[next].fencode(enc, in, out); if (ENC_OK != err ) return err; } if(GRE_CHKSUM(ho)) { if(n >= 6) { int len = BUFF_DIFF(out, ho); uint16_t *csum = (uint16_t *) ((uint8_t *)ho + 4); *csum = 0; *csum = ones_compl_checksum((const char *)ho, len); } } return ENC_OK; } //------------------------------------------------------------------------- // function table: // these must be in the same order PROTO_IDs are defined! // all entries must have a function //------------------------------------------------------------------------- static EncoderFunctions encoders[PROTO_MAX] = { { Eth_Encode, Eth_Update, Eth_Format }, { FPath_Encode, FPath_Update, FPath_Format }, // FabricPath { XXX_Encode, XXX_Update, XXX_Format }, // Cisco Metadata { IP4_Encode, IP4_Update, IP4_Format }, { UN4_Encode, ICMP4_Update, ICMP4_Format }, { XXX_Encode, XXX_Update, XXX_Format, }, // ICMP_IP4 { UDP_Encode, UDP_Update, UDP_Format }, { TCP_Encode, TCP_Update, TCP_Format }, { IP6_Encode, IP6_Update, IP6_Format }, { Opt6_Encode, Opt6_Update, XXX_Format }, // IP6 Hop Opts { Opt6_Encode, Opt6_Update, XXX_Format }, // IP6 Dst Opts { UN6_ICMP6_Encode, ICMP6_Update, ICMP6_Format }, { XXX_Encode, XXX_Update, XXX_Format, }, // ICMP_IP6 { XXX_Encode, XXX_Update, VLAN_Format }, #ifdef GRE { GRE_Encode, GRE_Update, GRE_Format }, { XXX_Encode, XXX_Update, XXX_Format }, // ERSPAN #endif { PPPoE_Encode,XXX_Update, XXX_Format }, { XXX_Encode, XXX_Update, XXX_Format }, // PPP Encap #ifdef MPLS { MPLS_Encode, XXX_Update, XXX_Format }, // MPLS #endif { XXX_Encode, XXX_Update, XXX_Format, }, // ARP { GTP_Encode, GTP_Update, XXX_Format, }, // GTP { XXX_Encode, XXX_Update, XXX_Format, } // Auth Header }; snort-2.9.15.1/src/encode.h0000644000175200017520000001101213571422607012240 00000000000000/* $Id$ */ /**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2005-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ // @file encode.h // @author Russ Combs #ifndef __ENCODE_H__ #define __ENCODE_H__ #include "decode.h" extern Packet *encode_pkt; extern uint64_t total_rebuilt_pkts; void Encode_Init(void); void Encode_Term(void); typedef enum { ENC_TCP_FIN, ENC_TCP_RST, ENC_UNR_NET, ENC_UNR_HOST, ENC_UNR_PORT, ENC_UNR_FW, ENC_TCP_PUSH, ENC_UDP, ENC_MAX } EncodeType; #define ENC_FLAG_FWD 0x80000000 // send in forward direction #define ENC_FLAG_SEQ 0x40000000 // VAL bits contain seq adj #define ENC_FLAG_ID 0x20000000 // use randomized IP ID #define ENC_FLAG_NET 0x10000000 // stop after innermost network (ip4/6) layer #define ENC_FLAG_DEF 0x08000000 // stop before innermost ip4 opts or ip6 frag header #define ENC_FLAG_RAW 0x04000000 // don't encode outer eth header (this is raw ip) #define ENC_FLAG_RST_CLNT 0x02000000 // finish with a client RST packet #define ENC_FLAG_RST_SRVR 0x01000000 // finish with a server RST packet #define ENC_FLAG_VAL 0x00FFFFFF // bits for adjusting seq and/or ack typedef uint32_t EncodeFlags; // 255 is max pseudo-random flush point; eth mtu ensures that maximum flushes // are not trimmed which throws off the tracking total in stream5_paf.c #define MAXIMUM_PAF_MAX (IP_MAXPACKET - ETHERNET_MTU - 255) // ICMPv6 Reason codes...ones used by encode are defined here now, ICMP ones // are defind in header files from dnet, but none exist for ICMPv6, if these // become defined in a system header file those should be used and these removed #define ICMP6_UNREACH_NET 0x00 #define ICMP6_UNREACH_HOST 0x03 #define ICMP6_UNREACH_PORT 0x04 #define ICMP6_UNREACH_FILTER_PROHIB 0x01 // orig must be the current packet from the interface to // ensure proper encoding (not the reassembled packet). // len is number of bytes in the encoded packet upon return // (or 0 if the returned pointer is null). const uint8_t* Encode_Reject( EncodeType, EncodeFlags, const Packet* orig, uint32_t* len); const uint8_t* Encode_Response( EncodeType, EncodeFlags, const Packet* orig, uint32_t* len, const uint8_t* payLoad, uint32_t payLen); // allocate a Packet for later formatting (cloning) Packet* Encode_New(void); // release the allocated Packet void Encode_Delete(Packet*); // orig is the wire pkt; clone was obtained with New() int Encode_Format(EncodeFlags, const Packet* orig, Packet* clone, PseudoPacketType); #ifdef HAVE_DAQ_ADDRESS_SPACE_ID int Encode_Format_With_DAQ_Info ( EncodeFlags f, const Packet* p, Packet* c, PseudoPacketType type, const DAQ_PktHdr_t*, uint32_t opaque); #elif defined(HAVE_DAQ_ACQUIRE_WITH_META) int Encode_Format_With_DAQ_Info ( EncodeFlags f, const Packet* p, Packet* c, PseudoPacketType type, uint32_t opaque); #endif // update length and checksum fields in layers and caplen, etc. void Encode_Update(Packet*); // Set the destination MAC address void Encode_SetDstMAC(uint8_t* ); static inline void Encode_SetPkt(Packet* p) { encode_pkt = p; } static inline Packet* Encode_GetPkt(void) { return encode_pkt; } static inline void Encode_Reset(void) { Encode_SetPkt(NULL); } static inline void UpdateRebuiltPktCount(void) { total_rebuilt_pkts++; } static inline uint64_t GetRebuiltPktCount(void) { return total_rebuilt_pkts; } static inline uint16_t Encode_GetMaxPayload(Packet* p) { Layer l; if(!p->next_layer) return 0; l = p->layers[p->next_layer - 1]; return ETHERNET_MTU - (l.start - p->layers[0].start) - l.length; } #endif // __ENCODE_H__ snort-2.9.15.1/src/active.c0000644000175200017520000003266513571422607012272 00000000000000/* $Id$ */ /**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2005-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ // @file active.c // @author Russ Combs #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_DUMBNET_H #include #else #include #endif #include "active.h" #include "session_api.h" #include "stream_api.h" #include "snort.h" #include "preprocessors/spp_frag3.h" #ifdef ACTIVE_RESPONSE #include "encode.h" #include "sfdaq.h" #endif // these can't be pkt flags because we do the handling // of these flags following all processing and the drop // or response may have been produced by a pseudopacket. tActiveDrop active_drop_pkt = ACTIVE_ALLOW; tActiveSsnDrop active_drop_ssn = ACTIVE_SSN_ALLOW; // TBD consider performance of replacing active_drop_pkt/ssn // with a active_verdict. change over if it is a wash or better. int active_tunnel_bypass = 0; int active_suspend = 0; #ifdef ACTIVE_RESPONSE int active_have_rsp = 0; #define MAX_ATTEMPTS 20 static uint8_t s_attempts = 0; static int s_enabled = 0; static eth_t* s_link = NULL; static ip_t* s_ipnet = NULL; static void* s_rejData, *s_rspData; static Active_ResponseFunc s_rejFunc = NULL, s_rspFunc = NULL; static int Active_Open(const char*); static int Active_Close(void); static int Active_SendEth(const DAQ_PktHdr_t*, int, const uint8_t*, uint32_t); static int Active_SendIp(const DAQ_PktHdr_t*, int, const uint8_t*, uint32_t); typedef int (*send_t) ( const DAQ_PktHdr_t* h, int rev, const uint8_t* buf, uint32_t len); static send_t s_send = DAQ_Inject; static uint64_t s_injects = 0; static inline PROTO_ID GetInnerProto (const Packet* p) { if ( !p->next_layer ) return PROTO_MAX; return ( p->layers[p->next_layer-1].proto ); } //-------------------------------------------------------------------- // this implementation ensures that flexible responses // take precedence over active responses. int Active_QueueReject (void) { if ( Active_Suspended() ) return 0; if ( !s_rejFunc ) { s_rejFunc = (Active_ResponseFunc)Active_KillSession; s_rejData = NULL; active_have_rsp = 1; } return 0; } int Active_QueueResponse (Active_ResponseFunc f, void* pv) { if ( Active_Suspended() ) return 0; if ( !s_rspFunc ) { s_rspFunc = f; s_rspData = pv; active_have_rsp = 1; } return 0; } // helper function static inline void Active_ClearQueue (void) { s_rejFunc = s_rspFunc = NULL; s_rejData = s_rspData = NULL; } int Active_ResetQueue () { Active_ClearQueue(); return 0; } int Active_SendResponses (Packet* p) { if ( s_rspFunc ) { s_rspFunc(p, s_rspData); } else if ( s_rejFunc ) { s_rejFunc(p, s_rejData); } else { return 0; } if ( p->ssnptr && session_api ) { session_api->init_active_response(p, p->ssnptr); } Active_ClearQueue(); return 1; } //-------------------------------------------------------------------- void Active_KillSession (Packet* p, EncodeFlags* pf) { EncodeFlags flags = pf ? *pf : ENC_FLAG_FWD; if ( !IsIP(p) ) return; switch ( GET_IPH_PROTO(p) ) { case IPPROTO_TCP: Active_SendReset(p, 0); if ( flags & ENC_FLAG_FWD ) Active_SendReset(p, ENC_FLAG_FWD); break; default: if ( Active_PacketForceDropped() ) Active_SendUnreach(p, ENC_UNR_FW); else Active_SendUnreach(p, ENC_UNR_PORT); break; } } //-------------------------------------------------------------------- int Active_Init (SnortConfig* sc) { s_attempts = sc->respond_attempts; if ( s_attempts > MAX_ATTEMPTS ) s_attempts = MAX_ATTEMPTS; if ( s_enabled && !s_attempts ) s_attempts = 1; if ( s_enabled && (!DAQ_CanInject() || sc->respond_device) ) { if ( ScReadMode() || Active_Open(sc->respond_device) ) { LogMessage("WARNING: active responses disabled since DAQ " "can't inject packets.\n"); #ifndef REG_TEST s_attempts = s_enabled = 0; #endif } if (NULL != sc->eth_dst) Encode_SetDstMAC(sc->eth_dst); } return 0; } int Active_Term (void) { Active_Close(); return 0; } int Active_IsEnabled (void) { return s_enabled; } void Active_SetEnabled (int on_off) { if ( !on_off || on_off > s_enabled ) s_enabled = on_off; } static inline uint32_t GetFlags (void) { uint32_t flags = ENC_FLAG_ID; if ( DAQ_RawInjection() || s_ipnet ) flags |= ENC_FLAG_RAW; return flags; } //-------------------------------------------------------------------- static uint32_t Strafe(int, uint32_t, const Packet*); void Active_SendReset(Packet* p, EncodeFlags ef) { int i; uint32_t flags = (GetFlags() | ef) & ~ENC_FLAG_VAL; uint32_t value = ef & ENC_FLAG_VAL; for ( i = 0; i < s_attempts; i++ ) { uint32_t len = 0; const uint8_t* rej; value = Strafe(i, value, p); rej = Encode_Reject(ENC_TCP_RST, flags|value, p, &len); if ( !rej ) return; s_send(p->pkth, !(ef & ENC_FLAG_FWD), rej, len); } } void Active_SendUnreach(Packet* p, EncodeType type) { uint32_t len; const uint8_t* rej; uint32_t flags = GetFlags(); if ( !s_attempts ) return; rej = Encode_Reject(type, flags, p, &len); if ( !rej ) return; s_send(p->pkth, 1, rej, len); } bool Active_SendData ( Packet* p, EncodeFlags flags, const uint8_t* buf, uint32_t blen) { uint16_t toSend; uint16_t sent; uint16_t maxPayload; const uint8_t* seg; uint32_t plen; EncodeFlags tmp_flags; flags |= GetFlags(); flags &= ~ENC_FLAG_VAL; if (flags & ENC_FLAG_RST_SRVR) { plen = 0; tmp_flags = flags ^ ENC_FLAG_FWD; seg = Encode_Response(ENC_TCP_RST, tmp_flags, p, &plen, NULL, 0); if ( seg ) s_send(p->pkth, !(tmp_flags & ENC_FLAG_FWD), seg, plen); } flags |= ENC_FLAG_SEQ; sent = 0; maxPayload = Encode_GetMaxPayload(p); if(maxPayload) { do{ plen = 0; toSend = blen > maxPayload ? maxPayload : blen; flags = (flags & ~ENC_FLAG_VAL) | sent; seg = Encode_Response(ENC_TCP_PUSH, flags, p, &plen, buf, toSend); if ( !seg ) return false; s_send(p->pkth, !(flags & ENC_FLAG_FWD), seg, plen); buf += toSend; sent += toSend; } while(blen -= toSend); } plen = 0; flags = (flags & ~ENC_FLAG_VAL) | sent; seg = Encode_Response(ENC_TCP_FIN, flags, p, &plen, NULL, 0); if ( !seg ) return false; s_send(p->pkth, !(flags & ENC_FLAG_FWD), seg, plen); if (flags & ENC_FLAG_RST_CLNT) { sent++; plen = 0; flags = (flags & ~ENC_FLAG_VAL) | sent; seg = Encode_Response(ENC_TCP_RST, flags, p, &plen, NULL, 0); if ( seg ) s_send(p->pkth, !(flags & ENC_FLAG_FWD), seg, plen); } return true; } void Active_InjectData ( Packet* p, EncodeFlags flags, const uint8_t* buf, uint32_t blen) { uint32_t plen = 0; const uint8_t* seg; if ( !s_attempts ) return; flags |= GetFlags(); flags &= ~ENC_FLAG_VAL; seg = Encode_Response(ENC_TCP_PUSH, flags, p, &plen, buf, blen); if ( !seg ) return; s_send(p->pkth, !(flags & ENC_FLAG_FWD), seg, plen); } void Active_UDPInjectData ( Packet* p, EncodeFlags flags, const uint8_t* buf, uint32_t blen) { uint32_t plen = 0; const uint8_t* seg; if ( !s_attempts ) return; flags |= GetFlags(); seg = Encode_Response(ENC_UDP, flags, p, &plen, buf, blen); if ( !seg ) return; s_send(p->pkth, !(flags & ENC_FLAG_FWD ), seg , plen); } //-------------------------------------------------------------------- int Active_IsRSTCandidate(const Packet* p) { if ( GetInnerProto(p) != PROTO_TCP ) return 0; if ( !p->tcph ) return 0; /* ** This ensures that we don't reset packets that we just ** spoofed ourselves, thus inflicting a self-induced DOS ** attack. */ return ( !(p->tcph->th_flags & TH_RST) ); } int Active_IsUNRCandidate(const Packet* p) { // FIXTHIS allow unr to tcp/udp/icmp4/icmp6 only or for all switch ( GetInnerProto(p) ) { case PROTO_UDP: case PROTO_TCP: case PROTO_ICMP4: case PROTO_ICMP6: return 1; default: break; } return 0; } //-------------------------------------------------------------------- // TBD strafed sequence numbers could be divided by window // scaling if present. static uint32_t Strafe (int i, uint32_t flags, const Packet* p) { flags &= ENC_FLAG_VAL; switch ( i ) { case 0: flags |= ENC_FLAG_SEQ; break; case 1: flags = p->dsize; flags &= ENC_FLAG_VAL; flags |= ENC_FLAG_SEQ; break; case 2: case 3: flags += (p->dsize << 1); flags &= ENC_FLAG_VAL; flags |= ENC_FLAG_SEQ; break; case 4: flags += (p->dsize << 2); flags &= ENC_FLAG_VAL; flags |= ENC_FLAG_SEQ; break; default: flags += (ntohs(p->tcph->th_win) >> 1); flags &= ENC_FLAG_VAL; flags |= ENC_FLAG_SEQ; break; } return flags; } #endif // ACTIVE_RESPONSE //-------------------------------------------------------------------- // support for decoder and rule actions static inline void _Active_ForceIgnoreSession(Packet *p) { if (p->ssnptr && stream_api) { stream_api->drop_packet(p); } //drop this and all following fragments frag3DropAllFragments(p); } static inline void _Active_DoIgnoreSession(Packet *p) { if ( ScIpsInlineMode() || ScTreatDropAsIgnore() ) { _Active_ForceIgnoreSession(p); } } int Active_IgnoreSession (Packet* p) { Active_DropPacket(p); _Active_DoIgnoreSession(p); return 0; } int Active_ForceDropAction(Packet *p) { if ( !IsIP(p) ) return 0; // explicitly drop packet Active_ForceDropPacket(); switch ( GET_IPH_PROTO(p) ) { case IPPROTO_TCP: case IPPROTO_UDP: Active_DropSession(p); _Active_ForceIgnoreSession(p); } return 0; } static inline int _Active_DoReset(Packet *p) { #ifdef ACTIVE_RESPONSE if ( !Active_IsEnabled() ) return 0; if ( !IPH_IS_VALID(p) ) return 0; switch ( GET_IPH_PROTO(p) ) { case IPPROTO_TCP: if ( Active_IsRSTCandidate(p) ) Active_QueueReject(); break; // FIXTHIS send unr to udp/icmp4/icmp6 only or for all non-tcp? case IPPROTO_UDP: case IPPROTO_ICMP: case IPPROTO_ICMPV6: if ( Active_IsUNRCandidate(p) ) Active_QueueReject(); break; } #endif return 0; } int Active_DropAction (Packet* p) { Active_IgnoreSession(p); #ifdef ACTIVE_RESPONSE if (( s_enabled < 2 ) || (active_drop_ssn == ACTIVE_SSN_DROP_WITHOUT_RESET)) return 0; #endif return _Active_DoReset(p); } int Active_ForceDropResetAction(Packet *p) { Active_ForceDropAction(p); return _Active_DoReset(p); } //-------------------------------------------------------------------- // support for non-DAQ injection #ifdef ACTIVE_RESPONSE static int Active_Open (const char* dev) { if ( dev && strcasecmp(dev, "ip") ) { s_link = eth_open(dev); if ( !s_link ) FatalError("%s: can't open %s!\n", "Active response", dev); s_send = Active_SendEth; } else { s_ipnet = ip_open(); if ( !s_ipnet ) FatalError("%s: can't open ip!\n", "Active response"); s_send = Active_SendIp; } return ( s_link || s_ipnet ) ? 0 : -1; } static int Active_Close (void) { if ( s_link ) eth_close(s_link); if ( s_ipnet ) ip_close(s_ipnet); s_link = NULL; s_ipnet = NULL; return 0; } static int Active_SendEth ( const DAQ_PktHdr_t* h, int rev, const uint8_t* buf, uint32_t len) { ssize_t sent = eth_send(s_link, buf, len); s_injects++; return ( (uint32_t) sent != len ); } static int Active_SendIp ( const DAQ_PktHdr_t* h, int rev, const uint8_t* buf, uint32_t len) { ssize_t sent = ip_send(s_ipnet, buf, len); s_injects++; return ( (uint32_t) sent != len ); } uint64_t Active_GetInjects (void) { return s_injects; } #endif snort-2.9.15.1/src/active.h0000644000175200017520000001777613571422607012305 00000000000000/* $Id$ */ /**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2005-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ // @file active.h // @author Russ Combs #ifndef __ACTIVE_H__ #define __ACTIVE_H__ #include "decode.h" #include "snort.h" #ifdef ACTIVE_RESPONSE #include "encode.h" int Active_Init(SnortConfig*); int Active_Term(void); typedef void (*Active_ResponseFunc)(Packet*, void* data); int Active_QueueReject(void); int Active_QueueResponse(Active_ResponseFunc, void*); int Active_ResetQueue(void); // this must be called on the wire packet and not a // reassembled packet so that encoding is correct. int Active_SendResponses(Packet*); uint64_t Active_GetInjects(void); // NULL flags implies ENC_FLAG_FWD void Active_KillSession(Packet*, EncodeFlags*); void Active_SendReset(Packet*, EncodeFlags); void Active_SendUnreach(Packet*, EncodeType); bool Active_SendData(Packet*, EncodeFlags, const uint8_t* buf, uint32_t len); void Active_InjectData(Packet*, EncodeFlags, const uint8_t* buf, uint32_t len); void Active_UDPInjectData(Packet*, EncodeFlags, const uint8_t* buf, uint32_t len); int Active_IsRSTCandidate(const Packet*); int Active_IsUNRCandidate(const Packet*); int Active_IsEnabled(void); void Active_SetEnabled(int on_off); #endif // ACTIVE_RESPONSE typedef enum { ACTIVE_ALLOW, // don't drop ACTIVE_CANT_DROP, // can't drop ACTIVE_WOULD_DROP, // would drop ACTIVE_DROP, // should drop ACTIVE_FORCE_DROP, // must drop ACTIVE_RETRY // queue for retry } tActiveDrop; typedef enum { ACTIVE_SSN_ALLOW, // don't drop ACTIVE_SSN_DROP, // can drop and reset ACTIVE_SSN_DROP_WITHOUT_RESET // can drop but without reset } tActiveSsnDrop; extern tActiveDrop active_drop_pkt; extern tActiveSsnDrop active_drop_ssn; #ifdef ACTIVE_RESPONSE extern int active_have_rsp; #endif extern int active_tunnel_bypass; extern int active_suspend; static inline void Active_Reset (void) { active_drop_pkt = ACTIVE_ALLOW; active_drop_ssn = ACTIVE_SSN_ALLOW; #ifdef ACTIVE_RESPONSE active_have_rsp = 0; #endif active_tunnel_bypass = 0; } static inline void Active_Suspend (void) { active_suspend = 1; } static inline void Active_Resume (void) { active_suspend = 0; } static inline bool Active_Suspended (void) { return ( active_suspend != 0 ); } static inline tActiveDrop Active_GetDisposition (void) { return active_drop_pkt; } static inline void Active_CantDrop(void) { #if 0 // not yet supported if ( active_drop_pkt < ACTIVE_CANT_DROP ) active_drop_pkt = ACTIVE_CANT_DROP; #else if ( active_drop_pkt < ACTIVE_WOULD_DROP ) active_drop_pkt = ACTIVE_WOULD_DROP; #endif } static inline void Active_ForceDropPacket( void ) { if ( Active_Suspended() ) Active_CantDrop(); else active_drop_pkt = ACTIVE_FORCE_DROP; } static inline void Active_NapDropPacket( const Packet* p ) { if ( Active_Suspended() ) { Active_CantDrop(); } else if ( active_drop_pkt != ACTIVE_FORCE_DROP ) { if ( ScNapInlineMode() ) { if ( DAQ_GetInterfaceMode(p->pkth) == DAQ_MODE_INLINE ) active_drop_pkt = ACTIVE_DROP; else active_drop_pkt = ACTIVE_WOULD_DROP; } else if (ScNapInlineTestMode()) { active_drop_pkt = ACTIVE_WOULD_DROP; } } } static inline void Active_DropPacket( const Packet* p ) { if ( Active_Suspended() ) { Active_CantDrop(); } else if ( active_drop_pkt != ACTIVE_FORCE_DROP ) { if ( ScIpsInlineMode() ) { if ( DAQ_GetInterfaceMode(p->pkth) == DAQ_MODE_INLINE ) active_drop_pkt = ACTIVE_DROP; else active_drop_pkt = ACTIVE_WOULD_DROP; } else if (ScIpsInlineTestMode()) { active_drop_pkt = ACTIVE_WOULD_DROP; } } } static inline bool Active_DAQRetryPacket( const Packet *p ) { bool retry_queued = false; if( ( active_drop_pkt == ACTIVE_ALLOW ) && DAQ_CanRetry( ) ) { if ( DAQ_GetInterfaceMode(p->pkth) == DAQ_MODE_INLINE ) { active_drop_pkt = ACTIVE_RETRY; retry_queued = true; } } return retry_queued; } static inline void Active_DAQDropPacket(const Packet *p) { if ( Active_Suspended() ) { Active_CantDrop(); } else if ( active_drop_pkt != ACTIVE_FORCE_DROP ) { if ( DAQ_GetInterfaceMode(p->pkth) == DAQ_MODE_INLINE ) active_drop_pkt = ACTIVE_DROP; else active_drop_pkt = ACTIVE_WOULD_DROP; } } static inline void _Active_DropSession (const Packet* p, tActiveSsnDrop ssn_drop) { if ( Active_Suspended() ) { Active_CantDrop(); return; } active_drop_ssn = ssn_drop; Active_DropPacket(p); } static inline void _Active_ForceDropSession (tActiveSsnDrop ssn_drop) { if ( Active_Suspended() ) { Active_CantDrop(); return; } active_drop_ssn = ssn_drop; Active_ForceDropPacket(); } static inline void Active_DropSession (const Packet* p) { _Active_DropSession(p, ACTIVE_SSN_DROP); } static inline void Active_ForceDropSession (void) { _Active_ForceDropSession(ACTIVE_SSN_DROP); } static inline void Active_DropSessionWithoutReset (const Packet* p) { _Active_DropSession(p, ACTIVE_SSN_DROP_WITHOUT_RESET); } static inline void Active_ForceDropSessionWithoutReset (void) { _Active_ForceDropSession(ACTIVE_SSN_DROP_WITHOUT_RESET); } static inline int Active_PacketWouldBeDropped (void) { return (active_drop_pkt == ACTIVE_WOULD_DROP ); } static inline int Active_PacketForceDropped (void) { return (active_drop_pkt == ACTIVE_FORCE_DROP ); } static inline int Active_PacketWasDropped (void) { return ( active_drop_pkt >= ACTIVE_DROP ); } static inline int Active_RetryIsPending (void) { return ( active_drop_pkt == ACTIVE_RETRY ); } static inline int Active_SessionWasDropped (void) { return ( active_drop_ssn != ACTIVE_SSN_ALLOW ); } #ifdef ACTIVE_RESPONSE static inline int Active_ResponseQueued (void) { return ( active_have_rsp != ACTIVE_SSN_ALLOW ); } #endif static inline void Active_SetTunnelBypass (void) { active_tunnel_bypass++; } static inline void Active_ClearTunnelBypass (void) { active_tunnel_bypass--; } static inline int Active_GetTunnelBypass (void) { return ( active_tunnel_bypass > 0 ); } // drops current session with active response invoked // for rules with action = drop | sdrop | reject int Active_DropAction(Packet*); // drops current session w/o active response invoked // for rules with custom response = resp3 | react int Active_IgnoreSession(Packet*); // force drops the current session w/o active response invoked // ignores policy/inline test mode and treat drop as alert int Active_ForceDropAction(Packet *p); // force drops the current session with active response invoked // ignores policy/inline test mode and treat drop as alert int Active_ForceDropResetAction(Packet *p); const char* Active_GetDispositionString(); #endif // __ACTIVE_H__ snort-2.9.15.1/src/log.c0000644000175200017520000017620513571422607011577 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifdef HAVE_STRINGS_H #include #endif #ifndef WIN32 #include #include #include #endif /* !WIN32 */ #include #include #include "log.h" #include "rules.h" #include "treenodes.h" #include "util.h" #include "snort_debug.h" #include "signature.h" #include "util_net.h" #include "snort_bounds.h" #include "obfuscation.h" #include "detection_util.h" #include "detect.h" #include "snort.h" extern OptTreeNode *otn_tmp; /* global ptr to current rule data */ char *data_dump_buffer; /* printout buffer for PrintNetData */ int data_dump_buffer_size = 0;/* size of printout buffer */ int dump_size; /* amount of data to print */ extern int IsGzipData(void *); extern int IsJSNormData(void *); void AllocDumpBuf(); /***************** LOG ASCII ROUTINES *******************/ #ifndef NO_NON_ETHER_DECODER #endif /* * Function: PrintNetData(FILE *, u_char *,int, Packet *) * * Purpose: Do a side by side dump of a buffer, hex dump of buffer bytes on * the left, decoded ASCII on the right. * * Arguments: fp => ptr to stream to print to * start => pointer to buffer data * len => length of data buffer * * Returns: void function */ void PrintNetData(FILE * fp, const u_char * start, const int len, Packet *p) { char *end; /* ptr to buffer end */ int i; /* counter */ int j; /* counter */ int dbuf_size; /* data buffer size */ int done; /* flag */ char *data; /* index pointer */ char *frame_ptr; /* we use 66 byte frames for a printed line */ char *d_ptr; /* data pointer into the frame */ char *c_ptr; /* char pointer into the frame */ char conv[] = "0123456789ABCDEF"; /* xlation lookup table */ int next_layer, ip_start, ip_ob_start, ip_ob_end, byte_pos; next_layer = ip_start = byte_pos = 0; ip_ob_start = ip_ob_end = -1; /* initialization */ done = 0; /* zero, print a and get out */ if(!len) { fputc('\n', fp); return; } if(start == NULL) { printf("Got NULL ptr in PrintNetData()\n"); return; } end = (char*) (start + (len - 1)); /* set the end of buffer ptr */ if(len > IP_MAXPACKET) { if (ScLogVerbose()) { printf("Got bogus buffer length (%d) for PrintNetData, defaulting to 16 bytes!\n", len); } if (ScVerboseByteDump()) { dbuf_size = (FRAME_SIZE + 8) + (FRAME_SIZE + 8) + 1; } else { dbuf_size = FRAME_SIZE + FRAME_SIZE + 1; } /* dbuf_size = 66 + 67; */ end = (char*) (start + 15); } else { if (ScVerboseByteDump()) { /* figure out how big the printout data buffer has to be */ dbuf_size = ((len / 16) * (FRAME_SIZE + 8)) + (FRAME_SIZE + 8) + 1; } else { /* figure out how big the printout data buffer has to be */ dbuf_size = ((len / 16) * FRAME_SIZE) + FRAME_SIZE + 1; } /* dbuf_size = ((len / 16) * 66) + 67; */ } /* generate the buffer */ if (data_dump_buffer == NULL) { AllocDumpBuf(); } if (data_dump_buffer == NULL) FatalError("Failed allocating %X bytes to data_dump_buffer!\n", data_dump_buffer_size); /* clean it out */ memset(data_dump_buffer, 0x20, dbuf_size); /* set the byte buffer pointer to step thru the data buffer */ data = (char*) start; /* set the frame pointer to the start of the printout buffer */ frame_ptr = data_dump_buffer; /* initialize counters and frame index pointers */ i = 0; j = 0; if(p && ScObfuscate() ) { next_layer = p->next_layer; for ( i = 0; i < next_layer; i++ ) { if ( p->layers[i].proto == PROTO_IP4 || p->layers[i].proto == PROTO_IP6 ) { if(p->layers[i].length && p->layers[i].start) break; } } ip_start = p->layers[i].start - start; if(ip_start > 0 ) { ip_ob_start = ip_start + 10; if(p->layers[i].proto == PROTO_IP4) ip_ob_end = ip_ob_start + 2 + 2*(sizeof(struct in_addr)); else ip_ob_end = ip_ob_start + 2 + 2*(sizeof(struct in6_addr)); } i=0; } /* loop thru the whole buffer */ while(!done) { if (ScVerboseByteDump()) { d_ptr = frame_ptr + 8; c_ptr = (frame_ptr + 8 + C_OFFSET); SnortSnprintf(frame_ptr, (data_dump_buffer + data_dump_buffer_size) - frame_ptr, "0x%04X: ", j); j += 16; } else { d_ptr = frame_ptr; c_ptr = (frame_ptr + C_OFFSET); } /* process 16 bytes per frame */ for(i = 0; i < 16; i++, byte_pos++) { if(ScObfuscate() && ((byte_pos >= ip_ob_start) && (byte_pos < ip_ob_end))) { *d_ptr = 'X'; d_ptr++; *d_ptr = 'X'; d_ptr++; *d_ptr = 0x20; d_ptr++; *c_ptr = 'X'; } else { /* * look up the ASCII value of the first nybble of the current * data buffer */ *d_ptr = conv[((*data & 0xFF) >> 4)]; d_ptr++; /* look up the second nybble */ *d_ptr = conv[((*data & 0xFF) & 0x0F)]; d_ptr++; /* put a space in between */ *d_ptr = 0x20; d_ptr++; /* print out the char equivalent */ if(*data > 0x1F && *data < 0x7F) *c_ptr = (char) (*data & 0xFF); else *c_ptr = 0x2E; } c_ptr++; /* increment the pointer or finish up */ if(data < end) data++; else { *c_ptr = '\n'; c_ptr++; *c_ptr = '\n'; c_ptr++; *c_ptr = 0; dump_size = (int) (c_ptr - data_dump_buffer); fwrite(data_dump_buffer, dump_size, 1, fp); //ClearDumpBuf(); return; } } *c_ptr = '\n'; if (ScVerboseByteDump()) { frame_ptr += (FRAME_SIZE + 8); } else { frame_ptr += FRAME_SIZE; } } //ClearDumpBuf(); } /* * Function: PrintCharData(FILE *, char *,int) * * Purpose: Dump the ASCII data from a packet * the left, decoded ASCII on the right. * * Arguments: fp => ptr to stream to print to * data => pointer to buffer data * data_len => length of data buffer * * Returns: void function */ void PrintCharData(FILE * fp, const char *data, int data_len) { int bytes_processed; /* count of bytes in the data buffer * processed so far */ int linecount = 0; /* number of lines in this dump */ const char *index; /* index pointer into the data buffer */ char *ddb_ptr; /* index pointer into the data_dump_buffer */ int size; /* if there's no data, return */ if(data == NULL) { return; } /* setup the pointers and counters */ bytes_processed = data_len; index = data; /* allocate a buffer to print the data to */ //data_dump_buffer = (char *) calloc(data_len + (data_len >> 6) + 2, sizeof(char)); if (data_dump_buffer == NULL) { AllocDumpBuf(); } size = (data_len + (data_len >> 6) + 2) * sizeof(char); /* Based on data_len < 65535, this should never happen, but check just in * case sizeof(char) is big or something. */ if (data_dump_buffer_size < size) { data_dump_buffer_size = size; ClearDumpBuf(); /* Reallocate for a bigger size. */ AllocDumpBuf(); } if (data_dump_buffer == NULL) FatalError("Failed allocating %X bytes to data_dump_buffer!\n", data_dump_buffer_size); /* clean it out */ memset(data_dump_buffer, 0x20, size); ddb_ptr = data_dump_buffer; /* loop thru the bytes in the data buffer */ while(bytes_processed) { if(*index > 0x1F && *index < 0x7F) { *ddb_ptr = *index; } else { *ddb_ptr = '.'; } if(++linecount == 64) { ddb_ptr++; *ddb_ptr = '\n'; linecount = 0; } ddb_ptr++; index++; bytes_processed--; } /* slam a \n on the back */ ddb_ptr++; *ddb_ptr = '\n'; ddb_ptr++; /* setup the globals */ dump_size = (int) (ddb_ptr - data_dump_buffer); fwrite(data_dump_buffer, dump_size, 1, fp); //ClearDumpBuf(); } static int PrintObfuscatedData(FILE* fp, Packet *p) { uint8_t *payload = NULL; uint16_t payload_len = 0; if (obApi->getObfuscatedPayload(p, &payload, (uint16_t *)&payload_len) != OB_RET_SUCCESS) { return -1; } /* dump the application layer data */ if (ScOutputAppData() && !ScVerboseByteDump()) { if (ScOutputCharData()) PrintCharData(fp, (char *)payload, payload_len); else PrintNetData(fp, payload, payload_len, NULL); } else if (ScVerboseByteDump()) { uint8_t buf[UINT16_MAX]; uint16_t dlen = p->data - p->pkt; int ret; ret = SafeMemcpy(buf, p->pkt, dlen, buf, buf + sizeof(buf)); if (ret != SAFEMEM_SUCCESS) { DEBUG_WRAP(DebugMessage(DEBUG_LOG, "%s: SafeMemcpy() Failed !!!", __FUNCTION__);) free(payload); return -1; } ret = SafeMemcpy(buf + dlen, payload, payload_len, buf, buf + sizeof(buf)); if (ret != SAFEMEM_SUCCESS) { DEBUG_WRAP(DebugMessage(DEBUG_LOG, "%s: SafeMemcpy() Failed !!!", __FUNCTION__);) free(payload); return -1; } PrintNetData(fp, buf, dlen + payload_len, NULL); } fprintf(fp, "=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+" "=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+\n\n"); p->packet_flags |= PKT_LOGGED; free(payload); return 0; } /* * Function: PrintIPPkt(FILE *, int, Packet *) * * Purpose: Dump the packet to the stream pointer * * Arguments: fp => pointer to print data to * type => packet protocol * p => pointer to decoded packet struct * * Returns: void function */ void PrintIPPkt(FILE * fp, int type, Packet * p) { char timestamp[TIMEBUF_SIZE]; if (p->packet_flags & PKT_LOGGED) return; DEBUG_WRAP(DebugMessage(DEBUG_LOG, "PrintIPPkt type = %d\n", type);); memset((char *) timestamp, 0, TIMEBUF_SIZE); ts_print((struct timeval *) & p->pkth->ts, timestamp); /* dump the timestamp */ fwrite(timestamp, strlen(timestamp), 1, fp); /* dump the ethernet header if we're doing that sort of thing */ if(ScOutputDataLink()) { Print2ndHeader(fp, p); #ifdef MPLS if(p->mpls) { PrintMPLSHeader(fp, p); } #endif #ifdef GRE if (p->outer_iph) { PrintOuterIPHeader(fp, p); if (p->greh) PrintGREHeader(fp, p); } #endif } PrintIPHeader(fp, p); /* if this isn't a fragment, print the other header info */ if(!p->frag_flag) { switch(GET_IPH_PROTO(p)) { case IPPROTO_TCP: if(p->tcph != NULL) { PrintTCPHeader(fp, p); } else { PrintNetData(fp, (u_char *) (u_char *)p->iph + (GET_IPH_HLEN(p) << 2), GET_IP_PAYLEN(p), NULL); } break; case IPPROTO_UDP: if(p->udph != NULL) { PrintUDPHeader(fp, p); } else { PrintNetData(fp, (u_char *) (u_char *)p->iph + (GET_IPH_HLEN(p) << 2), GET_IP_PAYLEN(p), NULL); } break; case IPPROTO_ICMP: if(p->icmph != NULL) { PrintICMPHeader(fp, p); } else { PrintNetData(fp, (u_char *) ((u_char *)p->iph + (GET_IPH_HLEN(p) << 2)), GET_IP_PAYLEN(p), NULL); } break; default: break; } } if ((p->dsize > 0) && obApi->payloadObfuscationRequired(p) && (PrintObfuscatedData(fp, p) == 0)) { return; } /* dump the application layer data */ if (ScOutputAppData() && !ScVerboseByteDump()) { if (ScOutputCharData()) { PrintCharData(fp, (char*) p->data, p->dsize); if(!IsJSNormData(p->ssnptr)) { fprintf(fp, "%s\n", "Normalized JavaScript for this packet"); PrintCharData(fp, (const char*)file_data_ptr.data, file_data_ptr.len); } else if(!IsGzipData(p->ssnptr)) { fprintf(fp, "%s\n", "Decompressed Data for this packet"); PrintCharData(fp, (const char*)file_data_ptr.data, file_data_ptr.len); } } else { PrintNetData(fp, p->data, p->dsize, NULL); if(!IsJSNormData(p->ssnptr)) { fprintf(fp, "%s\n", "Normalized JavaScript for this packet"); PrintNetData(fp, file_data_ptr.data, file_data_ptr.len, NULL); } else if(!IsGzipData(p->ssnptr)) { fprintf(fp, "%s\n", "Decompressed Data for this packet"); PrintNetData(fp, file_data_ptr.data, file_data_ptr.len, NULL); } } } else if (ScVerboseByteDump()) { PrintNetData(fp, p->pkt, p->pkth->caplen, p); } fprintf(fp, "=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+" "=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+\n\n"); p->packet_flags |= PKT_LOGGED; } /**************************************************************************** * * Function: OpenAlertFile(char *) * * Purpose: Set up the file pointer/file for alerting * * Arguments: filearg => the filename to open * * Returns: file handle * ***************************************************************************/ FILE *OpenAlertFile(const char *filearg) { char filename[STD_BUF+1]; FILE *file; char suffix[5]; /* filename suffix */ #ifdef WIN32 SnortStrncpy(suffix, ".ids", sizeof(suffix)); #else suffix[0] = '\0'; #endif if(filearg == NULL) { if (snort_conf->alert_file == NULL) { if(!ScDaemonMode()) SnortSnprintf(filename, STD_BUF, "%s/alert%s", snort_conf->log_dir, suffix); else SnortSnprintf(filename, STD_BUF, "%s/%s", snort_conf->log_dir, DEFAULT_DAEMON_ALERT_FILE); } else { SnortSnprintf(filename, STD_BUF, "%s/%s%s", snort_conf->log_dir, snort_conf->alert_file, suffix); } } else { SnortSnprintf(filename, STD_BUF, "%s", filearg); } DEBUG_WRAP(DebugMessage(DEBUG_INIT,"Opening alert file: %s\n", filename);); if((file = fopen(filename, "a")) == NULL) { FatalError("OpenAlertFile() => fopen() alert file %s: %s\n", filename, strerror(errno)); } #ifdef WIN32 /* Do not buffer in WIN32 */ setvbuf(file, (char *) NULL, _IONBF, (size_t) 0); #else setvbuf(file, (char *) NULL, _IOLBF, (size_t) 0); #endif return file; } /**************************************************************************** * * Function: RollAlertFile(char *) * * Purpose: rename existing alert file with by appending time to name * * Arguments: filearg => the filename to rename (same as for OpenAlertFile()) * * Returns: 0=success, else errno * ***************************************************************************/ int RollAlertFile(const char *filearg) { char oldname[STD_BUF+1]; char newname[STD_BUF+1]; char suffix[5]; /* filename suffix */ time_t now = time(NULL); #ifdef WIN32 SnortStrncpy(suffix, ".ids", sizeof(suffix)); #else suffix[0] = '\0'; #endif if(filearg == NULL) { if(!ScDaemonMode()) SnortSnprintf(oldname, STD_BUF, "%s/alert%s", snort_conf->log_dir, suffix); else SnortSnprintf(oldname, STD_BUF, "%s/%s", snort_conf->log_dir, DEFAULT_DAEMON_ALERT_FILE); } else { SnortSnprintf(oldname, STD_BUF, "%s", filearg); } SnortSnprintf(newname, sizeof(newname)-1, "%s.%lu", oldname, (unsigned long)now); DEBUG_WRAP(DebugMessage(DEBUG_INIT,"Rolling alert file: %s\n", newname);); if ( rename(oldname, newname) ) { FatalError("RollAlertFile() => rename(%s, %s) = %s\n", oldname, newname, strerror(errno)); } return errno; } /* * * Function: AllocDumpBuf() * * Purpose: Allocate the buffer that PrintNetData() uses * * Arguments: None. * * Returns: void function * */ void AllocDumpBuf(void) { if (data_dump_buffer_size == 0) { if (ScVerboseByteDump()) { data_dump_buffer_size = (((IP_MAXPACKET+1)/16) * (FRAME_SIZE + 8)) + (FRAME_SIZE + 8) + 1; } else { data_dump_buffer_size = ((IP_MAXPACKET+1)/16) * FRAME_SIZE + FRAME_SIZE + 1; } } data_dump_buffer = (char *)calloc( 1,data_dump_buffer_size ); /* make sure it got allocated properly */ if(data_dump_buffer == NULL) { FatalError("AllocDumpBuf(): Failed allocating %X bytes!\n", data_dump_buffer_size); } } /* * * Function: ClearDumpBuf() * * Purpose: Clear out the buffer that PrintNetData() generates * * Arguments: None. * * Returns: void function * */ void ClearDumpBuf(void) { if(data_dump_buffer) free(data_dump_buffer); else return; data_dump_buffer = NULL; dump_size = 0; } /**************************************************************************** * * Function: NoAlert(Packet *, char *) * * Purpose: Don't alert at all * * Arguments: p => pointer to the packet data struct * msg => the message to not print in the alert * * Returns: void function * ***************************************************************************/ void NoAlert(Packet * p, char *msg, void *arg, Event *event) { return; } /**************************************************************************** * * Function: NoLog(Packet *) * * Purpose: Don't log anything * * Arguments: p => packet to not log * * Returns: void function * ***************************************************************************/ void NoLog(Packet * p, char *msg, void *arg, Event *event) { return; } /**************************************************************************** * * Function: Print2ndHeader(FILE *, Packet p) * * Purpose: Print2ndHeader -- prints second layber header info. * * Arguments: fp => file stream to print to * * Returns: void function * ***************************************************************************/ void Print2ndHeader(FILE * fp, Packet * p) { switch(DAQ_GetBaseProtocol()) { case DLT_EN10MB: /* Ethernet */ if(p && p->eh) PrintEthHeader(fp, p); break; #ifndef NO_NON_ETHER_DECODER #ifdef DLT_IEEE802_11 case DLT_IEEE802_11: if(p && p->wifih) PrintWifiHeader(fp, p); break; #endif case DLT_IEEE802: /* Token Ring */ if(p && p->trh) PrintTrHeader(fp, p); break; #ifdef DLT_LINUX_SLL case DLT_LINUX_SLL: if (p && p->sllh) PrintSLLHeader(fp, p); /* Linux cooked sockets */ break; #endif #endif // NO_NON_ETHER_DECODER default: if (ScLogVerbose()) { ErrorMessage("Datalink %i type 2nd layer display is not " "supported\n", DAQ_GetBaseProtocol()); } } } #ifndef NO_NON_ETHER_DECODER /**************************************************************************** * * Function: PrintTrHeader(FILE *, Packet p) & * Purpose: Print the packet TokenRing header to the specified stream * * Arguments: fp => file stream to print to * * Returns: void function ***************************************************************************/ void PrintTrHeader(FILE * fp, Packet * p) { fprintf(fp, "%X:%X:%X:%X:%X:%X -> ", p->trh->saddr[0], p->trh->saddr[1], p->trh->saddr[2], p->trh->saddr[3], p->trh->saddr[4], p->trh->saddr[5]); fprintf(fp, "%X:%X:%X:%X:%X:%X\n", p->trh->daddr[0], p->trh->daddr[1], p->trh->daddr[2], p->trh->daddr[3], p->trh->daddr[4], p->trh->daddr[5]); fprintf(fp, "access control:0x%X frame control:0x%X\n", p->trh->ac, p->trh->fc); if(!p->trhllc) return; fprintf(fp, "DSAP: 0x%X SSAP 0x%X protoID: %X%X%X Ethertype: %X\n", p->trhllc->dsap, p->trhllc->ssap, p->trhllc->protid[0], p->trhllc->protid[1], p->trhllc->protid[2], p->trhllc->ethertype); if(p->trhmr) { fprintf(fp, "RIF structure is present:\n"); fprintf(fp, "bcast: 0x%X length: 0x%X direction: 0x%X largest" "fr. size: 0x%X res: 0x%X\n", TRH_MR_BCAST(p->trhmr), TRH_MR_LEN(p->trhmr), TRH_MR_DIR(p->trhmr), TRH_MR_LF(p->trhmr), TRH_MR_RES(p->trhmr)); fprintf(fp, "rseg -> %X:%X:%X:%X:%X:%X:%X:%X\n", p->trhmr->rseg[0], p->trhmr->rseg[1], p->trhmr->rseg[2], p->trhmr->rseg[3], p->trhmr->rseg[4], p->trhmr->rseg[5], p->trhmr->rseg[6], p->trhmr->rseg[7]); } } #endif // NO_NON_ETHER_DECODER /**************************************************************************** * * Function: PrintEthHeader(FILE *) * * Purpose: Print the packet Ethernet header to the specified stream * * Arguments: fp => file stream to print to * * Returns: void function * ***************************************************************************/ void PrintEthHeader(FILE * fp, Packet * p) { /* src addr */ fprintf(fp, "%02X:%02X:%02X:%02X:%02X:%02X -> ", p->eh->ether_src[0], p->eh->ether_src[1], p->eh->ether_src[2], p->eh->ether_src[3], p->eh->ether_src[4], p->eh->ether_src[5]); /* dest addr */ fprintf(fp, "%02X:%02X:%02X:%02X:%02X:%02X ", p->eh->ether_dst[0], p->eh->ether_dst[1], p->eh->ether_dst[2], p->eh->ether_dst[3], p->eh->ether_dst[4], p->eh->ether_dst[5]); /* protocol and pkt size */ fprintf(fp, "type:0x%X len:0x%X\n", ntohs(p->eh->ether_type), p->pkth->pktlen); } #ifdef MPLS void PrintMPLSHeader(FILE* log, Packet* p) { fprintf(log,"label:0x%05X exp:0x%X bos:0x%X ttl:0x%X\n", p->mplsHdr.label, p->mplsHdr.exp, p->mplsHdr.bos, p->mplsHdr.ttl); } #endif #ifdef GRE void PrintGREHeader(FILE *log, Packet *p) { if (p->greh == NULL) return; fprintf(log, "GRE version:%u flags:0x%02X ether-type:0x%04X\n", GRE_VERSION(p->greh), p->greh->flags, GRE_PROTO(p->greh)); } #endif #ifndef NO_NON_ETHER_DECODER /**************************************************************************** * * Function: PrintSLLHeader(FILE *) * * Purpose: Print the packet SLL (fake) header to the specified stream (piece * partly is borrowed from tcpdump :)) * * Arguments: fp => file stream to print to * * Returns: void function * ***************************************************************************/ void PrintSLLHeader(FILE * fp, Packet * p) { switch (ntohs(p->sllh->sll_pkttype)) { case LINUX_SLL_HOST: (void)fprintf(fp, "< "); break; case LINUX_SLL_BROADCAST: (void)fprintf(fp, "B "); break; case LINUX_SLL_MULTICAST: (void)fprintf(fp, "M "); break; case LINUX_SLL_OTHERHOST: (void)fprintf(fp, "P "); break; case LINUX_SLL_OUTGOING: (void)fprintf(fp, "> "); break; default: (void)fprintf(fp, "? "); break; } /* mac addr */ fprintf(fp, "l/l len: %i l/l type: 0x%X %02X:%02X:%02X:%02X:%02X:%02X\n", htons(p->sllh->sll_halen), ntohs(p->sllh->sll_hatype), p->sllh->sll_addr[0], p->sllh->sll_addr[1], p->sllh->sll_addr[2], p->sllh->sll_addr[3], p->sllh->sll_addr[4], p->sllh->sll_addr[5]); /* protocol and pkt size */ fprintf(fp, "pkt type:0x%X proto: 0x%X len:0x%X\n", ntohs(p->sllh->sll_pkttype), ntohs(p->sllh->sll_protocol), p->pkth->pktlen); } void PrintArpHeader(FILE * fp, Packet * p) { // XXX-IPv6 "NOT YET IMPLEMENTED - printing ARP header" } #endif // NO_NON_ETHER_DECODER /**************************************************************************** * * Function: PrintIPHeader(FILE *) * * Purpose: Dump the IP header info to the specified stream * * Arguments: fp => stream to print to * * Returns: void function * ***************************************************************************/ void PrintIPHeader(FILE * fp, Packet * p) { if(!IPH_IS_VALID(p)) { fprintf(fp, "IP header truncated\n"); return; } PrintIpAddrs(fp, p); if (!ScOutputDataLink()) { fputc('\n', fp); } else { fputc(' ', fp); } fprintf(fp, "%s TTL:%u TOS:0x%X ID:%u IpLen:%u DgmLen:%u", protocol_names[GET_IPH_PROTO(p)], GET_IPH_TTL(p), GET_IPH_TOS(p), IS_IP6(p) ? ntohl(GET_IPH_ID(p)) : ntohs((uint16_t)GET_IPH_ID(p)), GET_IPH_HLEN(p) << 2, GET_IP_DGMLEN(p)); /* print the reserved bit if it's set */ if((uint8_t)((ntohs(GET_IPH_OFF(p)) & 0x8000) >> 15) == 1) fprintf(fp, " RB"); /* printf more frags/don't frag bits */ if((uint8_t)((ntohs(GET_IPH_OFF(p)) & 0x4000) >> 14) == 1) fprintf(fp, " DF"); if((uint8_t)((ntohs(GET_IPH_OFF(p)) & 0x2000) >> 13) == 1) fprintf(fp, " MF"); fputc('\n', fp); /* print IP options */ if(p->ip_option_count != 0) { PrintIpOptions(fp, p); } /* print fragment info if necessary */ if(p->frag_flag) { fprintf(fp, "Frag Offset: 0x%04X Frag Size: 0x%04X\n", (p->frag_offset & 0x1FFF), GET_IP_PAYLEN(p)); } } #ifdef GRE void PrintOuterIPHeader(FILE *fp, Packet *p) { int save_family = p->family; IPH_API *save_api = p->iph_api; const IPHdr *save_iph = p->iph; uint8_t save_ip_option_count = p->ip_option_count; IP4Hdr *save_ip4h = p->ip4h; IP6Hdr *save_ip6h = p->ip6h; uint8_t save_frag_flag = p->frag_flag; uint16_t save_sp = p->sp, save_dp = p->dp; p->family = p->outer_family; p->iph_api = p->outer_iph_api; p->iph = p->outer_iph; p->ip_option_count = 0; p->ip4h = &p->outer_ip4h; p->ip6h = &p->outer_ip6h; p->frag_flag = 0; if (p->proto_bits & PROTO_BIT__TEREDO) { if (p->outer_udph) { p->sp = ntohs(p->outer_udph->uh_sport); p->dp = ntohs(p->outer_udph->uh_dport); } else { p->sp = ntohs(p->udph->uh_sport); p->dp = ntohs(p->udph->uh_dport); } } PrintIPHeader(fp, p); p->family = save_family; p->iph_api = save_api; p->iph = save_iph; p->ip_option_count = save_ip_option_count; p->ip4h = save_ip4h; p->ip6h = save_ip6h; p->frag_flag = save_frag_flag; if (p->proto_bits & PROTO_BIT__TEREDO) { p->sp = save_sp; p->dp = save_dp; } } #endif /**************************************************************************** * * Function: PrintTCPHeader(FILE *) * * Purpose: Dump the TCP header info to the specified stream * * Arguments: fp => file stream to print data to * * Returns: void function * ***************************************************************************/ void PrintTCPHeader(FILE * fp, Packet * p) { char tcpFlags[9]; if(p->tcph == NULL) { fprintf(fp, "TCP header truncated\n"); return; } /* print TCP flags */ CreateTCPFlagString(p, tcpFlags); fwrite(tcpFlags, 8, 1, fp); /* We don't care about the NULL */ /* print other TCP info */ fprintf(fp, " Seq: 0x%lX Ack: 0x%lX Win: 0x%X TcpLen: %d", (u_long) ntohl(p->tcph->th_seq), (u_long) ntohl(p->tcph->th_ack), ntohs(p->tcph->th_win), TCP_OFFSET(p->tcph) << 2); if((p->tcph->th_flags & TH_URG) != 0) { fprintf(fp, " UrgPtr: 0x%X\n", (uint16_t) ntohs(p->tcph->th_urp)); } else { fputc((int) '\n', fp); } /* dump the TCP options */ if(p->tcp_option_count != 0) { PrintTcpOptions(fp, p); } } /* Input is packet and an nine-byte (including NULL) character array. Results * are put into the character array. */ void CreateTCPFlagString(Packet * p, char *flagBuffer) { /* parse TCP flags */ *flagBuffer++ = (char) ((p->tcph->th_flags & TH_RES1) ? '1' : '*'); *flagBuffer++ = (char) ((p->tcph->th_flags & TH_RES2) ? '2' : '*'); *flagBuffer++ = (char) ((p->tcph->th_flags & TH_URG) ? 'U' : '*'); *flagBuffer++ = (char) ((p->tcph->th_flags & TH_ACK) ? 'A' : '*'); *flagBuffer++ = (char) ((p->tcph->th_flags & TH_PUSH) ? 'P' : '*'); *flagBuffer++ = (char) ((p->tcph->th_flags & TH_RST) ? 'R' : '*'); *flagBuffer++ = (char) ((p->tcph->th_flags & TH_SYN) ? 'S' : '*'); *flagBuffer++ = (char) ((p->tcph->th_flags & TH_FIN) ? 'F' : '*'); *flagBuffer = '\0'; } /**************************************************************************** * * Function: PrintUDPHeader(FILE *) * * Purpose: Dump the UDP header to the specified file stream * * Arguments: fp => file stream * * Returns: void function * ***************************************************************************/ void PrintUDPHeader(FILE * fp, Packet * p) { if(p->udph == NULL) { fprintf(fp, "UDP header truncated\n"); return; } /* not much to do here... */ fprintf(fp, "Len: %d\n", ntohs(p->udph->uh_len) - UDP_HEADER_LEN); } /**************************************************************************** * * Function: PrintICMPHeader(FILE *) * * Purpose: Print ICMP header * * Arguments: fp => file stream * * Returns: void function * ***************************************************************************/ void PrintICMPHeader(FILE * fp, Packet * p) { /* 32 digits plus 7 colons and a NULL byte */ char buf[8*4 + 7 + 1]; if(p->icmph == NULL) { fprintf(fp, "ICMP header truncated\n"); return; } fprintf(fp, "Type:%d Code:%d ", p->icmph->type, p->icmph->code); switch(p->icmph->type) { case ICMP_ECHOREPLY: fprintf(fp, "ID:%d Seq:%d ", ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq)); fwrite("ECHO REPLY", 10, 1, fp); break; case ICMP_DEST_UNREACH: fwrite("DESTINATION UNREACHABLE: ", 25, 1, fp); switch(p->icmph->code) { case ICMP_NET_UNREACH: fwrite("NET UNREACHABLE", 15, 1, fp); break; case ICMP_HOST_UNREACH: fwrite("HOST UNREACHABLE", 16, 1, fp); break; case ICMP_PROT_UNREACH: fwrite("PROTOCOL UNREACHABLE", 20, 1, fp); break; case ICMP_PORT_UNREACH: fwrite("PORT UNREACHABLE", 16, 1, fp); break; case ICMP_FRAG_NEEDED: fprintf(fp, "FRAGMENTATION NEEDED, DF SET\n" "NEXT LINK MTU: %u", ntohs(p->icmph->s_icmp_nextmtu)); break; case ICMP_SR_FAILED: fwrite("SOURCE ROUTE FAILED", 19, 1, fp); break; case ICMP_NET_UNKNOWN: fwrite("NET UNKNOWN", 11, 1, fp); break; case ICMP_HOST_UNKNOWN: fwrite("HOST UNKNOWN", 12, 1, fp); break; case ICMP_HOST_ISOLATED: fwrite("HOST ISOLATED", 13, 1, fp); break; case ICMP_PKT_FILTERED_NET: fwrite("ADMINISTRATIVELY PROHIBITED NETWORK FILTERED", 44, 1, fp); break; case ICMP_PKT_FILTERED_HOST: fwrite("ADMINISTRATIVELY PROHIBITED HOST FILTERED", 41, 1, fp); break; case ICMP_NET_UNR_TOS: fwrite("NET UNREACHABLE FOR TOS", 23, 1, fp); break; case ICMP_HOST_UNR_TOS: fwrite("HOST UNREACHABLE FOR TOS", 24, 1, fp); break; case ICMP_PKT_FILTERED: fwrite("ADMINISTRATIVELY PROHIBITED,\nPACKET FILTERED", 44, 1, fp); break; case ICMP_PREC_VIOLATION: fwrite("PREC VIOLATION", 14, 1, fp); break; case ICMP_PREC_CUTOFF: fwrite("PREC CUTOFF", 12, 1, fp); break; default: fwrite("UNKNOWN", 7, 1, fp); break; } PrintICMPEmbeddedIP(fp, p); break; case ICMP_SOURCE_QUENCH: fwrite("SOURCE QUENCH", 13, 1, fp); PrintICMPEmbeddedIP(fp, p); break; case ICMP_REDIRECT: fwrite("REDIRECT", 8, 1, fp); switch(p->icmph->code) { case ICMP_REDIR_NET: fwrite(" NET", 4, 1, fp); break; case ICMP_REDIR_HOST: fwrite(" HOST", 5, 1, fp); break; case ICMP_REDIR_TOS_NET: fwrite(" TOS NET", 8, 1, fp); break; case ICMP_REDIR_TOS_HOST: fwrite(" TOS HOST", 9, 1, fp); break; } /* written this way since inet_ntoa was typedef'ed to use sfip_ntoa * which requires sfcidr_t instead of inaddr's. This call to inet_ntoa * is a rare case that doesn't use sfcidr_t's. */ // XXX-IPv6 NOT YET IMPLEMENTED - IPV6 addresses technically not supported - need to change ICMP header sfip_raw_ntop(AF_INET, (void *)&p->icmph->s_icmp_gwaddr, buf, sizeof(buf)); fprintf(fp, " NEW GW: %s", buf); PrintICMPEmbeddedIP(fp, p); break; case ICMP_ECHO: fprintf(fp, "ID:%d Seq:%d ", ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq)); fwrite("ECHO", 4, 1, fp); break; case ICMP_ROUTER_ADVERTISE: fprintf(fp, "ROUTER ADVERTISMENT: " "Num addrs: %d Addr entry size: %d Lifetime: %u", p->icmph->s_icmp_num_addrs, p->icmph->s_icmp_wpa, ntohs(p->icmph->s_icmp_lifetime)); break; case ICMP_ROUTER_SOLICIT: fwrite("ROUTER SOLICITATION", 19, 1, fp); break; case ICMP_TIME_EXCEEDED: fwrite("TTL EXCEEDED", 12, 1, fp); switch(p->icmph->code) { case ICMP_TIMEOUT_TRANSIT: fwrite(" IN TRANSIT", 11, 1, fp); break; case ICMP_TIMEOUT_REASSY: fwrite(" TIME EXCEEDED IN FRAG REASSEMBLY", 33, 1, fp); break; } PrintICMPEmbeddedIP(fp, p); break; case ICMP_PARAMETERPROB: fwrite("PARAMETER PROBLEM", 17, 1, fp); switch(p->icmph->code) { case ICMP_PARAM_BADIPHDR: fprintf(fp, ": BAD IP HEADER BYTE %u", p->icmph->s_icmp_pptr); break; case ICMP_PARAM_OPTMISSING: fwrite(": OPTION MISSING", 16, 1, fp); break; case ICMP_PARAM_BAD_LENGTH: fwrite(": BAD LENGTH", 12, 1, fp); break; } PrintICMPEmbeddedIP(fp, p); break; case ICMP_TIMESTAMP: fprintf(fp, "ID: %u Seq: %u TIMESTAMP REQUEST", ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq)); break; case ICMP_TIMESTAMPREPLY: fprintf(fp, "ID: %u Seq: %u TIMESTAMP REPLY:\n" "Orig: %u Rtime: %u Ttime: %u", ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq), p->icmph->s_icmp_otime, p->icmph->s_icmp_rtime, p->icmph->s_icmp_ttime); break; case ICMP_INFO_REQUEST: fprintf(fp, "ID: %u Seq: %u INFO REQUEST", ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq)); break; case ICMP_INFO_REPLY: fprintf(fp, "ID: %u Seq: %u INFO REPLY", ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq)); break; case ICMP_ADDRESS: fprintf(fp, "ID: %u Seq: %u ADDRESS REQUEST", ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq)); break; case ICMP_ADDRESSREPLY: fprintf(fp, "ID: %u Seq: %u ADDRESS REPLY: 0x%08X", ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq), (u_int) ntohl(p->icmph->s_icmp_mask)); break; default: fwrite("UNKNOWN", 7, 1, fp); break; } putc('\n', fp); } /**************************************************************************** * * Function: PrintICMPEmbeddedIP(FILE *, Packet *) * * Purpose: Prints the original/encapsulated IP header + 64 bits of the * original IP payload in an ICMP packet * * Arguments: fp => file stream * p => packet struct * * Returns: void function * ***************************************************************************/ void PrintICMPEmbeddedIP(FILE *fp, Packet *p) { Packet op; Packet *orig_p; uint32_t orig_ip_hlen; if (fp == NULL || p == NULL) return; memset((char *) &op, 0, sizeof(Packet)); orig_p = &op; orig_p->iph = p->orig_iph; orig_p->tcph = p->orig_tcph; orig_p->udph = p->orig_udph; orig_p->sp = p->orig_sp; orig_p->dp = p->orig_dp; orig_p->icmph = p->orig_icmph; orig_p->iph_api = p->orig_iph_api; orig_p->ip4h = p->orig_ip4h; orig_p->ip6h = p->orig_ip6h; orig_p->family = p->orig_family; if(orig_p->iph != NULL) { fprintf(fp, "\n** ORIGINAL DATAGRAM DUMP:\n"); PrintIPHeader(fp, orig_p); orig_ip_hlen = IP_HLEN(p->orig_iph) << 2; switch(GET_IPH_PROTO(orig_p)) { case IPPROTO_TCP: if(orig_p->tcph != NULL) fprintf(fp, "Seq: 0x%lX\n", (u_long)ntohl(orig_p->tcph->th_seq)); break; case IPPROTO_UDP: if(orig_p->udph != NULL) fprintf(fp, "Len: %d Csum: %d\n", ntohs(orig_p->udph->uh_len) - UDP_HEADER_LEN, ntohs(orig_p->udph->uh_chk)); break; case IPPROTO_ICMP: if(orig_p->icmph != NULL) PrintEmbeddedICMPHeader(fp, orig_p->icmph); break; default: fprintf(fp, "Protocol: 0x%X (unknown or " "header truncated)", GET_IPH_PROTO(orig_p)); break; } /* switch */ /* if more than 8 bytes of original IP payload sent */ if (p->dsize - orig_ip_hlen > 8) { fprintf(fp, "(%d more bytes of original packet)\n", p->dsize - orig_ip_hlen - 8); } fprintf(fp, "** END OF DUMP"); } else { fprintf(fp, "\nORIGINAL DATAGRAM TRUNCATED"); } } /**************************************************************************** * * Function: PrintEmbeddedICMPHeader(FILE *, ICMPHdr *) * * Purpose: Prints the 64 bits of the original IP payload in an ICMP packet * that requires it * * Arguments: fp => file stream * icmph => ICMPHdr struct pointing to original ICMP * * Returns: void function * ***************************************************************************/ void PrintEmbeddedICMPHeader(FILE *fp, const ICMPHdr *icmph) { if (fp == NULL || icmph == NULL) return; fprintf(fp, "Type: %d Code: %d Csum: %u", icmph->type, icmph->code, ntohs(icmph->csum)); switch (icmph->type) { case ICMP_DEST_UNREACH: case ICMP_TIME_EXCEEDED: case ICMP_SOURCE_QUENCH: break; case ICMP_PARAMETERPROB: if (icmph->code == 0) fprintf(fp, " Ptr: %u", icmph->s_icmp_pptr); break; case ICMP_REDIRECT: // XXX-IPv6 "NOT YET IMPLEMENTED - ICMP printing" break; case ICMP_ECHO: case ICMP_ECHOREPLY: case ICMP_TIMESTAMP: case ICMP_TIMESTAMPREPLY: case ICMP_INFO_REQUEST: case ICMP_INFO_REPLY: case ICMP_ADDRESS: case ICMP_ADDRESSREPLY: fprintf(fp, " Id: %u SeqNo: %u", ntohs(icmph->s_icmp_id), ntohs(icmph->s_icmp_seq)); break; case ICMP_ROUTER_ADVERTISE: fprintf(fp, " Addrs: %u Size: %u Lifetime: %u", icmph->s_icmp_num_addrs, icmph->s_icmp_wpa, ntohs(icmph->s_icmp_lifetime)); break; default: break; } fprintf(fp, "\n"); return; } void PrintIpOptions(FILE * fp, Packet * p) { int i; int j; u_long init_offset; u_long print_offset; init_offset = ftell(fp); if(!p->ip_option_count || p->ip_option_count > 40) return; fprintf(fp, "IP Options (%d) => ", p->ip_option_count); for(i = 0; i < (int) p->ip_option_count; i++) { print_offset = ftell(fp); if((print_offset - init_offset) > 60) { fwrite("\nIP Options => ", 15, 1, fp); init_offset = ftell(fp); } switch(p->ip_options[i].code) { case IPOPT_RR: fwrite("RR ", 3, 1, fp); break; case IPOPT_EOL: fwrite("EOL ", 4, 1, fp); break; case IPOPT_NOP: fwrite("NOP ", 4, 1, fp); break; case IPOPT_TS: fwrite("TS ", 3, 1, fp); break; case IPOPT_ESEC: fwrite("ESEC ", 5, 1, fp); break; case IPOPT_SECURITY: fwrite("SEC ", 4, 1, fp); break; case IPOPT_LSRR: case IPOPT_LSRR_E: fwrite("LSRR ", 5, 1, fp); break; case IPOPT_SATID: fwrite("SID ", 4, 1, fp); break; case IPOPT_SSRR: fwrite("SSRR ", 5, 1, fp); break; case IPOPT_RTRALT: fwrite("RTRALT ", 7, 1, fp); break; default: fprintf(fp, "Opt %d: ", p->ip_options[i].code); if(p->ip_options[i].len) { for(j = 0; j < p->ip_options[i].len; j++) { if (p->ip_options[i].data) fprintf(fp, "%02X", p->ip_options[i].data[j]); else fprintf(fp, "%02X", 0); if((j % 2) == 0) fprintf(fp, " "); } } break; } } fwrite("\n", 1, 1, fp); } void PrintTcpOptions(FILE * fp, Packet * p) { int i; int j; u_char tmp[5]; u_long init_offset; u_long print_offset; init_offset = ftell(fp); fprintf(fp, "TCP Options (%d) => ", p->tcp_option_count); if(p->tcp_option_count > 40 || !p->tcp_option_count) return; for(i = 0; i < (int) p->tcp_option_count; i++) { print_offset = ftell(fp); if((print_offset - init_offset) > 60) { fwrite("\nTCP Options => ", 16, 1, fp); init_offset = ftell(fp); } switch(p->tcp_options[i].code) { case TCPOPT_MAXSEG: memset((char *) tmp, 0, 5); fwrite("MSS: ", 5, 1, fp); if (p->tcp_options[i].data) memcpy(tmp, p->tcp_options[i].data, 2); fprintf(fp, "%u ", EXTRACT_16BITS(tmp)); break; case TCPOPT_EOL: fwrite("EOL ", 4, 1, fp); break; case TCPOPT_NOP: fwrite("NOP ", 4, 1, fp); break; case TCPOPT_WSCALE: if (p->tcp_options[i].data) fprintf(fp, "WS: %u ", p->tcp_options[i].data[0]); else fprintf(fp, "WS: %u ", 0); break; case TCPOPT_SACK: memset((char *) tmp, 0, 5); if (p->tcp_options[i].data && (p->tcp_options[i].len >= 2)) memcpy(tmp, p->tcp_options[i].data, 2); fprintf(fp, "Sack: %u@", EXTRACT_16BITS(tmp)); memset((char *) tmp, 0, 5); if (p->tcp_options[i].data && (p->tcp_options[i].len >= 4)) memcpy(tmp, (p->tcp_options[i].data) + 2, 2); fprintf(fp, "%u ", EXTRACT_16BITS(tmp)); break; case TCPOPT_SACKOK: fwrite("SackOK ", 7, 1, fp); break; case TCPOPT_ECHO: memset((char *) tmp, 0, 5); if (p->tcp_options[i].data) memcpy(tmp, p->tcp_options[i].data, 4); fprintf(fp, "Echo: %u ", EXTRACT_32BITS(tmp)); break; case TCPOPT_ECHOREPLY: memset((char *) tmp, 0, 5); if (p->tcp_options[i].data) memcpy(tmp, p->tcp_options[i].data, 4); fprintf(fp, "Echo Rep: %u ", EXTRACT_32BITS(tmp)); break; case TCPOPT_TIMESTAMP: memset((char *) tmp, 0, 5); if (p->tcp_options[i].data) memcpy(tmp, p->tcp_options[i].data, 4); fprintf(fp, "TS: %u ", EXTRACT_32BITS(tmp)); memset((char *) tmp, 0, 5); if (p->tcp_options[i].data) memcpy(tmp, (p->tcp_options[i].data) + 4, 4); fprintf(fp, "%u ", EXTRACT_32BITS(tmp)); break; case TCPOPT_CC: memset((char *) tmp, 0, 5); if (p->tcp_options[i].data) memcpy(tmp, p->tcp_options[i].data, 4); fprintf(fp, "CC %u ", EXTRACT_32BITS(tmp)); break; case TCPOPT_CCNEW: memset((char *) tmp, 0, 5); if (p->tcp_options[i].data) memcpy(tmp, p->tcp_options[i].data, 4); fprintf(fp, "CCNEW: %u ", EXTRACT_32BITS(tmp)); break; case TCPOPT_CCECHO: memset((char *) tmp, 0, 5); if (p->tcp_options[i].data) memcpy(tmp, p->tcp_options[i].data, 4); fprintf(fp, "CCECHO: %u ", EXTRACT_32BITS(tmp)); break; default: if(p->tcp_options[i].len) { fprintf(fp, "Opt %d (%d): ", p->tcp_options[i].code, (int) p->tcp_options[i].len); for(j = 0; j < p->tcp_options[i].len; j++) { if (p->tcp_options[i].data) fprintf(fp, "%02X", p->tcp_options[i].data[j]); else fprintf(fp, "%02X", 0); if ((j + 1) % 2 == 0) fprintf(fp, " "); } fprintf(fp, " "); } else { fprintf(fp, "Opt %d ", p->tcp_options[i].code); } break; } } fwrite("\n", 1, 1, fp); } /* * Function: PrintPriorityData(FILE *) * * Purpose: Prints out priority data associated with an alert * * Arguments: fp => file descriptor to write the data to * do_newline => tack a \n to the end of the line or not (bool) * * Returns: void function */ void PrintPriorityData(FILE *fp, int do_newline) { if (otn_tmp == NULL) return; if ((otn_tmp->sigInfo.classType != NULL) && (otn_tmp->sigInfo.classType->name != NULL)) { fprintf(fp, "[Classification: %s] ", otn_tmp->sigInfo.classType->name); } fprintf(fp, "[Priority: %d] ", otn_tmp->sigInfo.priority); if (do_newline) fprintf(fp, "\n"); } /* * Function: PrintXrefs(FILE *) * * Purpose: Prints out cross reference data associated with an alert * * Arguments: fp => file descriptor to write the data to * do_newline => tack a \n to the end of the line or not (bool) * * Returns: void function */ void PrintXrefs(FILE *fp, int do_newline) { ReferenceNode *refNode = NULL; if(otn_tmp) { refNode = otn_tmp->sigInfo.refs; while(refNode != NULL) { FPrintReference(fp, refNode); refNode = refNode->next; /* on the last loop through, print a newline in Full mode */ if(do_newline && (refNode == NULL)) fprintf(fp, "\n"); } } } /* This function name is being altered for Win32 because it conflicts with a Win32 SDK function name. However calls to this function from within Snort do not need to change because SetEvent() is defined in log.h to evaluate to SnortSetEvent() on Win32 compiles. */ #ifndef WIN32 void SetEvent #else void SnortSetEvent #endif (Event *event, uint32_t generator, uint32_t id, uint32_t rev, #if !defined(FEAT_OPEN_APPID) uint32_t classification, uint32_t priority, uint32_t event_ref) #else /* defined(FEAT_OPEN_APPID) */ uint32_t classification, uint32_t priority, uint32_t event_ref, char *event_appid) #endif /* defined(FEAT_OPEN_APPID) */ { event->sig_generator = generator; event->sig_id = id; event->sig_rev = rev; event->classification = classification; event->priority = priority; /* this one gets set automatically */ event->event_id = ++event_id | ScEventLogId(); if(event_ref) event->event_reference = event_ref; else event->event_reference = event->event_id; #if defined(FEAT_OPEN_APPID) if (event_appid) memcpy(event->app_name, event_appid, MAX_EVENT_APPNAME_LEN); else event->app_name[0] = 0; #endif /* defined(FEAT_OPEN_APPID) */ event->ref_time.tv_sec = 0; return; } #ifndef NO_NON_ETHER_DECODER /* * Function: PrintEapolPkt(FILE *, Packet *) * * Purpose: Dump the packet to the stream pointer * * Arguments: fp => pointer to print data to * type => packet protocol * p => pointer to decoded packet struct * * Returns: void function */ void PrintEapolPkt(FILE * fp, Packet * p) { char timestamp[TIMEBUF_SIZE]; memset((char *) timestamp, 0, TIMEBUF_SIZE); ts_print((struct timeval *) & p->pkth->ts, timestamp); /* dump the timestamp */ fwrite(timestamp, strlen(timestamp), 1, fp); /* dump the ethernet header if we're doing that sort of thing */ if (ScOutputDataLink()) { Print2ndHeader(fp, p); } PrintEapolHeader(fp, p); if (p->eplh->eaptype == EAPOL_TYPE_EAP) { PrintEAPHeader(fp, p); } else if (p->eplh->eaptype == EAPOL_TYPE_KEY) { PrintEapolKey(fp, p); } /* dump the application layer data */ if(ScOutputAppData() && !ScVerboseByteDump()) { if (ScOutputCharData()) PrintCharData(fp, (char*) p->data, p->dsize); else PrintNetData(fp, p->data, p->dsize, NULL); } else if (ScVerboseByteDump()) { PrintNetData(fp, p->pkt, p->pkth->caplen, p); } fprintf(fp, "=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+\n\n"); } /**************************************************************************** * * Function: PrintWifiHeader(FILE *) * * Purpose: Print the packet 802.11 header to the specified stream * * Arguments: fp => file stream to print to * * Returns: void function * ***************************************************************************/ void PrintWifiHeader(FILE * fp, Packet * p) { /* This assumes we are printing a data packet, could be changed to print other types as well */ const u_char *da = NULL, *sa = NULL, *bssid = NULL, *ra = NULL, *ta = NULL; /* per table 4, IEEE802.11 section 7.2.2 */ if ((p->wifih->frame_control & WLAN_FLAG_TODS) && (p->wifih->frame_control & WLAN_FLAG_FROMDS)) { ra = p->wifih->addr1; ta = p->wifih->addr2; da = p->wifih->addr3; sa = p->wifih->addr4; } else if (p->wifih->frame_control & WLAN_FLAG_TODS) { bssid = p->wifih->addr1; sa = p->wifih->addr2; da = p->wifih->addr3; } else if (p->wifih->frame_control & WLAN_FLAG_FROMDS) { da = p->wifih->addr1; bssid = p->wifih->addr2; sa = p->wifih->addr3; } else { da = p->wifih->addr1; sa = p->wifih->addr2; bssid = p->wifih->addr3; } /* DO this switch to provide additional info on the type */ switch(p->wifih->frame_control & 0x00ff) { case WLAN_TYPE_MGMT_BEACON: fprintf(fp, "Beacon "); break; /* management frames */ case WLAN_TYPE_MGMT_ASREQ: fprintf(fp, "Assoc. Req. "); break; case WLAN_TYPE_MGMT_ASRES: fprintf(fp, "Assoc. Resp. "); break; case WLAN_TYPE_MGMT_REREQ: fprintf(fp, "Reassoc. Req. "); break; case WLAN_TYPE_MGMT_RERES: fprintf(fp, "Reassoc. Resp. "); break; case WLAN_TYPE_MGMT_PRREQ: fprintf(fp, "Probe Req. "); break; case WLAN_TYPE_MGMT_PRRES: fprintf(fp, "Probe Resp. "); break; case WLAN_TYPE_MGMT_ATIM: fprintf(fp, "ATIM "); break; case WLAN_TYPE_MGMT_DIS: fprintf(fp, "Dissassoc. "); break; case WLAN_TYPE_MGMT_AUTH: fprintf(fp, "Authent. "); break; case WLAN_TYPE_MGMT_DEAUTH: fprintf(fp, "Deauthent. "); break; /* Control frames */ case WLAN_TYPE_CONT_PS: case WLAN_TYPE_CONT_RTS: case WLAN_TYPE_CONT_CTS: case WLAN_TYPE_CONT_ACK: case WLAN_TYPE_CONT_CFE: case WLAN_TYPE_CONT_CFACK: fprintf(fp, "Control "); break; } if (sa != NULL) { fprintf(fp, "%X:%X:%X:%X:%X:%X -> ", sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]); } else if (ta != NULL) { fprintf(fp, "ta: %X:%X:%X:%X:%X:%X da: ", ta[0], ta[1], ta[2], ta[3], ta[4], ta[5]); } fprintf(fp, "%X:%X:%X:%X:%X:%X\n", da[0], da[1], da[2], da[3], da[4], da[5]); if (bssid != NULL) { fprintf(fp, "bssid: %X:%X:%X:%X:%X:%X", bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]); } if (ra != NULL) { fprintf(fp, " ra: %X:%X:%X:%X:%X:%X", ra[0], ra[1], ra[2], ra[3], ra[4], ra[5]); } fprintf(fp, " Flags:"); if (p->wifih->frame_control & WLAN_FLAG_TODS) fprintf(fp," ToDs"); if (p->wifih->frame_control & WLAN_FLAG_TODS) fprintf(fp," FrDs"); if (p->wifih->frame_control & WLAN_FLAG_FRAG) fprintf(fp," Frag"); if (p->wifih->frame_control & WLAN_FLAG_RETRY) fprintf(fp," Re"); if (p->wifih->frame_control & WLAN_FLAG_PWRMGMT) fprintf(fp," Pwr"); if (p->wifih->frame_control & WLAN_FLAG_MOREDAT) fprintf(fp," MD"); if (p->wifih->frame_control & WLAN_FLAG_WEP) fprintf(fp," Wep"); if (p->wifih->frame_control & WLAN_FLAG_ORDER) fprintf(fp," Ord"); fprintf(fp, "\n"); } /* * Function: PrintWifiPkt(FILE *, Packet *) * * Purpose: Dump the packet to the stream pointer * * Arguments: fp => pointer to print data to * p => pointer to decoded packet struct * * Returns: void function */ void PrintWifiPkt(FILE * fp, Packet * p) { char timestamp[TIMEBUF_SIZE]; memset((char *) timestamp, 0, TIMEBUF_SIZE); ts_print((struct timeval *) & p->pkth->ts, timestamp); /* dump the timestamp */ fwrite(timestamp, strlen(timestamp), 1, fp); /* dump the ethernet header if we're doing that sort of thing */ Print2ndHeader(fp, p); /* dump the application layer data */ if (ScOutputAppData() && !ScVerboseByteDump()) { if (ScOutputCharData()) PrintCharData(fp, (char*) p->data, p->dsize); else PrintNetData(fp, p->data, p->dsize, NULL); } else if (ScVerboseByteDump()) { PrintNetData(fp, p->pkt, p->pkth->caplen, p); } fprintf(fp, "=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+" "=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+\n\n"); } /**************************************************************************** * * Function: PrintEapolHeader(FILE *, Packet *) * * Purpose: Dump the EAPOL header info to the specified stream * * Arguments: fp => stream to print to * * Returns: void function * ***************************************************************************/ void PrintEapolHeader(FILE * fp, Packet * p) { fprintf(fp, "EAPOL type: "); switch(p->eplh->eaptype) { case EAPOL_TYPE_EAP: fprintf(fp, "EAP"); break; case EAPOL_TYPE_START: fprintf(fp, "Start"); break; case EAPOL_TYPE_LOGOFF: fprintf(fp, "Logoff"); break; case EAPOL_TYPE_KEY: fprintf(fp, "Key"); break; case EAPOL_TYPE_ASF: fprintf(fp, "ASF Alert"); break; default: fprintf(fp, "Unknown"); } fprintf(fp, " Len: %d\n", ntohs(p->eplh->len)); } /**************************************************************************** * * Function: PrintEAPHeader(FILE *) * * Purpose: Dump the EAP header to the specified file stream * * Arguments: fp => file stream * * Returns: void function * ***************************************************************************/ void PrintEAPHeader(FILE * fp, Packet * p) { if(p->eaph == NULL) { fprintf(fp, "EAP header truncated\n"); return; } fprintf(fp, "code: "); switch(p->eaph->code) { case EAP_CODE_REQUEST: fprintf(fp, "Req "); break; case EAP_CODE_RESPONSE: fprintf(fp, "Resp"); break; case EAP_CODE_SUCCESS: fprintf(fp, "Succ"); break; case EAP_CODE_FAILURE: fprintf(fp, "Fail"); break; } fprintf(fp, " id: 0x%x len: %d", p->eaph->id, ntohs(p->eaph->len)); if (p->eaptype != NULL) { fprintf(fp, " type: "); switch(*(p->eaptype)) { case EAP_TYPE_IDENTITY: fprintf(fp, "id"); break; case EAP_TYPE_NOTIFY: fprintf(fp, "notify"); break; case EAP_TYPE_NAK: fprintf(fp, "nak"); break; case EAP_TYPE_MD5: fprintf(fp, "md5"); break; case EAP_TYPE_OTP: fprintf(fp, "otp"); break; case EAP_TYPE_GTC: fprintf(fp, "token"); break; case EAP_TYPE_TLS: fprintf(fp, "tls"); break; default: fprintf(fp, "undef"); break; } } fprintf(fp, "\n"); } /**************************************************************************** * * Function: PrintEapolKey(FILE *) * * Purpose: Dump the EAP header to the specified file stream * * Arguments: fp => file stream * * Returns: void function * ***************************************************************************/ void PrintEapolKey(FILE * fp, Packet * p) { uint16_t length; if(p->eapolk == NULL) { fprintf(fp, "Eapol Key truncated\n"); return; } fprintf(fp, "KEY type: "); if (p->eapolk->type == 1) { fprintf(fp, "RC4"); } memcpy(&length, &p->eapolk->length, 2); length = ntohs(length); fprintf(fp, " len: %d", length); fprintf(fp, " index: %d ", p->eapolk->index & 0x7F); fprintf(fp, p->eapolk->index & 0x80 ? " unicast\n" : " broadcast\n"); } #endif // NO_NON_ETHER_DECODER void PrintIpAddrs(FILE *fp, Packet *p) { if (!IPH_IS_VALID(p)) return; if (p->frag_flag || ((GET_IPH_PROTO(p) != IPPROTO_TCP) && (GET_IPH_PROTO(p) != IPPROTO_UDP))) { char *ip_fmt = "%s -> %s"; if (ScObfuscate()) { fprintf(fp, ip_fmt, ObfuscateIpToText(GET_SRC_ADDR(p)), ObfuscateIpToText(GET_DST_ADDR(p))); } else { fprintf(fp, ip_fmt, inet_ntoax(GET_SRC_ADDR(p)), inet_ntoax(GET_DST_ADDR(p))); } } else { char *ip_fmt = "%s:%d -> %s:%d"; if (ScObfuscate()) { fprintf(fp, ip_fmt, ObfuscateIpToText(GET_SRC_ADDR(p)), p->sp, ObfuscateIpToText(GET_DST_ADDR(p)), p->dp); } else { fprintf(fp, ip_fmt, inet_ntoax(GET_SRC_ADDR(p)), p->sp, inet_ntoax(GET_DST_ADDR(p)), p->dp); } } } snort-2.9.15.1/src/log.h0000644000175200017520000000643413571422607011600 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifndef __LOG_H__ #define __LOG_H__ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "event.h" #include "decode.h" #ifndef LOG_AUTHPRIV # define LOG_AUTHPRIV LOG_AUTH #endif #define FRAME_SIZE 66 #define C_OFFSET 49 /* P R O T O T Y P E S ******************************************************/ void PrintIpAddrs(FILE *, Packet *); void PrintIPPkt(FILE *, int,Packet*); void PrintNetData(FILE *, const u_char *, const int, Packet *); void ClearDumpBuf(void); void Print2ndHeader(FILE *, Packet *); void PrintEthHeader(FILE *, Packet *); #ifdef MPLS void PrintMPLSHeader(FILE *, Packet *); #endif #ifdef GRE void PrintGREHeader(FILE *, Packet *); void PrintOuterIPHeader(FILE *, Packet *); #endif void PrintIPHeader(FILE *, Packet *); void PrintTCPHeader(FILE *, Packet *); void PrintTcpOptions(FILE *, Packet *); void PrintIpOptions(FILE *, Packet *); void PrintICMPHeader(FILE *, Packet *); void PrintICMPEmbeddedIP(FILE *, Packet *); void PrintEmbeddedICMPHeader(FILE *, const ICMPHdr *); void PrintUDPHeader(FILE *, Packet *); void PrintPriorityData(FILE *, int); void PrintXrefs(FILE *, int); void CreateTCPFlagString(Packet *, char *); #ifndef NO_NON_ETHER_DECODER void PrintEapolPkt(FILE *, Packet *); void PrintEapolKey(FILE *, Packet *); void PrintWifiPkt(FILE *, Packet *); void PrintTrHeader(FILE *, Packet *); void PrintWifiHeader(FILE *, Packet *); void PrintSLLHeader(FILE *, Packet *); void PrintArpHeader(FILE *, Packet *); void PrintEapolHeader(FILE *, Packet *); void PrintEAPHeader(FILE *, Packet *); #endif void NoLog(Packet *, char *, void *, Event *); void NoAlert(Packet *, char *, void *, Event *); FILE *OpenAlertFile(const char *); int RollAlertFile(const char *); #ifndef WIN32 void SetEvent(Event *, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, #if !defined(FEAT_OPEN_APPID) uint32_t); #else /* defined(FEAT_OPEN_APPID) */ uint32_t, char *); #endif /* defined(FEAT_OPEN_APPID) */ #else /* There is a naming conflict with a Win32 standard function, so compensate */ #define SetEvent SnortSetEvent void SnortSetEvent(Event *, uint32_t, uint32_t, uint32_t, uint32_t, #if !defined(FEAT_OPEN_APPID) uint32_t, uint32_t); #else /* defined(FEAT_OPEN_APPID) */ uint32_t, uint32_t, char *); #endif /* defined(FEAT_OPEN_APPID) */ #endif #endif /* __LOG_H__ */ snort-2.9.15.1/src/mstring.c0000644000175200017520000006172013571422607012474 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /*************************************************************************** * * File: MSTRING.C * * Purpose: Provide a variety of string functions not included in libc. Makes * up for the fact that the libstdc++ is hard to get reference * material on and I don't want to write any more non-portable c++ * code until I have solid references and libraries to use. * * History: * * 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 * 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 * **************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "sf_types.h" #include "mstring.h" #include "snort_debug.h" #include "plugbase.h" /* needed for fasthex() */ #include "util.h" #include "detection_util.h" static char * mSplitAddTok(const char *, const int, const char *, const char); #ifdef TEST_MSTRING int main() { char test[] = "\0\0\0\0\0\0\0\0\0CKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\0\0"; char find[] = "CKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\0\0"; /* char test[] = "\x90\x90\x90\x90\x90\x90\xe8\xc0\xff\xff\xff/bin/sh\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"; char find[] = "\xe8\xc0\xff\xff\xff/bin/sh"; */ int i; int toks; int *shift; int *skip; /* shift=make_shift(find,sizeof(find)-1); skip=make_skip(find,sizeof(find)-1); */ DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,"%d\n", mSearch(test, sizeof(test) - 1, find, sizeof(find) - 1, shift, skip));); return 0; } #endif /**************************************************************** * * Function: mSplit() * * Purpose: Splits a string into tokens non-destructively. * * Parameters: * char * * The string to be split * char * * A string of token seperaters * int * The maximum number of tokens to be returned. A value * of 0 means to get them all. * int * * Place to store the number of tokens returned * char * The "escape metacharacter", treat the character after * this character as a literal and "escape" a seperator. * * Note if max_toks is reached, the last tok in the returned * token array will possibly have separator characters in it. * * Returns: * 2D char array with one token per "row" of the returned * array. * ****************************************************************/ char ** mSplit(const char *str, const char *sep_chars, const int max_toks, int *num_toks, const char meta_char) { size_t cur_tok = 0; /* current token index into array of strings */ size_t tok_start; /* index to start of token */ size_t i, j; int escaped = 0; /* It's rare we'll need more than this even if max_toks is set really * high. Store toks here until finished, then allocate. If more than * this is necessary, then allocate max toks */ char *toks_buf[TOKS_BUF_SIZE]; size_t toks_buf_size = TOKS_BUF_SIZE; int toks_buf_size_increment = 10; char **toks_alloc = NULL; /* Used if the static buf isn't enough */ char **toks = toks_buf; /* Pointer to one of the two above */ char **retstr; char *whitespace = " \t"; size_t str_length, sep_length; assert (num_toks); *num_toks = 0; if (str == NULL) return NULL; str_length = strlen(str); if (str_length == 0) return NULL; if (sep_chars == NULL) sep_chars = whitespace; sep_length = strlen(sep_chars); if (sep_length == 0) return NULL; /* Meta char cannot also be a separator char */ for (i = 0; i < sep_length; i++) { if (sep_chars[i] == meta_char) return NULL; } /* Move past initial separator characters and whitespace */ for (i = 0; i < str_length; i++) { if (isspace((int)str[i])) continue; for (j = 0; j < sep_length; j++) { if (str[i] == sep_chars[j]) break; } /* Not a separator character or whitespace */ if (j == sep_length) break; } if (i == str_length) { /* Nothing but separator characters or whitespace in string */ return NULL; } /* User only wanted one tok so return the rest of the string in * one tok */ if ((cur_tok + 1) == (size_t)max_toks) { retstr = (char **)SnortAlloc(sizeof(char *)); retstr[cur_tok] = SnortStrndup(&str[i], str_length - i); if (retstr[cur_tok] == NULL) { mSplitFree(&retstr, cur_tok + 1); return NULL; } *num_toks = cur_tok + 1; return retstr; } /* Mark the beginning of the next tok */ tok_start = i; for (; i < str_length; i++) { if (!escaped) { /* Got an escape character. Don't include it now, but * must be a character after it. */ if (str[i] == meta_char) { escaped = 1; continue; } /* See if the current character is a separator */ for (j = 0; j < sep_length; j++) { if (str[i] == sep_chars[j]) break; } /* It's a normal character */ if (j == sep_length) continue; /* Current character matched a separator character. Trim off * whitespace previous to the separator. If we get here, there * is at least one savable character */ for (j = i; j > tok_start; j--) { if (!isspace((int)str[j - 1])) break; } /* Allocate a buffer. The length will not have included the * meta char of escaped separators */ toks[cur_tok] = mSplitAddTok(&str[tok_start], j - tok_start, sep_chars, meta_char); /* Increment current token index */ cur_tok++; /* Move past any more separator characters or whitespace */ for (; i < str_length; i++) { if (isspace((int)str[i])) continue; for (j = 0; j < sep_length; j++) { if (str[i] == sep_chars[j]) break; } /* Not a separator character or whitespace */ if (j == sep_length) break; } /* Nothing but separator characters or whitespace left in the string */ if (i == str_length) { *num_toks = cur_tok; if (toks != toks_alloc) { retstr = (char **)SnortAlloc(sizeof(char *) * cur_tok); memcpy(retstr, toks, (sizeof(char *) * cur_tok)); } else { retstr = toks; } return retstr; } /* Reached the size of our current string buffer and need to * allocate something bigger. Only get here once if max toks * set to something other than 0 because we'll just allocate * max toks in that case. */ if (cur_tok == toks_buf_size) { char **tmp; if (toks_alloc != NULL) tmp = toks_alloc; else tmp = toks_buf; if (max_toks != 0) toks_buf_size = max_toks; else toks_buf_size = cur_tok + toks_buf_size_increment; toks_alloc = (char **)SnortAlloc(sizeof(char *) * toks_buf_size); memcpy(toks_alloc, tmp, (sizeof(char *) * cur_tok)); toks = toks_alloc; if (tmp != toks_buf) free(tmp); } if ((max_toks != 0) && ((cur_tok + 1) == (size_t)max_toks)) { /* Return rest of string as last tok */ *num_toks = cur_tok + 1; /* Already got a ret string */ if (toks != toks_alloc) { retstr = (char **)SnortAlloc(sizeof(char *) * (cur_tok + 1)); memcpy(retstr, toks, (sizeof(char *) * (cur_tok + 1))); } else { retstr = toks; } /* Trim whitespace at end of last tok */ for (j = str_length; j > tok_start; j--) { if (!isspace((int)str[j - 1])) break; } retstr[cur_tok] = SnortStrndup(&str[i], j - i); if (retstr[cur_tok] == NULL) { mSplitFree(&retstr, cur_tok + 1); return NULL; } return retstr; } tok_start = i--; } else { /* This character is escaped with the meta char */ escaped = 0; } } /* Last character was an escape character */ if (escaped) { for (i = 0; i < cur_tok; i++) free(toks[i]); if (toks == toks_alloc) free(toks_alloc); return NULL; } /* Trim whitespace at end of last tok */ for (j = i; j > tok_start; j--) { if (!isspace((int)str[j - 1])) break; } /* Last character was not a separator character so we've got * one more tok. Unescape escaped sepatator charactors */ if (toks != toks_alloc) { retstr = (char **)SnortAlloc(sizeof(char *) * (cur_tok + 1)); memcpy(retstr, toks, (sizeof(char *) * (cur_tok + 1))); } else { retstr = toks; } retstr[cur_tok] = mSplitAddTok(&str[tok_start], j - tok_start, sep_chars, meta_char); /* Just add one to cur_tok index instead of incrementing * since we're done */ *num_toks = cur_tok + 1; return retstr; } /* Will not return NULL. SnortAlloc will fatal if it fails */ static char * mSplitAddTok(const char *str, const int len, const char *sep_chars, const char meta_char) { size_t i, j, k; char *tok; int tok_len = 0; int got_meta = 0; size_t sep_length = strlen(sep_chars); /* Get the length of the returned tok * Could have a maximum token length and use a fixed sized array and * fill it in as we go but don't want to put on that constraint */ for (i = 0; (int)i < len; i++) { if (!got_meta) { if (str[i] == meta_char) { got_meta = 1; continue; } } else { /* See if the current character is a separator */ for (j = 0; j < sep_length; j++) { if (str[i] == sep_chars[j]) break; } /* It's a non-separator character, so include * the meta character in the return tok */ if (j == sep_length) tok_len++; got_meta = 0; } tok_len++; } /* Allocate it and fill it in */ tok = (char *)SnortAlloc(tok_len + 1); for (i = 0, k = 0; (int)i < len; i++) { if (!got_meta) { if (str[i] == meta_char) { got_meta = 1; continue; } } else { /* See if the current character is a separator */ for (j = 0; j < sep_length; j++) { if (str[i] == sep_chars[j]) break; } /* It's a non-separator character, so include * the meta character in the return tok */ if (j == sep_length) tok[k++] = meta_char; got_meta = 0; } tok[k++] = str[i]; } return tok; } /**************************************************************** * * Free the buffer allocated by mSplit(). * * char** toks = NULL; * int num_toks = 0; * toks = (str, " ", 2, &num_toks, 0); * mSplitFree(&toks, num_toks); * * At this point, toks is again NULL. * ****************************************************************/ void mSplitFree(char ***pbuf, int num_toks) { int i; char** buf; /* array of string pointers */ if( pbuf==NULL || *pbuf==NULL ) { return; } buf = *pbuf; for( i=0; i 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)) { DEBUG_WRAP(DebugMessage(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; } /**************************************************************** * * Function: make_skip(char *, int) * * Purpose: Create a Boyer-Moore skip table for a given pattern * * Parameters: * ptrn => pattern * plen => length of the data in the pattern buffer * * Returns: * int * - the skip table * ****************************************************************/ int *make_skip(char *ptrn, int plen) { int i; int *skip = (int *) SnortAlloc(256* sizeof(int)); for ( i = 0; i < 256; i++ ) skip[i] = plen + 1; while(plen != 0) skip[(unsigned char) *ptrn++] = plen--; return skip; } /**************************************************************** * * Function: make_shift(char *, int) * * Purpose: Create a Boyer-Moore shift table for a given pattern * * Parameters: * ptrn => pattern * plen => length of the data in the pattern buffer * * Returns: * int * - the shift table * ****************************************************************/ int *make_shift(char *ptrn, int plen) { int *shift = (int *) SnortAlloc(plen * sizeof(int)); int *sptr = shift + plen - 1; char *pptr = ptrn + plen - 1; char c; c = ptrn[plen - 1]; *sptr = 1; while(sptr-- != shift) { char *p1 = ptrn + plen - 2, *p2, *p3; do { while(p1 >= ptrn && *p1-- != c); p2 = ptrn + plen - 2; p3 = p1; while(p3 >= ptrn && *p3-- == *p2-- && p2 >= pptr); } while(p3 >= ptrn && p2 >= pptr); *sptr = shift + plen - sptr + p2 - p3; pptr--; } return shift; } /**************************************************************** * * Function: mSearch(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 * 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: * Integer value, 1 on success (str constains substr), 0 on * failure (substr not in str) * ****************************************************************/ int mSearch(const char *buf, int blen, const char *ptrn, int plen, int *skip, int *shift) { int b_idx = plen; #ifdef DEBUG_MSGS char *hexbuf; int cmpcnt = 0; #endif DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,"buf: %p blen: %d ptrn: %p " "plen: %d\n", buf, blen, ptrn, plen);); #ifdef DEBUG_MSGS hexbuf = fasthex((const u_char *)buf, blen); DebugMessage(DEBUG_PATTERN_MATCH,"buf: %s\n", hexbuf); free(hexbuf); hexbuf = fasthex((const u_char *)ptrn, plen); DebugMessage(DEBUG_PATTERN_MATCH,"ptrn: %s\n", hexbuf); free(hexbuf); DebugMessage(DEBUG_PATTERN_MATCH,"buf: %p blen: %d ptrn: %p " "plen: %d\n", buf, blen, ptrn, plen); #endif /* DEBUG_MSGS */ if(plen == 0) return 1; while(b_idx <= blen) { int p_idx = plen, skip_stride, shift_stride; while(buf[--b_idx] == ptrn[--p_idx]) { #ifdef DEBUG_MSGS cmpcnt++; #endif if(b_idx < 0) return 0; if(p_idx == 0) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "match: compares = %d.\n", cmpcnt);); UpdateDoePtr(((const uint8_t *)&(buf[b_idx]) + plen), 0); return 1; } } skip_stride = skip[(unsigned char) buf[b_idx]]; shift_stride = shift[p_idx]; b_idx += (skip_stride > shift_stride) ? skip_stride : shift_stride; } DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "no match: compares = %d.\n", cmpcnt);); return 0; } /**************************************************************** * * Function: mSearchCI(char *, int, char *, int) * * Purpose: Determines if a string contains a (non-regex) * substring matching is case insensitive * * 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: * Integer value, 1 on success (str constains substr), 0 on * failure (substr not in str) * ****************************************************************/ int mSearchCI(const char *buf, int blen, const char *ptrn, int plen, int *skip, int *shift) { int b_idx = plen; #ifdef DEBUG_MSGS int cmpcnt = 0; #endif if(plen == 0) return 1; while(b_idx <= blen) { int p_idx = plen, skip_stride, shift_stride; while((unsigned char) ptrn[--p_idx] == toupper((unsigned char) buf[--b_idx])) { #ifdef DEBUG_MSGS cmpcnt++; #endif if(p_idx == 0) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "match: compares = %d.\n", cmpcnt);); UpdateDoePtr(((const uint8_t *)&(buf[b_idx]) + plen), 0); return 1; } } skip_stride = skip[toupper((unsigned char) buf[b_idx])]; shift_stride = shift[p_idx]; b_idx += (skip_stride > shift_stride) ? skip_stride : shift_stride; } DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "no match: compares = %d.\n", cmpcnt);); return 0; } /**************************************************************** * * 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: * Integer value, 1 on success (str constains substr), 0 on * failure (substr not in str) * ****************************************************************/ 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 */ DEBUG_WRAP( DebugMessage(DEBUG_PATTERN_MATCH, "buf: %p blen: %d ptrn: %p " " plen: %d b_idx: %d\n", buf, blen, ptrn, plen, b_idx); DebugMessage(DEBUG_PATTERN_MATCH, "packet data: \"%s\"\n", buf); DebugMessage(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; DEBUG_WRAP(DebugMessage(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)) { DEBUG_WRAP(DebugMessage(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] == '*') { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,"Checking wildcard matching...\n");); while(p_idx != 0 && ptrn[--p_idx] == '*'); /* fool-proof */ while(buf[--b_idx] != ptrn[p_idx]) { DEBUG_WRAP(DebugMessage(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) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "b_idx went to 0, returning 0\n");) return 0; } } DEBUG_WRAP(DebugMessage(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) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "match: compares = %d.\n", cmpcnt);); return 1; } if(b_idx == 0) break; } DEBUG_WRAP(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; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "b_idx skip-shifted to %d\n", b_idx);); b_idx += regexcomp; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "b_idx regex compensated %d steps, to %d\n", regexcomp, b_idx);); regexcomp = 0; } DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "no match: compares = %d, b_idx = %d, " "blen = %d\n", cmpcnt, b_idx, blen);); return 0; } snort-2.9.15.1/src/mstring.h0000644000175200017520000000320713571422607012475 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifndef __MSTRING_H__ #define __MSTRING_H__ /* D E F I N E S *******************************************************/ #define TOKS_BUF_SIZE 100 /* P R O T O T Y P E S *************************************************/ char ** mSplit(const char *, const char *, const int, int *, const char); void mSplitFree(char ***toks, int numtoks); int mContainsSubstr(const char *, int, const 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 *); int *make_skip(char *, int); int *make_shift(char *, int); #endif /* __MSTRING_H__ */ snort-2.9.15.1/src/hashstring.c0000644000175200017520000001077113571422607013163 00000000000000 /* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /*************************************************************************** * * File: HashString.C * * Purpose: Provide a hashed string compare function. * * History: * * Date: Author: Notes: * ---------- ------- ---------------------------------------------- * 10/02/13 ECB Initial coding begun * **************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "sf_types.h" #include "hashstring.h" #include "snort_debug.h" #include "util.h" #include "sf_sechash.h" #include "detection_util.h" #ifdef TEST_HASHSTRING int main() { char test[] = "\0\0\0\0\0\0\0\0\0CKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\0\0"; char find[] = "CKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\0\0"; /* char test[] = "\x90\x90\x90\x90\x90\x90\xe8\xc0\xff\xff\xff/bin/sh\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"; char find[] = "\xe8\xc0\xff\xff\xff/bin/sh"; */ int i; int toks; int *shift; int *skip; /* shift=make_shift(find,sizeof(find)-1); skip=make_skip(find,sizeof(find)-1); */ DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,"%d\n", mSearch(test, sizeof(test) - 1, find, sizeof(find) - 1, shift, skip));); return 0; } #endif /**************************************************************** * * Function: hashSearchFixed(char *, int, Secure_Hash_Type type, char *) * * Purpose: Determines if a string hashes to a given hash digest. * * Parameters: * buf => data buffer we want to find the data in * blen => data buffer length * type => Pattern_Type * ptrn => pattern to find * * Returns: * Integer value, 1 on success (hash of string matches pattern), 0 on * failure * ****************************************************************/ int hashSearchFixed(const char *buf, int blen, const Secure_Hash_Type type, const char *ptrn) { unsigned char *digest; size_t pattern_length; #ifdef DEBUG_MSGS char *hexbuf; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,"buf: %p blen: %d ptrn: %p " "type: %d\n", buf, blen, ptrn, (int)type);); hexbuf = fasthex((const u_char *)buf, blen); DebugMessage(DEBUG_PATTERN_MATCH,"buf: %s\n", hexbuf); free(hexbuf); hexbuf = fasthex((const u_char *)ptrn, strlen(ptrn)); DebugMessage(DEBUG_PATTERN_MATCH,"ptrn: %s\n", hexbuf); free(hexbuf); #endif /* DEBUG_MSGS */ if((blen == 0) || (ptrn == NULL) || (buf == NULL)) return( 0 ); switch( type ) { case SECHASH_MD5: { digest = MD5DIGEST((const unsigned char *)buf, (unsigned int)blen, NULL); pattern_length = MD5_HASH_SIZE; break; } case SECHASH_SHA256: { digest = SHA256DIGEST((const unsigned char *)buf, (unsigned int)blen, NULL); pattern_length = SHA256_HASH_SIZE; break; } case SECHASH_SHA512: { digest = SHA512DIGEST((const unsigned char *)buf, (unsigned int)blen, NULL); pattern_length = SHA512_HASH_SIZE; break; } default: { return( 0 ); } } if(memcmp((const void *)digest, (const void *)ptrn, pattern_length) == 0) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "match\n");); UpdateDoePtr(((const uint8_t *)&(buf[0]) + blen), 0); return 1; } DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "no match\n");); return 0; } snort-2.9.15.1/src/hashstring.h0000644000175200017520000000234513571422607013166 00000000000000 /* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __HASHSTRING_H__ #define __HASHSTRING_H__ #include "sf_sechash.h" /* D E F I N E S *******************************************************/ /* P R O T O T Y P E S *************************************************/ int hashSearchFixed(const char *, int, const Secure_Hash_Type type, const char *); #endif /* __HASHSTRING_H__ */ snort-2.9.15.1/src/parser.c0000644000175200017520000131747013571422607012314 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** Copyright (C) 2000,2001 Andrew R. Baker ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_DUMBNET_H #include #else #include #endif #ifdef HAVE_STRINGS_H # include #endif #ifndef WIN32 # include # include # include # include # include # include # include #endif /* !WIN32 */ #include "encode.h" #include "snort_bounds.h" #include "rules.h" #include "treenodes.h" #include "parser.h" #include "plugbase.h" #include "plugin_enum.h" #include "snort_debug.h" #include "util.h" #include "mstring.h" #include "detect.h" #include "fpcreate.h" #include "log.h" #include "generators.h" #include "tag.h" #include "signature.h" #include "strlcatu.h" #include "strlcpyu.h" #include "sfthreshold.h" #include "sfutil/sfthd.h" #include "snort.h" #include "event_queue.h" #include "asn1.h" #include "sfutil/sfghash.h" #include "sp_preprocopt.h" #include "detection-plugins/sp_icmp_type_check.h" #include "detection-plugins/sp_ip_proto.h" #include "detection-plugins/sp_pattern_match.h" #include "detection-plugins/sp_flowbits.h" #include "sf_vartable.h" #include "ipv6_port.h" #include "sfutil/sf_ip.h" #include "sflsq.h" #include "ppm.h" #include "rate_filter.h" #include "detection_filter.h" #include "sfPolicy.h" #include "sfutil/mpse.h" #include "sfutil/sfrim.h" #include "sfutil/sfportobject.h" #include "sfutil/strvec.h" #include "active.h" #include "file_config.h" #include "file_service_config.h" #include "dynamic-plugins/sp_dynamic.h" #include "dynamic-output/plugins/output.h" #ifdef SIDE_CHANNEL # include "sidechannel.h" #endif #ifdef TARGET_BASED # include "sftarget_reader.h" #endif /* Macros *********************************************************************/ #define ENABLE_ALL_RULES 1 #define ENABLE_RULE 1 #define ENABLE_ONE_RULE 0 #define MAX_RULE_OPTIONS 256 #define MAX_LINE_LENGTH 32768 #define MAX_IPLIST_ENTRIES 4096 #define DEFAULT_LARGE_RULE_GROUP 9 #define SF_IPPROTO_UNKNOWN -1 #define MAX_RULE_COUNT (65535 * 2) /* Rule list order keywords * This is separate from keywords because activation was used * instead of activate */ #define RULE_LIST_TYPE__ALERT "alert" #define RULE_LIST_TYPE__DROP "drop" #define RULE_LIST_TYPE__LOG "log" #define RULE_LIST_TYPE__PASS "pass" #define RULE_LIST_TYPE__REJECT "reject" #define RULE_LIST_TYPE__SDROP "sdrop" #define RULE_PROTO_OPT__IP "ip" #define RULE_PROTO_OPT__TCP "tcp" #define RULE_PROTO_OPT__UDP "udp" #define RULE_PROTO_OPT__ICMP "icmp" #define RULE_DIR_OPT__DIRECTIONAL "->" #define RULE_DIR_OPT__BIDIRECTIONAL "<>" /* For user defined rule type */ #define RULE_TYPE_OPT__TYPE "type" /* Rule options * Only the basic ones are here. The detection options and preprocessor * detection options define their own */ #define RULE_OPT__CLASSTYPE "classtype" #define RULE_OPT__DETECTION_FILTER "detection_filter" #define RULE_OPT__GID "gid" #define RULE_OPT__MSG "msg" #define RULE_OPT__METADATA "metadata" #define RULE_OPT__LOGTO "logto" #define RULE_OPT__PRIORITY "priority" #define RULE_OPT__REFERENCE "reference" #define RULE_OPT__REVISION "rev" #define RULE_OPT__SID "sid" #define RULE_OPT__TAG "tag" #define RULE_OPT__THRESHOLD "threshold" /* Metadata rule option keys */ #define METADATA_KEY__ENGINE "engine" #define METADATA_KEY__OS "os" #define METADATA_KEY__RULE_FLUSHING "rule-flushing" #define METADATA_KEY__RULE_TYPE "rule-type" #define METADATA_KEY__SOID "soid" #define METADATA_KEY__SERVICE "service" /* Metadata rule option values */ #define METADATA_VALUE__DECODE "decode" #define METADATA_VALUE__DETECT "detect" #define METADATA_VALUE__DISABLED "disabled" #define METADATA_VALUE__ENABLED "enabled" #define METADATA_VALUE__OFF "off" #define METADATA_VALUE__ON "on" #define METADATA_VALUE__PREPROC "preproc" #define METADATA_VALUE__SHARED "shared" /* MPLS payload types */ #ifdef MPLS # define MPLS_PAYLOAD_OPT__IPV4 "ipv4" # define MPLS_PAYLOAD_OPT__IPV6 "ipv6" # define MPLS_PAYLOAD_OPT__ETHERNET "ethernet" #endif /* Tag options */ #define TAG_OPT__BYTES "bytes" #define TAG_OPT__DST "dst" #define TAG_OPT__HOST "host" #define TAG_OPT__PACKETS "packets" #define TAG_OPT__SECONDS "seconds" #define TAG_OPT__SESSION "session" #define TAG_OPT__SRC "src" #define TAG_OPT__EXCLUSIVE "exclusive" /* Dynamic library specifier option values */ #define DYNAMIC_LIB_OPT__FILE "file" #define DYNAMIC_LIB_OPT__DIRECTORY "directory" /* Threshold options */ #define THRESHOLD_OPT__COUNT "count" #define THRESHOLD_OPT__GID "gen_id" #define THRESHOLD_OPT__IP "ip" #define THRESHOLD_OPT__SECONDS "seconds" #define THRESHOLD_OPT__SID "sig_id" #define THRESHOLD_OPT__TRACK "track" #define THRESHOLD_OPT__TYPE "type" #define THRESHOLD_TYPE__BOTH "both" #define THRESHOLD_TYPE__LIMIT "limit" #define THRESHOLD_TYPE__THRESHOLD "threshold" #define THRESHOLD_TRACK__BY_DST "by_dst" #define THRESHOLD_TRACK__BY_SRC "by_src" #define RULE_STATE_OPT__DISABLED "disabled" #define RULE_STATE_OPT__ENABLED "enabled" #define DETECTION_OPT__BLEEDOVER_PORT_LIMIT "bleedover-port-limit" #define DETECTION_OPT__BLEEDOVER_WARNINGS_ENABLED "bleedover-warnings-enabled" #define DETECTION_OPT__DEBUG "debug" #define DETECTION_OPT__DEBUG_PRINT_NOCONTENT_RULE_TESTS "debug-print-nocontent-rule-tests" #define DETECTION_OPT__DEBUG_PRINT_RULE_GROUP_BUILD_DETAILS "debug-print-rule-group-build-details" #define DETECTION_OPT__DEBUG_PRINT_RULE_GROUPS_UNCOMPILED "debug-print-rule-groups-uncompiled" #define DETECTION_OPT__DEBUG_PRINT_RULE_GROUPS_COMPILED "debug-print-rule-groups-compiled" #define DETECTION_OPT__ENABLE_SINGLE_RULE_GROUP "enable-single-rule-group" #define DETECTION_OPT__MAX_QUEUE_EVENTS "max_queue_events" #define DETECTION_OPT__NO_STREAM_INSERTS "no_stream_inserts" #define DETECTION_OPT__SEARCH_METHOD "search-method" #define DETECTION_OPT__SEARCH_OPTIMIZE "search-optimize" #define DETECTION_OPT__SPLIT_ANY_ANY "split-any-any" #define DETECTION_OPT__MAX_PATTERN_LEN "max-pattern-len" #define DETECTION_OPT__DEBUG_PRINT_FAST_PATTERN "debug-print-fast-pattern" /* Protected Content options - there should be a better way instead of declaring the type strings here */ #define PROTECTED_CONTENT_OPT__HASH_TYPE "hash" #define EVENT_QUEUE_OPT__LOG "log" #define EVENT_QUEUE_OPT__MAX_QUEUE "max_queue" #define EVENT_QUEUE_OPT__ORDER_EVENTS "order_events" #define EVENT_QUEUE_OPT__PROCESS_ALL_EVENTS "process_all_events" #define EVENT_TRACE_OPT__FILE "file" #define EVENT_TRACE_OPT__MAX_DATA "max_data" #define EVENT_TRACE_OPT__FILE_DEFAULT "event_trace.txt" #define EVENT_TRACE_OPT__MAX_DATA_DEFAULT 64 #define ORDER_EVENTS_OPT__CONTENT_LENGTH "content_length" #define ORDER_EVENTS_OPT__PRIORITY "priority" #define THRESHOLD_OPT__MEMCAP "memcap" #define CHECKSUM_MODE_OPT__ALL "all" #define CHECKSUM_MODE_OPT__NONE "none" #define CHECKSUM_MODE_OPT__IP "ip" #define CHECKSUM_MODE_OPT__NO_IP "noip" #define CHECKSUM_MODE_OPT__TCP "tcp" #define CHECKSUM_MODE_OPT__NO_TCP "notcp" #define CHECKSUM_MODE_OPT__UDP "udp" #define CHECKSUM_MODE_OPT__NO_UDP "noudp" #define CHECKSUM_MODE_OPT__ICMP "icmp" #define CHECKSUM_MODE_OPT__NO_ICMP "noicmp" #define RULE_STATE_OPT__DISABLED "disabled" #define RULE_STATE_OPT__ENABLED "enabled" #define POLICY_MODE_PASSIVE "tap" #define POLICY_MODE_INLINE "inline" #define POLICY_MODE_INLINE_TEST "inline_test" #ifdef PERF_PROFILING # define PROFILE_OPT__FILENAME "filename" # define PROFILE_OPT__PRINT "print" # define PROFILE_OPT__ALL "all" # define PROFILE_OPT__SORT "sort" # define PROFILE_OPT__CHECKS "checks" # define PROFILE_OPT__AVG_TICKS "avg_ticks" # define PROFILE_OPT__TOTAL_TICKS "total_ticks" # define PROFILE_OPT__MATCHES "matches" # define PROFILE_OPT__NO_MATCHES "nomatches" # define PROFILE_OPT__AVG_TICKS_PER_MATCH "avg_ticks_per_match" # define PROFILE_OPT__AVG_TICKS_PER_NO_MATCH "avg_ticks_per_nomatch" # define PROFILE_OPT__APPEND "append" #endif #ifdef PPM_MGR # define PPM_OPT__MAX_PKT_TIME "max-pkt-time" # define PPM_OPT__MAX_RULE_TIME "max-rule-time" # define PPM_OPT__SUSPEND_TIMEOUT "suspend-timeout" # define PPM_OPT__SUSPEND_EXP_RULES "suspend-expensive-rules" # define PPM_OPT__THRESHOLD "threshold" # define PPM_OPT__FAST_PATH_EXP_PKTS "fastpath-expensive-packets" # define PPM_OPT__PKT_LOG "pkt-log" # define PPM_OPT__RULE_LOG "rule-log" # define PPM_OPT__ALERT "alert" # define PPM_OPT__LOG "log" # define PPM_OPT__DEBUG_PKTS "debug-pkts" #endif #ifdef ACTIVE_RESPONSE #define RESPONSE_OPT__ATTEMPTS "attempts" #define RESPONSE_OPT__DEVICE "device" #define RESPONSE_OPT__DST_MAC "dst_mac" #endif #define ERR_PAIR_COUNT \ "%s has incorrect argument count; should be %d pairs.", ERR_KEY #define ERR_NOT_PAIRED \ "%s is missing an option or argument to go with: %s.", ERR_KEY, pairs[0] #define ERR_EXTRA_OPTION \ "%s has extra option of type: %s.", ERR_KEY, pairs[0] #define ERR_BAD_OPTION \ "%s has unknown option: %s.", ERR_KEY, pairs[0] #define ERR_BAD_VALUE \ "%s has unknown %s: %s.", ERR_KEY, pairs[0], pairs[1] #define ERR_BAD_ARG_COUNT \ "%s has incorrect argument count.", ERR_KEY #define ERR_CREATE \ "%s could not be created.", ERR_KEY #define ERR_CREATE_EX \ "%s could not be created: %s.", ERR_KEY // arbitrary conf file name used to allow initialization w/o conf // (required for packet logging mode) #define NULL_CONF "null" /* Data types *****************************************************************/ typedef void (*ParseFunc)(SnortConfig *, SnortPolicy *, char *); typedef void (*ParseConfigFunc)(SnortConfig *, char *); typedef void (*ParseRuleOptFunc)(SnortConfig *, RuleTreeNode *, OptTreeNode *, RuleType, char *); /* Used to determine whether or not to parse the keyword line based on * whether or not we're parsing rules */ typedef enum _KeywordType { KEYWORD_TYPE__MAIN, KEYWORD_TYPE__RULE, KEYWORD_TYPE__ALL } KeywordType; typedef enum _VarType { VAR_TYPE__DEFAULT, VAR_TYPE__PORTVAR, VAR_TYPE__IPVAR } VarType; typedef struct _KeywordFunc { char *name; KeywordType type; int expand_vars; int default_policy_only; ParseFunc parse_func; } KeywordFunc; typedef struct _RuleOptFunc { char *name; int args_required; int only_once; int detection; ParseRuleOptFunc parse_func; } RuleOptFunc; typedef struct _ConfigFunc { char *name; int args_required; int only_once; int default_policy_only; ParseConfigFunc parse_func; } ConfigFunc; /* Tracking the port_list_t structure for printing and debugging at * this point...temporarily... */ typedef struct { int rule_type; int proto; int icmp_type; int ip_proto; char *protocol; char *src_port; char *dst_port; unsigned int gid; unsigned int sid; int dir; char content; char uricontent; } port_entry_t; typedef struct { int pl_max; int pl_cnt; port_entry_t pl_array[MAX_RULE_COUNT]; } port_list_t; /* rule counts for port lists */ typedef struct { int src; int dst; int aa; /* any-any */ int sd; /* src+dst ports specified */ int nc; /* no content */ } rule_count_t; /* Externs ********************************************************************/ extern VarNode *cmd_line_var_list; extern char *snort_conf_file; extern char *snort_conf_dir; extern RuleOptConfigFuncNode *rule_opt_config_funcs; /* Globals ********************************************************************/ char *file_name = NULL; /* current config file being processed */ int file_line = 0; /* current line being processed in the file */ /* Main parsing function uses this to indicate whether or not * rules are to be parsed. */ static int parse_rules = 0; /* Used when parsing rule options and a threshold is used. Need to add * sid and gid to threshold object and they might not have been * parsed yet. */ static THDX_STRUCT *thdx_tmp = NULL; int rule_count = 0; /* number of rules generated */ int detect_rule_count = 0; /* number of detection rules generated */ int decode_rule_count = 0; /* number of decoder rules generated */ int preproc_rule_count = 0; /* number of preprocessor rules generated */ int head_count = 0; /* number of header blocks (chain heads?) */ int otn_count = 0; /* number of chains */ static port_list_t port_list; static rule_count_t tcpCnt; static rule_count_t udpCnt; static rule_count_t icmpCnt; static rule_count_t ipCnt; rule_index_map_t *ruleIndexMap = NULL; /* rule index -> sid:gid map */ static void ParseAlert(SnortConfig *, SnortPolicy *, char *); static void ParseDrop(SnortConfig *, SnortPolicy *, char *); static void ParseLog(SnortConfig *, SnortPolicy *, char *); static void ParsePass(SnortConfig *, SnortPolicy *, char *); static void ParseReject(SnortConfig *, SnortPolicy *, char *); static void ParseSdrop(SnortConfig *, SnortPolicy *, char *); #ifdef TARGET_BASED static void ParseAttributeTable(SnortConfig *, SnortPolicy *, char *); #endif /* TARGET_BASED */ static void ParseConfig(SnortConfig *, SnortPolicy *, char *); static void ParseDynamicDetectionInfo(SnortConfig *, SnortPolicy *, char *); static void ParseDynamicEngineInfo(SnortConfig *, SnortPolicy *, char *); static void ParseDynamicPreprocessorInfo(SnortConfig *, SnortPolicy *, char *); # ifdef SIDE_CHANNEL static void ParseDynamicSideChannelInfo(SnortConfig *, SnortPolicy *, char *); # endif /* SIDE_CHANNEL */ static void ParseDynamicOutputInfo(SnortConfig *, SnortPolicy *, char *); static void ParseEventFilter(SnortConfig *, SnortPolicy *, char *); static void ParseInclude(SnortConfig *, SnortPolicy *, char *); static void ParseIpVar(SnortConfig *, SnortPolicy *, char *); static void ParsePortVar(SnortConfig *, SnortPolicy *, char *); static void ParsePreprocessor(SnortConfig *, SnortPolicy *, char *); static void ParseRateFilter(SnortConfig *, SnortPolicy *, char *); static void ParseRuleState(SnortConfig *, SnortPolicy *, char *); static void ParseRuleTypeDeclaration(SnortConfig *, SnortPolicy *, char *); #ifdef SIDE_CHANNEL static void ParseSideChannelModule(SnortConfig *, SnortPolicy *, char *); static void ConfigSideChannel(SnortConfig *, char *); #endif /* SIDE_CHANNEL */ static void ParseSuppress(SnortConfig *, SnortPolicy *, char *); static void ParseThreshold(SnortConfig *, SnortPolicy *, char *); static void ParseVar(SnortConfig *, SnortPolicy *, char *); static void ParseFile(SnortConfig *, SnortPolicy *, char *); static void AddVarToTable(SnortConfig *, char *, char *); int ParseBool(char *arg); static const KeywordFunc snort_conf_keywords[] = { /* Rule keywords */ { SNORT_CONF_KEYWORD__ALERT, KEYWORD_TYPE__RULE, 0, 0, ParseAlert }, { SNORT_CONF_KEYWORD__DROP, KEYWORD_TYPE__RULE, 0, 0, ParseDrop }, { SNORT_CONF_KEYWORD__BLOCK, KEYWORD_TYPE__RULE, 0, 0, ParseDrop }, { SNORT_CONF_KEYWORD__LOG, KEYWORD_TYPE__RULE, 0, 0, ParseLog }, { SNORT_CONF_KEYWORD__PASS, KEYWORD_TYPE__RULE, 0, 0, ParsePass }, { SNORT_CONF_KEYWORD__REJECT, KEYWORD_TYPE__RULE, 0, 0, ParseReject }, { SNORT_CONF_KEYWORD__SDROP, KEYWORD_TYPE__RULE, 0, 0, ParseSdrop }, { SNORT_CONF_KEYWORD__SBLOCK, KEYWORD_TYPE__RULE, 0, 0, ParseSdrop }, /* Non-rule keywords */ #ifdef TARGET_BASED /* Need to fatal error if attribute_table is not configured in default * policy. Since we're just skipping configuring non-default * configurations with default only configuration types, set this to * be configured for non-default policies and fatal in function */ { SNORT_CONF_KEYWORD__ATTRIBUTE_TABLE, KEYWORD_TYPE__MAIN, 1, 0, ParseAttributeTable }, #endif { SNORT_CONF_KEYWORD__CONFIG, KEYWORD_TYPE__MAIN, 1, 0, ParseConfig }, { SNORT_CONF_KEYWORD__DYNAMIC_OUTPUT , KEYWORD_TYPE__MAIN, 1, 1, ParseDynamicOutputInfo }, { SNORT_CONF_KEYWORD__DYNAMIC_DETECTION, KEYWORD_TYPE__MAIN, 1, 1, ParseDynamicDetectionInfo }, { SNORT_CONF_KEYWORD__DYNAMIC_ENGINE, KEYWORD_TYPE__MAIN, 1, 1, ParseDynamicEngineInfo }, { SNORT_CONF_KEYWORD__DYNAMIC_PREPROC, KEYWORD_TYPE__MAIN, 1, 1, ParseDynamicPreprocessorInfo }, #ifdef SIDE_CHANNEL { SNORT_CONF_KEYWORD__DYNAMIC_SIDE_CHAN, KEYWORD_TYPE__MAIN, 1, 1, ParseDynamicSideChannelInfo }, #endif /* SIDE_CHANNEL */ { SNORT_CONF_KEYWORD__EVENT_FILTER, KEYWORD_TYPE__MAIN, 1, 0, ParseEventFilter }, { SNORT_CONF_KEYWORD__INCLUDE, KEYWORD_TYPE__ALL, 1, 0, ParseInclude }, { SNORT_CONF_KEYWORD__IPVAR, KEYWORD_TYPE__MAIN, 0, 0, ParseIpVar }, { SNORT_CONF_KEYWORD__OUTPUT, KEYWORD_TYPE__MAIN, 1, 1, ParseOutput }, { SNORT_CONF_KEYWORD__PORTVAR, KEYWORD_TYPE__MAIN, 0, 0, ParsePortVar }, { SNORT_CONF_KEYWORD__PREPROCESSOR, KEYWORD_TYPE__MAIN, 1, 0, ParsePreprocessor }, { SNORT_CONF_KEYWORD__RATE_FILTER, KEYWORD_TYPE__MAIN, 0, 0, ParseRateFilter }, { SNORT_CONF_KEYWORD__RULE_STATE, KEYWORD_TYPE__MAIN, 1, 0, ParseRuleState }, { SNORT_CONF_KEYWORD__RULE_TYPE, KEYWORD_TYPE__ALL, 1, 0, ParseRuleTypeDeclaration }, #ifdef SIDE_CHANNEL { SNORT_CONF_KEYWORD__SIDE_CHANNEL, KEYWORD_TYPE__MAIN, 1, 1, ParseSideChannelModule }, #endif /* SIDE_CHANNEL */ { SNORT_CONF_KEYWORD__SUPPRESS, KEYWORD_TYPE__MAIN, 0, 0, ParseSuppress }, { SNORT_CONF_KEYWORD__THRESHOLD, KEYWORD_TYPE__MAIN, 1, 0, ParseThreshold }, { SNORT_CONF_KEYWORD__VAR, KEYWORD_TYPE__MAIN, 0, 0, ParseVar }, { SNORT_CONF_KEYWORD__FILE, KEYWORD_TYPE__MAIN, 0, 1, ParseFile }, { NULL, KEYWORD_TYPE__ALL, 0, 0, NULL } /* Marks end of array */ }; static void ParseOtnClassType(SnortConfig *, RuleTreeNode *, OptTreeNode *, RuleType, char *); static void ParseOtnDetectionFilter(SnortConfig *, RuleTreeNode *, OptTreeNode *, RuleType, char *); static void ParseOtnGid(SnortConfig *, RuleTreeNode *, OptTreeNode *, RuleType, char *); static void ParseOtnLogTo(SnortConfig *, RuleTreeNode *, OptTreeNode *, RuleType, char *); static void ParseOtnMessage(SnortConfig *, RuleTreeNode *, OptTreeNode *, RuleType, char *); static void ParseOtnMetadata(SnortConfig *, RuleTreeNode *, OptTreeNode *, RuleType, char *); static void ParseOtnPriority(SnortConfig *, RuleTreeNode *, OptTreeNode *, RuleType, char *); static void ParseOtnReference(SnortConfig *, RuleTreeNode *, OptTreeNode *, RuleType, char *); static void ParseOtnRevision(SnortConfig *, RuleTreeNode *, OptTreeNode *, RuleType, char *); static void ParseOtnSid(SnortConfig *, RuleTreeNode *, OptTreeNode *, RuleType, char *); static void ParseOtnTag(SnortConfig *, RuleTreeNode *, OptTreeNode *, RuleType, char *); static void ParseOtnThreshold(SnortConfig *, RuleTreeNode *, OptTreeNode *, RuleType, char *); static const RuleOptFunc rule_options[] = { { RULE_OPT__CLASSTYPE, 1, 1, 0, ParseOtnClassType }, { RULE_OPT__DETECTION_FILTER, 1, 1, 1, ParseOtnDetectionFilter }, { RULE_OPT__GID, 1, 1, 0, ParseOtnGid }, { RULE_OPT__LOGTO, 1, 1, 0, ParseOtnLogTo }, { RULE_OPT__METADATA, 1, 0, 0, ParseOtnMetadata }, { RULE_OPT__MSG, 1, 1, 0, ParseOtnMessage }, { RULE_OPT__PRIORITY, 1, 1, 0, ParseOtnPriority }, { RULE_OPT__REFERENCE, 1, 0, 0, ParseOtnReference }, { RULE_OPT__REVISION, 1, 1, 0, ParseOtnRevision }, { RULE_OPT__SID, 1, 1, 0, ParseOtnSid }, { RULE_OPT__TAG, 1, 1, 0, ParseOtnTag }, { RULE_OPT__THRESHOLD, 1, 1, 1, ParseOtnThreshold }, { NULL, 0, 0, 0, NULL } /* Marks end of array */ }; #ifdef PERF_PROFILING /* Internal prototypes used in lists below */ static void _ConfigProfilePreprocs(SnortConfig *, char *); static void _ConfigProfileRules(SnortConfig *, char *); #endif static const ConfigFunc config_opts[] = { { CONFIG_OPT__ALERT_FILE, 1, 1, 1, ConfigAlertFile }, { CONFIG_OPT__ALERT_WITH_IFACE_NAME, 0, 1, 1, ConfigAlertWithInterfaceName }, { CONFIG_OPT__AUTOGEN_PREPROC_DECODER_RULES, 0, 1, 0, ConfigAutogenPreprocDecoderRules }, { CONFIG_OPT__ASN1, 1, 1, 1, ConfigAsn1 }, { CONFIG_OPT__BINDING, 1, 0, 1, ConfigBinding }, { CONFIG_OPT__BPF_FILE, 1, 1, 1, ConfigBpfFile }, { CONFIG_OPT__CHECKSUM_DROP, 0, 0, 0, ConfigChecksumDrop }, { CONFIG_OPT__CHECKSUM_MODE, 0, 0, 0, ConfigChecksumMode }, { CONFIG_OPT__CHROOT_DIR, 1, 1, 1, ConfigChrootDir }, { CONFIG_OPT__CLASSIFICATION, 1, 0, 0, ConfigClassification }, { CONFIG_OPT__DAEMON, 0, 1, 1, ConfigDaemon }, { CONFIG_OPT__DECODE_DATA_LINK, 0, 1, 1, ConfigDecodeDataLink }, { CONFIG_OPT__DECODE_ESP, 0, 1, 1, ConfigEnableEspDecoding }, { CONFIG_OPT__DEFAULT_RULE_STATE, 0, 1, 1, ConfigDefaultRuleState }, { CONFIG_OPT__DETECTION, 1, 0, 1, ConfigDetection }, /* This is reconfigurable */ { CONFIG_OPT__DETECTION_FILTER, 1, 1, 1, ConfigDetectionFilter }, { CONFIG_OPT__DISABLE_DECODE_ALERTS, 0, 1, 0, ConfigDisableDecodeAlerts }, { CONFIG_OPT__DISABLE_DECODE_DROPS, 0, 1, 0, ConfigDisableDecodeDrops }, #ifdef INLINE_FAILOPEN { CONFIG_OPT__DISABLE_INLINE_FAILOPEN, 0, 1, 1, ConfigDisableInlineFailopen }, #endif { CONFIG_OPT__DISABLE_IP_OPT_ALERTS, 0, 1, 0, ConfigDisableIpOptAlerts }, { CONFIG_OPT__DISABLE_IP_OPT_DROPS, 0, 1, 0, ConfigDisableIpOptDrops }, { CONFIG_OPT__DISABLE_TCP_OPT_ALERTS, 0, 1, 0, ConfigDisableTcpOptAlerts }, { CONFIG_OPT__DISABLE_TCP_OPT_DROPS, 0, 1, 0, ConfigDisableTcpOptDrops }, { CONFIG_OPT__DISABLE_TCP_OPT_EXP_ALERTS, 0, 1, 0, ConfigDisableTcpOptExperimentalAlerts }, { CONFIG_OPT__DISABLE_TCP_OPT_EXP_DROPS, 0, 1, 0, ConfigDisableTcpOptExperimentalDrops }, { CONFIG_OPT__DISABLE_TCP_OPT_OBS_ALERTS, 0, 1, 0, ConfigDisableTcpOptObsoleteAlerts }, { CONFIG_OPT__DISABLE_TCP_OPT_OBS_DROPS, 0, 1, 0, ConfigDisableTcpOptObsoleteDrops }, { CONFIG_OPT__DISABLE_TTCP_ALERTS, 0, 1, 0, ConfigDisableTTcpAlerts }, { CONFIG_OPT__DISABLE_TCP_OPT_TTCP_ALERTS, 0, 1, 0, ConfigDisableTTcpAlerts }, { CONFIG_OPT__DISABLE_TTCP_DROPS, 0, 1, 0, ConfigDisableTTcpDrops }, { CONFIG_OPT__DUMP_CHARS_ONLY, 0, 1, 1, ConfigDumpCharsOnly }, { CONFIG_OPT__DUMP_PAYLOAD, 0, 1, 1, ConfigDumpPayload }, { CONFIG_OPT__DUMP_PAYLOAD_VERBOSE, 0, 1, 1, ConfigDumpPayloadVerbose }, { CONFIG_OPT__ENABLE_DECODE_DROPS, 0, 1, 0, ConfigEnableDecodeDrops }, { CONFIG_OPT__ENABLE_DECODE_OVERSIZED_ALERTS, 0, 1, 0, ConfigEnableDecodeOversizedAlerts }, { CONFIG_OPT__ENABLE_DECODE_OVERSIZED_DROPS, 0, 1, 0, ConfigEnableDecodeOversizedDrops }, { CONFIG_OPT__ENABLE_DEEP_TEREDO_INSPECTION, 0, 1, 1, ConfigEnableDeepTeredoInspection }, { CONFIG_OPT__ENABLE_GTP_DECODING, 0, 1, 1, ConfigEnableGTPDecoding }, { CONFIG_OPT__ENABLE_IP_OPT_DROPS, 0, 1, 1, ConfigEnableIpOptDrops }, #ifdef MPLS { CONFIG_OPT__ENABLE_MPLS_MULTICAST, 0, 1, 1, ConfigEnableMplsMulticast }, { CONFIG_OPT__ENABLE_MPLS_OVERLAPPING_IP, 0, 1, 1, ConfigEnableMplsOverlappingIp }, #endif { CONFIG_OPT__ENABLE_TCP_OPT_DROPS, 0, 1, 0, ConfigEnableTcpOptDrops }, { CONFIG_OPT__ENABLE_TCP_OPT_EXP_DROPS, 0, 1, 0, ConfigEnableTcpOptExperimentalDrops }, { CONFIG_OPT__ENABLE_TCP_OPT_OBS_DROPS, 0, 1, 0, ConfigEnableTcpOptObsoleteDrops }, { CONFIG_OPT__ENABLE_TTCP_DROPS, 0, 1, 0, ConfigEnableTTcpDrops }, { CONFIG_OPT__ENABLE_TCP_OPT_TTCP_DROPS, 0, 1, 0, ConfigEnableTTcpDrops }, { CONFIG_OPT__EVENT_FILTER, 1, 1, 1, ConfigEventFilter }, { CONFIG_OPT__EVENT_QUEUE, 1, 1, 1, ConfigEventQueue }, { CONFIG_OPT__EVENT_TRACE, 0, 1, 1, ConfigEventTrace }, { CONFIG_OPT__REACT, 1, 1, 1, ConfigReact }, #ifdef ENABLE_RESPONSE3 { CONFIG_OPT__FLEXRESP2_INTERFACE, 1, 1, 1, ConfigFlexresp2Interface }, { CONFIG_OPT__FLEXRESP2_ATTEMPTS, 1, 1, 1, ConfigFlexresp2Attempts }, { CONFIG_OPT__FLEXRESP2_MEMCAP, 1, 1, 1, ConfigFlexresp2Memcap }, { CONFIG_OPT__FLEXRESP2_ROWS, 1, 1, 1, ConfigFlexresp2Rows }, #endif #ifdef ACTIVE_RESPONSE { CONFIG_OPT__RESPONSE, 1, 1, 1, ConfigResponse }, #endif { CONFIG_OPT__FLOWBITS_SIZE, 1, 1, 1, ConfigFlowbitsSize }, { CONFIG_OPT__IGNORE_PORTS, 1, 0, 1, ConfigIgnorePorts }, { CONFIG_OPT__ALERT_VLAN, 0, 1, 1, ConfigIncludeVlanInAlert }, { CONFIG_OPT__INTERFACE, 1, 1, 1, ConfigInterface }, { CONFIG_OPT__IPV6_FRAG, 1, 1, 1, ConfigIpv6Frag }, { CONFIG_OPT__LAYER2RESETS, 1, 1, 1, ConfigLayer2Resets }, { CONFIG_OPT__LOG_DIR, 1, 1, 1, ConfigLogDir }, { CONFIG_OPT__DAQ_TYPE, 1, 1, 1, ConfigDaqType }, { CONFIG_OPT__DAQ_MODE, 1, 1, 1, ConfigDaqMode }, { CONFIG_OPT__DAQ_VAR, 1, 0, 1, ConfigDaqVar }, { CONFIG_OPT__DAQ_DIR, 1, 0, 1, ConfigDaqDir }, { CONFIG_OPT__DIRTY_PIG, 0, 1, 1, ConfigDirtyPig }, #ifdef TARGET_BASED { CONFIG_OPT__MAX_ATTRIBUTE_HOSTS, 1, 1, 1, ConfigMaxAttributeHosts }, { CONFIG_OPT__MAX_ATTRIBUTE_SERVICES_PER_HOST, 1, 1, 1, ConfigMaxAttributeServicesPerHost }, { CONFIG_OPT__MAX_METADATA_SERVICES, 1, 1, 1, ConfigMaxMetadataServices }, { CONFIG_OPT__DISABLE_ATTRIBUTE_RELOAD, 0, 1, 1, ConfigDisableAttributeReload }, #endif #ifdef MPLS { CONFIG_OPT__MAX_MPLS_LABELCHAIN_LEN, 0, 1, 1, ConfigMaxMplsLabelChain }, { CONFIG_OPT__MPLS_PAYLOAD_TYPE, 0, 1, 1, ConfigMplsPayloadType }, #endif { CONFIG_OPT__MIN_TTL, 1, 1, 0, ConfigMinTTL }, #ifdef NORMALIZER { CONFIG_OPT__NEW_TTL, 1, 1, 0, ConfigNewTTL }, #endif { CONFIG_OPT__NO_LOG, 0, 1, 1, ConfigNoLog }, { CONFIG_OPT__NO_PCRE, 0, 1, 1, ConfigNoPcre }, { CONFIG_OPT__NO_PROMISCUOUS, 0, 1, 1, ConfigNoPromiscuous }, { CONFIG_OPT__OBFUSCATE, 0, 1, 1, ConfigObfuscate }, { CONFIG_OPT__ORDER, 1, 1, 1, ConfigRuleListOrder }, { CONFIG_OPT__PAF_MAX, 1, 1, 0, ConfigPafMax }, { CONFIG_OPT__PKT_COUNT, 1, 1, 1, ConfigPacketCount }, { CONFIG_OPT__PKT_SNAPLEN, 1, 1, 1, ConfigPacketSnaplen }, { CONFIG_OPT__PCRE_MATCH_LIMIT, 1, 1, 1, ConfigPcreMatchLimit }, { CONFIG_OPT__PCRE_MATCH_LIMIT_RECURSION, 1, 1, 1, ConfigPcreMatchLimitRecursion }, /* XXX We can configure this on the command line - why not in config file ??? */ #ifdef NOT_UNTIL_WE_DAEMONIZE_AFTER_READING_CONFFILE { CONFIG_OPT__PID_PATH, 1, 1, 1, ConfigPidPath }, #endif { CONFIG_OPT__POLICY, 1, 1, 0, ConfigPolicy }, { CONFIG_OPT__IPS_POLICY_MODE, 1, 1, 0, ConfigIpsPolicyMode }, { CONFIG_OPT__NAP_POLICY_MODE, 1, 1, 0, ConfigNapPolicyMode }, { CONFIG_OPT__POLICY_VERSION , 1, 0, 0, ConfigPolicyVersion }, { CONFIG_OPT__PROTECTED_CONTENT , 1, 0, 0, ConfigProtectedContent }, #ifdef PPM_MGR { CONFIG_OPT__PPM, 1, 0, 1, ConfigPPM }, #endif #ifdef PERF_PROFILING { CONFIG_OPT__PROFILE_PREPROCS, 0, 1, 1, _ConfigProfilePreprocs }, { CONFIG_OPT__PROFILE_RULES, 0, 1, 1, _ConfigProfileRules }, #endif { CONFIG_OPT__QUIET, 0, 1, 1, ConfigQuiet }, { CONFIG_OPT__RATE_FILTER, 1, 1, 1, ConfigRateFilter }, { CONFIG_OPT__REFERENCE, 1, 0, 1, ConfigReference }, { CONFIG_OPT__REFERENCE_NET, 1, 1, 1, ConfigReferenceNet }, { CONFIG_OPT__SET_GID, 1, 1, 1, ConfigSetGid }, { CONFIG_OPT__SET_UID, 1, 1, 1, ConfigSetUid }, { CONFIG_OPT__SHOW_YEAR, 0, 1, 1, ConfigShowYear }, { CONFIG_OPT__SO_RULE_MEMCAP, 1, 1, 1, ConfigSoRuleMemcap }, { CONFIG_OPT__STATEFUL, 0, 1, 1, ConfigStateful }, { CONFIG_OPT__TAGGED_PACKET_LIMIT, 1, 1, 1, ConfigTaggedPacketLimit }, { CONFIG_OPT__THRESHOLD, 1, 1, 1, ConfigThreshold }, { CONFIG_OPT__UMASK, 1, 1, 1, ConfigUmask }, { CONFIG_OPT__UTC, 0, 1, 1, ConfigUtc }, { CONFIG_OPT__VERBOSE, 0, 1, 1, ConfigVerbose }, { CONFIG_OPT__VLAN_AGNOSTIC, 0, 1, 1, ConfigVlanAgnostic }, { CONFIG_OPT__ADDRESSSPACE_AGNOSTIC, 0, 1, 1, ConfigAddressSpaceAgnostic }, { CONFIG_OPT__LOG_IPV6_EXTRA, 0, 1, 1, ConfigLogIPv6Extra }, { CONFIG_OPT__DUMP_DYNAMIC_RULES_PATH, 1, 1, 1, ConfigDumpDynamicRulesPath }, { CONFIG_OPT__CONTROL_SOCKET_DIR, 1, 1, 1, ConfigControlSocketDirectory }, { CONFIG_OPT__FILE, 1, 1, 1, ConfigFile }, { CONFIG_OPT__TUNNEL_BYPASS, 1, 1, 1, ConfigTunnelVerdicts }, #ifdef SIDE_CHANNEL { CONFIG_OPT__SIDE_CHANNEL, 0, 1, 1, ConfigSideChannel }, #endif { CONFIG_OPT__MAX_IP6_EXTENSIONS, 1, 1, 1, ConfigMaxIP6Extensions }, { CONFIG_OPT__DISABLE_REPLACE, 0, 1, 0, ConfigDisableReplace }, #ifdef DUMP_BUFFER { CONFIG_OPT__BUFFER_DUMP, 1, 1, 1, ConfigBufferDump }, { CONFIG_OPT__BUFFER_DUMP_ALERT, 1, 1, 1, ConfigBufferDump }, #endif { NULL, 0, 0, 0, NULL } /* Marks end of array */ }; /* Used to determine if a config option has already been configured * Gets zeroed when initially parsing a configuration file, then each * index gets set to 1 as an option is configured. Maps to config_opts */ static uint8_t config_opt_configured[sizeof(config_opts) / sizeof(ConfigFunc)]; /* Private function prototypes ************************************************/ static void InitVarTables(SnortPolicy *); static void InitPolicyMode(SnortPolicy *); static void InitParser(void); static int VarIsIpAddr(vartable_t *, char *); static RuleType GetRuleType(char *); static void CreateDefaultRules(SnortConfig *); static void ParseConfigFile(SnortConfig *, SnortPolicy *, char *); static int ValidateUserDefinedRuleType(SnortConfig *, char *); static void IntegrityCheckRules(SnortConfig *); static void ParseDynamicLibInfo(DynamicLibInfo *, char *); static int GetRuleProtocol(char *); static RuleTreeNode * ProcessHeadNode(SnortConfig *, RuleTreeNode *, ListHead *); static int ContinuationCheck(char *); static ListHead * CreateRuleType(SnortConfig *, char *, RuleType, int, ListHead *); static int GetChecksumFlags(char *); static int GetPolicyMode(char *,int ); static void OtnInit(SnortConfig *); static void _ParseRuleTypeDeclaration(SnortConfig *, FILE *, char *, int); static void printRuleListOrder(RuleListNode *); static RuleListNode * addNodeToOrderedList(RuleListNode *, RuleListNode *, int); static VarEntry * VarDefine(SnortConfig *, char *, char *); static char * VarSearch(SnortConfig *, char *); static char * ExpandVars(SnortConfig *, char *); static VarEntry * VarAlloc(void); static int ParsePort(SnortConfig *, char *, uint16_t *, uint16_t *, char *, int *); static uint16_t ConvPort(char *, char *); static char * ReadLine(FILE *); static void DeleteVars(VarEntry *); static int ValidateIPList(IpAddrSet *, char *); static int PortVarDefine(SnortConfig *, char *, char *); static void port_entry_free(port_entry_t *); static int port_list_add_entry(port_list_t *, port_entry_t *); #if 0 static port_entry_t * port_list_get(port_list_t *, int); static void port_list_print(port_list_t *); #endif static void port_list_free(port_list_t *); static void finish_portlist_table(FastPatternConfig *, char *, PortTable *); static void PortTablesFinish(rule_port_tables_t *, FastPatternConfig *); static rule_port_tables_t * PortTablesNew(void); static int FinishPortListRule(rule_port_tables_t *, RuleTreeNode *, OptTreeNode *, int, port_entry_t *, FastPatternConfig *); static PortObject * ParsePortListTcpUdpPort(PortVarTable *, PortTable *, char *); static int ParsePortList(RuleTreeNode *, PortVarTable *, PortTable *, char *, int, int); static void ParseRule(SnortConfig *, SnortPolicy *, char *, RuleType, ListHead *); static void TransferOutputConfigs(OutputConfig *, OutputConfig **); static OutputConfig * DupOutputConfig(OutputConfig *); static void RemoveOutputConfigs(OutputConfig **, int); static void XferHeader(RuleTreeNode *, RuleTreeNode *); static OptTreeNode * ParseRuleOptions(SnortConfig *, RuleTreeNode *, char *, RuleType, int); #ifndef SOURCEFIRE static void DefineAllIfaceVars(SnortConfig *); static void DefineIfaceVar(SnortConfig *, char *, uint8_t *, uint8_t *); #endif #ifdef DEBUG_MSGS #if 0 static void DumpList(IpAddrNode *, int); #endif static void DumpChain(char *, int, int); static void DumpRuleChains(RuleListNode *); #endif static int ProcessIP(SnortConfig *, char *, RuleTreeNode *, int, int); static int TestHeader(RuleTreeNode *, RuleTreeNode *); static void FreeRuleTreeNode(RuleTreeNode *rtn); static void DestroyRuleTreeNode(RuleTreeNode *rtn); static void AddrToFunc(RuleTreeNode *, int); static void PortToFunc(RuleTreeNode *, int, int, int); static void SetupRTNFuncList(RuleTreeNode *); static void DisallowCrossTableDuplicateVars(SnortConfig *, char *, VarType); static int mergeDuplicateOtn(SnortConfig *, OptTreeNode *, OptTreeNode *, RuleTreeNode *); #if 0 #ifdef DEBUG_MSGS static void PrintRtnPorts(RuleTreeNode *); #endif #endif static void FreeRuleTreeNodes(SnortConfig *); static void FreeOutputLists(ListHead *list); static int ParseNetworkBindingLine(tSfPolicyConfig *, int, char **, char *); static int ParseVlanBindingLine(tSfPolicyConfig *, int, char **, char *); static int ParsePolicyIdBindingLine(tSfPolicyConfig *, int, char **, char *); static RuleTreeNode * findHeadNode(SnortConfig *, RuleTreeNode *, tSfPolicyId); // only keep drop rules // if we are inline (and can actually drop), // or we are going to just alert instead of drop, // or we are going to ignore session data instead of drop. // the alert case is tested for separately with ScTreatDropAsAlert(). static inline int ScKeepDropRules (SnortConfig * sc) { return ( ScIpsInlineModeNewConf(sc) || ScAdapterInlineModeNewConf(sc) || ScTreatDropAsIgnoreNewConf(sc) ); } static inline int ScLoadAsDropRules (SnortConfig * sc) { return ( ScIpsInlineTestModeNewConf(sc) || ScAdapterInlineTestModeNewConf(sc) ); } /**************************************************************************** * Function: ParseSnortConf() * * Read the rules file a line at a time and send each rule to the rule parser * This is the first pass of the configuration file. It parses everything * except the rules. * * Arguments: None * * Returns: * SnortConfig * * An initialized and configured snort configuration struct. * This struct should be passed on the second pass of the * configuration file to parse the rules. * ***************************************************************************/ SnortConfig * ParseSnortConf(void) { SnortConfig *sc = SnortConfNew(); VarNode *tmp = cmd_line_var_list; tSfPolicyId policy_id; file_line = 0; file_name = snort_conf_file ? snort_conf_file : NULL_CONF; InitParser(); /* Setup the default rule action anchor points * Need to do this now in case we get a user defined rule type */ CreateDefaultRules(sc); sc->port_tables = PortTablesNew(); mpseInitSummary(); OtnInit(sc); /* Used to store "config" configurations */ sc->config_table = sfghash_new(20, 0, 0, free); if (sc->config_table == NULL) { ParseError("%s(%d) No memory to create config table.\n", __FILE__, __LINE__); } sc->fast_pattern_config = FastPatternConfigNew(); sc->event_queue_config = EventQueueConfigNew(); sc->threshold_config = ThresholdConfigNew(); sc->rate_filter_config = RateFilter_ConfigNew(); sc->detection_filter_config = DetectionFilterConfigNew(); sc->ip_proto_only_lists = (SF_LIST **)SnortAlloc(NUM_IP_PROTOS * sizeof(SF_LIST *)); /* We're not going to parse rules on the first pass */ parse_rules = 0; sc->policy_config = sfPolicyInit(); if (sc->policy_config == NULL) { ParseError("No memory to create policy configuration.\n"); } /* Add the default policy */ policy_id = sfPolicyAdd(sc->policy_config, file_name); sfSetDefaultPolicy(sc->policy_config, policy_id); sfDynArrayCheckBounds((void **)&sc->targeted_policies, policy_id, &sc->num_policies_allocated); sc->targeted_policies[policy_id] = SnortPolicyNew(); InitVarTables(sc->targeted_policies[policy_id]); InitPolicyMode(sc->targeted_policies[policy_id]); setParserPolicy(sc, policy_id); #ifndef SOURCEFIRE /* If snort is not run with root privileges, no interfaces will be defined, * so user beware if an iface_ADDRESS variable is used in snort.conf and * snort is not run as root (even if just in read mode) */ DefineAllIfaceVars(sc); #endif /* Add command line defined variables - duplicates will already * have been resolved */ while (tmp != NULL) { AddVarToTable(sc, tmp->name, tmp->value); tmp = tmp->next; } /* Initialize storage space for preprocessor defined rule options */ sc->preproc_rule_options = PreprocessorRuleOptionsNew(); if (sc->preproc_rule_options == NULL) { ParseError("Could not allocate storage for preprocessor rule options.\n"); } if ( strcmp(file_name, NULL_CONF) ) ParseConfigFile(sc, sc->targeted_policies[policy_id], file_name); /* We've picked up any targeted policy configs at this point so * it's probably okay to parse them here */ for (policy_id = 0; policy_id < sfPolicyNumAllocated(sc->policy_config); policy_id++) { char *fname = sfPolicyGet(sc->policy_config, policy_id); /* Already configured default policy */ if (policy_id == sfGetDefaultPolicy(sc->policy_config)) continue; if (fname != NULL) { sfDynArrayCheckBounds( (void **)&sc->targeted_policies, policy_id, &sc->num_policies_allocated); sc->targeted_policies[policy_id] = SnortPolicyNew(); InitVarTables(sc->targeted_policies[policy_id]); InitPolicyMode(sc->targeted_policies[policy_id]); setParserPolicy(sc, policy_id); /* Need to reset this for each targeted policy */ memset(config_opt_configured, 0, sizeof(config_opt_configured)); /* Add command line defined variables - duplicates will already * have been resolved */ tmp = cmd_line_var_list; while (tmp != NULL) { AddVarToTable(sc, tmp->name, tmp->value); tmp = tmp->next; } /* Parse as include file so if the file is specified relative to * the snort conf directory we'll pick it up */ ParseInclude(sc, sc->targeted_policies[policy_id], fname); } } /* This can be initialized now since we've picked up any user * defined rules */ sc->omd = OtnXMatchDataNew(sc->num_rule_types); /* Reset these. The only issue in not reseting would be if we were * parsing a command line again, but do it anyway */ file_name = NULL; file_line = 0; return sc; } static int ParsePolicyIdBindingLine( tSfPolicyConfig *config, int num_toks, char **toks, char *fileName ) { int i; int parsedPolicyId; for (i = 0; i < num_toks; i++) { char *endp; if ( toks[i] ) { errno = 0; parsedPolicyId = SnortStrtolRange(toks[i], &endp, 10, 0, USHRT_MAX); if ((errno == ERANGE) || (*endp != '\0')) return -1; if ( sfPolicyIdAddBinding(config, parsedPolicyId, fileName) != 0) { return -1; //FatalError("Unable to add policy: policyId %d, file %s\n", parsedPolicyId, fileName); } } else { return -1; //FatalError("formating error in binding file: %s\n", aLine); } } return 0; } static int ParseVlanBindingLine( tSfPolicyConfig *config, int num_toks, char **toks, char *fileName ) { int i; int vlanId1=0, vlanId2=0; for (i = 0; i < num_toks; i++) { int num_tok2; char **toks2; int vlanId; unsigned pos; char *findStr1, *findStr2; char *endp; findStr1 = strchr(toks[i], '-'); if ( findStr1 ) { pos = findStr1 - toks[i]; if ( pos == 0 || pos == (strlen(toks[i]) - 1) ) { return -1; } findStr2 = strchr(findStr1+1, '-'); if ( findStr2 ) { return -1; } toks2 = mSplit(toks[i], "-", 2, &num_tok2, 0); if (num_tok2 == 2) { /* vlanId1 must be < SF_VLAN_BINDING_MAX -1 to allow for an actual range */ vlanId1 = SnortStrtolRange(toks2[0], &endp, 10, 0, SF_VLAN_BINDING_MAX-1); if( *endp ) { mSplitFree(&toks2, num_tok2); return -1; } /* vlanId2 must be > vlanId1 */ vlanId2 = SnortStrtolRange(toks2[1], &endp, 10, vlanId1+1, SF_VLAN_BINDING_MAX); if ( *endp ) { mSplitFree(&toks2, num_tok2); return -1; } if ( (vlanId1 < 0) || (vlanId2 >= SF_VLAN_BINDING_MAX) || (vlanId1 > vlanId2) ) { mSplitFree(&toks2, num_tok2); return -1; //FatalError("Invalid range: %d:%d\n", vlanId1, vlanId2); } for (vlanId = vlanId1; vlanId <= vlanId2; vlanId++) { if ( sfVlanAddBinding(config, vlanId, fileName) != 0) { mSplitFree(&toks2, num_tok2); return -1; //FatalError("Unable to add policy: vlan %d, file %s\n", vlanId, fileName); } } } else { mSplitFree(&toks2, num_tok2); return -1; } mSplitFree(&toks2, num_tok2); } else if ( toks[i] ) { vlanId = SnortStrtolRange(toks[i], &endp, 10, 0, SF_VLAN_BINDING_MAX-1); if( *endp ) return -1; if ( (vlanId >= SF_VLAN_BINDING_MAX) || sfVlanAddBinding(config, vlanId, fileName) != 0) { return -1; //FatalError("Unable to add policy: vlan %d, file %s\n", vlanId, fileName); } } else { return -1; //FatalError("formating error in binding file: %s\n", aLine); } } return 0; } static int ParseNetworkBindingLine( tSfPolicyConfig *config, int num_toks, char **toks, char *fileName ) { int i; for (i = 0; i < num_toks; i++) { SFIP_RET status; sfcidr_t *sfip; if( (sfip = sfip_alloc(toks[i], &status)) == NULL ) { return -1; } if (sfNetworkAddBinding(config, sfip, fileName) != 0) { sfip_free(sfip); return -1; // FatalError("Unable to add policy: vlan %d, file %s\n", vlanId, fileName); } sfip_free(sfip); } return 0; } #ifdef DEBUG_MSGS static void DumpRuleChains(RuleListNode *rule_lists) { RuleListNode *rule = rule_lists; if (rule_lists == NULL) return; while (rule != NULL) { DumpChain(rule->name, rule->mode, ETHERNET_TYPE_IP); DumpChain(rule->name, rule->mode, IPPROTO_TCP); DumpChain(rule->name, rule->mode, IPPROTO_UDP); DumpChain(rule->name, rule->mode, IPPROTO_ICMP); rule = rule->next; } } /**************************************************************************** * * Function: DumpChain(RuleTreeNode *, char *, char *) * * Purpose: Iterate over RTNs calling DumpList on each * * Arguments: rtn_idx => the RTN index pointer * rulename => the name of the rule the list belongs to * listname => the name of the list being printed out * * Returns: void function * ***************************************************************************/ static void DumpChain(char *name, int mode, int proto) { // XXX Not yet implemented - Rule chain dumping } /**************************************************************************** * * Function: DumpList(IpAddrNode*) * * Purpose: print out the chain lists by header block node group * * Arguments: node => the head node * * Returns: void function * ***************************************************************************/ #if 0 // avoid warning: ‘DumpList’ defined but not used static void DumpList(IpAddrNode *idx, int negated) { DEBUG_WRAP(int i=0;); if(!idx) return; while(idx != NULL) { DEBUG_WRAP(DebugMessage(DEBUG_RULES, "[%d] %s", i++, sfip_ntoa(idx->ip));); if(negated) { DEBUG_WRAP(DebugMessage(DEBUG_RULES, " (EXCEPTION_FLAG Active)\n");); } else { DEBUG_WRAP(DebugMessage(DEBUG_RULES, "\n");); } idx = idx->next; } } #endif /* 0 */ #endif /* DEBUG */ /* * Finish adding the rule to the port tables * * 1) find the table this rule should belong to (src/dst/any-any tcp,udp,icmp,ip or nocontent) * 2) find an index for the sid:gid pair * 3) add all no content rules to a single no content port object, the ports are irrelevant so * make it a any-any port object. * 4) if it's an any-any rule with content, add to an any-any port object * 5) find if we have a port object with these ports defined, if so get it, otherwise create it. * a)do this for src and dst port * b)add the rule index/id to the portobject(s) * c)if the rule is bidir add the rule and port-object to both src and dst tables * */ static int FinishPortListRule(rule_port_tables_t *port_tables, RuleTreeNode *rtn, OptTreeNode *otn, int proto, port_entry_t *pe, FastPatternConfig *fp) { int large_port_group = 0; int src_cnt = 0; int dst_cnt = 0; int rim_index; PortTable *dstTable; PortTable *srcTable; #ifdef TARGET_BASED PortTable *dstTable_noservice; PortTable *srcTable_noservice; #endif PortObject *aaObject; rule_count_t *prc; #ifdef TARGET_BASED ServiceOverride service_override = otn->sigInfo.service_override; int num_services = otn->sigInfo.num_services; if ( !IsAdaptiveConfigured() ) otn->sigInfo.service_override = ServiceOverride_ElsePorts; else if ( service_override == ServiceOverride_Nil && num_services ) otn->sigInfo.service_override = ServiceOverride_ElsePorts; else if ( service_override == ServiceOverride_Nil && !num_services ) otn->sigInfo.service_override = ServiceOverride_OrPorts; #endif /* Select the Target PortTable for this rule, based on protocol, src/dst * dir, and if there is rule content */ if (proto == IPPROTO_TCP) { dstTable = port_tables->tcp_dst; srcTable = port_tables->tcp_src; aaObject = port_tables->tcp_anyany; prc = &tcpCnt; #ifdef TARGET_BASED dstTable_noservice = port_tables->ns_tcp_dst; srcTable_noservice = port_tables->ns_tcp_src; #endif } else if (proto == IPPROTO_UDP) { dstTable = port_tables->udp_dst; srcTable = port_tables->udp_src; aaObject = port_tables->udp_anyany; prc = &udpCnt; #ifdef TARGET_BASED dstTable_noservice = port_tables->ns_udp_dst; srcTable_noservice = port_tables->ns_udp_src; #endif } else if (proto == IPPROTO_ICMP) { dstTable = port_tables->icmp_dst; srcTable = port_tables->icmp_src; aaObject = port_tables->icmp_anyany; prc = &icmpCnt; #ifdef TARGET_BASED dstTable_noservice = port_tables->ns_icmp_dst; srcTable_noservice = port_tables->ns_icmp_src; #endif } else if (proto == ETHERNET_TYPE_IP) { dstTable = port_tables->ip_dst; srcTable = port_tables->ip_src; aaObject = port_tables->ip_anyany; prc = &ipCnt; #ifdef TARGET_BASED dstTable_noservice = port_tables->ns_ip_dst; srcTable_noservice = port_tables->ns_ip_src; #endif } else { return -1; } /* Count rules with both src and dst specific ports */ if (!(rtn->flags & ANY_DST_PORT) && !(rtn->flags & ANY_SRC_PORT)) { DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS, "***\n***Info: src & dst ports are both specific" " >> gid=%u sid=%u src=%s dst=%s\n***\n", otn->sigInfo.generator, otn->sigInfo.id, pe->src_port, pe->dst_port);); prc->sd++; } /* Create/find an index to store this rules sid and gid at, * and use as reference in Port Objects */ rim_index = otn->ruleIndex; /* Add up the nocontent rules */ if (!pe->content && !pe->uricontent) prc->nc++; /* If not an any-any rule test for port bleedover, if we are using a * single rule group, don't bother */ if (!fpDetectGetSingleRuleGroup(fp) && (rtn->flags & (ANY_DST_PORT|ANY_SRC_PORT)) != (ANY_DST_PORT|ANY_SRC_PORT)) { if (!(rtn->flags & ANY_SRC_PORT)) { src_cnt = PortObjectPortCount(rtn->src_portobject); if (src_cnt >= fpDetectGetBleedOverPortLimit(fp)) large_port_group = 1; } if (!(rtn->flags & ANY_DST_PORT)) { dst_cnt = PortObjectPortCount(rtn->dst_portobject); if (dst_cnt >= fpDetectGetBleedOverPortLimit(fp)) large_port_group = 1; } if (large_port_group && fpDetectGetBleedOverWarnings(fp)) { LogMessage("***Bleedover Port Limit(%d) Exceeded for rule %u:%u " "(%d)ports: ", fpDetectGetBleedOverPortLimit(fp), otn->sigInfo.generator, otn->sigInfo.id, (src_cnt > dst_cnt) ? src_cnt : dst_cnt); /* If logging to syslog, this will be all multiline */ fflush(stdout); fflush(stderr); PortObjectPrintPortsRaw(rtn->src_portobject); LogMessage(" -> "); PortObjectPrintPortsRaw(rtn->dst_portobject); LogMessage(" adding to any-any group\n"); fflush(stdout);fflush(stderr); } } /* If an any-any rule add rule index to any-any port object * both content and no-content type rules go here if they are * any-any port rules... * If we have an any-any rule or a large port group or * were using a single rule group we make it an any-any rule. */ if (((rtn->flags & (ANY_DST_PORT|ANY_SRC_PORT)) == (ANY_DST_PORT|ANY_SRC_PORT)) || large_port_group || fpDetectGetSingleRuleGroup(fp)) { if (proto == ETHERNET_TYPE_IP) { /* Add the IP rules to the higher level app protocol groups, if they apply * to those protocols. All IP rules should have any-any port descriptors * and fall into this test. IP rules that are not tcp/udp/icmp go only into the * IP table */ DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS, "Finishing IP any-any rule %u:%u\n", otn->sigInfo.generator,otn->sigInfo.id);); switch (GetOtnIpProto(otn)) { case IPPROTO_TCP: PortObjectAddRule(port_tables->tcp_anyany, rim_index); tcpCnt.aa++; break; case IPPROTO_UDP: PortObjectAddRule(port_tables->udp_anyany, rim_index); udpCnt.aa++; break; case IPPROTO_ICMP: PortObjectAddRule(port_tables->icmp_anyany, rim_index); icmpCnt.aa++; break; case -1: /* Add to all ip proto anyany port tables */ PortObjectAddRule(port_tables->tcp_anyany, rim_index); tcpCnt.aa++; PortObjectAddRule(port_tables->udp_anyany, rim_index); udpCnt.aa++; PortObjectAddRule(port_tables->icmp_anyany, rim_index); icmpCnt.aa++; break; default: break; } /* Add to the IP ANY ANY */ PortObjectAddRule(aaObject, rim_index); prc->aa++; } else { /* For other protocols-tcp/udp/icmp add to the any any group */ PortObjectAddRule(aaObject, rim_index); prc->aa++; } return 0; /* done */ } /* add rule index to dst table if we have a specific dst port or port list */ if (!(rtn->flags & ANY_DST_PORT)) { PortObject *pox; prc->dst++; DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS, "Finishing rule: dst port rule\n");); /* find the proper port object */ pox = PortTableFindInputPortObjectPorts(dstTable, rtn->dst_portobject); if (pox == NULL) { /* Create a permanent port object */ pox = PortObjectDupPorts(rtn->dst_portobject); if (pox == NULL) { ParseError("Could not dup a port object - out of memory!\n"); } /* Add the port object to the table, and add the rule to the port object */ PortTableAddObject(dstTable, pox); } PortObjectAddRule(pox, rim_index); /* if bidir, add this rule and port group to the src table */ if (rtn->flags & BIDIRECTIONAL) { pox = PortTableFindInputPortObjectPorts(srcTable, rtn->dst_portobject); if (pox == NULL) { pox = PortObjectDupPorts(rtn->dst_portobject); if (pox == NULL) { ParseError("Could not dup a bidir-port object - out of memory!\n"); } PortTableAddObject(srcTable, pox); } PortObjectAddRule(pox, rim_index); } #ifdef TARGET_BASED // Add to the NOSERVICE group if (IsAdaptiveConfigured() && (otn->sigInfo.num_services == 0 || otn->sigInfo.service_override == ServiceOverride_OrPorts)) { if ( otn->sigInfo.service_override == ServiceOverride_AndPorts ) ParseError("Service override \"and-ports\" specified on a port only rule."); pox = PortTableFindInputPortObjectPorts(dstTable_noservice, rtn->dst_portobject); if (pox == NULL) { pox = PortObjectDupPorts(rtn->dst_portobject); if (pox == NULL) ParseError("Could not dup a port object - out of memory!"); PortTableAddObject(dstTable_noservice, pox); } PortObjectAddRule(pox, rim_index); } #endif // TARGET_BASED } /* add rule index to src table if we have a specific src port or port list */ if (!(rtn->flags & ANY_SRC_PORT)) { PortObject *pox; prc->src++; pox = PortTableFindInputPortObjectPorts(srcTable, rtn->src_portobject); if (pox == NULL) { pox = PortObjectDupPorts(rtn->src_portobject); if (pox == NULL) { ParseError("Could not dup a port object - out of memory!\n"); } PortTableAddObject(srcTable, pox); } PortObjectAddRule(pox, rim_index); /* if bidir, add this rule and port group to the dst table */ if (rtn->flags & BIDIRECTIONAL) { pox = PortTableFindInputPortObjectPorts(dstTable, rtn->src_portobject); if (pox == NULL) { pox = PortObjectDupPorts(rtn->src_portobject); if (pox == NULL) { ParseError("Could not dup a bidir-port object - out " "of memory!\n"); } PortTableAddObject(dstTable, pox); } PortObjectAddRule(pox, rim_index); } #ifdef TARGET_BASED // Add to the NOSERVICE group if (IsAdaptiveConfigured() && (otn->sigInfo.num_services == 0 || otn->sigInfo.service_override == ServiceOverride_OrPorts)) { if ( otn->sigInfo.service_override == ServiceOverride_AndPorts ) ParseError("Service override \"and-ports\" specified on a port only rule."); /* find the proper port object */ pox = PortTableFindInputPortObjectPorts(srcTable_noservice, rtn->src_portobject); if (pox == NULL) { pox = PortObjectDupPorts(rtn->src_portobject); if (pox == NULL) ParseError("Could not dup a port object - out of memory!\n"); PortTableAddObject(srcTable_noservice, pox); } PortObjectAddRule(pox, rim_index); } #endif // TARGET_BASED } return 0; } /* * Parse a port string as a port var, and create or find a port object for it, * and add it to the port var table. These are used by the rtn's * as src and dst port lists for final rtn/otn processing. * * These should not be confused with the port objects used to merge ports and rules * to build PORT_GROUP objects. Those are generated after the otn processing. * */ static PortObject * ParsePortListTcpUdpPort(PortVarTable *pvt, PortTable *noname, char *port_str) { PortObject * portobject; //PortObject * pox; char * errstr=0; POParser poparser; if ((pvt == NULL) || (noname == NULL) || (port_str == NULL)) return NULL; /* 1st - check if we have an any port */ if( strcasecmp(port_str,"any")== 0 ) { portobject = PortVarTableFind(pvt, "any"); if (portobject == NULL) ParseError("PortVarTable missing an 'any' variable."); return portobject; } /* 2nd - check if we have a PortVar */ else if( port_str[0]=='$' ) { /*||isalpha(port_str[0])*/ /*TODO: interferes with protocol names for ports*/ char * name = port_str + 1; DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"PortVarTableFind: finding '%s'\n", port_str);); /* look it up in the port var table */ portobject = PortVarTableFind(pvt, name); if (portobject == NULL) ParseError("***PortVar Lookup failed on '%s'.", port_str); DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"PortVarTableFind: '%s' found!\n", port_str);); } /* 3rd - and finally process a raw port list */ else { /* port list = [p,p,p:p,p,...] or p or p:p , no embedded spaces due to tokenizer */ PortObject * pox; DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS, "parser.c->PortObjectParseString: parsing '%s'\n",port_str);); portobject = PortObjectParseString(pvt, &poparser, 0, port_str, 0); DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS, "parser.c->PortObjectParseString: '%s' done.\n",port_str);); if( !portobject ) { errstr = PortObjectParseError( &poparser ); ParseError("***Rule--PortVar Parse error: (pos=%d,error=%s)\n>>%s\n>>%*s\n", poparser.pos,errstr,port_str,poparser.pos,"^"); } /* check if we already have this port object in the un-named port var table ... */ pox = PortTableFindInputPortObjectPorts(noname, portobject); if( pox ) { DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS, "parser.c: already have '%s' as a PortObject - " "calling PortObjectFree(portbject) line=%d\n",port_str,__LINE__ );); PortObjectFree( portobject ); portobject = pox; } else { DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS, "parser.c: adding '%s' as a PortObject line=%d\n",port_str,__LINE__ );); /* Add to the un-named port var table */ if (PortTableAddObject(noname, portobject)) { ParseError("Unable to add raw port object to unnamed " "port var table, out of memory!\n"); } } } return portobject; } #ifdef XXXXX /* * Extract the Icmp Type field to determine the PortGroup. */ PortObject * GetPortListIcmpPortObject( OptTreeNode * otn, PortTable * rulesPortTable, PortObject * anyAnyPortObject ) { PortObject * portobject=0; int type; IcmpTypeCheckData * IcmpType; IcmpType = (IcmpTypeCheckData *)otn->ds_list[PLUGIN_ICMP_TYPE]; if( IcmpType && (IcmpType->operator == ICMP_TYPE_TEST_EQ) ) { type = IcmpType->icmp_type; } else { return anyAnyPortObject; } /* TODO: optimize */ return anyAnyPortObject; } /* * Extract the IP Protocol field to determine the PortGroup. */ PortObject * GetPortListIPPortObject( OptTreeNode * otn,PortTable * rulesPortTable, PortObject * anyAnyPortObject ) { if (GetOtnIpProto(otn) == -1) return anyAnyPortObject; /* TODO: optimize */ return anyAnyPortObject; } #if 0 Not currently used /* * Extract the Icmp Type field to determine the PortGroup. */ static int GetOtnIcmpType(OptTreeNode * otn ) { int type; IcmpTypeCheckData * IcmpType; IcmpType = (IcmpTypeCheckData *)otn->ds_list[PLUGIN_ICMP_TYPE]; if( IcmpType && (IcmpType->operator == ICMP_TYPE_TEST_EQ) ) { type = IcmpType->icmp_type; } else { return -1; } return -1; } #endif #endif /* XXXX - PORTLISTS */ /* * Process the rule, add it to the appropriate PortObject * and add the PortObject to the rtn. * * TCP/UDP rules use ports/portlists, icmp uses the icmp type field and ip uses the protocol * field as a dst port for the purposes of looking up a rule group as packets are being * processed. * * TCP/UDP- use src/dst ports * ICMP - use icmp type as dst port,src=-1 * IP - use protocol as dst port,src=-1 * * rtn - proto_node * port_str - port list string or port var name * proto - protocol * dst_flag - dst or src port flag, true = dst, false = src * */ static int ParsePortList(RuleTreeNode *rtn, PortVarTable *pvt, PortTable *noname, char *port_str, int proto, int dst_flag) { PortObject *portobject = NULL; /* src or dst */ /* Get the protocol specific port object */ if( proto == IPPROTO_TCP || proto == IPPROTO_UDP ) { portobject = ParsePortListTcpUdpPort(pvt, noname, port_str); } else /* ICMP, IP - no real ports just Type and Protocol */ { portobject = PortVarTableFind(pvt, "any"); if (portobject == NULL) { ParseError("PortVarTable missing an 'any' variable\n"); } } DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"Rule-PortVar Parsed: %s \n",port_str);); /* !ports - port lists can be mixed 80:90,!82, * so the old NOT flag is depracated for port lists */ /* set up any any flags */ if( PortObjectHasAny(portobject) ) { if( dst_flag ) rtn->flags |= ANY_DST_PORT; else rtn->flags |= ANY_SRC_PORT; } /* check for a pure not rule - fatal if we find one */ if( PortObjectIsPureNot( portobject ) ) { ParseError("Pure NOT ports are not allowed!"); /* if( dst_flag ) rtn->flags |= EXCEPT_DST_PORT; else rtn->flags |= EXCEPT_SRC_PORT; */ } /* * set to the port object for this rules src/dst port, * these are used during rtn/otn port verification of the rule. */ if (dst_flag) rtn->dst_portobject = portobject; else rtn->src_portobject = portobject; return 0; } /**************************************************************************** * * Function: CheckForIPListConflicts * * Purpose: Checks For IP List Conflicts in a RuleTreeNode. Such as * negations that are overlapping and more general are not allowed. * * For example, the following is not allowed: * * [1.1.0.0/16,!1.0.0.0/8] * * The following is allowed though (not overlapping): * * [1.1.0.0/16,!2.0.0.0/8] * * Arguments: addrset -- IpAddrSet pointer. * * Returns: -1 if IP is empty, 1 if a conflict exists and 0 otherwise. * ***************************************************************************/ int CheckForIPListConflicts(IpAddrSet *addrset) { /* Conflict checking takes place inside the SFIP library */ return 0; } /**************************************************************************** * * Function: AddRuleFuncToList(int (*func)(), RuleTreeNode *) * * Purpose: Adds RuleTreeNode associated detection functions to the * current rule's function list * * Arguments: *func => function pointer to the detection function * rtn => pointer to the current rule * * Returns: void function * ***************************************************************************/ void AddRuleFuncToList(int (*rfunc) (Packet *, struct _RuleTreeNode *, struct _RuleFpList *, int), RuleTreeNode * rtn) { RuleFpList *idx; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Adding new rule to list\n");); idx = rtn->rule_func; if(idx == NULL) { rtn->rule_func = (RuleFpList *)SnortAlloc(sizeof(RuleFpList)); rtn->rule_func->RuleHeadFunc = rfunc; } else { while(idx->next != NULL) idx = idx->next; idx->next = (RuleFpList *)SnortAlloc(sizeof(RuleFpList)); idx = idx->next; idx->RuleHeadFunc = rfunc; } } /**************************************************************************** * * Function: SetupRTNFuncList(RuleTreeNode *) * * Purpose: Configures the function list for the rule header detection * functions (addrs and ports) * * Arguments: rtn => the pointer to the current rules list entry to attach to * * Returns: void function * ***************************************************************************/ static void SetupRTNFuncList(RuleTreeNode * rtn) { DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Initializing RTN function list!\n");); DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Functions: ");); if(rtn->flags & BIDIRECTIONAL) { DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"CheckBidirectional->\n");); AddRuleFuncToList(CheckBidirectional, rtn); } else { /* Attach the proper port checking function to the function list */ /* * the in-line "if's" check to see if the "any" or "not" flags have * been set so the PortToFunc call can determine which port testing * function to attach to the list */ PortToFunc(rtn, (rtn->flags & ANY_DST_PORT ? 1 : 0), (rtn->flags & EXCEPT_DST_PORT ? 1 : 0), DST); /* as above */ PortToFunc(rtn, (rtn->flags & ANY_SRC_PORT ? 1 : 0), (rtn->flags & EXCEPT_SRC_PORT ? 1 : 0), SRC); /* link in the proper IP address detection function */ AddrToFunc(rtn, SRC); /* last verse, same as the first (but for dest IP) ;) */ AddrToFunc(rtn, DST); } DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"RuleListEnd\n");); /* tack the end (success) function to the list */ AddRuleFuncToList(RuleListEnd, rtn); } /**************************************************************************** * * Function: AddrToFunc(RuleTreeNode *, u_long, u_long, int, int) * * Purpose: Links the proper IP address testing function to the current RTN * based on the address, netmask, and addr flags * * Arguments: rtn => the pointer to the current rules list entry to attach to * ip => IP address of the current rule * mask => netmask of the current rule * exception_flag => indicates that a "!" has been set for this * address * mode => indicates whether this is a rule for the source * or destination IP for the rule * * Returns: void function * ***************************************************************************/ static void AddrToFunc(RuleTreeNode * rtn, int mode) { /* * if IP and mask are both 0, this is a "any" IP and we don't need to * check it */ switch(mode) { case SRC: if((rtn->flags & ANY_SRC_IP) == 0) { DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"CheckSrcIP -> ");); AddRuleFuncToList(CheckSrcIP, rtn); } break; case DST: if((rtn->flags & ANY_DST_IP) == 0) { DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"CheckDstIP -> ");); AddRuleFuncToList(CheckDstIP, rtn); } break; } } /**************************************************************************** * * Function: PortToFunc(RuleTreeNode *, int, int, int) * * Purpose: Links in the port analysis function for the current rule * * Arguments: rtn => the pointer to the current rules list entry to attach to * any_flag => accept any port if set * except_flag => indicates negation (logical NOT) of the test * mode => indicates whether this is a rule for the source * or destination port for the rule * * Returns: void function * ***************************************************************************/ static void PortToFunc(RuleTreeNode * rtn, int any_flag, int except_flag, int mode) { /* * if the any flag is set we don't need to perform any test to match on * this port */ if(any_flag) return; /* if the except_flag is up, test with the "NotEq" funcs */ if(except_flag) { switch(mode) { case SRC: DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"CheckSrcPortNotEq -> ");); AddRuleFuncToList(CheckSrcPortNotEq, rtn); break; case DST: DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"CheckDstPortNotEq -> ");); AddRuleFuncToList(CheckDstPortNotEq, rtn); break; } return; } /* default to setting the straight test function */ switch(mode) { case SRC: DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"CheckSrcPortEqual -> ");); AddRuleFuncToList(CheckSrcPortEqual, rtn); break; case DST: DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"CheckDstPortEqual -> ");); AddRuleFuncToList(CheckDstPortEqual, rtn); break; } return; } /**************************************************************************** * Function: ParsePreprocessor() * * Saves the preprocessor configuration for loading later after dynamic * preprocessor keywords and configuration functions have been registered. * Configuration is also used later for configuration reload to check if * configuration has changed. * * Arguments: * SnortConfig * * Snort configuration to attach preprocessor configuration to. * char * * The preprocessor arguments. * * Returns: void function * ***************************************************************************/ static void ParsePreprocessor(SnortConfig *sc, SnortPolicy *p, char *args) { char **toks; int num_toks; char *keyword; char *opts = NULL; PreprocConfig *config; if ((sc == NULL) || (p == NULL) || (args == NULL)) return; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES, "Preprocessor\n");); /* break out the arguments from the keywords */ toks = mSplit(args, ":", 2, &num_toks, '\\'); keyword = toks[0]; if (num_toks > 1) opts = toks[1]; /* Save the configuration and load later */ config = (PreprocConfig *)SnortAlloc(sizeof(PreprocConfig)); if (p->preproc_configs == NULL) { p->preproc_configs = config; } else { PreprocConfig *tmp = p->preproc_configs; while (tmp->next != NULL) tmp = tmp->next; tmp->next = config; } config->keyword = SnortStrdup(keyword); config->file_name = SnortStrdup(file_name); config->file_line = file_line; if (opts != NULL) config->opts = SnortStrdup(opts); else config->opts = NULL; mSplitFree(&toks, num_toks); } void ConfigurePreprocessors(SnortConfig *sc, int configure_dynamic) { char *stored_file_name = file_name; int stored_file_line = file_line; tSfPolicyId i; if (sc == NULL) return; for (i = 0; i < sc->num_policies_allocated; i++) { PreprocConfig *config; setParserPolicy(sc, i); if (sc->targeted_policies[i] == NULL) continue; config = sc->targeted_policies[i]->preproc_configs; for (; config != NULL; config = config->next) { PreprocConfigFuncNode *node; if (config->configured) continue; file_name = config->file_name; file_line = config->file_line; node = GetPreprocConfig(config->keyword); if ((node == NULL) && configure_dynamic) ParseError("Unknown preprocessor: \"%s\".", config->keyword); if (node != NULL) { #ifdef SNORT_RELOAD if (node->initialized) { if (node->reload_func != NULL) { PreprocessorSwapData *swapData; PreprocessorSwapData **swapDataNode; for (swapData = sc->preprocSwapData; swapData && swapData->preprocNode != node; swapData = swapData->next); if (!swapData) { swapData = (PreprocessorSwapData *)SnortAlloc(sizeof(*swapData)); swapData->preprocNode = node; for (swapDataNode = &sc->preprocSwapData; *swapDataNode; swapDataNode = &(*swapDataNode)->next); *swapDataNode = swapData; } node->reload_func(sc, config->opts, &swapData->data); if (!sc->streamReloadConfig && node->keyword && strcmp(node->keyword, "stream5_global") == 0) sc->streamReloadConfig = swapData->data; } } else #endif { if (node->config_func != NULL) node->config_func(sc, config->opts); } config->configured = 1; } } } #ifdef SNORT_RELOAD for (i = 0; i < sc->num_policies_allocated; i++) { PreprocConfig *config; setParserPolicy(sc, i); if (sc->targeted_policies[i] == NULL) continue; setParserPolicy(sc, i); config = sc->targeted_policies[i]->preproc_configs; /* Set all configured preprocessors to intialized */ for (; config != NULL; config = config->next) { if (config->configured) { PreprocConfigFuncNode *node = GetPreprocConfig(config->keyword); if (node != NULL) node->initialized = 1; } } } #endif /* Reset these since we're done with configuring dynamic preprocessors */ file_name = stored_file_name; file_line = stored_file_line; } #ifdef SIDE_CHANNEL static void ParseSideChannelModule(SnortConfig *sc, SnortPolicy *p, char *args) { char **toks; int num_toks; char *opts = NULL; SideChannelModuleConfig *config; toks = mSplit(args, ":", 2, &num_toks, '\\'); if (num_toks > 1) opts = toks[1]; config = (SideChannelModuleConfig *) SnortAlloc(sizeof(SideChannelModuleConfig)); if (sc->side_channel_config.module_configs == NULL) { sc->side_channel_config.module_configs = config; } else { SideChannelModuleConfig *tmp = sc->side_channel_config.module_configs; while (tmp->next != NULL) tmp = tmp->next; tmp->next = config; } config->keyword = SnortStrdup(toks[0]); if (opts != NULL) config->opts = SnortStrdup(opts); /* This could come from parsing the command line (No, actually, I don't think that it could...) */ if (file_name != NULL) { config->file_name = SnortStrdup(file_name); config->file_line = file_line; } mSplitFree(&toks, num_toks); } void ConfigureSideChannelModules(SnortConfig *sc) { SideChannelModuleConfig *config; char *stored_file_name = file_name; int stored_file_line = file_line; int rval; for (config = sc->side_channel_config.module_configs; config != NULL; config = config->next) { file_name = config->file_name; file_line = config->file_line; rval = ConfigureSideChannelModule(config->keyword, config->opts); if (rval == -ENOENT) ParseError("Unknown side channel plugin: \"%s\"", config->keyword); } /* Reset these since we're done with configuring side channels */ file_name = stored_file_name; file_line = stored_file_line; } #endif /* SIDE_CHANNEL */ /* Parses standalone rate_filter configuration. * * Parses rate_filter configuration in the following format and populates internal * structures: * @code * rate_filter gid , sid , * track , * count , seconds , * new_action , * timeout [, apply_to ]; * @endcode * And then adds it into pContext. * * @param rule - string containing rate_filter configuration from snort.conf file. * * @returns void */ static void ParseRateFilter(SnortConfig *sc, SnortPolicy *p, char *args) { char **toks; int num_toks; int count_flag = 0; int new_action_flag = 0; int timeout_flag = 0; int seconds_flag = 0; int tracking_flag = 0; int genid_flag = 0; int sigid_flag = 0; int apply_flag = 0; int i; const char* ERR_KEY = "rate_filter"; tSFRFConfigNode thdx; memset( &thdx, 0, sizeof(thdx) ); /* Potential IP list might be present so we can't split on commas * Change commas to semi-colons */ args = FixSeparators(args, ';', "rate_filter"); toks = mSplit(args, ";", 0, &num_toks, 0); /* get rule option pairs */ for (i = 0; i < num_toks; i++) { char **pairs; int num_pairs; pairs = mSplit(toks[i], " \t", 2, &num_pairs, 0); /* get rule option pairs */ if (num_pairs != 2) { ParseError(ERR_NOT_PAIRED); } if (!strcasecmp(pairs[0], "gen_id")) { if ( genid_flag++ ) { ParseError(ERR_EXTRA_OPTION); } thdx.gid = xatou(pairs[1], "rate_filter: gen_id"); } else if (!strcasecmp(pairs[0], "sig_id")) { if ( sigid_flag++ ) { ParseError(ERR_EXTRA_OPTION); } thdx.sid = xatou(pairs[1], "rate_filter: sig_id"); } else if (!strcasecmp(pairs[0], "track")) { if ( tracking_flag++ ) { ParseError(ERR_EXTRA_OPTION); } if (!strcasecmp(pairs[1], "by_src")) { thdx.tracking = SFRF_TRACK_BY_SRC; } else if (!strcasecmp(pairs[1], "by_dst")) { thdx.tracking = SFRF_TRACK_BY_DST; } else if (!strcasecmp(pairs[1], "by_rule")) { thdx.tracking = SFRF_TRACK_BY_RULE; } else { ParseError(ERR_BAD_VALUE); } } else if (!strcasecmp(pairs[0], "count")) { if ( count_flag++ ) { ParseError(ERR_EXTRA_OPTION); } thdx.count = xatoup(pairs[1], "rate_filter: count"); } else if (!strcasecmp(pairs[0], "seconds")) { if ( seconds_flag++ ) { ParseError(ERR_EXTRA_OPTION); } thdx.seconds = xatou(pairs[1], "rate_filter: seconds"); } else if (!strcasecmp(pairs[0], "new_action")) { if ( new_action_flag++ ) { ParseError(ERR_EXTRA_OPTION); } if (!strcasecmp(pairs[1], "alert")) { thdx.newAction = RULE_TYPE__ALERT; } else if (!strcasecmp(pairs[1], "drop")) { thdx.newAction = RULE_TYPE__DROP; } else if (!strcasecmp(pairs[1], "pass")) { thdx.newAction = RULE_TYPE__PASS; } else if (!strcasecmp(pairs[1], "log")) { thdx.newAction = RULE_TYPE__LOG; } else if (!strcasecmp(pairs[1], "reject")) { thdx.newAction = RULE_TYPE__REJECT; } else if (!strcasecmp(pairs[1], "sdrop")) { thdx.newAction = RULE_TYPE__SDROP; } else { ParseError(ERR_BAD_VALUE); } } else if (!strcasecmp(pairs[0], "timeout")) { if ( timeout_flag++ ) { ParseError(ERR_EXTRA_OPTION); } thdx.timeout = xatou(pairs[1],"rate_filter: timeout"); } else if (!strcasecmp(pairs[0], "apply_to")) { char *ip_list = pairs[1]; if ( apply_flag++ ) { ParseError(ERR_EXTRA_OPTION); } thdx.applyTo = IpAddrSetParse(sc, ip_list); } else { ParseError(ERR_BAD_OPTION); } mSplitFree(&pairs, num_pairs); } if ( (genid_flag != 1) || (sigid_flag != 1) || (tracking_flag != 1) || (count_flag != 1) || (seconds_flag != 1) || (new_action_flag != 1) || (timeout_flag != 1) || (apply_flag > 1) ) { ParseError(ERR_BAD_ARG_COUNT); } if ( !thdx.seconds && (thdx.gid != GENERATOR_INTERNAL || thdx.sid != INTERNAL_EVENT_SESSION_ADD) ) { ParseError("rate_filter: seconds must be > 0"); } if (RateFilter_Create(sc, sc->rate_filter_config, &thdx)) { ParseError(ERR_CREATE); } mSplitFree(&toks, num_toks); } static void ParseRuleTypeOutput(SnortConfig *sc, char *args, ListHead *list) { char **toks; int num_toks; char *opts = NULL; OutputConfig *config; toks = mSplit(args, ":", 2, &num_toks, '\\'); if (num_toks > 1) opts = toks[1]; config = (OutputConfig *)SnortAlloc(sizeof(OutputConfig)); if (sc->rule_type_output_configs == NULL) { sc->rule_type_output_configs = config; } else { OutputConfig *tmp = sc->rule_type_output_configs; while (tmp->next != NULL) tmp = tmp->next; tmp->next = config; } config->keyword = SnortStrdup(toks[0]); if (opts != NULL) config->opts = SnortStrdup(opts); config->rule_list = list; if (file_name != NULL) { config->file_name = SnortStrdup(file_name); config->file_line = file_line; } mSplitFree(&toks, num_toks); } void ParseOutput(SnortConfig *sc, SnortPolicy *p, char *args) { char **toks; int num_toks; char *opts = NULL; OutputConfig *config; toks = mSplit(args, ":", 2, &num_toks, '\\'); if (num_toks > 1) opts = toks[1]; config = (OutputConfig *)SnortAlloc(sizeof(OutputConfig)); if (sc->output_configs == NULL) { sc->output_configs = config; } else { OutputConfig *tmp = sc->output_configs; while (tmp->next != NULL) tmp = tmp->next; tmp->next = config; } config->keyword = SnortStrdup(toks[0]); if (opts != NULL) config->opts = SnortStrdup(opts); /* This could come from parsing the command line */ if (file_name != NULL) { config->file_name = SnortStrdup(file_name); config->file_line = file_line; } mSplitFree(&toks, num_toks); } static void TransferOutputConfigs(OutputConfig *from_list, OutputConfig **to_list) { if ((from_list == NULL) || (to_list == NULL)) return; for (; from_list != NULL; from_list = from_list->next) { if (*to_list == NULL) { *to_list = DupOutputConfig(from_list); } else { OutputConfig *tmp = DupOutputConfig(from_list); if (tmp != NULL) { tmp->next = *to_list; *to_list = tmp; } } } } static OutputConfig * DupOutputConfig(OutputConfig *dupme) { OutputConfig *medup; if (dupme == NULL) return NULL; medup = (OutputConfig *)SnortAlloc(sizeof(OutputConfig)); if (dupme->keyword != NULL) medup->keyword = SnortStrdup(dupme->keyword); if (dupme->opts != NULL) medup->opts = SnortStrdup(dupme->opts); if (dupme->file_name != NULL) medup->file_name = SnortStrdup(dupme->file_name); medup->file_line = dupme->file_line; medup->rule_list = dupme->rule_list; return medup; } static void RemoveOutputConfigs(OutputConfig **head, int remove_flags) { OutputConfig *config; OutputConfig *last = NULL; if (head == NULL) return; config = *head; while (config != NULL) { int type_flags = GetOutputTypeFlags(config->keyword); if (type_flags & remove_flags) { OutputConfig *tmp = config; config = config->next; if (last == NULL) *head = config; else last->next = config; free(tmp->keyword); if (tmp->opts != NULL) free(tmp->opts); if (tmp->file_name != NULL) free(tmp->file_name); free(tmp); } else { last = config; config = config->next; } } } void ResolveOutputPlugins(SnortConfig *cmd_line, SnortConfig *config_file) { int cmd_line_type_flags = 0; if (cmd_line == NULL) return; if (cmd_line->no_log) { /* Free any log output plugins in both lists */ RemoveOutputConfigs(&cmd_line->output_configs, OUTPUT_TYPE__LOG); if (config_file != NULL) { RemoveOutputConfigs(&config_file->output_configs, OUTPUT_TYPE__LOG); RemoveOutputConfigs(&config_file->rule_type_output_configs, OUTPUT_TYPE__LOG); } } else if ((config_file != NULL) && config_file->no_log) { /* Free any log output plugins in config list */ RemoveOutputConfigs(&config_file->output_configs, OUTPUT_TYPE__LOG); RemoveOutputConfigs(&config_file->rule_type_output_configs, OUTPUT_TYPE__LOG); } if (cmd_line->no_alert) { /* Free any alert output plugins in both lists */ RemoveOutputConfigs(&cmd_line->output_configs, OUTPUT_TYPE__ALERT); if (config_file != NULL) { RemoveOutputConfigs(&config_file->output_configs, OUTPUT_TYPE__ALERT); RemoveOutputConfigs(&config_file->rule_type_output_configs, OUTPUT_TYPE__ALERT); } } else if ((config_file != NULL) && config_file->no_alert) { /* Free any alert output plugins in config list */ RemoveOutputConfigs(&config_file->output_configs, OUTPUT_TYPE__ALERT); RemoveOutputConfigs(&config_file->rule_type_output_configs, OUTPUT_TYPE__ALERT); } /* Command line overrides configuration file output */ if (cmd_line->output_configs != NULL) { OutputConfig *config = cmd_line->output_configs; for (; config != NULL; config = config->next) { int type_flags = GetOutputTypeFlags(config->keyword); cmd_line_type_flags |= type_flags; if (config_file != NULL) { RemoveOutputConfigs(&config_file->output_configs, type_flags); RemoveOutputConfigs(&config_file->rule_type_output_configs, type_flags); } } /* Put what's in the command line output into the config file output */ if (config_file != NULL) TransferOutputConfigs(cmd_line->output_configs, &config_file->output_configs); } if (config_file != NULL) { if (cmd_line->no_log) config_file->no_log = cmd_line->no_log; if (cmd_line->no_alert) config_file->no_alert = cmd_line->no_alert; } /* Don't try to configure defaults if running in test mode */ if (!ScTestModeNewConf(cmd_line)) { if (config_file == NULL) { if (!cmd_line->no_log && !(cmd_line_type_flags & OUTPUT_TYPE__LOG)) ParseOutput(cmd_line, NULL, "log_tcpdump"); if (!cmd_line->no_alert && !(cmd_line_type_flags & OUTPUT_TYPE__ALERT)) ParseOutput(cmd_line, NULL, "alert_full"); } else { int config_file_type_flags = 0; OutputConfig *config = config_file->output_configs; for (; config != NULL; config = config->next) config_file_type_flags |= GetOutputTypeFlags(config->keyword); if (!config_file->no_log && !(config_file_type_flags & OUTPUT_TYPE__LOG)) ParseOutput(config_file, NULL, "log_tcpdump"); if (!config_file->no_alert && !(config_file_type_flags & OUTPUT_TYPE__ALERT)) ParseOutput(config_file, NULL, "alert_full"); } } } void ConfigureOutputPlugins(SnortConfig *sc) { OutputConfig *config; char *stored_file_name = file_name; int stored_file_line = file_line; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Output Plugin\n");); for (config = sc->output_configs; config != NULL; config = config->next) { OutputConfigFunc oc_func; file_name = config->file_name; file_line = config->file_line; oc_func = GetOutputConfigFunc(config->keyword); if (oc_func == NULL) ParseError("Unknown output plugin: \"%s\"", config->keyword); oc_func(sc, config->opts); } /* Configure output plugins for user defined rule types */ for (config = sc->rule_type_output_configs; config != NULL; config = config->next) { OutputConfigFunc oc_func; file_name = config->file_name; file_line = config->file_line; oc_func = GetOutputConfigFunc(config->keyword); if (oc_func == NULL) ParseError("Unknown output plugin \"%s\"", config->keyword); /* Each user defined rule type has it's own rule list and output plugin is * attached to it's Alert and/or Log lists */ sc->head_tmp = config->rule_list; oc_func(sc, config->opts); sc->head_tmp = NULL; } /* Reset these since we're done with configuring dynamic preprocessors */ file_name = stored_file_name; file_line = stored_file_line; } static void FreeRuleTreeNode(RuleTreeNode *rtn) { RuleFpList *idx, *tmp; if (!rtn) return; if (rtn->sip) { sfvar_free(rtn->sip); } if (rtn->dip) { sfvar_free(rtn->dip); } idx = rtn->rule_func; while (idx) { tmp = idx; idx = idx->next; free(tmp); } } static void DestroyRuleTreeNode(RuleTreeNode *rtn) { if (!rtn) return; rtn->otnRefCount--; if (rtn->otnRefCount != 0) return; FreeRuleTreeNode(rtn); free(rtn); } /**************************************************************************** * * Function: mergeDuplicateOtn() * * Purpose: Conditionally removes duplicate SID/GIDs. Keeps duplicate with * higher revision. If revision is the same, keeps newest rule. * * Arguments: otn_dup => The existing duplicate * rtn => the RTN chain to check * char => String describing the rule * rule_type => enumerated rule type (alert, pass, log) * * Returns: 0 if original rule stays, 1 if new rule stays * ***************************************************************************/ static int mergeDuplicateOtn(SnortConfig *sc, OptTreeNode *otn_dup, OptTreeNode *otn_new, RuleTreeNode *rtn_new) { RuleTreeNode *rtn_dup = NULL; RuleTreeNode *rtnTmp2 = NULL; unsigned i; if (otn_dup->proto != otn_new->proto) { ParseError("GID %d SID %d in rule duplicates previous rule, with " "different protocol.", otn_new->sigInfo.generator, otn_new->sigInfo.id); } rtn_dup = getParserRtnFromOtn(sc, otn_dup); if((rtn_dup != NULL) && (rtn_dup->type != rtn_new->type)) { ParseError("GID %d SID %d in rule duplicates previous rule, with " "different type.", otn_new->sigInfo.generator, otn_new->sigInfo.id); } if((otn_new->sigInfo.shared < otn_dup->sigInfo.shared) || ((otn_new->sigInfo.shared == otn_dup->sigInfo.shared) && (otn_new->sigInfo.rev < otn_dup->sigInfo.rev))) { //existing OTN is newer version. Keep existing and discard the new one. //OTN is for new policy group, salvage RTN deleteRtnFromOtn(sc, otn_new, getParserPolicy(sc)); ParseMessage("GID %d SID %d duplicates previous rule. Using %s.", otn_new->sigInfo.generator, otn_new->sigInfo.id, otn_dup->sigInfo.shared ? "SO rule.":"higher revision"); /* delete the data for each rule option in this OTN */ OtnDeleteData(otn_new); /* Now free the OTN itself -- this function is also used * by the hash-table calls out of OtnRemove, so it cannot * be modified to delete data for rule options */ OtnFree(otn_new); //Add rtn to existing otn for the first rule instance in a policy, //otherwise ignore it if (rtn_dup == NULL) { addRtnToOtn(sc, otn_dup, getParserPolicy(sc), rtn_new); } else { DestroyRuleTreeNode(rtn_new); } return 0; } //delete existing rule instance and keep the new one for (i = 0; i < otn_dup->proto_node_num; i++) { rtnTmp2 = deleteRtnFromOtn(sc, otn_dup, i); if ((rtnTmp2 && (i != getParserPolicy(sc)))) { addRtnToOtn(sc, otn_new, i, rtnTmp2); } } if (rtn_dup) { if (ScConfErrorOutNewConf(sc)) { ParseError("GID %d SID %d in rule duplicates previous rule.", otn_new->sigInfo.generator, otn_new->sigInfo.id); } else { ParseWarning("GID %d SID %d in rule duplicates previous " "rule. Ignoring old rule.\n", otn_new->sigInfo.generator, otn_new->sigInfo.id); } switch (otn_new->sigInfo.rule_type) { case SI_RULE_TYPE_DETECT: detect_rule_count--; break; case SI_RULE_TYPE_DECODE: decode_rule_count--; break; case SI_RULE_TYPE_PREPROC: preproc_rule_count--; break; default: break; } } otn_count--; OtnRemove(sc->otn_map, sc->so_rule_otn_map, otn_dup); DestroyRuleTreeNode(rtn_dup); return 1; } /**************************************************************************** * * Function: ParseRuleOptions(char *, int) * * Purpose: Process an individual rule's options and add it to the * appropriate rule chain * * Arguments: rule => rule string * rule_type => enumerated rule type (alert, pass, log) * *conflicts => Identifies whether there was a conflict due to duplicate * rule and whether existing otn was newer or not. * 0 - no conflict * 1 - existing otn is newer. * -1 - existing otn is older. * * Returns: * OptTreeNode * * The new OptTreeNode on success or NULL on error. * ***************************************************************************/ OptTreeNode * ParseRuleOptions(SnortConfig *sc, RuleTreeNode *rtn, char *rule_opts, RuleType rule_type, int protocol) { OptTreeNode *otn; RuleOptOtnHandler otn_handler = NULL; int num_detection_opts = 0; char *dopt_keyword = NULL; OptFpList *fpl = NULL; int got_sid = 0; otn = (OptTreeNode *)SnortAlloc(sizeof(OptTreeNode)); otn->chain_node_number = otn_count; otn->proto = protocol; otn->event_data.sig_generator = GENERATOR_SNORT_ENGINE; otn->sigInfo.generator = GENERATOR_SNORT_ENGINE; otn->sigInfo.rule_type = SI_RULE_TYPE_DETECT; /* standard rule */ otn->sigInfo.rule_flushing = SI_RULE_FLUSHING_ON; /* usually just standard rules cause a flush*/ otn->sigInfo.service_override = ServiceOverride_Nil; /* Set the default rule state */ otn->rule_state = ScDefaultRuleStateNewConf(sc); if (rule_opts == NULL) { DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES, "No rule options.\n");); if (ScRequireRuleSidNewConf(sc)) ParseError("Each rule must contain a Rule-sid."); addRtnToOtn(sc, otn, getParserPolicy(sc), rtn); otn->ruleIndex = RuleIndexMapAdd(ruleIndexMap, otn->sigInfo.generator, otn->sigInfo.id); } else { char **toks; int num_toks; char configured[sizeof(rule_options) / sizeof(RuleOptFunc)]; int i; OptTreeNode *otn_dup; if ((rule_opts[0] != '(') || (rule_opts[strlen(rule_opts) - 1] != ')')) { ParseError("Rule options must be enclosed in '(' and ')'."); } /* Move past '(' and zero out ')' */ rule_opts++; rule_opts[strlen(rule_opts) - 1] = '\0'; /* Used to determine if a rule option has already been configured * in the rule. Some can only be configured once */ memset(configured, 0, sizeof(configured)); toks = mSplit(rule_opts, ";", 0, &num_toks, '\\'); for (i = 0; i < num_toks; i++) { char **opts; int num_opts; char *option_args = NULL; int j; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES," option: %s\n", toks[i]);); /* break out the option name from its data */ opts = mSplit(toks[i], ":", 2, &num_opts, '\\'); DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES," option name: %s\n", opts[0]);); if (num_opts == 2) { option_args = opts[1]; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES," option args: %s\n", option_args);); } for (j = 0; rule_options[j].name != NULL; j++) { if (strcasecmp(opts[0], rule_options[j].name) == 0) { if (configured[j] && rule_options[j].only_once) { ParseError("Only one '%s' rule option per rule.", opts[0]); } if ((option_args == NULL) && rule_options[j].args_required) { ParseError("No argument passed to keyword \"%s\". " "Make sure you didn't forget a ':' or the " "argument to this keyword.\n", opts[0]); } rule_options[j].parse_func(sc, rtn, otn, rule_type, option_args); configured[j] = 1; if ( !dopt_keyword && rule_options[j].detection ) dopt_keyword = SnortStrdup(opts[0]); break; } } /* Because we actually allow an sid of 0 */ if ((rule_options[j].name != NULL) && (strcasecmp(rule_options[j].name, RULE_OPT__SID) == 0)) { got_sid = 1; } /* It's possibly a detection option plugin */ if (rule_options[j].name == NULL) { RuleOptConfigFuncNode *dopt = rule_opt_config_funcs; for (; dopt != NULL; dopt = dopt->next) { if (strcasecmp(opts[0], dopt->keyword) == 0) { dopt->func(sc, option_args, otn, protocol); /* If this option contains an OTN handler, save it for use after the rule is done parsing. */ if (dopt->otn_handler != NULL) otn_handler = dopt->otn_handler; /* This is done so if we have a preprocessor/decoder * rule, we can tell the user that detection options * are not supported with those types of rules, and * what the detection option is */ if ((dopt_keyword == NULL) && (dopt->type == OPT_TYPE_DETECTION)) { dopt_keyword = SnortStrdup(opts[0]); } break; } } if (dopt == NULL) { /* Maybe it's a preprocessor rule option */ PreprocOptionInit initFunc = NULL; PreprocOptionEval evalFunc = NULL; PreprocOptionFastPatternFunc fpFunc = NULL; PreprocOptionOtnHandler preprocOtnHandler = NULL; PreprocOptionCleanup cleanupFunc = NULL; void *opt_data = NULL; int ret = GetPreprocessorRuleOptionFuncs (sc, opts[0], &initFunc, &evalFunc, &preprocOtnHandler, &fpFunc, &cleanupFunc); if (ret && (initFunc != NULL)) { initFunc(sc, opts[0], option_args, &opt_data); AddPreprocessorRuleOption(sc, opts[0], otn, opt_data, evalFunc); if (preprocOtnHandler != NULL) otn_handler = (RuleOptOtnHandler)preprocOtnHandler; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "%s->", opts[0]);); } else { /* Unrecognized rule option */ ParseError("Unknown rule option: '%s'.", opts[0]); } } if (dopt_keyword == NULL) dopt_keyword = SnortStrdup(opts[0]); num_detection_opts++; } mSplitFree(&opts, num_opts); } if ((dopt_keyword != NULL) && (otn->sigInfo.rule_type != SI_RULE_TYPE_DETECT)) { /* Preprocessor and decoder rules can not have * detection options */ ParseError("Preprocessor and decoder rules do not support " "detection options: %s.", dopt_keyword); } if (dopt_keyword != NULL) free(dopt_keyword); /* Each rule must have a sid irrespective of snort * in test mode or IPS/IDS mode.*/ if (!got_sid) ParseError("Each rule must contain a rule sid."); DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"OptListEnd\n");); addRtnToOtn(sc, otn, getParserPolicy(sc), rtn); /* Check for duplicate SID */ otn_dup = OtnLookup(sc->otn_map, otn->sigInfo.generator, otn->sigInfo.id); if (otn_dup != NULL) { otn->ruleIndex = otn_dup->ruleIndex; if (mergeDuplicateOtn(sc, otn_dup, otn, rtn) == 0) { /* We are keeping the old/dup OTN and trashing the new one * we just created - it's free'd in the remove dup function */ mSplitFree(&toks, num_toks); return NULL; } } else { otn->ruleIndex = RuleIndexMapAdd(ruleIndexMap, otn->sigInfo.generator, otn->sigInfo.id); } mSplitFree(&toks, num_toks); } otn->num_detection_opts += num_detection_opts; otn_count++; if (otn->sigInfo.rule_type == SI_RULE_TYPE_DETECT) { detect_rule_count++; } else if (otn->sigInfo.rule_type == SI_RULE_TYPE_DECODE) { //Set the bit if the decoder rule is enabled in the policies UpdateDecodeRulesArray(otn->sigInfo.id, ENABLE_RULE, ENABLE_ONE_RULE); decode_rule_count++; } else if (otn->sigInfo.rule_type == SI_RULE_TYPE_PREPROC) { preproc_rule_count++; } fpl = AddOptFuncToList(OptListEnd, otn); fpl->type = RULE_OPTION_TYPE_LEAF_NODE; if (otn_handler != NULL) { otn_handler(sc, otn); } FinalizeContentUniqueness(sc, otn); ValidateFastPattern(otn); if ((thdx_tmp != NULL) && (otn->detection_filter != NULL)) { ParseError("The \"detection_filter\" rule option and the \"threshold\" " "rule option cannot be used in the same rule.\n"); } if (thdx_tmp != NULL) { int rstat; thdx_tmp->sig_id = otn->sigInfo.id; thdx_tmp->gen_id = otn->sigInfo.generator; rstat = sfthreshold_create(sc, sc->threshold_config, thdx_tmp); if (rstat) { if (rstat == THD_TOO_MANY_THDOBJ) { ParseError("threshold (in rule): could not create threshold - " "only one per sig_id=%u.", thdx_tmp->sig_id); } else { ParseError("threshold (in rule): could not add threshold " "for sig_id=%u!\n", thdx_tmp->sig_id); } } thdx_tmp = NULL; } /* setup gid,sid->otn mapping */ SoRuleOtnLookupAdd(sc->so_rule_otn_map, otn); OtnLookupAdd(sc->otn_map, otn); return otn; } /**************************************************************************** * * Function: GetRuleProtocol(char *) * * Purpose: Figure out which protocol the current rule is talking about * * Arguments: proto_str => the protocol string * * Returns: The integer value of the protocol * ***************************************************************************/ static int GetRuleProtocol(char *proto_str) { if (strcasecmp(proto_str, RULE_PROTO_OPT__TCP) == 0) { return IPPROTO_TCP; } else if (strcasecmp(proto_str, RULE_PROTO_OPT__UDP) == 0) { return IPPROTO_UDP; } else if (strcasecmp(proto_str, RULE_PROTO_OPT__ICMP) == 0) { return IPPROTO_ICMP; } else if (strcasecmp(proto_str, RULE_PROTO_OPT__IP) == 0) { return ETHERNET_TYPE_IP; } else { /* If we've gotten here, we have a protocol string we didn't recognize * and should exit */ ParseError("Bad protocol: %s.", proto_str); } return -1; } static int ProcessIP(SnortConfig *sc, char *addr, RuleTreeNode *rtn, int mode, int neg_list) { vartable_t *ip_vartable = sc->targeted_policies[getParserPolicy(sc)]->ip_vartable; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Got address string: %s\n", addr);); assert(rtn); /* If a rule has a variable in it, we want to copy that variable's * contents to the IP variable (IP list) stored with the rtn. * This code tries to look up the variable, and if found, will copy it * to the rtn->{sip,dip} */ if(mode == SRC) { int ret; if (rtn->sip == NULL) { sfip_var_t *tmp = sfvt_lookup_var(ip_vartable, addr); if (tmp != NULL) { rtn->sip = sfvar_create_alias(tmp, tmp->name); if (rtn->sip == NULL) ret = SFIP_FAILURE; else ret = SFIP_SUCCESS; } else { rtn->sip = (sfip_var_t *)SnortAlloc(sizeof(sfip_var_t)); ret = sfvt_add_to_var(ip_vartable, rtn->sip, addr); } } else { ret = sfvt_add_to_var(ip_vartable, rtn->sip, addr); } /* The function sfvt_add_to_var adds 'addr' to the variable 'rtn->sip' */ if (ret != SFIP_SUCCESS) { if(ret == SFIP_LOOKUP_FAILURE) { ParseError("Undefined variable in the string: %s.", addr); } else if(ret == SFIP_CONFLICT) { ParseError("Negated IP ranges that are more general than " "non-negated ranges are not allowed. Consider " "inverting the logic: %s.", addr); } else if(ret == SFIP_NOT_ANY) { ParseError("!any is not allowed: %s.", addr); } else { ParseError("Unable to process the IP address: %s.", addr); } } if(rtn->sip->head && rtn->sip->head->flags & SFIP_ANY) { rtn->flags |= ANY_SRC_IP; } } /* mode == DST */ else { int ret; if (rtn->dip == NULL) { sfip_var_t *tmp = sfvt_lookup_var(ip_vartable, addr); if (tmp != NULL) { rtn->dip = sfvar_create_alias(tmp, tmp->name); if (rtn->dip == NULL) ret = SFIP_FAILURE; else ret = SFIP_SUCCESS; } else { rtn->dip = (sfip_var_t *)SnortAlloc(sizeof(sfip_var_t)); ret = sfvt_add_to_var(ip_vartable, rtn->dip, addr); } } else { ret = sfvt_add_to_var(ip_vartable, rtn->dip, addr); } if (ret != SFIP_SUCCESS) { if(ret == SFIP_LOOKUP_FAILURE) { ParseError("Undefined variable in the string: %s.", addr); } else if(ret == SFIP_CONFLICT) { ParseError("Negated IP ranges that are more general than " "non-negated ranges are not allowed. Consider " "inverting the logic: %s.", addr); } else if(ret == SFIP_NOT_ANY) { ParseError("!any is not allowed: %s.", addr); } else { ParseError("Unable to process the IP address: %s.", addr); } } if(rtn->dip->head && rtn->dip->head->flags & SFIP_ANY) { rtn->flags |= ANY_DST_IP; } } /* Make sure the IP lists provided by the user are valid */ if (mode == SRC) ValidateIPList(rtn->sip, addr); else ValidateIPList(rtn->dip, addr); return 0; } /**************************************************************************** * * Function: ParsePort(SnortConfig *, char *, u_short *) * * Purpose: Convert the port string over to an integer value * * Arguments: prule_port => port rule string * port => converted integer value of the port * * Returns: 0 for a normal port number, 1 for an "any" port * ***************************************************************************/ int ParsePort(SnortConfig *sc, char *prule_port, uint16_t *hi_port, uint16_t *lo_port, char *proto, int *not_flag) { char **toks; /* token dbl buffer */ int num_toks; /* number of tokens found by mSplit() */ char *rule_port; /* port string */ *not_flag = 0; /* check for variable */ if(!strncmp(prule_port, "$", 1)) { if((rule_port = VarGet(sc, prule_port + 1)) == NULL) { ParseError("Undefined variable %s.", prule_port); } } else rule_port = prule_port; if(rule_port[0] == '(') { /* user forgot to put a port number in for this rule */ ParseError("Bad port number: \"%s\".", rule_port); } /* check for wildcards */ if(!strcasecmp(rule_port, "any")) { *hi_port = 0; *lo_port = 0; return 1; } if(rule_port[0] == '!') { if(!strcasecmp(&rule_port[1], "any")) { ParseWarning("Negating \"any\" is invalid. Rule " "will be ignored."); return -1; } *not_flag = 1; rule_port++; } if(rule_port[0] == ':') { *lo_port = 0; } toks = mSplit(rule_port, ":", 2, &num_toks, 0); switch(num_toks) { case 1: *hi_port = (u_short)ConvPort(toks[0], proto); if(rule_port[0] == ':') { *lo_port = 0; } else { *lo_port = *hi_port; if(strchr(rule_port, ':') != NULL) { *hi_port = MAXPORTS-1; } } break; case 2: *lo_port = (u_short)ConvPort(toks[0], proto); if(toks[1][0] == 0) *hi_port = MAXPORTS-1; else *hi_port = (u_short)ConvPort(toks[1], proto); break; default: ParseError("Port conversion failed on \"%s\".", rule_port); } mSplitFree(&toks, num_toks); return 0; } /**************************************************************************** * * Function: ConvPort(char *, char *) * * Purpose: Convert the port string over to an integer value * * Arguments: port => port string * proto => converted integer value of the port * * Returns: the port number * ***************************************************************************/ uint16_t ConvPort(char *port, char *proto) { int conv; /* storage for the converted number */ char *digit; /* used to check for a number */ struct servent *service_info; /* * convert a "word port" (http, ftp, imap, whatever) to its corresponding * numeric port value */ if(isalpha((int) port[0]) != 0) { service_info = getservbyname(port, proto); if(service_info != NULL) { conv = ntohs(service_info->s_port); return conv; } else { ParseError("getservbyname() failed on \"%s\".", port); } } digit = port; while (*digit) { if(!isdigit((int) *digit)) { ParseError("Invalid port: %s.", port); } digit++; } /* convert the value */ conv = atoi(port); /* make sure it's in bounds */ if ((conv < 0) || (conv > MAXPORTS-1)) { ParseError("Bad port number: %s.", port); } return (uint16_t)conv; } /**************************************************************************** * * Function: XferHeader(RuleTreeNode *, RuleTreeNode *) * * Purpose: Transfer the rule block header data from point A to point B * * Arguments: rule => the place to xfer from * rtn => the place to xfer to * * Returns: void function * ***************************************************************************/ static void XferHeader(RuleTreeNode *test_node, RuleTreeNode *rtn) { rtn->flags = test_node->flags; rtn->type = test_node->type; rtn->sip = test_node->sip; rtn->dip = test_node->dip; rtn->proto = test_node->proto; rtn->src_portobject = test_node->src_portobject; rtn->dst_portobject = test_node->dst_portobject; } /**************************************************************************** * * Function: CompareIPNodes(RuleTreeNode *, RuleTreeNode *). Support function * for CompareIPLists. * * Purpose: Checks if the node's contents equal. * * Returns: 1 if they match, 0 if they don't * ***************************************************************************/ int CompareIPNodes(IpAddrNode *one, IpAddrNode *two) { if( (sfip_compare(&one->ip->addr, &two->ip->addr) != SFIP_EQUAL) || (sfip_bits(one->ip) != sfip_bits(two->ip)) || (sfvar_flags(one) != sfvar_flags(two)) ) return 0; return 1; } /**************************************************************************** * * Function: TestHeader(RuleTreeNode *, RuleTreeNode *) * * Purpose: Check to see if the two header blocks are identical * * Arguments: rule => uh * rtn => uuuuhhhhh.... * * Returns: 1 if they match, 0 if they don't * ***************************************************************************/ static int TestHeader(RuleTreeNode * rule, RuleTreeNode * rtn) { if ((rule == NULL) || (rtn == NULL)) return 0; if (rule->type != rtn->type) return 0; if (rule->proto != rtn->proto) return 0; /* For custom rule type declarations */ if (rule->listhead != rtn->listhead) return 0; if (rule->flags != rtn->flags) return 0; if ((rule->sip != NULL) && (rtn->sip != NULL) && (sfvar_compare(rule->sip, rtn->sip) != SFIP_EQUAL)) { return 0; } if ((rule->dip != NULL) && (rtn->dip != NULL) && (sfvar_compare(rule->dip, rtn->dip) != SFIP_EQUAL)) { return 0; } /* compare the port group pointers - this prevents confusing src/dst port objects * with the same port set, and it's quicker. It does assume that we only have * one port object and pointer for each unique port set...this is handled by the * parsing and initial port object storage and lookup. This must be consistent during * the rule parsing phase. - man */ if ((rule->src_portobject != rtn->src_portobject) || (rule->dst_portobject != rtn->dst_portobject)) { return 0; } return 1; } /* * PortVarDefine * * name - portlist name, i.e. http, smtp, ... * s - port number, port range, or a list of numbers/ranges in brackets * * examples: * portvar http [80,8080,8138,8700:8800,!8711] * portvar http $http_basic */ static int PortVarDefine(SnortConfig *sc, char *name, char *s) { PortObject *po; POParser pop; char *errstr="unknown"; int rstat; PortVarTable *portVarTable = sc->targeted_policies[getParserPolicy(sc)]->portVarTable; char *end; bool invalidvar = true; DisallowCrossTableDuplicateVars(sc, name, VAR_TYPE__PORTVAR); for(end = name; *end && !isspace((int)*end) && *end != '\\'; end++) { if(isalpha((int)*end)) invalidvar = false; } if(invalidvar) ParseError("Can not define variable name - %s. Use different name", name); if( SnortStrcasestr(s,strlen(s),"any") ) /* this allows 'any' or '[any]' */ { if(strstr(s,"!")) { ParseError("Illegal use of negation and 'any': %s.", s); } po = PortObjectNew(); if( !po ) { ParseError("PortVarTable missing an 'any' variable.\n"); } PortObjectSetName( po, name ); PortObjectAddPortAny( po ); } else { /* Parse the Port List info into a PortObject */ po = PortObjectParseString(portVarTable, &pop, name, s, 0); if(!po) { errstr = PortObjectParseError( &pop ); ParseError("*** PortVar Parse error: (pos=%d,error=%s)\n>>%s\n>>%*s.", pop.pos,errstr,s,pop.pos,"^"); } } /* Add The PortObject to the PortList Table */ rstat = PortVarTableAdd(portVarTable, po); if( rstat < 0 ) { ParseError("***PortVarTableAdd failed with '%s', exiting.", po->name); } else if( rstat > 0 ) { ParseMessage("PortVar '%s', already defined.", po->name); } /* Print the PortList - PortObjects */ LogMessage("PortVar '%s' defined : ",po->name); PortObjectPrintPortsRaw(po); LogMessage("\n"); return 0; } /**************************************************************************** * * Function: VarAlloc() * * Purpose: allocates memory for a variable * * Arguments: none * * Returns: pointer to new VarEntry * ***************************************************************************/ VarEntry *VarAlloc() { VarEntry *new; new = (VarEntry *)SnortAlloc(sizeof(VarEntry)); return(new); } /**************************************************************************** * * Function: VarIsIpAddr(char *, char *) * * Purpose: Checks if a var is an IP address. Necessary since moving forward * we want all IP addresses handled by the IP variable table. * If a list is given, this checks each value. * * Arguments: value => the string to check * * Returns: 1 if IP address, 0 otherwise * ***************************************************************************/ static int VarIsIpAddr(vartable_t *ip_vartable, char *value) { char *tmp; /* empty list, consider this an IP address */ if ((*value == '[') && (*(value+1) == ']')) return 1; while(*value == '!' || *value == '[') value++; /* Check for dotted-quad */ if( isdigit((int)*value) && ((tmp = strchr(value, (int)'.')) != NULL) && ((tmp = strchr(tmp+1, (int)'.')) != NULL) && (strchr(tmp+1, (int)'.') != NULL)) return 1; /* IPv4 with a mask, and fewer than 4 fields */ else if( isdigit((int)*value) && (strchr(value+1, (int)':') == NULL) && ((tmp = strchr(value+1, (int)'/')) != NULL) && isdigit((int)(*(tmp+1))) ) return 1; /* IPv6 */ else if((tmp = strchr(value, (int)':')) != NULL) { char *tmp2; if((tmp2 = strchr(tmp+1, (int)':')) == NULL) return 0; for(tmp++; tmp < tmp2; tmp++) if(!isxdigit((int)*tmp)) return 0; return 1; } /* Any */ else if(!strncmp(value, "any", 3)) return 1; /* Check if it's a variable containing an IP */ else if(sfvt_lookup_var(ip_vartable, value+1) || sfvt_lookup_var(ip_vartable, value)) return 1; return 0; } /**************************************************************************** * * Function: CheckBrackets(char *) * * Purpose: Check that the brackets match up in a string that * represents a list. * * Arguments: value => the string to check * * Returns: 1 if the brackets match correctly, 0 otherwise * ***************************************************************************/ static int CheckBrackets(char *value) { int num_brackets = 0; while (*value == '!') value++; if ((value[0] != '[') || value[strlen(value)-1] != ']') { /* List does not begin or end with a bracket. */ return 0; } while ((*value != '\0') && (num_brackets >= 0)) { if (*value == '[') num_brackets++; else if (*value == ']') num_brackets--; value++; } if (num_brackets != 0) { /* Mismatched brackets */ return 0; } return 1; } /**************************************************************************** * * Function: VarIsIpList(vartable_t *, char*) * * Purpose: Checks if a var is a list of IP addresses. * * Arguments: value => the string to check * * Returns: 1 if each item is an IP address, 0 otherwise * ***************************************************************************/ static int VarIsIpList(vartable_t *ip_vartable, char *value) { char *copy, *item; int item_is_ip = 1; copy = SnortStrdup((const char*)value); /* Ensure that the brackets are correct. */ if (strchr((const char*)copy, ',')) { /* This is a list! */ if (CheckBrackets(copy) == 0) { free(copy); return 0; } } /* There's no need to worry about the list structure here. * We just strip out the IP delimiters and process each one. */ item = strtok(copy, "[],!"); while ((item != NULL) && item_is_ip) { item_is_ip = VarIsIpAddr(ip_vartable, item); item = strtok(NULL, "[],!"); } free(copy); return item_is_ip; } /**************************************************************************** * * Function: DisallowCrossTableDuplicateVars(char *, int) * * Purpose: FatalErrors if the a variable name is redefined across variable * types. Enforcing this mutual exclusion prevents the * catatrophe where the variable lookup fall-through (see VarSearch) * finds an unintended variable from the wrong table. Note: VarSearch * is only necessary for ExpandVars. * * Arguments: name => The name of the variable * var_type => The type of the variable that is about to be defined. * The corresponding variable table will not be searched. * * Returns: void function * ***************************************************************************/ static void DisallowCrossTableDuplicateVars(SnortConfig *sc, char *name, VarType var_type) { VarEntry *var_table = sc->targeted_policies[getParserPolicy(sc)]->var_table; PortVarTable *portVarTable = sc->targeted_policies[getParserPolicy(sc)]->portVarTable; VarEntry *p = var_table; vartable_t *ip_vartable = sc->targeted_policies[getParserPolicy(sc)]->ip_vartable; /* If this is a faked Portvar, treat as a portvar */ if ((var_type == VAR_TYPE__DEFAULT) && (strstr(name, "_PORT") || strstr(name, "PORT_"))) { var_type = VAR_TYPE__PORTVAR; } switch (var_type) { case VAR_TYPE__DEFAULT: if (PortVarTableFind(portVarTable, name) || sfvt_lookup_var(ip_vartable, name) ) { ParseError("Can not redefine variable name %s to be of type " "'var'. Use a different name.", name); } break; case VAR_TYPE__PORTVAR: if (var_table != NULL) { do { if(strcasecmp(p->name, name) == 0) { ParseError("Can not redefine variable name %s to be of " "type 'portvar'. Use a different name.", name); } p = p->next; } while(p != var_table); } if(sfvt_lookup_var(ip_vartable, name)) { ParseError("Can not redefine variable name %s to be of type " "'portvar'. Use a different name.", name); } break; case VAR_TYPE__IPVAR: if (var_table != NULL) { do { if(strcasecmp(p->name, name) == 0) { ParseError("Can not redefine variable name %s to be of " "type 'ipvar'. Use a different name.", name); } p = p->next; } while(p != var_table); } if(PortVarTableFind(portVarTable, name)) { ParseError("Can not redefine variable name %s to be of type " "'ipvar'. Use a different name.", name); } default: /* Invalid function usage */ break; } } /**************************************************************************** * * Function: VarDefine(char *, char *) * * Purpose: define the contents of a variable * * Arguments: name => the name of the variable * value => the contents of the variable * * Returns: void function * ***************************************************************************/ VarEntry * VarDefine(SnortConfig *sc, char *name, char *value) { VarEntry *var_table = sc->targeted_policies[getParserPolicy(sc)]->var_table; vartable_t *ip_vartable = sc->targeted_policies[getParserPolicy(sc)]->ip_vartable; VarEntry *p; uint32_t var_id = 0; if(value == NULL) { ParseError("Bad value in variable definition! Make sure you don't " "have a \"$\" in the var name."); } if(VarIsIpList(ip_vartable, value)) { SFIP_RET ret; if (ip_vartable == NULL) return NULL; /* Verify a variable by this name is not already used as either a * portvar or regular var. Enforcing this mutual exclusion prevents the * catatrophe where the variable lookup fall-through (see VarSearch) * finds an unintended variable from the wrong table. Note: VarSearch * is only necessary for ExpandVars. */ DisallowCrossTableDuplicateVars(sc, name, VAR_TYPE__IPVAR); if((ret = sfvt_define(ip_vartable, name, value)) != SFIP_SUCCESS) { switch(ret) { case SFIP_ARG_ERR: ParseError("The following is not allowed: %s.", value); break; case SFIP_DUPLICATE: ParseMessage("Var '%s' redefined.", name); break; case SFIP_CONFLICT: ParseError("Negated IP ranges that are more general than " "non-negated ranges are not allowed. Consider " "inverting the logic in %s.", name); break; case SFIP_NOT_ANY: ParseError("!any is not allowed in %s.", name); break; default: ParseError("Failed to parse the IP address: %s.", value); } } return NULL; } /* Check if this is a variable that stores an IP */ else if(*value == '$') { sfip_var_t *var; if((var = sfvt_lookup_var(ip_vartable, value)) != NULL) { sfvt_define(ip_vartable, name, value); return NULL; } } DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS, "VarDefine: name=%s value=%s\n",name,value);); /* Check to see if this variable is just being aliased */ if (var_table != NULL) { VarEntry *tmp = var_table; do { /* value+1 to move past $ */ if (strcmp(tmp->name, value+1) == 0) { var_id = tmp->id; break; } tmp = tmp->next; } while (tmp != var_table); } value = ExpandVars(sc, value); if(!value) { ParseError("Could not expand var('%s').", name); } DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS, "VarDefine: name=%s value=%s (expanded)\n",name,value);); DisallowCrossTableDuplicateVars(sc, name, VAR_TYPE__DEFAULT); if (var_table == NULL) { p = VarAlloc(); p->name = SnortStrdup(name); p->value = SnortStrdup(value); p->prev = p; p->next = p; sc->targeted_policies[getParserPolicy(sc)]->var_table = p; p->id = sc->targeted_policies[getParserPolicy(sc)]->var_id++; return p; } /* See if an existing variable is being redefined */ p = var_table; do { if (strcasecmp(p->name, name) == 0) { if (p->value != NULL) free(p->value); p->value = SnortStrdup(value); ParseWarning("Var '%s' redefined\n", p->name); return p; } p = p->next; } while (p != var_table); /* List is circular */ p = VarAlloc(); p->name = SnortStrdup(name); p->value = SnortStrdup(value); p->prev = var_table; p->next = var_table->next; p->next->prev = p; var_table->next = p; if (!var_id) p->id = sc->targeted_policies[getParserPolicy(sc)]->var_id++; else p->id = var_id; #ifdef XXXXXXX vlen = strlen(value); LogMessage("Var '%s' defined, value len = %d chars", p->name, vlen ); if( vlen < 64 ) { LogMessage(", value = %s\n", value ); } else { LogMessage("\n"); n = 128; s = value; while(vlen) { if( n > vlen ) n = vlen; LogMessage(" %.*s\n", n, s ); s += n; vlen -= n; } } #endif return p; } static void DeleteVars(VarEntry *var_table) { VarEntry *q, *p = var_table; while (p) { q = p->next; if (p->name) free(p->name); if (p->value) free(p->value); if (p->addrset) { IpAddrSetDestroy(p->addrset); } free(p); p = q; if (p == var_table) break; /* Grumble, it's a friggin circular list */ } } /**************************************************************************** * * Function: VarGet(SnortConfig *, char *) * * Purpose: get the contents of a variable * * Arguments: name => the name of the variable * * Returns: char * to contents of variable or FatalErrors on an * undefined variable name * ***************************************************************************/ char *VarGet(SnortConfig *sc, char *name) { SnortPolicy *policy; VarEntry *var_table; vartable_t *ip_vartable; sfip_var_t *var; if (sc == NULL) return NULL; policy = sc->targeted_policies[getParserPolicy(sc)]; if (policy == NULL) return NULL; var_table = sc->targeted_policies[getParserPolicy(sc)]->var_table; // XXX-IPv6 This function should never be used if IP6 support is enabled! // Infact it won't presently even work for IP variables since the raw ASCII // value is never stored, and is never meant to be used. ip_vartable = sc->targeted_policies[getParserPolicy(sc)]->ip_vartable; if((var = sfvt_lookup_var(ip_vartable, name)) == NULL) { /* Do the old style lookup since it wasn't found in * the variable table */ if(var_table != NULL) { VarEntry *p = var_table; do { if(strcasecmp(p->name, name) == 0) return p->value; p = p->next; } while(p != var_table); } ParseError("Undefined variable name: %s.", name); } return name; } /**************************************************************************** * * Function: ExpandVars() * * Purpose: expand all variables in a string * * Arguments: * SnortConfig * * The snort config that has the vartables. * char * * The name of the variable. * * Returns: * char * * The expanded string. Note that the string is returned in a * static variable and most likely needs to be string dup'ed. * ***************************************************************************/ static char * ExpandVars(SnortConfig *sc, char *string) { static char estring[ PARSERULE_SIZE ]; char rawvarname[128], varname[128], varaux[128], varbuffer[128]; char varmodifier, *varcontents; int varname_completed, c, i, j, iv, jv, l_string, name_only; int quote_toggle = 0; if(!string || !*string || !strchr(string, '$')) return(string); memset((char *) estring, 0, PARSERULE_SIZE); i = j = 0; l_string = strlen(string); DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES, "ExpandVars, Before: %s\n", string);); while(i < l_string && j < (int)sizeof(estring) - 1) { c = string[i++]; if(c == '"') { /* added checks to make sure that we are inside a quoted string */ quote_toggle ^= 1; } if(c == '$' && !quote_toggle) { memset((char *) rawvarname, 0, sizeof(rawvarname)); varname_completed = 0; name_only = 1; iv = i; jv = 0; if(string[i] == '(') { name_only = 0; iv = i + 1; } while(!varname_completed && iv < l_string && jv < (int)sizeof(rawvarname) - 1) { c = string[iv++]; if((name_only && !(isalnum(c) || c == '_')) || (!name_only && c == ')')) { varname_completed = 1; if(name_only) iv--; } else { rawvarname[jv++] = (char)c; } } if(varname_completed || iv == l_string) { char *p; i = iv; varcontents = NULL; memset((char *) varname, 0, sizeof(varname)); memset((char *) varaux, 0, sizeof(varaux)); varmodifier = ' '; p = strchr(rawvarname, ':'); if (p) { SnortStrncpy(varname, rawvarname, p - rawvarname); if(strlen(p) >= 2) { varmodifier = *(p + 1); SnortStrncpy(varaux, p + 2, sizeof(varaux)); } } else SnortStrncpy(varname, rawvarname, sizeof(varname)); memset((char *) varbuffer, 0, sizeof(varbuffer)); varcontents = VarSearch(sc, varname); switch(varmodifier) { case '-': if(!varcontents || !strlen(varcontents)) varcontents = varaux; break; case '?': if(!varcontents || !strlen(varcontents)) { ErrorMessage("%s(%d): ", file_name, file_line); if(strlen(varaux)) ParseError("%s", varaux); else ParseError("Undefined variable \"%s\".", varname); } break; } /* If variable not defined now, we're toast */ if(!varcontents || !strlen(varcontents)) ParseError("Undefined variable name: %s.", varname); if(varcontents) { int l_varcontents = strlen(varcontents); iv = 0; while(iv < l_varcontents && j < (int)sizeof(estring) - 1) estring[j++] = varcontents[iv++]; } } else { estring[j++] = '$'; } } else { estring[j++] = (char)c; } } DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES, "ExpandVars, After: %s\n", estring);); return estring; } char * ProcessFileOption(SnortConfig *sc, const char *filespec) { char *filename = NULL; char buffer[STD_BUF]; if (sc == NULL) sc = snort_conf; if(filespec == NULL) { ParseError("no argument in this file option, remove extra ':' at the end of the alert option\n"); } /* look for ".." in the string and complain and exit if it is found */ if(strstr(filespec, "..") != NULL) { ParseError("file definition contains \"..\". Do not do that!\n"); } if(filespec[0] == '/') { /* absolute filespecs are saved as is */ filename = SnortStrdup(filespec); } else { /* relative filespec is considered relative to the log directory */ /* or /var/log if the log directory has not been set */ /* Make sure this function isn't called before log dir is set */ if ((sc != NULL) && (sc->log_dir != NULL)) { strlcpy(buffer, snort_conf->log_dir, STD_BUF); } else { strlcpy(buffer, "/var/log/snort", STD_BUF); } strlcat(buffer, "/", STD_BUF - strlen(buffer)); strlcat(buffer, filespec, STD_BUF - strlen(buffer)); buffer[sizeof(buffer) - 1] = '\0'; filename = SnortStrdup(buffer); } DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"ProcessFileOption: %s\n", filename);); return filename; } #ifdef TARGET_BASED static void ParseAttributeTable(SnortConfig *sc, SnortPolicy *p, char *args) { tSfPolicyId currentPolicyId = getParserPolicy(sc); tSfPolicyId defaultPolicyId = sfGetDefaultPolicy(sc->policy_config); TargetBasedConfig *defTbc = &sc->targeted_policies[defaultPolicyId]->target_based_config; /* Save for configuring after configuration is parsed in case * config max_attribute_hosts is configured after this */ if ((currentPolicyId != defaultPolicyId) && ((defTbc->args == NULL) || (strcmp(args, defTbc->args) != 0))) { //arguments should be same as in default policy. Ignoring the arguments ParseError("Attribute table must be configured in default policy if " "it is to be used in other policies and attribute table " "filename must be the same across policies."); } if(p->target_based_config.args) free(p->target_based_config.args); p->target_based_config.args = SnortStrdup(args); if (file_name != NULL) { if(p->target_based_config.file_name) free(p->target_based_config.file_name); p->target_based_config.file_name = SnortStrdup(file_name); p->target_based_config.file_line = file_line; } } #endif static void ParseConfig(SnortConfig *sc, SnortPolicy *p, char *args) { char **toks; int num_toks; char *opts = NULL; int i; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Rule file config\n");); toks = mSplit(args, ":", 2, &num_toks, 0); DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Opt: %s\n", toks[0]);); if (num_toks > 1) { /* Dup the opts because we're putting into hash table */ opts = SnortStrdup(toks[1]); DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Args: %s\n", opts);); } switch (sfghash_add(sc->config_table, toks[0], opts)) { case SFGHASH_NOMEM: ParseError("%s(%d) No memory to add entry to config table.\n", __FILE__, __LINE__); break; case SFGHASH_INTABLE: /* Only reference and classifications are likely dup candidates * right now and we're not too worried about keeping track of * all of them */ if (opts != NULL) { free(opts); opts = toks[1]; } break; default: break; } for (i = 0; config_opts[i].name != NULL; i++) { if (strcasecmp(toks[0], config_opts[i].name) == 0) { if ((getParserPolicy(sc) != getDefaultPolicy()) && config_opts[i].default_policy_only) { /* Config option configurable on by the default policy*/ /**Dont raise parse error, ignore any config that is not allowed in non-default * policy. */ DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Config option \"%s\" " "configurable only by default policy. Ignoring it\n", toks[0])); break; } if (config_opts[i].only_once && config_opt_configured[i]) { /* Configured already and set to only configure once * This array is reset for each policy read in so this is * on a per policy basis */ ParseError("Config option \"%s\" can only be " "configured once.", toks[0]); } if (config_opts[i].args_required && (opts == NULL)) { /* Need arguments and there are none */ ParseError("Config option \"%s\" requires arguments.", toks[0]); } config_opts[i].parse_func(sc, opts); config_opt_configured[i] = 1; break; } } if (config_opts[i].name == NULL) { /* Didn't find a matching config option */ ParseError("Unknown config directive: %s.", toks[0]); } mSplitFree(&toks, num_toks); } /**************************************************************************** * * Purpose: Check that special rules have an OTN. * TODO: Free up memory associated with disabled rules. * * Arguments: list => Pointer for a list of rules * * Returns: void function * * Notes: man - modified to used .shared flag in otn sigInfo instead of specialGID * sas - removed specialGID * *****************************************************************************/ int CheckRuleStates(SnortConfig *sc) { RuleTreeNode *rtn; OptTreeNode *otn; SFGHASH_NODE *hashNode; int oneErr = 0; tSfPolicyId policyId = 0; if (sc == NULL) return 0; for (hashNode = sfghash_findfirst(sc->otn_map); hashNode; hashNode = sfghash_findnext(sc->otn_map)) { otn = (OptTreeNode *)hashNode->data; for (policyId = 0; policyId < otn->proto_node_num; policyId++) { rtn = otn->proto_nodes[policyId]; if (!rtn) { continue; } if ((rtn->proto == IPPROTO_TCP) || (rtn->proto == IPPROTO_UDP) || (rtn->proto == IPPROTO_ICMP) || (rtn->proto == ETHERNET_TYPE_IP)) { //do operation if ( otn->sigInfo.shared ) { if (otn->ds_list[PLUGIN_DYNAMIC] == NULL) { // Have a dynamic rule but no dynamic plugin if (otn->sigInfo.id != otn->sigInfo.otnKey.sid) { // If its a different SID, but same soid metadata as something // else, try to find it OptTreeNode *otn_original; otn_original = SoRuleOtnLookup(sc->so_rule_otn_map, otn->sigInfo.otnKey.gid, otn->sigInfo.otnKey.sid); if ( otn_original && (otn != otn_original) && !otn->sigInfo.dup_opt_func ) { OptFpList *opt_func = otn->opt_func; while (opt_func != NULL) { /* Delete the option functions that came from the * parsing -- this rule will be identical to its * "cloned" brother. */ OptFpList *tmp = opt_func; opt_func = opt_func->next; free(tmp); } if (otn_original->sigInfo.shared) { /* Its still a shared object -- has its own detection function. */ otn->ds_list[PLUGIN_DYNAMIC] = otn_original->ds_list[PLUGIN_DYNAMIC]; } else { /* It was back-converted from a shared object */ int i; for (i=PLUGIN_CLIENTSERVER; ids_list[i] = otn_original->ds_list[i]; } otn->sigInfo.shared = 0; /* no longer shared */ } otn->opt_func = otn_original->opt_func; otn->sigInfo.dup_opt_func = 1; } } } if (otn->sigInfo.shared && (otn->ds_list[PLUGIN_DYNAMIC] == NULL)) { /* If still shared... */ ParseWarning("Encoded Rule Plugin SID: %d, GID: %d not " "registered properly. Disabling this rule.\n", otn->sigInfo.id, otn->sigInfo.generator); oneErr = 1; otn->rule_state = RULE_STATE_DISABLED; } } } } } return oneErr; } /**************************************************************************** * * Purpose: Adjust the information for a given rule * relative to the Rule State list * * Arguments: None * * Returns: void function * * Notes: specialGID is depracated, uses sigInfo.shared flag * *****************************************************************************/ void SetRuleStates(SnortConfig *sc) { RuleState *rule_state; #if 0 int oneErr = 0, err; #endif if (sc == NULL) return; /* First, cycle through the rule state list and update the * rule state for each one we find. */ for (rule_state = sc->rule_state_list; rule_state != NULL; rule_state = rule_state->next) { /* Lookup the OTN by ruleState->sid, ruleState->gid */ OptTreeNode *otn = OtnLookup(sc->otn_map, rule_state->gid, rule_state->sid); if (otn == NULL) { ParseError("Rule state specified for invalid SID: %d GID: %d\n", rule_state->sid, rule_state->gid); } otn->rule_state = rule_state->state; } /* Check TCP/UDP/ICMP/IP in one iteration for all rulelists and for all policies*/ #if 1 CheckRuleStates(sc); #else err = CheckRuleStates(sc); if (err) oneErr = 1; if (oneErr) { FatalError("Misconfigured or unregistered encoded rule plugins\n"); } #endif } /**************************************************************************** * * Purpose: Parses a rule state line. * Format is sid, gid, state, action. * state should be "enabled" or "disabled" * action should be "alert", "drop", "sdrop", "log", etc. * * Arguments: args => string containing a single rule state entry * * Returns: void function * *****************************************************************************/ static void ParseRuleState(SnortConfig *sc, SnortPolicy *p, char *args) { char **toks; int num_toks; RuleState *state; char *endptr; if (sc == NULL) return; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"RuleState\n");); toks = mSplit(args, ", ", 0, &num_toks, 0); if (num_toks != 4) ParseError("Config rule_state: Empty state info."); state = (RuleState *)SnortAlloc(sizeof(RuleState)); state->sid = SnortStrtoul(toks[0], &endptr, 0); if ((errno == ERANGE) || (*endptr != '\0')) { ParseError("Invalid sid for rule state: %s. Sid must be between 0 and " "%u inclusive.", args, UINT32_MAX); } state->gid = SnortStrtoul(toks[1], &endptr, 0); if ((errno == ERANGE) || (*endptr != '\0')) { ParseError("Invalid gid for rule state: %s. Gid must be between 0 and " "%u inclusive.", args, UINT32_MAX); } if (strcasecmp(toks[2], RULE_STATE_OPT__DISABLED) == 0) { state->state = RULE_STATE_DISABLED; } else if (strcasecmp(toks[2], RULE_STATE_OPT__ENABLED) == 0) { state->state = RULE_STATE_ENABLED; } else { ParseError("Rule_state: Invalid state - must be either " "'enabled' or 'disabled'."); } state->action = GetRuleType(toks[3]); if (state->action == RULE_TYPE__NONE) { ParseError("Rule_state: Invalid action - must be a valid " "rule type."); } mSplitFree(&toks, num_toks); if (sc->rule_state_list == NULL) { sc->rule_state_list = state; } else { state->next = sc->rule_state_list; sc->rule_state_list = state; } } static void ParseDynamicLibInfo(DynamicLibInfo *dylib_info, char *args) { char getcwd_path[PATH_MAX]; char **toks = NULL; int num_toks = 0; char *path = NULL; PathType ptype = PATH_TYPE__FILE; DynamicLibPath *dylib_path; struct stat buf; if (dylib_info == NULL) return; if (dylib_info->count >= MAX_DYNAMIC_LIBS) { ParseError("Maximum number of loaded libriaries of this dynamic " "library type exceeded: %d.", MAX_DYNAMIC_LIBS); } if (args == NULL) { if (getcwd(getcwd_path, sizeof(getcwd_path)) == NULL) { ParseError("Dynamic library path too long. If you really " "think your path needs to be as long as it is, please " "submit a bug to bugs@snort.org."); } path = getcwd_path; ptype = PATH_TYPE__DIRECTORY; } else { toks = mSplit(args, " \t", 0, &num_toks, 0); if (num_toks == 1) { path = toks[0]; ptype = PATH_TYPE__FILE; } else if (num_toks == 2) { if (strcasecmp(toks[0], DYNAMIC_LIB_OPT__FILE) == 0) { ptype = PATH_TYPE__FILE; } else if (strcasecmp(toks[0], DYNAMIC_LIB_OPT__DIRECTORY) == 0) { ptype = PATH_TYPE__DIRECTORY; } else { ParseError("Invalid specifier for Dynamic library specifier. " "Should be file|directory pathname."); } path = toks[1]; } else { ParseError("Missing/incorrect dynamic engine lib specifier."); } } dylib_path = (DynamicLibPath *)SnortAlloc(sizeof(DynamicLibPath)); dylib_path->ptype = ptype; dylib_path->path = SnortStrdup(path); dylib_info->lib_paths[dylib_info->count] = dylib_path; dylib_info->count++; if (toks != NULL) mSplitFree(&toks, num_toks); if (stat(dylib_path->path, &buf) == -1) { ParseError("Could not stat dynamic module path \"%s\": %s.\n", dylib_path->path, strerror(errno)); } dylib_path->last_mod_time = buf.st_mtime; } /**************************************************************************** * * Purpose: Parses a dynamic engine line * Format is full path of dynamic engine * * Arguments: args => string containing a single dynamic engine * * Returns: void function * *****************************************************************************/ static void ParseDynamicEngineInfo(SnortConfig *sc, SnortPolicy *p, char *args) { if (sc == NULL) return; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"DynamicEngine\n");); if (sc->dyn_engines == NULL) { sc->dyn_engines = (DynamicLibInfo *)SnortAlloc(sizeof(DynamicLibInfo)); sc->dyn_engines->type = DYNAMIC_TYPE__ENGINE; } ParseDynamicLibInfo(sc->dyn_engines, args); } /**************************************************************************** * * Purpose: Parses a dynamic detection lib line * Format is full path of dynamic engine * * Arguments: args => string containing a single dynamic engine * * Returns: void function * *****************************************************************************/ static void ParseDynamicDetectionInfo(SnortConfig *sc, SnortPolicy *p, char *args) { if (sc == NULL) return; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"DynamicDetection\n");); if (sc->dyn_rules == NULL) { sc->dyn_rules = (DynamicLibInfo *)SnortAlloc(sizeof(DynamicLibInfo)); sc->dyn_rules->type = DYNAMIC_TYPE__DETECTION; } ParseDynamicLibInfo(sc->dyn_rules, args); } /**************************************************************************** * * Purpose: Parses a dynamic preprocessor lib line * Format is full path of dynamic engine * * Arguments: args => string containing a single dynamic engine * * Returns: void function * *****************************************************************************/ static void ParseDynamicPreprocessorInfo(SnortConfig *sc, SnortPolicy *p, char *args) { if (sc == NULL) return; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"DynamicPreprocessor\n");); if (sc->dyn_preprocs == NULL) { sc->dyn_preprocs = (DynamicLibInfo *)SnortAlloc(sizeof(DynamicLibInfo)); sc->dyn_preprocs->type = DYNAMIC_TYPE__PREPROCESSOR; } ParseDynamicLibInfo(sc->dyn_preprocs, args); } # ifdef SIDE_CHANNEL /**************************************************************************** * * Purpose: Parses a dynamic side channel lib line * Format is full path of dynamic side channel * * Arguments: args => string containing a single dynamic side channel * * Returns: void function * *****************************************************************************/ static void ParseDynamicSideChannelInfo(SnortConfig *sc, SnortPolicy *p, char *args) { if (sc == NULL) return; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"DynamicSideChannel\n");); if (sc->dyn_side_channels == NULL) { sc->dyn_side_channels = (DynamicLibInfo *)SnortAlloc(sizeof(DynamicLibInfo)); sc->dyn_side_channels->type = DYNAMIC_TYPE__SIDE_CHANNEL; } ParseDynamicLibInfo(sc->dyn_side_channels, args); } # endif /* SIDE_CHANNEL */ /**************************************************************************** * * Purpose: Parses a dynamic output lib line * Format is full path of dynamic output * * Arguments: args => string containing a single dynamic output * * Returns: void function * *****************************************************************************/ static void ParseDynamicOutputInfo(SnortConfig *sc, SnortPolicy *p, char *args) { char **toks = NULL; int num_toks = 0; char *path = NULL; PathType ptype = PATH_TYPE__FILE; if (sc == NULL) return; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"DynamicOutput\n");); if (args == NULL) { char *getcwd_path = SnortAlloc(PATH_MAX); if (getcwd(getcwd_path, PATH_MAX) == NULL) { ParseError("Dynamic library path too long. If you really " "think your path needs to be as long as it is, please " "submit a bug to bugs@snort.org."); } path = getcwd_path; ptype = PATH_TYPE__DIRECTORY; } else { toks = mSplit(args, " \t", 0, &num_toks, 0); if (num_toks == 1) { path = SnortStrdup(toks[0]); ptype = PATH_TYPE__FILE; } else if (num_toks == 2) { if (strcasecmp(toks[0], DYNAMIC_LIB_OPT__FILE) == 0) { ptype = PATH_TYPE__FILE; } else if (strcasecmp(toks[0], DYNAMIC_LIB_OPT__DIRECTORY) == 0) { ptype = PATH_TYPE__DIRECTORY; } else { ParseError("Invalid specifier for Dynamic library specifier. " "Should be file|directory pathname."); } path = SnortStrdup(toks[1]); } else { ParseError("Missing/incorrect dynamic engine lib specifier."); } mSplitFree(&toks, num_toks); } if (ptype == PATH_TYPE__DIRECTORY) output_load(path); else if (ptype == PATH_TYPE__FILE) output_load_module(path); if (path) free(path); } /* verify that we are not reusing some other keyword */ static int ValidateUserDefinedRuleType(SnortConfig *sc, char *keyword) { RuleListNode *node; if ((sc == NULL) || (sc->rule_lists == NULL)) return 0; node = sc->rule_lists; /* This keyword cannot match any of our predefined rule types */ if (GetRuleType(keyword) != RULE_TYPE__NONE) return 0; /* Walk through the rule list to make sure the user didn't already * define this one */ while (node != NULL) { if (strcasecmp(node->name, keyword) == 0) return 0; node = node->next; } return 1; } /* This function does nothing. It is just a place holder in the snort conf * keyword array so the keyword can be matched. Its's a special configuration * case in that multiple non-escaped lines need to be read and the current * file pointer needs to be passed in. */ static void ParseRuleTypeDeclaration(SnortConfig *sc, SnortPolicy *p, char *arg) { return; } static void _ParseRuleTypeDeclaration(SnortConfig *sc, FILE *fp, char *arg, int prules) { char **toks; int num_toks; char *input; char *rule_type_name; RuleType type; int rval = 1; ListHead *listhead = NULL; int got_output = 0; if ((sc == NULL) || (fp == NULL) || (arg == NULL)) return; /* Already parsed this or ignoring for any non-default policy, but need to move past * the rule declaration because it doesn't have continuation characters */ if (prules /* parsing rules */ || (getParserPolicy(sc) != getDefaultPolicy())) { while (1) { input = ReadLine(fp); if (input == NULL) ParseError("Rule type declaration syntax error: %s.", arg); toks = mSplit(input, " \t", 2, &num_toks, 0); /* Just continue for blank line */ if (toks == NULL) continue; /* Got end of rule type */ if ((num_toks == 1) && (strcmp(toks[0], "}") == 0)) { free(input); mSplitFree(&toks, num_toks); break; } free(input); mSplitFree(&toks, num_toks); } return; } DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Rule type declaration\n");); toks = mSplit(arg, " \t", 2, &num_toks, 0); /* Need rule type name for creating new node in rule list */ rule_type_name = SnortStrdup(ExpandVars(sc, toks[0])); /* Verify keyword is unique */ if (!ValidateUserDefinedRuleType(sc, rule_type_name)) { ParseError("Duplicate rule type declaration found: %s.", rule_type_name); } DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Declaring new rule type: %s\n", rule_type_name);); if (num_toks == 2) { /* User put '{' on the same line, which is okay */ if ((toks[1] != NULL) && (strcmp(toks[1], "{") != 0)) { ParseError("Rule type declaration syntax error: %s.", arg); } } else { /* Get next line. It should only be '{' */ input = ReadLine(fp); if ((input == NULL) || (strcmp(input, "{") != 0)) { ParseError("Rule type declaration syntax error: %s.", arg); } free(input); } mSplitFree(&toks, num_toks); input = ReadLine(fp); if (input == NULL) ParseError("Rule type declaration syntax error: %s.", arg); toks = mSplit(input, " \t", 2, &num_toks, 0); if ((num_toks != 2) || (strcasecmp(toks[0], RULE_TYPE_OPT__TYPE) != 0)) { ParseError("Rule type declaration syntax error: %s.", arg); } type = GetRuleType(toks[1]); if (type == RULE_TYPE__NONE) ParseError("Invalid type for rule type declaration: %s.", toks[1]); DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"\ttype(%i): %s\n", type, toks[1]);); if (type == RULE_TYPE__PASS) rval = 0; listhead = CreateRuleType(sc, rule_type_name, type, rval, NULL); free(rule_type_name); free(input); mSplitFree(&toks, num_toks); /* Get output plugin declarations * This will break if '}' is found on the line and fatal error if not and * the line isn't an output configuration */ while (1) { input = ReadLine(fp); if (input == NULL) ParseError("Rule type declaration syntax error: %s.", arg); toks = mSplit(input, " \t", 2, &num_toks, 0); /* Just continue for blank line */ if (toks == NULL) continue; /* Got end of rule type */ if ((num_toks == 1) && (strcmp(toks[0], "}") == 0)) { free(input); mSplitFree(&toks, num_toks); break; } if ((num_toks != 2) || (strcasecmp(toks[0], SNORT_CONF_KEYWORD__OUTPUT) != 0)) { ParseError("Rule type declaration syntax error: %s. This line " "should contain an output declaration.", toks[0]); } ParseRuleTypeOutput(sc, toks[1], listhead); free(input); mSplitFree(&toks, num_toks); got_output = 1; } if (!got_output) ParseError("Rule type declaration requires an output configuration."); sc->num_rule_types++; } /* adapted from ParseRuleFile in rules.c * Returns NULL if the end of file is reached or some other strange file * reading error should occur * Will read lines until it finds one that isn't empty or commented * Returned string, if not NULL, needs to be freed */ char * ReadLine(FILE * file) { char *buf = (char *)SnortAlloc(MAX_LINE_LENGTH + 1); /* Read a line from file and return it. Return NULL for lines that * are comment characters or empty */ while ((fgets(buf, MAX_LINE_LENGTH, file)) != NULL) { int i; char *index; char *ret_line; file_line++; index = buf; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES, "Got line %s (%d): %s\n", file_name, file_line, buf);); /* advance through any whitespace at the beginning of the line */ while (isspace((int)*index)) index++; /* If it's an empty line or starts with a comment character */ if ((strlen(index) == 0) || (*index == '#') || (*index == ';')) continue; /* Trim off any whitespace at the end of the line */ for (i = strlen(index); i > 0; i--) { if (!isspace((int)index[i - 1])) break; } index[i] = '\0'; /* return a copy of the line */ ret_line = SnortStrdup(index); free(buf); return ret_line; } free(buf); return NULL; } /* * Same as VarGet - but this does not Fatal out if a var is not found */ static char * VarSearch(SnortConfig *sc, char *name) { VarEntry *var_table = sc->targeted_policies[getParserPolicy(sc)]->var_table; PortVarTable *portVarTable = sc->targeted_policies[getParserPolicy(sc)]->portVarTable; vartable_t *ip_vartable = sc->targeted_policies[getParserPolicy(sc)]->ip_vartable; sfip_var_t *ipvar; if ((ipvar = sfvt_lookup_var(ip_vartable, name)) != NULL) return ExpandVars(sc, ipvar->value); /* XXX Return a string value */ if (PortVarTableFind(portVarTable, name)) return name; if (var_table != NULL) { VarEntry *p = var_table; do { if(strcasecmp(p->name, name) == 0) return p->value; p = p->next; } while(p != var_table); } return NULL; } /***************************************************************** * Function: GetPcaps() * * This function takes a list of pcap types and arguments from * the command line, parses them depending on type and puts them * in a user supplied queue. The pcap object list will contain * PcapReadObject structures. The returned queue contains * strings representing paths to pcaps. * * returns -1 on error and 0 on success * ****************************************************************/ int GetPcaps(SF_LIST *pol, SF_QUEUE *pcap_queue) { PcapReadObject *pro = NULL; int type = 0; char *arg = NULL; char *filter = NULL; int ret = 0; if ((pol == NULL) || (pcap_queue == NULL)) return -1; for (pro = (PcapReadObject *)sflist_first(pol); pro != NULL; pro = (PcapReadObject *)sflist_next(pol)) { type = pro->type; arg = pro->arg; filter = pro->filter; switch (type) { case PCAP_SINGLE: { char *pcap = NULL; struct stat stat_buf; /* Don't check file if reading from stdin */ if (strcmp(arg, "-") != 0) { /* do a quick check to make sure file exists */ if (stat(arg, &stat_buf) == -1) { ErrorMessage("Error getting stat on pcap file: %s: %s\n", arg, strerror(errno)); return -1; } else if (!(stat_buf.st_mode & (S_IFREG|S_IFIFO))) { ErrorMessage("Specified pcap is not a regular file: %s\n", arg); return -1; } } pcap = SnortStrdup(arg); ret = sfqueue_add(pcap_queue, (NODE_DATA)pcap); if (ret == -1) { ErrorMessage("Could not add pcap to pcap list\n"); free(pcap); return -1; } } break; case PCAP_FILE_LIST: /* arg should be a file with a list of pcaps in it */ { FILE *pcap_file = NULL; char *pcap = NULL; char path_buf[4096]; /* max chars we'll accept for a path */ pcap_file = fopen(arg, "r"); if (pcap_file == NULL) { ErrorMessage("Could not open pcap list file: %s: %s\n", arg, strerror(errno)); return -1; } while (fgets(path_buf, sizeof(path_buf), pcap_file) != NULL) { char *path_buf_ptr, *path_buf_end; struct stat stat_buf; path_buf[sizeof(path_buf) - 1] = '\0'; path_buf_ptr = &path_buf[0]; path_buf_end = path_buf_ptr + strlen(path_buf_ptr); /* move past spaces if any */ while (isspace((int)*path_buf_ptr)) path_buf_ptr++; /* if nothing but spaces on line, continue */ if (*path_buf_ptr == '\0') continue; /* get rid of trailing spaces */ while ((path_buf_end > path_buf_ptr) && (isspace((int)*(path_buf_end - 1)))) path_buf_end--; *path_buf_end = '\0'; /* do a quick check to make sure file exists */ if (stat(path_buf_ptr, &stat_buf) == -1) { ErrorMessage("Error getting stat on pcap file: %s: %s\n", path_buf_ptr, strerror(errno)); fclose(pcap_file); return -1; } #ifndef WIN32 else if (stat_buf.st_mode & S_IFDIR) { ret = GetFilesUnderDir(path_buf_ptr, pcap_queue, filter); if (ret == -1) { ErrorMessage("Error getting pcaps under dir: %s\n", path_buf_ptr); fclose(pcap_file); return -1; } } #endif else if (stat_buf.st_mode & S_IFREG) { #ifndef WIN32 if ((filter == NULL) || (fnmatch(filter, path_buf_ptr, 0) == 0)) { #endif pcap = SnortStrdup(path_buf_ptr); ret = sfqueue_add(pcap_queue, (NODE_DATA)pcap); if (ret == -1) { ErrorMessage("Could not insert pcap into list: %s\n", pcap); free(pcap); fclose(pcap_file); return -1; } #ifndef WIN32 } #endif } else { #ifdef WIN32 ErrorMessage("Specified entry in \'%s\' is not a regular file: %s\n", arg, path_buf_ptr); #else ErrorMessage("Specified entry in \'%s\' is not a regular file or directory: %s\n", arg, path_buf_ptr); #endif fclose(pcap_file); return -1; } } fclose(pcap_file); } break; case PCAP_LIST: /* arg should be a space separated list of pcaps */ { char *tmp = NULL; char *pcap = NULL; struct stat stat_buf; tmp = strtok_r(arg, " ", &arg); if (tmp == NULL) { ErrorMessage("No pcaps specified in pcap list\n"); return -1; } do { /* do a quick check to make sure file exists */ if (stat(tmp, &stat_buf) == -1) { ErrorMessage("Error getting stat on file: %s: %s\n", tmp, strerror(errno)); return -1; } else if (!(stat_buf.st_mode & (S_IFREG|S_IFIFO))) { ErrorMessage("Specified pcap is not a regular file: %s\n", tmp); return -1; } pcap = SnortStrdup(tmp); ret = sfqueue_add(pcap_queue, (NODE_DATA)pcap); if (ret == -1) { ErrorMessage("Could not insert pcap into list: %s\n", pcap); free(pcap); return -1; } } while ((tmp = strtok_r(NULL, " ", &arg)) != NULL); } break; #ifndef WIN32 case PCAP_DIR: /* arg should be a directory name */ ret = GetFilesUnderDir(arg, pcap_queue, filter); if (ret == -1) { ErrorMessage("Error getting pcaps under dir: %s\n", arg); return -1; } break; #endif default: ParseError("Bad read multiple pcaps type\n"); break; } } return 0; } int ValidateIPList(IpAddrSet *addrset, char *token) { if(!addrset || !(addrset->head||addrset->neg_head)) { ParseError("Empty IP used either as source IP or as " "destination IP in a rule. IP list: %s.", token); } return 0; } void ParserCleanup(void) { port_list_free(&port_list); if (ruleIndexMap != NULL) { RuleIndexMapFree(&ruleIndexMap); ruleIndexMap = NULL; } } static void InitVarTables(SnortPolicy *p) { if (p == NULL) return; if (p->var_table != NULL) DeleteVars(p->var_table); p->var_id = 1; if (p->ip_vartable != NULL) sfvt_free_table(p->ip_vartable); p->ip_vartable = sfvt_alloc_table(); if (p->portVarTable != NULL) PortVarTableFree(p->portVarTable); p->portVarTable = PortVarTableCreate(); if (p->nonamePortVarTable != NULL) PortTableFree(p->nonamePortVarTable); p->nonamePortVarTable = PortTableNew(); if ((p->portVarTable == NULL) || (p->nonamePortVarTable == NULL)) { ParseError("Failed to create port variable tables.\n"); } } static void InitPolicyMode(SnortPolicy *p) { if (!ScAdapterInlineMode() && !ScAdapterInlineTestMode()) { p->ips_policy_mode = POLICY_MODE__PASSIVE; p->nap_policy_mode = POLICY_MODE__PASSIVE; } else if (ScAdapterInlineTestMode()) { p->ips_policy_mode = POLICY_MODE__INLINE_TEST; p->nap_policy_mode = POLICY_MODE__INLINE_TEST; } else { p->ips_policy_mode = POLICY_MODE__INLINE; p->nap_policy_mode = POLICY_MODE__INLINE; } } static void InitParser(void) { rule_count = 0; detect_rule_count = 0; decode_rule_count = 0; preproc_rule_count = 0; head_count = 0; otn_count = 0; memset(&tcpCnt, 0, sizeof(tcpCnt)); memset(&udpCnt, 0, sizeof(udpCnt)); memset(&ipCnt, 0, sizeof(ipCnt)); memset(&icmpCnt, 0, sizeof(icmpCnt)); port_list_free(&port_list); memset(&port_list, 0, sizeof(port_list)); port_list.pl_max = MAX_RULE_COUNT; if (ruleIndexMap != NULL) RuleIndexMapFree(&ruleIndexMap); ruleIndexMap = RuleIndexMapCreate(MAX_RULE_COUNT); if (ruleIndexMap == NULL) { ParseError("Failed to create rule index map.\n"); } /* This is for determining if a config option has already been * configured. Most can only be configured once */ memset(config_opt_configured, 0, sizeof(config_opt_configured)); } void ParseRules(SnortConfig *sc) { tSfPolicyId policy_id; if ((sc == NULL) || (snort_conf_file == NULL)) return; file_line = 0; file_name = snort_conf_file; LogMessage("\n"); LogMessage("+++++++++++++++++++++++++++++++++++++++++++++++++++\n"); LogMessage("Initializing rule chains...\n"); /* Global set for parsing a configuration file to tell it whether * we're parsing rules or not - see ParseConfigFile */ parse_rules = 1; /* Set to default policy */ policy_id = sfGetDefaultPolicy(sc->policy_config); setParserPolicy(sc, policy_id); ParseConfigFile(sc, sc->targeted_policies[policy_id], snort_conf_file); /* Parse rules in targeted policies */ for (policy_id = 0; policy_id < sfPolicyNumAllocated(sc->policy_config); policy_id++) { char *fname = sfPolicyGet(sc->policy_config, policy_id); if (policy_id == sfGetDefaultPolicy(sc->policy_config)) continue; if (fname != NULL) { setParserPolicy(sc, policy_id); ParseInclude(sc, sc->targeted_policies[policy_id], fname); } } LogMessage("%d Snort rules read\n", rule_count); LogMessage(" %d detection rules\n", detect_rule_count); LogMessage(" %d decoder rules\n", decode_rule_count); LogMessage(" %d preprocessor rules\n", preproc_rule_count); LogMessage("%d Option Chains linked into %d Chain Headers\n", otn_count, head_count); LogMessage("+++++++++++++++++++++++++++++++++++++++++++++++++++\n"); LogMessage("\n"); #ifdef DEBUG_MSGS DumpRuleChains(sc->rule_lists); #endif IntegrityCheckRules(sc); /*FindMaxSegSize();*/ /* Compile/Finish and Print the PortList Tables */ PortTablesFinish(sc->port_tables, sc->fast_pattern_config); LogMessage("+-------------------[Rule Port Counts]---------------------------------------\n"); LogMessage("|%8s%8s%8s%8s%8s\n", " ", "tcp", "udp", "icmp", "ip"); LogMessage("|%8s%8u%8u%8u%8u\n", "src", tcpCnt.src, udpCnt.src, icmpCnt.src, ipCnt.src); LogMessage("|%8s%8u%8u%8u%8u\n", "dst", tcpCnt.dst, udpCnt.dst, icmpCnt.dst, ipCnt.dst); LogMessage("|%8s%8u%8u%8u%8u\n", "any", tcpCnt.aa, udpCnt.aa, icmpCnt.aa, ipCnt.aa); LogMessage("|%8s%8u%8u%8u%8u\n", "nc", tcpCnt.nc, udpCnt.nc, icmpCnt.nc, ipCnt.nc); LogMessage("|%8s%8u%8u%8u%8u\n", "s+d", tcpCnt.sd, udpCnt.sd, icmpCnt.sd, ipCnt.sd); LogMessage("+----------------------------------------------------------------------------\n"); ///print_rule_index_map( ruleIndexMap ); ///port_list_print( &port_list ); /* Reset these. The only issue in not reseting would be if we were * parsing a command line again, but do it anyway */ file_name = NULL; file_line = 0; } static void ParseInclude(SnortConfig *sc, SnortPolicy *p, char *arg) { struct stat file_stat; /* for include path testing */ /* Save place in previous file */ char *stored_file_name = file_name; int stored_file_line = file_line; /* Including top level snort conf file */ if (strcmp(arg, snort_conf_file) == 0) { ParseError("Cannot include \"%s\" in an include directive.", snort_conf_file); } /* XXX Maybe not allow an include in an included file to avoid * potential recursion issues */ file_line = 0; file_name = SnortStrdup(arg); /* Stat the file. If that fails, stat it relative to the directory * that the top level snort configuration file was in */ if (stat(file_name, &file_stat) == -1) { int path_len = strlen(snort_conf_dir) + strlen(arg) + 1; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"ParseConfigFile: stat " "on %s failed - going to config_dir\n", file_name);); free(file_name); file_name = (char *)SnortAlloc(path_len); snprintf(file_name, path_len, "%s%s", snort_conf_dir, arg); DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"ParseConfigFile: Opening " "and parsing %s\n", file_name);); } ParseConfigFile(sc, p, file_name); free(file_name); file_name = stored_file_name; file_line = stored_file_line; } static void ParseConfigFile(SnortConfig *sc, SnortPolicy *p, char *fname) { /* Used for line continuation */ int continuation = 0; char *saved_line = NULL; char *new_line = NULL; char *buf = (char *)SnortAlloc(MAX_LINE_LENGTH + 1); FILE *fp = fopen(fname, "r"); /* open the rules file */ if (fp == NULL) { ParseError("Unable to open rules file \"%s\": %s.\n", fname, strerror(errno)); } /* loop thru each file line and send it to the rule parser */ while ((fgets(buf, MAX_LINE_LENGTH, fp)) != NULL) { /* buffer indexing pointer */ char *index = buf; /* Increment the line counter so the error messages know which * line to bitch about */ file_line++; /* fgets always appends a null, so doing a strlen should be safe */ if ((strlen(buf) + 1) == MAX_LINE_LENGTH) { ParseError("Line greater than or equal to %u characters which is " "more than the parser is willing to handle. Try " "splitting it up on multiple lines if possible.", MAX_LINE_LENGTH); } DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES, "Got line %s (%d): %s\n", fname, file_line, buf);); /* advance through any whitespace at the beginning of the line */ while (isspace((int)*index)) index++; /* If it's an empty line or starts with a comment character */ if ((strlen(index) == 0) || (*index == '#') || (*index == ';')) continue; if (continuation) { int new_line_len = strlen(saved_line) + strlen(index) + 1; if (new_line_len >= PARSERULE_SIZE) { ParseError("Rule greater than or equal to %u characters which " "is more than the parser is willing to handle. " "Submit a bug to bugs@snort.org if you legitimately " "feel like your rule or keyword configuration needs " "more than this amount of space.", PARSERULE_SIZE); } new_line = (char *)SnortAlloc(new_line_len); snprintf(new_line, new_line_len, "%s%s", saved_line, index); free(saved_line); saved_line = NULL; index = new_line; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"concat rule: %s\n", new_line);); } /* check for a '\' continuation character at the end of the line * if it's there we need to get the next line in the file */ if (ContinuationCheck(index) == 0) { char **toks; int num_toks; char *keyword; char *args; int i; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES, "[*] Processing keyword: %s\n", index);); /* Get the keyword and args */ toks = mSplit(index, " \t", 2, &num_toks, 0); if (num_toks != 2) ParseError("Invalid configuration line: %s", index); keyword = SnortStrdup(ExpandVars(sc, toks[0])); args = toks[1]; for (i = 0; snort_conf_keywords[i].name != NULL; i++) { if (strcasecmp(keyword, snort_conf_keywords[i].name) == 0) { if ((getParserPolicy(sc) != getDefaultPolicy()) && snort_conf_keywords[i].default_policy_only) { /* Keyword only configurable in the default policy*/ DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Config option \"%s\" configurable only by default policy. Ignoring it", toks[0])); break; } if (((snort_conf_keywords[i].type == KEYWORD_TYPE__RULE) && !parse_rules) || ((snort_conf_keywords[i].type == KEYWORD_TYPE__MAIN) && parse_rules)) { break; } if (snort_conf_keywords[i].expand_vars) args = SnortStrdup(ExpandVars(sc, toks[1])); /* Special parsing case is ruletype. * Need to send the file pointer so it can parse what's * between '{' and '}' which can span multiple lines * without a line continuation character */ if (strcasecmp(keyword, SNORT_CONF_KEYWORD__RULE_TYPE) == 0) _ParseRuleTypeDeclaration(sc, fp, args, parse_rules); else snort_conf_keywords[i].parse_func(sc, p, args); break; } } /* Didn't find any pre-defined snort_conf_keywords. Look for a user defined * rule type */ if ((snort_conf_keywords[i].name == NULL) && parse_rules) { RuleListNode *node; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES, "Unknown rule type, " "might be declared\n");); for (node = sc->rule_lists; node != NULL; node = node->next) { if (strcasecmp(node->name, keyword) == 0) break; } if (node == NULL) ParseError("Unknown rule type: %s.", toks[0]); if ( node->mode == RULE_TYPE__DROP ) { if ( ScTreatDropAsAlertNewConf(sc) ) ParseRule(sc, p, args, RULE_TYPE__ALERT, node->RuleList); else if ( ScKeepDropRules(sc) || ScLoadAsDropRules(sc) ) ParseRule(sc, p, args, node->mode, node->RuleList); } else if ( node->mode == RULE_TYPE__SDROP ) { if ( ScKeepDropRules(sc) && !ScTreatDropAsAlertNewConf(sc) ) ParseRule(sc, p, args, node->mode, node->RuleList); else if ( ScLoadAsDropRules(sc) ) ParseRule(sc, p, args, RULE_TYPE__DROP, node->RuleList); } else { ParseRule(sc, p, args, node->mode, node->RuleList); } } if (args != toks[1]) free(args); free(keyword); mSplitFree(&toks, num_toks); if(new_line != NULL) { free(new_line); new_line = NULL; continuation = 0; } } else { /* save the current line */ saved_line = SnortStrdup(index); /* current line was a continuation itself... */ if (new_line != NULL) { free(new_line); new_line = NULL; } /* set the flag to let us know the next line is * a continuation line */ continuation = 1; } } fclose(fp); free(buf); } static int ContinuationCheck(char *rule) { char *idx; /* indexing var for moving around on the string */ idx = rule + strlen(rule) - 1; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"initial idx set to \'%c\'\n", *idx);); while(isspace((int)*idx)) { idx--; } if(*idx == '\\') { DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Got continuation char, " "clearing char and returning 1\n");); /* clear the '\' so there isn't a problem on the appended string */ *idx = '\x0'; return 1; } return 0; } void ConfigAlertBeforePass(SnortConfig *sc, char *args) { if (sc == NULL) return; sc->run_flags |= RUN_FLAG__ALERT_BEFORE_PASS; } void ConfigAlertFile(SnortConfig *sc, char *args) { if ((args == NULL) || (sc == NULL) || (sc->alert_file != NULL)) return; sc->alert_file = SnortStrdup(args); DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"alertfile set to: %s\n", sc->alert_file);); } void ConfigAlertWithInterfaceName(SnortConfig *sc, char *args) { if (sc == NULL) return; sc->output_flags |= OUTPUT_FLAG__ALERT_IFACE; } void ConfigAsn1(SnortConfig *sc, char *args) { long int num_nodes; char *endptr; if ((sc == NULL) || (args == NULL)) return; num_nodes = SnortStrtol(args, &endptr, 0); if ((errno == ERANGE) || (*endptr != '\0') || (num_nodes <= 0)) { ParseError("Invalid argument to 'asn1' configuration. " "Must be a positive integer."); } sc->asn1_mem = num_nodes; } void ConfigAutogenPreprocDecoderRules(SnortConfig *sc, char *args) { SnortPolicy* policy; if (sc == NULL) return; /* config autogenerate_preprocessor_decoder_rules */ UpdateDecodeRulesArray(0, ENABLE_RULE, ENABLE_ALL_RULES); policy = sc->targeted_policies[getParserPolicy(sc)]; policy->policy_flags |= POLICY_FLAG__AUTO_OTN; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Autogenerating Preprocessor and Decoder OTNs\n");); } void ConfigBinding(SnortConfig *sc, char *args) { int num_toks; int num_toks1; char **toks; char **toks1; char *fileName; int bindingType; toks1 = mSplit(args, " \t", 3, &num_toks1, 0); if(num_toks1 < 3) { mSplitFree(&toks1, num_toks1); ParseError("Need at least two arguments to 'config binding'"); return; } if (!strcmp("policy_id", toks1[1])) { bindingType = SF_BINDING_TYPE_POLICY_ID; } #ifndef POLICY_BY_ID_ONLY else if (!strcmp("vlan", toks1[1])) { bindingType = SF_BINDING_TYPE_VLAN; } else if (!strcmp("net", toks1[1])) { bindingType = SF_BINDING_TYPE_NETWORK; } #endif else { mSplitFree(&toks1, num_toks1); ParseError("Invalid binding type in 'config binding'"); return; } fileName = toks1[0]; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES, "Policy File: %s\n", fileName);); #define MAX_BOUND_ADDRS_PER_LINE 512 toks = mSplit(toks1[2], ",", MAX_BOUND_ADDRS_PER_LINE + 1, &num_toks, 0); if (num_toks < 1) { mSplitFree(&toks1, num_toks1); mSplitFree(&toks, num_toks); ParseError(" Invalid arguments to 'config binding'"); return; } if (num_toks >= 512) { mSplitFree(&toks1, num_toks1); mSplitFree(&toks, num_toks); ParseError(" Too many network addresses specified in 'config binding'. " " Maximum is %d.\n", MAX_BOUND_ADDRS_PER_LINE); return; } if (bindingType == SF_BINDING_TYPE_POLICY_ID) { if (ParsePolicyIdBindingLine(sc->policy_config, num_toks, &toks[0], fileName)) { FatalError("%s(%d) Formatting error in binding config for %s\n", file_name, file_line, fileName); } } else if (bindingType == SF_BINDING_TYPE_VLAN) { if (ParseVlanBindingLine(sc->policy_config, num_toks, &toks[0], fileName)) { FatalError("%s(%d) Formatting error in binding config for %s\n", file_name, file_line, fileName); } } else { if (ParseNetworkBindingLine(sc->policy_config, num_toks, &toks[0], fileName)) { FatalError("%s(%d) Formatting error in binding config for %s\n", file_name, file_line, fileName); } } mSplitFree(&toks1, num_toks1); mSplitFree(&toks, num_toks); } void ConfigBpfFile(SnortConfig *sc, char *args) { if ((args == NULL) || (sc == NULL) || (sc->bpf_file != NULL)) return; sc->bpf_file = SnortStrdup(args); } void ConfigChecksumDrop(SnortConfig *sc, char *args) { if (sc == NULL) return; if (sc->targeted_policies == NULL) { //This is the case for command line argument sc->checksum_drop_flags = GetChecksumFlags(args); sc->checksum_drop_flags_modified = 1; } else { SnortPolicy *pPolicy = sc->targeted_policies[getParserPolicy(sc)]; pPolicy->checksum_drop_flags = GetChecksumFlags(args); pPolicy->checksum_drop_flags_modified = 1; } } void ConfigChecksumMode(SnortConfig *sc, char *args) { if (sc == NULL) return; if (sc->targeted_policies == NULL) { //This is the case for command line argument sc->checksum_flags = GetChecksumFlags(args); sc->checksum_flags_modified = 1; } else { SnortPolicy *pPolicy = sc->targeted_policies[getParserPolicy(sc)]; pPolicy->checksum_flags = GetChecksumFlags(args); pPolicy->checksum_flags_modified = 1; } } static int GetChecksumFlags(char *args) { char **toks; int num_toks; int i; int negative_flags = 0; int positive_flags = 0; int got_positive_flag = 0; int got_negative_flag = 0; int ret_flags = 0; if (args == NULL) return CHECKSUM_FLAG__ALL; toks = mSplit(args, " \t", 10, &num_toks, 0); for (i = 0; i < num_toks; i++) { if (strcasecmp(toks[i], CHECKSUM_MODE_OPT__ALL) == 0) { positive_flags = CHECKSUM_FLAG__ALL; negative_flags = 0; got_positive_flag = 1; } else if (strcasecmp(toks[i], CHECKSUM_MODE_OPT__NONE) == 0) { positive_flags = 0; negative_flags = CHECKSUM_FLAG__ALL; got_negative_flag = 1; } else if (strcasecmp(toks[i], CHECKSUM_MODE_OPT__IP) == 0) { positive_flags |= CHECKSUM_FLAG__IP; negative_flags &= ~CHECKSUM_FLAG__IP; got_positive_flag = 1; } else if (strcasecmp(toks[i], CHECKSUM_MODE_OPT__NO_IP) == 0) { positive_flags &= ~CHECKSUM_FLAG__IP; negative_flags |= CHECKSUM_FLAG__IP; got_negative_flag = 1; } else if (strcasecmp(toks[i], CHECKSUM_MODE_OPT__TCP) == 0) { positive_flags |= CHECKSUM_FLAG__TCP; negative_flags &= ~CHECKSUM_FLAG__TCP; got_positive_flag = 1; } else if (strcasecmp(toks[i], CHECKSUM_MODE_OPT__NO_TCP) == 0) { positive_flags &= ~CHECKSUM_FLAG__TCP; negative_flags |= CHECKSUM_FLAG__TCP; got_negative_flag = 1; } else if (strcasecmp(toks[i], CHECKSUM_MODE_OPT__UDP) == 0) { positive_flags |= CHECKSUM_FLAG__UDP; negative_flags &= ~CHECKSUM_FLAG__UDP; got_positive_flag = 1; } else if (strcasecmp(toks[i], CHECKSUM_MODE_OPT__NO_UDP) == 0) { positive_flags &= ~CHECKSUM_FLAG__UDP; negative_flags |= CHECKSUM_FLAG__UDP; got_negative_flag = 1; } else if (strcasecmp(toks[i], CHECKSUM_MODE_OPT__ICMP) == 0) { positive_flags |= CHECKSUM_FLAG__ICMP; negative_flags &= ~CHECKSUM_FLAG__ICMP; got_positive_flag = 1; } else if (strcasecmp(toks[i], CHECKSUM_MODE_OPT__NO_ICMP) == 0) { positive_flags &= ~CHECKSUM_FLAG__ICMP; negative_flags |= CHECKSUM_FLAG__ICMP; got_negative_flag = 1; } else { ParseError("Unknown command line checksum option: %s.", toks[i]); } } /* Invert the negative flags with all checksums */ negative_flags ^= CHECKSUM_FLAG__ALL; negative_flags &= CHECKSUM_FLAG__ALL; if (got_positive_flag && got_negative_flag) { /* If we got both positive and negative flags just take the * combination of the two */ ret_flags = positive_flags & negative_flags; } else if (got_positive_flag) { /* If we got a positive flag assume the user wants checksums * to be cleared */ ret_flags = positive_flags; } else /* got a negative flag */ { /* If we got a negative flag assume the user thinks all * checksums are on */ ret_flags = negative_flags; } mSplitFree(&toks, num_toks); return ret_flags; } void ConfigChrootDir(SnortConfig *sc, char *args) { #ifdef WIN32 ParseError("Setting the chroot directory is not supported in " "the WIN32 port of snort!"); #else if ((args == NULL) || (sc == NULL) || (sc->chroot_dir != NULL)) return; sc->chroot_dir = SnortStrdup(args); #endif } void ConfigClassification(SnortConfig *sc, char *args) { char **toks; int num_toks; char *endptr; ClassType *new_node, *current; int max_id = 0; if ((args == NULL) || (sc == NULL)) return; toks = mSplit(args, ",", 0, &num_toks, '\\'); if (num_toks != 3) ParseError("Invalid classification config: %s.", args); /* create the new node */ new_node = (ClassType *)SnortAlloc(sizeof(ClassType)); new_node->type = SnortStrdup(toks[0]); new_node->name = SnortStrdup(toks[1]); new_node->priority = SnortStrtol(toks[2], &endptr, 0); if ((errno == ERANGE) || (*endptr != '\0') || (new_node->priority <= 0)) { ParseError("Invalid argument for classification priority " "configuration: %s. Must be a positive integer.", toks[2]); } current = sc->classifications; while (current != NULL) { /* dup check */ if (strcasecmp(current->type, new_node->type) == 0) { if (getParserPolicy(sc) == getDefaultPolicy()) { ParseWarning("Duplicate classification \"%s\"" "found, ignoring this line\n", new_node->type); } break; } if (current->id > max_id) max_id = current->id; current = current->next; } /* Got a dup */ if (current != NULL) { free(new_node->name); free(new_node->type); free(new_node); mSplitFree(&toks, num_toks); return; } /* insert node */ new_node->id = max_id + 1; new_node->next = sc->classifications; sc->classifications = new_node; mSplitFree(&toks, num_toks); } void ConfigCreatePidFile(SnortConfig *sc, char *args) { if (sc == NULL) return; sc->run_flags |= RUN_FLAG__CREATE_PID_FILE; } void ConfigDaemon(SnortConfig *sc, char *args) { #ifdef WIN32 ParseError("Setting the Daemon mode is not supported in the " "WIN32 port of snort! Use 'snort /SERVICE ...' instead."); #else if (sc == NULL) return; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Daemon mode flag set\n");); sc->run_flags |= RUN_FLAG__DAEMON; sc->logging_flags |= LOGGING_FLAG__QUIET; #endif } void ConfigDecodeDataLink(SnortConfig *sc, char *args) { if (sc == NULL) return; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Decode DLL set\n");); sc->output_flags |= OUTPUT_FLAG__SHOW_DATA_LINK; } void ConfigDefaultRuleState(SnortConfig *sc, char *args) { if (sc == NULL) return; LogMessage("Found rule_state config directive\n"); if (args == NULL) { sc->default_rule_state = RULE_STATE_ENABLED; } else if (strcasecmp(args, RULE_STATE_OPT__DISABLED) == 0) { sc->default_rule_state = RULE_STATE_DISABLED; } else { /* Any other word and just call it enabled */ sc->default_rule_state = RULE_STATE_ENABLED; } } void ConfigDetection(SnortConfig *sc, char *args) { int i; char **toks; int num_toks; FastPatternConfig *fp; int old_stream_inserts = -1; int old_max_queue_events = -1; if ((sc == NULL) || (args == NULL)) return; fp = sc->fast_pattern_config; if (fp->configured) { ParseWarning("Reconfiguring detection options."); /* Save max queue events and stream inserts in case they are * not configured again - these will carry over into the new * configuration */ old_max_queue_events = fp->max_queue_events; old_stream_inserts = fp->inspect_stream_insert; fpSetDefaults(fp); } toks = mSplit(args, ", ", 20, &num_toks, 0); for (i = 0; i < num_toks; i++) { if (strcasecmp(toks[i], DETECTION_OPT__SEARCH_OPTIMIZE) == 0) { fpSetDetectSearchOpt(fp, 1); } else if (strcasecmp(toks[i], DETECTION_OPT__ENABLE_SINGLE_RULE_GROUP) == 0) { fpDetectSetSingleRuleGroup(fp); LogMessage("Using Single-Rule-Group Detection\n"); } else if (strcasecmp(toks[i], DETECTION_OPT__DEBUG_PRINT_NOCONTENT_RULE_TESTS) == 0) { fpDetectSetDebugPrintNcRules(fp); } else if (strcasecmp(toks[i], DETECTION_OPT__DEBUG_PRINT_RULE_GROUP_BUILD_DETAILS) == 0) { fpDetectSetDebugPrintRuleGroupBuildDetails(fp); } else if (strcasecmp(toks[i], DETECTION_OPT__DEBUG_PRINT_RULE_GROUPS_UNCOMPILED) == 0) { fpDetectSetDebugPrintRuleGroupsUnCompiled(fp); } else if (strcasecmp(toks[i], DETECTION_OPT__DEBUG_PRINT_RULE_GROUPS_COMPILED) == 0) { fpDetectSetDebugPrintRuleGroupsCompiled(fp); } else if (strcasecmp(toks[i], DETECTION_OPT__DEBUG) == 0) { fpSetDebugMode(fp); } else if (strcasecmp(toks[i], DETECTION_OPT__NO_STREAM_INSERTS) == 0) { fpSetStreamInsert(fp); old_stream_inserts = -1; /* Don't reset to old value */ } else if (strcasecmp(toks[i], DETECTION_OPT__BLEEDOVER_WARNINGS_ENABLED) == 0) { fpDetectSetBleedOverWarnings(fp); } else if (strcasecmp(toks[i], DETECTION_OPT__SEARCH_METHOD) == 0) { i++; if (i < num_toks) { if (fpSetDetectSearchMethod(fp, toks[i]) == -1) { ParseError("Invalid argument to 'search-method': %s.", toks[i]); } } else { ParseError("Need an argument to 'search-method'."); } } else if (strcasecmp(toks[i], DETECTION_OPT__BLEEDOVER_PORT_LIMIT) == 0) { i++; if (i < num_toks) { char *endptr; int n = SnortStrtol(toks[i], &endptr, 0); if ((errno == ERANGE) || (*endptr != '\0') || (n <= 0)) { ParseError("Invalid argument for bleedover limit: %s. " "Need a non-negative integer.", toks[i]); } fpDetectSetBleedOverPortLimit(fp, n); LogMessage("Bleedover Port Limit : %d\n",n); } else { ParseError("Missing port-count argument to 'bleedover_port_limit'."); } } else if (strcasecmp(toks[i], DETECTION_OPT__MAX_QUEUE_EVENTS) == 0) { i++; if (i < num_toks) { char *endptr; int n = SnortStrtol(toks[i], &endptr, 0); if ((errno == ERANGE) || (*endptr != '\0') || (n <= 0)) { ParseError("Invalid argument for max_queue_events: %s. " "Need a non-negative integer.", toks[i]); } fpSetMaxQueueEvents(fp, n); old_max_queue_events = -1; /* Don't reset to old value */ } else { ParseError("Missing argument to 'max_queue_events'."); } } else if (strcasecmp(toks[i], DETECTION_OPT__SPLIT_ANY_ANY) == 0) { fpDetectSetSplitAnyAny(fp, 1); } else if (strcasecmp(toks[i], DETECTION_OPT__MAX_PATTERN_LEN) == 0) { i++; if (i < num_toks) { char *endptr; int n = SnortStrtol(toks[i], &endptr, 0); if ((errno == ERANGE) || (*endptr != '\0') || (n < 0)) { ParseError("Invalid argument for max-pattern-len: %s. " "Need a non-negative integer.", toks[i]); } fpSetMaxPatternLen(fp, n); } else { ParseError("Missing argument to 'max-pattern-len'."); } } else if (strcasecmp(toks[i], DETECTION_OPT__DEBUG_PRINT_FAST_PATTERN) == 0) { fpDetectSetDebugPrintFastPatterns(fp, 1); } else { ParseError("'%s' is an invalid option to the 'config detection' " "configuration.", toks[i]); } } mSplitFree(&toks, num_toks); if (old_max_queue_events != -1) fp->max_queue_events = old_max_queue_events; if (old_stream_inserts != -1) fp->inspect_stream_insert = old_stream_inserts; fp->configured = 1; } void ConfigDetectionFilter(SnortConfig *sc, char *args) { char **toks; int num_toks; if ((sc == NULL) || (args == NULL)) return; if (!sc->detection_filter_config->enabled) return; toks = mSplit(args, " \t", 2, &num_toks, 0); if (num_toks != 2) { ParseError("Detection filter memcap requires a positive " "integer argument."); } if (strcasecmp(toks[0], THRESHOLD_OPT__MEMCAP) == 0) { char *endptr; sc->detection_filter_config->memcap = SnortStrtol(toks[1], &endptr, 0); if ((errno == ERANGE) || (*endptr != '\0') || (sc->detection_filter_config->memcap < 0)) { ParseError("Invalid detection filter memcap: %s. Must be a " "positive integer.", toks[1]); } } else { ParseError("Unknown argument to threshold configuration: %s.", toks[0]); } mSplitFree(&toks, num_toks); } void ConfigDisableDecodeAlerts(SnortConfig *sc, char *args) { if (sc == NULL) return; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "disabling the decoder alerts\n");); sc->targeted_policies[getParserPolicy(sc)]->decoder_alert_flags &= ~DECODE_EVENT_FLAG__DEFAULT; } void ConfigDisableDecodeDrops(SnortConfig *sc, char *args) { if (sc == NULL) return; /* OBSOLETE -- default is disabled */ DEBUG_WRAP(DebugMessage(DEBUG_INIT, "disabling the drop of decoder alerts\n");); sc->targeted_policies[getParserPolicy(sc)]->decoder_drop_flags &= ~DECODE_EVENT_FLAG__DEFAULT; } #ifdef INLINE_FAILOPEN void ConfigDisableInlineFailopen(SnortConfig *sc, char *args) { if (sc == NULL) return; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Inline Init Failopen disabled\n");); sc->run_flags |= RUN_FLAG__DISABLE_FAILOPEN; } #endif void ConfigDisableIpOptAlerts(SnortConfig *sc, char *args) { if (sc == NULL) return; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "disabling the alert of all the ipopt alerts\n");); sc->targeted_policies[getParserPolicy(sc)]->decoder_alert_flags &= ~DECODE_EVENT_FLAG__IP_OPT_ANOMALY; } void ConfigDisableIpOptDrops(SnortConfig *sc, char *args) { if (sc == NULL) return; /* OBSOLETE -- default is disabled */ DEBUG_WRAP(DebugMessage(DEBUG_INIT, "disabling the drop of all the ipopt alerts\n");); sc->targeted_policies[getParserPolicy(sc)]->decoder_drop_flags &= ~DECODE_EVENT_FLAG__IP_OPT_ANOMALY; } void ConfigDisableTcpOptAlerts(SnortConfig *sc, char *args) { if (sc == NULL) return; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "disabling the all the other tcpopt alerts\n");); sc->targeted_policies[getParserPolicy(sc)]->decoder_alert_flags &= ~DECODE_EVENT_FLAG__TCP_OPT_ANOMALY; } void ConfigDisableTcpOptDrops(SnortConfig *sc, char *args) { if (sc == NULL) return; /* OBSOLETE -- default is disabled */ DEBUG_WRAP(DebugMessage(DEBUG_INIT, "disabling the drop of all other tcpopt alerts\n");); sc->targeted_policies[getParserPolicy(sc)]->decoder_drop_flags &= ~DECODE_EVENT_FLAG__TCP_OPT_ANOMALY; } void ConfigDisableTcpOptExperimentalAlerts(SnortConfig *sc, char *args) { if (sc == NULL) return; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "disabling the tcpopt experimental alerts\n");); sc->targeted_policies[getParserPolicy(sc)]->decoder_alert_flags &= ~DECODE_EVENT_FLAG__TCP_EXP_OPT; } void ConfigDisableTcpOptExperimentalDrops(SnortConfig *sc, char *args) { if (sc == NULL) return; /* OBSOLETE -- default is disabled */ DEBUG_WRAP(DebugMessage(DEBUG_INIT, "disabling the drop of tcpopt exprimental alerts\n");); sc->targeted_policies[getParserPolicy(sc)]->decoder_drop_flags &= ~DECODE_EVENT_FLAG__TCP_EXP_OPT; } void ConfigDisableTcpOptObsoleteAlerts(SnortConfig *sc, char *args) { if (sc == NULL) return; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "disabling the tcpopt obsolete alerts\n");); sc->targeted_policies[getParserPolicy(sc)]->decoder_alert_flags &= ~DECODE_EVENT_FLAG__TCP_OBS_OPT; } void ConfigDisableTcpOptObsoleteDrops(SnortConfig *sc, char *args) { if (sc == NULL) return; /* OBSOLETE -- default is disabled */ DEBUG_WRAP(DebugMessage(DEBUG_INIT, "disabling the drop of tcpopt obsolete alerts\n");); sc->targeted_policies[getParserPolicy(sc)]->decoder_drop_flags &= ~DECODE_EVENT_FLAG__TCP_OBS_OPT; } void ConfigDisableTTcpAlerts(SnortConfig *sc, char *args) { if (sc == NULL) return; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "disabling the ttcp alerts\n");); sc->targeted_policies[getParserPolicy(sc)]->decoder_alert_flags &= ~DECODE_EVENT_FLAG__TCP_TTCP_OPT; } void ConfigDisableTTcpDrops(SnortConfig *sc, char *args) { if (sc == NULL) return; /* OBSOLETE -- default is disabled */ DEBUG_WRAP(DebugMessage(DEBUG_INIT, "disabling the drop of ttcp alerts\n");); sc->targeted_policies[getParserPolicy(sc)]->decoder_drop_flags &= ~DECODE_EVENT_FLAG__TCP_TTCP_OPT; } void ConfigDumpCharsOnly(SnortConfig *sc, char *args) { if (sc == NULL) return; /* dump the application layer as text only */ DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Character payload dump set\n");); sc->output_flags |= OUTPUT_FLAG__CHAR_DATA; } void ConfigDumpPayload(SnortConfig *sc, char *args) { if (sc == NULL) return; /* dump the application layer */ DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Payload dump set\n");); sc->output_flags |= OUTPUT_FLAG__APP_DATA; } void ConfigDumpPayloadVerbose(SnortConfig *sc, char *args) { if (sc == NULL) return; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Verbose packet bytecode dumps enabled\n");); sc->output_flags |= OUTPUT_FLAG__VERBOSE_DUMP; } void ConfigEnableDecodeDrops(SnortConfig *sc, char *args) { if (sc == NULL) return; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Enabling the drop of decoder alerts\n");); sc->targeted_policies[getParserPolicy(sc)]->decoder_drop_flags |= DECODE_EVENT_FLAG__DEFAULT; } void ConfigEnableDecodeOversizedAlerts(SnortConfig *sc, char *args) { if (sc == NULL) return; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Enabling the decoder oversized packet alerts\n");); sc->targeted_policies[getParserPolicy(sc)]->decoder_alert_flags |= DECODE_EVENT_FLAG__OVERSIZED; } void ConfigEnableDecodeOversizedDrops(SnortConfig *sc, char *args) { if (sc == NULL) return; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Enabling the drop of decoder oversized packets\n");); sc->targeted_policies[getParserPolicy(sc)]->decoder_drop_flags |= DECODE_EVENT_FLAG__OVERSIZED; } void ConfigEnableDeepTeredoInspection(SnortConfig *sc, char *args) { if (sc == NULL) return; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Enabling deep Teredo inspection\n");); sc->enable_teredo = 1; /* TODO: add this to some existing flag bitfield? */ } #define GTP_U_PORT 2152 #define GTP_U_PORT_V0 3386 void ConfigEnableGTPDecoding(SnortConfig *sc, char *args) { PortObject *portObject; int numberOfPorts = 0; if (sc == NULL) return; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Enabling GTP decoding\n");); sc->enable_gtp = 1; /*Set the ports*/ portObject = PortVarTableFind( sc->targeted_policies[getParserPolicy(sc)]->portVarTable, "GTP_PORTS"); if (portObject) { sc->gtp_ports = PortObjectCharPortArray(sc->gtp_ports,portObject, &numberOfPorts); } if (!sc->gtp_ports || (0 == numberOfPorts)) { /*No ports defined, use default GTP ports*/ sc->gtp_ports = (char *)SnortAlloc(UINT16_MAX); sc->gtp_ports[GTP_U_PORT] = 1; sc->gtp_ports[GTP_U_PORT_V0] = 1; } } void ConfigEnableEspDecoding(SnortConfig *sc, char *args) { int ret; if (sc == NULL) return; if (args) { ret = ParseBool(args); if (ret == -1) { ParseError("Invalid argument to ESP decoder argument: %s\n" "Please specify \"enable\" or \"disable\".", args); } sc->enable_esp = ret; } DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Changing ESP decoding\n");); } void ConfigEnableIpOptDrops(SnortConfig *sc, char *args) { if (sc == NULL) return; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "disabling the drop of all the ipopt alerts\n");); sc->targeted_policies[getParserPolicy(sc)]->decoder_drop_flags |= DECODE_EVENT_FLAG__IP_OPT_ANOMALY; } #ifdef MPLS void ConfigEnableMplsMulticast(SnortConfig *sc, char *args) { if (sc == NULL) return; sc->run_flags |= RUN_FLAG__MPLS_MULTICAST; } void ConfigEnableMplsOverlappingIp(SnortConfig *sc, char *args) { if (sc == NULL) return; sc->run_flags |= RUN_FLAG__MPLS_OVERLAPPING_IP; } #endif void ConfigEnableTcpOptDrops(SnortConfig *sc, char *args) { if (sc == NULL) return; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "disabling the drop of all other tcpopt alerts\n");); sc->targeted_policies[getParserPolicy(sc)]->decoder_drop_flags |= DECODE_EVENT_FLAG__TCP_OPT_ANOMALY; } void ConfigEnableTcpOptExperimentalDrops(SnortConfig *sc, char *args) { if (sc == NULL) return; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "enabling the drop of tcpopt exprimental alerts\n");); sc->targeted_policies[getParserPolicy(sc)]->decoder_drop_flags |= DECODE_EVENT_FLAG__TCP_EXP_OPT; } void ConfigEnableTcpOptObsoleteDrops(SnortConfig *sc, char *args) { if (sc == NULL) return; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "disabling the drop of tcpopt obsolete alerts\n");); sc->targeted_policies[getParserPolicy(sc)]->decoder_drop_flags |= DECODE_EVENT_FLAG__TCP_OBS_OPT; } void ConfigEnableTTcpDrops(SnortConfig *sc, char *args) { if (sc == NULL) return; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "disabling the drop of ttcp alerts\n");); sc->targeted_policies[getParserPolicy(sc)]->decoder_drop_flags &= ~DECODE_EVENT_FLAG__TCP_TTCP_OPT; } void ConfigEventFilter(SnortConfig *sc, char *args) { char **toks; int num_toks; if ((sc == NULL) || (args == NULL)) return; if (!sc->threshold_config->enabled) return; toks = mSplit(args, " \t", 2, &num_toks, 0); if (num_toks != 2) { ParseError("Threshold memcap requires a positive integer argument."); } if (strcasecmp(toks[0], THRESHOLD_OPT__MEMCAP) == 0) { char *endptr; sc->threshold_config->memcap = SnortStrtol(toks[1], &endptr, 0); if ((errno == ERANGE) || (*endptr != '\0') || (sc->threshold_config->memcap < 0)) { ParseError("Invalid threshold memcap: %s. Must be a " "positive integer.", toks[1]); } } else { ParseError("Unknown argument to threshold configuration: %s.", toks[0]); } mSplitFree(&toks, num_toks); } void ConfigEventQueue(SnortConfig *sc, char *args) { char **toks; int num_toks; int i; EventQueueConfig *eq; if ((sc == NULL) || (args == NULL)) return; eq = sc->event_queue_config; toks = mSplit(args, ", ", 0, &num_toks, 0); for (i = 0; i < num_toks; i++) { if (strcasecmp(toks[i], EVENT_QUEUE_OPT__MAX_QUEUE) == 0) { i++; if (i < num_toks) { char *endptr; eq->max_events = SnortStrtol(toks[i], &endptr, 0); if ((errno == ERANGE) || (*endptr != '\0') || (eq->max_events <= 0)) { ParseError("Invalid argument for max_queue: %s. Must " "be a positive integer.", toks[i]); } } else { ParseError("No argument to 'max_queue'. Argument must " "be a positive integer."); } } else if (strcasecmp(toks[i], EVENT_QUEUE_OPT__LOG) == 0) { i++; if (i < num_toks) { char *endptr; eq->log_events = SnortStrtol(toks[i], &endptr, 0); if ((errno == ERANGE) || (*endptr != '\0') || (eq->log_events <= 0)) { ParseError("Invalid argument for 'log': %s. Must be " "a positive integer.", toks[i]); } } else { ParseError("No argument to 'log'. Argument must be a " "positive integer."); } } else if (strcasecmp(toks[i], EVENT_QUEUE_OPT__ORDER_EVENTS) == 0) { i++; if(i < num_toks) { if (strcasecmp(toks[i], ORDER_EVENTS_OPT__PRIORITY) == 0) { eq->order = SNORT_EVENTQ_PRIORITY; } else if (strcasecmp(toks[i], ORDER_EVENTS_OPT__CONTENT_LENGTH) == 0) { eq->order = SNORT_EVENTQ_CONTENT_LEN; } else { ParseError("Invalid argument to 'order_events': %s. " "Arguments may be either 'priority' or " "content_length.", toks[i]); } } else { ParseError("No argument to 'order_events'. Arguments may be " "either 'priority' or content_length."); } } else if (strcasecmp(toks[i], EVENT_QUEUE_OPT__PROCESS_ALL_EVENTS) == 0) { eq->process_all_events = 1; } else { ParseError("Invalid argument to 'event_queue'. To configure " "event_queue, the options 'max_queue', 'log', and " "'order_events' must be configured."); } } if (eq->max_events < eq->log_events ) eq->max_events = eq->log_events; mSplitFree(&toks, num_toks); } void ConfigEventTrace(SnortConfig *sc, char *args) { char **toks; int num_toks = 0; int i; if ( !sc ) return; sc->event_trace_file = EVENT_TRACE_OPT__FILE_DEFAULT; sc->event_trace_max = EVENT_TRACE_OPT__MAX_DATA_DEFAULT; if ( args ) toks = mSplit(args, ", ", 0, &num_toks, 0); for (i = 0; i < num_toks; i++) { if (strcasecmp(toks[i], EVENT_TRACE_OPT__MAX_DATA) == 0) { i++; if (i < num_toks) { char* endptr; long max = SnortStrtol(toks[i], &endptr, 0); if ( (errno == ERANGE) || (*endptr != '\0') || (max <= 0) || (max > 65535) ) { ParseError("Invalid argument for %s: %s. Must be a positive " "integer < 65536.", EVENT_TRACE_OPT__MAX_DATA, toks[i]); } sc->event_trace_max = (uint16_t)max; } else { ParseError("No argument to %s. Argument must be a positive " "integer < 65536.", EVENT_TRACE_OPT__MAX_DATA); } } else if (strcasecmp(toks[i], EVENT_TRACE_OPT__FILE) == 0) { i++; if(i < num_toks) sc->event_trace_file = toks[i]; else { ParseError("No argument to %s. Argument must be a string." EVENT_TRACE_OPT__FILE); } } else { ParseError("Invalid argument to 'event_trace'. To configure " "event_trace, only the options 'file' and 'max_data' can " "can be specified. Defaults are %s and %d.", EVENT_TRACE_OPT__FILE_DEFAULT, EVENT_TRACE_OPT__MAX_DATA_DEFAULT); } } sc->event_trace_file = SnortStrdup(sc->event_trace_file); mSplitFree(&toks, num_toks); } void ConfigReact (SnortConfig *sc, char *args) { if ((sc == NULL) || (args == NULL)) return; sc->react_page = SnortStrdup(args); DEBUG_WRAP(DebugMessage(DEBUG_INIT, "react: page is %s\n", sc->react_page);); } #ifdef ENABLE_RESPONSE3 void ConfigFlexresp2Interface(SnortConfig *sc, char *args) { ParseWarning("flexresp2_interface is no longer supported.\n"); } void ConfigFlexresp2Attempts(SnortConfig *sc, char *args) { ParseWarning("flexresp2_attempts is no longer supported; " "you must use config response: attempts <#> instead.\n"); } void ConfigFlexresp2Memcap(SnortConfig *sc, char *args) { ParseWarning("flexresp2_memcap is no longer supported.\n"); } void ConfigFlexresp2Rows(SnortConfig *sc, char *args) { ParseWarning("flexresp2_rows is no longer supported.\n"); } #endif #ifdef ACTIVE_RESPONSE // TBD: once code can be checked in, move all config funcs // from parser.[ch] to [parser-]config.[ch] *or* at least move // Config* declarations from parser.h to parser.c or parser-config.h. void ConfigResponse (SnortConfig *sc, char *args) { char **toks; int num_toks; int i; if ((sc == NULL) || (args == NULL)) return; toks = mSplit(args, ", ", 0, &num_toks, 0); for (i = 0; i < num_toks; i++) { if ( !strcasecmp(toks[i], RESPONSE_OPT__ATTEMPTS) ) { if ( ++i < num_toks ) { char *endptr; long int value = strtol(toks[i], &endptr, 0); if ((errno == ERANGE) || (*endptr != '\0') || (value < 1) || (value > 20)) { ParseError("Invalid argument for attempts: %s. " "Argument must be between 1 and 20 inclusive.", toks[i]); } sc->respond_attempts = (uint8_t)value; } else { ParseError("No argument to 'attempts'. " "Argument must be between 1 and 20 inclusive."); } } else if ( !strcasecmp(toks[i], RESPONSE_OPT__DEVICE) ) { if ( ++i < num_toks ) { sc->respond_device = SnortStrdup(toks[i]); } else { ParseError("No argument to 'device'. Use 'ip' for network " "layer responses or 'eth0' etc. for link layer responses."); } } else if ( !strcasecmp(toks[i], RESPONSE_OPT__DST_MAC) ) { if ( ++i < num_toks ) { eth_addr_t dst; if (eth_pton( toks[i], &dst) < 0) { ParseError("Format check failed: %s, Use format like 12:34:56:78:90:1a", toks[i]); } sc->eth_dst = SnortAlloc (sizeof(dst.data)); memcpy(sc->eth_dst, dst.data, sizeof(dst.data)); } else { ParseError("No argument to 'dst_mac'. Use format 12:34:56:78:90:1a"); } } else { ParseError("Invalid config response option '%s'", toks[i]); } } mSplitFree(&toks, num_toks); } #endif void ConfigFlowbitsSize(SnortConfig *sc, char *args) { if ((sc == NULL) || (args == NULL)) return; setFlowbitSize(args); sc->flowbit_size = (uint16_t)getFlowbitSizeInBytes(); } /**************************************************************************** * * Purpose: Parses a protocol plus a list of ports. * The protocol should be "udp" or "tcp". * The ports list should be a list of numbers or pairs of numbers. * Each element of the list is separated by a space character. * Each pair of numbers is separated by a colon character. * So the string passed in is e.g. "tcp 443 578 6667:6681 13456" * The numbers do not have to be in numerical order. * * Arguments: * SnortConfig * * The snort config to store ignored ports. * char * * string containing protocol plus list of ports * * Returns: void function * *****************************************************************************/ void ConfigIgnorePorts(SnortConfig *sc, char *args) { char ** toks; int num_toks = 0; int i, p; uint16_t hi_port = 0, lo_port = 0; int protocol; int not_flag; if ((sc == NULL) || (args == NULL)) return; LogMessage("Found ignore_ports config directive (%s)\n", args); toks = mSplit(args, " \t", 0, &num_toks, 0); if ( !num_toks ) ParseError("config ignore_ports: Empty port list."); protocol = GetRuleProtocol(toks[0]); if ( !(protocol == IPPROTO_TCP || protocol == IPPROTO_UDP) ) { ParseError("Invalid protocol: %s.", toks[0]); } for ( i = 1; i < num_toks; i++ ) { /* Re-use function from rules processing */ ParsePort(sc, toks[i], &hi_port, &lo_port, toks[0], ¬_flag); for ( p = lo_port; p <= hi_port; p++ ) { if (protocol == IPPROTO_TCP) sc->ignore_ports[p] |= PROTO_BIT__TCP; else if (protocol == IPPROTO_UDP) sc->ignore_ports[p] |= PROTO_BIT__UDP; } } mSplitFree(&toks, num_toks); } void ConfigIncludeVlanInAlert(SnortConfig *sc, char *args) { if (sc == NULL) return; sc->output_flags |= OUTPUT_FLAG__ALERT_VLAN; } void ConfigInterface(SnortConfig *sc, char *args) { if ((args == NULL) || (sc == NULL) || (sc->interface != NULL)) return; #ifdef WIN32 /* first, try to handle the "-i1" case, where an interface * is specified by number. If this fails, then fall-through * to the case outside the ifdef/endif, where an interface * can be specified by its fully qualified name, like as is * shown by running 'snort -W', ie. * "\Device\Packet_{12345678-90AB-CDEF-1234567890AB}" */ { char errorbuf[PCAP_ERRBUF_SIZE]; int adaplen = atoi(args); if (adaplen > 0) { pcap_if_t *alldevs; pcap_if_t *dev; int i = 1; if (pcap_findalldevs(&alldevs, errorbuf) == -1) ParseError("Could not get device list: %s.", errorbuf); for (dev = alldevs; dev != NULL; dev = dev->next) { if (i == adaplen) break; i++; } if (dev == NULL) ParseError("Invalid device number: %d.", adaplen); sc->interface = SnortStrdup(dev->name); pcap_freealldevs(alldevs); return; } } #endif /* WIN32 */ /* this code handles the case in which the user specifies * the entire name of the interface and it is compiled * regardless of which OS you have */ sc->interface = SnortStrdup(args); } void ConfigIpv6Frag(SnortConfig *sc, char *args) { int num_opts; char **opt_toks; int i; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"IPv6 Rule Option\n");); if ((sc == NULL) || (args == NULL)) return; opt_toks = mSplit(args, ",", 0, &num_opts, 0); for (i = 0; i < num_opts; i++) { char **arg_toks; int num_args; arg_toks = mSplit(opt_toks[i], " \t", 2, &num_args, 0); if(num_args != 2 || !arg_toks[1]) { ParseError("ipv6_frag option '%s' requires an argument.", arg_toks[0]); continue; } if(!strcasecmp(arg_toks[0], "bsd_icmp_frag_alert")) { DEBUG_WRAP(DebugMessage(DEBUG_INIT, "disabling the BSD ICMP fragmentation alert\n");); if(!strcasecmp(arg_toks[1], "off")) sc->targeted_policies[getParserPolicy(sc)]->decoder_alert_flags &= ~DECODE_EVENT_FLAG__IPV6_BSD_ICMP_FRAG; } else if(!strcasecmp(arg_toks[0], "bad_ipv6_frag_alert")) { DEBUG_WRAP(DebugMessage(DEBUG_INIT, "disabling the IPv6 bad fragmentation packet alerts\n");); if(!strcasecmp(arg_toks[1], "off")) sc->targeted_policies[getParserPolicy(sc)]->decoder_alert_flags &= ~DECODE_EVENT_FLAG__IPV6_BAD_FRAG; } else if (!strcasecmp(arg_toks[0], "frag_timeout")) { long val; char *endp; val = strtol(arg_toks[1], &endp, 0); if(val <= 0 || val > 3600) { ParseError("ipv6_frag_timeout: Invalid argument '%s'. " "Must be greater that 0 and less than 3600 " "secnods.", arg_toks[1]); } if(args == endp || *endp) { ParseError("ipv6_frag_timeout: Invalid argument '%s'.", arg_toks[1]); } sc->ipv6_frag_timeout = val; } else if (!strcasecmp(arg_toks[0], "max_frag_sessions")) { long val; char *endp; val = strtol(arg_toks[1], &endp, 0); if (val <= 0) { ParseError("ipv6_max_frag_sessions: Invalid number of sessions " "'%s'. Must be greater than 0.", arg_toks[1]); } if(args == endp || *endp) { ParseError("ipv6_max_frag_sessions: Invalid number of " "sessions '%s'.", arg_toks[1]); } sc->ipv6_max_frag_sessions = val; } else if (!strcasecmp(arg_toks[0], "drop_bad_ipv6_frag")) { if(!strcasecmp(arg_toks[1], "off")) { DEBUG_WRAP(DebugMessage(DEBUG_INIT, "disabling the BSD ICMP fragmentation alert\n");); sc->targeted_policies[getParserPolicy(sc)]->decoder_drop_flags &= ~DECODE_EVENT_FLAG__IPV6_BAD_FRAG; } } else { ParseError("Invalid option to ipv6_frag '%s %s'.", arg_toks[0], arg_toks[1]); } mSplitFree(&arg_toks, num_args); } mSplitFree(&opt_toks, num_opts); } void ConfigLayer2Resets(SnortConfig *sc, char *args) { ParseWarning("layer2resets is deprecated.\n"); } void ConfigLogDir(SnortConfig *sc, char *args) { if ((args == NULL) || (sc == NULL) || (sc->log_dir != NULL)) return; sc->log_dir = SnortStrdup(args); } void ConfigDaqType(SnortConfig *sc, char *args) { if ( !args || !sc ) return; if ( sc->daq_type ) ParseError("Setting DAQ to %s but %s already selected.\n", args, sc->daq_type); // will be validated later after paths are established sc->daq_type = SnortStrdup(args); } void ConfigDaqMode(SnortConfig *sc, char *args) { if ( !args || !sc || sc->daq_mode ) return; // will be validated later when daq is instantiated sc->daq_mode = SnortStrdup(args); } void ConfigDaqVar(SnortConfig *sc, char *args) { if ( !args || !sc ) return; if ( !sc->daq_vars ) { sc->daq_vars = StringVector_New(); if ( !sc->daq_vars ) ParseError("can't allocate memory for daq_var '%s'.", args); } if ( !StringVector_Add(sc->daq_vars, args) ) ParseError("can't allocate memory for daq_var '%s'.", args); } void ConfigDaqDir(SnortConfig *sc, char *args) { if ( !args || !sc ) return; if ( !sc->daq_dirs ) { sc->daq_dirs = StringVector_New(); if ( !sc->daq_dirs ) ParseError("can't allocate memory for daq_dir '%s'.", args); } if ( !StringVector_Add(sc->daq_dirs, args) ) ParseError("can't allocate memory for daq_dir '%s'.", args); } void ConfigDirtyPig(SnortConfig *sc, char *args) { if ( sc ) sc->dirty_pig = 1; } #ifdef TARGET_BASED void ConfigMaxAttributeHosts(SnortConfig *sc, char *args) { uint32_t val = 0; char *endp; if ((sc == NULL) || (args == NULL)) return; val = strtoul(args, &endp, 10); if (args == endp || *endp || (val == 0)) { ParseError("max_attribute_hosts: Invalid number of hosts '%s'. Must " "be unsigned positive integer value.", args); } if ((val > MAX_MAX_ATTRIBUTE_HOSTS) || (val < MIN_MAX_ATTRIBUTE_HOSTS)) { ParseError("max_atttribute_hosts: Invalid number of hosts %s'. " "Must be between %d and %d.", args, MIN_MAX_ATTRIBUTE_HOSTS, MAX_MAX_ATTRIBUTE_HOSTS); } sc->max_attribute_hosts = val; } void ConfigMaxAttributeServicesPerHost(SnortConfig *sc, char *args) { uint32_t val = 0; char *endp; if ((sc == NULL) || (args == NULL)) return; val = strtoul(args, &endp, 10); if (args == endp || *endp || (val == 0)) { ParseError("max_attribute_services_per_host: Invalid number of services '%s'. Must " "be unsigned positive integer value.", args); } if ((val > MAX_MAX_ATTRIBUTE_SERVICES_PER_HOST) || (val < MIN_MAX_ATTRIBUTE_SERVICES_PER_HOST)) { ParseError("max_atttribute_services_per_host: Invalid number of services %s'. " "Must be between %d and %d.", args, MIN_MAX_ATTRIBUTE_SERVICES_PER_HOST, MAX_MAX_ATTRIBUTE_SERVICES_PER_HOST); } sc->max_attribute_services_per_host = val; } void ConfigMaxMetadataServices(SnortConfig *sc, char *args) { uint32_t val = 0; char *endp; if ((sc == NULL) || (args == NULL)) return; val = strtoul(args, &endp, 10); if (args == endp || *endp || (val == 0)) { ParseError("max_metadata_services: Invalid number of hosts '%s'. Must " "be unsigned positive integer value.", args); } if ((val > MAX_MAX_METADATA_SERVICES) || (val < MIN_MAX_METADATA_SERVICES)) { ParseError("max_metadata_services: Invalid number of hosts '%s'. " "Must be between %d and %d.", args, MIN_MAX_METADATA_SERVICES, MAX_MAX_METADATA_SERVICES); } sc->max_metadata_services = val; } void ConfigDisableAttributeReload(SnortConfig *sc, char *args) { if (sc == NULL) return; sc->run_flags |= RUN_FLAG__DISABLE_ATTRIBUTE_RELOAD_THREAD; } #endif #ifdef MPLS void ConfigMaxMplsLabelChain(SnortConfig *sc, char *args) { char *endp; long val = 0; if (sc == NULL) return; if (args != NULL) { val = strtol(args, &endp, 0); if ((args == endp) || *endp || (val < -1)) val = DEFAULT_LABELCHAIN_LENGTH; } else { val = DEFAULT_LABELCHAIN_LENGTH; } sc->mpls_stack_depth = val; } void ConfigMplsPayloadType(SnortConfig *sc, char *args) { if (sc == NULL) return; if (args != NULL) { if (strcasecmp(args, MPLS_PAYLOAD_OPT__IPV4) == 0) { sc->mpls_payload_type = MPLS_PAYLOADTYPE_IPV4; } else if (strcasecmp(args, MPLS_PAYLOAD_OPT__IPV6) == 0) { sc->mpls_payload_type = MPLS_PAYLOADTYPE_IPV6; } else if (strcasecmp(args, MPLS_PAYLOAD_OPT__ETHERNET) == 0) { sc->mpls_payload_type = MPLS_PAYLOADTYPE_ETHERNET; } else { ParseError("Non supported mpls payload type: %s.", args); } } else { sc->mpls_payload_type = DEFAULT_MPLS_PAYLOADTYPE; } } #endif void ConfigMinTTL(SnortConfig *sc, char *args) { long int value; char *endptr; if ((sc == NULL) || (args == NULL)) return; value = strtol(args, &endptr, 0); if ((errno == ERANGE) || (*endptr != '\0') || (value < 1) || (value > UINT8_MAX)) { ParseError("Invalid argument to 'min_ttl' configuration: %s. " "Must be a positive integer.", args); } { SnortPolicy* pPolicy = sc->targeted_policies[getParserPolicy(sc)]; pPolicy->min_ttl = (uint8_t)value; } } #ifdef NORMALIZER void ConfigNewTTL(SnortConfig *sc, char *args) { long int value; char *endptr; if ((sc == NULL) || (args == NULL)) return; value = strtol(args, &endptr, 0); if ((errno == ERANGE) || (*endptr != '\0') || (value < 1) || (value > UINT8_MAX)) { ParseError("Invalid argument to 'new_ttl' configuration: %s. " "Must be a non-negative integer.", args); } { SnortPolicy* pPolicy = sc->targeted_policies[getParserPolicy(sc)]; pPolicy->new_ttl = (uint8_t)value; } } #endif void ConfigNoLog(SnortConfig *sc, char *args) { if (sc == NULL) return; sc->no_log = 1; } void ConfigNoLoggingTimestamps(SnortConfig *sc, char *args) { if (sc == NULL) return; sc->output_flags |= OUTPUT_FLAG__NO_TIMESTAMP; } void ConfigNoPcre(SnortConfig *sc, char *args) { if (sc == NULL) return; sc->run_flags |= RUN_FLAG__NO_PCRE; } void ConfigNoPromiscuous(SnortConfig *sc, char *args) { if (sc == NULL) return; sc->run_flags |= RUN_FLAG__NO_PROMISCUOUS; } void ConfigObfuscate(SnortConfig *sc, char *args) { if (sc == NULL) return; sc->output_flags |= OUTPUT_FLAG__OBFUSCATE; } void ConfigObfuscationMask(SnortConfig *sc, char *args) { if ((sc == NULL) || (args == NULL)) return; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Got obfus data: %s\n", args);); sc->output_flags |= OUTPUT_FLAG__OBFUSCATE; sfip_pton(args, &sc->obfuscation_net); } void ConfigPafMax (SnortConfig *sc, char *args) { long int value; char *endptr; const unsigned max = MAXIMUM_PAF_MAX; if ((sc == NULL) || (args == NULL)) return; value = SnortStrtoulRange(args, &endptr, 0, 0, max); if ( (errno == ERANGE) || (*endptr != '\0') ) { ParseError( "Invalid argument to '%s' configuration: %s. " "Must be between 0 (off) and %u (max).", CONFIG_OPT__PAF_MAX, args, max); } { sc->paf_max = (uint32_t)value; } } void ConfigRuleListOrder(SnortConfig *sc, char *args) { OrderRuleLists(sc, args); } void ConfigPcreMatchLimit(SnortConfig *sc, char *args) { char *endp; long val = 0; if ((sc == NULL) || (args == NULL)) return; val = strtol(args, &endp, 0); if ((args == endp) || *endp || (val < -1)) { ParseError("pcre_match_limit: Invalid value '%s'.", args); } sc->pcre_match_limit = val; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "pcre_match_limit: %d\n", sc->pcre_match_limit);); } void ConfigPcreMatchLimitRecursion(SnortConfig *sc, char *args) { char *endp; long val = 0; if ((sc == NULL) || (args == NULL)) return; val = strtol(args, &endp, 0); if ((args == endp) || *endp || (val < -1)) { ParseError("pcre_match_limit_recursion: Invalid value '%s'.", args); } sc->pcre_match_limit_recursion = val; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "pcre_match_limit_recursion: %d\n", sc->pcre_match_limit_recursion);); } void ConfigPerfFile(SnortConfig *sc, char *args) { if ((sc == NULL) || (args == NULL)) return; sc->perf_file = SnortStrdup(args); } void ConfigPacketCount(SnortConfig *sc, char *args) { char *endptr; long count; if ((sc == NULL) || (args == NULL)) return; count = SnortStrtoul(args, &endptr, 0); if ((errno == ERANGE) || (*endptr != '\0')) { ParseError("Invalid packet count: %s. Packet count must be between " "0 and %u inclusive.", args, UINT32_MAX); } if ( count > 0 ) { sc->pkt_cnt = count; LogMessage("Exiting after " STDu64 " packets\n", sc->pkt_cnt); return; } #ifdef REG_TEST sc->pkt_skip = -count; LogMessage("Processing after " STDu64 " packets\n", sc->pkt_skip); #else ParseError("Invalid packet count: %s. Packet count must be greater than zero."); #endif } void ConfigPacketSnaplen(SnortConfig *sc, char *args) { char *endptr; uint32_t snaplen; if ((sc == NULL) || (args == NULL)) return; snaplen = SnortStrtoul(args, &endptr, 0); if ((errno == ERANGE) || (*endptr != '\0') || ((snaplen != 0) && (snaplen < MIN_SNAPLEN)) || (snaplen > MAX_SNAPLEN) ) { ParseError("Invalid snaplen: %s. Snaplen must be between " "%u and %u inclusive or 0 for default = %u.", args, MIN_SNAPLEN, MAX_SNAPLEN, DAQ_GetSnapLen()); } sc->pkt_snaplen = snaplen; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Snap length of packets set to: %d\n", sc->pkt_snaplen);); } void ConfigPidPath(SnortConfig *sc, char *args) { if ((args == NULL) || (sc == NULL)) return; LogMessage("Found pid path directive (%s)\n", args); sc->run_flags |= RUN_FLAG__CREATE_PID_FILE; if (SnortStrncpy(sc->pid_path, args, sizeof(sc->pid_path)) != SNORT_STRNCPY_SUCCESS) ParseError("Pid path too long."); DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Pid Path directory = %s\n", sc->pid_path);); } void ConfigPolicy(SnortConfig *sc, char *args) { int num_toks; char **toks; if ((sc == NULL) || (sc->targeted_policies == NULL)) return; toks = mSplit(args, " \t,", 20, &num_toks, 0); if (num_toks != 1) { mSplitFree(&toks, num_toks); return; } sc->targeted_policies[getParserPolicy(sc)]->configPolicyId = (unsigned short)(atoi(toks[0])); mSplitFree(&toks, num_toks); } void ConfigIpsPolicyMode(SnortConfig *sc, char *args) { if ((sc == NULL) || (sc->targeted_policies == NULL)) return; sc->targeted_policies[getParserPolicy(sc)]->ips_policy_mode = GetPolicyMode(args, sc->run_flags); } void ConfigNapPolicyMode(SnortConfig *sc, char *args) { if ((sc == NULL) || (sc->targeted_policies == NULL)) return; sc->targeted_policies[getParserPolicy(sc)]->nap_policy_mode = GetPolicyMode(args, sc->run_flags); } static int GetPolicyMode(char *args, int run_flags) { char **toks; int num_toks; int i; int mode = 0; if (args == NULL) { if ( run_flags & RUN_FLAG__INLINE ) return POLICY_MODE__INLINE; else if ( run_flags & RUN_FLAG__INLINE_TEST ) return POLICY_MODE__INLINE_TEST; else return POLICY_MODE__PASSIVE; } toks = mSplit(args, " \t", 10, &num_toks, 0); for (i = 0; i < num_toks; i++) { if (strcasecmp(toks[i], POLICY_MODE_PASSIVE) == 0) { if ( ScAdapterInlineTestMode() ) mode = POLICY_MODE__INLINE_TEST; else mode = POLICY_MODE__PASSIVE; } else if (strcasecmp(toks[i], POLICY_MODE_INLINE) == 0) { /* If --enable-inline-test is specified it overwrites * policy_mode: inline */ if( ScAdapterInlineTestMode() ) mode = POLICY_MODE__INLINE_TEST; else if (!ScAdapterInlineMode()) { ParseWarning("Adapter is in Passive Mode. Hence switching " "policy mode to tap."); mode = POLICY_MODE__PASSIVE; } else mode = POLICY_MODE__INLINE; } else if (strcasecmp(toks[i], POLICY_MODE_INLINE_TEST) == 0) { mode = POLICY_MODE__INLINE_TEST; } else { ParseError("Unknown command line policy mode option: %s.", toks[i]); } } mSplitFree(&toks, num_toks); return mode; } void ConfigPolicyVersion(SnortConfig *sc, char *args) { char **toks; int num_toks; if ((sc == NULL) || (sc->targeted_policies == NULL) || (snort_conf_file == NULL) || (args == NULL)) { return; } toks = mSplit(args, " \t", 0, &num_toks, 0); if (num_toks == 1) { if (getParserPolicy(sc) != getDefaultPolicy()) { ParseError("Targeted policies must have base policy version and " "targeted policy version."); } if (sc->base_version == NULL) { sc->base_version = SnortStrdup(toks[0]); } else { if (strcmp(sc->base_version, toks[0]) != 0) { ParseError("Base policy version mismatch: Current base " "version: %s, %s: %s", sc->base_version, file_name, toks[0]); } } } else if (num_toks == 2) { SnortPolicy *p = sc->targeted_policies[getParserPolicy(sc)]; if (getParserPolicy(sc) == getDefaultPolicy()) ParseError("Base policy must only have one policy version."); if (sc->base_version == NULL) { ParseError("Config option \"%s\" must be configured in \"%s\"", CONFIG_OPT__POLICY_VERSION, snort_conf_file); } if (strcmp(sc->base_version, toks[0]) != 0) { ParseError("Base policy version mismatch: Current base " "version: %s, %s: %s", sc->base_version, file_name, toks[0]); } if (p->policy_version == NULL) { p->policy_version = SnortStrdup(toks[1]); } else { if (strcmp(p->policy_version, toks[1]) != 0) { ParseError("Targeted policy version mismatch: Current targeted " "policy version: %s, %s: %s", p->policy_version, file_name, toks[1]); } } } else { ParseError("Invalid number of arguments to \"%s\": %s.", CONFIG_OPT__POLICY_VERSION, args); } mSplitFree(&toks, num_toks); } void ConfigProtectedContent(SnortConfig *sc, char *args) { int num_toks; char **toks; if ((sc == NULL) || (args == NULL)) return; toks = mSplit(args, " \t", 2, &num_toks, 0); if( num_toks != 2 ) ParseError("Invalid argument to protected_content"); if( strcasecmp(toks[0], PROTECTED_CONTENT_OPT__HASH_TYPE) != 0 ) ParseError("Invalid argument to protected_content"); if( (sc->Default_Protected_Content_Hash_Type = SecHash_Name2Type( toks[1] )) == SECHASH_NONE ) ParseError("Invalid protected content hash type"); mSplitFree(&toks, num_toks); } #ifdef PPM_MGR /* * config ppm: feature, feature, feature,.. * * config ppm: max-pkt-time usecs, * disable-pkt-inspection, * max-rule-time usecs, * disable-rule-inspection, threshold 5, * max-suspend-time secs, * rule-events alert|syslog|console, * pkt-events alert|syslog|console, * debug, * debug-pkts */ void ConfigPPM(SnortConfig *sc, char *args) { char **toks; int num_toks; int i; char *endptr; unsigned long int val; char **opts; int num_opts; int pktOpts = 0, ruleOpts = 0; if (sc == NULL) return; toks = mSplit(args, ",", 0, &num_toks, 0); if (!sc->ppm_cfg.enabled) ppm_init(&sc->ppm_cfg); /* defaults are set by ppm_init() */ for(i = 0; i < num_toks; i++) { opts = mSplit(toks[i], " \t", 0, &num_opts, 0); if (strcasecmp(opts[0], PPM_OPT__MAX_PKT_TIME) == 0) { if (num_opts != 2) { ParseError("config ppm: missing argument for '%s'.", opts[0]); } val = SnortStrtoul(opts[1], &endptr, 0); if ((opts[1][0] == '-') || (errno == ERANGE) || (*endptr != '\0')) { ParseError("config ppm: Invalid %s '%s'.", opts[0], opts[1]); } ppm_set_max_pkt_time(&sc->ppm_cfg, val); } else if (strcasecmp(opts[0], PPM_OPT__MAX_RULE_TIME) == 0) { if (num_opts != 2) { ParseError("config ppm: missing argument for '%s'.", opts[0]); } val = SnortStrtoul(opts[1], &endptr, 0); if ((opts[1][0] == '-') || (errno == ERANGE) || (*endptr != '\0')) { ParseError("config ppm: Invalid %s '%s'.", opts[0], opts[1]); } ppm_set_max_rule_time(&sc->ppm_cfg, val); } else if (strcasecmp(opts[0], PPM_OPT__SUSPEND_TIMEOUT) == 0) { if (num_opts != 2) { ParseError("config ppm: missing argument for '%s'.", opts[0]); } val = SnortStrtoul(opts[1], &endptr, 0); if ((opts[1][0] == '-') || (errno == ERANGE) || (*endptr != '\0')) { ParseError("config ppm: Invalid %s '%s'.", opts[0], opts[1]); } ppm_set_max_suspend_time(&sc->ppm_cfg, val); ruleOpts++; } else if (strcasecmp(opts[0], PPM_OPT__SUSPEND_EXP_RULES) == 0) { if (num_opts != 1) { ParseError("config ppm: too many arguments for '%s'.", opts[0]); } ppm_set_rule_action(&sc->ppm_cfg, PPM_ACTION_SUSPEND); ruleOpts++; } else if (strcasecmp(opts[0], PPM_OPT__THRESHOLD) == 0) { if (num_opts != 2) { ParseError("config ppm: missing argument for '%s'.", opts[0]); } val = SnortStrtoul(opts[1], &endptr, 0); if ((opts[1][0] == '-') || (errno == ERANGE) || (*endptr != '\0')) { ParseError("config ppm: Invalid %s '%s'.", opts[0], opts[1]); } ppm_set_rule_threshold(&sc->ppm_cfg, val); ruleOpts++; } else if (strcasecmp(opts[0], PPM_OPT__FAST_PATH_EXP_PKTS) == 0) { if (num_opts != 1) { ParseError("config ppm: too many arguments for '%s'.", opts[0]); } ppm_set_pkt_action(&sc->ppm_cfg, PPM_ACTION_SUSPEND); pktOpts++; } else if (strcasecmp(opts[0], PPM_OPT__PKT_LOG) == 0) { if (num_opts == 1) { ppm_set_pkt_log(&sc->ppm_cfg, PPM_LOG_MESSAGE); } else { int k; for (k = 1; k < num_opts; k++) { if (strcasecmp(opts[k], PPM_OPT__ALERT) == 0) { ppm_set_pkt_log(&sc->ppm_cfg, PPM_LOG_ALERT); } else if (strcasecmp(opts[k], PPM_OPT__LOG) == 0) { ppm_set_pkt_log(&sc->ppm_cfg, PPM_LOG_MESSAGE); } else { ParseError("config ppm: Invalid %s arg '%s'.", opts[0], opts[k]); } } } pktOpts++; } else if (strcasecmp(opts[0], PPM_OPT__RULE_LOG) == 0) { int k; if (num_opts == 1) { ParseError("config ppm: insufficient %s opts.", opts[0]); } for (k = 1; k < num_opts; k++) { if (strcasecmp(opts[k], PPM_OPT__ALERT) == 0) { ppm_set_rule_log(&sc->ppm_cfg, PPM_LOG_ALERT); } else if (strcasecmp(opts[k], PPM_OPT__LOG) == 0) { ppm_set_rule_log(&sc->ppm_cfg, PPM_LOG_MESSAGE); } else { ParseError("config ppm: Invalid %s arg '%s'.", opts[0], opts[k]); } } ruleOpts++; } #ifdef DEBUG else if (strcasecmp(opts[0], PPM_OPT__DEBUG_PKTS) == 0) { if (num_opts != 1) { ParseError("config ppm: too many arguments for '%s'.", opts[0]); } ppm_set_debug_pkts(&sc->ppm_cfg, 1); pktOpts++; } #if 0 else if(!strcasecmp(opts[0], "debug-rules")) { if( 1 != num_opts ) ParseError("config ppm: too many arguments for '%s'.", opts[0]); ppm_set_debug_rules(1); } #endif #endif else { ParseError("'%s' is an invalid option to the 'config ppm:' " "configuration.", opts[0]); } mSplitFree(&opts, num_opts); } mSplitFree(&toks, num_toks); } #endif void ConfigProcessAllEvents(SnortConfig *sc, char *args) { if (sc == NULL) return; sc->run_flags |= RUN_FLAG__PROCESS_ALL_EVENTS; } #ifdef PERF_PROFILING /* Profiling configurations are done later after log directory has * absolutely been set */ static void _ConfigProfilePreprocs(SnortConfig *sc, char *args) { return; } void ConfigProfilePreprocs(SnortConfig *sc, char *args) { char **toks; int num_toks; int i; if (sc == NULL) return; LogMessage("Found profile_preprocs config directive (%s)\n", args == NULL ? "" : args); /* Initialize the defaults */ sc->profile_preprocs.num = -1; sc->profile_preprocs.sort = PROFILE_SORT_AVG_TICKS; toks = mSplit(args, ",", 0, &num_toks, 0); if (num_toks > 3) { ParseError("profile_preprocs speciified with invalid options (%s)", args); } for (i = 0; i < num_toks; i++) { char **opts; int num_opts; int opt_filename = 0; char *endptr; opts = mSplit(toks[i], " \t", 0, &num_opts, 0); if (num_opts > 0) { opt_filename = strcasecmp(opts[0], PROFILE_OPT__FILENAME) == 0; } if ((!opt_filename && (num_opts != 2)) || (opt_filename && ((num_opts > 3) || (num_opts < 2)))) { ParseError("profile_preprocs has an invalid option (%s)", toks[i]); } if (strcasecmp(opts[0], PROFILE_OPT__PRINT) == 0) { if (strcasecmp(opts[1], PROFILE_OPT__ALL) == 0) { sc->profile_preprocs.num = -1; } else { sc->profile_preprocs.num = SnortStrtol(opts[1], &endptr, 10); if ((errno == ERANGE) || (*endptr != '\0')) { ParseError("Invalid argument to profile_preprocs 'print' " "configuration: %s", opts[1]); } } } else if (strcasecmp(opts[0], PROFILE_OPT__SORT) == 0) { if (strcasecmp(opts[1], PROFILE_OPT__CHECKS) == 0) { sc->profile_preprocs.sort = PROFILE_SORT_CHECKS; } else if (strcasecmp(opts[1], PROFILE_OPT__AVG_TICKS) == 0) { sc->profile_preprocs.sort = PROFILE_SORT_AVG_TICKS; } else if (strcasecmp(opts[1], PROFILE_OPT__TOTAL_TICKS) == 0) { sc->profile_preprocs.sort = PROFILE_SORT_TOTAL_TICKS; } else { ParseError("profile_preprocs has an invalid sort option (%s)", toks[i]); } } else if (strcasecmp(opts[0], PROFILE_OPT__FILENAME) == 0) { sc->profile_preprocs.filename = ProcessFileOption(sc, opts[1]); if (opts[2] && (strcasecmp(opts[2], PROFILE_OPT__APPEND) == 0)) { sc->profile_preprocs.append = 1; } else { sc->profile_preprocs.append = 0; } } else { ParseError("profile_preprocs has an invalid option (%s)", toks[i]); } mSplitFree(&opts, num_opts); } mSplitFree(&toks, num_toks); } static void _ConfigProfileRules(SnortConfig *sc, char *args) { return; } void ConfigProfileRules(SnortConfig *sc, char *args) { char **toks; int num_toks; int i; if (sc == NULL) return; LogMessage("Found profile_rules config directive (%s)\n", args == NULL ? "" : args); /* Initialize the defaults */ sc->profile_rules.num = -1; sc->profile_rules.sort = PROFILE_SORT_AVG_TICKS; toks = mSplit(args, ",", 0, &num_toks, 0); if (num_toks > 3) { ParseError("profile_rules speciified with invalid options (%s)", args); } for (i = 0; i < num_toks;i++) { char **opts; int num_opts; int opt_filename = 0; char *endptr; opts = mSplit(toks[i], " \t", 0, &num_opts, 0); if (num_opts > 0) { opt_filename = strcasecmp(opts[0], PROFILE_OPT__FILENAME) == 0; } if ((!opt_filename && (num_opts != 2)) || (opt_filename && ((num_opts > 3) || (num_opts < 2)))) { ParseError("profile_rules has an invalid option (%s)", toks[i]); } if (strcasecmp(opts[0], PROFILE_OPT__PRINT) == 0) { if (strcasecmp(opts[1], PROFILE_OPT__ALL) == 0) { sc->profile_rules.num = -1; } else { sc->profile_rules.num = SnortStrtol(opts[1], &endptr, 10); if ((errno == ERANGE) || (*endptr != '\0')) { ParseError("Invalid argument to profile_rules 'print' " "configuration: %s", opts[1]); } } } else if (strcasecmp(opts[0], PROFILE_OPT__SORT) == 0) { if (strcasecmp(opts[1], PROFILE_OPT__CHECKS) == 0) { sc->profile_rules.sort = PROFILE_SORT_CHECKS; } else if (strcasecmp(opts[1], PROFILE_OPT__MATCHES) == 0) { sc->profile_rules.sort = PROFILE_SORT_MATCHES; } else if (strcasecmp(opts[1], PROFILE_OPT__NO_MATCHES) == 0) { sc->profile_rules.sort = PROFILE_SORT_NOMATCHES; } else if (strcasecmp(opts[1], PROFILE_OPT__AVG_TICKS) == 0) { sc->profile_rules.sort = PROFILE_SORT_AVG_TICKS; } else if (strcasecmp(opts[1], PROFILE_OPT__AVG_TICKS_PER_MATCH) == 0) { sc->profile_rules.sort = PROFILE_SORT_AVG_TICKS_PER_MATCH; } else if (strcasecmp(opts[1], PROFILE_OPT__AVG_TICKS_PER_NO_MATCH) == 0) { sc->profile_rules.sort = PROFILE_SORT_AVG_TICKS_PER_NOMATCH; } else if (strcasecmp(opts[1], PROFILE_OPT__TOTAL_TICKS) == 0) { sc->profile_rules.sort = PROFILE_SORT_TOTAL_TICKS; } else { ParseError("profile_rules has an invalid sort option (%s)", toks[i]); } } else if (strcasecmp(opts[0], PROFILE_OPT__FILENAME) == 0) { sc->profile_rules.filename = ProcessFileOption(sc, opts[1]); if (opts[2] && (strcasecmp(opts[2], PROFILE_OPT__APPEND) == 0)) { sc->profile_rules.append = 1; } else { sc->profile_rules.append = 0; } } else { ParseError("profile_rules has an invalid option (%s)", toks[i]); } mSplitFree(&opts, num_opts); } mSplitFree(&toks, num_toks); } #endif void ConfigQuiet(SnortConfig *sc, char *args) { if (sc == NULL) return; sc->logging_flags |= LOGGING_FLAG__QUIET; sc->internal_log_level = INTERNAL_LOG_LEVEL__ERROR; } /* * Process the 'config rate_filter: memcap <#bytes>' */ // TBD refactor - was cloned from sfthreshold.c void ConfigRateFilter(SnortConfig *sc, char *args) { char **toks; int num_toks; if ((sc == NULL) || (args == NULL)) return; toks = mSplit(args, " \t", 2, &num_toks, 0); if (num_toks != 2) { ParseError("Rate filter memcap requires a positive integer argument."); } if (strcasecmp(toks[0], "memcap") == 0) { char *endptr; sc->rate_filter_config->memcap = SnortStrtol(toks[1], &endptr, 0); if ((errno == ERANGE) || (*endptr != '\0') || (sc->rate_filter_config->memcap < 0)) { ParseError("Invalid rate filter memcap: %s. Must be a " "positive integer.", toks[1]); } } else { ParseError("Unknown argument to rate filter configuration: %s.", toks[0]); } mSplitFree(&toks, num_toks); } void ConfigReference(SnortConfig *sc, char *args) { char **toks; int num_toks; char *url = NULL; if ((sc == NULL) || (args == NULL)) return; /* 2 tokens: name */ toks = mSplit(args, " \t", 0, &num_toks, 0); if (num_toks > 2) { ParseError("Reference config requires at most two arguments: " "\"name []\"."); } if (num_toks == 2) url = toks[1]; ReferenceSystemAdd(&sc->references, toks[0], url); mSplitFree(&toks, num_toks); } /* * Function: ConfigReferenceNet * * Purpose: Translate the command line character string into its equivalent * 32-bit network byte ordered value (with netmask) * * Arguments: args => The address/CIDR block * * Returns: void function */ void ConfigReferenceNet(SnortConfig *sc, char *args) { if ((sc == NULL) || (args == NULL)) return; sfip_pton(args, &sc->homenet); } void ConfigSetGid(SnortConfig *sc, char *args) { #ifdef WIN32 ParseError("Setting the group id is not supported in the " "WIN32 port of snort!"); #else size_t i; char *endptr; if ((sc == NULL) || (args == NULL)) return; for (i = 0; i < strlen(args); i++) { /* If we get something other than a digit, assume it's * a group name */ if (!isdigit((int)args[i])) { struct group *gr = getgrnam(args); if (gr == NULL) ParseError("Group \"%s\" unknown.", args); sc->group_id = gr->gr_gid; break; } } /* It's all digits. Assume it's a group id */ if (i == strlen(args)) { sc->group_id = SnortStrtol(args, &endptr, 10); if ((errno == ERANGE) || (*endptr != '\0') || (sc->group_id < 0)) { ParseError("Group id \"%s\" out of range.", args); } } #endif } void ConfigSetUid(SnortConfig *sc, char *args) { #ifdef WIN32 ParseError("Setting the user id is not supported in the " "WIN32 port of snort!"); #else size_t i; char *endptr; if ((sc == NULL) || (args == NULL)) return; for (i = 0; i < strlen(args); i++) { /* If we get something other than a digit, assume it's * a user name */ if (!isdigit((int)args[i])) { struct passwd *pw = getpwnam(args); if (pw == NULL) ParseError("User \"%s\" unknown.", args); sc->user_id = (int)pw->pw_uid; /* Why would someone want to run as another user * but still as root group? */ if (sc->group_id == -1) sc->group_id = (int)pw->pw_gid; break; } } /* It's all digits. Assume it's a user id */ if (i == strlen(args)) { sc->user_id = SnortStrtol(args, &endptr, 10); if ((errno == ERANGE) || (*endptr != '\0')) ParseError("User id \"%s\" out of range.", args); /* Set group id to user's default group if not * already set */ if (sc->group_id == -1) { struct passwd *pw = getpwuid((uid_t)sc->user_id); if (pw == NULL) ParseError("User \"%s\" unknown.", args); sc->group_id = (int)pw->pw_gid; } } DEBUG_WRAP(DebugMessage(DEBUG_INIT, "UserID: %d GroupID: %d.\n", sc->user_id, sc->group_id);); #endif /* !WIN32 */ } void ConfigShowYear(SnortConfig *sc, char *args) { if (sc == NULL) return; sc->output_flags |= OUTPUT_FLAG__INCLUDE_YEAR; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Enabled year in timestamp\n");); } void ConfigSoRuleMemcap(SnortConfig *sc, char *args) { char *endptr; if ((sc == NULL) || (args == NULL)) return; sc->so_rule_memcap = SnortStrtoul(args, &endptr, 0); if ((errno == ERANGE) || (*endptr != '\0')) { ParseError("Invalid so rule memcap: %s. Memcap must be between " "0 and %u inclusive.", args, UINT32_MAX); } } void ConfigStateful(SnortConfig *sc, char *args) { if (sc == NULL) return; /* If stream5 is configured, the STATEFUL flag is set. This is * somewhat misnamed and is used to assure a session is established */ sc->run_flags |= RUN_FLAG__ASSURE_EST; } void ConfigTaggedPacketLimit(SnortConfig *sc, char *args) { char *endptr; if ((sc == NULL) || (args == NULL)) return; sc->tagged_packet_limit = SnortStrtol(args, &endptr, 0); if ((errno == ERANGE) || (*endptr != '\0') || (sc->tagged_packet_limit < 0)) { ParseError("Invalid tagged_packet_limit: %s. Must be a " "positive integer.", args); } } /* Process the 'config threshold: memcap #bytes, option2-name option2-value, ...' config threshold: memcap #bytes */ void ConfigThreshold(SnortConfig *sc, char *args) { static int warned = 0; if (!warned) { ParseWarning("config threshold is deprecated;" " use config event_filter instead.\n"); warned = 1; } ConfigEventFilter(sc, args); } void ConfigTreatDropAsAlert(SnortConfig *sc, char *args) { if (sc == NULL) return; sc->run_flags |= RUN_FLAG__TREAT_DROP_AS_ALERT; } void ConfigTreatDropAsIgnore(SnortConfig *sc, char *args) { if (sc == NULL) return; sc->run_flags |= RUN_FLAG__TREAT_DROP_AS_IGNORE; } void ConfigUmask(SnortConfig *sc, char *args) { #ifdef WIN32 ParseError("Setting the umask is not supported in the " "WIN32 port of snort!"); #else char *endptr; long mask; if ((sc == NULL) || (args == NULL)) return; mask = SnortStrtol(args, &endptr, 0); if ((errno == ERANGE) || (*endptr != '\0') || (mask < 0) || (mask & ~FILEACCESSBITS)) { ParseError("Bad umask: %s", args); } sc->file_mask = (mode_t)mask; #endif } void ConfigUtc(SnortConfig *sc, char *args) { if (sc == NULL) return; sc->output_flags |= OUTPUT_FLAG__USE_UTC; } void ConfigVerbose(SnortConfig *sc, char *args) { if (sc == NULL) return; sc->logging_flags |= LOGGING_FLAG__VERBOSE; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Verbose Flag active\n");); } void ConfigVlanAgnostic(SnortConfig *sc, char *args) { if (sc == NULL) return; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "VLAN Agnostic active\n");); sc->vlan_agnostic = 1; /* TODO: add this to some existing flag bitfield? */ } void ConfigAddressSpaceAgnostic(SnortConfig *sc, char *args) { if (sc == NULL) return; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Address Space Agnostic active\n");); sc->addressspace_agnostic = 1; /* TODO: add this to some existing flag bitfield? */ } void ConfigLogIPv6Extra(SnortConfig *sc, char *args) { if (sc == NULL) return; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "LOG IPV6 EXTRA DATA active\n");); sc->log_ipv6_extra = 1; /* TODO: add this to some existing flag bitfield? */ } void ConfigDumpDynamicRulesPath(SnortConfig *sc, char *args) { if (sc == NULL) return; sc->run_mode_flags |= RUN_MODE_FLAG__RULE_DUMP; if ( args != NULL ) sc->dynamic_rules_path = SnortStrdup(args); } void ConfigControlSocketDirectory(SnortConfig *sc, char *args) { if (sc == NULL) return; if ( args != NULL ) sc->cs_dir = SnortStrdup(args); } void ConfigFile(SnortConfig *sc, char *args) { if (sc == NULL) return; if ( args != NULL ) { if (!sc->file_config) sc->file_config = file_service_config_create(); file_service_config(sc, args, sc->file_config); } } void ConfigTunnelVerdicts ( SnortConfig *sc, char *args ) { char* tmp, *tok; if (sc == NULL) return; tmp = SnortStrdup(args); tok = strtok(tmp, " ,"); while ( tok ) { if ( !strcasecmp(tok, "gtp") ) sc->tunnel_mask |= TUNNEL_GTP; else if ( !strcasecmp(tok, "teredo") ) sc->tunnel_mask |= TUNNEL_TEREDO; else if ( !strcasecmp(tok, "gre") ) sc->tunnel_mask |= TUNNEL_GRE; else if ( !strcasecmp(tok, "6in4") ) sc->tunnel_mask |= TUNNEL_6IN4; else if ( !strcasecmp(tok, "4in6") ) sc->tunnel_mask |= TUNNEL_4IN6; else if ( !strcasecmp(tok, "4in4") ) sc->tunnel_mask |= TUNNEL_4IN4; else if ( !strcasecmp(tok, "6in6") ) sc->tunnel_mask |= TUNNEL_6IN6; else if ( !strcasecmp(tok, "mpls") ) sc->tunnel_mask |= TUNNEL_MPLS; else ParseError("Unknown tunnel bypass protocol"); tok = strtok(NULL, " ,"); } free(tmp); } #ifdef SIDE_CHANNEL static void ConfigSideChannel(SnortConfig *sc, char *args) { if (sc == NULL) return; sc->side_channel_config.enabled = true; if (args != NULL) sc->side_channel_config.opts = SnortStrdup(args); } #endif void ConfigMaxIP6Extensions(SnortConfig *sc, char *args) { char *endptr; unsigned long parsed_value; if ((sc == NULL) || (args == NULL)) return; parsed_value = SnortStrtoul(args, &endptr, 0); if ((*endptr != '\0') || (parsed_value > UINT8_MAX)) { ParseError("Max IP6 extension count must be a value between 0 and %d (inclusive), not: '%s'.", UINT8_MAX, args); } sc->max_ip6_extensions = (uint8_t) parsed_value; } void ConfigDisableReplace(SnortConfig *sc, char *args) { if(sc == NULL) return; sc->disable_replace_opt = 1; } #ifdef DUMP_BUFFER void ConfigBufferDump(SnortConfig *sc, char *args) { if ( !sc ) return; sc->no_log = 0; if (!args) return; if ( !sc->buffer_dump_file ) { sc->buffer_dump_file = StringVector_New(); if ( !sc->buffer_dump_file ) ParseError("can't allocate memory for buffer_dump_file '%s'.", args); } if ( !StringVector_Add(sc->buffer_dump_file, args) ) ParseError("can't allocate memory for buffer_dump '%s'.", args); } #endif /**************************************************************************** * * Function: ParseRule() * * Purpose: Process an individual rule and add it to the rule list * * Arguments: rule => rule string * * Returns: void function * ***************************************************************************/ static void ParseRule(SnortConfig *sc, SnortPolicy *p, char *args, RuleType rule_type, ListHead *list) { char **toks = NULL; int num_toks = 0; int protocol = 0; RuleTreeNode test_rtn; RuleTreeNode *rtn; OptTreeNode *otn; char *roptions = NULL; port_entry_t pe; PortVarTable *portVarTable = p->portVarTable; PortTable *nonamePortVarTable = p->nonamePortVarTable; if ((sc == NULL) || (args == NULL)) return; memset(&test_rtn, 0, sizeof(RuleTreeNode)); memset(&pe, 0, sizeof(pe)); DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"[*] Rule start\n");); /* We have a preproc or decoder rule - we assume a header of 'tcp any any -> any any ' */ if (*args == '(') { test_rtn.flags |= ANY_DST_PORT; test_rtn.flags |= ANY_SRC_PORT; test_rtn.flags |= ANY_DST_IP; test_rtn.flags |= ANY_SRC_IP; test_rtn.flags |= BIDIRECTIONAL; test_rtn.type = rule_type; protocol = IPPROTO_TCP; roptions = args; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES, "Preprocessor Rule detected\n");); } else { /* proto ip port dir ip port r*/ toks = mSplit(args, " \t", 7, &num_toks, '\\'); /* A rule might not have rule options */ if (num_toks < 6) { ParseError("Bad rule in rules file: %s", args); } if (num_toks == 7) roptions = toks[6]; test_rtn.type = rule_type; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES, "Non-Preprocessor Rule detected\n");); /* Set the rule protocol - fatal errors if protocol not found */ protocol = GetRuleProtocol(toks[0]); test_rtn.proto = protocol; switch (protocol) { case IPPROTO_TCP: sc->ip_proto_array[IPPROTO_TCP] = 1; break; case IPPROTO_UDP: sc->ip_proto_array[IPPROTO_UDP] = 1; break; case IPPROTO_ICMP: sc->ip_proto_array[IPPROTO_ICMP] = 1; sc->ip_proto_array[IPPROTO_ICMPV6] = 1; break; case ETHERNET_TYPE_IP: /* This will be set via ip_protos */ break; default: ParseError("Bad protocol: %s", toks[0]); break; } /* Process the IP address and CIDR netmask - changed version 1.2.1 * "any" IP's are now set to addr 0, netmask 0, and the normal rules are * applied instead of checking the flag if we see a "!" we * need to set a flag so that we can properly deal with it when we are * processing packets. */ ProcessIP(sc, toks[1], &test_rtn, SRC, 0); /* Check to make sure that the user entered port numbers. * Sometimes they forget/don't know that ICMP rules need them */ if ((strcasecmp(toks[2], RULE_DIR_OPT__DIRECTIONAL) == 0) || (strcasecmp(toks[2], RULE_DIR_OPT__BIDIRECTIONAL) == 0)) { ParseError("Port value missing in rule!"); } DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"Src-Port: %s\n",toks[2]);); if (ParsePortList(&test_rtn, portVarTable, nonamePortVarTable, toks[2], protocol, 0 /* =src port */ )) { ParseError("Bad source port: '%s'", toks[2]); } /* changed version 1.8.4 * Die when someone has tried to define a rule character other * than -> or <> */ if ((strcmp(toks[3], RULE_DIR_OPT__DIRECTIONAL) != 0) && (strcmp(toks[3], RULE_DIR_OPT__BIDIRECTIONAL) != 0)) { ParseError("Illegal direction specifier: %s", toks[3]); } /* New in version 1.3: support for bidirectional rules * This checks the rule "direction" token and sets the bidirectional * flag if the token = '<>' */ if (strcmp(toks[3], RULE_DIR_OPT__BIDIRECTIONAL) == 0) { DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Bidirectional rule!\n");); test_rtn.flags |= BIDIRECTIONAL; } /* changed version 1.2.1 * "any" IP's are now set to addr 0, netmask 0, and the normal rules are * applied instead of checking the flag * If we see a "!" we need to set a flag so that we can * properly deal with it when we are processing packets */ ProcessIP(sc, toks[4], &test_rtn, DST, 0); DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"Dst-Port: %s\n", toks[5]);); if (ParsePortList(&test_rtn, portVarTable, nonamePortVarTable, toks[5], protocol, 1 /* =dst port */ )) { ParseError("Bad destination port: '%s'", toks[5]); } } DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"test_rtn.flags = 0x%X\n", test_rtn.flags);); DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Processing Head Node....\n");); test_rtn.listhead = list; rtn = ProcessHeadNode(sc, &test_rtn, list); /* The IPs in the test node get free'd in ProcessHeadNode if there is * already a matching RTN. The portobjects will get free'd when the * port var table is free'd */ DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Parsing Rule Options...\n");); otn = ParseRuleOptions(sc, rtn, roptions, rule_type, protocol); if (otn == NULL) { /* This otn is a dup and we're choosing to keep the old one */ mSplitFree(&toks, num_toks); return; } rule_count++; /* Get rule option info */ pe.gid = otn->sigInfo.generator; pe.sid = otn->sigInfo.id; /* Have to have at least 6 toks */ if (num_toks != 0) { pe.protocol = SnortStrdup(toks[0]); pe.src_port = SnortStrdup(toks[2]); pe.dst_port = SnortStrdup(toks[5]); } /* See what kind of content is going in the fast pattern matcher */ if (otn->ds_list[PLUGIN_DYNAMIC] != NULL) { DynamicData *dd = (DynamicData *)otn->ds_list[PLUGIN_DYNAMIC]; if (dd->contentFlags & CONTENT_HTTP) pe.uricontent = 1; else if (dd->contentFlags & CONTENT_NORMAL) pe.content = 1; } else { /* Since http_cookie content is not used in fast pattern matcher, * need to iterate the entire list */ if (otn->ds_list[PLUGIN_PATTERN_MATCH_URI] != NULL) { PatternMatchData *pmd = otn->ds_list[PLUGIN_PATTERN_MATCH_URI]; for (; pmd != NULL; pmd = pmd->next) { if ( IsHttpBufFpEligible(pmd->http_buffer) ) { pe.uricontent = 1; break; } } } if (!pe.uricontent && ((otn->ds_list[PLUGIN_PATTERN_MATCH] != NULL) || (otn->ds_list[PLUGIN_PATTERN_MATCH_OR] != NULL))) { pe.content = 1; } } if (rtn->flags & BIDIRECTIONAL) pe.dir = 1; pe.proto = protocol; pe.rule_type = rule_type; port_list_add_entry(&port_list, &pe); /* * The src/dst port parsing must be done before the Head Nodes are processed, since they must * compare the ports/port_objects to find the right rtn list to add the otn rule to. * * After otn processing we can finalize port object processing for this rule */ if (FinishPortListRule(sc->port_tables, rtn, otn, protocol, &pe, sc->fast_pattern_config)) ParseError("Failed to finish a port list rule."); mSplitFree(&toks, num_toks); } /**************************************************************************** * * Function: ProcessHeadNode(RuleTreeNode *, ListHead *, int) * * Purpose: Process the header block info and add to the block list if * necessary * * Arguments: test_node => data generated by the rules parsers * list => List Block Header refernece * protocol => ip protocol * * Returns: void function * ***************************************************************************/ static RuleTreeNode * ProcessHeadNode(SnortConfig *sc, RuleTreeNode *test_node, ListHead *list) { RuleTreeNode *rtn = findHeadNode(sc, test_node, getParserPolicy(sc)); /* if it doesn't match any of the existing nodes, make a new node and * stick it at the end of the list */ if (rtn == NULL) { DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Building New Chain head node\n");); rtn = (RuleTreeNode *)SnortAlloc(sizeof(RuleTreeNode)); rtn->otnRefCount++; /* copy the prototype header info into the new header block */ XferHeader(test_node, rtn); head_count++; rtn->head_node_number = head_count; /* initialize the function list for the new RTN */ SetupRTNFuncList(rtn); /* add link to parent listhead */ rtn->listhead = list; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES, "New Chain head flags = 0x%X\n", rtn->flags);); } else { rtn->otnRefCount++; FreeRuleTreeNode(test_node); } return rtn; } #if 0 #ifdef DEBUG_MSGS static void PrintRtnPorts(RuleTreeNode *rtn_list) { int i = 0; char buf[STD_BUF]; SnortSnprintf(buf, STD_BUF, "%s", " "); while (rtn_list != NULL) { if (rtn_list->flags & EXCEPT_DST_PORT) { SnortSnprintfAppend(buf, STD_BUF, "!"); } SnortSnprintfAppend(buf, STD_BUF, "%d ", rtn_list->ldp); rtn_list = rtn_list->right; if (i == 15) { DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES, "%s\n", buf);); i = 0; SnortSnprintf(buf, STD_BUF, "%s", " "); } i++; } DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES, "%s\n", buf);); } #endif #endif static void ParseAlert(SnortConfig *sc, SnortPolicy *p, char *args) { DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES, "Alert\n");); ParseRule(sc, p, args, RULE_TYPE__ALERT, &sc->Alert); } static void ParseDrop(SnortConfig *sc, SnortPolicy *p, char *args) { DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Drop\n");); /* Parse as an alert if we're treating drops as alerts */ if (ScTreatDropAsAlertNewConf(sc)) ParseRule(sc, p, args, RULE_TYPE__ALERT, &sc->Alert); else if ( ScKeepDropRules(sc) || ScLoadAsDropRules(sc) ) ParseRule(sc, p, args, RULE_TYPE__DROP, &sc->Drop); } static void ParseLog(SnortConfig *sc, SnortPolicy *p, char *args) { DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES, "Log\n");); ParseRule(sc, p, args, RULE_TYPE__LOG, &sc->Log); } static void ParsePass(SnortConfig *sc, SnortPolicy *p, char *args) { DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES, "Pass\n");); ParseRule(sc, p, args, RULE_TYPE__PASS, &sc->Pass); } static void ParseReject(SnortConfig *sc, SnortPolicy *p, char *args) { DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES, "Reject\n");); ParseRule(sc, p, args, RULE_TYPE__REJECT, &sc->Reject); #ifdef ACTIVE_RESPONSE Active_SetEnabled(1); #endif } static void ParseSdrop(SnortConfig *sc, SnortPolicy *p, char *args) { DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES, "SDrop\n");); if ( ScKeepDropRules(sc) && !ScTreatDropAsAlertNewConf(sc) ) ParseRule(sc, p, args, RULE_TYPE__SDROP, &sc->SDrop); } static void ParsePortVar(SnortConfig *sc, SnortPolicy *p, char *args) { char **toks; int num_toks; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES, "PortVar\n");); toks = mSplit(args, " \t", 0, &num_toks, 0); if (num_toks != 2) { ParseError("Missing argument to %s", toks[0]); } /* Check command line variables to see if this has already * been defined */ if (cmd_line_var_list != NULL) { VarNode *tmp = cmd_line_var_list; while (tmp != NULL) { /* Already defined this via command line */ if (strcasecmp(toks[0], tmp->name) == 0) { mSplitFree(&toks, num_toks); return; } tmp = tmp->next; } } PortVarDefine(sc, toks[0], toks[1]); mSplitFree(&toks, num_toks); } static void ParseIpVar(SnortConfig *sc, SnortPolicy *p, char *args) { char **toks; int num_toks; int ret; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES, "IpVar\n");); toks = mSplit(args, " \t", 0, &num_toks, 0); if (num_toks != 2) { ParseError("Missing argument to %s", toks[0]); } /* Check command line variables to see if this has already * been defined */ if (cmd_line_var_list != NULL) { VarNode *tmp = cmd_line_var_list; while (tmp != NULL) { /* Already defined this via command line */ if (strcasecmp(toks[0], tmp->name) == 0) { mSplitFree(&toks, num_toks); return; } tmp = tmp->next; } } DisallowCrossTableDuplicateVars(sc, toks[0], VAR_TYPE__IPVAR); if((ret = sfvt_define(p->ip_vartable, toks[0], toks[1])) != SFIP_SUCCESS) { switch(ret) { case SFIP_ARG_ERR: ParseError("The following is not allowed: %s.", toks[1]); break; case SFIP_DUPLICATE: ParseMessage("Var '%s' redefined.", toks[0]); break; case SFIP_CONFLICT: ParseError("Negated IP ranges that are more general than " "non-negated ranges are not allowed. Consider " "inverting the logic in %s.", toks[0]); break; case SFIP_NOT_ANY: ParseError("!any is not allowed in %s.", toks[0]); break; case SFIP_INVALID_VAR: ParseError("Variable name should contain minimum 1 alphabetic character." " Following variable name is not allowed: %s.", toks[0]); break; default: ParseError("Failed to parse the IP address: %s.", toks[1]); } } mSplitFree(&toks, num_toks); } static void ParseVar(SnortConfig *sc, SnortPolicy *p, char *args) { char **toks; int num_toks; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Variable\n");); toks = mSplit(args, " \t", 0, &num_toks, 0); if (num_toks != 2) { ParseError("Missing argument to %s", toks[0]); } /* Check command line variables to see if this has already * been defined */ if (cmd_line_var_list != NULL) { VarNode *tmp = cmd_line_var_list; while (tmp != NULL) { // Already defined this via command line if (strcasecmp(toks[0], tmp->name) == 0) { mSplitFree(&toks, num_toks); return; } tmp = tmp->next; } } AddVarToTable(sc, toks[0], toks[1]); mSplitFree(&toks, num_toks); } static void ParseFile(SnortConfig *sc, SnortPolicy *p, char *args) { if (!sc->file_config) sc->file_config = file_service_config_create(); file_rule_parse(args, sc->file_config); } static void AddVarToTable(SnortConfig *sc, char *name, char *value) { //TODO: snort.cfg and rules should use PortVar instead ...this allows compatability for now. if (strstr(name, "_PORT") || strstr(name, "PORT_")) { DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"PortVar\n");); PortVarDefine(sc, name, value); } else { VarDefine(sc, name, value); } } static void ParseThreshFilter( SnortConfig *sc, SnortPolicy *p, char *args, const char* ERR_KEY ) { char **toks; int num_toks; int count_flag = 0; int seconds_flag = 0; int type_flag = 0; int tracking_flag = 0; int genid_flag = 0; int sigid_flag = 0; int i; THDX_STRUCT thdx; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Event Filter\n");); memset(&thdx, 0, sizeof(THDX_STRUCT)); toks = mSplit(args, ",", 0, &num_toks, 0); /* get rule option pairs */ for (i = 0; i < num_toks; i++) { char **pairs; int num_pairs; pairs = mSplit(toks[i], " \t", 0, &num_pairs, 0); /* get rule option pairs */ if (num_pairs != 2) { ParseError(ERR_NOT_PAIRED); } if (strcasecmp(pairs[0], THRESHOLD_OPT__COUNT) == 0) { if ( count_flag++ ) { ParseError(ERR_EXTRA_OPTION); } thdx.count = xatol(pairs[1],"event_filter: count"); if ((thdx.count < 1) && (thdx.count != THD_NO_THRESHOLD)) { ParseError("event_filter: count must be > 0 or %d\n", THD_NO_THRESHOLD); } } else if (strcasecmp(pairs[0], THRESHOLD_OPT__SECONDS) == 0) { if ( seconds_flag++ ) { ParseError(ERR_EXTRA_OPTION); } thdx.seconds = xatoup(pairs[1],"event_filter: seconds"); } else if (strcasecmp(pairs[0], THRESHOLD_OPT__TYPE) == 0) { if ( type_flag++ ) { ParseError(ERR_EXTRA_OPTION); } if (strcasecmp(pairs[1], THRESHOLD_TYPE__LIMIT) == 0) { thdx.type = THD_TYPE_LIMIT; } else if (strcasecmp(pairs[1], THRESHOLD_TYPE__THRESHOLD) == 0) { thdx.type = THD_TYPE_THRESHOLD; } else if (strcasecmp(pairs[1], THRESHOLD_TYPE__BOTH) == 0) { thdx.type = THD_TYPE_BOTH; } else { ParseError(ERR_BAD_VALUE); } } else if (strcasecmp(pairs[0], THRESHOLD_OPT__TRACK) == 0) { if ( tracking_flag++ ) { ParseError(ERR_EXTRA_OPTION); } if (strcasecmp(pairs[1], THRESHOLD_TRACK__BY_SRC) == 0) { thdx.tracking = THD_TRK_SRC; } else if (strcasecmp(pairs[1], THRESHOLD_TRACK__BY_DST) == 0) { thdx.tracking = THD_TRK_DST; } else { ParseError(ERR_BAD_VALUE); } } else if (strcasecmp(pairs[0], THRESHOLD_OPT__GID) == 0) { if ( genid_flag++ ) { ParseError(ERR_EXTRA_OPTION); } thdx.gen_id = xatou(pairs[1], "event_filter: gen_id"); } else if (strcasecmp(pairs[0], THRESHOLD_OPT__SID) == 0) { if ( sigid_flag++ ) { ParseError(ERR_EXTRA_OPTION); } thdx.sig_id = xatou(pairs[1], "event_filter: sig_id"); } else { ParseError(ERR_BAD_OPTION); } mSplitFree(&pairs, num_pairs); } if ((count_flag + tracking_flag + type_flag + seconds_flag + genid_flag + sigid_flag) != 6) { ParseError(ERR_BAD_ARG_COUNT); } if (sfthreshold_create(sc, sc->threshold_config, &thdx)) { if (thdx.sig_id == 0) { ParseError(ERR_CREATE_EX, "only one per gen_id != 0"); } else if (thdx.gen_id == 0) { ParseError(ERR_CREATE_EX, "gen_id = 0 requires sig_id = 0"); } else { ParseError(ERR_CREATE_EX, "gen_id, sig_id must be unique"); } } mSplitFree(&toks, num_toks); } /* threshold gen_id #, sig_id #, type limit|threshold|both, \ track by_src|by_dst, count #, seconds # */ static void ParseThreshold(SnortConfig *sc, SnortPolicy *p, char *args) { static int warned = 0; if (!warned) { ParseWarning("threshold (standalone) is deprecated; " "use event_filter instead.\n"); warned = 1; } ParseThreshFilter(sc, p, args, "standalone threshold"); } static void ParseEventFilter(SnortConfig *sc, SnortPolicy *p, char *args) { ParseThreshFilter(sc, p, args, "event_filter"); } /* suppress gen_id #, sig_id #, track by_src|by_dst, ip cidr' */ static void ParseSuppress(SnortConfig *sc, SnortPolicy *p, char *args) { char **toks; int num_toks; int tracking_flag = 0; int genid_flag = 0; int sigid_flag = 0; int ip_flag = 0; int i; THDX_STRUCT thdx; const char* ERR_KEY = "suppress"; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Suppress\n");); memset(&thdx, 0, sizeof(THDX_STRUCT)); thdx.type = THD_TYPE_SUPPRESS; thdx.priority = THD_PRIORITY_SUPPRESS; thdx.tracking = THD_TRK_NONE; /* Potential IP list might be present so we can't split on commas * Change commas to semi-colons */ args = FixSeparators(args, ';', "suppress"); toks = mSplit(args, ";", 0, &num_toks, 0); /* get rule option pairs */ for (i = 0; i < num_toks; i++) { char **pairs; int num_pairs; pairs = mSplit(toks[i], " \t", 2, &num_pairs, 0); /* get rule option pairs */ if (num_pairs != 2) { ParseError(ERR_NOT_PAIRED); } if (strcasecmp(pairs[0], THRESHOLD_OPT__TRACK) == 0) { if ( tracking_flag++ ) { ParseError(ERR_EXTRA_OPTION); } if (strcasecmp(pairs[1], THRESHOLD_TRACK__BY_SRC) == 0) { thdx.tracking = THD_TRK_SRC; } else if (strcasecmp(pairs[1], THRESHOLD_TRACK__BY_DST) == 0) { thdx.tracking = THD_TRK_DST; } else { ParseError(ERR_BAD_VALUE); } } else if (strcasecmp(pairs[0], THRESHOLD_OPT__GID) == 0) { if ( genid_flag++ ) { ParseError(ERR_EXTRA_OPTION); } thdx.gen_id = xatou(pairs[1], "suppress: gen_id"); } else if (strcasecmp(pairs[0], THRESHOLD_OPT__SID) == 0) { if ( sigid_flag++ ) { ParseError(ERR_EXTRA_OPTION); } thdx.sig_id = xatou(pairs[1], "suppress: sig_id"); } else if (strcasecmp(pairs[0], THRESHOLD_OPT__IP) == 0) { if ( ip_flag++ ) { ParseError(ERR_EXTRA_OPTION); } thdx.ip_address = IpAddrSetParse(sc, pairs[1]); } else { ParseError(ERR_BAD_OPTION); } mSplitFree(&pairs, num_pairs); } if (((genid_flag + sigid_flag) != 2) || (((tracking_flag + ip_flag) != 0) && ((tracking_flag + ip_flag) != 2))) { ParseError(ERR_BAD_ARG_COUNT); } if (sfthreshold_create(sc, sc->threshold_config, &thdx)) { ParseError(ERR_CREATE); } mSplitFree(&toks, num_toks); } static void ParseOtnClassType(SnortConfig *sc, RuleTreeNode *rtn, OptTreeNode *otn, RuleType rtype, char *args) { ClassType *class_type; if (args == NULL) { ParseWarning("ClassType without an argument!"); return; } class_type = ClassTypeLookupByType(sc, args); if (class_type == NULL) ParseError("Unknown ClassType: %s", args); otn->sigInfo.classType = class_type; /* Add the class_id to class_id so we can reference it for all rules, * whether they have a class_id or not. */ otn->sigInfo.class_id = class_type->id; if (otn->sigInfo.priority == 0) otn->sigInfo.priority = class_type->priority; /* XXX deprecated */ otn->event_data.classification = class_type->id; if (otn->event_data.priority == 0) otn->event_data.priority = class_type->priority; } static void ParseOtnDetectionFilter(SnortConfig *sc, RuleTreeNode *rtn, OptTreeNode *otn, RuleType rtype, char *args) { int count_flag = 0; int seconds_flag = 0; int tracking_flag = 0; char **toks; int num_toks; int i; static THDX_STRUCT thdx; const char* ERR_KEY = "detection_filter"; memset(&thdx, 0, sizeof(THDX_STRUCT)); toks = mSplit(args, ",", 0, &num_toks, 0); /* Parameter Check - enough args ?*/ if (num_toks != 3) { ParseError(ERR_PAIR_COUNT, 3); } for (i = 0; i < num_toks; i++) { char **pairs; int num_pairs; pairs = mSplit(toks[i], " \t", 0, &num_pairs, 0); if (num_pairs != 2) { ParseError(ERR_NOT_PAIRED); } if (strcasecmp(pairs[0], THRESHOLD_OPT__COUNT) == 0) { if ( count_flag++ ) { ParseError(ERR_EXTRA_OPTION); } thdx.count = xatoup(pairs[1],"detection_filter: count"); } else if (strcasecmp(pairs[0], THRESHOLD_OPT__SECONDS) == 0) { if ( seconds_flag++ ) { ParseError(ERR_EXTRA_OPTION); } thdx.seconds = xatoup(pairs[1],"detection_filter: seconds"); } else if (strcasecmp(pairs[0], THRESHOLD_OPT__TRACK) == 0) { if ( tracking_flag++ ) { ParseError(ERR_EXTRA_OPTION); } if (strcasecmp(pairs[1], THRESHOLD_TRACK__BY_SRC) == 0) { thdx.tracking = THD_TRK_SRC; } else if (strcasecmp(pairs[1], THRESHOLD_TRACK__BY_DST) == 0) { thdx.tracking = THD_TRK_DST; } else { ParseError(ERR_BAD_VALUE); } } else { ParseError(ERR_BAD_OPTION); } mSplitFree(&pairs, num_pairs); } if ((count_flag + tracking_flag + seconds_flag) != 3) { ParseError(ERR_BAD_ARG_COUNT); } mSplitFree(&toks, num_toks); thdx.type = THD_TYPE_DETECT; otn->detection_filter = detection_filter_create(sc->detection_filter_config, &thdx); } static void ParseOtnGid(SnortConfig *sc, RuleTreeNode *rtn, OptTreeNode *otn, RuleType rtype, char *args) { unsigned long int gid; char *endptr; if (args == NULL) ParseError("Gid rule option requires an argument."); gid = SnortStrtoul(args, &endptr, 0); if ((errno == ERANGE) || (*endptr != '\0')) { ParseError("Invalid argument to 'gid' rule option: %s. " "Must be a positive integer.", args); } otn->sigInfo.generator = (uint32_t)gid; otn->event_data.sig_generator = (uint32_t)gid; } /**************************************************************************** * Function: ParseOtnLogTo() * * Purpose: stuff the special log filename onto the proper rule option * * Arguments: * OptTreeNode * * The otn for this rule option * RuleType * The rule type of the rule using this option * char * * The arguments to this rule option * * Returns: None * ***************************************************************************/ static void ParseOtnLogTo(SnortConfig *sc, RuleTreeNode *rtn, OptTreeNode *otn, RuleType rtype, char *args) { char *sptr; char *eptr; if (args == NULL) ParseError("'logto' requires a file name as an argument."); /* grab everything between the starting " and the end one */ sptr = strchr(args, '"'); eptr = strrchr(args, '"'); if ((sptr != NULL) && (eptr != NULL)) { /* increment past the first quote */ sptr++; /* zero out the second one */ *eptr = 0; } else { sptr = args; } /* alloc up a nice shiny clean buffer */ otn->logto = SnortStrdup(sptr); } /**************************************************************************** * Function: ParseOtnMessage() * * Purpose: Stuff the alert message onto the rule * * Arguments: * OptTreeNode * * The otn for this rule option * RuleType * The rule type of the rule using this option * char * * The arguments to this rule option * * Returns: None * ***************************************************************************/ static void ParseOtnMessage(SnortConfig *sc, RuleTreeNode *rtn, OptTreeNode *otn, RuleType rtype, char *args) { size_t i; int escaped = 0; char msg_buf[2048]; /* Arbitrary length, but should be enough */ if (args == NULL) ParseError("Message rule option requires an argument."); if (*args == '"') { /* Have to have at least quote, char, quote */ if (strlen(args) < 3) ParseError("Empty argument passed to rule option 'msg'."); if (args[strlen(args) - 1] != '"') { ParseError("Unmatch quote in rule option 'msg'."); } /* Move past first quote and NULL terminate last quote */ args++; args[strlen(args) - 1] = '\0'; /* If last quote is escaped, fatal error. * Make sure the backslash is not escaped */ if ((args[strlen(args) - 1] == '\\') && (strlen(args) > 1) && (args[strlen(args) - 2] != '\\')) { ParseError("Unmatch quote in rule option 'msg'."); } } /* Only valid escaped chars are ';', '"' and '\' */ /* Would be ok except emerging threats rules are escaping other chars */ for (i = 0; (i < sizeof(msg_buf)) && (*args != '\0');) { if (escaped) { #if 0 if ((*args != ';') && (*args != '"') && (*args != '\\')) { ParseError("Invalid escaped character in 'msg' rule " "option: '%c'. Valid characters to escape are " "';', '\"' and '\\'.\n", *args); } #endif msg_buf[i++] = *args; escaped = 0; } else if (*args == '\\') { escaped = 1; } else { msg_buf[i++] = *args; } args++; } if (escaped) { ParseError("Message in 'msg' rule option has invalid escape character\n"); } if (i == sizeof(msg_buf)) { ParseError("Message in 'msg' rule option too long. Please limit " "to %d characters.", sizeof(msg_buf)); } msg_buf[i] = '\0'; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES, "Message: %s\n", msg_buf);); otn->sigInfo.message = SnortStrdup(msg_buf); } /* * metadata may be key/value pairs or just keys * * metadata: key [=] value, key [=] value, key [=] value, key, key, ... ; * * This option may be used one or more times, with one or more key/value pairs. * * updated 8/28/06 - man * * keys: * * engine * rule-flushing * rule-type * soid * service */ static void ParseOtnMetadata(SnortConfig *sc, RuleTreeNode *rtn, OptTreeNode *otn, RuleType rtype, char *args) { char **metadata_toks; int num_metadata_toks; int i; char **key_value_toks = NULL; int num_key_value_toks = 0; if (args == NULL) ParseError("Metadata rule option requires an argument."); DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES, "metadata: %s\n", args);); metadata_toks = mSplit(args, ",", 100, &num_metadata_toks, 0); for (i = 0; i < num_metadata_toks; i++) { char *key = NULL; char *value = NULL; // After the first loop iteration, free the |key_value_toks| if (key_value_toks != NULL) { mSplitFree(&key_value_toks, num_key_value_toks); key_value_toks = NULL; num_key_value_toks = 0; } key_value_toks = mSplit(metadata_toks[i], "= ", 2, &num_key_value_toks, 0); key = key_value_toks[0]; if (num_key_value_toks == 2) value = key_value_toks[1]; DEBUG_WRAP( DebugMessage(DEBUG_CONFIGRULES, "metadata: key=%s\n", key); if(value) DebugMessage(DEBUG_CONFIGRULES, " value=%s\n", value); ); /* process key/value pairs */ if (strcasecmp(key, METADATA_KEY__ENGINE) == 0) { if (value == NULL) ParseError("Metadata key '%s' requires a value", key); if (strcasecmp(value, METADATA_VALUE__SHARED) != 0) ParseError("Metadata key '%s', passed an invalid value '%s'.", key, value); otn->sigInfo.shared = 1; } /* this should follow 'rule-type' since it changes rule_flusing defaults set by rule-type */ else if (strcasecmp(key, METADATA_KEY__RULE_FLUSHING) == 0) { if (value == NULL) ParseError("Metadata key '%s' requires a value.", key); if ((strcasecmp(value, METADATA_VALUE__ENABLED) == 0) || (strcasecmp(value, METADATA_VALUE__ON) == 0)) { otn->sigInfo.rule_flushing = SI_RULE_FLUSHING_ON; } else if ((strcasecmp(value, METADATA_VALUE__DISABLED) == 0) || (strcasecmp(value, METADATA_VALUE__OFF) == 0)) { otn->sigInfo.rule_flushing = SI_RULE_FLUSHING_OFF; } else { ParseError("Metadata key '%s', passed an invalid value '%s'.", key, value); } } else if (strcasecmp(key, METADATA_KEY__RULE_TYPE) == 0) { if (value == NULL) ParseError("Metadata key '%s' requires a value.", key); if (strcasecmp(value, METADATA_VALUE__PREPROC) == 0) { otn->sigInfo.rule_type = SI_RULE_TYPE_PREPROC; otn->sigInfo.rule_flushing = SI_RULE_FLUSHING_OFF; } else if (strcasecmp(value, METADATA_VALUE__DECODE) == 0) { if ( otn->sigInfo.id >= DECODE_INDEX_MAX ) { ParseError("Unknown 'sid' for rule-type decode."); } else { otn->sigInfo.rule_type = SI_RULE_TYPE_DECODE; otn->sigInfo.rule_flushing = SI_RULE_FLUSHING_OFF; } } else if (strcasecmp(value, METADATA_VALUE__DETECT) == 0) { otn->sigInfo.rule_type = SI_RULE_TYPE_DETECT; otn->sigInfo.rule_flushing = SI_RULE_FLUSHING_ON; } else { ParseError("Metadata key '%s', passed an invalid value '%s'.", key, value); } } else if (strcasecmp(key, METADATA_KEY__SOID) == 0) { char **toks; int num_toks; char *endptr; uint64_t long_val; if (value == NULL) ParseError("Metadata key '%s' requires a value.", key); /* value is a '|' separated pair of gid|sid representing the * GID/SID of the original rule. This is used when the rule * is duplicated rule by a user with different IP/port info. */ toks = mSplit(value, "|", 2, &num_toks, 0); if (num_toks != 2) { ParseError("Metadata Key '%s' Invalid Value. Must be a pipe " "(|) separated pair.", key); } long_val = SnortStrtoul(toks[0], &endptr, 10); if ((errno == ERANGE) || (*endptr != '\0') || (long_val > UINT32_MAX)) ParseError("Bogus gid %s", toks[0]); otn->sigInfo.otnKey.gid = (uint32_t)long_val; long_val = SnortStrtoul(toks[1], &endptr, 10); if ((errno == ERANGE) || (*endptr != '\0') || (long_val > UINT32_MAX)) ParseError("Bogus sid %s", toks[1]); otn->sigInfo.otnKey.sid = (uint32_t)long_val; mSplitFree(&toks, num_toks); } #ifdef TARGET_BASED /* track all of the rules for each service */ else if (strcasecmp(key, METADATA_KEY__SERVICE) == 0 ) { // metadata: service http, ... ; unsigned j, svc_count = otn->sigInfo.num_services; int16_t ordinal = 0; bool found = false; if (value == NULL) { ParseError("Metadata key '%s' requires a value.", key); } if (otn->sigInfo.num_services >= sc->max_metadata_services) { ParseError("Too many service's specified for rule."); } if (otn->sigInfo.services == NULL) { otn->sigInfo.services = SnortAlloc(sizeof(ServiceInfo) * sc->max_metadata_services); } // Service Override(s) if ( strcmp(value, "and-ports") == 0 ) { if (otn->sigInfo.service_override != ServiceOverride_Nil) ParseWarning("Multiple service overrides specified: using '%s'", value); otn->sigInfo.service_override = ServiceOverride_AndPorts; continue; } else if ( strcmp(value, "or-ports") == 0 ) { if (otn->sigInfo.service_override != ServiceOverride_Nil) ParseWarning("Multiple service overrides specified: using '%s'", value); otn->sigInfo.service_override = ServiceOverride_OrPorts; continue; } else if ( strcmp(value, "else-ports") == 0 ) { if (otn->sigInfo.service_override != ServiceOverride_Nil) ParseWarning("Multiple service overrides specified: using '%s'", value); otn->sigInfo.service_override = ServiceOverride_ElsePorts; continue; } else if ( strcmp(value, "unknown") == 0 ) { if (otn->sigInfo.service_override != ServiceOverride_Nil) ParseWarning("Multiple service overrides specified: using '%s'", value); // "Unknown" is a convenient synonym for "else-ports". // It emulates pre-Snort 2.9.8 behavior on "port-only" rules. otn->sigInfo.service_override = ServiceOverride_ElsePorts; continue; } else { ordinal = FindProtocolReference(value); if (ordinal == SFTARGET_UNKNOWN_PROTOCOL) ordinal = AddProtocolReference(value); } for ( j = 0; j < svc_count; j++ ) { if (otn->sigInfo.services[j].service_ordinal == ordinal) { ParseWarning("Duplicate service metadata \"%s\" found.", value); found = true; break; } } if ( !found ) { otn->sigInfo.services[svc_count].service = SnortStrdup(value); otn->sigInfo.services[svc_count].service_ordinal = ordinal; otn->sigInfo.num_services++; } } #endif // TARGET_BASED } mSplitFree(&key_value_toks, num_key_value_toks); mSplitFree(&metadata_toks, num_metadata_toks); } static void ParseOtnPriority(SnortConfig *sc, RuleTreeNode *rtn, OptTreeNode *otn, RuleType rtype, char *args) { unsigned long int priority; char *endptr; if (args == NULL) ParseError("Priority rule option requires an argument."); priority = SnortStrtoul(args, &endptr, 0); if ((errno == ERANGE) || (*endptr != '\0')) { ParseError("Invalid argument to 'gid' rule option: %s. " "Must be a positive integer.", args); } otn->sigInfo.priority = (uint32_t)priority; /* deprecated */ otn->event_data.priority = (uint32_t)priority; } static void ParseOtnReference(SnortConfig *sc, RuleTreeNode *rtn, OptTreeNode *otn, RuleType rtype, char *args) { char **toks; int num_toks; if (args == NULL) ParseError("Reference rule option requires an argument."); /* 2 tokens: system, id */ toks = mSplit(args, ",", 2, &num_toks, 0); if (num_toks != 2) { ParseWarning("Ignoring invalid Reference spec '%s'.", args); mSplitFree(&toks, num_toks); return; } AddReference(sc, &otn->sigInfo.refs, toks[0], toks[1]); mSplitFree(&toks, num_toks); } static void ParseOtnRevision(SnortConfig *sc, RuleTreeNode *rtn, OptTreeNode *otn, RuleType rtype, char *args) { unsigned long int rev; char *endptr; if (args == NULL) ParseError("Revision rule option requires an argument."); rev = SnortStrtoul(args, &endptr, 0); if ((errno == ERANGE) || (*endptr != '\0')) { ParseError("Invalid argument to 'rev' rule option: %s. " "Must be a positive integer.", args); } otn->sigInfo.rev = (uint32_t)rev; /* deprecated */ otn->event_data.sig_rev = (uint32_t)rev; } static void ParseOtnSid(SnortConfig *sc, RuleTreeNode *rtn, OptTreeNode *otn, RuleType rtype, char *args) { unsigned long int sid; char *endptr; if (args == NULL) ParseError("Revision rule option requires an argument."); sid = SnortStrtoul(args, &endptr, 0); if ((errno == ERANGE) || (*endptr != '\0')) { ParseError("Invalid argument to 'sid' rule option: %s. " "Must be a positive integer.", args); } otn->sigInfo.id = (uint32_t)sid; /* deprecated */ otn->event_data.sig_id = (uint32_t)sid; } static void ParseOtnTag(SnortConfig *sc, RuleTreeNode *rtn, OptTreeNode *otn, RuleType rtype, char *args) { int type = 0; int count = 0; int metric = 0; int packets = 0; int seconds = 0; int bytes = 0; int direction = 0; int i; char **toks; int num_toks; uint8_t got_count = 0; if (otn->tag != NULL) ParseError("Can only use 'tag' rule option once per rule."); DEBUG_WRAP(DebugMessage(DEBUG_RULES, "Parsing tag args: %s\n", args);); toks = mSplit(args, " ,", 0, &num_toks, 0); if (num_toks < 1) ParseError("Invalid tag arguments: %s", args); if (strcasecmp(toks[0], TAG_OPT__SESSION) == 0) type = TAG_SESSION; else if (strcasecmp(toks[0], TAG_OPT__HOST) == 0) type = TAG_HOST; else ParseError("Invalid tag type: %s", toks[0]); for (i = 1; i < num_toks; i++) { if (!got_count) { if (isdigit((int)toks[i][0])) { long int val; char *endptr; val = SnortStrtol(toks[i], &endptr, 0); if ((errno == ERANGE) || (*endptr != '\0') || (val < 0) || (val > INT32_MAX)) { ParseError("Invalid argument to 'tag' rule option. " "Numbers must be between 0 and %d.", INT32_MAX); } count = (int)val; got_count = 1; } else { /* Check for src/dst/exclusive */ break; } } else { if (strcasecmp(toks[i], TAG_OPT__SECONDS) == 0) { if (metric & TAG_METRIC_SECONDS) ParseError("Can only configure seconds metric to tag rule option once"); if (!count) ParseError("Tag seconds metric must have a positive count"); metric |= TAG_METRIC_SECONDS; seconds = count; } else if (strcasecmp(toks[i], TAG_OPT__PACKETS) == 0) { if (metric & (TAG_METRIC_PACKETS|TAG_METRIC_UNLIMITED)) ParseError("Can only configure packets metric to tag rule option once"); if (count) metric |= TAG_METRIC_PACKETS; else metric |= TAG_METRIC_UNLIMITED; packets = count; } else if (strcasecmp(toks[i], TAG_OPT__BYTES) == 0) { if (metric & TAG_METRIC_BYTES) ParseError("Can only configure bytes metric to tag rule option once"); if (!count) ParseError("Tag bytes metric must have a positive count"); metric |= TAG_METRIC_BYTES; bytes = count; } else { ParseError("Invalid tag metric: %s", toks[i]); } got_count = 0; } } if ( got_count ) ParseError("Invalid tag rule option: %s", args); if ((metric & TAG_METRIC_UNLIMITED) && !(metric & (TAG_METRIC_BYTES|TAG_METRIC_SECONDS))) { ParseError("Invalid Tag options. 'packets' parameter '0' but " "neither seconds or bytes specified: %s", args); } if (i < num_toks) { if (type == TAG_HOST) { if (strcasecmp(toks[i], TAG_OPT__SRC) == 0) direction = TAG_HOST_SRC; else if (strcasecmp(toks[i], TAG_OPT__DST) == 0) direction = TAG_HOST_DST; else ParseError("Invalid 'tag:host' option: %s.", toks[i]); } else { if (strcasecmp(toks[i], TAG_OPT__EXCLUSIVE) == 0) metric |= TAG_METRIC_SESSION; else ParseError("Invalid 'tag:session' option: %s.", toks[i]); } i++; } else if (type == TAG_HOST) { ParseError("Tag host type must specify direction"); } if ( !metric || (i != num_toks) ) ParseError("Invalid 'tag' option: %s.", args); mSplitFree(&toks, num_toks); DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Set type: %d metric: %x count: %d\n", type, metric, count);); otn->tag = (TagData *)SnortAlloc(sizeof(TagData)); otn->tag->tag_type = type; otn->tag->tag_metric = metric; otn->tag->tag_seconds = seconds; otn->tag->tag_bytes = bytes; otn->tag->tag_packets = packets; otn->tag->tag_direction = direction; } /* Parse Threshold Rule option parameters for each RULE 'threshold: type limit|threshold|both, track by_src|by_dst, count #, seconds #;' */ static void ParseOtnThreshold(SnortConfig *sc, RuleTreeNode *rtn, OptTreeNode *otn, RuleType rtype, char *args) { int count_flag = 0; int seconds_flag = 0; int type_flag = 0; int tracking_flag = 0; char **toks; int num_toks; static THDX_STRUCT thdx; int i; static int warned = 0; const char* ERR_KEY = "rule threshold"; if (args == NULL) ParseError("Threshold rule option requires an argument."); if (!warned) { ParseWarning("threshold (in rule) is deprecated; " "use detection_filter instead.\n"); warned = 1; } memset(&thdx, 0, sizeof(THDX_STRUCT)); /* Make this lower than standalone threshold command defaults ??? */ thdx.priority = -1; toks = mSplit(args, ",", 0, &num_toks, 0); /* Parameter Check - enough args ?*/ if (num_toks != 4) { ParseError(ERR_PAIR_COUNT, 4); } for (i = 0; i < num_toks; i++) { char **pairs; int num_pairs; pairs = mSplit(toks[i], " \t", 0, &num_pairs, 0); if (num_pairs != 2) { ParseError(ERR_NOT_PAIRED); } if (strcasecmp(pairs[0], THRESHOLD_OPT__COUNT) == 0) { if ( count_flag++ ) { ParseError(ERR_EXTRA_OPTION); } thdx.count = xatoup(pairs[1],"threshold: count"); } else if (strcasecmp(pairs[0], THRESHOLD_OPT__SECONDS) == 0) { if ( seconds_flag++ ) { ParseError(ERR_EXTRA_OPTION); } thdx.seconds = xatoup(pairs[1],"threshold: seconds"); } else if (strcasecmp(pairs[0], THRESHOLD_OPT__TYPE) == 0) { if ( type_flag++ ) { ParseError(ERR_EXTRA_OPTION); } if (strcasecmp(pairs[1], THRESHOLD_TYPE__LIMIT) == 0) { thdx.type = THD_TYPE_LIMIT; } else if (strcasecmp(pairs[1], THRESHOLD_TYPE__THRESHOLD) == 0) { thdx.type = THD_TYPE_THRESHOLD; } else if (strcasecmp(pairs[1], THRESHOLD_TYPE__BOTH) == 0) { thdx.type = THD_TYPE_BOTH; } else { ParseError(ERR_BAD_VALUE); } } else if (strcasecmp(pairs[0], THRESHOLD_OPT__TRACK) == 0) { if ( tracking_flag++ ) { ParseError(ERR_EXTRA_OPTION); } if (strcasecmp(pairs[1], THRESHOLD_TRACK__BY_SRC) == 0) { thdx.tracking = THD_TRK_SRC; } else if (strcasecmp(pairs[1], THRESHOLD_TRACK__BY_DST) == 0) { thdx.tracking = THD_TRK_DST; } else { ParseError(ERR_BAD_VALUE); } } else { ParseError(ERR_BAD_OPTION); } mSplitFree(&pairs, num_pairs); } if ((count_flag + tracking_flag + type_flag + seconds_flag) != 4) { ParseError(ERR_BAD_ARG_COUNT); } mSplitFree(&toks, num_toks); /* Save this since we still need to add gid and sid */ thdx_tmp = &thdx; } static void CreateDefaultRules(SnortConfig *sc) { if (sc == NULL) return; CreateRuleType(sc, RULE_LIST_TYPE__PASS, RULE_TYPE__PASS, 0, &sc->Pass); /* changed on Jan 06 */ CreateRuleType(sc, RULE_LIST_TYPE__DROP, RULE_TYPE__DROP, 1, &sc->Drop); CreateRuleType(sc, RULE_LIST_TYPE__SDROP, RULE_TYPE__SDROP, 0, &sc->SDrop); CreateRuleType(sc, RULE_LIST_TYPE__REJECT, RULE_TYPE__REJECT, 1, &sc->Reject); CreateRuleType(sc, RULE_LIST_TYPE__ALERT, RULE_TYPE__ALERT, 1, &sc->Alert); CreateRuleType(sc, RULE_LIST_TYPE__LOG, RULE_TYPE__LOG, 1, &sc->Log); } static RuleType GetRuleType(char *arg) { if (arg == NULL) return RULE_TYPE__NONE; if (strcasecmp(arg, SNORT_CONF_KEYWORD__ALERT) == 0) return RULE_TYPE__ALERT; else if (strcasecmp(arg, SNORT_CONF_KEYWORD__DROP) == 0) return RULE_TYPE__DROP; else if (strcasecmp(arg, SNORT_CONF_KEYWORD__BLOCK) == 0) return RULE_TYPE__DROP; else if (strcasecmp(arg, SNORT_CONF_KEYWORD__LOG) == 0) return RULE_TYPE__LOG; else if (strcasecmp(arg, SNORT_CONF_KEYWORD__PASS) == 0) return RULE_TYPE__PASS; else if (strcasecmp(arg, SNORT_CONF_KEYWORD__REJECT) == 0) return RULE_TYPE__REJECT; else if (strcasecmp(arg, SNORT_CONF_KEYWORD__SDROP) == 0) return RULE_TYPE__SDROP; else if (strcasecmp(arg, SNORT_CONF_KEYWORD__SBLOCK) == 0) return RULE_TYPE__SDROP; return RULE_TYPE__NONE; } static void FreeRuleTreeNodes(SnortConfig *sc) { RuleTreeNode *rtn; OptTreeNode *otn; tSfPolicyId policyId; SFGHASH_NODE *hashNode; if (sc->otn_map == NULL) return; for (hashNode = sfghash_findfirst(sc->otn_map); hashNode; hashNode = sfghash_findnext(sc->otn_map)) { otn = (OptTreeNode *)hashNode->data; /* Autogenerated OTNs along with their respective pseudo RTN * will get cleaned up when the OTN is free'd */ if (otn->generated) continue; for (policyId = 0; policyId < otn->proto_node_num; policyId++) { rtn = getRtnFromOtn(otn, policyId); DestroyRuleTreeNode(rtn); otn->proto_nodes[policyId] = NULL; } } } static void FreeOutputLists(ListHead *list) { if (list->AlertList != NULL) FreeOutputList(list->AlertList); if (list->LogList != NULL) FreeOutputList(list->LogList); } void FreeRuleLists(SnortConfig *sc) { if (sc == NULL) return; FreeRuleTreeNodes(sc); FreeOutputLists(&sc->Drop); FreeOutputLists(&sc->SDrop); FreeOutputLists(&sc->Reject); FreeOutputLists(&sc->Alert); FreeOutputLists(&sc->Log); FreeOutputLists(&sc->Pass); FreeOutputLists(&sc->Activation); FreeOutputLists(&sc->Dynamic); /* Iterate through the user-defined types */ if (sc->rule_lists != NULL) { RuleListNode *node = sc->rule_lists; while (node != NULL) { RuleListNode *tmp = node; node = node->next; if ((tmp->RuleList != &sc->Drop) && (tmp->RuleList != &sc->SDrop) && (tmp->RuleList != &sc->Reject) && (tmp->RuleList != &sc->Alert) && (tmp->RuleList != &sc->Log) && (tmp->RuleList != &sc->Pass) && (tmp->RuleList != &sc->Activation) && (tmp->RuleList != &sc->Dynamic)) { FreeOutputLists(tmp->RuleList); free(tmp->RuleList); } if (tmp->name) free(tmp->name); free(tmp); } sc->rule_lists = NULL; } } static void port_entry_free(port_entry_t *pentry) { if (pentry->src_port != NULL) { free(pentry->src_port); pentry->src_port = NULL; } if (pentry->dst_port != NULL) { free(pentry->dst_port); pentry->dst_port = NULL; } if (pentry->protocol != NULL) { free(pentry->protocol); pentry->protocol = NULL; } } static int port_list_add_entry( port_list_t * plist, port_entry_t * pentry) { int ret; if( !plist ) { port_entry_free(pentry); return -1; } if( plist->pl_cnt >= plist->pl_max ) { port_entry_free(pentry); return -1; } ret = SafeMemcpy( &plist->pl_array[plist->pl_cnt], pentry, sizeof(port_entry_t), &plist->pl_array[plist->pl_cnt], (char*)(&plist->pl_array[plist->pl_cnt]) + sizeof(port_entry_t)); if (ret != SAFEMEM_SUCCESS) { ParseError("%s SafeMemcpy() Failed !!!", __FUNCTION__); return -1; } plist->pl_cnt++; return 0; } #if 0 static port_entry_t * port_list_get( port_list_t * plist, int index) { if( index < plist->pl_max ) { return &plist->pl_array[index]; } return NULL; } static void port_list_print( port_list_t * plist) { int i; for(i=0;ipl_cnt;i++) { LogMessage("rule %d { ", i); LogMessage(" gid %u sid %u",plist->pl_array[i].gid,plist->pl_array[i].sid ); LogMessage(" protocol %s", plist->pl_array[i].protocol); LogMessage(" dir %d",plist->pl_array[i].dir); LogMessage(" src_port %s dst_port %s ", plist->pl_array[i].src_port, plist->pl_array[i].dst_port ); LogMessage(" content %d", plist->pl_array[i].content); LogMessage(" uricontent %d", plist->pl_array[i].uricontent); LogMessage(" }\n"); } } #endif static void port_list_free( port_list_t * plist) { int i; for(i=0;ipl_cnt;i++) { port_entry_free(&plist->pl_array[i]); } plist->pl_cnt = 0; } /* Finish processing/setup Port Tables */ static void finish_portlist_table(FastPatternConfig *fp, char *s, PortTable *pt) { PortTableSortUniqRules(pt); if( fpDetectGetDebugPrintRuleGroupsUnCompiled(fp) ) { LogMessage("***\n***Port-Table : %s Ports/Rules-UnCompiled\n",s); PortTablePrintInputEx( pt, rule_index_map_print_index ); } PortTableCompile( pt ); if( fpDetectGetDebugPrintRuleGroupsCompiled(fp) ) { LogMessage("***\n***Port-Table : %s Ports/Rules-Compiled\n",s); PortTablePrintCompiledEx( pt, rule_index_map_print_index ); LogMessage("*** End of Compiled Group\n"); } } void rule_index_map_print_index( int index, char *buf, int bufsize ) { if( index < ruleIndexMap->num_rules ) { SnortSnprintfAppend(buf, bufsize, "%u:%u ", ruleIndexMap->map[index].gid, ruleIndexMap->map[index].sid); } } static rule_port_tables_t * PortTablesNew(void) { rule_port_tables_t *rpt = (rule_port_tables_t *)SnortAlloc(sizeof(rule_port_tables_t)); /* No content rule objects */ rpt->tcp_nocontent = PortObjectNew(); if (rpt->tcp_nocontent == NULL) ParseError("ParseRulesFile nocontent PortObjectNew() failed"); PortObjectAddPortAny(rpt->tcp_nocontent); rpt->udp_nocontent = PortObjectNew(); if (rpt->udp_nocontent == NULL) ParseError("ParseRulesFile nocontent PortObjectNew() failed"); PortObjectAddPortAny(rpt->udp_nocontent); rpt->icmp_nocontent = PortObjectNew(); if (rpt->icmp_nocontent == NULL) ParseError("ParseRulesFile nocontent PortObjectNew() failed"); PortObjectAddPortAny(rpt->icmp_nocontent); rpt->ip_nocontent = PortObjectNew(); if (rpt->ip_nocontent == NULL) ParseError("ParseRulesFile nocontent PortObjectNew() failed"); PortObjectAddPortAny(rpt->ip_nocontent); /* Create the Any-Any Port Objects for each protocol */ rpt->tcp_anyany = PortObjectNew(); if (rpt->tcp_anyany == NULL) ParseError("ParseRulesFile tcp any-any PortObjectNew() failed"); PortObjectAddPortAny(rpt->tcp_anyany); rpt->udp_anyany = PortObjectNew(); if (rpt->udp_anyany == NULL) ParseError("ParseRulesFile udp any-any PortObjectNew() failed"); PortObjectAddPortAny(rpt->udp_anyany); rpt->icmp_anyany = PortObjectNew(); if (rpt->icmp_anyany == NULL) ParseError("ParseRulesFile icmp any-any PortObjectNew() failed"); PortObjectAddPortAny(rpt->icmp_anyany); rpt->ip_anyany = PortObjectNew(); if (rpt->ip_anyany == NULL) ParseError("ParseRulesFile ip PortObjectNew() failed"); PortObjectAddPortAny(rpt->ip_anyany); /* Create the tcp Rules PortTables */ rpt->tcp_src = PortTableNew(); if (rpt->tcp_src == NULL) ParseError("ParseRulesFile tcp-src PortTableNew() failed"); rpt->tcp_dst = PortTableNew(); if (rpt->tcp_dst == NULL) ParseError("ParseRulesFile tcp-dst PortTableNew() failed"); /* Create the udp Rules PortTables */ rpt->udp_src = PortTableNew(); if (rpt->udp_src == NULL) ParseError("ParseRulesFile udp-src PortTableNew() failed"); rpt->udp_dst = PortTableNew(); if (rpt->udp_dst == NULL) ParseError("ParseRulesFile udp-dst PortTableNew() failed"); /* Create the icmp Rules PortTables */ rpt->icmp_src = PortTableNew(); if (rpt->icmp_src == NULL) ParseError("ParseRulesFile icmp-src PortTableNew() failed"); rpt->icmp_dst = PortTableNew(); if (rpt->icmp_dst == NULL) ParseError("ParseRulesFile icmp-dst PortTableNew() failed"); /* Create the ip Rules PortTables */ rpt->ip_src = PortTableNew(); if (rpt->ip_src == NULL) ParseError("ParseRulesFile ip-src PortTableNew() failed"); rpt->ip_dst = PortTableNew(); if (rpt->ip_dst == NULL) ParseError("ParseRulesFile ip-dst PortTableNew() failed"); /* * someday these could be read from snort.conf, something like... * 'config portlist: large-rule-count ' */ rpt->tcp_src->pt_lrc = DEFAULT_LARGE_RULE_GROUP; rpt->tcp_dst->pt_lrc = DEFAULT_LARGE_RULE_GROUP; rpt->udp_src->pt_lrc = DEFAULT_LARGE_RULE_GROUP; rpt->udp_dst->pt_lrc = DEFAULT_LARGE_RULE_GROUP; rpt->icmp_src->pt_lrc= DEFAULT_LARGE_RULE_GROUP; rpt->icmp_dst->pt_lrc= DEFAULT_LARGE_RULE_GROUP; rpt->ip_src->pt_lrc = DEFAULT_LARGE_RULE_GROUP; rpt->ip_dst->pt_lrc = DEFAULT_LARGE_RULE_GROUP; #ifndef TARGET_BASED // if TARGET_BASED is not enabled, ensure that these // port tables are NULL. rpt->ns_tcp_src = NULL; rpt->ns_tcp_dst = NULL; rpt->ns_udp_src = NULL; rpt->ns_udp_dst = NULL; rpt->ns_icmp_src = NULL; rpt->ns_icmp_dst = NULL; rpt->ns_ip_src = NULL; rpt->ns_ip_dst = NULL; #endif #ifdef TARGET_BASED // Create NOSERVICE port tables rpt->ns_tcp_src = PortTableNew(); if (rpt->ns_tcp_src == NULL) ParseError("ParseRulesFile tcp-src PortTableNew() failed"); rpt->ns_tcp_dst = PortTableNew(); if (rpt->ns_tcp_dst == NULL) ParseError("ParseRulesFile tcp-dst PortTableNew() failed"); /* Create the udp Rules PortTables */ rpt->ns_udp_src = PortTableNew(); if (rpt->ns_udp_src == NULL) ParseError("ParseRulesFile udp-src PortTableNew() failed"); rpt->ns_udp_dst = PortTableNew(); if (rpt->ns_udp_dst == NULL) ParseError("ParseRulesFile udp-dst PortTableNew() failed"); /* Create the icmp Rules PortTables */ rpt->ns_icmp_src = PortTableNew(); if (rpt->ns_icmp_src == NULL) ParseError("ParseRulesFile icmp-src PortTableNew() failed"); rpt->ns_icmp_dst = PortTableNew(); if (rpt->ns_icmp_dst == NULL) ParseError("ParseRulesFile icmp-dst PortTableNew() failed"); /* Create the ip Rules PortTables */ rpt->ns_ip_src = PortTableNew(); if (rpt->ns_ip_src == NULL) ParseError("ParseRulesFile ip-src PortTableNew() failed"); rpt->ns_ip_dst = PortTableNew(); if (rpt->ns_ip_dst == NULL) ParseError("ParseRulesFile ip-dst PortTableNew() failed"); rpt->ns_tcp_src->pt_lrc = DEFAULT_LARGE_RULE_GROUP; rpt->ns_tcp_dst->pt_lrc = DEFAULT_LARGE_RULE_GROUP; rpt->ns_udp_src->pt_lrc = DEFAULT_LARGE_RULE_GROUP; rpt->ns_udp_dst->pt_lrc = DEFAULT_LARGE_RULE_GROUP; rpt->ns_icmp_src->pt_lrc = DEFAULT_LARGE_RULE_GROUP; rpt->ns_icmp_dst->pt_lrc = DEFAULT_LARGE_RULE_GROUP; rpt->ns_ip_src->pt_lrc = DEFAULT_LARGE_RULE_GROUP; rpt->ns_ip_dst->pt_lrc = DEFAULT_LARGE_RULE_GROUP; #endif // TARGET_BASED return rpt; } static void PortTablesFinish(rule_port_tables_t *port_tables, FastPatternConfig *fp) { /* TCP-SRC */ if (fpDetectGetDebugPrintRuleGroupsCompiled(fp)) { LogMessage("*** TCP-Any-Any Port List\n"); PortObjectPrintEx(port_tables->tcp_anyany, rule_index_map_print_index); } finish_portlist_table(fp, "tcp src", port_tables->tcp_src); finish_portlist_table(fp, "tcp dst", port_tables->tcp_dst); /* UDP-SRC */ if (fpDetectGetDebugPrintRuleGroupsCompiled(fp)) { LogMessage("*** UDP-Any-Any Port List\n"); PortObjectPrintEx(port_tables->udp_anyany, rule_index_map_print_index); } finish_portlist_table(fp, "udp src", port_tables->udp_src); finish_portlist_table(fp, "udp dst", port_tables->udp_dst); /* ICMP-SRC */ if (fpDetectGetDebugPrintRuleGroupsCompiled(fp)) { LogMessage("*** ICMP-Any-Any Port List\n"); PortObjectPrintEx(port_tables->icmp_anyany, rule_index_map_print_index); } finish_portlist_table(fp, "icmp src", port_tables->icmp_src); finish_portlist_table(fp, "icmp dst", port_tables->icmp_dst); /* IP-SRC */ if (fpDetectGetDebugPrintRuleGroupsCompiled(fp)) { LogMessage("IP-Any-Any Port List\n"); PortObjectPrintEx(port_tables->ip_anyany, rule_index_map_print_index); } finish_portlist_table(fp, "ip src", port_tables->ip_src); finish_portlist_table(fp, "ip dst", port_tables->ip_dst); #ifdef TARGET_BASED // NOSERVICE Port Tables finish_portlist_table(fp, "tcp src noservice", port_tables->ns_tcp_src); finish_portlist_table(fp, "tcp dst noservice", port_tables->ns_tcp_dst); finish_portlist_table(fp, "udp src noservice", port_tables->ns_udp_src); finish_portlist_table(fp, "udp dst noservice", port_tables->ns_udp_dst); finish_portlist_table(fp, "icmp src noservice", port_tables->ns_icmp_src); finish_portlist_table(fp, "icmp dst noservice", port_tables->ns_icmp_dst); finish_portlist_table(fp, "ip src noservice", port_tables->ns_ip_src); finish_portlist_table(fp, "ip dst noservice", port_tables->ns_ip_dst); #endif // TARGET_BASED RuleListSortUniq(port_tables->tcp_anyany->rule_list); RuleListSortUniq(port_tables->udp_anyany->rule_list); RuleListSortUniq(port_tables->icmp_anyany->rule_list); RuleListSortUniq(port_tables->ip_anyany->rule_list); RuleListSortUniq(port_tables->tcp_nocontent->rule_list); RuleListSortUniq(port_tables->udp_nocontent->rule_list); RuleListSortUniq(port_tables->icmp_nocontent->rule_list); RuleListSortUniq(port_tables->ip_nocontent->rule_list); } void VarTablesFree(SnortConfig *sc) { tSfPolicyId i; if (sc == NULL) return; for (i = 0; i < sc->num_policies_allocated; i++) { SnortPolicy *p = sc->targeted_policies[i]; if (p == NULL) continue; if (p->var_table != NULL) { DeleteVars(p->var_table); p->var_table = NULL; } if (p->ip_vartable != NULL) { sfvt_free_table(p->ip_vartable); p->ip_vartable = NULL; } if (p->portVarTable != NULL) { PortVarTableFree(p->portVarTable); p->portVarTable = NULL; } if (p->nonamePortVarTable != NULL) { PortTableFree(p->nonamePortVarTable); p->nonamePortVarTable = NULL; } } } void PortTablesFree(rule_port_tables_t *port_tables) { if (port_tables == NULL) return; if (port_tables->tcp_src) PortTableFree(port_tables->tcp_src); if (port_tables->tcp_dst) PortTableFree(port_tables->tcp_dst); if (port_tables->udp_src) PortTableFree(port_tables->udp_src); if (port_tables->udp_dst) PortTableFree(port_tables->udp_dst); if (port_tables->icmp_src) PortTableFree(port_tables->icmp_src); if (port_tables->icmp_dst) PortTableFree(port_tables->icmp_dst); if (port_tables->ip_src) PortTableFree(port_tables->ip_src); if (port_tables->ip_dst) PortTableFree(port_tables->ip_dst); if (port_tables->tcp_anyany) PortObjectFree(port_tables->tcp_anyany); if (port_tables->udp_anyany) PortObjectFree(port_tables->udp_anyany); if (port_tables->icmp_anyany) PortObjectFree(port_tables->icmp_anyany); if (port_tables->ip_anyany) PortObjectFree(port_tables->ip_anyany); if (port_tables->tcp_nocontent) PortObjectFree(port_tables->tcp_nocontent); if (port_tables->udp_nocontent) PortObjectFree(port_tables->udp_nocontent); if (port_tables->icmp_nocontent) PortObjectFree(port_tables->icmp_nocontent); if (port_tables->ip_nocontent) PortObjectFree(port_tables->ip_nocontent); #ifdef TARGET_BASED if (port_tables->ns_tcp_src) PortTableFree(port_tables->ns_tcp_src); if (port_tables->ns_tcp_dst) PortTableFree(port_tables->ns_tcp_dst); if (port_tables->ns_udp_src) PortTableFree(port_tables->ns_udp_src); if (port_tables->ns_udp_dst) PortTableFree(port_tables->ns_udp_dst); if (port_tables->ns_icmp_src) PortTableFree(port_tables->ns_icmp_src); if (port_tables->ns_icmp_dst) PortTableFree(port_tables->ns_icmp_dst); if (port_tables->ns_ip_src) PortTableFree(port_tables->ns_ip_src); if (port_tables->ns_ip_dst) PortTableFree(port_tables->ns_ip_dst); #endif free(port_tables); } /**************************************************************************** * * Function: CreateRuleType * * Purpose: Creates a new type of rule and adds it to the end of the rule list * * Arguments: name = name of this rule type * mode = the mode for this rule type * rval = return value for this rule type (for detect events) * head = list head to use (or NULL to create a new one) * * Returns: the ListHead for the rule type * ***************************************************************************/ static ListHead * CreateRuleType(SnortConfig *sc, char *name, RuleType mode, int rval, ListHead *head) { RuleListNode *node; int evalIndex = 0; if (sc == NULL) return NULL; node = (RuleListNode *)SnortAlloc(sizeof(RuleListNode)); /* If this is the first rule list node, then we need to * create a new list. */ if (sc->rule_lists == NULL) { sc->rule_lists = node; } else { RuleListNode *tmp = sc->rule_lists; RuleListNode *last; do { /* We do not allow multiple rules types with the same name. */ if (strcasecmp(tmp->name, name) == 0) { free(node); return NULL; } evalIndex++; last = tmp; tmp = tmp->next; } while (tmp != NULL); last->next = node; } /* User defined rule type so we need to create a list head for it */ if (head == NULL) { node->RuleList = (ListHead *)SnortAlloc(sizeof(ListHead)); } else { /* Our default rules already have list heads */ node->RuleList = head; } node->RuleList->ruleListNode = node; node->mode = mode; node->rval = rval; node->name = SnortStrdup(name); node->evalIndex = evalIndex; sc->evalOrder[node->mode] = evalIndex; sc->num_rule_types++; return node->RuleList; } static void OtnInit(SnortConfig *sc) { if (sc == NULL) return; /* Don't initialize this more than once */ if ((sc->so_rule_otn_map != NULL) || (sc->otn_map != NULL)) return; /* Init sid-gid -> otn map */ sc->so_rule_otn_map = SoRuleOtnLookupNew(); if (sc->so_rule_otn_map == NULL) ParseError("ParseRulesFile so_otn_map sfghash_new failed.\n"); /* Init sid-gid -> otn map */ sc->otn_map = OtnLookupNew(); if (sc->otn_map == NULL) ParseError("ParseRulesFile otn_map sfghash_new failed.\n"); } #ifndef SOURCEFIRE #define IFACE_VARS_MAX 128 typedef struct iface_var { char name[128]; uint32_t net; uint32_t netmask; } iface_var_t; /**************************************************************************** * * Function : DefineAllIfaceVars() * Purpose : Find all up interfaces and define iface_ADDRESS vars for them * Arguments : none * Returns : void function * ****************************************************************************/ static void DefineAllIfaceVars(SnortConfig *sc) { /* Cache retrieved devs so if user is running with dropped privs and * does a reload, we can use previous values */ static int num_vars = 0; /* Should be more than enough to cover the number of * interfaces on a machine */ static iface_var_t iface_vars[IFACE_VARS_MAX]; if (num_vars > 0) { int i; for (i = 0; i < num_vars; i++) { DefineIfaceVar(sc, iface_vars[i].name, (uint8_t *)&iface_vars[i].net, (uint8_t *)&iface_vars[i].netmask); } } else { char errbuf[PCAP_ERRBUF_SIZE]; pcap_if_t *alldevs; pcap_if_t *dev; bpf_u_int32 net, netmask; #ifdef WIN32 int i = 1; #endif if (pcap_findalldevs(&alldevs, errbuf) == -1) return; for (dev = alldevs; dev != NULL; dev = dev->next) { if (pcap_lookupnet(dev->name, &net, &netmask, errbuf) == 0) { /* We've hit the maximum variables we can cache */ if (num_vars >= IFACE_VARS_MAX) break; #ifdef WIN32 /* For windows, define var as the index that it will be */ SnortSnprintf(iface_vars[num_vars].name, sizeof(iface_vars[num_vars].name), "%d", i); #else SnortSnprintf(iface_vars[num_vars].name, sizeof(iface_vars[num_vars].name), "%s", dev->name); #endif DefineIfaceVar(sc, iface_vars[num_vars].name, (uint8_t *)&net, (uint8_t *)&netmask); iface_vars[num_vars].net = net; iface_vars[num_vars].netmask = netmask; num_vars++; } #ifdef WIN32 i++; #endif } pcap_freealldevs(alldevs); } } /**************************************************************************** * * Function : DefineIfaceVar() * Purpose : Assign network address and network mask to IFACE_ADDR_VARNAME * variable. * Arguments : interface name (string) netaddress and netmask (4 octets each) * Returns : void function * ****************************************************************************/ static void DefineIfaceVar(SnortConfig *sc, char *iname, uint8_t *network, uint8_t *netmask) { char valbuf[32]; char varbuf[BUFSIZ]; if ((network == NULL) || (*network == 0)) return; SnortSnprintf(varbuf, BUFSIZ, "%s_ADDRESS", iname); SnortSnprintf(valbuf, 32, "%d.%d.%d.%d/%d.%d.%d.%d", network[0] & 0xff, network[1] & 0xff, network[2] & 0xff, network[3] & 0xff, netmask[0] & 0xff, netmask[1] & 0xff, netmask[2] & 0xff, netmask[3] & 0xff); VarDefine(sc, varbuf, valbuf); } #endif void PrintRuleOrder(RuleListNode *rule_lists) { printRuleListOrder(rule_lists); } /**************************************************************************** * * Function: OrderRuleLists * * Purpose: Orders the rule lists into the specefied order. * * Returns: void function * ***************************************************************************/ void OrderRuleLists(SnortConfig *sc, char *order) { int i; int evalIndex = 0; RuleListNode *ordered_list = NULL; RuleListNode *prev; RuleListNode *node; char **toks; int num_toks; toks = mSplit(order, " \t", 0, &num_toks, 0); for( i = 0; i < num_toks; i++ ) { prev = NULL; node = sc->rule_lists; while (node != NULL) { if (strcmp(toks[i], node->name) == 0) { if (prev == NULL) sc->rule_lists = node->next; else prev->next = node->next; /* Add node to ordered list */ ordered_list = addNodeToOrderedList(ordered_list, node, evalIndex++); sc->evalOrder[node->mode] = evalIndex; break; } else { prev = node; node = node->next; } } if( node == NULL ) { ParseError("Ruletype \"%s\" does not exist or " "has already been ordered.", toks[i]); } } mSplitFree(&toks, num_toks); /* anything left in the rule lists needs to be moved to the ordered lists */ while (sc->rule_lists != NULL) { node = sc->rule_lists; sc->rule_lists = node->next; /* Add node to ordered list */ ordered_list = addNodeToOrderedList(ordered_list, node, evalIndex++); sc->evalOrder[node->mode] = evalIndex; } /* set the rulelists to the ordered list */ sc->rule_lists = ordered_list; } static RuleListNode *addNodeToOrderedList(RuleListNode *ordered_list, RuleListNode *node, int evalIndex) { RuleListNode *prev; prev = ordered_list; /* set the eval order for this rule set */ node->evalIndex = evalIndex; if(!prev) { ordered_list = node; } else { while(prev->next) prev = prev->next; prev->next = node; } node->next = NULL; return ordered_list; } static void printRuleListOrder(RuleListNode * node) { char buf[STD_BUF]; RuleListNode *first_node = node; SnortSnprintf(buf, STD_BUF, "Rule application order: "); while( node != NULL ) { SnortSnprintfAppend(buf, STD_BUF, "%s%s", node == first_node ? "" : "->", node->name); node = node->next; } LogMessage("%s\n", buf); } NORETURN void ParseError(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 (file_name != NULL) FatalError("%s(%d) %s\n", file_name, file_line, buf); else FatalError("%s\n", buf); } void ParseWarning(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 (file_name != NULL) LogMessage("WARNING: %s(%d) %s\n", file_name, file_line, buf); else LogMessage("%s\n", buf); } void ParseMessage(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 (file_name != NULL) LogMessage("%s(%d) %s\n", file_name, file_line, buf); else LogMessage("%s\n", buf); } typedef struct _RuleTreeNodeKey { RuleTreeNode *rtn; tSfPolicyId policyId; } RuleTreeNodeKey; // RuleTreeNode *getRtnFromOtn() made in line /**Delete rtn from OTN. * * @param otn pointer to structure OptTreeNode. * @param policyId policy id * * @return pointer to deleted RTN, NULL otherwise. */ RuleTreeNode * deleteRtnFromOtn( SnortConfig *sc, OptTreeNode *otn, tSfPolicyId policyId ) { RuleTreeNode *rtn = NULL; if (otn->proto_nodes && (otn->proto_node_num >= (policyId+1))) { rtn = getRtnFromOtn(otn, policyId); otn->proto_nodes[policyId] = NULL; if (rtn) { RuleTreeNodeKey key; key.policyId = policyId; key.rtn = rtn; if (sc && sc->rtn_hash_table) { sfxhash_remove(sc->rtn_hash_table, &key); } } return rtn; } return NULL; } uint32_t rtn_hash_func(SFHASHFCN *p, unsigned char *k, int n) { uint32_t a,b,c; RuleTreeNodeKey* rtnk = (RuleTreeNodeKey *)k; RuleTreeNode *rtn = rtnk->rtn; a = rtn->type; b = rtn->flags; c = (uint32_t)(uintptr_t)rtn->listhead; mix(a,b,c); a += (uint32_t)(uintptr_t)rtn->src_portobject; b += (uint32_t)(uintptr_t)rtn->dst_portobject; c += (uint32_t)(uintptr_t)rtnk->policyId; final(a,b,c); return c; } int rtn_compare_func(const void *k1, const void *k2, size_t n) { RuleTreeNodeKey* rtnk1 = (RuleTreeNodeKey *)k1; RuleTreeNodeKey* rtnk2 = (RuleTreeNodeKey *)k2; if (!rtnk1 || !rtnk2) return 1; if (rtnk1->policyId != rtnk2->policyId) return 1; if (TestHeader( rtnk1->rtn, rtnk2->rtn)) return 0; else return 1; } /**Add RTN to OTN for a particular OTN. * @param otn pointer to structure OptTreeNode. * @param policyId policy id * @param rtn pointer to RuleTreeNode structure * * @return 0 if successful, * -ve otherwise */ int addRtnToOtn( SnortConfig *sc, OptTreeNode *otn, tSfPolicyId policyId, RuleTreeNode *rtn ) { RuleTreeNodeKey key; if (otn->proto_node_num <= policyId) { /* realloc the list, initialize missing elements to 0 and add * policyId */ RuleTreeNode **tmpNodeArray; unsigned int numNodes = (policyId + 1); tmpNodeArray = SnortAlloc(sizeof(RuleTreeNode *) * numNodes); /* copy original contents, the remaining elements are already * zeroed out by snortAlloc */ if (otn->proto_nodes) { memcpy(tmpNodeArray, otn->proto_nodes, sizeof(RuleTreeNode *) * otn->proto_node_num); free(otn->proto_nodes); } otn->proto_node_num = numNodes; otn->proto_nodes = tmpNodeArray; } //add policyId if (otn->proto_nodes[policyId]) { DestroyRuleTreeNode(rtn); return -1; } otn->proto_nodes[policyId] = rtn; // Optimized for parsing only, this check avoids adding run time rtn if (!sc) return 0; if (!sc->rtn_hash_table) { sc->rtn_hash_table = sfxhash_new(10000, sizeof(RuleTreeNodeKey), 0, 0, 0, NULL, NULL, 1); if (sc->rtn_hash_table == NULL) FatalError("Failed to create rule tree node hash table"); sfxhash_set_keyops(sc->rtn_hash_table, rtn_hash_func, rtn_compare_func); } key.policyId = policyId; key.rtn = rtn; sfxhash_add(sc->rtn_hash_table, &key, rtn); return 0; //success } // the presence of ip lists exceeds mSplit's one-level parsing // so we transform rule string into something that mSplit can // handle by changing ',' to c outside ip lists. // we also strip the leading keyword. char* FixSeparators (char* rule, char c, const char* err) { int list = 0; char* p = strchr(rule, c); if ( p && err ) { FatalError("%s(%d) => %s: '%c' not allowed in argument\n", file_name, file_line, err, c); } while ( isspace((int)*rule) ) rule++; p = rule; while ( *p ) { if ( *p == '[' ) list++; else if ( *p == ']' ) list--; else if ( *p == ',' && !list ) *p = c; p++; } return rule; } void GetNameValue (char* arg, char** nam, char** val, const char* err) { while ( isspace((int)*arg) ) arg++; *nam = arg; while ( *arg && !isspace((int)*arg) ) arg++; if ( *arg ) *arg++ = '\0'; *val = arg; if ( err && !**val ) { FatalError("%s(%d) => %s: name value pair expected: %s\n", file_name, file_line, err, *nam); } } static void IntegrityCheckRules(SnortConfig *sc) { OptFpList *ofl_idx = NULL; int opt_func_count; SFGHASH_NODE *hashNode = NULL; OptTreeNode *otn = NULL; tSfPolicyId policyId = 0; RuleTreeNode *rtn = NULL; for (hashNode = sfghash_findfirst(sc->otn_map); hashNode; hashNode = sfghash_findnext(sc->otn_map)) { otn = (OptTreeNode *)hashNode->data; for (policyId = 0; policyId < otn->proto_node_num; policyId++) { rtn = getRtnFromOtn(otn, policyId); if (!rtn) { continue; } if ((rtn->proto == IPPROTO_TCP) || (rtn->proto == IPPROTO_UDP) || (rtn->proto == IPPROTO_ICMP) || (rtn->proto == ETHERNET_TYPE_IP)) { //do operation ofl_idx = otn->opt_func; opt_func_count = 0; while(ofl_idx != NULL) { opt_func_count++; //DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "%p->",ofl_idx->OptTestFunc);); ofl_idx = ofl_idx->next; } if(opt_func_count == 0) { ParseError("Zero Length OTN List\n"); } //DEBUG_WRAP(DebugMessage(DEBUG_DETECT,"\n");); } } } //DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "OK\n");); } /**returns matched header node. */ static RuleTreeNode * findHeadNode(SnortConfig *sc, RuleTreeNode *testNode, tSfPolicyId policyId) { if (sc->rtn_hash_table) { RuleTreeNodeKey key; key.policyId = policyId; key.rtn = testNode; return ((RuleTreeNode *)sfxhash_find(sc->rtn_hash_table, &key)); } else return NULL; } void configOptsPrint() { int i; printf("Global policy only options\n"); for (i = 0; config_opts[i].name != NULL; i++) { if(config_opts[i].default_policy_only ) { printf("\t%s,\t%s\n", config_opts[i].name, config_opts[i].only_once ? "Once":""); } } printf("\nPolicy Specific options\n"); for (i = 0; config_opts[i].name != NULL; i++) { if(config_opts[i].default_policy_only == 0) { printf("\t%s,\t%s\n", config_opts[i].name, config_opts[i].only_once ? "Once":""); } } } SnortPolicy * SnortPolicyNew(void) { SnortPolicy *pPolicy = (SnortPolicy *)SnortAlloc(sizeof(SnortPolicy)); if (pPolicy) { // minimum possible (allows all but errors to pass by default) pPolicy->min_ttl = 1; #ifdef NORMALIZER pPolicy->new_ttl = 5; #endif /* Turn on all decoder alerts by default except for oversized alert. * Useful for bug reports ... */ pPolicy->decoder_alert_flags |= DECODE_EVENT_FLAG__DEFAULT; pPolicy->decoder_alert_flags |= DECODE_EVENT_FLAG__TCP_EXP_OPT; pPolicy->decoder_alert_flags |= DECODE_EVENT_FLAG__TCP_OBS_OPT; pPolicy->decoder_alert_flags |= DECODE_EVENT_FLAG__TCP_TTCP_OPT; pPolicy->decoder_alert_flags |= DECODE_EVENT_FLAG__TCP_OPT_ANOMALY; pPolicy->decoder_alert_flags |= DECODE_EVENT_FLAG__IP_OPT_ANOMALY; pPolicy->decoder_alert_flags |= DECODE_EVENT_FLAG__IPV6_BAD_FRAG; pPolicy->decoder_alert_flags |= DECODE_EVENT_FLAG__IPV6_BSD_ICMP_FRAG; pPolicy->decoder_drop_flags |= DECODE_EVENT_FLAG__IPV6_BAD_FRAG; pPolicy->checksum_flags = CHECKSUM_FLAG__ALL; memset( pPolicy->pp_enabled, 0, sizeof( PreprocEnableMask ) * MAX_PORTS ); } return pPolicy; } void SnortPolicyFree(SnortPolicy *pPolicy) { if (pPolicy == NULL) return; if (pPolicy->policy_version != NULL) free(pPolicy->policy_version); #ifdef TARGET_BASED if (pPolicy->target_based_config.args != NULL) { free(pPolicy->target_based_config.args); if (pPolicy->target_based_config.file_name != NULL) free(pPolicy->target_based_config.file_name); } #endif } /* Parse a boolean argument, with many ways to say "on" or "off". Arguments: char * arg => string argument to parse Returns: 1: Parsed a positive argument ("1", "on", "yes", "enable", "true") 0: Parsed a negative argument ("0", "off", "no", "disable", "false") -1: Error */ int ParseBool(char *arg) { if (arg == NULL) return -1; /* Trim leading whitespace */ while (isspace(*arg)) arg++; if ( (strcasecmp(arg, "1") == 0) || (strcasecmp(arg, "on") == 0) || (strcasecmp(arg, "yes") == 0) || (strcasecmp(arg, "enable") == 0) || (strcasecmp(arg, "true") == 0) ) return 1; if ( (strcasecmp(arg, "0") == 0) || (strcasecmp(arg, "off") == 0) || (strcasecmp(arg, "no") == 0) || (strcasecmp(arg, "disable") == 0) || (strcasecmp(arg, "false") == 0) ) return 0; /* Other values are invalid! */ return -1; } snort-2.9.15.1/src/parser.h0000644000175200017520000005103113571422607012304 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** Copyright (C) 2000-2001 Andrew R. Baker ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifndef __PARSER_H__ #define __PARSER_H__ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include "rules.h" #include "treenodes.h" #include "decode.h" #include "sflsq.h" #include "snort.h" #include "util.h" /* Macros *********************************************************************/ /* Rule keywords */ #define SNORT_CONF_KEYWORD__ACTIVATE "activate" #define SNORT_CONF_KEYWORD__ALERT "alert" #define SNORT_CONF_KEYWORD__DROP "drop" #define SNORT_CONF_KEYWORD__BLOCK "block" #define SNORT_CONF_KEYWORD__DYNAMIC "dynamic" #define SNORT_CONF_KEYWORD__LOG "log" #define SNORT_CONF_KEYWORD__PASS "pass" #define SNORT_CONF_KEYWORD__REJECT "reject" #define SNORT_CONF_KEYWORD__SDROP "sdrop" #define SNORT_CONF_KEYWORD__SBLOCK "sblock" /* Include keyword */ #define SNORT_CONF_KEYWORD__INCLUDE "include" /* Rest of the keywords */ #define SNORT_CONF_KEYWORD__ATTRIBUTE_TABLE "attribute_table" #define SNORT_CONF_KEYWORD__CONFIG "config" #define SNORT_CONF_KEYWORD__DYNAMIC_DETECTION "dynamicdetection" #define SNORT_CONF_KEYWORD__DYNAMIC_ENGINE "dynamicengine" #define SNORT_CONF_KEYWORD__DYNAMIC_PREPROC "dynamicpreprocessor" #define SNORT_CONF_KEYWORD__DYNAMIC_OUTPUT "dynamicoutput" #ifdef SIDE_CHANNEL # define SNORT_CONF_KEYWORD__DYNAMIC_SIDE_CHAN "dynamicsidechannel" #endif #define SNORT_CONF_KEYWORD__EVENT_FILTER "event_filter" # define SNORT_CONF_KEYWORD__IPVAR "ipvar" #define SNORT_CONF_KEYWORD__OUTPUT "output" #define SNORT_CONF_KEYWORD__PORTVAR "portvar" #define SNORT_CONF_KEYWORD__PREPROCESSOR "preprocessor" #define SNORT_CONF_KEYWORD__RATE_FILTER "rate_filter" #define SNORT_CONF_KEYWORD__RULE_STATE "rule_state" #define SNORT_CONF_KEYWORD__RULE_TYPE "ruletype" #ifdef SIDE_CHANNEL # define SNORT_CONF_KEYWORD__SIDE_CHANNEL "sidechannel" #endif #define SNORT_CONF_KEYWORD__SUPPRESS "suppress" #define SNORT_CONF_KEYWORD__THRESHOLD "threshold" #define SNORT_CONF_KEYWORD__VAR "var" #define SNORT_CONF_KEYWORD__VERSION "version" #define SNORT_CONF_KEYWORD__FILE "file" /* Config options */ #define CONFIG_OPT__ALERT_FILE "alertfile" #define CONFIG_OPT__ALERT_WITH_IFACE_NAME "alert_with_interface_name" #define CONFIG_OPT__AUTOGEN_PREPROC_DECODER_RULES "autogenerate_preprocessor_decoder_rules" #define CONFIG_OPT__ASN1 "asn1" #define CONFIG_OPT__BINDING "binding" #define CONFIG_OPT__BPF_FILE "bpf_file" #define CONFIG_OPT__CHECKSUM_DROP "checksum_drop" #define CONFIG_OPT__CHECKSUM_MODE "checksum_mode" #define CONFIG_OPT__CHROOT_DIR "chroot" #define CONFIG_OPT__CLASSIFICATION "classification" #define CONFIG_OPT__DAEMON "daemon" #define CONFIG_OPT__DECODE_DATA_LINK "decode_data_link" #define CONFIG_OPT__DECODE_ESP "decode_esp" #define CONFIG_OPT__DEFAULT_RULE_STATE "default_rule_state" #define CONFIG_OPT__DETECTION "detection" #define CONFIG_OPT__DETECTION_FILTER "detection_filter" #define CONFIG_OPT__PROTECTED_CONTENT "protected_content" #ifdef INLINE_FAILOPEN # define CONFIG_OPT__DISABLE_INLINE_FAILOPEN "disable_inline_init_failopen" #endif #define CONFIG_OPT__DISABLE_DECODE_ALERTS "disable_decode_alerts" #define CONFIG_OPT__DISABLE_DECODE_DROPS "disable_decode_drops" #define CONFIG_OPT__DISABLE_IP_OPT_ALERTS "disable_ipopt_alerts" #define CONFIG_OPT__DISABLE_IP_OPT_DROPS "disable_ipopt_drops" #define CONFIG_OPT__DISABLE_TCP_OPT_ALERTS "disable_tcpopt_alerts" #define CONFIG_OPT__DISABLE_TCP_OPT_DROPS "disable_tcpopt_drops" #define CONFIG_OPT__DISABLE_TCP_OPT_EXP_ALERTS "disable_tcpopt_experimental_alerts" #define CONFIG_OPT__DISABLE_TCP_OPT_EXP_DROPS "disable_tcpopt_experimental_drops" #define CONFIG_OPT__DISABLE_TCP_OPT_OBS_ALERTS "disable_tcpopt_obsolete_alerts" #define CONFIG_OPT__DISABLE_TCP_OPT_OBS_DROPS "disable_tcpopt_obsolete_drops" #define CONFIG_OPT__DISABLE_TTCP_ALERTS "disable_ttcp_alerts" #define CONFIG_OPT__DISABLE_TCP_OPT_TTCP_ALERTS "disable_tcpopt_ttcp_alerts" #define CONFIG_OPT__DISABLE_TTCP_DROPS "disable_ttcp_drops" #define CONFIG_OPT__DUMP_CHARS_ONLY "dump_chars_only" #define CONFIG_OPT__DUMP_PAYLOAD "dump_payload" #define CONFIG_OPT__DUMP_PAYLOAD_VERBOSE "dump_payload_verbose" #define CONFIG_OPT__ENABLE_DECODE_DROPS "enable_decode_drops" #define CONFIG_OPT__ENABLE_DECODE_OVERSIZED_ALERTS "enable_decode_oversized_alerts" #define CONFIG_OPT__ENABLE_DECODE_OVERSIZED_DROPS "enable_decode_oversized_drops" #define CONFIG_OPT__ENABLE_DEEP_TEREDO_INSPECTION "enable_deep_teredo_inspection" #define CONFIG_OPT__ENABLE_GTP_DECODING "enable_gtp" #define CONFIG_OPT__ENABLE_IP_OPT_DROPS "enable_ipopt_drops" #ifdef MPLS # define CONFIG_OPT__ENABLE_MPLS_MULTICAST "enable_mpls_multicast" # define CONFIG_OPT__ENABLE_MPLS_OVERLAPPING_IP "enable_mpls_overlapping_ip" #endif /* MPLS */ #define CONFIG_OPT__ENABLE_TCP_OPT_DROPS "enable_tcpopt_drops" #define CONFIG_OPT__ENABLE_TCP_OPT_EXP_DROPS "enable_tcpopt_experimental_drops" #define CONFIG_OPT__ENABLE_TCP_OPT_OBS_DROPS "enable_tcpopt_obsolete_drops" #define CONFIG_OPT__ENABLE_TTCP_DROPS "enable_ttcp_drops" #define CONFIG_OPT__ENABLE_TCP_OPT_TTCP_DROPS "enable_tcpopt_ttcp_drops" #define CONFIG_OPT__EVENT_FILTER "event_filter" #define CONFIG_OPT__EVENT_QUEUE "event_queue" #define CONFIG_OPT__EVENT_TRACE "event_trace" # define CONFIG_OPT__REACT "react" #ifdef ENABLE_RESPONSE3 # define CONFIG_OPT__FLEXRESP2_INTERFACE "flexresp2_interface" # define CONFIG_OPT__FLEXRESP2_ATTEMPTS "flexresp2_attempts" # define CONFIG_OPT__FLEXRESP2_MEMCAP "flexresp2_memcap" # define CONFIG_OPT__FLEXRESP2_ROWS "flexresp2_rows" #endif // ENABLE_RESPONSE3 #ifdef ACTIVE_RESPONSE # define CONFIG_OPT__RESPONSE "response" #endif #define CONFIG_OPT__FLOWBITS_SIZE "flowbits_size" #define CONFIG_OPT__IGNORE_PORTS "ignore_ports" #define CONFIG_OPT__ALERT_VLAN "include_vlan_in_alerts" #define CONFIG_OPT__INTERFACE "interface" #define CONFIG_OPT__IPV6_FRAG "ipv6_frag" #define CONFIG_OPT__LAYER2RESETS "layer2resets" #define CONFIG_OPT__LOG_DIR "logdir" #define CONFIG_OPT__DAQ_TYPE "daq" #define CONFIG_OPT__DAQ_MODE "daq_mode" #define CONFIG_OPT__DAQ_VAR "daq_var" #define CONFIG_OPT__DAQ_DIR "daq_dir" #define CONFIG_OPT__DIRTY_PIG "dirty_pig" #ifdef TARGET_BASED # define CONFIG_OPT__MAX_ATTRIBUTE_HOSTS "max_attribute_hosts" # define CONFIG_OPT__MAX_ATTRIBUTE_SERVICES_PER_HOST "max_attribute_services_per_host" # define CONFIG_OPT__MAX_METADATA_SERVICES "max_metadata_services" #define CONFIG_OPT__DISABLE_ATTRIBUTE_RELOAD "disable-attribute-reload-thread" #endif /* TARGET_BASED */ #ifdef MPLS # define CONFIG_OPT__MAX_MPLS_LABELCHAIN_LEN "max_mpls_labelchain_len" # define CONFIG_OPT__MPLS_PAYLOAD_TYPE "mpls_payload_type" #endif /* MPLS */ #define CONFIG_OPT__MIN_TTL "min_ttl" #ifdef NORMALIZER #define CONFIG_OPT__NEW_TTL "new_ttl" #endif #define CONFIG_OPT__NO_LOG "nolog" #define CONFIG_OPT__NO_PCRE "nopcre" #define CONFIG_OPT__NO_PROMISCUOUS "no_promisc" #define CONFIG_OPT__OBFUSCATE "obfuscate" #define CONFIG_OPT__ORDER "order" #define CONFIG_OPT__PAF_MAX "paf_max" #define CONFIG_OPT__PCRE_MATCH_LIMIT "pcre_match_limit" #define CONFIG_OPT__PCRE_MATCH_LIMIT_RECURSION "pcre_match_limit_recursion" #define CONFIG_OPT__PKT_COUNT "pkt_count" #define CONFIG_OPT__PKT_SNAPLEN "snaplen" #define CONFIG_OPT__PID_PATH "pidpath" #define CONFIG_OPT__POLICY "policy_id" #define CONFIG_OPT__IPS_POLICY_MODE "policy_mode" #define CONFIG_OPT__NAP_POLICY_MODE "na_policy_mode" #define CONFIG_OPT__POLICY_VERSION "policy_version" #ifdef PPM_MGR # define CONFIG_OPT__PPM "ppm" #endif #ifdef PERF_PROFILING # define CONFIG_OPT__PROFILE_PREPROCS "profile_preprocs" # define CONFIG_OPT__PROFILE_RULES "profile_rules" #endif /* PERF_PROFILING */ #define CONFIG_OPT__QUIET "quiet" #define CONFIG_OPT__RATE_FILTER "rate_filter" #define CONFIG_OPT__REFERENCE "reference" #define CONFIG_OPT__REFERENCE_NET "reference_net" #define CONFIG_OPT__SET_GID "set_gid" #define CONFIG_OPT__SET_UID "set_uid" #define CONFIG_OPT__SHOW_YEAR "show_year" #define CONFIG_OPT__SO_RULE_MEMCAP "so_rule_memcap" #define CONFIG_OPT__STATEFUL "stateful" #define CONFIG_OPT__TAGGED_PACKET_LIMIT "tagged_packet_limit" #define CONFIG_OPT__THRESHOLD "threshold" #define CONFIG_OPT__UMASK "umask" #define CONFIG_OPT__UTC "utc" #define CONFIG_OPT__VERBOSE "verbose" #define CONFIG_OPT__VLAN_AGNOSTIC "vlan_agnostic" #define CONFIG_OPT__ADDRESSSPACE_AGNOSTIC "addressspace_agnostic" #define CONFIG_OPT__LOG_IPV6_EXTRA "log_ipv6_extra_data" #define CONFIG_OPT__DUMP_DYNAMIC_RULES_PATH "dump-dynamic-rules-path" #define CONFIG_OPT__CONTROL_SOCKET_DIR "cs_dir" #define CONFIG_OPT__FILE "file" #define CONFIG_OPT__TUNNEL_BYPASS "tunnel_verdicts" #ifdef SIDE_CHANNEL # define CONFIG_OPT__SIDE_CHANNEL "sidechannel" #endif #define CONFIG_OPT__MAX_IP6_EXTENSIONS "max_ip6_extensions" #define CONFIG_OPT__DISABLE_REPLACE "disable_replace" #ifdef DUMP_BUFFER #define CONFIG_OPT__BUFFER_DUMP "buffer_dump" #define CONFIG_OPT__BUFFER_DUMP_ALERT "buffer_dump_alert" #endif /* exported values */ extern char *file_name; extern int file_line; /* rule setup funcs */ SnortConfig * ParseSnortConf(void); void ParseRules(SnortConfig *); void ParseOutput(SnortConfig *, SnortPolicy *, char *); void OrderRuleLists(SnortConfig *, char *); void PrintRuleOrder(RuleListNode *); char * VarGet(SnortConfig *, char *); char * ProcessFileOption(SnortConfig *, const char *); void SetRuleStates(SnortConfig *); int GetPcaps(SF_LIST *, SF_QUEUE *); void ParserCleanup(void); void FreeRuleLists(SnortConfig *); void VarTablesFree(SnortConfig *); void PortTablesFree(rule_port_tables_t *); int CompareIPNodes(IpAddrNode *, IpAddrNode *); void ResolveOutputPlugins(SnortConfig *, SnortConfig *); void ConfigureOutputPlugins(SnortConfig *); void ConfigurePreprocessors(SnortConfig *, int); void ConfigureSideChannelModules(SnortConfig *); NORETURN void ParseError(const char *, ...); void ParseWarning(const char *, ...); void ParseMessage(const char *, ...); void ConfigAlertBeforePass(SnortConfig *, char *); void ConfigAlertFile(SnortConfig *, char *); void ConfigAlertWithInterfaceName(SnortConfig *, char *); void ConfigAsn1(SnortConfig *, char *); void ConfigAutogenPreprocDecoderRules(SnortConfig *, char *); void ConfigBinding(SnortConfig *, char *); void ConfigBpfFile(SnortConfig *, char *); void ConfigChecksumDrop(SnortConfig *, char *); void ConfigChecksumMode(SnortConfig *, char *); void ConfigChrootDir(SnortConfig *, char *); void ConfigClassification(SnortConfig *, char *); void ConfigCreatePidFile(SnortConfig *, char *); void ConfigDaemon(SnortConfig *, char *); void ConfigDecodeDataLink(SnortConfig *, char *); void ConfigDefaultRuleState(SnortConfig *, char *); void ConfigDetection(SnortConfig *, char *); void ConfigDetectionFilter(SnortConfig *, char *); void ConfigDisableDecodeAlerts(SnortConfig *, char *); void ConfigDisableDecodeDrops(SnortConfig *, char *); #ifdef INLINE_FAILOPEN void ConfigDisableInlineFailopen(SnortConfig *, char *); #endif void ConfigDisableIpOptAlerts(SnortConfig *, char *); void ConfigDisableIpOptDrops(SnortConfig *, char *); void ConfigDisableTcpOptAlerts(SnortConfig *, char *); void ConfigDisableTcpOptDrops(SnortConfig *, char *); void ConfigDisableTcpOptExperimentalAlerts(SnortConfig *, char *); void ConfigDisableTcpOptExperimentalDrops(SnortConfig *, char *); void ConfigDisableTcpOptObsoleteAlerts(SnortConfig *, char *); void ConfigDisableTcpOptObsoleteDrops(SnortConfig *, char *); void ConfigDisableTTcpAlerts(SnortConfig *, char *); void ConfigDisableTTcpDrops(SnortConfig *, char *); void ConfigDumpCharsOnly(SnortConfig *, char *); void ConfigDumpPayload(SnortConfig *, char *); void ConfigDumpPayloadVerbose(SnortConfig *, char *); void ConfigEnableDecodeDrops(SnortConfig *, char *); void ConfigEnableDecodeOversizedAlerts(SnortConfig *, char *); void ConfigEnableDecodeOversizedDrops(SnortConfig *, char *); void ConfigEnableDeepTeredoInspection(SnortConfig *sc, char *args); void ConfigEnableGTPDecoding(SnortConfig *sc, char *args); void ConfigEnableEspDecoding(SnortConfig *sc, char *args); void ConfigEnableIpOptDrops(SnortConfig *, char *); #ifdef MPLS void ConfigEnableMplsMulticast(SnortConfig *, char *); void ConfigEnableMplsOverlappingIp(SnortConfig *, char *); #endif void ConfigEnableTcpOptDrops(SnortConfig *, char *); void ConfigEnableTcpOptExperimentalDrops(SnortConfig *, char *); void ConfigEnableTcpOptObsoleteDrops(SnortConfig *, char *); void ConfigEnableTTcpDrops(SnortConfig *, char *); void ConfigEventFilter(SnortConfig *, char *); void ConfigEventQueue(SnortConfig *, char *); void ConfigEventTrace(SnortConfig *, char *); #ifdef ENABLE_RESPONSE3 void ConfigFlexresp2Interface(SnortConfig *, char *); void ConfigFlexresp2Attempts(SnortConfig *, char *); void ConfigFlexresp2Memcap(SnortConfig *, char *); void ConfigFlexresp2Rows(SnortConfig *, char *); #endif #ifdef ACTIVE_RESPONSE void ConfigResponse(SnortConfig*, char*); #endif void ConfigReact(SnortConfig*, char*); void ConfigFlowbitsSize(SnortConfig *, char *); void ConfigIgnorePorts(SnortConfig *, char *); void ConfigIncludeVlanInAlert(SnortConfig *, char *); void ConfigInterface(SnortConfig *, char *); void ConfigIpv6Frag(SnortConfig *, char *); void ConfigLayer2Resets(SnortConfig *, char *); void ConfigLogDir(SnortConfig *, char *); void ConfigDaqType(SnortConfig *, char *); void ConfigDaqMode(SnortConfig *, char *); void ConfigDaqVar(SnortConfig *, char *); void ConfigDaqDir(SnortConfig *, char *); void ConfigDirtyPig(SnortConfig *, char *); #ifdef TARGET_BASED void ConfigMaxAttributeHosts(SnortConfig *, char *); void ConfigMaxAttributeServicesPerHost(SnortConfig *, char *); void ConfigMaxMetadataServices(SnortConfig *, char *); void ConfigDisableAttributeReload(SnortConfig *, char *); #endif #ifdef MPLS void ConfigMaxMplsLabelChain(SnortConfig *, char *); void ConfigMplsPayloadType(SnortConfig *, char *); #endif void ConfigMinTTL(SnortConfig *, char *); #ifdef NORMALIZER void ConfigNewTTL(SnortConfig *, char *); #endif void ConfigNoLog(SnortConfig *, char *); void ConfigNoLoggingTimestamps(SnortConfig *, char *); void ConfigNoPcre(SnortConfig *, char *); void ConfigNoPromiscuous(SnortConfig *, char *); void ConfigObfuscate(SnortConfig *, char *); void ConfigObfuscationMask(SnortConfig *, char *); void ConfigPafMax(SnortConfig *, char *); void ConfigRateFilter(SnortConfig *, char *); void ConfigRuleListOrder(SnortConfig *, char *); void ConfigPacketCount(SnortConfig *, char *); void ConfigPacketSnaplen(SnortConfig *, char *); void ConfigPcreMatchLimit(SnortConfig *, char *); void ConfigPcreMatchLimitRecursion(SnortConfig *, char *); void ConfigPerfFile(SnortConfig *sc, char *); void ConfigPidPath(SnortConfig *, char *); void ConfigPolicy(SnortConfig *, char *); void ConfigIpsPolicyMode(SnortConfig *, char *); void ConfigNapPolicyMode(SnortConfig *, char *); void ConfigPolicyVersion(SnortConfig *, char *); void ConfigProtectedContent(SnortConfig *, char *); #ifdef PPM_MGR void ConfigPPM(SnortConfig *, char *); #endif void ConfigProcessAllEvents(SnortConfig *, char *); #ifdef PERF_PROFILING void ConfigProfilePreprocs(SnortConfig *, char *); void ConfigProfileRules(SnortConfig *, char *); #endif void ConfigQuiet(SnortConfig *, char *); void ConfigReadPcapFile(SnortConfig *, char *); void ConfigReference(SnortConfig *, char *); void ConfigReferenceNet(SnortConfig *, char *); void ConfigSetGid(SnortConfig *, char *); void ConfigSetUid(SnortConfig *, char *); void ConfigShowYear(SnortConfig *, char *); void ConfigSoRuleMemcap(SnortConfig *, char *); void ConfigStateful(SnortConfig *, char *); void ConfigTaggedPacketLimit(SnortConfig *, char *); void ConfigThreshold(SnortConfig *, char *); #ifdef TIMESTATS void ConfigTimestatsInterval(SnortConfig *, char *); #endif void ConfigTreatDropAsAlert(SnortConfig *, char *); void ConfigTreatDropAsIgnore(SnortConfig *, char *); void ConfigUmask(SnortConfig *, char *); void ConfigUtc(SnortConfig *, char *); void ConfigVerbose(SnortConfig *, char *); void ConfigVlanAgnostic(SnortConfig *, char *); void ConfigAddressSpaceAgnostic(SnortConfig *, char *); void ConfigLogIPv6Extra(SnortConfig *, char *); void ConfigDumpDynamicRulesPath(SnortConfig *, char *); void ConfigControlSocketDirectory(SnortConfig *, char *); void ConfigFile(SnortConfig *, char *); void ConfigTunnelVerdicts(SnortConfig*, char*); void ConfigMaxIP6Extensions(SnortConfig *, char*); void ConfigDisableReplace(SnortConfig *, char*); #ifdef DUMP_BUFFER void ConfigBufferDump(SnortConfig *, char *); #endif int addRtnToOtn( SnortConfig *sc, OptTreeNode *otn, tSfPolicyId policyId, RuleTreeNode *rtn ); RuleTreeNode* deleteRtnFromOtn( SnortConfig *sc, OptTreeNode *otn, tSfPolicyId policyId ); // use this so mSplit doesn't split IP lists (try c = ';') char* FixSeparators (char* rule, char c, const char* err); // use this as an alternative to mSplit when you just want name, value void GetNameValue (char* arg, char** nam, char** val, const char* err); /*Get RTN for a given OTN and policyId. * * @param otn pointer to structure OptTreeNode. * @param policyId policy id * * @return pointer to deleted RTN, NULL otherwise. */ static inline RuleTreeNode *getRtnFromOtn(OptTreeNode *otn, tSfPolicyId policyId) { if (otn && otn->proto_nodes && (otn->proto_node_num > (unsigned)policyId)) { return otn->proto_nodes[policyId]; } return NULL; } /**Get rtn from otn for the current policy. */ static inline RuleTreeNode *getParserRtnFromOtn(SnortConfig *sc, OptTreeNode *otn) { return getRtnFromOtn(otn, getParserPolicy(sc)); } static inline RuleTreeNode *getRuntimeRtnFromOtn(OptTreeNode *otn) { return getRtnFromOtn(otn, getIpsRuntimePolicy()); } SnortPolicy * SnortPolicyNew(void); void SnortPolicyFree(SnortPolicy *pPolicy); #endif /* __PARSER_H__ */ snort-2.9.15.1/src/profiler.c0000644000175200017520000007222613571422607012636 00000000000000/* ** $Id$ ** ** profiler.c ** ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2005-2013 Sourcefire, Inc. ** Steven Sturges ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** */ #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "snort.h" #include "rules.h" #include "treenodes.h" #include "treenodes.h" #include "parser.h" #include "plugin_enum.h" #include "util.h" #include "rules.h" #include "treenodes.h" #include "treenodes.h" #include "profiler.h" #include "sf_types.h" #include "sf_textlog.h" #include "detection_options.h" #ifdef PERF_PROFILING /* Data types *****************************************************************/ typedef struct _OTN_WorstPerformer { OptTreeNode *otn; struct _OTN_WorstPerformer *next; struct _OTN_WorstPerformer *prev; double ticks_per_check; double ticks_per_match; double ticks_per_nomatch; } OTN_WorstPerformer; typedef struct _Preproc_WorstPerformer { PreprocStatsNode *node; struct _Preproc_WorstPerformer *next; struct _Preproc_WorstPerformer *prev; struct _Preproc_WorstPerformer *children; double ticks_per_check; double pct_of_parent; double pct_of_total; } Preproc_WorstPerformer; /* Globals ********************************************************************/ double ticks_per_microsec = 0.0; OTN_WorstPerformer *worstPerformers = NULL; Preproc_WorstPerformer *worstPreprocPerformers = NULL; PreprocStats totalPerfStats; PreprocStats metaPerfStats; static PreprocStatsNode * PreprocStatsNodeList = NULL; int max_layers = 0; /* Externs ********************************************************************/ extern PreprocStats mpsePerfStats, rulePerfStats, ncrulePerfStats; void getTicksPerMicrosec(void) { if (ticks_per_microsec == 0.0) { ticks_per_microsec = get_ticks_per_usec(); } } void ResetRuleProfiling(void) { /* Cycle through all Rules, print ticks & check count for each */ RuleTreeNode *rtn; SFGHASH_NODE *hashNode; OptTreeNode *otn = NULL; tSfPolicyId policyId = 0; SnortConfig *sc = snort_conf; if ((sc == NULL) || (sc->profile_rules.num == 0)) return; for (hashNode = sfghash_findfirst(sc->otn_map); hashNode; hashNode = sfghash_findnext(sc->otn_map)) { otn = (OptTreeNode *)hashNode->data; for ( policyId = 0; policyId < otn->proto_node_num; policyId++ ) { rtn = getRtnFromOtn(otn, policyId); if (rtn == NULL) continue; if ((rtn->proto == IPPROTO_TCP) || (rtn->proto == IPPROTO_UDP) || (rtn->proto == IPPROTO_ICMP) || (rtn->proto == ETHERNET_TYPE_IP)) { //do operation otn->ticks = 0; otn->ticks_match = 0; otn->ticks_no_match = 0; otn->checks = 0; otn->matches = 0; otn->alerts = 0; otn->noalerts = 0; #ifdef PPM_MGR otn->ppm_disable_cnt = 0; #endif } } } } void PrintWorstRules(int numToPrint) { OptTreeNode *otn; OTN_WorstPerformer *node, *tmp; int num = 0; TextLog *log = NULL; time_t cur_time; char fullname[STD_BUF]; int ret; SnortConfig *sc = snort_conf; if (sc == NULL) return; getTicksPerMicrosec(); cur_time = time(NULL); if (sc->profile_rules.filename != NULL) { if (sc->profile_rules.append) { log = TextLog_Init(sc->profile_rules.filename, 512*1024, 512*1024); if (log != NULL) TextLog_Print(log, "\ntimestamp: %u\n", cur_time); } else { ret = SnortSnprintf(fullname, STD_BUF, "%s.%u", sc->profile_rules.filename, (uint32_t)cur_time); if(ret != SNORT_SNPRINTF_SUCCESS) FatalError("profiler: file path+name too long\n"); log = TextLog_Init(fullname, 512*1024, 512*1024); } } if (numToPrint != -1) { if(log) { TextLog_Print(log, "Rule Profile Statistics (worst %d rules)\n", numToPrint); } else { LogMessage("Rule Profile Statistics (worst %d rules)\n", numToPrint); } } else { if(log) { TextLog_Print(log, "Rule Profile Statistics (all rules)\n"); } else { LogMessage("Rule Profile Statistics (all rules)\n"); } } if(log) { TextLog_Print(log, "==========================================================\n"); } else { LogMessage("==========================================================\n"); } if (!worstPerformers) { if(log) { TextLog_Print(log, "No rules were profiled\n"); TextLog_Term(log); } else { LogMessage("No rules were profiled\n"); } return; } if(log) { TextLog_Print(log, #ifdef PPM_MGR "%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s\n", #else "%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s\n", #endif 6, "Num", 9, "SID", 4, "GID", 4, "Rev", 11, "Checks", 10, "Matches", 10, "Alerts", 20, "Microsecs", 11, "Avg/Check", 11, "Avg/Match", 13, "Avg/Nonmatch" #ifdef PPM_MGR , 11, "Disabled" #endif ); } else { LogMessage( #ifdef PPM_MGR "%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s\n", #else "%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s\n", #endif 6, "Num", 9, "SID", 4, "GID", 4, "Rev", 11, "Checks", 10, "Matches", 10, "Alerts", 20, "Microsecs", 11, "Avg/Check", 11, "Avg/Match", 13, "Avg/Nonmatch" #ifdef PPM_MGR , 11, "Disabled" #endif ); } if(log) { TextLog_Print(log, #ifdef PPM_MGR "%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s\n", #else "%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s\n", #endif 6, "===", 9, "===", 4, "===", 4, "===", 11, "======", 10, "=======", 10, "======", 20, "=========", 11, "=========", 11, "=========", 13, "============" #ifdef PPM_MGR , 11, "========" #endif ); } else { LogMessage( #ifdef PPM_MGR "%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s\n", #else "%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s\n", #endif 6, "===", 9, "===", 4, "===", 4, "===", 11, "======", 10, "=======", 10, "======", 20, "=========", 11, "=========", 11, "=========", 13, "============" #ifdef PPM_MGR , 11, "========" #endif ); } for (node = worstPerformers, num=1; node && ((numToPrint < 0) ? 1 : (num <= numToPrint)); node= node->next, num++) { //if (!node) // break; otn = node->otn; if(log) { TextLog_Print(log, #ifdef PPM_MGR "%*d%*d%*d%*d" FMTu64("*") FMTu64("*") FMTu64("*") FMTu64("*") "%*.1f%*.1f%*.1f" FMTu64("*") "\n", #else "%*d%*d%*d%*d" FMTu64("*") FMTu64("*") FMTu64("*") FMTu64("*") "%*.1f%*.1f%*.1f" "\n", #endif 6, num, 9, otn->sigInfo.id, 4, otn->sigInfo.generator, 4, otn->sigInfo.rev, 11, otn->checks, 10, otn->matches, 10, otn->alerts, 20, (uint64_t)(otn->ticks/ticks_per_microsec), 11, node->ticks_per_check/ticks_per_microsec, 11, node->ticks_per_match/ticks_per_microsec, 13, node->ticks_per_nomatch/ticks_per_microsec #ifdef PPM_MGR , 11, otn->ppm_disable_cnt #endif ); } else { LogMessage( #ifdef PPM_MGR "%*d%*d%*d%*d" FMTu64("*") FMTu64("*") FMTu64("*") FMTu64("*") "%*.1f%*.1f%*.1f" FMTu64("*") "\n", #else "%*d%*d%*d%*d" FMTu64("*") FMTu64("*") FMTu64("*") FMTu64("*") "%*.1f%*.1f%*.1f" "\n", #endif 6, num, 9, otn->sigInfo.id, 4, otn->sigInfo.generator, 4, otn->sigInfo.rev, 11, otn->checks, 10, otn->matches, 10, otn->alerts, 20, (uint64_t)(otn->ticks/ticks_per_microsec), 11, node->ticks_per_check/ticks_per_microsec, 11, node->ticks_per_match/ticks_per_microsec, 13, node->ticks_per_nomatch/ticks_per_microsec #ifdef PPM_MGR , 11, otn->ppm_disable_cnt #endif ); } } /* Do some cleanup */ for (node = worstPerformers; node; ) { tmp = node->next; free(node); node = tmp; } if(log) TextLog_Term(log); worstPerformers = NULL; } void CollectRTNProfile(void) { OptTreeNode *otn; OTN_WorstPerformer *new, *node, *last = NULL; char got_position; SFGHASH_NODE *hashNode; SnortConfig *sc = snort_conf; if (sc == NULL) return; for (hashNode = sfghash_findfirst(sc->otn_map); hashNode; hashNode = sfghash_findnext(sc->otn_map)) { otn = (OptTreeNode *)hashNode->data; /* Only log info if OTN has actually been eval'd */ if (otn->checks > 0 && otn->ticks > 0) { double ticks_per_check = (double)otn->ticks/(double)otn->checks; double ticks_per_nomatch; double ticks_per_match; if (otn->matches > otn->checks) otn->checks = otn->matches; if (otn->matches) ticks_per_match = (double)otn->ticks_match/(double)otn->matches; else ticks_per_match = 0.0; if (otn->checks == otn->matches) ticks_per_nomatch = 0.0; else ticks_per_nomatch = (double)otn->ticks_no_match/(double)(otn->checks - otn->matches); /* Find where he goes in the list * Cycle through the list and add * this where it goes */ new = (OTN_WorstPerformer *)SnortAlloc(sizeof(OTN_WorstPerformer)); new->otn = otn; new->ticks_per_check = ticks_per_check; new->ticks_per_match = ticks_per_match; new->ticks_per_nomatch = ticks_per_nomatch; got_position = 0; for (node = worstPerformers; node && !got_position; node = node->next) { last = node; switch (sc->profile_rules.sort) { case PROFILE_SORT_CHECKS: if (otn->checks >= node->otn->checks) { got_position = 1; } break; case PROFILE_SORT_MATCHES: if (otn->matches >= node->otn->matches) { got_position = 1; } break; case PROFILE_SORT_NOMATCHES: if (otn->checks - otn->matches > node->otn->checks - node->otn->matches) { got_position = 1; } break; case PROFILE_SORT_AVG_TICKS_PER_MATCH: if (ticks_per_match >= node->ticks_per_match) { got_position = 1; } break; case PROFILE_SORT_AVG_TICKS_PER_NOMATCH: if (ticks_per_nomatch >= node->ticks_per_nomatch) { got_position = 1; } break; case PROFILE_SORT_TOTAL_TICKS: if (otn->ticks >= node->otn->ticks) { got_position = 1; } break; default: case PROFILE_SORT_AVG_TICKS: if (ticks_per_check >= node->ticks_per_check) { got_position = 1; } break; } if (got_position) break; } if (node) { new->next = node; new->prev = node->prev; node->prev = new; if (new->prev) new->prev->next = new; /* Reset the head of list */ if (node == worstPerformers) worstPerformers = new; } else { if (!last) { worstPerformers = new; } else { new->prev = last; last->next = new; } } } } } void ShowRuleProfiles(void) { /* Cycle through all Rules, print ticks & check count for each */ SnortConfig *sc = snort_conf; if ((sc == NULL) || (sc->profile_rules.num == 0)) return; detection_option_tree_update_otn_stats(sc->detection_option_tree_hash_table); CollectRTNProfile(); /* Specifically call out a top xxx or something? */ PrintWorstRules(sc->profile_rules.num); return; } /* The preprocessor profile list is only accessed for printing stats when * Snort shuts down, so adding new nodes during a reload shouldn't be a * problem. */ void RegisterPreprocessorProfile(const char *keyword, PreprocStats *stats, int layer, PreprocStats *parent, StatsNodeFreeFunc freefn) { PreprocStatsNode *node; if (stats == NULL) return; node = (PreprocStatsNode *)SnortAlloc(sizeof(PreprocStatsNode)); if (PreprocStatsNodeList == NULL) { PreprocStatsNodeList = node; } else { PreprocStatsNode *tmp = PreprocStatsNodeList; PreprocStatsNode *last; do { if (strcasecmp(tmp->name, keyword) == 0) { //FatalError("Duplicate Preprocessor Stats Name (%s)\n", keyword); /* Don't fatal error here since during a reload there are * probably going to be dups - just return */ //multiple policy support free(node); return; } last = tmp; tmp = tmp->next; } while (tmp != NULL); last->next = node; } node->name = SnortStrdup(keyword); node->stats = stats; /* Set the stats reference */ node->parent = parent; node->layer = layer; node->freefn = freefn; if (layer > max_layers) max_layers = layer; } void FreePreprocPerformance(Preproc_WorstPerformer *idx) { Preproc_WorstPerformer *child, *tmp; child = idx->children; while (child) { FreePreprocPerformance(child); tmp = child; child = child->next; free(tmp); } } void PrintPreprocPerformance(TextLog *log, int num, Preproc_WorstPerformer *idx) { Preproc_WorstPerformer *child; int i; /* indent 'Num' based on the layer */ unsigned int indent = 6 - (5 - idx->node->layer); if (num != 0) { indent += 2; if(log) { TextLog_Print(log, "%*d%*s%*d" FMTu64("*") FMTu64("*") FMTu64("*") "%*.2f%*.2f%*.2f\n", indent, num, 28 - indent, idx->node->name, 6, idx->node->layer, 11, idx->node->stats->checks, 11, idx->node->stats->exits, 20, (uint64_t)(idx->node->stats->ticks/ticks_per_microsec), 11, idx->ticks_per_check/ticks_per_microsec, 14, idx->pct_of_parent, 13, idx->pct_of_total); } else { LogMessage("%*d%*s%*d" FMTu64("*") FMTu64("*") FMTu64("*") "%*.2f%*.2f%*.2f\n", indent, num, 28 - indent, idx->node->name, 6, idx->node->layer, 11, idx->node->stats->checks, 11, idx->node->stats->exits, 20, (uint64_t)(idx->node->stats->ticks/ticks_per_microsec), 11, idx->ticks_per_check/ticks_per_microsec, 14, idx->pct_of_parent, 13, idx->pct_of_total); } } else { /* The totals */ indent += strlen(idx->node->name); if(log) { TextLog_Print(log, "%*s%*s%*d" FMTu64("*") FMTu64("*") FMTu64("*") "%*.2f%*.2f%*.2f\n", indent, idx->node->name, 28 - indent, idx->node->name, 6, idx->node->layer, 11, idx->node->stats->checks, 11, idx->node->stats->exits, 20, (uint64_t)(idx->node->stats->ticks/ticks_per_microsec), 11, idx->ticks_per_check/ticks_per_microsec, 14, idx->pct_of_parent, 13, idx->pct_of_parent); } else { LogMessage("%*s%*s%*d" FMTu64("*") FMTu64("*") FMTu64("*") "%*.2f%*.2f%*.2f\n", indent, idx->node->name, 28 - indent, idx->node->name, 6, idx->node->layer, 11, idx->node->stats->checks, 11, idx->node->stats->exits, 20, (uint64_t)(idx->node->stats->ticks/ticks_per_microsec), 11, idx->ticks_per_check/ticks_per_microsec, 14, idx->pct_of_parent, 13, idx->pct_of_parent); } } child = idx->children; i = 1; while (child) { PrintPreprocPerformance(log, i++, child); child = child->next; } } void CleanupPreprocStatsNodeList(void) { PreprocStatsNode *node, *nxt; node = PreprocStatsNodeList; while (node) { nxt = node->next; if (node->freefn) node->freefn(node->stats); free(node->name); free(node); node = nxt; } PreprocStatsNodeList = NULL; } void CleanupPreprocPerformance(Preproc_WorstPerformer *worst) { Preproc_WorstPerformer *idx, *child, *tmp; idx = worst; while (idx) { tmp = idx->next; child = idx->children; CleanupPreprocPerformance(child); free(idx); idx = tmp; } } void PrintWorstPreprocs(int numToPrint) { Preproc_WorstPerformer *idx; Preproc_WorstPerformer *total = NULL; int num = 0; TextLog *log = NULL; time_t cur_time; char fullname[STD_BUF]; int ret; SnortConfig *sc = snort_conf; getTicksPerMicrosec(); cur_time = time(NULL); if (sc->profile_preprocs.filename != NULL) { if (sc->profile_preprocs.append) { log = TextLog_Init(sc->profile_preprocs.filename, 512*1024, 512*1024); if (log != NULL) TextLog_Print(log, "\ntimestamp: %u\n", cur_time); } else { ret = SnortSnprintf(fullname, STD_BUF, "%s.%u", sc->profile_preprocs.filename, (uint32_t)cur_time); if(ret != SNORT_SNPRINTF_SUCCESS) FatalError("profiler: file path+name too long\n"); log = TextLog_Init(fullname, 512*1024, 512*1024); } } if (numToPrint != -1) { if(log) { TextLog_Print(log, "Preprocessor Profile Statistics (worst %d)\n", numToPrint); } else { LogMessage("Preprocessor Profile Statistics (worst %d)\n", numToPrint); } } else { if(log) { TextLog_Print(log, "Preprocessor Profile Statistics (all)\n"); } else { LogMessage("Preprocessor Profile Statistics (all)\n"); } } if(log) { TextLog_Print(log, "==========================================================\n"); } else { LogMessage("==========================================================\n"); } if (!worstPreprocPerformers) { if(log) { TextLog_Print(log, "No Preprocessors were profiled\n"); TextLog_Term(log); } else { LogMessage("No Preprocessors were profiled\n"); } CleanupPreprocPerformance(worstPreprocPerformers); worstPreprocPerformers = NULL; return; } if(log) { TextLog_Print(log, "%*s%*s%*s%*s%*s%*s%*s%*s%*s\n", 4, "Num", 24, "Preprocessor", 6, "Layer", 11, "Checks", 11, "Exits", 20, "Microsecs", 11, "Avg/Check", 14, "Pct of Caller", 13, "Pct of Total"); } else { LogMessage("%*s%*s%*s%*s%*s%*s%*s%*s%*s\n", 4, "Num", 24, "Preprocessor", 6, "Layer", 11, "Checks", 11, "Exits", 20, "Microsecs", 11, "Avg/Check", 14, "Pct of Caller", 13, "Pct of Total"); } if(log) { TextLog_Print(log, "%*s%*s%*s%*s%*s%*s%*s%*s%*s\n", 4, "===", 24, "============", 6, "=====", 11, "======", 11, "=====", 20, "=========", 11, "=========", 14, "=============", 13, "============"); } else { LogMessage("%*s%*s%*s%*s%*s%*s%*s%*s%*s\n", 4, "===", 24, "============", 6, "=====", 11, "======", 11, "=====", 20, "=========", 11, "=========", 14, "=============", 13, "============"); } for (idx = worstPreprocPerformers, num=1; idx && ((numToPrint < 0) ? 1 : (num <= numToPrint)); idx= idx->next, num++) { /* Skip the total counter */ if (idx->node->stats == &totalPerfStats) { num--; total = idx; continue; } //if (!idx) // break; PrintPreprocPerformance(log, num, idx); //LogMessage("%*d%*s%*d%*d" FMTu64("*") "%*.1f%*.1f\n", // 6, num, 20, idx->node->name, 6, idx->node->layer, // 11, idx->node->stats->checks, // 11, idx->node->stats->exits, // 20, idx->node->stats->ticks, // 11, idx->ticks_per_check, // 14, idx->pct_of_parent, // 14, idx->pct_of_total); } if (total) PrintPreprocPerformance(log, 0, total); if(log) TextLog_Term(log); CleanupPreprocPerformance(worstPreprocPerformers); worstPreprocPerformers = NULL; } Preproc_WorstPerformer *findPerfParent(PreprocStatsNode *node, Preproc_WorstPerformer *top) { Preproc_WorstPerformer *list = top; Preproc_WorstPerformer *parent; if (!list) return NULL; if (list->node->layer > node->layer) return NULL; while (list) { if (list->node->stats == node->parent) { parent = list; return parent; } parent = findPerfParent(node, list->children); if (parent) return parent; list = list->next; } return NULL; } void ResetPreprocProfiling(void) { PreprocStatsNode *idx = NULL; SnortConfig *sc = snort_conf; if ((sc == NULL) || (sc->profile_preprocs.num == 0)) return; for (idx = PreprocStatsNodeList; idx != NULL; idx = idx->next) { idx->stats->ticks = 0; idx->stats->ticks_start = 0; idx->stats->checks = 0; idx->stats->exits = 0; } } void ShowPreprocProfiles(void) { /* Cycle through all Rules, print ticks & check count for each */ PreprocStatsNode *idx; int layer; Preproc_WorstPerformer *parent, *new, *this = NULL, *last = NULL; char got_position; Preproc_WorstPerformer *listhead; double ticks_per_check; SnortConfig *sc = snort_conf; if ((sc == NULL) || (sc->profile_preprocs.num == 0)) return; /* Adjust mpse stats to not include rule evaluation */ mpsePerfStats.ticks -= rulePerfStats.ticks; /* And adjust the rules to include the NC rules */ rulePerfStats.ticks += ncrulePerfStats.ticks; for (layer=0;layer<=max_layers;layer++) { for (idx = PreprocStatsNodeList; idx; idx = idx->next) { if (idx->stats->checks == 0 || idx->stats->ticks == 0) continue; if (idx->layer != layer) continue; last = NULL; ticks_per_check = (double)idx->stats->ticks/(double)idx->stats->checks; new = (Preproc_WorstPerformer *)SnortAlloc(sizeof(Preproc_WorstPerformer)); new->node = idx; new->ticks_per_check = ticks_per_check; if (idx->parent) { /* Find this idx's parent in the list */ parent = findPerfParent(idx, worstPreprocPerformers); if (parent && (parent->node->stats != &totalPerfStats)) { listhead = parent->children; } else { listhead = worstPreprocPerformers; parent = NULL; } new->pct_of_parent = (double)idx->stats->ticks/idx->parent->ticks*100.0; new->pct_of_total = (double)idx->stats->ticks/totalPerfStats.ticks*100.0; } else { parent = NULL; new->pct_of_parent = 0.0; new->pct_of_total = 100.0; listhead = worstPreprocPerformers; } got_position = 0; for (this = listhead; this && !got_position; this = this->next) { last = this; switch (sc->profile_preprocs.sort) { case PROFILE_SORT_CHECKS: if (new->node->stats->checks >= this->node->stats->checks) { got_position = 1; } break; case PROFILE_SORT_TOTAL_TICKS: if (new->node->stats->ticks >= this->node->stats->ticks) { got_position = 1; } break; default: case PROFILE_SORT_AVG_TICKS: if (new->ticks_per_check >= this->ticks_per_check) { got_position = 1; } break; } if (got_position) break; } if (this) { new->next = this; new->prev = this->prev; this->prev = new; if (new->prev) new->prev->next = new; /* Reset the head of the list */ if (this == listhead) { if (parent) { parent->children = new; } else { worstPreprocPerformers = new; } } } else { if (!last) { if (parent) { parent->children = new; } else { worstPreprocPerformers = new; } } else { new->prev = last; last->next = new; } } } } PrintWorstPreprocs(sc->profile_preprocs.num); CleanupPreprocStatsNodeList(); } #endif snort-2.9.15.1/src/profiler.h0000644000175200017520000001574713571422607012650 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2005-2013 Sourcefire, Inc. ** Author: Steven Sturges ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifndef __PROFILER_H__ #define __PROFILER_H__ #ifdef PERF_PROFILING #include "cpuclock.h" /* Sort preferences for rule profiling */ #define PROFILE_SORT_CHECKS 1 #define PROFILE_SORT_MATCHES 2 #define PROFILE_SORT_NOMATCHES 3 #define PROFILE_SORT_AVG_TICKS 4 #define PROFILE_SORT_AVG_TICKS_PER_MATCH 5 #define PROFILE_SORT_AVG_TICKS_PER_NOMATCH 6 #define PROFILE_SORT_TOTAL_TICKS 7 /* MACROS that handle profiling of rules and preprocessors */ #define PROFILE_VARS_NAMED(name) uint64_t name##_ticks_start, name##_ticks_end #define PROFILE_VARS PROFILE_VARS_NAMED(snort) #define PROFILE_START_NAMED(name) \ get_clockticks(name##_ticks_start) #define PROFILE_END_NAMED(name) \ get_clockticks(name##_ticks_end) #define NODE_PROFILE_END \ PROFILE_END_NAMED(node); \ node_ticks_delta = node_ticks_end - node_ticks_start #ifndef PROFILING_RULES #define PROFILING_RULES ScProfileRules() #endif #define NODE_PROFILE_VARS uint64_t node_ticks_start = 0, node_ticks_end = 0, node_ticks_delta = 0, node_deltas = 0 #define NODE_PROFILE_START(node) \ if (PROFILING_RULES) { \ node->checks++; \ PROFILE_START_NAMED(node); \ } #define NODE_PROFILE_END_MATCH(node) \ if (PROFILING_RULES) { \ NODE_PROFILE_END; \ node->ticks += node_ticks_delta + node_deltas; \ node->ticks_match += node_ticks_delta + node_deltas; \ } #define NODE_PROFILE_END_NOMATCH(node) \ if (PROFILING_RULES) { \ NODE_PROFILE_END; \ node->ticks += node_ticks_delta + node_deltas; \ node->ticks_no_match += node_ticks_delta + node_deltas; \ } #define NODE_PROFILE_TMPSTART(node) \ if (PROFILING_RULES) { \ PROFILE_START_NAMED(node); \ } #define NODE_PROFILE_TMPEND(node) \ if (PROFILING_RULES) { \ NODE_PROFILE_END; \ node_deltas += node_ticks_delta; \ } #define OTN_PROFILE_ALERT(otn) otn->alerts++; #ifndef PROFILING_PREPROCS #define PROFILING_PREPROCS ScProfilePreprocs() #endif #define PREPROC_PROFILE_START_NAMED(name, ppstat) \ if (PROFILING_PREPROCS) { \ ppstat.checks++; \ PROFILE_START_NAMED(name); \ ppstat.ticks_start = name##_ticks_start; \ } #define PREPROC_PROFILE_START(ppstat) PREPROC_PROFILE_START_NAMED(snort, ppstat) #define PREPROC_PROFILE_START_NAMED_PI(name, ppstat) \ { \ ppstat.checks++; \ PROFILE_START_NAMED(name); \ ppstat.ticks_start = name##_ticks_start; \ } #define PREPROC_PROFILE_START_PI(ppstat) PREPROC_PROFILE_START_NAMED_PI(snort, ppstat) #define PREPROC_PROFILE_REENTER_START_NAMED(name, ppstat) \ if (PROFILING_PREPROCS) { \ PROFILE_START_NAMED(name); \ ppstat.ticks_start = name##_ticks_start; \ } #define PREPROC_PROFILE_REENTER_START(ppstat) PREPROC_PROFILE_REENTER_START_NAMED(snort, ppstat) #define PREPROC_PROFILE_TMPSTART_NAMED(name, ppstat) \ if (PROFILING_PREPROCS) { \ PROFILE_START_NAMED(name); \ ppstat.ticks_start = name##_ticks_start; \ } #define PREPROC_PROFILE_TMPSTART(ppstat) PREPROC_PROFILE_TMPSTART_NAMED(snort, ppstat) #define PREPROC_PROFILE_END_NAMED(name, ppstat) \ if (PROFILING_PREPROCS) { \ PROFILE_END_NAMED(name); \ ppstat.exits++; \ ppstat.ticks += name##_ticks_end - ppstat.ticks_start; \ } #define PREPROC_PROFILE_END(ppstat) PREPROC_PROFILE_END_NAMED(snort, ppstat) #define PREPROC_PROFILE_END_NAMED_PI(name, ppstat) \ { \ PROFILE_END_NAMED(name); \ ppstat.exits++; \ ppstat.ticks += name##_ticks_end - ppstat.ticks_start; \ } #define PREPROC_PROFILE_END_PI(ppstat) PREPROC_PROFILE_END_NAMED_PI(snort, ppstat) #define PREPROC_PROFILE_REENTER_END_NAMED(name, ppstat) \ if (PROFILING_PREPROCS) { \ PROFILE_END_NAMED(name); \ ppstat.ticks += name##_ticks_end - ppstat.ticks_start; \ } #define PREPROC_PROFILE_REENTER_END(ppstat) PREPROC_PROFILE_REENTER_END_NAMED(snort, ppstat) #define PREPROC_PROFILE_TMPEND_NAMED(name, ppstat) \ if (PROFILING_PREPROCS) { \ PROFILE_END_NAMED(name); \ ppstat.ticks += name##_ticks_end - ppstat.ticks_start; \ } #define PREPROC_PROFILE_TMPEND(ppstat) PREPROC_PROFILE_TMPEND_NAMED(snort, ppstat) /************** Profiling API ******************/ void ShowRuleProfiles(void); /* Preprocessor stats info */ typedef struct _PreprocStats { uint64_t ticks, ticks_start; uint64_t checks; uint64_t exits; } PreprocStats; typedef void (*FreeFunc)(PreprocStats *stats); typedef struct _PreprocStatsNode { PreprocStats *stats; char *name; int layer; FreeFunc freefn; PreprocStats *parent; struct _PreprocStatsNode *next; } PreprocStatsNode; typedef struct _ProfileConfig { int num; int sort; int append; char *filename; } ProfileConfig; typedef void (*StatsNodeFreeFunc)(PreprocStats *stats); void RegisterPreprocessorProfile(const char *keyword, PreprocStats *stats, int layer, PreprocStats *parent, StatsNodeFreeFunc freefn); void ShowPreprocProfiles(void); void ResetRuleProfiling(void); void ResetPreprocProfiling(void); void CleanupPreprocStatsNodeList(void); extern PreprocStats totalPerfStats; #else #define PROFILE_VARS #define PROFILE_VARS_NAMED(name) #define NODE_PROFILE_VARS #define NODE_PROFILE_START(node) #define NODE_PROFILE_END_MATCH(node) #define NODE_PROFILE_END_NOMATCH(node) #define NODE_PROFILE_TMPSTART(node) #define NODE_PROFILE_TMPEND(node) #define OTN_PROFILE_ALERT(otn) #define PREPROC_PROFILE_START(ppstat) #define PREPROC_PROFILE_START_NAMED(name, ppstat) #define PREPROC_PROFILE_START_PI(ppstat) #define PREPROC_PROFILE_REENTER_START(ppstat) #define PREPROC_PROFILE_REENTER_START_NAMED(name, ppstat) #define PREPROC_PROFILE_TMPSTART(ppstat) #define PREPROC_PROFILE_TMPSTART_NAMED(name, ppstat) #define PREPROC_PROFILE_END(ppstat) #define PREPROC_PROFILE_END_NAMED(name, ppstat) #define PREPROC_PROFILE_END_PI(ppstat) #define PREPROC_PROFILE_REENTER_END(ppstat) #define PREPROC_PROFILE_REENTER_END_NAMED(name, ppstat) #define PREPROC_PROFILE_TMPEND(ppstat) #define PREPROC_PROFILE_TMPEND_NAMED(name, ppstat) #endif #endif /* __PROFILER_H__ */ snort-2.9.15.1/src/plugbase.c0000644000175200017520000014511413571422607012613 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #ifdef HAVE_STRINGS_H #include #endif #ifndef WIN32 #include #include #include #endif /* !WIN32 */ #include #include #include "sf_types.h" #include "plugbase.h" #include "spo_plugbase.h" #include "snort.h" #include "snort_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_session.h" #include "preprocessors/spp_stream6.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" #include "preprocessors/spp_normalize.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_byte_extract.h" #include "detection-plugins/sp_byte_math.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_base64_decode.h" #include "detection-plugins/sp_base64_data.h" #include "detection-plugins/sp_pkt_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" #include "detection-plugins/sp_file_type.h" #if defined(FEAT_OPEN_APPID) #include "detection-plugins/sp_appid.h" #endif /* defined(FEAT_OPEN_APPID) */ /* built-in output plugins */ #include "output-plugins/spo_alert_syslog.h" #include "output-plugins/spo_log_tcpdump.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_log_null.h" #include "output-plugins/spo_log_ascii.h" #include "output-plugins/spo_unified2.h" #ifdef DUMP_BUFFER #include "output-plugins/spo_log_buffer_dump.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 RuleOptByteOrderFuncNode *rule_opt_byte_order_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 OutputFuncNode *AlertList; extern OutputFuncNode *LogList; /**************************** Detection Plugin API ****************************/ /* For translation from enum to char* */ #ifdef DEBUG_MSGS static const char *optTypeMap[OPT_TYPE_MAX] = { "action", "logging", "detection" }; #define ENUM2STR(num, map) \ ((num < sizeof(map)/sizeof(map[0])) ? map[num] : "undefined") #endif static GetHttpXffFieldsFunc getHttpXffFieldsFunc = NULL; 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(); SetupPktData(); SetupByteTest(); SetupByteJump(); SetupByteExtract(); SetupByteMath(); SetupIsDataAt(); SetupFileData(); SetupBase64Decode(); SetupBase64Data(); SetupPcre(); SetupFlowBits(); SetupAsn1(); #ifdef ENABLE_REACT SetupReact(); #endif #ifdef ENABLE_RESPOND SetupRespond(); #endif SetupFTPBounce(); SetupUriLenCheck(); SetupCvs(); SetupFileType(); #if defined(FEAT_OPEN_APPID) SetupAppId(); #endif /* defined(FEAT_OPEN_APPID) */ } /**************************************************************************** * * 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 ro_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, ro_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("%s(%d) Duplicate detection plugin keyword: %s.\n", file_name, 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 = ro_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 roo_func) { RuleOptOverrideInitFuncNode *node = rule_opt_override_init_funcs; while (node != NULL) { if (strcasecmp(node->keyword, keyword) == 0) { node->func(keyword, option, roo_func); break; } node = node->next; } } void RegisterByteOrderKeyword(char *keyword, RuleOptByteOrderFunc roo_func) { RuleOptByteOrderFuncNode *node = (RuleOptByteOrderFuncNode *)SnortAlloc(sizeof(RuleOptByteOrderFuncNode)); RuleOptByteOrderFuncNode *list = rule_opt_byte_order_funcs; RuleOptByteOrderFuncNode *last; node->keyword = SnortStrdup(keyword); node->func = roo_func; node->next = NULL; if (list == NULL) rule_opt_byte_order_funcs = node; else { while (list != NULL) { if (strcasecmp(node->keyword, list->keyword) == 0) { free(node->keyword); free(node); return; } last = list; list = list->next; } last->next = node; } } RuleOptByteOrderFunc GetByteOrderFunc(char *keyword) { RuleOptByteOrderFuncNode *node = rule_opt_byte_order_funcs; while (node != NULL) { if (strcasecmp(keyword, node->keyword) == 0) return node->func; node = node->next; } return NULL; } /**************************************************************************** * * 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, (void *)node->vfunc); 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 ro_eval_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", ro_eval_func);); ofp->OptTestFunc = ro_eval_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 * ***************************************************************************/ // TBD this can prolly be replaced with a single item // because we allow at most one response per packet void AddRspFuncToList(ResponseFunc resp_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", resp_func);); rsp->func = resp_func; rsp->params = params; } void PostConfigInitPlugins(struct _SnortConfig *sc, PostConfigFuncNode *post_config_funcs) { while (post_config_funcs != NULL) { post_config_funcs->func(sc, 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 FreeRuleOptByteOrderFuncs(RuleOptByteOrderFuncNode *head) { while (head != NULL) { RuleOptByteOrderFuncNode *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 func */ free(tmp); } } void FreePluginPostConfigFuncs(PostConfigFuncNode *head) { while (head != NULL) { PostConfigFuncNode *tmp = head; head = head->next; /* don't free sig->arg, that's free'd by the CleanExit func */ free(tmp); } } /************************** Non Rule Detection Plugin API *********************/ DetectionEvalFuncNode * AddFuncToDetectionList(SnortConfig *sc, DetectionEvalFunc detect_eval_func, uint16_t priority, uint32_t detect_id, uint32_t proto_mask) { DetectionEvalFuncNode *node; tSfPolicyId policy_id = getParserPolicy(sc); 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 detection function ID %d/bit %d/pri %d to list\n", detect_id, p->num_detects, priority);); node = (DetectionEvalFuncNode *)SnortAlloc(sizeof(DetectionEvalFuncNode)); if (p->detect_eval_funcs == NULL) { p->detect_eval_funcs = node; } else { DetectionEvalFuncNode *tmp = p->detect_eval_funcs; DetectionEvalFuncNode *last = NULL; do { if (tmp->detect_id == detect_id) { free(node); FatalError("Detection function already registered with ID %d\n", detect_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->detect_eval_funcs = node; } else { node->next = tmp; last->next = node; } } node->func = detect_eval_func; node->priority = priority; node->detect_id = detect_id; //node->detect_bit = (1 << detect_id); node->proto_mask = proto_mask; p->num_detects++; p->detect_proto_mask |= proto_mask; //p->detect_bit_mask |= node->detect_bit; return node; } void FreeDetectionEvalFuncs(DetectionEvalFuncNode *head) { DetectionEvalFuncNode *tmp; while (head != NULL) { tmp = head->next; //if (head->context) // free(head->context); free(head); head = tmp; } } /************************** Buffer Dump Plugin API ***************************/ #ifdef DUMP_BUFFER void RegisterBufferTracer(TraceBuffer *(*bdfunc)(), BUFFER_DUMP_FUNC type) { getBuffers[type] = bdfunc; bdmask |= (UINT64_C(1) << type); } #endif /************************** Preprocessor Plugin API ***************************/ static void AddFuncToPreprocSignalList(PreprocSignalFunc, void *, PreprocSignalFuncNode **, uint16_t, uint32_t); void RegisterPreprocessors(void) { LogMessage("Initializing Preprocessors!\n"); SetupARPspoof(); #ifdef NORMALIZER SetupNormalizer(); #endif SetupFrag3(); SetupSessionManager(); SetupStream6(); 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(const char *keyword, PreprocConfigFunc pp_config_func) #else void RegisterPreprocessor(const char *keyword, PreprocConfigFunc pp_config_func, PreprocReloadFunc rfunc, PreprocReloadVerifyFunc rvfunc, PreprocReloadSwapFunc sfunc, PreprocReloadSwapFreeFunc ffunc) #endif { PreprocConfigFuncNode *node = (PreprocConfigFuncNode *)SnortAlloc(sizeof(PreprocConfigFuncNode)); DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Registering keyword:preproc => %s:%p\n", keyword, pp_config_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 = pp_config_func; #ifdef SNORT_RELOAD node->reload_func = rfunc; node->reload_verify_func = rvfunc; node->reload_swap_func = sfunc; node->reload_swap_free_func = ffunc; #endif } #ifdef SNORT_RELOAD void *GetRelatedReloadData(SnortConfig *sc, const char *keyword) { PreprocessorSwapData *swapData; for (swapData = sc->preprocSwapData; swapData; swapData = swapData->next) { if (swapData->preprocNode && swapData->preprocNode->keyword && strcasecmp(swapData->preprocNode->keyword, keyword) == 0) { return swapData->data; } } return NULL; } void *GetReloadStreamConfig(SnortConfig *sc) { return sc->streamReloadConfig; } #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(const char *keyword, PreprocStatsFunc pp_stats_func) { PreprocStatsFuncNode *node; DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Registering final stats function: " "preproc => %s:%p\n", keyword, pp_stats_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 = pp_stats_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_vfunc); node = node->next; } LogMessage("-------------------------------------------------\n\n"); } int IsPreprocEnabled(SnortConfig *sc, uint32_t preproc_id) { PreprocEvalFuncNode *node; tSfPolicyId policy_id = getParserPolicy(sc); 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(SnortConfig *sc, PreprocEvalFunc pp_eval_func, uint16_t priority, uint32_t preproc_id, uint32_t proto_mask) { PreprocEvalFuncNode *node; tSfPolicyId policy_id = getParserPolicy(sc); 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 = pp_eval_func; node->priority = priority; node->preproc_id = preproc_id; node->preproc_bit = (UINT64_C(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 AddFuncToPreprocListAllNapPolicies(struct _SnortConfig *sc, PreprocEvalFunc pp_eval_func, uint16_t priority, uint32_t preproc_id, uint32_t proto_mask) { tSfPolicyId save_policy_id = getParserPolicy( sc ); uint32_t i; if (sc == NULL) FatalError("%s(%d) Snort config for parsing is NULL.\n", __FILE__, __LINE__); // preprocs are only registered in NAP policies so if num_prerocs > 0 then policy is NAP, this works here // because this func is always called after all policies have been parsed and preprocs configured per policy // have already registered... for( i = 0; i < sc->num_policies_allocated; i++ ) if( ( sc->targeted_policies[ i ] != NULL ) && ( sc->targeted_policies[ i ]->num_preprocs > 0 ) ) { setParserPolicy( sc, i ); AddFuncToPreprocList( sc, pp_eval_func, priority, preproc_id, proto_mask ); } setParserPolicy( sc, save_policy_id ); } PreprocMetaEvalFuncNode * AddFuncToPreprocMetaEvalList( SnortConfig *sc, PreprocMetaEvalFunc pp_meta_eval_func, uint16_t priority, uint32_t preproc_id) { PreprocMetaEvalFuncNode *node; tSfPolicyId policy_id = getDefaultPolicy( ); SnortPolicy *p; if (sc == NULL) { FatalError("%s(%d) Snort config for parsing is NULL.\n", __FILE__, __LINE__); } #ifndef HAVE_DAQ_ACQUIRE_WITH_META WarningMessage("Metadata not available for processing. Not registering Preprocessor Meta Eval id %d\n", preproc_id); return NULL; // Not supported #endif 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 = (PreprocMetaEvalFuncNode *)SnortAlloc(sizeof(PreprocMetaEvalFuncNode)); if (p->preproc_meta_eval_funcs == NULL) { p->preproc_meta_eval_funcs = node; SetupMetadataCallback(); } else { PreprocMetaEvalFuncNode *tmp = p->preproc_meta_eval_funcs; PreprocMetaEvalFuncNode *last = NULL; do { if (tmp->preproc_id == preproc_id) { free(node); FatalError("Preprocessor Meta Eval 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_meta_eval_funcs = node; } else { node->next = tmp; last->next = node; } } node->func = pp_meta_eval_func; node->priority = priority; node->preproc_id = preproc_id; node->preproc_bit = (UINT64_C(1) << preproc_id); p->num_meta_preprocs++; p->preproc_meta_bit_mask |= node->preproc_bit; return node; } void AddFuncToPreprocPostConfigList(SnortConfig *sc, PreprocPostConfigFunc pp_post_config_func, void *data) { PreprocPostConfigFuncNode *node; 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 = pp_post_config_func; } void PostConfigPreprocessors(SnortConfig *sc) { PreprocPostConfigFuncNode *list; if (sc == NULL) { FatalError("%s(%d) Snort config is NULL.\n", __FILE__, __LINE__); } list = sc->preproc_post_config_funcs; for (; list != NULL; list = list->next) { if (list->func != NULL) list->func(sc, list->data); } } void FilterConfigPreprocessors(SnortConfig *sc) { tSfPolicyId policy_id; SnortPolicy *p; PreprocEvalFuncNode *node; PreprocEvalFuncNode **list; PreprocEvalFuncNode **free_list; if (sc == NULL) { ParseError("%s(%d) Snort config is NULL.\n", __FILE__, __LINE__); } if (!sc->disable_all_policies) return; policy_id = getParserPolicy(sc); p = sc->targeted_policies[policy_id]; if (p == NULL) return; list = &p->preproc_eval_funcs; free_list = &p->unused_preproc_eval_funcs; while ((node = *list) != NULL) { if (node->preproc_bit & sc->reenabled_preprocessor_bits) { list = &node->next; } else { *list = node->next; node->next = NULL; *free_list = node; free_list = &node->next; } } } #ifdef SNORT_RELOAD void SwapPreprocConfigurations(SnortConfig *sc) { PreprocessorSwapData *node; PreprocConfigFuncNode *preproc; for (node = sc->preprocSwapData; node != NULL; node = node->next) { if ((preproc = node->preprocNode) && preproc->reload_swap_func) node->data = preproc->reload_swap_func(sc, node->data); } } void FreeSwappedPreprocConfigurations(struct _SnortConfig *sc) { PreprocessorSwapData *node; PreprocConfigFuncNode *preproc; for (node = sc->preprocSwapData; node != NULL; node = node->next) { if (node->data && (preproc = node->preprocNode) && preproc->reload_swap_free_func) { preproc->reload_swap_free_func(node->data); node->data = NULL; } } } #endif void AddFuncToConfigCheckList(SnortConfig *sc, PreprocCheckConfigFunc pp_chk_config_func) { PreprocCheckConfigFuncNode *node; 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 = pp_chk_config_func; } /* functions to aid in cleaning up after plugins */ void AddFuncToPreprocCleanExitList(PreprocSignalFunc pp_sig_func, void *arg, uint16_t priority, uint32_t preproc_id) { AddFuncToPreprocSignalList(pp_sig_func, arg, &preproc_clean_exit_funcs, priority, preproc_id); } void AddFuncToPreprocShutdownList(PreprocSignalFunc pp_shutdown_func, void *arg, uint16_t priority, uint32_t preproc_id) { AddFuncToPreprocSignalList(pp_shutdown_func, arg, &preproc_shutdown_funcs, priority, preproc_id); } void AddFuncToPreprocResetList(PreprocSignalFunc pp_sig_func, void *arg, uint16_t priority, uint32_t preproc_id) { AddFuncToPreprocSignalList(pp_sig_func, arg, &preproc_reset_funcs, priority, preproc_id); } void AddFuncToPreprocResetStatsList(PreprocSignalFunc pp_sig_func, void *arg, uint16_t priority, uint32_t preproc_id) { AddFuncToPreprocSignalList(pp_sig_func, arg, &preproc_reset_stats_funcs, priority, preproc_id); } static void AddFuncToPreprocSignalList(PreprocSignalFunc pp_sig_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 = pp_sig_func; node->arg = arg; node->preproc_id = preproc_id; node->priority = priority; } void AddFuncToPeriodicCheckList(PeriodicFunc periodic_func, void *arg, uint16_t priority, uint32_t preproc_id, uint32_t period ) { PeriodicCheckFuncNode **list= &periodic_check_funcs; PeriodicCheckFuncNode *node; node = (PeriodicCheckFuncNode *)SnortAlloc(sizeof(PeriodicCheckFuncNode)); if (*list == NULL) { *list = node; } else { PeriodicCheckFuncNode *tmp = *list; PeriodicCheckFuncNode *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 = periodic_func; node->arg = arg; node->preproc_id = preproc_id; node->priority = priority; node->period = period; node->time_left = period; } 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 FreePreprocMetaEvalFuncs(PreprocMetaEvalFuncNode *head) { PreprocMetaEvalFuncNode *tmp; while (head != NULL) { tmp = head->next; //if (head->context) // free(head->context); 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 func */ free(head); head = tmp; } } void FreePeriodicFuncs(PeriodicCheckFuncNode *head) { PeriodicCheckFuncNode *tmp; while (head != NULL) { tmp = head->next; /* don't free sig->arg, that's free'd by the CleanExit func */ free(head); head = tmp; } } int CheckPreprocessorsConfig(SnortConfig *sc) { PreprocCheckConfigFuncNode *idx; int rval; if (sc == NULL) { FatalError("%s(%d) Snort config is NULL.\n", __FILE__, __LINE__); } idx = sc->preproc_config_check_funcs; LogMessage("Verifying Preprocessor Configurations!\n"); while(idx != NULL) { if ((rval = idx->func(sc))) return rval; idx = idx->next; } return 0; } #ifdef SNORT_RELOAD int VerifyReloadedPreprocessors(SnortConfig *sc) { int rval; PreprocessorSwapData *node; PreprocConfigFuncNode *preproc; for (node = sc->preprocSwapData; node != NULL; node = node->next) { if (node->data && (preproc = node->preprocNode) && preproc->reload_verify_func && (rval = preproc->reload_verify_func(sc, node->data))) { return rval; } } return 0; } void FreePreprocessorReloadData(SnortConfig *sc) { PreprocessorSwapData *node; PreprocConfigFuncNode *preproc; while ((node = sc->preprocSwapData)) { sc->preprocSwapData = node->next; if (node->data && (preproc = node->preprocNode) && preproc->reload_swap_free_func) preproc->reload_swap_free_func(node->data); free(node); } } #endif void DisableAllPolicies(SnortConfig *sc) { if (!sc->disable_all_policies) { sc->disable_all_policies = 1; sc->reenabled_preprocessor_bits = (UINT64_C(1) << PP_FRAG3); sc->reenabled_preprocessor_bits |= (UINT64_C(1) << PP_STREAM); sc->reenabled_preprocessor_bits |= (UINT64_C(1) << PP_PERFMONITOR); } } int ReenablePreprocBit(SnortConfig *sc, unsigned int preproc_id) { sc->reenabled_preprocessor_bits |= (UINT64_C(1) << preproc_id); return 0; } /***************************** Output Plugin API *****************************/ extern OutputConfigFuncNode *output_config_funcs; static void AppendOutputFuncList(OutputFunc, void *, OutputFuncNode **); void RegisterOutputPlugins(void) { LogMessage("Initializing Output Plugins!\n"); AlertSyslogSetup(); LogTcpdumpSetup(); AlertFastSetup(); AlertFullSetup(); #ifndef WIN32 /* Win32 doesn't support AF_UNIX sockets */ AlertUnixSockSetup(); #endif /* !WIN32 */ AlertCSVSetup(); LogNullSetup(); Unified2Setup(); LogAsciiSetup(); #ifdef DUMP_BUFFER LogBufferDumpSetup(); #endif #ifdef LINUX /* This uses linux only capabilities */ AlertSFSocket_Setup(); #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 oc_func) { OutputConfigFuncNode *node = (OutputConfigFuncNode *)SnortAlloc(sizeof(OutputConfigFuncNode)); DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Registering keyword:output => %s:%p\n", keyword, oc_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->config_func = oc_func; node->output_type_flags = type_flags; } void RemoveOutputPlugin(char *keyword) { OutputConfigFuncNode *head = output_config_funcs; if (!head ||(keyword == NULL)) return; /*If head node, remove head*/ if(head->keyword != NULL) { if (strcasecmp(head->keyword, keyword) == 0) { output_config_funcs = head->next; free(head->keyword); free(head); return; } } while (head->next != NULL) { OutputConfigFuncNode *next; next = head->next; if(next->keyword != NULL ) { if (strcasecmp(next->keyword, keyword) == 0) { head->next = next->next; free(next->keyword); free(next); break; } } head = head->next; } return; } 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->config_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->config_vfunc); idx = idx->next; } LogMessage("-------------------------------------------------\n\n"); } void AddFuncToOutputList(SnortConfig *sc, OutputFunc o_func, OutputType type, void *arg) { switch (type) { case OUTPUT_TYPE__ALERT: if (sc->head_tmp != NULL) AppendOutputFuncList(o_func, arg, &sc->head_tmp->AlertList); else AppendOutputFuncList(o_func, arg, &AlertList); break; case OUTPUT_TYPE__LOG: if (sc->head_tmp != NULL) AppendOutputFuncList(o_func, arg, &sc->head_tmp->LogList); else AppendOutputFuncList(o_func, arg, &LogList); break; default: /* just to be error-prone */ FatalError("Unknown output type: %i. Possible bug, please " "report.\n", type); } } #ifdef DUMP_BUFFER /**************************************************************************** * * Function: AddBDFuncToOutputList() * * Purpose: This function is called only when buffer dump is enabled. For * BufferDump output plugin, bdfptr points to LogBufferDump function. For all * other output plugins, bdfptr points to NULL. * * Arguments: sc => snort config * o_func => output plugin function * type => alert or log types * arg => pointer to output stream to which buffers will be dumped * * Returns: void function * ***************************************************************************/ void AddBDFuncToOutputList(SnortConfig *sc, OutputFunc o_func, OutputType type, void *arg) { OutputFuncNode *node; if (sc->head_tmp != NULL) node = sc->head_tmp->LogList; else node = LogList; while (node->next != NULL) node = node->next; node->bdfptr = o_func; } #endif void AppendOutputFuncList(OutputFunc o_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 = o_func; node->arg = arg; #ifdef DUMP_BUFFER node->bdfptr = NULL; #endif } /************************** Miscellaneous Functions **************************/ /* functions to aid in cleaning up after plugins * Used for both rule options and output. Preprocessors have their own */ static inline void _AddFuncToPostConfigList(PostConfigFunc pl_post_func, void *arg, PostConfigFuncNode **list) { PostConfigFuncNode *node; node = (PostConfigFuncNode *)SnortAlloc(sizeof(PostConfigFuncNode)); if (*list == NULL) { *list = node; } else { PostConfigFuncNode *tmp = *list; while (tmp->next != NULL) tmp = tmp->next; tmp->next = node; } node->func = pl_post_func; node->arg = arg; } #ifdef SNORT_RELOAD void AddFuncToReloadList(PostConfigFunc pl_post_func, void *arg) { _AddFuncToPostConfigList(pl_post_func, arg, &plugin_reload_funcs); } #endif void AddFuncToCleanExitList(PluginSignalFunc pl_sig_func, void *arg) { AddFuncToSignalList(pl_sig_func, arg, &plugin_clean_exit_funcs); } void AddFuncToShutdownList(PluginSignalFunc pl_sig_func, void *arg) { AddFuncToSignalList(pl_sig_func, arg, &plugin_shutdown_funcs); } void AddFuncToPostConfigList(SnortConfig *sc, PostConfigFunc pl_post_func, void *arg) { _AddFuncToPostConfigList(pl_post_func, arg, &sc->plugin_post_config_funcs); } void AddFuncToSignalList(PluginSignalFunc pl_sig_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 = pl_sig_func; node->arg = arg; } void AddFuncToRuleOptParseCleanupList(RuleOptParseCleanupFunc ro_parse_clean_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 = ro_parse_clean_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); } } void RegisterGetHttpXffFields(GetHttpXffFieldsFunc fn) { if (!getHttpXffFieldsFunc) getHttpXffFieldsFunc = fn; } char** GetHttpXffFields(int* nFields) { if (getHttpXffFieldsFunc) return getHttpXffFieldsFunc(nFields); else return NULL; } snort-2.9.15.1/src/plugbase.h0000644000175200017520000003265613571422607012626 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifndef __PLUGBASE_H__ #define __PLUGBASE_H__ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "bitop_funcs.h" #include "rules.h" #include "treenodes.h" #include "sf_types.h" #include "snort_debug.h" #include "preprocids.h" #ifndef WIN32 # include #endif /* !WIN32 */ #ifdef ENABLE_SSL # ifdef Free /* Free macro in radix.h if defined, will conflict with OpenSSL definition */ # undef Free # endif #endif #ifndef WIN32 # include #endif /* !WIN32 */ #ifdef ENABLE_SSL # undef Free #endif #if defined(SOLARIS) || defined(FREEBSD) || defined(OPENBSD) # include #endif #if defined(FREEBSD) || defined(OPENBSD) || defined(NETBSD) || defined(OSF1) # include #endif #ifndef IFNAMSIZ /* IFNAMSIZ is defined in all platforms I checked.. */ # include #endif #include "preprocids.h" /* Macros *********************************************************************/ #define SMALLBUFFER 32 #define DETECTION_KEYWORD 0 #define RESPONSE_KEYWORD 1 #define ENCODING_HEX 0 #define ENCODING_BASE64 1 #define ENCODING_ASCII 2 #define DETAIL_FAST 0 #define DETAIL_FULL 1 /**************************** Rule Option Plugin API **************************/ typedef enum _RuleOptType { OPT_TYPE_ACTION = 0, OPT_TYPE_LOGGING, OPT_TYPE_DETECTION, OPT_TYPE_MAX } RuleOptType; typedef void (*RuleOptConfigFunc)(struct _SnortConfig *, char *, OptTreeNode *, int); typedef void (*RuleOptOtnHandler)(struct _SnortConfig *, OptTreeNode *); typedef void (*RuleOptOverrideFunc)(struct _SnortConfig *, char *, char *, char *, OptTreeNode *, int); typedef void (*RuleOptOverrideInitFunc)(char *, char *, RuleOptOverrideFunc); typedef int (*RuleOptEvalFunc)(void *, Packet *); typedef int (*ResponseFunc)(Packet*, void*); typedef void (*PluginSignalFunc)(int, void *); typedef void (*PluginSignalFuncWithSnortConfig)(struct _SnortConfig *, int, void *); typedef void (*PostConfigFunc)(struct _SnortConfig *, int, void *); typedef void (*RuleOptParseCleanupFunc)(void); typedef int (*RuleOptByteOrderFunc)(void *, int32_t); #define func fptr.fptr #define vfunc fptr.void_fptr typedef struct _RuleOptConfigFuncNode { char *keyword; RuleOptType type; union { RuleOptConfigFunc fptr; void *void_fptr; } fptr; RuleOptOtnHandler otn_handler; struct _RuleOptConfigFuncNode *next; } RuleOptConfigFuncNode; typedef struct _RuleOptOverrideInitFuncNode { char *keyword; RuleOptType type; union { RuleOptOverrideInitFunc fptr; void *void_fptr; } fptr; RuleOptOtnHandler otn_handler; struct _RuleOptOverrideInitFuncNode *next; } RuleOptOverrideInitFuncNode; typedef struct _RuleOptParseCleanupNode { union { RuleOptParseCleanupFunc fptr; void *void_fptr; } fptr; struct _RuleOptParseCleanupNode *next; } RuleOptParseCleanupNode; typedef struct _RuleOptByteOrderFuncNode { char *keyword; union { RuleOptByteOrderFunc fptr; void *void_fptr; } fptr; struct _RuleOptByteOrderFuncNode *next; } RuleOptByteOrderFuncNode; void RegisterRuleOptions(void); void RegisterRuleOption(char *, RuleOptConfigFunc, RuleOptOverrideInitFunc, RuleOptType, RuleOptOtnHandler); void RegisterOverrideKeyword(char *, char *, RuleOptOverrideFunc); void RegisterByteOrderKeyword(char *, RuleOptByteOrderFunc); void DumpRuleOptions(void); OptFpList * AddOptFuncToList(RuleOptEvalFunc, OptTreeNode *); void AddRspFuncToList(ResponseFunc, OptTreeNode *, void *); void FreeRuleOptConfigFuncs(RuleOptConfigFuncNode *); void FreeRuleOptOverrideInitFuncs(RuleOptOverrideInitFuncNode *); void AddFuncToRuleOptParseCleanupList(RuleOptParseCleanupFunc); void RuleOptParseCleanup(void); void FreeRuleOptParseCleanupList(RuleOptParseCleanupNode *); void RegisterByteOrderKeyword(char *, RuleOptByteOrderFunc); RuleOptByteOrderFunc GetByteOrderFunc(char *); void FreeRuleOptByteOrderFuncs(RuleOptByteOrderFuncNode *); /***************************** Buffer Dump API ********************************/ #ifdef DUMP_BUFFER void RegisterBufferTracer(TraceBuffer * (*)(), BUFFER_DUMP_FUNC); #endif /***************************** Non Rule Detection API *************************/ typedef void (*DetectionEvalFunc)(Packet *, void *); typedef struct _DetectionEvalFuncNode { void *context; uint16_t priority; uint32_t detect_id; //uint32_t detect_bit; uint32_t proto_mask; union { DetectionEvalFunc fptr; void *void_fptr; } fptr; struct _DetectionEvalFuncNode *next; } DetectionEvalFuncNode; DetectionEvalFuncNode * AddFuncToDetectionList(struct _SnortConfig *, DetectionEvalFunc, uint16_t, uint32_t, uint32_t); void FreeDetectionEvalFuncs(DetectionEvalFuncNode *); /***************************** Preprocessor API *******************************/ typedef void (*PreprocConfigFunc)(struct _SnortConfig *, char *); typedef void (*PreprocStatsFunc)(int); typedef void (*PreprocEvalFunc)(Packet *, void *); typedef int (*PreprocCheckConfigFunc)(struct _SnortConfig *); typedef void (*PreprocSignalFunc)(int, void *); typedef void (*PreprocPostConfigFunc)(struct _SnortConfig *, void *); typedef void (*PreprocMetaEvalFunc)(int, const uint8_t *); typedef void (*PeriodicFunc)(int, void *); #ifdef SNORT_RELOAD struct _PreprocConfigFuncNode; typedef struct _PreprocessorSwapData { struct _PreprocConfigFuncNode *preprocNode; void *data; struct _PreprocessorSwapData *next; } PreprocessorSwapData; typedef void (*PreprocReloadFunc)(struct _SnortConfig *, char *, void **); typedef int (*PreprocReloadVerifyFunc)(struct _SnortConfig *, void *); typedef void * (*PreprocReloadSwapFunc)(struct _SnortConfig *, void *); typedef void (*PreprocReloadSwapFreeFunc)(void *); #endif #define config_func cfptr.fptr #define config_vfunc cfptr.void_fptr typedef struct _PreprocConfigFuncNode { char *keyword; union { PreprocConfigFunc fptr; void *void_fptr; } cfptr; #ifdef SNORT_RELOAD /* Tells whether we call the config func or reload func */ int initialized; PreprocReloadFunc reload_func; PreprocReloadVerifyFunc reload_verify_func; PreprocReloadSwapFunc reload_swap_func; PreprocReloadSwapFreeFunc reload_swap_free_func; #endif struct _PreprocConfigFuncNode *next; } PreprocConfigFuncNode; typedef struct _PreprocStatsFuncNode { char *keyword; union { PreprocStatsFunc fptr; void *void_fptr; } fptr; struct _PreprocStatsFuncNode *next; } PreprocStatsFuncNode; typedef struct _PreprocEvalFuncNode { void *context; uint16_t priority; uint32_t preproc_id; PreprocEnableMask preproc_bit; uint32_t proto_mask; union { PreprocEvalFunc fptr; void *void_fptr; } fptr; struct _PreprocEvalFuncNode *next; } PreprocEvalFuncNode; typedef struct _PreprocMetaEvalFuncNode { uint16_t priority; uint32_t preproc_id; PreprocEnableMask preproc_bit; union { PreprocMetaEvalFunc fptr; void *void_fptr; } fptr; struct _PreprocMetaEvalFuncNode *next; } PreprocMetaEvalFuncNode; typedef struct _PreprocCheckConfigFuncNode { union { PreprocCheckConfigFunc fptr; void *void_fptr; } fptr; struct _PreprocCheckConfigFuncNode *next; } PreprocCheckConfigFuncNode; typedef struct _PreprocSignalFuncNode { void *arg; uint16_t priority; uint32_t preproc_id; union { PreprocSignalFunc fptr; void *void_fptr; } fptr; struct _PreprocSignalFuncNode *next; } PreprocSignalFuncNode; typedef struct _PreprocPostConfigFuncNode { void *data; union { PreprocPostConfigFunc fptr; void *void_fptr; } fptr; struct _PreprocPostConfigFuncNode *next; } PreprocPostConfigFuncNode; typedef struct _PeriodicCheckFuncNode { void *arg; uint16_t priority; uint32_t preproc_id; uint32_t period; uint32_t time_left; union { PeriodicFunc fptr; void *void_fptr; } fptr; struct _PeriodicCheckFuncNode *next; } PeriodicCheckFuncNode; struct _SnortConfig; void RegisterPreprocessors(void); #ifndef SNORT_RELOAD void RegisterPreprocessor(const char *, PreprocConfigFunc); #else void RegisterPreprocessor(const char *, PreprocConfigFunc, PreprocReloadFunc, PreprocReloadVerifyFunc, PreprocReloadSwapFunc, PreprocReloadSwapFreeFunc); void *GetRelatedReloadData(struct _SnortConfig *, const char *); void *GetReloadStreamConfig(struct _SnortConfig *sc); #endif PreprocConfigFuncNode * GetPreprocConfig(char *); PreprocConfigFunc GetPreprocConfigFunc(char *); void RegisterPreprocStats(const char *, PreprocStatsFunc); void DumpPreprocessors(void); void AddFuncToConfigCheckList(struct _SnortConfig *, PreprocCheckConfigFunc); void AddFuncToPreprocPostConfigList(struct _SnortConfig *, PreprocPostConfigFunc, void *); int CheckPreprocessorsConfig(struct _SnortConfig *); PreprocEvalFuncNode * AddFuncToPreprocList(struct _SnortConfig *, PreprocEvalFunc, uint16_t, uint32_t, uint32_t); void AddFuncToPreprocListAllNapPolicies(struct _SnortConfig *sc, PreprocEvalFunc pp_eval_func, uint16_t priority, uint32_t preproc_id, uint32_t proto_mask); PreprocMetaEvalFuncNode * AddFuncToPreprocMetaEvalList(struct _SnortConfig *, PreprocMetaEvalFunc, uint16_t, uint32_t); void AddFuncToPreprocCleanExitList(PreprocSignalFunc, void *, uint16_t, uint32_t); void AddFuncToPreprocShutdownList(PreprocSignalFunc, void *, uint16_t, uint32_t); void AddFuncToPreprocResetList(PreprocSignalFunc, void *, uint16_t, uint32_t); void AddFuncToPreprocResetStatsList(PreprocSignalFunc, void *, uint16_t, uint32_t); int IsPreprocEnabled(struct _SnortConfig *, uint32_t); void FreePreprocConfigFuncs(void); void FreePreprocCheckConfigFuncs(PreprocCheckConfigFuncNode *); void FreePreprocStatsFuncs(PreprocStatsFuncNode *); void FreePreprocEvalFuncs(PreprocEvalFuncNode *); void FreePreprocMetaEvalFuncs(PreprocMetaEvalFuncNode *); void FreePreprocSigFuncs(PreprocSignalFuncNode *); void FreePreprocPostConfigFuncs(PreprocPostConfigFuncNode *); void PostConfigPreprocessors(struct _SnortConfig *); void FilterConfigPreprocessors(struct _SnortConfig *sc); #ifdef SNORT_RELOAD int VerifyReloadedPreprocessors(struct _SnortConfig *); void SwapPreprocConfigurations(struct _SnortConfig *); void FreeSwappedPreprocConfigurations(struct _SnortConfig *); void FreePreprocessorReloadData(struct _SnortConfig *); #endif void AddFuncToPeriodicCheckList(PeriodicFunc, void *, uint16_t, uint32_t, uint32_t); void FreePeriodicFuncs(PeriodicCheckFuncNode *head); static inline void DisableAppPreprocessors( Packet *p ) { p->preprocessor_bits &= ( PP_CLASS_NETWORK | PP_CLASS_NGFW ); } static inline void DisableAllPreprocessors( Packet *p ) { p->preprocessor_bits = PP_DISABLE_ALL; } static inline int EnablePreprocessor(Packet *p, unsigned int preproc_id) { p->preprocessor_bits |= (UINT64_C(1) << preproc_id); return 0; } static inline void EnablePreprocessors(Packet *p, PreprocEnableMask enabled_pps) { p->preprocessor_bits = enabled_pps; } static inline int IsPreprocessorEnabled(Packet *p, PreprocEnableMask preproc_bit) { return ( ( p->preprocessor_bits & preproc_bit ) != 0 ); } void DisableAllPolicies(struct _SnortConfig *); int ReenablePreprocBit(struct _SnortConfig *, unsigned int preproc_id); /************************** Miscellaneous Functions **************************/ typedef struct _PluginSignalFuncNode { void *arg; union { PluginSignalFunc fptr; void *void_fptr; } fptr; struct _PluginSignalFuncNode *next; } PluginSignalFuncNode; typedef struct _PostConfigFuncNode { void *arg; union { PostConfigFunc fptr; void *void_fptr; } fptr; struct _PostConfigFuncNode *next; } PostConfigFuncNode; /* Used for both rule options and output. Preprocessors have their own */ #ifdef SNORT_RELOAD void AddFuncToReloadList(PostConfigFunc, void *); #endif void AddFuncToCleanExitList(PluginSignalFunc, void *); void AddFuncToShutdownList(PluginSignalFunc, void *); void AddFuncToPostConfigList(struct _SnortConfig *, PostConfigFunc, void *); void AddFuncToSignalList(PluginSignalFunc, void *, PluginSignalFuncNode **); void PostConfigInitPlugins(struct _SnortConfig *, PostConfigFuncNode *); void FreePluginSigFuncs(PluginSignalFuncNode *); void FreePluginPostConfigFuncs(PostConfigFuncNode *); typedef char** (*GetHttpXffFieldsFunc)(int* nFields); char** GetHttpXffFields(int* nFields); void RegisterGetHttpXffFields(GetHttpXffFieldsFunc fn); #endif /* __PLUGBASE_H__ */ snort-2.9.15.1/src/preprocids.h0000644000175200017520000001731313571422607013167 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2005-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #ifndef _PREPROC_IDS_H #define _PREPROC_IDS_H #include #ifdef DUMP_BUFFER #include "sf_types.h" #endif /* ** Preprocessor Communication Defines ** ---------------------------------- ** These defines allow preprocessors to be turned ** on and off for each packet. Preprocessors can be ** turned off and on before preprocessing occurs and ** during preprocessing. ** ** Currently, the order in which the preprocessors are ** placed in the snort.conf determine the order of ** evaluation. So if one module wants to turn off ** another module, it must come first in the order. */ // currently 64 bits (preprocessors) // are available. #define PP_BO 0 #define PP_APP_ID 1 #define PP_DNS 2 #define PP_FRAG3 3 #define PP_FTPTELNET 4 #define PP_HTTPINSPECT 5 #define PP_PERFMONITOR 6 #define PP_RPCDECODE 7 #define PP_SHARED_RULES 8 #define PP_SFPORTSCAN 9 #define PP_SMTP 10 #define PP_SSH 11 #define PP_SSL 12 #define PP_STREAM 13 #define PP_TELNET 14 #define PP_ARPSPOOF 15 #define PP_DCE2 16 #define PP_SDF 17 #define PP_NORMALIZE 18 #define PP_ISAKMP 19 // used externally #define PP_SESSION 20 #define PP_SIP 21 #define PP_POP 22 #define PP_IMAP 23 #define PP_NETWORK_DISCOVERY 24 // used externally #define PP_FW_RULE_ENGINE 25 // used externally #define PP_REPUTATION 26 #define PP_GTP 27 #define PP_MODBUS 28 #define PP_DNP3 29 #define PP_FILE 30 #define PP_FILE_INSPECT 31 #define PP_NAP_RULE_ENGINE 32 #define PP_PREFILTER_RULE_ENGINE 33 // used externally #define PP_HTTPMOD 34 #define PP_HTTP2 35 #define PP_CIP 36 #define PP_MAX 37 #define PP_ALL 50 #define PP_ENABLE_ALL (~0) #define PP_DISABLE_ALL 0x0 #ifdef WIN32 #ifndef UINT64_C #define UINT64_C(v) (v) #endif #endif // preprocessors that run before or as part of Network Analysis Policy processing... If enabled by // configuration they are never disabled #define PP_CLASS_NETWORK ( ( UINT64_C(1) << PP_FRAG3 ) | ( UINT64_C(1) << PP_PERFMONITOR ) | \ ( UINT64_C(1) << PP_SFPORTSCAN ) | ( UINT64_C(1) << PP_STREAM ) | \ ( UINT64_C(1) << PP_NORMALIZE ) | ( UINT64_C(1) << PP_SESSION ) | \ ( UINT64_C(1) << PP_REPUTATION ) ) // Firewall and Application ID & Netowrk Discovery preprocessors...also always run if enabled by configuration #define PP_CLASS_NGFW ( ( UINT64_C(1) << PP_APP_ID ) | ( UINT64_C(1) << PP_FW_RULE_ENGINE ) | \ ( UINT64_C(1) << PP_NETWORK_DISCOVERY ) | ( UINT64_C(1) << PP_PREFILTER_RULE_ENGINE ) | \ ( UINT64_C(1) << PP_HTTPMOD) ) // Application preprocessors...once the application or protocol for a stream is determined only preprocessors // that analyze that type of stream are enabled (usually there is only 1...) #define PP_CLASS_PROTO_APP ( ( UINT64_C(1) << PP_BO ) | ( UINT64_C(1) << PP_DNS ) | \ ( UINT64_C(1) << PP_FTPTELNET ) | ( UINT64_C(1) << PP_HTTPINSPECT ) | \ ( UINT64_C(1) << PP_RPCDECODE ) | ( UINT64_C(1) << PP_SHARED_RULES ) | \ ( UINT64_C(1) << PP_SMTP ) | ( UINT64_C(1) << PP_SSH ) | \ ( UINT64_C(1) << PP_SSL ) | ( UINT64_C(1) << PP_TELNET ) | \ ( UINT64_C(1) << PP_ARPSPOOF ) | ( UINT64_C(1) << PP_DCE2 ) | \ ( UINT64_C(1) << PP_SDF ) | ( UINT64_C(1) << PP_ISAKMP) | \ ( UINT64_C(1) << PP_POP ) | ( UINT64_C(1) << PP_IMAP ) | \ ( UINT64_C(1) << PP_GTP ) | ( UINT64_C(1) << PP_MODBUS ) | \ ( UINT64_C(1) << PP_DNP3 ) | ( UINT64_C(1) << PP_FILE ) | \ ( UINT64_C(1) << PP_FILE_INSPECT ) ) #define PP_DEFINED_GLOBAL ( ( UINT64_C(1) << PP_APP_ID ) | ( UINT64_C(1) << PP_FW_RULE_ENGINE ) | \ ( UINT64_C(1) << PP_NETWORK_DISCOVERY ) | ( UINT64_C(1) << PP_PERFMONITOR) | \ ( UINT64_C(1) << PP_SESSION ) | ( UINT64_C(1) << PP_PREFILTER_RULE_ENGINE ) ) #define PP_CORE_ORDER_SESSION 0 #define PP_CORE_ORDER_IPREP 1 #define PP_CORE_ORDER_NAP 2 #define PP_CORE_ORDER_NORML 3 #define PP_CORE_ORDER_FRAG3 4 #define PP_CORE_ORDER_PREFILTER 5 // used externally #define PP_CORE_ORDER_STREAM 6 #define PRIORITY_CORE 0x0 #define PRIORITY_CORE_LAST 0x0f #define PRIORITY_FIRST 0x10 #define PRIORITY_NETWORK 0x20 #define PRIORITY_TRANSPORT 0x100 #define PRIORITY_TUNNEL 0x105 #define PRIORITY_SCANNER 0x110 #define PRIORITY_APPLICATION 0x200 #define PRIORITY_LAST 0xffff #ifdef DUMP_BUFFER /* dump_alert_only makes sure that bufferdump happens only when a rule is triggered. dumped_state avoids repeatition of buffer dump for a packet that has an alert, when --buffer-dump is given as command line option. dump_enabled gets set when --buffer-dump or --buffer-dump-alert option is given. */ extern bool dump_alert_only; extern bool dumped_state; extern bool dump_enabled; #define MAX_BUFFER_DUMP_FUNC 13 #define MAX_HTTP_BUFFER_DUMP 16 #define MAX_SMTP_BUFFER_DUMP 7 #define MAX_SIP_BUFFER_DUMP 16 #define MAX_DNP3_BUFFER_DUMP 4 #define MAX_POP_BUFFER_DUMP 7 #define MAX_MODBUS_BUFFER_DUMP 3 #define MAX_SSH_BUFFER_DUMP 11 #define MAX_DNS_BUFFER_DUMP 10 #define MAX_DCERPC2_BUFFER_DUMP 7 #define MAX_FTPTELNET_BUFFER_DUMP 7 #define MAX_IMAP_BUFFER_DUMP 4 #define MAX_SSL_BUFFER_DUMP 4 #define MAX_GTP_BUFFER_DUMP 6 typedef enum { HTTP_BUFFER_DUMP_FUNC, SMTP_BUFFER_DUMP_FUNC, SIP_BUFFER_DUMP_FUNC, DNP3_BUFFER_DUMP_FUNC, POP_BUFFER_DUMP_FUNC, MODBUS_BUFFER_DUMP_FUNC, SSH_BUFFER_DUMP_FUNC, DNS_BUFFER_DUMP_FUNC, DCERPC2_BUFFER_DUMP_FUNC, FTPTELNET_BUFFER_DUMP_FUNC, IMAP_BUFFER_DUMP_FUNC, SSL_BUFFER_DUMP_FUNC, GTP_BUFFER_DUMP_FUNC } BUFFER_DUMP_FUNC; typedef struct _TraceBuffer { char *buf_name; char *buf_content; uint16_t length; } TraceBuffer; typedef uint64_t BufferDumpEnableMask; extern TraceBuffer *(*getBuffers[MAX_BUFFER_DUMP_FUNC])(void); extern BufferDumpEnableMask bdmask; #endif typedef uint64_t PreprocEnableMask; #endif /* _PREPROC_IDS_H */ snort-2.9.15.1/src/snort.c0000644000175200017520000051627513571422607012170 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * * Program: Snort * * Purpose: Check out the README file for info on what you can do * with Snort. * * Author: Martin Roesch (roesch@clark.net) * * Comments: Ideas and code stolen liberally from Mike Borella's IP Grab * program. Check out his stuff at http://www.borella.net. I * also have ripped some util functions from TCPdump, plus Mike's * prog is derived from it as well. All hail TCPdump.... * */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef HAVE_GETTID #define _GNU_SOURCE #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_MALLOC_TRIM #include #endif #ifndef WIN32 #include #else #include #endif #ifdef HAVE_GETOPT_LONG //#define _GNU_SOURCE /* A GPL copy of getopt & getopt_long src code is now in sfutil */ # undef HAVE_GETOPT_LONG #endif #include #ifdef HAVE_STRINGS_H # include #endif #ifndef WIN32 # include # include # include # include # include #endif /* !WIN32 */ #if !defined(CATCH_SEGV) && !defined(WIN32) # include #endif #include "decode.h" #include "encode.h" #include "sfdaq.h" #include "active.h" #include "snort.h" #include "rules.h" #include "treenodes.h" #include "plugbase.h" #include "snort_debug.h" #include "util.h" #include "parser.h" #include "tag.h" #include "log.h" #include "detect.h" #include "mstring.h" #include "fpcreate.h" #include "fpdetect.h" #include "sfthreshold.h" #include "rate_filter.h" #include "packet_time.h" #include "detection-plugins/sp_flowbits.h" #include "preprocessors/spp_perfmonitor.h" #include "preprocessors/perf-base.h" #include "preprocessors/perf.h" #include "mempool.h" #include "strlcpyu.h" #include "sflsq.h" #include "sp_replace.h" #include "output-plugins/spo_log_tcpdump.h" #include "event_queue.h" #include "asn1.h" #include "mpse.h" #include "generators.h" #include "ppm.h" #include "profiler.h" #include "dynamic-plugins/sp_dynamic.h" #include "dynamic-plugins/sf_dynamic_define.h" #include "dynamic-output/plugins/output.h" #include "sfutil/strvec.h" #include "detection_util.h" #include "sfcontrol_funcs.h" #include "idle_processing_funcs.h" #include "file_service.h" #include "pkt_tracer.h" #include "session_expect.h" #include "reload.h" #include "reg_test.h" #include "memory_stats.h" #ifdef SIDE_CHANNEL # include "sidechannel.h" #endif #include "dynamic-plugins/sf_dynamic_engine.h" #include "dynamic-plugins/sf_dynamic_detection.h" #define PROFILE_PREPROCS_NOREDEF #include "dynamic-plugins/sf_dynamic_preprocessor.h" #include "dynamic-plugins/sp_preprocopt.h" #ifdef SIDE_CHANNEL # include "dynamic-plugins/sf_dynamic_side_channel.h" #endif #ifdef TARGET_BASED # include "target-based/sftarget_reader.h" #endif #ifdef EXIT_CHECK # include "cpuclock.h" #endif #include "sfActionQueue.h" #ifdef INTEL_SOFT_CPM #include "sfutil/intel-soft-cpm.h" #endif #include "session_api.h" #include "stream_common.h" #include "stream5_ha.h" #ifdef CONTROL_SOCKET #include "dump.h" #endif #ifdef PERF_PROFILING #include "perf_indicators.h" #endif /* Macros *********************************************************************/ #ifndef DLT_LANE8023 /* * Old OPEN BSD Log format is 17. * Define DLT_OLDPFLOG unless DLT_LANE8023 (Suse 6.3) is already * defined in bpf.h. */ # define DLT_OLDPFLOG 17 #endif #define ALERT_MODE_OPT__NONE "none" #define ALERT_MODE_OPT__PKT_CNT "packet-count" #define ALERT_MODE_OPT__FULL "full" #define ALERT_MODE_OPT__FAST "fast" #define ALERT_MODE_OPT__CONSOLE "console" #define ALERT_MODE_OPT__CMG "cmg" #define ALERT_MODE_OPT__JH "jh" #define ALERT_MODE_OPT__DJR "djr" #define ALERT_MODE_OPT__AJK "ajk" #define ALERT_MODE_OPT__UNIX_SOCK "unsock" #define ALERT_MODE_OPT__TEST "test" #define LOG_MODE_OPT__NONE "none" #define LOG_MODE_OPT__PCAP "pcap" #define LOG_MODE_OPT__ASCII "ascii" #ifdef MPLS # define MPLS_PAYLOAD_OPT__IPV4 "ipv4" # define MPLS_PAYLOAD_OPT__IPV6 "ipv6" # define MPLS_PAYLOAD_OPT__ETHERNET "ethernet" #endif #define DEFAULT_PAF_MAX 16384 /* Instead of 16k as Flowcount, We should use a smaller number for idle pruning in SnortIdle() to avoid AAB. * Now in snort Idle case, we will prune the sessions with in AAB timeout (Miminum configurable AAB value). * Tested and found out, on an average 0.2 ms is taking to prune one session. * FlowCount = (AAB timeout / time to prune onesession ) / 3 (tcp+udp+ip) */ #define AAB_THRESHOLD 250 #define TIME_TO_PRUNE_ONE_SESSION 0.2 const uint32_t FLOW_COUNT = (AAB_THRESHOLD/TIME_TO_PRUNE_ONE_SESSION) / 3; volatile int detection_lib_changed = 0; /* Data types *****************************************************************/ typedef enum _GetOptArgType { LONGOPT_ARG_NONE = 0, LONGOPT_ARG_REQUIRED, LONGOPT_ARG_OPTIONAL } GetOptArgType; /* Externs *******************************************************************/ /* Undefine the one from sf_dynamic_preprocessor.h */ #ifdef PERF_PROFILING extern PreprocStats detectPerfStats, decodePerfStats, metaPerfStats, totalPerfStats, eventqPerfStats, rulePerfStats, mpsePerfStats; extern PreprocStats ruleCheckBitPerfStats, ruleSetBitPerfStats, ruleFailedFlowbitsPerfStats; extern PreprocStats ruleRTNEvalPerfStats, ruleOTNEvalPerfStats, ruleHeaderNoMatchPerfStats; extern PreprocStats ruleAddEventQPerfStats, ruleNQEventQPerfStats; extern PreprocStats preprocRuleOptionPerfStats; #endif /* for getopt */ extern char *optarg; extern int optind; extern int opterr; extern int optopt; extern ListHead *head_tmp; /* Globals/Public *************************************************************/ PacketCount pc; /* packet count information */ uint32_t *netmasks = NULL; /* precalculated netmask array */ char **protocol_names = NULL; char *snort_conf_file = NULL; /* -c */ char *snort_conf_dir = NULL; SnortConfig *snort_cmd_line_conf = NULL; SnortConfig *snort_conf = NULL; int internal_log_level = INTERNAL_LOG_LEVEL__MESSAGE; tSfActionQueueId decoderActionQ = NULL; MemPool decoderAlertMemPool; VarNode *cmd_line_var_list = NULL; static pthread_mutex_t cleanup_mutex = PTHREAD_MUTEX_INITIALIZER; #ifdef TARGET_BASED pthread_t attribute_reload_thread_id; pid_t attribute_reload_thread_pid; volatile int attribute_reload_thread_running = 0; volatile int attribute_reload_thread_stop = 0; int reload_attribute_table_flags = 0; #endif volatile bool snort_initializing = true; volatile int snort_exiting = 0; volatile int already_exiting = 0; static pid_t snort_main_thread_pid = 0; #ifndef WIN32 static pthread_t snort_main_thread_id = 0; #endif #if defined(SNORT_RELOAD) && !defined(WIN32) volatile int snort_reload = 0; static pthread_t snort_reload_thread_id; volatile int snort_reload_thread_created = 0; pid_t snort_reload_thread_pid; #endif const struct timespec thread_sleep = { 0, 100 }; #ifdef OPENBSD const struct timespec packet_sleep = { 0, 1 }; #endif #ifdef HAVE_PCAP_LEX_DESTROY extern void pcap_lex_destroy(void); #endif PreprocConfigFuncNode *preproc_config_funcs = NULL; OutputConfigFuncNode *output_config_funcs = NULL; RuleOptConfigFuncNode *rule_opt_config_funcs = NULL; RuleOptOverrideInitFuncNode *rule_opt_override_init_funcs = NULL; RuleOptParseCleanupNode *rule_opt_parse_cleanup_list = NULL; RuleOptByteOrderFuncNode *rule_opt_byte_order_funcs = NULL; PreprocSignalFuncNode *preproc_clean_exit_funcs = NULL; PreprocSignalFuncNode *preproc_shutdown_funcs = NULL; PreprocSignalFuncNode *preproc_reset_funcs = NULL; PreprocSignalFuncNode *preproc_reset_stats_funcs = NULL; PreprocStatsFuncNode *preproc_stats_funcs = NULL; PluginSignalFuncNode *plugin_shutdown_funcs = NULL; PluginSignalFuncNode *plugin_clean_exit_funcs = NULL; #ifdef SNORT_RELOAD PostConfigFuncNode *plugin_reload_funcs = NULL; #endif OutputFuncNode *AlertList = NULL; /* Alert function list */ OutputFuncNode *LogList = NULL; /* Log function list */ PeriodicCheckFuncNode *periodic_check_funcs = NULL; grinder_t grinder; pthread_mutex_t dynamic_rules_lock; #ifdef SIDE_CHANNEL pthread_mutex_t snort_process_lock; static bool snort_process_lock_held = false; #endif uint8_t iprep_current_update_counter; /* Locals/Private ************************************************************/ static long int pcap_loop_count = 0; static SF_QUEUE *pcap_save_queue = NULL; #if defined(INLINE_FAILOPEN) && !defined(WIN32) static pthread_t inline_failopen_thread_id; static pid_t inline_failopen_thread_pid; static volatile int inline_failopen_thread_running = 0; static volatile int inline_failopen_initialized = 0; static int inline_failopen_pass_pkt_cnt = 0; static void * SnortPostInitThread(void *); static DAQ_Verdict IgnoreCallback (void*, const DAQ_PktHdr_t*, const uint8_t*); #endif static char signal_error_msg[STD_BUF]; static int exit_signal = 0; static bool dump_stats_signal = false; static bool rotate_stats_signal = false; #ifdef TARGET_BASED static bool no_attr_table_signal = false; #endif #ifndef SNORT_RELOAD static volatile bool reload_signal = false; #else /* reload_signal is incremented in the signal handler for SIGNAL_SNORT_RELOAD * which is handled in the main thread. The reload thread compares the * reload_signal count to reload_total which it increments after an equality * test between reload_signal and reload_total fails (which means we got a new * SIGNAL_SNORT_RELOAD). They need to be the same type and size to do this * comparison. See ReloadConfigThread() */ volatile snort_reload_t reload_signal = 0; snort_reload_t reload_total = 0; #endif static int done_processing = 0; static int exit_logged = 0; static SF_LIST *pcap_object_list = NULL; static SF_QUEUE *pcap_queue = NULL; static char* pcap_filter = NULL; static int snort_argc = 0; static char **snort_argv = NULL; /* command line options for getopt */ static const char *valid_options = "?A:bB:c:CdDeEfF:" #ifndef WIN32 "g:" #endif "G:h:Hi:Ik:K:l:L:" #ifndef WIN32 "m:" #endif "Mn:NOpP:q" #ifndef WIN32 "Q" #endif "r:R:sS:" #ifndef WIN32 "t:" #endif "T" #ifndef WIN32 "u:" #endif "UvVw:" #ifdef WIN32 "W" #endif "XxyZ:" ; static struct option long_options[] = { {"logid", LONGOPT_ARG_REQUIRED, NULL, 'G'}, {"perfmon-file", LONGOPT_ARG_REQUIRED, NULL, 'Z'}, {"snaplen", LONGOPT_ARG_REQUIRED, NULL, 'P'}, {"version", LONGOPT_ARG_NONE, NULL, 'V'}, {"help", LONGOPT_ARG_NONE, NULL, '?'}, {"conf-error-out", LONGOPT_ARG_NONE, NULL,'x'}, {"dynamic-engine-lib", LONGOPT_ARG_REQUIRED, NULL, DYNAMIC_ENGINE_FILE}, {"dynamic-engine-lib-dir", LONGOPT_ARG_REQUIRED, NULL, DYNAMIC_ENGINE_DIRECTORY}, {"dynamic-detection-lib", LONGOPT_ARG_REQUIRED, NULL, DYNAMIC_LIBRARY_FILE}, {"dynamic-detection-lib-dir", LONGOPT_ARG_REQUIRED, NULL, DYNAMIC_LIBRARY_DIRECTORY}, {"dump-dynamic-rules", LONGOPT_ARG_REQUIRED, NULL, DUMP_DYNAMIC_RULES}, {"dynamic-preprocessor-lib", LONGOPT_ARG_REQUIRED, NULL, DYNAMIC_PREPROC_FILE}, {"dynamic-preprocessor-lib-dir", LONGOPT_ARG_REQUIRED, NULL, DYNAMIC_PREPROC_DIRECTORY}, {"dynamic-output-lib", LONGOPT_ARG_REQUIRED, NULL, DYNAMIC_OUTPUT_FILE}, {"dynamic-output-lib-dir", LONGOPT_ARG_REQUIRED, NULL, DYNAMIC_OUTPUT_DIRECTORY}, {"alert-before-pass", LONGOPT_ARG_NONE, NULL, ALERT_BEFORE_PASS}, {"treat-drop-as-alert", LONGOPT_ARG_NONE, NULL, TREAT_DROP_AS_ALERT}, {"treat-drop-as-ignore", LONGOPT_ARG_NONE, NULL, TREAT_DROP_AS_IGNORE}, {"process-all-events", LONGOPT_ARG_NONE, NULL, PROCESS_ALL_EVENTS}, {"pid-path", LONGOPT_ARG_REQUIRED, NULL, PID_PATH}, {"create-pidfile", LONGOPT_ARG_NONE, NULL, CREATE_PID_FILE}, {"nolock-pidfile", LONGOPT_ARG_NONE, NULL, NOLOCK_PID_FILE}, {"no-interface-pidfile", LONGOPT_ARG_NONE, NULL, NO_IFACE_PID_FILE}, #ifdef INLINE_FAILOPEN {"disable-inline-init-failopen", LONGOPT_ARG_NONE, NULL, DISABLE_INLINE_FAILOPEN}, #endif {"nostamps", LONGOPT_ARG_NONE, NULL, NO_LOGGING_TIMESTAMPS}, #ifdef TARGET_BASED {"disable-attribute-reload-thread", LONGOPT_ARG_NONE, NULL, DISABLE_ATTRIBUTE_RELOAD}, #endif {"pcap-single", LONGOPT_ARG_REQUIRED, NULL, PCAP_SINGLE}, {"pcap-file", LONGOPT_ARG_REQUIRED, NULL, PCAP_FILE_LIST}, {"pcap-list", LONGOPT_ARG_REQUIRED, NULL, PCAP_LIST}, #ifndef WIN32 {"pcap-dir", LONGOPT_ARG_REQUIRED, NULL, PCAP_DIR}, {"pcap-filter", LONGOPT_ARG_REQUIRED, NULL, PCAP_FILTER}, {"pcap-no-filter", LONGOPT_ARG_NONE, NULL, PCAP_NO_FILTER}, #endif {"pcap-loop", LONGOPT_ARG_REQUIRED, NULL, PCAP_LOOP}, {"pcap-reload", LONGOPT_ARG_NONE, NULL, PCAP_RELOAD}, {"pcap-reset", LONGOPT_ARG_NONE, NULL, PCAP_RESET}, {"pcap-show", LONGOPT_ARG_NONE, NULL, PCAP_SHOW}, #ifdef EXIT_CHECK {"exit-check", LONGOPT_ARG_REQUIRED, NULL, ARG_EXIT_CHECK}, #endif {"search-method", LONGOPT_ARG_REQUIRED, NULL, DETECTION_SEARCH_METHOD}, {"man", LONGOPT_ARG_REQUIRED, NULL, DETECTION_SEARCH_METHOD}, #ifdef MPLS {"enable-mpls-multicast", LONGOPT_ARG_NONE, NULL, ENABLE_MPLS_MULTICAST}, {"enable-mpls-overlapping-ip", LONGOPT_ARG_NONE, NULL, ENABLE_OVERLAPPING_IP}, {"max-mpls-labelchain-len", LONGOPT_ARG_REQUIRED, NULL, MAX_MPLS_LABELCHAIN_LEN}, {"mpls-payload-type", LONGOPT_ARG_REQUIRED, NULL, MPLS_PAYLOAD_TYPE}, #endif {"require-rule-sid", LONGOPT_ARG_NONE, NULL, REQUIRE_RULE_SID}, {"daq", LONGOPT_ARG_REQUIRED, NULL, ARG_DAQ_TYPE}, {"daq-mode", LONGOPT_ARG_REQUIRED, NULL, ARG_DAQ_MODE}, {"daq-var", LONGOPT_ARG_REQUIRED, NULL, ARG_DAQ_VAR}, {"daq-dir", LONGOPT_ARG_REQUIRED, NULL, ARG_DAQ_DIR}, {"daq-list", LONGOPT_ARG_OPTIONAL, NULL, ARG_DAQ_LIST}, {"dirty-pig", LONGOPT_ARG_NONE, NULL, ARG_DIRTY_PIG}, {"enable-inline-test", LONGOPT_ARG_NONE, NULL, ENABLE_INLINE_TEST}, {"cs-dir", LONGOPT_ARG_REQUIRED, NULL, ARG_CS_DIR}, {"ha-peer", LONGOPT_ARG_NONE, NULL, ARG_HA_PEER}, {"ha-out", LONGOPT_ARG_REQUIRED, NULL, ARG_HA_OUT}, {"ha-in", LONGOPT_ARG_REQUIRED, NULL, ARG_HA_IN}, {"ha-pdts-in", LONGOPT_ARG_REQUIRED, NULL, ARG_HA_PDTS_IN}, {"suppress-config-log", LONGOPT_ARG_NONE, NULL, SUPPRESS_CONFIG_LOG}, #ifdef DUMP_BUFFER {"buffer-dump", LONGOPT_ARG_OPTIONAL, NULL, BUFFER_DUMP}, {"buffer-dump-alert", LONGOPT_ARG_OPTIONAL, NULL, BUFFER_DUMP_ALERT}, #endif {0, 0, 0, 0} }; #ifdef DUMP_BUFFER bool dump_alert_only; bool dumped_state; bool dump_enabled; TraceBuffer *(*getBuffers[MAX_BUFFER_DUMP_FUNC])(void); BufferDumpEnableMask bdmask; #endif typedef void (*log_func_t)(Packet*); static void LogPacket (Packet* p) { pc.log_pkts++; CallLogPlugins(p, NULL, NULL); } static void IgnorePacket (Packet* p) { } static log_func_t log_func = IgnorePacket; /* Private function prototypes ************************************************/ static void InitNetmasks(void); static void InitProtoNames(void); static const char* GetPacketSource(char**); static void SnortInit(int, char **); static void InitPidChrootAndPrivs(pid_t); static void ParseCmdLine(int, char **); static int ShowUsage(char *); static void PrintVersion(SnortConfig *); static void SetSnortConfDir(void); static void InitGlobals(void); static void InitSignals(void); #if defined(NOCOREFILE) && !defined(WIN32) static void SetNoCores(void); #endif static void SnortCleanup(int); static void ParseCmdLineDynamicLibInfo(SnortConfig *, int, char *); static DynamicLibInfo * DupDynamicLibInfo(DynamicLibInfo *); static void FreeDynamicLibInfo(DynamicLibInfo *); static void FreeDynamicLibInfos(SnortConfig *); static void FreeOutputConfigs(OutputConfig *); #ifdef SIDE_CHANNEL static void FreeSideChannelModuleConfigs(SideChannelModuleConfig *); #endif static void FreePreprocConfigs(SnortConfig *); static void FreeRuleStateList(RuleState *); static void FreeClassifications(ClassType *); static void FreeReferences(ReferenceSystemNode *); static void FreePlugins(SnortConfig *); static void FreePreprocessors(SnortConfig *); static void SnortUnprivilegedInit(void); static int SetPktProcessor(void); static void PacketLoop(void); #if 0 static char * ConfigFileSearch(void); #endif static void SnortReset(void); static void LoadDynamicPlugins(SnortConfig *); static void SnortIdle(void); #ifndef WIN32 static void SnortStartThreads(void); #endif /* Signal handler declarations ************************************************/ static void SigDumpStatsHandler(int); static void SigExitHandler(int); static void SigReloadHandler(int); static void SigRotateStatsHandler(int); #ifdef CONTROL_SOCKET static void SigPipeHandler(int); #endif static void SigOopsHandler(int); int InMainThread () { return ( #ifndef WIN32 pthread_equal(snort_main_thread_id, pthread_self()) #else 1 #endif ); } bool SnortIsInitializing( ) { #if defined(INLINE_FAILOPEN) && !defined(WIN32) return snort_initializing && !inline_failopen_initialized; #else return snort_initializing; #endif } static int IsProcessingPackets(uint16_t type, const uint8_t *data, uint32_t length, void **new_config, char *statusBuf, int statusBuf_len) { return (!snort_initializing && !snort_exiting && !exit_signal) ? 0 : -1; } /* F U N C T I O N D E F I N I T I O N S **********************************/ #define INLINE_FAIL_OPEN_NOT_USED 0 #define INLINE_FAIL_OPEN_COMPLETE 1 #define INLINE_FAIL_OPEN_ERROR 2 static int InlineFailOpen (void) { #if defined(INLINE_FAILOPEN) && !defined(WIN32) int error = 0; if (ScAdapterInlineMode() && !ScReadMode() && !ScDisableInlineFailopen()) { /* If in inline mode, start a thread to handle the rest of snort * initialization, then dispatch packets until that initialization * is complete. */ LogMessage("Fail Open Thread starting..\n"); if (pthread_create(&inline_failopen_thread_id, NULL, SnortPostInitThread, NULL)) { ErrorMessage("Failed to start Fail Open Thread. " "Starting normally\n"); } else { while (!inline_failopen_thread_running) nanosleep(&thread_sleep, NULL); LogMessage("Fail Open Thread started tid=%p (pid=%u)\n", (void*)inline_failopen_thread_id, inline_failopen_thread_pid); # ifdef DEBUG { FILE *tmp = fopen("/var/tmp/fo_threadid", "w"); if ( tmp ) { fprintf(tmp, "Fail Open Thread PID: %u\n", inline_failopen_thread_pid); fclose(tmp); } } # endif DAQ_Start(); SetPktProcessor(); inline_failopen_initialized = 1; /* Passing packets is in the main thread because some systems * may have to refer to packet passing thread via process id * (linuxthreads) */ while (snort_initializing) { error = DAQ_Acquire(1, IgnoreCallback, NULL); if (error) break; } pthread_join(inline_failopen_thread_id, NULL); inline_failopen_thread_running = 0; LogMessage("Fail Open Thread terminated, passed %d packets.\n", inline_failopen_pass_pkt_cnt); if(error) return INLINE_FAIL_OPEN_ERROR; else return INLINE_FAIL_OPEN_COMPLETE; } } #endif return INLINE_FAIL_OPEN_NOT_USED; } /* * * Function: main(int, char *) * * Purpose: Handle program entry and exit, call main prog sections * This can handle both regular (command-line) style * startup, as well as Win32 Service style startup. * * Arguments: See command line args in README file * * Returns: 0 => normal exit, 1 => exit on error * */ int main(int argc, char *argv[]) { #if defined(WIN32) && defined(ENABLE_WIN32_SERVICE) /* Do some sanity checking, because some people seem to forget to * put spaces between their parameters */ if ((argc > 1) && ((_stricmp(argv[1], (SERVICE_CMDLINE_PARAM SERVICE_INSTALL_CMDLINE_PARAM)) == 0) || (_stricmp(argv[1], (SERVICE_CMDLINE_PARAM SERVICE_UNINSTALL_CMDLINE_PARAM)) == 0) || (_stricmp(argv[1], (SERVICE_CMDLINE_PARAM SERVICE_SHOW_CMDLINE_PARAM)) == 0))) { FatalError("You must have a space after the '%s' command-line parameter\n", SERVICE_CMDLINE_PARAM); } /* If the first parameter is "/SERVICE", then start Snort as a Win32 service */ if((argc > 1) && (_stricmp(argv[1],SERVICE_CMDLINE_PARAM) == 0)) { return SnortServiceMain(argc, argv); } #endif /* WIN32 && ENABLE_WIN32_SERVICE */ snort_argc = argc; snort_argv = argv; return SnortMain(argc, argv); } /* * * Function: SnortMain(int, char *) * * Purpose: The real place that the program handles entry and exit. Called * called by main(), or by SnortServiceMain(). * * Arguments: See command line args in README file * * Returns: 0 => normal exit, 1 => exit on error * */ int SnortMain(int argc, char *argv[]) { char* tmp_ptr = NULL; const char* intf; int daqInit; #ifndef WIN32 // must be done now in case of fatal error // and again after daemonization snort_main_thread_id = pthread_self(); #endif SnortInit(argc, argv); #if 0 sleep(10); #endif intf = GetPacketSource(&tmp_ptr); daqInit = intf || snort_conf->daq_type; if ( daqInit ) { DAQ_Init(snort_conf); DAQ_New(snort_conf, intf); DAQ_UpdateTunnelBypass(snort_conf); } if ( tmp_ptr ) free(tmp_ptr); if ( ScDaemonMode() ) { GoDaemon(); } // this must follow daemonization snort_main_thread_pid = gettid(); #ifndef WIN32 snort_main_thread_id = pthread_self(); #endif #ifndef WIN32 /* Change groups */ InitGroups(ScUid(), ScGid()); #endif #if !defined(HAVE_LINUXTHREADS) && !defined(WIN32) // this could be moved to linux threads location // and only done there SnortStartThreads(); #endif ReloadControlSocketRegister(); /* For SFR CLI*/ ControlSocketRegisterHandler(CS_TYPE_ACTION_STATS, NULL, NULL, &DisplayActionStats); if (ControlSocketRegisterHandler(CS_TYPE_IS_PROCESSING, &IsProcessingPackets, NULL, NULL)) { LogMessage("Failed to register the is processing control handler.\n"); } if (ControlSocketRegisterHandler(CS_TYPE_PKT_TRACER, &DebugPktTracer, NULL, NULL)) { LogMessage("Failed to register the packet tracer control handler.\n"); } #ifdef CONTROL_SOCKET if (ControlSocketRegisterHandler(CS_TYPE_DUMP_PACKETS, &PacketDumpCommand, NULL, NULL)) { LogMessage("Failed to register the packet dump control handler.\n"); } #endif if (ControlSocketRegisterHandler(CS_TYPE_MEM_USAGE, &MemoryPreFunction, &MemoryControlFunction, &MemoryPostFunction)) { LogMessage("Failed to register the memory stats display handler.\n"); } if ( ScTestMode() ) { if ( daqInit && DAQ_UnprivilegedStart() ) SetPktProcessor(); SnortUnprivilegedInit(); } else if ( DAQ_UnprivilegedStart() ) { SnortUnprivilegedInit(); SetPktProcessor(); DAQ_Start(); } else { switch(InlineFailOpen()) { case INLINE_FAIL_OPEN_COMPLETE: break; case INLINE_FAIL_OPEN_NOT_USED: DAQ_Start(); SetPktProcessor(); SnortUnprivilegedInit(); break; case INLINE_FAIL_OPEN_ERROR: default: CleanExit(1); return 0; } } #if defined(DAQ_CAPA_CST_TIMEOUT) Daq_Capa_Timeout = DAQ_CanGetTimeout(); if(getDaqCapaTimeoutFnPtr) { getDaqCapaTimeoutFnPtr(Daq_Capa_Timeout); } #endif #if defined(DAQ_CAPA_VRF) Daq_Capa_Vrf = DAQ_CanGetVrf(); #endif if(!exit_signal) PacketLoop(); // DAQ is shutdown in CleanExit() since we don't always return here CleanExit(0); return 0; } #ifndef WIN32 /* All threads need to be created after daemonizing. If created in * the parent thread, when it goes away, so will all of the threads. * The child does not "inherit" threads created in the parent. */ static void SnortStartThreads(void) { ControlSocketInit(); #ifdef SIDE_CHANNEL SideChannelStartTXThread(); #endif # ifdef SNORT_RELOAD if (ScIdsMode()) { LogMessage("Reload thread starting...\n"); if (pthread_create(&snort_reload_thread_id, NULL, ReloadConfigThread, NULL) != 0) { ErrorMessage("Could not create configuration reload thread.\n"); CleanExit(1); } while (!snort_reload_thread_created) nanosleep(&thread_sleep, NULL); LogMessage("Reload thread started, thread %p (%u)\n", (void*)snort_reload_thread_id, snort_reload_thread_pid); } # endif # ifdef TARGET_BASED if(IsAdaptiveConfigured() && !ScDisableAttrReload(snort_conf)) SFAT_StartReloadThread(); # endif } #else /* WIN32 */ //------------------------------------------------------------------------------ // interface stuff //------------------------------------------------------------------------------ static void PrintAllInterfaces (void) { char errorbuf[PCAP_ERRBUF_SIZE]; pcap_if_t *alldevs; pcap_if_t *dev; int j = 1; MIB_IFTABLE *iftable = NULL; unsigned int len = 0; unsigned int ret, i; if (pcap_findalldevs(&alldevs, errorbuf) == -1) FatalError("Could not get device list: %s.", errorbuf); /* max of two iterations here -- first to get the * correct length if not big enough. Second to * get the data. */ for (len = sizeof(iftable[0]); ; ) { if (iftable) free(iftable); iftable = SnortAlloc(len); ret = GetIfTable(iftable, &len, TRUE); if (ret == NO_ERROR) break; else if (ret != ERROR_INSUFFICIENT_BUFFER) FatalError("Could not get device list: %s.", errorbuf);; } printf("Index\tPhysical Address\tIP Address\tDevice Name\tDescription\n"); printf("-----\t----------------\t----------\t-----------\t-----------\n"); for (dev = alldevs; dev != NULL; dev = dev->next, j++) { uint8_t *mac_addr = NULL; for (i = 0; idwNumEntries; i++) { if (strncmp(dev->description, iftable->table[i].bDescr, iftable->table[i].dwDescrLen) == 0) { mac_addr = iftable->table[i].bPhysAddr; break; } } printf("%5d\t", j); if (mac_addr) { printf("%02X:%02X:%02X:%02X:%02X:%02X\t", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); } else { printf("00:00:00:00:00:00\t"); } if (dev->addresses) { struct sockaddr_in* saddr = (struct sockaddr_in*)dev->addresses->addr; sfcidr_t dev_ip; if ((saddr->sin_family == AF_INET) || (saddr->sin_family == AF_INET6)) { sfip_set_raw(&dev_ip, &saddr->sin_addr, saddr->sin_family); printf("%s\t", inet_ntoa(&dev_ip)); } else { printf("disabled\t"); } printf("%s\t%s\n", dev->name, dev->description); } else { printf("disabled\t%s\t%s\n", dev->name, dev->description); } } pcap_freealldevs(alldevs); free(iftable); } #endif /* WIN32 */ // pcap list stuff ... static void PQ_SetFilter (const char* f) { if (pcap_filter != NULL) free(pcap_filter); pcap_filter = f ? SnortStrdup(f) : NULL; } static void PQ_Single (const char* pcap) { PcapReadObject* pro; if (pcap_object_list == NULL) { pcap_object_list = sflist_new(); if (pcap_object_list == NULL) FatalError("Could not allocate list to store pcap\n"); } pro = (PcapReadObject *)SnortAlloc(sizeof(PcapReadObject)); pro->type = PCAP_SINGLE; pro->arg = SnortStrdup(pcap); pro->filter = NULL; if (sflist_add_tail(pcap_object_list, (NODE_DATA)pro) == -1) FatalError("Could not add pcap object to list: %s\n", pcap); } static void PQ_Multi (char type, const char* list) { PcapReadObject* pro; if (pcap_object_list == NULL) { pcap_object_list = sflist_new(); if (pcap_object_list == NULL) FatalError("Could not allocate list to store pcaps\n"); } pro = (PcapReadObject *)SnortAlloc(sizeof(PcapReadObject)); pro->type = type; pro->arg = SnortStrdup(list); if (pcap_filter != NULL) pro->filter = SnortStrdup(pcap_filter); else pro->filter = NULL; if (sflist_add_tail(pcap_object_list, (NODE_DATA)pro) == -1) FatalError("Could not add pcap object to list: %s\n", list); } static void PQ_SetUp (void) { if (pcap_object_list != NULL) { if (sflist_count(pcap_object_list) == 0) { sflist_free_all(pcap_object_list, NULL); FatalError("No pcaps specified.\n"); } pcap_queue = sfqueue_new(); pcap_save_queue = sfqueue_new(); if ((pcap_queue == NULL) || (pcap_save_queue == NULL)) FatalError("Could not allocate pcap queues.\n"); if (GetPcaps(pcap_object_list, pcap_queue) == -1) FatalError("Error getting pcaps.\n"); if (sfqueue_count(pcap_queue) == 0) FatalError("No pcaps found.\n"); /* free pcap list used to get params */ while (sflist_count(pcap_object_list) > 0) { PcapReadObject *pro = (PcapReadObject *)sflist_remove_head(pcap_object_list); if (pro == NULL) FatalError("Failed to remove pcap item from list.\n"); if (pro->arg != NULL) free(pro->arg); if (pro->filter != NULL) free(pro->filter); free(pro); } sflist_free_all(pcap_object_list, NULL); pcap_object_list = NULL; } if (pcap_filter != NULL) { free(pcap_filter); pcap_filter = NULL; } } static int PQ_CleanUp (void) { /* clean up pcap queues */ if (pcap_queue != NULL) sfqueue_free_all(pcap_queue, free); if (pcap_save_queue != NULL) sfqueue_free_all(pcap_save_queue, free); return 0; } static void PQ_Show (const char* pcap) { if ( !ScPcapShow() ) return; if ( !strcmp(pcap, "-") ) pcap = "stdin"; fprintf(stdout, "Reading network traffic from \"%s\" with snaplen = %d\n", pcap, DAQ_GetSnapLen()); } static const char* PQ_First (void) { const char* pcap = (char*)sfqueue_remove(pcap_queue); if ( !pcap ) return pcap; if ( sfqueue_add(pcap_save_queue, (NODE_DATA)pcap) == -1 ) FatalError("Could not add pcap to saved list\n"); return pcap; } // this must follow 2nd or later start and not stop because we force a // reset when the dlt changes even if not enabled with --pcap-reset to // avoid eventually flushing stream packets through a different grinder // than the one they were queued with. static void PQ_Reset () { static int dlt = -1; int new_dlt = DAQ_GetBaseProtocol(); if ( ScPcapReset() || ((dlt != new_dlt) && (dlt != -1)) ) SnortReset(); dlt = new_dlt; /* open a new tcpdump file - necessary because the snaplen and * datalink could be different between pcaps */ if (snort_conf->log_tcpdump) { /* this sleep is to ensure we get a new log file since it has a * time stamp with resolution to the second */ #ifdef WIN32 Sleep(1000); #else sleep(1); #endif LogTcpdumpReset(); } } static int PQ_Next (void) { char reopen_pcap = 0; if (sfqueue_count(pcap_queue) > 0) { reopen_pcap = 1; } else if (pcap_loop_count) { if (pcap_loop_count > 0) pcap_loop_count--; if (pcap_loop_count != 0) { SF_QUEUE *tmp; /* switch pcap lists */ tmp = pcap_queue; pcap_queue = pcap_save_queue; pcap_save_queue = tmp; reopen_pcap = 1; } } if (reopen_pcap) { /* reinitialize pcap */ const char* pcap = PQ_First(); if ( !pcap ) FatalError("Could not get pcap from list\n"); DAQ_Stop(); DAQ_Delete(); DAQ_New(snort_conf, pcap); DAQ_Start(); PQ_Reset(); PQ_Show(pcap); SetPktProcessor(); #if defined(SNORT_RELOAD) && !defined(WIN32) if ( snort_conf->run_flags & RUN_FLAG__PCAP_RELOAD && ScIdsMode()) { /* Awaiting user confirmation */ printf("Hit return to continue.\n"); fflush(stdout); while(getc(stdin) != '\n'); SigReloadHandler(SIGNAL_SNORT_RELOAD); while (!snort_reload) sleep(1); } #endif return 1; } return 0; } static char* GetFirstInterface (void) { char *iface = NULL; char errorbuf[PCAP_ERRBUF_SIZE]; #ifdef WIN32 pcap_if_t *alldevs; if ( (pcap_findalldevs(&alldevs, errorbuf) == -1) || !alldevs ) { FatalError( "Failed to lookup interface: %s. " "Please specify one with -i switch\n", errorbuf); } /* Pick first interface */ iface = SnortStrdup(alldevs->name); pcap_freealldevs(alldevs); #else DEBUG_WRAP(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); } DEBUG_WRAP(DebugMessage(DEBUG_INIT, "found interface %s\n", PRINT_INTERFACE(iface));); iface = SnortStrdup(iface); #endif return iface; } static const char* GetPacketSource (char** sptr) { const char* intf = "other"; if ( ScReadMode() ) { intf = PQ_First(); PQ_Show(intf); } else if ( !ScVersionMode() && !ScRuleDumpMode() ) { intf = snort_conf->interface; // don't get interface if daq is explicitly configured // since we can't assume that an interface is compatible if ( !intf && !ScTestMode() && (!snort_conf->daq_type || // but we make execptions for these: // TBD make selection based on DAQ_TYPE_XXX !strcasecmp(snort_conf->daq_type, "afpacket") || !strcasecmp(snort_conf->daq_type, "pcap") || !strcasecmp(snort_conf->daq_type, "dump")) ) { intf = GetFirstInterface(); *sptr = (char*)intf; } } return intf; } static void InitPidChrootAndPrivs(pid_t pid) { #ifndef WIN32 /* Drop the Chrooted Settings */ if (snort_conf->chroot_dir) SetChroot(snort_conf->chroot_dir, &snort_conf->log_dir); /* Drop privileges if requested, when initialization is done */ SetUidGid(ScUid(), ScGid()); #endif /* create the PID file */ if ( !ScReadMode() && (ScDaemonMode() || *snort_conf->pidfile_suffix || ScCreatePidFile())) { CreatePidFile(DAQ_GetInterfaceSpec(), pid); } } static void LoadDynamicPlugins(SnortConfig *sc) { unsigned i; if (sc == NULL) return; if (sc->dyn_engines != NULL) { /* Load the dynamic engines */ for (i = 0; i < sc->dyn_engines->count; i++) { switch (sc->dyn_engines->lib_paths[i]->ptype) { case PATH_TYPE__FILE: LoadDynamicEngineLib(sc, sc->dyn_engines->lib_paths[i]->path, 0); break; case PATH_TYPE__DIRECTORY: LoadAllDynamicEngineLibs(sc, sc->dyn_engines->lib_paths[i]->path); break; } } } if (sc->dyn_rules != NULL) { /* Load the dynamic detection libs */ for (i = 0; i < sc->dyn_rules->count; i++) { switch (sc->dyn_rules->lib_paths[i]->ptype) { case PATH_TYPE__FILE: LoadDynamicDetectionLib(sc, sc->dyn_rules->lib_paths[i]->path, 0); break; case PATH_TYPE__DIRECTORY: LoadAllDynamicDetectionLibs(sc, sc->dyn_rules->lib_paths[i]->path); break; } } } if (sc->dyn_preprocs != NULL) { /* Load the dynamic preprocessors */ for (i = 0; i < sc->dyn_preprocs->count; i++) { switch (sc->dyn_preprocs->lib_paths[i]->ptype) { case PATH_TYPE__FILE: LoadDynamicPreprocessor(sc, sc->dyn_preprocs->lib_paths[i]->path, 0); break; case PATH_TYPE__DIRECTORY: LoadAllDynamicPreprocessors(sc, sc->dyn_preprocs->lib_paths[i]->path); break; } } } # ifdef SIDE_CHANNEL if (sc->dyn_side_channels != NULL) { /* Load the dynamic side channels */ for (i = 0; i < sc->dyn_side_channels->count; i++) { switch (sc->dyn_side_channels->lib_paths[i]->ptype) { case PATH_TYPE__FILE: LoadDynamicSideChannelLib(sc, sc->dyn_side_channels->lib_paths[i]->path, 0); break; case PATH_TYPE__DIRECTORY: LoadAllDynamicSideChannelLibs(sc, sc->dyn_side_channels->lib_paths[i]->path); break; } } } # endif /* SIDE_CHANNEL */ ValidateDynamicEngines(sc); } static void DisplayDynamicPluginVersions(SnortConfig *sc) { void *lib = NULL; DynamicPluginMeta *meta; RemoveDuplicateEngines(); RemoveDuplicateDetectionPlugins(sc); RemoveDuplicatePreprocessorPlugins(); #ifdef SIDE_CHANNEL RemoveDuplicateSideChannelPlugins(); #endif /* SIDE_CHANNEL */ lib = GetNextEnginePluginVersion(NULL); while ( lib != NULL ) { meta = GetDetectionPluginMetaData(lib); LogMessage(" Rules Engine: %s Version %d.%d \n", meta->uniqueName, meta->major, meta->minor, meta->build); lib = GetNextEnginePluginVersion(lib); } lib = GetNextDetectionPluginVersion(sc, NULL); while ( lib != NULL ) { meta = GetEnginePluginMetaData(lib); LogMessage(" Rules Object: %s Version %d.%d \n", meta->uniqueName, meta->major, meta->minor, meta->build); lib = GetNextDetectionPluginVersion(sc, lib); } lib = GetNextPreprocessorPluginVersion(NULL); while ( lib != NULL ) { meta = GetPreprocessorPluginMetaData(lib); LogMessage(" Preprocessor Object: %s Version %d.%d \n", meta->uniqueName, meta->major, meta->minor, meta->build); lib = GetNextPreprocessorPluginVersion(lib); } #ifdef SIDE_CHANNEL lib = GetNextSideChannelPluginVersion(NULL); while ( lib != NULL ) { meta = GetSideChannelPluginMetaData(lib); LogMessage(" Side Channel Object: %s Version %d.%d \n", meta->uniqueName, meta->major, meta->minor, meta->build); lib = GetNextSideChannelPluginVersion(lib); } #endif /* SIDE_CHANNEL */ lib = GetNextOutputModule(NULL); while ( lib != NULL ) { LogMessage(" Output Module: %s Version %u\n", GetOutputModuleName(lib), GetOutputModuleVersion(lib)); lib = GetNextOutputModule(lib); } } /* * This function will print versioning information regardless of whether or * not the quiet flag is set. If the quiet flag has been set and we want * to honor it, check it before calling this function. */ static void PrintVersion(SnortConfig *sc) { DisplayBanner(); /* Get and print out library versions. * This information would be printed only for one Snort instance which doesn't * have --suppress-config-log option. For Snort instances with --supress-config-log, * we print only banner to provide some info about Snort process being started/reloaded. * This change is done to avoid duplicate logging of plugin information. */ if (ScSuppressConfigLog()) ScSetInternalLogLevel(INTERNAL_LOG_LEVEL__ERROR); DisplayDynamicPluginVersions(sc); ScRestoreInternalLogLevel(); } static void PrintDaqModules (SnortConfig* sc, char* dir) { if ( dir ) ConfigDaqDir(sc, dir); DAQ_Load(snort_conf); DAQ_PrintTypes(stdout); DAQ_Unload(); } #ifdef EXIT_CHECK static uint64_t exitTime = 0; static void ExitCheckStart (void) { if ( exitTime ) { return; } LogMessage("Exit Check: signaling at " STDu64 "callback\n", pc.total_from_daq); get_clockticks(exitTime); #ifndef WIN32 kill(0, SIGINT); // send to all processes in my process group #else raise(SIGINT); #endif } static void ExitCheckEnd (void) { uint64_t now = 0; double usecs = 0.0; if ( !exitTime ) { LogMessage( "Exit Check: callbacks = " STDu64 "(limit not reached)\n", pc.total_from_daq ); return; } get_clockticks(now); exitTime = now - exitTime; usecs = exitTime / get_ticks_per_usec(); LogMessage("Exit Check: usecs = %f\n", usecs); } #endif #ifdef HAVE_DAQ_ACQUIRE_WITH_META static int MetaCallback( void* user, const DAQ_MetaHdr_t *metahdr, const uint8_t* data) { tSfPolicyId policy_id = getDefaultPolicy(); SnortPolicy *policy; PreprocMetaEvalFuncNode *idx; PROFILE_VARS; #ifdef SIDE_CHANNEL if (ScSideChannelEnabled() && !snort_process_lock_held) { pthread_mutex_lock(&snort_process_lock); snort_process_lock_held = true; } #endif /* First thing we do is process a Usr signal that we caught */ if (SignalCheck()) { #ifndef SNORT_RELOAD /* Got SIGNAL_SNORT_RELOAD */ Restart(); #endif } CheckForReload(); PREPROC_PROFILE_START(metaPerfStats); policy = snort_conf->targeted_policies[policy_id]; idx = policy->preproc_meta_eval_funcs; while (idx != NULL) { idx->func(metahdr->type, data); idx = idx->next; } PREPROC_PROFILE_END(metaPerfStats); #if defined(WIN32) && defined(ENABLE_WIN32_SERVICE) if (ScTerminateService() || ScPauseService()) { return 0; // time to go } #endif #ifdef SNORT_RELOAD ReloadAdjust(false, 0); #endif ControlSocketDoWork(0); #ifdef SIDE_CHANNEL SideChannelDrainRX(0); #endif return 0; } #endif void SetupMetadataCallback(void) { #ifdef HAVE_DAQ_ACQUIRE_WITH_META DAQ_Set_MetaCallback(&MetaCallback); #endif } // non-local for easy access from core static Packet s_packet; static DAQ_PktHdr_t s_pkth; static uint8_t s_data[65536]; static DAQ_Verdict PacketCallback( void* user, const DAQ_PktHdr_t* pkthdr, const uint8_t* pkt) { int inject = 0; DAQ_Verdict verdict = DAQ_VERDICT_PASS; verdict_reason = VERDICT_REASON_NO_BLOCK; PROFILE_VARS; PREPROC_PROFILE_START_PI(totalPerfStats); #ifdef SIDE_CHANNEL if (ScSideChannelEnabled() && !snort_process_lock_held) { pthread_mutex_lock(&snort_process_lock); snort_process_lock_held = true; } #endif #ifdef EXIT_CHECK if (snort_conf->exit_check && (pc.total_from_daq >= snort_conf->exit_check)) ExitCheckStart(); #endif /* First thing we do is process a Usr signal that we caught */ if (SignalCheck()) { #ifndef SNORT_RELOAD /* Got SIGNAL_SNORT_RELOAD */ PREPROC_PROFILE_END_PI(totalPerfStats); Restart(); #endif } pc.total_from_daq++; /* Increment counter that we're evaling rules for caching results */ rule_eval_pkt_count++; #ifdef TARGET_BASED /* Load in a new attribute table if we need to... */ AttributeTableReloadCheck(); #endif CheckForReload(); /* Save off the time of each and every packet */ packet_time_update(&pkthdr->ts); #ifdef REG_TEST if ( snort_conf->pkt_skip && pc.total_from_daq <= snort_conf->pkt_skip ) { PREPROC_PROFILE_END_PI(totalPerfStats); return verdict; } #endif #if defined(WIN32) && defined(ENABLE_WIN32_SERVICE) if (ScTerminateService() || ScPauseService()) { PREPROC_PROFILE_END_PI(totalPerfStats); return verdict; // time to go } #endif /* reset the thresholding subsystem checks for this packet */ sfthreshold_reset(); PREPROC_PROFILE_START(eventqPerfStats); SnortEventqReset(); Replace_ResetQueue(); #ifdef ACTIVE_RESPONSE Active_ResetQueue(); #endif PREPROC_PROFILE_END(eventqPerfStats); verdict = ProcessPacket(&s_packet, pkthdr, pkt, NULL); #ifdef ACTIVE_RESPONSE if ( Active_ResponseQueued() ) { Active_SendResponses(&s_packet); } #endif if ( Active_PacketWasDropped() ) { if ( verdict == DAQ_VERDICT_PASS ) { #ifdef HAVE_DAQ_VERDICT_RETRY if ( Active_RetryIsPending() && !(s_packet.packet_flags & PKT_RETRANSMIT) ) verdict = DAQ_VERDICT_RETRY; else verdict = DAQ_VERDICT_BLOCK; #else verdict = DAQ_VERDICT_BLOCK; #endif } } else { Replace_ModifyPacket(&s_packet); if ( s_packet.packet_flags & PKT_MODIFIED ) { // this packet was normalized and/or has replacements Encode_Update(&s_packet); verdict = DAQ_VERDICT_REPLACE; } #ifdef NORMALIZER else if ( s_packet.packet_flags & PKT_RESIZED ) { // we never increase, only trim, but // daq doesn't support resizing wire packet if ( !DAQ_Inject(s_packet.pkth, 0, s_packet.pkt, s_packet.pkth->pktlen) ) { verdict = DAQ_VERDICT_BLOCK; inject = 1; } } #endif else { if ((s_packet.packet_flags & PKT_IGNORE) || (session_api && (session_api->get_ignore_direction(s_packet.ssnptr) == SSN_DIR_BOTH))) { if ( !Active_GetTunnelBypass() ) { verdict = DAQ_VERDICT_WHITELIST; } else { verdict = DAQ_VERDICT_PASS; pc.internal_whitelist++; } } else if ( s_packet.packet_flags & PKT_TRUST ) { if (session_api) session_api->set_ignore_direction(s_packet.ssnptr, SSN_DIR_BOTH); verdict = DAQ_VERDICT_WHITELIST; } else { verdict = DAQ_VERDICT_PASS; } } } #if defined(HAVE_DAQ_LOCALLY_ORIGINATED) && defined(HAVE_DAQ_LOCALLY_DESTINED) /* Don't whitelist packets to/from internal endpoints */ if (verdict == DAQ_VERDICT_WHITELIST && (pkthdr->flags & (DAQ_PKT_FLAG_LOCALLY_DESTINED | DAQ_PKT_FLAG_LOCALLY_ORIGINATED))) { verdict = DAQ_VERDICT_PASS; } #endif #ifdef ENABLE_HA /* This needs to be called here since the session could have been updated anywhere up to this point. :( */ if (session_api) session_api->process_ha(s_packet.ssnptr, pkthdr); #endif /* Collect some "on the wire" stats about packet size, etc */ UpdateWireStats(&sfBase, pkthdr->caplen, Active_PacketWasDropped(), inject); Active_Reset(); Encode_Reset(); if( session_api ) session_api->check_session_timeout(4, pkthdr->ts.tv_sec); #ifdef SNORT_RELOAD ReloadAdjust(false, pkthdr->ts.tv_sec); #endif ControlSocketDoWork(0); #ifdef SIDE_CHANNEL SideChannelDrainRX(0); #endif if ((verdict == DAQ_VERDICT_BLOCK || verdict == DAQ_VERDICT_BLACKLIST) && (verdict_reason == VERDICT_REASON_NO_BLOCK)) verdict_reason = VERDICT_REASON_UNKNOWN; #ifdef HAVE_DAQ_VERDICT_RETRY if (verdict == DAQ_VERDICT_RETRY && verdict_reason == VERDICT_REASON_NO_BLOCK) verdict_reason = VERDICT_REASON_DAQRETRY; #endif if (pkt_trace_enabled) writePktTraceData(verdict, getNapRuntimePolicy(), getIpsRuntimePolicy(), &s_packet); #if defined(HAVE_DAQ_EXT_MODFLOW) && defined(HAVE_DAQ_VERDICT_REASON) if (verdict_reason != VERDICT_REASON_NO_BLOCK) sendReason(&s_packet); #endif #if defined(DAQ_VERSION) && DAQ_VERSION > 9 if (pkthdr->flags & DAQ_PKT_FLAG_DEBUG_ON) { print_pktverdict(&s_packet,verdict); } #endif s_packet.pkth = NULL; // no longer avail on segv PREPROC_PROFILE_END_PI(totalPerfStats); return verdict; } static void PrintPacket(Packet *p) { if (p->iph != NULL) { PrintIPPkt(stdout, GET_IPH_PROTO((p)), p); } #ifndef NO_NON_ETHER_DECODER else if (p->ah != NULL) { PrintArpHeader(stdout, p); } else if (p->eplh != NULL) { PrintEapolPkt(stdout, p); } else if (p->wifih && ScOutputWifiMgmt()) { PrintWifiPkt(stdout, p); } #endif // NO_NON_ETHER_DECODER } DAQ_Verdict ProcessPacket( Packet* p, const DAQ_PktHdr_t* pkthdr, const uint8_t* pkt, void* ft) { DAQ_Verdict verdict = DAQ_VERDICT_PASS; // set runtime policy to default...idx is same for both nap & ips setNapRuntimePolicy(getDefaultPolicy()); setIpsRuntimePolicy(getDefaultPolicy()); /* call the packet decoder */ (*grinder) (p, pkthdr, pkt); assert(p->pkth && p->pkt); if (ft) { p->packet_flags |= (PKT_PSEUDO | PKT_REBUILT_FRAG); p->pseudo_type = PSEUDO_PKT_IP; p->fragtracker = ft; Encode_SetPkt(p); } if ( !p->proto_bits ) p->proto_bits = PROTO_BIT__OTHER; // required until decoders are fixed else if ( !p->family && (p->proto_bits & PROTO_BIT__IP) ) p->proto_bits &= ~PROTO_BIT__IP; /***** Policy specific decoding should into this function *****/ p->configPolicyId = snort_conf->targeted_policies[ getNapRuntimePolicy() ]->configPolicyId; #if defined(HAVE_DAQ_EXT_MODFLOW) && defined(HAVE_DAQ_PKT_TRACE) if (pkt_trace_cli_flag || (pkthdr->flags & DAQ_PKT_FLAG_TRACE_ENABLED)) #else if (pkt_trace_cli_flag) #endif { pkt_trace_enabled = pktTracerDebugCheck(p); if (pkt_trace_enabled) { addPktTraceInfo(p); if (p->packet_flags & PKT_IGNORE) addPktTraceData(VERDICT_REASON_SNORT, snprintf(trace_line, MAX_TRACE_LINE, "Snort: packet ignored\n")); } } else pkt_trace_enabled = false; /* just throw away the packet if we are configured to ignore this port */ if ( !(p->packet_flags & PKT_IGNORE) ) { /* start calling the detection processes */ Preprocess(p); log_func(p); } else if (!pkt_trace_enabled) // ignored packet addPktTraceData(VERDICT_REASON_SNORT, 0); if ( Active_SessionWasDropped() ) { if ( !Active_PacketForceDropped() ) Active_DropAction(p); else Active_ForceDropAction(p); if ( Active_GetTunnelBypass() ) pc.internal_blacklist++; else if ( ScIpsInlineMode() || Active_PacketForceDropped() ) { verdict = DAQ_VERDICT_BLACKLIST; } else verdict = DAQ_VERDICT_IGNORE; } #ifdef CONTROL_SOCKET if (packet_dump_stop) PacketDumpClose(); else if (packet_dump_file && #ifdef HAVE_DAQ_ADDRESS_SPACE_ID #ifdef DAQ_CAPA_VRF (pkthdr->address_space_id_src == packet_dump_address_space_id) && #else pkthdr->address_space_id == packet_dump_address_space_id && #endif #endif (!packet_dump_fcode.bf_insns || sfbpf_filter(packet_dump_fcode.bf_insns, (uint8_t *)pkt, pkthdr->caplen, pkthdr->pktlen))) { pcap_dump((uint8_t*)packet_dump_file, (const struct pcap_pkthdr*)pkthdr, pkt); pcap_dump_flush((pcap_dumper_t*)packet_dump_file); } #endif return verdict; } Packet *NewGrinderPkt(Packet *p, DAQ_PktHdr_t* phdr, uint8_t *pkt) { if( !p ) { IP6Option* ip6_extensions; p = SnortAlloc(sizeof(*p)); ip6_extensions = SnortAlloc(sizeof(IP6Option) * ScMaxIP6Extensions()); if ( !p || !ip6_extensions ) FatalError("Encode_New() => Failed to allocate packet\n"); p->ip6_extensions = ip6_extensions; } if ( phdr && pkt ) { (*grinder)(p, phdr, pkt); } return p; } void DeleteGrinderPkt( Packet *p) { if(!p) return; if(p->ip6_extensions) free(p->ip6_extensions); free(p); } /* * Function: ShowUsage(char *) * * Purpose: Display the program options and exit * * Arguments: argv[0] => name of the program (argv[0]) * * Returns: 0 => success */ static int ShowUsage(char *program_name) { fprintf(stdout, "USAGE: %s [-options] \n", program_name); #if defined(WIN32) && defined(ENABLE_WIN32_SERVICE) fprintf(stdout, " %s %s %s [-options] \n", program_name , SERVICE_CMDLINE_PARAM , SERVICE_INSTALL_CMDLINE_PARAM); fprintf(stdout, " %s %s %s\n", program_name , SERVICE_CMDLINE_PARAM , SERVICE_UNINSTALL_CMDLINE_PARAM); fprintf(stdout, " %s %s %s\n", program_name , SERVICE_CMDLINE_PARAM , SERVICE_SHOW_CMDLINE_PARAM); #endif #ifdef WIN32 # define FPUTS_WIN32(msg) fputs(msg,stdout) # define FPUTS_UNIX(msg) NULL # define FPUTS_BOTH(msg) fputs(msg,stdout) #else # define FPUTS_WIN32(msg) # define FPUTS_UNIX(msg) fputs(msg,stdout) # define FPUTS_BOTH(msg) fputs(msg,stdout) #endif FPUTS_BOTH ("Options:\n"); FPUTS_BOTH (" -A Set alert mode: fast, full, console, test or none " " (alert file alerts only)\n"); FPUTS_UNIX (" \"unsock\" enables UNIX socket logging (experimental).\n"); FPUTS_BOTH (" -b Log packets in tcpdump format (much faster!)\n"); FPUTS_BOTH (" -B Obfuscated IP addresses in alerts and packet dumps using CIDR mask\n"); FPUTS_BOTH (" -c Use Rules File \n"); FPUTS_BOTH (" -C Print out payloads with character data only (no hex)\n"); FPUTS_BOTH (" -d Dump the Application Layer\n"); FPUTS_UNIX (" -D Run Snort in background (daemon) mode\n"); FPUTS_BOTH (" -e Display the second layer header info\n"); FPUTS_WIN32(" -E Log alert messages to NT Eventlog. (Win32 only)\n"); FPUTS_BOTH (" -f Turn off fflush() calls after binary log writes\n"); FPUTS_BOTH (" -F Read BPF filters from file \n"); FPUTS_UNIX (" -g Run snort gid as group (or gid) after initialization\n"); FPUTS_BOTH (" -G <0xid> Log Identifier (to uniquely id events for multiple snorts)\n"); FPUTS_BOTH (" -h Set home network = \n" " (for use with -l or -B, does NOT change $HOME_NET in IDS mode)\n"); FPUTS_BOTH (" -H Make hash tables deterministic.\n"); FPUTS_BOTH (" -i Listen on interface \n"); FPUTS_BOTH (" -I Add Interface name to alert output\n"); FPUTS_BOTH (" -k Checksum mode (all,noip,notcp,noudp,noicmp,none)\n"); FPUTS_BOTH (" -K Logging mode (pcap[default],ascii,none)\n"); FPUTS_BOTH (" -l Log to directory \n"); FPUTS_BOTH (" -L Log to this tcpdump file\n"); FPUTS_UNIX (" -M Log messages to syslog (not alerts)\n"); FPUTS_UNIX (" -m Set umask = \n"); FPUTS_BOTH (" -n Exit after receiving packets\n"); FPUTS_BOTH (" -N Turn off logging (alerts still work)\n"); FPUTS_BOTH (" -O Obfuscate the logged IP addresses\n"); FPUTS_BOTH (" -p Disable promiscuous mode sniffing\n"); printf (" -P Set explicit snaplen of packet (default: %d)\n", DAQ_GetSnapLen()); FPUTS_BOTH (" -q Quiet. Don't show banner and status report\n"); #ifndef WIN32 FPUTS_BOTH (" -Q Enable inline mode operation.\n"); #endif FPUTS_BOTH (" -r Read and process tcpdump file \n"); FPUTS_BOTH (" -R Include 'id' in snort_intf.pid file name\n"); FPUTS_BOTH (" -s Log alert messages to syslog\n"); FPUTS_BOTH (" -S Set rules file variable n equal to value v\n"); FPUTS_UNIX (" -t Chroots process to after initialization\n"); FPUTS_BOTH (" -T Test and report on the current Snort configuration\n"); FPUTS_UNIX (" -u Run snort uid as user (or uid) after initialization\n"); FPUTS_BOTH (" -U Use UTC for timestamps\n"); FPUTS_BOTH (" -v Be verbose\n"); FPUTS_BOTH (" -V Show version number\n"); FPUTS_WIN32(" -W Lists available interfaces. (Win32 only)\n"); #if defined(NON_ETHER_DECODER) && defined(DLT_IEEE802_11) FPUTS_BOTH (" -w Dump 802.11 management and control frames\n"); #endif FPUTS_BOTH (" -X Dump the raw packet data starting at the link layer\n"); FPUTS_BOTH (" -x Exit if Snort configuration problems occur\n"); FPUTS_BOTH (" -y Include year in timestamp in the alert and log files\n"); FPUTS_BOTH (" -Z Set the performonitor preprocessor file path and name\n"); FPUTS_BOTH (" -? Show this information\n"); FPUTS_BOTH (" are standard BPF options, as seen in TCPDump\n"); FPUTS_BOTH ("Longname options and their corresponding single char version\n"); FPUTS_BOTH (" --logid <0xid> Same as -G\n"); FPUTS_BOTH (" --perfmon-file Same as -Z\n"); FPUTS_BOTH (" --pid-path Specify the directory for the Snort PID file\n"); FPUTS_BOTH (" --snaplen Same as -P\n"); FPUTS_BOTH (" --help Same as -?\n"); FPUTS_BOTH (" --version Same as -V\n"); FPUTS_BOTH (" --alert-before-pass Process alert, drop, sdrop, or reject before pass, default is pass before alert, drop,...\n"); FPUTS_BOTH (" --treat-drop-as-alert Converts drop, sdrop, and reject rules into alert rules during startup\n"); FPUTS_BOTH (" --treat-drop-as-ignore Use drop, sdrop, and reject rules to ignore session traffic when not inline.\n"); FPUTS_BOTH (" --process-all-events Process all queued events (drop, alert,...), default stops after 1st action group\n"); FPUTS_BOTH (" --enable-inline-test Enable Inline-Test Mode Operation\n"); FPUTS_BOTH (" --dynamic-engine-lib Load a dynamic detection engine\n"); FPUTS_BOTH (" --dynamic-engine-lib-dir Load all dynamic engines from directory\n"); FPUTS_BOTH (" --dynamic-detection-lib Load a dynamic rules library\n"); FPUTS_BOTH (" --dynamic-detection-lib-dir Load all dynamic rules libraries from directory\n"); FPUTS_BOTH (" --dump-dynamic-rules Creates stub rule files of all loaded rules libraries\n"); FPUTS_BOTH (" --dynamic-preprocessor-lib Load a dynamic preprocessor library\n"); FPUTS_BOTH (" --dynamic-preprocessor-lib-dir Load all dynamic preprocessor libraries from directory\n"); FPUTS_BOTH (" --dynamic-output-lib Load a dynamic output library\n"); FPUTS_BOTH (" --dynamic-output-lib-dir Load all dynamic output libraries from directory\n"); FPUTS_UNIX (" --create-pidfile Create PID file, even when not in Daemon mode\n"); FPUTS_UNIX (" --nolock-pidfile Do not try to lock Snort PID file\n"); FPUTS_UNIX (" --no-interface-pidfile Do not include the interface name in Snort PID file\n"); #ifdef INLINE_FAILOPEN FPUTS_UNIX (" --disable-inline-init-failopen Do not fail open and pass packets while initializing with inline mode.\n"); #endif #ifdef TARGET_BASED FPUTS_UNIX (" --disable-attribute-reload-thread Do not create a thread to reload the attribute table\n"); #endif FPUTS_BOTH (" --pcap-single Same as -r.\n"); FPUTS_BOTH (" --pcap-file file that contains a list of pcaps to read - read mode is implied.\n"); FPUTS_BOTH (" --pcap-list \"\" a space separated list of pcaps to read - read mode is implied.\n"); FPUTS_UNIX (" --pcap-dir a directory to recurse to look for pcaps - read mode is implied.\n"); FPUTS_UNIX (" --pcap-filter filter to apply when getting pcaps from file or directory.\n"); FPUTS_UNIX (" --pcap-no-filter reset to use no filter when getting pcaps from file or directory.\n"); FPUTS_BOTH (" --pcap-loop this option will read the pcaps specified on command line continuously.\n" " for times. A value of 0 will read until Snort is terminated.\n"); FPUTS_BOTH (" --pcap-reset if reading multiple pcaps, reset snort to post-configuration state before reading next pcap.\n"); #if defined(SNORT_RELOAD) && !defined(WIN32) FPUTS_BOTH (" --pcap-reload if reading multiple pcaps, reload snort config between pcaps.\n"); #endif FPUTS_BOTH (" --pcap-show print a line saying what pcap is currently being read.\n"); FPUTS_BOTH (" --exit-check Signal termination after callbacks from DAQ_Acquire(), showing the time it\n" " takes from signaling until DAQ_Stop() is called.\n"); FPUTS_BOTH (" --conf-error-out Same as -x\n"); #ifdef MPLS FPUTS_BOTH (" --enable-mpls-multicast Allow multicast MPLS\n"); FPUTS_BOTH (" --enable-mpls-overlapping-ip Handle overlapping IPs within MPLS clouds\n"); FPUTS_BOTH (" --max-mpls-labelchain-len Specify the max MPLS label chain\n"); FPUTS_BOTH (" --mpls-payload-type Specify the protocol (ipv4, ipv6, ethernet) that is encapsulated by MPLS\n"); #endif FPUTS_BOTH (" --require-rule-sid Require that all snort rules have SID specified.\n"); FPUTS_BOTH (" --daq Select packet acquisition module (default is pcap).\n"); FPUTS_BOTH (" --daq-mode Select the DAQ operating mode.\n"); FPUTS_BOTH (" --daq-var Specify extra DAQ configuration variable.\n"); FPUTS_BOTH (" --daq-dir Tell snort where to find desired DAQ.\n"); FPUTS_BOTH (" --daq-list[=] List packet acquisition modules available in dir. Default is static modules only.\n"); FPUTS_BOTH (" --dirty-pig Don't flush packets and release memory on shutdown.\n"); FPUTS_BOTH (" --cs-dir Directory to use for control socket.\n"); FPUTS_BOTH (" --ha-peer Activate live high-availability state sharing with peer.\n"); FPUTS_BOTH (" --ha-out Write high-availability events to this file.\n"); FPUTS_BOTH (" --ha-in Read high-availability events from this file on startup (warm-start).\n"); FPUTS_BOTH (" --suppress-config-log Suppress configuration information output.\n"); #ifdef DUMP_BUFFER FPUTS_BOTH (" --buffer-dump= Dump buffers for all packets\n"); FPUTS_BOTH (" --buffer-dump-alert= Dump buffers when a rule triggers\n"); #endif #undef FPUTS_WIN32 #undef FPUTS_UNIX #undef FPUTS_BOTH return 0; } static void ParseCmdLineDynamicLibInfo(SnortConfig *sc, int type, char *path) { DynamicLibInfo *dli = NULL; DynamicLibPath *dlp = NULL; if ((sc == NULL) || (path == NULL)) FatalError("%s(%d) NULL arguments.\n", __FILE__, __LINE__); switch (type) { case DYNAMIC_PREPROC_FILE: case DYNAMIC_PREPROC_DIRECTORY: DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Dynamic preprocessor specifier\n");); if (sc->dyn_preprocs == NULL) { sc->dyn_preprocs = (DynamicLibInfo *)SnortAlloc(sizeof(DynamicLibInfo)); sc->dyn_preprocs->type = DYNAMIC_TYPE__PREPROCESSOR; } else if (sc->dyn_preprocs->count >= MAX_DYNAMIC_LIBS) { FatalError("Maximum number of loaded Dynamic Preprocessor Libs " "(%d) exceeded.\n", MAX_DYNAMIC_LIBS); } dli = sc->dyn_preprocs; break; case DYNAMIC_LIBRARY_FILE: case DYNAMIC_LIBRARY_DIRECTORY: DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Dynamic detection specifier\n");); if (sc->dyn_rules == NULL) { sc->dyn_rules = (DynamicLibInfo *)SnortAlloc(sizeof(DynamicLibInfo)); sc->dyn_rules->type = DYNAMIC_TYPE__DETECTION; } else if (sc->dyn_rules->count >= MAX_DYNAMIC_LIBS) { FatalError("Maximum number of loaded Dynamic Detection Libs " "(%d) exceeded.\n", MAX_DYNAMIC_LIBS); } dli = sc->dyn_rules; break; case DYNAMIC_ENGINE_FILE: case DYNAMIC_ENGINE_DIRECTORY: DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Dynamic engine specifier\n");); if (sc->dyn_engines == NULL) { sc->dyn_engines = (DynamicLibInfo *)SnortAlloc(sizeof(DynamicLibInfo)); sc->dyn_engines->type = DYNAMIC_TYPE__ENGINE; } else if (sc->dyn_engines->count >= MAX_DYNAMIC_LIBS) { FatalError("Maximum number of loaded Dynamic Engine Libs " "(%d) exceeded.\n", MAX_DYNAMIC_LIBS); } dli = sc->dyn_engines; break; case DYNAMIC_OUTPUT_FILE: output_load_module(path); return; break; case DYNAMIC_OUTPUT_DIRECTORY: output_load(path); return; break; default: FatalError("%s(%d) Invalid dynamic type: %d\n", __FILE__, __LINE__, type); break; } dlp = (DynamicLibPath *)SnortAlloc(sizeof(DynamicLibPath)); switch (type) { case DYNAMIC_PREPROC_FILE: case DYNAMIC_LIBRARY_FILE: case DYNAMIC_ENGINE_FILE: case DYNAMIC_OUTPUT_FILE: dlp->ptype = PATH_TYPE__FILE; break; case DYNAMIC_PREPROC_DIRECTORY: case DYNAMIC_LIBRARY_DIRECTORY: case DYNAMIC_ENGINE_DIRECTORY: case DYNAMIC_OUTPUT_DIRECTORY: dlp->ptype = PATH_TYPE__DIRECTORY; break; default: FatalError("%s(%d) Invalid dynamic type: %d\n", __FILE__, __LINE__, type); break; } dlp->path = SnortStrdup(path); dli->lib_paths[dli->count] = dlp; dli->count++; } /* * Function: ParseCmdLine(int, char **) * * Parses command line arguments * * Arguments: * int * count of arguments passed to the routine * char ** * 2-D character array, contains list of command line args * * Returns: None * */ static void ParseCmdLine(int argc, char **argv) { int ch; int option_index = -1; char *endptr; /* for SnortStrtol calls */ SnortConfig *sc; int output_logging = 0; int output_alerting = 0; int syslog_configured = 0; #ifndef WIN32 int daemon_configured = 0; #endif int version_flag_parsed = 0; int quiet_flag_parsed = 0; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Parsing command line...\n");); if (snort_cmd_line_conf != NULL) { FatalError("%s(%d) Trying to parse the command line again.\n", __FILE__, __LINE__); } snort_cmd_line_conf = SnortConfNew(); snort_conf = snort_cmd_line_conf; /* Set the global for log messages */ sc = snort_cmd_line_conf; optind = 1; /* Look for a -D and/or -M switch so we can start logging to syslog * with "snort" tag right away */ while ((ch = getopt_long(argc, argv, valid_options, long_options, &option_index)) != -1) { switch (ch) { case 'M': if (syslog_configured) break; /* If daemon or logging to syslog use "snort" as identifier and * start logging there now */ openlog("snort", LOG_PID | LOG_CONS, LOG_DAEMON); sc->logging_flags |= LOGGING_FLAG__SYSLOG; syslog_configured = 1; break; #ifndef WIN32 case 'E': sc->run_flags |= RUN_FLAG__DAEMON_RESTART; /* Fall through */ case 'D': if (daemon_configured) break; /* If daemon or logging to syslog use "snort" as identifier and * start logging there now */ openlog("snort", LOG_PID | LOG_CONS, LOG_DAEMON); ConfigDaemon(sc, optarg); daemon_configured = 1; break; #endif case 'V': version_flag_parsed = 1; break; case 'q': quiet_flag_parsed = 1; break; case '?': /* show help and exit with 1 */ PrintVersion(sc); ShowUsage(argv[0]); exit(1); break; default: break; } } if (version_flag_parsed) { sc->run_mode_flags |= RUN_MODE_FLAG__VERSION; } else if (quiet_flag_parsed) { ConfigQuiet(sc, NULL); internal_log_level = INTERNAL_LOG_LEVEL__ERROR; } /* ** Set this so we know whether to return 1 on invalid input. ** Snort uses '?' for help and getopt uses '?' for telling us there ** was an invalid option, so we can't use that to tell invalid input. ** Instead, we check optopt and it will tell us. */ optopt = 0; optind = 1; /* loop through each command line var and process it */ while ((ch = getopt_long(argc, argv, valid_options, long_options, &option_index)) != -1) { DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Processing cmd line switch: %c\n", ch);); switch (ch) { case DYNAMIC_ENGINE_FILE: /* Load dynamic engine specified */ case DYNAMIC_ENGINE_DIRECTORY: /* Load dynamic engine specified */ case DYNAMIC_PREPROC_FILE: /* Load dynamic preprocessor lib specified */ case DYNAMIC_PREPROC_DIRECTORY: case DYNAMIC_LIBRARY_FILE: /* Load dynamic detection lib specified */ case DYNAMIC_LIBRARY_DIRECTORY: case DYNAMIC_OUTPUT_FILE: /* Load dynamic output lib specified */ case DYNAMIC_OUTPUT_DIRECTORY: ParseCmdLineDynamicLibInfo(sc, ch, optarg); break; case DUMP_DYNAMIC_RULES: ConfigDumpDynamicRulesPath(sc, optarg); break; case ALERT_BEFORE_PASS: ConfigAlertBeforePass(sc, NULL); break; case PROCESS_ALL_EVENTS: ConfigProcessAllEvents(sc, NULL); break; case TREAT_DROP_AS_ALERT: ConfigTreatDropAsAlert(sc, NULL); break; case TREAT_DROP_AS_IGNORE: ConfigTreatDropAsIgnore(sc, NULL); break; case PID_PATH: ConfigPidPath(sc, optarg); break; case CREATE_PID_FILE: ConfigCreatePidFile(sc, NULL); break; case NOLOCK_PID_FILE: sc->run_flags |= RUN_FLAG__NO_LOCK_PID_FILE; break; case NO_IFACE_PID_FILE: sc->run_flags |= RUN_FLAG__NO_IFACE_PID_FILE; break; #ifdef INLINE_FAILOPEN case DISABLE_INLINE_FAILOPEN: ConfigDisableInlineFailopen(sc, NULL); break; #endif case NO_LOGGING_TIMESTAMPS: ConfigNoLoggingTimestamps(sc, NULL); break; #ifdef EXIT_CHECK case ARG_EXIT_CHECK: { char* endPtr; sc->exit_check = SnortStrtoul(optarg, &endPtr, 0); if ((errno == ERANGE) || (*endPtr != '\0')) FatalError("--exit-check value must be non-negative integer\n"); LogMessage("Exit Check: limit = "STDu64" callbacks\n", sc->exit_check); } break; #endif #ifdef TARGET_BASED case DISABLE_ATTRIBUTE_RELOAD: ConfigDisableAttributeReload(sc, NULL); break; #endif case DETECTION_SEARCH_METHOD: if (sc->fast_pattern_config != NULL) FatalError("Can only configure search method once.\n"); sc->fast_pattern_config = FastPatternConfigNew(); if (fpSetDetectSearchMethod(sc->fast_pattern_config, optarg) == -1) FatalError("Invalid search method: %s.\n", optarg); break; case ARG_DAQ_TYPE: ConfigDaqType(sc, optarg); break; case ARG_DAQ_MODE: ConfigDaqMode(sc, optarg); break; case ARG_DAQ_VAR: ConfigDaqVar(sc, optarg); break; case ARG_DAQ_DIR: ConfigDaqDir(sc, optarg); break; case ARG_DAQ_LIST: PrintDaqModules(sc, optarg); exit(0); break; case ARG_DIRTY_PIG: ConfigDirtyPig(sc, optarg); break; case 'A': /* alert mode */ output_alerting = 1; if (strcasecmp(optarg, ALERT_MODE_OPT__NONE) == 0) { sc->no_alert = 1; } else if (strcasecmp(optarg, ALERT_MODE_OPT__PKT_CNT) == 0) { /* print packet count at start of alert */ sc->output_flags |= OUTPUT_FLAG__ALERT_PKT_CNT; } else if (strcasecmp(optarg, ALERT_MODE_OPT__FULL) == 0) { ParseOutput(sc, NULL, "alert_full"); } else if (strcasecmp(optarg, "console:" ALERT_MODE_OPT__FULL) == 0) { ParseOutput(sc, NULL, "alert_full: stdout"); } else if (strcasecmp(optarg, ALERT_MODE_OPT__FAST) == 0) { ParseOutput(sc, NULL, "alert_fast"); } else if ( strcasecmp(optarg, "console:" ALERT_MODE_OPT__FAST) == 0 || strcasecmp(optarg, ALERT_MODE_OPT__CONSOLE) == 0 ) { ParseOutput(sc, NULL, "alert_fast: stdout"); } else if ((strcasecmp(optarg, ALERT_MODE_OPT__CMG) == 0) || (strcasecmp(optarg, ALERT_MODE_OPT__JH) == 0) || (strcasecmp(optarg, ALERT_MODE_OPT__DJR) == 0)) { ParseOutput(sc, NULL, "alert_fast: stdout packet"); sc->no_log = 1; /* turn on layer2 headers */ sc->output_flags |= OUTPUT_FLAG__SHOW_DATA_LINK; /* turn on data dump */ sc->output_flags |= OUTPUT_FLAG__APP_DATA; } else if (strcasecmp(optarg, ALERT_MODE_OPT__AJK) == 0) { ParseOutput(sc, NULL, "unified2"); } else if (strcasecmp(optarg, ALERT_MODE_OPT__UNIX_SOCK) == 0) { ParseOutput(sc, NULL, "alert_unixsock"); } else if (strcasecmp(optarg, ALERT_MODE_OPT__TEST) == 0) { ParseOutput(sc, NULL, "alert_test"); sc->no_log = 1; } else if (strcasecmp(optarg, "console:" ALERT_MODE_OPT__TEST) == 0) { ParseOutput(sc, NULL, "alert_test: stdout"); sc->no_log = 1; } else { FatalError("Unknown command line alert option: %s\n", optarg); } break; case 'b': /* log packets in binary format for post-processing */ ParseOutput(sc, NULL, "log_tcpdump"); output_logging = 1; break; case 'B': /* obfuscate with a substitution mask */ ConfigObfuscationMask(sc, optarg); break; case 'c': /* use configuration file x */ sc->run_mode_flags |= RUN_MODE_FLAG__IDS; snort_conf_file = SnortStrdup(optarg); break; case 'C': /* dump the application layer as text only */ ConfigDumpCharsOnly(sc, NULL); break; case 'd': /* dump the application layer data */ ConfigDumpPayload(sc, NULL); break; #ifndef WIN32 case 'E': /* Restarting from daemon mode */ case 'D': /* daemon mode */ /* These are parsed at the beginning so as to start logging * to syslog right away */ break; #endif case 'e': /* show second level header info */ ConfigDecodeDataLink(sc, NULL); break; #ifdef WIN32 case 'E': /* log alerts to Event Log */ ParseOutput(sc, NULL, "alert_syslog"); sc->logging_flags &= ~LOGGING_FLAG__SYSLOG_REMOTE; output_alerting = 1; break; #endif case 'f': sc->output_flags |= OUTPUT_FLAG__LINE_BUFFER; break; case 'F': /* read BPF filter in from a file */ ConfigBpfFile(sc, optarg); break; #ifndef WIN32 case 'g': /* setgid */ ConfigSetGid(sc, optarg); break; #endif case 'G': /* snort loG identifier */ sc->event_log_id = SnortStrtoul(optarg, &endptr, 0); if ((errno == ERANGE) || (*endptr != '\0') || (sc->event_log_id > UINT16_MAX)) { FatalError("Snort log identifier invalid: %s. It must " "be between 0 and %u.\n", optarg, UINT16_MAX); } /* Forms upper 2 bytes. Lower two bytes are the event id */ sc->event_log_id <<= 16; break; case 'h': /* set home network to x, this will help determine what to set * logging diectories to */ ConfigReferenceNet(sc, optarg); break; case 'H': sc->run_flags |= RUN_FLAG__STATIC_HASH; break; case 'i': ConfigInterface(sc, optarg); break; case 'I': /* add interface name to alert string */ ConfigAlertWithInterfaceName(sc, NULL); break; case 'k': /* set checksum mode */ ConfigChecksumMode(sc, optarg); break; case 'K': /* log mode */ if (strcasecmp(optarg, LOG_MODE_OPT__NONE) == 0) { sc->no_log = 1; } else if (strcasecmp(optarg, LOG_MODE_OPT__PCAP) == 0) { ParseOutput(sc, NULL, "log_tcpdump"); } else if (strcasecmp(optarg, LOG_MODE_OPT__ASCII) == 0) { ParseOutput(sc, NULL, "log_ascii"); } else { FatalError("Unknown command line log option: %s\n", optarg); } output_logging = 1; break; case 'l': /* use log dir */ ConfigLogDir(sc, optarg); break; case 'L': /* set BinLogFile name */ /* implies tcpdump format logging * 256 is kind of arbitrary but should be more than enough */ if (strlen(optarg) < 256) { ParseOutput(sc, NULL, "log_tcpdump"); sc->pcap_log_file = SnortStrdup(optarg); } else { FatalError("log_tcpdump file name \"%s\" has to be less " "than or equal to 256 characters.\n", optarg); } output_logging = 1; break; case 'M': /* This is parsed at the beginning so as to start logging * to syslog right away */ break; #ifndef WIN32 case 'm': /* set the umask for the output files */ ConfigUmask(sc, optarg); break; #endif case 'n': /* grab x packets and exit */ ConfigPacketCount(sc, optarg); break; case 'N': /* no logging mode */ ConfigNoLog(sc, NULL); break; case 'O': /* obfuscate the logged IP addresses for privacy */ ConfigObfuscate(sc, NULL); break; case 'p': /* disable explicit promiscuous mode */ ConfigNoPromiscuous(sc, NULL); break; case 'P': /* explicitly define snaplength of packets */ ConfigPacketSnaplen(sc, optarg); break; case 'q': /* no stdout output mode */ /* This is parsed at the beginning so as to start logging * in quiet mode right away */ break; #ifndef WIN32 case 'Q': LogMessage("Enabling inline operation\n"); sc->run_flags |= RUN_FLAG__INLINE; break; #endif case ENABLE_INLINE_TEST: LogMessage("Enable Inline Test Mode\n"); sc->run_flags |= RUN_FLAG__INLINE_TEST; break; case 'r': /* read packets from a TCPdump file instead of the net */ case PCAP_SINGLE: PQ_Single(optarg); sc->run_flags |= RUN_FLAG__READ; break; case 'R': /* augment pid file name suffix */ if ((strlen(optarg) >= MAX_PIDFILE_SUFFIX) || (strlen(optarg) <= 0) || (strstr(optarg, "..") != NULL) || (strstr(optarg, "/") != NULL)) { FatalError("Invalid pidfile suffix: %s. Suffix must " "less than %u characters and not have " "\"..\" or \"/\" in the name.\n", optarg, MAX_PIDFILE_SUFFIX); } SnortStrncpy(sc->pidfile_suffix, optarg, sizeof(sc->pidfile_suffix)); break; case 's': /* log alerts to syslog */ #ifndef WIN32 ParseOutput(sc, NULL, "alert_syslog"); #else sc->logging_flags |= LOGGING_FLAG__SYSLOG_REMOTE; #endif output_alerting = 1; break; case 'S': /* set a rules file variable */ { char *equal_ptr = strchr(optarg, '='); VarNode *node; if (equal_ptr == NULL) { FatalError("Format for command line variable definitions " "is:\n -S var=value\n"); } /* Save these and parse when snort conf is parsed so * they can be added to the snort conf configuration */ node = (VarNode *)SnortAlloc(sizeof(VarNode)); node->name = SnortStrndup(optarg, equal_ptr - optarg); /* Make sure it's not already in the list */ if (cmd_line_var_list != NULL) { VarNode *tmp = cmd_line_var_list; while (tmp != NULL) { if (strcasecmp(tmp->name, node->name) == 0) { FreeVarList(cmd_line_var_list); FatalError("Duplicate variable name: %s.\n", tmp->name); } tmp = tmp->next; } } node->value = SnortStrdup(equal_ptr + 1); node->line = SnortStrdup(optarg); node->next = cmd_line_var_list; cmd_line_var_list = node; /* Put line in a parser parsable form - we know the * equals is already there */ equal_ptr = strchr(node->line, '='); *equal_ptr = ' '; } break; #ifndef WIN32 case 't': /* chroot to the user specified directory */ ConfigChrootDir(sc, optarg); break; #endif case 'T': /* test mode, verify that the rules load properly */ sc->run_mode_flags |= RUN_MODE_FLAG__TEST; break; #ifndef WIN32 case 'u': /* setuid */ ConfigSetUid(sc, optarg); break; #endif case 'U': /* use UTC */ ConfigUtc(sc, NULL); break; case 'v': /* be verbose */ ConfigVerbose(sc, NULL); break; case 'V': /* prog ver already gets printed out, so we just exit */ break; #ifdef WIN32 case 'W': PrintVersion(sc); PrintAllInterfaces(); exit(0); /* XXX Should maybe use CleanExit here? */ break; #endif #if !defined(NO_NON_ETHER_DECODER) && defined(DLT_IEEE802_11) case 'w': /* show 802.11 all frames info */ sc->output_flags |= OUTPUT_FLAG__SHOW_WIFI_MGMT; break; #endif case 'X': /* display verbose packet bytecode dumps */ ConfigDumpPayloadVerbose(sc, NULL); break; case 'x': sc->run_flags |= RUN_FLAG__CONF_ERROR_OUT; break; case 'y': /* Add year to timestamp in alert and log files */ ConfigShowYear(sc, NULL); break; case 'Z': /* Set preprocessor perfmon file path/filename */ ConfigPerfFile(sc, optarg); break; case PCAP_FILE_LIST: case PCAP_LIST: #ifndef WIN32 case PCAP_DIR: #endif PQ_Multi((char)ch, optarg); sc->run_flags |= RUN_FLAG__READ; break; case PCAP_LOOP: { long int loop_count = SnortStrtol(optarg, &endptr, 0); if ((errno == ERANGE) || (*endptr != '\0') || (loop_count < 0) || (loop_count > 2147483647)) { FatalError("Valid values for --pcap-loop are between 0 and 2147483647\n"); } if (loop_count == 0) pcap_loop_count = -1; else pcap_loop_count = loop_count; } break; case PCAP_RESET: sc->run_flags |= RUN_FLAG__PCAP_RESET; break; #if defined(SNORT_RELOAD) && !defined(WIN32) case PCAP_RELOAD: sc->run_flags |= RUN_FLAG__PCAP_RELOAD; break; #endif #ifndef WIN32 case PCAP_FILTER: PQ_SetFilter(optarg); break; case PCAP_NO_FILTER: PQ_SetFilter(NULL); break; #endif case PCAP_SHOW: sc->run_flags |= RUN_FLAG__PCAP_SHOW; break; #ifdef MPLS case ENABLE_MPLS_MULTICAST: ConfigEnableMplsMulticast(sc, NULL); break; case ENABLE_OVERLAPPING_IP: ConfigEnableMplsOverlappingIp(sc, NULL); break; case MAX_MPLS_LABELCHAIN_LEN: ConfigMaxMplsLabelChain(sc, optarg); break; case MPLS_PAYLOAD_TYPE: ConfigMplsPayloadType(sc, optarg); break; #endif case REQUIRE_RULE_SID: sc->run_flags |= RUN_FLAG__REQUIRE_RULE_SID; break; case ARG_CS_DIR: if ( optarg != NULL ) sc->cs_dir = SnortStrdup(optarg); break; #ifdef REG_TEST case ARG_HA_PEER: sc->ha_peer = true; break; case ARG_HA_OUT: sc->ha_out = SnortStrdup(optarg); break; case ARG_HA_IN: sc->ha_in = SnortStrdup(optarg); break; case ARG_HA_PDTS_IN: sc->ha_pdts_in = SnortStrdup(optarg); break; #endif case SUPPRESS_CONFIG_LOG: sc->suppress_config_log = 1; break; #ifdef DUMP_BUFFER case BUFFER_DUMP: dump_alert_only = false; dump_enabled = true; ConfigBufferDump(sc, optarg); ParseOutput(sc, NULL, "log_buffer_dump"); break; case BUFFER_DUMP_ALERT: dump_alert_only = true; dump_enabled = true; ConfigBufferDump(sc, optarg); ParseOutput(sc, NULL, "log_buffer_dump"); break; #endif case '?': /* show help and exit with 1 */ PrintVersion(sc); ShowUsage(argv[0]); /* XXX Should do a clean exit */ exit(1); break; default: FatalError("Invalid option: %c.\n", ch); break; } } sc->bpf_filter = copy_argv(&argv[optind]); if ((sc->run_mode_flags & RUN_MODE_FLAG__TEST) && (sc->run_flags & RUN_FLAG__DAEMON)) { FatalError("Cannot use test mode and daemon mode together.\n" "To verify configuration, run first in test " "mode and then restart in daemon mode.\n"); } if ((sc->run_flags & RUN_FLAG__INLINE) && (sc->run_flags & RUN_FLAG__INLINE_TEST)) { FatalError("Cannot use inline adapter mode and inline test " "mode together. \n"); } // TBD no reason why command line args only can't be checked // marginally useful, perhaps, but why do we go out of our way // to make things hard on the user? if ((sc->run_mode_flags & RUN_MODE_FLAG__TEST) && (snort_conf_file == NULL)) { FatalError("Test mode must be run with a snort configuration " "file. Use the '-c' option on the command line to " "specify a configuration file.\n"); } if (pcap_loop_count && !(sc->run_flags & RUN_FLAG__READ)) { FatalError("--pcap-loop can only be used in combination with pcaps " "on the command line.\n"); } #if defined(SNORT_RELOAD) && !defined(WIN32) if ((sc->run_flags & RUN_FLAG__PCAP_RELOAD) && !(sc->run_flags & RUN_FLAG__READ)) { FatalError("--pcap-reload can only be used in combination with pcaps " "on the command line.\n"); } #endif /* Set the run mode based on what we've got from command line */ /* Version overrides all */ if (sc->run_mode_flags & RUN_MODE_FLAG__VERSION) { sc->run_mode = RUN_MODE__VERSION; } /* Next dumping so rule stubs */ else if (sc->run_mode_flags & RUN_MODE_FLAG__RULE_DUMP) { sc->run_mode = RUN_MODE__RULE_DUMP; } /* Next if we want to test a snort conf */ else if (sc->run_mode_flags & RUN_MODE_FLAG__TEST) { sc->run_mode = RUN_MODE__TEST; } /* Now if there is a snort conf. If a snort conf wasn't given on the * command line, we'll look in a default place if the next ones * don't match */ else if ((sc->run_mode_flags & RUN_MODE_FLAG__IDS) && (snort_conf_file != NULL)) { sc->run_mode = RUN_MODE__IDS; } /* If logging but not alerting or log directory is set */ else if ((output_logging && !output_alerting) || (sc->log_dir != NULL)) { sc->no_alert = 1; sc->run_mode = RUN_MODE__PACKET_LOG; } /* If none of the above and not logging or alerting and verbose */ else if ((!output_logging && !output_alerting) && (sc->logging_flags & LOGGING_FLAG__VERBOSE)) { sc->no_alert = 1; sc->no_log = 1; sc->run_mode = RUN_MODE__PACKET_DUMP; } #if 1 if (!sc->run_mode) { sc->no_alert = 1; sc->no_log = 1; sc->run_mode = RUN_MODE__PACKET_DUMP; } #else if (!sc->run_mode) sc->run_mode = RUN_MODE__IDS; /* If mode mandates a conf and we don't have one, check for default. */ if (((sc->run_mode == RUN_MODE__IDS) || (sc->run_mode == RUN_MODE__TEST)) && (snort_conf_file == NULL)) { snort_conf_file = ConfigFileSearch(); if (snort_conf_file == NULL) { DisplayBanner(); ShowUsage(argv[0]); FatalError("\n\nUh, you need to tell me to do something..."); } } #endif if ((sc->run_mode == RUN_MODE__PACKET_LOG) && (sc->output_configs == NULL)) { ParseOutput(sc, NULL, "log_tcpdump"); } switch ( snort_conf->run_mode ) { case RUN_MODE__IDS: if (ScLogVerbose()) log_func = PrintPacket; break; case RUN_MODE__PACKET_LOG: log_func = LogPacket; break; case RUN_MODE__PACKET_DUMP: log_func = PrintPacket; break; default: break; } SetSnortConfDir(); } /* * Function: SetPktProcessor() * * Purpose: Set root decoder based on datalink */ // TBD add GetDecoder(dlt) to decode module and hide all // protocol decoder functions. static int SetPktProcessor(void) { const char* slink = NULL; const char* extra = NULL; int dlt = DAQ_GetBaseProtocol(); switch ( dlt ) { case DLT_EN10MB: slink = "Ethernet"; grinder = DecodeEthPkt; break; #ifdef DLT_LOOP case DLT_LOOP: #endif case DLT_NULL: /* loopback and stuff.. you wouldn't perform intrusion detection * on it, but it's ok for testing. */ slink = "LoopBack"; extra = "Data link layer header parsing for this network type " "isn't implemented yet"; grinder = DecodeNullPkt; break; case DLT_RAW: case DLT_IPV4: slink = "Raw IP4"; extra = "There's no second layer header available for this datalink"; grinder = DecodeRawPkt; break; case DLT_IPV6: slink = "Raw IP6"; extra = "There's no second layer header available for this datalink"; grinder = DecodeRawPkt6; break; #ifdef DLT_I4L_IP case DLT_I4L_IP: slink = "I4L-ip"; grinder = DecodeEthPkt; break; #endif #ifndef NO_NON_ETHER_DECODER #ifdef DLT_I4L_CISCOHDLC case DLT_I4L_CISCOHDLC: slink = "I4L-cisco-h"; grinder = DecodeI4LCiscoIPPkt; break; #endif case DLT_PPP: slink = "PPP"; extra = "Second layer header parsing for this datalink " "isn't implemented yet"; grinder = DecodePppPkt; break; #ifdef DLT_I4L_RAWIP case DLT_I4L_RAWIP: // you need the I4L modified version of libpcap to get this stuff // working slink = "I4L-rawip"; grinder = DecodeI4LRawIPPkt; break; #endif #ifdef DLT_IEEE802_11 case DLT_IEEE802_11: slink = "IEEE 802.11"; grinder = DecodeIEEE80211Pkt; break; #endif #ifdef DLT_ENC case DLT_ENC: slink = "Encapsulated data"; grinder = DecodeEncPkt; break; #else case 13: #endif /* DLT_ENC */ case DLT_IEEE802: slink = "Token Ring"; grinder = DecodeTRPkt; break; case DLT_FDDI: slink = "FDDI"; grinder = DecodeFDDIPkt; break; #ifdef DLT_CHDLC case DLT_CHDLC: slink = "Cisco HDLC"; grinder = DecodeChdlcPkt; break; #endif case DLT_SLIP: slink = "SLIP"; extra = "Second layer header parsing for this datalink " "isn't implemented yet\n"; grinder = DecodeSlipPkt; break; #ifdef DLT_PPP_SERIAL case DLT_PPP_SERIAL: /* PPP with full HDLC header*/ slink = "PPP Serial"; extra = "Second layer header parsing for this datalink " " isn't implemented yet"; grinder = DecodePppSerialPkt; break; #endif #ifdef DLT_LINUX_SLL case DLT_LINUX_SLL: slink = "Linux SLL"; grinder = DecodeLinuxSLLPkt; break; #endif #ifdef DLT_PFLOG case DLT_PFLOG: slink = "OpenBSD PF log"; grinder = DecodePflog; break; #endif #ifdef DLT_OLDPFLOG case DLT_OLDPFLOG: slink = "Old OpenBSD PF log"; grinder = DecodeOldPflog; break; #endif #endif // NO_NON_ETHER_DECODER default: /* oops, don't know how to handle this one */ FatalError("Cannot decode data link type %d\n", dlt); break; } if ( !ScReadMode() || ScPcapShow() ) { LogMessage("Decoding %s\n", slink); } if (extra && ScOutputDataLink()) { LogMessage("%s\n", extra); snort_conf->output_flags &= ~OUTPUT_FLAG__SHOW_DATA_LINK; } #ifdef ACTIVE_RESPONSE Encode_Init(); #endif return 0; } /* * Handle idle time checks in snort packet processing loop */ static void SnortIdle(void) { /* Rollover of performance log */ if (IsSetRotatePerfFileFlag()) { sfRotateBaseStatsFile(perfmon_config); sfRotateFlowStatsFile(perfmon_config); ClearRotatePerfFileFlag(); } #ifdef OPENBSD #ifdef SNORT_RELOAD else if (reload_signal != reload_total) nanosleep(&packet_sleep, NULL); #endif #endif #ifndef REG_TEST if( session_api ) session_api->check_session_timeout(FLOW_COUNT, time(NULL)); #ifdef SNORT_RELOAD ReloadAdjust(true, time(NULL)); #endif #endif ControlSocketDoWork(1); #ifdef SIDE_CHANNEL SideChannelDrainRX(0); #endif IdleProcessingExecute(); } void PacketLoop (void) { int error = 0; int pkts_to_read = (int)snort_conf->pkt_cnt; time_t curr_time, last_time; curr_time = time(NULL); last_time = curr_time; TimeStart(); while ( !exit_logged ) { error = DAQ_Acquire(pkts_to_read, PacketCallback, NULL); #ifdef CONTROL_SOCKET if (packet_dump_stop) PacketDumpClose(); #endif #ifdef SIDE_CHANNEL /* If we didn't manage to lock the process lock in a DAQ acquire callback, lock it now. */ if (ScSideChannelEnabled() && !snort_process_lock_held) { pthread_mutex_lock(&snort_process_lock); snort_process_lock_held = true; } #endif if ( error ) { //Update the time tracker curr_time = packet_time(); last_time = curr_time; if ( !ScReadMode() || !PQ_Next() ) { /* If not read-mode or no next pcap, we're done */ break; } #ifdef REG_TEST else regTestCheckIPIncrement(); #endif } /* Check for any pending signals when no packets are read*/ else { // TBD SnortIdle() only checks for perf file rotation // and that can only be done after calling SignalCheck() // so either move SnortIdle() to SignalCheck() or directly // set the flag in the signal handler (and then clear it // in SnortIdle()). if ( !ScReadMode() ) { time_t new_time = time(NULL); curr_time += new_time - last_time; last_time = new_time; // Check if its time to dump perf data sfPerformanceStatsOOB(perfmon_config, curr_time); } // check for signals if ( SignalCheck() ) { #ifndef SNORT_RELOAD // Got SIGNAL_SNORT_RELOAD Restart(); #endif } CheckForReload(); } if ( pkts_to_read > 0 ) { if ( snort_conf->pkt_cnt <= pc.total_from_daq ) break; else pkts_to_read = (int)(snort_conf->pkt_cnt - pc.total_from_daq); } // idle time processing..quick things to check or do ... // TBD fix this per above ... and if it stays here, should // prolly change the name if acquire breaks due to a signal // (since in that case we aren't idle here) SnortIdle(); #ifdef SIDE_CHANNEL /* Unlock the Snort process lock once we've hit the DAQ acquire timeout. */ if (snort_process_lock_held) { snort_process_lock_held = false; pthread_mutex_unlock(&snort_process_lock); } #endif } #ifdef CONTROL_SOCKET PacketDumpClose(); #endif #ifdef SIDE_CHANNEL /* Error conditions can lead to exiting the packet loop prior to unlocking the process lock. */ if (snort_process_lock_held) { snort_process_lock_held = false; pthread_mutex_unlock(&snort_process_lock); } #endif if ( !exit_logged && error ) { if ( error == DAQ_READFILE_EOF ) error = 0; else if ( error > 0 ) { DAQ_Abort(); exit(1); } CleanExit(error); } done_processing = 1; } /* Resets Snort to a post-configuration state */ static void SnortReset(void) { PreprocSignalFuncNode *idxPreprocReset; PreprocSignalFuncNode *idxPreprocResetStats; /* reset preprocessors */ idxPreprocReset = preproc_reset_funcs; while (idxPreprocReset != NULL) { idxPreprocReset->func(-1, idxPreprocReset->arg); idxPreprocReset = idxPreprocReset->next; } SnortEventqReset(); Replace_ResetQueue(); #ifdef ACTIVE_RESPONSE Active_ResetQueue(); #endif sfthreshold_reset_active(); RateFilter_ResetActive(); TagCacheReset(); #ifdef PERF_PROFILING ShowPreprocProfiles(); ShowRuleProfiles(); #endif DropStats(0); /* zero out packet count */ memset(&pc, 0, sizeof(pc)); #ifdef PERF_PROFILING ResetRuleProfiling(); ResetPreprocProfiling(); #endif /* reset preprocessor stats */ idxPreprocResetStats = preproc_reset_stats_funcs; while (idxPreprocResetStats != NULL) { idxPreprocResetStats->func(-1, idxPreprocResetStats->arg); idxPreprocResetStats = idxPreprocResetStats->next; } } #if 0 /* locate one of the possible default config files */ /* allocates memory to hold filename */ static char *ConfigFileSearch(void) { struct stat st; int i; char *conf_files[]={"/etc/snort.conf", "./snort.conf", NULL}; char *fname = NULL; char *rval = NULL; i = 0; /* search the default set of config files */ while(conf_files[i]) { fname = conf_files[i]; if(stat(fname, &st) != -1) { rval = SnortStrdup(fname); break; } i++; } /* search for .snortrc in the HOMEDIR */ if(!rval) { char *home_dir = NULL; if((home_dir = getenv("HOME")) != NULL) { char *snortrc = "/.snortrc"; int path_len; path_len = strlen(home_dir) + strlen(snortrc) + 1; /* create the full path */ fname = (char *)SnortAlloc(path_len); SnortSnprintf(fname, path_len, "%s%s", home_dir, snortrc); if(stat(fname, &st) != -1) rval = fname; else free(fname); } } return rval; } #endif /* Signal Handlers ************************************************************/ static void SigExitHandler(int signal) { if (exit_signal != 0) return; exit_signal = signal; } static void SigDumpStatsHandler(int signal) { dump_stats_signal = true; } static void SigRotateStatsHandler(int signal) { rotate_stats_signal = true; } static void SigReloadHandler(int signal) { #if defined(SNORT_RELOAD) && !defined(WIN32) reload_signal++; #else reload_signal = true; #endif } #ifdef CONTROL_SOCKET static void SigPipeHandler(int signal) { } #endif #ifdef TARGET_BASED void SigNoAttributeTableHandler(int signal) { no_attr_table_signal = true; } #endif static void SigOopsHandler(int signal) { if ( s_packet.pkth ) { s_pkth = *s_packet.pkth; if ( s_packet.pkt ) memcpy(s_data, s_packet.pkt, 0xFFFF & s_packet.pkth->caplen); } SnortAddSignal(signal, SIG_DFL, 0); raise(signal); } static void PrintStatistics (void) { if ( ScTestMode() || ScVersionMode() || ScRuleDumpMode() ) return; fpShowEventStats(snort_conf); #ifdef PERF_PROFILING { int saved_internal_log_level = internal_log_level; internal_log_level = INTERNAL_LOG_LEVEL__MESSAGE; ShowPreprocProfiles(); ShowRuleProfiles(); internal_log_level = saved_internal_log_level; } #endif DropStats(2); print_thresholding(snort_conf->threshold_config, 1); } /**************************************************************************** * * Function: CleanExit() * * Purpose: Clean up misc file handles and such and exit * * Arguments: exit value; * * Returns: void function * ****************************************************************************/ void CleanExit(int exit_val) { SnortConfig tmp; #ifdef TARGET_BASED #ifdef DEBUG #if 0 SFLAT_dump(); #endif #endif #endif /* Have to trick LogMessage to log correctly after snort_conf * is freed */ memset(&tmp, 0, sizeof(tmp)); if (snort_conf != NULL) { tmp.internal_log_level = snort_conf->internal_log_level; tmp.run_mode = snort_conf->run_mode; tmp.run_flags |= (snort_conf->run_flags & RUN_FLAG__DAEMON); tmp.logging_flags |= (snort_conf->logging_flags & LOGGING_FLAG__SYSLOG); } SnortCleanup(exit_val); snort_conf = &tmp; if (!ScVersionMode()) { LogMessage("Snort exiting\n"); } #ifndef WIN32 closelog(); #endif if ( !done_processing ) exit(exit_val); } static void SnortCleanup(int exit_val) { PreprocSignalFuncNode *idxPreproc = NULL; PluginSignalFuncNode *idxPlugin = NULL; /* This function can be called more than once. For example, * once from the SIGINT signal handler, and once recursively * as a result of calling pcap_close() below. We only need * to perform the cleanup once. */ if (pthread_mutex_trylock(&cleanup_mutex) == 0) { /* * We have the lock now, make sure no one else called this * function before this thread did. */ if (already_exiting != 0 ) { pthread_mutex_unlock(&cleanup_mutex); return; } } else { /* * Someother thread is cleaning up. Return. */ return; } already_exiting = 1; snort_exiting = 1; snort_initializing = false; /* just in case we cut out early */ Active_Suspend(); // rules that fire now can't actually block #if defined(INLINE_FAILOPEN) && !defined(WIN32) if (inline_failopen_thread_running) pthread_kill(inline_failopen_thread_id, SIGKILL); #endif if ( DAQ_WasStarted() ) { #ifdef EXIT_CHECK if (snort_conf->exit_check) ExitCheckEnd(); #endif DAQ_Stop(); } ControlSocketCleanUp(); #ifdef SIDE_CHANNEL SideChannelStopTXThread(); SideChannelCleanUp(); #endif IdleProcessingCleanUp(); if ( snort_conf->dirty_pig ) { DAQ_Delete(); DAQ_Term(); ScRestoreInternalLogLevel(); PrintStatistics(); pthread_mutex_unlock(&cleanup_mutex); return; } #if defined(SNORT_RELOAD) && !defined(WIN32) /* Setting snort_exiting will cause the thread to break out * of it's loop and exit */ if (snort_reload_thread_created) pthread_join(snort_reload_thread_id, NULL); #endif #if defined(TARGET_BASED) && !defined(WIN32) if (attribute_reload_thread_running) { /* Set the flag to stop the attribute reload thread and * send VTALRM signal to pull it out of the idle sleep. * Thread exits normally on next iteration through its * loop. * * If its doing other processing, that continues post * interrupt and thread exits normally. */ attribute_reload_thread_stop = 1; pthread_kill(attribute_reload_thread_id, SIGVTALRM); while (attribute_reload_thread_running) nanosleep(&thread_sleep, NULL); pthread_join(attribute_reload_thread_id, NULL); } #endif /* Do some post processing on any incomplete Preprocessor Data */ idxPreproc = preproc_shutdown_funcs; while (idxPreproc) { idxPreproc->func(SIGQUIT, idxPreproc->arg); idxPreproc = idxPreproc->next; } /* Do some post processing on any incomplete Plugin Data */ idxPlugin = plugin_shutdown_funcs; while(idxPlugin) { idxPlugin->func(SIGQUIT, idxPlugin->arg); idxPlugin = idxPlugin->next; } if (!ScTestMode() && !ScVersionMode() && !ScRuleDumpMode() ) { if ( !exit_val ) TimeStop(); } /* Exit preprocessors */ idxPreproc = preproc_clean_exit_funcs; while(idxPreproc) { idxPreproc->func(SIGQUIT, idxPreproc->arg); idxPreproc = idxPreproc->next; } /* Do some post processing on any incomplete Plugin Data */ idxPlugin = plugin_clean_exit_funcs; while(idxPlugin) { idxPlugin->func(SIGQUIT, idxPlugin->arg); idxPlugin = idxPlugin->next; } if (decoderActionQ != NULL) { sfActionQueueDestroy (decoderActionQ); mempool_destroy (&decoderAlertMemPool); decoderActionQ = NULL; memset(&decoderAlertMemPool, 0, sizeof(decoderAlertMemPool)); } MemoryStatsFree(); DAQ_Delete(); DAQ_Term(); ScRestoreInternalLogLevel(); // Do we need this? PrintStatistics(); #ifdef ACTIVE_RESPONSE Active_Term(); Encode_Term(); #endif CleanupProtoNames(); #ifdef TARGET_BASED SFAT_Cleanup(); FreeProtoocolReferenceTable(); #endif PQ_CleanUp(); ClosePidFile(); /* remove pid file */ if (SnortStrnlen(snort_conf->pid_filename, sizeof(snort_conf->pid_filename)) > 0) { int ret; ret = unlink(snort_conf->pid_filename); if (ret != 0) { ErrorMessage("Could not remove pid file %s: %s\n", snort_conf->pid_filename, strerror(errno)); } } #ifdef INTEL_SOFT_CPM //IntelPmPrintBufferStats(); #endif /* free allocated memory */ if (snort_conf == snort_cmd_line_conf) { SnortConfFree(snort_cmd_line_conf); snort_cmd_line_conf = NULL; snort_conf = NULL; } else { SnortConfFree(snort_cmd_line_conf); snort_cmd_line_conf = NULL; SnortConfFree(snort_conf); snort_conf = NULL; } #ifdef SNORT_RELOAD if (snort_conf_new != NULL) { /* If main thread is exiting, it won't swap in the new configuration, * so free it here, really just to quiet valgrind. Note this needs to * be done here since some preprocessors, will potentially need access * to the data here since stream5 flushes out its cache and potentially * sends reassembled packets back through Preprocess */ SnortConfFree(snort_conf_new); snort_conf_new = NULL; } #endif EventTrace_Term(); detection_filter_cleanup(); sfthreshold_free(); RateFilter_Cleanup(); asn1_free_mem(); FreeOutputConfigFuncs(); FreePreprocConfigFuncs(); FreeRuleOptConfigFuncs(rule_opt_config_funcs); rule_opt_config_funcs = NULL; FreeRuleOptOverrideInitFuncs(rule_opt_override_init_funcs); rule_opt_override_init_funcs = NULL; FreeRuleOptByteOrderFuncs(rule_opt_byte_order_funcs); rule_opt_byte_order_funcs = NULL; FreeRuleOptParseCleanupList(rule_opt_parse_cleanup_list); rule_opt_parse_cleanup_list = NULL; FreeOutputList(AlertList); AlertList = NULL; FreeOutputList(LogList); LogList = NULL; /* Global lists */ FreePreprocStatsFuncs(preproc_stats_funcs); preproc_stats_funcs = NULL; FreePreprocSigFuncs(preproc_shutdown_funcs); preproc_shutdown_funcs = NULL; FreePreprocSigFuncs(preproc_clean_exit_funcs); preproc_clean_exit_funcs = NULL; FreePreprocSigFuncs(preproc_reset_funcs); preproc_reset_funcs = NULL; FreePreprocSigFuncs(preproc_reset_stats_funcs); preproc_reset_stats_funcs = NULL; FreePluginSigFuncs(plugin_shutdown_funcs); plugin_shutdown_funcs = NULL; FreePluginSigFuncs(plugin_clean_exit_funcs); plugin_clean_exit_funcs = NULL; #ifdef SNORT_RELOAD FreePluginPostConfigFuncs(plugin_reload_funcs); plugin_reload_funcs = NULL; #endif FreePeriodicFuncs(periodic_check_funcs); periodic_check_funcs = NULL; ParserCleanup(); CloseDynamicPreprocessorLibs(); CloseDynamicEngineLibs(); #ifdef SIDE_CHANNEL CloseDynamicSideChannelLibs(); #endif output_unload(); CleanupTag(); ClearDumpBuf(); #ifdef PERF_PROFILING CleanupPreprocStatsNodeList(); #endif if (netmasks != NULL) { free(netmasks); netmasks = NULL; } if (protocol_names != NULL) { int i; for (i = 0; i < NUM_IP_PROTOS; i++) { if (protocol_names[i] != NULL) free(protocol_names[i]); } free(protocol_names); protocol_names = NULL; } #ifdef INTEL_SOFT_CPM IntelPmStopInstance(); #endif SynToMulticastDstIpDestroy(); MulticastReservedIpDestroy(); FreeVarList(cmd_line_var_list); if (snort_conf_file != NULL) free(snort_conf_file); if (snort_conf_dir != NULL) free(snort_conf_dir); if (s_packet.ip6_extensions != NULL) free(s_packet.ip6_extensions); close_fileAPI(); pthread_mutex_unlock(&cleanup_mutex); } void Restart(void) { int daemon_mode = ScDaemonMode(); #ifndef WIN32 if ((!ScReadMode() && (getuid() != 0)) || (snort_conf->chroot_dir != NULL)) { LogMessage("Reload via Signal Reload does not work if you aren't root " "or are chroot'ed.\n"); # ifdef SNORT_RELOAD /* We are restarting because of a configuration verification problem */ CleanExit(1); # else return; # endif } #endif /* WIN32 */ LogMessage("\n"); LogMessage("***** Restarting Snort *****\n"); LogMessage("\n"); SnortCleanup(0); if (daemon_mode) { int ch; int option_index = -1; optind = 1; while ((ch = getopt_long(snort_argc, snort_argv, valid_options, long_options, &option_index)) != -1) { switch (ch) { case 'D': { int i = optind-1, j; int index = strlen(snort_argv[i]) - 1; /* 'D' isn't the last option in the opt string so * optind hasn't moved past this option string yet */ if ((snort_argv[i][0] != '-') || ((index > 0) && (snort_argv[i][1] == '-')) || (snort_argv[i][index] != 'D')) { i++; } /* Replace -D with -E to indicate we've already daemonized */ for (j = 0; j < (int)strlen(snort_argv[i]); j++) { if (snort_argv[i][j] == 'D') { snort_argv[i][j] = 'E'; break; } } } break; default: break; } } } #ifdef PARANOID execv(snort_argv[0], snort_argv); #else execvp(snort_argv[0], snort_argv); #endif /* only get here if we failed to restart */ LogMessage("Restarting %s failed: %s\n", snort_argv[0], strerror(errno)); #ifndef WIN32 closelog(); #endif exit(-1); } void print_packet_count(void) { LogMessage("[" STDu64 "]", pc.total_from_daq); } /* * Check for signal activity */ int SignalCheck(void) { switch (exit_signal) { case SIGTERM: if (!exit_logged) { ErrorMessage("*** Caught Term-Signal\n"); exit_logged = 1; if ( DAQ_BreakLoop(DAQ_SUCCESS) ) return 0; } CleanExit(0); break; case SIGINT: if (!exit_logged) { ErrorMessage("*** Caught Int-Signal\n"); exit_logged = 1; if ( DAQ_BreakLoop(DAQ_SUCCESS) ) return 0; } CleanExit(0); break; case SIGQUIT: if (!exit_logged) { ErrorMessage("*** Caught Quit-Signal\n"); exit_logged = 1; if ( DAQ_BreakLoop(DAQ_SUCCESS) ) return 0; } CleanExit(0); break; default: break; } if (dump_stats_signal) { ErrorMessage("*** Caught Dump Stats-Signal\n"); DropStats(0); } dump_stats_signal = false; if (rotate_stats_signal) { ErrorMessage("*** Caught Signal: 'Rotate Perfmonitor Stats'\n"); /* Make sure the preprocessor is enabled - it can only be enabled * in default policy */ if (!ScIsPreprocEnabled(PP_PERFMONITOR, 0)) { ErrorMessage("!!! Cannot rotate stats - Perfmonitor is not configured !!!\n"); } else { SetRotatePerfFileFlag(); } } rotate_stats_signal = false; #ifdef TARGET_BASED if (no_attr_table_signal) ErrorMessage("!!! Cannot reload attribute table - Attribute table is not configured !!!\n"); no_attr_table_signal = false; #endif #ifndef SNORT_RELOAD if (reload_signal ) { ErrorMessage("*** Caught Reload-Signal\n"); reload_signal = false; return 1; } reload_signal = false; #endif return 0; } static void InitGlobals(void) { memset(&pc, 0, sizeof(pc)); InitNetmasks(); InitProtoNames(); #ifdef SIDE_CHANNEL pthread_mutex_init(&snort_process_lock, NULL); #endif pthread_mutex_init(&cleanup_mutex, NULL); pthread_mutex_init(&dynamic_rules_lock, NULL); } /* Alot of this initialization can be skipped if not running in IDS mode * but the goal is to minimize config checks at run time when running in * IDS mode so we keep things simple and enforce that the only difference * among run_modes is how we handle packets via the log_func. */ SnortConfig * SnortConfNew(void) { SnortConfig *sc = (SnortConfig *)SnortAlloc(sizeof(SnortConfig)); sc->pkt_cnt = 0; #ifdef REG_TEST sc->pkt_skip = 0; #endif sc->pkt_snaplen = -1; /*user_id and group_id should be initialized to -1 by default, because * chown() use this later, -1 means no change to user_id/group_id*/ sc->user_id = -1; sc->group_id = -1; sc->checksum_flags = CHECKSUM_FLAG__ALL; sc->tagged_packet_limit = 256; sc->default_rule_state = RULE_STATE_ENABLED; sc->pcre_match_limit = 1500; sc->pcre_match_limit_recursion = 1500; sc->ipv6_max_frag_sessions = 10000; sc->ipv6_frag_timeout = 60; /* This is the default timeout on BSD */ memset(sc->pid_path, 0, sizeof(sc->pid_path)); memset(sc->pid_filename, 0, sizeof(sc->pid_filename)); memset(sc->pidfile_suffix, 0, sizeof(sc->pidfile_suffix)); #ifdef TARGET_BASED /* Default max size of the attribute table */ sc->max_attribute_hosts = DEFAULT_MAX_ATTRIBUTE_HOSTS; sc->max_attribute_services_per_host = DEFAULT_MAX_ATTRIBUTE_SERVICES_PER_HOST; /* Default max number of services per rule */ sc->max_metadata_services = DEFAULT_MAX_METADATA_SERVICES; #endif #if defined(FEAT_OPEN_APPID) sc->max_metadata_appid = DEFAULT_MAX_METADATA_APPID; #endif /* defined(FEAT_OPEN_APPID) */ #ifdef MPLS sc->mpls_stack_depth = DEFAULT_LABELCHAIN_LENGTH; #endif sc->targeted_policies = NULL; sc->num_policies_allocated = 0; sc->paf_max = DEFAULT_PAF_MAX; /* Default secure hash pattern type */ sc->Default_Protected_Content_Hash_Type = SECHASH_NONE; sc->max_ip6_extensions = DEFAULT_MAX_IP6_EXTENSIONS; sc->internal_log_level = INTERNAL_LOG_LEVEL__MESSAGE; return sc; } void SnortConfFree(SnortConfig *sc) { tSfPolicyId i; if (sc == NULL) return; if (sc->dynamic_rules_path != NULL) free(sc->dynamic_rules_path); if (sc->log_dir != NULL) free(sc->log_dir); if (sc->orig_log_dir != NULL) free(sc->orig_log_dir); if (sc->interface != NULL) free(sc->interface); if (sc->bpf_file != NULL) free(sc->bpf_file); if (sc->pcap_log_file != NULL) free(sc->pcap_log_file); if (sc->chroot_dir != NULL) free(sc->chroot_dir); if (sc->alert_file != NULL) free(sc->alert_file); if (sc->perf_file != NULL) free(sc->perf_file); if (sc->bpf_filter != NULL) free(sc->bpf_filter); if (sc->event_trace_file != NULL) free(sc->event_trace_file); #ifdef PERF_PROFILING if (sc->profile_rules.filename != NULL) free(sc->profile_rules.filename); if (sc->profile_preprocs.filename != NULL) free(sc->profile_preprocs.filename); #endif /* Main Thread only should cleanup if snort is exiting unless dynamic libs have changed */ if (detection_lib_changed || (InMainThread() && snort_exiting)) { pthread_mutex_lock(&dynamic_rules_lock); DynamicRuleListFree(sc->dynamic_rules); sc->dynamic_rules = NULL; pthread_mutex_unlock(&dynamic_rules_lock); CloseDynamicDetectionLibs(sc); detection_lib_changed = false; } FreeDynamicLibInfos(sc); FreeOutputConfigs(sc->output_configs); FreeOutputConfigs(sc->rule_type_output_configs); #ifdef SIDE_CHANNEL FreeSideChannelModuleConfigs(sc->side_channel_config.module_configs); #ifdef REG_TEST if (sc && sc->file_config) FileSSConfigFree(sc->file_config); #endif #endif FreePreprocConfigs(sc); if (sc->config_table != NULL) sfghash_delete(sc->config_table); if (sc->base_version != NULL) free(sc->base_version); for (i = 0; i < sc->num_policies_allocated; i++) { SnortPolicyFree(sc->targeted_policies[i]); } FreeRuleStateList(sc->rule_state_list); FreeClassifications(sc->classifications); FreeReferences(sc->references); FreeRuleLists(sc); SoRuleOtnLookupFree(sc->so_rule_otn_map); OtnLookupFree(sc->otn_map); VarTablesFree(sc); PortTablesFree(sc->port_tables); FastPatternConfigFree(sc->fast_pattern_config); ThresholdConfigFree(sc->threshold_config); RateFilter_ConfigFree(sc->rate_filter_config); DetectionFilterConfigFree(sc->detection_filter_config); FreePlugins(sc); PreprocessorRuleOptionsFree(sc->preproc_rule_options); OtnxMatchDataFree(sc->omd); if (sc->pcre_ovector != NULL) free(sc->pcre_ovector); if ( sc->event_queue_config ) EventQueueConfigFree(sc->event_queue_config); if ( sc->event_queue ) SnortEventqFree(sc->event_queue); if (sc->ip_proto_only_lists != NULL) { unsigned int j; for (j = 0; j < NUM_IP_PROTOS; j++) sflist_free_all(sc->ip_proto_only_lists[j], NULL); free(sc->ip_proto_only_lists); } sfPolicyFini(sc->policy_config); fpDeleteFastPacketDetection(sc); if (sc->rtn_hash_table) sfxhash_delete(sc->rtn_hash_table); for (i = 0; i < sc->num_policies_allocated; i++) { SnortPolicy *p = sc->targeted_policies[i]; if (p != NULL) free(p); } free(sc->targeted_policies); if ( sc->react_page ) free(sc->react_page); if ( sc->daq_type ) free(sc->daq_type); if ( sc->daq_mode ) free(sc->daq_mode); if ( sc->daq_vars ) StringVector_Delete(sc->daq_vars); if ( sc->daq_dirs ) StringVector_Delete(sc->daq_dirs); #ifdef ACTIVE_RESPONSE if ( sc->respond_device ) free(sc->respond_device); if (sc->eth_dst ) free(sc->eth_dst); #endif if (sc->gtp_ports) free(sc->gtp_ports); if(sc->cs_dir) free(sc->cs_dir); #ifdef REG_TEST if(sc->ha_out) free(sc->ha_out); if(sc->ha_in) free(sc->ha_in); if(sc->ha_pdts_in) free(sc->ha_pdts_in); #endif free_file_config(sc->file_config); #ifdef SIDE_CHANNEL if (sc->side_channel_config.opts) free(sc->side_channel_config.opts); #endif #ifdef DUMP_BUFFER if (sc->buffer_dump_file) StringVector_Delete(sc->buffer_dump_file); #endif #ifdef INTEL_SOFT_CPM IntelPmRelease(sc->ipm_handles); #endif #ifdef SNORT_RELOAD FreePreprocessorReloadData(sc); ReloadFreeAdjusters(sc); #endif FreeMandatoryEarlySessionCreators(sc->mandatoryESCreators); free(sc); #ifdef HAVE_MALLOC_TRIM malloc_trim(0); #endif } /**************************************************************************** * * Function: InitNetMasks() * * Purpose: Loads the netmask struct in network order. Yes, I know I could * just load the array when I define it, but this is what occurred * to me when I wrote this at 3:00 AM. * * Arguments: None. * * Returns: void function * ****************************************************************************/ static void InitNetmasks(void) { if (netmasks == NULL) netmasks = (uint32_t *)SnortAlloc(33 * sizeof(uint32_t)); netmasks[0] = 0x00000000; netmasks[1] = 0x80000000; netmasks[2] = 0xC0000000; netmasks[3] = 0xE0000000; netmasks[4] = 0xF0000000; netmasks[5] = 0xF8000000; netmasks[6] = 0xFC000000; netmasks[7] = 0xFE000000; netmasks[8] = 0xFF000000; netmasks[9] = 0xFF800000; netmasks[10] = 0xFFC00000; netmasks[11] = 0xFFE00000; netmasks[12] = 0xFFF00000; netmasks[13] = 0xFFF80000; netmasks[14] = 0xFFFC0000; netmasks[15] = 0xFFFE0000; netmasks[16] = 0xFFFF0000; netmasks[17] = 0xFFFF8000; netmasks[18] = 0xFFFFC000; netmasks[19] = 0xFFFFE000; netmasks[20] = 0xFFFFF000; netmasks[21] = 0xFFFFF800; netmasks[22] = 0xFFFFFC00; netmasks[23] = 0xFFFFFE00; netmasks[24] = 0xFFFFFF00; netmasks[25] = 0xFFFFFF80; netmasks[26] = 0xFFFFFFC0; netmasks[27] = 0xFFFFFFE0; netmasks[28] = 0xFFFFFFF0; netmasks[29] = 0xFFFFFFF8; netmasks[30] = 0xFFFFFFFC; netmasks[31] = 0xFFFFFFFE; netmasks[32] = 0xFFFFFFFF; } /**************************************************************************** * * Function: InitProtoNames() * * Purpose: Initializes the protocol names * * Arguments: None. * * Returns: void function * ****************************************************************************/ static void InitProtoNames(void) { int i; if (protocol_names == NULL) protocol_names = (char **)SnortAlloc(sizeof(char *) * NUM_IP_PROTOS); for (i = 0; i < NUM_IP_PROTOS; i++) { switch(i) { #ifdef REG_TEST #define PROTO_000 "IP" //Appears as HOPOPT on some systems #define PROTO_004 "IPENCAP" //Appears as IPV4 on some systems #define PROTO_255 "PROTO:255" //Appears as RESERVED on some systems case 0: protocol_names[i] = SnortStrdup(PROTO_000); break; case 4: protocol_names[i] = SnortStrdup(PROTO_004); break; case 255: protocol_names[i] = SnortStrdup(PROTO_255); break; #endif default: { struct protoent *pt = getprotobynumber(i); if (pt != NULL) { size_t j; protocol_names[i] = SnortStrdup(pt->p_name); for (j = 0; j < strlen(protocol_names[i]); j++) protocol_names[i][j] = toupper(protocol_names[i][j]); } else { char protoname[10]; SnortSnprintf(protoname, sizeof(protoname), "PROTO:%03d", i); protocol_names[i] = SnortStrdup(protoname); } } } } } static void SetSnortConfDir(void) { /* extract the config directory from the config filename */ if (snort_conf_file != NULL) { #ifndef WIN32 char *path_sep = strrchr(snort_conf_file, '/'); #else char *path_sep = strrchr(snort_conf_file, '\\'); #endif /* is there a directory seperator in the filename */ if (path_sep != NULL) { path_sep++; /* include path separator */ snort_conf_dir = SnortStrndup(snort_conf_file, path_sep - snort_conf_file); } else { snort_conf_dir = SnortStrdup("./"); } DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Config file = %s, config dir = " "%s\n", snort_conf_file, snort_conf_dir);); } } static void FreePlugins(SnortConfig *sc) { if (sc == NULL) return; FreePreprocessors(sc); FreePluginPostConfigFuncs(sc->plugin_post_config_funcs); sc->plugin_post_config_funcs = NULL; } static void FreePreprocessors(SnortConfig *sc) { tSfPolicyId i; if (sc == NULL) return; FreePreprocCheckConfigFuncs(sc->preproc_config_check_funcs); sc->preproc_config_check_funcs = NULL; for (i = 0; i < sc->num_policies_allocated; i++) { SnortPolicy *p = sc->targeted_policies[i]; if (p == NULL) continue; FreePreprocEvalFuncs(p->preproc_eval_funcs); p->preproc_eval_funcs = NULL; p->num_preprocs = 0; FreePreprocEvalFuncs(p->unused_preproc_eval_funcs); p->unused_preproc_eval_funcs = NULL; FreePreprocMetaEvalFuncs(p->preproc_meta_eval_funcs); p->preproc_meta_eval_funcs = NULL; p->num_meta_preprocs = 0; FreeDetectionEvalFuncs(p->detect_eval_funcs); p->detect_eval_funcs = NULL; p->num_detects = 0; } FreePreprocPostConfigFuncs(sc->preproc_post_config_funcs); sc->preproc_post_config_funcs = NULL; } SnortConfig * MergeSnortConfs(SnortConfig *cmd_line, SnortConfig *config_file) { unsigned int i; /* Move everything from the command line config over to the * config_file config */ if (cmd_line == NULL) { FatalError("%s(%d) Merging snort configs: snort conf is NULL.\n", __FILE__, __LINE__); } ResolveOutputPlugins(cmd_line, config_file); if (config_file == NULL) { if (cmd_line->log_dir == NULL) cmd_line->log_dir = SnortStrdup(DEFAULT_LOG_DIR); } else if ((cmd_line->log_dir == NULL) && (config_file->log_dir == NULL)) { config_file->log_dir = SnortStrdup(DEFAULT_LOG_DIR); } else if (cmd_line->log_dir != NULL) { if (config_file->log_dir != NULL) free(config_file->log_dir); config_file->log_dir = SnortStrdup(cmd_line->log_dir); } if (config_file == NULL) return cmd_line; /* Used because of a potential chroot */ config_file->orig_log_dir = SnortStrdup(config_file->log_dir); config_file->run_mode = cmd_line->run_mode; config_file->run_mode_flags |= cmd_line->run_mode_flags; if ((cmd_line->run_mode == RUN_MODE__TEST) && (config_file->run_flags & RUN_FLAG__DAEMON)) { /* Just ignore deamon setting in conf file */ config_file->run_flags &= ~RUN_FLAG__DAEMON; } config_file->run_flags |= cmd_line->run_flags; config_file->output_flags |= cmd_line->output_flags; config_file->logging_flags |= cmd_line->logging_flags; config_file->internal_log_level = cmd_line->internal_log_level; config_file->suppress_config_log = cmd_line->suppress_config_log; /* Merge checksum flags. If command line modified them, use from the * command line, else just use from config_file. */ for (i = 0; i < config_file->num_policies_allocated; i++) { if (config_file->targeted_policies[i] != NULL) { if (cmd_line->checksum_flags_modified) config_file->targeted_policies[i]->checksum_flags = cmd_line->checksum_flags; if (cmd_line->checksum_drop_flags_modified) config_file->targeted_policies[i]->checksum_drop_flags = cmd_line->checksum_drop_flags; } } config_file->event_log_id = cmd_line->event_log_id; if (cmd_line->dynamic_rules_path != NULL) { if(strcmp(cmd_line->dynamic_rules_path, "") != 0) { if( config_file->dynamic_rules_path != NULL ) free(config_file->dynamic_rules_path); config_file->dynamic_rules_path = SnortStrdup(cmd_line->dynamic_rules_path); } } if (cmd_line->dyn_engines != NULL) { FreeDynamicLibInfo(config_file->dyn_engines); config_file->dyn_engines = DupDynamicLibInfo(cmd_line->dyn_engines); } if (cmd_line->dyn_rules != NULL) { FreeDynamicLibInfo(config_file->dyn_rules); config_file->dyn_rules = DupDynamicLibInfo(cmd_line->dyn_rules); } if (cmd_line->dyn_preprocs != NULL) { FreeDynamicLibInfo(config_file->dyn_preprocs); config_file->dyn_preprocs = DupDynamicLibInfo(cmd_line->dyn_preprocs); } if (cmd_line->pid_path[0] != '\0') ConfigPidPath(config_file, cmd_line->pid_path); config_file->exit_check = cmd_line->exit_check; /* Command line only configures search method */ if (cmd_line->fast_pattern_config != NULL) config_file->fast_pattern_config->search_method = cmd_line->fast_pattern_config->search_method; if (sfip_is_set(&cmd_line->obfuscation_net)) memcpy(&config_file->obfuscation_net, &cmd_line->obfuscation_net, sizeof(sfcidr_t)); if (sfip_is_set(&cmd_line->homenet)) memcpy(&config_file->homenet, &cmd_line->homenet, sizeof(sfcidr_t)); if (cmd_line->interface != NULL) { if (config_file->interface != NULL) free(config_file->interface); config_file->interface = SnortStrdup(cmd_line->interface); } if (cmd_line->bpf_file != NULL) { if (config_file->bpf_file != NULL) free(config_file->bpf_file); config_file->bpf_file = SnortStrdup(cmd_line->bpf_file); } if (cmd_line->bpf_filter != NULL) config_file->bpf_filter = SnortStrdup(cmd_line->bpf_filter); if (cmd_line->pkt_snaplen != -1) config_file->pkt_snaplen = cmd_line->pkt_snaplen; if (cmd_line->pkt_cnt != 0) config_file->pkt_cnt = cmd_line->pkt_cnt; #ifdef REG_TEST if (cmd_line->pkt_skip != 0) config_file->pkt_skip = cmd_line->pkt_skip; #endif if (cmd_line->group_id != -1) config_file->group_id = cmd_line->group_id; if (cmd_line->user_id != -1) config_file->user_id = cmd_line->user_id; /* Only configurable on command line */ if (cmd_line->pcap_log_file != NULL) config_file->pcap_log_file = SnortStrdup(cmd_line->pcap_log_file); if (cmd_line->file_mask != 0) config_file->file_mask = cmd_line->file_mask; if (cmd_line->pidfile_suffix[0] != '\0') { SnortStrncpy(config_file->pidfile_suffix, cmd_line->pidfile_suffix, sizeof(config_file->pidfile_suffix)); } if (cmd_line->chroot_dir != NULL) { if (config_file->chroot_dir != NULL) free(config_file->chroot_dir); config_file->chroot_dir = SnortStrdup(cmd_line->chroot_dir); } if (cmd_line->perf_file != NULL) { if (config_file->perf_file != NULL) free(config_file->perf_file); config_file->perf_file = SnortStrdup(cmd_line->perf_file); } if ( cmd_line->daq_type ) config_file->daq_type = SnortStrdup(cmd_line->daq_type); if ( cmd_line->daq_mode ) config_file->daq_mode = SnortStrdup(cmd_line->daq_mode); if ( cmd_line->dirty_pig ) config_file->dirty_pig = cmd_line->dirty_pig; if ( cmd_line->daq_vars ) { /* Command line overwrites daq_vars */ if (config_file->daq_vars) StringVector_Delete(config_file->daq_vars); config_file->daq_vars = StringVector_New(); StringVector_AddVector(config_file->daq_vars, cmd_line->daq_vars); } if ( cmd_line->daq_dirs ) { /* Command line overwrites daq_dirs */ if (config_file->daq_dirs) StringVector_Delete(config_file->daq_dirs); config_file->daq_dirs = StringVector_New(); StringVector_AddVector(config_file->daq_dirs, cmd_line->daq_dirs); } #ifdef MPLS if (cmd_line->mpls_stack_depth != DEFAULT_LABELCHAIN_LENGTH) config_file->mpls_stack_depth = cmd_line->mpls_stack_depth; /* Set MPLS payload type here if it hasn't been defined */ if ((cmd_line->mpls_payload_type == 0) && (config_file->mpls_payload_type == 0)) { config_file->mpls_payload_type = DEFAULT_MPLS_PAYLOADTYPE; } else if (cmd_line->mpls_payload_type != 0) { config_file->mpls_payload_type = cmd_line->mpls_payload_type; } #endif if (cmd_line->run_flags & RUN_FLAG__PROCESS_ALL_EVENTS) config_file->event_queue_config->process_all_events = 1; if (cmd_line->cs_dir != NULL) { if (config_file->cs_dir != NULL) free(config_file->cs_dir); config_file->cs_dir = SnortStrdup(cmd_line->cs_dir); } if (config_file->cs_dir) { #ifndef WIN32 /* * If an absolute path is specified, then use that. * otherwise, relative to pid path */ if ((config_file->cs_dir[0] != '/') && config_file->pid_path[0]) { char fullpath[PATH_MAX]; if (config_file->pid_path[strlen(config_file->pid_path) - 1] == '/') { SnortSnprintf(fullpath, sizeof(fullpath), "%s%s", config_file->pid_path, config_file->cs_dir); } else { SnortSnprintf(fullpath, sizeof(fullpath), "%s/%s", config_file->pid_path, config_file->cs_dir); } free (config_file->cs_dir); config_file->cs_dir = SnortStrdup(fullpath); } #else /*Not supported in WINDOWS*/ free (config_file->cs_dir); config_file->cs_dir = NULL; #endif ControlSocketConfigureDirectory(config_file->cs_dir); } #ifdef REG_TEST config_file->ha_peer = cmd_line->ha_peer; if ( cmd_line->ha_out ) { if(config_file->ha_out != NULL) free(config_file->ha_out); config_file->ha_out = strdup(cmd_line->ha_out); } if ( cmd_line->ha_in ) { if(config_file->ha_in != NULL) free(config_file->ha_in); config_file->ha_in = strdup(cmd_line->ha_in); } if ( cmd_line->ha_pdts_in ) { if(config_file->ha_pdts_in != NULL) free(config_file->ha_pdts_in); config_file->ha_pdts_in = strdup(cmd_line->ha_pdts_in); } #endif #ifdef DUMP_BUFFER /* Command line overwrites daq_dirs */ if (config_file->buffer_dump_file) StringVector_Delete(config_file->buffer_dump_file); config_file->buffer_dump_file = StringVector_New(); StringVector_AddVector(config_file->buffer_dump_file, cmd_line->buffer_dump_file); #endif return config_file; } static void FreeDynamicLibInfos(SnortConfig *sc) { if (sc == NULL) return; if (sc->dyn_engines != NULL) { FreeDynamicLibInfo(sc->dyn_engines); sc->dyn_engines = NULL; } if (sc->dyn_rules != NULL) { FreeDynamicLibInfo(sc->dyn_rules); sc->dyn_rules = NULL; } if (sc->dyn_preprocs != NULL) { FreeDynamicLibInfo(sc->dyn_preprocs); sc->dyn_preprocs = NULL; } #ifdef SIDE_CHANNEL if (sc->dyn_side_channels != NULL) { FreeDynamicLibInfo(sc->dyn_side_channels); sc->dyn_side_channels = NULL; } #endif } static void FreeDynamicLibInfo(DynamicLibInfo *lib_info) { unsigned i; if (lib_info == NULL) return; for (i = 0; i < lib_info->count; i++) { free(lib_info->lib_paths[i]->path); free(lib_info->lib_paths[i]); } free(lib_info); } static DynamicLibInfo * DupDynamicLibInfo(DynamicLibInfo *src) { DynamicLibInfo *dst; unsigned i; if (src == NULL) return NULL; dst = (DynamicLibInfo *)SnortAlloc(sizeof(DynamicLibInfo)); dst->type = src->type; dst->count = src->count; for (i = 0; i < src->count; i++) { DynamicLibPath *dylib_path = (DynamicLibPath *)SnortAlloc(sizeof(DynamicLibPath)); dylib_path->ptype = src->lib_paths[i]->ptype; dylib_path->path = SnortStrdup(src->lib_paths[i]->path); dst->lib_paths[i] = dylib_path; } return dst; } void FreeVarList(VarNode *head) { while (head != NULL) { VarNode *tmp = head; head = head->next; if (tmp->name != NULL) free(tmp->name); if (tmp->value != NULL) free(tmp->value); if (tmp->line != NULL) free(tmp->line); free(tmp); } } void SnortInit(int argc, char **argv) { #ifdef WIN32 char dllSearchPath[PATH_MAX]; #endif InitSignals(); #if defined(NOCOREFILE) && !defined(WIN32) SetNoCores(); #else StoreSnortInfoStrings(); #endif #ifdef WIN32 if(GetSystemDirectory(dllSearchPath, PATH_MAX)) { LogMessage("System directory is: %s\n", dllSearchPath); if (!SetDllDirectory(dllSearchPath)) FatalError("Failed to set Windows DLL search path.\n"); } else FatalError("Could not find the Windows System directory.\n"); if (!init_winsock()) // TBD moves to windows daq FatalError("Could not Initialize Winsock!\n"); #endif InitGlobals(); /* chew up the command line */ ParseCmdLine(argc, argv); switch (snort_conf->run_mode) { case RUN_MODE__VERSION: break; case RUN_MODE__RULE_DUMP: LogMessage("Running in Rule Dump mode\n"); break; case RUN_MODE__IDS: LogMessage("Running in IDS mode\n"); break; case RUN_MODE__TEST: LogMessage("Running in Test mode\n"); break; case RUN_MODE__PACKET_LOG: LogMessage("Running in packet logging mode\n"); break; case RUN_MODE__PACKET_DUMP: LogMessage("Running in packet dump mode\n"); break; default: break; } if (ScSuppressConfigLog() || ScVersionMode()) ScSetInternalLogLevel(INTERNAL_LOG_LEVEL__ERROR); LogMessage("\n"); LogMessage(" --== Initializing Snort ==--\n"); if (SnortStrnlen(signal_error_msg, STD_BUF)> 0) { ErrorMessage("%s", signal_error_msg); } if (!ScVersionMode()) { /* Every run mode except version will potentially need output * If output plugins should become dynamic, this needs to move */ RegisterOutputPlugins(); #ifdef DEBUG DumpOutputPlugins(); #endif } init_fileAPI(); /* if we're using the rules system, it gets initialized here */ if (snort_conf_file != NULL) { SnortConfig *sc; /* initialize all the plugin modules */ RegisterPreprocessors(); RegisterRuleOptions(); InitTag(); #ifdef DEBUG DumpPreprocessors(); DumpRuleOptions(); #endif #ifdef PERF_PROFILING /* Register the main high level perf stats */ RegisterPreprocessorProfile("detect", &detectPerfStats, 0, &totalPerfStats, NULL); RegisterPreprocessorProfile("mpse", &mpsePerfStats, 1, &detectPerfStats, NULL); RegisterPreprocessorProfile("rule eval", &rulePerfStats, 1, &detectPerfStats, NULL); RegisterPreprocessorProfile("rtn eval", &ruleRTNEvalPerfStats, 2, &rulePerfStats, NULL); RegisterPreprocessorProfile("rule tree eval", &ruleOTNEvalPerfStats, 2, &rulePerfStats, NULL); RegisterPreprocessorProfile("preproc_rule_options", &preprocRuleOptionPerfStats, 3, &ruleOTNEvalPerfStats, NULL); RegisterPreprocessorProfile("decode", &decodePerfStats, 0, &totalPerfStats, NULL); RegisterPreprocessorProfile("eventq", &eventqPerfStats, 0, &totalPerfStats, NULL); RegisterPreprocessorProfile("total", &totalPerfStats, 0, NULL, NULL); RegisterPreprocessorProfile("daq meta", &metaPerfStats, 0, NULL, NULL); (void)PerfIndicator_RegisterPreprocStat( &totalPerfStats, Perf_Indicator_Type_Packet_Latency ); #endif LogMessage("Parsing Rules file \"%s\"\n", snort_conf_file); sc = ParseSnortConf(); /* Merge the command line and config file confs to take care of * command line overriding config file. * Set the global snort_conf that will be used during run time */ snort_conf = MergeSnortConfs(snort_cmd_line_conf, sc); InitSynToMulticastDstIp(snort_conf); InitMulticastReservedIp(snort_conf); #ifdef TARGET_BASED /* Parse attribute table stuff here since config max_attribute_hosts * is apart from attribute table configuration. * Only attribute table in default policy is processed. Attribute table in * other policies indicates that attribute table in default table should * be used. Filenames for attribute_table should be same across all policies. */ { tSfPolicyId defaultPolicyId = sfGetDefaultPolicy(snort_conf->policy_config); TargetBasedConfig *tbc = &snort_conf->targeted_policies[defaultPolicyId]->target_based_config; if (tbc->args != NULL) { char *saved_file_name = file_name; int saved_file_line = file_line; file_name = tbc->file_name; file_line = tbc->file_line; SFAT_ParseAttributeTable(tbc->args, snort_conf); #ifndef WIN32 if (!ScDisableAttrReload(snort_conf)) { /* Register signal handler for attribute table. */ SnortAddSignal(SIGNAL_SNORT_READ_ATTR_TBL,SigAttributeTableReloadHandler,0); if(errno != 0) errno = 0; } #endif file_name = saved_file_name; file_line = saved_file_line; } } #endif if (snort_conf->asn1_mem != 0) asn1_init_mem(snort_conf->asn1_mem); else asn1_init_mem(256); if (snort_conf->alert_file != NULL) { char *tmp = snort_conf->alert_file; snort_conf->alert_file = ProcessFileOption(snort_conf, snort_conf->alert_file); free(tmp); } #ifdef PERF_PROFILING /* Parse profiling here because of file option and potential * dependence on log directory */ { char *opts = NULL; int in_table; in_table = sfghash_find2(snort_conf->config_table, CONFIG_OPT__PROFILE_PREPROCS, (void *)&opts); if (in_table) ConfigProfilePreprocs(snort_conf, opts); in_table = sfghash_find2(snort_conf->config_table, CONFIG_OPT__PROFILE_RULES, (void *)&opts); if (in_table) ConfigProfileRules(snort_conf, opts); } #endif if (ScAlertBeforePass()) { OrderRuleLists(snort_conf, "activation dynamic drop sdrop reject alert pass log"); } LogMessage("Tagged Packet Limit: %ld\n", snort_conf->tagged_packet_limit); /* Handles Fatal Errors itself. */ SnortEventqNew(snort_conf->event_queue_config, snort_conf->event_queue); } else if (ScPacketLogMode() || ScPacketDumpMode()) { /* Make sure there is a log directory */ /* This will return the cmd line conf and resolve the output * configuration */ SnortConfig* sc = ParseSnortConf(); snort_conf = MergeSnortConfs(snort_cmd_line_conf, sc); InitTag(); SnortEventqNew(snort_conf->event_queue_config, snort_conf->event_queue); } /* Allocate an array for IP6 extensions for the main Packet struct */ // Make sure this memory is freed on exit. s_packet.ip6_extensions = SnortAlloc(sizeof(*s_packet.ip6_extensions) * ScMaxIP6Extensions()); /* Finish up the pcap list and put in the queues */ PQ_SetUp(); if ((snort_conf->bpf_filter == NULL) && (snort_conf->bpf_file != NULL)) { LogMessage("Reading filter from bpf file: %s\n", snort_conf->bpf_file); snort_conf->bpf_filter = read_infile(snort_conf->bpf_file); } if (snort_conf->bpf_filter != NULL) LogMessage("Snort BPF option: %s\n", snort_conf->bpf_filter); LoadDynamicPlugins(snort_conf); /* Display snort version information here so that we can also show dynamic * plugin versions, if loaded. */ if (ScVersionMode()) { ScRestoreInternalLogLevel(); PrintVersion(snort_conf); CleanExit(0); } /* Validate the log directory for logging packets - probably should * add test mode as well, but not expected behavior */ if ( !(ScNoLog() && ScNoAlert()) ) { if (ScPacketLogMode()) CheckLogDir(); LogMessage("Log directory = %s\n", snort_conf->log_dir); } if (ScOutputUseUtc()) snort_conf->thiszone = 0; else snort_conf->thiszone = gmt2local(0); /* ripped from tcpdump */ ConfigureOutputPlugins(snort_conf); /* Have to split up configuring preprocessors between internal and dynamic * because the dpd structure has a pointer to the stream api and stream5 * needs to be configured first to set this */ ConfigurePreprocessors(snort_conf, 0); InitDynamicEngines(snort_conf->dynamic_rules_path); if (ScRuleDumpMode()) { if( snort_conf->dynamic_rules_path == NULL ) { FatalError("%s(%d) Please specify the directory path for dumping the dynamic rules \n", __FILE__, __LINE__); } DumpDetectionLibRules(snort_conf); CleanExit(0); } /* This will load each dynamic preprocessor module specified and set * the _dpd structure for each */ InitDynamicPreprocessors(); /* Now configure the dynamic preprocessors since the dpd structure * should be filled in and have the correct values */ ConfigurePreprocessors(snort_conf, 1); ParseRules(snort_conf); RuleOptParseCleanup(); InitDynamicDetectionPlugins(snort_conf); EventTrace_Init(); if (ScIdsMode() || ScTestMode()) { detection_filter_print_config(snort_conf->detection_filter_config); RateFilter_PrintConfig(snort_conf->rate_filter_config); print_thresholding(snort_conf->threshold_config, 0); PrintRuleOrder(snort_conf->rule_lists); /* Check rule state lists, enable/disabled * and err on 'special' GID without OTN. */ /* * Modified toi use sigInfo.shared in otn instead of the GENERATOR ID - man */ SetRuleStates(snort_conf); /* Verify the preprocessors are configured properly */ if (CheckPreprocessorsConfig(snort_conf)) { SnortFatalExit(); } /* Remove disabled preprocessors if policies are disabled */ FilterConfigPreprocessors(snort_conf); /* Need to do this after dynamic detection stuff is initialized, too */ FlowBitsVerify(); } if (snort_conf->file_mask != 0) umask(snort_conf->file_mask); else umask(077); /* set default to be sane */ // the following was moved from unpriv init; hopefully it can live here. decoderActionQ = sfActionQueueInit(snort_conf->event_queue_config->max_events*2); if (mempool_init(&decoderAlertMemPool, snort_conf->event_queue_config->max_events*2, sizeof(EventNode)) != 0) { FatalError("%s(%d) Could not initialize decoder action queue memory pool.\n", __FILE__, __LINE__); } fpCreateFastPacketDetection(snort_conf); #ifdef INTEL_SOFT_CPM if (snort_conf->fast_pattern_config->search_method == MPSE_INTEL_CPM) IntelPmActivate(snort_conf); #endif #ifdef PPM_MGR PPM_PRINT_CFG(&snort_conf->ppm_cfg); #endif #if defined(DAQ_VERSION) && DAQ_VERSION > 9 // This is needed when PPM is disabled and enabling snort-engine debugs if (!ppm_tpu) ppm_tpu = (PPM_TICKS)get_ticks_per_usec(); #endif #ifdef SIDE_CHANNEL RegisterSideChannelModules(); InitDynamicSideChannelPlugins(); ConfigureSideChannelModules(snort_conf); SideChannelConfigure(snort_conf); SideChannelInit(); #ifndef REG_TEST if (snort_conf && snort_conf->file_config) check_sidechannel_enabled(snort_conf->file_config); #endif #endif FileServiceInstall(); // If we suppressed output at the beginning of SnortInit(), // then restore it now. ScRestoreInternalLogLevel(); } #if defined(INLINE_FAILOPEN) && !defined(WIN32) static void * SnortPostInitThread(void *data) { sigset_t mtmask; inline_failopen_thread_pid = gettid(); inline_failopen_thread_running = 1; /* Don't handle any signals here */ sigfillset(&mtmask); pthread_sigmask(SIG_BLOCK, &mtmask, NULL); while (!inline_failopen_initialized) nanosleep(&thread_sleep, NULL); SnortUnprivilegedInit(); pthread_exit((void *)NULL); } static DAQ_Verdict IgnoreCallback ( void *user, const DAQ_PktHdr_t* pkthdr, const uint8_t* pkt) { /* Empty function -- do nothing with the packet we just read */ inline_failopen_pass_pkt_cnt++; #ifdef DEBUG { FILE *tmp = fopen("/var/tmp/fo_threadid", "a"); if ( tmp ) { fprintf(tmp, "Packet Count %d\n", inline_failopen_pass_pkt_cnt); fclose(tmp); } } #endif return DAQ_VERDICT_PASS; } #endif /* defined(INLINE_FAILOPEN) && !defined(WIN32) */ // this function should only include initialization that must be done as a // non-root user such as creating log files. other initialization stuff should // be in the main initialization function since, depending on platform and // configuration, this may be running in a background thread while passing // packets in a fail open mode in the main thread. we don't want big delays // here to cause excess latency or dropped packets in that thread which may // be the case if all threads are pinned to a single cpu/core. // // clarification: once snort opens/starts the DAQ, packets are queued for snort // and must be disposed of quickly or the queue will overflow and packets will // be dropped so the fail open thread does the remaining initialization while // the main thread passes packets. prior to opening and starting the DAQ, // packet passing is done by the driver/hardware. the goal then is to put as // much initialization stuff in SnortInit() as possible and to restrict this // function to those things that depend on DAQ startup or non-root user/group. static void SnortUnprivilegedInit(void) { #ifdef ACTIVE_RESPONSE // this depends on instantiated daq capabilities // so it is done here instead of SnortInit() Active_Init(snort_conf); #endif InitPidChrootAndPrivs(snort_main_thread_pid); #if defined(HAVE_LINUXTHREADS) && !defined(WIN32) // this must be done after dropping privs for linux threads // to ensure that child threads can communicate with parent SnortStartThreads(); #endif // perfmon, for one, opens a log file for writing here PostConfigPreprocessors(snort_conf); // log_tcpdump opens a log file for writing here; also ... // note that things like opening log_tcpdump will fail here if the // user specified -u (we dropped privileges) and the log defaults // to /var/log/snort. in this case they must override log path. PostConfigInitPlugins(snort_conf, snort_conf->plugin_post_config_funcs); #ifdef SIDE_CHANNEL SideChannelPostInit(); #endif LogMessage("\n"); LogMessage(" --== Initialization Complete ==--\n"); /* Tell 'em who wrote it, and what "it" is */ PrintVersion(snort_conf); if (ScTestMode()) { LogMessage("\n"); LogMessage("Snort successfully validated the configuration!\n"); CleanExit(0); } LogMessage("Commencing packet processing (pid=%u)\n", snort_main_thread_pid); snort_initializing = false; } #if defined(NOCOREFILE) && !defined(WIN32) static void SetNoCores(void) { struct rlimit rlim; getrlimit(RLIMIT_CORE, &rlim); rlim.rlim_max = 0; setrlimit(RLIMIT_CORE, &rlim); } #endif /* Add a signal handler * * If check needed, also check whether previous signal_handler is neither SIG_IGN nor SIG_DFL * * Return: * 0: error * 1: success */ int SnortAddSignal(int sig, sighandler_t signal_handler, int check_needed) { sighandler_t pre_handler; #ifdef HAVE_SIGACTION struct sigaction action; struct sigaction old_action; sigemptyset(&action.sa_mask); action.sa_flags = 0; action.sa_handler = signal_handler; sigaction(sig, &action, &old_action); pre_handler = old_action.sa_handler; #else pre_handler = signal(sig, signal_handler); #endif if (SIG_ERR == pre_handler) { SnortSnprintfAppend(signal_error_msg, STD_BUF, "Could not add handler for signal %d \n", sig); return 0; } else if (check_needed && (SIG_IGN != pre_handler) && (SIG_DFL!= pre_handler)) { SnortSnprintfAppend(signal_error_msg, STD_BUF, "WARNING: Handler is already installed for signal %d.\n", sig); } return 1; } static void InitSignals(void) { #ifndef WIN32 # if defined(LINUX) || defined(FREEBSD) || defined(OPENBSD) || \ defined(SOLARIS) || defined(BSD) || defined(MACOS) sigset_t set; sigemptyset(&set); # if defined(INLINE_FAILOPEN) || \ defined(TARGET_BASED) || defined(SNORT_RELOAD) pthread_sigmask(SIG_SETMASK, &set, NULL); # else sigprocmask(SIG_SETMASK, &set, NULL); # endif /* INLINE_FAILOPEN */ # else sigsetmask(0); # endif /* LINUX, BSD, SOLARIS */ #endif /* !WIN32 */ /* Make this prog behave nicely when signals come along. * Windows doesn't like all of these signals, and will * set errno for some. Ignore/reset this error so it * doesn't interfere with later checks of errno value. */ signal_error_msg[0] = '\0'; SnortAddSignal(SIGTERM, SigExitHandler, 1); SnortAddSignal(SIGINT, SigExitHandler, 1); #ifndef WIN32 SnortAddSignal(SIGQUIT, SigExitHandler, 1); SnortAddSignal(SIGNAL_SNORT_DUMP_STATS, SigDumpStatsHandler, 1); SnortAddSignal(SIGNAL_SNORT_RELOAD, SigReloadHandler, 1); SnortAddSignal(SIGNAL_SNORT_ROTATE_STATS, SigRotateStatsHandler, 1); #endif #ifdef CONTROL_SOCKET SnortAddSignal(SIGPIPE, SigPipeHandler, 1); #endif #ifdef TARGET_BASED #ifndef WIN32 /* Used to print warning if attribute table is not configured * When it is, it will set new signal handler */ SnortAddSignal(SIGNAL_SNORT_READ_ATTR_TBL, SigNoAttributeTableHandler, 1); #endif #endif SnortAddSignal(SIGABRT, SigOopsHandler, 1); SnortAddSignal(SIGSEGV, SigOopsHandler, 1); #ifndef WIN32 SnortAddSignal(SIGBUS, SigOopsHandler, 1); #endif errno = 0; } static void FreeOutputConfigs(OutputConfig *head) { while (head != NULL) { OutputConfig *tmp = head; head = head->next; if (tmp->keyword != NULL) free(tmp->keyword); if (tmp->opts != NULL) free(tmp->opts); if (tmp->file_name != NULL) free(tmp->file_name); /* Don't free listhead as it's just a pointer to the user defined * rule's rule list node's list head */ free(tmp); } } #ifdef SIDE_CHANNEL static void FreeSideChannelModuleConfigs(SideChannelModuleConfig *head) { while (head != NULL) { SideChannelModuleConfig *tmp = head; head = head->next; if (tmp->keyword != NULL) free(tmp->keyword); if (tmp->opts != NULL) free(tmp->opts); if (tmp->file_name != NULL) free(tmp->file_name); free(tmp); } } #endif static void FreePreprocConfigs(SnortConfig *sc) { tSfPolicyId i; if (sc == NULL) return; for (i = 0; i < sc->num_policies_allocated; i++) { SnortPolicy *p = sc->targeted_policies[i]; PreprocConfig *head; if (p == NULL) continue; head = p->preproc_configs; while (head != NULL) { PreprocConfig *tmp = head; head = head->next; if (tmp->keyword != NULL) free(tmp->keyword); if (tmp->opts != NULL) free(tmp->opts); if (tmp->file_name != NULL) free(tmp->file_name); free(tmp); } } } static void FreeRuleStateList(RuleState *head) { while (head != NULL) { RuleState *tmp = head; head = head->next; free(tmp); } } static void FreeClassifications(ClassType *head) { while (head != NULL) { ClassType *tmp = head; head = head->next; if (tmp->name != NULL) free(tmp->name); if (tmp->type != NULL) free(tmp->type); free(tmp); } } static void FreeReferences(ReferenceSystemNode *head) { while (head != NULL) { ReferenceSystemNode *tmp = head; head = head->next; if (tmp->name != NULL) free(tmp->name); if (tmp->url != NULL) free(tmp->url); free(tmp); } } #if defined(DAQ_VERSION) && DAQ_VERSION > 9 void print_pktverdict (Packet *p,uint64_t verdict) { static const char* pktverdict[7] = { "ALLOW", "BLOCK", "REPLACE", "WHITELIST", "BLACKLSIT", "IGNORE", "RETRY" }; uint8_t log_level = (verdict == DAQ_VERDICT_BLOCK || verdict == DAQ_VERDICT_BLACKLIST)?DAQ_DEBUG_PKT_LEVEL_INFO:DAQ_DEBUG_PKT_LEVEL_DEBUG; DEBUG_SNORT_ENGINE(p,log_level,"Packet Verdict:%s\n",pktverdict[verdict]); } void print_flow(Packet *p,char *str,uint32_t id,uint64_t start,uint64_t end) { static const char* preproc[50] = { "PP_BO", "PP_APP_ID", "PP_DNS", "PP_FRAG", "PP_FTPTELNET", "PP_HTTPINSPECT", "PP_PERFMONITOR", "PP_RPCDECODE", "PP_SHARED_RULES", "PP_SFPORTSCAN", "PP_SMTP", "PP_SSH", "PP_SSL", "PP_STREAM", "PP_TELNET", "PP_ARPSPOOF", "PP_DCE", "PP_SDF", "PP_NORMALIZE", "PP_ISAKMP", "PP_SESSION", "PP_SIP", "PP_POP", "PP_IMAP", "PP_NETWORK_DISCOVERY", "PP_FW_RULE_ENGINE", "PP_REPUTATION", "PP_GTP", "PP_MODBUS", "PP_DNP ", "PP_FILE", "PP_FILE_INSPECT", "PP_NAP_RULE_ENGINE", "PP_REFILTER_RULE_ENGINE", "PP_HTTPMOD", "PP_HTTP ", "PP_CIP", "PP_MAX" }; const char* preproc_info = (str == NULL)?preproc[id]:str; uint64_t diff =0; if (ppm_tpu) { diff = (end-start)/ppm_tpu; } DEBUG_SNORT_ENGINE(p,DAQ_DEBUG_PKT_LEVEL_DEBUG,"%s processing time %u usec\n",preproc_info,diff); } #endif snort-2.9.15.1/src/snort.h0000644000175200017520000015202613571422607012163 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2005-2013 Sourcefire, Inc. ** Copyright (C) 1998-2005 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifndef __SNORT_H__ #define __SNORT_H__ /* I N C L U D E S **********************************************************/ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include "sf_types.h" #include "spo_plugbase.h" #include "decode.h" #include "perf.h" #include "sfdaq.h" #include "sf_types.h" #include "sfutil/sflsq.h" #include "sfutil/sfActionQueue.h" #include "profiler.h" #include "rules.h" #include "treenodes.h" #include "sfutil/sf_ipvar.h" #include "sfutil/sfghash.h" #include "sfutil/sfrim.h" #include "sfutil/sfportobject.h" #include "sfutil/asn1.h" #include "sfutil/sf_sechash.h" #include "signature.h" #include "event_queue.h" #include "sfthreshold.h" #include "fpcreate.h" #include "plugbase.h" #include "fpdetect.h" #include "ppm.h" #include "sfutil/sfrf.h" #include "sfutil/sfPolicy.h" #include "pkt_tracer.h" #include "detection_filter.h" #include "generators.h" #include "preprocids.h" #include #include "sf_dynamic_meta.h" #if defined(INLINE_FAILOPEN) || \ defined(TARGET_BASED) || defined(SNORT_RELOAD) # include #endif /* D E F I N E S ************************************************************/ /* Mark this as a modern version of snort */ #define SNORT_20 #define MIN_SNAPLEN 68 #define MAX_SNAPLEN UINT16_MAX #define MAX_IFS 1 #define TIMEBUF_SIZE 26 #define MAX_PIDFILE_SUFFIX 11 /* uniqueness extension to PID file, see '-R' */ #define ASSURE_ALL 0 /* all TCP alerts fire regardless of stream state */ #define ASSURE_EST 1 /* only established TCP sessions fire alerts */ /* This macro helps to simplify the differences between Win32 and non-Win32 code when printing out the name of the interface */ #ifndef WIN32 # define PRINT_INTERFACE(i) (i ? i : "NULL") #else # define PRINT_INTERFACE(i) print_interface(i) #endif #define RF_ANY_SIP 0x01 #define RF_ANY_DIP 0x02 #define RF_ANY_SP 0x04 #define RF_ANY_DP 0x10 #define RF_ANY_FLAGS 0x20 #ifndef WIN32 # define DEFAULT_LOG_DIR "/var/log/snort" # define DEFAULT_DAEMON_ALERT_FILE "alert" #else # define DEFAULT_LOG_DIR "log" # define DEFAULT_DAEMON_ALERT_FILE "log/alert.ids" #endif /* WIN32 */ /* you can redefine the user ID which is allowed to * initialize interfaces using pcap and read from them */ #ifndef SNIFFUSER # define SNIFFUSER 0 #endif #ifdef ACCESSPERMS # define FILEACCESSBITS ACCESSPERMS #else # ifdef S_IAMB # define FILEACCESSBITS S_IAMB # else # define FILEACCESSBITS 0x1FF # endif #endif #define DO_IP_CHECKSUMS 0x00000001 #define DO_TCP_CHECKSUMS 0x00000002 #define DO_UDP_CHECKSUMS 0x00000004 #define DO_ICMP_CHECKSUMS 0x00000008 #define LOG_UNIFIED 0x00000001 #define LOG_TCPDUMP 0x00000002 #define LOG_UNIFIED2 0x0000004 #ifndef SIGNAL_SNORT_RELOAD #define SIGNAL_SNORT_RELOAD SIGHUP #endif #ifndef SIGNAL_SNORT_DUMP_STATS #define SIGNAL_SNORT_DUMP_STATS SIGUSR1 #endif #ifndef SIGNAL_SNORT_ROTATE_STATS #define SIGNAL_SNORT_ROTATE_STATS SIGUSR2 #endif // this one should not be changed by user #define SIGNAL_SNORT_CHILD_READY SIGCHLD #ifdef TARGET_BASED #ifndef SIGNAL_SNORT_READ_ATTR_TBL # define SIGNAL_SNORT_READ_ATTR_TBL SIGURG #endif #endif #define MODE_PACKET_DUMP 1 #define MODE_PACKET_LOG 2 #define MODE_IDS 3 #define MODE_TEST 4 #define MODE_RULE_DUMP 5 #define MODE_VERSION 6 #define LOG_ASCII 1 #define LOG_PCAP 2 #define LOG_NONE 3 #define ALERT_FULL 1 #define ALERT_FAST 2 #define ALERT_NONE 3 #define ALERT_UNSOCK 4 #define ALERT_STDOUT 5 #define ALERT_CMG 6 #define ALERT_SYSLOG 8 #define ALERT_TEST 9 #define ALERT_UNIFIED 10 #ifdef MPLS # define MPLS_PAYLOADTYPE_IPV4 1 # define MPLS_PAYLOADTYPE_ETHERNET 2 # define MPLS_PAYLOADTYPE_IPV6 3 # define MPLS_PAYLOADTYPE_ERROR -1 # define DEFAULT_MPLS_PAYLOADTYPE MPLS_PAYLOADTYPE_IPV4 # define DEFAULT_LABELCHAIN_LENGTH -1 #endif /* This feature allows us to change the state of a rule, * independent of it appearing in a rules file. */ #define RULE_STATE_DISABLED 0 #define RULE_STATE_ENABLED 1 #define MAX_DYNAMIC_ENGINES 16 #define MAX_DYNAMIC_DETECTION_LIBS 16 #define MAX_DYNAMIC_PREPROC_LIBS 16 #ifdef TARGET_BASED # define ATTRIBUTE_TABLE_RELOAD_FLAG 0x01 # define ATTRIBUTE_TABLE_AVAILABLE_FLAG 0x02 # define ATTRIBUTE_TABLE_RELOADING_FLAG 0x04 # define ATTRIBUTE_TABLE_TAKEN_FLAG 0x08 # define ATTRIBUTE_TABLE_PARSE_FAILED_FLAG 0x10 # define DEFAULT_MAX_ATTRIBUTE_HOSTS 10000 # define DEFAULT_MAX_ATTRIBUTE_SERVICES_PER_HOST 100 # define DEFAULT_MAX_METADATA_SERVICES 8 # define MAX_MAX_ATTRIBUTE_HOSTS (512 * 1024) # define MIN_MAX_ATTRIBUTE_HOSTS 32 # define MAX_MAX_ATTRIBUTE_SERVICES_PER_HOST 65535 # define MIN_MAX_ATTRIBUTE_SERVICES_PER_HOST 1 # define MAX_MAX_METADATA_SERVICES 256 # define MIN_MAX_METADATA_SERVICES 1 #if defined(FEAT_OPEN_APPID) # define MAX_MAX_METADATA_APPID 256 # define MIN_MAX_METADATA_APPID 1 # define DEFAULT_MAX_METADATA_APPID 8 #endif /* defined(FEAT_OPEN_APPID) */ #endif # define DEFAULT_MAX_IP6_EXTENSIONS 8 struct _SnortConfig; typedef int (*InitDetectionLibFunc)(struct _SnortConfig *); /* D A T A S T R U C T U R E S *********************************************/ typedef struct _VarEntry { char *name; char *value; unsigned char flags; IpAddrSet *addrset; uint32_t id; struct _VarEntry *prev; struct _VarEntry *next; } VarEntry; /* GetoptLong Option numbers ********************/ typedef enum _GetOptLongIds { PID_PATH = 1, DYNAMIC_LIBRARY_DIRECTORY, DYNAMIC_LIBRARY_FILE, DYNAMIC_PREPROC_DIRECTORY, DYNAMIC_PREPROC_FILE, DYNAMIC_ENGINE_FILE, DYNAMIC_ENGINE_DIRECTORY, DUMP_DYNAMIC_RULES, DYNAMIC_OUTPUT_DIRECTORY, DYNAMIC_OUTPUT_FILE, CREATE_PID_FILE, TREAT_DROP_AS_ALERT, TREAT_DROP_AS_IGNORE, PROCESS_ALL_EVENTS, ALERT_BEFORE_PASS, NOLOCK_PID_FILE, NO_IFACE_PID_FILE, #ifdef INLINE_FAILOPEN DISABLE_INLINE_FAILOPEN, #endif NO_LOGGING_TIMESTAMPS, PCAP_LOOP, PCAP_SINGLE, PCAP_FILE_LIST, PCAP_LIST, PCAP_DIR, PCAP_FILTER, PCAP_NO_FILTER, PCAP_RELOAD, PCAP_RESET, PCAP_SHOW, #define EXIT_CHECK // allow for rollback for now #ifdef EXIT_CHECK ARG_EXIT_CHECK, #endif #ifdef TARGET_BASED DISABLE_ATTRIBUTE_RELOAD, #endif DETECTION_SEARCH_METHOD, CONF_ERROR_OUT, #ifdef MPLS ENABLE_MPLS_MULTICAST, ENABLE_OVERLAPPING_IP, MAX_MPLS_LABELCHAIN_LEN, MPLS_PAYLOAD_TYPE, #endif REQUIRE_RULE_SID, ARG_DAQ_TYPE, ARG_DAQ_MODE, ARG_DAQ_VAR, ARG_DAQ_DIR, ARG_DAQ_LIST, ARG_DIRTY_PIG, ENABLE_INLINE_TEST, ARG_CS_DIR, ARG_HA_PEER, ARG_HA_OUT, ARG_HA_IN, ARG_HA_PDTS_IN, SUPPRESS_CONFIG_LOG, #ifdef DUMP_BUFFER BUFFER_DUMP, BUFFER_DUMP_ALERT, #endif GET_OPT_LONG_IDS_MAX } GetOptLongIds; typedef struct _PreprocConfig { char *keyword; char *opts; char *file_name; int file_line; /* We have to configure internal and dynamic preprocessors separately, * mainly because of the stream_api which is set in stream5 and needs to * be set before calling the dynamic preprocessor initialization * functions which set _dpd and call the setup function. streamAPI is set * in the _dpd so stream5 needs to be configured first */ int configured; struct _PreprocConfig *next; } PreprocConfig; typedef struct _OutputConfig { char *keyword; char *opts; char *file_name; int file_line; ListHead *rule_list; struct _OutputConfig *next; } OutputConfig; #ifdef SIDE_CHANNEL typedef struct _SideChannelModuleConfig { char *keyword; char *opts; char *file_name; int file_line; struct _SideChannelModuleConfig *next; } SideChannelModuleConfig; typedef struct _SideChannelConfig { bool enabled; char *opts; SideChannelModuleConfig *module_configs; } SideChannelConfig; #endif typedef enum _DynamicType { DYNAMIC_TYPE__ENGINE, DYNAMIC_TYPE__DETECTION, DYNAMIC_TYPE__PREPROCESSOR, DYNAMIC_TYPE__SIDE_CHANNEL, DYNAMIC_TYPE__MAX } DynamicType; typedef enum _PathType { PATH_TYPE__FILE, PATH_TYPE__DIRECTORY } PathType; typedef struct _DynamicLibPath { PathType ptype; char *path; time_t last_mod_time; } DynamicLibPath; #define MAX_DYNAMIC_LIBS 16 typedef struct _DynamicLibInfo { DynamicType type; unsigned int count; DynamicLibPath *lib_paths[MAX_DYNAMIC_LIBS]; } DynamicLibInfo; typedef enum _RunMode { /* -V */ RUN_MODE__VERSION = 1, /* --dump-dynamic-rules */ RUN_MODE__RULE_DUMP, /* neither of the above and snort.conf presence (-c or implicit) */ RUN_MODE__IDS, /* snort.conf presence and -T */ RUN_MODE__TEST, /* neither -V or --dump-dynamic-rules and no snort.conf, but logging * enabled on command line - NONE type logging seems to count here */ RUN_MODE__PACKET_LOG, RUN_MODE__PACKET_DUMP } RunMode; typedef enum _RunModeFlag { /* -V */ RUN_MODE_FLAG__VERSION = 0x00000001, /* --dump-dynamic-rules */ RUN_MODE_FLAG__RULE_DUMP = 0x00000002, /* neither of the above and snort.conf presence (-c or implicit) */ RUN_MODE_FLAG__IDS = 0x00000004, /* snort.conf presence and -T */ RUN_MODE_FLAG__TEST = 0x00000008, /* neither -V or --dump-dynamic-rules and no snort.conf, but logging * enabled on command line - NONE type logging seems to count here */ RUN_MODE_FLAG__PACKET_LOG = 0x00000010, RUN_MODE_FLAG__PACKET_DUMP = 0x00000020 } RunModeFlag; typedef enum _RunFlag { RUN_FLAG__READ = 0x00000001, /* -r --pcap-dir, etc. */ RUN_FLAG__DAEMON = 0x00000002, /* -D */ RUN_FLAG__DAEMON_RESTART = 0x00000004, /* --restart */ RUN_FLAG__NO_PROMISCUOUS = 0x00000008, /* -p */ RUN_FLAG__INLINE = 0x00000010, /* -Q */ RUN_FLAG__STATIC_HASH = 0x00000020, /* -H */ RUN_FLAG__CREATE_PID_FILE = 0x00000040, /* --pid-path and --create-pidfile */ RUN_FLAG__NO_LOCK_PID_FILE = 0x00000080, /* --nolock-pidfile */ RUN_FLAG__TREAT_DROP_AS_ALERT = 0x00000100, /* --treat-drop-as-alert */ RUN_FLAG__ALERT_BEFORE_PASS = 0x00000200, /* --alert-before-pass */ RUN_FLAG__CONF_ERROR_OUT = 0x00000400, /* -x and --conf-error-out */ #ifdef MPLS RUN_FLAG__MPLS_MULTICAST = 0x00000800, /* --enable_mpls_multicast */ RUN_FLAG__MPLS_OVERLAPPING_IP = 0x00001000, /* --enable_mpls_overlapping_ip */ #endif /* --process-all-events * this is transferred to the snort event queue var */ RUN_FLAG__PROCESS_ALL_EVENTS = 0x00002000, #ifdef TARGET_BASED /* --disable-attribute-reload-thread */ RUN_FLAG__DISABLE_ATTRIBUTE_RELOAD_THREAD = 0x00004000, #endif RUN_FLAG__STATEFUL = 0x00008000, /* set if stream5 configured */ RUN_FLAG__INLINE_TEST = 0x00010000, /* --enable-inline-test*/ // UNUSED = 0x00020000, #ifdef INLINE_FAILOPEN RUN_FLAG__DISABLE_FAILOPEN = 0x00040000, /* --disable-inline-init-failopen */ #endif #ifdef MIMICK_IPV6 RUN_FLAG__MIMICK_IP6 = 0x00100000, /* -6 */ #endif RUN_FLAG__PCAP_RESET = 0x00200000, RUN_FLAG__PCAP_SHOW = 0x00400000, RUN_FLAG__REQUIRE_RULE_SID = 0x00800000, RUN_FLAG__NO_PCRE = 0x01000000, RUN_FLAG__ASSURE_EST = 0x02000000 /* config stateful */ #if defined(WIN32) && defined(ENABLE_WIN32_SERVICE) ,RUN_FLAG__TERMINATE_SERVICE = 0x04000000, RUN_FLAG__PAUSE_SERVICE = 0x08000000 #endif ,RUN_FLAG__TREAT_DROP_AS_IGNORE= 0x10000000, /* --treat-drop-as-ignore */ #if defined(SNORT_RELOAD) && !defined(WIN32) RUN_FLAG__PCAP_RELOAD = 0x20000000, /* --pcap-reload */ #endif RUN_FLAG__NO_IFACE_PID_FILE = 0x40000000 /* --no-interface-pidfile */ } RunFlag; typedef enum _OutputFlag { OUTPUT_FLAG__LINE_BUFFER = 0x00000001, /* -f */ OUTPUT_FLAG__VERBOSE_DUMP = 0x00000002, /* -X */ OUTPUT_FLAG__CHAR_DATA = 0x00000004, /* -C */ OUTPUT_FLAG__APP_DATA = 0x00000008, /* -d */ OUTPUT_FLAG__SHOW_DATA_LINK = 0x00000010, /* -e */ #ifndef NO_NON_ETHER_DECODER OUTPUT_FLAG__SHOW_WIFI_MGMT = 0x00000020, /* -w */ #endif OUTPUT_FLAG__USE_UTC = 0x00000040, /* -U */ OUTPUT_FLAG__INCLUDE_YEAR = 0x00000080, /* -y */ /* Note using this alters the packet - can't be used inline */ OUTPUT_FLAG__OBFUSCATE = 0x00000100, /* -B */ OUTPUT_FLAG__ALERT_IFACE = 0x00000200, /* -I */ OUTPUT_FLAG__NO_TIMESTAMP = 0x00000400, /* --nostamps */ OUTPUT_FLAG__ALERT_PKT_CNT = 0x00000800, /* -A packet-count */ /* XXX XXX pv.outputVidInAlerts */ OUTPUT_FLAG__ALERT_VLAN = 0x00001000 /* config include_vlan_in_alerts */ } OutputFlag; typedef enum _LoggingFlag { LOGGING_FLAG__VERBOSE = 0x00000001, /* -v */ LOGGING_FLAG__QUIET = 0x00000002, /* -q */ LOGGING_FLAG__SYSLOG = 0x00000004 /* -M */ #ifdef WIN32 ,LOGGING_FLAG__SYSLOG_REMOTE = 0x00000008 /* -s and -E */ #endif } LoggingFlag; typedef enum _InternalLogLevel { INTERNAL_LOG_LEVEL__SUPPRESS_ALL, INTERNAL_LOG_LEVEL__ERROR, INTERNAL_LOG_LEVEL__WARNING, INTERNAL_LOG_LEVEL__MESSAGE } InternalLogLevel; /* -k * config checksum_mode * config checksum_drop_mode */ typedef enum _ChecksumFlag { CHECKSUM_FLAG__IP = 0x00000001, CHECKSUM_FLAG__TCP = 0x00000002, CHECKSUM_FLAG__UDP = 0x00000004, CHECKSUM_FLAG__ICMP = 0x00000008, CHECKSUM_FLAG__ALL = 0x7fffffff } ChecksumFlag; typedef enum { /* config autogenerate_preprocessor_decoder_rules */ POLICY_FLAG__AUTO_OTN = 0x00000001 } PolicyFlag; typedef enum _PolicyModeFlag { POLICY_MODE__PASSIVE, POLICY_MODE__INLINE, POLICY_MODE__INLINE_TEST } PolicyMode; typedef enum _DecodeEventFlag { DECODE_EVENT_FLAG__DEFAULT = 0x00000001, DECODE_EVENT_FLAG__OVERSIZED = 0x00000002, DECODE_EVENT_FLAG__TCP_EXP_OPT = 0x00000004, DECODE_EVENT_FLAG__TCP_OBS_OPT = 0x00000008, DECODE_EVENT_FLAG__TCP_TTCP_OPT = 0x00000010, DECODE_EVENT_FLAG__TCP_OPT_ANOMALY = 0x00000020, DECODE_EVENT_FLAG__IP_OPT_ANOMALY = 0x00000040, DECODE_EVENT_FLAG__IPV6_BAD_FRAG = 0x00000080, DECODE_EVENT_FLAG__IPV6_BSD_ICMP_FRAG = 0x00000100 } DecodeEventFlag; typedef enum { TUNNEL_GTP = 0x01, TUNNEL_TEREDO = 0x02, TUNNEL_6IN4 = 0x04, TUNNEL_4IN6 = 0x08, TUNNEL_4IN4 = 0x10, TUNNEL_6IN6 = 0x20, TUNNEL_GRE = 0x40, TUNNEL_MPLS = 0x80 } TunnelFlags; typedef struct _VarNode { char *name; char *value; char *line; struct _VarNode *next; } VarNode; #ifdef TARGET_BASED typedef struct _TargetBasedConfig { char *args; char *file_name; int file_line; } TargetBasedConfig; #endif typedef struct _SnortPolicy { #ifdef TARGET_BASED TargetBasedConfig target_based_config; #endif PreprocConfig *preproc_configs; VarEntry *var_table; uint32_t var_id; vartable_t *ip_vartable; /* The portobjects in these are attached to rtns and used during runtime */ PortVarTable *portVarTable; /* named entries, uses a hash table */ PortTable *nonamePortVarTable; /* un-named entries */ PreprocEnableMask pp_enabled[MAX_PORTS]; PreprocEvalFuncNode *preproc_eval_funcs; PreprocEvalFuncNode *unused_preproc_eval_funcs; PreprocMetaEvalFuncNode *preproc_meta_eval_funcs; int preproc_proto_mask; int num_preprocs; int num_meta_preprocs; int ips_policy_mode; int nap_policy_mode; uint32_t policy_flags; /* mask of preprocessors that have registered runtime process functions */ PreprocEnableMask preproc_bit_mask; PreprocEnableMask preproc_meta_bit_mask; int num_detects; //int detect_bit_mask; int detect_proto_mask; DetectionEvalFuncNode *detect_eval_funcs; /** Identifier assigned by user to correlate unified2 events to actual * policy. User or DC should assign each policy a unique number. Snort * will not verify uniqueness. */ unsigned short configPolicyId; char *policy_version; uint8_t min_ttl; /* config min_ttl */ #ifdef NORMALIZER uint8_t new_ttl; /* config new_ttl */ #endif //checksum_mode and checksum_drop are now policy specific int checksum_flags; /* -k */ int checksum_flags_modified; int checksum_flags_saved; int checksum_drop_flags; int checksum_drop_flags_modified; //disable_decode_alerts and disable_decode_drop int decoder_alert_flags; int decoder_drop_flags; int decoder_alert_flags_saved; int decoder_drop_flags_saved; bool ssl_policy_enabled; } SnortPolicy; typedef struct _DynamicDetectionPlugin { void *handle; DynamicPluginMeta metaData; InitDetectionLibFunc initFunc; struct _DynamicDetectionPlugin *next; struct _DynamicDetectionPlugin *prev; } DynamicDetectionPlugin; #ifdef INTEL_SOFT_CPM struct _IntelPmHandles; #endif struct _MandatoryEarlySessionCreator; #ifdef SNORT_RELOAD struct _ReloadAdjustEntry; #endif struct _fileConfig; struct _DynamicRuleNode; typedef struct _SnortConfig { RunMode run_mode; int run_mode_flags; int run_flags; int output_flags; int logging_flags; int log_tcpdump; int no_log; int no_alert; int dirty_pig; //used for processing command line arguments, checksum configuration //in conf files is maintained at policy level int checksum_flags; /* -k */ int checksum_flags_modified; int checksum_drop_flags; int checksum_drop_flags_modified; uint32_t event_log_id; /* -G */ int pkt_snaplen; uint64_t pkt_cnt; /* -n */ #ifdef REG_TEST uint64_t pkt_skip; #endif char *dynamic_rules_path; /* --dump-dynamic-rules */ /* --dynamic-engine-lib * --dynamic-engine-lib-dir * --dynamic-detection-lib * --dynamic-detection-lib-dir * --dynamic-preprocessor-lib * --dynamic-preprocessor-lib-dir * * See below for struct type */ DynamicLibInfo *dyn_engines; DynamicLibInfo *dyn_rules; DynamicLibInfo *dyn_preprocs; #ifdef SIDE_CHANNEL DynamicLibInfo *dyn_side_channels; #endif char pid_path[STD_BUF]; /* --pid-path or config pidpath */ #ifdef EXIT_CHECK uint64_t exit_check; /* --exit-check */ #endif /* -h and -B */ sfcidr_t homenet; sfcidr_t obfuscation_net; /* config disable_decode_alerts * config enable_decode_oversized_alerts * config enable_decode_oversized_drops * config enable_decode_drops * config disable_decode_drops * config disable_tcpopt_experimental_alerts * config enable_tcpopt_experimental_drops * config disable_tcpopt_experimental_drops * config disable_tcpopt_obsolete_alerts * config enable_tcpopt_obsolete_drops * config disable_tcpopt_obsolete_drops * config disable_ttcp_alerts, config disable_tcpopt_ttcp_alerts * config enable_ttcp_drops, config enable_tcpopt_ttcp_drops * config disable_ttcp_drops * config disable_tcpopt_alerts * config enable_tcpopt_drops * config disable_tcpopt_drops * config disable_ipopt_alerts * config enable_ipopt_drops * config disable_ipopt_drops * config ipv6_frag: * bsd_icmp_frag_alert * bad_ipv6_frag_alert * frag_timeout - not in DecoderFlags * max_frag_sessions - not in DecoderFlags * drop_bad_ipv6_frag */ uint32_t ipv6_frag_timeout; uint32_t ipv6_max_frag_sessions; uint16_t flowbit_size; char pid_filename[STD_BUF]; /* used with pid_path */ char pidfile_suffix[MAX_PIDFILE_SUFFIX + 1]; /* -R */ char *log_dir; /* -l or config log_dir */ char *orig_log_dir; /* set in case of chroot */ char *interface; /* -i or config interface */ char *bpf_file; /* -F or config bpf_file */ char *pcap_log_file; /* -L */ char *chroot_dir; /* -t or config chroot */ char *alert_file; char *perf_file; /* -Z */ char *bpf_filter; /* last command line arguments */ char* daq_type; /* --daq or config daq */ char* daq_mode; /* --daq-mode or config daq_mode */ void* daq_vars; /* --daq-var or config daq_var */ void* daq_dirs; /* --daq-dir or config daq_dir */ char* event_trace_file; uint16_t event_trace_max; int thiszone; #ifdef WIN32 char syslog_server[STD_BUF]; int syslog_server_port; # ifdef ENABLE_WIN32_SERVICE int terminate_service_flag; int pause_service_flag; # endif #endif uint8_t ignore_ports[UINT16_MAX]; /* config ignore_ports */ long int tagged_packet_limit; /* config tagged_packet_limit */ long int pcre_match_limit; /* config pcre_match_limit */ long int pcre_match_limit_recursion; /* config pcre_match_limit_recursion */ int *pcre_ovector; int pcre_ovector_size; #ifdef PERF_PROFILING ProfileConfig profile_rules; /* config profile_rules */ ProfileConfig profile_preprocs; /* config profile_preprocs */ #endif int user_id; int group_id; mode_t file_mask; #ifdef MPLS uint8_t mpls_payload_type; /* --mpls_payload_type */ long int mpls_stack_depth; /* --max_mpls_labelchain_len */ #endif int default_rule_state; /* config default_rule_state */ char* react_page; /* config react */ #ifdef ACTIVE_RESPONSE uint8_t respond_attempts; /* config respond */ char* respond_device; uint8_t *eth_dst; /* config destination MAC address */ #endif #ifdef TARGET_BASED uint32_t max_attribute_hosts; /* config max_attribute_hosts */ uint32_t max_attribute_services_per_host; /* config max_attribute_services_per_host */ uint32_t max_metadata_services; /* config max_metadata_services */ #endif #if defined(FEAT_OPEN_APPID) uint32_t max_metadata_appid; #endif /* defined(FEAT_OPEN_APPID) */ OutputConfig *output_configs; OutputConfig *rule_type_output_configs; SFGHASH *config_table; /* table of config keywords and arguments */ int asn1_mem; int active_dynamic_nodes; RuleState *rule_state_list; ClassType *classifications; ReferenceSystemNode *references; SFGHASH *so_rule_otn_map; SFGHASH *otn_map; SFGHASH *preproc_rule_options; FastPatternConfig *fast_pattern_config; EventQueueConfig *event_queue_config; PreprocPostConfigFuncNode *preproc_post_config_funcs; PreprocCheckConfigFuncNode *preproc_config_check_funcs; /* XXX XXX policy specific? */ ThresholdConfig *threshold_config; RateFilterConfig *rate_filter_config; DetectionFilterConfig *detection_filter_config; SF_EVENTQ *event_queue[NUM_EVENT_QUEUES]; SF_LIST **ip_proto_only_lists; uint8_t ip_proto_array[NUM_IP_PROTOS]; int num_rule_types; RuleListNode *rule_lists; int evalOrder[RULE_TYPE__MAX + 1]; ListHead Alert; /* Alert Block Header */ ListHead Log; /* Log Block Header */ ListHead Pass; /* Pass Block Header */ ListHead Activation; /* Activation Block Header */ ListHead Dynamic; /* Dynamic Block Header */ ListHead Drop; ListHead SDrop; ListHead Reject; PostConfigFuncNode *plugin_post_config_funcs; OTNX_MATCH_DATA *omd; /* Pattern matcher queue statistics */ unsigned int max_inq; uint64_t tot_inq_flush; uint64_t tot_inq_inserts; uint64_t tot_inq_uinserts; /* Protected Content secure hash type default */ Secure_Hash_Type Default_Protected_Content_Hash_Type; /* master port list table */ rule_port_tables_t *port_tables; #ifdef PPM_MGR ppm_cfg_t ppm_cfg; #endif /* The port-rule-maps map the src-dst ports to rules for * udp and tcp, for Ip we map the dst port as the protocol, * and for Icmp we map the dst port to the Icmp type. This * allows us to use the decode packet information to in O(1) * select a group of rules to apply to the packet. These * rules may have uricontent, content, or they may be no content * rules, or any combination. We process the uricontent 1st, * then the content, and then the no content rules for udp/tcp * and icmp, than we process the ip rules. */ PORT_RULE_MAP *prmIpRTNX; PORT_RULE_MAP *prmTcpRTNX; PORT_RULE_MAP *prmUdpRTNX; PORT_RULE_MAP *prmIcmpRTNX; #ifdef TARGET_BASED srmm_table_t *srmmTable; /* srvc rule map master table */ srmm_table_t *spgmmTable; /* srvc port_group map master table */ sopg_table_t *sopgTable; /* service-oridnal to port_group table */ #endif SFXHASH *detection_option_hash_table; SFXHASH *detection_option_tree_hash_table; SFXHASH *rtn_hash_table; tSfPolicyConfig *policy_config; SnortPolicy **targeted_policies; unsigned int num_policies_allocated; char *base_version; uint8_t enable_teredo; /* config enable_deep_teredo_inspection */ uint8_t enable_gtp; /* config enable_gtp */ char *gtp_ports; uint8_t enable_esp; uint8_t vlan_agnostic; /* config vlan_agnostic */ uint8_t addressspace_agnostic; /* config addressspace_agnostic */ uint8_t log_ipv6_extra; /* config log_ipv6_extra_data */ uint8_t tunnel_mask; uint32_t so_rule_memcap; uint32_t paf_max; /* config paf_max */ char *cs_dir; bool ha_peer; char *ha_out; char *ha_in; char *ha_pdts_in; char *output_dir; struct _fileConfig *file_config; int disable_all_policies; PreprocEnableMask reenabled_preprocessor_bits; /* flags for preprocessors to check, if all policies are disabled */ #ifdef SIDE_CHANNEL SideChannelConfig side_channel_config; #endif #ifdef SNORT_RELOAD int reloadPolicyFlag; PreprocessorSwapData *preprocSwapData; void *streamReloadConfig; #endif tSfPolicyId parserPolicyId; #ifdef INTEL_SOFT_CPM struct _IntelPmHandles *ipm_handles; #endif /* Used when a user defines a new rule type (ruletype keyword) * It points to the new rule type's ListHead and is used for accessing the * rule type's AlertList and LogList. * The output plugins used for the rule type need to be attached to the new * rule type's list head's AlertList or LogList. It's set before calling * the output plugin's initialization routine, because in that routine, * AddFuncToOutputList is called (plugbase.c) and there, the output function * is attached to the new rule type's appropriate list. * NOTE: This variable MUST NOT be used during runtime */ ListHead *head_tmp; uint8_t max_ip6_extensions; int internal_log_level; int suppress_config_log; uint8_t disable_replace_opt; struct _MandatoryEarlySessionCreator* mandatoryESCreators; bool normalizer_set; #ifdef DUMP_BUFFER char *buffer_dump_file; #endif #ifdef SNORT_RELOAD struct _ReloadAdjustEntry* raSessionEntry; struct _ReloadAdjustEntry* volatile raEntry; struct _ReloadAdjustEntry* raCurrentEntry; time_t raLastLog; #endif DynamicDetectionPlugin *loadedDetectionPlugins; struct _DynamicRuleNode *dynamic_rules; } SnortConfig; /* struct to collect packet statistics */ typedef struct _PacketCount { uint64_t total_from_daq; uint64_t total_processed; uint64_t s5tcp1; uint64_t s5tcp2; uint64_t ipv6opts; uint64_t eth; uint64_t ethdisc; uint64_t ipv6disc; uint64_t ip6ext; uint64_t other; uint64_t tcp; uint64_t udp; uint64_t icmp; uint64_t arp; #ifndef NO_NON_ETHER_DECODER uint64_t eapol; #endif uint64_t vlan; uint64_t nested_vlan; uint64_t ipv6; uint64_t ipv6_up; uint64_t ipv6_upfail; uint64_t frag6; uint64_t icmp6; uint64_t tdisc; uint64_t udisc; uint64_t tcp6; uint64_t udp6; uint64_t teredo; uint64_t ipdisc; uint64_t icmpdisc; uint64_t embdip; uint64_t ip; uint64_t ipx; uint64_t ethloopback; uint64_t invalid_checksums; uint64_t bad_ttl; #ifdef GRE uint64_t ip4ip4; uint64_t ip4ip6; uint64_t ip6ip4; uint64_t ip6ip6; uint64_t gre; uint64_t gre_ip; uint64_t gre_eth; uint64_t gre_arp; uint64_t gre_ipv6; uint64_t gre_ipv6ext; uint64_t gre_ipx; uint64_t gre_loopback; uint64_t gre_vlan; uint64_t gre_ppp; #endif uint64_t discards; uint64_t alert_pkts; uint64_t total_alert_pkts; uint64_t log_pkts; uint64_t pass_pkts; uint64_t match_limit; uint64_t queue_limit; uint64_t log_limit; uint64_t event_limit; uint64_t alert_limit; uint64_t frags; /* number of frags that have come in */ uint64_t frag_trackers; /* number of tracking structures generated */ uint64_t rebuilt_frags; /* number of packets rebuilt */ uint64_t frag_incomp; /* number of frags cleared due to memory issues */ uint64_t frag_timeout; /* number of frags cleared due to timeout */ uint64_t rebuild_element; /* frags that were element of rebuilt pkt */ uint64_t frag_mem_faults; /* number of times the memory cap was hit */ uint64_t tcp_stream_pkts; /* number of packets tcp reassembly touches */ uint64_t rebuilt_tcp; /* number of phoney tcp packets generated */ uint64_t tcp_streams; /* number of tcp streams created */ uint64_t rebuilt_segs; /* number of tcp segments used in rebuilt pkts */ uint64_t queued_segs; /* number of tcp segments stored for rebuilt pkts */ uint64_t str_mem_faults; /* number of times the stream memory cap was hit */ #ifdef TARGET_BASED uint64_t attribute_table_reloads; /* number of times attribute table was reloaded. */ #endif #ifndef NO_NON_ETHER_DECODER #ifdef DLT_IEEE802_11 /* wireless statistics */ uint64_t wifi_mgmt; uint64_t wifi_data; uint64_t wifi_control; uint64_t assoc_req; uint64_t assoc_resp; uint64_t reassoc_req; uint64_t reassoc_resp; uint64_t probe_req; uint64_t probe_resp; uint64_t beacon; uint64_t atim; uint64_t dissassoc; uint64_t auth; uint64_t deauth; uint64_t ps_poll; uint64_t rts; uint64_t cts; uint64_t ack; uint64_t cf_end; uint64_t cf_end_cf_ack; uint64_t data; uint64_t data_cf_ack; uint64_t data_cf_poll; uint64_t data_cf_ack_cf_poll; uint64_t cf_ack; uint64_t cf_poll; uint64_t cf_ack_cf_poll; #endif #endif // NO_NON_ETHER_DECODER #ifdef MPLS uint64_t mpls; #endif uint64_t internal_blacklist; uint64_t internal_whitelist; uint64_t syn_rate_limit_events; uint64_t syn_rate_limit_drops; } PacketCount; typedef struct _PcapReadObject { int type; char *arg; char *filter; } PcapReadObject; #if defined(DAQ_CAPA_CST_TIMEOUT) bool Daq_Capa_Timeout; #endif #if defined(DAQ_CAPA_VRF) bool Daq_Capa_Vrf; #endif /* ptr to the packet processor */ typedef void (*grinder_t)(Packet *, const DAQ_PktHdr_t*, const uint8_t *); /* E X T E R N S ************************************************************/ extern const struct timespec thread_sleep; extern volatile bool snort_initializing; extern volatile int snort_exiting; #ifdef SNORT_RELOAD typedef uint32_t snort_reload_t; extern volatile snort_reload_t reload_signal; extern volatile int detection_lib_changed; extern snort_reload_t reload_total; #endif #if defined(SNORT_RELOAD) && !defined(WIN32) extern volatile int snort_reload_thread_created; extern pid_t snort_reload_thread_pid; #endif extern SnortConfig *snort_conf; extern SnortConfig *snort_cmd_line_conf; extern int internal_log_level; #include "sfutil/sfPolicyData.h" /* Specifically for logging the IPv6 fragmented ICMP BSD vulnerability */ extern Packet *BsdPseudoPacket; extern PacketCount pc; /* packet count information */ extern char **protocol_names; extern grinder_t grinder; #ifdef SIDE_CHANNEL extern pthread_mutex_t snort_process_lock; #endif extern pthread_mutex_t dynamic_rules_lock; extern OutputFuncNode *AlertList; extern OutputFuncNode *LogList; extern tSfActionQueueId decoderActionQ; #if defined(SNORT_RELOAD) && !defined(WIN32) extern volatile int snort_reload; #endif #ifdef SNORT_RELOAD extern PostConfigFuncNode *plugin_reload_funcs; #endif extern PeriodicCheckFuncNode *periodic_check_funcs; #if defined(DAQ_VERSION) && DAQ_VERSION > 9 void print_pktverdict (Packet *, uint64_t ); void print_flow(Packet *, char *, uint32_t, uint64_t, uint64_t ); #endif /* P R O T O T Y P E S ******************************************************/ int SnortMain(int argc, char *argv[]); DAQ_Verdict ProcessPacket(Packet*, const DAQ_PktHdr_t*, const uint8_t*, void*); Packet *NewGrinderPkt(Packet *p, DAQ_PktHdr_t* phdr, uint8_t *pkt); void DeleteGrinderPkt(Packet *); void SetupMetadataCallback(void); int InMainThread(void); bool SnortIsInitializing(void); void SigCantHupHandler(int signal); void print_packet_count(void); int SignalCheck(void); void Restart(void); void FreeVarList(VarNode *); SnortConfig * SnortConfNew(void); void SnortConfFree(SnortConfig *); void CleanupPreprocessors(SnortConfig *); void CleanupPlugins(SnortConfig *); void CleanExit(int); SnortConfig * MergeSnortConfs(SnortConfig *, SnortConfig *); typedef void (*sighandler_t)(int); int SnortAddSignal(int sig, sighandler_t handler, int); #ifdef TARGET_BASED void SigNoAttributeTableHandler(int); #endif /* * If any of the following API are modified or new ones are * introduced, we have to make sure if they are called in * reload path. If yes, they have to use new snort config. */ static inline int ScTestMode(void) { return snort_conf->run_mode == RUN_MODE__TEST; } static inline int ScRuleDumpMode(void) { return snort_conf->run_mode == RUN_MODE__RULE_DUMP; } static inline int ScVersionMode(void) { return snort_conf->run_mode == RUN_MODE__VERSION; } static inline int ScIdsMode(void) { return snort_conf->run_mode == RUN_MODE__IDS; } static inline int ScPacketLogMode(void) { return snort_conf->run_mode == RUN_MODE__PACKET_LOG; } static inline int ScPacketDumpMode(void) { return snort_conf->run_mode == RUN_MODE__PACKET_DUMP; } static inline int ScDaemonMode(void) { return snort_conf->run_flags & RUN_FLAG__DAEMON; } static inline int ScDaemonRestart(void) { return snort_conf->run_flags & RUN_FLAG__DAEMON_RESTART; } static inline int ScReadMode(void) { return snort_conf->run_flags & RUN_FLAG__READ; } static inline int ScLogSyslog(void) { return snort_conf->logging_flags & LOGGING_FLAG__SYSLOG; } #ifdef WIN32 static inline int ScLogSyslogRemote(void) { return snort_conf->logging_flags & LOGGING_FLAG__SYSLOG_REMOTE; } #endif static inline int ScLogVerbose(void) { return snort_conf->logging_flags & LOGGING_FLAG__VERBOSE; } static inline int ScLogQuiet(void) { return snort_conf->logging_flags & LOGGING_FLAG__QUIET; } static inline int ScCheckInternalLogLevel(int level) { return internal_log_level >= level; } static inline void ScSetInternalLogLevel(int level) { if (!ScLogQuiet()) internal_log_level = level; } static inline void ScRestoreInternalLogLevel(void) { internal_log_level = snort_conf->internal_log_level; } static inline int ScDecoderAlerts(void) { return snort_conf->targeted_policies[getNapRuntimePolicy()]->decoder_alert_flags & DECODE_EVENT_FLAG__DEFAULT; } static inline int ScDecoderDrops(void) { return snort_conf->targeted_policies[getNapRuntimePolicy()]->decoder_drop_flags & DECODE_EVENT_FLAG__DEFAULT; } static inline int ScDecoderOversizedAlerts(void) { return snort_conf->targeted_policies[getNapRuntimePolicy()]->decoder_alert_flags & DECODE_EVENT_FLAG__OVERSIZED; } static inline int ScDecoderOversizedDrops(void) { return snort_conf->targeted_policies[getNapRuntimePolicy()]->decoder_drop_flags & DECODE_EVENT_FLAG__OVERSIZED; } static inline int ScDecoderIpv6BadFragAlerts(void) { return snort_conf->targeted_policies[getNapRuntimePolicy()]->decoder_alert_flags & DECODE_EVENT_FLAG__IPV6_BAD_FRAG; } static inline int ScDecoderIpv6BadFragDrops(void) { return snort_conf->targeted_policies[getNapRuntimePolicy()]->decoder_drop_flags & DECODE_EVENT_FLAG__IPV6_BAD_FRAG; } static inline int ScDecoderIpv6BsdIcmpFragAlerts(void) { return snort_conf->targeted_policies[getNapRuntimePolicy()]->decoder_alert_flags & DECODE_EVENT_FLAG__IPV6_BSD_ICMP_FRAG; } static inline int ScDecoderIpv6BsdIcmpFragDrops(void) { return snort_conf->targeted_policies[getNapRuntimePolicy()]->decoder_drop_flags & DECODE_EVENT_FLAG__IPV6_BSD_ICMP_FRAG; } static inline int ScDecoderTcpOptAlerts(void) { return snort_conf->targeted_policies[getNapRuntimePolicy()]->decoder_alert_flags & DECODE_EVENT_FLAG__TCP_OPT_ANOMALY; } static inline int ScDecoderTcpOptDrops(void) { return snort_conf->targeted_policies[getNapRuntimePolicy()]->decoder_drop_flags & DECODE_EVENT_FLAG__TCP_OPT_ANOMALY; } static inline int ScDecoderTcpOptExpAlerts(void) { return snort_conf->targeted_policies[getNapRuntimePolicy()]->decoder_alert_flags & DECODE_EVENT_FLAG__TCP_EXP_OPT; } static inline int ScDecoderTcpOptExpDrops(void) { return snort_conf->targeted_policies[getNapRuntimePolicy()]->decoder_drop_flags & DECODE_EVENT_FLAG__TCP_EXP_OPT; } static inline int ScDecoderTcpOptObsAlerts(void) { return snort_conf->targeted_policies[getNapRuntimePolicy()]->decoder_alert_flags & DECODE_EVENT_FLAG__TCP_OBS_OPT; } static inline int ScDecoderTcpOptObsDrops(void) { return snort_conf->targeted_policies[getNapRuntimePolicy()]->decoder_drop_flags & DECODE_EVENT_FLAG__TCP_OBS_OPT; } static inline int ScDecoderTcpOptTTcpAlerts(void) { return snort_conf->targeted_policies[getNapRuntimePolicy()]->decoder_alert_flags & DECODE_EVENT_FLAG__TCP_TTCP_OPT; } static inline int ScDecoderTcpOptTTcpDrops(void) { return snort_conf->targeted_policies[getNapRuntimePolicy()]->decoder_drop_flags & DECODE_EVENT_FLAG__TCP_TTCP_OPT; } static inline int ScDecoderIpOptAlerts(void) { return snort_conf->targeted_policies[getNapRuntimePolicy()]->decoder_alert_flags & DECODE_EVENT_FLAG__IP_OPT_ANOMALY; } static inline int ScDecoderIpOptDrops(void) { return snort_conf->targeted_policies[getNapRuntimePolicy()]->decoder_drop_flags & DECODE_EVENT_FLAG__IP_OPT_ANOMALY; } static inline int ScIpChecksums(void) { return snort_conf->targeted_policies[getNapRuntimePolicy()]->checksum_flags & CHECKSUM_FLAG__IP; } static inline int ScIpChecksumDrops(void) { return snort_conf->targeted_policies[getNapRuntimePolicy()]->checksum_drop_flags & CHECKSUM_FLAG__IP; } static inline int ScUdpChecksums(void) { return snort_conf->targeted_policies[getNapRuntimePolicy()]->checksum_flags & CHECKSUM_FLAG__UDP; } static inline int ScUdpChecksumDrops(void) { return snort_conf->targeted_policies[getNapRuntimePolicy()]->checksum_drop_flags & CHECKSUM_FLAG__UDP; } static inline int ScTcpChecksums(void) { return snort_conf->targeted_policies[getNapRuntimePolicy()]->checksum_flags & CHECKSUM_FLAG__TCP; } static inline int ScTcpChecksumDrops(void) { return snort_conf->targeted_policies[getNapRuntimePolicy()]->checksum_drop_flags & CHECKSUM_FLAG__TCP; } static inline int ScIcmpChecksums(void) { return snort_conf->targeted_policies[getNapRuntimePolicy()]->checksum_flags & CHECKSUM_FLAG__ICMP; } static inline int ScIcmpChecksumDrops(void) { return snort_conf->targeted_policies[getNapRuntimePolicy()]->checksum_drop_flags & CHECKSUM_FLAG__ICMP; } static inline int ScIgnoreTcpPort(uint16_t port) { return snort_conf->ignore_ports[port] & PROTO_BIT__TCP; } static inline int ScIgnoreUdpPort(uint16_t port) { return snort_conf->ignore_ports[port] & PROTO_BIT__UDP; } #ifdef MPLS static inline long int ScMplsStackDepth(void) { return snort_conf->mpls_stack_depth; } #ifdef MPLS_RFC4023_SUPPORT static inline long int ScMplsPayloadCheck(uint8_t ih1, long int iRet) { // IPv4 if (((ih1 & 0xF0) >> 4) == 4) return MPLS_PAYLOADTYPE_IPV4; // IPv6 else if (((ih1 & 0xF0) >> 4) == 6) return MPLS_PAYLOADTYPE_IPV6; else return iRet; } #endif static inline long int ScMplsPayloadType(void) { return snort_conf->mpls_payload_type; } static inline int ScMplsOverlappingIp(void) { return snort_conf->run_flags & RUN_FLAG__MPLS_OVERLAPPING_IP; } static inline int ScMplsMulticast(void) { return snort_conf->run_flags & RUN_FLAG__MPLS_MULTICAST; } #endif static inline uint32_t ScIpv6FragTimeout(void) { return snort_conf->ipv6_frag_timeout; } static inline uint32_t ScIpv6MaxFragSessions(void) { return snort_conf->ipv6_max_frag_sessions; } static inline uint8_t ScMinTTL(void) { return snort_conf->targeted_policies[getNapRuntimePolicy()]->min_ttl; } #ifdef NORMALIZER static inline uint8_t ScNewTTL(void) { return snort_conf->targeted_policies[getNapRuntimePolicy()]->new_ttl; } #endif static inline uint32_t ScPafMax (void) { return snort_conf->paf_max; } static inline bool ScPafEnabled (void) { return ( ScPafMax() > 0 ); } static inline uint32_t ScEventLogId(void) { return snort_conf->event_log_id; } static inline int ScConfErrorOut(void) { return snort_conf->run_flags & RUN_FLAG__CONF_ERROR_OUT; } static inline int ScAssureEstablished(void) { return snort_conf->run_flags & RUN_FLAG__ASSURE_EST; } /* Set if stream5 is configured */ static inline int ScStateful(void) { return snort_conf->run_flags & RUN_FLAG__STATEFUL; } static inline long int ScPcreMatchLimit(void) { return snort_conf->pcre_match_limit; } static inline long int ScPcreMatchLimitRecursion(void) { return snort_conf->pcre_match_limit_recursion; } #ifdef PERF_PROFILING static inline int ScProfilePreprocs(void) { return snort_conf->profile_preprocs.num; } static inline int ScProfileRules(void) { return snort_conf->profile_rules.num; } #endif static inline int ScStaticHash(void) { return snort_conf->run_flags & RUN_FLAG__STATIC_HASH; } static inline int ScAutoGenPreprocDecoderOtns(void) { return (((snort_conf->targeted_policies[getNapRuntimePolicy()])->policy_flags) & POLICY_FLAG__AUTO_OTN ); } static inline int ScProcessAllEvents(void) { return snort_conf->event_queue_config->process_all_events; } static inline int ScNapPassiveMode(void) { return (((snort_conf->targeted_policies[getNapRuntimePolicy()])->nap_policy_mode) == POLICY_MODE__PASSIVE ); } static inline int ScIpsPassiveMode(void) { return (((snort_conf->targeted_policies[getIpsRuntimePolicy()])->ips_policy_mode) == POLICY_MODE__PASSIVE ); } static inline int ScAdapterPassiveMode(void) { return !(snort_conf->run_flags & (RUN_FLAG__INLINE | RUN_FLAG__INLINE_TEST)); } static inline int ScNapInlineMode(void) { return (((snort_conf->targeted_policies[getNapRuntimePolicy()])->nap_policy_mode) == POLICY_MODE__INLINE ); } static inline int ScIpsInlineMode(void) { return (((snort_conf->targeted_policies[getIpsRuntimePolicy()])->ips_policy_mode) == POLICY_MODE__INLINE ); } static inline int ScAdapterInlineMode(void) { return snort_conf->run_flags & RUN_FLAG__INLINE; } static inline int ScNapInlineTestMode(void) { return (((snort_conf->targeted_policies[getNapRuntimePolicy()])->nap_policy_mode) == POLICY_MODE__INLINE_TEST ); } static inline int ScIpsInlineTestMode(void) { return (((snort_conf->targeted_policies[getIpsRuntimePolicy()])->ips_policy_mode) == POLICY_MODE__INLINE_TEST ); } static inline int ScAdapterInlineTestMode(void) { return snort_conf->run_flags & RUN_FLAG__INLINE_TEST; } static inline int ScOutputIncludeYear(void) { return snort_conf->output_flags & OUTPUT_FLAG__INCLUDE_YEAR; } static inline int ScOutputUseUtc(void) { return snort_conf->output_flags & OUTPUT_FLAG__USE_UTC; } static inline int ScOutputDataLink(void) { return snort_conf->output_flags & OUTPUT_FLAG__SHOW_DATA_LINK; } static inline int ScVerboseByteDump(void) { return snort_conf->output_flags & OUTPUT_FLAG__VERBOSE_DUMP; } static inline int ScAlertPacketCount(void) { return snort_conf->output_flags & OUTPUT_FLAG__ALERT_PKT_CNT; } static inline int ScObfuscate(void) { return snort_conf->output_flags & OUTPUT_FLAG__OBFUSCATE; } static inline int ScOutputAppData(void) { return snort_conf->output_flags & OUTPUT_FLAG__APP_DATA; } static inline int ScOutputCharData(void) { return snort_conf->output_flags & OUTPUT_FLAG__CHAR_DATA; } static inline int ScAlertInterface(void) { return snort_conf->output_flags & OUTPUT_FLAG__ALERT_IFACE; } static inline int ScNoOutputTimestamp(void) { return snort_conf->output_flags & OUTPUT_FLAG__NO_TIMESTAMP; } static inline int ScLineBufferedLogging(void) { return snort_conf->output_flags & OUTPUT_FLAG__LINE_BUFFER; } static inline int ScDefaultRuleState(void) { return snort_conf->default_rule_state; } static inline int ScRequireRuleSid(void) { return snort_conf->run_flags & RUN_FLAG__REQUIRE_RULE_SID; } #ifdef INLINE_FAILOPEN static inline int ScDisableInlineFailopen(void) { return snort_conf->run_flags & RUN_FLAG__DISABLE_FAILOPEN; } #endif static inline int ScNoLockPidFile(void) { return snort_conf->run_flags & RUN_FLAG__NO_LOCK_PID_FILE; } static inline long int ScTaggedPacketLimit(void) { return snort_conf->tagged_packet_limit; } static inline int ScCreatePidFile(void) { return snort_conf->run_flags & RUN_FLAG__CREATE_PID_FILE; } static inline int ScNoInterfacePidFile(void) { return snort_conf->run_flags & RUN_FLAG__NO_IFACE_PID_FILE; } static inline int ScPcapShow(void) { return snort_conf->run_flags & RUN_FLAG__PCAP_SHOW; } static inline int ScPcapReset(void) { return snort_conf->run_flags & RUN_FLAG__PCAP_RESET; } #ifndef NO_NON_ETHER_DECODER static inline int ScOutputWifiMgmt(void) { return snort_conf->output_flags & OUTPUT_FLAG__SHOW_WIFI_MGMT; } #endif #ifdef TARGET_BASED static inline uint32_t ScMaxAttrHosts(SnortConfig *sc) { return sc->max_attribute_hosts; } static inline uint32_t ScMaxAttrServicesPerHost(void) { return snort_conf->max_attribute_services_per_host; } static inline int ScDisableAttrReload(SnortConfig *sc) { return sc->run_flags & RUN_FLAG__DISABLE_ATTRIBUTE_RELOAD_THREAD; } #endif static inline int ScTreatDropAsAlert(void) { return snort_conf->run_flags & RUN_FLAG__TREAT_DROP_AS_ALERT; } static inline int ScTreatDropAsIgnore(void) { return snort_conf->run_flags & RUN_FLAG__TREAT_DROP_AS_IGNORE; } static inline int ScAlertBeforePass(void) { return snort_conf->run_flags & RUN_FLAG__ALERT_BEFORE_PASS; } static inline int ScNoPcre(void) { return snort_conf->run_flags & RUN_FLAG__NO_PCRE; } static inline int ScGetEvalIndex(RuleType type) { return snort_conf->evalOrder[type]; } static inline int ScNoLog(void) { return snort_conf->no_log; } static inline int ScNoAlert(void) { return snort_conf->no_alert; } #if defined(WIN32) && defined(ENABLE_WIN32_SERVICE) static inline int ScTerminateService(void) { return snort_conf->run_flags & RUN_FLAG__TERMINATE_SERVICE; } static inline int ScPauseService(void) { return snort_conf->run_flags & RUN_FLAG__PAUSE_SERVICE; } #endif static inline int ScUid(void) { return snort_conf->user_id; } static inline int ScGid(void) { return snort_conf->group_id; } static inline char * ScPcapLogFile(void) { return snort_conf->pcap_log_file; } #ifdef SIDE_CHANNEL static inline int ScSideChannelEnabled(void) { return snort_conf->side_channel_config.enabled; } #endif // use of macro avoids depending on generators.h #define EventIsInternal(gid) (gid == GENERATOR_INTERNAL) static inline void EnableInternalEvent(RateFilterConfig *config, uint32_t sid) { if (config == NULL) return; config->internal_event_mask |= (1 << sid); } static inline int InternalEventIsEnabled(RateFilterConfig *config, uint32_t sid) { if (config == NULL) return 0; return (config->internal_event_mask & (1 << sid)); } static inline int ScIsPreprocEnabled(uint32_t preproc_id, tSfPolicyId policy_id) { SnortPolicy *policy; if (policy_id >= snort_conf->num_policies_allocated) return 0; policy = snort_conf->targeted_policies[policy_id]; if (policy == NULL) return 0; if (policy->preproc_bit_mask & (UINT64_C(1) << preproc_id)) return 1; return 0; } static inline int ScDeepTeredoInspection(void) { return snort_conf->enable_teredo; } static inline int ScGTPDecoding(void) { return snort_conf->enable_gtp; } static inline int ScIsGTPPort(uint16_t port) { return snort_conf->gtp_ports[port]; } static inline int ScESPDecoding(void) { return snort_conf->enable_esp; } static inline int ScVlanAgnostic(void) { return snort_conf->vlan_agnostic; } static inline int ScAddressSpaceAgnostic(void) { return snort_conf->addressspace_agnostic; } static inline int ScLogIPv6Extra(void) { return snort_conf->log_ipv6_extra; } static inline uint32_t ScSoRuleMemcap(void) { return snort_conf->so_rule_memcap; } static inline bool ScTunnelBypassEnabled (uint8_t proto) { return !(snort_conf->tunnel_mask & proto); } static inline uint8_t ScMaxIP6Extensions(void) { return snort_conf->max_ip6_extensions; } static inline int ScSuppressConfigLog(void) { return snort_conf->suppress_config_log; } static inline int ScDisableReplaceOpt(void) { return snort_conf->disable_replace_opt; } static inline int ScIpsInlineModeNewConf (SnortConfig * sc) { return (((sc->targeted_policies[getParserPolicy(sc)])->ips_policy_mode) == POLICY_MODE__INLINE ); } static inline int ScAdapterInlineModeNewConf (SnortConfig * sc) { return sc->run_flags & RUN_FLAG__INLINE; } static inline int ScTreatDropAsIgnoreNewConf (SnortConfig * sc) { return sc->run_flags & RUN_FLAG__TREAT_DROP_AS_IGNORE; } static inline int ScIpsInlineTestModeNewConf (SnortConfig * sc) { return (((sc->targeted_policies[getParserPolicy(sc)])->ips_policy_mode) == POLICY_MODE__INLINE_TEST ); } static inline int ScAdapterInlineTestModeNewConf (SnortConfig * sc) { return sc->run_flags & RUN_FLAG__INLINE_TEST; } static inline int ScTestModeNewConf (SnortConfig * sc) { return sc->run_mode == RUN_MODE__TEST; } static inline int ScConfErrorOutNewConf (SnortConfig * sc) { return sc->run_flags & RUN_FLAG__CONF_ERROR_OUT; } static inline int ScDefaultRuleStateNewConf (SnortConfig * sc) { return sc->default_rule_state; } static inline int ScRequireRuleSidNewConf (SnortConfig * sc) { return sc->run_flags & RUN_FLAG__REQUIRE_RULE_SID; } static inline int ScTreatDropAsAlertNewConf (SnortConfig * sc) { return sc->run_flags & RUN_FLAG__TREAT_DROP_AS_ALERT; } static inline int ScSuppressConfigLogNewConf (SnortConfig* sc) { return sc->suppress_config_log; } static inline int ScLogQuietNewConf (SnortConfig* sc) { return sc->logging_flags & LOGGING_FLAG__QUIET; } static inline void ScSetInternalLogLevelNewConf (SnortConfig* sc, int level) { if (!ScLogQuietNewConf(sc)) internal_log_level = level; } static inline void ScRestoreInternalLogLevelNewConf (SnortConfig* sc) { internal_log_level = sc->internal_log_level; } static inline long int ScPcreMatchLimitNewConf (SnortConfig *sc) { return sc->pcre_match_limit; } static inline long int ScPcreMatchLimitRecursionNewConf (SnortConfig *sc) { return sc->pcre_match_limit_recursion; } static inline int ScNoOutputTimestampNewConf (SnortConfig *sc) { return sc->output_flags & OUTPUT_FLAG__NO_TIMESTAMP; } static inline int ScNapPassiveModeNewConf (SnortConfig* sc) { return (((sc->targeted_policies[getParserPolicy(sc)])->nap_policy_mode) == POLICY_MODE__PASSIVE ); } static inline int ScNapInlineTestModeNewConf (SnortConfig* sc) { return (((sc->targeted_policies[getParserPolicy(sc)])->nap_policy_mode) == POLICY_MODE__INLINE_TEST ); } static inline uint32_t ScPafMaxNewConf (SnortConfig *sc) { return sc->paf_max; } static inline bool ScPafEnabledNewConf (SnortConfig *sc) { return ( ScPafMaxNewConf(sc) > 0 ); } #if defined(DAQ_CAPA_CST_TIMEOUT) static inline uint64_t GetTimeout( Packet *p, uint64_t *timeout) { DAQ_QueryFlow_t query; int rval; query.type = DAQ_QUERYFLOW_TYPE_TIMEOUT_VAL; query.length = sizeof(uint64_t); query.value = timeout; rval = DAQ_QueryFlow( p->pkth, &query); if(rval != DAQ_SUCCESS) *timeout = 1; return 1; } #endif /* query flow */ #endif /* __SNORT_H__ */ snort-2.9.15.1/src/build.h0000644000175200017520000000002613571422607012105 00000000000000#define BUILD "15125" snort-2.9.15.1/src/snprintf.c0000644000175200017520000003225213571422607012652 00000000000000/* $Id$ */ /* ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* ** This file contains various routines which we shamelessly steal from other ** opensource products :-P (I love code reuseability idea) ** fygrave@tigerteam.net */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifndef HAVE_SNPRINTF #include "snprintf.h" /* snprintf() and all supporting routines were taken from sendmail, hence the * copyleft message */ /* * Copyright (c) 1998 Sendmail, Inc. All rights reserved. * Copyright (c) 1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * By using this file, you agree to the terms and conditions set * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. * */ /* ** SNPRINTF, VSNPRINT -- counted versions of printf ** ** These versions have been grabbed off the net. They have been ** cleaned up to compile properly and support for .precision and ** %lx has been added. */ /************************************************************** * Original: * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 * A bombproof version of doprnt (sm_dopr) included. * Sigh. This sort of thing is always nasty do deal with. Note that * the version here does not include floating point... * * snprintf() is used instead of sprintf() as it does limit checks * for string length. This covers a nasty loophole. * * The other functions are there to prevent NULL pointers from * causing nast effects. **************************************************************/ void sm_dopr(); char *DoprEnd; int SnprfOverflow; #ifndef HAVE_SNPRINTF /* VARARGS3 */ int #ifdef __STDC__ snprintf(char *str, size_t count, const char *fmt, ...) #else snprintf(str, count, fmt, va_alist) char *str; size_t count; const char *fmt; va_dcl #endif { int len; VA_LOCAL_DECL VA_START(fmt); len = vsnprintf(str, count, fmt, ap); VA_END; return len; } #ifndef luna2 #ifndef HAVE_VSNPRINTF int vsnprintf(str, count, fmt, args) char *str; size_t count; const char *fmt; va_list args; { str[0] = 0; DoprEnd = str + count - 1; SnprfOverflow = 0; sm_dopr( str, fmt, args ); if(count > 0) DoprEnd[0] = 0; if(SnprfOverflow && tTd(57, 2)) printf("\nvsnprintf overflow, len = %ld, str = %s", (long) count, shortenstring(str, MAXSHORTSTR)); return strlen((const char *)str); } #endif /* !HAVE_VSNPRINTF */ #endif /* !luna2 */ #endif /* !HASSNPRINTF */ /* * sm_dopr(): poor man's version of doprintf */ void fmtstr __P((char *value, int ljust, int len, int zpad, int maxwidth)); void fmtnum __P((long value, int base, int dosign, int ljust, int len, int zpad)); void dostr __P(( char * , int )); char *output; void dopr_outch __P(( int c )); int SyslogErrno; void sm_dopr( buffer, format, args ) char *buffer; const char *format; va_list args; { int ch; long value; int longflag = 0; int pointflag = 0; int maxwidth = 0; char *strvalue; int ljust; int len; int zpad; #if !HAVE_STRERROR && !defined(ERRLIST_PREDEFINED) extern char *sys_errlist[]; extern int sys_nerr; #endif output = buffer; while((ch = *format++) != '\0') { switch(ch) { case '%': ljust = len = zpad = maxwidth = 0; longflag = pointflag = 0; nextch: ch = *format++; switch(ch) { case 0: dostr( "**end of format**" , 0); return; case '-': ljust = 1; goto nextch; case '0': /* set zero padding if len not set */ if(len==0 && !pointflag) zpad = '0'; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if(pointflag) maxwidth = maxwidth*10 + ch - '0'; else len = len*10 + ch - '0'; goto nextch; case '*': if(pointflag) maxwidth = va_arg( args, int ); else len = va_arg( args, int ); goto nextch; case '.': pointflag = 1; goto nextch; case 'l': longflag = 1; goto nextch; case 'u': case 'U': /*fmtnum(value,base,dosign,ljust,len,zpad) */ if(longflag) { value = va_arg( args, long ); } else { value = va_arg( args, int ); } fmtnum( value, 10,0, ljust, len, zpad ); break; case 'o': case 'O': /*fmtnum(value,base,dosign,ljust,len,zpad) */ if(longflag) { value = va_arg( args, long ); } else { value = va_arg( args, int ); } fmtnum( value, 8,0, ljust, len, zpad ); break; case 'd': case 'D': if(longflag) { value = va_arg( args, long ); } else { value = va_arg( args, int ); } fmtnum( value, 10,1, ljust, len, zpad ); break; case 'x': if(longflag) { value = va_arg( args, long ); } else { value = va_arg( args, int ); } fmtnum( value, 16,0, ljust, len, zpad ); break; case 'X': if(longflag) { value = va_arg( args, long ); } else { value = va_arg( args, int ); } fmtnum( value,-16,0, ljust, len, zpad ); break; case 's': strvalue = va_arg( args, char *); if(maxwidth > 0 || !pointflag) { if(pointflag && len > maxwidth) len = maxwidth; /* Adjust padding */ fmtstr( strvalue,ljust,len,zpad, maxwidth); } break; case 'c': ch = va_arg( args, int ); dopr_outch( ch ); break; case 'm': #if HAVE_STRERROR dostr(strerror(SyslogErrno), 0); #else if(SyslogErrno < 0 || SyslogErrno >= sys_nerr) { dostr("Error ", 0); fmtnum(SyslogErrno, 10, 0, 0, 0, 0); } else dostr((char *)sys_errlist[SyslogErrno], 0); #endif break; case '%': dopr_outch( ch ); continue; default: dostr( "???????" , 0); } break; default: dopr_outch( ch ); break; } } *output = 0; } void fmtstr( value, ljust, len, zpad, maxwidth ) char *value; int ljust, len, zpad, maxwidth; { int padlen, strlen; /* amount to pad */ if(value == 0) { value = ""; } for(strlen = 0; value[strlen]; ++ strlen); /* strlen */ if(strlen > maxwidth && maxwidth) strlen = maxwidth; padlen = len - strlen; if(padlen < 0) padlen = 0; if(ljust) padlen = -padlen; while(padlen > 0) { dopr_outch( ' ' ); --padlen; } dostr( value, maxwidth ); while(padlen < 0) { dopr_outch( ' ' ); ++padlen; } } void fmtnum( value, base, dosign, ljust, len, zpad ) long value; int base, dosign, ljust, len, zpad; { int signvalue = 0; unsigned long uvalue; char convert[20]; int place = 0; int padlen = 0; /* amount to pad */ int caps = 0; /* DEBUGP(("value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n", value, base, dosign, ljust, len, zpad )); */ uvalue = value; if(dosign) { if(value < 0) { signvalue = '-'; uvalue = -value; } } if(base < 0) { caps = 1; base = -base; } do { convert[place++] = (caps? "0123456789ABCDEF":"0123456789abcdef") [uvalue % (unsigned)base ]; uvalue = (uvalue / (unsigned)base ); }while(uvalue); convert[place] = 0; padlen = len - place; if(padlen < 0) padlen = 0; if(ljust) padlen = -padlen; /* DEBUGP(( "str '%s', place %d, sign %c, padlen %d\n", convert,place,signvalue,padlen)); */ if(zpad && padlen > 0) { if(signvalue) { dopr_outch( signvalue ); --padlen; signvalue = 0; } while(padlen > 0) { dopr_outch( zpad ); --padlen; } } while(padlen > 0) { dopr_outch( ' ' ); --padlen; } if(signvalue) dopr_outch( signvalue ); while(place > 0) dopr_outch( convert[--place] ); while(padlen < 0) { dopr_outch( ' ' ); ++padlen; } } void dostr( str , cut) char *str; int cut; { if(cut) { while(*str && cut-- > 0) dopr_outch(*str++); } else { while(*str) dopr_outch(*str++); } } void dopr_outch( c ) int c; { #if 0 if(iscntrl(c) && c != '\n' && c != '\t') { c = '@' + (c & 0x1F); if(DoprEnd == 0 || output < DoprEnd) *output++ = '^'; } #endif if(DoprEnd == 0 || output < DoprEnd) *output++ = c; else SnprfOverflow++; } /* ** QUAD_TO_STRING -- Convert a quad type to a string. ** ** Convert a quad type to a string. This must be done ** separately as %lld/%qd are not supported by snprint() ** and adding support would slow down systems which only ** emulate the data type. ** ** Parameters: ** value -- number to convert to a string. ** ** Returns: ** pointer to a string. */ char * quad_to_string(value) QUAD_T value; { char *fmtstr; static char buf[64]; /* ** Use sprintf() instead of snprintf() since snprintf() ** does not support %qu or %llu. The buffer is large enough ** to hold the string so there is no danger of buffer ** overflow. */ #if NEED_PERCENTQ fmtstr = "%qu"; #elif SIZEOF_UNSIGNED_LONG_INT == 8 fmtstr = "%lu"; #else fmtstr = "%llu"; #endif sprintf(buf, fmtstr, value); return buf; } /* ** SHORTENSTRING -- return short version of a string ** ** If the string is already short, just return it. If it is too ** long, return the head and tail of the string. ** ** Parameters: ** s -- the string to shorten. ** m -- the max length of the string. ** ** Returns: ** Either s or a short version of s. */ char * shortenstring(s, m) register const char *s; int m; { int l; static char buf[MAXSHORTSTR + 1]; l = strlen(s); if(l < m) return(char *) s; if(m > MAXSHORTSTR) m = MAXSHORTSTR; else if(m < 10) { if(m < 5) { strncpy(buf, s, m); buf[m] = '\0'; return buf; } strncpy(buf, s, m - 3); strcpy(buf + m - 3, "..."); return buf; } m = (m - 3) / 2; strncpy(buf, s, m); strcpy(buf + m, "..."); strcpy(buf + m + 3, s + l - m); return buf; } #endif snort-2.9.15.1/src/snprintf.h0000644000175200017520000000364313571422607012661 00000000000000/* $Id$ */ /* ** Copyright (C) 2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __SNPRINTF_H__ #define __SNPRINTF_H__ #ifndef HAVE_SNPRINTF #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifdef __STDC__ #include # define VA_LOCAL_DECL va_list ap; # define VA_START(f) va_start(ap, f) # define VA_END va_end(ap) #else /* __STDC__ */ #ifndef WIN32 #include #endif /* WIN32 */ # define VA_LOCAL_DECL va_list ap; # define VA_START(f) va_start(ap) # define VA_END va_end(ap) #endif /* __STDC__ */ #ifndef __P #include "cdefs.h" #endif /* ! __P */ #ifndef QUAD_T # define QUAD_T unsigned long #endif /* ! QUAD_T */ #define tTd(flag, level) (tTdvect[flag] >= (u_char)level) #define MAXSHORTSTR 203 /* max short string length */ u_char tTdvect[100]; /* trace vector */ int snprintf(char *, size_t , const char *, ...); #ifndef HAVE_VSNPRINTF int vsnprintf(char *, size_t, const char *, va_list); #endif /* HAVE_VSNPRINTF */ char *shortenstring(register const char *, int); #endif /* HAVE_SNPRINTF */ #endif /* __SNPRINTF_H__ */ snort-2.9.15.1/src/strlcatu.c0000644000175200017520000000501213571422607012642 00000000000000/* * Copyright (c) 1998 Todd C. Miller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``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. */ /* $Id$ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifndef HAVE_STRLCAT #if defined(LIBC_SCCS) && !defined(lint) static char *rcsid = "$OpenBSD: strlcat.c,v 1.5 2001/01/13 16:17:24 millert Exp $"; #endif /* LIBC_SCCS and not lint */ #include #include /* * Appends src to string dst of size siz (unlike strncat, siz is the * full size of dst, not space left). At most siz-1 characters * will be copied. Always NUL terminates (unless siz <= strlen(dst)). * Returns strlen(initial dst) + strlen(src); if retval >= siz, * truncation occurred. */ size_t strlcat(char *dst, const char *src, size_t siz) { register char *d = dst; register const char *s = src; register size_t n = siz; size_t dlen; /* Find the end of dst and adjust bytes left but don't go past end */ while (n-- != 0 && *d != '\0') d++; dlen = d - dst; n = siz - dlen; if (n == 0) return(dlen + strlen(s)); while (*s != '\0') { if (n != 1) { *d++ = *s; n--; } s++; } *d = '\0'; return(dlen + (s - src)); /* count does not include NUL */ } #endif snort-2.9.15.1/src/strlcatu.h0000644000175200017520000000175413571422607012660 00000000000000/* $Id$ */ /* ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __STRLCAT_H__ #define __STRLCAT_H__ #ifndef HAVE_STRLCAT size_t strlcat(char *, const char *, size_t); #endif #endif /* __STRLCAT_H__ */ snort-2.9.15.1/src/strlcpyu.c0000644000175200017520000000464513571422607012701 00000000000000/* * Copyright (c) 1998 Todd C. Miller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``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. */ /* $Id$ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifndef HAVE_STRLCPY #if defined(LIBC_SCCS) && !defined(lint) static char *rcsid = "$OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $"; #endif /* LIBC_SCCS and not lint */ #include #include /* * Copy src to string dst of size siz. At most siz-1 characters * will be copied. Always NUL terminates (unless siz == 0). * Returns strlen(src); if retval >= siz, truncation occurred. */ size_t strlcpy(char *dst, const char *src, size_t siz) { register char *d = dst; register const char *s = src; register size_t n = siz; /* Copy as many bytes as will fit */ if (n != 0 && --n != 0) { do { if ((*d++ = *s++) == 0) break; } while (--n != 0); } /* Not enough room in dst, add NUL and traverse rest of src */ if (n == 0) { if (siz != 0) *d = '\0'; /* NUL-terminate dst */ while (*s++) ; } return(s - src - 1); /* count does not include NUL */ } #endif snort-2.9.15.1/src/strlcpyu.h0000644000175200017520000000175413571422607012704 00000000000000/* $Id$ */ /* ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __STRLCPY_H__ #define __STRLCPY_H__ #ifndef HAVE_STRLCPY size_t strlcpy(char *, const char *, size_t); #endif #endif /* __STRLCPY_H__ */ snort-2.9.15.1/src/tag.c0000644000175200017520000005522313571422607011565 00000000000000/* ** Copyright (C) 1998-2002 Martin Roesch ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Chris Green ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ /* I N C L U D E S ************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "decode.h" #include "rules.h" #include "treenodes.h" #include "snort_debug.h" #include "util.h" #include "generators.h" #include "log.h" #include "parser.h" #include "snort.h" #include "tag.h" #include "sfxhash.h" #include "ipv6_port.h" /* D E F I N E S **************************************************/ #define MAX_TAG_NODES 256 /* by default we'll set a 5 minute timeout if we see no activity * on a tag with a 'count' metric so that we prune dead sessions * periodically since we're not doing TCP state tracking */ #define TAG_PRUNE_QUANTUM 300 #define TAG_MEMCAP 4194304 /* 4MB */ /* D A T A S T R U C T U R E S **********************************/ /**Key used for identifying a session or host. */ typedef struct _tagSessionKey { struct in6_addr sip; ///source IP address struct in6_addr dip; ///destination IP address /* ports */ uint16_t sp; ///source port uint16_t dp; ///destination port } tTagSessionKey; /**Node identifying a session or host based tagging. */ typedef struct _TagNode { /**key identifying a session or host. */ tTagSessionKey key; /** transport proto */ uint8_t proto; /** number of packets/seconds/bytes to tag for */ int seconds; int packets; int bytes; /** counters of number of packets tagged and max to * prevent Eventing DOS */ int pkt_count; /** packets/seconds selector */ int metric; /** session or host mode */ int mode; /** last UNIX second that this node had a successful match */ uint32_t last_access; /** event id number for correlation with trigger events */ uint16_t event_id; struct timeval event_time; void* log_list; // retain custom logging if any from triggering alert } TagNode; /* G L O B A L S **************************************************/ /**host tag cache */ static SFXHASH *host_tag_cache_ptr; /**session tag cache */ static SFXHASH *ssn_tag_cache_ptr; static uint32_t last_prune_time; static uint32_t tag_alloc_faults; static uint32_t tag_memory_usage; static bool s_exclusive = false; static unsigned s_sessions = 0; // TBD when tags leverage sessions, tag nodes can be freed at end // of session. then we can configure this to allow multiple // (consecutive) sessions to be captured. static const unsigned s_max_sessions = 1; /* P R O T O T Y P E S ********************************************/ static TagNode * TagAlloc(SFXHASH *); static void TagFree(SFXHASH *, TagNode *); static int TagFreeSessionNodeFunc(void *key, void *data); static int TagFreeHostNodeFunc(void *key, void *data); static int PruneTagCache(uint32_t, int); static int PruneTime(SFXHASH* tree, uint32_t thetime); static void TagSession(Packet *, TagData *, uint32_t, uint16_t, void*); static void TagHost(Packet *, TagData *, uint32_t, uint16_t, void*); static void AddTagNode(Packet *, TagData *, int, uint32_t, uint16_t, void*); static inline void SwapTag(TagNode *); /**Calculated memory needed per node insertion into respective cache. Its includes * memory needed for allocating TagNode, SFXHASH_NODE, and key size. * * @param hash - pointer to SFXHASH that should point to either ssn_tag_cache_ptr * or host_tag_cache_ptr. * * @returns number of bytes needed */ static inline unsigned int memory_per_node( SFXHASH *hash ) { if (hash == ssn_tag_cache_ptr) { return sizeof(tTagSessionKey)+sizeof(SFXHASH_NODE)+sizeof(TagNode); } else if (hash == host_tag_cache_ptr) { return sizeof(sfaddr_t)+sizeof(SFXHASH_NODE)+sizeof(TagNode); } return 0; } /** Allocate a TagNode * * Alocates a TagNode while guaranteeing that total memory usage remains within TAG_MEMCAP. * Least used nodes may be deleted from ssn_tag_cache and host_tag_cache to make space if * the limit is being exceeded. * * @param hash - pointer to SFXHASH that should point to either ssn_tag_cache_ptr * or host_tag_cache_ptr. * * @returns a pointer to new TagNode or NULL if memory couldn't * be allocated */ static TagNode * TagAlloc( SFXHASH *hash ) { TagNode *tag_node = NULL; if(tag_memory_usage + memory_per_node(hash) > TAG_MEMCAP) { /* aggressively prune */ struct timeval tv; struct timezone tz; int pruned_nodes = 0; tag_alloc_faults++; gettimeofday(&tv, &tz); pruned_nodes = PruneTagCache((uint32_t)tv.tv_sec, 0); if(pruned_nodes == 0) { /* if we can't prune due to time, just try to nuke * 5 not so recently used nodes */ pruned_nodes = PruneTagCache(0, 5); /* unlikely to happen since memcap has been reached */ if (pruned_nodes == 0) return NULL; } } tag_node = (TagNode *)calloc(1, sizeof(TagNode)); if (tag_node != NULL) tag_memory_usage += memory_per_node(hash); return tag_node; } /**Frees allocated TagNode. * * @param hash - pointer to SFXHASH that should point to either ssn_tag_cache_ptr * or host_tag_cache_ptr. * @param node - pointer to node to be freed */ static void TagFree( SFXHASH *hash, TagNode *node ) { if (node == NULL) return; if ( node->metric & TAG_METRIC_SESSION ) s_exclusive = false; free((void *)node); tag_memory_usage -= memory_per_node(hash); } /**Callback from session tag cache to free user data. * @param key - pointer to key to session tag * @param data - pointer to user data, to be freed. * @returns 0 */ static int TagFreeSessionNodeFunc(void *key, void *data) { TagFree(ssn_tag_cache_ptr, (TagNode *)data); return 0; } /**Callback from host tag cache to free user data. * @param key - pointer to key to session tag * @param data - pointer to user data, to be freed. * @returns 0 */ static int TagFreeHostNodeFunc(void *key, void *data) { TagFree(host_tag_cache_ptr, (TagNode *)data); return 0; } /**Reset all data structures and free all memory. */ void TagCacheReset(void) { sfxhash_make_empty(ssn_tag_cache_ptr); sfxhash_make_empty(host_tag_cache_ptr); } #ifdef DEBUG_MSGS /** * Print out a tag node IFF we are current in debug_flow * * @param np tagnode pointer to print */ static void PrintTagNode(TagNode *np) { char sipstr[INET6_ADDRSTRLEN]; char dipstr[INET6_ADDRSTRLEN]; if(!DebugThis(DEBUG_FLOW)) { return; } sfip_raw_ntop(AF_INET6, &np->key.sip, sipstr, sizeof(sipstr)); sfip_raw_ntop(AF_INET6, &np->key.dip, dipstr, sizeof(dipstr)); printf("+--------------------------------------------------------------\n"); printf("| Ssn Counts: %d, Host Counts: %d\n", ssn_tag_cache_ptr->count, host_tag_cache_ptr->count); printf("| (%u) %s:%d -> %s:%d Metric: %u " "LastAccess: %u, event_id: %u mode: %u event_time.tv_sec: %"PRIu64"\n" "| Packets: %d, Bytes: %d, Seconds: %d\n", np->proto, sipstr, np->key.sp, dipstr, np->key.dp, np->metric, np->last_access, np->event_id, np->mode, (uint64_t)np->event_time.tv_sec, np->packets, np->bytes, np->seconds); printf("+--------------------------------------------------------------\n"); } #endif /* DEBUG */ /** * swap the sips and dips, dp's and sp's * * @param np TagNode ptr */ static inline void SwapTag(TagNode *np) { struct in6_addr tip; uint16_t tport; tip = np->key.sip; np->key.sip = np->key.dip; np->key.dip = tip; tport = np->key.sp; np->key.sp = np->key.dp; np->key.dp = tport; } void InitTag(void) { unsigned int hashTableSize = TAG_MEMCAP/sizeof(TagNode); ssn_tag_cache_ptr = sfxhash_new( hashTableSize, /* number of hash buckets */ sizeof(tTagSessionKey), /* size of the key we're going to use */ 0, /* size of the storage node */ 0, /* disable memcap*/ 0, /* use auto node recovery */ NULL, /* anr free function */ TagFreeSessionNodeFunc, /* user free function */ 0); /* recycle node flag */ host_tag_cache_ptr = sfxhash_new( hashTableSize, /* number of hash buckets */ sizeof(struct in6_addr), /* size of the key we're going to use */ 0, /* size of the storage node */ 0, /* disable memcap*/ 0, /* use auto node recovery */ NULL, /* anr free function */ TagFreeHostNodeFunc, /* user free function */ 0); /* recycle node flag */ } void CleanupTag(void) { if (ssn_tag_cache_ptr) { sfxhash_delete(ssn_tag_cache_ptr); } if (host_tag_cache_ptr) { sfxhash_delete(host_tag_cache_ptr); } } static void TagSession(Packet *p, TagData *tag, uint32_t time, uint16_t event_id, void* log_list) { DEBUG_WRAP(DebugMessage(DEBUG_FLOW, "TAGGING SESSION\n");); AddTagNode(p, tag, TAG_SESSION, time, event_id, log_list); } static void TagHost(Packet *p, TagData *tag, uint32_t time, uint16_t event_id, void* log_list) { int mode; DEBUG_WRAP(DebugMessage(DEBUG_FLOW, "TAGGING HOST\n");); switch(tag->tag_direction) { case TAG_HOST_DST: mode = TAG_HOST_DST; break; case TAG_HOST_SRC: mode = TAG_HOST_SRC; break; default: mode = TAG_HOST_SRC; break; } AddTagNode(p, tag, mode, time, event_id, log_list); } static void AddTagNode(Packet *p, TagData *tag, int mode, uint32_t now, uint16_t event_id, void* log_list) { TagNode *idx; /* index pointer */ TagNode *returned; SFXHASH *tag_cache_ptr = NULL; DEBUG_WRAP(DebugMessage(DEBUG_FLOW, "Adding new Tag Head\n");); if ( tag->tag_metric & TAG_METRIC_SESSION ) { if ( s_exclusive ) return; if ( s_sessions >= s_max_sessions ) return; s_exclusive = true; ++s_sessions; } if(mode == TAG_SESSION) { DEBUG_WRAP(DebugMessage(DEBUG_FLOW,"Session Tag!\n");); tag_cache_ptr = ssn_tag_cache_ptr; } else { DEBUG_WRAP(DebugMessage(DEBUG_FLOW,"Host Tag!\n");); tag_cache_ptr = host_tag_cache_ptr; } idx = TagAlloc(tag_cache_ptr); /* If a TagNode couldn't be allocated, just write an error message * and return - won't be able to track this one. */ if (idx == NULL) { ErrorMessage("AddTagNode(): Unable to allocate %u bytes of memory for new TagNode\n", (unsigned)sizeof(TagNode)); return; } sfaddr_copy_to_raw(&idx->key.sip, GET_SRC_IP(p)); sfaddr_copy_to_raw(&idx->key.dip, GET_DST_IP(p)); idx->key.sp = p->sp; idx->key.dp = p->dp; idx->proto = GET_IPH_PROTO(p); idx->metric = tag->tag_metric; idx->last_access = now; idx->event_id = event_id; idx->event_time.tv_sec = p->pkth->ts.tv_sec; idx->event_time.tv_usec = p->pkth->ts.tv_usec; idx->mode = mode; idx->pkt_count = 0; idx->log_list = log_list; if(idx->metric & TAG_METRIC_SECONDS) { /* set the expiration time for this tag */ idx->seconds = now + tag->tag_seconds; } if(idx->metric & TAG_METRIC_BYTES) { /* set the expiration time for this tag */ idx->bytes = tag->tag_bytes; } if(idx->metric & TAG_METRIC_PACKETS) { /* set the expiration time for this tag */ idx->packets = tag->tag_packets; } DEBUG_WRAP(PrintTagNode(idx);); /* check for duplicates */ returned = (TagNode *) sfxhash_find(tag_cache_ptr, idx); if(returned == NULL) { DEBUG_WRAP(DebugMessage(DEBUG_FLOW,"Looking the other way!!\n");); SwapTag(idx); returned = (TagNode *) sfxhash_find(tag_cache_ptr, idx); SwapTag(idx); } if(returned == NULL) { DEBUG_WRAP(DebugMessage(DEBUG_FLOW,"Inserting a New Tag!\n");); /* if we're supposed to be tagging the other side, swap it around -- Lawrence Reed */ if(mode == TAG_HOST_DST) { SwapTag(idx); } if(sfxhash_add(tag_cache_ptr, idx, idx) != SFXHASH_OK) { DEBUG_WRAP(DebugMessage(DEBUG_FLOW, "sfxhash_add failed, that's going to " "make life difficult\n");); TagFree(tag_cache_ptr, idx); return; } DEBUG_WRAP(PrintTagNode(idx);); } else { DEBUG_WRAP(DebugMessage(DEBUG_FLOW,"Existing Tag found!\n");); if(idx->metric & TAG_METRIC_SECONDS) returned->seconds = idx->seconds; else returned->seconds += idx->seconds; /* get rid of the new tag since we are using an existing one */ TagFree(tag_cache_ptr, idx); DEBUG_WRAP(PrintTagNode(returned);); } } int CheckTagList(Packet *p, Event *event, void** log_list) { TagNode idx; TagNode *returned = NULL; SFXHASH* taglist = NULL; char create_event = 1; /* check for active tags */ if(!sfxhash_count(host_tag_cache_ptr) && !sfxhash_count(ssn_tag_cache_ptr)) { return 0; } if(p == NULL || !IPH_IS_VALID(p)) { DEBUG_WRAP(DebugMessage(DEBUG_FLOW, "bailing from CheckTagList, p->iph == NULL\n");); return 0; } DEBUG_WRAP(DebugMessage(DEBUG_FLOW,"Host Tags Active: %d Session Tags Active: %d\n", sfxhash_count(host_tag_cache_ptr), sfxhash_count(ssn_tag_cache_ptr));); DEBUG_WRAP(DebugMessage(DEBUG_FLOW, "[*] Checking session tag list (forward)...\n");); sfaddr_copy_to_raw(&idx.key.sip, GET_SRC_IP(p)); sfaddr_copy_to_raw(&idx.key.dip, GET_DST_IP(p)); idx.key.sp = p->sp; idx.key.dp = p->dp; /* check for session tags... */ returned = (TagNode *) sfxhash_find(ssn_tag_cache_ptr, &idx); if(returned == NULL) { sfaddr_copy_to_raw(&idx.key.dip, GET_SRC_IP(p)); sfaddr_copy_to_raw(&idx.key.sip, GET_DST_IP(p)); idx.key.dp = p->sp; idx.key.sp = p->dp; DEBUG_WRAP(DebugMessage(DEBUG_FLOW, " Checking session tag list (reverse)...\n");); returned = (TagNode *) sfxhash_find(ssn_tag_cache_ptr, &idx); if(returned == NULL) { DEBUG_WRAP(DebugMessage(DEBUG_FLOW, " Checking host tag list " "(forward)...\n");); returned = (TagNode *) sfxhash_find(host_tag_cache_ptr, &idx); if(returned == NULL) { /* ** Only switch sip, because that's all we check for ** the host tags. */ sfaddr_copy_to_raw(&idx.key.sip, GET_SRC_IP(p)); returned = (TagNode *) sfxhash_find(host_tag_cache_ptr, &idx); } if(returned != NULL) { DEBUG_WRAP(DebugMessage(DEBUG_FLOW," [*!*] Found host node\n");); taglist = host_tag_cache_ptr; } } else { DEBUG_WRAP(DebugMessage(DEBUG_FLOW," [*!*] Found session node\n");); taglist = ssn_tag_cache_ptr; } } else { DEBUG_WRAP(DebugMessage(DEBUG_FLOW," [*!*] Found session node\n");); taglist = ssn_tag_cache_ptr; } if(returned != NULL) { DEBUG_WRAP(DebugMessage(DEBUG_FLOW, " ! Found tag node !\n");); returned->last_access = p->pkth->ts.tv_sec; returned->pkt_count++; if ( returned->metric & TAG_METRIC_SECONDS ) { if(p->pkth->ts.tv_sec > returned->seconds) { returned->metric = 0; create_event = 0; } } if ( returned->metric & TAG_METRIC_BYTES ) { int n = p->pkth->caplen; if ( n < returned->bytes ) returned->bytes -= n; else returned->metric = 0; } if ( returned->metric & TAG_METRIC_PACKETS ) { if ( returned->packets > 1 ) returned->packets--; else returned->metric = 0; } if ( !(returned->metric & TAG_METRIC_UNLIMITED) ) { /* Check whether or not to actually log an event. * This is used to prevent a poorly written tag rule * from DOSing a backend event processors on high * bandwidth sensors. */ /* Use the global max. */ /* If its non-0, check count for this tag node */ if ( ScTaggedPacketLimit() && returned->pkt_count >= ScTaggedPacketLimit() ) { returned->metric = 0; } } if ( create_event ) { /* set the event info */ SetEvent(event, GENERATOR_TAG, TAG_LOG_PKT, 1, 1, 1, #if !defined(FEAT_OPEN_APPID) returned->event_id); #else /* defined(FEAT_OPEN_APPID) */ returned->event_id, NULL); #endif /* defined(FEAT_OPEN_APPID) */ /* set event reference details */ event->ref_time.tv_sec = returned->event_time.tv_sec; event->ref_time.tv_usec = returned->event_time.tv_usec; event->event_reference = returned->event_id | ScEventLogId(); *log_list = returned->log_list; } if ( !returned->metric ) { DEBUG_WRAP(DebugMessage(DEBUG_FLOW, " Prune condition met for tag, removing from list\n");); if (sfxhash_remove(taglist, returned) != SFXHASH_OK) { LogMessage("WARNING: failed to remove tagNode from hash.\n"); } } } if ( (u_int)(p->pkth->ts.tv_sec) > last_prune_time + TAG_PRUNE_QUANTUM ) { DEBUG_WRAP(DebugMessage(DEBUG_FLOW, "Exceeded Prune Quantum, pruning tag trees\n");); PruneTagCache(p->pkth->ts.tv_sec, 0); last_prune_time = p->pkth->ts.tv_sec; } if ( returned && create_event ) return 1; return 0; } static int PruneTagCache(uint32_t thetime, int mustdie) { int pruned = 0; if (mustdie == 0) { if(sfxhash_count(ssn_tag_cache_ptr) != 0) { pruned = PruneTime(ssn_tag_cache_ptr, thetime); } if(sfxhash_count(host_tag_cache_ptr) != 0) { pruned += PruneTime(host_tag_cache_ptr, thetime); } } else { TagNode *lru_node = NULL; while (pruned < mustdie && (sfxhash_count(ssn_tag_cache_ptr) > 0 || sfxhash_count(host_tag_cache_ptr) > 0)) { if ((lru_node = (TagNode *)sfxhash_lru(ssn_tag_cache_ptr)) != NULL) { if (sfxhash_remove(ssn_tag_cache_ptr, lru_node) != SFXHASH_OK) { LogMessage("WARNING: failed to remove tagNode from hash.\n"); } pruned++; } if ((lru_node = (TagNode *)sfxhash_lru(host_tag_cache_ptr)) != NULL) { if (sfxhash_remove(host_tag_cache_ptr, lru_node) != SFXHASH_OK) { LogMessage("WARNING: failed to remove tagNode from hash.\n"); } pruned++; } } } return pruned; } static int PruneTime(SFXHASH* tree, uint32_t thetime) { int pruned = 0; TagNode *lru_node = NULL; while ((lru_node = (TagNode *)sfxhash_lru(tree)) != NULL) { if ((lru_node->last_access + TAG_PRUNE_QUANTUM) < thetime) { if (sfxhash_remove(tree, lru_node) != SFXHASH_OK) { LogMessage("WARNING: failed to remove tagNode from hash.\n"); } pruned++; } else { break; } } return pruned; } void SetTags(Packet *p, OptTreeNode *otn, RuleTreeNode *rtn, uint16_t event_id) { DEBUG_WRAP(DebugMessage(DEBUG_FLOW, "Setting tags\n");); if(otn != NULL && otn->tag != NULL) { if (otn->tag->tag_type != 0) { void* log_list = rtn ? rtn->listhead : NULL; switch(otn->tag->tag_type) { case TAG_SESSION: DEBUG_WRAP(DebugMessage(DEBUG_FLOW,"Setting session tag:\n"); DebugMessage(DEBUG_FLOW,"SIP: %s SP: %d ", sfip_ntoa(GET_SRC_IP(p)), p->sp); DebugMessage(DEBUG_FLOW,"DIP: %s DP: %d\n", sfip_ntoa(GET_DST_IP(p)),p->dp);); TagSession(p, otn->tag, p->pkth->ts.tv_sec, event_id, log_list); break; case TAG_HOST: DEBUG_WRAP(DebugMessage(DEBUG_FLOW,"Setting host tag:\n"); DebugMessage(DEBUG_FLOW,"SIP: %s SP: %d ", sfip_ntoa(GET_SRC_IP(p)),p->sp); DebugMessage(DEBUG_FLOW, "DIP: %s DP: %d\n", sfip_ntoa(GET_DST_IP(p)),p->dp);); TagHost(p, otn->tag, p->pkth->ts.tv_sec, event_id, log_list); break; default: LogMessage("WARNING: Trying to tag with unknown " "tag type.\n"); break; } } } return; } snort-2.9.15.1/src/tag.h0000644000175200017520000000313013571422607011560 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifndef __TAG_H__ #define __TAG_H__ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "rules.h" #include "treenodes.h" #include "event.h" #include "decode.h" #define TAG_SESSION 1 #define TAG_HOST 2 #define TAG_HOST_SRC 3 #define TAG_HOST_DST 4 #define TAG_METRIC_SECONDS 0x01 #define TAG_METRIC_PACKETS 0x02 #define TAG_METRIC_BYTES 0x04 #define TAG_METRIC_UNLIMITED 0x08 #define TAG_METRIC_SESSION 0x10 void InitTag(void); void CleanupTag(void); int CheckTagList(Packet *, Event *, void**); void SetTags(Packet *, OptTreeNode *, RuleTreeNode *, uint16_t); void TagCacheReset(void); #endif /* __TAG_H__ */ snort-2.9.15.1/src/util.c0000644000175200017520000020431413571422607011764 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #ifndef WIN32 #include #include #include #include #include #include #endif /* !WIN32 */ #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_MALLINFO #include static struct mallinfo mi; #endif #ifndef WIN32 #include #include #include #include #endif /* !WIN32 */ #include #ifdef HAVE_STRINGS_H #include #endif #include #include "snort.h" #include "mstring.h" #include "snort_debug.h" #include "util.h" #include "parser.h" #include "sfdaq.h" #include "build.h" #include "plugbase.h" #include "sf_types.h" #include "sflsq.h" #include "pcre.h" #include "mpse.h" #include "ppm.h" #include "active.h" #include "packet_time.h" #include "control/sfcontrol.h" #ifdef TARGET_BASED #include "sftarget_reader.h" #endif #ifdef SIDE_CHANNEL #include "sidechannel.h" #endif #ifdef WIN32 #include "win32/WIN32-Code/name.h" #endif #include "stream_common.h" #ifdef PATH_MAX #define PATH_MAX_UTIL PATH_MAX #else #define PATH_MAX_UTIL 1024 #endif /* PATH_MAX */ extern PreprocStatsFuncNode *preproc_stats_funcs; // 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 /**************************************************************************** * Store interesting data in memory that would not otherwise be visible * in a CORE(5) file ***************************************************************************/ #define SNORT_VERSION_STRING ("### Snort Version "VERSION" Build "BUILD"\n") #define SNORT_VERSION_STRLEN sizeof(SNORT_VERSION_STRING) char __snort_version_string[SNORT_VERSION_STRLEN]; void StoreSnortInfoStrings( void ) { strncpy(__snort_version_string, SNORT_VERSION_STRING, sizeof(__snort_version_string)); } #undef SNORT_VERSION_STRING #undef SNORT_VERSION_STRLEN /**************************************************************************** * * 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; const char * zlib_ver; info = getenv("HOSTTYPE"); if( !info ) { info=""; } pcre_ver = pcre_version(); zlib_ver = zlib_version; LogMessage("\n"); LogMessage(" ,,_ -*> Snort! <*-\n"); LogMessage(" o\" )~ Version %s%s (Build %s) %s\n", VERSION, #ifdef GRE " GRE", #else "", #endif BUILD, info); LogMessage(" '''' By Martin Roesch & The Snort Team: http://www.snort.org/contact#team\n"); LogMessage(" Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved.\n"); LogMessage(" Copyright (C) 1998-2013 Sourcefire, Inc., et al.\n"); #ifdef HAVE_PCAP_LIB_VERSION LogMessage(" Using %s\n", pcap_lib_version()); #endif LogMessage(" Using PCRE version: %s\n", pcre_ver); LogMessage(" Using ZLIB version: %s\n", zlib_ver); 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.. */ memset((char *) &tz, 0, 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(!lt) { /* Invalid time, set to 0*/ s = 0; Time = 0; lt = gmtime(&Time); } if (ScOutputIncludeYear()) { int year = (lt->tm_year >= 100) ? (lt->tm_year - 100) : lt->tm_year; (void) SnortSnprintf(timebuf, TIMEBUF_SIZE, "%02d/%02d/%02d-%02d:%02d:%02d.%06u ", lt->tm_mon + 1, lt->tm_mday, year, 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: ErrorMessageThrottled(ThrottleInfo *,const char *, ...) * * Purpose: Print a message to stderr, and throttle when * too many messages are printed. * * Arguments: throttleInfo => point to the saved throttle state information * format => the formatted error string to print out * ... => format commands/fillers * * Returns: void function */ void ErrorMessageThrottled(ThrottleInfo *throttleInfo, const char *format,...) { char buf[STD_BUF+1]; va_list ap; time_t current_time = packet_time(); if ((snort_conf == NULL)||(!throttleInfo)) return; if (!ScCheckInternalLogLevel(INTERNAL_LOG_LEVEL__ERROR)) return; throttleInfo->count++; DEBUG_WRAP(DebugMessage(DEBUG_INIT,"current_time: %d, throttle (%p): count "STDu64", last update: %d\n", (int)current_time, throttleInfo, throttleInfo->count, (int)throttleInfo->lastUpdate );) /*Note: we only output the first error message, * and the statistics after at least duration_to_log seconds * when the same type of error message is printed out again */ if (current_time - (time_t)throttleInfo->duration_to_log > throttleInfo->lastUpdate) { int index; va_start(ap, format); index = vsnprintf(buf, STD_BUF, format, ap); va_end(ap); if (index && (throttleInfo->count > 1)) { snprintf(&buf[index - 1], STD_BUF-index, " (suppressed "STDu64" times in the last %d seconds).\n", throttleInfo->count, (int) (current_time - throttleInfo->lastUpdate)); } ErrorMessage("%s",buf); throttleInfo->lastUpdate = current_time; throttleInfo->count = 0; } } /* * 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 (!ScCheckInternalLogLevel(INTERNAL_LOG_LEVEL__MESSAGE)) 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: WarningMessage(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 WarningMessage(const char *format,...) { char buf[STD_BUF+1]; va_list ap; if (snort_conf == NULL) return; if (!ScCheckInternalLogLevel(INTERNAL_LOG_LEVEL__WARNING)) return; va_start(ap, format); if (ScDaemonMode() || ScLogSyslog()) { vsnprintf(buf, STD_BUF, format, ap); buf[STD_BUF] = '\0'; syslog(LOG_DAEMON | LOG_WARNING, "%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 */ static int already_fatal = 0; /* * Function: SnortFatalExit(void) * * Purpose: When a fatal error occurs, this function cleanly * shuts down the program * * Arguments: none * * Returns: void function */ NORETURN void SnortFatalExit(void) { // ----------------------------- // bail now if we are reentering if ( already_fatal ) exit(1); else already_fatal = 1; if (!snort_conf || (!ScDaemonMode() && !ScLogSyslog())) fprintf(stderr,"Fatal Error, Quitting..\n"); if ( InMainThread() || SnortIsInitializing() ) { DAQ_Abort(); exit(1); } else { DAQ_BreakLoop(1); #ifndef WIN32 pthread_exit(NULL); #endif } } /* * 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; // ----------------------------- // bail now if we are reentering if ( already_fatal ) exit(1); else already_fatal = 1; // ----------------------------- 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 } if ( InMainThread() || SnortIsInitializing() ) { DAQ_Abort(); exit(1); } else { DAQ_BreakLoop(1); #ifndef WIN32 pthread_exit(NULL); #endif } } /**************************************************************************** * * 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(const char *intf, pid_t pid) { struct stat pt; #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 */ if ((stat(_PATH_VARRUN, &pt) == -1) || !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)); if ((stat(snort_conf->pid_path, &pt) == -1) || !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"); } if (ScNoInterfacePidFile()) { SnortSnprintf(snort_conf->pid_filename, sizeof(snort_conf->pid_filename), "%s/snort%s.pid", snort_conf->pid_path, snort_conf->pidfile_suffix); } else { 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, (int)pid); } /* Give desired user control over lock file */ fchown(fileno(pid_lockfile), ScUid(), ScGid()); } } #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", (int)pid, snort_conf->pid_filename); fprintf(pid_file, "%d\n", (int)pid); fflush(pid_file); #ifndef WIN32 /* Give desired user control over pid file */ fchown(fileno(pid_file), ScUid(), ScGid()); #endif } else { char errBuf[STD_BUF]; #ifdef WIN32 SnortSnprintf(errBuf, STD_BUF, "%s", strerror(errno)); #else strerror_r(errno, errBuf, STD_BUF); #endif ErrorMessage("Failed to create pid file %s, Error: %s", snort_conf->pid_filename, errBuf); 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 ( !DAQ_Unprivileged() ) { LogMessage("WARNING: cannot set uid and gid - %s DAQ does not" " support unprivileged operation.\n", DAQ_GetType()); return; } if (setgid(group_id) < 0) FatalError("Cannot set gid: %d\n", group_id); LogMessage("Set gid to %d\n", group_id); } if ((user_id != -1) && (getuid() != (uid_t)user_id)) { if ( !DAQ_Unprivileged() ) { LogMessage("WARNING: cannot set uid and gid - %s DAQ does not" " support unprivileged operation.\n", DAQ_GetType()); return; } if (setuid(user_id) < 0) FatalError("Can not set uid: %d\n", user_id); LogMessage("Set uid to %d\n", user_id); } #endif /* WIN32 */ } /**************************************************************************** * * Function: InitGroups() * * Purpose: Sets the groups of the process based on the UserID with the * GroupID added * * Arguments: none * * Returns: void function * ****************************************************************************/ void InitGroups(int user_id, int group_id) { #ifndef WIN32 if ((user_id != -1) && (getuid() == 0)) { struct passwd *pw = getpwuid(user_id); if (pw != NULL) { /* getpwuid and initgroups may use the same static buffers */ char *username = SnortStrdup(pw->pw_name); if (initgroups(username, group_id) < 0) { free(username); FatalError("Can not initgroups(%s,%d)", username, group_id); } free(username); } /** Just to be on the safe side... **/ endgrent(); endpwent(); } #endif /* WIN32 */ } //------------------------------------------------------------------------- #define STATS_SEPARATOR \ "===============================================================================" static inline int DisplayCount (char *buf, const char* s, uint64_t n, int size) { return snprintf(buf+size, CS_STATS_BUF_SIZE-size, "%11s: " FMTu64("12") "\n", s, n); } static inline int DisplayStat (char *buf, const char* s, uint64_t n, uint64_t tot, int size) { return snprintf(buf+size, CS_STATS_BUF_SIZE-size, "%11s: " FMTu64("12") " (%7.3f%%)\n", s, n, CalcPct(n, tot)); } static inline void LogCount (const char* s, uint64_t n) { LogMessage("%11s: " FMTu64("12") "\n", s, n); } static inline void LogStat (const char* s, uint64_t n, uint64_t tot) { LogMessage( "%11s: " FMTu64("12") " (%7.3f%%)\n", s, n, CalcPct(n, tot)); } static struct timeval starttime; void TimeStart (void) { gettimeofday(&starttime, NULL); } void TimeStop (void) { uint32_t days = 0, hrs = 0, mins = 0, secs = 0; uint32_t total_secs = 0, tmp = 0; uint64_t pps = 0; struct timeval endtime, difftime; gettimeofday(&endtime, NULL); TIMERSUB(&endtime, &starttime, &difftime); LogMessage("%s\n", STATS_SEPARATOR); LogMessage("Run time for packet processing was %lu.%lu seconds\n", (unsigned long)difftime.tv_sec, (unsigned long)difftime.tv_usec); LogMessage("Snort processed " STDu64 " packets.\n", pc.total_from_daq); tmp = total_secs = (uint32_t)difftime.tv_sec; if ( total_secs < 1 ) total_secs = 1; days = tmp / SECONDS_PER_DAY; tmp = tmp % SECONDS_PER_DAY; hrs = tmp / SECONDS_PER_HOUR; tmp = tmp % SECONDS_PER_HOUR; mins = tmp / SECONDS_PER_MIN; secs = tmp % SECONDS_PER_MIN; LogMessage("Snort ran for %u days %u hours %u minutes %u seconds\n", days, hrs, mins, secs); if ( days > 0 ) { uint64_t n = (pc.total_from_daq / (total_secs / SECONDS_PER_DAY)); LogCount("Pkts/day", n); } if ( hrs > 0 || days > 0 ) { uint64_t n = (pc.total_from_daq / (total_secs / SECONDS_PER_HOUR)); LogCount("Pkts/hr", n); } if ( mins > 0 || hrs > 0 || days > 0 ) { uint64_t n = (pc.total_from_daq / (total_secs / SECONDS_PER_MIN)); LogCount("Pkts/min", n); } pps = (pc.total_from_daq / total_secs); LogCount("Pkts/sec", pps); } //------------------------------------------------------------------------- static const char* Verdicts[MAX_DAQ_VERDICT] = { "Allow", "Block", "Replace", "Whitelist", "Blacklist", #ifdef HAVE_DAQ_VERDICT_RETRY "Ignore", "Retry" #else "Ignore" #endif }; #ifdef HAVE_MALLINFO static void display_mallinfo(void) { mi = mallinfo(); LogMessage("%s\n", STATS_SEPARATOR); LogMessage("Memory usage summary:\n"); LogMessage(" Total non-mmapped bytes (arena): %d\n", mi.arena); LogMessage(" Bytes in mapped regions (hblkhd): %d\n", mi.hblkhd); LogMessage(" Total allocated space (uordblks): %d\n", mi.uordblks); LogMessage(" Total free space (fordblks): %d\n", mi.fordblks); LogMessage(" Topmost releasable block (keepcost): %d\n", mi.keepcost); #ifdef DEBUG LogMessage(" Number of free chunks (ordblks): %d\n", mi.ordblks); LogMessage(" Number of free fastbin blocks (smblks):%d\n", mi.smblks); LogMessage(" Number of mapped regions (hblks): %d\n", mi.hblks); LogMessage(" Max. total allocated space (usmblks): %d\n", mi.usmblks); LogMessage(" Free bytes held in fastbins (fsmblks): %d\n", mi.fsmblks); #endif } #endif void DisplayActionStats (uint16_t type, void *old_context, struct _THREAD_ELEMENT *te, ControlDataSendFunc f) { char buffer[CS_STATS_BUF_SIZE + 1]; int len = 0; int i = 0; uint64_t total = pc.total_processed; uint64_t pkts_recv = pc.total_from_daq; const DAQ_Stats_t* pkt_stats = DAQ_GetStats(); if (total) { // ensure proper counting of log_limit SnortEventqResetCounts(); len += snprintf(buffer, CS_STATS_BUF_SIZE, "Action Stats:\n"); len += DisplayStat(buffer, "Alerts", pc.total_alert_pkts, total, len); len += DisplayStat(buffer, "Logged", pc.log_pkts, total, len); len += DisplayStat(buffer, "Passed", pc.pass_pkts, total, len); len += snprintf(buffer+len, CS_STATS_BUF_SIZE-len, "Limits:\n"); len += DisplayCount(buffer, "Match", pc.match_limit, len); len += DisplayCount(buffer, "Queue", pc.queue_limit, len); len += DisplayCount(buffer, "Log", pc.log_limit, len); len += DisplayCount(buffer, "Event", pc.event_limit, len); len += DisplayCount(buffer, "Alert", pc.alert_limit, len); len += snprintf(buffer+len, CS_STATS_BUF_SIZE-len, "Verdicts:\n"); for ( i = 0; i < MAX_DAQ_VERDICT && len < CS_STATS_BUF_SIZE; i++ ) { const char* s = Verdicts[i]; len += DisplayStat(buffer, s, pkt_stats->verdicts[i], pkts_recv, len); } if ( pc.internal_blacklist ) len += DisplayStat(buffer, "Int Blklst", pc.internal_blacklist, pkts_recv, len); if ( pc.internal_whitelist ) len += DisplayStat(buffer, "Int Whtlst", pc.internal_whitelist, pkts_recv, len); } else { len = snprintf(buffer, CS_STATS_BUF_SIZE, "Action Stats are not available\n Total Action Processed:"FMTu64("12") "\n", total); } if (-1 == f(te, (const uint8_t *)buffer, len)) { LogMessage("Unable to send data to the frontend\n"); } } /* exiting should be 0 for if not exiting, 1 if restarting, and 2 if exiting */ void DropStats(int exiting) { PreprocStatsFuncNode *idx; uint64_t total = pc.total_processed; uint64_t pkts_recv = pc.total_from_daq; const DAQ_Stats_t* pkt_stats = DAQ_GetStats(); /*Display all the memory usage in main arena*/ #ifdef HAVE_MALLINFO display_mallinfo(); #endif #ifdef PPM_MGR PPM_PRINT_SUMMARY(&snort_conf->ppm_cfg); #endif { uint64_t pkts_drop, pkts_out, pkts_inj; pkts_recv = pkt_stats->hw_packets_received; pkts_drop = pkt_stats->hw_packets_dropped; if ( pkts_recv > pkt_stats->packets_filtered + pkt_stats->packets_received ) pkts_out = pkts_recv - pkt_stats->packets_filtered - pkt_stats->packets_received; else pkts_out = 0; pkts_inj = pkt_stats->packets_injected; #ifdef ACTIVE_RESPONSE pkts_inj += Active_GetInjects(); #endif LogMessage("%s\n", STATS_SEPARATOR); LogMessage("Packet I/O Totals:\n"); LogCount("Received", pkts_recv); LogStat("Analyzed", pkt_stats->packets_received, pkts_recv); LogStat("Dropped", pkts_drop, pkts_recv + pkts_drop); LogStat("Filtered", pkt_stats->packets_filtered, pkts_recv); LogStat("Outstanding", pkts_out, pkts_recv); LogCount("Injected", pkts_inj); #ifdef REG_TEST if ( snort_conf->pkt_skip ) LogCount("Skipped", snort_conf->pkt_skip); #endif } LogMessage("%s\n", STATS_SEPARATOR); LogMessage("Breakdown by protocol (includes rebuilt packets):\n"); LogStat("Eth", pc.eth, total); LogStat("VLAN", pc.vlan, total); if (pc.nested_vlan != 0) LogStat("Nested VLAN", pc.nested_vlan, total); LogStat("IP4", pc.ip, total); LogStat("Frag", pc.frags, total); LogStat("ICMP", pc.icmp, total); LogStat("UDP", pc.udp, total); LogStat("TCP", pc.tcp, total); LogStat("IP6", pc.ipv6, total); LogStat("IP6 Ext", pc.ip6ext, total); LogStat("IP6 Opts", pc.ipv6opts, total); LogStat("Frag6", pc.frag6, total); LogStat("ICMP6", pc.icmp6, total); LogStat("UDP6", pc.udp6, total); LogStat("TCP6", pc.tcp6, total); LogStat("Teredo", pc.teredo, total); LogStat("ICMP-IP", pc.embdip, total); #ifndef NO_NON_ETHER_DECODER LogStat("EAPOL", pc.eapol, total); #endif #ifdef GRE LogStat("IP4/IP4", pc.ip4ip4, total); LogStat("IP4/IP6", pc.ip4ip6, total); LogStat("IP6/IP4", pc.ip6ip4, total); LogStat("IP6/IP6", pc.ip6ip6, total); LogStat("GRE", pc.gre, total); LogStat("GRE Eth", pc.gre_eth, total); LogStat("GRE VLAN", pc.gre_vlan, total); LogStat("GRE IP4", pc.gre_ip, total); LogStat("GRE IP6", pc.gre_ipv6, total); LogStat("GRE IP6 Ext", pc.gre_ipv6ext, total); LogStat("GRE PPTP", pc.gre_ppp, total); LogStat("GRE ARP", pc.gre_arp, total); LogStat("GRE IPX", pc.gre_ipx, total); LogStat("GRE Loop", pc.gre_loopback, total); #endif /* GRE */ #ifdef MPLS LogStat("MPLS", pc.mpls, total); #endif LogStat("ARP", pc.arp, total); LogStat("IPX", pc.ipx, total); LogStat("Eth Loop", pc.ethloopback, total); LogStat("Eth Disc", pc.ethdisc, total); LogStat("IP4 Disc", pc.ipdisc, total); LogStat("IP6 Disc", pc.ipv6disc, total); LogStat("TCP Disc", pc.tdisc, total); LogStat("UDP Disc", pc.udisc, total); LogStat("ICMP Disc", pc.icmpdisc, total); LogStat("All Discard", pc.discards, total); LogStat("Other", pc.other, total); LogStat("Bad Chk Sum", pc.invalid_checksums, total); LogStat("Bad TTL", pc.bad_ttl, total); LogStat("S5 G 1", pc.s5tcp1, total); LogStat("S5 G 2", pc.s5tcp2, total); if ( InternalEventIsEnabled(snort_conf->rate_filter_config, INTERNAL_EVENT_SYN_RECEIVED) ) { LogStat("SYN RL Evnt", pc.syn_rate_limit_events, total); LogStat("SYN RL Drop", pc.syn_rate_limit_drops, total); } LogCount("Total", total); if ( !ScPacketDumpMode() && !ScPacketLogMode() ) { int i; // ensure proper counting of log_limit SnortEventqResetCounts(); LogMessage("%s\n", STATS_SEPARATOR); LogMessage("Action Stats:\n"); LogStat("Alerts", pc.total_alert_pkts, total); LogStat("Logged", pc.log_pkts, total); LogStat("Passed", pc.pass_pkts, total); LogMessage("Limits:\n"); LogCount("Match", pc.match_limit); LogCount("Queue", pc.queue_limit); LogCount("Log", pc.log_limit); LogCount("Event", pc.event_limit); LogCount("Alert", pc.alert_limit); LogMessage("Verdicts:\n"); for ( i = 0; i < MAX_DAQ_VERDICT; i++ ) { const char* s = Verdicts[i]; LogStat(s, pkt_stats->verdicts[i], pkts_recv); } if ( pc.internal_blacklist > 0 ) LogStat("Int Blklst", pc.internal_blacklist, pkts_recv); if ( pc.internal_whitelist > 0 ) LogStat("Int Whtlst", pc.internal_whitelist, pkts_recv); } #ifdef TARGET_BASED if (ScIdsMode() && IsAdaptiveConfigured()) { LogMessage("%s\n", STATS_SEPARATOR); LogMessage("Attribute Table Stats:\n"); LogCount("Number Entries", (uint64_t)SFAT_NumberOfHosts()); LogCount("Table Reloaded", pc.attribute_table_reloads); } #endif /* TARGET_BASED */ //mpse_print_qinfo(); #ifndef NO_NON_ETHER_DECODER #ifdef DLT_IEEE802_11 if(DAQ_GetBaseProtocol() == DLT_IEEE802_11) { LogMessage("%s\n", STATS_SEPARATOR); LogMessage("Wireless Stats:\n"); LogMessage("Breakdown by type:\n"); LogStat("Management Packets", pc.wifi_mgmt, total); LogStat("Control Packets", pc.wifi_control, total); LogStat("Data Packets", pc.wifi_data, total); } #endif /* DLT_IEEE802_11 */ #endif // NO_NON_ETHER_DECODER for (idx = preproc_stats_funcs; idx != NULL; idx = idx->next) { LogMessage("%s\n", STATS_SEPARATOR); idx->func(exiting ? 1 : 0); } #ifdef SIDE_CHANNEL SideChannelStats(exiting, STATS_SEPARATOR); #endif /* SIDE_CHANNEL */ LogMessage("%s\n", STATS_SEPARATOR); } /**************************************************************************** * * 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, strerror(errno)); if(fstat(fd, &buf) < 0) FatalError("can't stat %s: %s\n", fname, 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, 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 volatile int parent_wait = 1; static void SigChildReadyHandler(int signal) { 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 cpid; if (ScDaemonRestart()) return; LogMessage("Initializing daemon mode\n"); /* Don't daemonize if we've already daemonized and * received a SIGNAL_SNORT_RELOAD. */ if(getppid() != 1) { /* Register signal handler that parent can trap signal */ SnortAddSignal(SIGNAL_SNORT_CHILD_READY, SigChildReadyHandler, 1); if (errno != 0) errno = 0; /* now fork the child */ printf("Spawning daemon child...\n"); cpid = fork(); if(cpid > 0) { /* Continue waiting until receiving signal from child */ int status; /* Parent */ printf("My daemon child %d lives...\n", cpid); /* Don't exit quite yet. Wait for the child * to signal that is there and created the PID * file. */ do { #ifdef DEBUG printf("Parent waiting for child...\n"); #endif sleep(1); } while (parent_wait); if (waitpid(cpid, &status, WNOHANG) == cpid) { if (WIFEXITED(status)) { LogMessage("Child exited unexpectedly\n"); exit_val = -1; } else if (WIFSIGNALED(status)) { LogMessage("Child terminated unexpectedly\n"); exit_val = -2; } } #ifdef DEBUG printf("Child terminated unexpectedly (%d)\n", status); #endif printf("Daemon parent exiting (%d)\n", exit_val); exit(exit_val); /* parent */ } if(cpid < 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 if (dup(0)) {} /* stdout, fd 0 => fd 1 */ if (dup(0)) {} /* stderr, fd 0 => fd 2 */ SignalWaitingParent(); #endif /* ! WIN32 */ } /* Signal the parent that child is ready */ void SignalWaitingParent(void) { #ifndef WIN32 pid_t ppid = getppid(); #ifdef DEBUG printf("Signaling parent %d from child %d\n", ppid, getpid()); #endif if (kill(ppid, SIGNAL_SNORT_CHILD_READY)) { LogMessage("Daemon initialized, failed to signal parent pid: " "%d, failure: %d, %s\n", ppid, errno, strerror(errno)); } else { LogMessage("Daemon initialized, signaled parent pid: %d\n", ppid); } #endif } /* 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 || (slen == 0) || !*s || !accept) 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 || (slen == 0) || !*s || !searchstr) 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--; } return s; } /* * Find first occurrence of substring in s, ignore case. */ const char *SnortStrcasestr(const char *s, int slen, const char *substr) { char ch, nc; int len; if (!s || (slen == 0) || !*s || !substr) return NULL; if ((ch = *substr++) != 0) { ch = tolower((char)ch); len = strlen(substr); do { do { if ((nc = *s++) == 0) { return NULL; } slen--; if(slen == 0) return NULL; } while ((char)tolower((uint8_t)nc) != ch); if(slen - len < 0) return NULL; } while (strncasecmp(s, substr, len) != 0); s--; } return s; } 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(logdir != NULL) free(logdir); #if 0 /* XXX XXX */ /* install the I can't do this signal handler */ signal(SIGNAL_SNORT_RELOAD, 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)); continue; } 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: 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; } /**************************************************************************** * * Function: fasthex(u_char *xdata, int length) * * Purpose: Outputs a purdy fugly hex output, only used by mstring with * DEBUG_MSGS enabled. * * 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 *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 */ 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) || (val > INT_MAX) || (val < INT_MIN) || (*endptr != '\0')) FatalError("%s: Invalid integer input: %s\n", etext, s); return (int)val; } /* * Fatal Integer Parser * Ascii to Integer conversion with fatal error support */ unsigned 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) || (val > UINT_MAX) || (*endptr != '\0')) FatalError("%s: Invalid integer input: %s\n", etext, s); return (unsigned int)val; } unsigned 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 (unsigned int)val; } char * ObfuscateIpToText(sfaddr_t *ip) { 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; if (buf_num) ip_buf = ip_buf2; else ip_buf = ip_buf1; buf_num ^= 1; ip_buf[0] = 0; if (ip == NULL) return ip_buf; if (!sfip_is_set(&snort_conf->obfuscation_net)) { if (sfaddr_family(ip) == AF_INET6) SnortSnprintf(ip_buf, buf_size, "x:x:x:x::x:x:x:x"); else SnortSnprintf(ip_buf, buf_size, "xxx.xxx.xxx.xxx"); } else { sfaddr_t tmp; char *tmp_buf; IP_COPY_VALUE(tmp, ip); if (sfip_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); } 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"); } int CheckValueInRange(const char *value_str, 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; } snort-2.9.15.1/src/util.h0000644000175200017520000002640613571422607011775 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __UTIL_H__ #define __UTIL_H__ #define TIMEBUF_SIZE 26 #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifndef WIN32 # include # include # ifdef LINUX # include # endif #endif #include #include #include #ifdef HAVE_STRINGS_H #include #endif #include #include "sf_types.h" #include "sflsq.h" #include "sfutil/sf_ipvar.h" #include "ipv6_port.h" #include "control/sfcontrol.h" /* Macros *********************************************************************/ /* specifies that a function does not return * used for quieting Visual Studio warnings */ #ifdef _MSC_VER # if _MSC_VER >= 1400 # define NORETURN __declspec(noreturn) # else # define NORETURN # endif #else # define NORETURN #endif #if !defined(__GNUC__) || __GNUC__ < 2 || \ (__GNUC__ == 2 && __GNUC_MINOR__ < 5) #define __attribute__(x) /* delete __attribute__ if non-gcc or gcc1 */ #endif #define SNORT_SNPRINTF_SUCCESS 0 #define SNORT_SNPRINTF_TRUNCATION 1 #define SNORT_SNPRINTF_ERROR -1 #define SNORT_STRNCPY_SUCCESS 0 #define SNORT_STRNCPY_TRUNCATION 1 #define SNORT_STRNCPY_ERROR -1 #define SNORT_STRNLEN_ERROR -1 #define SECONDS_PER_DAY 86400 /* number of seconds in a day */ #define SECONDS_PER_HOUR 3600 /* number of seconds in a hour */ #define SECONDS_PER_MIN 60 /* number of seconds in a minute */ #define STD_BUF 1024 #define COPY4(x, y) \ x[0] = y[0]; x[1] = y[1]; x[2] = y[2]; x[3] = y[3]; #define COPY16(x,y) \ x[0] = y[0]; x[1] = y[1]; x[2] = y[2]; x[3] = y[3]; \ x[4] = y[4]; x[5] = y[5]; x[6] = y[6]; x[7] = y[7]; \ x[8] = y[8]; x[9] = y[9]; x[10] = y[10]; x[11] = y[11]; \ x[12] = y[12]; x[13] = y[13]; x[14] = y[14]; x[15] = y[15]; /* Externs ********************************************************************/ extern uint32_t *netmasks; /* Data types *****************************************************************/ typedef struct _IntervalStats { uint64_t recv, recv_total; uint64_t drop, drop_total; uint64_t processed, processed_total; uint64_t tcp, tcp_total; uint64_t udp, udp_total; uint64_t icmp, icmp_total; uint64_t arp, arp_total; uint64_t ipx, ipx_total; uint64_t eapol, eapol_total; uint64_t ipv6, ipv6_total; uint64_t ethloopback, ethloopback_total; uint64_t other, other_total; uint64_t frags, frags_total; uint64_t discards, discards_total; uint64_t frag_trackers, frag_trackers_total; uint64_t frag_rebuilt, frag_rebuilt_total; uint64_t frag_element, frag_element_total; uint64_t frag_incomp, frag_incomp_total; uint64_t frag_timeout, frag_timeout_total; uint64_t frag_mem_faults, frag_mem_faults_total; uint64_t tcp_str_packets, tcp_str_packets_total; uint64_t tcp_str_trackers, tcp_str_trackers_total; uint64_t tcp_str_flushes, tcp_str_flushes_total; uint64_t tcp_str_segs_used, tcp_str_segs_used_total; uint64_t tcp_str_segs_queued, tcp_str_segs_queued_total; uint64_t tcp_str_mem_faults, tcp_str_mem_faults_total; #ifdef GRE uint64_t ip4ip4, ip4ip4_total; uint64_t ip4ip6, ip4ip6_total; uint64_t ip6ip4, ip6ip4_total; uint64_t ip6ip6, ip6ip6_total; uint64_t gre, gre_total; uint64_t gre_ip, gre_ip_total; uint64_t gre_eth, gre_eth_total; uint64_t gre_arp, gre_arp_total; uint64_t gre_ipv6, gre_ipv6_total; uint64_t gre_ipx, gre_ipx_total; uint64_t gre_loopback, gre_loopback_total; uint64_t gre_vlan, gre_vlan_total; uint64_t gre_ppp, gre_ppp_total; #endif #ifdef DLT_IEEE802_11 uint64_t wifi_mgmt, wifi_mgmt_total; uint64_t wifi_control, wifi_control_total; uint64_t wifi_data, wifi_data_total; #endif } IntervalStats; /* Public function prototypes *************************************************/ void StoreSnortInfoStrings(void); int DisplayBanner(void); int gmt2local(time_t); void ts_print(register const struct timeval *, char *); char *copy_argv(char **); void strip(char *); double CalcPct(uint64_t, uint64_t); void GoDaemon(void); void SignalWaitingParent(void); void CheckLogDir(void); char *read_infile(char *); void CleanupProtoNames(void); void CreatePidFile(const char *, pid_t); void ClosePidFile(void); void SetUidGid(int, int); void InitGroups(int, int); void SetChroot(char *, char **); void DropStats(int); /* Function For Displaying in SFR CLI */ void DisplayActionStats (uint16_t type, void *old_context, struct _THREAD_ELEMENT *te, ControlDataSendFunc f); void TimeStart(void); void TimeStop(void); #ifndef __GNUC__ #define __attribute__(x) /*NOTHING*/ #endif void LogMessage(const char *, ...) __attribute__((format (printf, 1, 2))); void WarningMessage(const char *, ...) __attribute__((format (printf, 1, 2))); void ErrorMessage(const char *, ...) __attribute__((format (printf, 1, 2))); typedef struct _ThrottleInfo { time_t lastUpdate; /*Within this duration (in seconds), maximal one distinct message is logged*/ uint32_t duration_to_log; uint64_t count; }ThrottleInfo; void ErrorMessageThrottled(ThrottleInfo*,const char *, ...) __attribute__((format (printf, 2, 3))); NORETURN void FatalError(const char *, ...) __attribute__((format (printf, 1, 2))); NORETURN void SnortFatalExit(void); int SnortSnprintf(char *, size_t, const char *, ...) __attribute__((format (printf, 3, 4))); int SnortSnprintfAppend(char *, size_t, const char *, ...) __attribute__((format (printf, 3, 4))); char *SnortStrdup(const char *); int SnortStrncpy(char *, const char *, size_t); char *SnortStrndup(const char *, size_t); int SnortStrnlen(const char *, int); const char *SnortStrnPbrk(const char *s, int slen, const char *accept); const char *SnortStrnStr(const char *s, int slen, const char *searchstr); const char *SnortStrcasestr(const char *s, int slen, const char *substr); int CheckValueInRange(const char *value_str, char *option, unsigned long lo, unsigned long hi, unsigned long *value); void *SnortAlloc2(size_t, const char *, ...); char *CurrentWorkingDir(void); char *GetAbsolutePath(char *dir); char *StripPrefixDir(char *prefix, char *dir); void PrintPacketData(const uint8_t *, const uint32_t); char * ObfuscateIpToText(sfaddr_t *); #ifndef WIN32 SF_LIST * SortDirectory(const char *); int GetFilesUnderDir(const char *, SF_QUEUE *, const char *); #endif /*********************************************************** If you use any of the functions in this section, you need to call free() on the char * that is returned after you are done using it. Otherwise, you will have created a memory leak. ***********************************************************/ char *hex(const u_char *, int); char *fasthex(const u_char *, int); int xatol(const char *, const char *); unsigned int xatou(const char *, const char *); unsigned int xatoup(const char *, const char *); // return > 0 static inline void* SnortMalloc (unsigned long size) { void* pv = malloc(size); if ( pv ) return pv; FatalError("Unable to allocate memory! (%lu requested)\n", size); return NULL; } static inline void* SnortAlloc (unsigned long size) { void* pv = calloc(size, sizeof(char)); if ( pv ) return pv; FatalError("Unable to allocate memory! (%lu requested)\n", size); return NULL; } static inline long SnortStrtol(const char *nptr, char **endptr, int base) { long iRet; errno = 0; iRet = strtol(nptr, endptr, base); return iRet; } static inline unsigned long SnortStrtoul(const char *nptr, char **endptr, int base) { unsigned long iRet; errno = 0; iRet = strtoul(nptr, endptr, base); return iRet; } // Checks to make sure we're not going to evaluate a negative number for which // strtoul() gladly accepts and parses returning an underflowed wrapped unsigned // long without error. // // Buffer passed in MUST be NULL terminated. // // Returns // int // -1 if buffer is nothing but spaces or first non-space character is a // negative sign. Also if errno is EINVAL (which may be due to a bad // base) or there was nothing to convert. // 0 on success // // Populates pointer to uint32_t value passed in which should // only be used on a successful return from this function. // // Also will set errno to ERANGE on a value returned from strtoul that is // greater than UINT32_MAX, but still return success. // static inline int SnortStrToU32(const char *buffer, char **endptr, uint32_t *value, int base) { unsigned long int tmp; if ((buffer == NULL) || (endptr == NULL) || (value == NULL)) return -1; // Only positive numbers should be processed and strtoul will // eat up white space and process '-' and '+' so move past // white space and check for a negative sign. while (isspace((int)*buffer)) buffer++; // If all spaces or a negative sign is found, return error. // XXX May also want to exclude '+' as well. if ((*buffer == '\0') || (*buffer == '-')) return -1; tmp = SnortStrtoul(buffer, endptr, base); // The user of the function should check for ERANGE in errno since this // function can be used such that an ERANGE error is acceptable and // value gets truncated to UINT32_MAX. if ((errno == EINVAL) || (*endptr == buffer)) return -1; // If value is greater than a UINT32_MAX set value to UINT32_MAX // and errno to ERANGE if (tmp > UINT32_MAX) { tmp = UINT32_MAX; errno = ERANGE; } *value = (uint32_t)tmp; 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; } #ifndef HAVE_GETTID static inline pid_t gettid(void) { #if defined(LINUX) && defined(SYS_gettid) return syscall(SYS_gettid); #else return getpid(); #endif } #endif #endif /*__UTIL_H__*/ snort-2.9.15.1/src/detect.c0000644000175200017520000011750413571422607012263 00000000000000/* $Id$ */ /* ** Copyright (C) 1998-2002 Martin Roesch ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Dan Roelker ** Marc Norton ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** ** NOTES ** 5.7.02: Added interface for new detection engine. (Norton/Roelker) ** */ #define FASTPKT /* I N C L U D E S **********************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "snort.h" #include "detect.h" #include "plugbase.h" #include "snort_debug.h" #include "util.h" #include "mstring.h" #include "tag.h" #include "pcrm.h" #include "fpcreate.h" #include "fpdetect.h" #include "sfthreshold.h" #include "event_wrapper.h" #include "event_queue.h" #include "obfuscation.h" #include "profiler.h" #include "session_api.h" #include "session_common.h" #include "stream_api.h" #include "active.h" #include "signature.h" #include "ipv6_port.h" #include "ppm.h" #include "sf_types.h" #include "active.h" #include "detection_util.h" #include "preprocids.h" #if defined(FEAT_OPEN_APPID) #include "sp_appid.h" #include "appIdApi.h" #endif /* defined(FEAT_OPEN_APPID) */ #ifdef PORTLISTS #include "sfutil/sfportobject.h" #endif #ifdef PERF_PROFILING PreprocStats detectPerfStats; #endif #ifdef TARGET_BASED #include "target-based/sftarget_protocol_reference.h" #endif #include "sfPolicy.h" /* #define ITERATIVE_ENGINE */ OptTreeNode *otn_tmp = NULL; /* OptTreeNode temp ptr */ int do_detect; int do_detect_content; uint16_t event_id; static char check_tags_flag; static int CheckTagging(Packet *); #ifdef PERF_PROFILING PreprocStats eventqPerfStats; #endif static inline int preprocHandlesProto( Packet *p, PreprocEvalFuncNode *ppn ) { return ( ( p->proto_bits & ppn->proto_mask ) || ( ppn->proto_mask == PROTO_BIT__ALL ) ); } static inline bool processDecoderAlertsActionQ( Packet *p ) { // with policy selected, process any decoder alerts and queued actions DecodePolicySpecific(p); // actions are queued only for IDS case sfActionQueueExecAll(decoderActionQ); return true; } static void DispatchPreprocessors( Packet *p, tSfPolicyId policy_id, SnortPolicy *policy ) { SessionControlBlock *scb = NULL; PreprocEvalFuncNode *ppn; PreprocEnableMask pps_enabled_foo; bool alerts_processed = false; #if defined(DAQ_VERSION) && DAQ_VERSION > 9 uint64_t start=0, end=0; #endif // No expected sessions yet. p->expectedSession = NULL; // until we are in a Session context dispatch preprocs from the policy list if there is one p->cur_pp = policy->preproc_eval_funcs; if( p->cur_pp == NULL ) { alerts_processed = processDecoderAlertsActionQ( p ); LogMessage("WARNING: No preprocessors configured for policy %d.\n", policy_id); return; } pps_enabled_foo = policy->pp_enabled[ p->dp ] | policy->pp_enabled[ p->sp ]; EnablePreprocessors( p, pps_enabled_foo ); do { ppn = p->cur_pp; p->cur_pp = ppn->next; // if packet has no data and we are up to APP preprocs then get out if( p->dsize == 0 && ppn->priority >= PRIORITY_APPLICATION ) break; if ( preprocHandlesProto( p, ppn ) && IsPreprocessorEnabled( p, ppn->preproc_bit ) ) { #if defined(DAQ_VERSION) && DAQ_VERSION > 9 if (p->pkth && (p->pkth->flags & DAQ_PKT_FLAG_DEBUG_ON)) { get_clockticks(start); ppn->func( p, ppn->context ); get_clockticks(end); print_flow(p,NULL,ppn->preproc_id,start,end); } else ppn->func( p, ppn->context ); #else ppn->func( p, ppn->context ); #endif } if( !alerts_processed && ( p->ips_os_selected || ppn->preproc_id == PP_FW_RULE_ENGINE ) ) alerts_processed = processDecoderAlertsActionQ( p ); if( scb == NULL && p->ssnptr != NULL ) scb = ( SessionControlBlock * ) p->ssnptr; // if we now have session, update enabled pps if changed by previous preproc if( scb != NULL && pps_enabled_foo != scb->enabled_pps ) { EnablePreprocessors( p, scb->enabled_pps ); pps_enabled_foo = scb->enabled_pps; } } while ( ( p->cur_pp != NULL ) && !( p->packet_flags & PKT_PASS_RULE ) ); // queued decoder alerts are processed after the selection of the // IPS rule config for the flow, if not yet done then process them now if( !alerts_processed ) alerts_processed = processDecoderAlertsActionQ( p ); if( p->dsize == 0 ) DisableDetect( p ); } int Preprocess(Packet * p) { int retval = 0; int detect_retval = 0; tSfPolicyId policy_id; /* NAP runtime policy may have been updated during decode, * but preprocess needs default nap policy for session * preprocessor selection, hence use default policy when * called without session pointer set. */ if( !p->ssnptr ) policy_id = getDefaultPolicy(); else policy_id = getNapRuntimePolicy(); SnortPolicy *policy = snort_conf->targeted_policies[policy_id]; #ifdef PPM_MGR uint64_t pktcnt=0; #endif PROFILE_VARS; if (policy == NULL) return -1; #ifdef PPM_MGR /* Begin Packet Performance Monitoring */ if( PPM_PKTS_ENABLED() ) { pktcnt = PPM_INC_PKT_CNT(); PPM_GET_TIME(); PPM_INIT_PKT_TIMER(); #ifdef DEBUG if( PPM_DEBUG_PKTS() ) { /* for debugging, info gathering, so don't worry about * (unsigned) casting of pktcnt, were not likely to debug * 4G packets */ LogMessage("PPM: Process-BeginPkt[%u] caplen=%u\n", (unsigned)pktcnt,p->pkth->caplen); } #endif } #endif // If the packet has errors or syn over rate, we won't analyze it. if ( p->error_flags ) { // process any decoder alerts now that policy has been selected... DecodePolicySpecific(p); //actions are queued only for IDS case sfActionQueueExecAll(decoderActionQ); DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "Packet errors = 0x%x, ignoring traffic!\n", p->error_flags);); if ( p->error_flags & PKT_ERR_BAD_TTL ) pc.bad_ttl++; else if( p->error_flags & PKT_ERR_SYN_RL_DROP ) pc.syn_rate_limit_drops++; else pc.invalid_checksums++; } else { /* Not a completely ideal place for this since any entries added on the * PacketCallback -> ProcessPacket -> Preprocess trail will get * obliterated - right now there isn't anything adding entries there. * Really need it here for stream5 clean exit, since all of the * flushed, reassembled packets are going to be injected directly into * this function and there may be enough that the obfuscation entry * table will overflow if we don't reset it. Putting it here does * have the advantage of fewer entries per logging cycle */ obApi->resetObfuscationEntries(); do_detect = do_detect_content = !snort_conf->disable_all_policies; /* ** Reset the appropriate application-layer protocol fields */ ClearHttpBuffers(); p->alt_dsize = 0; DetectReset(p->data, p->dsize); // ok, dispatch all preprocs enabled for this packet/session DispatchPreprocessors( p, policy_id, policy ); if ( do_detect ) { detect_retval = Detect(p); } } check_tags_flag = 1; #ifdef DUMP_BUFFER dumped_state = false; #endif PREPROC_PROFILE_START(eventqPerfStats); retval = SnortEventqLog(snort_conf->event_queue, p); #ifdef DUMP_BUFFER /* dump_alert_only makes sure that bufferdump happens only when a rule is triggered. dumped_state avoids repetition of buffer dump for a packet that has an alert, when --buffer-dump is given as command line option. When --buffer-dump is given as command line option, BufferDump output plugin is called for each packet. bdfptr will be NULL for all other output plugins. */ if (!dump_alert_only && !dumped_state) { OutputFuncNode *idx = LogList; while (idx != NULL) { if (idx->bdfptr != NULL) idx->bdfptr(p, NULL , idx->arg, NULL); idx = idx->next; } } #endif SnortEventqReset(); PREPROC_PROFILE_END(eventqPerfStats); /* Check for normally closed session */ if( session_api ) session_api->check_session_closed(p); if( session_api && p->ssnptr && ( session_api->get_session_flags(p->ssnptr) & SSNFLAG_FREE_APP_DATA) ) { SessionControlBlock *scb = ( SessionControlBlock * ) p->ssnptr; session_api->free_application_data(scb); scb->ha_state.session_flags &= ~SSNFLAG_FREE_APP_DATA; } /* ** By checking tagging here, we make sure that we log the ** tagged packet whether it generates an alert or not. */ if (IPH_IS_VALID(p)) CheckTagging(p); otn_tmp = NULL; /* ** If we found events in this packet, let's flush ** the stream to make sure that we didn't miss any ** attacks before this packet. */ if(retval && IsTCP(p) && stream_api) stream_api->alert_flush_stream(p); #ifdef PPM_MGR if( PPM_PKTS_ENABLED() ) { PPM_GET_TIME(); PPM_TOTAL_PKT_TIME(); PPM_ACCUM_PKT_TIME(); #ifdef DEBUG if( PPM_DEBUG_PKTS() ) { LogMessage("PPM: Pkt[%u] Used= ",(unsigned)pktcnt); PPM_PRINT_PKT_TIME("%g usecs\n"); LogMessage("PPM: Process-EndPkt[%u]\n\n",(unsigned)pktcnt); } #endif // When detection is required to happen and it is skipped , then only we will print the trace. if (do_detect && (!detect_retval)) PPM_LATENCY_TRACE(); PPM_PKT_LOG(p); } if( PPM_RULES_ENABLED() ) { PPM_RULE_LOG(pktcnt, p); } if( PPM_PKTS_ENABLED() ) { PPM_END_PKT_TIMER(); } #endif return retval; } /* ** NAME ** CheckTagging:: */ /** ** This is where we check to see if we tag the packet. We only do ** this if we've alerted on a non-pass rule and the packet is not ** rebuilt. ** ** We don't log rebuilt packets because the output plugins log the ** individual packets of a rebuilt stream, so we don't want to dup ** tagged packets for rebuilt streams. ** ** @return integer */ static int CheckTagging(Packet *p) { Event event; if(check_tags_flag == 1 && !(p->packet_flags & PKT_REBUILT_STREAM)) { void* listhead = NULL; DEBUG_WRAP(DebugMessage(DEBUG_FLOW, "calling CheckTagList\n");); if(CheckTagList(p, &event, &listhead)) { DEBUG_WRAP(DebugMessage(DEBUG_FLOW, "Matching tag node found, " "calling log functions\n");); /* if we find a match, we want to send the packet to the * logging mechanism */ CallLogFuncs(p, "Tagged Packet", listhead, &event); } } return 0; } #if defined(FEAT_OPEN_APPID) static void updateEventAppName (Packet *p, OptTreeNode *otn, Event *event) { const char *appName; size_t appNameLen; AppIdOptionData *app_data = (AppIdOptionData*)otn->ds_list[PLUGIN_APPID]; if (app_data && (app_data->matched_appid) && (appName = appIdApi.getApplicationName(app_data->matched_appid))) { appNameLen = strlen(appName); if (appNameLen >= sizeof(event->app_name)) appNameLen = sizeof(event->app_name) - 1; memcpy(event->app_name, appName, appNameLen); event->app_name[appNameLen] = '\0'; } else if (p->ssnptr) { //log most specific appid when rule didn't have any appId int16_t serviceProtoId, clientProtoId, payloadProtoId, miscProtoId, pickedProtoId; stream_api->get_application_id(p->ssnptr, &serviceProtoId, &clientProtoId, &payloadProtoId, &miscProtoId); if ((p->packet_flags & PKT_FROM_CLIENT)) { if (!(pickedProtoId = payloadProtoId) && !(pickedProtoId = miscProtoId) && !(pickedProtoId = clientProtoId)) pickedProtoId = serviceProtoId; } else { if (!(pickedProtoId = payloadProtoId) && !(pickedProtoId = miscProtoId) && !(pickedProtoId = serviceProtoId)) pickedProtoId = clientProtoId; } if ((pickedProtoId) && (appName = appIdApi.getApplicationName(pickedProtoId))) { appNameLen = strlen(appName); if (appNameLen >= sizeof(event->app_name)) appNameLen = sizeof(event->app_name) - 1; memcpy(event->app_name, appName, appNameLen); event->app_name[appNameLen] = '\0'; } else { event->app_name[0] = 0; } } else { event->app_name[0] = 0; } } #endif /* defined(FEAT_OPEN_APPID) */ void CallLogFuncs(Packet *p, const char *message, ListHead *head, Event *event) { OutputFuncNode *idx = NULL; if (event->sig_generator != GENERATOR_TAG) { event->ref_time.tv_sec = p->pkth->ts.tv_sec; event->ref_time.tv_usec = p->pkth->ts.tv_usec; } /* set the event number */ event->event_id = event_id | ScEventLogId(); check_tags_flag = 0; pc.log_pkts++; if ( head == NULL || head->LogList == NULL ) { CallLogPlugins(p, message, event); return; } idx = head->LogList; while ( idx != NULL ) { idx->func(p, message, idx->arg, event); idx = idx->next; } } void CallLogPlugins(Packet * p, const char *message, Event *event) { OutputFuncNode *idx = LogList; while ( idx != NULL ) { idx->func(p, message, idx->arg, event); idx = idx->next; } } /* Call the output functions that are directly attached to the signature */ void CallSigOutputFuncs(Packet *p, OptTreeNode *otn, Event *event) { OutputFuncNode *idx = NULL; idx = otn->outputFuncs; while(idx) { idx->func(p, otn->sigInfo.message, idx->arg, event); idx = idx->next; } } void CallAlertFuncs(Packet * p, const char *message, ListHead * head, Event *event) { OutputFuncNode *idx = NULL; event->ref_time.tv_sec = p->pkth->ts.tv_sec; event->ref_time.tv_usec = p->pkth->ts.tv_usec; /* set the event number */ event->event_id = event_id | ScEventLogId(); /* set the event reference info */ event->event_reference = event->event_id; pc.total_alert_pkts++; if ( event->sig_generator != GENERATOR_SPP_REPUTATION ) { /* Don't include IP Reputation events in count */ pc.alert_pkts++; } if ( head == NULL || head->AlertList == NULL ) { CallAlertPlugins(p, message, event); return; } idx = head->AlertList; while ( idx != NULL ) { idx->func(p, message, idx->arg, event); idx = idx->next; } } void CallAlertPlugins(Packet * p, const char *message, Event *event) { OutputFuncNode *idx = AlertList; while ( idx != NULL ) { idx->func(p, message, idx->arg, event); idx = idx->next; } } /**************************************************************************** * * Function: Detect(Packet *) * * Purpose: Apply the rules lists to the current packet * * Arguments: p => ptr to the decoded packet struct * * Returns: 1 == detection event * 0 == no detection * ***************************************************************************/ int Detect(Packet * p) { int detected = 0; PROFILE_VARS; #if defined(DAQ_VERSION) && DAQ_VERSION > 9 uint64_t start = 0, end = 0; #endif if ((p == NULL) || !IPH_IS_VALID(p)) { return 0; } if (stream_api && stream_api->is_session_http2(p->ssnptr) && !(p->packet_flags & PKT_REBUILT_STREAM)) { return 0; } if (!snort_conf->ip_proto_array[GET_IPH_PROTO(p)]) { #ifdef GRE switch (p->outer_family) { case AF_INET: if (!snort_conf->ip_proto_array[p->outer_ip4h.ip_proto]) return 0; break; case AF_INET6: if (!snort_conf->ip_proto_array[p->outer_ip6h.next]) return 0; break; default: return 0; } #else return 0; #endif /* GRE */ } if (p->packet_flags & PKT_PASS_RULE) { /* If we've already seen a pass rule on this, * no need to continue do inspection. */ return 0; } #ifdef PPM_MGR /* * Packet Performance Monitoring * (see if preprocessing took too long) */ if( PPM_PKTS_ENABLED() ) { PPM_GET_TIME(); PPM_PACKET_TEST(); if( PPM_PACKET_ABORT_FLAG() ) return 0; } #endif /* ** This is where we short circuit so ** that we can do IP checks. */ PREPROC_PROFILE_START(detectPerfStats); #if defined(DAQ_VERSION) && DAQ_VERSION > 9 if (p->pkth && (p->pkth->flags & DAQ_PKT_FLAG_DEBUG_ON)) { get_clockticks(start); detected = fpEvalPacket(p); get_clockticks(end); print_flow(p,"DETECTION",0,start,end); } else detected = fpEvalPacket(p); #else detected = fpEvalPacket(p); #endif PREPROC_PROFILE_END(detectPerfStats); return detected; } void TriggerResponses(Packet * p, OptTreeNode * otn) { RspFpList *idx; idx = otn->rsp_func; DEBUG_WRAP(DebugMessage(DEBUG_DETECT,"Triggering responses %p\n", idx);); while(idx != NULL) { idx->func(p, idx->params); idx = idx->next; } } int CheckAddrPort( sfip_var_t *rule_addr, PortObject * po, Packet *p, uint32_t flags, int mode) { sfaddr_t* pkt_addr; /* packet IP address */ u_short pkt_port; /* packet port */ int global_except_addr_flag = 0; /* global exception flag is set */ int any_port_flag = 0; /* any port flag set */ int except_port_flag = 0; /* port exception flag set */ int ip_match = 0; /* flag to indicate addr match made */ DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "CheckAddrPort: ");); /* set up the packet particulars */ if(mode & CHECK_SRC_IP) { pkt_addr = GET_SRC_IP(p); pkt_port = p->sp; DEBUG_WRAP(DebugMessage(DEBUG_DETECT,"SRC ");); if(mode & INVERSE) { global_except_addr_flag = flags & EXCEPT_DST_IP; any_port_flag = flags & ANY_DST_PORT; except_port_flag = flags & EXCEPT_DST_PORT; } else { global_except_addr_flag = flags & EXCEPT_SRC_IP; any_port_flag = flags & ANY_SRC_PORT; except_port_flag = flags & EXCEPT_SRC_PORT; } } else { pkt_addr = GET_DST_IP(p); pkt_port = p->dp; DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "DST ");); if(mode & INVERSE) { global_except_addr_flag = flags & EXCEPT_SRC_IP; any_port_flag = flags & ANY_SRC_PORT; except_port_flag = flags & EXCEPT_SRC_PORT; } else { global_except_addr_flag = flags & EXCEPT_DST_IP; any_port_flag = flags & ANY_DST_PORT; except_port_flag = flags & EXCEPT_DST_PORT; } } DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "addr %lx, port %d ", pkt_addr, pkt_port);); if(!rule_addr) goto bail; if(!(global_except_addr_flag)) /*modeled after Check{Src,Dst}IP function*/ { if(sfvar_ip_in(rule_addr, pkt_addr)) ip_match = 1; } else { DEBUG_WRAP(DebugMessage(DEBUG_DETECT, ", global exception flag set");); /* global exception flag is up, we can't match on *any* * of the source addresses */ if(sfvar_ip_in(rule_addr, pkt_addr)) return 0; ip_match=1; } bail: if(!ip_match) { DEBUG_WRAP(DebugMessage(DEBUG_DETECT, ", no address match, " "packet rejected\n");); return 0; } DEBUG_WRAP(DebugMessage(DEBUG_DETECT, ", addresses accepted");); /* if the any port flag is up, we're all done (success) */ if(any_port_flag) { DEBUG_WRAP(DebugMessage(DEBUG_DETECT, ", any port match, " "packet accepted\n");); return 1; } #ifdef TARGET_BASED if (!(mode & (CHECK_SRC_PORT | CHECK_DST_PORT))) { DEBUG_WRAP( DebugMessage(DEBUG_ATTRIBUTE, "detect.c: CheckAddrPort..." "target-based-protocol=%d,ignoring ports\n", GetProtocolReference(p));); return 1; } else { DEBUG_WRAP( DebugMessage(DEBUG_ATTRIBUTE, "detect.c: CheckAddrPort..." "target-based-protocol=%d,not ignoring ports\n", GetProtocolReference(p));); } #endif /* TARGET_BASED */ /* check the packet port against the rule port */ if( !PortObjectHasPort(po,pkt_port) ) { /* if the exception flag isn't up, fail */ if(!except_port_flag) { DEBUG_WRAP(DebugMessage(DEBUG_DETECT, ", port mismatch, " "packet rejected\n");); return 0; } DEBUG_WRAP(DebugMessage(DEBUG_DETECT, ", port mismatch exception");); } else { /* if the exception flag is up, fail */ if(except_port_flag) { DEBUG_WRAP(DebugMessage(DEBUG_DETECT, ", port match exception, packet rejected\n");); return 0; } DEBUG_WRAP(DebugMessage(DEBUG_DETECT, ", ports match");); } /* ports and address match */ DEBUG_WRAP(DebugMessage(DEBUG_DETECT, ", packet accepted!\n");); return 1; } /**************************************************************************** * * Function: DumpList(IpAddrNode*) * * Purpose: print out the chain lists by header block node group * * Arguments: node => the head node * * Returns: void function * ***************************************************************************/ void DumpList(IpAddrNode *idx, int negated) { DEBUG_WRAP(int i=0;); if(!idx) return; while(idx != NULL) { DEBUG_WRAP(DebugMessage(DEBUG_RULES, "[%d] %s", i++, sfip_ntoa(&idx->ip->addr));); if(negated) { DEBUG_WRAP(DebugMessage(DEBUG_RULES, " (EXCEPTION_FLAG Active)\n");); } else { DEBUG_WRAP(DebugMessage(DEBUG_RULES, "\n");); } idx = idx->next; } } /**************************************************************************** * * Function: DumpChain(RuleTreeNode *, char *, char *) * * Purpose: Iterate over RTNs calling DumpList on each * * Arguments: rtn_idx => the RTN index pointer * rulename => the name of the rule the list belongs to * listname => the name of the list being printed out * * Returns: void function * ***************************************************************************/ void DumpChain(RuleTreeNode * rtn_head, char *rulename, char *listname) { // XXX Not yet implemented - Rule chain dumping } #define CHECK_ADDR_SRC_ARGS(x) (x)->src_portobject #define CHECK_ADDR_DST_ARGS(x) (x)->dst_portobject int CheckBidirectional(Packet *p, struct _RuleTreeNode *rtn_idx, RuleFpList *fp_list, int check_ports) { DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "Checking bidirectional rule...\n");); if(CheckAddrPort(rtn_idx->sip, CHECK_ADDR_SRC_ARGS(rtn_idx), p, rtn_idx->flags, CHECK_SRC_IP | (check_ports ? CHECK_SRC_PORT : 0))) { DEBUG_WRAP(DebugMessage(DEBUG_DETECT, " Src->Src check passed\n");); if(! CheckAddrPort(rtn_idx->dip, CHECK_ADDR_DST_ARGS(rtn_idx), p, rtn_idx->flags, CHECK_DST_IP | (check_ports ? CHECK_DST_PORT : 0))) { DEBUG_WRAP(DebugMessage(DEBUG_DETECT, " Dst->Dst check failed," " checking inverse combination\n");); if(CheckAddrPort(rtn_idx->dip, CHECK_ADDR_DST_ARGS(rtn_idx), p, rtn_idx->flags, (CHECK_SRC_IP | INVERSE | (check_ports ? CHECK_SRC_PORT : 0)))) { DEBUG_WRAP(DebugMessage(DEBUG_DETECT, " Inverse Dst->Src check passed\n");); if(!CheckAddrPort(rtn_idx->sip, CHECK_ADDR_SRC_ARGS(rtn_idx), p, rtn_idx->flags, (CHECK_DST_IP | INVERSE | (check_ports ? CHECK_DST_PORT : 0)))) { DEBUG_WRAP(DebugMessage(DEBUG_DETECT, " Inverse Src->Dst check failed\n");); return 0; } else { DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "Inverse addr/port match\n");); } } else { DEBUG_WRAP(DebugMessage(DEBUG_DETECT, " Inverse Dst->Src check failed," " trying next rule\n");); return 0; } } else { DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "dest IP/port match\n");); } } else { DEBUG_WRAP(DebugMessage(DEBUG_DETECT, " Src->Src check failed, trying inverse test\n");); if(CheckAddrPort(rtn_idx->dip, CHECK_ADDR_DST_ARGS(rtn_idx), p, rtn_idx->flags, CHECK_SRC_IP | INVERSE | (check_ports ? CHECK_SRC_PORT : 0))) { DEBUG_WRAP(DebugMessage(DEBUG_DETECT, " Dst->Src check passed\n");); if(!CheckAddrPort(rtn_idx->sip, CHECK_ADDR_SRC_ARGS(rtn_idx), p, rtn_idx->flags, CHECK_DST_IP | INVERSE | (check_ports ? CHECK_DST_PORT : 0))) { DEBUG_WRAP(DebugMessage(DEBUG_DETECT, " Src->Dst check failed\n");); return 0; } else { DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "Inverse addr/port match\n");); } } else { DEBUG_WRAP(DebugMessage(DEBUG_DETECT," Inverse test failed, " "testing next rule...\n");); return 0; } } DEBUG_WRAP(DebugMessage(DEBUG_DETECT," Bidirectional success!\n");); return 1; } /**************************************************************************** * * Function: CheckSrcIp(Packet *, struct _RuleTreeNode *, RuleFpList *) * * Purpose: Test the source IP and see if it equals the SIP of the packet * * Arguments: p => ptr to the decoded packet data structure * rtn_idx => ptr to the current rule data struct * fp_list => ptr to the current function pointer node * * Returns: 0 on failure (no match), 1 on success (match) * ***************************************************************************/ int CheckSrcIP(Packet * p, struct _RuleTreeNode * rtn_idx, RuleFpList * fp_list, int check_ports) { DEBUG_WRAP(DebugMessage(DEBUG_DETECT,"CheckSrcIPEqual: ");); if(!(rtn_idx->flags & EXCEPT_SRC_IP)) { if( sfvar_ip_in(rtn_idx->sip, GET_SRC_IP(p)) ) { // XXX NOT YET IMPLEMENTED - debugging in Snort6 #if 0 #ifdef DEBUG_MSGS sfaddr_t ip; if(idx->addr_flags & EXCEPT_IP) { DebugMessage(DEBUG_DETECT, " SIP exception match\n"); } else { DebugMessage(DEBUG_DETECT, " SIP match\n"); } ip = *iph_ret_src(p); /* necessary due to referencing/dereferencing */ DebugMessage(DEBUG_DETECT, "Rule: %s Packet: %s\n", inet_ntoa(idx->ip_addr), inet_ntoa(ip)); #endif /* DEBUG */ #endif /* the packet matches this test, proceed to the next test */ return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); } } else { /* global exception flag is up, we can't match on *any* * of the source addresses */ DEBUG_WRAP(DebugMessage(DEBUG_DETECT," global exception flag, \n");); if( sfvar_ip_in(rtn_idx->sip, GET_SRC_IP(p)) ) return 0; return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); } DEBUG_WRAP(DebugMessage(DEBUG_DETECT," Mismatch on SIP\n");); return 0; /* return 0 on a failed test */ return 0; } /**************************************************************************** * * Function: CheckDstIp(Packet *, struct _RuleTreeNode *, RuleFpList *) * * Purpose: Test the dest IP and see if it equals the DIP of the packet * * Arguments: p => ptr to the decoded packet data structure * rtn_idx => ptr to the current rule data struct * fp_list => ptr to the current function pointer node * * Returns: 0 on failure (no match), 1 on success (match) * ***************************************************************************/ int CheckDstIP(Packet *p, struct _RuleTreeNode *rtn_idx, RuleFpList *fp_list, int check_ports) { DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "CheckDstIPEqual: ");) if(!(rtn_idx->flags & EXCEPT_DST_IP)) { if( sfvar_ip_in(rtn_idx->dip, GET_DST_IP(p)) ) { // #ifdef DEBUG_MSGS // XXX idx's equivalent is lost inside of sfvar_ip_in // DebugMessage(DEBUG_DETECT, "Rule: %s Packet: ", // inet_ntoa(idx->ip_addr)); // DebugMessage(DEBUG_DETECT, "%s\n", sfip_ntoa(iph_ret_dst(p))); // #endif /* the packet matches this test, proceed to the next test */ return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); } } else { /* global exception flag is up, we can't match on *any* * of the source addresses */ DEBUG_WRAP(DebugMessage(DEBUG_DETECT," global exception flag, \n");); if( sfvar_ip_in(rtn_idx->dip, GET_DST_IP(p)) ) return 0; return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); } return 0; } int CheckSrcPortEqual(Packet *p, struct _RuleTreeNode *rtn_idx, RuleFpList *fp_list, int check_ports) { DEBUG_WRAP(DebugMessage(DEBUG_DETECT,"CheckSrcPortEqual: ");); #ifdef TARGET_BASED /* Check if attributes provided match earlier */ if (check_ports == 0) { DEBUG_WRAP( DebugMessage(DEBUG_ATTRIBUTE, "detect.c: CheckSrcPortEq..." "target-based-protocol=%d,ignoring ports\n", GetProtocolReference(p));); return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); } else { DEBUG_WRAP( DebugMessage(DEBUG_ATTRIBUTE, "detect.c: CheckSrcPortEq..." "target-based-protocol=%d,not ignoring ports\n", GetProtocolReference(p));); } #endif /* TARGET_BASED */ if( PortObjectHasPort(rtn_idx->src_portobject,p->sp) ) { DEBUG_WRAP(DebugMessage(DEBUG_DETECT, " SP match!\n");); return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); } else { DEBUG_WRAP(DebugMessage(DEBUG_DETECT, " SP mismatch!\n");); } return 0; } int CheckSrcPortNotEq(Packet *p, struct _RuleTreeNode *rtn_idx, RuleFpList *fp_list, int check_ports) { DEBUG_WRAP(DebugMessage(DEBUG_DETECT,"CheckSrcPortNotEq: ");); #ifdef TARGET_BASED /* Check if attributes provided match earlier */ if (check_ports == 0) { DEBUG_WRAP( DebugMessage(DEBUG_ATTRIBUTE, "detect.c: CheckSrcPortNotEq..." "target-based-protocol=%d,ignoring ports\n", GetProtocolReference(p));); return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); } else { DEBUG_WRAP( DebugMessage(DEBUG_ATTRIBUTE, "detect.c: CheckSrcPortNotEq..." "target-based-protocol=%d,not ignoring ports\n", GetProtocolReference(p));); } #endif /* TARGET_BASED */ if( !PortObjectHasPort(rtn_idx->src_portobject,p->sp) ) { DEBUG_WRAP(DebugMessage(DEBUG_DETECT, " !SP match!\n");); return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); } else { DEBUG_WRAP(DebugMessage(DEBUG_DETECT, " !SP mismatch!\n");); } return 0; } int CheckDstPortEqual(Packet *p, struct _RuleTreeNode *rtn_idx, RuleFpList *fp_list, int check_ports) { DEBUG_WRAP(DebugMessage(DEBUG_DETECT,"CheckDstPortEqual: ");); #ifdef TARGET_BASED /* Check if attributes provided match earlier */ if (check_ports == 0) { DEBUG_WRAP( DebugMessage(DEBUG_ATTRIBUTE, "detect.c: CheckDstPortEq..." "target-based-protocol=%d,ignoring ports\n", GetProtocolReference(p));); return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); } else { DEBUG_WRAP( DebugMessage(DEBUG_ATTRIBUTE, "detect.c: CheckDstPortEq..." "target-based-protocol=%d,not ignoring ports\n", GetProtocolReference(p));); } #endif /* TARGET_BASED */ if( PortObjectHasPort(rtn_idx->dst_portobject,p->dp) ) { DEBUG_WRAP(DebugMessage(DEBUG_DETECT, " DP match!\n");); return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); } else { DEBUG_WRAP(DebugMessage(DEBUG_DETECT," DP mismatch!\n");); } return 0; } int CheckDstPortNotEq(Packet *p, struct _RuleTreeNode *rtn_idx, RuleFpList *fp_list, int check_ports) { DEBUG_WRAP(DebugMessage(DEBUG_DETECT,"CheckDstPortNotEq: ");); #ifdef TARGET_BASED /* Check if attributes provided match earlier */ if (check_ports == 0) { DEBUG_WRAP( DebugMessage(DEBUG_ATTRIBUTE, "detect.c: CheckDstPortNotEq..." "target-based-protocol=%d,ignoring ports\n", GetProtocolReference(p));); return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); } else { DEBUG_WRAP( DebugMessage(DEBUG_ATTRIBUTE, "detect.c: CheckDstPortNotEq..." "target-based-protocol=%d,not ignoring ports\n", GetProtocolReference(p));); } #endif /* TARGET_BASED */ if( !PortObjectHasPort(rtn_idx->dst_portobject,p->dp) ) { DEBUG_WRAP(DebugMessage(DEBUG_DETECT, " !DP match!\n");); return fp_list->next->RuleHeadFunc(p, rtn_idx, fp_list->next, check_ports); } else { DEBUG_WRAP(DebugMessage(DEBUG_DETECT," !DP mismatch!\n");); } return 0; } int RuleListEnd(Packet *p, struct _RuleTreeNode *rtn_idx, RuleFpList *fp_list, int check_ports) { return 1; } int OptListEnd(void *option_data, Packet *p) { return DETECTION_OPTION_MATCH; } /* Rule Match Action Functions */ int PassAction(void) { pc.pass_pkts++; DEBUG_WRAP(DebugMessage(DEBUG_DETECT," => Pass rule, returning...\n");); return 1; } int AlertAction(Packet * p, OptTreeNode * otn, RuleTreeNode * rtn, Event * event) { if (!rtn) { // This function may be called from ppm, which doesn't do an RTN lookup rtn = getRuntimeRtnFromOtn(otn); if (!rtn) return 0; } DEBUG_WRAP(DebugMessage(DEBUG_DETECT, " Generating alert! \"%s\", policyId %d\n", otn->sigInfo.message, getIpsRuntimePolicy());); #if defined(FEAT_OPEN_APPID) updateEventAppName (p, otn, event); #endif /* defined(FEAT_OPEN_APPID) */ /* Call OptTreeNode specific output functions */ if(otn->outputFuncs) CallSigOutputFuncs(p, otn, event); if (ScAlertPacketCount()) print_packet_count(); CallAlertFuncs(p, otn->sigInfo.message, rtn->listhead, event); DEBUG_WRAP(DebugMessage(DEBUG_DETECT, " => Finishing alert packet!\n");); CallLogFuncs(p, otn->sigInfo.message, rtn->listhead, event); /* if(p->ssnptr != NULL && stream_api) { if(stream_api->alert_flush_stream(p) == 0) { CallLogFuncs(p, otn->sigInfo.message, otn->rtn->listhead, event); } } else { CallLogFuncs(p, otn->sigInfo.message, otn->rtn->listhead, event); } */ DEBUG_WRAP(DebugMessage(DEBUG_DETECT," => Alert packet finished, returning!\n");); return 1; } int DropAction(Packet * p, OptTreeNode * otn, RuleTreeNode * rtn, Event * event) { DEBUG_WRAP(DebugMessage(DEBUG_DETECT, " Generating Alert and dropping! \"%s\"\n", otn->sigInfo.message);); if(stream_api && !stream_api->alert_inline_midstream_drops()) { if(session_api->get_session_flags(p->ssnptr) & SSNFLAG_MIDSTREAM) { DEBUG_WRAP(DebugMessage(DEBUG_DETECT, " Alert Came From Midstream Session Silently Drop! " "\"%s\"\n", otn->sigInfo.message);); Active_DropSession(p); if (pkt_trace_enabled) addPktTraceData(VERDICT_REASON_SNORT, snprintf(trace_line, MAX_TRACE_LINE, "Snort: gid %u, sid %u, midstream %s\n", otn->sigInfo.generator, otn->sigInfo.id, getPktTraceActMsg())); else addPktTraceData(VERDICT_REASON_SNORT, 0); return 1; } } /* ** Set packet flag so output plugins will know we dropped the ** packet we just logged. */ Active_DropSession(p); #if defined(FEAT_OPEN_APPID) updateEventAppName (p, otn, event); #endif /* defined(FEAT_OPEN_APPID) */ CallAlertFuncs(p, otn->sigInfo.message, rtn->listhead, event); CallLogFuncs(p, otn->sigInfo.message, rtn->listhead, event); if (pkt_trace_enabled) addPktTraceData(VERDICT_REASON_SNORT, snprintf(trace_line, MAX_TRACE_LINE, "Snort detect_drop: gid %u, sid %u, %s\n", otn->sigInfo.generator, otn->sigInfo.id, getPktTraceActMsg())); else addPktTraceData(VERDICT_REASON_SNORT, 0); return 1; } int SDropAction(Packet * p, OptTreeNode * otn, Event * event) { DEBUG_WRAP(DebugMessage(DEBUG_DETECT, " Dropping without Alerting! \"%s\"\n", otn->sigInfo.message);); // Let's silently drop the packet Active_DropSession(p); if (pkt_trace_enabled) addPktTraceData(VERDICT_REASON_SNORT, snprintf(trace_line, MAX_TRACE_LINE, "Snort detect_sdrop: gid %u, sid %u, %s\n", otn->sigInfo.generator, otn->sigInfo.id, getPktTraceActMsg())); else addPktTraceData(VERDICT_REASON_SNORT, 0); return 1; } int LogAction(Packet * p, OptTreeNode * otn, RuleTreeNode * rtn, Event * event) { DEBUG_WRAP(DebugMessage(DEBUG_DETECT," => Logging packet data and returning...\n");); CallLogFuncs(p, otn->sigInfo.message, rtn->listhead, event); #ifdef BENCHMARK printf(" Check count = %d\n", check_count); check_count = 0; printf(" **** cmpcount: %d **** \n", cmpcount); #endif return 1; } /* end of rule action functions */ snort-2.9.15.1/src/detect.h0000644000175200017520000000763413571422607012272 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* I N C L U D E S ************************************************/ #ifndef __DETECT_H__ #define __DETECT_H__ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "snort_debug.h" #include "decode.h" #include "rules.h" #include "treenodes.h" #include "parser.h" #include "plugbase.h" #include "log.h" #include "event.h" #include "sfutil/sfportobject.h" /* P R O T O T Y P E S ******************************************************/ extern int do_detect; extern int do_detect_content; extern uint16_t event_id; /* rule match action functions */ int PassAction(void); int ActivateAction(Packet *, OptTreeNode *, RuleTreeNode *, Event *); int AlertAction(Packet *, OptTreeNode *, RuleTreeNode *, Event *); int DropAction(Packet *, OptTreeNode *, RuleTreeNode *, Event *); int SDropAction(Packet *, OptTreeNode *, Event *); int DynamicAction(Packet *, OptTreeNode *, RuleTreeNode *, Event *); int LogAction(Packet *, OptTreeNode *, RuleTreeNode *, Event *); /* detection/manipulation funcs */ int Preprocess(Packet *); int Detect(Packet *); void CallOutputPlugins(Packet *); int EvalPacket(ListHead *, int, Packet * ); int EvalHeader(RuleTreeNode *, Packet *, int); int EvalOpts(OptTreeNode *, Packet *); void TriggerResponses(Packet *, OptTreeNode *); int CheckAddrPort(sfip_var_t *, PortObject* , Packet *, uint32_t, int); /* detection modules */ int CheckBidirectional(Packet *, struct _RuleTreeNode *, RuleFpList *, int); int CheckSrcIP(Packet *, struct _RuleTreeNode *, RuleFpList *, int); int CheckDstIP(Packet *, struct _RuleTreeNode *, RuleFpList *, int); int CheckSrcIPNotEq(Packet *, struct _RuleTreeNode *, RuleFpList *, int); int CheckDstIPNotEq(Packet *, struct _RuleTreeNode *, RuleFpList *, int); int CheckSrcPortEqual(Packet *, struct _RuleTreeNode *, RuleFpList *, int); int CheckDstPortEqual(Packet *, struct _RuleTreeNode *, RuleFpList *, int); int CheckSrcPortNotEq(Packet *, struct _RuleTreeNode *, RuleFpList *, int); int CheckDstPortNotEq(Packet *, struct _RuleTreeNode *, RuleFpList *, int); int RuleListEnd(Packet *, struct _RuleTreeNode *, RuleFpList *, int); int OptListEnd(void *option_data, Packet *p); void CallLogPlugins(Packet *, const char *, Event *); void CallAlertPlugins(Packet *, const char *, Event *); void CallLogFuncs(Packet *, const char *, ListHead *, Event *); void CallAlertFuncs(Packet *, const char *, ListHead *, Event *); static inline void DisableDetect( Packet *p ) { DisableAppPreprocessors( p ); do_detect_content = 0; } static inline void DisableAllDetect( Packet *p ) { DisableAppPreprocessors( p ); do_detect = do_detect_content = 0; } static inline void EnableContentDetect( void ) { do_detect_content = 1; } static inline void DisablePacketAnalysis( Packet *p ) { DisableAllPreprocessors ( p ); do_detect = do_detect_content = 0; } /* counter for number of times we evaluate rules. Used to * cache result of check for rule option tree nodes. */ extern uint64_t rule_eval_pkt_count; #endif /* __DETECT_H__ */ snort-2.9.15.1/src/signature.c0000644000175200017520000002675413571422607013022 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Author(s): Andrew R. Baker ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "signature.h" #include "util.h" #include "rules.h" #include "treenodes.h" #include "mstring.h" #include "sfutil/sfghash.h" #include "snort.h" #include "parser.h" #ifdef TARGET_BASED #include "target-based/sftarget_protocol_reference.h" #endif #include "parser.h" #include "sfPolicy.h" /* for eval and free functions */ #include "detection-plugins/sp_pattern_match.h" static OptTreeNode *soidOTN = NULL; /********************* Reference Implementation *******************************/ ReferenceNode * AddReference(SnortConfig *sc, ReferenceNode **head, char *system, char *id) { ReferenceNode *node; if ((system == NULL) || (id == NULL) || (sc == NULL) || (head == NULL)) { return NULL; } /* create the new node */ node = (ReferenceNode *)SnortAlloc(sizeof(ReferenceNode)); /* lookup the reference system */ node->system = ReferenceSystemLookup(sc->references, system); if (node->system == NULL) node->system = ReferenceSystemAdd(&sc->references, system, NULL); node->id = SnortStrdup(id); /* Add the node to the front of the list */ node->next = *head; *head = node; return node; } /* print a reference node */ void FPrintReference(FILE *fp, ReferenceNode *ref_node) { if ((fp == NULL) || (ref_node == NULL)) return; if (ref_node->system != NULL) { if(ref_node->system->url) { fprintf(fp, "[Xref => %s%s]", ref_node->system->url, ref_node->id); } else { fprintf(fp, "[Xref => %s %s]", ref_node->system->name, ref_node->id); } } else { fprintf(fp, "[Xref => %s]", ref_node->id); } } /********************* End of Reference Implementation ************************/ /********************** Reference System Implementation ***********************/ ReferenceSystemNode * ReferenceSystemAdd(ReferenceSystemNode **head, char *name, char *url) { ReferenceSystemNode *node; if (name == NULL) { ErrorMessage("NULL reference system name\n"); return NULL; } if (head == NULL) return NULL; /* create the new node */ node = (ReferenceSystemNode *)SnortAlloc(sizeof(ReferenceSystemNode)); node->name = SnortStrdup(name); if (url != NULL) node->url = SnortStrdup(url); /* Add to the front of the list */ node->next = *head; *head = node; return node; } ReferenceSystemNode * ReferenceSystemLookup(ReferenceSystemNode *head, char *name) { if (name == NULL) return NULL; while (head != NULL) { if (strcasecmp(name, head->name) == 0) break; head = head->next; } return head; } /****************** End of Reference System Implementation ********************/ /************************ Class/Priority Implementation ***********************/ /* NOTE: This lookup can only be done during parse time */ ClassType * ClassTypeLookupByType(SnortConfig *sc, char *type) { ClassType *node; if (sc == NULL) FatalError("%s(%d) Snort config is NULL.\n", __FILE__, __LINE__); if (type == NULL) return NULL; node = sc->classifications; while (node != NULL) { if (strcasecmp(type, node->type) == 0) break; node = node->next; } return node; } /* NOTE: This lookup can only be done during parse time */ ClassType * ClassTypeLookupById(SnortConfig *sc, int id) { ClassType *node; if (sc == NULL) FatalError("%s(%d) Snort config is NULL.\n", __FILE__, __LINE__); node = sc->classifications; while (node != NULL) { if (id == node->id) break; node = node->next; } return node; } OptTreeNode * SoRuleOtnLookup(SFGHASH *so_rule_otn_map, uint32_t gid, uint32_t sid) { OptTreeNode *otn = NULL; OtnKey key; if (so_rule_otn_map == NULL) return NULL; key.gid = gid; key.sid = sid; soidOTN = otn = (OptTreeNode *)sfghash_find(so_rule_otn_map, &key); return otn; } OptTreeNode * SoRuleOtnLookupNext(uint32_t gid, uint32_t sid) { OptTreeNode * otn = NULL; if (soidOTN) { otn = soidOTN->nextSoid; soidOTN = soidOTN->nextSoid; } return otn; } SFGHASH * SoRuleOtnLookupNew(void) { return sfghash_new(10000, sizeof(OtnKey), 0, NULL); } void SoRuleOtnLookupAdd(SFGHASH *so_rule_otn_map, OptTreeNode *otn) { if ((so_rule_otn_map == NULL) || (otn == NULL)) return; if (otn->sigInfo.otnKey.gid == 0) { otn->sigInfo.otnKey.gid = otn->sigInfo.generator; otn->sigInfo.otnKey.sid = otn->sigInfo.id; } if (sfghash_add(so_rule_otn_map, &(otn->sigInfo.otnKey), otn) == SFGHASH_INTABLE) { OptTreeNode *otn_original = so_rule_otn_map->cnode->data; if (!otn_original) { /* */ FatalError("Missing Duplicate\n"); } while (otn_original->nextSoid) { otn_original = otn_original->nextSoid; } otn_original->nextSoid = otn; } } void SoRuleOtnLookupFree(SFGHASH *so_rule_otn_map) { if (so_rule_otn_map == NULL) return; sfghash_delete(so_rule_otn_map); } void OtnRemove(SFGHASH *otn_map, SFGHASH *so_rule_otn_map, OptTreeNode *otn) { OtnKey key; if (otn == NULL) return; key.gid = otn->sigInfo.generator; key.sid = otn->sigInfo.id; if (so_rule_otn_map != NULL) sfghash_remove(so_rule_otn_map, &(otn->sigInfo.otnKey)); if (otn_map != NULL) sfghash_remove(otn_map, &key); } void OtnDeleteData(void *data) { OptTreeNode *otn = (OptTreeNode *)data; OptFpList *opt_func; if (otn == NULL) return; opt_func = otn->opt_func; while (opt_func != NULL) { /* For each of the pattern matcher options in this rule, * delete the data associated with it. This is the only * rule option type (as of now) that this is required for since * patterns are not added to the hash table (via * add_detection_option()) until FinalizeContentUniqueness() is * called -- after the duplicate OTN checks. * * All other rule option types are added to the hash table * at parse time, thus the data associated with that rule * option is cleaned from the hash table when the table itself * is cleaned up. */ OptFpList *tmp = opt_func; opt_func = opt_func->next; if ((tmp->OptTestFunc == CheckANDPatternMatch) || (tmp->OptTestFunc == CheckUriPatternMatch)) { PatternMatchFree(tmp->context); } } } void OtnFree(void *data) { OptTreeNode *otn = (OptTreeNode *)data; OptFpList *opt_func; RspFpList *rsp_func; ReferenceNode *ref_node; #ifdef TARGET_BASED unsigned int svc_idx; #endif if (otn == NULL) return; /* If the opt_func list was copied from another OTN, don't free it here */ if (!otn->sigInfo.dup_opt_func) { opt_func = otn->opt_func; while (opt_func != NULL) { OptFpList *tmp = opt_func; opt_func = opt_func->next; free(tmp); } } rsp_func = otn->rsp_func; while (rsp_func) { RspFpList *tmp = rsp_func; rsp_func = rsp_func->next; // we don't free params here because they should have been // passed to add_detection_option() which will ensure the // unique ones are freed once. free(tmp); } if (otn->sigInfo.message != NULL) { if (!otn->generated) free((void*)otn->sigInfo.message); } #ifdef TARGET_BASED for (svc_idx = 0; svc_idx < otn->sigInfo.num_services; svc_idx++) { if (otn->sigInfo.services[svc_idx].service) free(otn->sigInfo.services[svc_idx].service); } if (otn->sigInfo.services) free(otn->sigInfo.services); #endif ref_node = otn->sigInfo.refs; while (ref_node != NULL) { ReferenceNode *tmp = ref_node; ref_node = ref_node->next; free(tmp->id); free(tmp); } if (otn->tag != NULL) free(otn->tag); /* RTN was generated on the fly. Don't necessarily know which policy * at this point so go through all RTNs and delete them */ if (otn->generated) { int i; for (i = 0; i < otn->proto_node_num; i++) { RuleTreeNode *rtn = deleteRtnFromOtn(NULL, otn, i); if (rtn != NULL) free(rtn); } } if (otn->proto_nodes) free(otn->proto_nodes); if (otn->detection_filter) free(otn->detection_filter); if (otn->preproc_fp_list != NULL) FreePmdList(otn->preproc_fp_list); free(otn); } SFGHASH * OtnLookupNew(void) { return sfghash_new(10000, sizeof(OtnKey), 0, OtnFree); } void OtnLookupAdd(SFGHASH *otn_map, OptTreeNode *otn) { int status; OtnKey key; if (otn_map == NULL) return; key.gid = otn->sigInfo.generator; key.sid = otn->sigInfo.id; status = sfghash_add(otn_map, &key, otn); switch (status) { case SFGHASH_OK: /* otn was inserted successfully */ break; case SFGHASH_INTABLE: /* Assume it's a rule without an sid */ if (key.sid == 0) { ParseError("Duplicate rule with same gid (%u) and no sid. To " "avoid this, make sure all of your rules define an " "sid.\n", key.gid); } else { ParseError("Duplicate rule with same gid (%u) and sid (%u)\n", key.gid, key.sid); } break; case SFGHASH_NOMEM: FatalError("Failed to allocate memory for rule.\n"); break; default: FatalError("%s(%d): OtnLookupAdd() - unexpected return value " "from sfghash_add().\n", __FILE__, __LINE__); break; } } OptTreeNode * OtnLookup(SFGHASH *otn_map, uint32_t gid, uint32_t sid) { OptTreeNode * otn; OtnKey key; if (otn_map == NULL) return NULL; key.gid = gid; key.sid = sid; otn = (OptTreeNode *)sfghash_find(otn_map, &key); return otn; } void OtnLookupFree(SFGHASH *otn_map) { if (otn_map == NULL) return; sfghash_delete(otn_map); } /***************** End of Class/Priority Implementation ***********************/ snort-2.9.15.1/src/signature.h0000644000175200017520000001100713571422607013010 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Author(s): Andrew R. Baker ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __SIGNATURE_H__ #define __SIGNATURE_H__ #ifdef OSF1 #include #endif #include #include #include "sfutil/sfghash.h" #include "sf_types.h" struct _OptTreeNode; struct _SnortConfig; struct _RuleTreeNode; /* this contains a list of the URLs for various reference systems */ typedef struct _ReferenceSystemNode { char *name; char *url; struct _ReferenceSystemNode *next; } ReferenceSystemNode; ReferenceSystemNode * ReferenceSystemAdd(ReferenceSystemNode **, char *, char *); ReferenceSystemNode * ReferenceSystemLookup(ReferenceSystemNode *, char *); void ParseReferenceSystemConfig(char *args); /* XXX: update to point to the ReferenceURLNode in the referenceURL list */ typedef struct _ReferenceNode { char *id; ReferenceSystemNode *system; struct _ReferenceNode *next; } ReferenceNode; ReferenceNode * AddReference(struct _SnortConfig *, ReferenceNode **, char *, char *); void FPrintReference(FILE *, ReferenceNode *); /* struct for rule classification */ typedef struct _ClassType { char *type; /* classification type */ int id; /* classification id */ char *name; /* "pretty" classification name */ int priority; /* priority */ struct _ClassType *next; } ClassType; void ParseClassificationConfig(char *); /* NOTE: These lookups can only be done during parse time */ ClassType * ClassTypeLookupByType(struct _SnortConfig *, char *); ClassType * ClassTypeLookupById(struct _SnortConfig *, int); /* * sid-gid -> otn mapping */ typedef struct _OtnKey { uint32_t gid; uint32_t sid; } OtnKey; #define SI_RULE_FLUSHING_OFF 0 #define SI_RULE_FLUSHING_ON 1 #define SI_RULE_TYPE_DETECT 0 #define SI_RULE_TYPE_DECODE 1 #define SI_RULE_TYPE_PREPROC 2 #ifdef TARGET_BASED typedef struct _ServiceInfo { char *service; int16_t service_ordinal; } ServiceInfo; typedef enum _ServiceOverride { ServiceOverride_ElsePorts = 0, ServiceOverride_AndPorts, ServiceOverride_OrPorts, ServiceOverride_Nil } ServiceOverride; #endif typedef struct _SigInfo { uint32_t generator; uint32_t id; uint32_t rev; uint32_t class_id; ClassType *classType; uint32_t priority; const char *message; ReferenceNode *refs; char shared; /* shared object rule */ char dup_opt_func; /* has soid, and refers to another shared object rule */ char rule_type; /* 0-std rule, 1-decoder, rule, 3 preprocessor rule */ char rule_flushing; /* 0-disabled, 1-enabled */ OtnKey otnKey; #ifdef TARGET_BASED unsigned int num_services; ServiceInfo *services; ServiceOverride service_override; #endif #if defined(FEAT_OPEN_APPID) unsigned int num_appid; #endif /* defined(FEAT_OPEN_APPID) */ } SigInfo; SFGHASH * SoRuleOtnLookupNew(void); void SoRuleOtnLookupAdd(SFGHASH *, struct _OptTreeNode *); struct _OptTreeNode * SoRuleOtnLookup(SFGHASH *, uint32_t gid, uint32_t sid); struct _OptTreeNode * SoRuleOtnLookupNext(uint32_t gid, uint32_t sid); void SoRuleOtnLookupFree(SFGHASH *); SFGHASH * OtnLookupNew(void); void OtnLookupAdd(SFGHASH *, struct _OptTreeNode *); struct _OptTreeNode * OtnLookup(SFGHASH *, uint32_t gid, uint32_t sid); void OtnLookupFree(SFGHASH *); void OtnRemove(SFGHASH *, SFGHASH *, struct _OptTreeNode *); void OtnDeleteData(void *data); void OtnFree(void *data); static inline bool IsPreprocDecoderRule(char rule_type) { if ((rule_type == SI_RULE_TYPE_DECODE) || (rule_type == SI_RULE_TYPE_PREPROC)) return true; return false; } #endif /* SIGNATURE */ snort-2.9.15.1/src/mempool.c0000644000175200017520000002703313571422607012460 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * This is used to allocate a list of fixed size objects in a static * memory pool aside from the concerns of alloc/free */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifdef HAVE_STRINGS_H #include #endif #include "mempool.h" /*SharedObjectAddStarts #include "sf_types.h" #include "sf_dynamic_preprocessor.h" SharedObjectAddEnds */ //#define TEST_MEMPOOL #ifdef TEST_MEMPOOL #define ErrorMessage printf #else #include "util.h" #endif #ifdef REG_TEST #include "reg_test.h" #endif static inline void mempool_free_pools(MemPool *mempool) { MemBucket* item; if (mempool == NULL) return; while((item = mempool->used_list_head)) { mempool->used_list_head = item->next; free(item); } while((item = mempool->free_list)) { mempool->free_list = item->next; free(item); } } /* Function: int mempool_init_optional_prealloc(MemPool *mempool, * PoolCount num_objects, * size_t obj_size, * int prealloc) * * Purpose: initialize a mempool object and allocate memory for it * Args: mempool - pointer to a MemPool struct * num_objects - number of items in this pool * obj_size - size of the items * prealloc - flag for preallocating the objects * * Returns: 0 on success, 1 on failure */ int mempool_init_optional_prealloc(MemPool *mempool, unsigned num_objects, size_t obj_size, int prealloc) { unsigned i; if(mempool == NULL) return 1; if(num_objects < 1) return 1; if(obj_size < 1) return 1; memset(mempool, 0, sizeof(*mempool)); mempool_setObjectSize(mempool, num_objects, obj_size); if (prealloc) { for (i = 0; i < num_objects; i++) { MemBucket *bp; if((bp = malloc(sizeof(*bp) + obj_size)) == NULL) { ErrorMessage("%s(%d) mempool_init(): membucket is null\n", __FILE__, __LINE__); mempool_destroy(mempool); return 1; } bp->data = bp + 1; bp->obj_size = obj_size; bp->scbPtr = NULL; bp->next = mempool->free_list; mempool->free_list = bp; mempool->free_memory += obj_size; } } return 0; } /* Function: int mempool_init(MemPool *mempool, * PoolCount num_objects, size_t obj_size) * * Purpose: initialize a mempool object and allocate memory for it * Args: mempool - pointer to a MemPool struct * num_objects - number of items in this pool * obj_size - size of the items * * Returns: 0 on success, 1 on failure */ int mempool_init(MemPool *mempool, unsigned num_objects, size_t obj_size) { return mempool_init_optional_prealloc(mempool, num_objects, obj_size, 0); } /* Function: int mempool_clean(MemPool *mempool) * * Purpose: return all memory to free list * Args: mempool - pointer to a MemPool struct * * Returns: 0 on success, -1 on failure */ int mempool_clean(MemPool *mempool) { if (mempool == NULL) return -1; while (mempool->used_list_head) mempool_free(mempool, mempool->used_list_head); return 0; } /* Function: int mempool_destroy(MemPool *mempool) * * Purpose: destroy a set of mempool objects * Args: mempool - pointer to a MemPool struct * * Returns: 0 on success, 1 on failure */ int mempool_destroy(MemPool *mempool) { if(mempool == NULL) return 1; mempool_free_pools(mempool); /* TBD - callback to free up every stray pointer */ memset(mempool, 0, sizeof(MemPool)); return 0; } static inline MemBucket *_mempool_alloc(MemPool *mempool, bool force_alloc) { MemBucket *b; if(mempool == NULL) return NULL; /* get one item off the free_list, put one item on the usedlist */ while ((b = mempool->free_list)) { if (b->obj_size == mempool->obj_size) break; mempool_free_bucket(mempool); } if (!b) { if (force_alloc || ((mempool->used_memory + mempool->obj_size) <= mempool->max_memory)) { if ((b = malloc(sizeof(*b) + mempool->obj_size)) == NULL) { ErrorMessage("%s(%d) mempool_init(): membucket is null\n", __FILE__, __LINE__); return NULL; } b->data = b + 1; b->obj_size = mempool->obj_size; b->scbPtr = NULL; #ifdef REG_TEST if (REG_TEST_FLAG_SESSION_FORCE_RELOAD & getRegTestFlags()) { if ((mempool->used_memory + mempool->obj_size) > mempool->max_memory) printf("%s: force alloc hit\n", __FUNCTION__); } #endif } else { #ifdef TEST_MEMPOOL printf("No free mempool objects\n"); #endif return NULL; } } else { mempool->free_list = b->next; mempool->free_memory -= b->obj_size; } b->next = NULL; b->prev = mempool->used_list_tail; if (mempool->used_list_tail) mempool->used_list_tail->next = b; mempool->used_list_tail = b; if (mempool->used_list_head == NULL) mempool->used_list_head = b; mempool->used_memory += b->obj_size; /* TBD -- make configurable */ memset(b->data, 0, b->obj_size); return b; } /* Function: MemBucket *mempool_alloc(MemPool *mempool); * * Purpose: allocate a new object from the mempool * Args: mempool - pointer to a MemPool struct * * Returns: a pointer to the mempool object on success, NULL on failure */ MemBucket *mempool_alloc(MemPool *mempool) { return _mempool_alloc(mempool, FALSE); } /* Function: MemBucket *mempool_force_alloc(MemPool *mempool); * * Purpose: allocate a new object from the mempool even it cross its max_memory * This has to be used when the mempool memory gets free at end of this * path. * Ex: during Reload adjust, we know that mempool gets free at end of Pkt processing * So, to ensure session allocation success mempool_force_alloc will be called. * Args: mempool - pointer to a MemPool struct * * Returns: a pointer to the mempool object on success, NULL on failure */ MemBucket *mempool_force_alloc(MemPool *mempool) { return _mempool_alloc(mempool, TRUE); } void mempool_free(MemPool *mempool, MemBucket *obj) { if ((mempool == NULL) || (obj == NULL)) return; if (obj->prev) obj->prev->next = obj->next; else mempool->used_list_head = obj->next; if (obj->next) obj->next->prev = obj->prev; else mempool->used_list_tail = obj->prev; mempool->used_memory -= obj->obj_size; if (obj->obj_size == mempool->obj_size) { obj->next = mempool->free_list; mempool->free_list = obj; mempool->free_memory += obj->obj_size; } else free(obj); } int mempool_free_bucket(MemPool *mempool) { MemBucket *obj; if (mempool == NULL || mempool->free_list == NULL) return -1; obj = mempool->free_list; mempool->free_list = obj->next; mempool->free_memory -= obj->obj_size; free(obj); return 0; } MemBucket* mempool_get_lru_bucket(MemPool *memory_pool) { MemBucket *lru_bucket = NULL; lru_bucket = mempool_oldestUsedBucket(memory_pool); return lru_bucket; } unsigned mempool_prune_freelist(MemPool *memory_pool, size_t new_max_memory, unsigned maxWork) { for( ; maxWork && (memory_pool->used_memory + memory_pool->free_memory) > new_max_memory; maxWork--) { if(mempool_free_bucket(memory_pool)) break; } return maxWork; } #ifdef TEST_MEMPOOL #define SIZE 36 int main(void) { MemPool test; MemBucket *bucks[SIZE]; MemBucket *bucket = NULL; int i; //char *stuffs[4] = { "eenie", "meenie", "minie", "moe" }; char *stuffs2[36] = { "1eenie", "2meenie", "3minie", " 4moe", "1xxxxx", "2yyyyyy", "3zzzzz", " 4qqqq", "1eenie", "2meenie", "3minie", " 4moe", "1eenie", "2meenie", "3minie", " 4moe", "1eenie", "2meenie", "3minie", " 4moe", "1eenie", "2meenie", "3minie", " 4moe", "1eenie", "2meenie", "3minie", " 4moe", "1eenie", "2meenie", "3minie", " 4moe", "1eenie", "2meenie", "3minie", " 4moe" }; if(mempool_init(&test, 36, 256)) { printf("error in mempool initialization\n"); } printf("free: %" PRIu64 ", used: %" PRIu64 "\n", (uint64_t)test.free_memory, (uint64_t)test.used_memory); for(i = 0; i < 36; i++) { if((bucks[i] = mempool_alloc(&test)) == NULL) { printf("error in mempool_alloc: i=%d\n", i); continue; } bucket = bucks[i]; bucket->data = strncpy(bucket->data, stuffs2[i], 256); printf("bucket->data: %s\n", (char *) bucket->data); } printf("free: %" PRIu64 ", used: %" PRIu64 "\n", (uint64_t)test.free_memory, (uint64_t)test.used_memory); for(i = 0; i < 2; i++) { mempool_free(&test, bucks[i]); bucks[i] = NULL; } printf("free: %" PRIu64 ", used: %" PRIu64 "\n", (uint64_t)test.free_memory, (uint64_t)test.used_memory); for(i = 0; i < 14; i++) { if((bucks[i] = mempool_alloc(&test)) == NULL) { printf("error in mempool_alloc: i=%d\n", i); continue; } bucket = bucks[i]; bucket->data = strncpy(bucket->data, stuffs2[i], 256); printf("bucket->data: %s\n", (char *) bucket->data); } printf("free: %" PRIu64 ", used: %" PRIu64 "\n", (uint64_t)test.free_memory, (uint64_t)test.used_memory); if (mempool_clean(&test)) { printf("error in mempool_clean\n"); } printf("free: %" PRIu64 ", used: %" PRIu64 "\n", (uint64_t)test.free_memory, (uint64_t)test.used_memory); for(i = 0; i < 14; i++) { if((bucks[i] = mempool_alloc(&test)) == NULL) { printf("error in mempool_alloc: i=%d\n", i); continue; } bucket = bucks[i]; bucket->data = strncpy(bucket->data, stuffs2[i], 256); printf("bucket->data: %s\n", (char *) bucket->data); } printf("free: %" PRIu64 ", used: %" PRIu64 "\n", (uint64_t)test.free_memory, (uint64_t)test.used_memory); if (mempool_destroy(&test)) { printf("error in mempool_destroy\n"); } return 0; } #endif /* TEST_MEMPOOL */ snort-2.9.15.1/src/mempool.h0000644000175200017520000000607113571422607012464 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _MEMPOOL_H #define _MEMPOOL_H typedef struct _MemBucket { struct _MemBucket* next; struct _MemBucket* prev; void *data; size_t obj_size; void *scbPtr; } MemBucket; typedef struct _MemPool { MemBucket* used_list_head; MemBucket* used_list_tail; MemBucket* free_list; size_t obj_size; size_t max_memory; size_t used_memory; size_t free_memory; } MemPool; MemBucket* mempool_get_lru_bucket(MemPool *memory_pool); unsigned mempool_prune_freelist(MemPool *memory_pool, size_t new_max_memory, unsigned maxWork); int mempool_init(MemPool *mempool, unsigned num_objects, size_t obj_size); int mempool_init_optional_prealloc(MemPool *mempool, unsigned num_objects, size_t obj_size, int prealloc); int mempool_destroy(MemPool *mempool); MemBucket *mempool_alloc(MemPool *mempool); MemBucket *mempool_force_alloc(MemPool *mempool); void mempool_free(MemPool *mempool, MemBucket *obj); int mempool_free_bucket(MemPool *mempool); int mempool_clean(MemPool *mempool); static inline MemBucket* mempool_oldestUsedBucket( MemPool *mempool ) { return mempool->used_list_head; } static inline unsigned int mempool_numUsedBuckets( MemPool *mempool ) { return (unsigned int)((mempool->used_memory + mempool->obj_size - 1) / mempool->obj_size); } static inline unsigned int mempool_numFreeBuckets( MemPool *mempool ) { return (unsigned int)((mempool->free_memory + mempool->obj_size - 1) / mempool->obj_size); } static inline unsigned int mempool_numTotalBuckets( MemPool *mempool ) { return (unsigned int)((mempool->used_memory + mempool->free_memory + mempool->obj_size - 1) / mempool->obj_size); } static inline void mempool_setNumObjects( MemPool *mempool, unsigned num_objects ) { mempool->max_memory = num_objects * mempool->obj_size; } static inline void mempool_setObjectSize( MemPool *mempool, unsigned num_objects, size_t obj_size ) { mempool->obj_size = obj_size; mempool->max_memory = num_objects * obj_size; } #endif /* _MEMPOOL_H */ snort-2.9.15.1/src/sf_sdlist.c0000644000175200017520000002246413571422607013005 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sf_sdlist.h" #include #include #include /* Function: int sf_sdlist_init(sfSDlist *list, void (*destroy)(void *data)) * * Purpose: initialize an dlist * Args: list - pointer to a dlist structure * destroy - free function ( use NULL for none ) * Returns: * 1 on failure , 0 on success */ int sf_sdlist_init(sfSDList *list, void (*destroy)(void *data)) { list->destroy = destroy; list->size = 0; list->head = NULL; list->tail = NULL; return 0; } /* Function: int sf_sdlist_delete(sfSDList *list) * * Purpose: delete every item of a list * Args: list -> pointer to a dlist structure * * Returns: 1 on failure , 0 on success */ int sf_sdlist_delete(sfSDList *list) { while(list->head != NULL) { sf_sdlist_remove_next(list, NULL); } return 0; } /* * Function: int sf_sdlist_insert_next(sfSDList *list, SDListItem *item, * void *data, SDListItem *container) * * Purpose: insert data in container in the list after the item * Args: list - dlist structure * item - current position in list structure * data - current data to insert * container - place to put the data * * Returns: 0 on sucess, 1 on failure */ int sf_sdlist_insert_next(sfSDList *list, SDListItem *item, void *data, SDListItem *container) { SDListItem *new = container; if(new == NULL) return -1; new->data = data; if(item == NULL) { /* We are inserting at the head of the list HEAD */ if(list->size == 0) { list->tail = new; } new->next = list->head; list->head = new; } else { if(item->next == NULL) { /* TAIL */ list->tail = new; } new->next = item->next; item->next = new; } new->prev = item; if(new->next != NULL) { new->next->prev = new; } list->size++; return 0; } int sf_sdlist_append(sfSDList *list, void *data, SDListItem *container) { return sf_sdlist_insert_next(list, list->tail, data, container); } int sf_sdlist_remove_next(sfSDList *list, SDListItem *item) { SDListItem *li = NULL; void *data; if(list->size == 0) { return -1; } /* remove the head */ if(item == NULL) { li = list->head; data = li->data; list->head = li->next; } else { if(item->next == NULL) { return -1; } li = item->next; data = li->data; item->next = li->next; } if(li->next != NULL) { li->next->prev = item; } if(list->destroy != NULL) list->destroy(data); list->size--; if(list->size == 0) { list->tail = NULL; } return 0; } /* * Function: int sf_sdlist_remove(sfSDList *list, SDListItem *item) * * Purpose: remove the item pointed to by item * Args: list - list pointer * item - item to unlink from the list * * Returns: 0 on success , 1 on exception * */ int sf_sdlist_remove(sfSDList *list, SDListItem *item) { SDListItem *next_item; SDListItem *prev_item; if(item == NULL) { return -1; } next_item = item->next; prev_item = item->prev; if(next_item != NULL) { next_item->prev = prev_item; } else { list->tail = prev_item; } if(prev_item != NULL) { prev_item->next = next_item; } else { /* HEAD */ list->head = next_item; } if(list->destroy != NULL) list->destroy(item->data); list->size--; if(list->size == 0) { list->head = NULL; list->tail = NULL; } return 0; } void print_sdlist(sfSDList *a) { SDListItem *li; printf("***"); printf(" size: %d\n", a->size); for(li = a->head; li != NULL; li = li->next) { printf(" `- %p\n", (void*)li); } } int sf_sdlist_ins_next(sfSDList *list, SDListItem *item, const void *data) { SDListItem *new_item; // Do not allow a NULL item unless the list is empty. if (item == NULL && sf_sdlist_size(list) != 0) return -1; // Allocate storage for the item. if ((new_item = ( SDListItem * ) malloc( sizeof(SDListItem) )) == NULL) return -1; // Insert the new item into the list. new_item->data = (void *)data; if (sf_sdlist_size(list) == 0) { // Handle insertion when the list is empty. list->head = new_item; list->head->prev = NULL; list->head->next = NULL; list->tail = new_item; } else { // Handle insertion when the list is not empty. new_item->next = item->next; new_item->prev = item; if (item->next == NULL) list->tail = new_item; else item->next->prev = new_item; item->next = new_item; } // Adjust the size of the list to account for the inserted item. list->size++; return 0; } int sf_sdlist_ins_prev(sfSDList *list, SDListItem *item, const void *data) { SDListItem *new_item; // Do not allow a NULL item unless the list is empty. if (item == NULL && sf_sdlist_size(list) != 0) return -1; // Allocate storage to be managed by the abstract datatype. if ((new_item = (SDListItem *) malloc( sizeof(SDListItem) )) == NULL) return -1; // Insert the new item into the list. new_item->data = (void *)data; if (sf_sdlist_size(list) == 0) { // Handle insertion when the list is empty. list->head = new_item; list->head->prev = NULL; list->head->next = NULL; list->tail = new_item; } else { // Handle insertion when the list is not empty. new_item->next = item; new_item->prev = item->prev; if (item->prev == NULL) list->head = new_item; else item->prev->next = new_item; item->prev = new_item; } // Adjust the size of the list to account for the new item. list->size++; return 0; } int sf_sdlist_rem_item(sfSDList *list, SDListItem *item, void **data) { // Do not allow a NULL item or removal from an empty list. if (item == NULL || sf_sdlist_size(list) == 0) return -1; *data = item->data; if (item == list->head) { // Handle removal from the head of the list. list->head = item->next; if (list->head == NULL) list->tail = NULL; else item->next->prev = NULL; } else { // Handle removal from other than the head of the list. item->prev->next = item->next; if (item->next == NULL) list->tail = item->prev; else item->next->prev = item->prev; } // Free the storage allocated by the abstract datatype. free(item); // Adjust the size of the list to account for the removed item. list->size--; return 0; } /* Function: int sf_sdlist_purge(sfSDList *list) * * Purpose: remove every item of a list, free all * allocated container memory * * Args: list -> pointer to a dlist structure * * Returns: 1 on failure , 0 on success */ int sf_sdlist_purge(sfSDList *list) { void *data; while(list->head != NULL) { sf_sdlist_rem_item(list, list->head, &data); if(list->destroy != NULL) list->destroy(data); } return 0; } #ifdef TEST_SDLIST void bad(void *d) { free(d); return; } int main(void) { sfSDList a; SDListItem *li; SDListItem listpool[1000]; sf_sdlist_init(&a, &bad); if(sf_sdlist_append(&a, (char *) SnortStrdup("hello"), &listpool[0])) { printf("error appending!\n"); } sf_sdlist_append(&a, (char *)SnortStrdup("goodbye"), &listpool[1]); sf_sdlist_insert_next(&a, NULL, (char *)SnortStrdup("woo"), &listpool[2]); printf("list size %d\n", a.size); for(li = a.head; li != NULL; li = li->next) { printf("%s\n", (char *) li->data); } printf("*** removing ***\n"); sf_sdlist_remove(&a, &listpool[1]); printf("list size %d\n", a.size); for(li = a.head; li != NULL; li = li->next) { printf("%s\n", (char *) li->data); } sf_sdlist_delete(&a); printf("list size %d\n", a.size); return 0; } #endif /* TEST_SDLIST */ snort-2.9.15.1/src/sf_sdlist.h0000644000175200017520000000525013571422607013004 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 2002 Martin Roesch ** ** This is hi ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _SF_SDLIST #define _SF_SDLIST #include "sf_sdlist_types.h" /* based off Linked List structure p. 57 _Mastering algorithms in C_ * * Differs from sf_list by using static listitem blocks. * * Use mempool as the interface to this code instead of trying to use it directly * */ /* initialize a DList */ int sf_sdlist_init(sfSDList *list, void (*destroy)(void *data)); /* delete an DList */ int sf_sdlist_delete(sfSDList *list); /* insert item, putting data in container */ int sf_sdlist_insert_next(sfSDList *list, SDListItem *item, void *data, SDListItem *container); /* remove the item after the item */ int sf_sdlist_remove_next(sfSDList *list, SDListItem *item); /* remove this item from the list */ int sf_sdlist_remove(sfSDList *list, SDListItem *item); /* append at the end of the list */ int sf_sdlist_append(sfSDList *list, void *data, SDListItem *container); void print_sdlist(sfSDList *list); // list functions that handle memory allocation for inserted list items int sf_sdlist_ins_next(sfSDList *list, SDListItem *item, const void *data); int sf_sdlist_ins_prev(sfSDList *list, SDListItem *item, const void *data); int sf_sdlist_rem_item(sfSDList *list, SDListItem *item, void **data); int sf_sdlist_purge(sfSDList *list); // macro implementation of simple doubly linked list operations #define sf_sdlist_size(list) ((list)->size) #define sf_sdlist_head(list) ((list)->head) #define sf_sdlist_tail(list) ((list)->tail) #define sf_sdlist_is_head(item) ((item)->prev == NULL ? 1 : 0) #define sf_sdlist_is_tail(item) ((item)->next == NULL ? 1 : 0) #define sf_sdlist_data(item) ((item)->data) #define sf_sdlist_next(item) ((item)->next) #define sf_sdlist_prev(item) ((item)->prev) #endif /* _SF_DLIST */ snort-2.9.15.1/src/sf_sdlist_types.h0000644000175200017520000000315613571422607014233 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 2002 Martin Roesch ** ** This is hi ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _SF_SDLIST_TYPES #define _SF_SDLIST_TYPES /* based off Linked List structure p. 57 _Mastering algorithms in C_ * * Differs from sf_list by using static listitem blocks. * * Use mempool as the interface to this code instead of trying to use it directly * */ typedef struct _SDListItem { void *data; struct _SDListItem *next; struct _SDListItem *prev; } SDListItem; typedef struct sfSDList { int size; SDListItem *head; SDListItem *tail; void (*destroy)(void *data); /* delete function called for each member of the linked list */ } sfSDList; #endif /* _SF_SDLIST_TYPES */ snort-2.9.15.1/src/fpcreate.c0000644000175200017520000031733413571422607012607 00000000000000/* ** $Id$ ** ** fpcreate.c ** ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Dan Roelker ** Marc Norton ** ** NOTES ** 5.7.02 - Initial Checkin. Norton/Roelker ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** ** 6/13/05 - marc norton ** Added plugin support for fast pattern match data ** */ #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "snort.h" #include "rules.h" #include "treenodes.h" #include "treenodes.h" #include "parser.h" #include "fpcreate.h" #include "fpdetect.h" #include "sp_pattern_match.h" #include "sp_icmp_code_check.h" #include "sp_icmp_type_check.h" #include "sp_file_data.h" #include "sp_ip_proto.h" #include "plugin_enum.h" #include "util.h" #include "rules.h" #include "treenodes.h" #include "treenodes.h" #include "parser.h" #include "target-based/sftarget_reader.h" #include "mpse.h" #include "bitop_funcs.h" #ifdef INTEL_SOFT_CPM #include "sfutil/intel-soft-cpm.h" #endif #include "snort.h" #include "sp_clientserver.h" #include "sfutil/sfportobject.h" #include "sfutil/sfrim.h" #include "detection_options.h" #include "sfPolicy.h" #include "dynamic-plugins/sp_dynamic.h" #include "dynamic-plugins/sp_preprocopt.h" #include "dynamic-plugins/sf_dynamic_define.h" /* * Content flag values */ enum { PGCT_NOCONTENT=0, PGCT_CONTENT=1, PGCT_URICONTENT=2 }; static void fpAddIpProtoOnlyRule(SF_LIST **, OptTreeNode *); static void fpRegIpProto(uint8_t *, OptTreeNode *); static int fpCreatePortGroups(SnortConfig *, rule_port_tables_t *); static void fpDeletePortGroup(void *); static void fpDeletePMX(void *data); static int fpGetFinalPattern(FastPatternConfig *fp, PatternMatchData *pmd, char **ret_pattern, int *ret_bytes); static FPContentInfo * GetLongestDynamicContent(FPContentInfo *content_list); static PatternMatchData * GetDynamicFastPatternPmd(DynamicData *dd, int dd_type); static inline int IsDynamicContentFpEligible(FPContentInfo *content); static inline PatternMatchData * DynamicContentToPmd(FPContentInfo *content_info); static inline void FreeDynamicContentList(FPContentInfo *fplist); static PatternMatchData * GetLongestPmdContent(OptTreeNode *otn, int type); static int fpFinishPortGroupRule(SnortConfig *sc, PORT_GROUP *pg, PmType pm_type, OptTreeNode *otn, PatternMatchData *pmd, FastPatternConfig *fp); static int fpFinishPortGroup(SnortConfig *sc, PORT_GROUP *pg, FastPatternConfig *fp); static int fpAllocPms(SnortConfig *sc, PORT_GROUP *pg, FastPatternConfig *fp); static int fpAddPortGroupRule(SnortConfig *sc, PORT_GROUP *pg, OptTreeNode *otn, FastPatternConfig *fp); static int fpAddPortGroupPrmx(PORT_GROUP *pg, OptTreeNode *otn, int cflag); static inline int IsPmdFpEligible(PatternMatchData *content); static void PrintFastPatternInfo(OptTreeNode *otn, PatternMatchData *pmd, const char *pattern, int pattern_length, PmType pm_type); static int GetPreprocOptPmdList(OptTreeNode *, PatternMatchData **); static int UsePreprocOptFastPatterns(PatternMatchData *, PatternMatchData *); static const char *pm_type_strings[PM_TYPE__MAX] = { "Normal Content", "HTTP Uri content", "HTTP Header content", "HTTP Client body content", "HTTP Method content", }; /* #define LOCAL_DEBUG */ extern rule_index_map_t * ruleIndexMap; extern int rule_count; #ifdef TARGET_BASED #include "target-based/sftarget_protocol_reference.h" static sopg_table_t * ServicePortGroupTableNew(void) { return (sopg_table_t *)SnortAlloc(sizeof(sopg_table_t)); } /* * Test if this otn is for traffic to the server */ static int fpOtnFlowToServer( OptTreeNode * otn ) { if( OtnFlowFromClient(otn) ) return 1; if (otn->ds_list[PLUGIN_DYNAMIC]) { DynamicData *dd = (DynamicData *)otn->ds_list[PLUGIN_DYNAMIC]; DynamicOptionType optType = OPTION_TYPE_FLOWFLAGS; int flags = FLOW_TO_SERVER; if (dd->hasOptionFunction(dd->contextData, optType, flags)) return 1; } return 0; } /* * Test if this otn is for traffic to the client */ static int fpOtnFlowToClient( OptTreeNode * otn ) { if( OtnFlowFromServer(otn) ) return 1; if (otn->ds_list[PLUGIN_DYNAMIC]) { DynamicData *dd = (DynamicData *)otn->ds_list[PLUGIN_DYNAMIC]; DynamicOptionType optType = OPTION_TYPE_FLOWFLAGS; int flags = FLOW_TO_CLIENT; if (dd->hasOptionFunction(dd->contextData, optType, flags)) return 1; } return 0; } #if 0 Not currently used /* * Extract the Icmp Type field to determine the PortGroup. * * returns : * -1 : any, or not an EQ tests * >0 : any other ip type * */ static int GetOtnIcmpType (OptTreeNode * otn ) { int type; IcmpTypeCheckData * IcmpType; IcmpType = (IcmpTypeCheckData *)otn->ds_list[PLUGIN_ICMP_TYPE]; if( IcmpType && (IcmpType->operator == ICMP_TYPE_TEST_EQ) ) { type = IcmpType->icmp_type; } else { return -1; } return -1; } #endif static SFGHASH * alloc_srvmap(void) { SFGHASH *p = sfghash_new(1000, 0, 0, /*nodes are lists,free them in sfghash_delete*/ (void(*)(void*))sflist_free); if (p == NULL) FatalError("could not allocate a service rule map - no memory?\n"); return p; } static srmm_table_t * ServiceMapNew(void) { srmm_table_t *table = (srmm_table_t *)SnortAlloc(sizeof(srmm_table_t)); table->tcp_to_srv = alloc_srvmap(); table->tcp_to_cli = alloc_srvmap(); table->udp_to_srv = alloc_srvmap(); table->udp_to_cli = alloc_srvmap(); table->icmp_to_srv = alloc_srvmap(); table->icmp_to_cli = alloc_srvmap(); table->ip_to_srv = alloc_srvmap(); table->ip_to_cli = alloc_srvmap(); return table; } static void ServiceTableFree(SFGHASH *table) { if (table != NULL) sfghash_delete(table); } static void ServiceMapFree(srmm_table_t *srvc_map) { if (srvc_map == NULL) return; ServiceTableFree(srvc_map->tcp_to_srv); ServiceTableFree(srvc_map->tcp_to_cli); ServiceTableFree(srvc_map->udp_to_srv); ServiceTableFree(srvc_map->udp_to_cli); ServiceTableFree(srvc_map->icmp_to_srv); ServiceTableFree(srvc_map->icmp_to_cli); ServiceTableFree(srvc_map->ip_to_srv); ServiceTableFree(srvc_map->ip_to_cli); free(srvc_map); } static SFGHASH * alloc_spgmm(void) { SFGHASH * p; /* TODO: keys are ascii service names - for now ! */ p = sfghash_new(1000, /* # rows in table */ 0, /* size: of key 0 = ascii, >0 = fixed size */ 0, /* bool:user keys, if true just store this pointer, don't copy the key */ fpDeletePortGroup); /* ??? Why shouldn't we delete the port groups ??? */ //(void(*)(void*))0 /* free nodes are port_groups do not delete here */ ); if (p == NULL) FatalError("could not allocate a service port_group map : no memory?\n"); return p; } static srmm_table_t * ServicePortGroupMapNew(void) { srmm_table_t *table = (srmm_table_t *)SnortAlloc(sizeof(srmm_table_t)); table->tcp_to_srv = alloc_spgmm(); table->tcp_to_cli = alloc_spgmm(); table->udp_to_srv = alloc_spgmm(); table->udp_to_cli = alloc_spgmm(); table->icmp_to_srv = alloc_spgmm(); table->icmp_to_cli = alloc_spgmm(); table->ip_to_srv = alloc_spgmm(); table->ip_to_cli = alloc_spgmm(); return table; } static void ServicePortGroupTableFree(SFGHASH *table) { #if 0 SFGHASH_NODE *node; PORT_GROUP *pg; /* Not sure why we wouldn't want to free the data */ for (node = sfghash_findfirst(table); node != NULL; node = sfghash_findnext(table)) { pg = (PORT_GROUP *)node->data; if (pg == NULL) continue; /* XXX XXX (if we need to recycle these) free the PORT_GROUP */ node->data = NULL; } #endif if (table == NULL) return; sfghash_delete(table); } static void ServicePortGroupMapFree(srmm_table_t *srvc_pg_map) { if (srvc_pg_map == NULL) return; ServicePortGroupTableFree(srvc_pg_map->tcp_to_srv); ServicePortGroupTableFree(srvc_pg_map->tcp_to_cli); ServicePortGroupTableFree(srvc_pg_map->udp_to_srv); ServicePortGroupTableFree(srvc_pg_map->udp_to_cli); ServicePortGroupTableFree(srvc_pg_map->icmp_to_srv); ServicePortGroupTableFree(srvc_pg_map->icmp_to_cli); ServicePortGroupTableFree(srvc_pg_map->ip_to_srv); ServicePortGroupTableFree(srvc_pg_map->ip_to_cli); free(srvc_pg_map); } /* * Add the otn to the list stored by the key = servicename. * * table - table of service/otn-list pairs * servicename - ascii service name from rule metadata option * otn - rule - may be content,-no-content, or uri-content * */ static void ServiceMapAddOtnRaw( SFGHASH * table, char * servicename, OptTreeNode * otn ) { SF_LIST * list; OptTreeNode * otn_tmp = NULL; list = (SF_LIST*) sfghash_find( table, servicename ); if( !list ) { /* create the list */ list = sflist_new(); if( !list ) FatalError("service_rule_map: could not create a service rule-list\n"); /* add the service list to the table */ if( sfghash_add( table, servicename, list ) != SFGHASH_OK ) { FatalError("service_rule_map: could not add a rule to the rule-service-map\n"); } } if( list->tail && (otn_tmp = list->tail->ndata) && (otn_tmp == otn)) return; /* add the rule since this is not duplicate */ if( sflist_add_tail( list, otn ) ) FatalError("service_rule_map: could not add a rule to the service rule-list\n"); } /* * maintain a table of service maps, one for each protocol and direction, * each service map maintains a list of otn's for each service it maps to a * service name. */ static int ServiceMapAddOtn(srmm_table_t *srmm, int proto, char *servicename, OptTreeNode *otn) { SFGHASH * to_srv; /* to srv service rule map */ SFGHASH * to_cli; /* to cli service rule map */ if( !servicename ) return 0; if(!otn ) return 0; if( proto == IPPROTO_TCP) { to_srv = srmm->tcp_to_srv; to_cli = srmm->tcp_to_cli; } else if( proto == IPPROTO_UDP) { to_srv = srmm->udp_to_srv; to_cli = srmm->udp_to_cli; } else if( proto == IPPROTO_ICMP ) { to_srv = srmm->icmp_to_srv; to_cli = srmm->icmp_to_cli; } else if( proto == ETHERNET_TYPE_IP ) { to_srv = srmm->ip_to_srv; to_cli = srmm->ip_to_cli; } else { return 0; } if( fpOtnFlowToServer(otn) ) { ServiceMapAddOtnRaw( to_srv, servicename, otn ); } else if( fpOtnFlowToClient(otn) ) { ServiceMapAddOtnRaw( to_cli, servicename, otn ); } else /* else add to both sides */ { ServiceMapAddOtnRaw( to_srv, servicename, otn ); ServiceMapAddOtnRaw( to_cli, servicename, otn ); } return 0; } // TARGET_BASED #endif /* ** The following functions are wrappers to the pcrm routines, ** that utilize the variables that we have intialized by ** calling fpCreateFastPacketDetection(). These functions ** are also used in the file fpdetect.c, where we do lookups ** on the initialized variables. */ #ifdef TARGET_BASED int prmFindRuleGroupIp(PORT_RULE_MAP *prm, int ip_proto, PORT_GROUP **ip_group, PORT_GROUP ** gen) { PORT_GROUP *unused_a; PORT_GROUP *unused_b; PORT_GROUP *unused_c; return prmFindRuleGroup(prm, ip_proto, -1, &unused_a, ip_group, &unused_b, &unused_c, gen); } int prmFindRuleGroupIcmp(PORT_RULE_MAP *prm, int type, PORT_GROUP **type_group, PORT_GROUP ** gen) { PORT_GROUP *unused_a; PORT_GROUP *unused_b; PORT_GROUP *unused_c; return prmFindRuleGroup(prm, type, -1, &unused_a, type_group, &unused_b, &unused_c, gen); } int prmFindRuleGroupTcp(PORT_RULE_MAP *prm, int dport, int sport, PORT_GROUP ** src, PORT_GROUP **dst, PORT_GROUP **nssrc, PORT_GROUP **nsdst, PORT_GROUP ** gen) { return prmFindRuleGroup( prm, dport, sport, src, dst, nssrc, nsdst, gen); } int prmFindRuleGroupUdp(PORT_RULE_MAP *prm, int dport, int sport, PORT_GROUP ** src, PORT_GROUP ** dst, PORT_GROUP **nssrc, PORT_GROUP **nsdst, PORT_GROUP ** gen) { return prmFindRuleGroup( prm, dport, sport, src, dst, nssrc, nsdst, gen); } #else int prmFindRuleGroupIp(PORT_RULE_MAP *prm, int ip_proto, PORT_GROUP **ip_group, PORT_GROUP ** gen) { PORT_GROUP *unused_a; return prmFindRuleGroup(prm, ip_proto, -1, &unused_a, ip_group, gen); } int prmFindRuleGroupIcmp(PORT_RULE_MAP *prm, int type, PORT_GROUP **type_group, PORT_GROUP ** gen) { PORT_GROUP *unused_a; return prmFindRuleGroup(prm, type, -1, &unused_a, type_group, gen); } int prmFindRuleGroupTcp(PORT_RULE_MAP *prm, int dport, int sport, PORT_GROUP ** src, PORT_GROUP **dst, PORT_GROUP ** gen) { return prmFindRuleGroup( prm, dport, sport, src, dst, gen); } int prmFindRuleGroupUdp(PORT_RULE_MAP *prm, int dport, int sport, PORT_GROUP ** src, PORT_GROUP ** dst, PORT_GROUP ** gen) { return prmFindRuleGroup( prm, dport, sport, src, dst, gen); } #endif // TARGET_BASED void free_detection_option_root(void **existing_tree) { detection_option_tree_root_t *root; if (!existing_tree || !*existing_tree) return; root = *existing_tree; free(root->children); free(root); *existing_tree = NULL; } void free_detection_option_tree(detection_option_tree_node_t *node) { int i; for (i=0;inum_children;i++) { free_detection_option_tree(node->children[i]); } free(node->children); free(node); } /* These aren't currently used */ //static int num_trees = 0; //static int num_nc_trees = 0; //static int num_dup_trees = 0; int finalize_detection_option_tree(SnortConfig *sc, detection_option_tree_root_t *root) { detection_option_tree_node_t *node = NULL; void *dup_node = NULL; int i; if (!root) return -1; for (i=0;inum_children;i++) { node = root->children[i]; if (add_detection_option_tree(sc, node, &dup_node) == DETECTION_OPTION_EQUAL) { free_detection_option_tree(node); root->children[i] = (detection_option_tree_node_t *)dup_node; //num_dup_trees++; } else { //num_trees++; } #ifdef DEBUG_OPTION_TREE print_option_tree(root->children[i], 0); #endif } return 0; } int otn_create_tree(OptTreeNode *otn, void **existing_tree) { detection_option_tree_node_t *node = NULL, *child; detection_option_tree_root_t *root = NULL; OptFpList *opt_fp = NULL; int i; if (!existing_tree) return -1; if (!*existing_tree) { *existing_tree = SnortAlloc(sizeof(detection_option_tree_root_t)); } root = *existing_tree; #ifdef PPM_MGR root->tree_state = RULE_STATE_ENABLED; #endif opt_fp = otn->opt_func; if (!root->children) { root->num_children++; root->children = SnortAlloc(sizeof(detection_option_tree_node_t *) * root->num_children); } i = 0; child = root->children[i]; /* Build out sub-nodes for each option in the OTN fp list */ while (opt_fp) { /* If child node does not match existing option_data, * Create a child branch from a given sub-node. */ void *option_data = opt_fp->context; char found_child_match = 0; if (opt_fp->type == RULE_OPTION_TYPE_LEAF_NODE) { opt_fp = opt_fp->next; continue; } /* Don't add contents that are only for use in the * fast pattern matcher */ if ((opt_fp->type == RULE_OPTION_TYPE_CONTENT) || (opt_fp->type == RULE_OPTION_TYPE_CONTENT_URI)) { PatternMatchData *pmd = (PatternMatchData *)option_data; if (pmd->fp_only) { opt_fp = opt_fp->next; continue; } } if (!child) { /* No children at this node */ child = SnortAlloc(sizeof(detection_option_tree_node_t)); child->option_data = option_data; child->option_type = opt_fp->type; child->evaluate = opt_fp->OptTestFunc; if (!node) { root->children[i] = child; } else { node->children[i] = child; } child->num_children++; child->children = SnortAlloc(sizeof(detection_option_tree_node_t *) * child->num_children); child->last_check.is_relative = opt_fp->isRelative; if (node && child->last_check.is_relative) { node->relative_children++; } } else { if (child->option_data != option_data) { if (!node) { for (i=1;inum_children;i++) { child = root->children[i]; if (child->option_data == option_data) { found_child_match = 1; break; } } } else { for (i=1;inum_children;i++) { child = node->children[i]; if (child->option_data == option_data) { found_child_match = 1; break; } } } } else { found_child_match = 1; } if (found_child_match == 0) { /* No matching child node, create a new and add to array */ detection_option_tree_node_t **tmp_children; child = SnortAlloc(sizeof(detection_option_tree_node_t)); child->option_data = option_data; child->option_type = opt_fp->type; child->evaluate = opt_fp->OptTestFunc; child->num_children++; child->children = SnortAlloc(sizeof(detection_option_tree_node_t *) * child->num_children); child->last_check.is_relative = opt_fp->isRelative; if (!node) { root->num_children++; tmp_children = SnortAlloc(sizeof(detection_option_tree_node_t *) * root->num_children); memcpy(tmp_children, root->children, sizeof(detection_option_tree_node_t *) * (root->num_children-1)); free(root->children); root->children = tmp_children; root->children[root->num_children-1] = child; } else { node->num_children++; tmp_children = SnortAlloc(sizeof(detection_option_tree_node_t *) * node->num_children); memcpy(tmp_children, node->children, sizeof(detection_option_tree_node_t *) * (node->num_children-1)); free(node->children); node->children = tmp_children; node->children[node->num_children-1] = child; if (child->last_check.is_relative) node->relative_children++; } } } node = child; i=0; child = node->children[i]; opt_fp = opt_fp->next; } /* Append a leaf node that has option data of the SigInfo/otn pointer */ child = SnortAlloc(sizeof(detection_option_tree_node_t)); child->option_data = otn; child->option_type = RULE_OPTION_TYPE_LEAF_NODE; if (!node) { if (root->children[0]) { detection_option_tree_node_t **tmp_children; root->num_children++; tmp_children = SnortAlloc(sizeof(detection_option_tree_node_t *) * root->num_children); memcpy(tmp_children, root->children, sizeof(detection_option_tree_node_t *) * (root->num_children-1)); free(root->children); root->children = tmp_children; } root->children[root->num_children-1] = child; } else { if (node->children[0]) { detection_option_tree_node_t **tmp_children; node->num_children++; tmp_children = SnortAlloc(sizeof(detection_option_tree_node_t *) * node->num_children); memcpy(tmp_children, node->children, sizeof(detection_option_tree_node_t *) * (node->num_children-1)); free(node->children); node->children = tmp_children; } node->children[node->num_children-1] = child; } return 0; } static int add_patrn_to_neg_list(void *id, void **list) { PMX *pmx = (PMX *)id; NCListNode **ncl = (NCListNode **)list; NCListNode *new; if ((id == NULL) || (list == NULL)) return -1; new = (NCListNode *)SnortAlloc(sizeof(NCListNode)); new->pmx = pmx; new->next = *ncl; *ncl = new; return 0; } static void neg_list_free(void **list) { NCListNode *ncln; if (list == NULL) return; ncln = (NCListNode *)*list; while (ncln != NULL) { NCListNode *tmp = ncln->next; free(ncln); ncln = tmp; } *list = NULL; } int pmx_create_tree(struct _SnortConfig *sc, void *id, void **existing_tree) { PMX *pmx = NULL; RULE_NODE *rnNode = NULL; OptTreeNode *otn = NULL; if (!existing_tree) return -1; if (!*existing_tree) { *existing_tree = SnortAlloc(sizeof(detection_option_tree_root_t)); } if (!id) { /* NULL input id (PMX *), last call for this pattern state */ return finalize_detection_option_tree(sc, (detection_option_tree_root_t *)*existing_tree); } pmx = (PMX*)id; rnNode = (RULE_NODE*)(pmx->RuleNode); otn = (OptTreeNode *)rnNode->rnRuleData; return otn_create_tree(otn, existing_tree); } /* ** The following functions deal with the intialization of the ** detection engine. These are set through parser.c with the ** option 'config detection:'. This functionality may be ** broken out later into it's own file to separate from this ** file's functionality. */ /* ** Initialize detection options. */ FastPatternConfig * FastPatternConfigNew(void) { FastPatternConfig *fp = (FastPatternConfig *)SnortAlloc(sizeof(FastPatternConfig)); fpSetDefaults(fp); return fp; } void fpSetDefaults(FastPatternConfig *fp) { if (fp == NULL) return; memset(fp, 0, sizeof(FastPatternConfig)); fp->inspect_stream_insert = 1; fp->search_method = MPSE_AC_BNFA; fp->max_queue_events = 5; fp->bleedover_port_limit = 1024; } void FastPatternConfigFree(FastPatternConfig *fp) { if (fp == NULL) return; free(fp); } int fpDetectGetSingleRuleGroup(FastPatternConfig *fp) { return fp->portlists_flags & PL_SINGLE_RULE_GROUP; } int fpDetectGetBleedOverPortLimit(FastPatternConfig *fp) { return fp->bleedover_port_limit; } int fpDetectGetBleedOverWarnings(FastPatternConfig *fp) { return fp->portlists_flags & PL_BLEEDOVER_WARNINGS_ENABLED; } int fpDetectGetDebugPrintNcRules(FastPatternConfig *fp) { return fp->portlists_flags & PL_DEBUG_PRINT_NC_DETECT_RULES; } int fpDetectGetDebugPrintRuleGroupBuildDetails(FastPatternConfig *fp) { return fp->portlists_flags & PL_DEBUG_PRINT_RULEGROWP_BUILD; } int fpDetectGetDebugPrintRuleGroupsCompiled(FastPatternConfig *fp) { return fp->portlists_flags & PL_DEBUG_PRINT_RULEGROUPS_COMPILED; } int fpDetectGetDebugPrintRuleGroupsUnCompiled(FastPatternConfig *fp) { return fp->portlists_flags & PL_DEBUG_PRINT_RULEGROUPS_UNCOMPILED;; } int fpDetectGetDebugPrintFastPatterns(FastPatternConfig *fp) { return fp->debug_print_fast_pattern; } int fpDetectSplitAnyAny(FastPatternConfig *fp) { return fp->split_any_any; } void fpDetectSetSingleRuleGroup(FastPatternConfig *fp) { fp->portlists_flags |= PL_SINGLE_RULE_GROUP; } void fpDetectSetBleedOverPortLimit(FastPatternConfig *fp, unsigned int n) { fp->bleedover_port_limit = n; } void fpDetectSetBleedOverWarnings(FastPatternConfig *fp) { fp->portlists_flags |= PL_BLEEDOVER_WARNINGS_ENABLED; } void fpDetectSetDebugPrintNcRules(FastPatternConfig *fp) { fp->portlists_flags |= PL_DEBUG_PRINT_NC_DETECT_RULES; } void fpDetectSetDebugPrintRuleGroupBuildDetails(FastPatternConfig *fp) { fp->portlists_flags |= PL_DEBUG_PRINT_RULEGROWP_BUILD; } void fpDetectSetDebugPrintRuleGroupsCompiled(FastPatternConfig *fp) { fp->portlists_flags |= PL_DEBUG_PRINT_RULEGROUPS_COMPILED; } void fpDetectSetDebugPrintRuleGroupsUnCompiled(FastPatternConfig *fp) { fp->portlists_flags |= PL_DEBUG_PRINT_RULEGROUPS_UNCOMPILED; } void fpDetectSetDebugPrintFastPatterns(FastPatternConfig *fp, int flag) { fp->debug_print_fast_pattern = flag; } void fpSetDetectSearchOpt(FastPatternConfig *fp, int flag) { fp->search_opt = flag; if (flag) LogMessage(" Search-Method-Optimizations = enabled\n"); } /* Search method is set using: config detect: search-method ac-bnfa | ac | ac-full | ac-sparsebands | ac-sparse | ac-banded | ac-std | verbose */ int fpSetDetectSearchMethod(FastPatternConfig *fp, char *method) { LogMessage("Detection:\n"); if( !strcasecmp(method,"ac-std") ) { fp->search_method = MPSE_AC; LogMessage(" Search-Method = AC-Std\n"); } else if( !strcasecmp(method,"ac-bnfa-q") || !strcasecmp(method,"ac-bnfa") ) { fp->search_method = MPSE_AC_BNFA_Q; LogMessage(" Search-Method = AC-BNFA-Q\n"); } else if( !strcasecmp(method,"ac-bnfa-nq") ) { fp->search_method = MPSE_AC_BNFA; LogMessage(" Search-Method = AC-BNFA\n"); } else if( !strcasecmp(method,"ac-q") || !strcasecmp(method,"ac") ) { fp->search_method = MPSE_ACF_Q; LogMessage(" Search-Method = AC-Full-Q\n"); } else if( !strcasecmp(method,"ac-split") ) { fp->search_method = MPSE_ACF_Q; fp->split_any_any = 1; LogMessage(" Search-Method = AC-Full-Q\n"); LogMessage(" Split Any/Any group = enabled\n"); } else if( !strcasecmp(method,"ac-nq") ) { fp->search_method = MPSE_ACF; LogMessage(" Search-Method = AC-Full\n"); } else if( !strcasecmp(method,"acs") ) { fp->search_method = MPSE_ACS; LogMessage(" Search-Method = AC-Sparse\n"); } else if( !strcasecmp(method,"ac-banded") ) { fp->search_method = MPSE_ACB; LogMessage(" Search-Method = AC-Banded\n"); } else if( !strcasecmp(method,"ac-sparsebands") ) { fp->search_method = MPSE_ACSB; LogMessage(" Search-Method = AC-Sparse-Bands\n"); } /* These are for backwards compatability - and will be removed in future releases*/ else if( !strcasecmp(method,"mwm") ) { fp->search_method = MPSE_LOWMEM; LogMessage(" Search-Method = Low-Mem (MWM depracated)\n"); } else if( !strcasecmp(method,"lowmem-q") || !strcasecmp(method,"lowmem") ) { fp->search_method = MPSE_LOWMEM_Q; LogMessage(" Search-Method = Low-Mem-Q\n"); } else if( !strcasecmp(method,"lowmem-nq") ) { fp->search_method = MPSE_LOWMEM; LogMessage(" Search-Method = Low-Mem\n"); } #ifdef INTEL_SOFT_CPM else if( !strcasecmp(method,"intel-cpm") ) { fp->search_method = MPSE_INTEL_CPM; LogMessage(" Search-Method = Intel CPM\n"); } #endif else { return -1; } return 0; } void fpDetectSetSplitAnyAny(FastPatternConfig *fp, int enable) { if (enable) { fp->split_any_any = 1; LogMessage(" Split Any/Any group = enabled\n"); } else { fp->split_any_any = 0; } } /* ** Set the debug mode for the detection engine. */ void fpSetDebugMode(FastPatternConfig *fp) { fp->debug = 1; } /* ** Revert the detection engine back to not inspecting packets ** that are going to be rebuilt. */ void fpSetStreamInsert(FastPatternConfig *fp) { fp->inspect_stream_insert = 0; } /* ** Sets the maximum number of events to queue up in fpdetect before ** selecting an event. */ void fpSetMaxQueueEvents(FastPatternConfig *fp, unsigned int num_events) { fp->max_queue_events = num_events; } /* ** Sets the maximum length of patterns to be inserted into the ** pattern matcher used. */ void fpSetMaxPatternLen(FastPatternConfig *fp, unsigned int max_len) { if (fp->max_pattern_len != 0) { LogMessage("WARNING: Maximum pattern length redefined.\n"); } fp->max_pattern_len = max_len; LogMessage(" Maximum pattern length = %u\n", max_len); } /* FLP_Trim * * Trim zero byte prefixes, this increases uniqueness * * returns * length - of trimmed pattern * buff - ptr to new beggining of trimmed buffer */ static int FLP_Trim( char * p, int plen, char ** buff ) { int i; int size = 0; if( !p ) return 0; for(i=0;ipattern_buf = (char *)SnortAlloc(content_info->length); memcpy(pmd->pattern_buf, content_info->content, content_info->length); pmd->pattern_size = content_info->length; pmd->nocase = content_info->noCaseFlag; pmd->exception_flag = content_info->exception_flag; pmd->fp = content_info->fp; pmd->fp_offset = content_info->fp_offset; pmd->fp_length = content_info->fp_length; pmd->fp_only = content_info->fp_only; pmd->http_buffer = content_info->uri_buffer & 0xF; // FIXTHIS make include return pmd; } static PatternMatchData * DynamicFpContentsToPmdList(FPContentInfo *fp_list) { FPContentInfo *tmp; PatternMatchData *pmd_list = NULL; if (fp_list == NULL) return NULL; for (tmp = fp_list; tmp != NULL; tmp = tmp->next) { PatternMatchData *pmd = DynamicContentToPmd(tmp); if (pmd != NULL) { /* Add these flags to indicate these patterns are only * for the fast pattern matcher */ pmd->fp = 1; pmd->fp_only = 1; /* Add to list of pmds */ (void)AppendPmdToList(&pmd_list, pmd); } } return pmd_list; } static inline void FreeDynamicContentList(FPContentInfo *fplist) { while (fplist != NULL) { FPContentInfo *tmp = fplist->next; if (fplist->content != NULL) free(fplist->content); free(fplist); fplist = tmp; } } static PatternMatchData * GetDynamicFastPatternPmd(DynamicData *dd, int dd_type) { FPContentInfo *dc_list = NULL; if (dd == NULL) return NULL; if (dd->getDynamicContents(dd->contextData, dd_type, &dc_list) == 0) { PatternMatchData *pmd = DynamicContentToPmd(GetLongestDynamicContent(dc_list)); FreeDynamicContentList(dc_list); return pmd; } return NULL; } static inline int IsDynamicContentFpEligible(FPContentInfo *content) { if (content == NULL) return 0; if ((content->content != NULL) && (content->length != 0)) { /* Negative contents cannot be considered for dynamic rules since * detection option tree evaluation only looks at content types * for short circuiting rules found in the pattern matcher and * essentially the dynamic rule will always have to be evaluated * anyway in the no content tree */ if (content->exception_flag) return 0; return 1; } return 0; } static FPContentInfo * GetLongestDynamicContent(FPContentInfo *content_list) { FPContentInfo *content = NULL; FPContentInfo *content_zero = NULL; FPContentInfo *tmp; int max_size = 0; int max_zero_size = 0; if (content_list == NULL) return NULL; for (tmp = content_list; tmp != NULL; tmp = tmp->next) { if (tmp->fp) return tmp; /* XXX COOKIE contents and some others should not be in the content list * See GetDynamicContents() in sf_snort_detection_engine.c */ if (IsDynamicContentFpEligible(tmp)) { int size = FLP_Trim(tmp->content, tmp->length, NULL); /* In case we get all zeros patterns */ if ((size == 0) && (tmp->length > max_zero_size)) { max_zero_size = tmp->length; content_zero = tmp; } else if (size > max_size) { max_size = size; content = tmp; } } } if (content != NULL) return content; else if (content_zero != NULL) return content_zero; return NULL; } static inline int IsPmdFpEligible(PatternMatchData *content) { if (content == NULL) return 0; if ((content->pattern_buf != NULL) && (content->pattern_size != 0) && (!content->protected_pattern)) { /* We don't add cookie and some other contents to fast pattern matcher */ if(content->http_buffer && !IsHttpBufFpEligible(content->http_buffer)) return 0; if (content->exception_flag) { /* Negative contents can only be considered if they are not relative * and don't have any offset or depth. This is because the pattern * matcher does not take these into consideration and may find the * content in a non-relevant section of the payload and thus disable * the rule when it shouldn't be. * Also case sensitive patterns cannot be considered since patterns * are inserted into the pattern matcher without case which may * lead to false negatives */ if (content->use_doe || !content->nocase || (content->offset != 0) || (content->depth != 0)) { return 0; } } return 1; } return 0; } static PatternMatchData * GetLongestPmdContent(OptTreeNode *otn, int type) { PatternMatchData *pmd = NULL; PatternMatchData *pmd_not = NULL; PatternMatchData *pmd_zero = NULL; PatternMatchData *pmd_zero_not = NULL; OptFpList *ofl; int max_size = 0; int max_zero_size = 0; uint8_t base64_buf_flag = 0; uint8_t mime_buf_flag = 0; if (otn == NULL) return NULL; for (ofl = otn->opt_func; ofl != NULL; ofl = ofl->next) { PatternMatchData *tmp = (PatternMatchData *)ofl->context; FileData *filedata; switch (ofl->type) { case RULE_OPTION_TYPE_CONTENT: if (type != CONTENT_NORMAL) continue; else if(base64_buf_flag || mime_buf_flag) continue; break; case RULE_OPTION_TYPE_CONTENT_URI: base64_buf_flag = 0; mime_buf_flag = 0; if (type != CONTENT_HTTP) continue; break; case RULE_OPTION_TYPE_BASE64_DATA: base64_buf_flag =1; continue; case RULE_OPTION_TYPE_PKT_DATA: base64_buf_flag = 0; mime_buf_flag = 0; continue; case RULE_OPTION_TYPE_FILE_DATA: filedata = (FileData *)ofl->context; if(filedata->mime_decode_flag) mime_buf_flag = 1; continue; default: continue; } if (tmp->fp) return tmp; if (IsPmdFpEligible(tmp)) { int size = FLP_Trim(tmp->pattern_buf, tmp->pattern_size, NULL); /* In case we get all zeros patterns */ if ((size == 0) && ((int)tmp->pattern_size > max_zero_size)) { if (tmp->exception_flag) { pmd_zero_not = tmp; } else { max_zero_size = tmp->pattern_size; pmd_zero = tmp; } } else if (size > max_size) { if (tmp->exception_flag) { pmd_not = tmp; } else { max_size = size; pmd = tmp; } } } } if (pmd != NULL) return pmd; else if (pmd_zero != NULL) return pmd_zero; else if (pmd_not != NULL) return pmd_not; else if (pmd_zero_not != NULL) return pmd_zero_not; return NULL; } static int GetPreprocOptPmdList(OptTreeNode *otn, PatternMatchData **pmd_list) { OptFpList *ofl; int dir = 0; if ((otn == NULL) || (pmd_list == NULL)) return -1; if (otn->ds_list[PLUGIN_DYNAMIC] != NULL) { DynamicData *dd = otn->ds_list[PLUGIN_DYNAMIC]; FPContentInfo *fp_contents = NULL; if (dd->getPreprocFpContents(dd->contextData, &fp_contents) == 0) { *pmd_list = DynamicFpContentsToPmdList(fp_contents); FreeDynamicContentList(fp_contents); if (*pmd_list == NULL) return -1; return 0; } return -1; } if (otn->ds_list[PLUGIN_CLIENTSERVER] != NULL) { ClientServerData *csd = (ClientServerData *)otn->ds_list[PLUGIN_CLIENTSERVER]; if (csd->from_server) dir = PKT_FROM_SERVER; else if (csd->from_client) dir = PKT_FROM_CLIENT; } for (ofl = otn->opt_func; ofl != NULL; ofl = ofl->next) { if (ofl->type == RULE_OPTION_TYPE_PREPROCESSOR) { FPContentInfo *fp_contents = NULL; if (GetPreprocFastPatterns(ofl->context, otn->proto, dir, &fp_contents) == 0) { PatternMatchData *tmp_list = DynamicFpContentsToPmdList(fp_contents); (void)AppendPmdToList(pmd_list, tmp_list); FreeDynamicContentList(fp_contents); } } } if (*pmd_list == NULL) return -1; return 0; } static int UsePreprocOptFastPatterns(PatternMatchData *pmd, PatternMatchData *preproc_pmds) { int pmd_size; PatternMatchData *tmp; if ((pmd == NULL) || !IsPmdFpEligible(pmd)) return 1; if (preproc_pmds == NULL) return 0; pmd_size = FLP_Trim(pmd->pattern_buf, pmd->pattern_size, NULL); for (tmp = preproc_pmds; tmp != NULL; tmp = tmp->next) { int tmp_size = FLP_Trim(tmp->pattern_buf, tmp->pattern_size, NULL); /* If both are not contents or both are not not contents, * compare pattern length */ if ((tmp->exception_flag && pmd->exception_flag) || (!tmp->exception_flag && !pmd->exception_flag)) { if (tmp_size > pmd_size) return 1; } /* If the preproc pattern is not notted and the content pmd is, * use the preproc patterns */ if (!tmp->exception_flag && pmd->exception_flag) return 1; } return 0; } static int fpFinishPortGroupRule(SnortConfig *sc, PORT_GROUP *pg, PmType pm_type, OptTreeNode *otn, PatternMatchData *pmd_list, FastPatternConfig *fp) { PMX * pmx; RULE_NODE * rn; char *pattern; int pattern_length; PatternMatchData *pmd; int pg_type; if ((pg == NULL) || (otn == NULL) || (fp == NULL)) return -1; switch (pm_type) { case PM_TYPE__CONTENT: if (pmd_list == NULL) return -1; pg_type = PGCT_CONTENT; break; case PM_TYPE__HTTP_URI_CONTENT: case PM_TYPE__HTTP_HEADER_CONTENT: case PM_TYPE__HTTP_CLIENT_BODY_CONTENT: if (pmd_list == NULL) return -1; pg_type = PGCT_URICONTENT; break; case PM_TYPE__MAX: default: if (pmd_list != NULL) return -1; fpAddPortGroupPrmx(pg, otn, PGCT_NOCONTENT); return 0; /* Not adding any content to pattern matcher */ } for (pmd = pmd_list; pmd != NULL; pmd = pmd->next) { if (pmd->exception_flag) fpAddPortGroupPrmx(pg, otn, PGCT_NOCONTENT); else fpAddPortGroupPrmx(pg, otn, pg_type); if (fpGetFinalPattern(fp, pmd, &pattern, &pattern_length) == -1) return -1; /* create a rule_node */ rn = (RULE_NODE *)SnortAlloc(sizeof(RULE_NODE)); rn->rnRuleData = otn; /* create pmx */ pmx = (PMX *)SnortAlloc(sizeof(PMX)); pmx->RuleNode = rn; pmx->PatternMatchData = pmd; if (fpDetectGetDebugPrintFastPatterns(fp)) PrintFastPatternInfo(otn, pmd, pattern, pattern_length, pm_type); mpseAddPatternWithSnortConfig( sc, pg->pgPms[pm_type], pattern, pattern_length, pmd->nocase, pmd->offset, pmd->depth, (unsigned)pmd->exception_flag, pmx, rn->iRuleNodeID ); } return 0; } static int fpFinishPortGroup(SnortConfig *sc, PORT_GROUP *pg, FastPatternConfig *fp) { PmType i; int rules = 0; if ((pg == NULL) || (fp == NULL)) return -1; for (i = PM_TYPE__CONTENT; i < PM_TYPE__MAX; i++) { if (pg->pgPms[i] != NULL) { if (mpseGetPatternCount(pg->pgPms[i]) != 0) { if (mpsePrepPatternsWithSnortConf(sc, pg->pgPms[i], pmx_create_tree, add_patrn_to_neg_list) != 0) { FatalError("%s(%d) Failed to compile port group " "patterns.\n", __FILE__, __LINE__); } if (fp->debug) mpsePrintInfo(pg->pgPms[i]); rules = 1; } else { mpseFree(pg->pgPms[i]); pg->pgPms[i] = NULL; } } } if (pg->pgHeadNC != NULL) { RULE_NODE *ruleNode; for (ruleNode = pg->pgHeadNC; ruleNode; ruleNode = ruleNode->rnNext) { OptTreeNode *otn = (OptTreeNode *)ruleNode->rnRuleData; otn_create_tree(otn, &pg->pgNonContentTree); } finalize_detection_option_tree(sc, (detection_option_tree_root_t*)pg->pgNonContentTree); rules = 1; } if (!rules) { /* Nothing in the port group so we can just free it */ free(pg); return -1; } return 0; } static int fpAllocPms(SnortConfig *sc, PORT_GROUP *pg, FastPatternConfig *fp) { PmType i; for (i = PM_TYPE__CONTENT; i < PM_TYPE__MAX; i++) { /* init pattern matchers */ pg->pgPms[i] = mpseNewWithSnortConfig(sc, fp->search_method, MPSE_INCREMENT_GLOBAL_CNT, fpDeletePMX, free_detection_option_root, neg_list_free); if (pg->pgPms[i] == NULL) { PmType j; for (j = PM_TYPE__CONTENT; j < i; j++) { mpseFree(pg->pgPms[j]); pg->pgPms[j] = NULL; } LogMessage("%s(%d) Failed to create pattern matcher for pattern " "matcher type: %d\n", __FILE__, __LINE__, i); return -1; } if (fp->search_opt) mpseSetOpt(pg->pgPms[i], 1); } return 0; } static PmType GetPmType (HTTP_BUFFER hb_type) { switch ( hb_type ) { case HTTP_BUFFER_URI: return PM_TYPE__HTTP_URI_CONTENT; case HTTP_BUFFER_HEADER: return PM_TYPE__HTTP_HEADER_CONTENT; case HTTP_BUFFER_CLIENT_BODY: return PM_TYPE__HTTP_CLIENT_BODY_CONTENT; default: break; } return PM_TYPE__CONTENT; } static int fpAddPortGroupRule(SnortConfig *sc, PORT_GROUP *pg, OptTreeNode *otn, FastPatternConfig *fp) { PatternMatchData *pmd = NULL; PatternMatchData *pmd_uri = NULL; PatternMatchData *preproc_opt_pmds = NULL; if ((pg == NULL) || (otn == NULL)) return -1; /* Preprocessor or decoder rule, skip inserting it */ if (otn->sigInfo.rule_type != SI_RULE_TYPE_DETECT) return -1; /* Rule not enabled */ if (otn->rule_state != RULE_STATE_ENABLED) return -1; /* Check for an so dynamic rule */ if (otn->ds_list[PLUGIN_DYNAMIC] != NULL) { DynamicData *dd = otn->ds_list[PLUGIN_DYNAMIC]; /* The pmds returned here will have been dynamically allocated */ pmd = GetDynamicFastPatternPmd(dd, CONTENT_NORMAL); if ((pmd != NULL) && pmd->fp) { if (fpFinishPortGroupRule(sc, pg, PM_TYPE__CONTENT, otn, pmd, fp) == 0) { /* Need to do this so the pmd can be freed later */ (void)AppendPmdToList(&dd->pmds, pmd); if (pmd->pattern_size > otn->longestPatternLen) otn->longestPatternLen = pmd->pattern_size; return 0; } PatternMatchFree((void *)pmd); pmd = NULL; } pmd_uri = GetDynamicFastPatternPmd(dd, CONTENT_HTTP); if (pmd_uri != NULL) { PmType pm_type = GetPmType(pmd_uri->http_buffer); if (fpFinishPortGroupRule(sc, pg, pm_type, otn, pmd_uri, fp) == 0) { /* Using the http content so free this */ if (pmd != NULL) PatternMatchFree((void *)pmd); (void)AppendPmdToList(&dd->pmds, pmd_uri); if (pmd_uri->pattern_size > otn->longestPatternLen) otn->longestPatternLen = pmd_uri->pattern_size; return 0; } PatternMatchFree((void *)pmd_uri); pmd_uri = NULL; } /* If we get this far then no URI contents were added */ if (GetPreprocOptPmdList(otn, &preproc_opt_pmds) == 0) { if (UsePreprocOptFastPatterns(pmd, preproc_opt_pmds)) { /* Preprocessor rule option fast pattern contents * will be used so free and NULL the content pmd */ if (pmd != NULL) FreePmdList(pmd); pmd = preproc_opt_pmds; } else { /* The content rule option fast pattern is a better choice * than the preprocessor rule option fast patterns, so use it */ FreePmdList(preproc_opt_pmds); } } if (fpFinishPortGroupRule(sc, pg, PM_TYPE__CONTENT, otn, pmd, fp) == 0) { (void)AppendPmdToList(&dd->pmds, pmd); if (pmd->pattern_size > otn->longestPatternLen) otn->longestPatternLen = pmd->pattern_size; return 0; } /* Either no content or adding pmd failed */ /* Either single pmd or preprocessor rule option pmd list */ if (pmd != NULL) FreePmdList(pmd); if (fpFinishPortGroupRule(sc, pg, PM_TYPE__MAX, otn, NULL, fp) != 0) return -1; return 0; } pmd = GetLongestPmdContent(otn, CONTENT_NORMAL); /* Pull it out of the ds_list so we can treat it as a one item list * It will get free'd via the detection option tree callback for * content rule options - the ds pmd list is useless at this point * and should not be used anyway because of detection option tree * duplicate handling - see FinalizeContentUniqueness() */ (void)RemovePmdFromList(pmd); if ((pmd != NULL) && pmd->fp) { if (fpFinishPortGroupRule(sc, pg, PM_TYPE__CONTENT, otn, pmd, fp) == 0) { if (pmd->pattern_size > otn->longestPatternLen) otn->longestPatternLen = pmd->pattern_size; return 0; } } /* http buffer contents take precedence over normal contents if * no normal contents have the fast_pattern option */ pmd_uri = GetLongestPmdContent(otn, CONTENT_HTTP); (void)RemovePmdFromList(pmd_uri); if (pmd_uri != NULL) { PmType pm_type = GetPmType(pmd_uri->http_buffer); if (fpFinishPortGroupRule(sc, pg, pm_type, otn, pmd_uri, fp) == 0) { if (pmd_uri->pattern_size > otn->longestPatternLen) otn->longestPatternLen = pmd_uri->pattern_size; return 0; } } /* If we get this far then no URI contents were added */ if (GetPreprocOptPmdList(otn, &preproc_opt_pmds) == 0) { if (!UsePreprocOptFastPatterns(pmd, preproc_opt_pmds)) { /* The content rule option fast pattern is a better choice * than the preprocessor rule option fast patterns, so use it */ FreePmdList(preproc_opt_pmds); } else { pmd = preproc_opt_pmds; /* Need to be able to free this list */ (void)AppendPmdToList( (PatternMatchData **)&otn->preproc_fp_list, preproc_opt_pmds); } } if (fpFinishPortGroupRule(sc, pg, PM_TYPE__CONTENT, otn, pmd, fp) == 0) { if (pmd->pattern_size > otn->longestPatternLen) otn->longestPatternLen = pmd->pattern_size; return 0; } #if 0 /* XXX Not currently used */ /* If the "or" content rule option should ever be instated, some sort of * decision should be made between this and other normal "and" contents. * Adding one content is probably preferable over adding multiple contents, * but if the one content is only one, two bytes and the "or" contents are * more unique, then adding the "or" contents might be preferable. Maybe * if the "and" content is more unique than the least unique "or" content */ pmd = otn->ds_list[PLUGIN_PATTERN_MATCH_OR]; if (pmd != NULL) fpAddAllContents(pg->pgPms[PM_TYPE__CONTENT], otn, id, pmd, fp); #endif /* No content added */ if (pmd == preproc_opt_pmds) FreePmdList(pmd); if (fpFinishPortGroupRule(sc, pg, PM_TYPE__MAX, otn, NULL, fp) != 0) return -1; return 0; } /* * Original PortRuleMaps for each protocol requires creating the following structures. * -pcrm.h * PORT_RULE_MAP -> srcPortGroup,dstPortGroup,genericPortGroup * PORT_GROUP -> pgPatData, pgPatDataUri (acsm objects), (also rule_node lists 1/rule, not neeed) * each rule content added to an acsm object has a PMX data ptr associated with it. * RULE_NODE -> iRuleNodeID (used for bitmap object index) * * -fpcreate.h * PMX -> RULE_NODE(->otn), PatternMatchData * * PortList model supports the same structures except: * * -pcrm.h * PORT_GROUP -> no rule_node lists needed, PortObjects maintain a list of rules used * * Generation of PortRuleMaps and data is done differently. * * 1) Build tcp/udp/icmp/ip src and dst PORT_GROUP objects based on the PortList Objects rules. * * 2) For each protocols PortList objects walk it's ports and assign the PORT_RULE_MAP src and dst * PORT_GROUP[port] array pointers to that PortList objects PORT_GROUP. * * Implementation: * * Each PortList Object will be translated into a PORT_GROUP, than pointed to by the * PORT_GROUP array in the PORT_RULE_MAP for the procotocol * * protocol = tcp, udp, ip, icmp - one port_rule_map for each of these protocols * { create a port_rule_map * dst port processing * for each port-list object create a port_group object * { create a pattern match object, store its pointer in port_group * for each rule index in port-list object * { * get the gid+sid for the index * lookup up the otn * create pmx * create RULE_NODE, set iRuleNodeID within this port-list object * get longest content for the rule * set up pmx,RULE_NODE * add the content and pmx to the pattern match object * } * compile the pattern match object * * repeat for uri content * } * src port processing * repeat as for dst port processing * } * ** bidirectional rules - these are added to both src and dst PortList objects, so they are * automatically handled during conversion to port_group objects. */ /* ** Build a Pattern group for the Uri-Content rules in this group ** ** The patterns added for each rule must be suffcient so if we find any of them ** we proceed to fully analyze the OTN and RTN against the packet. ** */ /* * Init a port-list based rule map */ static int fpCreateInitRuleMap ( PORT_RULE_MAP * prm, PortTable * src, PortTable * dst, PortObject * anyany, PortObject * nc, PortTable * ns_src, // TARGET_BASED PortTable * ns_dst )// TARGET_BASED { SFGHASH_NODE * node; PortObjectItem * poi; PortObject2 * po; int i; /* setup the any-any-port content port group */ prm->prmGeneric =(PORT_GROUP*) anyany->data; /* all rules that are any any some may not be content ? */ prm->prmNumGenericRules = anyany->rule_list->count; prm->prmNumSrcRules= 0; prm->prmNumDstRules= 0; prm->prmNumSrcGroups= 0; prm->prmNumDstGroups= 0; prm->prmNumNoServiceSrcRules= 0; prm->prmNumNoServiceDstRules= 0; prm->prmNumNoServiceSrcGroups= 0; prm->prmNumNoServiceDstGroups= 0; /* Process src PORT groups */ if(src ) { for( node=sfghash_findfirst(src->pt_mpxo_hash); node; node=sfghash_findnext(src->pt_mpxo_hash) ) { po = (PortObject2*)node->data; if( !po ) continue; if( !po->data ) continue; /* Add up the total src rules */ prm->prmNumSrcRules += po->rule_hash->count; /* Increment the port group count */ prm->prmNumSrcGroups++; /* Add this port group to the src table at each port that uses it */ for( poi = (PortObjectItem*)sflist_first(po->item_list); poi; poi = (PortObjectItem*)sflist_next(po->item_list) ) { switch(poi->type) { case PORT_OBJECT_ANY: break; case PORT_OBJECT_PORT: #if 0 /* This test is always true since poi->lport is a 16 bit * int and MAX_PORTS is 64K. If this relationship should * change, the test should be compiled back in. */ if( poi->lport < MAX_PORTS ) #endif prm->prmSrcPort[ poi->lport ] = (PORT_GROUP*)po->data; break; case PORT_OBJECT_RANGE: for(i= poi->lport;i<= poi->hport;i++ ) { prm->prmSrcPort[ i ] = (PORT_GROUP*)po->data; } break; } } } } /* process destination port groups */ if( dst ) { for( node=sfghash_findfirst(dst->pt_mpxo_hash); node; node=sfghash_findnext(dst->pt_mpxo_hash) ) { po = (PortObject2*)node->data; if( !po ) continue; if( !po->data ) continue; /* Add up the total src rules */ prm->prmNumDstRules += po->rule_hash->count; /* Increment the port group count */ prm->prmNumDstGroups++; /* Add this port group to the src table at each port that uses it */ for( poi = (PortObjectItem*)sflist_first(po->item_list); poi; poi = (PortObjectItem*)sflist_next(po->item_list) ) { switch(poi->type) { case PORT_OBJECT_ANY: break; case PORT_OBJECT_PORT: #if 0 /* This test is always true since poi->lport is a 16 bit * int and MAX_PORTS is 64K. If this relationship should * change, the test should be compiled back in. */ if( poi->lport < MAX_PORTS ) #endif prm->prmDstPort[ poi->lport ] = (PORT_GROUP*)po->data; break; case PORT_OBJECT_RANGE: for(i= poi->lport;i<= poi->hport;i++ ) { prm->prmDstPort[ i ] = (PORT_GROUP*)po->data; } break; } } } } if( ns_src ) { for( node=sfghash_findfirst(ns_src->pt_mpxo_hash); node; node=sfghash_findnext(ns_src->pt_mpxo_hash) ) { po = (PortObject2*)node->data; if( !po ) continue; if( !po->data ) continue; /* Add up the total ns_src rules */ prm->prmNumNoServiceSrcRules += po->rule_hash->count; /* Increment the port group count */ prm->prmNumNoServiceSrcGroups ++; /* Add this port group to the ns_src table at each port that uses it */ for( poi = (PortObjectItem*)sflist_first(po->item_list); poi; poi = (PortObjectItem*)sflist_next(po->item_list) ) { switch(poi->type) { case PORT_OBJECT_ANY: break; case PORT_OBJECT_PORT: #if 0 /* This test is always true since poi->lport is a 16 bit * int and MAX_PORTS is 64K. If this relationship should * change, the test should be compiled back in. */ if( poi->lport < MAX_PORTS ) #endif prm->prmNoServiceSrcPort[ poi->lport ] = (PORT_GROUP*)po->data; break; case PORT_OBJECT_RANGE: for(i= poi->lport;i<= poi->hport;i++ ) { prm->prmNoServiceSrcPort[ i ] = (PORT_GROUP*)po->data; } break; } } } } if( ns_dst ) { for( node=sfghash_findfirst(ns_dst->pt_mpxo_hash); node; node=sfghash_findnext(ns_dst->pt_mpxo_hash) ) { po = (PortObject2*)node->data; if( !po ) continue; if( !po->data ) continue; /* Add up the total ns_dst rules */ prm->prmNumNoServiceDstRules += po->rule_hash->count; /* Increment the port group count */ prm->prmNumNoServiceDstGroups ++; /* Add this port group to the ns_dst table at each port that uses it */ for( poi = (PortObjectItem*)sflist_first(po->item_list); poi; poi = (PortObjectItem*)sflist_next(po->item_list) ) { switch(poi->type) { case PORT_OBJECT_ANY: break; case PORT_OBJECT_PORT: #if 0 /* This test is always true since poi->lport is a 16 bit * int and MAX_PORTS is 64K. If this relationship should * change, the test should be compiled back in. */ if( poi->lport < MAX_PORTS ) #endif prm->prmNoServiceDstPort[ poi->lport ] = (PORT_GROUP*)po->data; break; case PORT_OBJECT_RANGE: for(i= poi->lport;i<= poi->hport;i++ ) { prm->prmNoServiceDstPort[ i ] = (PORT_GROUP*)po->data; } break; } } } } return 0; } /* * Create and initialize the rule maps */ static int fpCreateRuleMaps(SnortConfig *sc, rule_port_tables_t *p) { sc->prmTcpRTNX = prmNewMap(); if (sc->prmTcpRTNX == NULL) return 1; if (fpCreateInitRuleMap(sc->prmTcpRTNX, p->tcp_src, p->tcp_dst, p->tcp_anyany, p->tcp_nocontent, p->ns_tcp_src, p->ns_tcp_dst )) return -1; sc->prmUdpRTNX = prmNewMap(); if (sc->prmUdpRTNX == NULL) return -1; if (fpCreateInitRuleMap(sc->prmUdpRTNX, p->udp_src, p->udp_dst, p->udp_anyany, p->udp_nocontent, p->ns_udp_src, p->ns_udp_dst)) return -1; sc->prmIpRTNX = prmNewMap(); if (sc->prmIpRTNX == NULL) return 1; if (fpCreateInitRuleMap(sc->prmIpRTNX, p->ip_src, p->ip_dst, p->ip_anyany, p->ip_nocontent, p->ns_ip_src, p->ns_ip_dst)) return -1; sc->prmIcmpRTNX = prmNewMap(); if (sc->prmIcmpRTNX == NULL) return 1; if (fpCreateInitRuleMap(sc->prmIcmpRTNX, p->icmp_src, p->icmp_dst, p->icmp_anyany, p->icmp_nocontent, p->ns_icmp_src, p->ns_icmp_dst)) return -1; return 0; } static void fpFreeRuleMaps(SnortConfig *sc) { if (sc == NULL) return; if (sc->prmTcpRTNX != NULL) { free(sc->prmTcpRTNX); sc->prmTcpRTNX = NULL; } if (sc->prmUdpRTNX != NULL) { free(sc->prmUdpRTNX); sc->prmUdpRTNX = NULL; } if (sc->prmIpRTNX != NULL) { free(sc->prmIpRTNX); sc->prmIpRTNX = NULL; } if (sc->prmIcmpRTNX != NULL) { free(sc->prmIcmpRTNX); sc->prmIcmpRTNX = NULL; } } static int fpGetFinalPattern(FastPatternConfig *fp, PatternMatchData *pmd, char **ret_pattern, int *ret_bytes) { char *pattern; int bytes; assert(fp); assert(pmd); assert(ret_pattern); assert(ret_bytes); if ((fp == NULL) || (pmd == NULL) || (ret_pattern == NULL) || (ret_bytes == NULL)) { return -1; } pattern = pmd->pattern_buf; bytes = pmd->pattern_size; /* Don't mess with fast pattern only contents - they should be inserted * into the pattern matcher as is since the content won't be evaluated * as a rule option. * Don't mess with negated contents since truncating them could * inadvertantly disable evaluation of a rule - the shorter pattern * may be found, while the unaltered pattern may not be found, * disabling inspection of a rule we should inspect */ if (pmd->fp_only || pmd->exception_flag) { *ret_pattern = pattern; *ret_bytes = bytes; return 0; } if (pmd->fp && (pmd->fp_length != 0)) { /* (offset + length) potentially being larger than the pattern itself * is taken care of during parsing */ pattern = pmd->pattern_buf + pmd->fp_offset; bytes = pmd->fp_length; } else { /* Trim leading null bytes for non-deterministic pattern matchers. * Assuming many packets may have strings of 0x00 bytes in them, * this should help performance with non-deterministic pattern matchers * that have a full next state vector at state 0. If no patterns are * inserted into the state machine that start with 0x00, failstates that * land us at state 0 will allow us to roll through the 0x00 bytes, * since the next state is deterministic in state 0 and we won't move * beyond state 0 as long as the next input char is 0x00 */ if ((fp->search_method == MPSE_AC_BNFA_Q) || (fp->search_method == MPSE_AC_BNFA)) { bytes = FLP_Trim(pmd->pattern_buf, pmd->pattern_size, &pattern); if (bytes < (int)pmd->pattern_size) { /* The patten is all '\0' - use the whole pattern * XXX This potentially hurts the performance boost * gained by stripping leading zeros */ if (bytes == 0) { bytes = pmd->pattern_size; pattern = pmd->pattern_buf; } else { fp->num_patterns_trimmed++; } } } } if ((fp->max_pattern_len != 0) && (bytes > fp->max_pattern_len)) { bytes = fp->max_pattern_len; fp->num_patterns_truncated++; } *ret_pattern = pattern; *ret_bytes = bytes; return 0; } void fpDynamicDataFree(void *data) { DynamicData *dd = (DynamicData *)data; PatternMatchData *pmd; if (dd == NULL) return; pmd = (PatternMatchData *)dd->pmds; while (pmd != NULL) { PatternMatchData *tmp = pmd->next; PatternMatchFree((void *)pmd); pmd = tmp; } free(dd); } /* * Add a rule to the proper port group RULE_NODE list * * cflag : content flag ( 0=no content, 1=content, 2=uri-content) */ static int fpAddPortGroupPrmx(PORT_GROUP *pg, OptTreeNode *otn, int cflag) { /* Add the no content rule_node to the port group (NClist) */ switch (cflag) { case PGCT_NOCONTENT: prmxAddPortRuleNC( pg, otn ); break; case PGCT_CONTENT: prmxAddPortRule( pg, otn ); break; case PGCT_URICONTENT: prmxAddPortRuleUri( pg, otn ); break; default: return -1; } return 0; } static void fpPortGroupPrintRuleCount(PORT_GROUP *pg) { PmType type; if (pg == NULL) return; LogMessage("PortGroup rule summary:\n"); for (type = PM_TYPE__CONTENT; type < PM_TYPE__MAX; type++) { int count = mpseGetPatternCount(pg->pgPms[type]); switch (type) { case PM_TYPE__CONTENT: LogMessage("\tContent: %d\n", count); break; case PM_TYPE__HTTP_URI_CONTENT: LogMessage("\tHttp Uri Content: %d\n", count); break; case PM_TYPE__HTTP_HEADER_CONTENT: LogMessage("\tHttp Header Content: %d\n", count); break; case PM_TYPE__HTTP_CLIENT_BODY_CONTENT: LogMessage("\tHttp Client Body Content: %d\n", count); break; default: break; } } LogMessage("\tNo content: %u\n", pg->pgNoContentCount); } static void fpDeletePMX(void *data) { PMX *pmx = (PMX *)data; if (data == NULL) return; if (pmx->RuleNode != NULL) free(pmx->RuleNode); free(pmx); } static void fpDeletePortGroup(void *data) { PORT_GROUP *pg = (PORT_GROUP *)data; RULE_NODE *rn, *tmpRn; PmType i; rn = pg->pgHead; while (rn) { tmpRn = rn->rnNext; free(rn); rn = tmpRn; } pg->pgHead = NULL; rn = pg->pgUriHead; while (rn) { tmpRn = rn->rnNext; free(rn); rn = tmpRn; } pg->pgUriHead = NULL; rn = pg->pgHeadNC; while (rn) { tmpRn = rn->rnNext; free(rn); rn = tmpRn; } pg->pgHeadNC = NULL; for (i = PM_TYPE__CONTENT; i < PM_TYPE__MAX; i++) { if (pg->pgPms[i] != NULL) { mpseFree(pg->pgPms[i]); pg->pgPms[i] = NULL; } } free_detection_option_root(&pg->pgNonContentTree); free(pg); } /* * Create the PortGroup for these PortObject2 entitiies * * This builds the 1st pass multi-pattern state machines for * content and uricontent based on the rules in the PortObjects * hash table. */ static int fpCreatePortObject2PortGroup(SnortConfig *sc, PortObject2 *po, PortObject2 *poaa) { SFGHASH_NODE *node; unsigned sid, gid; OptTreeNode * otn; PORT_GROUP * pg; PortObject2 *pox; FastPatternConfig *fp = sc->fast_pattern_config; /* verify we have a port object */ if (po == NULL) return 0; po->data = 0; if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) PortObject2PrintPorts( po ); /* Check if we have any rules */ if (po->rule_hash == NULL) return 0; /* create a port_group */ pg = (PORT_GROUP *)SnortAlloc(sizeof(PORT_GROUP)); if (fpAllocPms(sc, pg, fp) != 0) { free(pg); return -1; } /* * Walk the rules in the PortObject and add to * the PORT_GROUP pattern state machine * and to the port group RULE_NODE lists. * (The lists are still used in some cases * during detection to walk the rules in a group * so we have to load these as well...fpEvalHeader()... for now.) * * po src/dst ports : content/uri and nocontent * poaa any-any ports : content/uri and nocontent * * each PG has src or dst contents, generic-contents, and no-contents * (src/dst or any-any ports) * */ pox = po; while (pox != NULL) { for (node = sfghash_findfirst(pox->rule_hash); node; node = sfghash_findnext(pox->rule_hash)) { int *prindex = (int *)node->data; /* be safe - no rule index, ignore it */ if (prindex == NULL) continue; /* look up gid:sid */ gid = RuleIndexMapGid(ruleIndexMap, *prindex); sid = RuleIndexMapSid(ruleIndexMap, *prindex); /* look up otn */ otn = OtnLookup(sc->otn_map, gid, sid); if (otn == NULL) { LogMessage("fpCreatePortObject2PortGroup...failed otn lookup, " "gid=%u sid=%u\n", gid, sid); continue; } if (otn->proto == ETHERNET_TYPE_IP) { /* If only one detection option and it's ip_proto it will be evaluated * at decode time instead of detection time */ if ((otn->ds_list[PLUGIN_IP_PROTO_CHECK] != NULL) && (otn->num_detection_opts == 1)) { fpAddIpProtoOnlyRule(sc->ip_proto_only_lists, otn); continue; } fpRegIpProto(sc->ip_proto_array, otn); } if (fpAddPortGroupRule(sc, pg, otn, fp) != 0) continue; } if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) fpPortGroupPrintRuleCount(pg); if (pox == poaa) break; pox = poaa; } /* This might happen if there was ip proto only rules * Don't return failure */ if (fpFinishPortGroup(sc, pg, fp) != 0) return 0; po->data = pg; po->data_free = fpDeletePortGroup; return 0; } /* * Create the port groups for this port table */ static int fpCreatePortTablePortGroups(SnortConfig *sc, PortTable *p, PortObject2 *poaa) { SFGHASH_NODE * node; int cnt=1; FastPatternConfig *fp = sc->fast_pattern_config; if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) LogMessage("%d Port Groups in Port Table\n",p->pt_mpo_hash->count); for (node=sfghash_findfirst(p->pt_mpo_hash); //p->pt_mpxo_hash node; node=sfghash_findnext(p->pt_mpo_hash) ) //p->pt->mpxo_hash { PortObject2 * po; po = (PortObject2*)node->data; if (po == NULL) continue; if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) LogMessage("Creating Port Group Object %d of %d\n",cnt++,p->pt_mpo_hash->count); /* if the object is not referenced, don't add it to the PORT_GROUPs * as it may overwrite other objects that are more inclusive. */ if (!po->port_cnt) continue; if (fpCreatePortObject2PortGroup(sc, po, poaa)) { LogMessage("fpCreatePortObject2PortGroup() failed\n"); return -1; } if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) mpsePrintSummary(fp->search_method); } return 0; } /* * Create port group objects for all port tables * * note: any-any ports are standard PortObjects not PortObject2's so we have to * uprade them for the create port group function */ static int fpCreatePortGroups(SnortConfig *sc, rule_port_tables_t *p) { PortObject2 *po2, *add_any_any = NULL; FastPatternConfig *fp = sc->fast_pattern_config; if (!rule_count) return 0 ; /* TCP */ /* convert the tcp-any-any to a PortObject2 creature */ po2 = PortObject2Dup(p->tcp_anyany); if (po2 == NULL) FatalError("Could not create a PortObject version 2 for tcp-any-any rules\n!"); if (!fpDetectSplitAnyAny(fp)) add_any_any = po2; if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) LogMessage("TCP-SRC\n"); if (fpCreatePortTablePortGroups(sc, p->tcp_src, add_any_any)) { LogMessage("fpCreatePorTablePortGroups failed-tcp_src\n"); return -1; } if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) LogMessage("TCP-DST\n"); if (fpCreatePortTablePortGroups(sc, p->tcp_dst, add_any_any)) { LogMessage("fpCreatePorTablePortGroups failed-tcp_dst\n"); return -1; } #ifdef TARGET_BASED if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) LogMessage("NS-TCP-SRC\n"); if (fpCreatePortTablePortGroups(sc, p->ns_tcp_src, add_any_any)) { LogMessage("fpCreatePortTablePortGroups failed-ns_tcp_src\n"); return -1; } if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) LogMessage("NS-TCP-DST\n"); if (fpCreatePortTablePortGroups(sc, p->ns_tcp_dst, add_any_any)) { LogMessage("fpCreatePortTablePortGroups failed-ns_tcp_dst\n"); return -1; } #endif if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) LogMessage("TCP-ANYANY\n"); if (fpCreatePortObject2PortGroup(sc, po2, 0)) { LogMessage("fpCreatePorTablePortGroups failed-tcp any-any\n"); return -1; } /* save the any-any port group */ p->tcp_anyany->data = po2->data; p->tcp_anyany->data_free = fpDeletePortGroup; po2->data = 0; /* release the dummy PortObject2 copy of tcp-any-any */ //LogMessage("fpcreate: calling PortObjectFree2(po2), line = %d\n",__LINE__ ); PortObject2Free(po2); /* UDP */ po2 = PortObject2Dup(p->udp_anyany); if (po2 == NULL ) FatalError("Could not create a PortObject version 2 for udp-any-any rules\n!"); if (!fpDetectSplitAnyAny(fp)) add_any_any = po2; if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) LogMessage("UDP-SRC\n"); if (fpCreatePortTablePortGroups(sc, p->udp_src, add_any_any)) { LogMessage("fpCreatePorTablePortGroups failed-udp_src\n"); return -1; } if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) LogMessage("UDP-DST\n"); if (fpCreatePortTablePortGroups(sc, p->udp_dst, add_any_any)) { LogMessage("fpCreatePorTablePortGroups failed-udp_dst\n"); return -1; } #ifdef TARGET_BASED if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) LogMessage("NS-UDP-SRC\n"); if (fpCreatePortTablePortGroups(sc, p->ns_udp_src, add_any_any)) { LogMessage("fpCreatePorTablePortGroups failed-ns_udp_src\n"); return -1; } if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) LogMessage("NS-UDP-DST\n"); if (fpCreatePortTablePortGroups(sc, p->ns_udp_dst, add_any_any)) { LogMessage("fpCreatePorTablePortGroups failed-ns_udp_dst\n"); return -1; } #endif // TARGET_BASED if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) LogMessage("UDP-ANYANY\n"); if (fpCreatePortObject2PortGroup(sc, po2, 0)) { LogMessage("fpCreatePortObject2PortGroup failed-udp_anyany\n"); return -1; } p->udp_anyany->data = po2->data; p->udp_anyany->data_free = fpDeletePortGroup; po2->data = 0; //LogMessage("fpcreate: calling PortObjectFree2(po2), line = %d\n",__LINE__ ); PortObject2Free(po2); /* ICMP */ po2 = PortObject2Dup(p->icmp_anyany); if (po2 == NULL) FatalError("Could not create a PortObject version 2 for icmp-any-any rules\n!"); if (!fpDetectSplitAnyAny(fp)) add_any_any = po2; if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) LogMessage("\nICMP-SRC "); if (fpCreatePortTablePortGroups(sc, p->icmp_src, add_any_any)) { LogMessage("fpCreatePorTablePortGroups failed-icmp_src\n"); return -1; } if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) LogMessage("\nICMP-DST "); if (fpCreatePortTablePortGroups(sc, p->icmp_dst, add_any_any)) { LogMessage("fpCreatePorTablePortGroups failed-icmp_src\n"); return -1; } #ifdef TARGET_BASED if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) LogMessage("\nNS-ICMP-SRC"); if (fpCreatePortTablePortGroups(sc, p->ns_icmp_src, add_any_any)) { LogMessage("fpCreatePorTablePortGroups failed-ns_icmp_src\n"); return -1; } if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) LogMessage("\nNS-ICMP-DST"); if (fpCreatePortTablePortGroups(sc, p->ns_icmp_dst, add_any_any)) { LogMessage("fpCreatePorTablePortGroups failed-ns_icmp_dst\n"); return -1; } #endif // TARGET_BASED if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) LogMessage("\nICMP-ANYANY "); if (fpCreatePortObject2PortGroup(sc, po2, 0)) { LogMessage("fpCreatePorTablePortGroups failed-icmp any-any\n"); return -1; } p->icmp_anyany->data = po2->data; p->icmp_anyany->data_free = fpDeletePortGroup; po2->data = 0; //LogMessage("fpcreate: calling PortObjectFree2(po2), line = %d\n",__LINE__ ); PortObject2Free(po2); /* IP */ po2 = PortObject2Dup(p->ip_anyany); if (po2 == NULL) FatalError("Could not create a PortObject version 2 for ip-any-any rules\n!"); if (!fpDetectSplitAnyAny(fp)) add_any_any = po2; if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) LogMessage("\nIP-SRC "); if (fpCreatePortTablePortGroups(sc, p->ip_src, add_any_any)) { LogMessage("fpCreatePorTablePortGroups failed-ip_src\n"); return -1; } if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) LogMessage("\nIP-DST "); if (fpCreatePortTablePortGroups(sc, p->ip_dst, add_any_any)) { LogMessage("fpCreatePorTablePortGroups failed-ip_dst\n"); return -1; } #ifdef TARGET_BASED if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) LogMessage("\nNS-IP-SRC "); if (fpCreatePortTablePortGroups(sc, p->ns_ip_src, add_any_any)) { LogMessage("fpCreatePorTablePortGroups failed-ns_ip_src\n"); return -1; } if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) LogMessage("\nNS-IP-DST "); if (fpCreatePortTablePortGroups(sc, p->ns_ip_dst, add_any_any)) { LogMessage("fpCreatePorTablePortGroups failed-ns_ip_dst\n"); return -1; } #endif // TARGET_BASED if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) LogMessage("\nIP-ANYANY "); if (fpCreatePortObject2PortGroup(sc, po2, 0)) { LogMessage("fpCreatePorTablePortGroups failed-ip any-any\n"); return -1; } p->ip_anyany->data = po2->data; p->ip_anyany->data_free = fpDeletePortGroup; po2->data = 0; //LogMessage("fpcreate: calling PortObjectFree2(po2), line = %d\n",__LINE__ ); PortObject2Free(po2); return 0; } /* * Scan the master otn lists and and pass * * * enabled - if true requires otn to be enabled * fcn - callback * proto - IP,TCP,IDP,ICMP protocol flag * otn - OptTreeNode */ void fpWalkOtns(int enabled, OtnWalkFcn fcn) { RuleTreeNode *rtn; SFGHASH_NODE *hashNode; OptTreeNode *otn = NULL; tSfPolicyId policyId = 0; if (snort_conf == NULL) return; for (hashNode = sfghash_findfirst(snort_conf->otn_map); hashNode; hashNode = sfghash_findnext(snort_conf->otn_map)) { otn = (OptTreeNode *)hashNode->data; for ( policyId = 0; policyId < otn->proto_node_num; policyId++ ) { rtn = getRtnFromOtn(otn, policyId); /* There can be gaps in the list of rtns. */ if (rtn == NULL) continue; if ((rtn->proto == IPPROTO_TCP) || (rtn->proto == IPPROTO_UDP) || (rtn->proto == IPPROTO_ICMP) || (rtn->proto == ETHERNET_TYPE_IP)) { //do operation if ( enabled && (otn->rule_state != RULE_STATE_ENABLED) ) { continue; } fcn( rtn->proto, rtn, otn ); } } } } #ifdef TARGET_BASED /* * Scan the master otn lists and load the Service maps * for service based rule grouping. */ static int fpCreateServiceMaps(SnortConfig *sc) { RuleTreeNode *rtn; SFGHASH_NODE *hashNode; OptTreeNode *otn = NULL; tSfPolicyId policyId = 0; unsigned int svc_idx; for (hashNode = sfghash_findfirst(sc->otn_map); hashNode; hashNode = sfghash_findnext(sc->otn_map)) { otn = (OptTreeNode *)hashNode->data; for ( policyId = 0; policyId < otn->proto_node_num; policyId++ ) { rtn = getRtnFromOtn(otn, policyId); if (rtn && ((rtn->proto == IPPROTO_TCP) || (rtn->proto == IPPROTO_UDP) || (rtn->proto == IPPROTO_ICMP) || (rtn->proto == ETHERNET_TYPE_IP))) { /* Non-content preprocessor or decoder rule. * don't add it */ if (otn->sigInfo.rule_type != SI_RULE_TYPE_DETECT) continue; /* Not enabled, don't do the FP content */ if (otn->rule_state != RULE_STATE_ENABLED) continue; for (svc_idx = 0; svc_idx < otn->sigInfo.num_services; svc_idx++) { if (ServiceMapAddOtn(sc->srmmTable, rtn->proto, otn->sigInfo.services[svc_idx].service, otn)) return -1; } } } } return 0; } /* * Build a Port Group for this service based on the list of otns. The final * port_group pointer is stored using the service name as the key. * * p - hash table mapping services to port_groups * srvc- service name, key used to store the port_group * ...could use a service id instead (bytes, fixed length,etc...) * list- list of otns for this service */ void fpBuildServicePortGroupByServiceOtnList(SnortConfig *sc, SFGHASH *p, const char *srvc, SF_LIST *list, FastPatternConfig *fp) { OptTreeNode * otn; int status; PORT_GROUP *pg = (PORT_GROUP *)SnortAlloc(sizeof(PORT_GROUP)); if (fpAllocPms(sc, pg, fp) != 0) { free(pg); return; } /* * add each rule to the port group pattern matchers, * or to the no-content rule list */ for (otn = sflist_first(list); otn; otn = sflist_next(list)) { if (otn->proto == ETHERNET_TYPE_IP) { /* If only one detection option and it's ip_proto it will be evaluated * at decode time instead of detection time * These will have already been added when adding port groups */ if ((otn->ds_list[PLUGIN_IP_PROTO_CHECK] != NULL) && (otn->num_detection_opts == 1)) { continue; } } if (fpAddPortGroupRule(sc, pg, otn, fp) != 0) continue; } if (fpFinishPortGroup(sc, pg, fp) != 0) return; /* Add the port_group using it's service name */ status = sfghash_add(p, srvc, pg); switch(status) { case SFGHASH_OK : /* port_group is successfully added using it's service name */ break; case SFGHASH_ERR : LogMessage("fpBuildServicePortGroupByServiceOtnList : Hash table is NULL. \n"); break; case SFGHASH_INTABLE : break; case SFGHASH_NOMEM : LogMessage("Failed to allocate memory to port_group/service.\n"); break; default : break; } } /* * For each service we create a PORT_GROUP based on the otn's defined to * be applicable to that service by the metadata option. * * Than we lookup the protocol/srvc oridinal in the target-based area * and assign the PORT_GROUP for the srvc to it. * * spg - service port group (lookup should be by service id/tag) * - this table maintains a port_group ptr for each service * srm - service rule map table (lookup by ascii service name) * - this table maintains a sf_list ptr (list of rule otns) for each service * */ void fpBuildServicePortGroups(SnortConfig *sc, SFGHASH *spg, PORT_GROUP **sopg, SFGHASH *srm, FastPatternConfig *fp) { SFGHASH_NODE * n; const char * srvc; SF_LIST * list; PORT_GROUP * pg; for(n=sfghash_findfirst(srm); n; n=sfghash_findnext(srm) ) { list = (SF_LIST *)n->data; if(!list)continue; srvc = n->key; if(!srvc)continue; fpBuildServicePortGroupByServiceOtnList(sc, spg, srvc, list, fp); /* Add this PORT_GROUP to the protocol-ordinal -> port_group table */ pg = sfghash_find( spg, srvc ); if( pg ) { int16_t id; id = FindProtocolReference(srvc); if(id==SFTARGET_UNKNOWN_PROTOCOL) { id = AddProtocolReference(srvc); if(id <=0 ) { FatalError("Could not AddProtocolReference!\n"); } if( id >= MAX_PROTOCOL_ORDINAL ) { LogMessage("fpBuildServicePortGroups: protocol-ordinal=%d exceeds " "limit of %d for service=%s\n",id,MAX_PROTOCOL_ORDINAL,srvc); } } else if( id > 0 ) { if( id < MAX_PROTOCOL_ORDINAL ) { sopg[ id ] = pg; LogMessage("fpBuildServicePortGroups: adding protocol-ordinal=%d " "as service=%s\n",id,srvc); } else { LogMessage("fpBuildServicePortGroups: protocol-ordinal=%d exceeds " "limit of %d for service=%s\n",id,MAX_PROTOCOL_ORDINAL,srvc); } } else /* id < 0 */ { LogMessage("fpBuildServicePortGroups: adding protocol-ordinal=%d for " "service=%s, can't use that !!!\n",id,srvc); } } else { LogMessage("*** fpBuildServicePortGroups: failed to create and find a port group for '%s' !!! \n",srvc ); } } } /* * For each proto+dir+service build a PORT_GROUP */ static void fpCreateServiceMapPortGroups(SnortConfig *sc) { FastPatternConfig *fp = sc->fast_pattern_config; sc->spgmmTable = ServicePortGroupMapNew(); sc->sopgTable = ServicePortGroupTableNew(); fpBuildServicePortGroups(sc, sc->spgmmTable->tcp_to_srv, sc->sopgTable->tcp_to_srv, sc->srmmTable->tcp_to_srv, fp); fpBuildServicePortGroups(sc, sc->spgmmTable->tcp_to_cli, sc->sopgTable->tcp_to_cli, sc->srmmTable->tcp_to_cli, fp); fpBuildServicePortGroups(sc, sc->spgmmTable->udp_to_srv, sc->sopgTable->udp_to_srv, sc->srmmTable->udp_to_srv, fp); fpBuildServicePortGroups(sc, sc->spgmmTable->udp_to_cli, sc->sopgTable->udp_to_cli, sc->srmmTable->udp_to_cli, fp); fpBuildServicePortGroups(sc, sc->spgmmTable->icmp_to_srv, sc->sopgTable->icmp_to_srv, sc->srmmTable->icmp_to_srv, fp); fpBuildServicePortGroups(sc, sc->spgmmTable->icmp_to_cli, sc->sopgTable->icmp_to_cli, sc->srmmTable->icmp_to_cli, fp); fpBuildServicePortGroups(sc, sc->spgmmTable->ip_to_srv, sc->sopgTable->ip_to_srv, sc->srmmTable->ip_to_srv, fp); fpBuildServicePortGroups(sc, sc->spgmmTable->ip_to_cli, sc->sopgTable->ip_to_srv, sc->srmmTable->ip_to_cli, fp); } PORT_GROUP * fpGetServicePortGroupByOrdinal(sopg_table_t *sopg, int proto, int dir, int16_t proto_ordinal) { //SFGHASH_NODE * n; PORT_GROUP *pg = NULL; if (proto_ordinal >= MAX_PROTOCOL_ORDINAL) return NULL; if (sopg == NULL) return NULL; switch (proto) { case IPPROTO_TCP: if (dir == TO_SERVER) pg = sopg->tcp_to_srv[proto_ordinal]; else pg = sopg->tcp_to_cli[proto_ordinal]; break; case IPPROTO_UDP: if (dir == TO_SERVER) pg = sopg->udp_to_srv[proto_ordinal]; else pg = sopg->udp_to_cli[proto_ordinal]; break; case IPPROTO_ICMP: if (dir == TO_SERVER) pg = sopg->icmp_to_srv[proto_ordinal]; else pg = sopg->icmp_to_cli[proto_ordinal]; break; case ETHERNET_TYPE_IP: if (dir == TO_SERVER) pg = sopg->ip_to_srv[proto_ordinal]; else pg = sopg->ip_to_cli[proto_ordinal]; break; default: break; } return pg; } /* * Print the rule gid:sid based onm the otn list */ void fpPrintRuleList( SF_LIST * list ) { OptTreeNode * otn; for( otn=(OptTreeNode*)sflist_first(list); otn; otn=(OptTreeNode*)sflist_next(list) ) { LogMessage("| %u:%u\n",otn->sigInfo.generator,otn->sigInfo.id); } } static void fpPrintServiceRuleMapTable( SFGHASH * p, char * msg ) { SFGHASH_NODE * n; if( !p || !p->count ) return; LogMessage("| Protocol [%s] %d services\n",msg,p->count ); LogMessage("----------------------------------------------------\n"); for( n = sfghash_findfirst(p); n; n = sfghash_findnext(p) ) { SF_LIST * list; list = (SF_LIST*)n->data; if( !list ) continue; if( !n->key ) continue; LogMessage("| Service [%s] %d rules, rule list follows as gid:sid.\n", (char*)n->key, list->count); fpPrintRuleList( list ); } LogMessage("----------------------------------------------------\n"); } static void fpPrintServiceRuleMaps(srmm_table_t *service_map) { LogMessage("+---------------------------------------------------\n"); LogMessage("| Service Rule Maps\n"); LogMessage("----------------------------------------------------\n"); fpPrintServiceRuleMapTable( service_map->tcp_to_srv, "tcp to server" ); fpPrintServiceRuleMapTable( service_map->tcp_to_cli, "tcp to client" ); fpPrintServiceRuleMapTable( service_map->udp_to_srv, "udp to server" ); fpPrintServiceRuleMapTable( service_map->udp_to_cli, "udp to client" ); fpPrintServiceRuleMapTable( service_map->icmp_to_srv, "icmp to server" ); fpPrintServiceRuleMapTable( service_map->icmp_to_cli, "icmp to client" ); fpPrintServiceRuleMapTable( service_map->ip_to_srv, "ip to server" ); fpPrintServiceRuleMapTable( service_map->ip_to_cli, "ip to client" ); } /* * */ void fpPrintServicePortGroupSummary(srmm_table_t *srvc_pg_map) { LogMessage("+--------------------------------\n"); LogMessage("| Service-PortGroup Table Summary \n"); LogMessage("---------------------------------\n"); if(srvc_pg_map->tcp_to_srv->count) LogMessage("| tcp to server : %d services\n",srvc_pg_map->tcp_to_srv->count); if(srvc_pg_map->tcp_to_cli->count) LogMessage("| tcp to cient : %d services\n",srvc_pg_map->tcp_to_cli->count); if(srvc_pg_map->udp_to_srv->count) LogMessage("| udp to server : %d services\n",srvc_pg_map->udp_to_srv->count); if(srvc_pg_map->udp_to_cli->count) LogMessage("| udp to cient : %d services\n",srvc_pg_map->udp_to_cli->count); if(srvc_pg_map->icmp_to_srv->count) LogMessage("| icmp to server : %d services\n",srvc_pg_map->icmp_to_srv->count); if(srvc_pg_map->icmp_to_cli->count) LogMessage("| icmp to cient : %d services\n",srvc_pg_map->icmp_to_cli->count); if(srvc_pg_map->ip_to_srv->count) LogMessage("| ip to server : %d services\n",srvc_pg_map->ip_to_srv->count); if(srvc_pg_map->ip_to_cli->count) LogMessage("| ip to cient : %d services\n",srvc_pg_map->ip_to_cli->count); LogMessage("---------------------------------\n"); } /* * Build Service based PORT_GROUPs using the rules * metadata option service parameter. */ static int fpCreateServicePortGroups(SnortConfig *sc) { FastPatternConfig *fp = sc->fast_pattern_config; sc->srmmTable = ServiceMapNew(); if (fpCreateServiceMaps(sc)) return -1; if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) fpPrintServiceRuleMaps(sc->srmmTable); fpCreateServiceMapPortGroups(sc); if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) fpPrintServicePortGroupSummary(sc->spgmmTable); //srvcmap_term(); return 0; } //TARGET_BASED #endif /* * Port list version * * 7/2007 - man * * Build Pattern Groups for 1st pass of content searching using * multi-pattern search method. */ int fpCreateFastPacketDetection(SnortConfig *sc) { rule_port_tables_t *port_tables; FastPatternConfig *fp; /* This is somewhat necessary because of how the detection option trees * are added via a callback from the pattern matcher */ if(!rule_count || (sc == NULL)) return 0; port_tables = sc->port_tables; fp = sc->fast_pattern_config; if ((port_tables == NULL) || (fp == NULL)) return 0; #ifdef INTEL_SOFT_CPM if (fp->search_method == MPSE_INTEL_CPM) IntelPmStartInstance(); #endif /* Use PortObjects to create PORT_GROUPs */ if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) LogMessage("Creating Port Groups....\n"); if (fpCreatePortGroups(sc, port_tables)) FatalError("Could not create PortGroup objects for PortObjects\n"); if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) LogMessage("Port Groups Done....\n"); /* Create rule_maps */ if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) LogMessage("Creating Rule Maps....\n"); if (fpCreateRuleMaps(sc, port_tables)) FatalError("Could not create rule maps\n"); if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) LogMessage("Rule Maps Done....\n"); #ifndef TARGET_BASED LogMessage("\n"); LogMessage("[ Port Based Pattern Matching Memory ]\n" ); mpsePrintSummary(fp->search_method); if (fp->max_pattern_len != 0) { LogMessage("[ Number of patterns truncated to %d bytes: %d ]\n", fp->max_pattern_len, fp->num_patterns_truncated); } if (fp->num_patterns_trimmed != 0) { LogMessage("[ Number of null byte prefixed patterns trimmed: %d ]\n", fp->num_patterns_trimmed); } #else if (IsAdaptiveConfiguredForSnortConfig(sc) || fpDetectGetDebugPrintFastPatterns(fp)) { if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) LogMessage("Creating Service Based Rule Maps....\n"); /* Build Service based port groups - rules require service metdata * i.e. 'metatdata: service [=] service-name, ... ;' * * Also requires a service attribute for lookup ... */ if (fpCreateServicePortGroups(sc)) FatalError("Could not create service based port groups\n"); if (fpDetectGetDebugPrintRuleGroupBuildDetails(fp)) LogMessage("Service Based Rule Maps Done....\n"); LogMessage("\n"); LogMessage("[ Port and Service Based Pattern Matching Memory ]\n" ); } else { LogMessage("\n"); LogMessage("[ Port Based Pattern Matching Memory ]\n" ); } mpsePrintSummary(fp->search_method); if (fp->max_pattern_len != 0) { LogMessage("[ Number of patterns truncated to %d bytes: %d ]\n", fp->max_pattern_len, fp->num_patterns_truncated); } if (fp->num_patterns_trimmed != 0) { LogMessage("[ Number of null byte prefixed patterns trimmed: %d ]\n", fp->num_patterns_trimmed); } #endif #ifdef INTEL_SOFT_CPM if (fp->search_method == MPSE_INTEL_CPM) IntelPmCompile(sc); #endif return 0; } void fpDeleteFastPacketDetection(SnortConfig *sc) { if (sc == NULL) return; /* Cleanup the detection option tree */ DetectionHashTableFree(sc->detection_option_hash_table); DetectionTreeHashTableFree(sc->detection_option_tree_hash_table); fpFreeRuleMaps(sc); #ifdef TARGET_BASED ServiceMapFree(sc->srmmTable); ServicePortGroupMapFree(sc->spgmmTable); if (sc->sopgTable != NULL) free(sc->sopgTable); #endif } /* ** Wrapper for prmShowEventStats */ void fpShowEventStats(SnortConfig *sc) { if ((sc == NULL) || (sc->fast_pattern_config == NULL)) return; /* If not debug, then we don't print anything. */ if (!sc->fast_pattern_config->debug) return; LogMessage("\n"); LogMessage("** TCP Event Stats --\n"); prmShowEventStats(sc->prmTcpRTNX); LogMessage("\n"); LogMessage("** UDP Event Stats --\n"); prmShowEventStats(sc->prmUdpRTNX); LogMessage("\n"); LogMessage("** ICMP Event Stats --\n"); prmShowEventStats(sc->prmIcmpRTNX); LogMessage("\n"); LogMessage("** IP Event Stats --\n"); prmShowEventStats(sc->prmIpRTNX); } static void fpAddIpProtoOnlyRule(SF_LIST **ip_proto_only_lists, OptTreeNode *otn) { uint8_t ip_protos[NUM_IP_PROTOS]; unsigned int i; if ((otn->ds_list[PLUGIN_IP_PROTO_CHECK] == NULL) || (otn->num_detection_opts != 1)) { return; } if (GetIpProtos(otn->ds_list[PLUGIN_IP_PROTO_CHECK], ip_protos, sizeof(ip_protos)) != 0) FatalError("%s(%d) Error getting ip protocols\n", __FILE__, __LINE__); for (i = 0; i < NUM_IP_PROTOS; i++) { OptTreeNode *dup; if (ip_protos[i]) { if (ip_proto_only_lists[i] == NULL) { ip_proto_only_lists[i] = sflist_new(); if (ip_proto_only_lists[i] == NULL) { FatalError("%s(%d) Could not allocate memory for " "ip_proto array\n", __FILE__, __LINE__); } } /* Search for dups */ for (dup = (OptTreeNode *)sflist_first(ip_proto_only_lists[i]); dup != NULL; dup = (OptTreeNode *)sflist_next(ip_proto_only_lists[i])) { if (dup == otn) return; } if (sflist_add_head(ip_proto_only_lists[i], otn) != 0) { FatalError("%s(%d) Failed to add otn to ip_proto array\n", __FILE__, __LINE__); } } } } static void fpRegIpProto(uint8_t *ip_proto_array, OptTreeNode *otn) { uint8_t ip_protos[NUM_IP_PROTOS]; unsigned int i; if (GetIpProtos(otn->ds_list[PLUGIN_IP_PROTO_CHECK], ip_protos, sizeof(ip_protos)) != 0) FatalError("%s(%d) Error getting ip protocols\n", __FILE__, __LINE__); for (i = 0; i < NUM_IP_PROTOS; i++) if (ip_protos[i]) ip_proto_array[i] = 1; } const char * PatternRawToContent(const char *pattern, int pattern_len) { static char content_buf[1024]; int max_write_size = sizeof(content_buf) - 64; int i, j = 0; int hex = 0; if ((pattern == NULL) || (pattern_len <= 0)) return ""; content_buf[j++] = '"'; for (i = 0; i < pattern_len; i++) { uint8_t c = (uint8_t)pattern[i]; if ((c < 128) && isprint(c) && !isspace(c) && (c != '|') && (c != '"') && (c != ';')) { if (hex) { content_buf[j-1] = '|'; hex = 0; } content_buf[j++] = c; } else { uint8_t up4, lo4; if (!hex) { content_buf[j++] = '|'; hex = 1; } up4 = c >> 4; lo4 = c & 0x0f; if (up4 > 0x09) up4 += ('A' - 0x0a); else up4 += '0'; if (lo4 > 0x09) lo4 += ('A' - 0x0a); else lo4 += '0'; content_buf[j++] = up4; content_buf[j++] = lo4; content_buf[j++] = ' '; } if (j > max_write_size) break; } if (j > max_write_size) { content_buf[j] = 0; SnortSnprintfAppend(content_buf, sizeof(content_buf), " ... \" (pattern too large)"); } else { if (hex) content_buf[j-1] = '|'; content_buf[j++] = '"'; content_buf[j] = 0; } return content_buf; } static void PrintFastPatternInfo(OptTreeNode *otn, PatternMatchData *pmd, const char *pattern, int pattern_length, PmType pm_type) { if ((otn == NULL) || (pmd == NULL)) return; LogMessage("%u:%u\n", otn->sigInfo.generator, otn->sigInfo.id); LogMessage(" Fast pattern matcher: %s\n", pm_type_strings[pm_type]); LogMessage(" Fast pattern set: %s\n", pmd->fp ? "yes" : "no"); LogMessage(" Fast pattern only: %s\n", pmd->fp_only ? "yes" : "no"); LogMessage(" Negated: %s\n", pmd->exception_flag ? "yes" : "no"); /* Fast pattern only patterns don't use offset and length */ if ((pmd->fp_length != 0) && !pmd->fp_only) { LogMessage(" Pattern : %d,%d\n", pmd->fp_offset, pmd->fp_length); LogMessage(" %s\n", PatternRawToContent(pmd->pattern_buf + pmd->fp_offset, pmd->fp_length)); } else { LogMessage(" Pattern offset,length: none\n"); } /* Fast pattern only patterns don't get truncated */ if (!pmd->fp_only && (((pmd->fp_length != 0) && (pmd->fp_length > pattern_length)) || ((pmd->fp_length == 0) && ((int)pmd->pattern_size > pattern_length)))) { LogMessage(" Pattern truncated: %d to %d bytes\n", pmd->fp_length ? pmd->fp_length : pmd->pattern_size, pattern_length); } else { LogMessage(" Pattern truncated: no\n"); } LogMessage(" Original pattern\n"); LogMessage(" %s\n", PatternRawToContent(pmd->pattern_buf,pmd->pattern_size)); LogMessage(" Final pattern\n"); LogMessage(" %s\n", PatternRawToContent(pattern, pattern_length)); } snort-2.9.15.1/src/fpcreate.h0000644000175200017520000001557113571422607012612 00000000000000/* ** $Id$ ** ** fpcreate.h ** ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Dan Roelker ** Marc Norton ** ** NOTES ** 5.7.02 - Initial Sourcecode. Norton/Roelker ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** ** 6/13/05 - marc norton ** Added plugin support for fast pattern match data ** */ #ifndef __FPCREATE_H__ #define __FPCREATE_H__ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "rules.h" #include "treenodes.h" //#include "parser.h" #include "pcrm.h" /* * Max Number of Protocols Supported by Rules in fpcreate.c * for tcp,udp,icmp,ip ... this is an array dimesnion used to * map protocol-ordinals to port_groups ... */ /* This is now defined in sftarget_protocol_refererence.h" * #define MAX_PROTOCOL_ORDINAL 8192 */ #include "sftarget_protocol_reference.h" /* * This controls how many fast pattern match contents may be * used/retrieved per rule in fpcreate.c. */ #define PLUGIN_MAX_FPLIST_SIZE 16 #define PL_BLEEDOVER_WARNINGS_ENABLED 0x01 #define PL_DEBUG_PRINT_NC_DETECT_RULES 0x02 #define PL_DEBUG_PRINT_RULEGROWP_BUILD 0x04 #define PL_DEBUG_PRINT_RULEGROUPS_UNCOMPILED 0x08 #define PL_DEBUG_PRINT_RULEGROUPS_COMPILED 0x10 #define PL_SINGLE_RULE_GROUP 0x20 typedef struct _pmx_ { void * RuleNode; void * PatternMatchData; } PMX; /* Used for negative content list */ typedef struct _NCListNode { PMX *pmx; struct _NCListNode *next; } NCListNode; /* ** This structure holds configuration options for the ** detection engine. */ typedef struct _FastPatternConfig { int inspect_stream_insert; int search_method; int search_opt; int search_method_verbose; int debug; unsigned int max_queue_events; unsigned int bleedover_port_limit; int configured; int portlists_flags; int split_any_any; int max_pattern_len; int num_patterns_truncated; /* due to max_pattern_len */ int num_patterns_trimmed; /* due to zero byte prefix */ int debug_print_fast_pattern; } FastPatternConfig; #ifdef TARGET_BASED /* * Service Rule Map Master Table */ typedef struct { SFGHASH * tcp_to_srv; SFGHASH * tcp_to_cli; SFGHASH * udp_to_srv; SFGHASH * udp_to_cli; SFGHASH * icmp_to_srv; SFGHASH * icmp_to_cli; SFGHASH * ip_to_srv; SFGHASH * ip_to_cli; } srmm_table_t; /* * Service/Protocol Oridinal To PORT_GROUP table */ typedef struct { PORT_GROUP *tcp_to_srv[MAX_PROTOCOL_ORDINAL]; PORT_GROUP *tcp_to_cli[MAX_PROTOCOL_ORDINAL]; PORT_GROUP *udp_to_srv[MAX_PROTOCOL_ORDINAL]; PORT_GROUP *udp_to_cli[MAX_PROTOCOL_ORDINAL]; PORT_GROUP *icmp_to_srv[MAX_PROTOCOL_ORDINAL]; PORT_GROUP *icmp_to_cli[MAX_PROTOCOL_ORDINAL]; PORT_GROUP *ip_to_srv[MAX_PROTOCOL_ORDINAL]; PORT_GROUP *ip_to_cli[MAX_PROTOCOL_ORDINAL]; } sopg_table_t; #endif /* ** This function initializes the detection engine configuration ** options before setting them. */ int fpInitDetectionEngine(void); /* ** This is the main routine to create a FastPacket inspection ** engine. It reads in the snort list of RTNs and OTNs and ** assigns them to PORT_MAPS. */ int fpCreateFastPacketDetection(struct _SnortConfig *); FastPatternConfig * FastPatternConfigNew(void); void fpSetDefaults(FastPatternConfig *); void FastPatternConfigFree(FastPatternConfig *); /* ** Functions that allow the detection routins to ** find the right classification for a given packet. */ int prmFindRuleGroupIp(PORT_RULE_MAP *, int, PORT_GROUP **, PORT_GROUP **); int prmFindRuleGroupIcmp(PORT_RULE_MAP *, int, PORT_GROUP **, PORT_GROUP **); #ifdef TARGET_BASED int prmFindRuleGroupTcp(PORT_RULE_MAP *prm, int dport, int sport, PORT_GROUP ** src, PORT_GROUP **dst, PORT_GROUP **nssrc, PORT_GROUP **nsdst, PORT_GROUP ** gen); int prmFindRuleGroupUdp(PORT_RULE_MAP *prm, int dport, int sport, PORT_GROUP ** src, PORT_GROUP ** dst, PORT_GROUP **nssrc, PORT_GROUP **nsdst, PORT_GROUP ** gen); #else int prmFindRuleGroupTcp(PORT_RULE_MAP *, int, int, PORT_GROUP **, PORT_GROUP **, PORT_GROUP **); int prmFindRuleGroupUdp(PORT_RULE_MAP *, int, int, PORT_GROUP **, PORT_GROUP **, PORT_GROUP **); #endif int fpSetDetectSearchMethod(FastPatternConfig *, char *); void fpSetDetectSearchOpt(FastPatternConfig *, int flag); void fpSetDebugMode(FastPatternConfig *); void fpSetStreamInsert(FastPatternConfig *); void fpSetMaxQueueEvents(FastPatternConfig *, unsigned int); void fpDetectSetSplitAnyAny(FastPatternConfig *, int); void fpSetMaxPatternLen(FastPatternConfig *, unsigned int); void fpDetectSetSingleRuleGroup(FastPatternConfig *); void fpDetectSetBleedOverPortLimit(FastPatternConfig *, unsigned int); void fpDetectSetBleedOverWarnings(FastPatternConfig *); void fpDetectSetDebugPrintNcRules(FastPatternConfig *); void fpDetectSetDebugPrintRuleGroupBuildDetails(FastPatternConfig *); void fpDetectSetDebugPrintRuleGroupsCompiled(FastPatternConfig *); void fpDetectSetDebugPrintRuleGroupsUnCompiled(FastPatternConfig *); void fpDetectSetDebugPrintFastPatterns(FastPatternConfig *, int); int fpDetectGetSingleRuleGroup(FastPatternConfig *); int fpDetectGetBleedOverPortLimit(FastPatternConfig *); int fpDetectGetBleedOverWarnings(FastPatternConfig *); int fpDetectGetDebugPrintNcRules(FastPatternConfig *); int fpDetectGetDebugPrintRuleGroupBuildDetails(FastPatternConfig *); int fpDetectGetDebugPrintRuleGroupsCompiled(FastPatternConfig *); int fpDetectGetDebugPrintRuleGroupsUnCompiled(FastPatternConfig *); int fpDetectSplitAnyAny(FastPatternConfig *); int fpDetectGetDebugPrintFastPatterns(FastPatternConfig *); void fpDeleteFastPacketDetection(struct _SnortConfig *); void free_detection_option_tree(detection_option_tree_node_t *node); int OtnFlowDir( OptTreeNode * p ); #ifdef TARGET_BASED PORT_GROUP * fpGetServicePortGroupByOrdinal(sopg_table_t *, int, int, int16_t); #endif /* ** Shows the event stats for the created FastPacketDetection */ void fpShowEventStats(struct _SnortConfig *); typedef int (*OtnWalkFcn)(int, RuleTreeNode *, OptTreeNode *); void fpWalkOtns(int, OtnWalkFcn); void fpDynamicDataFree(void *); const char * PatternRawToContent(const char *pattern, int pattern_len); #endif /* __FPCREATE_H__ */ snort-2.9.15.1/src/fpdetect.c0000644000175200017520000015345313571422607012614 00000000000000/* ** $Id$ ** ** fpdetect.c ** ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Author(s): Dan Roelker ** Marc Norton ** Andrew R. Baker ** Andrew J. Mullican ** Steven Sturges ** NOTES ** 5.15.02 - Initial Source Code. Norton/Roelker ** 2002-12-06 - Modify event selection logic to fix broken custom rule types ** arbitrary rule type ordering (ARB) ** 2005-02-08 - Track alerts per session so that they aren't double reported ** for rebuilt packets. AJM. ** 2005-02-17 - Track alerts per IP frag tracker so that they aren't double ** reported for rebuilt frags. SAS (code similar to AJM's for ** per session tracking). ** ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** */ # ifdef HAVE_CONFIG_H # include "config.h" # endif #include "snort.h" #include "detect.h" #include "snort_debug.h" #include "util.h" #include "tag.h" #include "rules.h" #include "treenodes.h" #include "pcrm.h" #include "fpcreate.h" #include "fpdetect.h" #include "mpse.h" #include "bitop.h" #include "perf-event.h" #include "sfthreshold.h" #include "rate_filter.h" #include "event_queue.h" #include "event_wrapper.h" #include "active.h" #include "encode.h" #include "sfPolicy.h" #include "sfPolicyData.h" #include "sp_pattern_match.h" #include "spp_frag3.h" #include "stream_api.h" # ifdef TARGET_BASED # include "target-based/sftarget_protocol_reference.h" # include "target-based/sftarget_reader.h" # endif #include "ppm.h" #include "generators.h" #include "detection_util.h" /* ** This define enables set-wise signature detection for ** IP and ICMP packets. During early testing, the old ** method of detection seemed faster for ICMP and IP ** signatures, but with modifications to the set-wise engine ** performance became much better. This define could be ** taken out, but is still in for regression testing. */ /* ** GLOBALS ** These variables are local to this file and deal with ** configuration issues that are set in snort.conf through ** variables. */ /* ** Assorted global variables from the old detection engine ** for backwards compatibility. */ extern OptTreeNode *otn_tmp; extern SFEVENT sfEvent; /* ** Static function prototypes */ int fpEvalRTN(RuleTreeNode *rtn, Packet *p, int check_ports); static inline int fpEvalHeaderIp(Packet *p, int ip_proto, OTNX_MATCH_DATA *); static inline int fpEvalHeaderIcmp(Packet *p, OTNX_MATCH_DATA *); static inline int fpEvalHeaderTcp(Packet *p, OTNX_MATCH_DATA *); static inline int fpEvalHeaderUdp(Packet *p, OTNX_MATCH_DATA *); static inline int fpEvalHeaderSW(PORT_GROUP *port_group, Packet *p, int check_ports, char ip_rule, OTNX_MATCH_DATA *); static int rule_tree_match (void* id, void * tree, int index, void * data, void *neg_list ); static inline int fpAddSessionAlert(Packet *p, OptTreeNode *otn); static inline int fpSessionAlerted(Packet *p, OptTreeNode *otn); //static inline int fpLogEvent(RuleTreeNode *rtn, OptTreeNode *otn, Packet *p); #ifdef PERF_PROFILING PreprocStats rulePerfStats; PreprocStats ncrulePerfStats; PreprocStats ruleRTNEvalPerfStats; PreprocStats ruleOTNEvalPerfStats; #endif /* initialize the global OTNX_MATCH_DATA variable */ OTNX_MATCH_DATA * OtnXMatchDataNew(int num_rule_types) { OTNX_MATCH_DATA *omd = (OTNX_MATCH_DATA *)SnortAlloc(sizeof(OTNX_MATCH_DATA)); omd->iMatchInfoArraySize = num_rule_types; omd->matchInfo = (MATCH_INFO *)SnortAlloc(num_rule_types * sizeof(MATCH_INFO)); return omd; } /* ** ** NAME ** InitMatchInfo:: ** ** DESCRIPTION ** Initialize the OTNX_MATCH_DATA structure. We do this for ** every packet so calloc is not used as this would zero the ** whole space and this only sets the necessary counters to ** zero, and saves us time. ** ** FORMAL INPUTS ** OTNX_MATCH_DATA * - pointer to structure to init. ** ** FORMAL OUTPUT ** None ** */ static inline void InitMatchInfo(OTNX_MATCH_DATA *o) { int i = 0; for(i = 0; i < o->iMatchInfoArraySize; i++) { o->matchInfo[i].iMatchCount = 0; o->matchInfo[i].iMatchIndex = 0; o->matchInfo[i].iMatchMaxLen = 0; } } void OtnxMatchDataFree(OTNX_MATCH_DATA *omd) { if (omd == NULL) return; if (omd->matchInfo != NULL) free(omd->matchInfo); free(omd); } // called by fpLogEvent(), which does the filtering etc. // this handles the non-rule-actions (responses). static inline void fpLogOther (Packet* p, OptTreeNode* otn, int action) { TriggerResponses(p, otn); if ( !EventTrace_IsEnabled() ) return; EventTrace_Log(p, otn, action); } /* ** ** NAME ** fpLogEvent:: ** ** DESCRIPTION ** This function takes the corresponding RTN and OTN for a snort rule ** and logs the event and packet that was alerted upon. This ** function was pulled out of fpEvalSomething, so now we can log an ** event no matter where we are. ** ** FORMAL INPUTS ** RuleTreeNode * - rtn for snort rule ** OptTreeNode * - otn for snort rule ** Packet * - packet that elicited event. */ int fpLogEvent(RuleTreeNode *rtn, OptTreeNode *otn, Packet *p) { int action = -1, rateAction = -1, filterEvent = 0; if (!rtn || !otn) { return 1; } DEBUG_WRAP(DebugMessage(DEBUG_DETECT, " => Got rule match, rtn type = %d, evalIndex = %d, passIndex = %d\n", rtn->type,ScGetEvalIndex(rtn->type), ScGetEvalIndex(RULE_TYPE__PASS));); if (RULE_TYPE__PASS == rtn->type) { p->packet_flags |= PKT_PASS_RULE; } if (otn->stateless) { /* Stateless rule, set the stateless bit */ p->packet_flags |= PKT_STATELESS; } else { /* Not stateless, clear the stateless bit if it was set * from a previous rule. */ p->packet_flags &= ~PKT_STATELESS; } if ((p->packet_flags & PKT_STREAM_UNEST_UNI) && ScAssureEstablished() && (!(p->packet_flags & PKT_REBUILT_STREAM)) && (otn->stateless == 0)) { // We still want to drop packets that are drop rules. // We just don't want to see the alert. if ((rtn->type == RULE_TYPE__DROP) || (rtn->type == RULE_TYPE__SDROP) || (rtn->type == RULE_TYPE__REJECT)) { Active_DropSession(p); if (pkt_trace_enabled) { addPktTraceData(VERDICT_REASON_SNORT, snprintf(trace_line, MAX_TRACE_LINE, "Snort fpdetect: gid %u, sid %u, %s\n", otn->sigInfo.generator, otn->sigInfo.id, getPktTraceActMsg())); } else addPktTraceData(VERDICT_REASON_SNORT, 0); } fpLogOther(p, otn, rtn->type); return 1; } // perform rate filtering tests - impacts action taken rateAction = RateFilter_Test(otn, p); if (rateAction < 0) { // internal events are no-ops if (EventIsInternal(otn->sigInfo.generator)) return 1; else action = (int) rtn->type; } else { if (rateAction >= RULE_TYPE__MAX) action = rateAction - RULE_TYPE__MAX; else action = rateAction; } // When rate filters kick in, event filters are still processed. // perform event filtering tests - impacts logging if ( IPH_IS_VALID(p) ) { filterEvent = sfthreshold_test( otn->event_data.sig_generator, otn->event_data.sig_id, GET_SRC_IP(p), GET_DST_IP(p), p->pkth->ts.tv_sec); } else { sfaddr_t cleared; IP_CLEAR(cleared); filterEvent = sfthreshold_test( otn->event_data.sig_generator, otn->event_data.sig_id, IP_ARG(cleared), IP_ARG(cleared), p->pkth->ts.tv_sec); } if ( (filterEvent < 0) || (filterEvent > 0 && (rateAction < RULE_TYPE__MAX)) ) { /* ** If InlineMode is on, then we still want to drop packets ** that are drop rules. We just don't want to see the alert. */ if ( (action == RULE_TYPE__DROP) || (action == RULE_TYPE__SDROP) || (action == RULE_TYPE__REJECT) ) { Active_DropSession(p); if (pkt_trace_enabled) { addPktTraceData(VERDICT_REASON_SNORT, snprintf(trace_line, MAX_TRACE_LINE, "Snort fpdetect_filter: gid %u, sid %u, %s\n", otn->sigInfo.generator, otn->sigInfo.id, getPktTraceActMsg())); } else addPktTraceData(VERDICT_REASON_SNORT, 0); } pc.event_limit++; fpLogOther(p, otn, action); return 1; } /* If this packet has been passed based on detection rules, * check the decoder/preprocessor events (they have been added to Event queue already). * If its order is lower than 'pass', it should have been passed. * This is consistent with other detection rules */ if ( (p->packet_flags & PKT_PASS_RULE) &&(ScGetEvalIndex(rtn->type) > ScGetEvalIndex(RULE_TYPE__PASS))) { fpLogOther(p, otn, rtn->type); return 1; } // Set the ref_time to 0 so we make the logging work right. otn->event_data.ref_time.tv_sec = 0; /* Set otn_tmp because log.c uses it to log details ** of the event. Maybe we should look into making this ** part of the log routines and not a global variable. ** This way we could support multiple events per packet. */ otn_tmp = otn; OTN_PROFILE_ALERT(otn); event_id++; switch (action) { case RULE_TYPE__PASS: PassAction(); SetTags(p, otn, rtn, event_id); break; case RULE_TYPE__ALERT: AlertAction(p, otn, rtn, &otn->event_data); SetTags(p, otn, rtn, event_id); break; case RULE_TYPE__LOG: LogAction(p, otn, rtn, &otn->event_data); SetTags(p, otn, rtn, event_id); break; case RULE_TYPE__DROP: DropAction(p, otn, rtn, &otn->event_data); SetTags(p, otn, rtn, event_id); break; case RULE_TYPE__SDROP: SDropAction(p, otn, &otn->event_data); break; case RULE_TYPE__REJECT: DropAction(p, otn, rtn, &otn->event_data); #ifdef ACTIVE_RESPONSE Active_QueueReject(); #endif SetTags(p, otn, rtn, event_id); break; default: break; } otn_tmp = NULL; fpLogOther(p, otn, action); return 0; } /* ** ** NAME ** fpAddMatch:: ** ** DESCRIPTION ** Add and Event to the appropriate Match Queue: Alert, Pass, or Log. ** This allows us to find multiple events per packet and pick the 'best' ** one. This function also allows us to change the order of alert, ** pass, and log signatures by cacheing them for decision later. ** ** IMPORTANT NOTE: ** fpAddMatch must be called even when the queue has been maxed ** out. This is because there are three different queues (alert, ** pass, log) and unless all three are filled (or at least the ** queue that is in the highest priority), events must be looked ** at to see if they are members of a queue that is not maxed out. ** ** FORMAL INPUTS ** OTNX_MATCH_DATA * - the omd to add the event to. ** int pLen - length of pattern that matched, 0 for no content ** OptTreeNode * - the otn to add. ** ** FORMAL OUTPUTS ** int - 1 max_events variable hit, 0 successful. ** */ int fpAddMatch(OTNX_MATCH_DATA *omd_local, int pLen, OptTreeNode *otn) { MATCH_INFO * pmi; int evalIndex; int i; RuleTreeNode *rtn = getRuntimeRtnFromOtn(otn); evalIndex = rtn->listhead->ruleListNode->evalIndex; /* bounds check index */ if( evalIndex >= omd_local->iMatchInfoArraySize ) { pc.match_limit++; return 1; } pmi = &omd_local->matchInfo[evalIndex]; /* ** If we hit the max number of unique events for any rule type alert, ** log or pass, then we don't add it to the list. */ if( pmi->iMatchCount >= (int)snort_conf->fast_pattern_config->max_queue_events || pmi->iMatchCount >= MAX_EVENT_MATCH) { pc.match_limit++; return 1; } /* Check that we are not storing the same otn again */ for( i=0; i< pmi->iMatchCount;i++ ) { if( pmi->MatchArray[ i ] == otn ) { //LogMessage("fpAddMatch: storing the same otn...\n"); return 0; } } /* ** Add the event to the appropriate list */ pmi->MatchArray[ pmi->iMatchCount ] = otn; /* ** This means that we are adding a NC rule ** and we only set the index to this rule ** if there is no content rules in the ** same array. */ if(pLen > 0) { /* ** Event Comparison Function ** Here the largest content match is the ** priority */ if( pmi->iMatchMaxLen < pLen ) { pmi->iMatchMaxLen = pLen; pmi->iMatchIndex = pmi->iMatchCount; } } pmi->iMatchCount++; return 0; } /* ** ** NAME ** fpEvalRTN:: ** ** DESCRIPTION ** Evaluates an RTN against a packet. We can probably get rid of ** the check_ports variable, but it's in there for good luck. :) ** ** FORMAL INPUTS ** RuleTreeNode * - RTN to check packet against. ** Packet * - Packet to evaluate ** int - whether to do a quick enhancement against ports. ** ** FORMAL OUTPUT ** int - 1 if match, 0 if match failed. ** */ int fpEvalRTN(RuleTreeNode *rtn, Packet *p, int check_ports) { PROFILE_VARS; PREPROC_PROFILE_START(ruleRTNEvalPerfStats); if(rtn == NULL) { PREPROC_PROFILE_END(ruleRTNEvalPerfStats); return 0; } /* TODO: maybe add a port test here ... */ DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "[*] Rule Head %d\n", rtn->head_node_number);) if(!rtn->rule_func->RuleHeadFunc(p, rtn, rtn->rule_func, check_ports)) { DEBUG_WRAP(DebugMessage(DEBUG_DETECT, " => Header check failed, checking next node\n");); DEBUG_WRAP(DebugMessage(DEBUG_DETECT, " => returned from next node check\n");); PREPROC_PROFILE_END(ruleRTNEvalPerfStats); return 0; } DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");); DEBUG_WRAP(DebugMessage(DEBUG_DETECT, " => RTN %d Matched!\n", rtn->head_node_number);); DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n");); /* ** Return that there is a rule match and log the event outside ** of this routine. */ PREPROC_PROFILE_END(ruleRTNEvalPerfStats); return 1; } static int detection_option_tree_evaluate(detection_option_tree_root_t *root, detection_option_eval_data_t *eval_data) { int i, rval = 0; PROFILE_VARS; if (!root) return 0; PREPROC_PROFILE_START(ruleOTNEvalPerfStats); /* Not really OTN, but close */ #ifdef PPM_MGR /* Start Rule Timer */ if( PPM_RULES_ENABLED() ) { PPM_GET_TIME(); PPM_INIT_RULE_TIMER(); if (root->tree_state == RULE_STATE_DISABLED) { PPM_REENABLE_TREE(root, eval_data->p); if (root->tree_state == RULE_STATE_DISABLED) { PPM_END_RULE_TIMER(); return 0; } } } #endif for ( i = 0; i< root->num_children; i++) { /* New tree, reset doe_ptr for safety */ UpdateDoePtr(NULL, 0); /* Increment number of events generated from that child */ rval += detection_option_node_evaluate(root->children[i], eval_data); } #ifdef PPM_MGR if( PPM_ENABLED() ) { PPM_GET_TIME(); /* Rule test */ if( PPM_RULES_ENABLED() ) { if( PPM_PKTS_ENABLED() ) PPM_INC_PKT_RULE_TESTS(); PPM_RULE_TEST(root, eval_data->p); PPM_ACCUM_RULE_TIME(); PPM_END_RULE_TIMER(); } } #endif PREPROC_PROFILE_END(ruleOTNEvalPerfStats); return rval; } static int rule_tree_match( void * id, void *tree, int index, void * data, void * neg_list) { OTNX_MATCH_DATA *pomd = (OTNX_MATCH_DATA *)data; PMX *pmx = (PMX*)id; PatternMatchData *pmd = (PatternMatchData*)pmx->PatternMatchData; detection_option_tree_root_t *root = (detection_option_tree_root_t *)tree; detection_option_eval_data_t eval_data; NCListNode *ncl; int rval=0; PROFILE_VARS; eval_data.pomd = pomd; eval_data.p = pomd->p; eval_data.pmd = pmd; eval_data.flowbit_failed = 0; eval_data.flowbit_noalert = 0; eval_data.detection_filter_count = 0; PREPROC_PROFILE_START(rulePerfStats); /* NOTE: The otn will be the first one in the match state. If there are * multiple rules associated with a match state, mucking with the otn * may muck with an unintended rule */ /* Set flag for not contents so they aren't evaluated */ for (ncl = (NCListNode *)neg_list; ncl != NULL; ncl = ncl->next) { PMX *neg_pmx = (PMX *)ncl->pmx; PatternMatchData *neg_pmd = (PatternMatchData *)neg_pmx->PatternMatchData; neg_pmd->last_check.ts.tv_sec = eval_data.p->pkth->ts.tv_sec; neg_pmd->last_check.ts.tv_usec = eval_data.p->pkth->ts.tv_usec; neg_pmd->last_check.packet_number = (rule_eval_pkt_count + (GetRebuiltPktCount())); neg_pmd->last_check.rebuild_flag = (eval_data.p->packet_flags & PKT_REBUILT_STREAM); } rval = detection_option_tree_evaluate(root, &eval_data); if (rval) { /* ** We have a qualified event from this tree */ pomd->pg->pgQEvents++; UpdateQEvents(&sfEvent); } else { /* ** This means that the event is non-qualified. */ pomd->pg->pgNQEvents++; UpdateNQEvents(&sfEvent); } PREPROC_PROFILE_END(rulePerfStats); if (eval_data.flowbit_failed) { return -1; } #ifdef GRE /* If this is for an IP rule set, evalute the rules from * the inner IP offset as well */ if (eval_data.p->packet_flags & PKT_IP_RULE) { if (eval_data.p->outer_ip_data) { const uint8_t *tmp_data = eval_data.p->data; uint16_t tmp_dsize = eval_data.p->dsize; const IPHdr *tmp_iph = eval_data.p->iph; IP4Hdr *tmp_ip4h = eval_data.p->ip4h; IP6Hdr *tmp_ip6h = eval_data.p->ip6h; eval_data.p->iph = eval_data.p->inner_iph; eval_data.p->ip4h = &eval_data.p->inner_ip4h; eval_data.p->ip6h = &eval_data.p->inner_ip6h; eval_data.p->data = eval_data.p->ip_data; eval_data.p->dsize = eval_data.p->ip_dsize; /* clear so we dont keep recursing */ eval_data.p->packet_flags &= ~PKT_IP_RULE; eval_data.p->packet_flags |= PKT_IP_RULE_2ND; /* Recurse, and evaluate with the inner IP */ rval = rule_tree_match(id, tree, index, data, NULL); eval_data.p->packet_flags &= ~PKT_IP_RULE_2ND; eval_data.p->packet_flags |= PKT_IP_RULE; /* restore original data & dsize */ eval_data.p->iph = tmp_iph; eval_data.p->ip4h = tmp_ip4h; eval_data.p->ip6h = tmp_ip6h; eval_data.p->data = tmp_data; eval_data.p->dsize = tmp_dsize; } } #endif return 0; } static int sortOrderByPriority(const void *e1, const void *e2) { OptTreeNode *otn1; OptTreeNode *otn2; if (!e1 || !e2) return 0; otn1 = *(OptTreeNode **)e1; otn2 = *(OptTreeNode **)e2; if( otn1->sigInfo.priority < otn2->sigInfo.priority ) return -1; if( otn1->sigInfo.priority > otn2->sigInfo.priority ) return +1; /* This improves stability of repeated tests */ if( otn1->sigInfo.id < otn2->sigInfo.id ) return -1; if( otn1->sigInfo.id > otn2->sigInfo.id ) return +1; return 0; } static int sortOrderByContentLength(const void *e1, const void *e2) { OptTreeNode *otn1; OptTreeNode *otn2; if (!e1 || !e2) return 0; otn1 = *(OptTreeNode **)e1; otn2 = *(OptTreeNode **)e2; if (otn1->longestPatternLen < otn2->longestPatternLen) return +1; if (otn1->longestPatternLen > otn2->longestPatternLen) return -1; /* This improves stability of repeated tests */ if( otn1->sigInfo.id < otn2->sigInfo.id ) return +1; if( otn1->sigInfo.id > otn2->sigInfo.id ) return -1; return 0; } /* ** ** NAME ** fpFinalSelectEvent:: ** ** DESCRIPTION ** fpFinalSelectEvent is called at the end of packet processing ** to decide, if there hasn't already been a selection, to decide ** what event to select. This function is different from ** fpSelectEvent by the fact that fpSelectEvent only selects an ** event if it is the first priority setting (drop/pass/alert...). ** ** We also loop through the events we log, so that we don't log the ** same event twice. This can happen with unique conflicts some ** of the time. ** ** IMPORTANT NOTE: ** We call fpFinalSelectEvent() after all processing of the packet ** has been completed. The reason this must be called afterwards is ** because of unique rule group conflicts for a packet. If there is ** a unique conflict, then we inspect both rule groups and do the final ** event select after both rule groups have been inspected. The ** problem came up with bi-directional rules with pass rule ordering ** as the first type of rule. Before we would detect a alert rule in ** the first rule group, and since there was no pass rules we would ** log that alert rule. However, if we had inspected the second rule ** group, we would have found a pass rule and that should have taken ** precedence. We now inspect both rule groups before doing a final ** event select. ** ** NOTES ** Jan 2006 : marc norton ** Previously it was possible to not log all desired events, if for ** instance the rule order was alert->drop in inline mode we would ** alert but no drop. The default ordering of 'drop alert pass log ...' ** normally handles this, however, it could happen. Also, in the ** default ordering alerts on the same packet a drop was applied to ** did not get logged. To be more flexible and handle all manners of ** subjective rule ordering and logging desired by the whole farm we've ** changed things a bit. ** ** Now, each actions event list is processed in order, based on the rule ** order. We process all events up to the log limit specified via the ** 'config event_queue: ...' as you might expect. Pass rules are ** handled a bit differently. As soon as a pass rule based event is ** processed in the event queue, we stop processing any further events ** on the packet if the pass event is the 1st ordering that sees an ** event. Otherwise if the ordering has it that pass rule events are ** processed after a drop or alert you will see the drops and alerts, ** and the pass event just causes us to stop processing any more events ** on the packet, but the packet does not pass. Also, the --alert-on-drop ** flag causes any drop/sdrop/reject rules to be loaded as alert rules. ** The default has been to ignore them on parsing. ** ** If this is less than clear, herese the $.02 version: ** default order -> pass drop alert log ( --alert-before-pass reverts ** to -> drop alert pass log ) the 1st action-type of events in the rule ** ordering to be seen gets logged by default the --flush-all-events ** flag will cause secondary and tertiary action-events to be logged. ** the -o flag is useless, but accepted, for now. ** the max_events and log fields are reduced to only needing the log ** events field. max_fields is harmless. ** ( drop rules may be honored as alerts in IDS mode (no -Q) by using ** the --alert-on-drop flag ) ** ** FORMAL INPUTS ** OTNX_MATCH_DATA * - omd to select event from. ** Packet * - pointer to packet to log. ** ** FORMAL OUTPUT ** int - return 0 if no match, 1 if match. ** */ static inline int fpFinalSelectEvent(OTNX_MATCH_DATA *o, Packet *p) { int i; int j; int k; OptTreeNode *otn; int tcnt = 0; EventQueueConfig *eq = snort_conf->event_queue_config; RuleTreeNode *rtn; for( i = 0; i < o->iMatchInfoArraySize; i++ ) { /* bail if were not dumping events in all the action groups, * and we've alresady got some events */ if (!ScProcessAllEvents() && (tcnt > 0)) return 1; if(o->matchInfo[i].iMatchCount) { /* * We must always sort so if we que 8 and log 3 and they are * all from the same action group we want them sorted so we get * the highest 3 in priority, priority and lenght sort do NOT * take precedence over 'alert drop pass ...' ordering. If * order is 'drop alert', and we log 3 for drop alertsdo not * get logged. IF order is 'alert drop', and we log 3 for * alert, than no drops are logged. So, there should be a * built in drop/sdrop/reject comes before alert/pass/log as * part of the natural ordering....Jan '06.. */ /* Sort the rules in this action group */ if (eq->order == SNORT_EVENTQ_PRIORITY) { qsort(o->matchInfo[i].MatchArray, o->matchInfo[i].iMatchCount, sizeof(void *), sortOrderByPriority); } else if (eq->order == SNORT_EVENTQ_CONTENT_LEN) { qsort(o->matchInfo[i].MatchArray, o->matchInfo[i].iMatchCount, sizeof(void*), sortOrderByContentLength); } else { FatalError("fpdetect: Order function for event queue is invalid.\n"); } /* Process each event in the action (alert,drop,log,...) groups */ for(j=0; j < o->matchInfo[i].iMatchCount; j++) { otn = o->matchInfo[i].MatchArray[j]; rtn = getRtnFromOtn(otn, getIpsRuntimePolicy()); if ((otn != NULL) && (rtn != NULL) && (rtn->type == RULE_TYPE__PASS)) { /* Already acted on rules, so just don't act on anymore */ if( tcnt > 0 ) return 1; } /* ** Loop here so we don't log the same event ** multiple times. */ for(k = 0; k < j; k++) { if(o->matchInfo[i].MatchArray[k] == otn) { otn = NULL; break; } } if( otn && !fpSessionAlerted(p, otn) && !fpFragAlerted(p, otn)) { /* ** QueueEvent */ int err = SnortEventqAdd( otn->sigInfo.generator, otn->sigInfo.id, otn->sigInfo.rev, otn->sigInfo.class_id, otn->sigInfo.priority, otn->sigInfo.message, (void *)otn); if ( err ) pc.queue_limit++; tcnt++; } else pc.alert_limit++; /* Only count it if we're going to log it */ if (tcnt <= eq->log_events) { if ( p->ssnptr ) fpAddSessionAlert(p, otn); if ( p->fragtracker ) fpAddFragAlert(p, otn); } if (tcnt >= eq->max_events) { pc.queue_limit++; return 1; } /* only log/count one pass */ if ((otn != NULL) && (rtn != NULL) && (rtn->type == RULE_TYPE__PASS)) { p->packet_flags |= PKT_PASS_RULE; return 1; } } } } return 0; } /* ** ** NAME ** fpAddSessionAlert:: ** ** DESCRIPTION ** This function flags an alert per session. ** ** FORMAL INPUTS ** Packet * - the packet to inspect ** OptTreeNode * - the rule that generated the alert ** ** FORMAL OUTPUTS ** int - 0 if not flagged ** 1 if flagged ** */ static inline int fpAddSessionAlert(Packet *p, OptTreeNode *otn) { if ( !p->ssnptr ) return 0; if ( !otn ) return 0; /* Only track a certain number of alerts per session */ if (stream_api) return !stream_api->add_session_alert( p->ssnptr, p, otn->sigInfo.generator, otn->sigInfo.id); return 0; } /* ** ** NAME ** fpSessionAlerted:: ** ** DESCRIPTION ** This function indicates whether or not an alert has been generated previously ** in this session, but only if this is a rebuilt packet. ** ** FORMAL INPUTS ** Packet * - the packet to inspect ** OptTreeNode * - the rule that generated the alert ** ** FORMAL OUTPUTS ** int - 0 if alert NOT previously generated ** 1 if alert previously generated ** */ static inline int fpSessionAlerted(Packet *p, OptTreeNode *otn) { SigInfo *si = &otn->sigInfo; if ( !stream_api ) return 0; if (!stream_api->check_session_alerted(p->ssnptr, p, si->generator, si->id)) return 0; else return 1; } #if 0 Not currently used /* * Prints an OTN in a simple format with: * * rule proto: # gid: # sid: # sp: # dp # \n */ void printRuleFmt1( SnortConfig *sc, OptTreeNode * otn ) { RuleTreeNode *rtn = getParserRtnFromOtn(otn); LogMessage("rule proto: "); if( rtn->proto== IPPROTO_TCP )LogMessage("tcp "); else if( rtn->proto== IPPROTO_UDP )LogMessage("udp "); else if( rtn->proto== IPPROTO_ICMP )LogMessage("icmp "); else if( rtn->proto== ETHERNET_TYPE_IP)LogMessage("ip "); LogMessage("gid:%u sid:%5u ", otn->sigInfo.generator,otn->sigInfo.id); LogMessage(" sp:"); fflush(stdout);fflush(stderr); PortObjectPrintPortsRaw(rtn->src_portobject); fflush(stdout);fflush(stderr); LogMessage(" dp:"); PortObjectPrintPortsRaw(rtn->dst_portobject); printf("\n"); fflush(stdout);fflush(stderr); } #endif /* ** ** NAME ** fpEvalHeaderSW:: ** ** DESCRIPTION ** This function does a set-wise match on content, and walks an otn list ** for non-content. The otn list search will eventually be redone for ** for performance purposes. ** ** FORMAL INPUTS ** PORT_GROUP * - the port group to inspect ** Packet * - the packet to inspect ** int - whether src/dst ports should be checked (udp/tcp or icmp) ** char - whether the rule is an IP rule (change the packet payload pointer) ** ** FORMAL OUTPUTS ** int - 0 for failed pattern match ** 1 for sucessful pattern match ** */ static inline int fpEvalHeaderSW(PORT_GROUP *port_group, Packet *p, int check_ports, char ip_rule, OTNX_MATCH_DATA *omd) { void * so; int start_state; const uint8_t *tmp_payload = NULL; uint16_t tmp_dsize = 0; IPHdr *tmp_iph = NULL; IP6Hdr *tmp_ip6h = NULL; IP4Hdr *tmp_ip4h = NULL; IPH_API *tmp_api = NULL; char repeat = 0; FastPatternConfig *fp = snort_conf->fast_pattern_config; PROFILE_VARS; if (ip_rule) { tmp_iph = (void *)p->iph; tmp_ip6h = (void *)p->ip6h; tmp_ip4h = (void *)p->ip4h; tmp_payload = p->data; tmp_dsize = p->dsize; tmp_api = p->iph_api; /* Set the packet payload pointers to that of IP, ** since this is an IP rule. */ #ifdef GRE if (p->outer_ip_data) { p->iph = p->outer_iph; p->ip6h = &p->outer_ip6h; p->ip4h = &p->outer_ip4h; p->data = p->outer_ip_data; p->dsize = p->outer_ip_dsize; p->iph_api = p->outer_iph_api; p->packet_flags |= PKT_IP_RULE; repeat = 2; } else #endif /* GRE */ { if (p->ip_data) { p->data = p->ip_data; p->dsize = p->ip_dsize; p->packet_flags |= PKT_IP_RULE; } } } else { p->packet_flags &= ~PKT_IP_RULE; } /* ** Init the info for rule ordering selection */ //InitMatchInfo(omd); if (do_detect_content) { /* ** PKT_STREAM_INSERT packets are being rebuilt and re-injected ** through this detection engine. So in order to avoid pattern ** matching bytes twice, we wait until the PKT_STREAM_INSERT ** packets are rebuilt and injected through the detection engine. ** ** PROBLEM: ** If a stream gets stomped on before it gets re-injected, an attack ** would be missed. So before a connection gets stomped, we ** re-inject the stream we have. */ /* ** First evaluate the detection functions. Namely those things ** that are between a preprocessor and rules. */ { tSfPolicyId policy_id = getIpsRuntimePolicy(); SnortPolicy *policy = snort_conf->targeted_policies[policy_id]; /* safe to assume policy is non NULL here because of check in * Preprocess() */ DetectionEvalFuncNode *idx = policy->detect_eval_funcs; for (; (idx != NULL) && !(p->packet_flags & PKT_PASS_RULE); idx = idx->next) { if ( p->proto_bits & idx->proto_mask ) //IsDetectBitSet(p, idx->preproc_bit)) { idx->func(p, idx->context); } } } if ( fp->inspect_stream_insert || !(p->packet_flags & PKT_STREAM_INSERT) ) { const HttpBuffer* hb; omd->pg = port_group; omd->p = p; omd->check_ports = check_ports; if ( GetHttpBufferMask() ) { if ( (hb = GetHttpBuffer(HTTP_BUFFER_URI)) ) { so = (void *)port_group->pgPms[PM_TYPE__HTTP_URI_CONTENT]; if ( so && mpseGetPatternCount(so) > 0 ) { start_state = 0; mpseSearch(so, hb->buf, hb->length, rule_tree_match, omd, &start_state); #ifdef PPM_MGR /* Bail if we spent too much time already */ if (PPM_PACKET_ABORT_FLAG()) goto fp_eval_header_sw_reset_ip; #endif } } if ( (hb = GetHttpBuffer(HTTP_BUFFER_HEADER)) ) { so = (void *)port_group->pgPms[PM_TYPE__HTTP_HEADER_CONTENT]; if ( so && mpseGetPatternCount(so) > 0 ) { start_state = 0; mpseSearch(so, hb->buf, hb->length, rule_tree_match, omd, &start_state); #ifdef PPM_MGR /* Bail if we spent too much time already */ if (PPM_PACKET_ABORT_FLAG()) goto fp_eval_header_sw_reset_ip; #endif } } if ( (hb = GetHttpBuffer(HTTP_BUFFER_CLIENT_BODY)) ) { so = (void *)port_group->pgPms[PM_TYPE__HTTP_CLIENT_BODY_CONTENT]; if ( so && mpseGetPatternCount(so) > 0 ) { start_state = 0; mpseSearch(so, hb->buf, hb->length, rule_tree_match, omd, &start_state); #ifdef PPM_MGR /* Bail if we spent too much time already */ if (PPM_PACKET_ABORT_FLAG()) goto fp_eval_header_sw_reset_ip; #endif } } } /* ** Decode Content Match ** We check to see if the packet has been normalized into ** the global (decode.c) DecodeBuffer. Currently, only ** telnet normalization writes to this buffer. So, if ** it is set, we do this the match against the normalized ** buffer and we do the check against the original ** payload, in case any of the rules have the ** 'rawbytes' option. */ so = (void *)port_group->pgPms[PM_TYPE__CONTENT]; if ((so != NULL) && (mpseGetPatternCount(so) > 0)) { if (Is_DetectFlag(FLAG_ALT_DECODE) && DecodeBuffer.len) { start_state = 0; mpseSearch(so, DecodeBuffer.data, DecodeBuffer.len, rule_tree_match, omd, &start_state); #ifdef PPM_MGR /* Bail if we spent too much time already */ if (PPM_PACKET_ABORT_FLAG()) goto fp_eval_header_sw_reset_ip; #endif } /* Adding this extra search on file data since we no more use DecodeBuffer to decode now*/ if(file_data_ptr.len) { start_state = 0; mpseSearch(so, file_data_ptr.data, file_data_ptr.len, rule_tree_match, omd, &start_state); #ifdef PPM_MGR /* Bail if we spent too much time already */ if (PPM_PACKET_ABORT_FLAG()) goto fp_eval_header_sw_reset_ip; #endif } /* ** Content-Match - If no Uri-Content matches, than do a Content search ** ** NOTE: ** We may want to bail after the Content search if there ** has been a successful match. */ if (p->data && p->dsize) { uint16_t pattern_match_size = p->dsize; if ( IsLimitedDetect(p) && (p->alt_dsize < p->dsize) ) pattern_match_size = p->alt_dsize; start_state = 0; mpseSearch(so, p->data, pattern_match_size, rule_tree_match, omd, &start_state); #ifdef PPM_MGR /* Bail if we spent too much time already */ if (PPM_PACKET_ABORT_FLAG()) goto fp_eval_header_sw_reset_ip; #endif } } } } /* ** PKT_REBUILT_STREAM packets are re-injected streams. This means ** that the "packet headers" are completely bogus and only the ** content matches are important. So for PKT_REBUILT_STREAMs, we ** don't inspect against no-content OTNs since these deal with ** packet headers, packet sizes, etc. ** ** NOTE: ** This has been changed when evaluating no-content rules because ** it was interfering with the pass->alert ordering. We still ** need to check no-contents against rebuilt packets, because of ** this problem. Immediate solution is to have the detection plugins ** bail if the rule should only be inspected against packets, a.k.a ** dsize checks. ** ** NOTE 2: ** PKT_REBUILT_STREAM packets are now cooked (encoded by Snort) ** and have the same encapsulations as the raw packets. The ** headers are "good enough" for detection (valid TCP sequence ** numbers, but zero checksums) but packet sizes are different. ** Given that TCP segmentation is arbitrary to start with, the ** use of dsize in a rule is questionable for raw or rebuilt. */ /* ** Walk and test the non-content OTNs */ if (fpDetectGetDebugPrintNcRules(fp)) LogMessage("NC-testing %u rules\n", port_group->pgNoContentCount); #ifdef PPM_MGR if( PPM_ENABLED() ) PPM_GET_TIME(); #endif do { if (port_group->pgHeadNC) { detection_option_eval_data_t eval_data; int rval; eval_data.pomd = omd; eval_data.p = p; eval_data.pmd = NULL; eval_data.flowbit_failed = 0; eval_data.flowbit_noalert = 0; eval_data.detection_filter_count = 0; PREPROC_PROFILE_START(ncrulePerfStats); rval = detection_option_tree_evaluate(port_group->pgNonContentTree, &eval_data); PREPROC_PROFILE_END(ncrulePerfStats); if (rval) { /* We have a qualified event from this tree */ port_group->pgQEvents++; UpdateQEvents(&sfEvent); } else { /* This means that the event is non-qualified. */ port_group->pgNQEvents++; UpdateNQEvents(&sfEvent); } } #ifdef GRE if (ip_rule && p->outer_ip_data) { /* Evaluate again with the inner IPs */ p->iph = p->inner_iph; p->ip6h = &p->inner_ip6h; p->ip4h = &p->inner_ip4h; p->data = p->ip_data; p->dsize = p->ip_dsize; p->iph_api = tmp_api; p->packet_flags |= PKT_IP_RULE_2ND | PKT_IP_RULE; repeat--; } #else repeat = 0; #endif /* GRE */ } while(repeat != 0); #ifdef PPM_MGR /* Tag only used with PPM right now */ fp_eval_header_sw_reset_ip: #endif if (ip_rule) { /* Set the data & dsize back to original values. */ p->iph = tmp_iph; p->ip6h = tmp_ip6h; p->ip4h = tmp_ip4h; p->data = tmp_payload; p->dsize = tmp_dsize; p->iph_api = tmp_api; p->packet_flags &= ~(PKT_IP_RULE| PKT_IP_RULE_2ND); } return 0; } /* ** fpEvalHeaderUdp:: */ static inline int fpEvalHeaderUdp(Packet *p, OTNX_MATCH_DATA *omd) { PORT_GROUP *src = NULL, *dst = NULL, *gen = NULL; #ifdef TARGET_BASED PORT_GROUP *nssrc = NULL, *nsdst = NULL; if (IsAdaptiveConfigured()) { /* Check for a service/protocol ordinal for this packet */ int16_t proto_ordinal = GetProtocolReference(p); if (proto_ordinal > 0 && proto_ordinal != SFTARGET_UNKNOWN_PROTOCOL) { prmFindGenericRuleGroup(snort_conf->prmUdpRTNX, &gen); /* TODO: To From Server ?, else we apply */ dst = fpGetServicePortGroupByOrdinal(snort_conf->sopgTable, IPPROTO_UDP, TO_SERVER, proto_ordinal); src = fpGetServicePortGroupByOrdinal(snort_conf->sopgTable, IPPROTO_UDP, TO_CLIENT, proto_ordinal); } // Find non-service based rule groups and the generic rule groups prmFindNoServiceRuleGroup(snort_conf->prmUdpRTNX, p->dp, p->sp, &nssrc, &nsdst, &gen); } if ( src == NULL && dst == NULL ) { if(!prmFindRuleGroupUdp(snort_conf->prmUdpRTNX, p->dp, p->sp, &src, &dst, &nssrc, &nsdst, &gen)) return 0; } else { prmFindNoServiceRuleGroup(snort_conf->prmUdpRTNX, p->dp, p->sp, &nssrc, &nsdst, &gen); } #else if (!prmFindRuleGroupUdp(snort_conf->prmUdpRTNX, p->dp, p->sp, &src, &dst, &gen)) return 0; #endif if (fpDetectGetDebugPrintNcRules(snort_conf->fast_pattern_config)) { LogMessage( "fpEvalHeaderUdp: sport=%d, dport=%d, src:%p, dst:%p, gen:%p\n", p->sp, p->dp, (void*)src, (void*)dst, (void*)gen); } InitMatchInfo(omd); if ( dst ) fpEvalHeaderSW(dst, p, 1, 0, omd); if ( src ) fpEvalHeaderSW(src, p, 1, 0, omd); #ifdef TARGET_BASED if ( nsdst ) fpEvalHeaderSW(nsdst, p, 1, 0, omd); if ( nssrc ) fpEvalHeaderSW(nssrc, p, 1, 0, omd); #endif if ( gen ) fpEvalHeaderSW(gen, p, 1, 0, omd); return fpFinalSelectEvent(omd, p); } /* ** fpEvalHeaderTcp:: */ static inline int fpEvalHeaderTcp(Packet *p, OTNX_MATCH_DATA *omd) { PORT_GROUP *src = NULL, *dst = NULL, *gen = NULL; #ifdef TARGET_BASED PORT_GROUP *nssrc = NULL, *nsdst = NULL; if (IsAdaptiveConfigured()) { int16_t proto_ordinal = GetProtocolReference(p); if (proto_ordinal > 0 && proto_ordinal != SFTARGET_UNKNOWN_PROTOCOL) { prmFindGenericRuleGroup(snort_conf->prmTcpRTNX, &gen); if (p->packet_flags & PKT_FROM_SERVER) src = fpGetServicePortGroupByOrdinal(snort_conf->sopgTable, IPPROTO_TCP, TO_CLIENT, proto_ordinal); if (p->packet_flags & PKT_FROM_CLIENT) dst = fpGetServicePortGroupByOrdinal(snort_conf->sopgTable, IPPROTO_TCP, TO_SERVER, proto_ordinal); } } if ( src == NULL && dst == NULL ) { if(!prmFindRuleGroupTcp(snort_conf->prmTcpRTNX, p->dp, p->sp, &src, &dst, &nssrc, &nsdst, &gen)) return 0; } else { prmFindNoServiceRuleGroup(snort_conf->prmTcpRTNX, p->dp, p->sp, &nssrc, &nsdst, &gen); } #else if (!prmFindRuleGroupTcp(snort_conf->prmTcpRTNX, p->dp, p->sp, &src, &dst, &gen)) return 0; #endif InitMatchInfo(omd); if ( dst ) fpEvalHeaderSW(dst, p, 1, 0, omd); if ( src ) fpEvalHeaderSW(src, p, 1, 0, omd); #ifdef TARGET_BASED if ( nsdst ) fpEvalHeaderSW(nsdst, p, 1, 0, omd); if ( nssrc ) fpEvalHeaderSW(nssrc, p, 1, 0, omd); #endif if ( gen ) fpEvalHeaderSW(gen, p, 1, 0, omd); return fpFinalSelectEvent(omd, p); } /* ** fpEvalHeaderICMP:: */ static inline int fpEvalHeaderIcmp(Packet *p, OTNX_MATCH_DATA *omd) { PORT_GROUP *gen = NULL, *type = NULL; if (!prmFindRuleGroupIcmp(snort_conf->prmIcmpRTNX, p->icmph->type, &type, &gen)) return 0; if (fpDetectGetDebugPrintNcRules(snort_conf->fast_pattern_config)) { LogMessage( "fpEvalHeaderIcmp: icmp->type=%d type=%p gen=%p\n", p->icmph->type, (void*)type, (void*)gen); } InitMatchInfo(omd); if (type != NULL) { if (fpEvalHeaderSW(type, p, 0, 0, omd)) return 1; } if (gen != NULL) { if (fpEvalHeaderSW(gen, p, 0, 0, omd)) return 1; } return fpFinalSelectEvent(omd, p); } /* ** fpEvalHeaderIP:: */ static inline int fpEvalHeaderIp(Packet *p, int ip_proto, OTNX_MATCH_DATA *omd) { PORT_GROUP *gen = NULL, *ip_group = NULL; if (!prmFindRuleGroupIp(snort_conf->prmIpRTNX, ip_proto, &ip_group, &gen)) return 0; if(fpDetectGetDebugPrintNcRules(snort_conf->fast_pattern_config)) LogMessage("fpEvalHeaderIp: ip_group=%p, gen=%p\n", (void*)ip_group, (void*)gen); InitMatchInfo(omd); if (ip_group != NULL) { if (fpEvalHeaderSW(ip_group, p, 0, 1, omd)) return 1; } if (gen != NULL) { if (fpEvalHeaderSW(gen, p, 0, 1, omd)) return 1; } return fpFinalSelectEvent(omd, p); } /* ** ** NAME ** fpEvalPacket:: ** ** DESCRIPTION ** This function is the interface to the Detect() routine. Here ** the IP protocol is processed. If it is TCP, UDP, or ICMP, we ** process the both that particular ruleset and the IP ruleset ** with in the fpEvalHeader for that protocol. If the protocol ** is not TCP, UDP, or ICMP, we just process the packet against ** the IP rules at the end of the fpEvalPacket routine. Since ** we are using a setwise methodology for snort rules, both the ** network layer rules and the transport layer rules are done ** at the same time. While this is not the best for modularity, ** it is the best for performance, which is what we are working ** on currently. ** ** FORMAL INPUTS ** Packet * - the packet to inspect ** ** FORMAL OUTPUT ** int - 0 means that packet has been processed. ** */ int fpEvalPacket(Packet *p) { int ip_proto = GET_IPH_PROTO(p); OTNX_MATCH_DATA *omd = snort_conf->omd; /* Run UDP rules against the UDP header of Teredo packets */ if ( p->udph && (p->proto_bits & (PROTO_BIT__TEREDO | PROTO_BIT__GTP)) ) { uint16_t tmp_sp = p->sp; uint16_t tmp_dp = p->dp; const UDPHdr *tmp_udph = p->udph; const uint8_t *tmp_data = p->data; int tmp_do_detect_content = do_detect_content; uint16_t tmp_dsize = p->dsize; if (p->outer_udph) { p->udph = p->outer_udph; } p->sp = ntohs(p->udph->uh_sport); p->dp = ntohs(p->udph->uh_dport); p->data = (const uint8_t *)p->udph + UDP_HEADER_LEN; if (p->outer_ip_dsize > UDP_HEADER_LEN) p->dsize = p->outer_ip_dsize - UDP_HEADER_LEN; if (p->dsize) do_detect_content = 1; fpEvalHeaderUdp(p, omd); p->sp = tmp_sp; p->dp = tmp_dp; p->udph = tmp_udph; p->data = tmp_data; p->dsize = tmp_dsize; do_detect_content = tmp_do_detect_content; } switch(ip_proto) { case IPPROTO_TCP: DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "Detecting on TcpList\n");); if(p->tcph == NULL) { ip_proto = -1; break; } return fpEvalHeaderTcp(p, omd); case IPPROTO_UDP: DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "Detecting on UdpList\n");); if(p->udph == NULL) { ip_proto = -1; break; } return fpEvalHeaderUdp(p, omd); case IPPROTO_ICMPV6: case IPPROTO_ICMP: DEBUG_WRAP(DebugMessage(DEBUG_DETECT, "Detecting on IcmpList\n");); if(p->icmph == NULL) { ip_proto = -1; break; } return fpEvalHeaderIcmp(p, omd); default: break; } /* ** No Match on TCP/UDP, Do IP */ return fpEvalHeaderIp(p, ip_proto, omd); } void fpEvalIpProtoOnlyRules(SF_LIST **ip_proto_only_lists, Packet *p) { if ((p != NULL) && IPH_IS_VALID(p)) { SF_LIST *l = ip_proto_only_lists[GET_IPH_PROTO(p)]; OptTreeNode *otn; /* If list is NULL, sflist_first returns NULL */ for (otn = (OptTreeNode *)sflist_first(l); otn != NULL; otn = (OptTreeNode *)sflist_next(l)) { if (fpEvalRTN(getRuntimeRtnFromOtn(otn), p, 0)) { SnortEventqAdd(otn->sigInfo.generator, otn->sigInfo.id, otn->sigInfo.rev, otn->sigInfo.class_id, otn->sigInfo.priority, otn->sigInfo.message, (void *)otn); if (RULE_TYPE__PASS == getRuntimeRtnFromOtn(otn)->type) { p->packet_flags |= PKT_PASS_RULE; } } } } } static inline OptTreeNode *CreateOtnForPolicy( uint32_t gid, uint32_t sid, uint32_t rev, uint32_t classification, uint32_t priority, const char * msg, tSfPolicyId policy_id ) { OptTreeNode *otn = otnCreate( gid, sid, rev, classification, priority, msg ); if (otn) { if (GenerateSnortEventRtn(otn, policy_id)) { OtnLookupAdd(snort_conf->otn_map, otn); } else { free(otn); otn = NULL; } } return otn; } OptTreeNode *GetOtnForPolicy( uint32_t gid, uint32_t sid, uint32_t rev, uint32_t classification, uint32_t priority, const char *msg, tSfPolicyId policy_id ) { OptTreeNode *otn = OtnLookup(snort_conf->otn_map, gid, sid); if (!getRtnFromOtn(otn, policy_id)) { if (ScAutoGenPreprocDecoderOtns()) { if (!otn) { return CreateOtnForPolicy( gid, sid, rev, classification, priority, msg, policy_id ); } else if (otn->generated && GenerateSnortEventRtn(otn, policy_id)) { return otn; } } return NULL; } return otn; } OptTreeNode *GetApplicableOtn( uint32_t gid, uint32_t sid, uint32_t rev, uint32_t classification, uint32_t priority, const char * msg ) { return GetOtnForPolicy( gid, sid, rev, classification, priority, msg, getApplicableRuntimePolicy(gid) ); } snort-2.9.15.1/src/fpdetect.h0000644000175200017520000000575513571422607012622 00000000000000/* ** $Id$ ** ** fpfuncs.h ** ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Dan Roelker ** Marc Norton ** ** NOTES ** 5.15.02 - Initial Source Code. Norton/Roelker ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** */ #ifndef __FPDETECT_H__ #define __FPDETECT_H__ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "fpcreate.h" #include "snort_debug.h" #include "decode.h" #include "sflsq.h" #include "event_queue.h" #include "sfPolicy.h" #define REBUILD_FLAGS (PKT_REBUILT_FRAG | PKT_REBUILT_STREAM) /* ** This is the only function that is needed to do an ** inspection on a packet. */ int fpEvalPacket(Packet *p); int fpLogEvent(RuleTreeNode *rtn, OptTreeNode *otn, Packet *p); int fpEvalRTN(RuleTreeNode *rtn, Packet *p, int check_ports); /* ** This define is for the number of unique events ** to match before choosing which event to log. ** (Since we can only log one.) This define is the limit. */ #define MAX_EVENT_MATCH 100 /* ** MATCH_INFO ** The events that are matched get held in this structure, ** and iMatchIndex gets set to the event that holds the ** highest priority. */ typedef struct { OptTreeNode *MatchArray[MAX_EVENT_MATCH]; int iMatchCount; int iMatchIndex; int iMatchMaxLen; }MATCH_INFO; /* ** OTNX_MATCH_DATA ** This structure holds information that is ** referenced during setwise pattern matches. ** It also contains information regarding the ** number of matches that have occurred and ** the event to log based on the event comparison ** function. */ typedef struct { PORT_GROUP * pg; Packet * p; int check_ports; MATCH_INFO *matchInfo; int iMatchInfoArraySize; } OTNX_MATCH_DATA; OTNX_MATCH_DATA * OtnXMatchDataNew(int); void OtnxMatchDataFree(OTNX_MATCH_DATA *); int fpAddMatch( OTNX_MATCH_DATA *omd_local, int pLen, OptTreeNode *otn); void fpEvalIpProtoOnlyRules(SF_LIST **, Packet *); OptTreeNode *GetOtnForPolicy( uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, const char *, tSfPolicyId ); OptTreeNode *GetApplicableOtn( uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, const char * ); #define TO_SERVER 1 #define TO_CLIENT 0 #endif snort-2.9.15.1/src/pcrm.c0000644000175200017520000012670413571422607011756 00000000000000/* ** $Id$ ** ** pcrm.c ** ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Marc Norton ** Dan Roelker ** ** NOTES ** 5.15.02 - Initial version of pcrm.c distributed. - Norton/Roelker ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* ** ** Packet Classificationa and Rule Manager ** ** ** A Fast Packet Classification method for Rule and Pattern Matching in SNORT ** -------------------------------------------------------------------------- ** ** A simple method for grouping rules into lists and looking them up quickly ** in realtime. ** ** There is a natural problem when aggregating rules into pattern groups for ** performing multi-pattern matching not seen with single pattern Boyer-Moore ** strategies. The problem is how to group the rules efficiently when ** considering that there are multiple parameters which govern what rules to ** apply to each packet or connection. The paramters, sip, dip, sport, dport, ** and flags form an enormous address space of possible packets that ** must be tested in realtime against a subset of rule patterns. Methods to ** group patterns precisely based on all of these parameters can quickly ** become complicated by both algorithmic implications and implementation ** details. The procedure described herein is quick and simple. ** ** The methodology presented here to solve this problem is based on the ** premise that we can use the source and destination ports to isolate ** pattern groups for pattern matching, and rely on an event validation ** procedure to authenticate other parameters such as sip, dip and flags after ** a pattern match is made. An instrinsic assumption here is that most sip ** and dip values will be acceptable and that the big gain in performance ** is due to the fact that by isolating traffic based on services (ports) ** we gain the most benefit. Additionally, and just as important, is the ** requirement that we can perform a multi-pattern recognition-inspection phase ** on a large set of patterns many times quicker than we can apply a single ** pattern test against many single patterns. ** ** The current implementation assumes that for each rule the src and dst ports ** each have one of 2 possible values. Either a specific port number or the ** ANYPORT designation. This does allow us to handle port ranges and NOT port ** rules as well. ** ** We make the following assumptions about classifying packets based on ports: ** ** 1) There are Unique ports which represent special services. For example, ** ports 21,25,80,110,etc. ** ** 2) Patterns can be grouped into Unique Pattern groups, and a Generic ** Pattern Group ** a) Unique pattern groups exist for source ports 21,25,80,110,etc. ** b) Unique pattern groups exist for destination ports 21,25,80,etc. ** c) A Generic pattern group exists for rules applied to every ** combination of source and destination ports. ** ** We make the following assumptions about packet traffic: ** ** 1) Well behaved traffic has one Unique port and one ephemeral port for ** most packets and sometimes legitimately, as in the case of DNS, has ** two unique ports that are the same. But we always determine that ** packets with two different but Unique ports is bogus, and should ** generate an alert. For example, if you have traffic going from ** port 80 to port 20. ** ** 2) In fact, state could tell us which side of this connection is a ** service and which side is a client. Than we could handle this packet ** more precisely, but this is a rare situation and is still bogus. We ** can choose not to do pattern inspections on these packets or to do ** complete inspections. ** ** Rules are placed into each group as follows: ** ** 1) Src Port == Unique Service, Dst Port == ANY -> Unique Src Port Table ** Src Port == Unique Service, Dst Port == ** Unique -> Unique Src & Dst Port Tables ** 2) Dst Port == Unqiue Service, Src Port == ANY -> Unique Dst Port Table ** Dst Port == Unqiue Service, Src Port == ** Unique -> Unique Dst & Src Port Tables ** 3) Dst Port == ANY, Src Port == ANY -> Generic Rule Set, ** And add to all Unique Src/Dst Rule Sets that have entries ** 4) !Dst or !Src Port is the same as ANY Dst or ANY Src port respectively ** 5) DstA:DstB is treated as an ANY port group, same for SrcA:SrcB ** ** Initialization ** -------------- ** For each rule check the dst-port, if it's specific, then add it to the ** dst table. If the dst-port is Any port, then do not add it to the dst ** port table. Repeat this for the src-port. ** ** If the rule has Any for both ports then it's added generic rule list. ** ** Also, fill in the Unique-Conflicts array, this indicates if it's OK to have ** the same Unique service port for both destination and source. This will ** force an alert if it's not ok. We optionally pattern match against this ** anyway. ** ** Processing Rules ** ----------------- ** When packets arrive: ** ** Categorize the Port Uniqueness: ** ** a)Check the DstPort[DstPort] for possible rules, ** if no entry,then no rules exist for this packet with this destination. ** ** b)Check the SrcPort[SrcPort] for possible rules, ** if no entry,then no rules exist for this packet with this source. ** ** Process the Uniqueness: ** ** If a AND !b has rules or !a AND b has rules then ** match against those rules ** ** If a AND b have rules then ** if( sourcePort != DstPort ) ** Alert on this traffic and optionally match both rule sets ** else if( SourcePort == DstPort ) ** Check the Unique-Conflicts array for allowable conflicts ** if( NOT allowed ) ** Alert on this traffic, optionally match the rules ** else ** match both sets of rules against this traffic ** ** If( !a AND ! b ) then ** Pattern Match against the Generic Rules ( these apply to all packets) ** ** ** example.c ** --------- ** ** PORT_RULE_MAP * prm; ** PORT_GROUP *src, *dst, *generic; ** ** RULE * prule; //user defined rule structure for user rules ** ** prm = prmNewMap(); ** ** for( each rule ) ** { ** prule = ....get a rule pointer ** ** prmAddRule( prm, prule->dport, prule->sport, prule ); ** } ** ** prmCompileGroups( prm ); ** ** while( sniff-packets ) ** { ** .... ** ** stat = prmFindRuleGroup( prm, dport, sport, &src, &dst, &generic ); ** switch( stat ) ** { ** case 0: // No rules at all ** break; ** case 1: // Dst Rules ** // pass 'dst->pgPatData', 'dst->pgPatDataUri' to the pattern engine ** break; ** case 2: // Src Rules ** // pass 'src->pgPatData', 'src->pgPatDataUri' to the pattern engine ** break; ** case 3: // Src/Dst Rules - Both ports represent Unique service ports ** // pass 'src->pgPatData' ,'src->pgPatDataUri' to the pattern engine ** // pass 'dst->pgPatData' 'src->pgPatDataUri' to the pattern engine ** break; ** case 4: // Generic Rules Only ** // pass 'generic->pgPatData' to the pattern engine ** // pass 'generic->pgPatDataUri' to the pattern engine ** break; ** } ** } ** */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "pcrm.h" #include "util.h" #include "fpcreate.h" #include "snort.h" /* ** ** NAME ** prmNewMap:: ** ** DESCRIPTION ** Allocate new PORT_RULE_MAP and return pointer. ** ** FORMAL INPUTS ** None ** ** FORMAL OUTPUT ** PORT_RULE_MAP * - NULL if failed, ptr otherwise. ** */ PORT_RULE_MAP * prmNewMap(void) { PORT_RULE_MAP * p; p = (PORT_RULE_MAP *)calloc(1, sizeof(PORT_RULE_MAP) ); return p; } /* ** ** NAME ** prmNewByteMap:: ** ** DESCRIPTION ** Allocate new BYTE_RULE_MAP and return pointer. ** ** FORMAL INPUTS ** None ** ** FORMAL OUTPUT ** BYTE_RULE_MAP * - NULL if failed, ptr otherwise. ** */ BYTE_RULE_MAP * prmNewByteMap(void) { BYTE_RULE_MAP * p; p = (BYTE_RULE_MAP *)calloc(1, sizeof(BYTE_RULE_MAP) ); return p; } /* ** ** NAME ** prmxFreeGroup:: ** ** DESCRIPTION ** Frees a PORT_GROUP of it's RuleNodes. ** ** FORMAL INPUTS ** PORT_GROUP * - port group to free ** ** FORMAL OUTPUT ** None ** */ static void prmxFreeGroup(PORT_GROUP *pg) { RULE_NODE * rn, *rx; rn = pg->pgHead; while( rn ) { rx = rn->rnNext; free( rn ); rn = rx; } pg->pgHead = NULL; rn = pg->pgHeadNC; while( rn ) { rx = rn->rnNext; free( rn ); rn = rx; } pg->pgHeadNC = NULL; rn = pg->pgUriHead; while( rn ) { rx = rn->rnNext; free( rn ); rn = rx; } pg->pgUriHead = NULL; } /* ** ** NAME ** prmFreeMap ** ** DESCRIPTION ** Frees the memory utilized by a PORT_RULE_MAP. ** ** FORMAL INPUTS ** PORT_RULE_MAP * - PORT_RULE_MAP to free ** ** FORMAL OUTPUT ** None ** */ void prmFreeMap( PORT_RULE_MAP * p ) { int i; if( p ) { for(i=0;iprmSrcPort[i]) { prmxFreeGroup( p->prmSrcPort[i] ); free(p->prmSrcPort[i]); } } for(i=0;iprmDstPort[i]) { prmxFreeGroup( p->prmDstPort[i] ); free(p->prmDstPort[i]); } } if(p->prmGeneric) { prmxFreeGroup( p->prmGeneric ); free(p->prmGeneric); } free( p ); } } /* ** ** NAME ** prmFreeByteMap ** ** DESCRIPTION ** Frees the memory utilized by a BYTE_RULE_MAP. ** ** FORMAL INPUTS ** BYTE_RULE_MAP * - BYTE_RULE_MAP to free ** ** FORMAL OUTPUT ** None ** */ void prmFreeByteMap( BYTE_RULE_MAP * p ) { int i; if( p ) { for(i=0;i<256;i++) { prmxFreeGroup( &p->prmByteGroup[i] ); } prmxFreeGroup( &p->prmGeneric ); free( p ); } } /* ** ** NAME ** prmxAddPortRule:: ** ** DESCRIPTION ** Adds a RULE_NODE to a PORT_GROUP. This particular ** function is specific in that it adds "content" rules. ** A "content" rule is a snort rule that has a content ** flag. ** ** Each RULE_NODE in a PORT_GROUP is given a RULE_NODE ** ID. This allows us to track particulars as to what ** rules have been alerted upon, and allows other neat ** things like correlating events on different streams. ** The RULE_NODE IDs may not be consecutive, because ** we can add RULE_NODES into "content", "uri", and ** "no content" lists. ** ** FORMAL INPUTS ** PORT_GROUP * - PORT_GROUP to add the rule to. ** RULE_PTR - void ptr to the user information ** ** FORMAL OUTPUT ** int - 0 is successful, 1 is failure ** */ //static int prmxAddPortRule( PORT_GROUP *p, RULE_PTR rd ) { if( !p->pgHead ) { p->pgHead = (RULE_NODE*) calloc( 1,sizeof(RULE_NODE) ); if( !p->pgHead )return 1; p->pgHead->rnNext = 0; p->pgHead->rnRuleData = rd; p->pgTail = p->pgHead; } else { p->pgTail->rnNext = (RULE_NODE*)calloc( 1,sizeof(RULE_NODE) ); if(!p->pgTail->rnNext)return 1; p->pgTail = p->pgTail->rnNext; p->pgTail->rnNext = 0; p->pgTail->rnRuleData = rd; } /* ** Set RULE_NODE ID to unique identifier */ p->pgTail->iRuleNodeID = p->pgCount; /* ** Update the total Rule Node Count for this PORT_GROUP */ p->pgCount++; p->pgContentCount++; return 0; } /* ** ** NAME ** prmxAddPortRuleUri:: ** ** DESCRIPTION ** Adds a RULE_NODE to a PORT_GROUP. This particular ** function is specific in that it adds "uri" rules. ** A "uri" rule is a snort rule that has a uri ** flag. ** ** Each RULE_NODE in a PORT_GROUP is given a RULE_NODE ** ID. This allows us to track particulars as to what ** rules have been alerted upon, and allows other neat ** things like correlating events on different streams. ** The RULE_NODE IDs may not be consecutive, because ** we can add RULE_NODES into "content", "uri", and ** "no content" lists. ** ** FORMAL INPUTS ** PORT_GROUP * - PORT_GROUP to add the rule to. ** RULE_PTR - void ptr to the user information ** ** FORMAL OUTPUT ** int - 0 is successful, 1 is failure ** */ //static int prmxAddPortRuleUri( PORT_GROUP *p, RULE_PTR rd ) { if( !p->pgUriHead ) { p->pgUriHead = (RULE_NODE*) calloc(1, sizeof(RULE_NODE) ); if( !p->pgUriHead ) return 1; p->pgUriTail = p->pgUriHead; p->pgUriHead->rnNext = 0; p->pgUriHead->rnRuleData = rd; } else { p->pgUriTail->rnNext = (RULE_NODE*)calloc(1, sizeof(RULE_NODE) ); if( !p->pgUriTail->rnNext) return 1; p->pgUriTail = p->pgUriTail->rnNext; p->pgUriTail->rnNext = 0; p->pgUriTail->rnRuleData = rd; } /* ** Set RULE_NODE ID to unique identifier */ p->pgUriTail->iRuleNodeID = p->pgCount; /* ** Update the total Rule Node Count for this PORT_GROUP */ p->pgCount++; p->pgUriContentCount++; return 0; } /* ** ** NAME ** prmxAddPortRuleNC:: ** ** DESCRIPTION ** Adds a RULE_NODE to a PORT_GROUP. This particular ** function is specific in that it adds "no content" rules. ** A "no content" rule is a snort rule that has no "content" ** or "uri" flag, and hence does not need to be pattern ** matched. ** ** Each RULE_NODE in a PORT_GROUP is given a RULE_NODE ** ID. This allows us to track particulars as to what ** rules have been alerted upon, and allows other neat ** things like correlating events on different streams. ** The RULE_NODE IDs may not be consecutive, because ** we can add RULE_NODES into "content", "uri", and ** "no content" lists. ** ** FORMAL INPUTS ** PORT_GROUP * - PORT_GROUP to add the rule to. ** RULE_PTR - void ptr to the user information ** ** FORMAL OUTPUT ** int - 0 is successful, 1 is failure ** */ //static int prmxAddPortRuleNC( PORT_GROUP *p, RULE_PTR rd ) { if( !p->pgHeadNC ) { p->pgHeadNC = (RULE_NODE*) calloc( 1,sizeof(RULE_NODE) ); if( !p->pgHeadNC )return 1; p->pgTailNC = p->pgHeadNC; p->pgHeadNC->rnNext = 0; p->pgHeadNC->rnRuleData = rd; } else { p->pgTailNC->rnNext = (RULE_NODE*)calloc( 1,sizeof(RULE_NODE) ); if(!p->pgTailNC->rnNext)return 1; p->pgTailNC = p->pgTailNC->rnNext; p->pgTailNC->rnNext = 0; p->pgTailNC->rnRuleData = rd; } /* ** Set RULE_NODE ID to unique identifier */ p->pgTailNC->iRuleNodeID = p->pgCount; /* ** Update the Total Rule Node Count for this PORT_GROUP */ p->pgCount++; p->pgNoContentCount++; return 0; } /* ** ** NAME ** prmAddNotNode:: ** ** DESCRIPTION ** NOT SUPPORTED YET. Build a list of pur NOT nodes i.e. content !"this" ** content:!"that". ** */ void prmAddNotNode( PORT_GROUP * pg, int id ) { NOT_RULE_NODE * p = calloc(1,sizeof( NOT_RULE_NODE)); if( !p ) return ; p->iPos = id; if( !pg->pgNotRuleList ) { pg->pgNotRuleList = p; p->next = 0; } else { p->next = pg->pgNotRuleList; pg->pgNotRuleList = p; } } /* ** ** NAME ** prmGetFirstRule:: ** ** DESCRIPTION ** This function returns the first rule user data in ** the "content" list of a PORT_GROUP. ** ** FORMAL INPUTS ** PORT_GROUP * - PORT_GROUP to retrieve data from. ** ** FORMAL OUTPUT ** RULE_PTR - the ptr to the user data. ** */ RULE_PTR prmGetFirstRule( PORT_GROUP * pg ) { pg->pgCur = pg->pgHead; if( !pg->pgCur ) return 0; return pg->pgCur->rnRuleData; } /* ** ** NAME ** prmGetNextRule:: ** ** DESCRIPTION ** Gets the next "content" rule. This function allows easy ** walking of the "content" rule list. ** ** FORMAL INPUTS ** PORT_GROUP * - PORT_GROUP to retrieve data from. ** ** FORMAL OUTPUT ** RULE_PTR - ptr to the user data ** */ RULE_PTR prmGetNextRule( PORT_GROUP * pg ) { if( pg->pgCur ) pg->pgCur = pg->pgCur->rnNext; if( !pg->pgCur ) return 0; return pg->pgCur->rnRuleData; } /* ** ** NAME ** prmGetFirstRuleUri:: ** ** DESCRIPTION ** This function returns the first rule user data in ** the "uri" list of a PORT_GROUP. ** ** FORMAL INPUTS ** PORT_GROUP * - PORT_GROUP to retrieve data from. ** ** FORMAL OUTPUT ** RULE_PTR - the ptr to the user data. ** */ RULE_PTR prmGetFirstRuleUri( PORT_GROUP * pg ) { pg->pgUriCur = pg->pgUriHead; if( !pg->pgUriCur ) return 0; return pg->pgUriCur->rnRuleData; } /* ** ** NAME ** prmGetNextRuleUri:: ** ** DESCRIPTION ** Gets the next "uri" rule. This function allows easy ** walking of the "uri" rule list. ** ** FORMAL INPUTS ** PORT_GROUP * - PORT_GROUP to retrieve data from. ** ** FORMAL OUTPUT ** RULE_PTR - ptr to the user data ** */ RULE_PTR prmGetNextRuleUri( PORT_GROUP * pg ) { if( pg->pgUriCur ) pg->pgUriCur = pg->pgUriCur->rnNext; if( !pg->pgUriCur ) return 0; return pg->pgUriCur->rnRuleData; } /* ** ** NAME ** prmGetFirstRuleNC:: ** ** DESCRIPTION ** This function returns the first rule user data in ** the "no content" list of a PORT_GROUP. ** ** FORMAL INPUTS ** PORT_GROUP * - PORT_GROUP to retrieve data from. ** ** FORMAL OUTPUT ** RULE_PTR - the ptr to the user data. ** */ RULE_PTR prmGetFirstRuleNC( PORT_GROUP * pg ) { pg->pgCurNC = pg->pgHeadNC; if( !pg->pgCurNC ) return 0; return pg->pgCurNC->rnRuleData; } /* ** ** NAME ** prmGetNextRuleNC:: ** ** DESCRIPTION ** Gets the next "no content" rule. This function allows easy ** walking of the "no content" rule list. ** ** FORMAL INPUTS ** PORT_GROUP * - PORT_GROUP to retrieve data from. ** ** FORMAL OUTPUT ** RULE_PTR - ptr to the user data ** */ RULE_PTR prmGetNextRuleNC( PORT_GROUP * pg ) { if( pg->pgCurNC ) pg->pgCurNC = pg->pgCurNC->rnNext; if( !pg->pgCurNC ) return 0; return pg->pgCurNC->rnRuleData; } /* ** ** NAME ** prmAddRule:: ** ** DESCRIPTION ** This function adds a rule to a PORT_RULE_MAP. Depending on the ** values of the sport and dport, the rule gets added in different ** groups (src,dst,generic). The values for dport and sport ** can be: 0 -> 64K or -1 for generic (meaning that the rule applies ** to all values. ** ** Warning: Consider this carefully. ** Some rules use 6000:6005 -> any for a port designation, we could ** add each rule to it's own group, in this case Src=6000 to 6005. ** But we opt to add them as ANY rules for now, to reduce groups. ** ** IMPORTANT: ** This function adds a rule to the "content" list of rules. ** ** FORMAL INPUTS ** PORT_RULE_MAP * - PORT_RULE_MAP to add rule to. ** int - the dst port value. ** int - the src port value. ** RULE_PTR - the ptr to the user data for the rule. ** ** FORMAL OUTPUT ** int - 0 is successful, 1 is failure. ** */ int prmAddRule( PORT_RULE_MAP * p, int dport, int sport, RULE_PTR rd ) { if( dport != ANYPORT && dport < MAX_PORTS ) /* dst=21,25,80,110,139 */ { p->prmNumDstRules++; /* ** Check to see if this PORT_GROUP has been initialized */ if(p->prmDstPort[dport] == NULL) { p->prmDstPort[dport] = (PORT_GROUP *)calloc(1, sizeof(PORT_GROUP)); if(p->prmDstPort[dport] == NULL) { return 1; } } if(p->prmDstPort[dport]->pgCount==0) p->prmNumDstGroups++; prmxAddPortRule( p->prmDstPort[ dport ], rd ); } if( sport != ANYPORT && sport < MAX_PORTS) /* src=ANY, SRC=80,21,25,etc. */ { p->prmNumSrcRules++; /* ** Check to see if this PORT_GROUP has been initialized */ if(p->prmSrcPort[sport] == NULL) { p->prmSrcPort[sport] = (PORT_GROUP *)calloc(1, sizeof(PORT_GROUP)); if(p->prmSrcPort[sport] == NULL) { return 1; } } if(p->prmSrcPort[sport]->pgCount==0) p->prmNumSrcGroups++; prmxAddPortRule( p->prmSrcPort[ sport ], rd ); } if( sport == ANYPORT && dport == ANYPORT) /* dst=ANY, src=ANY */ { p->prmNumGenericRules++; /* ** Check to see if this PORT_GROUP has been initialized */ if(p->prmGeneric == NULL) { p->prmGeneric = (PORT_GROUP *)calloc(1, sizeof(PORT_GROUP)); if(p->prmGeneric == NULL) { return 1; } } prmxAddPortRule( p->prmGeneric, rd ); } return 0; } int prmAddByteRule( BYTE_RULE_MAP * p, int dport, RULE_PTR rd ) { if( dport != ANYPORT && dport < 256 ) /* dst=21,25,80,110,139 */ { p->prmNumRules++; if( p->prmByteGroup[dport].pgCount==0 ) p->prmNumGroups++; prmxAddPortRule( &(p->prmByteGroup[ dport ]), rd ); } else if( dport == ANYPORT ) /* dst=ANY, src=ANY */ { p->prmNumGenericRules++; prmxAddPortRule( &(p->prmGeneric), rd ); } return 0; } /* ** ** NAME ** prmAddRuleUri:: ** ** DESCRIPTION ** This function adds a rule to a PORT_RULE_MAP. Depending on the ** values of the sport and dport, the rule gets added in different ** groups (src,dst,generic). The values for dport and sport ** can be: 0 -> 64K or -1 for generic (meaning that the rule applies ** to all values. ** ** Warning: Consider this carefully. ** Some rules use 6000:6005 -> any for a port designation, we could ** add each rule to it's own group, in this case Src=6000 to 6005. ** But we opt to add them as ANY rules for now, to reduce groups. ** ** IMPORTANT: ** This function adds a rule to the "uri" list of rules. ** ** FORMAL INPUTS ** PORT_RULE_MAP * - PORT_RULE_MAP to add rule to. ** int - the dst port value. ** int - the src port value. ** RULE_PTR - the ptr to the user data for the rule. ** ** FORMAL OUTPUT ** int - 0 is successful, 1 is failure. ** */ int prmAddRuleUri( PORT_RULE_MAP * p, int dport, int sport, RULE_PTR rd ) { if( dport != ANYPORT && dport < MAX_PORTS ) /* dst=21,25,80,110,139 */ { p->prmNumDstRules++; /* ** Check to see if this PORT_GROUP has been initialized */ if(p->prmDstPort[dport] == NULL) { p->prmDstPort[dport] = (PORT_GROUP *)calloc(1, sizeof(PORT_GROUP)); if(p->prmDstPort[dport] == NULL) { return 1; } } if(p->prmDstPort[dport]->pgCount==0) p->prmNumDstGroups++; prmxAddPortRuleUri( p->prmDstPort[ dport ], rd ); } if( sport != ANYPORT && sport < MAX_PORTS) /* src=ANY, SRC=80,21,25,etc. */ { p->prmNumSrcRules++; /* ** Check to see if this PORT_GROUP has been initialized */ if(p->prmSrcPort[sport] == NULL) { p->prmSrcPort[sport] = (PORT_GROUP *)calloc(1, sizeof(PORT_GROUP)); if(p->prmSrcPort[sport] == NULL) { return 1; } } if(p->prmSrcPort[sport]->pgCount==0) p->prmNumSrcGroups++; prmxAddPortRuleUri( p->prmSrcPort[ sport ], rd ); } if( sport == ANYPORT && dport == ANYPORT) /* dst=ANY, src=ANY */ { p->prmNumGenericRules++; /* ** Check to see if this PORT_GROUP has been initialized */ if(p->prmGeneric == NULL) { p->prmGeneric = (PORT_GROUP *)calloc(1, sizeof(PORT_GROUP)); if(p->prmGeneric == NULL) { return 1; } } prmxAddPortRuleUri( p->prmGeneric, rd ); } return 0; } /* ** ** NAME ** prmAddRuleNC:: ** ** DESCRIPTION ** This function adds a rule to a PORT_RULE_MAP. Depending on the ** values of the sport and dport, the rule gets added in different ** groups (src,dst,generic). The values for dport and sport ** can be: 0 -> 64K or -1 for generic (meaning that the rule applies ** to all values. ** ** Warning: Consider this carefully. ** Some rules use 6000:6005 -> any for a port designation, we could ** add each rule to it's own group, in this case Src=6000 to 6005. ** But we opt to add them as ANY rules for now, to reduce groups. ** ** IMPORTANT: ** This function adds a rule to the "no content" list of rules. ** ** FORMAL INPUTS ** PORT_RULE_MAP * - PORT_RULE_MAP to add rule to. ** int - the dst port value. ** int - the src port value. ** RULE_PTR - the ptr to the user data for the rule. ** ** FORMAL OUTPUT ** int - 0 is successful, 1 is failure. ** */ int prmAddRuleNC( PORT_RULE_MAP * p, int dport, int sport, RULE_PTR rd ) { if( dport != ANYPORT && dport < MAX_PORTS ) /* dst=21,25,80,110,139 */ { p->prmNumDstRules++; /* ** Check to see if this PORT_GROUP has been initialized */ if(p->prmDstPort[dport] == NULL) { p->prmDstPort[dport] = (PORT_GROUP *)calloc(1, sizeof(PORT_GROUP)); if(p->prmDstPort[dport] == NULL) { return 1; } } if(p->prmDstPort[dport]->pgCount==0) p->prmNumDstGroups++; prmxAddPortRuleNC( p->prmDstPort[ dport ], rd ); } if( sport != ANYPORT && sport < MAX_PORTS) /* src=ANY, SRC=80,21,25,etc. */ { p->prmNumSrcRules++; /* ** Check to see if this PORT_GROUP has been initialized */ if(p->prmSrcPort[sport] == NULL) { p->prmSrcPort[sport] = (PORT_GROUP *)calloc(1, sizeof(PORT_GROUP)); if(p->prmSrcPort[sport] == NULL) { return 1; } } if(p->prmSrcPort[sport]->pgCount==0) p->prmNumSrcGroups++; prmxAddPortRuleNC( p->prmSrcPort[ sport ], rd ); } if( sport == ANYPORT && dport == ANYPORT) /* dst=ANY, src=ANY */ { p->prmNumGenericRules++; /* ** Check to see if this PORT_GROUP has been initialized */ if(p->prmGeneric == NULL) { p->prmGeneric = (PORT_GROUP *)calloc(1, sizeof(PORT_GROUP)); if(p->prmGeneric == NULL) { return 1; } } prmxAddPortRuleNC( p->prmGeneric, rd ); } return 0; } int prmAddByteRuleNC( BYTE_RULE_MAP * p, int dport, RULE_PTR rd ) { if( dport != ANYPORT && dport < 256 ) /* dst=21,25,80,110,139 */ { p->prmNumRules++; if(p->prmByteGroup[dport].pgCount==0) p->prmNumGroups++; prmxAddPortRuleNC( &(p->prmByteGroup[ dport ]), rd ); } else if( dport == ANYPORT) /* dst=ANY, src=ANY */ { p->prmNumGenericRules++; prmxAddPortRuleNC( &(p->prmGeneric), rd ); } return 0; } /* ** ** NAME ** prmFindRuleGroup:: ** ** DESCRIPTION ** Given a PORT_RULE_MAP, this function selects the PORT_GROUP or ** PORT_GROUPs necessary to fully match a given dport, sport pair. ** The selection logic looks at both the dport and sport and ** determines if one or both are unique. If one is unique, then ** the appropriate PORT_GROUP ptr is set. If both are unique, then ** both th src and dst PORT_GROUP ptrs are set. If neither of the ** ports are unique, then the gen PORT_GROUP ptr is set. ** ** FORMAL INPUTS ** PORT_RULE_MAP * - the PORT_RULE_MAP to pick PORT_GROUPs from. ** int - the dst port value (0->64K or -1 for generic) ** int - the src port value (0->64K or -1 for generic) ** PORT_GROUP ** - the src PORT_GROUP ptr to set. ** PORT_GROUP ** - the dst PORT_GROUP ptr to set. ** PORT_GROUP ** - the generic PORT_GROUP ptr to set. ** ** FORMAL OUTPUT ** int - 0: Don't evaluate ** 1: There are port groups to evaluate ** ** NOTES ** Currently, if there is a "unique conflict", we return both the src ** and dst PORT_GROUPs. This conflict forces us to do two searches, one ** for the src and one for the dst. So we are taking twice the time to ** inspect a packet then usual. Obviously, this is not good. There ** are several options that we have to deal with unique conflicts, but ** have not implemented any currently. The optimum solution will be to ** incorporate streaming and protocol analysis to a session so we know ** what to match against. ** */ int prmFindRuleGroup( PORT_RULE_MAP *p, int dport, int sport, PORT_GROUP **src, PORT_GROUP **dst, #ifdef TARGET_BASED PORT_GROUP **ns_src, PORT_GROUP **ns_dst, #endif PORT_GROUP **gen ) { if (!p || !src || !dst || !gen) return 0; *src = NULL; *dst = NULL; *gen = NULL; #ifdef TARGET_BASED if ( !ns_src || !ns_dst ) return 0; *ns_src = NULL; *ns_dst = NULL; #endif if (dport != ANYPORT && dport < MAX_PORTS) { *dst = p->prmDstPort[dport]; #ifdef TARGET_BASED *ns_dst = p->prmNoServiceDstPort[dport]; #endif } if (sport != ANYPORT && sport < MAX_PORTS) { *src = p->prmSrcPort[sport]; #ifdef TARGET_BASED *ns_src = p->prmNoServiceSrcPort[sport]; #endif } /* If no Src/Dst rules - use the generic set, if any exist */ if (p->prmGeneric != NULL && p->prmGeneric->pgCount > 0) { if (fpDetectSplitAnyAny(snort_conf->fast_pattern_config) || (!*src && !*dst)) { *gen = p->prmGeneric; } } if (*src == NULL && *dst == NULL && *gen == NULL) { #ifdef TARGET_BASED if (*ns_src == NULL && *ns_dst == NULL) #endif { return 0; } } return 1; } #ifdef TARGET_BASED int prmFindNoServiceRuleGroup ( PORT_RULE_MAP *p, int dport, int sport, PORT_GROUP ** src, PORT_GROUP ** dst, PORT_GROUP ** gen ) { if (!p || !src || !dst) return 0; *src = NULL; *dst = NULL; *gen = NULL; if (dport != ANYPORT && dport < MAX_PORTS) *dst = p->prmNoServiceDstPort[dport]; if (sport != ANYPORT && sport < MAX_PORTS) *src = p->prmNoServiceSrcPort[sport]; if (p->prmGeneric != NULL && p->prmGeneric->pgCount > 0) { if (fpDetectSplitAnyAny(snort_conf->fast_pattern_config) || (!*src && !*dst)) { *gen = p->prmGeneric; } } if (*src || *dst || *gen) return 1; return 0; } #endif int prmFindGenericRuleGroup(PORT_RULE_MAP *p, PORT_GROUP ** gen) { if (gen == NULL) { return 0; } *gen = NULL; if ((p->prmGeneric != NULL) && (p->prmGeneric->pgCount > 0)) { if (fpDetectSplitAnyAny(snort_conf->fast_pattern_config)) { *gen = p->prmGeneric; return 1; } } return 0; } /* * */ int prmFindByteRuleGroup( BYTE_RULE_MAP * p, int dport, PORT_GROUP **dst , PORT_GROUP ** gen) { int stat= 0; if( (dport != ANYPORT && dport < 256 ) && p->prmByteGroup[dport].pgCount ) { *dst = &p->prmByteGroup[dport]; stat = 1; }else{ *dst=0; } /* If no Src/Dst rules - use the generic set, if any exist */ if( !stat && (p->prmGeneric.pgCount > 0) ) { *gen = &p->prmGeneric; stat = 4; }else{ *gen = 0; } return stat; } /* ** Access each Rule group by index (0-MAX_PORTS) */ PORT_GROUP * prmFindDstRuleGroup( PORT_RULE_MAP * p, int port ) { if( port < 0 || port >= MAX_PORTS ) return 0; if( p->prmDstPort[port]) return p->prmDstPort[port]; return 0; } /* ** Access each Rule group by index (0-MAX_PORTS) */ PORT_GROUP * prmFindSrcRuleGroup( PORT_RULE_MAP * p, int port ) { if( port < 0 || port >= MAX_PORTS ) return 0; if( p->prmSrcPort[port]) return p->prmSrcPort[port]; return 0; } /* ** Assign the pattern matching data to this group */ int prmSetGroupPatData( PORT_GROUP * pg, void * data ) { pg->pgPms[PM_TYPE__CONTENT] = data; return 0; } /* ** Get the patttern matching data for this group */ void * prmGetGroupPatData( PORT_GROUP * pg ) { return pg->pgPms[PM_TYPE__CONTENT]; } /* ** ** NAME ** prmCompileGroups:: ** ** DESCRIPTION ** Add Generic rules to each Unique rule group, this could be ** optimized a bit, right now we will process generic rules ** twice when packets have 2 unique ports, but this will not ** occur often. ** ** The generic rules are added to the Unique rule groups, so that ** the setwise methodology can be taking advantage of. ** ** FORMAL INPUTS ** PORT_RULE_MAP * - the PORT_RULE_MAP to compile generice rules. ** ** FORMAL OUTPUT ** int - 0 is successful; ** */ int prmCompileGroups( PORT_RULE_MAP * p ) { PORT_GROUP *pgGen, *pgSrc, *pgDst; RULE_PTR *prule; int i; /* ** Add Generic to Src and Dst groups */ pgGen = p->prmGeneric; if(!pgGen) return 0; for(i=0;iprmSrcPort[i]) { pgSrc = p->prmSrcPort[i]; prule = prmGetFirstRule( pgGen ); while( prule ) { prmxAddPortRule( pgSrc, prule ); prule = prmGetNextRule( pgGen ); } prule = prmGetFirstRuleUri( pgGen ); while( prule ) { prmxAddPortRuleUri( pgSrc, prule ); prule = prmGetNextRuleUri( pgGen ); } prule = prmGetFirstRuleNC( pgGen ); while( prule ) { prmxAddPortRuleNC( pgSrc, prule ); prule = prmGetNextRuleNC( pgGen ); } } if(p->prmDstPort[i]) { pgDst = p->prmDstPort[i]; prule = prmGetFirstRule( pgGen ); while( prule ) { prmxAddPortRule( pgDst, prule ); prule = prmGetNextRule( pgGen ); } prule = prmGetFirstRuleUri( pgGen ); while( prule ) { prmxAddPortRuleUri( pgDst, prule ); prule = prmGetNextRuleUri( pgGen ); } prule = prmGetFirstRuleNC( pgGen ); while( prule ) { prmxAddPortRuleNC( pgDst, prule ); prule = prmGetNextRuleNC( pgGen ); } } #ifdef TARGET_BASED if(p->prmNoServiceDstPort[i]) { pgDst = p->prmNoServiceDstPort [i]; for (prule = prmGetFirstRule (pgGen); prule; prule = prmGetNextRule (pgGen)) prmxAddPortRule (pgDst, prule); for (prule = prmGetFirstRuleUri (pgGen); prule; prule = prmGetNextRuleUri (pgGen)) prmxAddPortRuleUri (pgDst, prule); for (prule = prmGetFirstRuleNC (pgGen); prule; prule = prmGetNextRuleNC (pgGen)) prmxAddPortRuleNC (pgDst, prule); } if(p->prmNoServiceSrcPort[i]) { pgSrc = p->prmNoServiceSrcPort [i]; for (prule = prmGetFirstRule (pgGen); prule; prule = prmGetNextRule (pgGen)) prmxAddPortRule (pgSrc, prule); for (prule = prmGetFirstRuleUri (pgGen); prule; prule = prmGetNextRuleUri (pgGen)) prmxAddPortRuleUri (pgSrc, prule); for (prule = prmGetFirstRuleNC (pgGen); prule; prule = prmGetNextRuleNC (pgGen)) prmxAddPortRuleNC (pgSrc, prule); } #endif // TARGET_BASED } return 0; } /* * * */ int prmCompileByteGroups( BYTE_RULE_MAP * p ) { PORT_GROUP *pgGen, *pgByte; RULE_PTR *prule; int i; /* ** Add Generic to Unique groups */ pgGen = &p->prmGeneric; if( !pgGen->pgCount ) return 0; for(i=0;i<256;i++) { if(p->prmByteGroup[i].pgCount) { pgByte = &p->prmByteGroup[i]; prule = prmGetFirstRule( pgGen ); while( prule ) { prmxAddPortRule( pgByte, prule ); prule = prmGetNextRule( pgGen ); } prule = prmGetFirstRuleNC( pgGen ); while( prule ) { prmxAddPortRuleNC( pgByte, prule ); prule = prmGetNextRuleNC( pgGen ); } } } return 0; } /* ** ** NAME ** prmShowStats:: ** ** DESCRIPTION ** This function shows some basic stats on the fast packet ** classification. It show the the number of PORT_GROUPS ** for a PORT_RULE_MAP, and the break down of the different ** rule types (content, uri, no content). ** ** FORMAL INPUTS ** PORT_RULE_MAP * - the PORT_RULE_MAP to show stats on. ** ** FORMAL OUTPUT ** int - 0 is successful. ** */ int prmShowStats( PORT_RULE_MAP * p ) { int i; PORT_GROUP * pg; LogMessage("Packet Classification Rule Manager Stats ----\n"); LogMessage("NumDstGroups : %d\n",p->prmNumDstGroups); LogMessage("NumSrcGroups : %d\n",p->prmNumSrcGroups); LogMessage("\n"); LogMessage("NumDstRules : %d\n",p->prmNumDstRules); LogMessage("NumSrcRules : %d\n",p->prmNumSrcRules); LogMessage("NumGenericRules: %d\n",p->prmNumGenericRules); LogMessage("\n"); LogMessage("%d Dst Groups In Use, %d Unique Rules, includes generic\n",p->prmNumDstGroups,p->prmNumDstRules); for(i=0;ipgUriContentCount,pg->pgContentCount,pg->pgNoContentCount); if( pg->avgLen ) { LogMessage("MinLen=%d MaxLen=%d AvgLen=%d",pg->minLen,pg->maxLen,pg->avgLen); if(pg->c1)LogMessage(" [1]=%d",pg->c1); if(pg->c2)LogMessage(" [2]=%d",pg->c2); if(pg->c3)LogMessage(" [3]=%d",pg->c3); if(pg->c4)LogMessage(" [4]=%d",pg->c4); LogMessage("\n"); } } } LogMessage("%d Src Groups In Use, %d Unique Rules, includes generic\n",p->prmNumSrcGroups,p->prmNumSrcRules); for(i=0;ipgUriContentCount,pg->pgContentCount,pg->pgNoContentCount); if( pg->avgLen ) { LogMessage("MinLen=%d MaxLen=%d AvgLen=%d",pg->minLen,pg->maxLen,pg->avgLen); if(pg->c1)LogMessage(" [1]=%d",pg->c1); if(pg->c2)LogMessage(" [2]=%d",pg->c2); if(pg->c3)LogMessage(" [3]=%d",pg->c3); if(pg->c4)LogMessage(" [4]=%d",pg->c4); LogMessage("\n"); } } } pg = p->prmGeneric; if(pg){ LogMessage(" Generic Rules : %d uricontent, %d content, %d nocontent \n", pg->pgUriContentCount,pg->pgContentCount,pg->pgNoContentCount); if( pg->avgLen ) { LogMessage("MinLen=%d MaxLen=%d AvgLen=%d",pg->minLen,pg->maxLen,pg->avgLen); if(pg->c1)LogMessage(" [1]=%d",pg->c1); if(pg->c2)LogMessage(" [2]=%d",pg->c2); if(pg->c3)LogMessage(" [3]=%d",pg->c3); if(pg->c4)LogMessage(" [4]=%d",pg->c4); LogMessage("\n"); } } return 0; } /* ** ** NAME ** prmShowEventStats:: ** ** DESCRIPTION ** This function is used at the close of the Fast Packet ** inspection. It tells how many non-qualified and qualified ** hits occurred for each PORT_GROUP. A non-qualified hit ** is defined by an initial match against a packet, but upon ** further inspection a hit was not validated. Non-qualified ** hits occur because we can match on the most unique aspect ** of a packet, this is the content. Snort has other flags ** then content though, so once we hit a content match we must ** verify these additional flags. Sometimes these flags do ** not pass the validation. A qualified hit is an event that ** has been fully qualified, and has been put in the event ** cache for event selection. Qualified hits are not a subset ** of non-qualified hits. Ideally, non-qualified hits should ** be zero. The reason for these stats is that it allows ** users to trouble shoot PORT_GROUPs. A poorly written rule ** may cause many non-qualified events, and these stats ** allow the user to track this down. ** ** FORMAL INPUTS ** PORT_RULE_MAP * - the PORT_RULE_MAP to show stats on. ** ** FORMAL OUTPUT ** int - 0 is successful. ** */ int prmShowEventStats( PORT_RULE_MAP * p ) { int i; PORT_GROUP * pg; int NQEvents = 0; int QEvents = 0; LogMessage("Packet Classification Rule Manager Stats ----\n"); LogMessage("NumDstGroups : %d\n",p->prmNumDstGroups); LogMessage("NumSrcGroups : %d\n",p->prmNumSrcGroups); LogMessage("\n"); LogMessage("NumDstRules : %d\n",p->prmNumDstRules); LogMessage("NumSrcRules : %d\n",p->prmNumSrcRules); LogMessage("NumGenericRules: %d\n",p->prmNumGenericRules); LogMessage("\n"); LogMessage("%d Dst Groups In Use, %d Unique Rules, includes generic\n",p->prmNumDstGroups,p->prmNumDstRules); for(i=0;ipgNQEvents; QEvents += pg->pgQEvents; if( pg->pgNQEvents + pg->pgQEvents ) { LogMessage(" Dst Port %5d : %d group entries \n",i, pg->pgCount); LogMessage(" NQ Events : %d\n", pg->pgNQEvents); LogMessage(" Q Events : %d\n", pg->pgQEvents); } } } LogMessage("%d Src Groups In Use, %d Unique Rules, includes generic\n",p->prmNumSrcGroups,p->prmNumSrcRules); for(i=0;ipgNQEvents; QEvents += pg->pgQEvents; if( pg->pgNQEvents + pg->pgQEvents ) { LogMessage(" Src Port %5d : %d group entries \n",i, pg->pgCount); LogMessage(" NQ Events : %d\n", pg->pgNQEvents); LogMessage(" Q Events : %d\n", pg->pgQEvents); } } } pg = p->prmGeneric; if(pg) { NQEvents += pg->pgNQEvents; QEvents += pg->pgQEvents; if( pg->pgNQEvents + pg->pgQEvents ) { LogMessage(" Generic Rules : %d group entries\n", pg->pgCount); LogMessage(" NQ Events : %d\n", pg->pgNQEvents); LogMessage(" Q Events : %d\n", pg->pgQEvents); } } LogMessage("Total NQ Events : %d\n", NQEvents); LogMessage("Total Q Events : %d\n", QEvents); return 0; } snort-2.9.15.1/src/pcrm.h0000644000175200017520000001400713571422607011753 00000000000000/* ** $Id$ ** ** pcrm.h ** ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Marc Norton ** Dan Roelker ** ** ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** ** Packet Classification-Rule Manager ** */ #ifndef _PCRM_H #define _PCRM_H #include "decode.h" #include "bitop.h" typedef void * RULE_PTR; #define ANYPORT (-1) /* ** Macros to walk a RULE_NODE list, and get the ** RULE_PTR from a RULE_NODE, these eliminate ** subroutine calls, in high performance needs. */ #define PRM_GET_FIRST_GROUP_NODE(pg) (pg->pgHead) #define PRM_GET_NEXT_GROUP_NODE(rn) (rn->rnNext) #define PRM_GETRULE_FROM_NODE(rn) (rn->rnRuleData) #define PRM_GET_FIRST_GROUP_NODE_NC(pg) (pg->pgHeadNC) #define PRM_GET_NEXT_GROUP_NODE_NC(rn) (rn->rnNext) typedef enum _PmType { PM_TYPE__CONTENT = 0, PM_TYPE__HTTP_URI_CONTENT, PM_TYPE__HTTP_HEADER_CONTENT, PM_TYPE__HTTP_CLIENT_BODY_CONTENT, PM_TYPE__HTTP_METHOD_CONTENT, PM_TYPE__MAX } PmType; typedef struct _not_rule_node_ { struct _not_rule_node_ * next; int iPos; /* RULE_NODE->iRuleNodeID */ } NOT_RULE_NODE; typedef struct _rule_node_ { struct _rule_node_ * rnNext; RULE_PTR rnRuleData; int iRuleNodeID; }RULE_NODE; typedef struct { /* Content List */ RULE_NODE *pgHead, *pgTail, *pgCur; int pgContentCount; /* No-Content List */ RULE_NODE *pgHeadNC, *pgTailNC, *pgCurNC; int pgNoContentCount; /* Uri-Content List */ RULE_NODE *pgUriHead, *pgUriTail, *pgUriCur; int pgUriContentCount; /* Pattern Matching data structures (MPSE) */ void *pgPms[PM_TYPE__MAX]; /* detection option tree */ void *pgNonContentTree; int avgLen; int minLen; int maxLen; int c1,c2,c3,c4,c5; /* * Not rule list for this group */ NOT_RULE_NODE *pgNotRuleList; /* ** Count of rule_node's in this group/list */ int pgCount; int pgNQEvents; int pgQEvents; }PORT_GROUP; typedef struct { int prmNumDstRules; int prmNumSrcRules; int prmNumGenericRules; #ifdef TARGET_BASED int prmNumNoServiceDstRules; int prmNumNoServiceSrcRules; #endif int prmNumDstGroups; int prmNumSrcGroups; #ifdef TARGET_BASED int prmNumNoServiceDstGroups; int prmNumNoServiceSrcGroups; #endif PORT_GROUP *prmDstPort[MAX_PORTS]; PORT_GROUP *prmSrcPort[MAX_PORTS]; /* char prmConflicts[MAX_PORTS]; */ #ifdef TARGET_BASED PORT_GROUP *prmNoServiceDstPort[MAX_PORTS]; PORT_GROUP *prmNoServiceSrcPort[MAX_PORTS]; #endif PORT_GROUP *prmGeneric; } PORT_RULE_MAP ; typedef struct { int prmNumRules; int prmNumGenericRules; int prmNumGroups; PORT_GROUP prmByteGroup[256]; PORT_GROUP prmGeneric; } BYTE_RULE_MAP ; PORT_RULE_MAP * prmNewMap(void); BYTE_RULE_MAP * prmNewByteMap(void); void prmFreeMap( PORT_RULE_MAP * p ); void prmFreeByteMap( BYTE_RULE_MAP * p ); int prmxAddPortRule( PORT_GROUP * p, RULE_PTR rd ); int prmxAddPortRuleUri( PORT_GROUP * p, RULE_PTR rd ); int prmxAddPortRuleNC( PORT_GROUP * p, RULE_PTR rd ); int prmAddRule( PORT_RULE_MAP * p, int dport, int sport, RULE_PTR rd ); int prmAddByteRule( BYTE_RULE_MAP * p, int dport, RULE_PTR rd ); int prmAddRuleUri( PORT_RULE_MAP * p, int dport, int sport, RULE_PTR rd ); int prmAddRuleNC( PORT_RULE_MAP * p, int dport, int sport, RULE_PTR rd ); int prmAddByteRuleNC( BYTE_RULE_MAP * p, int dport, RULE_PTR rd ); void prmAddNotNode( PORT_GROUP * pg, int id ); int prmCompileGroups( PORT_RULE_MAP * p ); int prmCompileByteGroups( BYTE_RULE_MAP * p ); int prmShowStats( PORT_RULE_MAP * p ); int prmShowByteStats( BYTE_RULE_MAP * p ); int prmShowEventStats( PORT_RULE_MAP * p ); int prmShowEventByteStats( BYTE_RULE_MAP * p ); RULE_PTR prmGetFirstRule( PORT_GROUP * pg ); RULE_PTR prmGetNextRule( PORT_GROUP * pg ); RULE_PTR prmGetFirstRuleUri( PORT_GROUP * pg ); RULE_PTR prmGetNextRuleUri( PORT_GROUP * pg ); RULE_PTR prmGetFirstRuleNC( PORT_GROUP * pg ); RULE_PTR prmGetNextRuleNC( PORT_GROUP * pg ); #ifdef TARGET_BASED // Get all the port groups int prmFindRuleGroup( PORT_RULE_MAP*, int dest_port, int source_port, PORT_GROUP** source, PORT_GROUP** dest, PORT_GROUP** source_noservice, PORT_GROUP** dest_noservice, PORT_GROUP** anyany); // Return only the noservice port groups int prmFindNoServiceRuleGroup( PORT_RULE_MAP*, int dest_port, int source_port, PORT_GROUP** source_noservice, PORT_GROUP** dest_noservice, PORT_GROUP** anyany); #else // Get all the port groups int prmFindRuleGroup( PORT_RULE_MAP * p, int dest_port, int source_port, PORT_GROUP** src, PORT_GROUP** dst, PORT_GROUP** gen); #endif int prmFindByteRuleGroup( BYTE_RULE_MAP * p, int dport, PORT_GROUP **dst , PORT_GROUP ** gen); int prmFindGenericRuleGroup(PORT_RULE_MAP *prm, PORT_GROUP ** gen); PORT_GROUP * prmFindDstRuleGroup( PORT_RULE_MAP * p, int port ); PORT_GROUP * prmFindSrcRuleGroup( PORT_RULE_MAP * p, int port ); PORT_GROUP * prmFindByteRuleGroupUnique( BYTE_RULE_MAP * p, int port ); int prmSetGroupPatData( PORT_GROUP * pg, void * data ); void * prmGetGroupPatData( PORT_GROUP * pg ); #endif snort-2.9.15.1/src/snort_bounds.h0000644000175200017520000001405613571422607013535 00000000000000#ifndef _BOUNDS_H #define _BOUNDS_H /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2003-2013 Sourcefire, Inc. ** Chris Green ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** */ #ifdef OSF1 #include #endif #include #include #include #include #include #ifdef DEBUG #include #endif #include #define SAFEMEM_ERROR 0 #define SAFEMEM_SUCCESS 1 #ifdef DEBUG #define ERRORRET assert(0==1) #else #define ERRORRET return SAFEMEM_ERROR; #endif /* DEBUG */ #define MAXPORTS 65536 #define MAXPORTS_STORAGE 8192 /* * Check to make sure that p is less than or equal to the ptr range * pointers * * 1 means it's in bounds, 0 means it's not */ static inline int inBounds(const uint8_t *start, const uint8_t *end, const uint8_t *p) { if ((p >= start) && (p < end)) return 1; return 0; } static inline int SafeMemCheck(void *dst, size_t n, const void *start, const void *end) { void *tmp; if (n < 1) return SAFEMEM_ERROR; if ((dst == NULL) || (start == NULL) || (end == NULL)) return SAFEMEM_ERROR; tmp = ((uint8_t *)dst) + (n - 1); if (tmp < dst) return SAFEMEM_ERROR; if (!inBounds(start, end, dst) || !inBounds(start, end, tmp)) return SAFEMEM_ERROR; return SAFEMEM_SUCCESS; } /** * A Safer Memcpy * * @param dst where to copy to * @param src where to copy from * @param n number of bytes to copy * @param start start of the dest buffer * @param end end of the dst buffer * * @return SAFEMEM_ERROR on failure, SAFEMEM_SUCCESS on success */ static inline int SafeMemcpy(void *dst, const void *src, size_t n, const void *start, const void *end) { if (!n) return SAFEMEM_SUCCESS; if (SafeMemCheck(dst, n, start, end) != SAFEMEM_SUCCESS) ERRORRET; if (src == NULL) ERRORRET; memcpy(dst, src, n); return SAFEMEM_SUCCESS; } /** * A Safer Memmove * dst and src can be in the same buffer * * @param dst where to copy to * @param src where to copy from * @param n number of bytes to copy * @param start start of the dest buffer * @param end end of the dst buffer * * @return SAFEMEM_ERROR on failure, SAFEMEM_SUCCESS on success */ static inline int SafeMemmove(void *dst, const void *src, size_t n, const void *start, const void *end) { if (SafeMemCheck(dst, n, start, end) != SAFEMEM_SUCCESS) ERRORRET; if (src == NULL) ERRORRET; memmove(dst, src, n); return SAFEMEM_SUCCESS; } /** * A Safer Memmove * dst and src can be in the same buffer * * @param dst where to copy to * @param src where to copy from * @param n number of bytes to copy * @param start start of the dest buffer * @param end end of the dst buffer * * @return SAFEMEM_ERROR on failure, SAFEMEM_SUCCESS on success */ static inline int SafeBoundsMemmove(void *dst, const void *src, size_t n, const void *start, const void *end) { size_t overlap = 0; if (SafeMemCheck(dst, n, start, end) != SAFEMEM_SUCCESS) ERRORRET; if (src == NULL) ERRORRET; if( src == dst ) { return SAFEMEM_SUCCESS; } else if(inBounds(dst, ((uint8_t *)dst + n), src)) { overlap = (uint8_t *)src - (uint8_t *)dst; memcpy(dst, src , overlap); memmove(((uint8_t *)dst + overlap), ((uint8_t *)src + overlap), (n - overlap)); } else if(inBounds(src, ((uint8_t *)src + n), dst)) { overlap = (uint8_t *)dst - (uint8_t *)src; memcpy(((uint8_t *)dst + overlap), ((uint8_t *)src + overlap), (n - overlap)); memmove(dst, src, overlap); } else { memcpy(dst, src, n); } return SAFEMEM_SUCCESS; } /** * A Safer Memset * dst and src can be in the same buffer * * @param dst where to copy to * @param c character to set memory with * @param n number of bytes to set * @param start start of the dst buffer * @param end end of the dst buffer * * @return SAFEMEM_ERROR on failure, SAFEMEM_SUCCESS on success */ static inline int SafeMemset(void *dst, uint8_t c, size_t n, const void *start, const void *end) { if (SafeMemCheck(dst, n, start, end) != SAFEMEM_SUCCESS) ERRORRET; memset(dst, c, n); return SAFEMEM_SUCCESS; } /** * A Safer *a = *b * * @param start start of the dst buffer * @param end end of the dst buffer * @param dst the location to write to * @param src the source to read from * * @return 0 on failure, 1 on success */ static inline int SafeWrite(uint8_t *start, uint8_t *end, uint8_t *dst, uint8_t *src) { if(!inBounds(start, end, dst)) { ERRORRET; } *dst = *src; return 1; } static inline int SafeRead(uint8_t *start, uint8_t *end, uint8_t *src, uint8_t *read) { if(!inBounds(start,end, src)) { ERRORRET; } *read = *start; return 1; } /* An wrapper around snprintf to make it safe. * * This wrapper of snprintf returns the number of bytes written to the buffer. */ static inline size_t SafeSnprintf(char *str, size_t size, const char *format, ...) { va_list ap; int ret; if (size == 0) return 0; va_start(ap, format); ret = vsnprintf(str, size, format, ap); va_end(ap); if (ret < 0 || (size_t)ret >= size) return 0; return (size_t)ret; } #endif /* _BOUNDS_H */ snort-2.9.15.1/src/byte_extract.c0000644000175200017520000002146713571422607013512 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2003-2013 Sourcefire, Inc. ** Chris Green ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** ** */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "snort.h" #include "util.h" #include #include #include #ifdef HAVE_STRINGS_H #include #endif #include #include "snort_bounds.h" #include "byte_extract.h" #include "snort_debug.h" #define TEXTLEN (PARSELEN + 1) /** * Grab a binary representation of data from a buffer * * This method will read either a big or little endian value in binary * data from the packet and return an uint32_t value. * * @param endianess value to read the byte as * @param bytes_to_grab how many bytes should we grab from the packet * @param data pointer to where to grab the data from * @param start pointer to start range of buffer * @param end pointer to end range of buffer * @param value pointer to store data in * * @returns 0 on success, otherwise failure */ int byte_extract(int endianess, int bytes_to_grab, const uint8_t *ptr, const uint8_t *start, const uint8_t *end, uint32_t *value) { if(endianess != LITTLE && endianess != BIG) { /* we only support 2 byte formats */ return -2; } /* make sure the data to grab stays in bounds */ if(!inBounds(start,end,ptr + (bytes_to_grab - 1))) { return -3; } if(!inBounds(start,end,ptr)) { return -3; } /* * We only support grabbing 1, 2, or 4 bytes of binary data. * And now, due to popular demand, 3 bytes! */ switch(bytes_to_grab) { case 1: *value = (*ptr) & 0xFF; break; case 2: if(endianess == LITTLE) { *value = (*ptr) & 0xFF; *value |= (*(ptr + 1) & 0xFF) << 8; } else { *value = ((*ptr) & 0xFF) << 8; *value |= (*(ptr + 1)) & 0xFF; } break; case 3: if (endianess == LITTLE) { *value = (*ptr) & 0xFF; *value |= ((*(ptr + 1)) & 0xFF) << 8; *value |= ((*(ptr + 2)) & 0xFF) << 16; } else { *value = ((*ptr) & 0xFF) << 16; *value |= ((*(ptr + 1)) & 0xFF) << 8; *value |= (*(ptr + 2)) & 0xFF; } break; case 4: if(endianess == LITTLE) { *value = (*ptr) & 0xFF; *value |= ((*(ptr + 1)) & 0xFF) << 8; *value |= ((*(ptr + 2)) & 0xFF) << 16; *value |= ((*(ptr + 3)) & 0xFF) << 24; } else { *value = ((*ptr) & 0xFF) << 24; *value |= ((*(ptr + 1)) & 0xFF) << 16; *value |= ((*(ptr + 2)) & 0xFF) << 8; *value |= (*(ptr + 3)) & 0xFF; } break; default: /* unknown type */ return -1; } return 0; } /** * Grab a string representation of data from a buffer * * @param base base representation for data: -> man stroul() * @param bytes_to_grab how many bytes should we grab from the packet * @param data pointer to where to grab the data from * @param start pointer to start range of buffer * @param end pointer to end range of buffer * @param value pointer to store data in * * @returns 0 on success, otherwise failure */ int string_extract(int bytes_to_grab, int base, const uint8_t *ptr, const uint8_t *start, const uint8_t *end, uint32_t *value) { char byte_array[TEXTLEN]; char *parse_helper; int x; /* counter */ if(bytes_to_grab > (TEXTLEN - 1) || bytes_to_grab <= 0) { return -1; } /* make sure the data to grab stays in bounds */ if(!inBounds(start,end,ptr + (bytes_to_grab - 1))) { return -3; } if(!inBounds(start,end,ptr)) { return -3; } for(x=0;x void test_extract(void) { int i; uint32_t ret; uint8_t value1[2]; uint8_t value2[2]; uint8_t value3[4]; value1[0] = 0; value1[1] = 0xff; value2[0] = 0xff; value2[1] = 0x01; value3[0] = 0xff; value3[1] = 0xff; value3[2] = 0x00; value3[3] = 0x00; if(byte_extract(BIG, 2, value1, value1, value1 + 2, &ret)) { printf("test 1 failed\n"); } else { printf("test 1: value: %x %u\n", ret, ret); } if(byte_extract(LITTLE, 2, value1, value1, value1 + 2, &ret)) { printf("test 2 failed\n"); } else { printf("test 2: value: %x %u\n", ret, ret); } if(byte_extract(LITTLE, 2, value1 + 2, value1, value1 + 2, &ret)) { printf("test 3 failed correctly\n"); } else { printf("test 3: value: %x %u\n", ret, ret); } if(byte_extract(BIG, 2, value2, value2, value2 + 2, &ret)) { printf("test 1 failed\n"); } else { printf("test 1: value: %x %u\n", ret, ret); } if(byte_extract(LITTLE, 2, value2, value2, value2 + 2, &ret)) { printf("test 2 failed\n"); } else { printf("test 2: value: %x %u\n", ret, ret); } if(byte_extract(LITTLE, 2, value2 + 2, value2, value2 + 2, &ret)) { printf("test 3 failed correctly\n"); } else { printf("test 3: value: %x %u\n", ret, ret); } if(byte_extract(BIG, 4, value3, value3, value3 + 4, &ret)) { printf("test 1 failed\n"); } else { printf("test 1: value: %x %u\n", ret, ret); } if(byte_extract(LITTLE, 4, value3, value3, value3 + 4, &ret)) { printf("test 2 failed\n"); } else { printf("test 2: value: %x %u\n", ret, ret); } if(byte_extract(LITTLE, 4, value3 + 2, value3, value3 + 4, &ret)) { printf("test 3 failed correctly\n"); } else { printf("test 3: value: %x %u\n", ret, ret); } printf("-----------------------------\n"); for(i=0;i<10;i++) { if(byte_extract(LITTLE, 4, value3 + i, value3, value3 + 4, &ret)) { printf("[loop] %d failed correctly\n", i); } else { printf("[loop] value: %x %x\n", ret, *(uint32_t *) &value3); } } } void test_string(void) { char *stringdata = "21212312412"; int datalen = strlen(stringdata); uint32_t ret; if(string_extract(4, 10, stringdata, stringdata, stringdata + datalen, &ret) < 0) { printf("TS1: Failed\n"); } else { printf("TS1: value %x %u\n", ret, ret); } if(string_extract(10, 10, stringdata, stringdata, stringdata + datalen, &ret) < 0) { printf("TS2: Failed\n"); } else { printf("TS2: value %x %u\n", ret, ret); } if(string_extract(9, 10, stringdata, stringdata, stringdata + datalen, &ret) < 0) { printf("TS3: Failed\n"); } else { printf("TS3: value %x %u\n", ret, ret); } if(string_extract(19, 10, stringdata, stringdata, stringdata + datalen, &ret) < 0) { printf("TS4: Failed Normally\n"); } else { printf("TS4: value %x %u\n", ret, ret); } } int main(void) { test_extract(); test_string(); return 0; } #endif /* TEST_BYTE_EXTRACT */ snort-2.9.15.1/src/byte_extract.h0000644000175200017520000000304413571422607013506 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2003-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #ifndef _BYTE_EXTRACT_H #define _BYTE_EXTRACT_H #define ENDIAN_NONE -1 #define BIG 0 #define LITTLE 1 #define ENDIAN_FUNC 2 #define PARSELEN 10 int string_extract(int bytes_to_grab, int base, const uint8_t *ptr, const uint8_t *start, const uint8_t *end, uint32_t *value); int byte_extract(int endianess, int bytes_to_grab, const uint8_t *ptr, const uint8_t *start, const uint8_t *end, uint32_t *value); #endif /* _BYTE_EXTRACT_H */ snort-2.9.15.1/src/timersub.h0000644000175200017520000000313213571422607012641 00000000000000/* Copyright (C) 1991-1994,96,97,98,99,2000,01,02 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /* never worry about timersub type activies again -- from GLIBC and upcased. */ #define TIMERSUB(a, b, result) \ do { \ (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ if ((result)->tv_usec < 0) { \ --(result)->tv_sec; \ (result)->tv_usec += 1000000; \ } \ } while (0) snort-2.9.15.1/src/spo_plugbase.h0000644000175200017520000000547513571422607013506 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifndef __SPO_PLUGBASE_H__ #define __SPO_PLUGBASE_H__ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "event.h" #include "decode.h" typedef enum _OutputType { OUTPUT_TYPE__ALERT = 1, OUTPUT_TYPE__LOG, OUTPUT_TYPE__MAX } OutputType; typedef enum _OutputTypeFlag { OUTPUT_TYPE_FLAG__ALERT = 0x00000001, OUTPUT_TYPE_FLAG__LOG = 0x00000002, OUTPUT_TYPE_FLAG__ALL = 0x7fffffff } OutputTypeFlag; /***************************** Output Plugin API *****************************/ typedef void (*OutputConfigFunc)(struct _SnortConfig *, char *); typedef void (*OutputFunc)(Packet *, const char *, void *, Event *); typedef struct _OutputConfigFuncNode { char *keyword; int output_type_flags; union { OutputConfigFunc fptr; void *void_fptr; } cfptr; struct _OutputConfigFuncNode *next; } OutputConfigFuncNode; typedef struct _OutputFuncNode { void *arg; union { OutputFunc fptr; void *vfptr; } fptr; #ifdef DUMP_BUFFER /*A function pointer to point LogBufferDump function. This is used only for BufferDump output plugin. For other plugins, this would point to NULL. This would help in identifying the BufferDump output plugin while traversing the Loglist linked list*/ OutputFunc bdfptr; #endif struct _OutputFuncNode *next; } OutputFuncNode; void RegisterOutputPlugins(void); void RegisterOutputPlugin(char *, int, OutputConfigFunc); OutputConfigFunc GetOutputConfigFunc(char *); void RemoveOutputPlugin(char *); int GetOutputTypeFlags(char *); void DumpOutputPlugins(void); void AddFuncToOutputList(struct _SnortConfig *, OutputFunc, OutputType, void *); #ifdef DUMP_BUFFER void AddBDFuncToOutputList(struct _SnortConfig *, OutputFunc, OutputType, void *); #endif void FreeOutputConfigFuncs(void); void FreeOutputList(OutputFuncNode *); #endif /* __SPO_PLUGBASE_H__ */ snort-2.9.15.1/src/sfthreshold.c0000644000175200017520000003042713571422607013336 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2003-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* sfthreshold.c This file contains functions that glue the generic thresholding2 code to snort. dependent files: sfthd sfxghash sfghash sflsq util mstring Marc Norton 2003-05-29: cmg: Added s_checked variable -- when this is 1, the sfthreshold_test will always return the same answer until sfthreshold_reset is called 2003-11-3: man: cleaned up and added more startup printout. */ #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "mstring.h" #include "util.h" #include "parser.h" #include "sfthd.h" #include "sfthreshold.h" #include "snort.h" #ifndef WIN32 #include #include #include #endif #include /* Data */ THD_STRUCT *thd_runtime = NULL; static int thd_checked = 0; static int thd_answer = 0; typedef enum { PRINT_GLOBAL, PRINT_LOCAL, PRINT_SUPPRESS } PrintFormat; ThresholdConfig * ThresholdConfigNew(void) { ThresholdConfig *tc = (ThresholdConfig *)SnortAlloc(sizeof(ThresholdConfig)); /* sfthd_objs_new will handle fatal */ tc->thd_objs = sfthd_objs_new(); tc->memcap = 1024 * 1024; tc->enabled = 1; return tc; } void ThresholdConfigFree(ThresholdConfig *tc) { if (tc == NULL) return; if (tc->thd_objs != NULL) { sfthd_objs_free(tc->thd_objs); tc->thd_objs = NULL; } free(tc); } // prnMode = 0: init output format // prnMode = 1: term output format (with header and count of filtered events) // prnMode = 2: term output format (count only) static int print_thd_node( THD_NODE *p , PrintFormat type, unsigned* prnMode ) { char buf[STD_BUF+1]; memset(buf, 0, STD_BUF+1); switch( type ) { case PRINT_GLOBAL: if(p->type == THD_TYPE_SUPPRESS ) return 0; if(p->sig_id != 0 ) return 0; break; case PRINT_LOCAL: if(p->type == THD_TYPE_SUPPRESS ) return 0; if(p->sig_id == 0 || p->gen_id == 0 ) return 0; break; case PRINT_SUPPRESS: if(p->type != THD_TYPE_SUPPRESS ) return 0; break; } /* SnortSnprintfAppend(buf, STD_BUF, "| thd-id=%d", p->thd_id ); */ if ( *prnMode && !p->filtered ) return 1; if( p->gen_id == 0 ) { SnortSnprintfAppend(buf, STD_BUF, "| gen-id=global"); } else { SnortSnprintfAppend(buf, STD_BUF, "| gen-id=%-6d", p->gen_id ); } if( p->sig_id == 0 ) { SnortSnprintfAppend(buf, STD_BUF, " sig-id=global" ); } else { SnortSnprintfAppend(buf, STD_BUF, " sig-id=%-10d", p->sig_id ); } switch ( p->type ) { case THD_TYPE_LIMIT: SnortSnprintfAppend(buf, STD_BUF, " type=Limit "); break; case THD_TYPE_THRESHOLD: SnortSnprintfAppend(buf, STD_BUF, " type=Threshold"); break; case THD_TYPE_BOTH: SnortSnprintfAppend(buf, STD_BUF, " type=Both "); break; case THD_TYPE_SUPPRESS: if ( *prnMode ) SnortSnprintfAppend(buf, STD_BUF, " type=Suppress "); break; } switch ( p->tracking ) { case THD_TRK_NONE: SnortSnprintfAppend(buf, STD_BUF, " tracking=none"); break; case THD_TRK_SRC: SnortSnprintfAppend(buf, STD_BUF, " tracking=src"); break; case THD_TRK_DST: SnortSnprintfAppend(buf, STD_BUF, " tracking=dst"); break; } if( p->type == THD_TYPE_SUPPRESS ) { if ( p->tracking != THD_TRK_NONE ) { // TBD output suppress node ip addr set SnortSnprintfAppend(buf, STD_BUF, "-ip=%-16s", ""); } } else { SnortSnprintfAppend(buf, STD_BUF, " count=%-3d", p->count); SnortSnprintfAppend(buf, STD_BUF, " seconds=%-3d", p->seconds); } if ( *prnMode ) { if ( *prnMode == 1 ) { LogMessage("+-----------------------[filtered events]--------------------------------------\n"); *prnMode = 2; } SnortSnprintfAppend(buf, STD_BUF, " filtered=" STDu64, p->filtered); } LogMessage("%s\n", buf); return 1; } /* * */ static int print_thd_local(ThresholdObjects *thd_objs, PrintFormat type, unsigned* prnMode) { SFGHASH * sfthd_hash; THD_ITEM * sfthd_item; THD_NODE * sfthd_node; int gen_id; SFGHASH_NODE * item_hash_node; int lcnt=0; tSfPolicyId policyId; for (policyId = 0; policyId < thd_objs->numPoliciesAllocated; policyId++) { for(gen_id=0;gen_id < THD_MAX_GENID ; gen_id++ ) { sfthd_hash = thd_objs->sfthd_array[gen_id]; if( !sfthd_hash ) { continue; } for(item_hash_node = sfghash_findfirst( sfthd_hash ); item_hash_node != 0; item_hash_node = sfghash_findnext( sfthd_hash ) ) { /* Check for any Permanent sig_id objects for this gen_id */ sfthd_item = (THD_ITEM*)item_hash_node->data; if (sfthd_item->policyId != policyId) { continue; } for( sfthd_node = (THD_NODE*)sflist_first(sfthd_item->sfthd_node_list); sfthd_node != 0; sfthd_node = (THD_NODE*)sflist_next(sfthd_item->sfthd_node_list) ) { if (print_thd_node(sfthd_node, type, prnMode) != 0) lcnt++; } } } } if( !lcnt && !*prnMode ) LogMessage("| none\n"); return 0; } /* * Startup/Shutdown Display Of Thresholding */ void print_thresholding(ThresholdConfig *thd_config, unsigned shutdown) { int i; THD_NODE * thd; if (thd_config == NULL) return; if ( !shutdown ) { LogMessage("\n"); LogMessage("+-----------------------[event-filter-config]----------------------------------\n"); LogMessage("| memory-cap : %d bytes\n",thd_config->memcap); LogMessage("+-----------------------[event-filter-global]----------------------------------\n"); } if (thd_config->thd_objs == NULL) { if ( !shutdown ) LogMessage("| none\n"); } else { tSfPolicyId policyId; int gcnt=0; for (policyId = 0; policyId < thd_config->thd_objs->numPoliciesAllocated; policyId++) { if (thd_config->thd_objs->sfthd_garray[policyId] == NULL) { continue; } for(i=0;ithd_objs->sfthd_garray[policyId][i]; if( !thd ) continue; gcnt++; } if( !gcnt ) { if ( !shutdown ) LogMessage("| none\n"); } /* display gen_id=global and sig_id=global rules */ if( gcnt ) { for(i=0;ithd_objs->sfthd_garray[policyId][i]; if( !thd ) continue; if( thd->gen_id == 0 && thd->sig_id == 0 ) { print_thd_node( thd, PRINT_GLOBAL, &shutdown ); break; } } } /* display gen_id!=global and sig_id=global rules */ if( gcnt ) { for(i=0;ithd_objs->sfthd_garray[policyId][i]; if( !thd ) continue; if( thd->gen_id !=0 || thd->sig_id != 0 ) { print_thd_node( thd, PRINT_GLOBAL, &shutdown ); } } } } } if ( !shutdown ) LogMessage("+-----------------------[event-filter-local]-----------------------------------\n"); if (thd_config->thd_objs == NULL) { if ( !shutdown ) LogMessage("| none\n"); } else { print_thd_local(thd_config->thd_objs, PRINT_LOCAL, &shutdown); } if ( !shutdown ) LogMessage("+-----------------------[suppression]------------------------------------------\n"); if (thd_config->thd_objs == NULL) { if ( !shutdown ) LogMessage("| none\n"); } else { print_thd_local(thd_config->thd_objs, PRINT_SUPPRESS, &shutdown); } if ( !shutdown ) LogMessage("--------------------------------------------" "-----------------------------------\n"); } void sfthreshold_free(void) { if (thd_runtime != NULL) sfthd_free(thd_runtime); thd_runtime = NULL; } /* Create and Add a Thresholding Event Object */ int sfthreshold_create(struct _SnortConfig *sc, ThresholdConfig *thd_config, THDX_STRUCT *thdx) { if (thd_config == NULL) return -1; if (!thd_config->enabled) return 0; /* Auto init - memcap must be set 1st, which is not really a problem */ if (thd_runtime == NULL) { thd_runtime = sfthd_new(thd_config->memcap, thd_config->memcap); if (thd_runtime == NULL) return -1; } /* print_thdx( thdx ); */ /* Add the object to the table - */ return sfthd_create_threshold(sc, thd_config->thd_objs, thdx->gen_id, thdx->sig_id, thdx->tracking, thdx->type, thdx->priority, thdx->count, thdx->seconds, thdx->ip_address); } /* Test an event against the threshold object table to determine if it should be logged. It will always return the same answer until sfthreshold_reset is called gen_id: sig_id: sip: host ordered sip dip: host ordered dip curtime: 2003-05-29 cmg: This code is in use in fpLogEvent, CallAlertFuncs, CallLogFuncs and the reset function is called in ProcessPacket returns 0 - log !0 - don't log */ int sfthreshold_test( unsigned gen_id, unsigned sig_id, sfaddr_t* sip, sfaddr_t* dip, long curtime ) { if ((snort_conf->threshold_config == NULL) || !snort_conf->threshold_config->enabled) { return 0; } if (!thd_checked) { thd_checked = 1; thd_answer = sfthd_test_threshold(snort_conf->threshold_config->thd_objs, thd_runtime, gen_id, sig_id, sip, dip, curtime); } return thd_answer; } /** * Reset the thresholding system so that subsequent calls to * sfthreshold_test will indeed try to alter the thresholding system * */ void sfthreshold_reset(void) { thd_checked = 0; } /* empty out active entries */ void sfthreshold_reset_active(void) { if (thd_runtime == NULL) return; if (thd_runtime->ip_nodes != NULL) sfxhash_make_empty(thd_runtime->ip_nodes); if (thd_runtime->ip_gnodes != NULL) sfxhash_make_empty(thd_runtime->ip_gnodes); } snort-2.9.15.1/src/sfthreshold.h0000644000175200017520000000322713571422607013341 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2003-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #ifndef SF_THRESHOLD #define SF_THRESHOLD #include "sfthd.h" #include "ipv6_port.h" typedef struct _ThresholdConfig { int memcap; int enabled; ThresholdObjects *thd_objs; } ThresholdConfig; ThresholdConfig * ThresholdConfigNew(void); void ThresholdConfigFree(ThresholdConfig *); void sfthreshold_reset(void); int sfthreshold_create(struct _SnortConfig *, ThresholdConfig *, THDX_STRUCT *); int sfthreshold_test(unsigned int, unsigned int, sfaddr_t*, sfaddr_t*, long curtime); void print_thresholding(ThresholdConfig*, unsigned shutdown); void sfthreshold_reset_active(void); void sfthreshold_free(void); #endif snort-2.9.15.1/src/packet_time.c0000644000175200017520000000331013571422607013265 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 1998-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** * @file packet_time.c * @author Chris Green * @date Tue Jun 17 17:09:59 2003 * * @brief Easily allow modules to have a gettimeofday() based on packet time * * In many modules in snort, especially the rate detectors need to * work based off time values. It's very hard to reproduce time * constraints via pcap readbacks so we either have to throttle snort * or use the packet time. I choose the latter. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "packet_time.h" static struct timeval s_recent_packet = { 0, 0 }; void packet_time_update(const struct timeval *cur_tv) { s_recent_packet = *cur_tv; } time_t packet_time(void) { return s_recent_packet.tv_sec; } void packet_gettimeofday(struct timeval *tv) { *tv = s_recent_packet; } snort-2.9.15.1/src/packet_time.h0000644000175200017520000000251413571422607013277 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2003-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #ifndef _PACKET_TIME_H #define _PACKET_TIME_H #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifndef WIN32 #include #endif void packet_time_update(const struct timeval *cur_tv); time_t packet_time(void); void packet_gettimeofday(struct timeval *tv); #endif /* _PACKET_TIME_H */ snort-2.9.15.1/src/event_wrapper.c0000644000175200017520000001604513571422607013672 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 1998-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** * @file event_wrapper.c * @author Chris Green * * @date Wed Jun 18 10:49:59 2003 * * @brief generate a snort event * * This is a wrapper around SetEvent,CallLogFuncs,CallEventFuncs * * Notes: * * 10/31/05 - Marc Norton * Changes to support every event being controlled via a rule. * Modified GenerateSnortEvent() to re-route events to 'fpLogEvent' * if a suitable otn was found. If no otn was found, than we do * not log the event at all, as no rule was provided. * Preprocessors are configured independently, and may detect * an event, but the rule controls the alert/drop functionality. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sf_types.h" #include "rules.h" #include "treenodes.h" #include "signature.h" #include "util.h" #include "event_wrapper.h" #include "fpdetect.h" #include "snort_debug.h" #include "sfPolicy.h" RuleTreeNode* GenerateSnortEventRtn (OptTreeNode* otn, tSfPolicyId policyId) { RuleTreeNode *rtn = getRtnFromOtn(otn, policyId); if (!rtn) { rtn = calloc(1, sizeof(RuleTreeNode)); if (rtn) { rtn->type = RULE_TYPE__ALERT; if (addRtnToOtn(NULL, otn, policyId, rtn) != 0) rtn = NULL; } } return rtn; } OptTreeNode * GenerateSnortEventOtn( uint32_t gen_id, uint32_t sig_id, uint32_t sig_rev, uint32_t classification, uint32_t priority, const char *msg ) { OptTreeNode *otn; RuleTreeNode *rtn; otn = otnCreate(gen_id, sig_id, sig_rev, classification, priority, msg); if (otn) { rtn = GenerateSnortEventRtn(otn, getIpsRuntimePolicy()); if (!rtn) { free(otn); return NULL; } } DEBUG_WRAP( LogMessage("Generating OTN for GID: %u, SID: %u\n",gen_id,sig_id);); return otn; } /* * This function returns the rule action given the * details about the rule */ int GetSnortEventAction(uint32_t gid, uint32_t sid, uint32_t rev, uint32_t classification, uint32_t priority, const char *msg) { OptTreeNode *otn; RuleTreeNode *rtn; if (msg == NULL) return 0; otn = GetApplicableOtn(gid, sid, rev, classification, priority, msg); if (otn == NULL) return 0; rtn = getRuntimeRtnFromOtn(otn); if (rtn == NULL) return 0; return (rtn->type); } /* * This function has been updated to find an otn and route the call to fpLogEvent * if possible. This requires a rule be written for each decoder event, * and possibly some preporcessor events. The bulk of eventing is handled vie the * SnortEventqAdd() and SnortEventLog() functions - whichalready route the events to * the fpLogEvent()function. */ uint32_t GenerateSnortEvent( Packet *p, uint32_t gid, uint32_t sid, uint32_t rev, uint32_t classification, uint32_t priority, const char * msg ) { OptTreeNode *otn; RuleTreeNode *rtn; if (msg == NULL) return 0; otn = GetApplicableOtn(gid, sid, rev, classification, priority, msg); if (otn == NULL) return 0; rtn = getRuntimeRtnFromOtn(otn); if (rtn == NULL) return 0; LogSnortEvent(p, otn, rtn, msg); return otn->event_data.event_id; } /** * Log additional packet data using the same kinda mechanism tagging does. * * @param p Packet to log * @param gen_id generator id * @param sig_id signature id * @param sig_rev revision is * @param classification classification id * @param priority priority level * @param event_ref reference of a previous event * @param ref_sec the tv_sec of that previous event * @param msg The message data txt * * @return 1 on success, 0 on FAILURE ( note this is to stay the same as GenerateSnortEvent() ) */ int LogTagData( Packet * p, uint32_t gen_id, uint32_t sig_id, uint32_t sig_rev, uint32_t classification, uint32_t priority, uint32_t event_ref, time_t ref_sec, char * msg ) { Event event; if(!event_ref || !ref_sec) return 0; #if !defined(FEAT_OPEN_APPID) SetEvent(&event, gen_id, sig_id, sig_rev, classification, priority, event_ref); #else /* defined(FEAT_OPEN_APPID) */ SetEvent(&event, gen_id, sig_id, sig_rev, classification, priority, event_ref, NULL); #endif /* defined(FEAT_OPEN_APPID) */ event.ref_time.tv_sec = (uint32_t)ref_sec; if(p) CallLogFuncs(p, msg, NULL, &event); return 1; } void LogSnortEvent( Packet * p, OptTreeNode * otn, RuleTreeNode * rtn, const char * event_msg ) { if (IsPreprocDecoderRule(otn->sigInfo.rule_type)) { // If it's a preprocessor or decoder rule, the message we want to // use is the one that was passed in, not what is in the message of // the OTN, which will be generic if the rule was not autogenerated // and potentially wrong if it was. const char *tmp = otn->sigInfo.message; otn->sigInfo.message = event_msg; fpLogEvent(rtn, otn, p); otn->sigInfo.message = tmp; } else { fpLogEvent(rtn, otn, p); } } OptTreeNode *otnCreate(uint32_t gid, uint32_t sid, uint32_t rev, uint32_t classification, uint32_t priority, const char *msg) { OptTreeNode *otn = calloc(1, sizeof(OptTreeNode)); if (otn) { otn->sigInfo.generator = gid; otn->sigInfo.id = sid; otn->sigInfo.rev = rev; otn->sigInfo.message = msg; otn->sigInfo.priority = priority; otn->sigInfo.class_id = classification; otn->generated = 1; otn->sigInfo.rule_type=SI_RULE_TYPE_PREPROC; /* TODO: could be detect ... */ otn->sigInfo.rule_flushing=SI_RULE_FLUSHING_OFF; /* only standard rules do this */ otn->event_data.sig_generator = gid; otn->event_data.sig_id = sid; otn->event_data.sig_rev = rev; otn->event_data.classification = classification; otn->event_data.priority = priority; } return otn; } snort-2.9.15.1/src/event_wrapper.h0000644000175200017520000000527613571422607013703 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2003-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #ifndef _EVENT_WRAPPER_H #define _EVENT_WRAPPER_H #include "log.h" #include "detect.h" #include "decode.h" #include "rules.h" #include "treenodes.h" #include "generators.h" /* * this has been upgarded to reroute traffic to fpLogEvent() * to add support for thresholding, and other rule behaviors * like drop,alert. This has been updated to allow decoder events * which call it to be filtered through fpLogEvent. This of course * requires a rule be writen for each decoder event, and preprocssor event, * although preprocessors don't seem to use this much. */ uint32_t GenerateSnortEvent( Packet * p, uint32_t gen_id, uint32_t sig_id, uint32_t sig_rev, uint32_t classification, uint32_t priority, const char * msg ); OptTreeNode * GenerateSnortEventOtn( uint32_t gen_id, uint32_t sig_id, uint32_t sig_rev, uint32_t classification, uint32_t priority, const char * msg ); RuleTreeNode* GenerateSnortEventRtn(OptTreeNode *, tSfPolicyId); int GetSnortEventAction(uint32_t gid, uint32_t sid, uint32_t rev, uint32_t classification, uint32_t priority, const char *msg); int LogTagData( Packet * p, uint32_t gen_id, uint32_t sig_id, uint32_t sig_rev, uint32_t classification, uint32_t priority, uint32_t event_ref, time_t ref_sec, char * msg ); void LogSnortEvent(Packet *, OptTreeNode *, RuleTreeNode *, const char *); /* Utility functions */ OptTreeNode *otnCreate( uint32_t gid, uint32_t sid, uint32_t rev, uint32_t classification, uint32_t priority, const char *msg ); #endif /* _EVENT_WRAPPER_H */ snort-2.9.15.1/src/event_queue.c0000644000175200017520000001625313571422607013337 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2004-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** ** @file event_queue.c ** ** @author Daniel Roelker ** @author Marc Norton ** ** @brief Snort wrapper to sfeventq library. ** ** These functions wrap the sfeventq API and provide the priority ** functions for ordering incoming events. ** ** Notes: ** 11/1/05 Updates to add support for rules for all events in ** decoders and preprocessors and the detection engine. ** Added support for rule by rule flushing control via ** metadata. Also added code to check fo an otn for every ** event (gid,sid pair). This is now required to get events ** to be logged. The decoders and preprocessors are still ** configured independently, which allows them to inspect and ** call the alerting functions SnortEventqAdd, GenerateSnortEvent() ** and GenerateEvent2() for sfportscan.c. The GenerateSnortEvent() ** function now finds and otn and calls fpLogEvent. ** ** Any event that has no otn associated with it's gid,sid pair, ** will/should not alert, even if the preprocessor or decoiderr is ** configured to detect an alertable event. ** ** In the future, preporcessor may have an api that gets called ** after rules are loaded that checks for the gid/sid -> otn ** mapping, and then adjusts it's inspection or detection ** accordingly. ** ** SnortEventqAdd() - only adds events that have an otn ** */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sf_types.h" #include "fpcreate.h" #include "fpdetect.h" #include "util.h" #include "sfeventq.h" #include "event_wrapper.h" #include "event_queue.h" #include "sfthreshold.h" #include "sfPolicy.h" #include "sfPolicyData.h" //------------------------------------------------- // the push/pop methods ensure that qIndex stays in // bounds and that it is only popped after it was // successfully pushed. static unsigned qIndex = 0; static unsigned qOverflow = 0; static unsigned s_events = 0; // inline functions /* Get the event queue at the top of the stack */ static inline SF_EVENTQ *getEventQueue(void) { return snort_conf->event_queue[qIndex]; } // API functions void SnortEventqPush(void) { if ( qIndex < NUM_EVENT_QUEUES-1 ) qIndex++; else qOverflow++; } void SnortEventqPop(void) { if ( qOverflow > 0 ) qOverflow--; else if ( qIndex > 0 ) qIndex--; } //------------------------------------------------- /* ** Set default values */ EventQueueConfig * EventQueueConfigNew(void) { EventQueueConfig *eq = (EventQueueConfig *)SnortAlloc(sizeof(EventQueueConfig)); eq->max_events = 8; eq->log_events = 3; eq->order = SNORT_EVENTQ_CONTENT_LEN; eq->process_all_events = 0; return eq; } void EventQueueConfigFree(EventQueueConfig *eq) { if (eq == NULL) return; free(eq); } int SnortEventqAdd( uint32_t gid, uint32_t sid, uint32_t rev, uint32_t classification, uint32_t priority, const char * msg, void * rule_info ) { EventNode *en; OptTreeNode *otn = (OptTreeNode *) rule_info; if (!otn) otn = GetApplicableOtn(gid, sid, rev, classification, priority, msg); else if (!getRtnFromOtn(otn, getApplicableRuntimePolicy(gid))) otn = NULL; if (otn) { en = (EventNode *) sfeventq_event_alloc(getEventQueue()); if (!en) return -1; en->gid = gid; en->sid = sid; en->rev = rev; en->classification = classification; en->priority = priority; en->msg = msg; en->rule_info = rule_info; if (sfeventq_add(getEventQueue(), (void *) en) != 0) return -1; s_events++; } return 0; } void SnortEventqNew( EventQueueConfig *eq_config, SF_EVENTQ *eq[] ) { int i; for ( i = 0; i < NUM_EVENT_QUEUES; i++ ) { eq[i] = sfeventq_new(eq_config->max_events, eq_config->log_events, sizeof(EventNode)); if (eq[i] == NULL) FatalError("Failed to initialize Snort event queue.\n"); } } void SnortEventqFree(SF_EVENTQ *eq[]) { int i; for ( i = 0; i < NUM_EVENT_QUEUES; i++ ) sfeventq_free(eq[i]); } static int LogSnortEvents(void * event, void * user) { EventNode *en = (EventNode *) event; SNORT_EVENTQ_USER *snort_user = (SNORT_EVENTQ_USER *) user; OptTreeNode *otn; RuleTreeNode *rtn = NULL; if (!event || !user) return 0; if (s_events > 0) s_events--; if (en->rule_info) { otn = en->rule_info; } else { // The above en->rule_info may be NULL to avoid performing an OTN/RTN // lookup until after policy switching is finalized. In that case, // perform the lookup here. otn = GetApplicableOtn( en->gid, en->sid, en->rev, en->classification, en->priority, en->msg ); } if (otn) { rtn = getRtnFromOtn(otn, getApplicableRuntimePolicy(en->gid)); if (rtn) { snort_user->rule_alert = otn->sigInfo.rule_flushing; LogSnortEvent((Packet *) snort_user->pkt, otn, rtn, en->msg); } } sfthreshold_reset(); return 0; } /* ** NAME ** SnortEventqLog:: */ /** ** We return whether we logged events or not. We've add a eventq user ** structure so we can track whether the events logged were rule events ** or preprocessor/decoder events. The reason being that we don't want ** to flush a TCP stream for preprocessor/decoder events, and cause ** early flushing of the stream. ** ** @return 1 logged events ** @return 0 did not log events or logged only decoder/preprocessor events */ int SnortEventqLog(SF_EVENTQ *eq[], Packet *p) { static SNORT_EVENTQ_USER user; user.rule_alert = 0x00; user.pkt = (void *)p; if (sfeventq_action(eq[qIndex], LogSnortEvents, (void *)&user) > 0) { if (user.rule_alert) return 1; } return 0; } static inline void reset_counts (void) { pc.log_limit += s_events; s_events = 0; } void SnortEventqResetCounts (void) { reset_counts(); } void SnortEventqReset(void) { sfeventq_reset(getEventQueue()); reset_counts(); } snort-2.9.15.1/src/event_queue.h0000644000175200017520000000423513571422607013341 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2004-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #ifndef __EVENT_QUEUE_H__ #define __EVENT_QUEUE_H__ #include "decode.h" #include "sfutil/sfeventq.h" #include "treenodes.h" #define SNORT_EVENTQ_PRIORITY 1 #define SNORT_EVENTQ_CONTENT_LEN 2 struct _OptTreeNode; typedef struct _EventQueueConfig { int max_events; int log_events; int order; int process_all_events; } EventQueueConfig; typedef struct s_SNORT_EVENTQ_USER { char rule_alert; void *pkt; } SNORT_EVENTQ_USER; typedef struct _EventNode { unsigned int gid; unsigned int sid; unsigned int rev; unsigned int classification; unsigned int priority; const char *msg; OptTreeNode *rule_info; } EventNode; EventQueueConfig * EventQueueConfigNew(void); void EventQueueConfigFree(EventQueueConfig *); void SnortEventqNew(EventQueueConfig *, SF_EVENTQ*[]); void SnortEventqFree(SF_EVENTQ *[]); void SnortEventqReset(void); void SnortEventqResetCounts(void); int SnortEventqLog(SF_EVENTQ *[], Packet *); int SnortEventqAdd(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, const char *, void *); void SnortEventqPush(void); void SnortEventqPop(void); #endif snort-2.9.15.1/src/ipv6_port.h0000644000175200017520000001072713571422607012747 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2007-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef IPV6_PORT_H #define IPV6_PORT_H #include "snort_debug.h" /*****************/ /* IPv6 and IPv4 */ #include "sf_ip.h" #define IpAddrNode sfip_node_t #define IpAddrSet sfip_var_t #define IpAddrSetContains(x,y) sfvar_ip_in(x, y) #define IpAddrSetPrint sfvar_print #ifdef inet_ntoa #undef inet_ntoa #endif #define inet_ntoa sfip_ntoa #define GET_SRC_IP(p) ((p)->iph_api->iph_ret_src(p)) #define GET_DST_IP(p) ((p)->iph_api->iph_ret_dst(p)) #define GET_ORIG_SRC(p) ((p)->orig_iph_api->orig_iph_ret_src(p)) #define GET_ORIG_DST(p) ((p)->orig_iph_api->orig_iph_ret_dst(p)) /* These are here for backwards compatibility */ #define GET_SRC_ADDR(x) GET_SRC_IP(x) #define GET_DST_ADDR(x) GET_DST_IP(x) #define IP_EQUALITY(x,y) (sfip_compare((x),(y)) == SFIP_EQUAL) #define IP_EQUALITY_UNSET(x,y) (sfip_compare_unset((x),(y)) == SFIP_EQUAL) #define IP_LESSER(x,y) (sfip_compare((x),(y)) == SFIP_LESSER) #define IP_GREATER(x,y) (sfip_compare((x),(y)) == SFIP_GREATER) #define IS_IP4(x) ((x)->family == AF_INET) #define IS_IP6(x) ((x)->family == AF_INET6) #define IS_OUTER_IP4(x) ((x)->outer_family == AF_INET) #define IS_OUTER_IP6(x) ((x)->outer_family == AF_INET6) #define GET_IPH_TOS(p) (p)->iph_api->iph_ret_tos(p) #define GET_IPH_LEN(p) (p)->iph_api->iph_ret_len(p) #define GET_IPH_TTL(p) (p)->iph_api->iph_ret_ttl(p) #define GET_IPH_ID(p) (p)->iph_api->iph_ret_id(p) #define GET_IPH_OFF(p) (p)->iph_api->iph_ret_off(p) #define GET_IPH_VER(p) (p)->iph_api->iph_ret_ver(p) #define GET_IPH_PROTO(p) ((uint8_t)(IS_IP6(p) ? ((p)->ip6h->next) : ((p)->iph_api->iph_ret_proto(p)))) #define GET_ORIG_IPH_PROTO(p) (p)->orig_iph_api->orig_iph_ret_proto(p) #define GET_ORIG_IPH_VER(p) (p)->orig_iph_api->orig_iph_ret_ver(p) #define GET_ORIG_IPH_LEN(p) (p)->orig_iph_api->orig_iph_ret_len(p) #define GET_ORIG_IPH_OFF(p) (p)->orig_iph_api->orig_iph_ret_off(p) /* XXX make sure these aren't getting confused with sfip_is_valid within the code */ #define IPH_IS_VALID(p) iph_is_valid(p) #define IP_CLEAR(x) (x).family = (x).ia32[0] = (x).ia32[1] = (x).ia32[2] = (x).ia32[3] = 0; #define IP_IS_SET(x) sfip_is_set(&x) /* This loop trickery is intentional. If each copy is performed * individually on each field, then the following expression gets broken: * * if(conditional) IP_COPY_VALUE(a,b); * * If the macro is instead enclosed in braces, then having a semicolon * trailing the macro causes compile breakage. * So: use loop. */ #define IP_COPY_VALUE(dst, src) sfip_set_ip(&(dst), src) #define GET_IPH_HLEN(p) ((p)->iph_api->iph_ret_hlen(p)) #define SET_IPH_HLEN(p, val) #define GET_IP_DGMLEN(p) IS_IP6(p) ? (ntohs(GET_IPH_LEN(p)) + (GET_IPH_HLEN(p) << 2)) : ntohs(GET_IPH_LEN(p)) #define GET_IP_PAYLEN(p) IS_IP6(p) ? ntohs(GET_IPH_LEN(p)) : (ntohs(GET_IPH_LEN(p)) - (GET_IPH_HLEN(p) << 2)) #define IP_ARG(ipt) (&ipt) #define IP_PTR(ipp) (ipp) #define IP_VAL(ipt) (*ipt) #define GET_INNER_SRC_IP(p) (IS_IP6(p) ? (&((p)->inner_ip6h.ip_addrs->ip_src)):(&((p)->inner_ip4h.ip_addrs->ip_src))) #define GET_INNER_DST_IP(p) (IS_IP6(p) ? (&((p)->inner_ip6h.ip_addrs->ip_dst)):(&((p)->inner_ip4h.ip_addrs->ip_dst))) #define GET_OUTER_SRC_IP(p) (IS_OUTER_IP6(p) ? (&((p)->outer_ip6h.ip_addrs->ip_src)):(&((p)->outer_ip4h.ip_addrs->ip_src))) #define GET_OUTER_DST_IP(p) (IS_OUTER_IP6(p) ? (&((p)->outer_ip6h.ip_addrs->ip_dst)):(&((p)->outer_ip4h.ip_addrs->ip_dst))) #if 0 static inline int sfip_equal (sfaddr_t* ip1, sfaddr_t* ip2) { return _ip6_cmp(ip1, ip2) == SFIP_EQUAL; } #endif #if !defined(IPPROTO_IPIP) && defined(WIN32) /* Needed for some Win32 */ #define IPPROTO_IPIP 4 #endif #endif /* IPV6_PORT_H */ snort-2.9.15.1/src/ppm.c0000644000175200017520000004755513571422607011617 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2006-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* ** $Id$ ** ** ppm.c ** ** Packet Performance Monitor ** ** Author: Marc Norton ** Date: 10/2006 ** ** Usage: * * config ppm: max-pkt-time usecs * config ppm: max-rule-time usecs * config ppm: max-suspend-time secs * config ppm: threshold count * config ppm: suspend-expensive-rules * config ppm: fastpath-expensive-packets * config ppm: pkt-events syslog|console * config ppm: rule-events alert|syslog|console * config ppm: debug-rules * config ppm: debug-pkts * */ #include #include #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "snort.h" #include "rules.h" #include "treenodes.h" #include "treenodes.h" #include "decode.h" #include "parser.h" #include "plugin_enum.h" #include "util.h" #include "rules.h" #include "treenodes.h" #include "treenodes.h" #include "fpcreate.h" #include "event_queue.h" #include "event_wrapper.h" #include "log.h" #include "ppm.h" #include "sf_types.h" #include "generators.h" #ifdef PPM_MGR #define PPM_BASE_SUSPEND_RULE_GID 1000 #define PPM_BASE_CLEAR_RULE_GID 2000 #define PPM_DEFAULT_MAX_PKT_TICKS 0 #define PPM_DEFAULT_MAX_RULE_TICKS 0 #define PPM_DEFAULT_MAX_SUSP_SECS 60 #define PPM_DEFAULT_RULE_THRESHOLD 5 PPM_TICKS ppm_tpu = 0; /* ticks per usec */ ppm_pkt_timer_t ppm_pkt_times[PPM_MAX_TIMERS]; ppm_pkt_timer_t *ppm_pt = NULL; unsigned int ppm_pkt_index = 0; ppm_rule_timer_t ppm_rule_times[PPM_MAX_TIMERS]; ppm_rule_timer_t *ppm_rt = NULL; unsigned int ppm_rule_times_index = 0; uint64_t ppm_cur_time = 0; /* temporary flags */ int ppm_abort_this_pkt = 0; int ppm_suspend_this_rule = 0; /* debug-pkts data */ #define MAX_DP_NRULES 1000 typedef struct { uint64_t pkt; detection_option_tree_root_t * tree; PPM_TICKS ticks; } ppm_rules_t; /* suspended rules */ static ppm_rules_t ppm_rules[MAX_DP_NRULES]; static int ppm_n_rules; /* cleared rules - re-enabled */ static detection_option_tree_root_t * ppm_crules[MAX_DP_NRULES]; static int ppm_n_crules; void ppm_init_rules(void) { ppm_n_rules = 0; ppm_n_crules = 0; } void ppm_set_rule(detection_option_tree_root_t * root,PPM_TICKS ticks) { if( ppm_n_rules < MAX_DP_NRULES ) { ppm_rules[ppm_n_rules].tree=root; ppm_rules[ppm_n_rules].ticks=ticks; ppm_n_rules++; } } void ppm_clear_rule(detection_option_tree_root_t *root) { if( ppm_n_crules < MAX_DP_NRULES ) { ppm_crules[ppm_n_crules++]=root; } } /* * calc ticks per micro-secs in integer units */ static int ppm_calc_ticks(void) { ppm_tpu = (PPM_TICKS)get_ticks_per_usec(); if( ppm_tpu == 0 ) { return -1; } return 0; } void ppm_print_cfg(ppm_cfg_t *ppm_cfg) { if (ppm_cfg == NULL) return; if (!ppm_cfg->enabled) return ; if( ppm_cfg->max_pkt_ticks ) { LogMessage("\n"); LogMessage("Packet Performance Monitor Config:\n"); LogMessage(" ticks per usec : %lu ticks\n",(unsigned long)ppm_tpu); LogMessage(" max packet time : %lu usecs\n",(unsigned long)(ppm_cfg->max_pkt_ticks/ppm_tpu)); LogMessage(" packet action : "); if( ppm_cfg->pkt_action ) LogMessage("fastpath-expensive-packets\n"); else LogMessage("none\n"); LogMessage(" packet logging : "); if(ppm_cfg->pkt_log&PPM_LOG_ALERT) LogMessage("alert " ); if(ppm_cfg->pkt_log&PPM_LOG_MESSAGE) LogMessage("log "); if(!ppm_cfg->pkt_log) LogMessage("none "); LogMessage("\n"); #ifdef DEBUG LogMessage(" debug-pkts : %s\n",(ppm_cfg->debug_pkts)? "enabled":"disabled"); #endif } if( ppm_cfg->max_rule_ticks) { LogMessage("\n"); LogMessage("Rule Performance Monitor Config:\n"); LogMessage(" ticks per usec : %lu ticks\n",(unsigned long)ppm_tpu); LogMessage(" max rule time : %lu usecs\n",(unsigned long)(ppm_cfg->max_rule_ticks/ppm_tpu)); LogMessage(" rule action : "); if( ppm_cfg->rule_action ) { LogMessage("suspend-expensive-rules\n"); LogMessage(" rule threshold : %u \n",(unsigned int)ppm_cfg->rule_threshold); } else LogMessage("none\n"); #ifdef PPM_TEST /* use usecs instead of ticks for rule suspension during pcap playback */ LogMessage(" suspend timeout : %lu secs\n", (unsigned long)(ppm_cfg->max_suspend_ticks/((uint64_t)1000000)) ); #else LogMessage(" suspend timeout : %lu secs\n", (unsigned long)(ppm_cfg->max_suspend_ticks/((uint64_t)ppm_tpu*1000000)) ); #endif LogMessage(" rule logging : "); if(ppm_cfg->rule_log&PPM_LOG_ALERT) LogMessage("alert " ); if(ppm_cfg->rule_log&PPM_LOG_MESSAGE) LogMessage("log "); if(!ppm_cfg->rule_log) LogMessage("none "); LogMessage("\n"); #ifdef DEBUG /*LogMessage(" debug-rules : %s\n",(ppm_cfg->debug_rules)?"enabled":"disabled"); unsupported */ #endif } } static int print_rule( int proto, RuleTreeNode * r, OptTreeNode * o ) { if( o->rule_state != RULE_STATE_ENABLED ) { //if( o->sigInfo.generator==1 || o->sigInfo.generator==3 ) LogMessage(" disabled gid=%u, sid=%u\n",o->sigInfo.generator,o->sigInfo.id); } return 0; } void ppm_print_summary(ppm_cfg_t *ppm_cfg) { if (ppm_cfg == NULL) return; if (!ppm_cfg->enabled) return; LogMessage("===============================================================================\n"); if(ppm_cfg->max_pkt_ticks) { LogMessage("Packet Performance Summary:\n"); LogMessage(" max packet time : %g usecs\n", ppm_ticks_to_usecs(ppm_cfg->max_pkt_ticks)); LogMessage(" packet events : %u\n", (unsigned int)ppm_cfg->pkt_event_cnt); if( ppm_cfg->tot_pkts ) LogMessage(" avg pkt time : %g usecs\n", ppm_ticks_to_usecs((PPM_TICKS)(ppm_cfg->tot_pkt_time/ ppm_cfg->tot_pkts))); } if(ppm_cfg->max_rule_ticks) { LogMessage("Rule Performance Summary:\n"); LogMessage(" max rule time : %lu usecs\n", (unsigned long)(ppm_cfg->max_rule_ticks/ppm_tpu)); LogMessage(" rule events : %u\n", (unsigned int)ppm_cfg->rule_event_cnt); if( ppm_cfg->tot_rules ) LogMessage(" avg rule time : %g usecs\n", ppm_ticks_to_usecs((PPM_TICKS)(ppm_cfg->tot_rule_time/ ppm_cfg->tot_rules))); if( ppm_cfg->tot_nc_rules ) LogMessage(" avg nc-rule time : %g usecs\n", ppm_ticks_to_usecs((PPM_TICKS)(ppm_cfg->tot_nc_rule_time/ ppm_cfg->tot_nc_rules))); if( ppm_cfg->tot_pcre_rules ) LogMessage(" avg nc-pcre-rule time : %g usecs\n", ppm_ticks_to_usecs((PPM_TICKS)(ppm_cfg->tot_pcre_rule_time/ ppm_cfg->tot_pcre_rules))); fpWalkOtns( 0, print_rule ); } } double ppm_ticks_to_usecs(PPM_TICKS ticks) { if (ppm_tpu > 0) return (double)ticks / ppm_tpu; return 0.0; } /* * Initialization */ void ppm_init(ppm_cfg_t *ppm_cfg) { /* calc ticks per usec */ if (ppm_calc_ticks() == -1) return; ppm_cfg->enabled = 1; ppm_cfg->max_pkt_ticks = PPM_DEFAULT_MAX_PKT_TICKS; ppm_cfg->max_rule_ticks = PPM_DEFAULT_MAX_RULE_TICKS; /* use usecs instead of ticks for rule suspension during pcap playback */ ppm_cfg->max_suspend_ticks = (uint64_t)PPM_DEFAULT_MAX_SUSP_SECS * 1000000; #ifndef PPM_TEST ppm_cfg->max_suspend_ticks *= ppm_tpu; #endif ppm_cfg->rule_threshold = PPM_DEFAULT_RULE_THRESHOLD; } /* * Logging functions - syslog and/or events */ #define PPM_FMT_FASTPATH "PPM: Pkt-Event Pkt[" STDi64 "] used=%g usecs, %u rules, %u nc-rules tested, packet fastpathed (%s:%d -> %s:%d).\n" #define PPM_FMT_PACKET "PPM: Pkt-Event Pkt[" STDi64 "] used=%g usecs, %u rules, %u nc-rules tested (%s:%d -> %s:%d).\n" void ppm_pkt_log(ppm_cfg_t *ppm_cfg, Packet* p) { int filterEvent = 0; if (!ppm_cfg->max_pkt_ticks) return; ppm_cfg->pkt_event_cnt++; if (ppm_cfg->pkt_log & PPM_LOG_ALERT) { OptTreeNode* potn; Event ev; /* make sure we have an otn already in our table for this event */ potn = OtnLookup(snort_conf->otn_map, GENERATOR_PPM, PPM_EVENT_PACKET_ABORTED); if (potn == NULL) { /* have to make one */ potn = GenerateSnortEventOtn(GENERATOR_PPM, /* GID */ PPM_EVENT_PACKET_ABORTED, /* SID */ 1, /* Rev */ 0, /* classification */ 3, /* priority (low) */ PPM_EVENT_PACKET_ABORTED_STR /* msg string */); if (potn == NULL) return; OtnLookupAdd(snort_conf->otn_map, potn); } SetEvent(&ev, potn->sigInfo.generator, /* GID */ potn->sigInfo.id, /* SID */ potn->sigInfo.rev, /* Rev */ potn->sigInfo.class_id, /* classification */ potn->sigInfo.priority, /* priority (low) */ #if !defined(FEAT_OPEN_APPID) 0); #else /* defined(FEAT_OPEN_APPID) */ 0, NULL); #endif /* defined(FEAT_OPEN_APPID) */ if ( IPH_IS_VALID(p) ) { filterEvent = sfthreshold_test( potn->event_data.sig_generator, potn->event_data.sig_id, GET_SRC_IP(p), GET_DST_IP(p), p->pkth->ts.tv_sec); } else { sfaddr_t cleared; IP_CLEAR(cleared); filterEvent = sfthreshold_test( potn->event_data.sig_generator, potn->event_data.sig_id, IP_ARG(cleared), IP_ARG(cleared), p->pkth->ts.tv_sec); } if(filterEvent < 0) filterEvent = 0; else AlertAction(p, potn, NULL, &ev); } if (ppm_cfg->pkt_log & PPM_LOG_MESSAGE) { char src[INET6_ADDRSTRLEN]; char dst[INET6_ADDRSTRLEN]; sfaddr_t* addr = GET_SRC_IP(p); sfip_ntop(addr, src, sizeof(src)); addr = GET_DST_IP(p); sfip_ntop(addr, dst, sizeof(dst)); if (ppm_abort_this_pkt) { LogMessage(PPM_FMT_FASTPATH, ppm_pt->pktcnt, ppm_ticks_to_usecs((PPM_TICKS)ppm_pt->tot), ppm_pt->rule_tests, ppm_pt->nc_rule_tests, src, p->sp, dst, p->dp); } else { LogMessage(PPM_FMT_PACKET, ppm_pt->pktcnt, ppm_ticks_to_usecs((PPM_TICKS)ppm_pt->tot), ppm_pt->rule_tests, ppm_pt->nc_rule_tests, src, p->sp, dst, p->dp); } } } #define PPM_FMT_SUS_PKT "PPM: Rule-Event Pkt[" STDi64 "] suspended (%s:%d -> %s:%d).\n" #define PPM_FMT_SUSPENDED "PPM: Rule-Event Pkt[" STDi64 "] address=0x%p used=%g usecs suspended %s\n" #define PPM_FMT_REENABLED "PPM: Rule-Event Pkt[" STDi64 "] address=0x%p re-enabled %s\n" static inline OptTreeNode * PPMGetOTN(uint32_t sid, const char *msg) { OptTreeNode *otn = OtnLookup(snort_conf->otn_map, GENERATOR_PPM, sid); if (otn == NULL) { otn = GenerateSnortEventOtn(GENERATOR_PPM, sid, 1, 0, 3, msg); if (otn == NULL) return NULL; OtnLookupAdd(snort_conf->otn_map, otn); } else { tSfPolicyId policy_id = getIpsRuntimePolicy(); if ((getRtnFromOtn(otn, policy_id) == NULL) && (GenerateSnortEventRtn(otn, policy_id) == NULL)) return NULL; } return otn; } void ppm_rule_log(ppm_cfg_t *ppm_cfg, uint64_t pktcnt, Packet *p) { detection_option_tree_root_t *proot; OptTreeNode *otn; char timestamp[TIMEBUF_SIZE]; int filterEvent = 0; *timestamp = '\0'; if (!ppm_cfg->max_rule_ticks) return ; if (ppm_n_crules) { if (ppm_cfg->rule_log & PPM_LOG_ALERT) { Event ev; otn = PPMGetOTN(PPM_EVENT_RULE_TREE_ENABLED, PPM_EVENT_RULE_TREE_ENABLED_STR); if (otn != NULL) { const char *tmp = otn->sigInfo.message; SetEvent(&ev, otn->sigInfo.generator, /* GID */ otn->sigInfo.id, /* SID */ otn->sigInfo.rev, /* Rev */ otn->sigInfo.class_id, /* classification */ otn->sigInfo.priority, /* priority (low) */ #if !defined(FEAT_OPEN_APPID) 0); #else /* defined(FEAT_OPEN_APPID) */ 0, NULL); #endif /* defined(FEAT_OPEN_APPID) */ otn->sigInfo.message = PPM_EVENT_RULE_TREE_ENABLED_STR; if ( IPH_IS_VALID(p) ) { filterEvent = sfthreshold_test( otn->event_data.sig_generator, otn->event_data.sig_id, GET_SRC_IP(p), GET_DST_IP(p), p->pkth->ts.tv_sec); } else { sfaddr_t cleared; IP_CLEAR(cleared); filterEvent = sfthreshold_test( otn->event_data.sig_generator, otn->event_data.sig_id, IP_ARG(cleared), IP_ARG(cleared), p->pkth->ts.tv_sec); } if(filterEvent < 0) filterEvent = 0; else AlertAction(p, otn, NULL, &ev); otn->sigInfo.message = tmp; } } if (ppm_cfg->rule_log & PPM_LOG_MESSAGE) { int i; if(!*timestamp) ts_print((struct timeval*)&p->pkth->ts, timestamp); for (i=0; i< ppm_n_crules; i++) { proot = ppm_crules[i]; LogMessage(PPM_FMT_REENABLED, pktcnt, (void*)proot, timestamp); } } ppm_n_crules = 0; } if (ppm_n_rules) { if (ppm_cfg->rule_log & PPM_LOG_ALERT) { Event ev; otn = PPMGetOTN(PPM_EVENT_RULE_TREE_DISABLED, PPM_EVENT_RULE_TREE_DISABLED_STR); if (otn != NULL) { const char *tmp = otn->sigInfo.message; SetEvent(&ev, otn->sigInfo.generator, /* GID */ otn->sigInfo.id, /* SID */ otn->sigInfo.rev, /* Rev */ otn->sigInfo.class_id, /* classification */ otn->sigInfo.priority, /* priority (low) */ #if !defined(FEAT_OPEN_APPID) 0); #else /* defined(FEAT_OPEN_APPID) */ 0, NULL); #endif /* defined(FEAT_OPEN_APPID) */ otn->sigInfo.message = PPM_EVENT_RULE_TREE_DISABLED_STR; if ( IPH_IS_VALID(p) ) { filterEvent = sfthreshold_test( otn->event_data.sig_generator, otn->event_data.sig_id, GET_SRC_IP(p), GET_DST_IP(p), p->pkth->ts.tv_sec); } else { sfaddr_t cleared; IP_CLEAR(cleared); filterEvent = sfthreshold_test( otn->event_data.sig_generator, otn->event_data.sig_id, IP_ARG(cleared), IP_ARG(cleared), p->pkth->ts.tv_sec); } if(filterEvent < 0) filterEvent = 0; else AlertAction(p, otn, NULL, &ev); otn->sigInfo.message = tmp; } } if (ppm_cfg->rule_log & PPM_LOG_MESSAGE) { int i; char src[INET6_ADDRSTRLEN]; char dst[INET6_ADDRSTRLEN]; sfaddr_t* addr = GET_SRC_IP(p); sfip_ntop(addr, src, sizeof(src)); addr = GET_DST_IP(p); sfip_ntop(addr, dst, sizeof(dst)); LogMessage(PPM_FMT_SUS_PKT, pktcnt, src, p->sp, dst, p->dp); if(!*timestamp) ts_print((struct timeval*)&p->pkth->ts, timestamp); for (i=0; i< ppm_n_rules; i++) { proot = ppm_rules[i].tree; LogMessage(PPM_FMT_SUSPENDED, pktcnt, (void*)proot, ppm_ticks_to_usecs((PPM_TICKS)ppm_rules[i].ticks), timestamp); } } ppm_n_rules = 0; } } void ppm_set_rule_event(ppm_cfg_t *ppm_cfg, detection_option_tree_root_t *root) { if (!ppm_cfg->max_rule_ticks) return; ppm_cfg->rule_event_cnt++; if (ppm_cfg->rule_log && ppm_rt) ppm_set_rule(root, ppm_rt->tot); } void ppm_clear_rule_event(ppm_cfg_t *ppm_cfg, detection_option_tree_root_t *root) { if (!ppm_cfg->max_rule_ticks) return; ppm_cfg->rule_event_cnt++; if (ppm_cfg->rule_log) ppm_clear_rule(root); } /* * Config functions */ void ppm_set_pkt_action(ppm_cfg_t *ppm_cfg, int flag) { ppm_cfg->pkt_action = flag; } void ppm_set_pkt_log(ppm_cfg_t *ppm_cfg, int flag) { ppm_cfg->pkt_log |= flag; } void ppm_set_rule_action(ppm_cfg_t *ppm_cfg, int flag) { ppm_cfg->rule_action = flag; } void ppm_set_rule_log(ppm_cfg_t *ppm_cfg, int flag) { ppm_cfg->rule_log |= flag; } void ppm_set_max_pkt_time(ppm_cfg_t *ppm_cfg, PPM_USECS usecs) { ppm_cfg->max_pkt_ticks = usecs * ppm_tpu; } void ppm_set_max_rule_time(ppm_cfg_t *ppm_cfg, PPM_USECS usecs) { ppm_cfg->max_rule_ticks = usecs * ppm_tpu; } void ppm_set_max_suspend_time(ppm_cfg_t *ppm_cfg, PPM_SECS secs) { /* use usecs instead of ticks for rule suspension during pcap playback */ ppm_cfg->max_suspend_ticks = (uint64_t)secs * 1000000; #ifndef PPM_TEST ppm_cfg->max_suspend_ticks *= ppm_tpu; #endif } void ppm_set_rule_threshold(ppm_cfg_t *ppm_cfg, unsigned int cnt) { ppm_cfg->rule_threshold = cnt; } #ifdef DEBUG void ppm_set_debug_rules(ppm_cfg_t *ppm_cfg, int flag) { ppm_cfg->debug_rules = flag; } void ppm_set_debug_pkts(ppm_cfg_t *ppm_cfg, int flag) { ppm_cfg->debug_pkts = flag; } #endif #endif snort-2.9.15.1/src/ppm.h0000644000175200017520000002560413571422607011613 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2006-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* ** ppm.h - packet performance monitor ** ** Author: Marc Norton ** */ #ifndef __PACKET_PROCESSING_MONITOR_H__ #define __PACKET_PROCESSING_MONITOR_H__ #ifdef PPM_MGR #include "sf_types.h" #include "cpuclock.h" #define cputime get_clockticks typedef uint64_t PPM_TICKS; typedef uint64_t PPM_USECS; typedef unsigned int PPM_SECS; struct _SnortConfig; extern struct _SnortConfig *snort_conf; typedef struct { /* config section */ int enabled; PPM_TICKS max_pkt_ticks; int pkt_log; /* alert,console,syslog */ int pkt_action; /* suspend */ PPM_TICKS max_rule_ticks; uint64_t rule_threshold; /* rules must fail this many times in a row to suspend */ int rule_log; /* alert,console,syslog */ int rule_action; /* suspend */ #ifdef DEBUG int debug_pkts; int debug_rules; #endif /* stats section */ unsigned int rule_event_cnt; unsigned int pkt_event_cnt; uint64_t tot_pkt_time; /* ticks */ uint64_t tot_pkts; uint64_t tot_rule_time; /* ticks */ uint64_t tot_rules; uint64_t tot_nc_rule_time; /* ticks */ uint64_t tot_nc_rules; uint64_t tot_pcre_rule_time; /* ticks */ uint64_t tot_pcre_rules; uint64_t max_suspend_ticks; } ppm_cfg_t; typedef struct { uint64_t pktcnt; uint64_t start, cur, tot; uint64_t subtract; PPM_TICKS max_pkt_ticks; unsigned int rule_tests; unsigned int pcre_rule_tests; unsigned int nc_rule_tests; } ppm_pkt_timer_t; typedef struct { uint64_t start, cur, tot; PPM_TICKS max_rule_ticks; } ppm_rule_timer_t; /* global data */ #define PPM_MAX_TIMERS 10 extern PPM_TICKS ppm_tpu; extern ppm_pkt_timer_t ppm_pkt_times[PPM_MAX_TIMERS]; extern ppm_pkt_timer_t *ppm_pt; extern unsigned int ppm_pkt_index; extern ppm_rule_timer_t ppm_rule_times[PPM_MAX_TIMERS]; extern ppm_rule_timer_t *ppm_rt; extern unsigned int ppm_rule_times_index; extern uint64_t ppm_cur_time; extern int ppm_abort_this_pkt; extern int ppm_suspend_this_rule; #define PPM_LOG_ALERT 1 #define PPM_LOG_MESSAGE 2 #define PPM_ACTION_SUSPEND 1 /* Config flags */ #define PPM_ENABLED() (snort_conf->ppm_cfg.enabled > 0) #define PPM_PKTS_ENABLED() (snort_conf->ppm_cfg.max_pkt_ticks > 0) #define PPM_RULES_ENABLED() (snort_conf->ppm_cfg.max_rule_ticks > 0) /* packet, rule event flags */ #define PPM_PACKET_ABORT_FLAG() ppm_abort_this_pkt #define PPM_RULE_SUSPEND_FLAG() ppm_suspend_this_rule #define PPM_INC_PKT_CNT() snort_conf->ppm_cfg.tot_pkts++ #define PPM_PKT_CNT() ppm_pt->pktcnt #define PPM_PKT_LOG(p) if (ppm_abort_this_pkt) ppm_pkt_log(&snort_conf->ppm_cfg,p) #define PPM_RULE_LOG(cnt,p) ppm_rule_log(&snort_conf->ppm_cfg,cnt,p) #define PPM_ACCUM_PKT_TIME() snort_conf->ppm_cfg.tot_pkt_time += ppm_pt->tot; #define PPM_ACCUM_RULE_TIME() \ snort_conf->ppm_cfg.tot_rule_time += ppm_rt->tot; \ snort_conf->ppm_cfg.tot_rules++; #define PPM_ACCUM_NC_RULE_TIME() \ snort_conf->ppm_cfg.tot_nc_rule_time += ppm_rt->tot; \ snort_conf->ppm_cfg.tot_nc_rules++; #define PPM_ACCUM_PCRE_RULE_TIME() \ snort_conf->ppm_cfg.tot_pcre_rule_time += ppm_rt->tot; \ snort_conf->ppm_cfg.tot_pcre_rules++; #define PPM_GET_TIME() cputime(ppm_cur_time) #define PPM_PKT_RULE_TESTS() ppm_pt->rule_tests #define PPM_PKT_PCRE_RULE_TESTS() ppm_pt->pcre_rule_tests #define PPM_PKT_NC_RULE_TESTS() ppm_pt->nc_rule_tests #define PPM_INC_PKT_RULE_TESTS() if(ppm_pt)ppm_pt->rule_tests++ #define PPM_INC_PKT_PCRE_RULE_TESTS() if(ppm_pt)ppm_pt->pcre_rule_tests++ #define PPM_INC_PKT_NC_RULE_TESTS() if(ppm_pt)ppm_pt->nc_rule_tests++ #ifdef DEBUG #define PPM_DEBUG_PKTS() snort_conf->ppm_cfg.debug_pkts #endif #define PPM_PRINT_PKT_TIME(a) LogMessage(a, ppm_ticks_to_usecs((PPM_TICKS)ppm_pt->tot) ); #ifdef PPM_TEST /* use usecs instead of ticks for rule suspension during pcap playback */ #define PPM_RULE_TIME(p) ((p->pkth->ts.tv_sec * 1000000) + p->pkth->ts.tv_usec) #else #define PPM_RULE_TIME(p) ppm_cur_time #endif #define PPM_INIT_PKT_TIMER() \ if(ppm_pkt_index < PPM_MAX_TIMERS) \ { \ ppm_pt = &ppm_pkt_times[ppm_pkt_index++]; \ ppm_abort_this_pkt = 0; \ ppm_pt->pktcnt = snort_conf->ppm_cfg.tot_pkts; \ ppm_pt->start = ppm_cur_time; \ ppm_pt->subtract = 0; \ ppm_pt->rule_tests = 0; \ ppm_pt->pcre_rule_tests = 0; \ ppm_pt->nc_rule_tests = 0; \ ppm_pt->max_pkt_ticks = snort_conf->ppm_cfg.max_pkt_ticks; \ ppm_init_rules(); \ } #define PPM_TOTAL_PKT_TIME() \ if( ppm_pt) \ { \ ppm_pt->tot = ppm_cur_time - ppm_pt->start - ppm_pt->subtract; \ } #define PPM_END_PKT_TIMER() \ if( (ppm_pkt_index > 0) && ppm_pt) \ { \ ppm_pkt_index--; \ if( ppm_pkt_index > 0 ) \ { \ /*ppm_pkt_times[ppm_pkt_index-1].subtract=ppm_pt->tot; */ \ ppm_pt = &ppm_pkt_times[ppm_pkt_index-1]; \ } \ else \ { \ ppm_pt=0; \ } \ } #define PPM_INIT_RULE_TIMER() \ if(ppm_rule_times_index < PPM_MAX_TIMERS) \ { \ ppm_rt = &ppm_rule_times[ppm_rule_times_index++]; \ ppm_suspend_this_rule = 0; \ ppm_rt->start=ppm_cur_time; \ ppm_rt->max_rule_ticks = snort_conf->ppm_cfg.max_rule_ticks; \ } #define PPM_END_RULE_TIMER() \ if(( ppm_rule_times_index > 0) && ppm_rt ) \ { \ ppm_rule_times_index--; \ if (ppm_rule_times_index > 0) \ { \ ppm_rt=&ppm_rule_times[ppm_rule_times_index-1]; \ } else { \ ppm_rt=NULL; \ } \ } /* To print the log if ppm is enabled and ppm_abort_this_pkt is 1 */ #define PPM_LATENCY_TRACE() \ if( ppm_abort_this_pkt ) \ { \ if( pkt_trace_enabled ) \ { \ if( !PacketIsRebuilt(p)) \ { \ addPktTraceData(VERDICT_REASON_NO_BLOCK, snprintf(trace_line, MAX_TRACE_LINE, \ "PL flag : (1)")); \ } \ else \ { \ addPktTraceData(VERDICT_REASON_NO_BLOCK, snprintf(trace_line, MAX_TRACE_LINE, \ "PL/R flag : (1)")); \ } \ } \ } \ /* use PPM_GET_TIME; first to get the current time */ #define PPM_PACKET_TEST() \ if( ppm_pt ) \ { \ ppm_pt->tot = ppm_cur_time - ppm_pt->start /*- ppm_pt->subtract*/; \ if(ppm_pt->tot > ppm_pt->max_pkt_ticks) \ { \ if( snort_conf->ppm_cfg.pkt_action & PPM_ACTION_SUSPEND ) \ ppm_abort_this_pkt = 1; \ } \ } #if 0 && defined(PPM_TEST) #define PPM_DBG_CSV(state, otn, when) \ LogMessage( \ "PPM, %u, %u, %s, " STDu64 "\n", \ otn->sigInfo.generator, otn->sigInfo.id, state, when \ ) #else #define PPM_DBG_CSV(state, otn, when) #endif /* use PPM_GET_TIME; first to get the current time */ #define PPM_RULE_TEST(root,p) \ if( ppm_rt ) \ { \ ppm_rt->tot = ppm_cur_time - ppm_rt->start; \ if(ppm_rt->tot > ppm_rt->max_rule_ticks) \ { \ if( snort_conf->ppm_cfg.rule_action & PPM_ACTION_SUSPEND ) \ { \ int ii; \ ppm_suspend_this_rule = 1; \ (root)->ppm_disable_cnt++; \ if( pkt_trace_enabled ) \ { \ addPktTraceData(VERDICT_REASON_NO_BLOCK, snprintf(trace_line, MAX_TRACE_LINE, \ "RL flag : (1)")); \ } \ for ( ii = 0; ii< root->num_children; ii++) \ { \ root->children[ii]->ppm_disable_cnt++; \ } \ if( (root)->ppm_disable_cnt >= snort_conf->ppm_cfg.rule_threshold ) \ { \ ppm_set_rule_event(&snort_conf->ppm_cfg, root); \ (root)->tree_state=RULE_STATE_DISABLED; \ (root)->ppm_suspend_time=PPM_RULE_TIME(p); \ PPM_DBG_CSV("disabled", (root), (root)->ppm_suspend_time); \ } \ else \ { \ (root)->ppm_suspend_time=0; \ } \ } \ else \ { \ (root)->ppm_suspend_time=0; \ if( (root)->ppm_disable_cnt > 0 ) \ (root)->ppm_disable_cnt--; \ } \ } \ } #define PPM_REENABLE_TREE(root,p) \ if( (root)->ppm_suspend_time && snort_conf->ppm_cfg.max_suspend_ticks ) \ { \ PPM_TICKS now = PPM_RULE_TIME(p); \ PPM_TICKS then = (root)->ppm_suspend_time + snort_conf->ppm_cfg.max_suspend_ticks; \ if( now > then ) \ { \ (root)->ppm_suspend_time=0; \ (root)->tree_state=RULE_STATE_ENABLED; \ ppm_clear_rule_event(&snort_conf->ppm_cfg, root); \ PPM_DBG_CSV("enabled", (root), now); \ } \ else \ { \ PPM_DBG_CSV("pending", (root), then-now); \ } \ } void ppm_init(ppm_cfg_t *); #ifdef DEBUG void ppm_set_debug_rules(ppm_cfg_t *, int); void ppm_set_debug_pkts(ppm_cfg_t *, int); #endif void ppm_set_pkt_action(ppm_cfg_t *, int); void ppm_set_pkt_log(ppm_cfg_t *, int); void ppm_set_rule_action(ppm_cfg_t *, int); void ppm_set_rule_threshold(ppm_cfg_t *, unsigned int); void ppm_set_rule_log(ppm_cfg_t *, int); void ppm_set_max_pkt_time(ppm_cfg_t *, PPM_USECS); void ppm_set_max_rule_time(ppm_cfg_t *, PPM_USECS); void ppm_set_max_suspend_time(ppm_cfg_t *, PPM_SECS); void ppm_print_cfg(ppm_cfg_t *); void ppm_print_summary(ppm_cfg_t *); double ppm_ticks_to_usecs( PPM_TICKS ); void ppm_pkt_log(ppm_cfg_t*, Packet*); void ppm_set_rule_event (ppm_cfg_t *, detection_option_tree_root_t *); void ppm_clear_rule_event (ppm_cfg_t *, detection_option_tree_root_t *); void ppm_rule_log(ppm_cfg_t *, uint64_t, Packet *); void ppm_init_rules(void); void ppm_set_rule(detection_option_tree_root_t *, PPM_TICKS); #define PPM_INIT() ppm_init() #define PPM_PRINT_CFG(x) ppm_print_cfg(x) #define PPM_PRINT_SUMMARY(x) ppm_print_summary(x) #else /* !PPM_MGR */ #define PPM_GET_TIME() #define PPM_SET_TIME() #endif /* PPM_MGR */ #endif /* __PACKET_PROCESSING_MONITOR_H__ */ snort-2.9.15.1/src/pcap_pkthdr32.h0000644000175200017520000000277613571422607013470 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2007-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __PCAP_PKTHDR32_H__ #define __PCAP_PKTHDR32_H__ #include "sf_types.h" /* we must use fixed size of 32 bits, because on-disk * format of savefiles uses 32-bit tv_sec (and tv_usec) */ struct sf_timeval32 { uint32_t tv_sec; /* seconds */ uint32_t tv_usec; /* microseconds */ }; /* this is equivalent to the pcap pkthdr struct, but we need * a 32 bit one for unified output */ struct pcap_pkthdr32 { struct sf_timeval32 ts; /* packet timestamp */ uint32_t caplen; /* packet capture length */ uint32_t len; /* packet "real" length */ }; #endif // __PCAP_PKTHDR32_H__ snort-2.9.15.1/src/cpuclock.h0000644000175200017520000000625713571422607012625 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2006-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef CPU_CLOCK_TICKS_H #define CPU_CLOCK_TICKS_H /* Assembly to find clock ticks. */ #ifdef WIN32 #include /* INTEL WINDOWS */ __inline void __cputicks_msc(uint64_t *val) { __int64 t; __asm { rdtsc; mov dword PTR [t],eax; mov dword PTR [t+4],edx; } *val = (uint64_t)t; } #define get_clockticks(val) __cputicks_msc(&val) /* #define get_clockticks(val) \ QueryPerformanceCounter((PLARGE_INTEGER)&val) */ #else #include /* INTEL LINUX/BSD/.. */ #if (defined(__i386) || defined(__amd64) || defined(__x86_64__)) #define get_clockticks(val) \ { \ uint32_t a, d; \ __asm__ __volatile__ ("rdtsc" : "=a" (a), "=d" (d)); \ val = ((uint64_t)a) | (((uint64_t)d) << 32); \ } #else #if (defined(__ia64) && defined(__GNUC__) ) #define get_clockticks(val) \ { \ __asm__ __volatile__ ("mov %0=ar.itc" : "=r"(val)); \ } #else #if (defined(__ia64) && defined(__hpux)) #include #define get_clockticks(val) \ { \ val = _Asm_mov_from_ar (_AREG_ITC); \ } #else /* POWER PC */ #if (defined(__GNUC__) && (defined(__powerpc__) || (defined(__ppc__)))) #define get_clockticks(val) \ { \ uint32_t tbu0, tbu1, tbl; \ do \ { \ __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); \ __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); \ __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); \ } while (tbu0 != tbu1); \ val = ((uint64_t)tbl) | (((uint64_t)tbu0) << 32); \ } #else /* SPARC */ #ifdef SPARCV9 #ifdef _LP64 #define get_clockticks(val) \ { \ __asm__ __volatile__("rd %%tick, %0" : "=r"(val)); \ } #else #define get_clockticks(val) \ { \ uint32_t a, b; \ __asm__ __volatile__("rd %%tick, %0\n" \ "srlx %0, 32, %1" \ : "=r"(a), "=r"(b)); \ val = ((uint64_t)a) | (((uint64_t)b) << 32); \ } #endif /* _LP64 */ #else #define get_clockticks(val) #endif /* SPARC */ #endif /* POWERPC || PPC */ #endif /* IA64 && HPUX */ #endif /* IA64 && GNUC */ #endif /* I386 || AMD64 || X86_64 */ #endif /* WIN32 */ static inline double get_ticks_per_usec (void) { uint64_t start = 0, end = 0; get_clockticks(start); #ifdef WIN32 Sleep(1000); #else sleep(1); #endif get_clockticks(end); return (double)(end-start)/1e6; } #endif /* CPU_CLOCK_TICKS_H */ snort-2.9.15.1/src/sf_types.h0000644000175200017520000001436413571422607012654 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2007-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __SF_TYPES_H__ #define __SF_TYPES_H__ #include #ifdef HAVE_CONFIG_H #include "config.h" #ifdef WIN32 # include "stdint.h" # include "inttypes.h" #else /* Autoconf uses , and as standard includes for * determining if these exist so there shouldn't be any typedef conflicts with * including , or since these would be * defined already */ # if !defined(HAVE_UINT8_T) || !defined(HAVE_U_INT8_T) # if !defined(HAVE_UINT8_T) && !defined(HAVE_U_INT8_T) typedef unsigned char u_int8_t; typedef unsigned char uint8_t; # elif defined(HAVE_UINT8_T) typedef uint8_t u_int8_t; # else typedef u_int8_t uint8_t; # endif /* !defined(HAVE_UINT8_T) && !defined(HAVE_U_INT8_T) */ # endif /* !defined(HAVE_UINT8_T) || !defined(HAVE_U_INT8_T) */ # if !defined(HAVE_UINT16_T) || !defined(HAVE_U_INT16_T) # if !defined(HAVE_UINT16_T) && !defined(HAVE_U_INT16_T) typedef unsigned short u_int16_t; typedef unsigned short uint16_t; # elif defined(HAVE_UINT16_T) typedef uint16_t u_int16_t; # else typedef u_int16_t uint16_t; # endif /* !defined(HAVE_UINT16_T) && !defined(HAVE_U_INT16_T) */ # endif /* !defined(HAVE_UINT16_T) || !defined(HAVE_U_INT16_T) */ # if !defined(HAVE_UINT32_T) || !defined(HAVE_U_INT32_T) # if !defined(HAVE_UINT32_T) && !defined(HAVE_U_INT32_T) # if SIZEOF_UNSIGNED_LONG_INT == 4 typedef unsigned long int u_int32_t; typedef unsigned long int uint32_t; # elif SIZEOF_UNSIGNED_INT == 4 typedef unsigned int u_int32_t; typedef unsigned int uint32_t; # endif /* SIZEOF_UNSIGNED_LONG_INT == 4 */ # elif defined(HAVE_UINT32_T) typedef uint32_t u_int32_t; # else typedef u_int32_t uint32_t; # endif /* !defined(HAVE_UINT32_T) && !defined(HAVE_U_INT32_T) */ # endif /* !defined(HAVE_UINT32_T) || !defined(HAVE_U_INT32_T) */ # if !defined(HAVE_UINT64_T) || !defined(HAVE_U_INT64_T) # if !defined(HAVE_UINT64_T) && !defined(HAVE_U_INT64_T) # if SIZEOF_UNSIGNED_LONG_LONG_INT == 8 typedef unsigned long long int u_int64_t; typedef unsigned long long int uint64_t; # elif SIZEOF_UNSIGNED_LONG_INT == 8 typedef unsigned long int u_int64_t; typedef unsigned long int uint64_t; # endif # elif defined(HAVE_UINT64_T) typedef uint64_t u_int64_t; # else typedef u_int64_t uint64_t; # endif /* !defined(HAVE_UINT64_T) && !defined(HAVE_U_INT64_T) */ # endif /* !defined(HAVE_UINT64_T) || !defined(HAVE_U_INT64_T) */ # ifndef HAVE_INT8_T typedef char int8_t; # endif # ifndef HAVE_INT16_T typedef short int16_t; # endif # ifndef HAVE_INT32_T # if SIZEOF_LONG_INT == 4 typedef long int int32_t; # else typedef int int32_t; # endif # endif # ifndef HAVE_INT64_T # if SIZEOF_LONG_LONG_INT == 8 typedef long long int int64_t; # else typedef long int int64_t; # endif # endif # ifndef WIN32 # ifdef HAVE_INTTYPES_H /* includes */ # include # elif HAVE_STDINT_H # include # else /* Solaris - if inttypes.h is present, it should bring this in */ # ifndef SYS_INT_TYPES_H # if defined(_LP64) || defined(_I32LPx) typedef long int intptr_t; typedef unsigned long int uintptr_t; # else typedef int intptr_t; typedef unsigned int uintptr_t; # endif /* defined(_LP64) || defined(_I32LPx) */ # endif /* SYS_INT_TYPES_H */ # endif /* HAVE_INTTYPES_H elseif HAVE_STDINT_H */ # endif #endif /* WIN32 */ #endif /* HAVE_CONFIG_H */ /* if PRIu64 isn't in * we define it and similar here */ #ifndef PRIu64 # if SIZEOF_UNSIGNED_LONG_INT == 8 # define _SF_PREFIX "l" # else # define _SF_PREFIX "ll" # endif /* SIZEOF_UNSIGNED_LONG_INT == 8 */ # define PRIu64 _SF_PREFIX "u" # define PRIi64 _SF_PREFIX "i" # define PRIx64 _SF_PREFIX "x" #endif /* PRIu64 */ /* use these macros (and those in ) * for 64 bit format portability */ #define STDu64 "%" PRIu64 #define CSVu64 STDu64 "," #define FMTu64(fmt) "%" fmt PRIu64 #define STDi64 "%" PRIi64 #define CSVi64 STDi64 "," #define FMTi64(fmt) "%" fmt PRIi64 #define STDx64 "%" PRIx64 #define CSVx64 STDx64 "," #define FMTx64(fmt) "%" fmt PRIx64 #ifndef UINT8_MAX # define UINT8_MAX 0xff #endif #ifndef USHRT_MAX # define USHRT_MAX 0xffff #endif #ifndef UINT16_MAX # define UINT16_MAX 0xffff #endif #ifndef UINT32_MAX # define UINT32_MAX (4294967295U) #endif #ifndef UINT64_MAX # if SIZEOF_UNSIGNED_LONG_INT == 8 # define UINT64_MAX (18446744073709551615UL) # else # define UINT64_MAX (18446744073709551615ULL) # endif /* SIZEOF_UNSIGNED_LONG_INT == 8 */ #endif /* UINT64_MAX */ /* Somewhat arbitrary, but should be enough for this application * since files shouldn't be buried too deep. This provides about * 15 levels of 255 character path components */ #ifndef PATH_MAX # define PATH_MAX 4096 #endif /* utilities */ #ifndef boolean #ifndef HAVE_BOOLEAN typedef unsigned char boolean; #endif #endif #ifndef TRUE # define TRUE 1 #endif #ifndef FALSE # define FALSE 0 #endif #ifdef HAVE_STDBOOL_H # include #else # ifndef HAVE__BOOL # ifdef __cplusplus typedef bool _Bool; # else # define _Bool signed char # endif # endif # define bool _Bool # define false 0 # define true 1 # define __bool_true_false_are_defined 1 #endif #endif /* __SF_TYPES_H__ */ snort-2.9.15.1/src/log_text.c0000644000175200017520000015231513571422607012637 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // @file log_text.c // @author Russ Combs #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifdef HAVE_STRINGS_H #include #endif #ifndef WIN32 #include #include #include #endif /* !WIN32 */ #include #include #include "log.h" #include "rules.h" #include "treenodes.h" #include "util.h" #include "snort_debug.h" #include "signature.h" #include "util_net.h" #include "snort.h" #include "log_text.h" #include "sfutil/sf_textlog.h" #include "snort_bounds.h" #include "obfuscation.h" #include "detection_util.h" #include "sfutil/sf_ip.h" extern OptTreeNode *otn_tmp; /* global ptr to current rule data */ extern int IsGzipData(void *); extern int IsJSNormData(void *); /*-------------------------------------------------------------------- * utility functions *-------------------------------------------------------------------- */ void LogTimeStamp(TextLog* log, Packet* p) { char timestamp[TIMEBUF_SIZE]; ts_print((struct timeval*)&p->pkth->ts, timestamp); TextLog_Puts(log, timestamp); } /*-------------------------------------------------------------------- * alert stuff cloned from log.c *-------------------------------------------------------------------- */ /*-------------------------------------------------------------------- * Function: LogPriorityData() * * Purpose: Prints out priority data associated with an alert * * Arguments: log => pointer to TextLog to write the data to * doNewLine => tack a \n to the end of the line or not (bool) * * Returns: void function *-------------------------------------------------------------------- */ void LogPriorityData(TextLog* log, bool doNewLine) { if (otn_tmp == NULL) return; if ((otn_tmp->sigInfo.classType != NULL) && (otn_tmp->sigInfo.classType->name != NULL)) { TextLog_Print(log, "[Classification: %s] ", otn_tmp->sigInfo.classType->name); } TextLog_Print(log, "[Priority: %d] ", otn_tmp->sigInfo.priority); if (doNewLine) TextLog_NewLine(log); } #if defined(FEAT_OPEN_APPID) /*-------------------------------------------------------------------- * Function: LogAppID() * * Purpose: Prints out AppID data associated with an alert * * Arguments: log => pointer to TextLog to write the data to * appName => name of app ID detected (if any) * doNewLine => tack a \n to the end of the line or not (bool) * * Returns: void function *-------------------------------------------------------------------- */ void LogAppID(TextLog* log, const char* appName, bool doNewLine) { if (!appName || !appName[0]) return; TextLog_Print(log, "[AppID: %s] ", appName); if (doNewLine) TextLog_NewLine(log); } #endif /*-------------------------------------------------------------------- * Layer 2 header stuff cloned from log.c *-------------------------------------------------------------------- */ #ifndef NO_NON_ETHER_DECODER /*-------------------------------------------------------------------- * Function: LogTrHeader(TextLog*, Packet*) * * Purpose: Print the packet TokenRing header to the given TextLog * * Arguments: log => pointer to TextLog to print to * * Returns: void function *-------------------------------------------------------------------- */ void LogTrHeader(TextLog* log, Packet* p) { TextLog_Print(log, "%X:%X:%X:%X:%X:%X -> ", p->trh->saddr[0], p->trh->saddr[1], p->trh->saddr[2], p->trh->saddr[3], p->trh->saddr[4], p->trh->saddr[5]); TextLog_Print(log, "%X:%X:%X:%X:%X:%X\n", p->trh->daddr[0], p->trh->daddr[1], p->trh->daddr[2], p->trh->daddr[3], p->trh->daddr[4], p->trh->daddr[5]); TextLog_Print(log, "access control:0x%X frame control:0x%X\n", p->trh->ac, p->trh->fc); if(!p->trhllc) return; TextLog_Print(log, "DSAP: 0x%X SSAP 0x%X protoID: %X%X%X Ethertype: %X\n", p->trhllc->dsap, p->trhllc->ssap, p->trhllc->protid[0], p->trhllc->protid[1], p->trhllc->protid[2], p->trhllc->ethertype); if(p->trhmr) { TextLog_Print(log, "RIF structure is present:\n"); TextLog_Print(log, "bcast: 0x%X length: 0x%X direction: 0x%X largest" "fr. size: 0x%X res: 0x%X\n", TRH_MR_BCAST(p->trhmr), TRH_MR_LEN(p->trhmr), TRH_MR_DIR(p->trhmr), TRH_MR_LF(p->trhmr), TRH_MR_RES(p->trhmr)); TextLog_Print(log, "rseg -> %X:%X:%X:%X:%X:%X:%X:%X\n", p->trhmr->rseg[0], p->trhmr->rseg[1], p->trhmr->rseg[2], p->trhmr->rseg[3], p->trhmr->rseg[4], p->trhmr->rseg[5], p->trhmr->rseg[6], p->trhmr->rseg[7]); } } #endif // NO_NON_ETHER_DECODER /*-------------------------------------------------------------------- * Function: LogEthHeader() * * Purpose: Print the packet Ethernet header to the given TextLog * * Arguments: log => pointer to TextLog to print to * * Returns: void function *-------------------------------------------------------------------- */ static void LogEthHeader(TextLog* log, Packet* p) { /* src addr */ TextLog_Print(log, "%02X:%02X:%02X:%02X:%02X:%02X -> ", p->eh->ether_src[0], p->eh->ether_src[1], p->eh->ether_src[2], p->eh->ether_src[3], p->eh->ether_src[4], p->eh->ether_src[5]); /* dest addr */ TextLog_Print(log, "%02X:%02X:%02X:%02X:%02X:%02X ", p->eh->ether_dst[0], p->eh->ether_dst[1], p->eh->ether_dst[2], p->eh->ether_dst[3], p->eh->ether_dst[4], p->eh->ether_dst[5]); /* protocol and pkt size */ TextLog_Print(log, "type:0x%X len:0x%X\n", ntohs(p->eh->ether_type), p->pkth->pktlen); } #ifdef MPLS static void LogMPLSHeader(TextLog* log, Packet* p) { TextLog_Print(log,"label:0x%05X exp:0x%X bos:0x%X ttl:0x%X\n", p->mplsHdr.label, p->mplsHdr.exp, p->mplsHdr.bos, p->mplsHdr.ttl); } #endif #ifdef GRE static void LogGREHeader(TextLog *log, Packet *p) { if (p->greh == NULL) return; TextLog_Print(log, "GRE version:%u flags:0x%02X ether-type:0x%04X\n", GRE_VERSION(p->greh), p->greh->flags, GRE_PROTO(p->greh)); } #endif #ifndef NO_NON_ETHER_DECODER /*-------------------------------------------------------------------- * Function: LogSLLHeader(TextLog* ) * * Purpose: Print the packet SLL (fake) header to the given TextLog * (piece partly is borrowed from tcpdump :)) * * Arguments: log => pointer to TextLog to print to * * Returns: void function *-------------------------------------------------------------------- */ #ifdef DLT_LINUX_SLL static void LogSLLHeader(TextLog* log, Packet* p) { switch (ntohs(p->sllh->sll_pkttype)) { case LINUX_SLL_HOST: TextLog_Puts(log, "< "); break; case LINUX_SLL_BROADCAST: TextLog_Puts(log, "B "); break; case LINUX_SLL_MULTICAST: TextLog_Puts(log, "M "); break; case LINUX_SLL_OTHERHOST: TextLog_Puts(log, "P "); break; case LINUX_SLL_OUTGOING: TextLog_Puts(log, "> "); break; default: TextLog_Puts(log, "? "); break; } /* mac addr */ TextLog_Print(log, "l/l len: %i l/l type: 0x%X %02X:%02X:%02X:%02X:%02X:%02X\n", htons(p->sllh->sll_halen), ntohs(p->sllh->sll_hatype), p->sllh->sll_addr[0], p->sllh->sll_addr[1], p->sllh->sll_addr[2], p->sllh->sll_addr[3], p->sllh->sll_addr[4], p->sllh->sll_addr[5]); /* protocol and pkt size */ TextLog_Print(log, "pkt type:0x%X proto: 0x%X len:0x%X\n", ntohs(p->sllh->sll_pkttype), ntohs(p->sllh->sll_protocol), p->pkth->pktlen); } #endif /*-------------------------------------------------------------------- * Function: LogWifiHeader(TextLog* ) * * Purpose: Print the packet 802.11 header to the given TextLog * * Arguments: log => pointer to TextLog to print to * * Returns: void function *-------------------------------------------------------------------- */ static void LogWifiHeader(TextLog* log, Packet * p) { /* This assumes we are printing a data packet, could be changed to print other types as well */ const u_char *da = NULL, *sa = NULL, *bssid = NULL, *ra = NULL, *ta = NULL; /* per table 4, IEEE802.11 section 7.2.2 */ if ((p->wifih->frame_control & WLAN_FLAG_TODS) && (p->wifih->frame_control & WLAN_FLAG_FROMDS)) { ra = p->wifih->addr1; ta = p->wifih->addr2; da = p->wifih->addr3; sa = p->wifih->addr4; } else if (p->wifih->frame_control & WLAN_FLAG_TODS) { bssid = p->wifih->addr1; sa = p->wifih->addr2; da = p->wifih->addr3; } else if (p->wifih->frame_control & WLAN_FLAG_FROMDS) { da = p->wifih->addr1; bssid = p->wifih->addr2; sa = p->wifih->addr3; } else { da = p->wifih->addr1; sa = p->wifih->addr2; bssid = p->wifih->addr3; } /* DO this switch to provide additional info on the type */ switch(p->wifih->frame_control & 0x00ff) { case WLAN_TYPE_MGMT_BEACON: TextLog_Puts(log, "Beacon "); break; /* management frames */ case WLAN_TYPE_MGMT_ASREQ: TextLog_Puts(log, "Assoc. Req. "); break; case WLAN_TYPE_MGMT_ASRES: TextLog_Puts(log, "Assoc. Resp. "); break; case WLAN_TYPE_MGMT_REREQ: TextLog_Puts(log, "Reassoc. Req. "); break; case WLAN_TYPE_MGMT_RERES: TextLog_Puts(log, "Reassoc. Resp. "); break; case WLAN_TYPE_MGMT_PRREQ: TextLog_Puts(log, "Probe Req. "); break; case WLAN_TYPE_MGMT_PRRES: TextLog_Puts(log, "Probe Resp. "); break; case WLAN_TYPE_MGMT_ATIM: TextLog_Puts(log, "ATIM "); break; case WLAN_TYPE_MGMT_DIS: TextLog_Puts(log, "Dissassoc. "); break; case WLAN_TYPE_MGMT_AUTH: TextLog_Puts(log, "Authent. "); break; case WLAN_TYPE_MGMT_DEAUTH: TextLog_Puts(log, "Deauthent. "); break; /* Control frames */ case WLAN_TYPE_CONT_PS: case WLAN_TYPE_CONT_RTS: case WLAN_TYPE_CONT_CTS: case WLAN_TYPE_CONT_ACK: case WLAN_TYPE_CONT_CFE: case WLAN_TYPE_CONT_CFACK: TextLog_Puts(log, "Control "); break; } if (sa != NULL) { TextLog_Print(log, "%X:%X:%X:%X:%X:%X -> ", sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]); } else if (ta != NULL) { TextLog_Print(log, "ta: %X:%X:%X:%X:%X:%X da: ", ta[0], ta[1], ta[2], ta[3], ta[4], ta[5]); } TextLog_Print(log, "%X:%X:%X:%X:%X:%X\n", da[0], da[1], da[2], da[3], da[4], da[5]); if (bssid != NULL) { TextLog_Print(log, "bssid: %X:%X:%X:%X:%X:%X", bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]); } if (ra != NULL) { TextLog_Print(log, " ra: %X:%X:%X:%X:%X:%X", ra[0], ra[1], ra[2], ra[3], ra[4], ra[5]); } TextLog_Puts(log, " Flags:"); if (p->wifih->frame_control & WLAN_FLAG_TODS) TextLog_Puts(log," ToDs"); if (p->wifih->frame_control & WLAN_FLAG_TODS) TextLog_Puts(log," FrDs"); if (p->wifih->frame_control & WLAN_FLAG_FRAG) TextLog_Puts(log," Frag"); if (p->wifih->frame_control & WLAN_FLAG_RETRY) TextLog_Puts(log," Re"); if (p->wifih->frame_control & WLAN_FLAG_PWRMGMT) TextLog_Puts(log," Pwr"); if (p->wifih->frame_control & WLAN_FLAG_MOREDAT) TextLog_Puts(log," MD"); if (p->wifih->frame_control & WLAN_FLAG_WEP) TextLog_Puts(log," Wep"); if (p->wifih->frame_control & WLAN_FLAG_ORDER) TextLog_Puts(log," Ord"); TextLog_NewLine(log); } #endif // NO_NON_ETHER_DECODER /*-------------------------------------------------------------------- * Function: Log2ndHeader(TextLog* , Packet p) * * Purpose: Log2ndHeader -- prints second layber header info. * * Arguments: log => pointer to TextLog to print to * * Returns: void function *-------------------------------------------------------------------- */ void Log2ndHeader(TextLog* log, Packet* p) { switch(DAQ_GetBaseProtocol()) { case DLT_EN10MB: /* Ethernet */ if(p && p->eh) LogEthHeader(log, p); break; #ifndef NO_NON_ETHER_DECODER #ifdef DLT_IEEE802_11 case DLT_IEEE802_11: if(p && p->wifih) LogWifiHeader(log, p); break; #endif case DLT_IEEE802: /* Token Ring */ if(p && p->trh) LogTrHeader(log, p); break; #ifdef DLT_LINUX_SLL case DLT_LINUX_SLL: if (p && p->sllh) LogSLLHeader(log, p); /* Linux cooked sockets */ break; #endif #endif // NO_NON_ETHER_DECODER default: if (ScLogVerbose()) { // FIXTHIS should only be output once! ErrorMessage("Datalink %i type 2nd layer display is not " "supported\n", DAQ_GetBaseProtocol()); } } } /*------------------------------------------------------------------- * IP stuff cloned from log.c *------------------------------------------------------------------- */ static void LogIpOptions(TextLog* log, Packet * p) { int i; int j; u_long init_offset; u_long print_offset; init_offset = TextLog_Tell(log); if(!p->ip_option_count || p->ip_option_count > 40) return; TextLog_Print(log, "IP Options (%d) => ", p->ip_option_count); for(i = 0; i < (int) p->ip_option_count; i++) { print_offset = TextLog_Tell(log); if((print_offset - init_offset) > 60) { TextLog_Puts(log, "\nIP Options => "); init_offset = TextLog_Tell(log); } switch(p->ip_options[i].code) { case IPOPT_RR: TextLog_Puts(log, "RR "); break; case IPOPT_EOL: TextLog_Puts(log, "EOL "); break; case IPOPT_NOP: TextLog_Puts(log, "NOP "); break; case IPOPT_TS: TextLog_Puts(log, "TS "); break; case IPOPT_ESEC: TextLog_Puts(log, "ESEC "); break; case IPOPT_SECURITY: TextLog_Puts(log, "SEC "); break; case IPOPT_LSRR: case IPOPT_LSRR_E: TextLog_Puts(log, "LSRR "); break; case IPOPT_SATID: TextLog_Puts(log, "SID "); break; case IPOPT_SSRR: TextLog_Puts(log, "SSRR "); break; case IPOPT_RTRALT: TextLog_Puts(log, "RTRALT "); break; default: TextLog_Print(log, "Opt %d: ", p->ip_options[i].code); if(p->ip_options[i].len) { for(j = 0; j < p->ip_options[i].len; j++) { if (p->ip_options[i].data) TextLog_Print(log, "%02X", p->ip_options[i].data[j]); else TextLog_Print(log, "%02X", 0); if((j % 2) == 0) TextLog_Putc(log, ' '); } } break; } } TextLog_NewLine(log); } /*-------------------------------------------------------------------- * Function: LogIPAddrs(TextLog* ) * * Purpose: Dump the IP addresses to the given TextLog * Handles obfuscation * * Arguments: log => TextLog to print to * p => packet structure * * Returns: void function *-------------------------------------------------------------------- */ void LogIpAddrs(TextLog *log, Packet *p) { if (!IPH_IS_VALID(p)) return; if (p->frag_flag || ((GET_IPH_PROTO(p) != IPPROTO_TCP) && (GET_IPH_PROTO(p) != IPPROTO_UDP))) { char *ip_fmt = "%s -> %s"; if (ScObfuscate()) { TextLog_Print(log, ip_fmt, ObfuscateIpToText(GET_SRC_ADDR(p)), ObfuscateIpToText(GET_DST_ADDR(p))); } else { TextLog_Print(log, ip_fmt, inet_ntoax(GET_SRC_ADDR(p)), inet_ntoax(GET_DST_ADDR(p))); } } else { char *ip_fmt = "%s:%d -> %s:%d"; if (ScObfuscate()) { TextLog_Print(log, ip_fmt, ObfuscateIpToText(GET_SRC_ADDR(p)), p->sp, ObfuscateIpToText(GET_DST_ADDR(p)), p->dp); } else { TextLog_Print(log, ip_fmt, inet_ntoax(GET_SRC_ADDR(p)), p->sp, inet_ntoax(GET_DST_ADDR(p)), p->dp); } } } /*-------------------------------------------------------------------- * Function: LogIPHeader(TextLog* ) * * Purpose: Dump the IP header info to the given TextLog * * Arguments: log => TextLog to print to * * Returns: void function *-------------------------------------------------------------------- */ void LogIPHeader(TextLog* log, Packet * p) { if(!IPH_IS_VALID(p)) { TextLog_Print(log, "IP header truncated\n"); return; } LogIpAddrs(log, p); if(!ScOutputDataLink()) { TextLog_NewLine(log); } else { TextLog_Putc(log, ' '); } TextLog_Print(log, "%s TTL:%u TOS:0x%X ID:%u IpLen:%u DgmLen:%u", protocol_names[GET_IPH_PROTO(p)], GET_IPH_TTL(p), GET_IPH_TOS(p), IS_IP6(p) ? ntohl(GET_IPH_ID(p)) : ntohs((uint16_t)GET_IPH_ID(p)), GET_IPH_HLEN(p) << 2, GET_IP_DGMLEN(p)); /* print the reserved bit if it's set */ if((uint8_t)((ntohs(GET_IPH_OFF(p)) & 0x8000) >> 15) == 1) TextLog_Puts(log, " RB"); /* printf more frags/don't frag bits */ if((uint8_t)((ntohs(GET_IPH_OFF(p)) & 0x4000) >> 14) == 1) TextLog_Puts(log, " DF"); if((uint8_t)((ntohs(GET_IPH_OFF(p)) & 0x2000) >> 13) == 1) TextLog_Puts(log, " MF"); TextLog_NewLine(log); /* print IP options */ if(p->ip_option_count != 0) { LogIpOptions(log, p); } /* print fragment info if necessary */ if(p->frag_flag) { TextLog_Print(log, "Frag Offset: 0x%04X Frag Size: 0x%04X\n", (p->frag_offset & 0x1FFF), GET_IP_PAYLEN(p)); } } #ifdef GRE static void LogOuterIPHeader(TextLog *log, Packet *p) { int save_family = p->family; IPH_API *save_api = p->iph_api; const IPHdr *save_iph = p->iph; uint8_t save_ip_option_count = p->ip_option_count; IP4Hdr *save_ip4h = p->ip4h; IP6Hdr *save_ip6h = p->ip6h; uint8_t save_frag_flag = p->frag_flag; uint16_t save_sp = 0, save_dp = 0; p->family = p->outer_family; p->iph_api = p->outer_iph_api; p->iph = p->outer_iph; p->ip_option_count = 0; p->ip4h = &p->outer_ip4h; p->ip6h = &p->outer_ip6h; p->frag_flag = 0; if (p->proto_bits & PROTO_BIT__TEREDO) { save_sp = p->sp; save_dp = p->dp; if (p->outer_udph) { p->sp = ntohs(p->outer_udph->uh_sport); p->dp = ntohs(p->outer_udph->uh_dport); } else { p->sp = ntohs(p->udph->uh_sport); p->dp = ntohs(p->udph->uh_dport); } } LogIPHeader(log, p); p->family = save_family; p->iph_api = save_api; p->iph = save_iph; p->ip_option_count = save_ip_option_count; p->ip4h = save_ip4h; p->ip6h = save_ip6h; p->frag_flag = save_frag_flag; if (p->proto_bits & PROTO_BIT__TEREDO) { p->sp = save_sp; p->dp = save_dp; } } #endif /*------------------------------------------------------------------- * TCP stuff cloned from log.c *------------------------------------------------------------------- */ static void LogTcpOptions(TextLog* log, Packet * p) { int i; int j; u_char tmp[5]; #if 0 u_long init_offset; u_long print_offset; init_offset = TextLog_Tell(log); #endif TextLog_Print(log, "TCP Options (%d) => ", p->tcp_option_count); if(p->tcp_option_count > 40 || !p->tcp_option_count) return; for(i = 0; i < (int) p->tcp_option_count; i++) { #if 0 print_offset = TextLog_Tell(log); if((print_offset - init_offset) > 60) { TextLog_Puts(log, "\nTCP Options => "); init_offset = TextLog_Tell(log); } #endif switch(p->tcp_options[i].code) { case TCPOPT_MAXSEG: memset((char*)tmp, 0, sizeof(tmp)); TextLog_Puts(log, "MSS: "); if (p->tcp_options[i].data) memcpy(tmp, p->tcp_options[i].data, 2); TextLog_Print(log, "%u ", EXTRACT_16BITS(tmp)); break; case TCPOPT_EOL: TextLog_Puts(log, "EOL "); break; case TCPOPT_NOP: TextLog_Puts(log, "NOP "); break; case TCPOPT_WSCALE: if (p->tcp_options[i].data) TextLog_Print(log, "WS: %u ", p->tcp_options[i].data[0]); else TextLog_Print(log, "WS: %u ", 0); break; case TCPOPT_SACK: memset((char*)tmp, 0, sizeof(tmp)); if (p->tcp_options[i].data && (p->tcp_options[i].len >= 2)) memcpy(tmp, p->tcp_options[i].data, 2); TextLog_Print(log, "Sack: %u@", EXTRACT_16BITS(tmp)); memset((char*)tmp, 0, sizeof(tmp)); if (p->tcp_options[i].data && (p->tcp_options[i].len >= 4)) memcpy(tmp, (p->tcp_options[i].data) + 2, 2); TextLog_Print(log, "%u ", EXTRACT_16BITS(tmp)); break; case TCPOPT_SACKOK: TextLog_Puts(log, "SackOK "); break; case TCPOPT_ECHO: memset((char*)tmp, 0, sizeof(tmp)); if (p->tcp_options[i].data) memcpy(tmp, p->tcp_options[i].data, 4); TextLog_Print(log, "Echo: %u ", EXTRACT_32BITS(tmp)); break; case TCPOPT_ECHOREPLY: memset((char*)tmp, 0, sizeof(tmp)); if (p->tcp_options[i].data) memcpy(tmp, p->tcp_options[i].data, 4); TextLog_Print(log, "Echo Rep: %u ", EXTRACT_32BITS(tmp)); break; case TCPOPT_TIMESTAMP: memset((char*)tmp, 0, sizeof(tmp)); if (p->tcp_options[i].data) memcpy(tmp, p->tcp_options[i].data, 4); TextLog_Print(log, "TS: %u ", EXTRACT_32BITS(tmp)); memset((char*)tmp, 0, sizeof(tmp)); if (p->tcp_options[i].data) memcpy(tmp, (p->tcp_options[i].data) + 4, 4); TextLog_Print(log, "%u ", EXTRACT_32BITS(tmp)); break; case TCPOPT_CC: memset((char*)tmp, 0, sizeof(tmp)); if (p->tcp_options[i].data) memcpy(tmp, p->tcp_options[i].data, 4); TextLog_Print(log, "CC %u ", EXTRACT_32BITS(tmp)); break; case TCPOPT_CCNEW: memset((char*)tmp, 0, sizeof(tmp)); if (p->tcp_options[i].data) memcpy(tmp, p->tcp_options[i].data, 4); TextLog_Print(log, "CCNEW: %u ", EXTRACT_32BITS(tmp)); break; case TCPOPT_CCECHO: memset((char*)tmp, 0, sizeof(tmp)); if (p->tcp_options[i].data) memcpy(tmp, p->tcp_options[i].data, 4); TextLog_Print(log, "CCECHO: %u ", EXTRACT_32BITS(tmp)); break; default: if(p->tcp_options[i].len) { TextLog_Print(log, "Opt %d (%d): ", p->tcp_options[i].code, (int) p->tcp_options[i].len); for(j = 0; j < p->tcp_options[i].len; j++) { if (p->tcp_options[i].data) TextLog_Print(log, "%02X", p->tcp_options[i].data[j]); else TextLog_Print(log, "%02X", 0); if ((j + 1) % 2 == 0) TextLog_Putc(log, ' '); } TextLog_Putc(log, ' '); } else { TextLog_Print(log, "Opt %d ", p->tcp_options[i].code); } break; } } TextLog_NewLine(log); } /*-------------------------------------------------------------------- * Function: LogTCPHeader(TextLog* ) * * Purpose: Dump the TCP header info to the given TextLog * * Arguments: log => pointer to TextLog to print data to * * Returns: void function *-------------------------------------------------------------------- */ void LogTCPHeader(TextLog* log, Packet * p) { char tcpFlags[9]; if(p->tcph == NULL) { TextLog_Print(log, "TCP header truncated\n"); return; } /* print TCP flags */ CreateTCPFlagString(p, tcpFlags); TextLog_Puts(log, tcpFlags); /* We don't care about the NULL */ /* print other TCP info */ TextLog_Print(log, " Seq: 0x%lX Ack: 0x%lX Win: 0x%X TcpLen: %d", (u_long) ntohl(p->tcph->th_seq), (u_long) ntohl(p->tcph->th_ack), ntohs(p->tcph->th_win), TCP_OFFSET(p->tcph) << 2); if((p->tcph->th_flags & TH_URG) != 0) { TextLog_Print(log, " UrgPtr: 0x%X\n", (uint16_t) ntohs(p->tcph->th_urp)); } else { TextLog_NewLine(log); } /* dump the TCP options */ if(p->tcp_option_count != 0) { LogTcpOptions(log, p); } } /*------------------------------------------------------------------- * UDP stuff cloned from log.c *------------------------------------------------------------------- */ /*-------------------------------------------------------------------- * Function: LogUDPHeader(TextLog* ) * * Purpose: Dump the UDP header to the given TextLog * * Arguments: log => pointer to TextLog * * Returns: void function *-------------------------------------------------------------------- */ void LogUDPHeader(TextLog* log, Packet* p) { if(p->udph == NULL) { TextLog_Print(log, "UDP header truncated\n"); return; } /* not much to do here... */ TextLog_Print(log, "Len: %d\n", ntohs(p->udph->uh_len) - UDP_HEADER_LEN); } /*-------------------------------------------------------------------- * ICMP stuff cloned from log.c *-------------------------------------------------------------------- */ /*-------------------------------------------------------------------- * Function: LogEmbeddedICMPHeader(TextLog* , ICMPHdr *) * * Purpose: Prints the 64 bits of the original IP payload in an ICMP packet * that requires it * * Arguments: log => pointer to TextLog * icmph => ICMPHdr struct pointing to original ICMP * * Returns: void function *-------------------------------------------------------------------- */ static void LogEmbeddedICMPHeader(TextLog* log, const ICMPHdr *icmph) { if (log == NULL || icmph == NULL) return; TextLog_Print(log, "Type: %d Code: %d Csum: %u", icmph->type, icmph->code, ntohs(icmph->csum)); switch (icmph->type) { case ICMP_DEST_UNREACH: case ICMP_TIME_EXCEEDED: case ICMP_SOURCE_QUENCH: break; case ICMP_PARAMETERPROB: if (icmph->code == 0) TextLog_Print(log, " Ptr: %u", icmph->s_icmp_pptr); break; case ICMP_REDIRECT: // XXX-IPv6 "NOT YET IMPLEMENTED - ICMP printing" break; case ICMP_ECHO: case ICMP_ECHOREPLY: case ICMP_TIMESTAMP: case ICMP_TIMESTAMPREPLY: case ICMP_INFO_REQUEST: case ICMP_INFO_REPLY: case ICMP_ADDRESS: case ICMP_ADDRESSREPLY: TextLog_Print(log, " Id: %u SeqNo: %u", ntohs(icmph->s_icmp_id), ntohs(icmph->s_icmp_seq)); break; case ICMP_ROUTER_ADVERTISE: TextLog_Print(log, " Addrs: %u Size: %u Lifetime: %u", icmph->s_icmp_num_addrs, icmph->s_icmp_wpa, ntohs(icmph->s_icmp_lifetime)); break; default: break; } TextLog_NewLine(log); return; } /*-------------------------------------------------------------------- * Function: LogICMPEmbeddedIP(TextLog* , Packet *) * * Purpose: Prints the original/encapsulated IP header + 64 bits of the * original IP payload in an ICMP packet * * Arguments: log => pointer to TextLog * p => packet struct * * Returns: void function *-------------------------------------------------------------------- */ static void LogICMPEmbeddedIP(TextLog* log, Packet *p) { Packet op; Packet *orig_p; uint32_t orig_ip_hlen; if (log == NULL || p == NULL) return; memset((char*)&op, 0, sizeof(op)); orig_p = &op; orig_p->iph = p->orig_iph; orig_p->tcph = p->orig_tcph; orig_p->udph = p->orig_udph; orig_p->sp = p->orig_sp; orig_p->dp = p->orig_dp; orig_p->icmph = p->orig_icmph; orig_p->iph_api = p->orig_iph_api; orig_p->ip4h = p->orig_ip4h; orig_p->ip6h = p->orig_ip6h; orig_p->family = p->orig_family; if(orig_p->iph != NULL) { TextLog_Print(log, "\n** ORIGINAL DATAGRAM DUMP:\n"); LogIPHeader(log, orig_p); orig_ip_hlen = IP_HLEN(p->orig_iph) << 2; switch(GET_IPH_PROTO(orig_p)) { case IPPROTO_TCP: if(orig_p->tcph != NULL) TextLog_Print(log, "Seq: 0x%lX\n", (u_long)ntohl(orig_p->tcph->th_seq)); break; case IPPROTO_UDP: if(orig_p->udph != NULL) TextLog_Print(log, "Len: %d Csum: %d\n", ntohs(orig_p->udph->uh_len) - UDP_HEADER_LEN, ntohs(orig_p->udph->uh_chk)); break; case IPPROTO_ICMP: if(orig_p->icmph != NULL) LogEmbeddedICMPHeader(log, orig_p->icmph); break; default: TextLog_Print(log, "Protocol: 0x%X (unknown or " "header truncated)", GET_IPH_PROTO(orig_p)); break; } /* switch */ /* if more than 8 bytes of original IP payload sent */ if (p->dsize - orig_ip_hlen > 8) { TextLog_Print(log, "(%d more bytes of original packet)\n", p->dsize - orig_ip_hlen - 8); } TextLog_Puts(log, "** END OF DUMP"); } else { TextLog_Puts(log, "\nORIGINAL DATAGRAM TRUNCATED"); } } /*-------------------------------------------------------------------- * Function: LogICMPHeader(TextLog* ) * * Purpose: Print ICMP header * * Arguments: log => pointer to TextLog * * Returns: void function *-------------------------------------------------------------------- */ void LogICMPHeader(TextLog* log, Packet * p) { /* 32 digits plus 7 colons and a NULL byte */ char buf[8*4 + 7 + 1]; if(p->icmph == NULL) { TextLog_Puts(log, "ICMP header truncated\n"); return; } TextLog_Print(log, "Type:%d Code:%d ", p->icmph->type, p->icmph->code); switch(p->icmph->type) { case ICMP_ECHOREPLY: TextLog_Print(log, "ID:%d Seq:%d ", ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq)); TextLog_Puts(log, "ECHO REPLY"); break; case ICMP_DEST_UNREACH: TextLog_Puts(log, "DESTINATION UNREACHABLE: "); switch(p->icmph->code) { case ICMP_NET_UNREACH: TextLog_Puts(log, "NET UNREACHABLE"); break; case ICMP_HOST_UNREACH: TextLog_Puts(log, "HOST UNREACHABLE"); break; case ICMP_PROT_UNREACH: TextLog_Puts(log, "PROTOCOL UNREACHABLE"); break; case ICMP_PORT_UNREACH: TextLog_Puts(log, "PORT UNREACHABLE"); break; case ICMP_FRAG_NEEDED: TextLog_Print(log, "FRAGMENTATION NEEDED, DF SET\n" "NEXT LINK MTU: %u", ntohs(p->icmph->s_icmp_nextmtu)); break; case ICMP_SR_FAILED: TextLog_Puts(log, "SOURCE ROUTE FAILED"); break; case ICMP_NET_UNKNOWN: TextLog_Puts(log, "NET UNKNOWN"); break; case ICMP_HOST_UNKNOWN: TextLog_Puts(log, "HOST UNKNOWN"); break; case ICMP_HOST_ISOLATED: TextLog_Puts(log, "HOST ISOLATED"); break; case ICMP_PKT_FILTERED_NET: TextLog_Puts(log, "ADMINISTRATIVELY PROHIBITED NETWORK FILTERED"); break; case ICMP_PKT_FILTERED_HOST: TextLog_Puts(log, "ADMINISTRATIVELY PROHIBITED HOST FILTERED"); break; case ICMP_NET_UNR_TOS: TextLog_Puts(log, "NET UNREACHABLE FOR TOS"); break; case ICMP_HOST_UNR_TOS: TextLog_Puts(log, "HOST UNREACHABLE FOR TOS"); break; case ICMP_PKT_FILTERED: TextLog_Puts(log, "ADMINISTRATIVELY PROHIBITED,\nPACKET FILTERED"); break; case ICMP_PREC_VIOLATION: TextLog_Puts(log, "PREC VIOLATION"); break; case ICMP_PREC_CUTOFF: TextLog_Puts(log, "PREC CUTOFF"); break; default: TextLog_Puts(log, "UNKNOWN"); break; } LogICMPEmbeddedIP(log, p); break; case ICMP_SOURCE_QUENCH: TextLog_Puts(log, "SOURCE QUENCH"); LogICMPEmbeddedIP(log, p); break; case ICMP_REDIRECT: TextLog_Puts(log, "REDIRECT"); switch(p->icmph->code) { case ICMP_REDIR_NET: TextLog_Puts(log, " NET"); break; case ICMP_REDIR_HOST: TextLog_Puts(log, " HOST"); break; case ICMP_REDIR_TOS_NET: TextLog_Puts(log, " TOS NET"); break; case ICMP_REDIR_TOS_HOST: TextLog_Puts(log, " TOS HOST"); break; } /* written this way since inet_ntoa was typedef'ed to use sfip_ntoa * which requires sfcidr_t instead of inaddr's. This call to inet_ntoa * is a rare case that doesn't use sfcidr_t's. */ // XXX-IPv6 NOT YET IMPLEMENTED - IPV6 addresses technically not supported - need to change ICMP /* no inet_ntop in Windows */ sfip_raw_ntop(AF_INET, (const void *)(&p->icmph->s_icmp_gwaddr.s_addr), buf, sizeof(buf)); TextLog_Print(log, " NEW GW: %s", buf); LogICMPEmbeddedIP(log, p); break; case ICMP_ECHO: TextLog_Print(log, "ID:%d Seq:%d ", ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq)); TextLog_Puts(log, "ECHO"); break; case ICMP_ROUTER_ADVERTISE: TextLog_Print(log, "ROUTER ADVERTISMENT: " "Num addrs: %d Addr entry size: %d Lifetime: %u", p->icmph->s_icmp_num_addrs, p->icmph->s_icmp_wpa, ntohs(p->icmph->s_icmp_lifetime)); break; case ICMP_ROUTER_SOLICIT: TextLog_Puts(log, "ROUTER SOLICITATION"); break; case ICMP_TIME_EXCEEDED: TextLog_Puts(log, "TTL EXCEEDED"); switch(p->icmph->code) { case ICMP_TIMEOUT_TRANSIT: TextLog_Puts(log, " IN TRANSIT"); break; case ICMP_TIMEOUT_REASSY: TextLog_Puts(log, " TIME EXCEEDED IN FRAG REASSEMBLY"); break; } LogICMPEmbeddedIP(log, p); break; case ICMP_PARAMETERPROB: TextLog_Puts(log, "PARAMETER PROBLEM"); switch(p->icmph->code) { case ICMP_PARAM_BADIPHDR: TextLog_Print(log, ": BAD IP HEADER BYTE %u", p->icmph->s_icmp_pptr); break; case ICMP_PARAM_OPTMISSING: TextLog_Puts(log, ": OPTION MISSING"); break; case ICMP_PARAM_BAD_LENGTH: TextLog_Puts(log, ": BAD LENGTH"); break; } LogICMPEmbeddedIP(log, p); break; case ICMP_TIMESTAMP: TextLog_Print(log, "ID: %u Seq: %u TIMESTAMP REQUEST", ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq)); break; case ICMP_TIMESTAMPREPLY: TextLog_Print(log, "ID: %u Seq: %u TIMESTAMP REPLY:\n" "Orig: %u Rtime: %u Ttime: %u", ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq), p->icmph->s_icmp_otime, p->icmph->s_icmp_rtime, p->icmph->s_icmp_ttime); break; case ICMP_INFO_REQUEST: TextLog_Print(log, "ID: %u Seq: %u INFO REQUEST", ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq)); break; case ICMP_INFO_REPLY: TextLog_Print(log, "ID: %u Seq: %u INFO REPLY", ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq)); break; case ICMP_ADDRESS: TextLog_Print(log, "ID: %u Seq: %u ADDRESS REQUEST", ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq)); break; case ICMP_ADDRESSREPLY: TextLog_Print(log, "ID: %u Seq: %u ADDRESS REPLY: 0x%08X", ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq), (u_int) ntohl(p->icmph->s_icmp_mask)); break; default: TextLog_Puts(log, "UNKNOWN"); break; } TextLog_NewLine(log); } /*-------------------------------------------------------------------- * reference stuff cloned from signature.c *-------------------------------------------------------------------- */ /* print a reference node */ static void LogReference(TextLog* log, ReferenceNode *refNode) { if(refNode) { if(refNode->system) { if(refNode->system->url) TextLog_Print(log, "[Xref => %s%s]", refNode->system->url, refNode->id); else TextLog_Print(log, "[Xref => %s %s]", refNode->system->name, refNode->id); } else { TextLog_Print(log, "[Xref => %s]", refNode->id); } } return; } /* * Function: LogXrefs(TextLog* ) * * Purpose: Prints out cross reference data associated with an alert * * Arguments: log => pointer to TextLog to write the data to * doNewLine => tack a \n to the end of the line or not (bool) * * Returns: void function */ void LogXrefs(TextLog* log, bool doNewLine) { ReferenceNode *refNode = NULL; if(otn_tmp) { refNode = otn_tmp->sigInfo.refs; while(refNode != NULL) { LogReference(log, refNode); refNode = refNode->next; /* on the last loop through, print a newline in Full mode */ if(doNewLine && (refNode == NULL)) TextLog_NewLine(log); } } } /*-------------------------------------------------------------------- * payload stuff cloned from log.c *-------------------------------------------------------------------- */ /*-------------------------------------------------------------------- * Function: ScOutputCharData(TextLog*, char*, int) * * Purpose: Dump the printable ASCII data from a packet * * Arguments: log => ptr to TextLog to print to * data => pointer to buffer data * len => length of data buffer * * Returns: void function *-------------------------------------------------------------------- */ static void LogCharData(TextLog* log, const char *data, int len) { const char* pb = data; const char* end = data + len; int lineCount = 0; if ( !data ) { return; } while ( pb < end ) { if ( *pb > 0x1F && *pb < 0x7F) { /* printable */ TextLog_Putc(log, *pb); } else { /* not printable */ TextLog_Putc(log, '.'); } if ( ++lineCount == 64 ) { TextLog_Putc(log, ' '); TextLog_NewLine(log); lineCount = 0; } pb++; } /* slam a \n on the back */ TextLog_Putc(log, ' '); TextLog_NewLine(log); TextLog_Putc(log, ' '); } /* * Function: LogNetData(TextLog*, u_char *,int, Packet *) * * Purpose: Do a side by side dump of a buffer, hex on * the left, decoded ASCII on the right. * * Arguments: log => ptr to TextLog to print to * data => pointer to buffer data * len => length of data buffer * * Returns: void function */ #define BYTES_PER_FRAME 16 /* middle of packet:"41 02 43 04 45 06 47 08 49 0A 4B 0C 4D 0E 4F 0F A.C.E.G.I.K.M.O."*/ /* at end of packet:"41 02 43 04 45 06 47 08 A.C.E.G."*/ static char* pad3 = " "; static void LogNetData (TextLog* log, const u_char* data, const int len, Packet *p) { const u_char* pb = data; const u_char* end = data + len; int offset = 0; char conv[] = "0123456789ABCDEF"; /* xlation lookup table */ int next_layer, ip_start, ip_ob_start, ip_ob_end, byte_pos, char_pos; int i; next_layer = ip_start = byte_pos = char_pos = 0; ip_ob_start = ip_ob_end = -1; if ( !len ) { TextLog_NewLine(log); return; } if ( !data ) { TextLog_Print(log, "Got NULL ptr in LogNetData()\n"); return; } if ( len > IP_MAXPACKET ) { if (ScLogVerbose()) { TextLog_Print( log, "Got bogus buffer length (%d) for LogNetData, " "defaulting to %d bytes!\n", len, BYTES_PER_FRAME ); } end = data + BYTES_PER_FRAME; } if(p && ScObfuscate() ) { next_layer = p->next_layer; for ( i = 0; i < next_layer; i++ ) { if ( p->layers[i].proto == PROTO_IP4 || p->layers[i].proto == PROTO_IP6 ) { if(p->layers[i].length && p->layers[i].start) break; } } ip_start = p->layers[i].start - data; if(ip_start > 0 ) { ip_ob_start = ip_start + 10; if(p->layers[i].proto == PROTO_IP4) ip_ob_end = ip_ob_start + 2 + 2*(sizeof(struct in_addr)); else ip_ob_end = ip_ob_start + 2 + 2*(sizeof(struct in6_addr)); } } /* loop thru the whole buffer */ while ( pb < end ) { i = 0; if (ScVerboseByteDump()) { TextLog_Print(log, "0x%04X: ", offset); offset += BYTES_PER_FRAME; } /* process one frame */ /* first print the binary as ascii hex */ for (i = 0; i < BYTES_PER_FRAME && pb+i < end; i++, byte_pos++) { if(ScObfuscate() && ((byte_pos >= ip_ob_start) && (byte_pos < ip_ob_end))) { TextLog_Putc(log, 'X'); TextLog_Putc(log, 'X'); TextLog_Putc(log, ' '); } else { char b = pb[i]; TextLog_Putc(log, conv[(b & 0xFF) >> 4]); TextLog_Putc(log, conv[(b & 0xFF) & 0x0F]); TextLog_Putc(log, ' '); } } /* print ' ' past end of packet and before ascii */ TextLog_Puts(log, pad3+(3*i)); /* then print the actual ascii chars */ /* or a '.' for control chars */ for (i = 0; i < BYTES_PER_FRAME && pb+i < end; i++, char_pos++) { if(ScObfuscate() && ((char_pos >= ip_ob_start) && (char_pos < ip_ob_end))) { TextLog_Putc(log, 'X'); } else { char b = pb[i]; if ( b > 0x1F && b < 0x7F) TextLog_Putc(log, (char)(b & 0xFF)); else TextLog_Putc(log, '.'); } } pb += BYTES_PER_FRAME; TextLog_NewLine(log); } TextLog_NewLine(log); } #define SEPARATOR \ "=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+" static int LogObfuscatedData(TextLog* log, Packet *p) { uint8_t *payload = NULL; uint16_t payload_len = 0; if (obApi->getObfuscatedPayload(p, &payload, (uint16_t *)&payload_len) != OB_RET_SUCCESS) { return -1; } /* dump the application layer data */ if (ScOutputAppData() && !ScVerboseByteDump()) { if (ScOutputCharData()) LogCharData(log, (char *)payload, payload_len); else LogNetData(log, payload, payload_len, NULL); } else if (ScVerboseByteDump()) { uint8_t buf[UINT16_MAX]; uint16_t dlen = p->data - p->pkt; int ret; ret = SafeMemcpy(buf, p->pkt, dlen, buf, buf + sizeof(buf)); if (ret != SAFEMEM_SUCCESS) { DEBUG_WRAP(DebugMessage(DEBUG_LOG, "%s: SafeMemcpy() Failed !!!", __FUNCTION__);) free(payload); return -1; } ret = SafeMemcpy(buf + dlen, payload, payload_len, buf, buf + sizeof(buf)); if (ret != SAFEMEM_SUCCESS) { DEBUG_WRAP(DebugMessage(DEBUG_LOG, "%s: SafeMemcpy() Failed !!!", __FUNCTION__);) free(payload); return -1; } LogNetData(log, buf, dlen + payload_len, NULL); } TextLog_Print(log, "%s\n\n", SEPARATOR); free(payload); return 0; } /*-------------------------------------------------------------------- * Function: LogIPPkt(TextLog*, int, Packet *) * * Purpose: Dump the packet to the given TextLog * * Arguments: log => pointer to print data to * type => packet protocol * p => pointer to decoded packet struct * * Returns: void function *-------------------------------------------------------------------- */ #define DATA_PTR(p) \ ((u_char*)p->iph + (GET_IPH_HLEN(p) << 2)) #define DATA_LEN(p) \ (p->actual_ip_len - (GET_IPH_HLEN(p) << 2)) void LogIPPkt(TextLog* log, int type, Packet * p) { DEBUG_WRAP(DebugMessage(DEBUG_LOG, "LogIPPkt type = %d\n", type);); /* dump the timestamp */ LogTimeStamp(log, p); /* dump the ethernet header if we're doing that sort of thing */ if ( ScOutputDataLink() ) { Log2ndHeader(log, p); #ifdef MPLS if ( p->mpls ) { LogMPLSHeader(log, p); } #endif #ifdef GRE if ( p->outer_iph ) { LogOuterIPHeader(log, p); if ( p->greh ) LogGREHeader(log, p); } #endif } LogIPHeader(log, p); /* if this isn't a fragment, print the other header info */ if ( !p->frag_flag ) { switch (GET_IPH_PROTO(p)) { case IPPROTO_TCP: if ( p->tcph != NULL ) { LogTCPHeader(log, p); } else { LogNetData(log, DATA_PTR(p), DATA_LEN(p), NULL); } break; case IPPROTO_UDP: if ( p->udph != NULL ) { LogUDPHeader(log, p); } else { LogNetData(log, DATA_PTR(p), DATA_LEN(p), NULL); } break; case IPPROTO_ICMP: if ( p->icmph != NULL ) { LogICMPHeader(log, p); } else { LogNetData(log, DATA_PTR(p), GET_IP_PAYLEN(p), NULL); } break; default: break; } } if ((p->dsize > 0) && obApi->payloadObfuscationRequired(p) && (LogObfuscatedData(log, p) == 0)) { return; } /* dump the application layer data */ if (ScOutputAppData() && !ScVerboseByteDump()) { if (ScOutputCharData()) { LogCharData(log, (char *)p->data, p->dsize); if(!IsJSNormData(p->ssnptr)) { TextLog_Print(log, "%s\n", "Normalized JavaScript for this packet"); LogCharData(log, (const char*)file_data_ptr.data, file_data_ptr.len); } else if(!IsGzipData(p->ssnptr)) { TextLog_Print(log, "%s\n", "Decompressed Data for this packet"); LogCharData(log, (const char *)file_data_ptr.data, file_data_ptr.len); } } else { LogNetData(log, p->data, p->dsize, NULL); if(!IsJSNormData(p->ssnptr)) { TextLog_Print(log, "%s\n", "Normalized JavaScript for this packet"); LogNetData(log, file_data_ptr.data, file_data_ptr.len, NULL); } else if(!IsGzipData(p->ssnptr)) { TextLog_Print(log, "%s\n", "Decompressed Data for this packet"); LogNetData(log, file_data_ptr.data, file_data_ptr.len, NULL); } } } else if (ScVerboseByteDump()) { LogNetData(log, p->pkt, p->pkth->caplen, p); } TextLog_Print(log, "%s\n\n", SEPARATOR); } #ifndef NO_NON_ETHER_DECODER /*-------------------------------------------------------------------- * ARP stuff cloned from log.c *-------------------------------------------------------------------- */ void LogArpHeader(TextLog* log, Packet * p) { // XXX-IPv6 "NOT YET IMPLEMENTED - printing ARP header" } #endif // NO_NON_ETHER_DECODER #ifdef DUMP_BUFFER /*-------------------------------------------------------------------- * Function to dump the buffers used by snort during packet * processing and inspection *-------------------------------------------------------------------- */ void LogBuffer(TextLog *log, char *name, char *data, const int len) { int i = 0, j; char conv[] = "0123456789ABCDEF"; TextLog_Print(log, "\n%s, %d\n", name, len); while (i < len) { TextLog_Print(log, "\n%.8x ",i); for (j = 0; j < BYTES_PER_FRAME; j++) { if (j == (BYTES_PER_FRAME/2)) { TextLog_Putc(log, ' '); } if ((i+j) < len) { char b = data[j + i]; TextLog_Putc(log, conv[(b & 0xFF) >> 4]); TextLog_Putc(log, conv[(b & 0xFF) & 0x0F]); TextLog_Putc(log, ' '); } else { TextLog_Putc(log, ' '); TextLog_Putc(log, ' '); TextLog_Putc(log, ' '); } } TextLog_Putc(log, ' '); TextLog_Putc(log, '|'); for (j = 0; j < BYTES_PER_FRAME; j++) { if ((i+j) < len) { char b = data[j + i]; if ( b > 0x1F && b < 0x7F) { TextLog_Putc(log, (char)(b & 0xFF)); } else { TextLog_Putc(log, '.'); } } else { TextLog_Putc(log, ' '); } } TextLog_Putc(log, '|'); i = i + j; } TextLog_Putc(log, '\n'); } #endif snort-2.9.15.1/src/log_text.h0000644000175200017520000000612313571422607012637 00000000000000 /**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2003-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /** * @file log_text.h * @author Russ Combs * @date Fri Jun 27 10:34:37 2003 * * @brief logging to text file * * Use these methods to write to a TextLog. */ #ifndef _LOG_TEXT_H #define _LOG_TEXT_H #include "sfutil/sf_textlog.h" void LogPriorityData(TextLog*, bool doNewLine); #if defined(FEAT_OPEN_APPID) void LogAppID(TextLog*, const char* appName, bool doNewLine); #endif void LogXrefs(TextLog*, bool doNewLine); void LogIPPkt(TextLog*, int type, Packet*); void LogTimeStamp(TextLog*, Packet*); void LogTrHeader(TextLog*, Packet*); void Log2ndHeader(TextLog*, Packet*); void LogIpAddrs(TextLog*, Packet*); void LogIPHeader(TextLog*, Packet*); void LogTCPHeader(TextLog*, Packet*); void LogUDPHeader(TextLog*, Packet*); void LogICMPHeader(TextLog*, Packet*); void LogArpHeader(TextLog*, Packet*); #ifdef DUMP_BUFFER void LogBuffer(TextLog *, char *, char *, const int); #endif #if 0 /* these are implemented in log_text.c but not public */ static void LogEthHeader(TextLog*, Packet*); static void LogSLLHeader(TextLog*, Packet*); static void LogWifiHeader(TextLog*, Packet*); static void LogIpOptions(TextLog* , Packet*); static void LogTcpOptions(TextLog*, Packet*); static void LogEmbeddedICMPHeader(TextLog*, const ICMPHdr*); static void LogICMPEmbeddedIP(TextLog*, Packet*); static void LogReference(TextLog*, ReferenceNode*); static void ScOutputCharData(TextLog*, char* data, int len); static void LogNetData (TextLog*, const u_char* data, const int len, Packet *); #endif #if 0 /* these are only in log.c: */ /* called from snort.c: */ void PrintEapolPkt(FILE*, Packet*); /* *Key() and *Header() should be static/private */ void PrintEapolKey(FILE*, Packet*); void PrintEapolHeader(FILE*, Packet*); void PrintEAPHeader(FILE*, Packet*); /* commented out all over the place! */ /* still called in snort.c and spp_stream4.c */ void ClearDumpBuf(void); /* called from snort.c */ void PrintWifiPkt(FILE*, Packet*); /* called in a few places including log_text.c */ void CreateTCPFlagString(Packet*, char*); #endif #endif /* _LOG_TEXT_H */ snort-2.9.15.1/src/detection_filter.c0000644000175200017520000000734713571422607014341 00000000000000/* $Id$ */ /**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2003-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "mstring.h" #include "util.h" #include "parser.h" #include "sfthd.h" #include "snort.h" #ifndef WIN32 #include #include #include #endif static SFXHASH *detection_filter_hash = NULL; DetectionFilterConfig * DetectionFilterConfigNew(void) { DetectionFilterConfig *df = (DetectionFilterConfig *)SnortAlloc(sizeof(DetectionFilterConfig)); df->memcap = 1024 * 1024; df->enabled = 1; return df; } void DetectionFilterConfigFree(DetectionFilterConfig *config) { if (config == NULL) return; free(config); } void detection_filter_cleanup(void) { if (detection_filter_hash == NULL) return; sfxhash_delete(detection_filter_hash); detection_filter_hash = NULL; } /* * Startup Display */ void detection_filter_print_config(DetectionFilterConfig *df) { //int i, gcnt=0; //THD_NODE * thd; if (df == NULL) return; LogMessage("\n"); LogMessage("+-----------------------[detection-filter-config]" "------------------------------\n"); LogMessage("| memory-cap : %d bytes\n", df->memcap); LogMessage("+-----------------------[detection-filter-rules]" "-------------------------------\n"); if( !df->count) { LogMessage("| none\n"); } else { //print_thd_local(s_thd, PRINT_LOCAL ); } LogMessage("------------------------------------------------" "-------------------------------\n"); } int detection_filter_test ( void* pv, sfaddr_t* sip, sfaddr_t* dip, long curtime, detection_option_eval_data_t *eval_data) { if (pv == NULL) return 0; return sfthd_test_rule(detection_filter_hash, (THD_NODE*)pv, sip, dip, curtime, eval_data); } /* empty out active entries */ void detection_filter_reset_active(void) { if (detection_filter_hash == NULL) return; sfxhash_make_empty(detection_filter_hash); } void * detection_filter_create(DetectionFilterConfig *df_config, THDX_STRUCT *thdx) { if (df_config == NULL) return NULL; if (!df_config->enabled) return NULL; /* Auto init - memcap must be set 1st, which is not really a problem */ if (detection_filter_hash == NULL) { detection_filter_hash = sfthd_local_new(df_config->memcap); if (detection_filter_hash == NULL) return NULL; } df_config->count++; return sfthd_create_rule_threshold(df_config->count, thdx->tracking, thdx->type, thdx->count, thdx->seconds); } snort-2.9.15.1/src/detection_filter.h0000644000175200017520000000434113571422607014335 00000000000000/* $Id$ */ /**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2003-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #ifndef _DETECTION_FILTER_H_ #define _DETECTION_FILTER_H_ // the use of threshold standalone, in config, and in rules is deprecated. // - standalone and config are replaced with event_filter. // - within a rule is replaced with detection_filter. // // both detection_filter and event_filter use the same basic mechanism. // however, detection_filter is evaluated as the final step in rule matching. // and thereby controls event generation. event_filter is evaluated after // the event is queued, and thereby controls which events get logged. #include "sfthreshold.h" #include "ipv6_port.h" typedef struct _DetectionFilterConfig { int count; int memcap; int enabled; } DetectionFilterConfig; DetectionFilterConfig * DetectionFilterConfigNew(void); void DetectionFilterConfigFree(DetectionFilterConfig *); int detection_filter_init( void ); void detection_filter_cleanup( void ); void detection_filter_print_config(DetectionFilterConfig *); void detection_filter_reset_active(void); int detection_filter_test(void*, sfaddr_t* sip, sfaddr_t* dip, long curtime, detection_option_eval_data_t *eval_data); void * detection_filter_create(DetectionFilterConfig *, THDX_STRUCT *); #endif snort-2.9.15.1/src/detection_util.c0000644000175200017520000001236113571422607014021 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "detection_util.h" #include "sfutil/sf_textlog.h" #include "rules.h" #include "snort.h" uint8_t base64_decode_buf[DECODE_BLEN]; uint32_t base64_decode_size; uint8_t mime_present; const uint8_t *doe_ptr; uint8_t doe_buf_flags; uint16_t detect_flags; uint32_t http_mask; HttpBuffer http_buffer[HTTP_BUFFER_MAX]; DataPointer DetectBuffer; DataPointer file_data_ptr; DataBuffer DecodeBuffer; void *global_ssl_callback = NULL; const char* http_buffer_name[HTTP_BUFFER_MAX] = { "error/unset", "http_uri", "http_header", "http_client_body", "http_method", "http_cookie", "http_stat_code", "http_stat_msg", "http_raw_uri", "http_raw_header", "http_raw_cookie", }; static const char* rule_type[RULE_TYPE__MAX] = { "none", "alert", "drop", "log", "pass", "reject", "sdrop" }; #define LOG_CHARS 16 static TextLog* tlog = NULL; static unsigned nEvents = 0; static void LogBuffer (const char* s, const uint8_t* p, unsigned n) { char hex[(3*LOG_CHARS)+1]; char txt[LOG_CHARS+1]; unsigned odx = 0, idx = 0, at = 0; if ( !p ) return; if ( n > snort_conf->event_trace_max ) n = snort_conf->event_trace_max; for ( idx = 0; idx < n; idx++) { uint8_t byte = p[idx]; sprintf(hex + 3*odx, "%2.02X ", byte); txt[odx++] = isprint(byte) ? byte : '.'; if ( odx == LOG_CHARS ) { txt[odx] = hex[3*odx] = '\0'; TextLog_Print(tlog, "%s[%2u] %s %s\n", s, at, hex, txt); at = idx + 1; odx = 0; } } if ( odx ) { txt[odx] = hex[3*odx] = '\0'; TextLog_Print(tlog, "%s[%2u] %-48.48s %s\n", s, at, hex, txt); } } void EventTrace_Log (const Packet* p, OptTreeNode* otn, int action) { int i; const char* acts = (action < RULE_TYPE__MAX) ? rule_type[action] : "ERROR"; if ( !tlog ) return; TextLog_Print(tlog, "\nEvt=%u, Gid=%u, Sid=%u, Rev=%u, Act=%s\n", event_id, otn->sigInfo.generator, otn->sigInfo.id, otn->sigInfo.rev, acts ); TextLog_Print(tlog, "Pkt=%lu, Sec=%u.%6u, Len=%u, Cap=%u\n", pc.total_from_daq, p->pkth->ts.tv_sec, p->pkth->ts.tv_usec, p->pkth->pktlen, p->pkth->caplen ); TextLog_Print(tlog, "Pkt Bits: Flags=0x%X, PP=0x%llx, Proto=0x%X" ", Err=0x%X\n", p->packet_flags, p->preprocessor_bits, (unsigned)p->proto_bits, (unsigned)p->error_flags ); TextLog_Print(tlog, "Pkt Cnts: Dsz=%u, Alt=%u, Uri=0x%X\n", (unsigned)p->dsize, (unsigned)p->alt_dsize, http_mask ); TextLog_Print(tlog, "Detect: DoeFlags=0x%X, DetectFlags=0x%X, DetBuf=%u, B64=%u\n", doe_buf_flags, detect_flags, DetectBuffer.len, base64_decode_size ); LogBuffer("Decode", DecodeBuffer.data, DecodeBuffer.len); LogBuffer("Detect", DetectBuffer.data, DetectBuffer.len); LogBuffer("FileData", file_data_ptr.data, file_data_ptr.len); LogBuffer("Base64", base64_decode_buf, base64_decode_size); if(mime_present) LogBuffer("Mime", file_data_ptr.data, file_data_ptr.len); for ( i = 0; i < HTTP_BUFFER_MAX; i++ ) { const HttpBuffer* hb = GetHttpBuffer(i); if ( !hb ) continue; TextLog_Print(tlog, "%s[%u] = 0x%X\n", http_buffer_name[i], hb->length, hb->encode_type); LogBuffer(http_buffer_name[i], hb->buf, hb->length); } nEvents++; } void EventTrace_Init (void) { if ( snort_conf->event_trace_max > 0 ) { time_t now = time(NULL); const char* ts = ctime(&now); char buf[STD_BUF]; const char* dir = snort_conf->log_dir ? snort_conf->log_dir : "."; snprintf(buf, sizeof(buf), "%s/%s", dir, snort_conf->event_trace_file); tlog = TextLog_Init (buf, 128, 8*1024*1024); TextLog_Print(tlog, "\nTrace started at %s", ts); TextLog_Print(tlog, "Trace max_data is %u bytes\n", snort_conf->event_trace_max); } } void EventTrace_Term (void) { if ( tlog ) { time_t now = time(NULL); const char* ts = ctime(&now); TextLog_Print(tlog, "\nTraced %u events\n", nEvents); TextLog_Print(tlog, "Trace stopped at %s", ts); TextLog_Term(tlog); } } snort-2.9.15.1/src/detection_util.h0000644000175200017520000001702413571422607014027 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** ** Description ** This file contains the utility functions used by rule options. ** */ #ifndef __DETECTION_UTIL_H__ #define __DETECTION_UTIL_H__ #include #include "sf_types.h" #include "decode.h" #include "detect.h" #include "snort.h" #include "snort_debug.h" #include "treenodes.h" #ifndef DECODE_BLEN #define DECODE_BLEN 65535 #define MAX_URI 8192 // NOTE - if you change these, you must also change: // dynamic-plugins/sf_dynamic_common.h // dynamic-plugins/sf_dynamic_define.h // dynamic-plugins/sf_engine/sf_snort_plugin_api.h // detection-plugins/sp_pcre.h typedef enum { HTTP_BUFFER_NONE, HTTP_BUFFER_URI, HTTP_BUFFER_HEADER, HTTP_BUFFER_CLIENT_BODY, HTTP_BUFFER_METHOD, HTTP_BUFFER_COOKIE, HTTP_BUFFER_STAT_CODE, HTTP_BUFFER_STAT_MSG, HTTP_BUFFER_RAW_URI, HTTP_BUFFER_RAW_HEADER, HTTP_BUFFER_RAW_COOKIE, HTTP_BUFFER_MAX } HTTP_BUFFER; #endif typedef enum { FLAG_ALT_DECODE = 0x0001, FLAG_ALT_DETECT = 0x0002, FLAG_DETECT_ALL = 0xffff } DetectFlagType; #define DOE_BUF_URI 0x01 #define DOE_BUF_STD 0x02 #define HTTPURI_PIPELINE_REQ 0x01 #define HTTP_ENCODE_TYPE__UTF8_UNICODE 0x00000001 #define HTTP_ENCODE_TYPE__DOUBLE_ENCODE 0x00000002 #define HTTP_ENCODE_TYPE__NONASCII 0x00000004 #define HTTP_ENCODE_TYPE__BASE36 0x00000008 #define HTTP_ENCODE_TYPE__UENCODE 0x00000010 #define HTTP_ENCODE_TYPE__BARE_BYTE 0x00000020 #define HTTP_ENCODE_TYPE__IIS_UNICODE 0x00000040 #define HTTP_ENCODE_TYPE__ASCII 0x00000080 typedef struct { const uint8_t* buf; uint16_t length; uint32_t encode_type; } HttpBuffer; typedef struct { const uint8_t *data; uint16_t len; } DataPointer; typedef struct { uint8_t data[DECODE_BLEN]; uint16_t len; } DataBuffer; extern uint8_t base64_decode_buf[DECODE_BLEN]; extern uint32_t base64_decode_size; extern uint8_t mime_present; extern uint8_t doe_buf_flags; extern const uint8_t *doe_ptr; extern void *global_ssl_callback; extern uint16_t detect_flags; extern uint32_t http_mask; extern HttpBuffer http_buffer[HTTP_BUFFER_MAX]; extern const char* http_buffer_name[HTTP_BUFFER_MAX]; extern DataPointer DetectBuffer; extern DataPointer file_data_ptr; extern DataBuffer DecodeBuffer; static inline void ClearHttpBuffers (void) { http_mask = 0; } static inline uint32_t GetHttpBufferMask (void) { return http_mask; } static inline const HttpBuffer* GetHttpBuffer (HTTP_BUFFER b) { if ( !((1 << b) & http_mask) ) return NULL; return http_buffer + b; } static inline void SetHttpBufferEncoding ( HTTP_BUFFER b, const uint8_t* buf, unsigned len, uint32_t enc) { HttpBuffer* hb = http_buffer + b; assert(b < HTTP_BUFFER_MAX && buf); hb->buf = buf; hb->length = len; hb->encode_type = enc; http_mask |= (1 << b); } static inline void SetHttpBuffer (HTTP_BUFFER b, const uint8_t* buf, unsigned len) { SetHttpBufferEncoding(b, buf, len, 0); } #define SetDetectLimit(pktPtr, altLen) \ { \ pktPtr->alt_dsize = altLen; \ } #define IsLimitedDetect(pktPtr) (pktPtr->packet_flags & PKT_HTTP_DECODE) /* * Function: setFileDataPtr * * Purpose: Sets the file data pointer used by * file_data rule option. * * Arguments: ptr => pointer to the body data * * Returns: void * */ static inline void setFileDataPtr(const uint8_t *ptr, uint16_t decode_size) { file_data_ptr.data = ptr; file_data_ptr.len = decode_size; } /* * Function: IsBase64DecodeBuf * * Purpose: Checks if there is base64 decoded buffer. * * Arguments: p => doe_ptr * * Returns: Returns 1 if there is base64 decoded data * and if the doe_ptr is within the buffer. * Returns 0 otherwise. * */ static inline int IsBase64DecodeBuf(const uint8_t *p) { if( base64_decode_size && p ) { if ((p >= base64_decode_buf) && (p < (base64_decode_buf + base64_decode_size))) { return 1; } else return 0; } else return 0; } /* * Function: SetDoePtr(const uint8_t *ptr, uint8_t type) * * Purpose: This function set the doe_ptr and sets the type of * buffer to which doe_ptr points. * * Arguments: ptr => pointer * type => type of buffer * * Returns: void * */ static inline void SetDoePtr(const uint8_t *ptr, uint8_t type) { doe_ptr = ptr; doe_buf_flags = type; } /* * Function: UpdateDoePtr(const uint8_t *ptr, uint8_t update) * * Purpose: This function updates the doe_ptr and resets the type of * buffer to which doe_ptr points based on the update value. * * Arguments: ptr => pointer * update => reset the buf flag if update is not zero. * * Returns: void * */ static inline void UpdateDoePtr(const uint8_t *ptr, uint8_t update) { doe_ptr = ptr; if(update) doe_buf_flags = DOE_BUF_STD; } void EventTrace_Init(void); void EventTrace_Term(void); void EventTrace_Log(const Packet*, OptTreeNode*, int action); static inline int EventTrace_IsEnabled (void) { return ( snort_conf->event_trace_max > 0 ); } static inline void DetectFlag_Enable(DetectFlagType df) { detect_flags |= df; } static inline void DetectFlag_Disable(DetectFlagType df) { detect_flags &= ~df; } static inline int Is_DetectFlag(DetectFlagType df) { return ( (detect_flags & df) != 0 ); } static inline uint16_t Get_DetectFlags(void) { return detect_flags; } static inline void Reset_DetectFlags(uint16_t dflags) { detect_flags = dflags; } static inline void SetSSLCallback(void *p) { global_ssl_callback = p; } static inline void *GetSSLCallback(void) { return global_ssl_callback; } static inline int GetAltDetect(uint8_t **bufPtr, uint16_t *altLenPtr) { if ( Is_DetectFlag(FLAG_ALT_DETECT) ) { *bufPtr = (uint8_t*) DetectBuffer.data; *altLenPtr = DetectBuffer.len; return 1; } return 0; } static inline void SetAltDetect(const uint8_t *buf, uint16_t altLen) { DetectFlag_Enable(FLAG_ALT_DETECT); DetectBuffer.data = buf; DetectBuffer.len = altLen; } static inline void SetAltDecode(uint16_t altLen) { DetectFlag_Enable(FLAG_ALT_DECODE); DecodeBuffer.len = altLen; } static inline void DetectReset(const uint8_t *buf, uint16_t altLen) { DetectBuffer.data = buf; DetectBuffer.len = altLen; DetectFlag_Disable(FLAG_DETECT_ALL); /* Reset the values */ file_data_ptr.data = NULL; file_data_ptr.len = 0; base64_decode_size = 0; doe_buf_flags = 0; mime_present = 0; DecodeBuffer.len = 0; } #endif snort-2.9.15.1/src/rate_filter.c0000644000175200017520000001662113571422607013311 00000000000000/* $Id$ */ /**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2009-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* @file rate_filter.c * @brief rate filter interface for Snort * @ingroup rate_filter * @author Dilbagh Chahal */ /* @ingroup rate_filter * @{ */ #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "mstring.h" #include "util.h" #include "parser.h" #include "rate_filter.h" #include "sfrf.h" #include "snort.h" #include "sfthd.h" #ifndef WIN32 #include #include #include #endif #include #include "stream_api.h" #include "generators.h" static int _logConfigNode(tSFRFConfigNode*); static int _printThresholdContext(RateFilterConfig*); RateFilterConfig* RateFilter_ConfigNew(void) { RateFilterConfig *rf_config = (RateFilterConfig *)SnortAlloc(sizeof(*rf_config)); rf_config->memcap = 1024 * 1024; return rf_config; } /* Free threshold context * @param pContext pointer to global threshold context. */ void RateFilter_ConfigFree(RateFilterConfig *config) { int i; if (config == NULL) return; for (i = 0; i < SFRF_MAX_GENID; i++) { if (config->genHash[i] != NULL) sfghash_delete(config->genHash[i]); } free(config); } void RateFilter_Cleanup(void) { SFRF_Delete(); } /* * Create and Add a Thresholding Event Object */ int RateFilter_Create(SnortConfig *sc, RateFilterConfig *rf_config, tSFRFConfigNode *thdx) { int error; if (rf_config == NULL) return -1; #ifdef RF_DBG printf( "THRESHOLD: gid=%u, sid=%u, tracking=%d, count=%d, seconds=%d \n", thdx->gid, thdx->sid, thdx->tracking, thdx->count, thdx->seconds); } #endif /* Add the object to the table - */ error = SFRF_ConfigAdd(sc, rf_config, thdx); // enable internal events as required if ( !error && EventIsInternal(thdx->gid) ) { EnableInternalEvent(rf_config, thdx->sid); if ( thdx->sid == INTERNAL_EVENT_SESSION_ADD ) EnableInternalEvent(rf_config, INTERNAL_EVENT_SESSION_DEL); } return error; } /* Test an event against the threshold object table to determine if the new_action should be applied. returns 1 - rate threshold reached 0 - rate threshold not reached */ int RateFilter_Test( OptTreeNode* otn, Packet* p) { unsigned gid = otn->event_data.sig_generator; unsigned sid = otn->event_data.sig_id; sfaddr_t* sip; sfaddr_t* dip; sfaddr_t cleared; if ( IPH_IS_VALID(p) ) { sip = GET_SRC_IP(p); dip = GET_DST_IP(p); } else { IP_CLEAR(cleared); sip = IP_ARG(cleared); dip = IP_ARG(cleared); } if ((snort_conf == NULL) || (snort_conf->rate_filter_config == NULL)) { /* this should not happen, see the create fcn */ return -1; } if ( EventIsInternal(gid) ) { // at present stream5 connection events are the only internal // events and these require: src -> client, dst -> server. if ( p->packet_flags & PKT_FROM_SERVER ) { return SFRF_TestThreshold( snort_conf->rate_filter_config, gid, sid, dip, sip, p->pkth->ts.tv_sec, SFRF_COUNT_INCREMENT); } } return SFRF_TestThreshold( snort_conf->rate_filter_config, gid, sid, sip, dip, p->pkth->ts.tv_sec, SFRF_COUNT_INCREMENT); } /* empty out active entries */ void RateFilter_ResetActive (void) { SFRF_Flush(); } /* * Startup Display Of Thresholding */ void RateFilter_PrintConfig(RateFilterConfig *config) { if (config == NULL) return; LogMessage("\n"); LogMessage("+-----------------------[rate-filter-config]" "-----------------------------------\n"); LogMessage("| memory-cap : %d bytes\n", config->memcap); LogMessage("+-----------------------[rate-filter-rules]-" "-----------------------------------\n"); if (config->count == 0) { LogMessage("| none\n"); } else { _printThresholdContext(config); } LogMessage("--------------------------------------------" "-----------------------------------\n"); } static int _logConfigNode( tSFRFConfigNode* p) { char* trackBy = "?"; char buf[STD_BUF+1]; *buf = '\0'; // SnortSnprintfAppend(buf, STD_BUF, "| thd-id=%d", p->thd_id ); if ( p->gid == 0 ) { SnortSnprintfAppend(buf, STD_BUF, "| gen-id=global"); } else { SnortSnprintfAppend(buf, STD_BUF, "| gen-id=%-6d", p->gid ); } if ( p->sid == 0 ) { SnortSnprintfAppend(buf, STD_BUF, " sig-id=global" ); } else { SnortSnprintfAppend(buf, STD_BUF, " sig-id=%-10d", p->sid ); } SnortSnprintfAppend(buf, STD_BUF, " policyId=%-10d", p->policyId ); switch ( p->tracking ) { case SFRF_TRACK_BY_SRC : trackBy = "src"; break; case SFRF_TRACK_BY_DST : trackBy = "dst"; break; case SFRF_TRACK_BY_RULE: trackBy = "rule"; break; default: break; } SnortSnprintfAppend(buf, STD_BUF, " tracking=%s", trackBy); SnortSnprintfAppend(buf, STD_BUF, " count=%-3d", p->count); SnortSnprintfAppend(buf, STD_BUF, " seconds=%-3d", p->seconds); LogMessage("%s\n", buf); return 1; } static int _printThresholdContext(RateFilterConfig *config) { int gid; int lcnt=0; if (config == NULL) return 0; for ( gid=0; gid < SFRF_MAX_GENID; gid++ ) { SFGHASH_NODE* item_hash_node; SFGHASH* sfrf_hash = config->genHash [ gid ]; if ( !sfrf_hash ) { continue; } for ( item_hash_node = sfghash_findfirst( sfrf_hash ); item_hash_node != 0; item_hash_node = sfghash_findnext( sfrf_hash ) ) { tSFRFSidNode* sfrf_item; tSFRFConfigNode* sfrf_node; /* Check for any Permanent sid objects for this gid */ sfrf_item = (tSFRFSidNode*)item_hash_node->data; for ( sfrf_node = (tSFRFConfigNode*)sflist_first(sfrf_item->configNodeList); sfrf_node != 0; sfrf_node = (tSFRFConfigNode*)sflist_next(sfrf_item->configNodeList) ) { if ( _logConfigNode( sfrf_node) != 0 ) lcnt++; } } } if ( ! lcnt ) LogMessage("| none\n"); return 0; } snort-2.9.15.1/src/rate_filter.h0000644000175200017520000000326513571422607013316 00000000000000/* $Id$ */ /**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2009-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #ifndef _RATE_FILTER_H_ #define _RATE_FILTER_H_ /* @file rate_filter.h * @brief rate filter interface for Snort * @ingroup rate_filter * @author Dilbagh Chahal */ /* @ingroup rate_filter * @{ */ #include "decode.h" #include "rules.h" #include "treenodes.h" RateFilterConfig * RateFilter_ConfigNew(void); void RateFilter_ConfigFree(RateFilterConfig *); void RateFilter_Cleanup(void); struct _SnortConfig; int RateFilter_Create(struct _SnortConfig *sc, RateFilterConfig *, tSFRFConfigNode *); void RateFilter_PrintConfig(RateFilterConfig *); int RateFilter_Test(OptTreeNode*, Packet*); void RateFilter_ResetActive(void); /*@}*/ #endif snort-2.9.15.1/src/pkt_tracer.c0000644000175200017520000005116013571422607013144 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** ** DESCRIPTION: ** Enables packet tracing to log verdicts from preprocessors. */ #include #include #include #include "sf_types.h" #include "decode.h" #include "util.h" #include "session_api.h" #include "active.h" #include "pkt_tracer.h" #include "preprocessors/Session/session_common.h" Verdict_Reason verdict_reason = VERDICT_REASON_NO_BLOCK; // preproc# causing a packet drop volatile int pkt_trace_cli_flag; // set by message socket bool pkt_trace_enabled; // set by pktTracerDebugCheck char trace_line[MAX_TRACE_LINE]; // used by preproc to write a trace #define MAX_TRACE_SIZE 2048 #define DEBUG_SESSION_ID_SIZE (39+1+5+4+39+1+5+1+3+1+1+1+2+1+10+1+1+1+10+1) typedef struct _DebugSessionConstraints { uint16_t trace_version; struct in6_addr sip; int sip_flag; struct in6_addr dip; int dip_flag; uint16_t sport; uint16_t dport; uint8_t protocol; } DebugSessionConstraints; static bool alreadySentTrace; static bool pkt_trace_enabled_by_lina; static bool pkt_trace_enabled_by_clish_bk; static bool pkt_trace_enabled_by_clish; static DebugSessionConstraints pkt_tracer_debug_info; static char pkt_tracer_debug_session[DEBUG_SESSION_ID_SIZE]; static char pkt_tracer_debug_session_bk[DEBUG_SESSION_ID_SIZE]; static char pktTraceData[MAX_TRACE_SIZE]; static uint32_t pktTraceDataLen = 0; static bool first_trace_line = true; static bool trace_line_info_received = false; static bool trace_line_appid_received = false; // Handling the special case when SSL blocks a packet before snort gets it static bool snort_received_packet = false; static bool ssl_callback_before_snort = false; static inline void debugParse(const char *desc, const uint8_t *data, uint32_t length, volatile int *debug_flag, DebugSessionConstraints *info) { *debug_flag = 0; memset(info, 0, sizeof(*info)); do { if (length >= sizeof(info->trace_version)) { memcpy(&info->trace_version, data, sizeof(info->trace_version)); length -= sizeof(info->trace_version); data += sizeof(info->trace_version); if (info->trace_version != 1) // 'system support trace' version 1 takes five tuples as input break; } else break; if (length >= sizeof(info->protocol)) { info->protocol = *data; length -= sizeof(info->protocol); data += sizeof(info->protocol); } else break; if (length >= sizeof(info->sip)) { memcpy(&info->sip, data, sizeof(info->sip)); if (info->sip.s6_addr32[1] || info->sip.s6_addr32[2] || info->sip.s6_addr32[3]) info->sip_flag = 1; else if (info->sip.s6_addr32[0]) { info->sip.s6_addr32[3] = info->sip.s6_addr32[0]; info->sip.s6_addr32[0] = 0; info->sip.s6_addr16[5] = 0xFFFF; info->sip_flag = 1; } length -= sizeof(info->sip); data += sizeof(info->sip); } else break; if (length >= sizeof(info->sport)) { memcpy(&info->sport, data, sizeof(info->sport)); length -= sizeof(info->sport); data += sizeof(info->sport); } else break; if (length >= sizeof(info->dip)) { memcpy(&info->dip, data, sizeof(info->dip)); if (info->dip.s6_addr32[1] || info->dip.s6_addr32[2] || info->dip.s6_addr32[3]) info->dip_flag = 1; else if (info->dip.s6_addr32[0]) { info->dip.s6_addr32[3] = info->dip.s6_addr32[0]; info->dip.s6_addr32[0] = 0; info->dip.s6_addr16[5] = 0xFFFF; info->dip_flag = 1; } length -= sizeof(info->dip); data += sizeof(info->dip); } else break; if (length >= sizeof(info->dport)) { memcpy(&info->dport, data, sizeof(info->dport)); length -= sizeof(info->dport); data += sizeof(info->dport); } else break; } while (0); if (info->protocol || info->sip_flag || info->sport || info->dip_flag || info->dport) { int saf; int daf; char sipstr[INET6_ADDRSTRLEN]; char dipstr[INET6_ADDRSTRLEN]; if (!info->sip.s6_addr32[0] && !info->sip.s6_addr32[0] && !info->sip.s6_addr16[4] && info->sip.s6_addr16[5] == 0xFFFF) { saf = AF_INET; } else saf = AF_INET6; if (!info->dip.s6_addr32[0] && !info->dip.s6_addr32[0] && !info->dip.s6_addr16[4] && info->dip.s6_addr16[5] == 0xFFFF) { daf = AF_INET; } else daf = AF_INET6; if (!info->sip_flag) saf = daf; if (!info->dip_flag) daf = saf; sipstr[0] = 0; inet_ntop(saf, saf == AF_INET ? &info->sip.s6_addr32[3] : info->sip.s6_addr32, sipstr, sizeof(sipstr)); dipstr[0] = 0; inet_ntop(daf, daf == AF_INET ? &info->dip.s6_addr32[3] : info->dip.s6_addr32, dipstr, sizeof(dipstr)); LogMessage("Debugging %s with %s-%u and %s-%u %u\n", desc, sipstr, (unsigned)info->sport, dipstr, (unsigned)info->dport, (unsigned)info->protocol); *debug_flag = 1; } else LogMessage("Debugging %s disabled\n", desc); } int DebugPktTracer(uint16_t type, const uint8_t *data, uint32_t length, void **new_context, char* statusBuf, int statusBuf_len) { debugParse("packet-tracer", data, length, &pkt_trace_cli_flag, &pkt_tracer_debug_info); return 0; } bool pktTracerDebugCheck(Packet* p) { #if defined(HAVE_DAQ_EXT_MODFLOW) && defined(HAVE_DAQ_PKT_TRACE) if (p && p->pkth && p->pkth->flags & DAQ_PKT_FLAG_TRACE_ENABLED) { pkt_trace_enabled_by_lina = true; } else pkt_trace_enabled_by_lina = false; #else pkt_trace_enabled_by_lina = false; #endif pkt_trace_enabled_by_clish = false; if (!pkt_trace_cli_flag || !p || !(p->iph_api)) return pkt_trace_enabled_by_lina; sfaddr_t *src = GET_SRC_IP(p); sfaddr_t *dst = GET_DST_IP(p); uint16_t sport = p->sp; uint16_t dport = p->dp; #ifdef DAQ_CAPA_VRF uint16_t sAsId = DAQ_GetSourceAddressSpaceID(p->pkth); uint16_t dAsId = DAQ_GetDestinationAddressSpaceID(p->pkth); #endif uint8_t protocol = GET_IPH_PROTO(p); switch (protocol) { case IPPROTO_TCP: case IPPROTO_UDP: break; case IPPROTO_ICMP: if (sport == ICMP_ECHOREPLY) { dport = ICMP_ECHO; /* Treat ICMP echo reply the same as request */ sport = 0; } else /* otherwise, every ICMP type gets different key */ dport = 0; break; case IPPROTO_ICMPV6: if (sport == ICMP6_REPLY) { dport = ICMP6_ECHO; /* Treat ICMPv6 echo reply the same as request */ sport = 0; } else /* otherwise, every ICMP type gets different key */ dport = 0; break; default: sport = dport = 0; break; } if ((!pkt_tracer_debug_info.protocol || pkt_tracer_debug_info.protocol == protocol) && (((!pkt_tracer_debug_info.sport || pkt_tracer_debug_info.sport == sport) && (!pkt_tracer_debug_info.sip_flag || memcmp(&pkt_tracer_debug_info.sip, src, sizeof(pkt_tracer_debug_info.sip)) == 0) && (!pkt_tracer_debug_info.dport || pkt_tracer_debug_info.dport == dport) && (!pkt_tracer_debug_info.dip_flag || memcmp(&pkt_tracer_debug_info.dip, dst, sizeof(pkt_tracer_debug_info.dip)) == 0)) || ((!pkt_tracer_debug_info.sport || pkt_tracer_debug_info.sport == dport) && (!pkt_tracer_debug_info.sip_flag || memcmp(&pkt_tracer_debug_info.sip, dst, sizeof(pkt_tracer_debug_info.sip)) == 0) && (!pkt_tracer_debug_info.dport || pkt_tracer_debug_info.dport == sport) && (!pkt_tracer_debug_info.dip_flag || memcmp(&pkt_tracer_debug_info.dip, src, sizeof(pkt_tracer_debug_info.dip)) == 0)))) { int af; const struct in6_addr* sip = (const struct in6_addr*)src; const struct in6_addr* dip = (const struct in6_addr*)dst; unsigned offset; char sipstr[INET6_ADDRSTRLEN]; char dipstr[INET6_ADDRSTRLEN]; sipstr[0] = 0; if (sip->s6_addr32[0] || sip->s6_addr32[1] || sip->s6_addr16[4] || (sip->s6_addr16[5] && sip->s6_addr16[5] != 0xFFFF)) { af = AF_INET6; offset = 0; } else { af = AF_INET; offset = 12; } inet_ntop(af, &sip->s6_addr[offset], sipstr, sizeof(sipstr)); dipstr[0] = 0; if (dip->s6_addr32[0] || dip->s6_addr32[1] || dip->s6_addr16[4] || (dip->s6_addr16[5] && dip->s6_addr16[5] != 0xFFFF)) { af = AF_INET6; offset = 0; } else { af = AF_INET; offset = 12; } inet_ntop(af, &dip->s6_addr[offset], dipstr, sizeof(dipstr)); #ifdef DAQ_CAPA_VRF snprintf(pkt_tracer_debug_session, DEBUG_SESSION_ID_SIZE, "%s-%u - %s-%u %u AS %u-%u", sipstr, (unsigned)sport, dipstr, (unsigned)dport, (unsigned)protocol, sAsId, dAsId); #else snprintf(pkt_tracer_debug_session, DEBUG_SESSION_ID_SIZE, "%s-%u - %s-%u %u", sipstr, (unsigned)sport, dipstr, (unsigned)dport, (unsigned)protocol); #endif pkt_trace_enabled_by_clish = true; return true; } return pkt_trace_enabled_by_lina; } // Get name-string from DAQ_Verdict (must sync with DAQ_Verdict defined at daq_common.h) static char* getVerdictStr(DAQ_Verdict vd) { static char* vName[] = {"PASS", "BLOCK", "REPLACE", "WHITELIST", "BLACKLIST", "IGNORE", "RETRY", "Error in reading verdict!"}; if (vd > MAX_DAQ_VERDICT) vd = MAX_DAQ_VERDICT; return vName[vd]; } // Get name-string from Verdict_Reason (must sync with Verdict_Reason defined at sf_dynamic_common.h) static char* getModuleStr(Verdict_Reason module) { static char* mName[] = {"Packet Information", "Session String", "None", "a module", "DAQ Retry", "Snort", "AppID", "SSL", "Firewall", "Captive Portal", "Safe Search", "SI", "Prefilter", "FTP", "Stream", "Session", "Defragmentation", "Snort React", "Snort Response", "SI/Reputation", "X-Link2State", "Back Orifice", "SMB", "File Process", "IPS"}; if (module >= MAX_VERDICT_REASON) module = VERDICT_REASON_UNKNOWN; return mName[module]; } // If enabled by Lina, add trace_line to pktTraceData buffer, else print to /var/log/message void addPktTraceData(int reason, int traceLen) { Verdict_Reason module = (Verdict_Reason) reason; if (!snort_received_packet && module == VERDICT_REASON_SFSSL) ssl_callback_before_snort = true; // used in addPktTraceInfo on receiving packet by snort else if (module == VERDICT_REASON_INFO) { if (trace_line_info_received) return; // records only one packet info trace else trace_line_info_received = true; } else if (module == VERDICT_REASON_APPID) { if (trace_line_appid_received) return; // records only one appid trace else trace_line_appid_received = true; } else if (module > VERDICT_REASON_NO_BLOCK && (verdict_reason == VERDICT_REASON_NO_BLOCK || module == VERDICT_REASON_SI)) verdict_reason = module; // records the first blocking module and any subsequent blocking from SI if (traceLen <= 0) return; if (pkt_trace_enabled_by_clish) // tracing enabled by 'system support tracer' { if (first_trace_line) { first_trace_line = false; LogMessage("PktTracerDbg \n"); // empty line } LogMessage("PktTracerDbg %s %s\n", pkt_tracer_debug_session, trace_line); } if (pkt_trace_enabled_by_lina) // tracing enabled by Lina flag { if (pktTraceDataLen + traceLen >= MAX_TRACE_SIZE) { LogMessage("Packet trace buffer is full; logging skipped!\n"); return; } strncat(pktTraceData, trace_line, traceLen); pktTraceDataLen += traceLen; pktTraceData[MAX_TRACE_SIZE-1] = '\0'; } } // Writes pktTraceData buffer into PDTS or /var/log/message void writePktTraceData(DAQ_Verdict verdict, unsigned int napId, unsigned int ipsId, const Packet* p) { uint32_t snortId = (snort_conf->event_log_id >> 16); alreadySentTrace = false; if (pkt_trace_enabled_by_clish) { LogMessage("PktTracerDbg %s Snort id %u, NAP id %u, IPS id %u, Verdict %s\n", pkt_tracer_debug_session, snortId, napId, ipsId, getVerdictStr(verdict)); if (verdict_reason != VERDICT_REASON_NO_BLOCK) LogMessage("PktTracerDbg %s ===> Blocked by %s\n", pkt_tracer_debug_session, getModuleStr(verdict_reason)); } #if defined(HAVE_DAQ_EXT_MODFLOW) && defined(HAVE_DAQ_PKT_TRACE) if (pkt_trace_enabled_by_lina) { int len; if (pktTraceDataLen >= MAX_TRACE_SIZE) len = 0; else if (verdict_reason == VERDICT_REASON_NO_BLOCK) len = snprintf(pktTraceData+pktTraceDataLen, MAX_TRACE_SIZE - pktTraceDataLen, "Snort id %u, NAP id %u, IPS id %u, Verdict %s\n", snortId, napId, ipsId, getVerdictStr(verdict)); else len = snprintf(pktTraceData+pktTraceDataLen, MAX_TRACE_SIZE - pktTraceDataLen, "Snort id %u, NAP id %u, IPS id %u, Verdict %s, %s %s\n", snortId, napId, ipsId, getVerdictStr(verdict), "Blocked by", getModuleStr(verdict_reason)); if (len > 0) { pktTraceDataLen += len; if (pktTraceDataLen >= MAX_TRACE_SIZE) pktTraceDataLen = MAX_TRACE_SIZE-1; pktTraceData[MAX_TRACE_SIZE-1] = '\0'; } // Send to DAQ DAQ_ModFlow_t mod; DAQ_ModFlowPktTrace_t mod_tr; mod_tr.vreason = (uint8_t) verdict_reason; mod_tr.pkt_trace_data_len = pktTraceDataLen+1; // accounting '\0' mod_tr.pkt_trace_data = (uint8_t *) pktTraceData; mod.type = DAQ_MODFLOW_TYPE_PKT_TRACE; mod.length = sizeof(DAQ_ModFlowPktTrace_t); mod.value = (void *) &mod_tr; DAQ_ModifyFlow(p->pkth, &mod); if (pkt_trace_enabled_by_clish) // troubleshooting message in CLISH LogMessage("PktTracerDbg Trace buffer and verdict reason are sent to DAQ\n"); if (verdict_reason != VERDICT_REASON_NO_BLOCK) alreadySentTrace = true; } #endif // re-initialize after writing each packet trace pktTraceData[0] = '\0'; pktTraceDataLen = 0; trace_line_info_received = false; trace_line_appid_received = false; first_trace_line = true; snort_received_packet = false; ssl_callback_before_snort = false; } void addPktTraceInfo(void *packet) { Packet* p = (Packet *) packet; snort_received_packet = true; if (ssl_callback_before_snort) // special case { verdict_reason = VERDICT_REASON_SFSSL; ssl_callback_before_snort = false; } if (IsTCP(p)) { if (p->tcph->th_flags & TH_ACK) { addPktTraceData(VERDICT_REASON_INFO, snprintf(trace_line, MAX_TRACE_LINE, "Packet: TCP%s%s, ACK%s%s, seq %lu, ack %lu\n", PacketIsRebuilt(p)? " rebuilt" : "", p->tcph->th_flags & TH_SYN? ", SYN" : "", p->tcph->th_flags & TH_RST? ", RST" : "", p->tcph->th_flags & TH_FIN? ", FIN" : "", (unsigned long) ntohl(p->tcph->th_seq), (unsigned long) ntohl(p->tcph->th_ack))); } else { addPktTraceData(VERDICT_REASON_INFO, snprintf(trace_line, MAX_TRACE_LINE, "Packet: TCP%s%s%s%s, seq %lu\n", PacketIsRebuilt(p)? " rebuilt" : "", p->tcph->th_flags & TH_SYN? ", SYN" : "", p->tcph->th_flags & TH_RST? ", RST" : "", p->tcph->th_flags & TH_FIN? ", FIN" : "", (unsigned long) ntohl(p->tcph->th_seq))); } } else if (IsUDP(p)) { addPktTraceData(VERDICT_REASON_INFO, snprintf(trace_line, MAX_TRACE_LINE, "Packet: UDP\n")); } else if (IsICMP(p)) { addPktTraceData(VERDICT_REASON_INFO, snprintf(trace_line, MAX_TRACE_LINE, "Packet: ICMP\n")); } else if (IsIP(p)) { addPktTraceData(VERDICT_REASON_INFO, snprintf(trace_line, MAX_TRACE_LINE, "Packet: IP\n")); } else { addPktTraceData(VERDICT_REASON_INFO, snprintf(trace_line, MAX_TRACE_LINE, "Packet: not IP/TCP/UDP/ICMP\n")); } } const char* getPktTraceActMsg() { static const char* msg[] = {"drop", "would drop", "can't drop"}; if (Active_PacketWasDropped()) return msg[0]; else if (Active_PacketWouldBeDropped()) return msg[1]; else return msg[2]; } #if defined(HAVE_DAQ_EXT_MODFLOW) && defined(HAVE_DAQ_VERDICT_REASON) void sendReason(const Packet* p) { if (alreadySentTrace) // already sent verdict reason with trace data { alreadySentTrace = false; return; } DAQ_ModFlow_t mod; mod.type = DAQ_MODFLOW_TYPE_VER_REASON; mod.length = sizeof(uint8_t); mod.value = (void*)&verdict_reason; DAQ_ModifyFlow(p->pkth, &mod); if (pkt_trace_enabled_by_clish) // troubleshooting message in CLISH LogMessage("PktTracerDbg Verdict reason is sent to DAQ\n"); } #endif void SavePktTrace() { pkt_trace_enabled_by_clish_bk = pkt_trace_enabled_by_clish; if( pkt_trace_enabled_by_clish ) memcpy(pkt_tracer_debug_session_bk, pkt_tracer_debug_session, DEBUG_SESSION_ID_SIZE); } void RestorePktTrace() { pkt_trace_enabled_by_clish = pkt_trace_enabled_by_clish_bk; if(pkt_trace_enabled_by_clish) memcpy(pkt_tracer_debug_session, pkt_tracer_debug_session_bk, DEBUG_SESSION_ID_SIZE); } bool pktTracerDebugCheckSsn(void* ssn) { char sipstr[INET6_ADDRSTRLEN]; char dipstr[INET6_ADDRSTRLEN]; SessionControlBlock *scb = ( SessionControlBlock * ) ssn; pkt_trace_enabled_by_clish = false; if (!pkt_trace_cli_flag || !scb) return false; if ((!pkt_tracer_debug_info.protocol || pkt_tracer_debug_info.protocol == scb->protocol) && (((!pkt_tracer_debug_info.sport || pkt_tracer_debug_info.sport == ntohs(scb->client_port)) && (!pkt_tracer_debug_info.sip_flag || memcmp(&pkt_tracer_debug_info.sip, &scb->client_ip.ip, sizeof(pkt_tracer_debug_info.sip)) == 0) && (!pkt_tracer_debug_info.dport || pkt_tracer_debug_info.dport == ntohs(scb->server_port)) && (!pkt_tracer_debug_info.dip_flag || memcmp(&pkt_tracer_debug_info.dip, &scb->server_ip.ip, sizeof(pkt_tracer_debug_info.dip)) == 0)))) { sfip_ntop(&scb->client_ip, sipstr, sizeof(sipstr)); sfip_ntop(&scb->server_ip, dipstr, sizeof(dipstr)); uint16_t sport = ntohs(scb->client_port); uint16_t dport = ntohs(scb->server_port); #ifdef DAQ_CAPA_VRF uint16_t sAsId = scb->key->addressSpaceId_l; uint16_t dAsId = scb->key->addressSpaceId_h; snprintf(pkt_tracer_debug_session, DEBUG_SESSION_ID_SIZE, "%s-%u - %s-%u %u AS %u-%u", sipstr, (unsigned)sport, dipstr, (unsigned)dport, (unsigned)scb->protocol, sAsId, dAsId); #else snprintf(pkt_tracer_debug_session, DEBUG_SESSION_ID_SIZE, "%s-%u - %s-%u %u", sipstr, (unsigned)sport, dipstr, (unsigned)dport, (unsigned)scb->protocol); #endif pkt_trace_enabled_by_clish = true; return true; } return false; } snort-2.9.15.1/src/pkt_tracer.h0000644000175200017520000000340413571422607013147 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _PKT_TRACER_H #define _PKT_TRACER_H #include "sf_ip.h" #include "sfdaq.h" #include "dynamic-plugins/sf_dynamic_common.h" #define CS_TYPE_PKT_TRACER 120 #define MAX_TRACE_LINE 256 extern volatile int pkt_trace_cli_flag; extern bool pkt_trace_enabled; extern char trace_line[MAX_TRACE_LINE]; int DebugPktTracer(uint16_t type, const uint8_t *data, uint32_t length, void **new_context, char* statusBuf, int statusBuf_len); bool pktTracerDebugCheck(Packet* p); bool pktTracerDebugCheckSsn(void* ssn); void addPktTraceData(int module, int traceLen); void addPktTraceInfo(void *packet); void writePktTraceData(DAQ_Verdict verdict, unsigned int napId, unsigned int ipsId, const Packet* p); const char* getPktTraceActMsg(); void SavePktTrace(); void RestorePktTrace(); extern Verdict_Reason verdict_reason; #if defined(HAVE_DAQ_EXT_MODFLOW) && defined(HAVE_DAQ_VERDICT_REASON) void sendReason(const Packet* p); #endif #endif snort-2.9.15.1/src/obfuscation.c0000644000175200017520000013556313571422607013334 00000000000000/****************************************************************************** * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2009-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ******************************************************************************/ #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "obfuscation.h" #include "sf_types.h" #include "snort_debug.h" #include "decode.h" #include "util.h" #include "stream_api.h" #include "snort_bounds.h" #ifdef OBFUSCATION_TEST_STANDALONE # ifndef OBFUSCATION_TEST # define OBFUSCATION_TEST # endif # define TraverseReassembled stream_api->traverse_stream_segments static int TraverseReassembled( Packet *, int (*)(DAQ_PktHdr_t *, uint8_t *, uint8_t *, uint32_t, void *), void * ); #endif /******************************************************************************* * Macros ******************************************************************************/ #define OBFUSCATE_ENTRIES 512 #define OBFUSCATE_MAXLEN_ENTRIES 8 #define OBFUSCATE_SLICE_ENTRIES (OBFUSCATE_ENTRIES - OBFUSCATE_MAXLEN_ENTRIES) /******************************************************************************* * Data structures ******************************************************************************/ typedef struct _ObfuscationEntry { Packet *p; ob_size_t offset; ob_size_t length; ob_char_t ob_char; uint32_t seq; } ObfuscationEntry; typedef struct _ObfuscationStruct { int num_entries; int num_maxlen_entries; int sorted; ObfuscationEntry entries[OBFUSCATE_ENTRIES]; ObfuscationEntry *sort_entries[OBFUSCATE_ENTRIES]; ObfuscationEntry *maxlen_entries[OBFUSCATE_MAXLEN_ENTRIES]; } ObfuscationStruct; typedef struct _ObfuscationCallbackData { const Packet *packet; ObfuscationCallback user_callback; void *user_data; int entry_index; ob_size_t total_offset; } ObfuscationCallbackData; typedef struct _ObfuscationStreamCallbackData { ObfuscationCallbackData *data; uint32_t next_seq; int last_entry_index; } ObfuscationStreamCallbackData; typedef struct _ObfuscatedPayload { uint8_t **payload; ob_size_t *payload_len; ob_size_t payload_size; } ObfuscatedPayload; /******************************************************************************* * Globals ******************************************************************************/ static ObfuscationStruct ob_struct; /******************************************************************************* * Private function prototypes ******************************************************************************/ static inline int NumObfuscateMaxLenEntries(void); static inline int NumObfuscateSliceEntries(void); static inline ObRet ObfuscationEntryOverflow(ob_size_t); static inline int PayloadObfuscationRequired(Packet *); static inline void SetObfuscationEntry(ObfuscationEntry *, Packet *, ob_size_t, ob_size_t, ob_char_t, uint32_t); static inline void SortObfuscationEntries(void); static inline void SetObfuscationCallbackData( ObfuscationCallbackData *, Packet *, ObfuscationCallback, void *); static inline void SetObfuscationStreamCallbackData( ObfuscationStreamCallbackData *, ObfuscationCallbackData *, Packet *, ObfuscationCallback, void *); static ObRet AddObfuscationEntry(Packet *, ob_size_t, ob_size_t, ob_char_t); static int ObfuscationEntrySort(const void *, const void *); static ObRet TraverseObfuscationList(ObfuscationCallbackData *, const DAQ_PktHdr_t *, const uint8_t *, ob_size_t, uint32_t); static int ObfuscateStreamSegmentsCallback(DAQ_PktHdr_t *, uint8_t *, uint8_t *, uint32_t, void *); static ObRet GetObfuscatedPayloadCallback(const DAQ_PktHdr_t *, const uint8_t *, ob_size_t, ob_char_t, void *); static void PrintObfuscationEntry(const ObfuscationEntry *, int); /******************************************************************************* * API prototypes ******************************************************************************/ static void OB_API_ResetObfuscationEntries(void); static ObRet OB_API_AddObfuscationEntry(Packet *, ob_size_t, ob_size_t, ob_char_t); static int OB_API_PayloadObfuscationRequired(Packet *); static ObRet OB_API_ObfuscatePacket(Packet *, ObfuscationCallback, void *); static ObRet OB_API_ObfuscatePacketStreamSegments(Packet *, ObfuscationCallback, void *); static ObRet OB_API_GetObfuscatedPayload(Packet *, uint8_t **, ob_size_t *); static void OB_API_PrintObfuscationEntries(int); /* API accessor */ ObfuscationApi obfuscationApi = { OB_API_ResetObfuscationEntries, // resetObfuscationEntries OB_API_AddObfuscationEntry, // addObfuscationEntry OB_API_PayloadObfuscationRequired, // payloadObfuscationRequired OB_API_ObfuscatePacket, // obfuscatePacket OB_API_ObfuscatePacketStreamSegments, // obfuscatePacketStreamSegments OB_API_GetObfuscatedPayload, // getObfuscatedPayload OB_API_PrintObfuscationEntries // printObfuscationEntries }; ObfuscationApi *obApi = &obfuscationApi; static inline uint32_t get_pkt_seq_num(const Packet* p) { uint32_t pkt_seq = 0; if (p->tcph) pkt_seq = ntohl(p->tcph->th_seq); return pkt_seq; } static inline int32_t get_length_from_seq(uint32_t start, uint32_t end) { uint32_t length = end - start; if (length > UINT16_MAX) return (-1); else return length; } /******************************************************************************* * API Function definitions ******************************************************************************/ // resetObfuscationEntries void OB_API_ResetObfuscationEntries(void) { ob_struct.num_entries = 0; ob_struct.num_maxlen_entries = 0; ob_struct.sorted = 0; } // addObfuscationEntry static ObRet OB_API_AddObfuscationEntry(Packet *p, ob_size_t offset, ob_size_t length, ob_char_t ob_char) { if (p == NULL) return OB_RET_ERROR; p->packet_flags |= PKT_PAYLOAD_OBFUSCATE; return AddObfuscationEntry(p, offset, length, ob_char); } // payloadObfuscationRequired static int OB_API_PayloadObfuscationRequired(Packet *p) { return PayloadObfuscationRequired(p); } // obfuscatePacket static ObRet OB_API_ObfuscatePacket(Packet *p, ObfuscationCallback user_callback, void *user_data) { ObfuscationCallbackData callback_data; if (!PayloadObfuscationRequired(p)) return OB_RET_ERROR; SortObfuscationEntries(); SetObfuscationCallbackData(&callback_data, p, user_callback, user_data); /* Send header information first - isn't obfuscated */ if (user_callback(p->pkth, p->pkt, (ob_size_t)(p->data - p->pkt), 0, user_data) != OB_RET_SUCCESS) { return OB_RET_ERROR; } if (TraverseObfuscationList(&callback_data, NULL, p->data, (ob_size_t)(p->pkth->caplen - (p->data - p->pkt)), get_pkt_seq_num(p)) != OB_RET_SUCCESS) { return OB_RET_ERROR; } return OB_RET_SUCCESS; } // obfuscatePacketStreamSegments static ObRet OB_API_ObfuscatePacketStreamSegments(Packet *p, ObfuscationCallback user_callback, void *user_data) { ObfuscationStreamCallbackData stream_callback_data; ObfuscationCallbackData callback_data; if (!PayloadObfuscationRequired(p)) return OB_RET_ERROR; SortObfuscationEntries(); SetObfuscationStreamCallbackData(&stream_callback_data, &callback_data, p, user_callback, user_data); if (stream_api->traverse_stream_segments(p, ObfuscateStreamSegmentsCallback, (void *)&stream_callback_data) == -1) { return OB_RET_ERROR; } return OB_RET_SUCCESS; } // getObfuscatedPayload static ObRet OB_API_GetObfuscatedPayload(Packet *p, uint8_t **payload, ob_size_t *payload_len) { ObfuscationCallbackData callback_data; ObfuscatedPayload user_data; if (!PayloadObfuscationRequired(p)) return OB_RET_ERROR; if ((payload == NULL) || (payload_len == NULL)) return OB_RET_ERROR; *payload = NULL; *payload_len = 0; user_data.payload = payload; user_data.payload_len = payload_len; user_data.payload_size = 0; SortObfuscationEntries(); SetObfuscationCallbackData(&callback_data, p, GetObfuscatedPayloadCallback, (void *)&user_data); if (TraverseObfuscationList(&callback_data, NULL, p->data, (ob_size_t)(p->pkth->caplen - (p->data - p->pkt)), get_pkt_seq_num(p)) != OB_RET_SUCCESS) { return OB_RET_ERROR; } return OB_RET_SUCCESS; } // printObfuscationEntries static void OB_API_PrintObfuscationEntries(int sorted) { int i; ObfuscationEntry *entry; if (sorted) SortObfuscationEntries(); for (i = 0; i < ob_struct.num_entries; i++) { LogMessage("Entry: %d\n", i); if (sorted) entry = ob_struct.sort_entries[i]; else entry = &ob_struct.entries[i]; PrintObfuscationEntry(entry, 2); } } /******************************************************************************* * Private function definitions ******************************************************************************/ /******************************************************************************* * Function: NumObfuscateMaxLenEntries() * * Gets the number of current OB_LENGTH_MAX entries that have been added. * * Arguments * None * * Returns * The number of current OB_LENGTH_MAX entries. * ******************************************************************************/ static inline int NumObfuscateMaxLenEntries(void) { return ob_struct.num_maxlen_entries; } /******************************************************************************* * Function: NumObfuscateSliceEntries() * * Gets the number of current slice entries that have been added. * * Arguments * None * * Returns * The number of current slice entries. * ******************************************************************************/ static inline int NumObfuscateSliceEntries(void) { return ob_struct.num_entries - ob_struct.num_maxlen_entries; } /******************************************************************************* * Function: ObfuscationEntryOverflow() * * Determines whether or not there is enough space in the static entry array to * add another obfucation entry. * * Arguments * ob_size_t * The length of the entry that should be added. If length is OB_LENGTH_MAX * then the max length array is checked. * * Returns * OB_RET_SUCCESS if the entry can be added * OB_RET_OVERFLOW if there isn't enough space to add another entry * ******************************************************************************/ static inline ObRet ObfuscationEntryOverflow(ob_size_t length) { if (length == OB_LENGTH_MAX) { if (NumObfuscateMaxLenEntries() >= OBFUSCATE_MAXLEN_ENTRIES) return OB_RET_OVERFLOW; } else { if (NumObfuscateSliceEntries() >= OBFUSCATE_SLICE_ENTRIES) return OB_RET_OVERFLOW; } return OB_RET_SUCCESS; } /******************************************************************************* * Function: PayloadObfuscationRequired() * * Determines whether or not the packet requires obfuscation. An obfuscation * flag is added to the packet flags when an obfuscation entry is added that * is associated with the packet. If there isn't any data, then it doesn't * need obfuscation. * * Arguments * Packet *p * The Packet to check * * Returns * 0 if obfuscation is not needed. * 1 if the packet has been flagged for obfuscation. * ******************************************************************************/ static inline int PayloadObfuscationRequired(Packet *p) { if ((p == NULL) || (p->pkth == NULL) || (p->pkt == NULL) || (p->data == NULL) || (p->pkt >= p->data) || ((ob_size_t)(p->data - p->pkt) > p->pkth->caplen)) { return 0; } if (!(p->packet_flags & PKT_PAYLOAD_OBFUSCATE) || (ob_struct.num_entries == 0)) { return 0; } return 1; } /******************************************************************************* * Function: SetObfuscationEntry() * * Initializes an obfuscation entry with the passed in values. * * Arguments * ObfuscationEntry *entry * The obfuscation entry to initialize * Packet *p * The Packet to associate with this entry * ob_size_t offset * The offset into the packet to start obfuscation * ob_size_t length * The amount of data to obfuscate starting from offset * ob_char_t ob_char * The character to use when obfuscating * * Returns * None * ******************************************************************************/ static inline void SetObfuscationEntry(ObfuscationEntry *entry, Packet *p, ob_size_t offset, ob_size_t length, ob_char_t ob_char, uint32_t seq) { if (entry == NULL) return; entry->p = p; entry->offset = offset; entry->length = length; entry->ob_char = ob_char; entry->seq = seq; } /******************************************************************************* * Function: SetObfuscationCallbackData() * * Initializes the callback data for use in TraverseObfuscationList. * * Arguments * ObfuscationCallbackData *callback_data * The callback data struct to initialize * Packet *p * The Packet to associate with this entry * ob_size_t offset * The offset into the packet to start obfuscation * ob_size_t length * The amount of data to obfuscate starting from offset * ob_char_t ob_char * The character to use when obfuscating * * Returns * None * ******************************************************************************/ static inline void SetObfuscationCallbackData( ObfuscationCallbackData *callback_data, Packet *packet, ObfuscationCallback user_callback, void *user_data) { if (callback_data == NULL) return; callback_data->packet = packet; callback_data->user_callback = user_callback; callback_data->user_data = user_data; callback_data->entry_index = 0; callback_data->total_offset = 0; } /******************************************************************************* * Function: SetObfuscationStreamCallbackData() * * Initializes the callback data for use in TraverseObfuscationList. * * Arguments * ObfuscationStreamCallbackData *stream_callback_data * The stream callback data struct to initialize * ObfuscationCallbackData *callback_data * The callback data struct to initialize * Packet *p * The Packet to associate with this entry * ob_size_t offset * The offset into the packet to start obfuscation * ob_size_t length * The amount of data to obfuscate starting from offset * ob_char_t ob_char * The character to use when obfuscating * * Returns * None * ******************************************************************************/ static inline void SetObfuscationStreamCallbackData( ObfuscationStreamCallbackData *stream_callback_data, ObfuscationCallbackData *callback_data, Packet *packet, ObfuscationCallback user_callback, void *user_data) { if ((stream_callback_data == NULL) || (callback_data == NULL)) return; SetObfuscationCallbackData(callback_data, packet, user_callback, user_data); stream_callback_data->data = callback_data; stream_callback_data->next_seq = 0; stream_callback_data->last_entry_index = 0; } /******************************************************************************* * Function: SortObfuscationEntries() * * Uses qsort to sort the entries that have been added. Possibly qsort is not * the most efficient sort here since, in general, the entries will be added * from smallest offset to largest. * * Arguments * None * * Returns * None * ******************************************************************************/ static inline void SortObfuscationEntries(void) { if (!ob_struct.sorted) { qsort((void *)ob_struct.sort_entries, ob_struct.num_entries, sizeof(ObfuscationEntry *), ObfuscationEntrySort); ob_struct.sorted = 1; } } /******************************************************************************* * Function: AddObfuscationEntry() * * Adds an obfuscation entry to the obfuscation list. OB_LENGTH_MAX entries * are first checked to see if there is an entry already associated with * the Packet passed in. If there is, the entry with the lesser of the two * offsets is used. * * Arguments * Packet *p * The Packet to be associated with this entry * ob_size_t offset * The offset into the payload of this packet to start obfuscating * ob_size_t length * The length of the payload starting at offset to obfuscate * ob_char_t * The character to use when obfuscating * * Returns * OB_RET_SUCCESS if the entry was successfully added * OB_RET_OVERFLOW if there is no room left to store the entry * ******************************************************************************/ static ObRet AddObfuscationEntry(Packet *p, ob_size_t offset, ob_size_t length, ob_char_t ob_char) { ObfuscationEntry *entry; int entry_index = ob_struct.num_entries; uint32_t seq = offset + get_pkt_seq_num(p); if (length == OB_LENGTH_MAX) { int i; /* Check to see if there is an OB_LENGTH_MAX entry already associated * with this packet */ for (i = 0; i < ob_struct.num_maxlen_entries; i++) { entry = ob_struct.maxlen_entries[i]; if (entry->p == p) { /* Already have an entry for this packet. Use the entry with * the lesser of the two offsets */ if (offset < entry->offset) { entry->offset = offset; entry->ob_char = ob_char; } return OB_RET_SUCCESS; } } } if (ObfuscationEntryOverflow(length) != OB_RET_SUCCESS) return OB_RET_OVERFLOW; /* Reset sorted since we're adding an entry and the list will need * to be sorted again */ ob_struct.sorted = 0; /* Get the entry at the current index */ entry = &ob_struct.entries[entry_index]; SetObfuscationEntry(entry, p, offset, length, ob_char, seq); ob_struct.sort_entries[entry_index] = entry; ob_struct.num_entries++; if (length == OB_LENGTH_MAX) { ob_struct.maxlen_entries[ob_struct.num_maxlen_entries] = entry; ob_struct.num_maxlen_entries++; } return OB_RET_SUCCESS; } /******************************************************************************* * Function: ObfuscationEntrySort() * * Sorting callback. Sorted by offset, then length if the offsets are the same. * * Arguments * const void *data1 * The compare to argument * const void *data2 * The argument to compare to the first argument * * Returns * -1 if the first ObfuscationEntry is considered less than the second * 1 if the first ObfuscationEntry is considered greater than the second * 0 if both offset and length are equal * ******************************************************************************/ static int ObfuscationEntrySort(const void *data1, const void *data2) { ObfuscationEntry *ob1 = *((ObfuscationEntry **)data1); ObfuscationEntry *ob2 = *((ObfuscationEntry **)data2); if (ob1->offset < ob2->offset) return -1; else if (ob1->offset > ob2->offset) return 1; else if (ob1->length < ob2->length) return -1; else if (ob1->length > ob2->length) return 1; return 0; } /******************************************************************************* * Function: TraverseObfuscationList() * * This is the main function for obfuscating a payload or stream segments. * It walks through a packet and obfuscation entries, calling the user * callback with obfuscated and non-obfuscated instructions. * * Arguments * ObfuscationCallbackData *data * The state tracking data structure. Has the packet being obfuscated, * current obfuscation entry and total number of bytes obfuscated thus * far. * DAQ_PktHdr_t *pkth * The pcap header information associated with the payload being * obfuscated. * uint8_t *pkt * The start of the packet including Ethernet headers, etc. * uint8_t *payload * Pointer to the payload data to be obfuscated * ob_size_t * The size of the payload data * uint32_t * The sequence number of payload data * * Returns * OB_RET_SUCCESS if successfully completed * OB_RET_ERROR if the user callback doesn't return OB_RET_SUCCESS * ******************************************************************************/ static ObRet TraverseObfuscationList(ObfuscationCallbackData *data, const DAQ_PktHdr_t *pkth, const uint8_t *payload_data, ob_size_t payload_size, uint32_t seq_num) { int i; ob_size_t payload_offset = 0; const DAQ_PktHdr_t *pkth_tmp = pkth; uint32_t data_seq = get_pkt_seq_num(data->packet); int32_t length; #ifdef OBFUSCATION_TEST uint8_t print_array[OB_LENGTH_MAX]; ob_size_t total_offset = data->total_offset; ob_size_t start_total_offset = 0; ob_size_t start_payload_offset = 0; #endif if ((payload_data == NULL) || (payload_size == 0)) return OB_RET_ERROR; #ifdef OBFUSCATION_TEST LogMessage("Payload data: %u bytes\n", payload_size); LogMessage("===============================================================" "=================\n"); #endif /* Masks the start of raw packet that is not part of this rebuilt packet */ length = get_length_from_seq(seq_num, data_seq); if ( length > 0) { /* Call the user callback and tell it to obfuscate to 00 */ if (data->user_callback(pkth_tmp, NULL, (ob_size_t)length, 0, data->user_data) != OB_RET_SUCCESS) { return OB_RET_ERROR; } payload_offset += length; /* Only the first payload call sends the pcap_pkthdr */ pkth_tmp = NULL; } /* Start from current saved obfuscation entry index */ for (i = data->entry_index; i < ob_struct.num_entries; i++) { /* Get the entry from the sorted array */ const ObfuscationEntry *entry = ob_struct.sort_entries[i]; int32_t ob_offset = get_length_from_seq (seq_num, entry->seq); int32_t ob_end = get_length_from_seq (seq_num, entry->seq + entry->length); ob_size_t ob_length = entry->length; if (ob_end <= 0 ) continue; else if (ob_offset < 0) { ob_length = ob_end; ob_offset = 0; } /* Make sure it's for the right packet */ if (entry->p != data->packet) { #ifdef OBFUSCATION_TEST LogMessage("flags1: %08x, flags2: %08x\n", entry->p->packet_flags, data->packet->packet_flags); #endif continue; } #ifdef OBFUSCATION_TEST LogMessage(" Total offset: %u\n\n", total_offset); start_total_offset = total_offset; start_payload_offset = payload_offset; #endif /* Note the obfuscation offset is only used at this point to determine * the amount of data that does not need to be obfuscated up to the * offset or the length of what needs to be obfuscated if the offset * is less than what's already been logged */ if (ob_offset > payload_offset) { /* Get the amount of non-obfuscated data - need to log straight * packet data up to obfuscation offset */ ob_size_t length = ob_offset - payload_offset; /* If there is more length than what's left in the packet, * truncate it, do we don't overflow */ if (length > (payload_size - payload_offset)) length = payload_size - payload_offset; /* Call the user callback and tell it not to obfuscate the data * by passing in a non-NULL packet pointer */ if (data->user_callback(pkth_tmp, payload_data + payload_offset, length, 0, data->user_data) != OB_RET_SUCCESS) { return OB_RET_ERROR; } #ifdef OBFUSCATION_TEST SafeMemcpy(print_array + payload_offset, payload_data + payload_offset, length, print_array, print_array + sizeof(print_array)); #endif /* Only the first payload call sends the pcap_pkthdr */ pkth_tmp = NULL; /* Adjust offsets */ payload_offset += length; /* If there is no more packet data, break out of the loop */ if (payload_offset == payload_size) { #ifdef OBFUSCATION_TEST PrintPacketData(print_array + start_payload_offset, length); LogMessage("\n"); #endif break; } } else if (ob_offset < payload_offset) { /* If the entries offset is less than the current total offset, * decrease the length. */ if(ob_length > (payload_offset - ob_offset)) ob_length -= (payload_offset - ob_offset); else continue; } /* Adjust the amount of data to obfuscate if it exceeds the amount of * data left in the packet. Account for overflow */ if (((payload_offset + ob_length) > payload_size) || ((payload_offset + ob_length) <= payload_offset)) { ob_length = payload_size - payload_offset; } /* Call the user callback and tell it to obfuscate the data by passing * in a NULL packet pointer */ if (data->user_callback(pkth_tmp, NULL, ob_length, entry->ob_char, data->user_data) != OB_RET_SUCCESS) { return OB_RET_ERROR; } #ifdef OBFUSCATION_TEST LogMessage(" Entry: %d\n", i); LogMessage(" --------------------------\n"); PrintObfuscationEntry(entry, 4); LogMessage("\n"); SafeMemset(print_array + payload_offset, entry->ob_char, ob_length, print_array, print_array + sizeof(print_array)); if (ob_length < entry->length) { if (ob_offset < start_total_offset) { if (payload_offset + ob_length == payload_size) { LogMessage(" Obfuscating beyond already obfuscated " "(%u bytes) and to end of payload: %u bytes\n\n", (start_total_offset - ob_offset), ob_length); } else { LogMessage(" Obfuscating beyond already obfuscated " "(%u bytes): %u bytes\n\n", (start_total_offset - ob_offset), ob_length); } } else { LogMessage(" Obfuscating to end of payload: " "%u bytes\n\n", ob_length); } } else { LogMessage(" Obfuscating: %u bytes\n\n", ob_length); } PrintPacketData(print_array + start_payload_offset, (payload_offset - start_payload_offset) + ob_length); if (((entry->offset + entry->length) - (total_offset + ob_length)) > 0) { LogMessage("\n Remaining amount to obfuscate: %u bytes\n", (entry->offset + entry->length) - (total_offset + ob_length)); } LogMessage("\n"); #endif /* Only the first payload call sends the pcap_pkthdr */ pkth_tmp = NULL; /* Adjust offsets */ payload_offset += ob_length; /* If there is no more packet data, break out of the loop */ if (payload_offset == payload_size) break; } /* There's more data in the packet left, meaning we ran out of * obfuscation entries */ if (payload_size > payload_offset) { int32_t data_left = get_length_from_seq(seq_num + payload_offset, data->packet->dsize + data_seq); length = payload_size - payload_offset; if (data_left > 0) { if (data_left < length) length = data_left; /* Call the user callback and tell it not to obfuscate the data * by passing in a non-NULL packet pointer */ if (data->user_callback(pkth_tmp, payload_data + payload_offset, length, 0, data->user_data) != OB_RET_SUCCESS) { return OB_RET_ERROR; } #ifdef OBFUSCATION_TEST SafeMemcpy(print_array + payload_offset, payload_data + payload_offset, length, print_array, print_array + sizeof(print_array)); #endif payload_offset += length; } length = payload_size - payload_offset; /* Masks the start of raw packet that is not part of this rebuilt packet */ if (length > 0) { /* Call the user callback and tell it to obfuscate the data with 00*/ if(data->user_callback(pkth_tmp, NULL, length, 0, data->user_data) != OB_RET_SUCCESS) { return OB_RET_ERROR; } #ifdef OBFUSCATION_TEST SafeMemcpy(print_array + payload_offset, payload_data + payload_offset, length, print_array, print_array + sizeof(print_array)); #endif } } #ifdef OBFUSCATION_TEST LogMessage("Obfuscated payload\n"); LogMessage("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" "~~~~~~~~~~\n"); PrintPacketData(print_array, payload_size); LogMessage("\n\n"); #endif /* Save these for next time we come in if necessary. Mainly for * traversing stream segments */ data->entry_index = i; return OB_RET_SUCCESS; } /******************************************************************************* * Function: ObfuscateStreamSegmentsCallback() * * Stream API callback for traverse_stream_segments. * * Arguments * DAQ_PktHdr_t *pkth * The pcap header information associated with the segment packet. * uint8_t *pkt * Pointer to the segment packet data starting at packet headers * uint8_t *payload * Pointer to the segment payload data to be obfuscated * uint32_t * The sequence number of this segment * void *data * The ObfuscationCallBack data * * Returns * Per stream api traverse_reassembled: * 0 if obfuscation was successful. * -1 if we had to bail on the obfuscation due to the user callback * telling us to - this should tell traverse_stream_segments to stop * traversing and not call this anymore. * ******************************************************************************/ static int ObfuscateStreamSegmentsCallback(DAQ_PktHdr_t *pkth, uint8_t *pkt, uint8_t *payload, uint32_t seq_num, void *data) { ObfuscationStreamCallbackData *callback_data = (ObfuscationStreamCallbackData *)data; ob_size_t payload_size = (uint16_t)(pkth->caplen - (payload - pkt)); if ((pkt >= payload) || ((ob_size_t)(payload - pkt) > pkth->caplen)) return -1; if (callback_data->data->user_callback(pkth, pkt, (ob_size_t)(payload - pkt), 0, callback_data->data->user_data) != OB_RET_SUCCESS) { return -1; } /* If we get an overlap set the entry index to where the last packet * started, else set the last entry index to the end of the one for * the last segment */ if (callback_data->next_seq > seq_num) { callback_data->data->entry_index = callback_data->last_entry_index; } else { callback_data->last_entry_index = callback_data->data->entry_index; } if (TraverseObfuscationList(callback_data->data, NULL, payload, payload_size, seq_num) != OB_RET_SUCCESS) { return -1; } /* Update next expected sequence number */ callback_data->next_seq = seq_num + payload_size; return 0; } /******************************************************************************* * Function: GetObfuscationPayloadCallback() * * ObfuscationCallback for returning an allocated obfuscated payload. * * Arguments * DAQ_PktHdr_t *pkth * The pcap header information associated with the payload being * obfuscated. * uint8_t *packet_data * Pointer to the packet data to be obfuscated * ob_char_t ob_char * The obfuscation character * ob_size_t length * The length of the portion of packet payload to use * void *user_data * The ObfuscatedPayload data * * Returns * OB_RET_ERROR if copying obfuscation data is not successful * OB_RET_SUCCESS if successful copying data to payload * ******************************************************************************/ static ObRet GetObfuscatedPayloadCallback(const DAQ_PktHdr_t *pkth, const uint8_t *packet_data, ob_size_t length, ob_char_t ob_char, void *user_data) { ObfuscatedPayload *ob_payload = (ObfuscatedPayload *)user_data; uint8_t *payload; ob_size_t payload_len, payload_size; if (ob_payload == NULL) return OB_RET_ERROR; if ((ob_payload->payload == NULL) || (ob_payload->payload_len == NULL)) return OB_RET_ERROR; payload = *ob_payload->payload; payload_len = *ob_payload->payload_len; payload_size = ob_payload->payload_size; if ((payload_len + length) > payload_size) { /* Allocate extra so we don't have to reallocate every time in */ ob_size_t new_size = payload_len + length + 100; uint8_t *tmp = (uint8_t *)SnortAlloc(new_size); if (payload != NULL) { if (SafeMemcpy(tmp, payload, payload_len, tmp, tmp + new_size) != SAFEMEM_SUCCESS) { free(tmp); free(payload); return OB_RET_ERROR; } free(payload); } payload_size = new_size; ob_payload->payload_size = new_size; *ob_payload->payload = tmp; payload = tmp; } if (packet_data != NULL) { if (SafeMemcpy(payload + payload_len, packet_data, length, payload, payload + payload_size) != SAFEMEM_SUCCESS) { free(payload); return OB_RET_ERROR; } } else { if (SafeMemset(payload + payload_len, (uint8_t)ob_char, length, payload, payload + payload_size) != SAFEMEM_SUCCESS) { free(payload); return OB_RET_ERROR; } } *ob_payload->payload_len += length; return OB_RET_SUCCESS; } /******************************************************************************* * Function: PrintObfuscationEntry() * * Prints an obfuscation entry offsetted with optional leading whitespace. * * Arguments * const ObfuscationEntry *entry * The entry to print * int leading_whitespace * The amount of whitespace to use before printing a line. * Returns * None * ******************************************************************************/ static void PrintObfuscationEntry(const ObfuscationEntry *entry, int leading_space) { if (entry == NULL) return; LogMessage("%*sPacket: %p\n", leading_space, "", (void*)entry->p); LogMessage("%*sOffset: %u\n", leading_space, "", entry->offset); LogMessage("%*sLength: %u\n", leading_space, "", entry->length); if (isgraph((int)entry->ob_char)) LogMessage("%*sOb char: \'%c\'\n", leading_space, "", entry->ob_char); else LogMessage("%*sOb char: 0x%02x\n", leading_space, "", entry->ob_char); } /****************************************************************************** * Testing ******************************************************************************/ #ifdef OBFUSCATION_TEST_STANDALONE #include #include #include #include #include #include #define PAYLOAD_ALLOC_SIZE 1024 /* Used for standalone testing */ typedef struct _Segment { DAQ_PktHdr_t *pkth; uint8_t *data; uint16_t size; struct _Segment *next; } Segment; /* Used for standalone testing */ typedef struct _ObPacket { struct Packet p; Segment *seglist; } ObPacket; static uint8_t *ob_payload = NULL; static void ObTestAlloc(void **, int, int); static void CreateObEntries(Packet *, ob_char_t, ob_size_t, ob_size_t, int, int); static ObRet ObCallback(DAQ_PktHdr_t *, uint8_t *, ob_char_t, ob_size_t, void *); static uint8_t * GetPayloadFromFile(char *, ob_size_t *); static int TraverseReassembled(Packet *p, int (*callback)(DAQ_PktHdr_t *, uint8_t *, void *), void *user_data) { ObfuscationCallbackData *callback_data = (ObfuscationCallbackData *)user_data; int segments = 0; Segment *seg; ObPacket *op = (ObPacket *)p; for (seg = op->seglist; seg != NULL; seg = seg->next) { if (callback(seg->pkth, seg->data, user_data) != 0) return segments; segments++; } return segments; } static void ObTestAlloc(void **ptr, int ptr_size, int this_size) { if (ptr == NULL) return; if (*ptr == NULL) { *ptr = calloc(1, this_size); if (*ptr == NULL) { fprintf(stderr, "Failed to allocate memory for payload.\n"); exit(1); } } else { if (this_size > ptr_size) { *ptr = realloc(*ptr, this_size); if (*ptr == NULL) { fprintf(stderr, "Failed to allocate memory for payload.\n"); exit(1); } } } } static void CreateObEntries(Packet *p, ob_char_t ob_char, ob_size_t ob_offset, ob_size_t ob_length, int reverse, int add_maxlen) { typedef struct _ob_tmp_struct { ob_size_t offset; ob_size_t length; } ob_tmp_struct_t; ob_size_t offset; ob_tmp_struct_t *tmp_struct = NULL; int num_tmps = 0; int i; if (p == NULL) return; for (offset = (rand() % ob_offset) + 1; offset < (p->dsize - ob_offset); offset += (rand() % ob_offset) + 1) { ob_size_t length = rand() % ob_length + 1; ObTestAlloc((void **)&tmp_struct, sizeof(ob_tmp_struct_t) * num_tmps, sizeof(ob_tmp_struct_t) * (num_tmps + 1)); tmp_struct[num_tmps].offset = offset; tmp_struct[num_tmps].length = length; num_tmps++; if (add_maxlen && (offset > p->dsize/2)) obApi->addObfuscationEntry(p, offset, OB_LENGTH_MAX, ob_char); if ((offset + length) >= p->dsize) break; } if (reverse) { for (i = num_tmps - 1; i >= 0; i--) { obApi->addObfuscationEntry(p, tmp_struct[i].offset, tmp_struct[i].length, ob_char); } } else { for (i = 0; i < num_tmps; i++) { obApi->addObfuscationEntry(p, tmp_struct[i].offset, tmp_struct[i].length, ob_char); } } } static ObRet ObCallback(DAQ_PktHdr_t *pkth, uint8_t *packet_data, ob_char_t ob_char, ob_size_t length, void *user_data) { ob_size_t *offset = (ob_size_t *)user_data; if (packet_data != NULL) memcpy(ob_payload + *offset, packet_data, length); else memset(ob_payload + *offset, ob_char, length); *offset += length; return OB_RET_SUCCESS; } static uint8_t * GetPayloadFromFile(char *payload_file, ob_size_t *payload_bytes) { uint8_t *payload = NULL; FILE *fp; ob_size_t bytes; if (payload_bytes == NULL) return NULL; *payload_bytes = 0; fp = fopen(payload_file, "r"); if (fp == NULL) { fprintf(stderr, "Could not open payload file \"%s\": %s\n", payload_file, strerror(errno)); exit(1); } ObTestAlloc((void **)&payload, 0, PAYLOAD_ALLOC_SIZE); while ((bytes = fread(payload + *payload_bytes, sizeof(char), PAYLOAD_ALLOC_SIZE, fp)) == PAYLOAD_ALLOC_SIZE) { ObTestAlloc((void **)&payload, *payload_bytes + bytes, *payload_bytes + bytes + bytes); *payload_bytes += bytes; } fclose(fp); *payload_bytes += bytes; if (*payload_bytes > OB_LENGTH_MAX) *payload_bytes = OB_LENGTH_MAX; return payload; } static uint8_t * GetStaticPayload(ob_char_t ob_char, ob_size_t *payload_bytes) { uint8_t *payload = NULL; ob_size_t alloc_size = 1000; ob_char_t char1 = 0x00; ob_char_t char2 = 0x01; ob_char_t c = char1; if (c == ob_char) c = char2; ObTestAlloc((void **)&payload, 0, alloc_size); memset(payload, c, alloc_size); *payload_bytes = alloc_size; return payload; } static void SegmentPayload(Packet *p) { ob_size_t length; ob_size_t i; Segment *last; ObPacket *op = (ObPacket *)p; for (i = 0; i < p->dsize; i += length) { Segment *seg = NULL; length = rand() % 20 + 1; if (i + length > p->dsize) length = p->dsize - i; ObTestAlloc((void **)&seg, 0, sizeof(Segment)); ObTestAlloc((void **)&seg->data, 0, length); ObTestAlloc((void **)&seg->pkth, 0, sizeof(DAQ_PktHdr_t)); memcpy(seg->data, p->data + i, length); seg->size = length; seg->pkth->caplen = length; if (op->seglist == NULL) { op->seglist = seg; last = seg; } else { last->next = seg; last = seg; } if ((i + length) == p->dsize) break; } } void PrintUsage(char *prog) { fprintf(stderr, "Usage: %s [options]\n", prog); fprintf(stderr, " -a (add max length entry)\n"); fprintf(stderr, " -c \n"); fprintf(stderr, " -l \n"); fprintf(stderr, " -o \n"); fprintf(stderr, " -p \n"); fprintf(stderr, " -s (use segmentation)\n"); fprintf(stderr, " -r (reverse entries before sorting)\n"); } int main(int argc, char *argv[]) { char c; char *payload_file = NULL; ob_char_t ob_char = 'X'; int segment = 0; int reverse = 0; int add_maxlen = 0; ob_size_t ob_offset = 50; ob_size_t ob_length = 16; uint8_t *payload = NULL; ob_size_t payload_bytes = 0; ob_size_t offset = 0; DAQ_PktHdr_t pkth, *pkthtmp; Packet packet; while ((c = getopt(argc, argv, "ac:l:o:p:rsh")) != -1) { switch (c) { case 'a': add_maxlen = 1; break; case 'c': ob_char = (ob_char_t)strtol(optarg, NULL, 0); break; case 'l': { int value; if (!isdigit(optarg[0])) { PrintUsage(argv[0]); fprintf(stderr, "Obfuscation max length must be a " "positive integer.\n"); exit(1); } value = atoi(optarg); if (value > UINT16_MAX) { PrintUsage(argv[0]); fprintf(stderr, "Obfuscation max length must be " "less than 65535.\n"); exit(1); } ob_length = (ob_size_t)value; } break; case 'o': { int value; if (!isdigit(optarg[0])) { PrintUsage(argv[0]); fprintf(stderr, "Obfuscation offset must be a " "positive integer.\n"); exit(1); } value = atoi(optarg); if (value > UINT16_MAX) { PrintUsage(argv[0]); fprintf(stderr, "Obfuscation max offset must " "be less than 65535.\n"); exit(1); } ob_offset = (ob_size_t)value; } break; case 'p': payload_file = strdup(optarg); if (payload_file == NULL) { PrintUsage(argv[0]); fprintf(stderr, "Failed to copy payload file.\n"); exit(1); } break; case 'r': reverse = 1; break; case 's': segment = 1; break; case 'h': PrintUsage(argv[0]); exit(0); default: PrintUsage(argv[0]); fprintf(stderr, "Invalid option. Use -h for usage.\n"); exit(1); } } srand(time(NULL)); if (payload_file != NULL) { payload = GetPayloadFromFile(payload_file, &payload_bytes); if (payload == NULL) { fprintf(stderr, "Failed to get data from \"%s\"\n", payload_file); exit(1); } } else { payload = GetStaticPayload(ob_char, &payload_bytes); } ObTestAlloc((void **)&ob_payload, 0, payload_bytes); obApi->resetObfuscationEntries(); memset(&packet, 0, sizeof(packet)); pkthtmp = (DAQ_PktHdr_t *)&packet.pkth; pkthtmp = &pkth; pkthtmp->caplen = payload_bytes; pkthtmp->ts.tv_sec = 0; pkthtmp->ts.tv_usec = 0; packet.packet_flags |= PKT_PAYLOAD_OBFUSCATE; packet.data = payload; packet.dsize = payload_bytes; CreateObEntries(&packet, ob_char, ob_offset, ob_length, reverse, add_maxlen); //obApi->printObfuscationEntries(); if (segment) { SegmentPayload(&packet); if (obApi->payloadObfuscationRequired(&packet)) obApi->obfuscateStreamSegments(&packet, ObCallback, &offset); } else { if (obApi->payloadObfuscationRequired(&packet)) obApi->obfuscatePayload(&packet, ObCallback, &offset); } free(payload); free(ob_payload); if (payload_file != NULL) free(payload_file); return 0; } #endif /* OBFUSCATION_TEST_STANDALONE */ snort-2.9.15.1/src/obfuscation.h0000644000175200017520000002203113571422607013322 00000000000000/****************************************************************************** * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2009-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ******************************************************************************/ #ifndef __OBFUSCATION_H__ #define __OBFUSCATION_H__ #include #include "decode.h" /******************************************************************************* * Macros ******************************************************************************/ /* This should be defined to be greater than or equal to the maximum * amount of data expected to be obfuscated */ #define OB_LENGTH_MAX UINT16_MAX /******************************************************************************* * Types ******************************************************************************/ typedef uint8_t ob_char_t; typedef uint16_t ob_size_t; typedef enum _ObRet { OB_RET_SUCCESS, OB_RET_ERROR, OB_RET_OVERFLOW } ObRet; /******************************************************************************* * Callback to use for obfuscating payload or stream segments - see API below. * * The first chunk of a payload or stream segment whether needing obfuscation * or not will pass a valid pcap_pkthdr struct. Subsequent calls will pass NULL * for this structure. This is useful, especially for the stream segment API * call to know when a new segment begins. Any new "payload" will have a valid * pcap_pkthdr struct. * * If the slice sent in has a non-NULL packet data pointer, the data should *NOT* * be obfuscated. * * If the chunk sent in has a NULL packet data pointer, then that chunk of data * should be obfuscated with the obfuscation character. * * The length passed in is the amount of data that should be copied from the * packet data pointer or the amount of data that should be written with the * obfuscation character. * * Arguments * DAQ_PktHdr_t *pkth * The pcap header that contains the packet caplen and timestamps * uint8_t *packet_data * A pointer to the current offset into the packet data. NULL if * obfuscation of the payload slice is required. * ob_char_t ob_char * The obfuscation character to use if packet_data is NULL. * ob_size_t length * The amount of data to be logged or obfuscated. * void *user_data * The user data passed in to the API functions obfuscatePayload() or * obfuscateStreamSegments below. * * Returns * OB_RET_SUCCESS if all is good * OB_RET_ERROR if the rest of the obfuscation should not be done * ******************************************************************************/ typedef ObRet (*ObfuscationCallback) ( const DAQ_PktHdr_t *pkth, const uint8_t *packet_data, ob_size_t length, ob_char_t ob_char, void *user_data ); /******************************************************************************* * Obfuscation API ******************************************************************************/ typedef struct _ObfuscationApi { /* * Resets/clears any entries that have been added * Should be done per packet aquisition * * Arguments * None * * Returns * None */ void (*resetObfuscationEntries)(void); /* * Adds an obfuscation entry to the queue * * Arguments * Packet *p * The Packet struct that has the payload data that should be obfuscated * ob_size_t offset * The offset from the beginning of the payload to start obfuscation * ob_size_t length * The amount of data to obfuscate * ob_char_t ob_char * The character to use when obfuscating * * There are two types of entries that can be added. A slice entry that * has an offset and length less than OB_LENGTH_MAX and an entry with * length OB_LENGTH_MAX that implies obfuscating from offset to the end * of the packet data. * * NOTE -- * There is a fixed size of slice entries and OB_LENGTH_MAX entries. * If OB_RET_OVERFLOW is returned when attempting to add a slice entry, * a second call can be made to add an OB_LENGTH_MAX entry. Only one * OB_LENGTH_MAX entry can be associated with each Packet. If there is * already an OB_LENGTH_MAX entry for the packet, the lower of the two * offsets will be used. Although you should check for OB_RET_OVERFLOW * when attempting to add an OB_LENGTH_MAX entry, the fixed size should * be more than enough space to store an entry for each possible packet * that could be in the system at the time. * * Returns * OB_RET_SUCCESS on sucess * OB_RET_ERROR on error * OB_RET_OVERFLOW if there is no space left to add an entry */ ObRet (*addObfuscationEntry)(Packet *p, ob_size_t offset, ob_size_t length, ob_char_t ob_char); /* * Determines if there are any obfuscation entries associated with * the given Packet * * Arguments * Packet * * The Packet to check * * Returns * 1 if the packet requires obfuscation * 0 if it doesn't */ int (*payloadObfuscationRequired)(Packet *p); /* * Obfuscate the payload associated with the Packet. Mainly for use by the * output system to print or log an obfuscated payload. The callback will * be called for both payload segments that need obfuscation and those that * don't. See comment on ObfuscationCallback above. * * Arguments * Packet * * The Packet whose payload should be obfuscated * ObfuscationCallback * The function that will be called for each obfuscated and * non-obfuscated segment in the payload * void * * User data that will be passed to the callback * * Returns * OB_RET_SUCCESS on sucess * OB_RET_ERROR on error */ ObRet (*obfuscatePacket)(Packet *p, ObfuscationCallback callback, void *user_data); /* * Obfuscate the stream segments associated with the Packet. Mainly for use * by the output system to print or log the stream segments associated with * a Packet that have been marked as needing obfuscation. The callback will * be called for both stream segments that need obfuscation and those that * don't. It will be called for all stream segments. See comment on * ObfuscationCallback above. * * Arguments * Packet * * The Packet whose stream segments should be obfuscated * ObfuscationCallback * The function that will be called for each obfuscated and * non-obfuscated part of the stream segments. * void * * User data that will be passed to the callback * * Returns * OB_RET_SUCCESS on sucess * OB_RET_ERROR on error */ ObRet (*obfuscatePacketStreamSegments)(Packet *p, ObfuscationCallback callback, void *user_data); /* * Obfuscates the Packet payload and returns payload and payload length * in parameters * * NOTE * *payload will be set to NULL, so don't pass in an already * allocated pointer. * *payload_len will be zeroed. * * The payload returned is dynamically allocated and MUST be free'd. * * Arguments * Packet * * The Packet whose payload should be obfuscated * uint8_t **payload * A pointer to a payload pointer so it can be allocated, returned * and accessed. * ob_size_t *payload_len * A pointer to an ob_size_t so the length can be returned. * * Returns * OB_RET_ERROR if the payload could not be obfuscated * the pointers to payload and payload_len will not be valid * OB_RET_SUCCESS if the payload was obfuscated * the pointers to payload and payload_len will be valid */ ObRet (*getObfuscatedPayload)(Packet *p, uint8_t **payload, ob_size_t *payload_len); /* * Prints the current obfuscation entries. * * Arguments * int sorted * Print the sorted entries and sort if necessary. * * Returns * None */ void (*printObfuscationEntries)(int sorted); } ObfuscationApi; /* For access when including header */ extern ObfuscationApi *obApi; #endif /* __OBFUSCATION_H__ */ snort-2.9.15.1/src/rule_option_types.h0000644000175200017520000000533313571422607014577 00000000000000/**************************************************************************** * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2008-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #ifndef RULE_OPTION_TYPES__H #define RULE_OPTION_TYPES__H typedef enum _option_type_t { RULE_OPTION_TYPE_LEAF_NODE, RULE_OPTION_TYPE_ASN1, RULE_OPTION_TYPE_BYTE_TEST, RULE_OPTION_TYPE_BYTE_JUMP, RULE_OPTION_TYPE_BYTE_EXTRACT, RULE_OPTION_TYPE_FLOW, RULE_OPTION_TYPE_CVS, RULE_OPTION_TYPE_DSIZE, RULE_OPTION_TYPE_FLOWBIT, RULE_OPTION_TYPE_FTPBOUNCE, RULE_OPTION_TYPE_ICMP_CODE, RULE_OPTION_TYPE_ICMP_ID, RULE_OPTION_TYPE_ICMP_SEQ, RULE_OPTION_TYPE_ICMP_TYPE, RULE_OPTION_TYPE_IP_FRAGBITS, RULE_OPTION_TYPE_IP_FRAG_OFFSET, RULE_OPTION_TYPE_IP_ID, RULE_OPTION_TYPE_IP_OPTION, RULE_OPTION_TYPE_IP_PROTO, RULE_OPTION_TYPE_IP_SAME, RULE_OPTION_TYPE_IP_TOS, RULE_OPTION_TYPE_IS_DATA_AT, RULE_OPTION_TYPE_FILE_DATA, RULE_OPTION_TYPE_FILE_TYPE, RULE_OPTION_TYPE_BASE64_DECODE, RULE_OPTION_TYPE_BASE64_DATA, RULE_OPTION_TYPE_PKT_DATA, RULE_OPTION_TYPE_CONTENT, RULE_OPTION_TYPE_CONTENT_URI, RULE_OPTION_TYPE_PCRE, #ifdef ENABLE_REACT RULE_OPTION_TYPE_REACT, #endif #ifdef ENABLE_RESPOND RULE_OPTION_TYPE_RESPOND, #endif RULE_OPTION_TYPE_RPC_CHECK, RULE_OPTION_TYPE_SESSION, RULE_OPTION_TYPE_TCP_ACK, RULE_OPTION_TYPE_TCP_FLAG, RULE_OPTION_TYPE_TCP_SEQ, RULE_OPTION_TYPE_TCP_WIN, RULE_OPTION_TYPE_TTL, RULE_OPTION_TYPE_URILEN, RULE_OPTION_TYPE_HDR_OPT_CHECK, RULE_OPTION_TYPE_PREPROCESSOR, #if !defined(FEAT_OPEN_APPID) RULE_OPTION_TYPE_DYNAMIC #else /* defined(FEAT_OPEN_APPID) */ RULE_OPTION_TYPE_DYNAMIC, RULE_OPTION_TYPE_APPID #endif /* defined(FEAT_OPEN_APPID) */ ,RULE_OPTION_TYPE_BYTE_MATH } option_type_t; #endif /* RULE_OPTION_TYPES__H */ snort-2.9.15.1/src/sfdaq.c0000644000175200017520000006067413571422607012116 00000000000000/* $Id$ */ /**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2005-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ // @file sfdaq.c // @author Russ Combs #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sfdaq.h" #include "snort.h" #include "decode.h" #include "util.h" #include "sfutil/strvec.h" #include "sfcontrol_funcs.h" #define PKT_SNAPLEN 1514 #ifdef DEFAULT_DAQ #define XSTR(s) STR(s) #define STR(s) #s #define DAQ_DEFAULT XSTR(DEFAULT_DAQ) #else #define DAQ_DEFAULT "pcap" #endif #ifdef REG_TEST #ifndef DAQ_CAPA_INJECT_RAW #define DAQ_CAPA_INJECT_RAW 0x200 #endif #endif static char* interface_spec = NULL; static const DAQ_Module_t* daq_mod = NULL; static void* daq_hand = NULL; static DAQ_Mode daq_mode = DAQ_MODE_PASSIVE; static uint32_t snap = PKT_SNAPLEN; static int daq_dlt = -1; static int loaded = 0; static int s_error = DAQ_SUCCESS; static DAQ_Stats_t daq_stats, tot_stats; uint8_t file_io_buffer1[UINT16_MAX]; static void DAQ_Accumulate(void); typedef struct _MsgHeader_test { uint8_t event; uint8_t version; uint16_t total_length; uint8_t key_type; uint8_t key_size; } MsgHeader_test; #ifdef HAVE_DAQ_QUERYFLOW static inline ssize_t Read_test(int fd, void *buf, size_t count) { ssize_t n; errno = 0; while ((n = read(fd, buf, count)) <= (ssize_t) count) { if (n == (ssize_t) count) return 0; if (n > 0) { buf = (uint8_t *) buf + n; count -= n; } else if (n == 0) break; else if (errno != EINTR) { ErrorMessage("Error reading from Stream HA message file: %s (%d)\n", strerror(errno), errno); break; } } return -1; } #endif //-------------------------------------------------------------------- void DAQ_Load (const SnortConfig* sc) { const char** dirs = StringVector_GetVector(sc->daq_dirs); int err = daq_load_modules(dirs); if ( err ) FatalError("Can't load DAQ modules = %d\n", err); loaded = 1; } void DAQ_Unload () { daq_unload_modules(); loaded = 0; } //-------------------------------------------------------------------- int DAQ_PrintTypes (FILE* f) { DAQ_Module_Info_t* list = NULL; int i, nMods = daq_get_module_list(&list); if ( nMods ) fprintf(f, "Available DAQ modules:\n"); else fprintf(f, "No available DAQ modules " "(try adding directories with --daq-dir).\n"); for ( i = 0; i < nMods; i++ ) { fprintf(f, "%s(v%u):", list[i].name, list[i].version); if ( list[i].type & DAQ_TYPE_FILE_CAPABLE ) fprintf(f, " %s", "readback"); if ( list[i].type & DAQ_TYPE_INTF_CAPABLE ) fprintf(f, " %s", "live"); if ( list[i].type & DAQ_TYPE_INLINE_CAPABLE ) fprintf(f, " %s", "inline"); if ( list[i].type & DAQ_TYPE_MULTI_INSTANCE ) fprintf(f, " %s", "multi"); if ( !(list[i].type & DAQ_TYPE_NO_UNPRIV) ) fprintf(f, " %s", "unpriv"); fprintf(f, "\n"); } daq_free_module_list(list, nMods); return 0; } DAQ_Mode DAQ_GetInterfaceMode(const DAQ_PktHdr_t *h) { #ifdef DAQ_PKT_FLAG_NOT_FORWARDING // interface is not inline, so return passive if (h->flags & DAQ_PKT_FLAG_NOT_FORWARDING) return DAQ_MODE_PASSIVE; #endif // interface is inline if ( ScAdapterInlineMode() ) { return DAQ_MODE_INLINE; } // interface is passive or readback return DAQ_MODE_PASSIVE; } DAQ_Mode DAQ_GetMode (const SnortConfig* sc) { if ( sc->daq_mode ) { int i; for ( i = 0; i < MAX_DAQ_MODE; i++ ) { if ( !strcasecmp(daq_mode_string((DAQ_Mode)i), sc->daq_mode) ) { if ( ScAdapterInlineMode() && (i != DAQ_MODE_INLINE) ) FatalError("DAQ '%s' mode incompatible with -Q!\n", sc->daq_mode); return (DAQ_Mode)i; } } FatalError("Bad DAQ mode '%s'!\n", sc->daq_mode); } if ( ScAdapterInlineMode() ) return DAQ_MODE_INLINE; if ( ScReadMode() ) return DAQ_MODE_READ_FILE; return DAQ_MODE_PASSIVE; } //-------------------------------------------------------------------- static int DAQ_ValidateModule (DAQ_Mode mode) { uint32_t have = daq_get_type(daq_mod); uint32_t need = 0; if ( mode == DAQ_MODE_READ_FILE ) need |= DAQ_TYPE_FILE_CAPABLE; else if ( mode == DAQ_MODE_PASSIVE ) need |= DAQ_TYPE_INTF_CAPABLE; else need |= DAQ_TYPE_INLINE_CAPABLE; return ( (have & need) != 0 ); } static int DAQ_ValidateInstance () { uint32_t caps = daq_get_capabilities(daq_mod, daq_hand); if ( !ScAdapterInlineMode() ) return 1; if ( !(caps & DAQ_CAPA_BLOCK) ) LogMessage("WARNING: inline mode configured but DAQ can't " "block packets.\n"); #if 0 // this is checked in normalize.c and sp_respond.c // and warned/disabled only if it was configured if ( !(caps & DAQ_CAPA_REPLACE) ) { LogMessage("WARNING: normalizations/replacements disabled " " because DAQ can't replace packets.\n"); } // this is checked in spp_stream5.c and active.c // and warned/disabled only if it was configured if ( !(caps & DAQ_CAPA_INJECT) ) LogMessage("WARNING: inline mode configured but DAQ can't " "inject packets.\n"); #endif return 1; } void DAQ_UpdateTunnelBypass(SnortConfig* sc) { #ifdef HAVE_DAQ_REAL_ADDRESSES if (daq_mod && daq_hand) { uint32_t caps = daq_get_capabilities(daq_mod, daq_hand); if (caps & DAQ_CAPA_DECODE_GTP) { sc->tunnel_mask |= TUNNEL_GTP; LogMessage("DAQ tracking internal GTP sessions.\n"); } if (caps & DAQ_CAPA_DECODE_TEREDO) { sc->tunnel_mask |= TUNNEL_TEREDO; LogMessage("DAQ tracking internal TEREDO sessions.\n"); } if (caps & DAQ_CAPA_DECODE_GRE) { sc->tunnel_mask |= TUNNEL_GRE; LogMessage("DAQ tracking internal GRE sessions.\n"); } if (caps & DAQ_CAPA_DECODE_4IN4) { sc->tunnel_mask |= TUNNEL_4IN4; LogMessage("DAQ tracking internal IPv4 within IPv4 sessions.\n"); } if (caps & DAQ_CAPA_DECODE_6IN4) { sc->tunnel_mask |= TUNNEL_6IN4; LogMessage("DAQ tracking internal IPv6 within IPv4 sessions.\n"); } if (caps & DAQ_CAPA_DECODE_4IN6) { sc->tunnel_mask |= TUNNEL_4IN6; LogMessage("DAQ tracking internal IPv4 within IPv6 sessions.\n"); } if (caps & DAQ_CAPA_DECODE_6IN6) { sc->tunnel_mask |= TUNNEL_6IN6; LogMessage("DAQ tracking internal IPv6 within IPv6 sessions.\n"); } #ifdef DAQ_CAPA_DECODE_MPLS if (caps & DAQ_CAPA_DECODE_MPLS) { sc->tunnel_mask |= TUNNEL_MPLS; LogMessage("DAQ tracking internal MPLS sessions.\n"); } #endif } #endif } //-------------------------------------------------------------------- #if HAVE_DAQ_HUP_APPLY static int DAQ_PreControl(uint16_t type, const uint8_t *data, uint32_t length, void **new_config, char *statusBuf, int statusBuf_len) { if (daq_mod && daq_hand) return daq_hup_prep(daq_mod, daq_hand, new_config); return -1; } static int DAQ_Control(uint16_t type, void *new_config, void **old_config) { if (daq_mod && daq_hand) return daq_hup_apply(daq_mod, daq_hand, new_config, old_config); return -1; } static void DAQ_PostControl(uint16_t type, void *old_config, struct _THREAD_ELEMENT *te, ControlDataSendFunc f) { if (daq_mod && daq_hand) daq_hup_post(daq_mod, daq_hand, old_config); } #endif //-------------------------------------------------------------------- void DAQ_Init (const SnortConfig* sc) { const char* type = DAQ_DEFAULT; if ( !loaded ) DAQ_Load(sc); if ( sc->daq_type ) type = sc->daq_type; daq_mod = daq_find_module(type); if ( !daq_mod ) FatalError("Can't find %s DAQ!\n", type); snap = ( sc->pkt_snaplen > 0 ) ? sc->pkt_snaplen : PKT_SNAPLEN; daq_mode = DAQ_GetMode(sc); if ( !DAQ_ValidateModule(daq_mode) ) FatalError("%s DAQ does not support %s.\n", type, daq_mode_string(daq_mode)); memset(&daq_stats, 0, sizeof(daq_stats)); memset(&tot_stats, 0, sizeof(tot_stats)); LogMessage("%s DAQ configured to %s.\n", type, daq_mode_string(daq_mode)); #if HAVE_DAQ_HUP_APPLY if (ControlSocketRegisterHandler(CS_TYPE_HUP_DAQ, &DAQ_PreControl, &DAQ_Control, &DAQ_PostControl)) { LogMessage("Failed to register the DAQ control handler.\n"); } #else LogMessage("The DAQ version does not support reload.\n"); #endif } void DAQ_Term () { #ifndef WIN32 # ifndef DISABLE_DLCLOSE_FOR_VALGRIND_TESTING if ( loaded ) DAQ_Unload(); daq_mod = NULL; # endif #endif } void DAQ_Abort () { if ( DAQ_WasStarted() ) DAQ_Stop(); DAQ_Delete(); DAQ_Term(); } //-------------------------------------------------------------------- const char* DAQ_GetInterfaceSpec (void) { return interface_spec ? interface_spec : ""; } const char* DAQ_GetType(void) { return daq_mod ? daq_get_name(daq_mod) : "error"; } // Snort has its own snap applied to packets it acquires via the DAQ. This // should not be confused with the snap that was used to capture a pcap which // may be different. uint32_t DAQ_GetSnapLen (void) { return snap; } // That distinction does not hold with datalink types. Snort must use whatever // datalink type the DAQ coughs up as its base protocol decoder. For pcaps, // the datalink type in the file must be used - which may not be known until // start. The value is cached here since it used for packet operations like // logging and is needed at shutdown. this avoids sequencing issues. int DAQ_GetBaseProtocol (void) { return daq_dlt; } int DAQ_Unprivileged (void) { return !( daq_get_type(daq_mod) & DAQ_TYPE_NO_UNPRIV ); } int DAQ_UnprivilegedStart (void) { #ifdef INLINE_FAILOPEN return ( (daq_get_capabilities(daq_mod, daq_hand) & DAQ_CAPA_UNPRIV_START) || (ScUid() == -1 && ScGid() == -1) ); #else return ( (daq_get_capabilities(daq_mod, daq_hand) & DAQ_CAPA_UNPRIV_START) ); #endif } int DAQ_CanReplace (void) { return ( daq_get_capabilities(daq_mod, daq_hand) & DAQ_CAPA_REPLACE ); } int DAQ_CanInject (void) { return ( daq_get_capabilities(daq_mod, daq_hand) & DAQ_CAPA_INJECT ); } #if defined(DAQ_CAPA_CST_TIMEOUT) int DAQ_CanGetTimeout(void) { return ( daq_get_capabilities(daq_mod, daq_hand) & DAQ_CAPA_CST_TIMEOUT); } #endif #if defined(DAQ_CAPA_VRF) int DAQ_CanGetVrf(void) { return ( daq_get_capabilities(daq_mod, daq_hand) & DAQ_CAPA_VRF ); } #endif int DAQ_CanWhitelist (void) { #ifdef DAQ_CAPA_WHITELIST return ( daq_get_capabilities(daq_mod, daq_hand) & DAQ_CAPA_WHITELIST ); #else return 0; #endif } int DAQ_CanRetry (void) { #ifdef HAVE_DAQ_VERDICT_RETRY return ( daq_get_capabilities(daq_mod, daq_hand) & DAQ_CAPA_RETRY ); #else return 0; #endif } int DAQ_RawInjection (void) { return ( daq_get_capabilities(daq_mod, daq_hand) & DAQ_CAPA_INJECT_RAW ); } int DAQ_SetFilter(const char* bpf) { int err = 0; if ( bpf ) err = daq_set_filter(daq_mod, daq_hand, bpf); if ( err ) FatalError("Can't set DAQ BPF filter to '%s' (%s)!\n", bpf, daq_get_error(daq_mod, daq_hand)); return err; } //-------------------------------------------------------------------- static void DAQ_LoadVars (DAQ_Config_t* cfg, const SnortConfig* sc) { unsigned i = 0; do { char* key = StringVector_Get(sc->daq_vars, i++); char* val = NULL; if ( !key ) break; val = strchr(key, '='); if ( val ) *val++ = '\0'; daq_config_set_value(cfg, key, val); if ( val ) *--val = '='; } while ( 1 ); } static int DAQ_Config (DAQ_Config_t* cfg) { int err; char buf[256] = ""; const char* type = daq_get_name(daq_mod); // ideally this would be configurable ... if ( !strcasecmp(type, "dump") ) cfg->extra = (char*)daq_find_module("pcap"); err = daq_initialize(daq_mod, cfg, &daq_hand, buf, sizeof(buf)); if ( err ) FatalError("Can't initialize DAQ %s (%d) - %s\n", type, err, buf); return err; } //-------------------------------------------------------------------- int DAQ_New (const SnortConfig* sc, const char* intf) { DAQ_Config_t cfg; if ( !daq_mod ) FatalError("DAQ_Init not called!\n"); if ( intf ) interface_spec = SnortStrdup(intf); intf = DAQ_GetInterfaceSpec(); memset(&cfg, 0, sizeof(cfg)); cfg.name = (char*)intf; cfg.snaplen = snap; cfg.timeout = PKT_TIMEOUT; cfg.mode = daq_mode; cfg.extra = NULL; cfg.flags = 0; DAQ_LoadVars(&cfg, sc); if ( !ScReadMode() ) { if ( !(sc->run_flags & RUN_FLAG__NO_PROMISCUOUS) ) cfg.flags |= DAQ_CFG_PROMISC; } DAQ_Config(&cfg); if ( !DAQ_ValidateInstance() ) FatalError("DAQ configuration incompatible with intended operation.\n"); if ( DAQ_UnprivilegedStart() ) daq_dlt = daq_get_datalink_type(daq_mod, daq_hand); if ( intf && *intf ) { LogMessage("Acquiring network traffic from \"%s\".\n", strcmp(intf, "-") == 0 ? "stdin" : intf); } DAQ_SetFilter(sc->bpf_filter); daq_config_clear_values(&cfg); return 0; } int DAQ_Delete(void) { if ( daq_hand ) { DAQ_Accumulate(); daq_shutdown(daq_mod, daq_hand); daq_hand = NULL; } if ( interface_spec ) { free(interface_spec); interface_spec = NULL; } return 0; } //-------------------------------------------------------------------- int DAQ_Start () { int err = daq_start(daq_mod, daq_hand); if ( err ) FatalError("Can't start DAQ (%d) - %s!\n", err, daq_get_error(daq_mod, daq_hand)); else if ( !DAQ_UnprivilegedStart() ) daq_dlt = daq_get_datalink_type(daq_mod, daq_hand); return err; } int DAQ_WasStarted (void) { DAQ_State s; if ( !daq_mod || !daq_hand ) return 0; s = daq_check_status(daq_mod, daq_hand); return ( DAQ_STATE_STARTED == s ); } int DAQ_Stop () { int err = daq_stop(daq_mod, daq_hand); if ( err ) LogMessage("Can't stop DAQ (%d) - %s!\n", err, daq_get_error(daq_mod, daq_hand)); return err; } //-------------------------------------------------------------------- #ifdef HAVE_DAQ_ACQUIRE_WITH_META static DAQ_Meta_Func_t daq_meta_callback = NULL; void DAQ_Set_MetaCallback(DAQ_Meta_Func_t meta_callback) { daq_meta_callback = meta_callback; } #endif int DAQ_Acquire (int max, DAQ_Analysis_Func_t callback, uint8_t* user) { #if HAVE_DAQ_ACQUIRE_WITH_META int err = daq_acquire_with_meta(daq_mod, daq_hand, max, callback, daq_meta_callback, user); #else int err = daq_acquire(daq_mod, daq_hand, max, callback, user); #endif if ( err && err != DAQ_READFILE_EOF ) LogMessage("Can't acquire (%d) - %s!\n", err, daq_get_error(daq_mod, daq_hand)); if ( s_error != DAQ_SUCCESS ) { err = s_error; s_error = DAQ_SUCCESS; } return err; } int DAQ_Inject(const DAQ_PktHdr_t* h, int rev, const uint8_t* buf, uint32_t len) { int err = daq_inject(daq_mod, daq_hand, (DAQ_PktHdr_t*)h, buf, len, rev); #ifdef DEBUG if ( err ) LogMessage("Can't inject (%d) - %s!\n", err, daq_get_error(daq_mod, daq_hand)); #endif return err; } int DAQ_BreakLoop (int error) { s_error = error; return ( daq_breakloop(daq_mod, daq_hand) == DAQ_SUCCESS ); } //-------------------------------------------------------------------- static void DAQ_Accumulate (void) { int i; const DAQ_Stats_t* ps = DAQ_GetStats(); tot_stats.hw_packets_received += ps->hw_packets_received; tot_stats.hw_packets_dropped += ps->hw_packets_dropped; tot_stats.packets_received += ps->packets_received; tot_stats.packets_filtered += ps->packets_filtered; tot_stats.packets_injected += ps->packets_injected; for ( i = 0; i < MAX_DAQ_VERDICT; i++ ) tot_stats.verdicts[i] += ps->verdicts[i]; } // returns statically allocated stats - don't free const DAQ_Stats_t* DAQ_GetStats (void) { int err = 0; if ( !daq_hand && !ScPcapReset() ) return &tot_stats; if ( !daq_hand ) return &daq_stats; err = daq_get_stats(daq_mod, daq_hand, &daq_stats); if ( err ) LogMessage("Can't get DAQ stats (%d) - %s!\n", err, daq_get_error(daq_mod, daq_hand)); if ( !daq_stats.hw_packets_received ) // some DAQs don't provide hw numbers // so we default hw rx to the sw equivalent // (this means outstanding packets = 0) daq_stats.hw_packets_received = daq_stats.packets_received + daq_stats.packets_filtered; return &daq_stats; } //-------------------------------------------------------------------- #ifdef HAVE_DAQ_EXT_MODFLOW int DAQ_ModifyFlowOpaque(const DAQ_PktHdr_t *hdr, uint32_t opaque) { DAQ_ModFlow_t mod; mod.type = DAQ_MODFLOW_TYPE_OPAQUE; mod.length = sizeof(opaque); mod.value = &opaque; return daq_modify_flow(daq_mod, daq_hand, hdr, &mod); } int DAQ_ModifyFlowHAState(const DAQ_PktHdr_t *hdr, const void *data, uint32_t length) { #ifdef REG_TEST return 0; #else DAQ_ModFlow_t mod; mod.type = DAQ_MODFLOW_TYPE_HA_STATE; mod.length = length; mod.value = data; return daq_modify_flow(daq_mod, daq_hand, hdr, &mod); #endif } int DAQ_ModifyFlow(const DAQ_PktHdr_t *hdr, const DAQ_ModFlow_t* mod) { return daq_modify_flow(daq_mod, daq_hand, hdr, mod); } #else int DAQ_ModifyFlowOpaque(const DAQ_PktHdr_t *hdr, uint32_t opaque) { #ifdef HAVE_DAQ_ACQUIRE_WITH_META DAQ_ModFlow_t mod; mod.opaque = opaque; return daq_modify_flow(daq_mod, daq_hand, hdr, &mod); #else return DAQ_ERROR_NOTSUP; #endif } #endif #ifdef HAVE_DAQ_QUERYFLOW #ifndef REG_TEST int DAQ_QueryFlow(const DAQ_PktHdr_t *hdr, DAQ_QueryFlow_t* query) { return daq_query_flow(daq_mod, daq_hand, hdr, query); } #else int DAQ_QueryFlow(DAQ_PktHdr_t *hdr, DAQ_QueryFlow_t* query) { int rval,fd; MsgHeader_test *msg_header; uint8_t *msg; #if defined DAQ_QUERYFLOW_TYPE_IS_CONN_META_VALID if (query->type == DAQ_QUERYFLOW_TYPE_IS_CONN_META_VALID) return DAQ_ERROR_NOTSUP; #endif fd = * ((int * )hdr->priv_ptr); if (fd < 0) { return -1; } msg = file_io_buffer1; while ((rval = Read_test(fd, msg, sizeof(*msg_header))) == 0) { msg_header = (MsgHeader_test *) msg; if (msg_header->total_length < sizeof(*msg_header)) { ErrorMessage("Stream HA Message total length (%hu) is way too short!\n", msg_header->total_length); close(fd); return -1; } else if (msg_header->total_length > (UINT16_MAX - sizeof(*msg_header))) { ErrorMessage("Stream HA Message total length (%hu) is too long!\n", msg_header->total_length); close(fd); return -1; } else if (msg_header->total_length > sizeof(*msg_header) && (query->type == DAQ_QUERYFLOW_TYPE_HA_STATE)) { if ((rval = Read_test(fd, msg + sizeof(*msg_header), msg_header->total_length - sizeof(*msg_header))) != 0) { ErrorMessage("Error reading the remaining %zu bytes of an HA message from file: %s (%d)\n", msg_header->total_length - sizeof(*msg_header), strerror(errno), errno); close(fd); return rval; } DAQ_HA_State_Data_t *haState; haState = (DAQ_HA_State_Data_t *)query->value; haState->length = msg_header->total_length; haState->data = msg_header; return 0; } } return 0; } #endif #endif #if defined(DAQ_VERSION) && DAQ_VERSION > 8 void DAQ_DebugPkt(uint8_t moduleId, uint8_t logLevel, const DAQ_Debug_Packet_Params_t *params, const char *msg, ...) { #ifdef LOGC_DEBUG_PACKET va_list args_copy; va_start(args_copy, msg); daq_debug_packet(daq_mod,daq_hand, moduleId, logLevel, params, msg, args_copy); va_end(args_copy); #else { //do nothing here. } #endif } #endif #ifdef HAVE_DAQ_DP_ADD_DC /* * Initialize key for dynamic channel and call daq api method to notify firmware * of the expected dynamic channel. */ void DAQ_Add_Dynamic_Protocol_Channel(const Packet *ctrlPkt, sfaddr_t* cliIP, uint16_t cliPort, sfaddr_t* srvIP, uint16_t srvPort, uint8_t protocol, DAQ_DC_Params* params) { DAQ_DP_key_t dp_key; #ifdef HAVE_DAQ_DATA_CHANNEL_SEPARATE_IP_VERSIONS dp_key.src_af = sfaddr_family(cliIP); if (AF_INET == dp_key.src_af) { dp_key.sa.src_ip4.s_addr = sfaddr_get_ip4_value(cliIP); } else { memcpy(&dp_key.sa.src_ip6, sfaddr_get_ip6_ptr(cliIP), sizeof(dp_key.sa.src_ip6)); } dp_key.dst_af = sfaddr_family(srvIP); if (AF_INET == dp_key.dst_af) { dp_key.da.dst_ip4.s_addr = sfaddr_get_ip4_value(srvIP); } else { memcpy(&dp_key.da.dst_ip6, sfaddr_get_ip6_ptr(srvIP), sizeof(dp_key.da.dst_ip6)); } #else dp_key.af = sfaddr_family(cliIP); if( dp_key.af == AF_INET ) { dp_key.sa.src_ip4.s_addr = sfaddr_get_ip4_value(cliIP); dp_key.da.dst_ip4.s_addr = sfaddr_get_ip4_value(srvIP); } else { memcpy( &dp_key.sa.src_ip6, sfaddr_get_ip6_ptr(cliIP), sizeof( dp_key.sa.src_ip6 ) ); memcpy( &dp_key.da.dst_ip6, sfaddr_get_ip6_ptr(srvIP), sizeof( dp_key.da.dst_ip6 ) ); } #endif dp_key.protocol = protocol; dp_key.src_port = cliPort; dp_key.dst_port = srvPort; dp_key.vlan_cnots = 1; if( ctrlPkt->vh ) dp_key.vlan_id = VTH_VLAN( ctrlPkt->vh ); else dp_key.vlan_id = 0xFFFF; if( ctrlPkt->GTPencapsulated ) dp_key.tunnel_type = DAQ_DP_TUNNEL_TYPE_GTP_TUNNEL; #ifdef DAQ_DP_TUNNEL_TYPE_MPLS_TUNNEL else if ( ctrlPkt->mpls ) dp_key.tunnel_type = DAQ_DP_TUNNEL_TYPE_MPLS_TUNNEL; #endif else if ( ctrlPkt->encapsulated ) dp_key.tunnel_type = DAQ_DP_TUNNEL_TYPE_OTHER_TUNNEL; else dp_key.tunnel_type = DAQ_DP_TUNNEL_TYPE_NON_TUNNEL; // notify the firmware to add expected flow for this dynamic channel #ifdef HAVE_DAQ_DATA_CHANNEL_PARAMS { DAQ_Data_Channel_Params_t daq_params; memset(&daq_params, 0, sizeof(daq_params)); daq_params.timeout_ms = params->timeout_ms; if (params->flags & DAQ_DC_FLOAT) daq_params.flags |= DAQ_DATA_CHANNEL_FLOAT; if (params->flags & DAQ_DC_ALLOW_MULTIPLE) daq_params.flags |= DAQ_DATA_CHANNEL_ALLOW_MULTIPLE; if (params->flags & DAQ_DC_PERSIST) daq_params.flags |= DAQ_DATA_CHANNEL_PERSIST; daq_dp_add_dc(daq_mod, daq_hand, ctrlPkt->pkth, &dp_key, ctrlPkt->pkt, &daq_params); } #else daq_dp_add_dc( daq_mod, daq_hand, ctrlPkt->pkth, &dp_key, ctrlPkt->pkt ); #endif } #endif #if defined(DAQ_VERSION) && DAQ_VERSION > 9 int DAQ_Ioctl(unsigned int type, char *buf, size_t *size) { return daq_ioctl(daq_mod, daq_hand, type, buf, size); } #endif snort-2.9.15.1/src/sfdaq.h0000644000175200017520000001206713571422607012114 00000000000000/* $Id$ */ /**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2005-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ // @file sfdaq.h // @author Russ Combs #ifndef __DAQ_H__ #define __DAQ_H__ #include #include #include "ipv6_port.h" #define PKT_TIMEOUT 1000 // ms, worst daq resolution is 1 sec struct _SnortConfig; #include "decode.h" void DAQ_Load(const struct _SnortConfig*); void DAQ_Unload(void); void DAQ_Init(const struct _SnortConfig*); void DAQ_Term(void); void DAQ_Abort(void); int DAQ_PrintTypes(FILE*); const char* DAQ_GetType(void); int DAQ_Unprivileged(void); int DAQ_UnprivilegedStart(void); int DAQ_CanReplace(void); int DAQ_CanInject(void); int DAQ_CanWhitelist(void); int DAQ_CanRetry (void); int DAQ_RawInjection(void); #if defined(DAQ_CAPA_CST_TIMEOUT) int DAQ_CanGetTimeout(void); #endif #if defined(DAQ_CAPA_VRF) int DAQ_CanGetVrf(void); #endif const char* DAQ_GetInterfaceSpec(void); uint32_t DAQ_GetSnapLen(void); int DAQ_GetBaseProtocol(void); int DAQ_SetFilter(const char*); // total stats are accumulated when daq is deleted int DAQ_New(const struct _SnortConfig*, const char* intf); void DAQ_UpdateTunnelBypass(struct _SnortConfig*); int DAQ_Delete(void); int DAQ_Start(void); int DAQ_WasStarted(void); int DAQ_Stop(void); // TBD some stuff may be inlined once encapsulations are straight // (but only where performance justifies exposing implementation!) int DAQ_Acquire(int max, DAQ_Analysis_Func_t, uint8_t* user); int DAQ_Inject(const DAQ_PktHdr_t*, int rev, const uint8_t* buf, uint32_t len); int DAQ_BreakLoop(int error); #ifdef HAVE_DAQ_ACQUIRE_WITH_META void DAQ_Set_MetaCallback(DAQ_Meta_Func_t meta_callback); #endif DAQ_Mode DAQ_GetInterfaceMode(const DAQ_PktHdr_t *h); int DAQ_ModifyFlowOpaque(const DAQ_PktHdr_t *hdr, uint32_t opaque); #ifdef HAVE_DAQ_EXT_MODFLOW int DAQ_ModifyFlowHAState(const DAQ_PktHdr_t *hdr, const void *data, uint32_t length); int DAQ_ModifyFlow(const DAQ_PktHdr_t *hdr, const DAQ_ModFlow_t* mod); #endif #ifdef HAVE_DAQ_QUERYFLOW #ifdef REG_TEST int DAQ_QueryFlow( DAQ_PktHdr_t *hdr, DAQ_QueryFlow_t* query); #else int DAQ_QueryFlow(const DAQ_PktHdr_t *hdr, DAQ_QueryFlow_t* query); #endif #endif #if defined(DAQ_VERSION) && DAQ_VERSION > 8 void DAQ_DebugPkt(uint8_t moduleId, uint8_t logLevel, const DAQ_Debug_Packet_Params_t *params, const char *msg, ...); #endif #ifdef HAVE_DAQ_DP_ADD_DC typedef struct _DAQ_DC_Params { unsigned flags; unsigned timeout_ms; } DAQ_DC_Params; #define DAQ_DC_FLOAT 0x01 #define DAQ_DC_ALLOW_MULTIPLE 0x02 #define DAQ_DC_PERSIST 0x04 void DAQ_Add_Dynamic_Protocol_Channel(const Packet *ctrlPkt, sfaddr_t* cliIP, uint16_t cliPort, sfaddr_t* srvIP, uint16_t srvPort, uint8_t protocol, DAQ_DC_Params* params); #endif #ifdef DAQ_CAPA_VRF static inline uint16_t DAQ_GetSourceAddressSpaceID(const DAQ_PktHdr_t *h) { return h->address_space_id_src; } static inline uint16_t DAQ_GetDestinationAddressSpaceID(const DAQ_PktHdr_t *h) { return h->address_space_id_dst; } #endif #ifdef HAVE_DAQ_ADDRESS_SPACE_ID static inline uint16_t DAQ_GetAddressSpaceID(const DAQ_PktHdr_t *h) { return h->address_space_id; } #endif // returns total stats if no daq else current stats // returns statically allocated stats - don't free const DAQ_Stats_t* DAQ_GetStats(void); #if defined (DAQ_VERSION) && DAQ_VERSION >9 #define SNORT_DEBUG_PKT_LOG(pkth,moduleId,logLevel,msg,args...)\ {\ DAQ_Debug_Packet_Params_t daq_pkt_params;\ if((pkth) && ((pkth)->flags & DAQ_PKT_FLAG_DEBUG_ON))\ {\ daq_pkt_params.pkt_hdr = (DAQ_PktHdr_t *)(pkth);\ DAQ_DebugPkt(moduleId, logLevel, &daq_pkt_params, msg, ##args);\ }\ } #endif #if defined(DAQ_VERSION) && DAQ_VERSION > 9 #define DEBUG_SNORT_ENGINE(p, logLevel, format, args...) \ { \ SNORT_DEBUG_PKT_LOG(p->pkth, DAQ_DEBUG_PKT_MODULE_SNORT_ENGINE, logLevel, format, ##args) \ } #else #define DEBUG_SNORT_ENGINE(p, logLevel, format, args...) \ { \ } #endif #if defined(DAQ_VERSION) && DAQ_VERSION > 9 int DAQ_Ioctl(unsigned int type, char *buf, size_t *size); #endif #endif // __DAQ_H__ snort-2.9.15.1/src/reload.c0000644000175200017520000010221413571422607012251 00000000000000/* ** ** reload.c ** ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_GETTID #define _GNU_SOURCE #endif #include #include #include #include "reload.h" #include "snort.h" #include "parser.h" #include "sfcontrol_funcs.h" #include "sfcontrol.h" #include "mpse.h" #include "sp_flowbits.h" #include "sp_dynamic.h" #include "rate_filter.h" #include "file_service_config.h" #include "so_rule_mem_adjust.h" #include "file_service.h" #ifdef INTEL_SOFT_CPM #include "intel-soft-cpm.h" #endif #ifdef HAVE_MALLOC_TRIM #include #endif #ifdef SIDE_CHANNEL # include "sidechannel.h" #endif #ifdef SNORT_RELOAD #include "sftarget_reader.h" #endif #ifdef REG_TEST #include "reg_test.h" #endif extern volatile int attribute_reload_thread_running; extern int reload_attribute_table_flags; #if defined(SNORT_RELOAD) void ReloadFreeAdjusters(SnortConfig* sc) { ReloadAdjustEntry* rae; while ((rae = sc->raEntry)) { sc->raEntry = rae->raNext; if (rae->raUserFreeFunc && rae->raUserData) rae->raUserFreeFunc(rae->raUserData); free(rae); } if ((rae = sc->raSessionEntry)) { if (rae->raUserFreeFunc && rae->raUserData) rae->raUserFreeFunc(rae->raUserData); free(rae); sc->raSessionEntry = NULL; } } static ReloadAdjustEntry* ReloadAdjustRegisterAlloc(const char* raName, tSfPolicyId raPolicyId, ReloadAdjustFunc raFunc, void* raUserData, ReloadAdjustUserFreeFunc raUserFreeFunc) { static const char* raUnspecified = "Unspecified"; ReloadAdjustEntry* rae; if ((rae = (ReloadAdjustEntry*)calloc(1, sizeof*rae))) { rae->raName = raName ? raName : raUnspecified; rae->raPolicyId = raPolicyId; rae->raFunc = raFunc; rae->raUserData = raUserData; rae->raUserFreeFunc = raUserFreeFunc; LogMessage("Registered %s to adjust for reload.\n", rae->raName); } return rae; } int ReloadAdjustRegister(SnortConfig* sc, const char* raName, tSfPolicyId raPolicyId, ReloadAdjustFunc raFunc, void* raUserData, ReloadAdjustUserFreeFunc raUserFreeFunc) { ReloadAdjustEntry* rae; rae = ReloadAdjustRegisterAlloc(raName, raPolicyId, raFunc, raUserData, raUserFreeFunc); if (!rae) return -1; rae->raNext = sc->raEntry; sc->raEntry = rae; return 0; } int ReloadAdjustSessionRegister(SnortConfig* sc, const char* raName, tSfPolicyId raPolicyId, ReloadAdjustFunc raFunc, void* raUserData, ReloadAdjustUserFreeFunc raUserFreeFunc) { ReloadAdjustEntry* rae; rae = ReloadAdjustRegisterAlloc(raName, raPolicyId, raFunc, raUserData, raUserFreeFunc); if (!rae) return -1; sc->raSessionEntry = rae; return 0; } #endif #if defined(SNORT_RELOAD) && !defined(WIN32) && defined(CONTROL_SOCKET) static volatile bool reloadInProgress = false; static pthread_mutex_t reload_mutex = PTHREAD_MUTEX_INITIALIZER; #endif #if defined(SNORT_RELOAD) && !defined(WIN32) static volatile int snort_swapped = 0; SnortConfig *snort_conf_new = NULL; static SnortConfig *snort_conf_old = NULL; #endif bool SnortDynamicLibsChanged(void) { if (detection_lib_changed) return true; return false; } void CheckForReload(void) { #if defined(SNORT_RELOAD) && !defined(WIN32) /* Check for a new configuration */ if (snort_reload) { PostConfigFuncNode *idxPlugin; snort_reload = 0; /* There was an error reloading. A non-reloadable configuration * option changed */ if (snort_conf_new == NULL) { #ifdef RELOAD_ERROR_FATAL CleanExit(1); #else Restart(); #endif } snort_conf_old = snort_conf; snort_conf = snort_conf_new; snort_conf_new = NULL; FileServiceInstall(); ScRestoreInternalLogLevel(); SwapPreprocConfigurations(snort_conf); /* Need to do this here because there is potentially outstanding * state data pointing to the previous configuration. A race * condition is created if these are free'd in the reload thread * where a double free could occur. */ FreeSwappedPreprocConfigurations(snort_conf); #ifdef INTEL_SOFT_CPM if (snort_conf->fast_pattern_config->search_method == MPSE_INTEL_CPM) IntelPmActivate(snort_conf); #endif snort_swapped = 1; setNapRuntimePolicy( getParserPolicy(snort_conf) ); setIpsRuntimePolicy( getParserPolicy(snort_conf) ); /* Do any reload for plugin data */ idxPlugin = plugin_reload_funcs; while(idxPlugin) { idxPlugin->func(snort_conf, SIGHUP, idxPlugin->arg); idxPlugin = idxPlugin->next; } } #endif } #if defined(SNORT_RELOAD) && !defined(WIN32) static int VerifyLibInfos(DynamicLibInfo *old_info, DynamicLibInfo *new_info) { if ((old_info != NULL) && (new_info != NULL)) { unsigned i; if (old_info->type != new_info->type) { FatalError("%s(%d) Incompatible library types.\n", __FILE__, __LINE__); } if (old_info->count != new_info->count) return -1; for (i = 0; i < old_info->count; i++) { unsigned j; DynamicLibPath *old_path = old_info->lib_paths[i]; for (j = 0; j < new_info->count; j++) { DynamicLibPath *new_path = new_info->lib_paths[j]; if ((strcmp(old_path->path, new_path->path) == 0) && (old_path->ptype == new_path->ptype)) { if (old_path->last_mod_time != new_path->last_mod_time) return -1; break; } } if (j == new_info->count) return -1; } } else if (old_info != new_info) { return -1; } return 0; } static int VerifyOutputs(SnortConfig *old_config, SnortConfig *new_config) { OutputConfig *old_output_config, *new_output_config; int old_outputs = 0, new_outputs = 0; /* Get from output_configs to see if output has changed */ for (old_output_config = old_config->output_configs; old_output_config != NULL; old_output_config = old_output_config->next) { old_outputs++; } for (new_output_config = new_config->output_configs; new_output_config != NULL; new_output_config = new_output_config->next) { new_outputs++; } if (new_outputs != old_outputs) { ErrorMessage("Snort Reload: Any change to any output " "configurations requires a restart.\n"); return -1; } for (old_output_config = old_config->output_configs; old_output_config != NULL; old_output_config = old_output_config->next) { for (new_output_config = new_config->output_configs; new_output_config != NULL; new_output_config = new_output_config->next) { if (strcasecmp(old_output_config->keyword, new_output_config->keyword) == 0) { if ((old_output_config->opts != NULL) && (new_output_config->opts != NULL) && (strcasecmp(old_output_config->opts, new_output_config->opts) == 0)) { new_outputs++; break; } else if (old_output_config->opts == NULL && new_output_config->opts == NULL) { new_outputs++; break; } } } old_outputs++; } if (new_outputs != old_outputs) { ErrorMessage("Snort Reload: Any change to any output " "configurations requires a restart.\n"); return -1; } /* Check user defined rule type outputs */ for (old_output_config = old_config->rule_type_output_configs; old_output_config != NULL; old_output_config = old_output_config->next) { old_outputs++; } for (new_output_config = new_config->rule_type_output_configs; new_output_config != NULL; new_output_config = new_output_config->next) { new_outputs++; } if (new_outputs != old_outputs) { ErrorMessage("Snort Reload: Any change to any output " "configurations requires a restart.\n"); return -1; } /* Do user defined rule type outputs as well */ for (old_output_config = old_config->rule_type_output_configs; old_output_config != NULL; old_output_config = old_output_config->next) { for (new_output_config = new_config->rule_type_output_configs; new_output_config != NULL; new_output_config = new_output_config->next) { if (strcasecmp(old_output_config->keyword, new_output_config->keyword) == 0) { if (old_output_config->opts && new_output_config->opts) { if (strcasecmp(old_output_config->opts, new_output_config->opts) == 0) { new_outputs++; break; } } if (!old_output_config->opts && !new_output_config->opts) { new_outputs++; break; } } } old_outputs++; } if (new_outputs != old_outputs) { ErrorMessage("Snort Reload: Any change to any output " "configurations requires a restart.\n"); return -1; } return 0; } static int VerifyReload(SnortConfig *sc) { if (sc == NULL) return -1; #ifdef TARGET_BASED { SnortPolicy *p1 = sc->targeted_policies[getDefaultPolicy()]; SnortPolicy *p2 = snort_conf->targeted_policies[getDefaultPolicy()]; if ((p1->target_based_config.args != NULL) && (p2->target_based_config.args != NULL)) { if (strcasecmp(p1->target_based_config.args, p2->target_based_config.args) != 0) { ErrorMessage("Snort Reload: Changing the attribute table " "configuration requires a restart.\n"); return -1; } } } #endif if ((snort_conf->alert_file != NULL) && (sc->alert_file != NULL)) { if (strcasecmp(snort_conf->alert_file, sc->alert_file) != 0) { ErrorMessage("Snort Reload: Changing the alert file " "configuration requires a restart.\n"); return -1; } } else if (snort_conf->alert_file != sc->alert_file) { ErrorMessage("Snort Reload: Changing the alert file " "configuration requires a restart.\n"); return -1; } if (snort_conf->asn1_mem != sc->asn1_mem) { ErrorMessage("Snort Reload: Changing the asn1 memory configuration " "requires a restart.\n"); return -1; } if ((sc->bpf_filter == NULL) && (sc->bpf_file != NULL)) sc->bpf_filter = read_infile(sc->bpf_file); if ((sc->bpf_filter != NULL) && (snort_conf->bpf_filter != NULL)) { if (strcasecmp(snort_conf->bpf_filter, sc->bpf_filter) != 0) { ErrorMessage("Snort Reload: Changing the bpf filter configuration " "requires a restart.\n"); return -1; } } else if (sc->bpf_filter != snort_conf->bpf_filter) { ErrorMessage("Snort Reload: Changing the bpf filter configuration " "requires a restart.\n"); return -1; } #ifdef ACTIVE_RESPONSE if ( sc->respond_attempts != snort_conf->respond_attempts || sc->respond_device != snort_conf->respond_device ) { ErrorMessage("Snort Reload: Changing config response " "requires a restart.\n"); return -1; } #endif if ((snort_conf->chroot_dir != NULL) && (sc->chroot_dir != NULL)) { if (strcasecmp(snort_conf->chroot_dir, sc->chroot_dir) != 0) { ErrorMessage("Snort Reload: Changing the chroot directory " "configuration requires a restart.\n"); return -1; } } else if (snort_conf->chroot_dir != sc->chroot_dir) { ErrorMessage("Snort Reload: Changing the chroot directory " "configuration requires a restart.\n"); return -1; } if ((snort_conf->run_flags & RUN_FLAG__DAEMON) != (sc->run_flags & RUN_FLAG__DAEMON)) { ErrorMessage("Snort Reload: Changing to or from daemon mode " "requires a restart.\n"); return -1; } if ((snort_conf->interface != NULL) && (sc->interface != NULL)) { if (strcasecmp(snort_conf->interface, sc->interface) != 0) { ErrorMessage("Snort Reload: Changing the interface " "configuration requires a restart.\n"); return -1; } } else if (snort_conf->interface != sc->interface) { ErrorMessage("Snort Reload: Changing the interface " "configuration requires a restart.\n"); return -1; } /* Orig log dir because a chroot might have changed it */ if ((snort_conf->orig_log_dir != NULL) && (sc->orig_log_dir != NULL)) { if (strcasecmp(snort_conf->orig_log_dir, sc->orig_log_dir) != 0) { ErrorMessage("Snort Reload: Changing the log directory " "configuration requires a restart.\n"); return -1; } } else if (snort_conf->orig_log_dir != sc->orig_log_dir) { ErrorMessage("Snort Reload: Changing the log directory " "configuration requires a restart.\n"); return -1; } if (snort_conf->no_log != sc->no_log) { ErrorMessage("Snort Reload: Changing from log to no log or vice " "versa requires a restart.\n"); return -1; } if ((snort_conf->run_flags & RUN_FLAG__NO_PROMISCUOUS) != (sc->run_flags & RUN_FLAG__NO_PROMISCUOUS)) { ErrorMessage("Snort Reload: Changing to or from promiscuous mode " "requires a restart.\n"); return -1; } #ifdef PERF_PROFILING if ((snort_conf->profile_rules.num != sc->profile_rules.num) || (snort_conf->profile_rules.sort != sc->profile_rules.sort) || (snort_conf->profile_rules.append != sc->profile_rules.append)) { ErrorMessage("Snort Reload: Changing rule profiling number, sort " "or append configuration requires a restart.\n"); return -1; } if ((snort_conf->profile_rules.filename != NULL) && (sc->profile_rules.filename != NULL)) { if (strcasecmp(snort_conf->profile_rules.filename, sc->profile_rules.filename) != 0) { ErrorMessage("Snort Reload: Changing the rule profiling filename " "configuration requires a restart.\n"); return -1; } } else if (snort_conf->profile_rules.filename != sc->profile_rules.filename) { ErrorMessage("Snort Reload: Changing the rule profiling filename " "configuration requires a restart.\n"); return -1; } if ((snort_conf->profile_preprocs.num != sc->profile_preprocs.num) || (snort_conf->profile_preprocs.sort != sc->profile_preprocs.sort) || (snort_conf->profile_preprocs.append != sc->profile_preprocs.append)) { ErrorMessage("Snort Reload: Changing preprocessor profiling number, " "sort or append configuration requires a restart.\n"); return -1; } if ((snort_conf->profile_preprocs.filename != NULL) && (sc->profile_preprocs.filename != NULL)) { if (strcasecmp(snort_conf->profile_preprocs.filename, sc->profile_preprocs.filename) != 0) { ErrorMessage("Snort Reload: Changing the preprocessor profiling " "filename configuration requires a restart.\n"); return -1; } } else if (snort_conf->profile_preprocs.filename != sc->profile_preprocs.filename) { ErrorMessage("Snort Reload: Changing the preprocessor profiling " "filename configuration requires a restart.\n"); return -1; } #endif if (snort_conf->group_id != sc->group_id) { ErrorMessage("Snort Reload: Changing the group id " "configuration requires a restart.\n"); return -1; } if (snort_conf->user_id != sc->user_id) { ErrorMessage("Snort Reload: Changing the user id " "configuration requires a restart.\n"); return -1; } if (snort_conf->pkt_snaplen != sc->pkt_snaplen) { ErrorMessage("Snort Reload: Changing the packet snaplen " "configuration requires a restart.\n"); return -1; } if (snort_conf->threshold_config->memcap != sc->threshold_config->memcap) { ErrorMessage("Snort Reload: Changing the threshold memcap " "configuration requires a restart.\n"); return -1; } if (snort_conf->rate_filter_config->memcap != sc->rate_filter_config->memcap) { ErrorMessage("Snort Reload: Changing the rate filter memcap " "configuration requires a restart.\n"); return -1; } if (snort_conf->detection_filter_config->memcap != sc->detection_filter_config->memcap) { ErrorMessage("Snort Reload: Changing the detection filter memcap " "configuration requires a restart.\n"); return -1; } if (VerifyLibInfos(snort_conf->dyn_engines, sc->dyn_engines) == -1) { ErrorMessage("Snort Reload: Any change to the dynamic engine " "configuration requires a restart.\n"); return -1; } if (VerifyLibInfos(snort_conf->dyn_rules, sc->dyn_rules) == -1) { LogMessage("Snort Reload: Dynamic detection libs have changed.\n"); detection_lib_changed = 1; } if (VerifyLibInfos(snort_conf->dyn_preprocs, sc->dyn_preprocs) == -1) { ErrorMessage("Snort Reload: Any change to the dynamic preprocessor " "configuration requires a restart.\n"); return -1; } if (snort_conf->so_rule_memcap != sc->so_rule_memcap) { AdjustSoRuleMemory(sc, snort_conf); } if (VerifyOutputs(snort_conf, sc) == -1) return -1; #ifdef SIDE_CHANNEL if (SideChannelVerifyConfig(sc) != 0) { ErrorMessage("Snort Reload: Changing the side channel configuration requires a restart.\n"); return -1; } #endif if (ScMaxIP6Extensions() != sc->max_ip6_extensions) { ErrorMessage("Snort Reload: Changing Max IP6 extensions " "configuration requires a restart.\n"); return -1; } return 0; } static SnortConfig * ReloadConfig(void) { SnortConfig *sc; if (ScSuppressConfigLog()) ScSetInternalLogLevel(INTERNAL_LOG_LEVEL__ERROR); #ifdef HAVE_MALLOC_TRIM malloc_trim(0); #endif sc = ParseSnortConf(); sc = MergeSnortConfs(snort_cmd_line_conf, sc); sc->reloadPolicyFlag = 1; #ifdef PERF_PROFILING /* Parse profiling here because of file option and potential * dependence on log directory */ { char *opts = NULL; int in_table; in_table = sfghash_find2(sc->config_table, CONFIG_OPT__PROFILE_PREPROCS, (void *)&opts); if (in_table) ConfigProfilePreprocs(sc, opts); in_table = sfghash_find2(sc->config_table, CONFIG_OPT__PROFILE_RULES, (void *)&opts); if (in_table) ConfigProfileRules(sc, opts); } #endif if (VerifyReload(sc) == -1) { SnortConfFree(sc); return NULL; } DAQ_UpdateTunnelBypass(sc); if (sc->output_flags & OUTPUT_FLAG__USE_UTC) sc->thiszone = 0; else sc->thiszone = gmt2local(0); #ifdef TARGET_BASED SFAT_ReloadCheck(sc); #endif /* Preprocessors will have a reload callback */ ConfigurePreprocessors(sc, 1); FlowbitResetCounts(); ParseRules(sc); RuleOptParseCleanup(); /* Check if Dynamic detection libs have changed */ if (!detection_lib_changed) { pthread_mutex_lock(&dynamic_rules_lock); ReloadDynamicRules(sc); pthread_mutex_unlock(&dynamic_rules_lock); } else { ReloadDynamicDetectionLibs(sc); InitDynamicDetectionPlugins(sc); } /* Handles Fatal Errors itself. */ SnortEventqNew(sc->event_queue_config, sc->event_queue); detection_filter_print_config(sc->detection_filter_config); RateFilter_PrintConfig(sc->rate_filter_config); print_thresholding(sc->threshold_config, 0); PrintRuleOrder(sc->rule_lists); SetRuleStates(sc); if (file_sevice_config_verify(snort_conf, sc) == -1) { SnortConfFree(sc); return NULL; } if (VerifyReloadedPreprocessors(sc)) { SnortConfFree(sc); return NULL; } if (CheckPreprocessorsConfig(sc)) { SnortConfFree(sc); return NULL; } FilterConfigPreprocessors(sc); PostConfigPreprocessors(sc); /* Need to do this after dynamic detection stuff is initialized, too */ FlowBitsVerify(); if ((sc->file_mask != 0) && (sc->file_mask != snort_conf->file_mask)) umask(sc->file_mask); /* Transfer any user defined rule type outputs to the new rule list */ { RuleListNode *cur = snort_conf->rule_lists; for (; cur != NULL; cur = cur->next) { RuleListNode *new = sc->rule_lists; for (; new != NULL; new = new->next) { if (strcasecmp(cur->name, new->name) == 0) { OutputFuncNode *alert_list = cur->RuleList->AlertList; OutputFuncNode *log_list = cur->RuleList->LogList; sc->head_tmp = new->RuleList; for (; alert_list != NULL; alert_list = alert_list->next) { AddFuncToOutputList(sc, alert_list->func, OUTPUT_TYPE__ALERT, alert_list->arg); } for (; log_list != NULL; log_list = log_list->next) { AddFuncToOutputList(sc, log_list->func, OUTPUT_TYPE__LOG, log_list->arg); } sc->head_tmp = NULL; break; } } } } /* XXX XXX Can't do any output plugins */ //PostConfigInitPlugins(sc->plugin_post_config_funcs); fpCreateFastPacketDetection(sc); #ifdef PPM_MGR PPM_PRINT_CFG(&sc->ppm_cfg); #endif #if defined(DAQ_VERSION) && DAQ_VERSION > 9 // This is needed when PPM is disabled and enabling snort-engine debugs if (!ppm_tpu) ppm_tpu = (PPM_TICKS)get_ticks_per_usec(); #endif // Restores the configured logging level, if it was suppressed earlier ScRestoreInternalLogLevel(); return sc; } static void updatePeriodicCheck(void) { PeriodicCheckFuncNode *checkFunc; /* reset preprocessors */ checkFunc = periodic_check_funcs; while (checkFunc != NULL) { if ( 0 == checkFunc->time_left ) { checkFunc->func(-1, checkFunc->arg); checkFunc->time_left = checkFunc->period; //LogMessage(" --== Share Memory! ==--\n"); } else checkFunc->time_left--; checkFunc = checkFunc->next; } } void * ReloadConfigThread(void *data) { sigset_t mtmask; /* Don't handle any signals here */ sigfillset(&mtmask); pthread_sigmask(SIG_BLOCK, &mtmask, NULL); snort_reload_thread_pid = gettid(); snort_reload_thread_created = 1; while (snort_initializing) nanosleep(&thread_sleep, NULL); while (!snort_exiting) { if (reload_signal != reload_total) { int reload_failed = 0; #ifdef CONTROL_SOCKET pthread_mutex_lock(&reload_mutex); if (!reloadInProgress) { reloadInProgress = true; pthread_mutex_unlock(&reload_mutex); #endif reload_total++; LogMessage("\n"); LogMessage(" --== Reloading Snort ==--\n"); LogMessage("\n"); snort_conf_new = ReloadConfig(); // Restore Log level if we suppressed it earlier if (snort_conf_new == NULL) reload_failed = 1; snort_reload = 1; while (!snort_swapped && !snort_exiting) nanosleep(&thread_sleep, NULL); snort_swapped = 0; SnortConfFree(snort_conf_old); snort_conf_old = NULL; #ifdef INTEL_SOFT_CPM if (snort_conf->fast_pattern_config->search_method != MPSE_INTEL_CPM) IntelPmStopInstance(); #endif if (snort_exiting && !reload_failed) { /* This will load the new preprocessor configurations and * free the old ones, so any preprocessor cleanup that * requires a configuration will be using the new one * unless it relies on old configurations that are still * attached to existing sessions. */ SwapPreprocConfigurations(snort_conf); FreeSwappedPreprocConfigurations(snort_conf); #if defined (SIDE_CHANNEL) && defined (REG_TEST) if (snort_conf && snort_conf->file_config) FileSSConfigFree(snort_conf->file_config); #endif #ifdef CONTROL_SOCKET reloadInProgress = false; #endif /* Get out of the loop and exit */ break; } if (!reload_failed) { #if defined(TARGET_BASED) && !defined(WIN32) if(!IsAdaptiveConfigured()) { if(attribute_reload_thread_running) { ReloadAttributeThreadStop(); reload_attribute_table_flags = 0; #ifdef REG_TEST if(REG_TEST_FLAG_RELOAD & getRegTestFlags()) { printf("Adaptive profile disabled, attribute table cleared\n"); } #endif } SFAT_Cleanup(); SnortAddSignal(SIGNAL_SNORT_READ_ATTR_TBL, SigNoAttributeTableHandler, 1); } else if(IsAdaptiveConfigured() && ScDisableAttrReload(snort_conf)) { if(attribute_reload_thread_running) { ReloadAttributeThreadStop(); SFAT_CleanPrevConfig(); } SnortAddSignal(SIGNAL_SNORT_READ_ATTR_TBL, SigNoAttributeTableHandler, 1); } else if(IsAdaptiveConfigured() && !ScDisableAttrReload(snort_conf)) { SnortAddSignal(SIGNAL_SNORT_READ_ATTR_TBL,SigAttributeTableReloadHandler,0); } #endif while (snort_conf->raEntry) { sleep(1); } LogMessage("\n"); LogMessage(" --== Reload Complete ==--\n"); LogMessage("\n"); } #ifdef CONTROL_SOCKET reloadInProgress = false; } else pthread_mutex_unlock(&reload_mutex); #endif } /* Use the maintenance thread for periodic check*/ updatePeriodicCheck(); sleep(1); } pthread_exit((void *)0); } #endif #if defined(SNORT_RELOAD) && !defined(WIN32) && defined(CONTROL_SOCKET) static int ControlSocketReloadConfig(uint16_t type, const uint8_t *data, uint32_t length, void **new_config, char *statusBuf, int statusBuf_len) { SnortConfig *new_sc; pthread_mutex_lock(&reload_mutex); while (reloadInProgress || SnortIsInitializing()) { sleep(1); } reloadInProgress = true; pthread_mutex_unlock(&reload_mutex); LogMessage("\n"); LogMessage(" --== Reloading Snort ==--\n"); LogMessage("\n"); new_sc = ReloadConfig(); if (new_sc == NULL) { reloadInProgress = false; return -1; } *new_config = (void *)new_sc; return 0; } static int ControlSocketReloadSwap(uint16_t type, void *new_config, void **old_config) { PostConfigFuncNode *idxPlugin = NULL; *old_config = (void *)snort_conf; snort_conf = (SnortConfig *)new_config; FileServiceInstall(); SwapPreprocConfigurations(snort_conf); #ifdef INTEL_SOFT_CPM if (snort_conf->fast_pattern_config->search_method == MPSE_INTEL_CPM) IntelPmActivate(snort_conf); #endif /* Do any reload for plugin data */ idxPlugin = plugin_reload_funcs; while(idxPlugin) { idxPlugin->func(snort_conf, SIGHUP, idxPlugin->arg); idxPlugin = idxPlugin->next; } if (snort_conf->raSessionEntry) { /* Session is always the first to adjust */ snort_conf->raSessionEntry->raNext = snort_conf->raEntry; snort_conf->raEntry = snort_conf->raSessionEntry; snort_conf->raSessionEntry = NULL; } setNapRuntimePolicy( getParserPolicy(snort_conf) ); setIpsRuntimePolicy( getParserPolicy(snort_conf) ); #if defined(REG_TEST) && defined(PPM_MGR) if (REG_TEST_FLAG_RELOAD & getRegTestFlags()) { static char prev_ppm_cfg ; if (snort_conf->ppm_cfg.rule_log & PPM_LOG_MESSAGE) { if (! ( prev_ppm_cfg & PPM_LOG_MESSAGE) ) { printf("ppm rule-log set to PPM_LOG_MESSAGE\n"); prev_ppm_cfg |= PPM_LOG_MESSAGE; } } if( snort_conf->ppm_cfg.rule_log & PPM_LOG_ALERT ) { if ( ! ( prev_ppm_cfg & PPM_LOG_ALERT) ) { printf("ppm rule-log set to PPM_LOG_ALERT\n"); prev_ppm_cfg |= PPM_LOG_ALERT; } } } #endif return 0; } static void ControlSocketReloadFree(uint16_t type, void *old_config, struct _THREAD_ELEMENT *te, ControlDataSendFunc f) { SnortConfig *old_sc = (SnortConfig *)old_config; FreeSwappedPreprocConfigurations(snort_conf); SnortConfFree(old_sc); #ifdef INTEL_SOFT_CPM if (snort_conf->fast_pattern_config->search_method != MPSE_INTEL_CPM) IntelPmStopInstance(); #endif #if defined(TARGET_BASED) && !defined(WIN32) if(!IsAdaptiveConfigured()) { if(attribute_reload_thread_running) { ReloadAttributeThreadStop(); reload_attribute_table_flags = 0; #ifdef REG_TEST if(REG_TEST_FLAG_RELOAD & getRegTestFlags()) { printf("Adaptive profile disabled, attribute table cleared\n"); } #endif } SFAT_Cleanup(); SnortAddSignal(SIGNAL_SNORT_READ_ATTR_TBL, SigNoAttributeTableHandler, 1); } else if(IsAdaptiveConfigured() && ScDisableAttrReload(snort_conf)) { if(attribute_reload_thread_running) { ReloadAttributeThreadStop(); SFAT_CleanPrevConfig(); } SnortAddSignal(SIGNAL_SNORT_READ_ATTR_TBL, SigNoAttributeTableHandler, 1); } else if(IsAdaptiveConfigured() && !ScDisableAttrReload(snort_conf)) { SnortAddSignal(SIGNAL_SNORT_READ_ATTR_TBL,SigAttributeTableReloadHandler,0); } #endif while (snort_conf->raEntry && !snort_exiting ) sleep(1); if( !snort_conf->raEntry ) { LogMessage("\n"); LogMessage(" --== Reload Complete ==--\n"); LogMessage("\n"); } else { LogMessage(" Reloading Aborted \n"); } reloadInProgress = false; } #endif void ReloadControlSocketRegister(void) { #if defined(SNORT_RELOAD) && !defined(WIN32) && defined(CONTROL_SOCKET) if (ControlSocketRegisterHandler(CS_TYPE_RELOAD, &ControlSocketReloadConfig, &ControlSocketReloadSwap, &ControlSocketReloadFree)) { LogMessage("Failed to register the reload control handler.\n"); } #endif } snort-2.9.15.1/src/reload.h0000644000175200017520000000775713571422607012276 00000000000000/* ** ** reload.h ** ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** */ #ifndef __RELOAD_H__ #define __RELOAD_H__ #include #include "snort.h" #include "util.h" #include "reload_api.h" #include "sf_types.h" void CheckForReload(void); void ReloadControlSocketRegister(void); bool SnortDynamicLibsChanged(void); #if defined(SNORT_RELOAD) && !defined(WIN32) void * ReloadConfigThread(void *); #endif #if defined(SNORT_RELOAD) typedef struct _ReloadAdjustEntry { struct _ReloadAdjustEntry* raNext; const char* raName; tSfPolicyId raPolicyId; ReloadAdjustFunc raFunc; void* raUserData; ReloadAdjustUserFreeFunc raUserFreeFunc; } ReloadAdjustEntry; int ReloadAdjustRegister(SnortConfig* sc, const char* raName, tSfPolicyId raPolicyId, ReloadAdjustFunc raFunc, void* raUserData, ReloadAdjustUserFreeFunc raUserFreeFunc); int ReloadAdjustSessionRegister(SnortConfig* sc, const char* raName, tSfPolicyId raPolicyId, ReloadAdjustFunc raFunc, void* raUserData, ReloadAdjustUserFreeFunc raUserFreeFunc); void ReloadFreeAdjusters(SnortConfig* sc); static inline void ReloadAdjust(bool idle, time_t tv_sec) { ReloadAdjustEntry* rae = snort_conf->raEntry; if (rae) { static unsigned num_idle_callbacks = 0; static unsigned num_packet_callbacks = 0; static struct timeval adjust_started_at; if (rae != snort_conf->raCurrentEntry) { snort_conf->raCurrentEntry = rae; snort_conf->raLastLog = tv_sec; memset(&adjust_started_at, 0 , sizeof(adjust_started_at)); gettimeofday(&adjust_started_at, NULL); LogMessage("Adjusting %s during reload ( Started at : (%"PRIu64") milliseconds.\n", rae->raName, (uint64_t)(adjust_started_at.tv_sec * 1000 + adjust_started_at.tv_usec / 1000)); } if (idle) num_idle_callbacks++; else num_packet_callbacks++; if (rae->raFunc(idle, rae->raPolicyId, rae->raUserData)) { struct timeval curr_time; gettimeofday(&curr_time, NULL); LogMessage("Finished adjusting memory for %s : Total calls (packet loop=%u, idle loop=%u), Elapsed time = (%"PRIu64") milliseconds.\n", rae->raName, num_packet_callbacks, num_idle_callbacks, (uint64_t)((curr_time.tv_sec * 1000 + curr_time.tv_usec / 1000) - (adjust_started_at.tv_sec * 1000 + adjust_started_at.tv_usec / 1000)) ); num_idle_callbacks = 0; num_packet_callbacks = 0; memset(&adjust_started_at, 0 , sizeof(adjust_started_at)); snort_conf->raEntry = rae->raNext; free(rae); } else if (!snort_conf->raLastLog) snort_conf->raLastLog = tv_sec; else if ((unsigned)(tv_sec - snort_conf->raLastLog) >= 10) { snort_conf->raLastLog = tv_sec; WarningMessage("Waiting for %s to adjust for reload (packet loop=%u, idle loop=%u).\n", rae->raName, num_packet_callbacks, num_idle_callbacks); } } } #endif extern SnortConfig *snort_conf_new; #endif snort-2.9.15.1/src/reload_api.h0000644000175200017520000000326113571422607013111 00000000000000/* ** ** reload_api.h ** ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** */ #ifndef __RELOAD_API_H__ #define __RELOAD_API_H__ #ifdef SNORT_RELOAD /* The reload adjust function should do incremental adjustments to the running memory. The reload adjust function is registered using ReloadAdjustRegister from snort proper and _dpd.reloadAdjustRegister for plugins. The idle flag should be used to do more work when there is no traffic flowing. The user data is optional data needed to adjust the running memory. The function should return true if the adjustments are complete. */ typedef bool (*ReloadAdjustFunc)(bool idle, tSfPolicyId raPolicyId, void* userData); /* The reload adjust user free function is a function that can free the option user data associated with the reload adjust function. */ typedef void (*ReloadAdjustUserFreeFunc)(void* userData); #endif #endif snort-2.9.15.1/src/idle_processing.c0000644000175200017520000000405713571422607014162 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2011-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** * @file idle_processing.c * @author Ron Dempster * @date Tue Jun 17 17:09:59 2003 * * @brief Allow functions to be registered to be called when packet * processing is idle. * */ #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "idle_processing_funcs.h" #include "util.h" typedef struct _IDLE_HANDLER_ELEMENT { struct _IDLE_HANDLER_ELEMENT *next; IdleProcessingHandler handler; } IdleHandlerElement; static IdleHandlerElement *idle_handlers; int IdleProcessingRegisterHandler(IdleProcessingHandler func) { IdleHandlerElement *e; if ((e = calloc(1, sizeof(*e))) == NULL) { WarningMessage("%s\n", "Failed to allocate an idle handler element"); return -1; } e->handler = func; e->next = idle_handlers; idle_handlers = e; return 0; } void IdleProcessingExecute(void) { IdleHandlerElement *e; for (e = idle_handlers; e; e = e->next) e->handler(); } void IdleProcessingCleanUp(void) { IdleHandlerElement *e; while ((e = idle_handlers)) { idle_handlers = e->next; free(e); } } snort-2.9.15.1/src/idle_processing.h0000644000175200017520000000225013571422607014160 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2011-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #ifndef _IDLE_PROCESSING_H #define _IDLE_PROCESSING_H typedef void (*IdleProcessingHandler)(void); #endif /* _IDLE_PROCESSING_H */ snort-2.9.15.1/src/idle_processing_funcs.h0000644000175200017520000000245113571422607015361 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2011-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #ifndef _IDLE_PROCESSING_FUNCS_H #define _IDLE_PROCESSING_FUNCS_H #include "idle_processing.h" int IdleProcessingRegisterHandler(IdleProcessingHandler); void IdleProcessingExecute(void); void IdleProcessingCleanUp(void); #endif /* _IDLE_PROCESSING_FUNCS_H */ snort-2.9.15.1/src/appIdApi.h0000644000175200017520000002675613571422607012517 00000000000000/****************************************************************************** * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2009-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ******************************************************************************/ #ifndef __APPID_API_H__ #define __APPID_API_H__ #include "stdint.h" #include "stdbool.h" #include "ipv6_port.h" #include "sfghash.h" struct AppIdData; typedef int32_t tAppId; #define APPID_SESSION_RESPONDER_MONITORED (1ULL << 0) #define APPID_SESSION_INITIATOR_MONITORED (1ULL << 1) #define APPID_SESSION_SPECIAL_MONITORED (1ULL << 2) #define APPID_SESSION_INITIATOR_SEEN (1ULL << 3) #define APPID_SESSION_RESPONDER_SEEN (1ULL << 4) #define APPID_SESSION_DISCOVER_USER (1ULL << 5) #define APPID_SESSION_HAS_DHCP_FP (1ULL << 6) #define APPID_SESSION_HAS_DHCP_INFO (1ULL << 7) #define APPID_SESSION_HAS_SMB_INFO (1ULL << 8) #define APPID_SESSION_MID (1ULL << 9) #define APPID_SESSION_OOO (1ULL << 10) #define APPID_SESSION_SYN_RST (1ULL << 11) /**Service missed the first UDP packet in a flow. This causes detectors to see traffic in reverse direction. * Detectors should set this flag by verifying that packet from initiator is indeed a packet from responder. * Setting this flag without this check will cause RNA to not try other detectors in some cases (see bug 77551).*/ #define APPID_SESSION_UDP_REVERSED (1ULL << 12) #define APPID_SESSION_HTTP_SESSION (1ULL << 13) /**Service protocol was detected */ #define APPID_SESSION_SERVICE_DETECTED (1ULL << 14) /**Finsihed with client app detection */ #define APPID_SESSION_CLIENT_DETECTED (1ULL << 15) /**Flow is a data connection not a service */ #define APPID_SESSION_NOT_A_SERVICE (1ULL << 16) #define APPID_SESSION_DECRYPTED (1ULL << 17) #define APPID_SESSION_SERVICE_DELETED (1ULL << 18) //The following attributes are references only with appId /**Continue calling the routine after the service has been identified. */ #define APPID_SESSION_CONTINUE (1ULL << 19) /**Call service detection even if the host does not exist */ #define APPID_SESSION_IGNORE_HOST (1ULL << 20) /**Service protocol had incompatible client data */ #define APPID_SESSION_INCOMPATIBLE (1ULL << 21) /**we are ready to see out of network Server packets */ #define APPID_SESSION_CLIENT_GETS_SERVER_PACKETS (1ULL << 22) #define APPID_SESSION_DISCOVER_APP (1ULL << 23) #define APPID_SESSION_PORT_SERVICE_DONE (1ULL << 24) #define APPID_SESSION_ADDITIONAL_PACKET (1ULL << 25) #define APPID_SESSION_RESPONDER_CHECKED (1ULL << 26) #define APPID_SESSION_INITIATOR_CHECKED (1ULL << 27) #define APPID_SESSION_SSL_SESSION (1ULL << 28) #define APPID_SESSION_LOGIN_SUCCEEDED (1ULL << 29) #define APPID_SESSION_SPDY_SESSION (1ULL << 30) #define APPID_SESSION_ENCRYPTED (1ULL << 31) #define APPID_SESSION_APP_REINSPECT (1ULL << 32) #define APPID_SESSION_RESPONSE_CODE_CHECKED (1ULL << 33) #define APPID_SESSION_REXEC_STDERR (1ULL << 34) #define APPID_SESSION_CHP_INSPECTING (1ULL << 35) #define APPID_SESSION_STICKY_SERVICE (1ULL << 36) #define APPID_SESSION_APP_REINSPECT_SSL (1ULL << 37) #define APPID_SESSION_NO_TPI (1ULL << 38) #define APPID_SESSION_IGNORE_FLOW (1ULL << 39) #define APPID_SESSION_IGNORE_FLOW_LOGGED (1ULL << 40) #define APPID_SESSION_EXPECTED_EVALUATE (1ULL << 41) #define APPID_SESSION_HOST_CACHE_MATCHED (1ULL << 42) #define APPID_SESSION_OOO_CHECK_TP (1ULL << 43) #define APPID_SESSION_HTTP_TUNNEL (1ULL << 44) #define APPID_SESSION_HTTP_CONNECT (1ULL << 45) #define APPID_SESSION_IGNORE_ID_FLAGS (APPID_SESSION_IGNORE_FLOW | \ APPID_SESSION_NOT_A_SERVICE | \ APPID_SESSION_NO_TPI | \ APPID_SESSION_SERVICE_DETECTED | \ APPID_SESSION_PORT_SERVICE_DONE) typedef enum { APPID_FLOW_TYPE_IGNORE, APPID_FLOW_TYPE_NORMAL, APPID_FLOW_TYPE_TMP } APPID_FLOW_TYPE; typedef struct _RNAServiceSubtype { struct _RNAServiceSubtype *next; const char *service; const char *vendor; const char *version; } RNAServiceSubtype; #define DHCP_OP55_MAX_SIZE 64 #define DHCP_OP60_MAX_SIZE 64 typedef struct _DHCP_FP_DATA { struct _DHCP_FP_DATA *next; unsigned op55_len; unsigned op60_len; uint8_t op55[DHCP_OP55_MAX_SIZE]; uint8_t op60[DHCP_OP60_MAX_SIZE]; uint8_t mac[6]; } DhcpFPData; typedef struct _DHCPInfo { struct _DHCPInfo *next; uint32_t ipAddr; uint8_t macAddr[6]; uint32_t subnetmask; uint32_t leaseSecs; uint32_t router; } DHCPInfo; typedef struct _FpSMBData { struct _FpSMBData *next; unsigned major; unsigned minor; uint32_t flags; } FpSMBData; //maximum number of appIds replicated for a flow/session #define APPID_HA_SESSION_APP_NUM_MAX 8 #define APPID_HA_FLAGS_APP (1<<0) #define APPID_HA_FLAGS_TP_DONE (1<<1) #define APPID_HA_FLAGS_SVC_DONE (1<<2) #define APPID_HA_FLAGS_HTTP (1<<3) typedef struct _AppIdSessionHA { uint16_t flags; tAppId appId[APPID_HA_SESSION_APP_NUM_MAX]; } AppIdSessionHA; typedef enum { NOT_A_SEARCH_ENGINE, SUPPORTED_SEARCH_ENGINE, UNSUPPORTED_SEARCH_ENGINE, SEARCH_SUPPORT_TYPE_UNKNOWN, } SEARCH_SUPPORT_TYPE; typedef enum { REQ_AGENT_FID = 0, REQ_HOST_FID = 1, REQ_REFERER_FID = 2, REQ_URI_FID = 3, REQ_COOKIE_FID = 4, REQ_BODY_FID = 5, RSP_CONTENT_TYPE_FID = 6, RSP_LOCATION_FID = 7, RSP_BODY_FID = 8, HTTP_FIELD_MAX = RSP_BODY_FID } HTTP_FIELD_ID; /******************************************************************************* * AppId API ******************************************************************************/ struct AppIdApi { const char * (*getApplicationName)(int32_t appId); tAppId (*getApplicationId)(const char *appName); tAppId (*getServiceAppId)(struct AppIdData *session); tAppId (*getPortServiceAppId)(struct AppIdData *session); tAppId (*getOnlyServiceAppId)(struct AppIdData *session); tAppId (*getMiscAppId)(struct AppIdData *session); tAppId (*getClientAppId)(struct AppIdData *session); tAppId (*getPayloadAppId)(struct AppIdData *session); tAppId (*getReferredAppId)(struct AppIdData *session); tAppId (*getFwServiceAppId)(struct AppIdData *session); tAppId (*getFwMiscAppId)(struct AppIdData *session); tAppId (*getFwClientAppId)(struct AppIdData *session); tAppId (*getFwPayloadAppId)(struct AppIdData *session); tAppId (*getFwReferredAppId)(struct AppIdData *session); SFGHASH*(*getFwMultiPayloadList)(struct AppIdData *session); bool (*isSessionSslDecrypted)(struct AppIdData *session); bool (*isAppIdInspectingSession)(struct AppIdData *session); bool (*isAppIdAvailable)(struct AppIdData *session); char* (*getUserName)(struct AppIdData *session, tAppId *service, bool *isLoginSuccessful); char* (*getClientVersion)(struct AppIdData *session); uint64_t (*getAppIdSessionAttribute)(struct AppIdData *session, uint64_t flag); APPID_FLOW_TYPE (*getFlowType)(struct AppIdData *session); void (*getServiceInfo)(struct AppIdData *session, char **serviceVendor, char **serviceVersion, RNAServiceSubtype **subtype); short (*getServicePort)(struct AppIdData *session); sfaddr_t* (*getServiceIp)(struct AppIdData *session); struct in6_addr* (*getInitiatorIp)(struct AppIdData *session); char* (*getHttpUserAgent)(struct AppIdData *session); char* (*getHttpHost)(struct AppIdData *session); char* (*getHttpUrl)(struct AppIdData *session); char* (*getHttpReferer)(struct AppIdData *session); char* (*getHttpNewUrl)(struct AppIdData *session); char* (*getHttpUri)(struct AppIdData *session); char* (*getHttpResponseCode)(struct AppIdData *session); char* (*getHttpCookie)(struct AppIdData *session); char* (*getHttpNewCookie)(struct AppIdData *session); char* (*getHttpContentType)(struct AppIdData *session); char* (*getHttpLocation)(struct AppIdData *session); char* (*getHttpBody)(struct AppIdData *session); char* (*getHttpReqBody)(struct AppIdData *session); uint16_t (*getHttpUriOffset)(struct AppIdData *session); uint16_t (*getHttpUriEndOffset)(struct AppIdData *session); uint16_t (*getHttpCookieOffset)(struct AppIdData *session); uint16_t (*getHttpCookieEndOffset)(struct AppIdData *session); SEARCH_SUPPORT_TYPE (*getHttpSearch)(struct AppIdData *session); sfaddr_t* (*getHttpXffAddr)(struct AppIdData *session); char* (*getTlsHost)(struct AppIdData *session); DhcpFPData* (*getDhcpFpData)(struct AppIdData *session); void (*freeDhcpFpData)(struct AppIdData *session, DhcpFPData *data); DHCPInfo* (*getDhcpInfo)(struct AppIdData *session); void (*freeDhcpInfo)(struct AppIdData *session, DHCPInfo *data); FpSMBData* (*getSmbFpData)(struct AppIdData *session); void (*freeSmbFpData)(struct AppIdData *session, FpSMBData *data); char* (*getNetbiosName)(struct AppIdData *session); uint32_t (*produceHAState)(void *lwssn, uint8_t *buf); uint32_t (*consumeHAState)(void *lwssn, const uint8_t *buf, uint8_t length, uint8_t proto, const struct in6_addr* ip, uint16_t initiatorPort); struct AppIdData * (*getAppIdData)(void *lwssn); int (*getAppIdSessionPacketCount)(struct AppIdData *appIdData); char* (*getDNSQuery)(struct AppIdData *appIdData, uint8_t *query_len, bool *got_response); uint16_t (*getDNSQueryoffset)(struct AppIdData *appIdData); uint16_t (*getDNSRecordType)(struct AppIdData *appIdData); uint8_t (*getDNSResponseType)(struct AppIdData *appIdData); uint32_t (*getDNSTTL)(struct AppIdData *appIdData); uint16_t (*getDNSOptionsOffset)(struct AppIdData *appIdData); char* (*getHttpNewField)(struct AppIdData *session, HTTP_FIELD_ID fieldId); void (*freeHttpNewField)(struct AppIdData *appIdData, HTTP_FIELD_ID fieldId); uint16_t (*getHttpFieldOffset)(struct AppIdData *session, HTTP_FIELD_ID fieldId); uint16_t (*getHttpFieldEndOffset)(struct AppIdData *session, HTTP_FIELD_ID fieldId); bool (*isHttpInspectionDone)(struct AppIdData *session); void (*dumpDebugHostInfo)(void); }; /* For access when including header */ extern struct AppIdApi appIdApi; //#define UNIT_TESTING // NOTE These testing #define's are used in service_base.c and fw_appid.c //#define UNIT_TEST_FIRST_DECRYPTED_PACKET 12 // WARNING this assumes a single stream in a decrypted pcap #endif /* __APPID_API_H__ */ snort-2.9.15.1/src/reg_test.h0000644000175200017520000000415713571422607012633 00000000000000/* ** ** reg_test.h ** ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** */ #ifndef __REG_TEST_H__ #define __REG_TEST_H__ #ifdef REG_TEST #define REG_TEST_VARIABLE "SNORT_REG_TEST" #define REG_TEST_EMAIL_VARIABLE "SNORT_EMAIL_REG_TEST" #include #define REG_TEST_FLAG_SESSION_RELOAD (1 << 0) #define REG_TEST_FLAG_INCREMENT_IP_ADDRESS (1 << 1) #define REG_TEST_FLAG_RELOAD (1 << 2) #define REG_TEST_FLAG_PERFMON_RELOAD (1 << 3) #define REG_TEST_FLAG_APPDATA_ADJUSTER_RELOAD (1 << 4) #define REG_TEST_FLAG_FILE_CACHE (1 << 5) #define REG_TEST_FLAG_PORTSCAN_RELOAD (1 << 6) #define REG_TEST_FLAG_SESSION_FORCE_RELOAD (1 << 7) #define REG_TEST_FLAG_REPUTATION (1 << 8) #define REG_TEST_FLAG_STREAM_DECODE (1 << 9) #define REG_TEST_EMAIL_FLAG_MIME_MEMPOOL_ADJUST (1 << 0) #define REG_TEST_EMAIL_FLAG_LOG_MEMPOOL_ADJUST (1 << 1) #define REG_TEST_EMAIL_FLAG_DECODE_DEPTH_ADJUST (1 << 2) #define REG_TEST_EMAIL_FLAG_FD_MEMPOOL_ADJUST (1 << 3) #define REG_TEST_EMAIL_FLAG_GZIP_MEMPOOL_ADJUST (1 << 4) #define REG_TEST_EMAIL_FLAG_HTTP_MEMPOOL_ADJUST (1 << 5) extern uint32_t rt_ip_increment; uint64_t getRegTestFlags(void); uint64_t getRegTestFlagsForEmail(void); void regTestCheckIPIncrement(void); #endif #endif snort-2.9.15.1/src/reg_test.c0000644000175200017520000000366713571422607012633 00000000000000/* ** ** reg_test.c ** ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "reg_test.h" #include "sf_types.h" #ifdef REG_TEST uint32_t rt_ip_increment = 0; uint64_t getRegTestFlags(void) { static uint64_t regTestFlags = 0; static bool retTestInitialized = false; if (!retTestInitialized) { const char* key = getenv(REG_TEST_VARIABLE); if (key) regTestFlags = strtoul(key, NULL, 0); retTestInitialized = true; } return regTestFlags; } uint64_t getRegTestFlagsForEmail(void) { static uint64_t regTestFlags = 0; static bool retTestInitialized = false; if (!retTestInitialized) { const char* key = getenv(REG_TEST_EMAIL_VARIABLE); if (key) regTestFlags = strtoul(key, NULL, 0); retTestInitialized = true; } return regTestFlags; } void regTestCheckIPIncrement(void) { if (REG_TEST_FLAG_INCREMENT_IP_ADDRESS & getRegTestFlags()) rt_ip_increment++; } #endif snort-2.9.15.1/src/memory_stats.h0000644000175200017520000000402113571422607013533 00000000000000/* ** ** memory_stats.h ** ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Author(s): Puneeth Kumar C V ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** */ #ifndef __MEMORY_STATS_H__ #define __MEMORY_STATS_H__ #include "sf_types.h" #include "control/sfcontrol.h" typedef struct _PreprocMemNumAlloc { uint32_t num_of_alloc; uint32_t num_of_free; size_t used_memory; } PreprocMemNumAlloc; typedef struct _PreprocMemInfo { PreprocMemNumAlloc session_memory; PreprocMemNumAlloc cfg_memory; char *preproc_name; } PreprocMemInfo; typedef int (*MemoryStatsDisplayFunc)(char *buffer); void MemoryPostFunction(uint16_t type, void *old_context, struct _THREAD_ELEMENT *te, ControlDataSendFunc f); int MemoryControlFunction(uint16_t type, void *new_context, void **old_context); int MemoryPreFunction(uint16_t type, const uint8_t *data, uint32_t length, void **new_context, char *statusBuf, int statusBuf_len); int RegisterMemoryStatsFunction(uint preproc, char *preproc_name, MemoryStatsDisplayFunc cb); void* SnortPreprocAlloc (int num, unsigned long size, uint32_t preproc, bool data); void SnortPreprocFree (void *ptr, uint32_t size, uint32_t preproc, bool data); void MemoryStatsFree(); #endif snort-2.9.15.1/src/memory_stats.c0000644000175200017520000001447213571422607013541 00000000000000/* ** ** memory_stats.c ** ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Author(s): Puneeth Kumar C V ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "snort.h" #include "preprocids.h" #include "memory_stats.h" static MemoryStatsDisplayFunc MemStatsDisplayCallback[PP_MAX] = {0}; static PreprocMemInfo *preproc_mem_info[PP_MAX] = {0}; static int PopulateMemStatsBuff(char *buffer, uint32_t preproc_id) { return snprintf(buffer, CS_STATS_BUF_SIZE, "\n Heap Memory:\n" " Session: %14zu bytes\n" " Configuration: %14zu bytes\n" " -------------- ------------\n" " Total Memory: %14zu bytes\n" " No of allocs: %14d times\n" " IP sessions: %14d times\n" "----------------------------------------------------\n" , preproc_mem_info[preproc_id]->session_memory.used_memory , preproc_mem_info[preproc_id]->cfg_memory.used_memory , preproc_mem_info[preproc_id]->session_memory.used_memory + preproc_mem_info[preproc_id]->cfg_memory.used_memory , preproc_mem_info[preproc_id]->session_memory.num_of_alloc + preproc_mem_info[preproc_id]->cfg_memory.num_of_alloc , preproc_mem_info[preproc_id]->session_memory.num_of_free + preproc_mem_info[preproc_id]->cfg_memory.num_of_free); } static inline void PreprocDisplaystats(char *buffer, uint32_t preproc_id) { int len = 0; if (!(preproc_id != PP_ALL && preproc_id >= PP_MAX)) { if ( (preproc_id != PP_ALL) && (MemStatsDisplayCallback[preproc_id] != 0 && preproc_mem_info[preproc_id] != NULL) ) { len += MemStatsDisplayCallback[preproc_id](buffer); len += PopulateMemStatsBuff(buffer + len, preproc_id); } else for (preproc_id = PP_BO; preproc_id < PP_MAX; preproc_id++) if(MemStatsDisplayCallback[preproc_id] != 0 && preproc_mem_info[preproc_id] != NULL) { len += MemStatsDisplayCallback[preproc_id](buffer + len); len += PopulateMemStatsBuff(buffer + len, preproc_id); } } else { snprintf(buffer, CS_STATS_BUF_SIZE, "\nInvalid preprocessor.\n"); } } void MemoryPostFunction(uint16_t type, void *old_context, struct _THREAD_ELEMENT *te, ControlDataSendFunc f) { char *buffer = (char*) calloc(MEM_STATS_BUF_SIZE + 1, 1); uint32_t preproc_id; if(old_context) { preproc_id = *((uint32_t *) old_context); PreprocDisplaystats(buffer, preproc_id); if(-1 == f(te, (const uint8_t *)buffer, strlen(buffer))) LogMessage("Unable to send data to the frontend\n"); } } int MemoryControlFunction(uint16_t type, void *new_context, void **old_context) { if(new_context) *old_context = new_context; else LogMessage("\nnew_context is NULL\n"); return 0; } int MemoryPreFunction(uint16_t type, const uint8_t *data, uint32_t length, void **new_context, char *statusBuf, int statusBuf_len) { if(data) *new_context = (void*) data; else LogMessage("\ndata is NULL\n"); return 0; } int RegisterMemoryStatsFunction(uint preproc, char* preproc_name, MemoryStatsDisplayFunc cb) { if (preproc >= PP_MAX) { return -1; } MemStatsDisplayCallback[preproc] = cb; if (preproc_mem_info[preproc] == NULL) { preproc_mem_info[preproc] = (PreprocMemInfo *)SnortAlloc(sizeof(PreprocMemInfo)); preproc_mem_info[preproc]->preproc_name = preproc_name; } return 0; } void* SnortPreprocAlloc (int num, unsigned long size, uint32_t preproc, bool cfg) { void *pv = calloc(num, size); if ( pv ) { if (preproc_mem_info[preproc] == 0) { LogMessage("Memory stats information for preprocessor is NULL"); return pv; } if (cfg) { preproc_mem_info[preproc]->cfg_memory.used_memory += size; preproc_mem_info[preproc]->cfg_memory.num_of_alloc++; } else { preproc_mem_info[preproc]->session_memory.used_memory += size; preproc_mem_info[preproc]->session_memory.num_of_alloc++; } } else { FatalError("Unable to allocate memory! (%lu requested)\n", size); } return pv; } void SnortPreprocFree (void *ptr, uint32_t size, uint32_t preproc, bool cfg) { if( ptr ) { free(ptr); ptr = NULL; } if (preproc_mem_info[preproc] == NULL) { LogMessage("Memory stats information for preprocessor is NULL"); return; } if (cfg) { preproc_mem_info[preproc]->cfg_memory.used_memory -= size; preproc_mem_info[preproc]->cfg_memory.num_of_free++; } else { preproc_mem_info[preproc]->session_memory.used_memory -= size; preproc_mem_info[preproc]->session_memory.num_of_free++; } } void MemoryStatsFree () { int i; for (i = 0;i < PP_MAX;i++) { if (preproc_mem_info[i]) { free( preproc_mem_info[i]); preproc_mem_info[i] = NULL; } } } snort-2.9.15.1/src/dump.c0000644000175200017520000001125013571422607011747 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Author(s): Ron Dempster ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #include #include #include "snort.h" #include "dump.h" #include "util.h" uint16_t packet_dump_address_space_id; volatile pcap_dumper_t* packet_dump_file = NULL; pcap_t* packet_dump_pcap = NULL; volatile int packet_dump_stop; struct sfbpf_program packet_dump_fcode; void PacketDumpClose(void) { if (packet_dump_file) { pcap_dump_close((pcap_dumper_t*)packet_dump_file); packet_dump_file = NULL; pcap_close(packet_dump_pcap); packet_dump_pcap = NULL; sfbpf_freecode(&packet_dump_fcode); LogMessage("Stopped packet dump\n"); } packet_dump_stop = 0; } static int PacketDumpStop(void) { if (packet_dump_file) { int i; packet_dump_stop = 1; for (i = 5; 0 < i; i--) { if (!packet_dump_stop) break; sleep(1); } return packet_dump_stop; } return 0; } int PacketDumpCommand(uint16_t type, const uint8_t *data, uint32_t length, void **new_config, char *statusBuf, int statusBuf_len) { if (!length) PacketDumpStop(); else { const char* p; const char* end; const char* fname; char fileName[PATH_MAX]; char *filter; if (PacketDumpStop()) { WarningMessage("Failed to stop the previous packet dump\n"); return 1; } if (sizeof(packet_dump_address_space_id) > length) { WarningMessage("Invalid packet dump message length\n"); return 1; } packet_dump_address_space_id = *(const uint16_t*)data; data += sizeof(packet_dump_address_space_id); length -= sizeof(packet_dump_address_space_id); fname = (const char*)data; end = fname + length; for (p = fname; p < end && *p && (isalnum(*p) || *p == '/' || *p == '.' || *p == '-' || *p == '_'); p++); if (p >= end || *p) { WarningMessage("Invalid packet dump file name\n"); return 1; } p++; if (p >= end || *(end - 1)) { WarningMessage("Invalid packet dump BPF\n"); return 1; } filter = strdup(p); if (!filter) { WarningMessage("Couldn't allocate memory for the packet dump filter string\n"); return 1; } memset(&packet_dump_fcode, 0, sizeof(packet_dump_fcode)); if (sfbpf_compile(65535, DLT_EN10MB, &packet_dump_fcode, filter, 1, 0) < 0) { free(filter); WarningMessage("Packet dump BPF state machine compilation failed\n"); return 1; } free(filter); if (!sfbpf_validate(packet_dump_fcode.bf_insns, packet_dump_fcode.bf_len)) { WarningMessage("Packet dump BPF state machine validation failed\n"); return 1; } if (!(packet_dump_pcap = pcap_open_dead(DLT_EN10MB, 65535))) { WarningMessage("Packet dump failed to open a pcap instance\n"); return 1; } snprintf(fileName, sizeof(fileName), "%s.%u", fname, (unsigned)(snort_conf->event_log_id >> 16)); if (!(packet_dump_file = pcap_dump_open(packet_dump_pcap, fileName))) { pcap_close(packet_dump_pcap); packet_dump_pcap = NULL; WarningMessage("Packet dump failed to open the pcap file\n"); return 1; } LogMessage("Opened %s for packet dump of address space ID %u with filter (%s)\n", fileName, (unsigned)packet_dump_address_space_id, p); } return 0; } snort-2.9.15.1/src/dump.h0000644000175200017520000000270713571422607011763 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Author(s): Ron Dempster ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __DUMP_H__ #define __DUMP_H__ #include #include #include extern uint16_t packet_dump_address_space_id; extern volatile pcap_dumper_t* packet_dump_file; extern pcap_t* packet_dump_pcap; extern volatile int packet_dump_stop; extern struct sfbpf_program packet_dump_fcode; void PacketDumpClose(void); int PacketDumpCommand(uint16_t type, const uint8_t *data, uint32_t length, void **new_config, char *statusBuf, int statusBuf_len); #endif /* __DUMP_H__ */ snort-2.9.15.1/src/sfutil/0000755000000000000000000000000013571426517012173 500000000000000snort-2.9.15.1/src/sfutil/Makefile.in0000644000000000000000000004764313571425506014173 00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 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@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd 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/sfutil DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LIBRARIES = $(noinst_LIBRARIES) ARFLAGS = cru AM_V_AR = $(am__v_AR_@AM_V@) am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) am__v_AR_0 = @echo " AR " $@; am__v_AR_1 = libsfutil_a_AR = $(AR) $(ARFLAGS) libsfutil_a_LIBADD = am__libsfutil_a_SOURCES_DIST = sfghash.c sfghash.h sfhashfcn.c \ sfhashfcn.h sflsq.c sflsq.h sfmemcap.c sfmemcap.h sfthd.c \ sfthd.h sfxhash.c sfxhash.h ipobj.c ipobj.h getopt_long.c \ getopt.h getopt1.h acsmx.c acsmx.h acsmx2.c acsmx2.h \ sfksearch.c sfksearch.h bnfa_search.c bnfa_search.h mpse.c \ mpse.h bitop.h bitop_funcs.h util_math.c util_math.h \ util_net.c util_net.h util_str.c util_str.h util_utf.c \ util_utf.h util_jsnorm.c util_jsnorm.h util_unfold.c \ util_unfold.h asn1.c asn1.h sfeventq.c sfeventq.h \ sfsnprintfappend.c sfsnprintfappend.h sfrt.c sfrt.h \ sfrt_trie.h sfrt_dir.c sfrt_dir.h sfrt_flat.c sfrt_flat.h \ sfrt_flat_dir.c sfrt_flat_dir.h segment_mem.c segment_mem.h \ sfportobject.c sfportobject.h sfrim.c sfrim.h sfprimetable.c \ sfprimetable.h sf_ip.c sf_ip.h sf_ipvar.c sf_ipvar.h \ sf_vartable.c sf_vartable.h sf_iph.c sf_iph.h sf_textlog.c \ sf_textlog.h sf_sechash.c sf_sechash.h sfPolicy.c sfPolicy.h \ sfPolicyUserData.c sfPolicyUserData.h sfPolicyData.h \ sfActionQueue.c sfActionQueue.h sfrf.c sfrf.h strvec.c \ strvec.h sf_email_attach_decode.c sf_email_attach_decode.h \ sf_base64decode.c sf_base64decode.h Unified2_common.h \ sf_seqnums.h mpse_methods.h sfdebug.h intel-soft-cpm.c \ intel-soft-cpm.h md5.c md5.h sha2.c sha2.h @HAVE_INTEL_SOFT_CPM_TRUE@am__objects_1 = intel-soft-cpm.$(OBJEXT) @BUILD_OPENSSL_MD5_TRUE@am__objects_2 = md5.$(OBJEXT) @BUILD_OPENSSL_SHA_TRUE@am__objects_3 = sha2.$(OBJEXT) am_libsfutil_a_OBJECTS = sfghash.$(OBJEXT) sfhashfcn.$(OBJEXT) \ sflsq.$(OBJEXT) sfmemcap.$(OBJEXT) sfthd.$(OBJEXT) \ sfxhash.$(OBJEXT) ipobj.$(OBJEXT) getopt_long.$(OBJEXT) \ acsmx.$(OBJEXT) acsmx2.$(OBJEXT) sfksearch.$(OBJEXT) \ bnfa_search.$(OBJEXT) mpse.$(OBJEXT) util_math.$(OBJEXT) \ util_net.$(OBJEXT) util_str.$(OBJEXT) util_utf.$(OBJEXT) \ util_jsnorm.$(OBJEXT) util_unfold.$(OBJEXT) asn1.$(OBJEXT) \ sfeventq.$(OBJEXT) sfsnprintfappend.$(OBJEXT) sfrt.$(OBJEXT) \ sfrt_dir.$(OBJEXT) sfrt_flat.$(OBJEXT) sfrt_flat_dir.$(OBJEXT) \ segment_mem.$(OBJEXT) sfportobject.$(OBJEXT) sfrim.$(OBJEXT) \ sfprimetable.$(OBJEXT) sf_ip.$(OBJEXT) sf_ipvar.$(OBJEXT) \ sf_vartable.$(OBJEXT) sf_iph.$(OBJEXT) sf_textlog.$(OBJEXT) \ sf_sechash.$(OBJEXT) sfPolicy.$(OBJEXT) \ sfPolicyUserData.$(OBJEXT) sfActionQueue.$(OBJEXT) \ sfrf.$(OBJEXT) strvec.$(OBJEXT) \ sf_email_attach_decode.$(OBJEXT) sf_base64decode.$(OBJEXT) \ $(am__objects_1) $(am__objects_2) $(am__objects_3) libsfutil_a_OBJECTS = $(am_libsfutil_a_OBJECTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = am__depfiles_maybe = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libsfutil_a_SOURCES) DIST_SOURCES = $(am__libsfutil_a_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CCONFIGFLAGS = @CCONFIGFLAGS@ CFLAGS = @CFLAGS@ CONFIGFLAGS = @CONFIGFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ ICONFIGFLAGS = @ICONFIGFLAGS@ INCLUDES = @INCLUDES@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LUA_CFLAGS = @LUA_CFLAGS@ LUA_LIBS = @LUA_LIBS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIGNAL_SNORT_DUMP_STATS = @SIGNAL_SNORT_DUMP_STATS@ SIGNAL_SNORT_READ_ATTR_TBL = @SIGNAL_SNORT_READ_ATTR_TBL@ SIGNAL_SNORT_RELOAD = @SIGNAL_SNORT_RELOAD@ SIGNAL_SNORT_ROTATE_STATS = @SIGNAL_SNORT_ROTATE_STATS@ STRIP = @STRIP@ VERSION = @VERSION@ XCCFLAGS = @XCCFLAGS@ YACC = @YACC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ 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@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luajit_CFLAGS = @luajit_CFLAGS@ luajit_LIBS = @luajit_LIBS@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign no-dependencies noinst_LIBRARIES = libsfutil.a @HAVE_INTEL_SOFT_CPM_TRUE@INTEL_SOFT_CPM_SOURCES = intel-soft-cpm.c intel-soft-cpm.h @BUILD_OPENSSL_MD5_TRUE@OPENSSL_MD5 = \ @BUILD_OPENSSL_MD5_TRUE@ md5.c md5.h @BUILD_OPENSSL_SHA_TRUE@OPENSSL_SHA = \ @BUILD_OPENSSL_SHA_TRUE@ sha2.c sha2.h libsfutil_a_SOURCES = \ sfghash.c sfghash.h \ sfhashfcn.c sfhashfcn.h \ sflsq.c sflsq.h \ sfmemcap.c sfmemcap.h \ sfthd.c sfthd.h \ sfxhash.c sfxhash.h \ ipobj.c ipobj.h \ getopt_long.c getopt.h getopt1.h \ acsmx.c acsmx.h \ acsmx2.c acsmx2.h \ sfksearch.c sfksearch.h \ bnfa_search.c bnfa_search.h \ mpse.c mpse.h \ bitop.h bitop_funcs.h \ util_math.c util_math.h \ util_net.c util_net.h \ util_str.c util_str.h \ util_utf.c util_utf.h \ util_jsnorm.c util_jsnorm.h \ util_unfold.c util_unfold.h \ asn1.c asn1.h \ sfeventq.c sfeventq.h \ sfsnprintfappend.c sfsnprintfappend.h \ sfrt.c sfrt.h sfrt_trie.h sfrt_dir.c sfrt_dir.h \ sfrt_flat.c sfrt_flat.h sfrt_flat_dir.c sfrt_flat_dir.h \ segment_mem.c segment_mem.h \ sfportobject.c sfportobject.h \ sfrim.c sfrim.h \ sfprimetable.c sfprimetable.h \ sf_ip.c sf_ip.h \ sf_ipvar.c sf_ipvar.h \ sf_vartable.c sf_vartable.h \ sf_iph.c sf_iph.h \ sf_textlog.c sf_textlog.h \ sf_sechash.c sf_sechash.h \ sfPolicy.c sfPolicy.h \ sfPolicyUserData.c sfPolicyUserData.h \ sfPolicyData.h \ sfActionQueue.c sfActionQueue.h \ sfrf.c sfrf.h \ strvec.c strvec.h \ sf_email_attach_decode.c sf_email_attach_decode.h \ sf_base64decode.c sf_base64decode.h \ Unified2_common.h \ sf_seqnums.h \ mpse_methods.h \ sfdebug.h \ $(INTEL_SOFT_CPM_SOURCES) \ $(OPENSSL_MD5) \ $(OPENSSL_SHA) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/sfutil/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/sfutil/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: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libsfutil.a: $(libsfutil_a_OBJECTS) $(libsfutil_a_DEPENDENCIES) $(EXTRA_libsfutil_a_DEPENDENCIES) $(AM_V_at)-rm -f libsfutil.a $(AM_V_AR)$(libsfutil_a_AR) libsfutil.a $(libsfutil_a_OBJECTS) $(libsfutil_a_LIBADD) $(AM_V_at)$(RANLIB) libsfutil.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c .c.o: $(AM_V_CC)$(COMPILE) -c $< .c.obj: $(AM_V_CC)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: $(AM_V_CC)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files 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)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$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: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_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-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: 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: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLIBRARIES cscopelist-am ctags \ ctags-am 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-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am 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 tags-am uninstall uninstall-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: snort-2.9.15.1/src/sfutil/Makefile.am0000444000175200017520000000343113571422607014200 00000000000000AUTOMAKE_OPTIONS=foreign no-dependencies noinst_LIBRARIES = libsfutil.a if HAVE_INTEL_SOFT_CPM INTEL_SOFT_CPM_SOURCES = intel-soft-cpm.c intel-soft-cpm.h endif if BUILD_OPENSSL_MD5 OPENSSL_MD5 = \ md5.c md5.h endif if BUILD_OPENSSL_SHA OPENSSL_SHA = \ sha2.c sha2.h endif libsfutil_a_SOURCES = \ sfghash.c sfghash.h \ sfhashfcn.c sfhashfcn.h \ sflsq.c sflsq.h \ sfmemcap.c sfmemcap.h \ sfthd.c sfthd.h \ sfxhash.c sfxhash.h \ ipobj.c ipobj.h \ getopt_long.c getopt.h getopt1.h \ acsmx.c acsmx.h \ acsmx2.c acsmx2.h \ sfksearch.c sfksearch.h \ bnfa_search.c bnfa_search.h \ mpse.c mpse.h \ bitop.h bitop_funcs.h \ util_math.c util_math.h \ util_net.c util_net.h \ util_str.c util_str.h \ util_utf.c util_utf.h \ util_jsnorm.c util_jsnorm.h \ util_unfold.c util_unfold.h \ asn1.c asn1.h \ sfeventq.c sfeventq.h \ sfsnprintfappend.c sfsnprintfappend.h \ sfrt.c sfrt.h sfrt_trie.h sfrt_dir.c sfrt_dir.h \ sfrt_flat.c sfrt_flat.h sfrt_flat_dir.c sfrt_flat_dir.h \ segment_mem.c segment_mem.h \ sfportobject.c sfportobject.h \ sfrim.c sfrim.h \ sfprimetable.c sfprimetable.h \ sf_ip.c sf_ip.h \ sf_ipvar.c sf_ipvar.h \ sf_vartable.c sf_vartable.h \ sf_iph.c sf_iph.h \ sf_textlog.c sf_textlog.h \ sf_sechash.c sf_sechash.h \ sfPolicy.c sfPolicy.h \ sfPolicyUserData.c sfPolicyUserData.h \ sfPolicyData.h \ sfActionQueue.c sfActionQueue.h \ sfrf.c sfrf.h \ strvec.c strvec.h \ sf_email_attach_decode.c sf_email_attach_decode.h \ sf_base64decode.c sf_base64decode.h \ Unified2_common.h \ sf_seqnums.h \ mpse_methods.h \ sfdebug.h \ $(INTEL_SOFT_CPM_SOURCES) \ $(OPENSSL_MD5) \ $(OPENSSL_SHA) INCLUDES = @INCLUDES@ snort-2.9.15.1/src/sfutil/sfghash.c0000644000175200017520000004233013571422607013736 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2003-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* * * sfghash.c * * Generic hash table library. * * This hash table maps unique keys to void data pointers. * * Features: * 1) Keys may be ascii strings of variable size, or * fixed length (per table) binary byte sequences. This * allows use as a Mapping for String+Data pairs, or a * generic hashing. * 2) User can allocate keys, or pass copies and we can * allocate space and save keys. * 3) User can pass a free function to free up user data * when the table is deleted. * 4) Table rows sizes can be automatically adjusted to * the nearest prime number size. * * 6/10/03 - man - Upgraded the hash function to a Hardened hash function, * it has no predictable cycles, and each hash table gets a different * randomized hashing function. So even with the source code, you cannot predict * anything with this function. If an attacker can setup a feedback * loop he might gain some knowledge of how to muck with us, but even in that case * his odds are astronomically skinny. This is actually the same problem as solved * early on with hashing functions where degenerate data with close keys could * produce very long bucket chains. * * 8/31/06 - man - Added prime tables to speed up prime number lookup. * * Author: Marc Norton * */ #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sfghash.h" #include "sfprimetable.h" /* * Private Malloc */ static void * s_alloc( int n ) { return calloc( 1,n ); } /* * Private Free */ static void s_free( void * p ) { if( p )free( p ); } /* * * Create a new hash table * * nrows : number of rows in hash table, primes are best. * > 0 => we use the nearest prime internally * < 0 => we use the magnitude as nrows. * keysize : > 0 => bytes in each key, keys are binary bytes, * all keys are the same size. * ==0 => keys are strings and are null terminated, * allowing random key lengths. * userkeys : > 0 => indicates user owns the key data * and we should not allocate or free space for it, * nor should we attempt to free the user key. We just * save the pointer to the key. * ==0 => we should copy the keys and manage them internally * userfree : routine to free users data, null if we should not * free user data in sfghash_delete(). The routine * should be of the form 'void userfree(void * userdata)', * 'free' works for simple allocations. */ SFGHASH * sfghash_new( int nrows, int keysize, int userkeys, void (*userfree)(void*p) ) { int i; SFGHASH * h; if( nrows > 0 ) /* make sure we have a prime number */ { nrows = sf_nearest_prime( nrows ); } else /* use the magnitude or nrows as is */ { nrows = -nrows; } h = (SFGHASH*)s_alloc( sizeof(SFGHASH) ); if( !h ) return 0; memset( h, 0, sizeof(SFGHASH) ); h->sfhashfcn = sfhashfcn_new( nrows ); if( !h->sfhashfcn ) { free(h); return 0; } h->table = (SFGHASH_NODE**) s_alloc( sizeof(SFGHASH_NODE*) * nrows ); if( !h->table ) { free(h->sfhashfcn); free(h); return 0; } for( i=0; itable[i] = 0; } h->userkey = userkeys; h->keysize = keysize; h->nrows = nrows; h->count = 0; h->userfree = userfree; h->crow = 0; // findfirst/next current row h->cnode = 0; // findfirst/next current node ptr return h; } /* * Set Splay mode : Splays nodes to front of list on each access */ void sfghash_splaymode( SFGHASH * t, int n ) { if ( t ) t->splay = n; } /* * Delete the hash Table * * free key's, free node's, and free the users data, if they * supply a free function */ void sfghash_delete( SFGHASH * h ) { int i; SFGHASH_NODE * node, * onode; if( !h ) return; sfhashfcn_free( h->sfhashfcn ); if( h->table ) { for(i=0;inrows;i++) { for( node=h->table[i]; node; ) { onode = node; node = node->next; if( !h->userkey && onode->key ) s_free( (void *)onode->key ); if( h->userfree && onode->data ) h->userfree( onode->data ); /* free users data, with users function */ s_free( onode ); } } s_free( h->table ); h->table = 0; } s_free( h ); } /* * Get the # of Nodes in HASH the table */ int sfghash_count( SFGHASH * t ) { if( !t ) return 0; return t->count; } /* * Add a key + data pair * --------------------- * * key + data should both be non-zero, although data can be zero * * t - hash table * key - users key data (should be unique in this table) * may be ascii strings or fixed size binary keys * data - users data pointer * * returns SF_HASH_NOMEM: alloc error * SF_HASH_INTABLE : key already in table (t->cnode points to the node) * SF_OK: added a node for this key + data pair * * Notes: * If the key node already exists, then t->cnode points to it on return, * this allows you to do something with the node - like add the data to a * linked list of data items held by the node, or track a counter, or whatever. * */ int sfghash_add( SFGHASH * t, const void * const key, void * const data ) { unsigned hashkey; int klen; int index; SFGHASH_NODE *hnode; if (t == NULL) return SFGHASH_ERR; /* * Get proper Key Size */ if( t->keysize > 0 ) { klen = t->keysize; } else { /* need the null byte for strcmp() in sfghash_find() */ klen = strlen( (char*)key ) + 1; } hashkey = t->sfhashfcn->hash_fcn( t->sfhashfcn, (unsigned char*) key, klen ); index = hashkey % t->nrows; /* * Uniqueness: * Check 1st to see if the key is already in the table * Just bail if it is. */ for( hnode=t->table[index]; hnode; hnode=hnode->next ) { if( t->keysize > 0 ) { if( !t->sfhashfcn->keycmp_fcn(hnode->key,key,klen) ) { t->cnode = hnode; /* save pointer to the node */ return SFGHASH_INTABLE; /* found it */ } } else { if( !strcmp((const char *)hnode->key,(const char*)key) ) { t->cnode = hnode; /* save pointer to the node */ return SFGHASH_INTABLE; /* found it */ } } } /* * Create new node */ hnode = (SFGHASH_NODE*)s_alloc(sizeof(SFGHASH_NODE)); if( !hnode ) return SFGHASH_NOMEM; /* Add the Key */ if( t->userkey ) { /* Use the Users key */ hnode->key = key; } else { /* Create new key */ hnode->key = s_alloc( klen ); if( !hnode->key ) { free(hnode); return SFGHASH_NOMEM; } /* Copy key */ memcpy((void*)hnode->key,key,klen); } /* Add The Node */ if( t->table[index] ) /* add the node to the existing list */ { hnode->prev = 0; // insert node as head node hnode->next=t->table[index]; hnode->data=data; t->table[index]->prev = hnode; t->table[index] = hnode; } else /* 1st node in this list */ { hnode->prev=0; hnode->next=0; hnode->data=data; t->table[index] = hnode; } t->count++; return SFGHASH_OK; } /* * move a node to the front of the list */ static void movetofront( SFGHASH *t , int index, SFGHASH_NODE * n ) { if( t->table[index] != n ) // if not at front of list already... { /* Unlink the node */ if( n->prev ) n->prev->next = n->next; if( n->next ) n->next->prev = n->prev; /* Link at front of list */ n->prev=0; n->next=t->table[index]; t->table[index]->prev=n; } } /* * Find a Node based on the key, return users data. */ SFGHASH_NODE * sfghash_find_node( SFGHASH * t, const void * const key) { unsigned hashkey; int index, klen; SFGHASH_NODE *hnode; if ( !t ) return NULL; if( t->keysize ) { klen = t->keysize; } else { klen = strlen( (char*) key ) + 1; } hashkey = t->sfhashfcn->hash_fcn( t->sfhashfcn, (unsigned char*) key, klen ); index = hashkey % t->nrows; for( hnode=t->table[index]; hnode; hnode=hnode->next ) { if( t->keysize == 0 ) { if( !strcmp((char*)hnode->key,(char*)key) ) { if( t->splay > 0 ) movetofront(t,index,hnode); return hnode; } } else { if( !t->sfhashfcn->keycmp_fcn(hnode->key,key,t->keysize) ) { if( t->splay > 0 ) movetofront(t,index,hnode); return hnode; } } } return NULL; } /* * Find a Node based on the key, return users data. */ void * sfghash_find( SFGHASH * t, const void * const key) { SFGHASH_NODE * hnode; if ( !t ) return NULL; hnode = sfghash_find_node( t, key ); if( hnode ) return hnode->data; return NULL; } /* Returns whether or not the there is an entry in the table with key * Sets argument data to data in hash node which could be NULL. * This function is used to both make sure there is an entry in the * table and get potential data associated with entry */ int sfghash_find2(SFGHASH *t, void *key, void **data) { SFGHASH_NODE * hnode; if (t == NULL) return 0; hnode = sfghash_find_node(t, key); if (hnode != NULL) { *data = hnode->data; return 1; } return 0; } /* * Unlink and free the node */ static int sfghash_free_node( SFGHASH * t, unsigned index, SFGHASH_NODE * hnode ) { if( !t->userkey && hnode->key ) s_free( (void *)hnode->key ); hnode->key = 0; if( t->userfree) t->userfree( hnode->data); /* free users data, with users function */ if( hnode->prev ) // not the 1st node { hnode->prev->next = hnode->next; if( hnode->next ) hnode->next->prev = hnode->prev; } else if( t->table[index] ) // 1st node { t->table[index] = t->table[index]->next; if( t->table[index] )t->table[index]->prev = 0; } s_free( hnode ); t->count--; return SFGHASH_OK; } /* * Remove a Key/Data Pair from the table - find it, unlink it, and free the memory for it. * * returns : 0 - OK * -1 - node not found */ int sfghash_remove( SFGHASH * t, const void * const key) { SFGHASH_NODE * hnode; int klen; unsigned hashkey, index; if ( !t ) return 0; if( t->keysize > 0 ) { klen = t->keysize; } else { klen = strlen((char*)key) + 1; } hashkey = t->sfhashfcn->hash_fcn( t->sfhashfcn, (unsigned char*) key, klen ); index = hashkey % t->nrows; for( hnode=t->table[index]; hnode; hnode=hnode->next ) { if( t->keysize > 0 ) { if( !t->sfhashfcn->keycmp_fcn(hnode->key,key,klen) ) { return sfghash_free_node( t, index, hnode ); } } else { if( !strcmp((const char *)hnode->key,(const char*)key) ) { return sfghash_free_node( t, index, hnode ); } } } return SFGHASH_ERR; } /* * Get First Hash Table Node */ SFGHASH_NODE * sfghash_findfirst1( SFGHASH * t ) { if ( !t ) return NULL; /* Start with 1st row */ for( t->crow=0; t->crow < t->nrows; t->crow++ ) { /* Get 1st Non-Null node in row list */ t->cnode = t->table[t->crow]; if( t->cnode ) return t->cnode; } return NULL; } /* * Get Next Hash Table Node */ SFGHASH_NODE * sfghash_findnext1( SFGHASH * t ) { if ( !t ) return NULL; if( t->cnode ) /* get next in this list */ { /* Next node in current node list */ t->cnode = t->cnode->next; if( t->cnode ) { return t->cnode; } } /* Get 1st node in next non-empty row/node list */ for( t->crow++; t->crow < t->nrows; t->crow++ ) { t->cnode = t->table[ t->crow ]; if( t->cnode ) { return t->cnode; } } return NULL; } /* Internal use only */ static void sfghash_next( SFGHASH * t ) { if ( !t ) return; if( !t->cnode ) return ; /* Next node in current node list */ t->cnode = t->cnode->next; if( t->cnode ) { return; } /* Next row */ /* Get 1st node in next non-emtoy row/node list */ for( t->crow++; t->crow < t->nrows; t->crow++ ) { t->cnode = t->table[ t->crow ]; if( t->cnode ) { return; } } } /* * Get First Hash Table Node */ SFGHASH_NODE * sfghash_findfirst( SFGHASH * t ) { SFGHASH_NODE * n; if ( !t ) return NULL; /* Start with 1st row */ for( t->crow=0; t->crow < t->nrows; t->crow++ ) { /* Get 1st Non-Null node in row list */ t->cnode = t->table[ t->crow ]; if( t->cnode ) { n = t->cnode; sfghash_next( t ); // load t->cnode with the next entry return n; } } return NULL; } /* * Get Next Hash Table Node */ SFGHASH_NODE * sfghash_findnext( SFGHASH * t ) { SFGHASH_NODE * n; if ( !t ) return NULL; n = t->cnode; if( !n ) /* Done, no more entries */ { return NULL; } /* Preload next node into current node */ sfghash_next( t ); return n; } /** * Make sfhashfcn use a separate set of operators for the backend. * * @param h sfhashfcn ptr * @param hash_fcn user specified hash function * @param keycmp_fcn user specified key comparisoin function */ int sfghash_set_keyops( SFGHASH *h , unsigned (*hash_fcn)( SFHASHFCN * p, unsigned char *d, int n), int (*keycmp_fcn)( const void *s1, const void *s2, size_t n)) { if(h && hash_fcn && keycmp_fcn) { return sfhashfcn_set_keyops(h->sfhashfcn, hash_fcn, keycmp_fcn); } return -1; } /* * * Test Driver for Hashing * */ #ifdef SFGHASH_MAIN void myfree ( void * p ) { printf("freeing '%s'\n",p); free(p); } /* * Hash test program */ int main ( int argc, char ** argv ) { int i; SFGHASH * t; SFGHASH_NODE * n, *m; char str[256],*p; int num=100; if( argc > 1 ) num = atoi(argv[1]); sfatom_init(); /* Create a Hash Table */ t = sfghash_new( 1000, 0 , GH_COPYKEYS , myfree ); /* Add Nodes to the Hash Table */ for(i=0;ikey, n->data ); // hashing code frees user data using 'myfree' above .... if( sfghash_remove(t,n->key) ) printf("Could not remove the key node\n"); else printf("key node removed\n"); } for( n = sfatom_findfirst(); n; n = sfatom_findnext() ) { printf("atom-findfirst/next: key=%s, data=%s\n", n->key, n->data ); free( n->data ); //since atom data is not freed automatically } /* Free the table and it's user data */ printf("****sfghash_delete\n"); sfghash_delete( t ); printf("****sfatom_reset\n"); sfatom_reset(); printf("\nnormal pgm finish\n\n"); return 0; } #endif snort-2.9.15.1/src/sfutil/sfghash.h0000644000175200017520000000645113571422607013747 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2003-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* * * sfghash.h * * generic hash table - stores and maps key + data pairs * * Author: Marc Norton * */ #ifndef _SFGHASH_ #define _SFGHASH_ #include #include #include #include "sfhashfcn.h" /* * ERROR DEFINES */ #define SFGHASH_NOMEM -2 #define SFGHASH_ERR -1 #define SFGHASH_OK 0 #define SFGHASH_INTABLE 1 /* * Flags for ghash_new: userkeys */ #define GH_COPYKEYS 0 #define GH_USERKEYS 1 /* * Generic HASH NODE */ typedef struct _sfghash_node { struct _sfghash_node * next, * prev; const void * key; /* Copy of, or Pointer to, the Users key */ void *data; /* The users data, this is never copied! */ } SFGHASH_NODE; /* * Generic HASH table */ typedef struct _sfghash { SFHASHFCN * sfhashfcn; int keysize; /* bytes in key, if < 0 -> keys are strings */ int userkey; /* user owns the key */ SFGHASH_NODE ** table; /* array of node ptr's */ int nrows; /* # rows int the hash table use a prime number 211, 9871 */ unsigned count; /* total # nodes in table */ void (*userfree)( void * ); int crow; /* findfirst/next row in table */ SFGHASH_NODE * cnode; /* findfirst/next node ptr */ int splay; } SFGHASH, SFDICT; /* * HASH PROTOTYPES */ SFGHASH * sfghash_new( int nrows, int keysize, int userkeys, void (*userfree)(void*p) ); void sfghash_delete( SFGHASH * h ); int sfghash_add( SFGHASH * t, const void * const key, void * const data ); int sfghash_remove( SFGHASH * h, const void * const key); int sfghash_count( SFGHASH * h); void * sfghash_find( SFGHASH * h, const void * const key ); SFGHASH_NODE * sfghash_find_node( SFGHASH * t, const void * const key); int sfghash_find2(SFGHASH *, void *, void **); SFGHASH_NODE * sfghash_findfirst( SFGHASH * h ); SFGHASH_NODE * sfghash_findnext ( SFGHASH * h ); int sfghash_set_keyops( SFGHASH *h , unsigned (*hash_fcn)( SFHASHFCN * p, unsigned char *d, int n), int (*keycmp_fcn)( const void *s1, const void *s2, size_t n)); #endif snort-2.9.15.1/src/sfutil/sfhashfcn.c0000644000175200017520000000656313571422607014266 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2003-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* sfhashfcn.c Each hash table must allocate it's own SFGHASH struct, this is because sfghash_new uses the number of rows in the hash table to modulo the random values. Updates: 8/31/2006 - man - changed to use sfprimetable.c */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sf_types.h" #ifndef MODULUS_HASH # include "snort.h" #endif #include "sfhashfcn.h" #include "sfprimetable.h" SFHASHFCN * sfhashfcn_new( int m ) { SFHASHFCN * p; static int one=1; if( one ) /* one time init */ { srand( (unsigned) time(0) ); one = 0; } // This can make all of the hashing static for testing. //#define rand() 0 p = (SFHASHFCN*) calloc( 1,sizeof(SFHASHFCN) ); if( !p ) return 0; #ifndef MODULUS_HASH #ifndef DYNAMIC_PREPROC_CONTEXT if (ScStaticHash()) { sfhashfcn_static(p); } else #endif #endif { p->seed = sf_nearest_prime( (rand()%m)+3191 ); p->scale = sf_nearest_prime( (rand()%m)+709 ); p->hardener = (rand()*rand()) + 133824503; } p->hash_fcn = &sfhashfcn_hash; p->keycmp_fcn = &memcmp; return p; } void sfhashfcn_free( SFHASHFCN * p ) { if( p ) { free( p); } } void sfhashfcn_static( SFHASHFCN * p ) { p->seed = 3193; p->scale = 719; p->hardener = 133824503; } unsigned sfhashfcn_hash( SFHASHFCN * p, unsigned char *d, int n ) { unsigned hash = p->seed; while( n ) { hash *= p->scale; hash += *d++; n--; } return hash ^ p->hardener; } /** * Make sfhashfcn use a separate set of operators for the backend. * * @param h sfhashfcn ptr * @param hash_fcn user specified hash function * @param keycmp_fcn user specified key comparisoin function */ int sfhashfcn_set_keyops( SFHASHFCN *h, unsigned (*hash_fcn)( SFHASHFCN * p, unsigned char *d, int n), int (*keycmp_fcn)( const void *s1, const void *s2, size_t n)) { if(h && hash_fcn && keycmp_fcn) { h->hash_fcn = hash_fcn; h->keycmp_fcn = keycmp_fcn; return 0; } return -1; } snort-2.9.15.1/src/sfutil/sfhashfcn.h0000644000175200017520000000516613571422607014271 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2003-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* sfhashfcn.h */ #ifndef SFHASHFCN_INCLUDE #define SFHASHFCN_INCLUDE #include #include #include #include #define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) #define mix(a,b,c) \ { \ a -= c; a ^= rot(c, 4); c += b; \ b -= a; b ^= rot(a, 6); a += c; \ c -= b; c ^= rot(b, 8); b += a; \ a -= c; a ^= rot(c,16); c += b; \ b -= a; b ^= rot(a,19); a += c; \ c -= b; c ^= rot(b, 4); b += a; \ } #define final(a,b,c) \ { \ c ^= b; c -= rot(b,14); \ a ^= c; a -= rot(c,11); \ b ^= a; b -= rot(a,25); \ c ^= b; c -= rot(b,16); \ a ^= c; a -= rot(c,4); \ b ^= a; b -= rot(a,14); \ c ^= b; c -= rot(b,24); \ } typedef struct _SFHASHFCN { unsigned seed; unsigned scale; unsigned hardener; unsigned (*hash_fcn)(struct _SFHASHFCN * p, unsigned char *d, int n ); int (*keycmp_fcn)( const void *s1, const void *s2, size_t n); } SFHASHFCN; SFHASHFCN * sfhashfcn_new( int nrows ); void sfhashfcn_free( SFHASHFCN * p ); void sfhashfcn_static( SFHASHFCN * p ); unsigned sfhashfcn_hash( SFHASHFCN * p, unsigned char *d, int n ); int sfhashfcn_set_keyops( SFHASHFCN * p, unsigned (*hash_fcn)( SFHASHFCN * p, unsigned char *d, int n), int (*keycmp_fcn)( const void *s1, const void *s2, size_t n)); #endif snort-2.9.15.1/src/sfutil/sflsq.c0000644000175200017520000002410113571422607013437 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2003-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* * sflsq.c * * Simple list, stack, 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 * multiple readers to traverse a list. The built in 'cur' field does not * wrok for multiple readers. * * */ #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sflsq.h" /* * private alloc */ static void * s_alloc (size_t n) { void *p = (void*) calloc( 1,n ); return p; } /* * private free */ static void s_free (void *p) { if( p ) free( p ); } /* * INIT - called by the NEW functions */ void sflist_init ( SF_LIST * s) { s->count=0; s->head = s->tail = s->cur = 0; } /* * NEW */ SF_LIST * sflist_new(void) { SF_LIST * s; s = (SF_LIST*)s_alloc( sizeof(SF_LIST) ); if( s )sflist_init( s ); return s; } SF_STACK * sfstack_new(void) { return (SF_STACK*)sflist_new(); } SF_QUEUE * sfqueue_new(void) { return (SF_QUEUE*)sflist_new(); } /* * Add-before Item */ int sflist_add_before ( SF_LIST* s, SF_LNODE * lnode, NODE_DATA ndata ) { SF_LNODE * q; if( !lnode ) return 0; /* Add to head of list */ if( s->head == lnode ) { return sflist_add_head ( s, ndata ); } else { q = (SF_LNODE *) s_alloc ( sizeof (SF_LNODE) ); if( !q ) { return -1; } q->ndata = (NODE_DATA)ndata; q->next = lnode; q->prev = lnode->prev; lnode->prev->next = q; lnode->prev = q; } s->count++; return 0; } /* * ADD to List/Stack/Queue/Dictionary */ /* * Add-Head Item */ int sflist_add_head ( SF_LIST* s, NODE_DATA ndata ) { SF_LNODE * q; if (!s->head) { q = s->tail = s->head = (SF_LNODE *) s_alloc (sizeof (SF_LNODE)); if(!q)return -1; q->ndata = (NODE_DATA)ndata; q->next = 0; q->prev = 0; } else { q = (SF_LNODE *) s_alloc (sizeof (SF_LNODE)); if(!q)return -1; q->ndata = ndata; q->next = s->head; q->prev = 0; s->head->prev = q; s->head = q; } s->count++; return 0; } /* * Add-Tail Item */ int sflist_add_tail ( SF_LIST* s, NODE_DATA ndata ) { SF_LNODE * q; if (!s->head) { q = s->tail = s->head = (SF_LNODE *) s_alloc (sizeof (SF_LNODE)); if(!q)return -1; q->ndata = (NODE_DATA)ndata; q->next = 0; q->prev = 0; } else { q = (SF_LNODE *) s_alloc (sizeof (SF_LNODE)); if(!q)return -1; q->ndata = ndata; q->next = 0; q->prev = s->tail; s->tail->next = q; s->tail = q; } s->count++; return 0; } int sfqueue_add(SF_QUEUE * s, NODE_DATA ndata ) { 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 */ NODE_DATA sflist_first( SF_LIST * s ) { if(!s) return 0; s->cur = s->head; if( s->cur ) return s->cur->ndata; return 0; } NODE_DATA sflist_next( SF_LIST * s ) { if(!s) return 0; if( s->cur ) { s->cur = s->cur->next; if( s->cur ) return s->cur->ndata; } return 0; } NODE_DATA sflist_firstpos( SF_LIST * s, SF_LNODE ** v ) { if(!s) return 0; *v = s->head; if( *v ) return (*v)->ndata; return 0; } NODE_DATA sflist_nextpos( SF_LIST * s, SF_LNODE ** v ) { if(!s) return 0; if(v) { if(*v) { *v = (*v)->next; if( *v ) return (*v)->ndata; } } return 0; } /* * List walk - First/Next - return the node data or NULL */ SF_LNODE * sflist_first_node( SF_LIST * s ) { if(!s) return 0; s->cur = s->head; return s->cur; } SF_LNODE * sflist_next_node( SF_LIST * s ) { if(!s) return 0; if( s->cur ) { s->cur = s->cur->next; if( s->cur ) return s->cur; } return 0; } /* * Remove Head Item from list */ NODE_DATA sflist_remove_head (SF_LIST * s) { NODE_DATA ndata = 0; SF_QNODE * q; if ( s && s->head ) { q = s->head; ndata = q->ndata; s->head = s->head->next; s->count--; if( !s->head ) { s->tail = 0; } else { s->head->prev = NULL; } s_free( q ); } return (NODE_DATA)ndata; } /* * Remove tail Item from list */ NODE_DATA sflist_remove_tail (SF_LIST * s) { NODE_DATA ndata = 0; SF_QNODE * q; if (s && s->tail) { q = s->tail; ndata = q->ndata; s->count--; s->tail = q->prev; if (!s->tail) { s->head = NULL; } else { s->tail->next = NULL; } s_free (q); } return (NODE_DATA)ndata; } void sflist_remove_node (SF_LIST * s, SF_LNODE * n) { // NODE_DATA ndata = 0; SF_LNODE * cur; if( n == s->head ) { s->head = s->head->next; s->count--; if (!s->head) { s->tail = 0; } else { s->head->prev = NULL; } s_free( n ); return ; } else if( n == s->tail ) { s->tail = s->tail->prev; s->count--; if (!s->tail ) { s->head = 0; } else { s->tail->next = NULL; } s_free( n ); return ; } for(cur = s->head; cur!= NULL; cur = cur->next ) { if( n == cur ) { /* unlink a middle node */ n->next->prev = n->prev; n->prev->next = n->next; s->count--; s_free(n); return ; } } } /* * Remove Head Item from queue */ NODE_DATA sfqueue_remove (SF_QUEUE * s) { 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 */ int sfqueue_count (SF_QUEUE * s) { if(!s)return 0; return s->count; } int sflist_count ( SF_LIST* s) { if(!s)return 0; 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' */ void sflist_free_all( SF_LIST * s, void (*nfree)(void*) ) { void * p; if(!s) return; while( s->count > 0 ) { p = sflist_remove_head (s); if( p && nfree ) nfree( p ); } s_free(s); } void sfqueue_free_all(SF_QUEUE * s,void (*nfree)(void*) ) { 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; if(!s) return; while( s->count > 0 ) { p = sflist_remove_head (s); if( p && nfree ) nfree( 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 * * This does not free a nodes data */ void sflist_free (SF_LIST * s) { while( sflist_count(s) ) { sflist_remove_head(s); } s_free(s); } void sfqueue_free (SF_QUEUE * s) { 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; } snort-2.9.15.1/src/sfutil/sflsq.h0000644000175200017520000001076013571422607013452 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2003-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* * sflsq.h * * Simple LIST, STACK, QUEUE DICTIONARY(LIST BASED)interface * * All of these functions are based on lists, which use * the standard malloc. * * Note that NODE_DATA can be redifined with the * define below. * * Author: Marc Norton */ #ifndef _SFLSQ_ #define _SFLSQ_ /* * */ typedef void * NODE_DATA; /* * Simple list,stack or queue NODE */ typedef struct sf_lnode { struct sf_lnode *next; struct sf_lnode *prev; NODE_DATA ndata; } SF_QNODE,SF_SNODE,SF_LNODE; #define SFLIST_NODE_TO_DATA(node) (node)->ndata /* * Integer Stack - uses an array from the subroutines stack */ typedef struct { unsigned *stack; unsigned nstack; unsigned n; } SF_ISTACK; /* * Pointer Stack - uses an array from the subroutines stack */ typedef struct { void **stack; unsigned nstack; unsigned n; } SF_PSTACK; /* * Simple Structure for Queue's, stacks, lists */ typedef struct sf_list { SF_LNODE *head, *tail; SF_LNODE *cur; /* used for First/Next walking */ unsigned count; } SF_QUEUE,SF_STACK,SF_LIST; /* * Linked List Interface */ SF_LIST * sflist_new ( void ); void sflist_init ( SF_LIST * s); int sflist_add_tail ( SF_LIST* s, NODE_DATA ndata ); int sflist_add_head ( SF_LIST* s, NODE_DATA ndata ); int sflist_add_before ( SF_LIST* s, SF_LNODE * lnode, NODE_DATA ndata ); int sflist_add_after ( SF_LIST* s, SF_LNODE * lnode, NODE_DATA ndata ); NODE_DATA sflist_remove_head ( SF_LIST * s); NODE_DATA sflist_remove_tail ( SF_LIST * s); void sflist_remove_node (SF_LIST * s, SF_LNODE * n); int sflist_count ( SF_LIST* s); NODE_DATA sflist_first( SF_LIST * s); NODE_DATA sflist_next( SF_LIST * s); SF_LNODE * sflist_first_node( SF_LIST * s ); SF_LNODE * sflist_next_node( SF_LIST * s ); NODE_DATA sflist_firstpos( SF_LIST * s, SF_LNODE ** v ); NODE_DATA sflist_nextpos ( SF_LIST * s, SF_LNODE ** v ); void sflist_free ( SF_LIST * s); void sflist_free_all( SF_LIST * s, 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* s, NODE_DATA ndata ); NODE_DATA sfstack_remove ( SF_STACK * s); int sfstack_count ( SF_STACK * s); void sfstack_free ( SF_STACK * s); void sfstack_free_all( SF_STACK* s, 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 ) */ SF_QUEUE *sfqueue_new ( void ); int sfqueue_add( SF_QUEUE * s, NODE_DATA ndata ); NODE_DATA sfqueue_remove ( SF_QUEUE * s); int sfqueue_count ( SF_QUEUE * s); void sfqueue_free ( SF_QUEUE * s); void sfqueue_free_all( SF_QUEUE* s, 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 * s, unsigned * a, unsigned n ); int sfistack_push( SF_ISTACK *s, unsigned value); int sfistack_pop( SF_ISTACK *s, unsigned * value); int sfpstack_init( SF_PSTACK * s, void ** a, unsigned n ); int sfpstack_push( SF_PSTACK *s, void * value); int sfpstack_pop( SF_PSTACK *s, void ** value); #endif snort-2.9.15.1/src/sfutil/sfmemcap.c0000644000175200017520000000677713571422607014125 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2003-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* sfmemcap.c These functions wrap the alloc & free functions. They enforce a memory cap using the MEMCAP structure. The MEMCAP structure tracks memory usage. Each allocation has 4 bytes added to it so we can store the allocation size. This allows us to free a block and accurately track how much memory was recovered. Marc Norton */ #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sf_types.h" #include "snort_debug.h" #include "sfmemcap.h" #ifndef DYNAMIC_PREPROC_CONTEXT #include "util.h" #else #include "sf_dynamic_preprocessor.h" #endif //DYNAMIC_PREPROC_CONTEXT /* * Set max # bytes & init other variables. */ void sfmemcap_init( MEMCAP * mc, unsigned long nbytes ) { mc->memcap = nbytes; mc->memused= 0; mc->nblocks= 0; } /* * Create and Init a MEMCAP - use free to release it */ MEMCAP * sfmemcap_new( unsigned nbytes ) { MEMCAP * mc; mc = (MEMCAP*)calloc(1,sizeof(MEMCAP)); if( mc ) sfmemcap_init( mc, nbytes ); return mc; } /* * Release the memcap structure */ void sfmemcap_delete( MEMCAP * p ) { if(p)free( p ); } /* * Allocate some memory */ void * sfmemcap_alloc( MEMCAP * mc, unsigned long nbytes ) { long * data; //printf("sfmemcap_alloc: %d bytes requested, memcap=%d, used=%d\n",nbytes,mc->memcap,mc->memused); nbytes += sizeof(long); /* Check if we are limiting memory use */ if( mc->memcap > 0 ) { /* Check if we've maxed out our memory - if we are tracking memory */ if( (mc->memused + nbytes) > mc->memcap ) { return 0; } } //data = (long *) malloc( nbytes ); data = (long *)calloc(1, nbytes); if( data == NULL ) { return 0; } *data++ = (long)nbytes; mc->memused += nbytes; mc->nblocks++; return data; } /* * Free some memory */ void sfmemcap_free( MEMCAP * mc, void * p ) { long * q; q = (long*)p; q--; mc->memused -= (unsigned)(*q); mc->nblocks--; free(q); } /* * For debugging. */ void sfmemcap_showmem( MEMCAP * mc ) { fprintf(stderr, "memcap: memcap = %lu bytes,",mc->memcap); fprintf(stderr, " memused= %lu bytes,",mc->memused); fprintf(stderr, " nblocks= %d blocks\n",mc->nblocks); } /* * Dup Some memory. */ void * sfmemcap_dupmem( MEMCAP * mc, void * src, unsigned long n ) { void * data = (char *)sfmemcap_alloc( mc, n ); if(data == NULL) { return 0; } memcpy( data, src, n ); return data; } snort-2.9.15.1/src/sfutil/sfmemcap.h0000644000175200017520000000310213571422607014105 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2003-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* ** sfmemcap.h */ #ifndef __SF_MEMCAP_H__ #define __SF_MEMCAP_H__ typedef struct { unsigned long memused; unsigned long memcap; int nblocks; }MEMCAP; void sfmemcap_init(MEMCAP * mc, unsigned long nbytes); MEMCAP * sfmemcap_new( unsigned nbytes ); void sfmemcap_delete( MEMCAP * mc ); void * sfmemcap_alloc(MEMCAP * mc, unsigned long nbytes); void sfmemcap_showmem(MEMCAP * mc ); void sfmemcap_free( MEMCAP * mc, void * memory); void * sfmemcap_dupmem(MEMCAP * mc, void * src, unsigned long n ); #endif snort-2.9.15.1/src/sfutil/sfthd.c0000644000175200017520000011415513571422607013430 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2003-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /*! * * \file sfthd.c * * An Abstracted Event Thresholding System * * Marc Norton * * 3/5/07 - man - fixed memory leak in global config to limit * of one gid=0, or multiple gid!=0 but not both. * Boris Lytochkin found it. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifndef WIN32 #include #endif #include "parser/IpAddrSet.h" #include "sflsq.h" #include "sfghash.h" #include "sfxhash.h" #include "snort.h" #include "sfthd.h" #include "util.h" #include "sfPolicy.h" // Debug Printing //#define THD_DEBUG // This disables adding and testing of Threshold objects //#define CRIPPLE SFXHASH * sfthd_new_hash(unsigned nbytes, size_t key, size_t data) { size_t size = key + data; int nrows; /* Calc max ip nodes for this memory */ if ( nbytes < size ) { nbytes = size; } nrows = nbytes / (size); return sfxhash_new( nrows, /* try one node per row - for speed */ key, /* keys size */ data, /* data size */ nbytes, /* memcap **/ 1, /* ANR flag - true ?- Automatic Node Recovery=ANR */ 0, /* ANR callback - none */ 0, /* user freemem callback - none */ 1 ) ; /* Recycle nodes ?*/ } /*! Create a threshold table, initialize the threshold system, and optionally limit it's memory usage. @param nbytes maximum memory to use for thresholding objects, in bytes. @return THD_STRUCT* @retval 0 error @retval !0 valid THD_STRUCT */ SFXHASH * sfthd_local_new(unsigned bytes) { SFXHASH *local_hash = sfthd_new_hash(bytes, sizeof(THD_IP_NODE_KEY), sizeof(THD_IP_NODE)); #ifdef THD_DEBUG if (local_hash == NULL) printf("Could not allocate the sfxhash table\n"); #endif return local_hash; } SFXHASH * sfthd_global_new(unsigned bytes) { SFXHASH *global_hash = sfthd_new_hash(bytes, sizeof(THD_IP_GNODE_KEY), sizeof(THD_IP_NODE)); #ifdef THD_DEBUG if (global_hash == NULL) printf("Could not allocate the sfxhash table\n"); #endif return global_hash; } THD_STRUCT * sfthd_new(unsigned lbytes, unsigned gbytes) { THD_STRUCT * thd; /* Create the THD struct */ thd = (THD_STRUCT *)SnortAlloc(sizeof(THD_STRUCT)); #ifndef CRIPPLE /* Create hash table for all of the local IP Nodes */ thd->ip_nodes = sfthd_local_new(lbytes); if( !thd->ip_nodes ) { #ifdef THD_DEBUG printf("Could not allocate the sfxhash table\n"); #endif free(thd); return NULL; } if ( gbytes == 0 ) return thd; /* Create hash table for all of the global IP Nodes */ thd->ip_gnodes = sfthd_global_new(gbytes); if( !thd->ip_gnodes ) { #ifdef THD_DEBUG printf("Could not allocate the sfxhash table\n"); #endif sfxhash_delete(thd->ip_nodes); free(thd); return NULL; } #endif return thd; } ThresholdObjects * sfthd_objs_new(void) { return (ThresholdObjects *)SnortAlloc(sizeof(ThresholdObjects)); } static void sfthd_node_free(void *node) { THD_NODE *sfthd_node = (THD_NODE *)node; if (sfthd_node == NULL) return; if (sfthd_node->ip_address != NULL) { IpAddrSetDestroy(sfthd_node->ip_address); } free(sfthd_node); } void sfthd_objs_free(ThresholdObjects *thd_objs) { int i; tSfPolicyId policyId; if (thd_objs == NULL) return; for (i = 0; i < THD_MAX_GENID; i++) { if (thd_objs->sfthd_array[i]) sfghash_delete(thd_objs->sfthd_array[i]); } for (policyId = 0; policyId < thd_objs->numPoliciesAllocated; policyId++) { if (thd_objs->sfthd_garray[policyId] == NULL) continue; if (thd_objs->sfthd_garray[policyId][0] != NULL) { sfthd_node_free((void *)thd_objs->sfthd_garray[policyId][0]); /* Free any individuals */ for (i = 0; i < THD_MAX_GENID; i++) { if (thd_objs->sfthd_garray[policyId][i] != thd_objs->sfthd_garray[policyId][0]) { sfthd_node_free( (void *)thd_objs->sfthd_garray[policyId][i]); } } } else { /* Anything other GID will be allocated individually */ for (i = 1; i < THD_MAX_GENID; i++) { if (thd_objs->sfthd_garray[policyId][i]) { sfthd_node_free((void *)thd_objs->sfthd_garray[policyId][i]); } } } free(thd_objs->sfthd_garray[policyId]); } if (thd_objs->sfthd_garray != NULL) free(thd_objs->sfthd_garray); free(thd_objs); } void sfthd_item_free(void *item) { THD_ITEM *sfthd_item = (THD_ITEM*)item; sflist_free_all(sfthd_item->sfthd_node_list, sfthd_node_free); free(sfthd_item); } void sfthd_free(THD_STRUCT *thd) { if (thd == NULL) return; #ifndef CRIPPLE if (thd->ip_nodes != NULL) sfxhash_delete(thd->ip_nodes); if (thd->ip_gnodes != NULL) sfxhash_delete(thd->ip_gnodes); #endif free(thd); } void * sfthd_create_rule_threshold(int id, int tracking, int type, int count, unsigned int seconds) { THD_NODE *sfthd_node = (THD_NODE *)calloc(1, sizeof(THD_NODE)); if (sfthd_node == NULL) return NULL; sfthd_node->thd_id = id; sfthd_node->tracking = tracking; sfthd_node->type = type; sfthd_node->count = count; sfthd_node->seconds = seconds; return (void *)sfthd_node; } /*! Add a permanent threshold object to the threshold table. Multiple objects may be defined for each gen_id and sig_id pair. Internally a unique threshold id is generated for each pair. Threshold objects track the number of events seen during the time interval specified by seconds. Depending on the type of threshold object and the count value, the thresholding object determines if the current event should be logged or dropped. @param thd Threshold object from sfthd_new() @param gen_id Generator id @param sig_id Signauture id @param tracking Selects tracking by src ip or by dst ip @param type Thresholding type: Limit, Threshold, or Limt+Threshold, Suppress @param priority Assigns a relative priority to this object, higher numbers imply higher priority @param count Number of events @param seconds Time duration over which this threshold object acts. @param ip IP address, for supression @param ip-mask IP mask, applied with ip_mask, for supression @return integer @retval 0 successfully added the thresholding object @retval !0 failed */ static int sfthd_create_threshold_local(SnortConfig *sc, ThresholdObjects *thd_objs, THD_NODE* config) { SFGHASH * sfthd_hash; THD_ITEM * sfthd_item; THD_NODE * sfthd_node; tThdItemKey key; int nrows; int hstatus; tSfPolicyId policy_id = getParserPolicy(sc); if (thd_objs == NULL ) return -1; if( config->gen_id >= THD_MAX_GENID ) return -1; #ifdef CRIPPLE return 0; #endif /* Check for an existing 'gen_id' entry, if none found create one. */ if (thd_objs->sfthd_array[config->gen_id] == NULL) { if( config->gen_id == 1 )/* patmatch rules gen_id, many rules */ { nrows= THD_GEN_ID_1_ROWS; } else /* other gen_id's */ { nrows= THD_GEN_ID_ROWS; } /* Create the hash table for this gen_id */ sfthd_hash = sfghash_new( nrows, sizeof(tThdItemKey), 0, sfthd_item_free ); if( !sfthd_hash ) { return -2; } thd_objs->sfthd_array[config->gen_id] = sfthd_hash; } else { /* Get the hash table for this gen_id */ sfthd_hash = thd_objs->sfthd_array[config->gen_id]; } if (sfthd_hash == NULL) return -2; key.sig_id = config->sig_id; key.policyId = policy_id; /* Check if sig_id is already in the table - if not allocate and add it */ sfthd_item = (THD_ITEM*)sfghash_find( sfthd_hash, (void*)&key ); if( !sfthd_item ) { /* Create the sfthd_item hash node data */ sfthd_item = (THD_ITEM*)calloc(1,sizeof(THD_ITEM)); if( !sfthd_item ) { return -3; } sfthd_item->gen_id = config->gen_id; sfthd_item->sig_id = config->sig_id; sfthd_item->policyId = policy_id; sfthd_item->sfthd_node_list = sflist_new(); if(!sfthd_item->sfthd_node_list) { free(sfthd_item); return -4; } /* Add the sfthd_item to the hash table */ hstatus = sfghash_add( sfthd_hash, (void*)&key, sfthd_item ); if( hstatus ) { sflist_free(sfthd_item->sfthd_node_list); free(sfthd_item); return -5; } } /* * Test that we only have one Limit/Threshold/Both Object at the tail, * we can have multiple suppression nodes at the head */ if( sfthd_item->sfthd_node_list->count > 0 ) { THD_NODE * p; if( !sfthd_item->sfthd_node_list->tail) { /* can you say paranoid- if there is a count, there should be a tail */ return -10; } p = (THD_NODE*)sfthd_item->sfthd_node_list->tail->ndata; if(p) /* just to be safe- if thers a tail, there is is node data */ { if( p->type != THD_TYPE_SUPPRESS && config->type != THD_TYPE_SUPPRESS ) { #ifdef THD_DEBUG printf("THD_DEBUG: Could not add a 2nd Threshold object, " "you can only have 1 per sid: gid=%u, sid=%u\n", config->gen_id, config->sig_id); #endif /* cannot add more than one threshold per sid in version 3.0, wait for 3.2 and CIDR blocks */ return THD_TOO_MANY_THDOBJ; } } } /* Create a THD_NODE for this THD_ITEM (Object) */ sfthd_node = (THD_NODE*)calloc(1,sizeof(THD_NODE)); if( !sfthd_node ) { return -6; } /* Limit priorities to force supression nodes to highest priority */ if( config->priority >= THD_PRIORITY_SUPPRESS ) { config->priority = THD_PRIORITY_SUPPRESS - 1; } /* Copy the node parameters */ sfthd_node->thd_id = config->thd_id; sfthd_node->gen_id = config->gen_id; sfthd_node->sig_id = config->sig_id; sfthd_node->tracking = config->tracking; /* by_src, by_dst */ sfthd_node->type = config->type; sfthd_node->priority = config->priority; sfthd_node->count = config->count; sfthd_node->seconds = config->seconds; sfthd_node->ip_address= config->ip_address; if( config->type == THD_TYPE_SUPPRESS ) { sfthd_node->priority = THD_PRIORITY_SUPPRESS; } /* If sfthd_node list is empty - add as head node */ if( !sfthd_item->sfthd_node_list->count ) { #ifdef THD_DEBUG printf("Threshold node added to head of list\n");fflush(stdout); #endif sflist_add_head(sfthd_item->sfthd_node_list,sfthd_node); } /* else add the sfthd_node using priority to determine where in the list it belongs 3.0 we can have only 1 threshold object but several suppression objects plus a single threshold object is ok. Blocking multiple threshold objects is done above. Suppressions have the highest priority and are at the front of the list, the tail node is either a supprssion node or the only pure thresholding node. */ else { SF_LNODE* lnode; /* Walk the list and insert based on priorities if suppress */ for( lnode = sflist_first_node(sfthd_item->sfthd_node_list); lnode; lnode = sflist_next_node(sfthd_item->sfthd_node_list) ) { THD_NODE* sfthd_n = (THD_NODE*)lnode->ndata; /* check if the new node is higher priority */ if( sfthd_node->priority > sfthd_n->priority ) { /* insert before current node */ #ifdef THD_DEBUG printf("Threshold node added after based on priority\n");fflush(stdout); #endif sflist_add_before(sfthd_item->sfthd_node_list,lnode,sfthd_node); return 0; } /* last node, just insert it here */ if( !lnode->next ) { /* if last node, insert at end of list */ #ifdef THD_DEBUG printf("Threshold node added to tail\n");fflush(stdout); #endif sflist_add_tail(sfthd_item->sfthd_node_list,sfthd_node); return 0; } } } return 0; } /* */ static int sfthd_create_threshold_global(SnortConfig *sc, ThresholdObjects *thd_objs, THD_NODE* config) { THD_NODE *sfthd_node; tSfPolicyId policy_id = getParserPolicy(sc); if (thd_objs == NULL) return -1; if (thd_objs->sfthd_garray[policy_id] == NULL) { thd_objs->sfthd_garray[policy_id] = (THD_NODE **)(calloc(THD_MAX_GENID, sizeof(THD_NODE *))); if (thd_objs->sfthd_garray[policy_id] == NULL) { return -1; } } if ((config->gen_id == 0) && (thd_objs->sfthd_garray[policy_id][config->gen_id] != NULL)) { return THD_TOO_MANY_THDOBJ; } /* Reset the current threshold */ if (thd_objs->sfthd_garray[policy_id][config->gen_id] == thd_objs->sfthd_garray[policy_id][0]) { thd_objs->sfthd_garray[policy_id][config->gen_id] = NULL; } else if(thd_objs->sfthd_garray[policy_id][config->gen_id]) { return THD_TOO_MANY_THDOBJ; } sfthd_node = (THD_NODE*)calloc(1,sizeof(THD_NODE)); if( !sfthd_node ) { return -2; } /* Copy the node parameters */ sfthd_node->thd_id = config->thd_id; sfthd_node->gen_id = config->gen_id; sfthd_node->sig_id = config->sig_id; /* -1 for global thresholds */ sfthd_node->tracking = config->tracking; /* by_src, by_dst */ sfthd_node->type = config->type; sfthd_node->priority = config->priority; sfthd_node->count = config->count; sfthd_node->seconds = config->seconds; sfthd_node->ip_address = config->ip_address; /* need a hash of these where * key=[gen_id,sig_id] => THD_GNODE_KEY * data = THD_NODE's */ if (config->gen_id == 0) /* do em all */ { int i; for (i = 0; i < THD_MAX_GENID; i++) { /* only assign if there wasn't a value */ if (thd_objs->sfthd_garray[policy_id][i] == NULL) { thd_objs->sfthd_garray[policy_id][i] = sfthd_node; } } } else { thd_objs->sfthd_garray[policy_id][config->gen_id] = sfthd_node; } #ifdef THD_DEBUG printf("THD_DEBUG-GLOBAL: created global threshold object " "for gen_id=%d\n",config->gen_id); fflush(stdout); #endif return 0; } /*! Add a permanent threshold object to the threshold table. Multiple objects may be defined for each gen_id and sig_id pair. Internally a unique threshold id is generated for each pair. Threshold objects track the number of events seen during the time interval specified by seconds. Depending on the type of threshold object and the count value, the thresholding object determines if the current event should be logged or dropped. @param thd Threshold object from sfthd_new() @param gen_id Generator id @param sig_id Signauture id @param tracking Selects tracking by src ip or by dst ip @param type Thresholding type: Limit, Threshold, or Limt+Threshold, Suppress @param priority Assigns a relative priority to this object, higher numbers imply higher priority @param count Number of events @param seconds Time duration over which this threshold object acts. @param ip IP address, for supression @param ip-mask IP mask, applied with ip_mask, for supression @return integer @retval 0 successfully added the thresholding object @retval !0 failed --- Local and Global Thresholding is setup here --- */ int sfthd_create_threshold(SnortConfig *sc, ThresholdObjects *thd_objs, unsigned gen_id, unsigned sig_id, int tracking, int type, int priority, int count, int seconds, IpAddrSet* ip_address) { //allocate memory fpr sfthd_array if needed. tSfPolicyId policyId = getParserPolicy(sc); THD_NODE sfthd_node; memset(&sfthd_node, 0, sizeof(sfthd_node)); thd_objs->count++; sfthd_node.thd_id = thd_objs->count; /* produce a unique thd_id for this node */ sfthd_node.gen_id = gen_id; sfthd_node.sig_id = sig_id; sfthd_node.tracking = tracking; /* by_src, by_dst */ sfthd_node.type = type; sfthd_node.priority = priority; sfthd_node.count = count; sfthd_node.seconds = seconds; sfthd_node.ip_address= ip_address; sfDynArrayCheckBounds ((void **)&thd_objs->sfthd_garray, policyId, &thd_objs->numPoliciesAllocated); if (thd_objs->sfthd_garray[policyId] == NULL) { thd_objs->sfthd_garray[policyId] = SnortAlloc(THD_MAX_GENID * sizeof(THD_NODE *)); if (thd_objs->sfthd_garray[policyId] == NULL) { return -1; } } if( sig_id == 0 ) { return sfthd_create_threshold_global(sc, thd_objs, &sfthd_node); } if( gen_id == 0 ) return -1; return sfthd_create_threshold_local(sc, thd_objs, &sfthd_node); } #ifdef THD_DEBUG static char * printIP(unsigned u ) { static char s[80]; SnortSnprintf(s,80,"%d.%d.%d.%d", (u>>24)&0xff, (u>>16)&0xff, (u>>8)&0xff, u&0xff ); return s; } #endif int sfthd_test_rule(SFXHASH *rule_hash, THD_NODE *sfthd_node, sfaddr_t* sip, sfaddr_t* dip, long curtime, detection_option_eval_data_t *eval_data) { int status; if ((rule_hash == NULL) || (sfthd_node == NULL)) return 0; status = sfthd_test_local(rule_hash, sfthd_node, sip, dip, curtime, eval_data); return (status < -1) ? 1 : status; } static inline int sfthd_test_suppress ( THD_NODE* sfthd_node, sfaddr_t* ip) { if ( !sfthd_node->ip_address || IpAddrSetContains(sfthd_node->ip_address, ip) ) { #ifdef THD_DEBUG printf("THD_DEBUG: SUPPRESS NODE, do not log events with this IP\n"); fflush(stdout); #endif /* Don't log, and stop looking( event's to this address * for this gen_id+sig_id) */ sfthd_node->filtered++; return -1; } return 1; /* Keep looking for other suppressors */ } /* * Do the appropriate test for the Threshold Object Type */ static inline int sfthd_test_non_suppress( THD_NODE* sfthd_node, THD_IP_NODE* sfthd_ip_node, time_t curtime) { unsigned dt; if( sfthd_node->type == THD_TYPE_DETECT ) { #ifdef THD_DEBUG printf("\n...Detect Test\n"); fflush(stdout); #endif dt = (unsigned)(curtime - sfthd_ip_node->tstart); if( dt >= sfthd_node->seconds ) { /* reset */ sfthd_ip_node->tstart = curtime; if ( (unsigned)(curtime - sfthd_ip_node->tlast) > sfthd_node->seconds ) sfthd_ip_node->prev = 0; else sfthd_ip_node->prev = sfthd_ip_node->count - 1; sfthd_ip_node->count = 1; } sfthd_ip_node->tlast = curtime; #ifdef THD_DEBUG printf("...dt=%d, sfthd_node->seconds=%d\n",dt, sfthd_node->seconds ); printf("...sfthd_ip_node->count=%d, sfthd_node->count=%d\n", sfthd_ip_node->count,sfthd_node->count ); fflush(stdout); #endif if( (int)sfthd_ip_node->count > sfthd_node->count || (int)sfthd_ip_node->prev > sfthd_node->count ) { return 0; /* Log it, stop looking: log all > 'count' events */ } /* Don't Log yet, don't keep looking: * already logged our limit, don't log this sid */ sfthd_node->filtered++; return -2; } if( sfthd_node->type == THD_TYPE_LIMIT ) { #ifdef THD_DEBUG printf("\n...Limit Test\n"); fflush(stdout); #endif dt = (unsigned)(curtime - sfthd_ip_node->tstart); if( dt >= sfthd_node->seconds ) { /* reset */ sfthd_ip_node->tstart = curtime; sfthd_ip_node->count = 1; } #ifdef THD_DEBUG printf("...dt=%d, sfthd_node->seconds=%d\n",dt, sfthd_node->seconds ); printf("...sfthd_ip_node->count=%d, sfthd_node->count=%d\n", sfthd_ip_node->count,sfthd_node->count ); fflush(stdout); #endif if( (int)sfthd_ip_node->count <= sfthd_node->count ) { return 0; /* Log it, stop looking: only log the 1st 'count' events */ } /* Don't Log yet, don't keep looking: * already logged our limit, don't log this sid */ sfthd_node->filtered++; return -2; } else if( sfthd_node->type == THD_TYPE_THRESHOLD ) { #ifdef THD_DEBUG printf("\n...Threshold Test\n"); fflush(stdout); #endif dt = (unsigned)(curtime - sfthd_ip_node->tstart); if( dt >= sfthd_node->seconds ) { sfthd_ip_node->tstart = curtime; sfthd_ip_node->count = 1; } if( (int)sfthd_ip_node->count >= sfthd_node->count ) { /* reset */ sfthd_ip_node->count = 0; sfthd_ip_node->tstart= curtime; return 0; /* Log it, stop looking */ } sfthd_node->filtered++; return -2; /* don't log yet */ } else if( sfthd_node->type == THD_TYPE_BOTH ) { #ifdef THD_DEBUG printf("\n...Threshold+Limit Test\n"); fflush(stdout); #endif dt = (unsigned)(curtime - sfthd_ip_node->tstart); if( dt >= sfthd_node->seconds ) { sfthd_ip_node->tstart = curtime; sfthd_ip_node->count = 1; /* Don't Log yet, keep looking: * only log after we reach count, which must be > '1' */ sfthd_node->filtered++; return -2; } else { if( (int)sfthd_ip_node->count >= sfthd_node->count ) { if( (int)sfthd_ip_node->count > sfthd_node->count ) { /* don't log it, stop looking: * log once per time interval - than block it */ sfthd_node->filtered++; return -2; } /* Log it, stop looking: * log the 1st event we see past 'count' events */ return 0; } else /* Block it from logging */ { /* don't log it, stop looking: * we must see at least count events 1st */ sfthd_node->filtered++; return -2; } } } #ifdef THD_DEBUG printf("THD_DEBUG: You should not be here...\n"); fflush(stdout); #endif return 0; /* should not get here, so log it just to be safe */ } /*! * * Find/Test/Add an event against a single threshold object. * Events without thresholding objects are automatically loggable. * * @param thd Threshold table pointer * @param sfthd_node Permanent Thresholding Object * @param sip Event/Packet Src IP address- should be host ordered for comparison * @param dip Event/Packet Dst IP address * @param curtime Current Event/Packet time in seconds * * @return integer * @retval 0 : Event is loggable * @retval >0 : Event should not be logged, try next thd object * @retval <0 : Event should never be logged to this user! Suppressed Event+IP * */ int sfthd_test_local( SFXHASH *local_hash, THD_NODE * sfthd_node, sfaddr_t* sip, sfaddr_t* dip, time_t curtime, detection_option_eval_data_t *eval_data) { THD_IP_NODE_KEY key; THD_IP_NODE data,*sfthd_ip_node; int status=0; sfaddr_t* ip; tSfPolicyId policy_id = getIpsRuntimePolicy(); #ifdef THD_DEBUG printf("THD_DEBUG: Key THD_NODE IP=%s,",printIP((unsigned)sfthd_node->ip_address) ); printf(" MASK=%s\n",printIP((unsigned)sfthd_node->ip_mask) ); printf("THD_DEBUG: PKT SIP=%s\n",printIP((unsigned)sip) ); printf("THD_DEBUG: PKT DIP=%s\n",printIP((unsigned)dip) ); fflush(stdout); #endif /* -1 means don't do any limit or thresholding */ if ( sfthd_node->count == THD_NO_THRESHOLD) { #ifdef THD_DEBUG printf("\n...No Threshold applied for this object\n"); fflush(stdout); #endif return 0; } /* * Get The correct IP */ if (sfthd_node->tracking == THD_TRK_SRC) ip = sip; else ip = dip; /* * Check for and test Suppression of this event to this IP */ if( sfthd_node->type == THD_TYPE_SUPPRESS ) { #ifdef THD_DEBUG printf("THD_DEBUG: SUPPRESS NODE Testing...\n");fflush(stdout); #endif return sfthd_test_suppress(sfthd_node, ip); } /* * Go on and do standard thresholding */ /* Set up the key */ key.policyId = policy_id; sfaddr_copy_to_raw(&key.ip, ip); key.thd_id = sfthd_node->thd_id; /* Set up a new data element */ data.count = 0; data.prev = 0; data.tstart = data.tlast = curtime; /* Event time */ /* * Check for any Permanent sig_id objects for this gen_id or add this one ... */ status = sfxhash_add(local_hash, (void*)&key, &data); if (status == SFXHASH_INTABLE || status == SFXHASH_OK) { /* Already in the table */ sfthd_ip_node = local_hash->cnode->data; /* Increment the event count */ if(eval_data) { if(eval_data->detection_filter_count == 0) { eval_data->detection_filter_count = 1; sfthd_ip_node->count++; } } else { sfthd_ip_node->count++; } } else if (status != SFXHASH_OK) { /* hash error */ return 1; /* check the next threshold object */ } else { /* Was not in the table - it was added - work with our copy of the data */ sfthd_ip_node = &data; if(eval_data) { eval_data->detection_filter_count = 1; } } return sfthd_test_non_suppress(sfthd_node, sfthd_ip_node, curtime); } /* * Test a global thresholding object */ static inline int sfthd_test_global( SFXHASH *global_hash, THD_NODE * sfthd_node, unsigned gen_id, /* from current event */ unsigned sig_id, /* from current event */ sfaddr_t* sip, /* " */ sfaddr_t* dip, /* " */ time_t curtime ) { THD_IP_GNODE_KEY key; THD_IP_NODE data, *sfthd_ip_node; int status=0; sfaddr_t* ip; tSfPolicyId policy_id = getIpsRuntimePolicy(); #ifdef THD_DEBUG printf("THD_DEBUG-GLOBAL: gen_id=%u, sig_id=%u\n",gen_id,sig_id); printf("THD_DEBUG: Global THD_NODE IP=%s,",printIP((unsigned)sfthd_node->ip_address) ); printf(" MASK=%s\n",printIP((unsigned)sfthd_node->ip_mask) ); printf("THD_DEBUG: PKT SIP=%s\n",printIP((unsigned)sip) ); printf("THD_DEBUG: PKT DIP=%s\n",printIP((unsigned)dip) ); fflush(stdout); #endif /* -1 means don't do any limit or thresholding */ if ( sfthd_node->count == THD_NO_THRESHOLD) { #ifdef THD_DEBUG printf("\n...No Threshold applied for this object\n"); fflush(stdout); #endif return 0; } /* Get The correct IP */ if (sfthd_node->tracking == THD_TRK_SRC) ip = sip; else ip = dip; /* Check for and test Suppression of this event to this IP */ if( sfthd_node->type == THD_TYPE_SUPPRESS ) { #ifdef THD_DEBUG printf("THD_DEBUG: G-SUPPRESS NODE Testing...\n");fflush(stdout); #endif return sfthd_test_suppress(sfthd_node, ip); } /* * Go on and do standard thresholding */ /* Set up the key */ sfaddr_copy_to_raw(&key.ip, ip); key.gen_id = sfthd_node->gen_id; key.sig_id = sig_id; key.policyId = policy_id; /* Set up a new data element */ data.count = 1; data.prev = 0; data.tstart = data.tlast = curtime; /* Event time */ /* Check for any Permanent sig_id objects for this gen_id or add this one ... */ status = sfxhash_add(global_hash, (void*)&key, &data); if (status == SFXHASH_INTABLE) { /* Already in the table */ sfthd_ip_node = global_hash->cnode->data; /* Increment the event count */ sfthd_ip_node->count++; } else if (status != SFXHASH_OK) { /* hash error */ return 1; /* check the next threshold object */ } else { /* Was not in the table - it was added - work with our copy of the data */ sfthd_ip_node = &data; } return sfthd_test_non_suppress(sfthd_node, sfthd_ip_node, curtime); } /*! * * Test a an event against the threshold database. * Events without thresholding objects are automatically * loggable. * * @param thd Threshold table pointer * @param gen_id Generator Id from the event * @param sig_id Signature Id from the event * @param sip Event/Packet Src IP address * @param dip Event/Packet Dst IP address * @param curtime Current Event/Packet time * * @return integer * @retval 0 : Event is loggable * @retval !0 : Event should not be logged (-1 suppressed, 1 filtered) * */ int sfthd_test_threshold( ThresholdObjects *thd_objs, THD_STRUCT *thd, unsigned gen_id, unsigned sig_id, sfaddr_t* sip, sfaddr_t* dip, long curtime ) { tThdItemKey key; SFGHASH * sfthd_hash; THD_ITEM * sfthd_item; THD_NODE * sfthd_node; THD_NODE * g_thd_node = NULL; #ifdef THD_DEBUG int cnt; #endif int status=0; tSfPolicyId policy_id = getIpsRuntimePolicy(); if ((thd_objs == NULL) || (thd == NULL)) return 0; #ifdef CRIPPLE return 0; #endif #ifdef THD_DEBUG printf("sfthd_test_threshold...\n");fflush(stdout); #endif if( gen_id >= THD_MAX_GENID ) { #ifdef THD_DEBUG printf("THD_DEBUG: invalid gen_id=%u\n",gen_id); fflush(stdout); #endif return 0; /* bogus gen_id */ } /* * Get the hash table for this gen_id */ sfthd_hash = thd_objs->sfthd_array[gen_id]; if (sfthd_hash == NULL) { #ifdef THD_DEBUG printf("THD_DEBUG: no hash table entry for gen_id=%u\n",gen_id); fflush(stdout); #endif goto global_test; /* return 0; */ /* no threshold objects for this gen_id, log it ! */ } key.sig_id = sig_id; key.policyId = policy_id; /* * Check for any Permanent sig_id objects for this gen_id */ sfthd_item = (THD_ITEM *)sfghash_find(sfthd_hash, (void*)&key); if (sfthd_item == NULL) { #ifdef THD_DEBUG printf("THD_DEBUG: no THD objects for gen_id=%u, sig_id=%u\n",gen_id,sig_id); fflush(stdout); #endif /* no matching permanent sig_id objects so, log it ! */ goto global_test; } /* No List of Threshold objects - bail and log it */ if (sfthd_item->sfthd_node_list == NULL) { goto global_test; } /* For each permanent thresholding object, test/add/update the thd object */ /* We maintain a list of thd objects for each gen_id+sig_id */ /* each object has it's own unique thd_id */ /* Suppression nodes have a very high priority, so they are tested 1st */ #ifdef THD_DEBUG cnt=0; #endif for (sfthd_node = (THD_NODE *)sflist_first(sfthd_item->sfthd_node_list); sfthd_node != NULL; sfthd_node = (THD_NODE *)sflist_next(sfthd_item->sfthd_node_list)) { #ifdef THD_DEBUG cnt++; printf("THD_DEBUG: gen_id=%u sig_id=%u testing thd_id=%d thd_type=%d\n", gen_id, sig_id, sfthd_node->thd_id, sfthd_node->type); fflush(stdout); #endif /* * Test SUPPRESSION and THRESHOLDING */ status = sfthd_test_local(thd->ip_nodes, sfthd_node, sip, dip, curtime, NULL); if( status < 0 ) /* -1 == Don't log and stop looking */ { #ifdef THD_DEBUG printf("THD_DEBUG: gen_id=%u sig_id=%u, UnLoggable\n\n",gen_id, sig_id,cnt); fflush(stdout); #endif return (status < -1) ? 1 : -1; /* !0 == Don't log it*/ } else if( status == 0 ) /* Log it and stop looking */ { #ifdef THD_DEBUG printf("THD_DEBUG: gen_id=%u sig_id=%u tested %d THD_NODE's, " "Loggable\n\n",sfthd_item->gen_id, sfthd_item->sig_id,cnt); fflush(stdout); #endif return 0; /* 0 == Log the event */ } /* status > 0 : Log it later but Keep looking * check the next threshold object for a blocking action ... */ } /* * Test for a global threshold object * we're here cause ther were no threshold objects for this gen_id/sig_id pair */ global_test: #ifdef THD_DEBUG printf("THD_DEBUG-GLOBAL: doing global object test\n"); #endif if (thd_objs->sfthd_garray && thd_objs->sfthd_garray[policy_id]) { g_thd_node = thd_objs->sfthd_garray[policy_id][gen_id]; } if( g_thd_node ) { status = sfthd_test_global( thd->ip_gnodes, g_thd_node, gen_id, sig_id, sip, dip, curtime ); if( status < 0 ) /* -1 == Don't log and stop looking */ { #ifdef THD_DEBUG printf("THD_DEBUG-GLOBAL: gen_id=%u sig_id=%u THD_NODE's, " "UnLoggable\n\n",gen_id, sig_id); fflush(stdout); #endif return (status < -1) ? 1 : -1; /* !0 == Don't log it*/ } /* Log it ! */ #ifdef THD_DEBUG printf("THD_DEBUG-GLOBAL: gen_id=%u sig_id=%u THD_NODE's, " "Loggable\n\n",gen_id, sig_id); fflush(stdout); #endif } else { #ifdef THD_DEBUG printf("THD_DEBUG-GLOBAL: no Global THD Object for gen_id=%u, " "sig_id=%u\n\n",gen_id, sig_id); fflush(stdout); #endif } return 0; /* Default: Log it if we did not block the logging action */ } #ifdef THD_DEBUG /*! * A function to print the thresholding objects to stdout. * */ int sfthd_show_objects(ThresholdObjects *thd_objs) { SFGHASH * sfthd_hash; THD_ITEM * sfthd_item; THD_NODE * sfthd_node; int gen_id; SFGHASH_NODE * item_hash_node; tSfPolicyId policyId; for(gen_id=0;gen_id < THD_MAX_GENID ; gen_id++ ) { sfthd_hash = thd_objs->sfthd_array[gen_id]; if (sfthd_hash == NULL) continue; printf("...GEN_ID = %u\n",gen_id); for(item_hash_node = sfghash_findfirst( sfthd_hash ); item_hash_node != 0; item_hash_node = sfghash_findnext( sfthd_hash ) ) { /* Check for any Permanent sig_id objects for this gen_id */ sfthd_item = (THD_ITEM*)item_hash_node->data; printf(".....GEN_ID = %u, SIG_ID = %u, Policy = %u\n",gen_id,sfthd_item->sig_id, sfthd_item->policyId); /* For each permanent thresholding object, test/add/update the thd object */ /* We maintain a list of thd objects for each gen_id+sig_id */ /* each object has it's own unique thd_id */ for( sfthd_node = (THD_NODE*)sflist_first(sfthd_item->sfthd_node_list); sfthd_node != 0; sfthd_node = (THD_NODE*)sflist_next(sfthd_item->sfthd_node_list) ) { printf(".........THD_ID =%d\n",sfthd_node->thd_id ); if( sfthd_node->type == THD_TYPE_SUPPRESS ) printf(".........type =Suppress\n"); if( sfthd_node->type == THD_TYPE_LIMIT ) printf(".........type =Limit\n"); if( sfthd_node->type == THD_TYPE_THRESHOLD ) printf(".........type =Threshold\n"); if( sfthd_node->type == THD_TYPE_BOTH ) printf(".........type =Both\n"); printf(".........tracking=%d\n",sfthd_node->tracking); printf(".........priority=%d\n",sfthd_node->priority); if( sfthd_node->type == THD_TYPE_SUPPRESS ) { printf(".........ip =%s\n", sfip_to_str(&sfthd_node->ip_address)); printf(".........mask =%d\n", sfip_bits(&sfthd_node->ip_address)); printf(".........not_flag=%d\n",sfthd_node->ip_mask); } else { printf(".........count =%d\n",sfthd_node->count); printf(".........seconds =%d\n",sfthd_node->seconds); } } } } return 0; } #endif // THD_DEBUG snort-2.9.15.1/src/sfutil/sfthd.h0000644000175200017520000001565413571422607013441 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2003-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /*! \file sfthd.h */ #ifndef _SF_THRESHOLDING_ #define _SF_THRESHOLDING_ #include "ipv6_port.h" #include "parser/IpAddrSet.h" #include "sflsq.h" #include "sfghash.h" #include "sfxhash.h" #include "sfPolicy.h" #include "sfPolicyUserData.h" /*! Max GEN_ID value - Set this to the Max Used by Snort, this is used for the dimensions of the gen_id lookup array. Rows in each hash table, by gen_id. */ #define THD_MAX_GENID 8129 #define THD_GEN_ID_1_ROWS 4096 #define THD_GEN_ID_ROWS 512 #define THD_NO_THRESHOLD -1 #define THD_TOO_MANY_THDOBJ -15 /*! Type of Thresholding */ enum { THD_TYPE_LIMIT, THD_TYPE_THRESHOLD, THD_TYPE_BOTH, THD_TYPE_SUPPRESS, THD_TYPE_DETECT }; /* Very high priority for suppression objects users priorities are limited to this minus one */ #define THD_PRIORITY_SUPPRESS 1000000 /*! Tracking by src, or by dst */ enum { THD_TRK_NONE, // suppress only THD_TRK_SRC, THD_TRK_DST }; /*! THD_IP_NODE Dynamic hashed node data - added and deleted during runtime These are added during run-time, and recycled if we max out memory usage. */ typedef struct { unsigned count; unsigned prev; time_t tstart; time_t tlast; } THD_IP_NODE; /*! THD_IP_NODE_KEY HASH Key to lookup and store Ip nodes. The structure now tracks thresholds for different policies. This destroys locality of reference and may cause poor performance. */ typedef struct{ int thd_id; struct in6_addr ip; tSfPolicyId policyId; } THD_IP_NODE_KEY ; typedef struct{ unsigned gen_id; unsigned sig_id; struct in6_addr ip; tSfPolicyId policyId; } THD_IP_GNODE_KEY ; /*! THD_NODE A Thresholding Object These are created at program startup, and remain static. The THD_IP_NODE elements are dynamic. */ typedef struct { int thd_id; /* Id of this node */ unsigned gen_id; /* Keep these around if needed */ unsigned sig_id; int tracking; /* by_src, by_dst */ int type; int priority; int count; unsigned seconds; uint64_t filtered; IpAddrSet* ip_address; } THD_NODE; /*! THD_ITEM The THD_ITEM acts as a container of gen_id+sig_id based threshold objects, this allows multiple threshold objects to be applied to a single gen_id+sig_id pair. The sflist is created using the priority field, so highest priority objects are first in the list. When processing the highest priority object will trigger first. These are static data elements, built at program startup. */ typedef struct { tSfPolicyId policyId; unsigned gen_id; /* just so we know what gen_id we are */ unsigned sig_id; /* * List of THD_NODE's - walk this list and hash the * 'THD_NODE->sfthd_id + src_ip or dst_ip' to get the correct THD_IP_NODE. */ SF_LIST* sfthd_node_list; } THD_ITEM; // Temporary structure useful when parsing the Snort rules typedef struct _THDX_STRUCT { unsigned gen_id; unsigned sig_id; int type; int tracking; int priority; int count; unsigned int seconds; IpAddrSet* ip_address; } THDX_STRUCT; typedef struct { tSfPolicyId policyId; unsigned sig_id; } tThdItemKey; /*! THD_STRUCT The main thresholding data structure. Local and global threshold thd_id's are all unqiue, so we use just one ip_nodes lookup table */ typedef struct _THD_STRUCT { SFXHASH *ip_nodes; /* Global hash of active IP's key=THD_IP_NODE_KEY, data=THD_IP_NODE */ SFXHASH *ip_gnodes; /* Global hash of active IP's key=THD_IP_GNODE_KEY, data=THD_IP_GNODE */ } THD_STRUCT; typedef struct _ThresholdObjects { int count; /* Total number of thresholding/suppression objects */ SFGHASH *sfthd_array[THD_MAX_GENID]; /* Local Hash of THD_ITEM nodes, lookup by key=sig_id */ /* Double array of THD_NODE pointers. First index is policyId and therefore variable length. * Second index is genId and of fixed length, A simpler definition could be * THD_NODE * sfthd_garray[0][THD_MAX_GENID] and we could intentionally overflow first index, * but we may have to deal with compiler warnings if the array is indexed by value known at * compile time. */ //THD_NODE * (*sfthd_garray)[THD_MAX_GENID]; THD_NODE* **sfthd_garray; tSfPolicyId numPoliciesAllocated; } ThresholdObjects; /* * Prototypes */ // lbytes = local threshold memcap // gbytes = global threshold memcap (0 to disable global) THD_STRUCT * sfthd_new(unsigned lbytes, unsigned gbytes); SFXHASH * sfthd_local_new(unsigned bytes); SFXHASH * sfthd_global_new(unsigned bytes); void sfthd_free(THD_STRUCT *); ThresholdObjects * sfthd_objs_new(void); void sfthd_objs_free(ThresholdObjects *); int sfthd_test_rule(SFXHASH *rule_hash, THD_NODE *sfthd_node, sfaddr_t* sip, sfaddr_t* dip, long curtime, detection_option_eval_data_t *eval_data); void * sfthd_create_rule_threshold( int id, int tracking, int type, int count, unsigned int seconds ); struct _SnortConfig; int sfthd_create_threshold( struct _SnortConfig *, ThresholdObjects *, unsigned gen_id, unsigned sig_id, int tracking, int type, int priority, int count, int seconds, IpAddrSet* ip_address ); // 1: don't log due to event_filter // 0: log // -1: don't log due to suppress int sfthd_test_threshold( ThresholdObjects *, THD_STRUCT *, unsigned gen_id, unsigned sig_id, sfaddr_t* sip, sfaddr_t* dip, long curtime ) ; SFXHASH * sfthd_new_hash(unsigned, size_t, size_t); int sfthd_test_local( SFXHASH *local_hash, THD_NODE * sfthd_node, sfaddr_t* sip, sfaddr_t* dip, time_t curtime, detection_option_eval_data_t *eval_data); #ifdef THD_DEBUG int sfthd_show_objects( THD_STRUCT * thd ); #endif #endif snort-2.9.15.1/src/sfutil/sfxhash.c0000644000175200017520000011040213571422607013753 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2003-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /*!@file sfxhash.c * * A Customized hash table library for storing and accessing key + data pairs. * * This table incorporates a memory manager (memcap.c) to provide a memory cap, * and an automatic node recovery system for out of memory management. Keys and * Data are copied into the hash table during the add operation. The data may * be allocated and free'd by the user (by setting the datasize to zero ). A * user callback is provided to allow the user to do cleanup whenever a node * is released, by either the ANR system or the relase() function. * * Users can and should delete nodes when they know they are not needed anymore, * but this custom table is designed for the case where nodes are allocated * permanently, we have to limit memory, and we wish to recycle old nodes. * Many problems have a natural node ageing paradigm working in our favor, * so automated node aging makes sense. i.e. thresholding, tcp state. * * This hash table maps keys to data. All keys must be unique. * Uniqueness is enforcedby the code. * * Features: * * 1) Keys must be fixed length (per table) binary byte sequences. * keys are copied during the add function * 2) Data must be fixed length (per table) binary byte sequences. * data is copied during the add function - if datasize > 0 * Data may be managed by the user as well. * 3) Table row sizes can be automatically adjusted to * the nearest prime number size during table initialization/creation. * 4) Memory management includes tracking the size of each allocation, * number of allocations, enforcing a memory cap, and automatic node * recovery - when memory is low the oldest untouched node * is unlinked and recycled for use as a new node. * * Per Node Memory Usage: * ---------------------- * SFXHASH_NODE bytes * KEYSIZE bytes * [DATASIZE bytes] if datasize > 0 during call to sfxhash_new. * * The hash node memory (sfxhash_node,key,and data) is allocated with * one call to s_alloc/memcap_alloc. * * Author: Marc Norton * * 2003-06-03: cmg - added sfxhash_{l,m}ru to return {least,most} * recently used node from the global list * * - added _anrcount function * - changed count function to return unsigned to match structure * * 2003-06-11: cmg added * overhead_bytes + blocks to separate out the * memcap constraints from the hash table itself * find success v fail * * 2003-06-19: cmg added * * ability to set own hash function * ability to set own key cmp function * * 2003-06-30: rdempster * fixed bug in that would anr from the freelist * * 2005-11-15: modified sfxhash_add to check if 'data' is zero before memcpy'ing. * this allows user to pass null for data, and set up the data area * themselves after the call - this is much more flexible. * 8/31/2006: man - changed to use prime table lookup. */ #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sf_types.h" #include "snort_debug.h" #include "sfxhash.h" #include "sfprimetable.h" /**@defgroup sfxhash sourcefire.container.sfxhash * Implements SFXHASH as specialized hash container * @{ */ /* * Private Malloc - abstract the memory system */ static inline void * s_alloc( SFXHASH * t, int n ) { return sfmemcap_alloc( &t->mc, n ); } static inline void s_free( SFXHASH * t, void * p ) { sfmemcap_free( &t->mc, p ); } /* * User access to the memory management, do they need it ? WaitAndSee */ void * sfxhash_alloc( SFXHASH * t, unsigned nbytes ) { return s_alloc( t, nbytes ); } void sfxhash_free( SFXHASH * t, void * p ) { s_free( t, p ); } static int sfxhash_nearest_powerof2(int nrows) { unsigned i; nrows -= 1; for(i=1; i> i); nrows += 1; return nrows; } int sfxhash_calcrows(int num) { return sfxhash_nearest_powerof2(num); // return sf_nearest_prime( nrows ); } /*! * * Create a new hash table * * By default, this will "splay" nodes to the top of a free list. * * @param nrows number of rows in hash table * @param keysize key size in bytes, same for all keys * @param datasize datasize in bytes, zero indicates user manages data * @param maxmem maximum memory to use in bytes * @param anr_flag Automatic Node Recovery boolean flag * @param anrfree users Automatic Node Recovery memory release function * @param usrfree users standard memory release function * * @return SFXHASH* * @retval 0 out of memory * @retval !0 Valid SFXHASH pointer * */ /* Notes: if nrows < 0 don't cal the nearest powerof2. datasize must be the same for all entries, unless datasize is zero. maxmem of 0 indicates no memory limits. */ SFXHASH * sfxhash_new( unsigned nrows, int keysize, int datasize, unsigned long maxmem, int anr_flag, SFXHASH_FREE_FCN anrfree, SFXHASH_FREE_FCN usrfree, int recycle_flag ) { unsigned int i; SFXHASH * h; /* If nrows is not a power of two, need to find the * next highest power of two */ nrows = sfxhash_nearest_powerof2(nrows); /* Allocate the table structure from general memory */ h = (SFXHASH*)calloc(1, sizeof(SFXHASH)); if( !h ) { return 0; } /* this has a default hashing function */ h->sfhashfcn = sfhashfcn_new( nrows ); if( !h->sfhashfcn ) { free(h); return 0; } sfmemcap_init( &h->mc, maxmem ); /* Allocate the array of node ptrs */ h->table = (SFXHASH_NODE**) s_alloc( h, sizeof(SFXHASH_NODE*) * nrows ); if( !h->table ) { free(h->sfhashfcn); free(h); return 0; } for( i=0; itable[i] = 0; } h->anrfree = anrfree; h->usrfree = usrfree; h->keysize = keysize; #ifdef WORDS_MUSTALIGN if ((h->keysize) & 7) h->pad = (8 - ((h->keysize) & 7)); #else h->pad = 0; #endif h->datasize = datasize; h->nrows = nrows; h->max_nodes = 0; h->crow = 0; h->cnode = 0; h->count = 0; h->ghead = 0; h->gtail = 0; h->anr_count= 0; h->anr_tries= 0; h->anr_flag = anr_flag; h->splay = 1; h->recycle_nodes = recycle_flag; h->find_success = 0; h->find_fail = 0; /* save off how much we've already allocated from our memcap */ h->overhead_bytes = h->mc.memused; h->overhead_blocks = h->mc.nblocks; return h; } /*! * Set the maximum nodes used in this hash table. * Specifying 0 is unlimited (or otherwise limited by memcap). * * @param h SFXHASH table pointer * @param max_nodes maximum nodes to allow. * */ void sfxhash_set_max_nodes( SFXHASH *h, int max_nodes ) { if (h) { h->max_nodes = max_nodes; } } /*! * Set Splay mode : Splays nodes to front of list on each access * * @param t SFXHASH table pointer * @param n boolean flag toggles splaying of hash nodes * */ void sfxhash_splaymode( SFXHASH * t, int n ) { t->splay = n; } /*! * Free all nodes in the free list * * Removes and frees all of the nodes in the free list * No need to call the user free, since that should've been * done when those nodes were put back in the free list. * * @param h SFXHASH table pointer */ static void sfxhash_delete_free_list(SFXHASH *t) { SFXHASH_NODE *cur = NULL; SFXHASH_NODE *next = NULL; if (t == NULL || t->fhead == NULL) return; cur = t->fhead; while (cur != NULL) { next = cur->gnext; s_free(t, (void *)cur); cur = next; } t->fhead = NULL; t->ftail = NULL; t->anr_count = 0; } /*! * Delete the hash Table * * free key's, free node's, and free the users data. * * @param h SFXHASH table pointer * */ void sfxhash_delete( SFXHASH * h ) { unsigned i; SFXHASH_NODE * node, * onode; if( !h ) return; if( h->sfhashfcn ) sfhashfcn_free( h->sfhashfcn ); if( h->table ) { for(i=0;inrows;i++) { for( node=h->table[i]; node; ) { onode = node; node = node->next; /* Notify user that we are about to free this node function */ if( h->usrfree ) h->usrfree( onode->key, onode->data ); s_free( h,onode ); } } s_free( h, h->table ); h->table = 0; } sfxhash_delete_free_list( h ); free( h ); /* free the table from general memory */ } /*! * Empty out the hash table * * @param h SFXHASH table pointer * * @return -1 on error */ int sfxhash_make_empty(SFXHASH *h) { SFXHASH_NODE *n = NULL; SFXHASH_NODE *tmp = NULL; unsigned i; if (h == NULL) return -1; for (i = 0; i < h->nrows; i++) { for (n = h->table[i]; n != NULL; n = tmp) { tmp = n->next; if (sfxhash_free_node(h, n) != SFXHASH_OK) { return -1; } } } h->max_nodes = 0; h->crow = 0; h->cnode = NULL; h->count = 0; h->ghead = NULL; h->gtail = NULL; h->anr_count = 0; h->anr_tries = 0; h->find_success = 0; h->find_fail = 0; return 0; } /** Save the freed node for later use (recylcing). * Free List - uses the NODE gnext/gprev fields */ static void sfxhash_save_free_node( SFXHASH *t, SFXHASH_NODE * hnode ) { /* Add A Node to the Free Node List */ if( t->fhead ) /* add the node to head of the the existing list */ { hnode->gprev = 0; hnode->gnext = t->fhead; t->fhead->gprev = hnode; t->fhead = hnode; /* tail is not affected */ } else /* 1st node in this list */ { hnode->gprev = 0; hnode->gnext = 0; t->fhead = hnode; t->ftail = hnode; } t->anr_count++; } /**Get a previously freed node for reuse. */ static SFXHASH_NODE * sfxhash_get_free_node( SFXHASH *t ) { SFXHASH_NODE * node = t->fhead; /* Remove A Node from the Free Node List - remove the head node */ if( node ) { t->fhead = node->gnext; if( t->fhead ) t->fhead->gprev = 0; if( t->ftail == node ) /* no more nodes - clear the tail */ t->ftail = 0; t->anr_count--; } return node; } static void sfxhash_glink_node( SFXHASH *t, SFXHASH_NODE * hnode ) { /* Add The Node */ if( t->ghead ) /* add the node to head of the the existing list */ { hnode->gprev = 0; hnode->gnext = t->ghead; t->ghead->gprev = hnode; t->ghead = hnode; /* tail is not affected */ } else /* 1st node in this list */ { hnode->gprev = 0; hnode->gnext = 0; t->ghead = hnode; t->gtail = hnode; } } static void sfxhash_gunlink_node( SFXHASH *t, SFXHASH_NODE * hnode ) { if( t->gnode == hnode ) /* if this was the global next node */ { t->gnode = hnode->gnext; } /* Remove the Head Node */ if( t->ghead == hnode ) /* add the node to head of the the existing list */ { t->ghead = t->ghead->gnext; if( t->ghead ) t->ghead->gprev = 0; } if( hnode->gprev ) hnode->gprev->gnext = hnode->gnext; if( hnode->gnext ) hnode->gnext->gprev = hnode->gprev; if( t->gtail == hnode ) t->gtail = hnode->gprev; } /**Move node to the front of global list. Node movement is application specific. */ void sfxhash_gmovetofront( SFXHASH *t, SFXHASH_NODE * hnode ) { if( hnode != t->ghead ) { sfxhash_gunlink_node( t, hnode ); sfxhash_glink_node( t, hnode ); } } /* * */ static void sfxhash_link_node( SFXHASH * t, SFXHASH_NODE * hnode ) { /* Add The Node to the Hash Table Row List */ if( t->table[hnode->rindex] ) /* add the node to the existing list */ { hnode->prev = 0; // insert node as head node hnode->next=t->table[hnode->rindex]; t->table[hnode->rindex]->prev = hnode; t->table[hnode->rindex] = hnode; } else /* 1st node in this list */ { hnode->prev=0; hnode->next=0; t->table[hnode->rindex] = hnode; } } static void sfxhash_unlink_node( SFXHASH * t, SFXHASH_NODE * hnode ) { if( hnode->prev ) // definitely not the 1st node in the list { hnode->prev->next = hnode->next; if( hnode->next ) hnode->next->prev = hnode->prev; } else if( t->table[hnode->rindex] ) // must be the 1st node in the list { t->table[hnode->rindex] = t->table[hnode->rindex]->next; if( t->table[hnode->rindex] ) t->table[hnode->rindex]->prev = 0; } } /* * move a node to the front of the row list at row = 'index' */ static void movetofront( SFXHASH *t, SFXHASH_NODE * n ) { /* Modify Hash Node Row List */ if( t->table[n->rindex] != n ) // if not at front of list already... { /* Unlink the node */ sfxhash_unlink_node( t, n ); /* Link at front of list */ sfxhash_link_node( t, n ); } /* Move node in the global hash node list to the front */ if (n == t->gnode) t->gnode = n->gnext; sfxhash_gmovetofront( t, n ); } /* * Allocat a new hash node, uses Auto Node Recovery if needed and enabled. * * The oldest node is the one with the longest time since it was last touched, * and does not have any direct indication of how long the node has been around. * We don't monitor the actual time since last being touched, instead we use a * splayed global list of node pointers. As nodes are accessed they are splayed * to the front of the list. The oldest node is just the tail node. * */ static SFXHASH_NODE * sfxhash_newnode( SFXHASH * t ) { SFXHASH_NODE * hnode; /* Recycle Old Nodes - if any */ hnode = sfxhash_get_free_node( t ); /* Allocate memory for a node */ if( ! hnode ) { if ((t->max_nodes == 0) || (t->count < t->max_nodes)) { hnode = (SFXHASH_NODE*)s_alloc( t, sizeof(SFXHASH_NODE) + t->pad + t->keysize + t->datasize ); } } /* If we still haven't found hnode, we're at our memory limit. * * Uses Automatic Node Recovery, to recycle the oldest node-based on access * (Unlink and reuse the tail node) */ if( !hnode && t->anr_flag && t->gtail ) { /* Find the oldes node the users willing to let go. */ for(hnode = t->gtail; hnode; hnode = hnode->gprev ) { if( t->anrfree ) /* User has provided a permission+release callback function */ { t->anr_tries++;/* Count # ANR requests */ /* Ask the user for permission to release this node, but let them say no! */ if( t->anrfree( hnode->key, hnode->data ) ) { /* NO, don't recycle this node, user's not ready to let it go. */ continue; } /* YES, user said we can recycle this node */ } sfxhash_gunlink_node( t, hnode ); /* unlink from the global list */ sfxhash_unlink_node( t, hnode ); /* unlink from the row list */ t->count--; t->anr_count++; /* count # of ANR operations */ break; } } /* either we are returning a node or we're all full and the user * won't let us allocate anymore and we return NULL */ return hnode; } /* * * Find a Node based on the key, return the node and the index. * The index is valid even if the return value is NULL, in which * case the index is the corect row in which the node should be * created. * */ #define hashsize(n) ((uint32_t)1<<(n)) #define hashmask(n) (hashsize(n)-1) static SFXHASH_NODE * sfxhash_find_node_row( SFXHASH * t, const void * key, int * rindex ) { unsigned hashkey; int index; SFXHASH_NODE *hnode; hashkey = t->sfhashfcn->hash_fcn( t->sfhashfcn, (unsigned char*)key, t->keysize ); /* printf("hashkey: %u t->keysize: %d\n", hashkey, t->keysize); */ /* flowkey_fprint(stdout, key); */ /* printf("****\n"); */ // index = hashkey % t->nrows; /* Modulus is slow. Switched to a table size that is a power of 2. */ index = hashkey & (t->nrows - 1); *rindex = index; for( hnode=t->table[index]; hnode; hnode=hnode->next ) { if( !t->sfhashfcn->keycmp_fcn(hnode->key,key,t->keysize) ) { if( t->splay > 0 ) movetofront(t,hnode); t->find_success++; return hnode; } } t->find_fail++; return NULL; } /*! * Add a key + data pair to the hash table * * 2003-06-06: * - unique_tracker.c assumes that this splays * nodes to the top when they are added. * * This is done because of the successful find. * * @param t SFXHASH table pointer * @param key users key pointer * @param data users data pointer * * @return integer * @retval SFXHASH_OK success * @retval SFXHASH_INTABLE already in the table, t->cnode points to the node * @retval SFXHASH_NOMEM not enough memory */ static int sfxhash_add_ex( SFXHASH * t, const void * key, void* data , void **data_ptr) { int index; SFXHASH_NODE * hnode; /* Enforce uniqueness: Check for the key in the table */ hnode = sfxhash_find_node_row( t, key, &index ); if( hnode ) { t->cnode = hnode; if (data_ptr) *data_ptr = hnode->data; return SFXHASH_INTABLE; /* found it - return it. */ } /* * Alloc new hash node - allocate key space and data space at the same time. */ hnode = sfxhash_newnode( t ); if( !hnode ) { return SFXHASH_NOMEM; } /* Set up the new key pointer */ hnode->key = (char*)hnode + sizeof(SFXHASH_NODE); /* Copy the key */ memcpy(hnode->key,key,t->keysize); /* Save our table row index */ hnode->rindex = index; /* Copy the users data - or if datasize is zero set ptr to users data */ if( t->datasize ) { /* Set up the new data pointer */ hnode->data= (char*)hnode + sizeof(SFXHASH_NODE) + t->pad + t->keysize; if(data) { memcpy(hnode->data,data,t->datasize); } if (data_ptr) *data_ptr = hnode->data; } else { hnode->data = data; } /* Link the node into the table row list */ sfxhash_link_node ( t, hnode ); /* Link at the front of the global node list */ sfxhash_glink_node( t, hnode ); /* Track # active nodes */ t->count++; t->cnode = hnode; return SFXHASH_OK; } int sfxhash_add( SFXHASH * t, void * key, void * data) { return sfxhash_add_ex( t, key, data , NULL); } /*! * Add a key to the hash table, return the hash node * * 2003-06-06: * - unique_tracker.c assumes that this splays * nodes to the top when they are added. * * This is done because of the successful find. * * @param t SFXHASH table pointer * @param key users key pointer * * @return integer * @retval SFXHASH_OK success * @retval SFXHASH_INTABLE already in the table, t->cnode points to the node * @retval SFXHASH_NOMEM not enough memory */ SFXHASH_NODE * sfxhash_get_node( SFXHASH * t, const void * key ) { int index; SFXHASH_NODE * hnode; /* Enforce uniqueness: Check for the key in the table */ hnode = sfxhash_find_node_row( t, key, &index ); if( hnode ) { t->cnode = hnode; return hnode; /* found it - return it. */ } /* * Alloc new hash node - allocate key space and data space at the same time. */ hnode = sfxhash_newnode( t ); if( !hnode ) { return NULL; } /* Set up the new key pointer */ hnode->key = (char*)hnode + sizeof(SFXHASH_NODE); /* Copy the key */ memcpy(hnode->key,key,t->keysize); /* Save our table row index */ hnode->rindex = index; /* Copy the users data - or if datasize is zero set ptr to users data */ if( t->datasize ) { /* Set up the new data pointer */ hnode->data = (char*)hnode + sizeof(SFXHASH_NODE) + t->pad + t->keysize; } else { hnode->data = NULL; } /* Link the node into the table row list */ sfxhash_link_node ( t, hnode ); /* Link at the front of the global node list */ sfxhash_glink_node( t, hnode ); /* Track # active nodes */ t->count++; return hnode; } /*! * Find a Node based on the key * * @param t SFXHASH table pointer * @param key users key pointer * * @return SFXHASH_NODE* valid pointer to the hash node * @retval 0 node not found * */ SFXHASH_NODE * sfxhash_find_node( SFXHASH * t, const void * key) { int rindex; return sfxhash_find_node_row( t, key, &rindex ); } /*! * Find the users data based associated with the key * * @param t SFXHASH table pointer * @param key users key pointer * * @return void* valid pointer to the users data * @retval 0 node not found * */ void * sfxhash_find( SFXHASH * t, void * key) { SFXHASH_NODE * hnode; int rindex; hnode = sfxhash_find_node_row( t, key, &rindex ); if( hnode ) return hnode->data; return NULL; } /** * Get the HEAD of the in use list * * @param t table pointer * * @return the head of the list or NULL */ SFXHASH_NODE *sfxhash_ghead( SFXHASH * t ) { if(t) { return t->ghead; } return NULL; } /** * Walk the global list * * @param n current node * * @return the next node in the list or NULL when at the end */ SFXHASH_NODE *sfxhash_gnext( SFXHASH_NODE *n ) { if(n) { return n->gnext; } return NULL; } /** * Walk the global list * * @param n current node * * @return the next node in the list or NULL when at the end */ SFXHASH_NODE *sfxhash_gfindnext( SFXHASH * t ) { SFXHASH_NODE *n; n = t->gnode; if (n) t->gnode = n->gnext; return n; } /** * Get the HEAD of the in use list * * @param t table pointer * * @return the head of the list or NULL */ SFXHASH_NODE *sfxhash_gfindfirst( SFXHASH * t ) { if(t) { if (t->ghead) t->gnode = t->ghead->gnext; else t->gnode = NULL; return t->ghead; } return NULL; } /*! * Return the most recently used data from the global list * * @param t SFXHASH table pointer * * @return void* valid pointer to the users data * @retval 0 node not found * */ void * sfxhash_mru( SFXHASH * t ) { SFXHASH_NODE * hnode; hnode = sfxhash_ghead(t); if( hnode ) return hnode->data; return NULL; } /*! * Return the least recently used data from the global list * * @param t SFXHASH table pointer * * @return void* valid pointer to the users data * @retval 0 node not found * */ void * sfxhash_lru( SFXHASH * t ) { SFXHASH_NODE * hnode; hnode = t->gtail; if( hnode ) return hnode->data; return NULL; } /*! * Return the most recently used node from the global list * * @param t SFXHASH table pointer * * @return SFXHASH_NODE* valid pointer to a node * @retval 0 node not found * */ SFXHASH_NODE * sfxhash_mru_node( SFXHASH * t ) { SFXHASH_NODE * hnode; hnode = sfxhash_ghead(t); if( hnode ) return hnode; return NULL; } /*! * Return the least recently used node from the global list * * @param t SFXHASH table pointer * * @return SFXHASH_NODE* valid pointer to a node * @retval 0 node not found * */ SFXHASH_NODE * sfxhash_lru_node( SFXHASH * t ) { SFXHASH_NODE * hnode; hnode = t->gtail; if( hnode ) return hnode; return NULL; } /*! * Get some hash table statistics. NOT FOR REAL TIME USE. * * * @param t SFXHASH table pointer * @param filled how many * * @return max depth of the table * */ unsigned sfxhash_maxdepth( SFXHASH * t ) { unsigned i; unsigned max_depth = 0; SFXHASH_NODE * hnode; for( i=0; inrows; i++ ) { unsigned cur_depth = 0; for(hnode = t->table[i]; hnode != NULL; hnode = hnode->next) { cur_depth++; } if(cur_depth > max_depth) max_depth = cur_depth; } return max_depth; } /* * Unlink and free the node */ int sfxhash_free_node( SFXHASH * t, SFXHASH_NODE * hnode) { sfxhash_unlink_node( t, hnode ); /* unlink from the hash table row list */ sfxhash_gunlink_node( t, hnode ); /* unlink from global-hash-node list */ t->count--; if( t->usrfree ) { t->usrfree( hnode->key, hnode->data); } if( t->recycle_nodes ) { sfxhash_save_free_node( t, hnode ); } else { s_free( t, hnode ); } return SFXHASH_OK; } /* * Unlink and free an ANR node or the oldest node, if ANR is empty * behavior is undefined if t->usrfree is set */ int sfxhash_free_anr_lru( SFXHASH * t ) { if (!t) return SFXHASH_ERR; if (t->fhead) { SFXHASH_NODE* fn = sfxhash_get_free_node(t); if (fn) { s_free(t, fn); return SFXHASH_OK; } } if (t->gtail) { if (SFXHASH_OK == sfxhash_free_node(t, t->gtail)) { if (t->fhead) { SFXHASH_NODE* fn = sfxhash_get_free_node(t); if (fn) { s_free(t, fn); return SFXHASH_OK; } } //sfxhash_free_node calls s_free for us //when these conditions are met so we should //return SFXHASH_OK else if (!t->recycle_nodes) { return SFXHASH_OK; } } } return SFXHASH_ERR; } /* * Unlink and free an ANR node */ int sfxhash_free_anr( SFXHASH * t ) { if (!t) return SFXHASH_ERR; if (t->fhead) { SFXHASH_NODE* fn = sfxhash_get_free_node(t); if (fn) { s_free(t, fn); return SFXHASH_OK; } } return SFXHASH_ERR; } /*! * Remove a Key + Data Pair from the table. * * @param t SFXHASH table pointer * @param key users key pointer * * @return 0 success * @retval !0 failed * */ int sfxhash_remove( SFXHASH * t, void * key) { SFXHASH_NODE * hnode; unsigned hashkey, index; hashkey = t->sfhashfcn->hash_fcn( t->sfhashfcn, (unsigned char*)key, t->keysize ); // index = hashkey % t->nrows; /* Modulus is slow */ index = hashkey & (t->nrows - 1); hnode = t->table[index]; for( hnode=t->table[index]; hnode; hnode=hnode->next ) { if( !t->sfhashfcn->keycmp_fcn(hnode->key,key,t->keysize) ) { return sfxhash_free_node( t, hnode ); } } return SFXHASH_ERR; } /* Internal use only */ static void sfxhash_next( SFXHASH * t ) { if( !t->cnode ) return ; /* Next node in current node list */ t->cnode = t->cnode->next; if( t->cnode ) { return; } /* Next row */ /* Get 1st node in next non-emtoy row/node list */ for( t->crow++; t->crow < t->nrows; t->crow++ ) { t->cnode = t->table[ t->crow ]; if( t->cnode ) { return; } } } /*! * Find and return the first hash table node * * @param t SFXHASH table pointer * * @return 0 failed * @retval !0 valid SFXHASH_NODE * * */ SFXHASH_NODE * sfxhash_findfirst( SFXHASH * t ) { SFXHASH_NODE * n; if(!t) return NULL; /* Start with 1st row */ for( t->crow=0; t->crow < t->nrows; t->crow++ ) { /* Get 1st Non-Null node in row list */ t->cnode = t->table[ t->crow ]; if( t->cnode ) { n = t->cnode; sfxhash_next( t ); // load t->cnode with the next entry return n; } } return NULL; } /*! * Find and return the next hash table node * * @param t SFXHASH table pointer * * @return 0 failed * @retval !0 valid SFXHASH_NODE * * */ SFXHASH_NODE * sfxhash_findnext( SFXHASH * t ) { SFXHASH_NODE * n; n = t->cnode; if( !n ) /* Done, no more entries */ { return NULL; } /* Preload next node into current node */ sfxhash_next( t ); return n; } /** * Make sfhashfcn use a separate set of operators for the backend. * * @param h sfhashfcn ptr * @param hash_fcn user specified hash function * @param keycmp_fcn user specified key comparisoin function */ int sfxhash_set_keyops( SFXHASH *h , unsigned (*hash_fcn)( SFHASHFCN * p, unsigned char *d, int n), int (*keycmp_fcn)( const void *s1, const void *s2, size_t n)) { if(h && hash_fcn && keycmp_fcn) { return sfhashfcn_set_keyops(h->sfhashfcn, hash_fcn, keycmp_fcn); } return -1; } int sfxhash_add_return_data_ptr( SFXHASH * t, const void * key, void **data ) { if( !t->datasize ) return SFXHASH_ERR; *data = NULL; return sfxhash_add_ex(t, key, NULL, data); } /* * Calculate memcap size based on number of entries and per-entry cost * * @param num_entries number of entries * @param entry_cost cost of a single entry * * @return memcap size */ unsigned sfxhash_calc_maxmem(unsigned num_entries, unsigned entry_cost) { return num_entries * (entry_cost + sizeof(SFXHASH_NODE) + sizeof(long)); } /* * Try to decrease the memcap * First decrease memcap, then delete free list, then kick out lru nodes * Behavior is undefined when t->usrfree is set * * @param t SFXHASH table pointer * @param new_memcap the new desired memcap * @param max_work the maximum amount of work for the function to do (0 = do all available work) * * @return SFXHASH_OK when memcap is successfully decreased * @return SFXHASH_PENDING when more work needs to be done * @return SFXHASH_NOMEM when there isn't enough memory in the hash table * #return SFXHASH_ERR when an error has occurred */ int sfxhash_change_memcap( SFXHASH * t, unsigned long new_memcap, unsigned *max_work ) { unsigned work = 0; if (!t) return SFXHASH_ERR; if (new_memcap == t->mc.memcap) { return SFXHASH_OK; } if (new_memcap > t->mc.memcap) { t->mc.memcap = new_memcap; return SFXHASH_OK; } //memcap decreased if (new_memcap < t->overhead_bytes) return SFXHASH_ERR; while (new_memcap < t->mc.memused && (work < *max_work || *max_work == 0) && sfxhash_free_anr_lru(t) == SFXHASH_OK) work++; if (work == *max_work && new_memcap < t->mc.memused) { *max_work -= work; return SFXHASH_PENDING; } *max_work -= work; //else mem decrased or we ran out of work (no more nodes to free) //we ran out of nodes to free and there still isnt enough memory //or (we have undefined behavior: t->usrfree is set and sfxhash_free_anr_lru is returning SFXHASH_ERR) if (new_memcap < t->mc.memused) return SFXHASH_NOMEM; t->mc.memcap = new_memcap; return SFXHASH_OK; } /* * ----------------------------------------------------------------------------------------- * Test Driver for Hashing * ----------------------------------------------------------------------------------------- */ #ifdef SFXHASH_MAIN /* This is called when the user releases a node or kills the table */ int usrfree( void * key, void * data ) { /* Release any data you need to */ return 0; } /* Auto Node Recovery Callback - optional This is called to ask the user to kill a node, if it reutrns !0 than the hash library does not kill this node. If the user os willing to let the node die, the user must do any free'ing or clean up on the node during this call. */ int anrfree( void * key, void * data ) { static int bx = 0; /* Decide if we can free this node. */ //bx++; if(bx == 4 )bx=0; /* for testing */ /* if we are allowing the node to die, kill it */ if( !bx ) usrfree( key, data ); return bx; /* Allow the caller to kill this nodes data + key */ } /* * Hash test program : use 'sfxhash 1000 50000' to stress the Auto_NodeRecover feature */ int main ( int argc, char ** argv ) { int i; SFXHASH * t; SFXHASH_NODE * n; char strkey[256], strdata[256], * p; int num = 100; int mem = 0; memset(strkey,0,20); memset(strdata,0,20); if( argc > 1 ) { num = atoi(argv[1]); } if( argc > 2 ) { mem = atoi(argv[2]); } /* Create a Hash Table */ t = sfxhash_new( 100, /* one row per element in table, when possible */ 20, /* key size : padded with zeros */ 20, /* data size: padded with zeros */ mem, /* max bytes, 0=no max */ 1, /* enable AutoNodeRecovery */ anrfree, /* provide a function to let user know we want to kill a node */ usrfree, /* provide a function to release user memory */ 1); /* Recycle nodes */ if(!t) { printf("Low Memory!\n"); exit(0); } /* Add Nodes to the Hash Table */ for(i=0;imc); printf("...******\n"); /* Display All Nodes in the Hash Table findfirst/findnext */ printf("\n...FINDFIRST / FINDNEXT TEST\n"); for( n = sfxhash_findfirst(t); n != 0; n = sfxhash_findnext(t) ) { printf("hash-findfirst/next: n=%x, key=%s, data=%s\n", n, n->key, n->data ); /* remove node we are looking at, this is first/next safe. */ if( sfxhash_remove(t,n->key) ) { printf("...ERROR: Could not remove the key node!\n"); } else { printf("...key node removed\n"); } } printf("...Auto-Node-Recovery: %d recycle attempts, %d completions.\n",t->anr_tries,t->anr_count); /* Free the table and it's user data */ printf("...sfxhash_delete\n"); sfxhash_delete( t ); printf("\nnormal pgm finish\n\n"); return 0; } #endif /**@}*/ snort-2.9.15.1/src/sfutil/sfxhash.h0000644000175200017520000001702313571422607013765 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2003-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* * * sfxhash.h * * generic hash table - stores and maps key + data pairs * (supports memcap and automatic memory recovery when out of memory) * * Author: Marc Norton * */ #ifndef _SFXHASH_ #define _SFXHASH_ #include #include #include #include "sfmemcap.h" #include "sfhashfcn.h" /* * ERROR DEFINES */ #define SFXHASH_NOMEM -2 #define SFXHASH_ERR -1 #define SFXHASH_OK 0 #define SFXHASH_INTABLE 1 #define SFXHASH_PENDING 2 /** * HASH NODE */ typedef struct _sfxhash_node { struct _sfxhash_node * gnext, * gprev; /// global node list - used for ageing nodes struct _sfxhash_node * next, * prev; /// row node list int rindex; /// row index of table this node belongs to. void * key; /// Pointer to the key. void * data; /// Pointer to the users data, this is not copied ! } SFXHASH_NODE; typedef int (*SFXHASH_FREE_FCN)( void * key, void * data ); /** * SFGX HASH Table */ typedef struct _sfxhash { SFHASHFCN * sfhashfcn; /// hash function int keysize; /// bytes in key, if <= 0 -> keys are strings int datasize; /// bytes in key, if == 0 -> user data SFXHASH_NODE ** table; /// array of node ptr's */ unsigned nrows; /// # rows int the hash table use a prime number 211, 9871 unsigned count; /// total # nodes in table unsigned crow; /// findfirst/next row in table unsigned pad; SFXHASH_NODE * cnode; /// findfirst/next node ptr int splay; /// whether to splay nodes with same hash bucket unsigned max_nodes; ///maximum # of nodes within a hash MEMCAP mc; unsigned overhead_bytes; /// # of bytes that will be unavailable for nodes inside the table unsigned overhead_blocks; /// # of blocks consumed by the table unsigned find_fail; unsigned find_success; SFXHASH_NODE * ghead, * gtail; /// global - root of all nodes allocated in table SFXHASH_NODE * fhead, * ftail; /// list of free nodes, which are recyled SFXHASH_NODE * gnode; /* gfirst/gnext node ptr */ int recycle_nodes; /// recycle nodes. Nodes are not freed, but are used for subsequent new nodes /**Automatic Node Recover (ANR): When number of nodes in hash is equal to max_nodes, remove the least recently * used nodes and use it for the new node. anr_tries indicates # of ANR tries.*/ unsigned anr_tries; unsigned anr_count; /// # ANR ops performaed int anr_flag; /// 0=off, !0=on unsigned free_count; /// total # nodes in table SFXHASH_FREE_FCN anrfree; SFXHASH_FREE_FCN usrfree; } SFXHASH; /* * HASH PROTOTYPES */ int sfxhash_calcrows(int num); SFXHASH * sfxhash_new( unsigned nrows, int keysize, int datasize, unsigned long memcap, int anr_flag, SFXHASH_FREE_FCN anrfunc, SFXHASH_FREE_FCN usrfunc, int recycle_flag ); void sfxhash_set_max_nodes( SFXHASH *h, int max_nodes ); void sfxhash_delete( SFXHASH * h ); int sfxhash_make_empty(SFXHASH *); int sfxhash_add ( SFXHASH * h, void * key, void * data ); SFXHASH_NODE * sfxhash_get_node( SFXHASH * t, const void * key ); int sfxhash_remove( SFXHASH * h, void * key ); /*! * Get the # of Nodes in HASH the table * * @param t SFXHASH table pointer * */ static inline unsigned sfxhash_count( SFXHASH * t ) { return t->count; } /*! * Get the # of Nodes in HASH the table * * @param t SFXHASH table pointer * */ static inline unsigned sfxhash_total_count( SFXHASH * t ) { return t->count + t->anr_count; } /*! * Get the # auto recovery * * @param t SFXHASH table pointer * */ static inline unsigned sfxhash_anr_count( SFXHASH * t ) { return t->anr_count; } /*! * Get the # finds * * @param t SFXHASH table pointer * */ static inline unsigned sfxhash_find_total( SFXHASH * t ) { return t->find_success + t->find_fail; } /*! * Get the # unsucessful finds * * @param t SFXHASH table pointer * */ static inline unsigned sfxhash_find_fail( SFXHASH * t ) { return t->find_fail; } /*! * Get the # sucessful finds * * @param t SFXHASH table pointer * */ static inline unsigned sfxhash_find_success( SFXHASH * t ) { return t->find_success; } /*! * Get the # of overhead bytes * * @param t SFXHASH table pointer * */ static inline unsigned sfxhash_overhead_bytes( SFXHASH * t ) { return t->overhead_bytes; } /*! * Get the # of overhead blocks * * @param t SFXHASH table pointer * */ static inline unsigned sfxhash_overhead_blocks( SFXHASH * t ) { return t->overhead_blocks; } void * sfxhash_mru( SFXHASH * t ); void * sfxhash_lru( SFXHASH * t ); SFXHASH_NODE * sfxhash_mru_node( SFXHASH * t ); SFXHASH_NODE * sfxhash_lru_node( SFXHASH * t ); void * sfxhash_find( SFXHASH * h, void * key ); SFXHASH_NODE * sfxhash_find_node( SFXHASH * t, const void * key); SFXHASH_NODE * sfxhash_findfirst( SFXHASH * h ); SFXHASH_NODE * sfxhash_findnext ( SFXHASH * h ); SFXHASH_NODE * sfxhash_ghead( SFXHASH * h ); SFXHASH_NODE * sfxhash_gnext( SFXHASH_NODE * n ); void sfxhash_gmovetofront( SFXHASH *t, SFXHASH_NODE * hnode ); void sfxhash_splaymode( SFXHASH * h, int mode ); void * sfxhash_alloc( SFXHASH * t, unsigned nbytes ); void sfxhash_free( SFXHASH * t, void * p ); int sfxhash_free_node(SFXHASH *t, SFXHASH_NODE *node); /* sfxhash_free_anr_lru frees a node from the free list or the LRU node */ int sfxhash_free_anr_lru(SFXHASH *t); /* sfxhash_free_anr frees a node from the free list */ int sfxhash_free_anr(SFXHASH *t); unsigned sfxhash_maxdepth( SFXHASH * t ); int sfxhash_set_keyops( SFXHASH *h , unsigned (*hash_fcn)( SFHASHFCN * p, unsigned char *d, int n), int (*keycmp_fcn)( const void *s1, const void *s2, size_t n)); SFXHASH_NODE *sfxhash_gfindfirst( SFXHASH * t ); SFXHASH_NODE *sfxhash_gfindnext( SFXHASH * t ); int sfxhash_add_return_data_ptr( SFXHASH * t, const void * key, void **data ); unsigned sfxhash_calc_maxmem(unsigned num_entries, unsigned entry_cost); int sfxhash_change_memcap( SFXHASH * t, unsigned long new_memcap, unsigned *max_work ); #endif snort-2.9.15.1/src/sfutil/ipobj.c0000644000175200017520000003717613571422607013432 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2003-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* ipobj.c IP address encapsulation interface This module provides encapsulation of single IP ADDRESSes as objects, and collections of IP ADDRESSes as objects */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifndef WIN32 #include #include #include #include #endif #include #include "ipobj.h" #include "util.h" #include "snort_bounds.h" /* IP COLLECTION INTERFACE Snort Accepts: IP-Address 192.168.1.1 IP-Address/MaskBits 192.168.1.0/24 IP-Address/Mask 192.168.1.0/255.255.255.0 These can all be handled via the CIDR block notation : IP/MaskBits We use collections (lists) of cidr blocks to represent address blocks and indivdual addresses. For a single IPAddress the implied Mask is 32 bits,or 255.255.255.255, or 0xffffffff, or -1. */ IPSET * ipset_new(void) { IPSET * p = (IPSET *)SnortAlloc( sizeof(IPSET)); sflist_init(&p->ip_list); return p; } IPSET * ipset_copy( IPSET *ipsp ) { IPSET * newset = ipset_new(); IP_PORT *ip_port; for(ip_port =(IP_PORT*)sflist_first( &ipsp->ip_list ); ip_port !=NULL; ip_port =(IP_PORT*)sflist_next( &ipsp->ip_list ) ) { ipset_add(newset, &ip_port->ip, &ip_port->portset, ip_port->notflag); } return newset; } void ipset_free( IPSET * ipc ) { if (ipc) { IP_PORT *p = (IP_PORT *) sflist_first(&ipc->ip_list); while ( p ) { sflist_static_free_all(&p->portset.port_list, free); p = (IP_PORT *) sflist_next(&ipc->ip_list); } sflist_static_free_all(&ipc->ip_list, free); free( ipc ); } } int ipset_add ( IPSET * ipset, sfcidr_t *ip, void * vport, int notflag) { if( !ipset ) return -1; { PORTSET * portset = (PORTSET *) vport; IP_PORT *p = (IP_PORT*)calloc( 1,sizeof(IP_PORT) ); if(!p) return -1; sfip_set_ip(&p->ip, ip); p->portset = *portset; p->notflag = (char)notflag; if( notflag )sflist_add_head( &ipset->ip_list, p ); // test NOT items 1st else sflist_add_tail( &ipset->ip_list, p ); } return 0; } int ipset_contains( IPSET * ipc, sfaddr_t * ip, void *port) { PORTRANGE *pr; unsigned short portu; IP_PORT * p; if( !ipc ) return 0; if ( port ) portu = *((unsigned short *)port); else portu = 0; for(p =(IP_PORT*)sflist_first( &ipc->ip_list ); p!=0; p =(IP_PORT*)sflist_next( &ipc->ip_list ) ) { if( sfip_contains(&p->ip, ip) == SFIP_CONTAINS) { for( pr=(PORTRANGE*)sflist_first(&p->portset.port_list); pr != 0; pr=(PORTRANGE*)sflist_next(&p->portset.port_list) ) { /* * If the matching IP has a wildcard port (pr->port_hi == 0 ) * or if the ports actually match. */ if ( (pr->port_hi == 0) || (portu >= pr->port_lo && portu <= pr->port_hi) ) { if( p->notflag ) return 0; return 1; } } } } return 0; } int ipset_print( IPSET * ipc ) { char ip_str[80]; PORTRANGE * pr; if( !ipc ) return 0; { IP_PORT * p; printf("IPSET\n"); for( p =(IP_PORT*)sflist_first( &ipc->ip_list ); p!=0; p =(IP_PORT*)sflist_next( &ipc->ip_list ) ) { SnortSnprintf(ip_str, 80, "%s", sfip_to_str(&p->ip.addr)); printf("CIDR BLOCK: %c%s", p->notflag ? '!' : ' ', ip_str); for( pr=(PORTRANGE*)sflist_first(&p->portset.port_list); pr != 0; pr=(PORTRANGE*)sflist_next(&p->portset.port_list) ) { printf(" %d", pr->port_lo); if ( pr->port_hi != pr->port_lo ) printf("-%d", pr->port_hi); } printf("\n"); } } return 0; } static void portset_init( PORTSET * portset ) { sflist_init(&portset->port_list); } static int portset_add(PORTSET * portset, unsigned port_lo, unsigned port_hi) { PORTRANGE *p; if( !portset ) return -1; p = (PORTRANGE *) calloc( 1,sizeof(PORTRANGE) ); if(!p) return -1; p->port_lo = port_lo; p->port_hi = port_hi; sflist_add_tail(&portset->port_list, p ); return 0; } static int port_parse(char *portstr, PORTSET *portset) { unsigned port_lo = 0, port_hi = 0; char *port1; char *port_begin; char *port_end; char *port2 = NULL; port_begin = SnortStrdup(portstr); port1 = port_begin; port2 = strstr(port_begin, "-"); { if (*port1 == '\0') { free(port_begin); return -1; } if (port2) { *port2 = '\0'; port2++; } port_lo = strtoul(port1, &port_end, 10); if (port_end == port1) { free(port_begin); return -2; } if (port2) { port_hi = strtoul(port2, &port_end, 10); if (port_end == port2) { free(port_begin); return -3; } } else { port_hi = port_lo; } /* check to see if port is out of range */ if ( port_hi > MAXPORTS-1 || port_lo > MAXPORTS-1) { free(port_begin); return -4; } /* swap ports if necessary */ if (port_hi < port_lo) { unsigned tmp; tmp = port_hi; port_hi = port_lo; port_lo = tmp; } portset_add(portset, port_lo, port_hi); } free(port_begin); return 0; } static int ip_parse(char *ipstr, sfcidr_t *ip, char *not_flag, PORTSET *portset, char **endIP) { char *port_str; char *comma; char *end_bracket; if (*ipstr == '!') { ipstr++; *not_flag = 1; } else { *not_flag = 0; } comma = strchr(ipstr, ','); end_bracket = strrchr(ipstr, ']'); if (comma) { *comma = '\0'; } else if (end_bracket) { *end_bracket = '\0'; } if (sfip_pton(ipstr, ip) != SFIP_SUCCESS) return -1; /* Just to get the IP string out of the way */ port_str = strtok(ipstr, " \t"); /* Is either the port after the 1st space, or NULL */ port_str = strtok(NULL, " \t"); while (port_str) { if (!comma) { comma = strchr(port_str, ','); if (comma) *comma = '\0'; } if (!end_bracket) { end_bracket = strrchr(port_str, ']'); if (end_bracket) *end_bracket = '\0'; } port_parse(port_str, portset); port_str = strtok(NULL, " \t"); } if (portset->port_list.count == 0) { /* Make sure we have at least one port range in list, but * an invalid port range to convey all is good. */ portset_add(portset, 0, 0); } if (comma) { *endIP = comma; *comma = ','; } else if (end_bracket) { *end_bracket = ']'; *endIP = end_bracket; } else { /* Didn't see the comma or end bracket, so set endIP now */ *endIP = port_str; } return 0; } int ipset_parse(IPSET *ipset, char *ipstr) { char *copy, *startIP, *endIP; int parse_count = 0; char set_not_flag = 0; char item_not_flag; char open_bracket = 0; sfcidr_t ip; PORTSET portset; copy = strdup(ipstr); if(!copy) return -2; startIP = copy; if (*startIP == '!') { set_not_flag = 1; startIP++; } while (startIP) { if (*startIP == '[') { open_bracket++; startIP++; if (!*startIP) break; } if ((*startIP == ']') || (*startIP == '\0')) { open_bracket--; break; } portset_init(&portset); if(ip_parse(startIP, &ip, &item_not_flag, &portset, &endIP) != 0) { free(copy); return -5; } if(ipset_add(ipset, &ip, &portset, (item_not_flag ^ set_not_flag)) != 0) { free(copy); return -6; } parse_count++; if (endIP && (*endIP != ']')) { endIP++; } startIP = endIP; } free(copy); if (!parse_count) return -7; if (open_bracket) return -8; return 0; } #ifdef MAIN_IP #include #ifndef WIN32 #define rand random #define srand srandom #endif #define MAXIP 100 #include "sflsq.c" void test_ip4_parsing(void) { unsigned host, mask, not_flag; PORTSET portset; char **curip; int ret; IPADDRESS *adp; char *ips[] = { "138.26.1.24:25", "1.1.1.1/255.255.255.0:444", "1.1.1.1/16:25-28", "1.1.1.1/255.255.255.255:25 27-29", "z/24", "0/0", "0.0.0.0/0.0.0.0:25-26 28-29 31", "0.0.0.0/0.0.2.0", NULL }; for(curip = ips; curip[0] != NULL; curip++) { portset_init(&portset); /* network byte order stuff */ if((ret = ip4_parse(curip[0], 1, ¬_flag, &host, &mask, &portset)) != 0) { fprintf(stderr, "Unable to parse %s with ret %d\n", curip[0], ret); } else { printf("%c", not_flag ? '!' : ' '); printf("%s/", inet_ntoa(*(struct in_addr *) &host)); printf("%s", inet_ntoa(*(struct in_addr *) &mask)); printf(" parsed successfully!\n"); } /* host byte order stuff */ if((ret = ip4_parse(curip[0], 0, ¬_flag, &host, &mask, &portset)) != 0) { fprintf(stderr, "Unable to parse %s with ret %d\n", curip[0], ret); } else { adp = ip_new(IPV4_FAMILY); ip_set(adp, &host, IPV4_FAMILY); ip_fprint(stdout, adp); fprintf(stdout, "*****************\n"); ip_free(adp); } } return; } void test_ip4set_parsing(void) { char **curip; int ret; char *ips[] = { "12.24.24.1/32,!24.24.24.1", "[0.0.0.0/0.0.2.0,241.242.241.22]", "138.26.1.24", "1.1.1.1", "1.1.1.1/16", "1.1.1.1/255.255.255.255", "z/24", "0/0", "0.0.0.0/0.0.0.0", "0.0.0.0/0.0.2.0", NULL }; for(curip = ips; curip[0] != NULL; curip++) { IPSET *ipset = ipset_new(IPV4_FAMILY); /* network byte order stuff */ if((ret = ip4_setparse(ipset, curip[0])) != 0) { ipset_free(ipset); fprintf(stderr, "Unable to parse %s with ret %d\n", curip[0], ret); } else { printf("-[%s]\n ", curip[0]); ipset_print(ipset); printf("---------------------\n "); } } return; } // ----------------------------- void test_ip(void) { int i,k; IPADDRESS * ipa[MAXIP]; unsigned ipaddress,ipx; unsigned short ipaddress6[8], ipx6[8]; printf("IPADDRESS testing\n"); srand( time(0) ); for(i=0;i #include #include #include "sflsq.h" #include "ipv6_port.h" #ifdef WIN32 #define snprintf _snprintf #endif typedef struct { unsigned port_lo; unsigned port_hi; }PORTRANGE; typedef struct { SF_LIST port_list; }PORTSET; typedef struct { sfcidr_t ip; PORTSET portset; char notflag; } IP_PORT; typedef struct { SF_LIST ip_list; } IPSET; /* IP ADDRESS SET OBJECTS Snort Accepts: IP-Address 192.168.1.1 IP-Address/MaskBits 192.168.1.0/24 IP-Address/Mask 192.168.1.0/255.255.255.0 These can all be handled via the CIDR block notation : IP/MaskBits We use collections (lists) of cidr blocks to represent address blocks and indivdual addresses. For a single IPAddress the implied Mask is 32 bits,or 255.255.255.255, or 0xffffffff, or -1. */ IPSET * ipset_new (void); int ipset_add ( IPSET * ipset, sfcidr_t *ip, void * port, int notflag); int ipset_contains( IPSET * ipset, sfaddr_t *ip, void * port); IPSET * ipset_copy ( IPSET * ipset ); void ipset_free ( IPSET * ipset ); int ipset_print ( IPSET * ipset ); /* helper functions -- all the sets work in host order */ int ipset_parse(IPSET * ipset, char *ipstr); #endif snort-2.9.15.1/src/sfutil/getopt_long.c0000644000175200017520000006104213571422607014635 00000000000000/* Getopt for GNU. NOTE: getopt is now part of the C library, so if you don't know what "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu before changing it! Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it 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. */ /* This tells Alpha OSF/1 not to define a getopt prototype in . Ditto for AIX 3.2 and . */ #ifndef _NO_PROTO #define _NO_PROTO #endif #include #ifdef HAVE_CONFIG_H #if defined (emacs) || defined (CONFIG_BROKETS) /* We use instead of "config.h" so that a compilation using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h (which it would do because it found this file in $srcdir). */ #include #else #include "config.h" #endif #endif #ifndef __STDC__ /* This is a separate conditional since some stdc systems reject `defined (const)'. */ #ifndef const #define const #endif #endif #ifdef HAVE_STRING_H #include #endif /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #if defined (_LIBC) || !defined (__GNU_LIBRARY__) /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ /* Don't include stdlib.h for non-GNU C libraries because some of them contain conflicting prototypes for getopt. */ #include #endif /* GNU C library. */ /* This version of `getopt' appears to the caller like standard Unix `getopt' but it behaves differently for the user, since it allows the user to intersperse the options with the other arguments. As `getopt' works, it permutes the elements of ARGV so that, when it is done, all the options precede everything else. Thus all application programs are extended to handle flexible argument order. Setting the environment variable POSIXLY_CORRECT disables permutation. Then the behavior is completely standard. GNU application programs can use a third alternative mode in which they can distinguish the relative order of options and other arguments. */ #include "getopt1.h" /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ char *optarg = NULL; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns EOF, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ /* XXX 1003.2 says this must be 1 before any call. */ int optind = 0; /* The next char to be scanned in the option-element in which the last option character we returned was found. This allows us to pick up the scan where we left off. If this is zero, or a null string, it means resume the scan by advancing to the next ARGV-element. */ static char *nextchar; /* Callers store zero here to inhibit the error message for unrecognized options. */ int opterr = 1; /* Set to an option character which was unrecognized. This must be initialized on some systems to avoid linking in the system's own getopt implementation. */ int optopt = '?'; /* Describe how to deal with options that follow non-option ARGV-elements. If the caller did not specify anything, the default is REQUIRE_ORDER if the environment variable POSIXLY_CORRECT is defined, PERMUTE otherwise. REQUIRE_ORDER means don't recognize them as options; stop option processing when the first non-option is seen. This is what Unix does. This mode of operation is selected by either setting the environment variable POSIXLY_CORRECT, or using `+' as the first character of the list of option characters. PERMUTE is the default. We permute the contents of ARGV as we scan, so that eventually all the non-options are at the end. This allows options to be given in any order, even with programs that were not written to expect this. RETURN_IN_ORDER is an option available to programs that were written to expect options and other ARGV-elements in any order and that care about the ordering of the two. We describe each non-option ARGV-element as if it were the argument of an option with character code 1. Using `-' as the first character of the list of option characters selects this mode of operation. The special argument `--' forces an end of option-scanning regardless of the value of `ordering'. In the case of RETURN_IN_ORDER, only `--' can cause `getopt' to return EOF with `optind' != ARGC. */ static enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering; /* Value of POSIXLY_CORRECT environment variable. */ static char *posixly_correct; #ifdef __GNU_LIBRARY__ /* We want to avoid inclusion of string.h with non-GNU libraries because there are many ways it can cause trouble. On some systems, it contains special magic macros that don't work in GCC. */ #include #define my_index strchr #else /* Avoid depending on library functions or files whose names are inconsistent. */ #if !defined(_WIN32) char *getenv (); #endif static char * my_index (const char *str, int chr) { while (*str) { if (*str == chr) return (char *) str; str++; } return 0; } /* If using GCC, we can safely declare strlen this way. If not using GCC, it is ok not to declare it. */ #ifdef __GNUC__ /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. That was relevant to code that was here before. */ #ifndef __STDC__ /* gcc with -traditional declares the built-in strlen to return int, and has done so at least since version 2.4.5. -- rms. */ extern int strlen (const char *); #endif /* not __STDC__ */ #endif /* __GNUC__ */ #endif /* not __GNU_LIBRARY__ */ /* Handle permutation of arguments. */ /* Describe the part of ARGV that contains non-options that have been skipped. `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is the index after the last of them. */ static int first_nonopt; static int last_nonopt; /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) which contains all the non-options that have been skipped so far. The other is elements [last_nonopt,optind), which contains all the options processed since those non-options were skipped. `first_nonopt' and `last_nonopt' are relocated so that they describe the new indices of the non-options in ARGV after they are moved. */ static void exchange (char **argv) { int bottom = first_nonopt; int middle = last_nonopt; int top = optind; char *tem; /* Exchange the shorter segment with the far end of the longer segment. That puts the shorter segment into the right place. It leaves the longer segment in the right place overall, but it consists of two parts that need to be swapped next. */ while (top > middle && middle > bottom) { if (top - middle > middle - bottom) { /* Bottom segment is the short one. */ int len = middle - bottom; register int i; /* Swap it with the top part of the top segment. */ for (i = 0; i < len; i++) { tem = argv[bottom + i]; argv[bottom + i] = argv[top - (middle - bottom) + i]; argv[top - (middle - bottom) + i] = tem; } /* Exclude the moved bottom segment from further swapping. */ top -= len; } else { /* Top segment is the short one. */ int len = top - middle; register int i; /* Swap it with the bottom part of the bottom segment. */ for (i = 0; i < len; i++) { tem = argv[bottom + i]; argv[bottom + i] = argv[middle + i]; argv[middle + i] = tem; } /* Exclude the moved top segment from further swapping. */ bottom += len; } } /* Update records for the slots the non-options now occupy. */ first_nonopt += (optind - last_nonopt); last_nonopt = optind; } /* Initialize the internal data when the first call is made. */ static const char * _getopt_initialize (const char *optstring) { /* Start processing options with ARGV-element 1 (since ARGV-element 0 is the program name); the sequence of previously skipped non-option ARGV-elements is empty. */ first_nonopt = last_nonopt = optind = 1; nextchar = NULL; posixly_correct = getenv ("POSIXLY_CORRECT"); /* Determine how to handle the ordering of options and nonoptions. */ if (optstring[0] == '-') { ordering = RETURN_IN_ORDER; ++optstring; } else if (optstring[0] == '+') { ordering = REQUIRE_ORDER; ++optstring; } else if (posixly_correct != NULL) ordering = REQUIRE_ORDER; else ordering = PERMUTE; return optstring; } /* Scan elements of ARGV (whose length is ARGC) for option characters given in OPTSTRING. If an element of ARGV starts with '-', and is not exactly "-" or "--", then it is an option element. The characters of this element (aside from the initial '-') are option characters. If `getopt' is called repeatedly, it returns successively each of the option characters from each of the option elements. If `getopt' finds another option character, it returns that character, updating `optind' and `nextchar' so that the next call to `getopt' can resume the scan with the following option character or ARGV-element. If there are no more option characters, `getopt' returns `EOF'. Then `optind' is the index in ARGV of the first ARGV-element that is not an option. (The ARGV-elements have been permuted so that those that are not options now come last.) OPTSTRING is a string containing the legitimate option characters. If an option character is seen that is not listed in OPTSTRING, return '?' after printing an error message. If you set `opterr' to zero, the error message is suppressed but we still return '?'. If a char in OPTSTRING is followed by a colon, that means it wants an arg, so the following text in the same ARGV-element, or the text of the following ARGV-element, is returned in `optarg'. Two colons mean an option that wants an optional arg; if there is text in the current ARGV-element, it is returned in `optarg', otherwise `optarg' is set to zero. If OPTSTRING starts with `-' or `+', it requests different methods of handling the non-option ARGV-elements. See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. Long-named options begin with `--' instead of `-'. Their names may be abbreviated as long as the abbreviation is unique or is an exact match for some defined option. If they have an argument, it follows the option name in the same ARGV-element, separated from the option name by a `=', or else the in next ARGV-element. When `getopt' finds a long-named option, it returns 0 if that option's `flag' field is nonzero, the value of the option's `val' field if the `flag' field is zero. The elements of ARGV aren't really const, because we permute them. But we pretend they're const in the prototype to be compatible with other systems. LONGOPTS is a vector of `struct option' terminated by an element containing a name which is zero. LONGIND returns the index in LONGOPT of the long-named option found. It is only valid when a long-named option has been found by the most recent call. If LONG_ONLY is nonzero, '-' as well as '--' can introduce long-named options. */ int _getopt_internal (int argc, char *const *argv, const char *optstring, const struct option *longopts, int *longind, int long_only) { optarg = NULL; if (optind == 0) optstring = _getopt_initialize (optstring); if (nextchar == NULL || *nextchar == '\0') { /* Advance to the next ARGV-element. */ if (ordering == PERMUTE) { /* If we have just processed some options following some non-options, exchange them so that the options come first. */ if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (last_nonopt != optind) first_nonopt = optind; /* Skip any additional non-options and extend the range of non-options previously skipped. */ while (optind < argc && (argv[optind][0] != '-' || argv[optind][1] == '\0')) optind++; last_nonopt = optind; } /* The special ARGV-element `--' means premature end of options. Skip it like a null option, then exchange with previous non-options as if it were an option, then skip everything else like a non-option. */ if (optind != argc && !strcmp (argv[optind], "--")) { optind++; if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (first_nonopt == last_nonopt) first_nonopt = optind; last_nonopt = argc; optind = argc; } /* If we have done all the ARGV-elements, stop the scan and back over any non-options that we skipped and permuted. */ if (optind == argc) { /* Set the next-arg-index to point at the non-options that we previously skipped, so the caller will digest them. */ if (first_nonopt != last_nonopt) optind = first_nonopt; return EOF; } /* If we have come to a non-option and did not permute it, either stop the scan or describe it to the caller and pass it by. */ if ((argv[optind][0] != '-' || argv[optind][1] == '\0')) { if (ordering == REQUIRE_ORDER) return EOF; optarg = argv[optind++]; return 1; } /* We have found another option-ARGV-element. Skip the initial punctuation. */ nextchar = (argv[optind] + 1 + (longopts != NULL && argv[optind][1] == '-')); } /* Decode the current option-ARGV-element. */ /* Check whether the ARGV-element is a long option. If long_only and the ARGV-element has the form "-f", where f is a valid short option, don't consider it an abbreviated form of a long option that starts with f. Otherwise there would be no way to give the -f short option. On the other hand, if there's a long option "fubar" and the ARGV-element is "-fu", do consider that an abbreviation of the long option, just like "--fu", and not "-f" with arg "u". This distinction seems to be the most useful approach. */ if (longopts != NULL && (argv[optind][1] == '-' || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) { char *nameend; const struct option *p; const struct option *pfound = NULL; int exact = 0; int ambig = 0; int indfound = 0; int option_index; for (nameend = nextchar; *nameend && *nameend != '='; nameend++) /* Do nothing. */ ; /* Test all long options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) if (!strncmp (p->name, nextchar, nameend - nextchar)) { if (nameend - nextchar == (int) strlen (p->name)) { /* Exact match found. */ pfound = p; indfound = option_index; exact = 1; break; } else if (pfound == NULL) { /* First nonexact match found. */ pfound = p; indfound = option_index; } else /* Second or later nonexact match found. */ ambig = 1; } if (ambig && !exact) { if (opterr) fprintf (stderr, "%s: option `%s' is ambiguous\n", argv[0], argv[optind]); nextchar += strlen (nextchar); optind++; return '?'; } if (pfound != NULL) { option_index = indfound; optind++; if (*nameend) { /* Don't test has_arg with >, because some C compilers don't allow it to be used on enums. */ if (pfound->has_arg) optarg = nameend + 1; else { if (opterr) { if (argv[optind - 1][1] == '-') /* --option */ fprintf (stderr, "%s: option `--%s' doesn't allow an argument\n", argv[0], pfound->name); else /* +option or -option */ fprintf (stderr, "%s: option `%c%s' doesn't allow an argument\n", argv[0], argv[optind - 1][0], pfound->name); } nextchar += strlen (nextchar); return '?'; } } else if (pfound->has_arg == 1) { if (optind < argc) optarg = argv[optind++]; else { if (opterr) fprintf (stderr, "%s: option `%s' requires an argument\n", argv[0], argv[optind - 1]); nextchar += strlen (nextchar); return optstring[0] == ':' ? ':' : '?'; } } nextchar += strlen (nextchar); if (longind != NULL) *longind = option_index; if (pfound->flag) { *(pfound->flag) = pfound->val; return 0; } return pfound->val; } /* Can't find it as a long option. If this is not getopt_long_only, or the option starts with '--' or is not a valid short option, then it's an error. Otherwise interpret it as a short option. */ if (!long_only || argv[optind][1] == '-' || my_index (optstring, *nextchar) == NULL) { if (opterr) { if (argv[optind][1] == '-') /* --option */ fprintf (stderr, "%s: unrecognized option `--%s'\n", argv[0], nextchar); else /* +option or -option */ fprintf (stderr, "%s: unrecognized option `%c%s'\n", argv[0], argv[optind][0], nextchar); } nextchar = (char *) ""; optind++; return '?'; } } /* Look at and handle the next short option-character. */ { char c = *nextchar++; char *temp = my_index (optstring, c); /* Increment `optind' when we start to process its last character. */ if (*nextchar == '\0') ++optind; if (temp == NULL || c == ':') { if (opterr) { if (posixly_correct) /* 1003.2 specifies the format of this message. */ fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c); else fprintf (stderr, "%s: invalid option -- %c\n", argv[0], c); } optopt = c; return '?'; } if (temp[1] == ':') { if (temp[2] == ':') { /* This is an option that accepts an argument optionally. */ if (*nextchar != '\0') { optarg = nextchar; optind++; } else optarg = NULL; nextchar = NULL; } else { /* This is an option that requires an argument. */ if (*nextchar != '\0') { optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg, we must advance to the next element now. */ optind++; } else if (optind == argc) { if (opterr) { /* 1003.2 specifies the format of this message. */ fprintf (stderr, "%s: option requires an argument -- %c\n", argv[0], c); } optopt = c; if (optstring[0] == ':') c = ':'; else c = '?'; } else /* We already incremented `optind' once; increment it again when taking next ARGV-elt as argument. */ optarg = argv[optind++]; nextchar = NULL; } } return c; } } int getopt (int argc, char *const *argv, const char *optstring) { return _getopt_internal (argc, argv, optstring, (const struct option *) 0, (int *) 0, 0); } /* getopt_long and getopt_long_only entry points for GNU getopt. Copyright (C) 1987, 88, 89, 90, 91, 92, 1993 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it 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. */ int getopt_long (int argc, char *const *argv, const char *options, const struct option *long_options, int *opt_index) { return _getopt_internal (argc, argv, options, long_options, opt_index, 0); } /* Like getopt_long, but '-' as well as '--' can indicate a long option. If an option that starts with '-' (not '--') doesn't match a long option, but does match a short option, it is parsed as a short option instead. */ int getopt_long_only (int argc, char *const *argv, const char *options, const struct option *long_options, int *opt_index) { return _getopt_internal (argc, argv, options, long_options, opt_index, 1); } #endif /* _LIBC or not __GNU_LIBRARY__. */ snort-2.9.15.1/src/sfutil/getopt.h0000644000175200017520000000232613571422607013623 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _SNORT_GETOPT_H_ #define _SNORT_GETOPT_H_ #ifdef SNORT_GETOPT #define _next_char(string) (char)(*(string+1)) extern char * optarg; extern int optind; int getopt(int, char**, char*); #else #include #endif #endif /* _SNORT_GETOPT_H_ */ snort-2.9.15.1/src/sfutil/getopt1.h0000644000175200017520000001000413571422607013674 00000000000000/* Declarations for getopt. Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it 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. */ #ifndef _GETOPT1_H #define _GETOPT1_H 1 #ifndef HAVE_GETOPT_LONG #ifdef __cplusplus extern "C" { #endif /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ extern char *optarg; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns EOF, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ extern int optind; /* Callers store zero here to inhibit the error message `getopt' prints for unrecognized options. */ extern int opterr; /* Set to an option character which was unrecognized. */ extern int optopt; /* Describe the long-named options requested by the application. The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector of `struct option' terminated by an element containing a name which is zero. The field `has_arg' is: no_argument (or 0) if the option does not take an argument, required_argument (or 1) if the option requires an argument, optional_argument (or 2) if the option takes an optional argument. If the field `flag' is not NULL, it points to a variable that is set to the value given in the field `val' when the option is found, but left unchanged if the option is not found. To have a long-named option do something other than set an `int' to a compiled-in constant, such as set a value from `optarg', set the option's `flag' field to zero and its `val' field to a nonzero value (the equivalent single-letter option character, if there is one). For long options that have a zero `flag' field, `getopt' returns the contents of the `val' field. */ struct option { #if __STDC__ const char *name; #else char *name; #endif /* has_arg can't be an enum because some compilers complain about type mismatches in all the code that assumes it is an int. */ int has_arg; int *flag; int val; }; /* Names for the values of the `has_arg' field of `struct option'. */ #define no_argument 0 #define required_argument 1 #define optional_argument 2 #if __STDC__ #ifndef HAVE_GETOPT extern int getopt (int argc, char *const *argv, const char *optstring); #endif extern int getopt_long (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); extern int getopt_long_only (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); /* Internal only. Users should not call this directly. */ extern int _getopt_internal (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind, int long_only); #else /* not __STDC__ */ #ifndef HAVE_GETOPT extern int getopt (); #endif extern int getopt_long (); extern int getopt_long_only (); extern int _getopt_internal (); #endif /* not __STDC__ */ #ifdef __cplusplus } #endif #endif /* HAVE_GETOPT_LONG */ #endif /* _GETOPT_H */ snort-2.9.15.1/src/sfutil/acsmx.c0000644000175200017520000005055613571422607013437 00000000000000/* ** ** $Id$ ** ** Multi-Pattern Search Engine ** ** Aho-Corasick State Machine - uses a Deterministic Finite Automata - DFA ** ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Marc Norton ** ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** ** ** Reference - Efficient String matching: An Aid to Bibliographic Search ** Alfred V Aho and Margaret J Corasick ** Bell Labratories ** Copyright(C) 1975 Association for Computing Machinery,Inc ** ** Implemented from the 4 algorithms in the paper by Aho & Corasick ** and some implementation ideas from 'Practical Algorithms in C' ** ** Notes: ** 1) This version uses about 1024 bytes per pattern character - heavy on the memory. ** 2) This algorithm finds all occurrences of all patterns within a ** body of text. ** 3) Support is included to handle upper and lower case matching. ** 4) Some comopilers optimize the search routine well, others don't, this makes all the difference. ** 5) Aho inspects all bytes of the search text, but only once so it's very efficient, ** if the patterns are all large than the Modified Wu-Manbar method is often faster. ** 6) I don't subscribe to any one method is best for all searching needs, ** the data decides which method is best, ** and we don't know until after the search method has been tested on the specific data sets. ** ** ** May 2002 : Marc Norton 1st Version ** June 2002 : Modified interface for SNORT, added case support ** Aug 2002 : Cleaned up comments, and removed dead code. ** Nov 2,2002: Fixed queue_init() , added count=0 ** ** */ #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "acsmx.h" #include "util.h" #include "snort_debug.h" #ifdef DYNAMIC_PREPROC_CONTEXT #include "sf_dynamic_preprocessor.h" #endif //DYNAMIC_PREPROC_CONTEXT #define MEMASSERT(p,s) if(!p){fprintf(stderr,"ACSM-No Memory: %s!\n",s);exit(0);} #ifdef DEBUG_AC static int max_memory = 0; #endif /*static void Print_DFA( ACSM_STRUCT * acsm );*/ /* * */ static void * AC_MALLOC (int n) { void *p; p = calloc (1,n); #ifdef DEBUG_AC if (p) max_memory += n; #endif return p; } /* * */ static void AC_FREE (void *p) { if (p) free (p); } /* * Simple QUEUE NODE */ typedef struct _qnode { int state; struct _qnode *next; } QNODE; /* * Simple QUEUE Structure */ typedef struct _queue { QNODE * head, *tail; int count; } QUEUE; /* * */ static void queue_init (QUEUE * s) { s->head = s->tail = 0; s->count = 0; } /* * Add Tail Item to queue */ static void queue_add (QUEUE * s, int state) { QNODE * q; if (!s->head) { q = s->tail = s->head = (QNODE *) AC_MALLOC (sizeof (QNODE)); MEMASSERT (q, "queue_add"); q->state = state; q->next = 0; } else { q = (QNODE *) AC_MALLOC (sizeof (QNODE)); MEMASSERT (q, "queue_add"); q->state = state; q->next = 0; s->tail->next = q; s->tail = q; } s->count++; } /* * Remove Head Item from queue */ static int queue_remove (QUEUE * s) { int state = 0; QNODE * q; if (s->head) { q = s->head; state = q->state; s->head = s->head->next; s->count--; if (!s->head) { s->tail = 0; s->count = 0; } AC_FREE (q); } return state; } /* * */ static int queue_count (QUEUE * s) { return s->count; } /* * */ static void queue_free (QUEUE * s) { while (queue_count (s)) { queue_remove (s); } } /* ** Case Translation Table */ static unsigned char xlatcase[256]; /* * */ static void init_xlatcase () { int i; for (i = 0; i < 256; i++) { xlatcase[i] = (unsigned char)toupper (i); } } /* * */ static inline void ConvertCaseEx (unsigned char *d, unsigned char *s, int m) { int i; for (i = 0; i < m; i++) { d[i] = xlatcase[s[i]]; } } /* * */ static ACSM_PATTERN * CopyMatchListEntry (ACSM_PATTERN * px) { ACSM_PATTERN * p; p = (ACSM_PATTERN *) AC_MALLOC (sizeof (ACSM_PATTERN)); MEMASSERT (p, "CopyMatchListEntry"); memcpy (p, px, sizeof (ACSM_PATTERN)); px->udata->ref_count++; p->next = 0; return p; } /* * Add a pattern to the list of patterns terminated at this state. * Insert at front of list. */ static void AddMatchListEntry (ACSM_STRUCT * acsm, int state, ACSM_PATTERN * px) { ACSM_PATTERN * p; p = (ACSM_PATTERN *) AC_MALLOC (sizeof (ACSM_PATTERN)); MEMASSERT (p, "AddMatchListEntry"); memcpy (p, px, sizeof (ACSM_PATTERN)); p->next = acsm->acsmStateTable[state].MatchList; acsm->acsmStateTable[state].MatchList = p; } /* Add Pattern States */ static void AddPatternStates (ACSM_STRUCT * acsm, ACSM_PATTERN * p) { unsigned char *pattern; int state=0, next, n; n = p->n; pattern = p->patrn; /* * Match up pattern with existing states */ for (; n > 0; pattern++, n--) { next = acsm->acsmStateTable[state].NextState[*pattern]; if (next == ACSM_FAIL_STATE) break; state = next; } /* * Add new states for the rest of the pattern bytes, 1 state per byte */ for (; n > 0; pattern++, n--) { acsm->acsmNumStates++; acsm->acsmStateTable[state].NextState[*pattern] = acsm->acsmNumStates; state = acsm->acsmNumStates; } AddMatchListEntry (acsm, state, p); } /* * Build Non-Deterministic Finite Automata */ static void Build_NFA (ACSM_STRUCT * acsm) { int r, s; int i; QUEUE q, *queue = &q; ACSM_PATTERN * mlist=0; ACSM_PATTERN * px=0; /* Init a Queue */ queue_init (queue); /* Add the state 0 transitions 1st */ for (i = 0; i < ALPHABET_SIZE; i++) { s = acsm->acsmStateTable[0].NextState[i]; if (s) { queue_add (queue, s); acsm->acsmStateTable[s].FailState = 0; } } /* Build the fail state transitions for each valid state */ while (queue_count (queue) > 0) { r = queue_remove (queue); /* Find Final States for any Failure */ for (i = 0; i < ALPHABET_SIZE; i++) { int fs, next; if ((s = acsm->acsmStateTable[r].NextState[i]) != ACSM_FAIL_STATE) { queue_add (queue, s); fs = acsm->acsmStateTable[r].FailState; /* * Locate the next valid state for 'i' starting at s */ while ((next=acsm->acsmStateTable[fs].NextState[i]) == ACSM_FAIL_STATE) { fs = acsm->acsmStateTable[fs].FailState; } /* * Update 's' state failure state to point to the next valid state */ acsm->acsmStateTable[s].FailState = next; /* * Copy 'next'states MatchList to 's' states MatchList, * we copy them so each list can be AC_FREE'd later, * else we could just manipulate pointers to fake the copy. */ for (mlist = acsm->acsmStateTable[next].MatchList; mlist != NULL ; mlist = mlist->next) { px = CopyMatchListEntry (mlist); if( !px ) { FatalError("*** Out of memory Initializing Aho Corasick in acsmx.c ****"); } /* Insert at front of MatchList */ px->next = acsm->acsmStateTable[s].MatchList; acsm->acsmStateTable[s].MatchList = px; } } } } /* Clean up the queue */ queue_free (queue); } /* * Build Deterministic Finite Automata from NFA */ static void Convert_NFA_To_DFA (ACSM_STRUCT * acsm) { int r, s; int i; QUEUE q, *queue = &q; /* Init a Queue */ queue_init (queue); /* Add the state 0 transitions 1st */ for (i = 0; i < ALPHABET_SIZE; i++) { s = acsm->acsmStateTable[0].NextState[i]; if (s) { queue_add (queue, s); } } /* Start building the next layer of transitions */ while (queue_count (queue) > 0) { r = queue_remove (queue); /* State is a branch state */ for (i = 0; i < ALPHABET_SIZE; i++) { if ((s = acsm->acsmStateTable[r].NextState[i]) != ACSM_FAIL_STATE) { queue_add (queue, s); } else { acsm->acsmStateTable[r].NextState[i] = acsm->acsmStateTable[acsm->acsmStateTable[r].FailState]. NextState[i]; } } } /* Clean up the queue */ queue_free (queue); } /* * */ ACSM_STRUCT * acsmNew (void (*userfree)(void *p), void (*optiontreefree)(void **p), void (*neg_list_free)(void **p)) { ACSM_STRUCT * p; init_xlatcase (); p = (ACSM_STRUCT *) AC_MALLOC (sizeof (ACSM_STRUCT)); MEMASSERT (p, "acsmNew"); if (p) { memset (p, 0, sizeof (ACSM_STRUCT)); p->userfree = userfree; p->optiontreefree = optiontreefree; p->neg_list_free = neg_list_free; } return p; } /* * Add a pattern to the list of patterns for this state machine */ int acsmAddPattern (ACSM_STRUCT * p, unsigned char *pat, int n, int nocase, int offset, int depth, int negative, void * id, int iid) { ACSM_PATTERN * plist; plist = (ACSM_PATTERN *) AC_MALLOC (sizeof (ACSM_PATTERN)); MEMASSERT (plist, "acsmAddPattern"); plist->patrn = (unsigned char *) AC_MALLOC (n); ConvertCaseEx (plist->patrn, pat, n); plist->casepatrn = (unsigned char *) AC_MALLOC (n); memcpy (plist->casepatrn, pat, n); plist->udata = (ACSM_USERDATA *)AC_MALLOC(sizeof(ACSM_USERDATA)); MEMASSERT (plist->udata, "acsmAddPattern"); plist->udata->ref_count = 1; plist->udata->id = id; plist->n = n; plist->nocase = nocase; plist->negative = negative; plist->offset = offset; plist->depth = depth; plist->iid = iid; plist->next = p->acsmPatterns; p->acsmPatterns = plist; p->numPatterns++; return 0; } static int acsmBuildMatchStateTrees( ACSM_STRUCT * acsm, int (*build_tree)(void * id, void **existing_tree), int (*neg_list_func)(void *id, void **list) ) { int i, cnt = 0; ACSM_PATTERN * mlist; /* Find the states that have a MatchList */ for (i = 0; i < acsm->acsmMaxStates; i++) { for ( mlist=acsm->acsmStateTable[i].MatchList; mlist!=NULL; mlist=mlist->next ) { if (mlist->udata->id) { if (mlist->negative) { neg_list_func(mlist->udata->id, &acsm->acsmStateTable[i].MatchList->neg_list); } else { build_tree(mlist->udata->id, &acsm->acsmStateTable[i].MatchList->rule_option_tree); } } cnt++; } if (acsm->acsmStateTable[i].MatchList) { /* Last call to finalize the tree */ build_tree(NULL, &acsm->acsmStateTable[i].MatchList->rule_option_tree); } } return cnt; } static int acsmBuildMatchStateTreesWithSnortConf( struct _SnortConfig *sc, ACSM_STRUCT * acsm, int (*build_tree)(struct _SnortConfig *, void * id, void **existing_tree), int (*neg_list_func)(void *id, void **list) ) { int i, cnt = 0; ACSM_PATTERN * mlist; /* Find the states that have a MatchList */ for (i = 0; i < acsm->acsmMaxStates; i++) { for ( mlist=acsm->acsmStateTable[i].MatchList; mlist!=NULL; mlist=mlist->next ) { if (mlist->udata->id) { if (mlist->negative) { neg_list_func(mlist->udata->id, &acsm->acsmStateTable[i].MatchList->neg_list); } else { build_tree(sc, mlist->udata->id, &acsm->acsmStateTable[i].MatchList->rule_option_tree); } } cnt++; } if (acsm->acsmStateTable[i].MatchList) { /* Last call to finalize the tree */ build_tree(sc, NULL, &acsm->acsmStateTable[i].MatchList->rule_option_tree); } } return cnt; } /* * Compile State Machine */ static inline int _acsmCompile (ACSM_STRUCT * acsm) { int i, k; ACSM_PATTERN * plist; /* Count number of states */ acsm->acsmMaxStates = 1; for (plist = acsm->acsmPatterns; plist != NULL; plist = plist->next) { acsm->acsmMaxStates += plist->n; } acsm->acsmStateTable = (ACSM_STATETABLE *) AC_MALLOC (sizeof (ACSM_STATETABLE) * acsm->acsmMaxStates); MEMASSERT (acsm->acsmStateTable, "acsmCompile"); memset (acsm->acsmStateTable, 0, sizeof (ACSM_STATETABLE) * acsm->acsmMaxStates); /* Initialize state zero as a branch */ acsm->acsmNumStates = 0; /* Initialize all States NextStates to FAILED */ for (k = 0; k < acsm->acsmMaxStates; k++) { for (i = 0; i < ALPHABET_SIZE; i++) { acsm->acsmStateTable[k].NextState[i] = ACSM_FAIL_STATE; } } /* Add each Pattern to the State Table */ for (plist = acsm->acsmPatterns; plist != NULL; plist = plist->next) { AddPatternStates (acsm, plist); } /* Set all failed state transitions to return to the 0'th state */ for (i = 0; i < ALPHABET_SIZE; i++) { if (acsm->acsmStateTable[0].NextState[i] == ACSM_FAIL_STATE) { acsm->acsmStateTable[0].NextState[i] = 0; } } /* Build the NFA */ Build_NFA (acsm); /* Convert the NFA to a DFA */ Convert_NFA_To_DFA (acsm); /* printf ("ACSMX-Max Memory: %d bytes, %d states\n", max_memory, acsm->acsmMaxStates); */ //Print_DFA( acsm ); return 0; } int acsmCompile (ACSM_STRUCT * acsm, int (*build_tree)(void * id, void **existing_tree), int (*neg_list_func)(void *id, void **list)) { int rval; if ((rval = _acsmCompile (acsm))) return rval; if (build_tree && neg_list_func) { acsmBuildMatchStateTrees(acsm, build_tree, neg_list_func); } return 0; } int acsmCompileWithSnortConf (struct _SnortConfig *sc, ACSM_STRUCT * acsm, int (*build_tree)(struct _SnortConfig *, void * id, void **existing_tree), int (*neg_list_func)(void *id, void **list)) { int rval; if ((rval = _acsmCompile (acsm))) return rval; if (build_tree && neg_list_func) { acsmBuildMatchStateTreesWithSnortConf(sc, acsm, build_tree, neg_list_func); } return 0; } static unsigned char Tc[64*1024]; /* * Search Text or Binary Data for Pattern matches */ int acsmSearch (ACSM_STRUCT * acsm, unsigned char *Tx, int n, int (*Match)(void * id, void *tree, int index, void *data, void *neg_list), void *data, int* current_state ) { int state = 0; ACSM_PATTERN * mlist; unsigned char *Tend; ACSM_STATETABLE * StateTable = acsm->acsmStateTable; int nfound = 0; unsigned char *T; int index; /* Case conversion */ ConvertCaseEx (Tc, Tx, n); T = Tc; Tend = T + n; if ( !current_state ) { return 0; } state = *current_state; for (; T < Tend; T++) { state = StateTable[state].NextState[*T]; if( StateTable[state].MatchList != NULL ) { mlist = StateTable[state].MatchList; index = T - mlist->n + 1 - Tc; nfound++; if (Match (mlist->udata->id, mlist->rule_option_tree, index, data, mlist->neg_list) > 0) { *current_state = state; return nfound; } } } *current_state = state; return nfound; } /* * Free all memory */ void acsmFree (ACSM_STRUCT * acsm) { int i; ACSM_PATTERN * mlist, *ilist; for (i = 0; i < acsm->acsmMaxStates; i++) { mlist = acsm->acsmStateTable[i].MatchList; while (mlist) { ilist = mlist; mlist = mlist->next; ilist->udata->ref_count--; if (ilist->udata->ref_count == 0) { if (acsm->userfree && ilist->udata->id) acsm->userfree(ilist->udata->id); AC_FREE(ilist->udata); } if (ilist->rule_option_tree && acsm->optiontreefree) { acsm->optiontreefree(&(ilist->rule_option_tree)); } if (ilist->neg_list && acsm->neg_list_free) { acsm->neg_list_free(&(ilist->neg_list)); } AC_FREE (ilist); } } AC_FREE (acsm->acsmStateTable); mlist = acsm->acsmPatterns; while(mlist) { ilist = mlist; mlist = mlist->next; AC_FREE(ilist->patrn); AC_FREE(ilist->casepatrn); AC_FREE(ilist); } AC_FREE (acsm); } int acsmPatternCount ( ACSM_STRUCT * acsm ) { return acsm->numPatterns; } /* * */ /* static void Print_DFA( ACSM_STRUCT * acsm ) { int k; int i; int next; for (k = 0; k < acsm->acsmMaxStates; k++) { for (i = 0; i < ALPHABET_SIZE; i++) { next = acsm->acsmStateTable[k].NextState[i]; if( next == 0 || next == ACSM_FAIL_STATE ) { if( isprint(i) ) printf("%3c->%-5d\t",i,next); else printf("%3d->%-5d\t",i,next); } } printf("\n"); } } */ int acsmPrintDetailInfo(ACSM_STRUCT * p) { #ifdef WIN32 if(p) p = p; #endif return 0; } int acsmPrintSummaryInfo(void) { #ifdef XXXXX char * fsa[]={ "TRIE", "NFA", "DFA", }; ACSM_STRUCT2 * p = &summary.acsm; if( !summary.num_states ) return; LogMessage("+--[Pattern Matcher:Aho-Corasick Summary]----------------------\n"); LogMessage("| Alphabet Size : %d Chars\n",p->acsmAlphabetSize); LogMessage("| Sizeof State : %d bytes\n",sizeof(acstate_t)); LogMessage("| Storage Format : %s \n",sf[ p->acsmFormat ]); LogMessage("| Num States : %d\n",summary.num_states); LogMessage("| Num Transitions : %d\n",summary.num_transitions); LogMessage("| State Density : %.1f%%\n",100.0*(double)summary.num_transitions/(summary.num_states*p->acsmAlphabetSize)); LogMessage("| Finite Automatum : %s\n", fsa[p->acsmFSA]); if( max_memory < 1024*1024 ) LogMessage("| Memory : %.2fKbytes\n", (float)max_memory/1024 ); else LogMessage("| Memory : %.2fMbytes\n", (float)max_memory/(1024*1024) ); LogMessage("+-------------------------------------------------------------\n"); #endif return 0; } #ifdef ACSMX_MAIN /* * Text Data Buffer */ unsigned char text[512]; /* * A Match is found */ int MatchFound (unsigned id, int index, void *data) { fprintf (stdout, "%s\n", (char *) id); return 0; } /* * */ int main (int argc, char **argv) { int i, nocase = 0; ACSM_STRUCT * acsm; if (argc < 3) { fprintf (stderr, "Usage: acsmx pattern word-1 word-2 ... word-n -nocase\n"); exit (0); } acsm = acsmNew (); strcpy (text, argv[1]); for (i = 1; i < argc; i++) if (strcmp (argv[i], "-nocase") == 0) nocase = 1; for (i = 2; i < argc; i++) { if (argv[i][0] == '-') continue; acsmAddPattern (acsm, argv[i], strlen (argv[i]), nocase, 0, 0, argv[i], i - 2); } acsmCompile (acsm); acsmSearch (acsm, text, strlen (text), MatchFound, (void *) 0); acsmFree (acsm); printf ("normal pgm end\n"); return (0); } #endif /* */ snort-2.9.15.1/src/sfutil/acsmx.h0000644000175200017520000000663313571422607013441 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* ** ACSMX.H ** ** */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sf_types.h" #include #include #include #ifndef ACSMX_H #define ACSMX_H /* * Prototypes */ #define ALPHABET_SIZE 256 #define ACSM_FAIL_STATE -1 typedef struct _acsm_userdata { uint32_t ref_count; void *id; } ACSM_USERDATA; typedef struct _acsm_pattern { struct _acsm_pattern *next; unsigned char *patrn; unsigned char *casepatrn; int n; int nocase; int offset; int depth; int negative; ACSM_USERDATA *udata; int iid; void * rule_option_tree; void * neg_list; } ACSM_PATTERN; typedef struct { /* Next state - based on input character */ int NextState[ ALPHABET_SIZE ]; /* Failure state - used while building NFA & DFA */ int FailState; /* List of patterns that end here, if any */ ACSM_PATTERN *MatchList; }ACSM_STATETABLE; /* * State machine Struct */ typedef struct { int acsmMaxStates; int acsmNumStates; ACSM_PATTERN * acsmPatterns; ACSM_STATETABLE * acsmStateTable; int bcSize; short bcShift[256]; int numPatterns; void (*userfree)(void *p); void (*optiontreefree)(void **p); void (*neg_list_free)(void **p); }ACSM_STRUCT; /* * Prototypes */ ACSM_STRUCT * acsmNew (void (*userfree)(void *p), void (*optiontreefree)(void **p), void (*neg_list_free)(void **p)); int acsmAddPattern( ACSM_STRUCT * p, unsigned char * pat, int n, int nocase, int offset, int depth, int negative, void * id, int iid ); int acsmCompile ( ACSM_STRUCT * acsm, int (*build_tree)(void * id, void **existing_tree), int (*neg_list_func)(void *id, void **list)); struct _SnortConfig; int acsmCompileWithSnortConf ( struct _SnortConfig *, ACSM_STRUCT * acsm, int (*build_tree)(struct _SnortConfig *, void * id, void **existing_tree), int (*neg_list_func)(void *id, void **list)); int acsmSearch ( ACSM_STRUCT * acsm,unsigned char * T, int n, int (*Match)(void * id, void *tree, int index, void *data, void *neg_list), void * data, int* current_state ); void acsmFree ( ACSM_STRUCT * acsm ); int acsmPatternCount ( ACSM_STRUCT * acsm ); int acsmPrintDetailInfo(ACSM_STRUCT *); int acsmPrintSummaryInfo(void); #endif snort-2.9.15.1/src/sfutil/acsmx2.c0000644000175200017520000025251113571422607013514 00000000000000/* ** $Id$ ** ** Copyright(C) 2002,2003,2004 Marc Norton ** Copyright(C) 2003,2004 Daniel Roelker ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** ** acsmx2.c ** ** Multi-Pattern Search Engine ** ** Aho-Corasick State Machine - version 2.0 ** ** Supports both Non-Deterministic and Deterministic Finite Automata ** ** ** Reference - Efficient String matching: An Aid to Bibliographic Search ** Alfred V Aho and Margaret J Corasick ** Bell Labratories ** Copyright(C) 1975 Association for Computing Machinery,Inc ** ** +++ ** +++ Version 1.0 notes - Marc Norton: ** +++ ** ** Original implementation based on the 4 algorithms in the paper by ** Aho & Corasick, some implementation ideas from 'Practical Algorithms ** in C', and some of my own. ** ** 1) Finds all occurrences of all patterns within a text. ** ** +++ ** +++ Version 2.0 Notes - Marc Norton/Dan Roelker: ** +++ ** ** New implementation modifies the state table storage and access model to ** use compacted sparse vector storage. Dan Roelker and I hammered this ** strategy out amongst many others in order to reduce memory usage and ** improve caching performance. The memory usage is greatly reduced, we ** only use 1/4 of what we use to. The caching performance is better in ** pure benchmarking tests, but does not show overall improvement in Snort. ** Unfortunately, once a pattern match test has been performed Snort moves ** on to doing many other things before we get back to a patteren match test, ** so the cache is voided. ** ** This versions has better caching performance characteristics, reduced ** memory, more state table storage options, and requires no a priori case ** conversions. It does maintain the same public interface. (Snort only ** used banded storage). ** ** 1) Supports NFA and DFA state machines, and basic keyword state machines ** 2) Initial transition table uses Linked Lists ** 3) Improved state table memory options. NFA and DFA state transition ** tables are converted to one of 4 formats during compilation. ** a) Full matrix ** b) Sparse matrix ** c) Banded matrix (Default-this is the only one used in snort) ** d) Sparse-Banded matrix ** 4) Added support for acstate_t in .h file so we can compile states as ** 16, or 32 bit state values for another reduction in memory ** consumption, smaller states allows more of the state table to be ** cached, and improves performance on x86-P4. Your mileage may vary, ** especially on risc systems. ** 5) Added a bool to each state transition list to indicate if there is ** a matching pattern in the state. This prevents us from accessing ** another data array and can improve caching/performance. ** 6) The search functions are very sensitive, don't change them without ** extensive testing, or you'll just spoil the caching and prefetching ** opportunities. ** ** Extras for fellow pattern matchers: ** The table below explains the storage format used at each step. ** You can use an NFA or DFA to match with, the NFA is slower but tiny - ** set the structure directly. ** You can use any of the 4 storage modes above -full, sparse, banded, ** sparse-bands, set the structure directly. ** For applications where you have lots of data and a pattern set to ** search, this version was up to 3x faster than the previous verion, due ** to caching performance. This cannot be fully realized in Snort yet, ** but other applications may have better caching opportunities. ** Snort only needs to use the banded or full storage. ** ** Transition table format at each processing stage. ** ------------------------------------------------- ** Patterns -> Keyword State Table (List) ** Keyword State Table -> NFA (List) ** NFA -> DFA (List) ** DFA (List)-> Sparse Rows O(m-avg # transitions per state) ** -> Banded Rows O(1) ** -> Sparse-Banded Rows O(nb-# bands) ** -> Full Matrix O(1) ** ** Notes: ** ** 8/28/06 ** man - Sparse and SparseBands - fixed off by one in calculating matching index ** SparseBands changed ps increment to 2+n to increment between bands. ** ** 01/2008 ** man - added 2 phase pattern matcher using a pattern match queue. ** ** Matching states are queued, duplicate matches are dropped, ** and after the complete buffer scan the queued matches are ** processed. This improves cacheing performance, and reduces ** duplicate rule processing. The queue is limited in size and ** is flushed if it becomes full during the scan. This allows ** simple insertions. Tracking queue ops is optional, as this can ** impose a modest performance hit of a few percent. ** */ #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sf_types.h" #ifndef DYNAMIC_PREPROC_CONTEXT #define ACSMX2_TRACK_Q #ifdef ACSMX2_TRACK_Q # include "snort.h" #endif #endif //DYNAMIC_PREPROC_CONTEXT #include "acsmx2.h" #include "util.h" #include "snort_debug.h" #ifdef DYNAMIC_PREPROC_CONTEXT #include "sf_dynamic_preprocessor.h" #endif //DYNAMIC_PREPROC_CONTEXT #define printf LogMessage #define MEMASSERT(p,s) if(!p){FatalError("ACSM-No Memory: %s!\n",s);} static int acsm2_total_memory = 0; static int acsm2_pattern_memory = 0; static int acsm2_matchlist_memory = 0; static int acsm2_transtable_memory = 0; static int acsm2_dfa_memory = 0; static int acsm2_dfa1_memory = 0; static int acsm2_dfa2_memory = 0; static int acsm2_dfa4_memory = 0; static int acsm2_failstate_memory = 0; static int s_verbose=0; typedef struct acsm_summary_s { unsigned num_states; unsigned num_transitions; unsigned num_instances; unsigned num_patterns; unsigned num_characters; unsigned num_match_states; unsigned num_1byte_instances; unsigned num_2byte_instances; unsigned num_4byte_instances; ACSM_STRUCT2 acsm; } acsm_summary_t; static acsm_summary_t summary; void acsm_init_summary(void) { summary.num_states = 0; summary.num_transitions = 0; summary.num_instances = 0; summary.num_patterns = 0; summary.num_characters = 0; summary.num_match_states = 0; summary.num_1byte_instances = 0; summary.num_2byte_instances = 0; summary.num_4byte_instances = 0; memset(&summary.acsm, 0, sizeof(ACSM_STRUCT2)); acsm2_total_memory = 0; acsm2_pattern_memory = 0; acsm2_matchlist_memory = 0; acsm2_transtable_memory = 0; acsm2_dfa_memory = 0; acsm2_failstate_memory = 0; } /* ** Case Translation Table */ static unsigned char xlatcase[256]; /* * */ static void init_xlatcase() { int i; for (i = 0; i < 256; i++) { xlatcase[i] = (unsigned char)toupper(i); } } /* * Case Conversion */ static inline void ConvertCaseEx (unsigned char *d, unsigned char *s, int m) { int i; #ifdef XXXX int n; n = m & 3; m >>= 2; for (i = 0; i < m; i++ ) { d[0] = xlatcase[ s[0] ]; d[2] = xlatcase[ s[2] ]; d[1] = xlatcase[ s[1] ]; d[3] = xlatcase[ s[3] ]; d+=4; s+=4; } for (i=0; i < n; i++) { d[i] = xlatcase[ s[i] ]; } #else for (i=0; i < m; i++) { d[i] = xlatcase[ s[i] ]; } #endif } /* * */ void acsmSetVerbose2(void) { s_verbose = 1; } typedef enum _Acsm2MemoryType { ACSM2_MEMORY_TYPE__NONE = 0, ACSM2_MEMORY_TYPE__PATTERN, ACSM2_MEMORY_TYPE__MATCHLIST, ACSM2_MEMORY_TYPE__TRANSTABLE, ACSM2_MEMORY_TYPE__FAILSTATE } Acsm2MemoryType; /* * */ static void * AC_MALLOC( int n, Acsm2MemoryType type ) { void *p = calloc(1, n); if (p != NULL) { switch (type) { case ACSM2_MEMORY_TYPE__PATTERN: acsm2_pattern_memory += n; break; case ACSM2_MEMORY_TYPE__MATCHLIST: acsm2_matchlist_memory += n; break; case ACSM2_MEMORY_TYPE__TRANSTABLE: acsm2_transtable_memory += n; break; case ACSM2_MEMORY_TYPE__FAILSTATE: acsm2_failstate_memory += n; break; case ACSM2_MEMORY_TYPE__NONE: break; default: FatalError("%s(%d) Invalid memory type\n", __FILE__, __LINE__); break; } acsm2_total_memory += n; } return p; } static void * AC_MALLOC_DFA( int n, int sizeofstate ) { void *p = calloc(1, n); if (p != NULL) { switch (sizeofstate) { case 1: acsm2_dfa1_memory += n; break; case 2: acsm2_dfa2_memory += n; break; case 4: default: acsm2_dfa4_memory += n; break; } acsm2_dfa_memory += n; acsm2_total_memory += n; } return p; } /* * */ static void AC_FREE( void *p, int n, Acsm2MemoryType type ) { if (p != NULL) { switch (type) { case ACSM2_MEMORY_TYPE__PATTERN: acsm2_pattern_memory -= n; break; case ACSM2_MEMORY_TYPE__MATCHLIST: acsm2_matchlist_memory -= n; break; case ACSM2_MEMORY_TYPE__TRANSTABLE: acsm2_transtable_memory -= n; break; case ACSM2_MEMORY_TYPE__FAILSTATE: acsm2_failstate_memory -= n; break; case ACSM2_MEMORY_TYPE__NONE: default: break; } acsm2_total_memory -= n; free(p); } } static void AC_FREE_DFA( void *p, int n, int sizeofstate ) { if (p != NULL) { switch (sizeofstate) { case 1: acsm2_dfa1_memory -= n; break; case 2: acsm2_dfa2_memory -= n; break; case 4: default: acsm2_dfa4_memory -= n; break; } acsm2_dfa_memory -= n; acsm2_total_memory -= n; free(p); } } /* * Simple QUEUE NODE */ typedef struct _qnode { int state; struct _qnode *next; } QNODE; /* * Simple QUEUE Structure */ typedef struct _queue { QNODE * head, *tail; int count; } QUEUE; /* * Initialize the queue */ static void queue_init (QUEUE * s) { s->head = s->tail = 0; s->count= 0; } /* * Add Tail Item to queue (FiFo/LiLo) */ static void queue_add (QUEUE * s, int state) { QNODE * q; if (!s->head) { q = s->tail = s->head = (QNODE *)AC_MALLOC(sizeof(QNODE), ACSM2_MEMORY_TYPE__NONE); MEMASSERT (q, "queue_add"); q->state = state; q->next = 0; } else { q = (QNODE *)AC_MALLOC(sizeof(QNODE), ACSM2_MEMORY_TYPE__NONE); MEMASSERT (q, "queue_add"); q->state = state; q->next = 0; s->tail->next = q; s->tail = q; } s->count++; } /* * Remove Head Item from queue */ static int queue_remove (QUEUE * s) { int state = 0; QNODE * q; if (s->head) { q = s->head; state = q->state; s->head = s->head->next; s->count--; if( !s->head ) { s->tail = 0; s->count = 0; } AC_FREE(q, sizeof(QNODE), ACSM2_MEMORY_TYPE__NONE); } return state; } /* * Return items in the queue */ static int queue_count (QUEUE * s) { return s->count; } /* * Free the queue */ static void queue_free (QUEUE * s) { while (queue_count (s)) { queue_remove (s); } } /* * Get Next State-NFA */ static int List_GetNextState( ACSM_STRUCT2 * acsm, int state, int input ) { trans_node_t * t = acsm->acsmTransTable[state]; while( t ) { if( t->key == (acstate_t)input ) { return t->next_state; } t=t->next; } if( state == 0 ) return 0; return ACSM_FAIL_STATE2; /* Fail state ??? */ } /* * Get Next State-NFA, using direct index to speed up search */ static int List_GetNextStateOpt( ACSM_STRUCT2 * acsm, trans_node_t **acsmTransTableOpt, int state, int input ) { trans_node_t * t; int index = state * acsm->acsmAlphabetSize + input; t = acsmTransTableOpt[index]; if (t) return t->next_state; if( state == 0 ) return 0; return ACSM_FAIL_STATE2; /* Fail state ??? */ } /* * Get Next State-DFA */ static int List_GetNextState2( ACSM_STRUCT2 * acsm, int state, int input ) { trans_node_t * t = acsm->acsmTransTable[state]; while( t ) { if( t->key == (acstate_t)input ) { return t->next_state; } t = t->next; } return 0; /* default state */ } /* * Put Next State - Head insertion, and transition updates */ static int List_PutNextState( ACSM_STRUCT2 * acsm, int state, int input, int next_state ) { trans_node_t * p; trans_node_t * tnew; // printf(" List_PutNextState: state=%d, input='%c', next_state=%d\n",state,input,next_state); /* Check if the transition already exists, if so just update the next_state */ p = acsm->acsmTransTable[state]; while( p ) { /* transition already exists- reset the next state */ if( p->key == (acstate_t)input ) { p->next_state = next_state; return 0; } p=p->next; } /* Definitely not an existing transition - add it */ tnew = (trans_node_t*)AC_MALLOC(sizeof(trans_node_t), ACSM2_MEMORY_TYPE__TRANSTABLE); if( !tnew ) return -1; tnew->key = input; tnew->next_state = next_state; tnew->next = 0; tnew->next = acsm->acsmTransTable[state]; acsm->acsmTransTable[state] = tnew; acsm->acsmNumTrans++; return 0; } /* * Put Next State - Head insertion, and transition updates */ static int List_PutNextStateOpt( ACSM_STRUCT2 * acsm, trans_node_t **acsmTransTableOpt, int state, int input, int next_state ) { trans_node_t * tnew; trans_node_t *t; int index = state * acsm->acsmAlphabetSize + input; t = acsmTransTableOpt[index]; if (t) { t->next_state = next_state; return 0; } /* Definitely not an existing transition - add it */ tnew = (trans_node_t*)AC_MALLOC(sizeof(trans_node_t), ACSM2_MEMORY_TYPE__TRANSTABLE); if( !tnew ) return -1; tnew->key = input; tnew->next_state = next_state; tnew->next = 0; tnew->next = acsm->acsmTransTable[state]; acsm->acsmTransTable[state] = tnew; acsm->acsmNumTrans++; acsmTransTableOpt[index] = tnew; return 0; } /* * Free the entire transition table */ static int List_FreeTransTable( ACSM_STRUCT2 *acsm ) { int i; trans_node_t *t, *p; if (acsm->acsmTransTable == NULL) return 0; for (i = 0; i < acsm->acsmMaxStates; i++) { t = acsm->acsmTransTable[i]; while (t != NULL) { p = t->next; AC_FREE(t, sizeof(trans_node_t), ACSM2_MEMORY_TYPE__TRANSTABLE); t = p; } } AC_FREE(acsm->acsmTransTable, sizeof(void*) * acsm->acsmMaxStates, ACSM2_MEMORY_TYPE__TRANSTABLE); acsm->acsmTransTable = NULL; return 0; } /* * */ /* static int List_FreeList( trans_node_t * t ) { int tcnt=0; trans_node_t *p; while( t ) { p = t->next; free(t); t = p; acsm2_total_memory -= sizeof(trans_node_t); tcnt++; } return tcnt; } */ /* * Print the trans table to stdout */ static int List_PrintTransTable( ACSM_STRUCT2 * acsm ) { int i; trans_node_t * t; ACSM_PATTERN2 * patrn; if( !acsm->acsmTransTable ) return 0; printf("Print Transition Table- %d active states\n",acsm->acsmNumStates); for(i=0;i< acsm->acsmNumStates;i++) { t = acsm->acsmTransTable[i]; printf("state %3d: ",i); while( t ) { if( isascii((int)t->key) && isprint((int)t->key) ) printf("%3c->%-5d\t",t->key,t->next_state); else printf("%3d->%-5d\t",t->key,t->next_state); t = t->next; } patrn =acsm->acsmMatchList[i]; while( patrn ) { printf("%.*s ",patrn->n,patrn->patrn); patrn = patrn->next; } printf("\n"); } return 0; } /* * Converts row of states from list to a full vector format */ static inline int List_ConvToFull( ACSM_STRUCT2 *acsm, acstate_t state, acstate_t *full ) { int tcnt = 0; trans_node_t *t = acsm->acsmTransTable[state]; if (t == NULL) return 0; while (t != NULL) { switch (acsm->sizeofstate) { case 1: *((uint8_t *)full + t->key) = (uint8_t)t->next_state; break; case 2: *((uint16_t *)full + t->key) = (uint16_t)t->next_state; break; default: full[t->key] = t->next_state; break; } tcnt++; t = t->next; } return tcnt; } /* * Copy a Match List Entry - don't dup the pattern data */ static ACSM_PATTERN2* CopyMatchListEntry (ACSM_PATTERN2 * px) { ACSM_PATTERN2 * p; p = (ACSM_PATTERN2 *)AC_MALLOC(sizeof (ACSM_PATTERN2), ACSM2_MEMORY_TYPE__MATCHLIST); MEMASSERT (p, "CopyMatchListEntry"); memcpy (p, px, sizeof (ACSM_PATTERN2)); p->next = 0; return p; } /* * Check if a pattern is in the list already, * validate it using the 'id' field. This must be unique * for every pattern. */ /* static int FindMatchListEntry (ACSM_STRUCT2 * acsm, int state, ACSM_PATTERN2 * px) { ACSM_PATTERN2 * p; p = acsm->acsmMatchList[state]; while( p ) { if( p->id == px->id ) return 1; p = p->next; } return 0; } */ /* * Add a pattern to the list of patterns terminated at this state. * Insert at front of list. */ static void AddMatchListEntry (ACSM_STRUCT2 * acsm, int state, ACSM_PATTERN2 * px) { ACSM_PATTERN2 * p; p = (ACSM_PATTERN2 *)AC_MALLOC(sizeof (ACSM_PATTERN2), ACSM2_MEMORY_TYPE__MATCHLIST); MEMASSERT (p, "AddMatchListEntry"); memcpy (p, px, sizeof (ACSM_PATTERN2)); p->next = acsm->acsmMatchList[state]; acsm->acsmMatchList[state] = p; } static void AddPatternStates (ACSM_STRUCT2 * acsm, ACSM_PATTERN2 * p) { int state, next, n; unsigned char *pattern; n = p->n; pattern = p->patrn; state = 0; if(s_verbose)printf(" Begin AddPatternStates: acsmNumStates=%d\n",acsm->acsmNumStates); if(s_verbose)printf(" adding '%.*s', nocase=%d\n", n,p->patrn, p->nocase ); /* * Match up pattern with existing states */ for (; n > 0; pattern++, n--) { if(s_verbose)printf(" find char='%c'\n", *pattern ); next = List_GetNextState(acsm,state,*pattern); if ((acstate_t)next == ACSM_FAIL_STATE2 || next == 0) { break; } state = next; } /* * Add new states for the rest of the pattern bytes, 1 state per byte */ for (; n > 0; pattern++, n--) { if(s_verbose)printf(" add char='%c' state=%d NumStates=%d\n", *pattern, state, acsm->acsmNumStates ); acsm->acsmNumStates++; List_PutNextState(acsm,state,*pattern,acsm->acsmNumStates); state = acsm->acsmNumStates; } AddMatchListEntry (acsm, state, p ); if(s_verbose)printf(" End AddPatternStates: acsmNumStates=%d\n",acsm->acsmNumStates); } /* * Build A Non-Deterministic Finite Automata * The keyword state table must already be built, via AddPatternStates(). */ static void Build_NFA (ACSM_STRUCT2 * acsm) { int r, s, i; QUEUE q, *queue = &q; acstate_t * FailState = acsm->acsmFailState; ACSM_PATTERN2 ** MatchList = acsm->acsmMatchList; ACSM_PATTERN2 * mlist,* px; bool *queue_array; /* Init a Queue */ queue_init (queue); queue_array = (bool *) calloc( acsm->acsmNumStates, sizeof (bool)); /* Add the state 0 transitions 1st, the states at depth 1, fail to state 0 */ for (i = 0; i < acsm->acsmAlphabetSize; i++) { s = List_GetNextState2(acsm,0,i); if( s ) { if (!queue_array[s]) { queue_add(queue, s); queue_array[s] = true; } FailState[s] = 0; } } /* Build the fail state successive layer of transitions */ while (queue_count (queue) > 0) { r = queue_remove (queue); queue_array[r] = false; /* Find Final States for any Failure */ for (i = 0; i < acsm->acsmAlphabetSize; i++) { int fs, next; s = List_GetNextState(acsm,r,i); if( (acstate_t)s != ACSM_FAIL_STATE2 ) { if (!queue_array[s]) { queue_add(queue, s); queue_array[s] = true; } fs = FailState[r]; /* * Locate the next valid state for 'i' starting at fs */ while ((acstate_t)(next = List_GetNextState(acsm,fs,i)) == ACSM_FAIL_STATE2 ) { fs = FailState[fs]; } /* * Update 's' state failure state to point to the next valid state */ FailState[s] = next; /* * Copy 'next'states MatchList to 's' states MatchList, * we copy them so each list can be AC_FREE'd later, * else we could just manipulate pointers to fake the copy. */ for( mlist = MatchList[next]; mlist; mlist = mlist->next) { px = CopyMatchListEntry (mlist); /* Insert at front of MatchList */ px->next = MatchList[s]; MatchList[s] = px; } } } } /* Clean up the queue */ queue_free (queue); free(queue_array); if( s_verbose)printf("End Build_NFA: NumStates=%d\n",acsm->acsmNumStates); } /* * Build Deterministic Finite Automata from the NFA */ static void Convert_NFA_To_DFA (ACSM_STRUCT2 * acsm) { int i, r, s, cFailState; QUEUE q, *queue = &q; acstate_t * FailState = acsm->acsmFailState; trans_node_t **acsmTransTableOpt; bool *queue_array; /* Init a Queue */ queue_init (queue); queue_array = (bool*) calloc( acsm->acsmNumStates, sizeof (bool)); acsmTransTableOpt = (trans_node_t**) calloc(acsm->acsmAlphabetSize * acsm->acsmNumStates, sizeof(trans_node_t*)); for(i=0; iacsmNumStates; i++) { trans_node_t * t = acsm->acsmTransTable[i]; while( t ) { int index = i * acsm->acsmAlphabetSize + t->key; acsmTransTableOpt[index] = t; t=t->next; } } /* Add the state 0 transitions 1st */ for(i=0; iacsmAlphabetSize; i++) { s = List_GetNextStateOpt(acsm, acsmTransTableOpt, 0, i); if ( s != 0 ) { if (!queue_array[s]) { queue_add (queue, s); queue_array[s] = true; } } } /* Start building the next layer of transitions */ while( queue_count(queue) > 0 ) { r = queue_remove(queue); queue_array[r] = false; /* Process this states layer */ for (i = 0; i < acsm->acsmAlphabetSize; i++) { s = List_GetNextStateOpt(acsm, acsmTransTableOpt, r, i); if( (acstate_t)s != ACSM_FAIL_STATE2 && s!= 0) { if (!queue_array[s]) { queue_add(queue, s); queue_array[s] = true; } } else { cFailState = List_GetNextStateOpt(acsm, acsmTransTableOpt,FailState[r],i); if( cFailState != 0 && (acstate_t)cFailState != ACSM_FAIL_STATE2 ) { List_PutNextStateOpt(acsm,acsmTransTableOpt,r,i,cFailState); } } } } /* Clean up the queue */ queue_free (queue); free(acsmTransTableOpt); free(queue_array); if(s_verbose)printf("End Convert_NFA_To_DFA: NumStates=%d\n",acsm->acsmNumStates); } /* * * Convert a row lists for the state table to a full vector format * */ static int Conv_List_To_Full( ACSM_STRUCT2 *acsm ) { acstate_t k; acstate_t *p; acstate_t **NextState = acsm->acsmNextState; for (k = 0; k < (acstate_t)acsm->acsmNumStates; k++) { p = AC_MALLOC_DFA(acsm->sizeofstate * (acsm->acsmAlphabetSize + 2), acsm->sizeofstate); if (p == NULL) return -1; switch (acsm->sizeofstate) { case 1: List_ConvToFull(acsm, k, (acstate_t *)((uint8_t *)p + 2)); *((uint8_t *)p) = ACF_FULL; *((uint8_t *)p + 1) = 0; break; case 2: List_ConvToFull(acsm, k, (acstate_t *)((uint16_t *)p + 2)); *((uint16_t *)p) = ACF_FULL; *((uint16_t *)p + 1) = 0; break; default: List_ConvToFull(acsm, k, (p + 2)); p[0] = ACF_FULL; p[1] = 0; /* no matches yet */ break; } NextState[k] = p; /* now we have a full format row vector */ } return 0; } /* * Convert DFA memory usage from list based storage to a sparse-row storage. * * The Sparse format allows each row to be either full or sparse formatted. If the sparse row has * too many transitions, performance or space may dictate that we use the standard full formatting * for the row. More than 5 or 10 transitions per state ought to really whack performance. So the * user can specify the max state transitions per state allowed in the sparse format. * * Standard Full Matrix Format * --------------------------- * acstate_t ** NextState ( 1st index is row/state, 2nd index is column=event/input) * * example: * * events -> a b c d e f g h i j k l m n o p * states * N 1 7 0 0 0 3 0 0 0 0 0 0 0 0 0 0 * * Sparse Format, each row : Words Value * 1-1 fmt(0-full,1-sparse,2-banded,3-sparsebands) * 2-2 bool match flag (indicates this state has pattern matches) * 3-3 sparse state count ( # of input/next-state pairs ) * 4-3+2*cnt 'input,next-state' pairs... each sizof(acstate_t) * * above example case yields: * Full Format: 0, 1 7 0 0 0 3 0 0 0 0 0 0 0 0 0 0 ... * Sparse format: 1, 3, 'a',1,'b',7,'f',3 - uses 2+2*ntransitions (non-default transitions) */ static int Conv_Full_DFA_To_Sparse(ACSM_STRUCT2 * acsm) { int cnt, m, k, i; acstate_t * p, state, maxstates=0; acstate_t ** NextState = acsm->acsmNextState; acstate_t full[MAX_ALPHABET_SIZE]; for(k=0;kacsmNumStates;k++) { cnt=0; memset(full, 0, acsm->sizeofstate * acsm->acsmAlphabetSize); List_ConvToFull(acsm, (acstate_t)k, full ); for (i = 0; i < acsm->acsmAlphabetSize; i++) { state = full[i]; if( state != 0 && state != ACSM_FAIL_STATE2 ) cnt++; } if( cnt > 0 ) maxstates++; if( k== 0 || cnt > acsm->acsmSparseMaxRowNodes ) { p = AC_MALLOC_DFA(sizeof(acstate_t)*(acsm->acsmAlphabetSize+2), sizeof(acstate_t)); if(!p) return -1; p[0] = ACF_FULL; p[1] = 0; memcpy(&p[2],full,acsm->acsmAlphabetSize*sizeof(acstate_t)); } else { p = AC_MALLOC_DFA(sizeof(acstate_t)*(3+2*cnt), sizeof(acstate_t)); if(!p) return -1; m = 0; p[m++] = ACF_SPARSE; p[m++] = 0; /* no matches */ p[m++] = cnt; for(i = 0; i < acsm->acsmAlphabetSize ; i++) { state = full[i]; if( state != 0 && state != ACSM_FAIL_STATE2 ) { p[m++] = i; p[m++] = state; } } } NextState[k] = p; /* now we are a sparse formatted state transition array */ } return 0; } /* Convert Full matrix to Banded row format. Word values 1 2 -> banded 2 n number of values 3 i index of 1st value (0-256) 4 - 3+n next-state values at each index */ static int Conv_Full_DFA_To_Banded(ACSM_STRUCT2 * acsm) { int first = -1, last; acstate_t * p, state, full[MAX_ALPHABET_SIZE]; acstate_t ** NextState = acsm->acsmNextState; int cnt,m,k,i; for(k=0;kacsmNumStates;k++) { cnt=0; memset(full, 0, acsm->sizeofstate * acsm->acsmAlphabetSize); List_ConvToFull(acsm, (acstate_t)k, full ); first=-1; last =-2; for (i = 0; i < acsm->acsmAlphabetSize; i++) { state = full[i]; if( state !=0 && state != ACSM_FAIL_STATE2 ) { if( first < 0 ) first = i; last = i; } } /* calc band width */ cnt= last - first + 1; p = AC_MALLOC_DFA(sizeof(acstate_t)*(4+cnt), sizeof(acstate_t)); if(!p) return -1; m = 0; p[m++] = ACF_BANDED; p[m++] = 0; /* no matches */ p[m++] = cnt; p[m++] = first; for(i = first; i <= last; i++) { p[m++] = full[i]; } NextState[k] = p; /* now we are a banded formatted state transition array */ } return 0; } /* * Convert full matrix to Sparse Band row format. * * next - Full formatted row of next states * asize - size of alphabet * zcnt - max number of zeros in a run of zeros in any given band. * * Word Values * 1 ACF_SPARSEBANDS * 2 number of bands * repeat 3 - 5+ ....once for each band in this row. * 3 number of items in this band* 4 start index of this band * 5- next-state values in this band... */ static int calcSparseBands( acstate_t * next, int * begin, int * end, int asize, int zmax ) { int i, nbands,zcnt,last=0; acstate_t state; nbands=0; for( i=0; i zmax ) break; } else { zcnt=0; last = i; } } end[nbands++] = last; } } return nbands; } /* * Sparse Bands * * Row Format: * Word * 1 SPARSEBANDS format indicator * 2 bool indicates a pattern match in this state * 3 number of sparse bands * 4 number of elements in this band * 5 start index of this band * 6- list of next states * * m number of elements in this band * m+1 start index of this band * m+2- list of next states */ static int Conv_Full_DFA_To_SparseBands(ACSM_STRUCT2 * acsm) { acstate_t * p; acstate_t ** NextState = acsm->acsmNextState; int cnt,m,k,i,zcnt=acsm->acsmSparseMaxZcnt; int band_begin[MAX_ALPHABET_SIZE]; int band_end[MAX_ALPHABET_SIZE]; int nbands,j; acstate_t full[MAX_ALPHABET_SIZE]; for(k=0;kacsmNumStates;k++) { cnt=0; memset(full, 0, acsm->sizeofstate * acsm->acsmAlphabetSize); List_ConvToFull(acsm, (acstate_t)k, full ); nbands = calcSparseBands( full, band_begin, band_end, acsm->acsmAlphabetSize, zcnt ); /* calc band width space*/ cnt = 3; for(i=0;i= MAX_ALPHABET_SIZE) { AC_FREE_DFA(p, sizeof(acstate_t)*(cnt), sizeof(acstate_t)); return -1; } p[m++] = full[j]; /* some states may be state zero */ } } NextState[k] = p; /* now we are a sparse-banded formatted state transition array */ } return 0; } static void Print_DFA_MatchList( ACSM_STRUCT2 * acsm, int state ) { ACSM_PATTERN2 * mlist; for (mlist = acsm->acsmMatchList[state]; mlist; mlist = mlist->next) { printf("%.*s ", mlist->n, mlist->patrn); } } /* * */ static void Print_DFA(ACSM_STRUCT2 * acsm) { int k,i; acstate_t * p, state, n, fmt, index, nb; acstate_t ** NextState = acsm->acsmNextState; printf("Print DFA - %d active states\n",acsm->acsmNumStates); for(k=0;kacsmNumStates;k++) { p = NextState[k]; if( !p ) continue; fmt = *p++; printf("state %3d, fmt=%d: ",k,fmt); if( fmt ==ACF_SPARSE ) { n = *p++; for( ; n>0; n--, p+=2 ) { if( isascii((int)p[0]) && isprint((int)p[0]) ) printf("%3c->%-5d\t",p[0],p[1]); else printf("%3d->%-5d\t",p[0],p[1]); } } else if( fmt ==ACF_BANDED ) { n = *p++; index = *p++; for( ; n>0; n--, p++ ) { if( isascii((int)p[0]) && isprint((int)p[0]) ) printf("%3c->%-5d\t",index++,p[0]); else printf("%3d->%-5d\t",index++,p[0]); } } else if( fmt ==ACF_SPARSEBANDS ) { nb = *p++; for(i=0;(acstate_t)i0; n--, p++ ) { if( isascii((int)index) && isprint((int)index) ) printf("%3c->%-5d\t",index++,p[0]); else printf("%3d->%-5d\t",index++,p[0]); } } } else if( fmt == ACF_FULL ) { for( i=0; iacsmAlphabetSize; i++ ) { state = p[i]; if( state != 0 && state != ACSM_FAIL_STATE2 ) { if( isascii(i) && isprint(i) ) printf("%3c->%-5d\t",i,state); else printf("%3d->%-5d\t",i,state); } } } Print_DFA_MatchList( acsm, k); printf("\n"); } } /* * Write a state table to disk */ /* static void Write_DFA(ACSM_STRUCT2 * acsm, char * f) { int k,i; acstate_t * p, n, fmt, index, nb, bmatch; acstate_t ** NextState = acsm->acsmNextState; FILE * fp; printf("Dump DFA - %d active states\n",acsm->acsmNumStates); fp = fopen(f,"wb"); if(!fp) { printf("WARNING: could not write dfa to file - %s.\n",f); return; } fwrite( &acsm->acsmNumStates, 4, 1, fp); for(k=0;kacsmNumStates;k++) { p = NextState[k]; if( !p ) continue; fmt = *p++; bmatch = *p++; fwrite( &fmt, sizeof(acstate_t), 1, fp); fwrite( &bmatch, sizeof(acstate_t), 1, fp); if( fmt ==ACF_SPARSE ) { n = *p++; fwrite( &n, sizeof(acstate_t), 1, fp); fwrite( p, n*2*sizeof(acstate_t), 1, fp); } else if( fmt ==ACF_BANDED ) { n = *p++; fwrite( &n, sizeof(acstate_t), 1, fp); index = *p++; fwrite( &index, sizeof(acstate_t), 1, fp); fwrite( p, sizeof(acstate_t), n, fp); } else if( fmt ==ACF_SPARSEBANDS ) { nb = *p++; fwrite( &nb, sizeof(acstate_t), 1, fp); for(i=0;iacsmAlphabetSize, fp); } //Print_DFA_MatchList( acsm, k); } fclose(fp); } */ /* * * Convert an NFA or DFA row from sparse to full format * and store into the 'full' buffer. * * returns: * 0 - failed, no state transitions * *p - pointer to 'full' buffer * */ /* static acstate_t * acsmConvToFull(ACSM_STRUCT2 * acsm, acstate_t k, acstate_t * full ) { int i; acstate_t * p, n, fmt, index, nb, bmatch; acstate_t ** NextState = acsm->acsmNextState; p = NextState[k]; if( !p ) return 0; fmt = *p++; bmatch = *p++; if( fmt ==ACF_SPARSE ) { n = *p++; for( ; n>0; n--, p+=2 ) { full[ p[0] ] = p[1]; } } else if( fmt ==ACF_BANDED ) { n = *p++; index = *p++; for( ; n>0; n--, p++ ) { full[ index++ ] = p[0]; } } else if( fmt ==ACF_SPARSEBANDS ) { nb = *p++; for(i=0;i0; n--, p++ ) { full[ index++ ] = p[0]; } } } else if( fmt == ACF_FULL ) { memcpy(full,p,acsm->acsmAlphabetSize*sizeof(acstate_t)); } return full; } */ /* * Select the desired storage mode */ int acsmSelectFormat2( ACSM_STRUCT2 * acsm, int m ) { switch( m ) { case ACF_FULL: case ACF_SPARSE: case ACF_BANDED: case ACF_SPARSEBANDS: case ACF_FULLQ: acsm->acsmFormat = m; break; default: return -1; } return 0; } /* * */ void acsmSetMaxSparseBandZeros2( ACSM_STRUCT2 * acsm, int n ) { acsm->acsmSparseMaxZcnt = n; } /* * */ void acsmSetMaxSparseElements2( ACSM_STRUCT2 * acsm, int n ) { acsm->acsmSparseMaxRowNodes = n; } /* * */ int acsmSelectFSA2( ACSM_STRUCT2 * acsm, int m ) { switch( m ) { case FSA_TRIE: case FSA_NFA: case FSA_DFA: acsm->acsmFSA = m; default: return -1; } } /* * */ int acsmSetAlphabetSize2( ACSM_STRUCT2 * acsm, int n ) { if( n <= MAX_ALPHABET_SIZE ) { acsm->acsmAlphabetSize = n; } else { return -1; } return 0; } /* * Create a new AC state machine */ ACSM_STRUCT2 * acsmNew2 (void (*userfree)(void *p), void (*optiontreefree)(void **p), void (*neg_list_free)(void **p)) { ACSM_STRUCT2 * p; init_xlatcase (); p = (ACSM_STRUCT2 *)AC_MALLOC(sizeof (ACSM_STRUCT2), ACSM2_MEMORY_TYPE__NONE); MEMASSERT (p, "acsmNew"); if (p) { memset (p, 0, sizeof (ACSM_STRUCT2)); /* Some defaults */ p->acsmFSA = FSA_DFA; p->acsmFormat = ACF_FULL;//ACF_BANDED; p->acsmAlphabetSize = 256; p->acsmSparseMaxRowNodes = 256; p->acsmSparseMaxZcnt = 10; p->userfree = userfree; p->optiontreefree = optiontreefree; p->neg_list_free = neg_list_free; } return p; } /* * Add a pattern to the list of patterns for this state machine * */ int acsmAddPattern2 (ACSM_STRUCT2 * p, unsigned char *pat, int n, int nocase, int offset, int depth, int negative, void * id, int iid) { ACSM_PATTERN2 * plist; plist = (ACSM_PATTERN2 *) AC_MALLOC(sizeof (ACSM_PATTERN2), ACSM2_MEMORY_TYPE__PATTERN); MEMASSERT (plist, "acsmAddPattern"); plist->patrn = (unsigned char *)AC_MALLOC(n, ACSM2_MEMORY_TYPE__PATTERN); MEMASSERT (plist->patrn, "acsmAddPattern"); ConvertCaseEx(plist->patrn, pat, n); plist->casepatrn = (unsigned char *)AC_MALLOC(n, ACSM2_MEMORY_TYPE__PATTERN); MEMASSERT (plist->casepatrn, "acsmAddPattern"); memcpy (plist->casepatrn, pat, n); plist->n = n; plist->nocase = nocase; plist->offset = offset; plist->depth = depth; plist->negative = negative; plist->iid = iid; plist->udata = id; plist->next = p->acsmPatterns; p->acsmPatterns = plist; p->numPatterns++; 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 * data) { 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->offset = 0; plist->depth = 0; 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. */ static void acsmUpdateMatchStates( ACSM_STRUCT2 *acsm ) { acstate_t state; acstate_t **NextState = acsm->acsmNextState; ACSM_PATTERN2 **MatchList = acsm->acsmMatchList; for (state = 0; state < (acstate_t)acsm->acsmNumStates; state++) { acstate_t *p = NextState[state]; if (MatchList[state]) { switch (acsm->sizeofstate) { case 1: *((uint8_t *)p + 1) = 1; break; case 2: *((uint16_t *)p + 1) = 1; break; default: p[1] = 1; break; } summary.num_match_states++; } } } static int acsmBuildMatchStateTrees2( ACSM_STRUCT2 * acsm, int (*build_tree)(void * id, void **existing_tree), int (*neg_list_func)(void *id, void **list) ) { int i, cnt = 0; ACSM_PATTERN2 ** MatchList = acsm->acsmMatchList; ACSM_PATTERN2 * mlist; /* Find the states that have a MatchList */ for (i = 0; i < acsm->acsmNumStates; i++) { for ( mlist=MatchList[i]; mlist!=NULL; mlist=mlist->next ) { if (mlist->udata) { if (mlist->negative) { neg_list_func(mlist->udata, &MatchList[i]->neg_list); } else { build_tree(mlist->udata, &MatchList[i]->rule_option_tree); } } cnt++; } if (MatchList[i]) { /* Last call to finalize the tree */ build_tree(NULL, &MatchList[i]->rule_option_tree); } } return cnt; } static int acsmBuildMatchStateTrees2WithSnortConf( struct _SnortConfig *sc, ACSM_STRUCT2 * acsm, int (*build_tree)(struct _SnortConfig *, void * id, void **existing_tree), int (*neg_list_func)(void *id, void **list) ) { int i, cnt = 0; ACSM_PATTERN2 ** MatchList = acsm->acsmMatchList; ACSM_PATTERN2 * mlist; /* Find the states that have a MatchList */ for (i = 0; i < acsm->acsmNumStates; i++) { for ( mlist=MatchList[i]; mlist!=NULL; mlist=mlist->next ) { if (mlist->udata) { if (mlist->negative) { neg_list_func(mlist->udata, &MatchList[i]->neg_list); } else { build_tree(sc, mlist->udata, &MatchList[i]->rule_option_tree); } } cnt++; } if (MatchList[i]) { /* Last call to finalize the tree */ build_tree(sc, NULL, &MatchList[i]->rule_option_tree); } } return cnt; } void acsmCompressStates( ACSM_STRUCT2 *acsm, int flag ) { if (acsm == NULL) return; acsm->compress_states = flag; } /* * Compile State Machine - NFA or DFA and Full or Banded or Sparse or SparseBands */ static inline int _acsmCompile2( ACSM_STRUCT2* acsm ) { ACSM_PATTERN2* plist; /* Count number of possible states */ for (plist = acsm->acsmPatterns; plist != NULL; plist = plist->next) acsm->acsmMaxStates += plist->n; acsm->acsmMaxStates++; /* one extra */ /* Alloc a List based State Transition table */ acsm->acsmTransTable = (trans_node_t**)AC_MALLOC(sizeof(trans_node_t*) * acsm->acsmMaxStates, ACSM2_MEMORY_TYPE__TRANSTABLE); MEMASSERT(acsm->acsmTransTable, "acsmCompile"); if (s_verbose) { printf("ACSMX-Max Memory-TransTable Setup: %d bytes, %d states, " "%d active states\n", acsm2_total_memory, acsm->acsmMaxStates, acsm->acsmNumStates); } /* Alloc a MatchList table - this has a lis tof pattern matches for each state, if any */ acsm->acsmMatchList = (ACSM_PATTERN2 **)AC_MALLOC(sizeof(ACSM_PATTERN2*) * acsm->acsmMaxStates, ACSM2_MEMORY_TYPE__MATCHLIST); MEMASSERT(acsm->acsmMatchList, "acsmCompile"); if (s_verbose) { printf("ACSMX-Max Memory- MatchList Table Setup: %d bytes, %d states, " "%d active states\n", acsm2_total_memory, acsm->acsmMaxStates, acsm->acsmNumStates); printf("ACSMX-Max Memory-Table Setup: %d bytes, %d states, %d active " "states\n", acsm2_total_memory, acsm->acsmMaxStates, acsm->acsmNumStates); } /* Initialize state zero as a branch */ acsm->acsmNumStates = 0; /* Add each Pattern to the State Table - This forms a keywords state table */ for (plist = acsm->acsmPatterns; plist != NULL; plist = plist->next) { summary.num_patterns++; summary.num_characters += plist->n; AddPatternStates(acsm, plist); } /* Add the 0'th state */ acsm->acsmNumStates++; if (acsm->compress_states) { if (acsm->acsmNumStates < UINT8_MAX) { acsm->sizeofstate = 1; summary.num_1byte_instances++; } else if (acsm->acsmNumStates < UINT16_MAX) { acsm->sizeofstate = 2; summary.num_2byte_instances++; } else { acsm->sizeofstate = 4; summary.num_4byte_instances++; } } else { acsm->sizeofstate = 4; } /* Alloc a failure table - this has a failure state, and a match list for each state */ acsm->acsmFailState = (acstate_t*)AC_MALLOC(sizeof(acstate_t) * acsm->acsmNumStates, ACSM2_MEMORY_TYPE__FAILSTATE); MEMASSERT(acsm->acsmFailState, "acsmCompile"); /* Alloc a separate state transition table == in state 's' due to event 'k', transition to 'next' state */ acsm->acsmNextState = (acstate_t**)AC_MALLOC_DFA(acsm->acsmNumStates * sizeof(acstate_t*), acsm->sizeofstate); MEMASSERT(acsm->acsmNextState, "acsmCompile-NextState"); if (s_verbose) { printf("ACSMX-Max Trie List Memory : %d bytes, %d states, %d " "active states\n", acsm2_total_memory, acsm->acsmMaxStates, acsm->acsmNumStates); List_PrintTransTable(acsm); } if ((acsm->acsmFSA == FSA_DFA) || (acsm->acsmFSA == FSA_NFA)) { /* Build the NFA */ if (s_verbose) printf("Build_NFA\n"); Build_NFA(acsm); if (s_verbose) { printf("NFA-Trans-Nodes: %d\n",acsm->acsmNumTrans); printf("ACSMX-Max NFA List Memory : %d bytes, %d states / %d " "active states\n", acsm2_total_memory, acsm->acsmMaxStates, acsm->acsmNumStates); List_PrintTransTable(acsm); } } if (acsm->acsmFSA == FSA_DFA) { /* Convert the NFA to a DFA */ if (s_verbose) printf("Convert_NFA_To_DFA\n"); Convert_NFA_To_DFA(acsm); if (s_verbose) { printf("DFA-Trans-Nodes: %d\n",acsm->acsmNumTrans); printf("ACSMX-Max NFA-DFA List Memory : %d bytes, %d states / %d " "active states\n", acsm2_total_memory, acsm->acsmMaxStates, acsm->acsmNumStates); List_PrintTransTable( acsm ); } } /* Select Final Transition Table Storage Mode */ if (s_verbose) { printf("Converting Transition Lists -> Transition table, fmt=%d\n", acsm->acsmFormat); } if (acsm->acsmFormat == ACF_SPARSE) { /* Convert DFA Full matrix to a Sparse matrix */ if (Conv_Full_DFA_To_Sparse(acsm)) return -1; if (s_verbose) { printf ("ACSMX-Max Memory-Sparse: %d bytes, %d states, %d " "active states\n", acsm2_total_memory, acsm->acsmMaxStates, acsm->acsmNumStates); Print_DFA(acsm); } } else if (acsm->acsmFormat == ACF_BANDED) { /* Convert DFA Full matrix to a Sparse matrix */ if (Conv_Full_DFA_To_Banded(acsm)) return -1; if (s_verbose) { printf("ACSMX-Max Memory-banded: %d bytes, %d states, %d " "active states\n", acsm2_total_memory, acsm->acsmMaxStates, acsm->acsmNumStates); Print_DFA(acsm); } } else if (acsm->acsmFormat == ACF_SPARSEBANDS) { /* Convert DFA Full matrix to a Sparse matrix */ if (Conv_Full_DFA_To_SparseBands(acsm)) return -1; if (s_verbose) { printf("ACSMX-Max Memory-sparse-bands: %d bytes, %d states, %d " "active states\n", acsm2_total_memory, acsm->acsmMaxStates, acsm->acsmNumStates); Print_DFA(acsm); } } else if ((acsm->acsmFormat == ACF_FULL) || (acsm->acsmFormat == ACF_FULLQ)) { if (Conv_List_To_Full(acsm)) return -1; if (s_verbose) { printf("ACSMX-Max Memory-Full: %d bytes, %d states, %d active " "states\n", acsm2_total_memory, acsm->acsmMaxStates, acsm->acsmNumStates); Print_DFA(acsm); } /* Don't need the FailState table anymore */ AC_FREE(acsm->acsmFailState, sizeof(acstate_t) * acsm->acsmNumStates, ACSM2_MEMORY_TYPE__FAILSTATE); acsm->acsmFailState = NULL; } /* load boolean match flags into state table */ acsmUpdateMatchStates(acsm); /* Free up the Table Of Transition Lists */ List_FreeTransTable(acsm); if (s_verbose) { printf("ACSMX-Max Memory-Final: %d bytes, %d states, %d active " "states\n", acsm2_total_memory, acsm->acsmMaxStates, acsm->acsmNumStates); } if (s_verbose) acsmPrintInfo2(acsm); /* Accrue Summary State Stats */ summary.num_states += acsm->acsmNumStates; summary.num_transitions += acsm->acsmNumTrans; summary.num_instances++; memcpy(&summary.acsm, acsm, sizeof(ACSM_STRUCT2)); return 0; } int acsmCompile2( ACSM_STRUCT2* acsm, int (*build_tree)(void* id, void** existing_tree), int (*neg_list_func)(void* id, void** list) ) { int rval; if ((rval = _acsmCompile2(acsm))) return rval; if (build_tree && neg_list_func) { acsmBuildMatchStateTrees2(acsm, build_tree, neg_list_func); } return 0; } int acsmCompile2WithSnortConf( struct _SnortConfig *sc, ACSM_STRUCT2* acsm, int (*build_tree)(struct _SnortConfig *, void* id, void** existing_tree), int (*neg_list_func)(void* id, void** list) ) { int rval; if ((rval = _acsmCompile2(acsm))) return rval; if (build_tree && neg_list_func) { acsmBuildMatchStateTrees2WithSnortConf(sc, acsm, build_tree, neg_list_func); } return 0; } /* * Get the NextState from the NFA, all NFA storage formats use this */ static inline acstate_t SparseGetNextStateNFA(acstate_t * ps, acstate_t state, unsigned input) { acstate_t fmt; acstate_t n; unsigned int index; int nb; fmt = *ps++; ps++; /* skip bMatchState */ switch( fmt ) { case ACF_BANDED: { n = ps[0]; index = ps[1]; if( input < index ) { if(state==0) { return 0; } else { return (acstate_t)ACSM_FAIL_STATE2; } } if( input >= index + n ) { if(state==0) { return 0; } else { return (acstate_t)ACSM_FAIL_STATE2; } } if( ps[input-index] == 0 ) { if( state != 0 ) { return ACSM_FAIL_STATE2; } } return (acstate_t) ps[input-index]; } case ACF_SPARSE: { n = *ps++; /* number of sparse index-value entries */ for( ; n>0 ; n-- ) { if( ps[0] > input ) /* cannot match the input, already a higher value than the input */ { return (acstate_t)ACSM_FAIL_STATE2; /* default state */ } else if( ps[0] == input ) { return ps[1]; /* next state */ } ps+=2; } if( state == 0 ) { return 0; } return ACSM_FAIL_STATE2; } case ACF_SPARSEBANDS: { nb = *ps++; /* number of bands */ while( nb > 0 ) /* for each band */ { n = *ps++; /* number of elements */ index = *ps++; /* 1st element value */ if( input < index ) { if( state != 0 ) { return (acstate_t)ACSM_FAIL_STATE2; } return (acstate_t)0; } if( (input >= index) && (input < (index + n)) ) { if( ps[input-index] == 0 ) { if( state != 0 ) { return ACSM_FAIL_STATE2; } } return (acstate_t) ps[input-index]; } nb--; ps += n; } if( state != 0 ) { return (acstate_t)ACSM_FAIL_STATE2; } return (acstate_t)0; } case ACF_FULL: case ACF_FULLQ: { if( ps[input] == 0 ) { if( state != 0 ) { return ACSM_FAIL_STATE2; } } return ps[input]; } } return 0; } /* * Get the NextState from the DFA Next State Transition table * Full and banded are supported separately, this is for * sparse and sparse-bands */ static inline acstate_t SparseGetNextStateDFA(acstate_t * ps, acstate_t state, unsigned input) { acstate_t n, nb; unsigned int index; switch( ps[0] ) { /* BANDED */ case ACF_BANDED: { /* n=ps[2] : number of entries in the band */ /* index=ps[3] : index of the 1st entry, sequential thereafter */ if( input < ps[3] ) return 0; if( input >= (unsigned)(ps[3]+ps[2]) ) return 0; return ps[4+input-ps[3]]; } /* FULL */ case ACF_FULL: { return ps[2+input]; } /* SPARSE */ case ACF_SPARSE: { n = ps[2]; /* number of entries/ key+next pairs */ ps += 3; for( ; n>0 ; n-- ) { if( input < ps[0] ) /* cannot match the input, already a higher value than the input */ { return (acstate_t)0; /* default state */ } else if( ps[0] == input ) { return ps[1]; /* next state */ } ps += 2; } return (acstate_t)0; } /* SPARSEBANDS */ case ACF_SPARSEBANDS: { nb = ps[2]; /* number of bands */ ps += 3; while( nb > 0 ) /* for each band */ { n = ps[0]; /* number of elements in this band */ index = ps[1]; /* start index/char of this band */ if( input < index ) { return (acstate_t)0; } if( (input < (index + n)) ) { return (acstate_t) ps[2+input-index]; } nb--; ps += 2 + n; } return (acstate_t)0; } } return 0; } /* * Search Text or Binary Data for Pattern matches * * Sparse & Sparse-Banded Matrix search */ static inline int acsmSearchSparseDFA(ACSM_STRUCT2 * acsm, unsigned char *Tx, int n, int (*Match)(void * id, void *tree, int index, void *data, void *neg_list), void *data, int* current_state ) { acstate_t state; ACSM_PATTERN2 * mlist; unsigned char * Tend; int nfound = 0; unsigned char * T, * Tc; int index; acstate_t ** NextState = acsm->acsmNextState; ACSM_PATTERN2 ** MatchList = acsm->acsmMatchList; Tc = Tx; T = Tx; Tend = T + n; if ( !current_state ) { return 0; } state = *current_state; for( ; T < Tend; T++ ) { state = SparseGetNextStateDFA ( NextState[state], state, xlatcase[*T] ); /* test if this state has any matching patterns */ if( NextState[state][1] ) { mlist = MatchList[state]; if (mlist) { index = T - mlist->n - Tc + 1; nfound++; if (Match (mlist->udata, mlist->rule_option_tree, index, data, mlist->neg_list) > 0) { *current_state = state; return nfound; } } } } *current_state = state; return nfound; } void acsmx2_print_qinfo(void) { #ifdef ACSMX2_TRACK_Q if( snort_conf->max_inq ) { LogMessage("mpse: queue size = %d, max possible = %d\n", snort_conf->max_inq, AC_MAX_INQ); LogMessage("mpse: queue flushes = " STDu64 "\n", snort_conf->tot_inq_flush ); LogMessage("mpse: queue inserts = " STDu64 "\n", snort_conf->tot_inq_inserts ); LogMessage("mpse: queue uinserts = " STDu64 "\n", snort_conf->tot_inq_uinserts ); } #endif } static inline void _init_queue( PMQ * b) { b->inq=0; b->inq_flush=0; } /* uniquely insert into q, should splay elements for performance */ static inline int _add_queue(PMQ * b, void * p ) { int i; #ifdef ACSMX2_TRACK_Q snort_conf->tot_inq_inserts++; #endif for(i=(int)(b->inq)-1;i>=0;i--) if( p == b->q[i] ) return 0; #ifdef ACSMX2_TRACK_Q snort_conf->tot_inq_uinserts++; #endif if( b->inq < AC_MAX_INQ ) { b->q[ b->inq++ ] = p; } if( b->inq == AC_MAX_INQ ) { #ifdef ACSMX2_TRACK_Q b->inq_flush++; #endif return 1; } return 0; } static inline unsigned _process_queue( PMQ * q, int (*Match)(void * id, void *tree, int index, void *data, void *neg_list), void *data ) { ACSM_PATTERN2 * mlist; unsigned int i; #ifdef ACSMX2_TRACK_Q if( q->inq > snort_conf->max_inq ) snort_conf->max_inq = q->inq; snort_conf->tot_inq_flush += q->inq_flush; #endif for( i=0; iinq; i++ ) { mlist = q->q[i]; if (mlist) { if (Match (mlist->udata, mlist->rule_option_tree, 0, data, mlist->neg_list) > 0) { q->inq = 0; return 1; } } } q->inq=0; return 0; } /* * Matching states are queued, duplicate matches are dropped, * and after the complete buffer scan, the queued matches are * processed. This improves cacheing performance, and reduces * duplicate rule processing. The queue is limited in size and * is flushed if it becomes full during the scan. This allows * simple insertions. Tracking queue ops is optional, as this can * impose a modest performance hit of a few percent. */ #define AC_SEARCH_Q \ for (; T < Tend; T++) \ { \ ps = NextState[state]; \ sindex = xlatcase[T[0]]; \ if (ps[1]) \ { \ if (MatchList[state]) \ { \ if (_add_queue(&acsm->q,MatchList[state])) \ { \ if (_process_queue(&acsm->q, Match,data)) \ { \ *current_state = state; \ return 1; \ } \ } \ } \ } \ state = ps[2 + sindex]; \ } static inline int acsmSearchSparseDFA_Full_q( ACSM_STRUCT2 *acsm, unsigned char *T, int n, int (*Match)(void * id, void *tree, int index, void *data, void *neg_list), void *data, int *current_state ) { unsigned char *Tend; int sindex; acstate_t state; ACSM_PATTERN2 **MatchList = acsm->acsmMatchList; Tend = T + n; if (current_state == NULL) return 0; _init_queue(&acsm->q); state = *current_state; switch (acsm->sizeofstate) { case 1: { uint8_t *ps; uint8_t **NextState = (uint8_t **)acsm->acsmNextState; AC_SEARCH_Q; } break; case 2: { uint16_t *ps; uint16_t **NextState = (uint16_t **)acsm->acsmNextState; AC_SEARCH_Q; } break; default: { acstate_t *ps; acstate_t **NextState = acsm->acsmNextState; AC_SEARCH_Q; } break; } *current_state = state; if (MatchList[state]) _add_queue(&acsm->q,MatchList[state]); _process_queue(&acsm->q,Match,data); return 0; } /* * Matching states are queued, duplicate matches are dropped, * and after the complete buffer scan, the queued matches are * processed. This improves cacheing performance, and reduces * duplicate rule processing. The queue is limited in size and * is flushed if it becomes full during the scan. This allows * simple insertions. Tracking queue ops is optional, as this can * impose a modest performance hit of a few percent. */ #define AC_SEARCH_Q_ALL \ for (; T < Tend; T++) \ { \ ps = NextState[state]; \ sindex = xlatcase[T[0]]; \ if (ps[1]) \ { \ for( mlist = MatchList[state]; \ mlist!= NULL; \ mlist = mlist->next ) \ { \ if( mlist->nocase || (memcmp (mlist->casepatrn, T - mlist->n, mlist->n ) == 0)) \ { \ if (_add_queue(&acsm->q,mlist)) \ { \ if (_process_queue(&acsm->q, Match,data)) \ { \ *current_state = state; \ return 1; \ } \ } \ } \ } \ } \ state = ps[2 + sindex]; \ } static inline int acsmSearchSparseDFA_Full_q_all( ACSM_STRUCT2 *acsm, const unsigned char *T, int n, int (*Match)(void * id, void *tree, int index, void *data, void *neg_list), void *data, int *current_state ) { const unsigned char *Tend; int sindex; acstate_t state; ACSM_PATTERN2 **MatchList = acsm->acsmMatchList; ACSM_PATTERN2 *mlist; Tend = T + n; if (current_state == NULL) return 0; _init_queue(&acsm->q); state = *current_state; switch (acsm->sizeofstate) { case 1: { uint8_t *ps; uint8_t **NextState = (uint8_t **)acsm->acsmNextState; AC_SEARCH_Q_ALL; } break; case 2: { uint16_t *ps; uint16_t **NextState = (uint16_t **)acsm->acsmNextState; AC_SEARCH_Q_ALL; } break; default: { acstate_t *ps; acstate_t **NextState = acsm->acsmNextState; AC_SEARCH_Q_ALL; } break; } *current_state = state; for( mlist = MatchList[state]; mlist!= NULL; mlist = mlist->next ) { if( mlist->nocase || (memcmp (mlist->casepatrn, T - mlist->n, mlist->n ) == 0)) { if (_add_queue(&acsm->q,mlist)) { if (_process_queue(&acsm->q, Match,data)) { *current_state = state; return 1; } } } } _process_queue(&acsm->q,Match,data); return 0; } /* * Full format DFA search * Do not change anything here without testing, caching and prefetching * performance is very sensitive to any changes. * * Perf-Notes: * 1) replaced ConvertCaseEx with inline xlatcase - this improves performance 5-10% * 2) using 'nocase' improves performance again by 10-15%, since memcmp is not needed * 3) */ #define AC_SEARCH \ for( ; T < Tend; T++ ) \ { \ ps = NextState[ state ]; \ sindex = xlatcase[T[0]]; \ if (ps[1]) \ { \ mlist = MatchList[state]; \ if (mlist) \ { \ index = T - mlist->n - Tx; \ nfound++; \ if (Match (mlist->udata, mlist->rule_option_tree, index, data, mlist->neg_list) > 0) \ { \ *current_state = state; \ return nfound; \ } \ } \ } \ state = ps[2u + sindex]; \ } static inline int acsmSearchSparseDFA_Full( ACSM_STRUCT2 *acsm, unsigned char *Tx, int n, int (*Match)(void * id, void *tree, int index, void *data, void *neg_list), void *data, int *current_state ) { ACSM_PATTERN2 *mlist; unsigned char *Tend; unsigned char *T; int index; int sindex; int nfound = 0; acstate_t state; ACSM_PATTERN2 **MatchList = acsm->acsmMatchList; T = Tx; Tend = Tx + n; if (current_state == NULL) return 0; state = *current_state; switch (acsm->sizeofstate) { case 1: { uint8_t *ps; uint8_t **NextState = (uint8_t **)acsm->acsmNextState; AC_SEARCH; } break; case 2: { uint16_t *ps; uint16_t **NextState = (uint16_t **)acsm->acsmNextState; AC_SEARCH; } break; default: { acstate_t *ps; acstate_t **NextState = acsm->acsmNextState; AC_SEARCH; } break; } /* Check the last state for a pattern match */ mlist = MatchList[state]; if (mlist) { index = T - mlist->n - Tx; nfound++; if (Match(mlist->udata, mlist->rule_option_tree, index, data, mlist->neg_list) > 0) { *current_state = state; return nfound; } } *current_state = state; return nfound; } /* * Full format DFA search * Do not change anything here without testing, caching and prefetching * performance is very sensitive to any changes. * * Perf-Notes: * 1) replaced ConvertCaseEx with inline xlatcase - this improves performance 5-10% * 2) using 'nocase' improves performance again by 10-15%, since memcmp is not needed * 3) */ #define AC_SEARCH_ALL \ for( ; T < Tend; T++ ) \ { \ ps = NextState[ state ]; \ sindex = xlatcase[T[0]]; \ if (ps[1]) \ { \ for( mlist = MatchList[state]; \ mlist!= NULL; \ mlist = mlist->next ) \ { \ index = T - mlist->n - Tx; \ if( mlist->nocase || (memcmp (mlist->casepatrn, Tx + index, mlist->n ) == 0)) \ { \ nfound++; \ if (Match (mlist->udata, mlist->rule_option_tree, index, data, mlist->neg_list) > 0) \ { \ *current_state = state; \ return nfound; \ } \ } \ } \ } \ state = ps[2u + sindex]; \ } static inline int acsmSearchSparseDFA_Full_All( ACSM_STRUCT2 *acsm, const unsigned char *Tx, int n, int (*Match)(void * id, void *tree, int index, void *data, void *neg_list), void *data, int *current_state ) { ACSM_PATTERN2 *mlist; const unsigned char * Tend; const unsigned char * T; int index; int sindex; int nfound = 0; acstate_t state; ACSM_PATTERN2 **MatchList = acsm->acsmMatchList; T = Tx; Tend = Tx + n; if (current_state == NULL) return 0; state = *current_state; switch (acsm->sizeofstate) { case 1: { uint8_t *ps; uint8_t **NextState = (uint8_t **)acsm->acsmNextState; AC_SEARCH_ALL; } break; case 2: { uint16_t *ps; uint16_t **NextState = (uint16_t **)acsm->acsmNextState; AC_SEARCH_ALL; } break; default: { acstate_t *ps; acstate_t **NextState = acsm->acsmNextState; AC_SEARCH_ALL; } break; } /* Check the last state for a pattern match */ for( mlist = MatchList[state]; mlist!= NULL; mlist = mlist->next ) { index = T - mlist->n - Tx; if( mlist->nocase || (memcmp (mlist->casepatrn, Tx + index, mlist->n) == 0)) { nfound++; if (Match(mlist->udata, mlist->rule_option_tree, index, data, mlist->neg_list) > 0) { *current_state = state; return nfound; } } } *current_state = state; return nfound; } /* * Banded-Row format DFA search * Do not change anything here, caching and prefetching * performance is very sensitive to any changes. * * ps[0] = storage fmt * ps[1] = bool match flag * ps[2] = # elements in band * ps[3] = index of 1st element */ static inline int acsmSearchSparseDFA_Banded(ACSM_STRUCT2 * acsm, unsigned char *Tx, int n, int (*Match)(void * id, void *tree, int index, void *data, void *neg_list), void *data, int* current_state ) { acstate_t state; unsigned char * Tend; unsigned char * T; int sindex; int index; acstate_t ** NextState = acsm->acsmNextState; ACSM_PATTERN2 ** MatchList = acsm->acsmMatchList; ACSM_PATTERN2 * mlist; acstate_t * ps; int nfound = 0; T = Tx; Tend = T + n; if ( !current_state ) { return 0; } state = *current_state; for( ; T < Tend; T++ ) { ps = NextState[state]; sindex = xlatcase[ T[0] ]; /* test if this state has any matching patterns */ if( ps[1] ) { mlist = MatchList[state]; if (mlist) { index = T - mlist->n - Tx; nfound++; if (Match (mlist->udata, mlist->rule_option_tree, index, data, mlist->neg_list) > 0) { *current_state = state; return nfound; } } } if( (acstate_t)sindex < ps[3] ) state = 0; else if( (acstate_t)sindex >= (ps[3] + ps[2]) ) state = 0; else state = ps[ 4u + sindex - ps[3] ]; } /* Check the last state for a pattern match */ mlist = MatchList[state]; if (mlist) { index = T - mlist->n - Tx; nfound++; if (Match (mlist->udata, mlist->rule_option_tree, index, data, mlist->neg_list) > 0) { *current_state = state; return nfound; } } return nfound; } /* * Search Text or Binary Data for Pattern matches * * Sparse Storage Version */ static inline int acsmSearchSparseNFA(ACSM_STRUCT2 * acsm, unsigned char *Tx, int n, int (*Match)(void * id, void *tree, int index, void *data, void *neg_list), void *data, int* current_state ) { acstate_t state; ACSM_PATTERN2 * mlist; unsigned char * Tend; int nfound = 0; unsigned char * T; int index; acstate_t ** NextState= acsm->acsmNextState; acstate_t * FailState= acsm->acsmFailState; ACSM_PATTERN2 ** MatchList = acsm->acsmMatchList; unsigned char Tchar; T = Tx; Tend = T + n; if ( !current_state ) { return 0; } state = *current_state; for( ; T < Tend; T++ ) { acstate_t nstate; Tchar = xlatcase[ *T ]; while( (nstate=SparseGetNextStateNFA(NextState[state],state,Tchar))==ACSM_FAIL_STATE2 ) state = FailState[state]; state = nstate; mlist = MatchList[state]; if (mlist) { index = T - mlist->n - Tx; nfound++; if (Match (mlist->udata, mlist->rule_option_tree, index, data, mlist->neg_list) > 0) { *current_state = state; return nfound; } } } return nfound; } /* * Search Function */ int acsmSearch2(ACSM_STRUCT2 * acsm, unsigned char *Tx, int n, int (*Match)(void * id, void *tree, int index, void *data, void *neg_list), void *data, int* current_state ) { switch( acsm->acsmFSA ) { case FSA_DFA: if( acsm->acsmFormat == ACF_FULL ) { return acsmSearchSparseDFA_Full( acsm, Tx, n, Match, data, current_state ); } else if( acsm->acsmFormat == ACF_FULLQ ) { return acsmSearchSparseDFA_Full_q( acsm, Tx, n, Match, data, current_state ); } else if( acsm->acsmFormat == ACF_BANDED ) { return acsmSearchSparseDFA_Banded( acsm, Tx, n, Match, data, current_state ); } else { return acsmSearchSparseDFA( acsm, Tx, n, Match, data, current_state ); } case FSA_NFA: return acsmSearchSparseNFA( acsm, Tx, n, Match, data, current_state ); case FSA_TRIE: return 0; } return 0; } /* * Search Function */ int acsmSearchAll2(ACSM_STRUCT2 * acsm, unsigned char *Tx, int n, int (*Match)(void * id, void *tree, int index, void *data, void *neg_list), void *data, int* current_state ) { switch( acsm->acsmFSA ) { case FSA_DFA: if( acsm->acsmFormat == ACF_FULL ) { return acsmSearchSparseDFA_Full_All( acsm, Tx, n, Match, data, current_state ); } else if( acsm->acsmFormat == ACF_FULLQ ) { return acsmSearchSparseDFA_Full_q_all( acsm, Tx, n, Match, data, current_state ); } else if( acsm->acsmFormat == ACF_BANDED ) { return acsmSearchSparseDFA_Banded( acsm, Tx, n, Match, data, current_state ); } else { return acsmSearchSparseDFA( acsm, Tx, n, Match, data, current_state ); } case FSA_NFA: return acsmSearchSparseNFA( acsm, Tx, n, Match, data, current_state ); case FSA_TRIE: return 0; } return 0; } /* * Free all memory */ void acsmFree2( ACSM_STRUCT2 *acsm ) { int i; ACSM_PATTERN2 * mlist, *ilist, *plist; /* For AC_FREE don't really care at this point about stats */ for (i = 0; i < acsm->acsmNumStates; i++) { mlist = acsm->acsmMatchList[i]; while (mlist) { ilist = mlist; mlist = mlist->next; if (ilist->rule_option_tree && acsm->optiontreefree) acsm->optiontreefree(&(ilist->rule_option_tree)); if (ilist->neg_list && acsm->neg_list_free) acsm->neg_list_free(&(ilist->neg_list)); AC_FREE(ilist, 0, ACSM2_MEMORY_TYPE__NONE); } AC_FREE_DFA(acsm->acsmNextState[i], 0, 0); } for (plist = acsm->acsmPatterns; plist; ) { ACSM_PATTERN2 *tmpPlist = plist->next; if (acsm->userfree && (plist->udata != NULL)) acsm->userfree(plist->udata); AC_FREE(plist->patrn, 0, ACSM2_MEMORY_TYPE__NONE); AC_FREE(plist->casepatrn, 0, ACSM2_MEMORY_TYPE__NONE); AC_FREE(plist, 0, ACSM2_MEMORY_TYPE__NONE); plist = tmpPlist; } AC_FREE_DFA(acsm->acsmNextState, 0, 0); AC_FREE(acsm->acsmFailState, 0, ACSM2_MEMORY_TYPE__NONE); AC_FREE(acsm->acsmMatchList, 0, ACSM2_MEMORY_TYPE__NONE); AC_FREE(acsm, 0, ACSM2_MEMORY_TYPE__NONE); } int acsmPatternCount2 ( ACSM_STRUCT2 * acsm ) { return acsm->numPatterns; } /* * */ void acsmPrintInfo2( ACSM_STRUCT2 * p) { char * sf[]={ "Full Matrix", "Sparse Matrix", "Banded Matrix", "Sparse Banded Matrix", "Full-Q Matrix" }; char * fsa[]={ "TRIE", "NFA", "DFA" }; printf("+--[Pattern Matcher:Aho-Corasick]-----------------------------\n"); printf("| Alphabet Size : %d Chars\n",p->acsmAlphabetSize); if (p->compress_states) printf("| Sizeof State : %d\n", p->sizeofstate); else printf("| Sizeof State : %d bytes\n",(int)(sizeof(acstate_t))); printf("| Storage Format : %s \n",sf[ p->acsmFormat ]); printf("| Sparse Row Nodes : %d Max\n",p->acsmSparseMaxRowNodes); printf("| Sparse Band Zeros: %d Max\n",p->acsmSparseMaxZcnt); printf("| Num States : %d\n",p->acsmNumStates); printf("| Num Transitions : %d\n",p->acsmNumTrans); printf("| State Density : %.1f%%\n",100.0*(double)p->acsmNumTrans/(p->acsmNumStates*p->acsmAlphabetSize)); printf("| Finite Automaton : %s\n", fsa[p->acsmFSA]); if( acsm2_total_memory < 1024*1024 ) printf("| Memory : %.2fKbytes\n", (float)acsm2_total_memory/1024 ); else printf("| Memory : %.2fMbytes\n", (float)acsm2_total_memory/(1024*1024) ); printf("+-------------------------------------------------------------\n"); /* Print_DFA(acsm); */ } /* * */ int acsmPrintDetailInfo2( ACSM_STRUCT2 * p ) { return 0; } /* * Global sumary of all info and all state machines built during this run * This feeds off of the last pattern groupd built within snort, * all groups use the same format, state size, etc.. * Combined with accrued stats, we get an average picture of things. */ int acsmPrintSummaryInfo2(void) { char * sf[]={ "Full", "Sparse", "Banded", "Sparse-Bands", "Full-Q" }; char * fsa[]={ "TRIE", "NFA", "DFA" }; ACSM_STRUCT2 * p = &summary.acsm; if( !summary.num_states ) return 0; LogMessage("+- [ Aho-Corasick Summary ] -------------------------------------\n"); LogMessage("| Storage Format : %s \n",sf[ p->acsmFormat ]); LogMessage("| Finite Automaton : %s\n", fsa[p->acsmFSA]); LogMessage("| Alphabet Size : %d Chars\n",p->acsmAlphabetSize); if (summary.acsm.compress_states) LogMessage("| Sizeof State : Variable (1,2,4 bytes)\n"); else LogMessage("| Sizeof State : %d bytes\n",(int)(sizeof(acstate_t))); LogMessage("| Instances : %u\n",summary.num_instances); if (summary.acsm.compress_states) { LogMessage("| 1 byte states : %u\n", summary.num_1byte_instances); LogMessage("| 2 byte states : %u\n", summary.num_2byte_instances); LogMessage("| 4 byte states : %u\n", summary.num_4byte_instances); } LogMessage("| Characters : %u\n",summary.num_characters); LogMessage("| States : %d\n",summary.num_states); LogMessage("| Transitions : %d\n",summary.num_transitions); LogMessage("| State Density : %.1f%%\n", 100.0*(double)summary.num_transitions/(summary.num_states*p->acsmAlphabetSize)); LogMessage("| Patterns : %u\n",summary.num_patterns); LogMessage("| Match States : %d\n",summary.num_match_states); if( acsm2_total_memory < 1024*1024 ) { LogMessage("| Memory (KB) : %.2f\n", (float)acsm2_total_memory/1024 ); if (acsm2_pattern_memory > 0) LogMessage("| Pattern : %.2f\n", (float)acsm2_pattern_memory/1024 ); if (acsm2_matchlist_memory > 0) LogMessage("| Match Lists : %.2f\n", (float)acsm2_matchlist_memory/1024 ); if (acsm2_transtable_memory > 0) LogMessage("| Transitions : %.2f\n", (float)acsm2_transtable_memory/1024 ); if (acsm2_failstate_memory > 0) LogMessage("| Fail States : %.2f\n", (float)acsm2_failstate_memory/1024 ); if (acsm2_dfa_memory > 0) { if (summary.acsm.compress_states) { LogMessage("| DFA\n"); LogMessage("| 1 byte states : %.2f\n", (float)acsm2_dfa1_memory/1024); LogMessage("| 2 byte states : %.2f\n", (float)acsm2_dfa2_memory/1024); LogMessage("| 4 byte states : %.2f\n", (float)acsm2_dfa4_memory/1024); } else { LogMessage("| DFA : %.2f\n", (float)acsm2_dfa_memory/1024 ); } } } else { LogMessage("| Memory (MB) : %.2f\n", (float)acsm2_total_memory/(1024*1024) ); if (acsm2_pattern_memory > 0) LogMessage("| Patterns : %.2f\n", (float)acsm2_pattern_memory/(1024*1024) ); if (acsm2_matchlist_memory > 0) LogMessage("| Match Lists : %.2f\n", (float)acsm2_matchlist_memory/(1024*1024) ); if (acsm2_transtable_memory > 0) LogMessage("| Transitions : %.2f\n", (float)acsm2_transtable_memory/(1024*1024) ); if (acsm2_failstate_memory > 0) LogMessage("| Fail States : %.2f\n", (float)acsm2_failstate_memory/(1024*1024) ); if (acsm2_dfa_memory > 0) { if (summary.acsm.compress_states) { LogMessage("| DFA\n"); LogMessage("| 1 byte states : %.2f\n", (float)acsm2_dfa1_memory/(1024*1024)); LogMessage("| 2 byte states : %.2f\n", (float)acsm2_dfa2_memory/(1024*1024)); LogMessage("| 4 byte states : %.2f\n", (float)acsm2_dfa4_memory/(1024*1024)); } else { LogMessage("| DFA : %.2f\n", (float)acsm2_dfa_memory/(1024*1024) ); } } } LogMessage("+----------------------------------------------------------------\n"); return 0; } #ifdef ACSMX2S_MAIN /* * Text Data Buffer */ unsigned char text[512]; /* * A Match is found */ int MatchFound (void* id, int index, void *data) { fprintf (stdout, "%s\n", (char *) id); return 0; } /* * */ int main (int argc, char **argv) { int i, nc, nocase = 0; ACSM_STRUCT2 * acsm; char * p; if (argc < 3) { fprintf (stderr,"Usage: %s search-text pattern +pattern... [flags]\n",argv[0]); fprintf (stderr," flags: -nfa -nocase -full -sparse -bands -sparsebands -z zcnt (sparsebands) -sparsetree -v\n"); exit (0); } acsm = acsmNew2 (); if( !acsm ) { printf("acsm-no memory\n"); exit(0); } strncpy (text, argv[1], sizeof(text) - 1); text[sizeof(text) - 1] = '\0'; acsm->acsmFormat = ACF_FULL; for (i = 1; i < argc; i++) { if (strcmp (argv[i], "-nocase") == 0){ nocase = 1; } if (strcmp (argv[i], "-v") == 0){ s_verbose=1; } if (strcmp (argv[i], "-full") == 0){ acsm->acsmFormat = ACF_FULL; } if (strcmp (argv[i], "-fullq") == 0){ acsm->acsmFormat = ACF_FULLQ; } if (strcmp (argv[i], "-sparse") == 0){ acsm->acsmFormat = ACF_SPARSE; acsm->acsmSparseMaxRowNodes = 10; } if (strcmp (argv[i], "-bands") == 0){ acsm->acsmFormat = ACF_BANDED; } if (strcmp (argv[i], "-sparsebands") == 0){ acsm->acsmFormat = ACF_SPARSEBANDS; acsm->acsmSparseMaxZcnt = 10; } if (strcmp (argv[i], "-z") == 0){ acsm->acsmSparseMaxZcnt = atoi(argv[++i]); } if (strcmp (argv[i], "-nfa") == 0){ acsm->acsmFSA = FSA_NFA; } if (strcmp (argv[i], "-dfa") == 0){ acsm->acsmFSA = FSA_DFA; } if (strcmp (argv[i], "-trie") == 0){ acsm->acsmFSA = FSA_TRIE; } } for (i = 2; i < argc; i++) { if (argv[i][0] == '-') continue; p = argv[i]; if ( *p == '+') { nc=1; p++; } else { nc = nocase; } acsmAddPattern2 (acsm, p, strlen(p), nc, 0, 0,(void*)p, i - 2); } if(s_verbose)printf("Patterns added\n"); Print_DFA (acsm); acsmCompile2 (acsm); Write_DFA(acsm, "acsmx2-snort.dfa") ; if(s_verbose) printf("Patterns compiled--written to file.\n"); acsmPrintInfo2 ( acsm ); acsmSearch2 (acsm, text, strlen (text), MatchFound, (void *)0 ); acsmFree2 (acsm); printf ("normal pgm end\n"); return (0); } #endif /* */ snort-2.9.15.1/src/sfutil/acsmx2.h0000644000175200017520000001312213571422607013512 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2004-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* ** ACSMX2.H ** ** Version 2.0 ** ** Author: Marc Norton */ #include #include #include #ifndef ACSMX2S_H #define ACSMX2S_H /* * DEFINES and Typedef's */ #define MAX_ALPHABET_SIZE 256 /* FAIL STATE for 1,2,or 4 bytes for state transitions Uncomment this define to use 32 bit state values #define AC32 */ #define AC32 #ifdef AC32 typedef unsigned int acstate_t; #define ACSM_FAIL_STATE2 0xffffffff #else typedef unsigned short acstate_t; #define ACSM_FAIL_STATE2 0xffff #endif /* * */ typedef struct _acsm_pattern2 { struct _acsm_pattern2 *next; unsigned char *patrn; unsigned char *casepatrn; int n; int nocase; int offset; int depth; int negative; void *udata; int iid; void * rule_option_tree; void * neg_list; } ACSM_PATTERN2; /* * transition nodes - either 8 or 12 bytes */ typedef struct trans_node_s { acstate_t key; /* The character that got us here - sized to keep structure aligned on 4 bytes */ /* to better the caching opportunities. A value that crosses the cache line */ /* forces an expensive reconstruction, typing this as acstate_t stops that. */ acstate_t next_state; /* */ struct trans_node_s * next; /* next transition for this state */ } trans_node_t; /* * User specified final storage type for the state transitions */ enum { ACF_FULL, ACF_SPARSE, ACF_BANDED, ACF_SPARSEBANDS, ACF_FULLQ }; /* * User specified machine types * * TRIE : Keyword trie * NFA : * DFA : */ enum { FSA_TRIE, FSA_NFA, FSA_DFA }; #define AC_MAX_INQ 32 typedef struct { unsigned inq; unsigned inq_flush; void * q[AC_MAX_INQ]; } PMQ; /* * Aho-Corasick State Machine Struct - one per group of pattterns */ typedef struct { int acsmMaxStates; int acsmNumStates; ACSM_PATTERN2 * acsmPatterns; acstate_t * acsmFailState; ACSM_PATTERN2 ** acsmMatchList; /* list of transitions in each state, this is used to build the nfa & dfa */ /* after construction we convert to sparse or full format matrix and free */ /* the transition lists */ trans_node_t ** acsmTransTable; acstate_t ** acsmNextState; int acsmFormat; int acsmSparseMaxRowNodes; int acsmSparseMaxZcnt; int acsmNumTrans; int acsmAlphabetSize; int acsmFSA; int numPatterns; void (*userfree)(void *p); void (*optiontreefree)(void **p); void (*neg_list_free)(void **p); PMQ q; int sizeofstate; int compress_states; }ACSM_STRUCT2; /* * Prototypes */ ACSM_STRUCT2 * acsmNew2 (void (*userfree)(void *p), void (*optiontreefree)(void **p), void (*neg_list_free)(void **p)); int acsmAddPattern2( ACSM_STRUCT2 * p, unsigned char * pat, int n, int nocase, int offset, int depth, int negative, void * id, int iid ); int acsmCompile2 ( ACSM_STRUCT2 * acsm, int (*build_tree)(void * id, void **existing_tree), int (*neg_list_func)(void *id, void **list)); struct _SnortConfig; int acsmCompile2WithSnortConf ( struct _SnortConfig *, ACSM_STRUCT2 * acsm, int (*build_tree)(struct _SnortConfig *, void * id, void **existing_tree), int (*neg_list_func)(void *id, void **list)); int acsmSearch2 ( ACSM_STRUCT2 * acsm,unsigned char * T, int n, int (*Match)(void * id, void *tree, int index, void *data, void *neg_list), void * data, int* current_state ); int acsmSearchAll2 ( ACSM_STRUCT2 * acsm,unsigned char * T, int n, int (*Match)(void * id, void *tree, int index, void *data, void *neg_list), void * data, int* current_state ); void acsmFree2 ( ACSM_STRUCT2 * acsm ); int acsmPatternCount2 ( ACSM_STRUCT2 * acsm ); void acsmCompressStates(ACSM_STRUCT2 *, int); int acsmSelectFormat2( ACSM_STRUCT2 * acsm, int format ); int acsmSelectFSA2( ACSM_STRUCT2 * acsm, int fsa ); void acsmSetMaxSparseBandZeros2( ACSM_STRUCT2 * acsm, int n ); void acsmSetMaxSparseElements2( ACSM_STRUCT2 * acsm, int n ); int acsmSetAlphabetSize2( ACSM_STRUCT2 * acsm, int n ); void acsmSetVerbose2(void); void acsmPrintInfo2( ACSM_STRUCT2 * p); int acsmPrintDetailInfo2(ACSM_STRUCT2*); int acsmPrintSummaryInfo2(void); void acsmx2_print_qinfo(void); void acsm_init_summary(void); #endif snort-2.9.15.1/src/sfutil/sfksearch.c0000644000175200017520000005526713571422607014301 00000000000000/* * ksearch.c * * Basic Keyword Search Trie - uses linked lists to build the finite automata * * Keyword-Match: Performs the equivalent of a multi-string strcmp() * - use for token testing after parsing the language tokens using lex or the like. * * Keyword-Search: searches the input text for one of multiple keywords, * and supports case sensitivite and case insensitive patterns. * * ** Copyright (C) 2001 Marc Norton ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2003-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * */ #include #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sf_types.h" #ifndef DYNAMIC_PREPROC_CONTEXT #define SFKSEARCH_TRACK_Q #ifdef SFKSEARCH_TRACK_Q # include "snort.h" # include "util.h" #endif #endif //DYNAMIC_PREPROC_CONTEXT #include "snort_debug.h" #include "sfksearch.h" #include "snort_bounds.h" #include "sf_dynamic_preprocessor.h" static void KTrieFree(KTRIENODE *n); static unsigned int mtot = 0; unsigned int KTrieMemUsed(void) { return mtot; } void KTrieInitMemUsed(void) { mtot = 0; } /* * Allocate Memory */ static void * KTRIE_MALLOC(int n) { void *p; if (n < 1) return NULL; p = calloc(1, n); if (p) mtot += n; return p; } /* * Free Memory */ static void KTRIE_FREE(void *p) { if (p == NULL) return; free(p); } /* * Local/Tmp nocase array */ static unsigned char Tnocase[65*1024]; /* ** Case Translation Table */ static unsigned char xlatcase[256]; /* * */ static void init_xlatcase(void) { int i; static int first=1; if( !first ) return; /* thread safe */ for(i=0;i<256;i++) { xlatcase[ i ] = (unsigned char)tolower(i); } first=0; } /* * */ static inline void ConvertCaseEx( unsigned char * d, unsigned char *s, int m ) { int i; for( i=0; i < m; i++ ) { d[i] = xlatcase[ s[i] ]; } } /* * */ KTRIE_STRUCT * KTrieNew(int method, void (*userfree)(void *p), void (*optiontreefree)(void **p), void (*neg_list_free)(void **p)) { KTRIE_STRUCT * ts = (KTRIE_STRUCT*) KTRIE_MALLOC( sizeof(KTRIE_STRUCT) ); if( !ts ) return 0; memset(ts, 0, sizeof(KTRIE_STRUCT)); init_xlatcase(); ts->memory = sizeof(KTRIE_STRUCT); ts->nchars = 0; ts->npats = 0; ts->end_states = 0; ts->method = method; /* - old method, 1 = queue */ ts->userfree = userfree; ts->optiontreefree = optiontreefree; ts->neg_list_free = neg_list_free; return ts; } int KTriePatternCount(KTRIE_STRUCT *k) { return k->npats; } /* * Deletes memory that was used in creating trie * and nodes */ void KTrieDelete(KTRIE_STRUCT *k) { KTRIEPATTERN *p = NULL; KTRIEPATTERN *pnext = NULL; int i; if (k == NULL) return; p = k->patrn; while (p != NULL) { pnext = p->next; if (k->userfree && p->id) k->userfree(p->id); if (k->optiontreefree) { if (p && p->rule_option_tree) k->optiontreefree(&p->rule_option_tree); } if (k->neg_list_free) { if (p && p->neg_list) k->neg_list_free(&p->neg_list); } KTRIE_FREE(p->P); KTRIE_FREE(p->Pcase); KTRIE_FREE(p); p = pnext; } for (i = 0; i < KTRIE_ROOT_NODES; i++) KTrieFree(k->root[i]); KTRIE_FREE(k); } /* * Recursively delete all nodes in trie */ static void KTrieFree(KTRIENODE *n) { if (n == NULL) return; KTrieFree(n->child); KTrieFree(n->sibling); KTRIE_FREE(n); } /* * */ static KTRIEPATTERN * KTrieNewPattern(unsigned char * P, int n) { KTRIEPATTERN *p; int ret; if (n < 1) return NULL; p = (KTRIEPATTERN*) KTRIE_MALLOC( sizeof(KTRIEPATTERN) ); if (p == NULL) return NULL; /* Save as a nocase string */ p->P = (unsigned char*) KTRIE_MALLOC( n ); if( !p->P ) { KTRIE_FREE(p); return NULL; } ConvertCaseEx( p->P, P, n ); /* Save Case specific version */ p->Pcase = (unsigned char*) KTRIE_MALLOC( n ); if( !p->Pcase ) { KTRIE_FREE(p->P); KTRIE_FREE(p); return NULL; } ret = SafeMemcpy(p->Pcase, P, n, p->Pcase, p->Pcase + n); if (ret != SAFEMEM_SUCCESS) { KTRIE_FREE(p->Pcase); KTRIE_FREE(p->P); KTRIE_FREE(p); return NULL; } p->n = n; p->next = NULL; return p; } /* * Add Pattern info to the list of patterns */ int KTrieAddPattern( KTRIE_STRUCT * ts, unsigned char * P, int n, int nocase, int negative, void * id ) { KTRIEPATTERN *pnew; if( !ts->patrn ) { pnew = ts->patrn = KTrieNewPattern( P, n ); if( !pnew ) return -1; } else { pnew = KTrieNewPattern(P, n ); if( !pnew ) return -1; pnew->next = ts->patrn; /* insert at head of list */ ts->patrn = pnew; } pnew->nocase = nocase; pnew->negative = negative; pnew->id = id; pnew->mnext = NULL; ts->npats++; ts->memory += sizeof(KTRIEPATTERN) + 2 * n ; /* Case and nocase */ return 0; } /* * */ static KTRIENODE * KTrieCreateNode(KTRIE_STRUCT * ts) { KTRIENODE * t=(KTRIENODE*)KTRIE_MALLOC( sizeof(KTRIENODE) ); if(!t) return 0; memset(t,0,sizeof(KTRIENODE)); ts->memory += sizeof(KTRIENODE); return t; } /* * Insert a Pattern in the Trie */ static int KTrieInsert( KTRIE_STRUCT *ts, KTRIEPATTERN * px ) { int type = 0; int n = px->n; unsigned char *P = px->P; KTRIENODE *root; /* Make sure we at least have a root character for the tree */ if( !ts->root[*P] ) { ts->root[*P] = root = KTrieCreateNode(ts); if( !root ) return -1; root->edge = *P; }else{ root = ts->root[*P]; } /* Walk existing Patterns */ while( n ) { if( root->edge == *P ) { P++; n--; if( n && root->child ) { root=root->child; } else /* cannot continue */ { type = 0; /* Expand the tree via the child */ break; } } else { if( root->sibling ) { root=root->sibling; } else /* cannot continue */ { type = 1; /* Expand the tree via the sibling */ break; } } } /* * Add the next char of the Keyword, if any */ if( n ) { if( type == 0 ) { /* * Start with a new child to finish this Keyword */ root->child= KTrieCreateNode( ts ); if( ! root->child ) return -1; root=root->child; root->edge = *P; P++; n--; ts->nchars++; } else { /* * Start a new sibling bracnch to finish this Keyword */ root->sibling= KTrieCreateNode( ts ); if( ! root->sibling ) return -1; root=root->sibling; root->edge = *P; P++; n--; ts->nchars++; } } /* * Finish the keyword as child nodes */ while( n ) { root->child = KTrieCreateNode(ts); if( ! root->child ) return -1; root=root->child; root->edge = *P; P++; n--; ts->nchars++; } if( root->pkeyword ) { px->mnext = root->pkeyword; /* insert duplicates at front of list */ root->pkeyword = px; ts->duplicates++; } else { root->pkeyword = px; ts->end_states++; } return 0; } /* * */ static void Build_Bad_Character_Shifts( KTRIE_STRUCT * kt ) { int i,k; KTRIEPATTERN *plist; /* Calc the min pattern size */ kt->bcSize = 32000; for( plist=kt->patrn; plist!=NULL; plist=plist->next ) { if( plist->n < kt->bcSize ) { kt->bcSize = plist->n; /* smallest pattern size */ } } /* * Initialze the Bad Character shift table. */ for (i = 0; i < KTRIE_ROOT_NODES; i++) { kt->bcShift[i] = (unsigned short)kt->bcSize; } /* * Finish the Bad character shift table */ for( plist=kt->patrn; plist!=NULL; plist=plist->next ) { int shift, cindex; for( k=0; kbcSize; k++ ) { shift = kt->bcSize - 1 - k; cindex = plist->P[ k ]; if( shift < kt->bcShift[ cindex ] ) { kt->bcShift[ cindex ] = (unsigned short)shift; } } } } static int KTrieBuildMatchStateNode(KTRIENODE *root, int (*build_tree)(void * id, void **existing_tree), int (*neg_list_func)(void *id, void **list)) { int cnt = 0; KTRIEPATTERN *p; if (!root) return 0; /* each and every prefix match at this root*/ if (root->pkeyword) { for (p = root->pkeyword; p; p = p->mnext) { if (p->id) { if (p->negative) { neg_list_func(p->id, &root->pkeyword->neg_list); } else { build_tree(p->id, &root->pkeyword->rule_option_tree); } } cnt++; } /* Last call to finalize the tree for this root */ build_tree(NULL, &root->pkeyword->rule_option_tree); } /* for child of this root */ if (root->child) { cnt += KTrieBuildMatchStateNode(root->child, build_tree, neg_list_func); } /* 1st sibling of this root -- other siblings will be processed from * within the processing for root->sibling. */ if (root->sibling) { cnt += KTrieBuildMatchStateNode(root->sibling, build_tree, neg_list_func); } return cnt; } static int KTrieBuildMatchStateNodeWithSnortConf(struct _SnortConfig *sc, KTRIENODE *root, int (*build_tree)(struct _SnortConfig *, void * id, void **existing_tree), int (*neg_list_func)(void *id, void **list)) { int cnt = 0; KTRIEPATTERN *p; if (!root) return 0; /* each and every prefix match at this root*/ if (root->pkeyword) { for (p = root->pkeyword; p; p = p->mnext) { if (p->id) { if (p->negative) { neg_list_func(p->id, &root->pkeyword->neg_list); } else { build_tree(sc, p->id, &root->pkeyword->rule_option_tree); } } cnt++; } /* Last call to finalize the tree for this root */ build_tree(sc, NULL, &root->pkeyword->rule_option_tree); } /* for child of this root */ if (root->child) { cnt += KTrieBuildMatchStateNodeWithSnortConf(sc, root->child, build_tree, neg_list_func); } /* 1st sibling of this root -- other siblings will be processed from * within the processing for root->sibling. */ if (root->sibling) { cnt += KTrieBuildMatchStateNodeWithSnortConf(sc, root->sibling, build_tree, neg_list_func); } return cnt; } static int KTrieBuildMatchStateTrees( KTRIE_STRUCT * ts, int (*build_tree)(void * id, void **existing_tree), int (*neg_list_func)(void *id, void **list)) { int i, cnt = 0; KTRIENODE * root; /* Find the states that have a MatchList */ for (i = 0; i < KTRIE_ROOT_NODES; i++) { root = ts->root[i]; /* each and every prefix match at this root*/ if (root) { cnt += KTrieBuildMatchStateNode(root, build_tree, neg_list_func); } } return cnt; } static int KTrieBuildMatchStateTreesWithSnortConf( struct _SnortConfig *sc, KTRIE_STRUCT * ts, int (*build_tree)(struct _SnortConfig *, void * id, void **existing_tree), int (*neg_list_func)(void *id, void **list)) { int i, cnt = 0; KTRIENODE * root; /* Find the states that have a MatchList */ for (i = 0; i < KTRIE_ROOT_NODES; i++) { root = ts->root[i]; /* each and every prefix match at this root*/ if (root) { cnt += KTrieBuildMatchStateNodeWithSnortConf(sc, root, build_tree, neg_list_func); } } return cnt; } /* * Build the Keyword TRIE * */ static inline int _KTrieCompile(KTRIE_STRUCT * ts) { KTRIEPATTERN * p; /* static int tmem=0; */ /* * Build the Keyword TRIE */ for( p=ts->patrn; p; p=p->next ) { if( KTrieInsert( ts, p ) ) return -1; } /* * Build A Setwise Bad Character Shift Table */ Build_Bad_Character_Shifts( ts ); /* tmem += ts->memory; printf(" Compile stats: %d patterns, %d chars, %d duplicate patterns, %d bytes, %d total-bytes\n",ts->npats,ts->nchars,ts->duplicates,ts->memory,tmem); */ return 0; } int KTrieCompile(KTRIE_STRUCT * ts, int (*build_tree)(void * id, void **existing_tree), int (*neg_list_func)(void *id, void **list)) { int rval; if ((rval = _KTrieCompile(ts))) return rval; if (build_tree && neg_list_func) { KTrieBuildMatchStateTrees(ts, build_tree, neg_list_func); } return 0; } int KTrieCompileWithSnortConf(struct _SnortConfig *sc, KTRIE_STRUCT * ts, int (*build_tree)(struct _SnortConfig *, void * id, void **existing_tree), int (*neg_list_func)(void *id, void **list)) { int rval; if ((rval = _KTrieCompile(ts))) return rval; if (build_tree && neg_list_func) { KTrieBuildMatchStateTreesWithSnortConf(sc, ts, build_tree, neg_list_func); } return 0; } void sfksearch_print_qinfo(void) { #ifdef SFKSEARCH_TRACK_Q if( snort_conf->max_inq ) { LogMessage("lowmem: queue size = %u, max = %u\n", snort_conf->max_inq,SFK_MAX_INQ ); LogMessage("lowmem: queue flushes = "STDu64"\n", snort_conf->tot_inq_flush ); LogMessage("lowmem: queue inserts = "STDu64"\n", snort_conf->tot_inq_inserts ); LogMessage("lowmem: queue uinserts = "STDu64"\n", snort_conf->tot_inq_uinserts ); } #endif } static inline void _init_queue( SFK_PMQ * b) { b->inq=0; b->inq_flush=0; } /* uniquely insert into q */ static inline int _add_queue(SFK_PMQ * b, void * p ) { int i; #ifdef SFKSEARCH_TRACK_Q snort_conf->tot_inq_inserts++; #endif for(i=(int)(b->inq)-1;i>=0;i--) if( p == b->q[i] ) return 0; #ifdef SFKSEARCH_TRACK_Q snort_conf->tot_inq_uinserts++; #endif if( b->inq < SFK_MAX_INQ ) { b->q[ b->inq++ ] = p; } if( b->inq == SFK_MAX_INQ ) { #ifdef SFKSEARCH_TRACK_Q b->inq_flush++; #endif return 1; } return 0; } static inline unsigned _process_queue( SFK_PMQ * q, int(*match)(void * id, void *tree, int index, void *data, void *neg_list), void *data ) { KTRIEPATTERN * pk; unsigned int i; #ifdef SFKSEARCH_TRACK_Q if( q->inq > snort_conf->max_inq ) snort_conf->max_inq = q->inq; snort_conf->tot_inq_flush += q->inq_flush; #endif for( i=0; iinq; i++ ) { pk = q->q[i]; if (pk) { if (match (pk->id, pk->rule_option_tree, 0, data, pk->neg_list) > 0) { q->inq=0; return 1; } } } q->inq=0; return 0; } static inline int KTriePrefixMatchQ( KTRIE_STRUCT * kt, unsigned char * T, int n, int(*match)(void * id, void *tree, int index, void *data, void *neg_list), void * data ) { KTRIENODE * root; //KTRIEPATTERN * pk; //int index ; root = kt->root[ xlatcase[*T] ]; if( !root ) return 0; while( n ) { if( root->edge == xlatcase[*T] ) { T++; n--; if( root->pkeyword ) { if( _add_queue( &kt->q, root->pkeyword ) ) { if( _process_queue( &kt->q,match,data) ) { return 1; } } } if( n && root->child ) { root = root->child; } else /* cannot continue -- match is over */ { break; } } else { if( root->sibling ) { root = root->sibling; } else /* cannot continue */ { break; } } } return 0; } /* * Search - Algorithm * * This routine will log any substring of T that matches a keyword, * and processes all prefix matches. This is used for generic * pattern searching with a set of keywords and a body of text. * * * * kt- Trie Structure * T - nocase text * Tc- case specific text * n - text length * * returns: * # pattern matches */ static inline int KTriePrefixMatch( KTRIE_STRUCT * kt, unsigned char * T, unsigned char * Tc, unsigned char * bT, int n, int(*match)(void * id, void *tree, int index, void *data, void *neg_list), void * data ) { KTRIENODE * root = kt->root[ *T ]; int nfound = 0; KTRIEPATTERN * pk; int index ; /* Check if any keywords start with this character */ if( !root ) return 0; while( n ) { if( root->edge == *T ) { T++; n--; pk = root->pkeyword; if (pk) { index = (int)(T - bT - pk->n ); nfound++; if (match (pk->id, pk->rule_option_tree, index, data, pk->neg_list) > 0) { return nfound; } } if( n && root->child ) { root = root->child; } else /* cannot continue -- match is over */ { break; } } else { if( root->sibling ) { root = root->sibling; } else /* cannot continue */ { break; } } } return nfound; } static inline int KTrieSearchQ( KTRIE_STRUCT * ks, unsigned char * T, int n, int(*match)(void * id, void *tree, int index, void *data, void *neg_list), void * data ) { _init_queue(&ks->q); while( n > 0 ) { if( KTriePrefixMatchQ( ks, T++, n--, match, data ) ) return 0; } _process_queue(&ks->q,match,data); return 0; } /* * */ static inline int KTrieSearchNoBC( KTRIE_STRUCT * ks, unsigned char * Tx, int n, int(*match)(void * id, void *tree, int index, void *data, void *neg_list), void * data ) { int nfound = 0; unsigned char *T, *bT; ConvertCaseEx( Tnocase, Tx, n ); T = Tnocase; bT = T; for( ; n>0 ; n--, T++, Tx++ ) { nfound += KTriePrefixMatch( ks, T, Tx, bT, n, match, data ); } return nfound; } /* * */ static inline int KTrieSearchBC( KTRIE_STRUCT * ks, unsigned char * Tx, int n, int(*match)(void * id, void *tree, int index, void *data, void *neg_list), void * data ) { int tshift; unsigned char *Tend; unsigned char *T, *bT; int nfound = 0; short *bcShift = (short*)ks->bcShift; int bcSize = ks->bcSize; ConvertCaseEx( Tnocase, Tx, n ); T = Tnocase; bT = T; Tend = T + n - bcSize; bcSize--; for( ;T <= Tend; n--, T++, Tx++ ) { while( (tshift = bcShift[ *( T + bcSize ) ]) > 0 ) { T += tshift; Tx += tshift; if( T > Tend ) return nfound; } nfound += KTriePrefixMatch( ks, T, Tx, bT, n, match, data ); } return nfound; } /* * */ int KTrieSearch( KTRIE_STRUCT * ks, unsigned char * T, int n, int(*match)(void * id, void *tree, int index, void *data, void *neg_list), void * data ) { if( ks->method == KTRIEMETHOD_QUEUE ) { //if( ks->bcSize < 3) return KTrieSearchQ( ks, T, n, match, data ); //else // return KTrieSearchQBC( ks, T, n, match, data ); } else { if( ks->bcSize < 3) return KTrieSearchNoBC( ks, T, n, match, data ); else return KTrieSearchBC( ks, T, n, match, data ); } } /* * * TEST DRIVER FOR KEYWORD TRIE * */ #ifdef KTRIE_MAIN char ** gargv; int trie_nmatches = 0; int match( unsigned id, int index, void * data ) { trie_nmatches++; data = data; printf("id=%d found at index=%d, %s\n",id,index,gargv[id]); return 0; } /* * */ int main( int argc, char ** argv ) { int i; KTRIE_STRUCT * ts; int nocase=1; // don't care about case gargv = argv; ts = KTrieNew(); if( argc < 3 ) { printf("%s text pat1 pat2 ... patn [-c(ase-sensitive)\n",argv[0]); printf("search for keywords-default, or match keywords\n"); exit(0); } for(i=1;i %d characters, %d patterns, %d bytes allocated\n",ts->nchars,ts->npats,ts->memory); printf("Searching...\n"); KTrieSearch( ts, (unsigned char*)argv[1], strlen(argv[1]), match, 0 ); printf("%d matches found\n",trie_nmatches); printf("normal pgm finish.\n"); return 0; } #endif snort-2.9.15.1/src/sfutil/sfksearch.h0000644000175200017520000000731313571422607014273 00000000000000/* * ksearch.h * * Trie based multi-pattern matcher * * * Copyright (C) 2001 Marc Norton ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2003-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KTRIE_H #define KTRIE_H #define ALPHABET_SIZE 256 #ifdef HAVE_CONFIG_H #include "config.h" #endif #define KTRIEMETHOD_STD 0 #define KTRIEMETHOD_QUEUE 1 /* * */ typedef struct _ktriepattern { struct _ktriepattern * next; /* global list of all patterns */ struct _ktriepattern * mnext; /* matching list of duplicate keywords */ unsigned char * P; /* no case */ unsigned char * Pcase; /* case sensitive */ int n; int nocase; int negative; void * id; void * rule_option_tree; void * neg_list; } KTRIEPATTERN; /* * */ typedef struct _ktrienode { int edge; /* character */ struct _ktrienode * sibling; struct _ktrienode * child; KTRIEPATTERN *pkeyword; } KTRIENODE; #define KTRIE_ROOT_NODES 256 #define SFK_MAX_INQ 32 typedef struct { unsigned inq; unsigned inq_flush; void * q[SFK_MAX_INQ]; } SFK_PMQ; /* * */ typedef struct { KTRIEPATTERN * patrn; /* List of patterns, built as they are added */ KTRIENODE * root[KTRIE_ROOT_NODES]; /* KTrie nodes */ int memory; int nchars; int npats; int duplicates; int method; int end_states; /* should equal npats - duplicates */ int bcSize; unsigned short bcShift[KTRIE_ROOT_NODES]; void (*userfree)(void *p); void (*optiontreefree)(void **p); void (*neg_list_free)(void **p); SFK_PMQ q; } KTRIE_STRUCT; KTRIE_STRUCT * KTrieNew(int method, void (*userfree)(void *p), void (*optiontreefree)(void **p), void (*neg_list_free)(void **p)); int KTrieAddPattern( KTRIE_STRUCT *ts, unsigned char * P, int n, int nocase, int negative, void * id ); int KTrieCompile(KTRIE_STRUCT * ts, int (*build_tree)(void * id, void **existing_tree), int (*neg_list_func)(void *id, void **list)); struct _SnortConfig; int KTrieCompileWithSnortConf(struct _SnortConfig *, KTRIE_STRUCT * ts, int (*build_tree)(struct _SnortConfig *, void * id, void **existing_tree), int (*neg_list_func)(void *id, void **list)); int KTrieSearch( KTRIE_STRUCT * ts, unsigned char * T, int n, int(*match)(void * id, void *tree, int index, void *data, void *neg_list), void *data ); unsigned int KTrieMemUsed(void); void KTrieInitMemUsed(void); void KTrieDelete(KTRIE_STRUCT *k); int KTriePatternCount(KTRIE_STRUCT *k); void sfksearch_print_qinfo(void); #endif snort-2.9.15.1/src/sfutil/bnfa_search.c0000644000175200017520000023045013571422607014550 00000000000000/* ** bnfa_search.c ** ** Basic multi-pattern search engine using Aho-Corasick NFA construction. ** ** Version 3.0 (based on acsmx.c and acsmx2.c) ** ** author: marc norton ** date: started 12/21/05 ** ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2005-2013 Sourcefire, Inc. ** ** General Design ** Aho-Corasick based NFA state machine. ** Compacted sparse storage mode for better performance. ** Up to 16 Million states + transitions (combined) in compacted sparse mode. ** ** ** Compacted sparse array storage ** ** ** The primary data is held in one array. ** The patterns themselves are stored separately. ** The matching lists of patterns for each state are stored separately as well. ** The compacted sparse format improves caching/performance. ** ** word 1 : state ( only low 24 bits are used ) ** word 2 : control word = cb << 24 | fs ** cb: control byte ** cb = mb | fb | nt ** mb : 8th bit - if set state has matching patterns bit ** fb : 7th bit - if set full storage array bit (256 entries used), else sparse ** nt : 0-63= number of transitions (more than 63 requires full storage) ** fs: 24 bits for failure state transition index. ** word 3+ : transition word = input<<24 | next-state-index ** input : 8 bit character, input to state machine from search text ** next-state-index: 24 bits for index of next state ** (if we reallly need 16M states, we can add a state->index lookup array) ** ...repeat for each state ... ** ** * if a state is empty it has words 1 and 2, but no transition words. ** ** Construction: ** ** Patterns are added to a list based trie. ** The list based trie is compiled into a list based NFA with failure states. ** The list based NFA is converted to full or sparse format NFA. ** The Zero'th state sparse transitions may be stored in full format for ** performance. ** Sparse transition arrays are searched using linear and binary search ** strategies depending on the number of entries to search through in ** each state. ** The state machine in sparse mode is compacted into a single vector for ** better performance. ** ** Notes: ** ** The NFA can require twice the state transitions that a DFA uses. However, ** the construction of a DFA generates many additional transitions in each ** state which consumes significant additional memory. This particular ** implementation is best suited to environments where the very large memory ** requirements of a full state table implementation is not possible and/or ** the speed trade off is warranted to maintain a small memory footprint. ** ** Each state of an NFA usually has very few transitions but can have up to ** 256. It is important to not degenerate into a linear search so we utilize ** a binary search if there are more than 5 elements in the state to test for ** a match. This allows us to use a simple sparse memory design with an ** acceptable worst case search scenario. The binary search over 256 elements ** is limtied to a max of 8 tests. The zero'th state may use a full 256 state ** array, so a quick index lookup provides the next state transition. The ** zero'th state is generally visited much more than other states. ** ** Compiling : gcc, Intel C/C++, Microsoft C/C++, each optimize differently. ** My studies have shown Intel C/C++ 9,8,7 to be the fastest, Microsoft 8,7,6 ** is next fastest, and gcc 4.x,3.x,2.x is the slowest of the three. My ** testing has been mainly on x86. In general gcc does a poor job with ** optimizing this state machine for performance, compared to other less cache ** and prefetch sensitive algorithms. I've documented this behavior in a ** paper 'Optimizing Pattern Matching for IDS' (www.sourcefire.com, ** www.idsresearch.org). ** ** The code is sensitive to cache optimization and prefetching, as well as ** instruction pipelining. Aren't we all. To this end, the number of ** patterns, length of search text, and cpu cache L1,L2,L3 all affect ** performance. The relative performance of the sparse and full format NFA and ** DFA varies as you vary the pattern charactersitics,and search text length, ** but strong performance trends are present and stable. ** ** ** BNFA API SUMMARY ** ** bnfa=bnfaNew(); create a state machine ** bnfaAddPattern(bnfa,..); add a pattern to the state machine ** bnfaCompile (bnfa,..) compile the state machine ** bnfaPrintInfo(bnfa); print memory usage and state info ** bnfaPrint(bnfa); print the state machine in total ** state=bnfaSearch(bnfa, ...,state); search a data buffer for a pattern match ** bnfaFree (bnfa); free the bnfa ** ** ** Reference - Efficient String matching: An Aid to Bibliographic Search ** Alfred V Aho and Margaret J Corasick ** Bell Labratories ** Copyright(C) 1975 Association for Computing Machinery,Inc ** ** 12/4/06 - man - modified summary ** 6/26/07 - man - Added last_match tracking, and accounted for nocase/case by ** preseting the last match state, and reverting if we fail the ** case memcmp test for any rule in the states matching rule ** list. The states in the defaul matcher represent either ** case or nocase states, so they are dual mode, that makes ** this a bit tricky. When we sue the pure exact match, or ** pure don't care matching routines, we just track the last ** state, and never need to revert. This only tracks the ** single repeated states and repeated data. ** 01/2008 - man - added 2 phase pattern matcher using a pattern match queue. ** Text is scanned and matching states are queued, duplicate ** matches are dropped, and after the complete buffer scan the ** queued matches are processed. This improves cacheing ** performance, and reduces duplicate rule processing. The ** queue is limited in size and is flushed if it becomes full ** during the scan. This allows simple insertions. Tracking ** queue ops is optional, as this can impose a modest ** performance hit of a few percent. ** ** LICENSE (GPL) ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** */ #include #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sf_types.h" #ifndef DYNAMIC_PREPROC_CONTEXT #define BNFA_TRACK_Q #ifdef BNFA_TRACK_Q # include "snort.h" #endif #endif //DYNAMIC_PREPROC_CONTEXT #include "bnfa_search.h" #include "snort_debug.h" #include "util.h" #include "sf_dynamic_preprocessor.h" /* * Used to initialize last state, states are limited to 0-16M * so this will not conflict. */ #define LAST_STATE_INIT 0xffffffff #define printf LogMessage /* * Case Translation Table - his guarantees we use * indexed lookups for case conversion */ static unsigned char xlatcase[BNFA_MAX_ALPHABET_SIZE]; static void init_xlatcase(void) { int i; static int first=1; if( !first ) return; for(i=0; ihead = s->tail = 0; s->count= 0; s->maxcnt=0; } /* * Add items to tail of queue (fifo) */ static int queue_add (QUEUE * s, int state) { QNODE * q; if (!s->head) { q = s->tail = s->head = (QNODE *) BNFA_MALLOC (sizeof(QNODE),queue_memory); if(!q) return -1; q->state = state; q->next = 0; } else { q = (QNODE *) BNFA_MALLOC (sizeof(QNODE),queue_memory); if(!q) return -1; q->state = state; q->next = 0; s->tail->next = q; s->tail = q; } s->count++; if( s->count > s->maxcnt ) s->maxcnt = s->count; return 0; } /* * Remove items from head of queue (fifo) */ static int queue_remove (QUEUE * s) { int state = 0; QNODE * q; if (s->head) { q = s->head; state = q->state; s->head = s->head->next; s->count--; if( !s->head ) { s->tail = 0; s->count = 0; } BNFA_FREE (q,sizeof(QNODE),queue_memory); } return state; } /* * Return count of items in the queue */ static int queue_count (QUEUE * s) { return s->count; } /* * Free the queue */ static void queue_free (QUEUE * s) { while (queue_count (s)) { queue_remove (s); } } /* * Get next state from transition list */ static int _bnfa_list_get_next_state( bnfa_struct_t * bnfa, int state, int input ) { if ( state == 0 ) /* Full set of states always */ { bnfa_state_t * p = (bnfa_state_t*)bnfa->bnfaTransTable[0]; if(!p) { return 0; } return p[input]; } else { bnfa_trans_node_t * t = bnfa->bnfaTransTable[state]; while( t ) { if( t->key == (unsigned)input ) { return t->next_state; } t=t->next; } return BNFA_FAIL_STATE; /* Fail state */ } } /* * Put next state - head insertion, and transition updates */ static int _bnfa_list_put_next_state( bnfa_struct_t * bnfa, int state, int input, int next_state ) { if( state >= bnfa->bnfaMaxStates ) { return -1; } if( input >= bnfa->bnfaAlphabetSize ) { return -1; } if( state == 0 ) { bnfa_state_t * p; p = (bnfa_state_t*)bnfa->bnfaTransTable[0]; if( !p ) { p = (bnfa_state_t*)BNFA_MALLOC(sizeof(bnfa_state_t)*bnfa->bnfaAlphabetSize,bnfa->list_memory); if( !p ) { return -1; } bnfa->bnfaTransTable[0] = (bnfa_trans_node_t*)p; } if( p[input] ) { p[input] = next_state; return 0; } p[input] = next_state; } else { bnfa_trans_node_t * p; bnfa_trans_node_t * tnew; /* Check if the transition already exists, if so just update the next_state */ p = bnfa->bnfaTransTable[state]; while( p ) { if( p->key == (unsigned)input ) /* transition already exists- reset the next state */ { p->next_state = next_state; return 0; } p=p->next; } /* Definitely not an existing transition - add it */ tnew = (bnfa_trans_node_t*)BNFA_MALLOC(sizeof(bnfa_trans_node_t),bnfa->list_memory); if( !tnew ) { return -1; } tnew->key = input; tnew->next_state = next_state; tnew->next = bnfa->bnfaTransTable[state]; bnfa->bnfaTransTable[state] = tnew; } bnfa->bnfaNumTrans++; return 0; } /* * Free the entire transition list table */ static int _bnfa_list_free_table( bnfa_struct_t * bnfa ) { int i; bnfa_trans_node_t * t, *p; if( !bnfa->bnfaTransTable ) return 0; if( bnfa->bnfaTransTable[0] ) { BNFA_FREE(bnfa->bnfaTransTable[0],sizeof(bnfa_state_t)*bnfa->bnfaAlphabetSize,bnfa->list_memory); } for(i=1; ibnfaMaxStates; i++) { t = bnfa->bnfaTransTable[i]; while( t ) { p = t; t = t->next; BNFA_FREE(p,sizeof(bnfa_trans_node_t),bnfa->list_memory); } } if( bnfa->bnfaTransTable ) { BNFA_FREE(bnfa->bnfaTransTable,sizeof(bnfa_trans_node_t*)*bnfa->bnfaMaxStates,bnfa->list_memory); bnfa->bnfaTransTable = 0; } return 0; } static int bnfaBuildMatchStateTrees(bnfa_struct_t *bnfa, int (*build_tree)(void *id, void **existing_tree), int (*neg_list_func)(void *id, void **list)) { int i,cnt = 0; bnfa_match_node_t * mn; bnfa_match_node_t ** MatchList = bnfa->bnfaMatchList; bnfa_pattern_t * patrn; for (i=0;ibnfaNumStates;i++) { for(mn = MatchList[i]; mn!= NULL; mn = mn->next ) { patrn = (bnfa_pattern_t *)mn->data; if (patrn->userdata) { if (patrn->negative) { neg_list_func(patrn->userdata, &MatchList[i]->neg_list); } else { build_tree(patrn->userdata, &MatchList[i]->rule_option_tree); } } cnt++; } /* Last call to finalize the tree */ if (MatchList[i]) { build_tree(NULL, &MatchList[i]->rule_option_tree); } } return cnt; } #ifndef DYNAMIC_PREPROCESSOR_CONTEXT static int bnfaBuildMatchStateTreesWithSnortConf(struct _SnortConfig *sc, bnfa_struct_t *bnfa, int (*build_tree)(struct _SnortConfig *, void *id, void **existing_tree), int (*neg_list_func)(void *id, void **list)) { int i,cnt = 0; bnfa_match_node_t * mn; bnfa_match_node_t ** MatchList = bnfa->bnfaMatchList; bnfa_pattern_t * patrn; for (i=0;ibnfaNumStates;i++) { for(mn = MatchList[i]; mn!= NULL; mn = mn->next ) { patrn = (bnfa_pattern_t *)mn->data; if (patrn->userdata) { if (patrn->negative) { neg_list_func(patrn->userdata, &MatchList[i]->neg_list); } else { build_tree(sc, patrn->userdata, &MatchList[i]->rule_option_tree); } } cnt++; } /* Last call to finalize the tree */ if (MatchList[i]) { build_tree(sc, NULL, &MatchList[i]->rule_option_tree); } } return cnt; } #endif //DYNAMIC_PREPROCESSOR_CONTEXT #ifdef ALLOW_LIST_PRINT /* * Print the transition list table to stdout */ static int _bnfa_list_print_table( bnfa_struct_t * bnfa ) { int i; bnfa_trans_node_t * t; bnfa_match_node_t * mn; bnfa_pattern_t * patrn; if( !bnfa->bnfaTransTable ) { return 0; } printf("Print Transition Table- %d active states\n",bnfa->bnfaNumStates); for(i=0;i< bnfa->bnfaNumStates;i++) { printf("state %3d: ",i); if( i == 0 ) { int k; bnfa_state_t * p = (bnfa_state_t*)bnfa->bnfaTransTable[0]; if(!p) continue; for(k=0;kbnfaAlphabetSize;k++) { if( p[k] == 0 ) continue; if( isascii((int)p[k]) && isprint((int)p[k]) ) printf("%3c->%-5d\t",k,p[k]); else printf("%3d->%-5d\t",k,p[k]); } } else { t = bnfa->bnfaTransTable[i]; while( t ) { if( isascii((int)t->key) && isprint((int)t->key) ) printf("%3c->%-5d\t",t->key,t->next_state); else printf("%3d->%-5d\t",t->key,t->next_state); t = t->next; } } mn =bnfa->bnfaMatchList[i]; while( mn ) { patrn =(bnfa_pattern_t *)mn->data; printf("%.*s ",patrn->n,patrn->casepatrn); mn = mn->next; } printf("\n"); } return 0; } #endif /* * Converts a single row of states from list format to a full format */ static int _bnfa_list_conv_row_to_full(bnfa_struct_t * bnfa, bnfa_state_t state, bnfa_state_t * full ) { if( (int)state >= bnfa->bnfaMaxStates ) /* protects 'full' against overflow */ { return -1; } if( state == 0 ) { if( bnfa->bnfaTransTable[0] ) memcpy(full,bnfa->bnfaTransTable[0],sizeof(bnfa_state_t)*bnfa->bnfaAlphabetSize); else memset(full,0,sizeof(bnfa_state_t)*bnfa->bnfaAlphabetSize); return bnfa->bnfaAlphabetSize; } else { int tcnt = 0; bnfa_trans_node_t * t = bnfa->bnfaTransTable[ state ]; memset(full,0,sizeof(bnfa_state_t)*bnfa->bnfaAlphabetSize); if( !t ) { return 0; } while(t && (t->key < BNFA_MAX_ALPHABET_SIZE ) ) { full[ t->key ] = t->next_state; tcnt++; t = t->next; } return tcnt; } } /* * Add pattern characters to the initial upper case trie * unless Exact has been specified, in which case all patterns * are assumed to be case specific. */ static int _bnfa_add_pattern_states (bnfa_struct_t * bnfa, bnfa_pattern_t * p) { int state, next, n; unsigned char * pattern; bnfa_match_node_t * pmn; n = p->n; pattern = p->casepatrn; state = 0; /* * Match up pattern with existing states */ for (; n > 0; pattern++, n--) { if( bnfa->bnfaCaseMode == BNFA_CASE ) next = _bnfa_list_get_next_state(bnfa,state,*pattern); else next = _bnfa_list_get_next_state(bnfa,state,xlatcase[*pattern]); if( next == (int)BNFA_FAIL_STATE || next == 0 ) { break; } state = next; } /* * Add new states for the rest of the pattern bytes, 1 state per byte, uppercase */ for (; n > 0; pattern++, n--) { bnfa->bnfaNumStates++; if( bnfa->bnfaCaseMode == BNFA_CASE ) { if( _bnfa_list_put_next_state(bnfa,state,*pattern,bnfa->bnfaNumStates) < 0 ) return -1; } else { if( _bnfa_list_put_next_state(bnfa,state,xlatcase[*pattern],bnfa->bnfaNumStates) < 0 ) return -1; } state = bnfa->bnfaNumStates; if ( bnfa->bnfaNumStates >= bnfa->bnfaMaxStates ) { return -1; } } /* Add a pattern to the list of patterns terminated at this state */ pmn = (bnfa_match_node_t*)BNFA_MALLOC(sizeof(bnfa_match_node_t),bnfa->matchlist_memory); if( !pmn ) { return -1; } pmn->data = p; pmn->next = bnfa->bnfaMatchList[state]; bnfa->bnfaMatchList[state] = pmn; return 0; } #ifdef XXXXX int _bnfa_list_get_next_state( bnfa_struct_t * bnfa, int state, int input ) { if ( state == 0 ) /* Full set of states always */ { bnfa_state_t * p = (bnfa_state_t*)bnfa->bnfaTransTable[0]; if(!p) { return 0; } return p[input]; } else { bnfa_trans_node_t * t = bnfa->bnfaTransTable[state]; while( t ) { if( t->key == (unsigned)input ) { return t->next_state; } t=t->next; } return BNFA_FAIL_STATE; /* Fail state */ } } #endif static /* used only by KcontainsJ() */ int _bnfa_conv_node_to_full(bnfa_trans_node_t *t, bnfa_state_t * full ) { int tcnt = 0; memset(full,0,sizeof(bnfa_state_t)*BNFA_MAX_ALPHABET_SIZE); if( !t ) { return 0; } while(t && (t->key < BNFA_MAX_ALPHABET_SIZE ) ) { full[ t->key ] = t->next_state; tcnt++; t = t->next; } return tcnt; } /* * containment test - * test if all of tj transitions are in tk */ #ifdef XXXX static int KcontainsJx(bnfa_trans_node_t * tk, bnfa_trans_node_t *tj ) { bnfa_trans_node_t *t; int found; while( tj ) { found=0; for( t=tk;t;t=t->next ) { if( tj->key == t->key ) { found=1; break; } } if( !found ) return 0; tj=tj->next; /* get next tj key */ } return 1; } #endif static int KcontainsJ(bnfa_trans_node_t * tk, bnfa_trans_node_t *tj ) { bnfa_state_t full[BNFA_MAX_ALPHABET_SIZE]; if( !_bnfa_conv_node_to_full(tk,full) ) return 1; /* emtpy state */ while( tj ) { if( !full[tj->key] ) return 0; tj=tj->next; /* get next tj key */ } return 1; } /* * 1st optimization - eliminate duplicate fail states * * check if a fail state is a subset of the current state, * if so recurse to the next fail state, and so on. */ static int _bnfa_opt_nfa (bnfa_struct_t * bnfa) { int cnt=0; int k, fs, fr; bnfa_state_t * FailState = bnfa->bnfaFailState; for(k=2;kbnfaNumStates;k++) { fr = fs = FailState[k]; while( fs && KcontainsJ(bnfa->bnfaTransTable[k],bnfa->bnfaTransTable[fs]) ) { fs = FailState[fs]; } if( fr != fs ) { cnt++; FailState[ k ] = fs; } } #ifdef DEBUG if( cnt)LogMessage("ac-bnfa: %d nfa optimizations found in %d states\n",cnt,bnfa->bnfaNumStates); #endif return 0; } /* * Build a non-deterministic finite automata using Aho-Corasick construction * The keyword trie must already be built via _bnfa_add_pattern_states() */ static int _bnfa_build_nfa (bnfa_struct_t * bnfa) { int r, s, i; QUEUE q, *queue = &q; bnfa_state_t * FailState = bnfa->bnfaFailState; bnfa_match_node_t ** MatchList = bnfa->bnfaMatchList; bnfa_match_node_t * mlist; bnfa_match_node_t * px; /* Init a Queue */ queue_init (queue); /* Add the state 0 transitions 1st, * the states at depth 1, fail to state 0 */ for (i = 0; i < bnfa->bnfaAlphabetSize; i++) { /* note that state zero deos not fail, * it just returns 0..nstates-1 */ s = _bnfa_list_get_next_state(bnfa,0,i); if( s ) /* don't bother adding state zero */ { if( queue_add (queue, s) ) { return -1; } FailState[s] = 0; } } /* Build the fail state successive layer of transitions */ while (queue_count (queue) > 0) { r = queue_remove (queue); /* Find Final States for any Failure */ for(i = 0; ibnfaAlphabetSize; i++) { int fs, next; s = _bnfa_list_get_next_state(bnfa,r,i); if( s == (int)BNFA_FAIL_STATE ) continue; if( queue_add (queue, s) ) { return -1; } fs = FailState[r]; /* * Locate the next valid state for 'i' starting at fs */ while( (next=_bnfa_list_get_next_state(bnfa,fs,i)) == (int)BNFA_FAIL_STATE ) { fs = FailState[fs]; } /* * Update 's' state failure state to point to the next valid state */ FailState[s] = next; /* * Copy 'next'states MatchList into 's' states MatchList, * we just create a new list nodes, the patterns are not copied. */ for( mlist = MatchList[next];mlist;mlist = mlist->next) { /* Dup the node, don't copy the data */ px = (bnfa_match_node_t*)BNFA_MALLOC(sizeof(bnfa_match_node_t),bnfa->matchlist_memory); if( !px ) { return 0; } px->data = mlist->data; px->next = MatchList[s]; /* insert at head */ MatchList[s] = px; } } } /* Clean up the queue */ queue_free (queue); /* optimize the failure states */ if( bnfa->bnfaOpt ) _bnfa_opt_nfa(bnfa); return 0; } #ifdef ALLOW_NFA_FULL /* * Conver state machine to full format */ static int _bnfa_conv_list_to_full(bnfa_struct_t * bnfa) { int k; bnfa_state_t * p; bnfa_state_t ** NextState = bnfa->bnfaNextState; for(k=0;kbnfaNumStates;k++) { p = BNFA_MALLOC(sizeof(bnfa_state_t)*bnfa->bnfaAlphabetSize,bnfa->nextstate_memory); if(!p) { return -1; } _bnfa_list_conv_row_to_full( bnfa, (bnfa_state_t)k, p ); NextState[k] = p; /* now we have a full format row vector */ } return 0; } #endif /* * Convert state machine to csparse format * * Merges state/transition/failure arrays into one. * * For each state we use a state-word followed by the transition list for * the state sw(state 0 )...tl(state 0) sw(state 1)...tl(state1) sw(state2)... * tl(state2) .... * * The transition and failure states are replaced with the start index of * transition state, this eliminates the NextState[] lookup.... * * The compaction of multiple arays into a single array reduces the total * number of states that can be handled since the max index is 2^24-1, * whereas without compaction we had 2^24-1 states. */ static int _bnfa_conv_list_to_csparse_array(bnfa_struct_t * bnfa) { int m, k, i, nc; bnfa_state_t state; bnfa_state_t * FailState = (bnfa_state_t *)bnfa->bnfaFailState; bnfa_state_t * ps; /* transition list */ bnfa_state_t * pi; /* state indexes into ps */ bnfa_state_t ps_index=0; unsigned nps; bnfa_state_t full[BNFA_MAX_ALPHABET_SIZE]; /* count total state transitions, account for state and control words */ nps = 0; for(k=0;kbnfaNumStates;k++) { nps++; /* state word */ nps++; /* control word */ /* count transitions */ nc = 0; _bnfa_list_conv_row_to_full(bnfa, (bnfa_state_t)k, full ); for( i=0; ibnfaAlphabetSize; i++ ) { state = full[i] & BNFA_SPARSE_MAX_STATE; if( state != 0 ) { nc++; } } /* add in transition count */ if( (k == 0 && bnfa->bnfaForceFullZeroState) || nc > BNFA_SPARSE_MAX_ROW_TRANSITIONS ) { nps += BNFA_MAX_ALPHABET_SIZE; } else { for( i=0; ibnfaAlphabetSize; i++ ) { state = full[i] & BNFA_SPARSE_MAX_STATE; if( state != 0 ) { nps++; } } } } /* check if we have too many states + transitions */ if( nps > BNFA_SPARSE_MAX_STATE ) { /* Fatal */ return -1; } /* Alloc The Transition List - we need an array of bnfa_state_t items of size 'nps' */ ps = BNFA_MALLOC( nps*sizeof(bnfa_state_t),bnfa->nextstate_memory); if( !ps ) { /* Fatal */ return -1; } bnfa->bnfaTransList = ps; /* State Index list for pi - we need an array of bnfa_state_t items of size 'NumStates' */ pi = BNFA_MALLOC( bnfa->bnfaNumStates*sizeof(bnfa_state_t),bnfa->nextstate_memory); if( !pi ) { /* Fatal */ return -1; } /* Build the Transition List Array */ for(k=0;kbnfaNumStates;k++) { pi[k] = ps_index; /* save index of start of state 'k' */ ps[ ps_index ] = k; /* save the state were in as the 1st word */ ps_index++; /* skip past state word */ /* conver state 'k' to full format */ _bnfa_list_conv_row_to_full(bnfa, (bnfa_state_t)k, full ); /* count transitions */ nc = 0; for( i=0; ibnfaAlphabetSize; i++ ) { state = full[i] & BNFA_SPARSE_MAX_STATE; if( state != 0 ) { nc++; } } /* add a full state or a sparse state */ if( (k == 0 && bnfa->bnfaForceFullZeroState) || nc > BNFA_SPARSE_MAX_ROW_TRANSITIONS ) { /* set the control word */ ps[ps_index] = BNFA_SPARSE_FULL_BIT; ps[ps_index] |= FailState[k] & BNFA_SPARSE_MAX_STATE; if( bnfa->bnfaMatchList[k] ) { ps[ps_index] |= BNFA_SPARSE_MATCH_BIT; } ps_index++; /* copy the transitions */ _bnfa_list_conv_row_to_full(bnfa, (bnfa_state_t)k, &ps[ps_index] ); ps_index += BNFA_MAX_ALPHABET_SIZE; /* add in 256 transitions */ } else { /* set the control word */ ps[ps_index] = nc<bnfaMatchList[k] ) { ps[ps_index] |= BNFA_SPARSE_MATCH_BIT; } ps_index++; /* add in the transitions */ for( m=0, i=0; ibnfaAlphabetSize && m nps ) { /* Fatal */ return -1; } /* Replace Transition states with Transition Indices. This allows us to skip using NextState[] to locate the next state This limits us to <16M transitions due to 24 bit state sizes, and the fact we have now converted next-state fields to next-index fields in this array, and we have merged the next-state and state arrays. */ ps_index=0; for(k=0; k< bnfa->bnfaNumStates; k++ ) { if( pi[k] >= nps ) { /* Fatal */ return -1; } //ps_index = pi[k]; /* get index of next state */ ps_index++; /* skip state id */ /* Full Format */ if( ps[ps_index] & BNFA_SPARSE_FULL_BIT ) { /* Do the fail-state */ ps[ps_index] = ( ps[ps_index] & 0xff000000 ) | ( pi[ ps[ps_index] & BNFA_SPARSE_MAX_STATE ] ) ; ps_index++; /* Do the transition-states */ for(i=0;i>BNFA_SPARSE_COUNT_SHIFT; /* Do the cw = [cb | fail-state] */ ps[ps_index] = ( ps[ps_index] & 0xff000000 ) | ( pi[ ps[ps_index] & BNFA_SPARSE_MAX_STATE ] ); ps_index++; /* Do the transition-states */ for(i=0;i nps ) { /* Fatal */ return -1; } } BNFA_FREE(pi,bnfa->bnfaNumStates*sizeof(bnfa_state_t),bnfa->nextstate_memory); return 0; } /* * Print the state machine - rather verbose */ void bnfaPrint(bnfa_struct_t * bnfa) { int k; bnfa_match_node_t ** MatchList; bnfa_match_node_t * mlist; int ps_index=0; bnfa_state_t * ps=0; if( !bnfa ) return; MatchList = bnfa->bnfaMatchList; if( !bnfa->bnfaNumStates ) return; if( bnfa->bnfaFormat ==BNFA_SPARSE ) { printf("Print NFA-SPARSE state machine : %d active states\n", bnfa->bnfaNumStates); ps = bnfa->bnfaTransList; if( !ps ) return; } #ifdef ALLOW_NFA_FULL else if( bnfa->bnfaFormat ==BNFA_FULL ) { printf("Print NFA-FULL state machine : %d active states\n", bnfa->bnfaNumStates); } #endif for(k=0;kbnfaNumStates;k++) { printf(" state %-4d fmt=%d ",k,bnfa->bnfaFormat); if( bnfa->bnfaFormat == BNFA_SPARSE ) { unsigned i,cw,fs,nt,fb,mb; ps_index++; /* skip state number */ cw = ps[ps_index]; /* control word */ fb = (cw & BNFA_SPARSE_FULL_BIT)>>BNFA_SPARSE_VALUE_SHIFT; /* full storage bit */ mb = (cw & BNFA_SPARSE_MATCH_BIT)>>BNFA_SPARSE_VALUE_SHIFT; /* matching state bit */ nt = (cw & BNFA_SPARSE_COUNT_BITS)>>BNFA_SPARSE_VALUE_SHIFT;/* number of transitions 0-63 */ fs = (cw & BNFA_SPARSE_MAX_STATE)>>BNFA_SPARSE_VALUE_SHIFT; /* fail state */ ps_index++; /* skip control word */ printf("mb=%3u fb=%3u fs=%-4u ",mb,fb,fs); if( fb ) { printf(" nt=%-3d : ",bnfa->bnfaAlphabetSize); for( i=0; i<(unsigned)bnfa->bnfaAlphabetSize; i++, ps_index++ ) { if( ps[ps_index] == 0 ) continue; if( isascii((int)i) && isprint((int)i) ) printf("%3c->%-6d\t",i,ps[ps_index]); else printf("%3d->%-6d\t",i,ps[ps_index]); } } else { printf(" nt=%-3d : ",nt); for( i=0; i>BNFA_SPARSE_VALUE_SHIFT) && isprint(ps[ps_index]>>BNFA_SPARSE_VALUE_SHIFT) ) printf("%3c->%-6d\t",ps[ps_index]>>BNFA_SPARSE_VALUE_SHIFT,ps[ps_index] & BNFA_SPARSE_MAX_STATE); else printf("%3d->%-6d\t",ps[ps_index]>>BNFA_SPARSE_VALUE_SHIFT,ps[ps_index] & BNFA_SPARSE_MAX_STATE); } } } #ifdef ALLOW_NFA_FULL else if( bnfa->bnfaFormat == BNFA_FULL ) { int i; bnfa_state_t state; bnfa_state_t * p; bnfa_state_t ** NextState; NextState = (bnfa_state_t **)bnfa->bnfaNextState; if( !NextState ) continue; p = NextState[k]; printf("fs=%-4d nc=256 ",bnfa->bnfaFailState[k]); for( i=0; ibnfaAlphabetSize; i++ ) { state = p[i]; if( state != 0 && state != BNFA_FAIL_STATE ) { if( isascii(i) && isprint(i) ) printf("%3c->%-5d\t",i,state); else printf("%3d->%-5d\t",i,state); } } } #endif printf("\n"); if( MatchList[k] ) printf("---MatchList For State %d\n",k); for( mlist = MatchList[k]; mlist!= NULL; mlist = mlist->next ) { bnfa_pattern_t * pat; pat = (bnfa_pattern_t*)mlist->data; printf("---pattern : %.*s\n",pat->n,pat->casepatrn); } } } /* * Create a new AC state machine */ bnfa_struct_t * bnfaNew(void (*userfree)(void *p), void (*optiontreefree)(void **p), void (*neg_list_free)(void **p)) { bnfa_struct_t * p; int bnfa_memory=0; init_xlatcase (); p = (bnfa_struct_t *) BNFA_MALLOC(sizeof(bnfa_struct_t),bnfa_memory); if(!p) return 0; if( p ) { p->bnfaOpt = 0; p->bnfaCaseMode = BNFA_PER_PAT_CASE; p->bnfaFormat = BNFA_SPARSE; p->bnfaAlphabetSize = BNFA_MAX_ALPHABET_SIZE; p->bnfaForceFullZeroState = 1; p->bnfa_memory = sizeof(bnfa_struct_t); p->userfree = userfree; p->optiontreefree = optiontreefree; p->neg_list_free = neg_list_free; } queue_memory = 0; return p; } void bnfaSetOpt(bnfa_struct_t * p, int flag) { p->bnfaOpt=flag; } void bnfaSetCase(bnfa_struct_t * p, int flag) { if( flag == BNFA_PER_PAT_CASE ) p->bnfaCaseMode = flag; if( flag == BNFA_CASE ) p->bnfaCaseMode = flag; if( flag == BNFA_NOCASE ) p->bnfaCaseMode = flag; } /* * Fee all memory */ void bnfaFree (bnfa_struct_t * bnfa) { int i; bnfa_pattern_t * patrn, *ipatrn; bnfa_match_node_t * mlist, *ilist; for(i = 0; i < bnfa->bnfaNumStates; i++) { /* free match list entries */ mlist = bnfa->bnfaMatchList[i]; while (mlist) { ilist = mlist; mlist = mlist->next; if (ilist->rule_option_tree && bnfa->optiontreefree) { bnfa->optiontreefree(&(ilist->rule_option_tree)); } if (ilist->neg_list && bnfa->neg_list_free) { bnfa->neg_list_free(&(ilist->neg_list)); } BNFA_FREE(ilist,sizeof(bnfa_match_node_t),bnfa->matchlist_memory); } bnfa->bnfaMatchList[i] = 0; #ifdef ALLOW_NFA_FULL /* free next state entries */ if( bnfa->bnfaFormat==BNFA_FULL )/* Full format */ { if( bnfa->bnfaNextState[i] ) { BNFA_FREE(bnfa->bnfaNextState[i],bnfa->bnfaAlphabetSize*sizeof(bnfa_state_t),bnfa->nextstate_memory); } } #endif } /* Free patterns */ patrn = bnfa->bnfaPatterns; while(patrn) { ipatrn=patrn; patrn=patrn->next; BNFA_FREE(ipatrn->casepatrn,ipatrn->n,bnfa->pat_memory); if(bnfa->userfree && ipatrn->userdata) bnfa->userfree(ipatrn->userdata); BNFA_FREE(ipatrn,sizeof(bnfa_pattern_t),bnfa->pat_memory); } /* Free arrays */ BNFA_FREE(bnfa->bnfaFailState,bnfa->bnfaNumStates*sizeof(bnfa_state_t),bnfa->failstate_memory); BNFA_FREE(bnfa->bnfaMatchList,bnfa->bnfaNumStates*sizeof(bnfa_pattern_t*),bnfa->matchlist_memory); BNFA_FREE(bnfa->bnfaNextState,bnfa->bnfaNumStates*sizeof(bnfa_state_t*),bnfa->nextstate_memory); BNFA_FREE(bnfa->bnfaTransList,(2*bnfa->bnfaNumStates+bnfa->bnfaNumTrans)*sizeof(bnfa_state_t*),bnfa->nextstate_memory); free( bnfa ); /* cannot update memory tracker when deleting bnfa so just 'free' it !*/ } /* * Add a pattern to the pattern list */ int bnfaAddPattern (bnfa_struct_t * p, unsigned char *pat, int n, int nocase, int negative, void * userdata ) { bnfa_pattern_t * plist; plist = (bnfa_pattern_t *)BNFA_MALLOC(sizeof(bnfa_pattern_t),p->pat_memory); if(!plist) return -1; plist->casepatrn = (unsigned char *)BNFA_MALLOC(n,p->pat_memory ); if(!plist->casepatrn) { BNFA_FREE(plist,sizeof(bnfa_pattern_t),p->pat_memory); return -1; } memcpy (plist->casepatrn, pat, n); plist->n = n; plist->nocase = nocase; plist->negative = negative; plist->userdata = userdata; plist->next = p->bnfaPatterns; /* insert at front of list */ p->bnfaPatterns = plist; p->bnfaPatternCnt++; return 0; } /* * Compile the patterns into an nfa state machine */ static inline int _bnfaCompile (bnfa_struct_t * bnfa) { bnfa_pattern_t * plist; bnfa_match_node_t ** tmpMatchList; unsigned cntMatchStates; int i; queue_memory =0; /* Count number of states */ for(plist = bnfa->bnfaPatterns; plist != NULL; plist = plist->next) { bnfa->bnfaMaxStates += plist->n; } bnfa->bnfaMaxStates++; /* one extra */ /* Alloc a List based State Transition table */ bnfa->bnfaTransTable =(bnfa_trans_node_t**) BNFA_MALLOC(sizeof(bnfa_trans_node_t*) * bnfa->bnfaMaxStates,bnfa->list_memory ); if(!bnfa->bnfaTransTable) { return -1; } /* Alloc a MatchList table - this has a list of pattern matches for each state */ bnfa->bnfaMatchList=(bnfa_match_node_t**) BNFA_MALLOC(sizeof(void*)*bnfa->bnfaMaxStates,bnfa->matchlist_memory ); if(!bnfa->bnfaMatchList) { return -1; } /* Add each Pattern to the State Table - This forms a keyword trie using lists */ bnfa->bnfaNumStates = 0; for (plist = bnfa->bnfaPatterns; plist != NULL; plist = plist->next) { _bnfa_add_pattern_states (bnfa, plist); } bnfa->bnfaNumStates++; if( bnfa->bnfaNumStates > BNFA_SPARSE_MAX_STATE ) { return -1; /* Call bnfaFree to clean up */ } /* ReAlloc a smaller MatchList table - only need NumStates */ tmpMatchList=bnfa->bnfaMatchList; bnfa->bnfaMatchList=(bnfa_match_node_t**)BNFA_MALLOC(sizeof(void*) * bnfa->bnfaNumStates,bnfa->matchlist_memory); if(!bnfa->bnfaMatchList) { return -1; } memcpy(bnfa->bnfaMatchList,tmpMatchList,sizeof(void*) * bnfa->bnfaNumStates); BNFA_FREE(tmpMatchList,sizeof(void*) * bnfa->bnfaMaxStates,bnfa->matchlist_memory); #ifdef MATCH_LIST_CNT bnfa->bnfaMatchListCnt=(unsigned*)calloc(sizeof(unsigned) * bnfa->bnfaNumStates); if(!bnfa->bnfaMatchListCnt) { return -1; } #endif /* Alloc a failure state table - only need NumStates */ bnfa->bnfaFailState =(bnfa_state_t*)BNFA_MALLOC(sizeof(bnfa_state_t) * bnfa->bnfaNumStates,bnfa->failstate_memory); if(!bnfa->bnfaFailState) { return -1; } #ifdef ALLOW_NFA_FULL if( bnfa->bnfaFormat == BNFA_FULL ) { /* Alloc a state transition table - only need NumStates */ bnfa->bnfaNextState=(bnfa_state_t**)BNFA_MALLOC(sizeof(bnfa_state_t*) * bnfa->bnfaNumStates,bnfa->nextstate_memory); if(!bnfa->bnfaNextState) { return -1; } } #endif /* Build the nfa w/failure states - time the nfa construction */ if( _bnfa_build_nfa (bnfa) ) { return -1; } /* Convert nfa storage format from list to full or sparse */ if( bnfa->bnfaFormat == BNFA_SPARSE ) { if( _bnfa_conv_list_to_csparse_array(bnfa) ) { return -1; } BNFA_FREE(bnfa->bnfaFailState,sizeof(bnfa_state_t)*bnfa->bnfaNumStates,bnfa->failstate_memory); bnfa->bnfaFailState=0; } #ifdef ALLOW_NFA_FULL else if( bnfa->bnfaFormat == BNFA_FULL ) { if( _bnfa_conv_list_to_full( bnfa ) ) { return -1; } } #endif else { return -1; } /* Free up the Table Of Transition Lists */ _bnfa_list_free_table( bnfa ); /* Count states with Pattern Matches */ cntMatchStates=0; for(i=0;ibnfaNumStates;i++) { if( bnfa->bnfaMatchList[i] ) cntMatchStates++; } bnfa->bnfaMatchStates = cntMatchStates; bnfa->queue_memory = queue_memory; bnfaAccumInfo( bnfa ); return 0; } int bnfaCompile (bnfa_struct_t * bnfa, int (*build_tree)(void * id, void **existing_tree), int (*neg_list_func )(void *id, void **list)) { int rval; if ((rval = _bnfaCompile (bnfa))) return rval; if (build_tree && neg_list_func) { bnfaBuildMatchStateTrees( bnfa, build_tree, neg_list_func ); } return 0; } #ifndef DYNAMIC_PREPROCESSOR_CONTEXT int bnfaCompileWithSnortConf (struct _SnortConfig *sc, bnfa_struct_t * bnfa, int (*build_tree)(struct _SnortConfig *, void * id, void **existing_tree), int (*neg_list_func )(void *id, void **list)) { int rval; if ((rval = _bnfaCompile (bnfa))) return rval; if (build_tree && neg_list_func) { bnfaBuildMatchStateTreesWithSnortConf( sc, bnfa, build_tree, neg_list_func ); } return 0; } #endif //DYNAMIC_PREPROCESSOR_CONTEXT #ifdef ALLOW_NFA_FULL /* * Full Matrix Format Search */ static inline unsigned _bnfa_search_full_nfa( bnfa_struct_t * bnfa, unsigned char *Tx, int n, int (*Match)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list), void *data, bnfa_state_t state, int *current_state ) { unsigned char * Tend; unsigned char * T; unsigned char Tchar; unsigned index; bnfa_state_t ** NextState= bnfa->bnfaNextState; bnfa_state_t * FailState= bnfa->bnfaFailState; bnfa_match_node_t ** MatchList= bnfa->bnfaMatchList; bnfa_state_t * pcs; bnfa_match_node_t * mlist; bnfa_pattern_t * patrn; unsigned nfound = 0; int res; unsigned last_match=LAST_STATE_INIT; unsigned last_match_saved=LAST_STATE_INIT; T = Tx; Tend = T + n; for( ; T < Tend; T++ ) { Tchar = xlatcase[ *T ]; for(;;) { pcs = NextState[state]; if( pcs[Tchar] == 0 && state > 0 ) { state = FailState[state]; } else { state = pcs[Tchar]; break; } } if( state ) { if( state == last_match ) continue; last_match_saved=last_match; last_match = state; { mlist = MatchList[state]; if (!mlist) { continue; } patrn = (bnfa_pattern_t*)mlist->data; if( ( T - Tx) < patrn->n ) index = 0; else index = T - Tx - patrn->n + 1; nfound++; /* Don't do anything specific for case sensitive patterns and not, * since that will be covered by the rule tree itself. Each tree * might have both case sensitive & case insensitive patterns. */ res = Match (patrn->userdata, mlist->rule_option_tree, index, data, mlist->neg_list); if ( res > 0 ) { *current_state = state; return nfound; } else if( res < 0 ) { last_match = last_match_saved; } } } } *current_state = state; return nfound; } /* * Full Matrix Format Search - Exact matching patterns only */ static inline unsigned _bnfa_search_full_nfa_case( bnfa_struct_t * bnfa, unsigned char *Tx, int n, int (*Match)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list), void *data, bnfa_state_t state, int *current_state ) { unsigned char * Tend; unsigned char * T; unsigned char Tchar; unsigned index; bnfa_state_t ** NextState= bnfa->bnfaNextState; bnfa_state_t * FailState= bnfa->bnfaFailState; bnfa_match_node_t ** MatchList= bnfa->bnfaMatchList; bnfa_state_t * pcs; bnfa_match_node_t * mlist; bnfa_pattern_t * patrn; unsigned nfound = 0; unsigned last_match=LAST_STATE_INIT; unsigned last_match_saved=LAST_STATE_INIT; int res; T = Tx; Tend = T + n; for( ; T < Tend; T++ ) { Tchar = *T ; for(;;) { pcs = NextState[state]; if( pcs[Tchar] == 0 && state > 0 ) { state = FailState[state]; } else { state = pcs[Tchar]; break; } } if( state ) { if( state == last_match ) continue; last_match_saved=last_match; last_match = state; { mlist = MatchList[state]; if (!mlist) { continue; } patrn = (bnfa_pattern_t*)mlist->data; if( ( T - Tx) < patrn->n ) index = 0; else index = T - Tx - patrn->n + 1; nfound++; /* Don't do anything specific for case (in)sensitive patterns * since that will be covered by the rule tree itself. Each * tree might have both case sensitive & case insensitive patterns. */ res = Match (patrn->userdata, mlist->rule_option_tree, index, data, mlist->neg_list); if ( res > 0 ) { *current_state = state; return nfound; } else if( res < 0 ) { last_match = last_match_saved; } } } } *current_state = state; return nfound; } /* * Full Matrix Format Search - no case */ static inline unsigned _bnfa_search_full_nfa_nocase( bnfa_struct_t * bnfa, unsigned char *Tx, int n, int (*Match)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list), void *data, bnfa_state_t state, int *current_state ) { unsigned char * Tend; unsigned char * T; unsigned char Tchar; unsigned index; bnfa_state_t ** NextState= bnfa->bnfaNextState; bnfa_state_t * FailState= bnfa->bnfaFailState; bnfa_match_node_t ** MatchList= bnfa->bnfaMatchList; bnfa_state_t * pcs; bnfa_match_node_t * mlist; bnfa_pattern_t * patrn; unsigned nfound = 0; unsigned last_match=LAST_STATE_INIT; unsigned last_match_saved=LAST_STATE_INIT; int res; T = Tx; Tend = T + n; for( ; T < Tend; T++ ) { Tchar = xlatcase[ *T ]; for(;;) { pcs = NextState[state]; if( pcs[Tchar] == 0 && state > 0 ) { state = FailState[state]; } else { state = pcs[Tchar]; break; } } if( state ) { if( state == last_match ) continue; last_match_saved=last_match; last_match = state; { mlist = MatchList[state]; if (!mlist) { continue; } patrn = (bnfa_pattern_t*)mlist->data; if( ( T - Tx) < patrn->n ) index = 0; else index = T - Tx - patrn->n + 1; /* Don't do anything specific for case sensitive patterns and not, * since that will be covered by the rule tree itself. Each tree * might have both case sensitive & case insensitive patterns. */ res = Match (patrn->userdata, mlist->rule_option_tree, index, data, mlist->neg_list); if ( res > 0 ) { *current_state = state; return nfound; } else if( res < 0 ) { last_match = last_match_saved; } } } } *current_state = state; return nfound; } #endif /* binary array search on sparse transition array O(logN) search times..same as a binary tree. data must be in sorted order in the array. return: = -1 => not found >= 0 => index of element 'val' notes: val is tested against the high 8 bits of the 'a' array entry, this is particular to the storage format we are using. */ static inline int _bnfa_binearch( bnfa_state_t * a, int a_len, int val ) { int m, l, r; int c; l = 0; r = a_len - 1; while( r >= l ) { m = ( r + l ) >> 1; c = a[m] >> BNFA_SPARSE_VALUE_SHIFT; if( val == c ) { return m; } else if( val < c ) { r = m - 1; } else /* val > c */ { l = m + 1; } } return -1; } /* * Sparse format for state table using single array storage * * word 1: state * word 2: control-word = cb<<24| fs * cb : control-byte * : mb | fb | nt * mb : bit 8 set if match state, zero otherwise * fb : bit 7 set if using full format, zero otherwise * nt : number of transitions 0..63 (more than 63 requires full format) * fs: failure-transition-state * word 3+: byte-value(0-255) << 24 | transition-state */ static inline unsigned _bnfa_get_next_state_csparse_nfa_qx(bnfa_state_t * pcx, unsigned sindex, unsigned input) { int k; int nc; int index; register bnfa_state_t * pcs; for(;;) { pcs = pcx + sindex + 1; /* skip state-id == 1st word */ if( pcs[0] & BNFA_SPARSE_FULL_BIT ) { if( sindex == 0 ) { return pcs[1+input] & BNFA_SPARSE_MAX_STATE; } else { if( pcs[1+input] & BNFA_SPARSE_MAX_STATE ) return pcs[1+input] & BNFA_SPARSE_MAX_STATE; } } else { nc = (pcs[0]>>BNFA_SPARSE_COUNT_SHIFT) & BNFA_SPARSE_MAX_ROW_TRANSITIONS; if( nc > BNFA_SPARSE_LINEAR_SEARCH_LIMIT ) { /* binary search... */ index = _bnfa_binearch( pcs+1, nc, input ); if( index >= 0 ) { return pcs[index+1] & BNFA_SPARSE_MAX_STATE; } } else { /* linear search... */ for( k=0; k>BNFA_SPARSE_VALUE_SHIFT) == input ) { return pcs[k+1] & BNFA_SPARSE_MAX_STATE; } } } } return 0; /* no transition keyword match failed */ } } /* * Sparse format for state table using single array storage * * word 1: state * word 2: control-word = cb<<24| fs * cb : control-byte * : mb | fb | nt * mb : bit 8 set if match state, zero otherwise * fb : bit 7 set if using full format, zero otherwise * nt : number of transitions 0..63 (more than 63 requires full format) * fs: failure-transition-state * word 3+: byte-value(0-255) << 24 | transition-state */ static inline unsigned _bnfa_get_next_state_csparse_nfa(bnfa_state_t * pcx, unsigned sindex, unsigned input) { int k; int nc; int index; register bnfa_state_t * pcs; for(;;) { pcs = pcx + sindex + 1; /* skip state-id == 1st word */ if( pcs[0] & BNFA_SPARSE_FULL_BIT ) { if( sindex == 0 ) { return pcs[1+input] & BNFA_SPARSE_MAX_STATE; } else { if( pcs[1+input] & BNFA_SPARSE_MAX_STATE ) return pcs[1+input] & BNFA_SPARSE_MAX_STATE; } } else { nc = (pcs[0]>>BNFA_SPARSE_COUNT_SHIFT) & BNFA_SPARSE_MAX_ROW_TRANSITIONS; if( nc > BNFA_SPARSE_LINEAR_SEARCH_LIMIT ) { /* binary search... */ index = _bnfa_binearch( pcs+1, nc, input ); if( index >= 0 ) { return pcs[index+1] & BNFA_SPARSE_MAX_STATE; } } else { /* linear search... */ for( k=0; k>BNFA_SPARSE_VALUE_SHIFT) == input ) { return pcs[k+1] & BNFA_SPARSE_MAX_STATE; } } } } /* no transition found ... get the failure state and try again */ sindex = pcs[0] & BNFA_SPARSE_MAX_STATE; } } /* * Per Pattern case search, case is on per pattern basis * standard snort search * note: index is not used by snort, so it's commented * TRACK_Q can impose a modest couple % performance difference in the * pattern matching rate. */ /* Queue whole pattern groups at end states in AC */ void bnfa_print_qinfo(void) { #ifdef BNFA_TRACK_Q if( snort_conf->max_inq ) { LogMessage("ac-bnfa: queue size = %d, max = %d\n",snort_conf->max_inq, MAX_INQ ); LogMessage("ac-bnfa: queue flushes = "STDu64"\n", snort_conf->tot_inq_flush ); LogMessage("ac-bnfa: queue inserts = "STDu64"\n", snort_conf->tot_inq_inserts ); LogMessage("ac-bnfa: queue uinserts = "STDu64"\n", snort_conf->tot_inq_uinserts ); } #endif } static inline void _init_queue(bnfa_struct_t * b) { b->inq=0; b->inq_flush=0; } /* uniquely insert into q, should splay elements for performance */ static inline int _add_queue(bnfa_struct_t* b, bnfa_match_node_t * p ) { int i; #ifdef BNFA_TRACK_Q snort_conf->tot_inq_inserts++; #endif for(i=(int)(b->inq)-1;i>=0;i--) if( p == b->q[i] ) return 0; #ifdef BNFA_TRACK_Q snort_conf->tot_inq_uinserts++; #endif if( b->inq < MAX_INQ ) { b->q[ b->inq++ ] = p; } if( b->inq == MAX_INQ ) { #ifdef BNFA_TRACK_Q b->inq_flush++; #endif return 1; } return 0; } static inline unsigned _process_queue( bnfa_struct_t * bnfa, int (*Match)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list), void *data ) { bnfa_match_node_t * mlist; bnfa_pattern_t * patrn; int res; unsigned int i; #ifdef BNFA_TRACK_Q if( bnfa->inq > snort_conf->max_inq ) snort_conf->max_inq = bnfa->inq; snort_conf->tot_inq_flush += bnfa->inq_flush; #endif for( i=0; iinq; i++ ) { mlist = bnfa->q[i]; if (mlist) { patrn = (bnfa_pattern_t*)mlist->data; /*process a pattern - case is handled by otn processing */ res = Match (patrn->userdata, mlist->rule_option_tree, 0, data, mlist->neg_list); if ( res > 0 ) { /* terminate matching */ bnfa->inq=0;/* clear the q */ return 1; } } } bnfa->inq=0;/* clear the q */ return 0; } static inline unsigned _bnfa_search_csparse_nfa_qx(bnfa_struct_t * bnfa, unsigned char *T, int n, int (*Match)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list), void *data ) { bnfa_match_node_t * mlist; unsigned char * Tend; bnfa_match_node_t ** MatchList = bnfa->bnfaMatchList; bnfa_state_t * transList = bnfa->bnfaTransList; unsigned sindex=0; Tend = T + n; for(; TbnfaMatchList; bnfa_state_t * transList = bnfa->bnfaTransList; unsigned last_sindex; Tend = T + n; _init_queue(bnfa); for(; TbnfaMatchList; bnfa_pattern_t * patrn; bnfa_state_t * transList = bnfa->bnfaTransList; unsigned nfound = 0; unsigned last_match=LAST_STATE_INIT; unsigned last_match_saved=LAST_STATE_INIT; int res; #ifdef MATCH_LIST_CNT unsigned * MatchTestCnt = bnfa->bnfaMatchTestCnt; #endif T = Tx; Tend = T + n; for(; Tdata; if( ( T - Tx) < patrn->n ) index = 0; else index = T - Tx - patrn->n + 1; nfound++; /* Don't do anything specific for case sensitive patterns and not, * since that will be covered by the rule tree itself. Each tree * might have both case sensitive & case insensitive patterns. */ res = Match (patrn->userdata, mlist->rule_option_tree, index, data, mlist->neg_list); if ( res > 0 ) { *current_state = sindex; return nfound; } else if( res < 0 ) { last_match = last_match_saved; } } } } *current_state = sindex; return nfound; } /* * Case specific search, global to all patterns * * note: index is not used by snort, so it's commented */ static inline unsigned _bnfa_search_csparse_nfa_case( bnfa_struct_t * bnfa, unsigned char *Tx, int n, int (*Match)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list), void *data, unsigned sindex, int *current_state ) { bnfa_match_node_t * mlist; unsigned char * Tend; unsigned char * T; unsigned index; bnfa_match_node_t ** MatchList = bnfa->bnfaMatchList; bnfa_pattern_t * patrn; bnfa_state_t * transList = bnfa->bnfaTransList; unsigned nfound = 0; unsigned last_match=LAST_STATE_INIT; unsigned last_match_saved=LAST_STATE_INIT; int res; T = Tx; Tend = T + n; for(; Tdata; if( ( T - Tx) < patrn->n ) index = 0; else index = T - Tx - patrn->n + 1; nfound++; /* Don't do anything specific for case sensitive patterns and not, * since that will be covered by the rule tree itself. Each tree * might have both case sensitive & case insensitive patterns. */ res = Match (patrn->userdata, mlist->rule_option_tree, index, data, mlist->neg_list); if ( res > 0 ) { *current_state = sindex; return nfound; } else if( res < 0 ) { last_match = last_match_saved; } } } } *current_state = sindex; return nfound; } /* * NoCase search - global to all patterns * * note: index is not used by snort, so it's commented */ static inline unsigned _bnfa_search_csparse_nfa_nocase( bnfa_struct_t * bnfa, unsigned char *Tx, int n, int (*Match)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list), void *data, unsigned sindex, int *current_state ) { bnfa_match_node_t * mlist; unsigned char * Tend; unsigned char * T; unsigned char Tchar; unsigned index; bnfa_match_node_t ** MatchList = bnfa->bnfaMatchList; bnfa_pattern_t * patrn; bnfa_state_t * transList = bnfa->bnfaTransList; unsigned nfound = 0; unsigned last_match=LAST_STATE_INIT; unsigned last_match_saved=LAST_STATE_INIT; int res; T = Tx; Tend = T + n; for(; Tdata; if( ( T - Tx) < patrn->n ) index = 0; else index = T - Tx - patrn->n + 1; nfound++; /* Don't do anything specific for case sensitive patterns and not, * since that will be covered by the rule tree itself. Each tree * might have both case sensitive & case insensitive patterns. */ res = Match (patrn->userdata, mlist->rule_option_tree, index, data, mlist->neg_list); if ( res > 0 ) { *current_state = sindex; return nfound; } else if( res < 0 ) { last_match = last_match_saved; } } } } *current_state = sindex; return nfound; } /* * BNFA Search Function * * bnfa - state machine * Tx - text buffer to search * n - number of bytes in Tx * Match - function to call when a match is found * data - user supplied data that is passed to the Match function * sindex - state tracker, set value to zero to reset the state machine, * zero should be the value passed in on the 1st buffer or each buffer * that is to be analyzed on its own, the state machine updates this * during searches. This allows for sequential buffer searchs without * reseting the state machine. Save this value as returned from the * previous search for the next search. * * returns * The state or sindex of the state machine. This can than be passed back * in on the next search, if desired. */ unsigned bnfaSearchX( bnfa_struct_t * bnfa, unsigned char *T, int n, int (*Match)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list), void *data, unsigned sindex, int* current_state ) { int ret; _init_queue(bnfa); while( n > 0) { ret = _bnfa_search_csparse_nfa_qx( bnfa, T++, n--, Match, data ); if( ret ) return 0; } return _process_queue( bnfa, Match, data ); } unsigned bnfaSearch( bnfa_struct_t * bnfa, unsigned char *Tx, int n, int (*Match)(void * id, void *tree, int index, void *data, void *neg_list), void *data, unsigned sindex, int* current_state ) { int ret = 0; if (current_state) { sindex = (unsigned)*current_state; } #ifdef ALLOW_NFA_FULL if( bnfa->bnfaFormat == BNFA_SPARSE ) { if( bnfa->bnfaCaseMode == BNFA_PER_PAT_CASE ) { if (bnfa->bnfaMethod) { ret = _bnfa_search_csparse_nfa( bnfa, Tx, n, (int (*)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list)) Match, data, sindex, current_state ); } else { ret = _bnfa_search_csparse_nfa_q( bnfa, Tx, n, (int (*)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list)) Match, data, sindex, current_state ); } } else if( bnfa->bnfaCaseMode == BNFA_CASE ) { ret = _bnfa_search_csparse_nfa_case( bnfa, Tx, n, (int (*)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list)) Match, data, sindex, current_state ); } else /* NOCASE */ { ret = _bnfa_search_csparse_nfa_nocase( bnfa, Tx, n, (int (*)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list)) Match, data, sindex, current_state ); } } else if( bnfa->bnfaFormat == BNFA_FULL ) { if( bnfa->bnfaCaseMode == BNFA_PER_PAT_CASE ) { ret = _bnfa_search_full_nfa( bnfa, Tx, n, (int (*)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list)) Match, data, (bnfa_state_t) sindex, current_state ); } else if( bnfa->bnfaCaseMode == BNFA_CASE ) { ret = _bnfa_search_full_nfa_case( bnfa, Tx, n, (int (*)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list)) Match, data, (bnfa_state_t) sindex, current_state ); } else { ret = _bnfa_search_full_nfa_nocase( bnfa, Tx, n, (int (*)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list)) Match, data, (bnfa_state_t) sindex, current_state ); } } #else if( bnfa->bnfaCaseMode == BNFA_PER_PAT_CASE ) { if (bnfa->bnfaMethod) { ret = _bnfa_search_csparse_nfa( bnfa, Tx, n, (int (*)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list)) Match, data, sindex, current_state ); } else { ret = _bnfa_search_csparse_nfa_q( bnfa, Tx, n, (int (*)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list)) Match, data, sindex, current_state ); } } else if( bnfa->bnfaCaseMode == BNFA_CASE ) { ret = _bnfa_search_csparse_nfa_case( bnfa, Tx, n, (int (*)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list)) Match, data, sindex, current_state ); } else/* NOCASE */ { ret = _bnfa_search_csparse_nfa_nocase( bnfa, Tx, n, (int (*)(bnfa_pattern_t * id, void *tree, int index, void *data, void *neg_list)) Match, data, sindex, current_state ); } #endif return ret; } int bnfaPatternCount( bnfa_struct_t * p) { return p->bnfaPatternCnt; } /* * Summary Info Data */ static bnfa_struct_t summary; static int summary_cnt=0; /* * Info: Print info a particular state machine. */ void bnfaPrintInfoEx( bnfa_struct_t * p, char * text ) { unsigned max_memory; if( !p->bnfaNumStates ) { return; } max_memory = p->bnfa_memory + p->pat_memory + p->list_memory + p->matchlist_memory + p->failstate_memory + p->nextstate_memory; if( text && summary_cnt ) { LogMessage("+-[AC-BNFA Search Info%s]------------------------------\n",text); LogMessage("| Instances : %d\n",summary_cnt); } else { LogMessage("+-[AC-BNFA Search Info]------------------------------\n"); } LogMessage("| Patterns : %d\n",p->bnfaPatternCnt); LogMessage("| Pattern Chars : %d\n",p->bnfaMaxStates); LogMessage("| Num States : %d\n",p->bnfaNumStates); LogMessage("| Num Match States : %d\n",p->bnfaMatchStates); if( max_memory < 1024*1024 ) { LogMessage("| Memory : %.2fKbytes\n", (double)max_memory/1024 ); LogMessage("| Patterns : %.2fK\n",(double)p->pat_memory/1024 ); LogMessage("| Match Lists : %.2fK\n",(double)p->matchlist_memory/1024 ); LogMessage("| Transitions : %.2fK\n",(double)p->nextstate_memory/1024 ); } else { LogMessage("| Memory : %.2fMbytes\n", (double)max_memory/(1024*1024) ); LogMessage("| Patterns : %.2fM\n",(double)p->pat_memory/(1024*1024) ); LogMessage("| Match Lists : %.2fM\n",(double)p->matchlist_memory/(1024*1024) ); LogMessage("| Transitions : %.2fM\n",(double)p->nextstate_memory/(1024*1024) ); } LogMessage("+-------------------------------------------------\n"); } void bnfaPrintInfo( bnfa_struct_t * p ) { bnfaPrintInfoEx( p, 0 ); } void bnfaPrintSummary( void ) { bnfaPrintInfoEx( &summary, " Summary" ); } void bnfaInitSummary( void ) { summary_cnt=0; memset(&summary,0,sizeof(bnfa_struct_t)); } void bnfaAccumInfo( bnfa_struct_t * p ) { bnfa_struct_t * px = &summary; summary_cnt++; px->bnfaAlphabetSize = p->bnfaAlphabetSize; px->bnfaPatternCnt += p->bnfaPatternCnt; px->bnfaMaxStates += p->bnfaMaxStates; px->bnfaNumStates += p->bnfaNumStates; px->bnfaNumTrans += p->bnfaNumTrans; px->bnfaMatchStates += p->bnfaMatchStates; px->bnfa_memory += p->bnfa_memory; px->pat_memory += p->pat_memory; px->list_memory += p->list_memory; px->matchlist_memory += p->matchlist_memory; px->nextstate_memory += p->nextstate_memory; px->failstate_memory += p->failstate_memory; } #ifdef MATCH_LIST_CNT void bnfaPrintMatchListCnt( bnfa_struct_t * p ) { unsigned * cnt = p->bnfaMatchListCnt; int i; bnfa_match_node_t * mn; bnfa_pattern_t * patrn; printf("[ MatchListCnt for ac-bnfa state machine\n ]"); for(i=0;ibnfaNumStates;i++) { if( cnt[i] ) { printf("state[%d] cnt=%d",i,cnt[i]); mn = bnfa->MatchList[i] ; if( mn ) { patrn =(bnfa_pattern_t *)mn->data; //xprintOTNSidGid(cnt,patrn->userdata); } printf("\n"); fflush(stdout); } } } #endif #ifdef BNFA_MAIN #include /* * Text Data Buffer */ unsigned char text[512]; unsigned char text2[512]; static int s_verbose=0; /* * A Match is found */ int MatchFound (void* id, void *tree, int index, void *data, void *neglist) { fprintf (stdout, "%s\n", (char *) data); return 0; } void objfree(void **obj) { return; } int buildtree(void *id, void **existing) { return 1; } int neglist(void *id, void **list) { return 1; } void LogMessage(const char *format,...) { va_list ap; va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap); } SnortConfig sc; SnortConfig *snort_conf; /* * */ int main (int argc, char **argv) { int i, nc, nocase = 0; bnfa_struct_t * bnfa; int current_state = 0; bool split_search = false; char * p; if (argc < 3) { fprintf (stderr,"Usage: %s search-text pattern +pattern... [flags]\n",argv[0]); fprintf (stderr," flags: -q -nocase -splitsearch -v\n"); exit (0); } memset(&sc, 0, sizeof(SnortConfig)); snort_conf = ≻ bnfa = bnfaNew(free, objfree, objfree); if( !bnfa ) { printf("bnfa-no memory\n"); exit(0); } strncpy (text, argv[1], sizeof(text) - 1); text[sizeof(text) - 1] = '\0'; bnfa->bnfaMethod = 1; for (i = 1; i < argc; i++) { if (strcmp (argv[i], "-nocase") == 0){ nocase = 1; } if (strcmp (argv[i], "-v") == 0){ s_verbose=1; } if (strcmp (argv[i], "-splitsearch") == 0){ int len2 = strlen(text)/2; split_search =true; strncpy(text2, &text[len2], sizeof(text2) -1 ); text[len2] = '\0'; text2[len2] = '\0'; } if (strcmp (argv[i], "-q") == 0){ bnfa->bnfaMethod = 0; } } for (i = 2; i < argc; i++) { if (argv[i][0] == '-') continue; p = argv[i]; if ( *p == '+') { nc=1; p++; } else { nc = nocase; } bnfaAddPattern (bnfa, p, strlen(p), nc, 0, (void*)NULL); } if(s_verbose)printf("Patterns added\n"); //Print_DFA (acsm); bnfaCompile (bnfa, buildtree, neglist); //Write_DFA(acsm, "bnfa-snort.dfa") ; if(s_verbose) printf("Patterns compiled--written to file.\n"); bnfaPrintInfo ( bnfa ); bnfaPrintSummary ( ); bnfaSearch (bnfa, text, strlen (text), MatchFound, NULL, current_state, ¤t_state); if (split_search) bnfaSearch (bnfa, text2, strlen (text2), MatchFound, NULL, current_state, ¤t_state); bnfaFree (bnfa); printf ("normal pgm end\n"); return (0); } #endif /* */ snort-2.9.15.1/src/sfutil/bnfa_search.h0000644000175200017520000001363313571422607014557 00000000000000/* ** bnfa_search.h ** ** Basic NFA based multi-pattern search using Aho_corasick construction, ** and compacted sparse storage. ** ** Version 3.0 ** ** author: marc norton ** date: 12/21/05 ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2005-2013 Sourcefire, Inc. ** ** LICENSE (GPL) ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, ** USA k** */ #include #include #include #ifndef BNFA_SEARCH_H #define BNFA_SEARCH_H /* debugging - allow printing the trie and nfa in list format */ /* #define ALLOW_LIST_PRINT */ /* debugging - enable full format */ /* #define ALLOW_NFA_FULL */ /* * DEFINES and Typedef's */ //#define SPARSE_FULL_STATE_0 #define BNFA_MAX_ALPHABET_SIZE 256 #define BNFA_FAIL_STATE 0xffffffff #define BNFA_SPARSE_LINEAR_SEARCH_LIMIT 6 #define BNFA_SPARSE_MAX_STATE 0x00ffffff #define BNFA_SPARSE_COUNT_SHIFT 24 #define BNFA_SPARSE_VALUE_SHIFT 24 #define BNFA_SPARSE_MATCH_BIT 0x80000000 #define BNFA_SPARSE_FULL_BIT 0x40000000 #define BNFA_SPARSE_COUNT_BITS 0x3f000000 #define BNFA_SPARSE_MAX_ROW_TRANSITIONS 0x3f typedef unsigned int bnfa_state_t; /* * Internal Pattern Representation */ typedef struct bnfa_pattern { struct bnfa_pattern * next; unsigned char * casepatrn; /* case specific */ int n; /* pattern len */ int nocase; /* nocase flag */ int negative; /* pattern is negated */ void * userdata; /* ptr to users pattern data/info */ } bnfa_pattern_t; /* * List format transition node */ typedef struct bnfa_trans_node_s { bnfa_state_t key; bnfa_state_t next_state; struct bnfa_trans_node_s * next; } bnfa_trans_node_t; /* * List format patterns */ typedef struct bnfa_match_node_s { void * data; void * rule_option_tree; void * neg_list; struct bnfa_match_node_s * next; } bnfa_match_node_t; /* * Final storage type for the state transitions */ enum { BNFA_FULL, BNFA_SPARSE }; enum { BNFA_PER_PAT_CASE, BNFA_CASE, BNFA_NOCASE }; /* * Aho-Corasick State Machine Struct */ typedef struct { int bnfaMethod; int bnfaCaseMode; int bnfaFormat; int bnfaAlphabetSize; int bnfaOpt; unsigned bnfaPatternCnt; bnfa_pattern_t * bnfaPatterns; int bnfaMaxStates; int bnfaNumStates; int bnfaNumTrans; int bnfaMatchStates; bnfa_trans_node_t ** bnfaTransTable; bnfa_state_t ** bnfaNextState; bnfa_match_node_t ** bnfaMatchList; bnfa_state_t * bnfaFailState; bnfa_state_t * bnfaTransList; int bnfaForceFullZeroState; int bnfa_memory; int pat_memory; int list_memory; int queue_memory; int nextstate_memory; int failstate_memory; int matchlist_memory; void (*userfree)(void *); void (*optiontreefree)(void **); void (*neg_list_free)(void **); #define MAX_INQ 32 unsigned inq; unsigned inq_flush; void * q[MAX_INQ]; }bnfa_struct_t; /* * Prototypes */ bnfa_struct_t * bnfaNew ( void (*userfree)(void *p), void (*optiontreefree)(void **p), void (*neg_list_free)(void **p)); void bnfaSetOpt(bnfa_struct_t * p, int flag); void bnfaSetCase(bnfa_struct_t * p, int flag); void bnfaFree( bnfa_struct_t * pstruct ); int bnfaAddPattern( bnfa_struct_t * pstruct, unsigned char * pat, int patlen, int nocase, int negative, void * userdata); int bnfaCompile( bnfa_struct_t * pstruct, int (*build_tree)(void * id, void **existing_tree), int (*neg_list_func)(void *id, void **list)); struct _SnortConfig; int bnfaCompileWithSnortConf( struct _SnortConfig *, bnfa_struct_t * pstruct, int (*build_tree)(struct _SnortConfig *, void * id, void **existing_tree), int (*neg_list_func)(void *id, void **list)); unsigned bnfaSearch( bnfa_struct_t * pstruct, unsigned char * t, int tlen, int (*match)(void * id, void *tree, int index, void *data, void *neg_list), void * sdata, unsigned sindex, int* current_state ); int bnfaPatternCount( bnfa_struct_t * p); void bnfaPrint( bnfa_struct_t * pstruct); /* prints the nfa states-verbose!! */ void bnfaPrintInfo( bnfa_struct_t * pstruct); /* print info on this search engine */ /* * Summary - this tracks search engine information accross multiple instances of * search engines. It helps in snort where we have many search engines, each using * rule grouping, to track total patterns, states, memory, etc... * */ void bnfaPrintInfoEx( bnfa_struct_t * p, char * text ); void bnfaAccumInfo( bnfa_struct_t * pstruct); /* add info to summary over multiple search engines */ void bnfaPrintSummary(void); /* print current summary */ void bnfaInitSummary(void); /* reset accumulator foir global summary over multiple engines */ void bnfa_print_qinfo(void); #endif snort-2.9.15.1/src/sfutil/mpse.c0000644000175200017520000004572013571422607013265 00000000000000/* * $Id$ * * mpse.c * * An abstracted interface to the Multi-Pattern Matching routines, * thats why we're passing 'void *' objects around. * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2002-2013 Sourcefire, Inc. * Marc A Norton * * Updates: * 3/06 - Added AC_BNFA search ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "bitop.h" #include "bnfa_search.h" #include "acsmx.h" #include "acsmx2.h" #include "sfksearch.h" #include "mpse.h" #include "snort_debug.h" #include "sf_types.h" #include "util.h" #ifdef DYNAMIC_PREPROC_CONTEXT #include "sf_dynamic_preprocessor.h" #endif //DYNAMIC_PREPROC_CONTEXT #ifdef INTEL_SOFT_CPM #include "intel-soft-cpm.h" #endif #include "profiler.h" #include "snort.h" #ifdef PERF_PROFILING PreprocStats mpsePerfStats; #endif static uint64_t s_bcnt=0; typedef struct _mpse_struct { int method; void * obj; int verbose; uint64_t bcnt; char inc_global_counter; } MPSE; void * mpseNew( int method, int use_global_counter_flag, void (*userfree)(void *p), void (*optiontreefree)(void **p), void (*neg_list_free)(void **p)) { MPSE * p; p = (MPSE*)calloc( 1,sizeof(MPSE) ); if( !p ) return NULL; p->method = method; p->verbose = 0; p->obj = NULL; p->bcnt = 0; p->inc_global_counter = (char)use_global_counter_flag; switch( method ) { case MPSE_AC_BNFA: p->obj=bnfaNew(userfree, optiontreefree, neg_list_free); if(p->obj) ((bnfa_struct_t*)(p->obj))->bnfaMethod = 1; break; case MPSE_AC_BNFA_Q: p->obj=bnfaNew(userfree, optiontreefree, neg_list_free); if(p->obj) ((bnfa_struct_t*)(p->obj))->bnfaMethod = 0; break; case MPSE_AC: p->obj = acsmNew(userfree, optiontreefree, neg_list_free); break; case MPSE_ACF: p->obj = acsmNew2(userfree, optiontreefree, neg_list_free); if(p->obj)acsmSelectFormat2((ACSM_STRUCT2*)p->obj,ACF_FULL ); break; case MPSE_ACF_Q: p->obj = acsmNew2(userfree, optiontreefree, neg_list_free); if(p->obj)acsmSelectFormat2((ACSM_STRUCT2*)p->obj,ACF_FULLQ ); break; case MPSE_ACS: p->obj = acsmNew2(userfree, optiontreefree, neg_list_free); if(p->obj)acsmSelectFormat2((ACSM_STRUCT2*)p->obj,ACF_SPARSE ); break; case MPSE_ACB: p->obj = acsmNew2(userfree, optiontreefree, neg_list_free); if(p->obj)acsmSelectFormat2((ACSM_STRUCT2*)p->obj,ACF_BANDED ); break; case MPSE_ACSB: p->obj = acsmNew2(userfree, optiontreefree, neg_list_free); if(p->obj)acsmSelectFormat2((ACSM_STRUCT2*)p->obj,ACF_SPARSEBANDS ); break; case MPSE_LOWMEM: p->obj = KTrieNew(0,userfree, optiontreefree, neg_list_free); break; case MPSE_LOWMEM_Q: p->obj = KTrieNew(1,userfree, optiontreefree, neg_list_free); break; default: /* p is free'd below if no case */ break; } if( !p->obj ) { free(p); p = NULL; } return (void *)p; } #ifndef DYNAMIC_PREPROC_CONTEXT void * mpseNewWithSnortConfig( struct _SnortConfig *sc, int method, int use_global_counter_flag, void (*userfree)(void *p), void (*optiontreefree)(void **p), void (*neg_list_free)(void **p)) { MPSE * p; p = (MPSE*)calloc( 1,sizeof(MPSE) ); if( !p ) return NULL; p->method = method; p->verbose = 0; p->obj = NULL; p->bcnt = 0; p->inc_global_counter = (char)use_global_counter_flag; switch( method ) { case MPSE_AC_BNFA: p->obj=bnfaNew(userfree, optiontreefree, neg_list_free); if(p->obj) ((bnfa_struct_t*)(p->obj))->bnfaMethod = 1; break; case MPSE_AC_BNFA_Q: p->obj=bnfaNew(userfree, optiontreefree, neg_list_free); if(p->obj) ((bnfa_struct_t*)(p->obj))->bnfaMethod = 0; break; case MPSE_AC: p->obj = acsmNew(userfree, optiontreefree, neg_list_free); break; case MPSE_ACF: p->obj = acsmNew2(userfree, optiontreefree, neg_list_free); if(p->obj)acsmSelectFormat2((ACSM_STRUCT2*)p->obj,ACF_FULL ); break; case MPSE_ACF_Q: p->obj = acsmNew2(userfree, optiontreefree, neg_list_free); if(p->obj)acsmSelectFormat2((ACSM_STRUCT2*)p->obj,ACF_FULLQ ); break; case MPSE_ACS: p->obj = acsmNew2(userfree, optiontreefree, neg_list_free); if(p->obj)acsmSelectFormat2((ACSM_STRUCT2*)p->obj,ACF_SPARSE ); break; case MPSE_ACB: p->obj = acsmNew2(userfree, optiontreefree, neg_list_free); if(p->obj)acsmSelectFormat2((ACSM_STRUCT2*)p->obj,ACF_BANDED ); break; case MPSE_ACSB: p->obj = acsmNew2(userfree, optiontreefree, neg_list_free); if(p->obj)acsmSelectFormat2((ACSM_STRUCT2*)p->obj,ACF_SPARSEBANDS ); break; case MPSE_LOWMEM: p->obj = KTrieNew(0,userfree, optiontreefree, neg_list_free); break; case MPSE_LOWMEM_Q: p->obj = KTrieNew(1,userfree, optiontreefree, neg_list_free); break; #ifdef INTEL_SOFT_CPM case MPSE_INTEL_CPM: p->obj=IntelPmNew(sc, userfree, optiontreefree, neg_list_free); break; #endif default: /* p is free'd below if no case */ break; } if( !p->obj ) { free(p); p = NULL; } return (void *)p; } #endif //DYNAMIC_PREPROC_CONTEXT void mpseVerbose( void * pvoid ) { MPSE * p = (MPSE*)pvoid; p->verbose = 1; } void mpseSetOpt( void * pvoid, int flag ) { MPSE * p = (MPSE*)pvoid; if (p == NULL) return; switch( p->method ) { case MPSE_AC_BNFA_Q: case MPSE_AC_BNFA: if (p->obj) bnfaSetOpt((bnfa_struct_t*)p->obj,flag); break; case MPSE_ACF: case MPSE_ACF_Q: if (p->obj) acsmCompressStates((ACSM_STRUCT2*)p->obj, flag); break; default: break; } } void mpseFree( void * pvoid ) { MPSE * p = (MPSE*)pvoid; if (p == NULL) return; switch( p->method ) { case MPSE_AC_BNFA: case MPSE_AC_BNFA_Q: if (p->obj) bnfaFree((bnfa_struct_t*)p->obj); free(p); return; case MPSE_AC: if (p->obj) acsmFree((ACSM_STRUCT *)p->obj); free(p); return; case MPSE_ACF: case MPSE_ACF_Q: case MPSE_ACS: case MPSE_ACB: case MPSE_ACSB: if (p->obj) acsmFree2((ACSM_STRUCT2 *)p->obj); free(p); return; case MPSE_LOWMEM: case MPSE_LOWMEM_Q: if (p->obj) KTrieDelete((KTRIE_STRUCT *)p->obj); free(p); return; #ifdef INTEL_SOFT_CPM case MPSE_INTEL_CPM: if (p->obj) IntelPmDelete((IntelPm *)p->obj); free(p); break; #endif default: return; } } int mpseAddPattern ( void * pvoid, void * P, int m, unsigned noCase, unsigned offset, unsigned depth, unsigned negative, void* ID, int IID ) { MPSE * p = (MPSE*)pvoid; switch( p->method ) { case MPSE_AC_BNFA: case MPSE_AC_BNFA_Q: return bnfaAddPattern( (bnfa_struct_t*)p->obj, (unsigned char *)P, m, noCase, negative, ID ); case MPSE_AC: return acsmAddPattern( (ACSM_STRUCT*)p->obj, (unsigned char *)P, m, noCase, offset, depth, negative, ID, IID ); case MPSE_ACF: case MPSE_ACF_Q: case MPSE_ACS: case MPSE_ACB: case MPSE_ACSB: return acsmAddPattern2( (ACSM_STRUCT2*)p->obj, (unsigned char *)P, m, noCase, offset, depth, negative, ID, IID ); case MPSE_LOWMEM: case MPSE_LOWMEM_Q: return KTrieAddPattern( (KTRIE_STRUCT *)p->obj, (unsigned char *)P, m, noCase, negative, ID ); default: return -1; } } #ifndef DYNAMIC_PREPROC_CONTEXT int mpseAddPatternWithSnortConfig ( SnortConfig *sc, void * pvoid, void * P, int m, unsigned noCase, unsigned offset, unsigned depth, unsigned negative, void* ID, int IID ) { MPSE * p = (MPSE*)pvoid; switch( p->method ) { case MPSE_AC_BNFA: case MPSE_AC_BNFA_Q: return bnfaAddPattern( (bnfa_struct_t*)p->obj, (unsigned char *)P, m, noCase, negative, ID ); case MPSE_AC: return acsmAddPattern( (ACSM_STRUCT*)p->obj, (unsigned char *)P, m, noCase, offset, depth, negative, ID, IID ); case MPSE_ACF: case MPSE_ACF_Q: case MPSE_ACS: case MPSE_ACB: case MPSE_ACSB: return acsmAddPattern2( (ACSM_STRUCT2*)p->obj, (unsigned char *)P, m, noCase, offset, depth, negative, ID, IID ); case MPSE_LOWMEM: case MPSE_LOWMEM_Q: return KTrieAddPattern( (KTRIE_STRUCT *)p->obj, (unsigned char *)P, m, noCase, negative, ID ); #ifdef INTEL_SOFT_CPM case MPSE_INTEL_CPM: return IntelPmAddPattern(sc, (IntelPm *)p->obj, (unsigned char *)P, m, noCase, negative, ID, IID); #endif default: return -1; } } #endif // DYNAMIC_PREPROC_CONTEXT void mpseLargeShifts ( void * pvoid, int flag ) { MPSE * p = (MPSE*)pvoid; switch( p->method ) { default: return ; } } int mpsePrepPatterns ( void * pvoid, int ( *build_tree )(void *id, void **existing_tree), int ( *neg_list_func )(void *id, void **list) ) { int retv; MPSE * p = (MPSE*)pvoid; switch( p->method ) { case MPSE_AC_BNFA: case MPSE_AC_BNFA_Q: retv = bnfaCompile( (bnfa_struct_t*) p->obj, build_tree, neg_list_func ); break; case MPSE_AC: retv = acsmCompile( (ACSM_STRUCT*) p->obj, build_tree, neg_list_func ); break; case MPSE_ACF: case MPSE_ACF_Q: case MPSE_ACS: case MPSE_ACB: case MPSE_ACSB: retv = acsmCompile2( (ACSM_STRUCT2*) p->obj, build_tree, neg_list_func ); break; case MPSE_LOWMEM: case MPSE_LOWMEM_Q: return KTrieCompile( (KTRIE_STRUCT *)p->obj, build_tree, neg_list_func ); default: retv = 1; break; } return retv; } #ifndef DYNAMIC_PREPROC_CONTEXT int mpsePrepPatternsWithSnortConf ( struct _SnortConfig *sc, void * pvoid, int ( *build_tree )(struct _SnortConfig *, void *id, void **existing_tree), int ( *neg_list_func )(void *id, void **list) ) { int retv; MPSE * p = (MPSE*)pvoid; switch( p->method ) { case MPSE_AC_BNFA: case MPSE_AC_BNFA_Q: retv = bnfaCompileWithSnortConf( sc, (bnfa_struct_t*) p->obj, build_tree, neg_list_func ); break; case MPSE_AC: retv = acsmCompileWithSnortConf( sc, (ACSM_STRUCT*) p->obj, build_tree, neg_list_func ); break; case MPSE_ACF: case MPSE_ACF_Q: case MPSE_ACS: case MPSE_ACB: case MPSE_ACSB: retv = acsmCompile2WithSnortConf( sc, (ACSM_STRUCT2*) p->obj, build_tree, neg_list_func ); break; case MPSE_LOWMEM: case MPSE_LOWMEM_Q: return KTrieCompileWithSnortConf( sc, (KTRIE_STRUCT *)p->obj, build_tree, neg_list_func ); #ifdef INTEL_SOFT_CPM case MPSE_INTEL_CPM: return IntelPmFinishGroup(sc, (IntelPm *)p->obj, build_tree, neg_list_func); #endif default: retv = 1; break; } return retv; } #endif //DYNAMIC_PREPROC_CONTEXT void mpseSetRuleMask ( void *pvoid, BITOP * rm ) { MPSE * p = (MPSE*)pvoid; switch( p->method ) { default: return ; } } int mpsePrintInfo( void *pvoid ) { MPSE * p = (MPSE*)pvoid; fflush(stderr); fflush(stdout); switch( p->method ) { case MPSE_AC_BNFA: case MPSE_AC_BNFA_Q: bnfaPrintInfo( (bnfa_struct_t*) p->obj ); break; case MPSE_AC: return acsmPrintDetailInfo( (ACSM_STRUCT*) p->obj ); case MPSE_ACF: case MPSE_ACF_Q: case MPSE_ACS: case MPSE_ACB: case MPSE_ACSB: return acsmPrintDetailInfo2( (ACSM_STRUCT2*) p->obj ); default: return 1; } fflush(stderr); fflush(stdout); return 0; } int mpsePrintSummary(int method) { switch (method) { case MPSE_AC_BNFA: case MPSE_AC_BNFA_Q: bnfaPrintSummary(); break; case MPSE_AC: acsmPrintSummaryInfo(); break; case MPSE_ACF: case MPSE_ACF_Q: case MPSE_ACS: case MPSE_ACB: case MPSE_ACSB: acsmPrintSummaryInfo2(); break; case MPSE_LOWMEM: case MPSE_LOWMEM_Q: if( KTrieMemUsed() ) { double x; x = (double) KTrieMemUsed(); LogMessage("[ LowMem Search-Method Memory Used : %g %s ]\n", (x > 1.e+6) ? x/1.e+6 : x/1.e+3, (x > 1.e+6) ? "MBytes" : "KBytes" ); } break; default: break; } return 0; } #ifndef DYNAMIC_PREPROC_CONTEXT int mpsePrintSummaryWithSnortConfig(SnortConfig *sc, int method) { switch (method) { case MPSE_AC_BNFA: case MPSE_AC_BNFA_Q: bnfaPrintSummary(); break; case MPSE_AC: acsmPrintSummaryInfo(); break; case MPSE_ACF: case MPSE_ACF_Q: case MPSE_ACS: case MPSE_ACB: case MPSE_ACSB: acsmPrintSummaryInfo2(); break; case MPSE_LOWMEM: case MPSE_LOWMEM_Q: if( KTrieMemUsed() ) { double x; x = (double) KTrieMemUsed(); LogMessage("[ LowMem Search-Method Memory Used : %g %s ]\n", (x > 1.e+6) ? x/1.e+6 : x/1.e+3, (x > 1.e+6) ? "MBytes" : "KBytes" ); } break; default: break; } #ifdef INTEL_SOFT_CPM IntelPmPrintSummary(sc); #endif return 0; } #endif //DYNAMIC_PREPROC_CONTEXT void mpseInitSummary(void) { acsm_init_summary(); bnfaInitSummary(); KTrieInitMemUsed(); } int mpseSearch( void *pvoid, const unsigned char * T, int n, int ( *action )(void* id, void * tree, int index, void *data, void *neg_list), void * data, int* current_state ) { MPSE * p = (MPSE*)pvoid; int ret; PROFILE_VARS; PREPROC_PROFILE_START(mpsePerfStats); p->bcnt += n; if(p->inc_global_counter) s_bcnt += n; switch( p->method ) { case MPSE_AC_BNFA: case MPSE_AC_BNFA_Q: /* return is actually the state */ ret = bnfaSearch((bnfa_struct_t*) p->obj, (unsigned char *)T, n, action, data, 0 /* start-state */, current_state ); PREPROC_PROFILE_END(mpsePerfStats); return ret; case MPSE_AC: ret = acsmSearch( (ACSM_STRUCT*) p->obj, (unsigned char *)T, n, action, data, current_state ); PREPROC_PROFILE_END(mpsePerfStats); return ret; case MPSE_ACF: case MPSE_ACF_Q: case MPSE_ACS: case MPSE_ACB: case MPSE_ACSB: ret = acsmSearch2( (ACSM_STRUCT2*) p->obj, (unsigned char *)T, n, action, data, current_state ); PREPROC_PROFILE_END(mpsePerfStats); return ret; case MPSE_LOWMEM: case MPSE_LOWMEM_Q: ret = KTrieSearch( (KTRIE_STRUCT *)p->obj, (unsigned char *)T, n, action, data); *current_state = 0; PREPROC_PROFILE_END(mpsePerfStats); return ret; #ifdef INTEL_SOFT_CPM case MPSE_INTEL_CPM: ret = IntelPmSearch((IntelPm *)p->obj, (unsigned char *)T, n, action, data); *current_state = 0; PREPROC_PROFILE_END(mpsePerfStats); return ret; #endif default: PREPROC_PROFILE_END(mpsePerfStats); return 1; } } int mpseSearchAll( void *pvoid, const unsigned char * T, int n, int ( *action )(void* id, void * tree, int index, void *data, void *neg_list), void * data, int* current_state ) { MPSE * p = (MPSE*)pvoid; int ret; PROFILE_VARS; PREPROC_PROFILE_START(mpsePerfStats); p->bcnt += n; if(p->inc_global_counter) s_bcnt += n; switch( p->method ) { case MPSE_ACF: case MPSE_ACF_Q: case MPSE_ACS: case MPSE_ACB: case MPSE_ACSB: ret = acsmSearchAll2( (ACSM_STRUCT2*) p->obj, (unsigned char *)T, n, action, data, current_state ); PREPROC_PROFILE_END(mpsePerfStats); return ret; case MPSE_AC_BNFA: case MPSE_AC_BNFA_Q: case MPSE_AC: case MPSE_LOWMEM: case MPSE_LOWMEM_Q: #ifdef INTEL_SOFT_CPM case MPSE_INTEL_CPM: #endif default: //search all not implemented. PREPROC_PROFILE_END(mpsePerfStats); return 1; } } int mpseGetPatternCount(void *pvoid) { MPSE * p = (MPSE*)pvoid; if (p == NULL) return 0; switch( p->method ) { case MPSE_AC_BNFA: case MPSE_AC_BNFA_Q: return bnfaPatternCount((bnfa_struct_t *)p->obj); case MPSE_AC: return acsmPatternCount((ACSM_STRUCT*)p->obj); case MPSE_ACF: case MPSE_ACF_Q: case MPSE_ACS: case MPSE_ACB: case MPSE_ACSB: return acsmPatternCount2((ACSM_STRUCT2*)p->obj); case MPSE_LOWMEM: case MPSE_LOWMEM_Q: return KTriePatternCount((KTRIE_STRUCT*)p->obj); #ifdef INTEL_SOFT_CPM case MPSE_INTEL_CPM: return IntelGetPatternCount((IntelPm *)p->obj); #endif } return 0; } uint64_t mpseGetPatByteCount(void) { return s_bcnt; } void mpseResetByteCount(void) { s_bcnt = 0; } void mpse_print_qinfo(void) { sfksearch_print_qinfo(); bnfa_print_qinfo(); acsmx2_print_qinfo(); } snort-2.9.15.1/src/sfutil/mpse.h0000644000175200017520000000717413571422607013273 00000000000000/* ** $Id$ ** ** mpse.h ** ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Marc Norton ** ** Multi-Pattern Search Engine ** ** Supports: ** ** Modified Wu-Manber mwm.c/.h ** Aho-Corasick - Deterministic Finite Automatum ** Keyword Trie with Boyer Moore Bad Character Shifts ** ** 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 Gener* ** ** ** Updates: ** ** man - 7/25/2002 - modified #defines for WIN32, and added uint64 ** */ #ifndef _MPSE_H #define _MPSE_H #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sf_types.h" #include "bitop.h" #include "mpse_methods.h" /* * Move these defines to a generic Win32/Unix compatability file, * there must be one somewhere... */ #ifndef CDECL #define CDECL #endif #define MPSE_INCREMENT_GLOBAL_CNT 1 #define MPSE_DONT_INCREMENT_GLOBAL_COUNT 0 /* ** PROTOTYPES */ struct _SnortConfig; void * mpseNew( int method, int use_global_counter_flag, void (*userfree)(void *p), void (*optiontreefree)(void **p), void (*neg_list_free)(void **p)); void * mpseNewWithSnortConfig( struct _SnortConfig *sc, int method, int use_global_counter_flag, void (*userfree)(void *p), void (*optiontreefree)(void **p), void (*neg_list_free)(void **p)); void mpseFree( void * pv ); int mpseAddPattern ( void * pv, void * P, int m, unsigned noCase, unsigned offset, unsigned depth, unsigned negative, void* ID, int IID ); int mpseAddPatternWithSnortConfig ( struct _SnortConfig *sc, void * pvoid, void * P, int m, unsigned noCase, unsigned offset, unsigned depth, unsigned negative, void* ID, int IID ); void mpseLargeShifts ( void * pvoid, int flag ); int mpsePrepPatterns ( void * pvoid, int ( *build_tree )(void *id, void **existing_tree), int ( *neg_list_func )(void *id, void **list) ); struct _SnortConfig; int mpsePrepPatternsWithSnortConf ( struct _SnortConfig *, void * pvoid, int ( *build_tree )(struct _SnortConfig *, void *id, void **existing_tree), int ( *neg_list_func )(void *id, void **list) ); void mpseSetRuleMask ( void *pv, BITOP * rm ); int mpseSearch( void *pv, const unsigned char * T, int n, int ( *action )(void* id, void * tree, int index, void *data, void *neg_list), void * data, int* current_state ); int mpseSearchAll( void *pv, const unsigned char * T, int n, int ( *action )(void* id, void * tree, int index, void *data, void *neg_list), void * data, int* current_state ); int mpseGetPatternCount(void *pv); uint64_t mpseGetPatByteCount(void); void mpseResetByteCount(void); int mpsePrintInfo( void * obj ); int mpsePrintSummary(int); int mpsePrintSummaryWithSnortConfig(struct _SnortConfig *, int); void mpseVerbose( void * pvoid ); void mpseSetOpt( void * pvoid,int flag); void mpse_print_qinfo(void); void mpseInitSummary(void); #endif snort-2.9.15.1/src/sfutil/bitop.h0000644000175200017520000000266213571422607013441 00000000000000/* ** $Id$ ** ** bitopt.c ** ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Dan Roelker ** Marc Norton ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** ** NOTES ** 5.15.02 - Initial Source Code. Norton/Roelker ** 5.23.02 - Moved bitop functions to bitop.h to inline. Norton/Roelker ** 1.21.04 - Added static initialization. Roelker ** 9.13.05 - Separated type and inline func definitions. Sturges ** */ #ifndef _BITOP_H #define _BITOP_H typedef struct _BITOP { unsigned char *pucBitBuffer; unsigned int uiBitBufferSize; unsigned int uiMaxBits; } BITOP; #endif /* _BITOP_H */ snort-2.9.15.1/src/sfutil/bitop_funcs.h0000644000175200017520000001574413571422607014644 00000000000000/* ** $Id$ ** ** bitopt_funcs.h ** ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Dan Roelker ** Marc Norton ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** ** NOTES ** 5.15.02 - Initial Source Code. Norton/Roelker ** 5.23.02 - Moved bitop functions to bitop.h to inline. Norton/Roelker ** 1.21.04 - Added static initialization. Roelker ** 9.13.05 - Separated type and inline func definitions. Sturges ** */ #ifndef _BITOP_FUNCS_H #define _BITOP_FUNCS_H #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "snort_debug.h" #include "bitop.h" /* ** NAME ** boInitStaticBITOP:: */ /** ** This function is for use if you handle the bitop buffer allocation ** yourself. Just pass in the char array and the number of bytes the array ** is and this function sets up the structure for you. ** ** @retval int ** ** @return 0 successful ** @return !0 failed */ static inline int boInitStaticBITOP(BITOP *BitOp,int iBytes,unsigned char *buf) { if(iBytes < 1 || !buf || !BitOp) return 1; BitOp->pucBitBuffer = buf; BitOp->uiBitBufferSize = (unsigned int)iBytes; BitOp->uiMaxBits = (unsigned int)(iBytes << 3); memset(buf, 0x00, iBytes); return 0; } /* ** ** NAME ** boInitBITOP ** ** DESCRIPTION ** Initializes the BITOP structure for use. ** ** NOTE: ** BITOP structure must be zeroed to avoid misinterpretation ** of initialization. ** ** FORMAL INPUTS ** BITOP * - the structure to initialize ** int - the number of bit positions to hold. ** ** FORMAL OUTPUTS ** int - 0 if successful, 1 if failed. ** */ static inline int boInitBITOP(BITOP *BitOp, int iBytes) { int iSize; /* ** Sanity check for size */ if((iBytes < 1) || (BitOp == NULL)) { return 1; } /* ** Check for already initialized buffer, and ** if it is already initialized then we return that it ** is initialized. */ if(BitOp->pucBitBuffer) { return 0; } iSize = iBytes << 3; BitOp->pucBitBuffer = (unsigned char *)calloc(1, iBytes); if(BitOp->pucBitBuffer == NULL) { return 1; } BitOp->uiBitBufferSize = (unsigned int)iBytes; BitOp->uiMaxBits = (unsigned int)iSize; return 0; } /* ** ** NAME ** boResetBITOP ** ** DESCRIPTION ** This resets the bit buffer so that it can be used again. ** ** FORMAL INPUTS ** BITOP * - structure to reset ** ** FORMAL OUTPUT ** int - 0 if successful, 1 if failed. ** */ static inline int boResetBITOP(BITOP *BitOp) { if (BitOp == NULL) return 1; memset(BitOp->pucBitBuffer, 0x00, BitOp->uiBitBufferSize); return 0; } /* ** ** NAME ** boSetAllBits ** ** DESCRIPTION ** This resets the bit buffer to all 1's so that it can be used again. ** ** FORMAL INPUTS ** BITOP * - structure to reset ** ** FORMAL OUTPUT ** int - 0 if successful, 1 if failed. ** */ static inline int boSetAllBits(BITOP *BitOp) { if (BitOp == NULL) return 1; memset(BitOp->pucBitBuffer, 0xff, BitOp->uiBitBufferSize); return 0; } /* ** ** NAME ** boSetBit ** ** DESCRIPTION ** Set the bit in the specified position within the bit buffer. ** ** FORMAL INPUTS ** BITOP * - the structure with the bit buffer ** int - the position to set within the bit buffer ** ** FORMAL OUTPUTS ** int - 0 if the bit was set, 1 if there was an error. ** */ static inline int boSetBit(BITOP *BitOp, unsigned int uiPos) { unsigned char mask; /* ** Sanity Check while setting bits */ if((BitOp == NULL) || (BitOp->uiMaxBits <= uiPos)) return 1; mask = (unsigned char)( 0x80 >> (uiPos & 7)); BitOp->pucBitBuffer[uiPos >> 3] |= mask; return 0; } /* ** ** NAME ** boIsBitSet ** ** DESCRIPTION ** Checks for the bit set in iPos of bit buffer. ** ** FORMAL INPUTS ** BITOP * - structure that holds the bit buffer ** int - the position number in the bit buffer ** ** FORMAL OUTPUTS ** int - 0 if bit not set, 1 if bit is set. ** */ static inline int boIsBitSet(BITOP *BitOp, unsigned int uiPos) { unsigned char mask; /* ** Sanity Check while setting bits */ if((BitOp == NULL) || (BitOp->uiMaxBits <= uiPos)) return 0; mask = (unsigned char)(0x80 >> (uiPos & 7)); return (mask & BitOp->pucBitBuffer[uiPos >> 3]); } /* ** ** NAME ** boClearBit ** ** DESCRIPTION ** Clear the bit in the specified position within the bit buffer. ** ** FORMAL INPUTS ** BITOP * - the structure with the bit buffer ** int - the position to clear within the bit buffer ** ** FORMAL OUTPUTS ** int - 0 if the bit was cleared, 1 if there was an error. ** */ static inline void boClearBit(BITOP *BitOp, unsigned int uiPos) { unsigned char mask; /* ** Sanity Check while clearing bits */ if((BitOp == NULL) || (BitOp->uiMaxBits <= uiPos)) return; mask = (unsigned char)(0x80 >> (uiPos & 7)); BitOp->pucBitBuffer[uiPos >> 3] &= ~mask; } /* ** ** NAME ** boClearByte ** ** DESCRIPTION ** Clear the byte in the specified position within the bit buffer. ** ** FORMAL INPUTS ** BITOP * - the structure with the bit buffer ** int - the position to clear within the bit buffer ** ** FORMAL OUTPUTS ** int - 0 if the byte was cleared, 1 if there was an error. ** */ static inline void boClearByte(BITOP *BitOp, unsigned int uiPos) { /* ** Sanity Check while clearing bytes */ if((BitOp == NULL) || (BitOp->uiMaxBits <= uiPos)) return; BitOp->pucBitBuffer[uiPos >> 3] = 0; } /* ** ** NAME ** boFreeBITOP ** ** DESCRIPTION ** Frees memory created by boInitBITOP - specifically ** BitOp->pucBitBuffer ** ** NOTE: ** !!! ONLY USE THIS FUNCTION IF YOU USED boInitBITOP !!! ** ** FORMAL INPUTS ** BITOP * - the structure initially passed to boInitBITOP ** ** FORMAL OUTPUTS ** void function ** **/ static inline void boFreeBITOP(BITOP *BitOp) { if((BitOp == NULL) || (BitOp->pucBitBuffer == NULL)) return; free(BitOp->pucBitBuffer); BitOp->pucBitBuffer = NULL; } #endif /* _BITOPT_FUNCS_H_ */ snort-2.9.15.1/src/sfutil/util_math.c0000644000175200017520000000345513571422607014306 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2003-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /** * @file util_math.c * @author Chris Green * @date Fri Jun 27 10:12:57 2003 * * @brief math related util functions * * Place simple math functions that are useful all over the place * here. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "util_math.h" #include "sf_types.h" /** * Calculate the percentage of something. * * If the total is <= 0, we return 0. * * @param amt amount to that you have * @param total amount there is * * @return a/b * 100 */ double calc_percent(double amt, double total) { if(total <= 0.0) return 0.0; return (amt/total) * 100.0; } double calc_percent64(uint64_t amt, uint64_t total) { if (total <= 0) return 0.0; return ((double)amt/total) * 100.0; } snort-2.9.15.1/src/sfutil/util_math.h0000644000175200017520000000300213571422607014277 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2003-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /** * @file util_math.h * @author Chris Green * @date Fri Jun 27 10:12:57 2003 * * @brief math related util functions * * Place simple math functions that are useful all over the place * here. */ #ifndef _UTIL_MATH_H #define _UTIL_MATH_H #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sf_types.h" double calc_percent(double amt, double total); double calc_percent64(uint64_t amt, uint64_t total); #endif /* _UTIL_MATH_H */ snort-2.9.15.1/src/sfutil/util_net.c0000644000175200017520000000605513571422607014142 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2003-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #ifndef WIN32 /* for inet_ntoa */ #include #include #include #include #endif /* WIN32 */ #include #include "util_net.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 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 * * @param ip ip in NETWORK BYTE ORDER */ char *inet_ntoax(const sfaddr_t *ip) { 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; if (buf_num) ip_buf = ip_buf2; else ip_buf = ip_buf1; buf_num ^= 1; ip_buf[0] = 0; SnortSnprintf(ip_buf, buf_size, "%s", inet_ntoa(ip)); return ip_buf; } #ifdef TEST_UTIL_NET int main(void) { uint32_t ip1 = htonl(0xFF00FF00); uint32_t ip2 = htonl(0xFFAAFFAA); printf("%s -> %s\n", inet_ntoax(ip1), inet_ntoax(ip2)); /* the following one is invalid and will break the first one*/ printf("%s -> %s -> %s\n", inet_ntoax(ip1), inet_ntoax(ip2), inet_ntoax(ip2)); return 0; } #endif /* TEST_UTIL_NET */ snort-2.9.15.1/src/sfutil/util_net.h0000644000175200017520000000265513571422607014151 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2003-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /** * @file util_net.h * @author Chris Green * @date Fri Jun 27 10:20:31 2003 * * @brief simple network related functions * * Put your simple network related functions here */ #ifndef _UTIL_NET_H #define _UTIL_NET_H #include "sf_types.h" #include "ipv6_port.h" char *inet_ntoax(const sfaddr_t *); char * mktcpflag_str(int flags); #endif /* _UTIL_NET_H */ snort-2.9.15.1/src/sfutil/util_str.c0000644000175200017520000000662613571422607014170 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2003-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /** * @file util_str.c * @author Chris Green * @date Fri Jun 27 10:41:59 2003 * * @brief utility string functions * * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "util_str.h" #include #ifdef HAVE_STRINGS_H #include #endif /** * Convert a string to an int and check for problems * * @param str string to parse as an int * @param ret return value for the int * @param allow_negative allow negative values * * @return 0 on sucess, else failure */ int str2int(char *str, int *ret, int allow_negative) { char *endptr; long int value; if(ret && str && *str != '\0') { value = strtol(str, &endptr, 10); if(endptr == str) { /* parsing has failed */ return -1; } if(!allow_negative) { if(value < 0) { return -1; } } *ret = value; return 0; } return -1; } /** * Set opt_value to 1 if the value is on, 0 if it's off * * @param name option name to configure (not used but useful for debugging) * @param value value to configure (should be either on or off ) * @param opt_value ptr to integer to configure * * @returns 0 on success , else failure */ int toggle_option(char *name, char *value, int *opt_value) { int opt_on, opt_off; if(!name || !value || !opt_value || (*value == '\0') || (*name == '\0') ) return -1; opt_on = strcasecmp(value,"on"); opt_off = strcasecmp(value,"off"); if(opt_off && opt_on) { /* * the string is neither "on" or "off" * * we don't know what the hell we're looking at. return error. */ return -2; } if(opt_on == 0) *opt_value = 1; else *opt_value = 0; return 0; } #ifdef TEST_UTIL_STR int main(void) { int value; printf("you should see 4 pass messages\n"); if(str2int("-1",&value,0) != 0) printf("test 1 passed and failed to parse\n"); if(str2int("-1",&value,1) == 0 && value == -1) printf("test 2 passed: %d\n", value); if(str2int("0",&value,1) == 0 && value == 0 ) printf("test 3 passed: %d\n", value); if(str2int("124",&value,1) == 0 && value == 124 ) printf("test 4 passed: %d\n", value); } #endif /* TEST_UTIL_STR */ snort-2.9.15.1/src/sfutil/util_str.h0000644000175200017520000000262613571422607014171 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2003-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /** * @file util_str.h * @author Chris Green * @date Fri Jun 27 10:34:37 2003 * * @brief string utility functions * * some string handling wrappers */ #ifndef _UTIL_STR_H #define _UTIL_STR_H int str2int(char *str, int *ret, int allow_negative); int toggle_option(char *name, char *value, int *opt_value); #endif /* _UTIL_STR_H */ snort-2.9.15.1/src/sfutil/util_utf.c0000644000175200017520000002213613571422607014150 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2010-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* Some UTF-{16,32}{le,be} normalization functions */ #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "util_utf.h" #define DSTATE_FIRST 0 #define DSTATE_SECOND 1 #define DSTATE_THIRD 2 #define DSTATE_FOURTH 3 /* init a new decode_utf_state_t */ int init_decode_utf_state(decode_utf_state_t *new) { if (new == NULL) return DECODE_UTF_FAILURE; new->state = DSTATE_FIRST; new->charset = CHARSET_DEFAULT; return DECODE_UTF_SUCCESS; } /* terminate a decode_utf_state_t. returns DECODE_UTF_FAILURE if we're not at the base state. */ int term_decode_utf_state(decode_utf_state_t *dead) { if (dead == NULL) return DECODE_UTF_FAILURE; if (dead->state != DSTATE_FIRST) return DECODE_UTF_FAILURE; return DECODE_UTF_SUCCESS; } /* setters & getters */ int set_decode_utf_state_charset(decode_utf_state_t *dstate, int charset) { if (dstate == NULL) return DECODE_UTF_FAILURE; dstate->state = DSTATE_FIRST; dstate->charset = charset; return DECODE_UTF_SUCCESS; } int get_decode_utf_state_charset(decode_utf_state_t *dstate) { if (dstate == NULL) return DECODE_UTF_FAILURE; return dstate->charset; } /* Decode UTF-16le from src to dst. * * src => buffer containing utf-16le text * src_len => length of src * dst => buffer to write translated text * dst_len => length allocated for dst * bytes_copied => store the # of bytes copied to dst * dstate => saved state from last call * * returns: DECODE_UTF_SUCCESS or DECODE_UTF_FAILURE */ static int DecodeUTF16LE(char *src, unsigned int src_len, char *dst, unsigned int dst_len, int *bytes_copied, decode_utf_state_t *dstate) { char *src_index = src; char *dst_index = dst; int result = DECODE_UTF_SUCCESS; if (src == NULL || dst == NULL || bytes_copied == NULL || dstate == NULL || src_len == 0 || dst_len == 0) return DECODE_UTF_FAILURE; while ((src_index < (char *)(src + src_len)) && (dst_index < (char *)(dst + dst_len))) { /* Copy first byte, skip second, failing if second byte != 0 */ switch (dstate->state) { case DSTATE_FIRST: *dst_index++ = *src_index++; dstate->state = DSTATE_SECOND; break; case DSTATE_SECOND: if (*src_index++ > 0) result = DECODE_UTF_FAILURE; dstate->state = DSTATE_FIRST; break; default: return DECODE_UTF_FAILURE; } } *bytes_copied = (int) (dst_index - dst); return result; } /* Decode UTF-16be from src to dst. * * src => buffer containing utf-16le text * src_len => length of src * dst => buffer to write translated text * dst_len => length allocated for dst * bytes_copied => store the # of bytes copied to dst * dstate => saved state from last call * * returns: DECODE_UTF_SUCCESS or DECODE_UTF_FAILURE */ static int DecodeUTF16BE(char *src, unsigned int src_len, char *dst, unsigned int dst_len, int *bytes_copied, decode_utf_state_t *dstate) { char *src_index = src; char *dst_index = dst; int result = DECODE_UTF_SUCCESS; if (src == NULL || dst == NULL || bytes_copied == NULL || dstate == NULL || src_len == 0 || dst_len == 0) return DECODE_UTF_FAILURE; while ((src_index < (char *)(src + src_len)) && (dst_index < (char *)(dst + dst_len))) { /* Skip first byte, copy second. */ switch (dstate->state) { case DSTATE_FIRST: if (*src_index++ > 0) result = DECODE_UTF_FAILURE; dstate->state = DSTATE_SECOND; break; case DSTATE_SECOND: *dst_index++ = *src_index++; dstate->state = DSTATE_FIRST; break; default: return DECODE_UTF_FAILURE; } } *bytes_copied = (int) (dst_index - dst); return result; } /* Decode UTF-32le from src to dst. * * src => buffer containing utf-16le text * src_len => length of src * dst => buffer to write translated text * dst_len => length allocated for dst * bytes_copied => store the # of bytes copied to dst * dstate => saved state from last call * * returns: DECODE_UTF_SUCCESS or DECODE_UTF_FAILURE */ static int DecodeUTF32LE(char *src, unsigned int src_len, char *dst, unsigned int dst_len, int *bytes_copied, decode_utf_state_t *dstate) { char *src_index = src; char *dst_index = dst; int result = DECODE_UTF_SUCCESS; if (src == NULL || dst == NULL || bytes_copied == NULL || dstate == NULL || src_len == 0 || dst_len == 0) return DECODE_UTF_FAILURE; while ((src_index < (char *)(src + src_len)) && (dst_index < (char *)(dst + dst_len))) { /* Copy the first byte, then skip three. */ switch (dstate->state) { case DSTATE_FIRST: *dst_index++ = *src_index++; dstate->state++; break; case DSTATE_SECOND: case DSTATE_THIRD: case DSTATE_FOURTH: if (*src_index++ > 0) result = DECODE_UTF_FAILURE; if (dstate->state == DSTATE_FOURTH) dstate->state = DSTATE_FIRST; else dstate->state++; break; default: return DECODE_UTF_FAILURE; } } *bytes_copied = (int) (dst_index - dst); return result; } /* Decode UTF-32be from src to dst. * * src => buffer containing utf-16le text * src_len => length of src * dst => buffer to write translated text * dst_len => length allocated for dst * bytes_copied => store the # of bytes copied to dst * dstate => saved state from last call * * returns: DECODE_UTF_SUCCESS or DECODE_UTF_FAILURE */ static int DecodeUTF32BE(char *src, unsigned int src_len, char *dst, unsigned int dst_len, int *bytes_copied, decode_utf_state_t *dstate) { char *src_index = src; char *dst_index = dst; int result = DECODE_UTF_SUCCESS; if (src == NULL || dst == NULL || bytes_copied == NULL || dstate == NULL || src_len == 0 || dst_len == 0) return DECODE_UTF_FAILURE; while ((src_index < (char *)(src + src_len)) && (dst_index < (char *)(dst + dst_len))) { /* Skip 3 bytes, copy the fourth. */ switch (dstate->state) { case DSTATE_FIRST: case DSTATE_SECOND: case DSTATE_THIRD: if (*src_index++ > 0) result = DECODE_UTF_FAILURE; dstate->state++; break; case DSTATE_FOURTH: *dst_index++ = *src_index++; dstate->state = DSTATE_FIRST; break; default: return DECODE_UTF_FAILURE; } } *bytes_copied = (int) (dst_index - dst); return result; } /* Wrapper function for DecodeUTF{16,32}{LE,BE} */ int DecodeUTF(char *src, unsigned int src_len, char *dst, unsigned int dst_len, int *bytes_copied, decode_utf_state_t *dstate) { if (!bytes_copied) return DECODE_UTF_FAILURE; *bytes_copied = 0; // FIXIT-L Should make this an assert since it should never happen if (src == NULL || dst == NULL || dstate == NULL || src_len == 0 || dst_len == 0) return DECODE_UTF_FAILURE; switch (dstate->charset) { case CHARSET_UTF16LE: return DecodeUTF16LE(src, src_len, dst, dst_len, bytes_copied, dstate); case CHARSET_UTF16BE: return DecodeUTF16BE(src, src_len, dst, dst_len, bytes_copied, dstate); case CHARSET_UTF32LE: return DecodeUTF32LE(src, src_len, dst, dst_len, bytes_copied, dstate); case CHARSET_UTF32BE: return DecodeUTF32BE(src, src_len, dst, dst_len, bytes_copied, dstate); } /* In case the function is called with a bad charset. */ return DECODE_UTF_FAILURE; } snort-2.9.15.1/src/sfutil/util_utf.h0000644000175200017520000000420213571422607014147 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2010-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #ifndef UTIL_UTF_H #define UTIL_UTF_H /* return codes */ #define DECODE_UTF_SUCCESS 0 #define DECODE_UTF_FAILURE -1 /* character set types */ #define CHARSET_DEFAULT 0 #define CHARSET_UTF7 1 #define CHARSET_UTF16LE 2 #define CHARSET_UTF16BE 3 #define CHARSET_UTF32LE 4 #define CHARSET_UTF32BE 5 #define CHARSET_UNKNOWN 255 /* Since payloads don't have to end on 2/4-byte boundaries, callers to DecodeUTF are responsible for keeping a decode_utf_state_t. This carries state between subsequent calls. */ typedef struct decode_utf_state { int state; int charset; } decode_utf_state_t; /* Init & Terminate functions for decode_utf_state_t. */ int init_decode_utf_state(decode_utf_state_t *new); int term_decode_utf_state(decode_utf_state_t *dead); /* setters & getters */ int set_decode_utf_state_charset(decode_utf_state_t *dstate, int charset); int get_decode_utf_state_charset(decode_utf_state_t *dstate); /* UTF-Decoding function prototypes */ int DecodeUTF(char *src, unsigned int src_len, char *dst, unsigned int dst_len, int *bytes_copied, decode_utf_state_t *dstate); #endif /* UTIL_UTF_H */ snort-2.9.15.1/src/sfutil/util_jsnorm.c0000644000175200017520000010041713571422607014661 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 1998-2013 Sourcefire, Inc. ** ** Writen by Bhagyashree Bantwal ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include"util_jsnorm.h" #define INVALID_HEX_VAL -1 #define MAX_BUF 8 #define NON_ASCII_CHAR 0xff //Return values #define RET_OK 0 #define RET_QUIT -1 #define RET_INV -2 #define IS_OCT 0x1 #define IS_DEC 0X2 #define IS_HEX 0x4 #define IS_PERCENT 0x8 #define IS_UPERCENT 0x10 #define IS_BACKSLASH 0x20 #define IS_UBACKSLASH 0x40 #define ANY '\0' typedef enum { PNORM_ACT_DQUOTES, PNORM_ACT_NOP, PNORM_ACT_PLUS, PNORM_ACT_SPACE, PNORM_ACT_SQUOTES, PNORM_ACT_WITHIN_QUOTES } ActionPNorm; // Actions for SFCC typedef enum { SFCC_ACT_COMMA, SFCC_ACT_DEC, SFCC_ACT_HEX, SFCC_ACT_INV, SFCC_ACT_NOP, SFCC_ACT_OCT, SFCC_ACT_QUIT, SFCC_ACT_SPACE } ActionSFCC; // Actions for Unescape typedef enum { UNESC_ACT_BACKSLASH, UNESC_ACT_CONV, UNESC_ACT_NOP, UNESC_ACT_PAREN, UNESC_ACT_PERCENT, UNESC_ACT_QUIT, UNESC_ACT_SAVE, UNESC_ACT_SAVE_NOP, UNESC_ACT_SPACE, UNESC_ACT_UBACKSLASH, UNESC_ACT_UPERCENT, UNESC_ACT_UNESCAPE } ActionUnsc; // Actions for Javascript norm typedef enum { ACT_NOP, ACT_QUIT, ACT_SAVE, ACT_SFCC, ACT_SPACE, ACT_UNESCAPE } ActionJSNorm; int hex_lookup[256]; int valid_chars[256]; char decoded_out[6335]; typedef struct { uint8_t state; uint8_t event; uint8_t match; uint8_t other; uint8_t action; } JSNorm; typedef struct { char *data; uint16_t size; uint16_t len; }Dbuf; typedef struct { uint8_t fsm; uint8_t fsm_other; uint8_t prev_event; uint8_t d_quotes; uint8_t s_quotes; uint16_t num_spaces; char *overwrite; Dbuf output; }PNormState; typedef struct { uint8_t fsm; uint8_t buf[MAX_BUF]; uint8_t buflen; uint16_t cur_flags; uint16_t alert_flags; Dbuf output; } SFCCState; typedef struct { uint8_t fsm; uint8_t prev_event; uint16_t num_spaces; uint8_t *unicode_map; char *overwrite; Dbuf dest; } JSNormState; typedef struct { uint8_t fsm; uint8_t multiple_levels; uint8_t prev_event; uint16_t alert_flags; uint16_t num_spaces; int iNorm; int paren_count; uint8_t *unicode_map; char *overwrite; ActionUnsc prev_action; Dbuf output; } UnescapeState; // STATES for SFCC #define S0 0 #define S1 S0+3 #define S2 S1+1 #define S3 S2+1 #define S4 S3+1 static JSNorm sfcc_norm[] = { { S0+0, '(', S0+1, S0+1, SFCC_ACT_NOP }, { S0+1, '0', S0+2, S1+0, SFCC_ACT_NOP }, { S0+2, 'X', S3+0, S2+0, SFCC_ACT_NOP }, //decimal { S1+0, IS_DEC, S1+0, S4+0, SFCC_ACT_DEC }, //Octal { S2+0, IS_OCT, S2+0, S1+0, SFCC_ACT_OCT }, //Hex { S3+0, IS_HEX, S3+0, S4+0, SFCC_ACT_HEX }, { S4+0, ',', S0+1, S4+1, SFCC_ACT_COMMA }, { S4+1, ')', S0+1, S4+2, SFCC_ACT_QUIT }, { S4+2, ANY, S4+1, S0+1, SFCC_ACT_INV } }; #define U0 0 #define U1 U0+1 #define U2 U1+8 #define U3 U2+9 #define U4 U3+8 #define U5 U4+19 #define U6 U5+18 #define U7 U6+1 static JSNorm unescape_norm[] = { { U0+ 0, '(', U1+ 0, U1+ 0, UNESC_ACT_PAREN }, { U1+ 0, '%', U1+ 1, U2+ 0, UNESC_ACT_SAVE }, { U1+ 1, IS_HEX, U1+ 2, U1+ 3, UNESC_ACT_CONV }, { U1+ 2, IS_HEX, U0+ 0, U0+ 0, UNESC_ACT_PERCENT }, { U1+ 3, 'U', U1+ 4, U0+ 0, UNESC_ACT_SAVE_NOP }, { U1+ 4, IS_HEX, U1+ 5, U0+ 0, UNESC_ACT_CONV }, { U1+ 5, IS_HEX, U1+ 6, U0+ 0, UNESC_ACT_CONV }, { U1+ 6, IS_HEX, U1+ 7, U0+ 0, UNESC_ACT_CONV }, { U1+ 7, IS_HEX, U0+ 0, U0+ 0, UNESC_ACT_UPERCENT }, { U2+ 0, '\\', U2+ 1, U3+ 0, UNESC_ACT_SAVE }, { U2+ 1, 'X', U2+ 2, U2+ 4, UNESC_ACT_SAVE_NOP }, { U2+ 2, IS_HEX, U2+ 3, U0+ 0, UNESC_ACT_CONV }, { U2+ 3, IS_HEX, U0+ 0, U0+ 0, UNESC_ACT_BACKSLASH }, { U2+ 4, 'U', U2+ 5, U0+ 0, UNESC_ACT_CONV }, { U2+ 5, IS_HEX, U2+ 6, U0+ 0, UNESC_ACT_CONV }, { U2+ 6, IS_HEX, U2+ 7, U0+ 0, UNESC_ACT_CONV }, { U2+ 7, IS_HEX, U2+ 8, U0+ 0, UNESC_ACT_CONV }, { U2+ 8, IS_HEX, U0+ 0, U0+ 0, UNESC_ACT_UBACKSLASH }, { U3+ 0, 'U', U3+ 1, U4+ 0, UNESC_ACT_NOP }, { U3+ 1, 'N', U3+ 2, U0+ 0, UNESC_ACT_NOP }, { U3+ 2, 'E', U3+ 3, U0+ 0, UNESC_ACT_NOP }, { U3+ 3, 'S', U3+ 4, U0+ 0, UNESC_ACT_NOP }, { U3+ 4, 'C', U3+ 5, U0+ 0, UNESC_ACT_NOP }, { U3+ 5, 'A', U3+ 6, U0+ 0, UNESC_ACT_NOP }, { U3+ 6, 'P', U3+ 7, U0+ 0, UNESC_ACT_NOP }, { U3+ 7, 'E', U0+ 0, U0+ 0, UNESC_ACT_UNESCAPE }, { U4+ 0, 'S', U4+ 1, U5+ 0, UNESC_ACT_NOP }, { U4+ 1, 'T', U4+ 2, U0+ 0, UNESC_ACT_NOP }, { U4+ 2, 'R', U4+ 3, U0+ 0, UNESC_ACT_NOP }, { U4+ 3, 'I', U4+ 4, U0+ 0, UNESC_ACT_NOP }, { U4+ 4, 'N', U4+ 5, U0+ 0, UNESC_ACT_NOP }, { U4+ 5, 'G', U4+ 6, U0+ 0, UNESC_ACT_NOP }, { U4+ 6, '.', U4+ 7, U0+ 0, UNESC_ACT_NOP }, { U4+ 7, 'F', U4+ 8, U0+ 0, UNESC_ACT_NOP }, { U4+ 8, 'R', U4+ 9, U0+ 0, UNESC_ACT_NOP }, { U4+ 9, 'O', U4+10, U0+ 0, UNESC_ACT_NOP }, { U4+10, 'M', U4+11, U0+ 0, UNESC_ACT_NOP }, { U4+11, 'C', U4+12, U0+ 0, UNESC_ACT_NOP }, { U4+12, 'H', U4+13, U0+ 0, UNESC_ACT_NOP }, { U4+13, 'A', U4+14, U0+ 0, UNESC_ACT_NOP }, { U4+14, 'R', U4+15, U0+ 0, UNESC_ACT_NOP }, { U4+15, 'C', U4+16, U0+ 0, UNESC_ACT_NOP }, { U4+16, 'O', U4+17, U0+ 0, UNESC_ACT_NOP }, { U4+17, 'D', U4+18, U0+ 0, UNESC_ACT_NOP }, { U4+18, 'E', U0+ 0, U0+ 0, UNESC_ACT_UNESCAPE }, { U5+ 0, 'D', U5+ 1, U6+ 0, UNESC_ACT_NOP }, { U5+ 1, 'E', U5+ 2, U0+ 0, UNESC_ACT_NOP }, { U5+ 2, 'C', U5+ 3, U0+ 0, UNESC_ACT_NOP }, { U5+ 3, 'O', U5+ 4, U0+ 0, UNESC_ACT_NOP }, { U5+ 4, 'D', U5+ 5, U0+ 0, UNESC_ACT_NOP }, { U5+ 5, 'E', U5+ 6, U0+ 0, UNESC_ACT_NOP }, { U5+ 6, 'U', U5+ 7, U0+ 0, UNESC_ACT_NOP }, { U5+ 7, 'R', U5+ 8, U0+ 0, UNESC_ACT_NOP }, { U5+ 8, 'I', U5+ 9, U0+ 0, UNESC_ACT_UNESCAPE }, { U5+ 9, 'C', U5+10, U0+ 0, UNESC_ACT_NOP }, { U5+10, 'O', U5+11, U0+ 0, UNESC_ACT_NOP }, { U5+11, 'M', U5+12, U0+ 0, UNESC_ACT_NOP }, { U5+12, 'P', U5+13, U0+ 0, UNESC_ACT_NOP }, { U5+13, 'O', U5+14, U0+ 0, UNESC_ACT_NOP }, { U5+14, 'N', U5+15, U0+ 0, UNESC_ACT_NOP }, { U5+15, 'E', U5+16, U0+ 0, UNESC_ACT_NOP }, { U5+16, 'N', U5+17, U0+ 0, UNESC_ACT_NOP }, { U5+17, 'T', U0+ 0, U0+ 0, UNESC_ACT_UNESCAPE }, { U6+ 0, ')', U0+ 0, U7+ 0, UNESC_ACT_QUIT }, { U7+ 0, ANY, U0+ 0, U0+ 0, UNESC_ACT_NOP } }; #define P0 0 #define P1 P0+3 #define P2 P1+2 #define P3 P2+2 #define P4 P3+1 static JSNorm plus_norm[]= { { P0+ 0, ' ', P0+ 0, P0+ 1, PNORM_ACT_SPACE }, { P0+ 1, '"', P1+ 0, P0+ 2, PNORM_ACT_DQUOTES }, { P0+ 2, '\'', P2+ 0, P3+ 0, PNORM_ACT_SQUOTES }, { P1+ 0, '"', P0+ 0, P1+ 1, PNORM_ACT_DQUOTES }, { P1+ 1, ANY, P1+ 0, P1+ 0, PNORM_ACT_WITHIN_QUOTES }, { P2+ 0, '\'', P0+ 0, P2+ 1, PNORM_ACT_SQUOTES }, { P2+ 1, ANY, P2+ 0, P2+ 0, PNORM_ACT_WITHIN_QUOTES }, { P3+ 0, '+', P0+ 0, P4+ 0, PNORM_ACT_PLUS }, { P4+ 0, ANY, P0+ 0, P0+ 0, PNORM_ACT_NOP } }; #define Z0 0 #define Z1 Z0+9 #define Z2 Z1+20 #define Z3 Z2+19 #define Z6 Z3+10 static JSNorm javascript_norm[] = { { Z0+ 0, 'U', Z0+ 1, Z1+ 0, ACT_SAVE }, { Z0+ 1, 'N', Z0+ 2, Z0+ 0, ACT_NOP }, { Z0+ 2, 'E', Z0+ 3, Z0+ 0, ACT_NOP }, { Z0+ 3, 'S', Z0+ 4, Z0+ 0, ACT_NOP }, { Z0+ 4, 'C', Z0+ 5, Z0+ 0, ACT_NOP }, { Z0+ 5, 'A', Z0+ 6, Z0+ 0, ACT_NOP }, { Z0+ 6, 'P', Z0+ 7, Z0+ 0, ACT_NOP }, { Z0+ 7, 'E', Z0+ 8, Z0+ 0, ACT_NOP }, { Z0+ 8, '(', Z0+ 0, Z0+ 0, ACT_UNESCAPE }, { Z1+ 0, 'S', Z1+ 1, Z2+ 0, ACT_SAVE }, { Z1+ 1, 'T', Z1+ 2, Z0+ 0, ACT_NOP }, { Z1+ 2, 'R', Z1+ 3, Z0+ 0, ACT_NOP }, { Z1+ 3, 'I', Z1+ 4, Z0+ 0, ACT_NOP }, { Z1+ 4, 'N', Z1+ 5, Z0+ 0, ACT_NOP }, { Z1+ 5, 'G', Z1+ 6, Z0+ 0, ACT_NOP }, { Z1+ 6, '.', Z1+ 7, Z0+ 0, ACT_NOP }, { Z1+ 7, 'F', Z1+ 8, Z0+ 0, ACT_NOP }, { Z1+ 8, 'R', Z1+ 9, Z0+ 0, ACT_NOP }, { Z1+ 9, 'O', Z1+10, Z0+ 0, ACT_NOP }, { Z1+10, 'M', Z1+11, Z0+ 0, ACT_NOP }, { Z1+11, 'C', Z1+12, Z0+ 0, ACT_NOP }, { Z1+12, 'H', Z1+13, Z0+ 0, ACT_NOP }, { Z1+13, 'A', Z1+14, Z0+ 0, ACT_NOP }, { Z1+14, 'R', Z1+15, Z0+ 0, ACT_NOP }, { Z1+15, 'C', Z1+16, Z0+ 0, ACT_NOP }, { Z1+16, 'O', Z1+17, Z0+ 0, ACT_NOP }, { Z1+17, 'D', Z1+18, Z0+ 0, ACT_NOP }, { Z1+18, 'E', Z1+19, Z0+ 0, ACT_NOP }, { Z1+19, '(', Z0+ 0, Z0+ 0, ACT_SFCC }, { Z2+ 0, 'D', Z2+ 1, Z3+ 0, ACT_SAVE }, { Z2+ 1, 'E', Z2+ 2, Z0+ 0, ACT_NOP }, { Z2+ 2, 'C', Z2+ 3, Z0+ 0, ACT_NOP }, { Z2+ 3, 'O', Z2+ 4, Z0+ 0, ACT_NOP }, { Z2+ 4, 'D', Z2+ 5, Z0+ 0, ACT_NOP }, { Z2+ 5, 'E', Z2+ 6, Z0+ 0, ACT_NOP }, { Z2+ 6, 'U', Z2+ 7, Z0+ 0, ACT_NOP }, { Z2+ 7, 'R', Z2+ 8, Z0+ 0, ACT_NOP }, { Z2+ 8, 'I', Z2+ 9, Z0+ 0, ACT_NOP }, { Z2+ 9, 'C', Z2+10, Z2+18, ACT_NOP }, { Z2+10, 'O', Z2+11, Z0+ 0, ACT_NOP }, { Z2+11, 'M', Z2+12, Z0+ 0, ACT_NOP }, { Z2+12, 'P', Z2+13, Z0+ 0, ACT_NOP }, { Z2+13, 'O', Z2+14, Z0+ 0, ACT_NOP }, { Z2+14, 'N', Z2+15, Z0+ 0, ACT_NOP }, { Z2+15, 'E', Z2+16, Z0+ 0, ACT_NOP }, { Z2+16, 'N', Z2+17, Z0+ 0, ACT_NOP }, { Z2+17, 'T', Z2+18, Z0+ 0, ACT_NOP }, { Z2+18, '(', Z0+ 0, Z0+ 0, ACT_UNESCAPE }, { Z3+ 0, '<', Z3+ 1, Z6+ 0, ACT_NOP }, { Z3+ 1, '/', Z3+ 2, Z0+ 0, ACT_NOP }, { Z3+ 2, 'S', Z3+ 3, Z0+ 0, ACT_NOP }, { Z3+ 3, 'C', Z3+ 4, Z0+ 0, ACT_NOP }, { Z3+ 4, 'R', Z3+ 5, Z0+ 0, ACT_NOP }, { Z3+ 5, 'I', Z3+ 6, Z0+ 0, ACT_NOP }, { Z3+ 6, 'P', Z3+ 7, Z0+ 0, ACT_NOP }, { Z3+ 7, 'T', Z3+ 8, Z0+ 0, ACT_NOP }, { Z3+ 8, '>', Z3+ 0, Z3+ 9, ACT_QUIT }, { Z3+ 9, ANY, Z3+ 8, Z3+ 8, ACT_NOP }, { Z6+ 0, ANY, Z0+ 0, Z0+ 0, ACT_NOP } }; void UnescapeDecode(char *, uint16_t , char **, char **, uint16_t *, JSState *, uint8_t *); void InitJSNormLookupTable(void) { int iNum; int iCtr; memset(hex_lookup, INVALID_HEX_VAL, sizeof(hex_lookup)); memset(valid_chars, 0, sizeof(valid_chars)); iNum = 0; for(iCtr = 48; iCtr < 56; iCtr++) { hex_lookup[iCtr] = iNum; valid_chars[iCtr] = (IS_HEX|IS_OCT|IS_DEC); iNum++; } for(iCtr = 56; iCtr < 58; iCtr++) { hex_lookup[iCtr] = iNum; valid_chars[iCtr] = (IS_HEX|IS_DEC); iNum++; } iNum = 10; for(iCtr = 65; iCtr < 71; iCtr++) { valid_chars[iCtr] = IS_HEX; hex_lookup[iCtr] = iNum; iNum++; } iNum = 10; for(iCtr = 97; iCtr < 103; iCtr++) { valid_chars[iCtr] = IS_HEX; hex_lookup[iCtr] = iNum; iNum++; } } static inline int outBounds(const char *start, const char *end, char *ptr) { if((ptr >= start) && (ptr < end)) return 0; else return -1; } static inline void CheckWSExceeded(JSState *js, uint16_t *num_spaces) { if(js->allowed_spaces && (*num_spaces > js->allowed_spaces)) { js->alerts |= ALERT_SPACES_EXCEEDED; } *num_spaces = 0; } static void WriteDecodedPNorm(PNormState *s, int c, JSState *js) { const char *dstart, *dend; char *dptr; dstart = s->output.data; dend = s->output.data + s->output.size; dptr = s->output.data + s->output.len; CheckWSExceeded(js, &(s->num_spaces)); if(dptr < dend) { *dptr = (char)c; dptr++; } s->output.len = dptr - dstart; } static int PNorm_exec (PNormState *s, ActionPNorm a, int c, JSState *js) { char *cur_ptr; int iRet = RET_OK; cur_ptr = s->output.data+ s->output.len; switch(a) { case PNORM_ACT_DQUOTES: if(s->prev_event == '\\') { s->fsm = s->fsm_other; WriteDecodedPNorm(s, c, js); break; } s->d_quotes++; if( s->d_quotes == 2) { s->overwrite = cur_ptr; WriteDecodedPNorm(s, c, js); s->d_quotes = 0; break; } if(s->prev_event == '+') { s->prev_event = 0; if( s->overwrite && (s->overwrite < cur_ptr)) { s->output.len = s->overwrite - s->output.data; } else { WriteDecodedPNorm(s, c, js); } } else { WriteDecodedPNorm(s, c, js); } break; case PNORM_ACT_NOP: s->prev_event = c; s->overwrite = NULL; WriteDecodedPNorm(s, c, js); break; case PNORM_ACT_PLUS: s->prev_event = '+'; WriteDecodedPNorm(s, c, js); break; case PNORM_ACT_SPACE: if( s->num_spaces == 0) { WriteDecodedPNorm(s, c, js); } s->num_spaces++; break; case PNORM_ACT_SQUOTES: if(s->prev_event == '\\') { s->fsm = s->fsm_other; WriteDecodedPNorm(s, c, js); break; } s->s_quotes++; if( s->s_quotes == 2) { s->overwrite = cur_ptr; WriteDecodedPNorm(s, c, js); s->s_quotes = 0; break; } if(s->prev_event == '+') { s->prev_event = 0; if( s->overwrite && (s->overwrite < cur_ptr)) { s->output.len = s->overwrite - s->output.data; } else { WriteDecodedPNorm(s, c, js); } } else { WriteDecodedPNorm(s, c, js); } break; case PNORM_ACT_WITHIN_QUOTES: s->prev_event = c; WriteDecodedPNorm(s, c, js); default: break; } return iRet; } static int PNorm_scan_fsm(PNormState* s, int c, JSState *js) { char uc; JSNorm *m = plus_norm + s->fsm; uc = toupper(c); if(isspace(c)) { c = uc =' '; } do { if ( !m->event || ( m->event == uc)) { s->fsm = m->match; s->fsm_other = m->other; break; } s->fsm = m->other; m = plus_norm + s->fsm; } while ( 1 ); return(PNorm_exec(s, m->action, c, js)); } int PNormDecode(char *src, uint16_t srclen, char *dst, uint16_t dstlen, uint16_t *bytes_copied, JSState *js) { int iRet; const char *end; char *ptr; PNormState s; end = src + srclen; ptr = src; s.fsm = 0; s.prev_event = 0; s.d_quotes = 0; s.s_quotes = 0; s.output.data = dst; s.output.size = dstlen; s.output.len = 0; s.overwrite = NULL; s.num_spaces = 0; s.fsm_other = 0; while(ptr < end) { iRet = PNorm_scan_fsm(&s, *ptr, js); ptr++; } dst = s.output.data; *bytes_copied = s.output.len; return iRet; } int ConvertToChar( uint16_t flags, uint8_t *buf, uint8_t buflen) { int val = 0; char *p = NULL; buf[buflen] = ANY; if(flags & IS_DEC) { val = strtoul( (const char *)buf, &p, 10); } else if(flags & IS_OCT) { val = strtoul( (const char *)buf, &p, 8); } else if (flags & IS_HEX) { val = strtoul( (const char *)buf, &p, 16); } return val; } static void WriteDecodedSFCC(SFCCState *s) { char *start = s->output.data; char *end = s->output.data + s->output.size; uint16_t len = s->output.len; char *ptr = s->output.data + len; int copy_len = 0; if(ptr < end) { if(s->cur_flags) { *ptr = (char)ConvertToChar(s->cur_flags, s->buf, s->buflen); ptr++; } else { if((end - ptr) < s->buflen) copy_len = end - ptr; else copy_len = s->buflen; memcpy(ptr , s->buf , copy_len); ptr = ptr + copy_len; } } s->output.len = (ptr -start); s->cur_flags = 0; s->buflen = 0; } static int SFCC_exec (SFCCState *s, ActionSFCC a, int c) { int iRet = RET_OK; switch(a) { case SFCC_ACT_NOP: break; case SFCC_ACT_QUIT: WriteDecodedSFCC(s); iRet = RET_QUIT; break; case SFCC_ACT_INV: WriteDecodedSFCC(s); iRet = RET_INV; break; case SFCC_ACT_DEC: if( s->buflen < MAX_BUF) { s->buf[s->buflen] = c; s->buflen++; s->cur_flags = IS_DEC; } else { s->cur_flags = 0; WriteDecodedSFCC(s); } break; case SFCC_ACT_OCT: if( s->buflen < MAX_BUF) { s->buf[s->buflen] = c; s->buflen++; s->cur_flags = IS_OCT; } else { s->cur_flags = 0; WriteDecodedSFCC(s); } break; case SFCC_ACT_HEX: if( s->buflen < MAX_BUF) { s->buf[s->buflen] = c; s->buflen++; s->cur_flags = IS_HEX; } else { s->cur_flags = 0; WriteDecodedSFCC(s); } break; case SFCC_ACT_COMMA: case SFCC_ACT_SPACE: WriteDecodedSFCC(s); s->cur_flags = 0; break; default: break; } s->alert_flags |= s->cur_flags; return iRet; } static int SFCC_scan_fsm (SFCCState* s, int c) { int indexed = 0; int value = 0; int uc; JSNorm *m = sfcc_norm + s->fsm; uc = toupper(c); if(isspace(c)) return (SFCC_exec(s, SFCC_ACT_SPACE, c)); value = valid_chars[uc]; if(value) indexed = 1; do { if ( !m->event || ((indexed && ((m->event & value) == m->event)) || ( m->event == uc))) { s->fsm = m->match; break; } s->fsm = m->other; m = sfcc_norm + s->fsm; } while ( 1 ); return(SFCC_exec(s, m->action, c)); } void StringFromCharCodeDecode(char *src, uint16_t srclen, char **ptr, char **dst, uint16_t *bytes_copied, JSState *js, uint8_t *iis_unicode_map) { int iRet; const char *start, *end; SFCCState s; uint16_t alert = 0; start = src; end = src + srclen; s.buflen = 0; s.fsm = 0; s.output.data = decoded_out; s.output.size = sizeof(decoded_out); s.output.len = 0; s.cur_flags = s.alert_flags = 0; while(!outBounds(start, end, *ptr)) { iRet = SFCC_scan_fsm(&s, **ptr); if(iRet != RET_OK) { if( (iRet == RET_INV) && ((*ptr - 1) > start )) (*ptr)--; break; } (*ptr)++; } alert = s.alert_flags; //alert mixed encodings if(alert != ( alert & -alert)) { js->alerts |= ALERT_MIXED_ENCODINGS; } UnescapeDecode(s.output.data, s.output.len, &(s.output.data), &(s.output.data), &(s.output.len), js, iis_unicode_map); *dst = s.output.data; *bytes_copied = s.output.len; } static void WriteDecodedUnescape(UnescapeState *s, int c, JSState *js) { const char *dstart, *dend; char *dptr; dstart = s->output.data; dend = s->output.data + s->output.size; dptr = s->output.data + s->output.len; CheckWSExceeded(js, &(s->num_spaces)); if(dptr < dend) { *dptr = (char)c; dptr++; } s->output.len = dptr - dstart; } static int Unescape_exec (UnescapeState *s, ActionUnsc a, int c, JSState *js) { char *cur_ptr; int iRet = RET_OK; cur_ptr = s->output.data+ s->output.len; switch(a) { case UNESC_ACT_BACKSLASH: s->prev_action = 0; s->alert_flags |= IS_BACKSLASH; s->iNorm <<= 4; s->iNorm = (s->iNorm | (hex_lookup[c])); if( s->overwrite && (s->overwrite < cur_ptr)) { s->output.len = s->overwrite - s->output.data; } s->overwrite = NULL; WriteDecodedUnescape(s, s->iNorm, js); s->iNorm = 0; break; case UNESC_ACT_CONV: s->prev_action = 0; s->iNorm <<= 4; s->iNorm = (s->iNorm | (hex_lookup[c])); WriteDecodedUnescape(s, c, js); break; case UNESC_ACT_NOP: s->prev_action = 0; s->iNorm = 0; s->overwrite = NULL; WriteDecodedUnescape(s, c, js); break; case UNESC_ACT_PAREN: if(s->prev_action == UNESC_ACT_UNESCAPE) { s->prev_action = 0; s->multiple_levels++; } s->iNorm = 0; if(s->paren_count > 0) WriteDecodedUnescape(s, c, js); s->paren_count++; break; case UNESC_ACT_PERCENT: s->prev_action = 0; s->alert_flags |= IS_PERCENT; s->iNorm <<= 4; s->iNorm = (s->iNorm | (hex_lookup[c])); if( s->overwrite && (s->overwrite < cur_ptr)) { s->output.len = s->overwrite - s->output.data; } s->overwrite = NULL; WriteDecodedUnescape(s, s->iNorm, js); s->iNorm = 0; break; case UNESC_ACT_QUIT: s->prev_action = 0; s->iNorm = 0; s->overwrite = NULL; if(s->paren_count) s->paren_count--; if( s->paren_count == 0 ) iRet = RET_QUIT; else WriteDecodedUnescape(s, c, js); break; case UNESC_ACT_SAVE: s->prev_action = 0; s->iNorm = 0; s->overwrite = cur_ptr; WriteDecodedUnescape(s, c, js); break; case UNESC_ACT_SAVE_NOP: s->prev_action = 0; s->iNorm = 0; WriteDecodedUnescape(s, c, js); break; case UNESC_ACT_SPACE: s->iNorm = 0; if(s->prev_event == '\'' || s->prev_event =='"') { WriteDecodedUnescape(s, c, js); return iRet; } if( s->prev_event != ' ') { WriteDecodedUnescape(s, c, js); } s->num_spaces++; break; case UNESC_ACT_UBACKSLASH: s->prev_action = 0; s->alert_flags |= IS_UBACKSLASH; s->iNorm <<= 4; s->iNorm = (s->iNorm | (hex_lookup[c])); if( s->overwrite && (s->overwrite < cur_ptr)) { s->output.len = s->overwrite - s->output.data; } s->overwrite = NULL; if( s->iNorm > 0xff ) { if(s->unicode_map && (s->iNorm <= 0xffff)) { s->iNorm = s->unicode_map[s->iNorm]; if(s->iNorm == -1) s->iNorm = NON_ASCII_CHAR; } else { s->iNorm = NON_ASCII_CHAR; } } WriteDecodedUnescape(s, s->iNorm, js); s->iNorm = 0; break; case UNESC_ACT_UPERCENT: s->prev_action = 0; s->alert_flags |= IS_UPERCENT; s->iNorm <<= 4; s->iNorm = (s->iNorm | (hex_lookup[c])); if( s->overwrite && (s->overwrite < cur_ptr)) { s->output.len = s->overwrite - s->output.data; } s->overwrite = NULL; if( s->iNorm > 0xff ) { if(s->unicode_map && (s->iNorm <= 0xffff)) { s->iNorm = s->unicode_map[s->iNorm]; if(s->iNorm == -1) s->iNorm = NON_ASCII_CHAR; } else { s->iNorm = NON_ASCII_CHAR; } } WriteDecodedUnescape(s, s->iNorm, js); s->iNorm = 0; break; case UNESC_ACT_UNESCAPE: /* Save the action and wait till parenthesis to increment the multiple_levels. * Only space is allowed between this action and parentheses */ s->prev_action = a; s->iNorm = 0; WriteDecodedUnescape(s, c, js); break; default: break; } s->prev_event = c; return iRet; } static int Unescape_scan_fsm (UnescapeState* s, int c, JSState *js) { int indexed = 0; int value = 0; int uc; JSNorm *m = unescape_norm + s->fsm; uc = toupper(c); if(isspace(c)) { c = uc =' '; return(Unescape_exec(s, UNESC_ACT_SPACE, c, js)); } value = valid_chars[uc]; if(value) indexed = 1; do { if ( !m->event || ( ( m->event == uc) || (indexed && ((m->event & value) == m->event)))) { s->fsm = m->match; break; } s->fsm = m->other; m = unescape_norm + s->fsm; } while ( 1 ); return(Unescape_exec(s, m->action, c, js)); } void UnescapeDecode(char *src, uint16_t srclen, char **ptr, char **dst, uint16_t *bytes_copied, JSState *js, uint8_t *iis_unicode_map) { int iRet; const char *start, *end; UnescapeState s; uint16_t alert = 0; start = src; end = src + srclen; s.iNorm = 0; s.fsm = 0; s.output.data = decoded_out; s.output.size = sizeof(decoded_out); s.output.len = 0; s.alert_flags = 0; s.prev_event = 0; s.prev_action = 0; s.overwrite = NULL; s.multiple_levels = 1; s.unicode_map = iis_unicode_map; s.num_spaces = 0; s.paren_count = 0; while(!outBounds(start, end, *ptr)) { iRet = Unescape_scan_fsm(&s, **ptr, js); if(iRet != RET_OK) { /*if( (iRet == RET_INV) && ((*ptr - 1) > start )) (*ptr)--;*/ break; } (*ptr)++; } alert = s.alert_flags; //alert mixed encodings if(alert != ( alert & -alert)) { js->alerts |= ALERT_MIXED_ENCODINGS; } if(s.multiple_levels > js->allowed_levels) { js->alerts |= ALERT_LEVELS_EXCEEDED; } PNormDecode(s.output.data, s.output.len, s.output.data, s.output.len, bytes_copied, js); *dst = s.output.data; //*bytes_copied = s.output.len; } static inline void WriteJSNormChar(JSNormState *s, int c, JSState *js) { const char *dstart, *dend; char *dptr; dstart = s->dest.data; dend = s->dest.data + s->dest.size; dptr = s->dest.data + s->dest.len; CheckWSExceeded(js, &(s->num_spaces)); if(!outBounds(dstart, dend, dptr)) { *dptr = (char)c; dptr++; } s->dest.len = dptr - dstart; } static void WriteJSNorm(JSNormState *s, char *copy_buf, uint16_t copy_len, JSState *js) { const char *end, *dstart, *dend; char *ptr, *dptr; ptr = copy_buf; end = copy_buf + copy_len; dstart = s->dest.data; dend = s->dest.data + s->dest.size; dptr = s->dest.data + s->dest.len; CheckWSExceeded(js, &(s->num_spaces)); if(ptr < end) { if((dend - dptr) < copy_len ) { copy_len = dend - dptr; } memcpy(dptr, ptr, copy_len); dptr = dptr + copy_len; } s->dest.len = dptr - dstart; } static int JSNorm_exec(JSNormState *s, ActionJSNorm a, int c, char *src, uint16_t srclen, char **ptr, JSState *js) { char *cur_ptr; int iRet = RET_OK; uint16_t bcopied = 0; char *dest; cur_ptr = s->dest.data+ s->dest.len; switch(a) { case ACT_NOP: WriteJSNormChar(s, c, js); break; case ACT_SAVE: s->overwrite = cur_ptr; WriteJSNormChar(s, c, js); break; case ACT_SPACE: if( s->prev_event != ' ') { WriteJSNormChar(s, c, js); } s->num_spaces++; break; case ACT_UNESCAPE: if(s->overwrite && (s->overwrite < cur_ptr)) { s->dest.len = s->overwrite - s->dest.data; } UnescapeDecode(src, srclen, ptr, &dest, &bcopied, js, s->unicode_map); WriteJSNorm(s, dest, bcopied, js); break; case ACT_SFCC: if( s->overwrite && (s->overwrite < cur_ptr)) { s->dest.len = s->overwrite - s->dest.data; } StringFromCharCodeDecode(src, srclen, ptr, &dest, &bcopied, js, s->unicode_map); WriteJSNorm(s, dest, bcopied, js); break; case ACT_QUIT: iRet = RET_QUIT; WriteJSNormChar(s, c, js); break; default: break; } s->prev_event = c; return iRet; } static int JSNorm_scan_fsm (JSNormState* s, int c, char *src, uint16_t srclen, char **ptr, JSState *js) { char uc; JSNorm *m = javascript_norm + s->fsm; uc = toupper(c); if(isspace(c)) { c = uc =' '; return(JSNorm_exec(s, ACT_SPACE, c, src, srclen, ptr, js)); } do { if (!m->event || (m->event == uc)) { s->fsm = m->match; break; } s->fsm = m->other; m = javascript_norm + s->fsm; }while ( 1 ); return(JSNorm_exec(s, m->action, c, src, srclen, ptr, js)); } int JSNormalizeDecode(char *src, uint16_t srclen, char *dst, uint16_t destlen, char **ptr, int *bytes_copied, JSState *js, uint8_t *iis_unicode_map) { int iRet; const char *start, *end; JSNormState s; if(js == NULL) { return RET_QUIT; } start = src; end = src + srclen; s.fsm = 0; s.overwrite = NULL; s.dest.data = dst; s.dest.size = destlen; s.dest.len = 0; s.prev_event = 0; s.unicode_map = iis_unicode_map; s.num_spaces = 0; while(!outBounds(start, end, *ptr)) { iRet = JSNorm_scan_fsm(&s, **ptr, src, srclen, ptr, js); if(iRet != RET_OK) { break; } (*ptr)++; } if(!outBounds(start, end, *ptr) && (iRet == RET_QUIT)) { (*ptr)++; } dst = s.dest.data; *bytes_copied = s.dest.len; return RET_OK; } /* int main(int argc, char *argv[]) { FILE *iFile = NULL; FILE *oFile = NULL; char input[65535]; char output[65535]; int bytes_copied = 0; int bytes_read = 0; int ret = 0; char *ptr = input; JSState js; if( argc == 3 ) { iFile = fopen(argv[1], "r"); oFile = fopen(argv[2], "w"); } if(!oFile || !iFile) { fprintf(stderr, "usage: %s \n", argv[0]); return -1; } bytes_read = fread(input, 1, sizeof(input), iFile); js.allowed_spaces = 3; js.allowed_levels = 1; js.alerts = 0; InitJSNormLookupTable(); ret = JSNormalizeDecode(input, bytes_read, output, sizeof(output),&ptr, &bytes_copied, &js, NULL); if( ret == RET_OK) { fwrite( output, 1, bytes_copied, oFile); printf("OUTPUT IS %.*s\n",bytes_copied,output); printf("REMAINING is %s\n",ptr); if( js.alerts & ALERT_MIXED_ENCODINGS ) printf("ALERT MIXED ENCODINGS\n"); if(js.alerts & ALERT_SPACES_EXCEEDED) printf("ALERT SPACES EXCEEDED\n"); if(js.alerts & ALERT_LEVELS_EXCEEDED) printf("ALERT LEVELS EXCEEDED\n"); } fclose(iFile); fclose(oFile); return 0; }*/ snort-2.9.15.1/src/sfutil/util_jsnorm.h0000644000175200017520000000273513571422607014672 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 1998-2013 Sourcefire, Inc. ** ** Writen by Bhagyashree Bantwal ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #define ALERT_SPACES_EXCEEDED 0x1 #define ALERT_LEVELS_EXCEEDED 0x2 #define ALERT_MIXED_ENCODINGS 0x4 #define MAX_ALLOWED_OBFUSCATION 1 typedef struct { int allowed_spaces; int allowed_levels; uint16_t alerts; }JSState; int JSNormalizeDecode(char *, uint16_t , char *, uint16_t destlen, char **, int *, JSState *, uint8_t *); void InitJSNormLookupTable(void); snort-2.9.15.1/src/sfutil/util_unfold.c0000644000175200017520000001257713571422607014651 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 1998-2013 Sourcefire, Inc. ** ** Writen by Bhagyashree Bantwal ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "util_unfold.h" /* Given a string, removes header folding (\r\n followed by linear whitespace) * and exits when the end of a header is found, defined as \n followed by a * non-whitespace. This is especially helpful for HTML. */ int sf_unfold_header(const uint8_t *inbuf, uint32_t inbuf_size, uint8_t *outbuf, uint32_t outbuf_size, uint32_t *output_bytes, int trim_spaces, int *folded) { int num_spaces = 0; const uint8_t *cursor, *endofinbuf; uint8_t *outbuf_ptr; uint32_t n = 0; int httpheaderfolding = 0; int folding_present = 0; cursor = inbuf; endofinbuf = inbuf + inbuf_size; outbuf_ptr = outbuf; /* Keep adding chars until we get to the end of the line. If we get to the * end of the line and the next line starts with a tab or space, add the space * to the buffer and keep reading. If the next line does not start with a * tab or space, stop reading because that's the end of the header. */ while((cursor < endofinbuf) && (n < outbuf_size)) { if(((*cursor == ' ') || (*cursor == '\t'))) { if(folding_present) num_spaces++; if(httpheaderfolding) { num_spaces++; folding_present = 1; httpheaderfolding = 0; } else if(!trim_spaces) { /* Spaces are valid except after CRs */ *outbuf_ptr++ = *cursor; } } else if((*cursor == '\n') && (httpheaderfolding != 1)) { /* Can't have multiple LFs in a row, but if we get one it * needs to be followed by at least one space */ httpheaderfolding = 1; } else if((*cursor == '\r') && !httpheaderfolding) { /* CR needs to be followed by LF and can't start a line */ httpheaderfolding = 2; } else if(!httpheaderfolding) { *outbuf_ptr++ = *cursor; n++; } else { /* We have reached the end of the header */ /* Unless we get multiple CRs, which is suspicious, but not for us to decide */ break; } cursor++; } if(n < outbuf_size) *outbuf_ptr = '\0'; else outbuf[outbuf_size - 1] = '\0'; *output_bytes = outbuf_ptr - outbuf; if(folded) *folded = num_spaces; return 0; } /* Strips the CRLF from the input buffer */ int sf_strip_CRLF(const uint8_t *inbuf, uint32_t inbuf_size, uint8_t *outbuf, uint32_t outbuf_size, uint32_t *output_bytes) { const uint8_t *cursor, *endofinbuf; uint8_t *outbuf_ptr; uint32_t n = 0; if( !inbuf || !outbuf) return -1; cursor = inbuf; endofinbuf = inbuf + inbuf_size; outbuf_ptr = outbuf; while((cursor < endofinbuf) && (n < outbuf_size)) { if((*cursor != '\n') && (*cursor != '\r')) { *outbuf_ptr++ = *cursor; n++; } cursor++; } if(output_bytes) *output_bytes = outbuf_ptr - outbuf; return(0); } /* Strips the LWS at the end of line. * Only strips the LWS before LF or CRLF */ int sf_strip_LWS(const uint8_t *inbuf, uint32_t inbuf_size, uint8_t *outbuf, uint32_t outbuf_size, uint32_t *output_bytes) { const uint8_t *cursor, *endofinbuf; uint8_t *outbuf_ptr; uint32_t n = 0; uint8_t lws = 0; if( !inbuf || !outbuf) return -1; cursor = inbuf; endofinbuf = inbuf + inbuf_size; outbuf_ptr = outbuf; while((cursor < endofinbuf) && (n < outbuf_size)) { if((*cursor != '\n') && (*cursor != '\r')) { if((*cursor != ' ') && (*cursor != '\t')) lws = 0; else lws = 1; *outbuf_ptr++ = *cursor; n++; } else { if(lws) { lws = 0; while( n > 0 ) { if((*(outbuf_ptr-1) != ' ') && (*(outbuf_ptr-1) !='\t')) break; n--; outbuf_ptr--; } } *outbuf_ptr++ = *cursor; n++; } cursor++; } if(output_bytes) *output_bytes = outbuf_ptr - outbuf; return(0); } snort-2.9.15.1/src/sfutil/util_unfold.h0000644000175200017520000000242713571422607014647 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 1998-2013 Sourcefire, Inc. ** ** Writen by Bhagyashree Bantwal ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _UTIL_UNFOLD_H_ #define _UTIL_UNFOLD_H_ #include "sf_types.h" int sf_unfold_header(const uint8_t*, uint32_t, uint8_t*, uint32_t, uint32_t*, int, int * ); int sf_strip_CRLF(const uint8_t*, uint32_t, uint8_t*, uint32_t, uint32_t*); int sf_strip_LWS(const uint8_t*, uint32_t, uint8_t*, uint32_t, uint32_t*); #endif snort-2.9.15.1/src/sfutil/asn1.c0000644000175200017520000006616613571422607013172 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2004-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /** ** @file asn1.c ** ** @author Daniel Roelker ** ** @brief ASN.1 Decoding API for BER and DER encodings. ** ** Author: Daniel Roelker ** ** ASN.1 decoding functions that incorporate an internal stack for ** processing. That way we don't have to worry about attackers trying ** to overload the machine stack. ** ** Handles both DER and BER encodings, and also the indefinite encoding ** that BER supports. Lots of functionality can be added on top of ** this library. SNMP will probably be the first. ** ** NOTES: ** - Stop using global variables so we can have multiple instances, ** but we don't need that functionality right now. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #ifdef WIN32 #include #endif #include "asn1.h" #include "util.h" /* ** Macros */ #define SF_ASN1_CLASS(c) (((u_char)c) & SF_ASN1_CLASS_MASK) #define SF_ASN1_FLAG(c) (((u_char)c) & SF_ASN1_FLAG_MASK) #define SF_ASN1_TAG(c) (((u_char)c) & SF_ASN1_TAG_MASK) #define SF_ASN1_LEN_EXT(c) (((u_char)c) & SF_BER_LEN_MASK) #define ASN1_OOB(s,e,d) (!(((s) <= (d)) && ((d) < (e)))) #define ASN1_FATAL_ERR(e) ((e) < 0) #define ASN1_NONFATAL_ERR(e) ((e) > 0) #define ASN1_MAX_STACK 128 ASN1_CONFIG asn1_config; /* ** NAME ** asn1_init_node_index:: */ /** ** This function should get called whenever we decode a new ASN.1 ** string to initialize the memory. ** ** @return void */ static void asn1_init_node_index(void) { asn1_config.node_index = 0; } /* ** NAME ** asn1_node_alloc:: */ /** ** Allocate an ASN1_NODE. ** ** @return ASN1_TYPE * ** ** @retval NULL memory allocation failed ** @retval !NULL function successful */ static ASN1_TYPE * asn1_node_alloc(void) { if ((asn1_config.mem == NULL) || (asn1_config.num_nodes <= asn1_config.node_index)) return NULL; return &asn1_config.mem[asn1_config.node_index++]; } /* ** NAME ** asn1_init_mem:: */ /** ** This function initializes the number of nodes that we want to track in ** an ASN.1 decode. Pass in the max number of nodes for an ASN.1 decode and ** we will track that many. ** ** @return integer ** ** @retval ASN1_OK function successful ** @retval ASN1_ERR_MEM_ALLOC memory allocation failed ** @retval ASN1_ERR_INVALID_ARG invalid argument */ void asn1_init_mem(int num_nodes) { if (num_nodes <= 0) return; asn1_config.mem = (ASN1_TYPE *)SnortAlloc(sizeof(ASN1_TYPE) * num_nodes); asn1_config.num_nodes = num_nodes; asn1_config.node_index = 0; } /* ** NAME ** asn1_free_mem:: */ /** ** This function frees the number of nodes that we were tracking in ** an ASN.1 decode. ** ** @return none ** */ void asn1_free_mem(void) { if (asn1_config.mem != NULL) { free(asn1_config.mem); asn1_config.mem = NULL; } } /* ** NAME ** asn1_decode_tag_num_ext:: */ /** ** This routine decodes extended tag numbers and checks for overlong ** tag numbers, etc. ** ** @param ASN1_DATA ptr to data ** @param u_int ptr to tag num ** ** @return integer ** ** @retval ASN1_OK function successful ** @retval ASN1_ERR_OVERLONG_LEN tag number too large ** @retval ASN1_ERR_OOB encoding goes out of bounds ** @retval ASN1_ERR_NULL_MEM function arguments are NULL */ static int asn1_decode_tag_num_ext(ASN1_DATA *asn1_data, u_int *tag_num) { int iExtension = 0; u_int new_tag_num; if(!asn1_data || !tag_num) return ASN1_ERR_NULL_MEM; *tag_num = 0; /* ** Loop through the tag type while extension bit is set */ do { /* ** Is this an extension byte? */ iExtension = SF_ASN1_LEN_EXT(*asn1_data->data); new_tag_num = ((*tag_num << 7) | (*asn1_data->data & 0x7f)); if(*tag_num != 0 && new_tag_num <= *tag_num) { return ASN1_ERR_OVERLONG_LEN; } *tag_num = new_tag_num; asn1_data->data++; if(ASN1_OOB(asn1_data->start, asn1_data->end, asn1_data->data)) { return ASN1_ERR_OOB; } } while(iExtension); return ASN1_OK; } /* ** NAME ** asn1_decode_ident:: */ /** ** This function decodes the identifier byte(s) of an ASN.1 structure. ** We handle long tag numbers and check for overflows in the extended ** tag numbers. ** ** @return integer ** ** @retval ASN1_ERR_NULL_MEM function arguments are NULL ** @retval ASN1_ERR_OOB buffer out of bounds ** @retval ASN1_ERR_INVALID_BER_TAG_LEN tag num too large or bad encoding ** @retval ASN1_OK function ok */ static int asn1_decode_ident(ASN1_TYPE *asn1_type, ASN1_DATA *asn1_data) { ASN1_IDENT *ident; int iRet; if(!asn1_type || !asn1_data) return ASN1_ERR_NULL_MEM; ident = &asn1_type->ident; ident->asn1_class = SF_ASN1_CLASS(*asn1_data->data); ident->flag = SF_ASN1_FLAG(*asn1_data->data); ident->tag = SF_ASN1_TAG(*asn1_data->data); asn1_data->data++; if(ASN1_OOB(asn1_data->start, asn1_data->end, asn1_data->data)) { //printf("** decode_ident: oob\n"); return ASN1_ERR_OOB; } /* ** Is tag extended? */ if(ident->tag == SF_ASN1_TAG_EXTENSION) { ident->tag_type = SF_ASN1_TAG_EXTENSION; iRet = asn1_decode_tag_num_ext(asn1_data, &ident->tag); if(iRet) { //printf("** decode_ident: ext_len error\n"); return ASN1_ERR_INVALID_BER_TAG_LEN; } } return ASN1_OK; } /* ** NAME ** asn1_decode_len_type:: */ /** ** Determine the type of len encoding. Could be short, long or ** indeterminate. ** ** @return integer ** ** @retval SF_BER_LEN_DEF_LONG extended length ** @retval SF_BER_LEN_DEF_SHORT one byte length < 127 ** @retval SF_BER_LEN_INDEF indeterminate length */ static int asn1_decode_len_type(const u_char *data) { int iExt; iExt = SF_ASN1_LEN_EXT(*data); if(iExt) { if(*data & 0x7f) { return SF_BER_LEN_DEF_LONG; } else { return SF_BER_LEN_INDEF; } } return SF_BER_LEN_DEF_SHORT; } /* ** NAME ** asn1_decode_len_ext:: */ /** ** Decode the extended length version. Basically we read the first ** byte for the number of bytes in the extended length. We then read ** that number of bytes to determine the length. If the number of bytes ** in the length is greater than our variable, then we return ** ASN1_ERR_OVERLONG_LEN, and exit decoding. ** ** @return integer ** ** @retval ASN1_ERR_NULL_MEM function arguments NULL ** @retval ASN1_ERR_OVERLONG_LEN length to long for us to decode ** @retval ASN1_ERR_OOB out of bounds condition ** @retval ASN1_OK function successful */ static int asn1_decode_len_ext(ASN1_DATA *asn1_data, u_int *size) { int iBytes; int iCtr; u_int new_size; if(!asn1_data || !size) return ASN1_ERR_NULL_MEM; *size = 0; iBytes = (*asn1_data->data & 0x7f); asn1_data->data++; if(ASN1_OOB(asn1_data->start, asn1_data->end, asn1_data->data)) { return ASN1_ERR_OOB; } for(iCtr = 0; iCtr < iBytes; iCtr++) { new_size = ((*size << 8) | (*asn1_data->data)); /* ** If we've just added some data to the size, and ** we are still the same or less than the previous ** size, we've just overflowed our variable */ if(*size != 0 && new_size <= *size) { return ASN1_ERR_OVERLONG_LEN; } *size = new_size; asn1_data->data++; if(ASN1_OOB(asn1_data->start, asn1_data->end, asn1_data->data)) { /* ** Check to see if this was just an extended length that was zero at ** the end of the buffer. If it was, then return normal. */ if(*size == 0 && (iCtr+1) == iBytes) break; return ASN1_ERR_OOB; } } return ASN1_OK; } /* ** NAME ** asn1_decode_len:: */ /** ** This function decodes the ASN.1 type length. Determines what type of ** BER encoding is used for the length and decodes that length. ** ** @return integer ** ** @retval ASN1_ERR_NULL_MEM function arguments NULL ** @retval ASN1_ERR_FATAL should never get this ** @retval ASN1_ERR_OOB out of bounds condition ** @retval ASN1_OK function successful */ static int asn1_decode_len(ASN1_TYPE *asn1_type, ASN1_DATA *asn1_data) { ASN1_LEN *len; int iRet; if(!asn1_type || !asn1_data) return ASN1_ERR_NULL_MEM; len = &asn1_type->len; len->type = (unsigned char)asn1_decode_len_type(asn1_data->data); switch(len->type) { case SF_BER_LEN_DEF_SHORT: len->size = *asn1_data->data; (asn1_data->data)++; if(ASN1_OOB(asn1_data->start, asn1_data->end, asn1_data->data)) { /* ** Only return OOB if the short length wasn't zero. Otherwise, ** it's a valid encoding. */ if(len->size != 0) return ASN1_ERR_OOB; } break; case SF_BER_LEN_DEF_LONG: iRet = asn1_decode_len_ext(asn1_data, &len->size); if(iRet) return iRet; break; case SF_BER_LEN_INDEF: /* ** Not sure what to do here, so we'll just set the length ** to 0 and proceed for now. */ len->size = 0; asn1_data->data++; if(ASN1_OOB(asn1_data->start, asn1_data->end, asn1_data->data)) return ASN1_ERR_OOB; break; default: /* ** This should be one of the three values. So we are in ** error condition. */ return ASN1_ERR_FATAL; } return ASN1_OK; } /* ** NAME ** asn1_is_eoc:: */ /** ** This function checks and ASN1_TYPE for end-of-content encoding. This ** doesn't determine that this is what it is, but what it could be. ** ** @return int ** ** @retval 0 not EOC ** @retval 1 is EOC */ static int asn1_is_eoc(ASN1_TYPE *asn1) { if(!asn1) return 0; if(asn1->ident.asn1_class == 0x00 && asn1->ident.flag == 0x00 && asn1->ident.tag == 0x00 && asn1->len.type == SF_BER_LEN_DEF_SHORT && asn1->len.size == 0) { return 1; } return 0; } /* ** NAME ** asn1_decode_type:: */ /** ** This function decodes an ASN1_TYPE structure. It processes the type in ** three parts. ** ** 1) Identifier ** 2) Length ** 3) Data ** ** The data processing skips over primitive data (if it can) and processes ** construct data (if it can). ** ** This function also updates the data and len ptrs so we continue moving ** through the data. ** ** @return integer ** ** @retval ASN1_OK function successful ** @retval ASN1_ERR_MEM_ALLOC memory allocation failed ** @retval ASN1_ERR_INVALID_INDEF_LEN invalid indefinite encoding ** @retval ASN1_ERR_INVALID_ARG invalid argument ** @retval ASN1_ERR_OOB out of bounds */ static int asn1_decode_type(const u_char **data, u_int *len, ASN1_TYPE **asn1_type) { ASN1_DATA asn1data; u_int uiRawLen; int iRet; if(!*data) return ASN1_ERR_INVALID_ARG; *asn1_type = NULL; /* ** Check len first, because if it's 0, then we already decoded a valid ** construct. We let the caller know this, by returning OK, but setting ** the asn1_type ptr to NULL. */ if(*len == 0) return ASN1_OK; if(ASN1_OOB(*data, (*data) + *len, *data)) return ASN1_ERR_OOB; *asn1_type = asn1_node_alloc(); if(*asn1_type == NULL) { return ASN1_ERR_MEM_ALLOC; } memset(*asn1_type, 0x00, sizeof(ASN1_TYPE)); asn1data.start = *data; asn1data.end = (*data) + *len; asn1data.data = *data; iRet = asn1_decode_ident(*asn1_type, &asn1data); if(iRet) { return iRet; } iRet = asn1_decode_len(*asn1_type, &asn1data); if(iRet) { return iRet; } /* ** Set this varible here, so we can set the data_len for ** indeterminate constructs. */ uiRawLen = asn1data.end - asn1data.data; /* ** This is an important check. If the length is zero, it means that ** we've either hit a zero length type or we've hit a BER indefinite ** encoding (hate those). ** ** Standard says that only constructs can have the indefinite length ** encoding, but we still need to "prove" that. Thanks M$. */ if(!(*asn1_type)->len.size) { if((*asn1_type)->len.type != SF_BER_LEN_INDEF || (*asn1_type)->ident.flag == SF_ASN1_FLAG_CONSTRUCT) { (*asn1_type)->data = asn1data.data; if((*asn1_type)->len.type == SF_BER_LEN_INDEF) { (*asn1_type)->data_len = uiRawLen; } else { /* ** If we're not an indefinite type, then we check to ** see if we are an eoc, so we don't have to check again. */ (*asn1_type)->data_len = 0; if(asn1_is_eoc(*asn1_type)) (*asn1_type)->eoc = 1; } goto valid; } return ASN1_ERR_INVALID_INDEF_LEN; } /* ** Set data ptr for asn1 types that have data. */ (*asn1_type)->data = asn1data.data; /* ** Check for the ASN.1 type being larger than we have room for. */ if(uiRawLen < (*asn1_type)->len.size) { (*asn1_type)->data_len = uiRawLen; /* ** If we're a construct, then don't skip over the data because ** we have to process it. */ if((*asn1_type)->ident.flag == SF_ASN1_FLAG_CONSTRUCT) goto valid; return ASN1_ERR_OOB; } /* ** We got enough data in the buffer for the true identifier size, so ** we set it. */ (*asn1_type)->data_len = (*asn1_type)->len.size; /* ** Only jump data that's not going to be decoded. That means jump ** over primitive data and decode construct data. */ if(!((*asn1_type)->ident.flag == SF_ASN1_FLAG_CONSTRUCT)) { asn1data.data += (*asn1_type)->len.size; } valid: /* ** Update data buffer, before we return. Depending on if we just decoded ** a zero length identifier and are on the last data byte, we could be at ** the end of our buffer. Otherwise, we're still in the buffer. */ *len = asn1data.end - asn1data.data; *data = asn1data.data; return ASN1_OK; } /* ** NAME ** asn1_decode:: */ /** ** This function decodes an ASN.1 string and returns the decoded ** structures. We BER encoding, which means we handle both ** definite and indefinite length encodings (that was a B). ** ** @return integer ** ** @retval ASN1_OK function successful ** @retval !ASN1_OK lots of error conditions, figure it out */ int asn1_decode(const u_char *data, u_int len, ASN1_TYPE **asn1_type) { ASN1_TYPE *cur; ASN1_TYPE *child = NULL; ASN1_TYPE *indef; ASN1_TYPE *asnstack[ASN1_MAX_STACK]; const u_char *end; u_int con_len; int index = 0; int iRet; if(!data || !len) return ASN1_ERR_NULL_MEM; asn1_init_node_index(); /* ** Keep track of where the end of the data buffer is so we can continue ** processing if there is a construct. */ end = data + len; iRet = asn1_decode_type(&data,&len,asn1_type); if(iRet || !(*asn1_type)) { //printf("** initial bad decode\n"); return iRet; } cur = *asn1_type; while(cur) { /* ** This is where we decode the ASN.1 constructs. We do while() ** because we may have back to back constructs. We bail on the ** first indentifier that isn't a construct. */ while(cur && cur->ident.flag == SF_ASN1_FLAG_CONSTRUCT) { if(index < ASN1_MAX_STACK) asnstack[index++] = cur; else return ASN1_ERR_STACK; /* ** We now set the current len for this constructs true length, ** or raw length if true length is past buffer. */ if(cur->len.type != SF_BER_LEN_INDEF) { if(len < cur->data_len) return ASN1_ERR_OVERLONG_LEN; len = cur->data_len; } iRet = asn1_decode_type(&data, &len, &cur->cnext); if(iRet) { return iRet; } /* ** Check next child for ending of indefinite encodings. */ if(cur->cnext && cur->cnext->eoc) { if(index && (indef = asnstack[--index]) != NULL) { if(indef->len.type == SF_BER_LEN_INDEF) { indef->len.size = data - indef->data - 2; indef->data_len = indef->len.size; cur->cnext = NULL; cur = indef; break; } else { /* ** Not an EOC type, so it's just a strange child ** encoding. Put the construct back on the stack. */ asnstack[index++] = indef; } } } cur = cur->cnext; } /* ** If there is a node, then process any peers that this node has. */ if(cur) { iRet = asn1_decode_type(&data, &len, &cur->next); if(iRet) return iRet; /* ** Cycle through any eoc that might be back to back */ while(cur->next && cur->next->eoc) { if(index && (indef = asnstack[--index]) != NULL) { if(indef->len.type == SF_BER_LEN_INDEF) { indef->len.size = data - indef->data - 2; indef->data_len = indef->len.size; cur->next = NULL; cur = indef; iRet = asn1_decode_type(&data, &len, &cur->next); if(iRet) { return iRet; } continue; } asnstack[index++] = indef; } break; } cur = cur->next; if(cur) continue; } /* ** We only get here if the peer decode fails. ** ** Traverse the stack and close off any constructs that we ** are done with. This gets a little trickier, because we have to ** check for additional peers for each construct, depending on the ** length of the parent construct. */ while(index && (cur = asnstack[--index]) != NULL) { /* ** Get the construct length and set the length appropriately ** if there is more data in this construct. */ con_len = data - cur->data; if(cur->data_len > con_len) { len = cur->data_len - con_len; } /* ** If this construct has no more data left, then save it off as ** the last child of the previous construct. */ if(len == 0) { child = cur; } else if(child) { /* ** Means this construct has more data left, so if the child is set ** then we set it's next ptr. Otherwise, this means we are in ** an indeterminate construct, and need to check for eoc before we ** continue processing. */ asnstack[index++] = cur; cur = child; child = NULL; } iRet = asn1_decode_type(&data, &len, &cur->next); if(iRet) { return iRet; } if(cur->next && cur->next->eoc) { if(index && (indef = asnstack[--index]) != NULL) { if(indef->len.type == SF_BER_LEN_INDEF) { indef->len.size = data - indef->data - 2; indef->data_len = indef->len.size; cur->next = NULL; cur = indef; } else { asnstack[index++] = indef; } } } /* ** This logic tell us that we are on the root construct, but there ** are additional peers because there is more data. We recalculate ** the length and continue on. ** ** NOTE: ** We may not want this because research may only be able to point ** us at the first sequence and it's anyone's guess after that. */ if(!index && !(cur->next) && (data < end)) { len = (end - data); iRet = asn1_decode_type(&data, &len, &cur->next); if(iRet) return iRet; } cur = cur->next; if(cur) break; } /* ** The loop logic bails us out if there is no cur. */ } return ASN1_OK; } /* ** NAME ** asn1_traverse:: */ /** ** This function traverses a decoded ASN1 structure, applying a detection ** function for the different types. This is just to make this user stack ** generic AND easy. ** ** @return integer ** ** @retval 1 detection function successful ** @retval 0 detection function unsuccessful */ int asn1_traverse(ASN1_TYPE *asn1, void *user, int (*DetectFunc)(ASN1_TYPE *, void *)) { ASN1_TYPE *asnstack[ASN1_MAX_STACK]; int index = 0; ASN1_TYPE *cur; int iRet; if(!asn1) return 0; cur = asn1; while(cur) { while(cur && cur->ident.flag == SF_ASN1_FLAG_CONSTRUCT) { if(index < ASN1_MAX_STACK) asnstack[index++] = cur; else return 0; iRet = DetectFunc(cur, user); if(iRet) return 1; cur = cur->cnext; } if(cur) { iRet = DetectFunc(cur, user); if(iRet) return 1; cur = cur->next; if(cur) continue; } while(index && (cur = asnstack[--index]) != NULL) { cur = cur->next; if(cur) break; } } return 0; } /* ** NAME ** asn1_print_types:: */ /** ** Print out the ASN.1 type. ** ** @return integer ** ** @retval 0 printed */ int asn1_print_types(ASN1_TYPE *asn1_type, void *user) { unsigned int iTabs = 0; unsigned int iCtr; if(user) iTabs = *((int *)user); for(iCtr = 0; iCtr < iTabs; iCtr++) printf(" "); printf("## PRINT ASN1_TYPE STRUCTURE ##\n"); for(iCtr = 0; iCtr < iTabs; iCtr++) printf(" "); printf("IDENT - asn1_class: %.2x | flag: %.2x | tag_type: %.2x | " "tag_num: %d\n", asn1_type->ident.asn1_class, asn1_type->ident.flag, asn1_type->ident.tag_type, asn1_type->ident.tag); for(iCtr = 0; iCtr < iTabs; iCtr++) printf(" "); printf("LEN - type: %d | size: %u\n", asn1_type->len.type, asn1_type->len.size); for(iCtr = 0; iCtr < iTabs; iCtr++) printf(" "); printf("DATA | data_len: %d | ", asn1_type->data_len); if(asn1_type->data) { for(iCtr = 0; iCtr < asn1_type->data_len; iCtr++) printf(" %.2x", asn1_type->data[iCtr]); } else { printf(" NULL"); } printf("\n\n"); /* printf("\n"); //if(BitStringOverflow(asn1_type)) //{ // printf("!! BITSTRING OVERFLOW\n"); //} printf("\n"); if(asn1_type->cnext) asn1_print_types(asn1_type->cnext, iTabs+1); if(asn1_type->next) asn1_print_types(asn1_type->next, iTabs); */ return 0; } #ifdef I_WANT_MAIN_DAMMIT static int BitStringOverflow(ASN1_TYPE *asn1_type) { if(!asn1_type) return 0; if(asn1_type->ident.tag == SF_ASN1_TAG_BIT_STR && !asn1_type->ident.flag) { if(((asn1_type->len.size - 1)*8) < (u_int)asn1_type->data[0]) { return 1; } } return 0; } /* ** Program reads from stdin and decodes the hexadecimal ASN.1 stream ** into identifier,len,data. */ int main(int argc, char **argv) { ASN1_TYPE *asn1_type; char line[10000]; u_int ctmp; char *buf; int buf_size; int iCtr; int iRet; fgets(line, sizeof(line), stdin); buf_size = strlen(line); while(buf_size && line[buf_size-1] <= 0x20) { buf_size--; line[buf_size] = 0x00; } if(!buf_size) { printf("** No valid characters in data string.\n"); return 1; } if(buf_size % 2) { printf("** Data must be represent in hex, meaning that there is an " "odd number of characters in the data string.\n"); return 1; } buf_size >>= 1; buf = calloc(1,buf_size + 1); if(!buf) { return 1; } for(iCtr = 0; iCtr < buf_size; iCtr++) { if(!(isxdigit(line[iCtr*2]) && isxdigit(line[(iCtr*2)+1]))) { printf("** Data stream is not all hex digits.\n"); return 1; } sscanf(&line[iCtr*2], "%2x", &ctmp); buf[iCtr] = (char)ctmp; } buf[iCtr] = 0x00; asn1_init_mem(256); iRet = asn1_decode(buf, buf_size, &asn1_type); if(iRet && !asn1_type) { printf("** FAILED\n"); return 1; } printf("** iRet = %d\n", iRet); asn1_print_types(asn1_type, 0); free(buf); return 0; } #endif snort-2.9.15.1/src/sfutil/asn1.h0000644000175200017520000001007313571422607013161 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2004-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #ifndef __ASN1_H__ #define __ASN1_H__ /* ** ASN.1 Identifier Classes */ #define SF_ASN1_CLASS_MASK 0xc0 #define SF_ASN1_CLASS_UNIVERSAL 0x00 #define SF_ASN1_CLASS_APPLICATION 0x40 #define SF_ASN1_CLASS_CONTEXT 0x80 #define SF_ASN1_CLASS_PRIVATE 0xc0 /* ** ASN.1 Identifier Flags */ #define SF_ASN1_FLAG_MASK 0x20 #define SF_ASN1_FLAG_PRIMITIVE 0x00 #define SF_ASN1_FLAG_CONSTRUCT 0x20 /* ** ASN.1 Universal Tags */ #define SF_ASN1_TAG_MASK 0x1f #define SF_ASN1_TAG_RSV_ENC 0 #define SF_ASN1_TAG_BOOL 1 #define SF_ASN1_TAG_INT 2 #define SF_ASN1_TAG_BIT_STR 3 #define SF_ASN1_TAG_OCT_STR 4 #define SF_ASN1_TAG_NULL 5 #define SF_ASN1_TAG_OBJ_IDENT 6 #define SF_ASN1_TAG_OBJ_DESC 7 #define SF_ASN1_TAG_EXT 8 #define SF_ASN1_TAG_REAL 9 #define SF_ASN1_TAG_ENUM 10 #define SF_ASN1_TAG_EMB_PDV 11 #define SF_ASN1_TAG_REL_OBJ 13 #define SF_ASN1_TAG_SEQ 16 #define SF_ASN1_TAG_SET 17 #define SF_ASN1_TAG_UTF8_STR 12 #define SF_ASN1_TAG_NUM_STR 18 #define SF_ASN1_TAG_PRINT_STR 19 #define SF_ASN1_TAG_T61_STR 20 #define SF_ASN1_TAG_VID_STR 21 #define SF_ASN1_TAG_IA5_STR 22 #define SF_ASN1_TAG_GRAPH_STR 25 #define SF_ASN1_TAG_VIS_STR 26 #define SF_ASN1_TAG_GEN_STR 27 #define SF_ASN1_TAG_UNIV_STR 28 #define SF_ASN1_TAG_BMP_STR 30 #define SF_ASN1_TAG_UTC_TIME 23 #define SF_ASN1_TAG_GEN_TIME 24 #define SF_ASN1_TAG_EXTENSION 31 /* ** BER Length Decoding */ #define SF_BER_LEN_MASK 0x80 #define SF_BER_LEN_DEF_SHORT 1 #define SF_BER_LEN_DEF_LONG 2 #define SF_BER_LEN_INDEF 3 typedef struct s_ASN1_LEN { unsigned char type; unsigned int size; } ASN1_LEN; typedef struct s_ASN1_IDENT { unsigned char asn1_class; unsigned char flag; unsigned char tag_type; unsigned int tag; } ASN1_IDENT; typedef struct s_ASN1_TYPE { ASN1_IDENT ident; ASN1_LEN len; const unsigned char *data; unsigned int data_len; unsigned char eoc; struct s_ASN1_TYPE *next; struct s_ASN1_TYPE *cnext; } ASN1_TYPE; typedef struct s_ASN1_DATA { const unsigned char *data; const unsigned char *start; const unsigned char *end; unsigned int len; } ASN1_DATA; typedef struct s_ASN1_CONFIG { ASN1_TYPE *mem; int num_nodes; int node_index; } ASN1_CONFIG; /* ** Error Codes */ #define ASN1_ERR_OOB 1 #define ASN1_ERR_NONFATAL 2 #define ASN1_ERR_OVERLONG_LEN 3 #define ASN1_OK 0 #define ASN1_ERR_NULL_MEM -1 #define ASN1_ERR_INVALID_BER_TAG_LEN -3 #define ASN1_ERR_MEM_ALLOC -4 #define ASN1_ERR_FATAL -5 #define ASN1_ERR_INVALID_INDEF_LEN -6 #define ASN1_ERR_INVALID_ARG -7 #define ASN1_ERR_STACK -8 void asn1_init_mem(int); void asn1_free_mem(void); int asn1_decode(const unsigned char *data, unsigned int len, ASN1_TYPE **asn1_type); int asn1_print_types(ASN1_TYPE *asn1_type, void *user); int asn1_traverse(ASN1_TYPE *asn1, void * user, int (*DetectFunc)(ASN1_TYPE *, void *)); #endif snort-2.9.15.1/src/sfutil/sfeventq.c0000644000175200017520000002263313571422607014152 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2004-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /** ** @file sfeventq.c ** ** @author Daniel Roelker ** ** @brief This provides generic functions for queuing events and ** inserting the events with a provided function. All ** memory management for events is provided here. ** ** ** The sfeventq functions provide a generic way for handling events, ** prioritizing those events, and acting on the highest ranked events ** with a user function. ** ** Example on using sfeventq: ** ** 1. Initialize event queue ** sfeventq_init() ** ** 2. Add events to queue ** sfeventq_event_alloc() allocates the memory for storing the event. ** sfeventq_add() adds the event and prioritizes the event in the queue. ** You should only allocate and add one event at a time. Otherwise, ** event_alloc() will return NULL on memory exhaustion. ** ** 3. Event actions ** sfeventq_action() will call the provided function on the initialized ** number of events to log. */ #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sfeventq.h" #include "util.h" /* ** NAME ** sfeventq_new:: */ /** ** Initialize the event queue. Provide the max number of nodes that this ** queue will support, the number of top nodes to log in the queue, and the ** size of the event structure that the user will fill in. ** ** @return integer ** ** @retval -1 failure ** @retval 0 success */ SF_EVENTQ * sfeventq_new(int max_nodes, int log_nodes, int event_size) { SF_EVENTQ *eq; if ((max_nodes <= 0) || (log_nodes <= 0) || (event_size <= 0)) return NULL; eq = (SF_EVENTQ *)SnortAlloc(sizeof(SF_EVENTQ)); /* Initialize the memory for the nodes that we are going to use. */ eq->node_mem = (SF_EVENTQ_NODE *)SnortAlloc(sizeof(SF_EVENTQ_NODE) * max_nodes); eq->event_mem = (char *)SnortAlloc(event_size * (max_nodes + 1)); eq->max_nodes = max_nodes; eq->log_nodes = log_nodes; eq->event_size = event_size; eq->cur_nodes = 0; eq->cur_events = 0; eq->reserve_event = (void *)(&eq->event_mem[max_nodes * eq->event_size]); return eq; } /* ** NAME ** sfeventq_event_alloc:: */ /** ** Allocate the memory for an event to add to the event queue. This ** function is meant to be called first, the event structure filled in, ** and then added to the queue. While you can allocate several times before ** adding to the queue, this is not recommended as you may get a NULL ptr ** if you allocate more than the max node number. ** ** @return void * ** ** @retval NULL unable to allocate memory. ** @retval !NULL ptr to memory. */ void * sfeventq_event_alloc(SF_EVENTQ *eq) { void *event; if (eq->cur_events >= eq->max_nodes) { if (eq->reserve_event == NULL) return NULL; event = (void *)eq->reserve_event; eq->reserve_event = NULL; return event; } event = (void *)(&eq->event_mem[eq->cur_events * eq->event_size]); eq->cur_events++; return event; } /* ** NAME ** sfeventq_reset:: */ /** ** Resets the event queue. We also set the reserve event back ** to the last event in the queue. ** ** @return void */ void sfeventq_reset(SF_EVENTQ *eq) { eq->head = NULL; eq->cur_nodes = 0; eq->cur_events = 0; eq->reserve_event = (void *)(&eq->event_mem[eq->max_nodes * eq->event_size]); } /* ** NAME ** sfeventq_free:: */ /** ** Cleanup the event queue. ** ** @return none ** */ void sfeventq_free(SF_EVENTQ *eq) { if (eq == NULL) return; /* Free the memory for the nodes that were in use. */ if (eq->node_mem != NULL) { free(eq->node_mem); eq->node_mem = NULL; } if (eq->event_mem != NULL) { free(eq->event_mem); eq->event_mem = NULL; } free(eq); } /* ** NAME ** get_eventq_node:: */ /** ** This function returns a ptr to the node to use. We allocate the last ** event node if we have exhausted the event queue. Before we allocate ** the last node, we determine if the incoming event has a higher ** priority than the last node. If it does, we allocate the node, otherwise ** we drop it because it is lower priority. ** ** If the last node is allocated, we have to point the reserve_event to ** the allocated event memory, since the reserved_event memory was used ** for the incoming event. ** ** @return SF_EVENTQ_NODE * ** ** @retval NULL resource exhaustion and event is lower priority than last node ** @retval !NULL ptr to node memory. */ static SF_EVENTQ_NODE * get_eventq_node(SF_EVENTQ *eq, void *event) { if (eq->cur_nodes >= eq->max_nodes) return NULL; /* ** We grab the next node from the node memory. */ return &eq->node_mem[eq->cur_nodes++]; } /* ** NAME ** sfeventq_add: */ /** ** Add this event to the queue using the supplied ordering ** function. If the queue is exhausted, then we compare the ** event to be added with the last event, and decide whether ** it is a higher priority than the last node. ** ** @return integer ** ** @retval -1 add event failed ** @retval 0 add event succeeded */ int sfeventq_add(SF_EVENTQ *eq, void *event) { SF_EVENTQ_NODE *node; if(!event) return -1; /* ** If get_eventq_node() returns NULL, this means that ** we have exhausted the eventq and the incoming event ** is lower in priority then the last ranked event. ** So we just drop it. */ node = get_eventq_node(eq, event); if(!node) return -1; node->event = event; node->next = NULL; node->prev = NULL; /* ** This is the first node */ if(eq->cur_nodes == 1) { eq->head = eq->last = node; return 0; } /* ** This means we are the last node. */ node->prev = eq->last; eq->last->next = node; eq->last = node; return 0; } /* ** NAME ** sfeventq_action:: */ /** ** Call the supplied user action function on the highest priority ** events. ** ** @return integer ** ** @retval -1 action function failed on an event ** @retval 0 no events logged ** @retval 1 events logged */ int sfeventq_action(SF_EVENTQ *eq, int (*action_func)(void *, void *), void *user) { SF_EVENTQ_NODE *node; int logged = 0; if (action_func == NULL) return -1; if (eq->head == NULL) return 0; for (node = eq->head; node != NULL; node = node->next) { if (logged >= eq->log_nodes) return 1; if (action_func(node->event, user)) return -1; logged++; } return 1; } //#define I_WANT_MY_MAIN #ifdef I_WANT_MY_MAIN #include #include int myaction(void *event, void *user) { int *e; if(!event) return 1; e = (int *)event; printf("-- EVENT: %d\n", *e); return 0; } int main(int argc, char **argv) { int max_events; int log_events; int add_events; int *event; int iCtr; SF_EVENTQ *eq; if(argc < 4) { printf("-- Not enough args\n"); return 1; } max_events = atoi(argv[1]); if(max_events <= 0) { printf("-- max_events invalid.\n"); return 1; } log_events = atoi(argv[2]); if(log_events <= 0) { printf("-- log_events invalid.\n"); return 1; } add_events = atoi(argv[3]); if(add_events <= 0) { printf("-- add_events invalid.\n"); return 1; } if(max_events < log_events) { printf("-- log_events greater than max_events\n"); return 1; } srandom(time(NULL)); eq = sfeventq_new(max_events, log_events, sizeof(int)); if (eq == NULL) { printf("Couldn't allocate the event queue\n"); return 1; } do { printf("-- Event Queue Test --\n\n"); for(iCtr = 0; iCtr < add_events; iCtr++) { event = (int *)sfeventq_event_alloc(eq); if(!event) { printf("-- event allocation failed\n"); return 1; } *event = (int)(random()%3); sfeventq_add(eq, event); printf("-- added %d\n", *event); } printf("\n-- Logging\n\n"); if(sfeventq_action(eq, myaction, NULL)) { printf("-- There was a problem.\n"); return 1; } sfeventq_reset(eq); } while(getc(stdin) < 14); return 0; } #endif snort-2.9.15.1/src/sfutil/sfeventq.h0000644000175200017520000000452513571422607014157 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2004-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #ifndef __SF_EVENTQ_H__ #define __SF_EVENTQ_H__ #define NUM_EVENT_QUEUES 3 typedef struct s_SF_EVENTQ_NODE { void *event; struct s_SF_EVENTQ_NODE *prev; struct s_SF_EVENTQ_NODE *next; } SF_EVENTQ_NODE; typedef struct s_SF_EVENTQ { /* ** Handles the actual ordering and memory ** of the event queue and it's nodes. */ SF_EVENTQ_NODE *head; SF_EVENTQ_NODE *last; SF_EVENTQ_NODE *node_mem; char *event_mem; /* ** The reserve event allows us to allocate one extra node ** and compare against the last event in the queue to determine ** if the incoming event is a higher priority than the last ** event in the queue. */ char *reserve_event; /* ** Queue configuration */ int max_nodes; int log_nodes; int event_size; /* ** This element tracks the current number of ** nodes in the event queue. */ int cur_nodes; int cur_events; } SF_EVENTQ; SF_EVENTQ * sfeventq_new(int max_nodes, int log_nodes, int event_size); void * sfeventq_event_alloc(SF_EVENTQ *); void sfeventq_reset(SF_EVENTQ *); int sfeventq_add(SF_EVENTQ *, void *event); int sfeventq_action(SF_EVENTQ *, int (*action_func)(void *event, void *user), void *user); void sfeventq_free(SF_EVENTQ *); #endif snort-2.9.15.1/src/sfutil/sfsnprintfappend.c0000644000175200017520000000471613571422607015705 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2005-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* * * sfsnprintfappend.h * * snprintf that appends to destination buffer * * * Author: Steven Sturges * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "util.h" /**************************************************************************** * * Function: sfsnprintfappend * * Purpose: snprintf that appends to destination buffer * * Appends the snprintf format string and arguments to dest * without going beyond dsize bounds. Assumes dest has * been properly allocated, and is of dsize in length. * * Arguments: dest ==> pointer to string buffer to append to * dsize ==> size of buffer dest * format ==> snprintf format string * ... ==> arguments for printf * * Returns: number of characters added to the buffer * ****************************************************************************/ int sfsnprintfappend(char *dest, int dsize, const char *format, ...) { int currLen, appendLen; va_list ap; if (!dest || dsize == 0) return -1; currLen = SnortStrnlen(dest, dsize); if (currLen == -1) return -1; va_start(ap, format); appendLen = vsnprintf(dest+currLen, dsize-currLen, format, ap); va_end(ap); dest[dsize-1]=0;/* guarantee a null tremination */ return appendLen; } snort-2.9.15.1/src/sfutil/sfsnprintfappend.h0000644000175200017520000000247213571422607015707 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2005-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* * * sfsnprintfappend.h * * snprintf that appends to destination buffer * * * Author: Steven Sturges * */ #ifndef _SFSNPRINTF_APPEND_H_ #define _SFSNPRINTF_APPEND_H_ int sfsnprintfappend(char *dest, int dsize, const char *format, ...); #endif /* _SFSNPRINTF_APPEND_H_ */ snort-2.9.15.1/src/sfutil/sfrt.c0000644000175200017520000005210013571422607013265 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2006-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* * @file sfrt.c * @author Adam Keeton * @date Thu July 20 10:16:26 EDT 2006 * * Route implements two different routing table lookup mechanisms. The table * lookups have been adapted to return a void pointer so any information can * be associated with each CIDR block. * * As of this writing, the two methods used are Stefan Nilsson and Gunnar * Karlsson's LC-trie, and a multibit-trie method similar to Gupta et-al.'s * DIR-n-m. Presently, the LC-trie is used primarily for testing purposes as * the current implementation does not allow for fast dynamic inserts. * * The intended use is for a user to optionally specify large IP blocks and * then more specific information will be written into the routing tables * from RNA. Ideally, information will only move from less specific to more * specific. If a more general information is to overwrite existing entries, * the table should be free'ed and rebuilt. * * * Implementation: * * The routing tables associate an index into a "data" table with each CIDR. * Each entry in the data table stores a pointer to actual data. This * implementation was chosen so each routing entry only needs one word to * either index the data array, or point to another table. * * Inserts are performed by specifying a CIDR and a pointer to its associated * data. Since a new routing table entry may overwrite previous entries, * a flag selects whether the insert favors the most recent or favors the most * specific. Favoring most specific should be the default behvior. If * the user wishes to overwrite routing entries with more general data, the * table should be flushed, rather than using favor-most-recent. * * Before modifying the routing or data tables, the insert function performs a * lookup on the CIDR-to-be-insertted. If no entry or an entry *of differing * bit length* is found, the data is insertted into the data table, and its * index is used for the new routing table entry. If an entry is found that * is as specific as the new CIDR, the index stored points to where the new * data is written into the data table. * * If more specific CIDR blocks overwrote the data table, then the more * general routing table entries that were not overwritten will be referencing * the wrong data. Alternatively, less specific entries can only overwrite * existing routing table entries if favor-most-recent inserts are used. * * Because there is no quick way to clean the data-table if a user wishes to * use a favor-most-recent insert for more general data, the user should flush * the table with sfrt_free and create one anew. Alternatively, a small * memory leak occurs with the data table, as it will be storing pointers that * no routing table entry cares about. * * * The API calls that should be used are: * sfrt_new - create new table * sfrt_insert - insert entry * sfrt_lookup - lookup entry * sfrt_free - free table */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sf_types.h" #include "sfrt.h" char *rt_error_messages[] = { "Success", "Insert Failure", "Policy Table Exceeded", "Dir Insert Failure", "Dir Lookup Failure", "Memory Allocation Failure" #ifdef SUPPORT_LCTRIE , "LC Trie Compile Failure", "LC Trie Insert Failure", "LC Trie Lookup Failure" #endif }; static inline int allocateTableIndex(table_t *table); /* Create new lookup table * @param table_type Type of table. Uses the types enumeration in route.h * @param ip_type IPv4 or IPv6. Uses the types enumeration in route.h * @param data_size Max number of unique data entries * * Returns the new table. */ table_t *sfrt_new(char table_type, char ip_type, long data_size, uint32_t mem_cap) { table_t *table = (table_t*)malloc(sizeof(table_t)); if(!table) { return NULL; } /* If this limit is exceeded, there will be no way to distinguish * between pointers and indeces into the data table. Only * applies to DIR-n-m. */ #ifdef SUPPORT_LCTRIE #if SIZEOF_LONG_INT == 8 if(data_size >= 0x800000000000000 && table_type == LCT) #else if(data_size >= 0x8000000 && table_type != LCT) #endif #else /* SUPPORT_LCTRIE */ #if SIZEOF_LONG_INT == 8 if(data_size >= 0x800000000000000) #else if(data_size >= 0x8000000) #endif #endif { free(table); return NULL; } /* mem_cap is specified in megabytes, but internally uses bytes. Convert */ mem_cap *= 1024*1024; /* Maximum allowable number of stored entries */ table->max_size = data_size; table->lastAllocatedIndex = 0; table->data = (GENERIC*)calloc(sizeof(GENERIC) * table->max_size, 1); if(!table->data) { free(table); return NULL; } table->allocated = sizeof(table_t) + sizeof(GENERIC) * table->max_size; table->ip_type = ip_type; table->table_type = table_type; /* This will point to the actual table lookup algorithm */ table->rt = NULL; table->rt6 = NULL; /* index 0 will be used for failed lookups, so set this to 1 */ table->num_ent = 1; switch(table_type) { #ifdef SUPPORT_LCTRIE /* Setup LC-trie table */ case LCT: /* LC trie is presently not allowed */ table->insert = sfrt_lct_insert; table->lookup = sfrt_lct_lookup; table->free = sfrt_lct_free; table->usage = sfrt_lct_usage; table->print = NULL; table->remove = NULL; table->rt = sfrt_lct_new(data_size); free(table->data); free(table); return NULL; break; #endif /* Setup DIR-n-m table */ case DIR_24_8: case DIR_16x2: case DIR_16_8x2: case DIR_16_4x4: case DIR_8x4: case DIR_4x8: case DIR_2x16: case DIR_16_4x4_16x5_4x4: case DIR_16x7_4x4: case DIR_16x8: case DIR_8x16: table->insert = sfrt_dir_insert; table->lookup = sfrt_dir_lookup; table->free = sfrt_dir_free; table->usage = sfrt_dir_usage; table->print = sfrt_dir_print; table->remove = sfrt_dir_remove; break; default: free(table->data); free(table); return NULL; }; /* Allocate the user-specified DIR-n-m table */ switch(table_type) { case DIR_24_8: table->rt = sfrt_dir_new(mem_cap, 2, 24,8); break; case DIR_16x2: table->rt = sfrt_dir_new(mem_cap, 2, 16,16); break; case DIR_16_8x2: table->rt = sfrt_dir_new(mem_cap, 3, 16,8,8); break; case DIR_16_4x4: table->rt = sfrt_dir_new(mem_cap, 5, 16,4,4,4,4); break; case DIR_8x4: table->rt = sfrt_dir_new(mem_cap, 4, 8,8,8,8); break; /* There is no reason to use 4x8 except for benchmarking and * comparison purposes. */ case DIR_4x8: table->rt = sfrt_dir_new(mem_cap, 8, 4,4,4,4,4,4,4,4); break; /* There is no reason to use 2x16 except for benchmarking and * comparison purposes. */ case DIR_2x16: table->rt = sfrt_dir_new(mem_cap, 16, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2); break; case DIR_16_4x4_16x5_4x4: table->rt = sfrt_dir_new(mem_cap, 5, 16,4,4,4,4); table->rt6 = sfrt_dir_new(mem_cap, 14, 16,4,4,4,4,16,16,16,16,16,4,4,4,4); break; case DIR_16x7_4x4: table->rt = sfrt_dir_new(mem_cap, 5, 16,4,4,4,4); table->rt6 = sfrt_dir_new(mem_cap, 11, 16,16,16,16,16,16,16,4,4,4,4); break; case DIR_16x8: table->rt = sfrt_dir_new(mem_cap, 2, 16,16); table->rt6 = sfrt_dir_new(mem_cap, 8, 16,16,16,16,16,16,16,16); break; case DIR_8x16: table->rt = sfrt_dir_new(mem_cap, 4, 16,8,4,4); table->rt6 = sfrt_dir_new(mem_cap, 16, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8); break; }; if((!table->rt) || (!table->rt6)) { if (table->rt) table->free( table->rt ); if (table->rt6) table->free( table->rt6 ); free(table->data); free(table); return NULL; } return table; } /* Free lookup table */ void sfrt_free(table_t *table) { if(!table) { /* What are you calling me for? */ return; } if(!table->data) { /* This really really should not have happened */ } else { free(table->data); } if(!table->rt) { /* This should not have happened either */ } else { table->free( table->rt ); } if(!table->rt6) { /* This should not have happened either */ } else { table->free( table->rt6 ); } free(table); } /* Perform a lookup on value contained in "ip" */ GENERIC sfrt_lookup(sfaddr_t* ip, table_t* table) { tuple_t tuple; uint32_t* adr; int numAdrDwords; void *rt; if(!ip) { return NULL; } if(!table || !table->lookup) { return NULL; } if (sfaddr_family(ip) == AF_INET) { adr = sfaddr_get_ip4_ptr(ip); numAdrDwords = 1; rt = table->rt; } else { adr = sfaddr_get_ip6_ptr(ip); numAdrDwords = 4; rt = table->rt6; } tuple = table->lookup(adr, numAdrDwords, rt); if(tuple.index >= table->max_size) { return NULL; } return table->data[tuple.index]; } void sfrt_iterate(table_t* table, sfrt_iterator_callback userfunc) { uint32_t index, count; if (!table) return; for (index = 0, count = 0; index < table->max_size; index++) { if (table->data[index]) { userfunc(table->data[index]); if (++count == table->num_ent) break; } } return; } void sfrt_iterate_with_snort_config(struct _SnortConfig *sc, table_t* table, sfrt_sc_iterator_callback userfunc) { uint32_t index, count; if (!table) return; for (index = 0, count = 0; index < table->max_size; index++) { if (table->data[index]) { userfunc(sc, table->data[index]); if (++count == table->num_ent) break; } } return; } int sfrt_iterate2(table_t* table, sfrt_iterator_callback3 userfunc) { uint32_t index, count; if (!table) return 0; for (index = 0, count = 0; index < table->max_size; index++) { if (table->data[index]) { int ret = userfunc(table->data[index]); if (ret != 0) return ret; if (++count == table->num_ent) break; } } return 0; } int sfrt_iterate2_with_snort_config(struct _SnortConfig *sc, table_t* table, sfrt_sc_iterator_callback3 userfunc) { uint32_t index, count; if (!table) return 0; for (index = 0, count = 0; index < table->max_size; index++) { if (table->data[index]) { int ret = userfunc(sc, table->data[index]); if (ret != 0) return ret; if (++count == table->num_ent) break; } } return 0; } void sfrt_cleanup2( table_t* table, sfrt_iterator_callback2 cleanup_func, void *data ) { uint32_t index, count; if (!table) return; for (index = 0, count = 0; index < table->max_size; index++) { if (table->data[index]) { cleanup_func(table->data[index], data); /* cleanup_func is supposed to free memory associated with this * table->data[index]. Set that to NULL. */ table->data[index] = NULL; if (++count == table->num_ent) break; } } } void sfrt_cleanup(table_t* table, sfrt_iterator_callback cleanup_func) { uint32_t index, count; if (!table) return; for (index = 0, count = 0; index < table->max_size; index++) { if (table->data[index]) { cleanup_func(table->data[index]); /* cleanup_func is supposed to free memory associated with this * table->data[index]. Set that to NULL. */ table->data[index] = NULL; if (++count == table->num_ent) break; } } return; } GENERIC sfrt_search(sfaddr_t* ip, table_t *table) { uint32_t* adr; int numAdrDwords; tuple_t tuple; void *rt = NULL; if ((ip == NULL) || (table == NULL)) return NULL; if (sfaddr_family(ip) == AF_INET) { adr = sfaddr_get_ip4_ptr(ip); numAdrDwords = 1; rt = table->rt; } else { adr = sfaddr_get_ip6_ptr(ip); numAdrDwords = 4; rt = table->rt6; } tuple = table->lookup(adr, numAdrDwords, rt); if(tuple.index >= table->max_size) return NULL; return table->data[tuple.index]; } /* Insert "ip", of length "len", into "table", and have it point to "ptr" */ /* Insert "ip", of length "len", into "table", and have it point to "ptr" */ int sfrt_insert(sfcidr_t* ip, unsigned char len, GENERIC ptr, int behavior, table_t *table) { int index; int newIndex = 0; int res; uint32_t* adr; int numAdrDwords; tuple_t tuple; void *rt = NULL; if(!ip) { return RT_INSERT_FAILURE; } if (len == 0) return RT_INSERT_FAILURE; if(!table || !table->insert || !table->data || !table->lookup) { return RT_INSERT_FAILURE; } if (len > 128) { return RT_INSERT_FAILURE; } /* Check if we can reuse an existing data table entry by * seeing if there is an existing entry with the same length. */ /* Only perform this if the table is not an LC-trie */ #ifdef SUPPORT_LCTRIE if(table->table_type != LCT) { #endif if (sfaddr_family(&ip->addr) == AF_INET) { if (len < 96) { return RT_INSERT_FAILURE; } len -= 96; adr = sfip_get_ip4_ptr(ip); numAdrDwords = 1; rt = table->rt; } else { adr = sfip_get_ip6_ptr(ip); numAdrDwords = 4; rt = table->rt6; } if (!rt) { return RT_INSERT_FAILURE; } tuple = table->lookup(adr, numAdrDwords, rt); #ifdef SUPPORT_LCTRIE } #endif #ifdef SUPPORT_LCTRIE if(table->table_type == LCT || tuple.length != len) { #else if(tuple.length != len) { #endif if( table->num_ent >= table->max_size) { return RT_POLICY_TABLE_EXCEEDED; } index = newIndex = allocateTableIndex(table); if (!index) return RT_POLICY_TABLE_EXCEEDED; } else { index = tuple.index; } /* The actual value that is looked-up is an index * into the data table. */ res = table->insert(adr, numAdrDwords, len, index, behavior, rt); if ((res == RT_SUCCESS) && newIndex) { table->num_ent++; table->data[ index ] = ptr; } return res; } /** Pretty print table * Pretty print sfrt table. * @param table - routing table. */ void sfrt_print(table_t *table) { if(!table || !table->print ) { return; } if (table->rt) table->print(table->rt); if (table->rt6) table->print(table->rt6); } uint32_t sfrt_num_entries(table_t *table) { if(!table || !table->rt || !table->allocated) { return 0; } /* There is always a root node, so subtract 1 for it */ return table->num_ent - 1; } uint32_t sfrt_usage(table_t *table) { uint32_t usage; if(!table || !table->rt || !table->allocated || !table->usage) { return 0; } usage = table->allocated + table->usage( table->rt ); if (table->rt6) { usage += table->usage( table->rt6 ); } return usage; } /** Remove subnet from sfrt table. * Remove subnet identified by ip/len and return associated data. * @param ip - IP address * @param len - length of netmask * @param ptr - void ** that is set to value associated with subnet * @param behavior - RT_FAVOR_SPECIFIC or RT_FAVOR_TIME * @note - For RT_FAVOR_TIME behavior, if partial subnet is removed then table->data[x] is nulled. Any remaining entries * will then point to null data. This can cause hung or crosslinked data. RT_FAVOR_SPECIFIC does not have this drawback. * hung or crosslinked entries. */ int sfrt_remove(sfcidr_t* ip, unsigned char len, GENERIC *ptr, int behavior, table_t *table) { int index; uint32_t* adr; int numAdrDwords; void *rt = NULL; if(!ip) { return RT_REMOVE_FAILURE; } if (len == 0) return RT_REMOVE_FAILURE; if(!table || !table->data || !table->remove || !table->lookup ) { //remove operation will fail for LCT since this operation is not implemented return RT_REMOVE_FAILURE; } if (len > 128) { return RT_REMOVE_FAILURE; } #ifdef SUPPORT_LCTRIE if(table->table_type != LCT) { #endif if (sfaddr_family(&ip->addr) == AF_INET) { if (len < 96) { return RT_REMOVE_FAILURE; } len -= 96; adr = sfip_get_ip4_ptr(ip); numAdrDwords = 1; rt = table->rt; } else { adr = sfip_get_ip6_ptr(ip); numAdrDwords = 4; rt = table->rt6; } #ifdef SUPPORT_LCTRIE } #endif /* The actual value that is looked-up is an index * into the data table. */ index = table->remove(adr, numAdrDwords, len, behavior, rt); /* Remove value into policy table. See TBD in function header*/ if (index) { *ptr = table->data[ index ]; table->data[ index ] = NULL; table->num_ent--; } return RT_SUCCESS; } /**allocate first unused index value. With delete operation, index values can be non-contiguous. * Index 0 is error in this function but this is valid entry in table->data that is used * for failure case. Calling function must check for 0 and take appropriate error action. */ static inline int allocateTableIndex(table_t *table) { uint32_t index; //0 is special index for failed entries. for (index = table->lastAllocatedIndex+1; index != table->lastAllocatedIndex; index = (index+1) % table->max_size) { if (index && !table->data[index]) { table->lastAllocatedIndex = index; return index; } } return 0; } #ifdef DEBUG_SFRT #define NUM_IPS 32 #define NUM_DATA 4 int main() { table_t *dir; uint32_t ip_list[NUM_IPS]; /* entirely arbitrary */ char data[NUM_DATA]; /* also entirely arbitrary */ uint32_t index, val; for(index=0; index %c\n", index, ip_list[index], data[index%NUM_DATA], *(uint32_t*)sfrt_lookup(&ip_list[index], dir)); } for(index=0; index < NUM_IPS; index++) { val = *(uint32_t*)sfrt_lookup(&ip_list[index], dir); printf("\t@%d\t%x: %c. originally:\t%c\n", index, ip_list[index], val, data[index%NUM_DATA]); } printf("Usage: %d bytes\n", ((dir_table_t*)(dir->rt))->allocated); sfrt_free(dir); return 0; } #endif /* DEBUG_SFRT */ snort-2.9.15.1/src/sfutil/sfrt.h0000644000175200017520000002360713571422607013304 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2006-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* * @file sfrt.h * @author Adam Keeton * @date Thu July 20 10:16:26 EDT 2006 * * SFRT implements two different routing table lookup methods that have been * adapted to return a void pointers. Any generic information may be * associated with a given IP or CIDR block. * * As of this writing, the two methods used are Stefan Nilsson and Gunnar * Karlsson's LC-trie, and a multibit-trie method similar to Gupta et-al.'s * DIR-n-m. Presently, the LC-trie is used for testing purposes as the * current implementation does not allow for fast, dynamic inserts. * * The intended use is to associate large IP blocks with specific information; * such as what may be written into the table by RNA. * * NOTE: information should only move from less specific to more specific, ie: * * First insert: 1.1.0.0/16 -> some data * Second insert: 1.1.2.3 -> some other data * * As opposed to: * * First insert: 1.1.2.3 -> some other data * Second insert: 1.1.0.0/16 -> some data * * If more general information is to overwrite existing entries, the table * should be free'ed and rebuilt. This is due to the difficulty of cleaning * out stale entries with the current implementation. At runtime, this won't * be a significant issue since inserts should apply to specific IP addresses * and not entire blocks of IPs. * * * Implementation: * * The routing tables associate an index into a "data" table with each CIDR. * Each entry in the data table stores a pointer to actual data. This * implementation was chosen so each routing entry only needs one word to * either index the data array, or point to another table. * * Inserts are performed by specifying a CIDR and a pointer to its associated * data. Since a new routing table entry may overwrite previous entries, * a flag selects whether the insert favors the most recent or favors the most * specific. Favoring most specific should be the default behvior. If * the user wishes to overwrite routing entries with more general data, the * table should be flushed, rather than using favor-most-recent. * * Before modifying the routing or data tables, the insert function performs a * lookup on the CIDR-to-be-insertted. If no entry or an entry *of differing * bit length* is found, the data is insertted into the data table, and its * index is used for the new routing table entry. If an entry is found that * is as specific as the new CIDR, the index stored points to where the new * data is written into the data table. * * If more specific CIDR blocks overwrote the data table, then the more * general routing table entries that were not overwritten will be referencing * the wrong data. Alternatively, less specific entries can only overwrite * existing routing table entries if favor-most-recent inserts are used. * * Because there is no quick way to clean the data-table if a user wishes to * use a favor-most-recent insert for more general data, the user should flush * the table with sfrt_free and create one anew. Alternatively, a small * memory leak occurs with the data table, as it will be storing pointers that * no routing table entry cares about. * * * The API calls that should be used are: * sfrt_new - create new table * sfrt_insert - insert entry * sfrt_lookup - lookup entry * sfrt_free - free table */ #ifndef _SFRT_H_ #define _SFRT_H_ #include #include #include "sfrt_trie.h" #include "snort_debug.h" #include "ipv6_port.h" typedef sfcidr_t *IP; typedef void* GENERIC; /* To be replaced with a pointer to a policy */ typedef struct { word index; word length; } tuple_t; #include "sfrt_dir.h" /*#define SUPPORT_LCTRIE */ #ifdef SUPPORT_LCTRIE #include "sfrt_lctrie.h" #endif enum types { #ifdef SUPPORT_LCTRIE LCT, #endif DIR_24_8, DIR_16x2, DIR_16_8x2, DIR_16_4x4, DIR_8x4, DIR_4x8, DIR_2x16, DIR_16_4x4_16x5_4x4, DIR_16x7_4x4, DIR_16x8, DIR_8x16, IPv4, IPv6 }; enum return_codes { RT_SUCCESS=0, RT_INSERT_FAILURE, RT_POLICY_TABLE_EXCEEDED, DIR_INSERT_FAILURE, DIR_LOOKUP_FAILURE, MEM_ALLOC_FAILURE, #ifdef SUPPORT_LCTRIE LCT_COMPILE_FAILURE, LCT_INSERT_FAILURE, LCT_LOOKUP_FAILURE, #endif RT_REMOVE_FAILURE }; /* Defined in sfrt.c */ extern char *rt_error_messages[]; enum { RT_FAVOR_TIME, RT_FAVOR_SPECIFIC, RT_FAVOR_ALL }; /*******************************************************************/ /* Master table struct. Abstracts DIR and LC-trie methods */ typedef struct { GENERIC *data; /* data table. Each IP points to an entry here */ uint32_t num_ent; /* Number of entries in the policy table */ uint32_t max_size; /* Max size of policies array */ uint32_t lastAllocatedIndex; /* Index allocated last. Search for unused index starts from this value and then wraps around at max_size.*/ char ip_type; /* Only IPs of this family will be used */ char table_type; uint32_t allocated; void *rt; /* Actual "routing" table */ void *rt6; /* Actual "routing" table */ tuple_t (*lookup)(uint32_t* adr, int numAdrDwords, GENERIC tbl); int (*insert)(uint32_t* adr, int numAdrDwords, int len, word index, int behavior, GENERIC tbl); void (*free)(GENERIC tbl); uint32_t (*usage)(GENERIC tbl); void (*print)(GENERIC tbl); word (*remove)(uint32_t* adr, int numAdrDwords, int len, int behavior, GENERIC tbl); } table_t; /*******************************************************************/ /* Abstracted routing table API */ table_t * sfrt_new(char type, char ip_type, long data_size, uint32_t mem_cap); void sfrt_free(table_t *table); GENERIC sfrt_lookup(sfaddr_t* ip, table_t* table); GENERIC sfrt_search(sfaddr_t* ip, table_t *table); typedef void (*sfrt_iterator_callback)(void *); struct _SnortConfig; typedef void (*sfrt_sc_iterator_callback)(struct _SnortConfig *, void *); typedef int (*sfrt_sc_iterator_callback3)(struct _SnortConfig *, void *); typedef void (*sfrt_iterator_callback2)(void *, void *); typedef int (*sfrt_iterator_callback3)(void *); void sfrt_iterate(table_t* table, sfrt_iterator_callback userfunc); void sfrt_iterate_with_snort_config(struct _SnortConfig *sc, table_t* table, sfrt_sc_iterator_callback userfunc); int sfrt_iterate2(table_t* table, sfrt_iterator_callback3 userfunc); int sfrt_iterate2_with_snort_config(struct _SnortConfig *sc, table_t* table, sfrt_sc_iterator_callback3 userfunc); void sfrt_cleanup(table_t* table, sfrt_iterator_callback userfunc); void sfrt_cleanup2(table_t*, sfrt_iterator_callback2, void *); int sfrt_insert(sfcidr_t* ip, unsigned char len, GENERIC ptr, int behavior, table_t *table); int sfrt_remove(sfcidr_t* ip, unsigned char len, GENERIC *ptr, int behavior, table_t *table); uint32_t sfrt_usage(table_t *table); void sfrt_print(table_t *table); uint32_t sfrt_num_entries(table_t *table); /* Perform a lookup on value contained in "ip" * For performance reason, we use this simplified version instead of sfrt_lookup * Note: this only applied to table setting: DIR_8x16 (DIR_16_8_4x2 for IPV4), DIR_8x4*/ static inline GENERIC sfrt_dir8x_lookup(sfaddr_t *ip, table_t* table) { dir_sub_table_t *subtable; int i; void *rt = NULL; int index; if (sfaddr_family(ip) == AF_INET) { rt = table->rt; subtable = ((dir_table_t *)rt)->sub_table; /* 16 bits*/ index = ntohs(ip->ia16[6]); if( !subtable->entries[index] || subtable->lengths[index] ) { return table->data[subtable->entries[index]]; } subtable = (dir_sub_table_t *) subtable->entries[index]; /* 8 bits*/ index = ip->ia8[14]; if( !subtable->entries[index] || subtable->lengths[index] ) { return table->data[subtable->entries[index]]; } subtable = (dir_sub_table_t *) subtable->entries[index]; /* 4 bits */ index = ip->ia8[15] >> 4; if( !subtable->entries[index] || subtable->lengths[index] ) { return table->data[subtable->entries[index]]; } subtable = (dir_sub_table_t *) subtable->entries[index]; /* 4 bits */ index = ip->ia8[15] & 0xF; if( !subtable->entries[index] || subtable->lengths[index] ) { return table->data[subtable->entries[index]]; } } else { rt = table->rt6; subtable = ((dir_table_t *)rt)->sub_table; for (i = 0; i < 16; i++) { index = ip->ia8[i]; if( !subtable->entries[index] || subtable->lengths[index] ) { return table->data[subtable->entries[index]]; } subtable = (dir_sub_table_t *) subtable->entries[index]; } } return NULL; } #endif snort-2.9.15.1/src/sfutil/sfrt_trie.h0000644000175200017520000001160013571422607014315 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2006-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* trie.h A routing table for wordsized (32bits) bitstrings implemented as a static level- and pathcompressed trie. For details please consult Stefan Nilsson and Gunnar Karlsson. Fast Address Look-Up for Internet Routers. International Conference of Broadband Communications (BC'97). http://www.hut.fi/~sni/papers/router/router.html The code presented in this file has been tested with care but is not guaranteed for any purpose. The writer does not offer any warranties nor does he accept any liabilities with respect to the code. Stefan Nilsson, 4 nov 1997. Laboratory of Information Processing Science Helsinki University of Technology Stefan.Nilsson@hut.fi */ /* The trie is represented by an array and each node consists of an unsigned word. The first 5 bits (31-27) indicate the logarithm of the branching factor. The next 5 bits (26-22) indicate the skip value. The final 22 (21-0) bits is an adress, either to another internal node, or the base vector. The maximum capacity is 2^21 strings (or a few more). The trie is prefixfree. All strings that are prefixes of another string are stored separately. */ #ifndef RT_TRIE_H #define RT_TRIE_H #define ADRSIZE 32 /* the number of bits in an address */ /* A 32-bit word is used to hold the bit patterns of the addresses. In IPv6 this should be 128 bits. The following typedef is machine dependent. A word must be 32 bits long! */ typedef unsigned long word; /* The trie is represented by an array and each node in the trie is compactly represented using only 32 bits: 5 + 5 + 22 = branch + skip + adr */ typedef word node_t; #define NOPRE -1 /* an empty prefix pointer */ #define SETBRANCH(branch) ((branch)<<27) #define GETBRANCH(node) ((node)>>27) #define SETSKIP(skip) ((skip)<<22) #define GETSKIP(node) ((node)>>22 & 037) #define SETADR(adr) (adr) #define GETADR(node) ((node) & 017777777) /* extract n bits from str starting at position p */ #define EXTRACT(p, n, str) ((str)<<(p)>>(32-(n))) /* remove the first p bits from string */ #define REMOVE(p, str) ((str)<<(p)>>(p)) /* A next-hop table entry is a 32 bit string */ typedef word policy_t; /* The routing table entries are initially stored in a simple array */ typedef struct entryrec *entry_t; struct entryrec { word data; /* the routing entry */ int len; /* and its length */ policy_t policy; /* the corresponding next-hop */ int pre; /* this auxiliary variable is used in the */ }; /* construction of the final data structure */ /* base vector */ typedef struct baserec *base_t; struct baserec { word str; /* the routing entry */ int len; /* and its length */ int pre; /* pointer to prefix table, -1 if no prefix */ int policy; /* pointer to next-hop table */ }; typedef struct { /* compact version of above */ word str; int len; int pre; int policy; } comp_base_t; /* prefix vector */ typedef struct prerec *pre_t; struct prerec { int len; /* the length of the prefix */ int pre; /* pointer to prefix, -1 if no prefix */ int policy; /* pointer to policy table */ }; typedef struct { /* compact version of above */ int len; int pre; int policy; } comp_pre_t; /* The complete routing table data structure consists of a trie, a base vector, a prefix vector, and a next-hop table. */ typedef struct routtablerec *routtable_t; struct routtablerec { node_t *trie; /* the main trie search structure */ int triesize; comp_base_t *base; /* the base vector */ int basesize; comp_pre_t *pre; /* the prefix vector */ int presize; policy_t *policy; /* the next-hop table */ int policysize; int dirty; /* Whether or not the table needs to be rebuilt */ }; #endif snort-2.9.15.1/src/sfutil/sfrt_dir.c0000644000175200017520000005464413571422607014142 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2006-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* * @file sfdir.c * @author Adam Keeton * @date Thu July 20 10:16:26 EDT 2006 * * The implementation uses an multibit-trie that is similar to Gupta et-al's * DIR-n-m. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include /* For variadic */ #include #include /* For memset */ #include "sf_types.h" #include "sfrt.h" #include "sfrt_dir.h" typedef struct { uint32_t* adr; int bits; } IPLOOKUP; /* Create new "sub" table of 2^width entries */ static dir_sub_table_t *_sub_table_new(dir_table_t *root, uint32_t dimension, uint32_t prefill, uint32_t bit_length) { int width = root->dimensions[dimension]; int len = 1 << width; int index; dir_sub_table_t *sub; /* Check if creating this node will exceed the memory cap. * The symbols in the conditional (other than cap), come from the * allocs below. */ if( root->mem_cap < ( root->allocated + sizeof(dir_sub_table_t) + sizeof(word) * len + len ) || bit_length > 128) { return NULL; } /* Set up the initial prefilled "sub table" */ sub = (dir_sub_table_t*)malloc(sizeof(dir_sub_table_t)); if(!sub) { return NULL; } /* This keeps the width readily available rather than recalculating it * from the number of entries during an insert or lookup */ sub->width = width; /* need 2^sub->width entries */ sub->num_entries = len; sub->entries = (word*)malloc(sizeof(word) * sub->num_entries); if(!sub->entries) { free(sub); return NULL; } /* A "length" needs to be stored with each entry above. The length refers * to how specific the insertion that set the entry was. It is necessary * so that the entry is not overwritten by less general routing * information if "RT_FAVOR_SPECIFIC" insertions are being performed. */ sub->lengths = (uint8_t*)malloc(sub->num_entries); if(!sub->lengths) { free(sub->entries); free(sub); return NULL; } /* Can't use memset here since prefill is multibyte */ for(index = 0; index < sub->num_entries; index++) { sub->entries[index] = prefill; sub->lengths[index] = (uint8_t)bit_length; } sub->cur_num = 0; if (prefill) sub->filledEntries = sub->num_entries; else sub->filledEntries = 0; root->allocated += sizeof(dir_sub_table_t) + sizeof(word) * sub->num_entries + sub->num_entries; root->cur_num++; return sub; } /* Create new dir-n-m root table with 'count' depth */ dir_table_t *sfrt_dir_new(uint32_t mem_cap, int count,...) { va_list ap; uint32_t val; int index; dir_table_t* table = (dir_table_t*)malloc(sizeof(dir_table_t)); if(!table) { return NULL; } table->allocated = 0; table->dimensions = (int*)malloc(sizeof(int)*count); if(!table->dimensions) { free(table); return NULL; } table->dim_size = count; va_start(ap, count); for(index=0; index < count; index++) { val = va_arg(ap, int); table->dimensions[index] = val; } va_end(ap); table->mem_cap = mem_cap; table->cur_num = 0; table->sub_table = _sub_table_new(table, 0, 0, 0); if(!table->sub_table) { free(table->dimensions); free(table); return NULL; } table->allocated += sizeof(dir_table_t) + sizeof(int)*count; return table; } /* Traverse "sub" tables, freeing each */ static void _sub_table_free(uint32_t *allocated, dir_sub_table_t *sub) { int index; sub->cur_num--; for(index=0; index < sub->num_entries; index++) { /* The following condition will only be true if * this entry is a pointer */ if( !sub->lengths[index] && sub->entries[index] ) { _sub_table_free( allocated, (dir_sub_table_t*) sub->entries[index]); } } if(sub->entries) { /* This probably does not need to be checked * since if it was not allocated, we would have errored out * in _sub_table_new */ free(sub->entries); *allocated -= sizeof(word) * sub->num_entries; } if(sub->lengths) { /* This probably does not need to be checked * since if it was not allocated, we would have errored out * in _sub_table_new */ free(sub->lengths); *allocated -= sub->num_entries; } free(sub); *allocated -= sizeof(dir_sub_table_t); } /* Free the DIR-n-m structure */ void sfrt_dir_free(void *tbl) { dir_table_t *table = (dir_table_t*)tbl; if(!table) { return; } if(table->sub_table) { _sub_table_free(&table->allocated, table->sub_table); } if(table->dimensions) { free(table->dimensions); } free(table); } static inline void _dir_fill_all(uint32_t *allocated, uint32_t index, uint32_t fill, word length, uint32_t val, dir_sub_table_t *table) { /* Fill entries */ for(; index < fill; index++) { /* Before overwriting this entry, verify there's not an existing * pointer ... otherwise free it to avoid a huge memory leak. */ if(table->entries[index]) { if (!table->lengths[index]) { _sub_table_free(allocated, (dir_sub_table_t*)table->entries[index]); } } else { table->filledEntries++; } table->entries[index] = val; table->lengths[index] = (uint8_t)length; } } static inline void _dir_fill_less_specific(int index, int fill, word length, uint32_t val, dir_sub_table_t *table) { /* Fill entries */ for(; index < fill; index++) { /* If we encounter a pointer, and we're inserting at this level, we * automatically know that this entry refers to more specific * information. However, there might only be one more specific entry * in the entire block, meaning the rest must be filled. * * For instance, imagine a 24-8 with 1.2.3/24 -> A and 1.2.3.4/32 -> B * There will be a pointer at 1.2.3 in the first table. The second * table needs to have 255 entries pointing A, and 1 entry pointing to * B. * * Therefore, recurse to this next level. */ if( !table->lengths[index] && table->entries[index]) { dir_sub_table_t *next = (dir_sub_table_t*)table->entries[index]; _dir_fill_less_specific(0, 1 << next->width, length, val, next); } else if(length >= (word)table->lengths[index]) { if (!table->entries[index]) { table->filledEntries++; } table->entries[index] = val; table->lengths[index] = (char)length; } } } /*Remove entries all this level and discard any more specific entries. * * @note RT_FAVOR_TIME behavior can cause hung or crosslinked entries if part of a subnet * (which was added) are deleted. Same issue is there when a more general subnet overwrites * a specific subnet. table->data[] entry for more specific subnet is not cleared. * * @note RT_FAVOR_TIME can cause orphaned table->data[] entries if the entire subnet * is replaced by more specific sudnets. */ static inline uint32_t _dir_remove_all(uint32_t *allocated, uint32_t index, uint32_t fill, word length, dir_sub_table_t *table) { uint32_t valueIndex = 0; /* Fill entries */ for(; index < fill; index++) { /* Before overwriting this entry, verify there's not an existing * pointer ... otherwise free it to avoid a huge memory leak. */ if (table->entries[index]) { if (!table->lengths[index]) { _sub_table_free(allocated, (dir_sub_table_t*)table->entries[index]); } if(length == (word)table->lengths[index]) { valueIndex = table->entries[index]; } table->filledEntries--; //zero value here works since sfrt uses 0 for failed entries. table->entries[index] = 0; table->lengths[index] = 0; } } return valueIndex; } /**Remove entries which match in address/length in all subtables. * @note RT_FAVOR_SPECIFIC can cause orphaned table->data[] entries if the entire subnet * is replaced by more specific subnets. */ static inline uint32_t _dir_remove_less_specific(uint32_t *allocated, int index, int fill, word length, dir_sub_table_t *table) { uint32_t valueIndexRet = 0; uint32_t valueIndex = 0; for(; index < fill; index++) { if( !table->lengths[index] && table->entries[index]) { dir_sub_table_t *next = (dir_sub_table_t*)table->entries[index]; valueIndex = _dir_remove_less_specific(allocated, 0, 1 << next->width, length, next); if (valueIndex) { valueIndexRet = valueIndex; } if (!next->filledEntries) //table can be collapsed. { _sub_table_free(allocated, next); table->entries[index] = 0; table->lengths[index] = 0; table->filledEntries--; } } else if(length == (word)table->lengths[index]) { if (table->entries[index]) { table->filledEntries--; valueIndexRet = table->entries[index]; } table->entries[index] = 0; table->lengths[index] = 0; } } return valueIndexRet; } /* Sub table insertion * This is called by dir_insert and recursively to find the the sub table * that should house the value "ptr" * @param ip IP address structure * @param cur_len Number of bits of the IP left at this depth * @param length Number of bits of the IP used to specify this CIDR * @param ptr Information to be associated with this IP range * @param master_table The table that describes all, returned by dir_new */ static int _dir_sub_insert(IPLOOKUP *ip, int length, int cur_len, GENERIC ptr, int current_depth, int behavior, dir_sub_table_t *sub_table, dir_table_t *root_table) { word index; uint32_t fill; { uint32_t local_index, i; /* need to handle bits usage across multiple 32bit vals within IPv6. */ if (ip->bits < 32 ) { i=0; } else if (ip->bits < 64) { i=1; } else if (ip->bits < 96) { i=2; } else { i=3; } local_index = ip->adr[i] << (ip->bits %32); index = local_index >> (sizeof(local_index)*8 - sub_table->width); } /* Check if this is the last table to traverse to */ if(sub_table->width >= cur_len) { /* Calculate how many entries need to be filled * in this table. If the table is 24 bits wide, and the entry * is 20 bytes long, 2^4 entries need to be filled. */ fill = 1 << (sub_table->width - cur_len); index = (index >> (sub_table->width - cur_len)) << (sub_table->width - cur_len); fill += index; /* Favor most recent CIDR */ if(behavior == RT_FAVOR_TIME) { _dir_fill_all(&root_table->allocated, index, fill, length, (word)ptr, sub_table); } /* Fill over less specific CIDR */ else { _dir_fill_less_specific(index, fill, length, (word)ptr, sub_table); } } /* Need to traverse to a sub-table */ else { dir_sub_table_t *next_sub = (dir_sub_table_t *)sub_table->entries[index]; /* Check if we need to alloc a new sub table. * If next_sub was 0/NULL, there's no entry at this index * If the length is non-zero, there is an entry */ if(!next_sub || sub_table->lengths[index]) { if( root_table->dim_size <= current_depth ) { return RT_INSERT_FAILURE; } sub_table->entries[index] = (word) _sub_table_new(root_table, current_depth+1, (word) next_sub, sub_table->lengths[index]); if (!next_sub) { sub_table->filledEntries++; } sub_table->cur_num++; sub_table->lengths[index] = 0; next_sub = (dir_sub_table_t *)sub_table->entries[index]; if(!next_sub) { return MEM_ALLOC_FAILURE; } } /* Recurse to next level. Rightshift off appropriate number of * bits and update the length accordingly. */ ip->bits += sub_table->width; return (_dir_sub_insert(ip, length, cur_len - sub_table->width, ptr, current_depth+1, behavior, next_sub, root_table)); } return RT_SUCCESS; } /* Insert entry into DIR-n-m tables * @param ip IP address structure * @param len Number of bits of the IP used for lookup * @param ptr Information to be associated with this IP range * @param master_table The table that describes all, returned by dir_new */ int sfrt_dir_insert(uint32_t* adr, int numAdrDwords, int len, word data_index, int behavior, void *table) { dir_table_t *root = (dir_table_t*)table; uint32_t h_adr[4]; IPLOOKUP iplu; iplu.adr = h_adr; iplu.bits = 0; /* Validate arguments */ if(!root || !root->sub_table) { return DIR_INSERT_FAILURE; } h_adr[0] = ntohl(adr[0]); if (len > 96) { h_adr[1] = ntohl(adr[1]); h_adr[2] = ntohl(adr[2]); h_adr[3] = ntohl(adr[3]); } else if (len > 64) { h_adr[1] = ntohl(adr[1]); h_adr[2] = ntohl(adr[2]); } else if (len > 32) { h_adr[1] = ntohl(adr[1]); } /* Find the sub table in which to insert */ return _dir_sub_insert(&iplu, len, len, (GENERIC)data_index, 0, behavior, root->sub_table, root); } /* Traverse sub tables looking for match */ /* Called by dir_lookup and recursively */ static tuple_t _dir_sub_lookup(IPLOOKUP *ip, dir_sub_table_t *table) { word index; { uint32_t local_index, i; /* need to handle bits usage across multiple 32bit vals within IPv6. */ if (ip->bits < 32 ) { i=0; } else if (ip->bits < 64) { i=1; } else if (ip->bits < 96) { i=2; } else { i=3; } local_index = ip->adr[i] << (ip->bits %32); index = local_index >> (sizeof(local_index)*8 - table->width); } if( !table->entries[index] || table->lengths[index] ) { tuple_t ret; ret.index = table->entries[index]; ret.length = (word)table->lengths[index]; return ret; } ip->bits += table->width; return _dir_sub_lookup( ip, (dir_sub_table_t *)table->entries[index]); } /* Lookup information associated with the value "ip" */ tuple_t sfrt_dir_lookup(uint32_t* adr, int numAdrDwords, void *tbl) { dir_table_t *root = (dir_table_t*)tbl; uint32_t h_adr[4]; int i; IPLOOKUP iplu; iplu.adr = h_adr; iplu.bits = 0; if(!root || !root->sub_table) { tuple_t ret = { 0, 0 }; return ret; } for (i = 0; i < numAdrDwords; i++) { h_adr[i] = ntohl(adr[i]); } return _dir_sub_lookup(&iplu, root->sub_table); } uint32_t sfrt_dir_usage(void *table) { if(!table) { return 0; } return ((dir_table_t*)(table))->allocated; } static void _sub_table_print(dir_sub_table_t *sub, uint32_t level, dir_table_t *table) { int index; char label[100]; memset(label, ' ', sizeof(label)); label[level*5] = '\0'; printf("%sCurrent Nodes: %d, Filled Entries: %d, table Width: %d\n", label, sub->cur_num, sub->filledEntries, sub->width); for(index=0; index < sub->num_entries; index++) { if (sub->lengths[index] || sub->entries[index]) printf("%sIndex: %d, Length: %d, dataIndex: %d\n", label, index, sub->lengths[index], (uint32_t)sub->entries[index]); if( !sub->lengths[index] && sub->entries[index] ) { _sub_table_print((dir_sub_table_t*) sub->entries[index], level+1, table); } } } /* Print a table. * Prints a table and its subtable. This is used for debugging purpose only. * @param table The table that describes all, returned by dir_new */ void sfrt_dir_print(void *tbl) { dir_table_t *table = (dir_table_t*)tbl; if(!table) { return; } printf ("Nodes in use: %d\n", table->cur_num); if(table->sub_table) { _sub_table_print(table->sub_table, 1, table); } } /* Sub table removal * Recursive function to drill down to subnet table and remove entries. * @param ip IP address structure * @param length Number of bits of the IP used to specify this CIDR * @param cur_len Number of bits of the IP left at this depth * @param current_depth Number of levels down from root_table. * @param behavior RT_FAVOR_SPECIFIC or RT_FAVOR_TIME * @param root_table The table that describes all, returned by dir_new * @returns index of entry removed. Returns 0, which is a valid index, as failure code. * Calling function should treat 0 index as failure case.*/ static int _dir_sub_remove(IPLOOKUP *ip, int length, int cur_len, int current_depth, int behavior, dir_sub_table_t *sub_table, dir_table_t *root_table) { word index; uint32_t fill; uint32_t valueIndex = 0; { uint32_t local_index, i; /* need to handle bits usage across multiple 32bit vals within IPv6. */ if (ip->bits < 32 ) { i=0; } else if (ip->bits < 64) { i=1; } else if (ip->bits < 96) { i=2; } else { i=3; } local_index = ip->adr[i] << (ip->bits %32); index = local_index >> (sizeof(local_index)*8 - sub_table->width); } /* Check if this is the last table to traverse to */ if(sub_table->width >= cur_len) { /* Calculate how many entries need to be removed (filled with 0) * in this table. If the table is 24 bits wide, and the entry * is 20 bytes long, 2^4 entries need to be filled. */ fill = 1 << (sub_table->width - cur_len); index = (index >> (sub_table->width - cur_len)) << (sub_table->width - cur_len); fill += index; /* Remove and overwrite without consedering CIDR specificity*/ if(behavior == RT_FAVOR_TIME) { valueIndex = _dir_remove_all(&root_table->allocated, index, fill, length, sub_table); } /* Remove and overwrite only less specific CIDR */ else { valueIndex = _dir_remove_less_specific(&root_table->allocated, index, fill, length, sub_table); } } else { /* traverse to a next sub-table down*/ dir_sub_table_t *next_sub = (dir_sub_table_t *)sub_table->entries[index]; /*subtable was never added. */ if(!next_sub || sub_table->lengths[index]) { return 0; } /* Recurse to next level. Rightshift off appropriate number of * bits and update the length accordingly. */ ip->bits += sub_table->width; valueIndex = _dir_sub_remove(ip, length, cur_len - sub_table->width, current_depth+1, behavior, next_sub, root_table); if (!next_sub->filledEntries) { _sub_table_free(&root_table->allocated, next_sub); sub_table->entries[index] = 0; sub_table->lengths[index] = 0; sub_table->filledEntries--; root_table->cur_num--; } } return valueIndex; } /* Remove entry into DIR-n-m tables * @param ip IP address structure * @param len Number of bits of the IP used for lookup * @param behavior RT_FAVOR_SPECIFIC or RT_FAVOR_TIME * @param table The table that describes all, returned by dir_new * @return index to data or 0 on failure. Calling function should check for 0 since * this is valid index for failed operation. */ word sfrt_dir_remove(uint32_t* adr, int numAdrDwords, int len, int behavior, void *table) { dir_table_t *root = (dir_table_t*)table; uint32_t h_adr[4]; IPLOOKUP iplu; iplu.adr = h_adr; iplu.bits = 0; /* Validate arguments */ if(!root || !root->sub_table) { return 0; } h_adr[0] = ntohl(adr[0]); if (len > 96) { h_adr[1] = ntohl(adr[1]); h_adr[2] = ntohl(adr[2]); h_adr[3] = ntohl(adr[3]); } else if (len > 64) { h_adr[1] = ntohl(adr[1]); h_adr[2] = ntohl(adr[2]); } else if (len > 32) { h_adr[1] = ntohl(adr[1]); } /* Find the sub table in which to remove */ return _dir_sub_remove(&iplu, len, len, 0, behavior, root->sub_table, root); } snort-2.9.15.1/src/sfutil/sfrt_dir.h0000644000175200017520000000656613571422607014147 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2006-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* * @file sfdir.h * @author Adam Keeton * @date Thu July 20 10:16:26 EDT 2006 * * The implementation uses an multibit-trie that is similar to Gupta et-al's * DIR-n-m. */ #ifndef SFRT_DIR_H_ #define SFRT_DIR_H_ /*******************************************************************/ /* DIR-n-m data structures * Each table in the DIR-n-m method is represented by a * dir_sub_table_t. They are managed by a dir_table_t. */ typedef struct { word *entries; uint8_t *lengths; int num_entries; /* Number of entries in this table */ int width; /* width of this table. */ /* While one determines the other, this way fewer * calculations are needed at runtime, since both * are used. */ int cur_num; /* Present number of used nodes */ /** number of entries filled including chidren sub_tables. This is used * for freeing sub_tables when all entried are freed by delete operation. */ int filledEntries; } dir_sub_table_t; /* Master data structure for the DIR-n-m derivative */ typedef struct { int *dimensions; /* DIR-n-m will consist of any number of arbitrarily * long tables. This variable keeps track of the * dimensions */ int dim_size; /* And this variable keeps track of 'dimensions''s * dimensions! */ uint32_t mem_cap; /* User-defined maximum memory that can be allocated * for the DIR-n-m derivative */ int cur_num; /* Present number of used nodes */ uint32_t allocated; dir_sub_table_t *sub_table; } dir_table_t; /*******************************************************************/ /* DIR-n-m functions, these are not intended to be called directly */ dir_table_t * sfrt_dir_new(uint32_t mem_cap, int count,...); void sfrt_dir_free(void *); tuple_t sfrt_dir_lookup(uint32_t* adr, int numAdrDwords, void *table); int sfrt_dir_insert(uint32_t* adr, int numAdrDwords, int len, word data_index, int behavior, void *table); uint32_t sfrt_dir_usage(void *table); void sfrt_dir_print(void *table); word sfrt_dir_remove(uint32_t* adr, int numAdrDwords, int len, int behavior, void *table); #endif /* SFRT_DIR_H_ */ snort-2.9.15.1/src/sfutil/sfrt_flat.c0000644000175200017520000002357213571422607014306 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2011-2013 Sourcefire, Inc. ** ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** ** 9/7/2011 - Initial implementation ... Hui Cao */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sf_types.h" #include "sfrt_flat.h" #define MINIMAL_TABLE_MEMORY (1024*512) /*Basic table cost is around 512k*/ /* Create new lookup table * @param table_flat_type Type of table. Uses the types enumeration in route.h * @param ip_type IPv4 or IPv6. Uses the types enumeration in route.h * @param data_size Max number of unique data entries * * Returns the new table. */ table_flat_t *sfrt_flat_new(char table_flat_type, char ip_type, long data_size, uint32_t mem_cap) { table_flat_t *table; MEM_OFFSET table_ptr; uint8_t *base; long data_size_max = 1; table_ptr = segment_malloc(sizeof(table_flat_t)); #if 0 /*The first allocation always return 0*/ if(!table_ptr) { // return NULL; } #endif base = (uint8_t *)segment_basePtr(); table = (table_flat_t *)(&base[table_ptr]); /* If this limit is exceeded, there will be no way to distinguish * between pointers and indeces into the data table. Only * applies to DIR-n-m. */ #if SIZEOF_LONG_INT == 8 if(data_size >= 0x800000000000000) #else if(data_size >= 0x8000000) #endif { segment_free(table_ptr); return NULL; } /* mem_cap is specified in megabytes, but internally uses bytes. Convert */ mem_cap *= 1024*1024; /* Maximum allowable number of stored entries based on memcap */ if (mem_cap > MINIMAL_TABLE_MEMORY) data_size_max = (mem_cap - MINIMAL_TABLE_MEMORY)/sizeof(INFO); /* Maximum allowable number of stored entries */ if (data_size < data_size_max) table->max_size = data_size; else table->max_size = data_size_max; table->data = (INFO)segment_calloc(sizeof(INFO) * table->max_size, 1); if(!table->data) { segment_free(table_ptr); return NULL; } table->allocated = sizeof(table_flat_t) + sizeof(INFO) * table->max_size; table->ip_type = ip_type; table->table_flat_type = table_flat_type; /* This will point to the actual table lookup algorithm */ table->rt = 0; table->rt6 = 0; /* index 0 will be used for failed lookups, so set this to 1 */ table->num_ent = 1; /* Allocate the user-specified DIR-n-m table */ switch(table_flat_type) { case DIR_24_8: table->rt = sfrt_dir_flat_new( mem_cap, 2, 24, 8); break; case DIR_16x2: table->rt = sfrt_dir_flat_new( mem_cap, 2, 16,16); break; case DIR_16_8x2: table->rt = sfrt_dir_flat_new( mem_cap, 3, 16,8,8); break; case DIR_16_4x4: table->rt = sfrt_dir_flat_new( mem_cap, 5, 16,4,4,4,4); break; case DIR_8x4: table->rt = sfrt_dir_flat_new( mem_cap, 4, 8,8,8,8); break; /* There is no reason to use 4x8 except for benchmarking and * comparison purposes. */ case DIR_4x8: table->rt = sfrt_dir_flat_new( mem_cap, 8, 4,4,4,4,4,4,4,4); break; /* There is no reason to use 2x16 except for benchmarking and * comparison purposes. */ case DIR_2x16: table->rt = sfrt_dir_flat_new( mem_cap, 16, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2); break; case DIR_16_4x4_16x5_4x4: table->rt = sfrt_dir_flat_new(mem_cap, 5, 16,4,4,4,4); table->rt6 = sfrt_dir_flat_new(mem_cap, 14, 16,4,4,4,4,16,16,16,16,16,4,4,4,4); break; case DIR_16x7_4x4: table->rt = sfrt_dir_flat_new(mem_cap, 5, 16,4,4,4,4); table->rt6 = sfrt_dir_flat_new(mem_cap, 11, 16,16,16,16,16,16,16,4,4,4,4); break; case DIR_16x8: table->rt = sfrt_dir_flat_new(mem_cap, 2, 16,16); table->rt6 = sfrt_dir_flat_new(mem_cap, 8, 16,16,16,16,16,16,16,16); break; case DIR_8x16: table->rt = sfrt_dir_flat_new(mem_cap, 7, 16,4,4,2,2,2,2); table->rt6 = sfrt_dir_flat_new(mem_cap, 16, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8); break; }; if((!table->rt) || (!table->rt6)) { if (table->rt) sfrt_dir_flat_free( table->rt ); if (table->rt6) sfrt_dir_flat_free( table->rt6 ); segment_free(table->data); segment_free(table_ptr); return NULL; } return table; } /* Free lookup table */ void sfrt_flat_free(TABLE_PTR table_ptr) { table_flat_t *table; uint8_t *base; if(!table_ptr) { /* What are you calling me for? */ return; } base = (uint8_t *)segment_basePtr(); table = (table_flat_t *)(&base[table_ptr]); if(!table->data) { /* This really really should not have happened */ } else { segment_free(table->data); } if(!table->rt) { /* This should not have happened either */ } else { sfrt_dir_flat_free( table->rt ); } if(!table->rt6) { /* This should not have happened either */ } else { sfrt_dir_flat_free( table->rt6 ); } segment_free(table_ptr); } /* Perform a lookup on value contained in "ip" */ GENERIC sfrt_flat_lookup(sfaddr_t *ip, table_flat_t *table) { tuple_flat_t tuple; uint32_t* adr; int numAdrDwords; INFO *data; TABLE_PTR rt; uint8_t *base; if(!ip) { return NULL; } if(!table) { return NULL; } if (sfaddr_family(ip) == AF_INET) { adr = sfaddr_get_ip4_ptr(ip); numAdrDwords = 1; rt = table->rt; } else { adr = sfaddr_get_ip6_ptr(ip); numAdrDwords = 4; rt = table->rt6; } tuple = sfrt_dir_flat_lookup(adr, numAdrDwords, rt); if(tuple.index >= table->num_ent) { return NULL; } base = (uint8_t *)segment_basePtr(); data = (INFO *)(&base[table->data]); if (data[tuple.index]) return (GENERIC) &base[data[tuple.index]]; else return NULL; } /* Insert "ip", of length "len", into "table", and have it point to "ptr" */ /* Insert "ip", of length "len", into "table", and have it point to "ptr" */ int sfrt_flat_insert(sfcidr_t *ip, unsigned char len, INFO ptr, int behavior, table_flat_t* table, updateEntryInfoFunc updateEntry) { int index; int res = RT_SUCCESS; INFO *data; tuple_flat_t tuple; uint32_t* adr; int numAdrDwords; TABLE_PTR rt; uint8_t *base; int64_t bytesAllocated; if(!ip) { return RT_INSERT_FAILURE; } if (len == 0) return RT_INSERT_FAILURE; if(!table || !table->data) { return RT_INSERT_FAILURE; } if(len > 128) { return RT_INSERT_FAILURE; } if (sfaddr_family(&ip->addr) == AF_INET) { if (len < 96) { return RT_INSERT_FAILURE; } len -= 96; adr = sfip_get_ip4_ptr(ip); numAdrDwords = 1; rt = table->rt; } else { adr = sfip_get_ip6_ptr(ip); numAdrDwords = 4; rt = table->rt6; } tuple = sfrt_dir_flat_lookup(adr, numAdrDwords, rt); base = (uint8_t *)segment_basePtr(); data = (INFO *)(&base[table->data]); if(tuple.length != len) { if( table->num_ent >= table->max_size) { return RT_POLICY_TABLE_EXCEEDED; } index = table->num_ent; table->num_ent++; /* Insert value into policy table */ data[index] = 0; } else { index = tuple.index; } bytesAllocated = updateEntry(&data[index], ptr, SAVE_TO_CURRENT, base); if (bytesAllocated < 0) { if(tuple.length != len) table->num_ent--; return MEM_ALLOC_FAILURE; } table->allocated += (uint32_t)bytesAllocated; /* The actual value that is looked-up is an index * into the data table. */ res = sfrt_dir_flat_insert(adr, numAdrDwords, len, index, behavior, rt, updateEntry, data); /* Check if we ran out of memory. If so, need to decrement * table->num_ent */ if(res == MEM_ALLOC_FAILURE) { /* From the control flow above, it's possible table->num_ent was not * incremented. It should be safe to decrement here, because the only * time it will be incremented above is when we are potentially * mallocing one or more new entries (It's not incremented when we * overwrite an existing entry). */ table->num_ent--; } return res; } uint32_t sfrt_flat_num_entries(table_flat_t* table) { if(!table) { return 0; } if( !table->rt || !table->allocated) { return 0; } /* There is always a root node, so subtract 1 for it */ return table->num_ent - 1; } uint32_t sfrt_flat_usage(table_flat_t *table) { uint32_t usage; if(!table || !table->rt || !table->allocated ) { return 0; } usage = table->allocated + sfrt_dir_flat_usage( table->rt ); if (table->rt6) { usage += sfrt_dir_flat_usage( table->rt6 ); } return usage; } snort-2.9.15.1/src/sfutil/sfrt_flat.h0000644000175200017520000001763613571422607014317 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2011-2013 Sourcefire, Inc. ** ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** ** 9/7/2011 - Initial implementation ... Hui Cao ** ** This is based on the original sfrt.h, but using the flat segment memory. ** When allocating memory, it uses memory in the segment, and returns ** the offset. ** When accessing memory, it must use the base address and offset to ** correctly refer to it. */ #ifndef _SFRT_FLAT_H_ #define _SFRT_FLAT_H_ #include #include #include "snort_debug.h" #include "ipv6_port.h" #include "segment_mem.h" typedef MEM_OFFSET INFO; /* To be replaced with a pointer to a policy */ typedef MEM_OFFSET FLAT_INDEX; typedef MEM_OFFSET TABLE_PTR; typedef enum { SAVE_TO_NEW, SAVE_TO_CURRENT }SaveDest; typedef int64_t (*updateEntryInfoFunc)(INFO *entryInfo, INFO newInfo, SaveDest saveDest, uint8_t *base); typedef struct { FLAT_INDEX index; int length; } tuple_flat_t; #include "sfrt_flat_dir.h" /*******************************************************************/ /* Master table struct. Abstracts DIR and LC-trie methods */ typedef struct { uint32_t num_ent; /* Number of entries in the policy table */ uint32_t max_size; /* Max size of policies array */ char ip_type; /* Only IPs of this family will be used */ char table_flat_type; char mem_type; uint32_t allocated; INFO data; /* data table. Each IP points to an entry here */ TABLE_PTR rt; /* Actual "routing" table */ TABLE_PTR rt6; /* Actual "routing" table */ TABLE_PTR list_info; /* List file information table (entry information)*/ } table_flat_t; /*******************************************************************/ /* Abstracted routing table API */ table_flat_t * sfrt_flat_new(char table_flat_type, char ip_type, long data_size, uint32_t mem_cap); void sfrt_flat_free(TABLE_PTR table); GENERIC sfrt_flat_lookup(sfaddr_t *ip, table_flat_t *table); int sfrt_flat_insert(sfcidr_t *ip, unsigned char len, INFO ptr, int behavior, table_flat_t *table, updateEntryInfoFunc updateEntry); uint32_t sfrt_flat_usage(table_flat_t *table); uint32_t sfrt_flat_num_entries(table_flat_t *table); /* Perform a lookup on value contained in "ip" * For performance reason, we use this simplified version instead of sfrt_lookup * Note: this only applied to table setting: DIR_8x16 (DIR_16_8_4x2 for IPV4), DIR_8x4*/ static inline GENERIC sfrt_flat_dir8x_lookup(sfaddr_t *ip, table_flat_t* table) { dir_sub_table_flat_t *subtable; Entry_Value *entries_value; Entry_Len *entries_length; uint8_t *base = (uint8_t *) table; int i; dir_table_flat_t *rt = NULL; int index; INFO *data = (INFO *) (&base[table->data]); if (sfaddr_family(ip) == AF_INET) { rt = (dir_table_flat_t *)(&base[table->rt]); subtable = (dir_sub_table_flat_t *)(&base[rt->sub_table]); /* 16 bits */ index = ntohs(ip->ia16[6]); entries_value = (Entry_Value *)(&base[subtable->entries_value]); entries_length = (Entry_Len *)(&base[subtable->entries_length]); if( !entries_value[index] || entries_length[index] ) { if (data[entries_value[index]]) return (GENERIC) &base[data[entries_value[index]]]; else return NULL; } subtable = (dir_sub_table_flat_t *)(&base[entries_value[index]]); /* 4 bits */ index = ip->ia8[14] >> 4; entries_value = (Entry_Value *)(&base[subtable->entries_value]); entries_length = (Entry_Len *)(&base[subtable->entries_length]); if ( !entries_value[index] || entries_length[index] ) { if ( data[entries_value[index]] ) return (GENERIC) &base[data[entries_value[index]]]; else return NULL; } subtable = (dir_sub_table_flat_t *)(&base[entries_value[index]]); /* 4 bits */ index = ip->ia8[14] & 0xF; entries_value = (Entry_Value *)(&base[subtable->entries_value]); entries_length = (Entry_Len *)(&base[subtable->entries_length]); if( !entries_value[index] || entries_length[index] ) { if ( data[entries_value[index]] ) return (GENERIC) &base[data[entries_value[index]]]; else return NULL; } subtable = (dir_sub_table_flat_t *)(&base[entries_value[index]]); /* 2 bits */ index = ip->ia8[15] >> 6; entries_value = (Entry_Value *)(&base[subtable->entries_value]); entries_length = (Entry_Len *)(&base[subtable->entries_length]); if( !entries_value[index] || entries_length[index] ) { if ( data[entries_value[index]] ) return (GENERIC) &base[data[entries_value[index]]]; else return NULL; } subtable = (dir_sub_table_flat_t *)(&base[entries_value[index]]); /* 2 bits */ index = (ip->ia8[15] >> 4) & 0x3; entries_value = (Entry_Value *)(&base[subtable->entries_value]); entries_length = (Entry_Len *)(&base[subtable->entries_length]); if( !entries_value[index] || entries_length[index] ) { if ( data[entries_value[index]] ) return (GENERIC) &base[data[entries_value[index]]]; else return NULL; } subtable = (dir_sub_table_flat_t *)(&base[entries_value[index]]); /* 2 bits */ index = (ip->ia8[15] >> 2) & 0x3; entries_value = (Entry_Value *)(&base[subtable->entries_value]); entries_length = (Entry_Len *)(&base[subtable->entries_length]); if( !entries_value[index] || entries_length[index] ) { if ( data[entries_value[index]] ) return (GENERIC) &base[data[entries_value[index]]]; else return NULL; } subtable = (dir_sub_table_flat_t *)(&base[entries_value[index]]); /* 2 bits */ index = ip->ia8[15] & 0x3; entries_value = (Entry_Value *)(&base[subtable->entries_value]); entries_length = (Entry_Len *)(&base[subtable->entries_length]); if( !entries_value[index] || entries_length[index] ) { if ( data[entries_value[index]] ) return (GENERIC) &base[data[entries_value[index]]]; else return NULL; } } else { rt = (dir_table_flat_t *)(&base[table->rt6]); subtable = (dir_sub_table_flat_t *)(&base[rt->sub_table]); for (i = 0; i < 16; i++) { index = ip->ia8[i]; entries_value = (Entry_Value *)(&base[subtable->entries_value]); entries_length = (Entry_Len *)(&base[subtable->entries_length]); if( !entries_value[index] || entries_length[index] ) { if ( data[entries_value[index]] ) return (GENERIC) &base[data[entries_value[index]]]; else return NULL; } subtable = (dir_sub_table_flat_t *)(&base[entries_value[index]]); } } return NULL; } #endif snort-2.9.15.1/src/sfutil/sfrt_flat_dir.c0000644000175200017520000004562213571422607015144 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2011-2013 Sourcefire, Inc. ** ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** ** 9/7/2011 - Initial implementation ... Hui Cao */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include /* For variadic */ #include #include /* For memset */ #include "sf_types.h" #include "sfrt_flat.h" #include "sfrt_flat_dir.h" #if SIZEOF_UNSIGNED_LONG_INT == 8 #define ARCH_WIDTH 64 #else #define ARCH_WIDTH 32 #endif typedef struct { uint32_t* adr; int bits; } IPLOOKUP; /* Create new "sub" table of 2^width entries */ static TABLE_PTR _sub_table_flat_new(dir_table_flat_t *root, uint32_t dimension, uint32_t prefill, uint32_t bit_length) { int width = root->dimensions[dimension]; int len = 1 << width; int index; dir_sub_table_flat_t *sub; TABLE_PTR sub_ptr; uint8_t *base; Entry_Value *entries_value; Entry_Len *entries_length; /* Check if creating this node will exceed the memory cap. * The symbols in the conditional (other than cap), come from the * allocs below. */ if( root->mem_cap < ( root->allocated + sizeof(dir_sub_table_flat_t) + sizeof(Entry_Value) * len + sizeof(Entry_Len) * len) || bit_length > 128) { return 0; } /* Set up the initial prefilled "sub table" */ sub_ptr = segment_malloc(sizeof(dir_sub_table_flat_t)); if(!sub_ptr) { return 0; } base = (uint8_t *)segment_basePtr(); sub = (dir_sub_table_flat_t *)(&base[sub_ptr]); /* This keeps the width readily available rather than recalculating it * from the number of entries during an insert or lookup */ sub->width = width; /* need 2^sub->width entries */ /* A "length" needs to be stored with each entry above. The length refers * to how specific the insertion that set the entry was. It is necessary * so that the entry is not overwritten by less general routing * information if "RT_FAVOR_SPECIFIC" insertions are being performed. */ sub->entries_value = segment_malloc(sizeof(MEM_OFFSET) * len); if(!sub->entries_value) { segment_free(sub_ptr); return 0; } sub->entries_length = segment_malloc(sizeof(Entry_Len) * len); if(!sub->entries_length) { segment_free(sub_ptr); return 0; } entries_value = (Entry_Value *)(&base[sub->entries_value]); entries_length = (Entry_Len *)(&base[sub->entries_length]); /* Can't use memset here since prefill is multibyte */ for(index = 0; index < len; index++) { entries_value[index] = prefill; entries_length[index] = (uint8_t)bit_length; } root->allocated += sizeof(dir_sub_table_flat_t) + sizeof(Entry_Value) * len + sizeof(Entry_Len) * len; root->cur_num++; return sub_ptr; } /* Create new dir-n-m root table with 'count' depth */ TABLE_PTR sfrt_dir_flat_new(uint32_t mem_cap, int count,...) { va_list ap; uint32_t val; int index; TABLE_PTR table_ptr; dir_table_flat_t* table; uint8_t *base; table_ptr = segment_malloc(sizeof(dir_table_flat_t)); if(!table_ptr) { return 0; } base = (uint8_t *)segment_basePtr(); table = (dir_table_flat_t *)(&base[table_ptr]); table->allocated = 0; table->dim_size = count; va_start(ap, count); for(index=0; index < count; index++) { val = va_arg(ap, int); table->dimensions[index] = val; } va_end(ap); table->mem_cap = mem_cap; table->cur_num = 0; table->sub_table = _sub_table_flat_new(table, 0, 0, 0); if(!table->sub_table) { segment_free(table_ptr); return 0; } table->allocated += sizeof(dir_table_flat_t) + sizeof(int)*count; return table_ptr; } /* Traverse "sub" tables, freeing each */ static void _sub_table_flat_free(uint32_t *allocated, SUB_TABLE_PTR sub_ptr) { int index; dir_sub_table_flat_t *sub; uint8_t *base; int len; base = (uint8_t *)segment_basePtr(); sub = (dir_sub_table_flat_t *)(&base[sub_ptr]); len = 1 << sub->width; for(index=0; index < len; index++) { /* The following condition will only be true if * this entry is a pointer */ Entry_Value *entries_value = (Entry_Value *)(&base[sub->entries_value]); Entry_Len *entries_length = (Entry_Len *)(&base[sub->entries_length]); if( !entries_value[index] && entries_length[index] ) { _sub_table_flat_free( allocated, entries_value[index] ); } } if(sub->entries_value) { /* This probably does not need to be checked * since if it was not allocated, we would have errored out * in _sub_table_flat_new */ segment_free(sub->entries_value); *allocated -= sizeof(Entry_Value) * len; } if(sub->entries_length) { /* This probably does not need to be checked * since if it was not allocated, we would have errored out * in _sub_table_flat_new */ segment_free(sub->entries_length); *allocated -= sizeof(Entry_Len) * len; } segment_free(sub_ptr); *allocated -= sizeof(dir_sub_table_flat_t); } /* Free the DIR-n-m structure */ void sfrt_dir_flat_free(TABLE_PTR tbl_ptr) { dir_table_flat_t *table; uint8_t *base; if(!tbl_ptr) { return; } base = (uint8_t *)segment_basePtr(); table = (dir_table_flat_t *)(&base[tbl_ptr]); if(table->sub_table) { _sub_table_flat_free(&table->allocated, table->sub_table); } segment_free(tbl_ptr); } static inline void _dir_fill_all(uint32_t *allocated, uint32_t index, uint32_t fill, word length, uint32_t val, SUB_TABLE_PTR sub_ptr) { dir_sub_table_flat_t *subtable; uint8_t *base; base = (uint8_t *)segment_basePtr(); subtable = (dir_sub_table_flat_t *)(&base[sub_ptr]); /* Fill entries */ for(; index < fill; index++) { /* Before overwriting this entry, verify there's not an existing * pointer ... otherwise free it to avoid a huge memory leak. */ Entry_Value *entries_value = (Entry_Value *)(&base[subtable->entries_value]); Entry_Len *entries_length = (Entry_Len *)(&base[subtable->entries_length]); if( entries_value[index] && !entries_length[index] ) { _sub_table_flat_free(allocated, entries_value[index]); } entries_value[index] = val; entries_length[index] = (uint8_t)length; } } static inline void _dir_fill_less_specific(int index, int fill, word length, uint32_t val, SUB_TABLE_PTR sub_ptr) { dir_sub_table_flat_t *subtable; uint8_t *base; base = (uint8_t *)segment_basePtr(); subtable = (dir_sub_table_flat_t *)(&base[sub_ptr]); /* Fill entries */ for(; index < fill; index++) { /* If we encounter a pointer, and we're inserting at this level, we * automatically know that this entry refers to more specific * information. However, there might only be one more specific entry * in the entire block, meaning the rest must be filled. * * For instance, imagine a 24-8 with 1.2.3/24 -> A and 1.2.3.4/32 -> B * There will be a pointer at 1.2.3 in the first table. The second * table needs to have 255 entries pointing A, and 1 entry pointing to * B. * * Therefore, recurse to this next level. */ Entry_Value *entries_value = (Entry_Value *)(&base[subtable->entries_value]); Entry_Len *entries_length = (Entry_Len *)(&base[subtable->entries_length]); if( entries_value[index] && !entries_length[index] ) { dir_sub_table_flat_t *next = (dir_sub_table_flat_t*)(&base[entries_value[index]]); _dir_fill_less_specific(0, 1 << next->width, length, val, entries_value[index]); } else if(length >= (unsigned)entries_length[index]) { entries_value[index] = val; entries_length[index] = (char)length; } } } static inline int64_t _dir_update_info(int index, int fill, word length, uint32_t val, SUB_TABLE_PTR sub_ptr, updateEntryInfoFunc updateEntry, INFO *data) { dir_sub_table_flat_t *subtable; uint8_t *base; int64_t bytesAllocatedTotal = 0; base = (uint8_t *)segment_basePtr(); subtable = (dir_sub_table_flat_t *)(&base[sub_ptr]); /* Fill entries */ for(; index < fill; index++) { /* If we encounter a pointer, and we're inserting at this level, we * automatically know that this entry refers to more specific * information. However, there might only be one more specific entry * in the entire block, meaning the rest must be filled. * * For instance, imagine a 24-8 with 1.2.3/24 -> A and 1.2.3.4/32 -> B * There will be a pointer at 1.2.3 in the first table. The second * table needs to have 255 entries pointing A, and 1 entry pointing to * B. * * Therefore, recurse to this next level. */ Entry_Value *entries_value = (Entry_Value *)(&base[subtable->entries_value]); Entry_Len *entries_length = (Entry_Len *)(&base[subtable->entries_length]); if( entries_value[index] && !entries_length[index] ) { int64_t bytesAllocated; dir_sub_table_flat_t *next = (dir_sub_table_flat_t*)(&base[entries_value[index]]); bytesAllocated = _dir_update_info(0, 1 << next->width, length, val, entries_value[index], updateEntry, data); if (bytesAllocated < 0) return bytesAllocated; else bytesAllocatedTotal += bytesAllocated; } else if(length > (unsigned)entries_length[index]) { if(entries_value[index]) { int64_t bytesAllocated; bytesAllocated = updateEntry(&data[entries_value[index]], data[val], SAVE_TO_NEW, base); if (bytesAllocated < 0) return bytesAllocated; else bytesAllocatedTotal += bytesAllocated; } entries_value[index] = val; entries_length[index] = (uint8_t)length; } else if(entries_value[index]) { int64_t bytesAllocated; bytesAllocated = updateEntry(&data[entries_value[index]], data[val], SAVE_TO_CURRENT, base); if (bytesAllocated < 0) return bytesAllocated; else bytesAllocatedTotal += bytesAllocated; } } return bytesAllocatedTotal; } /* Sub table insertion * This is called by dir_insert and recursively to find the the sub table * that should house the value "ptr" * @param ip IP address structure * @param cur_len Number of bits of the IP left at this depth * @param length Number of bits of the IP used to specify this CIDR * @param ptr Information to be associated with this IP range * @param master_table The table that describes all, returned by dir_new */ static int _dir_sub_insert(IPLOOKUP *ip, int length, int cur_len, INFO ptr, int current_depth, int behavior, SUB_TABLE_PTR sub_ptr, dir_table_flat_t *root_table,updateEntryInfoFunc updateEntry, INFO *data) { word index; uint32_t fill; uint8_t *base = (uint8_t *)segment_basePtr(); dir_sub_table_flat_t *sub_table = (dir_sub_table_flat_t *)(&base[sub_ptr]); { uint32_t local_index, i; /* need to handle bits usage across multiple 32bit vals within IPv6. */ if (ip->bits < 32 ) { i=0; } else if (ip->bits < 64) { i=1; } else if (ip->bits < 96) { i=2; } else { i=3; } local_index = ip->adr[i] << (ip->bits %32); index = local_index >> (sizeof(local_index)*8 - sub_table->width); } /* Check if this is the last table to traverse to */ if(sub_table->width >= cur_len) { /* Calculate how many entries need to be filled * in this table. If the table is 24 bits wide, and the entry * is 20 bytes long, 2^4 entries need to be filled. */ fill = 1 << (sub_table->width - cur_len); index = (index >> (sub_table->width - cur_len)) << (sub_table->width - cur_len); fill += index; /* Favor most recent CIDR */ if(behavior == RT_FAVOR_TIME) { _dir_fill_all(&root_table->allocated, index, fill, length, (word)ptr, sub_ptr); } /* Fill over less specific CIDR */ else if (behavior == RT_FAVOR_SPECIFIC) { _dir_fill_less_specific(index, fill, length, (word)ptr, sub_ptr); } else if (behavior == RT_FAVOR_ALL) { int64_t bytesAllocated; bytesAllocated = _dir_update_info(index, fill, length, (word)ptr, sub_ptr, updateEntry, data); if (bytesAllocated < 0) return MEM_ALLOC_FAILURE; root_table->allocated += (uint32_t)bytesAllocated; if( root_table->mem_cap < root_table->allocated) return MEM_ALLOC_FAILURE; } } /* Need to traverse to a sub-table */ else { Entry_Value *entries_value = (Entry_Value *)(&base[sub_table->entries_value]); Entry_Len *entries_length = (Entry_Len *)(&base[sub_table->entries_length]); /* Check if we need to alloc a new sub table. * If next_sub was 0/NULL, there's no entry at this index * If the length is non-zero, there is an entry */ if(!entries_value[index] || entries_length[index]) { if( root_table->dim_size <= current_depth ) { return RT_INSERT_FAILURE; } entries_value[index] = (word) _sub_table_flat_new(root_table, current_depth+1, (word) entries_value[index], entries_length[index]); entries_length[index] = 0; if(!entries_value[index]) { return MEM_ALLOC_FAILURE; } } /* Recurse to next level. Rightshift off appropriate number of * bits and update the length accordingly. */ ip->bits += sub_table->width; return (_dir_sub_insert(ip, length, cur_len - sub_table->width, ptr, current_depth+1, behavior, entries_value[index], root_table, updateEntry, data)); } return RT_SUCCESS; } /* Insert entry into DIR-n-m tables * @param ip IP address structure * @param len Number of bits of the IP used for lookup * @param ptr Information to be associated with this IP range * @param master_table The table that describes all, returned by dir_new */ int sfrt_dir_flat_insert(uint32_t* adr, int numAdrDwords, int len, word data_index, int behavior, TABLE_PTR table_ptr, updateEntryInfoFunc updateEntry, INFO *data) { dir_table_flat_t *root; uint8_t *base; uint32_t h_adr[4]; IPLOOKUP iplu; iplu.adr = h_adr; iplu.bits = 0; base = (uint8_t *)segment_basePtr(); root = (dir_table_flat_t *)(&base[table_ptr]); /* Validate arguments */ if(!root || !root->sub_table) { return DIR_INSERT_FAILURE; } h_adr[0] = ntohl(adr[0]); if (len > 96) { h_adr[1] = ntohl(adr[1]); h_adr[2] = ntohl(adr[2]); h_adr[3] = ntohl(adr[3]); } else if (len > 64) { h_adr[1] = ntohl(adr[1]); h_adr[2] = ntohl(adr[2]); } else if (len > 32) { h_adr[1] = ntohl(adr[1]); } /* Find the sub table in which to insert */ return _dir_sub_insert(&iplu, len, len, data_index, 0, behavior, root->sub_table, root, updateEntry, data); } /* Traverse sub tables looking for match */ /* Called by dir_lookup and recursively */ static tuple_flat_t _dir_sub_flat_lookup(IPLOOKUP *ip, TABLE_PTR table_ptr) { word index; uint8_t *base = (uint8_t *)segment_basePtr(); Entry_Value *entries_value; Entry_Len *entries_length; dir_sub_table_flat_t *table = (dir_sub_table_flat_t *)(&base[table_ptr]); { uint32_t local_index, i; /* need to handle bits usage across multiple 32bit vals within IPv6. */ if (ip->bits < 32 ) { i=0; } else if (ip->bits < 64) { i=1; } else if (ip->bits < 96) { i=2; } else { i=3; } local_index = ip->adr[i] << (ip->bits %32); index = local_index >> (sizeof(local_index)*8 - table->width); } entries_value = (Entry_Value *)(&base[table->entries_value]); entries_length = (Entry_Len *)(&base[table->entries_length]); if( !entries_value[index] || entries_length[index] ) { tuple_flat_t ret; ret.index = entries_value[index]; ret.length = (word)entries_length[index]; return ret; } ip->bits += table->width; return _dir_sub_flat_lookup( ip, entries_value[index] ); } /* Lookup information associated with the value "ip" */ tuple_flat_t sfrt_dir_flat_lookup(uint32_t* adr, int numAdrDwords, TABLE_PTR table_ptr) { dir_table_flat_t *root; uint8_t *base = (uint8_t *)segment_basePtr(); uint32_t h_adr[4]; int i; IPLOOKUP iplu; iplu.adr = h_adr; iplu.bits = 0; if(!table_ptr ) { tuple_flat_t ret = { 0, 0 }; return ret; } root = (dir_table_flat_t *)(&base[table_ptr]); if(!root->sub_table) { tuple_flat_t ret = { 0, 0 }; return ret; } for (i = 0; i < numAdrDwords; i++) { h_adr[i] = ntohl(adr[i]); } return _dir_sub_flat_lookup(&iplu, root->sub_table); } uint32_t sfrt_dir_flat_usage(TABLE_PTR table_ptr) { dir_table_flat_t *table; uint8_t *base; if(!table_ptr) { return 0; } base = (uint8_t *)segment_basePtr(); table = (dir_table_flat_t *)(&base[table_ptr]); return ((dir_table_flat_t*)(table))->allocated; } snort-2.9.15.1/src/sfutil/sfrt_flat_dir.h0000644000175200017520000000540413571422607015143 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2011-2013 Sourcefire, Inc. ** ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** ** 9/7/2011 - Initial implementation ... Hui Cao */ #ifndef SFRT_DIR_FLAT_H_ #define SFRT_DIR_FLAT_H_ #include "sfrt.h" typedef MEM_OFFSET SUB_TABLE_PTR; typedef MEM_OFFSET ENTRIES_PTR; typedef uint8_t Entry_Len; typedef MEM_OFFSET Entry_Value; /*******************************************************************/ /* DIR-n-m data structures * Each table in the DIR-n-m method is represented by a * dir_sub_table_t. They are managed by a dir_table_t. */ typedef struct { int16_t width; /* width of this table. */ ENTRIES_PTR entries_value; ENTRIES_PTR entries_length; } dir_sub_table_flat_t; /* Master data structure for the DIR-n-m derivative */ typedef struct { int dimensions[20]; /* DIR-n-m will consist of any number of arbitrarily * long tables. This variable keeps track of the * dimensions */ int dim_size; /* And this variable keeps track of 'dimensions''s * dimensions! */ uint32_t mem_cap; /* User-defined maximum memory that can be allocated * for the DIR-n-m derivative */ int cur_num; /* Present number of used nodes */ uint32_t allocated; SUB_TABLE_PTR sub_table; } dir_table_flat_t; /*******************************************************************/ /* DIR-n-m functions, these are not intended to be called directly */ TABLE_PTR sfrt_dir_flat_new(uint32_t mem_cap, int count,...); void sfrt_dir_flat_free(TABLE_PTR); tuple_flat_t sfrt_dir_flat_lookup(uint32_t* adr, int numAdrDwords, TABLE_PTR table); int sfrt_dir_flat_insert(uint32_t* adr, int numAdrDwords, int len, word data_index, int behavior, TABLE_PTR, updateEntryInfoFunc updateEntry, INFO *data); uint32_t sfrt_dir_flat_usage(TABLE_PTR); #endif /* SFRT_DIR_FLAT_H_ */ snort-2.9.15.1/src/sfutil/segment_mem.c0000644000175200017520000000664713571422607014626 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2011-2013 Sourcefire, Inc. ** ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** ** 8/7/2011 - Initial implementation ... Hui Cao */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "segment_mem.h" /*point to the start of the unused memory*/ static MEM_OFFSET unused_ptr = 0; static size_t unused_mem = 0; static void *base_ptr = NULL; size_t segment_unusedmem(void) { return unused_mem; } /*************************************************************************** * Initialize the segment memory * Return values: * 1: success * 0: fail **************************************************************************/ int segment_meminit(uint8_t* buff, size_t mem_cap) { base_ptr = buff; unused_ptr = 0; unused_mem = mem_cap; return 1; } /*************************************************************************** * allocate memory block from segment * todo:currently, we only allocate memory continuously. Need to reuse freed * memory in the future. * return: * 0: fail * other: the offset of the allocated memory block **************************************************************************/ MEM_OFFSET segment_malloc ( size_t size ) { MEM_OFFSET current_ptr = unused_ptr; if (unused_mem < size) return 0; unused_ptr += size; unused_mem -= size; return current_ptr; } /*************************************************************************** * Free memory block from segment * Todo: currently, no action for free. Need to reuse freed memory in the * future. **************************************************************************/ void segment_free ( MEM_OFFSET ptr ) { return; } /*************************************************************************** * allocate memory block from segment and initialize it to zero * It calls segment_malloc() to get memory. * todo:currently, we only allocate memory continuously. Need to reuse freed * memory in the future. * return: * 0: fail * other: the offset of the allocated memory block **************************************************************************/ MEM_OFFSET segment_calloc ( size_t num, size_t size ) { MEM_OFFSET current_ptr; size_t total; if ((0 == size)||(0 == num)) return 0; /*Check possible overflow*/ if (num > SIZE_MAX/size) return 0; total = num * size; current_ptr = segment_malloc(total); if (0 != current_ptr) memset((uint8_t *)base_ptr + current_ptr, 0, total); return current_ptr; } void * segment_basePtr() { return base_ptr; } snort-2.9.15.1/src/sfutil/segment_mem.h0000644000175200017520000000252513571422607014622 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2011-2013 Sourcefire, Inc. ** ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** ** 8/7/2011 - Initial implementation ... Hui Cao */ #ifndef _SFSHARE_MEMEORY_H_ #define _SFSHARE_MEMEORY_H_ #include #include "sf_types.h" typedef uint32_t MEM_OFFSET; int segment_meminit(uint8_t*, size_t); MEM_OFFSET segment_malloc ( size_t size ); void segment_free (MEM_OFFSET ptr ); MEM_OFFSET segment_calloc ( size_t num, size_t size ); size_t segment_unusedmem(); void * segment_basePtr(); #endif snort-2.9.15.1/src/sfutil/sfportobject.c0000644000175200017520000030257713571422607015033 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2005-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* sfportobject.c author: marc norton date: 11/05/2005 description: Port objects provides support for generic ports lists comprised of individual ports, port ranges, and negation of ports and port ranges. Port lists require a somewhat more complex scheme to determine the proper grouping of rules for each port while minimizing the number of rule groups created. We can use a single group of rules in the multi-pattern detection phase, however that can have a huge impact on performance. Instead we try to create a smaller grouping of rules that might be applicable to each port. As rules are defined using port ranges, and port lists there will be port overlapps between rules. This requires us to determine whether we should create one larger rule group to apply to all relevant ports, or to create multiple rule groups and apply the smallest applicable one to each port. In practice snort has some rules which span almost all 64K ports which might cause all rules in all port-rule groups to be merged into one set unless we apply a more complex logic than simply merging rule-port groups with common ports. This is the problem addressed by the sfportobject module. port list examples of acceptable usage: - var has been overloaded, if it includes _port we add as a port-object also. var http_ports 80 var http_range_ports 80:81 var http_list_ports [80,8080,8138] - portvar has been added to indicate portvariables, this form does not require _port portvar http 80 portvar http_range 80:81 portvar http_list [80,8080,8138] 80 $http !90 80:81 $http_range !90:91 [80,8080,8138] $http_list [$http,$http_list] [2001,2008,20022,8100:8150,!8121,!8123] [!any] - uhhh, why do people ask about this ? Rules are defined using a port, a port-range or a list of these, we call these port objects. As rules are loaded we generate some large rule counts on some ports, and small rule counts on most ports. If for each port you build a list of rules on that port, we may end up with some ports with a large rule set that differs by the addition of a few rules on each port (relative to the group sizes) we don't want to generate compeletely different rule groups for these as that would than generate multiple large state machines for the multi-pattern matching phase of the detection engine which in turn could use a lot of memory. It turns out that one scheme, the one used herein, provides some blending of rule groups to minimize memory, and tries to minimize large group sizes to keep performance more optimal - although this is at the expense of memory. --- Port variables Var - has been overloaded. If it's name includes _port as part of the var name it is added to the PortVarTable. PortVar - has been added. These are always added to the PortVarTable. --- Loading Port lists and rules PortTables - we support src and dst tables for tcp/udp/icmp/ip/arp rules. PortVar References - we dup the PortVar entries as needed into each table if referenced, so HTTP_PORTS for tcp and udp contain different rules. If a rule references a PortVar we look it up in the table, if its not present we dup it from the PortVarTable, otherwise we just add the rule index to the PortVar HTTP_PORTS in the proper table. If a PortVar is not used to specify a Port entry in a rule we create a temp port-object, and check if it's port-list is already in the table. If it's not we make the temp port-object the permanent entry in the table. If it is, we just add the rule index to the existing entry, and delete the temp port-object. When the rules are done loading we should have a set of port-objects with port-lists that differ by at least one port. The next step handles the cases where we have multiple port-objects with at least one common port. --- Merging Ports and Rules We maintain for each port a list of port objects and their rules that apply to it. This allows us to view combining the rules associated with each port object using a few heuristics. A list of port objects applicable to each port presents rules in one of four catagories: 1) a single port object, and all rules associated with it. 2) multiple port objects each with a small set of rules associated with it. 3) one port object with a large rule set, and one or more port objects with a small set of rules associated with each. 4) multiple port objects with large rule sets, and zero or more port objects each with a small set of rules associated with it. We process these four categories as follows: 1) -a single port object (large or small) do nothing, each port referencing this port object is complete. 2) -multiple small port objects merge the rules for all port objects into one virtual object, for each port in this category lookup it's combined port object to see if it's already defined, if not create one. This way all ports that have the same port groups point to the same virtual port object. 3) -one large port object, and one or more small port objects add the small rule groups into the large rule set, using the existing port object. 4) -multiple large port objects and zero or more small port objects merge the large port objects into a virtual port object and add all rules from both large and small sets into it's rule set. we use the combined large group ports to form a key, so any ports referencing just these large rule groups, and some small ones will be recognized as the same. This handles cases where we have 2,3,4.etc large rule groups combined. Any time we see a 'n' grouping of the same large rule sets we'll look it up and point to it for that port. To determine when a port object has a large rule set or a small one we use a simple threshold value. In theory the larger this value is the more merging of rules in category 2 and 3 will occur. When this value is small category 4 should become a more prevalent situation. However, the behavior of groupings for a given threshold can change as more rules are added to port groups. Therefore generous statistics are printed after the rules and port objects are compiled into their final groupings. Procedure for using PortLists 1) Process Var's as PortVar's and standard Var's (for now). This allows existing snort features to work, with the Var's. Add in the PortVar support to parse the Var input into PortObjects, and add these to the PortVartable. 2) Read Rules a) Read port numbers and lists 1) Dereference PortVar/Var Names if any are referenced. b) Create a Port Object c) Test if this Port object exists already, 1) If so, add the sid to it. 2) If not add it .... Notes: All any-any port rules are managed separately, and added in to the final rules lists of each port group after this analysis. Rules defined with ranges are no longer considered any-any rules for the purpose of organizing port-rule groupings. This should help prevent some cross fertilization of rule groups with rules that are unneccessary, this causes rule group sizes to bloat and performance to slow. Hierarchy: PortTable -> PortObject's PortVar -> PortObject ( These are pure, and are dup'ed for use in the PortTables ) PortObject -> PortObjectItems (port or port range) */ #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sf_types.h" #include "snort.h" #include "snort_bounds.h" #include "snort_debug.h" #include "sfportobject.h" #include "sfrim.h" #include "util.h" #define PO_EXTRA_RULE_CNT 25 #define PTBL_LRC_DEFAULT 10 #define PO_INIT_ID 1000000 #define PO_HASH_TBL_ROWS 10000 /* Hash Key Comparisons for treating PortObjects as Keys return values memcmp style */ static int PortObject_keycmp( const void *a , const void *b, size_t n ) { #ifdef WIN32 n = n; #endif return !PortObjectEqual( *(PortObject**)a, *(PortObject**)b ); } /* * plx_t is a variable sized array of pointers */ typedef struct { int n; void ** p; }plx_t; static plx_t * plx_new( void * pv_array[], int n ) { plx_t * p; int i; if(!pv_array || n < 0) return NULL; p = SnortAlloc(sizeof(plx_t)); p->p = SnortAlloc(n * sizeof(void*)); p->n = n; for(i=0;ip[i] = pv_array[i]; } return p; } static void plx_free(void * p ) { plx_t * plx=(plx_t*)p; if( !plx ) return; if( plx->p ) free(plx->p); free( p ); } #ifdef DEBUG_MSGS static void plx_print(plx_t * p) { DEBUG_WRAP( int i; DebugMessage(DEBUG_PORTLISTS, "plx-n=%d\n", p->n); for(i=0;in;i++) DebugMessage(DEBUG_PORTLISTS, "plx[%d]=%lu\n", i, p->p[i]); ); } #endif /* * hash function for plx_t types */ static unsigned plx_hash( SFHASHFCN * p, unsigned char *d, int n ) { unsigned k, hash = p->seed; int i; plx_t* plx; #ifdef WIN32 n = n; /* To silence a Win32 warning */ #endif plx = *(plx_t**)d; for(i=0;in;i++) { unsigned char * pc_ptr = (unsigned char*)&plx->p[i]; for(k=0;kscale; hash += pc_ptr[k]; } } return hash ^ p->hardener; } /* for sorting an array of pointers */ static inline int p_keycmp( const void *a , const void *b ) { if( *(unsigned long**)a < *(unsigned long**)b ) return -1; if( *(unsigned long**)a > *(unsigned long**)b ) return 1; return 0; /* they are equal */ } /* Hash Key Comparisons for treating plx_t types as Keys return values memcmp style this only needs to produce 0 => exact match, otherwise not. -1, and +1 are not strictly needed, they could both return a non zero value for the purposes of hashing and searching. */ static int plx_keycmp( const void *a , const void *b, size_t n ) { int i, cmp; plx_t * pla = *(plx_t**)a; plx_t * plb = *(plx_t**)b; #ifdef WIN32 n = n; /* To silence a Win32 warning */ #endif if( pla->n < plb->n ) return -1; if( pla->n > plb->n ) return 1; for(i=0;in;i++) { if((cmp = p_keycmp(&pla->p[i], &plb->p[i])) != 0) return cmp; } return 0; /* they are equal */ } /* global for printing so we don't put so many bytes * on the stack */ static char po_print_buf[MAXPORTS]; /* PORT OBJECT FUNCTIONS */ /* Create a new PortObject */ PortObject * PortObjectNew(void) { PortObject *po = (PortObject *)SnortAlloc(sizeof(PortObject)); po->item_list =(SF_LIST*) sflist_new(); if( !po->item_list ) { free( po ); return 0; } po->rule_list =(SF_LIST*) sflist_new(); if( !po->rule_list ) { sflist_free_all( po->item_list, free ); free( po ); return 0; } return po; } /* This is the opposite of ntohl/htonl defines, and does the * swap on big endian hardware */ #ifdef WORDS_BIGENDIAN #define SWAP_BYTES(a) \ ((((uint32_t)(a) & 0xFF000000) >> 24) | \ (((uint32_t)(a) & 0x00FF0000) >> 8) | \ (((uint32_t)(a) & 0x0000FF00) << 8) | \ (((uint32_t)(a) & 0x000000FF) << 24)) #else #define SWAP_BYTES(a) (a) #endif static unsigned po_rule_hash_func(SFHASHFCN *p, unsigned char *k, int n) { unsigned char *key; int ikey = *(int*)k; /* Since the input is really an int, put the bytes into a normalized * order so that the hash function returns consistent results across * on BE & LE hardware. */ ikey = SWAP_BYTES(ikey); /* Set a pointer to the key to pass to the hashing function */ key = (unsigned char *)&ikey; return sfhashfcn_hash(p, key, n); } /* Create a new PortObject2 */ PortObject2 * PortObject2New(int nrules) { PortObject2 *po = (PortObject2 *)SnortAlloc(sizeof(PortObject2)); po->item_list =(SF_LIST*) sflist_new(); if( !po->item_list ) { free( po ); return 0; } po->rule_hash =(SFGHASH*) sfghash_new(nrules,sizeof(int),0,free /* frees data - should be rule id ptrs == (int*) */); if( !po->rule_hash ) { sflist_free_all( po->item_list, free ); free( po ); return 0; } /* Use hash function defined above for hashing the key as an int. */ sfghash_set_keyops(po->rule_hash, po_rule_hash_func, memcmp); //sfhashfcn_static( po->rule_hash->sfhashfcn ); /* TODO: Leave this in, else we get different events */ return po; } /* * Set the name of the Port Object */ int PortObjectSetName(PortObject * po, char * name) { if( !po ) return -1; if( !name ) return -1; /* free the old name */ if(po->name) free(po->name); /* alloc a new name */ po->name = SnortStrdup(name); if( !po->name ) return -1; return 0; } /* * Free a PortObjectItem */ void PortObjectItemFree (PortObjectItem * poi) { if(poi) free(poi); } /* * Free the PortObject */ void PortObjectFree( void * pvoid ) { PortObject * po = (PortObject *)pvoid; DEBUG_WRAP(static int pof_cnt = 0; pof_cnt++;); DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"PortObjectFree-Cnt: %d ptr=%p\n",pof_cnt,pvoid);); if( !po ) return ; if( po->name ) free (po->name ); if( po->item_list) sflist_free_all( po->item_list, free ); if( po->rule_list) sflist_free_all( po->rule_list, free ); if (po->data && po->data_free) { po->data_free(po->data); } free( po ); } /* * Free the PortObject2 */ void PortObject2Free( void * pvoid ) { PortObject2 * po = (PortObject2 *)pvoid; DEBUG_WRAP(static int pof2_cnt = 0; pof2_cnt++;); DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"PortObjectFree2-Cnt: %d ptr=%p\n",pof2_cnt,pvoid);); if( !po ) return; if( po->name ) free (po->name ); if( po->item_list) sflist_free_all( po->item_list, free ); if( po->rule_hash) sfghash_delete( po->rule_hash ); if (po->bitop) { boFreeBITOP(po->bitop); free(po->bitop); } if (po->data && po->data_free) { po->data_free(po->data); } free( po ); } /* * Create a new PortObjectItem */ PortObjectItem * PortObjectItemNew(void) { PortObjectItem *poi = (PortObjectItem *)SnortAlloc(sizeof(PortObjectItem)); return poi; } /* * Add a PortObjectItem to a PortObject */ int PortObjectAddItem( PortObject * po, PortObjectItem * poi, int *errflag) { PortObjectItem *p; SF_LNODE *pos = NULL; if(!po || !poi) return 0; if(errflag) *errflag = 0; /* Make sure this is not a duplicate */ for(p=(PortObjectItem*)sflist_firstpos(po->item_list,&pos); p != 0; p=(PortObjectItem*)sflist_nextpos(po->item_list,&pos) ) { if((p->lport == poi->lport) && (p->hport == poi->hport)) { if(errflag) *errflag = POPERR_DUPLICATE_ENTRY; return -1; /* -1 chosen for consistency with sflist_add_tail */ } } return sflist_add_tail( po->item_list, poi ); } /* * Add a PortObjectItem to a PortObject */ int PortObjectAddPortObject(PortObject * podst, PortObject * posrc, int *errflag) { PortObjectItem *po; SF_LNODE *pos = NULL; int ret = 0; if(errflag) *errflag = 0; for(po=(PortObjectItem*)sflist_firstpos(posrc->item_list, &pos); po != 0; po=(PortObjectItem*)sflist_nextpos(posrc->item_list, &pos) ) { PortObjectItem *poi = PortObjectItemDup(po); if((ret = PortObjectAddItem(podst, poi, errflag)) != 0) return ret; } return ret; } /* Dup a PortObjectItem */ PortObjectItem * PortObjectItemDup( PortObjectItem * poi) { PortObjectItem * poinew; if( !poi ) return 0; poinew = PortObjectItemNew(); if( !poinew ) return 0; memcpy(poinew,poi,sizeof(PortObjectItem)); return poinew; } /* * Dup the PortObjects Item List, RuleList, and Name */ PortObject * PortObjectDup( PortObject * po ) { PortObject * ponew = NULL; PortObjectItem * poi = NULL; PortObjectItem * poinew = NULL; SF_LNODE * lpos = NULL; int * prid = NULL; int * prule = NULL; ponew = PortObjectNew(); if( !ponew ) return 0; /* Dup the Name */ if( po->name ) ponew->name = strdup(po->name); else ponew->name = strdup("dup"); if( !ponew->name ) { free( ponew ); return NULL; } /* Dup the Item List */ if( po->item_list ) { for(poi =(PortObjectItem*)sflist_firstpos(po->item_list,&lpos); poi != NULL; poi =(PortObjectItem*)sflist_nextpos(po->item_list,&lpos) ) { poinew = PortObjectItemDup( poi ); if(!poinew) { free( ponew->name ); free( ponew ); return 0; } PortObjectAddItem( ponew, poinew, NULL ); } } /* Dup the input rule list */ if( po->rule_list ) { for(prid = (int*)sflist_firstpos(po->rule_list,&lpos); prid != 0; prid = (int*)sflist_nextpos(po->rule_list,&lpos) ) { prule = calloc(1,sizeof(int)); if(!prule) { free( poinew ); free( ponew->name ); free( ponew ); return NULL; } *prule = *prid; sflist_add_tail(ponew->rule_list,prule); } } return ponew; } /* * Dup the PortObjects Item List, and Name */ PortObject * PortObjectDupPorts( PortObject * po ) { PortObject * ponew = NULL; PortObjectItem * poi = NULL; PortObjectItem * poinew = NULL; SF_LNODE * lpos = NULL; ponew = PortObjectNew(); if( !ponew ) return 0; /* Dup the Name */ if( po->name ) ponew->name = strdup(po->name); else ponew->name = strdup("dup"); if( !ponew->name ) { free( ponew ); return NULL; } /* Dup the Item List */ if( po->item_list ) { for(poi =(PortObjectItem*)sflist_firstpos(po->item_list,&lpos); poi != NULL; poi =(PortObjectItem*)sflist_nextpos(po->item_list,&lpos) ) { poinew = PortObjectItemDup( poi ); if(!poinew) return 0; PortObjectAddItem( ponew, poinew, NULL ); } } return ponew; } /* * Dup the PortObjects Item List, Name, and RuleList->RuleHash */ PortObject2 * PortObject2Dup( PortObject * po ) { PortObject2 * ponew = NULL; PortObjectItem * poi = NULL; PortObjectItem * poinew = NULL; SF_LNODE * lpos = NULL; int * prid = NULL; int * prule = NULL; if( !po ) return NULL; if( !po->rule_list ) return NULL; ponew = PortObject2New(po->rule_list->count + PO_EXTRA_RULE_CNT); if( !ponew ) return NULL; /* Dup the Name */ if( po->name ) ponew->name = strdup(po->name); else ponew->name = strdup("dup"); if( !ponew->name ) { PortObject2Free(ponew); return NULL; } /* Dup the Item List */ if( po->item_list ) { for(poi =(PortObjectItem*)sflist_firstpos(po->item_list,&lpos); poi != NULL; poi =(PortObjectItem*)sflist_nextpos(po->item_list,&lpos) ) { poinew = PortObjectItemDup( poi ); if(!poinew) { PortObject2Free(ponew); return 0; } PortObjectAddItem( (PortObject*)ponew, poinew, NULL ); } } /* Dup the input rule list */ if( po->rule_list ) { for(prid = (int*)sflist_firstpos(po->rule_list,&lpos); prid != 0; prid = (int*)sflist_nextpos(po->rule_list,&lpos) ) { prule = calloc(1,sizeof(int)); if(!prule) { PortObject2Free(ponew); return NULL; } *prule = *prid; if( sfghash_add( ponew->rule_hash, prule, prule ) != SFGHASH_OK ) { free( prule ); } } } return ponew; } /* Add a Port to a PortObject */ int PortObjectAddPort( PortObject * po, int port, int not_flag ) { PortObjectItem * poi; poi = PortObjectItemNew(); if( !poi ) return -1; poi->type = PORT_OBJECT_PORT; if( not_flag ) poi->flags = PORT_OBJECT_NOT_FLAG; poi->lport = (unsigned short)port; poi->hport = (unsigned short)port; return sflist_add_tail( po->item_list, poi ); } /* Add a Port Range to a PortObject */ int PortObjectAddRange( PortObject * po, int lport, int hport, int not_flag ) { PortObjectItem * poi; poi = PortObjectItemNew(); if( !poi ) return -1; poi->type = PORT_OBJECT_RANGE; if( not_flag ) poi->flags = PORT_OBJECT_NOT_FLAG; poi->lport = (unsigned short)lport; poi->hport = (unsigned short)hport; return sflist_add_tail( po->item_list, poi ); } /* Add ANY port */ int PortObjectAddPortAny( PortObject * po ) { PortObjectItem * poi; if(!po) return -1 ; poi = PortObjectItemNew(); if( !poi ) return -1; poi->type = PORT_OBJECT_ANY; poi->lport = 0; poi->hport = MAXPORTS-1; if(!po->name) po->name = strdup("any"); if(!po->name) { free(poi); return -1; } return sflist_add_tail( po->item_list, poi ); } /* * Check if we have any ANY ports */ int PortObjectHasAny (PortObject * po ) { PortObjectItem *poi; if( !po ) return 0; for(poi=(PortObjectItem*)sflist_first(po->item_list); poi != 0; poi=(PortObjectItem*)sflist_next(po->item_list) ) { if( poi->type == PORT_OBJECT_ANY ) return 1; } return 0; } int PortObjectHasNot (PortObject * po ) { PortObjectItem *poi; if( !po ) return 0; for(poi=(PortObjectItem*)sflist_first(po->item_list); poi != 0; poi=(PortObjectItem*)sflist_next(po->item_list) ) { if ( poi->flags== PORT_OBJECT_NOT_FLAG) return 1; } return 0; } int PortObjectIsPureNot (PortObject * po ) { PortObjectItem *poi; int cnt=0; if( !po ) return 0; for(poi=(PortObjectItem*)sflist_first(po->item_list); poi != 0; poi=(PortObjectItem*)sflist_next(po->item_list) ) { cnt++; if ( poi->flags != PORT_OBJECT_NOT_FLAG) return 0; } if( cnt == 0 ) return 0; return 1; } /* * This does NOT return true if the object is an ANY port */ int PortObjectHasPort (PortObject * po, int port ) { PortObjectItem *poi; if( !po ) return 0; for(poi=(PortObjectItem*)sflist_first(po->item_list); poi != 0; poi=(PortObjectItem*)sflist_next(po->item_list) ) { switch( poi->type ) { case PORT_OBJECT_ANY: return 0; case PORT_OBJECT_PORT: if( poi->lport == (uint16_t)(port&0xffff) ) return 1; if( poi->flags & PORT_OBJECT_NOT_FLAG ) return 1; break; case PORT_OBJECT_RANGE: if( (uint16_t)port >= poi->lport && (uint16_t)port <= poi->hport ) return 1; if( poi->flags & PORT_OBJECT_NOT_FLAG ) return 1; break; } } return 0; } /* * This returns true if the object is an ANY port */ int PortObjectIncludesPort (PortObject * po, int port ) { PortObjectItem *poi; if( !po ) return 0; for(poi=(PortObjectItem*)sflist_first(po->item_list); poi != 0; poi=(PortObjectItem*)sflist_next(po->item_list) ) { switch( poi->type ) { case PORT_OBJECT_ANY: return 1; case PORT_OBJECT_PORT: if( poi->lport == (uint16_t)port ) return 1; if( poi->flags & PORT_OBJECT_NOT_FLAG ) return 1; break; case PORT_OBJECT_RANGE: if( (uint16_t)port >= poi->lport && (uint16_t)port <= poi->hport ) return 1; if( poi->flags & PORT_OBJECT_NOT_FLAG ) return 1; break; } } return 0; } /* * Locate a PortObject by Port number , this only locates the 1st one * This was a hack for testing.... */ PortObject * PortTableFindPortObjectByPort( PortTable * p , int port ) { PortObject * po; SF_LNODE * pos; for(po =(PortObject*)sflist_firstpos(p->pt_polist,&pos); po != NULL; po =(PortObject*)sflist_nextpos(p->pt_polist,&pos) ) { if( PortObjectHasPort ( po, port ) ) { return po; } } return 0; } /* * Calcs number of ports in this object, * object do not have to be normalized, * but if the same ports are referenced * twice, the count will be off. * * returns: * any = -1 * 0 = none/empty * >0 = number of ports */ int PortObjectPortCount (PortObject * po ) { PortObjectItem *poi; int cnt=0; int nports; if( !po ) return 0; for(poi=(PortObjectItem*)sflist_first(po->item_list); poi != 0; poi=(PortObjectItem*)sflist_next(po->item_list) ) { switch( poi->type ) { case PORT_OBJECT_ANY: return -1; case PORT_OBJECT_PORT: if( poi->flags & PORT_OBJECT_NOT_FLAG ) { cnt--; } else { cnt++; } break; case PORT_OBJECT_RANGE: nports = poi->hport - poi->lport + 1; if( poi->flags & PORT_OBJECT_NOT_FLAG ) { cnt-=nports; } else { cnt+=nports; } } } if( cnt < 0 ) { /* we have a pure not port or port range * * !80 = -1, add 64K (65535 -1 = 65534) * !80:81 = -2, (65535 - 2 = 65533) * * [:1023,!80] = 1024 - 1 = 1023 ports * */ cnt += SFPO_MAX_PORTS; /* add back in the acceptable ports */ } return cnt; } /* * Build a PortMap Char Array * returns: 0 if an ANY port. * n number of unique ports. */ char * PortObjectCharPortArray ( char * parray, PortObject * po, int * nports ) { int cnt = 0; unsigned not_cnt=0; PortObjectItem * poi; SF_LNODE * pos; if( !po || PortObjectHasAny ( po ) ) { return 0; /* ANY =64K */ } if( !parray ) { parray = (char*) calloc(1,SFPO_MAX_PORTS); if( !parray ) return 0; } for(poi=(PortObjectItem*)sflist_firstpos(po->item_list,&pos); poi != 0; poi=(PortObjectItem*)sflist_nextpos(po->item_list,&pos) ) { /* Add ports that are not NOT'd */ if( poi->flags & PORT_OBJECT_NOT_FLAG ) { not_cnt++; continue; } if( poi->type == PORT_OBJECT_PORT ) { if( !parray[poi->lport] ) cnt++; parray[poi->lport] = 1; } else if( poi->type == PORT_OBJECT_RANGE ) { int i; for(i=poi->lport;i<=poi->hport;i++) { if( !parray[i] ) cnt++; parray[i] = 1; } } } /* Remove any NOT'd ports that may have been added above */ for(poi=(PortObjectItem*)sflist_firstpos(po->item_list,&pos); poi != 0; poi=(PortObjectItem*)sflist_nextpos(po->item_list,&pos) ) { if( !( poi->flags & PORT_OBJECT_NOT_FLAG) ) continue; if( poi->type == PORT_OBJECT_PORT ) { if( parray[poi->lport] ) cnt--; parray[poi->lport] =0; } else if( poi->type == PORT_OBJECT_RANGE ) { int i; for(i=poi->lport;i<=poi->hport;i++) { if( parray[i] ) cnt--; parray[i] = 0; } } } /* A pure Not list */ if( po->item_list->count == not_cnt ) { int i; /* enable all of the ports */ for(i=0;iitem_list,&pos); poi != 0; poi=(PortObjectItem*)sflist_nextpos(po->item_list,&pos) ) { if( !( poi->flags & PORT_OBJECT_NOT_FLAG) ) continue; /* should not happen */ if( poi->type == PORT_OBJECT_PORT ) { if( parray[poi->lport] ) cnt--; parray[poi->lport] =0; } else if( poi->type == PORT_OBJECT_RANGE ) { int k; for(k=poi->lport;k<=poi->hport;k++) { if( parray[k] ) cnt--; parray[k] = 0; } } } } *nports = cnt; return parray; } /* * Make a list of ports form the char array, each char is either * on or off. */ static SF_LIST * PortObjectItemListFromCharPortArray( char * parray, int n, int nports ) { int i, lport ,hport; SF_LIST * plist; PortObjectItem * poi; plist = sflist_new(); if( !plist ) return 0; for(i=0; (i 0); i++) { if( parray[i] == 0 ) continue; /* Either a port or the start of a range */ lport = hport = i; nports--; for(i++;itype = PORT_OBJECT_PORT; poi->lport = (unsigned short)lport; } else { poi->type = PORT_OBJECT_RANGE; poi->lport =(unsigned short)lport; poi->hport =(unsigned short)hport; } if( sflist_add_tail( plist, poi ) ) { sflist_free_all( plist, free ); return 0; } } return plist; } /* * Removes Ports in B from A ... A = A - B */ int PortObjectRemovePorts( PortObject * a, PortObject * b ) { int i; int nportsa; int nportsb; SF_LIST * plist; static char pA[SFPO_MAX_PORTS]; static char pB[SFPO_MAX_PORTS]; memset(pA,0,SFPO_MAX_PORTS); memset(pB,0,SFPO_MAX_PORTS); /* Create a char array of ports */ PortObjectCharPortArray ( pA, a, &nportsa ); /* Create a char array of ports */ PortObjectCharPortArray ( pB, b, &nportsb ); for(i=0;iitem_list, free ); /* Replace the old PortObject list */ a->item_list = plist; return 0; } /* * Normalize a port object * * The reduces multiple references to a given port to a single unique reference * This function should be used on each PortObject, once it's completed. After * the normalized PortObject is created, the input PortObject may be deleted. */ int PortObjectNormalize (PortObject * po ) { SF_LIST * plist; int nports = 0; static char parray[SFPO_MAX_PORTS]; if( PortObjectHasAny ( po ) ) { return 0; /* ANY =65K */ } memset(parray,0,SFPO_MAX_PORTS); /* Create a char array of ports */ PortObjectCharPortArray ( parray, po, &nports ); /* Convert the array into a Port Object list */ plist = PortObjectItemListFromCharPortArray( parray, SFPO_MAX_PORTS, nports ); if( !plist ) return -1; /* Release the old port list */ sflist_free_all( po->item_list, free ); /* Replace the old PortObject list */ po->item_list = plist; return nports; } /* * Negate an entire PortObject */ int PortObjectNegate (PortObject * po ) { int i; SF_LIST * plist; int nports = 0; static char parray[SFPO_MAX_PORTS]; if( PortObjectHasAny ( po ) ) { return 0; /* ANY =65K */ } memset(parray,0,SFPO_MAX_PORTS); /* Create a char array of ports */ PortObjectCharPortArray ( parray, po, &nports ); for(i=0;iitem_list, free ); /* Replace the old PortObject list */ po->item_list = plist; return nports; } /* PortObjects should be normalized, prior to testing */ static int PortObjectItemsEqual(PortObjectItem * a, PortObjectItem * b ) { if( a->type != b->type ) return 0; switch( a->type ) { case PORT_OBJECT_ANY: return 1; case PORT_OBJECT_PORT: if( a->lport == b->lport ) return 1; break; case PORT_OBJECT_RANGE: if( a->lport == b->lport && a->hport == b->hport ) return 1; break; } return 0; } /* PortObjects should be normalized, prior to testing */ int PortObjectEqual( PortObject * a, PortObject *b ) { PortObjectItem *pa; PortObjectItem *pb; SF_LNODE * posa; SF_LNODE * posb; if( a->item_list->count != b->item_list->count ) return 0; pa = (PortObjectItem*)sflist_firstpos(a->item_list,&posa); pb = (PortObjectItem*)sflist_firstpos(b->item_list,&posb); while( pa && pb ) { if( !PortObjectItemsEqual( pa, pb) ) return 0; pa = (PortObjectItem*)sflist_nextpos(a->item_list,&posa); pb = (PortObjectItem*)sflist_nextpos(b->item_list,&posb); } if( pa || pb ) /* both are not done - cannot match */ return 0; return 1; /* match */ } /* Dup and Append PortObjectItems from pob to poa */ PortObject * PortObjectAppend(PortObject * poa, PortObject * pob ) { PortObjectItem * poia; PortObjectItem * poib; for( poib = (PortObjectItem*) sflist_first(pob->item_list); poib!= 0; poib = (PortObjectItem*)sflist_next(pob->item_list) ) { poia = PortObjectItemNew(); if(!poia) return 0; memcpy(poia,poib,sizeof(PortObjectItem)); sflist_add_tail(poa->item_list,poia); } return poa; } /* Dup and append rule list numbers from pob to poa */ PortObject * PortObjectAppendPortObject(PortObject * poa, PortObject * pob ) { int * prid; int * prid2; SF_LNODE * lpos; for( prid = (int*) sflist_firstpos(pob->rule_list,&lpos); prid!= 0; prid = (int*)sflist_nextpos(pob->rule_list,&lpos) ) { prid2 = calloc( 1, sizeof(int)); if( !prid2 ) return 0; *prid2 = *prid; sflist_add_tail(poa->rule_list,prid2); } return poa; } /* Dup and append rule list numbers from pob to poa */ PortObject2 * PortObject2AppendPortObject(PortObject2 * poa, PortObject * pob ) { int * prid; int * prid2; SF_LNODE * lpos; for( prid = (int*) sflist_firstpos(pob->rule_list,&lpos); prid!= 0; prid = (int*)sflist_nextpos(pob->rule_list,&lpos) ) { prid2 = calloc( 1, sizeof(int)); if( !prid2 ) return 0; *prid2 = *prid; if( sfghash_add(poa->rule_hash,prid2,prid2) != SFGHASH_OK ) { free(prid2); } } return poa; } /* Dup and append rule list numbers from pob to poa */ PortObject2 * PortObject2AppendPortObject2(PortObject2 * poa, PortObject2 * pob ) { int * prid; int * prid2; SFGHASH_NODE * node; for( node = sfghash_findfirst(pob->rule_hash); node!= NULL; node = sfghash_findnext(pob->rule_hash) ) { prid = node->data; if( !prid ) continue; prid2 = calloc( 1, sizeof(int)); if( !prid2 ) return 0; *prid2 = *prid; if( sfghash_add(poa->rule_hash,prid2,prid2) != SFGHASH_OK ) { free( prid2 ); } } return poa; } /* * Append Ports and Rules from pob to poa */ PortObject * PortObjectAppendEx(PortObject * poa, PortObject * pob ) { // LogMessage("PortObjectAppendEx: appending ports\n"); if( !PortObjectAppend( poa, pob ) ) return 0; //LogMessage("PortObjectAppendEx: appending rules\n"); if( !PortObjectAppendPortObject( poa, pob ) ) return 0; return poa; } /* * Append Ports and Rules from pob to poa */ PortObject2 * PortObjectAppendEx2(PortObject2 * poa, PortObject * pob ) { // LogMessage("PortObjectAppendEx: appending ports\n"); if( !PortObjectAppend((PortObject*) poa, pob ) ) return 0; // LogMessage("PortObjectAppendEx: appending rules\n"); if( !PortObject2AppendPortObject( poa, pob ) ) return 0; return poa; } /* PORT TABLE FUNCTIONS */ /* Create a new table */ PortTable * PortTableNew(void) { PortTable * p; p = (PortTable*) calloc(1,sizeof(PortTable)); if(!p) return 0; p->pt_polist = sflist_new(); if(!p->pt_polist ) { free(p); return 0; } p->pt_lrc = PTBL_LRC_DEFAULT; /* 10 rules, user should really control these */ p->pt_optimize = 1; /* if disabled, only one merged rule group is used */ return p; } void PortTableFree(PortTable *p) { int i; SFGHASH_NODE *node; if (!p) return; if (p->pt_polist) { sflist_free_all(p->pt_polist, PortObjectFree ); } if (p->pt_mpo_hash) { PortObject2 *po; for (node = sfghash_findfirst(p->pt_mpo_hash); node; node = sfghash_findnext(p->pt_mpo_hash)) { po = node->data; /* Free the data from this entry */ PortObject2Free(po); } sfghash_delete(p->pt_mpo_hash); } if (p->pt_plx_list) { sflist_free_all(p->pt_plx_list, plx_free); } if (p->pt_mpxo_hash) { #if 0 PortObject2 *po; for (node = sfghash_findfirst(p->pt_mpxo_hash); node; node = sfghash_findnext(p->pt_mpxo_hash)) { po = node->data; /* Free the data from this entry */ //PortObject2Free(po); } #endif sfghash_delete(p->pt_mpxo_hash); } for (i=0;ipt_port_object[i]) { PortObject2Free(p->pt_port_object[i]); } #endif } free(p); } PortObject * PortTableFindInputPortObjectName(PortTable * pt, char * po_name) { SF_LNODE * lpos; PortObject * po; if( !pt ) return NULL; if( !po_name ) return NULL; /* Normalize each of the input port objects */ for(po =(PortObject*)sflist_firstpos(pt->pt_polist,&lpos); po!=0; po =(PortObject*)sflist_nextpos(pt->pt_polist,&lpos) ) { if( po->name ) { if( strcmp(po->name,po_name)==0 ) { return po; } } } return NULL; } /* * Find PortObject by PortItem Info */ PortObject * PortTableFindInputPortObjectPorts( PortTable * pt, PortObject * pox ) { SF_LNODE * lpos; PortObject * po; if( !pt ) return NULL; if( !pox ) return NULL; for(po =(PortObject*)sflist_firstpos(pt->pt_polist,&lpos); po!=0; po =(PortObject*)sflist_nextpos(pt->pt_polist,&lpos) ) { if( PortObjectEqual( po, pox ) ) { return po; } } return NULL; } int PortTableNormalizeInputPortObjects( PortTable *p ) { SF_LNODE * lpos; PortObject * po; /* Normalize each of the input port objects */ for(po =(PortObject*)sflist_firstpos(p->pt_polist,&lpos); po!=0; po =(PortObject*)sflist_nextpos(p->pt_polist,&lpos) ) { PortObjectNormalize(po); } return 0; } int PortObjectAddRule( PortObject * po , int rule ) { int * pruleid; //LogMessage("Adding Rule %d to Port Object '%s'\n",rule,po->name); if( !po ) return -1; if( !po->rule_list ) return -1; /* Add rule index to rule list */ pruleid = calloc(1,sizeof(int)); if( !pruleid ) { return -1; } *pruleid = rule; sflist_add_tail( po->rule_list, pruleid ); return 0; } /* Add Users PortObjects to the Table We save the users port object, so it's no longer the users. */ int PortTableAddObject( PortTable *p, PortObject * po ) { SF_LNODE * lpos; PortObject * pox; /* Search for the Port Object in the input list, by address */ for(pox =(PortObject*)sflist_firstpos(p->pt_polist,&lpos); pox!=0; pox =(PortObject*)sflist_nextpos(p->pt_polist,&lpos) ) { if( pox == po ) { /* already in list - just return */ return 0; } } /* Save the users port object, if not already in the list */ if( sflist_add_tail(p->pt_polist,po) ) return -1; return 0; } /* Hash routine for hashing PortObjects as Keys p - SFHASHFCN * d - PortObject * n = 4 bytes (sizeof*) - not used Don't use this for type=ANY port objects */ static unsigned PortObject_hash( SFHASHFCN * p, unsigned char *d, int n ) { unsigned hash = p->seed; PortObjectItem * poi; PortObject * po; SF_LNODE * pos; #ifdef WIN32 n = n; /* This quiets a Win32 warning */ #endif po = *(PortObject**) d; /* hash up each item */ for(poi =(PortObjectItem*)sflist_firstpos(po->item_list,&pos); poi != NULL; poi =(PortObjectItem*)sflist_nextpos(po->item_list,&pos) ) { switch(poi->type) { case PORT_OBJECT_PORT: hash *= p->scale; hash += poi->lport & 0xff; hash *= p->scale; hash += (poi->lport >> 8) & 0xff; break; case PORT_OBJECT_RANGE: hash *= p->scale; hash += poi->lport & 0xff; hash *= p->scale; hash += (poi->lport >> 8) & 0xff; hash *= p->scale; hash += poi->hport & 0xff; hash *= p->scale; hash += (poi->hport >> 8) & 0xff; break; } } return hash ^ p->hardener; } /* * Merge multiple PortObjects into a final PortObject2, * this merges ports and rules. * * merge po's in pol, find a previous instance add it. * * This is done as follows: * 1) check if it's in the plx table-mhashx, this uses the list of * addresses of the Input PortObjects as it's key, not the ports. * This is quick and does not require assembling/merging the port * objects intoa PortObject2 1st. * 2) if found were done, otherwise * 3) make a merged PortObject2 * 4) Try adding the PortObject2 to it's table - mhash * a) if it adds go on, else * b) if it's already in the table * 1) get the one in the table * 2) add any ports in the just created one * 3) free the one just created * 5) Create a plx object * 6) Add the plx object to the plx Table * 1) if it's already in the object - fail this contradicts 1) * 7) return the create PortObject2, or the one retrived from the * PortObject table. * * pol - list of input PortObject pointers * pol_cnt- count in 'pol' * mhash - stores the merged ports, using the merged port objects port list as a key. * mhashx - stores plx keys, and PortObject2 *'s as data for the final merged port objects, * the plx keys provide a quicker way to compare port lists to ensure if two ports * are using the same set of rules (port objects). * mhash and mhashx reference the same port objects as data, but use different keys for lookup * purposes. Once we perform a merge we store the results, using the 'plx' as the key for future lookup. * plx - key to use to lookup and store the merged port object * * */ static PortObject2 * _merge_N_pol( SFGHASH * mhash, SFGHASH * mhashx, SF_LIST * plx_list, void ** pol, int pol_cnt, plx_t * plx ) { PortObject2 * ponew; PortObject2 * pox; plx_t * plx_tmp; int stat; int i; /* * Check for the merged port object in the plx table */ DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS, "++++n=%d sfghash_find-mhashx\n",pol_cnt);); ponew = sfghash_find( mhashx, &plx ); if( ponew ) { DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS, "n=%d ponew found in mhashx\n",pol_cnt);); return ponew; } DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS, "n=%d posnew not found in mhashx\n",pol_cnt);); /* * Merge the port objects together - ports and rules */ /* Dup the 1st port objects rules and ports */ ponew = PortObject2Dup( (PortObject *)pol[0] ); if( !ponew ) { FatalError("Could not Dup2\n"); } /* Merge in all the other port object rules and ports */ if( pol_cnt > 1 ) { for(i=1;irule_list->count,i);); PortObjectAppendEx2( ponew, (PortObject *)pol[i] ); DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS, "*** merged port-object[%d], %d rules\n", i,ponew->rule_hash->count);); } PortObjectNormalize( (PortObject*)ponew ); } DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS, "*** merged %d port objects, %d rules\n", pol_cnt,ponew->rule_hash->count);); DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"*** merged ponew - follows: \n");); // PortObjectPrint2(ponew); /* * Add the Merged PortObject2 to the PortObject2 hash table * keyed by ports. */ DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"n=%d sfghash_add-mhash\n",pol_cnt);); stat =sfghash_add( mhash, &ponew, ponew ); if( stat != SFGHASH_OK ) { /* This is possible since PLX hash on a different key */ if( stat == SFGHASH_INTABLE ) { DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"n=%d sfghash_add-mhash ponew in table\n",pol_cnt);); DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"n=%d sfghash_find-mhash ponew\n",pol_cnt);); pox = sfghash_find(mhash,&ponew); if( pox ) { PortObject2AppendPortObject2(pox,ponew); DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"sfportobject.c: merge_N_pol() line=%d SFGHASH_INTABLE\n",__LINE__);); PortObject2Free( ponew ); ponew = pox; DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"n=%d sfghash_find-mhash ponew found, new rules merged\n",pol_cnt);); } else { FatalError("mhash add/find error n=%d\n", pol_cnt); } } else { FatalError("Could not add ponew to hash table- error\n"); } } DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"***%d ports merged object added to mhash table\n",pol_cnt);); /* * Create a plx node and add it to plx table * as the key with the merged port object as the data */ plx_tmp = plx_new( pol, pol_cnt); if(!plx_tmp) { FatalError("plx_new: memory alloc error\n"); } sflist_add_head(plx_list, (void *)plx_tmp); /* * Add the plx node to the PLX hash table */ DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"n=%d sfghash_add-mhashx\n",pol_cnt);); stat = sfghash_add( mhashx, &plx_tmp, ponew ); if( stat != SFGHASH_OK ) { if( stat == SFGHASH_INTABLE ) { FatalError("Could not add merged plx to PLX HASH table-INTABLE\n"); } else { FatalError("Could not add merged plx to PLX HASH table\n"); } } DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"Added-%d Merged Rule Groups to PLX HASH\n",pol_cnt);); /* * Validate hash table entry */ if( sfghash_find( mhashx, &plx_tmp ) != ponew ) { FatalError("Find after add failed on PLX HASH table key\n"); } return ponew; } /* * Merge Input Port Objects into rule collections that are particular to * each port. We store the results as objects and point to these in the * pt_port_object[MAX_PORTS] array. * * We use plx_t types to manage tracking and testing for merged large * rule groups, and merged small port groups. * * mhash - table of merged port objects ( built and used here ) * mhashx - table of plx_t objects ( built and used here ) * pol - list of input port objects touching the current port * pol_cnt - number of port objects in port list * lcnt - large rule count * */ static PortObject2 * PortTableCompileMergePortObjectList2(SFGHASH * mhash, SFGHASH * mhashx, SF_LIST * plx_list, PortObject * pol[], int pol_cnt, unsigned int lcnt ) { PortObject2 * ponew = NULL; PortObject2 * posnew = NULL; static void * polarge[SFPO_MAX_LPORTS]; static void * posmall[SFPO_MAX_LPORTS]; int nlarge = 0; int nsmall = 0; plx_t plx_small; plx_t plx_large; unsigned largest; int i; /* * Find the largest rule count of all of the port objects */ largest = 0; for(i=0;irule_list->count >= (unsigned)lcnt ) { if( pol[i]->rule_list->count > largest ) largest = pol[i]->rule_list->count; } } /* * Classify PortObjects as large or small based on rule set size * and copy them into separate lists */ for(i=0;irule_list->count >= (unsigned)lcnt ) { if( nlarge < SFPO_MAX_LPORTS ) polarge[ nlarge++ ] = (void *)pol[i]; } else { if( nsmall < SFPO_MAX_LPORTS ) posmall[ nsmall++ ] = (void *)pol[i]; } } DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"*** %d small rule groups, %d large rule groups\n",nsmall,nlarge);); /* * Sort the pointers to the input port objects so * we always get them in the same order for key comparisons */ if( nlarge > 1 ) qsort( polarge, nlarge, sizeof(void*), p_keycmp ); if( nsmall > 1 ) qsort( posmall, nsmall, sizeof(void*), p_keycmp ); DEBUG_WRAP( for(i=0;itail && (parray[port]->tail->ndata == po)) return; sflist_add_tail( parray [port], po ); } // Update port object lists static inline void update_port_lists(SF_LIST **parray, PortObject *po) { PortObjectItem *poi; int port; bool not_flag_set = FALSE; for(poi=(PortObjectItem*)sflist_first(po->item_list); poi != 0; poi=(PortObjectItem*)sflist_next(po->item_list) ) { if( poi->type == PORT_OBJECT_ANY) return; else if( poi->type == PORT_OBJECT_PORT) { if (poi->flags & PORT_OBJECT_NOT_FLAG) { not_flag_set = TRUE; break; } add_port_object(parray, poi->lport, po); } else if( poi->type == PORT_OBJECT_RANGE) { if (poi->flags & PORT_OBJECT_NOT_FLAG) { not_flag_set = TRUE; break; } for( port = poi->lport; port <= poi->hport; port++ ) { add_port_object(parray, port, po); } } } if (not_flag_set) { for( port = 0; port < SFPO_MAX_PORTS; port++ ) { add_port_object(parray, port, po); } } } // Create optimized port lists per port static inline SF_LIST **create_port_lists(PortTable * p) { PortObject *po; SF_LNODE *lpos; SF_LIST **parray = calloc(sizeof(SF_LIST *),SFPO_MAX_PORTS); if(!parray) return NULL; /* Build a list of port objects touching port 'i' */ for(po=sflist_firstpos(p->pt_polist,&lpos); po; po=sflist_nextpos(p->pt_polist,&lpos) ) { update_port_lists(parray, po); } return parray; } static inline void delete_port_lists(SF_LIST **parray) { int port; for( port = 0; port < SFPO_MAX_PORTS; port++ ) { SF_LIST *list = (SF_LIST *) parray[port]; if (list) sflist_free(list); } } /* * * * mhash * mhashx data structure used: p->pt_polist */ int PortTableCompileMergePortObjects( PortTable * p ) { SF_LNODE * lpos; SFGHASH * mhash; SFGHASH * mhashx; SFGHASH_NODE * node; SF_LIST * plx_list; int id = PO_INIT_ID; static PortObject * pol[SFPO_MAX_LPORTS]; // TODO: dynamically allocate int pol_cnt; char * parray = NULL; int i; SF_LIST **optimized_pl; DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"***\n***Merging PortObjects->PortObjects2\n***\n");); /* Create a Merged Port Object Table - hash by ports */ mhash = sfghash_new(PO_HASH_TBL_ROWS, sizeof(PortObject *), 0 /*userkeys-no*/, 0 /*free data-don't*/); if( !mhash ) return -1; /* Setup hashing function and key comparison function */ sfhashfcn_set_keyops( mhash->sfhashfcn, PortObject_hash, PortObject_keycmp ); /* remove randomness */ if (ScStaticHash()) sfhashfcn_static( mhash->sfhashfcn ); p->pt_mpo_hash = mhash; /* Create a Merged Port Object Table - hash by ports */ mhashx = sfghash_new(PO_HASH_TBL_ROWS, sizeof(plx_t *), 0/*userkeys-no*/, 0/*freedata()-don't*/); if( !mhashx ) return -1; /* Setup hashing function and key comparison function */ sfhashfcn_set_keyops( mhashx->sfhashfcn,plx_hash,plx_keycmp ); /* remove randomness */ if (ScStaticHash()) sfhashfcn_static( mhashx->sfhashfcn ); p->pt_mpxo_hash = mhashx; DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"***\n*** PortList-Merging, Large Rule groups must have %d rules\n",p->pt_lrc);); plx_list = sflist_new(); sflist_init(plx_list); p->pt_plx_list = plx_list; optimized_pl = create_port_lists(p); if(!optimized_pl) { FatalError("Memory error in PortTableCompile()\n"); } /* * For each port, merge rules from all port objects that touch the port * into an optimal object, that may be shared with other ports. */ for(i=0;ipt_port_object[i] = 0; if( !pol_cnt ) { //port not contained in any PortObject continue; } DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"*** merging list for port[%d] \n",i);fflush(stdout);); /* merge the rules into an optimal port object */ p->pt_port_object[i] = PortTableCompileMergePortObjectList2( mhash, mhashx, plx_list, pol, pol_cnt, p->pt_lrc ); if( !p->pt_port_object[i] ) { FatalError(" Could not merge PorObjectList on port %d\n",i); } /* give the new compiled port object an id of its own */ p->pt_port_object[i]->id = id++; DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"\n");fflush(stdout);); } delete_port_lists(optimized_pl); free(optimized_pl); /* * Normalize the Ports so they indicate only the ports that * reference the composite port object */ /* 1st- Setup bitmasks for collecting ports */ for(node=sfghash_findfirst(mhashx); node; node=sfghash_findnext(mhashx) ) { unsigned char * buf; PortObject2 * poa; poa = (PortObject2*)node->data; if( !poa ) continue; if (!poa->bitop) { poa->bitop = calloc(1,sizeof(BITOP)); if( !poa->bitop) { FatalError("Memory error in PortTableCompile\n"); } buf = calloc(1,8192); if( !buf ) { FatalError("Memory alloc error in PortObjectCompile()\n"); } if( boInitStaticBITOP(poa->bitop,8192,buf) ) { FatalError("BitOp error in PortObjectCompile()\n"); } } } /* Count how many ports each final port-object is used on */ for(i=0;ipt_port_object[i]; if(poa) { poa->port_cnt++; if( poa->bitop ) { if( boSetBit(poa->bitop, (unsigned int) i ) ) { FatalError("BitOp-Set error\n"); } } else { FatalError("NULL po->bitop in po on port %d\n",i); } } } /* get a port array 64K bytes */ parray = calloc(1,SFPO_MAX_PORTS); if(!parray) { FatalError("Memory error in PortTableCompile()\n"); } /* Process Port-Bitop map and print final port-object usage stats */ for(node=sfghash_findfirst(mhashx); node; node=sfghash_findnext(mhashx) ) { SF_LIST * plist; PortObject2 * po; int nports; po = (PortObject2*)node->data; if( !po ) { FatalError("MergePortOBject-NormalizePorts -NULL po\n"); } if( !po->port_cnt )/* port object is not used ignore it */ continue; if( !po->bitop ) { //FatalError("MergePortOBject-NormalizePorts -NULL po->bitop\n"); continue; } /* Convert the bitop bits to a char array */ memset(parray,0,SFPO_MAX_PORTS); nports = 0; for(i=0;ibitop, i ) ) { parray[ i ] = 1; nports++; } } /* Release bit buffer for each port object */ if( po->bitop ) { //if( po->bitop->pucBitBuffer ) //{ // free( po->bitop->pucBitBuffer ); // po->bitop->pucBitBuffer = NULL; //} boFreeBITOP(po->bitop); free( po->bitop ); po->bitop=NULL; } /* Build a PortObjectItem list from the char array */ plist = PortObjectItemListFromCharPortArray( parray, SFPO_MAX_PORTS, nports); if( !plist ) { FatalError("MergePortObjects: No PortObjectItems in portobject\n"); } /* free the original list */ sflist_free_all( po->item_list, free ); /* set the new list - this is a list of port itmes for this port object */ po->item_list = plist; DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"port-object id = %d, port cnt = %d\n",po->id,po->port_cnt);); } if(parray) free(parray); return 0; } /* * * Verify all rules in 'po' list are in 'po2' hash * * return 0 - OK * !0 - a rule in po is not in po2 */ static int _po2_include_po_rules( PortObject2 * po2, PortObject * po ) { //SFGHASH_NODE * node; int * pid; int * id; SF_LNODE * rpos; /* get each rule in po */ for(pid=sflist_firstpos(po->rule_list,&rpos); pid; pid=sflist_nextpos(po->rule_list,&rpos) ) { /* find it in po2 */ id =(int*) sfghash_find(po2->rule_hash,pid); /* make sure it's in po2 */ if(!id ) { return 1; /* error */ } } return 0; } /* * Perform a consistency check on the final port+rule objects * * Walk the rules */ int PortTableConsistencyCheck( PortTable *p ) { char * parray = 0; SFGHASH_NODE * node; int i; SF_LNODE * pos; SF_LNODE * ipos; PortObject * ipo; PortObject2 * lastpo = NULL; PortObjectItem * poi; parray = calloc(1,SFPO_MAX_PORTS); if(!parray) { FatalError("Memory eror in PortTableComopile\n"); } /* Make sure each port is only in one composite port object */ for(node=sfghash_findfirst(p->pt_mpo_hash); node; node=sfghash_findnext(p->pt_mpo_hash) ) { PortObject2 * po; po = (PortObject2*)node->data; if( !po ) { FatalError("PortObject consistency Check failed, hash table problem\n"); } if( !po->port_cnt )/* port object is not used ignore it */ continue; for(i=0;ipt_polist,&pos); ipo; ipo=sflist_nextpos(p->pt_polist,&pos) ) { /* * for each port in this object get the composite port object * assigned to that port and verify all of the input objects rules * are in the composite object. This verifies all rules are applied * to the originally intended port. */ for(poi=sflist_firstpos(ipo->item_list,&ipos); poi; poi=sflist_nextpos(ipo->item_list,&ipos) ) { switch(poi->type) { case PORT_OBJECT_ANY: /* do nothing */ break; case PORT_OBJECT_PORT: if( _po2_include_po_rules( p->pt_port_object[ poi->lport ], ipo ) ) { FatalError("InputPortObject<->CompositePortObject consistency Check II failed!\n"); } break; case PORT_OBJECT_RANGE: { for(i=poi->lport;i<=poi->hport;i++) { /* small optimization*/ if( lastpo != p->pt_port_object[ i ] ) { if( _po2_include_po_rules( p->pt_port_object[ i ], ipo ) ) { FatalError("InputPortObject<->CompositePortObject consistency Check II failed!\n"); } lastpo = p->pt_port_object[ i ]; } } } break; } } } DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS, "***\n***Port Table Compiler Consistency Check Phase-II Passed !!! - Good to go Houston\n****\n");); return 0; } /* * Compile the PortTable * * This builds a set of Port+Rule objects that are in some way an optimal * set of objects to indicate which rules to apply to which ports. Since * these groups are calculated consistency checking is done with the finished * objects. */ int PortTableCompile( PortTable * p ) { /* * If not using an optimized Table use the rule_index_map in parser.c */ if( !p->pt_optimize ) { return 0; } DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"#PortTableCompile: Compiling Port Array Lists\n");); if( PortTableCompileMergePortObjects( p ) ) { FatalError("Could not create PortArryayLists\n"); } DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"Done\n");fflush(stdout);); if(ScTestMode()) PortTableConsistencyCheck(p); return 0; } static int integer_compare( const void *arg1, const void *arg2 ) { if( *(int*)arg1 < *(int*)arg2 ) return -1; if( *(int*)arg1 > *(int*)arg2 ) return 1; return 0; } static int * RuleListToSortedArray( SF_LIST * rl ) { SF_LNODE * pos = NULL; int * prid; int * ra; int k=0; if( !rl ) return 0; if(!rl->count) return NULL; ra = (int *)SnortAlloc(rl->count * sizeof(int)); for( prid = sflist_firstpos(rl,&pos); prid!= 0 && k < (int)rl->count; prid = sflist_nextpos(rl,&pos) ) { ra[k++] = *prid; } /* sort the array */ qsort(ra,rl->count,sizeof(int),integer_compare); return ra; } /**sort and uniq rule list. */ void RuleListSortUniq( SF_LIST * rl ) { unsigned i; int lastRuleIndex = -1; SF_LNODE *pos = NULL; int *currNode = NULL; unsigned uniqElements = 0; int *node = 0; int * rlist = NULL; rlist = RuleListToSortedArray(rl); if(!rlist ) { return ; } currNode = sflist_firstpos(rl,&pos); if (currNode == NULL) { free(rlist); return; } for(i=0; i < rl->count; i++) { if (rlist[i] > lastRuleIndex) { *currNode = lastRuleIndex = rlist[i]; //replace the next element in place currNode = sflist_nextpos(rl,&pos); uniqElements++; } } //free the remaining list nodes while (uniqElements != rl->count) { node = sflist_remove_tail (rl); free(node); } free(rlist); } /**Sort and make rule index in all port objects unique. Multiple policies may add * the same rule which can lead to duplication. */ void PortTableSortUniqRules( PortTable * p ) { PortObject * po; SF_LNODE *pos = NULL; for(po =(PortObject*)sflist_firstpos(p->pt_polist,&pos); po != NULL; po =(PortObject*)sflist_nextpos(p->pt_polist,&pos) ) { RuleListSortUniq(po->rule_list); } } static int * RuleHashToSortedArray( SFGHASH * rh ) { int * prid; int * ra; int k = 0; SFGHASH_NODE * node; if( !rh ) return 0; if(!rh->count) return NULL; ra = (int *)SnortAlloc(rh->count * sizeof(int)); for( node = sfghash_findfirst(rh); node != 0 && k < (int)rh->count; node = sfghash_findnext(rh) ) { prid = node->data; if( prid ) { ra[k++] = *prid; } } /* sort the array */ qsort(ra,rh->count,sizeof(int),integer_compare); return ra; } /* * Print Input Port List */ void PortTablePrintInput( PortTable * p ) { PortObject * po; SF_LNODE * pos; LogMessage("*** %d PortObjects in Table\n",p->pt_polist->count); for(po =(PortObject*)sflist_firstpos(p->pt_polist,&pos); po!=0; po =(PortObject*)sflist_nextpos(p->pt_polist,&pos) ) { PortObjectPrint( po ); } } void PortTablePrintInputEx( PortTable * p, void (*print_index_map)(int index, char *buf, int bufsize) ) { PortObject * po; SF_LNODE * pos; for(po =(PortObject*)sflist_firstpos(p->pt_polist,&pos); po != NULL; po =(PortObject*)sflist_nextpos(p->pt_polist,&pos) ) { PortObjectPrintEx( po, print_index_map ); } } /* Prints Compiled Ports/Rules Objects */ int PortTablePrintCompiledEx( PortTable * p , void (*print_index_map)(int index, char *buf, int bufsize) ) { PortObject2 * po = NULL; SFGHASH_NODE * node = NULL; LogMessage(" *** PortTableCompiled [ %d compiled port groups ] \n\n", p->pt_mpo_hash->count); for(node = sfghash_findfirst(p->pt_mpo_hash); node!= 0; node = sfghash_findnext(p->pt_mpo_hash) ) { po = node->data; PortObject2PrintEx( po, print_index_map ); } return 0; } /* Print port items. Used internally by sfportobject.c. Buffer assumed trusted. */ static void PortObjectItemPrint ( PortObjectItem * poi, char *dstbuf, int bufsize ) { SnortSnprintfAppend(dstbuf, bufsize, " "); if( poi->flags & PORT_OBJECT_NOT_FLAG ) SnortSnprintfAppend(dstbuf, bufsize, "!"); switch( poi->type ) { case PORT_OBJECT_PORT : SnortSnprintfAppend(dstbuf, bufsize, "%u", poi->lport); break; case PORT_OBJECT_RANGE : SnortSnprintfAppend(dstbuf, bufsize, "%u:%u",poi->lport,poi->hport); break; case PORT_OBJECT_ANY: SnortSnprintfAppend(dstbuf, bufsize, "any"); break; default: SnortSnprintfAppend(dstbuf, bufsize, " unknown port type @ %p", (void*)poi); break; } } void PortObjectPrintPortsRaw(PortObject * po ) { PortObjectItem * poi = NULL; SF_LNODE * pos = NULL; char * buf; int bufsize; /* Need to buffer the string so we only do one LogMessage, * due to syslog output. The largest string needed to represent * each portobject is the length required to represent: * " unknown port type @ 0x<8 max bytes>" (See PortObjectItemPrint), or: * 30 bytes. For the entire list, need room for spaces and brackets and * potential negations. Or: * list_size * (30 + 1space_for_each_element, + * 1potential_negation) + surrounding_whitespace + brackets + NULL */ bufsize = po->item_list->count * (30 + 1 + 1) + 5; buf = (char*)SnortAlloc(bufsize); SnortSnprintfAppend(buf, bufsize, " ["); for(poi=(PortObjectItem*)sflist_firstpos(po->item_list, &pos); poi != 0; poi=(PortObjectItem*)sflist_nextpos(po->item_list, &pos) ) { PortObjectItemPrint(poi, buf, bufsize); } SnortSnprintfAppend(buf, bufsize, " ]"); LogMessage("%s", buf); free(buf); } void PortObject2PrintPorts(PortObject2 * po ) { PortObjectItem * poi = NULL; SF_LNODE * pos = NULL; int bufsize = sizeof(po_print_buf); po_print_buf[0] = '\0'; SnortSnprintfAppend(po_print_buf, bufsize, " PortObject "); if( po->name ) { SnortSnprintfAppend(po_print_buf, bufsize, "%s ", po->name); } SnortSnprintfAppend(po_print_buf, bufsize, " Id:%d Ports:%d Rules:%d\n {\n Ports [", po->id, po->item_list->count, po->rule_hash->count); if( PortObjectHasAny( (PortObject*)po ) ) { SnortSnprintfAppend(po_print_buf, bufsize, "any"); } else { for(poi=(PortObjectItem*)sflist_firstpos(po->item_list,&pos); poi != 0; poi=(PortObjectItem*)sflist_nextpos(po->item_list,&pos) ) { PortObjectItemPrint(poi, po_print_buf, bufsize); } } SnortSnprintfAppend(po_print_buf, bufsize, " ]\n }\n"); LogMessage("%s", po_print_buf); } /* Print Port Object - Prints input ports and rules (uncompiled) ports rules (input by user) */ void PortObjectPrintEx(PortObject * po, void (*print_index_map)(int index, char *buf, int bufsize) ) { PortObjectItem * poi = NULL; SF_LNODE * pos = NULL; int k=0; int * rlist = NULL; unsigned i; int bufsize = sizeof(po_print_buf); po_print_buf[0] = '\0'; if( !po ) return ; if( !po->rule_list ) return ; if( !po->rule_list->count ) return ; SnortSnprintfAppend(po_print_buf, bufsize, " PortObject "); if( po->name ) { SnortSnprintfAppend(po_print_buf, bufsize, "%s ", po->name); } SnortSnprintfAppend(po_print_buf, bufsize, " Id:%d Ports:%d Rules:%d\n {\n", po->id, po->item_list->count,po->rule_list->count ); SnortSnprintfAppend(po_print_buf, bufsize, " Ports [\n "); if( PortObjectHasAny( po ) ) { SnortSnprintfAppend(po_print_buf, bufsize, "any"); } else { for(poi=(PortObjectItem*)sflist_firstpos(po->item_list,&pos); poi != 0; poi=(PortObjectItem*)sflist_nextpos(po->item_list,&pos) ) { PortObjectItemPrint(poi, po_print_buf, bufsize); } } SnortSnprintfAppend(po_print_buf, bufsize, " ]\n"); rlist = RuleListToSortedArray( po->rule_list ); if(!rlist ) { return ; } SnortSnprintfAppend(po_print_buf, bufsize, " Rules [ \n "); for(i=0;irule_list->count;i++) { if( print_index_map ) { print_index_map( rlist[i], po_print_buf, bufsize ); } else { SnortSnprintfAppend(po_print_buf, bufsize, " %d",rlist[i]); } k++; if( k == 25 ) { k=0; SnortSnprintfAppend(po_print_buf, bufsize, " \n "); } } SnortSnprintfAppend(po_print_buf, bufsize, " ]\n }\n"); LogMessage("%s", po_print_buf); free(rlist); } // extern void rule_index_map_print_index( int index ); void PortObjectPrint (PortObject * po ) { PortObjectPrintEx( po, rule_index_map_print_index ); } void PortObject2PrintEx(PortObject2 * po, void (*print_index_map)(int index, char *buf, int bufsize) ) { PortObjectItem * poi = NULL; SF_LNODE * pos = NULL; int k=0; int * rlist = NULL; unsigned int i; int bufsize = sizeof(po_print_buf); po_print_buf[0] = '\0'; SnortSnprintfAppend(po_print_buf, bufsize, " PortObject2 "); if( po->name ) SnortSnprintfAppend(po_print_buf, bufsize, "%s ",po->name); SnortSnprintfAppend(po_print_buf, bufsize, " Id:%d Ports:%d Rules:%d PortUsageCnt=%d\n {\n", po->id, po->item_list->count, po->rule_hash->count, po->port_cnt ); SnortSnprintfAppend(po_print_buf, bufsize, " Ports [\n "); if( PortObjectHasAny( (PortObject*)po ) ) { SnortSnprintfAppend(po_print_buf, bufsize, "any"); } else { for(poi=(PortObjectItem*)sflist_firstpos(po->item_list,&pos); poi != 0; poi=(PortObjectItem*)sflist_nextpos(po->item_list,&pos) ) { PortObjectItemPrint(poi, po_print_buf, bufsize); } } SnortSnprintfAppend(po_print_buf, bufsize, " ]\n"); rlist = RuleHashToSortedArray( po->rule_hash ); if(!rlist ) return ; SnortSnprintfAppend(po_print_buf, bufsize, " Rules [ \n "); for(i=0;irule_hash->count;i++) { if( print_index_map ) { print_index_map( rlist[i], po_print_buf, bufsize ); } else { SnortSnprintfAppend(po_print_buf, bufsize, " %d", rlist[i]); } k++; if( k == 25 ) { k=0; SnortSnprintfAppend(po_print_buf, bufsize, " \n "); } } SnortSnprintfAppend(po_print_buf, bufsize, " ]\n }\n"); LogMessage("%s", po_print_buf); free(rlist); } void PortObject2Print (PortObject2 * po ) { // void rule_index_map_print_index( int index ); PortObject2PrintEx( po, rule_index_map_print_index ); } /* Prints the original (normalized) PortGroups and as sepcified by the user */ void PortTablePrintUserRules( PortTable * p ) { PortObject * po; /* normalized user PortObjects and rule ids */ LogMessage(">>>PortTable - Rules\n"); for(po = (PortObject*)sflist_first(p->pt_polist); po!= 0; po = (PortObject*)sflist_next(p->pt_polist) ) { PortObjectPrint( po ); } /* port array of rule ids */ } /* Prints the Unique Port Groups and rules that reference them */ void PortTablePrintPortGroups( PortTable * p ) { PortObject2 * po; SFGHASH_NODE * ponode; /* normalized user PortObjects and rule ids */ LogMessage(">>>PortTable - Compiled Port Groups\n"); LogMessage(" [ %d port groups ] \n\n",p->pt_mpo_hash->count); for(ponode = sfghash_findfirst(p->pt_mpo_hash); ponode!= 0; ponode = sfghash_findnext(p->pt_mpo_hash) ) { po = ponode->data; PortObject2Print(po); } /* port array of rule ids */ } /* Print */ void PortTablePrintPortPortObjects( PortTable * p ) { int i; PortObject * po; SF_LIST * last = NULL; int bufsize = sizeof(po_print_buf); po_print_buf[0] = '\0'; LogMessage(">>>Port PortObjects\n"); for(i=0;ipt_port_lists[i] ) continue; if( p->pt_port_lists[i] == last ) continue; SnortSnprintfAppend(po_print_buf, bufsize, "---Port[%d] PortObjects [ ",i); for(po=(PortObject*)sflist_first(p->pt_port_lists[i]); po != 0; po=(PortObject*)sflist_next(p->pt_port_lists[i]) ) { SnortSnprintfAppend(po_print_buf, bufsize, "%d ",po->id); } SnortSnprintfAppend(po_print_buf, bufsize, "]\n"); last = p->pt_port_lists[i] ; } LogMessage("%s", po_print_buf); } /* * * Port Object Parser * */ static int POParserInit( POParser * pop, char * s, PortVarTable * pvTable ) { memset(pop,0,sizeof(POParser)); pop->pos = 0; pop->s = s; pop->slen = strlen(s); pop->errflag = 0; pop->pvTable = pvTable; return 0; } /* Get a Char */ static int POPGetChar( POParser * pop ) { int c; if( pop->slen > 0 ) { c = pop->s[0]; pop->slen--; pop->s++; pop->pos++; DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"GetChar: %c, %d bytes left\n",c, pop->slen);); return c; } return 0; } /* Skip whitespace till we find a non-whitespace char */ static int POPGetChar2( POParser * pop ) { int c; for(;;) { c=POPGetChar( pop ) ; if( !c ) return 0; if( isspace(c) || c==',' ) continue; break; } return c; } /* Restore last char */ static void POPUnGetChar( POParser * pop ) { if( pop->pos > 0 ) { pop->slen++; pop->s--; pop->pos--; } } /* Peek at next char */ static int POPPeekChar( POParser * pop ) { if( pop->slen > 0) { return pop->s[0]; } return 0; } #ifdef XXXX /* copy a simple alpha string */ static void POPeekString(POParser * p, char * s, int smax) { int c; int cnt = 0; int k = p->slen; smax--; s[0] = 0; while( k > 0 && cnt < smax ) { c = p->s[ cnt ]; if( c == 0 ) break; if( !isalpha(c) ) break; s[ cnt++ ] = c; s[ cnt ] = 0; k--; } } static void POGetString(POParser * p, char * s, int smax) { int c; int cnt = 0; smax--; s[0] = 0; while( p->slen > 0 && cnt < smax ) { c = p->s[ 0 ]; if( c == 0 ) break; if( !isalpha(c) ) break; s[ cnt++ ] = c; s[ cnt ] = 0; p->slen--; p->s++; } } #endif /* Skip whitespace : ' ', '\t', '\n' */ static int POPSkipSpace( POParser * p ) { int c; for( c = POPPeekChar(p); c != 0 ; c = POPPeekChar(p) ) { if( !isspace(c) && c != ',' ) return c; POPGetChar(p); } return 0; } /* Get the Port Object Name */ static char * POParserName( POParser * pop ) { int k = 0; int c; /* check if were done */ if( !pop || !pop->s || !*(pop->s) ) return 0; /* Start the name - skip space */ c = POPGetChar2(pop) ; if( !c ) return 0; if( c== '$' )/* skip leading '$' - old Var indicator */ { c = POPGetChar2(pop) ; if( !c ) return 0; } if( isalnum(c) ) { pop->token[k++] = (char)c; pop->token[k] = (char)0; } else { POPUnGetChar( pop ); return 0; /* not a name */ } for( c = POPGetChar(pop); c != 0 && k < POP_MAX_BUFFER_SIZE; c = POPGetChar(pop) ) { if( isalnum(c) || c== '_' || c=='-' || c=='.' ) { pop->token[k++] = (char)c; pop->token[k] = (char)0; } else { POPUnGetChar( pop ); break; } } DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,">>> POParserName : %s\n",pop->token);); return strdup(pop->token); } /* * Read an unsigned short (a port) */ static uint16_t POParserGetShort(POParser * pop) { int c; int k = 0; char buffer[32]; char * pend; POPSkipSpace(pop); buffer[0] = 0; while( (c = POPGetChar(pop)) != 0 ) { if( isdigit(c) ) { buffer[k++]=(char)c; buffer[k] =0; if( k == sizeof(buffer)-1 ) break; /* thats all that fits */ } else { if( c && ( c!= ':' && c != ' ' && c != ']' && c != ',' && c != '\t' && c != '\n' ) ) { pop->errflag = POPERR_NOT_A_NUMBER; return 0; } POPUnGetChar(pop); break; } } c = (int)strtoul(buffer,&pend,10); if(c > 65535 || c < 0) { pop->errflag = POPERR_BOUNDS; return 0; } DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"GetUNumber: %d\n",c);); return c; } static PortObject *_POParseVar(POParser *pop) { PortObject *pox; char *name; name = POParserName(pop); if(!name) { pop->pos++; pop->errflag = POPERR_NO_NAME; return NULL; } pox = PortVarTableFind(pop->pvTable, name); free(name); if(!pox) { pop->errflag = POPERR_BAD_VARIABLE; return NULL; } pox = PortObjectDup(pox); if(!pox) { pop->errflag = POPERR_MALLOC_FAILED; return NULL; } return pox; } /* * Sets the PORT_OBJECT_NOT_FLAG flag on each port object item in the list */ static void _PONegateList(PortObject *po) { PortObjectItem *poi; SF_LNODE * pos; if(!po) return; /* disable the NOT'd ports */ for(poi=(PortObjectItem*)sflist_firstpos(po->item_list,&pos); poi != 0; poi=(PortObjectItem*)sflist_nextpos(po->item_list,&pos) ) { poi->flags ^= PORT_OBJECT_NOT_FLAG; } } static PortObject *_POParsePort(POParser *pop) { uint16_t hport, lport; char c; PortObject *po = PortObjectNew(); if(!po) { pop->errflag = POPERR_MALLOC_FAILED; return NULL; } hport = MAXPORTS-1; pop->token[0]=0; /* The string in pop should only be of the form or : */ lport = POParserGetShort(pop); if(pop->errflag) { PortObjectFree(po); return NULL; } c = POPPeekChar(pop); if( c == ':' ) /* half open range */ { POPGetChar(pop); c = POPPeekChar(pop); if (((c == 0) && (pop->slen == 0)) || (c == ',')) { /* Open ended range, highport is 65k */ hport = MAXPORTS-1; PortObjectAddRange(po, lport, hport, 0); return po; } if( !isdigit((int)c) ) /* not a number */ { pop->errflag = POPERR_NOT_A_NUMBER; PortObjectFree(po); return NULL; } hport = POParserGetShort(pop); if( pop->errflag ) { PortObjectFree(po); return NULL; } if(lport > hport) { pop->errflag = POPERR_INVALID_RANGE; PortObjectFree(po); return NULL; } PortObjectAddRange(po, lport, hport, 0); } else { PortObjectAddPort(po, lport, 0); } return po; } static PortObject* _POParseString(POParser *pop) { PortObject * po; PortObject * potmp = NULL; int local_neg = 0; char c; int list_count = 0; po = PortObjectNew(); if(!po) { pop->errflag = POPERR_MALLOC_FAILED; return NULL; } while( (c = POPGetChar2(pop)) != 0 ) { if(c == '!') { local_neg = 1; continue; } if(c == '$') { /* Don't dup this again - the returned PortObject has already * been dup'ed */ potmp = _POParseVar(pop); } /* Start of a list. Tokenize list and recurse on it */ else if(c == '[') { POParser local_pop; char *tok; char *end; list_count++; if( (end = strrchr(pop->s, (int)']')) == NULL ) { pop->errflag = POPERR_NO_ENDLIST_BRACKET; PortObjectFree(po); return NULL; } if( (tok = SnortStrndup(pop->s, end - pop->s)) == NULL) { pop->errflag = POPERR_MALLOC_FAILED; PortObjectFree(po); return NULL; } POParserInit(&local_pop, tok, pop->pvTable); /* Recurse */ potmp = _POParseString(&local_pop); free(tok); if(!potmp) { pop->errflag = local_pop.errflag; PortObjectFree(po); return NULL; } /* Advance "cursor" to end of this list */ for(; c && pop->s != end; c = POPGetChar2(pop)) ; } else if(c == ']') { list_count--; if(list_count < 0) { pop->errflag = POPERR_EXTRA_BRACKET; PortObjectFree(po); return NULL; } continue; } else { POPUnGetChar(pop); potmp = _POParsePort(pop); } if(!potmp) { PortObjectFree(po); return NULL; } if(local_neg) { /* Note: this intentionally only sets the negation flag! */ /* The actual negation will take place when normalization is called */ _PONegateList(potmp); local_neg = 0; } if(PortObjectAddPortObject(po, potmp, &pop->errflag)) { PortObjectFree(po); PortObjectFree(potmp); return NULL; } if (potmp) { PortObjectFree(potmp); potmp = NULL; } } /* Check for mis-matched brackets */ if(list_count) { if(list_count > 0) pop->errflag = POPERR_NO_ENDLIST_BRACKET; else pop->errflag = POPERR_EXTRA_BRACKET; PortObjectFree(po); return NULL; } return po; } /* * PortObject : name value * PortObject : name [!][ value value value ... ] * * value : [!]port * [!]low-port[:high-port] * * inputs: * pvTable - PortVarTable to search for PortVar references in the current PortVar * pop - parsing structure * s - string with port object text * * nameflag - indicates a name must be present, this allows usage for * embedded rule or portvar declarations of portlists * returns: * (PortObject *) - a normalized version */ PortObject * PortObjectParseString ( PortVarTable * pvTable, POParser * pop, char * name, char * s , int nameflag ) { PortObject *po, *potmp; DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"PortObjectParseString: %s\n",s);); POParserInit( pop, s, pvTable ); po = PortObjectNew(); if(!po) { pop->errflag=POPERR_MALLOC_FAILED; return 0; } if( nameflag ) /* parse a name */ { po->name = POParserName( pop ); if(!po->name ) { pop->errflag=POPERR_NO_NAME; PortObjectFree(po); return 0; } } else { if( name ) po->name = SnortStrdup(name); else po->name = SnortStrdup("noname"); } // LogMessage("PortObjectParseString: po->name=%s\n",po->name); potmp = _POParseString(pop); if(!potmp) { PortObjectFree(po); return NULL; } PortObjectNormalize(potmp); if(PortObjectAddPortObject(po, potmp, &pop->errflag)) { PortObjectFree(po); PortObjectFree(potmp); return NULL; } PortObjectFree(potmp); return po; } char * PortObjectParseError( POParser * pop ) { switch( pop->errflag ) { case POPERR_NO_NAME: return "no name"; case POPERR_NO_ENDLIST_BRACKET: return "no end of list bracket." " Elements must be comma separated," " and no spaces may appear between" " brackets."; case POPERR_NOT_A_NUMBER: return "not a number"; case POPERR_EXTRA_BRACKET: return "extra list bracket"; case POPERR_NO_DATA: return "no data"; case POPERR_ADDITEM_FAILED: return "add item failed"; case POPERR_MALLOC_FAILED: return "mem alloc failed"; case POPERR_INVALID_RANGE: return "invalid port range"; case POPERR_DUPLICATE_ENTRY: return "duplicate ports in list"; case POPERR_BOUNDS: return "value out of bounds for a port"; case POPERR_BAD_VARIABLE: return "unrecognized variable"; default: break; } return "unknown POParse error"; } /* * * PORT VAR TABLE FUNCTIONS * */ /* * Create a PortVar Table * * The PortVar table used to store and lookup Named PortObjects */ PortVarTable * PortVarTableCreate(void) { PortObject * po; SFGHASH * h; /* * This is used during parsing of config, * so 1000 entries is ok, worst that happens is somewhat slower * config/rule processing. */ h = sfghash_new(1000,0,0,PortObjectFree); if( !h ) return 0; /* Create default port objects */ po = PortObjectNew(); if( !po ) { sfghash_delete(h); return 0; } /* Default has an ANY port */ PortObjectAddPortAny( po ); /* Add ANY to the table */ PortVarTableAdd( h, po ); return h; } /* * PortVarTableAdd() * * returns * -1 : error, no memory... * 0 : added * 1 : in table */ int PortVarTableAdd( PortVarTable * h, PortObject * po ) { int stat; stat = sfghash_add(h,po->name,po); if( stat == SFGHASH_INTABLE ) return 1; if( stat == SFGHASH_OK ) return 0; return -1; } PortObject * PortVarTableFind( PortVarTable * h, char * name ) { if (!h || !name) return NULL; return sfghash_find(h,name); } /* This deletes the table, the PortObjects and PortObjectItems, and rule list. */ int PortVarTableFree(PortVarTable * pvt) { if( pvt ) { sfghash_delete( pvt ); } return 0; } /* TEST DRIVER PorObjects use the follow creation strategy po = PortObjectNew(); PortObjectAddPort( po, 80, 0 ); PortObjectAddPort( po, 8080, 0 ); PortObjectAddPort( po, 8138, 0 ); PortTableAddObject( p, po, k++ ); PortVarTable just stores PorObjects by Name */ //#define MAIN_PORTOBJECT //char * sample1="http [ 80 8100:8200 !8150 ]"; //char * sample2="httpx [ !http 8120 ]"; #ifdef MAIN_PORTOBJECT int main( int argc, char ** argv ) { PortVarTable * pvTable; PortTable * p; PortObject * po; POParser pop; int i; int k=1; int debug=0; int names=1; int lrc =100; int lrp =20; char * portlist; for(i=1;ipt_lrc=lrc; // large rule count - primary for(i=1;i>Bogus PortObject Definition (pos=%d,errflag=%d)\n>>%s\n>>%*s\n", pop.pos,pop.errflag,PORTLISTS,pop.pos,"^"); continue; /* invalid parse - no port object to add */ } PortObjectPrint ( po ); if( PortVarTableAdd( pvTable, po ) ) /* requires a name : portlist http [ portlist ]*/ { LogMessage("error: named port var '%s' already in table \n",po->name); } // Lets test the lookup ... if( !PortVarTableFind(pvTable,po->name) ) { LogMessage("Could not find PortVar: %s\n",po->name); exit(0); } /* Assume each PortVar object has one rule and add it to the PortTable PortObjects that are defined in rules have no names and are not added to the PortVar table */ PortTableAddObject(p,po,k++/*rule id*/); } PortTableCompile( p ); //PortTablePrintRules( p ); //if(debug) PortTablePrintPortGroups( p ); //PortTablePrintPortPortObjects( p ); PortTableDumpPortRules( p ); LogMessage("\n"); LogMessage("#rule and port groups compiled successfully\n"); return 0; } #endif snort-2.9.15.1/src/sfutil/sfportobject.h0000644000175200017520000002713713571422607015034 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2005-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* sfportobject.h Port List Object Management author: marc norton Hierarchy: PortTable -> PortObject's PortVar -> PortObject PortObject -> PortObjectItems (port or port range) */ #ifndef SFPORTOBJECT_H #define SFPORTOBJECT_H #include "sflsq.h" #include "sfghash.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #define SFPO_MAX_LPORTS 500 #define SFPO_MAX_PORTS 65536 typedef SFGHASH PortVarTable; /* * PortObjectItem Flags */ #define PORT_OBJECT_NOT_FLAG 1 #define PORT_OBJECT_PORT 1 #define PORT_OBJECT_RANGE 2 #define PORT_OBJECT_ANY 3 /* * Port Object Item supports * port, lowport:highport, portlist */ typedef struct _PortObjectItem_s { int type; /* ANY, RANGE, PORT */ int flags; /* NOT */ uint16_t hport; /* hi port */ uint16_t lport; /* lo port */ uint16_t cur_port; /* internal - first/next */ uint16_t tmp; }PortObjectItem; /* * PortObject supports a set of PortObjectItems * * A Port Set may include one or more of the following * Port * Port Range * List of Ports mixed with Port Ranges */ #include "bitop_funcs.h" typedef struct { /* not used yet */ char * name; /* user name - always use strdup or malloc for this*/ SF_LIST * item_list; /* list of port and port-range items */ }PortList_x; typedef struct { char * name; /* user name - always use strdup or malloc for this*/ int id; /* internal tracking - compiling sets this value */ SF_LIST * item_list; /* list of port and port-range items */ SF_LIST * rule_list; /* list of rules */ void * data; /* user data, PORT_GROUP based on rule_list - only used by any-any ports */ void (*data_free)(void *); }PortObject; typedef struct { char * name; /* user name - always use strdup or malloc for this*/ int id; /* internal tracking - compiling sets this value */ SF_LIST * item_list; /* list of port and port-range items */ SFGHASH * rule_hash; /* hash of rule (rule-indexes) in use */ int port_cnt; /* count of ports using this object */ BITOP * bitop; /* for collecting ports that use this object */ void * data; /* user data, PORT_GROUP based on rule_hash */ void (*data_free)(void *); }PortObject2; /* Port Table */ typedef struct _PortTable_s { /* turns on group optimization, better speed-but more memory * otherwise a single merged rule group is used. */ int pt_optimize; /* save the users input port objects in this list * rules may be added after creation of a port object * but the ports are not modified. */ SF_LIST * pt_polist; int pt_poid; /* * Array of lists of PortObject pointers to unique PortObjects, * the associated rule lists are stored in Data elements in rh, * the keys are the address of the PortObjects */ SF_LIST * pt_port_lists[SFPO_MAX_PORTS]; /* Compiled / merged port object hash table */ SFGHASH * pt_mpo_hash; SFGHASH * pt_mpxo_hash; SF_LIST * pt_plx_list; /* a single rule list with all rules merged together */ SF_LIST * pt_merged_rule_list; /* * Final Port/Rule Groupings, one port object per port, or null */ PortObject2 * pt_port_object[SFPO_MAX_PORTS]; int pt_lrc; /* large rule count, this many rules is a large group */ /* Stats */ int single_merges; /* single PortObject on a port */ int small_merges; /* small port objects merged into a bigger object */ int large_single_merges; /* 1 large + some small objects */ int large_multi_merges; /* >1 large object merged + some small objects */ int non_opt_merges; }PortTable; typedef struct { PortTable * tcp_src, * tcp_dst; PortTable * udp_src, * udp_dst; PortTable * icmp_src,* icmp_dst; PortTable * ip_src, * ip_dst; #ifdef TARGET_BASED PortTable * ns_tcp_src, * ns_tcp_dst; PortTable * ns_udp_src, * ns_udp_dst; PortTable * ns_icmp_src,* ns_icmp_dst; PortTable * ns_ip_src, * ns_ip_dst; #endif PortObject * tcp_anyany; PortObject * udp_anyany; PortObject * icmp_anyany; PortObject * ip_anyany; PortObject * tcp_nocontent; PortObject * udp_nocontent; PortObject * icmp_nocontent; PortObject * ip_nocontent; }rule_port_tables_t; #define POPERR_NO_NAME 1 #define POPERR_NO_ENDLIST_BRACKET 2 #define POPERR_NOT_A_NUMBER 3 #define POPERR_EXTRA_BRACKET 4 #define POPERR_NO_DATA 5 #define POPERR_ADDITEM_FAILED 6 #define POPERR_MALLOC_FAILED 7 #define POPERR_INVALID_RANGE 8 #define POPERR_DUPLICATE_ENTRY 9 #define POPERR_BOUNDS 10 #define POPERR_BAD_VARIABLE 11 #define POP_MAX_BUFFER_SIZE 256 typedef struct { char * s; /* current string pointer */ int slen; /* bytes left in string */ int pos; /* position in string of last GetChar() */ char token[POP_MAX_BUFFER_SIZE+4]; /* single number, or range, or not flag */ int errflag; /* for handling PortObject references when parsing */ PortObject * po_ref; SF_LNODE * poi_pos; PortVarTable * pvTable; }POParser; /* Prototypes */ /* * Port List Table * * The PortTable provides support to analyze the Port List objects defined by * the user as either PortVar entries or simply as inline rule port * list declarations. */ PortTable * PortTableNew (void); void PortTableFree( PortTable *p ); int PortTableAddObject( PortTable *p, PortObject * po ); int PortTableAddObjectRaw( PortTable *p, PortObject * po ); int PortTableAddRule ( PortTable * p, int port, int rule ); int PortTableCompile ( PortTable * P); void PortTablePrintInputEx( PortTable * p, void (*rule_index_map_print)(int index, char *buf, int bufsize) ); int PortTablePrintCompiledEx( PortTable * p, void (*rule_index_map_print)(int index, char *buf, int bufsize) ); PortObject * PortTableFindPortObjectByPort( PortTable * pt , int port ); PortObject * PortTableFindInputPortObjectName(PortTable * pt, char * po_name); PortObject * PortTableFindInputPortObjectPorts( PortTable * pt , PortObject * po ); /* Port List Object */ PortObject * PortObjectNew ( void ); PortObject2 * PortObject2New (int nrules/*guess at this */); void PortObjectFree ( void * p ); void PortObject2Free ( void * p ); int PortObjectSetName ( PortObject * po, char * name ); PortObjectItem * PortObjectItemNew ( void ); PortObjectItem * PortObjectItemDup ( PortObjectItem * poi ); void PortObjectItemFree ( PortObjectItem * poi ); int PortObjectAddItem ( PortObject * po, PortObjectItem * poi, int *errflag); int PortObjectAddPortObject ( PortObject * podst, PortObject * posrc, int *errflag); int PortObjectAddPort ( PortObject * po, int port, int not_flag ); int PortObjectAddRange ( PortObject * po, int lport, int hport, int not_flag ); int PortObjectAddRule ( PortObject * po, int rule ); int PortObjectAddPortAny ( PortObject * po ); PortObject * PortObjectDup ( PortObject * po ); PortObject2 * PortObject2Dup ( PortObject * po ); PortObject * PortObjectDupPorts ( PortObject * po ); int * PortObjectExtractRuleArray( PortObject * po, int * nrules ); int * PortObject2ExtractRuleArray( PortObject2 * po, int * nrules ); int PortObjectNormalize ( PortObject * po ); int PortObjectNegate ( PortObject * po ); int PortObjectEqual ( PortObject * poa, PortObject * bob ); void PortObjectSetAny ( PortObject * po ); int PortObjectPortCount ( PortObject * po ); int PortObjectHasPort ( PortObject * po, int port ); int PortObjectHasNot ( PortObject * po ); int PortObjectIsPureNot ( PortObject * po ); int PortObjectHasAny ( PortObject * po ); int PortObjectIncludesPort(PortObject * po, int port ); char * PortObjectCharPortArray ( char * parray, PortObject * po, int * nports ); int PortObjectRemovePorts( PortObject * a, PortObject * b ); PortObject * PortObjectAppend(PortObject * poa, PortObject * pob ); PortObject * PortObjectAppendPortObject(PortObject * poa, PortObject * pob ); PortObject2 * PortObject2AppendPortObject(PortObject2 * poa, PortObject * pob ); PortObject2 * PortObject2AppendPortObject2(PortObject2 * poa, PortObject2 * pob ); PortObject * PortObjectAppendEx(PortObject * poa, PortObject * pob ); PortObject2 * PortObjectAppendEx2(PortObject2 * poa, PortObject * pob ); int PortTableNormalizeInputPortObjects( PortTable *p ); int PortTableCompileMergePortObjects( PortTable * p ); int PortTableConsistencyCheck( PortTable *p ); void PortTablePrintInput( PortTable * p ); void PortTablePrintUserRules( PortTable * p ); void PortTablePrintPortGroups( PortTable * p ); void PortTablePrintPortPortObjects( PortTable * p ); int PortVarTableFree(PortVarTable * pvt); void PortObjectPrint ( PortObject * po ); void PortObjectPrintPorts ( PortObject * po ); void PortObjectPrintPortsRaw(PortObject * po ); void PortObject2PrintPorts ( PortObject2 * po ); void PortObject2Print ( PortObject2 * po ); int PortObjectPrintDetails( PortObject * po ); void PortObjectPrintEx(PortObject * po, void (*print_index_map)(int index, char *buf, int bufsize) ); void PortObject2PrintEx(PortObject2 * po, void (*print_index_map)(int index, char *buf, int bufsize) ); void PortTableSortUniqRules( PortTable * p ); void RuleListSortUniq( SF_LIST * rl ); /* PortVarTable port lists may be defined as 'name port-list' */ PortVarTable * PortVarTableCreate (void); int PortVarTableAdd ( PortVarTable * pvt, PortObject * po ); PortObject * PortVarTableFind ( PortVarTable * pvt, char * name ); /* PortVars are internally stored in PortObjects This function parses PortVar strings into PortObjects */ PortObject * PortObjectParseString ( PortVarTable * pvTable, POParser * pop,char * name, char * s,int nameflag ); char * PortObjectParseError( POParser * p ); #endif snort-2.9.15.1/src/sfutil/sfrim.c0000644000175200017520000000653213571422607013437 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2005-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* * sfrim.c * * Rule Index Map * * author: marc norton * */ #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sfrim.h" /* * Return Sid associated with index * author: marc norton */ unsigned RuleIndexMapSid( rule_index_map_t * map, int index ) { if( ! map ) return 0; if( index < map->num_rules ) { return map->map[index].sid; } return 0; } /* * Return Gid associated with index * author: marc norton */ unsigned RuleIndexMapGid(rule_index_map_t * map, int index ) { if( ! map ) { return 0; } if( index < map->num_rules ) { return map->map[index].gid; } return 0; } /* * Create a rule index map table * author: marc norton */ rule_index_map_t * RuleIndexMapCreate( int max_rules ) { rule_index_map_t *p = calloc( 1, sizeof(rule_index_map_t) ); if(!p) { return 0; } p->max_rules=max_rules; p->num_rules=0; p->map = calloc( max_rules, sizeof(rule_number_t)); if(!p->map ) { free(p); return 0; } return p; } /* * Free a rule index map table * author: marc norton */ void RuleIndexMapFree( rule_index_map_t ** p ) { if( !p || !*p ) { return ; } if( (*p)->map ) { free((*p)->map); } free( *p ); *p = 0; } /* * Add a rule to a rule index map table * author: marc norton */ int RuleIndexMapAdd( rule_index_map_t * p, unsigned gid, unsigned sid ) { int index; if( !p ) { return -1; } if( p->num_rules == (p->max_rules - 1) ) { return -1; } index = p->num_rules ; p->map[ index ].gid = gid; p->map[ index ].sid = sid; p->num_rules++; //printf("RuleIndexMapping: index=%d gid=%u sid=%u\n",index,gid,sid); return index; } /* * print a rule index map table to stdout * author: marc norton */ void print_rule_index_map( rule_index_map_t * p ) { int i; printf("***\n*** Rule Index Map (%d entries)\n***\n",p->num_rules); for(i=0;inum_rules;i++) { printf("rule-index-map[%d] { gid:%u sid:%u }\n",i,p->map[i].gid,p->map[i].sid); } printf("***end rule index map ***\n"); } snort-2.9.15.1/src/sfutil/sfrim.h0000644000175200017520000000143013571422607013434 00000000000000/* * sfrim.h * * Rule Index Map * * author: marc norton * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2005-2013 Sourcefire, Inc. */ #ifndef SFRIM_H #define SFRIM_H typedef struct { unsigned gid; unsigned sid; }rule_number_t; typedef struct { int max_rules; int num_rules; rule_number_t * map; }rule_index_map_t; unsigned RuleIndexMapSid( rule_index_map_t * map, int index ); unsigned RuleIndexMapGid( rule_index_map_t * map, int index ); rule_index_map_t * RuleIndexMapCreate( int max_rules ); void RuleIndexMapFree( rule_index_map_t ** p ); int RuleIndexMapAdd( rule_index_map_t * p, unsigned gid, unsigned sid ); extern void rule_index_map_print_index( int index, char *buf, int ); #endif snort-2.9.15.1/src/sfutil/sfprimetable.c0000644000175200017520000026120713571422607014776 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2006-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* * sfprimetable.c * * Prime number calculation via Table lookups. * * This was implemented for use with the hasing functions * in sfghash, and sfxhash. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sfprimetable.h" /* 0-8K, increments=8 */ static unsigned prime_table0[1024]={ 3, /* 1 */ 7, /* 9 */ 17, /* 17 */ 23, /* 25 */ 31, /* 33 */ 41, /* 41 */ 47, /* 49 */ 53, /* 57 */ 61, /* 65 */ 73, /* 73 */ 79, /* 81 */ 89, /* 89 */ 97, /* 97 */ 103, /* 105 */ 113, /* 113 */ 113, /* 121 */ 127, /* 129 */ 137, /* 137 */ 139, /* 145 */ 151, /* 153 */ 157, /* 161 */ 167, /* 169 */ 173, /* 177 */ 181, /* 185 */ 193, /* 193 */ 199, /* 201 */ 199, /* 209 */ 211, /* 217 */ 223, /* 225 */ 233, /* 233 */ 241, /* 241 */ 241, /* 249 */ 257, /* 257 */ 263, /* 265 */ 271, /* 273 */ 281, /* 281 */ 283, /* 289 */ 293, /* 297 */ 293, /* 305 */ 313, /* 313 */ 317, /* 321 */ 317, /* 329 */ 337, /* 337 */ 337, /* 345 */ 353, /* 353 */ 359, /* 361 */ 367, /* 369 */ 373, /* 377 */ 383, /* 385 */ 389, /* 393 */ 401, /* 401 */ 409, /* 409 */ 409, /* 417 */ 421, /* 425 */ 433, /* 433 */ 439, /* 441 */ 449, /* 449 */ 457, /* 457 */ 463, /* 465 */ 467, /* 473 */ 479, /* 481 */ 487, /* 489 */ 491, /* 497 */ 503, /* 505 */ 509, /* 513 */ 521, /* 521 */ 523, /* 529 */ 523, /* 537 */ 541, /* 545 */ 547, /* 553 */ 557, /* 561 */ 569, /* 569 */ 577, /* 577 */ 577, /* 585 */ 593, /* 593 */ 601, /* 601 */ 607, /* 609 */ 617, /* 617 */ 619, /* 625 */ 631, /* 633 */ 641, /* 641 */ 647, /* 649 */ 653, /* 657 */ 661, /* 665 */ 673, /* 673 */ 677, /* 681 */ 683, /* 689 */ 691, /* 697 */ 701, /* 705 */ 709, /* 713 */ 719, /* 721 */ 727, /* 729 */ 733, /* 737 */ 743, /* 745 */ 751, /* 753 */ 761, /* 761 */ 769, /* 769 */ 773, /* 777 */ 773, /* 785 */ 787, /* 793 */ 797, /* 801 */ 809, /* 809 */ 811, /* 817 */ 823, /* 825 */ 829, /* 833 */ 839, /* 841 */ 839, /* 849 */ 857, /* 857 */ 863, /* 865 */ 863, /* 873 */ 881, /* 881 */ 887, /* 889 */ 887, /* 897 */ 887, /* 905 */ 911, /* 913 */ 919, /* 921 */ 929, /* 929 */ 937, /* 937 */ 941, /* 945 */ 953, /* 953 */ 953, /* 961 */ 967, /* 969 */ 977, /* 977 */ 983, /* 985 */ 991, /* 993 */ 997, /* 1001 */ 1009, /* 1009 */ 1013, /* 1017 */ 1021, /* 1025 */ 1033, /* 1033 */ 1039, /* 1041 */ 1049, /* 1049 */ 1051, /* 1057 */ 1063, /* 1065 */ 1069, /* 1073 */ 1069, /* 1081 */ 1087, /* 1089 */ 1097, /* 1097 */ 1103, /* 1105 */ 1109, /* 1113 */ 1117, /* 1121 */ 1129, /* 1129 */ 1129, /* 1137 */ 1129, /* 1145 */ 1153, /* 1153 */ 1153, /* 1161 */ 1163, /* 1169 */ 1171, /* 1177 */ 1181, /* 1185 */ 1193, /* 1193 */ 1201, /* 1201 */ 1201, /* 1209 */ 1217, /* 1217 */ 1223, /* 1225 */ 1231, /* 1233 */ 1237, /* 1241 */ 1249, /* 1249 */ 1249, /* 1257 */ 1259, /* 1265 */ 1259, /* 1273 */ 1279, /* 1281 */ 1289, /* 1289 */ 1297, /* 1297 */ 1303, /* 1305 */ 1307, /* 1313 */ 1321, /* 1321 */ 1327, /* 1329 */ 1327, /* 1337 */ 1327, /* 1345 */ 1327, /* 1353 */ 1361, /* 1361 */ 1367, /* 1369 */ 1373, /* 1377 */ 1381, /* 1385 */ 1381, /* 1393 */ 1399, /* 1401 */ 1409, /* 1409 */ 1409, /* 1417 */ 1423, /* 1425 */ 1433, /* 1433 */ 1439, /* 1441 */ 1447, /* 1449 */ 1453, /* 1457 */ 1459, /* 1465 */ 1471, /* 1473 */ 1481, /* 1481 */ 1489, /* 1489 */ 1493, /* 1497 */ 1499, /* 1505 */ 1511, /* 1513 */ 1511, /* 1521 */ 1523, /* 1529 */ 1531, /* 1537 */ 1543, /* 1545 */ 1553, /* 1553 */ 1559, /* 1561 */ 1567, /* 1569 */ 1571, /* 1577 */ 1583, /* 1585 */ 1583, /* 1593 */ 1601, /* 1601 */ 1609, /* 1609 */ 1613, /* 1617 */ 1621, /* 1625 */ 1627, /* 1633 */ 1637, /* 1641 */ 1637, /* 1649 */ 1657, /* 1657 */ 1663, /* 1665 */ 1669, /* 1673 */ 1669, /* 1681 */ 1669, /* 1689 */ 1697, /* 1697 */ 1699, /* 1705 */ 1709, /* 1713 */ 1721, /* 1721 */ 1723, /* 1729 */ 1733, /* 1737 */ 1741, /* 1745 */ 1753, /* 1753 */ 1759, /* 1761 */ 1759, /* 1769 */ 1777, /* 1777 */ 1783, /* 1785 */ 1789, /* 1793 */ 1801, /* 1801 */ 1801, /* 1809 */ 1811, /* 1817 */ 1823, /* 1825 */ 1831, /* 1833 */ 1831, /* 1841 */ 1847, /* 1849 */ 1847, /* 1857 */ 1861, /* 1865 */ 1873, /* 1873 */ 1879, /* 1881 */ 1889, /* 1889 */ 1889, /* 1897 */ 1901, /* 1905 */ 1913, /* 1913 */ 1913, /* 1921 */ 1913, /* 1929 */ 1933, /* 1937 */ 1933, /* 1945 */ 1951, /* 1953 */ 1951, /* 1961 */ 1951, /* 1969 */ 1973, /* 1977 */ 1979, /* 1985 */ 1993, /* 1993 */ 1999, /* 2001 */ 2003, /* 2009 */ 2017, /* 2017 */ 2017, /* 2025 */ 2029, /* 2033 */ 2039, /* 2041 */ 2039, /* 2049 */ 2053, /* 2057 */ 2063, /* 2065 */ 2069, /* 2073 */ 2081, /* 2081 */ 2089, /* 2089 */ 2089, /* 2097 */ 2099, /* 2105 */ 2113, /* 2113 */ 2113, /* 2121 */ 2129, /* 2129 */ 2137, /* 2137 */ 2143, /* 2145 */ 2153, /* 2153 */ 2161, /* 2161 */ 2161, /* 2169 */ 2161, /* 2177 */ 2179, /* 2185 */ 2179, /* 2193 */ 2179, /* 2201 */ 2207, /* 2209 */ 2213, /* 2217 */ 2221, /* 2225 */ 2221, /* 2233 */ 2239, /* 2241 */ 2243, /* 2249 */ 2251, /* 2257 */ 2251, /* 2265 */ 2273, /* 2273 */ 2281, /* 2281 */ 2287, /* 2289 */ 2297, /* 2297 */ 2297, /* 2305 */ 2311, /* 2313 */ 2311, /* 2321 */ 2311, /* 2329 */ 2333, /* 2337 */ 2341, /* 2345 */ 2351, /* 2353 */ 2357, /* 2361 */ 2357, /* 2369 */ 2377, /* 2377 */ 2383, /* 2385 */ 2393, /* 2393 */ 2399, /* 2401 */ 2399, /* 2409 */ 2417, /* 2417 */ 2423, /* 2425 */ 2423, /* 2433 */ 2441, /* 2441 */ 2447, /* 2449 */ 2447, /* 2457 */ 2459, /* 2465 */ 2473, /* 2473 */ 2477, /* 2481 */ 2477, /* 2489 */ 2477, /* 2497 */ 2503, /* 2505 */ 2503, /* 2513 */ 2521, /* 2521 */ 2521, /* 2529 */ 2531, /* 2537 */ 2543, /* 2545 */ 2551, /* 2553 */ 2557, /* 2561 */ 2557, /* 2569 */ 2557, /* 2577 */ 2579, /* 2585 */ 2593, /* 2593 */ 2593, /* 2601 */ 2609, /* 2609 */ 2617, /* 2617 */ 2621, /* 2625 */ 2633, /* 2633 */ 2633, /* 2641 */ 2647, /* 2649 */ 2657, /* 2657 */ 2663, /* 2665 */ 2671, /* 2673 */ 2677, /* 2681 */ 2689, /* 2689 */ 2693, /* 2697 */ 2699, /* 2705 */ 2713, /* 2713 */ 2719, /* 2721 */ 2729, /* 2729 */ 2731, /* 2737 */ 2741, /* 2745 */ 2753, /* 2753 */ 2753, /* 2761 */ 2767, /* 2769 */ 2777, /* 2777 */ 2777, /* 2785 */ 2791, /* 2793 */ 2801, /* 2801 */ 2803, /* 2809 */ 2803, /* 2817 */ 2819, /* 2825 */ 2833, /* 2833 */ 2837, /* 2841 */ 2843, /* 2849 */ 2857, /* 2857 */ 2861, /* 2865 */ 2861, /* 2873 */ 2879, /* 2881 */ 2887, /* 2889 */ 2897, /* 2897 */ 2903, /* 2905 */ 2909, /* 2913 */ 2917, /* 2921 */ 2927, /* 2929 */ 2927, /* 2937 */ 2939, /* 2945 */ 2953, /* 2953 */ 2957, /* 2961 */ 2969, /* 2969 */ 2971, /* 2977 */ 2971, /* 2985 */ 2971, /* 2993 */ 3001, /* 3001 */ 3001, /* 3009 */ 3011, /* 3017 */ 3023, /* 3025 */ 3023, /* 3033 */ 3041, /* 3041 */ 3049, /* 3049 */ 3049, /* 3057 */ 3061, /* 3065 */ 3067, /* 3073 */ 3079, /* 3081 */ 3089, /* 3089 */ 3089, /* 3097 */ 3089, /* 3105 */ 3109, /* 3113 */ 3121, /* 3121 */ 3121, /* 3129 */ 3137, /* 3137 */ 3137, /* 3145 */ 3137, /* 3153 */ 3137, /* 3161 */ 3169, /* 3169 */ 3169, /* 3177 */ 3181, /* 3185 */ 3191, /* 3193 */ 3191, /* 3201 */ 3209, /* 3209 */ 3217, /* 3217 */ 3221, /* 3225 */ 3229, /* 3233 */ 3229, /* 3241 */ 3229, /* 3249 */ 3257, /* 3257 */ 3259, /* 3265 */ 3271, /* 3273 */ 3271, /* 3281 */ 3271, /* 3289 */ 3271, /* 3297 */ 3301, /* 3305 */ 3313, /* 3313 */ 3319, /* 3321 */ 3329, /* 3329 */ 3331, /* 3337 */ 3343, /* 3345 */ 3347, /* 3353 */ 3361, /* 3361 */ 3361, /* 3369 */ 3373, /* 3377 */ 3373, /* 3385 */ 3391, /* 3393 */ 3391, /* 3401 */ 3407, /* 3409 */ 3413, /* 3417 */ 3413, /* 3425 */ 3433, /* 3433 */ 3433, /* 3441 */ 3449, /* 3449 */ 3457, /* 3457 */ 3463, /* 3465 */ 3469, /* 3473 */ 3469, /* 3481 */ 3469, /* 3489 */ 3491, /* 3497 */ 3499, /* 3505 */ 3511, /* 3513 */ 3517, /* 3521 */ 3529, /* 3529 */ 3533, /* 3537 */ 3541, /* 3545 */ 3547, /* 3553 */ 3559, /* 3561 */ 3559, /* 3569 */ 3571, /* 3577 */ 3583, /* 3585 */ 3593, /* 3593 */ 3593, /* 3601 */ 3607, /* 3609 */ 3617, /* 3617 */ 3623, /* 3625 */ 3631, /* 3633 */ 3637, /* 3641 */ 3643, /* 3649 */ 3643, /* 3657 */ 3659, /* 3665 */ 3673, /* 3673 */ 3677, /* 3681 */ 3677, /* 3689 */ 3697, /* 3697 */ 3701, /* 3705 */ 3709, /* 3713 */ 3719, /* 3721 */ 3727, /* 3729 */ 3733, /* 3737 */ 3739, /* 3745 */ 3739, /* 3753 */ 3761, /* 3761 */ 3769, /* 3769 */ 3769, /* 3777 */ 3779, /* 3785 */ 3793, /* 3793 */ 3797, /* 3801 */ 3803, /* 3809 */ 3803, /* 3817 */ 3823, /* 3825 */ 3833, /* 3833 */ 3833, /* 3841 */ 3847, /* 3849 */ 3853, /* 3857 */ 3863, /* 3865 */ 3863, /* 3873 */ 3881, /* 3881 */ 3889, /* 3889 */ 3889, /* 3897 */ 3889, /* 3905 */ 3911, /* 3913 */ 3919, /* 3921 */ 3929, /* 3929 */ 3931, /* 3937 */ 3943, /* 3945 */ 3947, /* 3953 */ 3947, /* 3961 */ 3967, /* 3969 */ 3967, /* 3977 */ 3967, /* 3985 */ 3989, /* 3993 */ 4001, /* 4001 */ 4007, /* 4009 */ 4013, /* 4017 */ 4021, /* 4025 */ 4027, /* 4033 */ 4027, /* 4041 */ 4049, /* 4049 */ 4057, /* 4057 */ 4057, /* 4065 */ 4073, /* 4073 */ 4079, /* 4081 */ 4079, /* 4089 */ 4093, /* 4097 */ 4099, /* 4105 */ 4111, /* 4113 */ 4111, /* 4121 */ 4129, /* 4129 */ 4133, /* 4137 */ 4139, /* 4145 */ 4153, /* 4153 */ 4159, /* 4161 */ 4159, /* 4169 */ 4177, /* 4177 */ 4177, /* 4185 */ 4177, /* 4193 */ 4201, /* 4201 */ 4201, /* 4209 */ 4217, /* 4217 */ 4219, /* 4225 */ 4231, /* 4233 */ 4241, /* 4241 */ 4243, /* 4249 */ 4253, /* 4257 */ 4261, /* 4265 */ 4273, /* 4273 */ 4273, /* 4281 */ 4289, /* 4289 */ 4297, /* 4297 */ 4297, /* 4305 */ 4297, /* 4313 */ 4297, /* 4321 */ 4327, /* 4329 */ 4337, /* 4337 */ 4339, /* 4345 */ 4349, /* 4353 */ 4357, /* 4361 */ 4363, /* 4369 */ 4373, /* 4377 */ 4373, /* 4385 */ 4391, /* 4393 */ 4397, /* 4401 */ 4409, /* 4409 */ 4409, /* 4417 */ 4423, /* 4425 */ 4423, /* 4433 */ 4441, /* 4441 */ 4447, /* 4449 */ 4457, /* 4457 */ 4463, /* 4465 */ 4463, /* 4473 */ 4481, /* 4481 */ 4483, /* 4489 */ 4493, /* 4497 */ 4493, /* 4505 */ 4513, /* 4513 */ 4519, /* 4521 */ 4523, /* 4529 */ 4523, /* 4537 */ 4523, /* 4545 */ 4549, /* 4553 */ 4561, /* 4561 */ 4567, /* 4569 */ 4567, /* 4577 */ 4583, /* 4585 */ 4591, /* 4593 */ 4597, /* 4601 */ 4603, /* 4609 */ 4603, /* 4617 */ 4621, /* 4625 */ 4621, /* 4633 */ 4639, /* 4641 */ 4649, /* 4649 */ 4657, /* 4657 */ 4663, /* 4665 */ 4673, /* 4673 */ 4679, /* 4681 */ 4679, /* 4689 */ 4691, /* 4697 */ 4703, /* 4705 */ 4703, /* 4713 */ 4721, /* 4721 */ 4729, /* 4729 */ 4733, /* 4737 */ 4733, /* 4745 */ 4751, /* 4753 */ 4759, /* 4761 */ 4759, /* 4769 */ 4759, /* 4777 */ 4783, /* 4785 */ 4793, /* 4793 */ 4801, /* 4801 */ 4801, /* 4809 */ 4817, /* 4817 */ 4817, /* 4825 */ 4831, /* 4833 */ 4831, /* 4841 */ 4831, /* 4849 */ 4831, /* 4857 */ 4861, /* 4865 */ 4871, /* 4873 */ 4877, /* 4881 */ 4889, /* 4889 */ 4889, /* 4897 */ 4903, /* 4905 */ 4909, /* 4913 */ 4919, /* 4921 */ 4919, /* 4929 */ 4937, /* 4937 */ 4943, /* 4945 */ 4951, /* 4953 */ 4957, /* 4961 */ 4969, /* 4969 */ 4973, /* 4977 */ 4973, /* 4985 */ 4993, /* 4993 */ 4999, /* 5001 */ 5009, /* 5009 */ 5011, /* 5017 */ 5023, /* 5025 */ 5023, /* 5033 */ 5039, /* 5041 */ 5039, /* 5049 */ 5051, /* 5057 */ 5059, /* 5065 */ 5059, /* 5073 */ 5081, /* 5081 */ 5087, /* 5089 */ 5087, /* 5097 */ 5101, /* 5105 */ 5113, /* 5113 */ 5119, /* 5121 */ 5119, /* 5129 */ 5119, /* 5137 */ 5119, /* 5145 */ 5153, /* 5153 */ 5153, /* 5161 */ 5167, /* 5169 */ 5171, /* 5177 */ 5179, /* 5185 */ 5189, /* 5193 */ 5197, /* 5201 */ 5209, /* 5209 */ 5209, /* 5217 */ 5209, /* 5225 */ 5233, /* 5233 */ 5237, /* 5241 */ 5237, /* 5249 */ 5237, /* 5257 */ 5261, /* 5265 */ 5273, /* 5273 */ 5281, /* 5281 */ 5281, /* 5289 */ 5297, /* 5297 */ 5303, /* 5305 */ 5309, /* 5313 */ 5309, /* 5321 */ 5323, /* 5329 */ 5333, /* 5337 */ 5333, /* 5345 */ 5351, /* 5353 */ 5351, /* 5361 */ 5351, /* 5369 */ 5351, /* 5377 */ 5381, /* 5385 */ 5393, /* 5393 */ 5399, /* 5401 */ 5407, /* 5409 */ 5417, /* 5417 */ 5419, /* 5425 */ 5431, /* 5433 */ 5441, /* 5441 */ 5449, /* 5449 */ 5449, /* 5457 */ 5449, /* 5465 */ 5471, /* 5473 */ 5479, /* 5481 */ 5483, /* 5489 */ 5483, /* 5497 */ 5503, /* 5505 */ 5507, /* 5513 */ 5521, /* 5521 */ 5527, /* 5529 */ 5531, /* 5537 */ 5531, /* 5545 */ 5531, /* 5553 */ 5557, /* 5561 */ 5569, /* 5569 */ 5573, /* 5577 */ 5581, /* 5585 */ 5591, /* 5593 */ 5591, /* 5601 */ 5591, /* 5609 */ 5591, /* 5617 */ 5623, /* 5625 */ 5623, /* 5633 */ 5641, /* 5641 */ 5647, /* 5649 */ 5657, /* 5657 */ 5659, /* 5665 */ 5669, /* 5673 */ 5669, /* 5681 */ 5689, /* 5689 */ 5693, /* 5697 */ 5701, /* 5705 */ 5711, /* 5713 */ 5717, /* 5721 */ 5717, /* 5729 */ 5737, /* 5737 */ 5743, /* 5745 */ 5749, /* 5753 */ 5749, /* 5761 */ 5749, /* 5769 */ 5749, /* 5777 */ 5783, /* 5785 */ 5791, /* 5793 */ 5801, /* 5801 */ 5807, /* 5809 */ 5813, /* 5817 */ 5821, /* 5825 */ 5827, /* 5833 */ 5839, /* 5841 */ 5849, /* 5849 */ 5857, /* 5857 */ 5861, /* 5865 */ 5869, /* 5873 */ 5881, /* 5881 */ 5881, /* 5889 */ 5897, /* 5897 */ 5903, /* 5905 */ 5903, /* 5913 */ 5903, /* 5921 */ 5927, /* 5929 */ 5927, /* 5937 */ 5939, /* 5945 */ 5953, /* 5953 */ 5953, /* 5961 */ 5953, /* 5969 */ 5953, /* 5977 */ 5981, /* 5985 */ 5987, /* 5993 */ 5987, /* 6001 */ 6007, /* 6009 */ 6011, /* 6017 */ 6011, /* 6025 */ 6029, /* 6033 */ 6037, /* 6041 */ 6047, /* 6049 */ 6053, /* 6057 */ 6053, /* 6065 */ 6073, /* 6073 */ 6079, /* 6081 */ 6089, /* 6089 */ 6091, /* 6097 */ 6101, /* 6105 */ 6113, /* 6113 */ 6121, /* 6121 */ 6121, /* 6129 */ 6133, /* 6137 */ 6143, /* 6145 */ 6151, /* 6153 */ 6151, /* 6161 */ 6163, /* 6169 */ 6173, /* 6177 */ 6173, /* 6185 */ 6173, /* 6193 */ 6199, /* 6201 */ 6203, /* 6209 */ 6217, /* 6217 */ 6221, /* 6225 */ 6229, /* 6233 */ 6229, /* 6241 */ 6247, /* 6249 */ 6257, /* 6257 */ 6263, /* 6265 */ 6271, /* 6273 */ 6277, /* 6281 */ 6287, /* 6289 */ 6287, /* 6297 */ 6301, /* 6305 */ 6311, /* 6313 */ 6317, /* 6321 */ 6329, /* 6329 */ 6337, /* 6337 */ 6343, /* 6345 */ 6353, /* 6353 */ 6361, /* 6361 */ 6367, /* 6369 */ 6373, /* 6377 */ 6379, /* 6385 */ 6389, /* 6393 */ 6397, /* 6401 */ 6397, /* 6409 */ 6397, /* 6417 */ 6421, /* 6425 */ 6427, /* 6433 */ 6427, /* 6441 */ 6449, /* 6449 */ 6451, /* 6457 */ 6451, /* 6465 */ 6473, /* 6473 */ 6481, /* 6481 */ 6481, /* 6489 */ 6491, /* 6497 */ 6491, /* 6505 */ 6491, /* 6513 */ 6521, /* 6521 */ 6529, /* 6529 */ 6529, /* 6537 */ 6529, /* 6545 */ 6553, /* 6553 */ 6553, /* 6561 */ 6569, /* 6569 */ 6577, /* 6577 */ 6581, /* 6585 */ 6581, /* 6593 */ 6599, /* 6601 */ 6607, /* 6609 */ 6607, /* 6617 */ 6619, /* 6625 */ 6619, /* 6633 */ 6637, /* 6641 */ 6637, /* 6649 */ 6653, /* 6657 */ 6661, /* 6665 */ 6673, /* 6673 */ 6679, /* 6681 */ 6689, /* 6689 */ 6691, /* 6697 */ 6703, /* 6705 */ 6709, /* 6713 */ 6719, /* 6721 */ 6719, /* 6729 */ 6737, /* 6737 */ 6737, /* 6745 */ 6737, /* 6753 */ 6761, /* 6761 */ 6763, /* 6769 */ 6763, /* 6777 */ 6781, /* 6785 */ 6793, /* 6793 */ 6793, /* 6801 */ 6803, /* 6809 */ 6803, /* 6817 */ 6823, /* 6825 */ 6833, /* 6833 */ 6841, /* 6841 */ 6841, /* 6849 */ 6857, /* 6857 */ 6863, /* 6865 */ 6871, /* 6873 */ 6871, /* 6881 */ 6883, /* 6889 */ 6883, /* 6897 */ 6899, /* 6905 */ 6911, /* 6913 */ 6917, /* 6921 */ 6917, /* 6929 */ 6917, /* 6937 */ 6917, /* 6945 */ 6949, /* 6953 */ 6961, /* 6961 */ 6967, /* 6969 */ 6977, /* 6977 */ 6983, /* 6985 */ 6991, /* 6993 */ 7001, /* 7001 */ 7001, /* 7009 */ 7013, /* 7017 */ 7019, /* 7025 */ 7027, /* 7033 */ 7039, /* 7041 */ 7043, /* 7049 */ 7057, /* 7057 */ 7057, /* 7065 */ 7069, /* 7073 */ 7079, /* 7081 */ 7079, /* 7089 */ 7079, /* 7097 */ 7103, /* 7105 */ 7109, /* 7113 */ 7121, /* 7121 */ 7129, /* 7129 */ 7129, /* 7137 */ 7129, /* 7145 */ 7151, /* 7153 */ 7159, /* 7161 */ 7159, /* 7169 */ 7177, /* 7177 */ 7177, /* 7185 */ 7193, /* 7193 */ 7193, /* 7201 */ 7207, /* 7209 */ 7213, /* 7217 */ 7219, /* 7225 */ 7229, /* 7233 */ 7237, /* 7241 */ 7247, /* 7249 */ 7253, /* 7257 */ 7253, /* 7265 */ 7253, /* 7273 */ 7253, /* 7281 */ 7283, /* 7289 */ 7297, /* 7297 */ 7297, /* 7305 */ 7309, /* 7313 */ 7321, /* 7321 */ 7321, /* 7329 */ 7333, /* 7337 */ 7333, /* 7345 */ 7351, /* 7353 */ 7351, /* 7361 */ 7369, /* 7369 */ 7369, /* 7377 */ 7369, /* 7385 */ 7393, /* 7393 */ 7393, /* 7401 */ 7393, /* 7409 */ 7417, /* 7417 */ 7417, /* 7425 */ 7433, /* 7433 */ 7433, /* 7441 */ 7433, /* 7449 */ 7457, /* 7457 */ 7459, /* 7465 */ 7459, /* 7473 */ 7481, /* 7481 */ 7489, /* 7489 */ 7489, /* 7497 */ 7499, /* 7505 */ 7507, /* 7513 */ 7517, /* 7521 */ 7529, /* 7529 */ 7537, /* 7537 */ 7541, /* 7545 */ 7549, /* 7553 */ 7561, /* 7561 */ 7561, /* 7569 */ 7577, /* 7577 */ 7583, /* 7585 */ 7591, /* 7593 */ 7591, /* 7601 */ 7607, /* 7609 */ 7607, /* 7617 */ 7621, /* 7625 */ 7621, /* 7633 */ 7639, /* 7641 */ 7649, /* 7649 */ 7649, /* 7657 */ 7649, /* 7665 */ 7673, /* 7673 */ 7681, /* 7681 */ 7687, /* 7689 */ 7691, /* 7697 */ 7703, /* 7705 */ 7703, /* 7713 */ 7717, /* 7721 */ 7727, /* 7729 */ 7727, /* 7737 */ 7741, /* 7745 */ 7753, /* 7753 */ 7759, /* 7761 */ 7759, /* 7769 */ 7759, /* 7777 */ 7759, /* 7785 */ 7793, /* 7793 */ 7793, /* 7801 */ 7793, /* 7809 */ 7817, /* 7817 */ 7823, /* 7825 */ 7829, /* 7833 */ 7841, /* 7841 */ 7841, /* 7849 */ 7853, /* 7857 */ 7853, /* 7865 */ 7873, /* 7873 */ 7879, /* 7881 */ 7883, /* 7889 */ 7883, /* 7897 */ 7901, /* 7905 */ 7907, /* 7913 */ 7919, /* 7921 */ 7927, /* 7929 */ 7937, /* 7937 */ 7937, /* 7945 */ 7951, /* 7953 */ 7951, /* 7961 */ 7963, /* 7969 */ 7963, /* 7977 */ 7963, /* 7985 */ 7993, /* 7993 */ 7993, /* 8001 */ 8009, /* 8009 */ 8017, /* 8017 */ 8017, /* 8025 */ 8017, /* 8033 */ 8039, /* 8041 */ 8039, /* 8049 */ 8053, /* 8057 */ 8059, /* 8065 */ 8069, /* 8073 */ 8081, /* 8081 */ 8089, /* 8089 */ 8093, /* 8097 */ 8101, /* 8105 */ 8111, /* 8113 */ 8117, /* 8121 */ 8123, /* 8129 */ 8123, /* 8137 */ 8123, /* 8145 */ 8147, /* 8153 */ 8161, /* 8161 */ 8167, /* 8169 */ 8171, /* 8177 */ 8179, /* 8185 */ }; /* 0-64K, increments=64 */ static unsigned prime_table1[]={ 1, /* 1 */ 61, /* 65 */ 127, /* 129 */ 193, /* 193 */ 257, /* 257 */ 317, /* 321 */ 383, /* 385 */ 449, /* 449 */ 509, /* 513 */ 577, /* 577 */ 641, /* 641 */ 701, /* 705 */ 769, /* 769 */ 829, /* 833 */ 887, /* 897 */ 953, /* 961 */ 1021, /* 1025 */ 1087, /* 1089 */ 1153, /* 1153 */ 1217, /* 1217 */ 1279, /* 1281 */ 1327, /* 1345 */ 1409, /* 1409 */ 1471, /* 1473 */ 1531, /* 1537 */ 1601, /* 1601 */ 1663, /* 1665 */ 1723, /* 1729 */ 1789, /* 1793 */ 1847, /* 1857 */ 1913, /* 1921 */ 1979, /* 1985 */ 2039, /* 2049 */ 2113, /* 2113 */ 2161, /* 2177 */ 2239, /* 2241 */ 2297, /* 2305 */ 2357, /* 2369 */ 2423, /* 2433 */ 2477, /* 2497 */ 2557, /* 2561 */ 2621, /* 2625 */ 2689, /* 2689 */ 2753, /* 2753 */ 2803, /* 2817 */ 2879, /* 2881 */ 2939, /* 2945 */ 3001, /* 3009 */ 3067, /* 3073 */ 3137, /* 3137 */ 3191, /* 3201 */ 3259, /* 3265 */ 3329, /* 3329 */ 3391, /* 3393 */ 3457, /* 3457 */ 3517, /* 3521 */ 3583, /* 3585 */ 3643, /* 3649 */ 3709, /* 3713 */ 3769, /* 3777 */ 3833, /* 3841 */ 3889, /* 3905 */ 3967, /* 3969 */ 4027, /* 4033 */ 4093, /* 4097 */ 4159, /* 4161 */ 4219, /* 4225 */ 4289, /* 4289 */ 4349, /* 4353 */ 4409, /* 4417 */ 4481, /* 4481 */ 4523, /* 4545 */ 4603, /* 4609 */ 4673, /* 4673 */ 4733, /* 4737 */ 4801, /* 4801 */ 4861, /* 4865 */ 4919, /* 4929 */ 4993, /* 4993 */ 5051, /* 5057 */ 5119, /* 5121 */ 5179, /* 5185 */ 5237, /* 5249 */ 5309, /* 5313 */ 5351, /* 5377 */ 5441, /* 5441 */ 5503, /* 5505 */ 5569, /* 5569 */ 5623, /* 5633 */ 5693, /* 5697 */ 5749, /* 5761 */ 5821, /* 5825 */ 5881, /* 5889 */ 5953, /* 5953 */ 6011, /* 6017 */ 6079, /* 6081 */ 6143, /* 6145 */ 6203, /* 6209 */ 6271, /* 6273 */ 6337, /* 6337 */ 6397, /* 6401 */ 6451, /* 6465 */ 6529, /* 6529 */ 6581, /* 6593 */ 6653, /* 6657 */ 6719, /* 6721 */ 6781, /* 6785 */ 6841, /* 6849 */ 6911, /* 6913 */ 6977, /* 6977 */ 7039, /* 7041 */ 7103, /* 7105 */ 7159, /* 7169 */ 7229, /* 7233 */ 7297, /* 7297 */ 7351, /* 7361 */ 7417, /* 7425 */ 7489, /* 7489 */ 7549, /* 7553 */ 7607, /* 7617 */ 7681, /* 7681 */ 7741, /* 7745 */ 7793, /* 7809 */ 7873, /* 7873 */ 7937, /* 7937 */ 7993, /* 8001 */ 8059, /* 8065 */ 8123, /* 8129 */ 8191, /* 8193 */ 8243, /* 8257 */ 8317, /* 8321 */ 8377, /* 8385 */ 8447, /* 8449 */ 8513, /* 8513 */ 8573, /* 8577 */ 8641, /* 8641 */ 8699, /* 8705 */ 8761, /* 8769 */ 8831, /* 8833 */ 8893, /* 8897 */ 8951, /* 8961 */ 9013, /* 9025 */ 9067, /* 9089 */ 9151, /* 9153 */ 9209, /* 9217 */ 9281, /* 9281 */ 9343, /* 9345 */ 9403, /* 9409 */ 9473, /* 9473 */ 9533, /* 9537 */ 9601, /* 9601 */ 9661, /* 9665 */ 9721, /* 9729 */ 9791, /* 9793 */ 9857, /* 9857 */ 9907, /* 9921 */ 9973, /* 9985 */ 10039, /* 10049 */ 10111, /* 10113 */ 10177, /* 10177 */ 10223, /* 10241 */ 10303, /* 10305 */ 10369, /* 10369 */ 10433, /* 10433 */ 10487, /* 10497 */ 10559, /* 10561 */ 10613, /* 10625 */ 10687, /* 10689 */ 10753, /* 10753 */ 10799, /* 10817 */ 10867, /* 10881 */ 10939, /* 10945 */ 11003, /* 11009 */ 11071, /* 11073 */ 11131, /* 11137 */ 11197, /* 11201 */ 11261, /* 11265 */ 11329, /* 11329 */ 11393, /* 11393 */ 11447, /* 11457 */ 11519, /* 11521 */ 11579, /* 11585 */ 11633, /* 11649 */ 11701, /* 11713 */ 11777, /* 11777 */ 11839, /* 11841 */ 11903, /* 11905 */ 11969, /* 11969 */ 12011, /* 12033 */ 12097, /* 12097 */ 12161, /* 12161 */ 12211, /* 12225 */ 12289, /* 12289 */ 12347, /* 12353 */ 12413, /* 12417 */ 12479, /* 12481 */ 12541, /* 12545 */ 12601, /* 12609 */ 12671, /* 12673 */ 12721, /* 12737 */ 12799, /* 12801 */ 12853, /* 12865 */ 12923, /* 12929 */ 12983, /* 12993 */ 13049, /* 13057 */ 13121, /* 13121 */ 13183, /* 13185 */ 13249, /* 13249 */ 13313, /* 13313 */ 13367, /* 13377 */ 13441, /* 13441 */ 13499, /* 13505 */ 13567, /* 13569 */ 13633, /* 13633 */ 13697, /* 13697 */ 13759, /* 13761 */ 13807, /* 13825 */ 13883, /* 13889 */ 13933, /* 13953 */ 14011, /* 14017 */ 14081, /* 14081 */ 14143, /* 14145 */ 14207, /* 14209 */ 14251, /* 14273 */ 14327, /* 14337 */ 14401, /* 14401 */ 14461, /* 14465 */ 14519, /* 14529 */ 14593, /* 14593 */ 14657, /* 14657 */ 14717, /* 14721 */ 14783, /* 14785 */ 14843, /* 14849 */ 14897, /* 14913 */ 14969, /* 14977 */ 15031, /* 15041 */ 15101, /* 15105 */ 15161, /* 15169 */ 15233, /* 15233 */ 15289, /* 15297 */ 15361, /* 15361 */ 15413, /* 15425 */ 15473, /* 15489 */ 15551, /* 15553 */ 15607, /* 15617 */ 15679, /* 15681 */ 15739, /* 15745 */ 15809, /* 15809 */ 15859, /* 15873 */ 15937, /* 15937 */ 16001, /* 16001 */ 16063, /* 16065 */ 16127, /* 16129 */ 16193, /* 16193 */ 16253, /* 16257 */ 16319, /* 16321 */ 16381, /* 16385 */ 16447, /* 16449 */ 16493, /* 16513 */ 16573, /* 16577 */ 16633, /* 16641 */ 16703, /* 16705 */ 16763, /* 16769 */ 16831, /* 16833 */ 16889, /* 16897 */ 16943, /* 16961 */ 17021, /* 17025 */ 17077, /* 17089 */ 17137, /* 17153 */ 17209, /* 17217 */ 17257, /* 17281 */ 17341, /* 17345 */ 17401, /* 17409 */ 17471, /* 17473 */ 17519, /* 17537 */ 17599, /* 17601 */ 17659, /* 17665 */ 17729, /* 17729 */ 17791, /* 17793 */ 17851, /* 17857 */ 17921, /* 17921 */ 17981, /* 17985 */ 18049, /* 18049 */ 18097, /* 18113 */ 18169, /* 18177 */ 18233, /* 18241 */ 18301, /* 18305 */ 18367, /* 18369 */ 18433, /* 18433 */ 18493, /* 18497 */ 18553, /* 18561 */ 18617, /* 18625 */ 18679, /* 18689 */ 18749, /* 18753 */ 18803, /* 18817 */ 18869, /* 18881 */ 18919, /* 18945 */ 19009, /* 19009 */ 19073, /* 19073 */ 19121, /* 19137 */ 19183, /* 19201 */ 19259, /* 19265 */ 19319, /* 19329 */ 19391, /* 19393 */ 19457, /* 19457 */ 19507, /* 19521 */ 19583, /* 19585 */ 19609, /* 19649 */ 19709, /* 19713 */ 19777, /* 19777 */ 19841, /* 19841 */ 19891, /* 19905 */ 19963, /* 19969 */ 20029, /* 20033 */ 20089, /* 20097 */ 20161, /* 20161 */ 20219, /* 20225 */ 20287, /* 20289 */ 20353, /* 20353 */ 20411, /* 20417 */ 20479, /* 20481 */ 20543, /* 20545 */ 20599, /* 20609 */ 20663, /* 20673 */ 20731, /* 20737 */ 20789, /* 20801 */ 20857, /* 20865 */ 20929, /* 20929 */ 20983, /* 20993 */ 21031, /* 21057 */ 21121, /* 21121 */ 21179, /* 21185 */ 21247, /* 21249 */ 21313, /* 21313 */ 21377, /* 21377 */ 21433, /* 21441 */ 21503, /* 21505 */ 21569, /* 21569 */ 21617, /* 21633 */ 21683, /* 21697 */ 21757, /* 21761 */ 21821, /* 21825 */ 21881, /* 21889 */ 21943, /* 21953 */ 22013, /* 22017 */ 22079, /* 22081 */ 22133, /* 22145 */ 22193, /* 22209 */ 22273, /* 22273 */ 22307, /* 22337 */ 22397, /* 22401 */ 22453, /* 22465 */ 22511, /* 22529 */ 22573, /* 22593 */ 22651, /* 22657 */ 22721, /* 22721 */ 22783, /* 22785 */ 22817, /* 22849 */ 22907, /* 22913 */ 22973, /* 22977 */ 23041, /* 23041 */ 23099, /* 23105 */ 23167, /* 23169 */ 23227, /* 23233 */ 23297, /* 23297 */ 23357, /* 23361 */ 23417, /* 23425 */ 23473, /* 23489 */ 23549, /* 23553 */ 23609, /* 23617 */ 23677, /* 23681 */ 23743, /* 23745 */ 23801, /* 23809 */ 23873, /* 23873 */ 23929, /* 23937 */ 24001, /* 24001 */ 24061, /* 24065 */ 24121, /* 24129 */ 24181, /* 24193 */ 24251, /* 24257 */ 24317, /* 24321 */ 24379, /* 24385 */ 24443, /* 24449 */ 24509, /* 24513 */ 24571, /* 24577 */ 24631, /* 24641 */ 24697, /* 24705 */ 24767, /* 24769 */ 24821, /* 24833 */ 24889, /* 24897 */ 24953, /* 24961 */ 25013, /* 25025 */ 25087, /* 25089 */ 25153, /* 25153 */ 25189, /* 25217 */ 25261, /* 25281 */ 25343, /* 25345 */ 25409, /* 25409 */ 25471, /* 25473 */ 25537, /* 25537 */ 25601, /* 25601 */ 25657, /* 25665 */ 25717, /* 25729 */ 25793, /* 25793 */ 25849, /* 25857 */ 25919, /* 25921 */ 25981, /* 25985 */ 26041, /* 26049 */ 26113, /* 26113 */ 26177, /* 26177 */ 26237, /* 26241 */ 26297, /* 26305 */ 26357, /* 26369 */ 26431, /* 26433 */ 26497, /* 26497 */ 26561, /* 26561 */ 26597, /* 26625 */ 26687, /* 26689 */ 26737, /* 26753 */ 26813, /* 26817 */ 26881, /* 26881 */ 26927, /* 26945 */ 26993, /* 27009 */ 27073, /* 27073 */ 27127, /* 27137 */ 27197, /* 27201 */ 27259, /* 27265 */ 27329, /* 27329 */ 27367, /* 27393 */ 27457, /* 27457 */ 27509, /* 27521 */ 27583, /* 27585 */ 27647, /* 27649 */ 27701, /* 27713 */ 27773, /* 27777 */ 27827, /* 27841 */ 27901, /* 27905 */ 27967, /* 27969 */ 28031, /* 28033 */ 28097, /* 28097 */ 28151, /* 28161 */ 28219, /* 28225 */ 28289, /* 28289 */ 28351, /* 28353 */ 28411, /* 28417 */ 28477, /* 28481 */ 28541, /* 28545 */ 28607, /* 28609 */ 28669, /* 28673 */ 28729, /* 28737 */ 28793, /* 28801 */ 28859, /* 28865 */ 28927, /* 28929 */ 28979, /* 28993 */ 29033, /* 29057 */ 29101, /* 29121 */ 29179, /* 29185 */ 29243, /* 29249 */ 29311, /* 29313 */ 29363, /* 29377 */ 29437, /* 29441 */ 29501, /* 29505 */ 29569, /* 29569 */ 29633, /* 29633 */ 29683, /* 29697 */ 29761, /* 29761 */ 29819, /* 29825 */ 29881, /* 29889 */ 29947, /* 29953 */ 30013, /* 30017 */ 30071, /* 30081 */ 30139, /* 30145 */ 30203, /* 30209 */ 30271, /* 30273 */ 30323, /* 30337 */ 30391, /* 30401 */ 30449, /* 30465 */ 30529, /* 30529 */ 30593, /* 30593 */ 30649, /* 30657 */ 30713, /* 30721 */ 30781, /* 30785 */ 30841, /* 30849 */ 30911, /* 30913 */ 30977, /* 30977 */ 31039, /* 31041 */ 31091, /* 31105 */ 31159, /* 31169 */ 31231, /* 31233 */ 31277, /* 31297 */ 31357, /* 31361 */ 31397, /* 31425 */ 31489, /* 31489 */ 31547, /* 31553 */ 31607, /* 31617 */ 31667, /* 31681 */ 31741, /* 31745 */ 31799, /* 31809 */ 31873, /* 31873 */ 31907, /* 31937 */ 31991, /* 32001 */ 32063, /* 32065 */ 32119, /* 32129 */ 32191, /* 32193 */ 32257, /* 32257 */ 32321, /* 32321 */ 32381, /* 32385 */ 32443, /* 32449 */ 32507, /* 32513 */ 32573, /* 32577 */ 32633, /* 32641 */ 32693, /* 32705 */ 32749, /* 32769 */ 32833, /* 32833 */ 32887, /* 32897 */ 32957, /* 32961 */ 33023, /* 33025 */ 33083, /* 33089 */ 33151, /* 33153 */ 33211, /* 33217 */ 33247, /* 33281 */ 33343, /* 33345 */ 33409, /* 33409 */ 33469, /* 33473 */ 33533, /* 33537 */ 33601, /* 33601 */ 33647, /* 33665 */ 33721, /* 33729 */ 33791, /* 33793 */ 33857, /* 33857 */ 33911, /* 33921 */ 33967, /* 33985 */ 34039, /* 34049 */ 34061, /* 34113 */ 34171, /* 34177 */ 34231, /* 34241 */ 34303, /* 34305 */ 34369, /* 34369 */ 34429, /* 34433 */ 34487, /* 34497 */ 34549, /* 34561 */ 34613, /* 34625 */ 34687, /* 34689 */ 34747, /* 34753 */ 34807, /* 34817 */ 34877, /* 34881 */ 34939, /* 34945 */ 34981, /* 35009 */ 35069, /* 35073 */ 35129, /* 35137 */ 35201, /* 35201 */ 35257, /* 35265 */ 35327, /* 35329 */ 35393, /* 35393 */ 35449, /* 35457 */ 35521, /* 35521 */ 35573, /* 35585 */ 35617, /* 35649 */ 35677, /* 35713 */ 35771, /* 35777 */ 35839, /* 35841 */ 35899, /* 35905 */ 35969, /* 35969 */ 36017, /* 36033 */ 36097, /* 36097 */ 36161, /* 36161 */ 36217, /* 36225 */ 36277, /* 36289 */ 36353, /* 36353 */ 36389, /* 36417 */ 36479, /* 36481 */ 36541, /* 36545 */ 36607, /* 36609 */ 36671, /* 36673 */ 36721, /* 36737 */ 36793, /* 36801 */ 36857, /* 36865 */ 36929, /* 36929 */ 36979, /* 36993 */ 37057, /* 37057 */ 37117, /* 37121 */ 37181, /* 37185 */ 37243, /* 37249 */ 37313, /* 37313 */ 37369, /* 37377 */ 37441, /* 37441 */ 37501, /* 37505 */ 37567, /* 37569 */ 37633, /* 37633 */ 37693, /* 37697 */ 37747, /* 37761 */ 37813, /* 37825 */ 37889, /* 37889 */ 37951, /* 37953 */ 38011, /* 38017 */ 38069, /* 38081 */ 38119, /* 38145 */ 38201, /* 38209 */ 38273, /* 38273 */ 38333, /* 38337 */ 38393, /* 38401 */ 38461, /* 38465 */ 38501, /* 38529 */ 38593, /* 38593 */ 38653, /* 38657 */ 38713, /* 38721 */ 38783, /* 38785 */ 38839, /* 38849 */ 38903, /* 38913 */ 38977, /* 38977 */ 39041, /* 39041 */ 39103, /* 39105 */ 39163, /* 39169 */ 39233, /* 39233 */ 39293, /* 39297 */ 39359, /* 39361 */ 39419, /* 39425 */ 39461, /* 39489 */ 39551, /* 39553 */ 39607, /* 39617 */ 39679, /* 39681 */ 39733, /* 39745 */ 39799, /* 39809 */ 39869, /* 39873 */ 39937, /* 39937 */ 39989, /* 40001 */ 40063, /* 40065 */ 40129, /* 40129 */ 40193, /* 40193 */ 40253, /* 40257 */ 40289, /* 40321 */ 40361, /* 40385 */ 40433, /* 40449 */ 40507, /* 40513 */ 40577, /* 40577 */ 40639, /* 40641 */ 40699, /* 40705 */ 40763, /* 40769 */ 40829, /* 40833 */ 40897, /* 40897 */ 40961, /* 40961 */ 41023, /* 41025 */ 41081, /* 41089 */ 41149, /* 41153 */ 41213, /* 41217 */ 41281, /* 41281 */ 41341, /* 41345 */ 41399, /* 41409 */ 41467, /* 41473 */ 41521, /* 41537 */ 41597, /* 41601 */ 41659, /* 41665 */ 41729, /* 41729 */ 41777, /* 41793 */ 41851, /* 41857 */ 41911, /* 41921 */ 41983, /* 41985 */ 42043, /* 42049 */ 42101, /* 42113 */ 42169, /* 42177 */ 42239, /* 42241 */ 42299, /* 42305 */ 42359, /* 42369 */ 42433, /* 42433 */ 42491, /* 42497 */ 42557, /* 42561 */ 42611, /* 42625 */ 42689, /* 42689 */ 42751, /* 42753 */ 42797, /* 42817 */ 42863, /* 42881 */ 42943, /* 42945 */ 43003, /* 43009 */ 43067, /* 43073 */ 43133, /* 43137 */ 43201, /* 43201 */ 43261, /* 43265 */ 43321, /* 43329 */ 43391, /* 43393 */ 43457, /* 43457 */ 43517, /* 43521 */ 43579, /* 43585 */ 43649, /* 43649 */ 43711, /* 43713 */ 43777, /* 43777 */ 43801, /* 43841 */ 43891, /* 43905 */ 43969, /* 43969 */ 44029, /* 44033 */ 44089, /* 44097 */ 44159, /* 44161 */ 44221, /* 44225 */ 44281, /* 44289 */ 44351, /* 44353 */ 44417, /* 44417 */ 44453, /* 44481 */ 44543, /* 44545 */ 44587, /* 44609 */ 44657, /* 44673 */ 44729, /* 44737 */ 44797, /* 44801 */ 44851, /* 44865 */ 44927, /* 44929 */ 44987, /* 44993 */ 45053, /* 45057 */ 45121, /* 45121 */ 45181, /* 45185 */ 45247, /* 45249 */ 45307, /* 45313 */ 45377, /* 45377 */ 45439, /* 45441 */ 45503, /* 45505 */ 45569, /* 45569 */ 45631, /* 45633 */ 45697, /* 45697 */ 45757, /* 45761 */ 45823, /* 45825 */ 45887, /* 45889 */ 45953, /* 45953 */ 45989, /* 46017 */ 46073, /* 46081 */ 46141, /* 46145 */ 46199, /* 46209 */ 46273, /* 46273 */ 46337, /* 46337 */ 46399, /* 46401 */ 46457, /* 46465 */ 46523, /* 46529 */ 46591, /* 46593 */ 46649, /* 46657 */ 46703, /* 46721 */ 46771, /* 46785 */ 46831, /* 46849 */ 46901, /* 46913 */ 46957, /* 46977 */ 47041, /* 47041 */ 47093, /* 47105 */ 47161, /* 47169 */ 47221, /* 47233 */ 47297, /* 47297 */ 47353, /* 47361 */ 47419, /* 47425 */ 47459, /* 47489 */ 47543, /* 47553 */ 47609, /* 47617 */ 47681, /* 47681 */ 47743, /* 47745 */ 47809, /* 47809 */ 47869, /* 47873 */ 47933, /* 47937 */ 47981, /* 48001 */ 48049, /* 48065 */ 48121, /* 48129 */ 48193, /* 48193 */ 48247, /* 48257 */ 48313, /* 48321 */ 48383, /* 48385 */ 48449, /* 48449 */ 48497, /* 48513 */ 48571, /* 48577 */ 48623, /* 48641 */ 48679, /* 48705 */ 48767, /* 48769 */ 48823, /* 48833 */ 48889, /* 48897 */ 48953, /* 48961 */ 49019, /* 49025 */ 49081, /* 49089 */ 49139, /* 49153 */ 49211, /* 49217 */ 49279, /* 49281 */ 49339, /* 49345 */ 49409, /* 49409 */ 49463, /* 49473 */ 49537, /* 49537 */ 49597, /* 49601 */ 49663, /* 49665 */ 49727, /* 49729 */ 49789, /* 49793 */ 49853, /* 49857 */ 49921, /* 49921 */ 49957, /* 49985 */ 50047, /* 50049 */ 50111, /* 50113 */ 50177, /* 50177 */ 50231, /* 50241 */ 50291, /* 50305 */ 50363, /* 50369 */ 50423, /* 50433 */ 50497, /* 50497 */ 50551, /* 50561 */ 50599, /* 50625 */ 50683, /* 50689 */ 50753, /* 50753 */ 50789, /* 50817 */ 50873, /* 50881 */ 50929, /* 50945 */ 51001, /* 51009 */ 51071, /* 51073 */ 51137, /* 51137 */ 51199, /* 51201 */ 51263, /* 51265 */ 51329, /* 51329 */ 51383, /* 51393 */ 51449, /* 51457 */ 51521, /* 51521 */ 51581, /* 51585 */ 51647, /* 51649 */ 51713, /* 51713 */ 51769, /* 51777 */ 51839, /* 51841 */ 51899, /* 51905 */ 51949, /* 51969 */ 52027, /* 52033 */ 52081, /* 52097 */ 52153, /* 52161 */ 52223, /* 52225 */ 52289, /* 52289 */ 52321, /* 52353 */ 52391, /* 52417 */ 52457, /* 52481 */ 52543, /* 52545 */ 52609, /* 52609 */ 52673, /* 52673 */ 52733, /* 52737 */ 52783, /* 52801 */ 52861, /* 52865 */ 52919, /* 52929 */ 52981, /* 52993 */ 53051, /* 53057 */ 53117, /* 53121 */ 53173, /* 53185 */ 53239, /* 53249 */ 53309, /* 53313 */ 53377, /* 53377 */ 53441, /* 53441 */ 53503, /* 53505 */ 53569, /* 53569 */ 53633, /* 53633 */ 53693, /* 53697 */ 53759, /* 53761 */ 53819, /* 53825 */ 53887, /* 53889 */ 53951, /* 53953 */ 54013, /* 54017 */ 54059, /* 54081 */ 54139, /* 54145 */ 54193, /* 54209 */ 54269, /* 54273 */ 54331, /* 54337 */ 54401, /* 54401 */ 54449, /* 54465 */ 54521, /* 54529 */ 54583, /* 54593 */ 54647, /* 54657 */ 54721, /* 54721 */ 54779, /* 54785 */ 54833, /* 54849 */ 54907, /* 54913 */ 54973, /* 54977 */ 55021, /* 55041 */ 55103, /* 55105 */ 55163, /* 55169 */ 55229, /* 55233 */ 55291, /* 55297 */ 55351, /* 55361 */ 55411, /* 55425 */ 55487, /* 55489 */ 55547, /* 55553 */ 55609, /* 55617 */ 55681, /* 55681 */ 55733, /* 55745 */ 55807, /* 55809 */ 55871, /* 55873 */ 55933, /* 55937 */ 55997, /* 56001 */ 56053, /* 56065 */ 56123, /* 56129 */ 56179, /* 56193 */ 56249, /* 56257 */ 56311, /* 56321 */ 56383, /* 56385 */ 56443, /* 56449 */ 56509, /* 56513 */ 56569, /* 56577 */ 56633, /* 56641 */ 56701, /* 56705 */ 56767, /* 56769 */ 56827, /* 56833 */ 56897, /* 56897 */ 56957, /* 56961 */ 56999, /* 57025 */ 57089, /* 57089 */ 57149, /* 57153 */ 57203, /* 57217 */ 57271, /* 57281 */ 57331, /* 57345 */ 57397, /* 57409 */ 57467, /* 57473 */ 57529, /* 57537 */ 57601, /* 57601 */ 57653, /* 57665 */ 57727, /* 57729 */ 57793, /* 57793 */ 57853, /* 57857 */ 57917, /* 57921 */ 57977, /* 57985 */ 58049, /* 58049 */ 58111, /* 58113 */ 58171, /* 58177 */ 58237, /* 58241 */ 58271, /* 58305 */ 58369, /* 58369 */ 58427, /* 58433 */ 58481, /* 58497 */ 58549, /* 58561 */ 58613, /* 58625 */ 58687, /* 58689 */ 58741, /* 58753 */ 58789, /* 58817 */ 58831, /* 58881 */ 58943, /* 58945 */ 59009, /* 59009 */ 59069, /* 59073 */ 59123, /* 59137 */ 59197, /* 59201 */ 59263, /* 59265 */ 59281, /* 59329 */ 59393, /* 59393 */ 59453, /* 59457 */ 59513, /* 59521 */ 59581, /* 59585 */ 59629, /* 59649 */ 59707, /* 59713 */ 59771, /* 59777 */ 59833, /* 59841 */ 59887, /* 59905 */ 59957, /* 59969 */ 60029, /* 60033 */ 60091, /* 60097 */ 60161, /* 60161 */ 60223, /* 60225 */ 60289, /* 60289 */ 60353, /* 60353 */ 60413, /* 60417 */ 60457, /* 60481 */ 60539, /* 60545 */ 60607, /* 60609 */ 60661, /* 60673 */ 60737, /* 60737 */ 60793, /* 60801 */ 60859, /* 60865 */ 60923, /* 60929 */ 60961, /* 60993 */ 61057, /* 61057 */ 61121, /* 61121 */ 61169, /* 61185 */ 61231, /* 61249 */ 61297, /* 61313 */ 61363, /* 61377 */ 61441, /* 61441 */ 61493, /* 61505 */ 61561, /* 61569 */ 61631, /* 61633 */ 61687, /* 61697 */ 61757, /* 61761 */ 61819, /* 61825 */ 61879, /* 61889 */ 61949, /* 61953 */ 62017, /* 62017 */ 62081, /* 62081 */ 62143, /* 62145 */ 62207, /* 62209 */ 62273, /* 62273 */ 62327, /* 62337 */ 62401, /* 62401 */ 62459, /* 62465 */ 62507, /* 62529 */ 62591, /* 62593 */ 62653, /* 62657 */ 62701, /* 62721 */ 62773, /* 62785 */ 62827, /* 62849 */ 62903, /* 62913 */ 62971, /* 62977 */ 63031, /* 63041 */ 63103, /* 63105 */ 63149, /* 63169 */ 63211, /* 63233 */ 63281, /* 63297 */ 63361, /* 63361 */ 63421, /* 63425 */ 63487, /* 63489 */ 63541, /* 63553 */ 63617, /* 63617 */ 63671, /* 63681 */ 63743, /* 63745 */ 63809, /* 63809 */ 63863, /* 63873 */ 63929, /* 63937 */ 63997, /* 64001 */ 64063, /* 64065 */ 64123, /* 64129 */ 64189, /* 64193 */ 64237, /* 64257 */ 64319, /* 64321 */ 64381, /* 64385 */ 64439, /* 64449 */ 64513, /* 64513 */ 64577, /* 64577 */ 64633, /* 64641 */ 64693, /* 64705 */ 64763, /* 64769 */ 64817, /* 64833 */ 64891, /* 64897 */ 64951, /* 64961 */ 65011, /* 65025 */ 65089, /* 65089 */ 65147, /* 65153 */ 65213, /* 65217 */ 65269, /* 65281 */ 65327, /* 65345 */ 65407, /* 65409 */ 65449, /* 65473 */ }; /* 0-1M, increments=1024 */ static unsigned prime_table2[1024]={ 1021, /* 1024 */ 2039, /* 2048 */ 3067, /* 3072 */ 4093, /* 4096 */ 5119, /* 5120 */ 6143, /* 6144 */ 7159, /* 7168 */ 8191, /* 8192 */ 9209, /* 9216 */ 10223, /* 10240 */ 11261, /* 11264 */ 12281, /* 12288 */ 13309, /* 13312 */ 14327, /* 14336 */ 15359, /* 15360 */ 16381, /* 16384 */ 17401, /* 17408 */ 18427, /* 18432 */ 19447, /* 19456 */ 20479, /* 20480 */ 21503, /* 21504 */ 22511, /* 22528 */ 23549, /* 23552 */ 24571, /* 24576 */ 25589, /* 25600 */ 26597, /* 26624 */ 27647, /* 27648 */ 28669, /* 28672 */ 29683, /* 29696 */ 30713, /* 30720 */ 31741, /* 31744 */ 32749, /* 32768 */ 33791, /* 33792 */ 34807, /* 34816 */ 35839, /* 35840 */ 36857, /* 36864 */ 37879, /* 37888 */ 38903, /* 38912 */ 39929, /* 39936 */ 40949, /* 40960 */ 41983, /* 41984 */ 43003, /* 43008 */ 44029, /* 44032 */ 45053, /* 45056 */ 46073, /* 46080 */ 47093, /* 47104 */ 48121, /* 48128 */ 49139, /* 49152 */ 50159, /* 50176 */ 51199, /* 51200 */ 52223, /* 52224 */ 53239, /* 53248 */ 54269, /* 54272 */ 55291, /* 55296 */ 56311, /* 56320 */ 57331, /* 57344 */ 58367, /* 58368 */ 59387, /* 59392 */ 60413, /* 60416 */ 61417, /* 61440 */ 62459, /* 62464 */ 63487, /* 63488 */ 64499, /* 64512 */ 65521, /* 65536 */ 66553, /* 66560 */ 67579, /* 67584 */ 68597, /* 68608 */ 69623, /* 69632 */ 70639, /* 70656 */ 71671, /* 71680 */ 72701, /* 72704 */ 73727, /* 73728 */ 74747, /* 74752 */ 75773, /* 75776 */ 76781, /* 76800 */ 77813, /* 77824 */ 78839, /* 78848 */ 79867, /* 79872 */ 80863, /* 80896 */ 81919, /* 81920 */ 82939, /* 82944 */ 83939, /* 83968 */ 84991, /* 84992 */ 86011, /* 86016 */ 87037, /* 87040 */ 88037, /* 88064 */ 89087, /* 89088 */ 90107, /* 90112 */ 91129, /* 91136 */ 92153, /* 92160 */ 93179, /* 93184 */ 94207, /* 94208 */ 95231, /* 95232 */ 96233, /* 96256 */ 97259, /* 97280 */ 98299, /* 98304 */ 99317, /* 99328 */ 100343, /* 100352 */ 101363, /* 101376 */ 102397, /* 102400 */ 103423, /* 103424 */ 104417, /* 104448 */ 105467, /* 105472 */ 106487, /* 106496 */ 107509, /* 107520 */ 108541, /* 108544 */ 109567, /* 109568 */ 110587, /* 110592 */ 111611, /* 111616 */ 112621, /* 112640 */ 113657, /* 113664 */ 114679, /* 114688 */ 115693, /* 115712 */ 116731, /* 116736 */ 117757, /* 117760 */ 118757, /* 118784 */ 119797, /* 119808 */ 120829, /* 120832 */ 121853, /* 121856 */ 122869, /* 122880 */ 123887, /* 123904 */ 124919, /* 124928 */ 125941, /* 125952 */ 126967, /* 126976 */ 127997, /* 128000 */ 129023, /* 129024 */ 130043, /* 130048 */ 131071, /* 131072 */ 132071, /* 132096 */ 133117, /* 133120 */ 134129, /* 134144 */ 135151, /* 135168 */ 136189, /* 136192 */ 137209, /* 137216 */ 138239, /* 138240 */ 139241, /* 139264 */ 140281, /* 140288 */ 141311, /* 141312 */ 142327, /* 142336 */ 143357, /* 143360 */ 144383, /* 144384 */ 145399, /* 145408 */ 146423, /* 146432 */ 147451, /* 147456 */ 148471, /* 148480 */ 149503, /* 149504 */ 150523, /* 150528 */ 151549, /* 151552 */ 152567, /* 152576 */ 153589, /* 153600 */ 154621, /* 154624 */ 155627, /* 155648 */ 156671, /* 156672 */ 157679, /* 157696 */ 158699, /* 158720 */ 159739, /* 159744 */ 160757, /* 160768 */ 161783, /* 161792 */ 162791, /* 162816 */ 163819, /* 163840 */ 164839, /* 164864 */ 165887, /* 165888 */ 166909, /* 166912 */ 167917, /* 167936 */ 168943, /* 168960 */ 169957, /* 169984 */ 171007, /* 171008 */ 172031, /* 172032 */ 173053, /* 173056 */ 174079, /* 174080 */ 175103, /* 175104 */ 176123, /* 176128 */ 177131, /* 177152 */ 178169, /* 178176 */ 179173, /* 179200 */ 180221, /* 180224 */ 181243, /* 181248 */ 182261, /* 182272 */ 183289, /* 183296 */ 184309, /* 184320 */ 185327, /* 185344 */ 186343, /* 186368 */ 187387, /* 187392 */ 188407, /* 188416 */ 189439, /* 189440 */ 190409, /* 190464 */ 191473, /* 191488 */ 192499, /* 192512 */ 193513, /* 193536 */ 194543, /* 194560 */ 195581, /* 195584 */ 196597, /* 196608 */ 197621, /* 197632 */ 198647, /* 198656 */ 199679, /* 199680 */ 200699, /* 200704 */ 201709, /* 201728 */ 202751, /* 202752 */ 203773, /* 203776 */ 204797, /* 204800 */ 205823, /* 205824 */ 206827, /* 206848 */ 207869, /* 207872 */ 208891, /* 208896 */ 209917, /* 209920 */ 210943, /* 210944 */ 211949, /* 211968 */ 212987, /* 212992 */ 214009, /* 214016 */ 214993, /* 215040 */ 216061, /* 216064 */ 217081, /* 217088 */ 218111, /* 218112 */ 219133, /* 219136 */ 220151, /* 220160 */ 221173, /* 221184 */ 222199, /* 222208 */ 223229, /* 223232 */ 224251, /* 224256 */ 225263, /* 225280 */ 226283, /* 226304 */ 227303, /* 227328 */ 228341, /* 228352 */ 229373, /* 229376 */ 230393, /* 230400 */ 231419, /* 231424 */ 232439, /* 232448 */ 233437, /* 233472 */ 234473, /* 234496 */ 235519, /* 235520 */ 236527, /* 236544 */ 237563, /* 237568 */ 238591, /* 238592 */ 239611, /* 239616 */ 240631, /* 240640 */ 241663, /* 241664 */ 242681, /* 242688 */ 243709, /* 243712 */ 244733, /* 244736 */ 245759, /* 245760 */ 246781, /* 246784 */ 247799, /* 247808 */ 248827, /* 248832 */ 249853, /* 249856 */ 250871, /* 250880 */ 251903, /* 251904 */ 252919, /* 252928 */ 253951, /* 253952 */ 254971, /* 254976 */ 255989, /* 256000 */ 257017, /* 257024 */ 258031, /* 258048 */ 259033, /* 259072 */ 260089, /* 260096 */ 261101, /* 261120 */ 262139, /* 262144 */ 263167, /* 263168 */ 264179, /* 264192 */ 265207, /* 265216 */ 266239, /* 266240 */ 267259, /* 267264 */ 268283, /* 268288 */ 269281, /* 269312 */ 270329, /* 270336 */ 271357, /* 271360 */ 272383, /* 272384 */ 273367, /* 273408 */ 274423, /* 274432 */ 275453, /* 275456 */ 276467, /* 276480 */ 277499, /* 277504 */ 278503, /* 278528 */ 279551, /* 279552 */ 280561, /* 280576 */ 281581, /* 281600 */ 282617, /* 282624 */ 283639, /* 283648 */ 284659, /* 284672 */ 285673, /* 285696 */ 286711, /* 286720 */ 287731, /* 287744 */ 288767, /* 288768 */ 289789, /* 289792 */ 290803, /* 290816 */ 291833, /* 291840 */ 292849, /* 292864 */ 293863, /* 293888 */ 294911, /* 294912 */ 295909, /* 295936 */ 296941, /* 296960 */ 297971, /* 297984 */ 298999, /* 299008 */ 300023, /* 300032 */ 301051, /* 301056 */ 302053, /* 302080 */ 303097, /* 303104 */ 304127, /* 304128 */ 305147, /* 305152 */ 306169, /* 306176 */ 307189, /* 307200 */ 308219, /* 308224 */ 309241, /* 309248 */ 310243, /* 310272 */ 311293, /* 311296 */ 312313, /* 312320 */ 313343, /* 313344 */ 314359, /* 314368 */ 315389, /* 315392 */ 316403, /* 316416 */ 317437, /* 317440 */ 318457, /* 318464 */ 319483, /* 319488 */ 320483, /* 320512 */ 321509, /* 321536 */ 322559, /* 322560 */ 323581, /* 323584 */ 324593, /* 324608 */ 325631, /* 325632 */ 326633, /* 326656 */ 327673, /* 327680 */ 328687, /* 328704 */ 329723, /* 329728 */ 330749, /* 330752 */ 331769, /* 331776 */ 332791, /* 332800 */ 333821, /* 333824 */ 334843, /* 334848 */ 335857, /* 335872 */ 336887, /* 336896 */ 337919, /* 337920 */ 338927, /* 338944 */ 339959, /* 339968 */ 340979, /* 340992 */ 341993, /* 342016 */ 343037, /* 343040 */ 344053, /* 344064 */ 345067, /* 345088 */ 346111, /* 346112 */ 347131, /* 347136 */ 348149, /* 348160 */ 349183, /* 349184 */ 350191, /* 350208 */ 351229, /* 351232 */ 352249, /* 352256 */ 353263, /* 353280 */ 354301, /* 354304 */ 355321, /* 355328 */ 356351, /* 356352 */ 357359, /* 357376 */ 358373, /* 358400 */ 359419, /* 359424 */ 360439, /* 360448 */ 361469, /* 361472 */ 362473, /* 362496 */ 363497, /* 363520 */ 364543, /* 364544 */ 365567, /* 365568 */ 366547, /* 366592 */ 367613, /* 367616 */ 368633, /* 368640 */ 369661, /* 369664 */ 370687, /* 370688 */ 371699, /* 371712 */ 372733, /* 372736 */ 373757, /* 373760 */ 374783, /* 374784 */ 375799, /* 375808 */ 376823, /* 376832 */ 377851, /* 377856 */ 378869, /* 378880 */ 379903, /* 379904 */ 380917, /* 380928 */ 381949, /* 381952 */ 382961, /* 382976 */ 383987, /* 384000 */ 385013, /* 385024 */ 386047, /* 386048 */ 387071, /* 387072 */ 388081, /* 388096 */ 389117, /* 389120 */ 390119, /* 390144 */ 391163, /* 391168 */ 392177, /* 392192 */ 393209, /* 393216 */ 394223, /* 394240 */ 395261, /* 395264 */ 396269, /* 396288 */ 397303, /* 397312 */ 398323, /* 398336 */ 399353, /* 399360 */ 400381, /* 400384 */ 401407, /* 401408 */ 402419, /* 402432 */ 403439, /* 403456 */ 404461, /* 404480 */ 405499, /* 405504 */ 406517, /* 406528 */ 407527, /* 407552 */ 408563, /* 408576 */ 409597, /* 409600 */ 410623, /* 410624 */ 411641, /* 411648 */ 412667, /* 412672 */ 413689, /* 413696 */ 414709, /* 414720 */ 415729, /* 415744 */ 416761, /* 416768 */ 417773, /* 417792 */ 418813, /* 418816 */ 419831, /* 419840 */ 420859, /* 420864 */ 421847, /* 421888 */ 422911, /* 422912 */ 423931, /* 423936 */ 424939, /* 424960 */ 425977, /* 425984 */ 427001, /* 427008 */ 428027, /* 428032 */ 429043, /* 429056 */ 430061, /* 430080 */ 431099, /* 431104 */ 432121, /* 432128 */ 433151, /* 433152 */ 434167, /* 434176 */ 435191, /* 435200 */ 436217, /* 436224 */ 437243, /* 437248 */ 438271, /* 438272 */ 439289, /* 439296 */ 440311, /* 440320 */ 441319, /* 441344 */ 442367, /* 442368 */ 443389, /* 443392 */ 444403, /* 444416 */ 445433, /* 445440 */ 446461, /* 446464 */ 447481, /* 447488 */ 448451, /* 448512 */ 449473, /* 449536 */ 450557, /* 450560 */ 451579, /* 451584 */ 452597, /* 452608 */ 453631, /* 453632 */ 454637, /* 454656 */ 455659, /* 455680 */ 456697, /* 456704 */ 457711, /* 457728 */ 458747, /* 458752 */ 459763, /* 459776 */ 460793, /* 460800 */ 461819, /* 461824 */ 462841, /* 462848 */ 463867, /* 463872 */ 464879, /* 464896 */ 465917, /* 465920 */ 466919, /* 466944 */ 467963, /* 467968 */ 468983, /* 468992 */ 469993, /* 470016 */ 471007, /* 471040 */ 472063, /* 472064 */ 473027, /* 473088 */ 474101, /* 474112 */ 475109, /* 475136 */ 476143, /* 476160 */ 477163, /* 477184 */ 478207, /* 478208 */ 479231, /* 479232 */ 480209, /* 480256 */ 481249, /* 481280 */ 482281, /* 482304 */ 483323, /* 483328 */ 484339, /* 484352 */ 485371, /* 485376 */ 486397, /* 486400 */ 487423, /* 487424 */ 488441, /* 488448 */ 489457, /* 489472 */ 490493, /* 490496 */ 491503, /* 491520 */ 492523, /* 492544 */ 493567, /* 493568 */ 494591, /* 494592 */ 495613, /* 495616 */ 496631, /* 496640 */ 497663, /* 497664 */ 498679, /* 498688 */ 499711, /* 499712 */ 500729, /* 500736 */ 501731, /* 501760 */ 502781, /* 502784 */ 503803, /* 503808 */ 504821, /* 504832 */ 505823, /* 505856 */ 506873, /* 506880 */ 507901, /* 507904 */ 508919, /* 508928 */ 509947, /* 509952 */ 510943, /* 510976 */ 511997, /* 512000 */ 513017, /* 513024 */ 514021, /* 514048 */ 515041, /* 515072 */ 516091, /* 516096 */ 517091, /* 517120 */ 518137, /* 518144 */ 519161, /* 519168 */ 520151, /* 520192 */ 521201, /* 521216 */ 522239, /* 522240 */ 523261, /* 523264 */ 524287, /* 524288 */ 525299, /* 525312 */ 526307, /* 526336 */ 527353, /* 527360 */ 528383, /* 528384 */ 529393, /* 529408 */ 530429, /* 530432 */ 531383, /* 531456 */ 532453, /* 532480 */ 533459, /* 533504 */ 534511, /* 534528 */ 535547, /* 535552 */ 536563, /* 536576 */ 537599, /* 537600 */ 538621, /* 538624 */ 539641, /* 539648 */ 540629, /* 540672 */ 541693, /* 541696 */ 542719, /* 542720 */ 543713, /* 543744 */ 544759, /* 544768 */ 545791, /* 545792 */ 546781, /* 546816 */ 547831, /* 547840 */ 548861, /* 548864 */ 549883, /* 549888 */ 550909, /* 550912 */ 551933, /* 551936 */ 552917, /* 552960 */ 553981, /* 553984 */ 554977, /* 555008 */ 556027, /* 556032 */ 557041, /* 557056 */ 558067, /* 558080 */ 559099, /* 559104 */ 560123, /* 560128 */ 561109, /* 561152 */ 562169, /* 562176 */ 563197, /* 563200 */ 564197, /* 564224 */ 565247, /* 565248 */ 566233, /* 566272 */ 567277, /* 567296 */ 568303, /* 568320 */ 569323, /* 569344 */ 570359, /* 570368 */ 571381, /* 571392 */ 572399, /* 572416 */ 573437, /* 573440 */ 574439, /* 574464 */ 575479, /* 575488 */ 576509, /* 576512 */ 577531, /* 577536 */ 578537, /* 578560 */ 579583, /* 579584 */ 580607, /* 580608 */ 581617, /* 581632 */ 582649, /* 582656 */ 583673, /* 583680 */ 584699, /* 584704 */ 585727, /* 585728 */ 586741, /* 586752 */ 587773, /* 587776 */ 588779, /* 588800 */ 589811, /* 589824 */ 590839, /* 590848 */ 591863, /* 591872 */ 592877, /* 592896 */ 593903, /* 593920 */ 594931, /* 594944 */ 595967, /* 595968 */ 596987, /* 596992 */ 598007, /* 598016 */ 599023, /* 599040 */ 600053, /* 600064 */ 601079, /* 601088 */ 602111, /* 602112 */ 603133, /* 603136 */ 604073, /* 604160 */ 605177, /* 605184 */ 606181, /* 606208 */ 607219, /* 607232 */ 608213, /* 608256 */ 609277, /* 609280 */ 610301, /* 610304 */ 611323, /* 611328 */ 612349, /* 612352 */ 613367, /* 613376 */ 614387, /* 614400 */ 615413, /* 615424 */ 616439, /* 616448 */ 617471, /* 617472 */ 618463, /* 618496 */ 619511, /* 619520 */ 620531, /* 620544 */ 621541, /* 621568 */ 622577, /* 622592 */ 623591, /* 623616 */ 624607, /* 624640 */ 625663, /* 625664 */ 626687, /* 626688 */ 627709, /* 627712 */ 628721, /* 628736 */ 629747, /* 629760 */ 630737, /* 630784 */ 631789, /* 631808 */ 632813, /* 632832 */ 633833, /* 633856 */ 634871, /* 634880 */ 635893, /* 635904 */ 636919, /* 636928 */ 637939, /* 637952 */ 638971, /* 638976 */ 639997, /* 640000 */ 640993, /* 641024 */ 642013, /* 642048 */ 643061, /* 643072 */ 644089, /* 644096 */ 645097, /* 645120 */ 646103, /* 646144 */ 647161, /* 647168 */ 648191, /* 648192 */ 649183, /* 649216 */ 650227, /* 650240 */ 651257, /* 651264 */ 652283, /* 652288 */ 653311, /* 653312 */ 654323, /* 654336 */ 655357, /* 655360 */ 656377, /* 656384 */ 657403, /* 657408 */ 658417, /* 658432 */ 659453, /* 659456 */ 660449, /* 660480 */ 661483, /* 661504 */ 662527, /* 662528 */ 663547, /* 663552 */ 664571, /* 664576 */ 665591, /* 665600 */ 666607, /* 666624 */ 667643, /* 667648 */ 668671, /* 668672 */ 669689, /* 669696 */ 670711, /* 670720 */ 671743, /* 671744 */ 672767, /* 672768 */ 673787, /* 673792 */ 674813, /* 674816 */ 675839, /* 675840 */ 676861, /* 676864 */ 677857, /* 677888 */ 678907, /* 678912 */ 679933, /* 679936 */ 680959, /* 680960 */ 681983, /* 681984 */ 683003, /* 683008 */ 684017, /* 684032 */ 685051, /* 685056 */ 686057, /* 686080 */ 687101, /* 687104 */ 688111, /* 688128 */ 689141, /* 689152 */ 690163, /* 690176 */ 691199, /* 691200 */ 692221, /* 692224 */ 693223, /* 693248 */ 694271, /* 694272 */ 695293, /* 695296 */ 696317, /* 696320 */ 697327, /* 697344 */ 698359, /* 698368 */ 699383, /* 699392 */ 700393, /* 700416 */ 701419, /* 701440 */ 702451, /* 702464 */ 703471, /* 703488 */ 704507, /* 704512 */ 705533, /* 705536 */ 706547, /* 706560 */ 707573, /* 707584 */ 708601, /* 708608 */ 709609, /* 709632 */ 710641, /* 710656 */ 711679, /* 711680 */ 712697, /* 712704 */ 713681, /* 713728 */ 714751, /* 714752 */ 715753, /* 715776 */ 716789, /* 716800 */ 717817, /* 717824 */ 718847, /* 718848 */ 719839, /* 719872 */ 720887, /* 720896 */ 721909, /* 721920 */ 722933, /* 722944 */ 723967, /* 723968 */ 724991, /* 724992 */ 726013, /* 726016 */ 727021, /* 727040 */ 728047, /* 728064 */ 729073, /* 729088 */ 730111, /* 730112 */ 731117, /* 731136 */ 732157, /* 732160 */ 733177, /* 733184 */ 734207, /* 734208 */ 735211, /* 735232 */ 736249, /* 736256 */ 737279, /* 737280 */ 738301, /* 738304 */ 739327, /* 739328 */ 740351, /* 740352 */ 741373, /* 741376 */ 742393, /* 742400 */ 743423, /* 743424 */ 744431, /* 744448 */ 745471, /* 745472 */ 746483, /* 746496 */ 747499, /* 747520 */ 748541, /* 748544 */ 749557, /* 749568 */ 750571, /* 750592 */ 751613, /* 751616 */ 752639, /* 752640 */ 753659, /* 753664 */ 754651, /* 754688 */ 755707, /* 755712 */ 756727, /* 756736 */ 757753, /* 757760 */ 758783, /* 758784 */ 759799, /* 759808 */ 760813, /* 760832 */ 761833, /* 761856 */ 762877, /* 762880 */ 763901, /* 763904 */ 764903, /* 764928 */ 765949, /* 765952 */ 766967, /* 766976 */ 767957, /* 768000 */ 769019, /* 769024 */ 770047, /* 770048 */ 771049, /* 771072 */ 772091, /* 772096 */ 773117, /* 773120 */ 774143, /* 774144 */ 775163, /* 775168 */ 776183, /* 776192 */ 777209, /* 777216 */ 778237, /* 778240 */ 779249, /* 779264 */ 780287, /* 780288 */ 781309, /* 781312 */ 782329, /* 782336 */ 783359, /* 783360 */ 784379, /* 784384 */ 785377, /* 785408 */ 786431, /* 786432 */ 787447, /* 787456 */ 788479, /* 788480 */ 789493, /* 789504 */ 790523, /* 790528 */ 791543, /* 791552 */ 792563, /* 792576 */ 793591, /* 793600 */ 794593, /* 794624 */ 795647, /* 795648 */ 796657, /* 796672 */ 797689, /* 797696 */ 798713, /* 798720 */ 799741, /* 799744 */ 800759, /* 800768 */ 801791, /* 801792 */ 802811, /* 802816 */ 803819, /* 803840 */ 804857, /* 804864 */ 805877, /* 805888 */ 806903, /* 806912 */ 807931, /* 807936 */ 808957, /* 808960 */ 809983, /* 809984 */ 810989, /* 811008 */ 812011, /* 812032 */ 813049, /* 813056 */ 814069, /* 814080 */ 815063, /* 815104 */ 816121, /* 816128 */ 817151, /* 817152 */ 818173, /* 818176 */ 819187, /* 819200 */ 820223, /* 820224 */ 821209, /* 821248 */ 822259, /* 822272 */ 823283, /* 823296 */ 824287, /* 824320 */ 825343, /* 825344 */ 826363, /* 826368 */ 827389, /* 827392 */ 828409, /* 828416 */ 829399, /* 829440 */ 830449, /* 830464 */ 831461, /* 831488 */ 832499, /* 832512 */ 833509, /* 833536 */ 834527, /* 834560 */ 835559, /* 835584 */ 836573, /* 836608 */ 837631, /* 837632 */ 838633, /* 838656 */ 839669, /* 839680 */ 840703, /* 840704 */ 841727, /* 841728 */ 842747, /* 842752 */ 843763, /* 843776 */ 844777, /* 844800 */ 845809, /* 845824 */ 846841, /* 846848 */ 847871, /* 847872 */ 848893, /* 848896 */ 849917, /* 849920 */ 850943, /* 850944 */ 851957, /* 851968 */ 852989, /* 852992 */ 853999, /* 854016 */ 855031, /* 855040 */ 856061, /* 856064 */ 857083, /* 857088 */ 858103, /* 858112 */ 859121, /* 859136 */ 860143, /* 860160 */ 861167, /* 861184 */ 862207, /* 862208 */ 863231, /* 863232 */ 864251, /* 864256 */ 865261, /* 865280 */ 866293, /* 866304 */ 867319, /* 867328 */ 868349, /* 868352 */ 869371, /* 869376 */ 870391, /* 870400 */ 871393, /* 871424 */ 872441, /* 872448 */ 873469, /* 873472 */ 874487, /* 874496 */ 875519, /* 875520 */ 876529, /* 876544 */ 877567, /* 877568 */ 878573, /* 878592 */ 879607, /* 879616 */ 880603, /* 880640 */ 881663, /* 881664 */ 882659, /* 882688 */ 883703, /* 883712 */ 884717, /* 884736 */ 885737, /* 885760 */ 886777, /* 886784 */ 887759, /* 887808 */ 888827, /* 888832 */ 889829, /* 889856 */ 890867, /* 890880 */ 891899, /* 891904 */ 892919, /* 892928 */ 893939, /* 893952 */ 894973, /* 894976 */ 895987, /* 896000 */ 897019, /* 897024 */ 898033, /* 898048 */ 899069, /* 899072 */ 900091, /* 900096 */ 901111, /* 901120 */ 902141, /* 902144 */ 903163, /* 903168 */ 904181, /* 904192 */ 905213, /* 905216 */ 906233, /* 906240 */ 907259, /* 907264 */ 908287, /* 908288 */ 909301, /* 909312 */ 910307, /* 910336 */ 911359, /* 911360 */ 912367, /* 912384 */ 913397, /* 913408 */ 914429, /* 914432 */ 915451, /* 915456 */ 916477, /* 916480 */ 917503, /* 917504 */ 918497, /* 918528 */ 919531, /* 919552 */ 920561, /* 920576 */ 921589, /* 921600 */ 922619, /* 922624 */ 923641, /* 923648 */ 924661, /* 924672 */ 925679, /* 925696 */ 926707, /* 926720 */ 927743, /* 927744 */ 928703, /* 928768 */ 929791, /* 929792 */ 930779, /* 930816 */ 931837, /* 931840 */ 932863, /* 932864 */ 933883, /* 933888 */ 934909, /* 934912 */ 935903, /* 935936 */ 936953, /* 936960 */ 937969, /* 937984 */ 939007, /* 939008 */ 940031, /* 940032 */ 941041, /* 941056 */ 942079, /* 942080 */ 943097, /* 943104 */ 944123, /* 944128 */ 945151, /* 945152 */ 946163, /* 946176 */ 947197, /* 947200 */ 948187, /* 948224 */ 949243, /* 949248 */ 950269, /* 950272 */ 951283, /* 951296 */ 952313, /* 952320 */ 953341, /* 953344 */ 954367, /* 954368 */ 955391, /* 955392 */ 956401, /* 956416 */ 957433, /* 957440 */ 958459, /* 958464 */ 959479, /* 959488 */ 960499, /* 960512 */ 961531, /* 961536 */ 962543, /* 962560 */ 963581, /* 963584 */ 964589, /* 964608 */ 965623, /* 965632 */ 966653, /* 966656 */ 967667, /* 967680 */ 968699, /* 968704 */ 969721, /* 969728 */ 970747, /* 970752 */ 971767, /* 971776 */ 972799, /* 972800 */ 973823, /* 973824 */ 974837, /* 974848 */ 975869, /* 975872 */ 976883, /* 976896 */ 977897, /* 977920 */ 978931, /* 978944 */ 979949, /* 979968 */ 980963, /* 980992 */ 981983, /* 982016 */ 982981, /* 983040 */ 984059, /* 984064 */ 985079, /* 985088 */ 986101, /* 986112 */ 987127, /* 987136 */ 988157, /* 988160 */ 989173, /* 989184 */ 990181, /* 990208 */ 991229, /* 991232 */ 992249, /* 992256 */ 993269, /* 993280 */ 994303, /* 994304 */ 995327, /* 995328 */ 996329, /* 996352 */ 997369, /* 997376 */ 998399, /* 998400 */ 999389, /* 999424 */ 1000429, /* 1000448 */ 1001467, /* 1001472 */ 1002493, /* 1002496 */ 1003517, /* 1003520 */ 1004537, /* 1004544 */ 1005553, /* 1005568 */ 1006589, /* 1006592 */ 1007609, /* 1007616 */ 1008617, /* 1008640 */ 1009651, /* 1009664 */ 1010687, /* 1010688 */ 1011697, /* 1011712 */ 1012733, /* 1012736 */ 1013741, /* 1013760 */ 1014779, /* 1014784 */ 1015769, /* 1015808 */ 1016789, /* 1016832 */ 1017851, /* 1017856 */ 1018879, /* 1018880 */ 1019903, /* 1019904 */ 1020913, /* 1020928 */ 1021919, /* 1021952 */ 1022963, /* 1022976 */ 1023991, /* 1024000 */ 1025021, /* 1025024 */ 1026043, /* 1026048 */ 1027067, /* 1027072 */ 1028089, /* 1028096 */ 1029113, /* 1029120 */ 1030121, /* 1030144 */ 1031161, /* 1031168 */ 1032191, /* 1032192 */ 1033189, /* 1033216 */ 1034239, /* 1034240 */ 1035263, /* 1035264 */ 1036271, /* 1036288 */ 1037303, /* 1037312 */ 1038329, /* 1038336 */ 1039351, /* 1039360 */ 1040381, /* 1040384 */ 1041373, /* 1041408 */ 1042427, /* 1042432 */ 1043453, /* 1043456 */ 1044479, /* 1044480 */ 1045493, /* 1045504 */ 1046527, /* 1046528 */ 1047551, /* 1047552 */ }; /* 0-128M, increments=102400 */ static unsigned prime_table3[1024]={ 131071, /* 131072 */ 262139, /* 262144 */ 393209, /* 393216 */ 524287, /* 524288 */ 655357, /* 655360 */ 786431, /* 786432 */ 917503, /* 917504 */ 1048573, /* 1048576 */ 1179641, /* 1179648 */ 1310719, /* 1310720 */ 1441771, /* 1441792 */ 1572853, /* 1572864 */ 1703903, /* 1703936 */ 1835003, /* 1835008 */ 1966079, /* 1966080 */ 2097143, /* 2097152 */ 2228221, /* 2228224 */ 2359267, /* 2359296 */ 2490337, /* 2490368 */ 2621431, /* 2621440 */ 2752499, /* 2752512 */ 2883577, /* 2883584 */ 3014653, /* 3014656 */ 3145721, /* 3145728 */ 3276799, /* 3276800 */ 3407857, /* 3407872 */ 3538933, /* 3538944 */ 3670013, /* 3670016 */ 3801073, /* 3801088 */ 3932153, /* 3932160 */ 4063217, /* 4063232 */ 4194301, /* 4194304 */ 4325359, /* 4325376 */ 4456433, /* 4456448 */ 4587503, /* 4587520 */ 4718579, /* 4718592 */ 4849651, /* 4849664 */ 4980727, /* 4980736 */ 5111791, /* 5111808 */ 5242877, /* 5242880 */ 5373931, /* 5373952 */ 5505023, /* 5505024 */ 5636077, /* 5636096 */ 5767129, /* 5767168 */ 5898209, /* 5898240 */ 6029299, /* 6029312 */ 6160381, /* 6160384 */ 6291449, /* 6291456 */ 6422519, /* 6422528 */ 6553577, /* 6553600 */ 6684659, /* 6684672 */ 6815741, /* 6815744 */ 6946813, /* 6946816 */ 7077883, /* 7077888 */ 7208951, /* 7208960 */ 7340009, /* 7340032 */ 7471099, /* 7471104 */ 7602151, /* 7602176 */ 7733233, /* 7733248 */ 7864301, /* 7864320 */ 7995391, /* 7995392 */ 8126453, /* 8126464 */ 8257531, /* 8257536 */ 8388593, /* 8388608 */ 8519647, /* 8519680 */ 8650727, /* 8650752 */ 8781797, /* 8781824 */ 8912887, /* 8912896 */ 9043967, /* 9043968 */ 9175037, /* 9175040 */ 9306097, /* 9306112 */ 9437179, /* 9437184 */ 9568219, /* 9568256 */ 9699323, /* 9699328 */ 9830393, /* 9830400 */ 9961463, /* 9961472 */ 10092539, /* 10092544 */ 10223593, /* 10223616 */ 10354667, /* 10354688 */ 10485751, /* 10485760 */ 10616831, /* 10616832 */ 10747903, /* 10747904 */ 10878961, /* 10878976 */ 11010037, /* 11010048 */ 11141113, /* 11141120 */ 11272181, /* 11272192 */ 11403247, /* 11403264 */ 11534329, /* 11534336 */ 11665403, /* 11665408 */ 11796469, /* 11796480 */ 11927551, /* 11927552 */ 12058621, /* 12058624 */ 12189677, /* 12189696 */ 12320753, /* 12320768 */ 12451807, /* 12451840 */ 12582893, /* 12582912 */ 12713959, /* 12713984 */ 12845033, /* 12845056 */ 12976121, /* 12976128 */ 13107197, /* 13107200 */ 13238263, /* 13238272 */ 13369333, /* 13369344 */ 13500373, /* 13500416 */ 13631477, /* 13631488 */ 13762549, /* 13762560 */ 13893613, /* 13893632 */ 14024671, /* 14024704 */ 14155763, /* 14155776 */ 14286809, /* 14286848 */ 14417881, /* 14417920 */ 14548979, /* 14548992 */ 14680063, /* 14680064 */ 14811133, /* 14811136 */ 14942197, /* 14942208 */ 15073277, /* 15073280 */ 15204349, /* 15204352 */ 15335407, /* 15335424 */ 15466463, /* 15466496 */ 15597559, /* 15597568 */ 15728611, /* 15728640 */ 15859687, /* 15859712 */ 15990781, /* 15990784 */ 16121849, /* 16121856 */ 16252919, /* 16252928 */ 16383977, /* 16384000 */ 16515067, /* 16515072 */ 16646099, /* 16646144 */ 16777213, /* 16777216 */ 16908263, /* 16908288 */ 17039339, /* 17039360 */ 17170429, /* 17170432 */ 17301463, /* 17301504 */ 17432561, /* 17432576 */ 17563633, /* 17563648 */ 17694709, /* 17694720 */ 17825791, /* 17825792 */ 17956849, /* 17956864 */ 18087899, /* 18087936 */ 18219001, /* 18219008 */ 18350063, /* 18350080 */ 18481097, /* 18481152 */ 18612211, /* 18612224 */ 18743281, /* 18743296 */ 18874367, /* 18874368 */ 19005433, /* 19005440 */ 19136503, /* 19136512 */ 19267561, /* 19267584 */ 19398647, /* 19398656 */ 19529717, /* 19529728 */ 19660799, /* 19660800 */ 19791869, /* 19791872 */ 19922923, /* 19922944 */ 20054011, /* 20054016 */ 20185051, /* 20185088 */ 20316151, /* 20316160 */ 20447191, /* 20447232 */ 20578297, /* 20578304 */ 20709347, /* 20709376 */ 20840429, /* 20840448 */ 20971507, /* 20971520 */ 21102583, /* 21102592 */ 21233651, /* 21233664 */ 21364727, /* 21364736 */ 21495797, /* 21495808 */ 21626819, /* 21626880 */ 21757951, /* 21757952 */ 21889019, /* 21889024 */ 22020091, /* 22020096 */ 22151167, /* 22151168 */ 22282199, /* 22282240 */ 22413289, /* 22413312 */ 22544351, /* 22544384 */ 22675403, /* 22675456 */ 22806521, /* 22806528 */ 22937591, /* 22937600 */ 23068667, /* 23068672 */ 23199731, /* 23199744 */ 23330773, /* 23330816 */ 23461877, /* 23461888 */ 23592937, /* 23592960 */ 23724031, /* 23724032 */ 23855101, /* 23855104 */ 23986159, /* 23986176 */ 24117217, /* 24117248 */ 24248299, /* 24248320 */ 24379391, /* 24379392 */ 24510463, /* 24510464 */ 24641479, /* 24641536 */ 24772603, /* 24772608 */ 24903667, /* 24903680 */ 25034731, /* 25034752 */ 25165813, /* 25165824 */ 25296893, /* 25296896 */ 25427957, /* 25427968 */ 25559033, /* 25559040 */ 25690097, /* 25690112 */ 25821179, /* 25821184 */ 25952243, /* 25952256 */ 26083273, /* 26083328 */ 26214379, /* 26214400 */ 26345471, /* 26345472 */ 26476543, /* 26476544 */ 26607611, /* 26607616 */ 26738687, /* 26738688 */ 26869753, /* 26869760 */ 27000817, /* 27000832 */ 27131903, /* 27131904 */ 27262931, /* 27262976 */ 27394019, /* 27394048 */ 27525109, /* 27525120 */ 27656149, /* 27656192 */ 27787213, /* 27787264 */ 27918323, /* 27918336 */ 28049407, /* 28049408 */ 28180459, /* 28180480 */ 28311541, /* 28311552 */ 28442551, /* 28442624 */ 28573673, /* 28573696 */ 28704749, /* 28704768 */ 28835819, /* 28835840 */ 28966909, /* 28966912 */ 29097977, /* 29097984 */ 29229047, /* 29229056 */ 29360087, /* 29360128 */ 29491193, /* 29491200 */ 29622269, /* 29622272 */ 29753341, /* 29753344 */ 29884411, /* 29884416 */ 30015481, /* 30015488 */ 30146531, /* 30146560 */ 30277627, /* 30277632 */ 30408701, /* 30408704 */ 30539749, /* 30539776 */ 30670847, /* 30670848 */ 30801917, /* 30801920 */ 30932987, /* 30932992 */ 31064063, /* 31064064 */ 31195117, /* 31195136 */ 31326181, /* 31326208 */ 31457269, /* 31457280 */ 31588351, /* 31588352 */ 31719409, /* 31719424 */ 31850491, /* 31850496 */ 31981567, /* 31981568 */ 32112607, /* 32112640 */ 32243707, /* 32243712 */ 32374781, /* 32374784 */ 32505829, /* 32505856 */ 32636921, /* 32636928 */ 32767997, /* 32768000 */ 32899037, /* 32899072 */ 33030121, /* 33030144 */ 33161201, /* 33161216 */ 33292283, /* 33292288 */ 33423319, /* 33423360 */ 33554393, /* 33554432 */ 33685493, /* 33685504 */ 33816571, /* 33816576 */ 33947621, /* 33947648 */ 34078699, /* 34078720 */ 34209787, /* 34209792 */ 34340861, /* 34340864 */ 34471933, /* 34471936 */ 34602991, /* 34603008 */ 34734079, /* 34734080 */ 34865141, /* 34865152 */ 34996223, /* 34996224 */ 35127263, /* 35127296 */ 35258347, /* 35258368 */ 35389423, /* 35389440 */ 35520467, /* 35520512 */ 35651579, /* 35651584 */ 35782613, /* 35782656 */ 35913727, /* 35913728 */ 36044797, /* 36044800 */ 36175871, /* 36175872 */ 36306937, /* 36306944 */ 36438013, /* 36438016 */ 36569083, /* 36569088 */ 36700159, /* 36700160 */ 36831227, /* 36831232 */ 36962291, /* 36962304 */ 37093373, /* 37093376 */ 37224437, /* 37224448 */ 37355503, /* 37355520 */ 37486591, /* 37486592 */ 37617653, /* 37617664 */ 37748717, /* 37748736 */ 37879783, /* 37879808 */ 38010871, /* 38010880 */ 38141951, /* 38141952 */ 38273023, /* 38273024 */ 38404081, /* 38404096 */ 38535151, /* 38535168 */ 38666219, /* 38666240 */ 38797303, /* 38797312 */ 38928371, /* 38928384 */ 39059431, /* 39059456 */ 39190519, /* 39190528 */ 39321599, /* 39321600 */ 39452671, /* 39452672 */ 39583727, /* 39583744 */ 39714799, /* 39714816 */ 39845887, /* 39845888 */ 39976939, /* 39976960 */ 40108027, /* 40108032 */ 40239103, /* 40239104 */ 40370173, /* 40370176 */ 40501231, /* 40501248 */ 40632313, /* 40632320 */ 40763369, /* 40763392 */ 40894457, /* 40894464 */ 41025499, /* 41025536 */ 41156569, /* 41156608 */ 41287651, /* 41287680 */ 41418739, /* 41418752 */ 41549803, /* 41549824 */ 41680871, /* 41680896 */ 41811949, /* 41811968 */ 41943023, /* 41943040 */ 42074101, /* 42074112 */ 42205183, /* 42205184 */ 42336253, /* 42336256 */ 42467317, /* 42467328 */ 42598397, /* 42598400 */ 42729437, /* 42729472 */ 42860537, /* 42860544 */ 42991609, /* 42991616 */ 43122683, /* 43122688 */ 43253759, /* 43253760 */ 43384813, /* 43384832 */ 43515881, /* 43515904 */ 43646963, /* 43646976 */ 43778011, /* 43778048 */ 43909111, /* 43909120 */ 44040187, /* 44040192 */ 44171261, /* 44171264 */ 44302303, /* 44302336 */ 44433391, /* 44433408 */ 44564461, /* 44564480 */ 44695549, /* 44695552 */ 44826611, /* 44826624 */ 44957687, /* 44957696 */ 45088739, /* 45088768 */ 45219827, /* 45219840 */ 45350869, /* 45350912 */ 45481973, /* 45481984 */ 45613039, /* 45613056 */ 45744121, /* 45744128 */ 45875191, /* 45875200 */ 46006249, /* 46006272 */ 46137319, /* 46137344 */ 46268381, /* 46268416 */ 46399471, /* 46399488 */ 46530557, /* 46530560 */ 46661627, /* 46661632 */ 46792699, /* 46792704 */ 46923761, /* 46923776 */ 47054809, /* 47054848 */ 47185907, /* 47185920 */ 47316991, /* 47316992 */ 47448061, /* 47448064 */ 47579131, /* 47579136 */ 47710207, /* 47710208 */ 47841257, /* 47841280 */ 47972341, /* 47972352 */ 48103417, /* 48103424 */ 48234451, /* 48234496 */ 48365563, /* 48365568 */ 48496639, /* 48496640 */ 48627697, /* 48627712 */ 48758783, /* 48758784 */ 48889837, /* 48889856 */ 49020913, /* 49020928 */ 49151987, /* 49152000 */ 49283063, /* 49283072 */ 49414111, /* 49414144 */ 49545193, /* 49545216 */ 49676267, /* 49676288 */ 49807327, /* 49807360 */ 49938431, /* 49938432 */ 50069497, /* 50069504 */ 50200573, /* 50200576 */ 50331599, /* 50331648 */ 50462683, /* 50462720 */ 50593783, /* 50593792 */ 50724859, /* 50724864 */ 50855899, /* 50855936 */ 50987003, /* 50987008 */ 51118069, /* 51118080 */ 51249131, /* 51249152 */ 51380179, /* 51380224 */ 51511277, /* 51511296 */ 51642341, /* 51642368 */ 51773431, /* 51773440 */ 51904511, /* 51904512 */ 52035569, /* 52035584 */ 52166641, /* 52166656 */ 52297717, /* 52297728 */ 52428767, /* 52428800 */ 52559867, /* 52559872 */ 52690919, /* 52690944 */ 52821983, /* 52822016 */ 52953077, /* 52953088 */ 53084147, /* 53084160 */ 53215229, /* 53215232 */ 53346301, /* 53346304 */ 53477357, /* 53477376 */ 53608441, /* 53608448 */ 53739493, /* 53739520 */ 53870573, /* 53870592 */ 54001663, /* 54001664 */ 54132721, /* 54132736 */ 54263789, /* 54263808 */ 54394877, /* 54394880 */ 54525917, /* 54525952 */ 54656983, /* 54657024 */ 54788089, /* 54788096 */ 54919159, /* 54919168 */ 55050217, /* 55050240 */ 55181311, /* 55181312 */ 55312351, /* 55312384 */ 55443433, /* 55443456 */ 55574507, /* 55574528 */ 55705589, /* 55705600 */ 55836659, /* 55836672 */ 55967701, /* 55967744 */ 56098813, /* 56098816 */ 56229881, /* 56229888 */ 56360911, /* 56360960 */ 56491993, /* 56492032 */ 56623093, /* 56623104 */ 56754167, /* 56754176 */ 56885219, /* 56885248 */ 57016319, /* 57016320 */ 57147379, /* 57147392 */ 57278461, /* 57278464 */ 57409529, /* 57409536 */ 57540599, /* 57540608 */ 57671671, /* 57671680 */ 57802739, /* 57802752 */ 57933817, /* 57933824 */ 58064861, /* 58064896 */ 58195939, /* 58195968 */ 58327039, /* 58327040 */ 58458091, /* 58458112 */ 58589161, /* 58589184 */ 58720253, /* 58720256 */ 58851307, /* 58851328 */ 58982389, /* 58982400 */ 59113469, /* 59113472 */ 59244539, /* 59244544 */ 59375587, /* 59375616 */ 59506679, /* 59506688 */ 59637733, /* 59637760 */ 59768831, /* 59768832 */ 59899901, /* 59899904 */ 60030953, /* 60030976 */ 60162029, /* 60162048 */ 60293119, /* 60293120 */ 60424183, /* 60424192 */ 60555227, /* 60555264 */ 60686321, /* 60686336 */ 60817397, /* 60817408 */ 60948479, /* 60948480 */ 61079531, /* 61079552 */ 61210603, /* 61210624 */ 61341659, /* 61341696 */ 61472753, /* 61472768 */ 61603811, /* 61603840 */ 61734899, /* 61734912 */ 61865971, /* 61865984 */ 61997053, /* 61997056 */ 62128127, /* 62128128 */ 62259193, /* 62259200 */ 62390261, /* 62390272 */ 62521331, /* 62521344 */ 62652407, /* 62652416 */ 62783477, /* 62783488 */ 62914549, /* 62914560 */ 63045613, /* 63045632 */ 63176693, /* 63176704 */ 63307763, /* 63307776 */ 63438839, /* 63438848 */ 63569917, /* 63569920 */ 63700991, /* 63700992 */ 63832057, /* 63832064 */ 63963131, /* 63963136 */ 64094207, /* 64094208 */ 64225267, /* 64225280 */ 64356349, /* 64356352 */ 64487417, /* 64487424 */ 64618493, /* 64618496 */ 64749563, /* 64749568 */ 64880587, /* 64880640 */ 65011703, /* 65011712 */ 65142769, /* 65142784 */ 65273851, /* 65273856 */ 65404909, /* 65404928 */ 65535989, /* 65536000 */ 65667067, /* 65667072 */ 65798137, /* 65798144 */ 65929211, /* 65929216 */ 66060277, /* 66060288 */ 66191351, /* 66191360 */ 66322427, /* 66322432 */ 66453479, /* 66453504 */ 66584561, /* 66584576 */ 66715643, /* 66715648 */ 66846709, /* 66846720 */ 66977767, /* 66977792 */ 67108859, /* 67108864 */ 67239883, /* 67239936 */ 67370999, /* 67371008 */ 67502063, /* 67502080 */ 67633127, /* 67633152 */ 67764223, /* 67764224 */ 67895251, /* 67895296 */ 68026363, /* 68026368 */ 68157433, /* 68157440 */ 68288503, /* 68288512 */ 68419567, /* 68419584 */ 68550631, /* 68550656 */ 68681719, /* 68681728 */ 68812769, /* 68812800 */ 68943851, /* 68943872 */ 69074933, /* 69074944 */ 69205987, /* 69206016 */ 69337087, /* 69337088 */ 69468151, /* 69468160 */ 69599221, /* 69599232 */ 69730303, /* 69730304 */ 69861331, /* 69861376 */ 69992443, /* 69992448 */ 70123513, /* 70123520 */ 70254563, /* 70254592 */ 70385641, /* 70385664 */ 70516729, /* 70516736 */ 70647793, /* 70647808 */ 70778861, /* 70778880 */ 70909933, /* 70909952 */ 71041021, /* 71041024 */ 71172091, /* 71172096 */ 71303153, /* 71303168 */ 71434229, /* 71434240 */ 71565283, /* 71565312 */ 71696363, /* 71696384 */ 71827423, /* 71827456 */ 71958521, /* 71958528 */ 72089573, /* 72089600 */ 72220663, /* 72220672 */ 72351733, /* 72351744 */ 72482807, /* 72482816 */ 72613861, /* 72613888 */ 72744937, /* 72744960 */ 72876031, /* 72876032 */ 73007089, /* 73007104 */ 73138171, /* 73138176 */ 73269247, /* 73269248 */ 73400311, /* 73400320 */ 73531379, /* 73531392 */ 73662461, /* 73662464 */ 73793521, /* 73793536 */ 73924583, /* 73924608 */ 74055637, /* 74055680 */ 74186747, /* 74186752 */ 74317801, /* 74317824 */ 74448877, /* 74448896 */ 74579951, /* 74579968 */ 74711027, /* 74711040 */ 74842099, /* 74842112 */ 74973181, /* 74973184 */ 75104243, /* 75104256 */ 75235327, /* 75235328 */ 75366397, /* 75366400 */ 75497467, /* 75497472 */ 75628513, /* 75628544 */ 75759613, /* 75759616 */ 75890653, /* 75890688 */ 76021661, /* 76021760 */ 76152821, /* 76152832 */ 76283897, /* 76283904 */ 76414973, /* 76414976 */ 76546039, /* 76546048 */ 76677113, /* 76677120 */ 76808119, /* 76808192 */ 76939253, /* 76939264 */ 77070317, /* 77070336 */ 77201347, /* 77201408 */ 77332471, /* 77332480 */ 77463541, /* 77463552 */ 77594599, /* 77594624 */ 77725691, /* 77725696 */ 77856767, /* 77856768 */ 77987821, /* 77987840 */ 78118903, /* 78118912 */ 78249973, /* 78249984 */ 78381047, /* 78381056 */ 78512101, /* 78512128 */ 78643199, /* 78643200 */ 78774259, /* 78774272 */ 78905303, /* 78905344 */ 79036411, /* 79036416 */ 79167479, /* 79167488 */ 79298543, /* 79298560 */ 79429619, /* 79429632 */ 79560673, /* 79560704 */ 79691761, /* 79691776 */ 79822829, /* 79822848 */ 79953901, /* 79953920 */ 80084969, /* 80084992 */ 80216063, /* 80216064 */ 80347103, /* 80347136 */ 80478199, /* 80478208 */ 80609279, /* 80609280 */ 80740339, /* 80740352 */ 80871419, /* 80871424 */ 81002489, /* 81002496 */ 81133567, /* 81133568 */ 81264587, /* 81264640 */ 81395683, /* 81395712 */ 81526763, /* 81526784 */ 81657841, /* 81657856 */ 81788923, /* 81788928 */ 81919993, /* 81920000 */ 82051043, /* 82051072 */ 82182137, /* 82182144 */ 82313213, /* 82313216 */ 82444279, /* 82444288 */ 82575331, /* 82575360 */ 82706431, /* 82706432 */ 82837501, /* 82837504 */ 82968563, /* 82968576 */ 83099641, /* 83099648 */ 83230717, /* 83230720 */ 83361781, /* 83361792 */ 83492863, /* 83492864 */ 83623931, /* 83623936 */ 83754997, /* 83755008 */ 83886053, /* 83886080 */ 84017117, /* 84017152 */ 84148213, /* 84148224 */ 84279277, /* 84279296 */ 84410353, /* 84410368 */ 84541421, /* 84541440 */ 84672487, /* 84672512 */ 84803581, /* 84803584 */ 84934621, /* 84934656 */ 85065719, /* 85065728 */ 85196789, /* 85196800 */ 85327849, /* 85327872 */ 85458929, /* 85458944 */ 85589989, /* 85590016 */ 85721081, /* 85721088 */ 85852147, /* 85852160 */ 85983217, /* 85983232 */ 86114279, /* 86114304 */ 86245343, /* 86245376 */ 86376443, /* 86376448 */ 86507507, /* 86507520 */ 86638577, /* 86638592 */ 86769647, /* 86769664 */ 86900731, /* 86900736 */ 87031759, /* 87031808 */ 87162857, /* 87162880 */ 87293939, /* 87293952 */ 87425021, /* 87425024 */ 87556087, /* 87556096 */ 87687167, /* 87687168 */ 87818239, /* 87818240 */ 87949307, /* 87949312 */ 88080359, /* 88080384 */ 88211449, /* 88211456 */ 88342519, /* 88342528 */ 88473569, /* 88473600 */ 88604653, /* 88604672 */ 88735721, /* 88735744 */ 88866797, /* 88866816 */ 88997827, /* 88997888 */ 89128939, /* 89128960 */ 89260027, /* 89260032 */ 89391103, /* 89391104 */ 89522171, /* 89522176 */ 89653217, /* 89653248 */ 89784313, /* 89784320 */ 89915383, /* 89915392 */ 90046441, /* 90046464 */ 90177533, /* 90177536 */ 90308599, /* 90308608 */ 90439667, /* 90439680 */ 90570751, /* 90570752 */ 90701797, /* 90701824 */ 90832871, /* 90832896 */ 90963967, /* 90963968 */ 91095013, /* 91095040 */ 91226101, /* 91226112 */ 91357177, /* 91357184 */ 91488251, /* 91488256 */ 91619321, /* 91619328 */ 91750391, /* 91750400 */ 91881443, /* 91881472 */ 92012537, /* 92012544 */ 92143609, /* 92143616 */ 92274671, /* 92274688 */ 92405723, /* 92405760 */ 92536823, /* 92536832 */ 92667863, /* 92667904 */ 92798969, /* 92798976 */ 92930039, /* 92930048 */ 93061117, /* 93061120 */ 93192191, /* 93192192 */ 93323249, /* 93323264 */ 93454307, /* 93454336 */ 93585379, /* 93585408 */ 93716471, /* 93716480 */ 93847549, /* 93847552 */ 93978559, /* 93978624 */ 94109681, /* 94109696 */ 94240733, /* 94240768 */ 94371833, /* 94371840 */ 94502899, /* 94502912 */ 94633963, /* 94633984 */ 94765039, /* 94765056 */ 94896119, /* 94896128 */ 95027197, /* 95027200 */ 95158249, /* 95158272 */ 95289329, /* 95289344 */ 95420401, /* 95420416 */ 95551487, /* 95551488 */ 95682541, /* 95682560 */ 95813621, /* 95813632 */ 95944691, /* 95944704 */ 96075739, /* 96075776 */ 96206839, /* 96206848 */ 96337919, /* 96337920 */ 96468979, /* 96468992 */ 96600041, /* 96600064 */ 96731101, /* 96731136 */ 96862169, /* 96862208 */ 96993269, /* 96993280 */ 97124347, /* 97124352 */ 97255409, /* 97255424 */ 97386467, /* 97386496 */ 97517543, /* 97517568 */ 97648637, /* 97648640 */ 97779701, /* 97779712 */ 97910759, /* 97910784 */ 98041831, /* 98041856 */ 98172887, /* 98172928 */ 98303999, /* 98304000 */ 98435063, /* 98435072 */ 98566121, /* 98566144 */ 98697187, /* 98697216 */ 98828281, /* 98828288 */ 98959337, /* 98959360 */ 99090427, /* 99090432 */ 99221489, /* 99221504 */ 99352567, /* 99352576 */ 99483647, /* 99483648 */ 99614689, /* 99614720 */ 99745787, /* 99745792 */ 99876851, /* 99876864 */ 100007927, /* 100007936 */ 100138979, /* 100139008 */ 100270069, /* 100270080 */ 100401139, /* 100401152 */ 100532207, /* 100532224 */ 100663291, /* 100663296 */ 100794319, /* 100794368 */ 100925431, /* 100925440 */ 101056507, /* 101056512 */ 101187577, /* 101187584 */ 101318647, /* 101318656 */ 101449717, /* 101449728 */ 101580793, /* 101580800 */ 101711839, /* 101711872 */ 101842931, /* 101842944 */ 101974009, /* 101974016 */ 102105049, /* 102105088 */ 102236149, /* 102236160 */ 102367189, /* 102367232 */ 102498301, /* 102498304 */ 102629369, /* 102629376 */ 102760387, /* 102760448 */ 102891499, /* 102891520 */ 103022537, /* 103022592 */ 103153649, /* 103153664 */ 103284733, /* 103284736 */ 103415791, /* 103415808 */ 103546879, /* 103546880 */ 103677949, /* 103677952 */ 103809011, /* 103809024 */ 103940093, /* 103940096 */ 104071157, /* 104071168 */ 104202233, /* 104202240 */ 104333311, /* 104333312 */ 104464369, /* 104464384 */ 104595397, /* 104595456 */ 104726527, /* 104726528 */ 104857589, /* 104857600 */ 104988641, /* 104988672 */ 105119741, /* 105119744 */ 105250811, /* 105250816 */ 105381841, /* 105381888 */ 105512951, /* 105512960 */ 105644029, /* 105644032 */ 105775079, /* 105775104 */ 105906167, /* 105906176 */ 106037237, /* 106037248 */ 106168319, /* 106168320 */ 106299379, /* 106299392 */ 106430449, /* 106430464 */ 106561523, /* 106561536 */ 106692601, /* 106692608 */ 106823677, /* 106823680 */ 106954747, /* 106954752 */ 107085799, /* 107085824 */ 107216891, /* 107216896 */ 107347943, /* 107347968 */ 107479033, /* 107479040 */ 107610079, /* 107610112 */ 107741167, /* 107741184 */ 107872249, /* 107872256 */ 108003323, /* 108003328 */ 108134393, /* 108134400 */ 108265459, /* 108265472 */ 108396521, /* 108396544 */ 108527603, /* 108527616 */ 108658681, /* 108658688 */ 108789727, /* 108789760 */ 108920831, /* 108920832 */ 109051903, /* 109051904 */ 109182947, /* 109182976 */ 109314043, /* 109314048 */ 109445107, /* 109445120 */ 109576189, /* 109576192 */ 109707253, /* 109707264 */ 109838293, /* 109838336 */ 109969403, /* 109969408 */ 110100409, /* 110100480 */ 110231531, /* 110231552 */ 110362559, /* 110362624 */ 110493661, /* 110493696 */ 110624753, /* 110624768 */ 110755793, /* 110755840 */ 110886883, /* 110886912 */ 111017983, /* 111017984 */ 111148963, /* 111149056 */ 111280121, /* 111280128 */ 111411173, /* 111411200 */ 111542261, /* 111542272 */ 111673343, /* 111673344 */ 111804389, /* 111804416 */ 111935459, /* 111935488 */ 112066553, /* 112066560 */ 112197629, /* 112197632 */ 112328683, /* 112328704 */ 112459751, /* 112459776 */ 112590839, /* 112590848 */ 112721893, /* 112721920 */ 112852981, /* 112852992 */ 112984061, /* 112984064 */ 113115133, /* 113115136 */ 113246183, /* 113246208 */ 113377279, /* 113377280 */ 113508319, /* 113508352 */ 113639419, /* 113639424 */ 113770457, /* 113770496 */ 113901553, /* 113901568 */ 114032599, /* 114032640 */ 114163703, /* 114163712 */ 114294721, /* 114294784 */ 114425807, /* 114425856 */ 114556913, /* 114556928 */ 114687977, /* 114688000 */ 114819031, /* 114819072 */ 114950131, /* 114950144 */ 115081189, /* 115081216 */ 115212287, /* 115212288 */ 115343341, /* 115343360 */ 115474417, /* 115474432 */ 115605467, /* 115605504 */ 115736539, /* 115736576 */ 115867627, /* 115867648 */ 115998719, /* 115998720 */ 116129789, /* 116129792 */ 116260849, /* 116260864 */ 116391917, /* 116391936 */ 116523007, /* 116523008 */ 116654077, /* 116654080 */ 116785133, /* 116785152 */ 116916223, /* 116916224 */ 117047291, /* 117047296 */ 117178367, /* 117178368 */ 117309421, /* 117309440 */ 117440509, /* 117440512 */ 117571523, /* 117571584 */ 117702649, /* 117702656 */ 117833711, /* 117833728 */ 117964793, /* 117964800 */ 118095853, /* 118095872 */ 118226893, /* 118226944 */ 118358003, /* 118358016 */ 118489081, /* 118489088 */ 118620143, /* 118620160 */ 118751207, /* 118751232 */ 118882279, /* 118882304 */ 119013347, /* 119013376 */ 119144447, /* 119144448 */ 119275511, /* 119275520 */ 119406587, /* 119406592 */ 119537653, /* 119537664 */ 119668723, /* 119668736 */ 119799803, /* 119799808 */ 119930873, /* 119930880 */ 120061951, /* 120061952 */ 120193019, /* 120193024 */ 120324077, /* 120324096 */ 120455147, /* 120455168 */ 120586231, /* 120586240 */ 120717307, /* 120717312 */ 120848353, /* 120848384 */ 120979447, /* 120979456 */ 121110523, /* 121110528 */ 121241597, /* 121241600 */ 121372649, /* 121372672 */ 121503737, /* 121503744 */ 121634801, /* 121634816 */ 121765871, /* 121765888 */ 121896949, /* 121896960 */ 122028019, /* 122028032 */ 122159101, /* 122159104 */ 122290171, /* 122290176 */ 122421241, /* 122421248 */ 122552317, /* 122552320 */ 122683391, /* 122683392 */ 122814463, /* 122814464 */ 122945527, /* 122945536 */ 123076601, /* 123076608 */ 123207677, /* 123207680 */ 123338737, /* 123338752 */ 123469783, /* 123469824 */ 123600857, /* 123600896 */ 123731963, /* 123731968 */ 123863023, /* 123863040 */ 123994099, /* 123994112 */ 124125161, /* 124125184 */ 124256243, /* 124256256 */ 124387321, /* 124387328 */ 124518397, /* 124518400 */ 124649449, /* 124649472 */ 124780531, /* 124780544 */ 124911601, /* 124911616 */ 125042663, /* 125042688 */ 125173759, /* 125173760 */ 125304787, /* 125304832 */ 125435897, /* 125435904 */ 125566963, /* 125566976 */ 125698021, /* 125698048 */ 125829103, /* 125829120 */ 125960189, /* 125960192 */ 126091241, /* 126091264 */ 126222293, /* 126222336 */ 126353407, /* 126353408 */ 126484469, /* 126484480 */ 126615551, /* 126615552 */ 126746623, /* 126746624 */ 126877693, /* 126877696 */ 127008733, /* 127008768 */ 127139833, /* 127139840 */ 127270849, /* 127270912 */ 127401947, /* 127401984 */ 127533047, /* 127533056 */ 127664113, /* 127664128 */ 127795181, /* 127795200 */ 127926263, /* 127926272 */ 128057327, /* 128057344 */ 128188409, /* 128188416 */ 128319469, /* 128319488 */ 128450533, /* 128450560 */ 128581631, /* 128581632 */ 128712691, /* 128712704 */ 128843761, /* 128843776 */ 128974841, /* 128974848 */ 129105901, /* 129105920 */ 129236959, /* 129236992 */ 129368051, /* 129368064 */ 129499129, /* 129499136 */ 129630199, /* 129630208 */ 129761273, /* 129761280 */ 129892333, /* 129892352 */ 130023407, /* 130023424 */ 130154483, /* 130154496 */ 130285567, /* 130285568 */ 130416631, /* 130416640 */ 130547621, /* 130547712 */ 130678781, /* 130678784 */ 130809853, /* 130809856 */ 130940911, /* 130940928 */ 131071987, /* 131072000 */ 131203069, /* 131203072 */ 131334131, /* 131334144 */ 131465177, /* 131465216 */ 131596279, /* 131596288 */ 131727359, /* 131727360 */ 131858413, /* 131858432 */ 131989477, /* 131989504 */ 132120557, /* 132120576 */ 132251621, /* 132251648 */ 132382717, /* 132382720 */ 132513781, /* 132513792 */ 132644851, /* 132644864 */ 132775931, /* 132775936 */ 132907007, /* 132907008 */ 133038053, /* 133038080 */ 133169137, /* 133169152 */ 133300207, /* 133300224 */ 133431293, /* 133431296 */ 133562329, /* 133562368 */ 133693433, /* 133693440 */ 133824503, /* 133824512 */ 133955581, /* 133955584 */ 134086639, /* 134086656 */ }; int sf_nearest_prime( int n ) { if( n < 0 ) n = -n; if( n < 8192 ) { return prime_table0[(n>>3)& 1023]; } else if( n < 64*1024 ) { return prime_table1[(n>>6)&1023]; } else if( n < 1024*1024 ) { return prime_table2[(n>>10)&1023]; } else if( n < 128*1024*1024 ) { return prime_table3[(n>>17)&1023]; } else if( n < 1024*1024*1024 ) { return prime_table3[(n>>20)&1023]; } return 134086639; /* too big for table, just use a big prime */ } snort-2.9.15.1/src/sfutil/sfprimetable.h0000644000175200017520000000217113571422607014774 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2006-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #ifndef SF_PRIME_TABLE #define SF_PRIME_TABLE int sf_nearest_prime( int n ); #endif snort-2.9.15.1/src/sfutil/sf_ip.c0000644000175200017520000004127513571422607013422 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 1998-2013 Sourcefire, Inc. ** Adam Keeton ** Kevin Liu ** ** $Id$ ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Adam Keeton * sf_ip.c * 11/17/06 * * Library for managing IP addresses of either v6 or v4 families. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include /* For ceil */ #include "sf_types.h" /* For bool */ #include "sf_ip.h" /* For inet_pton */ #ifndef WIN32 #include #include #include #include #endif /* WIN32 */ /* Support function */ // note that an ip6 address may have a trailing dotted quad form // but that it always has at least 2 ':'s; furthermore there is // no valid ip4 format (including mask) with 2 ':'s // we don't have to figure out if the format is entirely legal // we just have to be able to tell correct formats apart static inline int sfip_str_to_fam(const char *str) { const char* s; ARG_CHECK1(str, 0); s = strchr(str, (int)':'); if ( s && strchr(s+1, (int)':') ) return AF_INET6; if ( strchr(str, (int)'.') ) return AF_INET; return AF_UNSPEC; } /* Place-holder allocation incase we want to do something more indepth later */ static inline sfcidr_t *_sfip_alloc() { /* Note: using calloc here instead of SnortAlloc since the dynamic libs * can't presently resolve SnortAlloc */ return (sfcidr_t*)calloc(sizeof(sfcidr_t), 1); } /* Support function for _netmask_str_to_bit_count */ static inline int _count_bits(unsigned int val) { unsigned int count; for (count = 0; val; count++) { val &= val - 1; } return count; } /* Support function for sfip_pton. Used for converting a netmask string * into a number of bits to mask off */ static inline int _netmask_str_to_bit_count(char *mask, int family) { uint32_t buf[4]; int bits, i, nBits, nBytes; uint8_t* bytes = (uint8_t*)buf; /* XXX * Mask not validated. * Only sfip_pton should be using this function, and using it safely. * XXX */ if(inet_pton(family, mask, buf) < 1) return -1; bits = _count_bits(buf[0]); if(family == AF_INET6) { bits += _count_bits(buf[1]); bits += _count_bits(buf[2]); bits += _count_bits(buf[3]); nBytes = 16; } else { nBytes = 4; } // now make sure that only the most significant bits are set nBits = bits; for ( i = 0; i < nBytes; i++ ) { if ( nBits >= 8 ) { if ( bytes[i] != 0xff ) return -1; nBits -= 8; } else if ( nBits == 0 ) { if ( bytes[i] != 0x00 ) return -1; } else { if ( bytes[i] != ((0xff00 >> nBits) & 0xff) ) return -1; nBits = 0; } } return bits; } /* Masks off 'val' bits from the IP contained within 'ip' */ static inline int sfip_cidr_mask(sfaddr_t *ip, int val) { uint32_t *p; int index = (int)ceil(val / 32.0) - 1; int bits; ARG_CHECK1(ip, SFIP_ARG_ERR); p = sfaddr_get_ip6_ptr(ip); if( val < 0 || val > 128) return SFIP_ARG_ERR; if (val == 128) return SFIP_SUCCESS; /* Build the netmask by converting "val" into * the corresponding number of bits that are set */ bits = 32 - (val - (index * 32)); if (bits) { unsigned int mask; mask = ~0; mask >>= bits; mask <<= bits; p[index] &= htonl(mask); } index++; /* 0 off the rest of the IP */ for( ; index<4; index++) p[index] = 0; return SFIP_SUCCESS; } /* Parses "src" and stores results in "dst" */ static SFIP_RET _sfip_pton(const char *src, sfaddr_t *dst, uint16_t *srcBits) { char *mask; char *sfip_buf; char *ip; int bits; int family; if(!dst || !src) return SFIP_ARG_ERR; if((sfip_buf = strdup(src)) == NULL) return SFIP_ALLOC_ERR; ip = sfip_buf; family = sfip_str_to_fam(src); /* skip whitespace or opening bracket */ while(isspace((int)*ip) || (*ip == '[')) ip++; /* check for and extract a mask in CIDR form */ if( (mask = strchr(ip, (int)'/')) != NULL ) { /* NULL out this character so inet_pton will see the * correct ending to the IP string */ char* end = mask++; while ( (end > ip) && isspace((int)end[-1]) ) end--; *end = 0; while(isspace((int)*mask)) mask++; /* verify a leading digit */ if(((family == AF_INET6) && !isxdigit((int)*mask)) || ((family == AF_INET) && !isdigit((int)*mask))) { free(sfip_buf); return SFIP_CIDR_ERR; } /* Check if there's a netmask here instead of the number of bits */ if(strchr(mask, (int)'.') || strchr(mask, (int)':')) bits = _netmask_str_to_bit_count(mask, sfip_str_to_fam(mask)); else bits = atoi(mask); } else if( /* If this is IPv4, ia ':' may used specified to indicate a netmask */ ((family == AF_INET) && (mask = strchr(ip, (int)':')) != NULL) || /* We've already skipped the leading whitespace, if there is more * whitespace, then there's probably a netmask specified after it. */ (mask = strchr(ip, (int)' ')) != NULL ) { char* end = mask++; while ( (end > ip) && isspace((int)end[-1]) ) end--; *end = 0; /* Now the IP will end at this point */ /* skip whitespace */ while(isspace((int)*mask)) mask++; /* Make sure we're either looking at a valid digit, or a leading * colon, such as can be the case with IPv6 */ if(((family == AF_INET) && isdigit((int)*mask)) || ((family == AF_INET6) && (isxdigit((int)*mask) || *mask == ':'))) { bits = _netmask_str_to_bit_count(mask, sfip_str_to_fam(mask)); } /* No netmask */ else { if(family == AF_INET) bits = 32; else bits = 128; } } /* No netmask */ else { if(family == AF_INET) bits = 32; else bits = 128; } if(sfip_convert_ip_text_to_binary(family, ip, sfaddr_get_ip6_ptr(dst)) != SFIP_SUCCESS) { free(sfip_buf); return SFIP_INET_PARSE_ERR; } dst->family = family; /* Store mask */ bits += (family == AF_INET && bits >= 0) ? 96 : 0; /* Apply mask */ if(sfip_cidr_mask(dst, bits) != SFIP_SUCCESS) { free(sfip_buf); return SFIP_INVALID_MASK; } *srcBits = bits; free(sfip_buf); return SFIP_SUCCESS; } /* Allocate IP address from a character array describing the IP */ sfcidr_t *sfip_alloc(const char *ip, SFIP_RET *status) { SFIP_RET tmp; sfcidr_t *ret; if(!ip) { if(status) *status = SFIP_ARG_ERR; return NULL; } if((ret = _sfip_alloc()) == NULL) { if(status) *status = SFIP_ALLOC_ERR; return NULL; } if( (tmp = sfip_pton(ip, ret)) != SFIP_SUCCESS) { if(status) *status = tmp; sfip_free(ret); return NULL; } if(status) *status = SFIP_SUCCESS; return ret; } /* Allocate IP address from a character array describing the IP */ sfaddr_t *sfaddr_alloc(const char *ip, SFIP_RET *status) { SFIP_RET tmp; sfaddr_t *ret; uint16_t bits; if(!ip) { if(status) *status = SFIP_ARG_ERR; return NULL; } if((ret = (sfaddr_t*)calloc(sizeof(sfaddr_t), 1)) == NULL) { if(status) *status = SFIP_ALLOC_ERR; return NULL; } if( (tmp = _sfip_pton(ip, ret, &bits)) != SFIP_SUCCESS ) { if(status) *status = tmp; sfaddr_free(ret); return NULL; } if (bits != 128) { if(status) *status = SFIP_INET_PARSE_ERR; sfaddr_free(ret); return NULL; } if(status) *status = SFIP_SUCCESS; return ret; } /* Allocate IP address from an array of 8 byte integers */ sfaddr_t *sfip_alloc_raw(void *ip, int family, SFIP_RET *status) { sfaddr_t *ret; if(!ip) { if(status) *status = SFIP_ARG_ERR; return NULL; } if((ret = (sfaddr_t*)calloc(sizeof(sfaddr_t), 1)) == NULL) { if(status) *status = SFIP_ALLOC_ERR; return NULL; } sfip_set_raw(ret, ip, family); if(status) *status = SFIP_SUCCESS; return ret; } /* Converts string IP format to an array of values. Also checks IP address format. Specifically look for issues that inet_pton either overlooks or is inconsistent about. */ SFIP_RET sfip_convert_ip_text_to_binary( const int family, const char *ip, void *dst) { const char *my_ip; sfaddr_t* addr; my_ip = ip; if( my_ip == NULL ) return( SFIP_FAILURE ); /* Across platforms, inet_pton() is inconsistent about leading 0's in AF_INET (ie IPv4 addresses. */ if( family == AF_INET ) { char chr; bool new_octet; new_octet = true; while( (chr = *my_ip++) != '\0') { /* If we are at the first char of a new octet, look for a leading zero followed by another digit */ if( new_octet && (chr == '0') && isdigit(*my_ip)) return( SFIP_INET_PARSE_ERR ); /* when we see an octet separator, set the flag to start looking for a leading zero. */ new_octet = (chr == '.'); } addr = (sfaddr_t*)dst; addr->ia32[0] = addr->ia32[1] = addr->ia16[4] = 0; addr->ia16[5] = 0xFFFF; dst = &addr->ia32[3]; } if( inet_pton(family, ip, dst) < 1 ) return( SFIP_INET_PARSE_ERR ); return( SFIP_SUCCESS ); /* Otherwise, ip is OK */ } SFIP_RET sfaddr_pton(const char *src, sfaddr_t *dst) { SFIP_RET ret; uint16_t bits; ret = _sfip_pton(src, dst, &bits); if (ret == SFIP_SUCCESS && bits != 128) return SFIP_INET_PARSE_ERR; return ret; } SFIP_RET sfip_pton(const char *src, sfcidr_t *dst) { return _sfip_pton(src, &dst->addr, &dst->bits); } /* Sets existing IP, "dst", to be source IP, "src" */ SFIP_RET sfip_set_raw(sfaddr_t *dst, const void *src, int family) { ARG_CHECK3(dst, src, sfaddr_get_ip6_ptr(dst), SFIP_ARG_ERR); dst->family = family; if(family == AF_INET) { dst->ia32[0] = dst->ia32[1] = dst->ia16[4] = 0; dst->ia16[5] = 0xFFFF; dst->ia32[3] = *(uint32_t*)src; } else if(family == AF_INET6) { memcpy(sfaddr_get_ip6_ptr(dst), src, 16); } else { return SFIP_ARG_ERR; } return SFIP_SUCCESS; } /* Obfuscates an IP * Makes 'ip': ob | (ip & mask) */ void sfip_obfuscate(sfcidr_t *ob, sfaddr_t *ip) { uint32_t *ob_p, *ip_p; int index, i; unsigned int mask = 0; if(!ob || !ip) return; ob_p = sfip_get_ip6_ptr(ob); ip_p = sfaddr_get_ip6_ptr(ip); /* Build the netmask by converting "val" into * the corresponding number of bits that are set */ index = (int)ceil(ob->bits / 32.0) - 1; for(i = 0; i < 32- (ob->bits - (index * 32)); i++) mask = (mask<<1) + 1; /* Note: The old-Snort obfuscation code uses !mask for masking. * hence, this code uses the same algorithm as sfip_cidr_mask * except the mask below is not negated. */ ip_p[index] = htonl((ntohl(ip_p[index]) & mask)); /* 0 off the start of the IP */ while ( index > 0 ) ip_p[--index] = 0; /* OR remaining pieces */ ip_p[0] |= ob_p[0]; ip_p[1] |= ob_p[1]; ip_p[2] |= ob_p[2]; ip_p[3] |= ob_p[3]; } /* Check if ip is contained within the network specified by net */ /* Returns SFIP_EQUAL if so. * XXX sfip_contains assumes that "ip" is * not less-specific than "net" XXX */ SFIP_RET sfip_contains(const sfcidr_t *net, const sfaddr_t *ip) { unsigned int bits, mask, temp, i; const uint32_t *p1, *p2; /* SFIP_CONTAINS is returned here due to how IpAddrSetContains * handles zero'ed IPs" */ ARG_CHECK2(net, ip, SFIP_CONTAINS); bits = sfip_bits(net); p1 = sfip_get_ip6_ptr(net); p2 = sfaddr_get_ip6_ptr(ip); /* Iterate over each 32 bit segment */ for(i=0; i < bits/32; i++, p1++, p2++) { if(*p1 != *p2) return SFIP_NOT_CONTAINS; } mask = 32 - (bits - 32*i); if ( mask == 32 ) return SFIP_CONTAINS; /* At this point, there are some number of remaining bits to check. * Mask the bits we don't care about off of "ip" so we can compare * the ints directly */ temp = ntohl(*p2); temp = (temp >> mask) << mask; /* If p1 was setup correctly through this library, there is no need to * mask off any bits of its own. */ if(ntohl(*p1) == temp) return SFIP_CONTAINS; return SFIP_NOT_CONTAINS; } void sfip_raw_ntop(int family, const void *ip_raw, char *buf, int bufsize) { if(!ip_raw || !buf || (family != AF_INET && family != AF_INET6) || /* Make sure if it's IPv6 that the buf is large enough. */ /* Need atleast a max of 8 fields of 4 bytes plus 7 for colons in * between. Need 1 more byte for null. */ (family == AF_INET6 && bufsize < INET6_ADDRSTRLEN) || /* Make sure if it's IPv4 that the buf is large enough. */ /* 4 fields of 3 numbers, plus 3 dots and a null byte */ (family == AF_INET && bufsize < INET_ADDRSTRLEN) ) { if(buf && bufsize > 0) buf[0] = 0; return; } #if defined(HAVE_INET_NTOP) && !defined(REG_TEST) if (!inet_ntop(family, ip_raw, buf, bufsize)) snprintf(buf, bufsize, "ERROR"); #else /* 4 fields of at most 3 characters each */ if(family == AF_INET) { int i; uint8_t *p = (uint8_t*)ip_raw; for(i=0; p < ((uint8_t*)ip_raw) + 4; p++) { i += sprintf(&buf[i], "%d", *p); /* If this is the last iteration, this could technically cause one * extra byte to be written past the end. */ if(i < bufsize && ((p + 1) < ((uint8_t*)ip_raw+4))) buf[i] = '.'; i++; } /* Check if this is really just an IPv4 address represented as 6, * in compatible format */ #if 0 } else if(!field[0] && !field[1] && !field[2]) { unsigned char *p = (unsigned char *)(&ip->ip[12]); for(i=0; p < &ip->ip[16]; p++) i += sprintf(&buf[i], "%d.", *p); #endif } else { int i; uint16_t *p = (uint16_t*)ip_raw; for(i=0; p < ((uint16_t*)ip_raw) + 8; p++) { i += sprintf(&buf[i], "%04x", ntohs(*p)); /* If this is the last iteration, this could technically cause one * extra byte to be written past the end. */ if(i < bufsize && ((p + 1) < ((uint16_t*)ip_raw) + 8)) buf[i] = ':'; i++; } } #endif } void sfip_ntop(const sfaddr_t *ip, char *buf, int bufsize) { int family; if(!ip) { if(buf && bufsize > 0) buf[0] = 0; return; } family = sfaddr_family(ip); sfip_raw_ntop(family, sfaddr_get_ptr(ip), buf, bufsize); } /* Uses a static buffer to return a string representation of the IP */ char *sfip_to_str(const sfaddr_t *ip) { static char buf[INET6_ADDRSTRLEN]; sfip_ntop(ip, buf, sizeof(buf)); return buf; } void sfip_free(sfcidr_t *ip) { if(ip) free(ip); } void sfaddr_free(sfaddr_t *ip) { if(ip) free(ip); } /* Returns 1 if the IP is non-zero. 0 otherwise */ int sfip_is_loopback(const sfaddr_t *ip) { ARG_CHECK1(ip, 0); /* Check the first 80 bits in an IPv6 address, and */ /* verify they're zero. If not, it's not a loopback */ if(ip->ia32[0] || ip->ia32[1] || ip->ia16[4]) return 0; if(ip->ia16[5] == 0xFFFF) { /* ::ffff:7f00:0/104 is ipv4 compatible ipv6 */ return (ip->ia8[12] == 0x7f); } if(!ip->ia16[5]) { /* ::7f00:0/104 is ipv4 compatible ipv6 */ /* ::1 is the IPv6 loopback */ return (ip->ia32[3] == htonl(0x1) || ip->ia8[12] == 0x7f); } return 0; } snort-2.9.15.1/src/sfutil/sf_ip.h0000644000175200017520000004173613571422607013431 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 1998-2013 Sourcefire, Inc. ** Adam Keeton ** Kevin Liu * ** $ID: $ ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Adam Keeton * sf_ip.h * 11/17/06 */ #ifndef SF_IP_H #define SF_IP_H #ifndef WIN32 #include #include #include #include #endif #ifdef WIN32 #include #endif #include "snort_debug.h" /* for inline definition */ /* define SFIP_ROBUST to check pointers passed into the sfip libs. * Robustification should not be enabled if the client code is trustworthy. * Namely, if pointers are checked once in the client, or are pointers to * data allocated on the stack, there's no need to check them again here. * The intention is to prevent the same stack-allocated variable from being * checked a dozen different times. */ #define SFIP_ROBUST #ifdef SFIP_ROBUST #define ARG_CHECK1(a, z) if(!a) return z; #define ARG_CHECK2(a, b, z) if(!a || !b) return z; #define ARG_CHECK3(a, b, c, z) if(!a || !b || !c) return z; #elif defined(DEBUG) #define ARG_CHECK1(a, z) assert(a); #define ARG_CHECK2(a, b, z) assert(a); assert(b); #define ARG_CHECK3(a, b, c, z) assert(a); assert(b); assert(c); #else #define ARG_CHECK1(a, z) #define ARG_CHECK2(a, b, z) #define ARG_CHECK3(a, b, c, z) #endif #ifndef WIN32 #if !defined(s6_addr8) #define s6_addr8 __u6_addr.__u6_addr8 #endif #if !defined(s6_addr16) #define s6_addr16 __u6_addr.__u6_addr16 #endif #if !defined(s6_addr32) #define s6_addr32 __u6_addr.__u6_addr32 #endif #ifdef _WIN32 #pragma pack(push,1) #endif struct _sfaddr { struct in6_addr ip; uint16_t family; # define ia8 ip.s6_addr # define ia16 ip.s6_addr16 # define ia32 ip.s6_addr32 #ifdef _WIN32 }; #pragma pack(pop) #else } __attribute__((__packed__)); #endif typedef struct _sfaddr sfaddr_t; #ifdef _WIN32 #pragma pack(push,1) #endif struct _ip { sfaddr_t addr; uint16_t bits; # define ip8 addr.ip.s6_addr # define ip16 addr.ip.s6_addr16 # define ip32 addr.ip.s6_addr32 # define ip_family addr.family #ifdef _WIN32 }; #pragma pack(pop) #else } __attribute__((__packed__)); #endif typedef struct _ip sfcidr_t; #else // WIN32 Build #if !defined(s6_addr8) #define s6_addr8 u.u6_addr8 #endif #if !defined(s6_addr16) #define s6_addr16 u.u6_addr16 #endif #if !defined(s6_addr32) #define s6_addr32 u.u6_addr32 #endif struct sf_in6_addr { union { uint8_t u6_addr8[16]; uint16_t u6_addr16[8]; uint32_t u6_addr32[4]; } in6_u; }; #pragma pack(push,1) struct _sfaddr { struct in6_addr ip; uint16_t family; # define ia8 ip.s6_addr # define ia16 ip.s6_addr16 # define ia32 ip.s6_addr32 }; typedef struct _sfaddr sfaddr_t; struct _ip { sfaddr_t addr; uint16_t bits; # define ip8 addr.ip.s6_addr # define ip16 addr.ip.s6_addr16 # define ip32 addr.ip.s6_addr32 # define ip_family addr.family }; typedef struct _ip sfcidr_t; #pragma pack(pop) #endif // WIN32 typedef enum _return_values { SFIP_SUCCESS=0, SFIP_FAILURE, SFIP_LESSER, SFIP_GREATER, SFIP_EQUAL, SFIP_ARG_ERR, SFIP_CIDR_ERR, SFIP_INET_PARSE_ERR, SFIP_INVALID_MASK, SFIP_ALLOC_ERR, SFIP_CONTAINS, SFIP_NOT_CONTAINS, SFIP_DUPLICATE, /* Tried to add a duplicate variable name to table */ SFIP_LOOKUP_FAILURE, /* Failed to lookup a variable from the table */ SFIP_UNMATCHED_BRACKET, /* IP lists that are missing a closing bracket */ SFIP_NOT_ANY, /* For !any */ SFIP_CONFLICT, /* For IP conflicts in IP lists */ SFIP_INVALID_VAR /* variable definition is invalid */ } SFIP_RET; /* IP allocations and setting ******************************************/ /* Parses "src" and stores results in "dst" */ /* If the conversion is invalid, returns SFIP_FAILURE */ SFIP_RET sfaddr_pton(const char *src, sfaddr_t *dst); SFIP_RET sfip_pton(const char *src, sfcidr_t *dst); /* Allocate IP address from a character array describing the IP */ sfcidr_t *sfip_alloc(const char *ip, SFIP_RET *status); /* Frees an sfcidr_t */ void sfip_free(sfcidr_t *ip); /* Allocate IP address from a character array describing the IP */ sfaddr_t *sfaddr_alloc(const char *ip, SFIP_RET *status); /* Frees an sfaddr_t */ void sfaddr_free(sfaddr_t *ip); /* Allocate IP address from an array of integers. The array better be * long enough for the given family! */ sfaddr_t *sfip_alloc_raw(void *ip, int family, SFIP_RET *status); /* Sets existing IP, "dst", to a raw source IP (4 or 16 bytes, * according to family) */ SFIP_RET sfip_set_raw(sfaddr_t *dst, const void *src, int src_family); /* Sets existing IP, "dst", to be source IP, "src" */ #define sfip_set_ip(dst, src) *(dst) = *(src) /* Obfuscates an IP */ void sfip_obfuscate(sfcidr_t *ob, sfaddr_t *ip); /* Member-access *******************************************************/ #define sfip_get_ip4_value(x) ((x)->ip32[3]) #define sfaddr_get_ip4_value(x) ((x)->ia32[3]) #define sfip_get_ip4_ptr(x) (&(x)->ip32[3]) #define sfip_get_ip6_ptr(x) ((x)->ip32) #define sfip_get_ptr(x) (((x)->ip_family == AF_INET) ? &(x)->ip32[3] : (x)->ip32) #define sfaddr_get_ip4_ptr(x) (&(x)->ia32[3]) #define sfaddr_get_ip6_ptr(x) ((x)->ia32) #define sfaddr_get_ptr(x) (((x)->family == AF_INET) ? &(x)->ia32[3] : (x)->ia32) /* Returns the family of "ip", either AF_INET or AF_INET6 */ /* XXX This is a performance critical function, * need to determine if it's safe to not check these pointers */ /* ARG_CHECK1(ip, 0); */ #define sfaddr_family(x) ((x)->family) #define sfip_family(x) ((x)->ip_family) /* Returns the number of bits used for masking "ip" */ static inline unsigned char sfip_bits(const sfcidr_t *ip) { ARG_CHECK1(ip, 0); return (unsigned char)ip->bits; } static inline void sfip_set_bits(sfcidr_t *p, int bits) { if(!p) return; if(bits < 0 || bits > 128) return; p->bits = bits; } /* Returns the raw IP address as an in6_addr */ /*inline struct in6_addr sfip_to_raw(sfcidr_t *); */ /* IP Comparisons ******************************************************/ /* Check if ip is contained within the network specified by net */ /* Returns SFIP_EQUAL if so */ SFIP_RET sfip_contains(const sfcidr_t *net, const sfaddr_t *ip); /* Returns 1 if the IP is non-zero. 0 otherwise */ /* XXX This is a performance critical function, \ * need to determine if it's safe to not check these pointers */\ static inline int sfraw_is_set(const struct in6_addr *addr) { /* ARG_CHECK1(ip, -1); */ return (addr->s6_addr32[3] || addr->s6_addr32[0] || addr->s6_addr32[1] || addr->s6_addr16[4] || (addr->s6_addr16[5] && addr->s6_addr16[5] != 0xFFFF)) ? 1 : 0; } static inline int sfaddr_is_set(const sfaddr_t *addr) { /* ARG_CHECK1(ip, -1); */ return ((addr->family == AF_INET && addr->ia32[3]) || (addr->family == AF_INET6 && (addr->ia32[0] || addr->ia32[1] || addr->ia32[3] || addr->ia16[4] || (addr->ia16[5] && addr->ia16[5] != 0xFFFF)))) ? 1 : 0; } static inline int sfip_is_set(const sfcidr_t *ip) { /* ARG_CHECK1(ip, -1); */ return (sfaddr_is_set(&ip->addr) || ((ip->ip_family == AF_INET || ip->ip_family == AF_INET6) && ip->bits != 128)) ? 1 : 0; } /* Return 1 if the IP is a loopback IP */ int sfip_is_loopback(const sfaddr_t *ip); /* Returns 1 if the IPv6 address appears mapped. 0 otherwise. */ static inline int sfip_ismapped(const sfaddr_t *ip) { ARG_CHECK1(ip, 0); return (ip->ia32[0] || ip->ia32[1] || ip->ia16[4] || (ip->ia16[5] != 0xffff && ip->ia16[5])) ? 0 : 1; } /* Support function for sfip_compare */ static inline SFIP_RET _ip4_cmp(u_int32_t ip1, u_int32_t ip2) { u_int32_t hip1 = htonl(ip1); u_int32_t hip2 = htonl(ip2); if(hip1 < hip2) return SFIP_LESSER; if(hip1 > hip2) return SFIP_GREATER; return SFIP_EQUAL; } /* Support function for sfip_compare */ static inline SFIP_RET _ip6_cmp(const sfaddr_t *ip1, const sfaddr_t *ip2) { SFIP_RET ret; const uint32_t *p1, *p2; /* XXX * Argument are assumed trusted! * This function is presently only called by sfip_compare * on validated pointers. * XXX */ p1 = sfaddr_get_ip6_ptr(ip1); p2 = sfaddr_get_ip6_ptr(ip2); if( (ret = _ip4_cmp(p1[0], p2[0])) != SFIP_EQUAL) return ret; if( (ret = _ip4_cmp(p1[1], p2[1])) != SFIP_EQUAL) return ret; if( (ret = _ip4_cmp(p1[2], p2[2])) != SFIP_EQUAL) return ret; if( (ret = _ip4_cmp(p1[3], p2[3])) != SFIP_EQUAL) return ret; return ret; } /* Compares two IPs * Returns SFIP_LESSER, SFIP_EQUAL, SFIP_GREATER, if ip1 is less than, equal to, * or greater than ip2 In the case of mismatched families, the IPv4 address * is converted to an IPv6 representation. */ /* XXX-IPv6 Should add version of sfip_compare that just tests equality */ static inline SFIP_RET sfip_compare(const sfaddr_t *ip1, const sfaddr_t *ip2) { int f1,f2; ARG_CHECK2(ip1, ip2, SFIP_ARG_ERR); /* This is being done because at some points in the existing Snort code, * an unset IP is considered to match anything. Thus, if either IP is not * set here, it's considered equal. */ if(!sfaddr_is_set(ip1) || !sfaddr_is_set(ip2)) return SFIP_EQUAL; f1 = sfaddr_family(ip1); f2 = sfaddr_family(ip2); if(f1 == AF_INET && f2 == AF_INET) { return _ip4_cmp(sfaddr_get_ip4_value(ip1), sfaddr_get_ip4_value(ip2)); } return _ip6_cmp(ip1, ip2); } /* Compares two CIDRs * Returns SFIP_LESSER, SFIP_EQUAL, SFIP_GREATER, if ip1 is less than, equal to, * or greater than ip2 In the case of mismatched families, the IPv4 address * is converted to an IPv6 representation. */ static inline SFIP_RET sfip_cidr_compare(const sfcidr_t* ip1, const sfcidr_t *ip2) { SFIP_RET ret = sfip_compare(&ip1->addr, &ip2->addr); if(SFIP_EQUAL == ret) { if(ip1->bits < ip2->bits) return SFIP_LESSER; if(ip1->bits > ip2->bits) return SFIP_GREATER; } return ret; } /* Compares two IPs * Returns SFIP_LESSER, SFIP_EQUAL, SFIP_GREATER, if ip1 is less than, equal to, * or greater than ip2 In the case of mismatched families, the IPv4 address * is converted to an IPv6 representation. */ /* XXX-IPv6 Should add version of sfip_compare that just tests equality */ static inline SFIP_RET sfip_compare_unset(const sfaddr_t *ip1, const sfaddr_t *ip2) { int f1,f2; ARG_CHECK2(ip1, ip2, SFIP_ARG_ERR); /* This is to handle the special case when one of the values being * unset is considered to match nothing. This is the opposite of * sfip_compare(), defined above. Thus, if either IP is not * set here, it's considered not equal. */ if(!sfaddr_is_set(ip1) || !sfaddr_is_set(ip2)) return SFIP_FAILURE; f1 = sfaddr_family(ip1); f2 = sfaddr_family(ip2); if(f1 == AF_INET && f2 == AF_INET) { return _ip4_cmp(sfaddr_get_ip4_value(ip1), sfaddr_get_ip4_value(ip2)); } return _ip6_cmp(ip1, ip2); } static inline int sfip_fast_lt4(const sfaddr_t *ip1, const sfaddr_t *ip2) { return sfaddr_get_ip4_value(ip1) < sfaddr_get_ip4_value(ip2); } static inline int sfip_fast_gt4(const sfaddr_t *ip1, const sfaddr_t *ip2) { return sfaddr_get_ip4_value(ip1) > sfaddr_get_ip4_value(ip2); } static inline int sfip_fast_eq4(const sfaddr_t *ip1, const sfaddr_t *ip2) { return sfaddr_get_ip4_value(ip1) == sfaddr_get_ip4_value(ip2); } static inline int sfip_fast_lt6(const sfaddr_t *ip1, const sfaddr_t *ip2) { const uint32_t *p1, *p2; p1 = sfaddr_get_ip6_ptr(ip1); p2 = sfaddr_get_ip6_ptr(ip2); if(*p1 < *p2) return 1; else if(*p1 > *p2) return 0; if(p1[1] < p2[1]) return 1; else if(p1[1] > p2[1]) return 0; if(p1[2] < p2[2]) return 1; else if(p1[2] > p2[2]) return 0; if(p1[3] < p2[3]) return 1; else if(p1[3] > p2[3]) return 0; return 0; } static inline int sfip_fast_gt6(const sfaddr_t *ip1, const sfaddr_t *ip2) { const uint32_t *p1, *p2; p1 = sfaddr_get_ip6_ptr(ip1); p2 = sfaddr_get_ip6_ptr(ip2); if(*p1 > *p2) return 1; else if(*p1 < *p2) return 0; if(p1[1] > p2[1]) return 1; else if(p1[1] < p2[1]) return 0; if(p1[2] > p2[2]) return 1; else if(p1[2] < p2[2]) return 0; if(p1[3] > p2[3]) return 1; else if(p1[3] < p2[3]) return 0; return 0; } static inline int sfip_fast_eq6(const sfaddr_t *ip1, const sfaddr_t *ip2) { const uint32_t *p1, *p2; p1 = sfaddr_get_ip6_ptr(ip1); p2 = sfaddr_get_ip6_ptr(ip2); if(*p1 != *p2) return 0; if(p1[1] != p2[1]) return 0; if(p1[2] != p2[2]) return 0; if(p1[3] != p2[3]) return 0; return 1; } /* Checks if ip2 is equal to ip1 or contained within the CIDR ip1 */ static inline int sfip_fast_cont4(const sfcidr_t *ip1, const sfaddr_t *ip2) { uint32_t shift = 128 - sfip_bits(ip1); uint32_t ip = ntohl(sfaddr_get_ip4_value(ip2)); uint32_t ip3 = ntohl(sfip_get_ip4_value(ip1)); ip >>= shift; ip <<= shift; if(ip3 == 0) return 1; return (ip3 == ip); } /* Checks if ip2 is equal to ip1 or contained within the CIDR ip1 */ static inline int sfip_fast_cont6(const sfcidr_t *ip1, const sfaddr_t *ip2) { uint32_t ip; int i, bits = sfip_bits(ip1); int words = bits / 32; bits = 32 - (bits % 32); for ( i = 0; i < words; i++ ) { if ( ip1->ip32[i] != ip2->ia32[i] ) return 0; } if ( bits == 32 ) return 1; ip = ntohl(ip2->ia32[i]); ip >>= bits; ip <<= bits; return ntohl(ip1->ip32[i]) == ip; } /* Compares two IPs * Returns 1 for equal and 0 for not equal */ static inline int sfip_fast_equals_raw(const sfaddr_t *ip1, const sfaddr_t *ip2) { int f1,f2; ARG_CHECK2(ip1, ip2, 0); f1 = sfaddr_family(ip1); f2 = sfaddr_family(ip2); if(f1 == AF_INET) { if(f2 != AF_INET) return 0; if (sfip_fast_eq4(ip1, ip2)) return 1; } else if(f1 == AF_INET6) { if(f2 != AF_INET6) return 0; if (sfip_fast_eq6(ip1, ip2)) return 1; } return 0; } /******************************************************************** * Function: sfip_is_private() * * Checks if the address is local * * Arguments: * sfcidr_t * - IP address to check * * Returns: * 1 if the IP is in local network * 0 otherwise * ********************************************************************/ static inline int sfip_is_private(const sfaddr_t *ip) { ARG_CHECK1(ip, 0); /* Check the first 80 bits in an IPv6 address, and */ /* verify they're zero. If not, it's not a loopback */ if(ip->ia32[0] || ip->ia32[1] || ip->ia16[4]) return 0; if ( ip->ia16[5] == 0xffff ) { /* ::ffff: IPv4 mapped over IPv6 */ /* * 10.0.0.0 - 10.255.255.255 (10/8 prefix) * 172.16.0.0 - 172.31.255.255 (172.16/12 prefix) * 192.168.0.0 - 192.168.255.255 (192.168/16 prefix) * */ return ( (ip->ia8[12] == 10) ||((ip->ia8[12] == 172) && ((ip->ia8[13] & 0xf0 ) == 16)) ||((ip->ia8[12] == 192) && (ip->ia8[13] == 168)) ); } /* Check if the 3rd 32-bit int is zero */ if ( !ip->ia16[5] ) { /* ::ipv4 compatible ipv6 */ /* ::1 is the IPv6 loopback */ return ( (ip->ia8[12] == 10) ||((ip->ia8[12] == 172) && ((ip->ia8[13] & 0xf0 ) == 16)) ||((ip->ia8[12] == 192) && (ip->ia8[13] == 168)) || (ip->ia32[3] == htonl(0x1)) ); } return 0; } static inline void sfaddr_copy_to_raw(struct in6_addr *dst, const sfaddr_t *src) { dst->s6_addr32[0] = src->ia32[0]; dst->s6_addr32[1] = src->ia32[1]; dst->s6_addr32[2] = src->ia32[2]; dst->s6_addr32[3] = src->ia32[3]; } #define sfip_equals(x,y) (sfip_compare(&x, &y) == SFIP_EQUAL) #define sfip_not_equals !sfip_equals #define sfip_clear(x) memset(x, 0, 16) /* Printing ************************************************************/ /* Uses a static buffer to return a string representation of the IP */ char *sfip_to_str(const sfaddr_t *ip); #define sfip_ntoa(x) sfip_to_str(x) void sfip_raw_ntop(int family, const void *ip_raw, char *buf, int bufsize); void sfip_ntop(const sfaddr_t *ip, char *buf, int bufsize); /* Conversions *********************************************************/ SFIP_RET sfip_convert_ip_text_to_binary( const int, const char *src, void *dst ); #endif /* SF_IP_H */ snort-2.9.15.1/src/sfutil/sf_ipvar.c0000644000175200017520000007310113571422607014124 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 1998-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Adam Keeton * sf_ipvar.c * 11/17/06 * * Library for IP variables. */ #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "util.h" #include "sf_ipvar.h" #include "sf_vartable.h" #define LIST_OPEN '[' #define LIST_CLOSE ']' static SFIP_RET sfvar_list_compare(sfip_node_t *, sfip_node_t *); static inline void sfip_node_free ( sfip_node_t * ); static inline void sfip_node_freelist ( sfip_node_t * ); static inline sfip_var_t *_alloc_var(void) { return (sfip_var_t*)calloc(1, sizeof(sfip_var_t)); } void sfvar_free(sfip_var_t *var) { if(!var) return; if(var->name) free(var->name); if(var->value) free(var->value); if(var->mode == SFIP_LIST) { sfip_node_freelist(var->head); sfip_node_freelist(var->neg_head); } else if(var->mode == SFIP_TABLE) { // XXX } free(var); } sfip_node_t *sfipnode_alloc(char *str, SFIP_RET *status) { sfip_node_t *ret; if(!str) { if(status) *status = SFIP_ARG_ERR; return NULL; } if( (ret = (sfip_node_t*)calloc(1, sizeof(sfip_node_t))) == NULL ) { if(status) *status = SFIP_ALLOC_ERR; return NULL; } /* Check if this string starts with a '!', if so, * then the node needs to be negated */ if(*str == '!') { str++; ret->flags |= SFIP_NEGATED; } /* Check if this is an "any" */ if(!strncasecmp(str, "any", 3)) { /* Make sure they're not doing !any, which is meaningless */ if(ret->flags & SFIP_NEGATED) { if(status) *status = SFIP_ARG_ERR; free(ret); return NULL; } ret->flags |= SFIP_ANY; if( (ret->ip = sfip_alloc("0.0.0.0", status)) == NULL ) { /* Failed to parse this string, so free and return */ if(status) *status = SFIP_ALLOC_ERR; free(ret); return NULL; } if(status) *status = SFIP_SUCCESS; #if 0 if( (ret->ip = sfip_alloc("0.0.0.0", NULL)) == NULL) { if(status) *status = SFIP_FAILURE; free(ret); return NULL; } #endif } else if( (ret->ip = sfip_alloc(str, status)) == NULL ) { /* Failed to parse this string, so free and return */ if(status) *status = SFIP_INET_PARSE_ERR; free(ret); return NULL; } /* Check if this is a negated, zero'ed IP (equivalent of a "!any") */ if(!sfip_is_set(ret->ip) && (ret->flags & SFIP_NEGATED)) { if(status) *status = SFIP_NOT_ANY; free(ret->ip); free(ret); return NULL; } return ret; } static inline void sfip_node_free ( sfip_node_t *node ) { if ( !node ) return; if ( node->ip ) sfip_free(node->ip); free(node); } static inline void sfip_node_freelist ( sfip_node_t *root ) { sfip_node_t *node; if ( !root ) return; for ( node = root; node; node = root ) { root = root->next; sfip_node_free(node); } } sfip_node_t* MergeLists(sfip_node_t *list1, sfip_node_t* list2, uint16_t list1_len, uint16_t list2_len, uint16_t *merge_len) { SFIP_RET ret = SFIP_SUCCESS; sfip_node_t* listHead = NULL, *merge_list = NULL, *tmp = NULL, *node = NULL; uint16_t num_nodes = 0; if(!list1 && !list2) { *merge_len = 0; return NULL; } if (list1 == NULL) { *merge_len = list2_len; return list2; } if (list2 == NULL) { *merge_len = list1_len; return list1; } /*Both lists are sorted and not NULL. If list1 or list2 contains "any", free the other list*/ if(list1->flags & SFIP_ANY) { *merge_len = list1_len; while(list2) { tmp = list2->next; sfip_node_free(list2); list2 = tmp; } return list1; } if(list2->flags & SFIP_ANY) { *merge_len = list2_len; while(list1) { tmp = list1->next; sfip_node_free(list1); list1 = tmp; } return list2; } /*Iterate till one of the list is NULL. Append each node to merge_list*/ while (list1 && list2) { ret = sfip_cidr_compare(list1->ip, list2->ip); if(ret == SFIP_LESSER) { node = list1; list1 = list1->next; list1_len--; } else if(ret == SFIP_GREATER) { node = list2; list2 = list2->next; list2_len--; } else if(ret == SFIP_EQUAL) { node = list1; list1 = list1->next; /*Free the duplicate node*/ tmp = list2->next; sfip_node_free(list2); list2 = tmp; list1_len--; list2_len--; } if(!merge_list) { merge_list = node; listHead = node; } else { merge_list->next = node; merge_list = merge_list->next; } num_nodes++; } /*list2 is NULL. Append list1*/ if(list1 != NULL) { merge_list->next = list1; num_nodes += list1_len; } /*list1 is NULL. Append list2*/ if(list2 != NULL) { merge_list->next = list2; num_nodes += list2_len; } *merge_len = num_nodes; return listHead; } /* Deep copy of src added to dst */ /*src is sorted. Iterate over every node in dst and do sfvar_add_node*/ SFIP_RET sfvar_add(sfip_var_t *dst, sfip_var_t *src) { sfip_var_t *copiedvar; if(!dst || !src) return SFIP_ARG_ERR; if((copiedvar = sfvar_deep_copy(src)) == NULL) { return SFIP_ALLOC_ERR; } dst->head = MergeLists(dst->head, copiedvar->head, dst->head_count, copiedvar->head_count, &dst->head_count); dst->neg_head = MergeLists(dst->neg_head, copiedvar->neg_head, dst->neg_head_count, copiedvar->neg_head_count, &dst->neg_head_count); free(copiedvar); return SFIP_SUCCESS; } SFIP_RET sfvar_add_node(sfip_var_t *var, sfip_node_t *node, int negated) { sfip_node_t *p, *swp, *tmp; sfip_node_t **head; uint16_t *count; if(!var || !node) return SFIP_ARG_ERR; /* XXX */ /* As of this writing, 11/20/06, nodes are always added to * the list, regardless of the mode (list or table). */ if(negated) { head = &var->neg_head; count = &var->neg_head_count; } else { head = &var->head; count = &var->head_count; } if(!(*head)) { *head = node; ++*count; return SFIP_SUCCESS; } /*If head node is any, do not add anything else*/ if((*head)->flags & SFIP_ANY) { sfip_node_free(node); return SFIP_SUCCESS; } /* "Anys" should always be inserted first */ /* Otherwise, check if this IP is less than the head's IP */ SFIP_RET node_cmp_ret = SFIP_SUCCESS; if(node->flags & SFIP_ANY) { if((*head)->flags & SFIP_ANY) { sfip_node_free(node); return SFIP_SUCCESS; } else { /*Free the list when adding any*/ while(*head) { tmp = (*head)->next; sfip_node_free(*head); *head = tmp; } *head = node; *count = 1; return SFIP_SUCCESS; } } else { node_cmp_ret = sfip_cidr_compare(node->ip, (*head)->ip); if(node_cmp_ret == SFIP_EQUAL) { sfip_node_free(node); return SFIP_SUCCESS; } else if(node_cmp_ret == SFIP_LESSER) { node->next = *head; *head = node; ++*count; return SFIP_SUCCESS; } } /* If we're here, the head node was lesser than the new node */ /* Before searching the list, verify there is atleast two nodes. * (This saves an extra check during the loop below) */ if(!(*head)->next) { (*head)->next = node; ++*count; return SFIP_SUCCESS; } /* Insertion sort */ for(p = *head; p->next; p=p->next) { node_cmp_ret = sfip_cidr_compare(node->ip, p->next->ip); if(node_cmp_ret == SFIP_EQUAL) { sfip_node_free(node); return SFIP_SUCCESS; } else if(node_cmp_ret == SFIP_LESSER) { swp = p->next; p->next = node; node->next = swp; ++*count; return SFIP_SUCCESS; } } p->next = node; ++*count; return SFIP_SUCCESS; /* XXX Insert new node into routing table */ // sfrt_add(node->ip, } static SFIP_RET sfvar_list_compare(sfip_node_t *list1, sfip_node_t *list2) { sfip_node_t *tmp, *tmp2; if ((list1 == NULL) && (list2 == NULL)) return SFIP_EQUAL; /* Lists are ordered and of equal size */ for (tmp = list1, tmp2 = list2; (tmp != NULL) && (tmp2 != NULL); tmp = tmp->next, tmp2 = tmp2->next) { if ((sfip_cidr_compare(tmp->ip, tmp2->ip) != SFIP_EQUAL)) { return SFIP_FAILURE; } } return SFIP_EQUAL; } /* Check's if two variables have the same nodes */ SFIP_RET sfvar_compare(const sfip_var_t *one, const sfip_var_t *two) { /* If both NULL, consider equal */ if(!one && !two) return SFIP_EQUAL; /* If one NULL and not the other, consider unequal */ if((one && !two) || (!one && two)) return SFIP_FAILURE; if (sfvar_is_alias(one, two)) return SFIP_EQUAL; if(one->head_count != two->head_count) return SFIP_FAILURE; if (sfvar_list_compare(one->head, two->head) == SFIP_FAILURE) return SFIP_FAILURE; if(one->neg_head_count != two->neg_head_count) return SFIP_FAILURE; if (sfvar_list_compare(one->neg_head, two->neg_head) == SFIP_FAILURE) return SFIP_FAILURE; return SFIP_EQUAL; } /* Support function for sfvar_parse_iplist. Used to * correctly match up end brackets. * (Can't just do strchr(str, ']') because of the * [a, [b], c] case, and can't do strrchr because * of the [a, [b], [c]] case) */ static char *_find_end_token(char *str) { int stack = 0; for(; *str; str++) { if(*str == LIST_OPEN) stack++; else if(*str == LIST_CLOSE) stack--; if(!stack) { return str; } } return NULL; } /* Support function for sfvar_parse_iplist. * Negates a node */ static void _negate_node(sfip_node_t *node) { if(node->addr_flags & SFIP_NEGATED) { node->addr_flags &= ~SFIP_NEGATED; node->flags &= ~SFIP_NEGATED; } else { node->addr_flags |= SFIP_NEGATED; node->flags |= SFIP_NEGATED; } } /* Support function for sfvar_parse_iplist. * Negates a variable */ static void _negate_lists(sfip_var_t *var) { sfip_node_t *node; sfip_node_t *temp; uint16_t temp_count; for(node = var->head; node; node=node->next) _negate_node(node); for(node = var->neg_head; node; node=node->next) _negate_node(node); /* Swap lists */ temp = var->head; var->head = var->neg_head; var->neg_head = temp; /*Swap the counts*/ temp_count = var->neg_head_count; var->neg_head_count = var->head_count; var->head_count = temp_count; } SFIP_RET sfvar_parse_iplist(vartable_t *table, sfip_var_t *var, char *str, int negation) { char *end, *tok; SFIP_RET ret; int neg_ip; if(!var || !table || !str) return SFIP_ARG_ERR; while(*str) { /* Skip whitespace and leading commas */ if(isspace((int)*str) || *str == ',') { str++; continue; } neg_ip = 0; /* Handle multiple negations */ for(; *str == '!'; str++) neg_ip = !neg_ip; /* Find end of this token */ for(end = str+1; *end && !isspace((int)*end) && *end != LIST_CLOSE && *end != ','; end++) ; tok = SnortStrndup(str, end - str); if(*str == LIST_OPEN) { char *list_tok; /* Find end of this list */ if((end = _find_end_token(str)) == NULL) { /* No trailing bracket found */ free(tok); return SFIP_UNMATCHED_BRACKET; } str++; list_tok = SnortStrndup(str, end - str); if((ret = sfvar_parse_iplist(table, var, list_tok, negation ^ neg_ip)) != SFIP_SUCCESS) { free(list_tok); free(tok); return ret; } free(list_tok); } else if(*str == '$') { sfip_var_t *tmp_var; sfip_var_t *copy_var; if((tmp_var = sfvt_lookup_var(table, tok)) == NULL) { free(tok); return SFIP_LOOKUP_FAILURE; } copy_var = sfvar_deep_copy(tmp_var); /* Apply the negation */ if(negation ^ neg_ip) { /* Check for a negated "any" */ if(copy_var->head && copy_var->head->flags & SFIP_ANY) { free(tok); sfvar_free(copy_var); return SFIP_NOT_ANY; } /* Check if this is a negated, zero'ed IP (equivalent of a "!any") */ if(copy_var->head && !sfip_is_set(copy_var->head->ip)) { free(tok); sfvar_free(copy_var); return SFIP_NOT_ANY; } _negate_lists(copy_var); } sfvar_add(var, copy_var); sfvar_free(copy_var); } else if(*str == LIST_CLOSE) { /* This should be the last character, if not, then this is an * invalid extra closing bracket */ if(!(*(str+1))) { free(tok); return SFIP_SUCCESS; } free(tok); return SFIP_UNMATCHED_BRACKET; } else { sfip_node_t *node; /* Skip leading commas */ for(; *str == ','; str++) ; /* Check for a negated "any" */ if(negation ^ neg_ip && !strcasecmp(tok, "any")) { free(tok); return SFIP_NOT_ANY; } /* This should be an IP address! */ /* Allocate new node for this string and add it to "ret" */ if((node = sfipnode_alloc(tok, &ret)) == NULL) { free(tok); return ret; } if(negation ^ neg_ip) { _negate_node(node); } /* Check if this is a negated, zero'ed IP (equivalent of a "!any") */ if(!sfip_is_set(node->ip) && (node->flags & SFIP_NEGATED)) { sfip_node_free(node); free(tok); return SFIP_NOT_ANY; } ret = sfvar_add_node(var, node, negation ^ neg_ip); if(ret != SFIP_SUCCESS ) { free(tok); return ret; } } free(tok); if(*end) str = end + 1; else break; } return SFIP_SUCCESS; } SFIP_RET sfvar_validate(sfip_var_t *var) { sfip_node_t *idx, *neg_idx; if(!var->head || !var->neg_head) return SFIP_SUCCESS; for(idx = var->head; idx; idx = idx->next) { for(neg_idx = var->neg_head; neg_idx; neg_idx = neg_idx->next) { /* A smaller netmask means "less specific" */ if((sfip_bits(neg_idx->ip) <= sfip_bits(idx->ip)) && /* Verify they overlap */ (sfip_contains(neg_idx->ip, &idx->ip->addr) == SFIP_CONTAINS)) { return SFIP_CONFLICT; } } } return SFIP_SUCCESS; } sfip_var_t * sfvar_create_alias(const sfip_var_t *alias_from, const char *alias_to) { sfip_var_t *ret; if ((alias_from == NULL) || (alias_to == NULL)) return NULL; ret = sfvar_deep_copy(alias_from); if (ret == NULL) return NULL; ret->name = SnortStrdup(alias_to); ret->id = alias_from->id; return ret; } int sfvar_is_alias(const sfip_var_t *one, const sfip_var_t *two) { if ((one == NULL) || (two == NULL)) return 0; if ((one->id != 0) && (one->id == two->id)) return 1; return 0; } /* Allocates and returns a new variable, described by "variable". */ sfip_var_t *sfvar_alloc(vartable_t *table, char *variable, SFIP_RET *status) { sfip_var_t *ret, *tmpvar; char *str, *end, *tmp; SFIP_RET stat; bool invalidvar = true; if(!variable || !(*variable)) { if(status) *status = SFIP_ARG_ERR; return NULL; } if( (ret = _alloc_var()) == NULL ) { if(status) *status = SFIP_ALLOC_ERR; return NULL; } /* Extract and save the variable's name */ /* Start by skipping leading whitespace or line continuations: '\' */ for(str = variable ; *str && (isspace((int)*str) || *str == '\\'); str++) ; if (*str == 0) /* Didn't get anything */ { if (status) *status = SFIP_ARG_ERR; sfvar_free(ret); return NULL; } /* Find the end of the name */ for(end = str; *end && !isspace((int)*end) && *end != '\\'; end++) { if(isalpha((int)*end)) invalidvar = false; } if(invalidvar) { if(status) *status = SFIP_INVALID_VAR; sfvar_free(ret); return NULL; } if(!isalnum((int)*str) && *str != '$' && *str != '!' && *str != '_') { if(status) *status = SFIP_ARG_ERR; sfvar_free(ret); return NULL; } /* Set the new variable's name/key */ if((ret->name = SnortStrndup(str, end - str)) == NULL) { if(status) *status = SFIP_ALLOC_ERR; sfvar_free(ret); return NULL; } /* End points to the end of the name. Skip past it and any whitespace * or potential line continuations */ str = end; for (; (*str != 0) && (isspace((int)*str) || (*str == '\\')); str++); if (*str == 0) /* Didn't get anything */ { if (status) *status = SFIP_ARG_ERR; sfvar_free(ret); return NULL; } /* Trim off whitespace and line continuations from the end of the string */ end = (str + strlen(str)) - 1; for (; (end > str) && (isspace((int)*end) || (*end == '\\')); end--); end++; /* See if this is just an alias */ tmp = SnortStrndup(str, end - str); tmpvar = sfvt_lookup_var(table, tmp); free(tmp); if (tmpvar != NULL) { sfip_var_t *aliased = sfvar_create_alias(tmpvar, ret->name); if (aliased != NULL) { if (status != NULL) *status = SFIP_SUCCESS; sfvar_free(ret); return aliased; } } /* Everything is treated as a list, even if it's one element that's not * surrounded by brackets */ stat = sfvar_parse_iplist(table, ret, str, 0); if (status != NULL) *status = stat; if (stat != SFIP_SUCCESS) { sfvar_free(ret); return NULL; } if(ret->head && (ret->head->flags & SFIP_ANY && ret->head->flags & SFIP_NEGATED)) { if(status) *status = SFIP_NOT_ANY; sfvar_free(ret); return NULL; } if(sfvar_validate(ret) == SFIP_CONFLICT) { if(status) *status = SFIP_CONFLICT; sfvar_free(ret); return NULL; } return ret; } static inline sfip_node_t *_sfvar_deep_copy_list(const sfip_node_t *idx) { sfip_node_t *ret, *temp, *prev; ret = temp = NULL; for( ; idx; idx = idx->next) { prev = temp; if( (temp = (sfip_node_t*)calloc(1, sizeof(sfip_node_t))) == NULL ) { sfip_node_freelist(ret); return NULL; } if( (temp->ip = (sfcidr_t*)calloc(1, sizeof(sfcidr_t))) == NULL ) { sfip_node_freelist(ret); free(temp); return NULL; } temp->flags = idx->flags; temp->addr_flags = idx->addr_flags; /* If it's an "any", there may be no IP object */ if(idx->ip) memcpy(temp->ip, idx->ip, sizeof(sfcidr_t)); if(prev) prev->next = temp; else ret = temp; } return ret; } sfip_var_t *sfvar_deep_copy(const sfip_var_t *var) { sfip_var_t *ret; if(!var) return NULL; ret = (sfip_var_t*)SnortAlloc(sizeof(sfip_var_t)); ret->mode = var->mode; ret->head = _sfvar_deep_copy_list(var->head); ret->neg_head = _sfvar_deep_copy_list(var->neg_head); ret->head_count = var->head_count; ret->neg_head_count = var->neg_head_count; return ret; } /* Support function for sfvar_ip_in */ static inline int _sfvar_ip_in4(sfip_var_t *var, sfaddr_t *ip) { int match; sfip_node_t *pos_idx, *neg_idx; match = 0; pos_idx = var->head; neg_idx = var->neg_head; if(!pos_idx) { for( ; neg_idx; neg_idx = neg_idx->next) { if(sfaddr_family(&neg_idx->ip->addr) != AF_INET) continue; if(sfip_fast_cont4(neg_idx->ip, ip)) { return 0; } } return 1; } while(pos_idx) { if(neg_idx) { if(sfaddr_family(&neg_idx->ip->addr) == AF_INET && sfip_fast_cont4(neg_idx->ip, ip)) { return 0; } neg_idx = neg_idx->next; } /* No more potential negations. Check if we've already matched. */ else if(match) { return 1; } if(!match) { if(sfip_is_set(pos_idx->ip)) { if(sfaddr_family(&pos_idx->ip->addr) == AF_INET && sfip_fast_cont4(pos_idx->ip, ip)) { match = 1; } else { pos_idx = pos_idx->next; } } else { match = 1; } } } return 0; } /* Support function for sfvar_ip_in */ static inline int _sfvar_ip_in6(sfip_var_t *var, sfaddr_t *ip) { int match; sfip_node_t *pos_idx, *neg_idx; match = 0; pos_idx = var->head; neg_idx = var->neg_head; if(!pos_idx) { for( ; neg_idx; neg_idx = neg_idx->next) { if(sfaddr_family(&neg_idx->ip->addr) != AF_INET6) continue; if(sfip_fast_cont6(neg_idx->ip, ip)) { return 0; } } return 1; } while(pos_idx) { if(neg_idx) { if(sfaddr_family(&neg_idx->ip->addr) == AF_INET6 && sfip_fast_cont6(neg_idx->ip, ip)) { return 0; } neg_idx = neg_idx->next; } /* No more potential negations. Check if we've already matched. */ else if(match) { return 1; } if(!match) { if(sfip_is_set(pos_idx->ip)) { if(sfaddr_family(&pos_idx->ip->addr) == AF_INET6 && sfip_fast_cont6(pos_idx->ip, ip)) { match = 1; } else { pos_idx = pos_idx->next; } } else { match = 1; } } } return 0; } /* Returns SFIP_SUCCESS if ip is contained in 'var', SFIP_FAILURE otherwise */ /* If either argument is NULL, SFIP_ARG_ERR is returned. */ int sfvar_ip_in(sfip_var_t *var, sfaddr_t *ip) { if(!var || !ip) return 0; #if 0 if(var->mode == SFIP_TABLE) { // XXX } else { #endif /* Since this is a performance-critical function it uses different * codepaths for IPv6 and IPv4 traffic, rather than the dual-stack * functions. */ if(sfaddr_family(ip) == AF_INET) { return _sfvar_ip_in4(var, ip); } else { return _sfvar_ip_in6(var, ip); } #if 0 } #endif } static char buffer[1024]; void sfip_set_print(const char *prefix, sfip_node_t *p) { int ret; for(; p; p = p->next) { buffer[0] = '\0'; if(!p->ip) continue; if(p->flags & SFIP_NEGATED) { if (p->ip->bits != 128) { if (sfaddr_family(&p->ip->addr) == AF_INET6) { ret = SnortSnprintfAppend(buffer, sizeof(buffer), "!%s/%d", sfip_to_str(&p->ip->addr), p->ip->bits); } else { ret = SnortSnprintfAppend(buffer, sizeof(buffer), "!%s/%d", sfip_to_str(&p->ip->addr), p->ip->bits < 96 ? -1 : p->ip->bits - 96); } } else { ret = SnortSnprintfAppend(buffer, sizeof(buffer), "!%s", sfip_to_str(&p->ip->addr)); } if (ret != SNORT_SNPRINTF_SUCCESS) return; } else { if (p->ip->bits != 128) { if (sfaddr_family(&p->ip->addr) == AF_INET6) { ret = SnortSnprintfAppend(buffer, sizeof(buffer), "%s/%d", sfip_to_str(&p->ip->addr), p->ip->bits); } else { ret = SnortSnprintfAppend(buffer, sizeof(buffer), "%s/%d", sfip_to_str(&p->ip->addr), p->ip->bits < 96 ? -1 : p->ip->bits - 96); } } else { ret = SnortSnprintfAppend(buffer, sizeof(buffer), "%s", sfip_to_str(&p->ip->addr)); } if (ret != SNORT_SNPRINTF_SUCCESS) return; } if (prefix) LogMessage("%s%s\n", prefix, buffer); else LogMessage("%s\n", buffer); } } void sfvar_print(const char *prefix, sfip_var_t *var) { if (!var || !var->head) { return; } if(var->mode == SFIP_LIST) { if(var->head->flags & SFIP_ANY) { if (prefix) LogMessage("%sany\n", prefix); else LogMessage("any\n"); } else { sfip_set_print(prefix, var->head); } } else if(var->mode == SFIP_TABLE) { // XXX } } void sfip_set_print_to_file(FILE *f, sfip_node_t *p) { for(; p; p = p->next) { if(!p->ip) continue; if(p->flags & SFIP_NEGATED) fprintf(f, "\t!%s\n", sfip_to_str(&p->ip->addr)); else fprintf(f, "\t %s\n", sfip_to_str(&p->ip->addr)); } } /* Prints the variable "var" to the file descriptor 'f' */ void sfvar_print_to_file(FILE *f, sfip_var_t *var) { if(!f) return; if(!var || !var->head) { fprintf(f, "[no variable]\n"); return; } fprintf(f, "Name: %s\n", var->name); if(var->mode == SFIP_LIST) { if(var->head->flags & SFIP_ANY) fprintf(f, "\t%p: \n", (void*)var->head); else { sfip_set_print_to_file(f, var->head); } } else if(var->mode == SFIP_TABLE) { // XXX } } int sfvar_flags(sfip_node_t *node) { if(node) return node->flags; return -1; } /* XXX The unit tests for this code are performed within sf_vartable.c */ #if 0 int main() { sfip_vtable *table; sfip_var_t *var; sfcidr_t *ip; /* Test parsing */ /* Allowable arguments: * { [, , ... , } * Where an IP can be in CIDR notation, or be specified with a netmask. * IPs may also be negated with '!' */ puts("********************************************************************"); puts("Testing parsing:"); var = sfvar_str(" { 1.2.3.4/8, 5.5.5.5 255.255.255.0, any} "); sfip_print_var(stdout, var); sfvar_free(var); puts(""); var = sfvar_str(" { 1.2.3.4, ffff::3/127, 0.0.0.1} "); sfip_print_var(stdout, var); ip = sfip_alloc("1.2.3.5"); printf("(need more of these) 'in': %d\n", sfip_in(var, ip)); puts("also, use 'sfip_in' for the unit tests"); puts(""); return 0; } #endif snort-2.9.15.1/src/sfutil/sf_ipvar.h0000644000175200017520000001100413571422607014123 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 1998-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Adam Keeton * sf_ipvar.h * 11/17/06 */ #ifndef SF_IPVAR_H #define SF_IPVAR_H /* Flags */ #define SFIP_NEGATED 1 #define SFIP_ANY 2 #include #include "sf_ip.h" /* Selects which mode a given variable is using to * store and lookup IP addresses */ typedef enum _modes { SFIP_LIST, SFIP_TABLE } MODES; /* Used by the "list" mode. A doubly linked list of sfcidr_t objects. */ typedef struct _ip_node { sfcidr_t *ip; struct _ip_node *next; int flags; // XXX int addr_flags; /* Flags used exlusively by Snort */ /* Keeping these variables seperate keeps * this from stepping on Snort's toes. */ /* Should merge them later */ } sfip_node_t; /* An IP variable onkect */ typedef struct _var_t { /* Selects whether or not to use the list, the table, * or any other method added later */ MODES mode; /* Linked lists. Switch to something faster later */ sfip_node_t *head; sfip_node_t *neg_head; /* The mode above will select whether to use the sfip_node_t linked list * or the IP routing table */ // sfrt rt; /* Linked list of IP variables for the variable table */ struct _var_t *next; uint16_t head_count; uint16_t neg_head_count; uint32_t id; char *name; char *value; } sfip_var_t; /* A variable table for storing and looking up variables */ /* Expand later to use a faster data structure */ typedef struct _vartable_t { sfip_var_t *head; uint32_t id; } vartable_t; /* Creates a new variable that is an alias of another variable * Does a "deep" copy so it owns it's own pointers */ sfip_var_t * sfvar_create_alias(const sfip_var_t *alias_from, const char *alias_to); /* Returns 1 if the two variables are aliases of each other, 0 otherwise */ int sfvar_is_alias(const sfip_var_t *one, const sfip_var_t *two); /* Allocates a new variable as according to "str" */ sfip_var_t *sfvar_alloc(vartable_t *table, char *str, SFIP_RET *status); /* Makes sure there are no IP address conflicts in the variable */ /* Returns SFIP_CONFLICT if so */ SFIP_RET sfvar_validate(sfip_var_t *var); /* Parses an IP list described by 'str' and saves the results in 'var'. */ SFIP_RET sfvar_parse_iplist(vartable_t *table, sfip_var_t *var, char *str, int negation); /* Allocaties and returns an IP node described by 'str' */ sfip_node_t *sfipnode_alloc(char *str, SFIP_RET *status); /* Adds a deep copy of src to dst */ /* Ordering is not necessarily preserved */ SFIP_RET sfvar_add(sfip_var_t *dst, sfip_var_t *src); /* Adds the nodes in 'src' to the variable 'dst' */ /* The mismatch of types is for ease-of-supporting Snort4 and * Snort6 simultaneously */ SFIP_RET sfvar_add_node(sfip_var_t *dst, sfip_node_t *src, int negated); /* Compares two variables. Necessary when building RTN structure */ SFIP_RET sfvar_compare(const sfip_var_t *one, const sfip_var_t *two); /* Deep copy. Returns identical, new, linked list of sfipnodes. */ sfip_var_t *sfvar_deep_copy(const sfip_var_t *src); /* Free an allocated variable */ void sfvar_free(sfip_var_t *var); /* Returns non-zero if ip is contained in 'var', 0 otherwise */ /* If either argument is NULL, 0 is returned. */ int sfvar_ip_in(sfip_var_t *var, sfaddr_t *ip); /* Prints the variable "var" to the file descriptor 'f' */ void sfvar_print(const char *prefix, sfip_var_t *var); void sfip_set_print(const char *prefix, sfip_node_t *head); void sfvar_print_to_file(FILE *f, sfip_var_t *var); void sfip_set_print_to_file(FILE *f, sfip_node_t *head); /* Returns the node's flags */ int sfvar_flags(sfip_node_t *node); #endif snort-2.9.15.1/src/sfutil/sf_vartable.c0000644000175200017520000002701513571422607014606 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 1998-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Adam Keeton * sf_vartable.c * 11/17/06 * * Library for managing IP variables. */ #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sf_types.h" #include "sf_vartable.h" #include "util.h" vartable_t * sfvt_alloc_table(void) { vartable_t *table = (vartable_t *)SnortAlloc(sizeof(vartable_t)); /* ID for recognition of variables with different name, but same content * Start at 1, so a value of zero indicates not set. * This value should be incremented for each variable that hasn't been * identified as an alias of another variable */ table->id = 1; return table; } static char * sfvt_expand_value(vartable_t *table, char *value) { char *ptr, *end, *tmp, *ret = NULL; int retlen = 0, retsize = 0; int escaped = 0; if ((table == NULL) || (value == NULL)) return NULL; if (strlen(value) == 0) return NULL; ptr = value; end = value + strlen(value); while ((ptr < end) && isspace((int)*ptr)) ptr++; while ((end > ptr) && isspace((int)*(end-1))) end--; if (ptr == end) return NULL; tmp = SnortStrndup(ptr, end-ptr); if (tmp == NULL) return NULL; /* Start by allocating the length of the value */ retsize = strlen(value) + 1; ret = (char *)SnortAlloc(retsize); ptr = tmp; end = tmp + strlen(tmp); while (ptr < end) { if (!escaped && (*ptr == '$')) { char *varstart, *vartmp; int parens = 0; sfip_var_t *ipvar; ptr++; if (ptr >= end) goto sfvt_expand_value_error; if (*ptr == '(') { ptr++; parens = 1; } varstart = ptr; while (ptr < end) { if (parens) { if (*ptr == ')') { break; } } else if (!isalnum((int)*ptr) && (*ptr != '_')) { break; } ptr++; } if (varstart == ptr) goto sfvt_expand_value_error; vartmp = SnortStrndup(varstart, ptr - varstart); if (vartmp == NULL) goto sfvt_expand_value_error; ipvar = sfvt_lookup_var(table, vartmp); free(vartmp); if (ipvar == NULL) goto sfvt_expand_value_error; if (ipvar->value != NULL) { if ((int)(retlen + strlen(ipvar->value)) >= retsize) { char *tmpalloc; retsize = retlen + strlen(ipvar->value) + (end - ptr) + 1; tmpalloc = (char *)SnortAlloc(retsize); memcpy(tmpalloc, ret, retlen); memcpy(tmpalloc + retlen, ipvar->value, strlen(ipvar->value)); free(ret); retlen += strlen(ipvar->value); ret = tmpalloc; } } if (parens) ptr++; continue; } if (*ptr == '\\') escaped = 1; else escaped = 0; ret[retlen++] = *ptr; ptr++; } free(tmp); if ((retlen + 1) < retsize) { char *tmpalloc = (char *)SnortAlloc(retlen + 1); memcpy(tmpalloc, ret, retlen); free(ret); ret = tmpalloc; } ret[retlen] = 0; return ret; sfvt_expand_value_error: free(ret); free(tmp); return NULL; } // XXX this implementation is just used to support // Snort's underlying implementation better SFIP_RET sfvt_define(vartable_t *table, char *name, char *value) { char *buf; int len; sfip_var_t *ipret = NULL; SFIP_RET ret; if(!name || !value) return SFIP_ARG_ERR; len = strlen(name) + strlen(value) + 2; if((buf = (char*)malloc(len)) == NULL) { return SFIP_FAILURE; } SnortSnprintf(buf, len, "%s %s", name, value); ret = sfvt_add_str(table, buf, &ipret); if ((ret == SFIP_SUCCESS) || (ret == SFIP_DUPLICATE)) ipret->value = sfvt_expand_value(table, value); free(buf); return ret; } /* Adds the variable described by "str" to the table "table" */ SFIP_RET sfvt_add_str(vartable_t *table, char *str, sfip_var_t **ipret) { sfip_var_t *var; sfip_var_t *swp; sfip_var_t *p; int ret; SFIP_RET status; if(!table || !str || !ipret) return SFIP_FAILURE; /* Creates the variable */ if( (var = sfvar_alloc(table, str, &status)) == NULL ) { return status; } /* If this is an alias of another var, id will be set */ if (var->id == 0) var->id = table->id++; *ipret = var; /* Insertion sort */ if(!table->head) { table->head = var; return SFIP_SUCCESS; } if((ret = strcmp(var->name, table->head->name)) < 0) { var->next = table->head; table->head = var; return SFIP_SUCCESS; } /* Redefinition */ else if(ret == 0) { var->next = table->head->next; sfvar_free(table->head); table->head = var; return SFIP_DUPLICATE; } /* The loop below checks table->head->next->name in the first iteration. * Make sure there is a table->head->next first */ if(!table->head->next) { table->head->next = var; return SFIP_SUCCESS; } else if(!strcmp(var->name, table->head->next->name)) { var->next = table->head->next->next; sfvar_free(table->head->next); table->head->next = var; return SFIP_DUPLICATE; } for(p = table->head; p->next; p=p->next) { if((ret = strcmp(var->name, p->next->name)) < 0) { swp = p->next; p->next = var; var->next = swp; return SFIP_SUCCESS; } /* Redefinition */ else if(ret == 0) { var->next = p->next->next; sfvar_free(p->next); p->next = var; return SFIP_DUPLICATE; } } p->next = var; return SFIP_SUCCESS; } /* Adds the variable described by "src" to the variable "dst", * using the vartable for looking variables used within "src" */ SFIP_RET sfvt_add_to_var(vartable_t *table, sfip_var_t *dst, char *src) { SFIP_RET ret; if(!table || !dst || !src) return SFIP_ARG_ERR; if((ret = sfvar_parse_iplist(table, dst, src, 0)) == SFIP_SUCCESS) return sfvar_validate(dst); return ret; } /* Looks up a variable from the table by the variable's name */ sfip_var_t *sfvt_lookup_var(vartable_t *table, char *name) { sfip_var_t *p; int len; char *end; if(!table || !name) return NULL; if(*name == '$') name++; /* XXX should I assume there will be trailing garbage or * should I automatically find where the variable ends? */ for(end=name; *end && !isspace((int)*end) && *end != '\\' && *end != ']'; end++) ; len = end - name; for(p=table->head; len && p; p=p->next) { int name_len = strlen(p->name); if((len == name_len) && !strncmp(p->name, name, len)) return p; } return NULL; } void sfvt_free_table(vartable_t *table) { sfip_var_t *p, *tmp; if (!table) return; p = table->head; while (p) { tmp = p->next; sfvar_free(p); p = tmp; } free(table); } /* Prints a table's contents */ void sfip_print_table(FILE *f, vartable_t *table) { sfip_var_t *p; if(!f || !table) return; fprintf(f, "(Table %p)\n", (void*)table); for(p=table->head; p; p=p->next) { sfvar_print_to_file(f, p); puts(""); } } //#define TESTER #ifdef TESTER int failures = 0; #define TEST(x) if(x) printf("\tSuccess: line %d\n", __LINE__);\ else { printf("\tFAILURE: line %d\n", __LINE__); failures++; } int main() { vartable_t *table; sfip_var_t *var; sfcidr_t *ip; puts("********************************************************************"); puts("Testing variable table parsing:"); table = sfvt_alloc_table(); /* These are all valid */ TEST(sfvt_add_str(table, "foo [ 1.2.0.0/16, ffff:dead:beef::0 ] ", &var) == SFIP_SUCCESS); TEST(sfvt_add_str(table, " goo [ ffff:dead:beef::0 ] ", &var) == SFIP_SUCCESS); TEST(sfvt_add_str(table, " moo [ any ] ", &var) == SFIP_SUCCESS); /* Test variable redefine */ TEST(sfvt_add_str(table, " goo [ 192.168.0.1, 192.168.0.2, 192.168.255.0 255.255.248.0 ] ", &var) == SFIP_DUPLICATE); /* These should fail since it's a variable name with bogus arguments */ TEST(sfvt_add_str(table, " phlegm ", &var) == SFIP_FAILURE); TEST(sfvt_add_str(table, " phlegm [", &var) == SFIP_FAILURE); TEST(sfvt_add_str(table, " phlegm [ ", &var) == SFIP_FAILURE); TEST(sfvt_add_str(table, " phlegm [sdfg ", &var) == SFIP_FAILURE); TEST(sfvt_add_str(table, " phlegm [ sdfg, 12.123.1.4.5 }", &var) == SFIP_FAILURE); TEST(sfvt_add_str(table, " [ 12.123.1.4.5 ]", &var) == SFIP_FAILURE); TEST(sfvt_add_str(table, NULL, &var) == SFIP_FAILURE); TEST(sfvt_add_str(table, "", &var) == SFIP_FAILURE); puts(""); puts("********************************************************************"); puts("Expansions:"); /* Note: used this way leaks memory */ printf("\t%s\n", sfvt_alloc_expanded(table, "$foo")); printf("\t%s\n", sfvt_alloc_expanded(table, "goo $goo sf sfasdfasdf $moo")); printf("\t%s\n", sfvt_alloc_expanded(table, " ssdf $moo $moo asdf $fooadff $foo ")); printf("\t%s\n", sfvt_alloc_expanded(table, " ssdf $moo $moo\\sdf $foo adff")); puts(""); puts("********************************************************************"); puts("Containment checks:"); var = sfvt_lookup(table, "goo"); ip = sfip_alloc("192.168.248.255"); TEST(sfvar_ip_in(var, ip) == SFIP_SUCCESS); /* Check against the 'any' variable */ var = sfvt_lookup_var(table, "moo"); TEST(sfvar_ip_in(var, ip) == SFIP_SUCCESS); /* Verify it's not in this variable */ var = sfvt_lookup_var(table, "foo"); TEST(sfvar_ip_in(var, ip) == SFIP_FAILURE); /* Check boundary cases */ var = sfvt_lookup_var(table, "goo"); free_ip(ip); ip = sfip_alloc_str("192.168.0.3"); TEST(sfvar_ip_in(var, ip) == SFIP_FAILURE); free_ip(ip); ip = sfip_alloc_str("192.168.0.2"); TEST(sfvar_ip_in(var, ip) == SFIP_SUCCESS); puts(""); puts("********************************************************************"); printf("\n\tTotal Failures: %d\n", failures); return 0; } #endif snort-2.9.15.1/src/sfutil/sf_vartable.h0000644000175200017520000000351013571422607014605 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 1998-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * Adam Keeton * sf_vartable.h * 11/17/06 * * Library for implementing a variable table. * All API calls have the prefix "sfvt". */ #ifndef SF_VARTABLE_H #define SF_VARTABLE_H #include "ipv6_port.h" #include "sf_ipvar.h" /* Allocates new variable table */ vartable_t * sfvt_alloc_table(void); void sfvt_free_table(vartable_t *table); /* Adds the variable described by "str" to the table "table" */ SFIP_RET sfvt_add_str(vartable_t *table, char *str, sfip_var_t **); SFIP_RET sfvt_define(vartable_t *table, char *name, char *value); /* Adds the variable described by "str" to the variable "dst", * using the vartable for looking variables used within "str" */ SFIP_RET sfvt_add_to_var(vartable_t *table, sfip_var_t *dst, char *src); /* Looks up a variable from the table using the name as the key */ sfip_var_t *sfvt_lookup_var(vartable_t *table, char *name); /* Prints a table's contents */ void sfvt_print(FILE *f, vartable_t *table); #endif snort-2.9.15.1/src/sfutil/sf_iph.c0000644000175200017520000003264113571422607013567 00000000000000/* $Id$ */ /**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2007-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "decode.h" #include "reg_test.h" #define FAILURE -1 #define SUCCESS 0 #define IP6_HEADER_LEN 40 /* Version is the first four bits of the uint32_t passed in */ #define IP6_VER(x) \ (ntohl(x) >> 28) /* The 'Packet' structure is almost always allocated on the stack. * Likewise, return buffers will almost always be aswell. * So, for performance reasons, argument validation can be disabled * and removed from the code at compile time to prevent unecessary extra * conditionals from being checked at run-time. */ #define ERR_CHK_LVL 0 #if ERR_CHK_LVL == 2 #define VALIDATE(x,y) if(!x || !y) return FAILURE; #elif ERR_CHK_LVL == 1 #define VALIDATE(x,y) if(!y) return FAILURE; #else #define VALIDATE(x,y) #endif sfaddr_t *ip6_ret_src(const Packet *p) { VALIDATE(p, 1); return &p->ip6h->ip_addrs->ip_src; } sfaddr_t *orig_ip6_ret_src(const Packet *p) { VALIDATE(p, 1); return &p->orig_ip6h->ip_addrs->ip_src; } sfaddr_t *ip6_ret_dst(const Packet *p) { VALIDATE(p, 1); return &p->ip6h->ip_addrs->ip_dst; } sfaddr_t *orig_ip6_ret_dst(const Packet *p) { VALIDATE(p, 1); return &p->orig_ip6h->ip_addrs->ip_dst; } uint16_t ip6_ret_toc(const Packet *p) { uint16_t toc; VALIDATE(p,1); toc = (uint16_t)((ntohl(p->ip6h->vcl) & 0x0FF00000) >> 20); return toc; } uint16_t orig_ip6_ret_toc(const Packet *p) { uint16_t toc; VALIDATE(p,1); toc = (uint16_t)((ntohl(p->orig_ip6h->vcl) & 0x0FF00000) >> 20); return toc; } uint8_t ip6_ret_hops(const Packet *p) { // VALIDATE(p,1); return p->ip6h->hop_lmt; } uint8_t orig_ip6_ret_hops(const Packet *p) { // VALIDATE(p,1); return p->orig_ip6h->hop_lmt; } uint16_t ip6_ret_len(const Packet *p) { VALIDATE(p,1); /* The length field does not include the header in IPv6, but does in IPv4. * To make this analogous to IPv4, for Snort's purposes, we need to tack * on the difference. */ return p->ip6h->len; } uint16_t orig_ip6_ret_len(const Packet *p) { VALIDATE(p,1); return p->orig_ip6h->len; } uint32_t ip6_ret_id(const Packet *p) { IP6Frag *frag_hdr; if (p->ip6_extension_count == 0) return 0; frag_hdr = (IP6Frag*)p->ip6_extensions[p->ip6_frag_index].data; return frag_hdr->ip6f_ident; } uint32_t orig_ip6_ret_id(const Packet *p) { // XXX-IPv6 "NOT YET IMPLEMENTED - IP6 identification" return 0; } uint8_t ip6_ret_next(const Packet *p) { VALIDATE(p,1); return p->ip6h->next; } uint8_t orig_ip6_ret_next(const Packet *p) { VALIDATE(p,1); return p->orig_ip6h->next; } uint16_t ip6_ret_off(const Packet *p) { IP6Frag *frag_hdr; if (p->ip6_extension_count == 0) return 0; frag_hdr = (IP6Frag *)p->ip6_extensions[p->ip6_frag_index].data; return frag_hdr->ip6f_offlg; } uint16_t orig_ip6_ret_off(const Packet *p) { // XXX-IPv6 "NOT YET IMPLEMENTED - IP6 frag offset" return 0; } uint8_t ip6_ret_ver(const Packet *p) { return (uint8_t)IP6_VER(p->ip6h->vcl); } uint8_t orig_ip6_ret_ver(const Packet *p) { return (uint8_t)IP6_VER(p->orig_ip6h->vcl); } sfaddr_t *ip4_ret_dst(const Packet *p) { VALIDATE(p,1); return &p->ip4h->ip_addrs->ip_dst; } sfaddr_t *orig_ip4_ret_dst(const Packet *p) { VALIDATE(p,1); return &p->orig_ip4h->ip_addrs->ip_dst; } sfaddr_t *ip4_ret_src(const Packet *p) { VALIDATE(p,1); return &p->ip4h->ip_addrs->ip_src; } sfaddr_t *orig_ip4_ret_src(const Packet *p) { VALIDATE(p,1); return &p->orig_ip4h->ip_addrs->ip_src; } uint16_t ip4_ret_tos(const Packet *p) { VALIDATE(p,1); return p->ip4h->ip_tos; } uint16_t orig_ip4_ret_tos(const Packet *p) { VALIDATE(p,1); return p->orig_ip4h->ip_tos; } uint8_t ip4_ret_ttl(const Packet *p) { VALIDATE(p,1); return p->ip4h->ip_ttl; } uint8_t orig_ip4_ret_ttl(const Packet *p) { VALIDATE(p,1); return p->orig_ip4h->ip_ttl; } uint16_t ip4_ret_len(const Packet *p) { VALIDATE(p,1); return p->ip4h->ip_len; } uint16_t orig_ip4_ret_len(const Packet *p) { VALIDATE(p,1); return p->orig_ip4h->ip_len; } uint32_t ip4_ret_id(const Packet *p) { VALIDATE(p,1); return (uint32_t)p->ip4h->ip_id; } uint32_t orig_ip4_ret_id(const Packet *p) { VALIDATE(p,1); return (uint32_t)p->orig_ip4h->ip_id; } uint8_t ip4_ret_proto(const Packet *p) { // VALIDATION() return p->ip4h->ip_proto; } uint8_t orig_ip4_ret_proto(const Packet *p) { // VALIDATION() return p->orig_ip4h->ip_proto; } uint16_t ip4_ret_off(const Packet *p) { return p->ip4h->ip_off; } uint16_t orig_ip4_ret_off(const Packet *p) { return p->orig_ip4h->ip_off; } uint8_t ip4_ret_ver(const Packet *p) { return IP_VER(p->iph); } uint8_t orig_ip4_ret_ver(const Packet *p) { return IP_VER(p->orig_iph); } uint8_t ip4_ret_hlen(const Packet *p) { return IP_HLEN(p->iph); } uint8_t orig_ip4_ret_hlen(const Packet *p) { return IP_HLEN(p->orig_iph); } uint8_t ip6_ret_hlen(const Packet *p) { /* Snort is expecting this number to be in terms of 32 bit words */ return IP6_HDR_LEN / 4 ; } uint8_t orig_ip6_ret_hlen(const Packet *p) { return IP6_HDR_LEN / 4; } IPH_API ip4 = { ip4_ret_src, ip4_ret_dst, ip4_ret_tos, ip4_ret_ttl, ip4_ret_len, ip4_ret_id, ip4_ret_proto, ip4_ret_off, ip4_ret_ver, ip4_ret_hlen, orig_ip4_ret_src, orig_ip4_ret_dst, orig_ip4_ret_tos, orig_ip4_ret_ttl, orig_ip4_ret_len, orig_ip4_ret_id, orig_ip4_ret_proto, orig_ip4_ret_off, orig_ip4_ret_ver, orig_ip4_ret_hlen, IPH_API_V4 }; IPH_API ip6 = { ip6_ret_src, ip6_ret_dst, ip6_ret_toc, ip6_ret_hops, ip6_ret_len, ip6_ret_id, ip6_ret_next, ip6_ret_off, ip6_ret_ver, ip6_ret_hlen, orig_ip6_ret_src, orig_ip6_ret_dst, orig_ip6_ret_toc, orig_ip6_ret_hops, orig_ip6_ret_len, orig_ip6_ret_id, orig_ip6_ret_next, orig_ip6_ret_off, orig_ip6_ret_ver, orig_ip6_ret_hlen, IPH_API_V6 }; static inline void _set_callbacks(struct _Packet *p, int family, char orig) { if ( !orig ) { if(family == AF_INET) p->iph_api = &ip4; else p->iph_api = &ip6; p->family = family; } else { if(family == AF_INET) p->orig_iph_api = &ip4; else p->orig_iph_api = &ip6; p->orig_family = family; } } void set_callbacks(struct _Packet *p, int family, char orig) { _set_callbacks(p, family, orig); } void sfiph_build(Packet *p, const void *hdr, int family) { IP6RawHdr *hdr6; IPHdr *hdr4; if(!p || !hdr) return; /* If family is already set, we've been here before. * That means this is a nested IP. */ if (p->family != NO_IP) { memcpy(&p->outer_ips, &p->inner_ips, sizeof(p->outer_ips)); if (p->iph_api->ver == IPH_API_V4) { memcpy(&p->outer_ip4h, &p->inner_ip4h, sizeof(p->outer_ip4h) - sizeof(p->outer_ip4h.ip_addrs)); p->outer_ip4h.ip_addrs = &p->outer_ips; } else if (p->iph_api->ver == IPH_API_V6) { memcpy(&p->outer_ip6h, &p->inner_ip6h, sizeof(p->outer_ip6h) - sizeof(p->outer_ip6h.ip_addrs)); p->outer_ip6h.ip_addrs = &p->outer_ips; } p->outer_iph_api = p->iph_api; p->outer_family = p->family; } _set_callbacks(p, family, CALLBACK_IP); if(family == AF_INET) { hdr4 = (IPHdr*)hdr; /* The struct Snort uses is identical to the actual IP4 struct, * with the exception of the IP addresses. Copy over everything but * the IPs */ memcpy(&p->inner_ip4h, hdr4, sizeof(IPHdr) - 8); #ifdef HAVE_DAQ_REAL_ADDRESSES if (p->outer_family != NO_IP || !(p->pkth->flags & DAQ_PKT_FLAG_REAL_ADDRESSES)) { #endif sfip_set_raw(&p->inner_ips.ip_src, &hdr4->ip_src, AF_INET); sfip_set_raw(&p->inner_ips.ip_dst, &hdr4->ip_dst, AF_INET); #ifdef HAVE_DAQ_REAL_ADDRESSES } else { sfip_set_raw(&p->inner_ips.ip_src, p->pkth->real_sIP.s6_addr, (p->pkth->flags & DAQ_PKT_FLAG_REAL_SIP_V6) ? AF_INET6 : AF_INET); sfip_set_raw(&p->inner_ips.ip_dst, p->pkth->real_dIP.s6_addr, (p->pkth->flags & DAQ_PKT_FLAG_REAL_DIP_V6) ? AF_INET6 : AF_INET); } #endif p->inner_ip4h.ip_addrs = &p->inner_ips; p->actual_ip_len = ntohs(p->inner_ip4h.ip_len); p->ip4h = &p->inner_ip4h; } else { hdr6 = (IP6RawHdr*)hdr; /* The struct Snort uses is identical to the actual IP6 struct, * with the exception of the IP addresses. Copy over everything but * the IPs*/ memcpy(&p->inner_ip6h, hdr6, sizeof(IP6RawHdr) - 32); #ifdef HAVE_DAQ_REAL_ADDRESSES if (p->outer_family != NO_IP || !(p->pkth->flags & DAQ_PKT_FLAG_REAL_ADDRESSES)) { #endif sfip_set_raw(&p->inner_ips.ip_src, &hdr6->ip6_src, family); sfip_set_raw(&p->inner_ips.ip_dst, &hdr6->ip6_dst, family); #ifdef HAVE_DAQ_REAL_ADDRESSES } else { sfip_set_raw(&p->inner_ips.ip_src, p->pkth->real_sIP.s6_addr, (p->pkth->flags & DAQ_PKT_FLAG_REAL_SIP_V6) ? AF_INET6 : AF_INET); sfip_set_raw(&p->inner_ips.ip_dst, p->pkth->real_dIP.s6_addr, (p->pkth->flags & DAQ_PKT_FLAG_REAL_DIP_V6) ? AF_INET6 : AF_INET); } #endif p->inner_ip6h.ip_addrs = &p->inner_ips; p->actual_ip_len = ntohs(p->inner_ip6h.len) + IP6_HDR_LEN; p->ip6h = &p->inner_ip6h; } #ifdef REG_TEST if (rt_ip_increment) { uint32_t* addr; addr = sfaddr_get_ip4_ptr(&p->inner_ips.ip_src); *addr = htonl(ntohl(*addr) + rt_ip_increment); addr = sfaddr_get_ip4_ptr(&p->inner_ips.ip_dst); *addr = htonl(ntohl(*addr) + rt_ip_increment); } #endif } void sfiph_orig_build(Packet *p, const void *hdr, int family) { IP6RawHdr *hdr6; IPHdr *hdr4; if(!p || !hdr) return; /* If iph_api is already set, we've been here before. * That means this is a nested IP. */ if (p->orig_iph_api) { memcpy(&p->outer_orig_ips, &p->inner_orig_ips, sizeof(p->outer_orig_ips)); if (p->orig_iph_api->ver == IPH_API_V4) { memcpy(&p->outer_orig_ip4h, &p->inner_orig_ip4h, sizeof(p->outer_orig_ip4h) - sizeof(p->outer_orig_ip4h.ip_addrs)); p->outer_orig_ip4h.ip_addrs = &p->outer_orig_ips; p->outer_orig_iph_api = p->orig_iph_api; } else if (p->orig_iph_api->ver == IPH_API_V6) { memcpy(&p->outer_orig_ip6h, &p->inner_orig_ip6h, sizeof(p->outer_orig_ip6h) - sizeof(p->outer_orig_ip6h.ip_addrs)); p->outer_orig_ip6h.ip_addrs = &p->outer_orig_ips; p->outer_orig_iph_api = p->orig_iph_api; } } _set_callbacks(p, family, CALLBACK_ICMP_ORIG); if(family == AF_INET) { hdr4 = (IPHdr*)hdr; /* The struct Snort uses is identical to the actual IP6 struct, * with the exception of the IP addresses. Copy over everything but * the IPs */ memcpy(&p->inner_orig_ip4h, hdr4, sizeof(IPHdr) - 8); sfip_set_raw(&p->inner_orig_ips.ip_src, &hdr4->ip_src, family); sfip_set_raw(&p->inner_orig_ips.ip_dst, &hdr4->ip_dst, family); p->inner_orig_ip4h.ip_addrs = &p->inner_orig_ips; p->actual_ip_len = ntohs(p->inner_orig_ip4h.ip_len); p->orig_ip4h = &p->inner_orig_ip4h; } else { hdr6 = (IP6RawHdr*)hdr; /* The struct Snort uses is identical to the actual IP6 struct, * with the exception of the IP addresses. Copy over everything but * the IPs*/ memcpy(&p->inner_orig_ip6h, hdr6, sizeof(IP6RawHdr) - 32); sfip_set_raw(&p->inner_orig_ips.ip_src, &hdr6->ip6_src, family); sfip_set_raw(&p->inner_orig_ips.ip_dst, &hdr6->ip6_dst, family); p->inner_orig_ip6h.ip_addrs = &p->inner_orig_ips; p->actual_ip_len = ntohs(p->inner_orig_ip6h.len) + IP6_HDR_LEN; p->orig_ip6h = &p->inner_orig_ip6h; } } #ifdef TESTER int main() { Packet p; IP4Hdr i4; IP6Hdr i6; /* This test assumes we get an IPv4 packet and verifies * that the correct callbacks are setup, and they return * the correct values. */ _set_callbacks(&p, AF_INET, CALLBACK_IP); /* Same test as above, but with IPv6 */ _set_callbacks(&p, AF_INET6, CALLBACK_IP); return 0; } #endif snort-2.9.15.1/src/sfutil/sf_iph.h0000644000175200017520000000521013571422607013564 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2007-2013 Sourcefire, Inc. ** ** 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 nto, write to the Free Software ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, ** USA */ #ifndef SFIPH_H #define SFIPH_H struct _Packet; typedef struct _IPH_API { sfaddr_t * (*iph_ret_src)(const struct _Packet *); sfaddr_t * (*iph_ret_dst)(const struct _Packet *); uint16_t (*iph_ret_tos)(const struct _Packet *); uint8_t (*iph_ret_ttl)(const struct _Packet *); uint16_t (*iph_ret_len)(const struct _Packet *); uint32_t (*iph_ret_id)(const struct _Packet *); uint8_t (*iph_ret_proto)(const struct _Packet *); uint16_t (*iph_ret_off)(const struct _Packet *); uint8_t (*iph_ret_ver)(const struct _Packet *); uint8_t (*iph_ret_hlen)(const struct _Packet *); sfaddr_t * (*orig_iph_ret_src)(const struct _Packet *); sfaddr_t * (*orig_iph_ret_dst)(const struct _Packet *); uint16_t (*orig_iph_ret_tos)(const struct _Packet *); uint8_t (*orig_iph_ret_ttl)(const struct _Packet *); uint16_t (*orig_iph_ret_len)(const struct _Packet *); uint32_t (*orig_iph_ret_id)(const struct _Packet *); uint8_t (*orig_iph_ret_proto)(const struct _Packet *); uint16_t (*orig_iph_ret_off)(const struct _Packet *); uint8_t (*orig_iph_ret_ver)(const struct _Packet *); uint8_t (*orig_iph_ret_hlen)(const struct _Packet *); char ver; } IPH_API; extern IPH_API ip4; extern IPH_API ip6; #define IPH_API_V4 4 #define IPH_API_V6 6 #define iph_is_valid(p) ((p)->family != NO_IP) #define NO_IP 0 void sfiph_build(struct _Packet *p, const void *hdr, int family); void sfiph_orig_build(struct _Packet *p, const void *hdr, int family); /* Sets the callbacks to point at the family selected by * * "family". "family" is either AF_INET or AF_INET6 */ #define CALLBACK_IP 0 #define CALLBACK_ICMP_ORIG 1 void set_callbacks(struct _Packet *p, int family, char orig); #endif snort-2.9.15.1/src/sfutil/sf_textlog.c0000644000175200017520000001775513571422607014506 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2003-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /** * @file sf_textlog.c * @author Russ Combs * @date * * @brief implements buffered text stream for logging */ #include #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sf_types.h" #include "sf_textlog.h" #include "log.h" #include "util.h" /* some reasonable minimums */ #define MIN_BUF (1*K_BYTES) #define MIN_FILE (MIN_BUF) /*------------------------------------------------------------------- * TextLog_Open/Close: open/close associated log file *------------------------------------------------------------------- */ static FILE* TextLog_Open (const char* name) { if ( !name ) return OpenAlertFile(NULL); if ( !strcasecmp(name, "stdout") ) return stdout; return OpenAlertFile(name); } static void TextLog_Close (FILE* file) { if ( !file ) return; if ( file != stdout ) fclose(file); } static size_t TextLog_Size (FILE* file) { struct stat sbuf; int fd = fileno(file); int err = fstat(fd, &sbuf); return err ? 0 : sbuf.st_size; } /*------------------------------------------------------------------- * TextLog_Init: constructor *------------------------------------------------------------------- */ TextLog* TextLog_Init ( const char* name, unsigned int maxBuf, size_t maxFile ) { TextLog* this; if ( maxBuf < MIN_BUF ) maxBuf = MIN_BUF; if ( maxFile < MIN_FILE ) maxFile = MIN_FILE; if ( maxFile < maxBuf ) maxFile = maxBuf; this = (TextLog*)malloc(sizeof(TextLog)+maxBuf); if ( !this ) { FatalError("Unable to allocate a TextLog(%u)!\n", maxBuf); } this->name = name ? SnortStrdup(name) : NULL; this->file = TextLog_Open(this->name); this->size = TextLog_Size(this->file); this->last = time(NULL); this->maxFile = maxFile; this->maxBuf = maxBuf; TextLog_Reset(this); return this; } /*------------------------------------------------------------------- * TextLog_Term: destructor *------------------------------------------------------------------- */ void TextLog_Term (TextLog* this) { if ( !this ) return; TextLog_Flush(this); TextLog_Close(this->file); if ( this->name ) free(this->name); free(this); } /*------------------------------------------------------------------- * TextLog_Flush: start writing to new file * but don't roll over stdout or any sooner * than resolution of filename discriminator *------------------------------------------------------------------- */ static void TextLog_Roll (TextLog* this) { if ( this->file == stdout ) return; if ( this->last >= time(NULL) ) return; TextLog_Close(this->file); RollAlertFile(this->name); this->file = TextLog_Open(this->name); this->last = time(NULL); this->size = 0; } /*------------------------------------------------------------------- * TextLog_Flush: write buffered stream to file *------------------------------------------------------------------- */ bool TextLog_Flush(TextLog* this) { int ok; if ( !this->pos ) return FALSE; if ( this->size + this->pos > this->maxFile ) TextLog_Roll(this); ok = fwrite(this->buf, this->pos, 1, this->file); if ( ok == 1 ) { this->size += this->pos; TextLog_Reset(this); return TRUE; } return FALSE; } /*------------------------------------------------------------------- * TextLog_Putc: append char to buffer *------------------------------------------------------------------- */ bool TextLog_Putc (TextLog* this, char c) { if ( TextLog_Avail(this) < 1 ) { TextLog_Flush(this); } this->buf[this->pos++] = c; this->buf[this->pos] = '\0'; return TRUE; } /*------------------------------------------------------------------- * TextLog_Write: append string to buffer *------------------------------------------------------------------- */ bool TextLog_Write (TextLog* this, const char* str, int len) { int avail = TextLog_Avail(this); if ( len >= avail ) { TextLog_Flush(this); avail = TextLog_Avail(this); } len = snprintf(this->buf+this->pos, avail, "%s", str); if ( len >= avail ) { this->pos = this->maxBuf - 1; this->buf[this->pos] = '\0'; return FALSE; } else if ( len < 0 ) { return FALSE; } this->pos += len; return TRUE; } /*------------------------------------------------------------------- * TextLog_Printf: append formatted string to buffer *------------------------------------------------------------------- */ bool TextLog_Print (TextLog* this, const char* fmt, ...) { int avail = TextLog_Avail(this); int len; va_list ap; va_start(ap, fmt); len = vsnprintf(this->buf+this->pos, avail, fmt, ap); va_end(ap); if ( len >= avail ) { TextLog_Flush(this); avail = TextLog_Avail(this); va_start(ap, fmt); len = vsnprintf(this->buf+this->pos, avail, fmt, ap); va_end(ap); } if ( len >= avail ) { this->pos = this->maxBuf - 1; this->buf[this->pos] = '\0'; return FALSE; } else if ( len < 0 ) { return FALSE; } this->pos += len; return TRUE; } /*------------------------------------------------------------------- * TextLog_PrintUnicode: append formatted string to buffer *------------------------------------------------------------------- */ bool TextLog_PrintUnicode(TextLog* this, uint8_t *buffer, uint32_t length, uint8_t is_little_endian) { uint32_t out_len = length/2 + 1, i, j; wchar_t *outbuf = (wchar_t *)malloc(out_len*sizeof(wchar_t)); if (!outbuf) { FatalError("TextLog_PrintUnicode: Failed to allocate memory for outbuf\n"); return FALSE; } for(i = 0,j = 0; ifile, "%ls", outbuf); free(outbuf); return TRUE; } /*------------------------------------------------------------------- * TextLog_Quote: write string escaping quotes * TBD could be smarter by counting required escapes instead of * checking for 3 *------------------------------------------------------------------- */ bool TextLog_Quote (TextLog* this, const char* qs) { int pos = this->pos; if ( TextLog_Avail(this) < 3 ) { TextLog_Flush(this); } this->buf[pos++] = '"'; while ( *qs && (this->maxBuf - pos > 2) ) { if ( *qs == '"' || *qs == '\\' ) { this->buf[pos++] = '\\'; } this->buf[pos++] = *qs++; } if ( *qs ) return FALSE; this->buf[pos++] = '"'; this->pos = pos; return TRUE; } snort-2.9.15.1/src/sfutil/sf_textlog.h0000644000175200017520000000634613571422607014505 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2003-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /** * @file sf_textlog.h * @author Russ Combs * @date Fri Jun 27 10:34:37 2003 * * @brief declares buffered text stream for logging * * Declares a TextLog_*() api for buffered logging. This allows * relatively painless transition from fprintf(), fwrite(), etc. * to a buffer that is formatted in memory and written with one * fwrite(). * * Additionally, the file is capped at a maximum size. Beyond * that, the file is closed, renamed, and reopened. The current * file always has the same name. Old files are renamed to that * name plus a timestamp. */ #ifndef _SF_TEXT_LOG_H #define _SF_TEXT_LOG_H #include #include #include #define K_BYTES (1024) #define M_BYTES (K_BYTES*K_BYTES) #define G_BYTES (K_BYTES*M_BYTES) /* * DO NOT ACCESS STRUCT MEMBERS DIRECTLY * EXCEPT FROM WITHIN THE IMPLEMENTATION! */ typedef struct _TextLog { /* private: */ /* file attributes: */ FILE* file; char* name; size_t size; size_t maxFile; time_t last; /* buffer attributes: */ unsigned int pos; unsigned int maxBuf; char buf[1]; } TextLog; TextLog* TextLog_Init ( const char* name, unsigned int maxBuf, size_t maxFile ); void TextLog_Term (TextLog* this); bool TextLog_Putc(TextLog*, char); bool TextLog_Quote(TextLog*, const char*); bool TextLog_Write(TextLog*, const char*, int len); bool TextLog_Print(TextLog*, const char* format, ...); bool TextLog_PrintUnicode(TextLog*, uint8_t *, uint32_t, uint8_t); bool TextLog_Flush(TextLog*); /*------------------------------------------------------------------- * helper functions *------------------------------------------------------------------- */ static inline int TextLog_Tell (TextLog* this) { return this->pos; } static inline int TextLog_Avail (TextLog* this) { return this->maxBuf - this->pos - 1; } static inline void TextLog_Reset (TextLog* this) { this->pos = 0; this->buf[this->pos] = '\0'; } static inline bool TextLog_NewLine (TextLog* this) { return TextLog_Putc(this, '\n'); } static inline bool TextLog_Puts (TextLog* this, const char* str) { return TextLog_Write(this, str, strlen(str)); } #endif /* _SF_TEXT_LOG_H */ snort-2.9.15.1/src/sfutil/sf_sechash.c0000644000175200017520000000466313571422607014430 00000000000000 /* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /*************************************************************************** * * File: sf_sechash.C * * Purpose: Provide a set of secure hash utilities * * History: * * Date: Author: Notes: * ---------- ------- ---------------------------------------------- * 12/05/13 ECB Initial coding begun * **************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "sf_types.h" #include "sf_sechash.h" #include "snort_debug.h" static struct { Secure_Hash_Type type; char *name; unsigned int length; } Secure_Hash_Map[] = { { SECHASH_SHA512, "SHA512", 64 }, { SECHASH_SHA256, "SHA256", 32 }, { SECHASH_MD5, "MD5", 16 }, { SECHASH_NONE, "", 0 } }; unsigned int SecHash_Type2Length( const Secure_Hash_Type type ) { unsigned int index; index = 0; while(Secure_Hash_Map[index].type != SECHASH_NONE) { if( Secure_Hash_Map[index].type == type ) { return( Secure_Hash_Map[index].length ); } index += 1; } return( 0 ); } Secure_Hash_Type SecHash_Name2Type( const char *name ) { unsigned int index; index = 0; while(Secure_Hash_Map[index].type != SECHASH_NONE) { if( strcasecmp(name,Secure_Hash_Map[index].name) == 0 ) { return( Secure_Hash_Map[index].type ); } index += 1; } return( SECHASH_NONE ); } snort-2.9.15.1/src/sfutil/sf_sechash.h0000644000175200017520000000723513571422607014433 00000000000000 /* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __SF_SECHASH_H__ #define __SF_SECHASH_H__ /* D E F I N E S *******************************************************/ #define SHA256_HASH_SIZE 32 #define SHA512_HASH_SIZE 64 #define MD5_HASH_SIZE 16 /* I N C L U D E S *****************************************************/ #include "config.h" #include #ifdef HAVE_OPENSSL_SHA #include #define SHA256CONTEXT SHA256_CTX #define SHA512CONTEXT SHA512_CTX #define SHA256INIT SHA256_Init #define SHA256UPDATE SHA256_Update #define SHA256FINAL SHA256_Final #define SHA256DIGEST SHA256 #define SHA512INIT SHA512_Init #define SHA512UPDATE SHA512_Update #define SHA512FINAL SHA512_Final #define SHA512DIGEST SHA512 #else #include "sha2.h" #define SHA256CONTEXT SHA256_CTX #define SHA512CONTEXT SHA512_CTX #define SHA256INIT SHA256_Init #define SHA256UPDATE SHA256_Update #define SHA256FINAL SHA256_Final #define SHA256DIGEST SHA256 #define SHA512INIT SHA512_Init #define SHA512UPDATE SHA512_Update #define SHA512FINAL SHA512_Final #define SHA512DIGEST SHA512 static inline unsigned char *SHA256(const unsigned char *data, size_t size, unsigned char *digest){ static unsigned char d[SHA256_HASH_SIZE]; SHA256CONTEXT c; if(!digest) digest = d; SHA256INIT(&c); SHA256UPDATE(&c, data, size); SHA256FINAL(digest, &c); return digest; } static inline unsigned char *SHA512(const unsigned char *data, size_t size, unsigned char *digest){ static unsigned char d[SHA512_HASH_SIZE]; SHA512CONTEXT c; if(!digest) digest = d; SHA512INIT(&c); SHA512UPDATE(&c, data, size); SHA512FINAL(digest, &c); return digest; } #endif /* HAVE_OPENSSL_SHA */ #ifdef HAVE_OPENSSL_MD5 #include #define MD5CONTEXT MD5_CTX #define MD5INIT MD5_Init #define MD5UPDATE MD5_Update #define MD5FINAL MD5_Final #define MD5DIGEST MD5 #else #include "md5.h" #define MD5CONTEXT struct MD5Context #define MD5INIT MD5Init #define MD5UPDATE MD5Update #define MD5FINAL MD5Final #define MD5DIGEST MD5 static inline unsigned char *MD5(const unsigned char *data, size_t size, unsigned char *digest){ static unsigned char d[MD5_HASH_SIZE]; MD5CONTEXT c; if(!digest) digest = d; MD5INIT(&c); MD5UPDATE(&c, data, size); MD5FINAL(digest, &c); return digest; } #endif /* HAVE_OPENSSL_MD5 */ /* A set of secure hash types */ typedef enum { SECHASH_NONE = 0, SECHASH_SHA256 = 1, SECHASH_SHA512, SECHASH_MD5 } Secure_Hash_Type; /* P R O T O T Y P E S *************************************************/ unsigned int SecHash_Type2Length( const Secure_Hash_Type type ); Secure_Hash_Type SecHash_Name2Type( const char *name ); #endif /* __SF_SECHASH_H__ */ snort-2.9.15.1/src/sfutil/sfPolicy.c0000644000175200017520000003115713571422607014110 00000000000000/**************************************************************************** * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2008-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "stdlib.h" #include "stdio.h" #include "string.h" #include "sfPolicy.h" #include "snort_debug.h" #include "sfrt.h" tSfPolicyId napRuntimePolicyId = 0; tSfPolicyId ipsRuntimePolicyId = 0; static inline int IsBound ( tSfPolicyId id ) { return ( id != SF_POLICY_UNBOUND ); } static inline int NotBound ( tSfPolicyId id ) { return !IsBound(id); } static void netBindFree( void *policy, void *config ); tSfPolicyConfig * sfPolicyInit(void) { int i; tSfPolicyConfig *new = (tSfPolicyConfig *)calloc(1, sizeof(tSfPolicyConfig)); if (new == NULL) return NULL; //initialize vlan bindings for (i = 0; i < SF_VLAN_BINDING_MAX; i++) { new->vlanBindings[i] = SF_POLICY_UNBOUND; } for (i = 0; i < SF_POLICY_ID_BINDING_MAX; i++) { new->policyIdBindings[i] = SF_POLICY_UNBOUND; } //initialize net bindings new->netBindTable = sfrt_new(DIR_16x7_4x4, IPv6, SF_NETWORK_BINDING_MAX, 20); return new; } void sfPolicyFini(tSfPolicyConfig *config) { int i; if (config == NULL) return; for (i = 0; i < SF_VLAN_BINDING_MAX; i++) { sfVlanDeleteBinding(config, i); } for (i = 0; i < SF_POLICY_ID_BINDING_MAX; i++) { sfPolicyIdDeleteBinding(config, i); } sfrt_cleanup2(config->netBindTable, netBindFree, config); sfrt_free(config->netBindTable); //policyConfig are deleted when all bindings to it are deleted. /* free default policy */ if (config->ppPolicies != NULL) { sfPolicyDelete(config, config->defaultPolicyId); free(config->ppPolicies); } free(config); } static void netBindFree( void *policyId, void *config ) { if (policyId && config) { sfPolicyDelete((tSfPolicyConfig *)config, *((tSfPolicyId *)policyId)); free(policyId); } } /**Tracks filename to vlan group id */ int sfPolicyAdd(tSfPolicyConfig *config, char *fileName) { tSfPolicy *pObject = NULL; int emptyIndex = -1; tSfPolicyId i; tSfPolicy **ppTmp; if (config == NULL) return SF_POLICY_UNBOUND; for (i = 0; i < config->numAllocatedPolicies; i++) { if (config->ppPolicies[i]) { if (!strcmp(config->ppPolicies[i]->filename, fileName)) { config->ppPolicies[i]->refCount++; return i; } } else if (emptyIndex == -1) { emptyIndex = i; } } if (emptyIndex == -1) { //no empty slot available. Allocate more space for policies ppTmp = (tSfPolicy **)calloc(config->numAllocatedPolicies + POLICY_ALLOCATION_CHUNK, sizeof(tSfPolicy *)); if (!ppTmp) return SF_POLICY_UNBOUND; if (config->numAllocatedPolicies) { memcpy(ppTmp, config->ppPolicies, sizeof(tSfPolicyConfig *) * config->numAllocatedPolicies); free(config->ppPolicies); } config->ppPolicies = ppTmp; emptyIndex = config->numAllocatedPolicies; config->numAllocatedPolicies += POLICY_ALLOCATION_CHUNK; } //allocate and initialize pObject = (tSfPolicy *)calloc(1, sizeof(tSfPolicy)); if (!pObject) return SF_POLICY_UNBOUND; pObject->refCount++; pObject->filename = strdup(fileName); if (!pObject->filename) { free(pObject); return SF_POLICY_UNBOUND; } config->ppPolicies[emptyIndex] = pObject; config->numActivePolicies++; //successfully added. return emptyIndex; } void sfPolicyDelete(tSfPolicyConfig *config, tSfPolicyId policyId) { tSfPolicy *pObject = NULL; if ((config == NULL) || (config->ppPolicies == NULL) || (policyId >= config->numAllocatedPolicies)) { return; } pObject = config->ppPolicies[policyId]; if (pObject) { pObject->refCount--; if (pObject->refCount == 0) { if (pObject->filename) free(pObject->filename); free(pObject); config->ppPolicies[policyId] = NULL; config->numActivePolicies--; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES, "sfPolicyDelete: freed policyConfig policyId %d\n", policyId);); } } } char * sfPolicyGet(tSfPolicyConfig *config, tSfPolicyId policyId) { tSfPolicy *pObject = NULL; if ((config == NULL) || (config->ppPolicies == NULL) || (policyId >= config->numAllocatedPolicies)) { return NULL; } pObject = config->ppPolicies[policyId]; if (pObject) return pObject->filename; return NULL; } /**Creates policyId if needed and creates a binding between vlan and policyId. * Tracks vlanId to vlan group id mapping */ //TBD replace calloc with SnortAlloc() int sfVlanAddBinding(tSfPolicyConfig *config, int vlanId, char *fileName) { tSfPolicyId policyId; if (config == NULL || vlanId >= SF_VLAN_BINDING_MAX) return -1; //create a policyId policyId = sfPolicyAdd(config, fileName); if ( NotBound(policyId) ) { return -1; } config->vlanBindings[vlanId] = policyId; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES, "Added vlandId %d, file %s, policyId: %d\n", vlanId, fileName, policyId);); return 0; } tSfPolicyId sfVlanGetBinding(tSfPolicyConfig *config, int vlanId) { tSfPolicyId policyId; if(vlanId >= SF_VLAN_BINDING_MAX){ //invalid policyid will never be bound. return default return config->defaultPolicyId; } policyId = config->vlanBindings[vlanId]; if ( NotBound(policyId) ) { //return default policyId for uninitialized binding return config->defaultPolicyId; } return policyId; } void sfVlanDeleteBinding(tSfPolicyConfig *config, int vlanId) { tSfPolicyId policyId; if(vlanId >= SF_VLAN_BINDING_MAX) return; //invalid, can't delete if ((config == NULL) || (vlanId < 0)) return; policyId = config->vlanBindings[vlanId]; if ( IsBound(policyId) ) { sfPolicyDelete(config, policyId); config->vlanBindings[vlanId] = SF_POLICY_UNBOUND; } } int sfPolicyIdAddBinding(tSfPolicyConfig *config, int parsedPolicyId, char *fileName) { tSfPolicyId policyId; if (config == NULL || parsedPolicyId >= SF_POLICY_ID_BINDING_MAX) return -1; //create a policyId policyId = sfPolicyAdd(config, fileName); if ( NotBound(policyId) ) { return -1; } config->policyIdBindings[parsedPolicyId] = policyId; DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES, "Added parsedPolicyId %d, file %s, policyId: %d\n", parsedPolicyId, fileName, policyId);); return 0; } tSfPolicyId sfPolicyIdGetBinding(tSfPolicyConfig *config, int parsedPolicyId) { tSfPolicyId policyId; if(parsedPolicyId >= SF_POLICY_ID_BINDING_MAX){ //invalid policyid will never be bound. return default return config->defaultPolicyId; } policyId = config->policyIdBindings[parsedPolicyId]; if ( NotBound(policyId) ) { //return default policyId for uninitialized binding return config->defaultPolicyId; } return policyId; } void sfPolicyIdDeleteBinding(tSfPolicyConfig *config, int parsedPolicyId) { tSfPolicyId policyId; if(parsedPolicyId >= SF_POLICY_ID_BINDING_MAX) return; //invalid, can't delete if ((config == NULL) || (parsedPolicyId < 0)) return; policyId = config->policyIdBindings[parsedPolicyId]; if ( IsBound(policyId) ) { sfPolicyDelete(config, policyId); config->policyIdBindings[parsedPolicyId] = SF_POLICY_UNBOUND; } } /**Get applicable policy given of a packet. Vlan can be negative * number if vlan header is not present. * * Search policy bound to vlan if vlan is not negative. If matched polciy is default one, * then search using destination IP address. If matched policy is default then search using * source IP address. * * @param vlanId - vlan id from a packet. Should be unbound if vlan tag is not present. * @param srcIP - Source IP address * @param dstIP - Destination IP address * * @returns policyId */ tSfPolicyId sfGetApplicablePolicyId( tSfPolicyConfig *config, int vlanId, sfaddr_t* srcIp, sfaddr_t* dstIp ) { tSfPolicyId dst_id; if (config == NULL) return SF_POLICY_UNBOUND; if (vlanId > 0) { tSfPolicyId vlan_id = sfVlanGetBinding(config, vlanId); if (vlan_id > 0) return vlan_id; } dst_id = sfNetworkGetBinding(config, dstIp); return (dst_id > 0 ? dst_id : sfNetworkGetBinding(config, srcIp)); } /**Add network binding to a policy * @param Ip - IP address or CIDR block to policy identified by file. * @param fileName - name of configuration file * * @returns 0 if successful, -1 otherwise. */ int sfNetworkAddBinding( tSfPolicyConfig *config, sfcidr_t* Ip, char *fileName ) { tSfPolicyId *policyId; int iRet; if ((config == NULL) || (Ip == NULL) || (fileName == NULL)) return -1; if ((policyId = calloc(sizeof(tSfPolicyId), 1)) == NULL) { return -1; } //create a policyId *policyId = sfPolicyAdd(config, fileName); if ( NotBound(*policyId) ) { free(policyId); return -1; } iRet = sfrt_insert(Ip, (unsigned char)Ip->bits, (void *)policyId, RT_FAVOR_SPECIFIC, config->netBindTable); //DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Added vlandId %d, file %s, policyId: %d\n", vlanId, fileName, policyId);); if (iRet) { free(policyId); return -1; } return 0; } unsigned int sfNetworkGetBinding( tSfPolicyConfig *config, sfaddr_t* ip ) { tSfPolicyId *policyId = NULL; if ((void *)ip == NULL) return config->defaultPolicyId; policyId = (tSfPolicyId *)sfrt_lookup(ip, config->netBindTable); if (!policyId) { return config->defaultPolicyId; } return *policyId; } void sfNetworkDeleteBinding( tSfPolicyConfig *config, sfaddr_t* ip ) { tSfPolicyId *policyId; if ((void *)ip == NULL) return; policyId = (tSfPolicyId *)sfrt_lookup(ip, config->netBindTable); if (!policyId) return; //TBD - delete function is not provided in sfrt.c sfPolicyDelete(config, *policyId); } //Move to sfDynArray.c/h /**Dynamic array bound checks. If index is greater than maxElement then realloc like operation * is performed. * @param dynArray - dynamic array * @param index - 0 based. Index of element that will be accessed by application either as rvalue or lvalue. * @maxElements - Number of elements already allocated in dynArray. 0 value means no elements are allocated * and therefore dynArray[0] will cause memory allocation. */ int sfDynArrayCheckBounds ( void ** dynArray, unsigned int index, unsigned int *maxElements ) { void *ppTmp = NULL; if (index >= *maxElements) { //expand the array ppTmp = calloc(index+POLICY_ALLOCATION_CHUNK, sizeof(void *)); if (!(ppTmp)) { return -1; } if (*maxElements) { memcpy(ppTmp, *dynArray, sizeof(void*)*(*maxElements)); free(*dynArray); } *dynArray = ppTmp; *maxElements = index + POLICY_ALLOCATION_CHUNK; } return 0; } snort-2.9.15.1/src/sfutil/sfPolicy.h0000644000175200017520000001070713571422607014113 00000000000000/**************************************************************************** * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2008-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #ifndef _SF_POLICY_H_ #define _SF_POLICY_H_ #include "sf_ip.h" #include "ipv6_port.h" #include "sfrt.h" #include "snort_debug.h" /**Number of additional policies allocated with each re-alloc operation. */ #define POLICY_ALLOCATION_CHUNK 10 #define SF_VLAN_BINDING_MAX 4096 #define SF_POLICY_ID_BINDING_MAX 4096 #define SF_NETWORK_BINDING_MAX 4096 #define SF_POLICY_UNBOUND 0xffffffff #define SF_DEFAULT_POLICY_ID 0 /*vlan id or address range is reduced to policy id. and subsequent processing is done using policy id only. */ typedef struct { /**number of vlans which are member of this group. When membership falls to 0, then this group should be deleted. */ unsigned int refCount; char *filename; unsigned int isConfigProcessed:1; } tSfPolicy; typedef enum { SF_BINDING_TYPE_VLAN, SF_BINDING_TYPE_NETWORK, SF_BINDING_TYPE_POLICY_ID, SF_BINDING_TYPE_UNKNOWN } tSF_BINDING_TYPE; typedef unsigned int tSfPolicyId; typedef struct { /**group id assigned to each file name. The groupId is an abstract concept * to tie multiple vlans into one group. */ tSfPolicy **ppPolicies; tSfPolicyId defaultPolicyId; /**policy id of configuration file or packet being processed. */ tSfPolicyId numAllocatedPolicies; unsigned int numActivePolicies; /**vlan to policyId bindings. */ tSfPolicyId vlanBindings[SF_VLAN_BINDING_MAX]; /**policyId to policyId bindings. */ tSfPolicyId policyIdBindings[SF_POLICY_ID_BINDING_MAX]; /**Network to policyId bindings. */ table_t *netBindTable; } tSfPolicyConfig; tSfPolicyConfig * sfPolicyInit( void ); void sfPolicyFini( tSfPolicyConfig * ); int sfPolicyAdd( tSfPolicyConfig *, char * ); void sfPolicyDelete( tSfPolicyConfig *, tSfPolicyId ); char * sfPolicyGet( tSfPolicyConfig *, tSfPolicyId ); int sfVlanAddBinding( tSfPolicyConfig *, int, char * ); tSfPolicyId sfVlanGetBinding( tSfPolicyConfig *, int ); void sfVlanDeleteBinding( tSfPolicyConfig *, int ); int sfPolicyIdAddBinding( tSfPolicyConfig *, int, char * ); tSfPolicyId sfPolicyIdGetBinding( tSfPolicyConfig *, int ); void sfPolicyIdDeleteBinding( tSfPolicyConfig *, int ); unsigned int sfGetApplicablePolicyId( tSfPolicyConfig *, int, sfaddr_t*, sfaddr_t* ); int sfNetworkAddBinding( tSfPolicyConfig *, sfcidr_t *, char * ); unsigned int sfNetworkGetBinding( tSfPolicyConfig *, sfaddr_t* ); void sfNetworkDeleteBinding( tSfPolicyConfig *, sfaddr_t* ); static inline tSfPolicyId sfGetDefaultPolicy( tSfPolicyConfig *config ) { if (config == NULL) return 0; return config->defaultPolicyId; } static inline void sfSetDefaultPolicy( tSfPolicyConfig *config, tSfPolicyId policyId ) { if ((config == NULL) || (policyId >= config->numAllocatedPolicies)) return; config->defaultPolicyId = policyId; } static inline tSfPolicyId sfPolicyNumAllocated( tSfPolicyConfig *config ) { if (config == NULL) return 0; return config->numAllocatedPolicies; } /*dynamic array functions */ int sfDynArrayCheckBounds ( void ** dynArray, unsigned int index, unsigned int *maxElements ); typedef tSfPolicyId (*GetPolicyFunc)(void); struct _SnortConfig; typedef tSfPolicyId (*GetParserPolicyFunc)(struct _SnortConfig *); #endif snort-2.9.15.1/src/sfutil/sfPolicyUserData.c0000644000175200017520000001312613571422607015535 00000000000000/**************************************************************************** * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2008-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "stdlib.h" #include "string.h" #include "sf_types.h" #include "sfPolicy.h" #include "sfPolicyUserData.h" /** @defgroup sfPolicyConfig Sourcefire policy configuration module * * Create a user policy configuration context. A context provides facility for creating * policy specific data instances. User can create as many policy instances as memory * resources will allow. User can create/delete context, set/clear/get user date for a * specific policy, default policy or current policy. User can also iterate over all instances * user data. * * In current design, preprocessor use this module directly to manage policy specific data * instances. A future enhancement can be to extract policy management code from each processor * and put it in a new policy management module. Policy management module will set a single * pointer to user data before calling appropriate callback function in a preprocessor. As * an example, policy module will iterate over all policies and call CleanExit functions in every * preprocessor for each policy. This will make policy management module will hide policies from * preprocessors and make them policy agnostic. * @{ */ /**Create a user context. * Allocates a new context and return it to user. All transactions within a context are independent from * any other transactions in a different context. * * @returns tSfPolicyUserContextId */ tSfPolicyUserContextId sfPolicyConfigCreate(void) { tSfPolicyUserContext *pTmp = NULL; pTmp = calloc(1, sizeof(tSfPolicyUserContext)); return pTmp; } /**Delete a user policy data context. * @param pContext */ void sfPolicyConfigDelete( tSfPolicyUserContextId pContext ) { if (pContext == NULL) return; if (pContext->userConfig != NULL) free(pContext->userConfig); free(pContext); } /**Store a pointer to user data. * @param pContext * @param policyId is 0 based. * @param config - pointer to user configuration. */ int sfPolicyUserDataSet ( tSfPolicyUserContextId pContext, tSfPolicyId policyId, void *config ) { void **ppTmp; if (policyId >= pContext->numAllocatedPolicies) { //expand the array ppTmp = (void **)calloc(policyId+POLICY_ALLOCATION_CHUNK, sizeof(void *)); if (!(ppTmp)) { return -1; } if (pContext->numAllocatedPolicies) { memcpy(ppTmp, pContext->userConfig, sizeof(void*)*(pContext->numAllocatedPolicies)); free(pContext->userConfig); } pContext->userConfig = ppTmp; pContext->numAllocatedPolicies = policyId + POLICY_ALLOCATION_CHUNK; } if (pContext->userConfig[policyId]) { //dont overwrite existing configuration return -1; } pContext->userConfig[policyId] = config; pContext->numActivePolicies++; return 0; } /**user is responsible for freeing any memory. */ void * sfPolicyUserDataClear ( tSfPolicyUserContextId pContext, tSfPolicyId policyId ) { void *pTmp = NULL; if (policyId < pContext->numAllocatedPolicies) { pTmp = pContext->userConfig[policyId]; pContext->userConfig[policyId] = NULL; pContext->numActivePolicies--; } return pTmp; } int sfPolicyUserDataIterate ( struct _SnortConfig *sc, tSfPolicyUserContextId pContext, int (*callback)(struct _SnortConfig *sc, tSfPolicyUserContextId pContext, tSfPolicyId policyId, void* config) ) { tSfPolicyId policyId; int ret = 0; //must not use numActivePolicies because the callback may delete a policy for (policyId = 0; policyId < pContext->numAllocatedPolicies; policyId++) { if (pContext->userConfig[policyId]) { ret = callback(sc, pContext, policyId, pContext->userConfig[policyId]); if (ret != 0) break; } } return ret; } int sfPolicyUserDataFreeIterate ( tSfPolicyUserContextId pContext, int (*callback)(tSfPolicyUserContextId pContext, tSfPolicyId policyId, void* config) ) { tSfPolicyId policyId; int ret = 0; //must not use numActivePolicies because the callback may delete a policy for (policyId = 0; policyId < pContext->numAllocatedPolicies; policyId++) { if (pContext->userConfig[policyId]) { ret = callback(pContext, policyId, pContext->userConfig[policyId]); if (ret != 0) break; } } return ret; } /** @} */ // snort-2.9.15.1/src/sfutil/sfPolicyUserData.h0000644000175200017520000001071413571422607015542 00000000000000/**************************************************************************** * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2008-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #ifndef _SF_POLICY_USER_DATA_H_ #define _SF_POLICY_USER_DATA_H_ #include "sf_ip.h" #include "ipv6_port.h" #include "sfPolicy.h" /*SharedObjectAddStarts #include "sf_dynamic_preprocessor.h" SharedObjectAddEnds */ typedef struct { /**policy id of configuration file or packet being processed. */ tSfPolicyId currentPolicyId; /**Number of policies currently allocated. */ unsigned int numAllocatedPolicies; /**Number of policies active. Since we use an array of policy pointers, * number of allocated policies may be more than active policies. */ unsigned int numActivePolicies; /**user configuration for a policy. This is a pointer to an array of pointers * to user configuration. */ void **userConfig; } tSfPolicyUserContext; typedef tSfPolicyUserContext * tSfPolicyUserContextId; //SharedObjectDeleteBegins // index for default nap & ips polices is 0 // so single function to return the default idx static inline tSfPolicyId getDefaultPolicy(void) { return SF_DEFAULT_POLICY_ID; } //SharedObjectDeleteEnds tSfPolicyUserContextId sfPolicyConfigCreate( void ); void sfPolicyConfigDelete( tSfPolicyUserContextId pContext ); //Functions for setting, getting and clearing policy ids static inline void sfPolicyUserPolicySet ( tSfPolicyUserContextId pContext, tSfPolicyId policyId ) { pContext->currentPolicyId = policyId; } static inline tSfPolicyId sfPolicyUserPolicyGet ( tSfPolicyUserContextId pContext ) { return pContext->currentPolicyId; } static inline unsigned int sfPolicyUserPolicyGetActive ( tSfPolicyUserContextId pContext ) { return (pContext->numActivePolicies); } //Functions for setting, getting and clearing user data specific to policies. int sfPolicyUserDataSet ( tSfPolicyUserContextId pContext, tSfPolicyId policyId, void *config ); static inline void * sfPolicyUserDataGet ( tSfPolicyUserContextId pContext, tSfPolicyId policyId ) { if (pContext && policyId < pContext->numAllocatedPolicies) return pContext->userConfig[policyId]; return NULL; } static inline int sfPolicyUserDataSetDefault ( tSfPolicyUserContextId pContext, void *config ) { return sfPolicyUserDataSet (pContext, getDefaultPolicy(), config); } static inline void * sfPolicyUserDataGetDefault ( tSfPolicyUserContextId pContext ) { return sfPolicyUserDataGet (pContext, getDefaultPolicy()); } static inline int sfPolicyUserDataSetCurrent ( tSfPolicyUserContextId pContext, void *config ) { return sfPolicyUserDataSet (pContext, pContext->currentPolicyId, config); } static inline void * sfPolicyUserDataGetCurrent ( tSfPolicyUserContextId pContext ) { return sfPolicyUserDataGet (pContext, pContext->currentPolicyId); } void *sfPolicyUserDataClear( tSfPolicyUserContextId pContext, tSfPolicyId policyId ); int sfPolicyUserDataIterate( struct _SnortConfig *sc, tSfPolicyUserContextId pContext, int ( *callback )( struct _SnortConfig *sc, tSfPolicyUserContextId pContext, tSfPolicyId policyId, void *config ) ); int sfPolicyUserDataFreeIterate( tSfPolicyUserContextId pContext, int ( *callback )( tSfPolicyUserContextId pContext, tSfPolicyId policyId, void *config ) ); #endif snort-2.9.15.1/src/sfutil/sfPolicyData.h0000644000175200017520000000523013571422607014700 00000000000000/**************************************************************************** * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2008-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #ifndef _SF_POLICY_DATA_H_ #define _SF_POLICY_DATA_H_ #include "generators.h" #include "sfPolicy.h" extern tSfPolicyId napRuntimePolicyId; extern tSfPolicyId ipsRuntimePolicyId; extern uint8_t iprep_current_update_counter; static inline tSfPolicyId getNapRuntimePolicy(void) { return napRuntimePolicyId; } static inline tSfPolicyId getIpsRuntimePolicy(void) { return ipsRuntimePolicyId; } static inline tSfPolicyId getApplicableRuntimePolicy(uint32_t gid) { if (gid == GENERATOR_INTERNAL) return getNapRuntimePolicy(); else return getIpsRuntimePolicy(); } static inline void setNapRuntimePolicy(tSfPolicyId id) { napRuntimePolicyId = id; } static inline void setIpsRuntimePolicy(tSfPolicyId id) { ipsRuntimePolicyId = id; } static inline int isNapRuntimePolicyDefault(void) { return ( napRuntimePolicyId == SF_DEFAULT_POLICY_ID ); } static inline int isIpsRuntimePolicyDefault(void) { return ( ipsRuntimePolicyId == SF_DEFAULT_POLICY_ID ); } static inline tSfPolicyId getParserPolicy(SnortConfig *sc) { return sc ? sc->parserPolicyId : snort_conf->parserPolicyId; } static inline void setParserPolicy(SnortConfig *sc, tSfPolicyId id) { if (sc) sc->parserPolicyId = id; else snort_conf->parserPolicyId = id; } static inline int isParserPolicyDefault(SnortConfig *sc) { return ( ( sc ? sc->parserPolicyId : snort_conf->parserPolicyId ) == SF_DEFAULT_POLICY_ID ); } static inline void setIPRepUpdateCount(uint8_t count) { iprep_current_update_counter = count; } static inline uint8_t getIPRepUpdateCount(void) { return iprep_current_update_counter; } #endif snort-2.9.15.1/src/sfutil/sfActionQueue.c0000644000175200017520000000656113571422607015074 00000000000000/**************************************************************************** * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2008-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "stdlib.h" #include "stdio.h" #include "string.h" #include "util.h" #include "sfActionQueue.h" #include "mempool.h" #include "active.h" #include "pkt_tracer.h" tSfActionQueueId sfActionQueueInit( int queueLength ) { tSfActionQueue *queue = SnortAlloc(sizeof(tSfActionQueue)); if (queue) { if (mempool_init(&queue->mempool, queueLength, sizeof(tSfActionNode)) != 0) { FatalError("%s(%d) Could not initialize action queue memory pool.\n", __FILE__, __LINE__); } } return queue; } int sfActionQueueAdd( tSfActionQueueId actionQ, void (*callback)(void *), void *data ) { MemBucket *bucket = mempool_alloc(&actionQ->mempool); if (bucket != NULL) { tSfActionNode *node = bucket->data; node->callback = callback; node->data = data; //Using used_list in mempool for tracking allocated MemBucket return 0; } return -1; } void sfActionQueueExecAll( tSfActionQueueId actionQ ) { //drain while (mempool_numUsedBuckets(&actionQ->mempool)) { sfActionQueueExec(actionQ); } if (Active_PacketWasDropped() || Active_PacketWouldBeDropped()) { if (pkt_trace_enabled) addPktTraceData(VERDICT_REASON_SNORT, snprintf(trace_line, MAX_TRACE_LINE, "Snort: processed decoder alerts or actions queue, %s\n", getPktTraceActMsg())); else addPktTraceData(VERDICT_REASON_SNORT, 0); } } void sfActionQueueExec( tSfActionQueueId actionQ ) { MemBucket *firstUsedBucket = mempool_oldestUsedBucket(&actionQ->mempool); if (firstUsedBucket) { tSfActionNode *node = (tSfActionNode *)firstUsedBucket->data; (node->callback)(node->data); mempool_free(&actionQ->mempool, firstUsedBucket); } } /**Destroys action queue. All memory allocated by the actionQueue module is * freed. Since the queued actions are not executed, any memory freed in the action * will be lost. User should do a execAll if there is a potential memory leak * or the actions must be completed. */ void sfActionQueueDestroy( tSfActionQueueId actionQ ) { mempool_destroy(&actionQ->mempool); free(actionQ); } snort-2.9.15.1/src/sfutil/sfActionQueue.h0000644000175200017520000000331413571422607015072 00000000000000/**************************************************************************** * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2008-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #ifndef _SF_ACTION_QUEUE_ #define _SF_ACTION_QUEUE_ #include "mempool.h" typedef struct { MemPool mempool; } tSfActionQueue; typedef tSfActionQueue* tSfActionQueueId; typedef struct _sfActionNode { void (*callback)(void *); void *data; } tSfActionNode; tSfActionQueueId sfActionQueueInit( int queueLength ); int sfActionQueueAdd( tSfActionQueueId actionQ, void (*callback)(void *), void *data ); void sfActionQueueExecAll( tSfActionQueueId actionQ ); void sfActionQueueExec( tSfActionQueueId actionQ ); void sfActionQueueDestroy( tSfActionQueueId actionQ ); #endif snort-2.9.15.1/src/sfutil/sfrf.c0000644000175200017520000006204413571422607013257 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2009-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* @file sfrf.c * @brief rate filter implementation for Snort * @ingroup rate_filter * @author Dilbagh Chahal */ /* @ingroup rate_filter * @{ */ #include #include #include #ifndef WIN32 #include #include #endif /* !WIN32 */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "snort.h" #include "parser/IpAddrSet.h" #include "generators.h" #include "rules.h" #include "treenodes.h" #include "sfrf.h" #include "util.h" #include "sfPolicyData.h" #include "sfPolicyUserData.h" #include "session_common.h" // Number of hash rows for gid 1 (rules) #define SFRF_GEN_ID_1_ROWS 4096 // Number of hash rows for non-zero gid #define SFRF_GEN_ID_ROWS 512 // maximum number of norevert rate_filter configuration allowed. #define SFRF_NO_REVERT_LIMIT 1000 // private data ... /* Key to find tracking nodes in trackingHash. */ typedef struct { ///policy identifier. tSfPolicyId policyId; /* Internally generated threshold identity for a configured threshold. */ int tid; /* Stores either source or destination IP address on a matching packet, depending on * whether dos threshold is tracking by source or destination IP address. For tracking * by rule, it is cleared out (all 0s). */ struct in6_addr ip; } tSFRFTrackingNodeKey ; /* Tracking node for rate_filter. One node is created on fly, in tracking * hash for each threshold configure (identified by Tid) and source or * destination IP address. For rule based tracking, IP is cleared in the * created node. Nodes are deleted when hash performs ANR on hash. */ typedef struct { // automatically initialized to FS_NEW when allocated FilterState filterState; #ifdef SFRF_OVER_RATE int overRate; // 0 = count not exceeded in prior seconds time_t tlast; // time of most recent event #endif /* number of packets counted against a specific IP address or threshold. */ unsigned count; /* time when this sampling period started. */ time_t tstart; /* time when new action was activated due to rate limit exceeding. */ time_t revertTime; } tSFRFTrackingNode; SFXHASH *rf_hash = NULL; static int internal_syn_rate_limit_act; // private methods ... static int _checkThreshold( tSFRFConfigNode*, tSFRFTrackingNode*, time_t curTime ); static int _checkSamplingPeriod( tSFRFConfigNode*, tSFRFTrackingNode*, time_t curTime ); static tSFRFTrackingNode *_getSFRFTrackingNode( sfaddr_t*, unsigned tid, time_t curTime ); static void _updateDependentThresholds( RateFilterConfig *config, unsigned gid, unsigned sid, sfaddr_t* sip, sfaddr_t* dip, time_t curTime ); // public methods ... /* Create a new threshold global context * * Create a threshold table, initialize the threshold system, and optionally * limit it's memory usage. * * @param nbytes maximum memory to use for thresholding objects, in bytes. * @return pointer to newly created tSFRFContext */ #define SFRF_BYTES (sizeof(tSFRFTrackingNodeKey) + sizeof(tSFRFTrackingNode)) static void SFRF_New( unsigned nbytes ) { int nrows; /* Calc max ip nodes for this memory */ if ( nbytes < SFRF_BYTES ) { nbytes = SFRF_BYTES; } nrows = nbytes / (SFRF_BYTES); /* Create global hash table for all of the IP Nodes */ rf_hash = sfxhash_new( nrows, /* try one node per row - for speed */ sizeof(tSFRFTrackingNodeKey), /* keys size */ sizeof(tSFRFTrackingNode), /* data size */ nbytes, /* memcap **/ 1, /* ANR flag - true ?- Automatic Node Recovery=ANR */ 0, /* ANR callback - none */ 0, /* user freemem callback - none */ 1) ; /* Recycle nodes ?*/ } void SFRF_Delete (void) { if ( !rf_hash ) return; sfxhash_delete(rf_hash); rf_hash = NULL; } void SFRF_Flush (void) { if ( rf_hash ) sfxhash_make_empty(rf_hash); } static void SFRF_ConfigNodeFree(void *item) { tSFRFConfigNode *node = (tSFRFConfigNode *)item; if (node == NULL) return; if (node->applyTo != NULL) { IpAddrSetDestroy(node->applyTo); } free(node); } /* free tSFRFSidNode and related buffers. * * @param item - pointer to tSFRFSidNode to be freed. * @returns void */ static void SFRF_SidNodeFree(void* item) { tSFRFSidNode* pSidnode = (tSFRFSidNode*)item; sflist_free_all(pSidnode->configNodeList, SFRF_ConfigNodeFree); free(pSidnode); } /* Add a permanent threshold object to the threshold table. Multiple * objects may be defined for each gid and sid pair. Internally * a unique threshold id is generated for each pair. * * Threshold objects track the number of events seen during the time * interval specified by seconds. Depending on the type of threshold * object and the count value, the thresholding object determines if * the current event should be logged or dropped. * * @param pContext Threshold object from SFRF_ContextNew() * @param cfgNode Permanent Thresholding Object * * @return @retval 0 successfully added the thresholding object, !0 otherwise */ int SFRF_ConfigAdd(SnortConfig *sc, RateFilterConfig *rf_config, tSFRFConfigNode *cfgNode) { SFGHASH* genHash; int nrows; int hstatus; tSFRFSidNode* pSidNode; tSFRFConfigNode* pNewConfigNode; tSFRFGenHashKey key = {0,0}; tSfPolicyId policy_id = getParserPolicy(sc); // Auto init - memcap must be set 1st, which is not really a problem if ( rf_hash == NULL ) { SFRF_New(rf_config->memcap); if ( rf_hash == NULL ) return -1; } if ((rf_config == NULL) || (cfgNode == NULL)) return -1; if ( (cfgNode->sid == 0 ) || (cfgNode->gid == 0) ) return -1; if ( cfgNode->gid >= SFRF_MAX_GENID ) return -1; if ( cfgNode->count < 1 ) return -1; if ( cfgNode->timeout == 0 ) { if ( rf_config->noRevertCount >= SFRF_NO_REVERT_LIMIT ) return -1; rf_config->noRevertCount++; } /* Check for an existing 'gid' entry, if none found then create one. */ /* Get the hash table for this gid */ genHash = rf_config->genHash[cfgNode->gid]; if ( !genHash ) { if ( cfgNode->gid == 1 )/* patmatch rules gid, many rules */ { nrows= SFRF_GEN_ID_1_ROWS; } else /* other gid's */ { nrows= SFRF_GEN_ID_ROWS; } /* Create the hash table for this gid */ genHash = sfghash_new( nrows, sizeof(tSFRFGenHashKey), 0, SFRF_SidNodeFree ); if ( !genHash ) return -2; rf_config->genHash[cfgNode->gid] = genHash; } key.sid = cfgNode->sid; key.policyId = policy_id; /* Check if sid is already in the table - if not allocate and add it */ pSidNode = (tSFRFSidNode*)sfghash_find( genHash, (void*)&key ); if ( !pSidNode ) { /* Create the pSidNode hash node data */ pSidNode = (tSFRFSidNode*)calloc(1,sizeof(tSFRFSidNode)); if ( !pSidNode ) return -3; pSidNode->gid = cfgNode->gid; pSidNode->sid = cfgNode->sid; pSidNode->configNodeList = sflist_new(); if ( !pSidNode->configNodeList ) { free(pSidNode); return -4; } /* Add the pSidNode to the hash table */ hstatus = sfghash_add( genHash, (void*)&key, pSidNode ); if ( hstatus ) { sflist_free(pSidNode->configNodeList); free(pSidNode); return -5; } } /* Create a tSFRFConfigNode for this tSFRFSidNode (Object) */ pNewConfigNode = (tSFRFConfigNode*)calloc(1,sizeof(tSFRFConfigNode)); if ( !pNewConfigNode ) { sflist_free(pSidNode->configNodeList); free(pSidNode); return -6; } *pNewConfigNode = *cfgNode; rf_config->count++; /* Copy the node parameters, with unique internally assigned tid */ pNewConfigNode->tid = rf_config->count; if ( pNewConfigNode->tid == 0 ) { // tid overflow. rare but possible free(pNewConfigNode); sflist_free(pSidNode->configNodeList); free(pSidNode); return -6; } #ifdef SFRF_DEBUG printf("--%d-%d-%d: Threshold node added to tail of list\n", pNewConfigNode->tid, pNewConfigNode->gid, pNewConfigNode->sid); fflush(stdout); #endif sflist_add_tail(pSidNode->configNodeList,pNewConfigNode); return 0; } #ifdef SFRF_DEBUG static char* get_netip(sfaddr_t* ip) { return sfip_ntoa(ip); } #endif // SFRF_DEBUG /* * * Find/Test/Add an event against a single threshold object. * Events without thresholding objects are automatically loggable. * * @param pContext Threshold table pointer * @param cfgNode Permanent Thresholding Object * @param ip Event/Packet Src IP address- should be host ordered for comparison * @param curTime Current Event/Packet time in seconds * @param op operation of type SFRF_COUNT_OPERATION * * @return integer * @retval !0 : rate limit is reached. Return value contains new action. * @retval 0 : Otherwise */ static int SFRF_TestObject( tSFRFConfigNode* cfgNode, sfaddr_t* ip, time_t curTime, SFRF_COUNT_OPERATION op ) { tSFRFTrackingNode* dynNode; int retValue = -1; dynNode = _getSFRFTrackingNode(ip, cfgNode->tid, curTime); if ( dynNode == NULL ) return retValue; if ( _checkSamplingPeriod(cfgNode, dynNode, curTime) != 0 ) { #ifdef SFRF_DEBUG printf("...Sampling period reset\n"); fflush(stdout); #endif } switch (op) { case SFRF_COUNT_INCREMENT: if ( (dynNode->count+1) != 0 ) { dynNode->count++; } break; case SFRF_COUNT_DECREMENT: if ( cfgNode->seconds == 0 ) { // count can be decremented only for total count, and not for rate if ( dynNode->count != 0 ) { dynNode->count--; } } break; case SFRF_COUNT_RESET: dynNode->count = 0; break; default: break; } retValue = _checkThreshold(cfgNode, dynNode, curTime); // we drop after the session count has been incremented // but the decrement will never come so we "fix" it here // if the count were not incremented in such cases, the // threshold would never be exceeded. if ( !cfgNode->seconds && dynNode->count > cfgNode->count ) if ( cfgNode->newAction == RULE_TYPE__DROP ) dynNode->count--; #ifdef SFRF_DEBUG printf("--SFRF_DEBUG: %d-%d-%d: %d Packet IP %s, op: %d, count %d, action %d\n", cfgNode->tid, cfgNode->gid, cfgNode->sid, (unsigned) curTime, get_netip(ip), op, dynNode->count, retValue); fflush(stdout); #endif return retValue; } static inline int SFRF_AppliesTo(tSFRFConfigNode* pCfg, sfaddr_t* ip) { return ( !pCfg->applyTo || IpAddrSetContains(pCfg->applyTo, ip) ); } /* Test a an event against the threshold database. Events without thresholding * objects are automatically loggable. * * @param pContext Threshold table pointer * @param gid Generator Id from the event * @param sid Signature Id from the event * @param sip Event/Packet Src IP address * @param dip Event/Packet Dst IP address * @param curTime Current Event/Packet time * @param op operation of type SFRF_COUNT_OPERATION * * @return -1 if packet is within dos_threshold and therefore action is allowed. * >=0 if packet violates a dos_threshold and therefore new_action should * replace rule action. new_action value is returned. */ int SFRF_TestThreshold( RateFilterConfig *config, unsigned gid, unsigned sid, sfaddr_t* sip, sfaddr_t* dip, time_t curTime, SFRF_COUNT_OPERATION op ) { SFGHASH *genHash; tSFRFSidNode* pSidNode; tSFRFConfigNode* cfgNode; int newStatus = -1; int status = -1; tSFRFGenHashKey key; #ifdef SFRF_DEBUG printf("--%d-%d-%d: %s() entering\n", 0, gid, sid, __func__); fflush(stdout); #endif if ( gid >= SFRF_MAX_GENID ) return status; /* bogus gid */ if(EventIsInternal(gid) && sid == INTERNAL_EVENT_SYN_RECEIVED ) { if( internal_syn_rate_limit_act >= -1 ) return internal_syn_rate_limit_act; } // Some events (like 'TCP connection closed' raised by preprocessor may // not have any configured threshold but may impact thresholds for other // events (like 'TCP connection opened' _updateDependentThresholds(config, gid, sid, sip, dip, curTime); /* * Get the hash table for this gid */ genHash = config->genHash [ gid ]; if ( !genHash ) { #ifdef SFRF_DEBUG printf("--SFRF_DEBUG: %d-%d-%d: no hash table entry for gid\n", 0, gid, sid); fflush(stdout); #endif return status; } /* * Check for any Permanent sid objects for this gid */ key.sid = sid; key.policyId = getApplicableRuntimePolicy(gid); pSidNode = (tSFRFSidNode*)sfghash_find( genHash, (void*)&key ); if ( !pSidNode ) { #ifdef SFRF_DEBUG printf("--SFRF_DEBUG: %d-%d-%d: no DOS THD object\n", 0, gid, sid); fflush(stdout); #endif return status; } /* No List of Threshold objects - bail and log it */ if ( !pSidNode->configNodeList ) { #ifdef SFRF_DEBUG printf("--SFRF_DEBUG: %d-%d-%d: No user configuration\n", 0, gid, sid); fflush(stdout); #endif return status; } /* For each permanent thresholding object, test/add/update the config object */ /* We maintain a list of thd objects for each gid+sid */ /* each object has it's own unique thd_id */ for ( cfgNode = (tSFRFConfigNode*)sflist_first(pSidNode->configNodeList); cfgNode != 0; cfgNode = (tSFRFConfigNode*)sflist_next(pSidNode->configNodeList) ) { switch (cfgNode->tracking) { case SFRF_TRACK_BY_SRC: if ( SFRF_AppliesTo(cfgNode, sip) ) { newStatus = SFRF_TestObject(cfgNode, sip, curTime, op); } break; case SFRF_TRACK_BY_DST: if ( SFRF_AppliesTo(cfgNode, dip) ) { newStatus = SFRF_TestObject(cfgNode, dip, curTime, op); } break; case SFRF_TRACK_BY_RULE: { sfaddr_t cleared; IP_CLEAR(cleared); newStatus = SFRF_TestObject(cfgNode, IP_ARG(cleared), curTime, op); } break; default: // error case break; } #ifdef SFRF_DEBUG printf("--SFRF_DEBUG: %d-%d-%d: Time %d, rate limit blocked: %d\n", cfgNode->tid, gid, sid, (unsigned)curTime, newStatus); fflush(stdout); #endif // rate limit is reached if ( newStatus >= 0 && (status == -1) ) { status = newStatus; } } // rate limit not reached return status; } /* A function to print the thresholding objects to stdout. * * @param pContext pointer to global threshold context * @return */ void SFRF_ShowObjects(RateFilterConfig *config) { SFGHASH* genHash; tSFRFSidNode* pSidnode; tSFRFConfigNode* cfgNode; int gid; SFGHASH_NODE* sidHashNode; for ( gid=0;gid < SFRF_MAX_GENID ; gid++ ) { genHash = config->genHash [ gid ]; if ( !genHash ) { continue; } printf("...GEN_ID = %u\n",gid); for ( sidHashNode = sfghash_findfirst( genHash ); sidHashNode != 0; sidHashNode = sfghash_findnext( genHash ) ) { /* Check for any Permanent sid objects for this gid */ pSidnode = (tSFRFSidNode*)sidHashNode->data; printf(".....GEN_ID = %u, SIG_ID = %u, PolicyId = %u\n",gid, pSidnode->sid, pSidnode->policyId); /* For each permanent thresholding object, test/add/update the thd object */ /* We maintain a list of thd objects for each gid+sid */ /* each object has it's own unique thd_id */ for ( cfgNode = (tSFRFConfigNode*)sflist_first(pSidnode->configNodeList); cfgNode != 0; cfgNode = (tSFRFConfigNode*)sflist_next(pSidnode->configNodeList) ) { printf(".........SFRF_ID =%d\n",cfgNode->tid ); printf(".........tracking =%d\n",cfgNode->tracking); printf(".........count =%u\n",cfgNode->count); printf(".........seconds =%u\n",cfgNode->seconds); } } } } /* Set sampling period rate limit * * @param cfgNode threshold configuration node * @param dynNode tracking node for a configured node * @param curTime for packet timestamp * * @returns 0 if continuing with old sampling period. * 1 if new sampling period is started. */ static int _checkSamplingPeriod( tSFRFConfigNode* cfgNode, tSFRFTrackingNode* dynNode, time_t curTime ) { unsigned dt; if ( cfgNode->seconds ) { dt = (unsigned)(curTime - dynNode->tstart); if ( dt >= cfgNode->seconds ) { // observation period is over, start a new one dynNode->tstart = curTime; #ifdef SFRF_OVER_RATE dt = (unsigned)(curTime - dynNode->tlast); if ( dt > cfgNode->seconds ) dynNode->overRate = 0; else dynNode->overRate = (dynNode->count > cfgNode->count); dynNode->tlast = curTime; #endif dynNode->count = 0; return 1; } } #ifdef SFRF_OVER_RATE else { dynNode->overRate = (dynNode->count > cfgNode->count); } dynNode->tlast = curTime; #endif return 0; } /* Checks if rate limit is reached for a configured threshold. * * DOS Threshold monitoring is done is discrete time intervals specified by * 'cfgNode->seconds'. Once threshold action is activated, it stays active * for the revert timeout. Counters and seconds is maintained current at all * times. This may cause threshold action to be reactivated immediately if counter * is above threshold. * Threshold is tracked using a hash with ANR. This could cause some tracking nodes * to disappear when memory is low. Node deletion and subsequent creation will cause * rate limiting to start afresh for a specific stream. * * @param cfgNode threshold configuration node * @param dynNode tracking node for a configured node * @param curTime for packet timestamp * * @returns 0 if threshold is not reached * 1 otherwise */ static int _checkThreshold( tSFRFConfigNode* cfgNode, tSFRFTrackingNode* dynNode, time_t curTime ) { /* Once newAction is activated, it stays active for the revert timeout, unless ANR * causes the node itself to disappear. * Also note that we want to maintain the counters and rates update so that we reblock * offending traffic again quickly if it has not subsided. */ if ( dynNode->filterState == FS_ON ) { if ( (cfgNode->timeout != 0 ) && ((unsigned)(curTime - dynNode->revertTime) >= cfgNode->timeout)) { #ifdef SFRF_OVER_RATE if ( dynNode->count > cfgNode->count || dynNode->overRate ) { #ifdef SFRF_DEBUG printf("...dos action continued, count %u\n", dynnode->count); fflush(stdout); #endif dynNode->revertTime = curTime; return cfgNode->newAction; } #endif #ifdef SFRF_DEBUG printf("...dos action stopped, count %u\n", dynnode->count); fflush(stdout); #endif dynNode->filterState = FS_OFF; } else { #ifdef SFRF_DEBUG printf("...DOS action continued, count %u\n", dynNode->count); fflush(stdout); #endif return cfgNode->newAction; } } #ifdef SFRF_OVER_RATE if ( dynNode->count <= cfgNode->count && !dynNode->overRate ) #else if ( dynNode->count <= cfgNode->count ) #endif { // rate limit not reached. #ifdef SFRF_DEBUG printf("...DOS action nop, count %u\n", dynNode->count); fflush(stdout); #endif return -1; } // rate limit reached. dynNode->revertTime = curTime; dynNode->filterState = FS_ON; #ifdef SFRF_OVER_RATE dynNode->overRate = 1; #endif #ifdef SFRF_DEBUG printf("...DOS action started, count %u\n", dynNode->count); fflush(stdout); #endif return RULE_TYPE__MAX + cfgNode->newAction; } static void _updateDependentThresholds( RateFilterConfig *config, unsigned gid, unsigned sid, sfaddr_t* sip, sfaddr_t* dip, time_t curTime ) { if ( gid == GENERATOR_INTERNAL && sid == INTERNAL_EVENT_SESSION_DEL ) { // decrementing counters - this results in the following sequence: // 1. sfdos_thd_test_threshold(gid internal, sid DEL) // 2. _updateDependentThresholds(gid internal, sid DEL) // 3. | sfdos_thd_test_threshold(gid internal, sid ADD) // 4. | _updateDependentThresholds(gid internal, sid ADD) // 5. continue with regularly scheduled programming (ie step 1) SFRF_TestThreshold(config, gid, INTERNAL_EVENT_SESSION_ADD, sip, dip, curTime, SFRF_COUNT_DECREMENT); return; } } static tSFRFTrackingNode* _getSFRFTrackingNode( sfaddr_t* ip, unsigned tid, time_t curTime ) { tSFRFTrackingNode* dynNode = NULL; tSFRFTrackingNodeKey key; SFXHASH_NODE * hnode = NULL; /* Setup key */ sfaddr_copy_to_raw(&key.ip, ip); key.tid = tid; key.policyId = getNapRuntimePolicy(); // TBD-EDM should this be NAP or IPS? /* * Check for any Permanent sid objects for this gid or add this one ... */ hnode = sfxhash_get_node(rf_hash, (void*)&key); if ( hnode && hnode->data ) { dynNode = (tSFRFTrackingNode*)hnode->data; if ( dynNode->filterState == FS_NEW ) { // first time initialization dynNode->tstart = curTime; #ifdef SFRF_OVER_RATE dynNode->tlast = curTime; #endif dynNode->filterState = FS_OFF; } } return dynNode; } int SFRF_InternalSynRecdEvent(Packet* p) { sfaddr_t* sip = NULL, *dip = NULL; internal_syn_rate_limit_act = -2; if ( IPH_IS_VALID(p) ) { sip = GET_SRC_IP(p); dip = GET_DST_IP(p); getSessionPlugins()->select_session_nap( p, true ); internal_syn_rate_limit_act = SFRF_TestThreshold( snort_conf->rate_filter_config, GENERATOR_INTERNAL, INTERNAL_EVENT_SYN_RECEIVED, sip, dip, p->pkth->ts.tv_sec, SFRF_COUNT_INCREMENT); if(internal_syn_rate_limit_act > 0) { SnortEventqAdd( GENERATOR_INTERNAL, /* GID */ INTERNAL_EVENT_SYN_RECEIVED, /* SID */ 1, /* rev */ 0, /* class */ 3, /* priority */ "", /* event msg*/ NULL /* rule info ptr */ ); pc.syn_rate_limit_events++; } if( ScNapInlineMode() && ( DAQ_GetInterfaceMode(p->pkth) == DAQ_MODE_INLINE )) { int action = internal_syn_rate_limit_act; if (internal_syn_rate_limit_act >= RULE_TYPE__MAX) action = internal_syn_rate_limit_act - RULE_TYPE__MAX; if( (action == RULE_TYPE__DROP) || (action == RULE_TYPE__SDROP) || (action == RULE_TYPE__REJECT) ) { p->error_flags |= PKT_ERR_SYN_RL_DROP; } } } return 1; } /*@}*/ snort-2.9.15.1/src/sfutil/sfrf.h0000644000175200017520000001112313571422607013254 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2009-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #ifndef _SFRF_H_ #define _SFRF_H_ /* @file sfrf.h * @brief rate filter implementation for Snort * @ingroup rate_filter * @author Dilbagh Chahal */ /* @defgroup rate_filter sourcefire.rate_filter * Implements rate_filter feature for snort * @{ */ #include "ipv6_port.h" #include "parser/IpAddrSet.h" #include "sflsq.h" #include "sfghash.h" #include "sfxhash.h" #include "sfPolicy.h" // define to use over rate threshold #define SFRF_OVER_RATE // used for the dimensions of the gid lookup array. #define SFRF_MAX_GENID 8129 // rate_filter tracking by src, by dst, or by rule typedef enum { SFRF_TRACK_BY_SRC = 1, SFRF_TRACK_BY_DST, SFRF_TRACK_BY_RULE, SFRF_TRACK_BY_MAX } SFRF_TRACK; /* Type of operation for threshold tracking nodes. */ typedef enum { SFRF_COUNT_NOP, SFRF_COUNT_RESET, SFRF_COUNT_INCREMENT, SFRF_COUNT_DECREMENT, SFRF_COUNT_MAX } SFRF_COUNT_OPERATION; typedef enum { FS_NEW = 0, FS_OFF, FS_ON, FS_MAX } FilterState; /* A threshold configuration object, created for each configured rate_filter. * These are created at initialization, and remain static. */ typedef struct { // Internally generated unique threshold identity int tid; // Generator id from configured threshold unsigned gid; // Signature id from configured threshold unsigned sid; // Signature id from configured threshold tSfPolicyId policyId; // Threshold tracking by src, dst or rule SFRF_TRACK tracking; // Number of rule matching before rate limit is reached. unsigned count; // Duration in seconds for determining rate of rule matching unsigned seconds; // Action that replaces original rule action on reaching threshold RuleType newAction; // Threshold action duration in seconds before reverting to original rule action unsigned timeout; // ip set to restrict rate_filter IpAddrSet* applyTo; } tSFRFConfigNode; /* tSFRFSidNode acts as a container of gid+sid based threshold objects, * this allows multiple threshold objects to be applied to a single * gid+sid pair. This is static data elements, built at initialization. */ typedef struct { // List of threshold configuration nodes of type tSFRFConfigNode tSfPolicyId policyId; // Generator id from configured threshold unsigned gid; // Signature id from configured threshold unsigned sid; // List of threshold configuration nodes of type tSFRFConfigNode SF_LIST* configNodeList; } tSFRFSidNode; typedef struct { ///policy identifier tSfPolicyId policyId; // Signature id from configured threshold unsigned sid; } tSFRFGenHashKey; /* Single global context containing rate_filter configuration nodes. */ typedef struct _RateFilterConfig { /* Array of hash, indexed by gid. Each array element is a hash, which * is keyed on sid/policyId and data is a tSFRFSidNode node. */ SFGHASH* genHash [SFRF_MAX_GENID]; // Number of DOS thresholds added. int count; // count of no revert DOS thresholds unsigned noRevertCount; int memcap; int internal_event_mask; } RateFilterConfig; /* * Prototypes */ void SFRF_Delete(void); void SFRF_Flush(void); struct _SnortConfig; int SFRF_ConfigAdd(struct _SnortConfig *, RateFilterConfig *, tSFRFConfigNode* ); int SFRF_TestThreshold( RateFilterConfig *config, unsigned gid, unsigned sid, sfaddr_t* sip, sfaddr_t* dip, time_t curTime, SFRF_COUNT_OPERATION ); void SFRF_ShowObjects(RateFilterConfig *); int SFRF_InternalSynRecdEvent(Packet* p); /*@}*/ #endif // _SFRF_H_ snort-2.9.15.1/src/sfutil/strvec.c0000644000175200017520000000475313571422607013630 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2009-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "strvec.h" #include "util.h" typedef struct { char** v; unsigned n; } StringVector; void* StringVector_New (void) { StringVector* sv = SnortAlloc(sizeof(*sv)); sv->v = SnortAlloc(sizeof(*sv->v)); sv->n = 0; return sv; } void StringVector_Delete (void* pv) { unsigned i; StringVector* sv = (StringVector*)pv; if ( !sv ) return; for ( i = 0; i < sv->n; i++ ) free(sv->v[i]); free(sv->v); free(sv); } int StringVector_Add (void* pv, const char* s) { StringVector* sv = (StringVector*)pv; char** v; if ( !sv || !s ) return 0; v = realloc(sv->v, (sv->n+2) * sizeof(char*)); if ( !v ) return 0; sv->v = v; sv->v[sv->n++] = SnortStrdup(s); sv->v[sv->n] = NULL; return 1; } char* StringVector_Get (void* pv, unsigned index) { StringVector* sv = (StringVector*)pv; if ( !sv || index >= sv->n ) return NULL; return sv->v[index]; } int StringVector_AddVector (void* pd, void* ps) { unsigned i = 0; const char* s = StringVector_Get(ps, i++); while ( s ) { if ( !StringVector_Add(pd, s) ) return 0; s = StringVector_Get(ps, i++); } return 1; } const char** StringVector_GetVector (void* pv) { StringVector* sv = (StringVector*)pv; if ( !sv ) return NULL; return (const char**)sv->v; } snort-2.9.15.1/src/sfutil/strvec.h0000644000175200017520000000253213571422607013626 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2009-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #ifndef _STRVEC_H_ #define _STRVEC_H_ void* StringVector_New(void); void StringVector_Delete(void*); int StringVector_Add(void*, const char*); char* StringVector_Get(void*, unsigned index); int StringVector_AddVector(void* dst, void* src); const char** StringVector_GetVector(void*); #endif // _STRVEC_H_ snort-2.9.15.1/src/sfutil/sf_email_attach_decode.c0000644000175200017520000004634513571422607016733 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 1998-2013 Sourcefire, Inc. ** ** Author: Bhagyashree Bantwal ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sf_types.h" /*SharedObjectAddStarts #include "sf_dynamic_preprocessor.h" SharedObjectAddEnds */ #include "util.h" #include "sf_email_attach_decode.h" #define UU_DECODE_CHAR(c) (((c) - 0x20) & 0x3f) int sf_qpdecode(char *src, uint32_t slen, char *dst, uint32_t dlen, uint32_t *bytes_read, uint32_t *bytes_copied ) { char ch; if(!src || !slen || !dst || !dlen || !bytes_read || !bytes_copied ) return -1; *bytes_read = 0; *bytes_copied = 0; while( (*bytes_read < slen) && (*bytes_copied < dlen)) { ch = src[*bytes_read]; *bytes_read += 1; if( ch == '=' ) { if( (*bytes_read < slen)) { if(src[*bytes_read] == '\n') { *bytes_read += 1; continue; } else if( *bytes_read < (slen - 1) ) { char ch1 = src[*bytes_read]; char ch2 = src[*bytes_read + 1]; if( ch1 == '\r' && ch2 == '\n') { *bytes_read += 2; continue; } if (isxdigit((int)ch1) && isxdigit((int)ch2)) { char hexBuf[3]; char *eptr; hexBuf[0] = ch1; hexBuf[1] = ch2; hexBuf[2] = '\0'; dst[*bytes_copied]= (char)strtoul(hexBuf, &eptr, 16); if((*eptr != '\0')) { return -1; } *bytes_read += 2; *bytes_copied +=1; continue; } dst[*bytes_copied] = ch; *bytes_copied +=1; continue; } else { *bytes_read -= 1; return 0; } } else { *bytes_read -= 1; return 0; } } else if (isprint(ch) || isblank(ch) || ch == '\r' || ch == '\n' ) { dst[*bytes_copied] = ch; *bytes_copied +=1; } } return 0; } int sf_uudecode(uint8_t *src, uint32_t slen, uint8_t *dst, uint32_t dlen, uint32_t *bytes_read, uint32_t *bytes_copied, uint8_t *begin_found, uint8_t *end_found, uint8_t *file_name, uint32_t *fname_len, bool fname_present_already) { uint8_t *sod; int sol = 1, length = 0; uint8_t *ptr, *end, *dptr, *dend, *tptr = NULL; uint8_t *filename = NULL, *space = NULL; uint32_t tlen = 0, fname_length = 0; if(!src || !slen || !dst || !dlen || !bytes_read || !bytes_copied || !begin_found || !end_found ) return -1; ptr = src; end = src + slen; dptr = dst; dend = dst + dlen; /* begin not found. Search for begin */ if( !(*begin_found) ) { if( slen < 5 ) { /* Not enough data to search */ *bytes_read = 0; *bytes_copied = 0; return 0; } else { sod = (uint8_t *)SnortStrnStr((const char *)src, 5 , "begin"); if(sod) { *begin_found = 1; /* If NULL pointers are passed, or file name is alreayd in header * skip the file name parsing */ if ( !fname_present_already && file_name && fname_len ) { /* Initialize file and length */ *fname_len = 0; /* filename for uuencoded is present in mime body as * begin mode filename\r\n , extract the file name after * begin is found */ tptr = (uint8_t *) memchr( (const char *)sod, '\r', (end - sod) ); if ( !tptr ) { /* On some implementation its a just new line char \n */ tptr = (uint8_t *) memchr( (const char *)sod, '\n', (end - sod) ); } if ( tptr ) { tlen = (tptr - sod) ; space = (uint8_t *) memchr ( sod , ' ', tlen ); if ( space ) { ++space; //skip past the space filename = (uint8_t *) memchr ( space , ' ', ( ( sod + tlen) - space ) ); if ( filename ) { ++filename; // skip past the space /*filename now points to the file name */ fname_length = ( sod + tlen ) - (uint8_t *)(filename); if ( fname_length <= MAX_UNICODE_FILE_NAME ) { memcpy ( file_name, (uint8_t *) filename, fname_length ); *fname_len = fname_length; } } } } } /*begin str found. Move to the actual data*/ ptr = (uint8_t *)SnortStrnStr((const char *)(sod), (end - sod), "\n"); if( !ptr ) { *bytes_read = slen; *bytes_copied = 0; return 0; } } else { /*Encoded data for UUencode should start with begin. Error encountered.*/ return -1; } } } while( (ptr < end) && (dptr < dend)) { if(*ptr == '\n') { length = 0; sol = 1; ptr++; continue; } if(sol) { sol = 0; length = UU_DECODE_CHAR(*ptr); if( length <= 0 ) { /* empty line with no encoded characters indicates end of output */ break; } else if( length == 5 ) { if(*ptr == 'e') { *end_found = 1; break; } } /* check if destination buffer is big enough */ if(( dend - dptr) < length) { length = dend - dptr; } length = (length * 4) / 3 ; /*check if src buffer has enough encoded data*/ if( (end - (ptr + 1)) < length) { /*not enough data to decode. We will wait for the next packet*/ break; } ptr++; while( length > 0 ) { *dptr++ = (UU_DECODE_CHAR(ptr[0]) << 2) | (UU_DECODE_CHAR(ptr[1]) >> 4); ptr++; if(--length == 0 ) break; *dptr++ = (UU_DECODE_CHAR(ptr[0]) << 4) | (UU_DECODE_CHAR(ptr[1]) >> 2); ptr++; if (--length == 0) break; *dptr++ = (UU_DECODE_CHAR(ptr[0]) << 6) | (UU_DECODE_CHAR(ptr[1])); ptr += 2; length -= 2; } } else { /* probably padding. skip over it.*/ ptr++; } } if(*end_found) *bytes_read = end - src; else *bytes_read = ptr - src; *bytes_copied = dptr - dst; return 0; } int Base64Decode(const uint8_t *start, const uint8_t *end, Email_DecodeState *ds) { uint32_t encode_avail = 0, decode_avail = 0 ; uint8_t *encode_buf, *decode_buf; uint32_t act_encode_size = 0, act_decode_size = 0; uint32_t prev_bytes = 0; uint32_t i = 0; if (!(ds->b64_state.encode_depth)) { encode_avail = MAX_BUF; decode_avail = MAX_BUF; } else if ((ds->b64_state.encode_depth) < 0) { return DECODE_EXCEEDED; } else { encode_avail = ds->b64_state.encode_depth - ds->b64_state.encode_bytes_read; decode_avail = ds->b64_state.decode_depth - ds->b64_state.decode_bytes_read; } encode_buf = ds->encodeBuf; decode_buf = ds->decodeBuf; /* 1. Stop decoding when we have reached either the decode depth or encode depth. * 2. Stop decoding when we are out of memory */ if(encode_avail ==0 || decode_avail ==0 || (!encode_buf) || (!decode_buf)) { ResetEmailDecodeState(ds); return DECODE_EXCEEDED; } /*The non decoded encoded data in the previous packet is required for successful decoding * in case of base64 data spanned across packets*/ if( ds->prev_encoded_bytes ) { if(ds->prev_encoded_bytes > encode_avail) ds->prev_encoded_bytes = encode_avail; if(ds->prev_encoded_buf) { prev_bytes = ds->prev_encoded_bytes; encode_avail = encode_avail - prev_bytes; while(ds->prev_encoded_bytes) { /* Since this data cannot be more than 3 bytes*/ encode_buf[i] = ds->prev_encoded_buf[i]; i++; ds->prev_encoded_bytes--; } } } if(sf_strip_CRLF(start, (end-start), encode_buf + prev_bytes, encode_avail, &act_encode_size) != 0) { ResetEmailDecodeState(ds); return DECODE_FAIL; } act_encode_size = act_encode_size + prev_bytes; i = (act_encode_size)%4 ; /* Encoded data should be in multiples of 4. Then we need to wait for the remainder encoded data to * successfully decode the base64 data. This happens when base64 data is spanned across packets*/ if(i) { ds->prev_encoded_bytes = i; act_encode_size = act_encode_size - i; ds->prev_encoded_buf = encode_buf + act_encode_size; } if(sf_base64decode(encode_buf, act_encode_size, decode_buf, decode_avail, &act_decode_size) != 0) { ResetEmailDecodeState(ds); return DECODE_FAIL; } else if(!act_decode_size && !encode_avail) { ResetEmailDecodeState(ds); return DECODE_FAIL; } ds->decode_present = 1; ds->decodePtr = decode_buf; ds->decoded_bytes = act_decode_size; ds->b64_state.encode_bytes_read += act_encode_size; ds->b64_state.decode_bytes_read += act_decode_size; return DECODE_SUCCESS; } int QPDecode(const uint8_t *start, const uint8_t *end, Email_DecodeState *ds) { uint32_t encode_avail = 0, decode_avail = 0 ; uint8_t *encode_buf, *decode_buf; uint32_t act_encode_size = 0, act_decode_size = 0, bytes_read = 0; uint32_t prev_bytes = 0; uint32_t i = 0; if (!(ds->qp_state.encode_depth)) { encode_avail = MAX_BUF; decode_avail = MAX_BUF; } else if ((ds->qp_state.encode_depth) < 0) { return DECODE_EXCEEDED; } else { encode_avail = ds->qp_state.encode_depth - ds->qp_state.encode_bytes_read; decode_avail = ds->qp_state.decode_depth - ds->qp_state.decode_bytes_read; } encode_buf = ds->encodeBuf; decode_buf = ds->decodeBuf; /* 1. Stop decoding when we have reached either the decode depth or encode depth. * 2. Stop decoding when we are out of memory */ if(encode_avail ==0 || decode_avail ==0 || (!encode_buf) || (!decode_buf)) { ResetEmailDecodeState(ds); return DECODE_EXCEEDED; } /*The non decoded encoded data in the previous packet is required for successful decoding * in case of base64 data spanned across packets*/ if( ds->prev_encoded_bytes ) { if(ds->prev_encoded_bytes > encode_avail) ds->prev_encoded_bytes = encode_avail; if(ds->prev_encoded_buf) { prev_bytes = ds->prev_encoded_bytes; encode_avail = encode_avail - prev_bytes; while(ds->prev_encoded_bytes) { /* Since this data cannot be more than 3 bytes*/ encode_buf[i] = ds->prev_encoded_buf[i]; i++; ds->prev_encoded_bytes--; } } } if(sf_strip_LWS(start, (end-start), encode_buf + prev_bytes, encode_avail, &act_encode_size) != 0) { ResetEmailDecodeState(ds); return DECODE_FAIL; } act_encode_size = act_encode_size + prev_bytes; if(sf_qpdecode((char *)encode_buf, act_encode_size, (char *)decode_buf, decode_avail, &bytes_read, &act_decode_size) != 0) { ResetEmailDecodeState(ds); return DECODE_FAIL; } else if(!act_decode_size && !encode_avail) { ResetEmailDecodeState(ds); return DECODE_FAIL; } if(bytes_read < act_encode_size) { ds->prev_encoded_bytes = (act_encode_size - bytes_read); ds->prev_encoded_buf = encode_buf + bytes_read; act_encode_size = bytes_read; } ds->decode_present = 1; ds->decodePtr = decode_buf; ds->decoded_bytes = act_decode_size; ds->qp_state.encode_bytes_read += act_encode_size; ds->qp_state.decode_bytes_read += act_decode_size; return DECODE_SUCCESS; } int UUDecode(const uint8_t *start, const uint8_t *end, Email_DecodeState *ds, uint8_t *filename, uint32_t *fname_length, bool fname_present) { uint32_t encode_avail = 0, decode_avail = 0 ; uint8_t *encode_buf, *decode_buf; uint32_t act_encode_size = 0, act_decode_size = 0, bytes_read = 0; uint32_t prev_bytes = 0; uint32_t i = 0; if (!(ds->uu_state.encode_depth)) { encode_avail = MAX_BUF; decode_avail = MAX_BUF; } else if ((ds->uu_state.encode_depth) < 0) { ds->uu_state.begin_found = 0; return DECODE_EXCEEDED; } else { encode_avail = ds->uu_state.encode_depth - ds->uu_state.encode_bytes_read; decode_avail = ds->uu_state.decode_depth - ds->uu_state.decode_bytes_read; } encode_buf = ds->encodeBuf; decode_buf = ds->decodeBuf; /* 1. Stop decoding when we have reached either the decode depth or encode depth. * 2. Stop decoding when we are out of memory */ if(encode_avail ==0 || decode_avail ==0 || (!encode_buf) || (!decode_buf)) { ds->uu_state.begin_found = 0; ResetEmailDecodeState(ds); return DECODE_EXCEEDED; } /*The non decoded encoded data in the previous packet is required for successful decoding * in case of base64 data spanned across packets*/ if( ds->prev_encoded_bytes ) { if(ds->prev_encoded_bytes > encode_avail) ds->prev_encoded_bytes = encode_avail; if(ds->prev_encoded_buf) { prev_bytes = ds->prev_encoded_bytes; encode_avail = encode_avail - prev_bytes; while(ds->prev_encoded_bytes) { /* Since this data cannot be more than 3 bytes*/ encode_buf[i] = ds->prev_encoded_buf[i]; i++; ds->prev_encoded_bytes--; } } } if((uint32_t)(end- start) > encode_avail) act_encode_size = encode_avail; else act_encode_size = end - start; if(encode_avail > 0) { if(SafeMemcpy((encode_buf + prev_bytes), start, act_encode_size, encode_buf, (encode_buf+ encode_avail + prev_bytes)) != SAFEMEM_SUCCESS) { ResetEmailDecodeState(ds); return DECODE_FAIL; } } act_encode_size = act_encode_size + prev_bytes; if(sf_uudecode(encode_buf, act_encode_size, decode_buf, decode_avail, &bytes_read, &act_decode_size, &(ds->uu_state.begin_found), &(ds->uu_state.end_found), filename, fname_length, fname_present ) != 0) { ResetEmailDecodeState(ds); return DECODE_FAIL; } else if(!act_decode_size && !encode_avail) { /* Have insufficient data to decode */ ResetEmailDecodeState(ds); return DECODE_FAIL; } /* Found the end. No more encoded data */ if(ds->uu_state.end_found) { ds->uu_state.end_found = 0; ds->uu_state.begin_found = 0; } if(bytes_read < act_encode_size) { ds->prev_encoded_bytes = (act_encode_size - bytes_read); ds->prev_encoded_buf = encode_buf + bytes_read; act_encode_size = bytes_read; } ds->decode_present = 1; ds->decoded_bytes = act_decode_size; ds->decodePtr = decode_buf; ds->uu_state.encode_bytes_read += act_encode_size; ds->uu_state.decode_bytes_read += act_decode_size; return DECODE_SUCCESS; } int BitEncExtract(const uint8_t *start, const uint8_t *end, Email_DecodeState *ds) { uint32_t bytes_avail = 0; uint32_t act_size = 0; ClearPrevEncodeBuf(ds); if (!(ds->bitenc_state.depth)) { bytes_avail = MAX_BUF; } else if ((ds->bitenc_state.depth) < 0) { return DECODE_EXCEEDED; } else { bytes_avail = ds->bitenc_state.depth - ds->bitenc_state.bytes_read; } /* 1. Stop decoding when we have reached either the decode depth or encode depth. * 2. Stop decoding when we are out of memory */ if(bytes_avail ==0) { ResetEmailDecodeState(ds); return DECODE_EXCEEDED; } if( (uint32_t)(end-start) < bytes_avail ) { act_size = ( end - start); } else { act_size = bytes_avail; } ds->decode_present = 1; ds->decodePtr = (uint8_t *)start; ds->decoded_bytes = act_size; ds->bitenc_state.bytes_read += act_size; return DECODE_SUCCESS; } int EmailDecode(const uint8_t *start, const uint8_t *end, Email_DecodeState *ds, uint8_t *filename, uint32_t *fname_size, bool filename_present) { int iRet = DECODE_FAIL; switch(ds->decode_type) { case DECODE_B64: iRet = Base64Decode(start, end, ds); break; case DECODE_QP: iRet = QPDecode(start, end, ds ); break; case DECODE_UU: iRet = UUDecode(start, end, ds, filename, fname_size, filename_present); break; case DECODE_BITENC: iRet = BitEncExtract(start, end, ds); break; default: break; } return iRet; } snort-2.9.15.1/src/sfutil/sf_email_attach_decode.h0000644000175200017520000001534513571422607016734 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 1998-2013 Sourcefire, Inc. ** ** Writen by Bhagyashree Bantwal ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _SF_EMAIL_ATTACH_DECODE_H_ #define _SF_EMAIL_ATTACH_DECODE_H_ #include "sf_types.h" #include "util_unfold.h" #include "sf_base64decode.h" #include "snort_bounds.h" #include "file_mail_common.h" #include "file_api.h" #define MAX_BUF 65535 #define DECODE_SUCCESS 0 #define DECODE_EXCEEDED 1 /* Decode Complete when we reach the max depths */ #define DECODE_FAIL -1 typedef enum { DECODE_NONE = 0, DECODE_B64, DECODE_QP, DECODE_UU, DECODE_BITENC, DECODE_ALL } DecodeType; typedef struct s_Base64_DecodeState { uint32_t encode_bytes_read; uint32_t decode_bytes_read; int encode_depth; int decode_depth; } Base64_DecodeState; typedef struct s_QP_DecodeState { uint32_t encode_bytes_read; uint32_t decode_bytes_read; int encode_depth; int decode_depth; } QP_DecodeState; typedef struct s_UU_DecodeState { uint32_t encode_bytes_read; uint32_t decode_bytes_read; int encode_depth; int decode_depth; uint8_t begin_found; uint8_t end_found; } UU_DecodeState; typedef struct s_BitEnc_DecodeState { uint32_t bytes_read; int depth; } BitEnc_DecodeState; typedef struct s_Email_DecodeState { DecodeType decode_type; uint8_t decode_present; uint32_t prev_encoded_bytes; unsigned char *prev_encoded_buf; uint32_t decoded_bytes; uint8_t *encodeBuf; uint8_t *decodeBuf; uint8_t *decodePtr; Base64_DecodeState b64_state; QP_DecodeState qp_state; UU_DecodeState uu_state; BitEnc_DecodeState bitenc_state; } Email_DecodeState; typedef struct _MimeStats { uint64_t memcap_exceeded; uint64_t attachments[DECODE_ALL]; uint64_t decoded_bytes[DECODE_ALL]; } MimeStats; // end :: start + length int EmailDecode(const uint8_t *start, const uint8_t *end, Email_DecodeState *, uint8_t *fname, uint32_t *fname_size, bool filename_present); static inline int getCodeDepth(int code_depth, int64_t file_depth) { if (file_depth < 0 ) return code_depth; else if (( file_depth > MAX_BUF) || (!file_depth) ) return 0; else if (file_depth > code_depth) return (int)file_depth; else return code_depth; } static inline void SetEmailDecodeState(Email_DecodeState *ds, void *data, int max_depth, int b64_depth, int qp_depth, int uu_depth, int bitenc_depth, int64_t file_depth) { if ( max_depth & 7 ) { max_depth += (8 - (max_depth & 7)); } ds->decode_type = DECODE_NONE; ds->decode_present = 0; ds->prev_encoded_bytes = 0; ds->prev_encoded_buf = NULL; ds->decoded_bytes = 0; ds->encodeBuf = (uint8_t *)data; ds->decodeBuf = (uint8_t *)data + max_depth; ds->decodePtr = ds->decodeBuf; ds->b64_state.encode_depth = ds->b64_state.decode_depth = getCodeDepth(b64_depth, file_depth); ds->b64_state.encode_bytes_read = ds->b64_state.decode_bytes_read = 0; ds->qp_state.encode_depth = ds->qp_state.decode_depth = getCodeDepth(qp_depth, file_depth); ds->qp_state.encode_bytes_read = ds->qp_state.decode_bytes_read = 0; ds->uu_state.encode_depth = ds->uu_state.decode_depth = getCodeDepth(uu_depth, file_depth); ds->uu_state.encode_bytes_read = ds->uu_state.decode_bytes_read = 0; ds->uu_state.begin_found = 0; ds->uu_state.end_found = 0; ds->bitenc_state.depth = getCodeDepth(bitenc_depth, file_depth); ds->bitenc_state.bytes_read = 0; } static inline void updateMaxDepth(int64_t file_depth, int *max_depth) { if((!file_depth) || (file_depth > MAX_BUF)) { *max_depth = MAX_BUF; } else if (file_depth > (*max_depth)) { *max_depth = (int)file_depth; } } static inline void ClearPrevEncodeBuf(Email_DecodeState *ds) { ds->prev_encoded_bytes = 0; ds->prev_encoded_buf = NULL; } static inline void ResetBytesRead(Email_DecodeState *ds) { ds->uu_state.begin_found = ds->uu_state.end_found = 0; ClearPrevEncodeBuf(ds); ds->b64_state.encode_bytes_read = ds->b64_state.decode_bytes_read = 0; ds->qp_state.encode_bytes_read = ds->qp_state.decode_bytes_read = 0; ds->uu_state.encode_bytes_read = ds->uu_state.decode_bytes_read = 0; ds->bitenc_state.bytes_read = 0; } static inline void ResetDecodedBytes(Email_DecodeState *ds) { ds->decodePtr = NULL; ds->decoded_bytes = 0; ds->decode_present = 0; } static inline void ResetEmailDecodeState(Email_DecodeState *ds) { if ( ds == NULL ) return; ds->uu_state.begin_found = ds->uu_state.end_found = 0; ResetDecodedBytes(ds); ClearPrevEncodeBuf(ds); } static inline void ClearEmailDecodeState(Email_DecodeState *ds) { if(ds == NULL) return; ds->decode_type = DECODE_NONE; ResetEmailDecodeState(ds); } static inline int limitDetection(int depth, int decoded_bytes, int decode_bytes_total) { if (!depth) return decoded_bytes; else if (depth < decode_bytes_total - decoded_bytes) return 0; else if (depth > decode_bytes_total) return decoded_bytes; else return (depth + decoded_bytes - decode_bytes_total); } static inline int getDetectionSize(int b64_depth, int qp_depth, int uu_depth, int bitenc_depth, Email_DecodeState *ds) { int iRet = 0; switch(ds->decode_type) { case DECODE_B64: iRet = limitDetection(b64_depth, ds->decoded_bytes, ds->b64_state.decode_bytes_read); break; case DECODE_QP: iRet = limitDetection(qp_depth, ds->decoded_bytes, ds->qp_state.decode_bytes_read); break; case DECODE_UU: iRet = limitDetection(uu_depth, ds->decoded_bytes, ds->uu_state.decode_bytes_read); break; case DECODE_BITENC: iRet = limitDetection(bitenc_depth, ds->decoded_bytes, ds->bitenc_state.bytes_read); break; default: break; } return iRet; } #endif snort-2.9.15.1/src/sfutil/sf_base64decode.c0000644000175200017520000001244113571422607015233 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 1998-2013 Sourcefire, Inc. ** ** Writen by Patrick Mullen ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sf_base64decode.h" uint8_t sf_decode64tab[256] = { 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, 100,100,100,100,100,100,100,100,100,100,100,62 ,100,100,100, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,100,100,100, 99,100,100, 100, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,100,100,100,100,100, 100, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,100,100,100,100,100, 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100}; /* base64decode assumes the input data terminates with '=' and/or at the end of the input buffer * at inbuf_size. If extra characters exist within inbuf before inbuf_size is reached, it will * happily decode what it can and skip over what it can't. This is consistent with other decoders * out there. So, either terminate the string, set inbuf_size correctly, or at least be sure the * data is valid up until the point you care about. Note base64 data does NOT have to end with * '=' and won't if the number of bytes of input data is evenly divisible by 3. */ int sf_base64decode(uint8_t *inbuf, uint32_t inbuf_size, uint8_t *outbuf, uint32_t outbuf_size, uint32_t *bytes_written) { uint8_t *cursor, *endofinbuf; uint8_t *outbuf_ptr; uint8_t base64data[4], *base64data_ptr; /* temporary holder for current base64 chunk */ uint8_t tableval_a, tableval_b, tableval_c, tableval_d; uint32_t n; uint32_t max_base64_chars; /* The max number of decoded base64 chars that fit into outbuf */ int error = 0; /* This algorithm will waste up to 4 bytes but we really don't care. At the end we're going to copy the exact number of bytes requested. */ max_base64_chars = (outbuf_size / 3) * 4 + 4; /* 4 base64 bytes gives 3 data bytes, plus an extra 4 to take care of any rounding */ base64data_ptr = base64data; endofinbuf = inbuf + inbuf_size; /* Strip non-base64 chars from inbuf and decode */ n = 0; *bytes_written = 0; cursor = inbuf; outbuf_ptr = outbuf; while((cursor < endofinbuf) && (n < max_base64_chars)) { if(sf_decode64tab[*cursor] != 100) { *base64data_ptr++ = *cursor; n++; /* Number of base64 bytes we've stored */ if(!(n % 4)) { /* We have four databytes upon which to operate */ if((base64data[0] == '=') || (base64data[1] == '=')) { /* Error in input data */ error = 1; break; } /* retrieve values from lookup table */ tableval_a = sf_decode64tab[base64data[0]]; tableval_b = sf_decode64tab[base64data[1]]; tableval_c = sf_decode64tab[base64data[2]]; tableval_d = sf_decode64tab[base64data[3]]; if(*bytes_written < outbuf_size) { *outbuf_ptr++ = (tableval_a << 2) | (tableval_b >> 4); (*bytes_written)++; } if((base64data[2] != '=') && (*bytes_written < outbuf_size)) { *outbuf_ptr++ = (tableval_b << 4) | (tableval_c >> 2); (*bytes_written)++; } else { break; } if((base64data[3] != '=') && (*bytes_written < outbuf_size)) { *outbuf_ptr++ = (tableval_c << 6) | tableval_d; (*bytes_written)++; } else { break; } /* Reset our decode pointer for the next group of four */ base64data_ptr = base64data; } } cursor++; } if(error) return(-1); else return(0); } snort-2.9.15.1/src/sfutil/sf_base64decode.h0000644000175200017520000000221413571422607015235 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 1998-2013 Sourcefire, Inc. ** ** Writen by Patrick Mullen ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _SF_BASE64DECODE_H_ #define _SF_BASE64DECODE_H_ #include "sf_types.h" #include "util_unfold.h" int sf_base64decode(uint8_t*, uint32_t, uint8_t*, uint32_t, uint32_t*); #endif snort-2.9.15.1/src/sfutil/Unified2_common.h0000644000175200017520000001607413571422607015343 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* PLEASE DO NOT EDIT THIS FILE */ #ifndef __UNIFIED2_COMMON_H__ #define __UNIFIED2_COMMON_H__ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #ifndef WIN32 #ifdef LINUX #include #endif #include #endif /*! \defgroup Unified2 */ /** \addtogroup Unified2 */ /*@{*/ //SNORT DEFINES //Long time ago... #define UNIFIED2_EVENT 1 //CURRENT #define UNIFIED2_PACKET 2 #define UNIFIED2_IDS_EVENT 7 #define UNIFIED2_IDS_EVENT_IPV6 72 #define UNIFIED2_IDS_EVENT_MPLS 99 #define UNIFIED2_IDS_EVENT_IPV6_MPLS 100 #define UNIFIED2_IDS_EVENT_VLAN 104 #define UNIFIED2_IDS_EVENT_IPV6_VLAN 105 #define UNIFIED2_EXTRA_DATA 110 #if defined(FEAT_OPEN_APPID) #define UNIFIED2_IDS_EVENT_APPID 111 #define UNIFIED2_IDS_EVENT_APPID_IPV6 112 #define UNIFIED2_IDS_EVENT_APPSTAT 113 #define MAX_EVENT_APPNAME_LEN 64 #endif /* defined(FEAT_OPEN_APPID) */ /* Data structure used for serialization of Unified2 Records */ typedef struct _Serial_Unified2_Header { uint32_t type; uint32_t length; } Serial_Unified2_Header; //UNIFIED2_IDS_EVENT_VLAN = type 104 //comes from SFDC to EStreamer archive in serialized form with the extended header typedef struct _Unified2IDSEvent { uint32_t sensor_id; uint32_t event_id; uint32_t event_second; uint32_t event_microsecond; uint32_t signature_id; uint32_t generator_id; uint32_t signature_revision; uint32_t classification_id; uint32_t priority_id; uint32_t ip_source; uint32_t ip_destination; uint16_t sport_itype; uint16_t dport_icode; uint8_t protocol; uint8_t impact_flag;//overloads packet_action uint8_t impact; uint8_t blocked; uint32_t mpls_label; uint16_t vlanId; uint16_t pad2;//Policy ID #if defined(FEAT_OPEN_APPID) char app_name[MAX_EVENT_APPNAME_LEN]; #endif /* defined(FEAT_OPEN_APPID) */ } Unified2IDSEvent; //UNIFIED2_IDS_EVENT_IPV6_VLAN = type 105 typedef struct _Unified2IDSEventIPv6 { uint32_t sensor_id; uint32_t event_id; uint32_t event_second; uint32_t event_microsecond; uint32_t signature_id; uint32_t generator_id; uint32_t signature_revision; uint32_t classification_id; uint32_t priority_id; struct in6_addr ip_source; struct in6_addr ip_destination; uint16_t sport_itype; uint16_t dport_icode; uint8_t protocol; uint8_t impact_flag; uint8_t impact; uint8_t blocked; uint32_t mpls_label; uint16_t vlanId; uint16_t pad2;/*could be IPS Policy local id to support local sensor alerts*/ #if defined(FEAT_OPEN_APPID) char app_name[MAX_EVENT_APPNAME_LEN]; #endif /* defined(FEAT_OPEN_APPID) */ } Unified2IDSEventIPv6; //UNIFIED2_PACKET = type 2 typedef struct _Serial_Unified2Packet { uint32_t sensor_id; uint32_t event_id; uint32_t event_second; uint32_t packet_second; uint32_t packet_microsecond; uint32_t linktype; uint32_t packet_length; uint8_t packet_data[4]; } Serial_Unified2Packet; typedef struct _Unified2ExtraDataHdr{ uint32_t event_type; uint32_t event_length; }Unified2ExtraDataHdr; //UNIFIED2_EXTRA_DATA - type 110 typedef struct _SerialUnified2ExtraData{ uint32_t sensor_id; uint32_t event_id; uint32_t event_second; uint32_t type; /* EventInfo */ uint32_t data_type; /*EventDataType */ uint32_t blob_length; /* Length of the data + sizeof(blob_length) + sizeof(data_type)*/ } SerialUnified2ExtraData; typedef struct _Data_Blob { uint32_t length; const uint8_t *data; } Data_Blob; //UNIFIED2_EXTRA_DATA - type 110 typedef struct _Serial_Unified2ExtraData{ uint32_t sensor_id; uint32_t event_id; uint32_t event_second; uint32_t type; Data_Blob data; } Unified2ExtraData; typedef enum _EventInfoEnum { EVENT_INFO_XFF_IPV4 = 1, EVENT_INFO_XFF_IPV6, EVENT_INFO_REVIEWED_BY, EVENT_INFO_GZIP_DATA, EVENT_INFO_SMTP_FILENAME, EVENT_INFO_SMTP_MAILFROM, EVENT_INFO_SMTP_RCPTTO, EVENT_INFO_SMTP_EMAIL_HDRS, EVENT_INFO_HTTP_URI, EVENT_INFO_HTTP_HOSTNAME, EVENT_INFO_IPV6_SRC, EVENT_INFO_IPV6_DST, EVENT_INFO_JSNORM_DATA }EventInfoEnum; typedef enum _EventDataType { EVENT_DATA_TYPE_BLOB = 1, EVENT_DATA_TYPE_MAX }EventDataType; #define EVENT_TYPE_EXTRA_DATA 4 #define MAX_XFF_WRITE_BUF_LENGTH (sizeof(Serial_Unified2_Header) + \ sizeof(Unified2ExtraDataHdr) + sizeof(SerialUnified2ExtraData) \ + sizeof(struct in6_addr)) #define Serial_Unified2IDSEvent Unified2IDSEvent #define Serial_Unified2IDSEventIPv6 Unified2IDSEventIPv6 //---------------LEGACY, type '7' //These structures are not used anymore in the product typedef struct _Serial_Unified2IDSEvent_legacy { uint32_t sensor_id; uint32_t event_id; uint32_t event_second; uint32_t event_microsecond; uint32_t signature_id; uint32_t generator_id; uint32_t signature_revision; uint32_t classification_id; uint32_t priority_id; uint32_t ip_source; uint32_t ip_destination; uint16_t sport_itype; uint16_t dport_icode; uint8_t protocol; uint8_t impact_flag;//sets packet_action uint8_t impact; uint8_t blocked; } Serial_Unified2IDSEvent_legacy; //----------LEGACY, type '72' typedef struct _Serial_Unified2IDSEventIPv6_legacy { uint32_t sensor_id; uint32_t event_id; uint32_t event_second; uint32_t event_microsecond; uint32_t signature_id; uint32_t generator_id; uint32_t signature_revision; uint32_t classification_id; uint32_t priority_id; struct in6_addr ip_source; struct in6_addr ip_destination; uint16_t sport_itype; uint16_t dport_icode; uint8_t protocol; uint8_t impact_flag; uint8_t impact; uint8_t blocked; } Serial_Unified2IDSEventIPv6_legacy; #if defined(FEAT_OPEN_APPID) //UNIFIED2_IDS_EVENT_IPV6_VLAN = type 200 typedef struct _Serial_Unified2AppStat { uint32_t event_second; uint32_t AppCnt; } Serial_Unified2AppStat; #endif /* defined(FEAT_OPEN_APPID) */ ////////////////////-->LEGACY /*@}*/ #endif /* __UNIFIED2_COMMON_H__ */ snort-2.9.15.1/src/sfutil/sf_seqnums.h0000644000175200017520000000262313571422607014504 00000000000000/**************************************************************************** * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2012-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #ifndef _SF_SEQNUMS_H_ #define _SF_SEQNUMS_H_ /* Macros to deal with sequence numbers - p810 TCP Illustrated vol 2 */ #define SEQ_LT(a,b) ((int)((a) - (b)) < 0) #define SEQ_LEQ(a,b) ((int)((a) - (b)) <= 0) #define SEQ_GT(a,b) ((int)((a) - (b)) > 0) #define SEQ_GEQ(a,b) ((int)((a) - (b)) >= 0) #define SEQ_EQ(a,b) ((int)((a) - (b)) == 0) #endif // _SF_SEQNUMS_H_ snort-2.9.15.1/src/sfutil/mpse_methods.h0000644000175200017520000000234113571422607015005 00000000000000/* ** mpse.h ** ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** ** 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 Gener* */ #ifndef _MPSE_METHODS_H_ #define _MPSE_METHODS_H_ /* * Pattern Matching Methods */ //#define MPSE_MWM 1 #define MPSE_AC 2 //#define MPSE_KTBM 3 #define MPSE_LOWMEM 4 //#define MPSE_AUTO 5 #define MPSE_ACF 6 #define MPSE_ACS 7 #define MPSE_ACB 8 #define MPSE_ACSB 9 #define MPSE_AC_BNFA 10 #define MPSE_AC_BNFA_Q 11 #define MPSE_ACF_Q 12 #define MPSE_LOWMEM_Q 13 #ifdef INTEL_SOFT_CPM #define MPSE_INTEL_CPM 14 #endif /* INTEL_SOFT_CPM */ typedef enum { MPSE_PATTERN_CASE, MPSE_PATTERN_NOCASE } tMpseCaseEnum; #endif snort-2.9.15.1/src/sfutil/sfdebug.h0000644000175200017520000000431013571422607013733 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2006-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #ifndef _SFDEBUG_H_ #define _SFDEBUG_H_ #include /* ANY CHANGES MADE HERE SHOULD BE DUPLICATED TO toos/sfcontrol/sfcontrol.c */ static inline void DumpHex(FILE *fp, const uint8_t *data, unsigned len) { char str[18]; unsigned i; unsigned pos; char c; for (i=0, pos=0; i #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "intel-soft-cpm.h" #include "pm/cpa_pm_compile.h" #include "util.h" #include "snort.h" #include "snort_debug.h" #include "fpcreate.h" /* MACROS *********************************************************************/ #define GROUP_ARRAY_ALLOC_SIZE 50 #define PATTERN_ARRAY_ALLOC_SIZE 10 #define MAX_INQ 32 #define DIM(x) (sizeof(x)/sizeof(x[0])) /* DATA TYPES *****************************************************************/ typedef struct _IntelPmMatchQueue { unsigned int inq; unsigned int inq_flush; void * q[MAX_INQ]; } IntelPmMatchQueue; typedef struct _IntelPmMatchState { void *user_data; void *rule_option_tree; void *neg_list; void (*user_free)(void *); void (*option_tree_free)(void **); void (*neg_list_free)(void **); } IntelPmMatchState; typedef struct _IntelPmHandles { CpaPmPdbPatternSetHandle psh; /* pattern set handle */ CpaPmPdbHandle pdbh; /* pattern database handle */ Cpa16U pgids; /* pattern group ids */ Cpa32U pids; /* pattern ids */ Cpa32U pcs; /* pattern characters */ IntelPm **ipms; /* pattern matchers */ int ipms_len; IntelPmMatchState *pm_mtchs; int pm_mtchs_len; int refs; } IntelPmHandles; typedef int (*MatchFunc)(void * id, void *tree, int index, void *data, void *neg_list); /* GLOBALS ********************************************************************/ static CpaInstanceHandle ipm_instance = NULL; /* instance handle */ /* XXX Temporary stat for Intel */ //static uint64_t intel_pm_search_buf_sizes[65536]; //static uint64_t intel_pm_matches = 0; /* PROTOTYPES *****************************************************************/ static inline const char * GetCpaStatusStr(CpaStatus); static void IntelPmSearchCallback(const CpaInstanceHandle, CpaPmMatchCtx *); static inline void IntelPmInitQueue(IntelPmMatchQueue *); static inline int IntelPmAddQueue(IntelPmMatchQueue *, void *); static inline unsigned int IntelPmProcessQueue(IntelPmMatchQueue *, MatchFunc, void *); /* FUNCTIONS ******************************************************************/ static inline const char * GetCpaStatusStr(CpaStatus status) { switch (status) { case CPA_STATUS_SUCCESS: return CPA_STATUS_STR_SUCCESS; case CPA_STATUS_FAIL: return CPA_STATUS_STR_FAIL; case CPA_STATUS_RETRY: return CPA_STATUS_STR_RETRY; case CPA_STATUS_RESOURCE: return CPA_STATUS_STR_RESOURCE; case CPA_STATUS_INVALID_PARAM: return CPA_STATUS_STR_INVALID_PARAM; case CPA_STATUS_FATAL: return CPA_STATUS_STR_FATAL; default: break; } return "Unknown Cpa error"; } static inline void IntelPmInitQueue(IntelPmMatchQueue *q) { q->inq = 0; q->inq_flush = 0; } static inline int IntelPmAddQueue(IntelPmMatchQueue *q, void *p) { int i; for (i = (int)q->inq - 1; i >= 0; i--) { if(p == q->q[i]) return 0; } if (q->inq < MAX_INQ) q->q[q->inq++] = p; if (q->inq == MAX_INQ) return 1; return 0; } static inline unsigned int IntelPmProcessQueue(IntelPmMatchQueue *q, MatchFunc match, void *data) { unsigned int i; for (i = 0; i < q->inq; i++) { IntelPmMatchState *mstate = (IntelPmMatchState *)q->q[i]; if (mstate != NULL) { if (match(mstate->user_data, mstate->rule_option_tree, 0, data, mstate->neg_list) > 0) { q->inq = 0; return 1; } } } q->inq = 0; return 0; } void IntelPmStartInstance(void) { Cpa16U nInstances; CpaInstanceHandle instanceHandle; CpaInstanceHandle *pHandles; CpaStatus status; if (ipm_instance != NULL) return; status = cpaPmGetNumInstances(&nInstances); if (status != CPA_STATUS_SUCCESS) FatalError("cpaPmGetNumInstances() failed: %s\n", GetCpaStatusStr(status)); pHandles = (CpaInstanceHandle *)SnortAlloc(nInstances * sizeof(CpaInstanceHandle)); status = cpaPmGetInstances(nInstances, pHandles); if (status != CPA_STATUS_SUCCESS) FatalError("cpaPmGetInstances() failed: %s\n", GetCpaStatusStr(status)); instanceHandle = pHandles[0]; status = cpaPmStartInstance(instanceHandle); if (status != CPA_STATUS_SUCCESS) FatalError("cpaPmStartInstance() failed: %s\n", GetCpaStatusStr(status)); /* Not sure if this frees everything except the first handle - taken * from intel code */ free(pHandles); ipm_instance = instanceHandle; } void * IntelPmNew(SnortConfig *sc, void (*user_free)(void *p), void (*option_tree_free)(void **p), void (*neg_list_free)(void **p)) { CpaStatus status; IntelPm *ipm = (IntelPm *)SnortAlloc(sizeof(IntelPm)); if (sc->ipm_handles == NULL) { CpaPmPdbPatternSetHandle patternSetHandle; status = cpaPmPdbCreatePatternSet(ipm_instance, 0, &patternSetHandle); if (status != CPA_STATUS_SUCCESS) FatalError("cpaPmPdbCreatePatternSet() failed: %s\n", GetCpaStatusStr(status)); sc->ipm_handles = (IntelPmHandles *)SnortAlloc(sizeof(IntelPmHandles)); sc->ipm_handles->psh = patternSetHandle; sc->ipm_handles->pdbh = NULL; sc->ipm_handles->pgids = 1; sc->ipm_handles->pids = 0; sc->ipm_handles->refs = 1; //sc has a reference //memset(intel_pm_search_buf_sizes, 0, sizeof(intel_pm_search_buf_sizes)); } ipm->user_free = user_free; ipm->option_tree_free = option_tree_free; ipm->neg_list_free = neg_list_free; ipm->match_queue = SnortAlloc(sizeof(IntelPmMatchQueue)); ipm->handles = sc->ipm_handles; sc->ipm_handles->refs++; return (void *)ipm; } void IntelPmDelete(IntelPm *ipm) { int i; if (ipm == NULL) return; if (ipm->sessionCtx != NULL) { cpaPmReleaseSessionCtx(ipm_instance, ipm->sessionCtx); free(ipm->sessionCtx); ipm->sessionCtx = NULL; } if (ipm->match_queue != NULL) free(ipm->match_queue); for (i = 0; i < ipm->pattern_array_len; i++) { IntelPmPattern *pat = &ipm->pattern_array[i]; if (ipm->user_free && pat->user_data) ipm->user_free(pat->user_data); } free(ipm->pattern_array); IntelPmRelease(ipm->handles); free(ipm); } int IntelPmRelease(IntelPmHandles *handles) { CpaStatus status; int i; if (handles == NULL) return -1; handles->refs--; if (handles->refs != 0) return handles->refs; for (i = 0; i < handles->pm_mtchs_len; i++) { IntelPmMatchState *ms = &handles->pm_mtchs[i]; if (ms->rule_option_tree && ms->option_tree_free) ms->option_tree_free(&ms->rule_option_tree); if (ms->neg_list && ms->neg_list_free) ms->neg_list_free(&ms->neg_list); } if (handles->psh != NULL) { status = cpaPmPdbReleasePatternSet(ipm_instance, handles->psh); if (status != CPA_STATUS_SUCCESS) FatalError("cpaPmPdbReleasePatternSet() failed: %s\n", GetCpaStatusStr(status)); } if (handles->pdbh != NULL) { status = cpaPmPdbRelease(ipm_instance, handles->pdbh); if (status != CPA_STATUS_SUCCESS) FatalError("cpaPmPdbRelease() failed: %s\n", GetCpaStatusStr(status)); } free(handles->ipms); free(handles->pm_mtchs); free(handles); return 0; } int IntelPmAddPattern(SnortConfig *sc, IntelPm *ipm, unsigned char *pat, int pat_len, unsigned no_case, unsigned negative, void *pat_data, int pat_id) { Cpa32U patternOptions = CPA_PM_PDB_OPTIONS_CASELESS | CPA_PM_PDB_OPTIONS_LITERAL; CpaStatus status; IntelPmPattern *ipp; if ((ipm == NULL) || (sc->ipm_handles == NULL)) return -1; if (!ipm->patternGroupId) { ipm->patternGroupId = sc->ipm_handles->pgids++; ipm->patternIds = 1; } status = cpaPmPdbAddPattern( ipm_instance, sc->ipm_handles->psh, ipm->patternIds, patternOptions, pat_len, pat, ipm->patternGroupId); if (status != CPA_STATUS_SUCCESS) FatalError("cpaPmPdbAddPattern() failed: %s\n", GetCpaStatusStr(status)); if (ipm->pattern_array == NULL) { ipm->pattern_array = (IntelPmPattern *)SnortAlloc( sizeof(IntelPmPattern) * PATTERN_ARRAY_ALLOC_SIZE); ipm->pattern_array_len = PATTERN_ARRAY_ALLOC_SIZE; } else if (ipm->patternIds >= ipm->pattern_array_len) { IntelPmPattern *tmp = (IntelPmPattern *)SnortAlloc( sizeof(IntelPmPattern) * (ipm->patternIds + PATTERN_ARRAY_ALLOC_SIZE)); memcpy((void *)tmp, ipm->pattern_array, ipm->patternIds * sizeof(IntelPmPattern)); free(ipm->pattern_array); ipm->pattern_array = tmp; ipm->pattern_array_len = ipm->patternIds + PATTERN_ARRAY_ALLOC_SIZE; } ipp = &ipm->pattern_array[ipm->patternIds]; ipp->user_data = pat_data; ipp->rule_option_tree = NULL; ipp->neg_list = NULL; //ipp->pattern = (unsigned char *)SnortAlloc(pat_len); //memcpy(ipp->pattern, pat, pat_len); ipp->pattern = NULL; ipp->pattern_len = pat_len; ipp->no_case = no_case; ipp->negative = negative; ipp->id = pat_id; ipp->patternId = ipm->patternIds++; sc->ipm_handles->pids++; sc->ipm_handles->pcs += pat_len; return 0; } int IntelPmFinishGroup(SnortConfig *sc, IntelPm *ipm, int (*build_tree)(SnortConfig *, void *id, void **existing_tree), int (*neg_list_func)(void *id, void **list)) { Cpa32U sessionCtxSize; CpaPmSessionProperty sessionProperty; Cpa8U *pMemory; CpaStatus status; if (ipm == NULL) return -1; ipm->build_tree = build_tree; ipm->neg_list_func = neg_list_func; sessionProperty.numPatternGroupIds = 1; sessionProperty.patternGroups[0].id.pdb = 0; sessionProperty.patternGroups[0].id.group = ipm->patternGroupId; sessionProperty.stateless = CPA_TRUE; status = cpaPmSessionCtxGetSize(ipm_instance, &sessionProperty, &sessionCtxSize); if (status != CPA_STATUS_SUCCESS) FatalError("cpaPmSessionCtxGetSize() failed: %s\n", GetCpaStatusStr(status)); pMemory = (Cpa8U *)SnortAlloc(sessionCtxSize); status = cpaPmCreateSessionCtx(ipm_instance, &sessionProperty, pMemory, &ipm->sessionCtx); if (status != CPA_STATUS_SUCCESS) FatalError("cpaPmCreateSessionCtx() failed: %s\n", GetCpaStatusStr(status)); if (sc->ipm_handles->ipms == NULL) { sc->ipm_handles->ipms = (IntelPm **)SnortAlloc( sizeof(IntelPm *) * GROUP_ARRAY_ALLOC_SIZE); sc->ipm_handles->ipms_len = GROUP_ARRAY_ALLOC_SIZE; } else if (ipm->patternGroupId >= sc->ipm_handles->ipms_len) { IntelPm **tmp = (IntelPm **)SnortAlloc( sizeof(IntelPm *) * (ipm->patternGroupId + GROUP_ARRAY_ALLOC_SIZE)); memcpy((void *)tmp, sc->ipm_handles->ipms, sc->ipm_handles->ipms_len * sizeof(IntelPm *)); free(sc->ipm_handles->ipms); sc->ipm_handles->ipms = tmp; sc->ipm_handles->ipms_len = ipm->patternGroupId + GROUP_ARRAY_ALLOC_SIZE; } sc->ipm_handles->ipms[ipm->patternGroupId] = ipm; return 0; } void IntelPmCompile(SnortConfig *sc) { if ((ipm_instance == NULL) || (sc->ipm_handles == NULL) || (sc->ipm_handles->psh == NULL)) { return; } if (sc->ipm_handles->pdbh == NULL) { CpaStatus status; Cpa16U patternGroup; Cpa32U numMatchStates; status = cpaPmPdbCompile(ipm_instance, sc->ipm_handles->psh, CPA_PM_COMPILE_OPTION_CONSOLIDATE, NULL, &sc->ipm_handles->pdbh); if (status != CPA_STATUS_SUCCESS) FatalError("cpaPmPdbCompile() failed: %s\n", GetCpaStatusStr(status)); status = cpaPmMsoGetNumMatchStates(ipm_instance, sc->ipm_handles->pdbh, &numMatchStates); if (status != CPA_STATUS_SUCCESS) FatalError("cpaPmMsoGetNumMatchStates() failed: %s\n", GetCpaStatusStr(status)); /* Hack because the last match state is returned instead of the * number of match states */ numMatchStates += 1; sc->ipm_handles->pm_mtchs = (IntelPmMatchState *)SnortAlloc(numMatchStates * sizeof(IntelPmMatchState)); sc->ipm_handles->pm_mtchs_len = numMatchStates; for (patternGroup = 1; patternGroup < sc->ipm_handles->pgids; patternGroup++) { CpaPmMsoMatchStateIter matchStateIter = NULL; Cpa32U matchStateId; IntelPm *ipm = sc->ipm_handles->ipms[patternGroup]; if (ipm == NULL) continue; status = cpaPmMsoGetFirstMatchState(ipm_instance, sc->ipm_handles->pdbh, patternGroup, &matchStateIter, &matchStateId); if (status != CPA_STATUS_SUCCESS) FatalError("cpaPmMsoGetFirstMatchState() failed: %s\n", GetCpaStatusStr(status)); while (matchStateIter != NULL) { CpaPmMsoPatternIdIter patternIdIter = NULL; Cpa32U patternID; IntelPmPattern *ipp = NULL; void *rule_option_tree = NULL; void *neg_list = NULL; void *user_data = NULL; status = cpaPmMsoGetFirstPatternId(ipm_instance, sc->ipm_handles->pdbh, matchStateIter, &patternIdIter, &patternID); if (status != CPA_STATUS_SUCCESS) FatalError("cpaPmMsoGetFirstPatternId() failed: %s\n", GetCpaStatusStr(status)); while (patternIdIter != NULL) { ipp = &ipm->pattern_array[patternID]; if (user_data == NULL) user_data = ipp->user_data; if (ipp->negative) ipm->neg_list_func(ipp->user_data, &neg_list); else ipm->build_tree(sc, ipp->user_data, &rule_option_tree); status = cpaPmMsoGetNextPatternId(ipm_instance, sc->ipm_handles->pdbh, &patternIdIter, &patternID); if (status != CPA_STATUS_SUCCESS) FatalError("cpaPmMsoGetNextPatternId() failed: %s\n", GetCpaStatusStr(status)); } if (ipp != NULL) { ipm->build_tree(sc, NULL, &rule_option_tree); sc->ipm_handles->pm_mtchs[matchStateId].user_data = user_data; sc->ipm_handles->pm_mtchs[matchStateId].neg_list = neg_list; sc->ipm_handles->pm_mtchs[matchStateId].rule_option_tree = rule_option_tree; sc->ipm_handles->pm_mtchs[matchStateId].user_free = ipm->user_free; sc->ipm_handles->pm_mtchs[matchStateId].option_tree_free = ipm->option_tree_free; sc->ipm_handles->pm_mtchs[matchStateId].neg_list_free = ipm->neg_list_free; } status = cpaPmMsoGetNextMatchState(ipm_instance, sc->ipm_handles->pdbh, patternGroup, &matchStateIter, &matchStateId); if (status != CPA_STATUS_SUCCESS) FatalError("cpaPmMsoGetNextMatchState() failed: %s\n", GetCpaStatusStr(status)); } } } } void IntelPmActivate(SnortConfig *sc) { CpaStatus status; IntelPmHandles *handles = sc->ipm_handles; sc->ipm_handles = NULL; if (IntelPmRelease(handles) <= 0) return; if (ipm_instance == NULL) return; status = cpaPmActivatePdb(ipm_instance, handles->pdbh, NULL); if (status != CPA_STATUS_SUCCESS) FatalError("cpaPmPdbActivate() failed: %s\n", GetCpaStatusStr(status)); } static void IntelPmSearchCallback(const CpaInstanceHandle instanceHandle, CpaPmMatchCtx *pMatchCtxList) { Cpa32U i; IntelPm *ipm = (IntelPm *)pMatchCtxList->userData; IntelPmHandles *handles = (IntelPmHandles *)ipm->handles; for (i = 0; i < pMatchCtxList->numMatchResults; i++) { CpaPmMatchResult *result = &pMatchCtxList->pMatchResult[i]; //intel_pm_matches++; if (result->matchLength == 0) continue; if (result->patternGroupId.id.group != ipm->patternGroupId) continue; if (IntelPmAddQueue((IntelPmMatchQueue *)ipm->match_queue, (void *)&handles->pm_mtchs[result->patternId])) { IntelPmProcessQueue((IntelPmMatchQueue *)ipm->match_queue, ipm->match, ipm->data); } } } int IntelPmSearch(IntelPm *ipm, unsigned char *buffer, int buffer_len, MatchFunc match, void *data) { CpaFlatBuffer flat_buffer = {buffer_len, buffer}; CpaBufferList buffer_list = {1, &flat_buffer, NULL, NULL}; CpaPmMatchResult matchResults[100]; /* XXX Can this be unlimited? */ CpaPmMatchCtx matchCtxList; CpaStatus status; //intel_pm_search_buf_sizes[buffer_len]++; ipm->data = data; ipm->match = match; /* Note: Search options CPA_PM_MATCH_OPTION_RESET_STREAM | CPA_PM_MATCH_OPTION_END_OF_STREAM specify a stateless search. */ matchCtxList.pNext = NULL; matchCtxList.pBufferList = &buffer_list; matchCtxList.sessionCtx = ipm->sessionCtx; matchCtxList.matchOptions = CPA_PM_MATCH_OPTION_RESET_SESSION | CPA_PM_MATCH_OPTION_END_OF_SESSION | CPA_PM_MATCH_OPTION_EOB_NOCALLBACK | CPA_PM_MATCH_OPTION_FIND_FIRST_MATCH; matchCtxList.matchCallback = IntelPmSearchCallback; matchCtxList.userData = ipm; matchCtxList.sizeMatchResults = DIM(matchResults); matchCtxList.pMatchResult = matchResults; status = cpaPmSearchExec(ipm_instance, &matchCtxList, NULL); if (status != CPA_STATUS_SUCCESS) FatalError("cpaPmSearchExec() failed: %s\n", GetCpaStatusStr(status)); IntelPmProcessQueue((IntelPmMatchQueue *)ipm->match_queue, ipm->match, ipm->data); return 0; } int IntelGetPatternCount(IntelPm *ipm) { if (ipm == NULL) return 0; return (int)ipm->patternIds; } int IntelPmPrintInfo(IntelPm *ipm) { return 0; } void IntelPmPrintSummary(SnortConfig *sc) { if (sc->ipm_handles == NULL) return; LogMessage("+-[Intel PM Search Info Summary]------------------\n"); LogMessage("| Instances : %u\n", sc->ipm_handles->pgids - 1); /* pattern groups start at 1 */ LogMessage("| Patterns : %u\n", sc->ipm_handles->pids); LogMessage("| Pattern Chars : %u\n", sc->ipm_handles->pcs); LogMessage("+-------------------------------------------------\n"); } #if 0 /* XXX Temporary because Intel wants some stats on buffer sizes */ void IntelPmPrintBufferStats(void) { int i; LogMessage("===============================================================================\n"); LogMessage("Intel stats\n\n"); LogMessage("Number of buffers per size of buffer\n"); for (i = 0; i < 65535; i++) { if (intel_pm_search_buf_sizes[i] > 0) LogMessage("%5u bytes : %7llu buffers\n", i, intel_pm_search_buf_sizes[i]); } LogMessage("\nNumber of matches: %llu\n", intel_pm_matches); LogMessage("===============================================================================\n"); } #endif void IntelPmStopInstance(void) { if (ipm_instance != NULL) { CpaStatus status = cpaPmStopInstance(ipm_instance); if (status != CPA_STATUS_SUCCESS) FatalError("cpaPmStopInstance() failed: %s\n", GetCpaStatusStr(status)); ipm_instance = NULL; } } snort-2.9.15.1/src/sfutil/intel-soft-cpm.h0000644000175200017520000000677513571422607015176 00000000000000/**************************************************************************** * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2009-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef _INTEL_H_ #define _INTEL_H_ #include "cpa.h" #include "pm/cpa_pm.h" #include "cpa_types.h" #include "snort_debug.h" /* DATA TYPES *****************************************************************/ typedef struct _IntelPmPattern { void *user_data; void *rule_option_tree; void *neg_list; unsigned char *pattern; unsigned int pattern_len; unsigned int no_case; unsigned int negative; int id; /* pattern id passed in from mpse */ Cpa32U patternId; /* actual pattern id */ } IntelPmPattern; struct _SnortConfig; struct _IntelPmHandles; typedef struct _IntelPm { Cpa16U patternGroupId; Cpa32U patternIds; CpaPmSessionCtx sessionCtx; /* Temporary data for building trees */ int (*build_tree)(struct _SnortConfig *, void *id, void **existing_tree); int (*neg_list_func)(void *id, void **list); void *match_queue; /* Temporary data for match callback */ void *data; int (*match)(void *id, void *tree, int index, void *data, void *neg_list); void (*user_free)(void *); void (*option_tree_free)(void **); void (*neg_list_free)(void **); IntelPmPattern *pattern_array; Cpa32U pattern_array_len; /* Every IntelPm has a reference to this */ struct _IntelPmHandles *handles; } IntelPm; /* PROTOTYPES *****************************************************************/ void IntelPmStartInstance(void); void IntelPmStopInstance(void); void * IntelPmNew(struct _SnortConfig *, void (*user_free)(void *p), void (*option_tree_free)(void **p), void (*neg_list_free)(void **p)); void IntelPmDelete(IntelPm *ipm); int IntelPmAddPattern(struct _SnortConfig *sc, IntelPm *ipm, unsigned char *pat, int pat_len, unsigned no_case, unsigned negative, void *pat_data, int pat_id); int IntelPmFinishGroup(struct _SnortConfig *, IntelPm *ipm, int (*build_tree)(struct _SnortConfig *, void *id, void **existing_tree), int (*neg_list_func)(void *id, void **list)); void IntelPmCompile(struct _SnortConfig *); void IntelPmActivate(struct _SnortConfig *); void IntelPmDeactivate(void); int IntelPmSearch(IntelPm *ipm, unsigned char *buffer, int buffer_len, int (*match)(void * id, void *tree, int index, void *data, void *neg_list), void *data); int IntelGetPatternCount(IntelPm *ipm); int IntelPmPrintInfo(IntelPm *ipm); void IntelPmPrintSummary(struct _SnortConfig *); void IntelPmPrintBufferStats(void); int IntelPmRelease(struct _IntelPmHandles *); #endif /* _INTEL_H_ */ snort-2.9.15.1/src/sfutil/md5.c0000644000175200017520000002343213571422607013002 00000000000000/* * This code implements the MD5 message-digest algorithm. * The algorithm is due to Ron Rivest. This code was * written by Colin Plumb in 1993, no copyright is claimed. * This code is in the public domain; do with it what you wish. * * Equivalent code is available from RSA Data Security, Inc. * This code has been tested against that, and is equivalent, * except that you don't need to include two pages of legalese * with every copy. * * To compute the message digest of a chunk of bytes, declare an * MD5Context structure, pass it to MD5Init, call MD5Update as * needed on buffers full of bytes, and then call MD5Final, which * will fill a supplied 16-byte array with the digest. */ /* This code slightly modified to fit into Samba by abartlet@samba.org Jun 2001 and to fit the cifs vfs by Steve French sfrench@us.ibm.com */ #include "config.h" #ifndef HAVE_OPENSSL_MD5 #include #include "md5.h" static void MD5Transform(uint32_t buf[4], uint32_t const in[16]); /* * Note: this code is harmless on little-endian machines. */ static void byteReverse(unsigned char *buf, unsigned longs) { uint32_t t; do { t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 | ((unsigned) buf[1] << 8 | buf[0]); *(uint32_t *) buf = t; buf += 4; } while (--longs); } /* * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious * initialization constants. */ void MD5Init(struct MD5Context *ctx) { ctx->buf[0] = 0x67452301; ctx->buf[1] = 0xefcdab89; ctx->buf[2] = 0x98badcfe; ctx->buf[3] = 0x10325476; ctx->bits[0] = 0; ctx->bits[1] = 0; } /* * Update context to reflect the concatenation of another buffer full * of bytes. */ void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len) { register uint32_t t; /* Update bitcount */ t = ctx->bits[0]; if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t) ctx->bits[1]++; /* Carry from low to high */ ctx->bits[1] += len >> 29; t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ /* Handle any leading odd-sized chunks */ if (t) { unsigned char *p = (unsigned char *) ctx->in + t; t = 64 - t; if (len < t) { memmove(p, buf, len); return; } memmove(p, buf, t); byteReverse(ctx->in, 16); MD5Transform(ctx->buf, (uint32_t *) ctx->in); buf += t; len -= t; } /* Process data in 64-byte chunks */ while (len >= 64) { memmove(ctx->in, buf, 64); byteReverse(ctx->in, 16); MD5Transform(ctx->buf, (uint32_t *) ctx->in); buf += 64; len -= 64; } /* Handle any remaining bytes of data. */ memmove(ctx->in, buf, len); } /* * Final wrapup - pad to 64-byte boundary with the bit pattern * 1 0* (64-bit count of bits processed, MSB-first) */ void MD5Final(unsigned char digest[16], struct MD5Context *ctx) { unsigned int count; unsigned char *p; /* Compute number of bytes mod 64 */ count = (ctx->bits[0] >> 3) & 0x3F; /* Set the first char of padding to 0x80. This is safe since there is always at least one byte free */ p = ctx->in + count; *p++ = 0x80; /* Bytes of padding needed to make 64 bytes */ count = 64 - 1 - count; /* Pad out to 56 mod 64 */ if (count < 8) { /* Two lots of padding: Pad the first block to 64 bytes */ memset(p, 0, count); byteReverse(ctx->in, 16); MD5Transform(ctx->buf, (uint32_t *) ctx->in); /* Now fill the next block with 56 bytes */ memset(ctx->in, 0, 56); } else { /* Pad block to 56 bytes */ memset(p, 0, count - 8); } byteReverse(ctx->in, 14); /* Append length in bits and transform */ ((uint32_t *) ctx->in)[14] = ctx->bits[0]; ((uint32_t *) ctx->in)[15] = ctx->bits[1]; MD5Transform(ctx->buf, (uint32_t *) ctx->in); byteReverse((unsigned char *) ctx->buf, 4); memmove(digest, ctx->buf, 16); memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ } /* The four core functions - F1 is optimized somewhat */ /* #define F1(x, y, z) (x & y | ~x & z) */ #define F1(x, y, z) (z ^ (x & (y ^ z))) #define F2(x, y, z) F1(z, x, y) #define F3(x, y, z) (x ^ y ^ z) #define F4(x, y, z) (y ^ (x | ~z)) /* This is the central step in the MD5 algorithm. */ #define MD5STEP(f, w, x, y, z, data, s) \ ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) /* * The core of the MD5 algorithm, this alters an existing MD5 hash to * reflect the addition of 16 longwords of new data. MD5Update blocks * the data and converts bytes into longwords for this routine. */ static void MD5Transform(uint32_t buf[4], uint32_t const in[16]) { register uint32_t a, b, c, d; a = buf[0]; b = buf[1]; c = buf[2]; d = buf[3]; MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); buf[0] += a; buf[1] += b; buf[2] += c; buf[3] += d; } /*********************************************************************** the microsoft version of hmac_md5 initialisation. ***********************************************************************/ void hmac_md5_init_limK_to_64(const unsigned char *key, int key_len, struct HMACMD5Context *ctx) { int i; /* if key is longer than 64 bytes truncate it */ if (key_len > 64) { key_len = 64; } /* start out by storing key in pads */ memset(ctx->k_ipad, 0, sizeof (ctx->k_ipad)); memset(ctx->k_opad, 0, sizeof (ctx->k_opad)); memcpy(ctx->k_ipad, key, key_len); memcpy(ctx->k_opad, key, key_len); /* XOR key with ipad and opad values */ for (i = 0; i < 64; i++) { ctx->k_ipad[i] ^= 0x36; ctx->k_opad[i] ^= 0x5c; } MD5Init(&ctx->ctx); MD5Update(&ctx->ctx, ctx->k_ipad, 64); } /*********************************************************************** update hmac_md5 "inner" buffer ***********************************************************************/ void hmac_md5_update(const unsigned char *text, int text_len, struct HMACMD5Context *ctx) { MD5Update(&ctx->ctx, text, text_len); /* then text of datagram */ } /*********************************************************************** finish off hmac_md5 "inner" buffer and generate outer one. ***********************************************************************/ void hmac_md5_final(unsigned char *digest, struct HMACMD5Context *ctx) { struct MD5Context ctx_o; MD5Final(digest, &ctx->ctx); MD5Init(&ctx_o); MD5Update(&ctx_o, ctx->k_opad, 64); MD5Update(&ctx_o, digest, 16); MD5Final(digest, &ctx_o); } /*********************************************************** single function to calculate an HMAC MD5 digest from data. use the microsoft hmacmd5 init method because the key is 16 bytes. ************************************************************/ void hmac_md5(unsigned char key[16], unsigned char *data, int data_len, unsigned char *digest) { struct HMACMD5Context ctx; hmac_md5_init_limK_to_64(key, 16, &ctx); if (data_len != 0) { hmac_md5_update(data, data_len, &ctx); } hmac_md5_final(digest, &ctx); } #endif /* !HAVE_OPENSSL_MD5 */ snort-2.9.15.1/src/sfutil/md5.h0000644000175200017520000000226013571422607013003 00000000000000#include "config.h" #ifndef HAVE_OPENSSL_MD5 #ifndef MD5_H #define MD5_H #ifndef HEADER_MD5_H /* Try to avoid clashes with OpenSSL */ #define HEADER_MD5_H #endif #include struct MD5Context { uint32_t buf[4]; uint32_t bits[2]; unsigned char in[64]; }; #endif /* !MD5_H */ #ifndef _HMAC_MD5_H struct HMACMD5Context { struct MD5Context ctx; unsigned char k_ipad[65]; unsigned char k_opad[65]; }; #endif /* _HMAC_MD5_H */ void MD5Init(struct MD5Context *context); void MD5Update(struct MD5Context *context, unsigned char const *buf, unsigned len); void MD5Final(unsigned char digest[16], struct MD5Context *context); /* The following definitions come from lib/hmacmd5.c */ /* void hmac_md5_init_rfc2104(unsigned char *key, int key_len, struct HMACMD5Context *ctx);*/ void hmac_md5_init_limK_to_64(const unsigned char *key, int key_len, struct HMACMD5Context *ctx); void hmac_md5_update(const unsigned char *text, int text_len, struct HMACMD5Context *ctx); void hmac_md5_final(unsigned char *digest, struct HMACMD5Context *ctx); void hmac_md5(unsigned char key[16], unsigned char *data, int data_len, unsigned char *digest); #endif /* !HAVE_OPENSSL_MD5 */ snort-2.9.15.1/src/sfutil/sha2.c0000644000175200017520000010455713571422607013162 00000000000000/* * FILE: sha2.c * AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/ * * Copyright (c) 2000-2001, Aaron D. Gifford * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holder nor the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``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 OR CONTRIBUTOR(S) 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. * */ #include "config.h" #ifndef HAVE_OPENSSL_SHA #include /* memcpy()/memset() or bcopy()/bzero() */ #include /* assert() */ #include "sha2.h" /* * ASSERT NOTE: * Some sanity checking code is included using assert(). On my FreeBSD * system, this additional code can be removed by compiling with NDEBUG * defined. Check your own systems manpage on assert() to see how to * compile WITHOUT the sanity checking code on your system. * * UNROLLED TRANSFORM LOOP NOTE: * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform * loop version for the hash transform rounds (defined using macros * later in this file). Either define on the command line, for example: * * cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c * * or define below: * * #define SHA2_UNROLL_TRANSFORM * */ /*** SHA-256/384/512 Machine Architecture Definitions *****************/ /* * BYTE_ORDER NOTE: * * Please make sure that your system defines BYTE_ORDER. If your * architecture is little-endian, make sure it also defines * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are * equivilent. * * If your system does not define the above, then you can do so by * hand like this: * * #define LITTLE_ENDIAN 1234 * #define BIG_ENDIAN 4321 * * And for little-endian machines, add: * * #define BYTE_ORDER LITTLE_ENDIAN * * Or for big-endian machines: * * #define BYTE_ORDER BIG_ENDIAN * * The FreeBSD machine this was written on defines BYTE_ORDER * appropriately by including (which in turn includes * where the appropriate definitions are actually * made). */ #if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN) #error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN #endif /* * Define the followingsha2_* types to types of the correct length on * the native archtecture. Most BSD systems and Linux define u_intXX_t * types. Machines with very recent ANSI C headers, can use the * uintXX_t definintions from inttypes.h by defining SHA2_USE_INTTYPES_H * during compile or in the sha.h header file. * * Machines that support neither u_intXX_t nor inttypes.h's uintXX_t * will need to define these three typedefs below (and the appropriate * ones in sha.h too) by hand according to their system architecture. * * Thank you, Jun-ichiro itojun Hagino, for suggesting using u_intXX_t * types and pointing out recent ANSI C support for uintXX_t in inttypes.h. */ #ifdef SHA2_USE_INTTYPES_H typedef uint8_t sha2_byte; /* Exactly 1 byte */ typedef uint32_t sha2_word32; /* Exactly 4 bytes */ typedef uint64_t sha2_word64; /* Exactly 8 bytes */ #else /* SHA2_USE_INTTYPES_H */ typedef u_int8_t sha2_byte; /* Exactly 1 byte */ typedef u_int32_t sha2_word32; /* Exactly 4 bytes */ typedef u_int64_t sha2_word64; /* Exactly 8 bytes */ #endif /* SHA2_USE_INTTYPES_H */ /*** SHA-256/384/512 Various Length Definitions ***********************/ /* NOTE: Most of these are in sha2.h */ #define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8) #define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16) #define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16) /*** ENDIAN REVERSAL MACROS *******************************************/ #if BYTE_ORDER == LITTLE_ENDIAN #define REVERSE32(w,x) { \ sha2_word32 tmp = (w); \ tmp = (tmp >> 16) | (tmp << 16); \ (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \ } #if defined(WIN32) # define REVERSE64(w,x) { \ sha2_word64 tmp = (w); \ tmp = (tmp >> 32) | (tmp << 32); \ tmp = ((tmp & 0xff00ff00ff00ff00ui64) >> 8) | \ ((tmp & 0x00ff00ff00ff00ffui64) << 8); \ (x) = ((tmp & 0xffff0000ffff0000ui64) >> 16) | \ ((tmp & 0x0000ffff0000ffffui64) << 16); \ } #else /* defined(WIN32) */ #define REVERSE64(w,x) { \ sha2_word64 tmp = (w); \ tmp = (tmp >> 32) | (tmp << 32); \ tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \ ((tmp & 0x00ff00ff00ff00ffULL) << 8); \ (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \ ((tmp & 0x0000ffff0000ffffULL) << 16); \ } #endif /* defined(WIN32) */ #endif /* BYTE_ORDER == LITTLE_ENDIAN */ /* * Macro for incrementally adding the unsigned 64-bit integer n to the * unsigned 128-bit integer (represented using a two-element array of * 64-bit words): */ #define ADDINC128(w,n) { \ (w)[0] += (sha2_word64)(n); \ if ((w)[0] < (n)) { \ (w)[1]++; \ } \ } /* * Macros for copying blocks of memory and for zeroing out ranges * of memory. Using these macros makes it easy to switch from * using memset()/memcpy() and using bzero()/bcopy(). * * Please define either SHA2_USE_MEMSET_MEMCPY or define * SHA2_USE_BZERO_BCOPY depending on which function set you * choose to use: */ #if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY) /* Default to memset()/memcpy() if no option is specified */ #define SHA2_USE_MEMSET_MEMCPY 1 #endif #if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY) /* Abort with an error if BOTH options are defined */ #error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both! #endif #ifdef SHA2_USE_MEMSET_MEMCPY #define MEMSET_BZERO(p,l) memset((p), 0, (l)) #define MEMCPY_BCOPY(d,s,l) memcpy((d), (s), (l)) #endif #ifdef SHA2_USE_BZERO_BCOPY #define MEMSET_BZERO(p,l) bzero((p), (l)) #define MEMCPY_BCOPY(d,s,l) bcopy((s), (d), (l)) #endif /*** THE SIX LOGICAL FUNCTIONS ****************************************/ /* * Bit shifting and rotation (used by the six SHA-XYZ logical functions: * * NOTE: The naming of R and S appears backwards here (R is a SHIFT and * S is a ROTATION) because the SHA-256/384/512 description document * (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this * same "backwards" definition. */ /* Shift-right (used in SHA-256, SHA-384, and SHA-512): */ #define R(b,x) ((x) >> (b)) /* 32-bit Rotate-right (used in SHA-256): */ #define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) /* 64-bit Rotate-right (used in SHA-384 and SHA-512): */ #define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b)))) /* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */ #define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) /* Four of six logical functions used in SHA-256: */ #define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x))) #define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x))) #define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x))) #define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x))) /* Four of six logical functions used in SHA-384 and SHA-512: */ #define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x))) #define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x))) #define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x))) #define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x))) /*** INTERNAL FUNCTION PROTOTYPES *************************************/ /* NOTE: These should not be accessed directly from outside this * library -- they are intended for private internal visibility/use * only. */ void SHA512_Last(SHA512_CTX*); void SHA256_Transform(SHA256_CTX*, const sha2_word32*); void SHA512_Transform(SHA512_CTX*, const sha2_word64*); /*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ /* Hash constant words K for SHA-256: */ static const sha2_word32 K256[64] = { 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL }; /* Initial hash value H for SHA-256: */ static const sha2_word32 sha256_initial_hash_value[8] = { 0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL, 0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL }; #if defined(WIN32) /* Hash constant words K for SHA-384 and SHA-512: */ const static sha2_word64 K512[80] = { 0x428a2f98d728ae22ui64, 0x7137449123ef65cdui64, 0xb5c0fbcfec4d3b2fui64, 0xe9b5dba58189dbbcui64, 0x3956c25bf348b538ui64, 0x59f111f1b605d019ui64, 0x923f82a4af194f9bui64, 0xab1c5ed5da6d8118ui64, 0xd807aa98a3030242ui64, 0x12835b0145706fbeui64, 0x243185be4ee4b28cui64, 0x550c7dc3d5ffb4e2ui64, 0x72be5d74f27b896fui64, 0x80deb1fe3b1696b1ui64, 0x9bdc06a725c71235ui64, 0xc19bf174cf692694ui64, 0xe49b69c19ef14ad2ui64, 0xefbe4786384f25e3ui64, 0x0fc19dc68b8cd5b5ui64, 0x240ca1cc77ac9c65ui64, 0x2de92c6f592b0275ui64, 0x4a7484aa6ea6e483ui64, 0x5cb0a9dcbd41fbd4ui64, 0x76f988da831153b5ui64, 0x983e5152ee66dfabui64, 0xa831c66d2db43210ui64, 0xb00327c898fb213fui64, 0xbf597fc7beef0ee4ui64, 0xc6e00bf33da88fc2ui64, 0xd5a79147930aa725ui64, 0x06ca6351e003826fui64, 0x142929670a0e6e70ui64, 0x27b70a8546d22ffcui64, 0x2e1b21385c26c926ui64, 0x4d2c6dfc5ac42aedui64, 0x53380d139d95b3dfui64, 0x650a73548baf63deui64, 0x766a0abb3c77b2a8ui64, 0x81c2c92e47edaee6ui64, 0x92722c851482353bui64, 0xa2bfe8a14cf10364ui64, 0xa81a664bbc423001ui64, 0xc24b8b70d0f89791ui64, 0xc76c51a30654be30ui64, 0xd192e819d6ef5218ui64, 0xd69906245565a910ui64, 0xf40e35855771202aui64, 0x106aa07032bbd1b8ui64, 0x19a4c116b8d2d0c8ui64, 0x1e376c085141ab53ui64, 0x2748774cdf8eeb99ui64, 0x34b0bcb5e19b48a8ui64, 0x391c0cb3c5c95a63ui64, 0x4ed8aa4ae3418acbui64, 0x5b9cca4f7763e373ui64, 0x682e6ff3d6b2b8a3ui64, 0x748f82ee5defb2fcui64, 0x78a5636f43172f60ui64, 0x84c87814a1f0ab72ui64, 0x8cc702081a6439ecui64, 0x90befffa23631e28ui64, 0xa4506cebde82bde9ui64, 0xbef9a3f7b2c67915ui64, 0xc67178f2e372532bui64, 0xca273eceea26619cui64, 0xd186b8c721c0c207ui64, 0xeada7dd6cde0eb1eui64, 0xf57d4f7fee6ed178ui64, 0x06f067aa72176fbaui64, 0x0a637dc5a2c898a6ui64, 0x113f9804bef90daeui64, 0x1b710b35131c471bui64, 0x28db77f523047d84ui64, 0x32caab7b40c72493ui64, 0x3c9ebe0a15c9bebcui64, 0x431d67c49c100d4cui64, 0x4cc5d4becb3e42b6ui64, 0x597f299cfc657e2aui64, 0x5fcb6fab3ad6faecui64, 0x6c44198c4a475817ui64 }; /* Initial hash value H for SHA-384 */ const static sha2_word64 sha384_initial_hash_value[8] = { 0xcbbb9d5dc1059ed8ui64, 0x629a292a367cd507ui64, 0x9159015a3070dd17ui64, 0x152fecd8f70e5939ui64, 0x67332667ffc00b31ui64, 0x8eb44a8768581511ui64, 0xdb0c2e0d64f98fa7ui64, 0x47b5481dbefa4fa4ui64 }; /* Initial hash value H for SHA-512 */ const static sha2_word64 sha512_initial_hash_value[8] = { 0x6a09e667f3bcc908ui64, 0xbb67ae8584caa73bui64, 0x3c6ef372fe94f82bui64, 0xa54ff53a5f1d36f1ui64, 0x510e527fade682d1ui64, 0x9b05688c2b3e6c1fui64, 0x1f83d9abfb41bd6bui64, 0x5be0cd19137e2179ui64 }; #else /* defined(WIN32) */ /* Hash constant words K for SHA-384 and SHA-512: */ static const sha2_word64 K512[80] = { 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL }; /* Initial hash value H for SHA-384 */ static const sha2_word64 sha384_initial_hash_value[8] = { 0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL, 0x9159015a3070dd17ULL, 0x152fecd8f70e5939ULL, 0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL, 0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL }; /* Initial hash value H for SHA-512 */ static const sha2_word64 sha512_initial_hash_value[8] = { 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL }; #endif /* defined(WIN32) */ /* * Constant used by SHA256/384/512_End() functions for converting the * digest to a readable hexadecimal character string: */ static const char *sha2_hex_digits = "0123456789abcdef"; /*** SHA-256: *********************************************************/ void SHA256_Init(SHA256_CTX* context) { if (context == (SHA256_CTX*)0) { return; } MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH); MEMSET_BZERO(context->buffer, SHA256_BLOCK_LENGTH); context->bitcount = 0; } #ifdef SHA2_UNROLL_TRANSFORM /* Unrolled SHA-256 round macros: */ #if BYTE_ORDER == LITTLE_ENDIAN #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ REVERSE32(*data++, W256[j]); \ T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ K256[j] + W256[j]; \ (d) += T1; \ (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ j++ #else /* BYTE_ORDER == LITTLE_ENDIAN */ #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ K256[j] + (W256[j] = *data++); \ (d) += T1; \ (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ j++ #endif /* BYTE_ORDER == LITTLE_ENDIAN */ #define ROUND256(a,b,c,d,e,f,g,h) \ s0 = W256[(j+1)&0x0f]; \ s0 = sigma0_256(s0); \ s1 = W256[(j+14)&0x0f]; \ s1 = sigma1_256(s1); \ T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \ (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ (d) += T1; \ (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ j++ void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { sha2_word32 a, b, c, d, e, f, g, h, s0, s1; sha2_word32 T1, *W256; int j; W256 = (sha2_word32*)context->buffer; /* Initialize registers with the prev. intermediate value */ a = context->state[0]; b = context->state[1]; c = context->state[2]; d = context->state[3]; e = context->state[4]; f = context->state[5]; g = context->state[6]; h = context->state[7]; j = 0; do { /* Rounds 0 to 15 (unrolled): */ ROUND256_0_TO_15(a,b,c,d,e,f,g,h); ROUND256_0_TO_15(h,a,b,c,d,e,f,g); ROUND256_0_TO_15(g,h,a,b,c,d,e,f); ROUND256_0_TO_15(f,g,h,a,b,c,d,e); ROUND256_0_TO_15(e,f,g,h,a,b,c,d); ROUND256_0_TO_15(d,e,f,g,h,a,b,c); ROUND256_0_TO_15(c,d,e,f,g,h,a,b); ROUND256_0_TO_15(b,c,d,e,f,g,h,a); } while (j < 16); /* Now for the remaining rounds to 64: */ do { ROUND256(a,b,c,d,e,f,g,h); ROUND256(h,a,b,c,d,e,f,g); ROUND256(g,h,a,b,c,d,e,f); ROUND256(f,g,h,a,b,c,d,e); ROUND256(e,f,g,h,a,b,c,d); ROUND256(d,e,f,g,h,a,b,c); ROUND256(c,d,e,f,g,h,a,b); ROUND256(b,c,d,e,f,g,h,a); } while (j < 64); /* Compute the current intermediate hash value */ context->state[0] += a; context->state[1] += b; context->state[2] += c; context->state[3] += d; context->state[4] += e; context->state[5] += f; context->state[6] += g; context->state[7] += h; /* Clean up */ a = b = c = d = e = f = g = h = T1 = 0; } #else /* SHA2_UNROLL_TRANSFORM */ void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { sha2_word32 a, b, c, d, e, f, g, h, s0, s1; sha2_word32 T1, T2, *W256; int j; W256 = (sha2_word32*)context->buffer; /* Initialize registers with the prev. intermediate value */ a = context->state[0]; b = context->state[1]; c = context->state[2]; d = context->state[3]; e = context->state[4]; f = context->state[5]; g = context->state[6]; h = context->state[7]; j = 0; do { #if BYTE_ORDER == LITTLE_ENDIAN /* Copy data while converting to host byte order */ REVERSE32(*data++,W256[j]); /* Apply the SHA-256 compression function to update a..h */ T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j]; #else /* BYTE_ORDER == LITTLE_ENDIAN */ /* Apply the SHA-256 compression function to update a..h with copy */ T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++); #endif /* BYTE_ORDER == LITTLE_ENDIAN */ T2 = Sigma0_256(a) + Maj(a, b, c); h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2; j++; } while (j < 16); do { /* Part of the message block expansion: */ s0 = W256[(j+1)&0x0f]; s0 = sigma0_256(s0); s1 = W256[(j+14)&0x0f]; s1 = sigma1_256(s1); /* Apply the SHA-256 compression function to update a..h */ T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); T2 = Sigma0_256(a) + Maj(a, b, c); h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2; j++; } while (j < 64); /* Compute the current intermediate hash value */ context->state[0] += a; context->state[1] += b; context->state[2] += c; context->state[3] += d; context->state[4] += e; context->state[5] += f; context->state[6] += g; context->state[7] += h; /* Clean up */ a = b = c = d = e = f = g = h = T1 = T2 = 0; } #endif /* SHA2_UNROLL_TRANSFORM */ void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) { unsigned int freespace, usedspace; if (len == 0) { /* Calling with no data is valid - we do nothing */ return; } /* Sanity check: */ assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0); usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; if (usedspace > 0) { /* Calculate how much free space is available in the buffer */ freespace = SHA256_BLOCK_LENGTH - usedspace; if (len >= freespace) { /* Fill the buffer completely and process it */ MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); context->bitcount += freespace << 3; len -= freespace; data += freespace; SHA256_Transform(context, (sha2_word32*)context->buffer); } else { /* The buffer is not yet full */ MEMCPY_BCOPY(&context->buffer[usedspace], data, len); context->bitcount += len << 3; /* Clean up: */ usedspace = freespace = 0; return; } } while (len >= SHA256_BLOCK_LENGTH) { /* Process as many complete blocks as we can */ SHA256_Transform(context, (sha2_word32*)data); context->bitcount += SHA256_BLOCK_LENGTH << 3; len -= SHA256_BLOCK_LENGTH; data += SHA256_BLOCK_LENGTH; } if (len > 0) { /* There's left-overs, so save 'em */ MEMCPY_BCOPY(context->buffer, data, len); context->bitcount += len << 3; } /* Clean up: */ usedspace = freespace = 0; } void SHA256_Final(sha2_byte digest[], SHA256_CTX* context) { sha2_word32 *d = (sha2_word32*)digest; unsigned int usedspace; /* Sanity check: */ assert(context != (SHA256_CTX*)0); /* If no digest buffer is passed, we don't bother doing this: */ if (digest != (sha2_byte*)0) { usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; #if BYTE_ORDER == LITTLE_ENDIAN /* Convert FROM host byte order */ REVERSE64(context->bitcount,context->bitcount); #endif if (usedspace > 0) { /* Begin padding with a 1 bit: */ context->buffer[usedspace++] = 0x80; if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) { /* Set-up for the last transform: */ MEMSET_BZERO(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace); } else { if (usedspace < SHA256_BLOCK_LENGTH) { MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace); } /* Do second-to-last transform: */ SHA256_Transform(context, (sha2_word32*)context->buffer); /* And set-up for the last transform: */ MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); } } else { /* Set-up for the last transform: */ MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); /* Begin padding with a 1 bit: */ *context->buffer = 0x80; } /* Set the bit count: */ *(sha2_word64*)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount; /* Final transform: */ SHA256_Transform(context, (sha2_word32*)context->buffer); #if BYTE_ORDER == LITTLE_ENDIAN { /* Convert TO host byte order */ int j; for (j = 0; j < 8; j++) { REVERSE32(context->state[j],context->state[j]); *d++ = context->state[j]; } } #else MEMCPY_BCOPY(d, context->state, SHA256_DIGEST_LENGTH); #endif } /* Clean up state data: */ MEMSET_BZERO(context, sizeof(SHA256_CTX)); usedspace = 0; } char *SHA256_End(SHA256_CTX* context, char buffer[]) { sha2_byte digest[SHA256_DIGEST_LENGTH], *d = digest; int i; /* Sanity check: */ assert(context != (SHA256_CTX*)0); if (buffer != (char*)0) { SHA256_Final(digest, context); for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; *buffer++ = sha2_hex_digits[*d & 0x0f]; d++; } *buffer = (char)0; } else { MEMSET_BZERO(context, sizeof(SHA256_CTX)); } MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH); return buffer; } char* SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) { SHA256_CTX context; SHA256_Init(&context); SHA256_Update(&context, data, len); return SHA256_End(&context, digest); } /*** SHA-512: *********************************************************/ void SHA512_Init(SHA512_CTX* context) { if (context == (SHA512_CTX*)0) { return; } MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH); MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH); context->bitcount[0] = context->bitcount[1] = 0; } #ifdef SHA2_UNROLL_TRANSFORM /* Unrolled SHA-512 round macros: */ #if BYTE_ORDER == LITTLE_ENDIAN #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ REVERSE64(*data++, W512[j]); \ T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ K512[j] + W512[j]; \ (d) += T1, \ (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \ j++ #else /* BYTE_ORDER == LITTLE_ENDIAN */ #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ K512[j] + (W512[j] = *data++); \ (d) += T1; \ (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ j++ #endif /* BYTE_ORDER == LITTLE_ENDIAN */ #define ROUND512(a,b,c,d,e,f,g,h) \ s0 = W512[(j+1)&0x0f]; \ s0 = sigma0_512(s0); \ s1 = W512[(j+14)&0x0f]; \ s1 = sigma1_512(s1); \ T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \ (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \ (d) += T1; \ (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ j++ void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { sha2_word64 a, b, c, d, e, f, g, h, s0, s1; sha2_word64 T1, *W512 = (sha2_word64*)context->buffer; int j; /* Initialize registers with the prev. intermediate value */ a = context->state[0]; b = context->state[1]; c = context->state[2]; d = context->state[3]; e = context->state[4]; f = context->state[5]; g = context->state[6]; h = context->state[7]; j = 0; do { ROUND512_0_TO_15(a,b,c,d,e,f,g,h); ROUND512_0_TO_15(h,a,b,c,d,e,f,g); ROUND512_0_TO_15(g,h,a,b,c,d,e,f); ROUND512_0_TO_15(f,g,h,a,b,c,d,e); ROUND512_0_TO_15(e,f,g,h,a,b,c,d); ROUND512_0_TO_15(d,e,f,g,h,a,b,c); ROUND512_0_TO_15(c,d,e,f,g,h,a,b); ROUND512_0_TO_15(b,c,d,e,f,g,h,a); } while (j < 16); /* Now for the remaining rounds up to 79: */ do { ROUND512(a,b,c,d,e,f,g,h); ROUND512(h,a,b,c,d,e,f,g); ROUND512(g,h,a,b,c,d,e,f); ROUND512(f,g,h,a,b,c,d,e); ROUND512(e,f,g,h,a,b,c,d); ROUND512(d,e,f,g,h,a,b,c); ROUND512(c,d,e,f,g,h,a,b); ROUND512(b,c,d,e,f,g,h,a); } while (j < 80); /* Compute the current intermediate hash value */ context->state[0] += a; context->state[1] += b; context->state[2] += c; context->state[3] += d; context->state[4] += e; context->state[5] += f; context->state[6] += g; context->state[7] += h; /* Clean up */ a = b = c = d = e = f = g = h = T1 = 0; } #else /* SHA2_UNROLL_TRANSFORM */ void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { sha2_word64 a, b, c, d, e, f, g, h, s0, s1; sha2_word64 T1, T2, *W512 = (sha2_word64*)context->buffer; int j; /* Initialize registers with the prev. intermediate value */ a = context->state[0]; b = context->state[1]; c = context->state[2]; d = context->state[3]; e = context->state[4]; f = context->state[5]; g = context->state[6]; h = context->state[7]; j = 0; do { #if BYTE_ORDER == LITTLE_ENDIAN /* Convert TO host byte order */ REVERSE64(*data++, W512[j]); /* Apply the SHA-512 compression function to update a..h */ T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j]; #else /* BYTE_ORDER == LITTLE_ENDIAN */ /* Apply the SHA-512 compression function to update a..h with copy */ T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++); #endif /* BYTE_ORDER == LITTLE_ENDIAN */ T2 = Sigma0_512(a) + Maj(a, b, c); h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2; j++; } while (j < 16); do { /* Part of the message block expansion: */ s0 = W512[(j+1)&0x0f]; s0 = sigma0_512(s0); s1 = W512[(j+14)&0x0f]; s1 = sigma1_512(s1); /* Apply the SHA-512 compression function to update a..h */ T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); T2 = Sigma0_512(a) + Maj(a, b, c); h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2; j++; } while (j < 80); /* Compute the current intermediate hash value */ context->state[0] += a; context->state[1] += b; context->state[2] += c; context->state[3] += d; context->state[4] += e; context->state[5] += f; context->state[6] += g; context->state[7] += h; /* Clean up */ a = b = c = d = e = f = g = h = T1 = T2 = 0; } #endif /* SHA2_UNROLL_TRANSFORM */ void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) { unsigned int freespace, usedspace; if (len == 0) { /* Calling with no data is valid - we do nothing */ return; } /* Sanity check: */ assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0); usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; if (usedspace > 0) { /* Calculate how much free space is available in the buffer */ freespace = SHA512_BLOCK_LENGTH - usedspace; if (len >= freespace) { /* Fill the buffer completely and process it */ MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); ADDINC128(context->bitcount, freespace << 3); len -= freespace; data += freespace; SHA512_Transform(context, (sha2_word64*)context->buffer); } else { /* The buffer is not yet full */ MEMCPY_BCOPY(&context->buffer[usedspace], data, len); ADDINC128(context->bitcount, len << 3); /* Clean up: */ usedspace = freespace = 0; return; } } while (len >= SHA512_BLOCK_LENGTH) { /* Process as many complete blocks as we can */ SHA512_Transform(context, (sha2_word64*)data); ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3); len -= SHA512_BLOCK_LENGTH; data += SHA512_BLOCK_LENGTH; } if (len > 0) { /* There's left-overs, so save 'em */ MEMCPY_BCOPY(context->buffer, data, len); ADDINC128(context->bitcount, len << 3); } /* Clean up: */ usedspace = freespace = 0; } void SHA512_Last(SHA512_CTX* context) { unsigned int usedspace; usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; #if BYTE_ORDER == LITTLE_ENDIAN /* Convert FROM host byte order */ REVERSE64(context->bitcount[0],context->bitcount[0]); REVERSE64(context->bitcount[1],context->bitcount[1]); #endif if (usedspace > 0) { /* Begin padding with a 1 bit: */ context->buffer[usedspace++] = 0x80; if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) { /* Set-up for the last transform: */ MEMSET_BZERO(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace); } else { if (usedspace < SHA512_BLOCK_LENGTH) { MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace); } /* Do second-to-last transform: */ SHA512_Transform(context, (sha2_word64*)context->buffer); /* And set-up for the last transform: */ MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2); } } else { /* Prepare for final transform: */ MEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LENGTH); /* Begin padding with a 1 bit: */ *context->buffer = 0x80; } /* Store the length of input data (in bits): */ *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1]; *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0]; /* Final transform: */ SHA512_Transform(context, (sha2_word64*)context->buffer); } void SHA512_Final(sha2_byte digest[], SHA512_CTX* context) { sha2_word64 *d = (sha2_word64*)digest; /* Sanity check: */ assert(context != (SHA512_CTX*)0); /* If no digest buffer is passed, we don't bother doing this: */ if (digest != (sha2_byte*)0) { SHA512_Last(context); /* Save the hash data for output: */ #if BYTE_ORDER == LITTLE_ENDIAN { /* Convert TO host byte order */ int j; for (j = 0; j < 8; j++) { REVERSE64(context->state[j],context->state[j]); *d++ = context->state[j]; } } #else MEMCPY_BCOPY(d, context->state, SHA512_DIGEST_LENGTH); #endif } /* Zero out state data */ MEMSET_BZERO(context, sizeof(SHA512_CTX)); } char *SHA512_End(SHA512_CTX* context, char buffer[]) { sha2_byte digest[SHA512_DIGEST_LENGTH], *d = digest; int i; /* Sanity check: */ assert(context != (SHA512_CTX*)0); if (buffer != (char*)0) { SHA512_Final(digest, context); for (i = 0; i < SHA512_DIGEST_LENGTH; i++) { *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; *buffer++ = sha2_hex_digits[*d & 0x0f]; d++; } *buffer = (char)0; } else { MEMSET_BZERO(context, sizeof(SHA512_CTX)); } MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH); return buffer; } char* SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) { SHA512_CTX context; SHA512_Init(&context); SHA512_Update(&context, data, len); return SHA512_End(&context, digest); } /*** SHA-384: *********************************************************/ void SHA384_Init(SHA384_CTX* context) { if (context == (SHA384_CTX*)0) { return; } MEMCPY_BCOPY(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH); MEMSET_BZERO(context->buffer, SHA384_BLOCK_LENGTH); context->bitcount[0] = context->bitcount[1] = 0; } void SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) { SHA512_Update((SHA512_CTX*)context, data, len); } void SHA384_Final(sha2_byte digest[], SHA384_CTX* context) { sha2_word64 *d = (sha2_word64*)digest; /* Sanity check: */ assert(context != (SHA384_CTX*)0); /* If no digest buffer is passed, we don't bother doing this: */ if (digest != (sha2_byte*)0) { SHA512_Last((SHA512_CTX*)context); /* Save the hash data for output: */ #if BYTE_ORDER == LITTLE_ENDIAN { /* Convert TO host byte order */ int j; for (j = 0; j < 6; j++) { REVERSE64(context->state[j],context->state[j]); *d++ = context->state[j]; } } #else MEMCPY_BCOPY(d, context->state, SHA384_DIGEST_LENGTH); #endif } /* Zero out state data */ MEMSET_BZERO(context, sizeof(SHA384_CTX)); } char *SHA384_End(SHA384_CTX* context, char buffer[]) { sha2_byte digest[SHA384_DIGEST_LENGTH], *d = digest; int i; /* Sanity check: */ assert(context != (SHA384_CTX*)0); if (buffer != (char*)0) { SHA384_Final(digest, context); for (i = 0; i < SHA384_DIGEST_LENGTH; i++) { *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; *buffer++ = sha2_hex_digits[*d & 0x0f]; d++; } *buffer = (char)0; } else { MEMSET_BZERO(context, sizeof(SHA384_CTX)); } MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH); return buffer; } char* SHA384_Data(const sha2_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) { SHA384_CTX context; SHA384_Init(&context); SHA384_Update(&context, data, len); return SHA384_End(&context, digest); } #endif /* !HAVE_OPENSSL_SHA */ snort-2.9.15.1/src/sfutil/sha2.h0000644000175200017520000001416213571422607013157 00000000000000/* * FILE: sha2.h * AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/ * * Copyright (c) 2000-2001, Aaron D. Gifford * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holder nor the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``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 OR CONTRIBUTOR(S) 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. * * $Id$ */ #include "config.h" #ifndef HAVE_OPENSSL_SHA #ifndef __SHA2_H__ #define __SHA2_H__ #ifdef __cplusplus extern "C" { #endif /* * Import u_intXX_t size_t type definitions from system headers. You * may need to change this, or define these things yourself in this * file. */ #include #ifdef SHA2_USE_INTTYPES_H #include #endif /* SHA2_USE_INTTYPES_H */ /*** SHA-256/384/512 Various Length Definitions ***********************/ #define SHA256_BLOCK_LENGTH 64 #define SHA256_DIGEST_LENGTH 32 #define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) #define SHA384_BLOCK_LENGTH 128 #define SHA384_DIGEST_LENGTH 48 #define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1) #define SHA512_BLOCK_LENGTH 128 #define SHA512_DIGEST_LENGTH 64 #define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) /*** SHA-256/384/512 Context Structures *******************************/ /* NOTE: If your architecture does not define either u_intXX_t types or * uintXX_t (from inttypes.h), you may need to define things by hand * for your system: */ /* * Most BSD systems already define u_intXX_t types, as does Linux. * Some systems, however, like Compaq's Tru64 Unix instead can use * uintXX_t types defined by very recent ANSI C standards and included * in the file: * * #include * * If you choose to use then please define: * * #define SHA2_USE_INTTYPES_H * * Or on the command line during compile: * * cc -DSHA2_USE_INTTYPES_H ... */ #ifdef SHA2_USE_INTTYPES_H typedef struct _SHA256_CTX { uint32_t state[8]; uint64_t bitcount; uint8_t buffer[SHA256_BLOCK_LENGTH]; } SHA256_CTX; typedef struct _SHA512_CTX { uint64_t state[8]; uint64_t bitcount[2]; uint8_t buffer[SHA512_BLOCK_LENGTH]; } SHA512_CTX; #else /* SHA2_USE_INTTYPES_H */ typedef struct _SHA256_CTX { u_int32_t state[8]; u_int64_t bitcount; u_int8_t buffer[SHA256_BLOCK_LENGTH]; } SHA256_CTX; typedef struct _SHA512_CTX { u_int64_t state[8]; u_int64_t bitcount[2]; u_int8_t buffer[SHA512_BLOCK_LENGTH]; } SHA512_CTX; #endif /* SHA2_USE_INTTYPES_H */ typedef SHA512_CTX SHA384_CTX; /*** SHA-256/384/512 Function Prototypes ******************************/ #ifndef NOPROTO #ifdef SHA2_USE_INTTYPES_H void SHA256_Init(SHA256_CTX *); void SHA256_Update(SHA256_CTX*, const uint8_t*, size_t); void SHA256_Final(uint8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*); char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); char* SHA256_Data(const uint8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); void SHA384_Init(SHA384_CTX*); void SHA384_Update(SHA384_CTX*, const uint8_t*, size_t); void SHA384_Final(uint8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*); char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); char* SHA384_Data(const uint8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); void SHA512_Init(SHA512_CTX*); void SHA512_Update(SHA512_CTX*, const uint8_t*, size_t); void SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*); char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); char* SHA512_Data(const uint8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); #else /* SHA2_USE_INTTYPES_H */ void SHA256_Init(SHA256_CTX *); void SHA256_Update(SHA256_CTX*, const u_int8_t*, size_t); void SHA256_Final(u_int8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*); char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); char* SHA256_Data(const u_int8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); void SHA384_Init(SHA384_CTX*); void SHA384_Update(SHA384_CTX*, const u_int8_t*, size_t); void SHA384_Final(u_int8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*); char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); char* SHA384_Data(const u_int8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); void SHA512_Init(SHA512_CTX*); void SHA512_Update(SHA512_CTX*, const u_int8_t*, size_t); void SHA512_Final(u_int8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*); char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); char* SHA512_Data(const u_int8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); #endif /* SHA2_USE_INTTYPES_H */ #else /* NOPROTO */ void SHA256_Init(); void SHA256_Update(); void SHA256_Final(); char* SHA256_End(); char* SHA256_Data(); void SHA384_Init(); void SHA384_Update(); void SHA384_Final(); char* SHA384_End(); char* SHA384_Data(); void SHA512_Init(); void SHA512_Update(); void SHA512_Final(); char* SHA512_End(); char* SHA512_Data(); #endif /* NOPROTO */ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* __SHA2_H__ */ #endif /* !HAVE_OPENSSL_SHA */ snort-2.9.15.1/src/win32/0000755000000000000000000000000013571426517011627 500000000000000snort-2.9.15.1/src/win32/WIN32-Code/0000755000000000000000000000000013571426517013301 500000000000000snort-2.9.15.1/src/win32/WIN32-Code/getopt.c0000644000175200017520000001375513571422607014734 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifdef SNORT_GETOPT #include /* for EOF */ #include /* for strchr() */ #include "getopt.h" /* static (global) variables that are specified as exported by getopt() */ char *optarg = NULL; /* pointer to the start of the option argument */ int optind = 1; /* number of the next argv[] to be evaluated */ int opterr = 1; /* non-zero if a question mark should be returned when a non-valid option character is detected */ int optopt; int getopt(int argc, char *argv[], char *opstring) { static char *pIndexPosition = NULL; /* place inside current argv string */ char *pArgString = NULL; /* where to start from next */ char *pOptString; /* the string in our program */ if (pIndexPosition != NULL) { /* we last left off inside an argv string */ if (*(++pIndexPosition)) { /* there is more to come in the most recent argv */ pArgString = pIndexPosition; } } if (pArgString == NULL) { /* we didn't leave off in the middle of an argv string */ if (optind >= argc) { /* more command-line arguments than the argument count */ pIndexPosition = NULL; /* not in the middle of anything */ return EOF; /* used up all command-line arguments */ } /*--------------------------------------------------------------------- * If the next argv[] is not an option, there can be no more options. *-------------------------------------------------------------------*/ pArgString = argv[optind++]; /* set this to the next argument ptr */ if (('/' != *pArgString) && /* doesn't start with a slash or a dash? */ ('-' != *pArgString)) { --optind; /* point to current arg once we're done */ optarg = NULL; /* no argument follows the option */ pIndexPosition = NULL; /* not in the middle of anything */ return EOF; /* used up all the command-line flags */ } /* check for special end-of-flags markers */ if ((strcmp(pArgString, "-") == 0) || (strcmp(pArgString, "--") == 0)) { optarg = NULL; /* no argument follows the option */ pIndexPosition = NULL; /* not in the middle of anything */ return EOF; /* encountered the special flag */ } pArgString++; /* look past the / or - */ } if (':' == *pArgString) { /* is it a colon? */ /*--------------------------------------------------------------------- * Rare case: if opterr is non-zero, return a question mark; * otherwise, just return the colon we're on. *-------------------------------------------------------------------*/ return (opterr ? (int)'?' : (int)':'); } else if ((pOptString = strchr(opstring, *pArgString)) == 0) { /*--------------------------------------------------------------------- * The letter on the command-line wasn't any good. *-------------------------------------------------------------------*/ optarg = NULL; /* no argument follows the option */ pIndexPosition = NULL; /* not in the middle of anything */ return (opterr ? (int)'?' : (int)*pArgString); } else { /*--------------------------------------------------------------------- * The letter on the command-line matches one we expect to see *-------------------------------------------------------------------*/ if (':' == _next_char(pOptString)) { /* is the next letter a colon? */ /* It is a colon. Look for an argument string. */ if ('\0' != _next_char(pArgString)) { /* argument in this argv? */ optarg = &pArgString[1]; /* Yes, it is */ } else { /*------------------------------------------------------------- * The argument string must be in the next argv. * But, what if there is none (bad input from the user)? * In that case, return the letter, and optarg as NULL. *-----------------------------------------------------------*/ if (optind < argc) optarg = argv[optind++]; else { optarg = NULL; return (opterr ? (int)'?' : (int)*pArgString); } } pIndexPosition = NULL; /* not in the middle of anything */ } else { /* it's not a colon, so just return the letter */ optarg = NULL; /* no argument follows the option */ pIndexPosition = pArgString; /* point to the letter we're on */ } return (int)*pArgString; /* return the letter that matched */ } } #endif snort-2.9.15.1/src/win32/WIN32-Code/getopt_long.c0000644000175200017520000006142713571422607015752 00000000000000/* Getopt for GNU. NOTE: getopt is now part of the C library, so if you don't know what "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu before changing it! Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it 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. */ /* This tells Alpha OSF/1 not to define a getopt prototype in . Ditto for AIX 3.2 and . */ #ifndef _NO_PROTO #define _NO_PROTO #endif #include #ifdef HAVE_CONFIG_H #if defined (emacs) || defined (CONFIG_BROKETS) /* We use instead of "config.h" so that a compilation using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h (which it would do because it found this file in $srcdir). */ #include #else #include "config.h" #endif #endif #ifndef __STDC__ /* This is a separate conditional since some stdc systems reject `defined (const)'. */ #ifndef const #define const #endif #endif #ifdef HAVE_STRING_H #include #endif /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #if defined (_LIBC) || !defined (__GNU_LIBRARY__) /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ /* Don't include stdlib.h for non-GNU C libraries because some of them contain conflicting prototypes for getopt. */ #include #endif /* GNU C library. */ /* This version of `getopt' appears to the caller like standard Unix `getopt' but it behaves differently for the user, since it allows the user to intersperse the options with the other arguments. As `getopt' works, it permutes the elements of ARGV so that, when it is done, all the options precede everything else. Thus all application programs are extended to handle flexible argument order. Setting the environment variable POSIXLY_CORRECT disables permutation. Then the behavior is completely standard. GNU application programs can use a third alternative mode in which they can distinguish the relative order of options and other arguments. */ #include "getopt1.h" /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ char *optarg = NULL; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns EOF, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ /* XXX 1003.2 says this must be 1 before any call. */ int optind = 0; /* The next char to be scanned in the option-element in which the last option character we returned was found. This allows us to pick up the scan where we left off. If this is zero, or a null string, it means resume the scan by advancing to the next ARGV-element. */ static char *nextchar; /* Callers store zero here to inhibit the error message for unrecognized options. */ int opterr = 1; /* Set to an option character which was unrecognized. This must be initialized on some systems to avoid linking in the system's own getopt implementation. */ int optopt = '?'; /* Describe how to deal with options that follow non-option ARGV-elements. If the caller did not specify anything, the default is REQUIRE_ORDER if the environment variable POSIXLY_CORRECT is defined, PERMUTE otherwise. REQUIRE_ORDER means don't recognize them as options; stop option processing when the first non-option is seen. This is what Unix does. This mode of operation is selected by either setting the environment variable POSIXLY_CORRECT, or using `+' as the first character of the list of option characters. PERMUTE is the default. We permute the contents of ARGV as we scan, so that eventually all the non-options are at the end. This allows options to be given in any order, even with programs that were not written to expect this. RETURN_IN_ORDER is an option available to programs that were written to expect options and other ARGV-elements in any order and that care about the ordering of the two. We describe each non-option ARGV-element as if it were the argument of an option with character code 1. Using `-' as the first character of the list of option characters selects this mode of operation. The special argument `--' forces an end of option-scanning regardless of the value of `ordering'. In the case of RETURN_IN_ORDER, only `--' can cause `getopt' to return EOF with `optind' != ARGC. */ static enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering; /* Value of POSIXLY_CORRECT environment variable. */ static char *posixly_correct; #ifdef __GNU_LIBRARY__ /* We want to avoid inclusion of string.h with non-GNU libraries because there are many ways it can cause trouble. On some systems, it contains special magic macros that don't work in GCC. */ #include #define my_index strchr #else /* Avoid depending on library functions or files whose names are inconsistent. */ #if !defined(_WIN32) char *getenv (); #endif static char * my_index (str, chr) const char *str; int chr; { while (*str) { if (*str == chr) return (char *) str; str++; } return 0; } /* If using GCC, we can safely declare strlen this way. If not using GCC, it is ok not to declare it. */ #ifdef __GNUC__ /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. That was relevant to code that was here before. */ #ifndef __STDC__ /* gcc with -traditional declares the built-in strlen to return int, and has done so at least since version 2.4.5. -- rms. */ extern int strlen (const char *); #endif /* not __STDC__ */ #endif /* __GNUC__ */ #endif /* not __GNU_LIBRARY__ */ /* Handle permutation of arguments. */ /* Describe the part of ARGV that contains non-options that have been skipped. `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is the index after the last of them. */ static int first_nonopt; static int last_nonopt; /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) which contains all the non-options that have been skipped so far. The other is elements [last_nonopt,optind), which contains all the options processed since those non-options were skipped. `first_nonopt' and `last_nonopt' are relocated so that they describe the new indices of the non-options in ARGV after they are moved. */ static void exchange (argv) char **argv; { int bottom = first_nonopt; int middle = last_nonopt; int top = optind; char *tem; /* Exchange the shorter segment with the far end of the longer segment. That puts the shorter segment into the right place. It leaves the longer segment in the right place overall, but it consists of two parts that need to be swapped next. */ while (top > middle && middle > bottom) { if (top - middle > middle - bottom) { /* Bottom segment is the short one. */ int len = middle - bottom; register int i; /* Swap it with the top part of the top segment. */ for (i = 0; i < len; i++) { tem = argv[bottom + i]; argv[bottom + i] = argv[top - (middle - bottom) + i]; argv[top - (middle - bottom) + i] = tem; } /* Exclude the moved bottom segment from further swapping. */ top -= len; } else { /* Top segment is the short one. */ int len = top - middle; register int i; /* Swap it with the bottom part of the bottom segment. */ for (i = 0; i < len; i++) { tem = argv[bottom + i]; argv[bottom + i] = argv[middle + i]; argv[middle + i] = tem; } /* Exclude the moved top segment from further swapping. */ bottom += len; } } /* Update records for the slots the non-options now occupy. */ first_nonopt += (optind - last_nonopt); last_nonopt = optind; } /* Initialize the internal data when the first call is made. */ static const char * _getopt_initialize (optstring) const char *optstring; { /* Start processing options with ARGV-element 1 (since ARGV-element 0 is the program name); the sequence of previously skipped non-option ARGV-elements is empty. */ first_nonopt = last_nonopt = optind = 1; nextchar = NULL; posixly_correct = getenv ("POSIXLY_CORRECT"); /* Determine how to handle the ordering of options and nonoptions. */ if (optstring[0] == '-') { ordering = RETURN_IN_ORDER; ++optstring; } else if (optstring[0] == '+') { ordering = REQUIRE_ORDER; ++optstring; } else if (posixly_correct != NULL) ordering = REQUIRE_ORDER; else ordering = PERMUTE; return optstring; } /* Scan elements of ARGV (whose length is ARGC) for option characters given in OPTSTRING. If an element of ARGV starts with '-', and is not exactly "-" or "--", then it is an option element. The characters of this element (aside from the initial '-') are option characters. If `getopt' is called repeatedly, it returns successively each of the option characters from each of the option elements. If `getopt' finds another option character, it returns that character, updating `optind' and `nextchar' so that the next call to `getopt' can resume the scan with the following option character or ARGV-element. If there are no more option characters, `getopt' returns `EOF'. Then `optind' is the index in ARGV of the first ARGV-element that is not an option. (The ARGV-elements have been permuted so that those that are not options now come last.) OPTSTRING is a string containing the legitimate option characters. If an option character is seen that is not listed in OPTSTRING, return '?' after printing an error message. If you set `opterr' to zero, the error message is suppressed but we still return '?'. If a char in OPTSTRING is followed by a colon, that means it wants an arg, so the following text in the same ARGV-element, or the text of the following ARGV-element, is returned in `optarg'. Two colons mean an option that wants an optional arg; if there is text in the current ARGV-element, it is returned in `optarg', otherwise `optarg' is set to zero. If OPTSTRING starts with `-' or `+', it requests different methods of handling the non-option ARGV-elements. See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. Long-named options begin with `--' instead of `-'. Their names may be abbreviated as long as the abbreviation is unique or is an exact match for some defined option. If they have an argument, it follows the option name in the same ARGV-element, separated from the option name by a `=', or else the in next ARGV-element. When `getopt' finds a long-named option, it returns 0 if that option's `flag' field is nonzero, the value of the option's `val' field if the `flag' field is zero. The elements of ARGV aren't really const, because we permute them. But we pretend they're const in the prototype to be compatible with other systems. LONGOPTS is a vector of `struct option' terminated by an element containing a name which is zero. LONGIND returns the index in LONGOPT of the long-named option found. It is only valid when a long-named option has been found by the most recent call. If LONG_ONLY is nonzero, '-' as well as '--' can introduce long-named options. */ int _getopt_internal (argc, argv, optstring, longopts, longind, long_only) int argc; char *const *argv; const char *optstring; const struct option *longopts; int *longind; int long_only; { optarg = NULL; if (optind == 0) optstring = _getopt_initialize (optstring); if (nextchar == NULL || *nextchar == '\0') { /* Advance to the next ARGV-element. */ if (ordering == PERMUTE) { /* If we have just processed some options following some non-options, exchange them so that the options come first. */ if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (last_nonopt != optind) first_nonopt = optind; /* Skip any additional non-options and extend the range of non-options previously skipped. */ while (optind < argc && (argv[optind][0] != '-' || argv[optind][1] == '\0')) optind++; last_nonopt = optind; } /* The special ARGV-element `--' means premature end of options. Skip it like a null option, then exchange with previous non-options as if it were an option, then skip everything else like a non-option. */ if (optind != argc && !strcmp (argv[optind], "--")) { optind++; if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (first_nonopt == last_nonopt) first_nonopt = optind; last_nonopt = argc; optind = argc; } /* If we have done all the ARGV-elements, stop the scan and back over any non-options that we skipped and permuted. */ if (optind == argc) { /* Set the next-arg-index to point at the non-options that we previously skipped, so the caller will digest them. */ if (first_nonopt != last_nonopt) optind = first_nonopt; return EOF; } /* If we have come to a non-option and did not permute it, either stop the scan or describe it to the caller and pass it by. */ if ((argv[optind][0] != '-' || argv[optind][1] == '\0')) { if (ordering == REQUIRE_ORDER) return EOF; optarg = argv[optind++]; return 1; } /* We have found another option-ARGV-element. Skip the initial punctuation. */ nextchar = (argv[optind] + 1 + (longopts != NULL && argv[optind][1] == '-')); } /* Decode the current option-ARGV-element. */ /* Check whether the ARGV-element is a long option. If long_only and the ARGV-element has the form "-f", where f is a valid short option, don't consider it an abbreviated form of a long option that starts with f. Otherwise there would be no way to give the -f short option. On the other hand, if there's a long option "fubar" and the ARGV-element is "-fu", do consider that an abbreviation of the long option, just like "--fu", and not "-f" with arg "u". This distinction seems to be the most useful approach. */ if (longopts != NULL && (argv[optind][1] == '-' || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) { char *nameend; const struct option *p; const struct option *pfound = NULL; int exact = 0; int ambig = 0; int indfound; int option_index; for (nameend = nextchar; *nameend && *nameend != '='; nameend++) /* Do nothing. */ ; /* Test all long options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) if (!strncmp (p->name, nextchar, nameend - nextchar)) { if (nameend - nextchar == (int) strlen (p->name)) { /* Exact match found. */ pfound = p; indfound = option_index; exact = 1; break; } else if (pfound == NULL) { /* First nonexact match found. */ pfound = p; indfound = option_index; } else /* Second or later nonexact match found. */ ambig = 1; } if (ambig && !exact) { if (opterr) fprintf (stderr, "%s: option `%s' is ambiguous\n", argv[0], argv[optind]); nextchar += strlen (nextchar); optind++; return '?'; } if (pfound != NULL) { option_index = indfound; optind++; if (*nameend) { /* Don't test has_arg with >, because some C compilers don't allow it to be used on enums. */ if (pfound->has_arg) optarg = nameend + 1; else { if (opterr) { if (argv[optind - 1][1] == '-') /* --option */ fprintf (stderr, "%s: option `--%s' doesn't allow an argument\n", argv[0], pfound->name); else /* +option or -option */ fprintf (stderr, "%s: option `%c%s' doesn't allow an argument\n", argv[0], argv[optind - 1][0], pfound->name); } nextchar += strlen (nextchar); return '?'; } } else if (pfound->has_arg == 1) { if (optind < argc) optarg = argv[optind++]; else { if (opterr) fprintf (stderr, "%s: option `%s' requires an argument\n", argv[0], argv[optind - 1]); nextchar += strlen (nextchar); return optstring[0] == ':' ? ':' : '?'; } } nextchar += strlen (nextchar); if (longind != NULL) *longind = option_index; if (pfound->flag) { *(pfound->flag) = pfound->val; return 0; } return pfound->val; } /* Can't find it as a long option. If this is not getopt_long_only, or the option starts with '--' or is not a valid short option, then it's an error. Otherwise interpret it as a short option. */ if (!long_only || argv[optind][1] == '-' || my_index (optstring, *nextchar) == NULL) { if (opterr) { if (argv[optind][1] == '-') /* --option */ fprintf (stderr, "%s: unrecognized option `--%s'\n", argv[0], nextchar); else /* +option or -option */ fprintf (stderr, "%s: unrecognized option `%c%s'\n", argv[0], argv[optind][0], nextchar); } nextchar = (char *) ""; optind++; return '?'; } } /* Look at and handle the next short option-character. */ { char c = *nextchar++; char *temp = my_index (optstring, c); /* Increment `optind' when we start to process its last character. */ if (*nextchar == '\0') ++optind; if (temp == NULL || c == ':') { if (opterr) { if (posixly_correct) /* 1003.2 specifies the format of this message. */ fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c); else fprintf (stderr, "%s: invalid option -- %c\n", argv[0], c); } optopt = c; return '?'; } if (temp[1] == ':') { if (temp[2] == ':') { /* This is an option that accepts an argument optionally. */ if (*nextchar != '\0') { optarg = nextchar; optind++; } else optarg = NULL; nextchar = NULL; } else { /* This is an option that requires an argument. */ if (*nextchar != '\0') { optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg, we must advance to the next element now. */ optind++; } else if (optind == argc) { if (opterr) { /* 1003.2 specifies the format of this message. */ fprintf (stderr, "%s: option requires an argument -- %c\n", argv[0], c); } optopt = c; if (optstring[0] == ':') c = ':'; else c = '?'; } else /* We already incremented `optind' once; increment it again when taking next ARGV-elt as argument. */ optarg = argv[optind++]; nextchar = NULL; } } return c; } } int getopt (argc, argv, optstring) int argc; char *const *argv; const char *optstring; { return _getopt_internal (argc, argv, optstring, (const struct option *) 0, (int *) 0, 0); } /* getopt_long and getopt_long_only entry points for GNU getopt. Copyright (C) 1987, 88, 89, 90, 91, 92, 1993 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it 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. */ int getopt_long (argc, argv, options, long_options, opt_index) int argc; char *const *argv; const char *options; const struct option *long_options; int *opt_index; { return _getopt_internal (argc, argv, options, long_options, opt_index, 0); } /* Like getopt_long, but '-' as well as '--' can indicate a long option. If an option that starts with '-' (not '--') doesn't match a long option, but does match a short option, it is parsed as a short option instead. */ int getopt_long_only (argc, argv, options, long_options, opt_index) int argc; char *const *argv; const char *options; const struct option *long_options; int *opt_index; { return _getopt_internal (argc, argv, options, long_options, opt_index, 1); } #endif /* _LIBC or not __GNU_LIBRARY__. */ snort-2.9.15.1/src/win32/WIN32-Code/inet_aton.c0000644000175200017520000000311413571422607015376 00000000000000/* $Id$ */ /**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2004-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* Convert from "a.b.c.d" IP address string into * an in_addr structure. Returns 0 on failure, * and 1 on success. */ int inet_aton(const char *cp, struct in_addr *addr) { if( cp==NULL || addr==NULL ) { return(0); } /* Because this and INADDR_NONE are the same */ if (strcmp(cp, "255.255.255.255") == 0) { addr->s_addr = 0xffffffff; return 1; } addr->s_addr = inet_addr(cp); return (addr->s_addr == INADDR_NONE) ? 0 : 1; } snort-2.9.15.1/src/win32/WIN32-Code/inet_pton.c0000644000175200017520000000335513571422607015424 00000000000000#ifdef HAVE_CONFIG_H #include #endif int inet_pton(int af, const char *src, void *dst) { u_int16_t ipbuf[8]; u_int32_t val; u_int16_t short_val; char *end_ptr; int i,j; int index = 0; int skip_idx = -1; u_int16_t *dstip = (u_int16_t*)dst; if(!src || !dst) return -1; if(af == AF_INET) { return inet_aton(src, dst); } while(*src) { val = strtoul(src, &end_ptr, 16); if (val > USHRT_MAX) { return -1; } short_val = (u_int16_t)val; if(*src == ':') { src++; if(*src == ':') { if(skip_idx != -1) return -1; skip_idx = index; src++; if(*src && *src == ':') return -1; } else if(!*src) return -1; continue; } else if(*end_ptr == '.') { if(!inet_aton(src, (struct in_addr *)&ipbuf[index])) return -1; index += 2; break; } else { if(end_ptr == src) { return -1; } ipbuf[index++] = htons(short_val); src = end_ptr; /* Check for trailing garbage after the IP */ if(index == 8 && *src) return -1; } } if(index < 8 && skip_idx == -1) return -1; for(i = 0; i < skip_idx; i++) { dstip[i] = ipbuf[i]; } if(skip_idx == -1) skip_idx = 0; for(; i < 8 - (index - skip_idx); i++) { dstip[i] = 0; } for(j = skip_idx; i < 8; i++, j++) { dstip[i] = ipbuf[j]; } return 1; } snort-2.9.15.1/src/win32/WIN32-Code/misc.c0000644000175200017520000001774313571422607014366 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "snort.h" #include "util.h" /**************************************************************************** * * Function: gettimeofday(struct timeval *, struct timezone *) * * Purpose: Get current time of day. * * Arguments: tv => Place to store the curent time of day. * tz => Ignored. * * Returns: 0 => Success. * ****************************************************************************/ int gettimeofday(struct timeval *tv, struct timezone *tz) { struct _timeb tb; if(tv==NULL) { return -1; } _ftime(&tb); tv->tv_sec = (unsigned long)tb.time; tv->tv_usec = ((int) tb.millitm) * 1000; return 0; } /**************************************************************************** * * Function: GetAdapterFromList(void *,int) * * Purpose: Get a specific adapter from the list of adapters on the system. * * Arguments: device => Device to look for. * index => Adapter number. * * Returns: Adapter if device was valid. * * Comments: Shamelessly ripped from WinDump. * ****************************************************************************/ void *GetAdapterFromList(void *device,int index) { DWORD dwVersion; DWORD dwWindowsMajorVersion; char *Adapter95; WCHAR *Adapter; int i; dwVersion = GetVersion(); dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion))); /* Windows 95. */ if (dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4) { Adapter95 = device; for( i=0; i Name of Interface to print. * * Returns: Correct character format of Interface for the current platform. * * Comments: Shamelessly ripped from WinDump. * ****************************************************************************/ char *print_interface(const char *szInterface) { static char device[128]; if (szInterface == NULL) return("NULL"); /* Device always ends with a double \0, so this way to determine its length should be always valid */ if(IsTextUnicode(szInterface, wcslen((wchar_t *)szInterface), NULL)) SnortSnprintf(device, 128, "%S", (wchar_t *)szInterface); else SnortSnprintf(device, 128, "%s", szInterface); return(device); } /**************************************************************************** * * Function: PrintDeviceList(const char *) * * Purpose: Print all interfaces forund on the system that we can listen on. * * Arguments: device => List of all devices to listen on. * * Returns: void function. * * Comments: Shamelessly ripped from WinDump. * ****************************************************************************/ void PrintDeviceList(const char *device) { DWORD dwVersion; DWORD dwWindowsMajorVersion; const WCHAR* t; const char* t95; int i=0; int DescPos=0; char *Desc; int n=1; dwVersion=GetVersion(); dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion))); /* Windows 95. */ if (dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4) { t95 = (char*)device; while(*(t95+DescPos)!=0 || *(t95+DescPos-1)!=0) { DescPos++; } Desc=(char*)t95+DescPos+1; printf("\nInterface\tDevice\t\tDescription\n-------------------------------------------\n"); printf("%d ",n++); while ( ! (t95[i]==0 && t95[i-1]==0) ) { if ( t95[i] == 0 ) { putchar(' '); putchar('('); while( *Desc !=0 ) { putchar(*Desc); Desc++; } Desc++; putchar(')'); putchar('\n'); } else { putchar(t95[i]); } if( (t95[i]==0) && (t95[i+1]!=0) ) { printf("%d ",n++); } i++; } putchar('\n'); } else { /* WinNT. */ t = (WCHAR*) device; while( *(t+DescPos)!=0 || *(t+DescPos-1)!=0 ) { DescPos++; } DescPos <<= 1; Desc = (char*)t+DescPos+2; printf("\nInterface\tDevice\t\tDescription\n-------------------------------------------\n"); printf("%d ",n++); while ( ! ( t[i]==0 && t[i-1]==0 ) ) { if ( t[i] == 0 ) { putchar(' '); putchar('('); while( *Desc != 0 ) { putchar(*Desc); Desc++; } Desc++; putchar(')'); putchar('\n'); } else { putchar(t[i]); } if( t[i]==0 && t[i+1]!=0 ) { printf("%d ",n++); } i++; } putchar('\n'); } } /**************************************************************************** * * Function: init_winsock(void) * * Purpose: Initialize winsock. * * Arguments: None. * * Returns: 0 => Initilization failed. * 1 => Initilization succeeded. * ****************************************************************************/ int init_winsock(void) { WORD wVersionRequested = MAKEWORD(1, 1); WSADATA wsaData; if (WSAStartup(wVersionRequested, &wsaData)) { FatalError("[!]: Unable to find a usable Winsock.\n"); } if (LOBYTE(wsaData.wVersion) < 1 || HIBYTE(wsaData.wVersion) < 1) { FatalError("[!]: Unable to find Winsock version 1.1 or greater. You have version %d.%d.\n", LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion)); //WSACleanup(); //return 0; } return 1; } int geteuid(void) { return 0; } /**************************************************************************** * * Function: ffs(int x) * * Purpose: find first bit set in x * * Arguments: int x => integer in which to find bit * * Returns: bit => position of first LSB that is set in x * ****************************************************************************/ int ffs(int x) { int bit = 1; int mask = 1; if (x == 0) return 0; while ((x & mask) == 0) { mask = mask << 1; bit += 1; } if (bit > (sizeof(int)*8)) bit = 0; return bit; } snort-2.9.15.1/src/win32/WIN32-Code/name.aps0000444000175200017520000000161413571422607014700 00000000000000 ÿÿÿÿ@$HWBÿÿ ¸D:\DEV\SFENG\IMS\SFSNORT\SNORT\SRC\WIN32\WIN32-Code\name.rc€ ÿÿ ÿÿ0  ` %1 $The %1 service was installed. $The %1 service was removed. ,The %1 service could not be removed. 4The control handler could not be installed. ,The initialization process failed. The service was started. 4The service received an unsupported request. Debug: %1 The service was stopped. $HWBÿÿÈ0 !!ãÿ$HWBÿÿÉ0 $HWBÿÿÊ0 111$ÿÿ$ÿÿ°$HWBÿÿ0 @DHWBÿÿ €¤ÿÿ ÿÿ0 HHWBÿÿÈ0 €HWBÿÿÉ0 ¤HWBÿÿÊ0 snort-2.9.15.1/src/win32/WIN32-Code/name.h0000644000175200017520000000665113571422607014354 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2003-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ // // Values are 32 bit values layed out as follows: // // 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 // +---+-+-+-----------------------+-------------------------------+ // |Sev|C|R| Facility | Code | // +---+-+-+-----------------------+-------------------------------+ // // where // // Sev - is the severity code // // 00 - Success // 01 - Informational // 10 - Warning // 11 - Error // // C - is the Customer code flag // // R - is a reserved bit // // Facility - is the facility code // // Code - is the facility's status code // // // Define the facility codes // // // Define the severity codes // // // MessageId: EVMSG_SIMPLE // // MessageText: // // %1 // #define EVMSG_SIMPLE ((WORD)0x00000001L) // // MessageId: EVMSG_INSTALLED // // MessageText: // // The %1 service was installed. // #define EVMSG_INSTALLED ((WORD)0x00000002L) // // MessageId: EVMSG_REMOVED // // MessageText: // // The %1 service was removed. // #define EVMSG_REMOVED ((WORD)0x00000003L) // // MessageId: EVMSG_NOTREMOVED // // MessageText: // // The %1 service could not be removed. // #define EVMSG_NOTREMOVED ((WORD)0x00000004L) // // MessageId: EVMSG_CTRLHANDLERNOTINSTALLED // // MessageText: // // The control handler could not be installed. // #define EVMSG_CTRLHANDLERNOTINSTALLED ((WORD)0x00000005L) // // MessageId: EVMSG_FAILEDINIT // // MessageText: // // The initialization process failed. // #define EVMSG_FAILEDINIT ((WORD)0x00000006L) // // MessageId: EVMSG_STARTED // // MessageText: // // The service was started. // #define EVMSG_STARTED ((WORD)0x00000007L) // // MessageId: EVMSG_BADREQUEST // // MessageText: // // The service received an unsupported request. // #define EVMSG_BADREQUEST ((WORD)0x00000008L) // // MessageId: EVMSG_DEBUG // // MessageText: // // Debug: %1 // #define EVMSG_DEBUG ((WORD)0x00000009L) // // MessageId: EVMSG_STOPPED // // MessageText: // // The service was stopped. // #define EVMSG_STOPPED ((WORD)0x00000010L) snort-2.9.15.1/src/win32/WIN32-Code/name.mc0000444000175200017520000000172413571422607014516 00000000000000MessageIdTypedef=WORD MessageId=0x1 SymbolicName=EVMSG_SIMPLE Language=English %1 . MessageId=0x2 SymbolicName=EVMSG_INSTALLED Language=English The %1 service was installed. . MessageId=0x3 SymbolicName=EVMSG_REMOVED Language=English The %1 service was removed. . MessageId=0x4 SymbolicName=EVMSG_NOTREMOVED Language=English The %1 service could not be removed. . MessageId=0x5 SymbolicName=EVMSG_CTRLHANDLERNOTINSTALLED Language=English The control handler could not be installed. . MessageId=0x6 SymbolicName=EVMSG_FAILEDINIT Language=English The initialization process failed. . MessageId=0x7 SymbolicName=EVMSG_STARTED Language=English The service was started. . MessageId=0x8 SymbolicName=EVMSG_BADREQUEST Language=English The service received an unsupported request. . MessageId=0x9 SymbolicName=EVMSG_DEBUG Language=English Debug: %1 . MessageId=0x10 SymbolicName=EVMSG_STOPPED Language=English The service was stopped. . snort-2.9.15.1/src/win32/WIN32-Code/name.rc0000444000175200017520000000004513571422607014516 00000000000000LANGUAGE 0x9,0x1 1 11 MSG00001.bin snort-2.9.15.1/src/win32/WIN32-Code/MSG00001.bin0000444000175200017520000000060013571422607014746 00000000000000 ` %1 $The %1 service was installed. $The %1 service was removed. ,The %1 service could not be removed. 4The control handler could not be installed. ,The initialization process failed. The service was started. 4The service received an unsupported request. Debug: %1 The service was stopped. snort-2.9.15.1/src/win32/WIN32-Code/strtok_r.c0000644000175200017520000000414213571422607015267 00000000000000/* $Id$ */ /* * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include /* $KTH: strtok_r.c,v 1.5 1999/12/02 16:58:53 joda Exp $" */ #endif #include #ifndef HAVE_STRTOK_R char * strtok_r(char *s1, const char *s2, char **lasts) { char *ret; if (s1 == NULL) s1 = *lasts; while(*s1 && strchr(s2, *s1)) ++s1; if(*s1 == '\0') return NULL; ret = s1; while(*s1 && !strchr(s2, *s1)) ++s1; if(*s1) *s1++ = '\0'; *lasts = s1; return ret; } #endif /* HAVE_STRTOK_R */ snort-2.9.15.1/src/win32/WIN32-Code/syslog.c0000644000175200017520000002654113571422607014747 00000000000000/* $Id$ */ /* -/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/ . Copyright (c) 2001 Michael Davis . All rights reserved. . . Redistribution and use in source and binary forms, with or without . modification, are permitted provided that the following conditions . are met: . . 1. Redistributions of source code must retain the above copyright . notice, this list of conditions and the following disclaimer. . . 2. Redistributions in binary form must reproduce the above copyright . notice, this list of conditions and the following disclaimer in the . documentation and/or other materials provided with the distribution. . . 3. The name of author may not be used to endorse or promote products . derived from this software without specific prior written permission. . . THIS SOFTWARE IS PROVIDED ``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. . -\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\ */ #define _WINSOCKAPI_ /* Prevent inclusion of winsock.h in windows.h */ #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "name.h" #include "syslog.h" #include "snort.h" #include "util.h" #define TBUF_LEN 2048 #define FMT_LEN 1024 #define INTERNALLOG LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID static int LogFile = -1; /* fd for log */ static int opened; /* have done openlog() */ static int LogStat = 0; /* status bits, set by openlog() */ static char *LogTag = NULL; /* string to tag the entry with */ static int LogFacility = LOG_USER; /* default facility code */ static int LogMask = 0xff; /* mask of priorities to be logged */ void syslog(int pri, char *fmt, ...) { va_list ap; va_start(ap, fmt); vsyslog(pri, fmt, ap); va_end(ap); } void vsyslog(int pri, char *fmt, va_list ap){ char *p, *t; register int cnt; int tbuf_left, fmt_left, prlen, saved_errno; char *stdp, tbuf[TBUF_LEN], fmt_cpy[FMT_LEN]; time_t now; SOCKET sockfd; struct sockaddr_in sin; HANDLE hEventLog; /* handle to the Event Log. */ char *syslog_server = NULL; char host_buf[256]; /* Log to Event Log. */ if (!ScLogSyslogRemote()) { p = tbuf; tbuf_left = TBUF_LEN; saved_errno = errno; /* * We wouldn't need this mess if printf handled %m, or if * strerror() had been invented before syslog(). */ for (t = fmt_cpy, fmt_left = FMT_LEN; *fmt != '\0' && fmt_left > 1; fmt++) { if (*fmt == '%' && *(fmt + 1) == 'm') { fmt++; SnortSnprintf(t, fmt_left, "%s", strerror(saved_errno)); prlen = SnortStrnlen(t, fmt_left); t += prlen; fmt_left -= prlen; } else { if (fmt_left > 1) { *t++ = *fmt; fmt_left--; } } } *t = '\0'; fmt_cpy[FMT_LEN - 1] = '\0'; vsnprintf(p, tbuf_left, fmt_cpy, ap); p[tbuf_left - 1] = '\0'; /* Get connected, output the message to the local logger. */ if (!opened) openlog(LogTag, LogStat, 0); if ((strlen(snort_conf->syslog_server) != 0) && resolve_host(snort_conf->syslog_server)) { syslog_server = snort_conf->syslog_server; } hEventLog = RegisterEventSource(syslog_server, LogTag); if (hEventLog == NULL) return; /* Now, actually report it. */ ReportEvent( hEventLog , EVENTLOG_WARNING_TYPE , 0 , EVMSG_SIMPLE , NULL , 1 , 0 , (char **)&p , NULL); DeregisterEventSource(hEventLog); return; } /* Check for invalid bits. */ if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) { syslog(INTERNALLOG, "syslog: unknown facility/priority: %x", pri); pri &= LOG_PRIMASK|LOG_FACMASK; } /* Check priority against setlogmask values. */ if (!(LOG_MASK(LOG_PRI(pri)) & LogMask)) return; saved_errno = errno; /* Set default facility if none specified. */ if ((pri & LOG_FACMASK) == 0) pri |= LogFacility; /* Build the message. */ /* * Although it's tempting, we can't ignore the possibility of * overflowing the buffer when assembling the "fixed" portion * of the message. Strftime's "%h" directive expands to the * locale's abbreviated month name, but if the user has the * ability to construct to his own locale files, it may be * arbitrarily long. */ (void)time(&now); p = tbuf; tbuf_left = TBUF_LEN; #define DEC() \ do { \ if (prlen >= tbuf_left) \ prlen = tbuf_left - 1; \ p += prlen; \ tbuf_left -= prlen; \ } while (0) SnortSnprintf(p, tbuf_left, "<%d>", pri); prlen = SnortStrnlen(p, tbuf_left); DEC(); prlen = strftime(p, tbuf_left, "%b %d %H:%M:%S ", localtime(&now)); DEC(); if (gethostname(host_buf, sizeof(host_buf)) == 0) { SnortSnprintf(p, tbuf_left, "%s ", host_buf); prlen = SnortStrnlen(p, tbuf_left); DEC(); } if (LogStat & LOG_PERROR) stdp = p; if (LogTag == NULL) LogTag = VERSION; if (LogTag != NULL) { SnortSnprintf(p, tbuf_left, "%s", LogTag); prlen = SnortStrnlen(p, tbuf_left); DEC(); } if (LogStat & LOG_PID) { SnortSnprintf(p, tbuf_left, "[%d]", getpid()); prlen = SnortStrnlen(p, tbuf_left); DEC(); } if (LogTag != NULL) { if (tbuf_left > 1) { *p++ = ':'; tbuf_left--; } if (tbuf_left > 1) { *p++ = ' '; tbuf_left--; } } /* * We wouldn't need this mess if printf handled %m, or if * strerror() had been invented before syslog(). */ for (t = fmt_cpy, fmt_left = FMT_LEN; *fmt != '\0' && fmt_left > 1; fmt++) { if (*fmt == '%' && *(fmt + 1) == 'm') { fmt++; SnortSnprintf(t, fmt_left, "%s", strerror(saved_errno)); prlen = SnortStrnlen(t, fmt_left); if (prlen >= fmt_left) prlen = fmt_left - 1; t += prlen; fmt_left -= prlen; } else { if (fmt_left > 1) { *t++ = *fmt; fmt_left--; } } } *t = '\0'; fmt_cpy[FMT_LEN - 1] = '\0'; prlen = vsnprintf(p, tbuf_left, fmt_cpy, ap); p[tbuf_left - 1] = '\0'; DEC(); cnt = p - tbuf; /* Connect to Target server. */ if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == SOCKET_ERROR) { ErrorMessage("[!] ERROR: Could not create the socket to send the " "syslog alert. Error Number: %d.\n", WSAGetLastError()); return; } sin.sin_port = htons((u_short)snort_conf->syslog_server_port); sin.sin_family = AF_INET; sin.sin_addr.s_addr = resolve_host(snort_conf->syslog_server); if (!sin.sin_addr.s_addr) { ErrorMessage("[!] ERROR: Could not resolve syslog server's hostname. " "Error Number: %d.\n", WSAGetLastError()); closesocket(sockfd); return; } if(sendto(sockfd,tbuf,cnt,(int)NULL, (SOCKADDR *)&sin, sizeof(SOCKADDR_IN)) == SOCKET_ERROR) { ErrorMessage("[!] ERROR: Could not send the alert to the syslog " "server. Error Number: %d.\n", WSAGetLastError()); closesocket(sockfd); return; } closesocket(sockfd); } void openlog(char *ident, int logstat, int logfac){ if(ident != NULL){ LogTag = ident; LogStat = logstat; if (logfac != 0 && (logfac & ~LOG_FACMASK) == 0) LogFacility = logfac; /* Add the registry key each time openlog is called. */ AddEventSource(ident); } opened = 1; } /* Taken from MSDN. */ void AddEventSource(char *ident) { HKEY hk; DWORD dwData; char szFilePath[_MAX_PATH]; char key[_MAX_PATH]; // Add your source name as a subkey under the Application // key in the EventLog registry key. SnortSnprintf(key, sizeof(key), "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\%s", ident); if (RegCreateKey(HKEY_LOCAL_MACHINE, key, &hk)) { printf("Could not create the registry key."); exit(-1); } // Set the name of the message file. GetModuleFileName(NULL, szFilePath, sizeof(szFilePath)); szFilePath[ sizeof(szFilePath)-1 ] = 0; // Add the name to the EventMessageFile subkey. if (RegSetValueEx(hk, // subkey handle "EventMessageFile", // value name 0, // must be zero REG_EXPAND_SZ, // value type (LPBYTE) szFilePath, // pointer to value data strlen(szFilePath) + 1)) { // length of value data printf("Could not set the event message file."); exit(-1); } // Set the supported event types in the TypesSupported subkey. dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE | EVENTLOG_AUDIT_SUCCESS | EVENTLOG_AUDIT_FAILURE; if (RegSetValueEx(hk, // subkey handle "TypesSupported", // value name 0, // must be zero REG_DWORD, // value type (LPBYTE) &dwData, // pointer to value data sizeof(DWORD))){ // length of value data printf("Could not set the supported types."); exit(-1); } RegCloseKey(hk); } unsigned long resolve_host(char *host) { struct hostent *he; unsigned long ip; if (inet_addr(host) == INADDR_NONE) { he = gethostbyname(host); if (!he) { printf("Unable to resolve address: %s", host); return 0; } else { /* protecting against malicious DNS servers */ if (he->h_length < 0) { printf("Unable to resolve address: %s", host); return 0; } if(he->h_length <= sizeof(unsigned long)) { memcpy((char FAR *)&(ip), he->h_addr, he->h_length); } else { memcpy((char FAR *)&(ip), he->h_addr, sizeof(unsigned long)); } } } else { ip = inet_addr(host); } return ip; } snort-2.9.15.1/src/win32/WIN32-Code/win32_service.c0000644000175200017520000012145013571422607016104 00000000000000/* $Id$ */ /* ** Copyright (C) 2002 Chris Reid ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * win32_service.c v1.0 - 20 February 2002 * * Purpose: Lets Snort register as a Win32 Service. This includes both * an installation an uninstallation aspect. * * Author: Chris Reid (chris.reid@codecraftconsulants.com) * * Notes: The Snort command-line arguments need to be * saved into the registry when the snort service is * being installed. They are stored in: * HKLM \ SOFTWARE \ Snort * * Usage: * snort.exe /SERVICE /INSTALL [regular command-line params] * * snort.exe /SERVICE /UNINSTALL * * snort.exe /SERVICE /SHOW * * References * Microsoft has full docs on programming Win32 Services in their * MSDN (Microsoft Developer Network) library. * http://msdn.microsoft.com/ */ #ifdef ENABLE_WIN32_SERVICE /* * Enable the next line to automatically assign a description to the Service. * According to the Microsoft documentation, the call to ChangeServiceConfig2() * which sets the description is only available on Windows 2000 or newer. * * #define SET_SERVICE_DESCRIPTION */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include /* for Service stuff */ #include /* for printf(), etc */ #include /* for _getcwd() */ #include #include "snort.h" #include "snort_debug.h" #include "util.h" static LPTSTR g_lpszServiceName = "SnortSvc"; static LPTSTR g_lpszServiceDisplayName = "Snort"; static LPTSTR g_lpszServiceDescription = "The Open Source Network Intrusion Detection System"; static LPTSTR g_lpszRegistryKey = "SOFTWARE\\Snort"; static LPTSTR g_lpszRegistryCmdFormat = "CmdLineParam_%03d"; static LPTSTR g_lpszRegistryCountFormat= "CmdLineParamCount"; static SERVICE_STATUS g_SnortServiceStatus; static SERVICE_STATUS_HANDLE g_SnortServiceStatusHandle; #define MAX_REGISTRY_KEY_LENGTH 255 #define MAX_REGISTRY_DATA_LENGTH 1000 static VOID SvcDebugOut(LPSTR String, DWORD Status); static VOID SvcFormatMessage(LPSTR szString, int iCount); static VOID ReadServiceCommandLineParams( int * piArgCounter, char** * pargvDynamic ); static VOID WINAPI SnortServiceStart (DWORD argc, LPTSTR *argv); static VOID WINAPI SnortServiceCtrlHandler (DWORD opcode); static DWORD SnortServiceInitialization (DWORD argc, LPTSTR *argv, DWORD *specificError); static VOID InstallSnortService(int argc, char* argv[]); static VOID UninstallSnortService(); static VOID ShowSnortServiceParams(); /******************************************************************************* * (This documentation was taken from Microsoft's own doc's on how to create * a Win32 Service.) * * Writing a Service Program's main Function * ----------------------------------------------------------------------------- * * The main function of a service program calls the StartServiceCtrlDispatcher * function to connect to the SCM and start the control dispatcher thread. The * dispatcher thread loops, waiting for incoming control requests for the * services specified in the dispatch table. This thread does not return until * there is an error or all of the services in the process have terminated. When * all services in a process have terminated, the SCM sends a control request * to the dispatcher thread telling it to shut down. The thread can then return * from the StartServiceCtrlDispatcher call and the process can terminate. * * The following example is a service process that supports only one service. It * takes two parameters: a string that can contain one formatted output * character and a numeric value to be used as the formatted character. The * SvcDebugOut function prints informational messages and errors to the debugger. * For information on writing the SnortServiceStart and SnortServiceInitialization * functions, see Writing a ServiceMain Function. For information on writing the * SnortServiceCtrlHandler function, see Writing a Control Handler Function. *******************************************************************************/ /* this is the entry point which is called from main() */ int SnortServiceMain(int argc, char* argv[]) { int i; /* SERVICE_TABLE_ENTRY steDispatchTable[] = { { g_lpszServiceName, SnortServiceStart }, { NULL, NULL } }; */ SERVICE_TABLE_ENTRY steDispatchTable[2]; steDispatchTable[0].lpServiceName = g_lpszServiceName; steDispatchTable[0].lpServiceProc = SnortServiceStart; steDispatchTable[1].lpServiceName = NULL; steDispatchTable[1].lpServiceProc = NULL; for( i=1; i0) { memset(szString, 0, iCount); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ (LPTSTR) &lpMsgBuf, 0, NULL ); strncpy(szString, (LPCTSTR) lpMsgBuf, iCount-1); szString[iCount-1]=0; /* Free the buffer. */ LocalFree( lpMsgBuf ); lpMsgBuf = NULL; } } VOID ReadServiceCommandLineParams( int * piArgCounter, char** * pargvDynamic ) { HKEY hkSnort = NULL; long lRegRC = 0; DWORD dwType; DWORD dwDataSize; BYTE byData[MAX_REGISTRY_DATA_LENGTH]; int i; /********** * Read the registry entries for Snort command line parameters **********/ lRegRC = RegOpenKeyEx( HKEY_LOCAL_MACHINE, /* handle to open key */ g_lpszRegistryKey, /* subkey name */ 0, /* reserved (must be zero) */ KEY_READ, /* desired security access */ &hkSnort /* key handle */ ); if( lRegRC != ERROR_SUCCESS ) { TCHAR szMsg[1000]; SvcFormatMessage(szMsg, sizeof(szMsg)); FatalError(" [SNORT_SERVICE] Unable to open Snort registry entry. " " Perhaps Snort has not been installed as a service." " %s", szMsg); } memset(byData, 0, sizeof(byData)); dwDataSize = sizeof(byData); lRegRC = RegQueryValueEx( hkSnort, /* handle to key */ g_lpszRegistryCountFormat, /* value name */ NULL, /* reserved */ &dwType, /* type buffer */ byData, /* data buffer */ &dwDataSize /* size of data buffer */ ); if( lRegRC != ERROR_SUCCESS ) { TCHAR szMsg[1000]; SvcFormatMessage(szMsg, sizeof(szMsg)); FatalError(" [SNORT_SERVICE] Unable to read Snort registry entry '%s'." " Perhaps Snort has not been installed as a service." " %s", g_lpszRegistryCountFormat, szMsg); } (*piArgCounter) = * ((int*)&byData); (*pargvDynamic) = SnortAlloc( ((*piArgCounter) + 2) * sizeof(char *) ); (*pargvDynamic)[0] = SnortStrdup(g_lpszServiceName); DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Preparing to use the following command-line arguments:\n");); for( i=1; i<=(*piArgCounter); i++ ) { TCHAR szName[MAX_REGISTRY_KEY_LENGTH]; sprintf(szName, g_lpszRegistryCmdFormat, i); memset(byData, 0, sizeof(byData)); dwDataSize = sizeof(byData); lRegRC = RegQueryValueEx( hkSnort, /* handle to key */ szName, /* value name */ NULL, /* reserved */ &dwType, /* type buffer */ byData, /* data buffer */ &dwDataSize /* size of data buffer */ ); if( lRegRC != ERROR_SUCCESS ) { TCHAR szMsg[1000]; SvcFormatMessage(szMsg, sizeof(szMsg)); FatalError(" [SNORT_SERVICE] Unable to read Snort registry entry '%s'." " Perhaps Snort has not been installed as a service." " %s", szName, szMsg); } (*pargvDynamic)[i] = SnortStrdup( (char*) byData ); DEBUG_WRAP(DebugMessage(DEBUG_INIT, " %s\n", (*pargvDynamic)[i]);); } lRegRC = RegCloseKey( hkSnort ); if( lRegRC != ERROR_SUCCESS ) { TCHAR szMsg[1000]; SvcFormatMessage(szMsg, sizeof(szMsg)); FatalError(" [SNORT_SERVICE] Unable to close Snort registry entry." " Perhaps Snort has not been installed as a service." " %s", szMsg); } hkSnort = NULL; } /******************************************************************************* * (This documentation was taken from Microsoft's own doc's on how to create * a Win32 Service.) * * Writing a ServiceMain Function * ----------------------------------------------------------------------------- * * The SnortServiceStart function in the following example is the entry point for * the service. SnortServiceStart has access to the command-line arguments, in the * way that the main function of a console application does. The first parameter * contains the number of arguments being passed to the service. There will * always be at least one argument. The second parameter is a pointer to an * array of string pointers. The first item in the array always points to the * service name. * * The SnortServiceStart function first fills in the SERVICE_STATUS structure * including the control codes that it accepts. Although this service accepts * SERVICE_CONTROL_PAUSE and SERVICE_CONTROL_CONTINUE, it does nothing * significant when told to pause. The flags SERVICE_ACCEPT_PAUSE_CONTINUE was * included for illustration purposes only; if pausing does not add value to * your service, do not support it. * * The SnortServiceStart function then calls the RegisterServiceCtrlHandler * function to register SnortService as the service's Handler function and begin * initialization. The following sample initialization function, * SnortServiceInitialization, is included for illustration purposes; it does not * perform any initialization tasks such as creating additional threads. If * your service's initialization performs tasks that are expected to take longer * than one second, your code must call the SetServiceStatus function * periodically to send out wait hints and check points indicating that progress * is being made. * * When initialization has completed successfully, the example calls * SetServiceStatus with a status of SERVICE_RUNNING and the service continues * with its work. If an error has occurred in initialization, SnortServiceStart * reports SERVICE_STOPPED with the SetServiceStatus function and returns. * * Because this sample service does not complete any real tasks, SnortServiceStart * simply returns control to the caller. However, your service should use this * thread to complete whatever tasks it was designed to do. If a service does not * need a thread to do its work (such as a service that only processes RPC * requests), its ServiceMain function should return control to the caller. It is * important for the function to return, rather than call the ExitThread * function, because returning allows for cleanup of the memory allocated for the * arguments. * * To output debugging information, SnortServiceStart calls SvcDebugOut. The source * code for SvcDebugOut is given in Writing a Service Program's main Function. *******************************************************************************/ void logmsg(char* msg) { FILE *pFile; if( (pFile=fopen("c:\\snortlog.txt", "a")) != NULL ) { if( msg != NULL ) { fprintf(pFile,"%s",msg); } else { fprintf(pFile,"%s","Message String is NULL\n"); } fclose(pFile); pFile = NULL; } } void logadapternames( char* interfacenames, char* errorbuf ) { char AdaptersName[8192]; int i; memset(AdaptersName, 0x00, sizeof(AdaptersName)); for( i=0; irun_flags |= RUN_FLAG__PAUSE_SERVICE; g_SnortServiceStatus.dwCurrentState = SERVICE_PAUSED; break; case SERVICE_CONTROL_CONTINUE: /* Do whatever it takes to continue here. */ snort_conf->run_flags &= ~RUN_FLAG__PAUSE_SERVICE; g_SnortServiceStatus.dwCurrentState = SERVICE_RUNNING; break; case SERVICE_CONTROL_STOP: /* Do whatever it takes to stop here. */ snort_conf->run_flags |= RUN_FLAG__TERMINATE_SERVICE; Sleep( PKT_TIMEOUT * 2 ); /* wait for 2x the timeout, just to ensure that things * the service has processed any last packets */ g_SnortServiceStatus.dwWin32ExitCode = 0; g_SnortServiceStatus.dwCurrentState = SERVICE_STOPPED; g_SnortServiceStatus.dwCheckPoint = 0; g_SnortServiceStatus.dwWaitHint = 0; if (!SetServiceStatus (g_SnortServiceStatusHandle, &g_SnortServiceStatus)) { dwStatus = GetLastError(); SvcDebugOut(" [SNORT_SERVICE] SetServiceStatus error %ld\n",dwStatus); } SvcDebugOut(" [SNORT_SERVICE] Leaving SnortService \n",0); return; case SERVICE_CONTROL_INTERROGATE: /* Fall through to send current status. */ break; default: SvcDebugOut(" [SNORT_SERVICE] Unrecognized opcode %ld\n", dwOpcode); } /* Send current status. */ if (!SetServiceStatus (g_SnortServiceStatusHandle, &g_SnortServiceStatus)) { dwStatus = GetLastError(); SvcDebugOut(" [SNORT_SERVICE] SetServiceStatus error %ld\n",dwStatus); } return; } /******************************************************************************* * (This documentation was taken from Microsoft's own doc's on how to create * a Win32 Service.) * * Installing a Service * ----------------------------------------------------------------------------- * * A service configuration program uses the CreateService function to install a * service in a SCM database. The application-defined schSCManager handle must * have SC_MANAGER_CREATE_SERVICE access to the SCManager object. The following * example shows how to install a service. *******************************************************************************/ VOID InstallSnortService(int argc, char* argv[]) { SC_HANDLE schSCManager, schService; char buffer[_MAX_PATH+1]; LPCTSTR lpszBinaryPathName = NULL; HKEY hkSnort = NULL; long lRegRC = 0; int iArgCounter; DWORD dwWriteCounter = 0; #ifdef SET_SERVICE_DESCRIPTION SERVICE_DESCRIPTION sdBuf; #endif printf("\n\n"); printf(" [SNORT_SERVICE] Attempting to install the Snort service.\n"); /********** * Build up a string which stores the full path to the Snort executable. * This takes into account the current working directory, along with a * relative path to the Snort executable. **********/ memset( buffer, 0, sizeof(buffer) ); if( _getcwd( buffer, _MAX_PATH ) == NULL ) { TCHAR szMsg[1000]; SvcFormatMessage(szMsg, sizeof(szMsg)); FatalError(" [SNORT_SERVICE] Unable to determine current working directory. %s", szMsg); } if( buffer[strlen(buffer) - 1] != '\\' ) { if (strlen(buffer) < _MAX_PATH) { int len = strlen(buffer); buffer[len] = '\\'; buffer[len + 1] = '\0'; } else { FatalError(" [SNORT_SERVICE] Unable to create full path to Snort binary."); } } SnortSnprintfAppend(buffer, _MAX_PATH + 1, "%s ", argv[0]); SnortSnprintfAppend(buffer, _MAX_PATH + 1, "%s", SERVICE_CMDLINE_PARAM); lpszBinaryPathName = buffer; printf("\n"); printf(" [SNORT_SERVICE] The full path to the Snort binary appears to be:\n"); printf(" %s\n", lpszBinaryPathName); /********** * Create the registry entries for Snort command line parameters **********/ lRegRC = RegCreateKeyEx( HKEY_LOCAL_MACHINE, /* handle to open key */ g_lpszRegistryKey, /* subkey name */ 0, /* reserved (must be zero) */ NULL, /* class string */ REG_OPTION_NON_VOLATILE, /* special options */ KEY_ALL_ACCESS, /* desired security access */ NULL, /* inheritance */ &hkSnort, /* key handle */ NULL /* disposition value buffer */ ); if( lRegRC != ERROR_SUCCESS ) { TCHAR szMsg[1000]; SvcFormatMessage(szMsg, sizeof(szMsg)); FatalError(" [SNORT_SERVICE] Unable to create Snort registry entry. %s", szMsg); } for( iArgCounter=1; iArgCounter MAX_REGISTRY_DATA_LENGTH ) { FatalError(" [SNORT_SERVICE] A single command line parameter cannot exceed %d characters.", MAX_REGISTRY_DATA_LENGTH); } else { char szSubkeyName[30]; dwWriteCounter++; sprintf(szSubkeyName, g_lpszRegistryCmdFormat, dwWriteCounter); lRegRC = RegSetValueEx( hkSnort, /* handle to key to set value for */ szSubkeyName, /* name of the value to set */ 0, /* reserved */ REG_SZ, /* flag for value type */ (LPBYTE) argv[iArgCounter], /* address of value data */ strlen(argv[iArgCounter]) /* size of value data */ ); if( lRegRC != ERROR_SUCCESS ) { TCHAR szMsg[1000]; SvcFormatMessage(szMsg, sizeof(szMsg)); FatalError(" [SNORT_SERVICE] Unable to write Snort registry entry. %s", szMsg); } } } /* end for() */ lRegRC = RegSetValueEx( hkSnort, /* handle to key to set value for */ g_lpszRegistryCountFormat, /* name of the value to set */ 0, /* reserved */ REG_DWORD, /* flag for value type */ (LPBYTE) &dwWriteCounter, /* address of value data */ sizeof(dwWriteCounter) /* size of value data */ ); if( lRegRC != ERROR_SUCCESS ) { TCHAR szMsg[1000]; SvcFormatMessage(szMsg, sizeof(szMsg)); FatalError(" [SNORT_SERVICE] Unable to write Snort registry entry. %s", szMsg); } lRegRC = RegCloseKey( hkSnort ); if( lRegRC != ERROR_SUCCESS ) { TCHAR szMsg[1000]; SvcFormatMessage(szMsg, sizeof(szMsg)); FatalError(" [SNORT_SERVICE] Unable to close Snort registry entry. %s", szMsg); } printf("\n"); printf(" [SNORT_SERVICE] Successfully added registry keys to:\n"); printf(" \\HKEY_LOCAL_MACHINE\\%s\\\n", g_lpszRegistryKey); /********** * Add Snort to the Services database **********/ schSCManager = OpenSCManager(NULL, /* local machine */ NULL, /* defaults to SERVICES_ACTIVE_DATABASE */ SC_MANAGER_ALL_ACCESS); /* full access rights */ if (schSCManager == NULL) { DWORD dwErr = GetLastError(); LPCTSTR lpszBasicMessage = "Unable to open a connection to the Services database."; TCHAR szMsg[1000]; SvcFormatMessage(szMsg, sizeof(szMsg)); switch(dwErr) { case ERROR_ACCESS_DENIED: FatalError(" [SNORT_SERVICE] %s Access is denied. %s", lpszBasicMessage, szMsg); break; case ERROR_DATABASE_DOES_NOT_EXIST: FatalError(" [SNORT_SERVICE] %s Services database does not exist. %s", lpszBasicMessage, szMsg); break; case ERROR_INVALID_PARAMETER: FatalError(" [SNORT_SERVICE] %s Invalid parameter. %s", lpszBasicMessage, szMsg); break; default: FatalError(" [SNORT_SERVICE] %s Unrecognized error (%d). %s", lpszBasicMessage, dwErr, szMsg); break; } } schService = CreateService( schSCManager, /* SCManager database */ g_lpszServiceName, /* name of service */ g_lpszServiceDisplayName, /* service name to display */ SERVICE_ALL_ACCESS, /* desired access */ SERVICE_WIN32_OWN_PROCESS, /* service type */ SERVICE_DEMAND_START, /* start type */ SERVICE_ERROR_NORMAL, /* error control type */ lpszBinaryPathName, /* service's binary */ NULL, /* no load ordering group */ NULL, /* no tag identifier */ NULL, /* no dependencies */ NULL, /* LocalSystem account */ NULL); /* no password */ if (schService == NULL) { DWORD dwErr = GetLastError(); LPCTSTR lpszBasicMessage = "Error while adding the Snort service to the Services database."; TCHAR szMsg[1000]; SvcFormatMessage(szMsg, sizeof(szMsg)); switch(dwErr) { case ERROR_ACCESS_DENIED: FatalError(" [SNORT_SERVICE] %s Access is denied. %s", lpszBasicMessage, szMsg); break; case ERROR_CIRCULAR_DEPENDENCY: FatalError(" [SNORT_SERVICE] %s Circular dependency. %s", lpszBasicMessage, szMsg); break; case ERROR_DUP_NAME: FatalError(" [SNORT_SERVICE] %s The display name (\"%s\") is already in use. %s", lpszBasicMessage , g_lpszServiceDisplayName , szMsg); break; case ERROR_INVALID_HANDLE: FatalError(" [SNORT_SERVICE] %s Invalid handle. %s", lpszBasicMessage, szMsg); break; case ERROR_INVALID_NAME: FatalError(" [SNORT_SERVICE] %s Invalid service name. %s", lpszBasicMessage, szMsg); break; case ERROR_INVALID_PARAMETER: FatalError(" [SNORT_SERVICE] %s Invalid parameter. %s", lpszBasicMessage, szMsg); break; case ERROR_INVALID_SERVICE_ACCOUNT: FatalError(" [SNORT_SERVICE] %s Invalid service account. %s", lpszBasicMessage, szMsg); break; case ERROR_SERVICE_EXISTS: FatalError(" [SNORT_SERVICE] %s Service already exists. %s", lpszBasicMessage, szMsg); break; default: FatalError(" [SNORT_SERVICE] %s Unrecognized error (%d). %s", lpszBasicMessage, dwErr, szMsg); break; } } #ifdef SET_SERVICE_DESCRIPTION /* Apparently, the call to ChangeServiceConfig2() only works on Windows >= 2000 */ sdBuf.lpDescription = g_lpszServiceDescription; if( !ChangeServiceConfig2(schService, /* handle to service */ SERVICE_CONFIG_DESCRIPTION, /* change: description */ &sdBuf) ) /* value: new description */ { TCHAR szMsg[1000]; SvcFormatMessage(szMsg, sizeof(szMsg)); FatalError(" [SNORT_SERVICE] Unable to add a description to the Snort service. %s", szMsg); } #endif printf("\n"); printf(" [SNORT_SERVICE] Successfully added the Snort service to the Services database.\n"); CloseServiceHandle(schService); CloseServiceHandle(schSCManager); } /******************************************************************************* * (This documentation was taken from Microsoft's own doc's on how to create * a Win32 Service.) * * Deleting a Service * ----------------------------------------------------------------------------- * * In the following example, a service configuration program uses the * OpenService function to get a handle with DELETE access to an installed * service object. The program then uses the service object handle in the * DeleteService function to remove the service from the SCM database. *******************************************************************************/ VOID UninstallSnortService() { SC_HANDLE schSCManager, schService; //HKEY hkSnort = NULL; long lRegRC = 0; printf("\n\n"); printf(" [SNORT_SERVICE] Attempting to uninstall the Snort service.\n"); /********** * Removing the registry entries for Snort command line parameters **********/ lRegRC = RegDeleteKey( HKEY_LOCAL_MACHINE, /* handle to open key */ g_lpszRegistryKey /* subkey name */ ); if( lRegRC != ERROR_SUCCESS ) { TCHAR szMsg[1000]; SvcFormatMessage(szMsg, sizeof(szMsg)); printf(" [SNORT_SERVICE] Warning. Unable to remove root Snort registry entry. %s", szMsg); } printf("\n"); printf(" [SNORT_SERVICE] Successfully removed registry keys from:\n"); printf(" \\HKEY_LOCAL_MACHINE\\%s\\\n", g_lpszRegistryKey); /********** * Remove Snort from the Services database **********/ schSCManager = OpenSCManager(NULL, /* local machine */ NULL, /* ServicesActive database */ SC_MANAGER_ALL_ACCESS); /* full access rights */ if (schSCManager == NULL) { DWORD dwErr = GetLastError(); LPCTSTR lpszBasicMessage = "Unable to open a connection to the Services database."; TCHAR szMsg[1000]; SvcFormatMessage(szMsg, sizeof(szMsg)); switch(dwErr) { case ERROR_ACCESS_DENIED: FatalError(" [SNORT_SERVICE] %s Access is denied. %s", lpszBasicMessage, szMsg); break; case ERROR_DATABASE_DOES_NOT_EXIST: FatalError(" [SNORT_SERVICE] %s Services database does not exist. %s", lpszBasicMessage, szMsg); break; case ERROR_INVALID_PARAMETER: FatalError(" [SNORT_SERVICE] %s Invalid parameter. %s", lpszBasicMessage, szMsg); break; default: FatalError(" [SNORT_SERVICE] %s Unrecognized error (%d). %s", lpszBasicMessage, dwErr, szMsg); break; } } schService = OpenService(schSCManager, /* SCManager database */ g_lpszServiceName, /* name of service */ DELETE); /* only need DELETE access */ if (schService == NULL) { DWORD dwErr = GetLastError(); LPCTSTR lpszBasicMessage = "Unable to locate Snort in the Services database."; TCHAR szMsg[1000]; SvcFormatMessage(szMsg, sizeof(szMsg)); switch(dwErr) { case ERROR_ACCESS_DENIED: FatalError(" [SNORT_SERVICE] %s Access is denied. %s", lpszBasicMessage, szMsg); break; case ERROR_INVALID_HANDLE: FatalError(" [SNORT_SERVICE] %s Invalid handle. %s", lpszBasicMessage, szMsg); break; case ERROR_INVALID_NAME: FatalError(" [SNORT_SERVICE] %s Invalid name. %s", lpszBasicMessage, szMsg); break; case ERROR_SERVICE_DOES_NOT_EXIST: FatalError(" [SNORT_SERVICE] %s Service does not exist. %s", lpszBasicMessage, szMsg); break; default: FatalError(" [SNORT_SERVICE] %s Unrecognized error (%d). %s", lpszBasicMessage, dwErr, szMsg); break; } } if (! DeleteService(schService) ) { DWORD dwErr = GetLastError(); LPCTSTR lpszBasicMessage = "Unable to remove Snort from the Services database."; TCHAR szMsg[1000]; SvcFormatMessage(szMsg, sizeof(szMsg)); switch(dwErr) { case ERROR_ACCESS_DENIED: FatalError(" [SNORT_SERVICE] %s Access is denied. %s", lpszBasicMessage, szMsg); break; case ERROR_INVALID_HANDLE: FatalError(" [SNORT_SERVICE] %s Invalid handle. %s", lpszBasicMessage, szMsg); break; case ERROR_SERVICE_MARKED_FOR_DELETE: FatalError(" [SNORT_SERVICE] %s Service already marked for delete. %s", lpszBasicMessage, szMsg); break; default: FatalError(" [SNORT_SERVICE] %s Unrecognized error (%d). %s", lpszBasicMessage, dwErr, szMsg); break; } } printf("\n"); printf(" [SNORT_SERVICE] Successfully removed the Snort service from the Services database.\n"); CloseServiceHandle(schService); CloseServiceHandle(schSCManager); } VOID ShowSnortServiceParams(void) { int argc; char ** argv; int i; ReadServiceCommandLineParams( &argc, &argv ); printf("\n" "Snort is currently configured to run as a Windows service using the following\n" "command-line parameters:\n\n" " "); for( i=1; i<=argc; i++ ) { if( argv[i] != NULL ) { printf(" %s", argv[i]); free( argv[i] ); argv[i] = NULL; } } free( argv ); argv = NULL; printf("\n"); } #endif /* ENABLE_WIN32_SERVICE */ snort-2.9.15.1/src/win32/WIN32-Includes/0000755000000000000000000000000013571426536014176 500000000000000snort-2.9.15.1/src/win32/WIN32-Includes/NET/0000755000000000000000000000000013571426517014623 500000000000000snort-2.9.15.1/src/win32/WIN32-Includes/NET/Bpf.h0000644000175200017520000003121513571422607015457 00000000000000/* $Id$ */ /*- * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 * The Regents of the University of California. All rights reserved. * * This code is derived from the Stanford/CMU enet packet filter, * (net/enet.c) distributed as part of 4.3BSD, and code contributed * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence * Berkeley Laboratory. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)bpf.h 7.1 (Berkeley) 5/7/91 * * @(#) $Header$ (LBL) */ #ifndef BPF_MAJOR_VERSION /* BSD style release date */ #define BPF_RELEASE 199606 #ifdef WIN32 #include #include #endif typedef int bpf_int32; typedef u_int bpf_u_int32; /* * Alignment macros. BPF_WORDALIGN rounds up to the next * even multiple of BPF_ALIGNMENT. */ #ifndef __NetBSD__ #define BPF_ALIGNMENT sizeof(bpf_int32) #else #define BPF_ALIGNMENT sizeof(long) #endif #define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1)) #define BPF_MAXINSNS 512 #define BPF_MAXBUFSIZE 0x8000 #define BPF_MINBUFSIZE 32 /* * Structure for BIOCSETF. */ struct bpf_program { u_int bf_len; struct bpf_insn *bf_insns; }; /* * Struct returned by BIOCGSTATS. */ struct bpf_stat { u_int bs_recv; /* number of packets received */ u_int bs_drop; /* number of packets dropped */ }; /* * Struct return by BIOCVERSION. This represents the version number of * the filter language described by the instruction encodings below. * bpf understands a program iff kernel_major == filter_major && * kernel_minor >= filter_minor, that is, if the value returned by the * running kernel has the same major number and a minor number equal * equal to or less than the filter being downloaded. Otherwise, the * results are undefined, meaning an error may be returned or packets * may be accepted haphazardly. * It has nothing to do with the source code version. */ struct bpf_version { u_short bv_major; u_short bv_minor; }; /* Current version number of filter architecture. */ #define BPF_MAJOR_VERSION 1 #define BPF_MINOR_VERSION 1 /* * BPF ioctls * * The first set is for compatibility with Sun's pcc style * header files. If your using gcc, we assume that you * have run fixincludes so the latter set should work. */ #if (defined(sun) || defined(ibm032)) && !defined(__GNUC__) #define BIOCGBLEN _IOR(B,102, u_int) #define BIOCSBLEN _IOWR(B,102, u_int) #define BIOCSETF _IOW(B,103, struct bpf_program) #define BIOCFLUSH _IO(B,104) #define BIOCPROMISC _IO(B,105) #define BIOCGDLT _IOR(B,106, u_int) #define BIOCGETIF _IOR(B,107, struct ifreq) #define BIOCSETIF _IOW(B,108, struct ifreq) #define BIOCSRTIMEOUT _IOW(B,109, struct timeval) #define BIOCGRTIMEOUT _IOR(B,110, struct timeval) #define BIOCGSTATS _IOR(B,111, struct bpf_stat) #define BIOCIMMEDIATE _IOW(B,112, u_int) #define BIOCVERSION _IOR(B,113, struct bpf_version) #define BIOCSTCPF _IOW(B,114, struct bpf_program) #define BIOCSUDPF _IOW(B,115, struct bpf_program) #else #define BIOCGBLEN _IOR('B',102, u_int) #define BIOCSBLEN _IOWR('B',102, u_int) #define BIOCSETF _IOW('B',103, struct bpf_program) #define BIOCFLUSH _IO('B',104) #define BIOCPROMISC _IO('B',105) #define BIOCGDLT _IOR('B',106, u_int) #define BIOCGETIF _IOR('B',107, struct ifreq) #define BIOCSETIF _IOW('B',108, struct ifreq) #define BIOCSRTIMEOUT _IOW('B',109, struct timeval) #define BIOCGRTIMEOUT _IOR('B',110, struct timeval) #define BIOCGSTATS _IOR('B',111, struct bpf_stat) #define BIOCIMMEDIATE _IOW('B',112, u_int) #define BIOCVERSION _IOR('B',113, struct bpf_version) #define BIOCSTCPF _IOW('B',114, struct bpf_program) #define BIOCSUDPF _IOW('B',115, struct bpf_program) #endif /* * Structure prepended to each packet. */ struct bpf_hdr { struct timeval bh_tstamp; /* time stamp */ bpf_u_int32 bh_caplen; /* length of captured portion */ bpf_u_int32 bh_datalen; /* original length of packet */ u_short bh_hdrlen; /* length of bpf header (this struct plus alignment padding) */ }; /* * Because the structure above is not a multiple of 4 bytes, some compilers * will insist on inserting padding; hence, sizeof(struct bpf_hdr) won't work. * Only the kernel needs to know about it; applications use bh_hdrlen. */ #if defined(KERNEL) || defined(_KERNEL) #define SIZEOF_BPF_HDR 18 #endif /* * Data-link level type codes. */ /* * These are the types that are the same on all platforms; on other * platforms, a should be supplied that defines the additional * DLT_* codes appropriately for that platform (the BSDs, for example, * should not just pick up this version of "bpf.h"; they should also define * the additional DLT_* codes used by their kernels, as well as the values * defined here - and, if the values they use for particular DLT_ types * differ from those here, they should use their values, not the ones * here). */ #define DLT_NULL 0 /* no link-layer encapsulation */ #define DLT_EN10MB 1 /* Ethernet (10Mb) */ #define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ #define DLT_AX25 3 /* Amateur Radio AX.25 */ #define DLT_PRONET 4 /* Proteon ProNET Token Ring */ #define DLT_CHAOS 5 /* Chaos */ #define DLT_IEEE802 6 /* IEEE 802 Networks */ #define DLT_ARCNET 7 /* ARCNET */ #define DLT_SLIP 8 /* Serial Line IP */ #define DLT_PPP 9 /* Point-to-point Protocol */ #define DLT_FDDI 10 /* FDDI */ /* * These are values from the traditional libpcap "bpf.h". * Ports of this to particular platforms should replace these definitions * with the ones appropriate to that platform, if the values are * different on that platform. */ #define DLT_ATM_RFC1483 11 /* LLC/SNAP encapsulated atm */ #define DLT_RAW 12 /* raw IP */ /* * These are values from BSD/OS's "bpf.h". * These are not the same as the values from the traditional libpcap * "bpf.h"; however, these values shouldn't be generated by any * OS other than BSD/OS, so the correct values to use here are the * BSD/OS values. * * Platforms that have already assigned these values to other * DLT_ codes, however, should give these codes the values * from that platform, so that programs that use these codes will * continue to compile - even though they won't correctly read * files of these types. */ #define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ #define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ #define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ /* * This value is defined by NetBSD; other platforms should refrain from * using it for other purposes, so that NetBSD savefiles with a link * type of 50 can be read as this type on all platforms. */ #define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */ /* * This value was defined by libpcap 0.5; platforms that have defined * it with a different value should define it here with that value - * a link type of 104 in a save file will be mapped to DLT_C_HDLC, * whatever value that happens to be, so programs will correctly * handle files with that link type regardless of the value of * DLT_C_HDLC. * * The name DLT_C_HDLC was used by BSD/OS; we use that name for source * compatibility with programs written for BSD/OS. * * libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well, * for source compatibility with programs written for libpcap 0.5. */ #define DLT_C_HDLC 104 /* Cisco HDLC */ #define DLT_CHDLC DLT_C_HDLC /* * Reserved for future use. * Do not pick other numerical value for these unless you have also * picked up the tcpdump.org top-of-CVS-tree version of "savefile.c", * which will arrange that capture files for these DLT_ types have * the same "network" value on all platforms, regardless of what * value is chosen for their DLT_ type (thus allowing captures made * on one platform to be read on other platforms, even if the two * platforms don't use the same numerical values for all DLT_ types). */ #define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ /* * Values between 106 and 107 are used in capture file headers as * link-layer types corresponding to DLT_ types that might differ * between platforms; don't use those values for new DLT_ new types. */ /* * OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except * that the AF_ type in the link-layer header is in network byte order. * * OpenBSD defines it as 12, but that collides with DLT_RAW, so we * define it as 108 here. If OpenBSD picks up this file, it should * define DLT_LOOP as 12 in its version, as per the comment above - * and should not use 108 for any purpose. */ #define DLT_LOOP 108 /* * Values between 109 and 112 are used in capture file headers as * link-layer types corresponding to DLT_ types that might differ * between platforms; don't use those values for new DLT_ new types. */ /* * This is for Linux cooked sockets. */ #define DLT_LINUX_SLL 113 /* * The instruction encodings. */ /* instruction classes */ #define BPF_CLASS(code) ((code) & 0x07) #define BPF_LD 0x00 #define BPF_LDX 0x01 #define BPF_ST 0x02 #define BPF_STX 0x03 #define BPF_ALU 0x04 #define BPF_JMP 0x05 #define BPF_RET 0x06 #define BPF_MISC 0x07 /* ld/ldx fields */ #define BPF_SIZE(code) ((code) & 0x18) #define BPF_W 0x00 #define BPF_H 0x08 #define BPF_B 0x10 #define BPF_MODE(code) ((code) & 0xe0) #define BPF_IMM 0x00 #define BPF_ABS 0x20 #define BPF_IND 0x40 #define BPF_MEM 0x60 #define BPF_LEN 0x80 #define BPF_MSH 0xa0 /* alu/jmp fields */ #define BPF_OP(code) ((code) & 0xf0) #define BPF_ADD 0x00 #define BPF_SUB 0x10 #define BPF_MUL 0x20 #define BPF_DIV 0x30 #define BPF_OR 0x40 #define BPF_AND 0x50 #define BPF_LSH 0x60 #define BPF_RSH 0x70 #define BPF_NEG 0x80 #define BPF_JA 0x00 #define BPF_JEQ 0x10 #define BPF_JGT 0x20 #define BPF_JGE 0x30 #define BPF_JSET 0x40 #define BPF_SRC(code) ((code) & 0x08) #define BPF_K 0x00 #define BPF_X 0x08 /* ret - BPF_K and BPF_X also apply */ #define BPF_RVAL(code) ((code) & 0x18) #define BPF_A 0x10 /* misc */ #define BPF_MISCOP(code) ((code) & 0xf8) #define BPF_TAX 0x00 #define BPF_TXA 0x80 /* * The instruction data structure. */ struct bpf_insn { u_short code; u_char jt; u_char jf; bpf_int32 k; }; /* * Macros for insn array initializers. */ #define BPF_STMT(code, k) { (u_short)(code), 0, 0, k } #define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k } #if defined(BSD) && (defined(KERNEL) || defined(_KERNEL)) /* * Systems based on non-BSD kernels don't have ifnet's (or they don't mean * anything if it is in ) and won't work like this. */ # if __STDC__ extern void bpf_tap(struct ifnet *, u_char *, u_int); extern void bpf_mtap(struct ifnet *, struct mbuf *); extern void bpfattach(struct ifnet *, u_int, u_int); extern void bpfilterattach(int); # else extern void bpf_tap(); extern void bpf_mtap(); extern void bpfattach(); extern void bpfilterattach(); # endif /* __STDC__ */ #endif /* BSD && (_KERNEL || KERNEL) */ #if __STDC__ extern int bpf_validate(struct bpf_insn *, int); extern u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int); #else extern int bpf_validate(); extern u_int bpf_filter(); #endif /* * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST). */ #define BPF_MEMWORDS 16 #endif snort-2.9.15.1/src/win32/WIN32-Includes/NETINET/0000755000000000000000000000000013571426520015275 500000000000000snort-2.9.15.1/src/win32/WIN32-Includes/NETINET/IF_ETHER.H0000444000175200017520000000640313571422607016614 00000000000000/* * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)if_ether.h 8.3 (Berkeley) 5/2/95 */ #include /* * Ethernet address - 6 octets */ struct ether_addr { u_char ether_addr_octet[6]; }; /* * Structure of a 10Mb/s Ethernet header. */ struct ether_header { u_char ether_dhost[6]; u_char ether_shost[6]; u_short ether_type; }; #define ETHERTYPE_PUP 0x0200 /* PUP protocol */ #define ETHERTYPE_IP 0x0800 /* IP protocol */ #define ETHERTYPE_ARP 0x0806 /* Addr. resolution protocol */ #define ETHERTYPE_REVARP 0x8035 /* reverse Addr. resolution protocol */ /* * The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have * (type-ETHERTYPE_TRAIL)*512 bytes of data followed * by an ETHER type (as given above) and then the (variable-length) header. */ #define ETHERTYPE_TRAIL 0x1000 /* Trailer packet */ #define ETHERTYPE_NTRAILER 16 #define ETHERMTU 1500 #define ETHERMIN (60-14) /* * Ethernet Address Resolution Protocol. * * See RFC 826 for protocol description. Structure below is adapted * to resolving internet addresses. Field names used correspond to * RFC 826. */ struct ether_arp { struct arphdr ea_hdr; /* fixed-size header */ u_char arp_sha[6]; /* sender hardware address */ u_char arp_spa[4]; /* sender protocol address */ u_char arp_tha[6]; /* target hardware address */ u_char arp_tpa[4]; /* target protocol address */ }; #define arp_hrd ea_hdr.ar_hrd #define arp_pro ea_hdr.ar_pro #define arp_hln ea_hdr.ar_hln #define arp_pln ea_hdr.ar_pln #define arp_op ea_hdr.ar_op snort-2.9.15.1/src/win32/WIN32-Includes/NETINET/IN_SYSTM.H0000444000175200017520000000500313571422607016667 00000000000000/* * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)in_systm.h 8.1 (Berkeley) 6/10/93 */ /* * Miscellaneous internetwork * definitions for kernel. */ /* * Network types. * * Internally the system keeps counters in the headers with the bytes * swapped so that VAX instructions will work on them. It reverses * the bytes before transmission at each protocol level. The n_ types * represent the types with the bytes in ``high-ender'' order. */ typedef short n_short; /* short as received from the net */ typedef long n_long; /* long as received from the net */ typedef long n_time; /* ms since 00:00 GMT, byte rev */ #ifdef KERNEL n_time iptime __P((void)); #endif #ifndef _SA_FAMILY_T #define _SA_FAMILY_T typedef unsigned short sa_family_t; #endif snort-2.9.15.1/src/win32/WIN32-Includes/NETINET/IP.H0000444000175200017520000001351613571422607015702 00000000000000/* * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)ip.h 8.2 (Berkeley) 6/1/94 */ #ifndef WIN32 #include #else #include #ifndef LITTLE_ENDIAN #define LITTLE_ENDIAN 1234 #define BIG_ENDIAN 4321 #define BYTE_ORDER LITTLE_ENDIAN #endif #endif /* * Definitions for internet protocol version 4. * Per RFC 791, September 1981. */ #define IPVERSION 4 /* * Structure of an internet header, naked of options. * * We declare ip_len and ip_off to be short, rather than u_short * pragmatically since otherwise unsigned comparisons can result * against negative integers quite easily, and fail in subtle ways. */ struct ip { #if BYTE_ORDER == LITTLE_ENDIAN u_char ip_hl:4, /* header length */ ip_v:4; /* version */ #endif #if BYTE_ORDER == BIG_ENDIAN u_char ip_v:4, /* version */ ip_hl:4; /* header length */ #endif u_char ip_tos; /* type of service */ short ip_len; /* total length */ u_short ip_id; /* identification */ short ip_off; /* fragment offset field */ #define IP_DF 0x4000 /* dont fragment flag */ #define IP_MF 0x2000 /* more fragments flag */ #define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ u_char ip_ttl; /* time to live */ u_char ip_p; /* protocol */ u_short ip_sum; /* checksum */ struct in_addr ip_src,ip_dst; /* source and dest address */ }; #define IP_MAXPACKET 65535 /* maximum packet size */ /* * Definitions for IP type of service (ip_tos) */ #define IPTOS_LOWDELAY 0x10 #define IPTOS_THROUGHPUT 0x08 #define IPTOS_RELIABILITY 0x04 /* * Definitions for IP precedence (also in ip_tos) (hopefully unused) */ #define IPTOS_PREC_NETCONTROL 0xe0 #define IPTOS_PREC_INTERNETCONTROL 0xc0 #define IPTOS_PREC_CRITIC_ECP 0xa0 #define IPTOS_PREC_FLASHOVERRIDE 0x80 #define IPTOS_PREC_FLASH 0x60 #define IPTOS_PREC_IMMEDIATE 0x40 #define IPTOS_PREC_PRIORITY 0x20 #define IPTOS_PREC_ROUTINE 0x00 /* * Definitions for options. */ #define IPOPT_COPIED(o) ((o)&0x80) #define IPOPT_CLASS(o) ((o)&0x60) #define IPOPT_NUMBER(o) ((o)&0x1f) #define IPOPT_CONTROL 0x00 #define IPOPT_RESERVED1 0x20 #define IPOPT_DEBMEAS 0x40 #define IPOPT_RESERVED2 0x60 #define IPOPT_EOL 0 /* end of option list */ #define IPOPT_NOP 1 /* no operation */ #define IPOPT_RR 7 /* record packet route */ #define IPOPT_TS 68 /* timestamp */ #define IPOPT_SECURITY 130 /* provide s,c,h,tcc */ #define IPOPT_LSRR 131 /* loose source route */ #define IPOPT_SATID 136 /* satnet id */ #define IPOPT_SSRR 137 /* strict source route */ /* * Offsets to fields in options other than EOL and NOP. */ #define IPOPT_OPTVAL 0 /* option ID */ #define IPOPT_OLEN 1 /* option length */ #define IPOPT_OFFSET 2 /* offset within option */ #define IPOPT_MINOFF 4 /* min value of above */ /* * Time stamp option structure. */ struct ip_timestamp { u_char ipt_code; /* IPOPT_TS */ u_char ipt_len; /* size of structure (variable) */ u_char ipt_ptr; /* index of current entry */ #if BYTE_ORDER == LITTLE_ENDIAN u_char ipt_flg:4, /* flags, see below */ ipt_oflw:4; /* overflow counter */ #endif #if BYTE_ORDER == BIG_ENDIAN u_char ipt_oflw:4, /* overflow counter */ ipt_flg:4; /* flags, see below */ #endif union ipt_timestamp { n_long ipt_time[1]; struct ipt_ta { struct in_addr ipt_addr; n_long ipt_time; } ipt_ta[1]; } ipt_timestamp; }; /* flag bits for ipt_flg */ #define IPOPT_TS_TSONLY 0 /* timestamps only */ #define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */ #define IPOPT_TS_PRESPEC 3 /* specified modules only */ /* bits for security (not byte swapped) */ #define IPOPT_SECUR_UNCLASS 0x0000 #define IPOPT_SECUR_CONFID 0xf135 #define IPOPT_SECUR_EFTO 0x789a #define IPOPT_SECUR_MMMM 0xbc4d #define IPOPT_SECUR_RESTR 0xaf13 #define IPOPT_SECUR_SECRET 0xd788 #define IPOPT_SECUR_TOPSECRET 0x6bc5 /* * Internet implementation parameters. */ #define MAXTTL 255 /* maximum time to live (seconds) */ #define IPDEFTTL 64 /* default ttl, from RFC 1340 */ #define IPFRAGTTL 60 /* time to live for frags, slowhz */ #define IPTTLDEC 1 /* subtracted when forwarding */ #define IP_MSS 576 /* default maximum segment size */ snort-2.9.15.1/src/win32/WIN32-Includes/NETINET/IP_ICMP.H0000444000175200017520000001452613571422607016514 00000000000000/* * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)ip_icmp.h 8.1 (Berkeley) 6/10/93 */ /* * Interface Control Message Protocol Definitions. * Per RFC 792, September 1981. */ /* * Structure of an icmp header. */ struct icmp { u_char icmp_type; /* type of message, see below */ u_char icmp_code; /* type sub code */ u_short icmp_cksum; /* ones complement cksum of struct */ union { u_char ih_pptr; /* ICMP_PARAMPROB */ struct in_addr ih_gwaddr; /* ICMP_REDIRECT */ struct ih_idseq { n_short icd_id; n_short icd_seq; } ih_idseq; int ih_void; /* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */ struct ih_pmtu { n_short ipm_void; n_short ipm_nextmtu; } ih_pmtu; } icmp_hun; #define icmp_pptr icmp_hun.ih_pptr #define icmp_gwaddr icmp_hun.ih_gwaddr #define icmp_id icmp_hun.ih_idseq.icd_id #define icmp_seq icmp_hun.ih_idseq.icd_seq #define icmp_void icmp_hun.ih_void #define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void #define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu union { struct id_ts { n_time its_otime; n_time its_rtime; n_time its_ttime; } id_ts; struct id_ip { struct ip idi_ip; /* options and then 64 bits of data */ } id_ip; u_int id_mask; char id_data[1]; } icmp_dun; #define icmp_otime icmp_dun.id_ts.its_otime #define icmp_rtime icmp_dun.id_ts.its_rtime #define icmp_ttime icmp_dun.id_ts.its_ttime #define icmp_ip icmp_dun.id_ip.idi_ip #define icmp_mask icmp_dun.id_mask #define icmp_data icmp_dun.id_data }; /* * Lower bounds on packet lengths for various types. * For the error advice packets must first insure that the * packet is large enought to contain the returned ip header. * Only then can we do the check to see if 64 bits of packet * data have been returned, since we need to check the returned * ip header length. */ #define ICMP_MINLEN 8 /* abs minimum */ #define ICMP_TSLEN (8 + 3 * sizeof (n_time)) /* timestamp */ #define ICMP_MASKLEN 12 /* address mask */ #define ICMP_ADVLENMIN (8 + sizeof (struct ip) + 8) /* min */ #define ICMP_ADVLEN(p) (8 + ((p)->icmp_ip.ip_hl << 2) + 8) /* N.B.: must separately check that ip_hl >= 5 */ /* * Definition of type and code field values. */ #define ICMP_ECHOREPLY 0 /* echo reply */ #define ICMP_UNREACH 3 /* dest unreachable, codes: */ #define ICMP_UNREACH_NET 0 /* bad net */ #define ICMP_UNREACH_HOST 1 /* bad host */ #define ICMP_UNREACH_PROTOCOL 2 /* bad protocol */ #define ICMP_UNREACH_PORT 3 /* bad port */ #define ICMP_UNREACH_NEEDFRAG 4 /* IP_DF caused drop */ #define ICMP_UNREACH_SRCFAIL 5 /* src route failed */ #define ICMP_UNREACH_NET_UNKNOWN 6 /* unknown net */ #define ICMP_UNREACH_HOST_UNKNOWN 7 /* unknown host */ #define ICMP_UNREACH_ISOLATED 8 /* src host isolated */ #define ICMP_UNREACH_NET_PROHIB 9 /* prohibited access */ #define ICMP_UNREACH_HOST_PROHIB 10 /* ditto */ #define ICMP_UNREACH_TOSNET 11 /* bad tos for net */ #define ICMP_UNREACH_TOSHOST 12 /* bad tos for host */ #define ICMP_SOURCEQUENCH 4 /* packet lost, slow down */ #define ICMP_REDIRECT 5 /* shorter route, codes: */ #define ICMP_REDIRECT_NET 0 /* for network */ #define ICMP_REDIRECT_HOST 1 /* for host */ #define ICMP_REDIRECT_TOSNET 2 /* for tos and net */ #define ICMP_REDIRECT_TOSHOST 3 /* for tos and host */ #define ICMP_ECHO 8 /* echo service */ #define ICMP_ROUTERADVERT 9 /* router advertisement */ #define ICMP_ROUTERSOLICIT 10 /* router solicitation */ #define ICMP_TIMXCEED 11 /* time exceeded, code: */ #define ICMP_TIMXCEED_INTRANS 0 /* ttl==0 in transit */ #define ICMP_TIMXCEED_REASS 1 /* ttl==0 in reass */ #define ICMP_PARAMPROB 12 /* ip header bad */ #define ICMP_PARAMPROB_OPTABSENT 1 /* req. opt. absent */ #define ICMP_TSTAMP 13 /* timestamp request */ #define ICMP_TSTAMPREPLY 14 /* timestamp reply */ #define ICMP_IREQ 15 /* information request */ #define ICMP_IREQREPLY 16 /* information reply */ #define ICMP_MASKREQ 17 /* address mask request */ #define ICMP_MASKREPLY 18 /* address mask reply */ #define ICMP_MAXTYPE 18 #define ICMP_INFOTYPE(type) \ ((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \ (type) == ICMP_ROUTERADVERT || (type) == ICMP_ROUTERSOLICIT || \ (type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \ (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \ (type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY) #ifdef KERNEL void icmp_error __P((struct mbuf *, int, int, n_int, struct ifnet *)); void icmp_input __P((struct mbuf *, int)); void icmp_reflect __P((struct mbuf *)); void icmp_send __P((struct mbuf *, struct mbuf *)); int icmp_sysctl __P((int *, u_int, void *, size_t *, void *, size_t)); #endif snort-2.9.15.1/src/win32/WIN32-Includes/NETINET/IP_VAR.H0000444000175200017520000001616113571422607016411 00000000000000/* * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)ip_var.h 8.2 (Berkeley) 1/9/95 */ #ifndef WIN32 #include #else typedef char * caddr_t; #include #ifndef LITTLE_ENDIAN #define LITTLE_ENDIAN 1234 #define BIG_ENDIAN 4321 #define BYTE_ORDER LITTLE_ENDIAN #endif #endif /* * Overlay for ip header used by other protocols (tcp, udp). */ struct ipovly { caddr_t ih_next, ih_prev; /* for protocol sequence q's */ u_char ih_x1; /* (unused) */ u_char ih_pr; /* protocol */ short ih_len; /* protocol length */ struct in_addr ih_src; /* source internet address */ struct in_addr ih_dst; /* destination internet address */ }; /* * Ip reassembly queue structure. Each fragment * being reassembled is attached to one of these structures. * They are timed out after ipq_ttl drops to 0, and may also * be reclaimed if memory becomes tight. */ struct ipq { struct ipq *next,*prev; /* to other reass headers */ u_char ipq_ttl; /* time for reass q to live */ u_char ipq_p; /* protocol of this fragment */ u_short ipq_id; /* sequence id for reassembly */ struct ipasfrag *ipq_next,*ipq_prev; /* to ip headers of fragments */ struct in_addr ipq_src,ipq_dst; }; /* * Ip header, when holding a fragment. * * Note: ipf_next must be at same offset as ipq_next above */ struct ipasfrag { #if BYTE_ORDER == LITTLE_ENDIAN u_char ip_hl:4, ip_v:4; #endif #if BYTE_ORDER == BIG_ENDIAN u_char ip_v:4, ip_hl:4; #endif u_char ipf_mff; /* XXX overlays ip_tos: use low bit * to avoid destroying tos; * copied from (ip_off&IP_MF) */ short ip_len; u_short ip_id; short ip_off; u_char ip_ttl; u_char ip_p; u_short ip_sum; struct ipasfrag *ipf_next; /* next fragment */ struct ipasfrag *ipf_prev; /* previous fragment */ }; /* * Structure stored in mbuf in inpcb.ip_options * and passed to ip_output when ip options are in use. * The actual length of the options (including ipopt_dst) * is in m_len. */ #define MAX_IPOPTLEN 40 struct ipoption { struct in_addr ipopt_dst; /* first-hop dst if source routed */ char ipopt_list[MAX_IPOPTLEN]; /* options proper */ }; struct ipstat { n_long ips_total; /* total packets received */ n_long ips_badsum; /* checksum bad */ n_long ips_tooshort; /* packet too short */ n_long ips_toosmall; /* not enough data */ n_long ips_badhlen; /* ip header length < data size */ n_long ips_badlen; /* ip length < ip header length */ n_long ips_fragments; /* fragments received */ n_long ips_fragdropped; /* frags dropped (dups, out of space) */ n_long ips_fragtimeout; /* fragments timed out */ n_long ips_forward; /* packets forwarded */ n_long ips_cantforward; /* packets rcvd for unreachable dest */ n_long ips_redirectsent; /* packets forwarded on same net */ n_long ips_noproto; /* unknown or unsupported protocol */ n_long ips_delivered; /* datagrams delivered to upper level*/ n_long ips_localout; /* total ip packets generated here */ n_long ips_odropped; /* lost packets due to nobufs, etc. */ n_long ips_reassembled; /* total packets reassembled ok */ n_long ips_fragmented; /* datagrams sucessfully fragmented */ n_long ips_ofragments; /* output fragments created */ n_long ips_cantfrag; /* don't fragment flag was set, etc. */ n_long ips_badoptions; /* error in option processing */ n_long ips_noroute; /* packets discarded due to no route */ n_long ips_badvers; /* ip version != 4 */ n_long ips_rawout; /* total raw ip packets generated */ }; #ifdef KERNEL /* flags passed to ip_output as last parameter */ #define IP_FORWARDING 0x1 /* most of ip header exists */ #define IP_RAWOUTPUT 0x2 /* raw ip header exists */ #define IP_ROUTETOIF SO_DONTROUTE /* bypass routing tables */ #define IP_ALLOWBROADCAST SO_BROADCAST /* can send broadcast packets */ struct ipstat ipstat; struct ipq ipq; /* ip reass. queue */ u_short ip_id; /* ip packet ctr, for ids */ int ip_defttl; /* default IP ttl */ int in_control __P((struct socket *, n_long, caddr_t, struct ifnet *)); int ip_ctloutput __P((int, struct socket *, int, int, struct mbuf **)); void ip_deq __P((struct ipasfrag *)); int ip_dooptions __P((struct mbuf *)); void ip_drain __P((void)); void ip_enq __P((struct ipasfrag *, struct ipasfrag *)); void ip_forward __P((struct mbuf *, int)); void ip_freef __P((struct ipq *)); void ip_freemoptions __P((struct ip_moptions *)); int ip_getmoptions __P((int, struct ip_moptions *, struct mbuf **)); void ip_init __P((void)); int ip_mforward __P((struct mbuf *, struct ifnet *)); int ip_optcopy __P((struct ip *, struct ip *)); int ip_output __P((struct mbuf *, struct mbuf *, struct route *, int, struct ip_moptions *)); int ip_pcbopts __P((struct mbuf **, struct mbuf *)); struct ip * ip_reass __P((struct ipasfrag *, struct ipq *)); struct in_ifaddr * ip_rtaddr __P((struct in_addr)); int ip_setmoptions __P((int, struct ip_moptions **, struct mbuf *)); void ip_slowtimo __P((void)); struct mbuf * ip_srcroute __P((void)); void ip_stripoptions __P((struct mbuf *, struct mbuf *)); int ip_sysctl __P((int *, n_long, void *, size_t *, void *, size_t)); void ipintr __P((void)); int rip_ctloutput __P((int, struct socket *, int, int, struct mbuf **)); void rip_init __P((void)); void rip_input __P((struct mbuf *)); int rip_output __P((struct mbuf *, struct socket *, n_long)); int rip_usrreq __P((struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *)); #endif snort-2.9.15.1/src/win32/WIN32-Includes/NETINET/TCP.H0000444000175200017520000000715313571422607016020 00000000000000/* * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)tcp.h 8.1 (Berkeley) 6/10/93 */ typedef u_int tcp_seq; /* * TCP header. * Per RFC 793, September, 1981. */ struct tcphdr { u_short th_sport; /* source port */ u_short th_dport; /* destination port */ tcp_seq th_seq; /* sequence number */ tcp_seq th_ack; /* acknowledgement number */ #if BYTE_ORDER == LITTLE_ENDIAN u_char th_x2:4, /* (unused) */ th_off:4; /* data offset */ #endif #if BYTE_ORDER == BIG_ENDIAN u_char th_off:4, /* data offset */ th_x2:4; /* (unused) */ #endif u_char th_flags; #define TH_FIN 0x01 #define TH_SYN 0x02 #define TH_RST 0x04 #define TH_PUSH 0x08 #define TH_ACK 0x10 #define TH_URG 0x20 u_short th_win; /* window */ u_short th_sum; /* checksum */ u_short th_urp; /* urgent pointer */ }; #define TCPOPT_EOL 0 #define TCPOPT_NOP 1 #define TCPOPT_MAXSEG 2 #define TCPOLEN_MAXSEG 4 #define TCPOPT_WINDOW 3 #define TCPOLEN_WINDOW 3 #define TCPOPT_SACK_PERMITTED 4 /* Experimental */ #define TCPOLEN_SACK_PERMITTED 2 #define TCPOPT_SACK 5 /* Experimental */ #define TCPOPT_TIMESTAMP 8 #define TCPOLEN_TIMESTAMP 10 #define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP+2) /* appendix A */ #define TCPOPT_TSTAMP_HDR \ (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP) /* * Default maximum segment size for TCP. * With an IP MSS of 576, this is 536, * but 512 is probably more convenient. * This should be defined as MIN(512, IP_MSS - sizeof (struct tcpiphdr)). */ #define TCP_MSS 512 #define TCP_MAXWIN 65535 /* largest value for (unscaled) window */ #define TCP_MAX_WINSHIFT 14 /* maximum window shift */ /* * User-settable options (used with setsockopt). */ #ifndef TCP_NODELAY #define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */ #endif #ifndef TCP_MAXSEG #define TCP_MAXSEG 0x02 /* set maximum segment size */ #endif snort-2.9.15.1/src/win32/WIN32-Includes/NETINET/TCPIP.H0000444000175200017520000000473413571422607016253 00000000000000/* * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)tcpip.h 8.1 (Berkeley) 6/10/93 */ /* * Tcp+ip header, after ip options removed. */ struct tcpiphdr { struct ipovly ti_i; /* overlaid ip structure */ struct tcphdr ti_t; /* tcp header */ }; #define ti_next ti_i.ih_next #define ti_prev ti_i.ih_prev #define ti_x1 ti_i.ih_x1 #define ti_pr ti_i.ih_pr #define ti_len ti_i.ih_len #define ti_src ti_i.ih_src #define ti_dst ti_i.ih_dst #define ti_sport ti_t.th_sport #define ti_dport ti_t.th_dport #define ti_seq ti_t.th_seq #define ti_ack ti_t.th_ack #define ti_x2 ti_t.th_x2 #define ti_off ti_t.th_off #define ti_flags ti_t.th_flags #define ti_win ti_t.th_win #define ti_sum ti_t.th_sum #define ti_urp ti_t.th_urp snort-2.9.15.1/src/win32/WIN32-Includes/NETINET/TCP_VAR.H0000444000175200017520000002766313571422607016540 00000000000000/* * Copyright (c) 1982, 1986, 1993, 1994, 1995 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)tcp_var.h 8.4 (Berkeley) 5/24/95 */ /* * Kernel variables for tcp. */ /* * Tcp control block, one per tcp; fields: */ struct tcpcb { struct tcpiphdr *seg_next; /* sequencing queue */ struct tcpiphdr *seg_prev; short t_state; /* state of this connection */ short t_timer[TCPT_NTIMERS]; /* tcp timers */ short t_rxtshift; /* log(2) of rexmt exp. backoff */ short t_rxtcur; /* current retransmit value */ short t_dupacks; /* consecutive dup acks recd */ u_short t_maxseg; /* maximum segment size */ char t_force; /* 1 if forcing out a byte */ u_short t_flags; #define TF_ACKNOW 0x0001 /* ack peer immediately */ #define TF_DELACK 0x0002 /* ack, but try to delay it */ #define TF_NODELAY 0x0004 /* don't delay packets to coalesce */ #define TF_NOOPT 0x0008 /* don't use tcp options */ #define TF_SENTFIN 0x0010 /* have sent FIN */ #define TF_REQ_SCALE 0x0020 /* have/will request window scaling */ #define TF_RCVD_SCALE 0x0040 /* other side has requested scaling */ #define TF_REQ_TSTMP 0x0080 /* have/will request timestamps */ #define TF_RCVD_TSTMP 0x0100 /* a timestamp was received in SYN */ #define TF_SACK_PERMIT 0x0200 /* other side said I could SACK */ struct tcpiphdr *t_template; /* skeletal packet for transmit */ struct inpcb *t_inpcb; /* back pointer to internet pcb */ /* * The following fields are used as in the protocol specification. * See RFC783, Dec. 1981, page 21. */ /* send sequence variables */ tcp_seq snd_una; /* send unacknowledged */ tcp_seq snd_nxt; /* send next */ tcp_seq snd_up; /* send urgent pointer */ tcp_seq snd_wl1; /* window update seg seq number */ tcp_seq snd_wl2; /* window update seg ack number */ tcp_seq iss; /* initial send sequence number */ n_long snd_wnd; /* send window */ /* receive sequence variables */ n_long rcv_wnd; /* receive window */ tcp_seq rcv_nxt; /* receive next */ tcp_seq rcv_up; /* receive urgent pointer */ tcp_seq irs; /* initial receive sequence number */ /* * Additional variables for this implementation. */ /* receive variables */ tcp_seq rcv_adv; /* advertised window */ /* retransmit variables */ tcp_seq snd_max; /* highest sequence number sent; * used to recognize retransmits */ /* congestion control (for slow start, source quench, retransmit after loss) */ n_long snd_cwnd; /* congestion-controlled window */ n_long snd_ssthresh; /* snd_cwnd size threshhold for * for slow start exponential to * linear switch */ /* * transmit timing stuff. See below for scale of srtt and rttvar. * "Variance" is actually smoothed difference. */ u_short t_idle; /* inactivity time */ short t_rtt; /* round trip time */ tcp_seq t_rtseq; /* sequence number being timed */ short t_srtt; /* smoothed round-trip time */ short t_rttvar; /* variance in round-trip time */ u_short t_rttmin; /* minimum rtt allowed */ n_long max_sndwnd; /* largest window peer has offered */ /* out-of-band data */ char t_oobflags; /* have some */ char t_iobc; /* input character */ #define TCPOOB_HAVEDATA 0x01 #define TCPOOB_HADDATA 0x02 short t_softerror; /* possible error not yet reported */ /* RFC 1323 variables */ u_char snd_scale; /* window scaling for send window */ u_char rcv_scale; /* window scaling for recv window */ u_char request_r_scale; /* pending window scaling */ u_char requested_s_scale; n_long ts_recent; /* timestamp echo data */ n_long ts_recent_age; /* when last updated */ tcp_seq last_ack_sent; /* TUBA stuff */ caddr_t t_tuba_pcb; /* next level down pcb for TCP over z */ }; #define intotcpcb(ip) ((struct tcpcb *)(ip)->inp_ppcb) #define sototcpcb(so) (intotcpcb(sotoinpcb(so))) /* * The smoothed round-trip time and estimated variance * are stored as fixed point numbers scaled by the values below. * For convenience, these scales are also used in smoothing the average * (smoothed = (1/scale)sample + ((scale-1)/scale)smoothed). * With these scales, srtt has 3 bits to the right of the binary point, * and thus an "ALPHA" of 0.875. rttvar has 2 bits to the right of the * binary point, and is smoothed with an ALPHA of 0.75. */ #define TCP_RTT_SCALE 8 /* multiplier for srtt; 3 bits frac. */ #define TCP_RTT_SHIFT 3 /* shift for srtt; 3 bits frac. */ #define TCP_RTTVAR_SCALE 4 /* multiplier for rttvar; 2 bits */ #define TCP_RTTVAR_SHIFT 2 /* multiplier for rttvar; 2 bits */ /* * The initial retransmission should happen at rtt + 4 * rttvar. * Because of the way we do the smoothing, srtt and rttvar * will each average +1/2 tick of bias. When we compute * the retransmit timer, we want 1/2 tick of rounding and * 1 extra tick because of +-1/2 tick uncertainty in the * firing of the timer. The bias will give us exactly the * 1.5 tick we need. But, because the bias is * statistical, we have to test that we don't drop below * the minimum feasible timer (which is 2 ticks). * This macro assumes that the value of TCP_RTTVAR_SCALE * is the same as the multiplier for rttvar. */ #define TCP_REXMTVAL(tp) \ (((tp)->t_srtt >> TCP_RTT_SHIFT) + (tp)->t_rttvar) /* XXX * We want to avoid doing m_pullup on incoming packets but that * means avoiding dtom on the tcp reassembly code. That in turn means * keeping an mbuf pointer in the reassembly queue (since we might * have a cluster). As a quick hack, the source & destination * port numbers (which are no longer needed once we've located the * tcpcb) are overlayed with an mbuf pointer. */ #define REASS_MBUF(ti) (*(struct mbuf **)&((ti)->ti_t)) /* * TCP statistics. * Many of these should be kept per connection, * but that's inconvenient at the moment. */ struct tcpstat { n_long tcps_connattempt; /* connections initiated */ n_long tcps_accepts; /* connections accepted */ n_long tcps_connects; /* connections established */ n_long tcps_drops; /* connections dropped */ n_long tcps_conndrops; /* embryonic connections dropped */ n_long tcps_closed; /* conn. closed (includes drops) */ n_long tcps_segstimed; /* segs where we tried to get rtt */ n_long tcps_rttupdated; /* times we succeeded */ n_long tcps_delack; /* delayed acks sent */ n_long tcps_timeoutdrop; /* conn. dropped in rxmt timeout */ n_long tcps_rexmttimeo; /* retransmit timeouts */ n_long tcps_persisttimeo; /* persist timeouts */ n_long tcps_keeptimeo; /* keepalive timeouts */ n_long tcps_keepprobe; /* keepalive probes sent */ n_long tcps_keepdrops; /* connections dropped in keepalive */ n_long tcps_sndtotal; /* total packets sent */ n_long tcps_sndpack; /* data packets sent */ n_long tcps_sndbyte; /* data bytes sent */ n_long tcps_sndrexmitpack; /* data packets retransmitted */ n_long tcps_sndrexmitbyte; /* data bytes retransmitted */ n_long tcps_sndacks; /* ack-only packets sent */ n_long tcps_sndprobe; /* window probes sent */ n_long tcps_sndurg; /* packets sent with URG only */ n_long tcps_sndwinup; /* window update-only packets sent */ n_long tcps_sndctrl; /* control (SYN|FIN|RST) packets sent */ n_long tcps_rcvtotal; /* total packets received */ n_long tcps_rcvpack; /* packets received in sequence */ n_long tcps_rcvbyte; /* bytes received in sequence */ n_long tcps_rcvbadsum; /* packets received with ccksum errs */ n_long tcps_rcvbadoff; /* packets received with bad offset */ n_long tcps_rcvshort; /* packets received too short */ n_long tcps_rcvduppack; /* duplicate-only packets received */ n_long tcps_rcvdupbyte; /* duplicate-only bytes received */ n_long tcps_rcvpartduppack; /* packets with some duplicate data */ n_long tcps_rcvpartdupbyte; /* dup. bytes in part-dup. packets */ n_long tcps_rcvoopack; /* out-of-order packets received */ n_long tcps_rcvoobyte; /* out-of-order bytes received */ n_long tcps_rcvpackafterwin; /* packets with data after window */ n_long tcps_rcvbyteafterwin; /* bytes rcvd after window */ n_long tcps_rcvafterclose; /* packets rcvd after "close" */ n_long tcps_rcvwinprobe; /* rcvd window probe packets */ n_long tcps_rcvdupack; /* rcvd duplicate acks */ n_long tcps_rcvacktoomuch; /* rcvd acks for unsent data */ n_long tcps_rcvackpack; /* rcvd ack packets */ n_long tcps_rcvackbyte; /* bytes acked by rcvd acks */ n_long tcps_rcvwinupd; /* rcvd window update packets */ n_long tcps_pawsdrop; /* segments dropped due to PAWS */ n_long tcps_predack; /* times hdr predict ok for acks */ n_long tcps_preddat; /* times hdr predict ok for data pkts */ n_long tcps_pcbcachemiss; n_long tcps_persistdrop; /* timeout in persist state */ n_long tcps_badsyn; /* bogus SYN, e.g. premature ACK */ }; #ifdef KERNEL struct inpcb tcb; /* head of queue of active tcpcb's */ struct tcpstat tcpstat; /* tcp statistics */ n_long tcp_now; /* for RFC 1323 timestamps */ int tcp_attach __P((struct socket *)); void tcp_canceltimers __P((struct tcpcb *)); struct tcpcb * tcp_close __P((struct tcpcb *)); void tcp_ctlinput __P((int, struct sockaddr *, struct ip *)); int tcp_ctloutput __P((int, struct socket *, int, int, struct mbuf **)); struct tcpcb * tcp_disconnect __P((struct tcpcb *)); struct tcpcb * tcp_drop __P((struct tcpcb *, int)); void tcp_dooptions __P((struct tcpcb *, u_char *, int, struct tcpiphdr *, int *, n_long *, n_long *)); void tcp_drain __P((void)); void tcp_fasttimo __P((void)); void tcp_init __P((void)); void tcp_input __P((struct mbuf *, int)); int tcp_mss __P((struct tcpcb *, u_int)); struct tcpcb * tcp_newtcpcb __P((struct inpcb *)); void tcp_notify __P((struct inpcb *, int)); int tcp_output __P((struct tcpcb *)); void tcp_pulloutofband __P((struct socket *, struct tcpiphdr *, struct mbuf *)); void tcp_quench __P((struct inpcb *, int)); int tcp_reass __P((struct tcpcb *, struct tcpiphdr *, struct mbuf *)); void tcp_respond __P((struct tcpcb *, struct tcpiphdr *, struct mbuf *, n_long, n_long, int)); void tcp_setpersist __P((struct tcpcb *)); void tcp_slowtimo __P((void)); struct tcpiphdr * tcp_template __P((struct tcpcb *)); struct tcpcb * tcp_timers __P((struct tcpcb *, int)); void tcp_trace __P((int, int, struct tcpcb *, struct tcpiphdr *, int)); struct tcpcb * tcp_usrclosed __P((struct tcpcb *)); int tcp_usrreq __P((struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *)); void tcp_xmit_timer __P((struct tcpcb *, int)); #endif snort-2.9.15.1/src/win32/WIN32-Includes/NETINET/UDP.H0000444000175200017520000000410113571422607016010 00000000000000/* * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)udp.h 8.1 (Berkeley) 6/10/93 */ /* * Udp protocol header. * Per RFC 768, September, 1981. */ struct udphdr { u_short uh_sport; /* source port */ u_short uh_dport; /* destination port */ short uh_ulen; /* udp length */ u_short uh_sum; /* udp checksum */ }; snort-2.9.15.1/src/win32/WIN32-Includes/NETINET/UDP_VAR.H0000444000175200017520000000677413571422607016542 00000000000000/* * Copyright (c) 1982, 1986, 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)udp_var.h 8.1 (Berkeley) 6/10/93 */ /* * UDP kernel structures and variables. */ struct udpiphdr { struct ipovly ui_i; /* overlaid ip structure */ struct udphdr ui_u; /* udp header */ }; #define ui_next ui_i.ih_next #define ui_prev ui_i.ih_prev #define ui_x1 ui_i.ih_x1 #define ui_pr ui_i.ih_pr #define ui_len ui_i.ih_len #define ui_src ui_i.ih_src #define ui_dst ui_i.ih_dst #define ui_sport ui_u.uh_sport #define ui_dport ui_u.uh_dport #define ui_ulen ui_u.uh_ulen #define ui_sum ui_u.uh_sum struct udpstat { /* input statistics: */ n_long udps_ipackets; /* total input packets */ n_long udps_hdrops; /* packet shorter than header */ n_long udps_badsum; /* checksum error */ n_long udps_badlen; /* data length larger than packet */ n_long udps_noport; /* no socket on port */ n_long udps_noportbcast; /* of above, arrived as broadcast */ n_long udps_fullsock; /* not delivered, input socket full */ n_long udpps_pcbcachemiss; /* input packets missing pcb cache */ /* output statistics: */ n_long udps_opackets; /* total output packets */ }; /* * Names for UDP sysctl objects */ #define UDPCTL_CHECKSUM 1 /* checksum UDP packets */ #define UDPCTL_MAXID 2 #define UDPCTL_NAMES { \ { 0, 0 }, \ { "checksum", CTLTYPE_INT }, \ } #ifdef KERNEL struct inpcb udb; struct udpstat udpstat; void udp_ctlinput __P((int, struct sockaddr *, struct ip *)); void udp_init __P((void)); void udp_input __P((struct mbuf *, int)); int udp_output __P((struct inpcb *, struct mbuf *, struct mbuf *, struct mbuf *)); int udp_sysctl __P((int *, u_int, void *, size_t *, void *, size_t)); int udp_usrreq __P((struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *)); #endif snort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/0000755000000000000000000000000013571426520015370 500000000000000snort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/pcap/0000755000000000000000000000000013571426520016313 500000000000000snort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/pcap/bluetooth.h0000644000175200017520000000362313571422610020447 00000000000000/* * Copyright (c) 2006 Paolo Abeni (Italy) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * bluetooth data struct * By Paolo Abeni * * @(#) $Header$ */ #ifndef _PCAP_BLUETOOTH_STRUCTS_H__ #define _PCAP_BLUETOOTH_STRUCTS_H__ /* * Header prepended libpcap to each bluetooth h:4 frame. * fields are in network byte order */ typedef struct _pcap_bluetooth_h4_header { u_int32_t direction; /* if first bit is set direction is incoming */ } pcap_bluetooth_h4_header; #endif snort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/pcap/bpf.h0000644000175200017520000007055313571422610017217 00000000000000/*- * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 * The Regents of the University of California. All rights reserved. * * This code is derived from the Stanford/CMU enet packet filter, * (net/enet.c) distributed as part of 4.3BSD, and code contributed * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence * Berkeley Laboratory. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)bpf.h 7.1 (Berkeley) 5/7/91 * * @(#) $Header$ (LBL) */ /* * This is libpcap's cut-down version of bpf.h; it includes only * the stuff needed for the code generator and the userland BPF * interpreter, and the libpcap APIs for setting filters, etc.. * * "pcap-bpf.c" will include the native OS version, as it deals with * the OS's BPF implementation. * * XXX - should this all just be moved to "pcap.h"? */ #ifndef BPF_MAJOR_VERSION #ifdef __cplusplus extern "C" { #endif /* BSD style release date */ #define BPF_RELEASE 199606 #ifdef MSDOS /* must be 32-bit */ typedef long bpf_int32; typedef unsigned long bpf_u_int32; #else typedef int bpf_int32; typedef u_int bpf_u_int32; #endif /* * Alignment macros. BPF_WORDALIGN rounds up to the next * even multiple of BPF_ALIGNMENT. */ #ifndef __NetBSD__ #define BPF_ALIGNMENT sizeof(bpf_int32) #else #define BPF_ALIGNMENT sizeof(long) #endif #define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1)) #define BPF_MAXBUFSIZE 0x8000 #define BPF_MINBUFSIZE 32 /* * Structure for "pcap_compile()", "pcap_setfilter()", etc.. */ struct bpf_program { u_int bf_len; struct bpf_insn *bf_insns; }; /* * Struct return by BIOCVERSION. This represents the version number of * the filter language described by the instruction encodings below. * bpf understands a program iff kernel_major == filter_major && * kernel_minor >= filter_minor, that is, if the value returned by the * running kernel has the same major number and a minor number equal * equal to or less than the filter being downloaded. Otherwise, the * results are undefined, meaning an error may be returned or packets * may be accepted haphazardly. * It has nothing to do with the source code version. */ struct bpf_version { u_short bv_major; u_short bv_minor; }; /* Current version number of filter architecture. */ #define BPF_MAJOR_VERSION 1 #define BPF_MINOR_VERSION 1 /* * Data-link level type codes. * * Do *NOT* add new values to this list without asking * "tcpdump-workers@lists.tcpdump.org" for a value. Otherwise, you run * the risk of using a value that's already being used for some other * purpose, and of having tools that read libpcap-format captures not * being able to handle captures with your new DLT_ value, with no hope * that they will ever be changed to do so (as that would destroy their * ability to read captures using that value for that other purpose). */ /* * These are the types that are the same on all platforms, and that * have been defined by for ages. */ #define DLT_NULL 0 /* BSD loopback encapsulation */ #define DLT_EN10MB 1 /* Ethernet (10Mb) */ #define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ #define DLT_AX25 3 /* Amateur Radio AX.25 */ #define DLT_PRONET 4 /* Proteon ProNET Token Ring */ #define DLT_CHAOS 5 /* Chaos */ #define DLT_IEEE802 6 /* 802.5 Token Ring */ #define DLT_ARCNET 7 /* ARCNET, with BSD-style header */ #define DLT_SLIP 8 /* Serial Line IP */ #define DLT_PPP 9 /* Point-to-point Protocol */ #define DLT_FDDI 10 /* FDDI */ /* * These are types that are different on some platforms, and that * have been defined by for ages. We use #ifdefs to * detect the BSDs that define them differently from the traditional * libpcap * * XXX - DLT_ATM_RFC1483 is 13 in BSD/OS, and DLT_RAW is 14 in BSD/OS, * but I don't know what the right #define is for BSD/OS. */ #define DLT_ATM_RFC1483 11 /* LLC-encapsulated ATM */ #ifdef __OpenBSD__ #define DLT_RAW 14 /* raw IP */ #else #define DLT_RAW 12 /* raw IP */ #endif /* * Given that the only OS that currently generates BSD/OS SLIP or PPP * is, well, BSD/OS, arguably everybody should have chosen its values * for DLT_SLIP_BSDOS and DLT_PPP_BSDOS, which are 15 and 16, but they * didn't. So it goes. */ #if defined(__NetBSD__) || defined(__FreeBSD__) #ifndef DLT_SLIP_BSDOS #define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */ #define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */ #endif #else #define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ #define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ #endif /* * 17 is used for DLT_OLD_PFLOG in OpenBSD; * OBSOLETE: DLT_PFLOG is 117 in OpenBSD now as well. See below. * 18 is used for DLT_PFSYNC in OpenBSD; don't use it for anything else. */ #define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ /* * Apparently Redback uses this for its SmartEdge 400/800. I hope * nobody else decided to use it, too. */ #define DLT_REDBACK_SMARTEDGE 32 /* * These values are defined by NetBSD; other platforms should refrain from * using them for other purposes, so that NetBSD savefiles with link * types of 50 or 51 can be read as this type on all platforms. */ #define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */ #define DLT_PPP_ETHER 51 /* PPP over Ethernet */ /* * The Axent Raptor firewall - now the Symantec Enterprise Firewall - uses * a link-layer type of 99 for the tcpdump it supplies. The link-layer * header has 6 bytes of unknown data, something that appears to be an * Ethernet type, and 36 bytes that appear to be 0 in at least one capture * I've seen. */ #define DLT_SYMANTEC_FIREWALL 99 /* * Values between 100 and 103 are used in capture file headers as * link-layer types corresponding to DLT_ types that differ * between platforms; don't use those values for new DLT_ new types. */ /* * This value was defined by libpcap 0.5; platforms that have defined * it with a different value should define it here with that value - * a link type of 104 in a save file will be mapped to DLT_C_HDLC, * whatever value that happens to be, so programs will correctly * handle files with that link type regardless of the value of * DLT_C_HDLC. * * The name DLT_C_HDLC was used by BSD/OS; we use that name for source * compatibility with programs written for BSD/OS. * * libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well, * for source compatibility with programs written for libpcap 0.5. */ #define DLT_C_HDLC 104 /* Cisco HDLC */ #define DLT_CHDLC DLT_C_HDLC #define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ /* * 106 is reserved for Linux Classical IP over ATM; it's like DLT_RAW, * except when it isn't. (I.e., sometimes it's just raw IP, and * sometimes it isn't.) We currently handle it as DLT_LINUX_SLL, * so that we don't have to worry about the link-layer header.) */ /* * Frame Relay; BSD/OS has a DLT_FR with a value of 11, but that collides * with other values. * DLT_FR and DLT_FRELAY packets start with the Q.922 Frame Relay header * (DLCI, etc.). */ #define DLT_FRELAY 107 /* * OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except * that the AF_ type in the link-layer header is in network byte order. * * DLT_LOOP is 12 in OpenBSD, but that's DLT_RAW in other OSes, so * we don't use 12 for it in OSes other than OpenBSD. */ #ifdef __OpenBSD__ #define DLT_LOOP 12 #else #define DLT_LOOP 108 #endif /* * Encapsulated packets for IPsec; DLT_ENC is 13 in OpenBSD, but that's * DLT_SLIP_BSDOS in NetBSD, so we don't use 13 for it in OSes other * than OpenBSD. */ #ifdef __OpenBSD__ #define DLT_ENC 13 #else #define DLT_ENC 109 #endif /* * Values between 110 and 112 are reserved for use in capture file headers * as link-layer types corresponding to DLT_ types that might differ * between platforms; don't use those values for new DLT_ types * other than the corresponding DLT_ types. */ /* * This is for Linux cooked sockets. */ #define DLT_LINUX_SLL 113 /* * Apple LocalTalk hardware. */ #define DLT_LTALK 114 /* * Acorn Econet. */ #define DLT_ECONET 115 /* * Reserved for use with OpenBSD ipfilter. */ #define DLT_IPFILTER 116 /* * OpenBSD DLT_PFLOG; DLT_PFLOG is 17 in OpenBSD, but that's DLT_LANE8023 * in SuSE 6.3, so we can't use 17 for it in capture-file headers. * * XXX: is there a conflict with DLT_PFSYNC 18 as well? */ #ifdef __OpenBSD__ #define DLT_OLD_PFLOG 17 #define DLT_PFSYNC 18 #endif #define DLT_PFLOG 117 /* * Registered for Cisco-internal use. */ #define DLT_CISCO_IOS 118 /* * For 802.11 cards using the Prism II chips, with a link-layer * header including Prism monitor mode information plus an 802.11 * header. */ #define DLT_PRISM_HEADER 119 /* * Reserved for Aironet 802.11 cards, with an Aironet link-layer header * (see Doug Ambrisko's FreeBSD patches). */ #define DLT_AIRONET_HEADER 120 /* * Reserved for Siemens HiPath HDLC. */ #define DLT_HHDLC 121 /* * This is for RFC 2625 IP-over-Fibre Channel. * * This is not for use with raw Fibre Channel, where the link-layer * header starts with a Fibre Channel frame header; it's for IP-over-FC, * where the link-layer header starts with an RFC 2625 Network_Header * field. */ #define DLT_IP_OVER_FC 122 /* * This is for Full Frontal ATM on Solaris with SunATM, with a * pseudo-header followed by an AALn PDU. * * There may be other forms of Full Frontal ATM on other OSes, * with different pseudo-headers. * * If ATM software returns a pseudo-header with VPI/VCI information * (and, ideally, packet type information, e.g. signalling, ILMI, * LANE, LLC-multiplexed traffic, etc.), it should not use * DLT_ATM_RFC1483, but should get a new DLT_ value, so tcpdump * and the like don't have to infer the presence or absence of a * pseudo-header and the form of the pseudo-header. */ #define DLT_SUNATM 123 /* Solaris+SunATM */ /* * Reserved as per request from Kent Dahlgren * for private use. */ #define DLT_RIO 124 /* RapidIO */ #define DLT_PCI_EXP 125 /* PCI Express */ #define DLT_AURORA 126 /* Xilinx Aurora link layer */ /* * Header for 802.11 plus a number of bits of link-layer information * including radio information, used by some recent BSD drivers as * well as the madwifi Atheros driver for Linux. */ #define DLT_IEEE802_11_RADIO 127 /* 802.11 plus radiotap radio header */ /* * Reserved for the TZSP encapsulation, as per request from * Chris Waters * TZSP is a generic encapsulation for any other link type, * which includes a means to include meta-information * with the packet, e.g. signal strength and channel * for 802.11 packets. */ #define DLT_TZSP 128 /* Tazmen Sniffer Protocol */ /* * BSD's ARCNET headers have the source host, destination host, * and type at the beginning of the packet; that's what's handed * up to userland via BPF. * * Linux's ARCNET headers, however, have a 2-byte offset field * between the host IDs and the type; that's what's handed up * to userland via PF_PACKET sockets. * * We therefore have to have separate DLT_ values for them. */ #define DLT_ARCNET_LINUX 129 /* ARCNET */ /* * Juniper-private data link types, as per request from * Hannes Gredler . The DLT_s are used * for passing on chassis-internal metainformation such as * QOS profiles, etc.. */ #define DLT_JUNIPER_MLPPP 130 #define DLT_JUNIPER_MLFR 131 #define DLT_JUNIPER_ES 132 #define DLT_JUNIPER_GGSN 133 #define DLT_JUNIPER_MFR 134 #define DLT_JUNIPER_ATM2 135 #define DLT_JUNIPER_SERVICES 136 #define DLT_JUNIPER_ATM1 137 /* * Apple IP-over-IEEE 1394, as per a request from Dieter Siegmund * . The header that's presented is an Ethernet-like * header: * * #define FIREWIRE_EUI64_LEN 8 * struct firewire_header { * u_char firewire_dhost[FIREWIRE_EUI64_LEN]; * u_char firewire_shost[FIREWIRE_EUI64_LEN]; * u_short firewire_type; * }; * * with "firewire_type" being an Ethernet type value, rather than, * for example, raw GASP frames being handed up. */ #define DLT_APPLE_IP_OVER_IEEE1394 138 /* * Various SS7 encapsulations, as per a request from Jeff Morriss * and subsequent discussions. */ #define DLT_MTP2_WITH_PHDR 139 /* pseudo-header with various info, followed by MTP2 */ #define DLT_MTP2 140 /* MTP2, without pseudo-header */ #define DLT_MTP3 141 /* MTP3, without pseudo-header or MTP2 */ #define DLT_SCCP 142 /* SCCP, without pseudo-header or MTP2 or MTP3 */ /* * DOCSIS MAC frames. */ #define DLT_DOCSIS 143 /* * Linux-IrDA packets. Protocol defined at http://www.irda.org. * Those packets include IrLAP headers and above (IrLMP...), but * don't include Phy framing (SOF/EOF/CRC & byte stuffing), because Phy * framing can be handled by the hardware and depend on the bitrate. * This is exactly the format you would get capturing on a Linux-IrDA * interface (irdaX), but not on a raw serial port. * Note the capture is done in "Linux-cooked" mode, so each packet include * a fake packet header (struct sll_header). This is because IrDA packet * decoding is dependant on the direction of the packet (incomming or * outgoing). * When/if other platform implement IrDA capture, we may revisit the * issue and define a real DLT_IRDA... * Jean II */ #define DLT_LINUX_IRDA 144 /* * Reserved for IBM SP switch and IBM Next Federation switch. */ #define DLT_IBM_SP 145 #define DLT_IBM_SN 146 /* * Reserved for private use. If you have some link-layer header type * that you want to use within your organization, with the capture files * using that link-layer header type not ever be sent outside your * organization, you can use these values. * * No libpcap release will use these for any purpose, nor will any * tcpdump release use them, either. * * Do *NOT* use these in capture files that you expect anybody not using * your private versions of capture-file-reading tools to read; in * particular, do *NOT* use them in products, otherwise you may find that * people won't be able to use tcpdump, or snort, or Ethereal, or... to * read capture files from your firewall/intrusion detection/traffic * monitoring/etc. appliance, or whatever product uses that DLT_ value, * and you may also find that the developers of those applications will * not accept patches to let them read those files. * * Also, do not use them if somebody might send you a capture using them * for *their* private type and tools using them for *your* private type * would have to read them. * * Instead, ask "tcpdump-workers@lists.tcpdump.org" for a new DLT_ value, * as per the comment above, and use the type you're given. */ #define DLT_USER0 147 #define DLT_USER1 148 #define DLT_USER2 149 #define DLT_USER3 150 #define DLT_USER4 151 #define DLT_USER5 152 #define DLT_USER6 153 #define DLT_USER7 154 #define DLT_USER8 155 #define DLT_USER9 156 #define DLT_USER10 157 #define DLT_USER11 158 #define DLT_USER12 159 #define DLT_USER13 160 #define DLT_USER14 161 #define DLT_USER15 162 /* * For future use with 802.11 captures - defined by AbsoluteValue * Systems to store a number of bits of link-layer information * including radio information: * * http://www.shaftnet.org/~pizza/software/capturefrm.txt * * but it might be used by some non-AVS drivers now or in the * future. */ #define DLT_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */ /* * Juniper-private data link type, as per request from * Hannes Gredler . The DLT_s are used * for passing on chassis-internal metainformation such as * QOS profiles, etc.. */ #define DLT_JUNIPER_MONITOR 164 /* * Reserved for BACnet MS/TP. */ #define DLT_BACNET_MS_TP 165 /* * Another PPP variant as per request from Karsten Keil . * * This is used in some OSes to allow a kernel socket filter to distinguish * between incoming and outgoing packets, on a socket intended to * supply pppd with outgoing packets so it can do dial-on-demand and * hangup-on-lack-of-demand; incoming packets are filtered out so they * don't cause pppd to hold the connection up (you don't want random * input packets such as port scans, packets from old lost connections, * etc. to force the connection to stay up). * * The first byte of the PPP header (0xff03) is modified to accomodate * the direction - 0x00 = IN, 0x01 = OUT. */ #define DLT_PPP_PPPD 166 /* * Names for backwards compatibility with older versions of some PPP * software; new software should use DLT_PPP_PPPD. */ #define DLT_PPP_WITH_DIRECTION DLT_PPP_PPPD #define DLT_LINUX_PPP_WITHDIRECTION DLT_PPP_PPPD /* * Juniper-private data link type, as per request from * Hannes Gredler . The DLT_s are used * for passing on chassis-internal metainformation such as * QOS profiles, cookies, etc.. */ #define DLT_JUNIPER_PPPOE 167 #define DLT_JUNIPER_PPPOE_ATM 168 #define DLT_GPRS_LLC 169 /* GPRS LLC */ #define DLT_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */ #define DLT_GPF_F 171 /* GPF-F (ITU-T G.7041/Y.1303) */ /* * Requested by Oolan Zimmer for use in Gcom's T1/E1 line * monitoring equipment. */ #define DLT_GCOM_T1E1 172 #define DLT_GCOM_SERIAL 173 /* * Juniper-private data link type, as per request from * Hannes Gredler . The DLT_ is used * for internal communication to Physical Interface Cards (PIC) */ #define DLT_JUNIPER_PIC_PEER 174 /* * Link types requested by Gregor Maier of Endace * Measurement Systems. They add an ERF header (see * http://www.endace.com/support/EndaceRecordFormat.pdf) in front of * the link-layer header. */ #define DLT_ERF_ETH 175 /* Ethernet */ #define DLT_ERF_POS 176 /* Packet-over-SONET */ /* * Requested by Daniele Orlandi for raw LAPD * for vISDN (http://www.orlandi.com/visdn/). Its link-layer header * includes additional information before the LAPD header, so it's * not necessarily a generic LAPD header. */ #define DLT_LINUX_LAPD 177 /* * Juniper-private data link type, as per request from * Hannes Gredler . * The DLT_ are used for prepending meta-information * like interface index, interface name * before standard Ethernet, PPP, Frelay & C-HDLC Frames */ #define DLT_JUNIPER_ETHER 178 #define DLT_JUNIPER_PPP 179 #define DLT_JUNIPER_FRELAY 180 #define DLT_JUNIPER_CHDLC 181 /* * Multi Link Frame Relay (FRF.16) */ #define DLT_MFR 182 /* * Juniper-private data link type, as per request from * Hannes Gredler . * The DLT_ is used for internal communication with a * voice Adapter Card (PIC) */ #define DLT_JUNIPER_VP 183 /* * Arinc 429 frames. * DLT_ requested by Gianluca Varenni . * Every frame contains a 32bit A429 label. * More documentation on Arinc 429 can be found at * http://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf */ #define DLT_A429 184 /* * Arinc 653 Interpartition Communication messages. * DLT_ requested by Gianluca Varenni . * Please refer to the A653-1 standard for more information. */ #define DLT_A653_ICM 185 /* * USB packets, beginning with a USB setup header; requested by * Paolo Abeni . */ #define DLT_USB 186 /* * Bluetooth HCI UART transport layer (part H:4); requested by * Paolo Abeni. */ #define DLT_BLUETOOTH_HCI_H4 187 /* * IEEE 802.16 MAC Common Part Sublayer; requested by Maria Cruz * . */ #define DLT_IEEE802_16_MAC_CPS 188 /* * USB packets, beginning with a Linux USB header; requested by * Paolo Abeni . */ #define DLT_USB_LINUX 189 /* * Controller Area Network (CAN) v. 2.0B packets. * DLT_ requested by Gianluca Varenni . * Used to dump CAN packets coming from a CAN Vector board. * More documentation on the CAN v2.0B frames can be found at * http://www.can-cia.org/downloads/?269 */ #define DLT_CAN20B 190 /* * IEEE 802.15.4, with address fields padded, as is done by Linux * drivers; requested by Juergen Schimmer. */ #define DLT_IEEE802_15_4_LINUX 191 /* * Per Packet Information encapsulated packets. * DLT_ requested by Gianluca Varenni . */ #define DLT_PPI 192 /* * Header for 802.16 MAC Common Part Sublayer plus a radiotap radio header; * requested by Charles Clancy. */ #define DLT_IEEE802_16_MAC_CPS_RADIO 193 /* * Juniper-private data link type, as per request from * Hannes Gredler . * The DLT_ is used for internal communication with a * integrated service module (ISM). */ #define DLT_JUNIPER_ISM 194 /* * IEEE 802.15.4, exactly as it appears in the spec (no padding, no * nothing); requested by Mikko Saarnivala . */ #define DLT_IEEE802_15_4 195 /* * Various link-layer types, with a pseudo-header, for SITA * (http://www.sita.aero/); requested by Fulko Hew (fulko.hew@gmail.com). */ #define DLT_SITA 196 /* * Various link-layer types, with a pseudo-header, for Endace DAG cards; * encapsulates Endace ERF records. Requested by Stephen Donnelly * . */ #define DLT_ERF 197 /* * Special header prepended to Ethernet packets when capturing from a * u10 Networks board. Requested by Phil Mulholland * . */ #define DLT_RAIF1 198 /* * IPMB packet for IPMI, beginning with the I2C slave address, followed * by the netFn and LUN, etc.. Requested by Chanthy Toeung * . */ #define DLT_IPMB 199 /* * Juniper-private data link type, as per request from * Hannes Gredler . * The DLT_ is used for capturing data on a secure tunnel interface. */ #define DLT_JUNIPER_ST 200 /* * Bluetooth HCI UART transport layer (part H:4), with pseudo-header * that includes direction information; requested by Paolo Abeni. */ #define DLT_BLUETOOTH_HCI_H4_WITH_PHDR 201 /* * AX.25 packet with a 1-byte KISS header; see * * http://www.ax25.net/kiss.htm * * as per Richard Stearn . */ #define DLT_AX25_KISS 202 /* * LAPD packets from an ISDN channel, starting with the address field, * with no pseudo-header. * Requested by Varuna De Silva . */ #define DLT_LAPD 203 /* * Variants of various link-layer headers, with a one-byte direction * pseudo-header prepended - zero means "received by this host", * non-zero (any non-zero value) means "sent by this host" - as per * Will Barker . */ #define DLT_PPP_WITH_DIR 204 /* PPP - don't confuse with DLT_PPP_WITH_DIRECTION */ #define DLT_C_HDLC_WITH_DIR 205 /* Cisco HDLC */ #define DLT_FRELAY_WITH_DIR 206 /* Frame Relay */ #define DLT_LAPB_WITH_DIR 207 /* LAPB */ /* * 208 is reserved for an as-yet-unspecified proprietary link-layer * type, as requested by Will Barker. */ /* * IPMB with a Linux-specific pseudo-header; as requested by Alexey Neyman * . */ #define DLT_IPMB_LINUX 209 /* * FlexRay automotive bus - http://www.flexray.com/ - as requested * by Hannes Kaelber . */ #define DLT_FLEXRAY 210 /* * Media Oriented Systems Transport (MOST) bus for multimedia * transport - http://www.mostcooperation.com/ - as requested * by Hannes Kaelber . */ #define DLT_MOST 211 /* * Local Interconnect Network (LIN) bus for vehicle networks - * http://www.lin-subbus.org/ - as requested by Hannes Kaelber * . */ #define DLT_LIN 212 /* * X2E-private data link type used for serial line capture, * as requested by Hannes Kaelber . */ #define DLT_X2E_SERIAL 213 /* * X2E-private data link type used for the Xoraya data logger * family, as requested by Hannes Kaelber . */ #define DLT_X2E_XORAYA 214 /* * IEEE 802.15.4, exactly as it appears in the spec (no padding, no * nothing), but with the PHY-level data for non-ASK PHYs (4 octets * of 0 as preamble, one octet of SFD, one octet of frame length+ * reserved bit, and then the MAC-layer data, starting with the * frame control field). * * Requested by Max Filippov . */ #define DLT_IEEE802_15_4_NONASK_PHY 215 /* * DLT and savefile link type values are split into a class and * a member of that class. A class value of 0 indicates a regular * DLT_/LINKTYPE_ value. */ #define DLT_CLASS(x) ((x) & 0x03ff0000) /* * NetBSD-specific generic "raw" link type. The class value indicates * that this is the generic raw type, and the lower 16 bits are the * address family we're dealing with. Those values are NetBSD-specific; * do not assume that they correspond to AF_ values for your operating * system. */ #define DLT_CLASS_NETBSD_RAWAF 0x02240000 #define DLT_NETBSD_RAWAF(af) (DLT_CLASS_NETBSD_RAWAF | (af)) #define DLT_NETBSD_RAWAF_AF(x) ((x) & 0x0000ffff) #define DLT_IS_NETBSD_RAWAF(x) (DLT_CLASS(x) == DLT_CLASS_NETBSD_RAWAF) /* * The instruction encodings. */ /* instruction classes */ #define BPF_CLASS(code) ((code) & 0x07) #define BPF_LD 0x00 #define BPF_LDX 0x01 #define BPF_ST 0x02 #define BPF_STX 0x03 #define BPF_ALU 0x04 #define BPF_JMP 0x05 #define BPF_RET 0x06 #define BPF_MISC 0x07 /* ld/ldx fields */ #define BPF_SIZE(code) ((code) & 0x18) #define BPF_W 0x00 #define BPF_H 0x08 #define BPF_B 0x10 #define BPF_MODE(code) ((code) & 0xe0) #define BPF_IMM 0x00 #define BPF_ABS 0x20 #define BPF_IND 0x40 #define BPF_MEM 0x60 #define BPF_LEN 0x80 #define BPF_MSH 0xa0 /* alu/jmp fields */ #define BPF_OP(code) ((code) & 0xf0) #define BPF_ADD 0x00 #define BPF_SUB 0x10 #define BPF_MUL 0x20 #define BPF_DIV 0x30 #define BPF_OR 0x40 #define BPF_AND 0x50 #define BPF_LSH 0x60 #define BPF_RSH 0x70 #define BPF_NEG 0x80 #define BPF_JA 0x00 #define BPF_JEQ 0x10 #define BPF_JGT 0x20 #define BPF_JGE 0x30 #define BPF_JSET 0x40 #define BPF_SRC(code) ((code) & 0x08) #define BPF_K 0x00 #define BPF_X 0x08 /* ret - BPF_K and BPF_X also apply */ #define BPF_RVAL(code) ((code) & 0x18) #define BPF_A 0x10 /* misc */ #define BPF_MISCOP(code) ((code) & 0xf8) #define BPF_TAX 0x00 #define BPF_TXA 0x80 /* * The instruction data structure. */ struct bpf_insn { u_short code; u_char jt; u_char jf; bpf_u_int32 k; }; /* * Macros for insn array initializers. */ #define BPF_STMT(code, k) { (u_short)(code), 0, 0, k } #define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k } #if __STDC__ || defined(__cplusplus) extern int bpf_validate(const struct bpf_insn *, int); extern u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int); #else extern int bpf_validate(); extern u_int bpf_filter(); #endif /* * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST). */ #define BPF_MEMWORDS 16 #ifdef __cplusplus } #endif #endif snort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/pcap/namedb.h0000644000175200017520000000642313571422610017671 00000000000000/* * Copyright (c) 1994, 1996 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the Computer Systems * Engineering Group at Lawrence Berkeley Laboratory. * 4. Neither the name of the University nor of the Laboratory may be used * to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#) $Header$ (LBL) */ #ifndef lib_pcap_namedb_h #define lib_pcap_namedb_h #ifdef __cplusplus extern "C" { #endif /* * As returned by the pcap_next_etherent() * XXX this stuff doesn't belong in this interface, but this * library already must do name to address translation, so * on systems that don't have support for /etc/ethers, we * export these hooks since they'll */ struct pcap_etherent { u_char addr[6]; char name[122]; }; #ifndef PCAP_ETHERS_FILE #define PCAP_ETHERS_FILE "/etc/ethers" #endif struct pcap_etherent *pcap_next_etherent(FILE *); u_char *pcap_ether_hostton(const char*); u_char *pcap_ether_aton(const char *); bpf_u_int32 **pcap_nametoaddr(const char *); #ifdef INET6 struct addrinfo *pcap_nametoaddrinfo(const char *); #endif bpf_u_int32 pcap_nametonetaddr(const char *); int pcap_nametoport(const char *, int *, int *); int pcap_nametoportrange(const char *, int *, int *, int *); int pcap_nametoproto(const char *); int pcap_nametoeproto(const char *); int pcap_nametollc(const char *); /* * If a protocol is unknown, PROTO_UNDEF is returned. * Also, pcap_nametoport() returns the protocol along with the port number. * If there are ambiguous entried in /etc/services (i.e. domain * can be either tcp or udp) PROTO_UNDEF is returned. */ #define PROTO_UNDEF -1 /* XXX move these to pcap-int.h? */ int __pcap_atodn(const char *, bpf_u_int32 *); int __pcap_atoin(const char *, bpf_u_int32 *); u_short __pcap_nametodnaddr(const char *); #ifdef __cplusplus } #endif #endif snort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/pcap/pcap.h0000644000175200017520000003323013571422610017362 00000000000000/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ /* * Copyright (c) 1993, 1994, 1995, 1996, 1997 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the Computer Systems * Engineering Group at Lawrence Berkeley Laboratory. * 4. Neither the name of the University nor of the Laboratory may be used * to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#) $Header$ (LBL) */ #ifndef lib_pcap_pcap_h #define lib_pcap_pcap_h #if defined(WIN32) #include #elif defined(MSDOS) #include #include /* u_int, u_char etc. */ #else /* UN*X */ #include #include #endif /* WIN32/MSDOS/UN*X */ #ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H #include #endif #include #ifdef HAVE_REMOTE // We have to define the SOCKET here, although it has been defined in sockutils.h // This is to avoid the distribution of the 'sockutils.h' file around // (for example in the WinPcap developer's pack) #ifndef SOCKET #ifdef WIN32 #define SOCKET unsigned int #else #define SOCKET int #endif #endif #endif #ifdef __cplusplus extern "C" { #endif #define PCAP_VERSION_MAJOR 2 #define PCAP_VERSION_MINOR 4 #define PCAP_ERRBUF_SIZE 256 /* * Compatibility for systems that have a bpf.h that * predates the bpf typedefs for 64-bit support. */ #if BPF_RELEASE - 0 < 199406 typedef int bpf_int32; typedef u_int bpf_u_int32; #endif typedef struct pcap pcap_t; typedef struct pcap_dumper pcap_dumper_t; typedef struct pcap_if pcap_if_t; typedef struct pcap_addr pcap_addr_t; /* * The first record in the file contains saved values for some * of the flags used in the printout phases of tcpdump. * Many fields here are 32 bit ints so compilers won't insert unwanted * padding; these files need to be interchangeable across architectures. * * Do not change the layout of this structure, in any way (this includes * changes that only affect the length of fields in this structure). * * Also, do not change the interpretation of any of the members of this * structure, in any way (this includes using values other than * LINKTYPE_ values, as defined in "savefile.c", in the "linktype" * field). * * Instead: * * introduce a new structure for the new format, if the layout * of the structure changed; * * send mail to "tcpdump-workers@lists.tcpdump.org", requesting * a new magic number for your new capture file format, and, when * you get the new magic number, put it in "savefile.c"; * * use that magic number for save files with the changed file * header; * * make the code in "savefile.c" capable of reading files with * the old file header as well as files with the new file header * (using the magic number to determine the header format). * * Then supply the changes as a patch at * * http://sourceforge.net/projects/libpcap/ * * so that future versions of libpcap and programs that use it (such as * tcpdump) will be able to read your new capture file format. */ struct pcap_file_header { bpf_u_int32 magic; u_short version_major; u_short version_minor; bpf_int32 thiszone; /* gmt to local correction */ bpf_u_int32 sigfigs; /* accuracy of timestamps */ bpf_u_int32 snaplen; /* max length saved portion of each pkt */ bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */ }; /* * Macros for the value returned by pcap_datalink_ext(). * * If LT_FCS_LENGTH_PRESENT(x) is true, the LT_FCS_LENGTH(x) macro * gives the FCS length of packets in the capture. */ #define LT_FCS_LENGTH_PRESENT(x) ((x) & 0x04000000) #define LT_FCS_LENGTH(x) (((x) & 0xF0000000) >> 28) #define LT_FCS_DATALINK_EXT(x) ((((x) & 0xF) << 28) | 0x04000000) typedef enum { PCAP_D_INOUT = 0, PCAP_D_IN, PCAP_D_OUT } pcap_direction_t; /* * Generic per-packet information, as supplied by libpcap. * * The time stamp can and should be a "struct timeval", regardless of * whether your system supports 32-bit tv_sec in "struct timeval", * 64-bit tv_sec in "struct timeval", or both if it supports both 32-bit * and 64-bit applications. The on-disk format of savefiles uses 32-bit * tv_sec (and tv_usec); this structure is irrelevant to that. 32-bit * and 64-bit versions of libpcap, even if they're on the same platform, * should supply the appropriate version of "struct timeval", even if * that's not what the underlying packet capture mechanism supplies. */ struct pcap_pkthdr { struct timeval ts; /* time stamp */ bpf_u_int32 caplen; /* length of portion present */ bpf_u_int32 len; /* length this packet (off wire) */ }; /* * As returned by the pcap_stats() */ struct pcap_stat { u_int ps_recv; /* number of packets received */ u_int ps_drop; /* number of packets dropped */ u_int ps_ifdrop; /* drops by interface XXX not yet supported */ #ifdef HAVE_REMOTE u_int ps_capt; /* number of packets that are received by the application; please get rid off the Win32 ifdef */ u_int ps_sent; /* number of packets sent by the server on the network */ u_int ps_netdrop; /* number of packets lost on the network */ #endif /* HAVE_REMOTE */ }; #ifdef MSDOS /* * As returned by the pcap_stats_ex() */ struct pcap_stat_ex { u_long rx_packets; /* total packets received */ u_long tx_packets; /* total packets transmitted */ u_long rx_bytes; /* total bytes received */ u_long tx_bytes; /* total bytes transmitted */ u_long rx_errors; /* bad packets received */ u_long tx_errors; /* packet transmit problems */ u_long rx_dropped; /* no space in Rx buffers */ u_long tx_dropped; /* no space available for Tx */ u_long multicast; /* multicast packets received */ u_long collisions; /* detailed rx_errors: */ u_long rx_length_errors; u_long rx_over_errors; /* receiver ring buff overflow */ u_long rx_crc_errors; /* recv'd pkt with crc error */ u_long rx_frame_errors; /* recv'd frame alignment error */ u_long rx_fifo_errors; /* recv'r fifo overrun */ u_long rx_missed_errors; /* recv'r missed packet */ /* detailed tx_errors */ u_long tx_aborted_errors; u_long tx_carrier_errors; u_long tx_fifo_errors; u_long tx_heartbeat_errors; u_long tx_window_errors; }; #endif /* * Item in a list of interfaces. */ struct pcap_if { struct pcap_if *next; char *name; /* name to hand to "pcap_open_live()" */ char *description; /* textual description of interface, or NULL */ struct pcap_addr *addresses; bpf_u_int32 flags; /* PCAP_IF_ interface flags */ }; #define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */ /* * Representation of an interface address. */ struct pcap_addr { struct pcap_addr *next; struct sockaddr *addr; /* address */ struct sockaddr *netmask; /* netmask for that address */ struct sockaddr *broadaddr; /* broadcast address for that address */ struct sockaddr *dstaddr; /* P2P destination address for that address */ }; typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, const u_char *); /* * Error codes for the pcap API. * These will all be negative, so you can check for the success or * failure of a call that returns these codes by checking for a * negative value. */ #define PCAP_ERROR -1 /* generic error code */ #define PCAP_ERROR_BREAK -2 /* loop terminated by pcap_breakloop */ #define PCAP_ERROR_NOT_ACTIVATED -3 /* the capture needs to be activated */ #define PCAP_ERROR_ACTIVATED -4 /* the operation can't be performed on already activated captures */ #define PCAP_ERROR_NO_SUCH_DEVICE -5 /* no such device exists */ #define PCAP_ERROR_RFMON_NOTSUP -6 /* this device doesn't support rfmon (monitor) mode */ #define PCAP_ERROR_NOT_RFMON -7 /* operation supported only in monitor mode */ #define PCAP_ERROR_PERM_DENIED -8 /* no permission to open the device */ #define PCAP_ERROR_IFACE_NOT_UP -9 /* interface isn't up */ /* * Warning codes for the pcap API. * These will all be positive and non-zero, so they won't look like * errors. */ #define PCAP_WARNING 1 /* generic warning code */ #define PCAP_WARNING_PROMISC_NOTSUP 2 /* this device doesn't support promiscuous mode */ char *pcap_lookupdev(char *); int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *); pcap_t *pcap_create(const char *, char *); int pcap_set_snaplen(pcap_t *, int); int pcap_set_promisc(pcap_t *, int); int pcap_can_set_rfmon(pcap_t *); int pcap_set_rfmon(pcap_t *, int); int pcap_set_timeout(pcap_t *, int); int pcap_set_buffer_size(pcap_t *, int); int pcap_activate(pcap_t *); pcap_t *pcap_open_live(const char *, int, int, int, char *); pcap_t *pcap_open_dead(int, int); pcap_t *pcap_open_offline(const char *, char *); #if defined(WIN32) pcap_t *pcap_hopen_offline(intptr_t, char *); #if !defined(LIBPCAP_EXPORTS) #define pcap_fopen_offline(f,b) \ pcap_hopen_offline(_get_osfhandle(_fileno(f)), b) #else /*LIBPCAP_EXPORTS*/ static pcap_t *pcap_fopen_offline(FILE *, char *); #endif #else /*WIN32*/ pcap_t *pcap_fopen_offline(FILE *, char *); #endif /*WIN32*/ void pcap_close(pcap_t *); int pcap_loop(pcap_t *, int, pcap_handler, u_char *); int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *); const u_char* pcap_next(pcap_t *, struct pcap_pkthdr *); int pcap_next_ex(pcap_t *, struct pcap_pkthdr **, const u_char **); void pcap_breakloop(pcap_t *); int pcap_stats(pcap_t *, struct pcap_stat *); int pcap_setfilter(pcap_t *, struct bpf_program *); int pcap_setdirection(pcap_t *, pcap_direction_t); int pcap_getnonblock(pcap_t *, char *); int pcap_setnonblock(pcap_t *, int, char *); int pcap_inject(pcap_t *, const void *, size_t); int pcap_sendpacket(pcap_t *, const u_char *, int); const char *pcap_statustostr(int); const char *pcap_strerror(int); char *pcap_geterr(pcap_t *); void pcap_perror(pcap_t *, char *); int pcap_compile(pcap_t *, struct bpf_program *, const char *, int, bpf_u_int32); int pcap_compile_nopcap(int, int, struct bpf_program *, const char *, int, bpf_u_int32); void pcap_freecode(struct bpf_program *); int pcap_offline_filter(struct bpf_program *, const struct pcap_pkthdr *, const u_char *); int pcap_datalink(pcap_t *); int pcap_datalink_ext(pcap_t *); int pcap_list_datalinks(pcap_t *, int **); int pcap_set_datalink(pcap_t *, int); void pcap_free_datalinks(int *); int pcap_datalink_name_to_val(const char *); const char *pcap_datalink_val_to_name(int); const char *pcap_datalink_val_to_description(int); int pcap_snapshot(pcap_t *); int pcap_is_swapped(pcap_t *); int pcap_major_version(pcap_t *); int pcap_minor_version(pcap_t *); /* XXX */ FILE *pcap_file(pcap_t *); int pcap_fileno(pcap_t *); pcap_dumper_t *pcap_dump_open(pcap_t *, const char *); pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp); FILE *pcap_dump_file(pcap_dumper_t *); long pcap_dump_ftell(pcap_dumper_t *); int pcap_dump_flush(pcap_dumper_t *); void pcap_dump_close(pcap_dumper_t *); void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *); int pcap_findalldevs(pcap_if_t **, char *); void pcap_freealldevs(pcap_if_t *); const char *pcap_lib_version(void); /* XXX this guy lives in the bpf tree */ u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int); int bpf_validate(const struct bpf_insn *f, int len); char *bpf_image(const struct bpf_insn *, int); void bpf_dump(const struct bpf_program *, int); #if defined(WIN32) /* * Win32 definitions */ int pcap_setbuff(pcap_t *p, int dim); int pcap_setmode(pcap_t *p, int mode); int pcap_setmintocopy(pcap_t *p, int size); #ifdef WPCAP /* Include file with the wpcap-specific extensions */ #include #endif /* WPCAP */ #define MODE_CAPT 0 #define MODE_STAT 1 #define MODE_MON 2 #elif defined(MSDOS) /* * MS-DOS definitions */ int pcap_stats_ex (pcap_t *, struct pcap_stat_ex *); void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait); u_long pcap_mac_packets (void); #else /* UN*X */ /* * UN*X definitions */ int pcap_get_selectable_fd(pcap_t *); #endif /* WIN32/MSDOS/UN*X */ #ifdef HAVE_REMOTE /* Includes most of the public stuff that is needed for the remote capture */ #include #endif /* HAVE_REMOTE */ #ifdef __cplusplus } #endif #endif snort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/pcap/sll.h0000644000175200017520000001256413571422610017240 00000000000000/*- * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 * The Regents of the University of California. All rights reserved. * * This code is derived from the Stanford/CMU enet packet filter, * (net/enet.c) distributed as part of 4.3BSD, and code contributed * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence * Berkeley Laboratory. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#) $Header$ (LBL) */ /* * For captures on Linux cooked sockets, we construct a fake header * that includes: * * a 2-byte "packet type" which is one of: * * LINUX_SLL_HOST packet was sent to us * LINUX_SLL_BROADCAST packet was broadcast * LINUX_SLL_MULTICAST packet was multicast * LINUX_SLL_OTHERHOST packet was sent to somebody else * LINUX_SLL_OUTGOING packet was sent *by* us; * * a 2-byte Ethernet protocol field; * * a 2-byte link-layer type; * * a 2-byte link-layer address length; * * an 8-byte source link-layer address, whose actual length is * specified by the previous value. * * All fields except for the link-layer address are in network byte order. * * DO NOT change the layout of this structure, or change any of the * LINUX_SLL_ values below. If you must change the link-layer header * for a "cooked" Linux capture, introduce a new DLT_ type (ask * "tcpdump-workers@lists.tcpdump.org" for one, so that you don't give it * a value that collides with a value already being used), and use the * new header in captures of that type, so that programs that can * handle DLT_LINUX_SLL captures will continue to handle them correctly * without any change, and so that capture files with different headers * can be told apart and programs that read them can dissect the * packets in them. */ #ifndef lib_pcap_sll_h #define lib_pcap_sll_h /* * A DLT_LINUX_SLL fake link-layer header. */ #define SLL_HDR_LEN 16 /* total header length */ #define SLL_ADDRLEN 8 /* length of address field */ struct sll_header { u_int16_t sll_pkttype; /* packet type */ u_int16_t sll_hatype; /* link-layer address type */ u_int16_t sll_halen; /* link-layer address length */ u_int8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */ u_int16_t sll_protocol; /* protocol */ }; /* * The LINUX_SLL_ values for "sll_pkttype"; these correspond to the * PACKET_ values on Linux, but are defined here so that they're * available even on systems other than Linux, and so that they * don't change even if the PACKET_ values change. */ #define LINUX_SLL_HOST 0 #define LINUX_SLL_BROADCAST 1 #define LINUX_SLL_MULTICAST 2 #define LINUX_SLL_OTHERHOST 3 #define LINUX_SLL_OUTGOING 4 /* * The LINUX_SLL_ values for "sll_protocol"; these correspond to the * ETH_P_ values on Linux, but are defined here so that they're * available even on systems other than Linux. We assume, for now, * that the ETH_P_ values won't change in Linux; if they do, then: * * if we don't translate them in "pcap-linux.c", capture files * won't necessarily be readable if captured on a system that * defines ETH_P_ values that don't match these values; * * if we do translate them in "pcap-linux.c", that makes life * unpleasant for the BPF code generator, as the values you test * for in the kernel aren't the values that you test for when * reading a capture file, so the fixup code run on BPF programs * handed to the kernel ends up having to do more work. * * Add other values here as necessary, for handling packet types that * might show up on non-Ethernet, non-802.x networks. (Not all the ones * in the Linux "if_ether.h" will, I suspect, actually show up in * captures.) */ #define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */ #define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */ #endif snort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/pcap/usb.h0000644000175200017520000000544613571422610017240 00000000000000/* * Copyright (c) 2006 Paolo Abeni (Italy) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Basic USB data struct * By Paolo Abeni * * @(#) $Header$ */ #ifndef _PCAP_USB_STRUCTS_H__ #define _PCAP_USB_STRUCTS_H__ /* * possible transfer mode */ #define URB_TRANSFER_IN 0x80 #define URB_ISOCHRONOUS 0x0 #define URB_INTERRUPT 0x1 #define URB_CONTROL 0x2 #define URB_BULK 0x3 /* * possible event type */ #define URB_SUBMIT 'S' #define URB_COMPLETE 'C' #define URB_ERROR 'E' /* * USB setup header as defined in USB specification. * Appears at the front of each packet in DLT_USB captures. */ typedef struct _usb_setup { u_int8_t bmRequestType; u_int8_t bRequest; u_int16_t wValue; u_int16_t wIndex; u_int16_t wLength; } pcap_usb_setup; /* * Header prepended by linux kernel to each event. * Appears at the front of each packet in DLT_USB_LINUX captures. */ typedef struct _usb_header { u_int64_t id; u_int8_t event_type; u_int8_t transfer_type; u_int8_t endpoint_number; u_int8_t device_address; u_int16_t bus_id; char setup_flag;/*if !=0 the urb setup header is not present*/ char data_flag; /*if !=0 no urb data is present*/ int64_t ts_sec; int32_t ts_usec; int32_t status; u_int32_t urb_len; u_int32_t data_len; /* amount of urb data really present in this event*/ pcap_usb_setup setup; } pcap_usb_header; #endif snort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/pcap/vlan.h0000644000175200017520000000403713571422610017402 00000000000000/*- * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#) $Header$ */ #ifndef lib_pcap_vlan_h #define lib_pcap_vlan_h struct vlan_tag { u_int16_t vlan_tpid; /* ETH_P_8021Q */ u_int16_t vlan_tci; /* VLAN TCI */ }; #define VLAN_TAG_LEN 4 #endif snort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/bittypes.h0000644000175200017520000000753013571422610017363 00000000000000/* * Copyright (C) 1999 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef _BITTYPES_H #define _BITTYPES_H #ifndef HAVE_U_INT8_T #if SIZEOF_CHAR == 1 typedef unsigned char u_int8_t; typedef signed char int8_t; #elif SIZEOF_INT == 1 typedef unsigned int u_int8_t; typedef signed int int8_t; #else /* XXX */ #error "there's no appropriate type for u_int8_t" #endif #define HAVE_U_INT8_T 1 #define HAVE_INT8_T 1 #endif /* HAVE_U_INT8_T */ #ifndef HAVE_U_INT16_T #if SIZEOF_SHORT == 2 typedef unsigned short u_int16_t; typedef signed short int16_t; #elif SIZEOF_INT == 2 typedef unsigned int u_int16_t; typedef signed int int16_t; #elif SIZEOF_CHAR == 2 typedef unsigned char u_int16_t; typedef signed char int16_t; #else /* XXX */ #error "there's no appropriate type for u_int16_t" #endif #define HAVE_U_INT16_T 1 #define HAVE_INT16_T 1 #endif /* HAVE_U_INT16_T */ #ifndef HAVE_U_INT32_T #if SIZEOF_INT == 4 typedef unsigned int u_int32_t; typedef signed int int32_t; #elif SIZEOF_LONG == 4 typedef unsigned long u_int32_t; typedef signed long int32_t; #elif SIZEOF_SHORT == 4 typedef unsigned short u_int32_t; typedef signed short int32_t; #else /* XXX */ #error "there's no appropriate type for u_int32_t" #endif #define HAVE_U_INT32_T 1 #define HAVE_INT32_T 1 #endif /* HAVE_U_INT32_T */ #ifndef HAVE_U_INT64_T #if SIZEOF_LONG_LONG == 8 typedef unsigned long long u_int64_t; typedef long long int64_t; #elif defined(_MSC_EXTENSIONS) typedef unsigned _int64 u_int64_t; typedef _int64 int64_t; #elif SIZEOF_INT == 8 typedef unsigned int u_int64_t; #elif SIZEOF_LONG == 8 typedef unsigned long u_int64_t; #elif SIZEOF_SHORT == 8 typedef unsigned short u_int64_t; #else /* XXX */ #error "there's no appropriate type for u_int64_t" #endif #endif /* HAVE_U_INT64_T */ #ifndef PRId64 #ifdef _MSC_EXTENSIONS #define PRId64 "I64d" #else /* _MSC_EXTENSIONS */ #define PRId64 "lld" #endif /* _MSC_EXTENSIONS */ #endif /* PRId64 */ #ifndef PRIo64 #ifdef _MSC_EXTENSIONS #define PRIo64 "I64o" #else /* _MSC_EXTENSIONS */ #define PRIo64 "llo" #endif /* _MSC_EXTENSIONS */ #endif /* PRIo64 */ #ifndef PRIx64 #ifdef _MSC_EXTENSIONS #define PRIx64 "I64x" #else /* _MSC_EXTENSIONS */ #define PRIx64 "llx" #endif /* _MSC_EXTENSIONS */ #endif /* PRIx64 */ #ifndef PRIu64 #ifdef _MSC_EXTENSIONS #define PRIu64 "I64u" #else /* _MSC_EXTENSIONS */ #define PRIu64 "llu" #endif /* _MSC_EXTENSIONS */ #endif /* PRIu64 */ #endif /* _BITTYPES_H */ snort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/bucket_lookup.h0000644000175200017520000000412513571422610020363 00000000000000/* * Copyright (c) 2001 - 2003 * NetGroup, Politecnico di Torino (Italy) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Politecnico di Torino nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef __bucket_lookup #define __bucket_lookup #ifdef WIN32 #include "tme.h" #endif #ifdef __FreeBSD__ #ifdef _KERNEL #include #else #include #endif #endif #define BUCKET_LOOKUP_INSERT 0x00000011 uint32 bucket_lookup_insert(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref); #define BUCKET_LOOKUP 0x00000010 uint32 bucket_lookup(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref); #endifsnort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/count_packets.h0000644000175200017520000000410113571422610020351 00000000000000/* * Copyright (c) 2001 - 2003 * NetGroup, Politecnico di Torino (Italy) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Politecnico di Torino nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef __count_packets #define __count_packets #ifdef WIN32 #include "tme.h" #endif #ifdef __FreeBSD__ #ifdef _KERNEL #include #else #include #endif #endif typedef struct __c_p_data { struct timeval timestamp; uint64 packets; uint64 bytes; } c_p_data; #define COUNT_PACKETS 0x00000000 uint32 count_packets(uint8 *block, uint32 pkt_size, TME_DATA *data, MEM_TYPE *mem_ex, uint8 *mem_data); #endif snort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/Devioctl.h0000644000175200017520000000757313571422607017306 00000000000000/*++ BUILD Version: 0004 // Increment this if a change has global effects Copyright (c) 1992-1993 Microsoft Corporation Module Name: devioctl.h Revision History: -- */ // begin_winioctl #ifndef _DEVIOCTL_ #define _DEVIOCTL_ // begin_ntddk begin_nthal begin_ntifs // // Define the various device type values. Note that values used by Microsoft // Corporation are in the range 0-32767, and 32768-65535 are reserved for use // by customers. // #define DEVICE_TYPE ULONG #define FILE_DEVICE_BEEP 0x00000001 #define FILE_DEVICE_CD_ROM 0x00000002 #define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003 #define FILE_DEVICE_CONTROLLER 0x00000004 #define FILE_DEVICE_DATALINK 0x00000005 #define FILE_DEVICE_DFS 0x00000006 #define FILE_DEVICE_DISK 0x00000007 #define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008 #define FILE_DEVICE_FILE_SYSTEM 0x00000009 #define FILE_DEVICE_INPORT_PORT 0x0000000a #define FILE_DEVICE_KEYBOARD 0x0000000b #define FILE_DEVICE_MAILSLOT 0x0000000c #define FILE_DEVICE_MIDI_IN 0x0000000d #define FILE_DEVICE_MIDI_OUT 0x0000000e #define FILE_DEVICE_MOUSE 0x0000000f #define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010 #define FILE_DEVICE_NAMED_PIPE 0x00000011 #define FILE_DEVICE_NETWORK 0x00000012 #define FILE_DEVICE_NETWORK_BROWSER 0x00000013 #define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014 #define FILE_DEVICE_NULL 0x00000015 #define FILE_DEVICE_PARALLEL_PORT 0x00000016 #define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017 #define FILE_DEVICE_PRINTER 0x00000018 #define FILE_DEVICE_SCANNER 0x00000019 #define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001a #define FILE_DEVICE_SERIAL_PORT 0x0000001b #define FILE_DEVICE_SCREEN 0x0000001c #define FILE_DEVICE_SOUND 0x0000001d #define FILE_DEVICE_STREAMS 0x0000001e #define FILE_DEVICE_TAPE 0x0000001f #define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020 #define FILE_DEVICE_TRANSPORT 0x00000021 #define FILE_DEVICE_UNKNOWN 0x00000022 #define FILE_DEVICE_VIDEO 0x00000023 #define FILE_DEVICE_VIRTUAL_DISK 0x00000024 #define FILE_DEVICE_WAVE_IN 0x00000025 #define FILE_DEVICE_WAVE_OUT 0x00000026 #define FILE_DEVICE_8042_PORT 0x00000027 #define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028 #define FILE_DEVICE_BATTERY 0x00000029 #define FILE_DEVICE_BUS_EXTENDER 0x0000002a #define FILE_DEVICE_MODEM 0x0000002b #define FILE_DEVICE_VDM 0x0000002c #define FILE_DEVICE_MASS_STORAGE 0x0000002d // // Macro definition for defining IOCTL and FSCTL function control codes. Note // that function codes 0-2047 are reserved for Microsoft Corporation, and // 2048-4095 are reserved for customers. // #define CTL_CODE( DeviceType, Function, Method, Access ) ( \ ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \ ) // // Define the method codes for how buffers are passed for I/O and FS controls // #define METHOD_BUFFERED 0 #define METHOD_IN_DIRECT 1 #define METHOD_OUT_DIRECT 2 #define METHOD_NEITHER 3 // // Define the access check value for any access // // // The FILE_READ_ACCESS and FILE_WRITE_ACCESS constants are also defined in // ntioapi.h as FILE_READ_DATA and FILE_WRITE_DATA. The values for these // constants *MUST* always be in sync. // #define FILE_ANY_ACCESS 0 #define FILE_READ_ACCESS ( 0x0001 ) // file & pipe #define FILE_WRITE_ACCESS ( 0x0002 ) // file & pipe // end_ntddk end_nthal end_ntifs #endif // _DEVIOCTL_ // end_winioctl snort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/Gnuc.h0000644000175200017520000000127413571422607016421 00000000000000/* @(#) $Header$ (LBL) */ /* Define __P() macro, if necessary */ #ifndef __P #if __STDC__ #define __P(protos) protos #else #define __P(protos) () #endif #endif /* inline foo */ #ifndef __cplusplus #ifdef __GNUC__ #define inline __inline #else #define inline #endif #endif /* * Handle new and old "dead" routine prototypes * * For example: * * __dead void foo(void) __attribute__((volatile)); * */ #ifdef __GNUC__ #ifndef __dead #define __dead volatile #endif #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) #ifndef __attribute__ #define __attribute__(args) #endif #endif #else #ifndef __dead #define __dead #endif #ifndef __attribute__ #define __attribute__(args) #endif #endif snort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/ip6_misc.h0000644000175200017520000001304213571422610017224 00000000000000/* * Copyright (c) 1993, 1994, 1997 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * @(#) $Header$ (LBL) */ /* * This file contains a collage of declarations for IPv6 from FreeBSD not present in Windows */ #include #include #ifndef __MINGW32__ #define IN_MULTICAST(a) IN_CLASSD(a) #endif #define IN_EXPERIMENTAL(a) ((((u_int32_t) (a)) & 0xf0000000) == 0xf0000000) #define IN_LOOPBACKNET 127 #if defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF) /* IPv6 address */ struct in6_addr { union { u_int8_t u6_addr8[16]; u_int16_t u6_addr16[8]; u_int32_t u6_addr32[4]; } in6_u; #define s6_addr in6_u.u6_addr8 #define s6_addr16 in6_u.u6_addr16 #define s6_addr32 in6_u.u6_addr32 #define s6_addr64 in6_u.u6_addr64 }; #define IN6ADDR_ANY_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } #define IN6ADDR_LOOPBACK_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } #endif /* __MINGW32__ */ #if (defined _MSC_VER) || (defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF)) typedef unsigned short sa_family_t; #endif #if defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF) #define __SOCKADDR_COMMON(sa_prefix) \ sa_family_t sa_prefix##family /* Ditto, for IPv6. */ struct sockaddr_in6 { __SOCKADDR_COMMON (sin6_); u_int16_t sin6_port; /* Transport layer port # */ u_int32_t sin6_flowinfo; /* IPv6 flow information */ struct in6_addr sin6_addr; /* IPv6 address */ }; #define IN6_IS_ADDR_V4MAPPED(a) \ ((((u_int32_t *) (a))[0] == 0) && (((u_int32_t *) (a))[1] == 0) && \ (((u_int32_t *) (a))[2] == htonl (0xffff))) #define IN6_IS_ADDR_MULTICAST(a) (((u_int8_t *) (a))[0] == 0xff) #define IN6_IS_ADDR_LINKLOCAL(a) \ ((((u_int32_t *) (a))[0] & htonl (0xffc00000)) == htonl (0xfe800000)) #define IN6_IS_ADDR_LOOPBACK(a) \ (((u_int32_t *) (a))[0] == 0 && ((u_int32_t *) (a))[1] == 0 && \ ((u_int32_t *) (a))[2] == 0 && ((u_int32_t *) (a))[3] == htonl (1)) #endif /* __MINGW32__ */ #define ip6_vfc ip6_ctlun.ip6_un2_vfc #define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow #define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen #define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt #define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim #define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim #define nd_rd_type nd_rd_hdr.icmp6_type #define nd_rd_code nd_rd_hdr.icmp6_code #define nd_rd_cksum nd_rd_hdr.icmp6_cksum #define nd_rd_reserved nd_rd_hdr.icmp6_data32[0] /* * IPV6 extension headers */ #define IPPROTO_HOPOPTS 0 /* IPv6 hop-by-hop options */ #define IPPROTO_IPV6 41 /* IPv6 header. */ #define IPPROTO_ROUTING 43 /* IPv6 routing header */ #define IPPROTO_FRAGMENT 44 /* IPv6 fragmentation header */ #define IPPROTO_ESP 50 /* encapsulating security payload */ #define IPPROTO_AH 51 /* authentication header */ #define IPPROTO_ICMPV6 58 /* ICMPv6 */ #define IPPROTO_NONE 59 /* IPv6 no next header */ #define IPPROTO_DSTOPTS 60 /* IPv6 destination options */ #define IPPROTO_PIM 103 /* Protocol Independent Multicast. */ #define IPV6_RTHDR_TYPE_0 0 /* Option types and related macros */ #define IP6OPT_PAD1 0x00 /* 00 0 00000 */ #define IP6OPT_PADN 0x01 /* 00 0 00001 */ #define IP6OPT_JUMBO 0xC2 /* 11 0 00010 = 194 */ #define IP6OPT_JUMBO_LEN 6 #define IP6OPT_ROUTER_ALERT 0x05 /* 00 0 00101 */ #define IP6OPT_RTALERT_LEN 4 #define IP6OPT_RTALERT_MLD 0 /* Datagram contains an MLD message */ #define IP6OPT_RTALERT_RSVP 1 /* Datagram contains an RSVP message */ #define IP6OPT_RTALERT_ACTNET 2 /* contains an Active Networks msg */ #define IP6OPT_MINLEN 2 #define IP6OPT_BINDING_UPDATE 0xc6 /* 11 0 00110 */ #define IP6OPT_BINDING_ACK 0x07 /* 00 0 00111 */ #define IP6OPT_BINDING_REQ 0x08 /* 00 0 01000 */ #define IP6OPT_HOME_ADDRESS 0xc9 /* 11 0 01001 */ #define IP6OPT_EID 0x8a /* 10 0 01010 */ #define IP6OPT_TYPE(o) ((o) & 0xC0) #define IP6OPT_TYPE_SKIP 0x00 #define IP6OPT_TYPE_DISCARD 0x40 #define IP6OPT_TYPE_FORCEICMP 0x80 #define IP6OPT_TYPE_ICMP 0xC0 #define IP6OPT_MUTABLE 0x20 #if defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF) #ifndef EAI_ADDRFAMILY struct addrinfo { int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ int ai_family; /* PF_xxx */ int ai_socktype; /* SOCK_xxx */ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ size_t ai_addrlen; /* length of ai_addr */ char *ai_canonname; /* canonical name for hostname */ struct sockaddr *ai_addr; /* binary address */ struct addrinfo *ai_next; /* next structure in linked list */ }; #endif #endif /* __MINGW32__ */ snort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/memory_t.h0000644000175200017520000001005413571422610017346 00000000000000/* * Copyright (c) 2001 - 2003 * NetGroup, Politecnico di Torino (Italy) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Politecnico di Torino nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef __memory_t #define __memory_t #define uint8 UCHAR #define int8 CHAR #define uint16 USHORT #define int16 SHORT #define uint32 ULONG #define int32 LONG #define uint64 ULONGLONG #define int64 LONGLONG /*memory type*/ typedef struct __MEM_TYPE { uint8 *buffer; uint32 size; } MEM_TYPE, *PMEM_TYPE; #define LONG_AT(base,offset) (*(int32*)((uint8*)base+(uint32)offset)) #define ULONG_AT(base,offset) (*(uint32*)((uint8*)base+(uint32)offset)) #define SHORT_AT(base,offset) (*(int16*)((uint8*)base+(uint32)offset)) #define USHORT_AT(base,offset) (*(uint16*)((uint8*)base+(uint32)offset)) __inline int32 SW_LONG_AT(void *b, uint32 c) { return ((int32)*((uint8 *)b+c)<<24| (int32)*((uint8 *)b+c+1)<<16| (int32)*((uint8 *)b+c+2)<<8| (int32)*((uint8 *)b+c+3)<<0); } __inline uint32 SW_ULONG_AT(void *b, uint32 c) { return ((uint32)*((uint8 *)b+c)<<24| (uint32)*((uint8 *)b+c+1)<<16| (uint32)*((uint8 *)b+c+2)<<8| (uint32)*((uint8 *)b+c+3)<<0); } __inline int16 SW_SHORT_AT(void *b, uint32 os) { return ((int16) ((int16)*((uint8 *)b+os+0)<<8| (int16)*((uint8 *)b+os+1)<<0)); } __inline uint16 SW_USHORT_AT(void *b, uint32 os) { return ((uint16) ((uint16)*((uint8 *)b+os+0)<<8| (uint16)*((uint8 *)b+os+1)<<0)); } __inline VOID SW_ULONG_ASSIGN(void *dst, uint32 src) { *((uint8*)dst+0)=*((uint8*)&src+3); *((uint8*)dst+1)=*((uint8*)&src+2); *((uint8*)dst+2)=*((uint8*)&src+1); *((uint8*)dst+3)=*((uint8*)&src+0); } #ifdef WIN_NT_DRIVER #define ALLOCATE_MEMORY(dest,type,amount) \ (dest)=ExAllocatePool(NonPagedPool,sizeof(type)*(amount)); #define ALLOCATE_ZERO_MEMORY(dest,type,amount) \ { \ (dest)=ExAllocatePool(NonPagedPool,sizeof(type)*(amount)); \ if ((dest)!=NULL) \ RtlZeroMemory((dest),sizeof(type)*(amount)); \ } #define FREE_MEMORY(dest) ExFreePool(dest); #define ZERO_MEMORY(dest,amount) RtlZeroMemory(dest,amount); #define COPY_MEMORY(dest,src,amount) RtlCopyMemory(dest,src,amount); #else #define ALLOCATE_MEMORY(dest,type,amount) \ (dest)=(type*)GlobalAlloc(GPTR, sizeof(type)*(amount)); #define ALLOCATE_ZERO_MEMORY(dest,type,amount) \ (dest)=(type*)GlobalAlloc(GPTR, sizeof(type)*(amount)); #define FREE_MEMORY(dest) GlobalFree(dest); #define ZERO_MEMORY(dest,amount) RtlZeroMemory(dest,amount); #define COPY_MEMORY(dest,src,amount) RtlCopyMemory(dest,src,amount); #endif /*WIN_NT_DRIVER*/ #endif snort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/normal_lookup.h0000644000175200017520000000421113571422610020372 00000000000000/* * Copyright (c) 2001 - 2003 * NetGroup, Politecnico di Torino (Italy) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Politecnico di Torino nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef __normal_lookup #define __normal_lookup #ifdef WIN32 #include "tme.h" #endif #ifdef __FreeBSD__ #ifdef _KERNEL #include #else #include #endif #endif #define NORMAL_LUT_W_INSERT 0x00000000 uint32 normal_lut_w_insert(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref); #define NORMAL_LUT_WO_INSERT 0x00000001 uint32 normal_lut_wo_insert(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref); #define DUMMY_INSERT 1234 #endifsnort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/Ntddndis.h0000644000175200017520000013665413571422607017307 00000000000000/*++ BUILD Version: 0001 // Increment this if a change has global effects Copyright (c) 1990-1993 Microsoft Corporation Module Name: ntddndis.h Abstract: This is the include file that defines all constants and types for accessing the Network driver interface device. Author: Steve Wood (stevewo) 27-May-1990 Revision History: Adam Barr (adamba) 04-Nov-1992 added the correct values for NDIS 3.0. Jameel Hyder (jameelh) 01-Aug-95 added Pnp IoCTLs and structures Kyle Brandon (kyleb) 09/24/96 added general co ndis oids. -- */ #ifndef _NTDDNDIS_ #define _NTDDNDIS_ // // Device Name - this string is the name of the device. It is the name // that should be passed to NtOpenFile when accessing the device. // // Note: For devices that support multiple units, it should be suffixed // with the Ascii representation of the unit number. // #define DD_NDIS_DEVICE_NAME "\\Device\\UNKNOWN" // // NtDeviceIoControlFile IoControlCode values for this device. // // Warning: Remember that the low two bits of the code specify how the // buffers are passed to the driver! // #define _NDIS_CONTROL_CODE(request,method) \ CTL_CODE(FILE_DEVICE_PHYSICAL_NETCARD, request, method, FILE_ANY_ACCESS) #define IOCTL_NDIS_QUERY_GLOBAL_STATS _NDIS_CONTROL_CODE( 0, METHOD_OUT_DIRECT ) #define IOCTL_NDIS_QUERY_ALL_STATS _NDIS_CONTROL_CODE( 1, METHOD_OUT_DIRECT ) #define IOCTL_NDIS_ADD_DEVICE _NDIS_CONTROL_CODE( 2, METHOD_BUFFERED ) #define IOCTL_NDIS_DELETE_DEVICE _NDIS_CONTROL_CODE( 3, METHOD_BUFFERED ) #define IOCTL_NDIS_TRANSLATE_NAME _NDIS_CONTROL_CODE( 4, METHOD_BUFFERED ) #define IOCTL_NDIS_ADD_TDI_DEVICE _NDIS_CONTROL_CODE( 5, METHOD_BUFFERED ) #define IOCTL_NDIS_NOTIFY_PROTOCOL _NDIS_CONTROL_CODE( 6, METHOD_BUFFERED ) #define IOCTL_NDIS_GET_LOG_DATA _NDIS_CONTROL_CODE( 7, METHOD_OUT_DIRECT ) // // NtDeviceIoControlFile InputBuffer/OutputBuffer record structures for // this device. // // // This is the type of an NDIS OID value. // typedef ULONG NDIS_OID, *PNDIS_OID; // // IOCTL_NDIS_QUERY_ALL_STATS returns a sequence of these, packed // together (no padding is required since statistics all have // four or eight bytes of data). // typedef struct _NDIS_STATISTICS_VALUE { NDIS_OID Oid; ULONG DataLength; UCHAR Data[1]; // variable length } NDIS_STATISTICS_VALUE, *PNDIS_STATISTICS_VALUE; // // Structure used by TRANSLATE_NAME IOCTL // typedef struct _NET_PNP_ID { ULONG ClassId; ULONG Token; } NET_PNP_ID, *PNET_PNP_ID; typedef struct _NET_PNP_TRANSLATE_LIST { ULONG BytesNeeded; NET_PNP_ID IdArray[ANYSIZE_ARRAY]; } NET_PNP_TRANSLATE_LIST, *PNET_PNP_TRANSLATE_LIST; // // Structure used to define a self-contained variable data structure // typedef struct _NDIS_VAR_DATA_DESC { USHORT Length; // # of octects of data USHORT MaximumLength; // # of octects available LONG Offset; // Offset of data relative to the descriptor } NDIS_VAR_DATA_DESC, *PNDIS_VAR_DATA_DESC; // // Object Identifiers used by NdisRequest Query/Set Information // // // General Objects // #define OID_GEN_SUPPORTED_LIST 0x00010101 #define OID_GEN_HARDWARE_STATUS 0x00010102 #define OID_GEN_MEDIA_SUPPORTED 0x00010103 #define OID_GEN_MEDIA_IN_USE 0x00010104 #define OID_GEN_MAXIMUM_LOOKAHEAD 0x00010105 #define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106 #define OID_GEN_LINK_SPEED 0x00010107 #define OID_GEN_TRANSMIT_BUFFER_SPACE 0x00010108 #define OID_GEN_RECEIVE_BUFFER_SPACE 0x00010109 #define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010A #define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010B #define OID_GEN_VENDOR_ID 0x0001010C #define OID_GEN_VENDOR_DESCRIPTION 0x0001010D #define OID_GEN_CURRENT_PACKET_FILTER 0x0001010E #define OID_GEN_CURRENT_LOOKAHEAD 0x0001010F #define OID_GEN_DRIVER_VERSION 0x00010110 #define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111 #define OID_GEN_PROTOCOL_OPTIONS 0x00010112 #define OID_GEN_MAC_OPTIONS 0x00010113 #define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114 #define OID_GEN_MAXIMUM_SEND_PACKETS 0x00010115 #define OID_GEN_VENDOR_DRIVER_VERSION 0x00010116 #define OID_GEN_XMIT_OK 0x00020101 #define OID_GEN_RCV_OK 0x00020102 #define OID_GEN_XMIT_ERROR 0x00020103 #define OID_GEN_RCV_ERROR 0x00020104 #define OID_GEN_RCV_NO_BUFFER 0x00020105 #define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201 #define OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202 #define OID_GEN_MULTICAST_BYTES_XMIT 0x00020203 #define OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204 #define OID_GEN_BROADCAST_BYTES_XMIT 0x00020205 #define OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206 #define OID_GEN_DIRECTED_BYTES_RCV 0x00020207 #define OID_GEN_DIRECTED_FRAMES_RCV 0x00020208 #define OID_GEN_MULTICAST_BYTES_RCV 0x00020209 #define OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A #define OID_GEN_BROADCAST_BYTES_RCV 0x0002020B #define OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C #define OID_GEN_RCV_CRC_ERROR 0x0002020D #define OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E #define OID_GEN_GET_TIME_CAPS 0x0002020F #define OID_GEN_GET_NETCARD_TIME 0x00020210 // // These are connection-oriented general OIDs. // These replace the above OIDs for connection-oriented media. // #define OID_GEN_CO_SUPPORTED_LIST 0x00010101 #define OID_GEN_CO_HARDWARE_STATUS 0x00010102 #define OID_GEN_CO_MEDIA_SUPPORTED 0x00010103 #define OID_GEN_CO_MEDIA_IN_USE 0x00010104 #define OID_GEN_CO_LINK_SPEED 0x00010105 #define OID_GEN_CO_VENDOR_ID 0x00010106 #define OID_GEN_CO_VENDOR_DESCRIPTION 0x00010107 #define OID_GEN_CO_DRIVER_VERSION 0x00010108 #define OID_GEN_CO_PROTOCOL_OPTIONS 0x00010109 #define OID_GEN_CO_MAC_OPTIONS 0x0001010A #define OID_GEN_CO_MEDIA_CONNECT_STATUS 0x0001010B #define OID_GEN_CO_VENDOR_DRIVER_VERSION 0x0001010C #define OID_GEN_CO_MINIMUM_LINK_SPEED 0x0001010D #define OID_GEN_CO_GET_TIME_CAPS 0x00010201 #define OID_GEN_CO_GET_NETCARD_TIME 0x00010202 // // These are connection-oriented statistics OIDs. // #define OID_GEN_CO_XMIT_PDUS_OK 0x00020101 #define OID_GEN_CO_RCV_PDUS_OK 0x00020102 #define OID_GEN_CO_XMIT_PDUS_ERROR 0x00020103 #define OID_GEN_CO_RCV_PDUS_ERROR 0x00020104 #define OID_GEN_CO_RCV_PDUS_NO_BUFFER 0x00020105 #define OID_GEN_CO_RCV_CRC_ERROR 0x00020201 #define OID_GEN_CO_TRANSMIT_QUEUE_LENGTH 0x00020202 #define OID_GEN_CO_BYTES_XMIT 0x00020203 #define OID_GEN_CO_BYTES_RCV 0x00020204 #define OID_GEN_CO_BYTES_XMIT_OUTSTANDING 0x00020205 #define OID_GEN_CO_NETCARD_LOAD 0x00020206 // // These are objects for Connection-oriented media call-managers and are not // valid for ndis drivers. Under construction. // #define OID_CO_ADD_PVC 0xFF000001 #define OID_CO_DELETE_PVC 0xFF000002 #define OID_CO_GET_CALL_INFORMATION 0xFF000003 #define OID_CO_ADD_ADDRESS 0xFF000004 #define OID_CO_DELETE_ADDRESS 0xFF000005 #define OID_CO_GET_ADDRESSES 0xFF000006 #define OID_CO_ADDRESS_CHANGE 0xFF000007 #define OID_CO_SIGNALING_ENABLED 0xFF000008 #define OID_CO_SIGNALING_DISABLED 0xFF000009 // // 802.3 Objects (Ethernet) // #define OID_802_3_PERMANENT_ADDRESS 0x01010101 #define OID_802_3_CURRENT_ADDRESS 0x01010102 #define OID_802_3_MULTICAST_LIST 0x01010103 #define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 #define OID_802_3_MAC_OPTIONS 0x01010105 // // #define NDIS_802_3_MAC_OPTION_PRIORITY 0x00000001 #define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101 #define OID_802_3_XMIT_ONE_COLLISION 0x01020102 #define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103 #define OID_802_3_XMIT_DEFERRED 0x01020201 #define OID_802_3_XMIT_MAX_COLLISIONS 0x01020202 #define OID_802_3_RCV_OVERRUN 0x01020203 #define OID_802_3_XMIT_UNDERRUN 0x01020204 #define OID_802_3_XMIT_HEARTBEAT_FAILURE 0x01020205 #define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206 #define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207 // // 802.5 Objects (Token-Ring) // #define OID_802_5_PERMANENT_ADDRESS 0x02010101 #define OID_802_5_CURRENT_ADDRESS 0x02010102 #define OID_802_5_CURRENT_FUNCTIONAL 0x02010103 #define OID_802_5_CURRENT_GROUP 0x02010104 #define OID_802_5_LAST_OPEN_STATUS 0x02010105 #define OID_802_5_CURRENT_RING_STATUS 0x02010106 #define OID_802_5_CURRENT_RING_STATE 0x02010107 #define OID_802_5_LINE_ERRORS 0x02020101 #define OID_802_5_LOST_FRAMES 0x02020102 #define OID_802_5_BURST_ERRORS 0x02020201 #define OID_802_5_AC_ERRORS 0x02020202 #define OID_802_5_ABORT_DELIMETERS 0x02020203 #define OID_802_5_FRAME_COPIED_ERRORS 0x02020204 #define OID_802_5_FREQUENCY_ERRORS 0x02020205 #define OID_802_5_TOKEN_ERRORS 0x02020206 #define OID_802_5_INTERNAL_ERRORS 0x02020207 // // FDDI Objects // #define OID_FDDI_LONG_PERMANENT_ADDR 0x03010101 #define OID_FDDI_LONG_CURRENT_ADDR 0x03010102 #define OID_FDDI_LONG_MULTICAST_LIST 0x03010103 #define OID_FDDI_LONG_MAX_LIST_SIZE 0x03010104 #define OID_FDDI_SHORT_PERMANENT_ADDR 0x03010105 #define OID_FDDI_SHORT_CURRENT_ADDR 0x03010106 #define OID_FDDI_SHORT_MULTICAST_LIST 0x03010107 #define OID_FDDI_SHORT_MAX_LIST_SIZE 0x03010108 #define OID_FDDI_ATTACHMENT_TYPE 0x03020101 #define OID_FDDI_UPSTREAM_NODE_LONG 0x03020102 #define OID_FDDI_DOWNSTREAM_NODE_LONG 0x03020103 #define OID_FDDI_FRAME_ERRORS 0x03020104 #define OID_FDDI_FRAMES_LOST 0x03020105 #define OID_FDDI_RING_MGT_STATE 0x03020106 #define OID_FDDI_LCT_FAILURES 0x03020107 #define OID_FDDI_LEM_REJECTS 0x03020108 #define OID_FDDI_LCONNECTION_STATE 0x03020109 #define OID_FDDI_SMT_STATION_ID 0x03030201 #define OID_FDDI_SMT_OP_VERSION_ID 0x03030202 #define OID_FDDI_SMT_HI_VERSION_ID 0x03030203 #define OID_FDDI_SMT_LO_VERSION_ID 0x03030204 #define OID_FDDI_SMT_MANUFACTURER_DATA 0x03030205 #define OID_FDDI_SMT_USER_DATA 0x03030206 #define OID_FDDI_SMT_MIB_VERSION_ID 0x03030207 #define OID_FDDI_SMT_MAC_CT 0x03030208 #define OID_FDDI_SMT_NON_MASTER_CT 0x03030209 #define OID_FDDI_SMT_MASTER_CT 0x0303020A #define OID_FDDI_SMT_AVAILABLE_PATHS 0x0303020B #define OID_FDDI_SMT_CONFIG_CAPABILITIES 0x0303020C #define OID_FDDI_SMT_CONFIG_POLICY 0x0303020D #define OID_FDDI_SMT_CONNECTION_POLICY 0x0303020E #define OID_FDDI_SMT_T_NOTIFY 0x0303020F #define OID_FDDI_SMT_STAT_RPT_POLICY 0x03030210 #define OID_FDDI_SMT_TRACE_MAX_EXPIRATION 0x03030211 #define OID_FDDI_SMT_PORT_INDEXES 0x03030212 #define OID_FDDI_SMT_MAC_INDEXES 0x03030213 #define OID_FDDI_SMT_BYPASS_PRESENT 0x03030214 #define OID_FDDI_SMT_ECM_STATE 0x03030215 #define OID_FDDI_SMT_CF_STATE 0x03030216 #define OID_FDDI_SMT_HOLD_STATE 0x03030217 #define OID_FDDI_SMT_REMOTE_DISCONNECT_FLAG 0x03030218 #define OID_FDDI_SMT_STATION_STATUS 0x03030219 #define OID_FDDI_SMT_PEER_WRAP_FLAG 0x0303021A #define OID_FDDI_SMT_MSG_TIME_STAMP 0x0303021B #define OID_FDDI_SMT_TRANSITION_TIME_STAMP 0x0303021C #define OID_FDDI_SMT_SET_COUNT 0x0303021D #define OID_FDDI_SMT_LAST_SET_STATION_ID 0x0303021E #define OID_FDDI_MAC_FRAME_STATUS_FUNCTIONS 0x0303021F #define OID_FDDI_MAC_BRIDGE_FUNCTIONS 0x03030220 #define OID_FDDI_MAC_T_MAX_CAPABILITY 0x03030221 #define OID_FDDI_MAC_TVX_CAPABILITY 0x03030222 #define OID_FDDI_MAC_AVAILABLE_PATHS 0x03030223 #define OID_FDDI_MAC_CURRENT_PATH 0x03030224 #define OID_FDDI_MAC_UPSTREAM_NBR 0x03030225 #define OID_FDDI_MAC_DOWNSTREAM_NBR 0x03030226 #define OID_FDDI_MAC_OLD_UPSTREAM_NBR 0x03030227 #define OID_FDDI_MAC_OLD_DOWNSTREAM_NBR 0x03030228 #define OID_FDDI_MAC_DUP_ADDRESS_TEST 0x03030229 #define OID_FDDI_MAC_REQUESTED_PATHS 0x0303022A #define OID_FDDI_MAC_DOWNSTREAM_PORT_TYPE 0x0303022B #define OID_FDDI_MAC_INDEX 0x0303022C #define OID_FDDI_MAC_SMT_ADDRESS 0x0303022D #define OID_FDDI_MAC_LONG_GRP_ADDRESS 0x0303022E #define OID_FDDI_MAC_SHORT_GRP_ADDRESS 0x0303022F #define OID_FDDI_MAC_T_REQ 0x03030230 #define OID_FDDI_MAC_T_NEG 0x03030231 #define OID_FDDI_MAC_T_MAX 0x03030232 #define OID_FDDI_MAC_TVX_VALUE 0x03030233 #define OID_FDDI_MAC_T_PRI0 0x03030234 #define OID_FDDI_MAC_T_PRI1 0x03030235 #define OID_FDDI_MAC_T_PRI2 0x03030236 #define OID_FDDI_MAC_T_PRI3 0x03030237 #define OID_FDDI_MAC_T_PRI4 0x03030238 #define OID_FDDI_MAC_T_PRI5 0x03030239 #define OID_FDDI_MAC_T_PRI6 0x0303023A #define OID_FDDI_MAC_FRAME_CT 0x0303023B #define OID_FDDI_MAC_COPIED_CT 0x0303023C #define OID_FDDI_MAC_TRANSMIT_CT 0x0303023D #define OID_FDDI_MAC_TOKEN_CT 0x0303023E #define OID_FDDI_MAC_ERROR_CT 0x0303023F #define OID_FDDI_MAC_LOST_CT 0x03030240 #define OID_FDDI_MAC_TVX_EXPIRED_CT 0x03030241 #define OID_FDDI_MAC_NOT_COPIED_CT 0x03030242 #define OID_FDDI_MAC_LATE_CT 0x03030243 #define OID_FDDI_MAC_RING_OP_CT 0x03030244 #define OID_FDDI_MAC_FRAME_ERROR_THRESHOLD 0x03030245 #define OID_FDDI_MAC_FRAME_ERROR_RATIO 0x03030246 #define OID_FDDI_MAC_NOT_COPIED_THRESHOLD 0x03030247 #define OID_FDDI_MAC_NOT_COPIED_RATIO 0x03030248 #define OID_FDDI_MAC_RMT_STATE 0x03030249 #define OID_FDDI_MAC_DA_FLAG 0x0303024A #define OID_FDDI_MAC_UNDA_FLAG 0x0303024B #define OID_FDDI_MAC_FRAME_ERROR_FLAG 0x0303024C #define OID_FDDI_MAC_NOT_COPIED_FLAG 0x0303024D #define OID_FDDI_MAC_MA_UNITDATA_AVAILABLE 0x0303024E #define OID_FDDI_MAC_HARDWARE_PRESENT 0x0303024F #define OID_FDDI_MAC_MA_UNITDATA_ENABLE 0x03030250 #define OID_FDDI_PATH_INDEX 0x03030251 #define OID_FDDI_PATH_RING_LATENCY 0x03030252 #define OID_FDDI_PATH_TRACE_STATUS 0x03030253 #define OID_FDDI_PATH_SBA_PAYLOAD 0x03030254 #define OID_FDDI_PATH_SBA_OVERHEAD 0x03030255 #define OID_FDDI_PATH_CONFIGURATION 0x03030256 #define OID_FDDI_PATH_T_R_MODE 0x03030257 #define OID_FDDI_PATH_SBA_AVAILABLE 0x03030258 #define OID_FDDI_PATH_TVX_LOWER_BOUND 0x03030259 #define OID_FDDI_PATH_T_MAX_LOWER_BOUND 0x0303025A #define OID_FDDI_PATH_MAX_T_REQ 0x0303025B #define OID_FDDI_PORT_MY_TYPE 0x0303025C #define OID_FDDI_PORT_NEIGHBOR_TYPE 0x0303025D #define OID_FDDI_PORT_CONNECTION_POLICIES 0x0303025E #define OID_FDDI_PORT_MAC_INDICATED 0x0303025F #define OID_FDDI_PORT_CURRENT_PATH 0x03030260 #define OID_FDDI_PORT_REQUESTED_PATHS 0x03030261 #define OID_FDDI_PORT_MAC_PLACEMENT 0x03030262 #define OID_FDDI_PORT_AVAILABLE_PATHS 0x03030263 #define OID_FDDI_PORT_MAC_LOOP_TIME 0x03030264 #define OID_FDDI_PORT_PMD_CLASS 0x03030265 #define OID_FDDI_PORT_CONNECTION_CAPABILITIES 0x03030266 #define OID_FDDI_PORT_INDEX 0x03030267 #define OID_FDDI_PORT_MAINT_LS 0x03030268 #define OID_FDDI_PORT_BS_FLAG 0x03030269 #define OID_FDDI_PORT_PC_LS 0x0303026A #define OID_FDDI_PORT_EB_ERROR_CT 0x0303026B #define OID_FDDI_PORT_LCT_FAIL_CT 0x0303026C #define OID_FDDI_PORT_LER_ESTIMATE 0x0303026D #define OID_FDDI_PORT_LEM_REJECT_CT 0x0303026E #define OID_FDDI_PORT_LEM_CT 0x0303026F #define OID_FDDI_PORT_LER_CUTOFF 0x03030270 #define OID_FDDI_PORT_LER_ALARM 0x03030271 #define OID_FDDI_PORT_CONNNECT_STATE 0x03030272 #define OID_FDDI_PORT_PCM_STATE 0x03030273 #define OID_FDDI_PORT_PC_WITHHOLD 0x03030274 #define OID_FDDI_PORT_LER_FLAG 0x03030275 #define OID_FDDI_PORT_HARDWARE_PRESENT 0x03030276 #define OID_FDDI_SMT_STATION_ACTION 0x03030277 #define OID_FDDI_PORT_ACTION 0x03030278 #define OID_FDDI_IF_DESCR 0x03030279 #define OID_FDDI_IF_TYPE 0x0303027A #define OID_FDDI_IF_MTU 0x0303027B #define OID_FDDI_IF_SPEED 0x0303027C #define OID_FDDI_IF_PHYS_ADDRESS 0x0303027D #define OID_FDDI_IF_ADMIN_STATUS 0x0303027E #define OID_FDDI_IF_OPER_STATUS 0x0303027F #define OID_FDDI_IF_LAST_CHANGE 0x03030280 #define OID_FDDI_IF_IN_OCTETS 0x03030281 #define OID_FDDI_IF_IN_UCAST_PKTS 0x03030282 #define OID_FDDI_IF_IN_NUCAST_PKTS 0x03030283 #define OID_FDDI_IF_IN_DISCARDS 0x03030284 #define OID_FDDI_IF_IN_ERRORS 0x03030285 #define OID_FDDI_IF_IN_UNKNOWN_PROTOS 0x03030286 #define OID_FDDI_IF_OUT_OCTETS 0x03030287 #define OID_FDDI_IF_OUT_UCAST_PKTS 0x03030288 #define OID_FDDI_IF_OUT_NUCAST_PKTS 0x03030289 #define OID_FDDI_IF_OUT_DISCARDS 0x0303028A #define OID_FDDI_IF_OUT_ERRORS 0x0303028B #define OID_FDDI_IF_OUT_QLEN 0x0303028C #define OID_FDDI_IF_SPECIFIC 0x0303028D // // WAN objects // #define OID_WAN_PERMANENT_ADDRESS 0x04010101 #define OID_WAN_CURRENT_ADDRESS 0x04010102 #define OID_WAN_QUALITY_OF_SERVICE 0x04010103 #define OID_WAN_PROTOCOL_TYPE 0x04010104 #define OID_WAN_MEDIUM_SUBTYPE 0x04010105 #define OID_WAN_HEADER_FORMAT 0x04010106 #define OID_WAN_GET_INFO 0x04010107 #define OID_WAN_SET_LINK_INFO 0x04010108 #define OID_WAN_GET_LINK_INFO 0x04010109 #define OID_WAN_LINE_COUNT 0x0401010A #define OID_WAN_GET_BRIDGE_INFO 0x0401020A #define OID_WAN_SET_BRIDGE_INFO 0x0401020B #define OID_WAN_GET_COMP_INFO 0x0401020C #define OID_WAN_SET_COMP_INFO 0x0401020D #define OID_WAN_GET_STATS_INFO 0x0401020E // // LocalTalk objects // #define OID_LTALK_CURRENT_NODE_ID 0x05010102 #define OID_LTALK_IN_BROADCASTS 0x05020101 #define OID_LTALK_IN_LENGTH_ERRORS 0x05020102 #define OID_LTALK_OUT_NO_HANDLERS 0x05020201 #define OID_LTALK_COLLISIONS 0x05020202 #define OID_LTALK_DEFERS 0x05020203 #define OID_LTALK_NO_DATA_ERRORS 0x05020204 #define OID_LTALK_RANDOM_CTS_ERRORS 0x05020205 #define OID_LTALK_FCS_ERRORS 0x05020206 // // Arcnet objects // #define OID_ARCNET_PERMANENT_ADDRESS 0x06010101 #define OID_ARCNET_CURRENT_ADDRESS 0x06010102 #define OID_ARCNET_RECONFIGURATIONS 0x06020201 // // TAPI objects // #define OID_TAPI_ACCEPT 0x07030101 #define OID_TAPI_ANSWER 0x07030102 #define OID_TAPI_CLOSE 0x07030103 #define OID_TAPI_CLOSE_CALL 0x07030104 #define OID_TAPI_CONDITIONAL_MEDIA_DETECTION 0x07030105 #define OID_TAPI_CONFIG_DIALOG 0x07030106 #define OID_TAPI_DEV_SPECIFIC 0x07030107 #define OID_TAPI_DIAL 0x07030108 #define OID_TAPI_DROP 0x07030109 #define OID_TAPI_GET_ADDRESS_CAPS 0x0703010A #define OID_TAPI_GET_ADDRESS_ID 0x0703010B #define OID_TAPI_GET_ADDRESS_STATUS 0x0703010C #define OID_TAPI_GET_CALL_ADDRESS_ID 0x0703010D #define OID_TAPI_GET_CALL_INFO 0x0703010E #define OID_TAPI_GET_CALL_STATUS 0x0703010F #define OID_TAPI_GET_DEV_CAPS 0x07030110 #define OID_TAPI_GET_DEV_CONFIG 0x07030111 #define OID_TAPI_GET_EXTENSION_ID 0x07030112 #define OID_TAPI_GET_ID 0x07030113 #define OID_TAPI_GET_LINE_DEV_STATUS 0x07030114 #define OID_TAPI_MAKE_CALL 0x07030115 #define OID_TAPI_NEGOTIATE_EXT_VERSION 0x07030116 #define OID_TAPI_OPEN 0x07030117 #define OID_TAPI_PROVIDER_INITIALIZE 0x07030118 #define OID_TAPI_PROVIDER_SHUTDOWN 0x07030119 #define OID_TAPI_SECURE_CALL 0x0703011A #define OID_TAPI_SELECT_EXT_VERSION 0x0703011B #define OID_TAPI_SEND_USER_USER_INFO 0x0703011C #define OID_TAPI_SET_APP_SPECIFIC 0x0703011D #define OID_TAPI_SET_CALL_PARAMS 0x0703011E #define OID_TAPI_SET_DEFAULT_MEDIA_DETECTION 0x0703011F #define OID_TAPI_SET_DEV_CONFIG 0x07030120 #define OID_TAPI_SET_MEDIA_MODE 0x07030121 #define OID_TAPI_SET_STATUS_MESSAGES 0x07030122 // // ATM Connection Oriented Ndis // #define OID_ATM_SUPPORTED_VC_RATES 0x08010101 #define OID_ATM_SUPPORTED_SERVICE_CATEGORY 0x08010102 #define OID_ATM_SUPPORTED_AAL_TYPES 0x08010103 #define OID_ATM_HW_CURRENT_ADDRESS 0x08010104 #define OID_ATM_MAX_ACTIVE_VCS 0x08010105 #define OID_ATM_MAX_ACTIVE_VCI_BITS 0x08010106 #define OID_ATM_MAX_ACTIVE_VPI_BITS 0x08010107 #define OID_ATM_MAX_AAL0_PACKET_SIZE 0x08010108 #define OID_ATM_MAX_AAL1_PACKET_SIZE 0x08010109 #define OID_ATM_MAX_AAL34_PACKET_SIZE 0x0801010A #define OID_ATM_MAX_AAL5_PACKET_SIZE 0x0801010B #define OID_ATM_SIGNALING_VPIVCI 0x08010201 #define OID_ATM_ASSIGNED_VPI 0x08010202 #define OID_ATM_ACQUIRE_ACCESS_NET_RESOURCES 0x08010203 #define OID_ATM_RELEASE_ACCESS_NET_RESOURCES 0x08010204 #define OID_ATM_ILMI_VPIVCI 0x08010205 #define OID_ATM_DIGITAL_BROADCAST_VPIVCI 0x08010206 #define OID_ATM_GET_NEAREST_FLOW 0x08010207 #define OID_ATM_ALIGNMENT_REQUIRED 0x08010208 // // ATM specific statistics OIDs. // #define OID_ATM_RCV_CELLS_OK 0x08020101 #define OID_ATM_XMIT_CELLS_OK 0x08020102 #define OID_ATM_RCV_CELLS_DROPPED 0x08020103 #define OID_ATM_RCV_INVALID_VPI_VCI 0x08020201 #define OID_ATM_CELLS_HEC_ERROR 0x08020202 #define OID_ATM_RCV_REASSEMBLY_ERROR 0x08020203 // // PCCA (Wireless) object // // // All WirelessWAN devices must support the following OIDs // #define OID_WW_GEN_NETWORK_TYPES_SUPPORTED 0x09010101 #define OID_WW_GEN_NETWORK_TYPE_IN_USE 0x09010102 #define OID_WW_GEN_HEADER_FORMATS_SUPPORTED 0x09010103 #define OID_WW_GEN_HEADER_FORMAT_IN_USE 0x09010104 #define OID_WW_GEN_INDICATION_REQUEST 0x09010105 #define OID_WW_GEN_DEVICE_INFO 0x09010106 #define OID_WW_GEN_OPERATION_MODE 0x09010107 #define OID_WW_GEN_LOCK_STATUS 0x09010108 #define OID_WW_GEN_DISABLE_TRANSMITTER 0x09010109 #define OID_WW_GEN_NETWORK_ID 0x0901010A #define OID_WW_GEN_PERMANENT_ADDRESS 0x0901010B #define OID_WW_GEN_CURRENT_ADDRESS 0x0901010C #define OID_WW_GEN_SUSPEND_DRIVER 0x0901010D #define OID_WW_GEN_BASESTATION_ID 0x0901010E #define OID_WW_GEN_CHANNEL_ID 0x0901010F #define OID_WW_GEN_ENCRYPTION_SUPPORTED 0x09010110 #define OID_WW_GEN_ENCRYPTION_IN_USE 0x09010111 #define OID_WW_GEN_ENCRYPTION_STATE 0x09010112 #define OID_WW_GEN_CHANNEL_QUALITY 0x09010113 #define OID_WW_GEN_REGISTRATION_STATUS 0x09010114 #define OID_WW_GEN_RADIO_LINK_SPEED 0x09010115 #define OID_WW_GEN_LATENCY 0x09010116 #define OID_WW_GEN_BATTERY_LEVEL 0x09010117 #define OID_WW_GEN_EXTERNAL_POWER 0x09010118 // // Network Dependent OIDs - Mobitex: // #define OID_WW_MBX_SUBADDR 0x09050101 // OID 0x09050102 is reserved and may not be used #define OID_WW_MBX_FLEXLIST 0x09050103 #define OID_WW_MBX_GROUPLIST 0x09050104 #define OID_WW_MBX_TRAFFIC_AREA 0x09050105 #define OID_WW_MBX_LIVE_DIE 0x09050106 #define OID_WW_MBX_TEMP_DEFAULTLIST 0x09050107 // // Network Dependent OIDs - Pinpoint: // #define OID_WW_PIN_LOC_AUTHORIZE 0x09090101 #define OID_WW_PIN_LAST_LOCATION 0x09090102 #define OID_WW_PIN_LOC_FIX 0x09090103 // // Network Dependent - CDPD: // #define OID_WW_CDPD_SPNI 0x090D0101 #define OID_WW_CDPD_WASI 0x090D0102 #define OID_WW_CDPD_AREA_COLOR 0x090D0103 #define OID_WW_CDPD_TX_POWER_LEVEL 0x090D0104 #define OID_WW_CDPD_EID 0x090D0105 #define OID_WW_CDPD_HEADER_COMPRESSION 0x090D0106 #define OID_WW_CDPD_DATA_COMPRESSION 0x090D0107 #define OID_WW_CDPD_CHANNEL_SELECT 0x090D0108 #define OID_WW_CDPD_CHANNEL_STATE 0x090D0109 #define OID_WW_CDPD_NEI 0x090D010A #define OID_WW_CDPD_NEI_STATE 0x090D010B #define OID_WW_CDPD_SERVICE_PROVIDER_IDENTIFIER 0x090D010C #define OID_WW_CDPD_SLEEP_MODE 0x090D010D #define OID_WW_CDPD_CIRCUIT_SWITCHED 0x090D010E #define OID_WW_CDPD_TEI 0x090D010F #define OID_WW_CDPD_RSSI 0x090D0110 // // Network Dependent - Ardis: // #define OID_WW_ARD_SNDCP 0x09110101 #define OID_WW_ARD_TMLY_MSG 0x09110102 #define OID_WW_ARD_DATAGRAM 0x09110103 // // Network Dependent - DataTac: // #define OID_WW_TAC_COMPRESSION 0x09150101 #define OID_WW_TAC_SET_CONFIG 0x09150102 #define OID_WW_TAC_GET_STATUS 0x09150103 #define OID_WW_TAC_USER_HEADER 0x09150104 // // Network Dependent - Metricom: // #define OID_WW_MET_FUNCTION 0x09190101 // // IRDA objects // #define OID_IRDA_RECEIVING 0x0A010100 #define OID_IRDA_TURNAROUND_TIME 0x0A010101 #define OID_IRDA_SUPPORTED_SPEEDS 0x0A010102 #define OID_IRDA_LINK_SPEED 0x0A010103 #define OID_IRDA_MEDIA_BUSY 0x0A010104 #define OID_IRDA_EXTRA_RCV_BOFS 0x0A010200 #define OID_IRDA_RATE_SNIFF 0x0A010201 #define OID_IRDA_UNICAST_LIST 0x0A010202 #define OID_IRDA_MAX_UNICAST_LIST_SIZE 0x0A010203 #define OID_IRDA_MAX_RECEIVE_WINDOW_SIZE 0x0A010204 #define OID_IRDA_MAX_SEND_WINDOW_SIZE 0x0A010205 // // Medium the Ndis Driver is running on (OID_GEN_MEDIA_SUPPORTED/ // OID_GEN_MEDIA_IN_USE). // typedef enum _NDIS_MEDIUM { NdisMedium802_3, NdisMedium802_5, NdisMediumFddi, NdisMediumWan, NdisMediumLocalTalk, NdisMediumDix, // defined for convenience, not a real medium NdisMediumArcnetRaw, NdisMediumArcnet878_2, NdisMediumAtm, NdisMediumWirelessWan, NdisMediumIrda, NdisMediumMax // Not a real medium, defined as an upper-bound } NDIS_MEDIUM, *PNDIS_MEDIUM; // // Hardware status codes (OID_GEN_HARDWARE_STATUS). // typedef enum _NDIS_HARDWARE_STATUS { NdisHardwareStatusReady, NdisHardwareStatusInitializing, NdisHardwareStatusReset, NdisHardwareStatusClosing, NdisHardwareStatusNotReady } NDIS_HARDWARE_STATUS, *PNDIS_HARDWARE_STATUS; // // this is the type passed in the OID_GEN_GET_TIME_CAPS request // typedef struct _GEN_GET_TIME_CAPS { ULONG Flags; // Bits defined below ULONG ClockPrecision; } GEN_GET_TIME_CAPS, *PGEN_GET_TIME_CAPS; #define READABLE_LOCAL_CLOCK 0x000000001 #define CLOCK_NETWORK_DERIVED 0x000000002 #define CLOCK_PRECISION 0x000000004 #define RECEIVE_TIME_INDICATION_CAPABLE 0x000000008 #define TIMED_SEND_CAPABLE 0x000000010 #define TIME_STAMP_CAPABLE 0x000000020 // // // this is the type passed in the OID_GEN_GET_NETCARD_TIME request // typedef struct _GEN_GET_NETCARD_TIME { ULONG ReadTime; } GEN_GET_NETCARD_TIME, *PGEN_GET_NETCARD_TIME; // // Defines the attachment types for FDDI (OID_FDDI_ATTACHMENT_TYPE). // typedef enum _NDIS_FDDI_ATTACHMENT_TYPE { NdisFddiTypeIsolated = 1, NdisFddiTypeLocalA, NdisFddiTypeLocalB, NdisFddiTypeLocalAB, NdisFddiTypeLocalS, NdisFddiTypeWrapA, NdisFddiTypeWrapB, NdisFddiTypeWrapAB, NdisFddiTypeWrapS, NdisFddiTypeCWrapA, NdisFddiTypeCWrapB, NdisFddiTypeCWrapS, NdisFddiTypeThrough } NDIS_FDDI_ATTACHMENT_TYPE, *PNDIS_FDDI_ATTACHMENT_TYPE; // // Defines the ring management states for FDDI (OID_FDDI_RING_MGT_STATE). // typedef enum _NDIS_FDDI_RING_MGT_STATE { NdisFddiRingIsolated = 1, NdisFddiRingNonOperational, NdisFddiRingOperational, NdisFddiRingDetect, NdisFddiRingNonOperationalDup, NdisFddiRingOperationalDup, NdisFddiRingDirected, NdisFddiRingTrace } NDIS_FDDI_RING_MGT_STATE, *PNDIS_FDDI_RING_MGT_STATE; // // Defines the Lconnection state for FDDI (OID_FDDI_LCONNECTION_STATE). // typedef enum _NDIS_FDDI_LCONNECTION_STATE { NdisFddiStateOff = 1, NdisFddiStateBreak, NdisFddiStateTrace, NdisFddiStateConnect, NdisFddiStateNext, NdisFddiStateSignal, NdisFddiStateJoin, NdisFddiStateVerify, NdisFddiStateActive, NdisFddiStateMaintenance } NDIS_FDDI_LCONNECTION_STATE, *PNDIS_FDDI_LCONNECTION_STATE; // // Defines the medium subtypes for WAN medium (OID_WAN_MEDIUM_SUBTYPE). // typedef enum _NDIS_WAN_MEDIUM_SUBTYPE { NdisWanMediumHub, NdisWanMediumX_25, NdisWanMediumIsdn, NdisWanMediumSerial, NdisWanMediumFrameRelay, NdisWanMediumAtm, NdisWanMediumSonet, NdisWanMediumSW56K } NDIS_WAN_MEDIUM_SUBTYPE, *PNDIS_WAN_MEDIUM_SUBTYPE; // // Defines the header format for WAN medium (OID_WAN_HEADER_FORMAT). // typedef enum _NDIS_WAN_HEADER_FORMAT { NdisWanHeaderNative, // src/dest based on subtype, followed by NLPID NdisWanHeaderEthernet // emulation of ethernet header } NDIS_WAN_HEADER_FORMAT, *PNDIS_WAN_HEADER_FORMAT; // // Defines the line quality on a WAN line (OID_WAN_QUALITY_OF_SERVICE). // typedef enum _NDIS_WAN_QUALITY { NdisWanRaw, NdisWanErrorControl, NdisWanReliable } NDIS_WAN_QUALITY, *PNDIS_WAN_QUALITY; // // Defines the state of a token-ring adapter (OID_802_5_CURRENT_RING_STATE). // typedef enum _NDIS_802_5_RING_STATE { NdisRingStateOpened = 1, NdisRingStateClosed, NdisRingStateOpening, NdisRingStateClosing, NdisRingStateOpenFailure, NdisRingStateRingFailure } NDIS_802_5_RING_STATE, *PNDIS_802_5_RING_STATE; // // Defines the state of the LAN media // typedef enum _NDIS_MEDIA_STATE { NdisMediaStateConnected, NdisMediaStateDisconnected } NDIS_MEDIA_STATE, *PNDIS_MEDIA_STATE; // // The following is set on a per-packet basis as OOB data with NdisClass802_3Priority // typedef ULONG Priority_802_3; // 0-7 priority levels // // The following structure is used to query OID_GEN_CO_LINK_SPEED and // OID_GEN_CO_MINIMUM_LINK_SPEED. The first OID will return the current // link speed of the adapter. The second will return the minimum link speed // the adapter is capable of. // typedef struct _NDIS_CO_LINK_SPEED { ULONG Outbound; ULONG Inbound; } NDIS_CO_LINK_SPEED, *PNDIS_CO_LINK_SPEED; // // Ndis Packet Filter Bits (OID_GEN_CURRENT_PACKET_FILTER). // #define NDIS_PACKET_TYPE_DIRECTED 0x0001 #define NDIS_PACKET_TYPE_MULTICAST 0x0002 #define NDIS_PACKET_TYPE_ALL_MULTICAST 0x0004 #define NDIS_PACKET_TYPE_BROADCAST 0x0008 #define NDIS_PACKET_TYPE_SOURCE_ROUTING 0x0010 #define NDIS_PACKET_TYPE_PROMISCUOUS 0x0020 #define NDIS_PACKET_TYPE_SMT 0x0040 #define NDIS_PACKET_TYPE_ALL_LOCAL 0x0080 #define NDIS_PACKET_TYPE_MAC_FRAME 0x8000 #define NDIS_PACKET_TYPE_FUNCTIONAL 0x4000 #define NDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x2000 #define NDIS_PACKET_TYPE_GROUP 0x1000 // // Ndis Token-Ring Ring Status Codes (OID_802_5_CURRENT_RING_STATUS). // #define NDIS_RING_SIGNAL_LOSS 0x00008000 #define NDIS_RING_HARD_ERROR 0x00004000 #define NDIS_RING_SOFT_ERROR 0x00002000 #define NDIS_RING_TRANSMIT_BEACON 0x00001000 #define NDIS_RING_LOBE_WIRE_FAULT 0x00000800 #define NDIS_RING_AUTO_REMOVAL_ERROR 0x00000400 #define NDIS_RING_REMOVE_RECEIVED 0x00000200 #define NDIS_RING_COUNTER_OVERFLOW 0x00000100 #define NDIS_RING_SINGLE_STATION 0x00000080 #define NDIS_RING_RING_RECOVERY 0x00000040 // // Ndis protocol option bits (OID_GEN_PROTOCOL_OPTIONS). // #define NDIS_PROT_OPTION_ESTIMATED_LENGTH 0x00000001 #define NDIS_PROT_OPTION_NO_LOOPBACK 0x00000002 #define NDIS_PROT_OPTION_NO_RSVD_ON_RCVPKT 0x00000004 // // Ndis MAC option bits (OID_GEN_MAC_OPTIONS). // #define NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA 0x00000001 #define NDIS_MAC_OPTION_RECEIVE_SERIALIZED 0x00000002 #define NDIS_MAC_OPTION_TRANSFERS_NOT_PEND 0x00000004 #define NDIS_MAC_OPTION_NO_LOOPBACK 0x00000008 #define NDIS_MAC_OPTION_FULL_DUPLEX 0x00000010 #define NDIS_MAC_OPTION_EOTX_INDICATION 0x00000020 #define NDIS_MAC_OPTION_RESERVED 0x80000000 // // NDIS MAC option bits for OID_GEN_CO_MAC_OPTIONS. // #define NDIS_CO_MAC_OPTION_DYNAMIC_LINK_SPEED 0x00000001 #ifdef IRDA // // The following is set on a per-packet basis as OOB data with NdisClassIrdaPacketInfo // This is the per-packet info specified on a per-packet basis // typedef struct _NDIS_IRDA_PACKET_INFO { UINT ExtraBOFs; UINT MinTurnAroundTime; } NDIS_IRDA_PACKET_INFO, *PNDIS_IRDA_PACKET_INFO; #endif #ifdef WIRELESS_WAN // // Wireless WAN structure definitions // // // currently defined Wireless network subtypes // typedef enum _NDIS_WW_NETWORK_TYPE { NdisWWGeneric, NdisWWMobitex, NdisWWPinpoint, NdisWWCDPD, NdisWWArdis, NdisWWDataTAC, NdisWWMetricom, NdisWWGSM, NdisWWCDMA, NdisWWTDMA, NdisWWAMPS, NdisWWInmarsat, NdisWWpACT } NDIS_WW_NETWORK_TYPE; // // currently defined header formats // typedef enum _NDIS_WW_HEADER_FORMAT { NdisWWDIXEthernetFrames, NdisWWMPAKFrames, NdisWWRDLAPFrames, NdisWWMDC4800Frames } NDIS_WW_HEADER_FORMAT; // // currently defined encryption types // typedef enum _NDIS_WW_ENCRYPTION_TYPE { NdisWWUnknownEncryption = -1, NdisWWNoEncryption, NdisWWDefaultEncryption } NDIS_WW_ENCRYPTION_TYPE, *PNDIS_WW_ENCRYPTION_TYPE; // // OID_WW_GEN_INDICATION_REQUEST // typedef struct _NDIS_WW_INDICATION_REQUEST { NDIS_OID Oid; // IN UINT uIndicationFlag; // IN UINT uApplicationToken; // IN OUT HANDLE hIndicationHandle; // IN OUT INT iPollingInterval; // IN OUT NDIS_VAR_DATA_DESC InitialValue; // IN OUT NDIS_VAR_DATA_DESC OIDIndicationValue; // OUT - only valid after indication NDIS_VAR_DATA_DESC TriggerValue; // IN } NDIS_WW_INDICATION_REQUEST, *PNDIS_WW_INDICATION_REQUEST; #define OID_INDICATION_REQUEST_ENABLE 0x0000 #define OID_INDICATION_REQUEST_CANCEL 0x0001 // // OID_WW_GEN_DEVICE_INFO // typedef struct _WW_DEVICE_INFO { NDIS_VAR_DATA_DESC Manufacturer; NDIS_VAR_DATA_DESC ModelNum; NDIS_VAR_DATA_DESC SWVersionNum; NDIS_VAR_DATA_DESC SerialNum; } WW_DEVICE_INFO, *PWW_DEVICE_INFO; // // OID_WW_GEN_OPERATION_MODE // typedef INT WW_OPERATION_MODE; // 0 = Normal mode // 1 = Power saving mode // -1 = mode unknown // // OID_WW_GEN_LOCK_STATUS // typedef INT WW_LOCK_STATUS; // 0 = unlocked // 1 = locked // -1 = unknown lock status // // OID_WW_GEN_DISABLE_TRANSMITTER // typedef INT WW_DISABLE_TRANSMITTER; // 0 = transmitter enabled // 1 = transmitter disabled // -1 = unknown value // // OID_WW_GEN_NETWORK_ID // typedef NDIS_VAR_DATA_DESC WW_NETWORK_ID; // // OID_WW_GEN_PERMANENT_ADDRESS // typedef NDIS_VAR_DATA_DESC WW_PERMANENT_ADDRESS; // // OID_WW_GEN_CURRENT_ADDRESS // typedef struct _WW_CURRENT_ADDRESS { NDIS_WW_HEADER_FORMAT Format; NDIS_VAR_DATA_DESC Address; } WW_CURRENT_ADDRESS, *PWW_CURRENT_ADDRESS; // // OID_WW_GEN_SUSPEND_DRIVER // typedef BOOLEAN WW_SUSPEND_DRIVER; // 0 = driver operational // 1 = driver suspended // // OID_WW_GEN_BASESTATION_ID // typedef NDIS_VAR_DATA_DESC WW_BASESTATION_ID; // // OID_WW_GEN_CHANNEL_ID // typedef NDIS_VAR_DATA_DESC WW_CHANNEL_ID; // // OID_WW_GEN_ENCRYPTION_STATE // typedef BOOLEAN WW_ENCRYPTION_STATE; // 0 = if encryption is disabled // 1 = if encryption is enabled // // OID_WW_GEN_CHANNEL_QUALITY // typedef INT WW_CHANNEL_QUALITY; // 0 = Not in network contact, // 1-100 = Quality of Channel (100 is highest quality). // -1 = channel quality is unknown // // OID_WW_GEN_REGISTRATION_STATUS // typedef INT WW_REGISTRATION_STATUS; // 0 = Registration denied // 1 = Registration pending // 2 = Registered // -1 = unknown registration status // // OID_WW_GEN_RADIO_LINK_SPEED // typedef UINT WW_RADIO_LINK_SPEED; // Bits per second. // // OID_WW_GEN_LATENCY // typedef UINT WW_LATENCY; // milliseconds // // OID_WW_GEN_BATTERY_LEVEL // typedef INT WW_BATTERY_LEVEL; // 0-100 = battery level in percentage // (100=fully charged) // -1 = unknown battery level. // // OID_WW_GEN_EXTERNAL_POWER // typedef INT WW_EXTERNAL_POWER; // 0 = no external power connected // 1 = external power connected // -1 = unknown // // OID_WW_MET_FUNCTION // typedef NDIS_VAR_DATA_DESC WW_MET_FUNCTION; // // OID_WW_TAC_COMPRESSION // typedef BOOLEAN WW_TAC_COMPRESSION; // Determines whether or not network level compression // is being used. // // OID_WW_TAC_SET_CONFIG // typedef struct _WW_TAC_SETCONFIG { NDIS_VAR_DATA_DESC RCV_MODE; NDIS_VAR_DATA_DESC TX_CONTROL; NDIS_VAR_DATA_DESC RX_CONTROL; NDIS_VAR_DATA_DESC FLOW_CONTROL; NDIS_VAR_DATA_DESC RESET_CNF; NDIS_VAR_DATA_DESC READ_CNF; } WW_TAC_SETCONFIG, *PWW_TAC_SETCONFIG; // // OID_WW_TAC_GET_STATUS // typedef struct _WW_TAC_GETSTATUS { BOOLEAN Action; // Set = Execute command. NDIS_VAR_DATA_DESC Command; NDIS_VAR_DATA_DESC Option; NDIS_VAR_DATA_DESC Response; // The response to the requested command // - max. length of string is 256 octets. } WW_TAC_GETSTATUS, *PWW_TAC_GETSTATUS; // // OID_WW_TAC_USER_HEADER // typedef NDIS_VAR_DATA_DESC WW_TAC_USERHEADER; // This will hold the user header - Max. 64 octets. // // OID_WW_ARD_SNDCP // typedef struct _WW_ARD_SNDCP { NDIS_VAR_DATA_DESC Version; // The version of SNDCP protocol supported. INT BlockSize; // The block size used for SNDCP INT Window; // The window size used in SNDCP } WW_ARD_SNDCP, *PWW_ARD_SNDCP; // // OID_WW_ARD_TMLY_MSG // typedef BOOLEAN WW_ARD_CHANNEL_STATUS; // The current status of the inbound RF Channel. // // OID_WW_ARD_DATAGRAM // typedef struct _WW_ARD_DATAGRAM { BOOLEAN LoadLevel; // Byte that contains the load level info. INT SessionTime; // Datagram session time remaining. NDIS_VAR_DATA_DESC HostAddr; // Host address. NDIS_VAR_DATA_DESC THostAddr; // Test host address. } WW_ARD_DATAGRAM, *PWW_ARD_DATAGRAM; // // OID_WW_CDPD_SPNI // typedef struct _WW_CDPD_SPNI { UINT SPNI[10]; //10 16-bit service provider network IDs INT OperatingMode; // 0 = ignore SPNI, // 1 = require SPNI from list, // 2 = prefer SPNI from list. // 3 = exclude SPNI from list. } WW_CDPD_SPNI, *PWW_CDPD_SPNI; // // OID_WW_CDPD_WASI // typedef struct _WW_CDPD_WIDE_AREA_SERVICE_ID { UINT WASI[10]; //10 16-bit wide area service IDs INT OperatingMode; // 0 = ignore WASI, // 1 = Require WASI from list, // 2 = prefer WASI from list // 3 = exclude WASI from list. } WW_CDPD_WIDE_AREA_SERVICE_ID, *PWW_CDPD_WIDE_AREA_SERVICE_ID; // // OID_WW_CDPD_AREA_COLOR // typedef INT WW_CDPD_AREA_COLOR; // // OID_WW_CDPD_TX_POWER_LEVEL // typedef UINT WW_CDPD_TX_POWER_LEVEL; // // OID_WW_CDPD_EID // typedef NDIS_VAR_DATA_DESC WW_CDPD_EID; // // OID_WW_CDPD_HEADER_COMPRESSION // typedef INT WW_CDPD_HEADER_COMPRESSION; // 0 = no header compression, // 1 = always compress headers, // 2 = compress headers if MD-IS does // -1 = unknown // // OID_WW_CDPD_DATA_COMPRESSION // typedef INT WW_CDPD_DATA_COMPRESSION; // 0 = no data compression, // 1 = data compression enabled // -1 = unknown // // OID_WW_CDPD_CHANNEL_SELECT // typedef struct _WW_CDPD_CHANNEL_SELECT { UINT ChannelID; // channel number UINT fixedDuration; // duration in seconds } WW_CDPD_CHANNEL_SELECT, *PWW_CDPD_CHANNEL_SELECT; // // OID_WW_CDPD_CHANNEL_STATE // typedef enum _WW_CDPD_CHANNEL_STATE { CDPDChannelNotAvail, CDPDChannelScanning, CDPDChannelInitAcquired, CDPDChannelAcquired, CDPDChannelSleeping, CDPDChannelWaking, CDPDChannelCSDialing, CDPDChannelCSRedial, CDPDChannelCSAnswering, CDPDChannelCSConnected, CDPDChannelCSSuspended } WW_CDPD_CHANNEL_STATE, *PWW_CDPD_CHANNEL_STATE; // // OID_WW_CDPD_NEI // typedef enum _WW_CDPD_NEI_FORMAT { CDPDNeiIPv4, CDPDNeiCLNP, CDPDNeiIPv6 } WW_CDPD_NEI_FORMAT, *PWW_CDPD_NEI_FORMAT; typedef enum _WW_CDPD_NEI_TYPE { CDPDNeiIndividual, CDPDNeiMulticast, CDPDNeiBroadcast } WW_CDPD_NEI_TYPE; typedef struct _WW_CDPD_NEI { UINT uNeiIndex; WW_CDPD_NEI_FORMAT NeiFormat; WW_CDPD_NEI_TYPE NeiType; WORD NeiGmid; // group member identifier, only // meaningful if NeiType == // CDPDNeiMulticast NDIS_VAR_DATA_DESC NeiAddress; } WW_CDPD_NEI; // // OID_WW_CDPD_NEI_STATE // typedef enum _WW_CDPD_NEI_STATE { CDPDUnknown, CDPDRegistered, CDPDDeregistered } WW_CDPD_NEI_STATE, *PWW_CDPD_NEI_STATE; typedef enum _WW_CDPD_NEI_SUB_STATE { CDPDPending, // Registration pending CDPDNoReason, // Registration denied - no reason given CDPDMDISNotCapable, // Registration denied - MD-IS not capable of // handling M-ES at this time CDPDNEINotAuthorized, // Registration denied - NEI is not authorized to // use this subnetwork CDPDInsufficientAuth, // Registration denied - M-ES gave insufficient // authentication credentials CDPDUnsupportedAuth, // Registration denied - M-ES gave unsupported // authentication credentials CDPDUsageExceeded, // Registration denied - NEI has exceeded usage // limitations CDPDDeniedThisNetwork // Registration denied on this network, service // may be obtained on alternate Service Provider // network } WW_CDPD_NEI_SUB_STATE; typedef struct _WW_CDPD_NEI_REG_STATE { UINT uNeiIndex; WW_CDPD_NEI_STATE NeiState; WW_CDPD_NEI_SUB_STATE NeiSubState; } WW_CDPD_NEI_REG_STATE, *PWW_CDPD_NEI_REG_STATE; // // OID_WW_CDPD_SERVICE_PROVIDER_IDENTIFIER // typedef struct _WW_CDPD_SERVICE_PROVIDER_ID { UINT SPI[10]; //10 16-bit service provider IDs INT OperatingMode; // 0 = ignore SPI, // 1 = require SPI from list, // 2 = prefer SPI from list. // 3 = exclude SPI from list. } WW_CDPD_SERVICE_PROVIDER_ID, *PWW_CDPD_SERVICE_PROVIDER_ID; // // OID_WW_CDPD_SLEEP_MODE // typedef INT WW_CDPD_SLEEP_MODE; // // OID_WW_CDPD_TEI // typedef ULONG WW_CDPD_TEI; // // OID_WW_CDPD_CIRCUIT_SWITCHED // typedef struct _WW_CDPD_CIRCUIT_SWITCHED { INT service_preference; // -1 = unknown, // 0 = always use packet switched CDPD, // 1 = always use CS CDPD via AMPS, // 2 = always use CS CDPD via PSTN, // 3 = use circuit switched via AMPS only // when packet switched is not available. // 4 = use packet switched only when circuit // switched via AMPS is not available. // 5 = device manuf. defined service // preference. // 6 = device manuf. defined service // preference. INT service_status; // -1 = unknown, // 0 = packet switched CDPD, // 1 = circuit switched CDPD via AMPS, // 2 = circuit switched CDPD via PSTN. INT connect_rate; // CS connection bit rate (bits per second). // 0 = no active connection, // -1 = unknown // Dial code last used to dial. NDIS_VAR_DATA_DESC dial_code[20]; UINT sid; // Current AMPS system ID INT a_b_side_selection; // -1 = unknown, // 0 = no AMPS service // 1 = AMPS "A" side channels selected // 2 = AMPS "B" side channels selected INT AMPS_channel; // -1= unknown // 0 = no AMPS service. // 1-1023 = AMPS channel number in use UINT action; // 0 = no action // 1 = suspend (hangup) // 2 = dial // Default dial code for CS CDPD service // encoded as specified in the CS CDPD // implementor guidelines. NDIS_VAR_DATA_DESC default_dial[20]; // Number for the CS CDPD network to call // back the mobile, encoded as specified in // the CS CDPD implementor guidelines. NDIS_VAR_DATA_DESC call_back[20]; UINT sid_list[10]; // List of 10 16-bit preferred AMPS // system IDs for CS CDPD. UINT inactivity_timer; // Wait time after last data before dropping // call. // 0-65535 = inactivity time limit (seconds). UINT receive_timer; // secs. per CS-CDPD Implementor Guidelines. UINT conn_resp_timer; // secs. per CS-CDPD Implementor Guidelines. UINT reconn_resp_timer; // secs. per CS-CDPD Implementor Guidelines. UINT disconn_timer; // secs. per CS-CDPD Implementor Guidelines. UINT NEI_reg_timer; // secs. per CS-CDPD Implementor Guidelines. UINT reconn_retry_timer; // secs. per CS-CDPD Implementor Guidelines. UINT link_reset_timer; // secs. per CS-CDPD Implementor Guidelines. UINT link_reset_ack_timer; // secs. per CS-CDPD Implementor Guidelines. UINT n401_retry_limit; // per CS-CDPD Implementor Guidelines. UINT n402_retry_limit; // per CS-CDPD Implementor Guidelines. UINT n404_retry_limit; // per CS-CDPD Implementor Guidelines. UINT n405_retry_limit; // per CS-CDPD Implementor Guidelines. } WW_CDPD_CIRCUIT_SWITCHED, *WW_PCDPD_CIRCUIT_SWITCHED; typedef UINT WW_CDPD_RSSI; // // OID_WW_PIN_LOC_AUTHORIZE // typedef INT WW_PIN_AUTHORIZED; // 0 = unauthorized // 1 = authorized // -1 = unknown // // OID_WW_PIN_LAST_LOCATION // OID_WW_PIN_LOC_FIX // typedef struct _WW_PIN_LOCATION { INT Latitude; // Latitude in hundredths of a second INT Longitude; // Longitude in hundredths of a second INT Altitude; // Altitude in feet INT FixTime; // Time of the location fix, since midnight, local time (of the // current day), in tenths of a second INT NetTime; // Current local network time of the current day, since midnight, // in tenths of a second INT LocQuality; // 0-100 = location quality INT LatReg; // Latitude registration offset, in hundredths of a second INT LongReg; // Longitude registration offset, in hundredths of a second INT GMTOffset; // Offset in minutes of the local time zone from GMT } WW_PIN_LOCATION, *PWW_PIN_LOCATION; // // The following is set on a per-packet basis as OOB data with NdisClassWirelessWanMbxMailbox // typedef ULONG WW_MBX_MAILBOX_FLAG; // 1 = set mailbox flag, 0 = do not set mailbox flag // // OID_WW_MBX_SUBADDR // typedef struct _WW_MBX_PMAN { BOOLEAN ACTION; // 0 = Login PMAN, 1 = Logout PMAN UINT MAN; UCHAR PASSWORD[8]; // Password should be null for Logout and indications. // Maximum length of password is 8 chars. } WW_MBX_PMAN, *PWW_MBX_PMAN; // // OID_WW_MBX_FLEXLIST // typedef struct _WW_MBX_FLEXLIST { INT count; // Number of MAN entries used. // -1=unknown. UINT MAN[7]; // List of MANs. } WW_MBX_FLEXLIST; // // OID_WW_MBX_GROUPLIST // typedef struct _WW_MBX_GROUPLIST { INT count; // Number of MAN entries used. // -1=unknown. UINT MAN[15]; // List of MANs. } WW_MBX_GROUPLIST; // // OID_WW_MBX_TRAFFIC_AREA // typedef enum _WW_MBX_TRAFFIC_AREA { unknown_traffic_area, // The driver has no information about the current traffic area. in_traffic_area, // Mobile unit has entered a subscribed traffic area. in_auth_traffic_area, // Mobile unit is outside traffic area but is authorized. unauth_traffic_area // Mobile unit is outside traffic area but is un-authorized. } WW_MBX_TRAFFIC_AREA; // // OID_WW_MBX_LIVE_DIE // typedef INT WW_MBX_LIVE_DIE; // 0 = DIE last received // 1 = LIVE last received // -1 = unknown // // OID_WW_MBX_TEMP_DEFAULTLIST // typedef struct _WW_MBX_CHANNEL_PAIR { UINT Mobile_Tx; UINT Mobile_Rx; } WW_MBX_CHANNEL_PAIR, *PWW_MBX_CHANNEL_PAIR; typedef struct _WW_MBX_TEMPDEFAULTLIST { UINT Length; WW_MBX_CHANNEL_PAIR ChannelPair[1]; } WW_MBX_TEMPDEFAULTLIST, *WW_PMBX_TEMPDEFAULTLIST; #endif // WIRELESS_WAN #endif // _NTDDNDIS_ snort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/Ntddpack.h0000644000175200017520000000241413571422607017252 00000000000000 #ifndef __NTDDPACKET #define __NTDDPACKET 1 #include "devioctl.h" /*#include */ struct _PACKET_OID_DATA { ULONG Oid; ULONG Length; UCHAR Data[1]; }; typedef struct _PACKET_OID_DATA PACKET_OID_DATA, *PPACKET_OID_DATA; /*#include */ #define FILE_DEVICE_PROTOCOL 0x8000 #define IOCTL_PROTOCOL_QUERY_OID CTL_CODE(FILE_DEVICE_PROTOCOL, 0 , METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_PROTOCOL_SET_OID CTL_CODE(FILE_DEVICE_PROTOCOL, 1 , METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_PROTOCOL_STATISTICS CTL_CODE(FILE_DEVICE_PROTOCOL, 2 , METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_PROTOCOL_RESET CTL_CODE(FILE_DEVICE_PROTOCOL, 3 , METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_PROTOCOL_READ CTL_CODE(FILE_DEVICE_PROTOCOL, 4 , METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_PROTOCOL_WRITE CTL_CODE(FILE_DEVICE_PROTOCOL, 5 , METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_PROTOCOL_MACNAME CTL_CODE(FILE_DEVICE_PROTOCOL, 6 , METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_OPEN CTL_CODE(FILE_DEVICE_PROTOCOL, 7 , METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_CLOSE CTL_CODE(FILE_DEVICE_PROTOCOL, 8 , METHOD_BUFFERED, FILE_ANY_ACCESS) #endif snort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/Packet32.h0000644000175200017520000004107613571422610017077 00000000000000/* * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) * Copyright (c) 2005 - 2007 CACE Technologies, Davis (California) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Politecnico di Torino, CACE Technologies * nor the names of its contributors may be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /** @ingroup packetapi * @{ */ /** @defgroup packet32h Packet.dll definitions and data structures * Packet32.h contains the data structures and the definitions used by packet.dll. * The file is used both by the Win9x and the WinNTx versions of packet.dll, and can be included * by the applications that use the functions of this library * @{ */ #ifndef __PACKET32 #define __PACKET32 #include #ifdef HAVE_AIRPCAP_API #include #else #if !defined(AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_) #define AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ typedef struct _AirpcapHandle *PAirpcapHandle; #endif /* AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ */ #endif /* HAVE_AIRPCAP_API */ #ifdef HAVE_DAG_API #include #endif /* HAVE_DAG_API */ // Working modes #define PACKET_MODE_CAPT 0x0 ///< Capture mode #define PACKET_MODE_STAT 0x1 ///< Statistical mode #define PACKET_MODE_MON 0x2 ///< Monitoring mode #define PACKET_MODE_DUMP 0x10 ///< Dump mode #define PACKET_MODE_STAT_DUMP MODE_DUMP | MODE_STAT ///< Statistical dump Mode /// Alignment macro. Defines the alignment size. #define Packet_ALIGNMENT sizeof(int) /// Alignment macro. Rounds up to the next even multiple of Packet_ALIGNMENT. #define Packet_WORDALIGN(x) (((x)+(Packet_ALIGNMENT-1))&~(Packet_ALIGNMENT-1)) #define NdisMediumNull -1 ///< Custom linktype: NDIS doesn't provide an equivalent #define NdisMediumCHDLC -2 ///< Custom linktype: NDIS doesn't provide an equivalent #define NdisMediumPPPSerial -3 ///< Custom linktype: NDIS doesn't provide an equivalent #define NdisMediumBare80211 -4 ///< Custom linktype: NDIS doesn't provide an equivalent #define NdisMediumRadio80211 -5 ///< Custom linktype: NDIS doesn't provide an equivalent #define NdisMediumPpi -6 ///< Custom linktype: NDIS doesn't provide an equivalent // Loopback behaviour definitions #define NPF_DISABLE_LOOPBACK 1 ///< Drop the packets sent by the NPF driver #define NPF_ENABLE_LOOPBACK 2 ///< Capture the packets sent by the NPF driver /*! \brief Network type structure. This structure is used by the PacketGetNetType() function to return information on the current adapter's type and speed. */ typedef struct NetType { UINT LinkType; ///< The MAC of the current network adapter (see function PacketGetNetType() for more information) ULONGLONG LinkSpeed; ///< The speed of the network in bits per second }NetType; //some definitions stolen from libpcap #ifndef BPF_MAJOR_VERSION /*! \brief A BPF pseudo-assembly program. The program will be injected in the kernel by the PacketSetBPF() function and applied to every incoming packet. */ struct bpf_program { UINT bf_len; ///< Indicates the number of instructions of the program, i.e. the number of struct bpf_insn that will follow. struct bpf_insn *bf_insns; ///< A pointer to the first instruction of the program. }; /*! \brief A single BPF pseudo-instruction. bpf_insn contains a single instruction for the BPF register-machine. It is used to send a filter program to the driver. */ struct bpf_insn { USHORT code; ///< Instruction type and addressing mode. UCHAR jt; ///< Jump if true UCHAR jf; ///< Jump if false int k; ///< Generic field used for various purposes. }; /*! \brief Structure that contains a couple of statistics values on the current capture. It is used by packet.dll to return statistics about a capture session. */ struct bpf_stat { UINT bs_recv; ///< Number of packets that the driver received from the network adapter ///< from the beginning of the current capture. This value includes the packets ///< lost by the driver. UINT bs_drop; ///< number of packets that the driver lost from the beginning of a capture. ///< Basically, a packet is lost when the the buffer of the driver is full. ///< In this situation the packet cannot be stored and the driver rejects it. UINT ps_ifdrop; ///< drops by interface. XXX not yet supported UINT bs_capt; ///< number of packets that pass the filter, find place in the kernel buffer and ///< thus reach the application. }; /*! \brief Packet header. This structure defines the header associated with every packet delivered to the application. */ struct bpf_hdr { struct timeval bh_tstamp; ///< The timestamp associated with the captured packet. ///< It is stored in a TimeVal structure. UINT bh_caplen; ///< Length of captured portion. The captured portion can be different ///< from the original packet, because it is possible (with a proper filter) ///< to instruct the driver to capture only a portion of the packets. UINT bh_datalen; ///< Original length of packet USHORT bh_hdrlen; ///< Length of bpf header (this struct plus alignment padding). In some cases, ///< a padding could be added between the end of this structure and the packet ///< data for performance reasons. This filed can be used to retrieve the actual data ///< of the packet. }; /*! \brief Dump packet header. This structure defines the header associated with the packets in a buffer to be used with PacketSendPackets(). It is simpler than the bpf_hdr, because it corresponds to the header associated by WinPcap and libpcap to a packet in a dump file. This makes straightforward sending WinPcap dump files to the network. */ struct dump_bpf_hdr{ struct timeval ts; ///< Time stamp of the packet UINT caplen; ///< Length of captured portion. The captured portion can smaller than the ///< the original packet, because it is possible (with a proper filter) to ///< instruct the driver to capture only a portion of the packets. UINT len; ///< Length of the original packet (off wire). }; #endif struct bpf_stat; #define DOSNAMEPREFIX TEXT("Packet_") ///< Prefix added to the adapters device names to create the WinPcap devices #define MAX_LINK_NAME_LENGTH 64 //< Maximum length of the devices symbolic links #define NMAX_PACKET 65535 /*! \brief Addresses of a network adapter. This structure is used by the PacketGetNetInfoEx() function to return the IP addresses associated with an adapter. */ typedef struct npf_if_addr { struct sockaddr_storage IPAddress; ///< IP address. struct sockaddr_storage SubnetMask; ///< Netmask for that address. struct sockaddr_storage Broadcast; ///< Broadcast address. }npf_if_addr; #define ADAPTER_NAME_LENGTH 256 + 12 ///< Maximum length for the name of an adapter. The value is the same used by the IP Helper API. #define ADAPTER_DESC_LENGTH 128 ///< Maximum length for the description of an adapter. The value is the same used by the IP Helper API. #define MAX_MAC_ADDR_LENGTH 8 ///< Maximum length for the link layer address of an adapter. The value is the same used by the IP Helper API. #define MAX_NETWORK_ADDRESSES 16 ///< Maximum length for the link layer address of an adapter. The value is the same used by the IP Helper API. typedef struct WAN_ADAPTER_INT WAN_ADAPTER; ///< Describes an opened wan (dialup, VPN...) network adapter using the NetMon API typedef WAN_ADAPTER *PWAN_ADAPTER; ///< Describes an opened wan (dialup, VPN...) network adapter using the NetMon API #define INFO_FLAG_NDIS_ADAPTER 0 ///< Flag for ADAPTER_INFO: this is a traditional ndis adapter #define INFO_FLAG_NDISWAN_ADAPTER 1 ///< Flag for ADAPTER_INFO: this is a NdisWan adapter, and it's managed by WANPACKET #define INFO_FLAG_DAG_CARD 2 ///< Flag for ADAPTER_INFO: this is a DAG card #define INFO_FLAG_DAG_FILE 6 ///< Flag for ADAPTER_INFO: this is a DAG file #define INFO_FLAG_DONT_EXPORT 8 ///< Flag for ADAPTER_INFO: when this flag is set, the adapter will not be listed or openend by winpcap. This allows to prevent exporting broken network adapters, like for example FireWire ones. #define INFO_FLAG_AIRPCAP_CARD 16 ///< Flag for ADAPTER_INFO: this is an airpcap card #define INFO_FLAG_NPFIM_DEVICE 32 /*! \brief Describes an opened network adapter. This structure is the most important for the functioning of packet.dll, but the great part of its fields should be ignored by the user, since the library offers functions that avoid to cope with low-level parameters */ typedef struct _ADAPTER { HANDLE hFile; ///< \internal Handle to an open instance of the NPF driver. CHAR SymbolicLink[MAX_LINK_NAME_LENGTH]; ///< \internal A string containing the name of the network adapter currently opened. int NumWrites; ///< \internal Number of times a packets written on this adapter will be repeated ///< on the wire. HANDLE ReadEvent; ///< A notification event associated with the read calls on the adapter. ///< It can be passed to standard Win32 functions (like WaitForSingleObject ///< or WaitForMultipleObjects) to wait until the driver's buffer contains some ///< data. It is particularly useful in GUI applications that need to wait ///< concurrently on several events. In Windows NT/2000 the PacketSetMinToCopy() ///< function can be used to define the minimum amount of data in the kernel buffer ///< that will cause the event to be signalled. UINT ReadTimeOut; ///< \internal The amount of time after which a read on the driver will be released and ///< ReadEvent will be signaled, also if no packets were captured CHAR Name[ADAPTER_NAME_LENGTH]; PWAN_ADAPTER pWanAdapter; UINT Flags; ///< Adapter's flags. Tell if this adapter must be treated in a different way, using the Netmon API or the dagc API. #ifdef HAVE_AIRPCAP_API PAirpcapHandle AirpcapAd; #endif // HAVE_AIRPCAP_API #ifdef HAVE_NPFIM_API void* NpfImHandle; #endif // HAVE_NPFIM_API #ifdef HAVE_DAG_API dagc_t *pDagCard; ///< Pointer to the dagc API adapter descriptor for this adapter PCHAR DagBuffer; ///< Pointer to the buffer with the packets that is received from the DAG card struct timeval DagReadTimeout; ///< Read timeout. The dagc API requires a timeval structure unsigned DagFcsLen; ///< Length of the frame check sequence attached to any packet by the card. Obtained from the registry DWORD DagFastProcess; ///< True if the user requests fast capture processing on this card. Higher level applications can use this value to provide a faster but possibly unprecise capture (for example, libpcap doesn't convert the timestamps). #endif // HAVE_DAG_API } ADAPTER, *LPADAPTER; /*! \brief Structure that contains a group of packets coming from the driver. This structure defines the header associated with every packet delivered to the application. */ typedef struct _PACKET { HANDLE hEvent; ///< \deprecated Still present for compatibility with old applications. OVERLAPPED OverLapped; ///< \deprecated Still present for compatibility with old applications. PVOID Buffer; ///< Buffer with containing the packets. See the PacketReceivePacket() for ///< details about the organization of the data in this buffer UINT Length; ///< Length of the buffer DWORD ulBytesReceived; ///< Number of valid bytes present in the buffer, i.e. amount of data ///< received by the last call to PacketReceivePacket() BOOLEAN bIoComplete; ///< \deprecated Still present for compatibility with old applications. } PACKET, *LPPACKET; /*! \brief Structure containing an OID request. It is used by the PacketRequest() function to send an OID to the interface card driver. It can be used, for example, to retrieve the status of the error counters on the adapter, its MAC address, the list of the multicast groups defined on it, and so on. */ struct _PACKET_OID_DATA { ULONG Oid; ///< OID code. See the Microsoft DDK documentation or the file ntddndis.h ///< for a complete list of valid codes. ULONG Length; ///< Length of the data field UCHAR Data[1]; ///< variable-lenght field that contains the information passed to or received ///< from the adapter. }; typedef struct _PACKET_OID_DATA PACKET_OID_DATA, *PPACKET_OID_DATA; #ifdef __cplusplus extern "C" { #endif /** * @} */ /* BOOLEAN QueryWinPcapRegistryStringA(CHAR *SubKeyName, CHAR *Value, UINT *pValueLen, CHAR *DefaultVal); BOOLEAN QueryWinPcapRegistryStringW(WCHAR *SubKeyName, WCHAR *Value, UINT *pValueLen, WCHAR *DefaultVal); */ //--------------------------------------------------------------------------- // EXPORTED FUNCTIONS //--------------------------------------------------------------------------- PCHAR PacketGetVersion(); PCHAR PacketGetDriverVersion(); BOOLEAN PacketSetMinToCopy(LPADAPTER AdapterObject,int nbytes); BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject,int nwrites); BOOLEAN PacketSetMode(LPADAPTER AdapterObject,int mode); BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout); BOOLEAN PacketSetBpf(LPADAPTER AdapterObject,struct bpf_program *fp); BOOLEAN PacketSetLoopbackBehavior(LPADAPTER AdapterObject, UINT LoopbackBehavior); INT PacketSetSnapLen(LPADAPTER AdapterObject,int snaplen); BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s); BOOLEAN PacketGetStatsEx(LPADAPTER AdapterObject,struct bpf_stat *s); BOOLEAN PacketSetBuff(LPADAPTER AdapterObject,int dim); BOOLEAN PacketGetNetType (LPADAPTER AdapterObject,NetType *type); LPADAPTER PacketOpenAdapter(PCHAR AdapterName); BOOLEAN PacketSendPacket(LPADAPTER AdapterObject,LPPACKET pPacket,BOOLEAN Sync); INT PacketSendPackets(LPADAPTER AdapterObject,PVOID PacketBuff,ULONG Size, BOOLEAN Sync); LPPACKET PacketAllocatePacket(void); VOID PacketInitPacket(LPPACKET lpPacket,PVOID Buffer,UINT Length); VOID PacketFreePacket(LPPACKET lpPacket); BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync); BOOLEAN PacketSetHwFilter(LPADAPTER AdapterObject,ULONG Filter); BOOLEAN PacketGetAdapterNames(PTSTR pStr,PULONG BufferSize); BOOLEAN PacketGetNetInfoEx(PCHAR AdapterName, npf_if_addr* buffer, PLONG NEntries); BOOLEAN PacketRequest(LPADAPTER AdapterObject,BOOLEAN Set,PPACKET_OID_DATA OidData); HANDLE PacketGetReadEvent(LPADAPTER AdapterObject); BOOLEAN PacketSetDumpName(LPADAPTER AdapterObject, void *name, int len); BOOLEAN PacketSetDumpLimits(LPADAPTER AdapterObject, UINT maxfilesize, UINT maxnpacks); BOOLEAN PacketIsDumpEnded(LPADAPTER AdapterObject, BOOLEAN sync); BOOL PacketStopDriver(); VOID PacketCloseAdapter(LPADAPTER lpAdapter); BOOLEAN PacketStartOem(PCHAR errorString, UINT errorStringLength); BOOLEAN PacketStartOemEx(PCHAR errorString, UINT errorStringLength, ULONG flags); PAirpcapHandle PacketGetAirPcapHandle(LPADAPTER AdapterObject); // // Used by PacketStartOemEx // #define PACKET_START_OEM_NO_NETMON 0x00000001 #ifdef __cplusplus } #endif #endif //__PACKET32 snort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/pcap-bpf.h0000644000175200017520000000442113571422610017204 00000000000000/*- * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 * The Regents of the University of California. All rights reserved. * * This code is derived from the Stanford/CMU enet packet filter, * (net/enet.c) distributed as part of 4.3BSD, and code contributed * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence * Berkeley Laboratory. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#) $Header$ (LBL) */ /* * For backwards compatibility. * * Note to OS vendors: do NOT get rid of this file! Some applications * might expect to be able to include . */ #include snort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/pcap.h0000644000175200017520000000431413571422610016440 00000000000000/* * Copyright (c) 1993, 1994, 1995, 1996, 1997 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the Computer Systems * Engineering Group at Lawrence Berkeley Laboratory. * 4. Neither the name of the University nor of the Laboratory may be used * to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#) $Header$ (LBL) */ /* * For backwards compatibility. * * Note to OS vendors: do NOT get rid of this file! Many applications * expect to be able to include , and at least some of them * go through contortions in their configure scripts to try to detect * OSes that have "helpfully" moved pcap.h to without * leaving behind a file. */ #include snort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/pcap-int.h0000644000175200017520000003131313571422610017227 00000000000000/* * Copyright (c) 1994, 1995, 1996 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the Computer Systems * Engineering Group at Lawrence Berkeley Laboratory. * 4. Neither the name of the University nor of the Laboratory may be used * to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#) $Header$ (LBL) */ #ifndef pcap_int_h #define pcap_int_h #ifdef __cplusplus extern "C" { #endif #include #ifdef WIN32 #include #endif /* WIN32 */ #ifdef MSDOS #include #include #endif /* * Savefile */ typedef enum { NOT_SWAPPED, SWAPPED, MAYBE_SWAPPED } swapped_type_t; struct pcap_sf { FILE *rfile; int swapped; int hdrsize; swapped_type_t lengths_swapped; int version_major; int version_minor; u_char *base; }; struct pcap_md { struct pcap_stat stat; /*XXX*/ int use_bpf; /* using kernel filter */ u_long TotPkts; /* can't oflow for 79 hrs on ether */ u_long TotAccepted; /* count accepted by filter */ u_long TotDrops; /* count of dropped packets */ long TotMissed; /* missed by i/f during this run */ long OrigMissed; /* missed by i/f before this run */ char *device; /* device name */ #ifdef linux int sock_packet; /* using Linux 2.0 compatible interface */ int timeout; /* timeout specified to pcap_open_live */ int clear_promisc; /* must clear promiscuous mode when we close */ int cooked; /* using SOCK_DGRAM rather than SOCK_RAW */ int ifindex; /* interface index of device we're bound to */ int lo_ifindex; /* interface index of the loopback device */ struct pcap *next; /* list of open promiscuous sock_packet pcaps */ #endif #ifdef HAVE_DAG_API #ifdef HAVE_DAG_STREAMS_API u_char *dag_mem_bottom; /* DAG card current memory bottom pointer */ u_char *dag_mem_top; /* DAG card current memory top pointer */ #else void *dag_mem_base; /* DAG card memory base address */ u_int dag_mem_bottom; /* DAG card current memory bottom offset */ u_int dag_mem_top; /* DAG card current memory top offset */ #endif /* HAVE_DAG_STREAMS_API */ int dag_fcs_bits; /* Number of checksum bits from link layer */ int dag_offset_flags; /* Flags to pass to dag_offset(). */ int dag_stream; /* DAG stream number */ int dag_timeout; /* timeout specified to pcap_open_live. * Same as in linux above, introduce * generally? */ #endif /* HAVE_DAG_API */ #ifdef HAVE_REMOTE /*! There is really a mess with previous variables, and it seems to me that they are not used (they are used in pcap_pf.c only). I think we have to start using them. The meaning is the following: - TotPkts: the amount of packets received by the bpf filter, *before* applying the filter - TotAccepted: the amount of packets that satisfies the filter - TotDrops: the amount of packet that were dropped into the kernel buffer because of lack of space - TotMissed: the amount of packets that were dropped by the physical interface; it is basically the value of the hardware counter into the card. This number is never put to zero, so this number takes into account the *total* number of interface drops starting from the interface power-on. - OrigMissed: the amount of packets that were dropped by the interface *when the capture begins*. This value is used to detect the number of packets dropped by the interface *during the present capture*, so that (ps_ifdrops= TotMissed - OrigMissed). */ unsigned int TotNetDrops; //!< keeps the number of packets that have been dropped by the network /*! \brief It keeps the number of packets that have been received by the application. Packets dropped by the kernel buffer are not counted in this variable. The variable is always equal to (TotAccepted - TotDrops), exept for the case of remote capture, in which we have also packets in fligh, i.e. that have been transmitted by the remote host, but that have not been received (yet) from the client. In this case, (TotAccepted - TotDrops - TotNetDrops) gives a wrong result, since this number does not corresponds always to the number of packet received by the application. For this reason, in the remote capture we need another variable that takes into account of the number of packets actually received by the application. */ unsigned int TotCapt; #endif /* HAVE_REMOTE */ }; /* * Ultrix, DEC OSF/1^H^H^H^H^H^H^H^H^HDigital UNIX^H^H^H^H^H^H^H^H^H^H^H^H * Tru64 UNIX, and NetBSD pad to make everything line up on a nice boundary. */ #if defined(ultrix) || defined(__osf__) || (defined(__NetBSD__) && __NetBSD_Version__ > 106000000) #define PCAP_FDDIPAD 3 #endif struct pcap { #ifdef WIN32 ADAPTER *adapter; LPPACKET Packet; int timeout; int nonblock; #else int fd; int selectable_fd; int send_fd; #endif /* WIN32 */ int snapshot; int linktype; int tzoff; /* timezone offset */ int offset; /* offset for proper alignment */ int break_loop; /* flag set to force break from packet-reading loop */ #ifdef PCAP_FDDIPAD int fddipad; #endif #ifdef MSDOS int inter_packet_wait; /* offline: wait between packets */ void (*wait_proc)(void); /* call proc while waiting */ #endif struct pcap_sf sf; struct pcap_md md; /* * Read buffer. */ int bufsize; u_char *buffer; u_char *bp; int cc; /* * Place holder for pcap_next(). */ u_char *pkt; /* We're accepting only packets in this direction/these directions. */ pcap_direction_t direction; /* * Methods. */ int (*read_op)(pcap_t *, int cnt, pcap_handler, u_char *); int (*inject_op)(pcap_t *, const void *, size_t); int (*setfilter_op)(pcap_t *, struct bpf_program *); int (*setdirection_op)(pcap_t *, pcap_direction_t); int (*set_datalink_op)(pcap_t *, int); int (*getnonblock_op)(pcap_t *, char *); int (*setnonblock_op)(pcap_t *, int, char *); int (*stats_op)(pcap_t *, struct pcap_stat *); void (*close_op)(pcap_t *); /* * Placeholder for filter code if bpf not in kernel. */ struct bpf_program fcode; char errbuf[PCAP_ERRBUF_SIZE + 1]; int dlt_count; u_int *dlt_list; DAQ_PktHdr_t pkt_header; /* This is needed for the pcap_next_ex() to work */ #ifdef HAVE_REMOTE #ifndef WIN32 // Win32 already defines 'timeout' int timeout; //!< timeout to be used in the pcap_open() #endif /*! \brief '1' if we're the network client; needed by several functions (like pcap_setfilter() ) to know if they have to use the socket or they have to open the local adapter. */ int rmt_clientside; SOCKET rmt_sockctrl; //!< socket ID of the socket used for the control connection SOCKET rmt_sockdata; //!< socket ID of the socket used for the data connection int rmt_flags; //!< we have to save flags, since they are passed by the pcap_open_live(), but they are used by the pcap_startcapture() int rmt_capstarted; //!< 'true' if the capture is already started (needed to knoe if we have to call the pcap_startcapture() struct pcap_samp rmt_samp; //!< Keeps the parameters related to the sampling process. char *currentfilter; //!< Pointer to a buffer (allocated at run-time) that stores the current filter. Needed when flag PCAP_OPENFLAG_NOCAPTURE_RPCAP is turned on. #endif /* HAVE_REMOTE */ }; /* * This is a timeval as stored in disk in a dumpfile. * It has to use the same types everywhere, independent of the actual * `struct timeval' */ struct pcap_timeval { bpf_int32 tv_sec; /* seconds */ bpf_int32 tv_usec; /* microseconds */ }; /* * How a `pcap_pkthdr' is actually stored in the dumpfile. * * Do not change the format of this structure, in any way (this includes * changes that only affect the length of fields in this structure), * and do not make the time stamp anything other than seconds and * microseconds (e.g., seconds and nanoseconds). Instead: * * introduce a new structure for the new format; * * send mail to "tcpdump-workers@tcpdump.org", requesting a new * magic number for your new capture file format, and, when * you get the new magic number, put it in "savefile.c"; * * use that magic number for save files with the changed record * header; * * make the code in "savefile.c" capable of reading files with * the old record header as well as files with the new record header * (using the magic number to determine the header format). * * Then supply the changes to "patches@tcpdump.org", so that future * versions of libpcap and programs that use it (such as tcpdump) will * be able to read your new capture file format. */ struct pcap_sf_pkthdr { struct pcap_timeval ts; /* time stamp */ bpf_u_int32 caplen; /* length of portion present */ bpf_u_int32 len; /* length this packet (off wire) */ }; /* * How a `pcap_pkthdr' is actually stored in dumpfiles written * by some patched versions of libpcap (e.g. the ones in Red * Hat Linux 6.1 and 6.2). * * Do not change the format of this structure, in any way (this includes * changes that only affect the length of fields in this structure). * Instead, introduce a new structure, as per the above. */ struct pcap_sf_patched_pkthdr { struct pcap_timeval ts; /* time stamp */ bpf_u_int32 caplen; /* length of portion present */ bpf_u_int32 len; /* length this packet (off wire) */ int index; unsigned short protocol; unsigned char pkt_type; }; int yylex(void); #ifndef min #define min(a, b) ((a) > (b) ? (b) : (a)) #endif /* XXX should these be in pcap.h? */ int pcap_offline_read(pcap_t *, int, pcap_handler, u_char *); int pcap_read(pcap_t *, int cnt, pcap_handler, u_char *); #ifndef HAVE_STRLCPY #define strlcpy(x, y, z) \ (strncpy((x), (y), (z)), \ ((z) <= 0 ? 0 : ((x)[(z) - 1] = '\0')), \ strlen((y))) #endif #include #if !defined(HAVE_SNPRINTF) #define snprintf pcap_snprintf extern int snprintf (char *, size_t, const char *, ...); #endif #if !defined(HAVE_VSNPRINTF) #define vsnprintf pcap_vsnprintf extern int vsnprintf (char *, size_t, const char *, va_list ap); #endif /* * Routines that most pcap implementations can use for non-blocking mode. */ #if !defined(WIN32) && !defined(MSDOS) int pcap_getnonblock_fd(pcap_t *, char *); int pcap_setnonblock_fd(pcap_t *p, int, char *); #endif void pcap_close_common(pcap_t *); /* * Internal interfaces for "pcap_findalldevs()". * * "pcap_platform_finddevs()" is a platform-dependent routine to * add devices not found by the "standard" mechanisms (SIOCGIFCONF, * "getifaddrs()", etc.. * * "pcap_add_if()" adds an interface to the list of interfaces. */ int pcap_platform_finddevs(pcap_if_t **, char *); int add_addr_to_iflist(pcap_if_t **, const char *, u_int, struct sockaddr *, size_t, struct sockaddr *, size_t, struct sockaddr *, size_t, struct sockaddr *, size_t, char *); int pcap_add_if(pcap_if_t **, const char *, u_int, const char *, char *); struct sockaddr *dup_sockaddr(struct sockaddr *, size_t); int add_or_find_if(pcap_if_t **, pcap_if_t **, const char *, u_int, const char *, char *); #ifdef WIN32 char *pcap_win32strerror(void); #endif int install_bpf_program(pcap_t *, struct bpf_program *); int pcap_strcasecmp(const char *, const char *); #ifdef __cplusplus } #endif #endif snort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/pcap-namedb.h0000644000175200017520000000400213571422610017656 00000000000000/* * Copyright (c) 1994, 1996 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the Computer Systems * Engineering Group at Lawrence Berkeley Laboratory. * 4. Neither the name of the University nor of the Laboratory may be used * to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#) $Header$ (LBL) */ /* * For backwards compatibility. * * Note to OS vendors: do NOT get rid of this file! Some applications * might expect to be able to include . */ #include snort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/pcap-stdinc.h0000644000175200017520000000534513571422610017727 00000000000000/* * Copyright (c) 2002 - 2005 NetGroup, Politecnico di Torino (Italy) * Copyright (c) 2005 - 2009 CACE Technologies, Inc. Davis (California) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Politecnico di Torino nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * @(#) $Header$ (LBL) */ #define SIZEOF_CHAR 1 #define SIZEOF_SHORT 2 #define SIZEOF_INT 4 #ifndef _MSC_EXTENSIONS #define SIZEOF_LONG_LONG 8 #endif /* * Avoids a compiler warning in case this was already defined * (someone defined _WINSOCKAPI_ when including 'windows.h', in order * to prevent it from including 'winsock.h') */ #ifdef _WINSOCKAPI_ #undef _WINSOCKAPI_ #endif #include #include #include "bittypes.h" #include #include #ifndef __MINGW32__ #include "IP6_misc.h" #endif #define caddr_t char* #if _MSC_VER < 1500 #define snprintf _snprintf #define vsnprintf _vsnprintf #define strdup _strdup #endif #define inline __inline #ifdef __MINGW32__ #include #else /*__MINGW32__*/ /* MSVC compiler */ #ifndef _UINTPTR_T_DEFINED #ifdef _WIN64 typedef unsigned __int64 uintptr_t; #else typedef _W64 unsigned int uintptr_t; #endif #define _UINTPTR_T_DEFINED #endif #ifndef _INTPTR_T_DEFINED #ifdef _WIN64 typedef __int64 intptr_t; #else typedef _W64 int intptr_t; #endif #define _INTPTR_T_DEFINED #endif #endif /*__MINGW32__*/ snort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/pthread.h0000644000175200017520000010557413571422610017156 00000000000000/* This is an implementation of the threads API of POSIX 1003.1-2001. * * -------------------------------------------------------------------------- * * Pthreads-win32 - POSIX Threads Library for Win32 * Copyright(C) 1998 John E. Bossom * Copyright(C) 1999,2003 Pthreads-win32 contributors * * Contact Email: rpj@callisto.canberra.edu.au * * The current list of contributors is contained * in the file CONTRIBUTORS included with the source * code distribution. The list can also be seen at the * following World Wide Web location: * http://sources.redhat.com/pthreads-win32/contributors.html * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library in the file COPYING.LIB; * if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #if !defined( PTHREAD_H ) #define PTHREAD_H #undef PTW32_LEVEL #if defined(_POSIX_SOURCE) #define PTW32_LEVEL 0 /* Early POSIX */ #endif #if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 #undef PTW32_LEVEL #define PTW32_LEVEL 1 /* Include 1b, 1c and 1d */ #endif #if defined(INCLUDE_NP) #undef PTW32_LEVEL #define PTW32_LEVEL 2 /* Include Non-Portable extensions */ #endif #define PTW32_LEVEL_MAX 3 #if !defined(PTW32_LEVEL) #define PTW32_LEVEL PTW32_LEVEL_MAX /* Include everything */ #endif #ifdef _UWIN # define HAVE_STRUCT_TIMESPEC 1 # define HAVE_SIGNAL_H 1 # undef HAVE_CONFIG_H # pragma comment(lib, "pthread") #endif /* * ------------------------------------------------------------- * * * Module: pthread.h * * Purpose: * Provides an implementation of PThreads based upon the * standard: * * POSIX 1003.1-2001 * and * The Single Unix Specification version 3 * * (these two are equivalent) * * in order to enhance code portability between Windows, * various commercial Unix implementations, and Linux. * * See the ANNOUNCE file for a full list of conforming * routines and defined constants, and a list of missing * routines and constants not defined in this implementation. * * Authors: * There have been many contributors to this library. * The initial implementation was contributed by * John Bossom, and several others have provided major * sections or revisions of parts of the implementation. * Often significant effort has been contributed to * find and fix important bugs and other problems to * improve the reliability of the library, which sometimes * is not reflected in the amount of code which changed as * result. * As much as possible, the contributors are acknowledged * in the ChangeLog file in the source code distribution * where their changes are noted in detail. * * Contributors are listed in the CONTRIBUTORS file. * * As usual, all bouquets go to the contributors, and all * brickbats go to the project maintainer. * * Maintainer: * The code base for this project is coordinated and * eventually pre-tested, packaged, and made available by * * Ross Johnson * * QA Testers: * Ultimately, the library is tested in the real world by * a host of competent and demanding scientists and * engineers who report bugs and/or provide solutions * which are then fixed or incorporated into subsequent * versions of the library. Each time a bug is fixed, a * test case is written to prove the fix and ensure * that later changes to the code don't reintroduce the * same error. The number of test cases is slowly growing * and therefore so is the code reliability. * * Compliance: * See the file ANNOUNCE for the list of implemented * and not-implemented routines and defined options. * Of course, these are all defined is this file as well. * * Web site: * The source code and other information about this library * are available from * * http://sources.redhat.com/pthreads-win32/ * * ------------------------------------------------------------- */ /* Try to avoid including windows.h */ #if defined(__MINGW32__) && defined(__cplusplus) /* * FIXME: The pthreadGCE.dll build gets linker unresolved errors * on pthread_key_create() unless windows.h is included here. * It appears to have something to do with an argument type mismatch. * Looking at tsd.o with 'nm' shows this line: * 00000000 T _pthread_key_create__FPP14pthread_key_t_PFPv_v * instead of * 00000000 T _pthread_key_create */ #define PTW32_INCLUDE_WINDOWS_H #endif #ifdef PTW32_INCLUDE_WINDOWS_H #include #endif /* * ----------------- * autoconf switches * ----------------- */ #if HAVE_CONFIG_H #include "config.h" #endif /* HAVE_CONFIG_H */ #if PTW32_LEVEL >= PTW32_LEVEL_MAX /* Try to avoid including windows.h */ #if defined(__MINGW32__) && defined(__cplusplus) /* * FIXME: The pthreadGCE.dll build gets linker unresolved errors * on pthread_key_create() unless windows.h is included here. * It appears to have something to do with an argument type mismatch. * Looking at tsd.o with 'nm' shows this line: * 00000000 T _pthread_key_create__FPP14pthread_key_t_PFPv_v * instead of * 00000000 T _pthread_key_create */ #define PTW32_INCLUDE_WINDOWS_H #endif #ifdef PTW32_INCLUDE_WINDOWS_H #include #endif #ifndef NEED_FTIME #include #else /* NEED_FTIME */ /* use native WIN32 time API */ #endif /* NEED_FTIME */ #if HAVE_SIGNAL_H #include #endif /* HAVE_SIGNAL_H */ #include #include /* * Boolean values to make us independent of system includes. */ enum { PTW32_FALSE = 0, PTW32_TRUE = (! PTW32_FALSE) }; /* * This is a duplicate of what is in the autoconf config.h, * which is only used when building the pthread-win32 libraries. */ #ifndef PTW32_CONFIG_H # if defined(WINCE) # define NEED_ERRNO # define NEED_SEM # endif # if defined(_UWIN) || defined(__MINGW32__) # define HAVE_MODE_T # endif #endif /* * */ #if PTW32_LEVEL >= PTW32_LEVEL_MAX #ifdef NEED_ERRNO #include "need_errno.h" #else #include #endif #endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ /* * Several systems don't define ENOTSUP. If not, we use * the same value as Solaris. */ #ifndef ENOTSUP # define ENOTSUP 48 #endif #ifndef ETIMEDOUT # define ETIMEDOUT 10060 /* This is the value in winsock.h. */ #endif #include /* * To avoid including windows.h we define only those things that we * actually need from it. I don't like the potential incompatibility that * this creates with future versions of windows. */ #ifndef PTW32_INCLUDE_WINDOWS_H #ifndef HANDLE # define PTW32__HANDLE_DEF # define HANDLE void * #endif #ifndef DWORD # define PTW32__DWORD_DEF # define DWORD unsigned long #endif #endif #endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ #ifndef HAVE_STRUCT_TIMESPEC struct timespec { long tv_sec; long tv_nsec; }; #endif /* HAVE_STRUCT_TIMESPEC */ #ifndef SIG_BLOCK #define SIG_BLOCK 0 #endif /* SIG_BLOCK */ #ifndef SIG_UNBLOCK #define SIG_UNBLOCK 1 #endif /* SIG_UNBLOCK */ #ifndef SIG_SETMASK #define SIG_SETMASK 2 #endif /* SIG_SETMASK */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* * ------------------------------------------------------------- * * POSIX 1003.1-2001 Options * ========================= * * _POSIX_THREADS (set) * If set, you can use threads * * _POSIX_THREAD_ATTR_STACKSIZE (set) * If set, you can control the size of a thread's * stack * pthread_attr_getstacksize * pthread_attr_setstacksize * * _POSIX_THREAD_ATTR_STACKADDR (not set) * If set, you can allocate and control a thread's * stack. If not supported, the following functions * will return ENOSYS, indicating they are not * supported: * pthread_attr_getstackaddr * pthread_attr_setstackaddr * * _POSIX_THREAD_PRIORITY_SCHEDULING (set) * If set, you can use realtime scheduling. * Indicates the availability of: * pthread_attr_getinheritsched * pthread_attr_getschedparam * pthread_attr_getschedpolicy * pthread_attr_getscope * pthread_attr_setinheritsched * pthread_attr_setschedparam * pthread_attr_setschedpolicy * pthread_attr_setscope * pthread_getschedparam * pthread_setschedparam * sched_get_priority_max * sched_get_priority_min * sched_rr_set_interval * * _POSIX_THREAD_PRIO_INHERIT (not set) * If set, you can create priority inheritance * mutexes. * pthread_mutexattr_getprotocol + * pthread_mutexattr_setprotocol + * * _POSIX_THREAD_PRIO_PROTECT (not set) * If set, you can create priority ceiling mutexes * Indicates the availability of: * pthread_mutex_getprioceiling * pthread_mutex_setprioceiling * pthread_mutexattr_getprioceiling * pthread_mutexattr_getprotocol + * pthread_mutexattr_setprioceiling * pthread_mutexattr_setprotocol + * * _POSIX_THREAD_PROCESS_SHARED (not set) * If set, you can create mutexes and condition * variables that can be shared with another * process.If set, indicates the availability * of: * pthread_mutexattr_getpshared * pthread_mutexattr_setpshared * pthread_condattr_getpshared * pthread_condattr_setpshared * * _POSIX_THREAD_SAFE_FUNCTIONS (set) * If set you can use the special *_r library * functions that provide thread-safe behaviour * * _POSIX_READER_WRITER_LOCKS (set) * If set, you can use read/write locks * * _POSIX_SPIN_LOCKS (set) * If set, you can use spin locks * * _POSIX_BARRIERS (set) * If set, you can use barriers * * + These functions provide both 'inherit' and/or * 'protect' protocol, based upon these macro * settings. * * POSIX 1003.1-2001 Limits * =========================== * * PTHREAD_DESTRUCTOR_ITERATIONS * Maximum number of attempts to destroy * a thread's thread-specific data on * termination (must be at least 4) * * PTHREAD_KEYS_MAX * Maximum number of thread-specific data keys * available per process (must be at least 128) * * PTHREAD_STACK_MIN * Minimum supported stack size for a thread * * PTHREAD_THREADS_MAX * Maximum number of threads supported per * process (must be at least 64). * * _POSIX_SEM_NSEMS_MAX * The maximum number of semaphores a process can have. * (only defined if not already defined) * * _POSIX_SEM_VALUE_MAX * The maximum value a semaphore can have. * (only defined if not already defined) * * ------------------------------------------------------------- */ /* * POSIX Options */ #ifndef _POSIX_THREADS #define _POSIX_THREADS #endif #ifndef _POSIX_READER_WRITER_LOCKS #define _POSIX_READER_WRITER_LOCKS #endif #ifndef _POSIX_SPIN_LOCKS #define _POSIX_SPIN_LOCKS #endif #ifndef _POSIX_BARRIERS #define _POSIX_BARRIERS #endif #define _POSIX_THREAD_SAFE_FUNCTIONS #define _POSIX_THREAD_ATTR_STACKSIZE #define _POSIX_THREAD_PRIORITY_SCHEDULING #if defined( KLUDGE ) /* * The following are not supported */ #define _POSIX_THREAD_ATTR_STACKADDR #define _POSIX_THREAD_PRIO_INHERIT #define _POSIX_THREAD_PRIO_PROTECT #define _POSIX_THREAD_PROCESS_SHARED #endif /* KLUDGE */ /* * POSIX Limits * * PTHREAD_DESTRUCTOR_ITERATIONS * Standard states this must be at least * 4. * * PTHREAD_KEYS_MAX * WIN32 permits only 64 TLS keys per process. * This limitation could be worked around by * simply simulating keys. * * PTHREADS_STACK_MIN * POSIX specifies 0 which is also the value WIN32 * interprets as allowing the system to * set the size to that of the main thread. The * maximum stack size in Win32 is 1Meg. WIN32 * allocates more stack as required up to the 1Meg * limit. * * PTHREAD_THREADS_MAX * Not documented by WIN32. Wrote a test program * that kept creating threads until it failed * revealed this approximate number (Windows NT). * This number is somewhat less for Windows 9x * and is effectively less than 64. Perhaps this * constant should be set at DLL load time. * */ #define PTHREAD_DESTRUCTOR_ITERATIONS 4 #define PTHREAD_KEYS_MAX 64 #define PTHREAD_STACK_MIN 0 #define PTHREAD_THREADS_MAX 2019 #ifndef _POSIX_SEM_NSEMS_MAX /* Not used and only an arbitrary value. */ # define _POSIX_SEM_NSEMS_MAX 1024 #endif #ifndef _POSIX_SEM_VALUE_MAX # define _POSIX_SEM_VALUE_MAX (INT_MAX/2) #endif #if __GNUC__ && ! defined (__declspec) # error Please upgrade your GNU compiler to one that supports __declspec. #endif /* * When building the DLL code, you should define PTW32_BUILD so that * the variables/functions are exported correctly. When using the DLL, * do NOT define PTW32_BUILD, and then the variables/functions will * be imported correctly. */ #ifdef _DLL # ifdef PTW32_BUILD # define PTW32_DLLPORT __declspec (dllexport) # else # define PTW32_DLLPORT __declspec (dllimport) # endif #endif #if defined(_UWIN) && PTW32_LEVEL >= PTW32_LEVEL_MAX # include #else typedef struct pthread_t_ *pthread_t; typedef struct pthread_attr_t_ *pthread_attr_t; typedef struct pthread_once_t_ pthread_once_t; typedef struct pthread_key_t_ *pthread_key_t; typedef struct pthread_mutex_t_ *pthread_mutex_t; typedef struct pthread_mutexattr_t_ *pthread_mutexattr_t; typedef struct pthread_cond_t_ *pthread_cond_t; typedef struct pthread_condattr_t_ *pthread_condattr_t; #endif typedef struct pthread_rwlock_t_ *pthread_rwlock_t; typedef struct pthread_rwlockattr_t_ *pthread_rwlockattr_t; typedef struct pthread_spinlock_t_ *pthread_spinlock_t; typedef struct pthread_barrier_t_ *pthread_barrier_t; typedef struct pthread_barrierattr_t_ *pthread_barrierattr_t; /* * ==================== * ==================== * POSIX Threads * ==================== * ==================== */ enum { /* * pthread_attr_{get,set}detachstate */ PTHREAD_CREATE_JOINABLE = 0, /* Default */ PTHREAD_CREATE_DETACHED = 1, /* * pthread_attr_{get,set}inheritsched */ PTHREAD_INHERIT_SCHED = 0, PTHREAD_EXPLICIT_SCHED = 1, /* Default */ /* * pthread_{get,set}scope */ PTHREAD_SCOPE_PROCESS = 0, PTHREAD_SCOPE_SYSTEM = 1, /* Default */ /* * pthread_setcancelstate paramters */ PTHREAD_CANCEL_ENABLE = 0, /* Default */ PTHREAD_CANCEL_DISABLE = 1, /* * pthread_setcanceltype parameters */ PTHREAD_CANCEL_ASYNCHRONOUS = 0, PTHREAD_CANCEL_DEFERRED = 1, /* Default */ /* * pthread_mutexattr_{get,set}pshared * pthread_condattr_{get,set}pshared */ PTHREAD_PROCESS_PRIVATE = 0, PTHREAD_PROCESS_SHARED = 1, /* * pthread_barrier_wait */ PTHREAD_BARRIER_SERIAL_THREAD = -1 }; /* * ==================== * ==================== * Cancelation * ==================== * ==================== */ #define PTHREAD_CANCELED ((void *) -1) /* * ==================== * ==================== * Once Key * ==================== * ==================== */ #define PTHREAD_ONCE_INIT { PTW32_FALSE, -1 } struct pthread_once_t_ { int done; /* indicates if user function executed */ long started; /* First thread to increment this value */ /* to zero executes the user function */ }; /* * ==================== * ==================== * Object initialisers * ==================== * ==================== */ #define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t) -1) #define PTHREAD_COND_INITIALIZER ((pthread_cond_t) -1) #define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t) -1) #define PTHREAD_SPINLOCK_INITIALIZER ((pthread_spinlock_t) -1) /* * Mutex types. */ enum { /* Compatibility with LinuxThreads */ PTHREAD_MUTEX_FAST_NP, PTHREAD_MUTEX_RECURSIVE_NP, PTHREAD_MUTEX_ERRORCHECK_NP, PTHREAD_MUTEX_TIMED_NP = PTHREAD_MUTEX_FAST_NP, PTHREAD_MUTEX_ADAPTIVE_NP = PTHREAD_MUTEX_FAST_NP, /* For compatibility with POSIX */ PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_FAST_NP, PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP, PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP, PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL }; /* There are three implementations of cancel cleanup. * Note that pthread.h is included in both application * compilation units and also internally for the library. * The code here and within the library aims to work * for all reasonable combinations of environments. * * The three implementations are: * * WIN32 SEH * C * C++ * * Please note that exiting a push/pop block via * "return", "exit", "break", or "continue" will * lead to different behaviour amongst applications * depending upon whether the library was built * using SEH, C++, or C. For example, a library built * with SEH will call the cleanup routine, while both * C++ and C built versions will not. */ /* * Define defaults for cleanup code. * Note: Unless the build explicitly defines one of the following, then * we default to standard C style cleanup. This style uses setjmp/longjmp * in the cancelation and thread exit implementations and therefore won't * do stack unwinding if linked to applications that have it (e.g. * C++ apps). This is currently consistent with most/all commercial Unix * POSIX threads implementations. */ #if !defined( __CLEANUP_SEH ) && !defined( __CLEANUP_CXX ) && !defined( __CLEANUP_C ) # define __CLEANUP_C #endif #if defined( __CLEANUP_SEH ) && defined(__GNUC__) #error ERROR [__FILE__, line __LINE__]: GNUC does not support SEH. #endif typedef struct ptw32_cleanup_t ptw32_cleanup_t; typedef void (__cdecl *ptw32_cleanup_callback_t)(void *); struct ptw32_cleanup_t { ptw32_cleanup_callback_t routine; void *arg; struct ptw32_cleanup_t *prev; }; #ifdef __CLEANUP_SEH /* * WIN32 SEH version of cancel cleanup. */ #define pthread_cleanup_push( _rout, _arg ) \ { \ ptw32_cleanup_t _cleanup; \ \ _cleanup.routine = (ptw32_cleanup_callback_t)(_rout); \ _cleanup.arg = (_arg); \ __try \ { \ #define pthread_cleanup_pop( _execute ) \ } \ __finally \ { \ if( _execute || AbnormalTermination()) \ { \ (*(_cleanup.routine))( _cleanup.arg ); \ } \ } \ } #else /* __CLEANUP_SEH */ #ifdef __CLEANUP_C /* * C implementation of PThreads cancel cleanup */ #define pthread_cleanup_push( _rout, _arg ) \ { \ ptw32_cleanup_t _cleanup; \ \ ptw32_push_cleanup( &_cleanup, (ptw32_cleanup_callback_t) (_rout), (_arg) ); \ #define pthread_cleanup_pop( _execute ) \ (void) ptw32_pop_cleanup( _execute ); \ } #else /* __CLEANUP_C */ #ifdef __CLEANUP_CXX /* * C++ version of cancel cleanup. * - John E. Bossom. */ class PThreadCleanup { /* * PThreadCleanup * * Purpose * This class is a C++ helper class that is * used to implement pthread_cleanup_push/ * pthread_cleanup_pop. * The destructor of this class automatically * pops the pushed cleanup routine regardless * of how the code exits the scope * (i.e. such as by an exception) */ ptw32_cleanup_callback_t cleanUpRout; void * obj; int executeIt; public: PThreadCleanup() : cleanUpRout( 0 ), obj( 0 ), executeIt( 0 ) /* * No cleanup performed */ { } PThreadCleanup( ptw32_cleanup_callback_t routine, void * arg ) : cleanUpRout( routine ), obj( arg ), executeIt( 1 ) /* * Registers a cleanup routine for 'arg' */ { } ~PThreadCleanup() { if ( executeIt && ((void *) cleanUpRout != (void *) 0) ) { (void) (*cleanUpRout)( obj ); } } void execute( int exec ) { executeIt = exec; } }; /* * C++ implementation of PThreads cancel cleanup; * This implementation takes advantage of a helper * class who's destructor automatically calls the * cleanup routine if we exit our scope weirdly */ #define pthread_cleanup_push( _rout, _arg ) \ { \ PThreadCleanup cleanup((ptw32_cleanup_callback_t)(_rout), \ (void *) (_arg) ); #define pthread_cleanup_pop( _execute ) \ cleanup.execute( _execute ); \ } #else #error ERROR [__FILE__, line __LINE__]: Cleanup type undefined. #endif /* __CLEANUP_CXX */ #endif /* __CLEANUP_C */ #endif /* __CLEANUP_SEH */ /* * =============== * =============== * Methods * =============== * =============== */ /* * PThread Attribute Functions */ PTW32_DLLPORT int pthread_attr_init (pthread_attr_t * attr); PTW32_DLLPORT int pthread_attr_destroy (pthread_attr_t * attr); PTW32_DLLPORT int pthread_attr_getdetachstate (const pthread_attr_t * attr, int *detachstate); PTW32_DLLPORT int pthread_attr_getstackaddr (const pthread_attr_t * attr, void **stackaddr); PTW32_DLLPORT int pthread_attr_getstacksize (const pthread_attr_t * attr, size_t * stacksize); PTW32_DLLPORT int pthread_attr_setdetachstate (pthread_attr_t * attr, int detachstate); PTW32_DLLPORT int pthread_attr_setstackaddr (pthread_attr_t * attr, void *stackaddr); PTW32_DLLPORT int pthread_attr_setstacksize (pthread_attr_t * attr, size_t stacksize); PTW32_DLLPORT int pthread_attr_getschedparam (const pthread_attr_t *attr, struct sched_param *param); PTW32_DLLPORT int pthread_attr_setschedparam (pthread_attr_t *attr, const struct sched_param *param); PTW32_DLLPORT int pthread_attr_setschedpolicy (pthread_attr_t *, int); PTW32_DLLPORT int pthread_attr_getschedpolicy (pthread_attr_t *, int *); PTW32_DLLPORT int pthread_attr_setinheritsched(pthread_attr_t * attr, int inheritsched); PTW32_DLLPORT int pthread_attr_getinheritsched(pthread_attr_t * attr, int * inheritsched); PTW32_DLLPORT int pthread_attr_setscope (pthread_attr_t *, int); PTW32_DLLPORT int pthread_attr_getscope (const pthread_attr_t *, int *); /* * PThread Functions */ PTW32_DLLPORT int pthread_create (pthread_t * tid, const pthread_attr_t * attr, void *(*start) (void *), void *arg); PTW32_DLLPORT int pthread_detach (pthread_t tid); PTW32_DLLPORT int pthread_equal (pthread_t t1, pthread_t t2); PTW32_DLLPORT void pthread_exit (void *value_ptr); PTW32_DLLPORT int pthread_join (pthread_t thread, void **value_ptr); PTW32_DLLPORT pthread_t pthread_self (void); PTW32_DLLPORT int pthread_cancel (pthread_t thread); PTW32_DLLPORT int pthread_setcancelstate (int state, int *oldstate); PTW32_DLLPORT int pthread_setcanceltype (int type, int *oldtype); PTW32_DLLPORT void pthread_testcancel (void); PTW32_DLLPORT int pthread_once (pthread_once_t * once_control, void (*init_routine) (void)); #if PTW32_LEVEL >= PTW32_LEVEL_MAX PTW32_DLLPORT ptw32_cleanup_t *ptw32_pop_cleanup (int execute); PTW32_DLLPORT void ptw32_push_cleanup (ptw32_cleanup_t * cleanup, void (*routine) (void *), void *arg); #endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ /* * Thread Specific Data Functions */ PTW32_DLLPORT int pthread_key_create (pthread_key_t * key, void (*destructor) (void *)); PTW32_DLLPORT int pthread_key_delete (pthread_key_t key); PTW32_DLLPORT int pthread_setspecific (pthread_key_t key, const void *value); PTW32_DLLPORT void *pthread_getspecific (pthread_key_t key); /* * Mutex Attribute Functions */ PTW32_DLLPORT int pthread_mutexattr_init (pthread_mutexattr_t * attr); PTW32_DLLPORT int pthread_mutexattr_destroy (pthread_mutexattr_t * attr); PTW32_DLLPORT int pthread_mutexattr_getpshared (const pthread_mutexattr_t * attr, int *pshared); PTW32_DLLPORT int pthread_mutexattr_setpshared (pthread_mutexattr_t * attr, int pshared); PTW32_DLLPORT int pthread_mutexattr_settype (pthread_mutexattr_t * attr, int kind); PTW32_DLLPORT int pthread_mutexattr_gettype (pthread_mutexattr_t * attr, int *kind); /* * Barrier Attribute Functions */ PTW32_DLLPORT int pthread_barrierattr_init (pthread_barrierattr_t * attr); PTW32_DLLPORT int pthread_barrierattr_destroy (pthread_barrierattr_t * attr); PTW32_DLLPORT int pthread_barrierattr_getpshared (const pthread_barrierattr_t * attr, int *pshared); PTW32_DLLPORT int pthread_barrierattr_setpshared (pthread_barrierattr_t * attr, int pshared); /* * Mutex Functions */ PTW32_DLLPORT int pthread_mutex_init (pthread_mutex_t * mutex, const pthread_mutexattr_t * attr); PTW32_DLLPORT int pthread_mutex_destroy (pthread_mutex_t * mutex); PTW32_DLLPORT int pthread_mutex_lock (pthread_mutex_t * mutex); PTW32_DLLPORT int pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *abstime); PTW32_DLLPORT int pthread_mutex_trylock (pthread_mutex_t * mutex); PTW32_DLLPORT int pthread_mutex_unlock (pthread_mutex_t * mutex); /* * Spinlock Functions */ PTW32_DLLPORT int pthread_spin_init (pthread_spinlock_t * lock, int pshared); PTW32_DLLPORT int pthread_spin_destroy (pthread_spinlock_t * lock); PTW32_DLLPORT int pthread_spin_lock (pthread_spinlock_t * lock); PTW32_DLLPORT int pthread_spin_trylock (pthread_spinlock_t * lock); PTW32_DLLPORT int pthread_spin_unlock (pthread_spinlock_t * lock); /* * Barrier Functions */ PTW32_DLLPORT int pthread_barrier_init (pthread_barrier_t * barrier, const pthread_barrierattr_t * attr, unsigned int count); PTW32_DLLPORT int pthread_barrier_destroy (pthread_barrier_t * barrier); PTW32_DLLPORT int pthread_barrier_wait (pthread_barrier_t * barrier); /* * Condition Variable Attribute Functions */ PTW32_DLLPORT int pthread_condattr_init (pthread_condattr_t * attr); PTW32_DLLPORT int pthread_condattr_destroy (pthread_condattr_t * attr); PTW32_DLLPORT int pthread_condattr_getpshared (const pthread_condattr_t * attr, int *pshared); PTW32_DLLPORT int pthread_condattr_setpshared (pthread_condattr_t * attr, int pshared); /* * Condition Variable Functions */ PTW32_DLLPORT int pthread_cond_init (pthread_cond_t * cond, const pthread_condattr_t * attr); PTW32_DLLPORT int pthread_cond_destroy (pthread_cond_t * cond); PTW32_DLLPORT int pthread_cond_wait (pthread_cond_t * cond, pthread_mutex_t * mutex); PTW32_DLLPORT int pthread_cond_timedwait (pthread_cond_t * cond, pthread_mutex_t * mutex, const struct timespec *abstime); PTW32_DLLPORT int pthread_cond_signal (pthread_cond_t * cond); PTW32_DLLPORT int pthread_cond_broadcast (pthread_cond_t * cond); /* * Scheduling */ PTW32_DLLPORT int pthread_setschedparam (pthread_t thread, int policy, const struct sched_param *param); PTW32_DLLPORT int pthread_getschedparam (pthread_t thread, int *policy, struct sched_param *param); PTW32_DLLPORT int pthread_setconcurrency (int); PTW32_DLLPORT int pthread_getconcurrency (void); /* * Read-Write Lock Functions */ PTW32_DLLPORT int pthread_rwlock_init(pthread_rwlock_t *lock, const pthread_rwlockattr_t *attr); PTW32_DLLPORT int pthread_rwlock_destroy(pthread_rwlock_t *lock); PTW32_DLLPORT int pthread_rwlock_tryrdlock(pthread_rwlock_t *); PTW32_DLLPORT int pthread_rwlock_trywrlock(pthread_rwlock_t *); PTW32_DLLPORT int pthread_rwlock_rdlock(pthread_rwlock_t *lock); PTW32_DLLPORT int pthread_rwlock_timedrdlock(pthread_rwlock_t *lock, const struct timespec *abstime); PTW32_DLLPORT int pthread_rwlock_wrlock(pthread_rwlock_t *lock); PTW32_DLLPORT int pthread_rwlock_timedwrlock(pthread_rwlock_t *lock, const struct timespec *abstime); PTW32_DLLPORT int pthread_rwlock_unlock(pthread_rwlock_t *lock); PTW32_DLLPORT int pthread_rwlockattr_init (pthread_rwlockattr_t * attr); PTW32_DLLPORT int pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr); PTW32_DLLPORT int pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr, int *pshared); PTW32_DLLPORT int pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr, int pshared); #if PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 /* * Signal Functions. Should be defined in but MSVC and MinGW32 * already have signal.h that don't define these. */ PTW32_DLLPORT int pthread_kill(pthread_t thread, int sig); /* * Non-portable functions */ /* * Compatibility with Linux. */ PTW32_DLLPORT int pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr, int kind); PTW32_DLLPORT int pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr, int *kind); /* * Possibly supported by other POSIX threads implementations */ PTW32_DLLPORT int pthread_delay_np (struct timespec * interval); PTW32_DLLPORT int pthread_num_processors_np(void); /* * Useful if an application wants to statically link * the lib rather than load the DLL at run-time. */ PTW32_DLLPORT int pthread_win32_process_attach_np(void); PTW32_DLLPORT int pthread_win32_process_detach_np(void); PTW32_DLLPORT int pthread_win32_thread_attach_np(void); PTW32_DLLPORT int pthread_win32_thread_detach_np(void); /* * Register a system time change with the library. * Causes the library to perform various functions * in response to the change. Should be called whenever * the application's top level window receives a * WM_TIMECHANGE message. It can be passed directly to * pthread_create() as a new thread if desired. */ PTW32_DLLPORT void * pthread_timechange_handler_np(void *); #endif /*PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 */ #if PTW32_LEVEL >= PTW32_LEVEL_MAX /* * Returns the Win32 HANDLE for the POSIX thread. */ PTW32_DLLPORT HANDLE pthread_getw32threadhandle_np(pthread_t thread); /* * Protected Methods * * This function blocks until the given WIN32 handle * is signaled or pthread_cancel had been called. * This function allows the caller to hook into the * PThreads cancel mechanism. It is implemented using * * WaitForMultipleObjects * * on 'waitHandle' and a manually reset WIN32 Event * used to implement pthread_cancel. The 'timeout' * argument to TimedWait is simply passed to * WaitForMultipleObjects. */ PTW32_DLLPORT int pthreadCancelableWait (HANDLE waitHandle); PTW32_DLLPORT int pthreadCancelableTimedWait (HANDLE waitHandle, DWORD timeout); #endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ /* * Thread-Safe C Runtime Library Mappings. */ #ifndef _UWIN # if defined(NEED_ERRNO) PTW32_DLLPORT int * _errno( void ); # else # ifndef errno # if (defined(_MT) || defined(_DLL)) __declspec(dllimport) extern int * __cdecl _errno(void); # define errno (*_errno()) # endif # endif # endif #endif /* * WIN32 C runtime library had been made thread-safe * without affecting the user interface. Provide * mappings from the UNIX thread-safe versions to * the standard C runtime library calls. * Only provide function mappings for functions that * actually exist on WIN32. */ #if !defined(__MINGW32__) //we have our own implementation of strtok_r that gets linked into Snort //#define strtok_r( _s, _sep, _lasts ) \ // ( *(_lasts) = strtok( (_s), (_sep) ) ) #endif /* !__MINGW32__ */ #define asctime_r( _tm, _buf ) \ ( strcpy( (_buf), asctime( (_tm) ) ), \ (_buf) ) #define ctime_r( _clock, _buf ) \ ( strcpy( (_buf), ctime( (_clock) ) ), \ (_buf) ) #define gmtime_r( _clock, _result ) \ ( *(_result) = *gmtime( (_clock) ), \ (_result) ) #define localtime_r( _clock, _result ) \ ( *(_result) = *localtime( (_clock) ), \ (_result) ) #define rand_r( _seed ) \ ( _seed == _seed? rand() : rand() ) #ifdef __cplusplus /* * Internal exceptions */ class ptw32_exception {}; class ptw32_exception_cancel : public ptw32_exception {}; class ptw32_exception_exit : public ptw32_exception {}; #endif #if PTW32_LEVEL >= PTW32_LEVEL_MAX /* FIXME: This is only required if the library was built using SEH */ /* * Get internal SEH tag */ PTW32_DLLPORT DWORD ptw32_get_exception_services_code(void); #endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ #ifndef PTW32_BUILD #ifdef __CLEANUP_SEH /* * Redefine the SEH __except keyword to ensure that applications * propagate our internal exceptions up to the library's internal handlers. */ #define __except( E ) \ __except( ( GetExceptionCode() == ptw32_get_exception_services_code() ) \ ? EXCEPTION_CONTINUE_SEARCH : ( E ) ) #endif /* __CLEANUP_SEH */ #ifdef __CLEANUP_CXX /* * Redefine the C++ catch keyword to ensure that applications * propagate our internal exceptions up to the library's internal handlers. */ #ifdef _MSC_VER /* * WARNING: Replace any 'catch( ... )' with 'PtW32CatchAll' * if you want Pthread-Win32 cancelation and pthread_exit to work. */ #ifndef PtW32NoCatchWarn #pragma message("Specify \"/DPtW32NoCatchWarn\" compiler flag to skip this message.") #pragma message("------------------------------------------------------------------") #pragma message("When compiling applications with MSVC++ and C++ exception handling:") #pragma message(" Replace any 'catch( ... )' in routines called from POSIX threads") #pragma message(" with 'PtW32CatchAll' or 'CATCHALL' if you want POSIX thread") #pragma message(" cancelation and pthread_exit to work. For example:") #pragma message("") #pragma message(" #ifdef PtW32CatchAll") #pragma message(" PtW32CatchAll") #pragma message(" #else") #pragma message(" catch(...)") #pragma message(" #endif") #pragma message(" {") #pragma message(" /* Catchall block processing */") #pragma message(" }") #pragma message("------------------------------------------------------------------") #endif #define PtW32CatchAll \ catch( ptw32_exception & ) { throw; } \ catch( ... ) #else /* _MSC_VER */ #define catch( E ) \ catch( ptw32_exception & ) { throw; } \ catch( E ) #endif /* _MSC_VER */ #endif /* __CLEANUP_CXX */ #endif /* ! PTW32_BUILD */ #ifdef __cplusplus } /* End of extern "C" */ #endif /* __cplusplus */ #ifdef PTW32__HANDLE_DEF # undef HANDLE #endif #ifdef PTW32__DWORD_DEF # undef DWORD #endif #undef PTW32_LEVEL #undef PTW32_LEVEL_MAX #endif /* PTHREAD_H */ snort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/remote-ext.h0000644000175200017520000003514113571422610017610 00000000000000/* * Copyright (c) 2002 - 2003 * NetGroup, Politecnico di Torino (Italy) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Politecnico di Torino nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef __REMOTE_EXT_H__ #define __REMOTE_EXT_H__ #ifndef HAVE_REMOTE #error Please do not include this file directly. Just define HAVE_REMOTE and then include pcap.h #endif // Definition for Microsoft Visual Studio #if _MSC_VER > 1000 #pragma once #endif #ifdef __cplusplus extern "C" { #endif /*! \file remote-ext.h The goal of this file it to include most of the new definitions that should be placed into the pcap.h file. It includes all new definitions (structures and functions like pcap_open(). Some of the functions are not really a remote feature, but, right now, they are placed here. */ // All this stuff is public /*! \addtogroup remote_struct \{ */ /*! \brief Defines the maximum buffer size in which address, port, interface names are kept. In case the adapter name or such is larger than this value, it is truncated. This is not used by the user; however it must be aware that an hostname / interface name longer than this value will be truncated. */ #define PCAP_BUF_SIZE 1024 /*! \addtogroup remote_source_ID \{ */ /*! \brief Internal representation of the type of source in use (file, remote/local interface). This indicates a file, i.e. the user want to open a capture from a local file. */ #define PCAP_SRC_FILE 2 /*! \brief Internal representation of the type of source in use (file, remote/local interface). This indicates a local interface, i.e. the user want to open a capture from a local interface. This does not involve the RPCAP protocol. */ #define PCAP_SRC_IFLOCAL 3 /*! \brief Internal representation of the type of source in use (file, remote/local interface). This indicates a remote interface, i.e. the user want to open a capture from an interface on a remote host. This does involve the RPCAP protocol. */ #define PCAP_SRC_IFREMOTE 4 /*! \} */ /*! \addtogroup remote_source_string The formats allowed by the pcap_open() are the following: - file://path_and_filename [opens a local file] - rpcap://devicename [opens the selected device devices available on the local host, without using the RPCAP protocol] - rpcap://host/devicename [opens the selected device available on a remote host] - rpcap://host:port/devicename [opens the selected device available on a remote host, using a non-standard port for RPCAP] - adaptername [to open a local adapter; kept for compability, but it is strongly discouraged] - (NULL) [to open the first local adapter; kept for compability, but it is strongly discouraged] The formats allowed by the pcap_findalldevs_ex() are the following: - file://folder/ [lists all the files in the given folder] - rpcap:// [lists all local adapters] - rpcap://host:port/ [lists the devices available on a remote host] Referring to the 'host' and 'port' paramters, they can be either numeric or literal. Since IPv6 is fully supported, these are the allowed formats: - host (literal): e.g. host.foo.bar - host (numeric IPv4): e.g. 10.11.12.13 - host (numeric IPv4, IPv6 style): e.g. [10.11.12.13] - host (numeric IPv6): e.g. [1:2:3::4] - port: can be either numeric (e.g. '80') or literal (e.g. 'http') Here you find some allowed examples: - rpcap://host.foo.bar/devicename [everything literal, no port number] - rpcap://host.foo.bar:1234/devicename [everything literal, with port number] - rpcap://10.11.12.13/devicename [IPv4 numeric, no port number] - rpcap://10.11.12.13:1234/devicename [IPv4 numeric, with port number] - rpcap://[10.11.12.13]:1234/devicename [IPv4 numeric with IPv6 format, with port number] - rpcap://[1:2:3::4]/devicename [IPv6 numeric, no port number] - rpcap://[1:2:3::4]:1234/devicename [IPv6 numeric, with port number] - rpcap://[1:2:3::4]:http/devicename [IPv6 numeric, with literal port number] \{ */ /*! \brief String that will be used to determine the type of source in use (file, remote/local interface). This string will be prepended to the interface name in order to create a string that contains all the information required to open the source. This string indicates that the user wants to open a capture from a local file. */ #define PCAP_SRC_FILE_STRING "file://" /*! \brief String that will be used to determine the type of source in use (file, remote/local interface). This string will be prepended to the interface name in order to create a string that contains all the information required to open the source. This string indicates that the user wants to open a capture from a network interface. This string does not necessarily involve the use of the RPCAP protocol. If the interface required resides on the local host, the RPCAP protocol is not involved and the local functions are used. */ #define PCAP_SRC_IF_STRING "rpcap://" /*! \} */ /*! \addtogroup remote_open_flags \{ */ /*! \brief Defines if the adapter has to go in promiscuous mode. It is '1' if you have to open the adapter in promiscuous mode, '0' otherwise. Note that even if this parameter is false, the interface could well be in promiscuous mode for some other reason (for example because another capture process with promiscuous mode enabled is currently using that interface). On on Linux systems with 2.2 or later kernels (that have the "any" device), this flag does not work on the "any" device; if an argument of "any" is supplied, the 'promisc' flag is ignored. */ #define PCAP_OPENFLAG_PROMISCUOUS 1 /*! \brief Defines if the data trasfer (in case of a remote capture) has to be done with UDP protocol. If it is '1' if you want a UDP data connection, '0' if you want a TCP data connection; control connection is always TCP-based. A UDP connection is much lighter, but it does not guarantee that all the captured packets arrive to the client workstation. Moreover, it could be harmful in case of network congestion. This flag is meaningless if the source is not a remote interface. In that case, it is simply ignored. */ #define PCAP_OPENFLAG_DATATX_UDP 2 /*! \brief Defines if the remote probe will capture its own generated traffic. In case the remote probe uses the same interface to capture traffic and to send data back to the caller, the captured traffic includes the RPCAP traffic as well. If this flag is turned on, the RPCAP traffic is excluded from the capture, so that the trace returned back to the collector is does not include this traffic. */ #define PCAP_OPENFLAG_NOCAPTURE_RPCAP 4 /*! \brief Defines if the local adapter will capture its own generated traffic. This flag tells the underlying capture driver to drop the packets that were sent by itself. This is usefult when building applications like bridges, that should ignore the traffic they just sent. */ #define PCAP_OPENFLAG_NOCAPTURE_LOCAL 8 /*! \brief This flag configures the adapter for maximum responsiveness. In presence of a large value for nbytes, WinPcap waits for the arrival of several packets before copying the data to the user. This guarantees a low number of system calls, i.e. lower processor usage, i.e. better performance, which is good for applications like sniffers. If the user sets the PCAP_OPENFLAG_MAX_RESPONSIVENESS flag, the capture driver will copy the packets as soon as the application is ready to receive them. This is suggested for real time applications (like, for example, a bridge) that need the best responsiveness.*/ #define PCAP_OPENFLAG_MAX_RESPONSIVENESS 16 /*! \} */ /*! \addtogroup remote_samp_methods \{ */ /*! \brief No sampling has to be done on the current capture. In this case, no sampling algorithms are applied to the current capture. */ #define PCAP_SAMP_NOSAMP 0 /*! \brief It defines that only 1 out of N packets must be returned to the user. In this case, the 'value' field of the 'pcap_samp' structure indicates the number of packets (minus 1) that must be discarded before one packet got accepted. In other words, if 'value = 10', the first packet is returned to the caller, while the following 9 are discarded. */ #define PCAP_SAMP_1_EVERY_N 1 /*! \brief It defines that we have to return 1 packet every N milliseconds. In this case, the 'value' field of the 'pcap_samp' structure indicates the 'waiting time' in milliseconds before one packet got accepted. In other words, if 'value = 10', the first packet is returned to the caller; the next returned one will be the first packet that arrives when 10ms have elapsed. */ #define PCAP_SAMP_FIRST_AFTER_N_MS 2 /*! \} */ /*! \addtogroup remote_auth_methods \{ */ /*! \brief It defines the NULL authentication. This value has to be used within the 'type' member of the pcap_rmtauth structure. The 'NULL' authentication has to be equal to 'zero', so that old applications can just put every field of struct pcap_rmtauth to zero, and it does work. */ #define RPCAP_RMTAUTH_NULL 0 /*! \brief It defines the username/password authentication. With this type of authentication, the RPCAP protocol will use the username/ password provided to authenticate the user on the remote machine. If the authentication is successful (and the user has the right to open network devices) the RPCAP connection will continue; otherwise it will be dropped. This value has to be used within the 'type' member of the pcap_rmtauth structure. */ #define RPCAP_RMTAUTH_PWD 1 /*! \} */ /*! \brief This structure keeps the information needed to autheticate the user on a remote machine. The remote machine can either grant or refuse the access according to the information provided. In case the NULL authentication is required, both 'username' and 'password' can be NULL pointers. This structure is meaningless if the source is not a remote interface; in that case, the functions which requires such a structure can accept a NULL pointer as well. */ struct pcap_rmtauth { /*! \brief Type of the authentication required. In order to provide maximum flexibility, we can support different types of authentication based on the value of this 'type' variable. The currently supported authentication methods are defined into the \link remote_auth_methods Remote Authentication Methods Section\endlink. */ int type; /*! \brief Zero-terminated string containing the username that has to be used on the remote machine for authentication. This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication and it can be NULL. */ char *username; /*! \brief Zero-terminated string containing the password that has to be used on the remote machine for authentication. This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication and it can be NULL. */ char *password; }; /*! \brief This structure defines the information related to sampling. In case the sampling is requested, the capturing device should read only a subset of the packets coming from the source. The returned packets depend on the sampling parameters. \warning The sampling process is applied after the filtering process. In other words, packets are filtered first, then the sampling process selects a subset of the 'filtered' packets and it returns them to the caller. */ struct pcap_samp { /*! Method used for sampling. Currently, the supported methods are listed in the \link remote_samp_methods Sampling Methods Section\endlink. */ int method; /*! This value depends on the sampling method defined. For its meaning, please check at the \link remote_samp_methods Sampling Methods Section\endlink. */ int value; }; //! Maximum lenght of an host name (needed for the RPCAP active mode) #define RPCAP_HOSTLIST_SIZE 1024 /*! \} */ // end of public documentation // Exported functions /** \name New WinPcap functions This section lists the new functions that are able to help considerably in writing WinPcap programs because of their easiness of use. */ //\{ pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout, struct pcap_rmtauth *auth, char *errbuf); int pcap_createsrcstr(char *source, int type, const char *host, const char *port, const char *name, char *errbuf); int pcap_parsesrcstr(const char *source, int *type, char *host, char *port, char *name, char *errbuf); int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf); struct pcap_samp *pcap_setsampling(pcap_t *p); //\} // End of new winpcap functions /** \name Remote Capture functions */ //\{ SOCKET pcap_remoteact_accept(const char *address, const char *port, const char *hostlist, char *connectinghost, struct pcap_rmtauth *auth, char *errbuf); int pcap_remoteact_list(char *hostlist, char sep, int size, char *errbuf); int pcap_remoteact_close(const char *host, char *errbuf); void pcap_remoteact_cleanup(); //\} // End of remote capture functions #ifdef __cplusplus } #endif #endif snort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/sched.h0000644000175200017520000001117313571422610016604 00000000000000/* * Module: sched.h * * Purpose: * Provides an implementation of POSIX realtime extensions * as defined in * * POSIX 1003.1b-1993 (POSIX.1b) * * -------------------------------------------------------------------------- * * Pthreads-win32 - POSIX Threads Library for Win32 * Copyright(C) 1998 John E. Bossom * Copyright(C) 1999,2003 Pthreads-win32 contributors * * Contact Email: rpj@callisto.canberra.edu.au * * The current list of contributors is contained * in the file CONTRIBUTORS included with the source * code distribution. The list can also be seen at the * following World Wide Web location: * http://sources.redhat.com/pthreads-win32/contributors.html * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library in the file COPYING.LIB; * if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef _SCHED_H #define _SCHED_H #undef PTW32_LEVEL #if defined(_POSIX_SOURCE) #define PTW32_LEVEL 0 /* Early POSIX */ #endif #if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 #undef PTW32_LEVEL #define PTW32_LEVEL 1 /* Include 1b, 1c and 1d */ #endif #if defined(INCLUDE_NP) #undef PTW32_LEVEL #define PTW32_LEVEL 2 /* Include Non-Portable extensions */ #endif #define PTW32_LEVEL_MAX 3 #if !defined(PTW32_LEVEL) #define PTW32_LEVEL PTW32_LEVEL_MAX /* Include everything */ #endif #if __GNUC__ && ! defined (__declspec) # error Please upgrade your GNU compiler to one that supports __declspec. #endif /* * When building the DLL code, you should define PTW32_BUILD so that * the variables/functions are exported correctly. When using the DLL, * do NOT define PTW32_BUILD, and then the variables/functions will * be imported correctly. */ #ifdef PTW32_BUILD # define PTW32_DLLPORT __declspec (dllexport) #else # define PTW32_DLLPORT __declspec (dllimport) #endif /* * This is a duplicate of what is in the autoconf config.h, * which is only used when building the pthread-win32 libraries. */ #ifndef PTW32_CONFIG_H # if defined(WINCE) # define NEED_ERRNO # define NEED_SEM # endif # if defined(_UWIN) || defined(__MINGW32__) # define HAVE_MODE_T # endif #endif /* * */ #if PTW32_LEVEL >= PTW32_LEVEL_MAX #ifdef NEED_ERRNO #include "need_errno.h" #else #include #endif #endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ #if defined(__MINGW32__) || defined(_UWIN) #if PTW32_LEVEL >= PTW32_LEVEL_MAX /* For pid_t */ # include /* Required by Unix 98 */ # include #endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ #else typedef int pid_t; #endif /* Thread scheduling policies */ enum { SCHED_OTHER = 0, SCHED_FIFO, SCHED_RR, SCHED_MIN = SCHED_OTHER, SCHED_MAX = SCHED_RR }; struct sched_param { int sched_priority; }; #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ PTW32_DLLPORT int sched_yield (void); PTW32_DLLPORT int sched_get_priority_min (int policy); PTW32_DLLPORT int sched_get_priority_max (int policy); PTW32_DLLPORT int sched_setscheduler (pid_t pid, int policy); PTW32_DLLPORT int sched_getscheduler (pid_t pid); /* * Note that this macro returns ENOTSUP rather than * ENOSYS as might be expected. However, returning ENOSYS * should mean that sched_get_priority_{min,max} are * not implemented as well as sched_rr_get_interval. * This is not the case, since we just don't support * round-robin scheduling. Therefore I have chosen to * return the same value as sched_setscheduler when * SCHED_RR is passed to it. */ #define sched_rr_get_interval(_pid, _interval) \ ( errno = ENOTSUP, (int) -1 ) #ifdef __cplusplus } /* End of extern "C" */ #endif /* __cplusplus */ #undef PTW32_LEVEL #undef PTW32_LEVEL_MAX #endif /* !_SCHED_H */ snort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/semaphore.h0000644000175200017520000001025613571422610017502 00000000000000/* * Module: semaphore.h * * Purpose: * Semaphores aren't actually part of the PThreads standard. * They are defined by the POSIX Standard: * * POSIX 1003.1b-1993 (POSIX.1b) * * -------------------------------------------------------------------------- * * Pthreads-win32 - POSIX Threads Library for Win32 * Copyright(C) 1998 John E. Bossom * Copyright(C) 1999,2003 Pthreads-win32 contributors * * Contact Email: rpj@callisto.canberra.edu.au * * The current list of contributors is contained * in the file CONTRIBUTORS included with the source * code distribution. The list can also be seen at the * following World Wide Web location: * http://sources.redhat.com/pthreads-win32/contributors.html * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library in the file COPYING.LIB; * if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #if !defined( SEMAPHORE_H ) #define SEMAPHORE_H #undef PTW32_LEVEL #if defined(_POSIX_SOURCE) #define PTW32_LEVEL 0 /* Early POSIX */ #endif #if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 #undef PTW32_LEVEL #define PTW32_LEVEL 1 /* Include 1b, 1c and 1d */ #endif #if defined(INCLUDE_NP) #undef PTW32_LEVEL #define PTW32_LEVEL 2 /* Include Non-Portable extensions */ #endif #define PTW32_LEVEL_MAX 3 #if !defined(PTW32_LEVEL) #define PTW32_LEVEL PTW32_LEVEL_MAX /* Include everything */ #endif #if __GNUC__ && ! defined (__declspec) # error Please upgrade your GNU compiler to one that supports __declspec. #endif /* * When building the DLL code, you should define PTW32_BUILD so that * the variables/functions are exported correctly. When using the DLL, * do NOT define PTW32_BUILD, and then the variables/functions will * be imported correctly. */ #ifdef PTW32_BUILD # define PTW32_DLLPORT __declspec (dllexport) #else # define PTW32_DLLPORT __declspec (dllimport) #endif /* * This is a duplicate of what is in the autoconf config.h, * which is only used when building the pthread-win32 libraries. */ #ifndef PTW32_CONFIG_H # if defined(WINCE) # define NEED_ERRNO # define NEED_SEM # endif # if defined(_UWIN) || defined(__MINGW32__) # define HAVE_MODE_T # endif #endif /* * */ #if PTW32_LEVEL >= PTW32_LEVEL_MAX #ifdef NEED_ERRNO #include "need_errno.h" #else #include #endif #endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ #define _POSIX_SEMAPHORES #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #ifndef HAVE_MODE_T typedef unsigned int mode_t; #endif typedef struct sem_t_ * sem_t; PTW32_DLLPORT int sem_init (sem_t * sem, int pshared, unsigned int value); PTW32_DLLPORT int sem_destroy (sem_t * sem); PTW32_DLLPORT int sem_trywait (sem_t * sem); PTW32_DLLPORT int sem_wait (sem_t * sem); PTW32_DLLPORT int sem_timedwait (sem_t * sem, const struct timespec * abstime); PTW32_DLLPORT int sem_post (sem_t * sem); PTW32_DLLPORT int sem_post_multiple (sem_t * sem, int count); PTW32_DLLPORT int sem_open (const char * name, int oflag, mode_t mode, unsigned int value); PTW32_DLLPORT int sem_close (sem_t * sem); PTW32_DLLPORT int sem_unlink (const char * name); PTW32_DLLPORT int sem_getvalue (sem_t * sem, int * sval); #ifdef __cplusplus } /* End of extern "C" */ #endif /* __cplusplus */ #undef PTW32_LEVEL #undef PTW32_LEVEL_MAX #endif /* !SEMAPHORE_H */ snort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/tcp_session.h0000644000175200017520000000563113571422610020051 00000000000000/* * Copyright (c) 2001 - 2003 * NetGroup, Politecnico di Torino (Italy) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Politecnico di Torino nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef __tcp_session #define __tcp_session #ifdef WIN32 #include "tme.h" #endif #ifdef __FreeBSD__ #ifdef _KERNEL #include #else #include #endif #endif #define UNKNOWN 0 #define SYN_RCV 1 #define SYN_ACK_RCV 2 #define ESTABLISHED 3 #define CLOSED_RST 4 #define FIN_CLN_RCV 5 #define FIN_SRV_RCV 6 #define CLOSED_FIN 7 #define ERROR_TCP 8 #define FIRST_IS_CLN 0 #define FIRST_IS_SRV 0xffffffff #define FIN_CLN 1 #define FIN_SRV 2 #define MAX_WINDOW 65536 typedef struct __tcp_data { struct timeval timestamp_block; /*DO NOT MOVE THIS VALUE*/ struct timeval syn_timestamp; struct timeval last_timestamp; struct timeval syn_ack_timestamp; uint32 direction; uint32 seq_n_0_srv; uint32 seq_n_0_cln; uint32 ack_srv; /* acknowledge of (data sent by server) */ uint32 ack_cln; /* acknowledge of (data sent by client) */ uint32 status; uint32 pkts_cln_to_srv; uint32 pkts_srv_to_cln; uint32 bytes_srv_to_cln; uint32 bytes_cln_to_srv; uint32 close_state; } tcp_data; #define FIN 1 #define SYN 2 #define RST 4 #define PSH 8 #define ACK 16 #define URG 32 #define TCP_SESSION 0x00000800 uint32 tcp_session(uint8 *block, uint32 pkt_size, TME_DATA *data, MEM_TYPE *mem_ex, uint8 *mem_data); #endifsnort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/time_calls.h0000644000175200017520000002460513571422610017636 00000000000000/* * Copyright (c) 2001 * Politecnico di Torino. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the Politecnico * di Torino, and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef _time_calls #define _time_calls #ifdef WIN_NT_DRIVER #include "snort_debug.h" #include "ndis.h" #define DEFAULT_TIMESTAMPMODE 0 #define TIMESTAMPMODE_SINGLE_SYNCHRONIZATION 0 #define TIMESTAMPMODE_SYNCHRONIZATION_ON_CPU_WITH_FIXUP 1 #define TIMESTAMPMODE_QUERYSYSTEMTIME 2 #define TIMESTAMPMODE_RDTSC 3 #define TIMESTAMPMODE_SYNCHRONIZATION_ON_CPU_NO_FIXUP 99 #define TIMESTAMPMODE_REGKEY L"TimestampMode" extern ULONG TimestampMode; /*! \brief A microsecond precise timestamp. included in the sf_pkthdr or the bpf_hdr that NPF associates with every packet. */ struct timeval { long tv_sec; ///< seconds long tv_usec; ///< microseconds }; #endif /*WIN_NT_DRIVER*/ struct time_conv { ULONGLONG reference; struct timeval start[32]; }; #ifdef WIN_NT_DRIVER __inline void TIME_DESYNCHRONIZE(struct time_conv *data) { data->reference = 0; // data->start.tv_sec = 0; // data->start.tv_usec = 0; } __inline void ReadTimeStampModeFromRegistry(PUNICODE_STRING RegistryPath) { ULONG NewLength; PWSTR NullTerminatedString; RTL_QUERY_REGISTRY_TABLE Queries[2]; ULONG DefaultTimestampMode = DEFAULT_TIMESTAMPMODE; NewLength = RegistryPath->Length/2; NullTerminatedString = ExAllocatePool(PagedPool, (NewLength+1) *sizeof(WCHAR)); if (NullTerminatedString != NULL) { RtlCopyMemory(NullTerminatedString, RegistryPath->Buffer, RegistryPath->Length); NullTerminatedString[NewLength]=0; RtlZeroMemory(Queries, sizeof(Queries)); Queries[0].Flags = RTL_QUERY_REGISTRY_DIRECT; Queries[0].Name = TIMESTAMPMODE_REGKEY; Queries[0].EntryContext = &TimestampMode; Queries[0].DefaultType = REG_DWORD; Queries[0].DefaultData = &DefaultTimestampMode; Queries[0].DefaultLength = sizeof(ULONG); if (RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, NullTerminatedString, Queries, NULL, NULL) != STATUS_SUCCESS) { TimestampMode = DEFAULT_TIMESTAMPMODE; } RtlWriteRegistryValue( RTL_REGISTRY_ABSOLUTE, NullTerminatedString, TIMESTAMPMODE_REGKEY, REG_DWORD, &TimestampMode,sizeof(ULONG)); ExFreePool(NullTerminatedString); } else TimestampMode = DEFAULT_TIMESTAMPMODE; } #pragma optimize ("g",off) //Due to some weird behaviour of the optimizer of DDK build 2600 /* KeQueryPerformanceCounter TimeStamps */ __inline void SynchronizeOnCpu(struct timeval *start) { // struct timeval *start = (struct timeval*)Data; struct timeval tmp; LARGE_INTEGER SystemTime; LARGE_INTEGER i; ULONG tmp2; LARGE_INTEGER TimeFreq,PTime; // get the absolute value of the system boot time. PTime = KeQueryPerformanceCounter(&TimeFreq); KeQuerySystemTime(&SystemTime); start->tv_sec = (LONG)(SystemTime.QuadPart/10000000-11644473600); start->tv_usec = (LONG)((SystemTime.QuadPart%10000000)/10); start->tv_sec -= (ULONG)(PTime.QuadPart/TimeFreq.QuadPart); start->tv_usec -= (LONG)((PTime.QuadPart%TimeFreq.QuadPart)*1000000/TimeFreq.QuadPart); if (start->tv_usec < 0) { start->tv_sec --; start->tv_usec += 1000000; } } /*RDTSC timestamps */ /* callers must be at IRQL=PASSIVE_LEVEL*/ __inline VOID TimeSynchronizeRDTSC(struct time_conv *data) { struct timeval tmp; LARGE_INTEGER system_time; ULONGLONG curr_ticks; KIRQL old; LARGE_INTEGER start_kqpc,stop_kqpc,start_freq,stop_freq; ULONGLONG start_ticks,stop_ticks; ULONGLONG delta,delta2; KEVENT event; LARGE_INTEGER i; ULONGLONG reference; if (data->reference!=0) return; KeInitializeEvent(&event,NotificationEvent,FALSE); i.QuadPart=-3500000; KeRaiseIrql(HIGH_LEVEL,&old); start_kqpc=KeQueryPerformanceCounter(&start_freq); __asm { push eax push edx push ecx rdtsc lea ecx, start_ticks mov [ecx+4], edx mov [ecx], eax pop ecx pop edx pop eax } KeLowerIrql(old); KeWaitForSingleObject(&event,UserRequest,KernelMode,TRUE ,&i); KeRaiseIrql(HIGH_LEVEL,&old); stop_kqpc=KeQueryPerformanceCounter(&stop_freq); __asm { push eax push edx push ecx rdtsc lea ecx, stop_ticks mov [ecx+4], edx mov [ecx], eax pop ecx pop edx pop eax } KeLowerIrql(old); delta=stop_ticks-start_ticks; delta2=stop_kqpc.QuadPart-start_kqpc.QuadPart; if (delta>10000000000) { delta/=16; delta2/=16; } reference=delta*(start_freq.QuadPart)/delta2; data->reference=reference/1000; if (reference%1000>500) data->reference++; data->reference*=1000; reference=data->reference; KeQuerySystemTime(&system_time); __asm { push eax push edx push ecx rdtsc lea ecx, curr_ticks mov [ecx+4], edx mov [ecx], eax pop ecx pop edx pop eax } tmp.tv_sec=-(LONG)(curr_ticks/reference); tmp.tv_usec=-(LONG)((curr_ticks%reference)*1000000/reference); system_time.QuadPart-=116444736000000000; tmp.tv_sec+=(LONG)(system_time.QuadPart/10000000); tmp.tv_usec+=(LONG)((system_time.QuadPart%10000000)/10); if (tmp.tv_usec<0) { tmp.tv_sec--; tmp.tv_usec+=1000000; } data->start[0] = tmp; IF_LOUD(DbgPrint("Frequency " STDu64 " MHz\n",data->reference);) } #pragma optimize ("g",on) //Due to some weird behaviour of the optimizer of DDK build 2600 __inline VOID TIME_SYNCHRONIZE(struct time_conv *data) { ULONG NumberOfCpus, i; KAFFINITY AffinityMask; if (data->reference != 0) return; NumberOfCpus = NdisSystemProcessorCount(); if ( TimestampMode == TIMESTAMPMODE_SYNCHRONIZATION_ON_CPU_WITH_FIXUP || TimestampMode == TIMESTAMPMODE_SYNCHRONIZATION_ON_CPU_NO_FIXUP) { for (i = 0 ; i < NumberOfCpus ; i++ ) { AffinityMask = (1 << i); ZwSetInformationThread(NtCurrentThread(), ThreadAffinityMask, &AffinityMask, sizeof(KAFFINITY)); SynchronizeOnCpu(&(data->start[i])); } AffinityMask = 0xFFFFFFFF; ZwSetInformationThread(NtCurrentThread(), ThreadAffinityMask, &AffinityMask, sizeof(KAFFINITY)); data->reference = 1; } else if ( TimestampMode == TIMESTAMPMODE_QUERYSYSTEMTIME ) { //do nothing data->reference = 1; } else if ( TimestampMode == TIMESTAMPMODE_RDTSC ) { TimeSynchronizeRDTSC(data); } else { //it should be only the normal case i.e. TIMESTAMPMODE_SINGLESYNCHRONIZATION SynchronizeOnCpu(data->start); data->reference = 1; } return; } #pragma optimize ("g",off) //Due to some weird behaviour of the optimizer of DDK build 2600 __inline void GetTimeKQPC(struct timeval *dst, struct time_conv *data) { LARGE_INTEGER PTime, TimeFreq; LONG tmp; ULONG CurrentCpu; static struct timeval old_ts={0,0}; PTime = KeQueryPerformanceCounter(&TimeFreq); tmp = (LONG)(PTime.QuadPart/TimeFreq.QuadPart); if (TimestampMode == TIMESTAMPMODE_SYNCHRONIZATION_ON_CPU_WITH_FIXUP || TimestampMode == TIMESTAMPMODE_SYNCHRONIZATION_ON_CPU_NO_FIXUP) { //actually this code is ok only if we are guaranteed that no thread scheduling will take place. CurrentCpu = KeGetCurrentProcessorNumber(); dst->tv_sec = data->start[CurrentCpu].tv_sec + tmp; dst->tv_usec = data->start[CurrentCpu].tv_usec + (LONG)((PTime.QuadPart%TimeFreq.QuadPart)*1000000/TimeFreq.QuadPart); if (dst->tv_usec >= 1000000) { dst->tv_sec ++; dst->tv_usec -= 1000000; } if (TimestampMode == TIMESTAMPMODE_SYNCHRONIZATION_ON_CPU_WITH_FIXUP) { if (old_ts.tv_sec > dst->tv_sec || (old_ts.tv_sec == dst->tv_sec && old_ts.tv_usec > dst->tv_usec) ) *dst = old_ts; else old_ts = *dst; } } else { //it should be only the normal case i.e. TIMESTAMPMODE_SINGLESYNCHRONIZATION dst->tv_sec = data->start[0].tv_sec + tmp; dst->tv_usec = data->start[0].tv_usec + (LONG)((PTime.QuadPart%TimeFreq.QuadPart)*1000000/TimeFreq.QuadPart); if (dst->tv_usec >= 1000000) { dst->tv_sec ++; dst->tv_usec -= 1000000; } } } __inline void GetTimeRDTSC(struct timeval *dst, struct time_conv *data) { ULONGLONG tmp; __asm { push eax push edx push ecx rdtsc lea ecx, tmp mov [ecx+4], edx mov [ecx], eax pop ecx pop edx pop eax } if (data->reference==0) { return; } dst->tv_sec=(LONG)(tmp/data->reference); dst->tv_usec=(LONG)((tmp-dst->tv_sec*data->reference)*1000000/data->reference); dst->tv_sec+=data->start[0].tv_sec; dst->tv_usec+=data->start[0].tv_usec; if (dst->tv_usec>=1000000) { dst->tv_sec++; dst->tv_usec-=1000000; } } __inline void GetTimeQST(struct timeval *dst, struct time_conv *data) { LARGE_INTEGER SystemTime; KeQuerySystemTime(&SystemTime); dst->tv_sec = (LONG)(SystemTime.QuadPart/10000000-11644473600); dst->tv_usec = (LONG)((SystemTime.QuadPart%10000000)/10); } #pragma optimize ("g",on) //Due to some weird behaviour of the optimizer of DDK build 2600 __inline void GET_TIME(struct timeval *dst, struct time_conv *data) { if ( TimestampMode == TIMESTAMPMODE_RDTSC ) { GetTimeRDTSC(dst,data); } else if ( TimestampMode == TIMESTAMPMODE_QUERYSYSTEMTIME ) { GetTimeQST(dst,data); } else { GetTimeKQPC(dst,data); } } #else /*WIN_NT_DRIVER*/ __inline void FORCE_TIME(struct timeval *src, struct time_conv *dest) { dest->start[0]=*src; } __inline void GET_TIME(struct timeval *dst, struct time_conv *data) { *dst=data->start[0]; } #endif /*WIN_NT_DRIVER*/ #endif /*_time_calls*/ snort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/tme.h0000644000175200017520000001365413571422610016311 00000000000000/* * Copyright (c) 2001 - 2003 * NetGroup, Politecnico di Torino (Italy) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Politecnico di Torino nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef __tme_include_ #define __tme_include_ #ifdef WIN_NT_DRIVER #include "ndis.h" #else #include #endif /*WIN_NT_DRIVER*/ #include "memory_t.h" #include "time_calls.h" /* error codes */ #define TME_ERROR 0 #define TME_SUCCESS 1 #define TME_TRUE 2 #define TME_FALSE 3 /* some constants */ #define DEFAULT_MEM_EX_SIZE 65536 #define MAX_TME_DATA_BLOCKS 4 #define TME_NONE_ACTIVE 0xffffffff #define DELTA_READ 2 /* secs */ #define TME_LUT_ENTRIES 0x00000000 #define TME_MAX_FILL_STATE 0x00000001 /*potrebbe servire per un thread a passive level!?!?! */ #define TME_REHASHING_VALUE 0x00000002 #define TME_KEY_LEN 0x00000003 #define TME_SHARED_MEMORY_BLOCKS 0x00000004 #define TME_FILLED_ENTRIES 0x00000005 #define TME_BLOCK_SIZE 0x00000006 #define TME_EXTRA_SEGMENT_SIZE 0x00000007 #define TME_LOOKUP_CODE 0x00000008 #define TME_OUT_LUT_EXEC 0x00000009 #define TME_FILLED_BLOCKS 0x0000000a #define TME_DEFAULT_EXEC 0x0000000b #define TME_LUT_BASE_ADDRESS 0x0000000c #define TME_SHARED_MEMORY_BASE_ADDRESS 0x0000000d #define TME_EXTRA_SEGMENT_BASE_ADDRESS 0x0000000e #define TME_LAST_FOUND 0x0000000f /* contains the offset of the last found entry */ #define TME_LAST_FOUND_BLOCK 0x00000010 /* TME default values */ #define TME_LUT_ENTRIES_DEFAULT 32007 #define TME_REHASHING_VALUE_DEFAULT 1 #define TME_SHARED_MEMORY_BLOCKS_DEFAULT 16000 #define TME_BLOCK_SIZE_DEFAULT 64 #define TME_EXTRA_SEGMENT_SIZE_DEFAULT 0 #define TME_LOOKUP_CODE_DEFAULT 0 #define TME_OUT_LUT_EXEC_DEFAULT 0 #define TME_DEFAULT_EXEC_DEFAULT 0 #define TME_MAX_FILL_STATE_DEFAULT 15000 #define IS_VALIDATED(src,index) (src&(1<tv_sec=0x7fffffff; /* TME callback prototypes */ typedef uint32 (*lut_fcn)(uint8 *key, struct __TME_DATA *data,MEM_TYPE *mem_ex, struct time_conv *time_ref ); typedef uint32 (*exec_fcn)(uint8 *block, uint32 pkt_size, struct __TME_DATA *data, MEM_TYPE *mem_ex, uint8 *mem_data); /* DO NOT MODIFY THIS STRUCTURE!!!! GV */ typedef struct __RECORD { uint32 block; uint32 exec_fcn; } RECORD, *PRECORD; /* TME data registers */ struct __TME_DATA { uint32 lut_entries; uint32 max_fill_state; uint32 rehashing_value; uint32 key_len; uint32 shared_memory_blocks; uint32 filled_entries; uint32 block_size; uint32 extra_segment_size; uint32 filled_blocks; lut_fcn lookup_code; uint32 default_exec; uint32 out_lut_exec; uint8 *lut_base_address; uint8 *shared_memory_base_address; uint8 *extra_segment_base_address; struct timeval last_read; uint32 enable_deletion; uint8 *last_found; }; typedef struct __TME_DATA TME_DATA,*PTME_DATA; /* TME core */ typedef struct __TME_CORE { uint32 working; uint32 active; uint32 validated_blocks; TME_DATA block_data[MAX_TME_DATA_BLOCKS]; uint32 active_read; } TME_CORE, *PTME_CORE; static __inline int32 IS_DELETABLE(void *timestamp, TME_DATA *data) { struct timeval *ts=(struct timeval*)timestamp; if (data->enable_deletion==FALSE) return FALSE; if (data->filled_entriesmax_fill_state) return FALSE; if ((ts->tv_sec+DELTA_READ)last_read.tv_sec) return TRUE; return FALSE; } /* functions to manage TME */ uint32 init_tme_block(TME_CORE *tme, uint32 block); uint32 validate_tme_block(MEM_TYPE *mem_ex, TME_CORE *tme, uint32 block, uint32 mem_ex_offset); uint32 lookup_frontend(MEM_TYPE *mem_ex, TME_CORE *tme,uint32 mem_ex_offset, struct time_conv *time_ref); uint32 execute_frontend(MEM_TYPE *mem_ex, TME_CORE *tme, uint32 pkt_size,uint32 offset); uint32 set_active_tme_block(TME_CORE *tme, uint32 block); uint32 init_extended_memory(uint32 size, MEM_TYPE *mem_ex); uint32 reset_tme(TME_CORE *tme); uint32 get_tme_block_register(TME_DATA *data,MEM_TYPE *mem_ex,uint32 rgstr,uint32 *rval); uint32 set_tme_block_register(TME_DATA *data,MEM_TYPE *mem_ex,uint32 rgstr,uint32 value, int32 init); uint32 set_active_read_tme_block(TME_CORE *tme, uint32 block); uint32 set_autodeletion(TME_DATA *data, uint32 value); /* function mappers */ lut_fcn lut_fcn_mapper(uint32 index); exec_fcn exec_fcn_mapper(uint32 index); #endifsnort-2.9.15.1/src/win32/WIN32-Includes/WinPCAP/Win32-Extensions.h0000644000175200017520000000766513571422610020570 00000000000000/* * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Politecnico di Torino, CACE Technologies * nor the names of its contributors may be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef __WIN32_EXTENSIONS_H__ #define __WIN32_EXTENSIONS_H__ #ifdef __cplusplus extern "C" { #endif /* Definitions */ /*! \brief A queue of raw packets that will be sent to the network with pcap_sendqueue_transmit(). */ struct pcap_send_queue { u_int maxlen; ///< Maximum size of the the queue, in bytes. This variable contains the size of the buffer field. u_int len; ///< Current size of the queue, in bytes. char *buffer; ///< Buffer containing the packets to be sent. }; typedef struct pcap_send_queue pcap_send_queue; /*! \brief This typedef is a support for the pcap_get_airpcap_handle() function */ #if !defined(AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_) #define AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ typedef struct _AirpcapHandle *PAirpcapHandle; #endif #define BPF_MEM_EX_IMM 0xc0 #define BPF_MEM_EX_IND 0xe0 /*used for ST*/ #define BPF_MEM_EX 0xc0 #define BPF_TME 0x08 #define BPF_LOOKUP 0x90 #define BPF_EXECUTE 0xa0 #define BPF_INIT 0xb0 #define BPF_VALIDATE 0xc0 #define BPF_SET_ACTIVE 0xd0 #define BPF_RESET 0xe0 #define BPF_SET_MEMORY 0x80 #define BPF_GET_REGISTER_VALUE 0x70 #define BPF_SET_REGISTER_VALUE 0x60 #define BPF_SET_WORKING 0x50 #define BPF_SET_ACTIVE_READ 0x40 #define BPF_SET_AUTODELETION 0x30 #define BPF_SEPARATION 0xff /* Prototypes */ pcap_send_queue* pcap_sendqueue_alloc(u_int memsize); void pcap_sendqueue_destroy(pcap_send_queue* queue); int pcap_sendqueue_queue(pcap_send_queue* queue, const DAQ_PktHdr_t *pkt_header, const u_char *pkt_data); u_int pcap_sendqueue_transmit(pcap_t *p, pcap_send_queue* queue, int sync); HANDLE pcap_getevent(pcap_t *p); struct pcap_stat *pcap_stats_ex(pcap_t *p, int *pcap_stat_size); int pcap_setuserbuffer(pcap_t *p, int size); int pcap_live_dump(pcap_t *p, char *filename, int maxsize, int maxpacks); int pcap_live_dump_ended(pcap_t *p, int sync); int pcap_offline_filter(struct bpf_program *prog, const DAQ_PktHdr_t *header, const u_char *pkt_data); int pcap_start_oem(char* err_str, int flags); PAirpcapHandle pcap_get_airpcap_handle(pcap_t *p); #ifdef __cplusplus } #endif #endif //__WIN32_EXTENSIONS_H__ snort-2.9.15.1/src/win32/WIN32-Includes/libdnet/0000755000000000000000000000000013571426517015616 500000000000000snort-2.9.15.1/src/win32/WIN32-Includes/libdnet/dnet/0000755000000000000000000000000013571426517016550 500000000000000snort-2.9.15.1/src/win32/WIN32-Includes/libdnet/dnet/addr.h0000644000175200017520000000325713571422610017606 00000000000000/* * addr.h * * Network address operations. * * Copyright (c) 2000 Dug Song * * $Id$ */ #ifndef DNET_ADDR_H #define DNET_ADDR_H #define ADDR_TYPE_NONE 0 /* No address set */ #define ADDR_TYPE_ETH 1 /* Ethernet */ #define ADDR_TYPE_IP 2 /* Internet Protocol v4 */ #define ADDR_TYPE_IP6 3 /* Internet Protocol v6 */ struct addr { uint16_t addr_type; uint16_t addr_bits; union { eth_addr_t __eth; ip_addr_t __ip; ip6_addr_t __ip6; uint8_t __data8[16]; uint16_t __data16[8]; uint32_t __data32[4]; } __addr_u; }; #define addr_eth __addr_u.__eth #define addr_ip __addr_u.__ip #define addr_ip6 __addr_u.__ip6 #define addr_data8 __addr_u.__data8 #define addr_data16 __addr_u.__data16 #define addr_data32 __addr_u.__data32 #define addr_pack(addr, type, bits, data, len) do { \ (addr)->addr_type = type; \ (addr)->addr_bits = bits; \ memmove((addr)->addr_data8, (char *)data, len); \ } while (0) __BEGIN_DECLS int addr_cmp(const struct addr *a, const struct addr *b); int addr_bcast(const struct addr *a, struct addr *b); int addr_net(const struct addr *a, struct addr *b); char *addr_ntop(const struct addr *src, char *dst, size_t size); int addr_pton(const char *src, struct addr *dst); char *addr_ntoa(const struct addr *a); #define addr_aton addr_pton int addr_ntos(const struct addr *a, struct sockaddr *sa); int addr_ston(const struct sockaddr *sa, struct addr *a); int addr_btos(uint16_t bits, struct sockaddr *sa); int addr_stob(const struct sockaddr *sa, uint16_t *bits); int addr_btom(uint16_t bits, void *mask, size_t size); int addr_mtob(const void *mask, size_t size, uint16_t *bits); __END_DECLS #endif /* DNET_ADDR_H */ snort-2.9.15.1/src/win32/WIN32-Includes/libdnet/dnet/arp.h0000644000175200017520000000525613571422610017457 00000000000000/* * arp.h * * Address Resolution Protocol. * RFC 826 * * Copyright (c) 2000 Dug Song * * $Id$ */ #ifndef DNET_ARP_H #define DNET_ARP_H #define ARP_HDR_LEN 8 /* base ARP header length */ #define ARP_ETHIP_LEN 20 /* base ARP message length */ #ifndef __GNUC__ # define __attribute__(x) # pragma pack(1) #endif /* * ARP header */ struct arp_hdr { uint16_t ar_hrd; /* format of hardware address */ uint16_t ar_pro; /* format of protocol address */ uint8_t ar_hln; /* length of hardware address (ETH_ADDR_LEN) */ uint8_t ar_pln; /* length of protocol address (IP_ADDR_LEN) */ uint16_t ar_op; /* operation */ }; /* * Hardware address format */ #define ARP_HRD_ETH 0x0001 /* ethernet hardware */ #define ARP_HRD_IEEE802 0x0006 /* IEEE 802 hardware */ /* * Protocol address format */ #define ARP_PRO_IP 0x0800 /* IP protocol */ /* * ARP operation */ #define ARP_OP_REQUEST 1 /* request to resolve ha given pa */ #define ARP_OP_REPLY 2 /* response giving hardware address */ #define ARP_OP_REVREQUEST 3 /* request to resolve pa given ha */ #define ARP_OP_REVREPLY 4 /* response giving protocol address */ /* * Ethernet/IP ARP message */ struct arp_ethip { uint8_t ar_sha[ETH_ADDR_LEN]; /* sender hardware address */ uint8_t ar_spa[IP_ADDR_LEN]; /* sender protocol address */ uint8_t ar_tha[ETH_ADDR_LEN]; /* target hardware address */ uint8_t ar_tpa[IP_ADDR_LEN]; /* target protocol address */ }; /* * ARP cache entry */ struct arp_entry { struct addr arp_pa; /* protocol address */ struct addr arp_ha; /* hardware address */ }; #ifndef __GNUC__ # pragma pack() #endif #define arp_pack_hdr_ethip(hdr, op, sha, spa, tha, tpa) do { \ struct arp_hdr *pack_arp_p = (struct arp_hdr *)(hdr); \ struct arp_ethip *pack_ethip_p = (struct arp_ethip *) \ ((uint8_t *)(hdr) + ARP_HDR_LEN); \ pack_arp_p->ar_hrd = htons(ARP_HRD_ETH); \ pack_arp_p->ar_pro = htons(ARP_PRO_IP); \ pack_arp_p->ar_hln = ETH_ADDR_LEN; \ pack_arp_p->ar_pln = IP_ADDR_LEN; \ pack_arp_p->ar_op = htons(op); \ memmove(pack_ethip_p->ar_sha, &(sha), ETH_ADDR_LEN); \ memmove(pack_ethip_p->ar_spa, &(spa), IP_ADDR_LEN); \ memmove(pack_ethip_p->ar_tha, &(tha), ETH_ADDR_LEN); \ memmove(pack_ethip_p->ar_tpa, &(tpa), IP_ADDR_LEN); \ } while (0) typedef struct arp_handle arp_t; typedef int (*arp_handler)(const struct arp_entry *entry, void *arg); __BEGIN_DECLS arp_t *arp_open(void); int arp_add(arp_t *arp, const struct arp_entry *entry); int arp_delete(arp_t *arp, const struct arp_entry *entry); int arp_get(arp_t *arp, struct arp_entry *entry); int arp_loop(arp_t *arp, arp_handler callback, void *arg); arp_t *arp_close(arp_t *arp); __END_DECLS #endif /* DNET_ARP_H */ snort-2.9.15.1/src/win32/WIN32-Includes/libdnet/dnet/blob.h0000644000175200017520000000261013571422610017602 00000000000000/* * blob.h * * Binary blob handling. * * Copyright (c) 2002 Dug Song * * $Id$ */ #ifndef DNET_BLOB_H #define DNET_BLOB_H typedef struct blob { u_char *base; /* start of data */ int off; /* offset into data */ int end; /* end of data */ int size; /* size of allocation */ } blob_t; __BEGIN_DECLS blob_t *blob_new(void); int blob_read(blob_t *b, void *buf, int len); int blob_write(blob_t *b, const void *buf, int len); int blob_seek(blob_t *b, int off, int whence); #define blob_skip(b, l) blob_seek(b, l, SEEK_CUR) #define blob_rewind(b) blob_seek(b, 0, SEEK_SET) #define blob_offset(b) ((b)->off) #define blob_left(b) ((b)->end - (b)->off) int blob_index(blob_t *b, const void *buf, int len); int blob_rindex(blob_t *b, const void *buf, int len); int blob_pack(blob_t *b, const char *fmt, ...); int blob_unpack(blob_t *b, const char *fmt, ...); int blob_insert(blob_t *b, const void *buf, int len); int blob_delete(blob_t *b, void *buf, int len); int blob_print(blob_t *b, char *style, int len); blob_t *blob_free(blob_t *b); int blob_register_alloc(size_t size, void *(*bmalloc)(size_t), void (*bfree)(void *), void *(*brealloc)(void *, size_t)); #ifdef va_start typedef int (*blob_fmt_cb)(int pack, int len, blob_t *b, va_list *arg); int blob_register_pack(char c, blob_fmt_cb fmt_cb); #endif __END_DECLS #endif /* DNET_BLOB_H */ snort-2.9.15.1/src/win32/WIN32-Includes/libdnet/dnet/eth.h0000644000175200017520000000441013571422610017444 00000000000000/* * eth.h * * Ethernet. * * Copyright (c) 2000 Dug Song * * $Id$ */ #ifndef DNET_ETH_H #define DNET_ETH_H #define ETH_ADDR_LEN 6 #define ETH_ADDR_BITS 48 #define ETH_TYPE_LEN 2 #define ETH_CRC_LEN 4 #define ETH_HDR_LEN 14 #define ETH_LEN_MIN 64 /* minimum frame length with CRC */ #define ETH_LEN_MAX 1518 /* maximum frame length with CRC */ #define ETH_MTU (ETH_LEN_MAX - ETH_HDR_LEN - ETH_CRC_LEN) #define ETH_MIN (ETH_LEN_MIN - ETH_HDR_LEN - ETH_CRC_LEN) typedef struct eth_addr { uint8_t data[ETH_ADDR_LEN]; } eth_addr_t; struct eth_hdr { eth_addr_t eth_dst; /* destination address */ eth_addr_t eth_src; /* source address */ uint16_t eth_type; /* payload type */ }; /* * Ethernet payload types - http://standards.ieee.org/regauth/ethertype */ #define ETH_TYPE_PUP 0x0200 /* PUP protocol */ #define ETH_TYPE_IP 0x0800 /* IP protocol */ #define ETH_TYPE_ARP 0x0806 /* address resolution protocol */ #define ETH_TYPE_REVARP 0x8035 /* reverse addr resolution protocol */ #define ETH_TYPE_8021Q 0x8100 /* IEEE 802.1Q VLAN tagging */ #define ETH_TYPE_IPV6 0x86DD /* IPv6 protocol */ #define ETH_TYPE_MPLS 0x8847 /* MPLS */ #define ETH_TYPE_MPLS_MCAST 0x8848 /* MPLS Multicast */ #define ETH_TYPE_PPPOEDISC 0x8863 /* PPP Over Ethernet Discovery Stage */ #define ETH_TYPE_PPPOE 0x8864 /* PPP Over Ethernet Session Stage */ #define ETH_TYPE_LOOPBACK 0x9000 /* used to test interfaces */ #define ETH_IS_MULTICAST(ea) (*(ea) & 0x01) /* is address mcast/bcast? */ #define ETH_ADDR_BROADCAST "\xff\xff\xff\xff\xff\xff" #define eth_pack_hdr(h, dst, src, type) do { \ struct eth_hdr *eth_pack_p = (struct eth_hdr *)(h); \ memmove(ð_pack_p->eth_dst, &(dst), ETH_ADDR_LEN); \ memmove(ð_pack_p->eth_src, &(src), ETH_ADDR_LEN); \ eth_pack_p->eth_type = htons(type); \ } while (0) typedef struct eth_handle eth_t; __BEGIN_DECLS eth_t *eth_open(const char *device); int eth_get(eth_t *e, eth_addr_t *ea); int eth_set(eth_t *e, const eth_addr_t *ea); ssize_t eth_send(eth_t *e, const void *buf, size_t len); eth_t *eth_close(eth_t *e); char *eth_ntop(const eth_addr_t *eth, char *dst, size_t len); int eth_pton(const char *src, eth_addr_t *dst); char *eth_ntoa(const eth_addr_t *eth); #define eth_aton eth_pton __END_DECLS #endif /* DNET_ETH_H */ snort-2.9.15.1/src/win32/WIN32-Includes/libdnet/dnet/fw.h0000644000175200017520000000266613571422610017313 00000000000000/* * fw.h * * Network firewalling operations. * * Copyright (c) 2001 Dug Song * * $Id$ */ #ifndef DNET_FW_H #define DNET_FW_H struct fw_rule { char fw_device[INTF_NAME_LEN]; /* interface name */ uint8_t fw_op; /* operation */ uint8_t fw_dir; /* direction */ uint8_t fw_proto; /* IP protocol */ struct addr fw_src; /* src address / net */ struct addr fw_dst; /* dst address / net */ uint16_t fw_sport[2]; /* range / ICMP type */ uint16_t fw_dport[2]; /* range / ICMP code */ }; #define FW_OP_ALLOW 1 #define FW_OP_BLOCK 2 #define FW_DIR_IN 1 #define FW_DIR_OUT 2 #define fw_pack_rule(rule, dev, op, dir, p, s, d, sp1, sp2, dp1, dp2) \ do { \ strlcpy((rule)->fw_device, dev, sizeof((rule)->fw_device)); \ (rule)->fw_op = op; (rule)->fw_dir = dir; \ (rule)->fw_proto = p; \ memmove(&(rule)->fw_src, &(s), sizeof((rule)->fw_src)); \ memmove(&(rule)->fw_dst, &(d), sizeof((rule)->fw_dst)); \ (rule)->fw_sport[0] = sp1; (rule)->fw_sport[1] = sp2; \ (rule)->fw_dport[0] = dp1; (rule)->fw_dport[1] = dp2; \ } while (0) typedef struct fw_handle fw_t; typedef int (*fw_handler)(const struct fw_rule *rule, void *arg); __BEGIN_DECLS fw_t *fw_open(void); int fw_add(fw_t *f, const struct fw_rule *rule); int fw_delete(fw_t *f, const struct fw_rule *rule); int fw_loop(fw_t *f, fw_handler callback, void *arg); fw_t *fw_close(fw_t *f); __END_DECLS #endif /* DNET_FW_H */ snort-2.9.15.1/src/win32/WIN32-Includes/libdnet/dnet/icmp.h0000644000175200017520000002223213571422610017616 00000000000000/* * icmp.h * * Internet Control Message Protocol. * RFC 792, 950, 1256, 1393, 1475, 2002, 2521 * * Copyright (c) 2000 Dug Song * * $Id$ */ #ifndef DNET_ICMP_H #define DNET_ICMP_H #define ICMP_HDR_LEN 4 /* base ICMP header length */ #define ICMP_LEN_MIN 8 /* minimum ICMP message size, with header */ #ifndef __GNUC__ # define __attribute__(x) # pragma pack(1) #endif /* * ICMP header */ struct icmp_hdr { uint8_t icmp_type; /* type of message, see below */ uint8_t icmp_code; /* type sub code */ uint16_t icmp_cksum; /* ones complement cksum of struct */ }; /* * Types (icmp_type) and codes (icmp_code) - * http://www.iana.org/assignments/icmp-parameters */ #define ICMP_CODE_NONE 0 /* for types without codes */ #define ICMP_ECHOREPLY 0 /* echo reply */ #define ICMP_UNREACH 3 /* dest unreachable, codes: */ #define ICMP_UNREACH_NET 0 /* bad net */ #define ICMP_UNREACH_HOST 1 /* bad host */ #define ICMP_UNREACH_PROTO 2 /* bad protocol */ #define ICMP_UNREACH_PORT 3 /* bad port */ #define ICMP_UNREACH_NEEDFRAG 4 /* IP_DF caused drop */ #define ICMP_UNREACH_SRCFAIL 5 /* src route failed */ #define ICMP_UNREACH_NET_UNKNOWN 6 /* unknown net */ #define ICMP_UNREACH_HOST_UNKNOWN 7 /* unknown host */ #define ICMP_UNREACH_ISOLATED 8 /* src host isolated */ #define ICMP_UNREACH_NET_PROHIB 9 /* for crypto devs */ #define ICMP_UNREACH_HOST_PROHIB 10 /* ditto */ #define ICMP_UNREACH_TOSNET 11 /* bad tos for net */ #define ICMP_UNREACH_TOSHOST 12 /* bad tos for host */ #define ICMP_UNREACH_FILTER_PROHIB 13 /* prohibited access */ #define ICMP_UNREACH_HOST_PRECEDENCE 14 /* precedence error */ #define ICMP_UNREACH_PRECEDENCE_CUTOFF 15 /* precedence cutoff */ #define ICMP_SRCQUENCH 4 /* packet lost, slow down */ #define ICMP_REDIRECT 5 /* shorter route, codes: */ #define ICMP_REDIRECT_NET 0 /* for network */ #define ICMP_REDIRECT_HOST 1 /* for host */ #define ICMP_REDIRECT_TOSNET 2 /* for tos and net */ #define ICMP_REDIRECT_TOSHOST 3 /* for tos and host */ #define ICMP_ALTHOSTADDR 6 /* alternate host address */ #define ICMP_ECHO 8 /* echo service */ #define ICMP_RTRADVERT 9 /* router advertise, codes: */ #define ICMP_RTRADVERT_NORMAL 0 /* normal */ #define ICMP_RTRADVERT_NOROUTE_COMMON 16 /* selective routing */ #define ICMP_RTRSOLICIT 10 /* router solicitation */ #define ICMP_TIMEXCEED 11 /* time exceeded, code: */ #define ICMP_TIMEXCEED_INTRANS 0 /* ttl==0 in transit */ #define ICMP_TIMEXCEED_REASS 1 /* ttl==0 in reass */ #define ICMP_PARAMPROB 12 /* ip header bad */ #define ICMP_PARAMPROB_ERRATPTR 0 /* req. opt. absent */ #define ICMP_PARAMPROB_OPTABSENT 1 /* req. opt. absent */ #define ICMP_PARAMPROB_LENGTH 2 /* bad length */ #define ICMP_TSTAMP 13 /* timestamp request */ #define ICMP_TSTAMPREPLY 14 /* timestamp reply */ #define ICMP_INFO 15 /* information request */ #define ICMP_INFOREPLY 16 /* information reply */ #define ICMP_MASK 17 /* address mask request */ #define ICMP_MASKREPLY 18 /* address mask reply */ #define ICMP_TRACEROUTE 30 /* traceroute */ #define ICMP_DATACONVERR 31 /* data conversion error */ #define ICMP_MOBILE_REDIRECT 32 /* mobile host redirect */ #define ICMP_IPV6_WHEREAREYOU 33 /* IPv6 where-are-you */ #define ICMP_IPV6_IAMHERE 34 /* IPv6 i-am-here */ #define ICMP_MOBILE_REG 35 /* mobile registration req */ #define ICMP_MOBILE_REGREPLY 36 /* mobile registration reply */ #define ICMP_DNS 37 /* domain name request */ #define ICMP_DNSREPLY 38 /* domain name reply */ #define ICMP_SKIP 39 /* SKIP */ #define ICMP_PHOTURIS 40 /* Photuris */ #define ICMP_PHOTURIS_UNKNOWN_INDEX 0 /* unknown sec index */ #define ICMP_PHOTURIS_AUTH_FAILED 1 /* auth failed */ #define ICMP_PHOTURIS_DECOMPRESS_FAILED 2 /* decompress failed */ #define ICMP_PHOTURIS_DECRYPT_FAILED 3 /* decrypt failed */ #define ICMP_PHOTURIS_NEED_AUTHN 4 /* no authentication */ #define ICMP_PHOTURIS_NEED_AUTHZ 5 /* no authorization */ #define ICMP_TYPE_MAX 40 #define ICMP_INFOTYPE(type) \ ((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \ (type) == ICMP_RTRADVERT || (type) == ICMP_RTRSOLICIT || \ (type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \ (type) == ICMP_INFO || (type) == ICMP_INFOREPLY || \ (type) == ICMP_MASK || (type) == ICMP_MASKREPLY) /* * Echo message data */ struct icmp_msg_echo { uint16_t icmp_id; uint16_t icmp_seq; uint8_t icmp_data __flexarr; /* optional data */ }; /* * Fragmentation-needed (unreachable) message data */ struct icmp_msg_needfrag { uint16_t icmp_void; /* must be zero */ uint16_t icmp_mtu; /* MTU of next-hop network */ uint8_t icmp_ip __flexarr; /* IP hdr + 8 bytes of pkt */ }; /* * Unreachable, source quench, redirect, time exceeded, * parameter problem message data */ struct icmp_msg_quote { uint32_t icmp_void; /* must be zero */ #define icmp_gwaddr icmp_void /* router IP address to use */ #define icmp_pptr icmp_void /* ptr to bad octet field */ uint8_t icmp_ip __flexarr; /* IP hdr + 8 bytes of pkt */ }; /* * Router advertisement message data, RFC 1256 */ struct icmp_msg_rtradvert { uint8_t icmp_num_addrs; /* # of address / pref pairs */ uint8_t icmp_wpa; /* words / address == 2 */ uint16_t icmp_lifetime; /* route lifetime in seconds */ struct icmp_msg_rtr_data { uint32_t icmp_void; #define icmp_gwaddr icmp_void /* router IP address */ uint32_t icmp_pref; /* router preference (usu 0) */ } icmp_rtr __flexarr; /* variable # of routers */ }; #define ICMP_RTR_PREF_NODEFAULT 0x80000000 /* do not use as default gw */ /* * Timestamp message data */ struct icmp_msg_tstamp { uint32_t icmp_id; /* identifier */ uint32_t icmp_seq; /* sequence number */ uint32_t icmp_ts_orig; /* originate timestamp */ uint32_t icmp_ts_rx; /* receive timestamp */ uint32_t icmp_ts_tx; /* transmit timestamp */ }; /* * Address mask message data, RFC 950 */ struct icmp_msg_mask { uint32_t icmp_id; /* identifier */ uint32_t icmp_seq; /* sequence number */ uint32_t icmp_mask; /* address mask */ }; /* * Traceroute message data, RFC 1393, RFC 1812 */ struct icmp_msg_traceroute { uint16_t icmp_id; /* identifier */ uint16_t icmp_void; /* unused */ uint16_t icmp_ohc; /* outbound hop count */ uint16_t icmp_rhc; /* return hop count */ uint32_t icmp_speed; /* link speed, bytes/sec */ uint32_t icmp_mtu; /* MTU in bytes */ }; /* * Domain name reply message data, RFC 1788 */ struct icmp_msg_dnsreply { uint16_t icmp_id; /* identifier */ uint16_t icmp_seq; /* sequence number */ uint32_t icmp_ttl; /* time-to-live */ uint8_t icmp_names __flexarr; /* variable number of names */ }; /* * Generic identifier, sequence number data */ struct icmp_msg_idseq { uint16_t icmp_id; uint16_t icmp_seq; }; /* * ICMP message union */ union icmp_msg { struct icmp_msg_echo echo; /* ICMP_ECHO{REPLY} */ struct icmp_msg_quote unreach; /* ICMP_UNREACH */ struct icmp_msg_needfrag needfrag; /* ICMP_UNREACH_NEEDFRAG */ struct icmp_msg_quote srcquench; /* ICMP_SRCQUENCH */ struct icmp_msg_quote redirect; /* ICMP_REDIRECT (set to 0) */ uint32_t rtrsolicit; /* ICMP_RTRSOLICIT */ struct icmp_msg_rtradvert rtradvert; /* ICMP_RTRADVERT */ struct icmp_msg_quote timexceed; /* ICMP_TIMEXCEED */ struct icmp_msg_quote paramprob; /* ICMP_PARAMPROB */ struct icmp_msg_tstamp tstamp; /* ICMP_TSTAMP{REPLY} */ struct icmp_msg_idseq info; /* ICMP_INFO{REPLY} */ struct icmp_msg_mask mask; /* ICMP_MASK{REPLY} */ struct icmp_msg_traceroute traceroute; /* ICMP_TRACEROUTE */ struct icmp_msg_idseq dns; /* ICMP_DNS */ struct icmp_msg_dnsreply dnsreply; /* ICMP_DNSREPLY */ }; #ifndef __GNUC__ # pragma pack() #endif #define icmp_pack_hdr(hdr, type, code) do { \ struct icmp_hdr *icmp_pack_p = (struct icmp_hdr *)(hdr); \ icmp_pack_p->icmp_type = type; icmp_pack_p->icmp_code = code; \ } while (0) #define icmp_pack_hdr_echo(hdr, type, code, id, seq, data, len) do { \ struct icmp_msg_echo *echo_pack_p = (struct icmp_msg_echo *) \ ((uint8_t *)(hdr) + ICMP_HDR_LEN); \ icmp_pack_hdr(hdr, type, code); \ echo_pack_p->icmp_id = htons(id); \ echo_pack_p->icmp_seq = htons(seq); \ memmove(echo_pack_p->icmp_data, data, len); \ } while (0) #define icmp_pack_hdr_quote(hdr, type, code, word, pkt, len) do { \ struct icmp_msg_quote *quote_pack_p = (struct icmp_msg_quote *) \ ((uint8_t *)(hdr) + ICMP_HDR_LEN); \ icmp_pack_hdr(hdr, type, code); \ quote_pack_p->icmp_void = htonl(word); \ memmove(quote_pack_p->icmp_ip, pkt, len); \ } while (0) #define icmp_pack_hdr_mask(hdr, type, code, id, seq, mask) do { \ struct icmp_msg_mask *mask_pack_p = (struct icmp_msg_mask *) \ ((uint8_t *)(hdr) + ICMP_HDR_LEN); \ icmp_pack_hdr(hdr, type, code); \ mask_pack_p->icmp_id = htons(id); \ mask_pack_p->icmp_seq = htons(seq); \ mask_pack_p->icmp_mask = htonl(mask); \ } while (0) #define icmp_pack_hdr_needfrag(hdr, type, code, mtu, pkt, len) do { \ struct icmp_msg_needfrag *frag_pack_p = \ (struct icmp_msg_needfrag *)((uint8_t *)(hdr) + ICMP_HDR_LEN); \ icmp_pack_hdr(hdr, type, code); \ frag_pack_p->icmp_void = 0; \ frag_pack_p->icmp_mtu = htons(mtu); \ memmove(frag_pack_p->icmp_ip, pkt, len); \ } while (0) #endif /* DNET_ICMP_H */ snort-2.9.15.1/src/win32/WIN32-Includes/libdnet/dnet/intf.h0000644000175200017520000000417213571422610017631 00000000000000/* * intf.c * * Network interface operations. * * Copyright (c) 2000 Dug Song * * $Id$ */ #ifndef DNET_INTF_H #define DNET_INTF_H /* * Interface entry */ #define INTF_NAME_LEN 16 struct intf_entry { u_int intf_len; /* length of entry */ char intf_name[INTF_NAME_LEN]; /* interface name */ u_short intf_type; /* interface type (r/o) */ u_short intf_flags; /* interface flags */ u_int intf_mtu; /* interface MTU */ struct addr intf_addr; /* interface address */ struct addr intf_dst_addr; /* point-to-point dst */ struct addr intf_link_addr; /* link-layer address */ u_int intf_alias_num; /* number of aliases */ struct addr intf_alias_addrs __flexarr; /* array of aliases */ }; /* * MIB-II interface types - http://www.iana.org/assignments/ianaiftype-mib */ #define INTF_TYPE_OTHER 1 /* other */ #define INTF_TYPE_ETH 6 /* Ethernet */ #define INTF_TYPE_TOKENRING 9 /* Token Ring */ #define INTF_TYPE_FDDI 15 /* FDDI */ #define INTF_TYPE_PPP 23 /* Point-to-Point Protocol */ #define INTF_TYPE_LOOPBACK 24 /* software loopback */ #define INTF_TYPE_SLIP 28 /* Serial Line Interface Protocol */ #define INTF_TYPE_TUN 53 /* proprietary virtual/internal */ /* * Interface flags */ #define INTF_FLAG_UP 0x01 /* enable interface */ #define INTF_FLAG_LOOPBACK 0x02 /* is a loopback net (r/o) */ #define INTF_FLAG_POINTOPOINT 0x04 /* point-to-point link (r/o) */ #define INTF_FLAG_NOARP 0x08 /* disable ARP */ #define INTF_FLAG_BROADCAST 0x10 /* supports broadcast (r/o) */ #define INTF_FLAG_MULTICAST 0x20 /* supports multicast (r/o) */ typedef struct intf_handle intf_t; typedef int (*intf_handler)(const struct intf_entry *entry, void *arg); __BEGIN_DECLS intf_t *intf_open(void); int intf_get(intf_t *i, struct intf_entry *entry); int intf_get_src(intf_t *i, struct intf_entry *entry, struct addr *src); int intf_get_dst(intf_t *i, struct intf_entry *entry, struct addr *dst); int intf_set(intf_t *i, const struct intf_entry *entry); int intf_loop(intf_t *i, intf_handler callback, void *arg); intf_t *intf_close(intf_t *i); __END_DECLS #endif /* DNET_INTF_H */ snort-2.9.15.1/src/win32/WIN32-Includes/libdnet/dnet/ip.h0000644000175200017520000004040613571422610017301 00000000000000/* * ip.h * * Internet Protocol (RFC 791). * * Copyright (c) 2000 Dug Song * * $Id$ */ #ifndef DNET_IP_H #define DNET_IP_H #define IP_ADDR_LEN 4 /* IP address length */ #define IP_ADDR_BITS 32 /* IP address bits */ #define IP_HDR_LEN 20 /* base IP header length */ #define IP_OPT_LEN 2 /* base IP option length */ #define IP_OPT_LEN_MAX 40 #define IP_HDR_LEN_MAX (IP_HDR_LEN + IP_OPT_LEN_MAX) #define IP_LEN_MAX 65535 #define IP_LEN_MIN IP_HDR_LEN typedef uint32_t ip_addr_t; #ifndef __GNUC__ # define __attribute__(x) # pragma pack(1) #endif /* * IP header, without options */ struct ip_hdr { #if DNET_BYTESEX == DNET_BIG_ENDIAN uint8_t ip_v:4, /* version */ ip_hl:4; /* header length (incl any options) */ #elif DNET_BYTESEX == DNET_LIL_ENDIAN uint8_t ip_hl:4, ip_v:4; #else # error "need to include " #endif uint8_t ip_tos; /* type of service */ uint16_t ip_len; /* total length (incl header) */ uint16_t ip_id; /* identification */ uint16_t ip_off; /* fragment offset and flags */ uint8_t ip_ttl; /* time to live */ uint8_t ip_p; /* protocol */ uint16_t ip_sum; /* checksum */ ip_addr_t ip_src; /* source address */ ip_addr_t ip_dst; /* destination address */ }; /* * Type of service (ip_tos), RFC 1349 ("obsoleted by RFC 2474") */ #define IP_TOS_DEFAULT 0x00 /* default */ #define IP_TOS_LOWDELAY 0x10 /* low delay */ #define IP_TOS_THROUGHPUT 0x08 /* high throughput */ #define IP_TOS_RELIABILITY 0x04 /* high reliability */ #define IP_TOS_LOWCOST 0x02 /* low monetary cost - XXX */ #define IP_TOS_ECT 0x02 /* ECN-capable transport */ #define IP_TOS_CE 0x01 /* congestion experienced */ /* * IP precedence (high 3 bits of ip_tos), hopefully unused */ #define IP_TOS_PREC_ROUTINE 0x00 #define IP_TOS_PREC_PRIORITY 0x20 #define IP_TOS_PREC_IMMEDIATE 0x40 #define IP_TOS_PREC_FLASH 0x60 #define IP_TOS_PREC_FLASHOVERRIDE 0x80 #define IP_TOS_PREC_CRITIC_ECP 0xa0 #define IP_TOS_PREC_INTERNETCONTROL 0xc0 #define IP_TOS_PREC_NETCONTROL 0xe0 /* * Fragmentation flags (ip_off) */ #define IP_RF 0x8000 /* reserved */ #define IP_DF 0x4000 /* don't fragment */ #define IP_MF 0x2000 /* more fragments (not last frag) */ #define IP_OFFMASK 0x1fff /* mask for fragment offset */ /* * Time-to-live (ip_ttl), seconds */ #define IP_TTL_DEFAULT 64 /* default ttl, RFC 1122, RFC 1340 */ #define IP_TTL_MAX 255 /* maximum ttl */ /* * Protocol (ip_p) - http://www.iana.org/assignments/protocol-numbers */ #define IP_PROTO_IP 0 /* dummy for IP */ #define IP_PROTO_HOPOPTS IP_PROTO_IP /* IPv6 hop-by-hop options */ #define IP_PROTO_ICMP 1 /* ICMP */ #define IP_PROTO_IGMP 2 /* IGMP */ #define IP_PROTO_GGP 3 /* gateway-gateway protocol */ #define IP_PROTO_IPIP 4 /* IP in IP */ #define IP_PROTO_ST 5 /* ST datagram mode */ #define IP_PROTO_TCP 6 /* TCP */ #define IP_PROTO_CBT 7 /* CBT */ #define IP_PROTO_EGP 8 /* exterior gateway protocol */ #define IP_PROTO_IGP 9 /* interior gateway protocol */ #define IP_PROTO_BBNRCC 10 /* BBN RCC monitoring */ #define IP_PROTO_NVP 11 /* Network Voice Protocol */ #define IP_PROTO_PUP 12 /* PARC universal packet */ #define IP_PROTO_ARGUS 13 /* ARGUS */ #define IP_PROTO_EMCON 14 /* EMCON */ #define IP_PROTO_XNET 15 /* Cross Net Debugger */ #define IP_PROTO_CHAOS 16 /* Chaos */ #define IP_PROTO_UDP 17 /* UDP */ #define IP_PROTO_MUX 18 /* multiplexing */ #define IP_PROTO_DCNMEAS 19 /* DCN measurement */ #define IP_PROTO_HMP 20 /* Host Monitoring Protocol */ #define IP_PROTO_PRM 21 /* Packet Radio Measurement */ #define IP_PROTO_IDP 22 /* Xerox NS IDP */ #define IP_PROTO_TRUNK1 23 /* Trunk-1 */ #define IP_PROTO_TRUNK2 24 /* Trunk-2 */ #define IP_PROTO_LEAF1 25 /* Leaf-1 */ #define IP_PROTO_LEAF2 26 /* Leaf-2 */ #define IP_PROTO_RDP 27 /* "Reliable Datagram" proto */ #define IP_PROTO_IRTP 28 /* Inet Reliable Transaction */ #define IP_PROTO_TP 29 /* ISO TP class 4 */ #define IP_PROTO_NETBLT 30 /* Bulk Data Transfer */ #define IP_PROTO_MFPNSP 31 /* MFE Network Services */ #define IP_PROTO_MERITINP 32 /* Merit Internodal Protocol */ #define IP_PROTO_SEP 33 /* Sequential Exchange proto */ #define IP_PROTO_3PC 34 /* Third Party Connect proto */ #define IP_PROTO_IDPR 35 /* Interdomain Policy Route */ #define IP_PROTO_XTP 36 /* Xpress Transfer Protocol */ #define IP_PROTO_DDP 37 /* Datagram Delivery Proto */ #define IP_PROTO_CMTP 38 /* IDPR Ctrl Message Trans */ #define IP_PROTO_TPPP 39 /* TP++ Transport Protocol */ #define IP_PROTO_IL 40 /* IL Transport Protocol */ #define IP_PROTO_IPV6 41 /* IPv6 */ #define IP_PROTO_SDRP 42 /* Source Demand Routing */ #define IP_PROTO_ROUTING 43 /* IPv6 routing header */ #define IP_PROTO_FRAGMENT 44 /* IPv6 fragmentation header */ #define IP_PROTO_RSVP 46 /* Reservation protocol */ #define IP_PROTO_GRE 47 /* General Routing Encap */ #define IP_PROTO_MHRP 48 /* Mobile Host Routing */ #define IP_PROTO_ENA 49 /* ENA */ #define IP_PROTO_ESP 50 /* Encap Security Payload */ #define IP_PROTO_AH 51 /* Authentication Header */ #define IP_PROTO_INLSP 52 /* Integated Net Layer Sec */ #define IP_PROTO_SWIPE 53 /* SWIPE */ #define IP_PROTO_NARP 54 /* NBMA Address Resolution */ #define IP_PROTO_MOBILE 55 /* Mobile IP, RFC 2004 */ #define IP_PROTO_TLSP 56 /* Transport Layer Security */ #define IP_PROTO_SKIP 57 /* SKIP */ #define IP_PROTO_ICMPV6 58 /* ICMP for IPv6 */ #define IP_PROTO_NONE 59 /* IPv6 no next header */ #define IP_PROTO_DSTOPTS 60 /* IPv6 destination options */ #define IP_PROTO_ANYHOST 61 /* any host internal proto */ #define IP_PROTO_CFTP 62 /* CFTP */ #define IP_PROTO_ANYNET 63 /* any local network */ #define IP_PROTO_EXPAK 64 /* SATNET and Backroom EXPAK */ #define IP_PROTO_KRYPTOLAN 65 /* Kryptolan */ #define IP_PROTO_RVD 66 /* MIT Remote Virtual Disk */ #define IP_PROTO_IPPC 67 /* Inet Pluribus Packet Core */ #define IP_PROTO_DISTFS 68 /* any distributed fs */ #define IP_PROTO_SATMON 69 /* SATNET Monitoring */ #define IP_PROTO_VISA 70 /* VISA Protocol */ #define IP_PROTO_IPCV 71 /* Inet Packet Core Utility */ #define IP_PROTO_CPNX 72 /* Comp Proto Net Executive */ #define IP_PROTO_CPHB 73 /* Comp Protocol Heart Beat */ #define IP_PROTO_WSN 74 /* Wang Span Network */ #define IP_PROTO_PVP 75 /* Packet Video Protocol */ #define IP_PROTO_BRSATMON 76 /* Backroom SATNET Monitor */ #define IP_PROTO_SUNND 77 /* SUN ND Protocol */ #define IP_PROTO_WBMON 78 /* WIDEBAND Monitoring */ #define IP_PROTO_WBEXPAK 79 /* WIDEBAND EXPAK */ #define IP_PROTO_EON 80 /* ISO CNLP */ #define IP_PROTO_VMTP 81 /* Versatile Msg Transport*/ #define IP_PROTO_SVMTP 82 /* Secure VMTP */ #define IP_PROTO_VINES 83 /* VINES */ #define IP_PROTO_TTP 84 /* TTP */ #define IP_PROTO_NSFIGP 85 /* NSFNET-IGP */ #define IP_PROTO_DGP 86 /* Dissimilar Gateway Proto */ #define IP_PROTO_TCF 87 /* TCF */ #define IP_PROTO_EIGRP 88 /* EIGRP */ #define IP_PROTO_OSPF 89 /* Open Shortest Path First */ #define IP_PROTO_SPRITERPC 90 /* Sprite RPC Protocol */ #define IP_PROTO_LARP 91 /* Locus Address Resolution */ #define IP_PROTO_MTP 92 /* Multicast Transport Proto */ #define IP_PROTO_AX25 93 /* AX.25 Frames */ #define IP_PROTO_IPIPENCAP 94 /* yet-another IP encap */ #define IP_PROTO_MICP 95 /* Mobile Internet Ctrl */ #define IP_PROTO_SCCSP 96 /* Semaphore Comm Sec Proto */ #define IP_PROTO_ETHERIP 97 /* Ethernet in IPv4 */ #define IP_PROTO_ENCAP 98 /* encapsulation header */ #define IP_PROTO_ANYENC 99 /* private encryption scheme */ #define IP_PROTO_GMTP 100 /* GMTP */ #define IP_PROTO_IFMP 101 /* Ipsilon Flow Mgmt Proto */ #define IP_PROTO_PNNI 102 /* PNNI over IP */ #define IP_PROTO_PIM 103 /* Protocol Indep Multicast */ #define IP_PROTO_ARIS 104 /* ARIS */ #define IP_PROTO_SCPS 105 /* SCPS */ #define IP_PROTO_QNX 106 /* QNX */ #define IP_PROTO_AN 107 /* Active Networks */ #define IP_PROTO_IPCOMP 108 /* IP Payload Compression */ #define IP_PROTO_SNP 109 /* Sitara Networks Protocol */ #define IP_PROTO_COMPAQPEER 110 /* Compaq Peer Protocol */ #define IP_PROTO_IPXIP 111 /* IPX in IP */ #define IP_PROTO_VRRP 112 /* Virtual Router Redundancy */ #define IP_PROTO_PGM 113 /* PGM Reliable Transport */ #define IP_PROTO_ANY0HOP 114 /* 0-hop protocol */ #define IP_PROTO_L2TP 115 /* Layer 2 Tunneling Proto */ #define IP_PROTO_DDX 116 /* D-II Data Exchange (DDX) */ #define IP_PROTO_IATP 117 /* Interactive Agent Xfer */ #define IP_PROTO_STP 118 /* Schedule Transfer Proto */ #define IP_PROTO_SRP 119 /* SpectraLink Radio Proto */ #define IP_PROTO_UTI 120 /* UTI */ #define IP_PROTO_SMP 121 /* Simple Message Protocol */ #define IP_PROTO_SM 122 /* SM */ #define IP_PROTO_PTP 123 /* Performance Transparency */ #define IP_PROTO_ISIS 124 /* ISIS over IPv4 */ #define IP_PROTO_FIRE 125 /* FIRE */ #define IP_PROTO_CRTP 126 /* Combat Radio Transport */ #define IP_PROTO_CRUDP 127 /* Combat Radio UDP */ #define IP_PROTO_SSCOPMCE 128 /* SSCOPMCE */ #define IP_PROTO_IPLT 129 /* IPLT */ #define IP_PROTO_SPS 130 /* Secure Packet Shield */ #define IP_PROTO_PIPE 131 /* Private IP Encap in IP */ #define IP_PROTO_SCTP 132 /* Stream Ctrl Transmission */ #define IP_PROTO_FC 133 /* Fibre Channel */ #define IP_PROTO_RSVPIGN 134 /* RSVP-E2E-IGNORE */ #define IP_PROTO_RAW 255 /* Raw IP packets */ #define IP_PROTO_RESERVED IP_PROTO_RAW /* Reserved */ #define IP_PROTO_MAX 255 /* * Option types (opt_type) - http://www.iana.org/assignments/ip-parameters */ #define IP_OPT_CONTROL 0x00 /* control */ #define IP_OPT_DEBMEAS 0x40 /* debugging & measurement */ #define IP_OPT_COPY 0x80 /* copy into all fragments */ #define IP_OPT_RESERVED1 0x20 #define IP_OPT_RESERVED2 0x60 #define IP_OPT_EOL 0 /* end of option list */ #define IP_OPT_NOP 1 /* no operation */ #define IP_OPT_SEC (2|IP_OPT_COPY) /* DoD basic security */ #define IP_OPT_LSRR (3|IP_OPT_COPY) /* loose source route */ #define IP_OPT_TS (4|IP_OPT_DEBMEAS) /* timestamp */ #define IP_OPT_ESEC (5|IP_OPT_COPY) /* DoD extended security */ #define IP_OPT_CIPSO (6|IP_OPT_COPY) /* commercial security */ #define IP_OPT_RR 7 /* record route */ #define IP_OPT_SATID (8|IP_OPT_COPY) /* stream ID (obsolete) */ #define IP_OPT_SSRR (9|IP_OPT_COPY) /* strict source route */ #define IP_OPT_ZSU 10 /* experimental measurement */ #define IP_OPT_MTUP 11 /* MTU probe */ #define IP_OPT_MTUR 12 /* MTU reply */ #define IP_OPT_FINN (13|IP_OPT_COPY|IP_OPT_DEBMEAS) /* exp flow control */ #define IP_OPT_VISA (14|IP_OPT_COPY) /* exp access control */ #define IP_OPT_ENCODE 15 /* ??? */ #define IP_OPT_IMITD (16|IP_OPT_COPY) /* IMI traffic descriptor */ #define IP_OPT_EIP (17|IP_OPT_COPY) /* extended IP, RFC 1385 */ #define IP_OPT_TR (18|IP_OPT_DEBMEAS) /* traceroute */ #define IP_OPT_ADDEXT (19|IP_OPT_COPY) /* IPv7 ext addr, RFC 1475 */ #define IP_OPT_RTRALT (20|IP_OPT_COPY) /* router alert, RFC 2113 */ #define IP_OPT_SDB (21|IP_OPT_COPY) /* directed bcast, RFC 1770 */ #define IP_OPT_NSAPA (22|IP_OPT_COPY) /* NSAP addresses */ #define IP_OPT_DPS (23|IP_OPT_COPY) /* dynamic packet state */ #define IP_OPT_UMP (24|IP_OPT_COPY) /* upstream multicast */ #define IP_OPT_MAX 25 #define IP_OPT_COPIED(o) ((o) & 0x80) #define IP_OPT_CLASS(o) ((o) & 0x60) #define IP_OPT_NUMBER(o) ((o) & 0x1f) #define IP_OPT_TYPEONLY(o) ((o) == IP_OPT_EOL || (o) == IP_OPT_NOP) /* * Security option data - RFC 791, 3.1 */ struct ip_opt_data_sec { uint16_t s; /* security */ uint16_t c; /* compartments */ uint16_t h; /* handling restrictions */ uint8_t tcc[3]; /* transmission control code */ } __attribute__((__packed__)); #define IP_OPT_SEC_UNCLASS 0x0000 /* unclassified */ #define IP_OPT_SEC_CONFID 0xf135 /* confidential */ #define IP_OPT_SEC_EFTO 0x789a /* EFTO */ #define IP_OPT_SEC_MMMM 0xbc4d /* MMMM */ #define IP_OPT_SEC_PROG 0x5e26 /* PROG */ #define IP_OPT_SEC_RESTR 0xaf13 /* restricted */ #define IP_OPT_SEC_SECRET 0xd788 /* secret */ #define IP_OPT_SEC_TOPSECRET 0x6bc5 /* top secret */ /* * {Loose Source, Record, Strict Source} Route option data - RFC 791, 3.1 */ struct ip_opt_data_rr { uint8_t ptr; /* from start of option, >= 4 */ uint32_t iplist __flexarr; /* list of IP addresses */ } __attribute__((__packed__)); /* * Timestamp option data - RFC 791, 3.1 */ struct ip_opt_data_ts { uint8_t ptr; /* from start of option, >= 5 */ #if DNET_BYTESEX == DNET_BIG_ENDIAN uint8_t oflw:4, /* number of IPs skipped */ flg:4; /* address[ / timestamp] flag */ #elif DNET_BYTESEX == DNET_LIL_ENDIAN uint8_t flg:4, oflw:4; #endif uint32_t ipts __flexarr; /* IP address [/ timestamp] pairs */ } __attribute__((__packed__)); #define IP_OPT_TS_TSONLY 0 /* timestamps only */ #define IP_OPT_TS_TSADDR 1 /* IP address / timestamp pairs */ #define IP_OPT_TS_PRESPEC 3 /* IP address / zero timestamp pairs */ /* * Traceroute option data - RFC 1393, 2.2 */ struct ip_opt_data_tr { uint16_t id; /* ID number */ uint16_t ohc; /* outbound hop count */ uint16_t rhc; /* return hop count */ uint32_t origip; /* originator IP address */ } __attribute__((__packed__)); /* * IP option (following IP header) */ struct ip_opt { uint8_t opt_type; /* option type */ uint8_t opt_len; /* option length >= IP_OPT_LEN */ union ip_opt_data { struct ip_opt_data_sec sec; /* IP_OPT_SEC */ struct ip_opt_data_rr rr; /* IP_OPT_{L,S}RR */ struct ip_opt_data_ts ts; /* IP_OPT_TS */ uint16_t satid; /* IP_OPT_SATID */ uint16_t mtu; /* IP_OPT_MTU{P,R} */ struct ip_opt_data_tr tr; /* IP_OPT_TR */ uint32_t addext[2]; /* IP_OPT_ADDEXT */ uint16_t rtralt; /* IP_OPT_RTRALT */ uint32_t sdb[9]; /* IP_OPT_SDB */ uint8_t data8[IP_OPT_LEN_MAX - IP_OPT_LEN]; } opt_data; } __attribute__((__packed__)); #ifndef __GNUC__ # pragma pack() #endif /* * Classful addressing */ #define IP_CLASSA(i) (((uint32_t)(i) & htonl(0x80000000)) == \ htonl(0x00000000)) #define IP_CLASSA_NET (htonl(0xff000000)) #define IP_CLASSA_NSHIFT 24 #define IP_CLASSA_HOST (htonl(0x00ffffff)) #define IP_CLASSA_MAX 128 #define IP_CLASSB(i) (((uint32_t)(i) & htonl(0xc0000000)) == \ htonl(0x80000000)) #define IP_CLASSB_NET (htonl(0xffff0000)) #define IP_CLASSB_NSHIFT 16 #define IP_CLASSB_HOST (htonl(0x0000ffff)) #define IP_CLASSB_MAX 65536 #define IP_CLASSC(i) (((uint32_t)(i) & htonl(0xe0000000)) == \ htonl(0xc0000000)) #define IP_CLASSC_NET (htonl(0xffffff00)) #define IP_CLASSC_NSHIFT 8 #define IP_CLASSC_HOST (htonl(0x000000ff)) #define IP_CLASSD(i) (((uint32_t)(i) & htonl(0xf0000000)) == \ htonl(0xe0000000)) /* These ones aren't really net and host fields, but routing needn't know. */ #define IP_CLASSD_NET (htonl(0xf0000000)) #define IP_CLASSD_NSHIFT 28 #define IP_CLASSD_HOST (htonl(0x0fffffff)) #define IP_MULTICAST(i) IP_CLASSD(i) #define IP_EXPERIMENTAL(i) (((uint32_t)(i) & htonl(0xf0000000)) == \ htonl(0xf0000000)) #define IP_BADCLASS(i) (((uint32_t)(i) & htonl(0xf0000000)) == \ htonl(0xf0000000)) #define IP_LOCAL_GROUP(i) (((uint32_t)(i) & htonl(0xffffff00)) == \ htonl(0xe0000000)) /* * Reserved addresses */ #define IP_ADDR_ANY (htonl(0x00000000)) /* 0.0.0.0 */ #define IP_ADDR_BROADCAST (htonl(0xffffffff)) /* 255.255.255.255 */ #define IP_ADDR_LOOPBACK (htonl(0x7f000001)) /* 127.0.0.1 */ #define IP_ADDR_MCAST_ALL (htonl(0xe0000001)) /* 224.0.0.1 */ #define IP_ADDR_MCAST_LOCAL (htonl(0xe00000ff)) /* 224.0.0.255 */ #define ip_pack_hdr(hdr, tos, len, id, off, ttl, p, src, dst) do { \ struct ip_hdr *ip_pack_p = (struct ip_hdr *)(hdr); \ ip_pack_p->ip_v = 4; ip_pack_p->ip_hl = 5; \ ip_pack_p->ip_tos = tos; ip_pack_p->ip_len = htons(len); \ ip_pack_p->ip_id = htons(id); ip_pack_p->ip_off = htons(off); \ ip_pack_p->ip_ttl = ttl; ip_pack_p->ip_p = p; \ ip_pack_p->ip_src = src; ip_pack_p->ip_dst = dst; \ } while (0) typedef struct ip_handle ip_t; __BEGIN_DECLS ip_t *ip_open(void); ssize_t ip_send(ip_t *i, const void *buf, size_t len); ip_t *ip_close(ip_t *i); char *ip_ntop(const ip_addr_t *ip, char *dst, size_t len); int ip_pton(const char *src, ip_addr_t *dst); char *ip_ntoa(const ip_addr_t *ip); #define ip_aton ip_pton ssize_t ip_add_option(void *buf, size_t len, int proto, const void *optbuf, size_t optlen); void ip_checksum(void *buf, size_t len); int ip_cksum_add(const void *buf, size_t len, int cksum); #define ip_cksum_carry(x) \ (x = (x >> 16) + (x & 0xffff), (~(x + (x >> 16)) & 0xffff)) __END_DECLS #endif /* DNET_IP_H */ snort-2.9.15.1/src/win32/WIN32-Includes/libdnet/dnet/ip6.h0000644000175200017520000001255013571422610017366 00000000000000/* * ip6.h * * Internet Protocol, Version 6 (RFC 2460). * * Copyright (c) 2002 Dug Song * * $Id$ */ #ifndef DNET_IP6_H #define DNET_IP6_H #define IP6_ADDR_LEN 16 #define IP6_ADDR_BITS 128 #define IP6_HDR_LEN 40 /* IPv6 header length */ #define IP6_LEN_MIN IP6_HDR_LEN #define IP6_LEN_MAX 65535 /* non-jumbo payload */ #define IP6_MTU_MIN 1280 /* minimum MTU (1024 + 256) */ typedef struct ip6_addr { uint8_t data[IP6_ADDR_LEN]; } ip6_addr_t; #ifndef __GNUC__ # define __attribute__(x) # pragma pack(1) #endif /* * IPv6 header */ struct ip6_hdr { union { struct ip6_hdr_ctl { uint32_t ip6_un1_flow; /* 20 bits of flow ID */ uint16_t ip6_un1_plen; /* payload length */ uint8_t ip6_un1_nxt; /* next header */ uint8_t ip6_un1_hlim; /* hop limit */ } ip6_un1; uint8_t ip6_un2_vfc; /* 4 bits version, top 4 bits class */ } ip6_ctlun; ip6_addr_t ip6_src; ip6_addr_t ip6_dst; } __attribute__((__packed__)); #define ip6_vfc ip6_ctlun.ip6_un2_vfc #define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow #define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen #define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt /* IP_PROTO_* */ #define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim #define IP6_VERSION 0x60 #define IP6_VERSION_MASK 0xf0 /* ip6_vfc version */ #if DNET_BYTESEX == DNET_BIG_ENDIAN #define IP6_FLOWINFO_MASK 0x0fffffff /* ip6_flow info (28 bits) */ #define IP6_FLOWLABEL_MASK 0x000fffff /* ip6_flow label (20 bits) */ #elif DNET_BYTESEX == DNET_LIL_ENDIAN #define IP6_FLOWINFO_MASK 0xffffff0f /* ip6_flow info (28 bits) */ #define IP6_FLOWLABEL_MASK 0xffff0f00 /* ip6_flow label (20 bits) */ #endif /* * Hop limit (ip6_hlim) */ #define IP6_HLIM_DEFAULT 64 #define IP6_HLIM_MAX 255 /* * Preferred extension header order from RFC 2460, 4.1: * * IP_PROTO_IPV6, IP_PROTO_HOPOPTS, IP_PROTO_DSTOPTS, IP_PROTO_ROUTING, * IP_PROTO_FRAGMENT, IP_PROTO_AH, IP_PROTO_ESP, IP_PROTO_DSTOPTS, IP_PROTO_* */ /* * Routing header data (IP_PROTO_ROUTING) */ struct ip6_ext_data_routing { uint8_t type; /* routing type */ uint8_t segleft; /* segments left */ /* followed by routing type specific data */ } __attribute__((__packed__)); struct ip6_ext_data_routing0 { uint8_t type; /* always zero */ uint8_t segleft; /* segments left */ uint8_t reserved; /* reserved field */ uint8_t slmap[3]; /* strict/loose bit map */ ip6_addr_t addr[1]; /* up to 23 addresses */ } __attribute__((__packed__)); /* * Fragment header data (IP_PROTO_FRAGMENT) */ struct ip6_ext_data_fragment { uint16_t offlg; /* offset, reserved, and flag */ uint32_t ident; /* identification */ } __attribute__((__packed__)); /* * Fragmentation offset, reserved, and flags (offlg) */ #if DNET_BYTESEX == DNET_BIG_ENDIAN #define IP6_OFF_MASK 0xfff8 /* mask out offset from offlg */ #define IP6_RESERVED_MASK 0x0006 /* reserved bits in offlg */ #define IP6_MORE_FRAG 0x0001 /* more-fragments flag */ #elif DNET_BYTESEX == DNET_LIL_ENDIAN #define IP6_OFF_MASK 0xf8ff /* mask out offset from offlg */ #define IP6_RESERVED_MASK 0x0600 /* reserved bits in offlg */ #define IP6_MORE_FRAG 0x0100 /* more-fragments flag */ #endif /* * Option types, for IP_PROTO_HOPOPTS, IP_PROTO_DSTOPTS headers */ #define IP6_OPT_PAD1 0x00 /* 00 0 00000 */ #define IP6_OPT_PADN 0x01 /* 00 0 00001 */ #define IP6_OPT_JUMBO 0xC2 /* 11 0 00010 = 194 */ #define IP6_OPT_JUMBO_LEN 6 #define IP6_OPT_RTALERT 0x05 /* 00 0 00101 */ #define IP6_OPT_RTALERT_LEN 4 #define IP6_OPT_RTALERT_MLD 0 /* Datagram contains an MLD message */ #define IP6_OPT_RTALERT_RSVP 1 /* Datagram contains an RSVP message */ #define IP6_OPT_RTALERT_ACTNET 2 /* contains an Active Networks msg */ #define IP6_OPT_LEN_MIN 2 #define IP6_OPT_TYPE(o) ((o) & 0xC0) /* high 2 bits of opt_type */ #define IP6_OPT_TYPE_SKIP 0x00 /* continue processing on failure */ #define IP6_OPT_TYPE_DISCARD 0x40 /* discard packet on failure */ #define IP6_OPT_TYPE_FORCEICMP 0x80 /* discard and send ICMP on failure */ #define IP6_OPT_TYPE_ICMP 0xC0 /* ...only if non-multicast dst */ #define IP6_OPT_MUTABLE 0x20 /* option data may change en route */ /* * Extension header (chained via {ip6,ext}_nxt, following IPv6 header) */ struct ip6_ext_hdr { uint8_t ext_nxt; /* next header */ uint8_t ext_len; /* following length in units of 8 octets */ union { struct ip6_ext_data_routing routing; struct ip6_ext_data_fragment fragment; } ext_data; } __attribute__((__packed__)); #ifndef __GNUC__ # pragma pack() #endif /* * Reserved addresses */ #define IP6_ADDR_UNSPEC \ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" #define IP6_ADDR_LOOPBACK \ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" #define ip6_pack_hdr(hdr, fc, fl, plen, nxt, hlim, src, dst) do { \ struct ip6_hdr *ip6 = (struct ip6_hdr *)(hdr); \ ip6->ip6_flow = htonl(((uint32_t)(fc) << 28) & \ (IP6_FLOWLABEL_MASK | (fl))); \ ip6->ip6_vfc = (IP6_VERSION | ((fc) >> 4)); \ ip6->ip6_plen = htons((plen)); \ ip6->ip6_nxt = (nxt); ip6->ip6_hlim = (hlim); \ memmove(&ip6->ip6_src, &(src), IP6_ADDR_LEN); \ memmove(&ip6->ip6_dst, &(dst), IP6_ADDR_LEN); \ } while (0); __BEGIN_DECLS char *ip6_ntop(const ip6_addr_t *ip6, char *dst, size_t size); int ip6_pton(const char *src, ip6_addr_t *dst); char *ip6_ntoa(const ip6_addr_t *ip6); #define ip6_aton ip6_pton void ip6_checksum(void *buf, size_t len); __END_DECLS #endif /* DNET_IP6_H */ snort-2.9.15.1/src/win32/WIN32-Includes/libdnet/dnet/os.h0000644000175200017520000000623113571422610017310 00000000000000/* * os.h * * Sleazy OS-specific defines. * * Copyright (c) 2000 Dug Song * * $Id$ */ #ifndef DNET_OS_H #define DNET_OS_H #ifdef _WIN32 # include # include /* XXX */ # undef IP_OPT_LSRR # undef IP_OPT_TS # undef IP_OPT_RR # undef IP_OPT_SSRR #if !defined(UINT8_T_DEFINED) typedef u_char uint8_t; #endif #if !defined(UINT16_T_DEFINED) typedef u_short uint16_t; #endif #if !defined(UINT32_T_DEFINED) typedef u_int uint32_t; #endif # ifndef __CYGWIN__ typedef long ssize_t; # endif #else # include # include # include # include # include # include # ifdef __bsdi__ # include typedef u_int8_t uint8_t; typedef u_int16_t uint16_t; typedef u_int32_t uint32_t; typedef u_int64_t uint64_t; # else # include # endif #endif #define DNET_LIL_ENDIAN 1234 #define DNET_BIG_ENDIAN 4321 /* BSD and IRIX */ #ifdef BYTE_ORDER #if BYTE_ORDER == LITTLE_ENDIAN # define DNET_BYTESEX DNET_LIL_ENDIAN #elif BYTE_ORDER == BIG_ENDIAN # define DNET_BYTESEX DNET_BIG_ENDIAN #endif #endif /* Linux */ #ifdef __BYTE_ORDER #if __BYTE_ORDER == __LITTLE_ENDIAN # define DNET_BYTESEX DNET_LIL_ENDIAN #elif __BYTE_ORDER == __BIG_ENDIAN # define DNET_BYTESEX DNET_BIG_ENDIAN #endif #endif /* Solaris */ #if defined(_BIT_FIELDS_LTOH) # define DNET_BYTESEX DNET_LIL_ENDIAN #elif defined (_BIT_FIELDS_HTOL) # define DNET_BYTESEX DNET_BIG_ENDIAN #endif /* Win32 - XXX */ #ifdef _WIN32 # define DNET_BYTESEX DNET_LIL_ENDIAN #endif /* Nastiness from old BIND code. */ #ifndef DNET_BYTESEX # if defined(vax) || defined(ns32000) || defined(sun386) || defined(i386) || \ defined(MIPSEL) || defined(_MIPSEL) || defined(BIT_ZERO_ON_RIGHT) || \ defined(__alpha__) || defined(__alpha) # define DNET_BYTESEX DNET_LIL_ENDIAN # elif defined(sel) || defined(pyr) || defined(mc68000) || defined(sparc) || \ defined(is68k) || defined(tahoe) || defined(ibm032) || defined(ibm370) || \ defined(MIPSEB) || defined(_MIPSEB) || defined(_IBMR2) || defined(DGUX) ||\ defined(apollo) || defined(__convex__) || defined(_CRAY) || \ defined(__hppa) || defined(__hp9000) || \ defined(__hp9000s300) || defined(__hp9000s700) || defined(__ia64) || \ defined (BIT_ZERO_ON_LEFT) || defined(m68k) # define DNET_BYTESEX DNET_BIG_ENDIAN # else # error "bytesex unknown" # endif #endif /* C++ support. */ #undef __BEGIN_DECLS #undef __END_DECLS #ifdef __cplusplus # define __BEGIN_DECLS extern "C" { # define __END_DECLS } /* extern "C" */ #else # define __BEGIN_DECLS # define __END_DECLS #endif /* Support for flexible arrays. */ #undef __flexarr #if defined(__GNUC__) && ((__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)) /* GCC 2.97 supports C99 flexible array members. */ # define __flexarr [] #else # ifdef __GNUC__ # define __flexarr [0] # else # if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L # define __flexarr [] # elif defined(_WIN32) /* MS VC++ */ # define __flexarr [] # else /* Some other non-C99 compiler. Approximate with [1]. */ # define __flexarr [1] # endif # endif #endif #endif /* DNET_OS_H */ snort-2.9.15.1/src/win32/WIN32-Includes/libdnet/dnet/rand.h0000644000175200017520000000132413571422610017611 00000000000000/* * rand.h * * Pseudo-random number generation, based on OpenBSD arc4random(). * * Copyright (c) 2000 Dug Song * Copyright (c) 1996 David Mazieres * * $Id$ */ #ifndef DNET_RAND_H #define DNET_RAND_H typedef struct rand_handle rand_t; __BEGIN_DECLS rand_t *rand_open(void); int rand_get(rand_t *r, void *buf, size_t len); int rand_set(rand_t *r, const void *seed, size_t len); int rand_add(rand_t *r, const void *buf, size_t len); uint8_t rand_uint8(rand_t *r); uint16_t rand_uint16(rand_t *r); uint32_t rand_uint32(rand_t *r); int rand_shuffle(rand_t *r, void *base, size_t nmemb, size_t size); rand_t *rand_close(rand_t *r); __END_DECLS #endif /* DNET_RAND_H */ snort-2.9.15.1/src/win32/WIN32-Includes/libdnet/dnet/route.h0000644000175200017520000000142213571422610020022 00000000000000/* * route.c * * Kernel route table operations. * * Copyright (c) 2000 Dug Song * * $Id$ */ #ifndef DNET_ROUTE_H #define DNET_ROUTE_H /* * Routing table entry */ struct route_entry { struct addr route_dst; /* destination address */ struct addr route_gw; /* gateway address */ }; typedef struct route_handle route_t; typedef int (*route_handler)(const struct route_entry *entry, void *arg); __BEGIN_DECLS route_t *route_open(void); int route_add(route_t *r, const struct route_entry *entry); int route_delete(route_t *r, const struct route_entry *entry); int route_get(route_t *r, struct route_entry *entry); int route_loop(route_t *r, route_handler callback, void *arg); route_t *route_close(route_t *r); __END_DECLS #endif /* DNET_ROUTE_H */ snort-2.9.15.1/src/win32/WIN32-Includes/libdnet/dnet/tcp.h0000644000175200017520000001211313571422610017451 00000000000000/* * tcp.h * * Transmission Control Protocol (RFC 793). * * Copyright (c) 2000 Dug Song * * $Id$ */ #ifndef DNET_TCP_H #define DNET_TCP_H #define TCP_HDR_LEN 20 /* base TCP header length */ #define TCP_OPT_LEN 2 /* base TCP option length */ #define TCP_OPT_LEN_MAX 40 #define TCP_HDR_LEN_MAX (TCP_HDR_LEN + TCP_OPT_LEN_MAX) #ifndef __GNUC__ # define __attribute__(x) # pragma pack(1) #endif /* * TCP header, without options */ struct tcp_hdr { uint16_t th_sport; /* source port */ uint16_t th_dport; /* destination port */ uint32_t th_seq; /* sequence number */ uint32_t th_ack; /* acknowledgment number */ #if DNET_BYTESEX == DNET_BIG_ENDIAN uint8_t th_off:4, /* data offset */ th_x2:4; /* (unused) */ #elif DNET_BYTESEX == DNET_LIL_ENDIAN uint8_t th_x2:4, th_off:4; #else # error "need to include " #endif uint8_t th_flags; /* control flags */ uint16_t th_win; /* window */ uint16_t th_sum; /* checksum */ uint16_t th_urp; /* urgent pointer */ }; /* * TCP control flags (th_flags) */ #define TH_FIN 0x01 /* end of data */ #define TH_SYN 0x02 /* synchronize sequence numbers */ #define TH_RST 0x04 /* reset connection */ #define TH_PUSH 0x08 /* push */ #define TH_ACK 0x10 /* acknowledgment number set */ #define TH_URG 0x20 /* urgent pointer set */ #define TH_ECE 0x40 /* ECN echo, RFC 3168 */ #define TH_CWR 0x80 /* congestion window reduced */ #define TCP_PORT_MAX 65535 /* maximum port */ #define TCP_WIN_MAX 65535 /* maximum (unscaled) window */ /* * Sequence number comparison macros */ #define TCP_SEQ_LT(a,b) ((int)((a)-(b)) < 0) #define TCP_SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0) #define TCP_SEQ_GT(a,b) ((int)((a)-(b)) > 0) #define TCP_SEQ_GEQ(a,b) ((int)((a)-(b)) >= 0) /* * TCP FSM states */ #define TCP_STATE_CLOSED 0 /* closed */ #define TCP_STATE_LISTEN 1 /* listening from connection */ #define TCP_STATE_SYN_SENT 2 /* active, have sent SYN */ #define TCP_STATE_SYN_RECEIVED 3 /* have sent and received SYN */ #define TCP_STATE_ESTABLISHED 4 /* established */ #define TCP_STATE_CLOSE_WAIT 5 /* rcvd FIN, waiting for close */ #define TCP_STATE_FIN_WAIT_1 6 /* have closed, sent FIN */ #define TCP_STATE_CLOSING 7 /* closed xchd FIN, await FIN-ACK */ #define TCP_STATE_LAST_ACK 8 /* had FIN and close, await FIN-ACK */ #define TCP_STATE_FIN_WAIT_2 9 /* have closed, FIN is acked */ #define TCP_STATE_TIME_WAIT 10 /* in 2*MSL quiet wait after close */ #define TCP_STATE_MAX 11 /* * Options (opt_type) - http://www.iana.org/assignments/tcp-parameters */ #define TCP_OPT_EOL 0 /* end of option list */ #define TCP_OPT_NOP 1 /* no operation */ #define TCP_OPT_MSS 2 /* maximum segment size */ #define TCP_OPT_WSCALE 3 /* window scale factor, RFC 1072 */ #define TCP_OPT_SACKOK 4 /* SACK permitted, RFC 2018 */ #define TCP_OPT_SACK 5 /* SACK, RFC 2018 */ #define TCP_OPT_ECHO 6 /* echo (obsolete), RFC 1072 */ #define TCP_OPT_ECHOREPLY 7 /* echo reply (obsolete), RFC 1072 */ #define TCP_OPT_TIMESTAMP 8 /* timestamp, RFC 1323 */ #define TCP_OPT_POCONN 9 /* partial order conn, RFC 1693 */ #define TCP_OPT_POSVC 10 /* partial order service, RFC 1693 */ #define TCP_OPT_CC 11 /* connection count, RFC 1644 */ #define TCP_OPT_CCNEW 12 /* CC.NEW, RFC 1644 */ #define TCP_OPT_CCECHO 13 /* CC.ECHO, RFC 1644 */ #define TCP_OPT_ALTSUM 14 /* alt checksum request, RFC 1146 */ #define TCP_OPT_ALTSUMDATA 15 /* alt checksum data, RFC 1146 */ #define TCP_OPT_SKEETER 16 /* Skeeter */ #define TCP_OPT_BUBBA 17 /* Bubba */ #define TCP_OPT_TRAILSUM 18 /* trailer checksum */ #define TCP_OPT_MD5 19 /* MD5 signature, RFC 2385 */ #define TCP_OPT_SCPS 20 /* SCPS capabilities */ #define TCP_OPT_SNACK 21 /* selective negative acks */ #define TCP_OPT_REC 22 /* record boundaries */ #define TCP_OPT_CORRUPT 23 /* corruption experienced */ #define TCP_OPT_SNAP 24 /* SNAP */ #define TCP_OPT_TCPCOMP 26 /* TCP compression filter */ #define TCP_OPT_MAX 27 #define TCP_OPT_TYPEONLY(type) \ ((type) == TCP_OPT_EOL || (type) == TCP_OPT_NOP) /* * TCP option (following TCP header) */ struct tcp_opt { uint8_t opt_type; /* option type */ uint8_t opt_len; /* option length >= TCP_OPT_LEN */ union tcp_opt_data { uint16_t mss; /* TCP_OPT_MSS */ uint8_t wscale; /* TCP_OPT_WSCALE */ uint16_t sack[19]; /* TCP_OPT_SACK */ uint32_t echo; /* TCP_OPT_ECHO{REPLY} */ uint32_t timestamp[2]; /* TCP_OPT_TIMESTAMP */ uint32_t cc; /* TCP_OPT_CC{NEW,ECHO} */ uint8_t cksum; /* TCP_OPT_ALTSUM */ uint8_t md5[16]; /* TCP_OPT_MD5 */ uint8_t data8[TCP_OPT_LEN_MAX - TCP_OPT_LEN]; } opt_data; } __attribute__((__packed__)); #ifndef __GNUC__ # pragma pack() #endif #define tcp_pack_hdr(hdr, sport, dport, seq, ack, flags, win, urp) do { \ struct tcp_hdr *tcp_pack_p = (struct tcp_hdr *)(hdr); \ tcp_pack_p->th_sport = htons(sport); \ tcp_pack_p->th_dport = htons(dport); \ tcp_pack_p->th_seq = htonl(seq); \ tcp_pack_p->th_ack = htonl(ack); \ tcp_pack_p->th_x2 = 0; tcp_pack_p->th_off = 5; \ tcp_pack_p->th_flags = flags; \ tcp_pack_p->th_win = htons(win); \ tcp_pack_p->th_urp = htons(urp); \ } while (0) #endif /* DNET_TCP_H */ snort-2.9.15.1/src/win32/WIN32-Includes/libdnet/dnet/tun.h0000644000175200017520000000100313571422610017465 00000000000000/* * tun.h * * Network tunnel device. * * Copyright (c) 2001 Dug Song * * $Id$ */ #ifndef DNET_TUN_H #define DNET_TUN_H typedef struct tun tun_t; __BEGIN_DECLS tun_t *tun_open(struct addr *src, struct addr *dst, int mtu); int tun_fileno(tun_t *tun); const char *tun_name(tun_t *tun); ssize_t tun_send(tun_t *tun, const void *buf, size_t size); ssize_t tun_recv(tun_t *tun, void *buf, size_t size); tun_t *tun_close(tun_t *tun); __END_DECLS #endif /* DNET_TUN_H */ snort-2.9.15.1/src/win32/WIN32-Includes/libdnet/dnet/udp.h0000644000175200017520000000125013571422610017453 00000000000000/* * udp.h * * User Datagram Protocol (RFC 768). * * Copyright (c) 2000 Dug Song * * $Id$ */ #ifndef DNET_UDP_H #define DNET_UDP_H #define UDP_HDR_LEN 8 struct udp_hdr { uint16_t uh_sport; /* source port */ uint16_t uh_dport; /* destination port */ uint16_t uh_ulen; /* udp length (including header) */ uint16_t uh_sum; /* udp checksum */ }; #define UDP_PORT_MAX 65535 #define udp_pack_hdr(hdr, sport, dport, ulen) do { \ struct udp_hdr *udp_pack_p = (struct udp_hdr *)(hdr); \ udp_pack_p->uh_sport = htons(sport); \ udp_pack_p->uh_dport = htons(dport); \ udp_pack_p->uh_ulen = htons(ulen); \ } while (0) #endif /* DNET_UDP_H */ snort-2.9.15.1/src/win32/WIN32-Includes/libdnet/dnet.h0000644000175200017520000000073113571422610016666 00000000000000/* * dnet.h * * Copyright (c) 2001 Dug Song * * $Id$ */ #ifndef DNET_H #define DNET_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #endif /* DNET_H */ snort-2.9.15.1/src/win32/WIN32-Includes/rpc/0000755000000000000000000000000013571426520014753 500000000000000snort-2.9.15.1/src/win32/WIN32-Includes/rpc/auth.h0000644000175200017520000001265213571422610016045 00000000000000/* $Id$ */ /* $OpenBSD: auth.h,v 1.2 1997/09/21 10:46:09 niklas Exp $ */ /* $NetBSD: auth.h,v 1.7 1995/04/29 05:27:55 cgd Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 * * from: @(#)auth.h 1.17 88/02/08 SMI * @(#)auth.h 2.3 88/08/07 4.0 RPCSRC */ /* * auth.h, Authentication interface. * * Copyright (C) 1984, Sun Microsystems, Inc. * * The data structures are completely opaque to the client. The client * is required to pass a AUTH * to routines that create rpc * "sessions". */ #ifndef _RPC_AUTH_H #define _RPC_AUTH_H #ifndef WIN32 #include #endif #define MAX_AUTH_BYTES 400 #define MAXNETNAMELEN 255 /* maximum length of network user's name */ /* * Status returned from authentication check */ enum auth_stat { AUTH_OK=0, /* * failed at remote end */ AUTH_BADCRED=1, /* bogus credentials (seal broken) */ AUTH_REJECTEDCRED=2, /* client should begin new session */ AUTH_BADVERF=3, /* bogus verifier (seal broken) */ AUTH_REJECTEDVERF=4, /* verifier expired or was replayed */ AUTH_TOOWEAK=5, /* rejected due to security reasons */ /* * failed locally */ AUTH_INVALIDRESP=6, /* bogus response verifier */ AUTH_FAILED=7 /* some unknown reason */ }; #ifdef WIN32 /* This is now located in */ /*typedef unsigned int u_int32;*/ /* 32-bit unsigned integers */ #include #else /*typedef u_int32_t u_int32;*/ /* 32-bit unsigned integers */ #endif union des_block { struct { u_int32 high; u_int32 low; } key; char c[8]; }; typedef union des_block des_block; __BEGIN_DECLS extern bool_t xdr_des_block __P((XDR *, des_block *)); __END_DECLS /* * Authentication info. Opaque to client. */ struct opaque_auth { enum_t oa_flavor; /* flavor of auth */ caddr_t oa_base; /* address of more auth stuff */ u_int oa_length; /* not to exceed MAX_AUTH_BYTES */ }; /* * Auth handle, interface to client side authenticators. */ typedef struct __rpc_auth { struct opaque_auth ah_cred; struct opaque_auth ah_verf; union des_block ah_key; struct auth_ops { void (*ah_nextverf) __P((struct __rpc_auth *)); /* nextverf & serialize */ int (*ah_marshal) __P((struct __rpc_auth *, XDR *)); /* validate varifier */ int (*ah_validate) __P((struct __rpc_auth *, struct opaque_auth *)); /* refresh credentials */ int (*ah_refresh) __P((struct __rpc_auth *)); /* destroy this structure */ void (*ah_destroy) __P((struct __rpc_auth *)); } *ah_ops; caddr_t ah_private; } AUTH; /* * Authentication ops. * The ops and the auth handle provide the interface to the authenticators. * * AUTH *auth; * XDR *xdrs; * struct opaque_auth verf; */ #define AUTH_NEXTVERF(auth) \ ((*((auth)->ah_ops->ah_nextverf))(auth)) #define auth_nextverf(auth) \ ((*((auth)->ah_ops->ah_nextverf))(auth)) #define AUTH_MARSHALL(auth, xdrs) \ ((*((auth)->ah_ops->ah_marshal))(auth, xdrs)) #define auth_marshall(auth, xdrs) \ ((*((auth)->ah_ops->ah_marshal))(auth, xdrs)) #define AUTH_VALIDATE(auth, verfp) \ ((*((auth)->ah_ops->ah_validate))((auth), verfp)) #define auth_validate(auth, verfp) \ ((*((auth)->ah_ops->ah_validate))((auth), verfp)) #define AUTH_REFRESH(auth) \ ((*((auth)->ah_ops->ah_refresh))(auth)) #define auth_refresh(auth) \ ((*((auth)->ah_ops->ah_refresh))(auth)) #define AUTH_DESTROY(auth) \ ((*((auth)->ah_ops->ah_destroy))(auth)) #define auth_destroy(auth) \ ((*((auth)->ah_ops->ah_destroy))(auth)) extern struct opaque_auth _null_auth; /* * These are the various implementations of client side authenticators. */ /* * Unix style authentication * AUTH *authunix_create(machname, uid, gid, len, aup_gids) * char *machname; * int uid; * int gid; * int len; * int *aup_gids; */ __BEGIN_DECLS struct sockaddr_in; extern AUTH *authunix_create __P((char *, int, int, int, int *)); extern AUTH *authunix_create_default __P((void)); extern AUTH *authnone_create __P((void)); extern AUTH *authdes_create __P((char *, u_int, struct sockaddr_in *, des_block *)); __END_DECLS #define AUTH_NONE 0 /* no authentication */ #define AUTH_NULL 0 /* backward compatibility */ #define AUTH_UNIX 1 /* unix style (uid, gids) */ #define AUTH_SHORT 2 /* short hand unix style */ #define AUTH_DES 3 /* des style (encrypted timestamps) */ #endif /* !_RPC_AUTH_H */ snort-2.9.15.1/src/win32/WIN32-Includes/rpc/auth_unix.h0000644000175200017520000000520613571422610017105 00000000000000/* $Id$ */ /* $OpenBSD: auth_unix.h,v 1.2 1997/09/21 10:46:09 niklas Exp $ */ /* $NetBSD: auth_unix.h,v 1.4 1994/10/26 00:56:56 cgd Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 * * from: @(#)auth_unix.h 1.8 88/02/08 SMI * @(#)auth_unix.h 2.2 88/07/29 4.0 RPCSRC */ /* * auth_unix.h, Protocol for UNIX style authentication parameters for RPC * * Copyright (C) 1984, Sun Microsystems, Inc. */ /* * The system is very weak. The client uses no encryption for it * credentials and only sends null verifiers. The server sends backs * null verifiers or optionally a verifier that suggests a new short hand * for the credentials. */ #ifndef _RPC_AUTH_UNIX_H #define _RPC_AUTH_UNIX_H #include /* The machine name is part of a credential; it may not exceed 255 bytes */ #define MAX_MACHINE_NAME 255 /* gids compose part of a credential; there may not be more than 16 of them */ #define NGRPS 16 /* * Unix style credentials. */ struct authunix_parms { u_long aup_time; char *aup_machname; int aup_uid; int aup_gid; u_int aup_len; int *aup_gids; }; __BEGIN_DECLS extern bool_t xdr_authunix_parms __P((XDR *, struct authunix_parms *)); __END_DECLS /* * If a response verifier has flavor AUTH_SHORT, * then the body of the response verifier encapsulates the following structure; * again it is serialized in the obvious fashion. */ struct short_hand_verf { struct opaque_auth new_cred; }; #endif /* !_RPC_AUTH_UNIX_H */ snort-2.9.15.1/src/win32/WIN32-Includes/rpc/clnt.h0000644000175200017520000002327713571422610016051 00000000000000/* $Id$ */ /* $OpenBSD: clnt.h,v 1.4 1998/03/19 00:27:17 millert Exp $ */ /* $NetBSD: clnt.h,v 1.6 1995/04/29 05:27:58 cgd Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 * * from: @(#)clnt.h 1.31 88/02/08 SMI * @(#)clnt.h 2.1 88/07/29 4.0 RPCSRC */ /* * clnt.h - Client side remote procedure call interface. * * Copyright (C) 1984, Sun Microsystems, Inc. */ #ifndef _RPC_CLNT_H_ #define _RPC_CLNT_H_ #ifndef WIN32 #include #endif /* * Rpc calls return an enum clnt_stat. This should be looked at more, * since each implementation is required to live with this (implementation * independent) list of errors. */ enum clnt_stat { RPC_SUCCESS=0, /* call succeeded */ /* * local errors */ RPC_CANTENCODEARGS=1, /* can't encode arguments */ RPC_CANTDECODERES=2, /* can't decode results */ RPC_CANTSEND=3, /* failure in sending call */ RPC_CANTRECV=4, /* failure in receiving result */ RPC_TIMEDOUT=5, /* call timed out */ /* * remote errors */ RPC_VERSMISMATCH=6, /* rpc versions not compatible */ RPC_AUTHERROR=7, /* authentication error */ RPC_PROGUNAVAIL=8, /* program not available */ RPC_PROGVERSMISMATCH=9, /* program version mismatched */ RPC_PROCUNAVAIL=10, /* procedure unavailable */ RPC_CANTDECODEARGS=11, /* decode arguments error */ RPC_SYSTEMERROR=12, /* generic "other problem" */ /* * callrpc & clnt_create errors */ RPC_UNKNOWNHOST=13, /* unknown host name */ RPC_UNKNOWNPROTO=17, /* unkown protocol */ /* * _ create errors */ RPC_PMAPFAILURE=14, /* the pmapper failed in its call */ RPC_PROGNOTREGISTERED=15, /* remote program is not registered */ /* * unspecified error */ RPC_FAILED=16 }; /* * Error info. */ struct rpc_err { enum clnt_stat re_status; union { int RE_errno; /* realated system error */ enum auth_stat RE_why; /* why the auth error occurred */ struct { u_int32_t low; /* lowest verion supported */ u_int32_t high; /* highest verion supported */ } RE_vers; struct { /* maybe meaningful if RPC_FAILED */ int32_t s1; int32_t s2; } RE_lb; /* life boot & debugging only */ } ru; #define re_errno ru.RE_errno #define re_why ru.RE_why #define re_vers ru.RE_vers #define re_lb ru.RE_lb }; /* * Client rpc handle. * Created by individual implementations, see e.g. rpc_udp.c. * Client is responsible for initializing auth, see e.g. auth_none.c. */ typedef struct __rpc_client { AUTH *cl_auth; /* authenticator */ struct clnt_ops { /* call remote procedure */ enum clnt_stat (*cl_call) __P((struct __rpc_client *, u_long, xdrproc_t, caddr_t, xdrproc_t, caddr_t, struct timeval)); /* abort a call */ void (*cl_abort) __P((struct __rpc_client *)); /* get specific error code */ void (*cl_geterr) __P((struct __rpc_client *, struct rpc_err *)); /* frees results */ bool_t (*cl_freeres) __P((struct __rpc_client *, xdrproc_t, caddr_t)); /* destroy this structure */ void (*cl_destroy) __P((struct __rpc_client *)); /* the ioctl() of rpc */ bool_t (*cl_control) __P((struct __rpc_client *, u_int, void *)); } *cl_ops; caddr_t cl_private; /* private stuff */ } CLIENT; /* * client side rpc interface ops * * Parameter types are: * */ /* * enum clnt_stat * CLNT_CALL(rh, proc, xargs, argsp, xres, resp, timeout) * CLIENT *rh; * u_long proc; * xdrproc_t xargs; * caddr_t argsp; * xdrproc_t xres; * caddr_t resp; * struct timeval timeout; */ #define CLNT_CALL(rh, proc, xargs, argsp, xres, resp, secs) \ ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, (caddr_t)argsp, \ xres, (caddr_t)resp, secs)) #define clnt_call(rh, proc, xargs, argsp, xres, resp, secs) \ ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, (caddr_t)argsp, \ xres, (caddr_t)resp, secs)) /* * void * CLNT_ABORT(rh); * CLIENT *rh; */ #define CLNT_ABORT(rh) ((*(rh)->cl_ops->cl_abort)(rh)) #define clnt_abort(rh) ((*(rh)->cl_ops->cl_abort)(rh)) /* * struct rpc_err * CLNT_GETERR(rh); * CLIENT *rh; */ #define CLNT_GETERR(rh,errp) ((*(rh)->cl_ops->cl_geterr)(rh, errp)) #define clnt_geterr(rh,errp) ((*(rh)->cl_ops->cl_geterr)(rh, errp)) /* * bool_t * CLNT_FREERES(rh, xres, resp); * CLIENT *rh; * xdrproc_t xres; * caddr_t resp; */ #define CLNT_FREERES(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp)) #define clnt_freeres(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp)) /* * bool_t * CLNT_CONTROL(cl, request, info) * CLIENT *cl; * u_int request; * char *info; */ #define CLNT_CONTROL(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in)) #define clnt_control(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in)) /* * control operations that apply to both udp and tcp transports */ #define CLSET_TIMEOUT 1 /* set timeout (timeval) */ #define CLGET_TIMEOUT 2 /* get timeout (timeval) */ #define CLGET_SERVER_ADDR 3 /* get server's address (sockaddr) */ /* * udp only control operations */ #define CLSET_RETRY_TIMEOUT 4 /* set retry timeout (timeval) */ #define CLGET_RETRY_TIMEOUT 5 /* get retry timeout (timeval) */ /* * void * CLNT_DESTROY(rh); * CLIENT *rh; */ #define CLNT_DESTROY(rh) ((*(rh)->cl_ops->cl_destroy)(rh)) #define clnt_destroy(rh) ((*(rh)->cl_ops->cl_destroy)(rh)) /* * RPCTEST is a test program which is accessable on every rpc * transport/port. It is used for testing, performance evaluation, * and network administration. */ #define RPCTEST_PROGRAM ((u_long)1) #define RPCTEST_VERSION ((u_long)1) #define RPCTEST_NULL_PROC ((u_long)2) #define RPCTEST_NULL_BATCH_PROC ((u_long)3) /* * By convention, procedure 0 takes null arguments and returns them */ #define NULLPROC ((u_int)0) /* * Below are the client handle creation routines for the various * implementations of client side rpc. They can return NULL if a * creation failure occurs. */ /* * Memory based rpc (for speed check and testing) * CLIENT * * clntraw_create(prog, vers) * u_long prog; * u_long vers; */ __BEGIN_DECLS extern CLIENT *clntraw_create __P((u_long, u_long)); __END_DECLS /* * Generic client creation routine. Supported protocols are "udp" and "tcp" * CLIENT * * clnt_create(host, prog, vers, prot); * char *host; -- hostname * u_long prog; -- program number * u_long vers; -- version number * char *prot; -- protocol */ __BEGIN_DECLS extern CLIENT *clnt_create __P((char *, u_long, u_long, char *)); __END_DECLS /* * TCP based rpc * CLIENT * * clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz) * struct sockaddr_in *raddr; * u_long prog; * u_long version; * register int *sockp; * u_int sendsz; * u_int recvsz; */ __BEGIN_DECLS extern CLIENT *clnttcp_create __P((struct sockaddr_in *, u_long, u_long, int *, u_int, u_int)); __END_DECLS /* * UDP based rpc. * CLIENT * * clntudp_create(raddr, program, version, wait, sockp) * struct sockaddr_in *raddr; * u_long program; * u_long version; * struct timeval wait; * int *sockp; * * Same as above, but you specify max packet sizes. * CLIENT * * clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz) * struct sockaddr_in *raddr; * u_long program; * u_long version; * struct timeval wait; * int *sockp; * u_int sendsz; * u_int recvsz; */ __BEGIN_DECLS extern CLIENT *clntudp_create __P((struct sockaddr_in *, u_long, u_long, struct timeval, int *)); extern CLIENT *clntudp_bufcreate __P((struct sockaddr_in *, u_long, u_long, struct timeval, int *, u_int, u_int)); __END_DECLS /* * Print why creation failed */ __BEGIN_DECLS extern void clnt_pcreateerror __P((char *)); /* stderr */ extern char *clnt_spcreateerror __P((char *)); /* string */ __END_DECLS /* * Like clnt_perror(), but is more verbose in its output */ __BEGIN_DECLS extern void clnt_perrno __P((enum clnt_stat)); /* stderr */ extern char *clnt_sperrno __P((enum clnt_stat)); /* string */ __END_DECLS /* * Print an English error message, given the client error code */ __BEGIN_DECLS extern void clnt_perror __P((CLIENT *, char *)); /* stderr */ extern char *clnt_sperror __P((CLIENT *, char *)); /* string */ __END_DECLS /* * If a creation fails, the following allows the user to figure out why. */ struct rpc_createerr { enum clnt_stat cf_stat; struct rpc_err cf_error; /* useful when cf_stat == RPC_PMAPFAILURE */ }; extern struct rpc_createerr rpc_createerr; #define UDPMSGSIZE 8800 /* rpc imposed limit on udp msg size */ #define RPCSMALLMSGSIZE 400 /* a more reasonable packet size */ #endif /* !_RPC_CLNT_H */ snort-2.9.15.1/src/win32/WIN32-Includes/rpc/pmap_clnt.h0000644000175200017520000000627213571422610017062 00000000000000/* $Id$ */ /* $OpenBSD: pmap_clnt.h,v 1.3 1998/08/29 18:57:14 deraadt Exp $ */ /* $NetBSD: pmap_clnt.h,v 1.5 1994/12/04 01:12:42 cgd Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 * * from: @(#)pmap_clnt.h 1.11 88/02/08 SMI * @(#)pmap_clnt.h 2.1 88/07/29 4.0 RPCSRC */ /* * pmap_clnt.h * Supplies C routines to get to portmap services. * * Copyright (C) 1984, Sun Microsystems, Inc. */ /* * Usage: * success = pmap_set(program, version, protocol, port); * success = pmap_unset(program, version); * port = pmap_getport(address, program, version, protocol); * head = pmap_getmaps(address); * clnt_stat = pmap_rmtcall(address, program, version, procedure, * xdrargs, argsp, xdrres, resp, tout, port_ptr) * (works for udp only.) * clnt_stat = clnt_broadcast(program, version, procedure, * xdrargs, argsp, xdrres, resp, eachresult) * (like pmap_rmtcall, except the call is broadcasted to all * locally connected nets. For each valid response received, * the procedure eachresult is called. Its form is: * done = eachresult(resp, raddr) * bool_t done; * caddr_t resp; * struct sockaddr_in raddr; * where resp points to the results of the call and raddr is the * address if the responder to the broadcast. */ #ifndef _RPC_PMAPCLNT_H #define _RPC_PMAPCLNT_H #include __BEGIN_DECLS extern bool_t pmap_set __P((u_long, u_long, u_int, int)); extern bool_t pmap_unset __P((u_long, u_long)); extern struct pmaplist *pmap_getmaps __P((struct sockaddr_in *)); extern enum clnt_stat pmap_rmtcall __P((struct sockaddr_in *, u_long, u_long, u_long, xdrproc_t, caddr_t, xdrproc_t, caddr_t, struct timeval, u_long *)); extern enum clnt_stat clnt_broadcast __P((u_long, u_long, u_long, xdrproc_t, char *, xdrproc_t, char *, bool_t (*) __P((caddr_t, struct sockaddr_in *)))); extern u_short pmap_getport __P((struct sockaddr_in *, u_long, u_long, u_int)); __END_DECLS #endif /* !_RPC_PMAPCLNT_H */ snort-2.9.15.1/src/win32/WIN32-Includes/rpc/pmap_prot.h0000644000175200017520000000715713571422610017111 00000000000000/* $Id$ */ /* $OpenBSD: pmap_prot.h,v 1.3 1998/02/10 06:25:32 deraadt Exp $ */ /* $NetBSD: pmap_prot.h,v 1.4 1994/10/26 00:57:00 cgd Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 * * from: @(#)pmap_prot.h 1.14 88/02/08 SMI * @(#)pmap_prot.h 2.1 88/07/29 4.0 RPCSRC */ /* * pmap_prot.h * Protocol for the local binder service, or pmap. * * Copyright (C) 1984, Sun Microsystems, Inc. * * The following procedures are supported by the protocol: * * PMAPPROC_NULL() returns () * takes nothing, returns nothing * * PMAPPROC_SET(struct pmap) returns (bool_t) * TRUE is success, FALSE is failure. Registers the tuple * [prog, vers, prot, port]. * * PMAPPROC_UNSET(struct pmap) returns (bool_t) * TRUE is success, FALSE is failure. Un-registers pair * [prog, vers]. prot and port are ignored. * * PMAPPROC_GETPORT(struct pmap) returns (unsigned long). * 0 is failure. Otherwise returns the port number where the pair * [prog, vers] is registered. It may lie! * * PMAPPROC_DUMP() RETURNS (struct pmaplist *) * * PMAPPROC_CALLIT(unsigned int, unsigned int, unsigned int, string<>) * RETURNS (port, string<>); * usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc, encapsulatedargs); * Calls the procedure on the local machine. If it is not registered, * this procedure is quite; ie it does not return error information!!! * This procedure only is supported on rpc/udp and calls via * rpc/udp. This routine only passes null authentication parameters. * This file has no interface to xdr routines for PMAPPROC_CALLIT. * * The service supports remote procedure calls on udp/ip or tcp/ip socket 111. */ #ifndef _RPC_PMAPPROT_H #define _RPC_PMAPPROT_H #include #define PMAPPORT ((u_short)111) #define PMAPPROG ((u_long)100000) #define PMAPVERS ((u_long)2) #define PMAPVERS_PROTO ((u_long)2) #define PMAPVERS_ORIG ((u_long)1) #define PMAPPROC_NULL ((u_long)0) #define PMAPPROC_SET ((u_long)1) #define PMAPPROC_UNSET ((u_long)2) #define PMAPPROC_GETPORT ((u_long)3) #define PMAPPROC_DUMP ((u_long)4) #define PMAPPROC_CALLIT ((u_long)5) struct pmap { unsigned long pm_prog; unsigned long pm_vers; unsigned long pm_prot; unsigned long pm_port; }; struct pmaplist { struct pmap pml_map; struct pmaplist *pml_next; }; __BEGIN_DECLS extern bool_t xdr_pmap __P((XDR *, struct pmap *)); extern bool_t xdr_pmaplist __P((XDR *, struct pmaplist **)); __END_DECLS #endif /* !_RPC_PMAPPROT_H */ snort-2.9.15.1/src/win32/WIN32-Includes/rpc/pmap_rmt.h0000644000175200017520000000411513571422610016716 00000000000000/* $Id$ */ /* $OpenBSD: pmap_rmt.h,v 1.2 1997/09/21 10:46:13 niklas Exp $ */ /* $NetBSD: pmap_rmt.h,v 1.4 1994/10/26 00:57:01 cgd Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 * * from: @(#)pmap_rmt.h 1.2 88/02/08 SMI * @(#)pmap_rmt.h 2.1 88/07/29 4.0 RPCSRC */ /* * Structures and XDR routines for parameters to and replies from * the portmapper remote-call-service. * * Copyright (C) 1986, Sun Microsystems, Inc. */ #ifndef _RPC_PMAPRMT_H #define _RPC_PMAPRMT_H #include struct rmtcallargs { u_long prog, vers, proc, arglen; caddr_t args_ptr; xdrproc_t xdr_args; }; struct rmtcallres { u_long *port_ptr; u_long resultslen; caddr_t results_ptr; xdrproc_t xdr_results; }; __BEGIN_DECLS extern bool_t xdr_rmtcall_args __P((XDR *, struct rmtcallargs *)); extern bool_t xdr_rmtcallres __P((XDR *, struct rmtcallres *)); __END_DECLS #endif /* !_RPC_PMAPRMT_H */ snort-2.9.15.1/src/win32/WIN32-Includes/rpc/rpc_des.h0000644000175200017520000001307313571422610016521 00000000000000/* $Id$ */ x/* $OpenBSD: rpc_des.h,v 1.3 1998/02/10 06:25:33 deraadt Exp $ */ /* crypto/des/rpc_des.h */ /* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au) * All rights reserved. * * This package is an SSL implementation written * by Eric Young (eay@mincom.oz.au). * The implementation was written so as to conform with Netscapes SSL. * * This library is free for commercial and non-commercial use as long as * the following conditions are aheared to. The following conditions * apply to all code found in this distribution, be it the RC4, RSA, * lhash, DES, etc., code; not just the SSL code. The SSL documentation * included with this distribution is covered by the same copyright terms * except that the holder is Tim Hudson (tjh@mincom.oz.au). * * Copyright remains Eric Young's, and as such any Copyright notices in * the code are not to be removed. * If this package is used in a product, Eric Young should be given attribution * as the author of the parts of the library used. * This can be in the form of a textual message at program startup or * in documentation (online or textual) provided with the package. * * 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 copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * "This product includes cryptographic software written by * Eric Young (eay@mincom.oz.au)" * The word 'cryptographic' can be left out if the rouines from the library * being used are not cryptographic related :-). * 4. If you include any Windows specific code (or a derivative thereof) from * the apps directory (application code) you must include an acknowledgement: * "This product includes software written by Tim Hudson (tjh@mincom.oz.au)" * * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * The licence and distribution terms for any publically available version or * derivative of this code cannot be changed. i.e. this code cannot simply be * copied and put under another distribution licence * [including the GNU Public Licence.] */ /* @(#)des.h 2.2 88/08/10 4.0 RPCSRC; from 2.7 88/02/08 SMI */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ /* * Generic DES driver interface * Keep this file hardware independent! * Copyright (c) 1986 by Sun Microsystems, Inc. */ #define DES_MAXLEN 65536 /* maximum # of bytes to encrypt */ #define DES_QUICKLEN 16 /* maximum # of bytes to encrypt quickly */ #ifdef HEADER_DES_H #undef ENCRYPT #undef DECRYPT #endif enum desdir { ENCRYPT, DECRYPT }; enum desmode { CBC, ECB }; /* * parameters to ioctl call */ struct desparams { unsigned char des_key[8]; /* key (with low bit parity) */ enum desdir des_dir; /* direction */ enum desmode des_mode; /* mode */ unsigned char des_ivec[8]; /* input vector */ unsigned int des_len; /* number of bytes to crypt */ union { unsigned char UDES_data[DES_QUICKLEN]; unsigned char *UDES_buf; } UDES; # define des_data UDES.UDES_data /* direct data here if quick */ # define des_buf UDES.UDES_buf /* otherwise, pointer to data */ }; /* * Encrypt an arbitrary sized buffer */ #define DESIOCBLOCK _IOWR(d, 6, struct desparams) /* * Encrypt of small amount of data, quickly */ #define DESIOCQUICK _IOWR(d, 7, struct desparams) snort-2.9.15.1/src/win32/WIN32-Includes/rpc/rpc.h0000644000175200017520000000732213571422610015666 00000000000000/* $Id$ */ /* $OpenBSD: rpc.h,v 1.7 1998/12/20 23:43:18 millert Exp $ */ /* $NetBSD: rpc.h,v 1.5 1994/12/04 01:15:30 cgd Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 * * from: @(#)rpc.h 1.9 88/02/08 SMI * @(#)rpc.h 2.4 89/07/11 4.0 RPCSRC */ /* * rpc.h, Just includes the billions of rpc header files necessary to * do remote procedure calling. * * Copyright (C) 1984, Sun Microsystems, Inc. */ #ifndef _RPC_RPC_H #define _RPC_RPC_H #include /* some typedefs */ /* #include */ /* external data representation interfaces */ #include /* generic (de)serializer */ /* Client side only authentication */ #include /* generic authenticator (client side) */ /* Client side (mostly) remote procedure call */ #include /* generic rpc stuff */ /* Client side (mostly) pmap functions */ #include /* generic pmap stuff */ /* semi-private protocol headers */ #include /* protocol for rpc messages */ #include /* protocol for unix style cred */ /* * Uncomment-out the next line if you are building the rpc library with * DES Authentication (see the README file in the secure_rpc/ directory). */ #ifdef notdef #include /* protocol for des style cred */ #endif /* Server side only remote procedure callee */ #include /* service manager and multiplexer */ #include /* service side authenticator */ /* * COMMENT OUT THE NEXT INCLUDE (or add to the #ifndef) IF RUNNING ON * A VERSION OF UNIX THAT USES SUN'S NFS SOURCE. These systems will * already have the structures defined by included in . */ /* routines for parsing /etc/rpc */ struct rpcent { char *r_name; /* name of server for this rpc program */ char **r_aliases; /* alias list */ int r_number; /* rpc program number */ }; __BEGIN_DECLS extern struct rpcent *getrpcbyname __P((char *)); extern struct rpcent *getrpcbynumber __P((int)); extern struct rpcent *getrpcent __P((void)); extern void setrpcent __P((int)); extern void endrpcent __P((void)); extern int get_myaddress __P((struct sockaddr_in *)); extern int registerrpc __P((int, int, int, char *(*) __P((char [UDPMSGSIZE])), xdrproc_t, xdrproc_t)); extern int callrpc __P((char *, int, int, int, xdrproc_t, char *, xdrproc_t , char *)); extern int getrpcport __P((char *, int, int, int)); extern bool_t xdr_opaque_auth __P((XDR *, struct opaque_auth *)); __END_DECLS #endif /* !_RPC_RPC_H */ snort-2.9.15.1/src/win32/WIN32-Includes/rpc/rpc_msg.h0000644000175200017520000001072213571422610016532 00000000000000/* $Id$ */ /* $OpenBSD: rpc_msg.h,v 1.2 1997/09/21 10:46:15 niklas Exp $ */ /* $NetBSD: rpc_msg.h,v 1.5 1995/04/29 05:28:00 cgd Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 * * from: @(#)rpc_msg.h 1.7 86/07/16 SMI * @(#)rpc_msg.h 2.1 88/07/29 4.0 RPCSRC */ /* * rpc_msg.h * rpc message definition * * Copyright (C) 1984, Sun Microsystems, Inc. */ #ifndef _RPC_RPCMSG_H #define _RPC_RPCMSG_H #define RPC_MSG_VERSION ((u_long) 2) #define RPC_SERVICE_PORT ((u_short) 2048) /* * Bottom up definition of an rpc message. * NOTE: call and reply use the same overall stuct but * different parts of unions within it. */ enum msg_type { CALL=0, REPLY=1 }; enum reply_stat { MSG_ACCEPTED=0, MSG_DENIED=1 }; enum accept_stat { SUCCESS=0, PROG_UNAVAIL=1, PROG_MISMATCH=2, PROC_UNAVAIL=3, GARBAGE_ARGS=4, SYSTEM_ERR=5 }; enum reject_stat { RPC_MISMATCH=0, AUTH_ERROR=1 }; /* * Reply part of an rpc exchange */ /* * Reply to an rpc request that was accepted by the server. * Note: there could be an error even though the request was * accepted. */ struct accepted_reply { struct opaque_auth ar_verf; enum accept_stat ar_stat; union { struct { u_int32_t low; u_int32_t high; } AR_versions; struct { caddr_t where; xdrproc_t proc; } AR_results; /* and many other null cases */ } ru; #define ar_results ru.AR_results #define ar_vers ru.AR_versions }; /* * Reply to an rpc request that was rejected by the server. */ struct rejected_reply { enum reject_stat rj_stat; union { struct { u_int32_t low; u_int32_t high; } RJ_versions; enum auth_stat RJ_why; /* why authentication did not work */ } ru; #define rj_vers ru.RJ_versions #define rj_why ru.RJ_why }; /* * Body of a reply to an rpc request. */ struct reply_body { enum reply_stat rp_stat; union { struct accepted_reply RP_ar; struct rejected_reply RP_dr; } ru; #define rp_acpt ru.RP_ar #define rp_rjct ru.RP_dr }; /* * Body of an rpc request call. */ struct call_body { u_int32_t cb_rpcvers; /* must be equal to two */ u_int32_t cb_prog; u_int32_t cb_vers; u_int32_t cb_proc; struct opaque_auth cb_cred; struct opaque_auth cb_verf; /* protocol specific - provided by client */ }; /* * The rpc message */ struct rpc_msg { u_int32_t rm_xid; enum msg_type rm_direction; union { struct call_body RM_cmb; struct reply_body RM_rmb; } ru; #define rm_call ru.RM_cmb #define rm_reply ru.RM_rmb }; #define acpted_rply ru.RM_rmb.ru.RP_ar #define rjcted_rply ru.RM_rmb.ru.RP_dr __BEGIN_DECLS /* * XDR routine to handle a rpc message. * xdr_callmsg(xdrs, cmsg) * XDR *xdrs; * struct rpc_msg *cmsg; */ extern bool_t xdr_callmsg __P((XDR *, struct rpc_msg *)); /* * XDR routine to pre-serialize the static part of a rpc message. * xdr_callhdr(xdrs, cmsg) * XDR *xdrs; * struct rpc_msg *cmsg; */ extern bool_t xdr_callhdr __P((XDR *, struct rpc_msg *)); /* * XDR routine to handle a rpc reply. * xdr_replymsg(xdrs, rmsg) * XDR *xdrs; * struct rpc_msg *rmsg; */ extern bool_t xdr_replymsg __P((XDR *, struct rpc_msg *)); /* * Fills in the error part of a reply message. * _seterr_reply(msg, error) * struct rpc_msg *msg; * struct rpc_err *error; */ extern void _seterr_reply __P((struct rpc_msg *, struct rpc_err *)); __END_DECLS #endif /* !_RPC_RPCMSG_H */ snort-2.9.15.1/src/win32/WIN32-Includes/rpc/svc_auth.h0000644000175200017520000000344013571422610016713 00000000000000/* $Id$ */ /* $OpenBSD: svc_auth.h,v 1.2 1997/09/21 10:46:16 niklas Exp $ */ /* $NetBSD: svc_auth.h,v 1.4 1994/10/26 00:57:07 cgd Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 * * from: @(#)svc_auth.h 1.6 86/07/16 SMI * @(#)svc_auth.h 2.1 88/07/29 4.0 RPCSRC */ /* * svc_auth.h, Service side of rpc authentication. * * Copyright (C) 1984, Sun Microsystems, Inc. */ #ifndef _RPC_SVCAUTH_H #define _RPC_SVCAUTH_H /* * Server side authenticator */ __BEGIN_DECLS extern enum auth_stat _authenticate __P((struct svc_req *, struct rpc_msg *)); __END_DECLS #endif /* !_RPC_SVCAUTH_H */ snort-2.9.15.1/src/win32/WIN32-Includes/rpc/svc.h0000644000175200017520000002340013571422610015670 00000000000000/* $Id$ */ /* $OpenBSD: svc.h,v 1.2 1997/09/21 10:46:16 niklas Exp $ */ /* $NetBSD: svc.h,v 1.9 1995/04/29 05:28:01 cgd Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 * * from: @(#)svc.h 1.20 88/02/08 SMI * @(#)svc.h 2.2 88/07/29 4.0 RPCSRC */ /* * svc.h, Server-side remote procedure call interface. * * Copyright (C) 1984, Sun Microsystems, Inc. */ #ifndef _RPC_SVC_H #define _RPC_SVC_H #include /* * This interface must manage two items concerning remote procedure calling: * * 1) An arbitrary number of transport connections upon which rpc requests * are received. The two most notable transports are TCP and UDP; they are * created and registered by routines in svc_tcp.c and svc_udp.c, respectively; * they in turn call xprt_register and xprt_unregister. * * 2) An arbitrary number of locally registered services. Services are * described by the following four data: program number, version number, * "service dispatch" function, a transport handle, and a boolean that * indicates whether or not the exported program should be registered with a * local binder service; if true the program's number and version and the * port number from the transport handle are registered with the binder. * These data are registered with the rpc svc system via svc_register. * * A service's dispatch function is called whenever an rpc request comes in * on a transport. The request's program and version numbers must match * those of the registered service. The dispatch function is passed two * parameters, struct svc_req * and SVCXPRT *, defined below. */ enum xprt_stat { XPRT_DIED, XPRT_MOREREQS, XPRT_IDLE }; /* * Server side transport handle */ typedef struct __rpc_svcxprt { int xp_sock; u_short xp_port; /* associated port number */ struct xp_ops { /* receive incomming requests */ bool_t (*xp_recv) __P((struct __rpc_svcxprt *, struct rpc_msg *)); /* get transport status */ enum xprt_stat (*xp_stat) __P((struct __rpc_svcxprt *)); /* get arguments */ bool_t (*xp_getargs) __P((struct __rpc_svcxprt *, xdrproc_t, caddr_t)); /* send reply */ bool_t (*xp_reply) __P((struct __rpc_svcxprt *, struct rpc_msg *)); /* free mem allocated for args */ bool_t (*xp_freeargs) __P((struct __rpc_svcxprt *, xdrproc_t, caddr_t)); /* destroy this struct */ void (*xp_destroy) __P((struct __rpc_svcxprt *)); } *xp_ops; int xp_addrlen; /* length of remote address */ struct sockaddr_in xp_raddr; /* remote address */ struct opaque_auth xp_verf; /* raw response verifier */ caddr_t xp_p1; /* private */ caddr_t xp_p2; /* private */ } SVCXPRT; /* * Approved way of getting address of caller */ #define svc_getcaller(x) (&(x)->xp_raddr) /* * Operations defined on an SVCXPRT handle * * SVCXPRT *xprt; * struct rpc_msg *msg; * xdrproc_t xargs; * caddr_t argsp; */ #define SVC_RECV(xprt, msg) \ (*(xprt)->xp_ops->xp_recv)((xprt), (msg)) #define svc_recv(xprt, msg) \ (*(xprt)->xp_ops->xp_recv)((xprt), (msg)) #define SVC_STAT(xprt) \ (*(xprt)->xp_ops->xp_stat)(xprt) #define svc_stat(xprt) \ (*(xprt)->xp_ops->xp_stat)(xprt) #define SVC_GETARGS(xprt, xargs, argsp) \ (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp)) #define svc_getargs(xprt, xargs, argsp) \ (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp)) #define SVC_REPLY(xprt, msg) \ (*(xprt)->xp_ops->xp_reply) ((xprt), (msg)) #define svc_reply(xprt, msg) \ (*(xprt)->xp_ops->xp_reply) ((xprt), (msg)) #define SVC_FREEARGS(xprt, xargs, argsp) \ (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp)) #define svc_freeargs(xprt, xargs, argsp) \ (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp)) #define SVC_DESTROY(xprt) \ (*(xprt)->xp_ops->xp_destroy)(xprt) #define svc_destroy(xprt) \ (*(xprt)->xp_ops->xp_destroy)(xprt) /* * Service request */ struct svc_req { u_int32_t rq_prog; /* service program number */ u_int32_t rq_vers; /* service protocol version */ u_int32_t rq_proc; /* the desired procedure */ struct opaque_auth rq_cred; /* raw creds from the wire */ caddr_t rq_clntcred; /* read only cooked cred */ SVCXPRT *rq_xprt; /* associated transport */ }; /* * Service registration * * svc_register(xprt, prog, vers, dispatch, protocol) * SVCXPRT *xprt; * u_long prog; * u_long vers; * void (*dispatch)(); * int protocol; like TCP or UDP, zero means do not register */ __BEGIN_DECLS extern bool_t svc_register __P((SVCXPRT *, u_long, u_long, void (*) __P((struct svc_req *, SVCXPRT *)), int)); __END_DECLS /* * Service un-registration * * svc_unregister(prog, vers) * u_long prog; * u_long vers; */ __BEGIN_DECLS extern void svc_unregister __P((u_long, u_long)); __END_DECLS /* * Transport registration. * * xprt_register(xprt) * SVCXPRT *xprt; */ __BEGIN_DECLS extern void xprt_register __P((SVCXPRT *)); __END_DECLS /* * Transport un-register * * xprt_unregister(xprt) * SVCXPRT *xprt; */ __BEGIN_DECLS extern void xprt_unregister __P((SVCXPRT *)); __END_DECLS /* * When the service routine is called, it must first check to see if it * knows about the procedure; if not, it should call svcerr_noproc * and return. If so, it should deserialize its arguments via * SVC_GETARGS (defined above). If the deserialization does not work, * svcerr_decode should be called followed by a return. Successful * decoding of the arguments should be followed the execution of the * procedure's code and a call to svc_sendreply. * * Also, if the service refuses to execute the procedure due to too- * weak authentication parameters, svcerr_weakauth should be called. * Note: do not confuse access-control failure with weak authentication! * * NB: In pure implementations of rpc, the caller always waits for a reply * msg. This message is sent when svc_sendreply is called. * Therefore pure service implementations should always call * svc_sendreply even if the function logically returns void; use * xdr.h - xdr_void for the xdr routine. HOWEVER, tcp based rpc allows * for the abuse of pure rpc via batched calling or pipelining. In the * case of a batched call, svc_sendreply should NOT be called since * this would send a return message, which is what batching tries to avoid. * It is the service/protocol writer's responsibility to know which calls are * batched and which are not. Warning: responding to batch calls may * deadlock the caller and server processes! */ __BEGIN_DECLS extern bool_t svc_sendreply __P((SVCXPRT *, xdrproc_t, char *)); extern void svcerr_decode __P((SVCXPRT *)); extern void svcerr_weakauth __P((SVCXPRT *)); extern void svcerr_noproc __P((SVCXPRT *)); extern void svcerr_progvers __P((SVCXPRT *, u_long, u_long)); extern void svcerr_auth __P((SVCXPRT *, enum auth_stat)); extern void svcerr_noprog __P((SVCXPRT *)); extern void svcerr_systemerr __P((SVCXPRT *)); __END_DECLS /* * Lowest level dispatching -OR- who owns this process anyway. * Somebody has to wait for incoming requests and then call the correct * service routine. The routine svc_run does infinite waiting; i.e., * svc_run never returns. * Since another (co-existant) package may wish to selectively wait for * incoming calls or other events outside of the rpc architecture, the * routine svc_getreq is provided. It must be passed readfds, the * "in-place" results of a select system call (see select, section 2). */ /* * Global keeper of rpc service descriptors in use * dynamic; must be inspected before each call to select */ extern int svc_maxfd; #ifdef FD_SETSIZE extern fd_set svc_fdset; #define svc_fds svc_fdset.fds_bits[0] /* compatibility */ #else extern int svc_fds; #endif /* def FD_SETSIZE */ /* * a small program implemented by the svc_rpc implementation itself; * also see clnt.h for protocol numbers. */ extern void rpctest_service(); /* XXX relic? */ __BEGIN_DECLS extern void svc_getreq __P((int)); extern void svc_getreqset __P((fd_set *)); extern void svc_run __P((void)); __END_DECLS /* * Socket to use on svcxxx_create call to get default socket */ #define RPC_ANYSOCK -1 /* * These are the existing service side transport implementations */ /* * Memory based rpc for testing and timing. */ __BEGIN_DECLS extern SVCXPRT *svcraw_create __P((void)); __END_DECLS /* * Udp based rpc. */ __BEGIN_DECLS extern SVCXPRT *svcudp_create __P((int)); extern SVCXPRT *svcudp_bufcreate __P((int, u_int, u_int)); __END_DECLS /* * Tcp based rpc. */ __BEGIN_DECLS extern SVCXPRT *svctcp_create __P((int, u_int, u_int)); __END_DECLS /* * Fd based rpc. */ __BEGIN_DECLS extern SVCXPRT *svcfd_create __P((int, u_int, u_int)); __END_DECLS #endif /* !_RPC_SVC_H */ snort-2.9.15.1/src/win32/WIN32-Includes/rpc/types.h0000644000175200017520000000424613571422610016250 00000000000000/* $Id$ */ /* $OpenBSD: types.h,v 1.2 1997/09/21 10:46:17 niklas Exp $ */ /* $NetBSD: types.h,v 1.8 1995/04/29 05:28:05 cgd Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 * * from: @(#)types.h 1.18 87/07/24 SMI * @(#)types.h 2.3 88/08/15 4.0 RPCSRC */ /* * Rpc additions to */ #ifndef _RPC_TYPES_H #define _RPC_TYPES_H #ifdef WIN32 /* These are now located in */ /* typedef int int32_t; */ /* typedef unsigned int u_int32_t; */ #include #ifndef caddr_t typedef char * caddr_t; #endif #endif #define bool_t int32_t #define enum_t int32_t #define __dontcare__ -1 #ifndef FALSE # define FALSE (0) #endif #ifndef TRUE # define TRUE (1) #endif #ifndef NULL # define NULL 0 #endif #define mem_alloc(bsize) malloc(bsize) #define mem_free(ptr, bsize) free(ptr) #ifndef makedev /* ie, we haven't already included it */ #include #endif #ifdef WIN32 #include #else #include #endif #endif /* !_RPC_TYPES_H */ snort-2.9.15.1/src/win32/WIN32-Includes/rpc/xdr.h0000644000175200017520000002571213571422610015702 00000000000000/* $Id$ */ /* $OpenBSD: xdr.h,v 1.2 1997/09/21 10:46:18 niklas Exp $ */ /* $NetBSD: xdr.h,v 1.7 1995/04/29 05:28:06 cgd Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 * * from: @(#)xdr.h 1.19 87/04/22 SMI * @(#)xdr.h 2.2 88/07/29 4.0 RPCSRC */ /* * xdr.h, External Data Representation Serialization Routines. * * Copyright (C) 1984, Sun Microsystems, Inc. */ #ifndef _RPC_XDR_H #define _RPC_XDR_H #ifndef WIN32 #include #else #include "cdefs.h" #endif /* * XDR provides a conventional way for converting between C data * types and an external bit-string representation. Library supplied * routines provide for the conversion on built-in C data types. These * routines and utility routines defined here are used to help implement * a type encode/decode routine for each user-defined type. * * Each data type provides a single procedure which takes two arguments: * * bool_t * xdrproc(xdrs, argresp) * XDR *xdrs; * *argresp; * * xdrs is an instance of a XDR handle, to which or from which the data * type is to be converted. argresp is a pointer to the structure to be * converted. The XDR handle contains an operation field which indicates * which of the operations (ENCODE, DECODE * or FREE) is to be performed. * * XDR_DECODE may allocate space if the pointer argresp is null. This * data can be freed with the XDR_FREE operation. * * We write only one procedure per data type to make it easy * to keep the encode and decode procedures for a data type consistent. * In many cases the same code performs all operations on a user defined type, * because all the hard work is done in the component type routines. * decode as a series of calls on the nested data types. */ /* * Xdr operations. XDR_ENCODE causes the type to be encoded into the * stream. XDR_DECODE causes the type to be extracted from the stream. * XDR_FREE can be used to release the space allocated by an XDR_DECODE * request. */ enum xdr_op { XDR_ENCODE=0, XDR_DECODE=1, XDR_FREE=2 }; /* * This is the number of bytes per unit of external data. */ #define BYTES_PER_XDR_UNIT (4) #define RNDUP(x) ((((x) + BYTES_PER_XDR_UNIT - 1) / BYTES_PER_XDR_UNIT) \ * BYTES_PER_XDR_UNIT) /* * The XDR handle. * Contains operation which is being applied to the stream, * an operations vector for the paticular implementation (e.g. see xdr_mem.c), * and two private fields for the use of the particular impelementation. */ typedef struct __rpc_xdr { enum xdr_op x_op; /* operation; fast additional param */ struct xdr_ops { /* get a long from underlying stream */ bool_t (*x_getlong) __P((struct __rpc_xdr *, long *)); /* put a long to " */ bool_t (*x_putlong) __P((struct __rpc_xdr *, long *)); /* get some bytes from " */ bool_t (*x_getbytes) __P((struct __rpc_xdr *, caddr_t, u_int)); /* put some bytes to " */ bool_t (*x_putbytes) __P((struct __rpc_xdr *, caddr_t, u_int)); /* returns bytes off from beginning */ u_int (*x_getpostn) __P((struct __rpc_xdr *)); /* lets you reposition the stream */ bool_t (*x_setpostn) __P((struct __rpc_xdr *, u_int)); /* buf quick ptr to buffered data */ int32_t *(*x_inline) __P((struct __rpc_xdr *, u_int)); /* free privates of this xdr_stream */ void (*x_destroy) __P((struct __rpc_xdr *)); } *x_ops; caddr_t x_public; /* users' data */ caddr_t x_private; /* pointer to private data */ caddr_t x_base; /* private used for position info */ int x_handy; /* extra private word */ } XDR; /* * A xdrproc_t exists for each data type which is to be encoded or decoded. * * The second argument to the xdrproc_t is a pointer to an opaque pointer. * The opaque pointer generally points to a structure of the data type * to be decoded. If this pointer is 0, then the type routines should * allocate dynamic storage of the appropriate size and return it. * * XXX can't actually prototype it, because some take three args!!! */ typedef bool_t (*xdrproc_t) __P((/* XDR *, void *, u_int */)); /* * Operations defined on a XDR handle * * XDR *xdrs; * long *longp; * caddr_t addr; * u_int len; * u_int pos; */ #define XDR_GETLONG(xdrs, longp) \ (*(xdrs)->x_ops->x_getlong)(xdrs, longp) #define xdr_getlong(xdrs, longp) \ (*(xdrs)->x_ops->x_getlong)(xdrs, longp) #define XDR_PUTLONG(xdrs, longp) \ (*(xdrs)->x_ops->x_putlong)(xdrs, longp) #define xdr_putlong(xdrs, longp) \ (*(xdrs)->x_ops->x_putlong)(xdrs, longp) #define XDR_GETBYTES(xdrs, addr, len) \ (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len) #define xdr_getbytes(xdrs, addr, len) \ (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len) #define XDR_PUTBYTES(xdrs, addr, len) \ (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len) #define xdr_putbytes(xdrs, addr, len) \ (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len) #define XDR_GETPOS(xdrs) \ (*(xdrs)->x_ops->x_getpostn)(xdrs) #define xdr_getpos(xdrs) \ (*(xdrs)->x_ops->x_getpostn)(xdrs) #define XDR_SETPOS(xdrs, pos) \ (*(xdrs)->x_ops->x_setpostn)(xdrs, pos) #define xdr_setpos(xdrs, pos) \ (*(xdrs)->x_ops->x_setpostn)(xdrs, pos) #define XDR_INLINE(xdrs, len) \ (*(xdrs)->x_ops->x_inline)(xdrs, len) #define xdr_inline(xdrs, len) \ (*(xdrs)->x_ops->x_inline)(xdrs, len) #define XDR_DESTROY(xdrs) \ if ((xdrs)->x_ops->x_destroy) \ (*(xdrs)->x_ops->x_destroy)(xdrs) #define xdr_destroy(xdrs) \ if ((xdrs)->x_ops->x_destroy) \ (*(xdrs)->x_ops->x_destroy)(xdrs) /* * Support struct for discriminated unions. * You create an array of xdrdiscrim structures, terminated with * a entry with a null procedure pointer. The xdr_union routine gets * the discriminant value and then searches the array of structures * for a matching value. If a match is found the associated xdr routine * is called to handle that part of the union. If there is * no match, then a default routine may be called. * If there is no match and no default routine it is an error. */ #define NULL_xdrproc_t ((xdrproc_t)0) struct xdr_discrim { int value; xdrproc_t proc; }; /* * In-line routines for fast encode/decode of primitve data types. * Caveat emptor: these use single memory cycles to get the * data from the underlying buffer, and will fail to operate * properly if the data is not aligned. The standard way to use these * is to say: * if ((buf = XDR_INLINE(xdrs, count)) == NULL) * return (FALSE); * <<< macro calls >>> * where ``count'' is the number of bytes of data occupied * by the primitive data types. * * N.B. and frozen for all time: each data type here uses 4 bytes * of external representation. */ #define IXDR_GET_LONG(buf) ((long)ntohl((u_long)*(buf)++)) #define IXDR_PUT_LONG(buf, v) (*(buf)++ = (long)htonl((u_long)v)) #define IXDR_GET_BOOL(buf) ((bool_t)IXDR_GET_LONG(buf)) #define IXDR_GET_ENUM(buf, t) ((t)IXDR_GET_LONG(buf)) #define IXDR_GET_U_LONG(buf) ((u_long)IXDR_GET_LONG(buf)) #define IXDR_GET_SHORT(buf) ((short)IXDR_GET_LONG(buf)) #define IXDR_GET_U_SHORT(buf) ((u_short)IXDR_GET_LONG(buf)) #define IXDR_PUT_BOOL(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) #define IXDR_PUT_ENUM(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) #define IXDR_PUT_U_LONG(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) #define IXDR_PUT_SHORT(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) #define IXDR_PUT_U_SHORT(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) /* * These are the "generic" xdr routines. */ __BEGIN_DECLS extern bool_t xdr_void __P((void)); extern bool_t xdr_int __P((XDR *, int *)); extern bool_t xdr_u_int __P((XDR *, u_int *)); extern bool_t xdr_long __P((XDR *, long *)); extern bool_t xdr_u_long __P((XDR *, u_long *)); extern bool_t xdr_short __P((XDR *, short *)); extern bool_t xdr_u_short __P((XDR *, u_short *)); extern bool_t xdr_int16_t __P((XDR *, int16_t *)); extern bool_t xdr_u_int16_t __P((XDR *, u_int16_t *)); extern bool_t xdr_int32_t __P((XDR *, int32_t *)); extern bool_t xdr_u_int32_t __P((XDR *, u_int32_t *)); extern bool_t xdr_bool __P((XDR *, bool_t *)); extern bool_t xdr_enum __P((XDR *, enum_t *)); extern bool_t xdr_array __P((XDR *, char **, u_int *, u_int, u_int, xdrproc_t)); extern bool_t xdr_bytes __P((XDR *, char **, u_int *, u_int)); extern bool_t xdr_opaque __P((XDR *, caddr_t, u_int)); extern bool_t xdr_string __P((XDR *, char **, u_int)); extern bool_t xdr_union __P((XDR *, enum_t *, char *, struct xdr_discrim *, xdrproc_t)); extern bool_t xdr_char __P((XDR *, char *)); extern bool_t xdr_u_char __P((XDR *, u_char *)); extern bool_t xdr_vector __P((XDR *, char *, u_int, u_int, xdrproc_t)); extern bool_t xdr_float __P((XDR *, float *)); extern bool_t xdr_double __P((XDR *, double *)); extern bool_t xdr_reference __P((XDR *, caddr_t *, u_int, xdrproc_t)); extern bool_t xdr_pointer __P((XDR *, caddr_t *, u_int, xdrproc_t)); extern bool_t xdr_wrapstring __P((XDR *, char **)); extern void xdr_free __P((xdrproc_t, char *)); __END_DECLS /* * Common opaque bytes objects used by many rpc protocols; * declared here due to commonality. */ #define MAX_NETOBJ_SZ 1024 struct netobj { u_int n_len; char *n_bytes; }; typedef struct netobj netobj; extern bool_t xdr_netobj __P((XDR *, struct netobj *)); /* * These are the public routines for the various implementations of * xdr streams. */ __BEGIN_DECLS /* XDR using memory buffers */ extern void xdrmem_create __P((XDR *, char *, u_int, enum xdr_op)); #ifdef _STDIO_H_ /* XDR using stdio library */ extern void xdrstdio_create __P((XDR *, FILE *, enum xdr_op)); #endif /* XDR pseudo records for tcp */ extern void xdrrec_create __P((XDR *, u_int, u_int, char *, int (*) __P((caddr_t, caddr_t, int)), int (*) __P((caddr_t, caddr_t, int)))); /* make end of xdr record */ extern bool_t xdrrec_endofrecord __P((XDR *, int)); /* move to beginning of next record */ extern bool_t xdrrec_skiprecord __P((XDR *)); /* true if no more input */ extern bool_t xdrrec_eof __P((XDR *)); __END_DECLS #endif /* !_RPC_XDR_H */ snort-2.9.15.1/src/win32/WIN32-Includes/zlib/0000755000000000000000000000000013571426520015127 500000000000000snort-2.9.15.1/src/win32/WIN32-Includes/zlib/zconf.h0000644000175200017520000002322413571422610016374 00000000000000/* zconf.h -- configuration of the zlib compression library * Copyright (C) 1995-2005 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* @(#) $Id$ */ #ifndef ZCONF_H #define ZCONF_H /* * If you *really* need a unique prefix for all types and library functions, * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. */ #ifdef Z_PREFIX # define deflateInit_ z_deflateInit_ # define deflate z_deflate # define deflateEnd z_deflateEnd # define inflateInit_ z_inflateInit_ # define inflate z_inflate # define inflateEnd z_inflateEnd # define deflateInit2_ z_deflateInit2_ # define deflateSetDictionary z_deflateSetDictionary # define deflateCopy z_deflateCopy # define deflateReset z_deflateReset # define deflateParams z_deflateParams # define deflateBound z_deflateBound # define deflatePrime z_deflatePrime # define inflateInit2_ z_inflateInit2_ # define inflateSetDictionary z_inflateSetDictionary # define inflateSync z_inflateSync # define inflateSyncPoint z_inflateSyncPoint # define inflateCopy z_inflateCopy # define inflateReset z_inflateReset # define inflateBack z_inflateBack # define inflateBackEnd z_inflateBackEnd # define compress z_compress # define compress2 z_compress2 # define compressBound z_compressBound # define uncompress z_uncompress # define adler32 z_adler32 # define crc32 z_crc32 # define get_crc_table z_get_crc_table # define zError z_zError # define alloc_func z_alloc_func # define free_func z_free_func # define in_func z_in_func # define out_func z_out_func # define Byte z_Byte # define uInt z_uInt # define uLong z_uLong # define Bytef z_Bytef # define charf z_charf # define intf z_intf # define uIntf z_uIntf # define uLongf z_uLongf # define voidpf z_voidpf # define voidp z_voidp #endif #if defined(__MSDOS__) && !defined(MSDOS) # define MSDOS #endif #if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) # define OS2 #endif #if defined(_WINDOWS) && !defined(WINDOWS) # define WINDOWS #endif #if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) # ifndef WIN32 # define WIN32 # endif #endif #if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) # if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) # ifndef SYS16BIT # define SYS16BIT # endif # endif #endif /* * Compile with -DMAXSEG_64K if the alloc function cannot allocate more * than 64k bytes at a time (needed on systems with 16-bit int). */ #ifdef SYS16BIT # define MAXSEG_64K #endif #ifdef MSDOS # define UNALIGNED_OK #endif #ifdef __STDC_VERSION__ # ifndef STDC # define STDC # endif # if __STDC_VERSION__ >= 199901L # ifndef STDC99 # define STDC99 # endif # endif #endif #if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) # define STDC #endif #if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) # define STDC #endif #if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) # define STDC #endif #if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) # define STDC #endif #if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ # define STDC #endif #ifndef STDC # ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ # define const /* note: need a more gentle solution here */ # endif #endif /* Some Mac compilers merge all .h files incorrectly: */ #if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) # define NO_DUMMY_DECL #endif /* Maximum value for memLevel in deflateInit2 */ #ifndef MAX_MEM_LEVEL # ifdef MAXSEG_64K # define MAX_MEM_LEVEL 8 # else # define MAX_MEM_LEVEL 9 # endif #endif /* Maximum value for windowBits in deflateInit2 and inflateInit2. * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files * created by gzip. (Files created by minigzip can still be extracted by * gzip.) */ #ifndef MAX_WBITS # define MAX_WBITS 15 /* 32K LZ77 window */ #endif /* The memory requirements for deflate are (in bytes): (1 << (windowBits+2)) + (1 << (memLevel+9)) that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) plus a few kilobytes for small objects. For example, if you want to reduce the default memory requirements from 256K to 128K, compile with make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" Of course this will generally degrade compression (there's no free lunch). The memory requirements for inflate are (in bytes) 1 << windowBits that is, 32K for windowBits=15 (default value) plus a few kilobytes for small objects. */ /* Type declarations */ #ifndef OF /* function prototypes */ # ifdef STDC # define OF(args) args # else # define OF(args) () # endif #endif /* The following definitions for FAR are needed only for MSDOS mixed * model programming (small or medium model with some far allocations). * This was tested only with MSC; for other MSDOS compilers you may have * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, * just define FAR to be empty. */ #ifdef SYS16BIT # if defined(M_I86SM) || defined(M_I86MM) /* MSC small or medium model */ # define SMALL_MEDIUM # ifdef _MSC_VER # define FAR _far # else # define FAR far # endif # endif # if (defined(__SMALL__) || defined(__MEDIUM__)) /* Turbo C small or medium model */ # define SMALL_MEDIUM # ifdef __BORLANDC__ # define FAR _far # else # define FAR far # endif # endif #endif #if defined(WINDOWS) || defined(WIN32) /* If building or using zlib as a DLL, define ZLIB_DLL. * This is not mandatory, but it offers a little performance increase. */ # ifdef ZLIB_DLL # if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) # ifdef ZLIB_INTERNAL # define ZEXTERN extern __declspec(dllexport) # else # define ZEXTERN extern __declspec(dllimport) # endif # endif # endif /* ZLIB_DLL */ /* If building or using zlib with the WINAPI/WINAPIV calling convention, * define ZLIB_WINAPI. * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. */ # ifdef ZLIB_WINAPI # ifdef FAR # undef FAR # endif # include /* No need for _export, use ZLIB.DEF instead. */ /* For complete Windows compatibility, use WINAPI, not __stdcall. */ # define ZEXPORT WINAPI # ifdef WIN32 # define ZEXPORTVA WINAPIV # else # define ZEXPORTVA FAR CDECL # endif # endif #endif #if defined (__BEOS__) # ifdef ZLIB_DLL # ifdef ZLIB_INTERNAL # define ZEXPORT __declspec(dllexport) # define ZEXPORTVA __declspec(dllexport) # else # define ZEXPORT __declspec(dllimport) # define ZEXPORTVA __declspec(dllimport) # endif # endif #endif #ifndef ZEXTERN # define ZEXTERN extern #endif #ifndef ZEXPORT # define ZEXPORT #endif #ifndef ZEXPORTVA # define ZEXPORTVA #endif #ifndef FAR # define FAR #endif #if !defined(__MACTYPES__) typedef unsigned char Byte; /* 8 bits */ #endif typedef unsigned int uInt; /* 16 bits or more */ typedef unsigned long uLong; /* 32 bits or more */ #ifdef SMALL_MEDIUM /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ # define Bytef Byte FAR #else typedef Byte FAR Bytef; #endif typedef char FAR charf; typedef int FAR intf; typedef uInt FAR uIntf; typedef uLong FAR uLongf; #ifdef STDC typedef void const *voidpc; typedef void FAR *voidpf; typedef void *voidp; #else typedef Byte const *voidpc; typedef Byte FAR *voidpf; typedef Byte *voidp; #endif #if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ # include /* for off_t */ # include /* for SEEK_* and off_t */ # ifdef VMS # include /* for off_t */ # endif # define z_off_t off_t #endif #ifndef SEEK_SET # define SEEK_SET 0 /* Seek from beginning of file. */ # define SEEK_CUR 1 /* Seek from current position. */ # define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ #endif #ifndef z_off_t # define z_off_t long #endif #if defined(__OS400__) # define NO_vsnprintf #endif #if defined(__MVS__) # define NO_vsnprintf # ifdef FAR # undef FAR # endif #endif /* MVS linker does not support external names larger than 8 bytes */ #if defined(__MVS__) # pragma map(deflateInit_,"DEIN") # pragma map(deflateInit2_,"DEIN2") # pragma map(deflateEnd,"DEEND") # pragma map(deflateBound,"DEBND") # pragma map(inflateInit_,"ININ") # pragma map(inflateInit2_,"ININ2") # pragma map(inflateEnd,"INEND") # pragma map(inflateSync,"INSY") # pragma map(inflateSetDictionary,"INSEDI") # pragma map(compressBound,"CMBND") # pragma map(inflate_table,"INTABL") # pragma map(inflate_fast,"INFA") # pragma map(inflate_copyright,"INCOPY") #endif #endif /* ZCONF_H */ snort-2.9.15.1/src/win32/WIN32-Includes/zlib/zlib.h0000644000175200017520000020373113571422610016220 00000000000000/* zlib.h -- interface of the 'zlib' general purpose compression library version 1.2.3, July 18th, 2005 Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). */ #ifndef ZLIB_H #define ZLIB_H #include "zconf.h" #ifdef __cplusplus extern "C" { #endif #define ZLIB_VERSION "1.2.3" #define ZLIB_VERNUM 0x1230 /* The 'zlib' compression library provides in-memory compression and decompression functions, including integrity checks of the uncompressed data. This version of the library supports only one compression method (deflation) but other algorithms will be added later and will have the same stream interface. Compression can be done in a single step if the buffers are large enough (for example if an input file is mmap'ed), or can be done by repeated calls of the compression function. In the latter case, the application must provide more input and/or consume the output (providing more output space) before each call. The compressed data format used by default by the in-memory functions is the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped around a deflate stream, which is itself documented in RFC 1951. The library also supports reading and writing files in gzip (.gz) format with an interface similar to that of stdio using the functions that start with "gz". The gzip format is different from the zlib format. gzip is a gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. This library can optionally read and write gzip streams in memory as well. The zlib format was designed to be compact and fast for use in memory and on communications channels. The gzip format was designed for single- file compression on file systems, has a larger header than zlib to maintain directory information, and uses a different, slower check method than zlib. The library does not install any signal handler. The decoder checks the consistency of the compressed data, so the library should never crash even in case of corrupted input. */ typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); typedef void (*free_func) OF((voidpf opaque, voidpf address)); struct internal_state; typedef struct z_stream_s { Bytef *next_in; /* next input byte */ uInt avail_in; /* number of bytes available at next_in */ uLong total_in; /* total nb of input bytes read so far */ Bytef *next_out; /* next output byte should be put there */ uInt avail_out; /* remaining free space at next_out */ uLong total_out; /* total nb of bytes output so far */ char *msg; /* last error message, NULL if no error */ struct internal_state FAR *state; /* not visible by applications */ alloc_func zalloc; /* used to allocate the internal state */ free_func zfree; /* used to free the internal state */ voidpf opaque; /* private data object passed to zalloc and zfree */ int data_type; /* best guess about the data type: binary or text */ uLong adler; /* adler32 value of the uncompressed data */ uLong reserved; /* reserved for future use */ } z_stream; typedef z_stream FAR *z_streamp; /* gzip header information passed to and from zlib routines. See RFC 1952 for more details on the meanings of these fields. */ typedef struct gz_header_s { int text; /* true if compressed data believed to be text */ uLong time; /* modification time */ int xflags; /* extra flags (not used when writing a gzip file) */ int os; /* operating system */ Bytef *extra; /* pointer to extra field or Z_NULL if none */ uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ uInt extra_max; /* space at extra (only when reading header) */ Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ uInt name_max; /* space at name (only when reading header) */ Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ uInt comm_max; /* space at comment (only when reading header) */ int hcrc; /* true if there was or will be a header crc */ int done; /* true when done reading gzip header (not used when writing a gzip file) */ } gz_header; typedef gz_header FAR *gz_headerp; /* The application must update next_in and avail_in when avail_in has dropped to zero. It must update next_out and avail_out when avail_out has dropped to zero. The application must initialize zalloc, zfree and opaque before calling the init function. All other fields are set by the compression library and must not be updated by the application. The opaque value provided by the application will be passed as the first parameter for calls of zalloc and zfree. This can be useful for custom memory management. The compression library attaches no meaning to the opaque value. zalloc must return Z_NULL if there is not enough memory for the object. If zlib is used in a multi-threaded application, zalloc and zfree must be thread safe. On 16-bit systems, the functions zalloc and zfree must be able to allocate exactly 65536 bytes, but will not be required to allocate more than this if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers returned by zalloc for objects of exactly 65536 bytes *must* have their offset normalized to zero. The default allocation function provided by this library ensures this (see zutil.c). To reduce memory requirements and avoid any allocation of 64K objects, at the expense of compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). The fields total_in and total_out can be used for statistics or progress reports. After compression, total_in holds the total size of the uncompressed data and may be saved for use in the decompressor (particularly if the decompressor wants to decompress everything in a single step). */ /* constants */ #define Z_NO_FLUSH 0 #define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ #define Z_SYNC_FLUSH 2 #define Z_FULL_FLUSH 3 #define Z_FINISH 4 #define Z_BLOCK 5 /* Allowed flush values; see deflate() and inflate() below for details */ #define Z_OK 0 #define Z_STREAM_END 1 #define Z_NEED_DICT 2 #define Z_ERRNO (-1) #define Z_STREAM_ERROR (-2) #define Z_DATA_ERROR (-3) #define Z_MEM_ERROR (-4) #define Z_BUF_ERROR (-5) #define Z_VERSION_ERROR (-6) /* Return codes for the compression/decompression functions. Negative * values are errors, positive values are used for special but normal events. */ #define Z_NO_COMPRESSION 0 #define Z_BEST_SPEED 1 #define Z_BEST_COMPRESSION 9 #define Z_DEFAULT_COMPRESSION (-1) /* compression levels */ #define Z_FILTERED 1 #define Z_HUFFMAN_ONLY 2 #define Z_RLE 3 #define Z_FIXED 4 #define Z_DEFAULT_STRATEGY 0 /* compression strategy; see deflateInit2() below for details */ #define Z_BINARY 0 #define Z_TEXT 1 #define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ #define Z_UNKNOWN 2 /* Possible values of the data_type field (though see inflate()) */ #define Z_DEFLATED 8 /* The deflate compression method (the only one supported in this version) */ #define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ #define zlib_version zlibVersion() /* for compatibility with versions < 1.0.2 */ /* basic functions */ ZEXTERN const char * ZEXPORT zlibVersion OF((void)); /* The application can compare zlibVersion and ZLIB_VERSION for consistency. If the first character differs, the library code actually used is not compatible with the zlib.h header file used by the application. This check is automatically made by deflateInit and inflateInit. */ /* ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); Initializes the internal stream state for compression. The fields zalloc, zfree and opaque must be initialized before by the caller. If zalloc and zfree are set to Z_NULL, deflateInit updates them to use default allocation functions. The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: 1 gives best speed, 9 gives best compression, 0 gives no compression at all (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION requests a default compromise between speed and compression (currently equivalent to level 6). deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if level is not a valid compression level, Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible with the version assumed by the caller (ZLIB_VERSION). msg is set to null if there is no error message. deflateInit does not perform any compression: this will be done by deflate(). */ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); /* deflate compresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full. It may introduce some output latency (reading input without producing any output) except when forced to flush. The detailed semantics are as follows. deflate performs one or both of the following actions: - Compress more input starting at next_in and update next_in and avail_in accordingly. If not all input can be processed (because there is not enough room in the output buffer), next_in and avail_in are updated and processing will resume at this point for the next call of deflate(). - Provide more output starting at next_out and update next_out and avail_out accordingly. This action is forced if the parameter flush is non zero. Forcing flush frequently degrades the compression ratio, so this parameter should be set only when necessary (in interactive applications). Some output may be provided even if flush is not set. Before the call of deflate(), the application should ensure that at least one of the actions is possible, by providing more input and/or consuming more output, and updating avail_in or avail_out accordingly; avail_out should never be zero before the call. The application can consume the compressed output when it wants, for example when the output buffer is full (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK and with zero avail_out, it must be called again after making room in the output buffer because there might be more output pending. Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to decide how much data to accumualte before producing output, in order to maximize compression. If the parameter flush is set to Z_SYNC_FLUSH, all pending output is flushed to the output buffer and the output is aligned on a byte boundary, so that the decompressor can get all input data available so far. (In particular avail_in is zero after the call if enough output space has been provided before the call.) Flushing may degrade compression for some compression algorithms and so it should be used only when necessary. If flush is set to Z_FULL_FLUSH, all output is flushed as with Z_SYNC_FLUSH, and the compression state is reset so that decompression can restart from this point if previous compressed data has been damaged or if random access is desired. Using Z_FULL_FLUSH too often can seriously degrade compression. If deflate returns with avail_out == 0, this function must be called again with the same value of the flush parameter and more output space (updated avail_out), until the flush is complete (deflate returns with non-zero avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that avail_out is greater than six to avoid repeated flush markers due to avail_out == 0 on return. If the parameter flush is set to Z_FINISH, pending input is processed, pending output is flushed and deflate returns with Z_STREAM_END if there was enough output space; if deflate returns with Z_OK, this function must be called again with Z_FINISH and more output space (updated avail_out) but no more input data, until it returns with Z_STREAM_END or an error. After deflate has returned Z_STREAM_END, the only possible operations on the stream are deflateReset or deflateEnd. Z_FINISH can be used immediately after deflateInit if all the compression is to be done in a single step. In this case, avail_out must be at least the value returned by deflateBound (see below). If deflate does not return Z_STREAM_END, then it must be called again as described above. deflate() sets strm->adler to the adler32 checksum of all input read so far (that is, total_in bytes). deflate() may update strm->data_type if it can make a good guess about the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered binary. This field is only for information purposes and does not affect the compression algorithm in any manner. deflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if all input has been consumed and all output has been produced (only when flush is set to Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and deflate() can be called again with more input and more output space to continue compressing. */ ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending output. deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state was inconsistent, Z_DATA_ERROR if the stream was freed prematurely (some input or output was discarded). In the error case, msg may be set but then points to a static string (which must not be deallocated). */ /* ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); Initializes the internal stream state for decompression. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized before by the caller. If next_in is not Z_NULL and avail_in is large enough (the exact value depends on the compression method), inflateInit determines the compression method from the zlib header and allocates all data structures accordingly; otherwise the allocation will be deferred to the first call of inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to use default allocation functions. inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_VERSION_ERROR if the zlib library version is incompatible with the version assumed by the caller. msg is set to null if there is no error message. inflateInit does not perform any decompression apart from reading the zlib header if present: this will be done by inflate(). (So next_in and avail_in may be modified, but next_out and avail_out are unchanged.) */ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); /* inflate decompresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full. It may introduce some output latency (reading input without producing any output) except when forced to flush. The detailed semantics are as follows. inflate performs one or both of the following actions: - Decompress more input starting at next_in and update next_in and avail_in accordingly. If not all input can be processed (because there is not enough room in the output buffer), next_in is updated and processing will resume at this point for the next call of inflate(). - Provide more output starting at next_out and update next_out and avail_out accordingly. inflate() provides as much output as possible, until there is no more input data or no more space in the output buffer (see below about the flush parameter). Before the call of inflate(), the application should ensure that at least one of the actions is possible, by providing more input and/or consuming more output, and updating the next_* and avail_* values accordingly. The application can consume the uncompressed output when it wants, for example when the output buffer is full (avail_out == 0), or after each call of inflate(). If inflate returns Z_OK and with zero avail_out, it must be called again after making room in the output buffer because there might be more output pending. The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much output as possible to the output buffer. Z_BLOCK requests that inflate() stop if and when it gets to the next deflate block boundary. When decoding the zlib or gzip format, this will cause inflate() to return immediately after the header and before the first block. When doing a raw inflate, inflate() will go ahead and process the first block, and will return when it gets to the end of that block, or when it runs out of data. The Z_BLOCK option assists in appending to or combining deflate streams. Also to assist in this, on return inflate() will set strm->data_type to the number of unused bits in the last byte taken from strm->next_in, plus 64 if inflate() is currently decoding the last block in the deflate stream, plus 128 if inflate() returned immediately after decoding an end-of-block code or decoding the complete header up to just before the first byte of the deflate stream. The end-of-block will not be indicated until all of the uncompressed data from that block has been written to strm->next_out. The number of unused bits may in general be greater than seven, except when bit 7 of data_type is set, in which case the number of unused bits will be less than eight. inflate() should normally be called until it returns Z_STREAM_END or an error. However if all decompression is to be performed in a single step (a single call of inflate), the parameter flush should be set to Z_FINISH. In this case all pending input is processed and all pending output is flushed; avail_out must be large enough to hold all the uncompressed data. (The size of the uncompressed data may have been saved by the compressor for this purpose.) The next operation on this stream must be inflateEnd to deallocate the decompression state. The use of Z_FINISH is never required, but can be used to inform inflate that a faster approach may be used for the single inflate() call. In this implementation, inflate() always flushes as much output as possible to the output buffer, and always uses the faster approach on the first call. So the only effect of the flush parameter in this implementation is on the return value of inflate(), as noted below, or when it returns early because Z_BLOCK is used. If a preset dictionary is needed after this call (see inflateSetDictionary below), inflate sets strm->adler to the adler32 checksum of the dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise it sets strm->adler to the adler32 checksum of all output produced so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described below. At the end of the stream, inflate() checks that its computed adler32 checksum is equal to that saved by the compressor and returns Z_STREAM_END only if the checksum is correct. inflate() will decompress and check either zlib-wrapped or gzip-wrapped deflate data. The header type is detected automatically. Any information contained in the gzip header is not retained, so applications that need that information should instead use raw inflate, see inflateInit2() below, or inflateBack() and perform their own processing of the gzip header and trailer. inflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if the end of the compressed data has been reached and all uncompressed output has been produced, Z_NEED_DICT if a preset dictionary is needed at this point, Z_DATA_ERROR if the input data was corrupted (input stream not conforming to the zlib format or incorrect check value), Z_STREAM_ERROR if the stream structure was inconsistent (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no progress is possible or if there was not enough room in the output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and inflate() can be called again with more input and more output space to continue decompressing. If Z_DATA_ERROR is returned, the application may then call inflateSync() to look for a good compression block if a partial recovery of the data is desired. */ ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending output. inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state was inconsistent. In the error case, msg may be set but then points to a static string (which must not be deallocated). */ /* Advanced functions */ /* The following functions are needed only in some special applications. */ /* ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy)); This is another version of deflateInit with more compression options. The fields next_in, zalloc, zfree and opaque must be initialized before by the caller. The method parameter is the compression method. It must be Z_DEFLATED in this version of the library. The windowBits parameter is the base two logarithm of the window size (the size of the history buffer). It should be in the range 8..15 for this version of the library. Larger values of this parameter result in better compression at the expense of memory usage. The default value is 15 if deflateInit is used instead. windowBits can also be -8..-15 for raw deflate. In this case, -windowBits determines the window size. deflate() will then generate raw deflate data with no zlib header or trailer, and will not compute an adler32 check value. windowBits can also be greater than 15 for optional gzip encoding. Add 16 to windowBits to write a simple gzip header and trailer around the compressed data instead of a zlib wrapper. The gzip header will have no file name, no extra data, no comment, no modification time (set to zero), no header crc, and the operating system will be set to 255 (unknown). If a gzip stream is being written, strm->adler is a crc32 instead of an adler32. The memLevel parameter specifies how much memory should be allocated for the internal compression state. memLevel=1 uses minimum memory but is slow and reduces compression ratio; memLevel=9 uses maximum memory for optimal speed. The default value is 8. See zconf.h for total memory usage as a function of windowBits and memLevel. The strategy parameter is used to tune the compression algorithm. Use the value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no string match), or Z_RLE to limit match distances to one (run-length encoding). Filtered data consists mostly of small values with a somewhat random distribution. In this case, the compression algorithm is tuned to compress them better. The effect of Z_FILTERED is to force more Huffman coding and less string matching; it is somewhat intermediate between Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy parameter only affects the compression ratio but not the correctness of the compressed output even if it is not set appropriately. Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler decoder for special applications. deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid method). msg is set to null if there is no error message. deflateInit2 does not perform any compression: this will be done by deflate(). */ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, const Bytef *dictionary, uInt dictLength)); /* Initializes the compression dictionary from the given byte sequence without producing any compressed output. This function must be called immediately after deflateInit, deflateInit2 or deflateReset, before any call of deflate. The compressor and decompressor must use exactly the same dictionary (see inflateSetDictionary). The dictionary should consist of strings (byte sequences) that are likely to be encountered later in the data to be compressed, with the most commonly used strings preferably put towards the end of the dictionary. Using a dictionary is most useful when the data to be compressed is short and can be predicted with good accuracy; the data can then be compressed better than with the default empty dictionary. Depending on the size of the compression data structures selected by deflateInit or deflateInit2, a part of the dictionary may in effect be discarded, for example if the dictionary is larger than the window size in deflate or deflate2. Thus the strings most likely to be useful should be put at the end of the dictionary, not at the front. In addition, the current implementation of deflate will use at most the window size minus 262 bytes of the provided dictionary. Upon return of this function, strm->adler is set to the adler32 value of the dictionary; the decompressor may later use this value to determine which dictionary has been used by the compressor. (The adler32 value applies to the whole dictionary even if only a subset of the dictionary is actually used by the compressor.) If a raw deflate was requested, then the adler32 value is not computed and strm->adler is not set. deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a parameter is invalid (such as NULL dictionary) or the stream state is inconsistent (for example if deflate has already been called for this stream or if the compression method is bsort). deflateSetDictionary does not perform any compression: this will be done by deflate(). */ ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, z_streamp source)); /* Sets the destination stream as a complete copy of the source stream. This function can be useful when several compression strategies will be tried, for example when there are several ways of pre-processing the input data with a filter. The streams that will be discarded should then be freed by calling deflateEnd. Note that deflateCopy duplicates the internal compression state which can be quite large, so this strategy is slow and can consume lots of memory. deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc being NULL). msg is left unchanged in both source and destination. */ ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); /* This function is equivalent to deflateEnd followed by deflateInit, but does not free and reallocate all the internal compression state. The stream will keep the same compression level and any other attributes that may have been set by deflateInit2. deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being NULL). */ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, int level, int strategy)); /* Dynamically update the compression level and compression strategy. The interpretation of level and strategy is as in deflateInit2. This can be used to switch between compression and straight copy of the input data, or to switch to a different kind of input data requiring a different strategy. If the compression level is changed, the input available so far is compressed with the old level (and may be flushed); the new level will take effect only at the next call of deflate(). Before the call of deflateParams, the stream state must be set as for a call of deflate(), since the currently available input may have to be compressed and flushed. In particular, strm->avail_out must be non-zero. deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if strm->avail_out was zero. */ ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, int good_length, int max_lazy, int nice_length, int max_chain)); /* Fine tune deflate's internal compression parameters. This should only be used by someone who understands the algorithm used by zlib's deflate for searching for the best matching string, and even then only by the most fanatic optimizer trying to squeeze out the last compressed bit for their specific input data. Read the deflate.c source code for the meaning of the max_lazy, good_length, nice_length, and max_chain parameters. deflateTune() can be called after deflateInit() or deflateInit2(), and returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. */ ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, uLong sourceLen)); /* deflateBound() returns an upper bound on the compressed size after deflation of sourceLen bytes. It must be called after deflateInit() or deflateInit2(). This would be used to allocate an output buffer for deflation in a single pass, and so would be called before deflate(). */ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, int bits, int value)); /* deflatePrime() inserts bits in the deflate output stream. The intent is that this function is used to start off the deflate output with the bits leftover from a previous deflate stream when appending to it. As such, this function can only be used for raw deflate, and must be used before the first deflate() call after a deflateInit2() or deflateReset(). bits must be less than or equal to 16, and that many of the least significant bits of value will be inserted in the output. deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, gz_headerp head)); /* deflateSetHeader() provides gzip header information for when a gzip stream is requested by deflateInit2(). deflateSetHeader() may be called after deflateInit2() or deflateReset() and before the first call of deflate(). The text, time, os, extra field, name, and comment information in the provided gz_header structure are written to the gzip header (xflag is ignored -- the extra flags are set according to the compression level). The caller must assure that, if not Z_NULL, name and comment are terminated with a zero byte, and that if extra is not Z_NULL, that extra_len bytes are available there. If hcrc is true, a gzip header crc is included. Note that the current versions of the command-line version of gzip (up through version 1.3.x) do not support header crc's, and will report that it is a "multi-part gzip file" and give up. If deflateSetHeader is not used, the default gzip header has text false, the time set to zero, and os set to 255, with no extra, name, or comment fields. The gzip header is returned to the default state by deflateReset(). deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ /* ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, int windowBits)); This is another version of inflateInit with an extra parameter. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized before by the caller. The windowBits parameter is the base two logarithm of the maximum window size (the size of the history buffer). It should be in the range 8..15 for this version of the library. The default value is 15 if inflateInit is used instead. windowBits must be greater than or equal to the windowBits value provided to deflateInit2() while compressing, or it must be equal to 15 if deflateInit2() was not used. If a compressed stream with a larger window size is given as input, inflate() will return with the error code Z_DATA_ERROR instead of trying to allocate a larger window. windowBits can also be -8..-15 for raw inflate. In this case, -windowBits determines the window size. inflate() will then process raw deflate data, not looking for a zlib or gzip header, not generating a check value, and not looking for any check values for comparison at the end of the stream. This is for use with other formats that use the deflate compressed data format such as zip. Those formats provide their own check values. If a custom format is developed using the raw deflate format for compressed data, it is recommended that a check value such as an adler32 or a crc32 be applied to the uncompressed data as is done in the zlib, gzip, and zip formats. For most applications, the zlib format should be used as is. Note that comments above on the use in deflateInit2() applies to the magnitude of windowBits. windowBits can also be greater than 15 for optional gzip decoding. Add 32 to windowBits to enable zlib and gzip decoding with automatic header detection, or add 16 to decode only the gzip format (the zlib format will return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a crc32 instead of an adler32. inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg is set to null if there is no error message. inflateInit2 does not perform any decompression apart from reading the zlib header if present: this will be done by inflate(). (So next_in and avail_in may be modified, but next_out and avail_out are unchanged.) */ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, const Bytef *dictionary, uInt dictLength)); /* Initializes the decompression dictionary from the given uncompressed byte sequence. This function must be called immediately after a call of inflate, if that call returned Z_NEED_DICT. The dictionary chosen by the compressor can be determined from the adler32 value returned by that call of inflate. The compressor and decompressor must use exactly the same dictionary (see deflateSetDictionary). For raw inflate, this function can be called immediately after inflateInit2() or inflateReset() and before any call of inflate() to set the dictionary. The application must insure that the dictionary that was used for compression is provided. inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a parameter is invalid (such as NULL dictionary) or the stream state is inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the expected one (incorrect adler32 value). inflateSetDictionary does not perform any decompression: this will be done by subsequent calls of inflate(). */ ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); /* Skips invalid compressed data until a full flush point (see above the description of deflate with Z_FULL_FLUSH) can be found, or until all available input is skipped. No output is provided. inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the success case, the application may save the current current value of total_in which indicates where valid compressed data was found. In the error case, the application may repeatedly call inflateSync, providing more input each time, until success or end of the input data. */ ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, z_streamp source)); /* Sets the destination stream as a complete copy of the source stream. This function can be useful when randomly accessing a large stream. The first pass through the stream can periodically record the inflate state, allowing restarting inflate at those points when randomly accessing the stream. inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc being NULL). msg is left unchanged in both source and destination. */ ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); /* This function is equivalent to inflateEnd followed by inflateInit, but does not free and reallocate all the internal decompression state. The stream will keep attributes that may have been set by inflateInit2. inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being NULL). */ ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, int bits, int value)); /* This function inserts bits in the inflate input stream. The intent is that this function is used to start inflating at a bit position in the middle of a byte. The provided bits will be used before any bytes are used from next_in. This function should only be used with raw inflate, and should be used before the first inflate() call after inflateInit2() or inflateReset(). bits must be less than or equal to 16, and that many of the least significant bits of value will be inserted in the input. inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, gz_headerp head)); /* inflateGetHeader() requests that gzip header information be stored in the provided gz_header structure. inflateGetHeader() may be called after inflateInit2() or inflateReset(), and before the first call of inflate(). As inflate() processes the gzip stream, head->done is zero until the header is completed, at which time head->done is set to one. If a zlib stream is being decoded, then head->done is set to -1 to indicate that there will be no gzip header information forthcoming. Note that Z_BLOCK can be used to force inflate() to return immediately after header processing is complete and before any actual data is decompressed. The text, time, xflags, and os fields are filled in with the gzip header contents. hcrc is set to true if there is a header CRC. (The header CRC was valid if done is set to one.) If extra is not Z_NULL, then extra_max contains the maximum number of bytes to write to extra. Once done is true, extra_len contains the actual extra field length, and extra contains the extra field, or that field truncated if extra_max is less than extra_len. If name is not Z_NULL, then up to name_max characters are written there, terminated with a zero unless the length is greater than name_max. If comment is not Z_NULL, then up to comm_max characters are written there, terminated with a zero unless the length is greater than comm_max. When any of extra, name, or comment are not Z_NULL and the respective field is not present in the header, then that field is set to Z_NULL to signal its absence. This allows the use of deflateSetHeader() with the returned structure to duplicate the header. However if those fields are set to allocated memory, then the application will need to save those pointers elsewhere so that they can be eventually freed. If inflateGetHeader is not used, then the header information is simply discarded. The header is always checked for validity, including the header CRC if present. inflateReset() will reset the process to discard the header information. The application would need to call inflateGetHeader() again to retrieve the header from the next gzip stream. inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ /* ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, unsigned char FAR *window)); Initialize the internal stream state for decompression using inflateBack() calls. The fields zalloc, zfree and opaque in strm must be initialized before the call. If zalloc and zfree are Z_NULL, then the default library- derived memory allocation routines are used. windowBits is the base two logarithm of the window size, in the range 8..15. window is a caller supplied buffer of that size. Except for special applications where it is assured that deflate was used with small window sizes, windowBits must be 15 and a 32K byte window must be supplied to be able to decompress general deflate streams. See inflateBack() for the usage of these routines. inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of the paramaters are invalid, Z_MEM_ERROR if the internal state could not be allocated, or Z_VERSION_ERROR if the version of the library does not match the version of the header file. */ typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, in_func in, void FAR *in_desc, out_func out, void FAR *out_desc)); /* inflateBack() does a raw inflate with a single call using a call-back interface for input and output. This is more efficient than inflate() for file i/o applications in that it avoids copying between the output and the sliding window by simply making the window itself the output buffer. This function trusts the application to not change the output buffer passed by the output function, at least until inflateBack() returns. inflateBackInit() must be called first to allocate the internal state and to initialize the state with the user-provided window buffer. inflateBack() may then be used multiple times to inflate a complete, raw deflate stream with each call. inflateBackEnd() is then called to free the allocated state. A raw deflate stream is one with no zlib or gzip header or trailer. This routine would normally be used in a utility that reads zip or gzip files and writes out uncompressed files. The utility would decode the header and process the trailer on its own, hence this routine expects only the raw deflate stream to decompress. This is different from the normal behavior of inflate(), which expects either a zlib or gzip header and trailer around the deflate stream. inflateBack() uses two subroutines supplied by the caller that are then called by inflateBack() for input and output. inflateBack() calls those routines until it reads a complete deflate stream and writes out all of the uncompressed data, or until it encounters an error. The function's parameters and return types are defined above in the in_func and out_func typedefs. inflateBack() will call in(in_desc, &buf) which should return the number of bytes of provided input, and a pointer to that input in buf. If there is no input available, in() must return zero--buf is ignored in that case--and inflateBack() will return a buffer error. inflateBack() will call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() should return zero on success, or non-zero on failure. If out() returns non-zero, inflateBack() will return with an error. Neither in() nor out() are permitted to change the contents of the window provided to inflateBackInit(), which is also the buffer that out() uses to write from. The length written by out() will be at most the window size. Any non-zero amount of input may be provided by in(). For convenience, inflateBack() can be provided input on the first call by setting strm->next_in and strm->avail_in. If that input is exhausted, then in() will be called. Therefore strm->next_in must be initialized before calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in must also be initialized, and then if strm->avail_in is not zero, input will initially be taken from strm->next_in[0 .. strm->avail_in - 1]. The in_desc and out_desc parameters of inflateBack() is passed as the first parameter of in() and out() respectively when they are called. These descriptors can be optionally used to pass any information that the caller- supplied in() and out() functions need to do their job. On return, inflateBack() will set strm->next_in and strm->avail_in to pass back any unused input that was provided by the last in() call. The return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR if in() or out() returned an error, Z_DATA_ERROR if there was a format error in the deflate stream (in which case strm->msg is set to indicate the nature of the error), or Z_STREAM_ERROR if the stream was not properly initialized. In the case of Z_BUF_ERROR, an input or output error can be distinguished using strm->next_in which will be Z_NULL only if in() returned an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to out() returning non-zero. (in() will always be called before out(), so strm->next_in is assured to be defined if out() returns non-zero.) Note that inflateBack() cannot return Z_OK. */ ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); /* All memory allocated by inflateBackInit() is freed. inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream state was inconsistent. */ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); /* Return flags indicating compile-time options. Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: 1.0: size of uInt 3.2: size of uLong 5.4: size of voidpf (pointer) 7.6: size of z_off_t Compiler, assembler, and debug options: 8: DEBUG 9: ASMV or ASMINF -- use ASM code 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention 11: 0 (reserved) One-time table building (smaller code, but not thread-safe if true): 12: BUILDFIXED -- build static block decoding tables when needed 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed 14,15: 0 (reserved) Library content (indicates missing functionality): 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking deflate code when not needed) 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect and decode gzip streams (to avoid linking crc code) 18-19: 0 (reserved) Operation variations (changes in library functionality): 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate 21: FASTEST -- deflate algorithm with only one, lowest compression level 22,23: 0 (reserved) The sprintf variant used by gzprintf (zero is best): 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! 26: 0 = returns value, 1 = void -- 1 means inferred string length returned Remainder: 27-31: 0 (reserved) */ /* utility functions */ /* The following utility functions are implemented on top of the basic stream-oriented functions. To simplify the interface, some default options are assumed (compression level and memory usage, standard memory allocation functions). The source code of these utility functions can easily be modified if you need special options. */ ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)); /* Compresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be at least the value returned by compressBound(sourceLen). Upon exit, destLen is the actual size of the compressed buffer. This function can be used to compress a whole file at once if the input file is mmap'ed. compress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer. */ ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level)); /* Compresses the source buffer into the destination buffer. The level parameter has the same meaning as in deflateInit. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be at least the value returned by compressBound(sourceLen). Upon exit, destLen is the actual size of the compressed buffer. compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, Z_STREAM_ERROR if the level parameter is invalid. */ ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); /* compressBound() returns an upper bound on the compressed size after compress() or compress2() on sourceLen bytes. It would be used before a compress() or compress2() call to allocate the destination buffer. */ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)); /* Decompresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be large enough to hold the entire uncompressed data. (The size of the uncompressed data must have been saved previously by the compressor and transmitted to the decompressor by some mechanism outside the scope of this compression library.) Upon exit, destLen is the actual size of the compressed buffer. This function can be used to decompress a whole file at once if the input file is mmap'ed. uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. */ typedef voidp gzFile; ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); /* Opens a gzip (.gz) file for reading or writing. The mode parameter is as in fopen ("rb" or "wb") but can also include a compression level ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman only compression as in "wb1h", or 'R' for run-length encoding as in "wb1R". (See the description of deflateInit2 for more information about the strategy parameter.) gzopen can be used to read a file which is not in gzip format; in this case gzread will directly read from the file without decompression. gzopen returns NULL if the file could not be opened or if there was insufficient memory to allocate the (de)compression state; errno can be checked to distinguish the two cases (if errno is zero, the zlib error is Z_MEM_ERROR). */ ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); /* gzdopen() associates a gzFile with the file descriptor fd. File descriptors are obtained from calls like open, dup, creat, pipe or fileno (in the file has been previously opened with fopen). The mode parameter is as in gzopen. The next call of gzclose on the returned gzFile will also close the file descriptor fd, just like fclose(fdopen(fd), mode) closes the file descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). gzdopen returns NULL if there was insufficient memory to allocate the (de)compression state. */ ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); /* Dynamically update the compression level or strategy. See the description of deflateInit2 for the meaning of these parameters. gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not opened for writing. */ ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); /* Reads the given number of uncompressed bytes from the compressed file. If the input file was not in gzip format, gzread copies the given number of bytes into the buffer. gzread returns the number of uncompressed bytes actually read (0 for end of file, -1 for error). */ ZEXTERN int ZEXPORT gzwrite OF((gzFile file, voidpc buf, unsigned len)); /* Writes the given number of uncompressed bytes into the compressed file. gzwrite returns the number of uncompressed bytes actually written (0 in case of error). */ ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); /* Converts, formats, and writes the args to the compressed file under control of the format string, as in fprintf. gzprintf returns the number of uncompressed bytes actually written (0 in case of error). The number of uncompressed bytes written is limited to 4095. The caller should assure that this limit is not exceeded. If it is exceeded, then gzprintf() will return return an error (0) with nothing written. In this case, there may also be a buffer overflow with unpredictable consequences, which is possible only if zlib was compiled with the insecure functions sprintf() or vsprintf() because the secure snprintf() or vsnprintf() functions were not available. */ ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); /* Writes the given null-terminated string to the compressed file, excluding the terminating null character. gzputs returns the number of characters written, or -1 in case of error. */ ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); /* Reads bytes from the compressed file until len-1 characters are read, or a newline character is read and transferred to buf, or an end-of-file condition is encountered. The string is then terminated with a null character. gzgets returns buf, or Z_NULL in case of error. */ ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); /* Writes c, converted to an unsigned char, into the compressed file. gzputc returns the value that was written, or -1 in case of error. */ ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); /* Reads one byte from the compressed file. gzgetc returns this byte or -1 in case of end of file or error. */ ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); /* Push one character back onto the stream to be read again later. Only one character of push-back is allowed. gzungetc() returns the character pushed, or -1 on failure. gzungetc() will fail if a character has been pushed but not read yet, or if c is -1. The pushed character will be discarded if the stream is repositioned with gzseek() or gzrewind(). */ ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); /* Flushes all pending output into the compressed file. The parameter flush is as in the deflate() function. The return value is the zlib error number (see function gzerror below). gzflush returns Z_OK if the flush parameter is Z_FINISH and all output could be flushed. gzflush should be called only when strictly necessary because it can degrade compression. */ ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, z_off_t offset, int whence)); /* Sets the starting position for the next gzread or gzwrite on the given compressed file. The offset represents a number of bytes in the uncompressed data stream. The whence parameter is defined as in lseek(2); the value SEEK_END is not supported. If the file is opened for reading, this function is emulated but can be extremely slow. If the file is opened for writing, only forward seeks are supported; gzseek then compresses a sequence of zeroes up to the new starting position. gzseek returns the resulting offset location as measured in bytes from the beginning of the uncompressed stream, or -1 in case of error, in particular if the file is opened for writing and the new starting position would be before the current position. */ ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); /* Rewinds the given file. This function is supported only for reading. gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) */ ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); /* Returns the starting position for the next gzread or gzwrite on the given compressed file. This position represents a number of bytes in the uncompressed data stream. gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) */ ZEXTERN int ZEXPORT gzeof OF((gzFile file)); /* Returns 1 when EOF has previously been detected reading the given input stream, otherwise zero. */ ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); /* Returns 1 if file is being read directly without decompression, otherwise zero. */ ZEXTERN int ZEXPORT gzclose OF((gzFile file)); /* Flushes all pending output if necessary, closes the compressed file and deallocates all the (de)compression state. The return value is the zlib error number (see function gzerror below). */ ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); /* Returns the error message for the last error which occurred on the given compressed file. errnum is set to zlib error number. If an error occurred in the file system and not in the compression library, errnum is set to Z_ERRNO and the application may consult errno to get the exact error code. */ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); /* Clears the error and end-of-file flags for file. This is analogous to the clearerr() function in stdio. This is useful for continuing to read a gzip file that is being written concurrently. */ /* checksum functions */ /* These functions are not related to compression but are exported anyway because they might be useful in applications using the compression library. */ ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); /* Update a running Adler-32 checksum with the bytes buf[0..len-1] and return the updated checksum. If buf is NULL, this function returns the required initial value for the checksum. An Adler-32 checksum is almost as reliable as a CRC32 but can be computed much faster. Usage example: uLong adler = adler32(0L, Z_NULL, 0); while (read_buffer(buffer, length) != EOF) { adler = adler32(adler, buffer, length); } if (adler != original_adler) error(); */ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, z_off_t len2)); /* Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. */ ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); /* Update a running CRC-32 with the bytes buf[0..len-1] and return the updated CRC-32. If buf is NULL, this function returns the required initial value for the for the crc. Pre- and post-conditioning (one's complement) is performed within this function so it shouldn't be done by the application. Usage example: uLong crc = crc32(0L, Z_NULL, 0); while (read_buffer(buffer, length) != EOF) { crc = crc32(crc, buffer, length); } if (crc != original_crc) error(); */ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); /* Combine two CRC-32 check values into one. For two sequences of bytes, seq1 and seq2 with lengths len1 and len2, CRC-32 check values were calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and len2. */ /* various hacks, don't look :) */ /* deflateInit and inflateInit are macros to allow checking the zlib version * and the compiler's view of z_stream: */ ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, const char *version, int stream_size)); ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, const char *version, int stream_size)); ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy, const char *version, int stream_size)); ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, const char *version, int stream_size)); ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, unsigned char FAR *window, const char *version, int stream_size)); #define deflateInit(strm, level) \ deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) #define inflateInit(strm) \ inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) #define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ (strategy), ZLIB_VERSION, sizeof(z_stream)) #define inflateInit2(strm, windowBits) \ inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) #define inflateBackInit(strm, windowBits, window) \ inflateBackInit_((strm), (windowBits), (window), \ ZLIB_VERSION, sizeof(z_stream)) #if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) struct internal_state {int dummy;}; /* hack for buggy compilers */ #endif ZEXTERN const char * ZEXPORT zError OF((int)); ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); #ifdef __cplusplus } #endif #endif /* ZLIB_H */ snort-2.9.15.1/src/win32/WIN32-Includes/config.h0000644000000000000000000002306313571426536015540 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2005-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* $Id$ */ #ifndef __CONFIG_H__ #define __CONFIG_H__ /* config.h. Generated automatically by configure. */ /* config.h.in. Generated automatically from configure.in by autoheader. */ /* Define if on AIX 3. System headers sometimes define this. We just want to avoid a redefinition error message. */ #ifndef _ALL_SOURCE /* #undef _ALL_SOURCE */ #endif /* Define if you have the ANSI C header files. */ /* #undef STDC_HEADERS */ /* Define if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel and VAX). */ #define WORDS_LITTLEENDIAN 1 #define WIN32 1 #define ERRLIST_PREDEFINED 1 /* Define if you have the snprintf function. */ #define HAVE_SNPRINTF 1 /* Define if you have the strerror function. */ #define HAVE_STRERROR 1 /* Define if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define if you have the header file. */ #define HAVE_STDINT_H 1 /* Define if you have the header file. */ #define HAVE_STRING_H 1 /* Define if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define if you have the pcap library (-lpcap). */ #define HAVE_LIBPCAP 1 /* Define if you have vswprintf() function */ #define HAVE_VSWPRINTF 1 /* Define if you have wprintf() function */ #define HAVE_WPRINTF 1 /* Define to 1 if you have the header file. */ #define HAVE_WCHAR_H 1 /* Define to 1 if you have zlib support. */ #define HAVE_ZLIB 1 #ifndef SIZEOF_LONG_INT #define SIZEOF_LONG_INT 4 #endif #ifdef ENABLE_RESPONSE #define VERSION_ENABLE_RESPONSE "-FlexRESP" #else #define VERSION_ENABLE_RESPONSE #endif #ifdef DEBUG #define VERSION_DEBUG " [DEBUG] " #else #define VERSION_DEBUG #endif #define LIBPCAP_ACCUMULATES /* * This version number here, and package name below, * should both match the ones specified in the * AM_INIT_AUTOMAKE() macro of configure.in */ #define VERSION "2.9.15.1"VERSION_ENABLE_RESPONSE"-WIN32"VERSION_DEBUG #define PACKAGE "snort" #define IFNAMSIZ 255 /* _WIN32_WINNT has been modified to support SetDllDirectory API introduced in * Windows Server 2003 with SP1 and Windows XP with SP2 for Windows DLL Load Vulnerability. * As per documentation available on support forum, the macro corresponding to 0x0502 is _WIN32_WINNT_WS03. * However, Visual studio 6.0 on Win XP SP3 reports this as an undeclared identifier. * So, we decided to use numerical value instead of macro. */ #undef _WIN32_WINNT #define _WIN32_WINNT 0x0502 #undef NTDDI_VERSION #define NTDDI_VERSION 0x05020000 /* Abuse header guards to prevent winscard.h from being included. This was needed to prevent conflict with sqlfront.h */ #define _WINSCARD_H_ #include #include #ifdef _MSC_VER #pragma warning( disable : 4028 ) #endif #include #include #ifdef _MSC_VER #pragma warning( default : 4028 ) #endif #include #include #include #ifndef __MINGW32__ typedef int pid_t; #endif #ifndef __CYGWIN__ typedef long ssize_t; #endif #include #include "rpc/types.h" #undef interface /* Declare standard integer datatypes */ #ifdef u_int8_t #undef u_int8_t #endif #ifdef u_int16_t #undef u_int16_t #endif #ifdef u_int32_t #undef u_int32_t #endif #include #ifndef INET6_ADDRSTRLEN #define INET6_ADDRSTRLEN 46 #endif #if defined(WIN32) && !defined(inline) #define inline __inline #endif /* required for some calls to open(), * but it isn't defined under Win32. * Using 0x0080 to match * from OpenBSD. */ #ifndef O_SYNC #define O_SYNC 0x0080 #endif #ifndef CDECL #define CDECL __cdecl #endif // #define SIGKILL 9 /* kill (cannot be caught or ignored) */ #define SIGQUIT 3 /* quit */ #define SIGNAL_SNORT_RELOAD 1 /* Reload */ #define SIGNAL_SNORT_DUMP_STATS 30 /* Dump stats */ #define SIGNAL_SNORT_ROTATE_STATS 31 /* Rotate stats */ #define SIGPIPE 13 /* write on a pipe with no one to read it */ // #define EEXIST 17 /* File exists */ #ifndef W_OK #define W_OK 0x02 /* test for write permission */ #endif #ifndef R_OK #define R_OK 0x04 /* test for read permission */ #endif #define S_ISDIR(x) (((x) & 0170000) == 0040000) /* directory */ #define S_IRWXU 0000700 /* RWX mask for owner */ #define S_IRWXG 0000070 /* RWX mask for group */ #define S_IROTH 0000004 /* R for other */ #define S_IXOTH 0000001 /* X for other */ #define bcopy(src, dst, count) memcpy((void *)dst, (const void *)src, (size_t) count) #define bzero(addr, count) memset((addr), 0, (count)) #define index strchr #define mkdir(x, y) _mkdir(x) #define snprintf _snprintf #define strncasecmp strnicmp #define strcasecmp stricmp #define ftruncate _chsize #if _MSC_VER < 1500 /* VC9 defines this */ #define vsnprintf _vsnprintf #define strdup _strdup #endif #define IXDR_GET_LONG(buf) ((long)ntohl((u_long)*(buf)++)) #define IXDR_GET_ENUM(buf, t) ((t)IXDR_GET_LONG(buf)) #define RPC_MSG_VERSION ((u_long) 2) char * strtok_r(char *s1, const char *s2, char **lasts); int inet_aton(const char *cp, struct in_addr *addr); int inet_pton(int af, const char *src, void *dst); enum msg_type { CALL=0, REPLY=1 }; typedef unsigned long mode_t; struct timezone { int tz_minuteswest; /* minutes west of Greenwich */ int tz_dsttime; /* type of dst correction */ }; /* * Interface request structure used for socket * ioctl's. All interface ioctl's must have parameter * definitions which begin with ifr_name. The * remainder may be interface specific. */ struct ifreq { char ifr_name[128]; /* if name, e.g. "en0" */ union { struct sockaddr ifru_addr; struct sockaddr ifru_dstaddr; struct sockaddr ifru_broadaddr; short ifru_flags; int ifru_metric; caddr_t ifru_data; } ifr_ifru; #define ifr_addr ifr_ifru.ifru_addr /* address */ #define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */ #define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */ #define ifr_flags ifr_ifru.ifru_flags /* flags */ #define ifr_metric ifr_ifru.ifru_metric /* metric */ #define ifr_mtu ifr_ifru.ifru_metric /* mtu (overload) */ #define ifr_media ifr_ifru.ifru_metric /* media options (overload) */ #define ifr_data ifr_ifru.ifru_data /* for use by interface */ }; #define RUSAGE_SELF 0 /* calling process */ #define RUSAGE_CHILDREN -1 /* terminated child processes */ struct rusage { struct timeval ru_utime;/* user time used */ struct timeval ru_stime;/* system time used */ long ru_maxrss; long ru_ixrss; /* integral shared memory size */ long ru_idrss; /* integral unshared data " */ long ru_isrss; /* integral unshared stack " */ long ru_minflt; /* page reclaims */ long ru_majflt; /* page faults */ long ru_nswap; /* swaps */ long ru_inblock; /* block input operations */ long ru_oublock; /* block output operations */ long ru_msgsnd; /* messages sent */ long ru_msgrcv; /* messages received */ long ru_nsignals; /* signals received */ long ru_nvcsw; /* voluntary context switches */ long ru_nivcsw; /* involuntary " */ }; int gettimeofday(struct timeval *,struct timezone *); void *GetAdapterFromList(void *, int); char *print_interface(const char *); void PrintDeviceList(const char *); int init_winsock(void); int ffs(int x); inline int isblank(int c) { if (c == ' ' || c == '\t' || c == '\v') return 1; return 0; } #if defined(ENABLE_WIN32_SERVICE) #define SERVICE_CMDLINE_PARAM "/SERVICE" #define SERVICE_INSTALL_CMDLINE_PARAM "/INSTALL" #define SERVICE_UNINSTALL_CMDLINE_PARAM "/UNINSTALL" #define SERVICE_SHOW_CMDLINE_PARAM "/SHOW" int SnortServiceMain(int argc, char* argv[]); #endif /* ENABLE_WIN32_SERVICE */ #ifndef S_IFIFO #define S_IFIFO _S_IFIFO #endif #ifndef __FUNCTION__ #if _MSV_VER < 1300 #define __FUNCTION__ "dont know" #else #define __FUNCTION__ __func__ #endif #endif #endif /* __CONFIG_H__ */ snort-2.9.15.1/src/win32/WIN32-Includes/getopt.h0000644000175200017520000000232613571422610015617 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _SNORT_GETOPT_H_ #define _SNORT_GETOPT_H_ #ifdef SNORT_GETOPT #define _next_char(string) (char)(*(string+1)) extern char * optarg; extern int optind; int getopt(int, char**, char*); #else #include #endif #endif /* _SNORT_GETOPT_H_ */ snort-2.9.15.1/src/win32/WIN32-Includes/getopt1.h0000644000175200017520000001000413571422610015670 00000000000000/* Declarations for getopt. Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it 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. */ #ifndef _GETOPT1_H #define _GETOPT1_H 1 #ifndef HAVE_GETOPT_LONG #ifdef __cplusplus extern "C" { #endif /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ extern char *optarg; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns EOF, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ extern int optind; /* Callers store zero here to inhibit the error message `getopt' prints for unrecognized options. */ extern int opterr; /* Set to an option character which was unrecognized. */ extern int optopt; /* Describe the long-named options requested by the application. The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector of `struct option' terminated by an element containing a name which is zero. The field `has_arg' is: no_argument (or 0) if the option does not take an argument, required_argument (or 1) if the option requires an argument, optional_argument (or 2) if the option takes an optional argument. If the field `flag' is not NULL, it points to a variable that is set to the value given in the field `val' when the option is found, but left unchanged if the option is not found. To have a long-named option do something other than set an `int' to a compiled-in constant, such as set a value from `optarg', set the option's `flag' field to zero and its `val' field to a nonzero value (the equivalent single-letter option character, if there is one). For long options that have a zero `flag' field, `getopt' returns the contents of the `val' field. */ struct option { #if __STDC__ const char *name; #else char *name; #endif /* has_arg can't be an enum because some compilers complain about type mismatches in all the code that assumes it is an int. */ int has_arg; int *flag; int val; }; /* Names for the values of the `has_arg' field of `struct option'. */ #define no_argument 0 #define required_argument 1 #define optional_argument 2 #if __STDC__ #ifndef HAVE_GETOPT extern int getopt (int argc, char *const *argv, const char *optstring); #endif extern int getopt_long (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); extern int getopt_long_only (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); /* Internal only. Users should not call this directly. */ extern int _getopt_internal (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind, int long_only); #else /* not __STDC__ */ #ifndef HAVE_GETOPT extern int getopt (); #endif extern int getopt_long (); extern int getopt_long_only (); extern int _getopt_internal (); #endif /* not __STDC__ */ #ifdef __cplusplus } #endif #endif /* HAVE_GETOPT_LONG */ #endif /* _GETOPT_H */ snort-2.9.15.1/src/win32/WIN32-Includes/gnuc.h0000644000175200017520000000132213571422610015244 00000000000000/* @(#) $Header$ (LBL) */ /* Define __P() macro, if necessary */ #ifndef __P #if __STDC__ #define __P(protos) protos #else #define __P(protos) () #endif #endif /* inline foo */ #ifndef inline #ifndef __cplusplus #ifdef __GNUC__ #define inline __inline #else #define inline #endif #endif #endif /* * Handle new and old "dead" routine prototypes * * For example: * * __dead void foo(void) __attribute__((volatile)); * */ #ifdef __GNUC__ #ifndef __dead #define __dead volatile #endif #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) #ifndef __attribute__ #define __attribute__(args) #endif #endif #else #ifndef __dead #define __dead #endif #ifndef __attribute__ #define __attribute__(args) #endif #endif snort-2.9.15.1/src/win32/WIN32-Includes/inttypes.h0000644000175200017520000000213513571422610016172 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2007-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __INTTYPES_H__ #define __INTTYPES_H__ #ifndef PRIu64 #define _SF_PREFIX "I64" #define PRIu64 _SF_PREFIX "u" #define PRIi64 _SF_PREFIX "i" #define PRIx64 _SF_PREFIX "x" #endif #endif /* __INTTYPES_H__ */ snort-2.9.15.1/src/win32/WIN32-Includes/pcre.h0000644000175200017520000003147113571422610015251 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* This is the public header file for the PCRE library, to be #included by applications that call the PCRE functions. Copyright (c) 1997-2010 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ #ifndef _PCRE_H #define _PCRE_H /* The current PCRE version information. */ #define PCRE_MAJOR 8 #define PCRE_MINOR 10 #define PCRE_PRERELEASE #define PCRE_STATIC 1 /* Include this here so that we know we're static */ #define PCRE_DATE 2010-06-25 /* When an application links to a PCRE DLL in Windows, the symbols that are imported have to be identified as such. When building PCRE, the appropriate export setting is defined in pcre_internal.h, which includes this file. So we don't change existing definitions of PCRE_EXP_DECL and PCRECPP_EXP_DECL. */ #if defined(_WIN32) && !defined(PCRE_STATIC) # ifndef PCRE_EXP_DECL # define PCRE_EXP_DECL extern __declspec(dllimport) # endif # ifdef __cplusplus # ifndef PCRECPP_EXP_DECL # define PCRECPP_EXP_DECL extern __declspec(dllimport) # endif # ifndef PCRECPP_EXP_DEFN # define PCRECPP_EXP_DEFN __declspec(dllimport) # endif # endif #endif /* By default, we use the standard "extern" declarations. */ #ifndef PCRE_EXP_DECL # ifdef __cplusplus # define PCRE_EXP_DECL extern "C" # else # define PCRE_EXP_DECL extern # endif #endif #ifdef __cplusplus # ifndef PCRECPP_EXP_DECL # define PCRECPP_EXP_DECL extern # endif # ifndef PCRECPP_EXP_DEFN # define PCRECPP_EXP_DEFN # endif #endif /* Have to include stdlib.h in order to ensure that size_t is defined; it is needed here for malloc. */ #include /* Allow for C++ users */ #ifdef __cplusplus extern "C" { #endif /* Options. Some are compile-time only, some are run-time only, and some are both, so we keep them all distinct. */ #define PCRE_CASELESS 0x00000001 #define PCRE_MULTILINE 0x00000002 #define PCRE_DOTALL 0x00000004 #define PCRE_EXTENDED 0x00000008 #define PCRE_ANCHORED 0x00000010 #define PCRE_DOLLAR_ENDONLY 0x00000020 #define PCRE_EXTRA 0x00000040 #define PCRE_NOTBOL 0x00000080 #define PCRE_NOTEOL 0x00000100 #define PCRE_UNGREEDY 0x00000200 #define PCRE_NOTEMPTY 0x00000400 #define PCRE_UTF8 0x00000800 #define PCRE_NO_AUTO_CAPTURE 0x00001000 #define PCRE_NO_UTF8_CHECK 0x00002000 #define PCRE_AUTO_CALLOUT 0x00004000 #define PCRE_PARTIAL_SOFT 0x00008000 #define PCRE_PARTIAL 0x00008000 /* Backwards compatible synonym */ #define PCRE_DFA_SHORTEST 0x00010000 #define PCRE_DFA_RESTART 0x00020000 #define PCRE_FIRSTLINE 0x00040000 #define PCRE_DUPNAMES 0x00080000 #define PCRE_NEWLINE_CR 0x00100000 #define PCRE_NEWLINE_LF 0x00200000 #define PCRE_NEWLINE_CRLF 0x00300000 #define PCRE_NEWLINE_ANY 0x00400000 #define PCRE_NEWLINE_ANYCRLF 0x00500000 #define PCRE_BSR_ANYCRLF 0x00800000 #define PCRE_BSR_UNICODE 0x01000000 #define PCRE_JAVASCRIPT_COMPAT 0x02000000 #define PCRE_NO_START_OPTIMIZE 0x04000000 #define PCRE_NO_START_OPTIMISE 0x04000000 #define PCRE_PARTIAL_HARD 0x08000000 #define PCRE_NOTEMPTY_ATSTART 0x10000000 #define PCRE_UCP 0x20000000 /* Exec-time and get/set-time error codes */ #define PCRE_ERROR_NOMATCH (-1) #define PCRE_ERROR_NULL (-2) #define PCRE_ERROR_BADOPTION (-3) #define PCRE_ERROR_BADMAGIC (-4) #define PCRE_ERROR_UNKNOWN_OPCODE (-5) #define PCRE_ERROR_UNKNOWN_NODE (-5) /* For backward compatibility */ #define PCRE_ERROR_NOMEMORY (-6) #define PCRE_ERROR_NOSUBSTRING (-7) #define PCRE_ERROR_MATCHLIMIT (-8) #define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */ #define PCRE_ERROR_BADUTF8 (-10) #define PCRE_ERROR_BADUTF8_OFFSET (-11) #define PCRE_ERROR_PARTIAL (-12) #define PCRE_ERROR_BADPARTIAL (-13) #define PCRE_ERROR_INTERNAL (-14) #define PCRE_ERROR_BADCOUNT (-15) #define PCRE_ERROR_DFA_UITEM (-16) #define PCRE_ERROR_DFA_UCOND (-17) #define PCRE_ERROR_DFA_UMLIMIT (-18) #define PCRE_ERROR_DFA_WSSIZE (-19) #define PCRE_ERROR_DFA_RECURSE (-20) #define PCRE_ERROR_RECURSIONLIMIT (-21) #define PCRE_ERROR_NULLWSLIMIT (-22) /* No longer actually used */ #define PCRE_ERROR_BADNEWLINE (-23) /* Request types for pcre_fullinfo() */ #define PCRE_INFO_OPTIONS 0 #define PCRE_INFO_SIZE 1 #define PCRE_INFO_CAPTURECOUNT 2 #define PCRE_INFO_BACKREFMAX 3 #define PCRE_INFO_FIRSTBYTE 4 #define PCRE_INFO_FIRSTCHAR 4 /* For backwards compatibility */ #define PCRE_INFO_FIRSTTABLE 5 #define PCRE_INFO_LASTLITERAL 6 #define PCRE_INFO_NAMEENTRYSIZE 7 #define PCRE_INFO_NAMECOUNT 8 #define PCRE_INFO_NAMETABLE 9 #define PCRE_INFO_STUDYSIZE 10 #define PCRE_INFO_DEFAULT_TABLES 11 #define PCRE_INFO_OKPARTIAL 12 #define PCRE_INFO_JCHANGED 13 #define PCRE_INFO_HASCRORLF 14 #define PCRE_INFO_MINLENGTH 15 /* Request types for pcre_config(). Do not re-arrange, in order to remain compatible. */ #define PCRE_CONFIG_UTF8 0 #define PCRE_CONFIG_NEWLINE 1 #define PCRE_CONFIG_LINK_SIZE 2 #define PCRE_CONFIG_POSIX_MALLOC_THRESHOLD 3 #define PCRE_CONFIG_MATCH_LIMIT 4 #define PCRE_CONFIG_STACKRECURSE 5 #define PCRE_CONFIG_UNICODE_PROPERTIES 6 #define PCRE_CONFIG_MATCH_LIMIT_RECURSION 7 #define PCRE_CONFIG_BSR 8 /* Bit flags for the pcre_extra structure. Do not re-arrange or redefine these bits, just add new ones on the end, in order to remain compatible. */ #define PCRE_EXTRA_STUDY_DATA 0x0001 #define PCRE_EXTRA_MATCH_LIMIT 0x0002 #define PCRE_EXTRA_CALLOUT_DATA 0x0004 #define PCRE_EXTRA_TABLES 0x0008 #define PCRE_EXTRA_MATCH_LIMIT_RECURSION 0x0010 #define PCRE_EXTRA_MARK 0x0020 /* Types */ struct real_pcre; /* declaration; the definition is private */ typedef struct real_pcre pcre; /* When PCRE is compiled as a C++ library, the subject pointer type can be replaced with a custom type. For conventional use, the public interface is a const char *. */ #ifndef PCRE_SPTR #define PCRE_SPTR const char * #endif /* The structure for passing additional data to pcre_exec(). This is defined in such as way as to be extensible. Always add new fields at the end, in order to remain compatible. */ typedef struct pcre_extra { unsigned long int flags; /* Bits for which fields are set */ void *study_data; /* Opaque data from pcre_study() */ unsigned long int match_limit; /* Maximum number of calls to match() */ void *callout_data; /* Data passed back in callouts */ const unsigned char *tables; /* Pointer to character tables */ unsigned long int match_limit_recursion; /* Max recursive calls to match() */ unsigned char **mark; /* For passing back a mark pointer */ } pcre_extra; /* The structure for passing out data via the pcre_callout_function. We use a structure so that new fields can be added on the end in future versions, without changing the API of the function, thereby allowing old clients to work without modification. */ typedef struct pcre_callout_block { int version; /* Identifies version of block */ /* ------------------------ Version 0 ------------------------------- */ int callout_number; /* Number compiled into pattern */ int *offset_vector; /* The offset vector */ PCRE_SPTR subject; /* The subject being matched */ int subject_length; /* The length of the subject */ int start_match; /* Offset to start of this match attempt */ int current_position; /* Where we currently are in the subject */ int capture_top; /* Max current capture */ int capture_last; /* Most recently closed capture */ void *callout_data; /* Data passed in with the call */ /* ------------------- Added for Version 1 -------------------------- */ int pattern_position; /* Offset to next item in the pattern */ int next_item_length; /* Length of next item in the pattern */ /* ------------------------------------------------------------------ */ } pcre_callout_block; /* Indirection for store get and free functions. These can be set to alternative malloc/free functions if required. Special ones are used in the non-recursive case for "frames". There is also an optional callout function that is triggered by the (?) regex item. For Virtual Pascal, these definitions have to take another form. */ #ifndef VPCOMPAT PCRE_EXP_DECL void *(*pcre_malloc)(size_t); PCRE_EXP_DECL void (*pcre_free)(void *); PCRE_EXP_DECL void *(*pcre_stack_malloc)(size_t); PCRE_EXP_DECL void (*pcre_stack_free)(void *); PCRE_EXP_DECL int (*pcre_callout)(pcre_callout_block *); #else /* VPCOMPAT */ PCRE_EXP_DECL void *pcre_malloc(size_t); PCRE_EXP_DECL void pcre_free(void *); PCRE_EXP_DECL void *pcre_stack_malloc(size_t); PCRE_EXP_DECL void pcre_stack_free(void *); PCRE_EXP_DECL int pcre_callout(pcre_callout_block *); #endif /* VPCOMPAT */ /* Exported PCRE functions */ PCRE_EXP_DECL pcre *pcre_compile(const char *, int, const char **, int *, const unsigned char *); PCRE_EXP_DECL pcre *pcre_compile2(const char *, int, int *, const char **, int *, const unsigned char *); PCRE_EXP_DECL int pcre_config(int, void *); PCRE_EXP_DECL int pcre_copy_named_substring(const pcre *, const char *, int *, int, const char *, char *, int); PCRE_EXP_DECL int pcre_copy_substring(const char *, int *, int, int, char *, int); PCRE_EXP_DECL int pcre_dfa_exec(const pcre *, const pcre_extra *, const char *, int, int, int, int *, int , int *, int); PCRE_EXP_DECL int pcre_exec(const pcre *, const pcre_extra *, PCRE_SPTR, int, int, int, int *, int); PCRE_EXP_DECL void pcre_free_substring(const char *); PCRE_EXP_DECL void pcre_free_substring_list(const char **); PCRE_EXP_DECL int pcre_fullinfo(const pcre *, const pcre_extra *, int, void *); PCRE_EXP_DECL int pcre_get_named_substring(const pcre *, const char *, int *, int, const char *, const char **); PCRE_EXP_DECL int pcre_get_stringnumber(const pcre *, const char *); PCRE_EXP_DECL int pcre_get_stringtable_entries(const pcre *, const char *, char **, char **); PCRE_EXP_DECL int pcre_get_substring(const char *, int *, int, int, const char **); PCRE_EXP_DECL int pcre_get_substring_list(const char *, int *, int, const char ***); PCRE_EXP_DECL int pcre_info(const pcre *, int *, int *); PCRE_EXP_DECL const unsigned char *pcre_maketables(void); PCRE_EXP_DECL int pcre_refcount(pcre *, int); PCRE_EXP_DECL pcre_extra *pcre_study(const pcre *, int, const char **); PCRE_EXP_DECL const char *pcre_version(void); #ifdef __cplusplus } /* extern "C" */ #endif #endif /* End of pcre.h */ snort-2.9.15.1/src/win32/WIN32-Includes/pcreposix.h0000644000175200017520000001251413571422610016331 00000000000000/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ #ifndef _PCREPOSIX_H #define _PCREPOSIX_H /* This is the header for the POSIX wrapper interface to the PCRE Perl- Compatible Regular Expression library. It defines the things POSIX says should be there. I hope. Copyright (c) 1997-2009 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ /* Have to include stdlib.h in order to ensure that size_t is defined. */ #include /* Allow for C++ users */ #ifdef __cplusplus extern "C" { #endif /* Options, mostly defined by POSIX, but with some extras. */ #define REG_ICASE 0x0001 /* Maps to PCRE_CASELESS */ #define REG_NEWLINE 0x0002 /* Maps to PCRE_MULTILINE */ #define REG_NOTBOL 0x0004 /* Maps to PCRE_NOTBOL */ #define REG_NOTEOL 0x0008 /* Maps to PCRE_NOTEOL */ #define REG_DOTALL 0x0010 /* NOT defined by POSIX; maps to PCRE_DOTALL */ #define REG_NOSUB 0x0020 /* Maps to PCRE_NO_AUTO_CAPTURE */ #define REG_UTF8 0x0040 /* NOT defined by POSIX; maps to PCRE_UTF8 */ #define REG_STARTEND 0x0080 /* BSD feature: pass subject string by so,eo */ #define REG_NOTEMPTY 0x0100 /* NOT defined by POSIX; maps to PCRE_NOTEMPTY */ #define REG_UNGREEDY 0x0200 /* NOT defined by POSIX; maps to PCRE_UNGREEDY */ #define REG_UCP 0x0400 /* NOT defined by POSIX; maps to PCRE_UCP */ /* This is not used by PCRE, but by defining it we make it easier to slot PCRE into existing programs that make POSIX calls. */ #define REG_EXTENDED 0 /* Error values. Not all these are relevant or used by the wrapper. */ enum { REG_ASSERT = 1, /* internal error ? */ REG_BADBR, /* invalid repeat counts in {} */ REG_BADPAT, /* pattern error */ REG_BADRPT, /* ? * + invalid */ REG_EBRACE, /* unbalanced {} */ REG_EBRACK, /* unbalanced [] */ REG_ECOLLATE, /* collation error - not relevant */ REG_ECTYPE, /* bad class */ REG_EESCAPE, /* bad escape sequence */ REG_EMPTY, /* empty expression */ REG_EPAREN, /* unbalanced () */ REG_ERANGE, /* bad range inside [] */ REG_ESIZE, /* expression too big */ REG_ESPACE, /* failed to get memory */ REG_ESUBREG, /* bad back reference */ REG_INVARG, /* bad argument */ REG_NOMATCH /* match failed */ }; /* The structure representing a compiled regular expression. */ typedef struct { void *re_pcre; size_t re_nsub; size_t re_erroffset; } regex_t; /* The structure in which a captured offset is returned. */ typedef int regoff_t; typedef struct { regoff_t rm_so; regoff_t rm_eo; } regmatch_t; /* When an application links to a PCRE DLL in Windows, the symbols that are imported have to be identified as such. When building PCRE, the appropriate export settings are needed, and are set in pcreposix.c before including this file. */ #if defined(_WIN32) && !defined(PCRE_STATIC) && !defined(PCREPOSIX_EXP_DECL) # define PCREPOSIX_EXP_DECL extern __declspec(dllimport) # define PCREPOSIX_EXP_DEFN __declspec(dllimport) #endif /* By default, we use the standard "extern" declarations. */ #ifndef PCREPOSIX_EXP_DECL # ifdef __cplusplus # define PCREPOSIX_EXP_DECL extern "C" # define PCREPOSIX_EXP_DEFN extern "C" # else # define PCREPOSIX_EXP_DECL extern # define PCREPOSIX_EXP_DEFN extern # endif #endif /* The functions */ PCREPOSIX_EXP_DECL int regcomp(regex_t *, const char *, int); PCREPOSIX_EXP_DECL int regexec(const regex_t *, const char *, size_t, regmatch_t *, int); PCREPOSIX_EXP_DECL size_t regerror(int, const regex_t *, char *, size_t); PCREPOSIX_EXP_DECL void regfree(regex_t *); #ifdef __cplusplus } /* extern "C" */ #endif #endif /* End of pcreposix.h */ snort-2.9.15.1/src/win32/WIN32-Includes/stdint.h0000644000175200017520000000635713571422610015632 00000000000000/* $Id$ */ /* ** Copyright (C) 1998-2003 Chris Reid ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __STDINT_H__ #define __STDINT_H__ #include typedef __int8 int8_t; typedef __int16 int16_t; typedef __int32 int32_t; typedef unsigned __int8 uint8_t; #define UINT8_T_DEFINED typedef unsigned __int16 uint16_t; #define UINT16_T_DEFINED typedef unsigned __int32 uint32_t; #define UINT32_T_DEFINED #ifdef _MSC_VER # if _MSC_VER <= 1200 /* Visual C++ 6.0 */ /* Visual C++ 6.0 and before can't convert an unsigned __int64 * to a double, but can convert a signed __int64 to a double. * Alot of the code converts the UINT64 to a double for percent * calculations so we have to make this check */ typedef __int64 uint64_t; typedef __int64 int64_t; # else typedef unsigned __int64 uint64_t; typedef __int64 int64_t; # endif /* _MSC_VER <= 1200 */ #endif /* _MSC_VER */ /* win32 is ILP32 so a long will hold a ptr */ #ifdef _MSC_VER /* Visual C++ 6.0 - only 32 bit * Later Visual Studio versions define these */ # if _MSC_VER <= 1200 typedef long int intptr_t; typedef unsigned long int uintptr_t; #define _INTPTR_T_DEFINED #define _UINTPTR_T_DEFINED # endif /* #if _MSC_VER <= 1200 */ #else typedef long int intptr_t; typedef unsigned long int uintptr_t; #define _INTPTR_T_DEFINED #define _UINTPTR_T_DEFINED #endif /* #ifdef _MSC_VER */ #ifndef HAVE_U_INT8_T typedef uint8_t u_int8_t; #define HAVE_U_INT8_T #endif #ifndef HAVE_U_INT16_T typedef uint16_t u_int16_t; #define HAVE_U_INT16_T #endif #ifndef HAVE_U_INT32_T typedef uint32_t u_int32_t; #define HAVE_U_INT32_T #endif #ifndef HAVE_U_INT64_T typedef uint64_t u_int64_t; #define HAVE_U_INT64_T #endif #ifndef INT8_MAX # define INT8_MAX _I8_MAX #endif #ifndef INT16_MAX # define INT16_MAX _I16_MAX #endif #ifndef INT32_MAX # define INT32_MAX _I32_MAX #endif #ifndef INT64_MAX # define INT64_MAX _I64_MAX #endif #ifndef UINT8_MAX # define UINT8_MAX _UI8_MAX #endif #ifndef UINT16_MAX # define UINT16_MAX _UI16_MAX #endif #ifndef UINT32_MAX # define UINT32_MAX _UI32_MAX #endif #ifndef UINT64_MAX # ifdef _MSC_VER # if _MSC_VER <= 1200 /* Visual C++ 6.0 */ /* because we have to use a signed 64 bit type for double conversion */ # define UINT64_MAX _I64_MAX # else # define UINT64_MAX _UI64_MAX # endif # else /* No MSC_VER, make it signed */ # define UINT64_MAX _I64_MAX # endif #endif #ifndef SIZE_MAX #define SIZE_MAX UINT32_MAX #endif #endif /* __STDINT_H__ */ snort-2.9.15.1/src/win32/WIN32-Includes/syslog.h0000644000175200017520000002214013571422610015631 00000000000000/* $Id$ */ /* -/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/ . Copyright (c) 2001 Michael Davis . All rights reserved. . . Redistribution and use in source and binary forms, with or without . modification, are permitted provided that the following conditions . are met: . . 1. Redistributions of source code must retain the above copyright . notice, this list of conditions and the following disclaimer. . . 2. Redistributions in binary form must reproduce the above copyright . notice, this list of conditions and the following disclaimer in the . documentation and/or other materials provided with the distribution. . . 3. The name of author may not be used to endorse or promote products . derived from this software without specific prior written permission. . . THIS SOFTWARE IS PROVIDED ``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. . -\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\ */ /* $OpenBSD: syslog.h,v 1.5 1998/02/10 18:41:57 deraadt Exp $ */ /* $NetBSD: syslog.h,v 1.14 1996/04/03 20:46:44 christos Exp $ */ /* * Copyright (c) 1982, 1986, 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)syslog.h 8.1 (Berkeley) 6/2/93 */ #define _PATH_LOG "/dev/log" /* * priorities/facilities are encoded into a single 32-bit quantity, where the * bottom 3 bits are the priority (0-7) and the top 28 bits are the facility * (0-big number). Both the priorities and the facilities map roughly * one-to-one to strings in the syslogd(8) source code. This mapping is * included in this file. * * priorities (these are ordered) */ #define LOG_EMERG 0 /* system is unusable */ #define LOG_ALERT 1 /* action must be taken immediately */ #define LOG_CRIT 2 /* critical conditions */ #define LOG_ERR 3 /* error conditions */ #define LOG_WARNING 4 /* warning conditions */ #define LOG_NOTICE 5 /* normal but significant condition */ #define LOG_INFO 6 /* informational */ #define LOG_DEBUG 7 /* debug-level messages */ #define LOG_PRIMASK 0x07 /* mask to extract priority part (internal) */ /* extract priority */ #define LOG_PRI(p) ((p) & LOG_PRIMASK) #define LOG_MAKEPRI(fac, pri) (((fac) << 3) | (pri)) #ifdef SYSLOG_NAMES #define INTERNAL_NOPRI 0x10 /* the "no priority" priority */ /* mark "facility" */ #define INTERNAL_MARK LOG_MAKEPRI(LOG_NFACILITIES, 0) typedef struct _code { char *c_name; int c_val; } CODE; CODE prioritynames[] = { { "alert", LOG_ALERT }, { "crit", LOG_CRIT }, { "debug", LOG_DEBUG }, { "emerg", LOG_EMERG }, { "err", LOG_ERR }, { "error", LOG_ERR }, /* DEPRECATED */ { "info", LOG_INFO }, { "none", INTERNAL_NOPRI }, /* INTERNAL */ { "notice", LOG_NOTICE }, { "panic", LOG_EMERG }, /* DEPRECATED */ { "warn", LOG_WARNING }, /* DEPRECATED */ { "warning", LOG_WARNING }, { NULL, -1 }, }; #endif /* facility codes */ #define LOG_KERN (0<<3) /* kernel messages */ #define LOG_USER (1<<3) /* random user-level messages */ #define LOG_MAIL (2<<3) /* mail system */ #define LOG_DAEMON (3<<3) /* system daemons */ #define LOG_AUTH (4<<3) /* security/authorization messages */ #define LOG_SYSLOG (5<<3) /* messages generated internally by syslogd */ #define LOG_LPR (6<<3) /* line printer subsystem */ #define LOG_NEWS (7<<3) /* network news subsystem */ #define LOG_UUCP (8<<3) /* UUCP subsystem */ #define LOG_CRON (9<<3) /* clock daemon */ #define LOG_AUTHPRIV (10<<3) /* security/authorization messages (private) */ #define LOG_FTP (11<<3) /* ftp daemon */ /* other codes through 15 reserved for system use */ #define LOG_LOCAL0 (16<<3) /* reserved for local use */ #define LOG_LOCAL1 (17<<3) /* reserved for local use */ #define LOG_LOCAL2 (18<<3) /* reserved for local use */ #define LOG_LOCAL3 (19<<3) /* reserved for local use */ #define LOG_LOCAL4 (20<<3) /* reserved for local use */ #define LOG_LOCAL5 (21<<3) /* reserved for local use */ #define LOG_LOCAL6 (22<<3) /* reserved for local use */ #define LOG_LOCAL7 (23<<3) /* reserved for local use */ #define LOG_NFACILITIES 24 /* current number of facilities */ #define LOG_FACMASK 0x03f8 /* mask to extract facility part */ /* facility of pri */ #define LOG_FAC(p) (((p) & LOG_FACMASK) >> 3) #ifdef SYSLOG_NAMES CODE facilitynames[] = { { "auth", LOG_AUTH }, { "authpriv", LOG_AUTHPRIV }, { "cron", LOG_CRON }, { "daemon", LOG_DAEMON }, { "ftp", LOG_FTP }, { "kern", LOG_KERN }, { "lpr", LOG_LPR }, { "mail", LOG_MAIL }, { "mark", INTERNAL_MARK }, /* INTERNAL */ { "news", LOG_NEWS }, { "security", LOG_AUTH }, /* DEPRECATED */ { "syslog", LOG_SYSLOG }, { "user", LOG_USER }, { "uucp", LOG_UUCP }, { "local0", LOG_LOCAL0 }, { "local1", LOG_LOCAL1 }, { "local2", LOG_LOCAL2 }, { "local3", LOG_LOCAL3 }, { "local4", LOG_LOCAL4 }, { "local5", LOG_LOCAL5 }, { "local6", LOG_LOCAL6 }, { "local7", LOG_LOCAL7 }, { NULL, -1 }, }; #endif #ifdef _KERNEL #define LOG_PRINTF -1 /* pseudo-priority to indicate use of printf */ #endif /* * arguments to setlogmask. */ #define LOG_MASK(pri) (1 << (pri)) /* mask for one priority */ #define LOG_UPTO(pri) ((1 << ((pri)+1)) - 1) /* all priorities through pri */ /* * Option flags for openlog. * * LOG_ODELAY no longer does anything. * LOG_NDELAY is the inverse of what it used to be. */ #define LOG_PID 0x01 /* log the pid with each message */ #define LOG_CONS 0x02 /* log on the console if errors in sending */ #define LOG_ODELAY 0x04 /* delay open until first syslog() (default) */ #define LOG_NDELAY 0x08 /* don't delay open */ #define LOG_NOWAIT 0x10 /* don't wait for console forks: DEPRECATED */ #define LOG_PERROR 0x20 /* log to stderr as well */ #ifndef _KERNEL /* * Don't use va_list in the vsyslog() prototype. Va_list is typedef'd in two * places ( and ), so if we include one * of them here we may collide with the utility's includes. It's unreasonable * for utilities to have to include one of them to include syslog.h, so we get * _BSD_VA_LIST_ from and use it. */ #include #ifndef WIN32 #include #include #endif #ifdef WIN32 void AddEventSource(char *); void syslog(int, char *, ...); void vsyslog(int, char *, va_list); void openlog(char *, int, int); unsigned long resolve_host(char *); #else __BEGIN_DECLS void closelog __P((void)); void openlog __P((const char *, int, int)); int setlogmask __P((int)); void syslog __P((int, const char *, ...)) __attribute__((__format__(__printf__,2,3))); void vsyslog __P((int, const char *, _BSD_VA_LIST_)); __END_DECLS #endif #else /* !_KERNEL */ void logpri __P((int)); void log __P((int, const char *, ...)) __kprintf_attribute__((__format__(__kprintf__,2,3))); int addlog __P((const char *, ...)) __kprintf_attribute__((__format__(__kprintf__,1,2))); void logwakeup __P((void)); #endif /* !_KERNEL */ snort-2.9.15.1/src/win32/WIN32-Includes/unistd.h0000644000175200017520000000001313571422610015612 00000000000000/* $Id$ */ snort-2.9.15.1/src/win32/WIN32-Libraries/0000755000000000000000000000000013571426520014335 500000000000000snort-2.9.15.1/src/win32/WIN32-Libraries/libdnet/0000755000000000000000000000000013571426520015756 500000000000000snort-2.9.15.1/src/win32/WIN32-Libraries/libdnet/dnet.lib0000555000175200017520000041406413571422610017364 00000000000000! / 1305901072 0 12756 ` aèaèaèaèaèaèh‚j¦lÊoooooozÆzÆzÆzÆzÆzÆzÆzÆzÆŠ`Ž˜Ž˜Ž˜•••¥$¥$¥$¥$¥$¥$¥$¥$¥$¥$¥$¥$¥$¥$¥$¥$ÀþÀþÀþÀþÀþÆÆÆÆÆÑFÑFÑFÑFÑFÑFÑFÚ<Ú<Ú<Ú<Ú<Ú<Ú<Ú<Ú<Ú<Ú<Ú<Ú<Ú<Ú<Ú<Ú<Ú<Ú<Ú<Ú<Ú<Ú<Ú<VVVVVV°°°°°°°°°°°°°°(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶(¶_tun_close_tun_fileno_tun_name_tun_open_tun_recv_tun_send_strsep_strlcpy_strlcat_route_add_route_close_route_delete_route_get_route_loop_route_open_rand_add_rand_close_rand_get_rand_open_rand_set_rand_shuffle_rand_uint16_rand_uint32_rand_uint8_ip6_checksum_ip_close_ip_open_ip_send_ip_add_option_ip_checksum_ip_cksum_add??_C@_02CHGF@sl?$AA@??_C@_02EEIK@tr?$AA@??_C@_02FFHE@fd?$AA@??_C@_02GGHE@lo?$AA@??_C@_03DBFP@eth?$AA@??_C@_03HMEG@net?$AA@??_C@_03KNBL@ppp?$AA@??_C@_04ICFM@fddi?$AA@??_C@_05HGAB@?$CFs?$CFlu?$AA@_intf_close_intf_get_intf_get_dst_intf_get_src_intf_loop_intf_open_intf_set_fw_add_fw_close_fw_delete_fw_loop_fw_open_eth_close_eth_get_eth_open_eth_send_eth_set??_C@_01BJG@?6?$AA@??_C@_02HFBK@?3?5?$AA@??_C@_0L@OBLD@error?5?$CFlu?6?$AA@_err_errx_warn_warnx??_C@_01FCOA@?5?$AA@??_C@_02IHLC@?5?5?$AA@??_C@_02JBML@?$CFc?$AA@??_C@_03MFGH@?5?5?5?$AA@??_C@_04KAKK@hexl?$AA@??_C@_04OBKB@?$CF02x?$AA@??_C@_05OOAB@?$CF02x?5?$AA@??_C@_08MPCM@?5?5?$CF04x?3?5?$AA@_blob_delete_blob_free_blob_index_blob_insert_blob_new_blob_pack_blob_print_blob_printers_blob_read_blob_register_alloc_blob_register_pack_blob_rindex_blob_seek_blob_sprint_blob_unpack_blob_write_arp_add_arp_close_arp_delete_arp_get_arp_loop_arp_open??_C@_03KICP@?1?$CFd?$AA@??_C@_06POGA@?$PP?$PP?$PP?$PP?$PP?$PP?$AA@_addr_bcast_addr_btom_addr_btos_addr_cmp_addr_mtob_addr_net_addr_ntoa_addr_ntop_addr_ntos_addr_pton_addr_stob_addr_ston??_C@_00A@?$AA@??_C@_01ECJ@3?$AA@??_C@_01EOC@6?$AA@??_C@_01FBAH@1?$AA@??_C@_01FBMM@4?$AA@??_C@_01FLP@9?$AA@??_C@_01KOHF@7?$AA@??_C@_01KOLO@2?$AA@??_C@_01KPCI@8?$AA@??_C@_01PLFL@5?$AA@??_C@_01PLJA@0?$AA@??_C@_02BAND@08?$AA@??_C@_02BBEF@02?$AA@??_C@_02BBIO@07?$AA@??_C@_02BCLK@4e?$AA@??_C@_02BEFH@9f?$AA@??_C@_02BEJM@9c?$AA@??_C@_02BFAP@c1?$AA@??_C@_02BFME@c4?$AA@??_C@_02BICM@93?$AA@??_C@_02BIOH@96?$AA@??_C@_02BJHE@cd?$AA@??_C@_02BJLK@99?$AA@??_C@_02BJLP@ca?$AA@??_C@_02BNPF@0b?$AA@??_C@_02BOAK@45?$AA@??_C@_02BOMB@40?$AA@??_C@_02CAOC@d9?$AA@??_C@_02CBHE@d3?$AA@??_C@_02CBLP@d6?$AA@??_C@_02CDG@8c?$AA@??_C@_02CFDO@70?$AA@??_C@_02CFPF@75?$AA@??_C@_02CGAK@3b?$AA@??_C@_02CJEF@7e?$AA@??_C@_02CKHB@37?$AA@??_C@_02CKLK@32?$AA@??_C@_02CLCM@38?$AA@??_C@_02CNAP@df?$AA@??_C@_02CNME@dc?$AA@??_C@_02CPN@8f?$AA@??_C@_02DAKA@2b?$AA@??_C@_02DDFP@65?$AA@??_C@_02DDJE@60?$AA@??_C@_02DECB@ad?$AA@??_C@_02DEOK@aa?$AA@??_C@_02DGEI@e9?$AA@??_C@_02DGO@b4?$AA@??_C@_02DHBF@e6?$AA@??_C@_02DHNO@e3?$AA@??_C@_02DIFK@a1?$AA@??_C@_02DIJB@a4?$AA@??_C@_02DKF@b1?$AA@??_C@_02DLGO@ec?$AA@??_C@_02DLKF@ef?$AA@??_C@_02DMBA@22?$AA@??_C@_02DMNL@27?$AA@??_C@_02DNIG@28?$AA@??_C@_02DPOP@6e?$AA@??_C@_02EACB@c3?$AA@??_C@_02EAOK@c6?$AA@??_C@_02EBA@5e?$AA@??_C@_02EBHJ@9d?$AA@??_C@_02EBLC@9a?$AA@??_C@_02EBLH@c9?$AA@??_C@_02EEGL@00?$AA@??_C@_02EEKA@05?$AA@??_C@_02EHFP@4b?$AA@??_C@_02EIBA@0e?$AA@??_C@_02EKHJ@48?$AA@??_C@_02ELCE@47?$AA@??_C@_02ELOP@42?$AA@??_C@_02EMFK@cf?$AA@??_C@_02EMJB@cc?$AA@??_C@_02ENAC@91?$AA@??_C@_02ENMJ@94?$AA@??_C@_02FBPF@5b?$AA@??_C@_02FCAK@15?$AA@??_C@_02FCMB@10?$AA@??_C@_02FFLP@fa?$AA@??_C@_02FGEA@b6?$AA@??_C@_02FGIL@b3?$AA@??_C@_02FHBI@8a?$AA@??_C@_02FHBN@b9?$AA@??_C@_02FHND@8d?$AA@??_C@_02FJAP@f1?$AA@??_C@_02FJME@f4?$AA@??_C@_02FK@ff?$AA@??_C@_02FKDL@bc?$AA@??_C@_02FKPA@bf?$AA@??_C@_02FLGD@84?$AA@??_C@_02FLKI@81?$AA@??_C@_02FMND@58?$AA@??_C@_02FNEF@52?$AA@??_C@_02FNIO@57?$AA@??_C@_02FOLK@1e?$AA@??_C@_02GBAP@af?$AA@??_C@_02GBME@ac?$AA@??_C@_02GCDL@e4?$AA@??_C@_02GCPA@e1?$AA@??_C@_02GFEF@2e?$AA@??_C@_02GGHB@67?$AA@??_C@_02GGLK@62?$AA@??_C@_02GHCM@68?$AA@??_C@_02GHJ@18?$AA@??_C@_02GJDO@20?$AA@??_C@_02GJPF@25?$AA@??_C@_02GKAK@6b?$AA@??_C@_02GMOC@a9?$AA@??_C@_02GNHE@a3?$AA@??_C@_02GNLP@a6?$AA@??_C@_02GOEA@ea?$AA@??_C@_02GOIL@ed?$AA@??_C@_02HABA@72?$AA@??_C@_02HANL@77?$AA@??_C@_02HBIG@78?$AA@??_C@_02HCE@17?$AA@??_C@_02HDOP@3e?$AA@??_C@_02HEFK@d1?$AA@??_C@_02HEJB@d4?$AA@??_C@_02HICB@dd?$AA@??_C@_02HIOK@da?$AA@??_C@_02HMKA@7b?$AA@??_C@_02HOP@12?$AA@??_C@_02HPFP@35?$AA@??_C@_02HPJE@30?$AA@??_C@_02IACN@33?$AA@??_C@_02IAOG@36?$AA@??_C@_02IBLL@39?$AA@??_C@_02IDBJ@7a?$AA@??_C@_02IDNC@7d?$AA@??_C@_02IGL@50?$AA@??_C@_02IHFD@db?$AA@??_C@_02IKA@55?$AA@??_C@_02IKHF@d8?$AA@??_C@_02ILCI@d7?$AA@??_C@_02ILOD@d2?$AA@??_C@_02IMFG@3f?$AA@??_C@_02IMJN@3c?$AA@??_C@_02IPGC@74?$AA@??_C@_02IPKJ@71?$AA@??_C@_02JB@fc?$AA@??_C@_02JBPJ@eb?$AA@??_C@_02JCAG@a5?$AA@??_C@_02JCMN@a0?$AA@??_C@_02JFHI@6d?$AA@??_C@_02JFLD@6a?$AA@??_C@_02JGEM@26?$AA@??_C@_02JGIH@23?$AA@??_C@_02JHBB@29?$AA@??_C@_02JJAD@61?$AA@??_C@_02JJMI@64?$AA@??_C@_02JKDH@2c?$AA@??_C@_02JKPM@2f?$AA@??_C@_02JMNP@e8?$AA@??_C@_02JNEJ@e2?$AA@??_C@_02JNIC@e7?$AA@??_C@_02JOLG@ae?$AA@??_C@_02KBAD@1f?$AA@??_C@_02KBMI@1c?$AA@??_C@_02KCDH@54?$AA@??_C@_02KCPM@51?$AA@??_C@_02KEBB@82?$AA@??_C@_02KENK@87?$AA@??_C@_02KFEJ@be?$AA@??_C@_02KFIH@88?$AA@??_C@_02KGHN@f7?$AA@??_C@_02KGLG@f2?$AA@??_C@_02KHCA@f8?$AA@??_C@_02KIKB@8b?$AA@??_C@_02KJDC@b0?$AA@??_C@_02KJPJ@b5?$AA@??_C@_02KKAG@fb?$AA@??_C@_02KMOO@19?$AA@??_C@_02KNHI@13?$AA@??_C@_02KNLD@16?$AA@??_C@_02KOEM@5a?$AA@??_C@_02KOIH@5d?$AA@??_C@_02LCHA@97?$AA@??_C@_02LCLL@92?$AA@??_C@_02LDCN@98?$AA@??_C@_02LDOD@ce?$AA@??_C@_02LEFG@41?$AA@??_C@_02LEJN@44?$AA@??_C@_02LFP@1b?$AA@??_C@_02LHGC@0c?$AA@??_C@_02LHKJ@0f?$AA@??_C@_02LICN@4d?$AA@??_C@_02LIOG@4a?$AA@??_C@_02LKEE@09?$AA@??_C@_02LLBJ@06?$AA@??_C@_02LLNC@03?$AA@??_C@_02LOAL@9b?$AA@??_C@_02LPFD@c5?$AA@??_C@_02LPJI@c0?$AA@??_C@_02MAFG@6f?$AA@??_C@_02MAJN@6c?$AA@??_C@_02MCB@f3?$AA@??_C@_02MDGC@24?$AA@??_C@_02MDKJ@21?$AA@??_C@_02MEBM@ee?$AA@??_C@_02MGHF@a8?$AA@??_C@_02MHCI@a7?$AA@??_C@_02MHOD@a2?$AA@??_C@_02MIGH@e0?$AA@??_C@_02MIKM@e5?$AA@??_C@_02MLFD@ab?$AA@??_C@_02MMCN@63?$AA@??_C@_02MMOG@66?$AA@??_C@_02MNLL@69?$AA@??_C@_02MOK@f6?$AA@??_C@_02MPBJ@2a?$AA@??_C@_02MPNC@2d?$AA@??_C@_02NCLG@de?$AA@??_C@_02NFAD@31?$AA@??_C@_02NFMI@34?$AA@??_C@_02NGDH@7c?$AA@??_C@_02NGPM@7f?$AA@??_C@_02NJHI@3d?$AA@??_C@_02NJLD@3a?$AA@??_C@_02NKEM@76?$AA@??_C@_02NKIH@73?$AA@??_C@_02NLBB@79?$AA@??_C@_02NLH@f9?$AA@??_C@_02NOAG@d5?$AA@??_C@_02NOMN@d0?$AA@??_C@_02OAOO@49?$AA@??_C@_02OBHI@43?$AA@??_C@_02OBLD@46?$AA@??_C@_02OCEM@0a?$AA@??_C@_02OCIH@0d?$AA@??_C@_02OEN@86?$AA@??_C@_02OGAG@cb?$AA@??_C@_02OHFO@95?$AA@??_C@_02OHJF@90?$AA@??_C@_02OIG@83?$AA@??_C@_02OKHN@c7?$AA@??_C@_02OKLG@c2?$AA@??_C@_02OLCA@c8?$AA@??_C@_02OLOO@9e?$AA@??_C@_02ONAD@4f?$AA@??_C@_02ONMI@4c?$AA@??_C@_02OODH@04?$AA@??_C@_02OOPM@01?$AA@??_C@_02PAKM@bb?$AA@??_C@_02PBA@89?$AA@??_C@_02PBDP@80?$AA@??_C@_02PBF@ba?$AA@??_C@_02PBPE@85?$AA@??_C@_02PDFD@f5?$AA@??_C@_02PDJI@f0?$AA@??_C@_02PECN@1d?$AA@??_C@_02PEOG@1a?$AA@??_C@_02PGEE@59?$AA@??_C@_02PHBJ@56?$AA@??_C@_02PHNC@53?$AA@??_C@_02PIFG@11?$AA@??_C@_02PIJN@14?$AA@??_C@_02PLGC@5c?$AA@??_C@_02PLKJ@5f?$AA@??_C@_02PMBM@b2?$AA@??_C@_02PMNH@b7?$AA@??_C@_02PNEE@8e?$AA@??_C@_02PNIK@b8?$AA@??_C@_02PNO@bd?$AA@??_C@_02PPOD@fe?$AA@??_C@_03BCFK@234?$AA@??_C@_03BCJB@231?$AA@??_C@_03BEFM@175?$AA@??_C@_03BEJH@170?$AA@??_C@_03BKIF@138?$AA@??_C@_03BLBD@132?$AA@??_C@_03BLNI@137?$AA@??_C@_03CACH@107?$AA@??_C@_03CAOM@102?$AA@??_C@_03CBHK@108?$AA@??_C@_03CDN@160?$AA@??_C@_03CGCB@246?$AA@??_C@_03CGOK@243?$AA@??_C@_03CHHM@249?$AA@??_C@_03CIBD@199?$AA@??_C@_03CJEO@196?$AA@??_C@_03CJF@?$CFx?3?$AA@??_C@_03CJGO@201?$AA@??_C@_03CJIF@193?$AA@??_C@_03CJKF@204?$AA@??_C@_03CPG@165?$AA@??_C@_03CPGI@140?$AA@??_C@_03CPKD@145?$AA@??_C@_03DAEA@253?$AA@??_C@_03DGEG@112?$AA@??_C@_03DGIN@117?$AA@??_C@_03DHNA@118?$AA@??_C@_03DJAJ@155?$AA@??_C@_03DJMC@150?$AA@??_C@_03DOLJ@189?$AA@??_C@_03DPAP@214?$AA@??_C@_03DPCP@183?$AA@??_C@_03DPME@211?$AA@??_C@_03DPOE@186?$AA@??_C@_03EACP@178?$AA@??_C@_03EBHC@177?$AA@??_C@_03EBLJ@172?$AA@??_C@_03EDL@221?$AA@??_C@_03EGCJ@239?$AA@??_C@_03EHHE@236?$AA@??_C@_03EHLP@233?$AA@??_C@_03EODN@130?$AA@??_C@_03EOPG@135?$AA@??_C@_03EPA@224?$AA@??_C@_03FAID@229?$AA@??_C@_03FBBF@223?$AA@??_C@_03FBNO@226?$AA@??_C@_03FGIF@168?$AA@??_C@_03FHBD@162?$AA@??_C@_03FHNI@167?$AA@??_C@_03FIFM@125?$AA@??_C@_03FIJH@120?$AA@??_C@_03GDGI@110?$AA@??_C@_03GDKD@115?$AA@??_C@_03GFGO@251?$AA@??_C@_03GFKF@254?$AA@??_C@_03GKAB@181?$AA@??_C@_03GKCB@216?$AA@??_C@_03GKMK@184?$AA@??_C@_03GKOK@213?$AA@??_C@_03GLHM@219?$AA@??_C@_03GMCH@157?$AA@??_C@_03GMOM@152?$AA@??_C@_03GNHK@158?$AA@??_C@_03HDAP@244?$AA@??_C@_03HDME@241?$AA@??_C@_03HFAJ@105?$AA@??_C@_03HFMC@100?$AA@??_C@_03HKEG@142?$AA@??_C@_03HKIN@147?$AA@??_C@_03HLNA@148?$AA@??_C@_03HMEA@203?$AA@??_C@_03HMGA@194?$AA@??_C@_03HMIL@206?$AA@??_C@_03HMKL@191?$AA@??_C@_03HNNG@209?$AA@??_C@_03ICIE@198?$AA@??_C@_03IDBC@192?$AA@??_C@_03IDDC@205?$AA@??_C@_03IDNJ@197?$AA@??_C@_03IDPJ@200?$AA@??_C@_03IFDE@144?$AA@??_C@_03IFPP@141?$AA@??_C@_03IKHL@103?$AA@??_C@_03IKLA@106?$AA@??_C@_03ILON@109?$AA@??_C@_03IMHN@242?$AA@??_C@_03IMLG@247?$AA@??_C@_03INOL@248?$AA@??_C@_03JDFF@151?$AA@??_C@_03JDJO@154?$AA@??_C@_03JECO@188?$AA@??_C@_03JFFD@210?$AA@??_C@_03JFHD@187?$AA@??_C@_03JFJI@215?$AA@??_C@_03JFLI@182?$AA@??_C@_03JKNH@252?$AA@??_C@_03JMBK@116?$AA@??_C@_03JMNB@113?$AA@??_C@_03JNEH@119?$AA@??_C@_03KGLI@129?$AA@??_C@_03KHCO@123?$AA@??_C@_03KHOF@126?$AA@??_C@_03KIGB@164?$AA@??_C@_03KIKK@161?$AA@??_C@_03KOGH@225?$AA@??_C@_03KOKM@220?$AA@??_C@_03LABC@139?$AA@??_C@_03LBEP@136?$AA@??_C@_03LBIE@133?$AA@??_C@_03LIAG@230?$AA@??_C@_03LIMN@235?$AA@??_C@_03LOAA@171?$AA@??_C@_03LOML@174?$AA@??_C@_03MAFN@185?$AA@??_C@_03MAHN@212?$AA@??_C@_03MAJG@180?$AA@??_C@_03MALG@217?$AA@??_C@_03MBOL@218?$AA@??_C@_03MCP@128?$AA@??_C@_03MGHL@153?$AA@??_C@_03MGLA@156?$AA@??_C@_03MHON@159?$AA@??_C@_03MJDE@114?$AA@??_C@_03MJPP@111?$AA@??_C@_03MPDC@255?$AA@??_C@_03MPPJ@250?$AA@??_C@_03NABK@146?$AA@??_C@_03NANB@143?$AA@??_C@_03NBEH@149?$AA@??_C@_03NGBM@207?$AA@??_C@_03NGDM@190?$AA@??_C@_03NGNH@202?$AA@??_C@_03NGPH@195?$AA@??_C@_03NHC@127?$AA@??_C@_03NHEB@208?$AA@??_C@_03NJFD@240?$AA@??_C@_03NJJI@245?$AA@??_C@_03NLJ@122?$AA@??_C@_03NPFF@101?$AA@??_C@_03NPJO@104?$AA@??_C@_03OEGB@134?$AA@??_C@_03OEKK@131?$AA@??_C@_03OKLI@179?$AA@??_C@_03OLCO@173?$AA@??_C@_03OLOF@176?$AA@??_C@_03OMLO@238?$AA@??_C@_03ONCI@232?$AA@??_C@_03ONOD@237?$AA@??_C@_03PCAA@121?$AA@??_C@_03PCML@124?$AA@??_C@_03PKBE@228?$AA@??_C@_03PLEJ@227?$AA@??_C@_03PLIC@222?$AA@??_C@_03PMBC@169?$AA@??_C@_03PNEP@166?$AA@??_C@_03PNIE@163?$AA@_eth_ntoa_eth_ntop_eth_pton_ip6_ntoa_ip6_ntop_ip6_pton_ip_ntoa_ip_ntop_ip_pton/ 1305901072 0 11748 ` èa‚h¦jÊloÆz`Š˜Ž•$¥þÀÆFÑ<ÚV°¶(                 ??_C@_00A@?$AA@??_C@_01BJG@?6?$AA@??_C@_01ECJ@3?$AA@??_C@_01EOC@6?$AA@??_C@_01FBAH@1?$AA@??_C@_01FBMM@4?$AA@??_C@_01FCOA@?5?$AA@??_C@_01FLP@9?$AA@??_C@_01KOHF@7?$AA@??_C@_01KOLO@2?$AA@??_C@_01KPCI@8?$AA@??_C@_01PLFL@5?$AA@??_C@_01PLJA@0?$AA@??_C@_02BAND@08?$AA@??_C@_02BBEF@02?$AA@??_C@_02BBIO@07?$AA@??_C@_02BCLK@4e?$AA@??_C@_02BEFH@9f?$AA@??_C@_02BEJM@9c?$AA@??_C@_02BFAP@c1?$AA@??_C@_02BFME@c4?$AA@??_C@_02BICM@93?$AA@??_C@_02BIOH@96?$AA@??_C@_02BJHE@cd?$AA@??_C@_02BJLK@99?$AA@??_C@_02BJLP@ca?$AA@??_C@_02BNPF@0b?$AA@??_C@_02BOAK@45?$AA@??_C@_02BOMB@40?$AA@??_C@_02CAOC@d9?$AA@??_C@_02CBHE@d3?$AA@??_C@_02CBLP@d6?$AA@??_C@_02CDG@8c?$AA@??_C@_02CFDO@70?$AA@??_C@_02CFPF@75?$AA@??_C@_02CGAK@3b?$AA@??_C@_02CHGF@sl?$AA@??_C@_02CJEF@7e?$AA@??_C@_02CKHB@37?$AA@??_C@_02CKLK@32?$AA@??_C@_02CLCM@38?$AA@??_C@_02CNAP@df?$AA@??_C@_02CNME@dc?$AA@??_C@_02CPN@8f?$AA@??_C@_02DAKA@2b?$AA@??_C@_02DDFP@65?$AA@??_C@_02DDJE@60?$AA@??_C@_02DECB@ad?$AA@??_C@_02DEOK@aa?$AA@??_C@_02DGEI@e9?$AA@??_C@_02DGO@b4?$AA@??_C@_02DHBF@e6?$AA@??_C@_02DHNO@e3?$AA@??_C@_02DIFK@a1?$AA@??_C@_02DIJB@a4?$AA@??_C@_02DKF@b1?$AA@??_C@_02DLGO@ec?$AA@??_C@_02DLKF@ef?$AA@??_C@_02DMBA@22?$AA@??_C@_02DMNL@27?$AA@??_C@_02DNIG@28?$AA@??_C@_02DPOP@6e?$AA@??_C@_02EACB@c3?$AA@??_C@_02EAOK@c6?$AA@??_C@_02EBA@5e?$AA@??_C@_02EBHJ@9d?$AA@??_C@_02EBLC@9a?$AA@??_C@_02EBLH@c9?$AA@??_C@_02EEGL@00?$AA@??_C@_02EEIK@tr?$AA@??_C@_02EEKA@05?$AA@??_C@_02EHFP@4b?$AA@??_C@_02EIBA@0e?$AA@??_C@_02EKHJ@48?$AA@??_C@_02ELCE@47?$AA@??_C@_02ELOP@42?$AA@??_C@_02EMFK@cf?$AA@??_C@_02EMJB@cc?$AA@??_C@_02ENAC@91?$AA@??_C@_02ENMJ@94?$AA@??_C@_02FBPF@5b?$AA@??_C@_02FCAK@15?$AA@??_C@_02FCMB@10?$AA@??_C@_02FFHE@fd?$AA@??_C@_02FFLP@fa?$AA@??_C@_02FGEA@b6?$AA@??_C@_02FGIL@b3?$AA@??_C@_02FHBI@8a?$AA@??_C@_02FHBN@b9?$AA@??_C@_02FHND@8d?$AA@??_C@_02FJAP@f1?$AA@??_C@_02FJME@f4?$AA@??_C@_02FK@ff?$AA@??_C@_02FKDL@bc?$AA@??_C@_02FKPA@bf?$AA@??_C@_02FLGD@84?$AA@??_C@_02FLKI@81?$AA@??_C@_02FMND@58?$AA@??_C@_02FNEF@52?$AA@??_C@_02FNIO@57?$AA@??_C@_02FOLK@1e?$AA@??_C@_02GBAP@af?$AA@??_C@_02GBME@ac?$AA@??_C@_02GCDL@e4?$AA@??_C@_02GCPA@e1?$AA@??_C@_02GFEF@2e?$AA@??_C@_02GGHB@67?$AA@??_C@_02GGHE@lo?$AA@??_C@_02GGLK@62?$AA@??_C@_02GHCM@68?$AA@??_C@_02GHJ@18?$AA@??_C@_02GJDO@20?$AA@??_C@_02GJPF@25?$AA@??_C@_02GKAK@6b?$AA@??_C@_02GMOC@a9?$AA@??_C@_02GNHE@a3?$AA@??_C@_02GNLP@a6?$AA@??_C@_02GOEA@ea?$AA@??_C@_02GOIL@ed?$AA@??_C@_02HABA@72?$AA@??_C@_02HANL@77?$AA@??_C@_02HBIG@78?$AA@??_C@_02HCE@17?$AA@??_C@_02HDOP@3e?$AA@??_C@_02HEFK@d1?$AA@??_C@_02HEJB@d4?$AA@??_C@_02HFBK@?3?5?$AA@??_C@_02HICB@dd?$AA@??_C@_02HIOK@da?$AA@??_C@_02HMKA@7b?$AA@??_C@_02HOP@12?$AA@??_C@_02HPFP@35?$AA@??_C@_02HPJE@30?$AA@??_C@_02IACN@33?$AA@??_C@_02IAOG@36?$AA@??_C@_02IBLL@39?$AA@??_C@_02IDBJ@7a?$AA@??_C@_02IDNC@7d?$AA@??_C@_02IGL@50?$AA@??_C@_02IHFD@db?$AA@??_C@_02IHLC@?5?5?$AA@??_C@_02IKA@55?$AA@??_C@_02IKHF@d8?$AA@??_C@_02ILCI@d7?$AA@??_C@_02ILOD@d2?$AA@??_C@_02IMFG@3f?$AA@??_C@_02IMJN@3c?$AA@??_C@_02IPGC@74?$AA@??_C@_02IPKJ@71?$AA@??_C@_02JB@fc?$AA@??_C@_02JBML@?$CFc?$AA@??_C@_02JBPJ@eb?$AA@??_C@_02JCAG@a5?$AA@??_C@_02JCMN@a0?$AA@??_C@_02JFHI@6d?$AA@??_C@_02JFLD@6a?$AA@??_C@_02JGEM@26?$AA@??_C@_02JGIH@23?$AA@??_C@_02JHBB@29?$AA@??_C@_02JJAD@61?$AA@??_C@_02JJMI@64?$AA@??_C@_02JKDH@2c?$AA@??_C@_02JKPM@2f?$AA@??_C@_02JMNP@e8?$AA@??_C@_02JNEJ@e2?$AA@??_C@_02JNIC@e7?$AA@??_C@_02JOLG@ae?$AA@??_C@_02KBAD@1f?$AA@??_C@_02KBMI@1c?$AA@??_C@_02KCDH@54?$AA@??_C@_02KCPM@51?$AA@??_C@_02KEBB@82?$AA@??_C@_02KENK@87?$AA@??_C@_02KFEJ@be?$AA@??_C@_02KFIH@88?$AA@??_C@_02KGHN@f7?$AA@??_C@_02KGLG@f2?$AA@??_C@_02KHCA@f8?$AA@??_C@_02KIKB@8b?$AA@??_C@_02KJDC@b0?$AA@??_C@_02KJPJ@b5?$AA@??_C@_02KKAG@fb?$AA@??_C@_02KMOO@19?$AA@??_C@_02KNHI@13?$AA@??_C@_02KNLD@16?$AA@??_C@_02KOEM@5a?$AA@??_C@_02KOIH@5d?$AA@??_C@_02LCHA@97?$AA@??_C@_02LCLL@92?$AA@??_C@_02LDCN@98?$AA@??_C@_02LDOD@ce?$AA@??_C@_02LEFG@41?$AA@??_C@_02LEJN@44?$AA@??_C@_02LFP@1b?$AA@??_C@_02LHGC@0c?$AA@??_C@_02LHKJ@0f?$AA@??_C@_02LICN@4d?$AA@??_C@_02LIOG@4a?$AA@??_C@_02LKEE@09?$AA@??_C@_02LLBJ@06?$AA@??_C@_02LLNC@03?$AA@??_C@_02LOAL@9b?$AA@??_C@_02LPFD@c5?$AA@??_C@_02LPJI@c0?$AA@??_C@_02MAFG@6f?$AA@??_C@_02MAJN@6c?$AA@??_C@_02MCB@f3?$AA@??_C@_02MDGC@24?$AA@??_C@_02MDKJ@21?$AA@??_C@_02MEBM@ee?$AA@??_C@_02MGHF@a8?$AA@??_C@_02MHCI@a7?$AA@??_C@_02MHOD@a2?$AA@??_C@_02MIGH@e0?$AA@??_C@_02MIKM@e5?$AA@??_C@_02MLFD@ab?$AA@??_C@_02MMCN@63?$AA@??_C@_02MMOG@66?$AA@??_C@_02MNLL@69?$AA@??_C@_02MOK@f6?$AA@??_C@_02MPBJ@2a?$AA@??_C@_02MPNC@2d?$AA@??_C@_02NCLG@de?$AA@??_C@_02NFAD@31?$AA@??_C@_02NFMI@34?$AA@??_C@_02NGDH@7c?$AA@??_C@_02NGPM@7f?$AA@??_C@_02NJHI@3d?$AA@??_C@_02NJLD@3a?$AA@??_C@_02NKEM@76?$AA@??_C@_02NKIH@73?$AA@??_C@_02NLBB@79?$AA@??_C@_02NLH@f9?$AA@??_C@_02NOAG@d5?$AA@??_C@_02NOMN@d0?$AA@??_C@_02OAOO@49?$AA@??_C@_02OBHI@43?$AA@??_C@_02OBLD@46?$AA@??_C@_02OCEM@0a?$AA@??_C@_02OCIH@0d?$AA@??_C@_02OEN@86?$AA@??_C@_02OGAG@cb?$AA@??_C@_02OHFO@95?$AA@??_C@_02OHJF@90?$AA@??_C@_02OIG@83?$AA@??_C@_02OKHN@c7?$AA@??_C@_02OKLG@c2?$AA@??_C@_02OLCA@c8?$AA@??_C@_02OLOO@9e?$AA@??_C@_02ONAD@4f?$AA@??_C@_02ONMI@4c?$AA@??_C@_02OODH@04?$AA@??_C@_02OOPM@01?$AA@??_C@_02PAKM@bb?$AA@??_C@_02PBA@89?$AA@??_C@_02PBDP@80?$AA@??_C@_02PBF@ba?$AA@??_C@_02PBPE@85?$AA@??_C@_02PDFD@f5?$AA@??_C@_02PDJI@f0?$AA@??_C@_02PECN@1d?$AA@??_C@_02PEOG@1a?$AA@??_C@_02PGEE@59?$AA@??_C@_02PHBJ@56?$AA@??_C@_02PHNC@53?$AA@??_C@_02PIFG@11?$AA@??_C@_02PIJN@14?$AA@??_C@_02PLGC@5c?$AA@??_C@_02PLKJ@5f?$AA@??_C@_02PMBM@b2?$AA@??_C@_02PMNH@b7?$AA@??_C@_02PNEE@8e?$AA@??_C@_02PNIK@b8?$AA@??_C@_02PNO@bd?$AA@??_C@_02PPOD@fe?$AA@??_C@_03BCFK@234?$AA@??_C@_03BCJB@231?$AA@??_C@_03BEFM@175?$AA@??_C@_03BEJH@170?$AA@??_C@_03BKIF@138?$AA@??_C@_03BLBD@132?$AA@??_C@_03BLNI@137?$AA@??_C@_03CACH@107?$AA@??_C@_03CAOM@102?$AA@??_C@_03CBHK@108?$AA@??_C@_03CDN@160?$AA@??_C@_03CGCB@246?$AA@??_C@_03CGOK@243?$AA@??_C@_03CHHM@249?$AA@??_C@_03CIBD@199?$AA@??_C@_03CJEO@196?$AA@??_C@_03CJF@?$CFx?3?$AA@??_C@_03CJGO@201?$AA@??_C@_03CJIF@193?$AA@??_C@_03CJKF@204?$AA@??_C@_03CPG@165?$AA@??_C@_03CPGI@140?$AA@??_C@_03CPKD@145?$AA@??_C@_03DAEA@253?$AA@??_C@_03DBFP@eth?$AA@??_C@_03DGEG@112?$AA@??_C@_03DGIN@117?$AA@??_C@_03DHNA@118?$AA@??_C@_03DJAJ@155?$AA@??_C@_03DJMC@150?$AA@??_C@_03DOLJ@189?$AA@??_C@_03DPAP@214?$AA@??_C@_03DPCP@183?$AA@??_C@_03DPME@211?$AA@??_C@_03DPOE@186?$AA@??_C@_03EACP@178?$AA@??_C@_03EBHC@177?$AA@??_C@_03EBLJ@172?$AA@??_C@_03EDL@221?$AA@??_C@_03EGCJ@239?$AA@??_C@_03EHHE@236?$AA@??_C@_03EHLP@233?$AA@??_C@_03EODN@130?$AA@??_C@_03EOPG@135?$AA@??_C@_03EPA@224?$AA@??_C@_03FAID@229?$AA@??_C@_03FBBF@223?$AA@??_C@_03FBNO@226?$AA@??_C@_03FGIF@168?$AA@??_C@_03FHBD@162?$AA@??_C@_03FHNI@167?$AA@??_C@_03FIFM@125?$AA@??_C@_03FIJH@120?$AA@??_C@_03GDGI@110?$AA@??_C@_03GDKD@115?$AA@??_C@_03GFGO@251?$AA@??_C@_03GFKF@254?$AA@??_C@_03GKAB@181?$AA@??_C@_03GKCB@216?$AA@??_C@_03GKMK@184?$AA@??_C@_03GKOK@213?$AA@??_C@_03GLHM@219?$AA@??_C@_03GMCH@157?$AA@??_C@_03GMOM@152?$AA@??_C@_03GNHK@158?$AA@??_C@_03HDAP@244?$AA@??_C@_03HDME@241?$AA@??_C@_03HFAJ@105?$AA@??_C@_03HFMC@100?$AA@??_C@_03HKEG@142?$AA@??_C@_03HKIN@147?$AA@??_C@_03HLNA@148?$AA@??_C@_03HMEA@203?$AA@??_C@_03HMEG@net?$AA@??_C@_03HMGA@194?$AA@??_C@_03HMIL@206?$AA@??_C@_03HMKL@191?$AA@??_C@_03HNNG@209?$AA@??_C@_03ICIE@198?$AA@??_C@_03IDBC@192?$AA@??_C@_03IDDC@205?$AA@??_C@_03IDNJ@197?$AA@??_C@_03IDPJ@200?$AA@??_C@_03IFDE@144?$AA@??_C@_03IFPP@141?$AA@??_C@_03IKHL@103?$AA@??_C@_03IKLA@106?$AA@??_C@_03ILON@109?$AA@??_C@_03IMHN@242?$AA@??_C@_03IMLG@247?$AA@??_C@_03INOL@248?$AA@??_C@_03JDFF@151?$AA@??_C@_03JDJO@154?$AA@??_C@_03JECO@188?$AA@??_C@_03JFFD@210?$AA@??_C@_03JFHD@187?$AA@??_C@_03JFJI@215?$AA@??_C@_03JFLI@182?$AA@??_C@_03JKNH@252?$AA@??_C@_03JMBK@116?$AA@??_C@_03JMNB@113?$AA@??_C@_03JNEH@119?$AA@??_C@_03KGLI@129?$AA@??_C@_03KHCO@123?$AA@??_C@_03KHOF@126?$AA@??_C@_03KICP@?1?$CFd?$AA@??_C@_03KIGB@164?$AA@??_C@_03KIKK@161?$AA@??_C@_03KNBL@ppp?$AA@??_C@_03KOGH@225?$AA@??_C@_03KOKM@220?$AA@??_C@_03LABC@139?$AA@??_C@_03LBEP@136?$AA@??_C@_03LBIE@133?$AA@??_C@_03LIAG@230?$AA@??_C@_03LIMN@235?$AA@??_C@_03LOAA@171?$AA@??_C@_03LOML@174?$AA@??_C@_03MAFN@185?$AA@??_C@_03MAHN@212?$AA@??_C@_03MAJG@180?$AA@??_C@_03MALG@217?$AA@??_C@_03MBOL@218?$AA@??_C@_03MCP@128?$AA@??_C@_03MFGH@?5?5?5?$AA@??_C@_03MGHL@153?$AA@??_C@_03MGLA@156?$AA@??_C@_03MHON@159?$AA@??_C@_03MJDE@114?$AA@??_C@_03MJPP@111?$AA@??_C@_03MPDC@255?$AA@??_C@_03MPPJ@250?$AA@??_C@_03NABK@146?$AA@??_C@_03NANB@143?$AA@??_C@_03NBEH@149?$AA@??_C@_03NGBM@207?$AA@??_C@_03NGDM@190?$AA@??_C@_03NGNH@202?$AA@??_C@_03NGPH@195?$AA@??_C@_03NHC@127?$AA@??_C@_03NHEB@208?$AA@??_C@_03NJFD@240?$AA@??_C@_03NJJI@245?$AA@??_C@_03NLJ@122?$AA@??_C@_03NPFF@101?$AA@??_C@_03NPJO@104?$AA@??_C@_03OEGB@134?$AA@??_C@_03OEKK@131?$AA@??_C@_03OKLI@179?$AA@??_C@_03OLCO@173?$AA@??_C@_03OLOF@176?$AA@??_C@_03OMLO@238?$AA@??_C@_03ONCI@232?$AA@??_C@_03ONOD@237?$AA@??_C@_03PCAA@121?$AA@??_C@_03PCML@124?$AA@??_C@_03PKBE@228?$AA@??_C@_03PLEJ@227?$AA@??_C@_03PLIC@222?$AA@??_C@_03PMBC@169?$AA@??_C@_03PNEP@166?$AA@??_C@_03PNIE@163?$AA@??_C@_04ICFM@fddi?$AA@??_C@_04KAKK@hexl?$AA@??_C@_04OBKB@?$CF02x?$AA@??_C@_05HGAB@?$CFs?$CFlu?$AA@??_C@_05OOAB@?$CF02x?5?$AA@??_C@_06POGA@?$PP?$PP?$PP?$PP?$PP?$PP?$AA@??_C@_08MPCM@?5?5?$CF04x?3?5?$AA@??_C@_0L@OBLD@error?5?$CFlu?6?$AA@_addr_bcast_addr_btom_addr_btos_addr_cmp_addr_mtob_addr_net_addr_ntoa_addr_ntop_addr_ntos_addr_pton_addr_stob_addr_ston_arp_add_arp_close_arp_delete_arp_get_arp_loop_arp_open_blob_delete_blob_free_blob_index_blob_insert_blob_new_blob_pack_blob_print_blob_printers_blob_read_blob_register_alloc_blob_register_pack_blob_rindex_blob_seek_blob_sprint_blob_unpack_blob_write_err_errx_eth_close_eth_get_eth_ntoa_eth_ntop_eth_open_eth_pton_eth_send_eth_set_fw_add_fw_close_fw_delete_fw_loop_fw_open_intf_close_intf_get_intf_get_dst_intf_get_src_intf_loop_intf_open_intf_set_ip6_checksum_ip6_ntoa_ip6_ntop_ip6_pton_ip_add_option_ip_checksum_ip_cksum_add_ip_close_ip_ntoa_ip_ntop_ip_open_ip_pton_ip_send_rand_add_rand_close_rand_get_rand_open_rand_set_rand_shuffle_rand_uint16_rand_uint32_rand_uint8_route_add_route_close_route_delete_route_get_route_loop_route_open_strlcat_strlcpy_strsep_tun_close_tun_fileno_tun_name_tun_open_tun_recv_tun_send_warn_warnx// 1305901072 0 371 ` .\Release\tun-none.obj.\Release\strsep.obj.\Release\strlcpy.obj.\Release\strlcat.obj.\Release\route-win32.obj.\Release\rand.obj.\Release\ip6.obj.\Release\ip-win32.obj.\Release\ip-util.obj.\Release\intf-win32.obj.\Release\fw-none.obj.\Release\eth-win32.obj.\Release\err.obj.\Release\blob.obj.\Release\arp-win32.obj.\Release\addr.obj.\Release\addr-util.obj /0 1305901071 100666 1629 ` L xÖMr%.drectve( .textDT P`.debug$F^nHB.textxˆ P`.debug$F’¢HB.text¬¼ P`.debug$FÆÖHB.textàð P`.debug$Fú HB.text$ P`.debug$F.>HB.textH P`.debug$FXhHB-defaultlib:MSVCRT -defaultlib:OLDNAMES ÿÇ(3Àà ÿÇ(3Àà ÿÇ(ƒÈÿà ÿÇ(ƒÈÿà ÿÇ(ƒÈÿà 3ÀÃ".fileþÿgD:\temp\libdnet-1.11\src\tun-none.c@comp.id6& ÿÿ.drectve(‘·ÖÉ.text  .debug$F.text .debug$F.text}Ä};& .debug$F.text}Ä};2 .debug$F .text }Ä};< .debug$F  .text ÙΩ…F .debug$F  Q_tun_open__imp___errno_tun_name_tun_fileno_tun_send_tun_recv_tun_close /23 1305901072 100666 488 ` LxÖM .drectve(Œ .textP´ P`.debug$FHB-defaultlib:MSVCRT -defaultlib:OLDNAMES U‹l$V‹u…öu^3À]ÃS‹\$W‹Æ¾>F‹Ó¾ B;Ït…Éuôëì…ÿ_[u3ö‰u^]ÃÆFÿ‰u^]ÃF.fileþÿgD:\temp\libdnet-1.11\src\strsep.c@comp.id6& ÿÿ.drectve(.textPÚæ¦³_strsep .debug$F/44 1305901072 100666 488 ` LxÖM .drectve(Œ .textP´ P`.debug$FHB-defaultlib:MSVCRT -defaultlib:OLDNAMES ‹T$ ‹L$V‹t$ …ÒW‹Æt'zÿ…ÿtŠFˆA„Òt OtŠˆA@„Òuó…ÿuÆŠ@„ÉtŠ@„Òuù+Æ_H^ÃO.fileþÿgD:\temp\libdnet-1.11\src\strlcpy.c@comp.id6& ÿÿ.drectve(.textPJ'tw_strlcpy .debug$F/66 1305901072 100666 520 ` LxÖM> .drectve(Œ .textp´ P`.debug$F$4HB-defaultlib:MSVCRT -defaultlib:OLDNAMES ‹L$ S‹\$UVW‹|$‹Ã…É‹÷Qÿt €8t@‹êJ…íuó‹Ð+Ó+Ê‹éuƒÉÿ3Àò®÷ÑI_‹Á^]Â[À?tƒýtŠˆ@MŠNF„ÉuíÆ‹Â+Ç_Æ^][Ãk.fileþÿgD:\temp\libdnet-1.11\src\strlcat.c@comp.id6& ÿÿ.drectve(.textpè'uˆ_strlcat .debug$F/88 1305901072 100666 2939 ` L xÖM²3.drectve( .textDT P`.debug$F^nHB.text x P`.debug$F@PHB.textZê P`.debug$F&6HB.textÀ@ P`.debug$F2BHB.textÐL P`.debug$FDTHB.text0^Ž P`.debug$F˜¨HB-defaultlib:MSVCRT -defaultlib:OLDNAMES jjÿƒÄà  ƒìL¹3ÀV‹t$XW|$ó«‹ND$,PQè…ÀuaT$RVèƒÄ…À|Ofƒ|$uGf‹V‹D$ L$ jQR‰D$(è‹FƒÄ L$‰D$(QÇD$4ÇD$8è÷Ø_^ÀƒÄLÃ_ƒÈÿ^ƒÄLà /W{’ƒì8V‹t$Dfƒ>upD$Pjÿ‹NPQè…ÀuUf‹FT$DjRPè‹L$‹FƒÄ ;Èu‹T$‹D$D;ÐuD$Pè÷ØÀ^ƒÄ8ÃÿhèÇÿƒÈÿ^ƒÄ8Ã!6Ziz†ƒì8SVW‹|$Lfƒ?uv‹5D$ PjÿÖ‹OPQè…ÀuYƒ|$$u\hÿÖhÿ‹ØÿÖhÿ ØÿÖ D$;Ãt;hÿÿÿÿÖ‹Ø‹D$hà#ØÿÖ;Øt!ÿhèÇÿ_^ƒÈÿ[ƒÄ8Ãf‹GT$LjRPè‹L$$ƒÄ fÇGfÇG ‰O_^3À[ƒÄ8Ã%q‚À"ƒì,S‹UV‹5W‹|$@ÇD$<‹…ÀtPÿӃċD$PÿÖƒÄL$‰jQPè…Àtƒøzuwëи ¹f‰D$f‰D$*‹f‰L$f‰L$(3Ûƒ8~D‹l$H3ö‹TL$‰T$QTjRè‹T$ UR‹L0‰L$@ÿT$XƒÄ…Àu‹CƒÆ8;|Â_^]3À[ƒÄ,ÃÈÿ_^][ƒÄ,Ã+*@)‘(Ï 'V‹t$…öt‹W‹=…ÀtPÿ׃ÄVÿ׃Ä3À_^Ã3À^Ã++0.fileþÿgD:\temp\libdnet-1.11\src\route-win32.c@comp.id6& ÿÿ.drectve(Õåÿ.textÖöè~  .debug$F&ûÑ.text  Ì« ) A L V .debug$F¡³"„.textòâ^j x Ž œ ´ Å .debug$F.textÀ ¡Ô .debug$F çµjþ.text и¤.vß ë ö    .debug$F  .text 0™ª.¾& .debug$F  3_route_open__imp__calloc_route_add_CreateIpForwardEntry@4_addr_btom_addr_net_GetBestInterface@8_route_delete__imp__SetLastError@4__imp___errno_DeleteIpForwardEntry@4_GetBestRoute@12__imp__htonl@4_route_get_route_loop_addr_mtob_GetIpForwardTable@12__imp__malloc__imp__free_route_close /114 1305901072 100666 3933 ` LxÖM >.drectve(\ .text@„Ä P`.debug$FìüHB.text@F P`.debug$FP`HB.textPj P`.debug$FºÊHB.textÐÔ P`.debug$F¤´HB.textp¾ P`.debug$F.>HB.textHX P`.debug$FbrHB.text0|¬ P`.debug$FÀÐHB.textPÚ* P`.debug$FRbHB.textl|  P`.debug$Fš ª HB.text0´ ä  P`.debug$Fî þ HB-defaultlib:MSVCRT -defaultlib:OLDNAMES ìS3ÛhðjSD$SP‰\$ÿ‹T$L$QhRÿ‹D$SPÿh ÿƒÄ;ÄÔ3ɈLAù|óVWˆXÆÿ3öŠþÁˆáÿŠT|‹Îá€yIƒÉ€AŠL ÊHŠHáÿŠLˆ3ÉŠHFþˆT|³ŠˆHþɈ3öŠþÁˆáÿŠT|‹Îá€yIƒÉ€AŠŒ ÊHŠHáÿŠLˆ3ÉŠHFþˆT|°Š_ˆP‰˜‰˜^[Äà 2 > I 4AVW‹|$3ö…ÿv"S‹\$U‹l$UèƒÄˆF;÷rï][_3À^Ã_3À^Ã3‹D$SVŠþÊˈáÿ3ÛŠTtŠHʈHáÿŠLˆŠXÊ^áÿˆT[ŠDÃH‹L$3ÀˆD@=|ôSU‹l$VWÆAÆÿ3öŠþÊÈ%ÿ|‹Æ™÷|$ŠŠ*ŠQÃЊˆQ%ÿŠT3ÀˆŠAFþˆ\|ºŠˆAþȈ3öŠþÊÈ%ÿ|‹Æ™÷|$ŠŠAŠ*ÓÂ3ÒˆA%ÿFŠDþˆŠQˆ\ |¼Š_^ˆA]3À[ÃÄ‹L$SU‹l$ŠVþÈWˆ3ÿŠþÊÈ%ÿt‹Ç™÷|$ŠŠ*ŠQÃЊˆQ%ÿŠT3ÀˆŠAGÿˆ\|ºŠ_^]ˆQ3À[Ãf ‹D$PèƒÄÃ%V‹t$WVè3ÉVŠè‹ùèf¶ÀƒÄ Ç_^Ã$*V‹t$WVè%ÿVÁà‹øè%ÿVÁà øè3ÉVŠè ùèƒÄ%ÿ Ç_^Ã(4E/QSU‹l$Wƒýs_]3À[YË|$‹\$ ‹‡;ˇsJ…ÀSuÿƒÄ‰D$ …Àu&_]ƒÈÿ[YÃPÿƒÄ‰D$ …Àu_]ƒÈÿ[YËD$ ‰‡‰Ÿë‰D$ V3ö…í‰t$vx‹l$Wè‹L$$ƒÄ3ÒI÷ñ;ÖtO¯Ó‹L$‹|$$ыˋÁ‹òÁéó¥‹Èƒáó¤‹Ë‹ú‹Ñ‹õÁéó¥‹Êƒáó¤‹t$$‹Ë‹ýÁéó¥‹Èƒáó¤‹|$‹t$‹D$ Fë;ð‰t$rŒ^_]3À[YÃ3 M5‹/4V‹t$…öt"‹†W‹=…ÀtPÿ׃ÄVÿ׃Ä3À_^Ã3À^Ã;/:.fileþÿgD:\temp\libdnet-1.11\src\rand.c@comp.id6& ÿÿ.drectve(<úï_.text@‰¶Ð   : S .debug$F.text@‰(é÷r .debug$F.textP#4mö| .debug$F.textÐWº>MŠ .debug$F .text p¶'½” .debug$F  .text ‘Ó)êž .debug$F  .text0£' Qª .debug$F.textPŽ­G'· .debug$FÛ«ù[.textk O [ o .debug$F—Hç.text@ U_ip_send } .debug$F×tKí.text0Ç6_Ž ˜ ­ .debug$FÁ__imp__htons@4__imp__SetLastError@4__imp__setsockopt@20__imp__socket@12__imp__free__imp__WSAStartup@8__imp__calloc__imp__sendto@24_ip_close__imp__closesocket@4__imp__WSACleanup@0 /174 1305901072 100666 4047 ` LxÖMr *.drectve(, .textTä P`.debug$F*:HB.text€DÄ P`.debug$F HB.text€$¤  P`.debug$FX h HB-defaultlib:MSVCRT -defaultlib:OLDNAMES ƒì‹D$SUV…ÀWÇD$t ƒø…J‹t$ŠƒãÁã‰\$Þƒøu3À‰\$ŠC ÁèÁà‰D$Øf‹FPÿ‹l$,f‹øçÿÿ+ó‹Íþƒá¾+ñƒþu3ö‹T$Ńø<‡Ý‹L$f‹QRÿ‹L$ %ÿÿÆÅ;Á‡¹‹D$(Š„Àt<u½…ÿt WÍSQÿƒÄ …öt‹Î¸‹Ñ‹ûÁéó«‹ÊƒáÞóª‹D$(UPSÿ‹D$0ÝƒÄ î…Àu‹t$+ÞŠÁû2Ø€ã2؈ë ƒøu‹D$+ØŠH ÁûÀã€á ÙˆX ‹t$f‹VRÿÅPÿf‰F_‹Å^][ƒÄÃÿ_^Ç]ƒÈÿ[ƒÄÃS ˜ Ò ÿ O X l SUVW‹|$ƒÿ‚`‹t$jŠfÇF ƒàÁà‹èUVè‹È%ÿÿÁùÈf‹F‹‹ÑÁúƒÄ Ñ÷ÒPf‰V ÿÓ%ÿÿ©ÿ?… ŠF +ý<u\îƒÿ‚öfÇEf¶N ÏQÿÓjf‹ØWUãÿÿèØƒÆ SjVè‹È%ÿÿÁùȃÄ‹ÑÁúÑ_÷Òf‰U^][Ã<ugîƒÿ‚–fÇEf¶F ÇPÿÓjf‹ØWUãÿÿèØƒÆ SjVè‹È%ÿÿÁùȃÄ‹ÁÁøÁ÷Ðf…Àf‰EuE_fÇEÿÿ^][Ã<t<u2õƒÿr+jWVfÇFè‹È%ÿÿÁùÈƒÄ ‹ÑÁúÑ÷Òf‰V_^][Ã*@ ™§ùQvS‹\$ V‹óÑî‹L$ F™ƒâÂÁøæ€yNƒÎðFƒþ‡ðÿ$µ‹t$3Òf‹ƒÁòH…ÀŽÖ3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹òƒÁéRÿÿÿ‹t$3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹òƒÁé³þÿÿ‹t$3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹òƒÁéþÿÿ‹t$3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹òƒÁé“ýÿÿ‹t$3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹òƒÁéýÿÿ‹t$3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹òƒÁé›üÿÿ‹t$3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹òƒÁé.üÿÿ‹t$3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹òƒÁéËûÿÿ‹t$3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹òƒÁérûÿÿ‹t$3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹òƒÁé#ûÿÿ‹t$3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹òƒÁéÞúÿÿ‹t$3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹òƒÁé£úÿÿ‹t$3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹òƒÁérúÿÿ‹t$3Òf‹ƒÁò3Òf‹ƒÁò3Òf‹òƒÁéKúÿÿ‹t$3Òf‹ƒÁò3Òf‹òƒÁé.úÿÿ‹t$3Òf‹òƒÁéúÿÿ‹t$öÃt3ÀŠ!Pÿ%ÿÿð‹Æ^[Ã3'0 @%D&HLPTX\`dhl p!t"x#|$€.fileþÿgD:\temp\libdnet-1.11\src\ip-util.c@comp.id6& ÿÿ.drectve(ÑÝ <.text2j8$  ! 0 ? .debug$F.text€ÌòÇ£N .debug$F.text€'“è[ $L22183 $L22182ð$L22181É$L22180˜$L22179]$L22178$L22177É$L22176p$L22175 $L22174 $L22173)$L22172¨$L22171$L22170ˆ$L22169é$L221687$L22186@.debug$Fi_ip_add_option__imp___errno__imp__htons@4__imp__memmove__imp__ntohs@4_ip_checksum_ip_cksum_add /196 1305901072 100666 7070 ` L$xÖMït.drectve(´ .text Üü P`.debug$FHB.text€   P`.debug$FÈØHB.textÐâ² P`.dataä@0À.debug$FêúHB.textP T  P`.dataš @0À.data @0À.data  @0À.data¤ @0À.data© @0À.data¬ @0À.data° @0À.debug$F´ Ä HB.textðÎ ¾  P`.debug$Fð HB.text` j  P`.debug$F~ Ž HB.textp˜   P`.debug$F: J HB.text°T   P`.dataJ @0À.debug$FM ] HB.textÀg ' P`.debug$FYiHB.text s P`.debug$FEUHB.text _ P`.debug$F“£HB.text­= P`.debug$FQaHB.text`kË P`.debug$FÕåHB-defaultlib:MSVCRT -defaultlib:OLDNAMES hˆjÿƒÄà  ì\V‹´$dWVèƒÄ…À} _ƒÈÿ^Ä\˼$lGPVèƒÄL$‰„$Qè…Àt _ƒÈÿ^Ä\ÃT$WRVèƒÄ 3À_^Ä\Ã95HIew×QSU‹l$V‹t$W‹\$¹3À‹þó«‹I‹|““…ÿ‰|$ ~‹½‹9:t @ƒÂ;D$ |òPQèƒÄPhFjPÿf‹3ÿf‰Nf‰~‹¸ƒÄ;Èuf‰Fƒ½u€Në€N ‹•‰V‹ƒùu Åf‰FDfÇFF0FH‹M‰f‹Uf‰P‹¸ÍÌÌ̃é\n\÷áÁê‰|$’D•‰D$‹ƒ„98޼M‰L$ ‹L$‹T;‘……‹L…Ét}fƒ~u.fÇF‹“„N‹DQ‰F ‹“„jD PèƒÄ ëH;l$sB‹D$ fÇE‹‹„Pj‹T‰P‹ƒ„L Qè‹L$,‹FXƒÄ ƒÅƒÁ@‰L$ ‰FX‹ƒ„‹L$AƒÇ‹‰L$;ÊŒKÿÿÿ+î_‰.^][YÃMVbR‡%s%luÉ‹L$¸ƒùu¸Ãƒù u¸Ãƒùu¸Ãƒùu¸Ãƒùu¸Ãƒùu¸Ã41.%+0(;%F"sllopppfdditrethnetKQS‹V‹t$W‹=ÇD$ `‹†€…ÀtPÿӃċD$ Pÿ׃ÄL$ ‰†€jQPè…Àt ƒøz…ŒëÄÇD$ ‹†„…ÀtPÿӃċT$ Rÿ׃ÄL$ ‰†„jQPè…ÀtƒøzuLëÈ‹†€3Ûƒ8v63ÿ‹Œƒù s/‹”IR †Q苆€ƒÄCÇ\;rÌ_^3À[YÃ_^ƒÈÿ[YÃ=<E;‰:ÃBê9V‹t$‹F‹N;Èu/‹…ÉtÀ‰FÁàPQÿƒÄëj ÇFÿƒÄ‰‹N‹‹D$ ‰Š‹F@‰F^Ã!C5<SBSV‹t$WVè‹=ƒÄ‹Ø¡ƒ8~¾hQÿ׃Ä롾‹f‹Q%…ÀtFëÌVÿ‹L$[ƒÄ‹‘_^‹‚[à QLK3JOIgHSV‹t$ W‹=jhV»ÿ×ƒÄ …Àu _^¸[ÃjhVÿ×ƒÄ …Àu _^¸ [ÃjhVÿ×ƒÄ …Àu _^¸[ÃjhVÿ×ƒÄ …Àu _^¸[ÃjhVÿ×ƒÄ …Àu _^¸[ÃjhVÿ×ƒÄ …À¸t‹Ã_^[à U1/.ITc(}%—"fd°Qì\V‹´$lWfƒ>tÿ_Ç^ƒÈÿÄ\˼$hWèƒÄ…À|,‹„3À‹…Ò~‹vƒÁ91t @ƒÁ;Â|ôÿÇ_^ƒÈÿÄ\ËAL$Q‰„$ è…ÀuÜ‹”$lD$RPWèƒÄ 3À_^Ä\Ã[69c[‰ ²×Z‹D$ ì\fƒ8VtÿǃÈÿ^Ä\ËPŒ$QRè…Àt ƒÈÿ^Ä\ÃD$Pè…Àt ƒÈÿ^Ä\Ë´$dVèƒÄ…À} ƒÈÿ^Ä\ËŒ$hT$QRVèƒÄ 3À^Ä\Ã[5aNj9 ×`ÿj2Ç(ÿƒÈÿÃ[gfìV‹´$WV3ÿèƒÄ…À} _ƒÈÿ^Ĉ€SU3íƒ8~H3ÛL$TQRVÇD$è‹„$(L$PQÿ”$,‹øƒÄ…ÿu‹†€EÃ\;(|º]‹Ç[_^ÄÃ9OŽlS‹\$…ÛtOU‹-VW‹ó¿ ‹…ÀtPÿÕƒÄƒÆ Ou€…ÀtPÿՃċƒ„…ÀtPÿÕƒÄSÿÕƒÄ3À_^][Ã3À[à =\q.fileþÿgD:\temp\libdnet-1.11\src\intf-win32.c@comp.id6& ÿÿ.drectve(Õåÿ.text dß”‡  .debug$FÝov.text€ä– ' .debug$Fqì‘.textÐ aˆ“5 F Q .dataaîzmb.debug$FâŒG.text PX¬h € .data ¢òÿŸ .data ,E¨£¤ .data :±ñ¹ .data «Q×YÏ .dataøÛñNæ.data&$òû.data 5¶Þ.debug$FP¦~ .textð;‹nå' 8 K Z h .debug$FÛ«ù[.text`7tt ‚ .debug$F’F(Ç.textp"%ÂÀ‘   ¬»Ï .debug$Fê.Ð-.text° ŽÔß .data1ËMî .debug$F‘·ÖÉ.textÀ,ï‹|   .debug$F -Ô¸.text ‰v_ø. < .debug$F~s3p.text .eØóP Z .debug$F .text!«È•p! .debug$F"!.text#`T-ô¹{# .debug$F$#‡_intf_open__imp__calloc_intf_get_GetIfEntry@4__ifrow_to_entry_addr_mtob__imp___snprintf??_C@_05HGAB@?$CFs?$CFlu?$AA@__ifcombo_name??_C@_02CHGF@sl?$AA@??_C@_02GGHE@lo?$AA@??_C@_03KNBL@ppp?$AA@??_C@_04ICFM@fddi?$AA@??_C@_02EEIK@tr?$AA@??_C@_03DBFP@eth?$AA@??_C@_03HMEG@net?$AA@__refresh_tables_GetIpAddrTable@12_GetIfTable@12__imp__malloc__imp__free__ifcombo_add__imp__realloc__find_ifindex__imp__atoi__imp___pctype__imp____mb_cur_max__imp___isctype__ifcombo_type??_C@_02FFHE@fd?$AA@__imp__strncmp_intf_get_src__imp___errno_intf_get_dst_GetBestInterface@8_intf_set__imp__SetLastError@4_intf_loop_intf_close/221 1305901072 100666 1365 ` L xÖMî .drectve(Ì .textô P`.debug$FHB.text(8 P`.debug$FBRHB.text\l P`.debug$Fv†HB.text  P`.debug$FªºHB.textÄ P`.debug$FÔäHB-defaultlib:MSVCRT -defaultlib:OLDNAMES ÿÇ(3Àà ÿÇ(ƒÈÿà ÿÇ(ƒÈÿà ÿÇ(ƒÈÿà 3ÀÃ.fileþÿgD:\temp\libdnet-1.11\src\fw-none.c@comp.id6& ÿÿ.drectve(‘·ÖÉ.text_fw_open  .debug$F.text}Ä};_fw_add .debug$F.text}Ä}; .debug$F.text}Ä};_fw_loop .debug$F .text ÙΩ… .debug$F  '__imp___errno_fw_delete_fw_close /243 1305901072 100666 2682 ` L xÖM0.drectve(Ì .text€ôt P`.debug$F.HB.text08h P`.debug$F|ŒHB.text@–Ö P`.debug$FôHB.text`n P`.debug$FxˆHB.textP’â P`.debug$FìüHB-defaultlib:MSVCRT -defaultlib:OLDNAMES ƒìh¹3ÀUVW|$ó«è‹ð…öt%‹D$xjL$ PQèT$$RVèVèƒÄfƒ|$\t _^3À]ƒÄhÃD$ Pjè‹D$ƒÄ…Àv0Pÿ‹ðƒÄ…ö‰t$xtL$ QVèƒÄ„ÀuVÿƒÄ_^3À]ƒÄhÃjjÿ‹èƒÄ…íuVÿƒÄ3À_^]ƒÄhÊS„À‹Þ„‚SèƒÄ‰E…Àt;ƒ8ÿt*T$RUèƒÄ…Àu¹|$dt$3Àfó§t*‹t$|‹MQèƒÄ‹ûƒÉÿ3Àò®÷ÑIŠD \ „Àuë‹UhÐRèƒÄè‹t$|‰EVÿ‹EƒÄ…À[u UèƒÄ‹è_‹Å^]ƒÄhÃ+6<\n†”ªºÙ ó' F N \m! ‹D$V‹t$W‹|$‹NWPQè‹V‹jRPèƒÄ‹Ç_^Ã#/V‹t$…öt)‹F…Àt PèƒÄ‹…Àt PèƒÄVÿƒÄ3À^Ã"! +6!싌$D$Pj‹ÇD$RÇD$èƒÄ <u‹„$‹L$f‹T$ ‰f‰P3ÀÄÃÈÿÄÃ((\€'ì‹„$ÇD$ÇD$‹‰L$‹Œ$f‹PD$f‰T$ ‹PjRèþÈöØÀÄ Ã>(O€-.fileþÿgD:\temp\libdnet-1.11\src\eth-win32.c@comp.id6& ÿÿ.drectve(ÜÂI+.text€>e¢  $ 3 G Z h t ‚ ™ ¥ _strlcpy ¯ .debug$Fk|v.text0ÊÌE=º Ä Ö .debug$FÄ1`Ž.text@œzXè ó .debug$FhV¶.text`‘Ï)‚_eth_get  .debug$F .text P½?_:_eth_set .debug$F  _eth_open_PacketAllocatePacket_PacketSetBuff_PacketCloseAdapter_PacketOpenAdapter__imp__calloc__imp__free__imp__malloc_PacketGetAdapterNames_intf_close_intf_get_intf_open_eth_send_PacketSendPacket_PacketInitPacket_eth_close_PacketFreePacket_PacketRequest/267 1305901072 100666 2233 ` L xÖM&*.drectveRô .text`F¦ P`.data @0À.data @0À.debug$FHB.text`(ˆ P`.debug$FØèHB.textPòB P`.data~@0À.debug$F€HB.text@šÚ P`.debug$F HB-defaultlib:uuid.lib -defaultlib:uuid.lib -defaultlib:MSVCRT -defaultlib:OLDNAMES ‹D$V‹5…Àt)‹L$QƒÂ@PRÿ¡hƒÀ@PÿÖƒÄÿ‹ PƒÁ@hQÿÖ‹T$ƒÄ Rÿ^!&+:@I Z error %lu : _‹D$V‹5…Àt)‹L$ QƒÂ@PRÿ¡hƒÀ@PÿÖƒÄÿ‹ PƒÁ@hQÿÖƒÄ ^Ã!&+:@I U‹D$…Àt‹L$ QƒÂ@PRÿƒÄ ¡hƒÀ@Pÿ‹L$ ƒÄQÿ "'"1?  C‹D$…Àt‹L$QƒÂ@PRÿƒÄ ¡hƒÀ@PÿƒÄà "'"19'.fileþÿgD:\temp\libdnet-1.11\src\err.c@comp.id6& ÿÿ.drectveR“.text` ½Éd¼_err $L74345_ .data QXþ¨3 .dataäDx¼I` p| .debug$F.text` vr9_warn .debug$FJÖ§.textPyÖ-_errx $L74350C.data Šèïú‹ .debug$F .text @¥&³-_warnx .debug$F  Ÿ__imp__exit??_C@_0L@OBLD@error?5?$CFlu?6?$AA@__imp__GetLastError@0??_C@_02HFBK@?3?5?$AA@__imp__vfprintf__imp___iob__imp__fprintf??_C@_01BJG@?6?$AA@ /285 1305901072 100666 10973 ` L=xÖM«³.drectve(œ .data Ä ä @@À.data\ @0À.textPa ±  P`.debug$Fã ó HB.text@ý P`.debug$F= M HB.text`W ·  P`.debug$FÁ Ñ HB.textpÛ K P`.debug$F_oHB.textpyé P`.debug$Fý HB.textp‡ P`.debug$F‘¡HB.text0«Û P`.debug$FåõHB.text0ÿ/ P`.debug$Fk{HB.text0…µ P`.debug$F¿ÏHB.text@Ù P`.debug$F)HB.text@3 P`.debug$FsƒHB.text@ P`.debug$FÍÝHB.textpçW P`.debug$Fk{HB.text… P`.debug$F•¥HB.text0¯ß P`.debug$FóHB.text@ M P`.debug$Fu…HB.text0¿ P`.debug$FÓãHB.textí} P`.debug$F¥µHB.text¿O P`.debug$Fw‡HB.textP‘á P`.debug$FõHB.text`o P`.debug$Fƒ“HB.text`ý P`.debug$F!HB.text`+‹ P`.debug$FŸ¯HB.textÀ¹y P`.debug$Fƒ“HB.textPí P`.datao@0À.datar@0À.datat@0À.dataw@0À.data{@0À.data€@0À.data †@0À.data@0À.debug$F‘¡HB-defaultlib:MSVCRT -defaultlib:OLDNAMES  p0w˜~œƒ ˆ°Ü’ —hexlVjÿ‹ðƒÄ…öt:ÇFÇF¡‰F ‹ QÿƒÄ‰…ÀuVÿƒÄ3À^ËÆ^Ã! * 1AP‹T$‹D$ SV‹JW‹z+Ï;È}‹Á‹2‹È‹Ù÷‹|$Áéó¥‹Ëƒáó¤‹J_È^‰J[Ã=S‹\$U‹l$‹C‹K(;Ñ~+ÁÅPSèƒÄ…Àt]ƒÈÿ[ËCV‹t$W‹;‹Íø‹ÁÁéó¥‹Èƒáó¤‹C_Å^‰C‹Å][Ã%[ S‹\$ V‹t$ W‹F<‹F ;Ç}=…Àu_^ƒÈÿ[Ë ;ù~ ‹Ç™÷ù@¯Á‹ø‹WQÿƒÄ…Àu_^ƒÈÿ[ɉ~ ‹F_ÉF^3À[Ã% >c%S‹\$U‹l$USèƒÄ…ÀuQ‹C …ÀtJ‹K‹C+Á…À~‹PÊQÍQÿƒÄ ‹V‹t$W‹{‹Íø‹ÁÁéó¥‹Èƒáó¤‹C_Å^‰C‹Å][Ã]ƒÈÿ[à %6+o*S‹\$U‹l$‹C‹S (;ÊQ‹K …ÉtJW‹|$…ÿt‹ÍV‹3‹ÑðÁéó¥‹Êƒáó¤^‹C‹ ‹SÈ+Ð+Õ)RPQÿ‹CƒÄ +ʼnC‹Å_][Ã]ƒÈÿ[ÃS+n0Q‹T$ D$L$‰D$‹D$QRjPèƒÄÃ:#5‹L$ S‰L$UŠV„ÀW„‹l$ ‹|$‹t$Š<%…Œ¡A‰L$ƒ8~¾ jQÿ‹L$$ƒÄ롾‹ŠPƒà…ÀtT$j RQÿ‹L$(ƒÄ ë€9*u‹]ƒÃA‹Ã‰]‹@ü‰L$ë3À¾ ‹ …Ét~UVPWÿуÄ…À|q‹L$ëV…ÿt9‹F‹VX;Ú|+Â@PVèƒÄ…ÀuI‹L$‹‹FŠ ˆ ‹F‹L$@‰Fë‹~‹3ÛŠ:G¾À;؉~u‹|$A‰L$€9…ÿÿÿ_^]3À[Ã_^]ƒÈÿ[Ã->C=Q<n; Ï%+:Q‹T$ D$L$‰D$‹D$QRjPèƒÄÃ:#C‹D$ ‹L$ƒøu ‹D$‹Që ƒø‹D$u‹QÂ…À| ;A‰AÃÈÿÃ5H‹L$SUV‹Y‹t$‹A+Þ;ÃW‹ЋL$‹|$‹ò3íó¦t @B;Ã~êƒÈÿ_^][Ã:M‹L$S‹\$U‹AV+ÃWx‹Ћ|$‹Ë‹ò3íó¦t HJ…À}ìƒÈÿ_^][Ã3R¡W…À¿tTS‹\$ U‹l$V‹‹õŠŠÊ:u„ÉtŠPŠÊ:VuƒÀƒÆ„Éuà3ÀëÀƒØÿ…ÀuSÿWƒÄ‹GƒÇ…Àu¾^][3À_Ã3À_à gW3ÀÃ\V‹t$‹F …Àt ‹PÿƒÄVÿƒÄ3À^Ã&a‹D$£‹D$…Àt£‹D$ …Àt£‹D$…Àt£3Àà ,3f¾D$‹ ……Éu‹L$‰ …3ÀÃÈÿà  "k‹D$V…ÀtƒÈÿ^ËD$…À‹D$t8‹ƒÁ‰‹Á‹@üP‰D$ÿ‹L$‰D$D$jPQèƒÄ …À}6ƒÈÿ^Ë0‹T$ƒÆj‰0‹Æ‹püVRèƒÄ ƒøtƒÈÿ^ËPÿ‰3À^Ã-rB g}q‡p‹D$V…ÀtƒÈÿ^ËD$…À‹D$t9‹ƒÁ‰‹Áf‹@üP‰D$ÿ‹L$‰D$D$jPQèƒÄ …À}8ƒÈÿ^Ë0‹T$ƒÆj‰0‹Æ‹püVRèƒÄ ƒøtƒÈÿ^Ãf‹Pÿf‰3À^Ã.yC hxŠw‹D$‹ƒÁ‰‹Á‹L$‹@ü…ɃÈÿËT$Q…ÒPt‹D$PèƒÄ ËL$QèƒÄ Ã, :B~‹D$…ÀtƒÈÿËD$…À‹D$‹t#‹T$ ƒÁ‰‹ÁL$jŠ@üQRˆD$èƒÄ ÃÁj‰‹Á‹@üP‹D$PèƒÄ Ã5 PXƒ‹D$…ÀtƒÈÿËD$…À‹D$‹t#‹T$ ƒÁ‰‹ÁL$j‹@üQR‰D$èƒÄ ÃÁj‰‹Á‹@üP‹D$PèƒÄ Ã5 PXˆ‹D$…ÀtƒÈÿËD$…À‹D$‹t$‹T$ ƒÁ‰‹ÁL$jf‹@üQR‰D$èƒÄ ÃÁj‰‹Á‹@üP‹D$PèƒÄ Ã6 QY‹D$SU2Û‹VƒÁW‰‹Á‹hü‹D$…ÀtH‹t$…ö~Š\.ÿ„ÛtÆD.ÿë‹ýƒÉÿ3Àò®÷ÑI‹ñF‹D$VUPèƒÄ …À~E„Ûtˆ\.ÿ‹Æ_^][ËD$…À~.‹T$‹r‹z+÷;ð}‹ð3À…ö~‹J‹ËŠ „Ɉ (t @;Æ|ê_^]ƒÈÿ[ËrHñ_‰r^][ÃL ´’ƒìS‹\$UV‹C‹-W‹;‹ÈhÏ‹{+ø‰L$‰|$ÿÕƒÄ3ö…ÿ‰t$†ë‹\$$‹|$‹S‹ÆÂPhÿÕ+þƒÄƒÿv¿3Û…ÿv+öøu¸‹L$3ÒΊRPÿÕƒÄC;ßrÚƒûsöøu¸PÿÕƒÄCƒûråhÿÕƒÄ3Û…ÿv`‹T$ò‰t$‹L$‹3ÀŠ‹ð‹ƒø~hWVÿƒÄë¡‹f‹q%W…Àu¾.VhÿÕƒÄC;ßr®‹t$hÿÕ‹D$ƒÆƒÄ;ð‰t$‚ÿÿÿ_^][ƒÄð¯R¬q©x¦œ££ ´Ó>í=÷<š$¯%c %02x%02x %04x: H—.fileþÿgD:\temp\libdnet-1.11\src\blob.c@comp.id6& ÿÿ.drectve(ôH @.data  b@§.dataþ&6*_bl_size _bl_free_free :_realloc F_malloc .textP—±£Q .debug$F.text@…l:Œ[ .debug$F.text`ŽúT#f .debug$F .text pß’ðŒr .debug$F ñØã .text pÑV€  .debug$F  .textpGiØœ .debug$F.text0íä^u© .debug$FuÆ` .text0¾d¾´ ¾ ÌÛ ë.debug$F.text0Ê{ôÿ .debug$F.text@¹OSù  .debug$F.text@—£“¦ .debug$F.text@,( i# .debug$F.textpF*u0 .debug$F.textÙΩ…< .debug$F.text 0iUœI .debug$F! .text"@ÛënGT" .debug$F#".text$0-øI’i$ .debug$F%ÎkûÝ$.text&|æ*_fmt_D& } Œ .debug$F'Ã\…&.text(Ö~êu_fmt_H( › ª .debug$F)(.text*P‹ZW_fmt_b* .debug$F+*.text,`“ø§2_fmt_c, .debug$F-,.text.`õà…C_fmt_d. .debug$F/..text0`pƒxê_fmt_h0 .debug$F10.text2ÀÖ’»_fmt_s2 .debug$F3Îw7 2.text4P ¬¬Ñ¹4 .data5o¼VpÅ5.data6¢$„•Ý6.data7BbÉ­ò7.data8|Íû  8.data9Õš9"9.data:cc<:.data; ²#*¤X;.data<Šèïúz<Ž .debug$F=4œ_blob_printers??_C@_04KAKK@hexl?$AA@_blob_ascii_fmt_bl_realloc_bl_malloc_blob_new_blob_read_blob_write_blob_reserve_blob_insert__imp__memmove_blob_delete_blob_pack_blob_fmt__imp__strtol__imp___pctype__imp___isctype__imp____mb_cur_max_blob_unpack_blob_seek_blob_index_blob_rindex_blob_print_blob_sprint_blob_free_blob_register_alloc_blob_register_pack__imp__ntohl@4__imp__htonl@4__imp__ntohs@4__imp__htons@4_print_hexl??_C@_02JBML@?$CFc?$AA@??_C@_01FCOA@?5?$AA@??_C@_02IHLC@?5?5?$AA@??_C@_03MFGH@?5?5?5?$AA@??_C@_04OBKB@?$CF02x?$AA@??_C@_05OOAB@?$CF02x?5?$AA@??_C@_08MPCM@?5?5?$CF04x?3?5?$AA@??_C@_01BJG@?6?$AA@__imp__printf /304 1305901072 100666 2845 ` LxÖMt5.drectve(l .text”¤ P`.debug$F®¾HB.textpÈ8 P`.debug$FVfHB.text€pð P`.debug$F(HB.text@2r P`.debug$FšªHB.text@´ô P`.debug$FþHB.textÐè P`.debug$FHB.text0 P P`.debug$FZjHB-defaultlib:MSVCRT -defaultlib:OLDNAMES jjÿƒÄà  ƒìPD$V‹t$\Pjÿ‹NPQè…ÀtƒÈÿ^ƒÄPËT$,F‰T$ÇD$‹ÇD$‰L$ L$f‹P‹FQf‰T$‰D$è÷ØÀ^ƒÄPÃboƒìPD$V‹t$\Pjÿ‹NPQè…ÀtƒÈÿ^ƒÄPËT$,W¹3À|$ó«‹FL$Q‰T$ ‰D$è…À_tÿǃÈÿ^ƒÄPÃ3À^ƒÄPÃNYr‹D$‹L$PhQèƒÄ ƒøtÿhèÇÿƒÈÿÃ3Àà $*/:V‹t$W‹|$WVèƒÄ…ÀuƒÆƒÇ¹¸ó¥_^Ã_3À^à %2$ƒì,S‹UV‹5W‹|$@ÇD$‹…ÀtPÿӃċD$PÿÖƒÄL$‰jQPè…ÀtƒøzuuëЋfÇD$fÇD$ fÇD$(fÇD$*0‹3Û…É~C‹l$H3öƒ|u,‹TD ‰T$U‹‰L$0f‹PD$Pf‰T$8ÿT$LƒÄ…Àu‹CƒÆ;|Ã_^]3À[ƒÄ,ÃÈÿ_^][ƒÄ,Ã-,@+Í *V‹t$…öt‹W‹=…ÀtPÿ׃ÄVÿ׃Ä3À_^Ã3À^Ã-+2.fileþÿgD:\temp\libdnet-1.11\src\arp-win32.c@comp.id6& ÿÿ.drectve(Õåÿ.textÖöè~  .debug$Fcï".textp½¡_arp_add  0 A .debug$Fsˆâ.text€Љg'P \ j .debug$F~s3p.text@Âz™¯_arp_get ~ .debug$F -U’.text @„8.8” ¤ .debug$F $¬oË .text ÐcÝÊ® ¸ Ê Ø .debug$F  .text0™ª.¾ä .debug$Fï_arp_open__imp__calloc_CreateIpNetEntry@4_GetBestRoute@12__imp__htonl@4_arp_delete__imp___errno_DeleteIpNetEntry@4__imp__SetLastError@4__arp_get_entry_addr_cmp_arp_loop_GetIpNetTable@12__imp__malloc__imp__free_arp_close /328 1305901072 100666 6090 ` LxÖM½].drectve(t .text œ P`.debug$F<LHB.text Vv P`.debug$F¼ÌHB.text Öv P`.dataž@0À.debug$F¥µHB.text¿¿ P`.data @0À.debug$F # HB.textp- P`.debug$F÷  HB.text` q  P`.bss€0À.debug$FÁ Ñ HB.textpÛ K  P`.debug$FU e HB.textpo ß  P`.debug$Fé ù HB.textP S  P`.debug$Fg w HB.text` P`.debug$Fá ñ HB.textû  P`.debug$F)9HB.text`C P`.debug$F£³HB-defaultlib:MSVCRT -defaultlib:OLDNAMES SU‹l$ V‹t$3Àf‹E3Éf‹W+Áu{3É3Àf‹Nf‹E+Á‰L$ug‹ùÁï…ÿ~)ºüÿÿÿ+îN+Ö3À3ÛŠ)Š+ÃuEA ;Ç|ë‹l$‹L$‹Á%€yHƒÈø@u_^]3À[ùƒÊÿ+È3ÀŠD/Óâ3ÉŠL7#Ê#Â+Á_^][ÛS‹\$VWf‹f=u5f‹KD$jPQè‹D$ ‹L$ƒÄ fÇfÇ@ ‹S_#Ñ^‰P3À[Ãf=u,‹D$¹‹ó‹øó¥öCt P3Éf‰ ˆJ_fÇ@0^3À[Ãf=…ˆ‹|$3öOf‰‹Ñ3ÀfÇG€‰‰B‰B‰B f‹sÁîFÿƒøwÿ$…‹C‰G‹S ‰W ‹C‰G‹S‰3Àf‹C%€yHƒÈà@…À~L$jQPè‹T³‹D$ƒÄ #ЉT·_^3À[Ã_^ƒÈÿ[ÃT´îT  ƒìV‹t$f‹f=u:f‹ND$jPQè‹L$,‹D$ƒÄ fÇfÇA ‹V^#Ð÷Ð Ð3À‰QƒÄÃf=u,‹D$ ^fÇfÇ@0‹ ƒÀ‰f‹f‰P3ÀƒÄÃÿǃÈÿ^ƒÄÃTcoÿÿÿÿÿÿ‘S‹D$V‹t$ Wf‹fƒùuSƒørN‹\$PFSPèƒÄ …À„²f‹vfƒþ tz‹ûƒÉÿ3Àæÿÿò®÷ÑIVËhQÿƒÄ ‹Ã_^[ÃfƒùuPƒø*rK‹\$PNSQèƒÄ …Àt]f‹vfþ€t$‹ûƒÉÿ3Àæÿÿò®÷ÑIVËhQÿƒÄ _‹Ã^[Ãfƒùu"ƒørfƒ~0u‹T$PƒÆRVèƒÄ _^[Ãÿ_Ç^3À[Ã$'S&Z#}"©&°#Ú!ç/%d÷ ì83ÒSVW‹¼$Ht$ƒËÿ‹Ï+÷Š¥ ° Ç Ñ Û _ip_pton é .debug$F Ñ/ .text`‰†AH÷ .bss.debug$F.textp…BbÜ2 .debug$F.textpK®ª8= .debug$F.textP`NkH .debug$F.text`;u’S .debug$Fé ñ.text!~g^ i .debug$F.text`±r‰x .debug$Fƒ_addr_cmp_addr_net_addr_bcast__imp___errno??_C@_06POGA@?$PP?$PP?$PP?$PP?$PP?$PP?$AA@_addr_ntop_eth_ntop_ip6_ntop__imp__sprintf??_C@_03KICP@?1?$CFd?$AA@_addr_pton__imp__gethostbyname@4_ip6_pton_eth_pton__imp__strtol__imp__strchr_addr_ntoa_?buf@?1??addr_ntoa@@9@9_?p@?1??addr_ntoa@@9@9_addr_ntos_addr_ston_addr_btos_addr_stob_addr_btom__imp__htonl@4_addr_mtob/347 1305901072 100666 61249 ` L¼xÖM’m6.drectve(tE .dataœEœM@0À.dataœa@0À.dataŸa@0À.data¢a@0À.data¥a@0À.data¨a@0À.data«a@0À.data®a@0À.data±a@0À.data´a@0À.data·a@0À.dataºa@0À.data½a@0À.dataÀa@0À.dataÃa@0À.dataÆa@0À.dataÉa@0À.dataÌa@0À.dataÏa@0À.dataÒa@0À.dataÕa@0À.dataØa@0À.dataÛa@0À.dataÞa@0À.dataáa@0À.dataäa@0À.dataça@0À.dataêa@0À.dataía@0À.dataða@0À.dataóa@0À.dataöa@0À.dataùa@0À.dataüa@0À.dataÿa@0À.datab@0À.datab@0À.datab@0À.data b@0À.datab@0À.datab@0À.datab@0À.datab@0À.datab@0À.datab@0À.data b@0À.data#b@0À.data&b@0À.data)b@0À.data,b@0À.data/b@0À.data2b@0À.data5b@0À.data8b@0À.data;b@0À.data>b@0À.dataAb@0À.dataDb@0À.dataGb@0À.dataJb@0À.dataMb@0À.dataPb@0À.dataSb@0À.dataVb@0À.dataYb@0À.data\b@0À.data_b@0À.databb@0À.dataeb@0À.datahb@0À.datakb@0À.datanb@0À.dataqb@0À.datatb@0À.datawb@0À.datazb@0À.data}b@0À.data€b@0À.dataƒb@0À.data†b@0À.data‰b@0À.dataŒb@0À.datab@0À.data’b@0À.data•b@0À.data˜b@0À.data›b@0À.datažb@0À.data¡b@0À.data¤b@0À.data§b@0À.dataªb@0À.data­b@0À.data°b@0À.data³b@0À.data¶b@0À.data¹b@0À.data¼b@0À.data¿b@0À.dataÂb@0À.dataÅb@0À.dataÈb@0À.dataËb@0À.dataÎb@0À.dataÑb@0À.dataÔb@0À.data×b@0À.dataÚb@0À.dataÝb@0À.dataàb@0À.dataãb@0À.dataæb@0À.dataéb@0À.dataìb@0À.dataïb@0À.dataòb@0À.dataõb@0À.dataøb@0À.dataûb@0À.dataþb@0À.datac@0À.datac@0À.datac@0À.data c@0À.data c@0À.datac@0À.datac@0À.datac@0À.datac@0À.datac@0À.datac@0À.data"c@0À.data%c@0À.data(c@0À.data+c@0À.data.c@0À.data1c@0À.data4c@0À.data7c@0À.data:c@0À.data=c@0À.data@c@0À.dataCc@0À.dataFc@0À.dataIc@0À.dataLc@0À.dataOc@0À.dataRc@0À.dataUc@0À.dataXc@0À.data[c@0À.data^c@0À.dataac@0À.datadc@0À.datagc@0À.datajc@0À.datamc@0À.datapc@0À.datasc@0À.datavc@0À.datayc@0À.data|c@0À.datac@0À.data‚c@0À.data…c@0À.dataˆc@0À.data‹c@0À.dataŽc@0À.data’c@0À.data–c@0À.datašc@0À.datažc@0À.data¢c@0À.data¦c@0À.dataªc@0À.data®c@0À.data²c@0À.data¶c@0À.dataºc@0À.data¾c@0À.dataÂc@0À.dataÆc@0À.dataÊc@0À.dataÎc@0À.dataÒc@0À.dataÖc@0À.dataÚc@0À.dataÞc@0À.dataâc@0À.dataæc@0À.dataêc@0À.dataîc@0À.dataòc@0À.dataöc@0À.dataúc@0À.dataþc@0À.datad@0À.datad@0À.data d@0À.datad@0À.datad@0À.datad@0À.datad@0À.datad@0À.data"d@0À.data&d@0À.data*d@0À.data.d@0À.data2d@0À.data6d@0À.data:d@0À.data>d@0À.dataBd@0À.dataFd@0À.dataJd@0À.dataNd@0À.dataRd@0À.dataVd@0À.dataZd@0À.data^d@0À.databd@0À.datafd@0À.datajd@0À.datand@0À.datard@0À.datavd@0À.datazd@0À.data~d@0À.data‚d@0À.data†d@0À.dataŠd@0À.dataŽd@0À.data’d@0À.data–d@0À.datašd@0À.datažd@0À.data¢d@0À.data¦d@0À.dataªd@0À.data®d@0À.data²d@0À.data¶d@0À.dataºd@0À.data¾d@0À.dataÂd@0À.dataÆd@0À.dataÊd@0À.dataÎd@0À.dataÒd@0À.dataÖd@0À.dataÚd@0À.dataÞd@0À.dataâd@0À.dataæd@0À.dataêd@0À.dataîd@0À.dataòd@0À.dataöd@0À.dataúd@0À.dataþd@0À.datae@0À.datae@0À.data e@0À.datae@0À.datae@0À.datae@0À.datae@0À.datae@0À.data"e@0À.data&e@0À.data*e@0À.data.e@0À.data2e@0À.data6e@0À.data:e@0À.data>e@0À.dataBe@0À.dataFe@0À.dataJe@0À.dataNe@0À.dataRe@0À.dataVe@0À.dataZe@0À.data^e@0À.databe@0À.datafe@0À.dataje@0À.datane@0À.datare@0À.datave@0À.dataze@0À.data~e@0À.data‚e@0À.data†e@0À.dataŠe@0À.dataŽe@0À.data’e@0À.data–e@0À.dataše@0À.dataže@0À.data¢e@0À.data¦e@0À.dataªe@0À.data®e@0À.data²e@0À.data¶e@0À.dataºe@0À.data¾e@0À.dataÂe@0À.dataÆe@0À.dataÊe@0À.dataÎe@0À.dataÒe@0À.dataÖe@0À.dataÚe@0À.dataÞe@0À.dataâe@0À.dataæe@0À.dataêe@0À.dataîe@0À.dataòe@0À.dataöe@0À.dataúe@0À.dataþe@0À.dataf@0À.dataf@0À.dataf@0À.data f@0À.data f@0À.dataf@0À.dataf@0À.dataf@0À.dataf@0À.dataf@0À.dataf@0À.data"f@0À.data%f@0À.data(f@0À.data+f@0À.data.f@0À.data1f@0À.data4f@0À.data7f@0À.data:f@0À.data=f@0À.data@f@0À.dataCf@0À.dataFf@0À.dataIf@0À.dataLf@0À.dataOf@0À.dataRf@0À.dataUf@0À.dataXf@0À.data[f@0À.data^f@0À.dataaf@0À.datadf@0À.datagf@0À.datajf@0À.datamf@0À.datapf@0À.datasf@0À.datavf@0À.datayf@0À.data|f@0À.dataf@0À.data‚f@0À.data…f@0À.dataˆf@0À.data‹f@0À.dataŽf@0À.data‘f@0À.data”f@0À.data—f@0À.datašf@0À.dataf@0À.data f@0À.data£f@0À.data¦f@0À.data©f@0À.data¬f@0À.data¯f@0À.data²f@0À.dataµf@0À.data¸f@0À.data»f@0À.data¾f@0À.dataÁf@0À.dataÄf@0À.dataÇf@0À.dataÊf@0À.dataÍf@0À.dataÐf@0À.dataÓf@0À.dataÖf@0À.dataÙf@0À.dataÜf@0À.dataßf@0À.dataâf@0À.dataåf@0À.dataèf@0À.dataëf@0À.dataîf@0À.datañf@0À.dataôf@0À.data÷f@0À.dataúf@0À.dataýf@0À.datag@0À.datag@0À.datag@0À.data g@0À.data g@0À.datag@0À.datag@0À.datag@0À.datag@0À.datag@0À.datag@0À.datag@0À.datag@0À.datag@0À.textP gpg P`.debug$FzgŠgHB.text@”gÔg P`.debug$FègøgHB.text`hbh P`.debug$Flh|hHB.textP†hÖh P`.debug$FàhðhHB.text@úh:i P`.debug$FNi^iHB.text`hiÈi P`.debug$FÒiâiHB.textpìi\k P`.data„k@0À.debug$Fˆk˜kHB.text@¢kâk P`.debug$FöklHB.text@lPm P`.bss€0À.debug$FxmˆmHB-defaultlib:MSVCRT -defaultlib:OLDNAMES üùö óðíêç ä$á(Þ,Û0Ø4Õ8Ò<Ï@ÌDÉHÆLÃPÀT½Xº\·`´d±h®l«p¨t¥x¢|Ÿ€œ„™ˆ–Œ“”˜Šœ‡ „¤¨~¬{°x´u¸r¼oÀlÄiÈfÌcÐ`Ô]ØZÜWàTäQèNìKðHôEøBü?<96 30-*' $$!(,048<@ D HLPTýXú\÷`ôdñhîlëpètåxâ|߀܄و֌ÓД͘ʜǠĤÁ¨¾¬»°¸´µ¸²¼¯À¬Ä©È¦Ì£Ð Ôؚܗà”ä‘èŽì‹ðˆô…ø‚ü|yv spmjg d$a(^,[0X4U8R<O@LDIHFLCP@T=X:\7`4d1h.l+p(t%x"|€„ˆŒ” ˜ œ ¤¨þ¬û°ø´õ¸ò¼ïÀìÄéÈæÌãÐàÔÝØÚÜ×àÔäÑèÎìËðÈôÅøÂü¿¼¹¶ ³°­ª§ ¤$¡(ž,›0˜4•8’<@ŒD‰H†LƒP€T}Xz\w`tdqhnlkphtexb|_€\„YˆVŒSP”M˜JœG D¤A¨>¬;°8´5¸2¼/À,Ä)È&Ì#Ð ÔØÜàäèì ðôøüÿûøõ òïìéæ ã$à(Ý,Ú0×4Ô8Ñ<Î@ÞDÛHØLÕPÒTÏXÌ\É`ÆdÃhËlÈpÅtÂx¿|¼€À„½ˆºŒ·´”±˜®œ« ¨¤¥¨¹¬¶°³´°¸­¼ªÀ¢ÄŸÈœÌ™Ð–Ô“ØÜàŠä‡è§ì¤ð¡ôžø›ü˜„~ {xuro l$i(•,’04Œ8‰<†@fDcH`L]PZTWXT\Q`NdKhƒl€p}tzxw|t€H„EˆBŒ?<”9˜6œ3 0¤-¨q¬n°k´h¸e¼bÀ*Ä'È$Ì!ÐÔØÜàäè_ì\ðYôVøSüP   ýú÷ ô$ñ(M,J0G4D8A<>@îDëHèLåPâTßXÜ\Ù`ÖdÓh;l8p5t2x/|,€)„&ˆ#Œ ”˜œ ¤¨ ¬°´¸ÿ¼üÀùÄöÈóÌðÐíÔêØçÜäàáäÞèÛìØðÕôÒøÏüÌÉÆÃ À½º·´ ±$®(«,¨0¥4¢8Ÿ<œ@™D–H“LPTŠX‡\„`d~h{lxputrxo|l€i„fˆcŒ`]”Z˜WœT Q¤N¨K¬H°E´B¸?¼<À9Ä6È3Ì0Ð-Ô*Ø'Ü$à!äèìðôøü fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a8f8e8d8c8b8a7f7e7d7c7b7a6f6e6d6c6b6a5f5e5d5c5b5a4f4e4d4c4b4a3f3e3d3c3b3a2f2e2d2c2b2a1f1e1d1c1b1a0f0e0d0c0b0a090807060504030201002552542532522512502492482472462452442432422412402392382372362352342332322312302292282272262252242232222212202192182172162152142132122112102092082072062052042032022012001991981971961951941931921911901891881871861851841831821811801791781771761751741731721711701691681671661651641631621611601591581571561551541531521511501491481471461451441431421411401391381371361351341331321311301291281271261251241231221211201191181171161151141131121111101091081071061051041031021011009998979695949392919089888786858483828180797877767574737271706968676665646362616059585756555453525150494847464544434241403938373635343332313029282726252423222120191817161514131211109876543210‹T$ ‹D$ƒú‹Ès3ÀÃSVW‹|$3ö3ÒŠ>‹•Š„Ûˆt ŠZBA„ÛˆuõÆ:AFƒþ|×_^ÆAÿ[Ã# Lÿƒì‹D$jL$PQfÇD$ fÇD$0ÿT$ RèƒÄ$Ã)1S‹\$ U‹-V‹t$W3ÿD$jPVÿÕ‹L$$ƒÄ ;Ît!…À|=ÿƒÿ}€9:u ˆGƒÿq|ʃÿ_^][u€9u3ÀÃÈÿà _ ‹T$ ‹D$ƒú‹Ès3ÀÃSVW‹|$3ö3ÒŠ>‹•Š„Ûˆt ŠZBA„ÛˆuõÆ.AFƒþ|×_^ÆAÿ[Ã#üLƒì‹D$jL$PQfÇD$ fÇD$ ÿT$ RèƒÄ$Ã)1S‹\$ U‹-V‹t$W3ÿD$j PVÿÕ‹L$$ƒÄ ;Ît!…À|=ÿƒÿ}€9.u ˆGƒÿq|ʃÿ_^][u€9u3ÀÃÈÿà _‹D$ ƒìƒø.SUVW‹|$ s _^]3À[ƒÄËL$ƒÎÿƒÈÿ‰t$3Ò‹\$fƒ<uƒøÿu‹Â3Éë"ƒÁëƒøÿtƒþÿt;L$~ ‰D$‰L$‹ðƒÈÿƒÂƒú|Àƒøÿtƒþÿt‹T$;Ê~‰D$‰L$‹ð‹T$ƒþÿtƒú} ÇD$ÿÿÿÿë…öuÆ:G‹‹-3ö‹D$;ðuÆ:GòëEƒþ u…Àuƒú tWƒúu ‹D$fx ÿÿtF‹L$f‹RÿÕ%ÿÿPhWÿÓ‹T$ ƒÄ ø‹D$ƒÆƒþ|£Tƒúu=‹D$ Æ_^][ƒÄËt$ ‹T$$‹L$‹Æ+ǃÁ ÂPWQèƒÄ ÷ØÀ_#Æ^][ƒÄËD$ ÆGÿ_^][ƒÄì%²$ù#F%x:k ƒì‹D$jL$PQfÇD$ fÇD$€ÿT$ RèƒÄ$Ã)1*ƒìSUV‹t$$WƒÏÿЉ|$<:uF3í\$D$(jPVÿ‹L$4ƒÄ ;Îu€9:uPƒÿÿuK‰l$F‹ýë7€9.uƒý~H…À|9=ÿÿ2Pÿ‹L$(f‰Š„ÀtI<:uŠAq„ÀtEƒÃƒý|”ë1€9t,_^]ƒÈÿ[ƒÄÃLlQVèƒÄ…À|㹃ʼnL$(ëE…ítЀ9u˃ÿÿuƒýuÁ‹\$,3Ò…ÿ~‹Ït$‹û‹T$Ñéó¥Éfó¥‹ú+ýG ;Ð}+Âކ»ñß>.data?Iú¾ô?.data@!á§ @.dataAËrÌŒA.dataBŠCו3B.dataCoÓôxHC.dataD¬€ÙS]D.dataEí±ÂJrE.dataF*'ƒ†F.dataGk˜›G.dataH¨Eµ7°H.dataIô’×EÄI.dataJµ£Ì\ÙJ.dataKz¿TÛîK.dataL;ŽOÂL.dataMøÝbéM.dataN¹ìyð-N.dataO~z8¿AO.dataP?K#¦VP.dataQükQ.dataR½)”R.dataS6m²z”S.dataTõ>ŸQ©T.dataU´„H¾U.dataVs™ÅÓV.dataW2¨ÞèW.dataXñûó5ýX.dataY­,‘GY.dataZìŠ^'Z.data[#Ù<[.data\b0 ÀQ\.data]¡c$ëf].data^àR?ò{^.data_'Ä~½_.data`fõe¤¥`.dataa¥¦Hºa.databä—S–Ïb.datac>äc.datadýA03ùd.datae¼p+*e.dataf{æje#f.datag:×q|8g.datahù„\WMh.datai xßbi.datajÊ+ò2vj.datak‹é+‹k.datalLŒ¨d l.datam ½³}´m.datanÎîžVÉn.datao4?ƒÞo.datap÷l®9óp.dataq¶]µ  q.datarqËôo r.datas0úïv2 s.datató©Â]G t.datauUA\ u.datavÀl8q v.dataw7w!† w.dataxF¡6n› x.datay-w° y.datazÄÃ\Å z.data{ZëÚ {.data|™¸*:ï |.data}؉1# }.data~pl ~.data^.ku- .data€}F^B €.datamÅW .data‚®Òè;l ‚.dataƒïãó" ƒ.data„(u²m– „.data…iD©t« ….data†ª„_À †.data‡è—ŠÕ ‡.dataˆ+ħ>ê ˆ.data‰jõ¼'ÿ ‰.dataŠ­cýh Š.data‹ìRæq) ‹.dataŒ/ËZ> Œ.dataßýHS .dataŽ®e?h Ž.data]Ÿ~&} .dataš ?i’ .data‘Û8$p§ ‘.data’k [¼ ’.data“†CÑ “.data”E#=æ ”.data•!8$û •.data–÷yk –.data—‚†br% —.data˜AÕOY9 ˜.data™±)ÌN ™.datašrzá<c š.data›3Kú%x ›.dataœôÝ»j œ.dataµì s¢ .datažv¿X· ž.dataŸ*hï*Ì Ÿ.data kYô3á  .data¡¤El´ö ¡.data¢åtw­ ¢.data£&'Z† £.data¤gAŸ5 ¤.data¥ €ÐJ ¥.data¦á±É_ ¦.data§"â6ât §.data¨cÓ-û‰ ¨ž .data©çÕ³Ú© ©.dataª¦ä¨Ã¿ ª.data«aréŒÕ «.data¬ Cò•ë ¬.data­ãß¾­.data®¢!ħ®.data¯ÜðÄw-¯.data°ÁßnC°.data±RÝGéY±.data²ì\ðo².data³пqÛ…³.data´‘Žj›´.dataµV+±µ.data¶)0”Ƕ.data·Ôz¿Ý·.data¸•K¦ó¸.data¹Yæ‹r ¹.dataº×kº.data»×Ëì5».data¼–úõK¼.data½U©>Þa½.data¾˜%Çw¾.data¿Ódˆ¿.dataÀ’?‘£À.dataÁQlRº¹Á.dataÂ]I£ÏÂ.dataÃnŒIsåÃ.dataÄ/½RjûÄ.dataÅà¡ÊíÅ.dataÆ¡Ñô'Æ.dataÇbÃüß=Ç.dataÈ#òçÆSÈ.dataÉäd¦‰hÉ.dataÊ¥U½~Ê.dataËf»”Ë.dataÌ'7‹¢©Ì.dataÍ72q¿Í.dataÎvhÕÎ.dataϹŒïëÏ.dataÐø.—öÐ.dataÑ;}ºÝÑ.dataÒzL¡Ä-Ò.dataÓ½Úà‹CÓ.dataÔüëû’YÔ.dataÕ?¸Ö¹oÕ.dataÖ~‰Í …Ö.data×XÍp›×.dataØAiÖi±Ø.dataÙŽuNîÇÙ.dataÚÏDU÷ÝÚ.dataÛ xÜóÛ.dataÜM&cÅ Ü.dataÝа"ŠÝ.dataÞË9“5Þ.dataßÒ¸Kß.dataàIã¡aà.dataáaÌ©mwá.dataâ ý²tâ.dataãïá*ó£ã.dataä®Ð1ê¹ä.dataåmƒÁÏå.dataæ,²Øåæ.dataçë$F—ûç.dataèª]Žè.dataéiFp¥'é.dataê(wk¼=ê.dataëV¦klSë.dataì—puiì.dataíØ‹èòí.dataóë•î.dataïZéÞÀ«ï.dataðØÅÙÁð.datañÜN„–×ñ.dataòŸíò.dataó^,²¤ó.dataô©½ô.dataõká7g/õ.dataö*Ð,~Eö.data÷åÌ´ù[÷.dataø¤ý¯àqø.dataùg®‚ˇù.dataú&Ÿ™Òú.dataûá Ø³û.dataü 8ÄÉü.dataýckî¯ßý.dataþ"Zõ¶õþ.dataÿ\‹õf ÿ.dataºî!.dataÒ¦vø7.data“—máM.dataPÄ@Êc.dataõ[Óx.dataÖcœŽ.data—R…¤.dataT,®º.data07·Ð.data 5³då .data D¨}û .data ‹0ú .data Ê)+ã' .data  zÈ= .dataHKÑS.dataÝ\ži.dataÎìG‡.data ¿j¬•.dataLŽqµ«.data2_qeÁ.datasnj|×.data¼ròûí.dataýCéâ.data>ÄÉ.data!ßÐ/.data¸·žŸE.dataù†…†[.data:Õ¨­q.data{ä³´‡.data·I>`.dataöx%y³.data9d½þÉ.data xU¦çß .data!»‹Ìõ!.data"ú7Õ ".data#=¡Ñš!#.data$|ʃ7$.data%¿Ãç¨M%.data&þòü±c&.data'€#üay'.data(Áçx(.data)ÿ¤).data*O?dæ¹*.data+ŒlIÍÏ+.data,Í]RÔå,.data- Ë›û-.data.Kú‚..data/ˆ©%©&/.data0ɘ>°<0.data1ÙºcR1.data2˜¬¡zh2.data3W°9ý~3.data4"ä”4.data5ÕÒϪ5.data6”ãÖÀ6.data7SuU™Ö7.data8DN€ì8.data9Ñc«9.data:&x²:.data;î÷xb.;.data<¯Æc{D<.data=`ÚûüZ=.data>!ëàåp>.data?â¸ÍΆ?.data@£‰Öל@.dataAd—˜²A.dataB%.ŒÈB.dataCæ}¡ªÞC.dataD§Lº³ôD.dataE¥S>% E.dataFäb%<F.dataG+~½»4G.dataHjO¦¢IH.dataI©‹‰^I.dataJè-sJ.dataK/»Ñ߈K.dataLnŠÊÆL.dataM­Ùçí²M.dataNìèüôÇN.dataO’9ü$ÜO.dataPÓç=ðP.dataQºQ.dataR]%d£R.dataSžvIˆ.S.dataTßGR‘CT.dataUÑÞXU.dataVYàÇlV.dataWš³%ìW.dataXÛ‚>õ–X.dataY¯~ /«Y.dataZîO»6ÀZ.data[!S#±Õ[.data\`b8¨ê\.data]£1ƒÿ].data^âš^.data_%–OÕ)_.data`d§TÌ>`.dataa§ôyçSa.databæÅbþhb.datac˜b.}c.datadÙ%y7’d.datae9á°§e.datafWú©¼f.datag”[ׂÑg.datahÕjÌ›æh.dataiüÔûi.datajSÍ–Íj.datakž»æ%k.datalѯ ÿ:l.datamÁª$,Om.datan€›?5dn.dataoO‡§²yo.datap¶¼«Žp.dataqÍå‘€£q.datarŒÔŠ™·r.datasKBËÖÌs.datat sÐÏát.datauÉ ýäöu.datavˆæý v.datawöÀæ-w.datax·ñý44x.datayxíe³Iy.dataz9Ü~ª^z.data{úSs{.data|»¾H˜ˆ|.data}|( ×}.data~=β~.dataþJ?åÇ.data€¿{$üÜ€.datasÖ©(ñ.data‚2ç²1 ‚.dataƒýû*¶ ƒ.data„¼Ê1¯0 „.data…™„E ….data†>¨Z †.data‡ù>FÒo ‡.dataˆ¸]Ë„ ˆ.data‰{\pà™ ‰.dataŠ:mkù® Š.data‹D¼k)à ‹.dataŒp0Ø Œ.dataÊ‘è·í .dataŽ‹ ó®!Ž.dataHóÞ…!.data ÂÅœ,!.data‘ÎT„ÓA!‘.data’eŸÊV!’.data“L6²ák!“.data” ©ø€!”.data•-+•!•.data–\362ª!–.data—“/®µ¾!—.data˜Òµ¬Ò!˜.data™M˜‡ç!™.datašP|ƒžü!š.data›—êÂÑ"›.dataœÖÛÙÈ&"œ.dataˆôã:".datažT¹ïúO"ž.dataŸº„d"Ÿ.data û¼Ÿw" .data¡4 ‹"¡.data¢u‘‰Ÿ"¢.data£¶Â1¢²"£.data¤÷ó*»Æ"¤.data¥0ekôÚ"¥.data¦qTpíí"¦.data§²]Æ#§.data¨ó6Fß#¨.text©PGç¢})#© .debug$Fªlõ†l©.text«@cz™å3#« =# H# .debug$F¬oSÅ«.text­`‰…øW#­ a# .debug$F®­.text¯P|fÃÉ_ip_ntop¯ .debug$F°¯.text±@ÖI÷Â_ip_ntoa± .debug$F²±.text³`E–#‹_ip_pton³ .debug$F´¡2W³.textµp”/Äo#µ .data¶¸§èy#¶’# ¡# .debug$F·µ.text¸@ÉUÓÿ°#¸ .debug$F¹ÁẸ.textº@>=º#º .bss»Ä#»Ô# .debug$F¼ºã#_octet2hex??_C@_02FK@ff?$AA@??_C@_02PPOD@fe?$AA@??_C@_02FFHE@fd?$AA@??_C@_02JB@fc?$AA@??_C@_02KKAG@fb?$AA@??_C@_02FFLP@fa?$AA@??_C@_02NLH@f9?$AA@??_C@_02KHCA@f8?$AA@??_C@_02KGHN@f7?$AA@??_C@_02MOK@f6?$AA@??_C@_02PDFD@f5?$AA@??_C@_02FJME@f4?$AA@??_C@_02MCB@f3?$AA@??_C@_02KGLG@f2?$AA@??_C@_02FJAP@f1?$AA@??_C@_02PDJI@f0?$AA@??_C@_02DLKF@ef?$AA@??_C@_02MEBM@ee?$AA@??_C@_02GOIL@ed?$AA@??_C@_02DLGO@ec?$AA@??_C@_02JBPJ@eb?$AA@??_C@_02GOEA@ea?$AA@??_C@_02DGEI@e9?$AA@??_C@_02JMNP@e8?$AA@??_C@_02JNIC@e7?$AA@??_C@_02DHBF@e6?$AA@??_C@_02MIKM@e5?$AA@??_C@_02GCDL@e4?$AA@??_C@_02DHNO@e3?$AA@??_C@_02JNEJ@e2?$AA@??_C@_02GCPA@e1?$AA@??_C@_02MIGH@e0?$AA@??_C@_02CNAP@df?$AA@??_C@_02NCLG@de?$AA@??_C@_02HICB@dd?$AA@??_C@_02CNME@dc?$AA@??_C@_02IHFD@db?$AA@??_C@_02HIOK@da?$AA@??_C@_02CAOC@d9?$AA@??_C@_02IKHF@d8?$AA@??_C@_02ILCI@d7?$AA@??_C@_02CBLP@d6?$AA@??_C@_02NOAG@d5?$AA@??_C@_02HEJB@d4?$AA@??_C@_02CBHE@d3?$AA@??_C@_02ILOD@d2?$AA@??_C@_02HEFK@d1?$AA@??_C@_02NOMN@d0?$AA@??_C@_02EMFK@cf?$AA@??_C@_02LDOD@ce?$AA@??_C@_02BJHE@cd?$AA@??_C@_02EMJB@cc?$AA@??_C@_02OGAG@cb?$AA@??_C@_02BJLP@ca?$AA@??_C@_02EBLH@c9?$AA@??_C@_02OLCA@c8?$AA@??_C@_02OKHN@c7?$AA@??_C@_02EAOK@c6?$AA@??_C@_02LPFD@c5?$AA@??_C@_02BFME@c4?$AA@??_C@_02EACB@c3?$AA@??_C@_02OKLG@c2?$AA@??_C@_02BFAP@c1?$AA@??_C@_02LPJI@c0?$AA@??_C@_02FKPA@bf?$AA@??_C@_02KFEJ@be?$AA@??_C@_02PNO@bd?$AA@??_C@_02FKDL@bc?$AA@??_C@_02PAKM@bb?$AA@??_C@_02PBF@ba?$AA@??_C@_02FHBN@b9?$AA@??_C@_02PNIK@b8?$AA@??_C@_02PMNH@b7?$AA@??_C@_02FGEA@b6?$AA@??_C@_02KJPJ@b5?$AA@??_C@_02DGO@b4?$AA@??_C@_02FGIL@b3?$AA@??_C@_02PMBM@b2?$AA@??_C@_02DKF@b1?$AA@??_C@_02KJDC@b0?$AA@??_C@_02GBAP@af?$AA@??_C@_02JOLG@ae?$AA@??_C@_02DECB@ad?$AA@??_C@_02GBME@ac?$AA@??_C@_02MLFD@ab?$AA@??_C@_02DEOK@aa?$AA@??_C@_02GMOC@a9?$AA@??_C@_02MGHF@a8?$AA@??_C@_02MHCI@a7?$AA@??_C@_02GNLP@a6?$AA@??_C@_02JCAG@a5?$AA@??_C@_02DIJB@a4?$AA@??_C@_02GNHE@a3?$AA@??_C@_02MHOD@a2?$AA@??_C@_02DIFK@a1?$AA@??_C@_02JCMN@a0?$AA@??_C@_02BEFH@9f?$AA@??_C@_02OLOO@9e?$AA@??_C@_02EBHJ@9d?$AA@??_C@_02BEJM@9c?$AA@??_C@_02LOAL@9b?$AA@??_C@_02EBLC@9a?$AA@??_C@_02CPN@8f?$AA@??_C@_02PNEE@8e?$AA@??_C@_02FHND@8d?$AA@??_C@_02CDG@8c?$AA@??_C@_02KIKB@8b?$AA@??_C@_02FHBI@8a?$AA@??_C@_02NGPM@7f?$AA@??_C@_02CJEF@7e?$AA@??_C@_02IDNC@7d?$AA@??_C@_02NGDH@7c?$AA@??_C@_02HMKA@7b?$AA@??_C@_02IDBJ@7a?$AA@??_C@_02MAFG@6f?$AA@??_C@_02DPOP@6e?$AA@??_C@_02JFHI@6d?$AA@??_C@_02MAJN@6c?$AA@??_C@_02GKAK@6b?$AA@??_C@_02JFLD@6a?$AA@??_C@_02PLKJ@5f?$AA@??_C@_02EBA@5e?$AA@??_C@_02KOIH@5d?$AA@??_C@_02PLGC@5c?$AA@??_C@_02FBPF@5b?$AA@??_C@_02KOEM@5a?$AA@??_C@_02ONAD@4f?$AA@??_C@_02BCLK@4e?$AA@??_C@_02LICN@4d?$AA@??_C@_02ONMI@4c?$AA@??_C@_02EHFP@4b?$AA@??_C@_02LIOG@4a?$AA@??_C@_02IMFG@3f?$AA@??_C@_02HDOP@3e?$AA@??_C@_02NJHI@3d?$AA@??_C@_02IMJN@3c?$AA@??_C@_02CGAK@3b?$AA@??_C@_02NJLD@3a?$AA@??_C@_02JKPM@2f?$AA@??_C@_02GFEF@2e?$AA@??_C@_02MPNC@2d?$AA@??_C@_02JKDH@2c?$AA@??_C@_02DAKA@2b?$AA@??_C@_02MPBJ@2a?$AA@??_C@_02KBAD@1f?$AA@??_C@_02FOLK@1e?$AA@??_C@_02PECN@1d?$AA@??_C@_02KBMI@1c?$AA@??_C@_02LFP@1b?$AA@??_C@_02PEOG@1a?$AA@??_C@_02LHKJ@0f?$AA@??_C@_02EIBA@0e?$AA@??_C@_02OCIH@0d?$AA@??_C@_02LHGC@0c?$AA@??_C@_02BNPF@0b?$AA@??_C@_02OCEM@0a?$AA@??_C@_02LKEE@09?$AA@??_C@_02BAND@08?$AA@??_C@_02BBIO@07?$AA@??_C@_02LLBJ@06?$AA@??_C@_02EEKA@05?$AA@??_C@_02OODH@04?$AA@??_C@_02LLNC@03?$AA@??_C@_02BBEF@02?$AA@??_C@_02OOPM@01?$AA@??_C@_02EEGL@00?$AA@_octet2dec??_C@_03MPDC@255?$AA@??_C@_03GFKF@254?$AA@??_C@_03DAEA@253?$AA@??_C@_03JKNH@252?$AA@??_C@_03GFGO@251?$AA@??_C@_03MPPJ@250?$AA@??_C@_03CHHM@249?$AA@??_C@_03INOL@248?$AA@??_C@_03IMLG@247?$AA@??_C@_03CGCB@246?$AA@??_C@_03NJJI@245?$AA@??_C@_03HDAP@244?$AA@??_C@_03CGOK@243?$AA@??_C@_03IMHN@242?$AA@??_C@_03HDME@241?$AA@??_C@_03NJFD@240?$AA@??_C@_03EGCJ@239?$AA@??_C@_03OMLO@238?$AA@??_C@_03ONOD@237?$AA@??_C@_03EHHE@236?$AA@??_C@_03LIMN@235?$AA@??_C@_03BCFK@234?$AA@??_C@_03EHLP@233?$AA@??_C@_03ONCI@232?$AA@??_C@_03BCJB@231?$AA@??_C@_03LIAG@230?$AA@??_C@_03FAID@229?$AA@??_C@_03PKBE@228?$AA@??_C@_03PLEJ@227?$AA@??_C@_03FBNO@226?$AA@??_C@_03KOGH@225?$AA@??_C@_03EPA@224?$AA@??_C@_03FBBF@223?$AA@??_C@_03PLIC@222?$AA@??_C@_03EDL@221?$AA@??_C@_03KOKM@220?$AA@??_C@_03GLHM@219?$AA@??_C@_03MBOL@218?$AA@??_C@_03MALG@217?$AA@??_C@_03GKCB@216?$AA@??_C@_03JFJI@215?$AA@??_C@_03DPAP@214?$AA@??_C@_03GKOK@213?$AA@??_C@_03MAHN@212?$AA@??_C@_03DPME@211?$AA@??_C@_03JFFD@210?$AA@??_C@_03HNNG@209?$AA@??_C@_03NHEB@208?$AA@??_C@_03NGBM@207?$AA@??_C@_03HMIL@206?$AA@??_C@_03IDDC@205?$AA@??_C@_03CJKF@204?$AA@??_C@_03HMEA@203?$AA@??_C@_03NGNH@202?$AA@??_C@_03CJGO@201?$AA@??_C@_03IDPJ@200?$AA@??_C@_03CIBD@199?$AA@??_C@_03ICIE@198?$AA@??_C@_03IDNJ@197?$AA@??_C@_03CJEO@196?$AA@??_C@_03NGPH@195?$AA@??_C@_03HMGA@194?$AA@??_C@_03CJIF@193?$AA@??_C@_03IDBC@192?$AA@??_C@_03HMKL@191?$AA@??_C@_03NGDM@190?$AA@??_C@_03DOLJ@189?$AA@??_C@_03JECO@188?$AA@??_C@_03JFHD@187?$AA@??_C@_03DPOE@186?$AA@??_C@_03MAFN@185?$AA@??_C@_03GKMK@184?$AA@??_C@_03DPCP@183?$AA@??_C@_03JFLI@182?$AA@??_C@_03GKAB@181?$AA@??_C@_03MAJG@180?$AA@??_C@_03OKLI@179?$AA@??_C@_03EACP@178?$AA@??_C@_03EBHC@177?$AA@??_C@_03OLOF@176?$AA@??_C@_03BEFM@175?$AA@??_C@_03LOML@174?$AA@??_C@_03OLCO@173?$AA@??_C@_03EBLJ@172?$AA@??_C@_03LOAA@171?$AA@??_C@_03BEJH@170?$AA@??_C@_03PMBC@169?$AA@??_C@_03FGIF@168?$AA@??_C@_03FHNI@167?$AA@??_C@_03PNEP@166?$AA@??_C@_03CPG@165?$AA@??_C@_03KIGB@164?$AA@??_C@_03PNIE@163?$AA@??_C@_03FHBD@162?$AA@??_C@_03KIKK@161?$AA@??_C@_03CDN@160?$AA@??_C@_03MHON@159?$AA@??_C@_03GNHK@158?$AA@??_C@_03GMCH@157?$AA@??_C@_03MGLA@156?$AA@??_C@_03DJAJ@155?$AA@??_C@_03JDJO@154?$AA@??_C@_03MGHL@153?$AA@??_C@_03GMOM@152?$AA@??_C@_03JDFF@151?$AA@??_C@_03DJMC@150?$AA@??_C@_03NBEH@149?$AA@??_C@_03HLNA@148?$AA@??_C@_03HKIN@147?$AA@??_C@_03NABK@146?$AA@??_C@_03CPKD@145?$AA@??_C@_03IFDE@144?$AA@??_C@_03NANB@143?$AA@??_C@_03HKEG@142?$AA@??_C@_03IFPP@141?$AA@??_C@_03CPGI@140?$AA@??_C@_03LABC@139?$AA@??_C@_03BKIF@138?$AA@??_C@_03BLNI@137?$AA@??_C@_03LBEP@136?$AA@??_C@_03EOPG@135?$AA@??_C@_03OEGB@134?$AA@??_C@_03LBIE@133?$AA@??_C@_03BLBD@132?$AA@??_C@_03OEKK@131?$AA@??_C@_03EODN@130?$AA@??_C@_03KGLI@129?$AA@??_C@_03MCP@128?$AA@??_C@_03NHC@127?$AA@??_C@_03KHOF@126?$AA@??_C@_03FIFM@125?$AA@??_C@_03PCML@124?$AA@??_C@_03KHCO@123?$AA@??_C@_03NLJ@122?$AA@??_C@_03PCAA@121?$AA@??_C@_03FIJH@120?$AA@??_C@_03JNEH@119?$AA@??_C@_03DHNA@118?$AA@??_C@_03DGIN@117?$AA@??_C@_03JMBK@116?$AA@??_C@_03GDKD@115?$AA@??_C@_03MJDE@114?$AA@??_C@_03JMNB@113?$AA@??_C@_03DGEG@112?$AA@??_C@_03MJPP@111?$AA@??_C@_03GDGI@110?$AA@??_C@_03ILON@109?$AA@??_C@_03CBHK@108?$AA@??_C@_03CACH@107?$AA@??_C@_03IKLA@106?$AA@??_C@_03HFAJ@105?$AA@??_C@_03NPJO@104?$AA@??_C@_03IKHL@103?$AA@??_C@_03CAOM@102?$AA@??_C@_03NPFF@101?$AA@??_C@_03HFMC@100?$AA@??_C@_02BJLK@99?$AA@??_C@_02LDCN@98?$AA@??_C@_02LCHA@97?$AA@??_C@_02BIOH@96?$AA@??_C@_02OHFO@95?$AA@??_C@_02ENMJ@94?$AA@??_C@_02BICM@93?$AA@??_C@_02LCLL@92?$AA@??_C@_02ENAC@91?$AA@??_C@_02OHJF@90?$AA@??_C@_02PBA@89?$AA@??_C@_02KFIH@88?$AA@??_C@_02KENK@87?$AA@??_C@_02OEN@86?$AA@??_C@_02PBPE@85?$AA@??_C@_02FLGD@84?$AA@??_C@_02OIG@83?$AA@??_C@_02KEBB@82?$AA@??_C@_02FLKI@81?$AA@??_C@_02PBDP@80?$AA@??_C@_02NLBB@79?$AA@??_C@_02HBIG@78?$AA@??_C@_02HANL@77?$AA@??_C@_02NKEM@76?$AA@??_C@_02CFPF@75?$AA@??_C@_02IPGC@74?$AA@??_C@_02NKIH@73?$AA@??_C@_02HABA@72?$AA@??_C@_02IPKJ@71?$AA@??_C@_02CFDO@70?$AA@??_C@_02MNLL@69?$AA@??_C@_02GHCM@68?$AA@??_C@_02GGHB@67?$AA@??_C@_02MMOG@66?$AA@??_C@_02DDFP@65?$AA@??_C@_02JJMI@64?$AA@??_C@_02MMCN@63?$AA@??_C@_02GGLK@62?$AA@??_C@_02JJAD@61?$AA@??_C@_02DDJE@60?$AA@??_C@_02PGEE@59?$AA@??_C@_02FMND@58?$AA@??_C@_02FNIO@57?$AA@??_C@_02PHBJ@56?$AA@??_C@_02IKA@55?$AA@??_C@_02KCDH@54?$AA@??_C@_02PHNC@53?$AA@??_C@_02FNEF@52?$AA@??_C@_02KCPM@51?$AA@??_C@_02IGL@50?$AA@??_C@_02OAOO@49?$AA@??_C@_02EKHJ@48?$AA@??_C@_02ELCE@47?$AA@??_C@_02OBLD@46?$AA@??_C@_02BOAK@45?$AA@??_C@_02LEJN@44?$AA@??_C@_02OBHI@43?$AA@??_C@_02ELOP@42?$AA@??_C@_02LEFG@41?$AA@??_C@_02BOMB@40?$AA@??_C@_02IBLL@39?$AA@??_C@_02CLCM@38?$AA@??_C@_02CKHB@37?$AA@??_C@_02IAOG@36?$AA@??_C@_02HPFP@35?$AA@??_C@_02NFMI@34?$AA@??_C@_02IACN@33?$AA@??_C@_02CKLK@32?$AA@??_C@_02NFAD@31?$AA@??_C@_02HPJE@30?$AA@??_C@_02JHBB@29?$AA@??_C@_02DNIG@28?$AA@??_C@_02DMNL@27?$AA@??_C@_02JGEM@26?$AA@??_C@_02GJPF@25?$AA@??_C@_02MDGC@24?$AA@??_C@_02JGIH@23?$AA@??_C@_02DMBA@22?$AA@??_C@_02MDKJ@21?$AA@??_C@_02GJDO@20?$AA@??_C@_02KMOO@19?$AA@??_C@_02GHJ@18?$AA@??_C@_02HCE@17?$AA@??_C@_02KNLD@16?$AA@??_C@_02FCAK@15?$AA@??_C@_02PIJN@14?$AA@??_C@_02KNHI@13?$AA@??_C@_02HOP@12?$AA@??_C@_02PIFG@11?$AA@??_C@_02FCMB@10?$AA@??_C@_01FLP@9?$AA@??_C@_01KPCI@8?$AA@??_C@_01KOHF@7?$AA@??_C@_01EOC@6?$AA@??_C@_01PLFL@5?$AA@??_C@_01FBMM@4?$AA@??_C@_01ECJ@3?$AA@??_C@_01KOLO@2?$AA@??_C@_01FBAH@1?$AA@??_C@_01PLJA@0?$AA@_eth_ntop_eth_ntoa_addr_ntoa__imp__memmove_eth_pton__imp__strtol_ip6_ntop??_C@_03CJF@?$CFx?3?$AA@__imp__ntohs@4__imp__sprintf_ip6_ntoa_ip6_pton??_C@_00A@?$AA@__imp__htons@4 snort-2.9.15.1/src/win32/WIN32-Libraries/.cvswrappers0000444000175200017520000000001513571422610016661 00000000000000*.lib -k 'b' snort-2.9.15.1/src/win32/WIN32-Libraries/Packet.lib0000444000175200017520000002074213571422610016211 00000000000000! / 1305905731 0 1780 ` Crz°ÔÔ88ØØFFBBääþþttffRRnn´´!!úúff ” ”ºº $ $¬¬JJŠŠ!t!tøøˆˆ°°ÔÔÄÄ__IMPORT_DESCRIPTOR_packet__NULL_IMPORT_DESCRIPTORpacket_NULL_THUNK_DATA_PacketLibraryVersion__imp__PacketLibraryVersion_PacketGetVersion__imp__PacketGetVersion_PacketGetDriverVersion__imp__PacketGetDriverVersion_PacketOpenAdapter__imp__PacketOpenAdapter_PacketSendPacket__imp__PacketSendPacket_PacketSendPackets__imp__PacketSendPackets_PacketAllocatePacket__imp__PacketAllocatePacket_PacketInitPacket__imp__PacketInitPacket_PacketFreePacket__imp__PacketFreePacket_PacketReceivePacket__imp__PacketReceivePacket_PacketCloseAdapter__imp__PacketCloseAdapter_PacketSetHwFilter__imp__PacketSetHwFilter_PacketGetAdapterNames__imp__PacketGetAdapterNames_PacketRequest__imp__PacketRequest_PacketSetBuff__imp__PacketSetBuff_PacketSetBpf__imp__PacketSetBpf_PacketSetSnapLen__imp__PacketSetSnapLen_PacketGetStats__imp__PacketGetStats_PacketGetStatsEx__imp__PacketGetStatsEx_PacketGetNetType__imp__PacketGetNetType_PacketSetReadTimeout__imp__PacketSetReadTimeout_PacketSetMode__imp__PacketSetMode_PacketSetNumWrites__imp__PacketSetNumWrites_PacketGetNetInfoEx__imp__PacketGetNetInfoEx_PacketSetMinToCopy__imp__PacketSetMinToCopy_PacketGetReadEvent__imp__PacketGetReadEvent_PacketStopDriver__imp__PacketStopDriver_PacketSetDumpName__imp__PacketSetDumpName_PacketSetDumpLimits__imp__PacketSetDumpLimits_PacketIsDumpEnded__imp__PacketIsDumpEnded_PacketSetLoopbackBehavior__imp__PacketSetLoopbackBehavior_PacketGetAirPcapHandle__imp__PacketGetAirPcapHandle/ 1305905731 0 1790 ` #rz°Ô8ØFBäþtfRn´!úf” º$ ¬JŠt!øˆ°ÔÄC  # !   "  # !   "_PacketAllocatePacket_PacketCloseAdapter_PacketFreePacket_PacketGetAdapterNames_PacketGetAirPcapHandle_PacketGetDriverVersion_PacketGetNetInfoEx_PacketGetNetType_PacketGetReadEvent_PacketGetStats_PacketGetStatsEx_PacketGetVersion_PacketInitPacket_PacketIsDumpEnded_PacketLibraryVersion_PacketOpenAdapter_PacketReceivePacket_PacketRequest_PacketSendPacket_PacketSendPackets_PacketSetBpf_PacketSetBuff_PacketSetDumpLimits_PacketSetDumpName_PacketSetHwFilter_PacketSetLoopbackBehavior_PacketSetMinToCopy_PacketSetMode_PacketSetNumWrites_PacketSetReadTimeout_PacketSetSnapLen_PacketStopDriver__IMPORT_DESCRIPTOR_packet__NULL_IMPORT_DESCRIPTOR__imp__PacketAllocatePacket__imp__PacketCloseAdapter__imp__PacketFreePacket__imp__PacketGetAdapterNames__imp__PacketGetAirPcapHandle__imp__PacketGetDriverVersion__imp__PacketGetNetInfoEx__imp__PacketGetNetType__imp__PacketGetReadEvent__imp__PacketGetStats__imp__PacketGetStatsEx__imp__PacketGetVersion__imp__PacketInitPacket__imp__PacketIsDumpEnded__imp__PacketLibraryVersion__imp__PacketOpenAdapter__imp__PacketReceivePacket__imp__PacketRequest__imp__PacketSendPacket__imp__PacketSendPackets__imp__PacketSetBpf__imp__PacketSetBuff__imp__PacketSetDumpLimits__imp__PacketSetDumpName__imp__PacketSetHwFilter__imp__PacketSetLoopbackBehavior__imp__PacketSetMinToCopy__imp__PacketSetMode__imp__PacketSetNumWrites__imp__PacketSetReadTimeout__imp__PacketSetSnapLen__imp__PacketStopDriverpacket_NULL_THUNK_DATApacket.dll/ 1305905731 0 715 ` LCŠÖMëà .debug$SAl@B.idata$2­Á@0À.idata$6 ßÁ@ À packet.dll(ÿ Microsoft (R) LINK packet.dll@comp.idÿ ÿÿ.idata$2@Àh.idata$6.idata$4@Àh.idata$5@Àh8P__IMPORT_DESCRIPTOR_packet__NULL_IMPORT_DESCRIPTORpacket_NULL_THUNK_DATA packet.dll/ 1305905731 0 250 ` LCŠÖM¹.debug$SAd@B.idata$3¥@0À packet.dll(ÿ Microsoft (R) LINK@comp.idÿ ÿÿ__NULL_IMPORT_DESCRIPTORpacket.dll/ 1305905731 0 277 ` LCŠÖMÕ.debug$SAŒ@B.idata$5Í@0À.idata$4Ñ@0À packet.dll(ÿ Microsoft (R) LINK@comp.idÿ ÿÿpacket_NULL_THUNK_DATA packet.dll/ 1305905731 0 53 ` ÿÿLCŠÖM!_PacketAllocatePacketpacket.dll packet.dll/ 1305905731 0 51 ` ÿÿLCŠÖM_PacketCloseAdapterpacket.dll packet.dll/ 1305905731 0 49 ` ÿÿLCŠÖM_PacketFreePacketpacket.dll packet.dll/ 1305905731 0 54 ` ÿÿLCŠÖM"_PacketGetAdapterNamespacket.dllpacket.dll/ 1305905731 0 55 ` ÿÿLCŠÖM#_PacketGetAirPcapHandlepacket.dll packet.dll/ 1305905731 0 55 ` ÿÿLCŠÖM#_PacketGetDriverVersionpacket.dll packet.dll/ 1305905731 0 51 ` ÿÿLCŠÖM_PacketGetNetInfoExpacket.dll packet.dll/ 1305905731 0 49 ` ÿÿLCŠÖM_PacketGetNetTypepacket.dll packet.dll/ 1305905731 0 51 ` ÿÿLCŠÖM_PacketGetReadEventpacket.dll packet.dll/ 1305905731 0 47 ` ÿÿLCŠÖM _PacketGetStatspacket.dll packet.dll/ 1305905731 0 49 ` ÿÿLCŠÖM _PacketGetStatsExpacket.dll packet.dll/ 1305905731 0 49 ` ÿÿLCŠÖM _PacketGetVersionpacket.dll packet.dll/ 1305905731 0 49 ` ÿÿLCŠÖM _PacketInitPacketpacket.dll packet.dll/ 1305905731 0 50 ` ÿÿLCŠÖM _PacketIsDumpEndedpacket.dllpacket.dll/ 1305905731 0 53 ` ÿÿLCŠÖM!_PacketLibraryVersionpacket.dll packet.dll/ 1305905731 0 50 ` ÿÿLCŠÖM_PacketOpenAdapterpacket.dllpacket.dll/ 1305905731 0 52 ` ÿÿLCŠÖM _PacketReceivePacketpacket.dllpacket.dll/ 1305905731 0 46 ` ÿÿLCŠÖM_PacketRequestpacket.dllpacket.dll/ 1305905731 0 49 ` ÿÿLCŠÖM_PacketSendPacketpacket.dll packet.dll/ 1305905731 0 50 ` ÿÿLCŠÖM_PacketSendPacketspacket.dllpacket.dll/ 1305905731 0 45 ` ÿÿLCŠÖM_PacketSetBpfpacket.dll packet.dll/ 1305905731 0 46 ` ÿÿLCŠÖM_PacketSetBuffpacket.dllpacket.dll/ 1305905731 0 52 ` ÿÿLCŠÖM _PacketSetDumpLimitspacket.dllpacket.dll/ 1305905731 0 50 ` ÿÿLCŠÖM_PacketSetDumpNamepacket.dllpacket.dll/ 1305905731 0 50 ` ÿÿLCŠÖM_PacketSetHwFilterpacket.dllpacket.dll/ 1305905731 0 58 ` ÿÿLCŠÖM&_PacketSetLoopbackBehaviorpacket.dllpacket.dll/ 1305905731 0 51 ` ÿÿLCŠÖM_PacketSetMinToCopypacket.dll packet.dll/ 1305905731 0 46 ` ÿÿLCŠÖM_PacketSetModepacket.dllpacket.dll/ 1305905731 0 51 ` ÿÿLCŠÖM_PacketSetNumWritespacket.dll packet.dll/ 1305905731 0 53 ` ÿÿLCŠÖM!_PacketSetReadTimeoutpacket.dll packet.dll/ 1305905731 0 49 ` ÿÿLCŠÖM_PacketSetSnapLenpacket.dll packet.dll/ 1305905731 0 49 ` ÿÿLCŠÖM_PacketStopDriverpacket.dll snort-2.9.15.1/src/win32/WIN32-Libraries/pcre.lib0000444000175200017520000071674613571422610015753 00000000000000! / 1305905414 0 2359 ` RöªªN"†"†"†€DDDDDDDDDDxxxx5D7Š:b:b@4@4J8LÖLÖLÖLÖLÖQ†Q†Q†Q†Q†Q†Q†Q†Q†a¶h8\ ÈrÌ.Ì.Ì.Ì.Ì.Ì.Ì.Ì.Ì.Ì.Ì.Ì.Ì.Ì.Ì.Ì.Ì.Ì.Ì.Ì.Ì.Ì.Ì.Ì.Ì.Ì.Ì.Ì.Ì.Ì.Ì.Ì.Ì.Ì.˜__pcre_xclass??_C@_0BA@CFFK@8?410?52010?906?925?$AA@_pcre_version__pcre_valid_utf8__pcre_ucd_records__pcre_ucd_stage1__pcre_ucd_stage2__pcre_try_flipped__pcre_OP_lengths__pcre_ucp_gentype__pcre_utf8_table1__pcre_utf8_table1_size__pcre_utf8_table2__pcre_utf8_table3__pcre_utf8_table4__pcre_utt__pcre_utt_names__pcre_utt_size??_C@_0BF@LJPM@failed?5to?5get?5memory?$AA@??_C@_0CH@PLGM@unknown?5or?5incorrect?5option?5bit?$CI@??_C@_0CO@LPHN@argument?5is?5not?5a?5compiled?5regul@_pcre_study_pcre_refcount__pcre_ord2utf8__pcre_is_newline__pcre_was_newline??_C@_0N@LHIN@?2?$CK?$CL?$DP?$HL?$FO?4$?$HM?$CI?$CJ?$FL?$AA@_pcre_maketables_pcre_info_pcre_callout_pcre_free_pcre_malloc_pcre_stack_free_pcre_stack_malloc_pcre_copy_named_substring_pcre_copy_substring_pcre_free_substring_pcre_free_substring_list_pcre_get_named_substring_pcre_get_stringnumber_pcre_get_stringtable_entries_pcre_get_substring_pcre_get_substring_list_pcre_fullinfo_pcre_exec_pcre_dfa_exec_pcre_config??_C@_02IMGK@?2h?$AA@??_C@_02NOIK@?2H?$AA@??_C@_03CMNA@LF?$CJ?$AA@??_C@_03DCAH@CR?$CJ?$AA@??_C@_03HMCP@Q?2E?$AA@??_C@_03JDGE@?$HL0?0?$AA@??_C@_04EHIC@ANY?$CJ?$AA@??_C@_04KOOM@UCP?$CJ?$AA@??_C@_05EEPJ@?2P?$HLL?$HN?$AA@??_C@_05HAOA@UTF8?$CJ?$AA@??_C@_05IOOL@CRLF?$CJ?$AA@??_C@_05OOLL@?2p?$HLL?$HN?$AA@??_C@_06BGAI@DEFINE?$AA@??_C@_06CCDD@?2P?$HLLu?$HN?$AA@??_C@_06CGJJ@?2p?$HLLu?$HN?$AA@??_C@_06OLGE@?2P?$HLLl?$HN?$AA@??_C@_06OPMO@?2p?$HLLl?$HN?$AA@??_C@_06PKBN@?2P?$HLNd?$HN?$AA@??_C@_06POLH@?2p?$HLNd?$HN?$AA@??_C@_07CBC@?2P?$HLXwd?$HN?$AA@??_C@_07DIL@?2p?$HLXps?$HN?$AA@??_C@_07FHAO@?2P?$HLXan?$HN?$AA@??_C@_07HKEL@?2P?$HLXsp?$HN?$AA@??_C@_07LGBG@?2p?$HLXwd?$HN?$AA@??_C@_07LHIP@?2P?$HLXps?$HN?$AA@??_C@_07MOEP@?2p?$HLXsp?$HN?$AA@??_C@_07ODAK@?2p?$HLXan?$HN?$AA@??_C@_08PBHC@ANYCRLF?$CJ?$AA@??_C@_0CF@PBIC@Error?5text?5not?5found?5?$CIplease?5rep@??_C@_0N@CK@BSR_UNICODE?$CJ?$AA@??_C@_0N@JMJK@BSR_ANYCRLF?$CJ?$AA@__pcre_find_bracket_pcre_compile_pcre_compile2__pcre_default_tables / 1305905414 0 2279 ` öªN†"€DxD5Š7b:4@8JÖL†Q¶a8h \rÈ.̘R       ??_C@_02IMGK@?2h?$AA@??_C@_02NOIK@?2H?$AA@??_C@_03CMNA@LF?$CJ?$AA@??_C@_03DCAH@CR?$CJ?$AA@??_C@_03HMCP@Q?2E?$AA@??_C@_03JDGE@?$HL0?0?$AA@??_C@_04EHIC@ANY?$CJ?$AA@??_C@_04KOOM@UCP?$CJ?$AA@??_C@_05EEPJ@?2P?$HLL?$HN?$AA@??_C@_05HAOA@UTF8?$CJ?$AA@??_C@_05IOOL@CRLF?$CJ?$AA@??_C@_05OOLL@?2p?$HLL?$HN?$AA@??_C@_06BGAI@DEFINE?$AA@??_C@_06CCDD@?2P?$HLLu?$HN?$AA@??_C@_06CGJJ@?2p?$HLLu?$HN?$AA@??_C@_06OLGE@?2P?$HLLl?$HN?$AA@??_C@_06OPMO@?2p?$HLLl?$HN?$AA@??_C@_06PKBN@?2P?$HLNd?$HN?$AA@??_C@_06POLH@?2p?$HLNd?$HN?$AA@??_C@_07CBC@?2P?$HLXwd?$HN?$AA@??_C@_07DIL@?2p?$HLXps?$HN?$AA@??_C@_07FHAO@?2P?$HLXan?$HN?$AA@??_C@_07HKEL@?2P?$HLXsp?$HN?$AA@??_C@_07LGBG@?2p?$HLXwd?$HN?$AA@??_C@_07LHIP@?2P?$HLXps?$HN?$AA@??_C@_07MOEP@?2p?$HLXsp?$HN?$AA@??_C@_07ODAK@?2p?$HLXan?$HN?$AA@??_C@_08PBHC@ANYCRLF?$CJ?$AA@??_C@_0BA@CFFK@8?410?52010?906?925?$AA@??_C@_0BF@LJPM@failed?5to?5get?5memory?$AA@??_C@_0CF@PBIC@Error?5text?5not?5found?5?$CIplease?5rep@??_C@_0CH@PLGM@unknown?5or?5incorrect?5option?5bit?$CI@??_C@_0CO@LPHN@argument?5is?5not?5a?5compiled?5regul@??_C@_0N@CK@BSR_UNICODE?$CJ?$AA@??_C@_0N@JMJK@BSR_ANYCRLF?$CJ?$AA@??_C@_0N@LHIN@?2?$CK?$CL?$DP?$HL?$FO?4$?$HM?$CI?$CJ?$FL?$AA@__pcre_OP_lengths__pcre_default_tables__pcre_find_bracket__pcre_is_newline__pcre_ord2utf8__pcre_try_flipped__pcre_ucd_records__pcre_ucd_stage1__pcre_ucd_stage2__pcre_ucp_gentype__pcre_utf8_table1__pcre_utf8_table1_size__pcre_utf8_table2__pcre_utf8_table3__pcre_utf8_table4__pcre_utt__pcre_utt_names__pcre_utt_size__pcre_valid_utf8__pcre_was_newline__pcre_xclass_pcre_callout_pcre_compile_pcre_compile2_pcre_config_pcre_copy_named_substring_pcre_copy_substring_pcre_dfa_exec_pcre_exec_pcre_free_pcre_free_substring_pcre_free_substring_list_pcre_fullinfo_pcre_get_named_substring_pcre_get_stringnumber_pcre_get_stringtable_entries_pcre_get_substring_pcre_get_substring_list_pcre_info_pcre_maketables_pcre_malloc_pcre_refcount_pcre_stack_free_pcre_stack_malloc_pcre_study_pcre_version // 1305905414 0 538 ` .\Release\pcre_xclass.obj.\Release\pcre_version.obj.\Release\pcre_valid_utf8.obj.\Release\pcre_ucd.obj.\Release\pcre_try_flipped.obj.\Release\pcre_tables.obj.\Release\pcre_study.obj.\Release\pcre_refcount.obj.\Release\pcre_ord2utf8.obj.\Release\pcre_newline.obj.\Release\pcre_maketables.obj.\Release\pcre_info.obj.\Release\pcre_globals.obj.\Release\pcre_get.obj.\Release\pcre_fullinfo.obj.\Release\pcre_exec.obj.\Release\pcre_dfa_exec.obj.\Release\pcre_config.obj.\Release\pcre_compile.obj.\Release\pcre_chartables.obj/0 1305905398 100666 1912 ` LöˆÖMþ.drectve(Œ .text@´ô P`.debug$FäôHB-defaultlib:MSVCRT -defaultlib:OLDNAMES QSU‹l$V‹t$WŠŠÃƒàý‰D$}AöÃt<‹Íºƒá‹ÅÓâ‰T$™ƒâ‹T$ÁøŠL0„Ñt‹L$3À_^…É][”ÀYËl$€ãF„ÛtƒÆ 3ÀŠF‹ø…ÿ„ƒÿ»uQ3ÀŠF=À|8‹È3Òƒá?Š‘‹<• RÑá#øÓç‹Ç‹úJ…ÿ~zŠ+˃â?Óâ ÂFOuñ;è„{ÿÿÿé#ƒÿ…£3ÀŠF‹øÿÀ|6‹Ï3Àƒá?Š‹… @Ñá#×Óâ‹ú‹ÐH…Ò~@Š+˃â?Óâ úFHuñ3ÀŠF=À|=‹È3Òƒá?Š‘‹• RÑá#ØÓã‹Ã‹ÚJ…Û~jŠƒéƒâ?Óâ ÂFMuð‹l$;;èŽÏþÿÿéw‹Å3É™ƒâ‹ÕÁøŠˆÁáâ€yJƒÊ€BÊ3Àf‹M3ÉŠƒùŇKÿ$ƒÿëpŠ@< t<t<t3À3Ƀÿ”Á;ÁëS3Ƀÿ¸”Á;ÁëB3Ò3ÉŠP3ÀŠF;•”Á3Òƒÿ”Â;Êë ŠNŠX3ÒëŠNŠ3Ò:Ë”Â3Àƒÿ”À;Єþÿÿé¨3ÉŠH‹ƒøtLƒøtG3ÀëH3ÉŠH9t5ƒý t0ƒý t+ƒý t&ƒý t!3Àë"3ÉŠH9tƒý t ƒý tƒý ëÓ¸3Òƒÿ”Â;„Œýÿÿë43ÉŠH‹ƒøtƒøt ƒý_t3Àë¸3Òƒÿ”Â;„VýÿÿƒÆ3ÀŠF‹ø…ÿ…sýÿÿ‹D$_^][YÃ_^]3À[YËÿš¡÷þ9@“¯½ÊVp–Ê $(,0 4 8 < @ .fileþÿgD:\temp\PCRE\pcre-8.10\pcre_xclass.c@comp.id6& ÿÿ.drectve(Ún@A.text@:ûÌâ $L2237Â$L2235Ž$L2233h$L2231N$L2229-$L2227#$L2225$L2223Ó$L2221Î$L2285%8J\o.debug$F‚__pcre_xclass__pcre_ucp_gentype__pcre_ucd_records__pcre_ucd_stage2__pcre_ucd_stage1__pcre_utf8_table3__pcre_utf8_table4/26 1305905398 100666 616 ` LöˆÖM .drectve(´ .textÜì P`.dataö@0À.debug$FHB-defaultlib:MSVCRT -defaultlib:OLDNAMES ¸Ã 8.10 2010-06-25 .fileþÿgD:\temp\PCRE\pcre-8.10\pcre_version.c@comp.id6& ÿÿ.drectve(/üŒ¡.textj¶  .data'©9.debug$F:_pcre_version??_C@_0BA@CFFK@8?410?52010?906?925?$AA@/53 1305905398 100666 763 ` LöˆÖMè .drectve(Œ .text´Ä P`.debug$FÎÞHB-defaultlib:MSVCRT -defaultlib:OLDNAMES SU‹l$VW‹|$…í}Š‹Ç„ÉtŠH@„Éuø+Ç‹è‹ÅM…À‹÷޼3ÉŠù€Œ ùÀŒ¨‹Ñ3Àƒâ?Š‚‹Ð;ꌑƒúˆŠF+êFŠØ€ãÀ€û€ux‹úOtVOt!Ou8ùðu¨0tjë*ùô`u J…Ò~ŠNF€áÀ€ù€u-J…ÒïëöÁ>t!‹|$F‹ÕM…ÒDÿÿÿ_^]ƒÈÿ[ËÆ+Ç_^][ËL$‹Æ_^]+Á[ÃV   .fileþÿgD:\temp\PCRE\pcre-8.10\pcre_valid_utf8.c@comp.id6& ÿÿ.drectve(¨ÈX.text5î .debug$F)__pcre_valid_utf8__pcre_utf8_table4 /83 1305905398 100666 57277 ` LöˆÖM¼Þ .drectve(d .rdata0ÞŒ@@@-defaultlib:MSVCRT -defaultlib:OLDNAMES        !  !àÿÿÿ !    ç !y! !ÿÿÿÿ! 9ÿÿÿ!ÿÿÿ! ‡ÿÿÿ!Ôþÿÿ!Ã! Ò! Î! Í! O! Ê! Ë! Ï!a! Ó! Ñ!£! Õ!‚! Ö! Ú! Ù! Û!!8! !ÿÿÿÿ!þÿÿÿ!±ÿÿÿ! Ÿÿÿÿ! Èÿÿÿ! ~ÿÿÿ! +*! ]ÿÿÿ! (*!?*! =ÿÿÿ! E! G!*!*!*!.ÿÿÿ!2ÿÿÿ!3ÿÿÿ!6ÿÿÿ!5ÿÿÿ!1ÿÿÿ!/ÿÿÿ!-ÿÿÿ!÷)!ý)!+ÿÿÿ!*ÿÿÿ!ç)!&ÿÿÿ!»ÿÿÿ!'ÿÿÿ!¹ÿÿÿ!%ÿÿÿ!   T ÿÿÿÿ ‚ & % @ ? ÚÿÿÿÛÿÿÿàÿÿÿáÿÿÿÀÿÿÿÁÿÿÿ ÂÿÿÿÇÿÿÿ ÑÿÿÿÊÿÿÿøÿÿÿ  ÿÿÿÿªÿÿÿ°ÿÿÿ Äÿÿÿ ÿÿÿ ùÿÿÿ ~ÿÿÿ P àÿÿÿ °ÿÿÿ  ÿÿÿÿ   ñÿÿÿ 0Ðÿÿÿ    1111 77 ? ?? ???YY YY            + + ++ +5 55 5 5556 66 6 66   $ $$ $ $$/ // /88 888   9999 9 9999 && & & && ` ((((--22   33    %%% %% %%"" " """ 4'' ' '  ZZ Z Z ZZ= = == ==K K KK EE E EE H HHH   !Š!æ!Åÿÿÿ! Aâÿÿ øÿÿÿJVd€p~øÿÿÿ  ¶ÿÿÿ÷ÿÿÿÛãÿÿ ªÿÿÿ œÿÿÿ ÿÿÿ €ÿÿÿ ‚ÿÿÿ    £âÿÿ! Aßÿÿ! ºßÿÿ! !äÿÿÿ!!ðÿÿÿ!  æÿÿÿ 0Ðÿÿÿ! Öÿÿ! ñÿÿ! Öÿÿ!ÕÕÿÿ!ØÕÿÿ! äÕÿÿ! Öÿÿ! áÕÿÿ! âÕÿÿ! ÁÕÿÿ     ãÿÿ::<<<UUULLLL  NNN N! üuÿÿ00 0 0@@J JJ JJ D DD DII I IS S SSSS CC C C C&[[ [[VV V VV  #FB));;*** ( Øÿÿÿ.,, PPPAAAGG WWWMMRRQQXT T TTT>>>O   !""#$%&'((()*+,-./0123456789:;<=>?@AABCDEFGHIJKLLAMAANOPQRSTUVWXYZ[\]F^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^_^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^`abbbbbbbbcddefghijklmno"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""pqqqqqqqqqqqqqqqqrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr^^stuvwwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽŽŽŽŽŽ‘‘‘‘‘‘‘‘’F“”•–—˜™š›œžŸ ¡¢£¤^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^¥^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^¦^^^^§¨©ªrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr«rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr«            !"#$%&$'()***++,-.----/01/01/012/0134567899:;<=>?@ABBCDBEFGHGIJKLMMMNOOPQ-RRRRRRRRRSSSSSSSSS SSSSSSSSSSSS RRRRR S S TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTUTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTVWVWSXVWYYZ[[[YYYYYX \]]]Y^Y__`aaaaaaaaaaaaaaaaaYaaaaaaaaabccc`dddddddddddddddddedddddddddfgghijkkklmnVWVWVWVWVWopopopopopopopqrs`tuvVWwVW`xxxyyyyyyyyyyyyyyyyzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{||||||||||||||||}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~€€TT€}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~‚}~}~}~}~}~}~}~ƒ}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~YYYYYYYYYYY„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„YY…††††††Y‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡ˆY‰YYYYYYŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ‹ŠŒŠŠŒŠŠŒŠYYYYYYYYYYYYYŒŒYYYYYYYYYYYYYŽŽŽ‘‘’’’’’’’’’’’YYY“““““““““““““““““““““““““““““““S““““““““““TTTTTTTTTTT’’’’’’’’’Y““T““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““’’’’’’’”’’’’’’••’’‘’’’’““––––––––––“““‘‘“——————————————Y˜™š™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™šššššššššššššššššššššššššššYY™™™““““““““““““““““““““““““““““““““““““““““““““““““››››››››››››››››››››››››››››››››››››››œœœœœœœœœœœ›YYYYYYYYYYYYYYžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸ  ¡¢¢¢ YYYYY££££££££££££££££££££££¤¤¤¤¥¤¤¤¤¤¤¤¤¤¥¤¤¤¥¤¤¤¤¤YY¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY§§§¨©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©YY§©¨¨¨§§§§§§§§¨¨¨¨§¨Y©TT§§§YY©©©©©©©©©©§§ªªªªªªªªªª«©YYYYYY©©©©©©©Y¬­­Y®®®®®®®®YY®®YY®®®®®®®®®®®®®®®®®®®®®®Y®®®®®®®Y®YYY®®®®YY¬®­­­¬¬¬¬YY­­YY­­¬®YYYYYYYY­YYYY®®Y®®®¬¬YY¯¯¯¯¯¯¯¯¯¯®®°°±±±±±±²°YYYYY³³´YµµµµµµYYYYµµYYµµµµµµµµµµµµµµµµµµµµµµYµµµµµµµYµµYµµYµµYY³Y´´´³³YYYY³³YY³³³YYY³YYYYYYYµµµµYµYYYYYYY¶¶¶¶¶¶¶¶¶¶³³µµµ³YYYYYYYYYYY··¸Y¹¹¹¹¹¹¹¹¹Y¹¹¹Y¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹Y¹¹¹¹¹¹¹Y¹¹Y¹¹¹¹¹YY·¹¸¸¸·····Y··¸Y¸¸·YY¹YYYYYYYYYYYYYYY¹¹··YYººººººººººY»YYYYYYYYYYYYYYY¼½½Y¾¾¾¾¾¾¾¾YY¾¾YY¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾Y¾¾¾¾¾¾¾Y¾¾Y¾¾¾¾¾YY¼¾½¼½¼¼¼¼YY½½YY½½¼YYYYYYYY¼½YYYY¾¾Y¾¾¾¼¼YY¿¿¿¿¿¿¿¿¿¿À¾YYYYYYYYYYYYYYYYÁÂYÂÂÂÂÂÂYYYÂÂÂYÂÂÂÂYYYÂÂYÂYÂÂYYYÂÂYYYÂÂÂYYYÂÂÂÂÂÂÂÂÂÂÂÂYYYYÃÃÁÃÃYYYÃÃÃYÃÃÃÁYYÂYYYYYYÃYYYYYYYYYYYYYYÄÄÄÄÄÄÄÄÄÄÅÅÅÆÆÆÆÆÆÇÆYYYYYYÈÈÈYÉÉÉÉÉÉÉÉYÉÉÉYÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉYÉÉÉÉÉÉÉÉÉÉYÉÉÉÉÉYYYÉÊÊÊÈÈÈÈYÊÊÊYÊÊÊÊYYYYYYYÊÊYÉÉYYYYYYÉÉÊÊYYËËËËËËËËËËYYYYYYYYÌÌÌÌÌÌÌÍYYÎÎYÏÏÏÏÏÏÏÏYÏÏÏYÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏYÏÏÏÏÏÏÏÏÏÏYÏÏÏÏÏYYÐÏÎÐÎÎÎÎÎYÐÎÎYÎÎÐÐYYYYYYYÎÎYYYYYYYÏYÏÏÐÐYYÑÑÑÑÑÑÑÑÑÑY YYYYYYYYYYYYYYYÒÒYÓÓÓÓÓÓÓÓYÓÓÓYÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓYÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓYYYÓÒÒÒÔÔÔÔYÒÒÒYÒÒÒÔYYYYYYYYYÒYYYYYYYYÓÓÔÔYYÕÕÕÕÕÕÕÕÕÕÖÖÖÖÖÖYYY×ÓÓÓÓÓÓYYØØYÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙYYYÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙYÙÙÙÙÙÙÙÙÙYÙYYÙÙÙÙÙÙÙYYYÚYYYYØØØÚÚÚYÚYØØØØØØØØYYYYYYYYYYYYYYYYYYØØÛYYYYYYYYYYYYÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÜÜÝÝÝÝÝÝÝYYYYÜÜÜÜÜÜÞÝÝÝÝÝÝÝÝßààààààààààßßYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYááYáYYááYáYYáYYYYYYááááYáááááááYáááYáYáYYááYááááâááââââââYââáYYáááááYãYââââââYYääääääääääYYááYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYåæææçççççççççççççççæææææèèææææææééééééééééêêêêêêêêêêæèæèæèëìëìííååååååååYååååååååååååååååååååååååååååååååååååYYYYèèèèèèèèèèèèèèíèèèèèçèèååååYYYYèèèèèèèèYèèèèèèèèèèèèèèèèèèèèèèèèèèèèèèèèèèèèYææææææææèææææææYææççççç YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîïïððððïððððððïððïïððîññññññññññòòòòòòîîîîîîïïððîîîîðððîïïïîîïïïïïïïîîîððððîîîîîîîîîîîîîðïïððïïïïïïðîïññññññññññïïïðóóôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôYYYYYYYYYYõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõöYYY÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷øøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøYøøøøYYøøøøøøøYøYøøøøYYøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøYøøøøYYøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøYøøøøYYøøøøøøøYøYøøøøYYøøøøøøøøøøøøøøøYøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøYøøøøYYøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøYYYYùúûûûûûûûûüüüüüüüüüüüüüüüüüüüüYYYøøøøøøøøøøøøøøøøúúúúúúúúúúYYYYYYýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýYYYYYYYYYYYþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY                     YYYYYYYYY                    YYYYYYYYYYYY             Y   YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿYYYYYYYYYYYYY   !!!!  !!!YYYY!! !!!!!!   YYYY"YYY##$$$$$$$$$$%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%YY%%%%%YYYYYYYYYYY&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&YYYY'''''''''''''''''&&&&&&&''YYYYYY(((((((((((YYY))********************************+++++++++++++++++++++++,,---YY../////////////////////////////////////////////////////0101111111Y10100111111110000001111111111YY12222222222YYYYYY2222222222YYYYYY33333334333333YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY5555677777777777777777777777777777777777777777777777565555565666665667777777YYYY88888888889999999::::::::::555555555:::::::::YYY;;<==============================<;;;;<<;;<YYY==>>>>>>>>>>YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY????????????????????????????????????@@@@@@@@AAAAAAAA@@AAYYYBBBBBCCCCCCCCCCYYY???DDDDDDDDDDEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEFFFFFFGGYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYTTTTTTTTTTTTTTTTHTTTTTTTIIIITIIIIHYYYYYYYYYYYYY`````JRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRZZZZZ`````KLMRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRZTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTYYYYYYYYYYYYYYYYYYYYYYTTTNOPPPPPPPPQQQQQQQQPPPPPPYYQQQQQQYYPPPPPPPPQQQQQQQQPPPPPPPPQQQQQQQQPPPPPPYYQQQQQQYY`P`P`P`PYQYQYQYQPPPPPPPPQQQQQQQQRRSSSSTTUUVVWWYYPPPPPPPPXXXXXXXXPPPPPPPPXXXXXXXXPPPPPPPPXXXXXXXXPP`Y`Y``QQZZ[X\XXX`Y`Y``]]]][XXXPP``YY``QQ^^YXXXPP```s``QQ__wXXXYY`Y`Y````aa[XXYbbcd  YYYYYRYYRYRRRRRYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYTTTTTTTTTTTTTeeeeTeeeTTTTTTTTTTTTYYYYYYYYYYYYYYY f f gfffggfffg f fffff f h f ijff gffkfgIIIIg ggfffgggg  l mmmmmmmmmmmmmmmmnnnnnnnnnnnnnnnnoooooooYYYYYY                YYYYYYYYYYYYYYYYYYYYYYY YYYYYYYYYYYYYYYYYYYYYYYYY YYYYYYYYYYYYYYYYYYYYY ppppppppppppppppppppppppppqqqqqqqqqqqqqqqqqqqqqqqqqq     Y Y YYYY Y Y YY Y Y Y YYY YY  YYY Y YYYYYrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr  YYY YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYsssssssssssssssssssssssssssssssssssssssssssssssYtttttttttttttttttttttttttttttttttttttttttttttttYuvwxyz{|}R~~opopopopopopopopopopopopopopopopopopopopopopopopopopopopopopopopopopopopopopopopopopopopopopopopopop€€€€€€opopYYYYYYY‚‚‚‚ƒ‚‚„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„„YYYYYYYYYY………………………………………………………………………………………………………………………………………………YYYYYYYYY†YYYYYYYYYYYYYYYYøøøøøøøøøøøøøøøøøøøøøøøYYYYYYYYYøøøøøøøYøøøøøøøYøøøøøøøYøøøøøøøYøøøøøøøYøøøøøøøYøøøøøøøYøøøøøøøY€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€SYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡Y‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡YYYYYYYYYYYY‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡YYYYYYYYYYYYYYYYYYYYYYYYYY YYYY ˆI‰  ‰‰‰‰‰‰‰‰‰TTTTTTSSSSS ‰‰‰ˆI YŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠYYTT ‹‹ŠŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒSŒYYYYYŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽYYY÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷Y  ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽYYYYYYYY YYYYYYYYYYYYŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒY    Y ‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘YYYYYYYYYY ‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY’’’’’’’’’’’’’’’’’’’’’“’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’YYY”””””””””””””””””””””””””””””””””””””””””””””””””””””””YYYYYYYYY••••••••••••••••••••••••••••••••••••••••––––––——˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜™ššš˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜››››››››››˜˜YYYYYYYYYYYYYYYYYYYY}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~}~YY}~}~}~}~}~}~œ€YYYYYYYY€€K}~}~}~}~}~}~}~}~}~}~}~}~YYYYYYYYžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸ  ¡¡¡¡¡¡YYYYYYYY SSSSSSSSS R¢S YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY-----££¤£££¤££££¤£££££££££££££££££££££££¥¥¤¤¥¦¦¦¦YYYY  YYYYYY§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§¨¨¨¨YYYYYYYY©©ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª©©©©©©©©©©©©©©©©«YYYYYYYYY¬¬­­­­­­­­­­YYYYYY§§§§§§§§§§§§§§§§§§©©©©©©®®®©YYYY¯¯¯¯¯¯¯¯¯¯°°°°°°°°°°°°°°°°°°°°°°°°°°°°±±±±±±±±²²³³³³³³³³³³³³³³³³³³³³³³³´´´´´´´´´´´µµYYYYYYYYYYY¶÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷YYY···¸¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹·¸¸····¸¸·¸¸¸¸ºººººººººººººY»¼¼¼¼¼¼¼¼¼¼YYYYººYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½¾¾¾¾¾¾¿¿¾¾¿¿¾¾YYYYYYYYY½½½¾½½½½½½½½¾¿YYÀÀÀÀÀÀÀÀÀÀYYÁÁÁÁîîîîîîîîîîîîîîîîÂîîîîîîóóóîïYYYYÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÄÃÄÄÄÃÃÄÄÃÃÃÃÃÄÄÃÄÃYYYYYYYYYYYYYYYYYYYYYYYYÃÃÅÆÆYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÈÈÉÈÈÉÈÈÊÈÉYYËËËËËËËËËËYYYYYY÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷YYYYYYYYYYYY÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷YYYY÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷YYYYÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘YY‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘YY‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYˆˆˆˆˆYYYYYŠÎYYYYY““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY“““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““YYYYYYYYYYYYYYYY““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““YY““““““““““““““““““““““““““““““““““““““““““““““““““““““YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY““““““““““““ YYTTTTTTTTTTTTTTTTYYYYYYTTTTTTTYYYYYYYYY  YYYYYY“““““Y“““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““““YYY  ŒŒŒŒŒŒŒŒŒŒSŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒSS÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷YYY÷÷÷÷÷÷YY÷÷÷÷÷÷YY÷÷÷÷÷÷YY÷÷÷YYY Y  YYYYYYYYYY YYÏÏÏÏÏÏÏÏÏÏÏÏYÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏYÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏYÏÏYÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏYYÏÏÏÏÏÏÏÏÏÏÏÏÏÏYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏÏYYYYY YYYYYYY ÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÑÑÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÑYYYYY YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY TYYÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓYYYÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕYÖÖÖÖYYYYYYYYYYYY××××××××××××××××ר×××××××רYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙYÚÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛYYYYÛÛÛÛÛÛÛÛÜÝÝÝÝÝYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞÞßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßààààààààààààààààààààààààààààààààààààààààààààààààááááááááááááááááááááááááááááááYYââââââââââYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYããããããYYãYããããããããããããããããããããããããããããããããããããããããããããYããYYYãYYãääääääääääääääääääääääYåææææææææYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYççççççççççççççççççççççèèèèèèYYYéêêêêêêêêêêêêêêêêêêêêêêêêêêYYYYYëYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYìíííYííYYYYYííííììììYìììYìììììììììììììììììììììììììììYYYYíííYYYYíîîîîîîîîYYYYYYYYïïïïïïïïïYYYYYYYðððððððððððððððððððððððððððððññòóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóYYYôôôôôôôõõõõõõõõõõõõõõõõõõõõõõYYöööööööö÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷YYYYYøøøøøøøøùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùùYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúúYûûüýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýüüüûûûûüüûûþþÿþþþþYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY YYYYYYYYYY YY HHTTT HHHHHHTTTTTTTT TTTTTTT TTTT YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY YYYYYYYYYYYYYYYYYYYYYYYffffffffffffffffffffffffffggggggggggggggggggggggggggffffffffffffffffffffffffffgggggggYggggggggggggggggggffffffffffffffffffffffffffggggggggggggggggggggggggggfYffYYfYYffYYffffYffffffffggggYgYgggggggYgggggggggggffffffffffffffffffffffffffggggggggggggggggggggggggggffYffffYYffffffffYfffffffYggggggggggggggggggggggggggffYffffYfffffYfYYYfffffffYggggggggggggggggggggggggggffffffffffffffffffffffffffggggggggggggggggggggggggggffffffffffffffffffffffffffggggggggggggggggggggggggggffffffffffffffffffffffffffggggggggggggggggggggggggggffffffffffffffffffffffffffggggggggggggggggggggggggggffffffffffffffffffffffffffggggggggggggggggggggggggggffffffffffffffffffffffffffggggggggggggggggggggggggggggYYfffffffffffffffffffffffffgggggggggggggggggggggggggggggggfffffffffffffffffffffffffgggggggggggggggggggggggggggggggfffffffffffffffffffffffffgggggggggggggggggggggggggggggggfffffffffffffffffffffffffgggggggggggggggggggggggggggggggfffffffffffffffffffffffffgggggggggggggggggggggggggggggggfgYY YYYY YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY YY YYYYYYYYYYY Y YY YYY YYY YYYYYYYY YYYYYYY YYYYYYYYYYYYYYYYYYYYYYYYY Y YY YYYYYYYYYY YY YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY YYYYYYYYYYYYYY YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTYYYYYYYYYYYYYYYYÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍYY.fileþÿgD:\temp\PCRE\pcre-8.10\pcre_ucd.c@comp.id6& ÿÿ.drectve(ã+çÁ.rdata0Þ¯ëð020(;__pcre_ucd_stage2__pcre_ucd_stage1__pcre_ucd_records /106 1305905398 100666 1159 ` LöˆÖM4.drectve(Ü .text04 P`.debug$FÀÐHB.text@Ú P`.debug$F*HB-defaultlib:MSVCRT -defaultlib:OLDNAMES S‹\$j‹PèƒÄ=ERCPt3À[ÃU‹l$VW¹ ‹ó‹ýjó¥‹KQè‰E‹SjRè‰E3Àf‹C jPè3Éf‰E f‹KjQè3Òf‰Ef‹SjRèf‰E3Àf‹CjPè3Éf‰Ef‹KjQè3Òf‰Ef‹SjRèf‰EƒÄ@3Àf‹CjPè3Éf‰Ef‹KjQè‹\$,ƒÄ…Ûf‰Et<‹|$ ¹ ‹ójó¥‹Rè‹t$(j‰‹CPè‰F‹K(jQèƒÄ‰F(_‹Å^][à 6DUgy‹¯ÄÖü , ƒ|$u ‹D$3ÉŠÌŠè‹ÁËL$‹Á‹Ñ%ÿÁâ ‹ÑâÿÁé ÑÁàÁê ÂÃ<.fileþÿgD:\temp\PCRE\pcre-8.10\pcre_try_flipped.c@comp.id6& ÿÿ.drectve(.text04£ .debug$F.text@å½0 .debug$F!__pcre_try_flipped_byteflip /137 1305905398 100666 2807 ` LöˆÖMè.drectve(d .rdata\Œ@0@-defaultlib:MSVCRT -defaultlib:OLDNAMES !!ÿÿÿÿÿÿÿÿÿÿÿÀàðøüÿAnyArabicArmenianAvestanBalineseBamumBengaliBopomofoBrailleBugineseBuhidCCanadian_AboriginalCarianCcCfChamCherokeeCnCoCommonCopticCsCuneiformCypriotCyrillicDeseretDevanagariEgyptian_HieroglyphsEthiopicGeorgianGlagoliticGothicGreekGujaratiGurmukhiHanHangulHanunooHebrewHiraganaImperial_AramaicInheritedInscriptional_PahlaviInscriptional_ParthianJavaneseKaithiKannadaKatakanaKayah_LiKharoshthiKhmerLL&LaoLatinLepchaLimbuLinear_BLisuLlLmLoLtLuLycianLydianMMalayalamMcMeMeetei_MayekMnMongolianMyanmarNNdNew_Tai_LueNkoNlNoOghamOl_ChikiOld_ItalicOld_PersianOld_South_ArabianOld_TurkicOriyaOsmanyaPPcPdPePfPhags_PaPhoenicianPiPoPsRejangRunicSSamaritanSaurashtraScShavianSinhalaSkSmSoSundaneseSyloti_NagriSyriacTagalogTagbanwaTai_LeTai_ThamTai_VietTamilTeluguThaanaThaiTibetanTifinaghUgariticVaiXanXpsXspXwdYiZZlZpZs M=%N+3<DMSUiBpsvC{„‡Š ‘ ˜›>¥ ­ ¶ ¾ÉOÞçðû%-4=PNXQnR…SŽT•¦D¯ºÀÂÅ É!ÏEÖ"Ü#åUêíðóö ùFG $  V& )%3&;= @'L?PSV(\He)p*|WŽX™+Ÿ,§©¬¯²µ@¾AÉÌÏÒIÙ-ßáYëJöù./  K0)10283A4HZQ[Z5`6g7n8s9{:„;L‘•™¡<¤¦©¬‡.fileþÿgD:\temp\PCRE\pcre-8.10\pcre_tables.c@comp.id6& ÿÿ.drectve(¯³.rdata\»îèþX,|0CÄV¬i”|”x§¹__pcre_utt_size__pcre_utt__pcre_utt_names__pcre_ucp_gentype__pcre_utf8_table4__pcre_utf8_table3__pcre_utf8_table2__pcre_utf8_table1_size__pcre_utf8_table1__pcre_OP_lengths /163 1305905398 100666 8847 ` LöˆÖMÔ.drectve(” .text ¼\ P`.data.¢@0À.dataÐ@0À.data'å@0À.debug$F HB.text&¶ 7 P`.debug$FÜ ì HB.text@ö 6H P`.debug$FHB.text0 P P`.debug$FŒœHB.text ¦F P`.debug$FP`HB.textPj P`.debug$FºÊHB-defaultlib:MSVCRT -defaultlib:OLDNAMES ìˆS‹œ$VW‹¼$ 3ö…Û‰7„_;ERCP…S‹„$œ…ÀtÇ_^3À[ĈÃ3À3Éf‹Cf‹K¯ÁU3íf‹k‹ÓЊCꨅ‹öC …‹C …À‰D$uD$Pj jSè‹D$ ƒÄ‰D$4ˆ@‰L$8‰D$@¹3À|$‰T$<ó«‹CL$4‹ÐQÁê ƒâƒàRPD$ PUè‹ð‹¼$¸ƒÄN÷ÞöF‹KQUUèƒÄ ‹Ø…ö]u…Û|qjHÿƒÄ…ÀuÇ_^[ĈÃPljP…öÇ,ÇBtz¹t$ÇBó¥…Û|‹J_ƒÉ‰Z(^‰J[ĈÃÇ3À_^[ĈÃ<“è@(„ argument is not a compiled regular expressionfailed to get memoryunknown or incorrect option bit(s) set”"ƒì‹D$ SU‹l$VpŠWÁí ƒå3ÿ<_ÇD$ÿÿÿÿ‰|$tTtñƒÆëž‹D$…À| ‹T$…Òu ;ø}‹Ç‰D$€ùT…²ƒÆ3ÿ‰|$émÿÿÿ3ÒŠvŠVò€>Ttñ3ÀŠ3ÉŠˆñéKÿÿÿ3ÒŠò3ÀŠfŠFð€>TtñƒÆé*ÿÿÿGƒÆ…í„ÿÿÿŠFÿ<À‚ÿÿÿƒà?3ÉŠˆñéÿÿÿŠFG<t <¸u¸ðéäþÿÿ3ÒŠvŠVúƒÆ믊F3ÒŠvŠVú<t <¸u¸ðé¯þÿÿƒÆGFé¥þÿÿƒÇFéœþÿÿ…í…»GFéþÿÿŠN€ùt€ùuƒÆ3ÉŠˆñénþÿÿŠN€ùt€ùuƒÆ3ÒŠòéOþÿÿ3ÀŠfŠFt߃Æ!3ÀŠƒÀºƒøwÿ$…3ÉŠnŠNùƒÆéþÿÿGéþÿÿ÷D$$uQ3ÒŠvŠVRUSèƒÄ ‹È…À„ 3ÒŠqŠQÊ€9Ttñ;ðv;ñs 3ÀÇD$ë‹L$$QSPèƒÄ ë3ÀƒÆ3ÉŠƒÁºƒùw)ÿ$3ÉF¯Èùé•ýÿÿ3ÉŠnŠNƒÆ¯Èùé€ýÿÿ¹¯Èùéqýÿÿ3ÀŠfŠFËÈ„‘3ÒŠpŠP€8Ttñ;ñv;ðsÇD$ƒÆé8ýÿÿ‹D$$PSQèƒÄ øƒÆéýÿÿ3ÉŠˆñ…í„ ýÿÿŠFÿ<À‚ýÿÿƒà?3ÒŠòéðüÿÿ3Ò3ÉŠVŠˆÖ4 éÙüÿÿ_^]ƒÈÿ[ƒÄøþÿÿÿ_^][ƒÄËÿ  M;T:tá4ð4+1¾4Ý4$8!t‘ 4<1P4x7|5€,„)ˆ-Œ*2”˜/œ( 0¤'¨.¬%°&´"¸¼6À8Ä9È3ÌÐL+P+T,X,\+`+d#h#lptx|€„ˆŒƒìS‹\$U‹ë÷ÝíV‹t$ƒåðƒÅ WÇD$‰l$‹D$Š€é_öÙɃáþƒÁ|3ÀŠƒÀúƒøp‡‘3ÒŠÿ$•‹D$,‹L$$PSQVWèƒÄ…À„eƒø„33ÒŠwŠWú€?TtñƒÇ맃Çë¢3ÀŠgŠGø€?TtñƒÇ뎊OƒáƒÇ‰L$$é|ÿÿÿ‹T$,‹D$$RSGPVWèƒÄ…À„ÿ3ÉŠoŠOù€?TtñƒÇéGÿÿÿG3ÒŠwŠWú€?TtñƒÇé/ÿÿÿ‹D$,‹L$$SPGQWVèƒÄ‹øéÿÿÿ‹T$,‹D$$SRƒÇPWVèƒÄ‹øéóþÿÿGéíþÿÿƒÇ3ÀŠGƒÀúƒø‡zÿ$…ŠVŠN€Ê€É…ÛˆVˆNtŠNŠF€É ˆNˆFƒÇé£þÿÿŠF ƒÇˆFé“þÿÿŠN€É<…ÛˆNtŠNŠF€É ˆNˆFƒÇémþÿÿŠF ƒÇˆFé]þÿÿ‹L$,QUj@VèƒÄƒÇéDþÿÿ‹T$,RUj@VèƒÄƒÇé+þÿÿ‹D$,PUjVèŠFƒÄ ƒÇˆFé þÿÿ‹L$,3ÛŠ^QUjVèŠVƒÄ€â÷ Ó‹\$(ˆVƒÇéÝýÿÿ‹D$,PUh VèƒÄƒÇéÁýÿÿ‹L$,QUh VèƒÄƒÇé¥ýÿÿ…ÛtŠF ðƒÊÿˆFF‰Vf‰PˆPG‹Æ…Û‹Ïtp+νŠŠ Úˆ@Mu󽀋řƒâÂÁø€<8t;‹Í¸ƒáÓà…Àt+‹ÍåÀ€Í0Áù‹Áƒá™ƒâ²ÁøÆÒ⊠ڃÅ?ˆEý|«ë+ν ŠŠ Úˆ@MuóƒÇ 3ÀŠƒÀºƒø‡Yÿ$…‹l$‹\$(GéÔüÿÿ3À3ÉŠGŠOÁàÁ…/‹l$‹\$(ƒÇé¯üÿÿÇD$éƒÇ‹T$,‹D$$SRGPWVèƒÄéüŠVŠN€Ê€É…ÛˆVˆNtŠNŠF€É ˆNˆFéЀNéÇŠN€É<…ÛˆNtŠNŠF€É ˆNˆF餀N 雋L$,QUj@VèƒÄé…‹T$,RUj@VèƒÄër‹D$,PUjVèŠFƒÄ ˆFëW‹L$,3ÛŠ^QUjVèŠVƒÄ€â÷ ÓˆVë0‹D$,PUh VèƒÄë‹L$,QUh VèƒÄë‹l$‹\$(‹D$3ÒŠpŠP‰D$€8TuéUûÿÿ_^]¸[ƒÄÃ_^]3À[ƒÄËD$_^][ƒÄÃI      IRjYik@Ñ@o=oh\ë~y~Cyn~ŠyXQ®o%~;yN~ny~¥yøIüHGFE DJKdL a$`(M,]0_4^8g<R@SDfHNLCPhTeXc\b`BØYÜXàWäVèUìTðBôBøBüBBZB [BZPP A$A(P,P0O4O8@ƒì3À²SVW‹|$‹\$Š‹ÈÁé4‹ÈƒáÒ⊠ʈ‹L$(…É„¸ƒø†¯3ÀUŠG=Àr=‹È3Òƒá?Š‘‹,•4RÑæ#è‹ÎÓå‹ÊJ…É‹Å~jŠƒîƒâ?‹ÎÓâ ÂGMuî‹L$$]…ÉtSL$ ‹ÐQ3ÉÁꊊ‹ÐÁáƒâÊ3Òf‹M‹ ÕÈQè‹L$ƒÄáÿ‹ÑƒáÁê²Òâ‹Ç_^[ƒÄËL$ …Ét'‹L$$‹Q öt‹I3ÒŠ‹Ê²‹ÁƒáÁèÃÒâG_^[ƒÄÃT1[tŸs³rºqÂp&o‹L$ ƒì3ÀSU‹l$ VW‹|$…É~‹t$ ‹UŠ8Њ2 Úˆ8@;Á|ëƒù tX¾€‹Æ‹Î™ƒâƒá»ÂÓã‹MÁøŠ„Út)D$PVè‹L$ƒÄáÿ‹ÑƒáÁê:²ÒâFþ|­_^][ƒÄÃdp—y‹L$V‹t$3À…ö~%SU‹l$W‹|$‹UŠЊ:öÒ Úˆ@;Æ|é_][ƒþ ^t AƒÉÿ‰‰HÃF~.fileþÿgD:\temp\PCRE\pcre-8.10\pcre_study.c@comp.id6& ÿÿ.drectve(=™¥.text üíS .data.¾!¨?.data:™*²Fr .data'¨«ÆÖŽ.debug$FÒ,Kã.text7HýBöÆ $L2273·$L2286Ý$L2285G$L2283$L2274Æ$L2272¢$L2271•$L2559lÖ $L2256"$L2254 $L2558L$L2247ô$L2246è$L2243É$L2240ª$L2238›$L2237’$L2253Œ$L2252‹$L2235ˆ$L2234b$L2232S$L22316ê$L2229 $L2225ìý$L2223Ù$L2221Ê$L2216™$L2210l$L2209X$L2557x$L2556Ô.debug$F.text @H"s $L2605® $L2574ß $L2388Ò $L2420˜ $L2419‚ $L2418_ $L2417D $L24161 $L2415 $L2412ï $L2409º $L2407Ÿ $L2406œ $L2387 $L2463j $L2462\ $L2613 $L2443µ $L2442™ $L2441} $L2440a $L24394 $L2438 $L2437ú $L2436á $L2433« $L2430l $L2612Ø $L2424T $L2423Q $L2421K $L2405, $L2404 $L2400÷ $L2395 $L2394° $L2391œ $L2389— $L2422’ $L2380] $L2611ø $L2610d .debug$F 3(š" .text 0ʯOý . >Qcu.debug$F  .text  >(Àåˆ .debug$F .textPŸq¬ª— .debug$F©_pcre_study??_C@_0CO@LPHN@argument?5is?5not?5a?5compiled?5regul@??_C@_0BF@LJPM@failed?5to?5get?5memory?$AA@_pcre_malloc_pcre_fullinfo??_C@_0CH@PLGM@unknown?5or?5incorrect?5option?5bit?$CI@_find_minlength__pcre_find_bracket__pcre_utf8_table4__pcre_OP_lengths_set_start_bits_set_table_bit__pcre_ord2utf8__pcre_ucd_records__pcre_ucd_stage2__pcre_ucd_stage1__pcre_utf8_table3_set_type_bits_set_nottype_bits /188 1305905398 100666 521 ` LöˆÖM .drectve(Œ .textP´ P`.debug$FHB-defaultlib:MSVCRT -defaultlib:OLDNAMES ‹T$…Òu¸þÿÿÿËL$V3À‹ñf‹B÷Þ;ð^~ 3Àf‰B%ÿÿÃÁ=ÿÿ~¸ÿÿf‰B%ÿÿÃF .fileþÿgD:\temp\PCRE\pcre-8.10\pcre_refcount.c@comp.id6& ÿÿ.drectve(.textPx¢Z .debug$F_pcre_refcount /216 1305905398 100666 668 ` LöˆÖM<.drectve(Œ .textP´ P`.debug$F"2HB-defaultlib:MSVCRT -defaultlib:OLDNAMES ‹L$V‹53À…öW~º; ~@ƒÂ;Æ|ô‹t$ð…À~‹øŠÑ€â?€Ê€ˆNÁùOu_ Ñ@ˆ^à  C O .fileþÿgD:\temp\PCRE\pcre-8.10\pcre_ord2utf8.c@comp.id6& ÿÿ.drectve(vbw†.textPm:g ':.debug$FR__pcre_ord2utf8__pcre_utf8_table2__pcre_utf8_table1__pcre_utf8_table1_size/244 1305905398 100666 1429 ` LöˆÖMð.drectve(Ü .text@D P`.debug$FXhHB.textPr P`.debug$FÖæHB-defaultlib:MSVCRT -defaultlib:OLDNAMES ‹T$SUV…ÒWtN‹l$3ÀŠE=À|G‹È3Ûƒá?Š™‹û‹4½ Ñá#ðÓæ‹Æ¾;þ|Š.ƒéƒã?Óã ÃF;÷~îë ‹l$3ÀŠEƒ|$uLƒø t3ƒø …º‹T$J;ês ŠE< ¸t¸‹L$ _^]‰¸[ËT$ _^]Ǹ[Ã=…St9ƒø |nƒø ~Ùƒø ud‹D$H;ès ŠE< ¸t¸‹L$ _^]‰¸[ËL$ 3À…Ò•À@_^‰]¸[Ã=( |=) ‹T$ _^]Ǹ[Ã_^]3À[Ã% . 9 ‹T$‹D$SUJV…ÀWtbŠ$À<€u ŠJÿJ€áÀ€ù€tô3ÀŠ=À|G‹È3Ûƒá?Š™‹ë‹<­tmÑæ#ø‹ÎÓç‹Ç¿;ï|Šƒîƒã?‹ÎÓã ÃG;ý~ìë3ÀŠ‹L$_^]ƒù[uAƒø tƒø …¬‹T$¸ÇÃ;T$ v ŠBÿ< ¸t¸‹L$‰¸Ã=…Tt:ƒø t~iƒø d‹T$¸ÇÃ;T$ vÄŠBÿ< ¸t½‹L$¸‰ËL$‹D$3Ò…É•ÂB‰¸Ã=( |=) ‹L$¸ÇÃ3ÀÃ9 B A.fileþÿgD:\temp\PCRE\pcre-8.10\pcre_newline.c@comp.id6& ÿÿ.drectve(„é(.text@ŒKãï ).debug$F.textP·K8< .debug$FO__pcre_is_newline__pcre_utf8_table3__pcre_utf8_table4__pcre_was_newline /271 1305905398 100666 2503 ` LöˆÖM}.drectve(´ .textàܼ) P`.data V@0À.debug$FcsHB-defaultlib:MSVCRT -defaultlib:OLDNAMES Qh@ÿƒÄ‰D$…ÀuYÃSUVW‹=‹è3öVÿ׃ĈEEFþ|í‹3ö¡ƒ8~jVÿƒÄë‹ ‹Šrƒà…ÀVtÿÓëÿ׃ĈEEFþ|¿¹P3À‹ý3ö󫡃8~‹=jVÿ׃Äë‹ ‹=‹Šrƒà…Àt ‹Æ‹Î™ƒâƒá²ÁøÒâŠL(@D(@ ʈ¡ƒ8~ jVÿ׃Äë‹ ‹Šrƒà…Àt ‹Æ‹Î™ƒâƒá²ÁøÒâŠL(`D(` ʈ¡ƒ8~ jVÿ׃Äë‹ ‹Šrƒà…Àt&‹Æ‹Î™ƒâƒá²ÁøÒ⊌(€„(€ ʈ¡ƒ8~ hVÿ׃Äë‹ ‹f‹r%…Àt&‹Æ‹Î™ƒâƒá²ÁøÒ⊌( „(  ʈƒþ_u€«€¡ƒ8~ jVÿ׃Äë‹ ‹Šrƒà…Àt‹Æ‹Î™ƒâƒá²ÁøÅÒ⡃8~ h€Vÿ׃Äë‹ ‹Šr%€…Àt ‹Æ‹Î™ƒâƒá²ÁøÒâŠL( D( ʈ¡ƒ8~ hVÿ׃Äë‹ ‹f‹r%…Àt&‹Æ‹Î™ƒâƒá²ÁøÒ⊌(À„(À ʈ¡ƒ8~ hWVÿ׃Äë‹ ‹f‹r%W…Àt&‹Æ‹Î™ƒâƒá²ÁøÒ⊌(à„(à ʈ¡ƒ8~ jVÿ׃Äë‹ ‹Šrƒà…Àt&‹Æ‹Î™ƒâƒá²ÁøÒ⊌(„( ʈ¡ƒ8~ j Vÿ׃Äë‹ ‹Šrƒà …Àt&‹Æ‹Î™ƒâƒá²ÁøÒ⊌( „(  ʈFþŒìüÿÿ‹=Å@3ö3Ûƒþ t+¡ƒ8~ jVÿ׃Äë‹ ‹Šrƒà…Àt»¡ƒ8~ hVÿ׃Äë‹ ‹f‹r%…ÀtƒÃ¡ƒ8~ jVÿ׃Äë‹ ‹Šrƒà…ÀtƒÃ¡ƒ8~ h€Vÿ׃Äë‹ ‹Šr%€…ÀtƒÃ¡ƒ8~ hVÿ׃Äë‹ ‹f‹r%…Àuƒþ_uƒÃVhÿƒÄ…ÀtÀˆ]EFþŒêþÿÿ‹D$_^][YÃ<CQ\‘œ¬²ãø)>uÓè)\t®ÆLa¦ºÏåý)=Ukƒ  ¦ \*+?{^.$|()[Ò .fileþÿgD:\temp\PCRE\pcre-8.10\pcre_maketables.c@comp.id6& ÿÿ.drectve(§†bü.textà)ç‚Úd  .data Ǧá[#`o “ ¢ ±.debug$F¾_pcre_maketables__imp__strchr??_C@_0N@LHIN@?2?$CK?$CL?$DP?$HL?$FO?4$?$HM?$CI?$CJ?$FL?$AA@__imp___pctype__imp___isctype__imp____mb_cur_max__imp__toupper__imp__tolower_pcre_malloc /301 1305905398 100666 610 ` LöˆÖMh .drectve(Œ .text´D P`.debug$FN^HB-defaultlib:MSVCRT -defaultlib:OLDNAMES ‹D$ƒì(…Àu ¸þÿÿÿƒÄ(Ã8ERCPtjL$jQPèƒÄ…Àu ¸üÿÿÿƒÄ(ËL$0…Ét ‹Pâzü#‰‹T$4…Òt+f‹H öÁt3Éf‹H‰ 3Éf‹H‹ÁƒÄ(ÃáÿÿÁéƒÉþ‰ 3Éf‹H‹ÁƒÄ(Ã'  .fileþÿgD:\temp\PCRE\pcre-8.10\pcre_info.c@comp.id6& ÿÿ.drectve([ .textEß1   .debug$F"_pcre_info__pcre_try_flipped/325 1305905398 100666 1140 ` LöˆÖMô.drectve(, .bss€0À.dataTd@0À.textŒœ P`.debug$F¦¶HB.textÀÐ P`.debug$FÚêHB-defaultlib:MSVCRT -defaultlib:OLDNAMES  ‹D$PÿƒÄËD$PÿYà .fileþÿgD:\temp\PCRE\pcre-8.10\pcre_globals.c@comp.id6& ÿÿ.drectve(ã¼(P.bss.dataˆmÚ¯ #6A.textʯ­N _ .debug$Fék° .textô‹±˜m | .debug$Fˆ_pcre_callout_pcre_stack_free_pcre_stack_malloc_pcre_free_pcre_malloc_LocalPcreMalloc__imp__malloc_LocalPcreFree__imp__free/352 1305905398 100666 4083 ` LöˆÖM¸ ;.drectve(\ .text„„ P`.debug$F¢²HB.textмŒ P`.debug$FªºHB.text`Ä P`.debug$F$4HB.text@>~ P`.debug$F’¢HB.text ¬L P`.debug$F`pHB.text°z*  P`.debug$F4 D HB.textN ^  P`.debug$Fh x HB.textp‚ ò  P`.debug$Fü HB.text@ V  P`.debug$Fj z HB.text„ ”  P`.debug$Fž ® HB-defaultlib:MSVCRT -defaultlib:OLDNAMES ƒì D$SUV‹t$WPjjVèƒÄ…À…¯‹D$ …ÀŽžL$QjjVèƒÄ…À…‰T$Rj PVèƒÄ…Àut‹\$ ‰D$…Û~c‹D$‹t$$Ù+‹è‹D$Ñý‹Í¯L$ÈyŠŠÂ:u„ÀtŠVŠÂ:WuƒÆƒÇ„Àuà3ÀëÀƒØÿ…Àt"~E‰l$ë‹Ý‰\$ ;\$¸ùÿÿÿ_^][ƒÄ Ã3À3ÒŠŠQ_^Áà]Â[ƒÄ à < U òƒìD$SUV‹t$$WPjjVèƒÄ…À…É‹D$…ÀޏL$(QjjVèƒÄ…À…£T$Rj PVèƒÄ…À…Š‹\$‹L$ÇD$Cÿ¯D$(Á…Û‰D$ ~c‹D$‹L$,Ù+‹è‹D$Ñý‹ý¯|$(øwŠŠÂ:u„ÀtŠQŠÂ:VuƒÁƒÆ„Àuà3ÀëÀƒØÿ…Àt"~E‰l$ë‹Ý‰\$;\$¸ùÿÿÿ_^][ƒÄËT$‹ß;ú‰\$‰|$vL‹D$(‹ë+è‹D$,uŠŠË:u„ÉtŠXŠË:^uƒÀƒÆ„Éuà3ÀëÀƒØÿ…Àu ‹Ý;Ú‰\$wºë‹\$‹l$ ;ýsO‹D$(|‹D$,‹÷ŠŠÊ:u„ÉtŠPŠÊ:VuƒÀƒÆ„Éuà3ÀëÀƒØÿ…Àu‹D$‹L$(Áù;ʼnD$r¹‹D$0‹L$4‹T$_^‰‹D$ ]‰[ƒÄà < U Ç‹D$V…À|M;D$}G‹L$ À‹t$‹‹D+ÂH;ñ}¸úÿÿÿ^Ët$‹ÈSò‹T$‹ÙW‹úÁéó¥‹Ëƒáó¤_[Æ^øùÿÿÿ^Ã]‹D$‹L$V‹t$VPQèƒÄ …À~‹T$ ‹L$R‹T$QP‹D$RVPèƒÄ^Ã3<‹D$SUV‹HW÷Áuö@ u‹L$QPèƒÄ_^][ÃT$L$R‹T$QRPè‹ðƒÄ…ö_^][Ë\$‹l$;Ý‹Ów‹|$3É3ÀŠ ŠBÁáȃ<Ï}Ö;Õvæ¾¾K_^Áà]Á[Ã_^]‹Á[à =“SUV‹l$W‹|$¹4?…ö~V‹ÅÑê‹X+ƒÀJLuñQÿƒÄ‰D$…Àu _^]¸úÿÿÿ[ËL$ T¸…ö‰~KFÑè‰D$‹E‹]‹t$+Ø‹Ëð‹Á‹úÁéó¥‹È‹D$ƒáƒÀó¤‹L$‰PüӃʼnD$ÆBI‰L$u¾_^Ç]3À[Ã1#°"‹D$PÿYÃ) (‹D$SVW…À|[;D$}U‹|$4‹\·‹·+ÚCPÿƒÄ…Àu _^¸úÿÿÿ[Ë4·‹T$‹Ëò‹Ñ‹øÁéó¥‹Êƒáó¤‹L$ Æ_^‰‹Ã[Ã_^¸ùÿÿÿ[Ã'#o.‹D$‹L$V‹t$VPQèƒÄ …À~‹T$‹L$ RP‹D$PVQèƒÄ^Ã..73‹D$PÿYÃ) 8.fileþÿgD:\temp\PCRE\pcre-8.10\pcre_get.c@comp.id6& ÿÿ.drectve(2§;.text"£ve  .debug$F.textЕþòÿ* .debug$F.text`£—¾8H .debug$F.text@x-] .debug$F .text  ­Z+x .debug$F ùth¢ .text °,‘å ‡  .debug$F E"3 .textô‹±˜­ Ç.debug$F.textpëù[ÃÒ .debug$F.text@9hrßæ .debug$F.textô‹±˜ .debug$F_pcre_get_stringnumber_pcre_fullinfo_pcre_get_stringtable_entries_pcre_copy_substring_pcre_copy_named_substring_get_first_set_pcre_get_substring_list_pcre_malloc_pcre_free_substring_list_pcre_free_pcre_get_substring_pcre_get_named_substring_pcre_free_substring /375 1305905398 100666 1606 ` LöˆÖMÜ.drectve(Œ .textP´ P`.debug$FÂÒHB-defaultlib:MSVCRT -defaultlib:OLDNAMES ‹D$ƒìTSV3öW…À„ð‹|$p…ÿ„ä‹\$h…Ûtöt‹s8ERCPt,L$4T$ QVRPèƒÄ…Àu _^¸üÿÿÿ[ƒÄTÃ…ött$4‹L$lƒù‡‡ÿ$‹@%zü#‰_^3À[ƒÄTËH3À‰_^[ƒÄTÃ…öu ‰7_^3À[ƒÄTË63À‰7_^[ƒÄTÃ3Òf‹P3À‰_^[ƒÄTÃ3Éf‹H3À‰_^[ƒÄTÃf‹H öÁt3Éf‹H3À‰_^[ƒÄTÃáÿÿÁéƒÉþ3À‰_^[ƒÄTÃ…ötöFt‹CƒÀ‰_^3À[ƒÄTÃ3À‰_^[ƒÄTÃ…ötöFt‹v(3À‰7_^[ƒÄTÃÎÿ3À‰7_^[ƒÄTÃö@ t3Éf‹H3À‰_^[ƒÄTÃÉÿ3À‰_^[ƒÄTÃ3Òf‹P3À‰_^[ƒÄTÃ3Éf‹H3À‰_^[ƒÄTÃ3Òf‹PÐ3À‰_^[ƒÄTÃÇ_^3À[ƒÄTÊ@ öЃà‰_^3À[ƒÄTÊH Áéƒá3À‰_^[ƒÄTÊP Áêƒâ3À‰_^[ƒÄTÃ_^¸ýÿÿÿ[ƒÄTÃ_^¸þÿÿÿ[ƒÄTÃEt°  $(,048<@ D H LP .fileþÿgD:\temp\PCRE\pcre-8.10\pcre_fullinfo.c@comp.id6& ÿÿ.drectve(žô¤­.textPAçRÝ $L2245ä$L2243Ð$L2241½$L2238®$L2235›$L2233Š$L2231y$L2229T$L2226.$L2221$L2219×$L2217Æ$L2215µ$L2212™$L2210‹$L2208x$L2263) .debug$F<_pcre_fullinfo__pcre_default_tables__pcre_try_flipped/403 1305905410 100666 62359 ` L‰ÖM^ß .drectve(T .rdata|@0@.text  Š* P`.debug$F¢²HB.text±¼LÁÌ P`.debug$FDÝTÝHB.text ^ÝþÞ P`.debug$FDßTßHB-defaultlib:MSVCRT -defaultlib:OLDNAMES ìD‹Œ$XƒÈÿ‰D$‰„$Љ„$ä‹„$PSUV‹´$T,‹Œ$hW3ÛUÿ‹þ÷ÁoZâ‰\$0‰œ$艜$ì‰\$,‰\$(‰”$ð‰|$4t_^]¸ýÿÿÿ[ÄDÃ;ó„ý ;Äõ ‹„$p;Ë„$tu;ÃÛ ;Ã}_^]¸ñÿÿÿ[ÄDÃ3À3Éf‹Ff‹NƉL$X‹Œ$\‰D$`¸€–˜3Òf‹V‰D$<‰D$@‹F ;ˉT$\‰\$‰œ$ЉD$t<‹¨t‹Q‰T$¨t‹Q‰T$<¨t‹Q‰T$@¨t ‹Q ‰”$Шt‹A‰D$9\$uÇD$>ERCPtI‹T$Œ$Q„$0RPVè‹øƒÄ;û‰|$4u_^]¸üÿÿÿ[ÄDÃ9\$t Œ$‰L$‹G‹”$l‹È‹œ$` ÊÁéƒáÁ艌$ÜŠO ƒàÁ鉄$ä3Àf‹Gƒá‰Œ$Ø‹È3Àf‹G¯È3Àñf‹G‹Œ$hÆ‹´$d‰œ$ Þ‰„$œ‰Œ$À‰œ$¤‹GÁèƒà‰\$‰„$ˆ‹GÁè ƒà‰D$|‹OÁéƒá‰D$‰Œ$„‹OÁéƒá‰Œ$€‹ÊÁéƒá‰L$t‹ÊÁéƒá‰L$x‹ÊÁé ƒá‰Œ$Œ‹ÊÁéƒá÷‰Œ$t¹ë‹ÊÁéƒá‰Œ$´3ɉŒ$”‰Œ$Ô‰Œ$Ì‹L$‰L$hÁ@‰L$l‹Êá€t-ù€tùt7_^]¸éÿÿÿ[ÄDÃÇ„$˜ë%‹O÷Á€tÁéƒá‰Œ$˜ë Ç„$˜÷Âpu‹Oë‹Êápù0wTtK…Ét@ùt8ù uN¹ ùÿÇD$P~]‹|$4‹ÑÁúÇD$TˆT$dˆL$eëN¹ ëι ëÇù@t"ùPt_^]¸éÿÿÿ[ÄDÃÇD$PëÇD$PëÇD$TˆL$d‹”$l‹Œ$´…ÉtöG t_^]¸óÿÿÿ[ÄDÃ…ÀthöÆ uc‹”$`VRèƒÄ…À|_^]¸öÿÿÿ[ÄDË„$h…À~,;Æ}(3ÀŠEƒø~%Àt=Àt_^]¸õÿÿÿ[ÄDËœ$¤‹G‹´$tƒà¹‰„$ü‹Æ™÷ùf‹O+òf…ÉvV¸VUUUáÿÿ÷î‹ÂÁèÐ;Ê|>tI µQÿƒÄ‰D$D…Àu_^]¸úÿÿÿ[ÄDËœ$¤ÇD$0ë ‹”$p‰T$D 6¸VUUU÷é‹Â3ÉÁèЉt$H‰T$LÇD$pÇ„$¼ÿÿÿÿf‹OD ‹Œ$t;Á‰D$$~‰t$$‹D$D…Àt=‹Ð‹D$$ ²™+ºÑø+Бƒé;ÈrÇÿÿÿÿƒé;Èsó‹t$D‹T$T‹œ$¤ë‹t$D‹T$T‹„$Ü…Àu]öG t73Àf‹G‹ÈÁèƒàáÿƒø‰L$ ‰„$èu3‹T$h3ÀŠ ‹T$T‰D$ ë ‹„$Ø…Àu‹D$…Àt ö@tƒÀ‰D$,öG t63Àf‹G‹|$‹ÈÁèƒàáÿ‰„$ì3ÀŠ„‰Œ$à‰„$ô‹|$…ö‰|$t+‹L$$ Ž;ñs ‹|$D+σÁÁéƒÈÿó«‹œ$¤‹|$‹T$T‹„$ä…À„ä‹D$‹õ…Àt~;ëƒÌ‹D$P…Àt2‹T$‹L$PD$TRPSQVèƒÄ…À…£‹œ$¤‹T$T‹|$ë"‹Ã+Â;ðwŠL$dŠ:Áuƒút{ŠD$eŠN:ÈtpF;÷sŠ€áÀ€ù€uF;÷rñ;órŒëV;ësR‹D$P…Àt#T$TjRSPVèƒÄ…Àu4‹œ$¤‹T$Të"‹Ë+Ê;ñwŠD$dŠ:ÈuƒútŠL$eŠF:ÁtF;ór®‹þ‰|$‹´$l扴$ø…"‹D$ …À|Z‹„$è…Àt,;L$h3ÒŠU3ÀŠ ‹L$ ;Á„íE;ïráéã;ïƒÛ‹D$ 3ÒŠU;ЄÊE;ïrêéÀ‹„$Ø…À„^‹„$ ‹Œ$hÁ;膙‹D$…À„¨;D$P…Àt3;¬$ v`‹T$‹Œ$ D$TR‹T$TPQRUèƒÄ…À…Öë6‹L$T‹„$ ;êr$ŠT$d‹Å+Á8uƒù„­ŠL$eŠP:Ñ„ž‹D$E;胑ŠU€âÀ€ú€u ‹D$E;ès}ëê;l$‚bÿÿÿëo;ïsk‹D$P…Àt,;¬$ vQ‹Œ$ ‹T$PD$TjPQRUèƒÄ…Àu9ë.‹L$T‹„$ ;êrŠT$d‹Å+Á8uƒùtŠL$eŠP:Ñt ‹D$E;èr•€}ÿ up‹D$Pƒøtƒøub;l$s\€} uVEëS‹D$,…ÀtK;ïsG‹T$‹ð3À»ŠE‹ÈƒáÓãÁèŠ0„ØuE…Òt;ïsŠM€áÀ€ù€uE;ïsëî;ïrÆ‹´$ø‹L$…ö‰L$…¼‹„$´…À…­‹D$…Àtö@t ‹P(+Í;Ê‚F‹”$à…ÒŒƒ‹t$‹Æ+Å=è}t‹\$ ‹Œ$ð3À…ÛÀÅ;Áv\‹Œ$ì…Ét&;ƃý‹¼$ô3ÉŠ@;Êt);Ït%;ƃáëé;ƃ×3ÉŠ@;Êt ;ƃÆëíH;ƃ»‰„$ð‹”$ü‹Œ$œjjjD$DRPjjUQU‰¬$Љ¬$ØÇD$`è‹ø‹„$¼ƒÄ(…Àt‹D$(…Àu ‹”$°‰T$(ÿüÿÿ)tÿüÿÿ„?ÿüÿÿ…7ë)‹´$¨;õtë>ÿüÿÿŒÿüÿÿ~…ÿ… ‹D$u…Àt‹D$;ðsŠ€áÀ€ù€uF;ðrñ‹„$ä3ÿ…Àt8‹D$P‹œ$¤…À„–;ës(‹T$‹L$PD$TRPSQUèƒÄ…À…¶‹œ$¤‹„$Ü‹î…À…ž;t$‡”€~ÿ u-;t$s'€> u"‹D$4ö@ u‹D$Pƒøt ƒøtƒ|$Tun‹|$‹T$T‹t$DÇ„$ÔéNúÿÿ‹D$T‹Ó+Ð;êwŠŠL$dŠU:Ñ…{ÿÿÿƒøt%ŠT$eŠE:Âtéfÿÿÿ3ÿëƒÿ„€ÿüÿÿtx‹D$0…Àt‹L$DQÿƒÄ…ÿtƒÿôt ‹Ç_^][ÄDËD$(…Àt<‹Œ$tÇ„$Ôƒù~‹”$`‹Œ$p+‰‹D$+‰A¸ôÿÿÿ飃Èÿ雋D$0‹œ$t…ÀtF‹D$Dƒû|"‹”$p øÿÿÿpz‹ÑÁéó¥‹Êƒáó¤9œ$¸~ÇD$pPÿƒÄ‹D$p…Àt3Àë ‹„$¸™+ÂÑøƒû}3Àë%‹´$¨‹Œ$ ‹”$p+ñ‰2‹´$¬+ñ‰r‹Œ$\…Ét!ö t‹I‹”$Ô_^]‰[ÄDøþÿÿÿ_^][ÄDÃPs5ÝÄ7]þ¼ ˆ \  — Q ì0SUVW‹¼$X3À‰D$<‰D$4‹GD‹O‰D$ ‹;ÁP‰ƒÏv‹œ$`‹¬$D‹„$h‹O;Áƒ¿vŠ„$d‹Œ$\¨‰L$8tT$`‰l$d‰\$`‰”$`3À‰D$,‰D$(‹„$HŠ‹Á%ÿ‹Øƒûv‰\$0‡È«3ÒŠ“ÿ$•‹´$H3ÛŠFŠ~Š^TtñƒÆ‰´$Héhôÿÿ‹„$Hp‹Æ3ÉŠhŠHÁ€8Ttñ‹”$h‹Œ$`BƒÀR‹”$`jQ‹Œ$dR‹”$dQ‹Œ$dR‹”$dQRPUèƒÄ(…À…󟉴$Héñóÿÿ‹„$H@3ÉŠhŠHÁ€8TtñƒÀ‰„$HéËóÿÿ‹”$H3ÀŠbŠB+ЉT$0Š‹È3Òƒá?Š‘‹<•4RÑæ#ø‹ÎÓç‹ÊJ…É‹Ç~zŠUƒîƒâ?‹ÎÓâ ÂEOuí=wH„q= w$„qƒø „øpƒø „ïpÿ„$HéÎæÿÿ=€„Øpÿ„$Hé·æÿÿ=_ w/„¿p= r-= †­p=/ „¢pÿ„$Héæÿÿ=0„‹pÿ„$Héjæÿÿ‹œ$X;klƒL^‹L$ 3ÀŠEE…ÉtE=Àr>‹È3Òƒá?Š‘‹<•4RÑæ#ø‹ÎÓç‹ÊJ…É‹Ç~zŠUƒîƒâ?‹ÎÓâ ÂEOuí=w‹È3Òƒá?Š‘‹<•4RÑæ#ø‹ÎÓç‹ÊJ…É‹Ç~zŠUƒîƒâ?‹ÎÓâ ÂEOuí=…w „ oƒø r'ƒø †oÿ„$Héñäÿÿ=( r =) †ônÿ„$HéÓäÿÿ‹œ$X;klƒµ\‹L$ 3ÀŠEE…ÉtE=Àr>‹È3Òƒá?Š‘‹<•4RÑæ#ø‹ÎÓç‹ÊJ…É‹Ç~zŠUƒîƒâ?‹ÎÓâ ÂEOuí=…w t4ƒø ‚snƒø ‡jnÿ„$HéIäÿÿ=( ‚Sn=) ‡Hnÿ„$Hé'äÿÿ‹Œ$X;ilƒMn‹L$ 3ÀŠEE…ÉtE=Àr>‹È3Òƒá?Š‘‹<•4RÑæ#ø‹ÎÓç‹ÊJ…É‹Ç~zŠUƒîƒâ?‹ÎÓâ ÂEOuí‹È3ÒÁé‹´$HŠ‘‹ÈÁâƒáÑ3Éf‹ U3ÒŠVƒú ͇\ÿ$•ƒû„±[ƒ„$HéjãÿÿŠI€ù t€ùt €ùt3Àë¸3Òƒû”Â;„Vƒ„$Hé2ãÿÿ‹”$H3ÀŠA3ÉŠJ3Ò; …•Â3Àƒû”À;Є¦rƒ„$Héøâÿÿ‹”$HŠB3Ò:A•Â3Àƒû”À;Є1[ƒ„$HéÉâÿÿ‹”$HŠB3Ò:•Â3Àƒû”À;ЄwUƒ„$Hé›âÿÿ3ÒŠQ‹•ƒøt ƒøt3Àë¸3Ƀû”Á;Á„ rƒ„$Hé_âÿÿ3ÒŠQƒ<•tƒø tƒø tƒø t ƒø t3Àë¸3Ƀû”Á;Á„~Zƒ„$Héâÿÿ3ÒŠQƒ<•tƒø tƒø tƒø tƒø t ƒø t3Àë¸3Ƀû”Á;Á„¤Tƒ„$HéÈáÿÿ3ÒŠQ‹ •ƒùtƒùt ƒø_t3Àë¸3Ƀû”Á;Á„5qƒ„$Hé‡áÿÿ‹œ$X‹{l;ï‰|$ƒýY‹L$ 3ÀŠEE…ÉtK=ÀrD‹Ð3Ƀâ?ŠŠ‹Ñ‹ •4R#ÈÑæ‹Á‹ÎÓà‹ÊJ…É~zŠUƒîƒâ?‹ÎÓâ ÂEOuí‹|$‹È3ÒÁéƒàŠ‘3ÉÁâÐ3Àf‹UŠ Åƒ<„ÄY;\$ …Û¿u3ÀŠEëI3ÀŠE=Àr=‹Ð3Ƀâ?¾ŠŠ‹ù‹½ Ñá#ÐÓâ;þ‹Â|Š.ƒéƒâ?Óâ ÂF;÷~îG‹È3ÒÁéƒàŠ‘3ÉÁâÐ3Àf‹UŠ Åƒ<u‹D$ï;è‚gÿÿÿÿ„$Hé1àÿÿ‹„$H3Û‹¼$XŠxŠXƒÀ‰„$H‹„$TÑã;؉\$$}‹G ‹ ˜…É|‹t˜+ñë‹GH…Àt3öë‹wl+õF‹”$HŠ ‹Á%ÿPºƒú‡à3ÛŠšÿ$‹œ$HƒÀºC‹È‰œ$Hƒá¾˜¾€…À‰L$(‰D$uGÇD$ÿÿÿë=3À€ùM”À‰D$(‹„$H3É3ÛŠhŠxŠHŠX…ɉL$uÇD$ÿÿÿƒÀ‰„$H…ö„2ßÿÿƒûÇD$|/‹Œ$\‹T$$QWVURèƒÄ…À„X‹D$î@;ÉD$~Ñ‹D$;Ø…7XéåÞÿÿ‹\$$‹„$\PWVUSèƒÄ…À„>Zîé¾Þÿÿ‹„$HHƒÀ!‰L$,‰„$HŠ‹Á%ÿpºƒþ‡‰3ÒŠ–ÿ$•¾˜ºÿÿÿ‹´$HƒÀº‹ÈF¾€ƒá‰´$H…À‰L$(‰D$uRÇD$ÿÿÿëH3À€ùM”À‰D$(‹„$H3É3ÛŠhŠxŠHŠX…ɉL$uÇD$ÿÿÿƒÀ‰„$Hë »‰\$‹D$ …À„¹ƒûÇD$Œì‹Œ$X‹Ql‰T$;l$ƒ\Y3ÀŠEE=Àr>‹È3Òƒá?Š‘‹<•4RÑæ#ø‹ÎÓç‹ÊJ…É‹Ç~zŠUƒîƒâ?‹ÎÓâ ÂEOuí=ÿv ƒ|$0N„më‹ÈºƒáÓâ‹L$,Á芄Є¨U‹D$@;ÉD$ŽhÿÿÿëD¾;Þ|;‹Œ$X‹yl;ïƒY3ÀºŠEE‹ÈƒáÓâ‹L$,Á芄ЄÊOF;ó~Ï‹|$;ß…YéåÜÿÿ‹„$H3ÒŠpHŠP‰L$,‰„$HŠ‹Á%ÿpºƒþ‡3ÒŠ–ÿ$•¾˜ºÿÿÿ‹´$HƒÀº‹ÈF¾¸ƒá‰´$H…Û‰L$(‰\$uX»ÿÿÿ‰\$ëM3À€ùM”À‰D$(‹„$H3Û3ÉŠxŠhŠXŠH…Û‹ù‰\$u »ÿÿÿ‰\$ƒÀ‰„$Hë »‰\$‹ûƒÿÇD$Œ‹´$X;nlƒœ]‹L$ 3ÀŠEE…ÉtJ=ÀrC‹Ð3Ƀâ?ŠŠ‹Ñ‹4• RÑá#ðÓæ‹Æ‹òJ…ö~rŠUƒéƒâ?Óâ ÂENuï‹´$X‹L$,QPèƒÄ…À„æ|‹D$@;ljD$Žxÿÿÿ;û…]]élÛÿÿ‹D$ …À„ª‹Œ$H3ÒA¸‰Œ$HŠúÀrB‹Â3Ƀà?¾Šˆ‹Á‹<… @Ñá#úÓç;Æ|‹”$HŠƒéƒã?Óã ûF;ð~î@‹´$X‹Vl+Õ;ÂØ_‹ÈH…ÉŽßÚÿÿ‹¼$HŠMŠEG:щ¼$H…7o‹ÐH…Òãé¶Úÿÿ‹„$X‹Hl+̓ùŒà_‹Œ$HŠUE8Q…>k‹ÁƒÀ‰„$Hé|Úÿÿ‹D$ …À„<‹”$H3ÀB»‰”$HŠ‹ø‹÷‰|$$þÀr@‹Î3Àƒá?Š‹ø‹½ Ñá#ÆÓà;û‹ð‹Ã|Šƒéƒã?Óã ó@;Ç~î_‹|$$‹Œ$X‹Al+Å;Ø]_þ€s"‹A03ÛŠ]EBЉ”$H8…léÊÙÿÿ3ÀŠEE=Àr:‹È3Òƒá?Š‘‹<• RÑá#øÓç‹Ç‹úJ…ÿ~zŠUƒéƒâ?Óâ ÂEOuï‹”$HÓ;ð‰”$H„kÙÿÿ‹Î3ÒÁ銑‹ÎÁâƒáÑ3Éf‹ U‹ÍÖ;Â…”Qé4Ùÿÿ‹Œ$X‹Al+ŃøŒÙ^‹´$H‹A03Û3ÒŠ]ŠVEŠ8…pc‹ÆƒÀ‰„$HéíØÿÿ‹„$H3ÛŠxŠXƒÀ‰\$‰„$Hé´ÇD$,‹´$H3À3Û3ÒŠf€ù&ŠF”ƒÆ‰D$‰T$(‰´$HëÇD$,3Ûë »‰\$,‹„$HÇD$ÿÿÿ@‰„$HëQ¸3Û‰D$,‰D$ÿ„$Hë9¾˜áÿÿÿ‹´$HƒÀá‹ÈF¾€ƒá‰´$H…À‰L$(‰D$uÇD$ÿÿÿ‹D$ …À„4‹„$H3ɾ‰D$$Љt$0‹ùÿÀrZ‹×3Àƒâ?Š‚‹…4@Ñæ#׋ÎÓâ¿;ljT$|#‹Œ$HƒîŠ‹Îƒâ?Óâ‹L$ ÊG;ø‰L$~Ý‹|$p‰t$0‹Œ$H΃þ‰Œ$Hޏö„$\tB‹Ç3ÉÁè‹×ŠˆƒâÁáÊ3Àf‹M‹ÅÇ;ÇtL$XQPèƒÄ‰D$ëÇD$ƒûÇD$|o‹”$X‹Rl‹Â+ƉD$ë‹D$;èw‹L$0‹|$$‹õ3Àó¦u‹D$0ë.‹D$…ÀŽ÷]‹Ê+È;é‡ë]‹È|$X‹õ3Àó¦…Ù]‹D$è‹D$@;ÉD$~¥;\$„œÖÿÿ‹D$(…À…t\‹D$‰l$(;؉\$}a‹Œ$X‹D$0‹Ql‹Ú+Ø;ëw‹L$0‹|$$‹õ3Àó¦u‹D$0ë"‹D$…À~E‹Ê+È;éw=‹È|$X‹õ3Àó¦u/‹D$‹L$è‹D$@;Á‰D$|±‹´$X‹D$,…À„KGéÖÿÿ‹´$X‹F|…Àtá;êrÝ;¬$LvÔ¸‰F\‹N|;ȨWë¿‹„$H3ÉŠ@‰L$‰„$H‹ùö„$\„׋Œ$X3Ò¾‹A0;ÞŠ8‹ú‰|$|2‹Ql‰T$닌$X;l$ƒ®_3É3ÒŠMEŠ;ú…ñ_F;ó~×;\$„VÕÿÿ‹L$(…É…ß\‹t$‰l$(;Þ}T‹Œ$X‹Ql‰T$;l$s3É3ÒŠMŠ;úu2EC;Þ|æë*‹Œ$X‹A|…Àt;¬$Lv¸‰A\‹Q|;Ð?_‹D$,…À„EéÙÔÿÿ¸;Ø|%‹Œ$X‹ql;îƒe3ÒŠUE;ú…"_@;Ã~å;\$„¡Ôÿÿ‹D$(…À…ü\‹D$‹Œ$X;؉l$(};‹ql;îs3ÒŠU;úu+EC;Ø|íë#‹A|…Àt;¬$Lv¸‰A\‹Q|;М^‹D$,…À„EDé6Ôÿÿ‹œ$X;klƒË]‹´$H‹L$ 3ÀFŠEE…ɉ´$HtE=Àr>‹È3Òƒá?Š‘‹<•4RÑæ#ø‹ÎÓç‹ÊJ…É‹Ç~zŠUƒîƒâ?‹ÎÓâ ÂEOuíö„$\t;=s ‹K03ÒŠ‹Â‹Œ$H‹s03ÒŠ‹ú3ÒAŠ>‰Œ$H;Є]éÓÿÿ‹Œ$H3ÒŠA;ЉŒ$H„y]é_Óÿÿ‹„$H3ÉŠhŠHƒÀ‹ñ‰„$H‰t$騋„$H3Ò3öŠpŠP‰T$3Ò€ù3”ƒÀ‰T$(‰„$Hé¨ÇD$,3öë ¾‰t$,‹„$HÇD$ÿÿÿ@‰„$Hëz¸3ö‰D$,‰D$ÿ„$Hëb‹„$H3É3öÇD$,ŠhŠHƒÀ‰L$‰„$Hë9‹´$HƒÀÔF‹È‰´$Hƒá¾°¾€…À‰L$(‰D$uÇD$ÿÿÿ‹„$H3ÉŠ@‰„$HŠ„$\¨‰L$„W‹”$X‹B03Ò‰D$$Š‹D$ …À‰T$„‘»;󌿋„$X‹Hl‰L$;l$ƒ$\3ÀŠEE=Àr<‹Ð3Ƀâ?ŠŠ‹Ñ‹<• RÑá#øÓç‹Ç‹úJ…ÿ~zŠUƒéƒâ?Óâ ÂEOuï=s ‹T$$3ÉŠ ‹Á9D$„\C;Þ~Œë;¸;ð|2‹Œ$X‹|$$‹Il;éƒ\3Ò3ÛŠUEŠ:‹T$;Ó„"D@;Æ~Ü‹\$;ó„BÑÿÿ‹D$(…À…@\‹D$ ‹Í…À‰L$(„Ï;ó‹Ö´‹„$X‹Hl‰L$‹D$¾;èsr3ÀŠE‹øÿÀrA‹Ï3Àƒá?Š‹ð‹µ vÑá#ÇÓà‹ø¸;ð|Š(ƒéƒã?Óã û@;Æ~î‹\$Fÿs ‹D$$3ÉŠ ‹ù9|$t0îB;Ó|ƒë'‹Œ$X‹A|…Àt;¬$Lv‹Á‰p\‹H|;Î9[‹D$,…À„£?éUÐÿÿ;ó}Z‹”$X‹|$$‹Bl‹”$X;ès3Ò3ÛŠUŠ:‹T$;Ót/‹T$EF;ò|Ùë#‹B|…Àt;¬$Lv¸‰B\‹r|;ðT]‹D$,…À„È>éæÏÿÿ‹D$ …À„2»;ó|p‹„$X‹Hl‰L$;l$ƒ'`3ÀŠEE=Àr<‹Ð3Ƀâ?ŠŠ‹Ñ‹<• RÑá#øÓç‹Ç‹úJ…ÿ~zŠUƒéƒâ?Óâ ÂEOuï9D$„5BC;Þ~ž‹”$X‹\$;ó„NÏÿÿ‹D$(…À…ð\‹D$ ‹Í…À‰L$(„;ó‹Öå‹„$X‹Hl‰L$‹D$¾;胚3ÀŠE‹øÿÀrA‹Ï3Àƒá?Š‹ð‹µ vÑá#ÇÓà‹ø¸;ð|Š(ƒéƒã?Óã û@;Æ~î‹\$F9|$tpîB;Ó|’ëg¸;ðŒ:ÿÿÿ‹”$X‹|$‹Jl;éƒÃ[3ÛŠ]E;û„ \@;Æ~åéÿÿÿ‹Œ$X‹A|…Àt;¬$Lv‹Á¹‰H\‹P|;ÑY‹D$,…À„U<é0Îÿÿ;ó}H‹Blë‹”$X;ès‹|$3ÒŠU;út+EF;ó|âë#‹B|…Àt;¬$Lv¸‰B\‹r|;ðA[‹D$,…À„Z;éÓÍÿÿ‹Œ$H3ÀÇD$(ŠaŠAƒÁ‰D$‰D$‰Œ$H‹Ðé‹„$H3ÒÇD$ŠpŠP‰T$3Ò€ù@”ƒÀ‰T$(‹T$‰„$HéÙÇD$,ÇD$ë ¸‰D$,‰D$‹„$H‹T$@ÇD$ÿÿÿ‰„$H隸ÇD$‹T$‰D$,‰D$‹„$H@‰„$Hëp‹„$H3ÉÇD$ÇD$,Šh‹T$ŠHƒÀ‰L$‰„$Hë=¾Çÿÿÿ‹´$HƒÀÇ‹ÈF¾€ƒá‰´$H…À‰L$(‰T$‰D$uÇD$ÿÿÿ‹¼$H3ÀŠGƒø‰D$$‰¼$Htƒøt ƒÎÿ‰t$0ë'3Ƀø”Á‰L$43ÉŠG‹ñ3ÉŠG‰t$0‰L$<‰¼$H…ÒŽ|…öŒIƒþ‡¢Dÿ$µ‹D$4…À…nD¿;׌K‹„$X‹\$ ‹Hl‰L$;l$ƒX\3ÀŠEE…Û‹ðtDþÀr<‹Î3Àƒá?Š‹… @Ñá#Ö‹ðÓâH…ö~pŠEƒéƒà?Óà ÐENuï‹T$G;ú~¡éÕ»;ӌȋŒ$X‹Ql‰T$;l$ƒ-[‹L$ 3ÀŠEE…ÉtE=Àr>‹È3Òƒá?Š‘‹<•4RÑæ#ø‹ÎÓç‹ÊJ…É‹Ç~zŠUƒîƒâ?‹ÎÓâ ÂEOuí‹È3ÒÁéƒàŠ‘3ÉÁâÐ3Àf‹UŠ Å‹Áƒø tƒøt ƒøt3Àë¸;D$4„›=‹D$C;ØŽJÿÿÿ‹T$‹\$;Ó„¯Êÿÿ‹D$(…À…Û]‹D$0‰l$(…ÀŒÒƒø‡Cÿ$…‹D$‹Ú;У‹”$X‹Bl‰D$‹L$¸;éƒK‹L$ 3ÒŠU…ÉtAúÀr9‹Ê3Àƒá?¾Š‹<… @Ñá#úÓç;Æ|Š.ƒéƒâ?Óâ úF;ð~î@‹L$4…É…*è‹D$C;Ø|Šé»;ÓŒ$ÿÿÿ‹”$X‹Bl‰D$;l$ƒØY‹L$ 3ÀŠEE…ÉtE=Àr>‹È3Òƒá?Š‘‹<•4RÑæ#ø‹ÎÓç‹ÊJ…É‹Ç~zŠUƒîƒâ?‹ÎÓâ ÂEOuí‹È3ÒÁéƒàŠ‘3ÉÁâÐ3Àf‹U3ÒŠ Å‹D$<‹4;ð‹D$4”Â;ЄÏX‹D$C;ØŽPÿÿÿé]þÿÿ»;ÓŒTþÿÿ‹Œ$X‹Ql‰T$;l$ƒ¹X‹L$ 3ÀŠEE…ÉtE=Àr>‹È3Òƒá?Š‘‹<•4RÑæ#ø‹ÎÓç‹ÊJ…É‹Ç~zŠUƒîƒâ?‹ÎÓâ ÂEOuí‹È3ÒÁéƒà‹t$<Š‘3ÉÁâÐ3Àf‹U3ÒŠ Å‹D$4;ΔÂ;Є4;‹D$C;ØŽWÿÿÿé”ýÿÿ»;ÓŒ‹ýÿÿ‹„$X‹Hl‰L$;l$ƒ?X‹L$ 3ÀŠEE…ÉtG=Àr@‹Ð3Ƀâ?ŠŠ‹Ñ‹<•4RÑæ#ø‹ÎÓç‹ÊJ…É‹Ç~zŠUƒîƒâ?‹ÎÓâ ÂEOuí‹È3ÒÁéƒà‹t$<Š‘3ÉÁâÐ3Àf‹U3ÒŠ Å‹D$4;ΔÂ;Є;W‹D$C;ØŽUÿÿÿéÉüÿÿ»;ÓŒÀüÿÿ‹„$X‹Hl‰L$;l$ƒÑW‹L$ 3ÀŠEE…ÉtG=Àr@‹Ð3Ƀâ?ŠŠ‹Ñ‹<•4RÑæ#ø‹ÎÓç‹ÊJ…É‹Ç~zŠUƒîƒâ?‹ÎÓâ ÂEOuí‹È3ÒÁéƒàŠ‘3ÉÁâÐ3Àf‹UŠ Å‹ƒøt ƒøt3Àë¸;D$4„‘9‹D$C;ØŽHÿÿÿéñûÿÿƒúÇD$Œäûÿÿ‹”$X»‹Bl‰D$;l$ƒ“V‹L$ 3ÀŠEE…ÉtD=Àr=‹È3Òƒá?Š‘‹<•4RÑæ#ø‹ÎÓç‹ÊJ…É‹Ç~zŠU+óƒâ?‹ÎÓâ ÂEOuî‹È3ÒÁ銑‹ÈÁâƒáÑ3Éf‹ U3ÒŠÍ9•tƒø tƒø tƒø t ƒø t3Àë¸;D$4„wU‹D$‹L$@;Á‰D$Ž5ÿÿÿéýúÿÿƒúÇD$Œðúÿÿ‹„$X»‹Hl‰L$;l$ƒPU‹L$ 3ÀŠEE…ÉtF=Àr?‹Ð3Ƀâ?ŠŠ‹Ñ‹<•4RÑæ#ø‹ÎÓç‹ÊJ…É‹Ç~zŠU+óƒâ?‹ÎÓâ ÂEOuî‹È3ÒÁ銑‹ÈÁâƒáÑ3Éf‹ U3ÒŠÍ9•tƒø tƒø tƒø tƒø t ƒø t3Àë¸;D$4„ª7‹D$‹L$@;Á‰D$Ž.ÿÿÿéúÿÿ»;ÓŒùùÿÿ‹„$X‹|$ ‹Hl‰L$;l$ƒ©T3ÀŠEE…ÿtC=Àr<‹Ð3Ƀâ?ŠŠ‹Ñ‹4• RÑá#ðÓæ‹Æ‹òJ…ö~rŠUƒéƒâ?Óâ ÂENuï‹È3ÒÁ銑‹ÈÁâƒáÑ3Éf‹ U3ÒŠÍ‹ •ƒùtƒùt ƒø_t3Àë¸;D$4„™S‹D$C;ØŽIÿÿÿé'ùÿÿƒø…gƒúÇD$Œùÿÿ‹„$X‹Xl;ëƒ(T‹L$ 3ÀŠEE…ÉtE=Àr>‹È3Òƒá?Š‘‹<•4RÑæ#ø‹ÎÓç‹ÊJ…É‹Ç~zŠUƒîƒâ?‹ÎÓâ ÂEOuí‹È3ÒÁéƒàŠ‘3ÉÁâÐ3Àf‹UŠ Åƒ<„6;냙‹D$ ¿…Àu3ÀŠEëI3ÀŠE=Àr=‹Ð3Ƀâ?¾ŠŠ‹ù‹½ Ñá#ÐÓâ;þ‹Â|Š.ƒéƒâ?Óâ ÂF;÷~îG‹È3ÒÁéƒàŠ‘3ÉÁâÐ3Àf‹UŠ Åƒ<u ï;ë‚gÿÿÿ‹D$‹L$@;Á‰D$޹þÿÿé·÷ÿÿ‹|$ …ÿ„rƒÀúƒø‡Ú:ÿ$…»;ÓŒ‹÷ÿÿ‹Œ$X‹Al;能T‹ñ‹N…Ét‹ÖWƒÂRPQUèƒÄ…À…p:ë/‹N+Á;èw*‹´$XŠE:F,uƒù„M:ŠM‹Ö:J-„?:‹T$‹„$XE‹@l;èsŠM€áÀ€ù€uE;èrðC;ÚŽnÿÿÿéøöÿÿ¹;ÑŒçöÿÿ‹„$X‹@l;èƒ_RE;èsŠ]€ãÀ€û€uE;èrðA;Ê~Þéºöÿÿ‹„$X‹Hl+Ê;釮(êéŸöÿÿƒúÇD$ŒŠöÿÿ‹¼$X‹_l;ëƒ_R3ÀŠEE=ÀrG‹Ð3Ƀâ?ŠŠ‹Ñ‹ •4R#ÈÑæ‹Á‹ÎÓà‹ÊJ…É~zŠUƒîƒâ?‹ÎÓâ ÂEOu틼$Xƒø w%tƒø tF†ARƒø ‡8Rë*;ës1€} u+Eë(=…t=' †R=) ‡ R‹G`…À…/(‹D$‹L$@;Á‰D$Ž=ÿÿÿé¸õÿÿ»;ÓŒ«õÿÿ‹„$X‹Hl‰L$;l$ƒÜQ3ÀŠEE=Àr@‹Ð3Ƀâ?ŠŠ‹Ñ‹<•4RÑæ#ø‹ÎÓç‹ÊJ…É‹Ç~zŠUƒîƒâ?‹ÎÓâ ÂEOuí=w4„Ç2= w„º2ƒø „±2ƒø „¨2ëD=€„›2ë7=_ w%„Œ2= r#= †z2=/ „o2ë =0„b2‹D$C;ØŽ*ÿÿÿéÂôÿÿ»;ÓŒµôÿÿ‹„$X‹Hl‰L$;l$ƒCQ3ÀŠEE=Àr@‹Ð3Ƀâ?ŠŠ‹Ñ‹<•4RÑæ#ø‹ÎÓç‹ÊJ…É‹Ç~zŠUƒîƒâ?‹ÎÓâ ÂEOuí=w(tY= wtPƒø tKƒø …J7ë@=€…=7ë3=_ w!t*= ‚'7= v=/ …7ë =0…7‹D$C;ØŽ:ÿÿÿéÜóÿÿ»;ÓŒÏóÿÿ‹„$X‹Hl‰L$;l$ƒQQ3ÀŠEE=Àr@‹Ð3Ƀâ?ŠŠ‹Ñ‹<•4RÑæ#ø‹ÎÓç‹ÊJ…É‹Ç~zŠUƒîƒâ?‹ÎÓâ ÂEOuí=…w„ë0ƒø rƒø †Ý0ë=( r =) †É0‹D$C;ØŽmÿÿÿé)óÿÿ»;ÓŒóÿÿ‹„$X‹Hl‰L$;l$ƒAP3ÀŠEE=Àr@‹Ð3Ƀâ?ŠŠ‹Ñ‹<•4RÑæ#ø‹ÎÓç‹ÊJ…É‹Ç~zŠUƒîƒâ?‹ÎÓâ ÂEOuí=…wt*ƒø ‚¿5ƒø ‡¶5ë=( ‚©5=) ‡ž5‹D$C;ØŽiÿÿÿéròÿÿ¿;׌eòÿÿ‹„$X‹\$‹Hl‰L$‹È;l$ƒèO3ÀŠEE=ÀrC‹Ð3Ƀâ?ŠŠ‹Ñ‹4• RÑá#ðÓæ‹Æ‹òJ…ö~rŠUƒéƒâ?Óâ ÂENu$X=€s ‹Q4ö…cOG;û~éÙñÿÿ¹;ÑŒÌñÿÿ‹´$X‹|$‹Vl;ꃕ]ŠE<€ƒà]‹^4%ÿŠ$E„À„Ê]A;Ï~Òé‹ñÿÿ‹D$º;ÂŒzñÿÿ‹´$X‹ø‹Nl;éƒE]ŠE<€s‹^4%ÿö…‚]E;ésŠE$À<€uE;éròB;×~Çé0ñÿÿ¹;ÑŒ#ñÿÿ‹´$X‹|$‹Vl;êƒì\ŠE<€ƒ7]‹^4%ÿŠ$E„À„!]A;Ï~Òéâðÿÿ‹D$º;ÂŒÑðÿÿ‹´$X‹ø‹Nl;郜\ŠE<€s‹^4%ÿö…Ù\E;ésŠE$À<€uE;éròB;×~Çé‡ðÿÿ¹;ÑŒzðÿÿ‹´$X‹|$‹Vl;êƒC\ŠE<€ƒŽ\‹^4%ÿŠ$E„À„x\A;Ï~Òé9ðÿÿƒÀúƒø‡h3ÿ$…¾;ÖŒðÿÿ‹Œ$X‹Al;èƒKM‹ù‹O…Ét‹×jƒÂRPQUèƒÄ…À…ý2ë/‹O+Á;èw*‹¼$XŠE:G,uƒù„Ú2ŠM‹×:J-„Ì2‹T$EF;ò~é§ïÿÿ‹„$X‹Hl+Ê;é‡ÃJêéŒïÿÿ¾;ÖŒ{ïÿÿ‹¼$X‹Ol;éƒà]3ÀŠEEƒè ƒø{‡³Y3ÛŠ˜ÿ$;és€} uEë ‹G`…À…5F;ò~ºé*ïÿÿ¹;ÑŒïÿÿ‹¼$X‹t$‹Wl;êƒøK3ÀŠEEƒø „PYƒø „GY= „‹Œ$X‹ñ‹Ql‰T$‹D$¿;è‹×ƒî‹L$ 3ÀŠE…ÉtH=ÀrA‹È3Òƒá?Š‘‹•4RÑæ#Ø‹ÎÓã;׋Ã|Š/ƒîƒã?‹ÎÓã ÃG;ú~ì‹´$XB‹È3ÛÁéƒà‹|$<Š™3ÉÁãØ3Àf‹]Š Å3À;Ï‹L$4”À;Á„‡‹D$‹L$ê@;Á‰D$ŒBÿÿÿék;Ó‰T$_‹Œ$X‹ñ‹Ql‰T$‹D$¿;è‹×ƒ½‹L$ 3ÀŠE…ÉtH=ÀrA‹È3Òƒá?Š‘‹•4RÑæ#Ø‹ÎÓã;׋Ã|Š/ƒîƒã?‹ÎÓã ÃG;ú~ì‹´$XB‹È3ÛÁéƒàŠ™3ÉÁãØ3Àf‹]Š Å‹ƒøt ƒøt3Àë¸;D$4„›‹D$‹L$ê@;Á‰D$Œ5ÿÿÿé‹F|…À„t;¬$L†g‰~\‹F|;Çb)éT;Ó‰T$H‹´$X‹Vl‰T$‹D$¿;èƒÏ‹L$ 3ÀŠE…ÉtO=ÀrH‹È3Òƒá?¾Š‘‹ú‹½ Ñá#ÐÓâ;þ‹Â|Š.ƒéƒâ?Óâ ÂF;÷~î‹\$‹´$XG‹È3ÒÁ銑‹ÈÁâƒáÑ3Éf‹ U3Ҋ̓<•tƒø tƒø tƒø t ƒø t3Àë¸;D$4„r‹D$ï@;ÉD$Œ%ÿÿÿéZ‹F|…À„O;¬$L†B‰~\‹F|;Ç(6é/;Ó‰T$#‹„$X‹ð‹Hl‰L$‹D$¿;è‹×ƒÓ‹L$ 3ÀŠE…ÉtJ=ÀrC‹Ð3Ƀâ?ŠŠ‹Ñ‹•4RÑæ#Ø‹ÎÓã;׋Ã|Š/ƒîƒã?‹ÎÓã ÃG;ú~ì‹´$XB‹È3ÛÁ銙‹ÈÁãƒáÙ3Éf‹ ]3ۊ̓<tƒø tƒø tƒø tƒø t ƒø t3Àë¸;D$4„I‹D$‹L$ê@;Á‰D$Œÿÿÿé-‹F|…À„";¬$L†‰~\‹F|;Ǩ1é;Óú‹„$X‹Hl‰L$ë‹„$X‹L$¿;郴3ÀŠE‹ð‹D$ …ÀtEþÀr=‹Î3Àƒá?Š‹ø‹½ Ñá#ÆÓà‹ð¸;ø|Š(ƒéƒã?Óã ó@;Ç~îG‹Î3ÀÁ銋ÎÁàƒáÁ3Éf‹ E3ÀŠÍ‹…ƒøtƒøt ƒþ_t3Àë¸;D$4t/‹D$ïB;ÐŒ6ÿÿÿë‹H|…Ét;¬$Lv‰x\‹H|;Ï¥9‹D$,…À„éÁ®ÿÿ‹t$$ƒþ…œ;Ó‰T$‹Œ$X‹Yl‹„$X;ëƒC‹L$ 3ÀŠEE…ÉtG=Àr@‹Ð3Ƀâ?ŠŠ‹Ñ‹<•4RÑæ#ø‹ÎÓç‹ÊJ…É‹Ç~zŠUƒîƒâ?‹ÎÓâ ÂEOuí‹È3ÒÁéƒàŠ‘3ÉÁâÐ3Àf‹UŠ Åƒ<„Û;냙‹D$ ¿…Àu3ÀŠEëI3ÀŠE=Àr=‹Ð3Ƀâ?¾ŠŠ‹ù‹½ Ñá#ÐÓâ;þ‹Â|Š.ƒéƒâ?Óâ ÂF;÷~îG‹È3ÒÁéƒàŠ‘3ÉÁâÐ3Àf‹UŠ Åƒ<u ï;ë‚gÿÿÿ‹D$‹L$@;Á‰D$Œ°þÿÿë#‹H|…Ét;¬$Lv¹‰H\‹P|;Ñ`=‹D$,…À„wé­ÿÿ‹D$ …ÀFú„í ƒø‡|%ÿ$…ûÿÿÿ‹òŸ;Ó¶ ‹”$X‹Bl;èƒê‹J…Ét0‹T$ R‹”$\ƒÂRPQUèƒÄ…À…z ‹\$‹”$Xë(‹J+Á;èwŠE:B,uƒù„S ŠMŠB-:È„E ‹BlE;èsŠM€áÀ€ù€uE;èrðF;ó$ épÿÿÿ;Ó ‹”$X‹Bl;胅‹J…Ét0‹T$ R‹”$\ƒÂRPQUèƒÄ…À…Û‹\$‹”$Xë(‹J+Á;èwŠE:B,uƒù„´ŠMŠB-:È„¦‹BlE;èsŠM€áÀ€ù€uE;èrðF;ó…épÿÿÿ‹B|…À„u;¬$L†h¸‰B\‹J|;ȼVéPûÿÿÿ}g;Ó‹Ê>‹´$X‹Fl;èsE;èsŠU€âÀ€ú€uE;èrðA;Ë|âé‹F|…À„;¬$L†ù¸‰F\‹N|;È50éá‹„$X‹hléÒ+Ú‹”$X‹Ë‹Bl‹ð+õ;Îv2‹è‹B|…À„¯;¬$L†¢¸‰B\‹J|;È8éŠééƒ;Ó‰T$w‹Œ$X‹Ql;꿃¿3ÀŠE=ÀrH‹È3Ûƒá?Š™‹û‹4½ Ñá#ðÓæ‹Æ¾;þ|Š.ƒéƒã?Óã ÃF;÷~î‹\$‹Œ$XGƒø uE;êƒþ€} u8Eë5ƒø t.‹q`…ö…åƒø tƒø t=…t=( t =) …Âï‹D$@;ÉD$ŒBÿÿÿéª;Ó‰T$ž‹”$X‹ò‹Bl‰D$‹D$¿;è‹×ƒÚ3ÀŠE=ÀrA‹È3Òƒá?Š‘‹•4RÑæ#Ø‹ÎÓã;׋Ã|Š/ƒîƒã?‹ÎÓã ÃG;ú~ì‹´$XB=w$tO= wtFƒø tAƒø t<3Àë==€t13Àë2=_ wt$= r= v=/ t3Àë=0t3À븋\$$3Ƀû”Á;Á„½‹D$‹L$ê@;Á‰D$Œÿÿÿé¡‹F|…À„–;¬$L†‰‰~\‹F|;Çw*év;Ó‰T$j‹Œ$X‹Ql‰T$‹D$¿;胪3ÀŠE=ÀrL‹È3Òƒá?¾Š‘‹ú‹½ Ñá#ÐÓâ;þ‹Â|Š.ƒéƒâ?Óâ ÂF;÷~î‹\$‹t$$‹Œ$XG=…w6tBƒø rƒø v83À3Òƒþ”Â;„΋D$ï@;ÉD$Œ_ÿÿÿé¶=( rÏ=) wȸëËA|…À„–;¬$L†‰‰y\‹A|;Çý1év‹T$‹D$;Ðf‹„$X‹Hl‰L$‹L$¾;éƒX3ÉŠM‹ùÿÀrD‹Ç3Ƀà?Šˆ‹ñ‹µ vÑá#ÇÓà‹ø¸;ð|Š(ƒéƒã?Óã û@;Æ~î‹„$XFÿs ‹H4ö9…ß‹L$îB;ÑŒxÿÿÿéË‹T$‹D$;л‹„$X‹Hl‰L$‹L$¾;éƒÚ3ÉŠM‹ùÿÀrD‹Ç3Ƀà?Šˆ‹ñ‹µ vÑá#ÇÓà‹ø¸;ð|Š(ƒéƒã?Óã û@;Æ~î‹„$XFÿƒ=‹H4ö9„0‹L$îB;ÑŒtÿÿÿé‹T$‹D$;Ð ‹„$X‹Hl‰L$‹L$¾;éƒþ3ÉŠM‹ùÿÀrD‹Ç3Ƀà?Šˆ‹ñ‹µ vÑá#ÇÓà‹ø¸;ð|Š(ƒéƒã?Óã û@;Æ~î‹„$XFÿs ‹H4ö9……‹L$îB;ÑŒxÿÿÿéq‹T$‹D$;Ða‹„$X‹Hl‰L$‹L$¾;郀3ÉŠM‹ùÿÀrD‹Ç3Ƀà?Šˆ‹ñ‹µ vÑá#ÇÓà‹ø¸;ð|Š(ƒéƒã?Óã û@;Æ~î‹„$XFÿƒã‹H4ö9„Ö‹L$îB;ÑŒtÿÿÿé‹H|…É„·;¬$L†ªÇ@\‹H|ƒùû4é’‹T$‹D$;Ђ‹„$X‹Hl‰L$‹L$¾;ésx3ÉŠM‹ùÿÀrD‹Ç3Ƀà?Šˆ‹ñ‹µ vÑá#ÇÓà‹ø¸;ð|Š(ƒéƒã?Óã û@;Æ~î‹„$XFÿs ‹H4ö9…ÿ‹L$îB;Ñ|€éï‹H|…É„ä;¬$L†×Ç@\‹H|ƒùÄ.é¿‹T$‹D$;Я‹„$X‹Hl‰L$‹L$¾;ésq3ÉŠM‹ùÿÀrD‹Ç3Ƀà?Šˆ‹ñ‹µ vÑá#ÇÓà‹ø¸;ð|Š(ƒéƒã?Óã û@;Æ~î‹„$XFÿs9‹H4ö9t0‹L$îB;Ñ|„ë#‹H|…Ét;¬$LvÇ@\‹H|ƒùd3‹D$,…À„¼ é£ÿÿƒø‡ÿ$…‹D$‹ò;Ћ”$X‹Bl;èsj‹J…Ét)‹”$XjƒÂRPQUèƒÄ…À…Ï‹”$Xë*‹J+Á;èw!ŠEŠZ,:Ãuƒù„ªŠMŠB-:È„œ‹D$EF;ðŽë‹B|…À„;¬$L†t¸‰B\‹J|;ȸ/é\+Ú‹”$X‹Ë‹Bl‹ð+õ;Îv2‹è‹B|…À„9;¬$L†,¸‰B\‹J|;ÈMMééé ‹T$‹|$;×ý‹´$X‹Nl;éƒy3ÀŠEƒø uE;éƒØ€} u(ë%ƒø t ‹^`…Û…Àƒø tƒø t =……«EB;×|²é ;Ó‹Ê–‹¼$X‹t$‹Wl;êƒt3ÀŠEƒø „rƒø „i= „^EA;Î|ÐéS;Ó‹ÊI‹¼$X‹t$‹Wl;ês%3ÀŠEƒø tƒø t = …EA;Î|Üé‹G|…À„;¬$L†ú¸‰G\‹O|;Èéâ;Ó‹ÊØ‹¼$X‹t$‹Wl;ês?3ÀŠEƒø „¸ƒø „¯ƒø „¦ƒø „=…„’EA;Î|Â釋G|…À„|;¬$L†o¸‰G\‹O|;ȹéW;Ó‹ÊM‹¼$X‹t$‹Wl;ês/3ÀŠEƒø tƒø tƒø tƒø t =……EA;Î|Òé ‹G|…À„;¬$L†ô¸‰G\‹O|;ÈNéÜ;Ó‹ÂÒ‹´$X‹Nl;éƒð‹~43ÒŠUö…®E@;Ã|àé£;Ӌ™‹´$X‹Nl;郋~43ÒŠUö„uE@;Ã|àéj;Ó‹Â`‹´$X‹Nl;és‹~43ÒŠUö…@E@;Ã|äé5‹F|…À„*;¬$L†¸‰F\‹N|;ÈÓ é;Ó‹Âû‹´$X‹Nl;és‹~43ÒŠUö„ÛE@;Ã|äéЋF|…À„Å;¬$L†¸¸‰F\‹N|;ÈÖé ;Ӌ–‹´$X‹Nl;és‹~43ÒŠUöuzE@;Ã|èër‹F|…Àtk;¬$Lvb¸‰F\‹N|;Èk#ëM;Ó‹Â}G‹´$X‹Nl;és‹~43ÒŠUöt+E@;Ã|èë#‹F|…Àt;¬$Lv¸‰F\‹N|;ÈÉ‹D$,…À„EIééÿÿ3ÀŠfŠFŠLD€ùT‰„$Hu3ÉŠhŠHÁ€8Ttñ‰„$H‹Œ$H‹D$0ƒÁƒøc‰Œ$H„n‹œ$`Ç„$dé©‹„$H‹¼$X3ÒŠpŠP‹Â‰D$$4‹G;ðŒë‹¼$X3ÀƒûaœÀH3Ƀà‰„$d‹„$HŠhŠH€<T…‘‹”$h‹œ$`B‰T$0‹D$0‹Œ$d‹”$\‹´$HP‹„$XQ‹Œ$XSRW‹”$`P3ÀŠQ3ÉRŠˆÎQUèƒÄ(…Àt =üÿÿ…©H3Ò3ÀŠvŠVò‰´$HŠfŠF€<0Tt„닜$`‹„$d…À…æ‹„$H3É3ÒŠŠ‘‰„$H邊PH€ú‰L$8u‹”$\3ÉŠHƒâø ʉŒ$\Š‹„$h€ùWuE‹Œ$\‹”$P@P‹„$PjSQ‹L$HWVRPQUèƒÄ(…À…çG‹T$0‰”$Héý‹Œ$\‹”$P@P‹„$PjSQ‹L$@WVRPQUèƒÄ(…À…¢G‹T$8‰”$H鸀:aÀ$þƒÀ‰„$dŠ‹L$(‹ÅM;Á„¹>‹D$ …ÀtŠM€áÀ€ù€u ŠUÿM€âÀ€ú€tô‹„$`‹Œ$X‹”$TVjP‹„$XWQ‹Œ$\RSPQUèƒÄ(…Àt˜_^][Ä0Ã;éry‹”$h‹´$P‹œ$Tz‹„$`‹Œ$\‹”$XWjP‹„$XQ‹Œ$XRSVPQUèƒÄ(…À…>‹D$(M;ès¹‹”$X_3À‰²œ^][Ä0Ë´$P‹”$X‰²œ_^]3À[Ä0Ë„$h‹Œ$`‹œ$\‹”$X‹´$Px‹„$TWjQ‹Œ$XSR‹”$\PVQRUèƒÄ(…À…€=‹L$(‹ÅM;Át…ŠM€áÀ€ù€u ŠUÿM€âÀ€ú€tô‹„$`‹Œ$X‹”$TWjP‹„$XSQ‹Œ$\RVPQUèƒÄ(…Àt¤_^][Ä0Ã;é‚ÿÿÿ‹”$h‹´$P‹œ$Tz‹„$`‹Œ$\‹”$XWjP‹„$XQ‹Œ$XRSVPQUèƒÄ(…À…»<‹D$(M;ès¹é½þÿÿ‹„$h‹Œ$`‹œ$\‹”$X‹´$Px‹„$TWjQ‹Œ$XSR‹”$\PVQRUèƒÄ(…À…W<‹L$(‹ÅM;Á„XþÿÿŠM€áÀ€ù€u ŠUÿM€âÀ€ú€tô‹„$`‹Œ$X‹”$TWjP‹„$XSQ‹Œ$\RVPQUèƒÄ(…Àt _^][Ä0Ã;l$(rw‹”$h‹´$H‹œ$Pz‹„$`‹Œ$\‹”$XWjP‹„$`Q‹Œ$\RPSQVUèƒÄ(M…À…;;l$(s»‹Œ$X_^]‰™œ3À[Ä0Ëœ$P_^‰™œ]3À[Ä0Ã;l$(rw‹”$h‹¼$H‹œ$Pr‹„$`‹Œ$\‹”$XVjP‹„$`Q‹Œ$\RPSQWUèƒÄ(M…À…ø:;l$(s»‹”$X_^]‰šœ3À[Ä0Ë”$X‹œ$P_^‰šœ]3À[Ä0Ë„$h‹Œ$`‹”$\‹œ$Px‹„$TWjQ‹Œ$XR‹”$XVPSQRUèƒÄ(…À…h:;l$(„êŠEÿM$À<€u ŠMÿM€áÀ€ù€tô‹”$`‹„$\‹Œ$TWjR‹”$XP‹„$XVQSRPUèƒÄ(…Àt¦_^][Ä0ËŒ$h‹”$d‹„$H‹´$XAQ‹Œ$dR‹”$dQ‹Œ$`R‹”$\VxQ3ÉŠWR3ÒŠ‘3ÉŠHÂÈQUèƒÄ(=üÿÿuS‹vp‹ÏŠŠÓ:u„ÒtŠYŠÓ:^uƒÁƒÆ„Òuà3ÉëɃÙÿ…Éu‹”$X_^¸üÿÿ‰jp][Ä0Ë´$X‹Žœ…É…89‰¾œ_^][Ä0ËŒ$X‹„$P‰œ_^]3À[Ä0Ë”$h‹„$d‹Œ$`‹¼$XB‹´$PR‹”$`P‹„$\Q‹Œ$XRWP‹„$`3ÒVŠQ3ÉŠŠÈQUèƒÄ(…À…ž8‰·œ_^]¸üÿÿ[Ä0Ë”$h‹„$d‹Œ$`‹¼$XB‹´$PR‹”$`P‹„$\Q‹Œ$XRWP‹„$`3ÒVŠQ3ÉŠŠÈQUèƒÄ(…À… 8‰·œ_^]¸üÿÿ[Ä0Ë”$h‹„$d‹Œ$`‹´$X‹¼$HBR‹”$`P‹„$\Q‹Œ$\R‹”$\VP3ÀQŠ3ÉR3ÒŠˆŠW‹ÇÁÐRUèƒÄ(…À…™7ƒÇ¸üÿÿ‰¾œ_^][Ä0ËŒ$h‹”$d‹„$`‹´$X‹¼$PAQ‹Œ$`R‹”$\P‹„$XQVRWP‹„$h3É3ÒŠŠ‘ÐRUèƒÄ(…À…7‰np‰¾œ_^]¸üÿÿ[Ä0Ë„$h‹Œ$d‹”$`‹´$X‹¼$H@P‹„$`Q‹Œ$\R‹”$\P‹„$\VQ3ÉRŠ3ÒP3ÀŠ‘ŠG‹ÏÊÁPUèƒÄ(…À…Ž6ƒÇ¸üÿÿ‰~p_^][Ä0Ë”$h‹„$d‹Œ$`‹¼$XB‹´$PR‹”$`P‹„$\Q‹Œ$XRWP‹„$`3ÒVŠQ3ÉŠŠÈQUèƒÄ(…À…6‰·œ_^]¸üÿÿ[Ä0Ë”$h‹„$d‹Œ$`‹´$X‹¼$HBR‹”$`P‹„$\Q‹Œ$\R‹”$\VP3ÀQŠ3ÉR3ÒŠˆŠW‹ÇÁÐRUèƒÄ(…À…‰5ƒÇ¸üÿÿ‰¾œ_^][Ä0Ã_^]¸øÿÿÿ[Ä0Ã_^]¸ëÿÿÿ[Ä0Ë„$X‹Œ$T‹”$L_‰ht‰ˆ€‹Œ$L‰Pp^‰ˆœ]¸[Ä0Ë”$P_‰–œ^]3À[Ä0ËŒ$P_‰Žœ^]3À[Ä0ËF|…ÀtÅ;¬$Lv¼¸‰F\‹N|;È~­‹Œ$P_‰Žœ^]¸ôÿÿÿ[Ä0ËG|…Àt5;¬$Lv,¸‰G\‹O|;È~‹„$P‰‡œ_^]¸ôÿÿÿ[Ä0ËŒ$P3À‰œ_^][Ä0ËG|…À„»;¬$L†®¸‰G\‹O|;ÈŽ›‹„$P‰‡œ_^]¸ôÿÿÿ[Ä0ËC|…À„þ;¬$L†ñ¸‰C\‹K|;ÈŽÞ‹Œ$P_^‰‹œ]¸ôÿÿÿ[Ä0Ë”$X‹Œ$P_^]‰Šœ3À[Ä0Ë”$X‹Œ$P_^]‰Šœ3À[Ä0Ã_^]¸òÿÿÿ[Ä0ËC|…Àt5;¬$Lv,¸‰C\‹K|;È~‹Œ$P_^‰‹œ]¸ôÿÿÿ[Ä0Ë”$P_^‰“œ]3À[Ä0Ë„$P_^‰ƒœ]3À[Ä0ËG|…À„ ;ol‚;¬$L†õ¸‰G\‹O|;Ȏ⋌$P¸ôÿÿÿ‰œ_^][Ä0ËL$(…É„'‹„$h‹Œ$`‹”$\‰\$X‹„$TSjQ‹Œ$\R‹”$\WP‹„$`QRPUèƒÄ(…À…J2‹L$‹D$;È8*‹”$\‹D$$RWVUPèƒÄ…ÀtW‹T$‹Œ$`‹„$TîBS‰T$‹”$`jQ‹Œ$\R‹”$\WP‹„$`QRPUèƒÄ(…Àtˆ_^][Ä0ËG|…À„c%;ol‚Z%;¬$L†M%¸‰G\‹O|;ÈŽ:%‹”$P¸ôÿÿÿ‰—œ_^][Ä0Ã;؉l$(}1‹Œ$\‹T$$QWVURèƒÄ…À„„‹D$îC;Ø|Õ;l$(rY‹Œ$hY‹”$`‹„$\‹Œ$TSjR‹”$\P‹„$\WQ‹Œ$`RPQUèƒÄ(…À…î0‹D$(+î;ès±‹”$P3À‰—œ_^][Ä0ËG|…Àt€;ol‚wÿÿÿ;¬$L†jÿÿÿ¸‰G\‹O|;ÈŽWÿÿÿ‹„$P‰‡œ_^]¸ôÿÿÿ[Ä0ËG|…À„p(;ol‚g(é-(‹„$X‹H|…É„°;¬$L†£¹‰H\‹P|;ÑŽ‹”$P_^‰œ]¸ôÿÿÿ[Ä0ËŒ$X‹A|…À„+;¬$L†¸‰A\‹Q|;ÐŽ ‹„$P_^‰œ]¸ôÿÿÿ[Ä0ËD$(…À„Œ‹D$ …À„`‹”$h‹„$`‹Œ$\‹¼$X‹´$P‰\$Z‹”$TSjP‹„$XQ‹Œ$XWRVPQUèƒÄ(…À…T/ë‹´$P‹T$‹D$;ÐÒ;olƒ”3ÀŠEE=ÀrE‹È3Òƒá?Š‘‹ •4R#ÈÑæ‹Á‹ÎÓà‹ÊJ…É~zŠUƒîƒâ?‹ÎÓâ ÂEOu틼$X=ÿv ƒ|$0N„Ì&ë%‹ÈºƒáÓâ‹L$,Á芄ЄY‹¼$X‹Œ$`‹”$\‹„$T‹t$SjQ‹Œ$\R‹”$\WP‹„$`QRFPU‰t$8èƒÄ(…À„ÿÿÿ_^][Ä0ËŒ$h‹”$`‹„$\‹û‹œ$Pq‹Œ$XVjR‹”$`P‹„$\Q‹Œ$\RSPQUèƒÄ(…À…ö-;|$Í-‹„$X;hlsq3ÀºŠEE‹ÈƒáÓâ‹L$,Á芄ЄЋŒ$`‹”$\‹„$XVjQ‹Œ$`R‹”$\P‹„$\QSRPUGèƒÄ(…Àt„_^][Ä0ËH|…É„™;¬$L†Œ¹‰H\‹P|;ÑŽy_^‰˜œ]¸ôÿÿÿ[Ä0ËD$ ‰l$(…À„Ô;߉\$¯‹„$X‹Hl‰L$‹D$¾;èƒQ3ÀŠE=ÀrG‹Ð3Ƀâ?ŠŠ‹Ñ‹<•4RÑæ#ø‹ÎÓç‹Ç¿;×|Š/ƒîƒã?‹ÎÓã ÃG;ú~ì‹|$r=ÿv ƒ|$0Nt/ë‹ÈºƒáÓâ‹L$,Á芄Ðt‹D$î@;ljD$Œ_ÿÿÿ‹œ$L‹„$h‹Œ$`‹”$\‹´$Px‹„$XWjQ‹Œ$`R‹”$XPQVSRUèƒÄ(…À… ,‹L$(‹ÅM;Á„îÿÿŠM€áÀ€ù€u ŠUÿM€âÀ€ú€tô‹„$`‹Œ$\‹”$XWjP‹„$`Q‹Œ$XRPVSQUèƒÄ(…Àt _^][Ä0ËŒ$X‹A|…À„-ÿÿÿ‹œ$L;ë†%ÿÿÿ‹„$X¹‰H\‹P|;ÑŽ ÿÿÿ‹”$P_^‰œ]¸ôÿÿÿ[Ä0Ã;ß‹ó}N‹„$X‹\$,‹xlë‹„$X;3ÀºŠE‹ÈƒáÓâÁ芄Ðt ‹D$EF;ð|Ì;l$(‚ÿìÿÿ‹”$h‹´$P‹œ$Tz‹„$`‹Œ$\‹”$XWjP‹„$XQ‹Œ$XRSVPQUèƒÄ(…À… *‹D$(M;ès¹é¢ìÿÿ‹H|…Ét‹;¬$Lv‚¹‰H\‹P|;ÑŽoÿÿÿ‹Œ$P_^‰ˆœ]¸ôÿÿÿ[Ä0ËF|…À„Æ;¬$L†¹¸‰F\‹N|;Èަ‹„$P_‰†œ^]¸ôÿÿÿ[Ä0ËD$(…À„(‹„$h‹Œ$`‹”$\‹´$X‹ßx‹„$TWjQ‹Œ$\R‹”$\VP‹„$`QRPUèƒÄ(…À…¦);\$;nlƒAÿÿÿ‹L$ 3ÀŠEE…ÉtH=ÀrA‹È3Òƒá?Š‘‹4• RÑá#ðÓæ‹Æ‹òJ…ö~rŠUƒéƒâ?Óâ ÂENuï‹´$X‹L$,QPèƒÄ…À„‹”$`‹„$\‹Œ$TWjR‹”$\P‹„$\VQ‹Œ$`RPQUCèƒÄ(…À„;ÿÿÿ_^][Ä0ËD$‰l$(;ø‹ßŠ‹„$X¾;hlƒ<3ÀŠE‹ø‹D$ …ÀtEÿÀr=‹Ï3Òƒá?Š‘‹ò‹µ vÑá#ÇÓà‹ø¸;ð|Š(ƒéƒâ?Óâ ú@;Æ~îF‹D$,PWèƒÄ…Àt‹D$îC;ØŒvÿÿÿ‹œ$L‹”$h‹„$`‹Œ$\‹¼$Pr‹”$XVjP‹„$`Q‹Œ$XRPWSQUèƒÄ(…À…ä'‹D$(‹ÕM;Є³‹D$ …ÀtŠE$À<€u ŠMÿM€áÀ€ù€tô‹”$`‹„$\‹Œ$XVjR‹”$`P‹„$XQRWSPUèƒÄ(…Àtš_^][Ä0ËH|…É„.ÿÿÿ‹œ$L;ë†&ÿÿÿ‹„$X¹‰H\‹P|;ÑŽ ÿÿÿ‹Œ$P_^‰ˆœ]¸ôÿÿÿ[Ä0ËŒ$X3À‰¹œ_^][Ä0ËF|…À„};nl‚t;¬$L†g¸‰F\‹N|;ÈŽT‹”$P_‰–œ^]¸ôÿÿÿ[Ä0ËH|…É„ ;¬$L†ý Ç@\‹H|ƒùéÌ ‹A|…À„ª ;il‚¡ ;¬$L†” ¸‰A\‹Q|;ÐŽ ‹„$P_^‰œ]¸ôÿÿÿ[Ä0ËA|…À„I ;¬$L†< ÇA\‹A|ƒøé ‹„$h‹Œ$`‹”$\‹´$X‰\$X‹„$TSjQ‹Œ$\R‹”$\VP‹„$`QRPUèƒÄ(…À…¸%ë‹´$X‹L$‹D$;ȯ‹Fl‹t$0‹Ð+Ö;êw‹|$$‹Î‹õ3Òó¦u‹D$0ë*‹L$…ÉŽš+Á;è‡|$X‹õ3Àó¦…€‹D$‹T$‹Œ$`è‹„$XBS‰T$‹”$`jQ‹Œ$`R‹”$`P‹„$`Q‹Œ$`RPQUèƒÄ(…À„Eÿÿÿ_^][Ä0Ë”$P_‰–œ^]3À[Ä0Ë„$X‹H|…Ét:;hlr5;¬$Lv,¹‰H\‹P|;Ñ~‹Œ$P_^‰ˆœ]¸ôÿÿÿ[Ä0Ë”$P_^‰œ]3À[Ä0Éžœ_^]3À[Ä0Ë„$h‹Œ$`‹”$\‹´$X‹ûX‹„$TSjQ‹Œ$\R‹”$\VP‹„$`QRPUèƒÄ(…À… $;|$”;nlƒ5‹V03ÉŠM3ÀEŠ ‹L$;È…q‹Œ$`‹”$\‹„$TSjQ‹Œ$\R‹”$\VP‹„$`QRPUGèƒÄ(…Àt‘_^][Ä0ËŒ$h‹”$`‹„$\‹´$X‰\$Y‹Œ$TSjR‹”$\P‹„$\VQ‹Œ$`RPQUèƒÄ(…À…5#‹T$‹D$;к;nls_3ÀŠEE;ø…§‹Œ$`‹„$TBS‰T$‹”$`jQ‹Œ$\R‹”$\VP‹„$`QRPUèƒÄ(…Àt—_^][Ä0ËF|…Àt5;¬$Lv,¸‰F\‹N|;È~‹”$P_‰–œ^]¸ôÿÿÿ[Ä0Ë„$P_‰†œ^]3À[Ä0ËŒ$P_‰Žœ^]3À[Ä0ËC|…Àt5;¬$Lv,¸‰C\‹K|;È~‹„$P_^‰ƒœ]¸ôÿÿÿ[Ä0ËŒ$P_^‰‹œ]3À[Ä0Ë”$P_^‰“œ]3À[Ä0Ë„$P_^‰ƒœ]3À[Ä0ËŒ$X‹A|…Àt5;¬$Lv,¸‰A\‹Q|;Ð~‹”$P_^]‰‘œ¸ôÿÿÿ[Ä0Ë„$P_^‰œ]3À[Ä0Ë”$X‹Œ$P_^]‰Šœ3À[Ä0Ë„$X‹H|…Ét5;¬$Lv,¹‰H\‹P|;Ñ~‹Œ$P_^‰ˆœ]¸ôÿÿÿ[Ä0Ë”$P_^‰œ]3À[Ä0ËD$ …À„%‹”$h‹„$`‹Œ$\‹¼$X‹Þr‹”$TVjP‹„$\Q‹Œ$\WR‹”$`PQRUèƒÄ(…À…ˆ ;\$%;olƒµ3ÀŠEE=ÀrA‹È3Òƒá?Š‘‹<• RÑá#øÓç‹Ç‹úJ…ÿ~zŠUƒéƒâ?Óâ ÂEOu$X=s ‹O03ÒŠ‹Â9D$„³‹„$`‹Œ$\‹”$TVjP‹„$\Q‹Œ$\WR‹”$`PQRUCèƒÄ(…À„>ÿÿÿ_^][Ä0ËŒ$h‹”$`‹„$\‹œ$Py‹Œ$XWjR‹”$`P‹„$\Q‹Œ$\RSPQUèƒÄ(…À…e;t$}s‹„$X;hlƒàñÿÿ‹@03ÒŠU3ÉEŠ ‹D$;Átg‹”$`‹„$\‹Œ$XWjR‹”$`P‹„$\Q‹Œ$\RSPQUFèƒÄ(…Àt’_^][Ä0Ë”$X_^]‰šœ3À[Ä0Ë„$X_^‰˜œ]3À[Ä0ËB|…Àt5;¬$Lv,¸‰B\‹J|;È~‹„$P_^‰‚œ]¸ôÿÿÿ[Ä0ËŒ$P_^]‰Šœ3À[Ä0Ë„$P_^‰‚œ]3À[Ä0ËD$ …À„‹Œ$h‹”$`‹„$\‹¼$X‹Þq‹Œ$TVjR‹”$\P‹„$\WQ‹Œ$`RPQUèƒÄ(…À…ä;\$;olƒ3ÀŠEE=ÀrC‹Ð3Ƀâ?ŠŠ‹Ñ‹<• RÑá#øÓç‹Ç‹úJ…ÿ~zŠUƒéƒâ?Óâ ÂEOu$X9D$„‹„$`‹Œ$\‹”$TVjP‹„$\Q‹Œ$\WR‹”$`PQRUCèƒÄ(…À„Mÿÿÿ_^][Ä0ËŒ$h‹”$`‹„$\‹œ$Py‹Œ$XWjR‹”$`P‹„$\Q‹Œ$\RSPQUèƒÄ(…À…ЋD$;ð‹„$Xòýÿÿ;hlƒEïÿÿ‹L$3ÒŠUE;Ê„×ýÿÿ‹„$`‹Œ$\‹”$XWjP‹„$`Q‹Œ$\R‹”$\PSQRUFèƒÄ(…Àt_^][Ä0Ë„$X‹”$P_^‰œ]3À[Ä0Ë„$X‹H|…É„Ý;¬$L†Ð¹‰H\‹P|;Ñ޽‹Œ$P_^‰ˆœ]¸ôÿÿÿ[Ä0Ë„$X‹H|…Ét5;¬$Lv,¹‰H\‹P|;Ñ~‹”$P_^‰œ]¸ôÿÿÿ[Ä0ËŒ$P_^‰ˆœ]3À[Ä0Ë„$X‹H|…Ét5;¬$Lv,¹‰H\‹P|;Ñ~‹Œ$P_^‰ˆœ]¸ôÿÿÿ[Ä0Ë”$P_^‰œ]3À[Ä0ËŒ$X‹A|…Àt5;¬$Lv,¸‰A\‹Q|;Ð~‹„$P_^‰œ]¸ôÿÿÿ[Ä0Ë”$P_^]‰‘œ3À[Ä0ËG|…À„Õÿÿ;¬$L†Õÿÿ¸‰G\‹O|;ÈŽýÔÿÿ‹”$P¸ôÿÿÿ‰—œ_^][Ä0ËŒ$P3À‰œ_^][Ä0ËŒ$X‹A|…Àt5;¬$Lv,¸‰A\‹Q|;Ð~‹„$P_^‰œ]¸ôÿÿÿ[Ä0Ë”$P_^]‰‘œ3À[Ä0ËŒ$X‹A|…À„È;¬$L†»¸‰A\‹Q|;Ðލ‹”$P_^]‰‘œ¸ôÿÿÿ[Ä0ËG|…À„Ñèÿÿ;¬$L†Äèÿÿ¸‰G\‹O|;Èޱèÿÿ‹Œ$P¸ôÿÿÿ‰œ_^][Ä0ËŒ$X‹A|…Àt5;¬$Lv,¸‰A\‹Q|;Ð~‹”$P_^]‰‘œ¸ôÿÿÿ[Ä0Ë„$P_^‰œ]3À[Ä0ËŒ$X‹A|…Àt5;¬$Lv,¸‰A\‹Q|;Ð~‹„$P_^‰œ]¸ôÿÿÿ[Ä0Ë”$P_^]‰‘œ3À[Ä0ËD$0…ÀŒLƒø‡/åÿÿÿ$…‹”$h‹„$`‹Œ$\‹´$Xz‹”$TWj‹\$ P‹„$\Q‹Œ$\VR‹”$`PQRUèƒÄ(…À…H;\$½;nlƒÎ3ÀŠEE‹ð‹D$ …Àt@þÀr8‹Î3Àƒá?Š‹… @Ñá#Ö‹ðÓâH…ö~pŠEƒéƒà?Óà ÐENuï‹D$4…À…>äÿÿ‹Œ$`‹”$\‹´$X‹„$TWjQ‹Œ$\R‹”$\VP‹„$`QRPUCèƒÄ(…À„Dÿÿÿ_^][Ä0ËŒ$P_‰Žœ^]3À[Ä0ËF|…À„Ü ;¬$L†Ï ¸‰F\‹N|;È޼ ‹”$P_‰–œ^]¸ôÿÿÿ[Ä0ËŒ$h‹D$‹”$`‹¼$X‹´$PY‹Œ$T‰D$‹„$\SjR‹”$XP‹„$XWQVRPUèƒÄ(…À…Áë‹´$P‹L$‹D$;È?;olƒ‹L$ 3ÀŠEE…ÉtN=ÀrG‹Ð3Ƀâ?ŠŠ‹Ñ‹ •4R#ÈÑæ‹Á‹ÎÓà‹ÊJ…É~zŠUƒîƒâ?‹ÎÓâ ÂEOu틼$X‹È3ÒÁéƒàŠ‘3ÉÁâÐ3Àf‹UŠ Å‹Áƒø tƒøt ƒøt3Àë¸;D$4„åÿÿ‹T$‹„$\‹Œ$TB‰T$‹”$`SjR‹”$\P‹„$\WQ‹Œ$`RPQUèƒÄ(…À„êþÿÿ_^][Ä0ËG|…Àt.;¬$Lv%¸‰G\‹O|;È~‰·œ_^]¸ôÿÿÿ[Ä0É·œ_^]3À[Ä0ËŒ$h‹D$‹”$`‹¼$X‹´$PY‹Œ$T‰D$‹„$\SjR‹”$XP‹„$XWQVRPUèƒÄ(…À…øë‹´$P‹L$‹D$;Èvÿÿÿ;olƒ8ÿÿÿ‹L$ 3ÀŠEE…ÉtN=ÀrG‹Ð3Ƀâ?ŠŠ‹Ñ‹ •4R#ÈÑæ‹Á‹ÎÓà‹ÊJ…É~zŠUƒîƒâ?‹ÎÓâ ÂEOu틼$X‹È3ÒÁéƒàŠ‘3ÉÁâÐ3Àf‹U3ÒŠ Å‹‹L$<;Á‹D$4”Â;Є2 ‹Œ$`‹”$\‹„$T‹t$SjQ‹Œ$\R‹”$\WP‹„$`QRFPU‰t$8èƒÄ(…À„ðþÿÿ_^][Ä0Ë„$h‹T$‹Œ$`‹¼$X‹´$PX‹„$T‰T$‹”$\SjQ‹Œ$XR‹”$XWPVQRUèƒÄ(…À…}ë‹´$P‹D$‹L$;Áûýÿÿ;olƒ½ýÿÿ‹L$ 3ÀŠEE…ÉtL=ÀrE‹È3Òƒá?Š‘‹ •4R#ÈÑæ‹Á‹ÎÓà‹ÊJ…É~zŠUƒîƒâ?‹ÎÓâ ÂEOu틼$X‹È3ÒÁéƒà‹t$<Š‘3ÉÁâÐ3Àf‹U3ÒŠ Å‹D$4;ΔÂ;Єi‹T$‹„$`‹Œ$\BSj‰T$‹”$\P‹„$\Q‹Œ$\WR‹”$`PQRUèƒÄ(…À„ùþÿÿ_^][Ä0Ë”$h‹L$‹„$`‹¼$X‹´$PZ‹”$T‰L$‹Œ$\SjP‹„$XQ‹Œ$XWRVPQUèƒÄ(…À… ë‹´$P‹T$‹D$;Љüÿÿ;olƒKüÿÿ‹L$ 3ÀŠEE…ÉtL=ÀrE‹È3Òƒá?Š‘‹ •4R#ÈÑæ‹Á‹ÎÓà‹ÊJ…É~zŠUƒîƒâ?‹ÎÓâ ÂEOu틼$X‹È3ÒÁéƒà‹t$<Š‘3ÉÁâÐ3Àf‹U3ÒŠ Å‹D$4;ΔÂ;Є÷‹T$‹„$`‹Œ$\BSj‰T$‹”$\P‹„$\Q‹Œ$\WR‹”$`PQRUèƒÄ(…À„ùþÿÿ_^][Ä0Ë”$h‹L$‹„$`‹¼$X‹´$PZ‹”$T‰L$‹Œ$\SjP‹„$XQ‹Œ$XWRVPQUèƒÄ(…À…™ë‹´$P‹T$‹D$;Ðûÿÿ;olƒÙúÿÿ‹L$ 3ÀŠEE…ÉtL=ÀrE‹È3Òƒá?Š‘‹ •4R#ÈÑæ‹Á‹ÎÓà‹ÊJ…É~zŠUƒîƒâ?‹ÎÓâ ÂEOu틼$X‹È3ÒÁéƒàŠ‘3ÉÁâÐ3Àf‹UŠ Å‹ƒøt ƒøt3Àë¸;D$4„íÞÿÿ‹T$‹„$\‹Œ$TB‰T$‹”$`SjR‹”$\P‹„$\WQ‹Œ$`RPQUèƒÄ(…À„ìþÿÿ_^][Ä0ËŒ$h‹D$‹”$`‹¼$X‹´$PY‹Œ$T‰D$‹„$\SjR‹”$XP‹„$XWQVRPUèƒÄ(…À…ë‹´$P‹L$‹D$;Șùÿÿ;olƒZùÿÿ‹L$ 3ÀŠEE…ÉtN=ÀrG‹Ð3Ƀâ?ŠŠ‹Ñ‹ •4R#ÈÑæ‹Á‹ÎÓà‹ÊJ…É~zŠUƒîƒâ?‹ÎÓâ ÂEOu틼$X‹È3ÒÁ銑‹ÈÁâƒáÑ3Éf‹ U3Ҋ̓<•tƒø tƒø tƒø t ƒø t3Àë¸;D$4„è‹T$‹„$`‹Œ$\BSj‰T$‹”$\P‹„$\Q‹Œ$\WR‹”$`PQRUèƒÄ(…À„Ûþÿÿ_^][Ä0Ë”$h‹L$‹„$`‹¼$X‹´$PZ‹”$T‰L$‹Œ$\SjP‹„$XQ‹Œ$XWRVPQUèƒÄ(…À…Š ë‹´$P‹T$‹D$;Ðøÿÿ;olƒÊ÷ÿÿ‹L$ 3ÀŠEE…ÉtL=ÀrE‹È3Òƒá?Š‘‹ •4R#ÈÑæ‹Á‹ÎÓà‹ÊJ…É~zŠUƒîƒâ?‹ÎÓâ ÂEOu틼$X‹È3ÒÁ銑‹ÈÁâƒáÑ3Éf‹ U3Ҋ̓<•tƒø tƒø tƒø tƒø t ƒø t3Àë¸;D$4tY‹T$‹„$`‹Œ$\BSj‰T$‹”$\P‹„$\Q‹Œ$\WR‹”$`PQRUèƒÄ(…À„Üþÿÿ_^][Ä0Ë„$P‰‡œ_^]3À[Ä0ËŒ$h‹”$`‹„$\‹´$Xy‹Œ$TWj‹\$ R‹”$\P‹„$\VQ‹Œ$`RPQUèƒÄ(…À…å ;\$[;nlƒü‹L$ 3ÀŠEE…ÉtJ=ÀrC‹Ð3Ƀâ?ŠŠ‹Ñ‹4• RÑá#ðÓæ‹Æ‹òJ…ö~rŠUƒéƒâ?Óâ ÂENuï‹´$X‹È3ÒÁ銑‹ÈÁâƒáÑ3Éf‹ U3ÒŠÍ‹ •ƒùtƒùt ƒø_t3Àë¸;D$4„§‹„$`‹Œ$\‹”$TWjP‹„$\Q‹Œ$\VR‹”$`PQRUCèƒÄ(…À„üþÿÿ_^][Ä0ËF|…Àt5;¬$Lv,¸‰F\‹N|;È~‹Œ$P_‰Žœ^]¸ôÿÿÿ[Ä0Ë”$P_‰–œ^]3À[Ä0Ë„$P_‰†œ^]3À[Ä0Ã|$$…s‹”$h‹L$‹„$`‰L$‹Œ$\Z‹”$XSjP‹„$`Q‹Œ$`R‹”$`P‹„$`QRPUèƒÄ(…À…ý ‹¼$X‹L$‹D$;ÈÙÿÿ‹Gl;è‰D$ƒ™‹L$ 3ÀŠEE…ÉtN=ÀrG‹Ð3Ƀâ?ŠŠ‹Ñ‹ •4R#ÈÑæ‹Á‹ÎÓà‹ÊJ…É~zŠUƒîƒâ?‹ÎÓâ ÂEOu틼$X‹È3ÒÁéƒàŠ‘3ÉÁâÐ3Àf‹UŠ Åƒ<„aØÿÿ;l$ƒ‹D$ ¿…Àu3ÀŠEëI3ÀŠE=Àr=‹Ð3Ƀâ?¾ŠŠ‹ù‹½ Ñá#ÐÓâ;þ‹Â|Š.ƒéƒâ?Óâ ÂF;÷~îG‹È3ÒÁéƒàŠ‘3ÉÁâÐ3Àf‹UŠ Åƒ<u‹D$ï;è‚cÿÿÿ‹L$‹”$`‹„$\‹¼$XASj‰L$‹Œ$\R‹”$\P‹„$\WQ‹Œ$`RPQUèƒÄ(…À„Sþÿÿ_^][Ä0ËG|…Àt5;¬$Lv,¸‰G\‹O|;È~‹„$P‰‡œ_^]¸ôÿÿÿ[Ä0ËŒ$P3À‰œ_^][Ä0ËD$ …À„i‹D$‹Œ$h‹”$`‰D$A‹Œ$X‰D$0P‹„$`jR‹”$`P‹„$`Q‹Œ$`R‹”$`PQRUèƒÄ(…À…z‹œ$X‹¼$P‹D$‹L$;ÁÖ‹Cl;胖ƒ|$$ uO‹K…Ét‹T$ RSRPQUèƒÄ…À…¡ë*‹K+Á;èw!ŠEŠS,:Âuƒù„ƒŠMŠC-:È„u3ÀŠEE=ÀrG‹Ð3Ƀâ?ŠŠ‹Ñ‹ •4R#ÈÑæ‹Á‹ÎÓà‹ÊJ…É~zŠUƒîƒâ?‹ÎÓâ ÂEOu틼$P‹L$$ƒÁúƒù‡Óÿÿÿ$ƒø w5tƒø „o†ôƒø ‡ëë6;klƒU€} …KEéE=…t=' †¾=) ‡³‹C`…À…¨é=w:„–= w„‰ƒø „€ƒø „wéç=€„gé×=_ w,„U= ‚¿= †?=/ „4é¤=0„$é”=w:„‡= w„zƒø „qƒø …óéc=€…ãéS=_ w,„F= ‚Æ= †0=/ …°é =0… é=…w„Žƒø ‚úƒø †|éì=( ‚á=) †aéÑ=…w„ăø ‚Fƒø ‡=é­=( ‚-=) ‡"é’=ƒ‡‹S4ö…ëx=ƒø‹K4ö„ëë^=sW‹S4ö…ÕëH=ƒÈ‹K4ö„»ë.=s'‹S4ö…¥ë=ƒ˜‹K4ö„‹‹T$‹„$`‹Œ$\B‰T$‹T$0R‹”$XjP‹„$XQ‹Œ$XSRWPQUèƒÄ(…À„Züÿÿ_^][Ä0ËC|…Àt.;¬$Lv%¸‰C\‹K|;È~‰»œ_^]¸ôÿÿÿ[Ä0É»œ_^]3À[Ä0Ë„$h‹T$‹Œ$`‹´$P‹œ$Lx‹„$X‰T$‹”$\WjQ‹Œ$`R‹”$XPQVSRUèƒÄ(…À…‹D$‹L$;Èó‹”$X‹Bl;èƒûƒ|$$ uQ‹J…Ét"ƒÂjRPQUè‹”$lƒÄ…À…ÜÄÿÿë(‹J+Á;èwŠE:B,uƒù„ÀÄÿÿŠMŠB-:È„²Äÿÿ‹L$$3ÀŠEƒÁúEƒù‡ Ïÿÿÿ$ƒÀöƒø{‡‰Äÿÿ3ÉŠˆÿ$;jlƒö€} …ìEéæ‹B`…À…VÄÿÿéÖƒø „HÄÿÿƒø „?Äÿÿ= „4Äÿÿé´ƒø „«ƒø „¢= …Äÿÿé’ƒø ‚‰ƒø †ûÃÿÿ=…„ðÃÿÿësƒø ‚åÃÿÿƒø ve=……ÕÃÿÿëX‹J4ö…ÆÃÿÿëI‹J4ö„·Ãÿÿë:‹J4ö…¨Ãÿÿë+‹J4ö„™Ãÿÿë‹J4ö…ŠÃÿÿë ‹J4ö„{Ãÿÿ‹D$‹”$`‹Œ$X@‰D$‹„$\WjR‹”$`P‹„$XQRVSPUèƒÄ(…À„þÿÿ_^][Ä0ËŒ$X_3À‰±œ^][Ä0ËB|…À„Ãÿÿ;ë†üÂÿÿ¸‰B\‹J|;ÈŽéÂÿÿ‰²œ_^]¸ôÿÿÿ[Ä0ËŒ$P_^]‰Šœ¸ôÿÿÿ[Ä0Ã;l$(rs‹Œ$h‹œ$P‹¼$Tq‹”$`‹„$\‹Œ$XVjR‹”$XP‹„$XQWSRPUèƒÄ(M…ÀuF;l$(s¿‹Œ$X_^]‰™œ3À[Ä0Ëœ$P‹Œ$X_^]‰™œ3À[Ä0øûÿÿÿ_^][Ä0Ëÿ  !"#$$$$$$%%&'()*++++++,,-./01MMMMMMMM22345678889:9:;<=>?=>?MMMMM@ABCDEFGHIJKLª±Ñ”®3‘þ"0V ¨  è q iOô—Wê^é¸èÉçÐæ×åTê[é¸èÉçÐæ×å[èlçsæzåíèþçæ åˆRê[éÓêÜéXêaéÙêâé^êgéßêèéfêoéBêIéAêHé0ê7éØêßé„ê‹éÉèÝçìæùÕaåêå&åoå½å*ê3éqè‚ç‰æåÑêÚé è ç$ æ+ åÀ ÉÇ Èå ì i! ©! ð!Ä÷!Ãþ! "É"êÐ"éÐ#¿×#¾Þ#ò# £$ê¬$éä$»K%êT%é>&êG&éÉ&êÐ&é'è/'ç6'æ0( D((ê¤(é)è.)ç5)æF)±„,ê‹,éû- .ž.ê§.é–/êŸ/éÚ0êã0éŽ1ê—1é³3 Ç3Z4¡°4ê·4é05ê75éq5è‚5ç‰5æö5žJ6êQ6éÔ6êÛ6é7è&7ç/7æ:7å¤7ê«7éé7èú7ç8æm8êv8é´8èÅ8çÎ8æ89êA9é{9èŒ9ç“9æš9å:ê :éV:èj:çs:æz:å ;ê;éL;è`;çi;æp;åÿ;ê<é;<èO<çX<æ_<åá<êè<é"=è3=ç:=æA=å‚=ê‹=é½=èÎ=çÕ=æÜ=å">•Y>\?êe?éA@êJ@é7Aê@AéBê&BéÐBêÙBéCê–Cé”E†ÌEkF‚rFüIêJé@JèQJçXJæèJêïJé0KèAKçHKæQKåÎKêÕKéLè'Lç.Læ­Lê´LéõLèMç MæŒMê“MéÐMèáMçèMæïMå¤Nê­NéçNèûNçOæ OåÈOêÑOé PèPç(Pæ/PåùPêQé6QèJQçSQæZQå RêRéORè`RçgRænRå¯Rê¸RéêRèûRçSæ Så€SkÇSfTVêVéêVêñVéXê(Xé!Yê*YéÌYêÕYé{Zê„Zé&[ê/[é\ê \éÔ\êÝ\ém]^¥]«c´cd}dÂd+e‚eTf]f)g2ggÕhZicijjEj {j «j k_kÁk l|lê…lé¶lèÇlçÎlæÕlåm}mémJnänDo©o pqpÔpkqüqZr¼rÌr½sÆs;tDt»tËtCuLuÆuÖuKvTvËvÛvzJz –z{ v{}W}ê^}é ~n~î~•êžéW€»€Ä¾‚þ‚êƒé=ƒ»ƒƒäƒêíƒé„»€„ꄬ†i‡[ˆΈ/‰œ‰Ü‹ŒêŒéžŒÿŒq€Ž¸ŽêÁŽé3”Í“D”_”êf”騔£•ò•êû•é<–èM–çT–æ»–l—»—êÄ—é˜è˜ç˜æ&˜å~˜ç˜6™ê=™é‚™è“™çœ™æð™Yš¨šê¯šéôšè›ç›æb›Ë›œê!œébœèsœçzœæœåáœJ™ê¢éàèôçýæžåqžÚž)Ÿê0ŸénŸè‚Ÿç‹Ÿæ’Ÿå  ¿ êÈ é¡è¡ç¡æ&¡åƒ¡g¢º¢êâé£è£ç£æ#£åf£êo£é¡£è²£ç¹£æÀ£å¤ê¤=¥Ž¥ê—¥éߥ:ž¨O©˜©ñ©-ª+ ª*G«!¬€¬ÿ„¬ñˆ¬ðŒ¬ï¬ë”¬á˜¬àœ¬ß ¬Þ¤¬Ý¨¬Ü¬¬ä°¬ã´¬â¸¬Ö¼¬ÛÀ¬ÚĬÙȬØ̬×ЬËÔ¬ìجíܬýà¬òä¬î謺쬹ð¬°ô¬²ø¬¶ü¬¸­µ­´­³ ­·­©­®­¯­­ ­¬$­«(­ª,­¢0­§4­¨8­¦<­¥@­¤D­£H­ÅL­ÀP­ÊT­NX­ù\­÷`­ód­üh­ûl­úp­øt­Ox­P|­€­ö„­õˆ­MŒ­J­I”­H˜­Gœ­F ­E¤­K¨­L¬­°­ô´­0®Ô4®Ó8®Ò<®Ñ@®ÐD®ÏH®ÎL®ÍP®ÌT®ÇX®Æd®Âh®Át®½x®¼„® ˆ®ŸŒ®œ®›”®š˜®™œ®˜ ®—¤®–¨®¬®s°®r´®q¸®p¼®oÀ®nÄ®mÈ®lÌ®ŒЮ‹Ô®ŠØ®‰Ü®ˆஇä®”讓ì®’ð®ô®ø®‘ü®¯¯Ž¯ ¯y¯x¯w¯v¯u ¯t$¯…(¯„,¯„0¯4¯8¯ƒ<¯}@¯|D¯{H¯zL¯~P¯T¯€X¯دdܯcà¯bä¯aè¯`ì¯_ð¯jô¯iø¯hü¯°°g°f °f°e°e°V°U °T$°S(°R,°Q0°]4°\8°\<°@°D°[H°ZL°YP°XT°WX°C\°B`°Ad°@h°?l°>p°=t°<x°;|°4€°3„°2ˆ°1Œ°0°/”°.˜°.œ°. °¤°¨°9¬°8°°7´°6¸°5¼°#À°"İ!Ȱ ̰аÔ°ذܰà°ä°è°,ì°'ð°&ô°%ø°$ü°±(±)±ˆ±L ‹D$‹T$SU‹H V‹t$W‹‘‹xh‹Hlß‹|$+Ï;ñ~_^]3À[ÃöD$$„4‹HD…É„ø÷;þ‰t$ ƒ73ÒŠG‹êýÀ|;‹Å3Ƀà?Šˆ‹Á‹… @Ñá#ÕÓâ‹ê‹ÐH…Ò~pŠƒéƒà?Óà èGNuð3ÉŠ C‹ñþÀ|7‹Ö3Àƒâ?Š‚‹… @Ñá#ÖÓâ‹ò‹ÐH…Ò~@Šƒéƒâ?Óâ òCHuð;îtB‹Æ3É™ƒâ‹ÖÁøŠˆÁáâ€yJƒÊ€BÊ3Àf‹M‹ ÅÎ;é…ÿþÿÿ;|$ ‚ ÿÿÿ_^]¸[ËÖN…Ò~F‹@03Ò3ÉŠŠ GCŠ8…Ëþÿÿ‹ÎN…Éã_^]¸[ËÖN…Ò~ŠŠGC:Á…¥þÿÿ‹ÖN…Òë_^]¸[Ãkêtéµê¼éøèçæ” .fileþÿgD:\temp\PCRE\pcre-8.10\pcre_exec.c@comp.id6& ÿÿ.drectve(.rdatay{¡_rep_max_rep_min.text  @Ï¢  - ?L ^ q.debug$FäÀLŠ.text±Ì³u®_match $L6286Šn$L6241 $L3683ùx$L4371n¬$L4306«$L4368«$L4366óª$L4364äª$L4362Õª$L4360ƪ$L4358·ª$L4351œª$L4344}ª$L4337[ª$L43309ª$L4328)ª$L4325ª$L8115ü°$L8114 ±$L4319õ©$L8113¼°$L4230b¨$L4300J¨$L42984¨$L4295¨$L4293¨$L4290ê§$L4288Ч$L4281‘§$L4274R§$L4267Φ$L4260J¦$L4249ã¥$L8112|°$L41664 $L4150‹ž$L4134ûœ$L4118|›$L4102 š$L4086˜˜$L4070—$L4054T•$L4051Ñ“$L8111X°$L2380yv$L2378ûu$L2376tu$L2374ót$L2372it$L2370ës$L2368ms$L6057Ls$L2361pr$L2547bh$L7701'c$L2382ûb$L49136b$L4905ãa$L4897~a$L4889a$L4881à`$L4873§`$L4865,`$L4856¡_$L48480_$L4839ã^$L4826v^$L4820'^$L4812q]$L8110°$L4780‘\$L4764¾[$L4747ßZ$L47314Z$L4714…Y$L4698ÚX$L4675ÚW$L4652¦V$L4631ÍU$L4625~U$L4613U$L4590„S$L8109د$L4505©P$L4489|O$L4473WN$L4457@M$L4441aL$L4425‚K$L4409œJ$L4393°I$L4035+I$L4027äH$L4019H$L4011VH$L4003H$L3995ÈG$L3982|G$L39690G$L3956èF$L3943˜F$L3928ŽF$L3941ƒF$L3938vF$L8108L¯$L8107\¯$L39266F$L3918F$L3910˜E$L8106 ¯$L38957E$L3884ÜD$L3875ŽD$L38643D$L3855åC$L3841LC$L3822•B$L3803âA$L3784ü@$L3765@$L3742#?$L3740?$L3730Ê>$L3719&>$L8105Ì®$L3669¼;$L3655Á:$L3641Í9$L3627õ8$L3613*8$L3599a7$L3585‘6$L4377ú5$L8104¨®$L3571í4$L3557^4$L8103„®$L3546°3$L3545}3$L3544S3$L3543&3$L35423$L3541Ú2$L3499ª2$L3348á-$L3347¸-$L3346 -$L3345~-$L3344r-$L3343B-$L3341-$L3313G,‡ $L3206-($L3205($L3204ó'$L3203ç'$L3202º'$L3201²'$L3199'$L3170&$L3124%— $L3091$$L3089Û#$L8102t®$L8101|®$L3044˜#$L29856"$L2983û!$L8100d®$L8099l®$L2967¿!$L2944!$L2942Ë $L8098T®$L8097\®$L2933L $L2907ö$L2904µ$L2902g$L2900$L2898â$L2896´$L2894…$L2892K$L2890$L2888ý$L80960®$L2873V$L2857ª$L2841$L2825$L2809$L27896$L2777±$L27660$L2754«$L2743*$L2731¥$L2720$$L2716$L7656È$L2706f¥¸ËÝï$L2650ô$L2647m$L7650Q$L2634$L2633$L2631Ý$L7649Á$L2622$L2601² $L2597Œ $L2592 $L2587  $L7383~ $L2566V $L2537T $L2525Ä$L6814ì$L5565Þ$L2497¼ $L2490X$L2485Ú$6$L2393µ$L8095€¬$L8094¸­.debug$F.text fò{VD .debug$FO_pcre_exec_pcre_free__pcre_was_newline__pcre_is_newline_pcre_malloc__pcre_valid_utf8__pcre_try_flipped__pcre_default_tables__pcre_ord2utf8__pcre_xclass__pcre_ucp_gentype__pcre_ucd_records__pcre_ucd_stage2__pcre_ucd_stage1__pcre_utf8_table3__pcre_utf8_table4__imp__memmove__pcre_OP_lengths_pcre_callout_match_ref /427 1305905413 100666 27689 ` L‰ÖM†_Ÿ.drectve( .rdata,@0@.textP :Š P`.debug$Fä ô HB.textIþ þT  P`.debug$Fl_|_HB-defaultlib:MSVCRT -defaultlib:OLDNAMES ìÌSƒÈÿUV‰D$D‰D$l‰D$\‹„$ðW‹¼$à3ö3Û©oZ â‰|$P‰\$L‰t$d‰t$l‰t$\t_^]¸ýÿÿÿ[ÄÌÃ;þ„ß‹¬$è;î„Ð9´$„Ë„$ø;Æ‹„$üu;Æ©;Æ}_^]¸ñÿÿÿ[ÄÌü$}_^]¸íÿÿÿ[ÄÌËG ‰t$D‰D$(‹„$ä;ÆtP‹öÁt‹X‰\$LöÁt_^]¸îÿÿÿ[ÄÌÃöÁt_^]¸îÿÿÿ[ÄÌÃöÁt‹P ‰T$DöÁt‹@‰D$(?ERCPtAŒ$ˆ”$´QSRWèƒÄ;ƉD$Pu_^]¸üÿÿÿ[ÄÌÃ;Þt „$ˆ‰D$L‹Œ$ð‹œ$ì4)‹L$P+Fÿ‰T$‰D$h‹A‹ÐÁê ƒâ‰T$‹”$ô÷Âu ¨ÇD$TtÇD$T3Ò3Àf‹Qf‹A¯Ð3Àúf‹A‹T$Ç‹¼$ô‰D$‹„$ð‰l$‰T$ ‰D$,‰|$0‹Q÷Ç€‰T$4u‹A%€t ljD$0÷Çpu‹Aë‹Ç%p=0wMtD…Àt9=t2= uG¸ =ÿÇD$8~W‹ÈÇD$<ÁùˆL$@ˆD$AëL¸ ëÓ¸ ëÌ=@t!=Pt_^]¸éÿÿÿ[ÄÌÃÇD$8ëÇD$8ë ÇD$<ˆD$@‹D$…Àt`‹„$ôöÄ uTSUèƒÄ…À|_^]¸öÿÿÿ[ÄÌË„$ð…À~+;Ã}'3ÀŠƒø~%Àt=Àt_^]¸õÿÿÿ[ÄÌËl$(…íu ½‰l$(‹|$P‹\$T‰l$tf‹O ‹W‹ÁÁèÁêƒàƒâ…Û‰D$|‰T$XuJöÁt,3Àf‹G‹ØÁèƒàãÿƒø‰\$H‰D$lu$3ÀŠ+‰D$Hë…Àu‹D$L…Àt ö@tƒÀ‰D$döÁt)3Àf‹G‹ÈÁèƒàáÿ‰D$\3ÀŠ„)‰L$p‰D$`‹„$ô‹\$%‰„$„ë‹\$‹T$X‹„$„…À…å‹L$…Ò‰Œ$€„%‹D$‹þ…À‹D$ „’;ðƒý‹L$<‹l$8…ít/‹T$L$ uOFëL‹|$d…ÿtD‹l$;õs<‹T$3À»Š‹ÈƒáÓãÁèŠ8„ØuF…Òt;õsŠ€áÀ€ù€uF;õsëï;õrÈ‹D$x‹”$€…À‰T$…©÷„$ô€…˜‹D$L…Àtö@t‹x(‹Ê+Î;Ï‚­‹|$p…ÿ|s‹Â+Æ=è}h‹l$H‹L$h3À…íÀÆ;ÁvS‹L$\…Ét#;ƒu‹l$`3ÉŠ@;Ït);Ít%;ƒ\ëé;ƒR3ÉŠ@;Ït ;ƒAëíH;ƒ6‰D$h‹|$P‹„$‹Œ$‰t$$‹WjƒâjR‹”$P‹„$Q‹Œ$R‹T$0PQVD$ …ÿúÿÿöG …õúÿÿƒùtƒùt ƒ|$<…àúÿÿ‹T$X‹\$FéÚúÿÿ_^]ƒÈÿ[ÄÌøþÿÿÿ_^][ÄÌÃCá;_êŠD†M 3 ¸˜^èSUV‹´$¨^‹¬$À^W‹F‹N‹‰D$H‹„$À^‰L$<‹N$þ‰T$L‹”$Ð^Áé ‰„$À^‹„$È^ƒáBƒè‰”$Ð^‹Ð}ƒâ‰|$d+‹VÁè‰T$D‹ÐÁâ׋¼$°^‰L$@‰„$È^ŠÇD$\ÿÿÿÿ€û_ÇD$t €ûbt3À븀|8\…/3À‰D$X3ÛŠŠ_;؉\$X~‹Ã3ÛŠŠ_û€?Tt߅ɉD$X„¹‹¼$´^3Û…À‰\$P~.‹L$H;ùvO;ùvŠ$À<€uO;ùwó‹D$XC;Ø|á‰\$P‰¼$´^;~ s‰~ ‹´$°^J3ÀŠfŠF;ÃG‹|$‹ßG‰|$‹¼$È^;ß}u‹|$L‹\$P+þÇAüƒï‰yø‹¼$Ì^‰9‹û+ø‰y‹¼$´^ƒÁ3ÀŠfŠFð€>T…똋¼$´^‹L$H‹ß+Ø;Ùs‹ß+Ù‰\$P+ûé]ÿÿÿ‹Ø‰\$P+ûéPÿÿÿ‰t$l¸íÿÿÿ_^][Ę^Ë„$Ð^‹ÏƒøuN÷FtE3ÀŠaŠAÈ€9Ttñ‹E‰L$l‹M…À‰L$…Š‹t$d‹úÁá‹ÁÁéó¥‹Èƒá󤋼$´^ëw€û_t €ûbt3À븃Àr‹|$‹ßG‰|$‹¼$È^;ßaÿÿÿ‹\$LÇFü+ÃÆÁ‰Fè‹„$Ì^‰Fð3ÀŠaŠAȸ‰L$l€9Tt¯‹¼$´^ë‰t$l‹ÏÇE‰L$ ‹t$‹|$d3ۋ‹U‰\$X‰\$t‰\$‹Þ‰D$dÁãØ‹D$<ƒò;ȉ|$p‰t$‰U‰u‰\$ƒŠ‹T$@¸…Ò‰D$htq3ÒŠ‹êýÀ‰l$Trt‹Å3Òƒà?ЉT$8‹•4RÑæ#Å‹ÎÓà‹è¸;Љl$T| ‹L$ ƒîŠ‹Îƒâ?Óâ ê‹T$8@;Â~ä‰l$T‹t$B‰D$hë3ÒŠ‹êë 3ÀƒÍÿ‰D$h‰l$T3É…ö‰L$PŽA‹t$dÁáΉL$$‹1‹Q…ö‰t$‰”$Ì^}N‹Q …Ò~?‹T$‹òB‰T$‹”$È^;òâýÿÿ‹T$‰‹Q‰W‹”$Ì^‰W‹I I‰O ƒÇéC@÷Þ‰t$‰1‹T$PÇD$4…Ò~:‹T$dë‹T$8‹t$92u ‹r;q„@‹t$4ƒÂ‰T$8‹T$PF;ò‰t$4|Ћt$‹T$Lò3Ò…ÀЉT$,uŠŠ„ÉtÇD$tŠŠ„Ɇ#‹T$@ÇD$0…Ò„ªáÿ3ÒΉL$`Š‹ÊùÀ‰L$(‚™ƒá?3ÒŠ‘‹Ê‰L$8IÑâ‰T$0‹‹L$(#Ñ‹L$0Óâ‹Ê‹T$8ƒú‰L$(|E‹L$`‰T$`A‰L$4‹T$4‹L$0ƒéЉL$0ƒâ?Óâ‹L$( Ê‹T$4B‰L$(‰T$4‹T$`J‰T$`uÌ‹T$8B‰T$0ëáÿ3ÒŠ1‹Ê‰L$(‹T$,ƒú9|[ƒÁòƒùwSÿ$Â,‰T$,ë@ÂT‰T$,ë4Â@‰T$,ë(Âh‰T$,ëÂ|‰T$,ëÇD$0ÇD$(ÿÿÿÿJÿùÀ‡´>3ÒŠ‘ÿ$•;t$lty‹L$‹”$È^‹ÁA;‰L$Èûÿÿ‹D$‹¬$Ì^ÇC‰kP‰‹T$,ƒÃƒúU‰\$„>‹ÑA‰L$‹Œ$È^;Ñ„ûÿÿ3ÉŠnŠNÇC+Á‰k‰éà=‹”$´^‹D$ ;Âw+‹Œ$¬^‹AöÄ…Å=©t‹A‹t$HÆ;І­=‹D$\…À} ‹Œ$À^3ÀƒùÀ‰D$\…Àu(‹Œ$À^ë"~ñ‹´$À^@‰D$\ ;Î|Þ3À‹Î‰D$\ë ƒÁþ…É~(‹„$¼^RPƒÀPÿ‹”$À^‹D$hƒÄ ƒ¼$À^|‹Œ$¼^‹ò‹T$H+ò‰1‹t$ +ò‰q‹Œ$¬^÷A…ƒúÿÿé÷<3ÒŠvŠVò€>Ttñ‹D$‹È@‰D$‹„$È^;ÈPúÿÿ‹L$L‹”$Ì^+ñÇC‰3‰Sé©<‹l$L‹„$Ì^‹L$‹ÑA‰L$‹Œ$È^;Ñ úÿÿ‹Î3Ò+ÍÇCƒÁ‰C‰ ŠvŠVƒÃò‰\$€>Tt½é]<‹D$‹È@‰D$‹„$È^;ÈÅùÿÿ‹l$L‹„$Ì^‹Ö3É+ÕÇCƒÂ‰C‰ŠnŠNƒÃñ‰\$€>T… <‹L$‹ÑA‰L$‹Œ$È^;Ñsùÿÿ‹Î3Ò+ÍÇCƒÁ‰C‰ ŠvŠVƒÃò‰\$€>Tt½éÃ;‹l$‹Œ$È^‹ÅE;Á/ùÿÿ‹L$‹„$Ì^A3Ò‰ 3ɉK‰CŠvƒÃŠVt€>Tu3ÒŠvŠVò€>Ttñ‹ÕE‰l$‹¬$È^;Õàøÿÿ‹l$L‰K+õƒÆ‰3éA;3ÀŠfŠFt€>Tu3ÉŠnŠNñ€>Ttñ‹D$‹Ð@‰D$‹„$È^;Гøÿÿ+t$LƒÆ‰3éë:‹t$ ‹D$H;ðu‹Œ$¬^öA€„”ŠŒ$Ì^‹„$¬^öÁ„Ï:;t$<„Å:‹H …Ét3‹@;ð†³:‹T$@R‹”$°^ƒÂ$RP‹D$,QPèƒÄ…Àu>é‹:‹h$‹P‹ÍÊ;ñ‚y:ŠH(+õŠ:Ñ…j:ƒýt‹Œ$¬^ŠF:A)…R:‹D$‹Ð@‰D$‹„$È^;к÷ÿÿ‹D$‹Œ$Ì^@ÇC‰‰Ké:‹T$<‹D$ ;‚ :é#‹L$3ÀŠF‹ÑA‰L$‹Œ$È^;Ñi÷ÿÿ‹L$ÇCƒÁ‰ éÈ9‹T$H‹D$ ;ÂéÚ‹Œ$¸^‹T$H‹D$ Ñ;ÂéÂ…ÀŽ£9‹„$¬^‹H …Ét;‹@‹T$ ;ЃT(‹T$@R‹”$°^ƒÂ$RP‹D$,QPèƒÄ…À…_9é((‹p$‹H‹l$ +Î;é‡(ŠUŠH(:Ñ…(ƒþ„/9ŠMŠP):Ê„!9éê'…ÀŽ9éÝ'…À„$‹„$¬^‹H …Ét7‹@‹T$ ;Ѓê8‹”$¬^r$‹T$@RVP‹D$,QPèƒÄ…ÀuGéÂ8‹h$‹P‹L$ p$+Õ;ʇ«8Š ŠP(:Ê…ž8ƒýt‹T$ ‹Œ$¬^ŠBŠQ):Â…€8‹T$<‹‹D$ +Ñ;Âé„‹Œ$¬^‹QöÆ…µ…À„o‹Áö@ …F8‹H …Ét7‹@‹T$ ;Ѓ08‹”$¬^r$‹T$@RVP‹D$,QPèƒÄ…ÀuGé8‹h$‹P‹L$ p$+Õ;ʇñ7Š ŠP(:Ê…ä7ƒýt‹T$ ‹Œ$¬^ŠBŠQ):Â…Æ7ö„$Ì^…Õ‹T$<‹‹D$ +Ñ;Âé¼ö„$Ì^„—7‹A …Àt;‹I‹T$ ;у7‹T$@R‹”$°^ƒÂ$RQP‹D$0PèƒÄ…À…wéU7‹q$‹Q‹l$ +Ö;ê‡A7ŠEŠQ(:Â…37ƒþ„G‹„$¬^‹ÍŠQŠH):Ñé+…ÀŽ 7ýƒ7‹L$D‹D$,Š”)@Šˆ"ÑŠˆ2Ñ„Û6‹D$‹È@‰D$‹„$È^;ÈCôÿÿ‹T$Béz…Àޝ6ýsÌ륋D$ ‹L$H;Á† ‹Œ$¬^H‰D$8;A s‰A ‹l$@…ítŠ€áÀ€ù€uŠPÿH€âÀ€ú€tô‰D$83ÉŠ…í‹ñtTþÀrL‹Ö3Àƒâ?Š‚‹Ð‰T$`‹•,RÑå#Æ‹ÍÓà‹ð¸;Ð|‹L$8ƒíŠ‹Íƒâ?Óâ‹L$` ò@;Á~ä‹„$¬^÷@ tLƒþ_u¾ë_‹Î3ÒÁéƒæ3ÀŠ‘3ÉÁâÖf‹UŠ Å‹ƒøtƒøu$¾ëþs‹T$Dö„@t¾ë3ö‹D$h…À~~‹„$¬^‹H‹D$T÷Á tLƒø_u¸ë^‹È3ÒÁéƒàŠ‘3ÉÁâÐ3Àf‹UŠ Å‹ƒøtƒøu#¸ë=s‹T$Dö„@t¸ë3À3É;ð‹t$,”Á3Òƒþ”Â;Ê…ã4‹D$‹È@‰D$‹„$È^;ÈKòÿÿ‹T$Bé¥4…ÀŽ·4‹Í3ÒÁé‹ÅŠ‘ƒàÁâÐ3Éf‹ UÍ3ÉŠNƒù‡ÿ$¸éþŠ@< tï<të<éÖ3Ò3ÉŠP3ÀŠF9•”Á‹ÁéÏŠPŠN3À:Ñ”À齊ŠV3É:”Á‹Áéª3ÒŠP‹•ƒøt‘ƒøë~3ÉŠHƒ<„yÿÿÿƒý „pÿÿÿƒý „gÿÿÿƒý „^ÿÿÿƒý ëK3ÒŠPƒ<•„Fÿÿÿƒý „=ÿÿÿƒý „4ÿÿÿƒý ëÂ3ÉŠH‹ƒø„ÿÿÿƒø„ÿÿÿƒý_„ÿÿÿ3Àë ‹L$,3Àƒù•À‹t$,3Òƒþ”Â;Â…^3‹D$‹È@‰D$‹„$È^;ÈÆðÿÿ‹T$ƒÂ‹„$Ì^‰ÇG‰GƒÇé"3‹L$$‹Q…Ò‰T$$~;‹L$‹ñA‰L$‹Œ$È^;ñ{ðÿÿ‹L$ÇCƒÁ‰ ‹Œ$Ì^‰KƒÃ‰\$…ÀŽÐ2‹D$(ýr ƒø„»2ƒø „²2ƒø …£é¤2ƒø ut‹„$¬^‹H …Ét2‹@‹t$ ;ðs[‹T$@R‹”$°^ƒÂ$RP‹ÆQPèƒÄ…À…a2ë0‹p$‹H+Î9L$ w&‹L$ Š:P(uƒþ„=2ŠIŠP):Ê„/2‹T$$‹D$D‹t$(ŠŒ(@І"ÈŠ†2È„2…Ò~ƒ|$,Cu‹L$Iƒë‰L$‰\$‹D$‹È@‰D$‹„$È^;ÈSïÿÿ‹D$‹Œ$Ì^B‰‰W‰OƒÇéµ1‹L$‹ÑA‰L$‹Œ$È^;Ñïÿÿ‹L$‹”$Ì^ƒÁÇC‰ ‰SƒÃ‰L$8…À‰\$Žn1‹D$(ýr ƒø„Y1ƒø „P1ƒø …¥éB1ƒø ur‹„$¬^‹H …Ét4‹@‹T$ ;ÐsY‹T$@R‹”$°^ƒÂ$RP‹D$,QPèƒÄ…À…ý0ë0‹p$‹H‹T$ +Î;Ñw ‹ÊŠ:P(uƒþ„Ù0ŠIŠP):Ê„Ë0‹T$D‹D$(ŠŒ*@Š"ÊŠ2Ê„¦0‹L$8ƒ|$,Du‹T$Jƒë‰T$‰\$‹D$‹Ð@‰D$‹„$È^;Ðóíÿÿ‹„$Ì^‰ÇG‰GƒÇéV0‹L$‹ÑA‰L$‹Œ$È^;Ѿíÿÿ‹L$‹”$Ì^ƒÁÇC‰ ‰SƒÃ…À‰\$Ž0‹D$(ýr ƒø„þ/ƒø „õ/ƒø …¡éç/ƒø ur‹„$¬^‹H …Ét4‹@‹T$ ;ÐsY‹T$@R‹”$°^ƒÂ$RP‹D$,QPèƒÄ…À…¢/ë0‹p$‹H‹T$ +Î;Ñw ‹ÊŠ:P(uƒþ„~/ŠIŠP):Ê„p/‹T$D‹D$(ŠŒ*@Š"ÊŠ2Ê„K/ƒ|$,Bu‹L$Iƒë‰L$‰\$‹D$‹Ð@‰D$‹„$È^;Мìÿÿ‹D$éþ‹T$$…À‹R‰T$$Žþ.‹D$(ýr ƒø„é.ƒø „à.ƒø …¢éÒ.ƒø us‹„$¬^‹H …Ét2‹@9D$ s\‹T$@R‹”$°^ƒÂ$RP‹D$,QPèƒÄ…À….ë/‹H$‹P+Ñ‹L$ ;ÊwŠ:P(uƒx$„l.ŠIŠP):Ê„^.‹T$$‹D$DŠŒ(@‹l$(Š…"ÈŠ…2È„5.3ÀBŠfŠF;ЋD$‹ÈŒm@‰D$‹„$È^;ÈŒëÿÿ‹T$ƒÂéÁúÿÿ‹L$‹ÑA‰L$‹Œ$È^;Ñfëÿÿ‹”$Ì^‹L$‰S‹T$$ƒÁÇC‰ ‹RƒÃ‰L$8…À‰\$‰T$$ެ-‹D$(ýr ƒø„—-ƒø „Ž-ƒø …¦é€-ƒø us‹„$¬^‹H …Ét2‹@9D$ s\‹T$@R‹”$°^ƒÂ$RP‹D$,QPèƒÄ…À…=-ë/‹H$‹P+Ñ‹L$ ;ÊwŠ:P(uƒx$„-ŠIŠP):Ê„ -‹T$$‹D$DŠŒ(@‹l$(Š…"ÈŠ…2È„ã,‹L$8ƒ|$,Eu‹l$Mƒë‰l$‰\$3ÀBŠfŠF;ЋD$,üÿÿ‹È@‰D$‹„$È^;Èêÿÿ‹D$‹Œ$Ì^‰‰W‰OƒÇé‚,‹T$$‹R…Ò‰T$$~?‹L$‹ÑA‰L$‹Œ$È^;ÑÛéÿÿ‹L$‹”$Ì^ƒÁÇC‰ ‰S‹T$$ƒÃ‰\$…ÀŽ,,‹Å3ÉÁ芈‹ÅÁáƒàÈ3Àf‹M3ÉŠNƒùŇÿ$¸éüŠ@< tï<të<éÔ3ÉŠH3ÀŠF‹é3É9­”Á‹ÁéËŠH3À:N”À黊3É:F”Á‹Áéª3ÉŠH‹ƒøt“ƒøë~3ÉŠHƒ<„{ÿÿÿƒý „rÿÿÿƒý „iÿÿÿƒý „`ÿÿÿƒý ëK3ÉŠHƒ<„Hÿÿÿƒý „?ÿÿÿƒý „6ÿÿÿƒý ëÂ3ÉŠH‹ƒø„ÿÿÿƒø„ÿÿÿƒý_„ ÿÿÿ3Àë ‹L$,3Àƒù•À‹l$(3Ƀý”Á;Á…Õ*…Ò~|$,ou‹L$Iƒë‰L$‰\$‹D$‹È@‰D$‹„$È^;Èèÿÿ‹D$‹Œ$Ì^B‰‰W‰OƒÇé*‹T$$‹r…ö‰t$$~;‹L$‹ÑA‰L$‹Œ$È^;ÑÚçÿÿ‹L$‹”$Ì^ƒÁÇC‰ ‰SƒÃ‰\$…ÀŽ/*‹Í3ÒÁéƒåŠ‘3ÉÁâÕf‹ U3Ҋ̓<•„ù)‹L$ ÇD$0…ö,‰l$4~|$,ƒu‹L$Iƒë‰L$‰\$;l$<ƒ½3Ò¹ŠU‹òþÀ|H‹Æ3Ƀà?Šˆ¸‹é‹­LmÑá#ÖÓâ;è‹ò|‹T$4ƒéŠƒâ?Óâ ò@;Å~êM‹l$4‹Æ™ƒâÂ3ÒÁøŠÁâæ€yNƒÎ€FÖ3Àf‹U3ҊŃ<•u‹t$0‹D$<éF;è‰t$0‰l$4‚Gÿÿÿ‹t$$‹D$‹È@‰D$‹„$È^;Èiæÿÿ‹D$‹”$Ì^÷؉‹D$0F‰W‰w‰G ƒÇéÂ(‹L$$‹q…ö~>‹L$‹ÑA‰L$‹Œ$È^;Ñæÿÿ‹L$ÇCƒÃQ‰\$‰Sð‹”$Ì^‰Søë‹L$…ÀŽm(3Òƒý w0tƒý t]†Y(ƒý v>éO(‹D$ ‹l$<@;Ås@€8 u;ºë4ý…tý' †"(ý) ‡(‹„$¬^÷@€…(…ö~|$,—u‹l$Mƒë‰l$‰\$‹D$‹è@‰D$‹„$È^;èLåÿÿ÷Ù‰‹Œ$Ì^F‰O‰w‰W ƒÇé­'‹T$$‹R…Ò~>‹L$‹ñA‰L$‹Œ$È^;ñ åÿÿ‹L$ÇCƒÃq‰\$‰sð‹´$Ì^‰søë‹L$…ÀŽX'ý…w„‰ƒý rƒý v3ö‹l$(3Àƒý”À;ð…*'…Ò~|$,¿u‹t$Nƒë‰t$‰\$‹D$‹ð@‰D$‹„$È^;ðtäÿÿ÷Ù‰‹Œ$Ì^B‰O‰WÇG ƒÇéÑ&ý( r‰ý) w¾éyÿÿÿ‹T$$‹J…É~>‹T$‹òB‰T$‹”$È^;òäÿÿ‹t$ÇCƒÃV‰\$‰Sð‹”$Ì^‰Søë‹t$…ÀŽb&ýw&tVý wtLƒý tGƒý tB3ÀëCý€t63Àë7ý_ wt(ý rý vý/ t3Àëý0t3À븋l$(3Òƒý”Â;Â…é%…É~|$,«u‹T$Jƒë‰T$‰\$‹D$‹Ð@‰D$‹„$È^;Ð3ãÿÿ‹„$Ì^ÇG ÷ÞA‰7‰O‰GƒÇé%ÇD$$ëÇD$$‹L$‹ÑA‰L$‹Œ$È^;Ñæâÿÿ‹L$3ÒƒÁ‰S‰ ‹Œ$Ì^‰KƒÃ;‰\$Ž=%‹Å3ÉÁ芈‹ÅÁáƒàÈ3Àf‹M3ÉŠNƒùŇÿ$¸éüŠ@< tï<të<éÔ3ÉŠH3ÀŠF‹é3É9­”Á‹ÁéËŠH3À:N”À黊3É:F”Á‹Áéª3ÉŠH‹ƒøt“ƒøë~3ÉŠHƒ<„{ÿÿÿƒý „rÿÿÿƒý „iÿÿÿƒý „`ÿÿÿƒý ëK3ÉŠHƒ<„Hÿÿÿƒý „?ÿÿÿƒý „6ÿÿÿƒý ëÂ3ÉŠH‹ƒø„ÿÿÿƒø„ÿÿÿƒý_„ ÿÿÿ3Àë ‹L$,3Àƒù•À‹l$(3Ƀý”Á;Á…æ#‹D$,=nt=pu‹L$Iƒë‰L$‰\$‹D$‹È@‰D$‹„$È^;È,áÿÿ‹D$$‹L$Á‰W‹”$Ì^‰‰WƒÇé‰#ÇD$$3öë3ö‰t$$‹L$‹ÑA‰L$‹Œ$È^;Ñßàÿÿ‹L$‹”$Ì^ƒÁ‰s‰ ‰SƒÃ;Ɖ\$Ž8#‹Í3ÒÁéƒåŠ‘3ÉÁâÕf‹ U3Ҋ̓<•„#‹L$ ‰t$0È‹D$,=‚‰L$4t=„u‹T$Jƒë‰T$‰\$;L$<ƒ¶3Ò½Š‹òþÀ|F‹Æ3Ƀà?Šˆ¸‹é‹­LmÑá#ÖÓâ;è‹ò|‹T$4ƒéŠƒâ?Óâ ò@;Å~ê‹L$4E‹Æ™ƒâÂ3ÒÁøŠÁâæ€yNƒÎ€FÖ3Àf‹U3ҊŃ<•u‹t$0‹D$<ÍF;ȉt$0‰L$4‚Jÿÿÿ‹D$‹È@‰D$‹„$È^;Èzßÿÿ‹T$‹D$$‹Œ$Ì^‹T$0ÇG÷؉‰O‰W ƒÇéÊ!ÇD$$ëÇD$$‹L$‹ÑA‰L$‹Œ$È^;Ñ ßÿÿ‹L$ÇCƒÃQ‰\$‰Sð‹”$Ì^‰Sø…ÀŽt!3öƒý w0tƒý t]†`!ƒý v>éV!‹D$ ‹l$<@;Ås@€8 u;¾ë4ý…tý' †)!ý) ‡!‹„$¬^÷@€… !‹D$,=–t=˜u‹l$Mƒë‰l$‰\$‹D$‹è@‰D$‹„$È^;èOÞÿÿ‹D$$ÇGÁ‰W÷؉‰w ƒÇé® ÇD$$ëÇD$$‹L$‹ÑA‰L$‹Œ$È^;ÑÞÿÿ‹t$ÇCƒÃN‰\$‰Kð‹Œ$Ì^‰Kø…ÀŽX ý…w„‰ƒý rƒý v3À‹l$(3Òƒý”Â;Â…* ‹D$,=¾t=Àu‹T$Jƒë‰T$‰\$‹D$‹Ð@‰D$‹„$È^;ÐpÝÿÿ‹D$$‰OÆ÷؉3À‰G‰G ƒÇéÑý( r‰ý) w¸éyÿÿÿÇD$$ëÇD$$‹L$‹ÑA‰L$‹Œ$È^;Ñ Ýÿÿ‹t$ÇCƒÃN‰\$‰Kð‹Œ$Ì^‰Kø…ÀŽaýw&tVý wtLƒý tGƒý tB3ÀëCý€t63Àë7ý_ wt(ý rý vý/ t3Àëý0t3À븋l$(3Òƒý”Â;Â…è‹D$,=ªt=¬u‹T$Jƒë‰T$‰\$‹D$‹Ð@‰D$‹„$È^;Ð.Üÿÿ‹D$$‰OÆ÷؉3À‰G‰G ƒÇé|$,mt>‹L$‹ÑA‰L$‹Œ$È^;ÑíÛÿÿ‹T$ÇCƒÃJ‰\$‰Kð‹Œ$Ì^‰Køë‹T$‹L$$…À‹I‰L$$Ž0‹Å3ÉÁ芈‹ÅÁáƒàÈ3Àf‹M3ÉŠNƒùŇÿ$¸éüŠ@< tï<të<éÔ3ÉŠH3ÀŠF‹é3É9­”Á‹ÁéËŠH3À:N”À黊3É:F”Á‹Áéª3ÉŠH‹ƒøt“ƒøë~3ÉŠHƒ<„{ÿÿÿƒý „rÿÿÿƒý „iÿÿÿƒý „`ÿÿÿƒý ëK3ÉŠHƒ<„Hÿÿÿƒý „?ÿÿÿƒý „6ÿÿÿƒý ëÂ3ÉŠH‹ƒø„ÿÿÿƒø„ÿÿÿƒý_„ ÿÿÿ3Àë ‹L$,3Àƒù•À‹l$(3Ƀý”Á;Á…Ù|$,qu‹L$Iƒë‰L$‰\$‹l$$3ÀŠfEŠF;è‹D$‹È|@‰D$‹„$È^;ÈÚÿÿƒÂ‰éB@‰D$‹„$È^;ÈøÙÿÿ‰‹”$Ì^‰o‰WƒÇé_|$,t;‹L$‹ÑA‰L$‹Œ$È^;ѽÙÿÿ‹L$‹”$Ì^ƒÁÇC‰ ‰SƒÃ‰\$‹L$$…À‹Q‰T$$Ž‹Í3ÒÁéƒåŠ‘3ÉÁâÕf‹ U3Ҋ̓<•„Ñ‹L$ ÇD$(Á‹L$,ù…‰D$0u‹T$Jƒë‰T$‰\$;D$<ƒÆ‹L$03ÒÇD$8Š‹êýÀ|K‹Å3Òƒà?Š‹• RÑá#ÅÓà‹è¸;Ð|‹\$0ƒéŠƒã?Óã ë@;Â~ê‹\$‹L$0B‰T$8‹Å™ƒâÂ3ÒÁøŠÁâå€yMƒÍ€EÕ3Àf‹U3ҊŃ<•u‹T$8‹l$(‹D$<ÊE;ȉl$(‰L$0‚>ÿÿÿ‹L$$3ÀŠfAŠF;È‹D$|C‹È@‰D$‹„$È^;È*Øÿÿ‹L$‹„$Ì^ºüÿÿÿÇG+Ñ‹L$(‰‰G‰O ƒÇé{‹Ð@‰D$‹„$È^;Ðç×ÿÿ‹D$‰O‹L$(÷؉‹„$Ì^‰G‰O ƒÇéA|$,•t>‹L$‹ÑA‰L$‹Œ$È^;ÑŸ×ÿÿ‹L$ÇCƒÃQ‰\$‰Sð‹”$Ì^‰Søë‹L$‹T$$…À‹R‰T$$Žâ3Òƒý w0tƒý t]†Îƒý v>éÄ‹D$ ‹l$<@;Ås@€8 u;ºë4ý…tý' †—ý) ‡‹‹„$¬^÷@€…w|$,™u‹l$Mƒë‰l$‰\$‹l$$3ÀŠfEŠF‹õ;ð‹D$‰l$$‹ð|9@‰D$‹„$È^;ð®Öÿÿ¸üÿÿÿÇG+Á‹Œ$Ì^‰‰O‰W ƒÇé@‰D$‹„$È^;ðuÖÿÿ‹D$$‰W ÷Ù‰‹Œ$Ì^‰G‰OƒÇéÓ|$,½t>‹L$‹ÑA‰L$‹Œ$È^;Ñ1Öÿÿ‹L$ÇCƒÃQ‰\$‰Sð‹”$Ì^‰Søë‹L$‹T$$…À‹RŽxý…‡„¢ƒý r ƒý †”3í3Àƒ|$(”À;è…D|$,Áu‹l$Mƒë‰l$‰\$3ÀBŠfŠF;ЋD$Œ\‹Ð@‰D$‹„$È^;ÐÕÿÿ¸üÿÿÿ+Á‹Œ$Ì^‰3À‰G‰O‰G ƒÇéÜý( ‚xÿÿÿý) ‡lÿÿÿ½édÿÿÿ|$,©t>‹L$‹ÑA‰L$‹Œ$È^;ÑÕÿÿ‹L$ÇCƒÃQ‰\$‰Sð‹”$Ì^‰Søë‹L$‹T$$…À‹RŽ_ýw&tVý wtLƒý tGƒý tB3íëCý€t63íë7ý_ wt(ý rý vý/ t3íëý0t3íë½3Àƒ|$(”À;è…è|$,­u‹l$Mƒë‰l$‰\$3ÀBŠfŠF;ЋD$¤þÿÿ‹ð@‰D$‹„$È^;ð%Ôÿÿ÷Ù‰‰W‹”$Ì^‰WÇG ƒÇ郅ÀŽ{;l$(…q‹D$‹È@‰D$‹„$È^;ÈÙÓÿÿ‹T$0‹D$Léü 3ö;Æ„<9t$@„«‹L$(;éu‹D$‹È@‰D$‹„$È^;È’Óÿÿëcý€s‹T$D3ÀŠ„*ë*‹Å3ÒÁ芋ÅÁâƒàÐ3Àf‹U‹ÅÅ;È…Å‹D$‹È@‰D$‹„$È^;È-Óÿÿ‹T$0‹D$ƒÇL‹”$Ì^‰Oð‰wô‰Wøé‡‹D$D‹T$(Š (: …s‹D$‹È@‰D$‹„$È^;ÈÛÒÿÿ‹T$‹„$Ì^ƒÂ‰w‰‰GƒÇé;…ÀŽ3‹Í3ÒÁéƒåŠ‘3ÉÁâÕf‹ U3Ҋ̓<•„ý‹L$ ÇD$0,‹D$<;è‰l$4ƒ±3À¾ŠE=À‰D$TrO‹Ð3Ƀâ?ŠŠ‹ñ‹µ vÑá#иÓâ;ð‰T$T|Š(‹l$Tƒéƒâ?Óâ ê@‰l$T‹l$4;Æ~â‹D$TF‹È3ÒÁéƒàŠ‘3ÉÁâÐ3Àf‹UŠ Åƒ<u‹T$0‹D$<îB;è‰T$0‰l$4‚Oÿÿÿ‹D$‹Ð@‰D$‹„$È^;ЕÑÿÿ‹L$‹T$0ƒÈÿÇG+Á‹Œ$Ì^‰‰O‰W ƒÇéè3É;ÁŽÞƒý ‡¨tƒý „цăý †®é¶‹D$ ‹T$<@;ÂsF€8 uA‹D$‹Ð@‰D$‹„$È^;Ð Ñÿÿ‹T$ƒÈÿ‰O‹Œ$Ì^+‰O‰ÇG ƒÇéc‹D$‹Ð@‰D$‹„$È^;ÐËÐÿÿ‹D$‰O‹Œ$Ì^@‰‰OƒÇé-ý…tý' †ý) ‡ ‹”$¬^÷B€…ù‹D$‹Ð@‰D$‹„$È^;ÐaÐÿÿ‹D$‰O‹Œ$Ì^@‰‰OƒÇéÃ…ÀŽ»ý…w„­ƒý ‚rƒý †›édý( ‚Xý) †~éG…ÀŽqý…w„1ƒý ‚Zƒý †éLý( ‚@ý) ‡4éý…ÀŽ'ýw<„ý w„ ƒý „ƒý „ùéÂý€„èé±ý_ w,„Õý ‚—ý †½ý/ „±ë}ý0„£ëo…ÀŽ™ýw(t]ý wtSƒý tNƒý tIévý€t<éiý_ w#t-ý ‚Sý vý/ té>ý0…2‹D$‹Ð@‰D$‹„$È^;КÎÿÿ‹D$@‹Œ$Ì^‰ÇG‰OƒÇéø…ÀŽð‹”$Ì^öÂt‹L$(‹t$D3ÀŠ„1ë‹L$(‹Á;é„Ã;è„»‹D$‹È@‰D$‹„$È^;È#Îÿÿ‹D$0‹L$ÇGƒÇD‰Gð‰Wøé€‹L$$‹I…ɉL$$~C‹L$‹ÑA‰L$‹Œ$È^;ÑÙÍÿÿ‹L$0‹T$ÇCƒÃL‹”$Ì^‰Kð‰Sø‰\$ë‹”$Ì^…ÀŽƒÈÿöÂtO‹D$@‹L$(…Àt4ù€r,‹ñ3ÀÁîІ‹ñÁàƒæÆ3öf‹4E‹õÁë‹t$D3ÀŠ„1ë‹L$(;ét;èt3À븋t$,3Ƀþ,œÁ;Á…Ÿ‹L$$…É~ƒþ)tƒþ6u‹t$Nƒë‰t$‰\$‹D$‹ð@‰D$‹„$È^;ðåÌÿÿ‹D$A‰‰O‰WƒÇéN‹L$‹ÑA‰L$‹Œ$È^;ѶÌÿÿ‹L$0‹T$ÇCƒÃt‹Œ$Ì^‰sð‰Kø…À‰\$ŽƒÈÿöÁtO‹D$@‹L$(…Àt4ù€r,‹Á3ÒÁ芋ÁÁâƒàÐ3Àf‹U‹ÅÁë‹T$D3ÀŠ„ë‹L$(;ét;èt3À븋l$,3Ƀý,œÁ;Á……ƒý*tƒý7u‹L$Iƒë‰L$‰\$‹D$‹Ð@‰D$‹„$È^;ÐÓËÿÿ‹„$Ì^‰7ÇG‰GƒÇé6‹L$‹ÑA‰L$‹Œ$È^;ÑžËÿÿ‹L$0‹T$ÇCƒÃL‹”$Ì^‰Kð‰Sø…À‰\$Ží ƒÈÿöÂtO‹D$@‹L$(…Àt4ù€r,‹ñ3ÀÁîІ‹ñÁàƒæÆ3öf‹4E‹õÁë‹t$D3ÀŠ„1ë‹L$(;ét;èt3À븋t$,3Ƀþ,œÁ;Á…m ƒþ(tƒþ5u‹L$Iƒë‰L$‰\$‹D$‹È@‰D$‹„$È^;È»Êÿÿ‹D$ÇG‰‰WƒÇé! ‹L$$…À‹Q‰T$$Ž Š„$Ì^ƒÉÿ¨tV‹D$@…À‹D$(t7=€r0‹Ð3ÉÁꊊ‹ÐÁáƒâÊ3Òf‹M‹ Õ‹T$$Èë‹T$D3ÉŠŒ‹T$$ë‹D$(;èt;ét3À븋l$,3Ƀý,œÁ;Á… 3ÀBŠfŠF;ЋD$‹ÈŒ¹ßÿÿ@‰D$‹„$È^;ÈØÉÿÿ‹T$0‹D$L‰‹”$Ì^ÇG‰WƒÇé/ ‹L$‹ÑA‰L$‹Œ$È^;Ñ—Éÿÿ‹L$0‹T$ÇCƒÃL‹”$Ì^‰L$8‰Kð‹L$$‰Sø…À‹I‰\$‰L$$Ž× ƒÉÿöÂt\‹D$@…À‹D$(t:=€r3‹Ð3ÉÁꊊ‹ÐÁáƒâÊ3Òf‹M‹ Õ‹”$Ì^Èë‹T$D3ÉŠŒ‹”$Ì^ë‹D$(;èt;ét3í뽋D$,3Ƀø,œÁ;é…J ƒø+tƒø8u‹L$Iƒë‰L$‰\$‹l$$3ÀŠfEŠF;è‹D$‹È|,@‰D$‹„$È^;ȇÈÿÿ‹D$8ÇG‰‰WƒÇéí @‰D$‹„$È^;È[Èÿÿ‹D$‰o‰‰WƒÇéÅ ‹L$,ÇD$0ƒùP„Ä…ÀV!~ýÿ†‘3ÀƒùO”À‰D$0‹¬$È^‹´$Ì^‹L$L‹Â+Á3ÉŠ ƒÁºƒù‡Tÿ$‹L$‹ÑA;Õ‰L$ÓÇÿÿ‹L$0@‰3À‰C‰sƒÃ;ȉ\$„3 ‹L$‹ÑA;Õ‰L$¢Çÿÿ‹L$‰G‰‰wƒÇé ‹Í¸ƒáÓàÁíŠL."ÁöØÀ÷ØéWÿÿÿ3ÒŠvŠVÖ…À‰T$8ŽEÿÿÿƒÆVUè‹´$Ô^‹T$@‹¬$Ð^ƒÄ‰D$0é+ÿÿÿ‹T$$‹J…É~6‹T$‹êB‰l$8‹¬$È^‰T$‹T$8;ÕÇÿÿ@ÇC‰‰sƒÃ‰\$‹D$0…À„a ‹D$‹Ð@;Õ‰D$ÐÆÿÿ‹D$A‰‰O‰wƒÇé9 ‹L$‹ÑA;Õ‰L$¨Æÿÿ‹T$0@3ɉ‰K‰sƒÃ;щ\$„ ‹T$‹êB‰T$‹”$È^;êpÆÿÿ‰‰O‰wƒÇéÞ‹L$$‹i3ÉŠj‰l$$ŠJ;é|4‹L$‹éA‰L$‹Œ$È^;é/Æÿÿ‹l$$H‰ ÇC‰sƒÃ‰\$‹L$0…É„‡3ÉEŠjŠJ;é|5…Ét1‹L$‹ÑA‰L$‹Œ$È^;ÑÞÅÿÿƒÀÇG‰‰wƒÇéE‹D$‹È@‰D$‹„$È^;È­Åÿÿ‹T$‰o‰‰wƒÇé‹L$0…É„ ‹L$‹ÑA;Õ‰L$zÅÿÿ‰ÇG‰wƒÇéäÿD$XéÛ3ÀŠfŠFÆ‹è€}Tu3ÉŠmŠMé€}Ttð‹”$Ô^‹„$Ð^‹Œ$Ì^RPQ”$ôhèR‹T$\„$ôjP‹D$<‹È+Ê‹”$È^QPVRèƒÄ,ƒøð„¡‹L$,ƒùXt ƒùZt3öë¾3É…ÀÁ;Î…<‹D$‹Ð@‰D$‹„$È^;ФÄÿÿ+l$LƒÅ‰+éüŠF3ÉŠnTu3ÒŠvŠVò€>Ttñ‹”$Ô^R‹”$Ô^RQŒ$t?hèQ‹L$4”$œhèR‹Ñ+T$dRQP‹„$Ô^PèƒÄ,ƒøð„ƒƒýXt ƒýZt3íë½3É3Ò;Á‹D$Â;Õ‹Ðu'@‰D$‹„$È^;ÐŒÂÿÿ‹l$L‰K+õƒÆ‰3éæ@‰D$‹„$È^;ÐeÂÿÿ‹D$‹T$4‰K‹Œ$Ì^D‰K‰é¼3ÒŠvŠVúÿÿ…þ‹„$Ô^3Ò;‹D$‹ð~(@‰D$‹„$È^;ð Âÿÿ‹D$‰SƒÀ‰K‰ém@‰D$‹„$È^;ðâÁÿÿ‹D$‹t$4‰S‰KD0‰é@‹Œ$Ô^‹”$Ð^‹„$Ì^‹l$HAQRP‹D$,Œ$Ô/hèQ”$< hè‹ÈR+Í3ÒQŠvPŠV‹D$pЋ„$Ð^RPèƒÄ,…À„>ŽâDþ…À‰D$8ŒÉŒ„( ‰L$4‹D$4‹t$H‹‹@ 2ð+Â;΋èsŠ€âÀA€ú€uM;Îrð3É;é~=‹D$‹Ð@‰D$‹„$È^;ÐöÀÿÿ‹T$¸ýÿÿÿ+‹”$Ì^M‰‰O‰W‰o ƒÇë7‹D$‹Ð@‰D$‹„$È^;йÀÿÿ‹D$‹”$Ì^ƒÀ‰K‰‰SƒÃ‰\$‹D$8‹t$4ƒèƒî;Á‰D$8‰t$4>ÿÿÿé÷ƒøÿ…uÀÿÿéé‹„$Ô^‹Œ$Ð^‹”$Ì^PQR„$OhèP‹D$4Œ$ŒjQ‹L$d‹Ð+ÑRP‹„$Ð^VPèƒÄ,…À| ‹T$|‹D$x+ЉT$43ÉŠnŠNñ€>Ttñ‹l$LŠ‹Æ+ŃÀ€ùVt €ùWtƒÍÿë3ÉŠnŠN+ñ+õ‹î3É;Ñu.‹T$‹òB‰T$‹”$È^;ò²¿ÿÿ‹”$Ì^‰‰K‰Sé‹t$PF;t$|q9L$uk‹t$ ‰L$hò‹”$È^;щt$ ÇD$Žh¿ÿÿ‰‹„$Ì^‰O‰GƒÇ;éŒÌ‹ÊÇD$Pÿÿÿÿ…ÉÇD$Ž4¿ÿÿ‹\$d‰+ÇCé–‹L$H‹T$x4 ‹T$|Ê;ñsŠ€âÀF€ú€uÿL$4;ñrí‹L$‹ÑA‰L$‹Œ$È^;Ñà¾ÿÿ‹Œ$Ì^ÇG÷؉‹D$4H‰O‰G ƒÇ…íŒ6‹T$‹òB‰T$‹”$È^;òž¾ÿÿ÷݉/ÇG‰O‰G ƒÇé‹ …É„³‹„$¼^3ÒŠV‰„$¸‹D$H‰”$´‹T$<‰„$¼+퉔$À‹”$´^+Љ¬$°‰”$Ä‹T$ +Ð3ÀŠf‰”$ÈŠF3ÒŠv‰„$ØŠV‹„$¬^‰”$܉¬$Ì‹P,„$°PÇ„$Ôÿÿÿÿ‰”$ØÿуÄ…ÀŒË½ÿÿuB‹D$‹È@‰D$‹„$È^;Ȫ½ÿÿ‹L$3ÒŠSщÇC‹„$Ì^‰CƒÃ‰\$‹D$h‹l$T‹L$P‹t$‹T$pA;ΉL$PŒ=¿ÿÿ‹L$…É~F‹L$ ‹¬$Ä^ȉL$ é3¾ÿÿ_^]¸ðÿÿÿ[Ę^Ã_^]¸ïÿÿÿ[Ę^Ã_^]¸ìÿÿÿ[Ę^ü$Ð^ut‹D$t…Àtl‹”$Ä^‹L$X;Jt\‹”$¬^‹B©u öÄ€tF‹D$\…À}>‹L$ ‹D$<;Èr2;Œ$´^v)ƒ¼$À^|‹r ‹T$H‹Œ$¼^+ò+‰1‰AÇD$\ôÿÿÿ‹D$\_^][Ę^ÃBB BBBBBBBB B!"#$$$%%%%B&'()'()BBBBB**BBBBBBBB+BB,--BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB..//00111./01BBBBBBB2233445552345BBBBBBB6677889996789BBBBBBB::;;<<===:;<=BBBBBBB>>??@@AAA>?@AIœE›Pš‹  æ›üšŒ™ï“ö’Å ò Ž H ÷ q y ›)š‰~˜}Ÿ|¦{~!}(|/{´~Æ}Í|ây{L{b{•{¿{ðF N T¦ ® ¯     i q =~Q}`|miž{Õ{ë{{H{=~L}U|\{¿›Íš ~)}2|9{,~@}O|\Y{Ä{Ú{ {7 {4!~C!}L!|S!{´!›Â!š"~"}%"|,"{9&~M&}\&|i&Fš&{Ñ&{ç&{'{D'{e(~t(}}(|„({ê(›ñ(š;)~W)}`)|g){r.~†.}.|9/~H/}Q/|X/{ /›©/šò/~0} 0|0{f4~z4}4|€5~”5}›5|˜6~¬6}³6||7~7}—7|­8~Á8}È8|ø9):'î<e= 3> ?r@¾A_C @D\E`E˜dE˜hE—lE•pE•tE”xE”|E–€E‡„E†ˆEŒE€E”E…˜E„œEz E5¤E2¨E1¬E4°E3´E6¸Eƒ¼E‰ÀEˆÄEŠÈE‚ÌE8ÐE7ÔE0ØE-ÜE/àE.äE+èE,ìEmðEoôEnøEküElF*FF FF‘F"FFŽ F$F!(FŒ,F#0F‹4F8FZÜH=àH(äH(èH&ìH&ðH%ôH%øH$üH$I¦ .fileþÿgD:\temp\PCRE\pcre-8.10\pcre_dfa_exec.c@comp.id6& ÿÿ.drectve(§~¡¨.rdataŒˆñðx$.textP X*n. = P bx Š .debug$Fws®Î.textI  à‚5 $L3839ŸD°`D$L3260]C$L3219wA$L3192@ÈÚ$L3143L=$L3127…<$L3126|<$L3110‚;$L3104';$L3097²:è $L3091ü9$L4116àH$L3078›9$L306118$L3048?7$L3035*6$L30225$L3008à3$L3002h3$L2993¿2$L298312$L2973ç1$L29631$L2945x0$L2927%/$L2910.$L2906Ý-$L2886¦,$L2866+$L2842*$L2815($L2805<'$L2804'$L2803ß&$L2802É&$L2801¸&$L2800¨&$L2799‰&$L2798w&$L3763m&$L4115¼H$L2786Ñ%$L2770³$$L2768©$$L2752¼#$L2750²#$L2730 "$L2728–"$L2705ã $L2703× $L2696/ $L2695 $L2694Ò$L2693¼$L2692«$L2691›$L2690|$L2689j$L3748`$L4114˜H$L2678Ú$L2676Ð$L2660©$L2644³$L2624ž$L2601ß$L2595@$L2594$L2593ã$L2592Í$L2591¼$L2590¬$L2589$L2588{$L3733q$L4113tH$L2576Þ$L2561b$L2549O$L2538 $L2527«$L2515>$L2510·$L2509$L2508Z$L2507D$L25061$L2505$L2504$L2503ð$L3688æ$L4112PH$L2494¡ö .$L2461» $L2456© $L2452L $L2441ó $L2436Q $L2432D $L2428µ $L2424 $L2420Ž $L2417Z $L2413E $L2407] $L2400 $L2391$L2381$L3925°$L2368i@ $L2347ú$L4111€E$L4110ŒF$L2339À$L2338´$L2337¨$L2336œ$L2335$L4109\EOb__chkstk .debug$Fu_toptable2_toptable1_poptable_coptable_pcre_dfa_exec__pcre_was_newline__pcre_is_newline__pcre_default_tables__pcre_valid_utf8__pcre_try_flipped_internal_dfa_exec$NEXT_ACTIVE_STATE$2317__pcre_OP_lengths_pcre_callout__pcre_xclass__pcre_ucp_gentype__pcre_ucd_records__pcre_ucd_stage2__pcre_ucd_stage1__imp__memmove__pcre_utf8_table3__pcre_utf8_table4 /455 1305905413 100666 895 ` L‰ÖMâ.drectve(Œ .text°´d P`.debug$FÈØHB-defaultlib:MSVCRT -defaultlib:OLDNAMES ‹D$ƒøw|ÿ$…‹D$Ç3ÀËL$3ÀÇËT$3ÀÇ ËD$Ç3ÀËL$3ÀÇËT$3ÀÇ ËD$Ç€–˜3ÀËL$3ÀÇ€–˜Ã‹T$3ÀÇøýÿÿÿà Œ”˜ œ   ¤¨ ¬° .fileþÿgD:\temp\PCRE\pcre-8.10\pcre_config.c@comp.id6& ÿÿ.drectve(.text° ï A $L2202x$L2200k$L2198^$L2196Q$L2194D$L21927$L2190*$L2188$L2186$L2209Œ.debug$F_pcre_config /481 1305905414 100666 52134 ` LZ‰ÖM£Ø.drectve($ .rdata( L@@@.dataˆtü@0À.dataØ@0À.dataà@0À.dataã@0À.dataë@0À.dataò@0À.dataù@0À.dataÿ@0À.data@0À.data @0À.data@0À.data@0À.data @0À.data&@0À.data.@0À.data6@0À.data>@0À.dataF@0À.dataM@0À.text`T´ P`.debug$F@PHB.text0ZŠ P`.debug$F”¤HB.textP®þ' P`.data )@0À.data )@0À.data )@0À.data%)@0À.data*)@0À.data0)@0À.data4)@0À.data8)@0À.data=)@0À.debug$FC)S)HB.text0])) P`.data%¡)@0À.debug$FÆ)Ö)HB.textÀà) , P`.debug$FÂ-Ò-HB.textpÜ-L2 P`.debug$Fj2z2HB.text€;„2n¹ P`.data>u@0À.dataEu@0À.debug$FIuYuHB.text0cu“y P`.debug$F[zkzHB.textPuzÅ{ P`.debug$F÷{|HB.text |±| P`.debug$Fí|ý|HB.text°}·} P`.debug$Fß}ï}HB.textpù}i~ P`.debug$F}~~HB.text —~7‚ P`.debug$F_‚o‚HB.text0y‚©… P`.debug$F߆ï†HB.textù† ˆ P`.debug$FcˆsˆHB.textP}ˆÍˆ P`.debug$F׈çˆHB.textPñˆ P`.debug$FA‰Q‰HB.text`[‰»‰ P`.debug$F÷‰ŠHB.textÀŠÑŠ P`.debug$FåŠõŠHB.text ÿŠŒ P`.debug$F—Œ§ŒHB.text@±Œ P`.debug$FñŒHB.text0 P`.debug$F;KHB.text°UŽ P`.debug$FAŽQŽHB.text [Žk™E P`.dataœ@0À.debug$F!œ1œHB.text°;œë P`.debug$F•ž¥žHB.text𯞟Ÿ P`.debug$FǟןHB.text0១ P`.debug$FW¡g¡HB.text0q¡¡¢ P`.debug$Fû¢ £HB-defaultlib:MSVCRT -defaultlib:OLDNAMES :;<=>?@ÿÿüÿòÿúÿçÿþÿîÿýÿôÿñÿæÿïÿøÿìÿöÿêÿéÿ[\]^_`ûÿùÿ íÿäÿ ðÿ ÷ÿ ëÿõÿèÿMARKACCEPTCOMMITFFAILPRUNESKIPTHENÿÿÿÿkÿÿÿÿktÿÿÿÿrÿÿÿÿsÿÿÿÿsÿÿÿÿlmnopq alphalowerupperalnumasciiblankcntrldigitgraphprintpunctspacewordxdigit @þÿÿÿ€ÿÿÿÿ`ÿÿÿÿ ÿÿÿÿà ÿÿÿÿ ÿÿÿÿ@ÿÿÿÿÀÿÿÿÿàÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿ ÿÿÿÿno error\ at end of pattern\c at end of patternunrecognized character follows \numbers out of order in {} quantifiernumber too big in {} quantifiermissing terminating ] for character classinvalid escape sequence in character classrange out of order in character classnothing to repeatoperand of unlimited repeat could match the empty stringinternal error: unexpected repeatunrecognized character after (? or (?-POSIX named classes are supported only within a classmissing )reference to non-existent subpatternerroffset passed as NULLunknown option bit(s) setmissing ) after commentparentheses nested too deeplyregular expression is too largefailed to get memoryunmatched parenthesesinternal error: code overflowunrecognized character after (?<lookbehind assertion is not fixed lengthmalformed number or name after (?(conditional group contains more than two branchesassertion expected after (?((?R or (?[+-]digits must be followed by )unknown POSIX class namePOSIX collating elements are not supportedthis version of PCRE is not compiled with PCRE_UTF8 supportspare errorcharacter value in \x{...} sequence is too largeinvalid condition (?(0)\C not allowed in lookbehind assertionPCRE does not support \L, \l, \N{name}, \U, or \unumber after (?C is > 255closing ) for (?C expectedrecursive call could loop indefinitelyunrecognized character after (?Psyntax error in subpattern name (missing terminator)two named subpatterns have the same nameinvalid UTF-8 stringsupport for \P, \p, and \X has not been compiledmalformed \P or \p sequenceunknown property name after \P or \psubpattern name is too long (maximum 32 characters)too many named subpatterns (maximum 10000)repeated subpattern is too longoctal value is greater than \377 (not in UTF-8 mode)internal error: overran compiling workspaceinternal error: previously-checked referenced subpattern not foundDEFINE group contains more than one branchrepeating a DEFINE group is not allowedinconsistent NEWLINE options\g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain numbera numbered reference must not be zeroan argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)(*VERB) not recognizednumber is too bigsubpattern name expecteddigit expected after (?+] is an invalid data character in JavaScript compatibility modedifferent names for subpatterns of the same number are not allowed(*MARK) must have an argumentthis version of PCRE is not compiled with PCRE_UCP support DA> ;851. +$(,%4AD"H5PTX\dlD|€8\P{Xps}\H\P{Xan}\P{Lu}\P{Ll}\P{L}\p{Xps}\h\p{Xan}\p{Lu}\p{Ll}\p{L}\p{Xwd}\P{Xwd}\p{Xsp}\P{Xsp}\p{Nd}\P{Nd}‹D$3ÉSUŠV…ÉW„Ö‹|$‹l$‹\ƒùPu3ÉŠhŠHÁ騃ù\u…ÿŒ©‹Óâÿ錃ù_u3ÉŠhŠH;Ï„‡3ÒŠ_ëmqǃþ8w-3ÒŠ–ÿ$•ŠPëŠP€út€úu ƒÀë3ÒŠPÂ3ÒŠ‘Â…ít,ƒÁäƒùw$3ÒŠ‘ÿ$•ŠHÿ€ùÀr ƒá?3ÒŠ‘Â3ÉŠ…É…8ÿÿÿ3À_^][ÃIIZiZ{Y‚X¨Z¾TÅSØQôWøVüUP@RDOXN‹D$‹L$‹T$ P‹D$ Q‹L$ RjPQèƒÄÃd$_¸„è‹„$”SUVW‹¼$˜3í‹×;ÅÇD$$‰l$‰T$u‹„$ ;ÅtÇc_^]3À[Ä„É(‹„$ ;Åt‰(‹„$¨;Åu ÇD$é̉(‹„$¬;Åu ¸‰„$¬‹œ$œˆ‰L$0‰D$,ˆ@÷À…܉L$4‰D$8t ÇD$éd€?(…‹‹5€|**…zjT*hRÿÖƒÄ …Àu ƒÅ€Ïé#‹D$jhL(QÿÖƒÄ …ÀuƒÅË éü‹T$jhD*PÿÖƒÄ …ÀuƒÅ¸ãÿÿÿé΋L$jhT)RÿÖƒÄ …ÀuƒÅ¸ ãÿÿÿ颋D$jhL(QÿÖƒÄ …ÀuƒÅ¸0ãÿÿÿëy‹T$jhD*PÿÖƒÄ …ÀuƒÅ¸@ãÿÿÿëP‹L$jhT)RÿÖƒÄ …ÀuƒÅ ¸Pãÿÿÿë'‹D$j hL(QÿÖƒÄ …Àu ƒÅ¸€ãÿÿþ Ø‹T$€<*(„¤þÿÿë'‹T$j hD*PÿÖƒÄ …Àu ƒÅ¸ëÅ‹T$‹Ã¾Áè #ƉD$t.öÇ u)jÿW苌$°ƒÄ…À‰| ÇD$,馋T$‹Ã%€t=€t=t ÇD$8él‹Ã¹%p=0UtL…ÀtA=t:= uO¸ =ÿÇ„$„~W‰Œ$ˆ‹ÈÁùˆŒ$Œˆ„$ëI¸ ë˸ ëÄ=@t=Pt ÇD$8é鉌$„뉴$„뉴$ˆˆ„$Œ‹¼$˜„$”‰D$<Œ$”„$”‰L$@‰D$PƒÉÿ3À3ö‰|$DÕò®‹¼$˜‰T$÷ÑIT$$ÏD$,‰L$HŒ$”‰L$RPL$(VT$4QRVVD$,VPL$8‹ÃT$@QƒàRPS‰´$œ‰´$ ‰´$˜‰´$”‰´$Œ‰´$‰´$ˆ‰´$¬‰œ$¤‰´$¨‰´$€Æ„$È^è‹D$DƒÄ4;Æ…Ø‹D$$=~ ÇD$éÀ‹L$\ƒÁ¯L$X|(Wÿ‹ðƒÄ…öu ÇD$é“ÇERCP‰~‹T$p3ÿ‰Vf‹D$tf‰F ‹„$¬f‰~f‰~f‰~fÇF(f‹L$\Wf‰Nf‹T$\‹Èf‰Véf‰~÷Ùɉ~$#È3À‰N ‹T$d‰T$h‰|$d‰|$\f‹FÆ3Û3ɉD$Xf‹^f‹N¯Ù”$˜L$0‰T$TØ‹„$œQT$(WL$4RèQW‰\$X‰¼$‰¼$”‰¼$˜‰|$d‰l$,‰\$4WT$,Æ^‹FWL$4RQ‹ÈT$DƒáRQPèf‹”$”ƒÄ4f‰Vf‹D$hf‰Ff‹L$tf‰N ‹D$|;ÇtÇD$ ÿÿÿÿ9|$u‹T$€:tÇD$‹D$Æ‹D$‹L$$@‰D$+Ã;Á~ ÇD$ëu9|$uo‹D$PŒ$”;ÁvNƒè3Ò‰D$PŠPŠ03À‹êŠ$+ŠD+P‹D$PSèƒÄ ;Çt‹È*Ã+ËÁùˆ +ˆD+9|$uë­ÇD$5ëf‹Vf;VvÇD$9¼$€„œ‹D$jÿPSè‹èƒÄ ;ï„‚3ÉŠmŠM…ÉuI3Ò3ÀŠuþŠUÿŠD*ý|*ý‰„$D$,ˆ‹NPjQU芔$ ƒÄ…Àˆ|(‹ÈˆEÁùˆM3ÿ‹T$jÿƒÅRUè‹èƒÄ ;ïu’ëƒèþ÷ØÀ$õƒÀ$3ÿ‰D$9|$tTVÿƒÄ‹T$‹„$˜+Ћ„$¨‰‹L$Qè‹”$¨ƒÄ‰‹„$ …Àt‹L$‰_^]3À[Ä„ËF¨…‚‹T$l‰D$RD$WPSèƒÄ…Àt ‹F ‰Fë\‹D$(;Ç}L$WQSèƒÄ ;ljD$(|&‹ÈáÿöÄt‹\$03ÒŠ ;Ñu‹Á€N f‰Fë‹D$lPWSèƒÄ …Àt€N ‹D$ ;Ç|0öFtöÄt%‹ÈáÿöÄt‹|$03ÒŠ;Ñu€äþ€N f‰F‹Æ_^][ĄÅ‡„Úƒð‚7|cyv¸sáp mCj~gDª‚fç„‘ª7NŒNÑ’þN(eKŠ•ÅºÏ÷ÊBSR_UNICODE)BSR_ANYCRLF)ANYCRLF)ANY)CRLF)LF)CR)UCP)UTF8)K!d‹L$¸…É~Š@„ÒtŠ@„Òuù€8tI…ÉèøÃ 'Error text not found (please report),ŠQ‹D$SUVŠHp‹ÁW%ÿ3ÿƒøhÇD$ÿÿÿÿ‡§‹\$$‹l$3ÒŠÿ$•‹L$ 3Òƒø_S•ÂJQƒâUÖRèƒÄ…ÀŒmø3ÀŠfŠFð€>TtñƒÆé?‹D$…À}‰|$‹Çë;Ç…9€ùT…3ƒÆ3ÿé‹D$ …À„#‹K3ÀŠfŠFÁ‹È3ÒŠpŠP€8Ttñ;ñv;ð‚ð‹D$ SPƒÁUQèƒÄ…ÀŒØøƒÆé¹3ÉŠnŠNñ€>Ttñ3Ò3ÀŠŠ‚ðé—GƒÆë 3ÒŠvŠVúƒÆ÷Åt|ŠFÿ<Àruƒà?3ÉŠˆñëfŠF3ÒŠvŠVú<t<uƒÆƒÆëIƒÆGFëB3ÀŠfŠFt߃Æ!3ÀŠƒÀºƒøw&ÿ$…3À3ÉŠfŠN3Ò ÁŠvŠV;ÂuøƒÆëGŠ‹Á%ÿƒøh†aþÿÿƒÈÿ_^][YÃ_^]¸ýÿÿÿ[YÃ_^]¸þÿÿÿ[Yà       I5¥<¤W’ì’ZPQš—ð¢ôŸøšü”›ž œ˜™¡  £$•”•˜•œ“ “¤•¨•¬–°–´’ƒì<‹D$L‹T$HSU‹‹V‹t$x‹T$t‰L$‹NDW‹|$l‰L$0¹þÿÿÿ‰D$‰L$x‰L$O‰T$D‰D$H‰L$|Š3í€ù_‹Ø‰D$4‰l$(u$‹V 3ÉŠhŠH‰T$<‰L$(f‰L$@L$1‹D$T‹l$l3ÿ;Ç„;ׄƒú\u€{Eu ‰|$TCéÎ0;ït#9¼$4u‹”$0RSUè‹\$ƒÄ ‰|$l‹D$,öÄ@t"‹Œ$0‹D$QSP‰D$xè‹\$ƒÄ ‰D$‹L$4ŠT$…ɸˆ”$°t0|$À|&ŠKC€áÀ€ù€u‰\$Šˆ”°ŠK@C€áÀ€ù€tæŠT$,‹t$€â‰t$ €Ê3ɈF…À‰t$~Š” °ˆFA;È|ñ‰t$ŠŒ$°€ù t €ù …`/‹”$0ƒJH éW/ƒú*tm‹D$ƒø+tdƒø?t_ƒø{uCSè‹\$ƒÄ…ÀuH;ï‰|$(tH‹„$Ä‹ÐH…Ò‰„$Ä3‹„$4;Ç‹¼$0uWSUè‹\$ƒÄ ÇD$lëÇD$(‹¼$0‹T$,ö„µ‹G ‹L$ö…>/‹Áƒø#…‡C‰\$Š„Àtk‹|$4‹´$0‹NX…Ét!‹F;Øs:V\WRPQSè‹\$$ƒÄ…Àu/ë ‹N\‹V+Ñ;Úw:F`uƒùtŠCŠNa:Át C‰\$Š„Àt ë«‹N\\ ÿ‰\$€;…´.ÇD$‹T$,‹´$€‹¼$0‹¬$ öÆ@t'‹D$(…Àu‹D$WSP‰D$xè‹\$‹T$8ƒÄ ‰D$‹D$ƒø|‡Þýÿÿ3ÉŠˆÿ$öÂtƒ|$8þuÇD$8ÿÿÿÿ‹D$ÇD$ Æ@‰D$é.‹D$ÇD$ Æ@‰D$é.‹D$8ƒøþuƒÈÿ‰D$8‰D$P‹D$LÁê‰D$\‹D$€â‰D$ €Ê ˆ@‰D$éÈ-÷GD…¨.é>ýÿÿŠC‹L$<:‰L$ t<.t<=u”$„RSè‹\$ƒÄ…À…Œ.3í‰l$:…Š‹Þ3Ò‰\$3ÉŠ‰L$(‰L$<‰L$ Š ½öÁtC3ɉ\$Š öuñ‹Ë+ΉL$@Š €ù:u/C‹Ó‰\$‰T$<Š ‹ñæÿöu€ù_uC‰\$ëä‹Ã+‰D$(€;)…²¡3ÿ…À‰|$ŽŸ¾‹T$@‹;Ðu‹L$p‹ÂPUQÿƒÄ …Àt!‹\$‹¡GƒÆ ;øl*‰|$[ë¿4Á惾tu5‹„$0‹H Ç@P…Ét ‹D$Æu3ÒŠQ@ˆŠQˆP‹ ƒÀ…Éuæë‹D$‹T$(…Òu‹Ž…Ɍ׈@‰D$ë9‹Ž…Ɍҋt$<ˆ@‹Ê‹Ùˆ@‹øÂÁéó¥‹Ëƒá@ó¤‹|$Æ@ÿ‰D$¡‹\$;ø¨é‹T$,€ù?…C‰\$Š‹Ðâÿr߃þ[‡Å3ÉŠŽÿ$C‰\$Š„Àt<)t C‰\$Š„Àuñ€;„léµÇD$<ÇD$$^C‰\$‹L$$‹T$3Àƒù]œÀHˆ #‰T$D‹”$0‰D$ ƒùZÇD$|‹BL‰D$p„h ƒù[„_ 3Àé] ŠCÇD$$`‰\$ë,<'uCÇD$'‰\$ë<-ÇD$t<+u C3Ò‰\$Š‹„$03ÉŠK‹p ö1„w3ÉC3À‰\$ЉL$‹ûöt,…É|ö€t ‰LHÐëƒÉÿC3À‰\$Šöu؉L$‹t$‹ë+ï…ö~3ÀŠC;Ɖ\$…;ŠC<)‰\$…,‹„$4…À…„þÿÿ…Ò~E…ÉŽ5‹„$0ƒú-‹P4u+ÑB‹ÊëÊ…ÉŽ8;H8/‹D$‹ÑÁúˆPˆHé;þÿÿ‹„$03Û‹H,‹p(…É~.FUPWÿƒÄ …Àt‹„$0‹H0ñ‹H,C;Ù|Ù‹„$0;X,}#‹D$3ÉŠ.ŠN‹ÑˆHŠHÁúþÁˆPˆHéÒýÿÿ‹D$,‹´$0ÁèƒàPUWVèƒÄ…À~‹L$‹ÐÁúˆAŠAþÀˆQˆAé•ýÿÿ‹D$…À…N€?RuJ¹3À;é~"3ÒŠ9ö‚„;€A;ÍDBÐ|â…Àu¸ÿÿ‹L$‹ÐÁúÆAfˆQˆAé:ýÿÿƒýu)UhWÿƒÄ …Àu‹D$ÇD$(Æ@hé ýÿÿ‹D$…ÀŽ;F8ú‹L$‹ÐÁúˆQˆAéãüÿÿÇD$$XéÑüÿÿC‰\$€;)u‹D$ÇD$ Æs@‰D$éO ÇD$$Yé¦üÿÿŠK€ù!„¾€ù=„¥‹”$0áÿ‹R ö „•,<‹¼$0öØÀ‹O $é3ÒƒÀ>C‰\$‹èŠ‹óŠ ‰t$¨tC3À‰\$Šöuñ‹„$4‹Ë3Ò+Î;‰L$(„7Š;Õ…—,'¶‹W0A;ÂŽQƒù ‰G0¿é@ÇD$$ZƒÃéØûÿÿÇD$$[ƒÃéÈûÿÿÇD$$]éºûÿÿ‹D$3ɉD$l3ÒÆS‹\$@C‰\$Ç„$ÄŠö‚t ‰C‰\$LJÐ3ÒŠö‚uç€;)…°ùÿLj‹Œ$0‹T$@‹yÇD$ +×BÁúˆŠT$ŠYÆ@*ÓÆ@þˆPƒÀ‰D$é» C‰\$Š<=t<>t <<…éŒþÿÿ3É<>”Á‰L$(ÇD$)éM‹G,‹o(;‰T$‰T$@Ž ‹L$(‹t$}3Òó¦tÒƒÚÿ…Òu;‹L$(ŠT)„ÒuL‹Œ$03ÒŠu‹I4ŠUA;Ñt÷D$,„{ÇD$ë|‹”$0‹L$@‹z0ïA;ȉL$@}(뎋Œ$0‹|$@+Ç‹I0¯ÁP)URÿ‹\$ƒÄ ‹D$…ÀuE‹Œ$03ö‹y,‹A(…ÿ~2;Åt‹”$03ÉŠH‹R4Š(B;Ê„ëN‹Œ$0‹Q0ÂF;÷|΋„$0‹t$}‹P4BÁúˆUŠ@4þÀˆE‹D$(‹È‹ÑÁéó¥‹Êƒá󤋼$0ÆD(‹\$‹O,AC‰O,‰\$‹O4‹D$AÇD$(‰O4ÁùˆHŠW4ˆPé|ùÿÿÇD$)ÇD$(éÉC‰\$½)éŒöÆt³ÇD$$^éFùÿÿ‹D$,‹O4jPQT$UR‰œ$˜è‹MƒÄ…É… …Àò‹ð÷Þƒþu%‹\$€{\u€{EuƒÃé’ ÇD$Té… ƒþ„x ‹L$8ƒùþuƒþ~ ƒþ}ƒÉÿ‰L$8‰L$P‹L$Lƒþ‰L$\…½‹\$‹”$0C‹B$‰\$Š ‰D$`€é‰D$<Š‹é<+‰l$td<-t`‹Î¿Š„Àt(%ÿ;Åt‹”$0‹R Ѝu3ÿ¨tŠAA„ÀuØ3ÀŠ;Åt‹Œ$ Ç9é»…ÿuEÇD$(élC3ÒŠö‚t@3ÉŠöuò3ÒŠ;Õt‹„$ Ç9ér‹Þ‰\$Š‹ðæÿƒþ+uC3ɉ\$Š ö„Þ é'ƒþ-…3ÒŠSö‚…‹¬$03Ò<)‰T$‰T$@L$@tt<:tp%ÿC‹ð‰\$ƒî-ƒþK‡¬ 3ÀІÿ$…L$ë9‹‹EHÊ ‰‰EHë%‹ ë‹ ë‹ ë‹ ë ‹€Ìë‹ @‰Š‹T$@<)uŒ‹|$,‹D$Š ×÷Ð#Ѐù)‹Â‰D$X…Îöÿÿ‹M‹t$ƒÁ;ñu‹Œ$4…Étƒ9u‰EDëB‹Ð3×öÂtÆŠÈF€áˆ‹\$F‰t$‹ÈÁé ƒá‰Œ$Ѓñ‰Œ$̋ȃáÁá‰L$x‹”$‰D$,ÇD$ ‰éü¸‹¼$4t$|‹Ï‹¬$ ÷ÙÉ#ÎQR‹”$4Œ$´R”$ÈQ‹L$8R‹T$PQR‹T$HPD$0UL$hP‹„$€ƒâQRPèƒÄ4…À„Ý ƒ|$$`u3…ÿu/‹t$3É‹Æ3ÒAŠpŠP€8Uuð€~huwƒù9 ÇD$$h‹´$¬‹Œ$¼‹\$€;)…. …ÿtk‹L$|‹ºëÿÿ+Ðqú;ÖŒ/ Dú‰‹D$Æ^@ÆÆ@ƒÀÆU@ÆÆ@ƒÀ‰D$ééƒùÎ ƒùuŒƒÎÿƒÉÿ‰´$¬‰Œ$¼ë„‹D$$‹T$Dƒøh‰T$„´‹T$Lƒø]‰T$\‹T$8‰T$PÇ„$À|Zƒúþu/…É|‰L$8Ç„$ÀÇD$Pÿÿÿÿë'ÇD$8ÿÿÿÿÇD$Pÿÿÿÿë…É|…ö} L$p‹ñ‰´$¬…öŒC‰t$Lé:ƒøX…1…öŒ)‰t$Lé C‰\$3À3ÉŠ‰L$ö€t ‰C‰\$LHÐ3ÀŠö€uç‰L$3ÒŠ;Õ… ƒþ-u&…É„% ‹„$0‹@4+Á@…À‰D$Ž/ é\ƒþ+…S…É„< ‹”$0J4‰L$é8‹T$ƒþ…ZŠJZ€ùë,'öØÀƒàVƒÀ'‰D$‹Œ$0C3Ò‰\$‹A Š‹ûötC3Ò‰\$Šöuñ‹„$4‹ë+ï…Àt+…턹 ‹L$3ÀŠ;Á…Ì ƒý æ ÇD$ëv‹A,‹q(3Û…À~/NUQWÿƒÄ …ÀuŠD.„Àt‹„$0‹H0ñ‹H,C;Ù|Ñ‹„$0;X,} 3ÒŠ6ŠV‰T$ë"‹L$,ÁéƒáQUWPèƒÄ‰D$…Àމ ‹D$(…À„C‹´$0‹Œ$4‹D$‹^‰D$ …É…±‹L$Æ…Ét‹D$4‹Ñ‹NRPQè‹Ø‹D$ ƒÄ …ÛuT‹T$,‹\$ÁêƒâRSjVèƒÄ…ÀŒ ‹L$‹F‹ÑØ+ЋF$ƒÂÁúˆŠF‹V$*È€ÁˆJ‹F$ƒÀ‰F$ë03ÉŠkŠK…Éu(‹T$4‹„$,‹L$VRPQSèƒÄ…À…Í‹D$Æ]Æ@Æ@ƒÀ‹ÓÆR‹n+ÕƒÀÁúˆPþŠN*ÙˆXÿÆUÆ@Æ@ƒÀÇD$| ‰D$‹D$8ƒøþ…2ÇD$8ÿÿÿÿé%ƒþ#Œ¹Ýÿÿÿ+ȉL$ƒ|$8þuÇD$8ÿÿÿÿ‹D$‹L$‰D$ ‹ÑÆQ@ÁúˆˆHƒÀƒù ‰D$¸}Óà‹”$0‹r@ ð‹B<;ȉr@~‰J<‹B …À„±‹L$3Òf‹P;Ñt ‹…Àuðé˜fÇ@éƒþtfƒþtaƒþ| ƒþ"…t¹+ÈB‰T$d‹Kébƒþ~ƒþ}‹T$‹Ê‰T$ ö؈A‰L$é<‹L$ÇD$ ö؈A‰L$é"‹„$ Œ$èP”$àQD$RPèƒÄ…ÀŒI‹œ$Ü‹L$3Òƒþ”Â;Ó‰L$ •ƒÂˆAˆŠ„$èAˆA‰L$齋L$4…Étƒø~Œ$°QPèƒÄéjÐÿÿˆ„$°¸éYÐÿÿ‹”$0‹L$8ƒùþuL‹|$LƒÉÿƒø‰L$P‰|$\t‹|$x…ÿt ‰L$L‰L$8ëS‹Œ$°‹|$xáÿ σø‰L$8t7‹JL3ÀŠFÿë'‰L$P‹L$Lƒø‰L$\t‹D$x…Àu‹L$x3ÀŠFÿ‹rL Æ Á‰D$L‹\$‹D$‹¬$ä‹´$€C‰\$3ÉéòÍÿÿ‹”$ ‹„$_^Ç4‰]3À[ÄËŒ$ ‹„$_^Ç4‰]3À[ÄË”$$‹D$8‹Œ$(‰‹T$L‹„$‰‹L$‹”$‰‰‹”$4…Òt:‹‹ù½ëÿÿ+þ+è;ï}#‹„$ _^]Ç‹„$‰3À[ÄÃ+ÆÁ‰_^]¸[ÄË„$_ÇE@^‰]3À[ÄÊK‹„$€é:_öÙÉ^ƒáƒÁ ‰M‰]3À[ÄË”$ ‹„$_^lj]3À[ÄË„$ Çé싌$ ÇéÚ‹”$ ‹„$_^lj]3À[ÄË„$ _^]Ç‹„$‰3À[ÄËŒ$ ‹„$_^Ç ‰]3À[ÄË”$ ‹„$_^Ç ‰]3À[ÄË„$ _^]Ç7‹„$‰3À[ÄËŒ$ ‹„$_^lj]3À[ÄË”$ ‹„$_^lj]3À[ÄËŒ$ ÇBéÓ‹”$ Ç;éÁ‹„$ _^]Ç<‹„$‰3À[ÄËŒ$ ‹„$_^lj]3À[ÄË”$ ‹„$C_Ç^‰]3À[ÄË„$ K_^Ç‹„$]‰3À[ÄËŒ$ ‹„$_^Ç:‰]3À[ÄË”$ ‹„$_^lj]3À[ÄËD$‹”$ ÷ØÀ$ìƒÀ#‰éÒ‹„$ C_^Ç‹„$]‰3À[ÄËŒ$ ‹„$_^Ç'‰]3À[ÄË”$ ‹„$_^Ç&‰]3À[ÄË„$ _^]Ç)‹„$‰3À[ÄË”$ ‹„$_^Ç1‰]3À[ÄË„$ _^]Ç0‹„$‰3À[ÄËŒ$ ‹„$_^Ç+‰]3À[ÄË”$ ‹„$_^ÇA‰]3À[ÄË„$ _^]Ç?‹„$‰3À[ÄËŒ$ ‹„$K_Ç ^‰]3À[ÄÃÇE6éfÇEéZ‹„$_ÇE^‰]3À[ÄË„$_ÇE^‰]3À[ÄË”$ ‹„$_^lj]3À[ÄË„$ _^]Ç:‹„$‰3À[ÄËŒ$ ‹„$_^lj]3À[ÄË”$ ‹„$_^Ç:‰]3À[ÄË„$ _^]Ç>‹„$‰3À[ÄËŒ$ ‹„$_^Ç*‰]3À[ÄË”$ ‹„$_^Ç0‰]3À[ÄË„$ Ç닌$ Çë ‹”$ Ç(‹\$‹„$_^]‰3À[ÄÃI      I   I         I     R«ñ{vå '{¡-vQXXBýIƒQúµX]F vEEˆE Ô ùÛ øë 2m ï ï‘ ïž ï° ï ïÔ ï8 ïE ïW ïd ïv ïƒ ï• ï¢ ï· ïÄ ïÖ ïã ïõ ï ïI ïV ïEïRïdïqï›NQYúÏ z€åïøï€2ïïBê^éeè{ïDïЫŽ%¼…Œbœ«êbú«_4†4Õ…ZZkZ„Z¤QÐã×âPbd«% J… H˜ I± ƒà Hå I/!IF!I~!H¿!ÔÆ!Ó"# ç#ƒK$*•$ Ô$ÎÛ$ƒp& ‰& ¿'«Ú( * * U* u* ¹*ÀÀ*¿ ,ª˜- ±- á.ƒ0/*ˆ/N­/*0S212Ÿ1ý1ï9¶99Õ 9æ$9å(9,9ä09þ49Á89ÿ<9@9çD9µÈ9õÌ9öÐ9ñÔ9òØ9óÜ9ôà9ëä9îè9ðì9ìð9íô9÷ø9´:á :à$:ß(:Þ,:Ù0:Ø4:×8:Ö<:Ý@:ÜD:ÛH:ÚL:³t:Êx:Ò|:Ä€:È„:ψ:ÂŒ:Ð:É”:˘:Çœ:Æ :Ť:è:Ѭ:² ;¾;½;¸;·;¼ ;»$;º(;¹,;±DEFINEQ\E|;@ °Q‹D$S‹\$UV‹0Áë ƒãF3ÀWŠF…Û‰\$tD=À|=‹È3Òƒá?Š‘‹,•3Ò‹ñŠ;Ðt A3Ò‰L$Š;Ðuó…ÿt+‹D$,‹Ñ+Ö;ÂuPVWÿƒÄ …Àu ‹E_^][ƒÄ ËL$Š„À„ß‹|$0‹\$$<\uIA‰L$Š„À„ÄTtñéåƒûi„Ãûj„ºƒûv„±ƒûRuk‹D$ 3ÉŠnŠN‹PÊ3Ò‹ùŠwŠW…Ò„ÍP‹D$UPWèƒÄ…À…Ž3ÉŠoŠOù€?T…¬‹T$ ‹D$RUPWèƒÄ…ÀtÕé^ƒû^„߃û_„Öƒû]„̓û`„ÄCúƒøk‡.3ÉŠˆÿ$3ÒŠvŠVò‹ÆëF!3ÉŠƒÁºƒù‡/ÿ$3ÉŠhŠH…ÉéâŠF<t<…ÓƒÆéËŠFëç…턾ŠF<À‚³ƒà?3ÒŠòé¡…í„™ŠF<À‚Žƒà?3ÉŠˆñë3ÒŠVòëv3À3ÉŠfŠN Á„‹ƒû`u €<0TtðëQ3ÿ…ÿu‹T$ ‹D$RUPVèƒÄ…Àt¿3ÉŠnŠNñ€>TtÐ…ÿtPë3ÒŠ“ò3ÀŠfŠFð€>Ttñ3ÛŠ3ÉjŠ‹jÎjQè‹ð‹D$(ƒÄ;ð‚Óýÿÿ_^]¸[Ã_^]3À[ÃI        ZG 4Ï4BAB>‘Q¶Qû4$ZCZOGx5|:€9„<ˆ;Œ?@”6˜8œ7 77557 7$=(=,4‹D$3ÉSUŠV‹ñWNüƒùdwx‹T$ ‹|$‹l$3ÛŠ™ÿ$…ÿ~‹u3ÉŠH#÷‹Ù#ß;Þt‰MƒÀë1…Òt;3ÉŠhŠHÁ€8Ttñ3É3ÛŠŠ™Ãë…Òt3ÉŠŽÁ3ÉŠ‹ñNüƒùdv”_^][Ã&N-MjZzZ”J˜LœI K¤H GSUV‹t$…öWt-‹|$$‹\$ ‹l$‹F‹L$;ÁrWSUPèƒÄ…Àt‹6…öuß_^]¸[Ã_^]3À[Ã(4JS‹L$3ÒASŠŠAA„Àt(³]<\u8YuAë:Ãt%ÿ;Âu8Yt ŠAA„ÀuÚ3À[ËD$ [‰¸ÃKX SUV3öW„À¿t;‹\$‹l$3ÀІ;ØuSWUÿƒÄ …ÀtІ3ÉŠŽF„À|uÍ_^]ƒÈÿ[ËÆ_^][ÃFG F-ƒ:FBF^]‹D$ ‹L$VPQè‹ðƒÄ…ö„šS‹\$UW‹|$ ‹L$$‹o$;Ís<‹G~3ÒŠ1ŠQ;ßtƒÁ;Írë‹|$ ‹\$ë‹\$‹|$ ÁøˆŠÃˆA;O$r%‹O‹T$3ÀŠfŠFÈ;ÊrŠËÁúȈVˆN‹T$ƒÆRVè‹ðƒÄ…ö…tÿÿÿ_][^à g£g¹b‹D$3ÉVWŠ…É„™‹|$ƒùR„ŽƒùPu 3ÉŠhŠHÁëoqǃþ8w-3ÒŠ–ÿ$•ŠPëŠP€út€úu ƒÀë3ÒŠPÂ3ÒŠ‘Â…ÿt,ƒÁäƒùw$3ÒŠ‘ÿ$•ŠHÿ€ùÀr ƒá?3ÒŠ‘Â3ÉŠ…É…kÿÿÿ3À_^ÃI<qCpiZl†k™Q°o´n¸m¼iüjhg‹D$‹L$V‹t$ÆS@W‹ÑÆÿ‹~+×@ÁúˆŠV*Ê_ˆH2ɈHˆHƒÀ^Ã8v‹L$‹D$3ÒVŠqŠQ+‹T$‹r+Æ^‹ÐˆAÁúˆQÃ){V‹t$ W‹|$ ‹;Æw<‹È3ÒÁ銑‹ÈÁâƒáÑ3Éf‹ U‹ ÍÈ;Èu @;ÆvÍ_3À^Ã;Æv_3À^ËT$S‰ A@;Æw4‹Ð3ÛÁꊚ‹ÐÁãƒâÚ3Òf‹]‹ÕÐ;ÑuA@;ÆvÌ‹T$I[‰ ‰_¸^Ãê-é4ègê{é‚褀ƒì‹D$ 3ÉS‹\$Š@UƒãV‹t$(‰D$‹D$ W‰L$‰\$„•‹N 3ÒŠö t@3Ò‰D$$Šö uñ€8#ut@‰D$$Š„ÉtÔ‹|$ ‹VX…Òt!‹N;Ás:n\WUQRPèƒÄ…À‹D$$u3ë ‹V\‹n+ê;Åw:N`uƒútŠHŠVa:Êt@‰D$$ЄɄyÿÿÿë§F\‰D$$ékÿÿÿŠ€ù\…¯‹T$(‹F4jRL$4PT$0QRÇD$@è‹è‹D$@ƒÄ…À… ‹D$$@‰D$$‹|$ …Û„'‹N 3ÒŠö t@3Ò‰D$$Šö uñ€8#…@‰D$$Š„ÉtЋVX…Ò„¬‹N;ÁƒÁ^\WSQRPèƒÄ…À‹D$$…¹é ‹é‹N åÿö)€…‰‹L$ …É„gÿÿÿ@ýÀ‰D$$Œ[ÿÿÿ‹Õ3Ƀâ?ŠŠ‹Ñ‹ •‹Ï3Òƒá?Š‘‹• RÑá#ÇÓà‹ø¸;Ð|‹\$ƒéŠƒã?Óã û@;Â~ê‹Í÷ÙAúƒø‡q3ÒŠÿ$•ƒÿÞýÿÿ‹F ö8é+ƒÿD‹N ö9„7_^]¸[ƒÄÃÿ¦ýÿÿ‹V ö:éóƒÿ ‹F ö8„ÿ_^]¸[ƒÄÃÿnýÿÿ‹N ö9黃ÿÔ‹V ö:„Ç_^]¸[ƒÄÃÿB„†ÿ t|ƒÿ twƒÿ tr3À_ƒù^][”ÀƒÄÃÿ€tZ3À_ƒù^][”ÀƒÄÃÿ_ *t@ÿ |(ÿ ~0ÿ/ t(3À_ƒù^][”ÀƒÄÃÿ0t3À_ƒù^][”ÀƒÄÃ3À_ƒù^][•ÀƒÄÃÿ…t*ƒÿ |ƒÿ ~ 3À_ƒù^][”ÀƒÄÃÿ( |èÿ) à3À_ƒù^][•ÀƒÄít¹+È‹D$(jP‹L$$‰T$,jT$0QRÇD$0è‹è‹D$0ƒÄ…À…ÿD$$‹T$$D$(JL$ ‰T$$PT$ QD$,RPè‹ðƒÄ…öŒZ‹D$$@‰D$$Š€ù*„F€ù?„=jhPÿƒÄ …À„$‹\$3É‹D$ ƒýñ”Á3Ò;Ë•ÂRPVWèƒÄ_^][ƒÄÃýú„uûÿÿƒý÷„lûÿÿƒýöé¢3À_ƒýù^][”ÀƒÄÃýø„Kûÿÿƒýù„Bûÿÿƒýõ銃ý÷„1ûÿÿƒýí„(ûÿÿƒýëë|ƒýø„ûÿÿƒýî„ûÿÿƒýù„ûÿÿƒýõëJ3À_ƒýí^][”ÀƒÄÃýì„êúÿÿƒýù„áúÿÿƒýõ„Øúÿÿ_^]3À[ƒÄÃýö„Åúÿÿƒý÷„¼úÿÿƒý턳úÿÿƒý넪úÿÿƒýï„¡úÿÿ_^]3À[ƒÄÃýõ„Žúÿÿƒýù„…úÿÿ_^]3À[ƒÄà   I      xï h»QÄúW±^ƒ‰®­·QÀúQú‰êé¦è*êIéRè¶:ŸAžhQoú±œ¸›T2| ³ä±ëƒ ¶( ¨, ©0 ¦4 §8 ¤< ¥@  D ¡H ¢L £P ¬T «X ª\ †| € „ ˆ ŽŒ ‡ ‰” Š˜ ‹œ Œ  ˆ¤ ¨ †Ä ™È šÌ —Ð ˜Ô •Ø –Ü ‘à ”ä “è ’ì †{0, …‹L$V‹Á™ƒâÂ3ÒÁøŠ‹ÁÁâ%€yHƒÈ€@Ð3Àf‹U‹T$ JƒúŇ7ÿ$•Š@< „<„ <éËL$3ÒŠP3À‹4•;΋L$”À3Ò;Á”‹Â^Ã3ÉŠHë3ÉŠ‹t$3Ò;ñ‹L$”Â3À;Ñ”À^Ã3ÉŠH‹ƒøtƒøt‹L$3À3Ò;Á”‹Â^ËL$¸3Ò;Á”‹Â^Ã3ÒŠPƒ<•toƒù tjƒù ë3ÒŠPƒ<•tVƒù tQƒù tLƒù tGƒù tBƒù t=‹T$3À3É;”Á‹Á^Ã3ÒŠP‹•ƒøtƒøtƒù_t‹T$3À3É;”Á‹Á^ËT$¸3É;”Á‹Á^Ã3À^ÃIê1é@èMÀy½¼½÷½½I½ˆ¿Œ¾¼”»˜ºœ¹ ¸¤·¨¶S‹\$U‹l$V‹t$W‹|$3À3ÉŠjjVŠˆÏQè3ɃÄŠƒù^uUSVPèƒÄ…À„…ëoƒù_u3ɺŠhŠHƒù }Óâ ÓURë̓ùXt;ƒù]t6ƒù`t1ƒù9t ƒù:tƒùBtƒùt-ƒùt(öu7ƒùu2ë€x u*…Ýu&ëUSVPèƒÄ…Àt3ÒŠwŠWú€?Tu éBÿÿÿ_^]3À[Ã_^]¸[Ã!Z)G>ųÅãÅS‹\$U‹l$VW‹|$3À3ÉŠjjjŠˆËQè‹ð3ÀƒÄŠƒø`u\ŠFƒÆTtñjjƒÆjVèƒÄ‹ð3ÀŠƒø^uWUVèƒÄ …ÀtpëZƒø_u3ɸŠnŠNƒù }Óà ÅWPëÒƒøXt'ƒø]t"ƒø9tƒø:t ƒøBtƒøu1ë€~ u)…ïu%ëWUVèƒÄ …Àt3ÉŠkŠKÙ€;Tu éøþÿÿ_^]3À[Ã_^]¸[ÃZ&GFZ^ʇGÊùÊ)ÊS‹\$UVW‹|$jjCWPƒÍÿè3ɃÄŠqäƒþD‡‘3ÒŠ–ÿ$•3ÒƒùX”ÂRWPèƒÄ …À|k…í}‹èë3;èu_ë-ƒÀ‹L$…ÉtR…í}3ÉŠHЍ‹étÍë 3ÒŠP;êu03ÀŠcŠCØ€;Tu)jjKWQè3ɃÄŠqäƒþD†oÿÿÿ_^]ƒÈÿ[Ã_‹Å^][ÃG4Õ;ÔKϪGÐÑÔÒØÓÜÐ%Ï.fileþÿgD:\temp\PCRE\pcre-8.10\pcre_compile.c@comp.id6& ÿÿ.drectve(s†`.rdata( zÒ!á_digitab( D.dataˆ.data@Ží¡$.dataÙ]E.dataÁ˜[.datao|.dataˆglœ.data ÅSp¼ .data „>~ Û .data {6‚Èû .data ]>%Ü .data YŠLM% .data&%:§C^&.debug$F'%.text(À:`q —( $L2683½($L2673ä($L4608Ð($L2681ž($L4620”($L2675ˆ($L2674|($L2672x($L2671u($L2668X($L2666-($L2664'($L2662($L2660($L2651ª($L2646($L2641@($L4619ð($L4618((.debug$F)ñØã(.text*p ©* ¸ .debug$F+GBt*.text,€;¹z#±fÇ, $L3975a7,×€*,$L3727/,$L3443ì,ô+,$L3276 3,$L3974ý*,$L3973ö*,$L3972ð*,$L3971ê*,$L3970ä*,$L3969Þ*,$L3968Ê*,$L3967Ä*,$L4980 ;,$L49790;,$L4016Á(,$L3926¥(,$L3923 (,$L3901‹(,$L3863è&,$L3853H&,$L3852;&,$L4918%,$L3842a%,$L38391%,$L3838$%,.data-akt)-$L3787S",$L3786ú!,$L3785ò!,$L3780Ê!,$L4978t:,$L4977°:,$L3729º,$L3726*,$L3725%,$L3724 ,$L3723,$L3722,$L3721 ,$L3720,$L3719û,$L3718ó,$L3717ë,$L3716ã,$L3715Û,$L4976:,$L4975P:,$L3545Æ,$L3544¹,$L3543¬,$L3539t,2D$L3438},$L3425ò ,$L3423 ,$L3409à ,V $L3407 ,$L3403Û ,$L3399¦ ,$L3395x ,$L3391T ,$L3387) ,$L3383 ,$L3382ß ,$L4974È9,$L4973ü9,f.data.S›y.$L3291í,$L3289Û,$L3287¢,$L3285‰,$L3281\,$L49729,$L4971H9, .debug$F/,.text00BXk¢0 $L2366l0$L2363E0$L2345Œ0$L2339D0$L2331Û0$L2310Ê0$L2309»0$L5011Ä0$L5010à0.debug$F1oZÇ*0.text2P ¢¨Ý_get_ucp2 °ÁÌ.debug$F32.text4  ¯óÝÜ4 .debug$F54.text6°1K7ï6 .debug$F76.text8pœ.™À8 .debug$F98.text: ±H ®: .debug$F;:.text<0ÞÒÞ!< $L2821n<$L5096d<$L2774=<$L2833¾<$L2831œ<$L2829w<$L2825r<$L2822[<$L2819F<$L5111 <$L2812,<$L2810<$L5110x<$L5109 <.debug$F=<.text> £uG8> $L2598Ž>$L2614v>$L2613r>$L2608O>$L26041>$L5119”>$L5118¨>.debug$F?>.text@P¸¬’»P@ .debug$FA@.textBP%ǽ”`B .debug$FCB.textD` ‰(ÊtD .debug$FED.textFÀ‚ ņF .debug$FGF.textH  »`鈖H $L2759ŸH$L2743eH$L2758ŠH$L5154üH$L5153H$L2752^H$L2749LH$L2746GH$L5152°H$L5151ÀH.debug$FIH.textJ@Øl¦¤J .debug$FKJ.textL0 m#¹²L .debug$FML.textN° SÄN .debug$FOÝU¹N.textP EÖ:ƒ ÙP $L5186 P$L3150 P$L3148ð P$L3149Õ P$L3147° P$L3146  P$L3145€ P$L3144i P$L3143O P$L3142? P$L3105% P$L3131•P$L3123LP$L3116P$L3114dP$L3113AP$L3112,P$L3111 P$L3110ôP$L3109ÑP$L3108¼P$L5277Ä P$L5276ð P$L3096EP$L5275| P$L5274¬ P$L3090P$L3084P$L3077¼P$L3075P$L3074õP$L3073äP$L3072ÁP$L3071°P$L3070P$L3068|P$L3059ÐP$L3042ùP$L3034”P$L5273( P$L5272` P.dataQ£©d¡ðQ.debug$FRD¡ÚÊP.textS°D˨Ð S $L2969AS$L2968S$L2967ïS$L2966´S$L2965˜S$L2964‘S$L2963kS$L2962QS$L5294ˆS.debug$FTS.textUð!ÀbZ.U .debug$FVU.textW0ô>ê;W .debug$FXW.textY0 1k‰–IY $L5323ÁY$L4283gY$L4282dY$L4277?Y$L5330ÐY$L5329àY.debug$FZYa_error_texts_posix_substitutes??_C@_07LHIP@?2P?$HLXps?$HN?$AA@??_C@_02NOIK@?2H?$AA@??_C@_07FHAO@?2P?$HLXan?$HN?$AA@??_C@_06CCDD@?2P?$HLLu?$HN?$AA@??_C@_06OLGE@?2P?$HLLl?$HN?$AA@??_C@_05EEPJ@?2P?$HLL?$HN?$AA@??_C@_07DIL@?2p?$HLXps?$HN?$AA@??_C@_02IMGK@?2h?$AA@??_C@_07ODAK@?2p?$HLXan?$HN?$AA@??_C@_06CGJJ@?2p?$HLLu?$HN?$AA@??_C@_06OPMO@?2p?$HLLl?$HN?$AA@??_C@_05OOLL@?2p?$HLL?$HN?$AA@_substitutes??_C@_07LGBG@?2p?$HLXwd?$HN?$AA@??_C@_07CBC@?2P?$HLXwd?$HN?$AA@??_C@_07MOEP@?2p?$HLXsp?$HN?$AA@??_C@_07HKEL@?2P?$HLXsp?$HN?$AA@??_C@_06POLH@?2p?$HLNd?$HN?$AA@??_C@_06PKBN@?2P?$HLNd?$HN?$AA@_posix_class_maps_posix_name_lengths_posix_names_verbcount_verbnames__pcre_find_bracket__pcre_utf8_table4__pcre_OP_lengths_pcre_compile_pcre_compile2_pcre_free_pcre_malloc__pcre_valid_utf8??_C@_0N@CK@BSR_UNICODE?$CJ?$AA@??_C@_0N@JMJK@BSR_ANYCRLF?$CJ?$AA@??_C@_08PBHC@ANYCRLF?$CJ?$AA@??_C@_04EHIC@ANY?$CJ?$AA@??_C@_05IOOL@CRLF?$CJ?$AA@??_C@_03CMNA@LF?$CJ?$AA@??_C@_03DCAH@CR?$CJ?$AA@??_C@_04KOOM@UCP?$CJ?$AA@??_C@_05HAOA@UTF8?$CJ?$AA@__imp__strncmp__pcre_default_tables_find_error_text??_C@_0CF@PBIC@Error?5text?5not?5found?5?$CIplease?5rep@_find_fixedlength_compile_regex__imp__memmove_compile_branch$OTHER_CHAR_AFTER_QUERY$3934$NORMAL_CHAR$3257??_C@_06BGAI@DEFINE?$AA@__pcre_ucd_records__pcre_ucd_stage2__pcre_ucd_stage1__pcre_ord2utf8__pcre_utf8_table3??_C@_03HMCP@Q?2E?$AA@__pcre_is_newline_check_escape__pcre_utt_names__pcre_utt__pcre_utt_size_is_counted_repeat_read_repeat_counts_find_parens_find_parens_sub_could_be_empty_branch_first_significant_code_could_be_empty_check_posix_syntax_check_posix_name_adjust_recurse_find_recurse_auto_callout_complete_callout_get_othercase_range_check_auto_possessive??_C@_03JDGE@?$HL0?0?$AA@_check_char_prop__pcre_ucp_gentype_is_anchored_is_startline_find_firstassertedchar/508 1305905414 100666 1434 ` L‰ÖMÌ .drectve(d .rdata@Œ@0@-defaultlib:MSVCRT -defaultlib:OLDNAMES   !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ>ÿ~~ÿþÿÿþÿÿÿþÿÿ‡þÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿüøxÿÿÿÿ€€€€€€€€€€€€€€.fileþÿgD:\temp\PCRE\pcre-8.10\pcre_chartables.c@comp.id6& ÿÿ.drectve(<çÖý.rdata@__pcre_default_tablessnort-2.9.15.1/src/win32/WIN32-Libraries/wpcap.lib0000444000175200017520000004640013571422610016113 00000000000000! / 1305901362 0 4342 ` ³"v%x&®:::n:n???n?n, , 6 6 IDID:Ø:Ø/ò/ò@°@°JJ=Æ=Æ<<JôJôKZKZHH@H@HL0L05Î5Î,r,r,Ú,Ú4ð4ð. . JŠJŠ7â7â;>;>;¬;¬2Ú2Ú3@3@2p2p0Â0Â1˜1˜0\0\1.1.G.G.HÜHÜBÚBÚCFCFC¶C¶D(D(D˜D˜<€<€6666HnHn>š>š3¨3¨4„4„9*9*9”9”(b(b).).(È(È'þ'þLšLš)–)–*b*b)ü)ü>4>4-²-²?Ü?Ü44AABjBjAúAúAˆAˆ*È*È<î<î=V=VI°I°+¢+¢8º8ºE|E|.Š.Š/|/|//8N8N225Z5Z-J-J+8+8EêEêFVFVFÂFÂE E 7 7 G–G–KÄKÄ7z7z__IMPORT_DESCRIPTOR_wpcap__NULL_IMPORT_DESCRIPTORwpcap_NULL_THUNK_DATA__imp__pcap_lookupdev_pcap_lookupdev__imp__pcap_lookupnet_pcap_lookupnet__imp__pcap_open_live_pcap_open_live__imp__pcap_open_offline_pcap_open_offline__imp__pcap_close_pcap_close__imp__pcap_getnonblock_pcap_getnonblock__imp__pcap_setnonblock_pcap_setnonblock__imp__pcap_loop_pcap_loop__imp__pcap_dispatch_pcap_dispatch__imp__pcap_read_pcap_read__imp__pcap_setuserbuffer_pcap_setuserbuffer__imp__pcap_offline_read_pcap_offline_read__imp__pcap_next_pcap_next__imp__pcap_stats_pcap_stats__imp__pcap_stats_ex_pcap_stats_ex__imp__pcap_setfilter_pcap_setfilter__imp__pcap_perror_pcap_perror__imp__pcap_strerror_pcap_strerror__imp__pcap_geterr_pcap_geterr__imp__pcap_compile_pcap_compile__imp__pcap_compile_nopcap_pcap_compile_nopcap__imp__pcap_freecode_pcap_freecode__imp__pcap_datalink_pcap_datalink__imp__pcap_snapshot_pcap_snapshot__imp__pcap_is_swapped_pcap_is_swapped__imp__pcap_major_version_pcap_major_version__imp__pcap_minor_version_pcap_minor_version__imp__pcap_file_pcap_file__imp__pcap_fileno_pcap_fileno__imp__pcap_dump_open_pcap_dump_open__imp__pcap_dump_close_pcap_dump_close__imp__pcap_dump_flush_pcap_dump_flush__imp__pcap_dump_pcap_dump__imp__pcap_dump_file_pcap_dump_file__imp__pcap_setbuff_pcap_setbuff__imp__pcap_setmode_pcap_setmode__imp__pcap_sendpacket_pcap_sendpacket__imp__pcap_sendqueue_alloc_pcap_sendqueue_alloc__imp__pcap_sendqueue_destroy_pcap_sendqueue_destroy__imp__pcap_sendqueue_queue_pcap_sendqueue_queue__imp__pcap_sendqueue_transmit_pcap_sendqueue_transmit__imp__pcap_next_etherent_pcap_next_etherent__imp__pcap_getevent_pcap_getevent__imp__pcap_setmintocopy_pcap_setmintocopy__imp__pcap_open_dead_pcap_open_dead__imp__pcap_findalldevs_pcap_findalldevs__imp__pcap_freealldevs_pcap_freealldevs__imp__pcap_live_dump_pcap_live_dump__imp__pcap_live_dump_ended_pcap_live_dump_ended__imp__bpf_filter_bpf_filter__imp__bpf_validate_bpf_validate__imp__bpf_image_bpf_image__imp__bpf_dump_bpf_dump__imp__wsockinit_wsockinit__imp__endservent_endservent__imp__getservent_getservent__imp__eproto_db_eproto_db__imp__pcap_open_pcap_open__imp__pcap_createsrcstr_pcap_createsrcstr__imp__pcap_parsesrcstr_pcap_parsesrcstr__imp__pcap_findalldevs_ex_pcap_findalldevs_ex__imp__pcap_remoteact_accept_pcap_remoteact_accept__imp__pcap_remoteact_list_pcap_remoteact_list__imp__pcap_remoteact_close_pcap_remoteact_close__imp__pcap_remoteact_cleanup_pcap_remoteact_cleanup__imp__install_bpf_program_install_bpf_program__imp__pcap_next_ex_pcap_next_ex__imp__pcap_offline_filter_pcap_offline_filter__imp__pcap_setsampling_pcap_setsampling__imp__pcap_breakloop_pcap_breakloop__imp__pcap_list_datalinks_pcap_list_datalinks__imp__pcap_set_datalink_pcap_set_datalink__imp__pcap_datalink_name_to_val_pcap_datalink_name_to_val__imp__pcap_datalink_val_to_name_pcap_datalink_val_to_name__imp__pcap_datalink_val_to_description_pcap_datalink_val_to_description__imp__pcap_lib_version_pcap_lib_version__imp__pcap_dump_ftell_pcap_dump_ftell__imp__pcap_get_airpcap_handle_pcap_get_airpcap_handle__imp__pcap_create_pcap_create__imp__pcap_activate_pcap_activate__imp__pcap_set_promisc_pcap_set_promisc__imp__pcap_set_snaplen_pcap_set_snaplen__imp__pcap_set_timeout_pcap_set_timeout__imp__pcap_set_buffer_size_pcap_set_buffer_size__imp__pcap_hopen_offline_pcap_hopen_offline__imp__pcap_setdirection_pcap_setdirection__imp__pcap_statustostr_pcap_statustostr__imp__pcap_inject_pcap_inject/ 1305901362 0 4352 ` [v"x%®&:n:?n? , 6DIØ:ò/°@JÆ=<ôJZKHH@0LÎ5r,Ú,ð4 .ŠJâ7>;¬;Ú2@3p2Â0˜1\0.1.GÜHÚBFC¶C(D˜D€<66nHš>¨3„4*9”9b(.)È(þ'šL–)b*ü)4>²-Ü?4AjBúAˆAÈ*î<V=°I¢+º8|EŠ.|//N82Z5J-8+êEVFÂF E 7–GÄKz7³8576:<;ESIR>LNM $"%#P! 1@2Q. X[OJ34 -FG=0? ADCB()*+,WKTUV&Y/' HZ98576:<;ESIR>LNM $"%#P! 1@2Q. X[OJ34 -FG=0? ADCB()*+,WKTUV&Y/' HZ9__IMPORT_DESCRIPTOR_wpcap__NULL_IMPORT_DESCRIPTOR__imp__bpf_dump__imp__bpf_filter__imp__bpf_image__imp__bpf_validate__imp__endservent__imp__eproto_db__imp__getservent__imp__install_bpf_program__imp__pcap_activate__imp__pcap_breakloop__imp__pcap_close__imp__pcap_compile__imp__pcap_compile_nopcap__imp__pcap_create__imp__pcap_createsrcstr__imp__pcap_datalink__imp__pcap_datalink_name_to_val__imp__pcap_datalink_val_to_description__imp__pcap_datalink_val_to_name__imp__pcap_dispatch__imp__pcap_dump__imp__pcap_dump_close__imp__pcap_dump_file__imp__pcap_dump_flush__imp__pcap_dump_ftell__imp__pcap_dump_open__imp__pcap_file__imp__pcap_fileno__imp__pcap_findalldevs__imp__pcap_findalldevs_ex__imp__pcap_freealldevs__imp__pcap_freecode__imp__pcap_get_airpcap_handle__imp__pcap_geterr__imp__pcap_getevent__imp__pcap_getnonblock__imp__pcap_hopen_offline__imp__pcap_inject__imp__pcap_is_swapped__imp__pcap_lib_version__imp__pcap_list_datalinks__imp__pcap_live_dump__imp__pcap_live_dump_ended__imp__pcap_lookupdev__imp__pcap_lookupnet__imp__pcap_loop__imp__pcap_major_version__imp__pcap_minor_version__imp__pcap_next__imp__pcap_next_etherent__imp__pcap_next_ex__imp__pcap_offline_filter__imp__pcap_offline_read__imp__pcap_open__imp__pcap_open_dead__imp__pcap_open_live__imp__pcap_open_offline__imp__pcap_parsesrcstr__imp__pcap_perror__imp__pcap_read__imp__pcap_remoteact_accept__imp__pcap_remoteact_cleanup__imp__pcap_remoteact_close__imp__pcap_remoteact_list__imp__pcap_sendpacket__imp__pcap_sendqueue_alloc__imp__pcap_sendqueue_destroy__imp__pcap_sendqueue_queue__imp__pcap_sendqueue_transmit__imp__pcap_set_buffer_size__imp__pcap_set_datalink__imp__pcap_set_promisc__imp__pcap_set_snaplen__imp__pcap_set_timeout__imp__pcap_setbuff__imp__pcap_setdirection__imp__pcap_setfilter__imp__pcap_setmintocopy__imp__pcap_setmode__imp__pcap_setnonblock__imp__pcap_setsampling__imp__pcap_setuserbuffer__imp__pcap_snapshot__imp__pcap_stats__imp__pcap_stats_ex__imp__pcap_statustostr__imp__pcap_strerror__imp__wsockinit_bpf_dump_bpf_filter_bpf_image_bpf_validate_endservent_eproto_db_getservent_install_bpf_program_pcap_activate_pcap_breakloop_pcap_close_pcap_compile_pcap_compile_nopcap_pcap_create_pcap_createsrcstr_pcap_datalink_pcap_datalink_name_to_val_pcap_datalink_val_to_description_pcap_datalink_val_to_name_pcap_dispatch_pcap_dump_pcap_dump_close_pcap_dump_file_pcap_dump_flush_pcap_dump_ftell_pcap_dump_open_pcap_file_pcap_fileno_pcap_findalldevs_pcap_findalldevs_ex_pcap_freealldevs_pcap_freecode_pcap_get_airpcap_handle_pcap_geterr_pcap_getevent_pcap_getnonblock_pcap_hopen_offline_pcap_inject_pcap_is_swapped_pcap_lib_version_pcap_list_datalinks_pcap_live_dump_pcap_live_dump_ended_pcap_lookupdev_pcap_lookupnet_pcap_loop_pcap_major_version_pcap_minor_version_pcap_next_pcap_next_etherent_pcap_next_ex_pcap_offline_filter_pcap_offline_read_pcap_open_pcap_open_dead_pcap_open_live_pcap_open_offline_pcap_parsesrcstr_pcap_perror_pcap_read_pcap_remoteact_accept_pcap_remoteact_cleanup_pcap_remoteact_close_pcap_remoteact_list_pcap_sendpacket_pcap_sendqueue_alloc_pcap_sendqueue_destroy_pcap_sendqueue_queue_pcap_sendqueue_transmit_pcap_set_buffer_size_pcap_set_datalink_pcap_set_promisc_pcap_set_snaplen_pcap_set_timeout_pcap_setbuff_pcap_setdirection_pcap_setfilter_pcap_setmintocopy_pcap_setmode_pcap_setnonblock_pcap_setsampling_pcap_setuserbuffer_pcap_snapshot_pcap_stats_pcap_stats_ex_pcap_statustostr_pcap_strerror_wsockinitwpcap_NULL_THUNK_DATAwpcap.dll/ 1305901362 0 710 ` L2yÖMèà .debug$S@l@B.idata$2¬À@0À.idata$6 ÞÀ@ À wpcap.dll(ÿ Microsoft (R) LINK wpcap.dll@comp.idÿ ÿÿ.idata$2@Àh.idata$6.idata$4@Àh.idata$5@Àh7N__IMPORT_DESCRIPTOR_wpcap__NULL_IMPORT_DESCRIPTORwpcap_NULL_THUNK_DATAwpcap.dll/ 1305901362 0 249 ` L2yÖM¸.debug$S@d@B.idata$3¤@0À wpcap.dll(ÿ Microsoft (R) LINK@comp.idÿ ÿÿ__NULL_IMPORT_DESCRIPTOR wpcap.dll/ 1305901362 0 275 ` L2yÖMÔ.debug$S@Œ@B.idata$5Ì@0À.idata$4Ð@0À wpcap.dll(ÿ Microsoft (R) LINK@comp.idÿ ÿÿwpcap_NULL_THUNK_DATA wpcap.dll/ 1305901362 0 40 ` ÿÿL2yÖM_bpf_dumpwpcap.dllwpcap.dll/ 1305901362 0 42 ` ÿÿL2yÖM_bpf_filterwpcap.dllwpcap.dll/ 1305901362 0 41 ` ÿÿL2yÖM_bpf_imagewpcap.dll wpcap.dll/ 1305901362 0 44 ` ÿÿL2yÖM_bpf_validatewpcap.dllwpcap.dll/ 1305901362 0 42 ` ÿÿL2yÖM_endserventwpcap.dllwpcap.dll/ 1305901362 0 41 ` ÿÿL2yÖM_eproto_dbwpcap.dll wpcap.dll/ 1305901362 0 42 ` ÿÿL2yÖM_getserventwpcap.dllwpcap.dll/ 1305901362 0 51 ` ÿÿL2yÖM_install_bpf_programwpcap.dll wpcap.dll/ 1305901362 0 45 ` ÿÿL2yÖM_pcap_activatewpcap.dll wpcap.dll/ 1305901362 0 46 ` ÿÿL2yÖM _pcap_breakloopwpcap.dllwpcap.dll/ 1305901362 0 42 ` ÿÿL2yÖM _pcap_closewpcap.dllwpcap.dll/ 1305901362 0 44 ` ÿÿL2yÖM _pcap_compilewpcap.dllwpcap.dll/ 1305901362 0 51 ` ÿÿL2yÖM _pcap_compile_nopcapwpcap.dll wpcap.dll/ 1305901362 0 43 ` ÿÿL2yÖM _pcap_createwpcap.dll wpcap.dll/ 1305901362 0 49 ` ÿÿL2yÖM_pcap_createsrcstrwpcap.dll wpcap.dll/ 1305901362 0 45 ` ÿÿL2yÖM_pcap_datalinkwpcap.dll wpcap.dll/ 1305901362 0 57 ` ÿÿL2yÖM%_pcap_datalink_name_to_valwpcap.dll wpcap.dll/ 1305901362 0 64 ` ÿÿL2yÖM,_pcap_datalink_val_to_descriptionwpcap.dllwpcap.dll/ 1305901362 0 57 ` ÿÿL2yÖM%_pcap_datalink_val_to_namewpcap.dll wpcap.dll/ 1305901362 0 45 ` ÿÿL2yÖM_pcap_dispatchwpcap.dll wpcap.dll/ 1305901362 0 41 ` ÿÿL2yÖM_pcap_dumpwpcap.dll wpcap.dll/ 1305901362 0 47 ` ÿÿL2yÖM_pcap_dump_closewpcap.dll wpcap.dll/ 1305901362 0 46 ` ÿÿL2yÖM_pcap_dump_filewpcap.dllwpcap.dll/ 1305901362 0 47 ` ÿÿL2yÖM_pcap_dump_flushwpcap.dll wpcap.dll/ 1305901362 0 47 ` ÿÿL2yÖM_pcap_dump_ftellwpcap.dll wpcap.dll/ 1305901362 0 46 ` ÿÿL2yÖM_pcap_dump_openwpcap.dllwpcap.dll/ 1305901362 0 41 ` ÿÿL2yÖM_pcap_filewpcap.dll wpcap.dll/ 1305901362 0 43 ` ÿÿL2yÖM_pcap_filenowpcap.dll wpcap.dll/ 1305901362 0 48 ` ÿÿL2yÖM_pcap_findalldevswpcap.dllwpcap.dll/ 1305901362 0 51 ` ÿÿL2yÖM_pcap_findalldevs_exwpcap.dll wpcap.dll/ 1305901362 0 48 ` ÿÿL2yÖM_pcap_freealldevswpcap.dllwpcap.dll/ 1305901362 0 45 ` ÿÿL2yÖM_pcap_freecodewpcap.dll wpcap.dll/ 1305901362 0 55 ` ÿÿL2yÖM# _pcap_get_airpcap_handlewpcap.dll wpcap.dll/ 1305901362 0 43 ` ÿÿL2yÖM!_pcap_geterrwpcap.dll wpcap.dll/ 1305901362 0 45 ` ÿÿL2yÖM"_pcap_geteventwpcap.dll wpcap.dll/ 1305901362 0 48 ` ÿÿL2yÖM#_pcap_getnonblockwpcap.dllwpcap.dll/ 1305901362 0 50 ` ÿÿL2yÖM$_pcap_hopen_offlinewpcap.dllwpcap.dll/ 1305901362 0 43 ` ÿÿL2yÖM%_pcap_injectwpcap.dll wpcap.dll/ 1305901362 0 47 ` ÿÿL2yÖM&_pcap_is_swappedwpcap.dll wpcap.dll/ 1305901362 0 48 ` ÿÿL2yÖM'_pcap_lib_versionwpcap.dllwpcap.dll/ 1305901362 0 51 ` ÿÿL2yÖM(_pcap_list_datalinkswpcap.dll wpcap.dll/ 1305901362 0 46 ` ÿÿL2yÖM)_pcap_live_dumpwpcap.dllwpcap.dll/ 1305901362 0 52 ` ÿÿL2yÖM *_pcap_live_dump_endedwpcap.dllwpcap.dll/ 1305901362 0 46 ` ÿÿL2yÖM+_pcap_lookupdevwpcap.dllwpcap.dll/ 1305901362 0 46 ` ÿÿL2yÖM,_pcap_lookupnetwpcap.dllwpcap.dll/ 1305901362 0 41 ` ÿÿL2yÖM-_pcap_loopwpcap.dll wpcap.dll/ 1305901362 0 50 ` ÿÿL2yÖM._pcap_major_versionwpcap.dllwpcap.dll/ 1305901362 0 50 ` ÿÿL2yÖM/_pcap_minor_versionwpcap.dllwpcap.dll/ 1305901362 0 41 ` ÿÿL2yÖM0_pcap_nextwpcap.dll wpcap.dll/ 1305901362 0 50 ` ÿÿL2yÖM1_pcap_next_etherentwpcap.dllwpcap.dll/ 1305901362 0 44 ` ÿÿL2yÖM2_pcap_next_exwpcap.dllwpcap.dll/ 1305901362 0 51 ` ÿÿL2yÖM3_pcap_offline_filterwpcap.dll wpcap.dll/ 1305901362 0 49 ` ÿÿL2yÖM4_pcap_offline_readwpcap.dll wpcap.dll/ 1305901362 0 41 ` ÿÿL2yÖM5_pcap_openwpcap.dll wpcap.dll/ 1305901362 0 46 ` ÿÿL2yÖM6_pcap_open_deadwpcap.dllwpcap.dll/ 1305901362 0 46 ` ÿÿL2yÖM7_pcap_open_livewpcap.dllwpcap.dll/ 1305901362 0 49 ` ÿÿL2yÖM8_pcap_open_offlinewpcap.dll wpcap.dll/ 1305901362 0 48 ` ÿÿL2yÖM9_pcap_parsesrcstrwpcap.dllwpcap.dll/ 1305901362 0 43 ` ÿÿL2yÖM:_pcap_perrorwpcap.dll wpcap.dll/ 1305901362 0 41 ` ÿÿL2yÖM;_pcap_readwpcap.dll wpcap.dll/ 1305901362 0 53 ` ÿÿL2yÖM!<_pcap_remoteact_acceptwpcap.dll wpcap.dll/ 1305901362 0 54 ` ÿÿL2yÖM"=_pcap_remoteact_cleanupwpcap.dllwpcap.dll/ 1305901362 0 52 ` ÿÿL2yÖM >_pcap_remoteact_closewpcap.dllwpcap.dll/ 1305901362 0 51 ` ÿÿL2yÖM?_pcap_remoteact_listwpcap.dll wpcap.dll/ 1305901362 0 47 ` ÿÿL2yÖM@_pcap_sendpacketwpcap.dll wpcap.dll/ 1305901362 0 52 ` ÿÿL2yÖM A_pcap_sendqueue_allocwpcap.dllwpcap.dll/ 1305901362 0 54 ` ÿÿL2yÖM"B_pcap_sendqueue_destroywpcap.dllwpcap.dll/ 1305901362 0 52 ` ÿÿL2yÖM C_pcap_sendqueue_queuewpcap.dllwpcap.dll/ 1305901362 0 55 ` ÿÿL2yÖM#D_pcap_sendqueue_transmitwpcap.dll wpcap.dll/ 1305901362 0 52 ` ÿÿL2yÖM E_pcap_set_buffer_sizewpcap.dllwpcap.dll/ 1305901362 0 49 ` ÿÿL2yÖMF_pcap_set_datalinkwpcap.dll wpcap.dll/ 1305901362 0 48 ` ÿÿL2yÖMG_pcap_set_promiscwpcap.dllwpcap.dll/ 1305901362 0 48 ` ÿÿL2yÖMH_pcap_set_snaplenwpcap.dllwpcap.dll/ 1305901362 0 48 ` ÿÿL2yÖMI_pcap_set_timeoutwpcap.dllwpcap.dll/ 1305901362 0 44 ` ÿÿL2yÖMJ_pcap_setbuffwpcap.dllwpcap.dll/ 1305901362 0 49 ` ÿÿL2yÖMK_pcap_setdirectionwpcap.dll wpcap.dll/ 1305901362 0 46 ` ÿÿL2yÖML_pcap_setfilterwpcap.dllwpcap.dll/ 1305901362 0 49 ` ÿÿL2yÖMM_pcap_setmintocopywpcap.dll wpcap.dll/ 1305901362 0 44 ` ÿÿL2yÖMN_pcap_setmodewpcap.dllwpcap.dll/ 1305901362 0 48 ` ÿÿL2yÖMO_pcap_setnonblockwpcap.dllwpcap.dll/ 1305901362 0 48 ` ÿÿL2yÖMP_pcap_setsamplingwpcap.dllwpcap.dll/ 1305901362 0 50 ` ÿÿL2yÖMQ_pcap_setuserbufferwpcap.dllwpcap.dll/ 1305901362 0 45 ` ÿÿL2yÖMR_pcap_snapshotwpcap.dll wpcap.dll/ 1305901362 0 42 ` ÿÿL2yÖMS_pcap_statswpcap.dllwpcap.dll/ 1305901362 0 45 ` ÿÿL2yÖMT_pcap_stats_exwpcap.dll wpcap.dll/ 1305901362 0 48 ` ÿÿL2yÖMU_pcap_statustostrwpcap.dllwpcap.dll/ 1305901362 0 45 ` ÿÿL2yÖMV_pcap_strerrorwpcap.dll wpcap.dll/ 1305901362 0 41 ` ÿÿL2yÖMW_wsockinitwpcap.dll snort-2.9.15.1/src/win32/WIN32-Libraries/zlib.lib0000555000175200017520000030521013571422610015741 00000000000000! / 1264530311 0 2564 ` f'L*Ü*Ü*Ü*Ü*Ü*Ü*Ühhqqqqqqqqqqqqqqqqqqqqqqqqqqqq·V¿ä¿ä¿äè@è@è@è@è@è@è@è@è@è@è@è@è@è@è@è@è@è@è@è@è@è@è@¶¶¶¶¶¶¶¶¶¶¶¶¶RÌRÌRÌddd„Þ„Þ??_C@_00A@?$AA@??_C@_05CNKG@1?42?43?$AA@??_C@_0BA@FKCH@need?5dictionary?$AA@??_C@_0BE@EMHE@insufficient?5memory?$AA@??_C@_0BF@HPBB@incompatible?5version?$AA@??_C@_0L@DFEP@file?5error?$AA@??_C@_0L@EBEB@data?5error?$AA@??_C@_0L@JPFB@stream?5end?$AA@??_C@_0N@EHHN@buffer?5error?$AA@??_C@_0N@OPOA@stream?5error?$AA@_zError_z_errmsg_zcalloc_zcfree_zlibCompileFlags_zlibVersion_uncompress__dist_code__length_code__tr_align__tr_flush_block__tr_init__tr_stored_block__tr_tally_inflate_copyright_inflate_table??_C@_0BD@IFBC@invalid?5block?5type?$AA@??_C@_0BE@FAJE@invalid?5window?5size?$AA@??_C@_0BE@GABH@header?5crc?5mismatch?$AA@??_C@_0BF@OBFI@incorrect?5data?5check?$AA@??_C@_0BG@DILP@invalid?5distances?5set?$AA@??_C@_0BG@EGK@invalid?5distance?5code?$AA@??_C@_0BH@NLIB@incorrect?5header?5check?$AA@??_C@_0BH@PBLF@incorrect?5length?5check?$AA@??_C@_0BJ@LBGI@unknown?5header?5flags?5set?$AA@??_C@_0BJ@PEEP@invalid?5code?5lengths?5set?$AA@??_C@_0BK@BNJN@invalid?5bit?5length?5repeat?$AA@??_C@_0BL@KPEJ@unknown?5compression?5method?$AA@??_C@_0BM@BLEK@invalid?5literal?1lengths?5set?$AA@??_C@_0BM@CHJP@invalid?5literal?1length?5code?$AA@??_C@_0BN@DBOJ@invalid?5stored?5block?5lengths?$AA@??_C@_0BO@EEIF@invalid?5distance?5too?5far?5back?$AA@??_C@_0CE@LAKP@too?5many?5length?5or?5distance?5symb@_inflate_inflateCopy_inflateEnd_inflateGetHeader_inflateInit2__inflateInit__inflatePrime_inflateReset_inflateSetDictionary_inflateSync_inflateSyncPoint_inflate_fast_inflateBack_inflateBackEnd_inflateBackInit_??_C@_02HFBK@?3?5?$AA@??_C@_07GLHK@?$DMfd?3?$CFd?$DO?$AA@??_C@_0BF@KHAC@?$CFc?$CFc?$CFc?$CFc?$CFc?$CFc?$CFc?$CFc?$CFc?$CFc?$AA@_gzclearerr_gzclose_gzdirect_gzdopen_gzeof_gzerror_gzflush_gzgetc_gzgets_gzopen_gzprintf_gzputc_gzputs_gzread_gzrewind_gzseek_gzsetparams_gztell_gzungetc_gzwrite_deflate_deflateBound_deflateCopy_deflateEnd_deflateInit2__deflateInit__deflateParams_deflatePrime_deflateReset_deflateSetDictionary_deflateSetHeader_deflateTune_deflate_copyright_crc32_crc32_combine_get_crc_table_compress_compress2_compressBound_adler32_adler32_combine/ 1264530311 0 2416 ` ÈL'Ü*hqV·ä¿@è¶ÌRdÞ„f    ??_C@_00A@?$AA@??_C@_02HFBK@?3?5?$AA@??_C@_05CNKG@1?42?43?$AA@??_C@_07GLHK@?$DMfd?3?$CFd?$DO?$AA@??_C@_0BA@FKCH@need?5dictionary?$AA@??_C@_0BD@IFBC@invalid?5block?5type?$AA@??_C@_0BE@EMHE@insufficient?5memory?$AA@??_C@_0BE@FAJE@invalid?5window?5size?$AA@??_C@_0BE@GABH@header?5crc?5mismatch?$AA@??_C@_0BF@HPBB@incompatible?5version?$AA@??_C@_0BF@KHAC@?$CFc?$CFc?$CFc?$CFc?$CFc?$CFc?$CFc?$CFc?$CFc?$CFc?$AA@??_C@_0BF@OBFI@incorrect?5data?5check?$AA@??_C@_0BG@DILP@invalid?5distances?5set?$AA@??_C@_0BG@EGK@invalid?5distance?5code?$AA@??_C@_0BH@NLIB@incorrect?5header?5check?$AA@??_C@_0BH@PBLF@incorrect?5length?5check?$AA@??_C@_0BJ@LBGI@unknown?5header?5flags?5set?$AA@??_C@_0BJ@PEEP@invalid?5code?5lengths?5set?$AA@??_C@_0BK@BNJN@invalid?5bit?5length?5repeat?$AA@??_C@_0BL@KPEJ@unknown?5compression?5method?$AA@??_C@_0BM@BLEK@invalid?5literal?1lengths?5set?$AA@??_C@_0BM@CHJP@invalid?5literal?1length?5code?$AA@??_C@_0BN@DBOJ@invalid?5stored?5block?5lengths?$AA@??_C@_0BO@EEIF@invalid?5distance?5too?5far?5back?$AA@??_C@_0CE@LAKP@too?5many?5length?5or?5distance?5symb@??_C@_0L@DFEP@file?5error?$AA@??_C@_0L@EBEB@data?5error?$AA@??_C@_0L@JPFB@stream?5end?$AA@??_C@_0N@EHHN@buffer?5error?$AA@??_C@_0N@OPOA@stream?5error?$AA@__dist_code__length_code__tr_align__tr_flush_block__tr_init__tr_stored_block__tr_tally_adler32_adler32_combine_compress_compress2_compressBound_crc32_crc32_combine_deflate_deflateBound_deflateCopy_deflateEnd_deflateInit2__deflateInit__deflateParams_deflatePrime_deflateReset_deflateSetDictionary_deflateSetHeader_deflateTune_deflate_copyright_get_crc_table_gzclearerr_gzclose_gzdirect_gzdopen_gzeof_gzerror_gzflush_gzgetc_gzgets_gzopen_gzprintf_gzputc_gzputs_gzread_gzrewind_gzseek_gzsetparams_gztell_gzungetc_gzwrite_inflate_inflateBack_inflateBackEnd_inflateBackInit__inflateCopy_inflateEnd_inflateGetHeader_inflateInit2__inflateInit__inflatePrime_inflateReset_inflateSetDictionary_inflateSync_inflateSyncPoint_inflate_copyright_inflate_fast_inflate_table_uncompress_zError_z_errmsg_zcalloc_zcfree_zlibCompileFlags_zlibVersion// 1264530311 0 407 ` .\Win32_LIB_Release\zlib1.res.\Win32_LIB_Release\zutil.obj.\Win32_LIB_Release\uncompr.obj.\Win32_LIB_Release\trees.obj.\Win32_LIB_Release\inftrees.obj.\Win32_LIB_Release\inflate.obj.\Win32_LIB_Release\inffast.obj.\Win32_LIB_Release\infback.obj.\Win32_LIB_Release\gzio.obj.\Win32_LIB_Release\deflate.obj.\Win32_LIB_Release\crc32.obj.\Win32_LIB_Release\compress.obj.\Win32_LIB_Release\adler32.obj /0 1264530311 100666 1300 ` L‡3_K€.debug$SYŒ@B.rsrc$01Xæ>@@.rsrc$028H@@. 'C:\DOCUME~1\ssturges\LOCALS~1\Temp\lnk2#Microsoft CVTRES 5.00.1735.1€0€ H8H84VS_VERSION_INFO½ïþ?–StringFileInfor040904E4dFileDescriptionzlib data compression library,FileVersion1.2.34 InternalNamezlib1.dll|,LegalCopyright(C) 1995-2004 Jean-loup Gailly & Mark Adler< OriginalFilenamezlib1.dll*ProductNamezlib0ProductVersion1.2.3‚5CommentsDLL support by Alessandro Iacopetti & Gilles VollantDVarFileInfo$Translation ä@comp.idÇÿÿ.debug$SY.rsrc$01X.rsrc$028$R000000/30 1264530310 100666 3064 ` L†3_KÌB.drectve(„ .rdata(¬Ô @0@.data8@0À.data M@0À.dataZ@0À.data n@0À.data y@0À.data †@0À.bss€0À.data ‘@0À.dataœ@0À.text¬¼ P`.dataÆ@0À.debug$FÌÜHB.textæ P`.debug$FöHB.text 0 P`.debug$F:JHB.text Tt P`.debug$F~ŽHB.text˜¨ P`.debug$F²ÂHB-defaultlib:MSVCRT -defaultlib:OLDNAMES #   $incompatible versionbuffer errorinsufficient memorydata errorstream errorfile errorstream endneed dictionary¸Ã)1.2.3&¸UÃ.‹D$º …+Ñ‹Ã3‹D$¯D$ PÿƒÄà 98‹D$PÿYÃ? >.fileþÿgD:\temp\zlib\zutil.c@comp.id6& ÿÿ.drectve(WÈ Ç.rdata( .dataÖ¯E+.data }Å8.dataVxCY.data ¬Sä‚.data îE&:¡.data Dí<Â.bss á .data  õovÉñ .data IqèÝ .text j¶ 5 .data {M-B .debug$F .textÓ^¨\ .debug$F.text í—jâ_zError .debug$FˆmÚ¯.text Pyad_zcalloc n .debug$Fék° .text2 _zcfree | .debug$Fˆ_z_errmsg??_C@_0BF@HPBB@incompatible?5version?$AA@??_C@_0N@EHHN@buffer?5error?$AA@??_C@_0BE@EMHE@insufficient?5memory?$AA@??_C@_0L@EBEB@data?5error?$AA@??_C@_0N@OPOA@stream?5error?$AA@??_C@_0L@DFEP@file?5error?$AA@??_C@_00A@?$AA@??_C@_0L@JPFB@stream?5end?$AA@??_C@_0BA@FKCH@need?5dictionary?$AA@_zlibVersion??_C@_05CNKG@1?42?43?$AA@_zlibCompileFlags__imp__malloc__imp__free/60 1264530310 100666 852 ` L†3_KÞ.drectve(´ .text°ÜŒ P`.data¾@0À.debug$FÄÔHB-defaultlib:MSVCRT -defaultlib:OLDNAMES ƒì8‹L$H‹D$D‹T$$N$HB.text€X$ P`.debug$FØ)è)HB.text°ò)¢* P`.debug$FÀ*Ð*HB.text@Ú*/ P`.debug$F`/p/HB.textPz/ P`.debug$FÊ/Ú/HB.text ä/ P`.debug$F00HB.text0 P`.debug$F®0¾0HB.text€È0 P`.debug$FH1X1HB.text b12 P`.debug$F 22HB-defaultlib:MSVCRT -defaultlib:OLDNAMES 4       ŒLÌ,¬lìœ\Ü<¼|ü‚BÂ"¢bâ’RÒ2²rò ŠJÊ*ªjêšZÚ:ºzú†FÆ&¦fæ–VÖ6¶vöŽNÎ.®nîž^Þ>¾~þAÁ!¡aá‘QÑ1±qñ ‰IÉ)©ié™YÙ9¹yù…EÅ%¥eå•UÕ5µuõ MÍ-­mí]Ý=½}ý  “ “ S S Ó Ó 3 3 ³ ³ s s ó ó  ‹ ‹ K K Ë Ë + + « « k k ë ë   › › [ [ Û Û ; ; » » { { û û   ‡ ‡ G G Ç Ç ' ' § § g g ç ç   — — W W × × 7 7 · · w w ÷ ÷    O O Ï Ï / / ¯ ¯ o o ï ï   Ÿ Ÿ _ _ ß ß ? ? ¿ ¿   ÿ ÿ @ `P0pH(hX8xD$dT4tƒCÃ#£cã         (08@P`p€ Àà  0@`€À€  0@`è‹D$Pˆ”ˆ ‰ˆ ˆ| ‰ˆ0 3ÉÇ€ ‰$ Ç€, Ç€8 f‰ˆ¸‰ˆ¼Ç€´èYÃ0 @ Jf#lËT$V¹3ö‚”f‰0ƒÀIu÷‚ˆ ¹f‰0ƒÀIu÷‚| ¹f‰0ƒÀIu÷‰²¬‰²¨‰²°‰² fÇ‚”^Ãf#‹D$‹ˆ¼ƒù ~b‹T$SV‹òÓæ‹HWf °¸‹pŠ˜¸ˆ1‹p‹x3ÉŠˆ¹F‰pˆ 7‹H‹°¼A‰Hf¹f+Î_fÓêƒÆó‰°¼^[f‰¸ë‹T$Óâf ¸ƒÁ‰ˆ¼‹L$ ‹T$jQRPèƒÄÕ}(SV‹t$ W¸‹Ž¼ƒù ~]‹VÓà‹Nf †¸І¸ˆ‹N‹VA‰N‹Á3ÉŠŽ¹ˆ ‹F@f¹‰F‹†¼f+ȺfÓêƒÀ󉆼f‰–¸ëÓàf †¸ƒÁ‰Ž¼‹Ž¼3Òf‹¸+Â;È¡~^%ÿÿ‹øÓç‹Nf ¾¸‹~Šž¸ˆ9‹~‹^3ÉŠŽ¹G‰~ˆ ;‹N‹¾¼A‰Nf¹f+ÏTðfÓ艖¼f‰†¸ëÓàf †¸Ê‰Ž¼V苎¼‹–´+уă ƒú ƒù ¸~]‹VÓà‹Nf †¸І¸ˆ‹N‹VA‰N‹Á3ÉŠŽ¹ˆ ‹F@f¹‰F‹†¼f+ȺfÓêƒÀ󉆼f‰–¸ëÓàf †¸ƒÁ‰Ž¼‹Ž¼3Òf‹¸+Â;È¡~^%ÿÿ‹øÓç‹Nf ¾¸‹~Šž¸ˆ9‹~‹^3ÉŠŽ¹G‰~ˆ ;‹N‹¾¼A‰Nf¹f+ÏTðfÓ艖¼f‰†¸ëÓàf †¸Ê‰Ž¼VèƒÄdž´_^[ÑŸs»É@sU-SU‹l$V‹t$3ÀW‹Ž„…É~V…ív‹ƒx,u VèƒÄŽ QVè–$ RVèVè‹–¨‹Ž¬ƒÂ ƒÁ ÁêÁéƒÄ;ÊwëM‹Ñ};úw‹\$…Ût‹|$ WUSVèƒÄéXƒ¾ˆ„º;Ê„²‹Ž¼‹|$ ƒù W~Z‹Ú‹nÓãf ž¸‹^ŠŽ¸ˆ +‹^‹nC‰^‹Ë3ÛŠž¹ˆ)‹N‹ž¼A‰Nf¹f+ËfÓêƒÃ󉞼f‰–¸ëÓâf –¸ƒÁ‰Ž¼‹Ž @P‹†( @APQVè–ˆ †”RPVèƒÄ鑋޼‹|$ ƒù G~Z‹ÐÓâ‹Nf –¸‹VŠž¸ˆ‹V‹^B‰V‹Ê3ÒŠ–¹ˆ‹N‹–¼A‰Nf¹f+ÊfÓèƒÂó‰–¼f‰†¸ëÓàf †¸ƒÁ‰Ž¼hhVèƒÄ VèƒÄ…ÿt VèƒÄ_^][Ã&i67C7IK‹(>URdÝâèdñ#þx 2ƒì‹D$SUV‹t$W‹8‹@ƒÍÿ‹‹H 3À‰L$;ȉl$‰†PdžT=~>‹×fƒ:t$‹ŽP‰D$A‹è‰ŽP‰„Ž\ Æ„0XëfÇB‹L$@ƒÂ;Á|Ä‹ŽPƒù}]ƒý}E‹Åë3ÀA‰ŽP‰„Ž\ fLJƄX‹–¨J…Û‰–¨t3Éf‹Lƒ‹†¬+Á‰†¬‹ŽPƒù|§‰l$‹T$ ‰j‹†P™+‹ØÑûƒû|SWVèƒÄ Kƒû}ï‹D$‰D$‡‰D$‹†P‹ž` jW‹Œ†\ HV‰Ž` ‰†Pè‹–T‹®` ƒÄ J‹Â‰–T‰œ†\ ‹ŽTI‹Á‰ŽT‰¬†\ f‹¯fŸ‹D$f‰Š„XŠŒ.X:Ár%ÿëáÿ‹Á‹L$þÀjWˆ„X‹D$$f‰L¯f‰LŸ‰Ž` AƒÀV‰L$ ‰D$(苆PƒÄ ƒø*ÿÿÿ‹–T‹Ž` J‰–T‹Â‹T$ RV‰Œ†\ è‹D$Æ< VPWèƒÄ_^][ƒÄÃý<><Ù<A$F37‹D$SUV‹t$‹PW‹¬°\ 6;ʉl$‹|$}4‹´ˆ` ‹¬ˆ\ f‹·f‹¯f;ÓruŠ”XŠœ(X:ÓwA‹l$‹´ˆ\ f‹¯f‹·f;Ór/uŠ”(XŠœX:Óv+‹T$‰L$Ñቴ\ ‹P;Ê~‡‹L$_^‰¬ˆ\ ][ËT$_^‰¬\ ][ɬ°\ _^][ÃÑ<ƒì‹D$$SUV‹‹H‹@‰L$W3ö‹‹H‹h‰T$‹P‰L$$‰T$ ‹T$0¹3Àº< ‰t$ó«‹‚T‰l$(‹Œ‚\ f‰t‹‹²TFþ=©„²\ ‰D$0¸=+Æð‰D$‰t$4‹L$03À3ÿ‹ f‹D‹f‹|ƒ‹Ç@;Å~ ‹|$‹ÅG‰|$‹|$f‰D‹;Ï`‹t$ fÿ„B< 3ÿ;Î| ‹ù+þ‹t$$‹<¾f‹4‹Çæÿÿ¯Æ‚¨‹D$…Àt"‹l$3Àf‹D‹Š¬Ç‹l$(¯ÆÈ‰Š¬‹t$4‹L$0‹D$ƒÁH‰L$0‰D$…Sÿÿÿ‹|$…ÿ„ÔEÿfƒ¼B< ŒB< u ƒéHfƒ9töfÿŒB< fƒ„B> fÿŒj< ƒï…ÿÁ…í‹ý„‹¬j< ‰l$3Àf‹E…À‰D$0tb¬²\ ‹t$4‹MüNƒí‰t$4‹t$;Ήl$(8t‹3Àf‹;Çt"‹ï+è3Àf‹‹¯è‹‚¨Å‹l$(‰‚¨f‰>‹D$0H‰D$0…Àu©‹t$4‹l$Oƒí…ÿ‰l$u€_^][ƒÄÃ!A‹T$ ƒì 3ÀL$Vt$+ÖW¾f‹< ƒÁføÑç‹ÇNf‰Aþuë‹D$0…À|6‹t$,x3Éf‹N…Étf‹TLQ‹Â%ÿÿBPf‰TLèƒÄf‰ƒÆOuÑ_^ƒÄ Ã]nsFV‹t$‹† Ž”PQVè‹–( †ˆ RPVèŽ0 QVèƒÄ ¸3ÒŠfƒ¼–~ uHƒø}ç‹–¨L@щ–¨^ÃP)P67FoKQ‹D$ S3ÉVf‹HW3ÿÇD$ ÿÿÿÿ…ɺ¾u ºŠ¾‹\$…ÛfÇD˜ÿÿŒŸCU‰\$‹\$h‹Á3Éf‹MG;ú};Átn;þ} f¼ƒ| ë0…Àt;D$tfÿ„ƒ| fÿƒ¼ ëƒÿ  fÿƒÀ ëfÿƒÄ 3ÿ‰D$…Éu ºŠ¾ë;Áu º¾ë º¾‹D$ƒÅH‰D$…oÿÿÿ]_^[YÃçPSU‹D$V‹t$W‹Ž¼ƒù ~]ÿþÿÿ‹ÐÓâ‹Nf –¸‹VŠž¸ˆ‹N‹~3ÒŠ–¹A‰Nˆ9‹–¼‹nf¹f+ÊEfÓèƒÂõ‰n‰–¼f‰†¸ëÿþÿÿÓàf †¸ƒÁ‰Ž¼‹Ž¼ƒù ~_‹T$Bÿ‹ÐÓâ‹Nf –¸‹VŠž¸ˆ‹N‹~3ÒŠ–¹A‰Nˆ9‹–¼‹nf¹f+ÊEfÓèƒÂõ‰n‰–¼f‰†¸ë‹D$HÓàf †¸ƒÁ‰Ž¼‹Ž¼‹l$ ƒù Eü~Z‹ÐÓâ‹Nf –¸‹VŠž¸ˆ‹V‹~B‰V‹Ê3ÒŠ–¹ˆ9‹N‹–¼A‰Nf¹f+ÊfÓèƒÂô‰–¼f‰†¸ëÓàf †¸ƒÁ‰Ž¼3ÿ…펣‹Ž¼ƒù ~l3Ò3ÀŠ—f‹„–~ ‹ÐÓâ‹Nf –¸‹VŠž¸ˆ‹V‹^B‰V‹Ê3ÒŠ–¹ˆ‹N‹–¼A‰Nf¹f+ÊfÓèƒÂó‰–¼f‰†¸ë#3ÀЇf‹”†~ fÓâf –¸ƒÁ‰Ž¼G;ýŒ]ÿÿÿ‹D$Ž”HPQVè‹T$(†ˆ JRPVèƒÄ_^][Ã¥FZYZeUƒì‹D$S3Û3Òf‹XV…ÛWÇD$ ÿÿÿÿ¹¾u ¹Š¾‹|$ …ÿŒ0ƒÀG‰D$ ‹D$U‰|$‹|$$‹ë3ÛBf‹;щ\$‰T$ };ë„ä;Ö¬‹ˆ¼3öf‹´¨~ ¿+þ;Ï~g3Òf‹”¨| ‹úÓç‹Hf ¸¸‹xŠ˜¸ˆ9‹x‹X3ÉŠˆ¹G‰xˆ ‹H‹¸¼A‰Hf¹f+ÏfÓêf‰¸T7ð‰¼‹T$ ëf‹¼¨| fÓçf ¸¸Ήˆ¼J‰T$ …Yÿÿÿéü…í„Á;l$„¡‹ˆ¼3öf‹´¨~ ¿+þ;Ï~g3Òf‹”¨| ‹úÓç‹Hf ¸¸‹xŠ˜¸ˆ9‹x‹X3ÉŠˆ¹G‰xˆ ‹H‹¸¼A‰Hf¹f+ÏfÓêf‰¸T7ð‰¼‹T$ ëf‹¼¨| fÓçf ¸¸Ήˆ¼J‰T$ ‹ˆ¼3öf‹°¾ ¿+þ;Ï~f3Òf‹¼ ‹úÓç‹Hf ¸¸‹xŠ˜¸ˆ9‹x‹X3ÉŠˆ¹G‰xˆ ‹H‹¸¼A‰Hf¹f+ÏfÓêf‰¸T7ð‰¼‹T$ ëf‹¸¼ fÓçf ¸¸Ήˆ¼‹ˆ¼ƒù~^ƒÂý‹òÓæ‹Hf °¸‹pŠ˜¸ˆ1‹p‹x3ÉŠˆ¹F‰pˆ >‹H‹°¼A‰Hf¹f+ÎfÓêƒÆò‰°¼f‰¸éGƒÂýÓâf ¸ƒÁé-ƒú ‹ˆ¼3öf‹°Â ¿+þ;Ï~f3Òf‹À ‹úÓç‹Hf ¸¸‹xŠ˜¸ˆ9‹x‹X3ÉŠˆ¹G‰xˆ ‹H‹¸¼A‰Hf¹f+ÏfÓêf‰¸T7ð‰¼‹T$ ëf‹¸À fÓçf ¸¸Ήˆ¼‹ˆ¼ƒù ~^ƒÂý‹òÓæ‹Hf °¸‹pŠ˜¸ˆ1‹p‹x3ÉŠˆ¹F‰pˆ >‹H‹°¼A‰Hf¹f+ÎfÓêƒÆó‰°¼f‰¸é(ƒÂýÓâf ¸ƒÁ鋈¼3öf‹°Æ ¿+þ;Ï~f3Òf‹Ä ‹úÓç‹Hf ¸¸‹xŠ˜¸ˆ9‹x‹X3ÉŠˆ¹G‰xˆ ‹H‹¸¼A‰Hf¹f+ÏfÓêf‰¸T7ð‰¼‹T$ ëf‹¸Ä fÓçf ¸¸Ήˆ¼‹ˆ¼ƒù ~[ƒÂõ‹òÓæ‹Hf °¸‹pŠ˜¸ˆ1‹p‹x3ÉŠˆ¹F‰pˆ >‹H‹°¼A‰Hf¹f+ÎfÓêƒÆ÷‰°¼f‰¸ëƒÂõÓâf ¸ƒÁ‰ˆ¼‹\$3Ò…Û‰l$u ¹Š¾ë;ëu ¹¾ë ¹¾‹l$$‹|$ƒÅO‰l$$‰|$…âúÿÿ]_^[ƒÄÃuZ‹D$V‹t$ W‹ˆ ‹¤f‰4J‹˜‹¸ ‹L$ˆ :‹¸ G…ö‰¸ u fÿ„ˆ”ëJ‹°BN‰°3ÒŠ‘fÿ„˜þŒ˜s 3ÉŠŽë Áî3ÉŠŽfÿ„ˆˆ ‹ˆœ‹° I3Ò;ñ_”‹Â^ÃZy†«_‹D$ƒì3É‹ SU‹l$VW…Ò„p‹¤3ÿ3Ûf‹‹„$œÆD$@ÆD$f‰l$‹‹L$_‰ ‹ƒÂ‰‰ ‹ƒÁ‰Ç^]3À[ƒÄ|ùD$Nfƒ8u AƒÀƒùvñ;Ñs‰L$¾T$N‹Æ3ÿöf‹:+÷x@ƒÂƒøvì3Ò;ò~9”$tƒýt _^]ƒÈÿ[ƒÄ|Ãf‰T$n3Àf‹tNftnƒÀƒøf‰tnr鋼$¤;Úv5‹´$”f‹f…Àt%ÿÿ3íf‹lDl3Àf‰of‹fÿDDlDDlBƒÆ;ÓrÒ‹„$ºÿÿÿÿƒèt?HtÇD$4ÇD$0‰T$,ë6¸ÇD$,-‰D$4¸-‰D$0ë‰|$0‰|$4ÇD$,‹Ù‹Œ$œ3í‰T$8‹‹L$‰D$¸Óà‰l$‰D$<‰D$(Hÿ‰L$@‹Œ$ƒùu =°ƒp‰|$$‹T$‹L$$‹t$,ŠÃf‹ *ˆD$‹Á%ÿÿ;Æ} ÆD$f‰L$ë(~‹L$0Š AˆL$‹L$4f‹Af‰D$ë ÆD$`fÇD$‹Ë‹D$<+ʺÓâ‹L$‹ýÓï‹L$‰D$D4•ø ¹‹|$+Â+Î…À‰9uöKÿ¸Óà…ÅtÑè…Åuú3ö;Æt Pÿ#ÕЋêë3í‹T$$ƒÂfÿL\Lf9t\L‰T$$u;\$ „ë‹Ê‹”$”3À3Ûf‹f‹B;\$† ÿÿÿ‹t$@‹D$8#õ;ð‰t$H„õþÿÿ‹T$…Òu ‹D$‰D$‹Ð‹L$‹D$D‹|$ ¸‰L$‹Ë+ÊÑÓà;×s"tTL3ÿf‹>+Ç…À~‹|$ ABƒÆÑà;×ræ‹t$H‹T$(¸Óà‰D$<Ћ„$‰T$(ƒøu ‹Â=°ƒÛ‹Ö‹´$œ‰T$8‹ˆ ‹ŠD$ˆD‘‹‹L$+ÈÁùf‰Lé>þÿÿ‹T$ŠÃ*Â;îÆD$@ˆD$f‰t$ta;Öt)‹L$@‹D$8#Í;Èt‹”$œ‹\$‰t$ˆ\$‹‹Ö‰D$‹|$‹Å‹ÊÓè‹L$‰ ‡Kÿ¸Óà…ÅtÑè…Åuú;Æt Hÿ#ÍÈ‹éuŸ‹T$(‹„$œ_^ •‹Ñ]‰‹”$”‹D$[‰3ÀƒÄ|Ã_^]¸[ƒÄ|É ‘œ ² ˜.fileþÿgD:\temp\zlib\inftrees.c@comp.id6& ÿÿ.drectve(D/î..rdata0=ð"°Ap_0~.text ÞHÒ\‘ .debug$F _?dext@?1??inflate_table@@9@9_?dbase@?1??inflate_table@@9@9_?lext@?1??inflate_table@@9@9_?lbase@?1??inflate_table@@9@9_inflate_copyright_inflate_table/155 1264530310 100666 17932 ` L0†3_K:5°.drectve(” .rdata¦¼@0@.text`b P`.debug$FÂÒHB.textPÜ P`.debug$F,<HB.textàF& P`.dataN@0À.debug$FTdHB.text nŽ P`.debug$F˜¨HB.text²²)N P`.data¾,@0À.dataÕ,@0À.dataê,@0À.data-@0À.data-@0À.data:-@0À.dataP-@0À.datal-@0À.data$†-@0À.dataª-@0À.dataÃ-@0À.dataà-@0À.dataó-@0À.data.@0À.data .@0À.data7.@0À.dataK.@0À.debug$Ff.v.HB.text0€.°. P`.debug$FÄ.Ô.HB.text Þ. P`.debug$Fþ/0HB.textP0 P`.debug$Fh0x0HB.textà‚0b1 P`.debug$F€11HB.text0š1 P`.debug$FÊ1Ú1HB.textä1ä2 P`.debug$F33HB.text`3 P`.debug$F|3Œ3HB.text0–3 P`.debug$FÆ3Ö3HB.text@à3 P`.debug$F 505HB-defaultlib:MSVCRT -defaultlib:OLDNAMES `Psp0 À `  €@ àX ;x8 Ðh( °ˆH ðTã+t4 È d$ ¨„D è\ ˜S|< Øl, ¸ ŒL øR£#r2 Ä b" ¤‚B äZ ”Cz: Ôj* ´ ŠJ ôV@3v6 Ìf& ¬†F ì ^ œc~> Ün. ¼ŽN ü`Qƒq1  a! ¢A âY ’;y9 Òi) ² ‰I òU+u5 Ê e% ª…E ê] šS}= Úm- º M úSÃ#s3 Æ c# ¦ƒC æ[ –C{; Ök+ ¶ ‹K öW@3w7 Îg' ®‡G î _ žc? Þo/ ¾O þ`Psp0 Á ` ¡€@ áX ‘;x8 Ñh( ±ˆH ñTã+t4 É d$ ©„D é\ ™S|< Ùl, ¹ ŒL ùR£#r2 Å b" ¥‚B åZ •Cz: Õj* µ ŠJ õV@3v6 Íf& ­†F í ^ c~> Ýn. ½ŽN ý`Qƒq1 à a! £A ãY “;y9 Ói) ³ ‰I óU+u5 Ë e% «…E ë] ›S}= Ûm- » M ûSÃ#s3 Ç c# §ƒC ç[ —C{; ×k+ · ‹K ÷W@3w7 Ïg' ¯‡G ï _ Ÿc? ßo/ ¿O ÿA@!  @a`10  Á@     ‹T$3É;ÑtM‹B;ÁtF‰H‰J‰J‰JÇB0‰‰H‰H ‰H ‰H(‰H,‰H0‰H8‰H<ˆ0Ç@€‰Hl‰HP‰HL3ÀøþÿÿÿÃ] ‹D$V…Àt>‹@…Àt7‹L$ ƒù.‹P<4 ƒþ w#W¿Óç‹L$‰p3íUUUè‰CÆD$0ÆD$1‹‹KD$0jPQè‰CƒÄ‰l$Ç‹ÅéÜ‹C ÇC…ÀtÇ@0ÿÿÿÿöC„»‹L$3Ò‹Á%ÿÁàÁéÁ¹÷ñ…Ò…—‹L$‹Ñƒâ€út‹D$TÇ@Ç‹Áés‹C$ƒíÁé‰L$ƒáƒÁ;Èv‹L$T‹D$ÇAÇéBº3íÓâUUU‰Sè‹T$‹L$`÷ÒâƒÄ €Î ‰CÁê‰A0‰‰l$‹Åé‹D$TÇ@‹D$Çéèƒýs*…ÿ„93ÉOЉ|$‹Ñ‹ÍÓâƒÅÂFƒý‰D$‰t$rÖ<‰Ct‹L$TÇAéœöÄàt‹T$TÇB釋K …ÉtÁèƒà‰‹CöÄt%‹D$jˆD$(ÁèˆD$)‹KD$(PQèƒÄ ‰C3À3íÇëƒý s …ÿ„–3Ò‹ÍŠOÓâƒÅÂFƒý ‰D$rà‹K …Ét‰A‹CöÄt7‹D$jˆD$(‹È‹ÐÁèÁéÁêˆD$+ˆL$)ˆT$*‹KD$(PQèƒÄ ‰C3À3íÇëƒýs(…ÿ„3Ò‹ÍŠOÓâƒÅ‰|$ÂFƒý‰D$‰t$rØ‹K …Ét‹Ðâÿ‰Q‹K Áè‰A ‹CöÄt%‹D$T$$ˆD$$jÁèˆD$)‹CRPèƒÄ ‰C3À3í‰D$Ç‹KöÅtsƒýs*…ÿ„‘3ÉOЉ|$‹Ñ‹ÍÓâƒÅÂFƒý‰D$‰t$rÖ‹K ‰C@…Ét‰A‹CöÄt%‹D$jˆD$(ÁèˆD$)‹KD$(PQèƒÄ ‰C3À3í‰D$ë‹K …ÉtÇAÇ‹KöÅ„¬‹K@;ωL$v‹Ï‰L$…É„ˆ‹S …ÒtH‹R…Ò‰T$8t=‹S ‹s@‹z‹R+þ49;òv+׋ʋT$8‹t$ú‹ÑÁéó¥‹Êƒáó¤‹L$‹|$‹t$‹SöÆt‹D$‹KPVQè‹L$(‰C‹D$ƒÄ ‹S@+ùñ+щ|$‰t$‰S@‹K@…É…_ÇC@Ç‹KöÅ„–…ÿ„>3Ò3ÉŠ 2B‰T$‹S …Ò‰L$,t,‹R…Ò‰T$8t!‹K ‹S@;Q ‹L$,s‹|$8ˆ ‹S@‹|$B‰S@…Ét‹T$;×r³‹SöÆt‹T$‹CRVPè‹L$8‰C‹D$ƒÄ ‹T$+úò…ɉ|$‰t$…²ë‹K …ÉtÇAÇC@Ç‹KöÅ„–…ÿ„3Ò3ÉŠ 2B‰T$‹S …Ò‰L$,t,‹R$…Ò‰T$8t!‹K ‹S@;Q(‹L$,s‹|$8ˆ ‹S@‹|$B‰S@…Ét‹T$;×r³‹SöÆt‹L$‹SQVRè‹L$8‰C‹D$ƒÄ ‹T$+úò…ɉ|$‰t$…õë‹K …ÉtÇA$Ç‹KöÅtRƒýs*…ÿ„Ê3ÉOЉ|$‹Ñ‹ÍÓâƒÅÂFƒý‰D$‰t$rÖ‹Káÿÿ;Át‹T$TÇBé'3í‰l$‹C …Àt‹KÁù ƒá‰H,‹S ÇB0jjjè‹L$`‰CƒÄ ‰A0‹D$Ç éã ƒý s(…ÿ„43Ò‹ÍŠOÓâƒÅ‰|$ÂFƒý ‰D$‰t$r؋ȋÐáÿâÿÁáÊ3ÒŠt$ÁáÊÁèÁ‹L$T‰C‰A03À‰D$3íÇ ‹K …É„† jjjè‹T$`‰CƒÄ ‰B0‹D$Ç ƒ|$X„Ÿ ‹K…Ét‹ÍǃáÓè+é‰D$é" ƒýs&…ÿ„s 3ÉOЉ|$‹Ñ‹ÍÓâƒÅÂFƒý‰t$rڋȃáÑè‰K‹ÈƒáMƒù‰D$wdÿ$ÁèÇ ‰D$ƒíé Sè‹D$ƒÄÁèljD$ƒíé  ÁèljD$ƒíé‹ ‹T$TÇBÇÁè‰D$ƒíék ‹ÍƒáÓè+éƒý ‰D$s*…ÿ„¯ 3ÉOЉ|$‹Ñ‹ÍÓâƒÅÂFƒý ‰D$‰t$r֋ЋÈ÷ÒáÿÿÁê;Êt‹L$TÇAé 3À‰K@‰D$3íÇ‹K@…ɉL$„7;Ïv‹Ï‰L$‹T$ ;Êv‹Ê‰L$…É„* ‹t$‹|$(‹ÑÁéó¥‹Ê‹T$ƒáó¤‹L$‹t$‹|$ +ñщt$‹t$(‰T$‹S@+ùñ+щ|$ ‹|$‰t$(‹t$‰S@éu ƒýs&…ÿ„Æ 3ÉOЉ|$‹Ñ‹ÍÓâƒÅÂFƒý‰t$rڋȃíƒáÁèÁ‹ÐÁè‰K`‹ÈƒáƒâƒÁB‰K\‹K`Áèù‰Sd‰D$‡ÿ‹Êƒù‡ôÇChÇ‹Kh‹S\;Ês^ƒýs$…ÿ„8 3Ò‹ÍŠOÓâƒÅ‰|$ÂFƒý‰t$rÜ‹Sh3ÿŠÈƒíf‹t_‹F<‹n8‹ÈǃáÓå+Á3Ƀø‰F<‰n8r%¸øÿÿÿŠV8ˆT ‹^<‹n8Ø‹ÓAÁíƒú‰n8‰^ $L1866¯ $L1842, $L1817² .data¾ß! 3$L1787 .dataÛC5c_adler32 .dataO̼.data#bº_crc32 $L1741‘ $L2876t .debug$F .text0 å]Ñë .debug$F .text! ö0ø! .debug$F"!.text#PÏÇ!# .debug$F$#.text%àx(ìp% .debug$F&%.text'00z¦(' .debug$F('.text)sÿ‚:) .debug$F*).text+`69ÕG+ .debug$F,+.text-0ŸwWS- .debug$F.-.text/@Ã,Êie/ .debug$F0/r_?order@?1??inflate@@9@9_?distfix@?1??fixedtables@@9@9_?lenfix@?1??fixedtables@@9@9_inflateReset_inflatePrime_inflateInit2_??_C@_05CNKG@1?42?43?$AA@_inflateInit_??_C@_0BH@PBLF@incorrect?5length?5check?$AA@??_C@_0BF@OBFI@incorrect?5data?5check?$AA@??_C@_0BO@EEIF@invalid?5distance?5too?5far?5back?$AA@??_C@_0BG@EGK@invalid?5distance?5code?$AA@??_C@_0BM@CHJP@invalid?5literal?1length?5code?$AA@_inflate_fast??_C@_0BG@DILP@invalid?5distances?5set?$AA@??_C@_0BM@BLEK@invalid?5literal?1lengths?5set?$AA@??_C@_0BK@BNJN@invalid?5bit?5length?5repeat?$AA@??_C@_0CE@LAKP@too?5many?5length?5or?5distance?5symb@??_C@_0BJ@PEEP@invalid?5code?5lengths?5set?$AA@_inflate_table??_C@_0BN@DBOJ@invalid?5stored?5block?5lengths?$AA@??_C@_0BD@IFBC@invalid?5block?5type?$AA@??_C@_0BE@GABH@header?5crc?5mismatch?$AA@??_C@_0BJ@LBGI@unknown?5header?5flags?5set?$AA@??_C@_0BH@NLIB@incorrect?5header?5check?$AA@??_C@_0BE@FAJE@invalid?5window?5size?$AA@??_C@_0BL@KPEJ@unknown?5compression?5method?$AA@_fixedtables_updatewindow_inflateEnd_inflateSetDictionary_inflateGetHeader_inflateSync_syncsearch_inflateSyncPoint_inflateCopy/187 1264530311 100666 2130 ` L‡3_KD.drectve( .text,¼ P`.dataÚ@0À.dataö@0À.data @0À.debug$F*:HB-defaultlib:MSVCRT -defaultlib:OLDNAMES ƒìD‹D$HS‹\$PU‹‹H‹hJV‹p ‹@Lû‰L$,‹ÈN+Ë΋]<„0ÿþÿÿ‰L$@‹M(‰D$0‹E,‰L$$‹M0‰D$D‹E4‰L$‹ML‰D$(‹EP‰L$‹MT‰D$ ¸WÓà‹MX‹}8‰l$‰T$H‰D$8¸ÓàH‰D$<ƒûs%B3ÉŠ ‹Á‹ËÓàƒÃ3ÉŠJøB‹Á‹ËÓà‰T$øƒÃ‹L$8‹D$ #Ï‹ˆ‰D$L‹L$MáÿÓï+Ù%ÿtL¨uT¨@…/¹‰L$\‹È‹D$\Óà‹L$NáÿÿH#ÇÁ‹L$ ‹‰D$L‹L$MáÿÓï+Ù%ÿu´ŠD$NFˆé¬‹L$Náÿÿƒà‰L$\t8;ØsB3ɉT$Š ‹é‹ËÓåýƒÃ½‹ÈÓå‹L$\M#ïÍ‹l$‰L$\‹ÈÓï+؃ûs#B3À‹ËƒÃŠÓà3ÉŠJøB‹Á‹ËÓà‰T$øƒÃ‹L$<‹D$$#Ï‹ˆ‰D$L‹L$Máÿ%ÿÓï+Ù¨uJ¨@…3¹‰L$‹È‹D$Óà‹L$NáÿÿH#ÇÁ‹L$$‹‰D$L‹L$Máÿ%ÿÓï+Ù¨t¶‹L$Nƒàáÿÿ;؉L$s,B3ɉT$Š ‹é‹ËÓåƒÃý;ØsB3ɉT$Š ‹é‹ËÓåýƒÃ½‹ÈÓå+ØM#ï‹Í‹l$é‹ÈÓï‹L$D‹Æ+Á‰l$;è†+è‹D$H;è‡[‹D$,Hÿ‹D$…Àu&‹D$(+ÅÈ‹D$\;胉+ʼnD$\ŠAAFMˆuöëo;ÅsO+ÅD$(È‹D$+è‹D$\;ès]+ʼnD$\ŠAAFMˆuö‹L$,‹D$‹l$\I;Ås<+è‰D$@‰l$\‹èŠAAFMˆuöë+ÅÈ‹D$\;ès+ʼnD$\ŠAAFMˆuö‹D$‹Î+ȃ|$\v2¸«ªªª÷d$\‹êÑíŠQAFAˆŠFAˆŠFˆ‹T$\ƒêM‰T$\uß‹T$‹D$\…ÀtYŠAAFˆ‹D$\ƒøvIŠIFˆëA‹Æ+ÅŠH@F@ˆŠF@ˆŠFˆ‹L$\ƒéƒù‰L$\wÝ…ÉtŠH@Fˆ‹L$\ƒùvŠ@Fˆ‹l$;T$0sP;t$4sJé›üÿÿ‹L$X‹D$‹èÇAÇë,‹L$XÇAë¨ t ÇE ë‹D$XÇ@ÇE‹ÃÁè+РŸ+Ù‹ËÓà‹L$XH#øB‰F‰A ‹D$0+ƒÀ‰A‹D$4+ƉA‰}8_‰]<^][ƒÄDÃ1 invalid literal/length codeinvalid distance codeinvalid distance too far back.fileþÿgD:\temp\zlib\inffast.c@comp.id6& ÿÿ.drectve(ëQä±.text UÅ  .datayÔ*.data°–~æE.data,Ͻp.debug$F¦_inflate_fast??_C@_0BM@CHJP@invalid?5literal?1length?5code?$AA@??_C@_0BG@EGK@invalid?5distance?5code?$AA@??_C@_0BO@EEIF@invalid?5distance?5too?5far?5back?$AA@/219 1264530311 100666 10271 ` L‡3_K£R.drectve(\ .rdata¦„@0@.textÐ* ú  P`.data @0À.debug$F . HB.textP8 ˆ P`.dataÈ@0À.dataæ@0À.dataü@0À.data$@0À.data<@0À.dataR@0À.datan@0À.dataˆ@0À.data¡@0À.data¾@0À.debug$FÑáHB.text0ë P`.debug$F/?HB.text@I P`.debug$F‰™HB-defaultlib:MSVCRT -defaultlib:OLDNAMES `Psp0 À `  €@ àX ;x8 Ðh( °ˆH ðTã+t4 È d$ ¨„D è\ ˜S|< Øl, ¸ ŒL øR£#r2 Ä b" ¤‚B äZ ”Cz: Ôj* ´ ŠJ ôV@3v6 Ìf& ¬†F ì ^ œc~> Ün. ¼ŽN ü`Qƒq1  a! ¢A âY ’;y9 Òi) ² ‰I òU+u5 Ê e% ª…E ê] šS}= Úm- º M úSÃ#s3 Æ c# ¦ƒC æ[ –C{; Ök+ ¶ ‹K öW@3w7 Îg' ®‡G î _ žc? Þo/ ¾O þ`Psp0 Á ` ¡€@ áX ‘;x8 Ñh( ±ˆH ñTã+t4 É d$ ©„D é\ ™S|< Ùl, ¹ ŒL ùR£#r2 Å b" ¥‚B åZ •Cz: Õj* µ ŠJ õV@3v6 Íf& ­†F í ^ c~> Ýn. ½ŽN ý`Qƒq1 à a! £A ãY “;y9 Ói) ³ ‰I óU+u5 Ë e% «…E ë] ›S}= Ûm- » M ûSÃ#s3 Ç c# §ƒC ç[ —C{; ×k+ · ‹K ÷W@3w7 Ïg' ¯‡G ï _ Ÿc? ßo/ ¿O ÿA@!  @a`10  Á@     ‹D$S3ÛUV;ÃW„«ŠŠ :Á…›ƒ|$$8…‹t$;ót~‹l$;ëtv‹|$ƒÿ|mƒÿh‹F ‰^;Ãu ÇF ‰^(9^$uÇF$‹N(h0%jQÿV ƒÄ ;Ãu _^]¸üÿÿÿ[ú‹ÏÓâ‰F‰x$_‰h4^Ç@€‰P(‰X0‰X,]3À[Ã_^]¸þÿÿÿ[Ã_^]¸úÿÿÿ[ÃXg1.2.3Ç ‹D$ƒì(SU3í;Å„å‹X;݄ډhÇ ‰k‰k,‹V;ÍW‰L$t‹pë3ö‹C4‹K(‰D$ ‹ƒÀõ‰t$ƒø‰l$‰L$‡43ÒŠÿ$•‹C…Àt‹T$‹ýƒçÇ‹ÏÓê+ï‰T$éò ƒýsI‹|$D…öuD$PWÿT$H‹ðƒÄ…ö„ø ‹D$3ÉNЉt$‹Ñ‹ÍÓâ‹L$ƒÅÊ@ƒý‰L$‰D$r»‹D$‹ÈÑè‰D$ƒáƒàMƒø‰Kwlÿ$…‹L$Ç Áé‰L$ƒíéi Sè‹L$ƒÄÁéljL$ƒíéG ‹L$ÇÁé‰L$ƒíé. ‹T$<ÇBÇ‹L$Áé‰L$ƒíé ‹T$‹ýƒç‹Ï+ïÓêƒý ‰T$sI‹|$D…öuD$PWÿT$H‹ðƒÄ…ö„ý ‹D$3ÉNЉt$‹Ñ‹ÍÓâ‹L$ƒÅÊ@ƒý ‰L$‰D$r»‹L$‹Á÷Ñ%ÿÿÁé;Át‹D$<Ç@Çé 3í‰C@;ʼnl$„ËK@‹|$…ö‰L$$u‹D$DT$RPÿT$H‹ðƒÄ…ö‰t$„j …ÿu'‹{(‹C4‹L$LWPQ‰D$,‰|$(‰{,ÿT$TƒÄ …À…u 9t$$v‰t$$9|$$v‰|$$‹D$$‹t$‹|$ ‹È‹ÑÁéó¥‹Ê‹T$ ƒáÐó¤‹L$‹|$‹t$+Èø‰L$‰|$‹K@+ð+ȉt$‹t$‰T$ ‰K@…=ÿÿÿÇ é  ‹|$DƒýsI…öuD$PWÿT$H‹ðƒÄ…ö„¦ ‹D$3ÉNЉt$‹Ñ‹ÍÓâ‹L$ƒÅÊ@ƒý‰L$‰D$r»‹|$D‹D$ƒí‹ÈƒáÁèÁ‹ÐÁè‰K`‹ÈÁèƒâƒá‰D$‹C`BƒÁ=‰Sd‰K\‡b‹Âƒø‡W‹ÁÇCh…À†…ƒýsE…öuT$RWÿT$H‹ðƒÄ…ö„ø ‹D$3ÉNЉt$‹Ñ‹ÍÓâ‹L$ƒÅÊ@ƒý‰L$‰D$r»‹KhŠD$3Òƒàf‹M‹L$Áéf‰DSp‹ShB‰L$‹K\‹Âƒí;Á‰Sh‚{ÿÿÿ‹Kh¸;Ès!3É‹Sh3ÿf‹invalid distance too far backinvalid distance codeinvalid literal/length codetoo many length or distance symbolsinvalid distances setinvalid literal/lengths setinvalid bit length repeatinvalid code lengths setinvalid stored block lengthsinvalid block typeD ‹D$Ç@LÇ@T Ç@PÇ@Xà  !JV‹t$…öt#‹N…Ét‹F$…ÀtQ‹N(QÿЃÄÇF3À^øþÿÿÿ^Ã3O.fileþÿgD:\temp\zlib\infback.c@comp.id6& ÿÿ.drectve(@Ä£Ÿ.rdata¦+þã€!@.textÐä¯h^ _zcfree _zcalloc .data{M-p.debug$FYÑc‰.textP ™ÞpŠ $L2137˜$L2136ñ$L2133Ã.data,Ͻ—.data°–~æÍ.data yÔ*ø .data $;Ïù+ a $L1967g.data poã;o .data Ä€I÷› .data ÚÜLÎ .data—eÿ/ $L1762ê.data3 «B>$L1720€.data£.e*r$L1712\$L1711C$L1710!$L1709$L23644$L1677s$L2363$L2362 .debug$F.text0 å]Ñ› .debug$F.text@\]@f¨ .debug$F¸_?order@?1??inflateBack@@9@9_?distfix@?1??fixedtables@@9@9_?lenfix@?1??fixedtables@@9@9_inflateBackInit_??_C@_05CNKG@1?42?43?$AA@_inflateBack??_C@_0BO@EEIF@invalid?5distance?5too?5far?5back?$AA@??_C@_0BG@EGK@invalid?5distance?5code?$AA@??_C@_0BM@CHJP@invalid?5literal?1length?5code?$AA@??_C@_0CE@LAKP@too?5many?5length?5or?5distance?5symb@_inflate_fast??_C@_0BG@DILP@invalid?5distances?5set?$AA@??_C@_0BM@BLEK@invalid?5literal?1lengths?5set?$AA@??_C@_0BK@BNJN@invalid?5bit?5length?5repeat?$AA@??_C@_0BJ@PEEP@invalid?5code?5lengths?5set?$AA@_inflate_table??_C@_0BN@DBOJ@invalid?5stored?5block?5lengths?$AA@??_C@_0BD@IFBC@invalid?5block?5type?$AA@_fixedtables_inflateBackEnd /251 1264530311 100666 12602 ` L=‡3_K¨!».drectve(œ .rdataÄ @0@.text Ì ì  P`.debug$Fö  HB.textp €  P`.data> @0À.dataS @0À.debug$FY i HB.text@s ³  P`.dataÑ @0À.debug$FÙ é HB.textpó c P`.debug$Fw‡HB.text ‘1 P`.debug$FÇ×HB.text€áa P`.debug$Fu…HB.text°? P`.debug$FqHB.text°‹; P`.debug$FŸ¯HB.text0¹é P`.debug$FóHB.textP  P`.debug$F]mHB.text`w× P`.debug$FáñHB.textÐûË P`.debug$FéùHB.text€ƒ P`.debug$F¡±HB.text0»ë P`.debug$FõHB.text0? P`.debug$FIYHB.text@c£ P`.debug$F·ÇHB.textàѱ P`.debug$FÅÕHB.textßo P`.debug$F«»HB.textpÅ5 P`.debug$FScHB.text m P`.debug$F—§HB.text0± P`.debug$FáñHB.text û P`.debug$F+HB.textP5… P`.debug$F­½HB.textPÇ P`.debug$F?OHB.text0Y‰ P`.debug$F“£HB.text0­Ý P`.data7!@0À.bss€0À.debug$F:!J!HB.text0T!„! P`.debug$FŽ!ž!HB-defaultlib:MSVCRT -defaultlib:OLDNAMES ‹‹D$‹L$jÿPQèƒÄ à  ƒì\‹D$dSUV‹t$lW3ÛƒÏÿL$;ó‰|$‰\$‰D$‰L$t„i;Äajtÿ‹èƒÄ;ë„LSSS‰] ‰]$‰](‰]D‰]‰]H‰] ‰]‰]‰]@‰]8‰]<‰]d‰]h‰}lè‰EL‹þƒÉÿ3À‰]P‰]Xò®÷ÑQÿ‹ÐƒÄ;Ó‰UT„ã‹þƒÉÿ3Àò®÷Ñ+ù‹Á‹÷‹ú²rÁéó¥‹Èƒáó¤ˆ]\‹L$8uˆU\Š< $V‹t$…ötR€~\wuL‹F…Àu0‹N@‹FHQh@jP‰F ÿƒÄ=@tÇF8ÿÿÿÿÇF@‹T$‹D$ RPVèƒÄ ^øþÿÿÿ^Ã*/R.b-SV‹t$ W‹~ƒÿsg…ÿt ‹‹NDŠˆÿº@‹ÏÇ‹F@ÓúP‹FDÇRjPÿƒÄ…Àu‹N@öA tÇF8ÿÿÿÿ‹VЉV‹Â‹VDƒø‰s‰FX_^[Ë‹3ÉŠ;Ê…‹ 3ÒŠP;Ñ…õ‹NƒÀƒÁþV‰N‰èV‹øèƒÄƒÿ‹Ø…ÀöÃà…·¿VèƒÄOuôöÃt2VèV‹øèÁàøƒÄ‹ÇO…ÀtVèƒÄƒøÿt‹ÏO…ÉuëöÃtVèƒÄ…Àtƒøÿt VèƒÄ…ÀuîöÃtVèƒÄ…Àtƒøÿt VèƒÄ…ÀuîöÃt¿VèƒÄOuô‹V<_÷ÚÒƒâý‰V8^[ÃÇF8ýÿÿÿ_^[ÃÇFX_^[Ã@5zŒ­:µ:×:è:ð:::1:C:U:l:4V‹t$‹F<…ÀtƒÈÿ^ËF…ÀuHÿÇ‹F@‹NDPh@jQÿƒÄ‰F…Àu‹V@ÇF<ƒÈÿöB t‰F8^ËFD‰‹F3ÉH‰F‹Š@‰‹Á^Ã55t:SV‹t$ 3Û…öu^¸þÿÿÿ[ËFPW‹=…ÀtPÿ׃Ä‹F…ÀtŠF\IVf†‹D$jjPèƒÄ à €‹‹D$…Àt!€x\ru‹H<…Ét¸ËP83Ƀú”Á‹ÁÃ3ÀÃ,‹D$…Àt €x\ru‹@XÃ3ÀÕV‹t$WVèV‹øèÁàVøèÁàVøèƒÄƒøÿuÇF8ýÿÿÿÁàÇ_^Ã:::&:AšV‹t$…öu¸þÿÿÿ^À~\wu,jVèƒÄ…Àu‹FL‹N@PQè‹Vd‹F@RPèƒÄVèƒÄ^Ã{.¤;¤D?MŸS‹UV‹t$W‹|$½‹ÆW%ÿPÿÓƒÄÁîMuì_^][Ã¥0¤S‹\$UW…Ûu‹D$_][Çþÿÿÿ¡ËC8‹L$…À‰u _]¸[Ãøÿuÿ‹RÿƒÄ‹èë‹k…ít€}u‹C8¹Áà+È‹)‹CP…Àt PÿƒÄ‹ýƒÉÿ3Àò®‹{T÷ÑI‹ÑƒÉÿò®÷ÑID Pÿ‹ÐƒÄ…Ò‰SPu ¡_][Ë{TƒÉÿ3ÀVò®÷Ñ+ù‹Á‹÷‹úÁéó¥‹È3Àƒá󤿃Éÿò®÷Ñ+ù‹÷‹{P‹ÑƒÉÿò®‹ÊOÁéó¥‹Êƒáó¤‹ýƒÉÿò®÷Ñ+ù‹÷‹{P‹ÑƒÉÿò®‹ÊOÁéó¥‹Êƒáó¤‹CP^_][ò.±;D®`²uCœ­²Ù­: /ª‹D$3É;Átƒx8t‰H8‰H<‹@@PÿYø"·.fileþÿgD:\temp\zlib\gzio.c@comp.id6& ÿÿ.drectve(¦`'.rdata½ß.text ‘nÔ_gzopen .debug$FîyÔM.textp]M_gz_open   .data'©úç*q €  › ª .data{M-¹_crc32 Ó .debug$F/)F9.text @qª=_gzdopen á .data  õÛð .debug$F ¥D® .text p'¬A ! 0 .debug$F Èìnß .text œ†´¬> L .debug$F.text€„LËY .debug$F ˜‰Ñ.text°„ `·_destroy c q } ‰ .debug$F *ýœ.text° íPjT_gzread • _inflate .debug$F.text0WÀ\2_gzgetc .debug$F.textPy‹’£ .debug$F.text`òV[€_gzgets .debug$F.textÐ }](_gzwrite _deflate .debug$Fbì§.text€f®G­ · __chkstk .debug$F.text 0 9t_gzputc .debug$F! .text"0îÍ_gzputs" .debug$F#’k".text$@^Ì“Š_gzflush$ É .debug$F%$.text&àžÈˆ×& .debug$F'kqŸb&.text(#¯_gzseek( á .debug$F)(.text*pÚÿÒî* .debug$F+*.text, ‹!@¶_gztell, .debug$F-,.text.0†ü¹_gzeof. .debug$F/..text0 a€7ûø0 .debug$F10.text2PîŒ_getLong2 .debug$F32.text4Pg‘]_gzclose4 .debug$F5k 4.text60ÇNt_putLong6  .debug$F7ól>C6.text80 kc’Ò_gzerror8 .data9äDx¼9& .bss:6:F.debug$F;—“ÿM8.text<0ÓÍP< \ .debug$F=<l_gz_magic__imp__ftell__imp__fprintf??_C@_0BF@KHAC@?$CFc?$CFc?$CFc?$CFc?$CFc?$CFc?$CFc?$CFc?$CFc?$CFc?$AA@__imp___fdopen__imp__fopen__imp___errno_inflateInit2__deflateInit2_??_C@_05CNKG@1?42?43?$AA@__imp__malloc__imp__sprintf??_C@_07GLHK@?$DMfd?3?$CFd?$DO?$AA@_gzsetparams_deflateParams__imp__fwrite_check_header__imp__fread_get_byte__imp__fclose_inflateEnd_deflateEnd__imp__free_inflateReset_gzungetc_gzprintf__imp___vsnprintf__imp__fflush_do_flush__imp__fseek_gzrewind_gzdirect__imp__fputc??_C@_02HFBK@?3?5?$AA@__imp__strerror??_C@_00A@?$AA@_z_errmsg_gzclearerr__imp__clearerr/280 1264530311 100666 14553 ` L.‡3_Kž-….drectve(D .rdata¶l" @@@.text0†¶ P`.debug$FÀÐHB.text0Ú  P`.debug$FF V HB.text` p  P`.debug$Fz Š HB.text” $  P`.debug$FL \ HB.text0f P`.debug$F– ¦ HB.text@° P`.debug$Fð HB.textà ê P`.debug$F0@HB.text@J P`.debug$FŠšHB.textP¤ô P`.debug$FþHB.textÀØ P`.debug$Fú HB.text0 P`.debug$FDTHB.text€^ P`.debug$FÞîHB.textÀø P`.debug$F¸ÈHB.text°Ò‚ P`.debug$FŒœHB.text ¦F P`.debug$Fn~HB.text`ˆè P`.debug$F. > HB.textH X! P`.debug$Fb!r!HB.text|! " P`.debug$F "0"HB.textp:"ª% P`.debug$F&&HB.textp(& P`.debug$F˜'¨'HB.textв' P`.debug$F‚(’(HB.textpœ( - P`.debug$F„-”-HB-defaultlib:MSVCRT -defaultlib:OLDNAMES deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly   €€ € € 1.2.3@aLqXqdqp‚|‚ˆ‚”‚ ‚¬‚‹D$‹L$ ‹T$P‹D$QjjjjRPèƒÄ Ã% ‹D$S3ÒUV;ÂW½„ ŠŠ :Á…úƒ|$08…ï‹|$;úu _^]¸þÿÿÿ[ËG ‰W;Âu ÇG ‰W(9W$uÇG$‹L$ƒùÿu ÇD$‹L$‹\$ ;Ú}3í÷Ûë ƒû~½ƒë‹D$$ƒø|ƒø ˜ƒ|$u‘ƒû|Œƒû‡;Ê|ƒƒù zÿÿÿ‹D$(;ÂŒnÿÿÿƒøeÿÿÿƒûu» ‹O(hÀjQÿW ‹ðƒÄ …öu _^]¸üÿÿÿ[Éw‰n‰^0‹Ë‹\$$½ÓåK¸Óà‰NPƒÁ‰>ÇFUÿ‰n,‰FLH‰FT¸«ªªª‰V4÷áÑê‰VX‹G(jUPÿW ‹N,‰F8‹W(jQRÿW ‰F@‹FL‹O(jPQÿW ‰FDK¸jÓà‰†œ‹W(PRÿW ‹ŽœƒÄ0‰F‰V ‹V8…ÒtP‹V@…ÒtI‹VD…ÒtB…Àt>‹ÑWÑêÆF$PHȉ–¤‹T$,‰Ž˜‹L$‰–ˆ‰Ž„èƒÄ_^][ÃÇFš¡W‰GèƒÄ¸üÿÿÿ_^][Ã_^]¸úÿÿÿ[ÃQ`ó R+‹D$SUVW‹|$…À‹ï„ï‹X…Û„ä‹t$…ö„Ø‹Kƒù„̃ùu ƒ{*…½‹K…Ét‹@0WVPè‹L$ ƒÄ ‰A0ƒÿs_^]3À[ËC,úþÿÿ;øv‹è+ý÷‹{8‹Í‹Ñ3ÀÁéó¥‹Êƒáó¤‹s8‹KX‰kl‰k\ЉCHÓà3ÉŠNuý3Á‹KT#Á3Ò‰CH‹C8‹{H3É‹k@ŠL‹Á‹KXÓç‹KT3Ç‹{4#Á‹KD‰CH#úf‹Af‰D}‹KH‹CDf‰HB;ÖvÀ_^]3À[Ã_^]¸þÿÿÿ[ÃVSVW‹|$3Û;ûtz‹w;óts9_ tn9_$ti‰_‰_‰_ÇG,‹F‰^‰F‹F;Ã}÷؉F‹FS‹ÈS÷ÙÉSƒá¹ƒÁqƒø‰NuèëèƒÄ ‰G0‰^(VèVèƒÄ3À_^[Ã_^¸þÿÿÿ[Ã^"et!z\ ‹D$…Àt‹@…Àtƒxu ‹L$‰H3ÀøþÿÿÿÃ%'‹T$…Òt,‹B…Àt%‹L$‰ˆ¼¸Óà‹L$ H#Á‹Jf‰¸3ÀøþÿÿÿÃ:,‹T$S3ÀU…ÒW„Ä‹z…ÿ„¹‹\$ƒûÿu»ë…ÛŒ¡ƒû ˜‹l$…파ƒýƒ‹„V4[ IÁæ‹ ;Žt‹J…Ét jRèƒÄ9Ÿ„t?3Ò‰Ÿ„f‹–3ɉ—€f‹Ž3Ò‰Œf‹–3ɉ—f‹Ž‰O|‰¯ˆ^_][Ã_]¸þÿÿÿ[Ãe k |A– ¥ ´ à Þ1‹D$…Àt/‹@…Àt(‹L$‹T$ ‰ˆŒ‹L$‰€‹T$‰ˆ‰P|3ÀøþÿÿÿÃ=6‹T$V‹òWB?JÁèÁéðD1 ‹L$ …Ét!‹I…Ét‹y0¾;þu9qPu RèƒÄ_^Ã<<F;SU‹l$ V…íW„—‹u…ö„Œ‹L$ƒù…ÉŒw‹E …À„cƒ}u ‹E…À…R‹F=šu ƒù…?‹U…Òu¡_‰E^]¸ûÿÿÿ[ËV(ƒø*‰.‰T$‰N(»…à9^…4jjjè‰E0‹F‹NƒÄ Æ‹F‹V@‰FÆ‹‹~‹NG‹Ç‰~Æ‹V‹FB…À‰V‹ú…š‹Vˆ:‹~‹NG‹Ç‰~Æ‹VB‰V‹Â‹VÆ‹NA‰N‹Á‹NÆ‹F‹V@‰FÆ‹~‹†„Gƒø ‰~‹Ïu‹Ãë9žˆ};Ã|3À븋Vˆ ‹NA‰N‹Á‹NÆ ‹F@ÇFq‰Féð‹P$‹H,÷ÚÒƒâ÷ÙÉ#ËÑ‹H÷ÙɃáÑ‹H÷ÙɃáÑ‹…É‹N•ÀЈ9‹~‹V‹NG‰~ŠR‹Çˆ‹V‹NB‰V‹Â‹Q‹NÁꈋF‹V@‰F‹J‹VÁéˆ ‹V‹NB‰V‹Â‹Q‹NÁꈋ~‹†„Gƒø ‰~‹Ïu‹Ãë9žˆ};Ã|3À븋Vˆ ‹^‹N‹VC‰^ŠI ‹Ãˆ ‹~‹FG‰~‹Ï‹P…Òt*‹VŠ@ˆ ‹V‹NB‰V‹Â‹Q‹NÁꈋF@‰F‹È‹V‹B,…Àt‹FQ‹M0PQèƒÄ ‰E0ÇF ÇFE飋N0‹†ˆÁá éx;Ã}$‹†„;Ã|ƒø}¸ë3Òƒø•ÂÓ‹Âë3ÀÁà È‹Fl…ÀtƒÉ ‹Á3Ò¿ÇFq÷÷+ÊÏQVè‹FlƒÄ…Àt ‹E0ÁèPVè‹M0áÿÿQVèƒÄjjjèƒÄ ‰E0ƒ~E…Ô‹V‹B…À„¿‹B‹~ ‹N%ÿÿ;øsr‹F‹~ ;Çu8‹z,…ÿt;Áv‹V+ÁP‹E0ÑRPèƒÄ ‰E0Uè‹F‹V ƒÄ;‹Èt0‹V‹~ ‹^‹RŠ:ˆ‹V‹F B‰V‹V@‰F ‹zçÿÿ;ÇrŽ‹F‹P,…Òt‹F;Áv‹V+ÁP‹E0ÑRPèƒÄ ‰E0‹N‹V ;QuÇF ÇFIƒ~I…¸‹F‹H…É„£‹V‹F‹N ;Áu;‹N‹y,…ÿt;Âv‹M0+ÂP‹FÂPQèƒÄ ‰E0Uè‹F‹N ƒÄ;Á‹Ðt&‹~‹N 3ÛA‹Š\ÿ‰N ‹Nˆ‹NA…Û‰Ntë•»‹F‹H,…Ét‹F;Âv‹N+ÂÊ‹U0PQRèƒÄ ‰E0…Ûu ‰^ ÇF[ƒ~[…µ‹F‹H$…É„ ‹V‹F‹N ;Áu;‹N‹y,…ÿt;Âv‹M0+ÂP‹FÂPQèƒÄ ‰E0Uè‹F‹N ƒÄ;Á‹Ðt&‹~‹N 3ÛA‹$Š\ÿ‰N ‹Nˆ‹NA…Û‰Ntë•»‹F‹H,…Ét‹F;Âv‹N+ÂÊ‹U0PQRèƒÄ ‰E0…ÛuÇFgƒ~guj‹F‹H,…ÉtY‹N‹F ƒÁ;Èv UèƒÄ‹F‹N P;Ñw=‹NŠU0jjˆ‹~‹VG‰~‹M0‹ÇjÁéˆ ‹F@‰FèƒÄ ‰E0ÇFq‹F…ÀtUè‹EƒÄ…Àu8ÇF(ÿÿÿÿ_^]3À[ËE…Àu#‹|$‹D$;øƒÿt¡_‰E^]¸ûÿÿÿ[Ë|$‹F‹M=šu…Ét‹ _‰M^]¸ûÿÿÿ[Ã…Éu‹Nt…Éu…ÿ„³=š„¨‹†„WV@ÿ•ƒÄƒøtƒøuÇFš…À„…ƒø„|ƒøul;øu VèƒÄë;jjjVèƒÄƒÿu'‹FL‹NDfÇDAþ‹VL‹~D3ÀLþ‹ÑÁéó«‹ÊƒáóªUè‹EƒÄ…ÀuÇF(ÿÿÿÿ_^]3À[Ë|$ƒÿt_^]3À[ËF…À _^]¸[Ãø…¡‹F‹NŠU0ˆ‹~‹VG‰~‹M0‹ÇÁéˆ ‹F‹V@‰F‹M0Áéˆ ‹~‹VG‰~‹M0‹ÇÁéˆ ‹^‹NC‰^ŠU‹Ãˆ‹~‹VG‰~‹M‹ÇÁéˆ ‹F‹V@‰F‹MÁéˆ ‹~‹VG‰~‹M‹ÇÁéˆ ‹F@‰Fë ‹E0ÁèPVè‹M0áÿÿQVèƒÄUè‹FƒÄ…À~÷؉F‹N3À_^…É][”ÀËE…ÀuÇF(ÿÿÿÿ_^]3À[ˉU_^]¸þÿÿÿ[Ãg¢"²"3HJHZHh¿"ËM-"‘"Mú"S"_M¼"ðM0"JM§ä C)B^MNH^HgM ±A‹D$‹L$VW‹p‹x‹ÑÁêˆ>‹P‹pB‰P_ˆ ‹HA^‰HÃ/H‹D$V‹p‹H‹V;Ñv‹Ñ…ÒtX‹v‹ÊS‹ÙW‹x Áéó¥‹Ëƒáó¤‹x ‹Hú‰x ‹qò‰q‹X‹x‹HÚ+ú‰X‰x‹q_+ò[‰q‹@‹H…Éu‹H‰H^ÃrMV‹t$…öW„¨‹F…À„‹xƒÿ*t!ƒÿEtƒÿItƒÿ[tƒÿgt ƒÿqtÿšut‹@…Àt P‹F(PÿV$ƒÄ‹N‹AD…Àt ‹V(PRÿV$ƒÄ‹F‹@@…Àt ‹N(PQÿV$ƒÄ‹V‹B8…Àt P‹F(PÿV$ƒÄ‹N‹V(QRÿV$ƒÄ3ÀƒÿqÇF•ÀH_$ý^Ã_¸þÿÿÿ^þRSUV‹t$…öW„•‹l$…턉‹F…À‰D$„z¹‹ýó¥‹E(hÀjPÿU ‹ØƒÄ …Ûu _^]¸üÿÿÿ[Ët$¹°‹û‰]ó¥‹K,‰+‹U(jQRÿU ‰C8‹C,‹M(jPQÿU ‹SL‰C@‹E(jRPÿU ‹‹œ‰CD‹U(jQRÿU ‹{8ƒÄ0…ÿ‰C„Ú‹K@…ɄϋKD…ɄąÀ„¼‹K,‹T$Ñá‹r8‹éÁéó¥‹Íƒáó¤‹K,‹r@‹{@Ñá‹éÁéó¥‹Íƒáó¤‹KL‹rD‹{DÑá‹éÁéó¥‹Íƒáó¤‹K ‹r‹{‹éÁéó¥‹Íƒáó¤‹J‹z‹s+ÏÎ_‰K‹‹œ‹ÑÑêPNʉƒ¤‰‹˜ƒ”‹ˆ “| ^‰ƒ ‰‹$ ‰“0 ]3À[ÃUèƒÄ¸üÿÿÿ_^][Ã_^]¸þÿÿÿ[ÔR¯W‹T$SV3ö‹B,‹JLÑà‰B<‹BDWf‰tHþ‹JL‹zD3ÀL þ‹ÙÁéó«‹Ëƒá󪋂„3É_@Áàf‹ˆ‰Š€3Éf‹ˆ‰ŠŒ3Éf‹ˆ‰Š3Éf‹ˆ‰rl‰r\‰rt¸‰rh‰rH^‰J|‰Bx‰B`[ÃH W f u ™\SUV‹t$»ÿÿ‹F ƒÀû;Ãs‹Ø‹l$‹Ftƒøw Vè‹FtƒÄ…Àu…í„…À„«‹NlÇFtȉNl‹N\‹Vlt;Ðr?+ЉFl…ɉVt|‹V8Ñë3Ò+ÁjPRVè‹‹FlQ‰F\苃ċB…À„°‹N\‹Vl‹F,+Ñ-;Ђcÿÿÿ…É|‹F8Áë3ÀjRPVè‹‹NlR‰N\苃ċH…Étgé-ÿÿÿ‹N\…É|‹F8Áë3À3Òƒý”ÂR‹Vl+ÑRPVè‹‹FlQ‰F\苃ċB…Àu3Àƒý•ÀH^]ƒà[ËÅ^ƒè]÷ØÀ[$þƒÀÃ^]3À[Ã&gbMÌbÚMbMWaS‹\$UV‹k,W‹S<‹Kt‹Cl+Ñ‹K,+ÐŒ)úþÿÿ;Árq‹{8‹Í‹Á4/Áéó¥‹Èƒáó¤‹sp‹Kl‹C\+õ+͉sp‹sL‰Kl‹KD+ʼnC\ qƒé3Àf‹;År+Åë3ÀNf‰uè‹C@‹õ hƒé3Àf‹;År+Åë3ÀNf‰uèÕ‹‹H…Ét`‹Kt‹slR‹S8ÎÊQPè‹KtƒÄ È‹ñ‰Ktƒþr$‹Sl‹C8‹KX<3ÀЉCHÓà3ÉŠO3Á‹KT#Á‰CHþs ‹‹B…À… ÿÿÿ_^][ñlg‹L$ S‹\$U‹C‹è;év‹é…íu]3À[Ã+ʼnC‹C‹@ƒøu‹ ‹S0UQRèëƒøu‹‹K0UPQèƒÄ ‰C0‹ÍV‹3‹ÑW‹|$Áéó¥‹Êƒáó¤‹C‹ Å͉C_‹Å^‰ ][Ã7K"‚lQUV‹t$W3ÿ‹Ft=s'Vè‹FtƒÄ=s ‹L$…É„2…À„¾ƒørP‹FH‹NX‹Vl‹~8Óà3ÉŠL‹~4#ú‹V@3Á‹NT#Á‹ND‰FHf‹Af‰z‹Nl‹F4‹V@#È‹FH3ÿf‹)'.drectve(D .rdata l@0@.textl"|" P`.debug$F†"–"HB.text  "À" P`.debug$FÊ"Ú"HB.textðä"Ô%& P`.debug$FP'`'HB.textðj'Z( P`.debug$F–(¦(HB.text °( P`.debug$FÐ(à(HB.text0ê() P`.debug$F$)4)HB-defaultlib:MSVCRT -defaultlib:OLDNAMES –0w,aîºQ ™Ämôjp5¥c飕dž2ˆÛ¤¸ÜyéÕàˆÙÒ—+L¶ ½|±~-¸ç‘¿d·ò °jHq¹óÞA¾„}ÔÚëäÝmQµÔôÇ…ÓƒV˜lÀ¨kdzùbýìÉeŠO\Ùlcc=úõ È n;^iLäA`Õrqg¢Ñäjm ¨Zjz Ïäÿ “'® ±ž}D“ðÒ£‡hòþÂi]Wb÷Ëge€q6lçknvÔþà+Ó‰ZzÚÌJÝgoß¹ùùホC¾·Õް`è£ÖÖ~“Ñ¡ÄÂØ8RòßOñg»ÑgW¼¦Ýµ?K6²HÚ+ ØL ¯öJ6`zAÃï`ßUßg¨ïŽn1y¾iFŒ³a˃f¼ Òo%6âhR•w ÌG »¹"/&U¾;ºÅ( ½²’Z´+j³\§ÿ×Â1Ïе‹žÙ,®Þ[°Âd›&òc윣ju “m© œ?6ë…grW‚J¿•z¸â®+±{8¶ ›ŽÒ’ ¾Õå·ïÜ|!ßÛ ÔÒÓ†BâÔñø³ÝhnƒÚ;[&¹öáw°owG·æZˆpjÿÊ;f\ ÿžei®bøÓÿkaEÏlxâ  îÒ ×TƒN³9a&g§÷`ÐMGiIÛwn>JjÑ®ÜZÖÙf ß@ð;Ø7S®¼©Åž»ÞϲGéÿµ0ò½½ŠÂºÊ0“³S¦£´$6к“×Í)WÞT¿gÙ#.zf³¸JaÄh]”+o*7¾ ´¡Ž ÃßZï-A1‚b62ÃS-+ÅldEôw}†§ZVÇ–AOŠÙÈI»ÂÑŠèïúËÙôã Oµ¬M~®µŽ-ƒžÏ˜‡QÂJ#ÙSÓpôx’AïaU×®.æµ7×µ˜–„ƒY˜‚©›Ûú-°šË6©]]wællÿß?AÔžZÍ¢$„•㟌 F²§aw©¾¦áèñçÐóè$ƒÞÃe²ÅÚª®]]ëŸFD(Ìkoiýpv®k19ïZ* ,  m8ó6Fß²]ÆqTpí0ekô÷ó*»¶Â1¢u‘‰4 û¼Ÿº„yÞ©%8ï²<ÿyós¾Hèj}ÅA<*ÞXOyðD~bé‡-OÂÆTÛŠ”@»ƒè#¦ÂÙ8¿ Å 8Lô»!§– Ζ Ì\H1×E‹búnÊSáwT]»ºl £Ö?ˆ—–‘P˜×Þ©ÌÇÒúáì“Ëúõ\×bræykÞµT@Ÿ„OYX#Úp8$›A#=§kýeæZæ|% ËWd8ÐN£®‘⟊!̧3`ý¼*¯á$­îÐ?´-ƒŸl² †«$HÉêSÐ)F~ûhweâöy?/·H$6t 5*ò¼SK³HRpÞey1ï~`þóæç¿Âýþ|‘ÐÕ= ËÌú6Šƒ»‘šxT¼±9e§¨K˜ƒ; ©˜"Éúµ ˆË®O]ï_lôFÍ?ÙmŒÂtCZó#AêÁplÁ€AwØG×6—æ-ŽÅµ¥„„¼ŠAq[»Zh˜èwCÙÙlZO-_~6 œ-'Ý>˜¹S1ƒ b®‹ÑSµ’ÅôÝWôïÄ”§ÂïÕ–Ùöé¼®¨·kÞ1œ*ï*…íykʬHpÓo]ø.*Fáá6Þf ÅcTèT"eóMåó²¤Â©g‘„0& Ÿ)¸®ÅäùŸÞý:ÌóÖ{ýèϼk©€ýZ²™> Ÿ²8„«°$,ñ52F*sw1´ápHõÐkQ6ƒFzw²]cN×úËæáÒ̵Ìù„×àJ–¯ #¶Èp ‰A»„F]#l8Ä?1…(B˜Og©T~ÀúyUËbLÅ8^ô#˜§³Ü–ªTåZ1Oü™bbרSyÎOáIV~úP•-×{ÔÌbŠ-R»–4‘è»ÐÙ ìó~^­ÂeGn‘Hl/ Suè6:© #jT$+e?äy§–¥H¼f‘¤'*нà¼Ëò¡ÐëbÞýÀ#ïæÙ½á¼üЧ ?ƒŠ&~²‘?¹$ÐpøËi;FæBzwý[µkeÜôZ~Å7 Sîv8H÷±® ¸ðŸ¡3Ì?Šrý$“7jÂnÔ„Y¾Fܨ ëÂ˲|…O¸Q;ÑÖ…— áïU dù S“Ø -ž =G\ p£&GÉäw¢)`¬ /›aíÂß«õµiÈò5ÿ˜÷¦&±‘LsZ<#0þzޏMäzàFM8×,9Ž’É;¹ø :<îD? „†>R:À(ôq-Ãv³,šÈõ.­¢7/Àšp÷çXq®Ys™3Ür%“w+OQvrñtE›Õux܉~O¶K }!bÏ|¤t€y“BxÊ zýÊÆ{°.¼l‡D~mÞú8oéúnl†µk[ìwjR1h58ói¯b?mcf«+aQÁé`Ôצeã½ddº"fiàg Ë×H¡INSKyu‘JücÞOË N’·ZL¥Ý˜M˜šÄF¯ðGöN@EÁ$‚DD2ÍAsX@*æIBŒ‹CPhñTg3U>¼uW Ö·VŒÀøS»ª:Râ|PÕ~¾Qè9âZßS [†ífY±‡¤X4‘ë]û)\ZEo^m/­_€5á·q÷àîϱâÙ¥sã\³<ækÙþç2g¸å zä8J&ï äîVž¢ìaô`íäâ/èÓˆíéŠ6«ë½\iêð¸ýÇÒÑüžl—þ©Uÿ,úzØûBÄžùu®\øHéóƒÂò&=„ðWFñ”A ô£+Ëõú•÷ÍÿOö`]xÙW7ºØ‰üÚ9ã>Û¼õqÞ‹Ÿ³ßÒ!õÝåK7ÜØ k×ïf©Ö¶ØïÔ²-Õ¤bÐ3ΠÑjpæÓ]$Òþ^Å'”œÄ~*ÚÆI@ÇÌVWÂû<•â‚ÓÁ•èÀ¨¯MËŸÅÊÆ{ÉÈñ ÉtDÌCm†ÍÓÀÏ-¹Î@–¯‘wüm.B+’(铜>¦–«Td—òê"•Å€à”øÇ¼ŸÏ­~ž–8œ¡yú$oµ˜w™J»1›}Ñóš05‰_KŒ^á Ži‹Ï쀊Û÷B‹‚I‰µ#ƈˆdšƒ¿X‚æ°€ÑÚÜTÌ“„c¦Q…:‡ rÕ† Ðâ©—º ¨Îfªùn¤«|xë®K)¯¬o­%Æ­¬ñ§/ë3¦vUu¤A?·¥Ä)ø óC:¡ªý|£—¾¢Ðsĵç´¾§@¶‰Í‚· ÛͲ;±³bI±Ue‹°h"×»_HºöS¸1œ‘¹´ŠÞ¼ƒà½Ú^Z¿í4˜¾eg¼¸‹È ªî¯µW—b2ðÞ7Ü_k%¹8×ï(´ÅŠO}dà½o‡׸¿ÖJÝØjò3wßàVcXŸWPú0¥èŸúqø¬BÈÀ{ß­§ÇgCru&oÎÍp­•-û·¤?žÐ‡'èÏBs¢¬ ưÉGz>¯2 [ÈŽµg; Ї²i8P/ _ì—âðY…‡—å=ч†e´à:ÝZOÏ?(3w†äêãwXR Øí@h¿Qø¡ø+ðÄŸ—H*0"ZOWžâöoI“õÇ}§@ÕÀümNП5+·#Å–Ÿ *'Gýº| A’ô÷èH¨=X›X?¨#¶1Ó÷¡‰jÏv¨Ê¬á¾„`ÃÒp ^·æY¸©ô<ßL…çÂÑà€~i/Ë{kHwâ ËÇh±s)ÇaL ¸Ùõ˜oDÿÓü~Pfî7ÚVM'¹(@¶Æï°¤£ˆ °Û×g9‘xÒ+ôn“÷&;fšƒˆ?/‘íX“)T`D´1ø ߨMºÏñ¦ìß’þ‰¸.Fg›Tp'ì»HðqÞ/LÉ0€ùÛUçEcœ ?kùǃÓh6ÁrŠyË7]ä®Pá\@ÿTN%˜èösˆ‹®ï7ø@‚'>¼$é!AxU™¯×à‹Ê°\3;¶Yí^ÑåU°~PGÕìÿl!;b F‡Úçé2È‚ŽŽpÔží(±ùQ_Vä‚:1X:ƒ §æn3Á† m¦:µ¤á@½Á†ü/)IJNõ¯óv"2–žŠx¾+˜Ù— KÉôx.®HÀÀýÒ¥fAj^–÷y9*O—–Ÿ]òñ#åkM`~×õŽÑbçë¶Þ_RŽ Â7éµzÙFh¼!¼Ðê1߈Vc0aùÖ"žj𽦽ØÁ¿6n´­S šNrÿ)Î¥†{·táÇÍÙ’¨¾¬*F8#v¥€ufÆØz`þ®Ïr›ÉsÊ"ñ¤WG–ï©9­ýÌ^EîMvc‰ñÎ&DÜèAødQy/ù4“AÚ±&S¿ÖšëéÆù³Œ¡E bðiL¡¾Q›<Û6'„5™’–Pþ..™¹T&üÞèžq]Œwá4Î.6©«IŠEæ? ƒ»v‘àãö\[ýYéI˜>Uñ!‚lDa>Ԫ΋ÆÏ©7~8AÖ]&Ãn³‰v|ÖîÊÄoÖY ±¡áäóy¨K×i˲w«\¡Â¹9Æ~€þ©œå™$ 6 6nQާf†ÂqÚ>,Þo,I¹Ó”ð •渱{I £.±H>ÒC-YnûÃöÛ馑gQ©°ÌzÎ t”a¹fñÞw0–îa,™ QºmÄpjôéc¥5žd•£Ûˆ2yܸ¤àÕé—ÒÙˆ ¶L+~±|½ç¸-¿‘·dj° òó¹qH„¾AÞÚÔ}mÝäëôÔµQƒÓ…Çl˜Vdk¨ÀýbùzŠeÉì\OclÙú=c õ;n ÈLi^Õ`Aä¢gqr<äÑKÔGÒ …ý¥ µk5µ¨úB²˜lÛ»ÉÖ¬¼ù@2ØlãEß\uÜÖ Ï«Ñ=Y&Ù0¬QÞ:È×Q€¿Ða!´ôµV³Ä#Ϻ•™¸½¥(¸ž_ˆÆ Ù²± é$/o|‡XhLÁa«¶f-=vÜAÛq˜Ò ¼ïÕ*q±…‰¶µŸ¿ä¥è¸Ô3xÉ¢ù4– ¨Žá˜j »m=-‘dl—æc\kkQôlab…e0ØòbNl•í¥{‚ôÁõÄWe°ÙÆ·éP‹¾¸êü¹ˆ|bÝßÚ-IŒÓ|óûÔLeM²aX:µQΣ¼tÔ»0âJߥA=ؕפÑÄmÓÖôûCiéj4nÙü­gˆFÚ`¸ÐD-s3åª L_Ý |ÉPq<'Aª¾ É †Whµ% o…³¹fÔ ÎaäŸ^Þù)Ùɘ°Ð˜"Çר´Y³=.´ ·½\;Àºl­í¸ƒ š¿³¶¶â t±ÒšêÕG9Òw¯Û&s܃ãc ”d;„ mj>zjZ¨äÏ “ ÿ ®'}ž±ð“D‡£ÒòhiÂþ÷bW]€egËl6qnkçþÔv‰Ó+àÚzZgÝJÌù¹ßo޾ïù·¾C`°ŽÕÖÖ£è¡Ñ“~8ØÂÄOßòRÑ»gñ¦¼Wg?µÝH²6KØ +Ú¯ L6JöAz`ß`ïègßU1nŽïFi¾yËa³Œ¼fƒ%oÒ Rhâ6Ì w•» G"¹U&/ź;¾²½ (+´Z’\³jÂ×ÿ§µÐÏ1,Ùž‹[Þ®›d°ìcò&uj£œm“ œ ©ë6?rg…W•¿J‚â¸z{±+® ¶8’ÒŽ›åÕ¾ |Üï· Ûß!†ÓÒÔñÔâBhݳøÚƒn¾Íö¹&[o°wá·GwˆZæÿjpf;Ê \ežÿøb®iakÿÓlÏE  âx× ÒîNƒT9³Â§g&aÐ`÷IiGM>nwÛ®ÑjJÙÖZÜ@ß f7Ø;𩼮SÞ»žÅG²Ï0µÿé½½òʺŠS³“0$´£¦ºÐ6ÍדTÞW)#Ùg¿³fz.ÄaJ¸]h*o+”´ ¾7Ã Ž¡Zß-ï1A26b‚+-SÃdlÅ}wôEVZ§†OA–ÇÈÙŠÑ»IúïèŠãôÙˬµO µ®~Mžƒ-އ˜ÏJÂQSÙ#xôpÓaïA’.®×U7µæ˜µ×ƒ„–‚˜Y›©°-úÛ©6Ëšæw]]ÿllÔA?ßÍZž•„$¢ŒŸã§²F ¾©wañèá¦èóÐçÃÞƒ$ÚŲe]]®ªDFŸëokÌ(vpýi91k® *Zï  ,8mßF6óÆ]²ípTqôke0»*ó÷¢1¶‰‘u 4Ÿ¼û„º%©Þy<²ï8sóyÿjèH¾AÅ}XÞ*<ðyOéb~DÂO-‡ÛTÆ”Š»@¦#胿8ÙÂ8 Å !»ôL –§–Î\Ì E×1Hnúb‹wáSʺ»]T£ lˆ?Ö‘–—ÞטPÇÌ©ìáúÒõúË“rb×\kyæ@TµÞYO„ŸX#$8pÚ=#A›eýk§|æZæWË %NÐ8d‘®£ŠŸâ3§Ì!*¼ý`­$᯴?Ð-† ²lÉH$«ÐSêû~F)âewh/?yö6$H· t*5KS¼òRH³yeÞp`~ï1çæóþþý¿ÕБ|ÌË =ƒŠ6úš‘»±¼Tx¨§e9;ƒ˜K"˜© µúɮˈ_ï]OFôlmÙ?ÍtÂŒóZCêA#ÁlpÁØwA€—6×GŽ-極ż„„qAŠhZ»[Cwè˜ZlÙÙ-O 6~_'-œ>ݹ˜ ƒ1S‹®b’µSÑÝôÅÄïôWï§”öÙ–Õ®¼é·¨œ1Þk…*ï*ÊkyíÓpH¬ø]oáF*.fÞ6áÅ TèTcMóe"²óå©Â¤0„‘g)Ÿ &äÅ®¸ýÞŸùÖóÌ:Ïèý{€©k¼™²Zý²Ÿ >«„8,$°5ñ*F21wsHpá´QkÐõzFƒ6c]²wËú×NÒáæù̵Ìàׄ¯–J¶#  pÈ„»A‰#]F8l1?Ä(…gO˜B~T©UyúÀLbË8Ř#ô^³§ª–ÜåTüO1Z×bb™ÎySØIáOPú~V{×-•bÌÔ-Š4–»R»è‘ ÙÐ^~óìGe­lH‘nuS /:6è# ©$Tj?e+–§yä¼H¥¤‘f½Š*'ò˼àëСÀýÞbÙæï#¼á½ §Ðü&Šƒ??‘²~pÐ$¹iËøBæF;[ýwzÜekµÅ~ZôîS 7÷H8v¸ ®±¡ŸðŠ?Ì3“$ýrÂj7„ÔnF¾Y ¨ÜËÂë|²O…Q¸Ñ; —…Ö Uïá ùdØ“S ž- \G=&£päÉG¢w`)/ ¬ía›«ßÂiµõ5òÈ÷˜ÿ±&¦sL‘†„ <À:R=Pe6^X7œ}o5ÚÃ64©1W¿„0•Õ³2Ókê3Ý$kå%©§'ï1þ&-[É#bML" '{ æ™"!$ó*x´(+ºÞ)ü`F(> q-qô,³vÃ.õÈš/7¢­pšÀqXç÷sY®rÜ3™w“%vQO+tñruÕ›E~‰ÜxK¶O} |Ïb!y€t¤xB“z Ê{ÆÊýl¼.°m~D‡o8úÞnúékµ†ljwì[h1Rió85b¯cm?a+«f`éÁQe¦×Ôdd½ãf"ºgàiH×Ë I¡KSNJ‘uyOÞcüN ËLZ·’M˜Ý¥FÄš˜Gð¯E@NöD‚$ÁAÍ2D@XsBIæ*C‹ŒTñhPU3gWu¼>V·Ö SøÀŒR:ª»P|âQ¾~ÕZâ9è[ SßYfí†X¤‡±]ë‘4\)û^oEZ_­/má5€à÷q·â±Ïîãs¥Ùæ<³\çþÙkå¸g2äz ï&J8îä 좞Ví`ôaè/âäéíˆÓë«6Šêi\½ý¸ðüÑÒÇþ—lžÿU©ú,ûØzùžÄBø\®uóéHòƒð„=&ñFWô A”õË+£÷•úöOÿÍÙx]`غ7WÚü‰Û>ã9Þqõ¼ß³Ÿ‹Ýõ!ÒÜ7Kå×k ØÖ©fïÔïØ¶Õ-²Ðb¤Ñ Î3ÓæpjÒ$]Å^þÄœ”'ÆÚ*~Ç@IÂWVÌÕ<ûÁÓ‚¢Àè•ËM¯¨ÊÅŸÈÉ{ÆÉ ñÌDt͆mCÏÀÓι-‘¯–@müw’+B.“é(–¦>œ—dT«•"êò”à€ÅŸ¼Çøž~­Ïœ8–úy¡˜µo$™w›1»JšóÑ}‰50ŒK_Ž á^Ï‹iŠ€ì‹B÷Û‰I‚ˆÆ#µƒšdˆ‚X¿€°æÜÚÑ„“ÌT…Q¦c‡:†Õr ©âР¨ º—ªfΫ¤nù®ëx|¯)K­o¬¬­Æ%§ñ¦3ë/¤uUv¥·?A ø)Ä¡:Có£|ýª¢¾—µÄsдç¶@§¾·‚͉²ÍÛ ³±;±Ib°‹eU»×"hºH_¸Sö¹‘œ1¼ÞŠ´½àƒ¿Z^Ú¾˜4í¸¼geª È‹µ¯îb—W7Þð2%k_Ü×8¹Å´(ï}OŠo½àdׇJÖ¿¸òjØÝàßw3XcVPWŸè¥0úúŸB¬øqß{ÀÈgǧ­urCÍÎo&•­p-?¤·û‡ОÏè'¢sB°Æ ¬zGÉ 2¯>ŽÈ[ ;gµ²‡Ð/P8i—ì_ …Yðâ=å—‡e†‡ÑÝ:à´ÏOZw3(?êä†RXwã@íØ øQ¿hð+ø¡H—ŸÄZ"0*âžWOIoöÇõ“Õ@§}müÀ5ŸÐN#·+Ÿ–Å'* ºýGA |ô’¨Hè÷›X=#¨?X1¶‰¡÷ÓvÏj¬Ê¨¾áÃ`„^ pÒæ·ô©¸YLß<ÑÂç…i~€à{Ë/ÃwHkË ¢s±hÇaÇ)Ù¸ LDo˜õüÓÿîfP~VÚ7¹'M¶@(¤°ïÆ ˆ£Û°9g×+Òx‘“nô;&÷ƒšf‘/?ˆ)“Xí´D`T ø1M¨ß¦ñϺþ’ßìF.¸‰T›gì'pqðH»ÉL/ÞÛù€0cEçUk? œÓƒÇùÁ6hyŠrä]7Ë\áP®NTÿ@öè˜%®‹ˆs7ï‚@ø¼>'!é$™UxA‹àׯ3\°ÊíY¶;UåÑ^GP~°ÿìÕb;!lÚ‡F È2éçpŽŽ‚(ížÔQù±‚äV_:X1:§ ƒ3næ †Áµ:¦m½@á¤ü†ÁI)/¯õNJ2"vóŠž–˜+¾x —ÙxôÉKÀH®.ÒýÀjAf¥÷–^O*9y]Ÿ–—å#ñòMkõ×~`çbÑŽ_Þ¶ë ŽRzµé7hFÙм!¼ˆß1ê0cV"Öùašjž½¦½¿ÁØ­´n6 SrNš¥Î)ÿ·{†Çát’ÙÍ*¬¾¨8F€¥v#ØÆfu`zrÏ®þÊsÉ›W¤ñ"ï–Gý­9©E^ÌvMîÎñ‰cÜD&døAèù/yQA“4S&±ÚëšÖ¿³ùÆé E¡Œðb¡Li<›Q¾„'6Û–’™5..þP&T¹™žèÞüŒ]q4áw©6.ΊI«?æE»ƒ ãà‘v[\öIéYýñU>˜l‚!Ô>aDƋΪ~7©ÏÖA8nÃ&]|v‰³ÄÊîÖYÖoᡱ óäK¨yËi׫w²¹Â¡\~Æ9œ©þ€$™å6 6 ŽQn†f§>ÚqÂ,oÞ,”Ó¹I ð±¸æ•£ I{±.CÒ>HûnY-éÛöÃQg‘¦Ì°©t Îzf¹a”Þñ¸Ã ‹D$…ÀuËL$ ‹T$QPRèƒÄ ËD$‹L$SUVW‹|$…ÿ÷Ðt#öÁt‹Ð3ÛŠâÿ3ÓÁè‹•3ÂAOu݃ÿ ‹ñ‚!‹ïÁí‹3É3Â3ÒŠÔ‰D$ŠL$ƒÆ‹•‹Ð‹ %ÿÁê3˃Æ‹•‹Vü3Ë‹… 3Ë3À3Ê3ÒŠÕ‰L$ŠD$ƒÆ‹•‹Ñ‹…áÿÁê3ÃÆ‹•‹Vø3Ë 3Ã3É3Â3ÒŠÔ‰D$ŠL$ƒÆ‹•‹Ð‹ %ÿÁê3Ë‹•‹Vø3Ë‹… 3Ë3À3Ê3ÒŠÕ‰L$ŠD$‹•‹Ñ‹…áÿÁê3Ë•‹Vü3Ë 3Ã3É3Â3Ò‰D$ŠÔŠL$‹ ‹•‹ÐÁê3Ë%ÿ‹•‹3Ë‹… 3Ë3À3Ê3ÒŠÕ‰L$ŠD$ƒÆ‹•‹Ñ‹…áÿÁê3ÃÆ‹•‹Vü3Ë 3Ã3É3Â3ÒŠÔ‰D$ŠL$ƒÆ‹•‹Ð‹ %ÿÁê3Ëƒï ‹•‹Vü3Ë‹… 3Ë3À3Ê3ÒŠÕ‰L$ŠD$‹•‹Ñ‹…áÿÁê3Ë•3Ë 3ÃM…äýÿÿƒÿrN‹ïÁí‹3É3Â3ÒŠÔ‰D$ŠL$ƒÆ‹•‹Ð‹ %ÿÁê3˃ï‹•3Ë‹… 3ËM‹Áu·…ÿt‹È3ÒŠáÿ3ÊÁè‹ 3ÁFOuâ_^][÷ÐÃ/aj~Ц¯ÄÐìõ+4FRkr…¬µÊÖòû4=OX‡¤­ÐáìS‹œ$…Ûu‹„$[ÄÃÇD$ ƒ¸í¸L$º‰ƒÁÑàJuöD$VŒ$ˆPQè”$D$RPè‹´$ƒÄL$”$ˆQRèƒÄöÃt„$ˆVPèƒÄ‹ðÑût.Œ$ˆT$QRèƒÄöÃtD$VPèƒÄ‹ðÑûu¡‹Œ$‹Æ^3Á[ÄÃP$b$~$”¯$Âã@‹L$3À…Ét‹T$öÁt3ÑéƒÂ…ÉuðÃSU‹l$V‹t$W‹ý» +þ‹7PU艃ăÆKuë_^][Ã/$.fileþÿgD:\temp\zlib\crc32.c@comp.id6& ÿÿ.drectve(ÀÀ³x.rdata —¨(ã.textj¶  .debug$F.text  –€ê_crc32 .debug$F.textð&1m¶’ .debug$F.text ðÔ?, .debug$F  .text  ¯±g; .debug$F  .text 0±M .debug$F `_crc_table_get_crc_table_crc32_little_crc32_combine_gf2_matrix_times_gf2_matrix_square/342 1264530311 100666 1342 ` L‡3_Kü.drectve(T .text°|, P`.data^@0À.debug$FdtHB.text ~ž P`.debug$F¨¸HB.text  P`.debug$FâòHB-defaultlib:MSVCRT -defaultlib:OLDNAMES ƒì8‹L$H‹T$<‹D$DS‹\$DV‰L$ ‹L$T‰T$j8‰D$ ‹hT$QR‰D$(ÇD$8ÇD$<ÇD$@èƒÄ…ÀuGD$jPè‹ðƒÄƒþtL$QèƒÄ¸ûÿÿÿ…öt‹Æ^[ƒÄ8ËT$D$P‰èƒÄ^[ƒÄ8Ã*Q d x œ 1.2.3©‹D$‹L$ ‹T$jÿP‹D$ QRPèƒÄËD$‹È‹ÐÁéÁê ÁD Ã.fileþÿgD:\temp\zlib\compress.c@comp.id6& ÿÿ.drectve(yÌ.text°ôC‹  _deflate  .data{M-).debug$F.text ^}:C .debug$F.text ´8žM .debug$F\_compress2_deflateEnd_deflateInit_??_C@_05CNKG@1?42?43?$AA@_compress_compressBound/375 1264530311 100666 1389 ` L‡3_K8.drectve(Ü .textp P`.debug$Ft„HB.textŽ P`.debug$F.HB-defaultlib:MSVCRT -defaultlib:OLDNAMES ‹L$S‹\$VW‹ùÁïáÿÿƒûu3‹T$3ÀŠÈùñÿréñÿùÿñÿrïñÿ‹Ç_Áà^ Á[Ët$…öu _^¸[Ãûs:‹ÃK…ÀtC3ÒŠÊFùHuôùñÿréñÿ‹Ç3Ò¾ñÿ_÷ö^[‹ÂÁà ÁÃû°U‚Ö¸¯©n^÷ãÁê ‰T$ë°½[3À3ÒŠŠVÈ3ÀŠFùÊ3ÒŠVùÈ3ÀŠFùÊ3ÒŠVùÈ3ÀŠFùÊ3ÒŠVùÈ3ÀŠFùÊ3ÒŠV ùÈ3ÀŠF ùÊ3ÒŠV ùÈ3ÀŠF ùÊ3ÒŠV ùÈ3ÀŠFùÊ3ÒŠVùȃÆùÊùM…gÿÿÿ‹Á3Ò¹ñÿ÷ñ‹Ç¿ñÿ‹Ê3Ò÷÷ÿL$‹ú…8ÿÿÿ…Û„Úƒû‚¡‹ëÁí3Ò3ÀŠŠFÊ3ÒŠVùÈ3ÀŠFùÊ3ÒŠVùÈ3ÀŠFùÊ3ÒŠVùÈ3ÀŠFùÊ3ÒŠVùÈ3ÀŠF ùÊ3ÒŠV ùÈ3ÀŠF ùÊ3ÒŠV ùÈ3ÀŠF ùÊ3ÒŠVùÈ3ÀŠFùʃëùÈùƒÆM…dÿÿÿ‹ÓK…ÒtC3ÒŠÊFùHuô‹Á3Ò¹ñÿ¾ñÿ÷ñ‹Ç‹Ê3Ò÷ö‹ú‹Ç]Áà_^ Á[Ão‹D$ 3Ò¹ñÿS÷ñ‹L$V‹ñWæÿÿ»ñÿ‹ÆÁé‹ú3Ò¯Ç÷ó‹D$‹ØÁèãÿÿÈ+Ï´ðÿþñÿ„ ñÿvîñÿþñÿvîñÿ=âÿv-âÿ=ñÿv-ñÿÁà Æ_^[à .fileþÿgD:\temp\zlib\adler32.c@comp.id6& ÿÿ.drectve(.textpÂé¤ _adler32 .debug$F.text;]Û .debug$F_adler32_combine snort-2.9.15.1/src/win32/WIN32-Libraries/zlib1.lib0000555000175200017520000002507613571422610016033 00000000000000! / 1264530323 0 2020 ` iRTŠ)Ö)ÖÔÔ#´#´%¾%¾zz  @@88ªª'^'^'Î'Î%V%V&ö&ö$$$€$€)j)j>>¢¢(¢(¢pp"""" ú ú#P#PÒÒ ˜ ˜ 6 6¬¬"ì"ìHH!À!À!\!\"Š"Š‚‚ººääTTÚÚrrØØnn&Ž&Ž&$&$$ê$ê(6(6êê))__IMPORT_DESCRIPTOR_zlib1__NULL_IMPORT_DESCRIPTORzlib1_NULL_THUNK_DATA__imp__zlibVersion_zlibVersion__imp__deflate_deflate__imp__deflateEnd_deflateEnd__imp__inflate_inflate__imp__inflateEnd_inflateEnd__imp__deflateSetDictionary_deflateSetDictionary__imp__deflateCopy_deflateCopy__imp__deflateReset_deflateReset__imp__deflateParams_deflateParams__imp__deflateBound_deflateBound__imp__deflatePrime_deflatePrime__imp__inflateSetDictionary_inflateSetDictionary__imp__inflateSync_inflateSync__imp__inflateCopy_inflateCopy__imp__inflateReset_inflateReset__imp__inflateBack_inflateBack__imp__inflateBackEnd_inflateBackEnd__imp__zlibCompileFlags_zlibCompileFlags__imp__compress_compress__imp__compress2_compress2__imp__compressBound_compressBound__imp__uncompress_uncompress__imp__gzopen_gzopen__imp__gzdopen_gzdopen__imp__gzsetparams_gzsetparams__imp__gzread_gzread__imp__gzwrite_gzwrite__imp__gzprintf_gzprintf__imp__gzputs_gzputs__imp__gzgets_gzgets__imp__gzputc_gzputc__imp__gzgetc_gzgetc__imp__gzungetc_gzungetc__imp__gzflush_gzflush__imp__gzseek_gzseek__imp__gzrewind_gzrewind__imp__gztell_gztell__imp__gzeof_gzeof__imp__gzclose_gzclose__imp__gzerror_gzerror__imp__gzclearerr_gzclearerr__imp__adler32_adler32__imp__crc32_crc32__imp__deflateInit__deflateInit___imp__deflateInit2__deflateInit2___imp__inflateInit__inflateInit___imp__inflateInit2__inflateInit2___imp__inflateBackInit__inflateBackInit___imp__inflateSyncPoint_inflateSyncPoint__imp__get_crc_table_get_crc_table__imp__zError_zError/ 1264530323 0 2030 ` 6RTŠÖ)Ô´#¾%z @8ª^'Î'V%ö&$€$j)>¢¢(p""ú P#Ò˜ 6 ¬ì"HÀ!\!Š"‚ºäTÚrØnŽ&$&ê$6(ê)i-. 0/  5,*)+%#!" '&($32146-. 0/  5,*)+%#!" '&($32146__IMPORT_DESCRIPTOR_zlib1__NULL_IMPORT_DESCRIPTOR__imp__adler32__imp__compress__imp__compress2__imp__compressBound__imp__crc32__imp__deflate__imp__deflateBound__imp__deflateCopy__imp__deflateEnd__imp__deflateInit2___imp__deflateInit___imp__deflateParams__imp__deflatePrime__imp__deflateReset__imp__deflateSetDictionary__imp__get_crc_table__imp__gzclearerr__imp__gzclose__imp__gzdopen__imp__gzeof__imp__gzerror__imp__gzflush__imp__gzgetc__imp__gzgets__imp__gzopen__imp__gzprintf__imp__gzputc__imp__gzputs__imp__gzread__imp__gzrewind__imp__gzseek__imp__gzsetparams__imp__gztell__imp__gzungetc__imp__gzwrite__imp__inflate__imp__inflateBack__imp__inflateBackEnd__imp__inflateBackInit___imp__inflateCopy__imp__inflateEnd__imp__inflateInit2___imp__inflateInit___imp__inflateReset__imp__inflateSetDictionary__imp__inflateSync__imp__inflateSyncPoint__imp__uncompress__imp__zError__imp__zlibCompileFlags__imp__zlibVersion_adler32_compress_compress2_compressBound_crc32_deflate_deflateBound_deflateCopy_deflateEnd_deflateInit2__deflateInit__deflateParams_deflatePrime_deflateReset_deflateSetDictionary_get_crc_table_gzclearerr_gzclose_gzdopen_gzeof_gzerror_gzflush_gzgetc_gzgets_gzopen_gzprintf_gzputc_gzputs_gzread_gzrewind_gzseek_gzsetparams_gztell_gzungetc_gzwrite_inflate_inflateBack_inflateBackEnd_inflateBackInit__inflateCopy_inflateEnd_inflateInit2__inflateInit__inflateReset_inflateSetDictionary_inflateSync_inflateSyncPoint_uncompress_zError_zlibCompileFlags_zlibVersionzlib1_NULL_THUNK_DATAzlib1.dll/ 1264530323 0 710 ` L“3_Kèà .debug$S@l@B.idata$2¬À@0À.idata$6 ÞÀ@ À zlib1.dll(ÿ Microsoft (R) LINK zlib1.dll@comp.idÿ ÿÿ.idata$2@Àh.idata$6.idata$4@Àh.idata$5@Àh7N__IMPORT_DESCRIPTOR_zlib1__NULL_IMPORT_DESCRIPTORzlib1_NULL_THUNK_DATAzlib1.dll/ 1264530323 0 249 ` L“3_K¸.debug$S@d@B.idata$3¤@0À zlib1.dll(ÿ Microsoft (R) LINK@comp.idÿ ÿÿ__NULL_IMPORT_DESCRIPTOR zlib1.dll/ 1264530323 0 275 ` L“3_KÔ.debug$S@Œ@B.idata$5Ì@0À.idata$4Ð@0À zlib1.dll(ÿ Microsoft (R) LINK@comp.idÿ ÿÿzlib1_NULL_THUNK_DATA zlib1.dll/ 1264530323 0 39 ` ÿÿL“3_K_adler32zlib1.dll zlib1.dll/ 1264530323 0 40 ` ÿÿL“3_K_compresszlib1.dllzlib1.dll/ 1264530323 0 41 ` ÿÿL“3_K_compress2zlib1.dll zlib1.dll/ 1264530323 0 45 ` ÿÿL“3_K_compressBoundzlib1.dll zlib1.dll/ 1264530323 0 37 ` ÿÿL“3_K_crc32zlib1.dll zlib1.dll/ 1264530323 0 39 ` ÿÿL“3_K_deflatezlib1.dll zlib1.dll/ 1264530323 0 44 ` ÿÿL“3_K_deflateBoundzlib1.dllzlib1.dll/ 1264530323 0 43 ` ÿÿL“3_K_deflateCopyzlib1.dll zlib1.dll/ 1264530323 0 42 ` ÿÿL“3_K_deflateEndzlib1.dllzlib1.dll/ 1264530323 0 45 ` ÿÿL“3_K _deflateInit2_zlib1.dll zlib1.dll/ 1264530323 0 44 ` ÿÿL“3_K _deflateInit_zlib1.dllzlib1.dll/ 1264530323 0 45 ` ÿÿL“3_K _deflateParamszlib1.dll zlib1.dll/ 1264530323 0 44 ` ÿÿL“3_K _deflatePrimezlib1.dllzlib1.dll/ 1264530323 0 44 ` ÿÿL“3_K _deflateResetzlib1.dllzlib1.dll/ 1264530323 0 52 ` ÿÿL“3_K _deflateSetDictionaryzlib1.dllzlib1.dll/ 1264530323 0 45 ` ÿÿL“3_K_get_crc_tablezlib1.dll zlib1.dll/ 1264530323 0 42 ` ÿÿL“3_K_gzclearerrzlib1.dllzlib1.dll/ 1264530323 0 39 ` ÿÿL“3_K_gzclosezlib1.dll zlib1.dll/ 1264530323 0 39 ` ÿÿL“3_K_gzdopenzlib1.dll zlib1.dll/ 1264530323 0 37 ` ÿÿL“3_K_gzeofzlib1.dll zlib1.dll/ 1264530323 0 39 ` ÿÿL“3_K_gzerrorzlib1.dll zlib1.dll/ 1264530323 0 39 ` ÿÿL“3_K_gzflushzlib1.dll zlib1.dll/ 1264530323 0 38 ` ÿÿL“3_K_gzgetczlib1.dllzlib1.dll/ 1264530323 0 38 ` ÿÿL“3_K_gzgetszlib1.dllzlib1.dll/ 1264530323 0 38 ` ÿÿL“3_K_gzopenzlib1.dllzlib1.dll/ 1264530323 0 40 ` ÿÿL“3_K_gzprintfzlib1.dllzlib1.dll/ 1264530323 0 38 ` ÿÿL“3_K_gzputczlib1.dllzlib1.dll/ 1264530323 0 38 ` ÿÿL“3_K_gzputszlib1.dllzlib1.dll/ 1264530323 0 38 ` ÿÿL“3_K_gzreadzlib1.dllzlib1.dll/ 1264530323 0 40 ` ÿÿL“3_K_gzrewindzlib1.dllzlib1.dll/ 1264530323 0 38 ` ÿÿL“3_K_gzseekzlib1.dllzlib1.dll/ 1264530323 0 43 ` ÿÿL“3_K_gzsetparamszlib1.dll zlib1.dll/ 1264530323 0 38 ` ÿÿL“3_K _gztellzlib1.dllzlib1.dll/ 1264530323 0 40 ` ÿÿL“3_K!_gzungetczlib1.dllzlib1.dll/ 1264530323 0 39 ` ÿÿL“3_K"_gzwritezlib1.dll zlib1.dll/ 1264530323 0 39 ` ÿÿL“3_K#_inflatezlib1.dll zlib1.dll/ 1264530323 0 43 ` ÿÿL“3_K$_inflateBackzlib1.dll zlib1.dll/ 1264530323 0 46 ` ÿÿL“3_K%_inflateBackEndzlib1.dllzlib1.dll/ 1264530323 0 48 ` ÿÿL“3_K&_inflateBackInit_zlib1.dllzlib1.dll/ 1264530323 0 43 ` ÿÿL“3_K'_inflateCopyzlib1.dll zlib1.dll/ 1264530323 0 42 ` ÿÿL“3_K(_inflateEndzlib1.dllzlib1.dll/ 1264530323 0 45 ` ÿÿL“3_K)_inflateInit2_zlib1.dll zlib1.dll/ 1264530323 0 44 ` ÿÿL“3_K*_inflateInit_zlib1.dllzlib1.dll/ 1264530323 0 44 ` ÿÿL“3_K+_inflateResetzlib1.dllzlib1.dll/ 1264530323 0 52 ` ÿÿL“3_K ,_inflateSetDictionaryzlib1.dllzlib1.dll/ 1264530323 0 43 ` ÿÿL“3_K-_inflateSynczlib1.dll zlib1.dll/ 1264530323 0 48 ` ÿÿL“3_K._inflateSyncPointzlib1.dllzlib1.dll/ 1264530323 0 42 ` ÿÿL“3_K/_uncompresszlib1.dllzlib1.dll/ 1264530323 0 38 ` ÿÿL“3_K0_zErrorzlib1.dllzlib1.dll/ 1264530323 0 48 ` ÿÿL“3_K1_zlibCompileFlagszlib1.dllzlib1.dll/ 1264530323 0 43 ` ÿÿL“3_K2_zlibVersionzlib1.dll snort-2.9.15.1/src/win32/WIN32-Prj/0000755000000000000000000000000013571426520013154 500000000000000snort-2.9.15.1/src/win32/WIN32-Prj/build_releases.bat0000444000175200017520000000154613571422610016604 00000000000000@echo off REM $Id$ REM -- -------------------------------------------------------------- REM -- If you are having problems running "NMAKE", you probably REM -- haven't configured the proper paths. Uncomment the following REM -- line to help configure this properly. You will need to update REM -- the line to reflect whichever drive/path you specified when REM -- installing Visual C++ 6.0. REM -- -------------------------------------------------------------- REM call "C:\Program Files\Microsoft Visual Studio\VC98\Bin\vcvars32.bat" DEL snort___Win32_MySQL_Release\snort.exe DEL snort___Win32_SQLServer_Release\snort.exe DEL snort___Win32_Oracle_Release\snort.exe NMAKE /f "snort.mak" CFG="snort - Win32 MySQL Release" NMAKE /f "snort.mak" CFG="snort - Win32 SQLServer Release" NMAKE /f "snort.mak" CFG="snort - Win32 Oracle Release" snort-2.9.15.1/src/win32/WIN32-Prj/LibnetNT.dll0000555000175200017520000022000013571422610015275 00000000000000MZÿÿ¸@躴 Í!¸LÍ!This program cannot be run in DOS mode. $ˆ³8¼ÌÒVïÌÒVïÌÒVï·ÎZïÍÒVïúô]ïÍÒVïOÎXïØÒVï®ÍEïÊÒVïÌÒWï¬ÒVïúô\ï¾ÒVï3òRïÊÒVïRichÌÒVïPEL@ÀBCà!  €òW°0Âë°ºx l°X.text&’  `.rdataë° °@@.dataäKÐ@Ð@À.relocj @BSV‹t$Wƒþuc‹D$‹8‹Ç%€ÿt=€ÿu ƒþ~NÁçëå‹L$‹\$‹T$VQSRè.ƒÄ…Àt&‹ ;Î| +Ή ‹ÎN…ÉtN‹×Áêˆ@ÁçIuò_^[Ã3À_^[ÃSUV‹t$ 3íƒþW…‚‹D$ ‹8‹ÏÁéöÁ€t ½¾ë÷Ç€ÿuƒþ~ ÁçN÷Ç€ÿtï‹T$‹\$‹D$VRSP蓃Ä…Àt1‹ ;Î|++΃ý‰ uÆ@N‹ÎN…ÉtN‹×Áêˆ@ÁçIuò_^][Ã3À_^][ËD$ ‹L$SV‹t$W‹|$VPWQè4‹ØƒÄ…Ût 97|‹T$VRSèK-‹ƒÄ +Ɖ3_^[Ã_^3À[ËD$ƒ8}3ÀËL$ŠT$ ˆ‹JA‰‹T$RPQèHƒÄ ËD$‹ƒÁü‰yƒÁ‰3ÀËD$ŠL$ ˆ‹L$@‹ÑÁúÆ‚@ˆ@ˆ@ËL$ ‹D$Vù€W‹ð}‹|$ƒ?}E_3À^Ë|$ùÿ‹ƒú}_3À^ÃÆ@ˆ‹@+ðΉ_^Ãú}_3À^ÃÆ‚‹Ñ@Áúˆ@ˆ‹@+ðΉ_^Ãì@SU‹l$XV‹t$`Wƒþ‹Õ}ÇD$d3À‹t$dë‹E‹MU€Á‹Ø¹3ÿ=€sÆD Gë;=@s ÆD ƒÇë*= s ÆD ƒÇë=s ÆD ƒÇëÆD ƒÇA;Î}‹ƒÂ몋T$\‹t$X‹D$TWRVPèwþÿÿƒÄ…À„ƒ9>|‹Ë‹\$d¾ƒÅ;Þ~[ƒþt‹MƒÅ3ÒŠT4Jƒúw?ÿ$•”ˆë3‹ÑÁê€Ê€ˆ@‹ÑÁê€Ê€ˆ@‹ÑÁê€Ê€ˆ@‹ÑÁê€Ê€ˆŠÑ@€âˆ@F;ó|¥‹L$X‹+×_^]‰[ƒÄ@Ã_^]3À[ƒÄ@ÃI8]RG<‹D$ ‹L$‹T$jPQRèªýÿÿƒÄÃSUV‹t$ ƒþW|E‹l$ €}w;‹D$‹|$‹L$VPWQètýÿÿ‹ØƒÄ…Ût97|VUSè*‹ƒÄ +Ɖ3_^][Ã_^]3À[ÃìU‹l$P…íuƒÈÿ]ƒÄËD$$SV‹5±WPÿÖ‹L$4f‰D$QÿÖ‹\$8ŠT$ýÿÿ‹È%ÿÿÁùÈS‹ÁÁøÁ÷Ðf‰èò$ƒÄ _^¸[Ã$Ð#Ð#³$³$³$t#‹D$‹L$PQèáüÿÿ‹È%ÿÿÁùȃÄ‹ÁÁøÁ÷ÐÃSUVW‹|$ŠƒàÁà‹ð‹D$ƒøp‡ƒ3ÉŠˆü'ÿ$Ü'f‹l>>ƒÇ jWfÇCèyüÿÿ‹|$$ƒÄ‹ðWRÿø°%ÿÿWSðèXüÿÿƒÄðf‰ké f‹l>>ƒÇ jWfÇCè1üÿÿ‹|$$ƒÄ‹ðGPÿø°%ÿÿWSðèüÿÿƒÄðf‰kéÄ‹L$f‹\7þQWfÇGèêûÿÿƒÄ‹ðf‰_éž‹T$f‹\7þRWfÇGèÄûÿÿƒÄ‹ðf‰_ë{jèm$‹ØƒÄ…Û„‡f‹l> |> jSfÇèûÿÿS‹ðf‰/èV#ƒÄ ëA‹D$f‹_ PWfÇG èjûÿÿƒÄ‹ðf‰_ ë!‹L$f‹\7þQWfÇGèGûÿÿƒÄ‹ðf‰_‹ÎæÿÿÁùÎ_‹Á^ÁøÁ]÷Ð%ÿÿ[Ã_^]ƒÈÿ[Ëÿq'î&'^&¦&7'‘'Ò'‹D$Pèk$ƒÄËL$ì„$ T$VPQRèÆ%‹´$ƒÄ ‹ÆHtHt Hu hÜÐë hÐÐëhÄÐhÓè΃ÄD$PhÀÐhÓè·ƒÄ ƒþ^ujèk$ÄÃSV‹t$ W‹|$hÑW3Û膋D$ƒÄÑèHxjU3í@‰D$‹Ã%€yHƒÈø@uUhøÐWèVƒÄ ‹D$…Àtf‹ƒÆPÿø°%ÿÿë3Àf‹ƒÆPhðÐWè#‹D$ ƒÄ CƒÅH‰D$uŸ]öD$t6‹Ëá€yIƒÉøAuRhøÐWèéƒÄ 3ÀŠPhèÐWèÖƒÄ häÐWèȃÄ_^[ø`èV'W¹3À¼$`ó«D$Œ$ PQÇD$ è=ƒÄ„ÀuhÑèÊ&ƒÄƒÈÿ_Ä`ÃSVÿP°=€‚€<r|„$ ´$ ”$`f‹f…Éu*f9Hþt)f…Éu‹È‹ú+ÎÑù‹ÙÁéó¥‹Ëƒá ó¤pƒÀëɼ$`ƒÉÿ3Àò®‹„$`÷Ñ+ù‹Ñ‹÷‹8Áéó¥‹Êƒáó¤é˜U„$ ´$ 3Òœ$`f‹f…Éu-f9Hþt/f…Éu"‹È‹û+ÎÑùÑá‹éÁéó¥‹ÍƒáBó¤pà ƒÀƒú uÃŒ$`hT$QRè‚#|$ ƒÉÿ3ÀƒÄ ò®‹”$`]÷Ñ+ù‹Á‹÷‹:Áéó¥‹Èƒá󤋄$`^[_fǸÄ`ÃS‹\$…ÛUu]ƒÈÿ[Ãf‹CPÿ±‹l$‹Èåÿáÿÿ͉D$ùÿÿ~]ƒÈÿ[Ãf=vSUD+RPèÊƒÄ ‹T$ ‹ÍV‹ÁWr{Áéó¥‹ÈŠD$ƒáó¤3É_„À^v3À‹Ðâ€yJƒÊüBuA@MuꊊÐÑ2Ѐâ2Ðf¶D$ˆ‹T$ÂPÿø°f‰C]¸[Ãì,SU‹l$@V…íu ^]ƒÈÿ[ƒÄ,À} t ^]ƒÈÿ[ƒÄ,Ë\$@€û(v ^]ƒÈÿ[ƒÄ,Ãf‹EPÿø°‹ó‰D$ æÿ‹Îá€yIƒÉüAt*ـÈ\$@%ÿÿ‹\$@ãÿ ùÿÿ~ ^]ƒÈÿ[ƒÄ,ÊMƒál;Â~Áá+ÁUƒèPD+RPè”ƒÄ ‹Î‹t$<‹ÑW|$Áéó¥‹ÊŠT$Dƒáó¤‹Ët$‹Á}Áéó¥‹Èƒáó¤3É_„Òv3À‹ðæ€yNƒÎüFuA@KuêŠE fÇEŠØ$€ãðÀáÙf3ÉŠÊ‹T$ Ê2ØQˆ] ÿ±‹T$D^][f‰B¸ƒÄ,ÃVjj觃ģ°…Àu$èi$‹Pèúÿÿ‹L$Ph4ÑQèŒ#ƒÄ3À^Ãj躋ðƒÄ…öu^ÃW‹|$ ÇÇF‹WVj‹Pè<ƒÄ „Àu‹W3ɉ f‰Jë‹GƒÆ‹‰f‹Vf‰P3À‹O@ƒøŠ”‹ °ˆTÿ|æ¡°_^ÃìVWjè‹ðƒÄ…öu.è—#‹PèËùÿÿ‹Œ$$Ph4ÑQè·"ƒÄ3À_^ÄËÆ3Òh j‰‰P‰P‰P ‰Pè}ƒÄ‰F…Àu4èA#‹Qèuùÿÿ‹”$$Ph4ÑRèa"V讃Ä3À_^Ä˼$Wè;‹NƒÄ‰‹V‹…À„Òƒ8ÿ„ÉL$QPè ƒÄ„Àu‹”$ hpÑRèþ!‹FP鱋D$ƒøw+ÿ$…D0ÇF ë"ÇFëÇFëÇF ëÇF‹NhÿƒÁWQÇÇFè|"‹FT$$ƒÀRPV‰F è‡ ‹N D$0PQVè¸ýÿÿ‹VhЋPèVƒÄ,‹Æ_^ÄÃÿT°Ph@ÑèÉ ‹NQè’V范Ä3À_^Äî/“/Š/®/®/®/®/œ/¥/V‹t$Vèåéÿÿ‹FƒÄ‹…Àth€Pèä ‹N‹RèÓ ƒÄ ‹FPèVèƒÄ¸^ÃVèÈ ‹ð…öuh”Ñè ƒÄƒÈÿ^ËD$W‹|$WPVè™ ‹L$‰~ jV‹Q‹Pè~ Vèr ƒÄ‹Ç_^ÃV‹t$…öW¾Vèv‹ø‹D$ƒÄ…ÿ‰8u_ƒÈÿ^ËÎ3À‹ÑÁéó«‹Êƒáóª_¸^ÃV‹t$‹…ÀuƒÈÿ^ÃPè<ƒÄǸ^ÃS‹\$VWƒ;u_^ƒÈÿ[ËL$…ɹ‹Á%€yHƒÈü@tA‹Ñâ€yJƒÊüBuî‹D$f…Àw¸%ÿÿ¯Á‹ðVè«‹ ƒÄ‰A‹‹z…ÿu_^ƒÈÿ[ËÎ3À‹ÑÁéó«‹Êƒáóª‹_Ç@‹ ¸‰q ^[ÃVW‹|$ ‹…Àu_^ËL$…ɹ‹Ñâ€yJƒÊüBtA‹Ñâ€yJƒÊüBuî‹pS‹X ;Ó[v_3À^Ã…öu ‰H‹_^‹@ÉP‹_^‹A‹QÂÃV‹t$‹…ÀuƒÈÿ^Ë@PèÙ‹ƒÄÇA‹ÇBÿÿÿÿ‹^Ç@ ¸Ãì¡ÌÑ‹ ÐÑ‹ÔÑSUVW‹|$(‰D$f¡ØÑ…ÿ‰L$‰T$f‰D$u _^]ƒÈÿ[ƒÄÀ?t?Š\$‹÷„Ût ŠŠÃL$:Ât ŠAA„Àt ëòŠFF„ÀtëÜ‹L$$_^]ǃÈÿ[ƒÄÃj è‹t$(3ÛƒÄ;Éu ‰_^]ƒÈÿ[ƒÄËè‰\$(f‰]‰]Š´ˆU¡´‹H%ÿLQRèƒÄ;ãHu ‰_^]ƒÈÿ[ƒÄË ´hÈÑáÿWf‰H ´þÀ¢´è/ ‹ðƒÄ…ö„å…Ût'j èiƒÄ‰E…í„çf‹T$(‹èf‰UÇEVèæƒÄf‰E3Ûƒ=LÙ~¾jPèȃÄë¾ ‹@׊Jƒà…ÀtCëÏ€<-u%‹þƒÉÿ3ÀCò®÷ÑI;Ùt óVèƒÄë ¸ÿÿëf‹Ef‰Ef‹Mf;Èvf‹Ðf1Uf‹Ef1Ef‹Ef1E‹|$(hÈÑGj»‰|$0èJ‹ðƒÄ…ö…ÿÿÿ‹L$$f‹D$(_^‹][f‰¸ƒÄËD$$_^]ǃÈÿ[ƒÄËD$‹H3ÉŠH…ÀJuƒÈÿÃf‹ f;u‹D$‹L$ fÇfÇfÇ3ÀÃf…Ét áÿÿ‹@Iuúf‹HV‹t$ f‰‹L$f‹@^f‰fÿ¸ÃV‹t$…öuƒÈÿ^Ãf‹Ff‹Nf;Áu%ÿÿPhäÑhpÓè® ƒÄ ëáÿÿ%ÿÿQPhÜÑhpÓè ƒÄ‹v…öu³häÐhpÓèt ƒÄ¸^ÃìW¹3À|$ÆD$ó«f«ª‹¼$…ÿu 3À_ÄÃV3öf‹Gf‹Of;Áu%ÿÿPD4 hðÑPèÙƒÄ ëáÿÿ%ÿÿQPL4hèÑQ踃Äð‹G…ÀtD4hÈÑPF蜃ċ…ÿu—T$RèkƒÄ^_ÄÃV‹t$…öuƒÈÿ^Ãf‹f…Àt%ÿÿW‹ø‹Æ‹vP虃ÄOuï_¸^øÃì D$jjjjPÿ°‹T$L$QjhhRÿ °‹L$D$PjQÿ°‹D$ƒøwfÿ$…8D$ƒàƒÄ ÃD$3Ò¹ÿ÷ñ‹ÂƒÄ ÃD$3Ò¹ÿ÷ñ‹ÂƒÄ ÃD$3Ò¹ÿÿ÷ñ‹ÂƒÄ ÃD$3Ò¹ÿÿÿ÷ñ‹ÂƒÄ ÃD$ƒÄ Ã3ÀƒÄ ß7ª7½7Ð7ã7ö7fÿ¸fƒ|$V‹t$ujD$jP‰t$ÿ±…Àu]‹ ¸áÿÿá€yIƒÉþA¸¸u¸¸‹T$ ‹L$ âÿáÿR‹T$ âÿQæÿRVhôÑPè̃Äë6‹ ¸áÿÿá€yIƒÉþA¹¸u¹¸‹hRQèuƒÄ ¡¸%ÿÿ%€yHƒÈþ@^¸¸u¸¸Ãfƒ|$V‹t$ujD$jP‰t$ÿ±…Àu;‹L$ ‹T$ ‹D$ áÿâÿQ‹L$%ÿRæÿPVhôÑQèƒÄ^Ë‹D$jRPèÒƒÄ ^øVf9D$ WuK‹t$ Vÿ±ƒøÿ‰D$…·Vÿ±…Àu_ƒÈÿ^ÿH ‹@ ‹Ñ|$‹0Áéó¥‹Êƒáó¤‹D$_^Ã9LÙ~‹t$ 3ÀjŠPèMƒÄë‹t$ ‹@×3ÉŠŠJƒà…Àu_ƒÈÿ^Ã3Ò3ÿŠÁâ„Àt/3É<.t ‰%ÿLHÐùÿ‡rÿÿÿŠFF„ÀuÜŠ Ñ„ÀtFGƒÿ|ÂRÿ ±_^Ãì|SUV‹´$Whÿ„$VPè¼3ÛL$,ST$,Q„$ RPèž‹L$8‹= ±ƒÄQÿ׋¬$‹U‰‚ ‹D$#D$ @Pÿ׋M‰Š3ɉ\$ „À‰\$t7<_t ŠD1A„Àuóë(|1ƒÉÿ3À”$Œò®÷Ñ+ù‹Á‹÷‹úÁéó¥‹Èƒáó¤‹5°L$QhShÀÒh€ÿÖ…À…G‹L$T$Rh„$”SPQÿÖ…À…%‹D$T$RhSh¬ÒPÿÖ…À…¸‹5°L$‰D$‰D$T$$Q‹L$D$RPSh ÒQÿÖ…À…Ï‹D$$¹;Áu ¸Ò½|Òë ¸pÒ½`ÒT$‰L$RL$,T$QRSP‹D$$¿dP‰|$,ÿÖ‹±…ÀuL$(QÿÓ‹”$‹J‰ ë‹”$˜h4ÒRè+ƒÄD$L$(P‹D$T$QRjUP‰|$,ÿÖ…ÀuL$(QÿÓ‹”$‹J‰ë‹”$˜hÒRè܃ċ„$‹H‹‘ Rÿü°_^][Ä|Ãìhjè‰D$¡¼ƒÄ…ÀuXD$L$PT$QRèêìÿÿƒÄ ƒøÿuhäÒèèƒÄƒÈÿÄËL$D$PQè\ñÿÿƒÄ£¼…Àu ƒÈÿÄËT$Rè~ ƒÄ¸Äá¼PèóÿÿƒÄǼ¸Ãì¹3ÀV‹´$ W|$ó«‹ ¼‹FQPè„×ÿÿƒÄ…ÀuhÓëD‹ ¼‹¼$T$R‹QWVÂhRPèÝÿÿjD$2jPèOåÿÿƒÄ$ƒøÿuhÓhÓ薃ăÈÿ_^ÄἃÇL$W‹P QRPè‘òÿÿƒÄƒè_^ÄÃÿ%P±ÿ%H±ÿ%L±ÿ%±ÿ%±ÿ% ±ÿ%@±ÿ%$±ÿ%4±ÿ%<±ÿ%8±ÿ%(±ÿ%0±ÿ%,±ÌÌÌÌÌÌÌÌÌÌÌÌU‹ìWV‹u ‹M‹}‹Á‹ÑÆ;þv;ø‚x÷ÇuÁéƒâƒùr)ó¥ÿ$•è?‹Çºƒér ƒàÈÿ$…?ÿ$ø?ÿ$|??Vjÿ5  ÿ\°‰Eà9]àu'9HtVèOY…À…0ÿÿÿë3Û‹u j è8+YËEà‹Mðd‰ _^[ÉÃSV‹t$ WVèëVè÷,‹øD$ Pÿt$ Vè-VW‹Øèj-VèƒÄ ‹Ã_^[áàVj…À^u¸ë;Æ}‹Æ£àjPè`þÿÿY£Ä …ÀYu!jV‰5àèGþÿÿY£Ä …ÀYujècY3ɸPÓ‹Ä ‰ƒÀ ƒÁ=ÐÕ|ê3ɺ`Ó‹ñ‹ÁÁþƒà‹4µ€ À‹†ƒøÿt…Àuƒ ÿƒÂ AúÀÓ|Ñ^ÃèZ8€=$téA7ËD$¹PÓ;Ár=°Õw+ÁÁøƒÀPè©)YÃÀ Pÿ`°ËD$ƒø} ƒÀPèŠ)YËD$ƒÀ Pÿ`°ËD$¹PÓ;Ár=°Õw+ÁÁøƒÀPè¸)YÃÀ Pÿd°ËD$ƒø} ƒÀPè™)YËD$ƒÀ Pÿd°ÃU‹ììøSV‹u Wƒþ‚7ƒ}„-ƒeüN¯u‹]E€‰E…ÿÿÿó‰E ‹}‹Æ+Ã3Ò÷÷@ƒøw/ÿuWVSèùƒÄÿMüƒm ƒmƒ}üŒÜ‹E ‹‹E‹0ëÀÑè¯ÇWÃSPèƒÄ ‰]øþ‹EøE;ƉEøw SPÿUY…ÀY~è+};ûv SWÿUY…ÀY}îÿu;}øWr ÿuøèÑƒÄ ëÀSèÆ‹Eø‹Ï+Ë‹ÖƒÄ I+Ð;Ê|0‹M ;×s‹U ƒE +ù‹MÿEüƒE‰‰9;ƃFÿÿÿ‹Øé ÿÿÿ;Æs‹M ÿEüƒE ‰‹EƒE‰0‹EÃ;ǃÿÿÿ+}‹÷éðþÿÿ_^[ÉÃU‹ì‹EW‹} ;øv=‹MSÁV‰E ‹]‹u ;÷wSVÿUY…ÀY~‹ÞuëêÿuWSè+}ƒÄ ;}wÏ^[_]ËD$‹L$;ÁVt‹T$‹òJ…ötSrŠŠˆ@ˆANuó[^ÃU‹ìjÿhÀ±hÐod¡Pd‰%ƒì(SVW‹]3ÿ;ßuÿu èoYéæ‹u ;÷u SèsYéÑ¡¤ ƒø…9‰}܃þà‡ñj èë&Y‰}üSè€Y‰EØ;Ç„¤;5œ wLVSPèmƒÄ …Àt‰]Üë8Vè¦Y‰EÜ;Çt*‹CüH‰Eà;Ær‹ÆPSÿuÜèÃ5Sè-‰EØSPèNƒÄ9}ÜuK;÷uj^‰u ƒÆƒæð‰u VWÿ5  ÿ\°‰EÜ;Çt#‹CüH‰Eà;Ær‹ÆPSÿuÜèl5SÿuØèþƒÄƒMüÿèZ9}Øu";÷uj^ƒÆƒæð‰u VSWÿ5  ÿh°‰EÜ‹EÜ;Ç…½9=H„±VèEY…À…Ýþÿÿ雋u ‹]3ÿj è(&YÃø…Gƒþàw;÷vƒÆƒæðëj^‰u ‰}܃þà‡ój è’%YÇEüEÔPEÈPSèv ƒÄ ‹ø‰}Ð…ÿ„ª;5„ùs\‹ÞÁëSWÿuÔÿuÈè$ƒÄ…Àt‹E‰EÜë8SèÓ Y‰EÜ…Àt*¶Áà‰EÌ;Ær‹ÆPÿuÿuÜèI4WÿuÔÿuÈè_ ƒÄ‹]ƒ}ÜuSVjÿ5  ÿ\°‰EÜ…Àt=¶Áà‰EÌ;Ær‹ÆPSÿuÜè4WÿuÔÿuÈè ƒÄëVSjÿ5  ÿh°‰E܃Müÿè&‹EÜ;Çuf9=Ht^VèòY…À…ãþÿÿëK‹u ‹]j èÚ$Y3ÿÃ3Àƒþàw;÷uj^ƒÆƒæðVSWÿ5  ÿh°;Çu9=Ht Vè¡Y…ÀuÆ3À‹Mðd‰ _^[ÉÃVWj_WèD7‹t$Y…öt"€>tVèª9PVWè8WhرWè8ƒÄèƒ8|踋;@û} è©‹ë¡@û‹4…úVè_9PVWèÃ7jhäÐWè¶7Wè)7ƒÄ _^ÃU‹ìjÿhà±hÐod¡Pd‰%ƒìSVW‹u…ö„¬¡¤ ƒøu;j è`#YƒeüVèôY‰Eä…Àt VPèYYƒMüÿèƒ}äëQj è#YÃøuSj è #YÇEüEàPEØPVèƒÄ ‰EÜ…ÀtPÿuàÿuØèEƒÄ ƒMüÿè ƒ}Üuÿuë j è7#YÃVjÿ5  ÿl°‹Mðd‰ _^[ÉÃÿ5Hÿt$èYYÃ|$àw"ÿt$è…ÀYu9D$tÿt$èá …ÀYuÞ3ÀÃU‹ìjÿhø±hÐod¡Pd‰%ƒì SVW¡¤ ƒøuC‹u;5œ ‡“j è5"YƒeüVèY‰EäƒMüÿè ‹Eä…Àtmé†j èk"YÃøuZ‹E…Àtpƒæðëj^‰u;5„ùw.j èß!YÇEü‹ÆÁèPèbY‰EäƒMüÿè ‹Eä…Àu-Vë‹uj è "YËE…ÀujXƒÀ$ðPjÿ5  ÿ\°‹Mðd‰ _^[ÉÃVè 9‹ðƒ~$uh†è®þÿÿ…ÀY‰F$u¾Äë‹v$‹L$¡@û…É|;È}‹Áÿ4…úVèQ7Y‹ÆY^áÀ …ÀtÿÐhÐhÐèûhÐhÐèìƒÄÃjjÿt$ è$ƒÄ Ãjjÿt$ èƒÄ ÃjjjèƒÄ ÃWèŸj_9=,uÿt$ÿx°Pÿt°ƒ|$ S‹\$‰=(ˆ$u<¡¼ …Àt"‹ ¸ Vqü;ðr‹…ÀtÿЃî;5¼ sí^h ÐhÐèCYYh(Ðh$Ðè2YY…Û[tè_Ãÿt$‰=,ÿp°_Ãj è" YÃj èz YÃV‹t$;t$ s ‹…ÀtÿЃÆëí^ÃU‹ìƒì ‹EVÿu‰Eè‰EàEàÿu ÇEìBÇEäÿÿÿPèÎ"ƒÄ ÿMä‹ðx‹Eà€ ë EàPjèN8YY‹Æ^ÉÃU‹ìSV¾l WVÿ€°‹=|°3Û9h tVÿ×jè€Yj[ÿuÿu ÿuèƒÄ ‰E…Ût jè¾YëVÿ׋E_^[]ÃU‹ìƒì SV‹uW3Û3ÿ;ó‰]ø„E‹U;Óu3Àé9Ìu-;Óv"‹M f9ÿ‡YŠˆ7f‹AAf…ÀtG;úrá‹ÇéLƒ=LÙuP;ÓvRÿu è;Y‰EY‹ÐEøPSRVRÿu h ÿ5Üÿ„°;Äý9]ø…ô8\0ÿ…øéâEø‹=„°PSRVjÿÿu h ÿ5Üÿ׋ð;ót9]ø…·Fÿé½9]ø…¦ÿT°ƒøz…—;usREøPSÿ5LÙEþPjÿu Sÿ5Üÿ×;ÉEôtn9]øui 0;Mw!3Ò;Ã~ŠLþ‹E:ˈ t BF;Uô|ëƒE ë©‹ÆëJ9Ìu ÿu è’7Yë7EøPSSSjÿÿu h ÿ5Üÿ„°;Ãt9]øuHëèÇ*ƒÈÿ_^[ÉÃU‹ì‹M ‹E3Ò;Êtf9t@@Iuö;Êt f9u+EÑø@]ËE ]ÃSV¾pÓWVjèÅóÿÿV袋øD$ Pÿt$ VèH VW‹Øè VjèïóÿÿƒÄ(‹Ã_^[ÃÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌQ=L$ré-…=sì+ȋą‹á‹‹@PÃU‹ìƒì ‹EV‰Eè‰EàEÇEìBPEàÿu ÇEäÿÿÿPèÂƒÄ ÿMä‹ðx‹Eà€ ë EàPjèB5YY‹Æ^ÉÃVèv‹L$3ö‰¸ÐÕ;t"ƒÀF=8×rñƒùr"ƒù$wèBÇ ^Ãè5‹ õÔÕ^‰Ãù¼rùÊw èÇ^ÃèÇ^Ãè¼3ƒÀÃè³3ƒÀ ÃÌÌÌÌÌÌÌÌÌÌ‹L$ W…ÉtzVS‹Ù‹t$÷Æ‹|$uÁéuoë!ŠFˆGIt%„Àt)÷Æuë‹ÙÁéuQƒãt ŠFˆG„Àt/Kuó‹D$[^_Ã÷ÇtˆGI„Š÷Çuî‹ÙÁéulˆGKuú[^‹D$_ɃÇIt¯ºÿþþ~‹Ѓðÿ3‹ƒÆ©tÞ„Òt,„öt÷Âÿt ÷ÂÿuƉëâÿÿ‰ëâÿ‰ë3Ò‰ƒÇ3ÀIt 3À‰ƒÇIuøƒãu…‹D$[^_ÃU‹ìQ‹EHùw ‹ @×·AëR‹ÈV‹5@×Áù¶ÑöDV€^t€eþˆMüˆEýjë €eýˆEüjXM jjjQPEüPjè€4ƒÄ…ÀuÉ÷E #E ÉÃSUVW‹|$ƒ=LÙ~¶jPèoÿÿÿYYë¶‹ @׊Aƒà…ÀtGëÒ¶7Gƒþ-‹îtƒþ+u¶7G3Ûƒ=LÙ~ jVè.ÿÿÿYYë ¡@׊pƒà…Àt ›\Fж7Gëσý-‹Ãu÷Ø_^][Ãÿt$èlÿÿÿYÃU‹ìƒì SV‹u Wè‹1j‰E Y3À}àjó«_г¶Ê‹Á#ÏÁèÒãDàF„Òuå‹U…Òu‹E ‹PŠj¶ð‹Î[#ÏÓãÁîŠL5à„Ùt„ÀtBëà‹ÚŠ„Àt¶ð‹Îj#ÏXÓàÁîŠL5à„ÁuBëà€"B‹E _^‰P‹Ã+Â÷ØÀ#Ã[ÉÃjÿt$ÿt$ÿt$èƒÄÃU‹ìƒì SƒeøVW‹}Šw‰uüƒ=LÙ~¶ÃjPèþÿÿYYë‹ @׶ÊAƒà…ÀtŠFëЀû-‰uüuƒMë€û+uŠF‰uü‹E…ÀŒ‰ƒø„€ƒø$wj…ÀYu$€û0t ÇE ë2Šƒàt }ø€w …Àu,9uøv'èiûÿÿöEÇ"tƒMøÿë‹E$öØÀ÷ØƉEø…Ût‹Eü‰öEt‹Eø÷؉Eø‹Eøë ‹E …Àt‰83À_^[ÉËD$ƒø…ˆÿP°j£ðè…ÀYt<¡ð3ÉŠ ñ%ÿÁ-ð£ø‰ üÁàÁ£ôè.…Àu è63Àërÿˆ°£¨ èh6£4è/"è 4èN3èõÿÿÿ0ë>3É;Áu,9 0~½ÿ 09 (uèµõÿÿè®#èë-èÑë ƒøuQèq.YjX U‹ìS‹]V‹u W‹}…öu ƒ=0ë&ƒþtƒþu"¡¬ …Àt WVSÿÐ…Àt WVSèçþÿÿ…Àu3ÀëNWVSèå6ƒþ‰E u …Àu7WPSèÃþÿÿ…ötƒþu&WVSè²þÿÿ…Àu!E ƒ} t¡¬ …ÀtWVSÿЉE ‹E _^[] ¡<ƒøt …Àuƒ=@uè‚6ÿt$è²6hÿÿXÙYYáD…Àtÿt$ÿÐ…ÀYtjXÃ3ÀÃV‹t$jƒ&ÿŒ°f8MZu‹H<…Ét ÁŠHˆŠ@ˆF^ÃU‹ì¸,è)øÿÿ…hÿÿÿSPÇ…hÿÿÿ”ÿ˜°…Àtƒ½xÿÿÿuƒ½lÿÿÿrjXé…ÔíÿÿhPh(²ÿ”°…À„Ð3ÛÔíÿÿ8ÔíÿÿtŠj,PèÊ6Y;ÃYt0@‹È8t€9;uˆëA8uòj SPèÓúÿÿƒÄ ƒøtƒøtƒøtEüPè˜þÿÿ€}üYÀƒÀ[ÉÃ3Àj9D$h”ÀPÿ<°…À£  t6è“þÿÿƒø£¤ u høè-Yë ƒøuèg …Àuÿ5  ÿ°3ÀÃjXᤠVƒøWufS3Û9” U‹-l°~@¡˜ ‹=°p h@hÿ6ÿ×h€jÿ6ÿ×ÿvjÿ5  ÿÕƒÆC;” |Îÿ5˜ jÿ5  ÿÕ][ë'ƒøu"¿`Ù‹÷‹F…Àth€jPÿ°‹6;÷uåÿ5  ÿ°_^ÃÌÌÌÌÌÌÌÌÌ‹T$ ‹L$…ÒtG3ÀŠD$W‹ùƒúr-÷Ùƒát+шGIuú‹ÈÁàÁ‹ÈÁàÁ‹ÊƒâÁétó«…ÒtˆGJuú‹D$_ËD$Ãh@jÿ5  ÿ\°…À£˜ uËL$ƒ% ƒ%” j£Œ ‰ œ Ç„ Xá”  €¡˜  ˆ;Ás‹T$+P úrƒÀëè3ÀÃU‹ìƒì‹MSV‹u ‹AW‹þƒÆü+y Áï‹ÏiÉŒD‰Mð‹IöÁ‰Mü…æ‹11‰Uô‹Vü‰Uø‹Uôö‰] u~ÁúJƒú?vj?Z‹K;KuLƒú s»€‹ÊÓëL÷Ó!\¸Dþ u(‹M!ë!JເÓëL÷Ó!œ¸Äþ u‹M!Y‹Mü‹] ë‹Mü‹S‹[Mô‰Z‹U ‰Mü‹Z‹R‰S‹ÑÁúJƒú?vj?Z‹]øƒã‰]ô…”+uø‹]øÁûj?‰u K^;Þv‹ÞMø‹Ñ‰MüÁúJ;Öv‹Ö;Útc‹M ‹q;qu@ƒû s¾€‹ËÓî÷Ö!t¸DþLu&‹M!1ëKྀÓî÷Ö!´¸ÄþLu‹M!q‹M ‹q‹I‰N‹M ‹q‹I‰N‹u ë‹]ƒ}ôu;Ú„‹Mð‹\Ñ щ^‰N‰q‹N‰q‹N;Nu`ŠLƒú ˆMþÁˆLs%€}u»€‹ÊÓë‹M »€‹ÊÓëD¸D ë)€}uJເÓë‹M YJ຀Óê„¸Ä ‹Eü‰‰D0ü‹Eðÿ…÷¡ …À„Ü‹ ˆ ‹5°ÁáH »€h@SQÿÖ‹ ˆ ¡ º€Óê P¡ ‹ ˆ ‹@ƒ¤ˆÄ¡ ‹@þHC¡ ‹H€yCu ƒ`þ¡ ƒxÿuiSjÿp ÿÖ¡ ÿpjÿ5  ÿl°¡” ‹˜ €Áà‹È¡ +ÈLìQHQPèßÿÿ‹EƒÄ ÿ ” ; vƒm¡˜ £Œ ‹E‰=ˆ £ _^[ÉÃU‹ìƒì¡” ‹˜ SV€W<‚‹E‰}üHƒáð‰MðÁùIƒù }ƒÎÿÓîƒMøÿ‰uôëƒÁàƒÈÿ3öÓè‰uô‰Eø¡Œ ‹Ø;߉]s‹K‹;#Mø#þ Ïu ƒÃ;]ü‰]rç;]üuy‹Ú;؉]s‹K‹;#Mø#þ ÏuƒÃëæ;ØuY;]üsƒ{uƒÃ‰]ëí;]üu&‹Ú;؉]s ƒ{uƒÃëî;Øuè8‹Ø…Û‰]tSèÚY‹K‰‹Cƒ8ÿu3À鉌 ‹C‹ƒúÿ‰Uüt‹ŒÄ‹|D#Mø#þ Ïu7‹Ä‹pD#Uø#uôƒeüHD Ö‹uôu‹‘„ÿEü#UøƒÁ‹þ#9 ×té‹Uü‹Ê3ÿiÉŒD‰Mô‹LD#Îu ‹ŒÄj #Mø_…É|ÑáGë÷‹Mô‹Tù‹ +Mð‹ñ‰MøÁþNƒþ?~j?^;÷„ ‹J;Juaƒÿ }+»€‹ÏÓë‹Mü|8÷Ó‰]ì#\ˆD‰\ˆDþu8‹]‹Mì! ë1OເÓë‹Mü|8ŒˆÄ÷Ó!þ‰]ìu ‹]‹Mì!Kë‹]‹J‹zƒ}ø‰y‹J‹z‰y„”‹Mô‹|ñ ñ‰z‰J‰Q‹J‰Q‹J;JudŠLƒþ ˆM })þÁ€} ˆLu ¿€‹ÎÓï ;¿€‹ÎÓï‹Mü |ˆDë/þÁ€} ˆLu Nà¿€Óï {‹Mü¼ˆÄNྀÓî 7‹Mø…Ét ‰ ‰Lüë‹Mø‹uðÑN‰ ‰L2ü‹uô‹…Éy‰>u; u‹Mü; ˆ uƒ% ‹Mü‰B_^[Éá” ‹ „ VW3ÿ;Áu0D‰PÁàPÿ5˜ Wÿ5  ÿh°;Çtaƒ„ £˜ ¡” ‹ ˜ hÄAj€ÿ5  4ÿ\°;ljFt*jh hWÿ °;ljF uÿvWÿ5  ÿl°3ÀëƒNÿ‰>‰~ÿ” ‹Fƒÿ‹Æ_^ÃU‹ìQ‹MSVW‹q‹A3Û…À|ÑàCë÷‹Ãj?iÀZ„0D‰Eü‰@‰@ƒÀJuô‹ûjÁçy hh€Wÿ °…ÀuƒÈÿé“—p;úwt‹Æ4;ósCŠ„Ûu0jX^€;uCFë÷;òsN;Eüu‰që )u 9U ‚™‹}ü‹Ãë¶óÆ4;ur½q;÷s~;EsvŠ„Àu@j^X€;u%C@ë÷;]s +ò‰‰që ƒaq‰1ˆƒÀë6;Âs)E 9U r4‹óë®¶Àðë§;]s +‰‰Aë ƒaA‰ˆFkÉÁà+Áë3À_^[ÉÃU‹ìQ‹US‹] V¶ W‹}ƒeü‹Ã+GÁø ;M|Çv‹E+ȈÇGñë`se‹E4ƒø;ðwU;Æs €8u@ëô;ÆuBŠEˆ‹;Ðw+;ðv'ƒø;ðs3À‰38u@€<tù‰Cë ƒcC‰+MÇEü‹Eü_^[ÉÃV‹5¨°ÿ5ÌùÿÖÿ5¼ùÿÖÿ5¬ùÿÖÿ5ŒùÿÖ^ÃVW‹=¬°¾ˆù‹…Àt+þÌùt#þ¼ùtþ¬ùtþŒùt Pÿ×ÿ6èÜÿÿYƒÆþHú|Äÿ5¬ùÿ×ÿ5¼ùÿ×ÿ5Ìùÿ×ÿ5Œùÿ×_^ÃU‹ì‹EVƒ<…ˆù4…ˆùu>Wjè*Ýÿÿ‹øY…ÿujèêÿÿYjèÊÿÿÿƒ>YWu ÿ¨°‰>ëèÜÿÿYjè Y_ÿ6ÿ`°^]ÃU‹ì‹Eÿ4…ˆùÿd°]ÃÌU‹ìSVWUjjhðnÿuè03]_^[‹å]ËL$÷A¸t‹D$‹T$‰¸ÃSVW‹D$Pjþhøndÿ5d‰%‹D$ ‹X‹p ƒþÿt.;t$$t(4v‹ ³‰L$‰H ƒ|³uh‹D³è@ÿT³ëÃdƒÄ _^[Ã3Àd‹ yønu‹Q ‹R 9Qu¸ÃSQ»Húë SQ»Hú‹M‰K‰C‰k Y[ÂÌÌVC20XC00U‹ìƒìSVWUü‹] ‹E÷@…‚‰Eø‹E‰EüEø‰Cü‹s ‹{ƒþÿta vƒ|tEVUkÿT]^‹] Àt3x<‹{Sè©þÿÿƒÄkVSèÞþÿÿƒÄ vj‹Dèaÿÿÿ‹‰C ÿT‹{ v‹4롸ë¸ëUkjÿSèžþÿÿƒÄ]¸]_^[‹å]ÃU‹L$‹)‹AP‹APèyþÿÿƒÄ]ÂV‹t$ÿvè“!…ÀYtwþpÓu3Àë þÓucjXÿÀf÷F uRƒ<…°SW<…°»u Sè®Úÿÿ…ÀY‰uFj‰F‰X‰F‰Fë ‹?‰^‰~‰>‰^fN jX_[^Ã3À^Ã|$Vt ‹t$ öF tVè8 €f îƒfƒ&ƒfY^ÃU‹ììLSV‹u 3ÉW‰MðŠF„Û‰Mì‰MЉu „N¿ºë ‹Mĺ¿ƒ}ìŒ+€û |€ûx¾ÃŠ€ ²ƒàë3À¾„Á@²Áøƒø‰Ećéÿ$…Ýx3ÀƒMøÿ‰EÀ‰EȉE؉E܉Eü‰EÔéžÃè t;ƒèt-ƒètHHtƒè…¦ƒMüéƒMü锃Müé‹€Mü€é‚ƒMüéy€û*u#EPèB…ÀY‰EØ_ƒMü÷؉EØéQ‹EؾˀDAÐëéƒeøé9€û*uEPè…ÀY‰EøƒMøÿé‹Eø¾Ë€DAЉEøé€ûIt-€ûht€ûlt€ûw…é }üéáƒMüéØƒMü éÏ€>6u€~4uFF€Mý€‰u 鶃eÄ‹ @׃eÔ¶ÃöDA€tEìPÿu¾ÃPèÇŠƒÄ F‰u EìPÿu¾ÃPè®ƒÄ ém¾Ãƒøg8ƒøe–ƒøXì„”ƒèC„¡HHtpHHtlƒè …f÷Eü0u }üƒ}øÿ¾ÿÿÿt‹uøEPèäf÷EüY‹È‰Mô„…Éu ‹ \ú‰MôÇEÔ‹Á‹ÖN…Ò„ðfƒ8„æ@@ëçÇEÀ€Ã ƒMü@ƒ}ø½´ýÿÿ‰}ôÍÇEøéf÷Eü0u }üf÷EüEPt;èwP…´ýÿÿPè#ƒÄ ‰Eð…À}2ÇEÈë)ƒèZt2ƒè tÅH„é<èYˆ…´ýÿÿÇEð…´ýÿÿ‰EôéEPèú…ÀYt2‹H…Ét+…}üt¿Ñè‰Mô‰EðÇEÔéêƒeÔ‰Mô¿éØ¡Xú‰EôPéªu€ûgu>ÇEøë59Uø~‰Uø}ø£~$‹Eø]Pè–Öÿÿ…ÀY‰EÐt‹ø‰}ôëÇEø£‹EÿuÀƒÀ‰Eÿuø‹Hø‰M´‹@ü‰E¸¾ÃPE´WPÿðü‹uüƒÄæ€tƒ}øuWÿüüY€ûgu …öuWÿôüY€?-u€MýG‰}ôWèkYéƒèi„Ѓè„H„„HtQƒè„àýÿÿHH„°ƒè…âÇEÌ'ë<+ÁÑøéÍ…Éu ‹ Xú‰Mô‹Á‹ÖN…Òt€8t@ëñ+Áé¨ÇEøÇEÌöEü€ÇEðt\ŠEÌÆEê0QÇE܈EëëGöEü€ÇEðt: Uüë5EPèHöEü Yt f‹Mìf‰ë‹Mì‰ÇEÈé=ƒMü@ÇEð öEý€t EPèYëAöEü t!öEü@EPt èõY¿À™ë%èéY·ÀëòöEü@EPtèÔYëàèÌY3ÒöEü@t…Ò|…Às÷؃҉Eà÷Ú€Mý‰Uäë‰Eà‰UäöEý€uƒeäƒ}ø} ÇEøëƒeü÷¸9Eø~‰Eø‹Eà EäuƒeÜE³‰Eô‹EøÿMø…À‹Eà Eät?‹Eð™‹ú‹ðWVÿuäÿuàèRWVÿu䋨ƒÃ0ÿuàèЃû9‰Eà‰Uä~]Ì‹EôÿMôˆë¯E³+EôÿEôöEý‰Eðt‹Mô€90u…Àu ÿMô@‹MôÆ0‰Eðƒ}È…ô‹]üöÃ@t&öÇtÆEê-ëöÃtÆEê+ë öÃt ÆEê ÇEÜ‹uØ+uÜ+uðöà uEìPÿuVj è*ƒÄEìPEêÿuÿuÜPèEƒÄöÃtöÃuEìPÿuVj0èøƒÄƒ}ÔtAƒ}ð~;‹Eð‹]ôxÿf‹CPE¼PCèY…ÀY~2MìQÿuPE¼PèëƒÄ‹ÇO…ÀuÐëEìPÿuÿuðÿuôè̓ÄöEütEìPÿuVj 脃ă}Ðt ÿuÐèÒÿÿƒeÐY‹u ŠF„Û‰u …¾øÿÿ‹Eì_^[ÉÃsâqÿqKr‚r‹rÃrWsU‹ì‹M ÿIx‹ŠEˆÿ¶Àë QÿuèÝ YYƒøÿ‹Euƒÿ]Ãÿ]ÃVW‹|$‹ÇO…À~!‹t$Vÿt$ÿt$è¬ÿÿÿƒÄ ƒ>ÿt‹ÇO…Àã_^ÃS‹\$ ‹ÃKVW…À~&‹|$‹t$¾WFÿt$PèuÿÿÿƒÄ ƒ?ÿt‹ÃK…Àâ_^[ËD$ƒ‹‹@üËD$ƒ‹‹Aø‹QüËD$ƒ‹f‹@üÃU‹ìƒìHSVWh€èÒÑÿÿ‹ðY…öujè¨ÞÿÿY‰5€ Ç€  †€;ðs€fƒÿƒfÆF ¡€ ƒÆ$€ëÞE¸PÿÀ°fƒ}ê„Ñ‹Eì…À„Æ‹8X;‰Eü¸;ø|‹ø9=€ }V¾„ h€è>Ñÿÿ…ÀYt<ƒ€  ‰ˆ€;Ás€`ƒÿƒ`Æ@ ‹ƒÀ$Á€ëàƒÆ9=€ |·ë‹=€ 3ö…ÿ~L‹Eü‹ƒùÿt8Ѝt2¨u Qÿ¼°…Àt#‹Î‹ÆÁùƒà‹ € À‹Mü‹ ‰Š ˆHƒEüFC;÷|´3Û‹ € Ûƒ<ÿ4uM…ÛÆFujöXë ‹ÃH÷ØÀƒÀõPÿ¸°‹øƒÿÿtWÿ¼°…Àt %ÿ‰>ƒøu€N@ëƒøu €Në€N€Cƒû|—ÿ5€ ÿ´°_^[ÉÃSVW¾€ ‹…Àt7‹ø€;øs!_ ƒ{ütSÿ¬°‹ƒÇ$€ƒÃ$;ørâÿ6èÿÎÿÿƒ&YƒÆþ€ |¸_^[ÃSWj3Ûè€òÿÿYj_9=à~]V¡Ä ‹÷Áæ‹…ÀtAö@ ƒt PèƒøÿYtCƒÿ|)¡Ä ‹ƒÀ Pÿ¬°¡Ä ÿ4èŒÎÿÿ¡Ä Yƒ$G;=à|¥^jèqòÿÿY‹Ã_[ÃV‹t$Vè#…ÀYtƒÈÿ^ÃöF @tÿvè(÷ØY^ÀÃ3À^ÃSV‹t$ 3ÛW‹F ‹Èƒá€ùu7f©t1‹F‹>+ø…ÿ~&WPÿvèQƒÄ ;Çu‹F ¨€t$ý‰F ëƒN ƒËÿ‹Fƒf‰_‹Ã^[ÃjèYÃSVWj3Û3ÿèiñÿÿ3öY95à~t¡Ä ‹°…Àt_ö@ ƒtYPVè©Çÿÿ¡Ä YY‹°‹H öÁƒt0ƒ|$uPèÿÿÿƒøÿYtCëƒ|$uöÁtPèÿÿÿƒøÿYu ø¡Ä ÿ4°Vè«ÇÿÿYYF;5à|ŒjèDñÿÿƒ|$Y‹Ãt‹Ç_^[ÃÌÌU‹ìWV‹u ‹M‹}‹Á‹ÑÆ;þv;ø‚x÷ÇuÁéƒâƒùr)ó¥ÿ$•Ø~‹Çºƒér ƒàÈÿ$…ð}ÿ$è~ÿ$l~~,~P~#ÑŠˆŠFˆGŠFÁéˆGƒÆƒÇƒùrÌó¥ÿ$•Ø~I#ÑŠˆŠFÁéˆGƒÆƒÇƒùr¦ó¥ÿ$•Ø~#ÑŠˆFÁéGƒùrŒó¥ÿ$•Ø~IÏ~¼~´~¬~¤~œ~”~Œ~‹DŽä‰Dä‹DŽè‰Dè‹DŽì‰Dì‹DŽð‰Dð‹DŽô‰Dô‹DŽø‰Dø‹DŽü‰Düðøÿ$•Ø~‹ÿè~ð~ü~‹E^_Éʈ‹E^_ÉʈŠFˆG‹E^_ÉÃIŠˆŠFˆGŠFˆG‹E^_ÉÃt1ü|9ü÷Çu$Áéƒâƒùr ýó¥üÿ$•p€‹ÿ÷Ùÿ$ €I‹Çºƒùr ƒà+Èÿ$…xÿ$p€ˆ¨ÐŠF#шGNÁéOƒùr¶ýó¥üÿ$•p€IŠF#шGŠFÁéˆGƒîƒïƒùrŒýó¥üÿ$•p€ŠF#шGŠFˆGŠFÁéˆGƒîƒïƒù‚Zÿÿÿýó¥üÿ$•p€I$€,€4€<€D€L€T€g€‹DމD‹DމD‹DމD‹DމD‹DŽ ‰D ‹DމD‹DމDðøÿ$•p€‹ÿ€€ˆ€˜€¬€‹E^_ÉÊFˆG‹E^_ÉÃIŠFˆGŠFˆG‹E^_ÉÊFˆGŠFˆGŠFˆG‹E^_ÉËL$V; € WsX‹ÁÁø<…€ ‹Áƒà4À‹ÁæÆö@t7ƒ8ÿt2ƒ=@u3À+ÈtItIuPjôëPjõëPjöÿİ‹ƒ 0ÿ3ÀëèÑÿÿÇ èÑÿÿƒ ƒÈÿ_^ËD$;€ s‹ÈƒàÁùÀ‹ € öDt‹ÃèÀÐÿÿÇ è¾Ðÿÿƒ ƒÈÿËD$S‹ÈƒàÁùVW‹4€ € <ÀÁç÷ƒ~u#jè©ìÿÿƒ~Yu F Pÿ¨°ÿFjèïìÿÿY‹D8 Pÿ`°_^[ËD$‹ÈƒàÁùÀ‹ € D Pÿd°ÃV‹t$;5€ s@‹Î‹ÆÁùƒà‹ € ÀöDt%WVèPÿÿÿÿt$ÿt$Vè(V‹øè™ÿÿÿƒÄ‹Ç_^ÃèÛÏÿÿÇ èÙÏÿÿƒ ƒÈÿ^ÃU‹ììSVW3ÿ9}‰}ø‰}ðu3Àéf‹EÁø…€ ‹Eƒà4À‹ÁæöD0 tjWÿuèáƒÄ ‹Æö@€„Á‹E 9}‰Eü‰}†ê…ìûÿÿ‹Mü+M ;Ms)‹MüÿEüŠ €ù uÿEðÆ @ˆ@‹È•ìûÿÿ+Êù|Ì‹ø…ìûÿÿ+øEôjP…ìûÿÿWP‹ÿ40ÿȰ…ÀtC‹EôEø;Ç| ‹Eü+E ;ErŠ3ÿ‹Eø;Ç…9}tbj^9uuLèÃÎÿÿÇ èÁÎÿÿ‰0ëAÿT°‰EëÇMôWQÿuÿu ÿ0ÿȰ…Àt ‹Eô‰}‰Eøë§ÿT°‰EëœÿuèÎÿÿYƒÈÿë,‹öD0@t ‹E €8„ªþÿÿèTÎÿÿÇèRÎÿÿ‰8ëÒ+Eð_^[ÉÃÌÌÌÌÌÌÌÌÌ‹L$÷ÁtŠA„Àt@÷Áuñ‹ºÿþþ~Ѓðÿ3ƒÁ©tè‹Aü„Àt2„ät$©ÿt©ÿtëÍAÿ‹L$+ÁÃAþ‹L$+ÁÃAý‹L$+ÁÃAü‹L$+ÁÃÌÌÌÌÌW‹|$ëj¤$‹ÿ‹L$W÷ÁtŠA„Àt;÷Áuñ‹ºÿþþ~Ѓðÿ3ƒÁ©tè‹Aü„Àt#„ät©ÿt©ÿtëÍyÿë yþëyýëyü‹L$ ÷ÁtŠA„ÒtdˆG÷Áuî뉃Ǻÿþþ~‹Ѓðÿ3‹ƒÁ©tá„Òt4„öt'÷Âÿt÷Âÿtëlj‹D$_Ãf‰‹D$ÆG_Ãf‰‹D$_È‹D$_ÃVèVèÿÿÿаƒøÿ£Pût:jtjèÒ¼ÿÿ‹ðY…öYt)Vÿ5Pûÿ̰…ÀtVè4Yÿ¤°ƒNÿj‰X^Ã3À^Ãè,èÿÿ¡PûƒøÿtPÿÔ°ƒ PûÿËD$Ç@PýÇ@ÃVWÿT°ÿ5Pû‹øÿܰ‹ð…öu?jtjèG¼ÿÿ‹ðY…öYt&Vÿ5Pûÿ̰…ÀtVè©ÿÿÿYÿ¤°ƒNÿ‰ëjè@ÒÿÿYWÿذ‹Æ_^áPûƒøÿ„‘V‹t$…öu Pÿܰ‹ð…ötl‹F$…ÀtPè5ÄÿÿY‹F(…ÀtPè'ÄÿÿY‹F0…ÀtPèÄÿÿY‹F8…ÀtPè ÄÿÿY‹F@…ÀtPèýÃÿÿY‹FD…ÀtPèïÃÿÿY‹FP=ýtPèÞÃÿÿYVè×ÃÿÿYjÿ5Pûÿ̰^ÃU‹ìSV‹u ‹F ‹^¨‚„ö¨@…î¨tƒf¨„Þ‹N$þ‰‰F ‹F ƒfƒe $ï f© ‰F u"þpÓtþÓu Sèæ …ÀYuVè Yf÷F Wtg‹F‹>+øH‰‹NI…ÿ‰N~WPSèqúÿÿƒÄ ‰E ë6ƒûÿt‹Ë‹ÃÁùƒà‹ € Àë¸`úö@ t jjSèd ƒÄ ‹FŠMˆëjE_WPSèúÿÿƒÄ ‰E 9} _tƒN ë‹E%ÿë ‰F ƒÈÿ^[]ËL$fƒ9At f‹@@f…Òuö+ÁÑøHÃU‹ìjÿhøµhÐod¡Pd‰%ƒìSVW‰eè¡ä3Û;Ãu>EäPj^VhðµVÿè°…Àt‹ÆëEäPVhìµVSÿä°…À„ÎjX£äƒøu$‹E;Ãu¡Ìÿuÿuÿu ÿuPÿä°韃ø…”9]u¡Ü‰ESSÿuÿu ‹E ÷ØÀƒà@Pÿuÿà°‰Eà;Ãtc‰]ü<‹ÇƒÀ$üè+Èÿÿ‰eè‹ô‰uÜWSVè;ÒÿÿƒÄ ë jXËeè3Û3öƒMüÿ;ót)ÿuàVÿuÿu jÿuÿà°;ÃtÿuPVÿuÿè°ë3ÀeÌ‹Mðd‰ _^[ÉÃÌÌÌÌÌÌ‹D$‹L$ È‹L$ u ‹D$÷áÂS÷á‹Ø‹D$÷d$Ø‹D$÷áÓ[ÂS3Û9Ìu‹D$ƒøa|YƒøzTƒè [ÃV¾l WVÿ€°9h ‹=|°tVÿ×jèiäÿÿYj[ÿt$è…ÛY‰D$t jè­äÿÿYëVÿ׋D$_^[ÃU‹ìQƒ=ÌSu‹EƒøaŒ¯ƒøz¦ƒè éž‹]û}(ƒ=LÙ~ jSèäÈÿÿYYë ¡@׊Xƒà…Àu‹Ãëk‹@׋ÃÁø¶ÈöDJ€t€e ˆEˆ] jë €e ˆ]jXMüjjjQPEPhÿ5Ìè ƒÄ …Àt©ƒøu¶Eüë ¶Eý¶MüÁà Á[ÉÃS3Û9´ VWuè‹543ÿŠ:Ãt<=tGVèæøÿÿYtëè½Pè}Àÿÿ‹ðY;ó‰5 uj èMÍÿÿY‹=48t9UWè¬øÿÿ‹èYE€?=t"UèHÀÿÿ;ÃY‰uj èÍÿÿYWÿ6èùÿÿYƒÆYý8uÉ]ÿ54è1¿ÿÿY‰4‰_^ǰ [ÃU‹ìQQS3Û9´ VWuèÒ¾èhVSÿ°¡¨ ‰5‹þ8t‹øEøPEüPSSWèM‹Eø‹MüˆP訿ÿÿ‹ðƒÄ;óujè|ÌÿÿYEøPEüP‹Eü†PVWè‹EüƒÄH‰5_^£[ÉÃU‹ì‹M‹ESVƒ!‹uW‹} Ç‹E…ÿt‰7ƒÇ‰} €8"uDŠP@€ú"t)„Òt%¶Òö‚a t ÿ…ötŠˆF@ÿ…ötÕŠˆFëÎÿ…öt€&F€8"uF@ëCÿ…ötŠˆFŠ@¶Úöƒa t ÿ…ötŠˆF@€ú t „Òt €ú uÌ„ÒuHë…öt€fÿƒe€8„àŠ€ú t€ú u@ëñ€8„È…ÿt‰7ƒÇ‰} ‹UÿÇE3Û€8\u@Cë÷€8"u,öÃu%3ÿ9}t €x"Pu‹Âë‰}‹} 3Ò9U”‰UÑë‹ÓK…ÒtC…ötÆ\FÿKuóŠ„ÒtJƒ}u €ú t?€ú t:ƒ}t.…öt¶Úöƒa tˆF@ÿŠˆFë¶Òö‚a t@ÿÿ@éXÿÿÿ…öt€&Fÿéÿÿÿ…ÿtƒ'‹E_^[ÿ]ÃQQ¡ìSU‹- °VW3Û3ö3ÿ;Ãu3ÿÕ‹ð;ót Çìë(ÿœ°‹ø;û„êÇìéƒø…;óu ÿÕ‹ð;ó„Âf9‹Æt@@f9uù@@f9uò+Æ‹=„°ÑøSS@SSPVSS‰D$4ÿ׋è;ët2Uè½ÿÿ;ÃY‰D$t#SSUPÿt$$VSSÿ×…Àuÿt$è ¼ÿÿY‰\$‹\$Vÿð°‹ÃëSƒøuL;ûu ÿœ°‹ø;ût<8‹Çt @8uû@8uö+Ç@‹èU讼ÿÿ‹ðY;óu3öë UWVè€îÿÿƒÄ Wÿì°‹Æë3À_^][YYÃjX ¡<ƒøt …Àu*ƒ=@u!hüè¡ðY…ÀtÿÐhÿèYÃU‹ì줋U3ɸ`ü;t ƒÀA=ðürñV‹ñÁæ;–`ü…¡<ƒø„è…Àu ƒ=@„×úü„ñ…\þÿÿhPjÿ°…Àu…\þÿÿhܸPè’ôÿÿYY…\þÿÿWP½\þÿÿèýóÿÿ@Yƒø ÿÿÿÿõBÿÿÿÿ~Cÿÿÿÿ‹HÿÿÿÿÛI: ÿÿÿÿ,Kÿÿÿÿ„KÿÿÿÿPLÿÿÿÿ¬L__GLOBAL_HEAP_SELECTED__MSVCRT_HEAP_SELECTEEE50P (8PX700WP `h````ppxxxx(null)(null)Illegal byte sequenceDirectory not emptyFunction not implementedNo locks availableFilename too longResource deadlock avoidedResult too largeDomain errorBroken pipeToo many linksRead-only file systemInvalid seekNo space left on deviceFile too largeInappropriate I/O control operationToo many open filesToo many open files in systemInvalid argumentIs a directoryNot a directoryNo such deviceImproper linkFile existsResource deviceUnknown errorBad addressPermission deniedNot enough spaceResource temporarily unavailableNo child processesBad file descriptorExec format errorArg list too longNo such device or addressInput/output errorInterrupted function callNo such processNo such file or directoryOperation not permittedNo errorÿÿÿÿ*‰.‰runtime error TLOSS error SING error DOMAIN error R6028 - unable to initialize heap R6027 - not enough space for lowio initialization R6026 - not enough space for stdio initialization R6025 - pure virtual function call R6024 - not enough space for _onexit/atexit table R6019 - unable to open console device R6018 - unexpected heap error R6017 - unexpected multithread lock error R6016 - not enough space for thread data abnormal program termination R6009 - not enough space for environment R6008 - not enough space for arguments R6002 - floating point not loaded Microsoft Visual C++ Runtime Library Runtime Error! Program: ...ÿÿÿÿz˜~˜ÿÿÿÿ.™2™GetLastActivePopupGetActiveWindowMessageBoxAuser32.dllH:mm:ssdddd, MMMM dd, yyyyM/d/yyPMAMDecemberNovemberOctoberSeptemberAugustJulyJuneAprilMarchFebruaryJanuaryDecNovOctSepAugJulJunMayAprMarFebJanSaturdayFridayThursdayWednesdayTuesdayMondaySundaySatFriThuWedTueMonSunSunMonTueWedThuFriSatJanFebMarAprMayJunJulAugSepOctNovDecp¼°¼H±@¼˜½± ¼¤½ø°@»Þ½°(»H¾°8¾$¾ ¾þ½ì½Ž¿ª¿¸¿ØÁÆÁèÁ°Á ÁºÁœ¿„ÁrÁ^Á°½À½Î½ÁV¾b¾z¾’¾ ¾¬¾º¾Î¾â¾ú¾¿(¿:¿N¿d¿~¿,ÁDÁfÀÈ¿ä¿ü¿ÀÀ*À8ÀJÀZÀ|ÀŠÀ–À À°À¾ÀÔÀæÀøÀÁ€€ €4€3€€ €º¼Ò¼â¼½X½€½l½½D½0½ò¼Œ¼ž¼€¼+pcap_next2pcap_open_live'pcap_lookupnetwpcap.dllPacketGetAdapterNamesPacketRequestPacketSetBuffPacketGetNetTypePacketOpenAdapterPacketCloseAdapterPacketSetHwFilterPacketFreePacketPacketSendPacket PacketInitPacketPacketAllocatePacketpacket.dllWS2_32.dllmGetTickCounttGetVersionGetLastErrorKERNEL32.dll_CryptGenRandom^CryptGenKeyNCryptAcquireContextA{RegQueryValueExArRegOpenKeyExAADVAPI32.dll™HeapAllocfEnterCriticalSectionÁLeaveCriticalSection¢HeapReAllocŸHeapFree}ExitProcessžTerminateProcess÷GetCurrentProcess­InterlockedDecrement°InterlockedIncrementÒWideCharToMultiByteÊGetCommandLineA&GetModuleHandleA$GetModuleFileNameA GetEnvironmentVariableAuGetVersionExAHeapDestroy›HeapCreate¿VirtualFree»VirtualAllocªInitializeCriticalSectionUDeleteCriticalSection/RtlUnwindmSetHandleCountRGetStdHandleGetFileTypePGetStartupInfoA|SetStdHandleßWriteFileúGetCurrentThreadId¥TlsSetValue¢TlsAlloc£TlsFreeqSetLastError¤TlsGetValueäMultiByteToWideCharSGetStringTypeAVGetStringTypeW²FreeEnvironmentStringsA³FreeEnvironmentStringsWGetEnvironmentStringsGetEnvironmentStringsWªFlushFileBuffersjSetFilePointer¿GetCPInfo¿LCMapStringAÀLCMapStringW¹GetACP1GetOEMCP>GetProcAddressÂLoadLibraryACloseHandle@ÀBCäÄFF(Â@ÃXÄ0Ðpà°P  €Ð€` ° ðPP P P P P P P P P P ` !à!p"p0`=p1Ð2@#€(0&°-p:P70) 89ð" 1 1€+P,&9P2€.À<À5@673P5`@7à)€=À0p(ñÄÅÅ7ÅMÅfÅ}ŕŰÅÉÅàÅñÅÆÆ5ÆPÆmƉƣƵÆÅÆ×ÆéÆÿÆÇ-ÇFÇ`ÇzǔǪÇÀÇÑÇâÇóÇÈ!È7ÈMÈiÈ|ȉÈȯÈÁÈÒÈèÈøÈ É É0ÉCÉ\ÉnÉɑɥÉÃÉÞÉóÉ Ê*ÊBÊYÊvÊʢʷÊÇÊßÊ  !"#$%&'()*+,-./0123456789:;<=>?@ABCDELibNetNT.dlllibnet_build_arplibnet_build_asn1_bitstringlibnet_build_asn1_headerlibnet_build_asn1_intlibnet_build_asn1_lengthlibnet_build_asn1_nulllibnet_build_asn1_objidlibnet_build_asn1_sequencelibnet_build_asn1_stringlibnet_build_asn1_uintlibnet_build_dnslibnet_build_ethernetlibnet_build_icmp_echolibnet_build_icmp_masklibnet_build_icmp_redirectlibnet_build_icmp_timeexceedlibnet_build_icmp_timestamplibnet_build_icmp_unreachlibnet_build_igmplibnet_build_iplibnet_build_ipv4libnet_build_ospflibnet_build_ospf_dbdlibnet_build_ospf_hellolibnet_build_ospf_lsalibnet_build_ospf_lsa_aslibnet_build_ospf_lsa_netlibnet_build_ospf_lsa_rtrlibnet_build_ospf_lsa_sumlibnet_build_ospf_lsrlibnet_build_ospf_lsulibnet_build_riplibnet_build_tcplibnet_build_udplibnet_build_vrrplibnet_close_link_interfacelibnet_close_raw_socklibnet_destroy_packetlibnet_destroy_packet_arenalibnet_do_checksumlibnet_errorlibnet_get_checksumlibnet_get_hwaddrlibnet_get_ipaddrlibnet_get_prandlibnet_get_remote_maclibnet_hex_dumplibnet_host_lookuplibnet_host_lookup_rlibnet_in_cksumlibnet_init_packetlibnet_init_packet_arenalibnet_insert_ipolibnet_insert_tcpolibnet_ip_checklibnet_name_resolvelibnet_next_packet_from_arenalibnet_open_link_interfacelibnet_open_raw_socklibnet_plist_chain_dumplibnet_plist_chain_dump_stringlibnet_plist_chain_freelibnet_plist_chain_newlibnet_plist_chain_next_pairlibnet_reset_arp_databaselibnet_seed_prandlibnet_select_devicelibnet_write_iplibnet_write_link_layerll_strerrorÚC‘‚Dÿÿÿÿÿÿlibnet_get_remote_mac : link interface is not opened libnet_write_link_layer choked pcap_open_live: %s libnet_init_packet memory:%sWarning: Critical: Fatal: %02x %04x %02x Unable to retrieve the list of the adapters! malloc: %sUnable to open the driver, Error Code : %lx Cannot determine the network type Error:failed to allocate the LPPACKET structure.,0123456789,- %d-%d %d %d-%d%d%d.%d.%d.%dError while getting default gateway from registry Error while getting own IP from registry DefaultGatewayIPaddressDhcpDefaultGatewayDhcpIPaddressEnableDHCPParameters\TcpipSYSTEM\CurrentControlSet\Services failed to select device libnet_do_checksum failed libnet_win32_get_remote_mac failed à à         ! 5A CPR S WY l m pr € ‚ ƒ„ ‘)ž ¡¤ § ·Î×  J×J× ((((( H„„„„„„„„„„‚‚‚‚‚‚ .sM`Ù`ÙxÙxÙÿÿÿÿÿÿÿÿðñ`ÙàP€˜h “¬²œ²ÿÿÿÿ àµȵ¬µœµ€µlµPµ<µ(µµµÜ´È´´´¨´˜´ˆ´|´l´\´L´<´(´´ô³г˜´À³¨³˜³€³p³d³T³@³˜´$³˜´³ü²à²̲´²˜´+ÿÿÿÿCCCh¸<¸ ¸ ì·À··l·@··à¶¨¶p¶H¶x8¶y(¶z¶ü¶ÿ¶6ž6ž6ž6ž6ž6žÀ À–ÀÀŽÀÀÀ‘À’À“Àx ¤`‚y‚!¦ß¡¥Ÿàü@~€ü¨Á£Ú£ þ@þµÁ£Ú£ þAþ¶Ï¢ä¢å¢è¢[þ@~¡þQQÚ^Ú _ÚjÚ2ÓØÞàù1~þ þlºhºdº`º\ºXºTºLºDº<º0º$ººº ººººü¹ø¹ô¹ð¹ì¹è¹ä¹à¹ع̹Ĺ¼¹ü¹´¹¬¹¤¹˜¹¹„¹x¹t¹p¹h¹T¹L¹.PÿtttttttttXÿ€pðñÿÿPSTPDTœÿÜÿÿÿÿÿÿÿÿÿÿÿÿÿ;Zx—µÔó0Nmÿÿÿÿ:Yw–´Óò/MlL43”3˜3œ3 3¤3L4;5@5ì5(6Y6°6ù67È7/8p8u8¥8Ì89 9H9#:ë:¿;3<³<Ú<Ó=õ=Œ>¯? tƒ0±0;1U1û1p3–3`4Ü5à5ä5è5ì5ð5ô5S6Z6†6Î6Ü7à7ä7è7ì7ð7ô7ø7´8»8Â8Ç8Ù8Þ8 9>9\9q9«9¾9Ì9:8:—;7<’<Š=¾=Ù=_>j>®>?g?†?000D0H0L0P0T0X0\0`0d0Í033 323È3Ð3Ö3ð34 44!4s4‘4ú4V5â5ç5666!6Œ6­6È6b7y7‹7›788 8888#8C8M8e8l8™8ª8Â8É8ß8ö8ý8,9`9¥9¹9ë9 :i:´:,;<;;—;¸;Õ;Ú;á;æ;<:<‰<©<×<ÿ<(=a=p=ž=´=¼=ú=ÿ=>B>H>N>T>Z>`>f>l>r>x>~>„>Š>>Ø>ð>÷>ÿ>?? ?5?[?u?|?€?„?ˆ?Œ??”?˜?â?è?ì?ð?ô?@øZ0e0€0‡0Œ00”0±0Û0 1111 1$1(1,101z1€1„1ˆ1Œ1g2l2¹2Ç2 3S3Y3g3Û3õ34440464D4M4^4z4‰4›4¤4À4ã4í4ö455577V7Ž7ü78S8Y8m8÷8d9j9¥9«9Ä9: ::`:€::—:¬:È:Í:ñ:’;˜;­;ï;ô; <>,>2>»>Ã>É>Ñ>=?r?Ÿ?¥?Î?â?PØ 0#030t0˜0ž0ó0Ð1Ý12b3q3Í3è34%4.5F5ë566-6(7/7>7F7Q7W7]7g77„7Ž7¨7¶7¾7Ä788u88Ÿ8»8Ã8é8+9Z9`9™9À9e:l:{:ž:¤:°:À:Ç:Î:Ô:û:;;;';>;J;P;Á;Ç;Î;Û;â;ê;ð;ö;< g>m>‡>Œ>›>¡>±>¼>Î>á>ì>ò>÷>ý> ?'?-?8?=?F?K?[?a?¥?`°K082C2K2^2d2z22‡2‘2—2œ2¢2²2»2Õ2æ2ì2ÿ2a37 77"727i7s7{77‰7’7›7!8'82888T8Z8d8j8„8Š8’8¡8Ù8æ8F9`9á9ç9:·:Ä:Ó:4;‰;Ú;Ï=Õ=Ý=å=í=ù=þ= >>>">8>@>H>P>X>k>s> >»>Ë>Ñ>ä>%?Ž?¨?±?p¸¼0È0Ó0â0ì0¹1È1Þ13Ï3Ù4Q5l5}5é5Ý8á8å8é8í8ñ8õ8ù8ê9ð9:&:X:_:t:¦:°:Ñ:æ: ;4;B;s;y;†;§;Ì;ç;ï;<%<*<7K>e>l>p>t>x>|>€>„>ˆ>Ò>Ø>Ü>à>ä>J?U?p?w?|?€?„?¡?Ë?ý?€ô00 00000 0j0p0t0x0|0Ì0Û0û01J1^1˜1Ÿ1Å1Ý1÷122!2•253‚3š3¯3x5€5š5 5±5Ê5Ö5Ü5é5ù5ÿ56%6+6<6S6]6v6Ø6ð6ö6N7V7°7½778<8X8k8r8„8Œ8œ8­8À8Ø8ø8N9`9¹9Ô9Ü9â9è9):[:o:ƒ:Ä:ô:;5;E;ˆ;”;ž;²;À;Í;Ò;Ø;3<:<‚<Ç<ª=Ã=ø=>>&>6>u>Å>Ø>?.?=?O?u?‚??›?®?Õ?ä?ü&0:0X0d0€0•0«0²0N2e2w22…22Ø2ý233©4¹4ë4õ4<5O5Æ5Ó5ø56p7u7”7¡7®7¸7Â7Ê7Ø7ö78+8K8£8¹8ì8T9y9Ö9ò9ÿ9 ::(:4:f:x:‡:¨:®:Ï:Ù:ä:é:ñ:;;#;+;3;>;l;x;‚;;—;¡;§;ê;ô;ù;þ;<<"<‘<—<µ<Æ<Ù<î< =='=7=X=d=v=„=“=¤=²=»=Á=Í=Ò=Ü=ã=ë=ñ=ø=ý=>*>F>Y>Ø>â>þ>^?¦?¬?º?  090”0š0¨01'1_1q1„1À1"2°$°1¼1È1Ô1è1ô12 2ü56ü899 9Ð 000P3X3@7D7X9`9d9h9l9ð €9Œ9¬9¼9Ì9X:\::”:˜:œ: :¤:¨:¬:°:´:¸:¼:À:Ä:È:Ì:Ð:Ô:Ø:Ü:à:ä:è:ì:ð:ô:ø:ü:;;; ;;;;; ;$;(;,;0;4;8;<;d >¤>¨>¬>°>´>¸>¼>À>Ä>È>Ì>Ð>Ô>Ø>Ü>à>ä>è>ì>ð>ô>ø>ü>??? ????? ?$?(?,?0?4?8?@ƒÀƒùR‰D$t$@3ɉD$Šö@Òt@3Ò‰D$Šö‚@Òuî€8)…ª‹t$ŠHƒÆ€ù+‰t$t€ù*t€ù?t €ù{…Ðûÿÿ‹L$‹¬$pƒÁ¾ ‰L$é&ƒÀ3ɉD$Šö@Òt@3Ò‰D$Šö‚@Òuî€8)…eƒD$é{ûÿÿƒÀ‰D$Š€ù…t‹|$0‹È+Ê‹T$,G;ʉ|$0Ž1‰L$,é(€ù=t €ù>…‹t$X@3Ò‰D$Šö2t@3ɉD$Šö1uñ€8)…éê½ʼnD$Š€ù=t €ù!…%l$éÆŠH€ùRu€x)u‹L$ƒÀƒÁ‰L$é¥áÿö@Òt?‹T$ƒÀƒÂ‰D$‰T$3ÒŠö‚@Òt@3ɉD$Šö@Òuî€8)…ÞéW@‰D$€x?…öŠH€ù=„<€ù!„3€ù<…Øé%3ɃÀ‰L$D‰L$@L$@3Ò‰D$Š‹úw׃þO‡Û3ÒŠ–l*ÿ$•D*‹ƒÊ@‰ëÑ‹ƒÊ@‰ëÇ‹ƒÊ@‰뽋ƒÊ@‰볋ƒÊ@@‰ë©‹€Î@‰ëŸL$D@똋L$8…Éu*‹L$@‹”$l Ê‹T$D÷Ò#ÊÇD$8ÿÿÿÿ‰Œ$l3É3Òë‹T$@‹L$D ÊöÁt ‹t$½ƒÆöÁ‰t$t Œ$lƒÿ)uFƒý…/ùÿÿ‹L$$…Ét ƒù…ùÿÿƒD$$éùÿÿ‹Œ$löÅu‹L$ Aù–‰L$ ~»‹t$4þȃùŠL$$‰l$$ˆL4|‹L$‰Œ´DFˉt$4‰L$黸ÿÿ‹T$ƒÂ…ÿ‰T$v‹Œ¼@O‹ò‰|$4+ñ3ÉŠL<|‰L$$ë3ö3ÉŠHƒù{udƒÀPè¬ ƒÄ…À„æ‹L$T$UD$ RƒÁPQè) ‹MƒÄ…ɉD$… ‹T$‹L$…ÒuO‹|$G…ɉ|$~hƒÆI¯ñ‹ÏÎëWƒù*uƒÉÿ@ÇD$‰L$‰D$ë˃ù+uVƒÉÿº@‰T$‰L$‰D$zÿ‹\$¯þß;ʉ\$~+ʃƯ΋ÓL ú‰L$€x+…»÷ÿÿ‹L$@ƒÁ‰L$éª÷ÿÿƒù?u¹@ÇD$‰L$‰D$éPÿÿÿ‹D$º‹Ê‰T$‰L$늋D$‹L$‹T$X‹¬$p‹\$(ƒÁ3ÿ‰L$…Ûtƒþ\u{€xEuu3Û@‰\$(ëm‹Œ$löÁt,öu[ƒþ#u!@3ɉD$Š…ÉtIƒù tD@3ɉD$Š…Éuîë5ƒþ\u/‹T$ j‹ðQRD$ UPè ‹MƒÄ…É…ž…À|'‹T$X‹D$Gÿú}!@3ɉD$Š‹ñö€ué]ÿÿÿ‹Æÿú}H|$éžöÿÿ‹Œ$h_+Á‹Œ$pÇE û^‰]3À[ÄTËŒ$p_^]Ljû‹Œ$\+Á‹Œ$h[‰3ÀÄTËŒ$h‹”$p+Á‹Œ$t_Ç`û^‰]3À[ÄTËŒ$p_^]ÇDû‹Œ$\+Á‹Œ$h[‰3ÀÄTËŒ$p_^]Ç û‹Œ$\+Á‹Œ$h[‰3ÀÄTËŒ$h‹”$p+Á‹Œ$t_Çû^‰]3À[ÄTËŒ$p_^]Çäú‹Œ$\+Á‹Œ$h[‰3ÀÄTËŒ$h‹”$p+Á‹Œ$t_ÇÈú^‰]3À[ÄTËŒ$pƒÀ_^Ǩú‹Œ$`+Á‹Œ$l][‰3ÀÄTËŒ$h‹”$p+Á‹Œ$t_Ljú^‰]3À[ÄTËŒ$p_^]Çhú‹Œ$\+Á‹Œ$h[‰3ÀÄTˬ$p‹D$ƒÀ=‰D$~_ÇEHú^]3À[ÄTË\$,‹D${‹×¯T$0lUÿõ‹ðƒÄ…öu‹Œ$p_^]Ç0ú[ÄTËŒ$l‹”$xf‹D$0ƒÃÇERCP‰n‰N ‰Vf‰^f‰F3Ò‰|$hF3ÿ3Û‰T$d‰D$`f‹~f‹^‹¬$p¯ûø‹„$h‰D$D$LPD$|RPD$T‰|$h‰”$€‰|$HPÆLR‰T$4RT$,UD$XRP‹ÁT$DƒàRPQènf‹L$PƒÄ0f‰Nf‹T$lf‰V‹E…Àu‹D$€8tÇEú‹L$<Æ‹D$<‹L$@‰D$<+Ç;Á~ÇEøùf‹Vf;VvÇEÐùƒ}t-VÿõƒÄ‹D$‹Œ$h_+Á‹Œ$p^]‰3À[ÄTË„$l¨…‹T$p‰D$,RD$0jPWèH(ƒÄ…Àt‹F ëf‹D$H…À}L$,jQWèÅ)ƒÄ ‰D$H…À|*‹ÈáÿöÄt‹|$P3ÒŠ9;Ñu‹Áf‰F‹F @ë‹D$pPjWèÃ(ƒÄ …Àt ‹F ‰F ‹D$x…À|7‹V öÂtöÄt*‹ÈáÿöÄt‹|$P3ÛŠ9;Ùu€äþÊ f‰F‰V ‹Æ_^][ÄTÃn ä"wPL€;.$Ig<ç pà ë$ oˆ!‹ÿ"ú!3"ð!æ!¾!È!Ò!Ü!Š&        SU‹l$ 3ÀVW‹MAŠ…Àu‹T$_^Ç´ü‰M][Ãø0ŒsƒøzjpпuðÐ…Òt _‰M^]‹Â[ÃþH‡73ÒŠ–„,ÿ$•l,‹T$_^Ç|ü‰M][ËD$$…Àu;3À‹ÖŠA‹ù‹ð°„†@ÒtA3Û’ŠTSÐ3ÛŠY„ƒ@Òuçƒú |;T$~‹Ï3ÀŠƒø8|I_‰M^]3À[Ã_¸ïÿÿÿ‰M^]+Â[Ãè0¾ŠQ€ú0r€ú7wA3ÒŠDÂЋÖFƒú|â_‰M^]%ÿ[Ã3À¿²3ÛŠY„“@ÒtxA3ÛŠ‹óƒþa|ƒî 3ÛƒþAÃKƒãùƒÃ7Áà+ÃÆ‹÷Gƒþ|Æ_‰M^][ÃA3ÀŠ…Àu‹D$_^]Çdü3À[Ãøa|ƒøzƒè _‰M^]ƒð@[ÃöD$ @t ‹T$Ç@ü_‰M^][Ëÿ¡+;+)+,Ô+Q,‹D$3ÉSŠ@Š‘@Ò„Òu3À[Ã3ÒŠ‹Ê²„‘@Òt @3ÉŠ„‘@ÒuóŠ€ù}u¸[Ã@€ù,t3À[Ê€ù}u¸[Ãáÿ@Š™@Ò„Ûu3À[Ã3ÉŠ„‘@Òt @3ÉŠ„‘@ÒuóŠ3Ò€ù}[”‹ÂËD$3ÉSVг3öƒÊÿ„™@Òt4¶@tqÐ3ÉŠ„™@Òuì€8}u!‹ÖþÿÿUúÿÿM‹L$‰1‹L$^[‰ÊH@€ù}tØáÿ3Ò„™@Òt’@TQÐ3ÉŠ„™@Òuì;Ö}°‹L$^[ÇèüËT$^[ÇÈüËD$3É@VŠ@‹ñ€8^u@‹T$‹J 3ÒŠö t @3ÒŠö uõ3ÉŠ;Î^u€x]u ‹T$‰¸Ã3ÀÃì‹D$,‹T$(SU‹‹‰L$ ‹L$L‰D$‰L$‰D$Æ@‹T$‹Ø‰D$‹D$@ÆB‹L$V¾þÿÿÿDW3ÿ‹î‰D$‹T$,‹L$0ƒâ;ÑtÆ‹D$ŠL$,@€á‰D$ˆ‹D$@‰D$‹L$D…Ét$ÆE‹D$@‰D$‹øÆ‹T$ÆB‹D$ƒÀ‰D$‹D$XL$ PT$XQ‹L$HD$ RPT$$Q‹L$HD$$RPT$HQR胃Ä$…À„×€;=t ‹l$‹t$Të@‹L$…í| ;ét…ö}‹õƒÍÿ…É|‹D$T…À} ‹Á‰D$Të‹D$T‹È3Î÷ÁÿýÿÿtƒÎÿë ð‹D$D…Àt#‹T$Æ‹D$,PSè/ƒÄ…À|R‹ÈˆGÁùˆ‹T$€:|uh‹D$Æ=‹D$‹È+ËÁùˆH‹D$ŠÐ*ÓˆP‹D$‹L$‹Ø‰D$$ƒÀA‰D$‰L$é¨þÿÿƒøþ¸<ýt¸ý‹T$@‰‹L$<‹D$_^‰]3À[ƒÄËL$+Ë3À‹ÑŠcŠCˆKÁúˆS+Ø…À‹Èå‹D$‹L$Æ>‹D$‹Ð+ÑÁúˆP‹D$ŠÐ*Ñ‹L$0ˆP‹T$,‹D$ƒâƒÀ;щD$t‹T$€:)uÆ‹D$@‰D$ˆ‹D$@‹L$8‹T$<_‰‹D$‹L$H‰‹T$L¸‰)‰2^][ƒÄËD$S‹\$ UVWƒÍÿ3ÿpŠ‹Á%ÿƒøL|¸Lë‡3ÒŠH2ÿ$•2SVè»ÿÿÿƒÄ…ÀŒåø3ÀŠfŠFð€>=tñƒÆë®…í}‹ïë;ï…¼€ù=…¢ƒÆ3ÿëŽ3ÉŠnŠNñ€>=tñ3Ò3ÀŠŠ‚|ôðélÿÿÿF3ÀŠøté\ÿÿÿ3ÉŠnŠNùƒÆéJÿÿÿ3ÒŠvŠVúƒÆé8ÿÿÿGFé1ÿÿÿƒÆ!3ÀŠƒÀуøw)ÿ$…˜23À3ÉŠfŠN3Ò ÁŠvŠV;Âu!øƒÆéùþÿÿGéóþÿÿ_‹Å^][Ã_^]¸þÿÿÿ[ÃÈÿ_^][ËÿF1u1¼12ˆ1˜1ª1Ã1f112       I22û1û122Ù1Ù1숋„$ŒSUV‹‹„$ W‹ù‹‹„$¨ƒç3Ò‹(‹ÁÁè ƒà‰T$4‰„$”ƒð‰„$Œ¸þÿÿÿÁç‰T$$‰T$<‰L$@‰T$L‰T$d‰l$‰T$‰D$ ‰D$,‰D$0‰D$(‰|$X‹t$L3ÀŠE…ö‰D$t…À…öÁtX‹Œ$¼‹Q ö…„‹D$ƒø#u3E3À‰l$ŠE…À‰D$t!ƒø tdE3À‰l$ŠE…À‰D$ué‹T$<‹|$Xë‹T$<‹|$Xƒø|‡¡‹t$(3ÉŠˆ,Lÿ$üKöD$@t ƒþþuÇD$(ÿÿÿÿÇD$ÆC‹l$‹T$<‹|$X‹L$@E‰l$é4ÿÿÿÇD$Æë؃þþuƒÎÿ‰t$(‹T$0‰t$,‰T$ ‰\$Æ ë·ŠE‰\$<:t<.t<=u"‹„$¼L$TPQUè¯ùÿÿ‹l$ƒÄ …À…ÀE3Ò‰l$ŠU‹òƒþ^uE3À‰l$ÇD$ŠE‹ðëÇD$¹3À|$lÇD$ ÇD$ÿÿÿÿó«‹D$L…Àt!ƒþ\…õ€}E…ëÇD$LEé=ƒþ[…AŠE<:t <.t<=…Ћ¼$¼L$TWQUèüøÿÿƒÄ …À„®‹l$‹W3ö‰T$ ŠE‰t$8<:…%ƒÅ‰l$€}^u EÇD$8‰l$‹D$T+ÅPUè.ƒÄ;ÆŒöD$@tƒø3À@‰t$,<…˜Ñ‹L$jhŒùQè6R‹ð‹ƒÄ ÷ÞöF…À|q‹L$8…Ét*‹T$ 3É,Š)ŠT löРЈT lAƒù |ë…öt2ŠD$m <ë&‹T$ 3É,Š)ŠT l ЈT lAƒù |í…öt ŠD$m$ÈD$m‹D$,ƒÇ@ƒø‰D$,Œnÿÿÿ‹L$TÇD$ iéóƒþ\…™‹„$ ‹T$@jR‹‹”$´QD$RPèeôÿÿ‹ðƒÄ‹Î÷Ùƒùu¾‹Î÷Ùƒùu%‹l$€}\u€}EuƒÅé“ÇD$L醅ö)‹”$¼ƒÁûƒùÇD$ ‹B‡óÿ$¬L3öŠL0@ŠT4l шT4lFƒþ |ì‹l$é:3öŠT0@ŠL4löÒ ÊˆL4lFƒþ |ê‹l$é3öŠŒ0 ŠT4l шT4lFƒþ |é‹l$é÷3öŠ”0 ŠL4löÒ ÊˆL4lFƒþ |ç‹l$éÓ‹øD$l3ö+øŠD4lL4lŠ ÂFƒþ ˆ|ëŠD$m‹l$$÷ˆD$mé¡‹øD$l3ö+øŠD4lL4lŠöÒ ÂFƒþ ˆ|éŠD$m‹l$ ˆD$mémöD$@@…ê‹l$3ÀŠE‹ðë‹l$€}-…ç€}]„݃Å3À‰l$ŠEƒø\‰D$8uD‹”$ ‹L$@jQ‹‹Œ$´PT$QRè£òÿÿƒÄ‰D$8…À}ƒøü…Џ‰D$8‹l$;ÆŒs‹L$@ƒá+ƉL$D‹L$ T‰T$ ‹Æ‹Î™ƒâƒáÂÁø|l°ÒàŠ È‹D$D…Àˆt'‹Œ$¼‹Q3ÉŠ 2‹Áƒá™ƒâÂÁø|l°Òà‹D$8‰t$F;ð~¦ëgƒÅþ‰l$‹Æ‹Î™ƒâƒá²ÁøÒâŠLl|lŠD$@ ʨˆt+‹„$¼3Ò‹HŠ1‹ò‹Æ‹Î™ƒâƒáÂÁø|l°Òà‹D$ ‰t$@‰D$ E3ɉl$ŠM‹ñƒþ]……ûÿÿ‹D$L…À…ûÿÿƒ|$ …‘‹D$‹T$0…À‹D$(‰T$ tƒøþuƒÈÿ‰D$(ŠL$ÆC‰D$,ˆ éqúÿÿƒøþu)‹D$‹L$X ÁŠL$ÆCÇD$,ÿÿÿÿ‰D$(ÆCˆ éCúÿÿ‹T$‹L$X‰D$,‹„$¼‹@(Æ ÂÆC ÁCCŠÊ‰D$0ˆ éúÿÿ‹D$(ƒøþuƒÈÿ‰D$(‹T$0‰D$,‹D$‰T$ …Àt%Æ8Ct$l‹Ã+ó¿ Š @öшHÿOuôƒÃ éËùÿÿÆ7C¹t$l‹ûƒÃ ó¥é²ùÿÿEUèˆòÿÿƒÄ…À„ ‹´$¬‹L$T$$VD$8RAPQèóÿÿ‹è‹ƒÄ‰l$…À…‹|$$ë+ÇD$4ƒÏÿëÇD$4ƒÏÿë ÇD$4¿‰|$$‹T$3É;Ñ„‹t$4;ñu‹D$,‰D$(‹D$ ‰D$0+÷‰T$PŠE‰L$÷Þö‰L$Hæ<+‰t$Du3ÀE‰D$ÇD$H‰l$ë!ˆC‹D$ˆS‹|$$‹l$ƒÃ‹ÑŠ €ùuQK3ÉŠ ‰L$J;Ùu+‹L$4‹Úƒù~g‹Œ$¼‹y(‹L$ ù‹L$X ù‰|$0‹|$$ëGŠJþɈJ‹|$$‹l$‰\$Pë1€ùu3ÉÇD$ ŠJë€ù ƒÇD$áÿ‰L$‹Ú…ÿ„‹l$‹L$4Å…Éu0ƒÿÿuŠL$ˆCˆ C铃ÿ…¦ŠL$ˆCˆ Céyƒùuƒÿÿu4ŠL$ˆCˆ Cé^ŠL$€Áˆ ‹L$4CÁùˆ ŠT$4ˆS‹|$$ƒÃë$Š €ùu;ÚuƒÃëŠJþÁˆJ‹|$$ë€ùuC…ÿ}ŠL$ˆ CˆCˆ Céÿ;|$4t-ŠT$ˆ‹L$4‹|$$C+ù‰|$$ˆ‹T$$CÁúˆŠD$$ˆCƒÃŠL$ˆ CéÀ€ù7„E€ù8„<€ù:„3€ùLs€ùFt €ùG…É ‹ËÇD$`+ʃÿÿ‰L$8ÇD$u‹ú3ÉŠoŠOù€?>uñ‹Ë+Ï‹|$$‰L$`‹L$4…É……ÿu‹Ú韃ÿ)‹D$‹T$8RPpVèñFŠD$$‹L$(ƒÄ CI‰t$ˆë=‹T$8‹D$RPƒÀPèÈFŠL$$‹D$(€ÁIƒÄ ƒÃˆ@ÆL@‰D$ÆÆ@ƒÀ‰D$‹|$$‹l$‹T$‹D$O‰|$$ëoƒù~^‹L$d…Ét‹L$0…É}‹L$(‰L$0‹t$4¹;ñ‰L$~5‹L$8‹é‹ò‹ûÁéó¥‹Íƒáó¤‹L$8‹t$‹|$4ÙF;÷‰t$|׋|$$‹l$…ÿ~ +|$4‰|$$…ÿŒÈOÿ…ɉL$|r‹t$8ŠÈ‹D$€ÁIˆL$_ëŠL$_ˆ ‹L$C…Ét%ÆLC…Àu3Éë‹Ë+È‹Á‰\$Áøˆ‹D$ˆKƒÃ‹Î‹ò‹é‹ûÁéó¥‹Íƒáó¤‹t$8‹L$ÞI‰L$y§‹l$ë‹D$…À„Ë|$‹Ã‹ó+Ç3É@+ðŠnŠN…Éu3ÿë+ùÆ>‹ÈCÁùˆ ˆCƒÃˆN…ÿˆFuÊ逋T$`‹Ë?+ʈër…ÿu‹ÚéÅ‹L$4…Éu ƒÿÿu/ˆCëSƒùuƒÿÿu1ˆCëBƒÿu3ˆCë65ˆ‹T$4CÁúˆŠD$4ˆC‹D$$ƒÃƒøÿu3À‰D$$ÁøˆŠL$$ˆKƒÃ‹l$‹D$H…ÀtN‹L$P‹Ã+ÁPQƒÁ‰D$PQè¥D‹L$T‹T$\ƒÃƒÁÆFƒÄ Æ>‹ÁCÁøˆˆK‹T$PƒÃˆB‹D$PˆH‹l$‹t$D‹„$¼ÇD$ p(éºóÿÿ‹D$@E‰l$‰D$HŠMÇD$8€ù?…¬E‰l$ŠM‹Á%ÿp߃þ1‡¥3ÀІôLÿ$…ÄLE‰l$€})„`óÿÿE‰l$€})uõéPóÿÿºLE‰T$<‰l$égŠEºG‰D$‰L$D‰l$t ŠEE<>‰l$uô‹ÅÇD$ +ÁH‰D$,‹F…À~z‹T$‹L$,‹t$Dz3Òó¦tÒƒÚÿ…Òt%|6‹Œ$¼‹T$‹q‹L$ ÖA;ȉT$‰L$ }9ëÁ‹T$,‹L$€| „•‹”$¼‹l$ +Å‹J¯ÁP‹D$ÈPQèœAƒÄ ‹´$ ‹D$‹xAÁùˆŠþ‹t$DˆP‹T$,‹Ê‹éÁéó¥‹Íƒáó¤ÆD‹„$¼ÿ@‹´$ ‹B‹Â‰=–ŽÆÆCK‹ÁøˆCŠºãˆK‰T$<ÇD$8é¦<=t<>…š‹¼$¼%ÿE‰D$`‹w‰l$ŠE‹Í<)‰L$Ht E‰l$€})uõ‹ÅÇD$+Á‰D$D‹G…À~3‹l$‹D$D‹T$HNPQRèëCƒÄ …Àt‹W‹GòE;è‰l$|Õ‹l$‹D$‹O;Á{‹D$`3ÉŠNƒø>Š.tr‰\$Æ:‹ÑCÁúˆˆKƒÃƒù ¸}Óà‹”$¼‹r$ ð‹B ;ȉr$Ž˜ïÿÿ‰J éïÿÿE‰l$3À3ÉŠEö€@Òt ‰E‰l$LHÐ3ÀŠEö€@Òuæ…ɉ\$Æu‹´$¼‹F‰D$ë‹´$¼Qj‹VRèàƒÄ ‰D$…À„ß3ÉŠhŠH…Éu#‹”$¸‹D$QRSPè1 ƒÄ…À…Æ‹D$Æ;‹~‹È+ÏÁùˆKŠN*ÁˆCƒÃéÕîÿÿ3ÿ3Ò€ù)‰|$D‰T$D$te€ù:t`áÿE‹ñ‰l$ƒî-ƒþKw?3ÒŠ–HMÿ$•(MD$Dë*‹ƒÉë!‹ƒÉ닃É닃Éë ‹€Í닃É@‰ŠM‹T$€ù)u›‹t$@‹D$DŠM Ö÷Ð#Ѐù)‹Â‰D$H…ïúÿÿ‹È3ÎöÁtÆŠÐC€âˆ‹l$C‹Œ$œ‰D$@‰|$‰‹ÈÁé ƒáƒà‰Œ$”ƒñÁà‰Œ$Œ‰D$XéííÿÿöÄ„(ýÿÿºLëPL‰T$<3ÀƒúFœÀHˆ#ÃúC‰D$‹„$¼‰\$P‹h(t ƒúDt3À븋Œ$¼‹”$¸‹¼$¬QL$lRQ‹L$D”$œRQ‹Œ$´PT$(WR‹T$`D$pƒâP‹D$lQRPè¾çÿÿƒÄ0…À„ã‹t$<ƒþGu33À3É@ŠkŠKÙ€;>uðƒøƒøuƒÊÿƒÈÿ‰T$h‰„$ë ‹T$h‹„$‹L$0ƒþL‰L$ ‹L$(‰L$,ÇD$d}ƒþFtƒþGt ƒþAuO…Ò|KëEƒùþu,…À|‰D$(ÇD$dÇD$,ÿÿÿÿë"ÇD$(ÿÿÿÿÇD$,ÿÿÿÿë…À| …Ò} ŋЉT$h…Ò|‰T$0‹l$‹\$P€})…\éqìÿÿ‹„$ ‹T$@jR‹‹”$´QD$RP‰l$hèãÿÿƒÄ…À•‹È÷Ùƒùu%‹l$€}\u€}EuƒÅéìÿÿÇD$Léìÿÿƒþþuƒù~ ƒù }ƒÎÿ‰t$(‹T$0ƒù‰t$,‰T$ |!¹ïÿÿÿ‰\$+ÈÆ:‹ÁCÁøˆˆKƒÃéÅëÿÿƒù~ ƒù ‰\$|ÇD$ö؈é¥ëÿÿ‹L$TÇD$\‰L$‹D$‹¬$¼‰\$Æ‹t$ƒÃ3ɉ\$D‰L$‹T$L…Òt%ƒø\…‘€~E…‡FÇD$L‰t$éöD$@t3‹U öuqƒø#u%F3À‰t$Š…À„Šƒø tVF3À‰t$Š…Àtxëìƒø\u6‹Œ$ ‹D$@jP‹‹„$´RL$PQ‰t$hè­áÿÿƒÄ‰D$…À|3‹L$ˆ‹t$CA‰L$ùú}'‹U F3À‰t$ЉD$ö€ué/ÿÿÿ‹D$T‹L$‰D$‹D$(ƒøþuBƒùu ‹T$D3ÀÇD$,ÿÿÿÿŠ ljD$(‹D$0‰D$ ëP‹T$D3ÀŠ ǃù‰D$(‰D$,‹D$0ëƒù‰D$,u ‹T$0‰T$ ë‹u(3ÀŠCþ Æ Ç‰D$ ‹u(3ÀŠCÿ Æ Ç‰D$0‹D$ùúˆHêÿÿ‹l$Méÿéÿÿ‹Œ$°‹”$´‹D$0_‰1‹Œ$ ‰‹”$¤‰^‰*]¸[ĈÊE<:¸øþt¸Ìþ‹Œ$¬‹”$¨_^‰‰*]3À[ĈË”$¬_^3ÀÇÌþ‹”$ ‰*][ĈË„$¬Ç°þ‹l$‹”$¨_^3À‰*][ĈËŒ$¬Ç„þë׋”$¬_^3ÀÇ\þ‹”$ ‰*][ĈË„$¬‹”$¨_^ÇHþ‰*]3À[ĈËŒ$¬‹”$¨_^Ç$þ‰*]3À[ĈË”$¬_^3ÀÇ þ‹”$ ‰*][ĈË„$¬‹”$¨_^Çðý‰*]3À[ĈËŒ$¬‹”$¨_^ÇÌý‰*]3À[ĈË”$¬_^3ÀÇÐù‹”$ ‰*][ĈË„$¬ÇÐùéÐþÿÿ‹Œ$¬Ç¤ýé¾þÿÿÇpýé³þÿÿ‹”$¨Çdý_^‰*]3À[ĈÃIøI 4=@‰:–:4£:;4†GÓ3A:aH      Iè6É67O7+7 7qAˆ@º@hD§@„A^A¾AÑA#BcDE      ‹ÿ\E~E…EbEiEpEwEŒE‹D$3ÉSVŠW…Ét_‹|$‹5ÈôŠŽôƒùu3Û3ÉŠHŠÚØ ë2ƒùL~#ƒÁ´ù–~3ÉŠhŠH;Ït ‹ÎáÿÁë 3ÛŠ™|ôÃ3ÉŠ…Éu±3À_^[ÃSUV‹t$…öWt(‹|$ ‹\$‹l$‹F;ÅrWSPè)ƒÄ …Àt‹6…öuä_^]¸[Ã_^]3À[ËD$SUVWjƒÀjPè;‹l$$‹ðƒÄ ;õƒ«‹\$3ÀŠƒøL|F3ÉŠnŠN…É„Ž3ÿ…ÿuSUVè¯ÿÿÿƒÄ …Àt¿3ÒŠvŠVò€>=tÙ…ÿtkƒÆ3ÀŠë7Hûƒù;w/3ÒŠ‘dOÿ$•TO3ÉŠN!ƒÁуùw>ÿ$ O3ÉŠn"ŠN#…É+3ÒjŠ|ôjÖR茋ðƒÄ ;õ‚Yÿÿÿ_^]¸[Ã_^]3À[ËÿKOOAO O O OKOKO O OOO‹D$3ÉSVŠWƒÁýƒùHw\‹t$‹|$3ÒŠ‘DPÿ$•4P…ö~‹3ÉŠH#Ö‹Ù#Þ;Út‰ƒÀë3ÉŠhŠHÁ€8=tñ3Ò3ÉŠŠŠ|ôÁ3ÉŠƒÁýƒùHv¬_^[ÃPêOP/P ˆÑSUV3öW„Àt8‹\$‹l$¿Ìô3ÀІˆÑ;Øu‹SQUè7ƒÄ …ÀtІ‰ÑFƒÇ„ÀuÕ_^]ƒÈÿ[ËÆ_^][ÃS‹\$U‹l$V‹t$W‹|$jGVPè°þÿÿ3ÉƒÄ ŠƒùL~3ƒéLù–~3ÉŠhŠHƒù º}Óâ ÓURVPèªÿÿÿƒÄ…ÀthëRt@ƒùAt;ƒùFt6ƒùGt1ƒù&tƒù'uöt €x u@…Ýu<ë&ƒùt!ƒùtöu+ƒùu&ëUSVPèVÿÿÿƒÄ…Àt3ÉŠoŠOù€?=u éOÿÿÿ_^]3À[Ã_^]¸[ÃU‹l$ V‹t$ W‹|$jFjPèÔýÿÿ3ÉƒÄ ŠƒùL~2ƒéLù–~3ÉŠhŠHƒù º}Óâ ÕWRPè¯ÿÿÿƒÄ …ÀtSë=t,ƒùAt'ƒùFt"ƒùGtƒù&t ƒù'tƒùu1ë€x u)…ïu%ëWUPèpÿÿÿƒÄ …Àt3ÉŠnŠNñ€>=u édÿÿÿ_^3À]Ã_^¸]ÃS‹\$UVW‹|$ƒÍÿjCWPèýÿÿ3ÉƒÄ ŠƒùL|¹Lqîƒþ:wz3ÒŠ–\Sÿ$•HS3ÒƒùA”ÂRWPè­ÿÿÿƒÄ …À|T…í}‹èë2;èuHë,@@‹L$…Ét<…í}3ÉŠHЍ‹étÍë 3ÒŠP;êu3ÀŠcŠCØ€;=„hÿÿÿ_‹Å^][Ã_^]ƒÈÿ[ËÿùRúRøRÓR>S씋”$ ‹Œ$¨SƒÈÿ ‰D$‰D$(‰D$KÿU‰L$(‹Œ$´3ÀV÷ÁoÚÿÿW‰D$‰D$,‰D$<‰D$ t_^]¸ýÿÿÿ[ĔË´$¨;ð„#;Є9„$Àu 9„$Ä‹¼$¬‰D$;øÇD$L€–˜‰„$ t&‹¨t‹W‰T$¨t‹W‰T$L¨t ‹G ‰„$ >ERCPt_^]¸üÿÿÿ[ĔËF 3í‹Ðf‹nÁêƒâ‹ø‰T$$3Òf‹V ù¯Õ‹¬$¸Ç„$œT2‰¬$˜‹¬$´‰T$|‹”$°‰”$€Õ‰”$„‰T$‹Ð‹¬$ÄÁêƒâ‰T$t‹ÐÁê ƒâƒà‰T$p‹ÑÁêƒâ‰D$@‰T$h‹ÑÁé ƒá‹Å‰L$x‹NÁêƒâ‰L$\Á@‰T$l‰L$`¹™÷ùf‹FÁïƒç‰|$D+êf…ÀvQ‹È¸VUUU÷í‹ÂáÿÿÁèÐ;Ê|7lI ­QÿõƒÄ‰D$P…Àu_^]¸úÿÿÿ[Ä”ÃÇD$ë ‹”$À‰T$PL-¸VUUU÷é‹Â3Éf‹N‰l$TÁèÐD ‹Œ$ĉT$X;ÁÇD$dÇ„$”ÿÿÿÿ‰D$8~‹Å‰D$8‹L$P…Ét(™+ºÑø,©+ÐD•ƒí;èrÇEÿÿÿÿƒí;èsò…ÿuV÷F @t03Àf‹F‹ÈÁèƒàáÿƒø‰L$‰D$,u,‹T$\3ÀŠ ‰D$ë‹D$$…Àu‹D$…Àt ö@tƒÀ‰D$ ÷F t,3Àf‹F‹ÈÁèƒàáÿ‰D$<‹F3Ò‰L$4Š”‰T$(‹l$‹t$‹D$8‹|$P ‡;ùs +σÁÁéƒÈÿó«…í|F‹D$,…Àt';Þƒª‹D$\3É3ÒŠ Š;Õ„•C;Þrêé‹;Þƒƒ3ÀŠ;Åt{C;Þróët‹D$$…Àt%‹Œ$¸‹”$€Ñ;ÚvX;ÞsT€{ÿ tNC;ÞrõëG‹D$ …Àt?;Þs;3ÀºŠ‹ð‹ÎƒáÓâ‹L$ ‰T$™ƒâÂÁøŠ‹D$„ÂuS‹t$C;ÞrÉ‹l$‹|$4…ÿ|d‹Î+Ëùè}X‹L$03À…íÀÃ;ÁvG‹L$<…Ét#;Æs}3ÉŠ@;Ït);L$(t#;Æsjëë‹l$‹t$ë°;ÆsZ3ÒŠ@;×t;ÆsMëñH;ÆsF‰D$0‹D$@‹T$|jjL$PPQjRS‰œ$¤ÇD$dè ƒÄ…Àu5‹D$DC…Àu;Þ†xþÿÿ‹D$…Àt‹D$PPÿõƒÄ_^]ƒÈÿ[ĔÃø…­‹D$‹¬$Ä…ÀtF‹D$Pƒý|"‹”$À ­øÿÿÿpz‹ÑÁéó¥‹Êƒáó¤9¬$~ÇD$dPÿõƒÄ‹D$d…Àt3Àë ‹„$™+ÂÑøƒý} _^]3À[ĔËŒ$€‹´$Œ‹”$À+Ù+ñ_‰r^‰][Ĕøþÿÿÿ_^][Ä”ÃìÄ‹„$ØS‹œ$؉D$UV‹WH‰ ‹K;Ár_^]¸øÿÿÿ[ÄÄÊ„$ð‹¬$بt‹”$ìD$T‰T$T‰l$X‰„$ì‹´$ÜŠÇD$$‹Á%ÿ‹øƒÿL~2W´ú–‰T$~ 3ÒŠvŠV‰T$‹T$<‹S;úŒ ¿L3ÒŠ—Pwÿ$• vƒÆ뢋sT…ö„΋F…À…ˉCT‹N‹V‹CÁáQRPèF*‹N ‹T$,‰K@‹vƒÄ ‰”$èéWÿÿÿ3ÀŠFƒÆ‰„$èéCÿÿÿ‹„$苼$àjjPSNWQUè·þÿÿƒÄƒøt7…À…ê3ÒŠvŠVò€>=u ‹„$èjjPSNWQUè€þÿÿƒÄƒøuÉ€>>„ö„$ð…+3ÒŠvŠVò€>=tñ‹CHƒÆ‰„$àé­þÿÿ‹¼$à‹Œ$èjjQSVWRUè!þÿÿƒÄƒø„¬…À…PŠfŠFð€>=tÇö„$ð…¼ƒÆéWþÿÿ‹C83ÉŠnŠN+é;è‚lƒÆé:þÿÿ‹ ø5…Éto‹C3ÒŠV‰D$4‹C8‰T$0‹S<‰D$8+ÐÇD$,‰T$<‹S@+ЉT$@‹Õ+Ћ„$à‰T$D™+‹SXÑø‰D$H‹CL‰D$LD$,P‰T$TÿуÄ…Àñ Œ—ƒÆé¹ýÿÿ‹¼$싌$è‹”$àjWQSFRPU‰t$0‰l$8èýÿÿƒÄƒøt=…À…R3ÉŠnŠNñ€>=u&‹”$è‹„$àjWRSNPQUèâüÿÿƒÄƒøuÊ=tñ‹CH‹kD‰„$àŠ<>t ;l$…ƒÆéýÿÿ3ÉŠnŠNñ€>=tñéñüÿÿ‹”$ì‹„$苌$àjRPFSQVUèaüÿÿƒÄ…À…™3ÒŠvŠVò€>=tñƒÆé¬üÿÿF‹Æ3ÉŠhŠHÁ€8=tñ‹”$싌$èjR‹”$èQSƒÀRPUèüÿÿƒÄ…À…@éeüÿÿ3À‹þŠfŠF+ø‹„$ì‰|$‹H‹Š‰L$‰Œ$èt ;l$…ƒÆé8ûÿÿ‹C …Àt ;k8„R ö„$èt;k8t €}ÿ …9 Fé ûÿÿ;k8…* Féúúÿÿ‹SP‹K8Ñ;ê… Féäúÿÿö„$èt&;k=…‹Œ$ì‹”$èjQRSFWPUè\ñÿÿƒÄ…ÀtÈ_^][ÄÄÊNF€ùHuu3ÀŠfŠFÑà=þÿu‹KT3À…É•À…Àt¸ë;„$à} ‹Kƒ<}ç3ÀŠfŠFƒÀ‹”$싌$èjR‹”$èQSÆRPUèØðÿÿƒÄ_^][ÄÄËŒ$苼$àjjQSWPUè®ðÿÿƒÄƒøu%3ÒŠvŠVŠDt<=u#3ÀŠfŠFð€>=tñë…À…¼ 3ÉŠnŠNñ‹”$ì‹„$èjRPSƒÆWVUèQðÿÿƒÄ_^][ÄÄËCj‹ ¸‹T¸‰L$$‹K ‰T$ ‹T$+Ê‹ˆ‰T$(‹Õˆ‹KL‰L$,‹K8+Ñ‹Œ$쉋„$ð‹”$äPQSFRPUèéïÿÿƒÄ…À…! ‹L$(3Ò‰KLŠvŠVò€>=u7‹„$싌$è‹”$àjPQSFRPUè£ïÿÿƒÄ…Àt¾_^][ÄÄËK‹T$ ‰¹‹C‹L$‰L¸‹S ‹D$‹L$$+ЋC‰ _^]3À[ÄÄËC0…Àt;k@u _^]3À[ÄÄË”$à‰kD‰SH_^]¸[ÄÄËS43ÉŠnŠNʉL$ €9IuA‰L$ 3ÀŠƒèL=–‰D$0~ 3ÀŠaŠA‰D$0‹KTT$,‰L$,‹K ƒÆƒù‰ST‰t$4‰L$@ D$\‰D$<ë-PÿõƒÄ‰D$<…Àu_^]¸úÿÿÿ[ÄÄËL$@‹s‹”$ì‹ø‹„$èó¥‹K@jR‹T$(‰L$@‹Œ$èPSƒÂQRU‰k@è[îÿÿƒÄƒøtd…À…Ž ‹L$@‹t$<‹{D$,‰CT‹D$ ó¥3ÉŠhŠHÁ‰D$ €8=u^‹”$ì‹„$苌$àjR‹T$(PSƒÂQRUè÷íÿÿƒÄƒøuœ‹D$,L$\‰CT‹D$<;Át PÿõƒÄ_^]¸[ÄÄËD$<‹T$,L$\‰ST;Át PÿõƒÄ_^]3À[ÄÄÊNF€ù‰D$ u‹Œ$è3ÒŠVƒáø‹Â Á‰„$èë‹„$è€>@uM‹´$à‹T$ jWPSVRUèIíÿÿƒÄ…À… ‹„$è‹L$jWPSVQUè&íÿÿƒÄ…ÀtP_^][ÄÄË´$à‹T$jWPSVRUèüìÿÿƒÄ…À…4 ‹L$ P‹„$ìWPSVQUèÚìÿÿƒÄ…À… _^]3À[ÄÄÀ>@ub‹”$ì‹D$ ‹Œ$àjRPSƒÆQVUè›ìÿÿƒÄ…À…Ó ‹”$ì‹D$ ‹Œ$àjRPSQWUèqìÿÿƒÄ…À„ýÿÿ_^][ÄÄË”$ì‹D$ ‹Œ$àjRPSQWUè<ìÿÿƒÄ…À…t ‹”$싌$àP‹D$$RPSƒÆQVUèìÿÿƒÄ…À…H _^][ÄÄËT$$…Ò„¤‹D$‹Œ$ì‹”$èj‰D$‹„$äQRSPVUèÄëÿÿƒÄ…À…ü‹L$‹D$;Á@üÿÿ‹”$è‹D$RSWUPèd ƒÄ…À„ üÿÿ‹L$‹”$è‹„$àïAj‰L$‹Œ$ðQRSPVUè\ëÿÿƒÄ…Àtœ_^][ÄÄÃ;Á‰l$ ‰D$}5‹Œ$è‹T$QSWURèù ƒÄ…Àt‹D$‹L$ï@;Á‰D$|Ñ;l$ r7‹„$싌$è‹”$àjPQSRVUèçêÿÿƒÄ…À…‹D$ +ï;èsÉ_^]3À[ÄÄËT$$…Ò„µ‹Œ$è‹”$à‰D$‹„$ìjPQSRVUè“êÿÿƒÄ…À…Ë‹D$‹L$;Áûÿÿ;k<ƒûÿÿ3ɺŠME‹ùƒáÓâ‹Ç‹Ê™ƒâ‹T$ÁøŠ„È„Øúÿÿ‹L$‹”$ì‹„$èAj‰L$‹Œ$äRPSQVUèêÿÿƒÄ…Àt‡_^][ÄÄÃ;Á‰l$ ‰D$}N;k;ka$bRbˆf¶fäfg6g]gSff„t“t¢t±tÀtÏtotvu¤uÏuîu v,v0ubu‹L$‹T$SV‹A‹t$‹Y8W‹‹Q<‹|$+ÖÃ;ú~_^3À[ÃöD$ t,‹×O…Ò~=‹I3Ò3ÛŠŠF@Š 8 u׋×O…Òç_^¸[ËÏO…É~ŠŠF@:Ñu¶‹×O…Òï_^¸[ËD$3É3ÒƒìLf‹Hf‹P¯ÊS‹\$\VW…ÀtÇ„Î8ERCP…‹L$`…Ét_Ç\^3À[ƒÄLËP ÷ÂP…¢‹@|$ ‰D$,ˆ‰L$0ˆ@‰L$4‰D$8¹3Àó«‹ÊD$,Áé ƒáPƒâQRT$RVèaƒÄ…ÀtMj8ÿõƒÄ…Àu _Ç0ú^[ƒÄLÃHljHt$ Ç(ÆAy¹ó¥_^[ƒÄLÃÇ,_^3À[ƒÄLÃS‹\$U‹l$V‹t$W‹|$ƒÇŠ}>}@|@|J|J|V‹t$ ‹Æ‹Î™ƒâW‹|$ ÂÁøƒá²ÇÒ⊠ʈ‹D$…Àt%‹D$‹H ö1t‹P3ÉŠ 2²‹ÁƒáÁèÇÒâ_^ÃBÿ[ä$d$3ÀŠD$S‹ØÁà‹T$÷ÂtŠ B8ÙtÑ„ÉtQ÷Âuí ØW‹ÃÁãV Ø‹ ¿ÿþþ~‹Á‹÷3Ëðùƒñÿƒðÿ3Ï3ƃÂáu%tÓ%uæ€uÄ^_[3ÀËBü8Øt6„Àtï8Üt'„ätçÁè8Øt„ÀtÜ8Üt„ätÔë–^_Bÿ[ÃBþ^_[ÃBý^_[ÃBü^_[ÃS3Û9$7u‹D$ƒøa|YƒøzTƒè [ÃV¾,=WVÿÐ9(=‹=ÐtVÿ×jè Yj[ÿt$è…ÛY‰D$t jèPYëVÿ׋D$_^[ÃU‹ìQƒ=$7Su‹EƒøaŒ¯ƒøz¦ƒè éž‹]û}(ƒ=œ ~ jSè…YYë ¡ŠXƒà…Àu‹Ãëk‹‹ÃÁø¶ÈöDJ€t€e ˆEˆ] jë €e ˆ]jXMüjjjQPEPhÿ5$7è­ƒÄ …Àt©ƒøu¶Eüë ¶Eý¶MüÁà Á[ÉÃU‹ìQ‹EHùw ‹ ·AëR‹ÈV‹5Áù¶ÑöDV€^t€eþˆMüˆEýjë €eýˆEüjXM jjjQPEüPjèwƒÄ…ÀuÉ÷E #E ÉÃS3Û9$7u‹D$ƒøA|YƒøZTƒÀ [ÃV¾,=WVÿÐ9(=‹=ÐtVÿ×jè\ Yj[ÿt$è…ÛY‰D$t jè  YëVÿ׋D$_^[ÃU‹ìQƒ=$7SVWu‹EƒøAŒªƒøZ¡ƒÀ 陋]¿j;ß^}%95œ ~ VSèÑþÿÿYYë ¡ŠX#Æ…Àu‹Ãëe‹‹ÃÁø¶ÈöDJ€t€e jˆEˆ] Xë €e ˆ]‹ÆVjMüjQPEPWÿ5$7èÿ ƒÄ …Àt®;Æu¶Eüë ¶Eý¶MüÁà Á_^[ÉÃU‹ìjÿh@ÓhĤd¡Pd‰%ƒìSVW‹u…ö„¬¡$=ƒøu;j è' YƒeüVèìY‰Eä…Àt VPèYYƒMüÿèƒ}äëQj èV YÃøuSj èç YÇEüEàPEØPVèƒÄ ‰EÜ…ÀtPÿuàÿuØèGƒÄ ƒMüÿè ƒ}Üuÿuë j èþ YÃVjÿ5 =ÿ ЋMðd‰ _^[ÉÃÿ5H7ÿt$èYYÃ|$àw"ÿt$è…ÀYu9D$tÿt$è"…ÀYuÞ3ÀÃU‹ìjÿhXÓhĤd¡Pd‰%ƒì SVW¡$=ƒøuC‹u;5=‡“j èü YƒeüVèY‰EäƒMüÿè ‹Eä…Àtmé†j è2 YÃøuZ‹E…Àtpƒæðëj^‰u;5œ0w.j è¦ YÇEü‹ÆÁèPèdY‰EäƒMüÿè ‹Eä…Àu-Vë‹uj èÓ YËE…ÀujXƒÀ$ðPjÿ5 =ÿЋMðd‰ _^[ÉÃÌÌÌÌÌÌÌU‹ìWV‹u ‹M‹}‹Á‹ÑÆ;þv;ø‚x÷ÇuÁéƒâƒùr)ó¥ÿ$•Ø…‹Çºƒér ƒàÈÿ$…ð„ÿ$è…ÿ$l……,…P…#ÑŠˆŠFˆGŠFÁéˆGƒÆƒÇƒùrÌó¥ÿ$•Ø…I#ÑŠˆŠFÁéˆGƒÆƒÇƒùr¦ó¥ÿ$•Ø…#ÑŠˆFÁéGƒùrŒó¥ÿ$•Ø…IÏ…¼…´…¬…¤…œ…”…Œ…‹DŽä‰Dä‹DŽè‰Dè‹DŽì‰Dì‹DŽð‰Dð‹DŽô‰Dô‹DŽø‰Dø‹DŽü‰Düðøÿ$•Ø…‹ÿè…ð…ü…†‹E^_Éʈ‹E^_ÉʈŠFˆG‹E^_ÉÃIŠˆŠFˆGŠFˆG‹E^_ÉÃt1ü|9ü÷Çu$Áéƒâƒùr ýó¥üÿ$•p‡‹ÿ÷Ùÿ$ ‡I‹Çºƒùr ƒà+Èÿ$…x†ÿ$p‡ˆ†¨†ІŠF#шGNÁéOƒùr¶ýó¥üÿ$•p‡IŠF#шGŠFÁéˆGƒîƒïƒùrŒýó¥üÿ$•p‡ŠF#шGŠFˆGŠFÁéˆGƒîƒïƒù‚Zÿÿÿýó¥üÿ$•p‡I$‡,‡4‡<‡D‡L‡T‡g‡‹DމD‹DމD‹DމD‹DމD‹DŽ ‰D ‹DމD‹DމDðøÿ$•p‡‹ÿ€‡ˆ‡˜‡¬‡‹E^_ÉÊFˆG‹E^_ÉÃIŠFˆGŠFˆG‹E^_ÉÊFˆGŠFˆGŠFˆG‹E^_ÉÃÌÌÌÌÌÌÌÌÌÌÌU‹ìWVS‹Mã&‹Ù‹}‹÷3Àò®÷ÙË‹þ‹u ó¦ŠFÿ3É:GÿwtII÷Ñ‹Á[^_ÉáTM…ÀtÿÐhðhðèêhðhðèÛƒÄÃjjÿt$ èƒÄ ÃjjjèƒÄ ÃWèŸj_9=l6uÿt$ÿÐPÿЃ|$ S‹\$‰=h6ˆd6u<¡PM…Àt"‹ LMVqü;ðr‹…ÀtÿЃî;5PMsí^h ðhðèCYYh(ðh$ðè2YY…Û[tè_Ãÿt$‰=l6ÿÐ_Ãj èËYÃj è#YÃV‹t$;t$ s ‹…ÀtÿЃÆëí^á@MVj…À^u¸ë;Æ}‹Æ£@MjPèzY£8=…ÀYu!jV‰5@MèaY£8=…ÀYujèŒY3ɸ° ‹8=‰ƒÀ ƒÁ=0 |ê3ɺÀ ‹ñ‹ÁÁþƒà‹4µ<À‹†ƒøÿt…Àuƒ ÿƒÂ Aú |Ñ^Ãè< €=d6té#ËD$¹° ;Ár= w+ÁÁøƒÀPèÈYÃÀ Pÿ ÐËD$ƒø} ƒÀPè©YËD$ƒÀ Pÿ ÐËD$¹° ;Ár= w+ÁÁøƒÀPè×YÃÀ Pÿ$ÐËD$ƒø} ƒÀPè¸YËD$ƒÀ Pÿ$ÐÃVèv‹L$3ö‰¸0 ;t"ƒÀF=˜|ñƒùr"ƒù$wèBÇ ^Ãè5‹ õ4 ^‰Ãù¼rùÊw èÇ^ÃèÇ^ÃèC ƒÀÃè: ƒÀ ÃV‹t$WƒÏÿöF @tƒf ëVè¼þÿÿVèV‹øèÿÿÿƒÄ ‹Ç_^ÃV‹t$WƒÏÿöF ƒt4VèbV‹øèÏ!ÿvèç ƒÄ …À}ƒÏÿë‹F…Àt PèìöÿÿƒfYƒf ‹Ç_^ÃÌÌÌÌÌÌÌÌ‹L$ W…ÉtzVS‹Ù‹t$÷Æ‹|$uÁéuoë!ŠFˆGIt%„Àt)÷Æuë‹ÙÁéuQƒãt ŠFˆG„Àt/Kuó‹D$[^_Ã÷ÇtˆGI„Š÷Çuî‹ÙÁéulˆGKuú[^‹D$_ɃÇIt¯ºÿþþ~‹Ѓðÿ3‹ƒÆ©tÞ„Òt,„öt÷Âÿt ÷ÂÿuƉëâÿÿ‰ëâÿ‰ë3Ò‰ƒÇ3ÀIt 3À‰ƒÇIuøƒãu…‹D$[^_ËD$ƒø…ˆÿ,Ðj£06袅ÀYt<¡063ÉŠ 16%ÿÁ-06£86‰ <6ÁàÁ£46è×…Àu è¾3Àërÿ(У0=èT$£ 6è«èø!è:!èíúÿÿÿœ6ë>3É;Áu,9 œ6~½ÿ œ69 h6uèûÿÿè*èÂèYë ƒøuQèHYjX U‹ìS‹]V‹u W‹}…öu ƒ=œ6ë&ƒþtƒþu"¡4=…Àt WVSÿÐ…Àt WVSèçþÿÿ…Àu3ÀëNWVSèÑ$ƒþ‰E u …Àu7WPSèÃþÿÿ…ötƒþu&WVSè²þÿÿ…Àu!E ƒ} t¡4=…ÀtWVSÿЉE ‹E _^[] ¡¨6ƒøt …Àuƒ=¬6uèn$ÿt$èž$hÿÿ YYÃV‹50Ðÿ5èÿÖÿ5ØÿÖÿ5ÈÿÖÿ5¨ÿÖ^ÃVW‹=4…Àt+þèt#þØtþÈtþ¨t Pÿ×ÿ6èÉóÿÿYƒÆþd|Äÿ5Èÿ×ÿ5Øÿ×ÿ5èÿ×ÿ5¨ÿ×_^ÃU‹ì‹EVƒ<…¤4…¤u>Wjècôÿÿ‹øY…ÿujè ÿÿÿYjèÊÿÿÿƒ>YWu ÿ0Љ>ëèNóÿÿYjè Y_ÿ6ÿ Ð^]ÃU‹ì‹Eÿ4…¤ÿ$Ð]ÃU‹ìjÿhxÓhĤd¡Pd‰%ƒìSVW‰eè3ÿ9=<7uFWWj[ShtÓ¾VWÿDÐ…Àt‰<7ë"WWShpÓVWÿ@Ð…À„"Ç<79}~ÿuÿuèžYY‰E¡<7ƒøuÿuÿuÿuÿuÿu ÿuÿ@ÐéÞƒø…Ó9} u¡47‰E WWÿuÿu‹E$÷ØÀƒà@Pÿu ÿ<Ћ؉]ä;ß„œ‰}üƒÀ$üè )‰eè‹Ä‰E܃MüÿëjXËeè3ÿ‰}܃Müÿ‹]ä9}ÜtfSÿuÜÿuÿujÿu ÿ<Ð…ÀtMWWSÿuÜÿu ÿuÿDЋð‰uØ;÷t2öE t@9}„²;uÿuÿuSÿuÜÿu ÿuÿDÐ…À…3ÀeÈ‹Mðd‰ _^[ÉÃÇEü6ƒÀ$üèX(‰eè‹Ü‰]àƒMüÿëjXËeè3ÿ3ÛƒMüÿ‹uØ;ßt´VSÿuäÿuÜÿu ÿuÿDÐ…Àtœ9}WWuWWëÿuÿuVSh ÿu ÿ8Ћð;÷„qÿÿÿ‹Æélÿÿÿ‹T$‹D$…ÒVJÿt €8t@‹ñI…öuó€8^u+D$ËÂÃU‹ìjÿhÓhĤd¡Pd‰%ƒìSVW‰eè¡@73Û;Ãu>EäPj^VhtÓVÿLÐ…Àt‹ÆëEäPVhpÓVSÿHÐ…À„ÎjX£@7ƒøu$‹E;Ãu¡$7ÿuÿuÿu ÿuPÿHÐ韃ø…”9]u¡47‰ESSÿuÿu ‹E ÷ØÀƒà@Pÿuÿ<ЉEà;Ãtc‰]ü<‹ÇƒÀ$üèÛ&‰eè‹ô‰uÜWSVèk&ƒÄ ë jXËeè3Û3öƒMüÿ;ót)ÿuàVÿuÿu jÿuÿ<Ð;ÃtÿuPVÿuÿLÐë3ÀeÌ‹Mðd‰ _^[ÉÃV‹t$jƒ&ÿPÐf8MZu‹H<…Ét ÁŠHˆŠ@ˆF^ÃU‹ì¸,è<&…hÿÿÿSPÇ…hÿÿÿ”ÿ\Ð…Àtƒ½xÿÿÿuƒ½lÿÿÿrjXé…ÔíÿÿhPh´ÓÿXÐ…À„Ð3ÛÔíÿÿ8ÔíÿÿtŠj,Pè½êÿÿY;ÃYt0@‹È8t€9;uˆëA8uòj SPèX%ƒÄ ƒøtƒøtƒøtEüPè˜þÿÿ€}üYÀƒÀ[ÉÃ3Àj9D$h”ÀPÿdÐ…À£ =t6è“þÿÿƒø£$=u høèÌYë ƒøuè …Àuÿ5 =ÿ`Ð3ÀÃjXá$=VƒøWufS3Û9=U‹- Ð~@¡=‹=hÐp h@hÿ6ÿ×h€jÿ6ÿ×ÿvjÿ5 =ÿÕƒÆC;=|Îÿ5=jÿ5 =ÿÕ][ë'ƒøu"¿x‹÷‹F…Àth€jPÿhЋ6;÷uåÿ5 =ÿ`Ð_^Ãh@jÿ5 =ÿÐ…À£=uËL$ƒ%=ƒ%=j£ =‰ =Ç=Xá= €¡= ˆ;Ás‹T$+P úrƒÀëè3ÀÃU‹ìƒì‹MSV‹u ‹AW‹þƒÆü+y Áï‹ÏiÉŒD‰Mð‹IöÁ‰Mü…æ‹11‰Uô‹Vü‰Uø‹Uôö‰] u~ÁúJƒú?vj?Z‹K;KuLƒú s»€‹ÊÓëL÷Ó!\¸Dþ u(‹M!ë!JເÓëL÷Ó!œ¸Äþ u‹M!Y‹Mü‹] ë‹Mü‹S‹[Mô‰Z‹U ‰Mü‹Z‹R‰S‹ÑÁúJƒú?vj?Z‹]øƒã‰]ô…”+uø‹]øÁûj?‰u K^;Þv‹ÞMø‹Ñ‰MüÁúJ;Öv‹Ö;Útc‹M ‹q;qu@ƒû s¾€‹ËÓî÷Ö!t¸DþLu&‹M!1ëKྀÓî÷Ö!´¸ÄþLu‹M!q‹M ‹q‹I‰N‹M ‹q‹I‰N‹u ë‹]ƒ}ôu;Ú„‹Mð‹\Ñ щ^‰N‰q‹N‰q‹N;Nu`ŠLƒú ˆMþÁˆLs%€}u»€‹ÊÓë‹M »€‹ÊÓëD¸D ë)€}uJເÓë‹M YJ຀Óê„¸Ä ‹Eü‰‰D0ü‹Eðÿ…÷¡=…À„Ü‹ =‹5hÐÁáH »€h@SQÿÖ‹ =¡=º€Óê P¡=‹ =‹@ƒ¤ˆÄ¡=‹@þHC¡=‹H€yCu ƒ`þ¡=ƒxÿuiSjÿp ÿÖ¡=ÿpjÿ5 =ÿ С=‹=€Áà‹È¡=+ÈLìQHQPèÕëÿÿ‹EƒÄ ÿ =;=vƒm¡=£ =‹E‰==£=_^[ÉÃU‹ìƒì¡=‹=SV€W<‚‹E‰}üHƒáð‰MðÁùIƒù }ƒÎÿÓîƒMøÿ‰uôëƒÁàƒÈÿ3öÓè‰uô‰Eø¡ =‹Ø;߉]s‹K‹;#Mø#þ Ïu ƒÃ;]ü‰]rç;]üuy‹Ú;؉]s‹K‹;#Mø#þ ÏuƒÃëæ;ØuY;]üsƒ{uƒÃ‰]ëí;]üu&‹Ú;؉]s ƒ{uƒÃëî;Øuè8‹Ø…Û‰]tSèÚY‹K‰‹Cƒ8ÿu3Àé‰ =‹C‹ƒúÿ‰Uüt‹ŒÄ‹|D#Mø#þ Ïu7‹Ä‹pD#Uø#uôƒeüHD Ö‹uôu‹‘„ÿEü#UøƒÁ‹þ#9 ×té‹Uü‹Ê3ÿiÉŒD‰Mô‹LD#Îu ‹ŒÄj #Mø_…É|ÑáGë÷‹Mô‹Tù‹ +Mð‹ñ‰MøÁþNƒþ?~j?^;÷„ ‹J;Juaƒÿ }+»€‹ÏÓë‹Mü|8÷Ó‰]ì#\ˆD‰\ˆDþu8‹]‹Mì! ë1OເÓë‹Mü|8ŒˆÄ÷Ó!þ‰]ìu ‹]‹Mì!Kë‹]‹J‹zƒ}ø‰y‹J‹z‰y„”‹Mô‹|ñ ñ‰z‰J‰Q‹J‰Q‹J;JudŠLƒþ ˆM })þÁ€} ˆLu ¿€‹ÎÓï ;¿€‹ÎÓï‹Mü |ˆDë/þÁ€} ˆLu Nà¿€Óï {‹Mü¼ˆÄNྀÓî 7‹Mø…Ét ‰ ‰Lüë‹Mø‹uðÑN‰ ‰L2ü‹uô‹…Éy‰>u;=u‹Mü; =uƒ%=‹Mü‰B_^[Éá=‹ =VW3ÿ;Áu0D‰PÁàPÿ5=Wÿ5 =ÿpÐ;Çtaƒ=£=¡=‹ =hÄAj€ÿ5 =4ÿÐ;ljFt*jh hWÿlÐ;ljF uÿvWÿ5 =ÿ Ð3ÀëƒNÿ‰>‰~ÿ=‹Fƒÿ‹Æ_^ÃU‹ìQ‹MSVW‹q‹A3Û…À|ÑàCë÷‹Ãj?iÀZ„0D‰Eü‰@‰@ƒÀJuô‹ûjÁçy hh€WÿlÐ…ÀuƒÈÿé“—p;úwt‹Æ4;ósCŠ„Ûu0jX^€;uCFë÷;òsN;Eüu‰që )u 9U ‚™‹}ü‹Ãë¶óÆ4;ur½q;÷s~;EsvŠ„Àu@j^X€;u%C@ë÷;]s +ò‰‰që ƒaq‰1ˆƒÀë6;Âs)E 9U r4‹óë®¶Àðë§;]s +‰‰Aë ƒaA‰ˆFkÉÁà+Áë3À_^[ÉÃÌÌÌU‹ìSVWUjjhä£ÿuèð#]_^[‹å]ËL$÷A¸t‹D$‹T$‰¸ÃSVW‹D$Pjþhì£dÿ5d‰%‹D$ ‹X‹p ƒþÿt.;t$$t(4v‹ ³‰L$‰H ƒ|³uh‹D³è@ÿT³ëÃdƒÄ _^[Ã3Àd‹ yì£u‹Q ‹R 9Qu¸ÃSQ» 0ë SQ» 0‹M‰K‰C‰k Y[ÂÌÌVC20XC00U‹ìƒìSVWUü‹] ‹E÷@…‚‰Eø‹E‰EüEø‰Cü‹s ‹{ƒþÿta vƒ|tEVUkÿT]^‹] Àt3x<‹{Sè©þÿÿƒÄkVSèÞþÿÿƒÄ vj‹Dèaÿÿÿ‹‰C ÿT‹{ v‹4롸ë¸ëUkjÿSèžþÿÿƒÄ]¸]_^[‹å]ÃU‹L$‹)‹AP‹APèyþÿÿƒÄ]¡L7…Àtÿt$ÿÐ…ÀYtjXÃ3ÀÃU‹ìƒìHSVWh€è…Ýÿÿ‹ðY…öujè,èÿÿY‰5<Ç= †€;ðs€fƒÿƒfÆF ¡<ƒÆ$€ëÞE¸Pÿ„Ðfƒ}ê„Ñ‹Eì…À„Æ‹8X;‰Eü¸;ø|‹ø9==}V¾<h€èñÜÿÿ…ÀYt<ƒ= ‰ˆ€;Ás€`ƒÿƒ`Æ@ ‹ƒÀ$Á€ëàƒÆ9==|·ë‹==3ö…ÿ~L‹Eü‹ƒùÿt8Ѝt2¨u Qÿ€Ð…Àt#‹Î‹ÆÁùƒà‹ <À‹Mü‹ ‰Š ˆHƒEüFC;÷|´3Û‹ <Ûƒ<ÿ4uM…ÛÆFujöXë ‹ÃH÷ØÀƒÀõPÿ|ЋøƒÿÿtWÿ€Ð…Àt %ÿ‰>ƒøu€N@ëƒøu €Në€N€Cƒû|—ÿ5=ÿxÐ_^[ÉÃSVW¾<‹…Àt7‹ø€;øs!_ ƒ{ütSÿ4ЋƒÇ$€ƒÃ$;ørâÿ6è²Úÿÿƒ&YƒÆþ=|¸_^[ÃU‹ìjÿh@ÔhĤd¡Pd‰%ƒìSVW‹u¯u ‰u ‰uäƒþàw3Û;óuj^ƒÆƒæð‰u ë3Û‰]àƒþà‡¨¡$=ƒøuA‹}ä;==w|j è’æÿÿY‰]üWè¬ðÿÿY‰EàƒMüÿè9]àt^ÿuäëH3Û‹u j èÆæÿÿYÃøuA;5œ0w9j èOæÿÿYÇEü‹ÆÁèPè øÿÿY‰EàƒMüÿèL9]àtVSÿuàèDƒÄ 9]àu>Vjÿ5 =ÿЉEà9]àu'9H7tVèÃüÿÿY…À…0ÿÿÿë3Û‹u j è=æÿÿYËEà‹Mðd‰ _^[ÉÃSWj3Ûè½åÿÿYj_9=@M~]V¡8=‹÷Áæ‹…ÀtAö@ ƒt PèÒáÿÿƒøÿYtCƒÿ|)¡8=‹ƒÀ Pÿ4С8=ÿ4èÙÿÿ¡8=Yƒ$G;=@M|¥^jè®åÿÿY‹Ã_[ÃV‹t$Vè#…ÀYtƒÈÿ^ÃöF @tÿvè]÷ØY^ÀÃ3À^ÃSV‹t$ 3ÛW‹F ‹Èƒá€ùu7f©t1‹F‹>+ø…ÿ~&WPÿvè´ƒÄ ;Çu‹F ¨€t$ý‰F ëƒN ƒËÿ‹Fƒf‰_‹Ã^[ÃjèYÃSVWj3Û3ÿè¦äÿÿ3öY95@M~t¡8=‹°…Àt_ö@ ƒtYPVèÇßÿÿ¡8=YY‹°‹H öÁƒt0ƒ|$uPèÿÿÿƒøÿYtCëƒ|$uöÁtPèÿÿÿƒøÿYu ø¡8=ÿ4°VèÉßÿÿYYF;5@M|Œjèäÿÿƒ|$Y‹Ãt‹Ç_^[ÃVèuãÿÿÿЃøÿ£Ü0t:jtjèìüÿÿ‹ðY…öYt)Vÿ5Ü0ÿŒÐ…ÀtVè4YÿˆÐƒNÿj‰X^Ã3À^ÃèKãÿÿ¡Ü0ƒøÿtPÿ”Ѓ Ü0ÿËD$Ç@PP2Ç@ÃVWÿÐÿ5Ü0‹øÿœÐ‹ð…öu?jtjèaüÿÿ‹ðY…öYt&Vÿ5Ü0ÿŒÐ…ÀtVè©ÿÿÿYÿˆÐƒNÿ‰ëjèiâÿÿYWÿ˜Ð‹Æ_^áÜ0ƒøÿ„‘V‹t$…öu PÿœÐ‹ð…ötl‹F$…ÀtPèÖÿÿY‹F(…ÀtPèÖÿÿY‹F0…ÀtPèqÖÿÿY‹F8…ÀtPècÖÿÿY‹F@…ÀtPèUÖÿÿY‹FD…ÀtPèGÖÿÿY‹FP=P2tPè6ÖÿÿYVè/ÖÿÿYjÿ5Ü0ÿŒÐ^ÃV‹t$;5=s8‹Î‹ÆÁùƒà‹ <ÀöDtWVèEVè(V‹øè–ƒÄ ‹Ç_^ÃègÞÿÿÇ èeÞÿÿƒ ƒÈÿ^ÃV‹t$WVèɃøÿYt<ƒþtƒþujè²j‹øè©Y;ÇYtVèYPÿ Ð…Àu ÿЋøë3ÿVè‹ÆƒæÁøY‹…< ö€dˆ…ÿt WèiÝÿÿYƒÈÿë3À_^ÃV‹t$‹F ¨ƒt¨tÿvè&Õÿÿff ÷û3ÀY‰‰F‰F^ÃÌÌÌÌÌÌÌÌÌÌÌÌÌW‹|$ëj¤$‹ÿ‹L$W÷ÁtŠA„Àt;÷Áuñ‹ºÿþþ~Ѓðÿ3ƒÁ©tè‹Aü„Àt#„ät©ÿt©ÿtëÍyÿë yþëyýëyü‹L$ ÷ÁtŠA„ÒtdˆG÷Áuî뉃Ǻÿþþ~‹Ѓðÿ3‹ƒÁ©tá„Òt4„öt'÷Âÿt÷Âÿtëlj‹D$_Ãf‰‹D$ÆG_Ãf‰‹D$_È‹D$_ÃS3Û9HMVWu賋5 63ÿŠ:Ãt<=tGVèuYtëè½PèÀÔÿÿ‹ðY;ó‰5L6uj èaßÿÿY‹= 68t9UWè;‹èYE€?=t"Uè‹Ôÿÿ;ÃY‰uj è2ßÿÿYWÿ6è…þÿÿYƒÆYý8uÉ]ÿ5 6ètÓÿÿY‰ 6‰_^ÇDM[ÃU‹ìQQS3Û9HMVWuèõ¾X7hVSÿTС0=‰5\6‹þ8t‹øEøPEüPSSWèM‹Eø‹MüˆPèëÓÿÿ‹ðƒÄ;óujèÞÿÿYEøPEüP‹Eü†PVWè‹EüƒÄH‰5D6_^£@6[ÉÃU‹ì‹M‹ESVƒ!‹uW‹} Ç‹E…ÿt‰7ƒÇ‰} €8"uDŠP@€ú"t)„Òt%¶Òö‚á:t ÿ…ötŠˆF@ÿ…ötÕŠˆFëÎÿ…öt€&F€8"uF@ëCÿ…ötŠˆFŠ@¶Úöƒá:t ÿ…ötŠˆF@€ú t „Òt €ú uÌ„ÒuHë…öt€fÿƒe€8„àŠ€ú t€ú u@ëñ€8„È…ÿt‰7ƒÇ‰} ‹UÿÇE3Û€8\u@Cë÷€8"u,öÃu%3ÿ9}t €x"Pu‹Âë‰}‹} 3Ò9U”‰UÑë‹ÓK…ÒtC…ötÆ\FÿKuóŠ„ÒtJƒ}u €ú t?€ú t:ƒ}t.…öt¶Úöƒá:tˆF@ÿŠˆFë¶Òö‚á:t@ÿÿ@éXÿÿÿ…öt€&Fÿéÿÿÿ…ÿtƒ'‹E_^[ÿ]ÃQQ¡\8SU‹-°ÐVW3Û3ö3ÿ;Ãu3ÿÕ‹ð;ót Ç\8ë(ÿ¬Ð‹ø;û„êÇ\8éƒø…;óu ÿÕ‹ð;ó„Âf9‹Æt@@f9uù@@f9uò+Æ‹=8ÐÑøSS@SSPVSS‰D$4ÿ׋è;ët2UèXÑÿÿ;ÃY‰D$t#SSUPÿt$$VSSÿ×…Àuÿt$èLÐÿÿY‰\$‹\$Vÿ¨Ð‹ÃëSƒøuL;ûu ÿ¬Ð‹ø;ût<8‹Çt @8uû@8uö+Ç@‹èUèñÐÿÿ‹ðY;óu3öë UWVè?ƒÄ Wÿ¤Ð‹Æë3À_^][YYÃjX ¡¨6ƒøt …Àu*ƒ=¬6u!hüè¡`8Y…ÀtÿÐhÿèYÃU‹ì줋U3ɸ˜1;t ƒÀA=(2|ñV‹ñÁæ;–˜1…¡¨6ƒø„è…Àu ƒ=¬6„×úü„ñ…\þÿÿhPjÿTÐ…Àu…\þÿÿhhÚPèúÿÿYY…\þÿÿWP½\þÿÿèŒ@Yƒøƒàt }ø€w …Àu,9uøv'è¬ÏÿÿöEÇ"tƒMøÿë‹E$öØÀ÷ØƉEø…Ût‹Eü‰öEt‹Eø÷؉Eø‹Eøë ‹E …Àt‰83À_^[ÉÃÌÌÌÌÌ‹L$WSVŠ‹|$„ÒtiŠq„ötO‹÷‹L$ŠF8Ðt„Àt ŠF8Ðt „Àuõ^[_3ÀÊF8ðuë~ÿŠa„ät(ŠƒÆ8àuÄŠA„ÀtŠfÿƒÁ8àtßë±3À^[_ŠÂé³ÂÿÿGÿ^[_ËÇ^[_ÃSV‹D$ Àu‹L$‹D$3Ò÷ñ‹Ø‹D$ ÷ñ‹ÓëA‹È‹\$‹T$‹D$ ÑéÑÛÑêÑØ Éuô÷ó‹ð÷d$‹È‹D$÷æÑr;T$wr;D$ vN3Ò‹Æ^[ÂÌÌÌÌÌÌÌÌS‹D$ Àu‹L$‹D$ 3Ò÷ñ‹D$÷ñ‹Â3ÒëP‹È‹\$‹T$ ‹D$ÑéÑÛÑêÑØ Éuô÷ó‹È÷d$‘÷d$Ñr;T$ wr;D$v+D$T$+D$T$ ÷Ú÷؃Ú[ÂS‹\$;=VWsr‹ÃÁø<…<‹Ãƒà4À‹ÁæöD0tRSè‚‹YöD0t)Sè0YPÿ¼Ð…Àu ÿЋðë3ö…ötè—Íÿÿ‰0è‡ÍÿÿÇ ƒÎÿSèšY‹ÆëènÍÿÿÇ ƒÈÿ_^[ÃV‹t$;5=s@‹Î‹ÆÁùƒà‹ <ÀöDt%WVèõÿt$ÿt$Vè(V‹øè>ƒÄ‹Ç_^ÃèÍÿÿÇ è Íÿÿƒ ƒÈÿ^ÃU‹ììSVW3ÿ9}‰}ø‰}ðu3Àéf‹EÁø…<‹Eƒà4À‹ÁæöD0 tjWÿuè>ƒÄ ‹Æö@€„Á‹E 9}‰Eü‰}†ê…ìûÿÿ‹Mü+M ;Ms)‹MüÿEüŠ €ù uÿEðÆ @ˆ@‹È•ìûÿÿ+Êù|Ì‹ø…ìûÿÿ+øEôjP…ìûÿÿWP‹ÿ40ÿ´Ð…ÀtC‹EôEø;Ç| ‹Eü+E ;ErŠ3ÿ‹Eø;Ç…9}tbj^9uuLè÷ËÿÿÇ èõËÿÿ‰0ëAÿЉEëÇMôWQÿuÿu ÿ0ÿ´Ð…Àt ‹Eô‰}‰Eøë§ÿЉEëœÿuè5ËÿÿYƒÈÿë,‹öD0@t ‹E €8„ªþÿÿèˆËÿÿÇè†Ëÿÿ‰8ëÒ+Eð_^[ÉÃV‹t$WVèæƒøÿYu èZËÿÿÇ ë-ÿt$jÿt$PÿÀЋøƒÿÿuÿÐë3À…Àt Pè³ÊÿÿYƒÈÿë‹ÎƒæÁù‹Æ‹ <À€dýD‹Ç_^ËL$V; =WsX‹ÁÁø<…<‹Áƒà4À‹ÁæÆö@t7ƒ8ÿt2ƒ=¬6u3À+ÈtItIuPjôëPjõëPjöÿÄЋƒ 0ÿ3Àëè“ÊÿÿÇ è‘Êÿÿƒ ƒÈÿ_^ËD$;=s‹ÈƒàÁùÀ‹ <öDt‹ÃèOÊÿÿÇ èMÊÿÿƒ ƒÈÿËD$S‹ÈƒàÁùVW‹4<<<ÀÁç÷ƒ~u#jèÞÍÿÿƒ~Yu F Pÿ0ÐÿFjè$ÎÿÿY‹D8 Pÿ Ð_^[ËD$‹ÈƒàÁùÀ‹ <D Pÿ$ÐÃU‹ìƒìSVWjèÍÿÿÿuè•‹ØY;¸9Y‰]u3öép…Û„V3Ò¸à29ttƒÀ0B=Ð3|ñEèPSÿ¸Ðj^;Æ…!j@ƒ%ä;Y3À¿à:9uè󫪉¸9†ë€}M҄¯¶Aÿ¶Ò;‡”€ˆá:@ëîƒeüj@Y3À¿à:4Ró«Á檞ð2€;‹Ët,ŠQ„Òt%¶¶ú;Çw‹UüŠ’Ø2á:@;ÇvõAA€9uÔÿEüƒÃƒ}ürÁ‹EÇÌ9P£¸9èζä2¿À9¥¥Y£ä;¥ëRAA€yÿ…Gÿÿÿ‹Æ€ˆá:@=ÿrñSè•Y£ä;‰5Ì9ëƒ%Ì93À¿À9«««ëƒ=Ì8tè™è½éŒþÿÿƒÎÿjèKÌÿÿY‹Æ_^[ÉËD$ƒ%Ì8ƒøþuÇÌ8ÿ%ÌЃøýuÇÌ8ÿ%ÈЃøüu¡47ÇÌ8ËD$-¤t"ƒètƒè t Ht3ÀøøøøÃWj@Y3À¿à:ó«ª3À¿À9£¸9£Ì9£ä;«««_ÃU‹ììEìVPÿ5¸9ÿ¸Ðƒø…3À¾ˆ„ìþÿÿ@;ÆrôŠEòÆ…ìþÿÿ „Àt7SWUó¶ ¶À;Áw+ȼìþÿÿA¸ ‹ÙÁéó«‹ËƒáóªBBŠBÿ„ÀuÐ_[j…ìúÿÿÿ5ä;ÿ5¸9P…ìþÿÿVPjèbÍÿÿj…ìýÿÿÿ5¸9VP…ìþÿÿVPVÿ5ä;èïÊÿÿj…ìüÿÿÿ5¸9VP…ìþÿÿVPhÿ5ä;èÇÊÿÿƒÄ\3Àìúÿÿf‹öÂt€ˆá:Š”ìýÿÿˆà9ëöÂt€ˆá: Š”ìüÿÿë〠à9@AA;Ær¿ëI3À¾ƒøArƒøZw€ˆá:ŠÈ€Á ˆˆà9ëƒøarƒøzw€ˆá: ŠÈ€é ëà€ à9@;Ær¾^ÉÃ=HMujýèüÿÿYÇHMÃS3Û9Ð8VWuBh°ÚÿÔЋø;ûtg‹5ÐÐh¤ÚWÿÖ…À£Ð8tPh”ÚWÿÖh€ÚW£Ô8ÿÖ£Ø8¡Ô8…ÀtÿЋ؅Ût¡Ø8…ÀtSÿЋØÿt$ÿt$ÿt$SÿÐ8_^[Ã3ÀëøÌÌÌÌÌÌU‹ìWVS‹u ‹}7ƒxu;°ÿ‹ÿ Àt.ŠFŠ'G8Ätò,A<É€á ÁA†à,A<É€á ÁA8àtÒÀÿ¾Àëxðÿ,=ƒ=(=jëðÿ ,=jè—ÈÿÿÇ$¸ÿ3Û Àt'ŠFŠG8ØtòPSèB»ÿÿ‹ØƒÄè8»ÿÿƒÄ8ÃtÚÀƒØÿ‹ØX Àu ðÿ ,=ë jè§ÈÿÿƒÄ‹Ã[^_ÉÃU‹ìWVS‹M É„é‹u‹} 7ƒxuN·A³Z¶ IŠ& äŠt! ÀtFG8ür8Üwæ8ør8ØwÆ8Äu Iu×3É8Ä„›¹ÿÿÿÿ‚÷Ùé‰ðÿ,=ƒ=(=jëðÿ ,=‹Ùjè§ÇÿÿÇ$‹Ë3À3Û‹ÿŠ ÀŠt# ÛtFGQPSèQºÿÿ‹ØƒÄèGºÿÿƒÄY;Ãu IuÕ3É;Ãt ¹ÿÿÿÿr÷ÙX Àu ðÿ ,=ë‹Ùjè¨ÇÿÿƒÄ‹Ë‹Á[^_ÉÃjèlÆÿÿYÃÌÌÌÌÌÌ‹D$‹L$ È‹L$ u ‹D$÷áÂS÷á‹Ø‹D$÷d$Ø‹D$÷áÓ[Âÿ%tÐ$ÝBÝZÝrÝ~݊ݘݬÝÀÝØÝðÝÞÞ,ÞDÞZÞpÞ€ÞÞ¢Þ´ÞÈÞÞÞøÞßß$ß2ßBßPß\ßnß~ߌߞߴßÂßÎߨßèßößàà8àPàjàvà‚à–à¨à¸àÂàÎààà:;<=>?@ÿÿýÿôÿûÿñÿþÿðÿùÿ÷ÿóÿ[\]^_`üÿúÿ øÿ öÿòÿ€`ÿÿÿÿ€ÿÿÿÿÿÿÿÿ`ÿÿÿÿÿÿÿÿ@€`à ÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿ@ÿÿÿÿÿÿÿÿÀÿÿÿÿÿÿÿÿàÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿ ÿÿÿÿЂÿÿÿÿ(ƒÿÿÿÿôƒÿÿÿÿP„ÿÿÿÿRVÿÿÿÿ‘ ‘ÿÿÿÿŠ’Ž’__GLOBAL_HEAP_SELECTED__MSVCRT_HEAP_SELECTEEE50P (8PX700WP `h````ppxxxx(null)(null)ÿÿÿÿ[¨ÿÿÿÿä¨Illegal byte sequenceDirectory not emptyFunction not implementedNo locks availableFilename too longResource deadlock avoidedResult too largeDomain errorBroken pipeToo many linksRead-only file systemInvalid seekNo space left on deviceFile too largeInappropriate I/O control operationToo many open filesToo many open files in systemInvalid argumentIs a directoryNot a directoryNo such deviceImproper linkFile existsResource deviceUnknown errorBad addressPermission deniedNot enough spaceResource temporarily unavailableNo child processesBad file descriptorExec format errorArg list too longNo such device or addressInput/output errorInterrupted function callNo such processNo such file or directoryOperation not permittedNo errorruntime error TLOSS error SING error DOMAIN error R6028 - unable to initialize heap R6027 - not enough space for lowio initialization R6026 - not enough space for stdio initialization R6025 - pure virtual function call R6024 - not enough space for _onexit/atexit table R6019 - unable to open console device R6018 - unexpected heap error R6017 - unexpected multithread lock error R6016 - not enough space for thread data abnormal program termination R6009 - not enough space for environment R6008 - not enough space for arguments R6002 - floating point not loaded Microsoft Visual C++ Runtime Library Runtime Error! Program: ...GetLastActivePopupGetActiveWindowMessageBoxAuser32.dllH:mm:ssdddd, MMMM dd, yyyyM/d/yyPMAMDecemberNovemberOctoberSeptemberAugustJulyJuneAprilMarchFebruaryJanuaryDecNovOctSepAugJulJunMayAprMarFebJanSaturdayFridayThursdayWednesdayTuesdayMondaySundaySatFriThuWedTueMonSunSunMonTueWedThuFriSatJanFebMarAprMayJunJulAugSepOctNovDecHÜ4ÝÐ$ÝBÝZÝrÝ~݊ݘݬÝÀÝØÝðÝÞÞ,ÞDÞZÞpÞ€ÞÞ¢Þ´ÞÈÞÞÞøÞßß$ß2ßBßPß\ßnß~ߌߞߴßÂßÎߨßèßößàà8àPàjàvà‚à–à¨à¸àÂàÎàààGetLastErrorKERNEL32.dll­InterlockedDecrement°InterlockedIncrementŸHeapFree™HeapAlloc}ExitProcessžTerminateProcess÷GetCurrentProcessfEnterCriticalSectionÁLeaveCriticalSectionÊGetCommandLineAtGetVersionªInitializeCriticalSectionUDeleteCriticalSectionÒWideCharToMultiByteäMultiByteToWideChar¿LCMapStringAÀLCMapStringWSGetStringTypeAVGetStringTypeW&GetModuleHandleA$GetModuleFileNameA GetEnvironmentVariableAuGetVersionExAHeapDestroy›HeapCreate¿VirtualFree»VirtualAlloc¢HeapReAlloc/RtlUnwindmSetHandleCountRGetStdHandleGetFileTypePGetStartupInfoAúGetCurrentThreadId¥TlsSetValue¢TlsAlloc£TlsFreeqSetLastError¤TlsGetValueCloseHandle²FreeEnvironmentStringsA³FreeEnvironmentStringsWGetEnvironmentStringsGetEnvironmentStringsWßWriteFile¿GetCPInfoªFlushFileBuffersjSetFilePointer|SetStdHandle¹GetACP1GetOEMCP>GetProcAddressÂLoadLibraryAŒÌ?Öáádá°áø5Ð`` SõPPÐ` °õ°x ßáìáùáââ3â=âGâ[âtâ‚â›â±âÄâÜâæâöâã ã pcre.dllpcre_calloutpcre_compilepcre_configpcre_copy_named_substringpcre_copy_substringpcre_execpcre_freepcre_free_substringpcre_free_substring_listpcre_fullinfopcre_get_named_substringpcre_get_stringnumberpcre_get_substringpcre_get_substring_listpcre_infopcre_maketablespcre_mallocpcre_studypcre_version&‰ÅΉ  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ>ÿ~~ÿþÿÿþÿÿÿþÿÿ‡þÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿüøxÿÿÿÿ€€€€€€€€€€€€€*+?{^.$|()[!!´ù¬ù¤ùœù”ùŒù„ù|ùtùlùdù\ùTùLùOƒf‚  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ>ÿ~~ÿþÿÿþÿÿÿþÿÿ‡þÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿüøxÿÿÿÿ€€€€€€€€€€€€€xdigitwordspacepunctprintgraphdigitcntrlblankasciialnumupperloweralpha4.4 21-August-2003reference to non-existent subpatterninternal error: code overflowunmatched parenthesesfailed to get memoryregular expression too largeparentheses nested too deeplyunrecognized character after (?assertion expected after (?(malformed number after (?(unrecognized character after (?<syntax error after (?Punrecognized character after (?Pclosing ) for (?C expected(?R or (?digits must be followed by )missing ) after commentmissing terminating ] for character classunknown option bit(s) setthis version of PCRE is not compiled with PCRE_UTF8 supporterroffset passed as NULLunrecognized character follows \\c at end of patternPCRE does not support \L, \l, \N, \P, \p, \U, \u, or \X\ at end of patternnumber too big in {} quantifiernumbers out of order in {} quantifierlookbehind assertion is not fixed length\C not allowed in lookbehind assertionmissing )conditional group contains more than two branchesrecursive call could loop indefinitelytwo named groups have the same namenumber after (?C is > 255invalid condition (?(0)internal error: unexpected repeatnothing to repeatrange out of order in character classinvalid escape sequence in character classunknown POSIX class namePOSIX collating elements are not supportedPOSIX named classes are supported only within a classÿÿÿÿìcä´h¨|ipTl@närØ´s¨uˆxVpLv< xìÿxàÿìÿline-regexpforce PATTERN to match only whole linesline-regexselect non-matching linesinvert-matchprint version information and exitversionuse UTF-8 modeutf-8suppress error messagesno-messagesrecursively scan sub-directoriesrecursiveprint line number with output linesline-numberprint only FILE names containing matchesfiles-with-matchesignore case distinctionsignore-casesuppress the prefixing filename on outputno-filenameprint only a count of matching lines per FILEcountdisplay this help and exithelp´üdü@üèüÈü û„þ\þHþ<$þˆúøþdýÐù$üÌûˆûhúHú0úúøùäúýÈúpý`û`û°þÌþèû0ü þ<ý|üðýDû¤ý ûûÌýä      (6Ô¸¨˜ˆxXL8$ì0úØÈ¸match failedbad argumentbad back referenceexpression too bigbad range inside []unbalanced ()empty expressionbad escape sequencebad classcollation error - not relevantunbalanced []unbalanced {}? * + invalidpattern errorinvalid repeat counts in {}internal errorinvalid UTF-8 stringcharacter value in \x{...} sequence is too largespare erroroperand of unlimited repeat could match the empty string($  üôðìèäàØÔÐÌÈÄÀ¼¸¸¸ÐÌÈÄÀ¼¸¸¸ÐÌÈÄÀ¼¸¸¸ÐÌÈÄÀ¼¸¸°¨ œ”Œˆ„|tl`XLD<4( ÿBraBranumberBraminzeroBrazeroCond refCondOnceReverseAssertB notAssertBAssert notAssertKetRminKetRmaxKetAltCalloutRecurseRefxclassnclassclass{???+?+*?*notchars$^Opt\z\ZAnybyteAny\w\W\s\S\d\D\b\B\G\AEndargument is not a compiled regular expressionunknown or incorrect option bit(s) setšš ((((( H„„„„„„„„„„‚‚‚‚‚‚ .@=@=        ! 5A CPR S WY l m pr € ‚ ƒ„ ‘)ž ¡¤ § ·Î×  5ˆ°6à6ø6È6CCCxxÿÿÿÿÿÿÿÿðñxà “8Ô(Ôÿÿÿÿ ÿÿÿÿ„×l×P×@×$××ôÖàÖÌÖ¸Ö¤Ö€ÖlÖXÖLÖ<Ö,Ö ÖÖÖðÕàÕÌÕ¬Õ˜ÕtÕ<ÖdÕLÕ<Õ$ÕÕÕøÔäÔ<ÖÈÔ<Ö´Ô Ô„ÔpÔXÔ<Ö+ôÙÈÙ œÙ xÙLÙÙøØÌØ”ØlØ4Øü×Ô×xÄ×y´×z¤×ü ×ÿבǑǑǑǑǑÇÀ À–ÀÀŽÀÀÀ‘À’À“Àx ¤`‚y‚!¦ß¡¥Ÿàü@~€ü¨Á£Ú£ þ@þµÁ£Ú£ þAþ¶Ï¢ä¢å¢è¢[þ@~¡þQQÚ^Ú _ÚjÚ2ÓØÞàù1~þØ3ÜÛØÛÔÛÐÛÌÛÈÛÄۼ۴۬۠۔یۀÛ|ÛxÛtÛpÛlÛhÛdÛ`Û\ÛXÛTÛPÛHÛ<Û4Û,ÛlÛ$ÛÛÛÛÛôÚèÚäÚàÚØÚÄÚ¼Ú.ˆ4ä8ä8ä8ä8ä8ä8ä8ä8ä84€pðñÿÿPSTPDTÜ45ÿÿÿÿÿÿÿÿÿÿÿÿ;Zx—µÔó0Nmÿÿÿÿ:Yw–´Óò/Ml(€@€X€p€ôˆ€ € ¸ È Ø8Uè XðPDD4VS_VERSION_INFO½ïþv7v7? ¢StringFileInfo~040904E4*CompanyNamePcreBLicensesee: contrib/LICENSEŠ1FileDescriptionPcre: Perl-compatible regular-expression library>FileVersion4.4.1335.303528LibToolFileVersion0:1:0*InternalNamepcrebLegalCopyright© 2003 University of CambridgeB LegalTrademarksPcre®, pcre®: OriginalFilenamepcre.dll*ProductNamePcreBProductVersion4.4.1335.30352r)SpecialBuildGNU for Win32 <gnuwin32.sourceforge.net>DVarFileInfo$Translation ä( @€€€€€€€€€€€€€ÀÀÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‡337ÿÿÿÿÿÿÿÿÿÿø33338ÿÿÿÿÿÿÿÿÿÿƒ33333ÿÿÿÿÿÿÿÿÿ;»»333?ÿÿÿÿÿÿÿÿÿ»»»»337ÿÿÿÿÿÿÿÿÿ»»»»³33ÿÿÿÿÿÿÿÿû»»»»³33ÿÿÿÿÿÿÿÿÿ»ˆ‹»»33ÿÿÿÿÿÿÿÿû¸ˆ‹»»33ÿÿÿÿÿÿÿÿÿ»ÿø»»33ÿÿÿÿÿÿÿÿÿ¸ˆ‹»»37ÿÿÿÿÿÿÿÿÿ‹¸‹»¿ÿÿÿÿÿÿÿÿÿÿÿ‹»»»¿ÌÏÿüÏÿÿÌÌÿÿø‹»»¿ÌÏÿüÏÿÌÌÌÌÿÿˆ{»¿ÌÏÿÌÏüÌÌÌÌÿÿÿÿÿÿÌÏüÌÏüÌÿÿüÿÿÿÿÿÿÌÏüÌÏÌÌÿÿÿÿÿÿÿÿÿÌÏÌÌÿÌÌÌÌÌÿÿÿÿÿÿÌÌÌÏÿÌÌÌÌÌÿÿÿÿÿÿÌÌÌÌÿÌÌÿÌÌÿÿÿÿÿÿÌÌÌÌÏüÌÿÌÏÿÿÿÿÿÿÌÏÿÌÏüÌÿÌÏÿÿÿÿÿÿÌÏÿÌÏÿÌÌÌÿÿÿÿÿÿÿÌÏÿÌÏÿÿÌÏÿÿÿÿÿÿÿÌÏÿÌÏÿÿÿÿÿÿÿÿÿÿÿÌÌÌÌÏÿÿÿÿÿÿÿÿÿÿÿÌÌÌÌÏÿÿÿÿÿÿÿÿÿÿÿÌÌÌÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ èŒÑ1W2‡23J3e3Ÿ3´3ö3 4K4_4³4È4ð4595P5‰5 5Ù5í5#676Ž6¢6´6Ì6â6÷6 7!767N7i7¡7^8,9094989<9@9D9H9L9P9T9l9¸9¼9À9Ä9È90:R:n:Š:A;H;1?8?‡?™?ø? ¨ 01/1A1³1º1535m5‹5·5ñ56I6i6¤6Â6ÿ6(7A78;8L8Y8l9p9t9x9|9€9„9ˆ9Œ9ì9ð9ô9ø9ü9::: :D:H:L:P:T:X:\:`:d:h:Ü:ÿ:;%;1;R;k;ä;1<^0D0011}1Õ12 2$2(2,2024282<2@2D2˜2œ2 2¤2¨2¬2°2´2È3Ï3…55Å6@°}0„0õ0ç12q4‹4Q5X56:=:m:Œ:³:Æ:î:;/;W;z;˜;·;É;Ô;æ;ü;<<< <<<<< <$<(<¬<°<´<¸<¼<À<Ä<È<Ì<Ð<Ô<Ø<Ü<à<ä<è<ì<ð<(=,=0=4=8=<=@=D=µ=»=>õ>ü>?&?T?X?\?`? ?¤?¨?¬?°?´?¸?¼?ß?æ?P404080<0@0‘0¨0°0Ë0È2Ï2H3L3P3T3X35n8Ú8 ::…;`,1 11$12 21282±3¾3ö45ú56O6˜:w;¤;pk4,5 6¤6¨6¬6°6´6¸6¼6À6Ä6È6Ì6Ð6Ô6Ø6Ü6à6ä6è6ì6ð6ô6ø6ü6777 77777 7$7(7,7074787<7@7D7H7L7 7¤7°7´7À7Ä7È7Ì7Ð7Ô7Ø7Ü7à7ä7è7ì7ð7ô7ø7ü7888 8888ö8j9x9¯9þ9:µ:<>>> >$>(>,>0>4>8><>@>D>?œ?¤?ª?°?ñ?€`#070K0Œ0Ë0Ú011L1T1Z1`1¡1Ù1ë1þ1:2l2q2•263<3Q3“3˜3±3¿34p4v4È4à4ç4ï4ô4ø4ü4%5K5e5l5p5t5x5|5€5„5ˆ5Ò5Ø5Ü5à5ä5J6U6p6w6|6€6„6¡6Ë6ý677 77777 7j7p7t7x7|7 888#8(8`8l8s8ƒ8‰88š8³8»8À8Ì8Ñ8î8ô8'9A9O9]9h9|9‚99™9ª9Æ9Õ9ç9ð9 :/:9:B:^::•:¢:Ç:<¤<³<»<Æ<Ì<Ò<Ü<ô<ù<==+=3=9=|=Ž=ê=>>0>:>@>H>P>X>d>i>u>}>…>>£>«>³>»>Ã>Ö>Þ> ?&?6?>!>'>/>8>A>Ç>Í>Ø>Þ>ú>? ??*?0?8?G??Œ?ì? È0‡00¦0]1j1y1Ú1/2€2Ø34‚4œ4¥45Û5á566I6P6e6—6¡6Â6×6û6%737d7j7w7˜7½7Í7Ò78-8p8¹8¿8Í899F9S9X9e9q9+:2:K::Ÿ:Ä:Ì:æ:ì:ý:;";(;5;E;K;S;q;w;ˆ;Ÿ;©;Â;$<<d>–>¦>é>õ>ÿ>?!?.?3?9?”?›?ã?°È(0 1$1Y1a1{1‡1—1Ö1&292w22ž2°2Ö2ã2ñ2ü2363E3‡3›3¹3Å3á3ö3 44è5666666E6k6…6Œ66”6˜6œ6 6¤6¨6ò6ø6ü677j7u77—7œ7 7¤7Á7ë78$8(8,8084888<8@8Š88”8˜8œ8°9È9m:„:œ:¯: ==N=X=Ÿ=²=&>Æ>?+?@?´?Á?æ?À¼0010S0€0”0Î0Õ0û01-181Z1v1ƒ11£1¬1¸1ê1ü1 2,222S2]2h2m2u2Œ2¡2§2¯2·2Â2ð2ü2333%3+3n3x3}3‚3‡3 3¦34494J4]4r44ž4«4»4Ü4è4ú455(565?5E5Q5V5`5g5o5u5|55’5®5Î566*6y6©67 77v7Ö7Ð H3T3`3l3|3€3ˆ3Œ3”3˜3H4T4ðd 000Ì4Ð4Ô4Ø4Ü4à4ä4è4ì4ð4ô4ø4ü4555¨>È>Ø>è>x0|0€0„00˜0°0´0à0ä0è0ì0ð0ô0ø0ü0111 11111 1$1(1,1014181<1@1D1H1L1P1T1X1\1`1d1h1l1p1t1x1|1€1„1ˆ1Œ1œ1¤1¬1´1¼1Ä1Ì1Ô1Ü1ä1ì1ô1ü12 222$2024282<2@2D2Ð3Ø3Ü3à3ä3è3ì3ð3ô3ø3ü3444 44444 4$4(4,4044484<4@4D4H4L4P4T4X4\4`4d4h4l4p4t4x4|4€44”4˜4œ4 4¤4¨4¬4°4´4À4\5`5snort-2.9.15.1/src/win32/WIN32-Prj/zlib1.dll0000555000175200017520000022000013571422610014637 00000000000000MZÿÿ¸@𺴠Í!¸LÍ!This program cannot be run in DOS mode. $IÒ~W(¼-W(¼-W(¼-Ô á-U(¼-Ô4²-V(¼-87¶-R(¼-87¸-T(¼-W(½-A(¼-a¶-[(¼-.º-V(¼-¨¸-V(¼-RichW(¼-PELQ<_Kà! €j›  €ß]ðÝ<˜¤ X.text.Œ `.rdataÝC P @@.dataèðð@À.rsrc˜@@.reloc @B‹L$S‹\$VW‹ùÁïáÿÿƒûu3‹T$3ÀŠÈùñÿréñÿùÿñÿrïñÿ‹Ç_Áà^ Á[Ët$…öu _^¸[Ãûs:‹ÃK…ÀtC3ÒŠÊFùHuôùñÿréñÿ‹Ç3Ò¾ñÿ_÷ö^[‹ÂÁà ÁÃû°U‚Ö¸¯©n^÷ãÁê ‰T$ë°½[3À3ÒŠŠVÈ3ÀŠFùÊ3ÒŠVùÈ3ÀŠFùÊ3ÒŠVùÈ3ÀŠFùÊ3ÒŠVùÈ3ÀŠFùÊ3ÒŠV ùÈ3ÀŠF ùÊ3ÒŠV ùÈ3ÀŠF ùÊ3ÒŠV ùÈ3ÀŠFùÊ3ÒŠVùȃÆùÊùM…gÿÿÿ‹Á3Ò¹ñÿ÷ñ‹Ç¿ñÿ‹Ê3Ò÷÷ÿL$‹ú…8ÿÿÿ…Û„Úƒû‚¡‹ëÁí3Ò3ÀŠŠFÊ3ÒŠVùÈ3ÀŠFùÊ3ÒŠVùÈ3ÀŠFùÊ3ÒŠVùÈ3ÀŠFùÊ3ÒŠVùÈ3ÀŠF ùÊ3ÒŠV ùÈ3ÀŠF ùÊ3ÒŠV ùÈ3ÀŠF ùÊ3ÒŠVùÈ3ÀŠFùʃëùÈùƒÆM…dÿÿÿ‹ÓK…ÒtC3ÒŠÊFùHuô‹Á3Ò¹ñÿ¾ñÿ÷ñ‹Ç‹Ê3Ò÷ö‹ú‹Ç]Áà_^ Á[Ãì8‹L$H‹T$<‹D$DS‹\$DV‰L$ ‹L$T‰T$j8‰D$ ‹hðT$QR‰D$(ÇD$8ÇD$<ÇD$@軃ąÀuGD$jPè ‹ðƒÄƒþtL$QètƒÄ¸ûÿÿÿ…öt‹Æ^[ƒÄ8ËT$D$P‰èPƒÄ^[ƒÄ8ËD$‹L$ ‹T$jÿP‹D$ QRPè5ÿÿÿƒÄËD$‹È‹ÐÁéÁê ÁD øX ËD$…ÀuËL$ ‹T$QPRèƒÄ ËD$‹L$SUVW‹|$…ÿ÷Ðt#öÁt‹Ð3ÛŠâÿ3ÓÁè‹•X 3ÂAOu݃ÿ ‹ñ‚!‹ïÁí‹3É3Â3ÒŠÔ‰D$ŠL$ƒÆ‹•X¨‹Ð‹ X¤%ÿÁê3˃Æ‹•X ‹Vü3Ë‹…X¬3Ë3À3Ê3ÒŠÕ‰L$ŠD$ƒÆ‹•X¨‹Ñ‹…X¤áÿÁê3ÃÆ‹•X ‹Vø3ËX¬3Ã3É3Â3ÒŠÔ‰D$ŠL$ƒÆ‹•X¨‹Ð‹ X¤%ÿÁê3Ë‹•X ‹Vø3Ë‹…X¬3Ë3À3Ê3ÒŠÕ‰L$ŠD$‹•X¨‹Ñ‹…X¤áÿÁê3Ë•X ‹Vü3ËX¬3Ã3É3Â3Ò‰D$ŠÔŠL$‹ X¤‹•X¨‹ÐÁê3Ë%ÿ‹•X ‹3Ë‹…X¬3Ë3À3Ê3ÒŠÕ‰L$ŠD$ƒÆ‹•X¨‹Ñ‹…X¤áÿÁê3ÃÆ‹•X ‹Vü3ËX¬3Ã3É3Â3ÒŠÔ‰D$ŠL$ƒÆ‹•X¨‹Ð‹ X¤%ÿÁê3Ëƒï ‹•X ‹Vü3Ë‹…X¬3Ë3À3Ê3ÒŠÕ‰L$ŠD$‹•X¨‹Ñ‹…X¤áÿÁê3Ë•X 3ËX¬3ÃM…äýÿÿƒÿrN‹ïÁí‹3É3Â3ÒŠÔ‰D$ŠL$ƒÆ‹•X¨‹Ð‹ X¤%ÿÁê3˃ï‹•X 3Ë‹…X¬3ËM‹Áu·…ÿt‹È3ÒŠáÿ3ÊÁè‹ X 3ÁFOuâ_^][÷ÐËD$‹L$ ‹T$P‹D$QjjjjRPèƒÄ ËD$S3ÒUV;ÂW½„ ŠŠ Á:Á…úƒ|$08…ï‹|$;úu _^]¸þÿÿÿ[ËG ‰W;Âu ÇG `š‰W(9W$uÇG$€š‹L$ƒùÿu ÇD$‹L$‹\$ ;Ú}3í÷Ûë ƒû~½ƒë‹D$$ƒø|ƒø ˜ƒ|$u‘ƒû|Œƒû‡;Ê|ƒƒù zÿÿÿ‹D$(;ÂŒnÿÿÿƒøeÿÿÿƒûu» ‹O(hÀjQÿW ‹ðƒÄ …öu _^]¸üÿÿÿ[Éw‰n‰^0‹Ë‹\$$½ÓåK¸Óà‰NPƒÁ‰>ÇFUÿ‰n,‰FLH‰FT¸«ªªª‰V4÷áÑê‰VX‹G(jUPÿW ‹N,‰F8‹W(jQRÿW ‰F@‹FL‹O(jPQÿW ‰FDK¸jÓà‰†œ‹W(PRÿW ‹ŽœƒÄ0‰F‰V ‹V8…ÒtP‹V@…ÒtI‹VD…ÒtB…Àt>‹ÑWÑêÆF$PHȉ–¤‹T$,‰Ž˜‹L$‰–ˆ‰Ž„èIƒÄ_^][ÃÇFš¡àÝW‰Gèœ ƒÄ¸üÿÿÿ_^][Ã_^]¸úÿÿÿ[ËD$SUVW‹|$…À‹ï„ï‹X…Û„ä‹t$…ö„Ø‹Kƒù„̃ùu ƒ{*…½‹K…Ét‹@0WVPèÆöÿÿ‹L$ ƒÄ ‰A0ƒÿs_^]3À[ËC,úþÿÿ;øv‹è+ý÷‹{8‹Í‹Ñ3ÀÁéó¥‹Êƒáó¤‹s8‹KX‰kl‰k\ЉCHÓà3ÉŠNuý3Á‹KT#Á3Ò‰CH‹C8‹{H3É‹k@ŠL‹Á‹KXÓç‹KT3Ç‹{4#Á‹KD‰CH#úf‹Af‰D}‹KH‹CDf‰HB;ÖvÀ_^]3À[Ã_^]¸þÿÿÿ[ÃSVW‹|$3Û;ûtz‹w;óts9_ tn9_$ti‰_‰_‰_ÇG,‹F‰^‰F‹F;Ã}÷؉F‹FS‹ÈS÷ÙÉSƒá¹ƒÁqƒø‰Nuèùÿÿëè§õÿÿƒÄ ‰G0‰^(VèˆcVèb ƒÄ3À_^[Ã_^¸þÿÿÿ[ËT$…Òt,‹B…Àt%‹L$‰ˆ¼¸Óà‹L$ H#Á‹Jf‰¸3ÀøþÿÿÿËT$S3ÀU…ÒW„Ä‹z…ÿ„¹‹\$ƒûÿu»ë…ÛŒ¡ƒû ˜‹l$…파ƒýƒ‹„V4[ IÁæ‹ ˜À;Ž˜Àt‹J…Ét jRè°ƒÄ9Ÿ„t?3Ò‰Ÿ„f‹–’À3ɉ—€f‹ŽÀ3Ò‰Œf‹–”À3ɉ—f‹Ž–À‰O|‰¯ˆ^_][Ã_]¸þÿÿÿ[ËT$V‹òWB?JÁèÁéðD1 ‹L$ …Ét!‹I…Ét‹y0¾;þu9qPu Rè`÷ÿÿƒÄ_^ÃSU‹l$ V…íW„—‹u…ö„Œ‹L$ƒù…ÉŒw‹E …À„cƒ}u ‹E…À…R‹F=šu ƒù…?‹U…Òu¡äÝ_‰E^]¸ûÿÿÿ[ËV(ƒø*‰.‰T$‰N(»…à9^…4jjjèÚöÿÿ‰E0‹F‹NƒÄ Æ‹F‹V@‰FÆ‹‹~‹NG‹Ç‰~Æ‹V‹FB…À‰V‹ú…š‹Vˆ:‹~‹NG‹Ç‰~Æ‹VB‰V‹Â‹VÆ‹NA‰N‹Á‹NÆ‹F‹V@‰FÆ‹~‹†„Gƒø ‰~‹Ïu‹Ãë9žˆ};Ã|3À븋Vˆ ‹NA‰N‹Á‹NÆ ‹F@ÇFq‰Féð‹P$‹H,÷ÚÒƒâ÷ÙÉ#ËÑ‹H÷ÙɃáÑ‹H÷ÙɃáÑ‹…É‹N•ÀЈ9‹~‹V‹NG‰~ŠR‹Çˆ‹V‹NB‰V‹Â‹Q‹NÁꈋF‹V@‰F‹J‹VÁéˆ ‹V‹NB‰V‹Â‹Q‹NÁꈋ~‹†„Gƒø ‰~‹Ïu‹Ãë9žˆ};Ã|3À븋Vˆ ‹^‹N‹VC‰^ŠI ‹Ãˆ ‹~‹FG‰~‹Ï‹P…Òt*‹VŠ@ˆ ‹V‹NB‰V‹Â‹Q‹NÁꈋF@‰F‹È‹V‹B,…Àt‹FQ‹M0PQèÊôÿÿƒÄ ‰E0ÇF ÇFE飋N0‹†ˆÁá éx;Ã}$‹†„;Ã|ƒø}¸ë3Òƒø•ÂÓ‹Âë3ÀÁà È‹Fl…ÀtƒÉ ‹Á3Ò¿ÇFq÷÷+ÊÏQV艋FlƒÄ…Àt ‹E0ÁèPVèr‹M0áÿÿQVèbƒÄjjjè¤ðÿÿƒÄ ‰E0ƒ~E…Ô‹V‹B…À„¿‹B‹~ ‹N%ÿÿ;øsr‹F‹~ ;Çu8‹z,…ÿt;Áv‹V+ÁP‹E0ÑRPè½óÿÿƒÄ ‰E0Uè!‹F‹V ƒÄ;‹Èt0‹V‹~ ‹^‹RŠ:ˆ‹V‹F B‰V‹V@‰F ‹zçÿÿ;ÇrŽ‹F‹P,…Òt‹F;Áv‹V+ÁP‹E0ÑRPèOóÿÿƒÄ ‰E0‹N‹V ;QuÇF ÇFIƒ~I…¸‹F‹H…É„£‹V‹F‹N ;Áu;‹N‹y,…ÿt;Âv‹M0+ÂP‹FÂPQèëòÿÿƒÄ ‰E0UèO‹F‹N ƒÄ;Á‹Ðt&‹~‹N 3ÛA‹Š\ÿ‰N ‹Nˆ‹NA…Û‰Ntë•»‹F‹H,…Ét‹F;Âv‹N+ÂÊ‹U0PQRè‚òÿÿƒÄ ‰E0…Ûu ‰^ ÇF[ƒ~[…µ‹F‹H$…É„ ‹V‹F‹N ;Áu;‹N‹y,…ÿt;Âv‹M0+ÂP‹FÂPQè)òÿÿƒÄ ‰E0Uè‹F‹N ƒÄ;Á‹Ðt&‹~‹N 3ÛA‹$Š\ÿ‰N ‹Nˆ‹NA…Û‰Ntë•»‹F‹H,…Ét‹F;Âv‹N+ÂÊ‹U0PQRèÀñÿÿƒÄ ‰E0…ÛuÇFgƒ~guj‹F‹H,…ÉtY‹N‹F ƒÁ;Èv UèüƒÄ‹F‹N P;Ñw=‹NŠU0jjˆ‹~‹VG‰~‹M0‹ÇjÁéˆ ‹F@‰FèLñÿÿƒÄ ‰E0ÇFq‹F…ÀtU袋EƒÄ…Àu8ÇF(ÿÿÿÿ_^]3À[ËE…Àu#‹|$‹D$;øƒÿt¡äÝ_‰E^]¸ûÿÿÿ[Ë|$‹F‹M=šu…Ét‹ äÝ_‰M^]¸ûÿÿÿ[Ã…Éu‹Nt…Éu…ÿ„³=š„¨‹†„WV@ÿ•˜ÀƒÄƒøtƒøuÇFš…À„…ƒø„|ƒøul;øu Vèt\ƒÄë;jjjVèÃ[ƒÄƒÿu'‹FL‹NDfÇDAþ‹VL‹~D3ÀLþ‹ÑÁéó«‹ÊƒáóªU莋EƒÄ…ÀuÇF(ÿÿÿÿ_^]3À[Ë|$ƒÿt_^]3À[ËF…À _^]¸[Ãø…¡‹F‹NŠU0ˆ‹~‹VG‰~‹M0‹ÇÁéˆ ‹F‹V@‰F‹M0Áéˆ ‹~‹VG‰~‹M0‹ÇÁéˆ ‹^‹NC‰^ŠU‹Ãˆ‹~‹VG‰~‹M‹ÇÁéˆ ‹F‹V@‰F‹MÁéˆ ‹~‹VG‰~‹M‹ÇÁéˆ ‹F@‰Fë ‹E0ÁèPVèn‹M0áÿÿQVè^ƒÄUè…‹FƒÄ…À~÷؉F‹N3À_^…É][”ÀËE…ÀuÇF(ÿÿÿÿ_^]3À[ËØÝ‰U_^]¸þÿÿÿ[ËD$‹L$VW‹p‹x‹ÑÁêˆ>‹P‹pB‰P_ˆ ‹HA^‰HËD$V‹p‹H‹V;Ñv‹Ñ…ÒtX‹v‹ÊS‹ÙW‹x Áéó¥‹Ëƒáó¤‹x ‹Hú‰x ‹qò‰q‹X‹x‹HÚ+ú‰X‰x‹q_+ò[‰q‹@‹H…Éu‹H‰H^ÃV‹t$…öW„¨‹F…À„‹xƒÿ*t!ƒÿEtƒÿItƒÿ[tƒÿgt ƒÿqtÿšut‹@…Àt P‹F(PÿV$ƒÄ‹N‹AD…Àt ‹V(PRÿV$ƒÄ‹F‹@@…Àt ‹N(PQÿV$ƒÄ‹V‹B8…Àt P‹F(PÿV$ƒÄ‹N‹V(QRÿV$ƒÄ3ÀƒÿqÇF•ÀH_$ý^Ã_¸þÿÿÿ^ÃSUV‹t$…öW„•‹l$…턉‹F…À‰D$„z¹‹ýó¥‹E(hÀjPÿU ‹ØƒÄ …Ûu _^]¸üÿÿÿ[Ët$¹°‹û‰]ó¥‹K,‰+‹U(jQRÿU ‰C8‹C,‹M(jPQÿU ‹SL‰C@‹E(jRPÿU ‹‹œ‰CD‹U(jQRÿU ‹{8ƒÄ0…ÿ‰C„Ú‹K@…ɄϋKD…ɄąÀ„¼‹K,‹T$Ñá‹r8‹éÁéó¥‹Íƒáó¤‹K,‹r@‹{@Ñá‹éÁéó¥‹Íƒáó¤‹KL‹rD‹{DÑá‹éÁéó¥‹Íƒáó¤‹K ‹r‹{‹éÁéó¥‹Íƒáó¤‹J‹z‹s+ÏÎ_‰K‹‹œ‹ÑÑêPNʉƒ¤‰‹˜ƒ”‹ˆ “| ^‰ƒ ‰‹$ ‰“0 ]3À[ÃUè¨ýÿÿƒÄ¸üÿÿÿ_^][Ã_^]¸þÿÿÿ[ËT$SV3ö‹B,‹JLÑà‰B<‹BDWf‰tHþ‹JL‹zD3ÀL þ‹ÙÁéó«‹Ëƒá󪋂„3É_@Áàf‹ˆ’À‰Š€3Éf‹ˆÀ‰ŠŒ3Éf‹ˆ”À‰Š3Éf‹ˆ–À‰rl‰r\‰rt¸‰rh‰rH^‰J|‰Bx‰B`[ÃSUV‹t$»ÿÿ‹F ƒÀû;Ãs‹Ø‹l$‹Ftƒøw Vè6‹FtƒÄ…Àu…í„…À„«‹NlÇFtȉNl‹N\‹Vlt;Ðr?+ЉFl…ɉVt|‹V8Ñë3Ò+ÁjPRVèíX‹‹FlQ‰F\èßûÿÿ‹ƒÄ‹B…À„°‹N\‹Vl‹F,+Ñ-;Ђcÿÿÿ…É|‹F8Áë3ÀjRPVè X‹‹NlR‰N\è’ûÿÿ‹ƒÄ‹H…Étgé-ÿÿÿ‹N\…É|‹F8Áë3À3Òƒý”ÂR‹Vl+ÑRPVè[X‹‹FlQ‰F\èMûÿÿ‹ƒÄ‹B…Àu3Àƒý•ÀH^]ƒà[ËÅ^ƒè]÷ØÀ[$þƒÀÃ^]3À[ÃS‹\$UV‹k,W‹S<‹Kt‹Cl+Ñ‹K,+ÐŒ)úþÿÿ;Árq‹{8‹Í‹Á4/Áéó¥‹Èƒáó¤‹sp‹Kl‹C\+õ+͉sp‹sL‰Kl‹KD+ʼnC\ qƒé3Àf‹;År+Åë3ÀNf‰uè‹C@‹õ hƒé3Àf‹;År+Åë3ÀNf‰uèÕ‹‹H…Ét`‹Kt‹slR‹S8ÎÊQPè[‹KtƒÄ È‹ñ‰Ktƒþr$‹Sl‹C8‹KX<3ÀЉCHÓà3ÉŠO3Á‹KT#Á‰CHþs ‹‹B…À… ÿÿÿ_^][ËL$ S‹\$U‹C‹è;év‹é…íu]3À[Ã+ʼnC‹C‹@ƒøu‹ ‹S0UQRèåäÿÿëƒøu‹‹K0UPQèAèÿÿƒÄ ‰C0‹ÍV‹3‹ÑW‹|$Áéó¥‹Êƒáó¤‹C‹ Å͉C_‹Å^‰ ][ÃQUV‹t$W3ÿ‹Ft=s'VèFþÿÿ‹FtƒÄ=s ‹L$…É„2…À„¾ƒørP‹FH‹NX‹Vl‹~8Óà3ÉŠL‹~4#ú‹V@3Á‹NT#Á‹ND‰FHf‹Af‰z‹Nl‹F4‹V@#È‹FH3ÿf‹Ýÿÿ‰EL‹þƒÉÿ3À‰]P‰]Xò®÷ÑQÿ ‹ÐƒÄ;Ó‰UT„ã‹þƒÉÿ3Àò®÷Ñ+ù‹Á‹÷‹ú²rÁéó¥‹Èƒáó¤ˆ]\‹L$8uˆU\Š3íUUU艵ÿÿ‰CÆD$0ÆD$1‹‹KD$0jPQèlµÿÿ‰CƒÄ‰l$Ç‹ÅéÜ‹C ÇC…ÀtÇ@0ÿÿÿÿöC„»‹L$3Ò‹Á%ÿÁàÁéÁ¹÷ñ…Ò…—‹L$‹Ñƒâ€út‹D$TÇ@àñÇ‹Áés‹C$ƒíÁé‰L$ƒáƒÁ;Èv‹L$T‹D$ÇAÌñÇéBº3íÓâUUU‰Sè7±ÿÿ‹T$‹L$`÷ÒâƒÄ €Î ‰CÁê‰A0‰‰l$‹Åé‹D$TÇ@´ñ‹D$Çéèƒýs*…ÿ„93ÉOЉ|$‹Ñ‹ÍÓâƒÅÂFƒý‰D$‰t$rÖ<‰Ct‹L$TÇAàñéœöÄàt‹T$TÇB˜ñ釋K …ÉtÁèƒà‰‹CöÄt%‹D$jˆD$(ÁèˆD$)‹KD$(PQèгÿÿƒÄ ‰C3À3íÇëƒý s …ÿ„–3Ò‹ÍŠOÓâƒÅÂFƒý ‰D$rà‹K …Ét‰A‹CöÄt7‹D$jˆD$(‹È‹ÐÁèÁéÁêˆD$+ˆL$)ˆT$*‹KD$(PQèV³ÿÿƒÄ ‰C3À3íÇëƒýs(…ÿ„3Ò‹ÍŠOÓâƒÅ‰|$ÂFƒý‰D$‰t$rØ‹K …Ét‹Ðâÿ‰Q‹K Áè‰A ‹CöÄt%‹D$T$$ˆD$$jÁèˆD$)‹CRPèÕ²ÿÿƒÄ ‰C3À3í‰D$Ç‹KöÅtsƒýs*…ÿ„‘3ÉOЉ|$‹Ñ‹ÍÓâƒÅÂFƒý‰D$‰t$rÖ‹K ‰C@…Ét‰A‹CöÄt%‹D$jˆD$(ÁèˆD$)‹KD$(PQèV²ÿÿƒÄ ‰C3À3í‰D$ë‹K …ÉtÇAÇ‹KöÅ„¬‹K@;ωL$v‹Ï‰L$…É„ˆ‹S …ÒtH‹R…Ò‰T$8t=‹S ‹s@‹z‹R+þ49;òv+׋ʋT$8‹t$ú‹ÑÁéó¥‹Êƒáó¤‹L$‹|$‹t$‹SöÆt‹D$‹KPVQè§±ÿÿ‹L$(‰C‹D$ƒÄ ‹S@+ùñ+щ|$‰t$‰S@‹K@…É…_ÇC@Ç‹KöÅ„–…ÿ„>3Ò3ÉŠ 2B‰T$‹S …Ò‰L$,t,‹R…Ò‰T$8t!‹K ‹S@;Q ‹L$,s‹|$8ˆ ‹S@‹|$B‰S@…Ét‹T$;×r³‹SöÆt‹T$‹CRVPèó°ÿÿ‹L$8‰C‹D$ƒÄ ‹T$+úò…ɉ|$‰t$…²ë‹K …ÉtÇAÇC@Ç‹KöÅ„–…ÿ„3Ò3ÉŠ 2B‰T$‹S …Ò‰L$,t,‹R$…Ò‰T$8t!‹K ‹S@;Q(‹L$,s‹|$8ˆ ‹S@‹|$B‰S@…Ét‹T$;×r³‹SöÆt‹L$‹SQVRè6°ÿÿ‹L$8‰C‹D$ƒÄ ‹T$+úò…ɉ|$‰t$…õë‹K …ÉtÇA$Ç‹KöÅtRƒýs*…ÿ„Ê3ÉOЉ|$‹Ñ‹ÍÓâƒÅÂFƒý‰D$‰t$rÖ‹Káÿÿ;Át‹T$TÇB„ñé'3í‰l$‹C …Àt‹KÁù ƒá‰H,‹S ÇB0jjjèx¯ÿÿ‹L$`‰CƒÄ ‰A0‹D$Ç éã ƒý s(…ÿ„43Ò‹ÍŠOÓâƒÅ‰|$ÂFƒý ‰D$‰t$r؋ȋÐáÿâÿÁáÊ3ÒŠt$ÁáÊÁèÁ‹L$T‰C‰A03À‰D$3íÇ ‹K …É„† jjjèl«ÿÿ‹T$`‰CƒÄ ‰B0‹D$Ç ƒ|$X„Ÿ ‹K…Ét‹ÍǃáÓè+é‰D$é" ƒýs&…ÿ„s 3ÉOЉ|$‹Ñ‹ÍÓâƒÅÂFƒý‰t$rڋȃáÑè‰K‹ÈƒáMƒù‰D$wdÿ$èsÁèÇ ‰D$ƒíé SèÅ‹D$ƒÄÁèljD$ƒíé  ÁèljD$ƒíé‹ ‹T$TÇB@ñÇÁè‰D$ƒíék ‹ÍƒáÓè+éƒý ‰D$s*…ÿ„¯ 3ÉOЉ|$‹Ñ‹ÍÓâƒÅÂFƒý ‰D$‰t$r֋ЋÈ÷ÒáÿÿÁê;Êt‹L$TÇA ñé 3À‰K@‰D$3íÇ‹K@…ɉL$„7;Ïv‹Ï‰L$‹T$ ;Êv‹Ê‰L$…É„* ‹t$‹|$(‹ÑÁéó¥‹Ê‹T$ƒáó¤‹L$‹t$‹|$ +ñщt$‹t$(‰T$‹S@+ùñ+щ|$ ‹|$‰t$(‹t$‰S@éu ƒýs&…ÿ„Æ 3ÉOЉ|$‹Ñ‹ÍÓâƒÅÂFƒý‰t$rڋȃíƒáÁèÁ‹ÐÁè‰K`‹ÈƒáƒâƒÁB‰K\‹K`Áèù‰Sd‰D$‡ÿ‹Êƒù‡ôÇChÇ‹Kh‹S\;Ês^ƒýs$…ÿ„8 3Ò‹ÍŠOÓâƒÅ‰|$ÂFƒý‰t$rÜ‹Sh3ÿŠÈƒíf‹abÀbvcd~d«d¶dŒeüe‚fgh[knmÀm@oºo‚p¬pžqCrMr¥r e5eWele‹D$Ç@LÀÉÇ@T Ç@PÀÑÇ@XÃSU‹l$ V3ö‹]9s4u'‹K$¸Óà‹M(jPQÿU ƒÄ ;ƉC4u ^]¸[Ã9s(u‹K$ºÓâ‰s0‰s,‰S(‹D$‹u‹K(+Æ;ÁWr*‹u ‹{4+ñ‹ÁÁéó¥‹Èƒá3Àó¤‹K(_^ÇC0‰K,][Ã+K0;ȉL$v‹È‰L$‹{4‹S0‹u ú‹Ñ+ðÁéó¥‹Êƒáó¤‹L$+Át(‹u ‹{4‹È+ð‹ÑÁéó¥‹Êƒáó¤‰C0‹C(_^‰C,]3À[Ë{0‹C(ù‹×‰{0;ÐuÇC0‹S,;ÐsщS,_^]3À[ÃV‹t$…öt8‹F…Àt1‹N$…Ét*‹@4…Àt P‹F(PÿуÄ‹N‹V(QRÿV$ƒÄÇF3À^øþÿÿÿ^ÃSUVW‹|$…ÿt‹_…Ût‹C…À‹tƒø t _^]¸þÿÿÿ[Ãø ‹l$‹t$u'jjjèšÿÿUVPèšÿÿ‹KƒÄ;Át _^]¸ýÿÿÿ[ËGPWè'þÿÿƒÄ…Àt_^Ç]¸üÿÿÿ[ËC(;èv+‹{4‹È+ð‹ÑõÁéó¥‹Êƒáó¤‹C(_^‰C,ÇC ]3À[Ë{4‹Í+ý‹Ñø3ÀÁéó¥‹Êƒáó¤_‰k,^ÇC ][ÃSUVW‹|$…ÿ„á‹w…ö„Ö‹G…Àuƒ~<s _^]¸ûÿÿÿ[Ã>t_‹F<‹n8‹ÈǃáÓå+Á3Ƀø‰F<‰n8r%¸øÿÿÿŠV8ˆT ‹^<‹n8Ø‹ÓAÁíƒú‰n8‰^‹„$œÆD$@ÆD$f‰l$‹‹L$_‰ ‹ƒÂ‰‰ ‹ƒÁ‰Ç^]3À[ƒÄ|ùD$Nfƒ8u AƒÀƒùvñ;Ñs‰L$¾T$N‹Æ3ÿöf‹:+÷x@ƒÂƒøvì3Ò;ò~9”$tƒýt _^]ƒÈÿ[ƒÄ|Ãf‰T$n3Àf‹tNftnƒÀƒøf‰tnr鋼$¤;Úv5‹´$”f‹f…Àt%ÿÿ3íf‹lDl3Àf‰of‹fÿDDlDDlBƒÆ;ÓrÒ‹„$ºÿÿÿÿƒèt?HtÇD$4ÓÇD$0XÓ‰T$,ë6¸˜ÒÇD$,-‰D$4¸ØÒ-‰D$0ë‰|$0‰|$4ÇD$,‹Ù‹Œ$œ3í‰T$8‹‹L$‰D$¸Óà‰l$‰D$<‰D$(Hÿ‰L$@‹Œ$ƒùu =°ƒp‰|$$‹T$‹L$$‹t$,ŠÃf‹ *ˆD$‹Á%ÿÿ;Æ} ÆD$f‰L$ë(~‹L$0Š AˆL$‹L$4f‹Af‰D$ë ÆD$`fÇD$‹Ë‹D$<+ʺÓâ‹L$‹ýÓï‹L$‰D$D4•ø ¹‹|$+Â+Î…À‰9uöKÿ¸Óà…ÅtÑè…Åuú3ö;Æt Pÿ#ÕЋêë3í‹T$$ƒÂfÿL\Lf9t\L‰T$$u;\$ „ë‹Ê‹”$”3À3Ûf‹f‹B;\$† ÿÿÿ‹t$@‹D$8#õ;ð‰t$H„õþÿÿ‹T$…Òu ‹D$‰D$‹Ð‹L$‹D$D‹|$ ¸‰L$‹Ë+ÊÑÓà;×s"tTL3ÿf‹>+Ç…À~‹|$ ABƒÆÑà;×ræ‹t$H‹T$(¸Óà‰D$<Ћ„$‰T$(ƒøu ‹Â=°ƒÛ‹Ö‹´$œ‰T$8‹ˆ ‹ŠD$ˆD‘‹‹L$+ÈÁùf‰Lé>þÿÿ‹T$ŠÃ*Â;îÆD$@ˆD$f‰t$ta;Öt)‹L$@‹D$8#Í;Èt‹”$œ‹\$‰t$ˆ\$‹‹Ö‰D$‹|$‹Å‹ÊÓè‹L$‰ ‡Kÿ¸Óà…ÅtÑè…Åuú;Æt Hÿ#ÍÈ‹éuŸ‹T$(‹„$œ_^ •‹Ñ]‰‹”$”‹D$[‰3ÀƒÄ|Ã_^]¸[ƒÄ|Ãèk‹D$Pˆ”ˆ ‰ˆ ˆ| ‰ˆ0 3ÉÇ€ ò‰$ Ç€, òÇ€8 0òf‰ˆ¸‰ˆ¼Ç€´èYÃËT$V¹3ö‚”f‰0ƒÀIu÷‚ˆ ¹f‰0ƒÀIu÷‚| ¹f‰0ƒÀIu÷‰²¬‰²¨‰²°‰² fÇ‚”^ËD$‹ˆ¼ƒù ~b‹T$SV‹òÓæ‹HWf °¸‹pŠ˜¸ˆ1‹p‹x3ÉŠˆ¹F‰pˆ 7‹H‹°¼A‰Hf¹f+Î_fÓêƒÆó‰°¼^[f‰¸ë‹T$Óâf ¸ƒÁ‰ˆ¼‹L$ ‹T$jQRPèWƒÄÃSV‹t$ W¸‹Ž¼ƒù ~]‹VÓà‹Nf †¸І¸ˆ‹N‹VA‰N‹Á3ÉŠŽ¹ˆ ‹F@f¹‰F‹†¼f+ȺfÓêƒÀ󉆼f‰–¸ëÓàf †¸ƒÁ‰Ž¼‹Ž¼3Òf‹æØ¸+Â;È¡äØ~^%ÿÿ‹øÓç‹Nf ¾¸‹~Šž¸ˆ9‹~‹^3ÉŠŽ¹G‰~ˆ ;‹N‹¾¼A‰Nf¹f+ÏTðfÓ艖¼f‰†¸ëÓàf †¸Ê‰Ž¼Vè&‹Ž¼‹–´+уă ƒú ƒù ¸~]‹VÓà‹Nf †¸І¸ˆ‹N‹VA‰N‹Á3ÉŠŽ¹ˆ ‹F@f¹‰F‹†¼f+ȺfÓêƒÀ󉆼f‰–¸ëÓàf †¸ƒÁ‰Ž¼‹Ž¼3Òf‹æØ¸+Â;È¡äØ~^%ÿÿ‹øÓç‹Nf ¾¸‹~Šž¸ˆ9‹~‹^3ÉŠŽ¹G‰~ˆ ;‹N‹¾¼A‰Nf¹f+ÏTðfÓ艖¼f‰†¸ëÓàf †¸Ê‰Ž¼VèüƒÄdž´_^[ÃSU‹l$V‹t$3ÀW‹Ž„…É~V…ív‹ƒx,u VèFƒÄŽ QVèÖ–$ RVèÉVè“‹–¨‹Ž¬ƒÂ ƒÁ ÁêÁéƒÄ;ÊwëM‹Ñ};úw‹\$…Ût‹|$ WUSVèqüÿÿƒÄéXƒ¾ˆ„º;Ê„²‹Ž¼‹|$ ƒù W~Z‹Ú‹nÓãf ž¸‹^ŠŽ¸ˆ +‹^‹nC‰^‹Ë3ÛŠž¹ˆ)‹N‹ž¼A‰Nf¹f+ËfÓêƒÃ󉞼f‰–¸ëÓâf –¸ƒÁ‰Ž¼‹Ž @P‹†( @APQVèþ–ˆ †”RPVèÚƒÄ鑋޼‹|$ ƒù G~Z‹ÐÓâ‹Nf –¸‹VŠž¸ˆ‹V‹^B‰V‹Ê3ÒŠ–¹ˆ‹N‹–¼A‰Nf¹f+ÊfÓèƒÂó‰–¼f‰†¸ëÓàf †¸ƒÁ‰Ž¼hdÙhäÔVèDƒÄ Vè›úÿÿƒÄ…ÿt VènƒÄ_^][Ãì‹D$SUV‹t$W‹8‹@ƒÍÿ‹‹H 3À‰L$;ȉl$‰†PdžT=~>‹×fƒ:t$‹ŽP‰D$A‹è‰ŽP‰„Ž\ Æ„0XëfÇB‹L$@ƒÂ;Á|Ä‹ŽPƒù}]ƒý}E‹Åë3ÀA‰ŽP‰„Ž\ fLJƄX‹–¨J…Û‰–¨t3Éf‹Lƒ‹†¬+Á‰†¬‹ŽPƒù|§‰l$‹T$ ‰j‹†P™+‹ØÑûƒû|SWVè?ƒÄ Kƒû}ï‹D$‰D$‡‰D$‹†P‹ž` jW‹Œ†\ HV‰Ž` ‰†Pèþ‹–T‹®` ƒÄ J‹Â‰–T‰œ†\ ‹ŽTI‹Á‰ŽT‰¬†\ f‹¯fŸ‹D$f‰Š„XŠŒ.X:Ár%ÿëáÿ‹Á‹L$þÀjWˆ„X‹D$$f‰L¯f‰LŸ‰Ž` AƒÀV‰L$ ‰D$(èc‹†PƒÄ ƒø*ÿÿÿ‹–T‹Ž` J‰–T‹Â‹T$ RV‰Œ†\ è ‹D$Æ< VPWè(ƒÄ_^][ƒÄËD$SUV‹t$‹PW‹¬°\ 6;ʉl$‹|$}4‹´ˆ` ‹¬ˆ\ f‹·f‹¯f;ÓruŠ”XŠœ(X:ÓwA‹l$‹´ˆ\ f‹¯f‹·f;Ór/uŠ”(XŠœX:Óv+‹T$‰L$Ñቴ\ ‹P;Ê~‡‹L$_^‰¬ˆ\ ][ËT$_^‰¬\ ][ɬ°\ _^][Ãì‹D$$SUV‹‹H‹@‰L$W3ö‹‹H‹h‰T$‹P‰L$$‰T$ ‹T$0¹3Àº< ‰t$ó«‹‚T‰l$(‹Œ‚\ f‰t‹‹²TFþ=©„²\ ‰D$0¸=+Æð‰D$‰t$4‹L$03À3ÿ‹ f‹D‹f‹|ƒ‹Ç@;Å~ ‹|$‹ÅG‰|$‹|$f‰D‹;Ï`‹t$ fÿ„B< 3ÿ;Î| ‹ù+þ‹t$$‹<¾f‹4‹Çæÿÿ¯Æ‚¨‹D$…Àt"‹l$3Àf‹D‹Š¬Ç‹l$(¯ÆÈ‰Š¬‹t$4‹L$0‹D$ƒÁH‰L$0‰D$…Sÿÿÿ‹|$…ÿ„ÔEÿfƒ¼B< ŒB< u ƒéHfƒ9töfÿŒB< fƒ„B> fÿŒj< ƒï…ÿÁ…í‹ý„‹¬j< ‰l$3Àf‹E…À‰D$0tb¬²\ ‹t$4‹MüNƒí‰t$4‹t$;Ήl$(8t‹3Àf‹;Çt"‹ï+è3Àf‹‹¯è‹‚¨Å‹l$(‰‚¨f‰>‹D$0H‰D$0…Àu©‹t$4‹l$Oƒí…ÿ‰l$u€_^][ƒÄËT$ ƒì 3ÀL$Vt$+ÖW¾f‹< ƒÁføÑç‹ÇNf‰Aþuë‹D$0…À|6‹t$,x3Éf‹N…Étf‹TLQ‹Â%ÿÿBPf‰TLèÿ ƒÄf‰ƒÆOuÑ_^ƒÄ ÃV‹t$‹† Ž”PQVèW‹–( †ˆ RPVèCŽ0 QVèöùÿÿƒÄ ¸3ÒŠÐÔfƒ¼–~ uHƒø}ç‹–¨L@щ–¨^ÃQ‹D$ S3ÉVf‹HW3ÿÇD$ ÿÿÿÿ…ɺ¾u ºŠ¾‹\$…ÛfÇD˜ÿÿŒŸCU‰\$‹\$h‹Á3Éf‹MG;ú};Átn;þ} f¼ƒ| ë0…Àt;D$tfÿ„ƒ| fÿƒ¼ ëƒÿ  fÿƒÀ ëfÿƒÄ 3ÿ‰D$…Éu ºŠ¾ë;Áu º¾ë º¾‹D$ƒÅH‰D$…oÿÿÿ]_^[YÃSU‹D$V‹t$W‹Ž¼ƒù ~]ÿþÿÿ‹ÐÓâ‹Nf –¸‹VŠž¸ˆ‹N‹~3ÒŠ–¹A‰Nˆ9‹–¼‹nf¹f+ÊEfÓèƒÂõ‰n‰–¼f‰†¸ëÿþÿÿÓàf †¸ƒÁ‰Ž¼‹Ž¼ƒù ~_‹T$Bÿ‹ÐÓâ‹Nf –¸‹VŠž¸ˆ‹N‹~3ÒŠ–¹A‰Nˆ9‹–¼‹nf¹f+ÊEfÓèƒÂõ‰n‰–¼f‰†¸ë‹D$HÓàf †¸ƒÁ‰Ž¼‹Ž¼‹l$ ƒù Eü~Z‹ÐÓâ‹Nf –¸‹VŠž¸ˆ‹V‹~B‰V‹Ê3ÒŠ–¹ˆ9‹N‹–¼A‰Nf¹f+ÊfÓèƒÂô‰–¼f‰†¸ëÓàf †¸ƒÁ‰Ž¼3ÿ…펣‹Ž¼ƒù ~l3Ò3ÀŠ—ÐÔf‹„–~ ‹ÐÓâ‹Nf –¸‹VŠž¸ˆ‹V‹^B‰V‹Ê3ÒŠ–¹ˆ‹N‹–¼A‰Nf¹f+ÊfÓèƒÂó‰–¼f‰†¸ë#3ÀЇÐÔf‹”†~ fÓâf –¸ƒÁ‰Ž¼G;ýŒ]ÿÿÿ‹D$Ž”HPQVè&‹T$(†ˆ JRPVèƒÄ_^][Ãì‹D$S3Û3Òf‹XV…ÛWÇD$ ÿÿÿÿ¹¾u ¹Š¾‹|$ …ÿŒ0ƒÀG‰D$ ‹D$U‰|$‹|$$‹ë3ÛBf‹;щ\$‰T$ };ë„ä;Ö¬‹ˆ¼3öf‹´¨~ ¿+þ;Ï~g3Òf‹”¨| ‹úÓç‹Hf ¸¸‹xŠ˜¸ˆ9‹x‹X3ÉŠˆ¹G‰xˆ ‹H‹¸¼A‰Hf¹f+ÏfÓêf‰¸T7ð‰¼‹T$ ëf‹¼¨| fÓçf ¸¸Ήˆ¼J‰T$ …Yÿÿÿéü…í„Á;l$„¡‹ˆ¼3öf‹´¨~ ¿+þ;Ï~g3Òf‹”¨| ‹úÓç‹Hf ¸¸‹xŠ˜¸ˆ9‹x‹X3ÉŠˆ¹G‰xˆ ‹H‹¸¼A‰Hf¹f+ÏfÓêf‰¸T7ð‰¼‹T$ ëf‹¼¨| fÓçf ¸¸Ήˆ¼J‰T$ ‹ˆ¼3öf‹°¾ ¿+þ;Ï~f3Òf‹¼ ‹úÓç‹Hf ¸¸‹xŠ˜¸ˆ9‹x‹X3ÉŠˆ¹G‰xˆ ‹H‹¸¼A‰Hf¹f+ÏfÓêf‰¸T7ð‰¼‹T$ ëf‹¸¼ fÓçf ¸¸Ήˆ¼‹ˆ¼ƒù~^ƒÂý‹òÓæ‹Hf °¸‹pŠ˜¸ˆ1‹p‹x3ÉŠˆ¹F‰pˆ >‹H‹°¼A‰Hf¹f+ÎfÓêƒÆò‰°¼f‰¸éGƒÂýÓâf ¸ƒÁé-ƒú ‹ˆ¼3öf‹°Â ¿+þ;Ï~f3Òf‹À ‹úÓç‹Hf ¸¸‹xŠ˜¸ˆ9‹x‹X3ÉŠˆ¹G‰xˆ ‹H‹¸¼A‰Hf¹f+ÏfÓêf‰¸T7ð‰¼‹T$ ëf‹¸À fÓçf ¸¸Ήˆ¼‹ˆ¼ƒù ~^ƒÂý‹òÓæ‹Hf °¸‹pŠ˜¸ˆ1‹p‹x3ÉŠˆ¹F‰pˆ >‹H‹°¼A‰Hf¹f+ÎfÓêƒÆó‰°¼f‰¸é(ƒÂýÓâf ¸ƒÁ鋈¼3öf‹°Æ ¿+þ;Ï~f3Òf‹Ä ‹úÓç‹Hf ¸¸‹xŠ˜¸ˆ9‹x‹X3ÉŠˆ¹G‰xˆ ‹H‹¸¼A‰Hf¹f+ÏfÓêf‰¸T7ð‰¼‹T$ ëf‹¸Ä fÓçf ¸¸Ήˆ¼‹ˆ¼ƒù ~[ƒÂõ‹òÓæ‹Hf °¸‹pŠ˜¸ˆ1‹p‹x3ÉŠˆ¹F‰pˆ >‹H‹°¼A‰Hf¹f+ÎfÓêƒÆ÷‰°¼f‰¸ëƒÂõÓâf ¸ƒÁ‰ˆ¼‹\$3Ò…Û‰l$u ¹Š¾ë;ëu ¹¾ë ¹¾‹l$$‹|$ƒÅO‰l$$‰|$…âúÿÿ]_^[ƒÄËD$ƒì3É‹ SU‹l$VW…Ò„p‹¤3ÿ3Ûf‹jm ¨Zjz Ïäÿ “'® ±ž}D“ðÒ£‡hòþÂi]Wb÷Ëge€q6lçknvÔþà+Ó‰ZzÚÌJÝgoß¹ùùホC¾·Õް`è£ÖÖ~“Ñ¡ÄÂØ8RòßOñg»ÑgW¼¦Ýµ?K6²HÚ+ ØL ¯öJ6`zAÃï`ßUßg¨ïŽn1y¾iFŒ³a˃f¼ Òo%6âhR•w ÌG »¹"/&U¾;ºÅ( ½²’Z´+j³\§ÿ×Â1Ïе‹žÙ,®Þ[°Âd›&òc윣ju “m© œ?6ë…grW‚J¿•z¸â®+±{8¶ ›ŽÒ’ ¾Õå·ïÜ|!ßÛ ÔÒÓ†BâÔñø³ÝhnƒÚ;[&¹öáw°owG·æZˆpjÿÊ;f\ ÿžei®bøÓÿkaEÏlxâ  îÒ ×TƒN³9a&g§÷`ÐMGiIÛwn>JjÑ®ÜZÖÙf ß@ð;Ø7S®¼©Åž»ÞϲGéÿµ0ò½½ŠÂºÊ0“³S¦£´$6к“×Í)WÞT¿gÙ#.zf³¸JaÄh]”+o*7¾ ´¡Ž ÃßZï-A1‚b62ÃS-+ÅldEôw}†§ZVÇ–AOŠÙÈI»ÂÑŠèïúËÙôã Oµ¬M~®µŽ-ƒžÏ˜‡QÂJ#ÙSÓpôx’AïaU×®.æµ7×µ˜–„ƒY˜‚©›Ûú-°šË6©]]wællÿß?AÔžZÍ¢$„•㟌 F²§aw©¾¦áèñçÐóè$ƒÞÃe²ÅÚª®]]ëŸFD(Ìkoiýpv®k19ïZ* ,  m8ó6Fß²]ÆqTpí0ekô÷ó*»¶Â1¢u‘‰4 û¼Ÿº„yÞ©%8ï²<ÿyós¾Hèj}ÅA<*ÞXOyðD~bé‡-OÂÆTÛŠ”@»ƒè#¦ÂÙ8¿ Å 8Lô»!§– Ζ Ì\H1×E‹búnÊSáwT]»ºl £Ö?ˆ—–‘P˜×Þ©ÌÇÒúáì“Ëúõ\×bræykÞµT@Ÿ„OYX#Úp8$›A#=§kýeæZæ|% ËWd8ÐN£®‘⟊!̧3`ý¼*¯á$­îÐ?´-ƒŸl² †«$HÉêSÐ)F~ûhweâöy?/·H$6t 5*ò¼SK³HRpÞey1ï~`þóæç¿Âýþ|‘ÐÕ= ËÌú6Šƒ»‘šxT¼±9e§¨K˜ƒ; ©˜"Éúµ ˆË®O]ï_lôFÍ?ÙmŒÂtCZó#AêÁplÁ€AwØG×6—æ-ŽÅµ¥„„¼ŠAq[»Zh˜èwCÙÙlZO-_~6 œ-'Ý>˜¹S1ƒ b®‹ÑSµ’ÅôÝWôïÄ”§ÂïÕ–Ùöé¼®¨·kÞ1œ*ï*…íykʬHpÓo]ø.*Fáá6Þf ÅcTèT"eóMåó²¤Â©g‘„0& Ÿ)¸®ÅäùŸÞý:ÌóÖ{ýèϼk©€ýZ²™> Ÿ²8„«°$,ñ52F*sw1´ápHõÐkQ6ƒFzw²]cN×úËæáÒ̵Ìù„×àJ–¯ #¶Èp ‰A»„F]#l8Ä?1…(B˜Og©T~ÀúyUËbLÅ8^ô#˜§³Ü–ªTåZ1Oü™bbרSyÎOáIV~úP•-×{ÔÌbŠ-R»–4‘è»ÐÙ ìó~^­ÂeGn‘Hl/ Suè6:© #jT$+e?äy§–¥H¼f‘¤'*нà¼Ëò¡ÐëbÞýÀ#ïæÙ½á¼üЧ ?ƒŠ&~²‘?¹$ÐpøËi;FæBzwý[µkeÜôZ~Å7 Sîv8H÷±® ¸ðŸ¡3Ì?Šrý$“7jÂnÔ„Y¾Fܨ ëÂ˲|…O¸Q;ÑÖ…— áïU dù S“Ø -ž =G\ p£&GÉäw¢)`¬ /›aíÂß«õµiÈò5ÿ˜÷¦&±‘LsZ<#0þzޏMäzàFM8×,9Ž’É;¹ø :<îD? „†>R:À(ôq-Ãv³,šÈõ.­¢7/Àšp÷çXq®Ys™3Ür%“w+OQvrñtE›Õux܉~O¶K }!bÏ|¤t€y“BxÊ zýÊÆ{°.¼l‡D~mÞú8oéúnl†µk[ìwjR1h58ói¯b?mcf«+aQÁé`Ôצeã½ddº"fiàg Ë×H¡INSKyu‘JücÞOË N’·ZL¥Ý˜M˜šÄF¯ðGöN@EÁ$‚DD2ÍAsX@*æIBŒ‹CPhñTg3U>¼uW Ö·VŒÀøS»ª:Râ|PÕ~¾Qè9âZßS [†ífY±‡¤X4‘ë]û)\ZEo^m/­_€5á·q÷àîϱâÙ¥sã\³<ækÙþç2g¸å zä8J&ï äîVž¢ìaô`íäâ/èÓˆíéŠ6«ë½\iêð¸ýÇÒÑüžl—þ©Uÿ,úzØûBÄžùu®\øHéóƒÂò&=„ðWFñ”A ô£+Ëõú•÷ÍÿOö`]xÙW7ºØ‰üÚ9ã>Û¼õqÞ‹Ÿ³ßÒ!õÝåK7ÜØ k×ïf©Ö¶ØïÔ²-Õ¤bÐ3ΠÑjpæÓ]$Òþ^Å'”œÄ~*ÚÆI@ÇÌVWÂû<•â‚ÓÁ•èÀ¨¯MËŸÅÊÆ{ÉÈñ ÉtDÌCm†ÍÓÀÏ-¹Î@–¯‘wüm.B+’(铜>¦–«Td—òê"•Å€à”øÇ¼ŸÏ­~ž–8œ¡yú$oµ˜w™J»1›}Ñóš05‰_KŒ^á Ži‹Ï쀊Û÷B‹‚I‰µ#ƈˆdšƒ¿X‚æ°€ÑÚÜTÌ“„c¦Q…:‡ rÕ† Ðâ©—º ¨Îfªùn¤«|xë®K)¯¬o­%Æ­¬ñ§/ë3¦vUu¤A?·¥Ä)ø óC:¡ªý|£—¾¢Ðsĵç´¾§@¶‰Í‚· ÛͲ;±³bI±Ue‹°h"×»_HºöS¸1œ‘¹´ŠÞ¼ƒà½Ú^Z¿í4˜¾eg¼¸‹È ªî¯µW—b2ðÞ7Ü_k%¹8×ï(´ÅŠO}dà½o‡׸¿ÖJÝØjò3wßàVcXŸWPú0¥èŸúqø¬BÈÀ{ß­§ÇgCru&oÎÍp­•-û·¤?žÐ‡'èÏBs¢¬ ưÉGz>¯2 [ÈŽµg; Ї²i8P/ _ì—âðY…‡—å=ч†e´à:ÝZOÏ?(3w†äêãwXR Øí@h¿Qø¡ø+ðÄŸ—H*0"ZOWžâöoI“õÇ}§@ÕÀümNП5+·#Å–Ÿ *'Gýº| A’ô÷èH¨=X›X?¨#¶1Ó÷¡‰jÏv¨Ê¬á¾„`ÃÒp ^·æY¸©ô<ßL…çÂÑà€~i/Ë{kHwâ ËÇh±s)ÇaL ¸Ùõ˜oDÿÓü~Pfî7ÚVM'¹(@¶Æï°¤£ˆ °Û×g9‘xÒ+ôn“÷&;fšƒˆ?/‘íX“)T`D´1ø ߨMºÏñ¦ìß’þ‰¸.Fg›Tp'ì»HðqÞ/LÉ0€ùÛUçEcœ ?kùǃÓh6ÁrŠyË7]ä®Pá\@ÿTN%˜èösˆ‹®ï7ø@‚'>¼$é!AxU™¯×à‹Ê°\3;¶Yí^ÑåU°~PGÕìÿl!;b F‡Úçé2È‚ŽŽpÔží(±ùQ_Vä‚:1X:ƒ §æn3Á† m¦:µ¤á@½Á†ü/)IJNõ¯óv"2–žŠx¾+˜Ù— KÉôx.®HÀÀýÒ¥fAj^–÷y9*O—–Ÿ]òñ#åkM`~×õŽÑbçë¶Þ_RŽ Â7éµzÙFh¼!¼Ðê1߈Vc0aùÖ"žj𽦽ØÁ¿6n´­S šNrÿ)Î¥†{·táÇÍÙ’¨¾¬*F8#v¥€ufÆØz`þ®Ïr›ÉsÊ"ñ¤WG–ï©9­ýÌ^EîMvc‰ñÎ&DÜèAødQy/ù4“AÚ±&S¿ÖšëéÆù³Œ¡E bðiL¡¾Q›<Û6'„5™’–Pþ..™¹T&üÞèžq]Œwá4Î.6©«IŠEæ? ƒ»v‘àãö\[ýYéI˜>Uñ!‚lDa>Ԫ΋ÆÏ©7~8AÖ]&Ãn³‰v|ÖîÊÄoÖY ±¡áäóy¨K×i˲w«\¡Â¹9Æ~€þ©œå™$ 6 6nQާf†ÂqÚ>,Þo,I¹Ó”ð •渱{I £.±H>ÒC-YnûÃöÛ馑gQ©°ÌzÎ t”a¹fñÞw0–îa,™ QºmÄpjôéc¥5žd•£Ûˆ2yܸ¤àÕé—ÒÙˆ ¶L+~±|½ç¸-¿‘·dj° òó¹qH„¾AÞÚÔ}mÝäëôÔµQƒÓ…Çl˜Vdk¨ÀýbùzŠeÉì\OclÙú=c õ;n ÈLi^Õ`Aä¢gqr<äÑKÔGÒ …ý¥ µk5µ¨úB²˜lÛ»ÉÖ¬¼ù@2ØlãEß\uÜÖ Ï«Ñ=Y&Ù0¬QÞ:È×Q€¿Ða!´ôµV³Ä#Ϻ•™¸½¥(¸ž_ˆÆ Ù²± é$/o|‡XhLÁa«¶f-=vÜAÛq˜Ò ¼ïÕ*q±…‰¶µŸ¿ä¥è¸Ô3xÉ¢ù4– ¨Žá˜j »m=-‘dl—æc\kkQôlab…e0ØòbNl•í¥{‚ôÁõÄWe°ÙÆ·éP‹¾¸êü¹ˆ|bÝßÚ-IŒÓ|óûÔLeM²aX:µQΣ¼tÔ»0âJߥA=ؕפÑÄmÓÖôûCiéj4nÙü­gˆFÚ`¸ÐD-s3åª L_Ý |ÉPq<'Aª¾ É †Whµ% o…³¹fÔ ÎaäŸ^Þù)Ùɘ°Ð˜"Çר´Y³=.´ ·½\;Àºl­í¸ƒ š¿³¶¶â t±ÒšêÕG9Òw¯Û&s܃ãc ”d;„ mj>zjZ¨äÏ “ ÿ ®'}ž±ð“D‡£ÒòhiÂþ÷bW]€egËl6qnkçþÔv‰Ó+àÚzZgÝJÌù¹ßo޾ïù·¾C`°ŽÕÖÖ£è¡Ñ“~8ØÂÄOßòRÑ»gñ¦¼Wg?µÝH²6KØ +Ú¯ L6JöAz`ß`ïègßU1nŽïFi¾yËa³Œ¼fƒ%oÒ Rhâ6Ì w•» G"¹U&/ź;¾²½ (+´Z’\³jÂ×ÿ§µÐÏ1,Ùž‹[Þ®›d°ìcò&uj£œm“ œ ©ë6?rg…W•¿J‚â¸z{±+® ¶8’ÒŽ›åÕ¾ |Üï· Ûß!†ÓÒÔñÔâBhݳøÚƒn¾Íö¹&[o°wá·GwˆZæÿjpf;Ê \ežÿøb®iakÿÓlÏE  âx× ÒîNƒT9³Â§g&aÐ`÷IiGM>nwÛ®ÑjJÙÖZÜ@ß f7Ø;𩼮SÞ»žÅG²Ï0µÿé½½òʺŠS³“0$´£¦ºÐ6ÍדTÞW)#Ùg¿³fz.ÄaJ¸]h*o+”´ ¾7Ã Ž¡Zß-ï1A26b‚+-SÃdlÅ}wôEVZ§†OA–ÇÈÙŠÑ»IúïèŠãôÙˬµO µ®~Mžƒ-އ˜ÏJÂQSÙ#xôpÓaïA’.®×U7µæ˜µ×ƒ„–‚˜Y›©°-úÛ©6Ëšæw]]ÿllÔA?ßÍZž•„$¢ŒŸã§²F ¾©wañèá¦èóÐçÃÞƒ$ÚŲe]]®ªDFŸëokÌ(vpýi91k® *Zï  ,8mßF6óÆ]²ípTqôke0»*ó÷¢1¶‰‘u 4Ÿ¼û„º%©Þy<²ï8sóyÿjèH¾AÅ}XÞ*<ðyOéb~DÂO-‡ÛTÆ”Š»@¦#胿8ÙÂ8 Å !»ôL –§–Î\Ì E×1Hnúb‹wáSʺ»]T£ lˆ?Ö‘–—ÞטPÇÌ©ìáúÒõúË“rb×\kyæ@TµÞYO„ŸX#$8pÚ=#A›eýk§|æZæWË %NÐ8d‘®£ŠŸâ3§Ì!*¼ý`­$᯴?Ð-† ²lÉH$«ÐSêû~F)âewh/?yö6$H· t*5KS¼òRH³yeÞp`~ï1çæóþþý¿ÕБ|ÌË =ƒŠ6úš‘»±¼Tx¨§e9;ƒ˜K"˜© µúɮˈ_ï]OFôlmÙ?ÍtÂŒóZCêA#ÁlpÁØwA€—6×GŽ-極ż„„qAŠhZ»[Cwè˜ZlÙÙ-O 6~_'-œ>ݹ˜ ƒ1S‹®b’µSÑÝôÅÄïôWï§”öÙ–Õ®¼é·¨œ1Þk…*ï*ÊkyíÓpH¬ø]oáF*.fÞ6áÅ TèTcMóe"²óå©Â¤0„‘g)Ÿ &äÅ®¸ýÞŸùÖóÌ:Ïèý{€©k¼™²Zý²Ÿ >«„8,$°5ñ*F21wsHpá´QkÐõzFƒ6c]²wËú×NÒáæù̵Ìàׄ¯–J¶#  pÈ„»A‰#]F8l1?Ä(…gO˜B~T©UyúÀLbË8Ř#ô^³§ª–ÜåTüO1Z×bb™ÎySØIáOPú~V{×-•bÌÔ-Š4–»R»è‘ ÙÐ^~óìGe­lH‘nuS /:6è# ©$Tj?e+–§yä¼H¥¤‘f½Š*'ò˼àëСÀýÞbÙæï#¼á½ §Ðü&Šƒ??‘²~pÐ$¹iËøBæF;[ýwzÜekµÅ~ZôîS 7÷H8v¸ ®±¡ŸðŠ?Ì3“$ýrÂj7„ÔnF¾Y ¨ÜËÂë|²O…Q¸Ñ; —…Ö Uïá ùdØ“S ž- \G=&£päÉG¢w`)/ ¬ía›«ßÂiµõ5òÈ÷˜ÿ±&¦sL‘†„ <À:R=Pe6^X7œ}o5ÚÃ64©1W¿„0•Õ³2Ókê3Ý$kå%©§'ï1þ&-[É#bML" '{ æ™"!$ó*x´(+ºÞ)ü`F(> q-qô,³vÃ.õÈš/7¢­pšÀqXç÷sY®rÜ3™w“%vQO+tñruÕ›E~‰ÜxK¶O} |Ïb!y€t¤xB“z Ê{ÆÊýl¼.°m~D‡o8úÞnúékµ†ljwì[h1Rió85b¯cm?a+«f`éÁQe¦×Ôdd½ãf"ºgàiH×Ë I¡KSNJ‘uyOÞcüN ËLZ·’M˜Ý¥FÄš˜Gð¯E@NöD‚$ÁAÍ2D@XsBIæ*C‹ŒTñhPU3gWu¼>V·Ö SøÀŒR:ª»P|âQ¾~ÕZâ9è[ SßYfí†X¤‡±]ë‘4\)û^oEZ_­/má5€à÷q·â±Ïîãs¥Ùæ<³\çþÙkå¸g2äz ï&J8îä 좞Ví`ôaè/âäéíˆÓë«6Šêi\½ý¸ðüÑÒÇþ—lžÿU©ú,ûØzùžÄBø\®uóéHòƒð„=&ñFWô A”õË+£÷•úöOÿÍÙx]`غ7WÚü‰Û>ã9Þqõ¼ß³Ÿ‹Ýõ!ÒÜ7Kå×k ØÖ©fïÔïØ¶Õ-²Ðb¤Ñ Î3ÓæpjÒ$]Å^þÄœ”'ÆÚ*~Ç@IÂWVÌÕ<ûÁÓ‚¢Àè•ËM¯¨ÊÅŸÈÉ{ÆÉ ñÌDt͆mCÏÀÓι-‘¯–@müw’+B.“é(–¦>œ—dT«•"êò”à€ÅŸ¼Çøž~­Ïœ8–úy¡˜µo$™w›1»JšóÑ}‰50ŒK_Ž á^Ï‹iŠ€ì‹B÷Û‰I‚ˆÆ#µƒšdˆ‚X¿€°æÜÚÑ„“ÌT…Q¦c‡:†Õr ©âР¨ º—ªfΫ¤nù®ëx|¯)K­o¬¬­Æ%§ñ¦3ë/¤uUv¥·?A ø)Ä¡:Có£|ýª¢¾—µÄsдç¶@§¾·‚͉²ÍÛ ³±;±Ib°‹eU»×"hºH_¸Sö¹‘œ1¼ÞŠ´½àƒ¿Z^Ú¾˜4í¸¼geª È‹µ¯îb—W7Þð2%k_Ü×8¹Å´(ï}OŠo½àdׇJÖ¿¸òjØÝàßw3XcVPWŸè¥0úúŸB¬øqß{ÀÈgǧ­urCÍÎo&•­p-?¤·û‡ОÏè'¢sB°Æ ¬zGÉ 2¯>ŽÈ[ ;gµ²‡Ð/P8i—ì_ …Yðâ=å—‡e†‡ÑÝ:à´ÏOZw3(?êä†RXwã@íØ øQ¿hð+ø¡H—ŸÄZ"0*âžWOIoöÇõ“Õ@§}müÀ5ŸÐN#·+Ÿ–Å'* ºýGA |ô’¨Hè÷›X=#¨?X1¶‰¡÷ÓvÏj¬Ê¨¾áÃ`„^ pÒæ·ô©¸YLß<ÑÂç…i~€à{Ë/ÃwHkË ¢s±hÇaÇ)Ù¸ LDo˜õüÓÿîfP~VÚ7¹'M¶@(¤°ïÆ ˆ£Û°9g×+Òx‘“nô;&÷ƒšf‘/?ˆ)“Xí´D`T ø1M¨ß¦ñϺþ’ßìF.¸‰T›gì'pqðH»ÉL/ÞÛù€0cEçUk? œÓƒÇùÁ6hyŠrä]7Ë\áP®NTÿ@öè˜%®‹ˆs7ï‚@ø¼>'!é$™UxA‹àׯ3\°ÊíY¶;UåÑ^GP~°ÿìÕb;!lÚ‡F È2éçpŽŽ‚(ížÔQù±‚äV_:X1:§ ƒ3næ †Áµ:¦m½@á¤ü†ÁI)/¯õNJ2"vóŠž–˜+¾x —ÙxôÉKÀH®.ÒýÀjAf¥÷–^O*9y]Ÿ–—å#ñòMkõ×~`çbÑŽ_Þ¶ë ŽRzµé7hFÙм!¼ˆß1ê0cV"Öùašjž½¦½¿ÁØ­´n6 SrNš¥Î)ÿ·{†Çát’ÙÍ*¬¾¨8F€¥v#ØÆfu`zrÏ®þÊsÉ›W¤ñ"ï–Gý­9©E^ÌvMîÎñ‰cÜD&døAèù/yQA“4S&±ÚëšÖ¿³ùÆé E¡Œðb¡Li<›Q¾„'6Û–’™5..þP&T¹™žèÞüŒ]q4áw©6.ΊI«?æE»ƒ ãà‘v[\öIéYýñU>˜l‚!Ô>aDƋΪ~7©ÏÖA8nÃ&]|v‰³ÄÊîÖYÖoᡱ óäK¨yËi׫w²¹Â¡\~Æ9œ©þ€$™å6 6 ŽQn†f§>ÚqÂ,oÞ,”Ó¹I ð±¸æ•£ I{±.CÒ>HûnY-éÛöÃQg‘¦Ì°©t Îzf¹a”Þñ deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly p(p+p+ p+ 1 1€€ 1 € 1 € 1  11.2.3‹`Psp0 À `  €@ àX ;x8 Ðh( °ˆH ðTã+t4 È d$ ¨„D è\ ˜S|< Øl, ¸ ŒL øR£#r2 Ä b" ¤‚B äZ ”Cz: Ôj* ´ ŠJ ôV@3v6 Ìf& ¬†F ì ^ œc~> Ün. ¼ŽN ü`Qƒq1  a! ¢A âY ’;y9 Òi) ² ‰I òU+u5 Ê e% ª…E ê] šS}= Úm- º M úSÃ#s3 Æ c# ¦ƒC æ[ –C{; Ök+ ¶ ‹K öW@3w7 Îg' ®‡G î _ žc? Þo/ ¾O þ`Psp0 Á ` ¡€@ áX ‘;x8 Ñh( ±ˆH ñTã+t4 É d$ ©„D é\ ™S|< Ùl, ¹ ŒL ùR£#r2 Å b" ¥‚B åZ •Cz: Õj* µ ŠJ õV@3v6 Íf& ­†F í ^ c~> Ýn. ½ŽN ý`Qƒq1 à a! £A ãY “;y9 Ói) ³ ‰I óU+u5 Ë e% «…E ë] ›S}= Ûm- » M ûSÃ#s3 Ç c# §ƒC ç[ —C{; ×k+ · ‹K ÷W@3w7 Ïg' ¯‡G ï _ Ÿc? ßo/ ¿O ÿA@!  @a`10  Á@     `Psp0 À `  €@ àX ;x8 Ðh( °ˆH ðTã+t4 È d$ ¨„D è\ ˜S|< Øl, ¸ ŒL øR£#r2 Ä b" ¤‚B äZ ”Cz: Ôj* ´ ŠJ ôV@3v6 Ìf& ¬†F ì ^ œc~> Ün. ¼ŽN ü`Qƒq1  a! ¢A âY ’;y9 Òi) ² ‰I òU+u5 Ê e% ª…E ê] šS}= Úm- º M úSÃ#s3 Æ c# ¦ƒC æ[ –C{; Ök+ ¶ ‹K öW@3w7 Îg' ®‡G î _ žc? Þo/ ¾O þ`Psp0 Á ` ¡€@ áX ‘;x8 Ñh( ±ˆH ñTã+t4 É d$ ©„D é\ ™S|< Ùl, ¹ ŒL ùR£#r2 Å b" ¥‚B åZ •Cz: Õj* µ ŠJ õV@3v6 Íf& ­†F í ^ c~> Ýn. ½ŽN ý`Qƒq1 à a! £A ãY “;y9 Ói) ³ ‰I óU+u5 Ë e% «…E ë] ›S}= Ûm- » M ûSÃ#s3 Ç c# §ƒC ç[ —C{; ×k+ · ‹K ÷W@3w7 Ïg' ¯‡G ï _ Ÿc? ßo/ ¿O ÿA@!  @a`10  Á@      inflate 1.2.3 Copyright 1995-2005 Mark Adler  #+3;CScsƒ£ÃãÉÄ !1AaÁ  0@`@@       ŒLÌ,¬lìœ\Ü<¼|ü‚BÂ"¢bâ’RÒ2²rò ŠJÊ*ªjêšZÚ:ºzú†FÆ&¦fæ–VÖ6¶vöŽNÎ.®nîž^Þ>¾~þAÁ!¡aá‘QÑ1±qñ ‰IÉ)©ié™YÙ9¹yù…EÅ%¥eå•UÕ5µuõ MÍ-­mí]Ý=½}ý  “ “ S S Ó Ó 3 3 ³ ³ s s ó ó  ‹ ‹ K K Ë Ë + + « « k k ë ë   › › [ [ Û Û ; ; » » { { û û   ‡ ‡ G G Ç Ç ' ' § § g g ç ç   — — W W × × 7 7 · · w w ÷ ÷    O O Ï Ï / / ¯ ¯ o o ï ï   Ÿ Ÿ _ _ ß ß ? ? ¿ ¿   ÿ ÿ @ `P0pH(hX8xD$dT4tƒCÃ#£cã         (08@P`p€ Àà  0@`€À€  0@`´ò¨òÐòœòŒò€òlò\òDòÐò4Þ*ß ,Þnß Rß„Þ Þ¨Þ²Þ¼ÞÆÞÐÞØÞâތޖÞß ßßß6ßBßêÞøÞdftellXfprintf×_fdopenWfopenÈ_errno‘malloc²sprintfffwrite]freadLfclose^freeá_vsnprintfOfflushbfseekYfputc¼strerrorBclearerrMSVCRT.dll_initterm_adjust_fdiv„DisableThreadLibraryCallsKERNEL32.dllQ<_K¦á33¨ßtà@á p@pð  &`%°€À€ðà`PF D 8 D Eà@P>Ð>5@€@°@ ;CB`8D€>0?]PGÐV€FxPu\à\ [ u€vàwp™@š0š š°á¸áÁáËáÙáßáçáôáâ ââ&â4âAâNâcâqâ|â„âŒâ’âšâ¢â©â°â·âÀâÇâÎâÕâÞâåâñâøâã ããã,ã=ãIãTãbãoã|ã‘ãã®ã¹ãÀãÑã  !"#$%&'()*+,-./012zlib1.dlladler32compresscompress2compressBoundcrc32deflatedeflateBounddeflateCopydeflateEnddeflateInit2_deflateInit_deflateParamsdeflatePrimedeflateResetdeflateSetDictionaryget_crc_tablegzclearerrgzclosegzdopengzeofgzerrorgzflushgzgetcgzgetsgzopengzprintfgzputcgzputsgzreadgzrewindgzseekgzsetparamsgztellgzungetcgzwriteinflateinflateBackinflateBackEndinflateBackInit_inflateCopyinflateEndinflateInit2_inflateInit_inflateResetinflateSetDictionaryinflateSyncinflateSyncPointuncompresszErrorzlibCompileFlagszlibVersion1.2.3%c%c%c%c%c%c%c%c%c%c: invalid distance too far backinvalid distance codeinvalid literal/length codetoo many length or distance symbolsinvalid distances setinvalid literal/lengths setinvalid bit length repeatinvalid code lengths setinvalid stored block lengthsinvalid block typeincorrect length checkincorrect data checkheader crc mismatchunknown header flags setincorrect header checkinvalid window sizeunknown compression methodäÔ˜ÓdÙ Ô„Ôincompatible versionbuffer errorinsufficient memorydata errorstream errorfile errorstream endneed dictionary€0€ H`884VS_VERSION_INFO½ïþ?–StringFileInfor040904E4dFileDescriptionzlib data compression library,FileVersion1.2.34 InternalNamezlib1.dll|,LegalCopyright(C) 1995-2004 Jean-loup Gailly & Mark Adler< OriginalFilenamezlib1.dll*ProductNamezlib0ProductVersion1.2.3‚5CommentsDLL support by Alessandro Iacopetti & Gilles VollantDVarFileInfo$Translation äpš2a3¿3ñ3ú34464?4T4`4|4…4–4¢4»4Ä4Ö4â4û455 5<5E5Z5f5‚5‹5Ÿ5«5Ä5Í5ß5è56 646=6`6Ë677·8%;+;V;e;t;ƒ;W< o2—2Ô248'868E8£<Å<Ù<0H­2Ï2ã2ì5I67+7Z7a7ˆ7¢7«7Á7Ç7Ø7ß7898@8Š8î89J9\9Š:¥: ;G;T;B ?[?¢?PD90_2Œ4@5T6X6\6`6d6h6l6„6ˆ6Œ66§6µ6;';A;¦>ü>L?a?`(Á35s5â5G7ƒ7Þ7ô7€:—:ï:B;Y=?«?p`Š1í1t3x3|3€3„3ˆ3Œ33”3˜3œ3 3¤3¨3¬3°3´3¸3¼3À3Ä3È3Ì3Ð3Ô3Ø3Ü3à3ä3è3ì3ð3ô344Ù:á:ì:; >0>:>€00;1I1½3Â3:ÅÇF‹Æ_^[ÃV‹t$W‹=ØÀ‹FPÿ×Vÿ׃Ä_^ËD$‹T$VW‹H‹r‹8t;÷v_ƒÈÿ^ËpSñ‹Ê‹9‰>‹y‰~‹y‰~‹I ‰N ‹H‹x‹t$ƒÁ‰H‹Ù‹Jû‹ÙÁéó¥‹Ë[ƒáó¤‹R‹HÊ_‰H3À^ÃU‹l$‹E…ÀuÅøhРUÿÐÀƒÄ3À]ËL$SV‹t$Q‹V‹NRQPè> ‹Ø‹FƒÄ;ØtZWÿ<ÀµøjhVjPjhÿÀ‹þƒÉÿ3Àò®÷ÑI_ƒù|ˆ„)÷ˆ„)öVh´ hVÿÔÀƒÄ‹Ã^[]ÃSV‹t$ Wƒ>uhH¡ë9‹|$…ÿWÆøh0¡VÿÐÀƒÄ ƒÈÿ_^[ÃÿÜÀ‹ØƒÄ…Ûuh¡ÆøVÿÐÀƒÄƒÈÿ_^[ˆ¤PÿØÀ‹NWSQ‰ž¤‰¾ èKŸƒÄ3À_^[ÃV‹t$‹…ÀuhÔ¡ë>jPè:ŸƒÄ„Àuh¼¡ë(‹T$ W‹úƒÉÿ3Àò®‹÷ÑIQRPè ŸƒÄ „À_uh˜¡ÆøVÿÐÀƒÄƒÈÿ^ËL$‹T$‹QRPèÑžƒÄ 3À^ËL$‹…ÀuÁøh¢QÿÐÀƒÄƒÈÿËL$QP謞ƒÄ%ÿøxèŸSUV‹´$ˆW‹þƒÉÿ3À3Ûò®÷ÑI‰\$ù‰\$,v)‹„$˜h¤hPÿÔÀƒÄ ƒÈÿ_^][Äxˬ$˜L$0USSSQV莃ăøÿ„ù‹D$0ƒø…åUS”$Œ SD$[‹èƒÄƒýÿ‰l$„º¡¬ï‹T$ …À‰T$…¾¡¨ïÇD$<£…ÀÇD$@(ÇD$D£ÇD$Hð5ÇD$L£ÇD$PÀ't ¡ü¢év„$|hPÿ,À…À„E¼$|ƒÉÿ3ÀT$xò®÷Ñ+ù‹Á‹÷‹úT$xÁéó¥‹È3Àƒáó¤¿Ü¢ƒÉÿò®÷Ñ+ù‹÷‹Ù‹úƒÉÿò®‹ËOÁéó¥‹Ë‹0ÀƒáD$xó¤PÿÓ‹ð…öth£Vÿ4À…À…ƒVÿ8À¼$|ƒÉÿ3ÀT$xò®÷Ñ+ù‹Á‹÷‹úT$xÁéó¥‹È3Àƒáó¤¿Ô¢ƒÉÿò®÷Ñ+ù‹÷‹ú‹ÑƒÉÿò®‹ÊOÁéó¥‹ÊD$xƒáPó¤ÿÓ‹ð…öt^h£Vÿ4À…Àu Vÿ8ÀëE‹ Â3Û…É~#|$@‹OüQVÿ4À…À‰tÖ‹ ÂCƒÇ;Ù|á3À…É~‹TÄ@‰Åì¢@;Á|ð¡ü¢‹´$˜Ç¨ï£¬ï‹L$QÿЋ”$VRUÇD$,èûOƒÄ ƒøÿ„™jjD$f‰D$‹D$DPÿDÁf‰D$D‹D$(…ÀjuÿÜÀ‹Œ$˜ƒÄ‰ë ÿÜÀƒÄ‰E‹è…í‰l$„±3Ò‰‰P‰P‰P ‰Pf‹D$f…À„Áf=ƒà‹T$>‹L$hSâÿÿj„$„RPQè9\øƒÄƒÿÿ‰|$„‹T$>„$„ âÿÿPŒ$|h´¢QÆ„„hô£h¤¢”$˜hRÿÔÀ¼$ ƒÉÿ3Àò®÷ÑIyWÿÜÀƒÄ ‰E…À„RŒ$„WQPÿäÀƒÄ ‹T$@Rÿ Á‰E3Àf9D$D‰D$$‰D$†q‹„$˜‹T$hPjŒ$„hQRè^[‹L$(ƒÄȃùÿ‰L$„&‹D$xPÿDÁf=…‹D$$j…ÀuÿÜÀ‹L$ ƒÄ‰A ë ÿÜÀƒÄ‰‹L$$‹ðA…ö‰L$$„­‹”$˜^RD$|SPÇèýƒÄ ƒøÿ„¯‹Œ$˜FQ”$üPRèØƒÄ ƒøÿ„Š‹„$˜n PŒ$|UQè³ƒÄ ƒøÿ„e‹”$˜~R„$üWPèŽƒÄ ƒøÿ„@ƒ;u+‹F…Àu$ƒ}uƒ?uVÿØÀ‹D$(ƒÄ3öƒøu‰t$$‹D$‹L$D@áÿÿ;Á‰D$Œ“þÿÿ‹l$‹D$(‹L$T@;Á‰D$(Œýûÿÿ‹l$‹´$˜‹T$8‹ ÁRÿÓ‹|$;ø„'‹D$8hVPÿÓ+ÇPUètZƒÄƒø…_^]ƒÈÿ[ÄxÃÿàÀ‹Rë@hŒ¢hSÿÔÀƒÄ ëgÿàÀ‹Pëhl¢hSÿÔÀƒÄ ëFÿàÀ‹Qè:nPhÔ£hSë!ÿàÀ‹RènP‹„$ hÔ£hPÿÔÀƒÄ‹L$8‹5 ÁQÿÖ‹|$;øt.‹T$8jjRÿÖ+ÇP‹D$ Pè¥YƒÄƒøu_^]ƒÈÿ[ÄxËD$,…Àu‹L$jjQèùTƒÄ èÁR_^]ƒÈÿ[ÄxËD$,…Àu!hVUèÏTƒÄ …Àt_^]ƒÈÿ[ÄxÃè…R_^]3À[ÄxËD$SƒèV„LH„Ht‹D$ hè¤hPÿÔÀƒÄ ƒÈÿ^[Ët$ hhܤVÿäÀ‹\$ ƒÄ …Û„»€;„²Wh¨¤SÿÀÀ‹Ð‹ûƒÉÿ3ÀƒÄò®÷ÑIh;Ñu)‹=èÀh¤¤Vÿ×hSVÿ×hh ¤Vÿ׃Ä$ë ‹=èÀSVÿ×ƒÄ ‹\$…Ût€;thhœ¤Vÿ×hSVÿ׃Ähh˜¤Vÿ׋D$,ƒÄ …Àt€8t hPVÿ×ƒÄ _^3À[ËD$ hx¤hPÿÔÀƒÄ ƒÈÿ^[Ët$ hhܤVÿäÀ‹D$(ƒÄ …Àt<€8t7ë%‹t$ hhp¤VÿäÀ‹D$(ƒÄ …Àt€8thPVÿèÀƒÄ ^3À[ËL$ hP¤hQÿÔÀƒÄ ƒÈÿ^[Ãì S‹œ$ UV…ÛWÆD$Æ„$Æ„$tÆ‹„$ …ÀtÆ‹„$$ …ÀtÆ‹¼$ ‹-øÀhܤWÿÕ‹ðƒÄ…ö„˃Éÿ3Àò®÷ÑIƒùu‹„$ Ç_^]3À[Ä Ã‹=ôÀƒÆj[Vÿ׃Ä…À„õ‹=DÀL$”$Q„$RPh¼¥Vÿ׃ăøuL$”$QRh¤¥Vÿ׃ĺ…Ût$¼$ƒÉÿ3Àò®÷Ñ+ù‹Á‹÷‹ûÁéó¥‹Èƒá󤋜$ …Ût$¼$ƒÉÿ3Àò®÷Ñ+ù‹Á‹÷‹ûÁéó¥‹Èƒá󤋄$ …Àt‰‹”$$ …Ò„ÿÿÿŠD$„À„®|$ƒÉÿ3Àò®÷Ñ+ù‹Á‹÷‹úÁéó¥‹Èƒá3Àó¤_^][Ä Ã‹-DÀD$Œ$P”$QRh”¥VÿՃăø…ÿÿÿj/Vÿ׃Ä…ÀtD$Œ$PQhˆ¥VÿÕéöþÿÿ€>thT$VRÿäÀƒÄ Æ„$ºéÓþÿÿ‹„$( …À„Îéµhp¤WÿՃąÀtUŠHƒÀ„Ét9‹Œ$$ …ÉthPQÿäÀƒÄ ‹„$ …ÀtÇ_^]3À[Ä Ã‹„$( …ÀtlhL¥ëV…ÿtB€?t=‹„$$ …ÀthWPÿäÀƒÄ ‹„$ …À„ºýÿÿ_^Ç]3À[Ä Ã‹„$( …Àth ¥hPÿÔÀƒÄ _^]ƒÈÿ[Ä ÃSV‹t$ …ö‹Þt1W‹=ØÀ‹F…ÀtPÿ׃Ä‹F…ÀtPÿ׃Ä‹vSÿ׃ċޅöu×_^[Âì,‹„$<‹”$0SUV‹´$@W3Û3ÿ;Ó‰\$‰\$‰|$ ‰\$(‰\$‰\$,‰\$$‰\$‰u;óu_^]¸ù*[Ä,‹„$H;Ä–9X…Þ9X…Õ9X…Ì9X…ËöÁ‰L$t;Óu_^]¸&'[Ä,‹H;Ëtƒùt_^]¸?'[Ä,‹x;û‰|$ t!ƒÿtƒÿtƒÿt_^]¸<'[Ä,‹H ‰L$(;ó„T$,j RVÿÁ‹è‹D$8ƒÄ ‰l$€8u;Uÿ`Á;û‰D$‰D$…Ì¿‰|$$‰|$ éº_^]¸û*[Ä,‹5\Á…ÿtƒÿu!‹Œ$DhÜ¥QÿÖ…Àtf‹@‹è‰D$‰l$…ÿtƒÿu‹”$DhØ¥RÿÖ…Àt f‹X‹ë‰l$f…íu‹Ç_÷ØÀ^%„üÿÿ]ù*[Ä,Â…ÿu,f‹ûf÷ßÿƒÇf…Û‰|$ tfƒ|$ÇD$$uÇD$$‹´$@‹-üÀ…ö„|Š3Ò„À‹Ît"<.uBŠAA„ÀuóƒúuVÿdÁƒøÿ…köD$t ÇD$ù*éJаï¹3À|$5ˆT$4ˆ”$8ó«¹¼$9ó«hL$8D$8VQÇD$<‰D$œ$DÿäÀƒÄ Æ„$4‹´$L‹”$@RÆÇÿTÁ‹è…í„Îfƒ}u=fƒ} u6‹} ‹…Àt-‹‹L$‹T$(P‹D$$QRP臅À‰„݃Çp‹…ÀuÓ‹MhQSÿäÀ‹¼$XƒÄ 3öƃƒ?…Š‹ûƒÉÿ3Àò®÷ÑItu‹D$‹óŠŠÊ:u„ÉtŠPŠÊ:VuƒÀƒÆ„Éuà3ÀëÀƒØÿ…ÀtB‹D$0@ƒø‰D$0t4‹D$‰\$‹Øé ÿÿÿÿPÁÕÿÿƒøwÿ$…<.¾ù*ë.¾ú*ë'¾û*ë öD$tSèN‹‰A‹‹B…Àu¾…ö‰t$…‹D$$…À„Õ‹Œ$L‹9…ÿ„ã‹W‹_ j j‹jÿüÀ‹ðƒÄ…ö„¿jjÿüÀƒÄ…À„ f‹T$¹f‰f‰P‰h‰N‰N‰^ ÇF‰F‹G‰F‰w‹~…ÿ„s뎋D$$öØÀ%ÿÿÿ€PÿXÁj j‹ØÿÕ‹ðƒÄ…ötGjjÿՃąÀuVÿØÀƒÄ3öë,f‹L$‹T$(fÇf‰H‰XÇF‰~‰V ÇF‰F‹„$L…ö‰0„‚‹„$@…À„Þþÿÿ‹ŠD$ƒÉ¨‰„ËþÿÿSÿHÁ‹ð…öt:‹þƒÉÿ3Àò®÷ÑQjÿՋЃÄ…Òt!‹þƒÉÿ3Àò®÷Ñ+ù‹÷‹Ù‹ú‹ÇÁéó¥‹Ëƒá󤋌$L‹‰B‹‹H…É…kþÿÿÇD$‹¬$L‹ØÀ‹u…öt)‹F…ÀtPÿӃċF…ÀtPÿӃċ~VÿӃċ÷…ÿu×ÇE‹D$_^][Ä,ÂVÿØÀƒÄ…ÿu•_ÇD$ ‹D$ ^][Ä,‹ÿà+ç+î+à+V‹t$…öWu_3À^‹þƒÉÿ3Àò®÷ÑQjÿüÀ‹ÐƒÄ…Òu_^‹þƒÉÿ3ÀSò®÷Ñ+ù‹÷‹Ù‹ú‹ÇÁéó¥‹Ë[ƒáó¤_^ÂVW‹=üÀj jÿ׋ðƒÄ…öu_^Âjjÿ׃Ä…ÀuVÿØÀƒÄ3À_^Âf‹L$‹T$f‰H‹L$ ‰P‹T$fljFÇF‰N‰V ÇF‹Æ_^Âì ƒÉÿ3ÀSV‹´$ W‹þò®÷ÑIùv'‹„$( h¤hPÿÔÀƒÄ 3À_^[Ä ˼$( L$W”$Q„$RL$PQVè õÿÿƒÄƒøÿ„‹D$ ƒè„H„ˆHt¹¾8¦ó¥f¥_^3À[Ä ÃWVèiy‹ðƒÄ…ö„Ù‹”$$ RV讃ąÀtVècƒÄ3À_^[Ä Ë„$ ‹Œ$ ‹”$ ‰F ‰N|‰– ‹Æ_^[Ä Ëœ$ ‹„$ ‹”$ ‹ËWƒáPQD$RPè­W‹ðƒÄ…ötm‹…ÀtgöÃtjPèǃĄÀuh¦ëöÃtG‹jQ褃ĄÀu6hà¥hWÿÔÀVèVbƒÄ_^3À[Ä ÃT$WRèœcƒÄ‹ð‹Æ_^[Ä ËD$(ÃìØ‹„$èSU‹¬$øVWƹ3À|$4¾hó«UÇD$@‰t$<‰t$DèˆCƒÄƒøÿu _^] À[ÄØË„$ð…Àt;€8t6hL$UT$Sǃè KƒÄƒøÿu‰D$VǃÿØÀƒÄ‹D$_^][Ä8ø úèISVW‹¼$úÇD$ ‹‡(…À„~·øhVjD$húPjjjèãƒÄ …Àt _^ƒÈÿ[Ä úÃjjL$ j Qè/‹T$hVjD$(húPjjj\H蚃Ä0…Àt _^ƒÈÿ[Ä úËÓ3ɉ ‰JЇ(ˆ‹,QÿXÁ‰C‹T$ ‹hVD$ RPQèéƒÄ…Àt _^ƒÈÿ[Ä úˇhVjT$jRP芃ăøÿu _^ À[Ä úË—jL$h‹QRVèƒÄ=‹tƒøý|I…À|ƒøu@_^ƒÈÿ[Ä úËD$‹ ÁPÿÓ…Àt/‹L$hVQÿÓ‹—PR轃ăøÿu _^ƒÈÿ[Ä úÃ_^3À[Ä úøúèFGS‹œ$úVW‹ûƒÉÿ3ÀÇD$ ò®÷ÑIfùv¹‹„$ú‹ñæÿÿL$VPjQ苼$0úhWjT$(húRjjjèûƒÄ0…Àt _^ƒÈÿ[ÄúÃhWjD$húL$ PQVSèÉƒÄ …Àt _^ƒÈÿ[ÄúËT$ ‹Œ$úhWD$RPQè8ƒÄ÷Ø_^À[ÄúøúèVFSU‹¬$ ú3ÉV;éW‰L$tlf‹Ef‰D$‹E+Át`Ht)‹Œ$,úhÔ¨hQÿÔÀƒÄ ƒÈÿ_^][ÄúË}¾…ÿtƒÉÿ3Àò®÷ÑI‹ñƒÆ‹}…ÿtƒÉÿ3Àò®÷ÑIñë ‰L$¾‹œ$,úhSjT$húRjjjèÈ ƒÄ …Àt_^]ƒÈÿ[ÄúÃæÿÿD$ VjjPè‹L$ hSjT$,húRjjjt Pèy ƒÄ0…Àt_^]ƒÈÿ[ÄúË|$‹Î3ÀW‰‰Aÿ`Áfƒÿf‰…΋}…ÿtƒÉÿ3Àò®÷ÑIf‰NëfÇFhSjT$3Éhúf‹ND$0R‹UPQRèÿ ƒÄ …Àt_^]ƒÈÿ[ÄúË}…ÿtƒÉÿ3Àò®÷ÑIf‰NëfÇFhSjD$3Òhúf‹VL$0P‹EQRPè¦ ƒÄ …Àt_^]ƒÈÿ[ÄúÃf‹N‹=`ÁQÿ×f‹Vf‰FRÿ×f‰F‹D$‹´$$úhSL$(PQVèø ƒÄ…Àt_^]ƒÈÿ[ÄúÃhSjT$$jRVèž ƒÄƒøÿu _^] À[ÄúÃjjD$ hˆPVSè´ƒÄ=ˆtƒøý|C…À|?ƒøu:_^]ƒÈÿ[ÄúËL$‹= ÁQÿ×…Àt)‹T$hSRÿ×PVèÙ ƒÄ…Àt_^]ƒÈÿ[ÄúÃ_^]3À[ÄúÃV‹t$‹Î3ÀŠT$ ‰‰Aˆ‹D$ˆVPÿ`Á‹L$f‰FQÿXÁ‰F^ÃS‹\$ U‹l$V‹t$WVUSèøƒÄ …Àt_^]ƒÈÿ[ÊL$ „ÉtŠET$ <tE:Á„ÊJƒÂ„Éuê‹MjjQÿ ÁPSè hø¨hVÿÔÀƒÄ¸þÿÿÿ_^][ËEPÿ Á‹øhÿVj|BhÿVSè ƒÄ…Àt _^]¸ýÿÿÿ[ÃjÇÿÿÿjWSè§ ƒÄ3ÀƆÿŠE_^][ÃWVSèÛ ƒÄƒøÿu _^]¸ýÿÿÿ[ÃÆ73ÀŠE_^][Ã_^]%ÿ[ÃV‹t$ €>t9‹D$h4©hPÿÔÀ‹NƒÄ jjQÿ Á‹T$PRè% ƒÄƒÈÿ^Ã3À^ÃìTUVW¹3À|$,󫡸ï3í;ʼnl$ ‰l$0ÇD$4u UèYÌÿÿ£¸ïL$ T$,Q‹Œ$hRhà¦QÿЋðVÿpÁ;õtJUhh[hVUhÿÿÀ‹”$hh[h̦hRÿÔÀƒÄƒÈÿ_^]ÄTË=ôZ‹t$ ;ýt*;õt‹FPW踃ąÀtq‹v;õuè‹t$ ‹¿„;ýuÖ;õ„ס¬ï‰t$;Å…¿¡¨ïÇD$£;ÅÇD$(ÇD$£ÇD$ ð5ÇD$$£ÇD$(À't¡ü¢éw‹‡€_^]ÄTÃSŒ$\hQÿ,À…À„;¼$\ƒÉÿ3ÀT$Pò®÷Ñ+ù‹Á‹÷‹úT$PÁéó¥‹È3Àƒáó¤¿Ü¢ƒÉÿò®÷Ñ+ù‹÷‹Ù‹úƒÉÿò®‹ËOÁéó¥‹Ë‹0ÀƒáD$Pó¤PÿÓ‹ð;õ‹-4Àth£VÿÕ…ÀuVÿ8À¼$\ƒÉÿ3ÀT$Pò®÷Ñ+ù‹Á‹÷‹úT$PÁéó¥‹È3Àƒáó¤¿Ô¢ƒÉÿò®÷Ñ+ù‹÷‹ú‹ÑƒÉÿò®‹ÊOÁéó¥‹ÊD$PƒáPó¤ÿÓ‹ð…ötVh£VÿÕ…Àu Vÿ8ÀëA‹ Â3Û…É~|$‹OüQVÿÕ…À‰tÚ‹ ÂCƒÇ;Ù|å3À…É~‹TĉÅì¢@;Á|ð¡ü¢Ç¨ï[£¬ï‹L$QÿÐ_^3À]ÄTÃìVWÿ<À‹ðjD$ hPhVjhÿÿÀ‹¼$…Àuc…ÿ„½‹„$ …Àt+€8t&‹´$Ph¬©VWÿÔÀƒÄÆD7ÿ_^ÄË´$h„©VWÿÔÀƒÄ ÆD7ÿ_^ÄÃ…ÿt^‹„$ …Àt1€8t,L$V‹´$QPht©VWÿÔÀƒÄÆD7ÿ_^ÄÃT$V‹´$Rhd©VWÿÔÀƒÄÆD7ÿ_^Äá¼ïì…ÀuOD$PhÿÁ…Àt;V‹´$˜…ötW‹¼$ hÔ©WVÿÔÀƒÄ ÆD>ÿ_ÿ<ÁƒÈÿ^Äá¼ï@£¼ï3ÀÄá¼ïH£¼ïuÿ%<ÁËD$fƒ8u‹@Pÿ Á%ð-à÷ØÀÊ@þÀöØÀÃìhS‹œ$pUV‹C ‹K‹SWPQRÿ$Á‹øƒÿÿ‰|$u*‹„$Œ‹Œ$ˆPQhLªèØýÿÿƒÄ Ç_^][ÄhË„$€…À„‹‹S‹CRPWÿ4Á…Àt+‹Œ$Œ‹”$ˆQRh@ªèŒýÿÿƒÄ ƒÈÿ_^][ÄhÃ{…‹„$„PWÿ8Áƒøÿ…‹Œ$Œ‹”$ˆQRh4ªè?ýÿÿƒÄ ƒÈÿ_^][ÄhË´$ˆ‹¬$Œ…ÛÆ„¨‹C‹KPQWÿ0Áƒøÿ…ŒT$xhRjèìüÿÿ‹SD$ jdPjjjL$4jdQRèÏ „$¤L$@PQhô©UVÿÔÀ‹þƒÉÿ3ÀƒÄ@ò®÷ÑI‹|$ƒÊÿÆ1 t1+ш‹[ê…Û…qÿÿÿWÿhÁ_^]ƒÈÿ[ÄhÃ…ÛuWÿhÁ_^]ƒÈÿ[ÄhËÇ_^][ÄhÃV‹t$jVÿ,Á…Àt#‹D$‹L$ PQhXªèüÿÿƒÄ VÿhÁƒÈÿ^ÃVÿhÁ3À^á¸ïì,…ÀVW…±¡¨ïÇD$£…ÀÇD$ (ÇD$£ÇD$ð5ÇD$£ÇD$À't ¡ì¢éiSU„$4hPÿ,À…À„;¼$4ƒÉÿ3ÀT$(ò®÷Ñ+ù‹-0À‹Á‹÷‹úT$(Áéó¥‹È3Àƒáó¤¿Ü¢ƒÉÿò®÷Ñ+ù‹÷‹Ù‹úƒÉÿò®‹ËOÁéó¥‹ËD$(ƒáPó¤ÿÕ‹4À‹ð…öth£VÿÓ…ÀuVÿ8À¼$4ƒÉÿ3ÀT$(ò®÷Ñ+ù‹Á‹÷‹úT$(Áéó¥‹È3Àƒáó¤¿Ô¢ƒÉÿò®÷Ñ+ù‹÷‹ú‹ÑƒÉÿò®‹ÊOÁéó¥‹ÊD$(ƒáPó¤ÿÕ‹ð…ötVh£VÿÓ…Àu Vÿ8ÀëA‹ Â3í…É~|$‹OüQVÿÓ…À‰tÚ‹ ÂEƒÇ;é|å3À…É~‹TĉÅì¢@;Á|ð¡ì¢]Ǩï[£¸ï‹¼$D‹Œ$@‹”$<WQ‹Œ$@RQÿЋðVÿpÁ…öt-‹„$H…Àt‹”$LRPhܪèíùÿÿƒÄ _ƒÈÿ^Ä,Ë‹Hƒùt8ƒùt3‹´$H…öte‹¼$Lh°ªWVÿÔÀƒÄ ÆD>ÿƒÈÿ_^Ä,ÃxuC‹@Pè=ûÿÿƒÄ…Àu3‹´$H…öt‹¼$LhhªWVÿÔÀƒÄ ÆD>ÿ_ƒÈÿ^Ä,Ã_3À^Ä,ÃS‹\$U‹-(ÁV‹t$W‹|$jVWSÿÕƒøÿt;Æt/+ðøjVWSÿÕƒøÿuì‹D$$‹L$ PQhìªèöøÿÿƒÄ ƒÈÿ_^][Ã_^]3À[ËT$S‹\$V‹t$W‹ ;Î~(‹t$(…öt‹|$,høªWVÿÔÀƒÄ ÆD>ÿ_^ƒÈÿ[ËL$$…Éu‹|$‹t$‹Êø‹ÁÁéó¥‹Èƒáó¤‹_Â^‰3À[ÃSUVW‹|$3ö…ÿu_^]3À[Ë\$‹l$jWSUÿÁƒøÿt)…ÀtD‹L$ …Étgð;÷t_‹Çj+Æ PQUÿÁƒøÿu׋T$(‹D$$RPhT«èøÿÿƒÄ ƒÈÿ_^][Ët$$…öt‹|$(h(«WVÿÔÀƒÄ ÆD>ÿ_^]ƒÈÿ[ËÆ_^][ø€è¶6S‹œ$€U‹¬$ €V‹´$€W‹¼$ €þ€~*WSjD$h€PUè ÿÿÿƒÄƒøÿt*î€þ€Ö…öt&WSjL$VQUèàþÿÿƒÄƒøÿu_^]ƒÈÿ[Ä€Ã_^]3À[Ä€ÃìXSUV‹´$h…öW„œ€>„“‹þƒÉÿ3Àò®÷ÑQÿÜÀ‹ÐƒÄ…Ò‰T$u-‹„$|‹Œ$xPQh «èÅöÿÿƒÄ ¸þÿÿÿ_^][ÄXËþƒÉÿ3À‹œ$pò®÷Ñ+ù‹-ðÀ‹Á‹÷‹úSÁéó¥‹ÈRƒáó¤ÿÕ‹ðƒÄ…öÇD$„¿¹3À|$43Ò󫡸ï‰T$;‰T$8ÇD$<u Rèÿ¿ÿÿ£¸ïL$T$4QRhà¦VÿЋðVÿpÁ…ötT‹¼$x…ÿ„Zjhh[hVjhÿÿÀ‹´$|h[h̦VWÿÔÀƒÄÆD7ÿé‹t$…öt'‹F‹Œ$tPQè^ƒÄ…À„v‹v…öuÝ‹t$¡¬ï‰t$0…À…Æ¡¨ïÇD$£…ÀÇD$(ÇD$ £ÇD$$ð5ÇD$(£ÇD$,À't ¡ü¢é~”$`hRÿ,À…À„G¼$`ƒÉÿ3ÀT$Tò®÷Ñ+ù‹-0À‹Á‹÷‹úT$TÁéó¥‹È3Àƒáó¤¿Ü¢ƒÉÿò®÷Ñ+ù‹÷‹Ù‹úƒÉÿò®‹ËOÁéó¥‹ËD$TƒáPó¤ÿÕ‹ð…öt‹4Àh£VÿÓ…À…‡Vÿ8Àë‹4À¼$`ƒÉÿ3ÀT$Tò®÷Ñ+ù‹Á‹÷‹úT$TÁéó¥‹È3Àƒáó¤¿Ô¢ƒÉÿò®÷Ñ+ù‹÷‹ú‹ÑƒÉÿò®‹ÊOÁéó¥‹ÊD$TƒáPó¤ÿÕ‹ð…ötVh£VÿÓ…Àu Vÿ8ÀëA‹ Â3í…É~|$‹OüQVÿÓ…À‰tÚ‹ ÂEƒÇ;é|å3À…É~‹TĉÅì¢@;Á|ð¡ü¢‹œ$p‹-ðÀǨï‹L$0QÿÐÇD$SjÿÕ‹ðƒÄ…ö…3ýÿÿ‹D$…À„æ‹Ø¡¬ï…À…Ì¡¨ïÇD$£…ÀÇD$(ÇD$ £ÇD$$ð5ÇD$(£ÇD$,À'……„$`hPÿ,À…À„`¼$`ƒÉÿ3ÀT$Tò®÷Ñ+ù‹Á‹÷‹úT$TÁéó¥‹È3Àƒáó¤¿Ü¢ƒÉÿò®÷Ñ+ù‹÷‹é‹úƒÉÿò®‹ÍOÁéó¥‹Í‹-0ÀƒáD$Tó¤PÿÕ‹ð…öth£Vÿ4À…À…žVÿ8À¼$`ƒÉÿ3ÀT$Tò®÷Ñ+ù‹Á‹÷‹úT$TÁéó¥‹È3Àƒáó¤¿Ô¢ƒÉÿò®÷Ñ+ù‹÷‹ú‹ÑƒÉÿò®‹ÊOÁéó¥‹ÊD$TƒáPó¤ÿÕ‹ð…ötyh£Vÿ4À…Àu$Vÿ8Àë`‹T$RÿØÀƒÄ3À_^][ÄXË Â3í…É~#|$‹OüQVÿ4À…À‰t»‹ ÂEƒÇ;é|á3À…É~‹TĉÅì¢@;Á|ðǨï¡ü¢£¬ïSÿÐÇD$‹´$x…öt‹¼$|h`«WVÿÔÀƒÄ ÆD>ÿ‹D$PÿØÀƒÄƒÈÿ_^][ÄXÃ_^]¸[ÄXËT$V‹t$ f‹f;u1f=u‹B‹NƒÆƒÂ;Áu3À^ÃW~r¹3Òó§_u3À^ÃÈÿ^Ãì0‹”$4UŠŒ$LVf‹Wf‹èÇD$ ÿÿÿÿfƒíf÷Ýíƒå ƒÅöÁuHf=uB¹¿Àïr3Àó§u/‹„$D…Àt‹Œ$HQhð«PÿäÀƒÄ _^ƒÈÿ]Ä0á´ïS…À…¾¡¨ïÇD$£…ÀÇD$(ÇD$£ÇD$ ð5ÇD$$£ÇD$(À't ¡ô¢év”$8hRÿ,À…À„E¼$8ƒÉÿ3ÀT$,ò®÷Ñ+ù‹Á‹÷‹úT$,Áéó¥‹È3Àƒáó¤¿Ü¢ƒÉÿò®÷Ñ+ù‹÷‹Ù‹úƒÉÿò®‹ËOÁéó¥‹Ë‹0ÀƒáD$,ó¤PÿÓ‹ð…öth£Vÿ4À…À…ƒVÿ8À¼$8ƒÉÿ3ÀT$,ò®÷Ñ+ù‹Á‹÷‹úT$,Áéó¥‹È3Àƒáó¤¿Ô¢ƒÉÿò®÷Ñ+ù‹÷‹ú‹ÑƒÉÿò®‹ÊOÁéó¥‹ÊD$,ƒáPó¤ÿÓ‹ð…öt^h£Vÿ4À…Àu Vÿ8ÀëE‹ Â3Û…É~#|$‹OüQVÿ4À…À‰tÖ‹ ÂCƒÇ;Ù|á3À…É~‹TĉÅì¢@;Á|ð¡ô¢‹”$DǨ$X‹œ$P‹¼$HQ‹Œ$XQ‹Œ$TSQWURÿЋðVÿpÁ…ötq‹´$\…öt‹¬$`UVh\¦è\îÿÿƒÄ ÆD.ÿ‹5äÀ…ÿt‹¬$LUhÜ«WÿÖƒÄ ÆD/ÿ…Ût‹¼$TWhÈ«SÿÖƒÄ ÆD;ÿ[_^3À]Ä0ËD$[_^]Ä0øýÿÿÿÃVhDÿÜÀ‹ðƒÄ…öu+ÿàÀ‹Pè- ‹L$PhħhQÿÔÀƒÄ3À^ËT$W¹‘3À‹þRó«ÿÁƒÄ‰†¤…À_u2ÿàÀ‹PèÝ ‹L$PhħhQÿÔÀVÿØÀƒÄ3À^øà…jVdžÌš‰†Ð‰†Ô‰†Ø‰†Ü‰†à‰†ä‰†è‰†ì‰†ð‰†ô‰†øÇ†ü0‘è¶hÿÿVèKƒÄdž¨Ç† ‹Æ^ËD$‹H0…Éth¼hPÿÔÀƒÄ ƒÈÿÃ3ÀÃV‹t$VèÅÿÿÿƒÄ…Àt¸üÿÿÿ^ËD$ ‰F3À^ÃV‹t$Vè•ÿÿÿƒÄ…Àt¸üÿÿÿ^ËD$ ‰†¨3À^ÃV‹t$VèeÿÿÿƒÄ…Àt¸üÿÿÿ^ËD$ ‰†Œ3À^ÃV‹t$Vè5ÿÿÿƒÄ…Àt¸üÿÿÿ^ËD$ ‰† 3À^ÃV‹t$Vÿ–ȃÄ…À|ÇF0^ÃS‹\$VW‹|$ WSè!‹ðƒÄ…öu_^[ËD$PVèöþÿÿƒÄ…À|8‹L$QVèÿÿÿƒÄ…À|&‹T$RVè2ÿÿÿƒÄ…À|VÇF4è~ÿÿÿƒÄ…À}fƒøÿt5ƒøût0ƒøøt+PèòPSh0¼hWÿÔÀƒÄVèf ƒÄ3À_^[ÆhPWÿäÀƒÄ ƇÿVè: ƒÄ3À_^[ËÆ_^[ÃV‹t$‹†$…Àt‹†4…ÀuVèQÇÿÿƒÄ…ÀtƒÈÿ^ËD$‹L$‹T$ PQRVÿ–ЃÄ^ËD$‹L$ ‹T$P‹D$QRPÿЃÄÃSUV‹t$W‹†$…Àt‹†4…ÀuVèÞÆÿÿƒÄ…Àt_^]ƒÈÿ[Ë\$ ‹l$‹|$‹F<…ÀtSUWV賃ÄëSUWVÿ–ЃÄ…Àtï…À~ …ÿ~Ò+ø…ÿÌ3À_^][Ãì‹T$ ‹D$L$‰D$Qh0ŠjRèïþÿÿ3É…À‹D$žÁI#ÁƒÄËD$‹L$V‹‹1‰2‹q‰r‹q‰r‹I ^‰J ‹T$ ‰PÃìS‹\$V‹t$W‹|$ †‰|$‰D$ ‰‹†$…Àt3‹†4…ÀuVèÔÅÿÿƒÄ…Àt _^ƒÈÿ[ƒÄÃWSVèë¶ÿÿƒÄ _^[ƒÄËF<…Àt%D$ Ph‹jV蘃ąÀu"_^¸þÿÿÿ[ƒÄÃL$ Qh‹jVÿ–ЃÄ_^[ƒÄËD$‹L$V‹‹1‰2‹q‰r‹q‰r‹I ^‰J ‹P‹D$ ‰ËD$Ç@8ËD$‹@ ÃS‹\$‹ƒ …ÀuOjÿÜÀ‹L$ƒÄ…À‰u.ÿàÀ‹Rè®PhħÃhSÿÔÀƒÄƒÈÿ[ËK [‰¸ÃPjÿüÀ‹T$ƒÄ…À‰u ÿàÀ‹P뮋‹ V‹³WÁá‹Ñ‹øÁéó¥‹Êƒá󤋃 _^[ÃSVW‹|$‹ …Étf‹Ÿà…Ût\‹t$3À…É~‹—92t@ƒÂ;Á|ô;Á}Gƒùu‹‡ƒ8uþu ‰w _^3À[ÃVWÿӃăøÿu_^ À[Éw _^3À[Ët$‹G ;ÆtÔVèøƒÄ…ÀtPhp¼ëVh8¼ÇhWÿÔÀƒÄƒÈÿ_^[ËD$3ÉSVŠ‹t$‹Ñ3ÉŠŠ™€ÂN8š€ÂuŠ@„Òt53Ò3ÛŠŠAŠ’€Â8“€Âtâ3Ò^ŠQÿ3É[ŠŠ€Â3ÒŠ3ÀŠ‚€Â+ÁÃ^3À[á¬SVW3ÿ…Àt+‹\$¸¬‹ð‹SƒÀPèkÿÿÿƒÄ…Àt‹N ƒÆ G‹Æ…Éuà_^ƒÈÿ[à _^[‹ ¬á¬3É…ÀVt‹T$¸¬9Pt‹p ƒÀ A…öuð3À^ÃI^‹…¬ƒÀá¬3É…ÀVt‹T$¸¬9Pt‹p ƒÀ A…öuð3À^ÃI^‹…¬ËD$‹@ËD$‹@@ËD$‹@LËD$‹@PËD$‹@<ËD$‹ˆ$…Ét‹€,Ë…Àt‹ÃƒÈÿËD$‹L$‹ ÁPQƒÂ@h¤¼RÿÁƒÄËD$ËD$P‹D$PÿäƒÄËD$ ‹L$P‹D$QPÿèƒÄ ÃVWÿ<Àjh‹ðhüïjVjhÿÀ¿üïƒÉÿ3Àò®÷ÑIƒù| ˆûïˆúïjhüïÿôÀ¹ýðV+Èh¬¼QPÿÔÀƒÄ¸üï_^ËL$A ƒø wIÿ$…¸P¾ø ¾ø¾øì½øȽøŒ½øt½øH½ø½øà¼øȼÃQh´¼jhàïÿÔÀƒÄ¸àïÃIßÙÓÍÇÁ»µ¯å£©‹D$PÿHÀƒÄËD$P‹D$Pÿ؃ÄËL$‹Ü…Àuh`¾ÁhQÿÔÀƒÄ ƒÈÿËT$RQÿЃÄËD$P‹D$PÿìƒÄËD$P‹D$PÿðƒÄËD$P‹D$PÿôƒÄËD$P‹D$PÿøƒÄÃV‹t$W‹=ØÀ‹†´…ÀtPÿ׃Ädž´‹†…ÀtPÿ׃Ädždž ÆVè &ƒÄ_^ÃhDÿÜÀ‹ÐƒÄ…ÒuÃW¹‘3À‹úó«‹D$ ‹L$‰B‰J Ç‚ì’Ç‚ð0’Ç‚ô`’Ç‚ø’Ç‚üÀ’ÇB0‹Â_ËD$h˜¾hPÿÔÀƒÄ ƒÈÿËD$hÔ¾hPÿÔÀƒÄ ƒÈÿËD$h¿hPÿÔÀƒÄ ƒÈÿËD$hH¿hPÿÔÀƒÄ ƒÈÿÃËD$ ‹L$P‹D$QPÿÔƒÄ @÷ØÀ÷ØHËD$ ‹L$P‹D$QPÿÔƒÄ ÃV‹t$W‹=ØÀ‹†¤…ÀtPÿ׃ÄVÿ–üVÿ׃Ä_^ËD$‹H…Ét‹D$‹P‹@ R‹T$PRQè~ȃÄÃ3ÀáÔïU…ÀW…æSVèÆ‹è¸°Ã‹õŠŠŠÊ:Óu„ÉtŠPŠ^ŠÊ:ÓuƒÀƒÆ„ÉuÜ3ÀëÀƒØÿ^[…À¿€ÃuJƒÉÿ3Àò®÷ÑI¿°Ã‹ÑƒÉÿò®÷ÑID PÿÜÀh€Ãh°Ãh¸ÃP£ÔïÿÐÀ¡ÔïƒÄ_]ÃÉÿ3Àò®÷ÑI¿°Ã‹ÑƒÉÿò®÷ÑI‹ýуÉÿò®÷ÑID 2PÿÜÀh€ÃUh°ÃhØÃP£ÔïÿÐÀ¡ÔïƒÄ_]ÃVW‹|$ €?-uJŠG„ÀuC‹5 Áh€‹FPÿÄÀƒÄ‹D$PVèë‹øƒÄ…ÿu;5 Át VÿìÀƒÄ‹Ç_^ÃhøÂWÿLÀ‹ðƒÄ…öuÀÿàÀ‹QèHûÿÿ‹T$PWh0¼hRÿÔÀƒÄ3À_^ËD$jPÿhÀƒÄ…À}%ÿàÀ‹Qèþúÿÿ‹T$ PhRÿÔÀƒÄ3ÀÃhøÂPÿlÀƒÄ…Àu%ÿàÀ‹PèÆúÿÿ‹L$ PhQÿÔÀƒÄ3ÀËT$RPèƒÄÃìUVWhDÿÜÀ‹ðƒÄ…öu(‹t$,hhŒÃVÿäÀƒÄ Ɔÿ3À_^]ƒÄËl$(¹‘3À‹þó«UjD$jPÿpÀƒÄƒøtnöE t:ÿàÀ‹Qè#úÿÿ‹T$0PhpÃhRÿÔÀƒÄVÿØÀƒÄ3À_^]ƒÄÃP‹D$0jh(ÃhPÿÔÀƒÄVÿØÀƒÄ3À_^]ƒÄËD$ =Ôò¡‹øtx=4Ͳ¡ty‹È‹ÐçÿâÿÁéÁà ù ÐÁïÁâ úÿÔò¡t3ÿ4Ͳ¡t+‹D$,hÃhPÿÔÀƒÄ VÿØÀƒÄ3À_^]ƒÄÃL$ ÇF@QèGƒÄÿ4Ͳ¡u ÇFDëÇFDfƒ|$s+‹T$,hüÂhRÿÔÀƒÄ VÿØÀƒÄ3À_^]ƒÄËD$‰F(‹L$‰N‹T$ âÿÿÿR蛉F ‹L$$ƒÄáüÿ4Ͳ¡‰N$u ƒøuƒF‰n<‹T$HJ‰Ž°tƒè t3ÿë ¿ë¿3í;Í} dž°€‹†°ƒÀPÿÜÀƒÄ;ʼnFTu2‹|$,hhŒÃWÿäÀƒÄ ƇÿVÿØÀƒÄ3À_^]ƒÄÃç+ǃÀ‰†´‹L$áÿÿ‰NL‹T$âÿÿ‰VP‹D$%ÿÿƒèt-u'ÇFHë!‹D$f=s ÇFHëu ÇFHë‰nHdžÐp›džÔàšdžØ0[džÜ›‰®àdžäšdžèšÇ†ì šdžðPšdžô€šdžø°šdžü@›ÇF0‹Æ_^]ƒÄË ”¿‹D$V3öƒùÿtº”¿;Èt‹JƒÂFƒùÿuð^Ëõ¿^ËD$3ÒVf‹HŠÕŠñf‹Hf‰P3ÒŠÕŠñ‹Hf‰P‹Ñ‰L$áÿÁâ Ñ3ÉŠL$ Áâ Ñ3ÉŠl$ Ñ‹H ‰P‹Ñ‹ñâÿÁî Ö‹ñÁæáÿ ñ‹HÁêÁæ Ö‹ñ‰P ‹ÑâÿÁî Ö‹ñÁæáÿ ñ‹HÁêÁæ Ö‹ñ‰P‹ÑâÿÁî Ö‹ñÁæáÿ ñÁêÁæ Ö^‰PÃ3ÀËD$h˜ÃhPÿÔÀƒÄ ƒÈÿËD$hÄÃhPÿÔÀƒÄ ƒÈÿËD$hÄhPÿÔÀƒÄ ƒÈÿËD$h8ÄhPÿÔÀƒÄ ƒÈÿÃV‹t$hhxĆPÿäÀƒÄ ƆƒÈÿ^ËD$h¨ÄhPÿÔÀƒÄ ƒÈÿË ÁV‹t$‹F<;Át PÿìÀƒÄ‹FT^…ÀtPÿØÀYÃìSU‹l$ V‹t$ W3Û‹F8…À…‹†°‹Ž´PT$QRVè+‹ÈƒÄ…É…þ‹†…Àt‹L$‹T$Q‹Ž´RQPèÀƒÄ…Àt§ƒ¾8u‹ñB™÷¾<…Ò‰ñu„ƒ¾8ul‹|$¡ñ;øŒjÿÿÿ‹L$u ; ñŒXÿÿÿ‹†<€€€ Áù@B‰ ñ~)¸ƒÞC÷éÁú‹ÂÁèЋÁ×¹@B‰ñ™÷ù‰ ñ‹–´‹L$0D$RPQÿT$8ƒÄ C;ÝŒîþÿÿ…í*éåþÿÿ…Ûu!‰^8_^]¸þÿÿÿ[ƒÄËÁ_H^÷ØÀ]#Á[ƒÄÃ_^‹Ã][ƒÄÃì SUV‹t$0WL$‹~<‹FDWPjQ‰|$ ÿpÀ‹NDƒÄ;Át<öG tÿàÀ‹Rè.óÿÿPhpÃé…Àt PQhHÅé _^]¸[ƒÄ ËF@…À„¶‹D$ ‹L$8‹Ð‹øâÿiÁï ׋øçÿ‰l$8Áà ø‹D$$ÁêÁç ׋ø‹ØçÿÁë û‹Øãÿ‰UÁà Ø‹D$ÁïÁãQ û‰:‹øçÿÁà ø3ÀŠd$Áç ø3ÀŠD$ ø‹D$‰9‹øçÿÁà ø3ÀŠD$Áç ø3ÀŠd$ ø‰y‹|$ë(‹D$8‹L$ hP ‰l$8‰M‹L$$‰ ‹L$‰‹L$‰H‹FHHt Hu‹E‹ ;Áv ‹E‹ ‰M‰‹E‹\$@;ƪ=ÿÿvh0ÅëN9ñsf‹ ñÿÁè Áà …É£ñtQÿØÀ¡ñƒÄPÿÜÀƒÄ£ñ…Àu/£ñhÅÆhVÿÔÀƒÄ ƒÈÿ_^][ƒÄ áñ‹UWRjPÿpÀ‹MƒÄ;Át#öG „@ÿàÀ‹PèAñÿÿPhpÃé.‹Ë‰]‹\$<‹5ñ‹Ñ‹ûÁéó¥‹Êƒáó¤‹t$4‹F@…À„¶~ ½…©ƒ}‚Ÿ‹s‹‹î¹‹Ö‰D$3ÿåÿè2 ø 깋NjÕè ‹þ3Éçÿ Á ×¹è‹þ3Éçÿ Á ×¹èð‹|$‹è‰l$4‹ê¹‹Ç‹Öè¶3Éçÿ Ñ Ç¹è ‹L$3öáÿ Ö Á¹è†‹L$ Öáÿ Á¹èn‹L$4‹t$8 È ê‰ ‰kƒ>‚Âf‹C 3ÒŠÔŠðf‰S ‹ƒø‚©‹{‹s¹‹Ç‹Ö‰|$èó‹î%ÿ3É3Òåÿ Á Õ¹èÔ‹è3À‰l$4‹ê‹Ö‰l$<‹l$4‹ÎÁúâÿ ê3Ò‰l$4‹l$< è‹Ç‰l$<‹l$4Áé 鹉l$4‹l$< ê‹Öè²3Éçÿ Ñ Ç¹èœ‹L$3öáÿ Ö Á¹è‚‹L$ Öáÿ Á¹èj‹L$4 ê ȉK‹L$8‰kƒ9‚½‹C‹Ð‰D$8Áâ%ÿ Ð3ÀŠD$;Áâ Ð3ÀŠd$: ЉS‹ƒø ‚‰‹C‹Ð‰D$8Áâ%ÿ Ð3ÀŠD$;Áâ Ð3ÀŠd$: ЉS‹ƒø$rY‹C ‹Ð‹ðâÿÁî Ö‹ðÁæ%ÿ ðÁêÁæ Ö‰S ‹ƒø(r)‹C$‹È‹ÐáÿÁê Ê‹ÐÁâ%ÿ ÐÁéÁâ ʉK$_^]3À[ƒÄ Ë\$-u%ŠF„Àu‹ Á¾ÅB VPWS蔃Ä_^[ÃhŒÅVÿLÀƒÄ…ÀuÝÿàÀ‹PèììÿÿPVh0¼ÃhSÿÔÀƒÄ3À_^[á¿3ÒƒøÿVt‹t$¹¿;Æt‹AƒÁBƒøÿuðƒÈÿ^ËÕ”¿^á ÁV‹t$ƒÀ ;ðWu‹Nh€QÿÄÀë jVÿ\À‹|$‹L$ƒÄ‹W‹G(RPQVèZƒÄƒøÿuJÿàÀ‹Rè$ìÿÿP‹D$ PhÔÅÇhWÿÔÀ‹ ÁƒÄƒÁ ;ñt VÿìÀƒÄ_3À^ËÆ_^Ãì‹D$$‹L$(‹T$ ‰D$‹D$‰L$PjL$jQÇD$Ôò¡fÇD$fÇD$ÇD$‰T$$ÿ`ÀH÷ØÀƒÄ(ËD$ËD$PÿdÀƒÄËD$PÿTÀƒÄ@÷ØÀ÷ØHËD$PÿìÀYÃì UVD$3öPV‰t$‰t$è8 ƒÄ„Àu2ÿ<Àƒøzt'èÏéÿÿ‹L$Ph ÆhQÿÔÀƒÄƒÈÿ^]ƒÄ ËD$;Ɔ$PÿÜÀ‹èƒÄ;îu!‹T$hìÅhRÿÔÀƒÄ ƒÈÿ^]ƒÄ ÃD$PUè· ƒÄ„Àu.èYéÿÿ‹L$Ph ÆhQÿÔÀUÿØÀƒÄƒÈÿ^]ƒÄ Ëõ€>uŠF„ÀtFëñŠEƒÆSW„À‹Ýt=‹T$$D$RVSP蠃ăøÿt:‹ûƒÉÿ3Àò®÷ÑI‹þ\ ƒÉÿò®Š÷ÑI„ÀtuËL$$T$QRèõ ƒÄ…À}!‹D$ÇD$ÿÿÿÿ…ÀtPèX¿ƒÄ3À‰D$ë‹D$‹L$ U‰ÿØÀ‹D$ƒÄ_[^]ƒÄ ËT$3À‰2^]ƒÄ øè ‹„$‹Œ$ S‹œ$VW‹¼$$3öWPVST$ QRÇD$$èăøÿu _^ À[ÄÃD$ L$PQSèR ƒÄ „Àu _^3À[ÄËD$ ‹ÐH…Ò‰D$ ~E‹L$…Ét=@WÁàj”R” D RPQè,‹ðƒÄƒþÿt‹D$ ‹ÈH…ɉD$ »‹Æ_^[ÄÃVWjÿÜÀ‹ð3ÿƒÄ;÷u-ÿàÀ‹Pèèÿÿ‹L$$PhħhQÿÔÀƒÄƒÈÿ_^ËD$‰>;Çth€PèɺƒÄ;ljFué ‰~‹D$;Çt5h€P褺ƒÄ;ljFu#ÿàÀ‹Qèèÿÿ‹T$$PhħhRë~‰~‹D$;Çt5h€PèdºƒÄ;ljF u#ÿàÀ‹PèÜçÿÿ‹L$$PhħhQë>‰~ ‹D$;ÇtIh€Pè$ºƒÄ;ljFu7ÿàÀ‹RèœçÿÿP‹D$(hħhPÿÔÀVÿØÀƒÄƒÈÿ_^É~‹T$ ‹B ;Çt‹;Ït‹Áëö;Çu‰r _3À^É0_3À^Ã|$u h`_ÿÀ¸ ìD$PhÿÁ÷ØÀÄÃS‹\$VW‹ûƒÉÿ3Àò®÷ÑIƒùu_SÿÌÀxWÿÜÀ‹ðƒÄ…öu‹D$h@ÆhPÿÔÀƒÄ 3À_^[ÃSh<ÆWVÿÔÀ‹L$$QVè7ÜÿÿV‹øÿØÀƒÄë‹T$RSèÜÿÿƒÄ‹ø…ÿu_^3À[ÃWèYÃăøuLJÈn‹Ç_^[ÃLJȪ‹Ç_^[Ãì$ U‹¬$, VWµ„$(VL$(P”$4Q‹¤D$RPQ‰t$(è_zÿÿƒÄ…À…P‹D$ ƒøu2jUèCžÿÿƒÄ…À…7‹…¨3Ò…À•Â_‰•0^3À]Ä$ Ãøu~‹…¤jhܤPÿÈÀƒÄ …Àuc‹½¤ƒÉÿò®÷ÑIƒétPQÿÜÀ‹ÐƒÄ…Òt@‹½¤ƒÉÿƒÇ3Àò®÷Ñ+ù‹Á‹÷‹úÁéó¥‹Èƒá󤋅¤‰•¤PÿØÀ‹t$ƒÄ‹…¬3ÿ;Çt_^¸úÿÿÿ]Ä$ Ãèæýÿÿ‹¤QèFƒÄ;ljEu'è»ãÿÿPh´ hVÿÔÀƒÄƒÈÿ_^]Ä$ ÃT$RPèƒÄ„Àu0è‚ãÿÿPhLÇhVÿÔÀƒÄU藃ăÈÿ_^]Ä$ ËD$ƒøwutjƒø‡«ÿ$…h®jÇE ÿÜÀƒÄ;lj…„‹Ç‹…Ç@Ç… ëlÇE ëcÇE ëZÇE ëQÇE ëHƒÀƒøw9ÿ$…ˆ®ÇE hë0ÇE 2ë'‰} ë"ÇE iëÇE ëÇE ÀëÇE 9½¨t+‹Mj QèîƒÄ„ÀuGhÇhVÿÔÀƒÄ éñþÿÿ‹Uh€RèÀƒÄ„ÀuhàÆhVÿÔÀƒÄ éÃþÿÿÇ…°èè‹;ljEuh¸ÆhVÿÔÀƒÄ é”þÿÿ‹Eö€`…„þÿÿ9½ u Ç… @B‹ QPè6ƒÄ„ÀuhxÆhVÿÔÀƒÄ éEþÿÿ‹•°RÿÜÀƒÄ;lj…´u(ÿàÀ‹PèºâÿÿPhħhVÿÔÀƒÄéþÿÿ‹°‹UQPRè‹Eh€>P葃ĄÀuèEáÿÿPhPÆé¾ýÿÿ‹Œ‹UQR舃ĉ½Ü‰½àÇ…ÐÀ¯_Ç…Ø€²Ç…Ô°±Ç…äвÇ…èà²Ç…젮Džðð®Ç…ô@¯Ç…ø€¯Ç…ü@²^3À]Ä$ ÃIÔ«¬¬x¬x¬x¬%¬%¬o¬f¬]¬O¬F¬X¬‹D$V‹t$P‹QèàƒÄ<t%èRàÿÿPhtÇÆhVÿÔÀƒÄƒÈÿ^Ã3À^ÃV‹t$‹†$…Àu3‹D$ ‹PQèhƒÄ„ÀuhxÆÆhVÿÔÀƒÄ ƒÈÿ^Ã3À^ËD$V‹t$P‹QèòƒÄ„ÀuhÇÆhVÿÔÀƒÄ ƒÈÿ^Ã3À^ËD$V‹t$P‹Q较ĄÀuh¼ÇÆhVÿÔÀƒÄ ƒÈÿ^Ã3À^ÃQS‹\$ 3ÉU‹ƒ¼V;ÁW‰L$u]9K8t_^‰K8]¸þÿÿÿ[YËC‹ jPQèžƒÄ „Àu#høÇÃhSÿÔÀƒÄ ƒÈÿ_^][YËK‹A ‹q ‰L$닳¸ ‰L$ë‹L$‹C8…À…;ñƒ?‹ƒ8‹n3ÿƒøf‹~u$‹ñB™÷»<…Ò‰ñt D/$üð뵃»8up‹‹ ñ;ÂŒšu‹V¡$ñ;ÐŒˆ‹ƒ<‹N€€€ Áù@B‰ $ñ~+¸ƒÞC÷éÁú‹ÂÁèЋЋÁ‰ ñ¹@B™÷ù‰$ñ‹L$$7PVQÿT$,‹D$‹L$(T/ƒÄ ƒâüò@;Á‰D$Œ ÿÿÿ‹Á…À=éþþÿÿT/ƒâüòéôþÿÿ‹D$…Àu_^‰C8]¸þÿÿÿ[Yɳ¸+Î_^‰‹¼][YËD$‰³¸+Æ_^‰ƒ¼‹D$][YËD$_^ǃ¼][YÃSVWè‹ð…öu$‹D$hDÈhPÿÔÀƒÄ ƒÈÿ_^[Ë|$‹L$WQVè@‹\$jV‹R裃ĄÀu'h ÈÃhSÿÔÀVèyƒÄƒÈÿ_^[ÃVèiƒÄ‹Ç_^[ÃV‹t$‹…ÀtPèYƒÄÇ‹F…ÀtPè7ƒÄÇFVè¹ÞÿÿƒÄ^ËD$V‹t$P‹QèƒÄ„Àu%èrÜÿÿPhlÈÆhVÿÔÀƒÄƒÈÿ^Ãdž¼3À^ËD$‹@ËD$VW‹|$ …ÀtƒÎÿë‹·Œ‹VPèlÿƒÄ„Àu&èÜÿÿPh”ÈÇhWÿÔÀƒÄƒÈÿ_^Ã3Ƀþÿ”Á‰O_3À^ËD$‹L$PQèQ¸ƒÄáàñ…Àt"‹T$L$QRhPèBÛÿÿƒÄPÿPÀƒÄjhLòÿXÀS‹\$VW‹ûƒÉÿ3Àò®÷ÑI‹ñFVè$‹øVSWÿäÀƒÄ…ö~ÆD7ÿ‹Ç_^[ËD$UVWh¡Üñƒåü‹ ÅHñ4ÅHñ;évnƒÆ@ƒø£Üñ‹ø| hÄÈèBÿÿÿƒÄS»‹ÏÓãSÿÜÀƒÄ‰F…Àu hÄÈèÿÿÿƒÄ‹~‹Ë‹Ñ3ÀÁéó«‹Êƒá;ëóª‰[v hÄÈèñþÿÿƒÄ‹>‹F+ý‰>‹Ï_^Á]ÃVh`_ÿÀ‹D$‹L$‹T$P‹D$Q‹L$RPQèƒÄ‹ðh`_ÿÀ‹Æ^ÃU‹ìƒìSV‹uW‰uü‹]‹C …Àt;{ Àu2‹þƒÉÿ3Àò®÷ÑIt$h<ÉÃhSÿÔÀƒÄ ƒÈÿ_^[‹å]˃$…Àt^öƒ0tU‹ƒ@…Àt PÿØÀƒÄ…öt‹þƒÉÿ3Àò®÷ÑI‹ñFë¾VÿÜÀ‹MVQP‰ƒ@ÿäÀ‹“@ƒÄÆD2ÿ3À‰àñ£P_£€V£,òè¸kjhLòè ÿƒÄ…Àtè`ðèƒÈÿ_^[‹å]Ë}‹EW£<ñè0ØÿÿƒÄ£4ò…Àu$hÉÇhWÿÔÀƒÄ ƒÈÿ_^[‹å]ËEü…À‹Eüu¸°ïPèÛïWèƒÄèÍÀ¡€V…Àt hôÈèýÿÿƒÄ¡,ò…Àu‹ 4òQèƒÄ£,ò‹M…Ét?‹ P_…Éu5h,ò诡,òƒÄ…Àt ƒxu‹H…ÉuhÔÈè¼üÿÿ¡,òƒÄUøRPèz ‹M ƒÄ‰A‹Eø‰èWïè_^3À[‹å]ÃVW‹=ØÀÇÜñ¾Lñ‹…Àt Pÿ׃ÄǃÆþÌñ|ã_^ÃhÐè¶üÿÿ‹L$ƒÄÇ@‰@`‰HËD$‹L$VPQè@Úÿÿ‹ðƒÄ…öuƒÈÿ^ËT$‹D$‹L$WR‹T$PQRVèýÿÿV‹øèŸÛÿÿƒÄ‹Ç_^ÃV‹t$‹FÇ…ÀtPÿØÀƒÄÇF^ÃV‹t$‹F`PèBƒÄ芅Àt VPèoƒÄ‹ 4òQè0ÿÿÿPVè)‹F,3Ò…À”Âj‰V,èÿÿÿPVè‹F`ƒÄ£,ò^ËD$…Àt‹T$‹H,…Éu‹H<‰P<ë‹HT‰PT…É‹ÁuåÃV‹t$ W‹|$ ‹F`PWè¼ÿÿÿ‹W,3É…Ò”Á‰O,‹F,3ÒW…À”ÂV‰V,è‹N,ƒÄ3À…É”À‰F,‹O`‰N`_^ËL$D$…Ét‹‹H,…ÉuƒÀ<ëƒÀTƒ8uê‹L$‰ËT$‰ÃV‹t$3ÀW‹N,‹|$…É”À‰F,‹O`QVè/ÿÿÿ‹F,3Ò…À”ÂVW‰V,è›ÿÿÿ‹F`ƒÄ‰G`_^ËD$3É‹P,…Ò”Á‰H,ËD$VPèÒÿÿ‹ðƒÄ3ÒƒÉÿþ׉5Dò‰Hò‰ò‰”ò‰ 8ñ‰ 4ñ‰ äñ‰ Øñ‰Œò‰ Èñ‰ ,ñ‰ (ñ‰ 8ò‰ 0ñ‰Ìñ‰èñ‰@ñ‰ °È‰ ´È‰¸È‰ @ò‰ Dñ‡©3ÀІ8¿ÿ$… ¾Ç<òÇèñ‰Ðñ‰Ôñ^ÃÇ<òÇèñ‰Ðñ‰Ôñ^ÃÇ<ò Çèñ‰ÐñÇÔñ^É <òÇèñ‰Ðñ‰Ôñ^É <òÇèñ‰Ðñ‰Ôñ^É<òÇèñ‰Ðñ‰Ôñ^É<òÇèñ ‰Ðñ‰Ôñ^ÃÇ<òÇèñ‰Ðñ‰Ôñ^ÃÇ<òÇèñ‰Ðñ‰Ôñ^ÃÇ<òÇèñ‰Ðñ‰Ôñ^ø ÇÐñ£<ò£èñÇÔñ^øÇÐñ£<ò£èñÇÔñ^ÃÇ<ò‰èñÇ@ñÇÐñÇÔñ^É<ò‰èñÇÐñÇÔñ^øÇ4ñ£ò£8ñ¸‰äñ‰ Hò£Øñë'Ç<òÇèñ‰Ðñ‰Ôñ^ø£<ò£èñÇÐñÇÔñ^É <ò‰èñ‰Ðñ‰Ôñ^É <ò‰èñÇÐñ‰Ôñ^ÃÇ<òÇèñ‰Ðñ‰Ôñ^ÃÇ<òÇèñ,‰Ðñ‰Ôñ^ø£<ò£èñ‰Ðñ‰ Ôñ^øë¸£<ò£èñ‰ÐñÇÔñ ^ÃÇèñÇ<òÇÐñÇÔñ^ÃÇ<òÇèñ‰Ðñ‰ Ôñ^ÃÇ<òÇèñ ‰Ðñ‰ Ôñ^ÃÇ<òéȸ é9ÿÿÿÇ<ò é¯Ç<òé Ç<ò鑸ÇÈñÇ,ñ£(ñ£8òÇ0ñë\¸ÇÈñÇ,ñ£(ñ£8òÇ0ñ ë-¸ÇÈñÇ,ñ£(ñ£8òÇ0ñ‰ <ò‰ èñ‰ Ðñ‰ Ôñ^É <ò‰ èñ‰ Ðñ‰ ÔñÇHò^ÃVh”ÉèÇôÿÿƒÄ^Ëÿšº8ºa»ô¹^ºÖº<»¶»P¼|º»øºª¼†»¸º ¼+¼Ø»º̼½]½ð¼˜½é¼ˆ¼ô½ŽP¾޽½;½j¼§½¶½#¾j¾޾%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%% %%%%%%%% %%%%% %%%%%%%%%%%%%%%%%%%%% %%%%%%%%% !%%% "#!$%%%%%%%%%%%%¡DòVƒÀ‰WƒøIw33ÉŠˆ°Àÿ$œÀè-‹ðëè4‹ðëè‹‹ðë èR‹ðë3ö‹Dò‹|$ B—ƒøWw3ÉŠˆÁÿ$üÀ‹WRVèñƒÄ‹ð…öt‹GPVè®ZƒÄ‰w_^Ã.À@À7ÀIÀRÀ‹ÿuÀ„À¡@òU½ƒøÿ‰-P_„íSVWjè\òÿÿ‹ðjÇ ÇF èFòÿÿPVÇTÇ@ ðÿÿè’Yjè+òÿÿ‹øWVÇÇG !€èuYjèòÿÿ‹ØSVÇ ÇC èXYj‰_èîñÿÿ‹ØSVljk èàVWjjjèãóÿÿhЋøè7Óÿÿ‹ðVÇFE‰v`ÇFÿ‰~è[ØÿÿƒÄ‹Æ_^ËD$‹L$PjQjè­òÿÿƒÄËD$SVWPjjjèòÿÿ‹Ø‹D$(ƒÄƒø‡­ÿ$…Èá‹L$Qj踃Ä‹ðVSè×ÿÿƒÄ‹Æ_^[ËT$Rj藃ċðVSèûÖÿÿƒÄ‹Æ_^[Ët$VjèvVj‹øèl‹ðVWèS×ÿÿƒÄVSèÉÖÿÿƒÄ‹Æ_^[Ët$VjèDVj‹øè:‹ðVWè¡ÖÿÿƒÄVSè—ÖÿÿƒÄ‹Æ_^[Ãÿ%¸À^áá=á^áá‹D$‹L$PjQjèñÿÿƒÄËD$ SUVWPjj jè|ñÿÿ‹ðèuþÿÿ‹èUVè,Öÿÿ‹D$8ƒÄƒø‡Çÿ$…ã‹L$‹T$QRjèÔƒÄ ‹ðVUèøÕÿÿƒÄ‹Æ_^][ËD$‹L$PQjè­ƒÄ ‹ðVUèÑÕÿÿƒÄ‹Æ_^][Ët$‹|$VWjè†VWj‹Øè{‹ðVSè"ÖÿÿƒÄ VUè˜ÕÿÿƒÄ‹Æ_^][Ët$‹|$VWjèMVWj‹ØèB‹ðVSèiÕÿÿƒÄ VUè_ÕÿÿƒÄ‹Æ_^][Ãÿ%¸ÀI‰â;âbâ‰âÂâ‹D$SV‹t$;ÆW~‹È‹Æ‹ñ‹|$PjWjè,VjWj‹ØèO‹ðVSèöÔÿÿƒÄ(‹Æ_^[ËD$‹L$ ‹T$P‹D$jj0jÿQRPèaðÿÿƒÄËD$‹L$ ‹T$P‹D$jj jÿQRPè1ðÿÿƒÄËD$ SUVWPjjjè¬ïÿÿ‹è‹D$0ƒÄƒø‡Çÿ$…Ää‹L$‹T$QRjèÒƒÄ ‹ðVUè6ÔÿÿƒÄ‹Æ_^][ËD$‹L$PQjè«ƒÄ ‹ðVUèÔÿÿƒÄ‹Æ_^][Ët$‹|$VWjè„VWj‹Øèy‹ðVSè`ÔÿÿƒÄ VUèÖÓÿÿƒÄ‹Æ_^][Ët$‹|$VWjèKVWj‹Øè@‹ðVSè§ÓÿÿƒÄ VUèÓÿÿƒÄ‹Æ_^][Ãÿ%¸ÀKäýã$äKä„ä‹D$SV‹t$;ÆW~‹È‹Æ‹ñ‹|$PjWjèlþÿÿVjWj‹Øèþÿÿ‹ðVSè6ÓÿÿƒÄ(‹Æ_^[ÃSVWjjjèBïÿÿhЋøè–Îÿÿ‹ðjjjÇFE‰v`ÇF‰~èïÿÿhЋØèiÎÿÿ‹øWÇGE‰`ÇG‰_èÓÿÿVWè¶ÒÿÿƒÄ,‹Æ_^[ÃV‹t$…öWt hÄÏèœÍÿÿƒÄ‹D$ƒø(‡?ÿ$…è‹|$ SVjWèÇÿÿÿVjW‹Øè¼ÿÿÿ‹ðVSèÓÒÿÿƒÄ ‹Æ[_^ÃhèÀæÿÿ‹ø‹D$Pjj jèníÿÿ‹ðVWè%ÒÿÿƒÄ‹Æ_^áDòƒøht7ƒøkthþè„æÿÿ‹L$‹øQjjjë‹T$ €ÎRjjjè"íÿÿƒÄ_^ÃhþþèRæÿÿ‹ø‹D$Pjjjëjjhƒèÿÿÿ‹L$‹øQjjjèãìÿÿ‹ðVWèšÑÿÿƒÄ$‹Æ_^Ãh˜Ïè˜ÌÿÿƒÄhlÏè‹ÌÿÿƒÄhDÏè~ÌÿÿƒÄhÏèqÌÿÿƒÄhðÎèdÌÿÿƒÄhÄÎèWÌÿÿƒÄh˜ÎèJÌÿÿƒÄhlÎè=ÌÿÿƒÄ‹T$ Rè åÿÿƒÄ_^ÃhTÎè ÌÿÿƒÄh<ÎèÌÿÿƒÄh$ÎèÌÿÿƒÄh ÎèùËÿÿƒÄhôÍèìËÿÿƒÄhÜÍèßËÿÿƒÄhÄÍèÒËÿÿƒÄh¬ÍèÅËÿÿƒÄh݆è(åÿÿ‹ø‹D$Pjjécþÿÿh”ÍèžËÿÿƒÄh€Íè‘ËÿÿƒÄh€Íè„ËÿÿƒÄhhÍèwËÿÿƒÄhPÍèjËÿÿƒÄh4Íè]ËÿÿƒÄhÍèPËÿÿƒÄÿ%¸ÀIÛå&çæ¾æËæPçCç6ç]çjçwçØæåæÿæòæ ççžç¸çÅçÒç„ç‘çè3æèæèßçìçùçèèèèèèèèèèì`S‹œ$lU‹¬$rVW‹¼$yãÿçÿåÿûÿ‰|$‰l$$¦„“ƒû‡—‹´$tÿ$´ñ‹œ$tSèÀ‹ðƒÄ…öuSh\ÒèÊÿÿƒÄƒÈÿ…öt÷Æÿu ÁæÁà…öuîjUWPVèƒÄ_^][Ä`Ãÿ…ò¡DòH=¿‡Ï3ÉŠˆðñÿ$Ôñ‹¼$tWèRÄ‹ðƒÄ…öuWhDÒèžÉÿÿƒÄUVèäV‹øÿØÀƒÄ ‹Ç_^][Ä`˼$tWèÄ‹ðƒÄ…öuWh,ÒèZÉÿÿƒÄUVè` V‹øÿØÀƒÄ ‹Ç_^][Ä`˼$tWèÊËðƒÄ…öuWh ÒèÉÿÿƒÄUVèÌ V‹øÿØÀƒÄ ‹Ç_^][Ä`˼$tWè†Ã‹ðƒÄ…öuWhðÑèÒÈÿÿƒÄUVè8 V‹øÿØÀƒÄ ‹Ç_^][Ä`˼$tWèBËðƒÄ…öuWhÐÑèŽÈÿÿƒÄUVèäV‹øÿØÀƒÄ ‹Ç_^][Ä`á”ò…Àtchÿjjjè‚èÿÿ‹øWè Îÿÿ‹œ$ˆSèÝ‹ðƒÄ…öuShDÒè)ÈÿÿƒÄUVèo‹ØSWèÍÿÿVÿØÀƒÄ‹Ã_^][Ä`ÃhtÑèõÇÿÿƒÄé"ƒÿ u+‹”$tRè[ÃSUW%ÿÿjPèÛƒÄ_^][Ä`˼$tƒÈÿ‰D$LW‰D$T‰D$X‰D$\èM»‹ðƒÄ…ö‰t$0uWh`Ñè…ÇÿÿƒÄ¡<ò‹|$ƒøÿÇD$‰|$‹ïu…ÿu ½ÇD$…öt{‹Fƒèt*ƒèucƒ|$t\‹L$$‹F‹T$SQL$TRƒÀQPèqë!ƒýt9‹F‹T$$SR‹@UjÿPÿ ÁPè‹ø‹D$(ƒÄ…Àt ‹ÈWQèXÌÿÿƒÄ‰|$‹v…öu‰‹|$¡¬ï…À…«¡¨ïÇD$4£…ÀÇD$8(ÇD$<£ÇD$@ð5ÇD$D£ÇD$HÀ'…`”$hhRÿ,À…À„;¼$hƒÉÿ3ÀT$\ò®÷Ñ+ù‹Á‹÷‹úT$\Áéó¥‹È3Àƒáó¤¿Ü¢ƒÉÿò®÷Ñ+ù‹÷‹Ù‹úƒÉÿò®‹ËOÁéó¥‹Ë‹0ÀƒáD$\ó¤PÿÓ‹-4À‹ð…öth£VÿÕ…ÀuVÿ8À¼$hƒÉÿ3ÀT$\ò®÷Ñ+ù‹Á‹÷‹úT$\Áéó¥‹È3Àƒáó¤¿Ô¢ƒÉÿò®÷Ñ+ù‹÷‹ú‹ÑƒÉÿò®‹ÊOÁéó¥‹ÊD$\ƒáPó¤ÿÓ‹ð…ötVh£VÿÕ…Àu Vÿ8ÀëA‹ Â3Û…É~|$8‹OüQVÿÕ…À‰tÚ‹ ÂCƒÇ;Ù|å3À…É~‹TÄ8‰Åì¢@;Á|ðǨï¡ü¢‹|$£¬ï‹L$0QÿЋt$…öu$…ÿ¸°ït¸@Ñ‹”$tPRh,ÑèîÄÿÿƒÄ ‹Æ_^][Ä`Ã…ÿtƒÿtƒÿtƒÿt hÑèÁÄÿÿƒÄ‹´$tD$L$(PQV臺ƒÄ …ÀuVhüÐè•ÄÿÿƒÄƒÿu@‹D$ƒøuVhèÐèyÄÿÿƒÄéž=„uVhÔÐè_ÄÿÿƒÄé„ÇD$ëzƒÿu:‹D$ƒøuVhÀÐè4ÄÿÿƒÄë\=„uVhÔÐèÄÿÿƒÄëEÇD$ë;ƒÿu6‹D$ƒøuVhÀÐèõÃÿÿƒÄëƒøuVhèÐèàÃÿÿƒÄëÇD$„‹T$‹D$(URPè3‹L$‹T$4ƒÄ ‹ðVUQRèmƒÄ PèÉÿÿƒÄ‹Æ_^][Ä`Ã…ÿtƒÿtƒÿtƒÿt hœÐèwÃÿÿƒÄ‹´$tD$L$ PT$0QRVè蹃Ä…ÀuVh€ÐèFÃÿÿƒÄƒÿu@‹D$ƒøuVhdÐè*ÃÿÿƒÄéž=„uVhHÐèÃÿÿƒÄé„ÇD$ëzƒÿu:‹D$ƒøuVh,ÐèåÂÿÿƒÄë\=„uVhHÐèÎÂÿÿƒÄëEÇD$ë;ƒÿu6‹D$ƒøuVh,Ðè¦ÂÿÿƒÄëƒøuVhdÐè‘ÂÿÿƒÄëÇD$„‹D$‹L$ ‹T$,UPQRè‹L$0‹T$<ƒÄ‹ð‹D$VUPQRèăÄPè»ÇÿÿƒÄ‹Æ_^][Ä`ÃhüÏè1ÂÿÿƒÄWVè÷ƒÄ‰D$…À|UWPèdôÿÿƒÄ _^][Ä`ÃVhäÏèûÁÿÿƒÄWVèÁƒÄ‰D$…À|UWPè^ƒÄ _^][Ä`ÃVhäÏèÅÁÿÿƒÄhôÈè¸ÁÿÿƒÄÿ%¸ÀIxéxé"é‚î%ñ2ñhñÌï¡é)êåémê±êõêaë‹D$VƒøW‡ÿ$…Tó‹D$ ‹ HòPƒÁjQjè’êÿÿƒÄ_^ËT$ ¡HòRjPjèxêÿÿƒÄ_^Ët$ jVè¦ÿÿÿjV‹øèœÿÿÿ‹ðVWè3ÅÿÿƒÄ‹Æ_^Ët$ jVèÿÿÿjV‹øèuÿÿÿ‹ðVWèŒÅÿÿƒÄ‹Æ_^Ãÿ%¸À‹ÿ%óÆòäò%óþò‹D$VƒøW‡ÿ$…ô‹D$ PjjjèÚéÿÿƒÄ_^ËL$ QjjjèÄéÿÿƒÄ_^Ët$ jVè²ÿÿÿjV‹øè¨ÿÿÿ‹ðVWèÄÿÿƒÄ‹Æ_^Ët$ jVè‹ÿÿÿjV‹øèÿÿÿ‹ðVWèØÄÿÿƒÄ‹Æ_^Ãÿ%¸À‹ÿÙó†óœóÙó²ó‹D$VƒøW‡ÿ$…¸ô‹D$ Pjjjè*éÿÿƒÄ_^ËL$ QjjjèéÿÿƒÄ_^Ët$ jVè²ÿÿÿjV‹øè¨ÿÿÿ‹ðVWèÏÃÿÿƒÄ‹Æ_^Ët$ jVè‹ÿÿÿjV‹øèÿÿÿ‹ðVWè(ÄÿÿƒÄ‹Æ_^Ãÿ%¸À‹ÿ‰ô6ôLô‰ôbô‹D$SUVƒøW‡²ÿ$…œùjjjèßÿÿhЋðèá¾ÿÿ‹l$$‹øUj»Ejj‰_‰`ÇG‰wèJèÿÿ‹ðVWè!ÃÿÿjjjèFßÿÿhЉD$L蘾ÿÿ‹ø‹D$LW‰_‰`ÇG‰Gè¼ÃÿÿUjjjèèÿÿƒÄL‰D$PWèÒÂÿÿ‹L$VQèGÃÿÿjjjèìÞÿÿhЋøè@¾ÿÿVP‰X‰@`Ç@‰xè™Âÿÿjjjè¾ÞÿÿhЉD$Lè¾ÿÿ‹T$L‹øW‰_‰`ÇG‰Wè4ÃÿÿUjj jèxçÿÿƒÄL‰D$PWèJÂÿÿ‹D$VPè¿ÂÿÿjjjèdÞÿÿhЋøè¸½ÿÿVP‰X‰@`Ç@‰xèÂÿÿjjjè6ÞÿÿhЉD$L舽ÿÿ‹L$L‹øW‰_‰`ÇG‰Oè¬ÂÿÿUjj jèðæÿÿƒÄL‹èUWèÄÁÿÿVUè=ÂÿÿjjjèâÝÿÿhЋèè6½ÿÿ‹øW‰_‰`ÇG‰oè^ÂÿÿVWè‡ÁÿÿƒÄ,‹Æ_^][Ãjjjè¢ÝÿÿhЋøèö¼ÿÿ‹l$$‹ðUj»Ejj‰^‰v`ÇF‰~è_æÿÿ‹øWVè6Áÿÿjjjè[ÝÿÿhЉD$Lè­¼ÿÿ‹T$L‹ðV‰^‰v`ÇF‰VèÑÁÿÿUjjjèæÿÿƒÄL‰D$PVèçÀÿÿ‹D$WPè\ÁÿÿjjjèÝÿÿhЋðèU¼ÿÿWP‰X‰@`Ç@‰pè®ÀÿÿjjjèÓÜÿÿhЉD$Lè%¼ÿÿ‹L$L‹ðV‰^‰v`ÇF‰NèIÁÿÿUjjjèåÿÿƒÄL‹èUVèaÀÿÿWUèÚÀÿÿjjjèÜÿÿhЋèèÓ»ÿÿ‹ðV‰^‰v`ÇF‰nèûÀÿÿWVè$ÀÿÿƒÄ,‹Ç_^][ËT$Rjjjè*åÿÿƒÄ_^][Ãj jjjjècÛÿÿ‹øWè»ÀÿÿhðhÀjjjèFÛÿÿ‹ØSèžÀÿÿhðhÐjjjè)ÛÿÿƒÄD‹ðVè~ÀÿÿVSè§¿ÿÿVWè Àÿÿ‹D$(Pjj jè°äÿÿ‹øWV臿ÿÿƒÄ,‹Ç_^][Ãj jjjjèÞÚÿÿ‹ðVè6Àÿÿ‹L$,Qjjjèväÿÿ‹øWVèM¿ÿÿƒÄ0‹Ç_^][Ãjjjjjè¤Úÿÿ‹T$(‹øRjjjèBäÿÿ‹ðVWè¿ÿÿƒÄ,‹Æ_^][Ët$jVèƒûÿÿjV‹øèyûÿÿ‹ðVWèð¾ÿÿƒÄ‹Æ_^][Ët$jVèZûÿÿjV‹øèPûÿÿ‹ðVWèG¿ÿÿƒÄ‹Æ_^][Ãÿ%¸ÀIjùèôÓöjùAù6øNøÓø ù‹D$VƒøW‡ÿ$…Xú‹D$ Pjj jèŠãÿÿƒÄ_^ËL$ QjjjètãÿÿƒÄ_^Ët$ jVè²ÿÿÿjV‹øè¨ÿÿÿ‹ðVWè/¾ÿÿƒÄ‹Æ_^Ët$ jVè‹ÿÿÿjV‹øèÿÿÿ‹ðVW舾ÿÿƒÄ‹Æ_^Ãÿ%¸À‹ÿ)úÖùìù)úú‹D$Vƒø¾ìÕt¾äÕ‹L$ƒù(‡ÿ$´üS‹\$U‹l$W‹|$PSjUWè¾ÿÿÿ‹ð¡¸ÈƒÄ…Àu7‹D$$PSjUWè¡ÿÿÿ‹øWVèø½ÿÿ‹L$@‹T$0QSjURè…ÿÿÿ‹ðVWèܽÿÿƒÄ8_]‹Æ[^Ãjj h‹D$ ‹L$‹T$PQRèEƒÄ^Ãjjh5€ëÜjjhëÑVhÄÕè¸ÿÿƒÄVh¤Õè¸ÿÿƒÄVh„Õè¸ÿÿƒÄVhdÕèõ·ÿÿƒÄVhDÕèç·ÿÿƒÄVh$ÕèÙ·ÿÿƒÄVhÕèË·ÿÿƒÄVhäÔè½·ÿÿƒÄh¼Ôè°·ÿÿƒÄh˜Ô裷ÿÿƒÄ‹D$‹L$PQ衃Ä^ÃhtÔè‚·ÿÿƒÄhPÔèu·ÿÿƒÄh(Ôèh·ÿÿƒÄhÔè[·ÿÿƒÄhÜÓèN·ÿÿƒÄVh¼Óè@·ÿÿƒÄVh Óè2·ÿÿƒÄVh€Óè$·ÿÿƒÄh\Óè·ÿÿƒÄVh<Óè ·ÿÿƒÄVhÓèû¶ÿÿƒÄVhüÒèí¶ÿÿƒÄVhÜÒèß¶ÿÿƒÄh¸ÒèÒ¶ÿÿƒÄVh”ÒèĶÿÿƒÄVhtÒè¶¶ÿÿƒÄÿ%¸À˜ú­üþú+û ûDû6ûRû`ûnû|û¦ûÀûáûÔûûûîûüü#ü1üŠû˜û³û?üLüZühüvü„ü‘ü­ü­ü­ü­ü­ü­ü­ü­ü­üŸü‹D$ SUVƒøW‡Úÿ$…Tþ‹t$$ë‹t$(‹D$ PèDÏÿÿ‹L$‹T$QRjVj‹øèÖÿÿ‹ðVW襺ÿÿƒÄ ‹Æ_^][Ët$(‹|$$‹\$ ‹l$‹D$VWSjUPè‹ÿÿÿ‹L$,VWSjUQ‰D$Xèwÿÿÿ‹T$X‹ðVRèZºÿÿƒÄ8‹Æ_^][Ët$(‹|$$‹\$ ‹l$‹D$VWSjUPè@ÿÿÿ‹L$,VWSjUQ‰D$Xè,ÿÿÿ‹T$X‹ðVRèºÿÿƒÄ8‹Æ_^][Ãÿ%¸ÀIþxý~ýþµý‹D$ƒìƒøUVW‡ì3ÉŠˆÿ$xÇD$ ½ë ÇD$ ½Sh`èÎÿÿ‹5DÁƒÄ‰D$hÿÿÖ%ÿÿPhÿÖ%ÿÿPjjjèÕÔÿÿ‹\$0ƒÄ‰D$ SÿÖ%ÿÿUPjRjè„Ôÿÿ‹ø‹D$0WPè7¹ÿÿjjjjjè˜ÔÿÿƒÄ,‰D$ SÿÖ%ÿÿƒÅPjUjèKÔÿÿ‹L$0‹èUQèþ¸ÿÿWUèw¹ÿÿƒÄ hÿÿÖ%ÿÿPhÿÖ%ÿÿPjjjè?ÔÿÿƒÄ‰D$ SÿÖ‹T$%ÿÿPjƒÂRjèîÓÿÿ‹è‹D$0UP衸ÿÿWUè¹ÿÿjjjjjèûÓÿÿƒÄ4‹èSÿÖ‹L$%ÿÿPƒÁjQjè¬Óÿÿ‹ðVUèc¸ÿÿWVèܸÿÿ‹T$4WRèQ¸ÿÿƒÄ(‹Ç[_^]ƒÄËt$jVèXþÿÿjV‹øèNþÿÿ‹ðVWè%¸ÿÿƒÄ‹Æ_^]ƒÄËt$jVè-þÿÿjV‹øè#þÿÿ‹ðVWèz¸ÿÿƒÄ‹Æ_^]ƒÄÃh\Óèô²ÿÿƒÄÿ%¸ÀI7¡þ’þ bo‹L$‹D$ Vƒù¾ìÕt¾äÕƒø(‡¾ÿ$…˜¸ëÚVh\Öèv²ÿÿƒÄVh8Öèh²ÿÿƒÄVhÖèZ²ÿÿƒÄVh¤ÕèL²ÿÿƒÄVhÄÕè>²ÿÿƒÄVh„Õè0²ÿÿƒÄVhdÕè"²ÿÿƒÄVhDÕè²ÿÿƒÄVh$Õè²ÿÿƒÄVhÕèø±ÿÿƒÄVhäÔèê±ÿÿƒÄh¼ÔèݱÿÿƒÄh˜ÔèбÿÿƒÄVhðÕè±ÿÿƒÄhtÔèµ±ÿÿƒÄhPÔ許ÿÿƒÄh(Ôè›±ÿÿƒÄhÔ莱ÿÿƒÄ‹D$‹L$ ‹T$jjh݆PQRèNƒÄ^ÃVh¼Óè^±ÿÿƒÄVh ÓèP±ÿÿƒÄVh€ÓèB±ÿÿƒÄh\Óè5±ÿÿƒÄVh<Óè'±ÿÿƒÄVhÓè±ÿÿƒÄVhüÒè ±ÿÿƒÄVhÜÒèý°ÿÿƒÄh¸Òèð°ÿÿƒÄVh”Òèâ°ÿÿƒÄVhtÒèÔ°ÿÿƒÄÿ%¸ÀIØßûí %3AOy“®¡È»Õ÷]k†!.<JXfs‹D$ SUVƒøW‡dÿ$…¼‹\$$ë‹\$(‹l$‹5 Á‹E PÿÖ‹L$P‹Q RÿÖPC jPjè5Ðÿÿ‹MƒÄ‹øQÿÖ‹T$P‹BPÿÖPKjQjèÐÿÿWPèš´ÿÿ‹UƒÄRÿÖP‹D$‹HQÿÖPSjRjèèÏÿÿWPèq´ÿÿ‹EƒÄPÿÖ‹L$P‹RÿÖPjSjèÃÏÿÿWPèL´ÿÿ‹D$„$ƒý‡Pÿ$­Àƒþ u‹T$UWVjRèhæÿÿƒÄ_^][ÃþuKhô×èAŸÿÿƒÄhÑè4ŸÿÿƒÄ‹D$WVPè•ðÿÿ‹L$$ƒÄ ‹ØSWVQèÓñÿÿƒÄ Pèz¤ÿÿƒÄ‹Ã_^][ÃÊÿ…Ûu4€ùu/‹D$…Àt©ÿu ÁàÁâ…Àuï‰D$UWVRPèÝåÿÿƒÄ_^][ù ƒÊÿ+È‹D$ÓâÓàUWVRP‰D$,èµåÿÿƒÄ_^][Ãþu ¾é]ÿÿÿƒþuéSÿÿÿƒþu ¾„éDÿÿÿ…ö…/ÿÿÿƒÎÿé4ÿÿÿhØ×è[žÿÿƒÄ‹T$WVRèœÐÿÿƒÄ _^][Ã턆Mtíøu hôÈè&žÿÿƒÄÿ%¸Àƒþu¾ë)ƒþuë"ƒþu¾„ë…öuƒÎÿë hœÐèëÿÿƒÄ‹D$WVPPèëñÿÿƒÄ‹Ø‹D$SWVPPè8óÿÿƒÄPè/£ÿÿƒÄ‹Ã_^][ËD$WVPè)öÿÿƒÄ _^][ÃôôôÃû‹D$ìD…ÀtPhŒØègÿÿƒÄSUVW‹¼$XWè‘‹ðƒÄ…ö‰t$$uWhtØè;ÿÿƒÄ‹F…ÀtWhTØè&ÿÿƒÄ‹v‹¬$`ƒÆý€vh€h8ØèÿœÿÿƒÄ3À|$‰D$‰D$‰D$‰D$‹Å™ƒâЃÈÿÁú‹Ê‹ÙÁéó«‹Ëƒáóª‹Å%€yHƒÈø@t¹+È ÿÒàˆD‹L$‹÷Ñ…Èu'‹T$‹F÷Ò…Âu‹D$‹N÷Ð…Èu ‹L$‹F ÷Ñ…Át‹”$XURht×ècœÿÿƒÄ ‹œ$d€ûv€ût/hØèEœÿÿƒÄ3À_^][ÄDÃý€t hT×è#œÿÿƒÄ‹„$f‹Œ$eãÿ%ÿSáÿPT$QRVèCéÿÿ‰D$4¡¬ïƒÄ…À…§¡¨ïÇD$(£…ÀÇD$,(ÇD$0£ÇD$4ð5ÇD$8£ÇD$<À'…`„$LhPÿ,À…À„;¼$LƒÉÿ3ÀT$@ò®÷Ñ+ù‹Á‹÷‹úT$@Áéó¥‹È3Àƒáó¤¿Ü¢ƒÉÿò®÷Ñ+ù‹÷‹Ù‹úƒÉÿò®‹ËOÁéó¥‹Ë‹0ÀƒáD$@ó¤PÿÓ‹-4À‹ð…öth£VÿÕ…ÀuVÿ8À¼$LƒÉÿ3ÀT$@ò®÷Ñ+ù‹Á‹÷‹úT$@Áéó¥‹È3Àƒáó¤¿Ô¢ƒÉÿò®÷Ñ+ù‹÷‹ú‹ÑƒÉÿò®‹ÊOÁéó¥‹ÊD$@ƒáPó¤ÿÓ‹ð…ötVh£VÿÕ…Àu Vÿ8ÀëA‹ Â3Û…É~|$,‹OüQVÿÕ…À‰tÚ‹ ÂCƒÇ;Ù|å3À…É~‹TÄ,‰Åì¢@;Á|ðǨï¡ü¢£¬ï‹L$$QÿЋD$ _^][ÄDËD$<t„À…ú€ü…ñ¡DòH=¿‡Ó3ÉŠˆxÿ$\‹T$ ‹D$âÿRPè"ÙÿÿƒÄËL$ ‹T$áÿQRèÉÙÿÿƒÄËD$ ‹L$%ÿPQèaÚÿÿƒÄËT$ ‹D$âÿRPèøÚÿÿƒÄá”ò…ÀteVWhÿjjj虹ÿÿ‹ðVè!Ÿÿÿ‹L$&‹T$ áÿQRèœØÿÿ‹øWVè3žÿÿƒÄ$‹Ç_^ËD$ ‹L$%ÿPQè‡ßÿÿƒÄÃhÔØè™ÿÿƒÄh¤Øè ™ÿÿƒÄ3ÀËÿy«’Ã%Ü=‹L$‹A…Àt‹È‹A…Àu÷‹D$‰AËT$‰QÃQSUVWè‹t$‰D$‹FPèE‹D$$ƒÄHtHtƒètvh°Ùè¹—ÿÿƒÄ¿‹l$Eÿƒø'‡û3ÉŠˆXÿ$@è-¿ÿÿ‹ØV…ÛtDèÁPSèZÿÿÿjèó—ÿÿPSÇ èFÿÿÿjèß—ÿÿPSÇè2ÿÿÿƒÄ$ë3ÿ똿ë‘è]ƒÄ‹Øjè±—ÿÿƒÏ@P‰8‹ÌñS‰P èüþÿÿ‹FSPèòþÿÿƒÄé¼èÀÿÿ‹ØV…Ût9è9PSèÒþÿÿjèk—ÿÿPSÇ è¾þÿÿjèW—ÿÿPSÇèªþÿÿƒÄ$ë èàƒÄ‹Øjè4—ÿÿƒÏ@P‰8‹ èñ‹ÐñSщP èwþÿÿ‹FSPèmþÿÿUèתÿÿ‹ø‹ƒÄ…Àt WPèe›ÿÿƒÄ‰>éèf¹ÿÿV‹ØèžPSè7þÿÿjèЖÿÿPSÇ è#þÿÿjè¼–ÿÿPSÇèþÿÿj訖ÿÿ‹èƒÏ@US‰}èùýÿÿ‹ èñ‹ÐñÑS‰U ‹FPèÞýÿÿƒÄ8è&Ãÿÿ‹L$‹øWQè9ªÿÿƒÄPèКÿÿ‹ƒÄ…Àt WPèÀšÿÿƒÄWjèªÿÿƒÄP謚ÿÿƒÄ‰>ëghxÙè«•ÿÿƒÄëXh\Ù蜕ÿÿƒÄ¡Dò=£tƒøtƒøwt h0Ùèy•ÿÿƒÄVèj‹Øèç•ÿÿƒÏ@PS‰8è;ýÿÿ‹VSRè1ýÿÿƒÄ‹|$j‰~èÀ•ÿÿljx P‹FPè ýÿÿƒÄ ‹Æ_^][YËÿÎVõ«ÇºjèY•ÿÿ‹L$ÇaƒÄ‹Q‰P Ãjè9•ÿÿ‹L$Ç`ƒÄ‹Q‰P ÃSUVW‹|$Wè²ÿÿÿ‹t$‹ØVèÆÿÿÿ‹l$ƒÄƒý‰D$u;jèï”ÿÿhЉD$ ÇèÛ”ÿÿ‹L$$Ç@‰@`‹è‹D$ PQè üÿÿƒÄëhÐè±”ÿÿƒÄƒÍ ‰h‰@`‹è‹D$ …Àt UèÕ™ÿÿƒÄ‹T$RSèçûÿÿ‹GSPèÝûÿÿ‹O‹VQRèÐûÿÿ‹F‰E‹NQèQ‹WRèH‹6‹?ƒÄ …öt…ÿt WV貘ÿÿƒÄë‹þ…ÿt UWè ˜ÿÿƒÄ_‹Å^][ÃSVWè¸j ‹Øè”ÿÿj‹ðè”ÿÿ‹øjÇ€è÷“ÿÿÇƒÄ ‰G‰X ‰~‰^‹Æ_^[ÃSVWj èÆ“ÿÿ‹øè_j‹Øè¶“ÿÿ‹ð‹D$jljF è “ÿÿÇƒÄ ‰F‰X ‰w‰_‹Ç_^[ÃV‹t$Vè5þÿÿP‹FPèËúÿÿjèd“ÿÿÇ„Ç@ ‹NPQè­úÿÿjèF“ÿÿÇ‹V‰P P‹FPèúÿÿƒÄ$‹Æ^ÃSUVW‹|$Wè²ýÿÿ‹t$‹ØVèÆýÿÿj‹èèý’ÿÿ‹L$ PƒÉ U‰èMúÿÿUSèFúÿÿ‹WSRè<úÿÿ‹G‹NPQè/úÿÿ‹VRè¶‹GPè­jè¶’ÿÿ‹øÇèI‰G ‹NWQ‰FèùùÿÿƒÄ@‹Æ_^][ÃW¹3À¿ìñó«Ç0ò_á0ò¹‹…ìñ…Òt%@%€yHƒÈð@IyåhÐÙ£0ò謑ÿÿƒÄ3Àã0òÇ…ìñËD$Ç…ìñËD$Pj0èƒÄÃVjèè‘ÿÿ‹ðhÐÇ€èÖ‘ÿÿ‹L$‹T$ƒÄƒÉ‰p‰H‰@`‰P^ËD$VPj è³ÿÿÿ‹ðVèÛ–ÿÿƒÄ ‹Æ^ËD$WƒÀÚƒøV‡ª3ÉŠˆ,#ÿ$#‹T$‹D$ RjPjè ±ÿÿƒÄ_ËL$‹T$ QjRjèõƒÄ_ËD$‹L$ PjQjè}¶ÿÿƒÄ_Ãjè!‘ÿÿƒÄÇDëjè‘ÿÿƒÄÇT‹T$‹øVhЉW èòÿÿ‹ðVÇF‰v`‰~è–ÿÿƒÄ‹Æ^_Ãÿ%¸ÀIÊ"ˆ"p" "¸" #‹D$‹L$ ‹T$P‹D$jj0jÿQRPèA°ÿÿƒÄËD$V…ÀWŒ0ƒø~Tƒø…"Shèé¨ÿÿ‹5<ñ‹ø÷ÖVjjjjèÁ¯ÿÿVVjjj‹Øè²¯ÿÿ‹ðVSè¹”ÿÿVWè2”ÿÿƒÄ<‹Æ[_^áDòH=¿‡¹3ÉŠˆ0%ÿ$%jh˜òè­ƒÄ_^Ãjh¼ÈèKÎÿÿƒÄ_^Ãjh¼ÈèùÎÿÿƒÄ_^Ãjh¼Èè—ÏÿÿƒÄ_^Ãjh¼Èè5ÐÿÿƒÄ_^Ãjh¼ÈèÕÿÿƒÄ_^á”ò…ÀtBhÿjjjèÄ®ÿÿ‹ðVèL”ÿÿjh¼ÈèÐÍÿÿ‹øWVèg“ÿÿƒÄ$‹Ç_^Ãh4ÚèeŽÿÿƒÄhÚèXŽÿÿƒÄ3À_^ÃY$}$G$k$$¡$³$ñ$‹D$VƒøW‡G3ÉŠˆh(ÿ$X(‹DòBÿ=¿‡$3ÉŠˆ˜(ÿ$|(jh˜òèÃÄ_^ÃjèƒÄ_^Ãjè ƒÄ_^ÃSUjjjè®ÿÿhЋøèjÿÿ‹ð½Ej‰n‰v`ÇF‰~èÌ‹øWV賑ÿÿjjjèØ­ÿÿhЋØè,ÿÿ‹ðV‰n‰v`ÇF‰^èT’ÿÿjè‹ØSVèt‘ÿÿWSèí‘ÿÿƒÄDjjjè­ÿÿhЋðèãŒÿÿWP‰h‰@`Ç@‰pè<‘ÿÿjjjèa­ÿÿhЋØèµŒÿÿ‹ðV‰n‰v`ÇF‰^èÝ‘ÿÿjè‹ØSVèýÿÿWSèv‘ÿÿƒÄ@jjjè­ÿÿhЋØèlŒÿÿ‹ðV‰n‰v`ÇF‰^蔑ÿÿWVè½ÿÿƒÄ‹Ç][_^Ãj較Ä_^á”ò…À„hÿjjjèÉ«ÿÿ‹ðVèQ‘ÿÿ‹HòRè…‹øWVèlÿÿƒÄ ‹Ç_^ÃhèÚ¤ÿÿhàjjj‹øèh»ÿÿ‹ðVWè?ÿÿƒÄ‹Æ_^Ãh݆譤ÿÿhÿjjj‹øè[«ÿÿ‹ðVWèÿÿƒÄ‹Æ_^ÃhLÚè‹ÿÿƒÄ3À_^Ã&ì'(F(‹ÿC&'1&P&]&ª'F(‹D$VjPjè«ÿÿhЋðèeŠÿÿƒÄ‰pÇ@E‰@`Ç@^Ë DòAø=À‡Â3ÒŠœ*ÿ$•ˆ*‹D$PjèAöÿÿƒÄPjjè4öÿÿƒÄPjè‰ñÿÿƒÄ PjèÎôÿÿƒÄËD$…Àtjjjjè…©ÿÿƒÄÃjjjjèt©ÿÿƒÄËD$…Àtjjjjè[©ÿÿƒÄÃjjjjèJ©ÿÿƒÄËD$j…Àtjjjjè_©ÿÿƒÄÃjjjjèN©ÿÿƒÄÃQh¼Úè߈ÿÿƒÄ3ÀÃÃ)ö)J* *v*hìÚèö‡ÿÿƒÄ3ÀÃhÛèæ‡ÿÿƒÄ3ÀáDòƒÀ—ƒø:w(3ÉŠˆÐ+ÿ$È+‹T$‹D$RPjjjè¨ÿÿƒÄÃhLÛ衇ÿÿ‹D$ ƒÄÜ+µ+¡DòƒÀ—ƒø:w3ÉŠˆX,ÿ$P,h€Ûè*‡ÿÿƒÄ‹T$jRjjjèu§ÿÿƒÄÃ9,,,¡Dòƒèt ƒèzthàÛë.‹D$<t„Àu€üu‹D$ ‹L$%ÿPQè%ƒÄÃh´Ûèw†ÿÿƒÄh´Ûèj†ÿÿƒÄ3ÀËD$VƒøW‡ÿ$…˜-‹D$ PjjjèJ°ÿÿƒÄ_^ËL$ Qjjjè4°ÿÿƒÄ_^Ët$ jVè²ÿÿÿjV‹øè¨ÿÿÿ‹ðVWèïŠÿÿƒÄ‹Æ_^Ët$ jVè‹ÿÿÿjV‹øèÿÿÿ‹ðVWèH‹ÿÿƒÄ‹Æ_^Ãÿ%¸À‹ÿi--,-i-B-¡¸È…Àv h(Üè…ÿÿƒÄ¡Ðñ‹ Dò£´È‹ÁHtQhÜèz…ÿÿ‹D$ ƒÄË <òVhjQj茥ÿÿ‹ð‹D$ƒÄ…À|!WhÿPjjjè¥ÿÿ‹øWVè$ŠÿÿƒÄ‹÷_‹èñ‹ <ò¸ÐȋƉèñ‰ <ò^Ë ¸È¡Ðñ…ÉV£´ÈvjjƒÀþjPjè:¥ÿÿƒÄë;‹ Dò‹ÁHt#ƒètƒè_tQhDÜ资ÿÿƒÄ3öëhëhGˆè žÿÿƒÄ‹ð‹D$…À|(WhðÿÿÁà P¡´ÈjPjèפÿÿ‹øWVè^‰ÿÿƒÄ‹÷_‹Ôñ‹ Ðñ¸ÐÈ¡¸È‰Ôñ@‰ Ðñ£¸È‹Æ^Ãhcˆè–ÿÿƒÄÃhdˆè†ÿÿ‹ <òƒÄ‰ °È‹ Ðñ‰ ´ÈƒÁ‰ <ò¹ÇŒò‰ Ðñ‰ ÔñËD$ƒÀ̓ø‡ÿ$…Ä0¡ò…Àu h°Ü覃ÿÿƒÄ¡8ñƒøÿ…Ñ鯡ò…Àu hÜè}ƒÿÿƒÄ¡4ñƒøÿuÿ%¸À‹T$‹L$R‹T$QRjÿjPjèߣÿÿƒÄáäñƒøÿuÿ%¸À‹L$‹T$Q‹L$RQjjPjè°£ÿÿƒÄáØñƒøÿuÿ%¸À‹T$‹L$R‹T$QRjÿƒÀjPjè~£ÿÿƒÄáò…Àu hlÜèׂÿÿƒÄ¡äñƒøÿuÿ%¸À‹L$‹T$Q‹L$RQjÿjPjè9£ÿÿƒÄÃÿ%¸ÀI§/Ð/0D0v0‹D$VƒÀêWƒø ‡Óÿ$…Ì2¡ò…Àu hÀÝèT‚ÿÿƒÄjjjj3ètþÿÿjj‹øjéå¡ò…Àu h Ýè$‚ÿÿƒÄjjjj3èDþÿÿjj‹øj鵡ò…Àu h|ÝèôÿÿƒÄjjjj3èþÿÿjj‹øjé…¡ò…Àu hXÝèÄÿÿƒÄjjjj3èäýÿÿjj‹øjëX¡ò…Àu h8Ýè—ÿÿƒÄjjjj3è·ýÿÿjj‹øjë+¡ò…Àu hÝèjÿÿƒÄjjjj3èŠýÿÿjj‹øjj4è{ýÿÿ‹ðVWè2†ÿÿƒÄ(‹Æ_^áò…Àu hðÜè'ÿÿƒÄjjjj5èGýÿÿ‹ Øñ‹ðƒÄÇ”òAÇÐñ£Hò_P ƒÀ£èñ‹Æ‰<òÇÔñ^áò…Àu hÐÜè½€ÿÿƒÄjjjj5èÝüÿÿƒÄ‹ðÇ”ò_^Ãÿ%¸Àù0)1Y1‰1¶1ã1Å2Å2&22‹D$Vƒè„¥Ht;Htÿ%¸À¡Dò=Œt=Åt=‹t h$Þè"€ÿÿƒÄjjj 锡Dò=Œt=Åt=‹t hÞèðÿÿƒÄ‹ Èñjjj j?jQjèe ÿÿ‹Èñjjj j?jRj‹ðèK ÿÿVP褄ÿÿƒÄ@‹Æ^áDò=Œt=Åt=‹t häÝè‰ÿÿƒÄjjj¡Èñj?jPjèÿŸÿÿƒÄ‹ð^ËD$VHƒø‡ÿ$…˜5ƒ=,ñÿu h8ßè7ÿÿƒÄ‹t$ þÿvVhßèÿÿƒÄ‹L$‹T$¡,ñVQRjÿjPj莟ÿÿƒÄ^Ã=(ñÿu hôÞèæ~ÿÿƒÄ‹t$ þÿ?vVhÌÞèÌ~ÿÿƒÄ‹Î‹ÖƒáâüÁá‹D$ÊÁî Ááƒæ‹(ñÎQ‹L$PQhÿÀjRjèŸÿÿƒÄ^Ã=8òÿu h°Þèt~ÿÿƒÄ‹t$ þÿ?vVhˆÞèZ~ÿÿƒÄ‹L$‹Æ‹T$%?ÁæÆÁàP¡8òQRh?ÿjPj蹞ÿÿƒÄ^Ã=0ñÿu hlÞè~ÿÿƒÄ‹t$ ƒþvVhDÞèú}ÿÿƒÄ‹L$‹T$¡0ñÁæVQRhðjPjèežÿÿƒÄ^Ãÿ%¸À‹ÿ4g4Ù4<5‹D$VƒÀäWƒø+‡z3ÉŠˆX7ÿ$D7¡ò…Àu hÈßè|}ÿÿƒÄjèÂÿÿÿƒÄ‹ð_^áò…Àu h¤ßèW}ÿÿƒÄjjjj4èwùÿÿjjjj4‹øèhùÿÿ‹ðVW蟂ÿÿjjjj3èRùÿÿVPè ‚ÿÿƒÄ@‹Æ_^áò…Àu h|ßè}ÿÿƒÄj)è&j*‹øè‹ðVWèT‚ÿÿj+è VPèF‚ÿÿj,èÿVPè8‚ÿÿj-èñVPè*‚ÿÿj.èãVPè‚ÿÿƒÄ@jè"úÿÿVPè‹ÿÿƒÄ ‹Æ_^áò…Àu hTßè€|ÿÿƒÄj)è¦j*‹øè‹ðVWèÔÿÿj+èVPèÆÿÿj-èVPè¸ÿÿj.èqVPèªÿÿjè³ùÿÿVPèÿÿƒÄ@‹Æ_^Ãÿ%¸À‹ÿÑ5ö5M6Í6<7‹D$ƒÀ׃øwmÿ$…8jjjj6èà÷ÿÿƒÄÃjjjj6èÏ÷ÿÿƒÄÃjjjj6è¾÷ÿÿƒÄÃjjjj6è­÷ÿÿƒÄÃjjjMj6èœ÷ÿÿƒÄÃjjjZj6è‹÷ÿÿƒÄÃÿ%¸À£7´7Å7Ö7ç7ø7VW‹|$ ‹7VèjVèšjVè’Vè¬WèƒÄè®_^ÃV‹t$W‹‹xÇ@‹‹Hƒá€ùu‹‹A<‹QT;Âu ‰‹Pƒâ€útç‹‹@…Àt PWèˆâÿÿƒÄ‹‰y‹6‹Vƒâ€úuÇF_^ÃV‹t$W‹|$VÇöè6VèÐVèªVètVèžWVè¡öƒÄ…ÀtÅ_^Ë öW‹=4_3Àó«‹üõ‹D$BP‰üõèƒÄ_áüõV‹t$9FtR‰F‹F<…ÀÇFdt'PèÚÿÿÿ‹FTPèÑÿÿÿ‹N<‹VTƒÄ‹A$‹J$;Á‹Á@ë3À‰F$‹ 4_‹‰Vd‹ 4_‰4^áöW¯ öHx‹=öHƒÈÿó«¡ö‹L$H…À|‹QhHÇD‚yò‹y$…ÿŒŽSUV¡4_‹¸…Àtu‹‹ph‹ÑƒáÁê‹––¾Óæ Þ‰‹H<…ÉtI‹5ö‹Ih‹PhN…ö|F‹‹)#ëƒÂ‰)ƒÁNuï‹5ö‹HT‹PhN‹Ih…ö|F‹‹)#ëƒÂ‰)ƒÁNuï‹@d…Àu‹O‰xÿÿÿ^][_Ë œò¯ öIx¡øõˆAÇÿÿÿÿƒèIuô‹T$‹ œòW3À‹z8ó«‹ œò‹zPó«‹z$…ÿ|.V‹ 4_‹4¹…ötV0Rè FHPè‹vdƒÄ…öuäOyÔ^_ËT$VW‹ ‹r‹ÁƒáÁè‹<††¾Óæ þ‰8‹B …ÀtK‹5œò‹@8‹JN…ö|SF‹9‹#߃Á‰ƒÀNuï[‹J ‹R‹AP‹ œòI…É|A‹2‹8#þƒÂ‰8ƒÀIuï_^Ë öW¯ ö‹= ò3ÀÁá‹ÑÁéó«‹Êƒáóª‹D$‹x$…ÿŒSUV‹ 4_‹¹…Àtu‹‹pl‹ÑƒáÁê‹––¾Óæ Þ‰‹H<…ÉtI‹5ö‹Il‹PlN…ö|F‹‹) ëƒÂ‰)ƒÁNuï‹5ö‹HT‹PlN‹Il…ö|F‹‹) ëƒÂ‰)ƒÁNuï‹@d…Àu‹O‰wÿÿÿ^][_ËD$SU3Û‹h$VW;ë‹ý|&‹ 4_‹4¹;ótVèj‰ž€‹vdƒÄ;óuêOyÚº;ê|E¡4_‹;Ãt4‹HT‹p<‹I|‹~|‹°€ Ï‹x| ñ‰°€‹Î‹px÷Ö#ñ þ‰x|‹@d;ÃuÌB;Õ~»_^][ÃQSU‹l$VW3Û‹u3ÿ;ó‰\$tqƒ>ÿteVèíƒÄ…À|8ƒøu÷ÇuË÷ÇuËë…º‹ÈÓâ…×u ÚVèHƒÄ…À|º‹ÈÓâ…Óu T$ ú‹v…öu‹MEƒá€ùuXPèsƒÄ…À|Kƒøu5÷ÇuË÷Çu0‹T$ˉ}t_‰Ux‰]|^][YÃÿ%¸À}"º‹ÈÓâ…×u Ú‹T$‰}t_‰Ux‰]|^][YÃÿ%¸À‹T$‹ƒøÿuƒÈÿËȃáƒùwXÿ$˜>ƒàƒøu¸Ãè÷ØÀ$îƒÀÃ%àƒø@u¸Ãø`u»‹B Ã$,öØÀ$þƒÀÃ%ø,€öØÀƒÀÃÿ%¸À[>[>H>e>t>t>@>‚>‹T$‹ ƒùÿt.‹Áƒàƒøw$ÿ$…?¸øËB ÀáøöÙɃÁ‹ÁÃÈÿÃIÜ>â>è>è>Ü>ù>ù>ì>SUVWèÇ‹D$P‹h$èZ‹\$ƒÄ…í‹ý| ¡4_‹4¸…ötSVèê‹vdƒÄ…öuïOyà…Ûuu¿;ï|.‹ 4_‹4¹…ötV0RèÊ FHPèÁ ‹vdƒÄ…öuäG;ý~Ò‹L$Qè迃Ä;ï|(‹4_‹4º…ötVè Vèc‹vdƒÄ…öuêG;ý~Ø_^][Ë ö¡@_Áá‹ÑW‹=L_£8_3ÀÇöÁéó«‹Êƒáóª¹Õ3À¿¤òó«_ÃS‹\$VW‹Cp»ˆ…Àu ¹3Àó«ë?‹p¹ƈó¥‹H…Ét(¸ˆ‹Q‹4;4tǃÀ=Ð|ä‹I…ÉuØ‹s‹ƒÌ‹|$U‹«È‰D$…ötƒˆWPV訋vƒÄ …öuè‹D$3É;ùt:9‹€u;ét9«Èu ;Át9ƒÌt ‹Cƒà<u9Kt‰K‰ öëSèSè> ƒÄŠC]¨u%‹KjQjè6‰ƒ„‹CƒÄ ‰C4÷Ø_‰CL^[ËC‹“̉C4_÷؉“„‰CL^[ÃSU‹l$‹\$ ‹ÅW‹|$3ÒÁà3ǹÕÁà3Ã÷ñ‹•¤ò…Àt9u 9xu9htt‹@…Àuë¡öV@öÃà£öu*‹Ëƒátƒùu‹5L_ ʼn|1‹5L_Ç1‹58_‹ÎƒÆ‰58_‰A ‰‰y‰i‹4•¤ò‰q^_]‰ •¤ò[Ë@ _][ÃSU‹l$ V3Û‹u;ó„°W‹Î;ó‹þt ƒ?ÿu‹;ûuô;û„#‹w;ó„ƒ>ÿu‹v;óuô;󄋉t$ƒøuƒ>au‹G ‹N ;Áu ‰öÇ9…̓>uÇLJ‰ö9…®÷…€…ž>±t‹Þë‹F;Ãt ƒ8ÿu‹@;Ãuô‹Ø…Ûtwƒ; ur‹K…Étkƒ9ÿu‹I…Éuô…Ét[ƒ9uV‹A…ÀtOƒ8ÿu‹@…Àuô‹L$3Ûéÿÿÿ…Àt4‹öÂu-âà€ú@u"‹W P ÇÿÿÿÿÇÿÿÿÿÇÿÿÿÿÇö3Û‹L$éÃþÿÿ‹E_ƒø…¦÷…€…–‹ƒøuE‹…Ì‹L_9Ât‹D‹UЉUÇÿÿÿÿ‰öëd9]u_ÇÿÿÿÿÇE‰öëJƒøuÇÿÿÿÿ‹I ‹EÁ‰E‰öë,ƒøTu'9]u"‹Q ÇEE‰UÇÿÿÿÿU‰öèƒÄ‹EƒøEu‹M;Ëu‹UT‰U<ƒùÿu‹M<‰MT‹Ì‹5L_9Ît‹Ðƒâ€úu ‹LÎ$÷‰E‰M‹…È‹L_9Âte‹MöÁu]‹DÂáðƒÁðƒù0wY3ÒŠ‘Eÿ$•E‹U3É;”Á‹Áë9EÀ÷Øë ;EÀ@ë#E‹UT‹M<;Ñt‰ö;Ãt ‹E<‰ET^][ËMT^‰M<][Ãÿ%¸À¸DÆDÏD×DE‹D$‹H<‹PT‰P<‰HTÃSUV‹t$W‹=±‡†3ÉŠˆPJÿ$J‹V jRPèÐûÿÿ‹L$$‹T$(ƒÄ é~‹|$‹\$…Û‹ODt?‹L_ƒ<Êt3ƒà‹n j‰‹L_‹LÊé‹Í‰n QPèûÿÿƒÄ Çöë‹V QRPègûÿÿƒÄ …Û„Î9G@…ÅÇÿÿÿÿ_^][Ãjjh€éeÿÿÿ‹F jPjéXÿÿÿ‹N jQjè ûÿÿ‹L$$‹T$(ƒÄ éL‹V jRh±ëÞ‹D$‹|$…Àt;‹G@‹ L_ƒ<Át,Ç‹W@¡L_j‹DÐ÷ØPj‰F èÇúÿÿƒÄ ‰G@_^][ËO@jQh„è¬úÿÿƒÄ ‰G@_^][ËL$‹|$%ð…É„‘‹N …ÉuO…À„ƒø`„¹ƒøp„°ƒø@„§ƒø tƒøPu"‹V jRjÇèEúÿÿ‹L$$ƒÄ _^]‰A@[ËW@¡L_ƒ<Ðt-jQjèúÿÿ‹O@PQV賋V jRjèúÿÿƒÄ$‰G@_^][ËF jPjèîùÿÿ‹O@‹PQRèáùÿÿƒÄ‰G@_^][ËT$‹|$‹Èáð…Ò„ý‹_D‹L_ƒ<Útm‹G@ƒ<Ât SPVè>‹F jPjè‘ùÿÿƒÄ‰G@_^][ÃÉj‰‹OD‹L_‹DʉF Çö‹N QjèZùÿÿ‹W@P‹RPèMùÿÿƒÄ‰G@_^][Ë_@Úƒ:tv‹Z…Ûuo…ÉtNƒù@tIƒù t'ƒù0t"ƒùPtƒù`tƒùptù€uEÇÿÿÿÿ_^][ÃjjjÇÇF èãøÿÿƒÄ ë LJ‹GD9G@…>ÿÿÿÇÿÿÿÿ_^][ËOD‹W@QRPè³øÿÿƒÄ ‰G@_^][ËD$‹T$…Ò‹HDt9H@u Çÿÿÿÿ_^][Ã_^]‰H@[ËF ‹L$‹T$‹…Ò„-þÿÿ‹=L_ƒ<ÇtÇ‹=L_‹|lj~ Çö…Ò„üýÿÿ9A@…óýÿÿÇÿÿÿÿ_^][ËD$‹T$…Ò‹H@t9HDu Çÿÿÿÿ_^][Ã_^]‰HD[ËV ‹L$‹‘‹T$…Òt=‹=L_ƒ<ÇtÇ‹=L_‹|lj~ Çö…Òt9ADu Çÿÿÿÿ_^][Ã_^]‰AD[ËD$‹V ‹H@‹T$…Òt,9u(Çÿÿÿÿ_^][ËD$‹V ‹HD‹T$…Òt9„6ÿÿÿ‰_^][Ã6FCFÈIìIÏFJIšG”E°EïHqI(FmFÈH`F J    ¡L_‹L$‹T$ S‹\$V‹tÈW‹|Ћ%ð=€wf3ÉŠˆÐKÿ$¨K÷ë<+÷ë8¯þ‹÷ë1…ÿu hèßèúgÿÿƒÄ‹Æ3Ò÷÷‹ðë#÷ë ÷ë‹ÏÓæë‹ÏÓîë÷Þ‰s _Ç^Çö[Ãÿ%¸À‹ÿIKMKQKXKwKsK{KK‡K K        ƒìH¹3ÀUVW|$ ó«‹|$X‹w…ötD$ PVèg‹vƒÄ…öuëL$ WQRèOƒÄ3ÉT$ ‹…Àt!‹¯€¾Óæ…îuÇÿÿÿÿÇöAƒÂƒù|Ð_^]ƒÄHÃVW‹|$ Wè$ñÿÿ‹t$ƒÄ…À|ƒøuÇFDÇF@ëdžWè—ñÿÿƒÄ…À|ƒ<†tÇö‹ †Çÿÿÿÿ‰<†_^ÃS‹\$UV‹K W‹A<…À„¢;ATuP‹CP蛃Ä…Àu£ö‹K ‹Q<‰S 3í¡œò‰l$;è}o‹C‹4¨…ötNÁåVèTaHº‹ÈÅÓâ‹ <_÷Ò#ò‹‹C RPè‘‹øƒÄ …ÿt‹KWQè.ƒÄ…Àt …öu¹‹l$Eë˜Çö‰{ ‹G<…Àu‚_^][ËT$SVW‹º€…ÿt+‹t$3É‚ˆ+òºÓâ…×t ‹‹;ÓuAƒÀƒù|ã_^3À[Ã_^¸[ËT$SVW‹B…À}÷Ø3ö뾋L$9Au<‹R‹¹È;ºÈu+‹¹„‹š„;ûu …öt‹A<_^[Ã…öt ƒøu‹AT_^[Ã_^3À[ÃìSUVW‹|$‹Op…É„@‹A‹È‹A…À‰T$t‹p;–È…‹@…Àuê‹I‹Q‹ tV…Ét4‹ xV…Ét*…Àt&¿Wh(Vÿ À‹Ç_^Ã_¸^Ã_¸^á,V…ÀtPÿ8ÀÇ,VWh(Vÿ À‹Ç_^ÃìÇD$èÐüÿÿƒøuxD$L$PQÿ0VƒÄ…Àua‹D$V3ö…ÀvOW‹|$‹T$‹²PèWƒÄ…Àt‹…Òu‰ë‹ …Ét‹Ñ‹ …Éuø‰‹D$ F;ðrÉ…À_v‹L$Qÿ4VƒÄ3À^ƒÄÃ3ÀƒÄÃSUVWjÿÜÀ‹ØƒÄ…Ûu_^][ËË3À‹|$‰W‰A‰A‰A ‰AÿÿÿƒÄéè ƒù„• ‹T$(…ÒtJ‰T$(…Àt Ç_þÿÿÿ¡ _ƒÆ‹Ö‹\$‹ù‹l$,‰‹ $_ƒÃ‰|$$‰J¡(_‰\$‰B‹ ,_‹D$0‰J éŸýÿÿ‹T$83ÉŠèË…ɉL$4…#ÿÿÿ‹L$(…Éu!‹0_h0êB‰0_è¡_ƒÄë.ƒùu)…À„ù ëh _Rhêè¦ÿÿ¸þÿÿÿƒÄ £_‹\$ÇD$(¿ }XÍù:ÿÿÿt"Axùfƒ‹N‰L$‹né ‹~ð‹WRèžmÿÿƒÄ‹Øé ‹~Ћ‹NàWPjQèB—ÿÿƒÄ‹Øéð ‹~Ћ‹FàWjRPè&—ÿÿƒÄ‹ØéÔ ‹~ð‰|$ŠD$<uhèéë<uhÀéë<uhœéë <u hpéèÂ7ÿÿƒÄ‹WjQèÔ—ÿÿƒÄ ‹Øé‚ ‹~Ћ‹FàWRjPèšÿÿƒÄ‹Øéf ‹~ð‹Wh€jQèû™ÿÿƒÄ‹ØéI ‹~ð‹WRèEÿÿ‹Ø‹Pè±6ƒÄ é+ ‹~ð‹WQ臰ÿÿ‹‹ØRè“6ƒÄ é ‹F Pèì<ÿÿ‹N‹>ƒÄ‰L$éíƒÆð‹>‹V‰T$‹né܃Æð‹>‹F‰D$‹néÈ‹N ‹VìQRèÖ;ÿÿé§‹~ð‹WQjèó–ÿÿƒÄ ‹Øé¡‹V Rè€<ÿÿƒÄéŠNàŠVðŠˆL$ˆT$ˆD$‹|$ésŠNðŠˆL$ˆT$ÆD$‹|$éXŠFðŠˆD$ÆD$ˆL$‹|$é=ŠVðÆD$ˆT$ÆD$‹|$é#ŠFðÆD$ˆD$ÆD$‹|$é ŠNðŠˆL$ÆD$ˆT$‹|$éî‹^ü‹~àéã‹QèSJÿÿ‹= æƒÄ‹ØéËjëj‹‹Fà‹NðRPQè=¡ÿÿ‹= æƒÄ‹Øé¥‹‹= æé˜‹Rè8³ÿÿ‹= æƒÄ‹Øé€‹Pèð·ÿÿ‹= æƒÄ‹Øéh‹Qè(µÿÿ‹= æƒÄ‹ØéP‹^ ‹= æéB¿é8¿é.¿é$¿é¿é¿ é¿ éü¿éò¿ éè¿ éÞ¿ éÔ¿éÊ¿éÀ¿é¶¿é¬¿é¢¿é˜¿!鎿'é„¿$éz¿%ép¿(éf‹VðRèå¤ÿÿƒÄ‹øéS‹FðPè§ÿÿƒÄ‹øé@‹Qè0£ÿÿƒÄ‹øé.‹Rè΢ÿÿƒÄ‹øé‹‹Nà‹VðPQRè$£ÿÿƒÄ ‹øéjècªÿÿƒÄ‹øéñjèRªÿÿƒÄ‹øéà‹PèP®ÿÿƒÄ‹øéÎjÿè?®ÿÿƒÄ‹øé½‹QèÝ®ÿÿƒÄ‹øé«jÿèÌ®ÿÿƒÄ‹øéšè¯ÿÿ‹øéŽ葯ÿÿ‹øé‚‹R被ÿÿƒÄ‹øép‹Pè «ÿÿƒÄ‹øé^‹Q莫ÿÿƒÄ‹øéL‹Rè|«ÿÿƒÄ‹øé:‹Pèj«ÿÿƒÄ‹øé(‹QèX«ÿÿƒÄ‹øé‹Và‹> ×hüRèL«ÿÿƒÄ‹øéú‹j Pè8«ÿÿƒÄ‹øéæ‹hüQè!«ÿÿƒÄ‹øéÏ‹R蟫ÿÿƒÄ‹øé½‹h0ÇPè( ‹øƒÄƒÿÿ…¢hTéèÀ2ÿÿƒÄé¡ÄÈ3ÿ3É…Àt‹Và¸ÄÈ;PütƒÀAƒ8uòh@éè‹2ÿÿƒÄë‹<ÍÄÈ‹WQèÆ‹øƒÄƒÿÿ…@h$éè^2ÿÿƒÄé.¡ÄÈÇD$$…Àt5¸Äȋ苋RP胋øƒÄƒÿÿu+‹D$$‹MƒÅ@‰D$$‹Å…ÉuÖ‹l$hTéè2ÿÿƒÄéÖ‹L$$‹l$ <ÍÀÈé‹héRèM ÿÿƒÄ…Àu3ÿé§‹héPè2 ÿÿƒÄ…Àu ¿é‰‹h éQè ÿÿƒÄ…Àu ¿ék‹héRèö ÿÿƒÄ…Àu ¿éMhèèèk1ÿÿƒÄé;‹>é4‹PèƒÄ‹øé"‹QèƒÄ‹øé¿ é¿0éü¿éò‹RèÂÿÿƒÄ‹øéà‹Fð‹NÐjPQè ™ÿÿƒÄ ‹øéÇ‹Vð‹FЋN°RPQèî˜ÿÿƒÄ ‹øé¬‹‹FàRPjè&žÿÿƒÄ ‹øé”‹‹VàQRjèžÿÿƒÄ ‹øé|‹‹NàPQj èöÿÿƒÄ ‹øéd‹‹FàRPj0èÞÿÿƒÄ ‹øéL‹‹VàQRjPèÆÿÿƒÄ ‹øé4‹‹NàPQj@è®ÿÿƒÄ ‹øé‹‹FàRPj`è–ÿÿƒÄ ‹øé‹‹VàQRjpè~ÿÿƒÄ ‹øéì‹Pè ÿÿƒÄ‹øéÚè]œÿÿ‹øéο&éÄ¿|麿<é°¿>馿=霋~ð锿銿逿év¿él¿éb¿éX¿éN¿FéD¿Gé:ÇD$3é-ÇD$4é j‹Nð‹‹FäQRPèf«ÿÿƒÄ‹Øéjëâ‹Fôƒø3‰D$t ƒø4…ë‹‹T$jjQRè2«ÿÿƒÄ‹ØéЋF ‹NìPQè[4ÿÿ‹V‹>ƒÄ‰T$鬿騿éž¿锽銽逽ëy½ërjëj‹Fð‹‹VèPQRè$¯ÿÿƒÄ‹ØëU‹^ü‹= æëJ‹nøƒýtƒýt ƒýtƒýu3‹jjPUèî®ÿÿƒÄ‹Øë‹N ‹VìQRèª3ÿÿƒÄ‹F‹>‰D$‹n‹^ ‹t$D‹D$<‹L$ƒÆ÷Ø‹ÖÇD$<A‹L$‰:‰D$‰J‹L$4‰j‰Z 3ÒŠ‘PÊf‹¿ù¿U€ÎÇx=f9 EÕu¿EØÏ‰T$$ë ¿ỦD$$‹\$‹|$$‹l$,‹D$0ƒÃ‰\$é‰ñÿÿ‹l$,hÔèè$¡_ƒÄÇD$(ë#‹\$ÇD$(ë¡_‹\$ÇD$(‹l$,…Àtƒøþt‹L$8h _Qh´èè’ ÿÿƒÄ ‹D$<‹Ð÷Ú÷ØÁâ€R€i€8…{€8…¨€ 8…vý‚‚(‚2‚<‚(‚2‚<‚F‚8…X‚q‚Œ‚¤‚¼‚Ԃ삃ƒ4ƒLƒœƒ^ƒjƒtƒ~ƒˆƒ’ƒ8…œƒ¤ƒ®ƒ†„„¸ƒš„ƒ̃Öƒàƒêƒôƒþƒ „8…„4„ã„8„8…h„†„„š„¤„®„¸„¿„8…Ƅʄã„î„8……SU‹l$VW3ÿ‹ME…Ét#‹\$‹ð‹SPèýÿÿƒÄ…Àt‹NƒÆG‹Æ…Éuã_^]ƒÈÿ[ËDý_^][á€V@£€V‹D$Pht£èF)ÿÿƒÄÃhÛè6)ÿÿƒÄƒÈÿË ¬VìT…ɸu{‹ °V£¬V…Éu£°V¡´V…À¡ Áu£´V‹ ¸V…ÉuƒÀ £¸V¡¤V…Àt ‹ œVƒ<ˆu(è‹´Vh@Rèw‹ ¤V‹œVƒÄ‰‘è SUVW‹=¨V ˆV‹ßˆ‹5°V3ÉŠŠ˜æ 6ˆT$fƒ¹dÛt ‰5˜V‰=V‹T$¿©pë‹Â%ÿè¿,mHC;ît=¿±<úþš|Š…˜êˆD$‹T$ 6‹Â%ÿ¿©pëè¿,mHC;îuÿ upëâÿÊG¿4M f[ÄTÃ_^]¸$[ÄTÃ_^]¸%[ÄTÃ_^]¸C[ÄTÃ_^]¸D[ÄTÃ_^]¸E[ÄTÃ_^]¸F[ÄTÃ_^]¸U[ÄTÃ_^]¸V[ÄTÃ_^]¸W[ÄTÃ_^]¸X[ÄTÃ_^]¸][ÄTÃ_^]¸^[ÄTÃ_^]¸[[ÄTÃ_^]¸\[ÄTÃ_^]¸Y[ÄTÃ_^]¸Z[ÄTÃ_^]¸a[ÄTÃ_^]¸b[ÄTÃ_^]¸_[ÄTÃ_^]¸`[ÄTÃ_^]¸&[ÄTÃ_^]¸'[ÄTÃ_^]¸([ÄTÃ_^]¸)[ÄTÃ_^]¸*[ÄTÃ_^]¸+[ÄTÃ_^]¸d[ÄTÃ_^]¸e[ÄTÃ_^]¸f[ÄTÃ_^]¸g[ÄTÃ_^]¸h[ÄTÃ_^]¸i[ÄTÃ_^]¸j[ÄTþE_^][ÄTÃ_^]¸4[ÄTÃ_^]¸5[ÄTÃ_^]¸6[ÄTÃ_^]¸=[ÄTÃ_^]¸<[ÄTÃ_^]¸=[ÄTÃEUèƒÄ£ _¸;_^][ÄTÃUèòƒÄ£ _¸8_^][ÄTÃU脃ģ _¸#_^][ÄTÃUè¶ÿÿƒÄ£ _¸9_^][ÄTË _Rè’ÿÿƒÄ£ _¸:_^][ÄTÃ_^]Ç _¸#[ÄTÃ_^]Ç _¸#[ÄTÃ_^]Ç _¸#[ÄTÃ_^]Ç _¸#[ÄTÃ_^]Ç _ ¸#[ÄTÃ_^]Ç _ ¸#[ÄTÃ_^]Ç _ ¸#[ÄTÃ_^]Ç _ ¸#[ÄTÃ_^]Ç _¸#[ÄTÃ_^]Ç _¸#[ÄTÃ_^]Ç _¸#[ÄTÃ_^]Ç _¸#[ÄTÃ_^]Ç _ ¸#[ÄTÃ_^]Ç _¸#[ÄTÃ_^]Ç _¸#[ÄTÃ_^]Ç _¸#[ÄTÃ_^]Ç _¸#[ÄTÃ_^]Ç _¸#[ÄTÃ_^]Ç _ ¸#[ÄTÃEUè…ÿÿƒÄ£ _¸7_^][ÄTÃ_^]3À[ÄTÃêŒ **:JZjzŠšªºÊÚêú ‘‘*‘:‘J‘Z‘j‘z‘Š‘š‘ª‘º‘º‘ʑʑڑê‘ú‘ ’’*’:’J’Z’j’z’Š’š’ª’º’Ê’Ú’ê’ú’ ““*“:“J“Z“j“z“Š“š“ª“º“ʓړê“ú“ ””*”:”J”Z”j”z”Š”š”ª”º”ʔڔê”ú” ••*•:•J•Z•j•z•Š•š•ª•º•º•ʕڕê•ú• –ÔŠ–)–9–I–Y–i–y–‰–¨–Æ–ä–g|&—@—&—Z—¬˜t—ƘŽ—¨——Ü—^˜ö—˜à˜*˜D˜^˜x˜’˜¬˜Ƙà˜ú˜™™¢¹ð‹3™‹ ¤VSU‹-œV‹ _V‹©W‹Ú‹p¡ŒV|¡¨V;Çv$hPëèÆ ‹ ¤V‹ _¡¨V‹-œVƒÄ‹<©ƒ(u+Â_H^÷ØÀ]÷Ø@[Ëø+úO…ÿ~‹ÇŠ ˆFCHu÷‹ ¤V¡¨V‹-œV‹©ƒz,u3À£ŒV‹©‰Béñ‹r +÷N…ö‚÷ÙÉ#Ê‹ñ‹N+Á‹Ø‹F…Àt(‹F …Ò‹ÐÁêЋ‰V ƒÀPQèP ƒÄ‰FëÇF‹F…Àu h$ëèðƒÄ‹F‹ ¤V‹œVã¨V‹‘‹r +÷N…ö~„‹-œVþ ~¾ ‹©‹P…Ò„ 3í…ö†Š‹ À‹ ´VQÿӃăøÿt!ƒø t!‹¤V‹ œV‹Š‹JÍE;îˆ9r΃ø u*‹¤V¡œV‹ ‚‹QÕE‹ÅÆ: ‹ ¤V£ŒVéɃøÿu¡´Vö@ t hëèƒÄ‹ ¤V‹Å£ŒVéš‹-àÀÿÕÇ‹ ´V‹¤V¡œVQ‹pÀ‹ ‚Vj‹Q×RÿӃģŒV…ÀuT‹ ´VöA tHÿÕƒ8uvÿÕÇ‹´VRÿ¤À¡´V‹ ¤V‹œVPVj‹‘‹HÏQÿӃģŒV…Àt¬‹ ¤V‹œV‹ ‘‰A¡ŒV…ÀuL…ÿu0‹´V¾R襃Äë4hëè6‹ ¤V¡ŒVƒÄë·¡¤V‹ œV¾‹ˆ‰r,ë3ö¡œV‹ ¤V‹ŒV‹ :;A vI‹I‹ÂÑøÂÇPQ苤V‹ œVƒÄ‹ЉB¡¤V‹ œV‹ˆ‹B…Àu hÔê誃ġŒV‹ ¤V‹œVÇ£ŒV_‹ ‘‹QÆ¡¤V‹ œV‹ˆ‹ ŒV‹BÆD‹¤V¡œV‹ ‚‹Æ^]‹Q[‰ _ÃQ¡°VU‹-¨VW‹= _;ýƒ¹SVŠ„ÉtáÿŠ ˜æˆL$ëÆD$fƒºdÛt £˜V‰=V‹t$¿špë‹ÎáÿÙ¿]HC;Øt=¿‚<ú=š|Š˜êˆT$‹t$‹Îáÿ¿špëÙ¿]HC;ØuÿEpëæÿÆG;ý¿E ‚Kÿÿÿ^[_]YÃQ‹D$ÆD$ fƒ¹dÛt‹¨V£˜V‰V¿‘pë¿UJC;ÐtM‹T$VW¿<ú=š|âÿŠ •˜êˆL$‹T$ ‹úçÿ¿±pë÷¿4uHC;ðu½_^ë‹T$¿Epëâÿ¿ E ‹Á-™÷ØÀ#ÁYá¤V…Àt ‹ œVƒ<ˆu-è¶‹´Vh@Rè‹ ¤V‹œVƒÄ‰‘¡¤V…Àt ‹ œV‹ˆë3À‹T$RPè’ƒÄéšè[¡¤V‹ œV…Àt‹ˆë3ÒV‹t$;Öta…ÀtKƒ<ˆtE¡¨VŠ ˆVˆ‹¤V¡œV‹ ‚‹¨V‰Q¡¤V‹ œV‹ˆ¡ŒV‰B¡¤V‹ œV‰4ˆèÇ„V^á¤V‹ œV‹ˆ‹R‰ŒV‹ˆ‹R‰¨V‰ _‹ˆ‹‰ ´VŠˆˆVÃVj0舋ðƒÄ…öu hˆëèEƒÄ‹D$ ‰F ƒÀPèbƒÄ‰F…Àu hˆëèƒÄ‹D$ÇFPVèYƒÄ‹Æ^ÃV‹t$…öt>‹ ¤V‹œV…Ét‹‘ë3À;ðuÇ‘‹F…Àt ‹FPè%ƒÄVèƒÄ^ÃSVW‹=àÀÿ׋t$‹Vèy‹L$º‰‰V(¡¤VƒÄ…Àt U‹-œV‹¨]ë3À;ðt ‰V ÇF$…Ét#QèŽP肃Ä3É…ÀŸÁ‹Á‰Fÿ×_‰^[Ã3À‰Fÿ×_‰^[ËD$3É;Át:‹P‰Hˆ ‹PˆJ‹P‰PÇ@‰H,‹¤V;Ñt ‹ œV‹ Š;Áué<þÿÿá¤VV…ÀuAjèïƒÄ£¤V…Àuh¸ëè©¡¤VƒÄÇÇ VÇœV^Ë  V‹5œVQÿ;òrMq µQP衋Ѓą҉¤Vuh¸ëèH‹¤VƒÄW‹= V¹3À<ºó«‰5 V_^ÃSU‹l$Wƒýrd‹|$3Û8\/þuX8\/ÿuRVj0è*‹ðƒÄ;óu hìëèçƒÄEþV‰F ‰~‰~‰^‰‰F‰^ÇF‰^(‰^,èŠüÿÿƒÄ‹Æ^_][Ã_]3À[ËT$W‹úƒÉÿ3Àò®÷ÑIQRèƒÄ_ÃSVW‹|$_Sè ‹ðƒÄ…öu h@ìè]ƒÄ…ÿ~‹L$U‹Æ+΋@Mu÷]SÆD>VÆ>èÿÿÿ‹ðƒÄ…öu hìèƒÄÇF‹Æ_^[ËD$‹ ÁPƒÁ@hlìQÿÁƒÄ jÿœÀ‹D$PÿÜÀƒÄËD$‹L$PQÿ˜ÀƒÄËD$PÿØÀYËD$PèæþÿÿƒÄ£”Vá”V…Àt PèaüÿÿƒÄÇ”VøÃQUW‹|$3íÇD$ €?0u!ŠG¸Ÿä·Ò¶M¸ ¸á¶ѸÆ·ð¶\¸¸ÿ¶ݸÕ·k¸¸·õ¸ó·,·‰¸/¸;·é¸z¸w·†·¹˜¸ ¹§¸·¹1¹h·=¹,,,,,,,,,,, ,,,,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,!,,,"#,,$,,,,,,,%,,,,,,,&,,,,,,,',,,(,,,),,*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+¡ðZ…ÀtPÿìÀƒÄÇðZÇ_áðZSUV…ÀWu!h îhŒïÿLÀƒÄ£ðZ…Àu_^][Ë-tÀPhhPXÿÕ‹ðƒÄ …öto‹xÀ€>#tIh¤ïVÿӃąÀt:h ïÆV‰5àZÿÓ‹ðƒÄ…öt ÆŠFF< tø< tôhœïVÿÓ‹øƒÄ…ÿu"¡ðZPhhPXÿÕ‹ðƒÄ …öu—_^]3À[ÃÆVGÿ´ÀƒÄPÿ`Á¾TZh ïWf£èZ‰=ìZ‰5äZÿӃąÀt:Æ@t4Š„Ét.€ù t$€ù tþÜZs‰ƒÆh ïPÿӃąÀtÆ@…ÀuÌÇ_^]¸àZ[ÃZ†Ò†ʆ´†¦†ކv†Ä…H†8†,†††ô…æ…Ö…2„Š„–„…ô„…â„Ø„섾„´„Є.‡$‡‡‡‡þ†´…¨…’…ˆ…€…x…l…`…P…F…>…6…*…(„¨„…þ„âƒìƒøƒ„ „„„ž„d„<„F„P„Z„n„x„‚„€s€€€€€€€€ €t€€€ €5€o€4€€7€ € €€€p€8€€€3€€¶‚p‚†‚ƃ¢‚ü‚΂ä‚8ƒ ƒ$ƒrƒLƒ`ƒ°ƒˆƒœƒ\‚L‚8‚"‚‚úæÐ2yÖMN0@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.112.2.12 2008-09-22 20:16:01 guy Exp $ (LBL)  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿Àáâãäåæçèéêëìíîïðñòóôõö÷øùúÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿlibpcap version 1.0 branch 1_0_rel0b (20091008)4.1.1WinPcap version %s, based on %sWinPcap version %s (packet.dll version %s), based on %s@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.168.2.10 2008-10-06 15:38:39 gianluca Exp $ (LBL)@(#) $Header: /tcpdump/master/libpcap/fad-win32.c,v 1.15 2007/09/25 20:34:36 guy Exp $ (LBL)@(#) $Header: /tcpdump/master/libpcap/pcap-win32.c,v 1.34.2.8 2008-05-21 22:11:26 gianluca Exp $ (LBL)@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.290.2.16 2008-09-22 20:16:01 guy Exp $ (LBL)@(#) $Header: /tcpdump/master/libpcap/optimize.c,v 1.90.2.1 2008/01/02 04:22:16 guy Exp $ (LBL)@(#) $Header: /tcpdump/master/libpcap/bpf/net/bpf_filter.c,v 1.45.2.1 2008/01/02 04:22:16 guy Exp $ (LBL)@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.75.2.4 2008-04-20 18:19:24 guy Exp $ (LBL)@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.99.2.2 2007/11/18 02:04:55 guy Exp $ (LBL)˜è”èˆè„è|èpèdèXèLè @è 4è0(è0è@ è@èPôçPèç€àçØç Ì砼簴簤çÀœçÀˆç €ç°|çÀxçÐtçàlçð`ç˜èTç Dç00ç@(çP ç`çp ç€çðæ Üæ°ÄæÀÀæà´æð¤æ`ÇÈ@Ènpwvsqrt}zyx{|o  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmu~€‚ƒ„„„………………………†‡ˆˆˆ‰‰ŠŠ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽ‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘’’’’’’’’’’’’’’’““““““””””••––—˜˜™™š›››œœœžžžžžžžžžžžžžŸŸŸŸŸ  ¡¡¡¡¡¡¡¡¢¢¢¢££¤¤¤¤¥¦¦§§§¨¨¨¨©©©©ª««3EFDGHIJKLMNOPQRSUT¦noC VWXYqstuZ[d\]^_`acbefg¨©ª«®¯¬­°±²³´µh½¾¿ÀÁÂÃ332,v“’-.0klxyz{‰Š|‹}prž 33 “’' 54>B?@A$%ij:;<="#&w‘ŒŽº/¶È1Ä¢¡¤¥£33’ (Ÿ§‚ƒ†€‡ˆ!œ›š–—˜™*+»·¸ÉÅÆm’9786”¹Ç„…~¼Ê•ÿÿ|yzÑ…†tÓÔVWXY›œu[\žÜ Þánp®¯]^Á_`ab´µïcdº»ó:ÿØ:ÿ(=:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿåÿ6QRóÿ::ÿ:ÿ:ÿ:ÿ:ÿ:ÿèÿèÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿÊÿªª:ÿ—:ÿj :ÿ:ÿ :ÿ:ÿ:ÿ:ÿ4:ÿf:ÿ:ÿ¦ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿèÿ:ÿ:ÿ§ÿ:ÿ:ÿ:ÿAA:ÿÄÿ :ÿ:ÿüÿ!:ÿ:ÿ:ÿ——:ÿãÿúÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿôÿCõÿ:ÿ:ÿ:ÿ:ÿª:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿrsv:ÿ:ÿ:ÿz{€:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿÔÿ:ÿAA:ÿ:ÿ:ÿ:ÿ:ÿ:ÿn…†:ÿ:ÿ<Êÿ¬µ·¹:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿÍÿDDNcùÿùÿ:ÿ:ÿÔÿÔÿ:ÿÞÿ:ÿ:ÿ:ÿûÿ:ÿ:ÿ:ÿÌÿ:ÿ:ÿ:ÿ:ÿ——:ÿ:ÿ:ÿ:ÿ÷ÿ:ÿ¡:ÿr:ÿz:ÿ:ÿ:ÿ:ÿ:ÿJ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿÅ;ÿªÿ‡ÿþÿ:ÿ:ÿ¯ÿ:ÿ:ÿ:ÿ:ÿ-:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ:ÿ¸ÿÑÿêÿ­ÿ:ÿÝÿ:ÿ:ÿ:ÿ:ÿWÿ:ÿ:ÿ:ÿ:ÿ]ÿ:ÿU„}{ÎrsTîZ£¤×ÿÒýóÿ£¤ò¼½lÚß² ¸h¾¿À}ŸÄÉeqqÇÊmÛà wx~³ˆ¹wxãÿãÿËv¥¦§¨©ªÍ¥¦§¨©ªxfÒÂÖ×~UU‡ÈȰTTZZÃR±g·ˆÕØÙx ¡¢©ªiqÏo}{jkÆÆ×ÿ×ÿÝóÿóÿÅÅZZÌ×ÿ‡qóÿÍŸã¶£¤äåæçèéêëаðìíñ ¡¢¶ô£¤È÷õö  øùúR«¬­‹þûާ¨©ªÿ¦§¨©ªÆUSâÅÅZZ€‚ƒ§¨©ªýÿˆˆüR«¬­ ‡‡ !P"R#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQR  !"€‚ƒ#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQR  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQR  ¡¢"£¤#$%&',-./0123456789‰Š‹ŒŽH‘¥¦§¨©ªQ«¬­R’“”•–—˜™šWUT()±=>$‡Ô=>·op$$$b$d8xyzt{yz$()yzï888ó8lmUbWdlmlmvQopqrstvopqrst|}m$ÆqlmtTUvWyz$TUTUtwb$d†‡lmm567st8qtv8ÆÅ$$yzlm8lmyzyzvv†‡vv{Ÿ$=>£¤¥¦§¨©ªt$$®¯$567$$=>ÅÆ$$üý:$$wxyzv qrst$.pqrstÅÆ$|›ÿÿÅÆÅÆÿÿ89:;<qrstüýÿÿÔwxyzÿÿÿÿ ÿÿÿÿ !üý$%&'()*+,nÿÿÿÿÿÿÿÿÿÿÿÿ4ÿÿwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkÿÿÿÿnÿÿÿÿÿÿrÿÿ ÿÿw !ÿÿÿÿ$%&'()*+,ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ4ÿÿÿÿÿÿ89:;<ÿÿÿÿ?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkÿÿÿÿnÿÿÿÿÿÿrÿÿ ÿÿw !ÿÿÿÿ$%&'()*+,ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ4ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkÿÿÿÿnÿÿÿÿÿÿrÿÿÿÿÿÿÿÿw !ÿÿÿÿ$ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ567ÿÿ4ÿÿÿÿÿÿ=>ÿÿÿÿÿÿÿÿÿÿ?@ABCÿÿÿÿÿÿÿÿHIJKLMNOPQRSTUÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿd ÿÿÿÿÿÿopqrstÿÿÿÿrxyzÿÿwÿÿÿÿ"#ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ-./0123€  !$%&'()*+,4?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijknrw†‡Š‹Œ‘’“ž ¡¢£§¨$$$88$$$8™8š‡  ‡‘lm‚ƒŠž 89:;<„…†‡  "#-./0123Ž”{567=>opqrstxyz›œ$‡›œ¤¥$‡›œ©ªopxyzŸ „†‡Š „Švvvtt„…ˆ‰ lmlm$8•8—$8˜¥¦$$ª«$$$ :$$v‚ƒ.|}vƒvƒ„„$8–$¥ª|‘ŽfffgŽgggppggggŒŒŽŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒgŽjn@ŒpŒŒŒrlikhmŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒ!"ŒŒŒŒŒŒŒŒŒŒŒŒŒŒXŒAŒŒŒŒŒŒŒŒŒŒŒRŒŒŒŒŒŒŒŒŒŒŒŒŒŒAnŒqqŒpŒrprrrŒŒŒ@ŒMŒŒŒŒŒŒ6dŒŒŒŒŒŒŒŒŒŒŒ#ŒŒ*ŒŒCŒŒK$Œ`ŒŒŒŒaŒ-BNcŒŒŒŒŒŒŒZŒŒŒbŒe%Œ)Œ Œ UŒTŒŒŒŒqŒŒŒŒpŒsrrrrrŒŒŒŒ=(Œ&ŒŒŒŒ^ŒŒ, Œ ŒŒŒJŒ;_.ŒŒŒGŒŒŒŒ/ŒŒ'ŒŒYŒ[ŒŒŒ4FŒqqŒqqqŒpŒrŒrrsrrrrrrŒ789:ŒŒŒŒŒŒŒŒŒŒSŒ ŒLŒŒOŒŒŒ1ŒŒŒŒŒŒŒŒŒŒŒŒŒŒqŒŒŒŒqqŒpŒrrrsrrsrrrrrrrrrr]ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒCŒŒŒŒŒŒŒHIŒ\ŒŒŒŒŒŒŒŒŒŒŒŒqqŒqqqqŒpŒrrrrrsrrrrsrrrrrrŒŒŒŒ3<ŒŒŒŒŒŒŒŒŒŒŒŒDŒŒ+PQŒŒŒŒ5ІŒˆ‡‹ŒŒŒqŒŒŒqŒpŒrrrrrrsrrrrrrrrrrrrrrrrrŒŒŒŒŒŒŒŒŒŒŒŒŒutŒŒEŒŒŒ‰…ŒŒqqqqŒpŒrrrrrrrsrrrrsrrrrsrrrrrrrr>Œ6zŒŒŒŒŒŒŒŒŒ?0ŒŒŒŒŒŒŒpŒrrrrrrrrrsrrrrrrrrrrrrrrrrrrrrrrrrVŒŒŒŒŒŒŒŒŒŒŒ2ooqqŒpŒrrrrrrrorrsrrrrsrrrrsrrrrsrrrrrrrrrŒŒŒŒŒŒŒŒŒWooqŒoorrrrrrrrrrrrosrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrŒŒŒƒŒŒŒŒŒŒŒwqŒprrrrrrrrrrrsrrrrsrrrrsrrrrsrrrrsrrrrrrrrrŒŒŒŒyŒŒŒ}Œorrrrrrrrrrrrrrrsrrrrrrrrrrrrrrrrrrrrrrrrrrrrv‚„~ŒŒŒŒrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrŒŒŒŒrrrrrrrrrrrrrrrrrrrrrrrrrrrŒŒŒ€rrrrrrrrrrrrrrrrrrr{Œxrrrrrrrrrrrrrrrr|rrrrrrrrrrrr   !"#$%&'()*+,-./012345  þ5éé6è<õéRéd˜/å1©Ó©=,=z>KÏ×Ú  ¦›æì5ح³éé)@XÔpw™ééééé)¹¶Ã¶´±¥Ÿ¤¢¡ªš‰u“–†„‘tywQ{v}‹ßzyql§\Z]`U]TDJRAF?111„<+5.ª*Ê6$ý éé²ÊÓó #*Bäê ï æ ë ó î ã Õ Ò Ó Ú Õ Ê Ö Ñ Å ¾ Á ­ ° ¼ ­ ¬ ± ¡ — £ ž ’ ™ Ž Ž ‚ þp n } w z h l W Z _ X S Q ^ S D A K A > > jM ™K  áâ¸B ÐA > Ø%= < è,  L   ñ é ã ä S× ß Í Î Ì Ú Ã À ¸ µ Å ª ‘ œ ’ ‘ ä‡ ‚ Є 1I;rŠ ‰ ‚‰¡¹€ ÀZ{ z ×õïj h •˜g 6=f k A 7 E D # ! 0 I   û ô ê ô â á ñ Ÿî ã Û é Ù Ó Û Ê © ª £ ¨ ¶ nÈ …Æ ¤`6¼Xäû¥ ¤ Y£ ¢   Ÿ Dqž Ž ðdm …zŒ ’ ˆ g2‡ M®Å† j l Y _ O U b E T R JA ˜A )  '  &  "     ü  ó ï é ç ì ð ï Þö™ ÷ f7OVnî u¤í ì ë »TÓêé Óºè Úç ãþß Ò11Ö I±Õ Ü ‚¸ ¼ ¹ ¾ ² ¤ ¤ ° Ÿ ¤ œ Ž ™ ˜ ‰ • ‘ – {  t q— ˆ • §Ó¿×Þö‹ Š þɉ 'íy x w v Pîu oƒyr ‘òq j hji h ã%º_ Òó^ d 3:[ [û Z ) ßárnñ. ±O- , i+ ) ßV'  O t ˜ ¼ Ô QÜ ô 2 û  * 1 B Y 0 / - p bˆ Ÿ , œK+ £· Î  ¨ `æ ý  'g j«  ¿Þ  -  ;y<iãl¯²(#°*jþ!%W An B… B µ   ½ ‚ æ Ÿþ  æý ü û å 8 nä ža ã y qâ é pç æ ¢ Ý º rÜ Í „gÌ KLË Ê Maã Á û †¿ Æ ¨¯á½ é$ ; ¼ ‚™ÏÐpÑ­éþäÿT k ƒ ¢« Ã Û â ú Œ )@‹ Xo} | { †@ žµz f ©G ‹ Íä, Ÿ ¦ É+ ­ ü* ´ D ø) K +B îÔ " v·!  ÷øZ r ú7 8 O¹9 /: .0fhœ´½}  Ï5îø8ë!SêJVéÙÕrŠ…Ón o ³ÁˆÀÇ$ S ÄÃS T ô𠇙 žÛ œW ã ›šð ö 5€M£†¤& ƒ÷ wr 3 vWŽ¥9#O — ·ÎÄ Å  ~_ 9` ã½Õ¶çÿ1H`w¦¾ÕíÞÖ çæ $åš .äã¡ ‰ÿáFàßÄæ(Þí^ÇÆ?Å8vÄÁà?¸5 I ´²\ ^ Žw¦áPT×…†ðC‡H/³a ÐKáùm "n K­tóñÜdÆØÁÀŸ Å Þ¬©aÞ  `H 5 ö%!U¡þT ª îí :áȽV¨¸iT·Um&rovWâUq°SQÜï>GF+#*^"dV ´ËÌÍⶈ˜nr—¯ëÇêßå÷Áñ2½¼¬–Zk_T © ñÜ "ÅýÄ:Àª×RzstZs³CoÈ'Èà; ãûä?ù@9zBYBqh“u@¤ Ï¨¼bÛàýibq~cyŒ«š§Èɵ…‘Ý ” qéÃè ééVé]édékérz{!¯* {.‰#1%k—(m£QnªT±é·‰¸V¢¿XéÑÙÝàãæéìïòõøûþ  !$'*-158;?ADGJMPSVY]_bfkorvy|‚…ˆ‹“–šž£§©­°´·º¾ÀÃÆÉÌÏÒÕØÛßáäçêîðóöûÿ !$'*-037;>BFKOQUX\_dhmqswz~„‡‹•™œŸ¢¥¨«®±µ·º½ÀÄÆÉÌÏÒÖØÛÞáæêïóõùü  "&)-16:<@CGJOSX\^beilotx}ƒ‡ŠŽ‘”—› ¥©¬¯²µ¸»¾ÁÄÇÊÎÐÓÖÙÜàâåèëîñõ÷úý  !&*,037<@CFILORUX[_cfjnswy}€„‡Œ•™›Ÿ¢¦©¬±µº¾ÀÄÇËÎÑÖÚßãåéìðóöùýÿ  #&),/37:=ADGKMPSWY\_bfhknquwz}€„†‰Œ‘•šž ¤§«°´·º½ÀÃÆÉÌÐÒÕÙÞâãæëïôøùüÿ !&*+.16:?CDGJMQSX\_behknrw{|‚…ˆ‹Ž‘”—šŸ£¦©¬°´¸¼ÀÃÆÊÍÐÓÖÙÝà™™™™™™™š™™™™™™™™™›™™™œ™2™™™™™™1››444444™™’•ž™6™šŸ––––õö– û¡¢™£¤™™™¥¦DöøöøøK§™J¨©™™™™ª«¬­­™®™]¯¦‘’’—‘Kš°±™ž²™³´™¤µ¶··™¸™¬¹«™™º»™™™™¼½å’”’’ëší¾™™™¿ÀÁ™™™™ÂÙÄÅ™™™™ÆÇÈȺ»Éəʙ ËÌ88<í>ÍΙBÏ™EЙÑÒ™KÓÔÔ™Õ™RÖרØÙÚÛۙܙ^Ýޙߙàá™™™™âã?mmmmmmmmmmmmmmmmmmmmmmmmm†††m†‹ä™™™å™™æçè™™™™éê™ëì™™™™íî™ï™ðñ™™™™òóô™õöö÷øùù™ú™¼ûüýýýýýýýýýýýýýýýýýýýýÒýÒÖÖØþÿ™Ü™ß™â™™è™™ï       ™™û™™™ ™™™™™™              '')'',!™™™"™™#™™$%&™™™™'(™)*™™™™+,™-™./™™™™012™3™45™™™™6789™:;;<=>>™?™m@ABBBBBBBBBBBBBB~BBCD™„E™‡F™ŠG™H™I™™“JKK™L™šMNOOPQRR™S™¦TUV™WXXYZ[[™\™µ]^_`™abbcdee™f™Åghi™j™kl™™™™mnoooooooooooooáop™™™q™™r™™s™™tu™óvw™™xyz™{|™™™}~™€™‚™™™ƒ„…†™‡™ˆ‰™™™Š‹Œ™Ž™™™™‘’“”•™–——˜™šš™›™4œžžžžžžžžžžžŸ™™E ™H¡™K¢™N£™Q¤™™™¥¦§¨©©™ª«¬­­®¯°°™±²³´™µ¶¶·¸¹¹™º»¼½¾™¿ÀÀÁÂÃÙÄÅÆÇÈ™ÉÊÊËÌÍÍ™ÎÏÐљҙÓÔ™™™ÕÖ×ØØØØØØØØ™¨ÙÚ™ÛÜ™ÝÞ™ßà™áâ™ãäå噿çèéê™ëì™í™î™ïð™ñò™ó™ôõ™ö÷™ø™ùú™ûü™ý™þÿ™™™      ™  ™™™ !"#™$%%&'()*™+,,-./01™2334567™8™9:™;<<<<=™>?@ABCDDEFG™™H™I™J™K™L™M™N™O™P™7Q™8RR9:S<<<T™UV™HIW™JKX™LMY™NOZ™P[™\™<]™U^_`ab[c™\d^_`abede™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™    !"#$%&'()*+,,5,,,,,,,,n,9:,<=,,oHRS—,,,5,†ç,,,IA,BCTèJD‡UK,ELVˆFMG,0122222223W¸Ð456¹­7444444555555555555555565,®N,½,O¯,ÄÂÛPÇÅQÃ?8<?=?5Ü?,>4444444?h¾Õui5p?vwáxyjkŠÖlqmrÈs‹ÉtÊŒâ5755555555™ab¿5›55Iä555555YcåZ[d\™]e^f_zÀ`5{gÁÂ=„Æ|5€…}‚~™>ƒ,„…,*,5Ñ,”””””””?+,?Ò??É?5,‘‘‘‘‘‘‘?™5‘5êÊ?‘‘‘‘‘‘’““““““ú5ú™”™bcde””””””1•••••••¦f5–™5™Ã––––––>–––––––™™™™™™™™5™–™bcde™™™™™™™,øÃ,÷,±5,±™š››››››,™²Èœ™5Ê,øœœœœœœóôôôôôôôS²ô™™5òËôôôôôôõööööööö5ˆ5÷™ø™™Ð÷÷÷÷÷÷FFFFFFFYZZZZZZü™øù÷÷÷÷÷÷÷™™Òý÷™™Á5 ÷÷÷÷÷÷úûûûûûûûüµ™™ýý:™™·ýýýýýý5ýýýýýýý:Ä55Ñ77÷77×op™™™™™™™ØÚüÌ;q77CCCCCCC™5”5Cr777CCCCCCDEEEEEEÅ7™F”™™5FFFFFFõGGGGGGGHHHHHHH™™àH™77“7HHHHHHJKKKKKKK77$7L !™â#LLLLLLOLLLLLLLSTTTTTTTUhˆbVW‰jVVVVVVŠc‹Œ™¨©©©©©©7b7W[[[[[[[Uc™\™717d\\\\\\]^^^^^^e3J_N™7R7______d7e7"%™Ò7Ô‘’’’’’’’V77Z“j”€™•““““““çççççççД•“““““““5¦™ž“™™7¹““““““—˜˜˜˜˜˜™U7™™™ž7™™™™™™™™úššššššš˜7™U›™q51¦››››››5›››››››žŸŸŸŸŸŸ¶¡5¦ ³7774      ¤¥¥¥¥¥¥¦777§¦rsu7§§§§§§SªªªªªªªU¬°7«É77w7««««««¬­­­­­­¦77™®zx7É7®®®®®®³³³³³³³7¦7´™Ú777´´´´´´µ¶¶¶¶¶¶¶·777¸™¹Þ™à¸¸¸¸¸¸       NOOOOOO­™¹Â™™¦Ã™7Ä7¦Å¦ÆÇÈÉäääääää§7™7ä™77™Íääääääåææææææ577§ç™™™™Uçççççç‘èèèèèèèééééééé™™™é™™¦7éééééé–ëëëëëëë¦ú7ì¹ø™™ììììììVWWWWWWZ[[[[[[7¨øììììììì™¶”™ì©³°7Ïììììììííííííí5™î”™­©îîîîîî5îîîîîîîSñññññññò<¨úóWÒ#çóóóóóó™±²²²²²²´µµµµµµ7W÷øøøøøøøù™¦¹ú\û7úúúúúú¸¹¹¹¹¹¹ëìììììì7ûSþþþþþþþò¦ÿ¶™™77ÿÿÿÿÿÿP7=™™óôôôôôô÷øøøøøø7µ       ·™ ™7 7       7v¦@™7™75666666677³6A™E766666678888888E 79£:™ê999999ÿA7:79999999™P¦B9™°77í999999–<<<<<<<\7™{=B¦™ð<======5=======>>>>>>>Ð÷ü÷?Ï×ßÒ­??????5???????BCCCCCCÏ×ß™D0M777DDDDDDSªªªªªªªò777«™Q0MA««««««EFFFFFF™¤¡¢G¦77­QGGGGGGKLLLLLL¦77™M¦W777MMMMMM÷PPPPPPPù777QÀ777DQQQQQQRSSSSSS¦777T9õ¹7¶TTTTTT\\\\\\\7;]:³7°°]]]]]]^______¦ 7U`Y­7³``````µfffffff·7‡gUˆY¶gggggghiiiiiiij#DÐk‡lˆ¹kkkkkk²²²²²²²7Jl„„„„„„„‰UŠ‹„KÒ77ú„„„„„„…………………t›7‰…Š‹K………………7†††††††‡‡‡‡‡‡‡›–‡Ì77™Ê‡‡‡‡‡‡–‰‰‰‰‰‰‰77%–Цð¦öŠŠŠŠŠŠ5ŠŠŠŠŠŠŠ‹‹‹‹‹‹‹í ¦êŒ¦çù¦ŒŒŒŒŒŒ5ŒŒŒŒŒŒŒ÷7JL‘Wû¦DL‘‘‘‘‘‘™Mð7íêç™DÒ77\7û’’’’’’’“™M7”77™7””””””&#%;+++++++7VVX7˜™™™™™™™šW™Y›<œð7X››››››™7Ù¬W™YÊXœ÷ŸŸŸŸŸŸŸ7VË Pí™h      ¡¢¢¢¢¢¢¢£¡LJ¤Ë¥E ꤤ¤¤¤¤bcccccceffffffÊ7¥ªªªªªªª“˜A™«<ç7Û««««««¬­­­­­­­®ùÜ’¯™°ƒ77¯¯¯¯¯¯ijjjjjjðíê77çÌÌ7°hºººººººjyÍ™»?åƒ7»»»»»»¼½½½½½½ÕÒh¾Í™^¾¾¾¾¾¾55555557R4G577777555555–——————77777ÀÒ1ÓÓÓÓÓÓÓÖרÝÓß8777ÓÓÓÓÓÓžŸŸŸŸŸŸüü7775ÔÕÕÕÕÕÕÕý™;>Õ§>’ƒ7ÕÕÕÕÕÕ¢££££££41ƒý™5†††††††ª««««««­®®®®®®±²²²²²²º»»»»»»5‡‡‡‡‡‡‡j¬^‡7¨¦¡‡‡‡‡‡‡ÖGGGGGGGúØØØØØØØR4÷Ù˜G1>;ÙÙÙÙÙÙ5ÙÙÙÙÙÙÙÜÝÝÝÝÝÝçÛ74Þ1/ÛhÞÞÞÞÞÞ÷PPPPPPPjµdQb®“£QQQQQQßààààààšçáÛ“Û5áááááá\\\\\\\“55]Î55È]]]]]]âãããããã™j·ä®“Sü÷ääääääèééééé馣™êš—JA“êêêêêê˜íííííí횎Aî75ƒ‚îîîîîîïðððððð¦€~ñ}|{zyññññññ¡ùùùùùùù£xwvúutsrqúúúúúúûüüüüüü¦ponýmµj·±ýýýýýý¬®òù JAòA;             ¦;43 210/.      hj-,8Þ+*)('&%$#"!½¾¾¾¾¾¾ÁÂÂÂÂÂÂ7''''''' ™'7''''''((((((((™(((((()******·¦+S7òù++++++ú,,,,,,,7¦ö£-òðg------5-------˜00000001•ã2âœáàß222222ccccccc«««««««Þœ¡33333334Ý™5Ü¥Û555555ÚÙØ×Ô™ÓÐÏÎ7™Í¥¬66666667Ì™87°™888888»»»»»»» fqËÊ™•Á°<=======>™À–?¿@¾ •??????)******™½¼»™—–—º@˜CCCCCCC1˜™D·¦™UDDDDDDEFFFFFFFG£˜H™I––HHHHHH,------0111111ÃŽI¡NNNNNNN4‡†ÄOƒ‚€OOOOOOPQQQQQQQR77ÃSÄT~}|SSSSSS{™z77[\\\\\\Èy89T¬ZZZZZZZ7É™x[wvuts[[[[[[\]]]]]]]^7ÈÉ_n`m&7______™lk7abbbbbb7jÊ:i`kkkkkkk™ËhlƒgaÊllllllmnnnnnn™URoËÿNùóoooooo7Ð|||||||‡™BA|@Ñ;&7||||||}}}}}}}:987}6543Ñ}}}}}};~~~~~~~210/.”-,)effffffkllllll(Д'&%$™#"! ú€€€€€€€™5„………………‡†††††††˜ííííííí1 î    ÒîîîîîˆˆˆˆˆÓúÿ‰òñðï‰‰‰‰¡ùùùùùùù4íÓìúëêéæÒúúúúúúŠ‹‹‹‹‹‹™ãàߌÞÝÚÙØŒŒŒŒŒŒ¬7×™Ö ÕÔÓÒØ      ŽŽŽŽŽŽÙÑÐÏÎÍÌËÇ“””””””¦ƼÙ•»º·¶µ••••••<˜˜˜˜˜˜˜>´³²™±°¬«ª™™™™™™š››››››¦©¨§œ¦¥¤£¢œœœœœœE¤¤¤¤¤¤¤G¡ Ÿ¥ž˜Ž¥¥¥¥¥¥¦§§§§§§¦‰X;¨/-™™™¨¨¨¨¨¨P³³³³³³³R™™™´™™™™™´´´´´´µ¶¶¶¶¶¶¦™™™·™™™™™······\ÃÃÃÃÃÃÃ^™™™Ä™™™™™ÄÄÄÄÄÄÅÆÆÆÆÆÆ¦™™™Ç™™™™™ÇÇÇÇÇÇÎÎÎÎÎÎΙ™™Ï™™™™™ÏÏÏÏÏÏÐÑÑÑÑÑÑÑÒ™™™Ó™Ô™™™ÓÓÓÓÓÓnoooooorssssss™™Ô7;ááááááá™™™™â™™™™7ââââââ5âââââââ7úãããããããyzzzzzz™™7<æææææææç™™™è™@™™™èèèèèè|}}}}}}€™™@Eéééééééê™™™ë™I™™™ëëëëë뇈ˆˆˆˆˆŠ‹‹‹‹‹‹™™IPìììììììí™™™î™T™™™îîîîîîŽ*******7™T\ïïïïïïïð™ØÚñ™`7™™ññññññ™Û¥»¼¼¼¼¼¼™Ú™™™à`óôôôôôôõ™™Ûöá™™™™öööööö÷øøøøøøøù™™™ú™ûá™™úúúúúúlllllllzzzzzzzà™û<þþþþþþþç™™™ÿ™™™™™ÿÿÿÿÿÿ™™™™™™âˆˆˆˆˆˆˆã™™™™â™™E       ê™™ ™™™ã™               ™™™™™™èééééééëìììììì™Pí™™™™™™™™™™™™™™™ïðððððð      1™\!!!!!!!ð™™2"™™™™7""""""#$$$$$$$%7™7&2'™™™&&&&&&÷™™7 ™™1ø™'Ð2222222Ò™™™3™™™™333333345555554™™™6™™™™™6666667;BBBBBBB™4™™™™™™757úããããããã™37EFFFFFF™™™™G™™™™™GGGGGG<˜˜˜˜˜˜˜ç™™™™™™™™J™™™™™™HIIIIIIK™™™J™™™™™JJJJJJE¤¤¤¤¤¤¤ê™K™¥™™™™J¥¥¥¥¥¥KLLLLLL™™™™M™™™™™MMMMMMP³³³³³³³í™™™´™™™™N´´´´´´NOOOOOOO™™™P™™™™™PPPPPP\ÃÃÃÃÃÃÃð™O™Ä™™™™NÄÄÄÄÄÄQRRRRRR™™™™S™™™™™SSSSSSUVVVVVVVW™™™X™Y™™™XXXXXXR™Y÷]]]]]]]ù™™S^™™™™™^^^^^^ggggggg™™™hS™™™™hhhhhh ttttttt ™™™u™™™™™uuuuuu‚‚‚‚‚‚‚™™™ƒ™™™™™ƒƒƒƒƒƒ#%™™™‘™™™™™‘‘‘‘‘‘Й™™™™™™Ò™™™š™™™™™šššššš›œœœœœœœ™™™ž™Ÿ™™™žžžžžž      "######™™Ÿ7;èèèèèèè())))))™R7¨©©©©©©ª™™™«™™™™™««««««÷¬¬¬¬¬¬¬­™™™®™û™™™®®®®®®+,,,,,,ééééééé™™û¯¯¯¯¯¯¯°™™™±™™™™±±±±±±DEEEEEE™™ ²²²²²²²³™™™´™™™™´´´´´´       V™µµµµµµµ¶™VW·™™™™······™)))))))™™™™™WZ™#¸¸¸¸¸¸¸¹™Z[º™'™™™ºººººº™^______™™™™™[j™'U½½½½½½½W™™k¾™™™™™¾¾¾¾¾¾÷ÅÅÅÅÅÅÅ­™™™Æk™™™™ÆÆÆÆÆÆÌÌÌÌÌḬ̀™™™Í™™™™™ÍÍÍÍÍÍ ÔÔÔÔÔÔÔ³™™™Õ™™™™™ÕÕÕÕÕÕÜÜÜÜÜÜܶ™™™Ý™™™™™ÝÝÝÝÝÝ#äääääää¹™™™å™™™™™åååååå›ñññññññ™™™ò™™™™™òòòòòòUùùùùùùùú™™™û™Y™™jûûûûûûabbbbbb™lmmmmmm™Y÷]]]]]]]­™™™^™™™™™^^^^^^ggggggg°™™™h™™™™™hhhhhh ttttttt³™™™u™™™™™uuuuuu‚‚‚‚‚‚‚¶™™™ƒ™™™™™ƒƒƒƒƒƒ#¹™™™‘™™™™™‘‘‘‘‘‘Uú™™™™™™™™›5555555™™™6™™™™™666666U½½½½½½½ú™™™¾™™™™™¾¾¾¾¾¾pqqqqqqtuuuuuuxyyyyyy|}}}}}}_______€€„………………™™™™™™mmmmmmmqqqqqqquuuuuuu™™™™yyyyyyy}}}}}}}ŽŽŽŽŽŽ…………………ŽŽŽŽŽŽŽ.™™™™...@™@@@@@@@™———þþþMMMPPPQQQXXXVVV\\\`™`œœœ¡¡¡¢¢¢«««¯™¯°°°ZZ™™Z´´´¸¸¸PPPïïïóóóôôôõõõXXXúúú©©™™©ÿÿÿ™   ™@@@«««HHHIIIQQQU™UX™XYYY]]]a™a™™  ™™ gggkkk™ôôô‘‘‘”””•••–––›››OO™™O   ¤¤¤UU™UWW™™WXX™XYY[[™™[«««¯¯¯aa™a³™³¶™¶···»»»¿™¿ÚÚÚQQQ]]]åååæææîîîò™òõ™õöööúúúþ™þ™™    ™ ²™™²³³™³µµ™™µ¶¶™¶··¹¹™™¹¿¿™¿555™55•••...222555888999:::???ìì™™ìDDDHHHòò™òôô™™ôõõ™õööøø™™øOOOSSSþþ™þ™™™™™™™™[[[___  ™ a™ad™dg™ghhhlllp™p555™55‚‚‚îîîúúú   ‘‘‘™™™™ ™ ¡¡¡¥¥¥©™©¬™¬¯™¯°°°´´´¸™¸¹™¹¼™¼¿™¿ÀÀÀÄÄÄÈ™Èa™ac™™cdd™dff™™fgg™ghhjj™™jÏÏÏÓÓÓpp™p555™55999äääèèèëëëîîîñññòòòúúú——™™—ÿÿÿ™ŸŸ™™Ÿ  ™ ¡¡££™™£   ©©™©«™™«¬¬™¬®®™™®¯¯™¯°°²²™™²¸¸™¸¹™¹»™™»¼¼™¼¾¾™™¾¿¿™¿ÀÀ™™Â"""&&&ÈÈ™È(™(+™+.™.///3337™7555™55CCC™™™¥¥¥´´´ÄÄÄTTTZZZXXX___^^^`™`c™cdddiiihhhj™jm™mp™pqqqvvvuuuw™wx™x{™{~™~„„„ƒƒƒ…™…†™†‰™‰Œ™Œ’’’‘‘‘“™“(™(*™™*++™+--™™-..™.//11™™1šššžžž77™7555™55òòò®®®±±±´´´···ººº¿¿¿¾¾¾Á™ÁÂÂÂ\\™™\ÆÆÆÇÇÇ``™`bb™™bcc™cddff™™fÍÍÍÎÎÎjj™jl™™lmm™moo™™opp™pqqss™™sÕÕÕÖÖÖww™wx™xz™™z{{™{}}™™}~~™~™™ÝÝÝÞÞÞ……™…†™†ˆ™™ˆ‰‰™‰‹‹™™‹ŒŒ™Œ™™åååæææ““™“ç™çê™êí™íîîîó™óòòòô™ô555™55ü™üûûûý™ý^^^þ™þhhhÿ™ÿuuu™ƒƒƒ™‘‘‘¼¼™™¼XXXÁÁ™Á ™       ™™™™™™!™!$™$%%%&&&'™'*™*-™-...///ç™çé™™éêê™êìì™™ìíí™íîîðð™™ð6667™7ôô™ô555™55<<<¾¾¾>™>?™?@™@A™AB™BC™CF™FGGGHHHI™I  ™™   ™   L™L™™™™™™P™P™™™™™™™T™T™ ™™ !!™!##™™#$$™$%%X™X'™')™™)**™*,,™™,--™-..\™\]™]`™`c™cddde™e555™55i™i™ ™ ™™&™&/™/EE™™EFF™FGG=™=n™no™or™rs™sv™vw™wz™z{™{~™~_™™_bb™™b‚™‚H™H†™†m™™mq™™qu™™uy™™y}™™}Œ™Œ™…™™…‘™‘’™’“™“”™”•™•Ž™™Ž—™—˜™˜™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™  "  "í  'ƒ  ƒ' ' [î[RR_Rdcztdcêêtz!_€$!#$$$$!!)€!#!#g#)g#g))ò `ô“úú  ›  %`“% `o&ú9s%o&9&%&%›ë&,&&,Í,s},>>>>>>>?Í,?}?ëv?v,0000000?³w0––w?³0000001111111ûE^1    11111122222222Æ E2^˜Ÿ Æ222222444444446666666¥˜ŸI6­6666668Ip8 8Yp8Z¥88888888­Y8Zæ8I888888‘È‘‘‘‘‘‘‘þÈY‘Zæþx‘‘‘‘‘‘’’’’’’’’;;x’C’’’’’’’ùùùùùùù¨C’””””””””FL¨”S_nn””””””•••••••••fFL•¨ˆS_f••••••––––––––˜˜˜˜˜˜˜˜ˆq±˜qÀ˜˜˜˜˜˜šššššššššŸÀš±šŠŸššššššOOOOOOO!$©yêÃΚóóóóóóó©yêŠóÁ%ÃÎóóóóóóõõõõõõõrÁéõê½ÝÁrõõõõõõööööööööøøøøøøøª½Ý*øàÈÌªÉøøøøøøûûûûûûûûÈÌÌÉûÈÉà-.ûûûûûûýýýýýýýý>6>F>>>ã>SSSSSSSÏÄGãÏ`Ä  cÄnrÊvÍC CCCCCCCÊ ÍÊCÍ ÓÕÕCCCCCCDDDDDDDDzÓÕ~D†D êDDDDDD•••••••±±±±±±±N€DFFFFFFFF€æéNFðüåOFFFFFFJJJJJJJOÿ JéNðüJJJJJJKKKKKKKKCOÿK *CÞKKKKKKLLLLLLLLNNNNNNNÝN*ÖNÕNNNNNNNRRRRRRRRRÎ!RRRRRRTTTTTTTTTZÍ!Tb"$!ZTTTTTTUUUUUUUU"$nU$"&buUUUUUU[[[[[[[[[&Çu[nuzx{[[[[[[]]]]]]]]]zx{]…]xˆz]]]]]]µµµµµµµ÷÷÷÷÷÷÷Æ…]oˆ‹ÂoŽ|o}VoWooooV|W}‹ØŽ|‘‘‘‘‘‘‘|ØV‘W”›§Á‘‘‘‘‘‘’’’’’’’’”””””””ª”›§”¶ºÆÀà””””””————————¿¾ªà—º—¶ºÆ——————üüüüüüüÅZ—™™™™™™™ô·)5™Z´±Å™™™™™™šššššššÎÅôš)5®ZÎšššššš››››››››žžžžžžžžžþ[«žžžš“þžžžžžž[bbbbbbbddddddd<ž¤¤¤¤¤¤¤¤¤[’‘¤¤Œ<‰¤¤¤¤¤¤hhhhhhh˜˜˜˜˜˜˜´Ç¤ªªªªªªªªª…„´ªƒFIÇÛªªªªªª¬¬¬¬¬¬¬¬¬ÇÛ¬´¬ÛFI¬¬¬¬¬¬¡¡¡¡¡¡¡µ ¬¶¶¶¶¶¶¶¶¶~{µ¶LÞw ¸¶¶¶¶¶¶·······¸Þ v·ÞµßL8······ä¹äääääää߸8uäß¹qp;ääääääååååååååm 8;å;åj¹ ååååå妦¦¦¦¦¦¨¨¨¨¨¨¨ë%åççççççççOiëçRh?%ççççççëëëëëëëë!?O%ëë?R!dëëëëëëììììììììííííííí™Åc`íky‡™Åííííííîîîîîîîîðððððððky‡©ðè 9:=ððððððñññññññññ9:=ñ©è ìññññññòòòòòòòì=9:ò_@ ^òòòòòòöööööööö@ ìöZX¡¢£ööööööøøøøøøøøø¡¢£øW¤öøTøøøøøøùùùùùùùù¤öøùö¤S÷PùùùùùùÌ÷ø÷M;JÌÔ;(^GfÔ         Üfl p(^Ü               äC7 l 6pä      ¬¬¬¬¬¬¬²²²²²²²ó 5555555tx|5ó3h55555577777775ht7x|„ó577777788888888:::::::d„/:.¥ƒd+::::::<<<<<<<<¥ƒ&<%"¥<<<<<<========>>>>>>>  >ÿúù>>>>>>????????BBBBBBBBBÆô÷BöBõòøBBBBBBô÷ñÆîëèøäÓÐÏËÈÑÆBEEEEEEEEEô÷ÐEËEÑøÚEEEEEEÐËÇÑ×××××××ÚtEKKKKKKKKKKÚKÄtKKKKKK:tÀe¿KPPPPPPPPP:¼eP¸·´:PPPPPPRRRRRRRRR°¯¬ReR©¨¥RRRRRRfvR\\\\\\\\\¡ f\œ™vv\\\\\\^^^^^^^^^•v‘^f^Ý#^^^^^^Œ‰Ý#†ijq^iiiiiiiii#iji݃‚qpiiiiiijjjjjjjqolhjijgd_jjjjjjmmmmmmm[SOHmrswyõmmmmmm<<<<<<<rswyõm„D„„„„„„„rssw„yõÙÜA„„„„„„AAAAAAA–—ÙÜA„……………………–—ÙÜ…A?:98………………EEEEEEE52.–—…†††††††JJJJJJJLLLLLLLPPPPPPPVVVVVVV†‡‡‡‡‡‡‡  ‡ þ‡‡‡‡‡‡‰‰‰‰‰‰‰‰‹‹‹‹‹‹‹‹ýúöõ‹òñîêç‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽæåäáŽÞÛÚ¿¾ŽŽŽŽŽŽ»·¶³¯«¤žž ›–•”‘ƒ’’’’’’’’’‚ž~’}{zuŸ’’’’’’“““““““Ÿkga“`]YXU““““““————————TQŸ—MJIHG——————™™™™™™™™™DA@™9640,™™™™™™šššššššš+*)š%$"! šššššš¢¢¢¢¢¢¢¢¢¢¢¢¢¢¢¢£££££££££ ££££££­­­­­­­­­ÿú­õôóïé­­­­­­®®®®®®®®èãâ®áàßÞÝ®®®®®®ºººººººººÜÛÚºÙ×ÔÓÒºººººº¼¼¼¼¼¼¼¼¼ÑÐϼμÌËʼ¼¼¼¼¼XXXXXXX\\\\\\\¢£¼Ò­ÒÒÒÒÒÒÒÉÇ¢£ÒÅ­ÄÃÒÒÒÒÒÒÒÔÔÔÔÔÔÔÂÁÀ¿Ô¢£½¼­ÔÔÔÔÔÔÖÖÖÖÖÖÖ»¸´°Ö¯9®«§ÖÖÖÖÖÖØØØØØØØØ9¦£¢Ø¡ œ9ØØØØØØÙÙÙÙÙÙÙÙÜÜÜÜÜÜÜÜÜ“ŽÜÜŒ‹ŠÜÜÜÜÜÜccccccc«««««««®‰Üßßßßßßßß߈±®ß‡ß†²½ßßßßßß±…„ƒ²½~|{x8®¾wßâââââââââ±u¾â8â²½Áââââââ»»»»»»»Á8srq¾,nâèèèèèèèèèÂm,èkèjÁ-èèèèèèÊÊÊÊÊÊÊ-ihfÂ0,1aèííííííííí0`1í_\X-VííííííïïïïïïïïïQP0ï1ïMHGïïïïïïÌÌÌÌÌÌÌÐÐÐÐÐÐÐ[?ïùùùùùùùùù=<[ù75321ùùùùùùûûûûûûûûûÕÖ\û[û0/.ûûûûûû-\+ÕÖ÷÷÷÷÷÷÷a*ÕÖûa\)$!          ×ba  g      b×üüüüüüüge× be g  ffÿeþü÷ô'n'''''''òfñï'ìnèä'''''''(((((((âàßÝ(ÜÛÚÙn(((((())))))))Ø×ÕÓ)Ñ)ÐÎÌ))))))Ëo)+++++++ÉÆÅÄ+oÂÀ¿¼++++++,,,,,,,,»¹¸·,¶µo´³,,,,,,--------///////²±°®/­ª©¨§//////000000000¦¥¤0¢Ÿžr0000001111111rœ™—1ŽŒ‹Š111111333333333‰rˆ3†…„‚s3333334444444s€~}4|{yxw444444666666666vsu6trpo|6666667777777|nml7kjihf777777;;;;;;;;e^|;]\ZYX;;;;;;=========WVU=TSQPO======>>>>>>>>NML>KJIHG>>>>>>FFFFFFFFFFECFBA3+*FFFFFFGGGGGGGG(G GGGGGGQQQQQQQQQQQQQQQQRRRRRRRRRRRRRRR]]]]]]]]]]]]]]]]^^^^^^^^^^^^^^^kkkkkkkkkkkkkkkkmmmmmmmmmmmmmmmmm       m~~~~~~~~~~~~~~~~~€€€€€€€€€€„„„„„„„„„„„„„„„„„„‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ#######*******>Š}€>}€>UUUUUUUŠ’’’’’’’’}€’Š’’’’’’“““““““““““Š““““““lllllllzzzzzzz‹“˜˜˜˜˜˜˜˜˜‹˜˜˜˜˜˜˜šššššššššš‹šŽššššššˆˆˆˆˆˆˆŽ»š¤¤¤¤¤¤¤¤¤»¤Ž¤¤¤¤¤¤¦¦¦¦¦¦¦¦¦¦»¦¦¦¦¦¦¦•••••••———————¼¦³³³³³³³³³¼³³³³³³³µµµµµµµµµµ¼µµµµµµµ›››››››ÃÃÃÃÃÃÃëµÃÃÃÃÃÃÃÃÃëæÃÃÃÃÃÃÅÅÅÅÅÅÅÅŧ¦ÅëÅÅÅÅÅÅŦ§ÈÈÈÈÈÈÈì§ÅÑÑÑÑÑÑÑÑÑìÑïÑÑÑÑÑÑÒÒÒÒÒÒÒïÒìÒÒÒÒÒÒáááááááááïááááááááââââââââãããããããããÊÊÊÊÊÊÊðãååååååååðååååååææææææææææðææææææççççççççççççççéééééééééé ééééééêêêêêêê êêêêêêêììììììììì ìììììììííííííííííííííïïïïïïïïïïïïïïïïððððððððððððððóóóóóóóóóóóóóóóóóÐÐÐÐÐÐÐÒÒÒÒÒÒÒóøøøøøøøøøøøøøøøø                $$$$$$$$$$$$$$$$222222222222222244444444444444444ØØØØØØØÚÚÚÚÚÚÚ4BBBBBBBBBàààààààBDDDDDDDDDDDDDDDEEEEEEEEEEEEEEEEEâââââââéééééééEHHHHHHHHHHHHHHHHHHKKKKKKKKKKKKKKKKK       "KNNNNNNNNN#"NNNNNNNN#)))))))"+NQQQQQQQQQ#,+QQQQQQQQ,1111111+DQVVVVVVVVV,DVVVVVVV]]]]]]]]]]D]]]]]]ggggggggggggggggtttttttttttttttt‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚œœœœœœœœœœœœœœœœ¨¨¨¨¨¨¨¨¨¨¨E¨¨¨¨¨¨3333333EJJJJJJJ¨¬¬¬¬¬¬¬¬¬¬E¬¬¬¬¬¬¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯²²²²²²²²²²²²²²²²µµµµµµµµµµµµµµµµ¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸½½½½½½½½½½½½½½½½ññññññññññññññññùùùùùùùùùùùùùùùùNNNNNNNRRRRRRRVVVVVVVZZZZZZZ_______abjjjjjjjabmmmmmmmqqqqqqquuuuuuuabyyyyyyy}}}}}}}€€€€€€€…………………ŽŽŽŽŽŽŽšššš››››››››œœžžžŸŸŸ   ¡¡¡¢¢¢£££¤¤¤¥¥¥¦¦§§§¨¨¨©©©ªªª««¬¬¬­­­®®®¯¯¯°°°±±±²²²³³³´´´µµµ¶¶¶···¸¸¸¹¹¹ºº»»»¼¼¼½½¾¾¾¿¿¿ÀÀÀÁÁÁÂÂÂÃÃÄÄÅÅÅÆÆÆÇÇÈÈÈÉÉÉÊÊÊËËËÌÌÌÍÍÍÎÎÎÏÏÏÐÐÐÑÑÑÒÒÒÓÓÓÔÔÔÕÕÕÖÖÖ×××ØØØÙÙÙÚÚÛÛÛÜÜÜÝÝÝÞÞÞßßààáááâââããäääåååæææçççèèèéééêêëëìììíííîîïïððñññòòòóóôôõõõööö÷÷÷øøùùùúúúûûûüüüýýýýýþþþÿÿÿ                   !!!"""###$$$%%%&&&'''(())***+++,,--..///00011223344555666778899:::;;;<<<==>>>???@@@AAABBBBBCCCDDDEEEFFFGGGHHHIIIJJJKKKLLLMMMNNNOOOPPPQQRRRSSSTTTUUUVVWWWXXXYYYZZ[[[\\\]]]^^^__``aaabbbcccddeeefffggghhhiijjkklllmmmnnooooopppqqqrrrssstttuuuvvvwwwxxxyyyzz{{|||}}}~~~€€‚‚‚ƒƒƒ„„„……††‡‡ˆˆ‰‰‰ŠŠŠ‹‹‹ŒŒŽŽ‘‘‘’’’““””••–––———˜˜˜™™ššš›››œœœžžžžžŸŸŸ   ¡¡¡¢¢¢£££¤¤¤¥¥¥¦¦¦§§¨¨¨©©©ªªª«««¬¬¬­­­®®®¯¯°°°±±±²²²³³³´´µµµ¶¶¶···¸¸¹¹¹ººº»»»¼¼¼½½¾¾¿¿¿ÀÀÀÁÁÁÂÂÃÃÃÄÄÄÅÅÅÆÆÆÇÇÈÈÉÉÉÊÊÊËËËÌÌÍÍÍÎÎÎÏÏÏÐÐÐÑÑÒÒÓÓÔÔÔÕÕÖÖÖ××ØØØØØÙÙÚÚÚÛÛÜÜÜÝÝÞÞÞßßàààááâââããäääåååæææçççèèèéééêêêëëìììíííîîïïðððñññòòóóôôõõõööö÷÷øøùùúúúûûûüüýýþþÿÿÿ                  !!""##$$$%%%&&&''(())**+++,,,---..//00112223334445566778899:::;;<<<<<==>>??@@AABBCCDDDEEEFFGGHHIIJJKKLLMMNNOOPPQQRRRSSTTUUVVWWXXYYZZ[[\\]]^^__``aabbccddee™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.110.2.2 2008/02/06 10:21:47 guy Exp $ (LBL)@(#) $Header: /tcpdump/master/libpcap/nametoaddr.c,v 1.82.2.1 2008/02/06 10:21:47 guy Exp $ (LBL)@(#) $Header: /tcpdump/master/libpcap/etherent.c,v 1.23 2006/10/04 18:09:22 guy Exp $ (LBL)@(#) $Header: /tcpdump/master/libpcap/bpf_dump.c,v 1.14.4.1 2008/01/02 04:22:16 guy Exp $ (LBL)@(#) $Header: /tcpdump/master/libpcap/bpf_image.c,v 1.27.2.1 2008/01/02 04:22:16 guy Exp $ (LBL)ä€ÄÁ\ÖƒŒÁ€œ…DÀÐð†ÀZ†Ò†ʆ´†¦†ކv†Ä…H†8†,†††ô…æ…Ö…2„Š„–„…ô„…â„Ø„섾„´„Є.‡$‡‡‡‡þ†´…¨…’…ˆ…€…x…l…`…P…F…>…6…*…(„¨„…þ„âƒìƒøƒ„ „„„ž„d„<„F„P„Z„n„x„‚„€s€€€€€€€€ €t€€€ €5€o€4€€7€ € €€€p€8€€€3€€¶‚p‚†‚ƃ¢‚ü‚΂ä‚8ƒ ƒ$ƒrƒLƒ`ƒ°ƒˆƒœƒ\‚L‚8‚"‚‚úæÐWS2_32.dllPacketGetReadEvent PacketGetStatsExPacketSendPackets PacketInitPacketPacketSetDumpLimitsPacketSetDumpNamePacketSetMode PacketIsDumpEndedPacketSetMinToCopyPacketSetLoopbackBehavior PacketGetVersionPacketGetAdapterNamesPacketGetNetInfoExPacketSetReadTimeoutPacketSetBuffPacketAllocatePacketPacketSetHwFilterPacketGetNetTypePacketOpenAdapter PacketGetStatsPacketReceivePacketPacketFreePacketPacketSendPacketPacketCloseAdapterPacketSetBpfpacket.dll²sprintf®_snprintf^free‘mallocÈ_errnoÁstrncpy¿strncat»strcspnµsscanf·strchrÅstrstr@callocÉstrtoulÇstrtok¿_strdupXfprintf_iob¼strerrorWfopenLfclose«_setmode×_fdopenˆ_open_osfhandle]freadffwrite¬setbufdftellOfflushæwcslenÀstrncmplongjmpá_vsnprintf¨_setjmp34abort=atoiŽ_pctypea__mb_cur_max_isctypeBclearerrhgetcIexit§reallocªrewindMSVCRT.dll_initterm_adjust_fdivêFormatMessageAiGetLastErrorïFreeLibrary˜GetProcAddressHLoadLibraryA¹GetSystemDirectoryAÅFindCloseÓFindNextFileAÉFindFirstFileAInitializeCriticalSectionGLeaveCriticalSectionEnterCriticalSectionÞGetVersionInterlockedExchangeISleepInterlockedCompareExchangeKERNEL32.dll_isattyÞ_fileno¡putsžprintfÂstrpbrkRfgets2yÖMØŠXXh‡Ȉ(Šеð[¶` »pìP»0[ˆ@‹ “´@·P©ð"P‹@Љ`¢¥À¤à¤Ð¤À¢PŽ`Ž¥°Àe·0©ÀŽÐŽ •“ Ž€“`‹ðp`fàgp‰0Ž@Žð‰ ¯`ŠP“p›0/‘ ˆ€”°$ŽP‰1p?08?Ð’À0°ЇŒp‡@‡ ‡ÐpP‘ððŽ1`ް0@ ©âŠëŠöŠ‹ ‹‹"‹-‹A‹O‹^‹i‹v‹Š‹–‹¨‹¶‹Ћñ‹ ŒŒ#Œ3ŒBŒRŒbŒqŒ{Œ‡Œ˜Œ¬Œ½ŒËŒãŒïŒýŒ!-=Nbq†•¤®ÁÔÞñþŽ$Ž.Ž=ŽLŽ^ŽoŽ{ޅޛ޲ŽÇŽÛŽëŽ,DYk|ž«½ÌÞëü  .9GXf  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWwpcap.dllbpf_dumpbpf_filterbpf_imagebpf_validateendserventeproto_dbgetserventinstall_bpf_programpcap_activatepcap_breaklooppcap_closepcap_compilepcap_compile_nopcappcap_createpcap_createsrcstrpcap_datalinkpcap_datalink_name_to_valpcap_datalink_val_to_descriptionpcap_datalink_val_to_namepcap_dispatchpcap_dumppcap_dump_closepcap_dump_filepcap_dump_flushpcap_dump_ftellpcap_dump_openpcap_filepcap_filenopcap_findalldevspcap_findalldevs_expcap_freealldevspcap_freecodepcap_get_airpcap_handlepcap_geterrpcap_geteventpcap_getnonblockpcap_hopen_offlinepcap_injectpcap_is_swappedpcap_lib_versionpcap_list_datalinkspcap_live_dumppcap_live_dump_endedpcap_lookupdevpcap_lookupnetpcap_looppcap_major_versionpcap_minor_versionpcap_nextpcap_next_etherentpcap_next_expcap_offline_filterpcap_offline_readpcap_openpcap_open_deadpcap_open_livepcap_open_offlinepcap_parsesrcstrpcap_perrorpcap_readpcap_remoteact_acceptpcap_remoteact_cleanuppcap_remoteact_closepcap_remoteact_listpcap_sendpacketpcap_sendqueue_allocpcap_sendqueue_destroypcap_sendqueue_queuepcap_sendqueue_transmitpcap_set_buffer_sizepcap_set_datalinkpcap_set_promiscpcap_set_snaplenpcap_set_timeoutpcap_setbuffpcap_setdirectionpcap_setfilterpcap_setmintocopypcap_setmodepcap_setnonblockpcap_setsamplingpcap_setuserbufferpcap_snapshotpcap_statspcap_stats_expcap_statustostrpcap_strerrorwsockinitThe read event cannot be retrieved while reading from a filePacketGetStatsEx error: %sCannot retrieve the extended statistics from a file or a TurboCap portError opening adapter: %sCannot transmit a queue to an offline capture or to a TurboCap portError: not enough memoryError: invalid size %dImpossible to set user buffer while reading from a file or on a TurboCap portError setting kernel dump file nameError setting dump modelive dump needs a physical interface supported by the NPF driverwrong interface type. A physical interface supported by the NPF driver is neededInterface description too longInterface name too long%s '%s' %s %son remote nodeInternal error\wship6\ws2_32£(£ð5£À'freeaddrinfogetnameinfogetaddrinfo2002File%s%sError when listing files: does folder '%s' exist?%sNo interfaces found! Make sure libpcap/WinPcap is properly installed on the local machine.malloc() failed: %s%s '%s' %sNetwork adapteron local hostThe source string is too long. Cannot handle it correctly.The file name cannot be NULL.file://The host name cannot be NULL./:][aAbBcCdDeEfFgGhHjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZrpcap://The interface type is not valid.The interface name has not been specified in the source string.The file name has not been specified in the source string.%[^/]/%s%[^/:]:%[^/]/%s[%[1234567890:.]]/%s[%[1234567890:.]]:%[^/]/%stcpudpUnable to set max responsiveness.Unable to disable the capture of loopback packets.Source type not supported ,; getnameinfo(): accept(): 2003%u65535The host you want to close the active connection is not knowngetaddrinfo() %s0The string you provided is not able to keep the hostnames for all the active connectionsReceived a packet that is larger than the internal buffer size.select(): This function is able to open only remote interfacesmalloc: %spcap_startcapture_remote()%dgetsockname(): not (host %s and host %s and port %s and port %s) and not (host %s and host %s and port %s)(%s) and not (host %s and host %s and port %s and port %s) and not (host %s and host %s and port %s)getpeername(): Authentication type not recognized.The other endpoint sent a message that is not allowed here.Incompatible version number: message discarded.%s (code %d)%s%s (code %d)Unable to get the exact error message%sUnable to get the exact error messageFailed to initialize Winsock Is the server properly installed on %s? connect() failed: %slisten(): bind(): socket(): shutdown(): getaddrinfo(): multicast addresses are not valid when using TCP streamsgetaddrinfo(): socket type not supportedgetaddrinfo(): send(): Not enough space in the temporary send buffer.The other host terminated the connection.recv(): The host is not in the allowed host list. Connection refused.sock_check_hostlist(), malloc() failedNo port availableNo name availableNull address (possibly DAD Phase)ô»ä»Ø»Ì»À»´»¨»œ»»ˆ»€»|» p»h» X»8» 0»(» » »üºðºàºĺ´º¤º2”ºŒº3tº`ºcTºHºh8º0ºi$ººk ºø¹lð¹عmȹ¸¹q¬¹ ¹r”¹€¹ul¹P¹w@¹ ¹z¹¹{ð¸Ô¸À¸°¸œ¸„¸‚p¸P¸ƒ@¸ ¸„ ¸ø·…è·Ì·†¸·¤·‡Œ·l·ˆX·D·‰(··Šü¶à¶‹Ô¶ȶŒ¼¶°¶¤¶˜¶ŽŒ¶„¶t¶h¶L¶ ¶£ ¶ðµ¤àµ¼µ¦¨µ˜µ§€µlµ¨\µPµ©Dµ<µª0µ(µ«µü´®ð´д¯Ä´˜´°ˆ´t´±`´L´²<´0´³´´´ô³ä³µÜ³ȳ¶¸³¤³·˜³Œ³¸|³T³¹L³H³º0³ ³»ô²̲¼¼²¤²½˜²p²¾X²4²¿,²²Àô±¸±Á¨±„±Âp±`±ÃT±@±Ä8±$±Å±ì°Æà°ذÇȰ°°ȰX°ÉH°0°Ê°ð¯×IEEE 802.15.4 with non-ASK PHY dataDLT_IEEE802_15_4_NONASK_PHYAX.25 with KISS headerDLT_AX25_KISSBluetooth HCI UART transport layer plus pseudo-headerDLT_BLUETOOTH_HCI_H4_WITH_PHDRJuniper Secure TunnelDLT_JUNIPER_STIPMBDLT_IPMBEthernet with u10 Networks pseudo-headerDLT_RAIF1Endace ERF headerDLT_ERFSITA pseudo-headerDLT_SITAIEEE 802.15.4DLT_IEEE802_15_4Juniper Integrated Service ModuleDLT_JUNIPER_ISMIEEE 802.16 MAC Common Part Sublayer plus radiotap headerDLT_IEEE802_16_MAC_CPS_RADIOPer-Packet InformationDLT_PPIIEEE 802.15.4 with Linux paddingDLT_IEEE802_15_4_LINUXController Area Network (CAN) v. 2.0BDLT_CAN20BUSB with Linux headerDLT_USB_LINUXIEEE 802.16 MAC Common Part SublayerDLT_IEEE802_16_MAC_CPSBluetooth HCI UART transport layerDLT_BLUETOOTH_HCI_H4USBDLT_USBArinc 653 Interpartition CommunicationDLT_A653_ICMArinc 429DLT_A429Juniper Voice PICDLT_JUNIPER_VPFRF.16 Frame RelayDLT_MFRJuniper C-HDLCDLT_JUNIPER_CHDLCJuniper Frame RelayDLT_JUNIPER_FRELAYJuniper PPPDLT_JUNIPER_PPPJuniper EthernetDLT_JUNIPER_ETHERLinux vISDN LAPDDLT_LINUX_LAPDPacket-over-SONET with Endace ERF headerDLT_ERF_POSEthernet with Endace ERF headerDLT_ERF_ETHJuniper PIC PeerDLT_JUNIPER_PIC_PEERGPF-FDLT_GPF_FGPF-TDLT_GPF_TGPRS LLCDLT_GPRS_LLCJuniper PPPoE/ATMDLT_JUNIPER_PPPOE_ATMJuniper PPPoEDLT_JUNIPER_PPPOEPPP for pppd, with direction flagDLT_PPP_PPPDJuniper Passive Monitor PICDLT_JUNIPER_MONITOR802.11 plus AVS radio information headerDLT_IEEE802_11_RADIO_AVSLinux IrDADLT_LINUX_IRDADOCSISDLT_DOCSISSS7 SCCPDLT_SCCPSS7 MTP3DLT_MTP3SS7 MTP2DLT_MTP2SS7 MTP2 with Pseudo-headerDLT_MTP2_WITH_PHDRApple IP-over-IEEE 1394DLT_APPLE_IP_OVER_IEEE1394Juniper ATM1 PICDLT_JUNIPER_ATM1Juniper Advanced Services PICDLT_JUNIPER_SERVICESJuniper ATM2 PICDLT_JUNIPER_ATM2Juniper FRF.16 Frame RelayDLT_JUNIPER_MFRJuniper GGSN PICDLT_JUNIPER_GGSNJuniper Encryption Services PICDLT_JUNIPER_ESJuniper Multi-Link Frame RelayDLT_JUNIPER_MLFRJuniper Multi-Link PPPDLT_JUNIPER_MLPPPLinux ARCNETDLT_ARCNET_LINUX802.11 plus radiotap headerDLT_IEEE802_11_RADIOSun raw ATMDLT_SUNATMRFC 2625 IP-over-Fibre ChannelDLT_IP_OVER_FC802.11 plus Prism headerDLT_PRISM_HEADEROpenBSD pflog fileDLT_PFLOGLocaltalkDLT_LTALKLinux cookedDLT_LINUX_SLLOpenBSD encapsulated IPDLT_ENCOpenBSD loopbackDLT_LOOPFrame RelayDLT_FRELAY802.11DLT_IEEE802_11Cisco HDLCDLT_C_HDLCSymantec FirewallDLT_SYMANTEC_FIREWALLPPPoEDLT_PPP_ETHERPPP over serialDLT_PPP_SERIALLinux Classical IP-over-ATMDLT_ATM_CLIPBSD/OS PPPDLT_PPP_BSDOSBSD/OS SLIPDLT_SLIP_BSDOSRaw IPDLT_RAWRFC 1483 LLC-encapsulated ATMDLT_ATM_RFC1483FDDIDLT_FDDIPPPDLT_PPPSLIPDLT_SLIPBSD ARCNETDLT_ARCNETToken ringDLT_IEEE802EthernetDLT_EN10MBBSD loopbackDLT_NULLcan't perform operation on activated capture%s: %sDLT %d is not one of the DLTs supported by this device%s is not one of the DLTs supported by this device%s: %s (%lu)Unknown error: %dThat device is not upYou don't have permission to capture on that deviceThat operation is supported only in monitor modeThat device doesn't support monitor modeNo such device existsThe setting can't be changed after the pcap_t is activatedThe pcap_t has not been activatedLoop terminated by pcap_breakloopGeneric errorThat device doesn't support promiscuous modeGeneric warningSetting direction is not implemented on this platformStatistics aren't available from a pcap_open_dead pcap_tThe kernel buffer size cannot be set on a pcap_open_dead pcap_timpossible to set mode on a pcap_open_dead pcap_tThe mintocopy parameter cannot be set on a pcap_open_dead pcap_t cc d efghhj2233iikkllqqrrssuuvvwwxxyyzz{{||}}~~€€‚‚ƒƒ„„……††‡‡ˆˆ‰‰ŠŠ‹‹ŒŒŽŽ‘‘’’££¤¤¥¥¦¦§§¨¨©©ªª««¬¬­­®®¯¯°°±±²²³³´´µµ¶¶··¸¸¹¹ºº»»¼¼½½¾¾¿¿ÀÀÁÁÂÂÃÃÄÄÅÅÆÆÇÇÈÈÉÉÊÊËËÌÌÍÍÎÎÏÏÑÑÒÒÓÓÔÔÕÕÖÖ××ÿÿÿÿÿÿÿÿrbarchaic file formatbad dump file formattruncated dump file; tried to read %lu file header bytes, only got %luerror reading dump file: %sout of swapStatistics aren't available from savefilesThe kernel buffer size cannot be set while reading from a fileimpossible to set mode while reading from a fileThe mintocopy parameter cannot be set while reading from a fileSending packets isn't supported on savefilesSetting direction is not supported on savefilestruncated dump file; tried to read %u captured bytes, only got %luBUFMOD hack mallocbogus savefile headertruncated dump file; tried to read %lu header bytes, only got %luwbstandard output%s: link-layer type %d isn't supported in savefilesCan't write to %s: %sCannot allocate enough memory to list the adapters.PacketGetAdapterNames: %s%wsMalloc failedError calling PacketSetMinToCopy: %sdriver error: not enough memory to allocate the kernel bufferfailed to allocate the PACKET structurefailed to set hardware filter to non-promiscuous modefailed to set hardware filter to promiscuous modeCannot determine the network type: %sPacketGetStats error: %sdriver error: working mode not recognizeddriver error: unable to set the requested mintocopy sizeread error: PacketReceivePacket failedsend error: PacketSendPacket failedsend error: PacketAllocatePacket failedDriver error: cannot set bpf filter: %sPacketSetReadTimeout: %sÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿout of memoryexpression rejects all packetssyntax error in filter expressionsnaplen of 0 rejects all packetspcap_compile cannot generate filters for a TurboCap port when the PPI linktype is used.unknown data link type %d'radio' is not a valid protocol typelink layer applied in wrong contextAX.25 link-layer type filtering not implementedIPMB link-layer type filtering not implementedRAIF1 link-layer type filtering not implementedSITA link-layer type filtering not implementedIEEE 802.16 link-layer type filtering not implementedIEEE 802.15.4 link-layer type filtering not implementedCAN20B link-layer type filtering not implementedBluetooth link-layer type filtering not implementedUSB link-layer type filtering not implementedLAPD link-layer type filtering not implementedERF link-layer type filtering not implementedMTP2 link-layer type filtering not implementedDOCSIS link-layer type filtering not implementedIrDA link-layer type filtering not implementedMulti-link Frame Relay link-layer type filtering not implementedunsupported protocol over mpls'radio proto' is bogus'netbeui proto' is bogus'ipx proto' is bogus'stp proto' is bogus'ah proto' is bogus'icmp6 proto' is bogus'vrrp proto' is bogus'pim proto' is bogus'igrp proto' is bogus'igmp proto' is bogus'icmp proto' is bogus'sctp proto' is bogus'tcp proto' is bogus'udp proto' is bogusmopdl does not encapsulate another protocolmoprc does not encapsulate another protocollat does not encapsulate another protocolsca does not encapsulate another protocoldecnet encapsulation is not specifiableatalk encapsulation is not specifiablerarp does not encapsulate another protocolarp does not encapsulate another protocoldirection applied to 'proto'unknown protocol: %s'gateway' not supported in this configurationport in range '%s' is udpport in range '%s' is sctpport in range '%s' is tcpunknown port in range '%s'illegal qualifier of 'portrange'port '%s' is udpport '%s' is sctpport '%s' is tcpunknown port '%s'illegal qualifier of 'port'unknown host '%s'%s for specified address familyunknown host '%s'only ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel supports link-level host nameunknown Fibre Channel host '%s'unknown 802.11 host '%s'unknown token ring host '%s'unknown FDDI host '%s'unknown ether host '%s'unknown network '%s''radio' modifier applied to %s'netbeui' modifier applied to %sIPX host filtering not implemented'stp' modifier applied to %s'clnp' modifier applied to %s'isis' modifier applied to %s'esis' modifier applied to %sISO host filtering not implemented'esp' modifier applied to %s'ah' modifier applied to %s'icmp6' modifier applied to %s'ip6' modifier applied to ip hostMOPRC host filtering not implementedMOPDL host filtering not implementedLAT host filtering not implementedSCA host filtering not implementedAARP host filtering not implementedATALK host filtering not implemented'vrrp' modifier applied to %s'pim' modifier applied to %s'igrp' modifier applied to %s'igmp' modifier applied to %s'icmp' modifier applied to %s'udp' modifier applied to %s'sctp' modifier applied to %s'tcp' modifier applied to %shostnet'decnet' modifier applied to ip6 %s'arp' modifier applied to ip6 %s'rarp' modifier applied to ip6 %s'ip' modifier applied to ip6 %sunknown osi proto '%s'clnpisisesisunknown ether proto '%s'unknown ip proto '%s'unsupported proto to gen_protochain'protochain' not supported with 802.11bad protocol applied for 'protochain'Mask syntax for networks onlynon-network bits set in "%s/%d"mask length must be <= 32non-network bits set in "%s mask %s"'gateway' requires a nameillegal link layer addressinvalid qualifier against IPv6 addressmask length must be <= %u%s resolved to multiple addressinvalid ip6 address %sno mask %s supportedethernet address used in non-ether expressionethernet addresses supported only on ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channelradio information not present in captureunsupported index operationIPv6 upper-layer protocol is not supported by proto[x]data size must be 1, 2, or 4too many registers needed to evaluate expressiononly link-layer/IP broadcast filters supportednot a broadcast linklink-layer multicast filters supported only on ethernet/FDDI/token ring/ARCNET/802.11/ATM LANE/Fibre Channelinbound/outbound not supported on linktype %dlibpcap was compiled without pf supportlibpcap was compiled on a machine without pf support802.11 link-layer types supported only on 802.11frame direction supported only with 802.11 headersARCnet address used in non-arc expressionaid supported only on ARCnetno VLAN support for data link type %dno VLAN match after MPLSno MPLS support for data link type %d'callref' supported only on raw ATM'vci' supported only on raw ATM'vpi' supported only on raw ATM'llc' supported only on raw ATM'lane' supported only on raw ATM'ilmic' supported only on raw ATM'sc' supported only on raw ATM'oam4ec' supported only on raw ATM'oam4sc' supported only on raw ATM'bcc' supported only on raw ATM'metac' supported only on raw ATM'fisu' supported only on MTP2'lssu' supported only on MTP2'msu' supported only on MTP2sls value %u too big; max value = 15'sls' supported only on SS7dpc value %u too big; max value = 16383'dpc' supported only on SS7opc value %u too big; max value = 16383'opc' supported only on SS7sio value %u too big; max value = 255'sio' supported only on SS7'metaconnect' supported only on raw ATM'connectmsg' supported only on raw ATM'oamf4' supported only on raw ATM'oam' supported only on raw ATMdivision by zeromallocno destination foundmultiple matches%s for block-local relative jump: off=%dno jmp destinationnot enough coreBPF program is not validany%Smemory allocation failureTcStatisticsQueryValueTcStatisticsUpdateTcStatisticsDestroyTcPacketsBufferCommitNextPacketTcPacketsBufferQueryNextPacketTcPacketsBufferDestroyTcPacketsBufferCreateTcInstanceQueryStatisticsTcInstanceTransmitPacketsTcInstanceGetReceiveWaitHandleTcInstanceReceivePacketsTcInstanceQueryFeatureTcInstanceSetFeatureTcInstanceCloseTcInstanceOpenByNameTcPortGetDescriptionTcPortGetNameTcStatusGetStringTcFreePortListTcQueryPortListTcApi.dllError setting the read timeout a TurboCap instance: %sError enabling reception on a TurboCap instance: %sError opening TurboCap adapter: %sError allocating memoryGetting the non blocking status is not available for TurboCap portsSetting the non blocking status is not available for TurboCap portssend error: TcPacketsBufferCommitNextPacket failure: %s (%08x)send error: TcInstanceTransmitPackets failure: %s (%08x)send error: TcPacketsBufferCreate failure: %s (%08x)send error: the TurboCap API does not support packets larger than 64kread error, TcPacketsBufferQueryNextPacket failure: %s (%08x)read error, TcInstanceReceivePackets failure: %s (%08x)TurboCap error setting the mintocopy: %s (%08x)Mintocopy cannot be less than 0.Mode %u not supported by TurboCap devices. TurboCap only supports capture.TurboCap error in TcStatisticsQueryValue: %s (%08x)TurboCap error in TcInstanceQueryStatistics: %s (%08x)setfilter, unable to install the filter: %ssetfilter: No filter specifiedÿÿÿÿqos-cf-ack-pollqos-cf-pollqosqos-data-cf-ack-pollqos-data-cf-pollqos-data-cf-ackqos-datacf-ack-pollcf-pollcf-acknulldata-cf-ack-polldata-cf-polldata-cf-ackcf-end-ackcf-endackctsrtsps-polldeauthenticationdeauthauthenticationauthdisassociationdisassocatimbeaconprobe-respproberespprobe-reqprobereqreassoc-respreassocrespreassoc-reqreassocreqassoc-respassocrespassoc-reqassocreqcontrolctlmanagementmgtdataCleanup: poppingCleanup: discarding lookaheadmemory exhaustedunknown 802.11 directiondstodsfromdstodsnodsunknown 802.11 subtype nameunknown 802.11 typeunknown 802.11 type name'protochain' modifier applied to ip host'proto' modifier applied to ip host'portrange' modifier applied to ip host'port' modifier applied to ip hostError: poppingError: discardingsyntax errorfatal flex scanner internal error--no action foundillegal char '%c'illegal token: %sbogus ethernet address %sbogus IPv6 address %sout of dynamic memory in yy_get_next_buffer()input in flex scanner failedfatal error - scanner input buffer overflowfatal flex scanner internal error--end of buffer missedout of dynamic memory in pcap__create_buffer()out of dynamic memory in pcap_ensure_buffer_stack()out of dynamic memory in pcap__scan_buffer()bad buffer in pcap__scan_bytes()out of dynamic memory in pcap__scan_bytes()%s àíÜíØíÔí݆ÐíÈí5€Àí¸í`°í`¨í`¤í` í`”í8€Œí[€„í\€|훀píó€dí\í>€Tí<€PíþLíBHíà@íðnetbeuiipxstpisodecdnsdecdtsloopbackatalkarpatalkvprodvexplanbridgescalatdecnetmoprcmopdlspriterarparpip6ipxnspup%d-%dmalformed decnet address '%s'%d.%d/etc/ethersrdecnet name support not included, '%s' cannot be translated { 0x%x, %d, %d, 0x%08x }, %u %u %u %u %d (%03d) %-8s %s(%03d) %-8s %-16s jt %d jf %d0x%xunimptxataxnegrshlshoranddivmulsubaddxjsetjeqjgejgtjastxstM[%d]4*([%d]&0xf)ldxbldx#0x%x[x + %d]#pktlenldbldh[%d]ld#%dret/etc/services,/ # €0€H``<<4VS_VERSION_INFO½ïþÙÙœStringFileInfox000004b0PCompanyNameCACE Technologies, Inc.ÂMFileDescriptionwpcap.dll Dynamic Link Library - based on libpcap 1.0rel0b branch (20091008)6 FileVersion4.1.0.17534 InternalNamewpcap.dllä`LegalCopyrightCopyright © 2005-2009 CACE Technologies. Copyright © 1999-2005 NetGroup, Politecnico di Torino.(LegalTrademarks< OriginalFilenamewpcap.dll0ProductNameWinPcap: ProductVersion4.1.0.1753,Build DescriptionDVarFileInfo$Translation°è00c0j0Ž0 0Ã0î01Ã1Ê1ý12A2M2m2ƒ2Š2š2¨2µ2Ì2ü23<3I33ˆ3ë3÷3“4Á4Ø455"5'5>5D5I5e5|5¨5È5Ö5õ5ÿ5 6’6Ÿ6ß6õ67-78888g8„8—8¬8Ë8à8ÿ8949A:…:š:¢:¬:´:¼:Ä:Ì:Ó:ë:&;J;a;h;w;ª;ß;æ;ñ;ù;<<3<=ß>S?a?f?y?”?²?À? ´090K01s1¸1Â1Î1Ù1ã1ï1ú122+272D2331383V3]3}3‚3˜3¦3Ä3Ý3 44.454U4\4y4Š4–455F5_5y5–5T6n6›6¹6ç67D7g7œ7¨7Ï7&9?9y9Ž9¸9(:S:v:Ä:í:K;Ë;Ü;M<>@>D>H>q>´>Ü>\?h?Ì?0(—0´0À0Ä1ã1222&272\2i2q2{2ƒ2‹2“2›2´2õ2333:3I3‚3º3Á3Ì3Ô3é3õ34 4)4.4V4e4¡45N5d5l5v5„55ô5û5»6Ã6Ú6é6ð6i7ƒ7š7Ð7;8N8o8…8‘8¡8´8À8Å8Ñ8'989@9J9R9Z9b9j9ƒ9¾9â9ô9ÿ9:D:}:: ;;';/;9;A;I;Q;Y;r;­;Ñ;è;ï;þ;1]>o>z>ˆ>»>ð>þ>?#?g>t>|>†>Ž>–>ž>¦>¿>ú>(?4?9?K?S?†?´?¿?Í?Õ?ò?P  000$0·011;1H1P1Z1b1j1r1z11™1Ú1þ122.2g2Ÿ2¦2±2¹2Î2Ú2ó2ý2 3373L3»344 4*424:4B4J4Q4i44°4è4ï4þ475o5v55‰5•5¬5Å5Ï5Ý5è56616F6N6X6`6h6p6x66—6¾6Þ677,7e77¤7¯7·7Ã7Ú7ó7ý788;8J8ú849;9H9“9t:‰:›:;(;/;¢;·;¿;É;Ñ;Ù;á;é;<)6>L>r>¨>»>É>Û>ê>f?`´…0•0ß0ø0Y2!373R3f3“3²3È3ã3ô3ü34444&4?4€4±4¼4Ã4Ò4 5<5G5N5Y5a5v5†5Ÿ5±5º5¿5ì5 6!6>6H6]6e6o6w66‡66¨6é67&7+7=7E7~7¯7º7È7Ð7ñ7 88%8*8R8g8„8¨8ü89F9R9ž9„:.;ª<¶<œ=e>?~??ö?p800%0¿0Ë0Ü0181N1Z1i1{1‡1Œ1˜1®1í1þ1222 2(20272`2›2¿2Õ2Ü2ê23R3`3h3…3ž3¨3®3¸3Ú3û3+434P4X44˜4»4Ã4á4û45 5/5?5E5a5g5o55Ï5ï5"6;6j6ˆ6Æ677M7f7š7­7¼7È7Ñ7æ7î7ø78888898]8z8ª8µ8Ã8ö8+999A9^9w99ˆ9’9½9Ú9::]:e:˜:Ñ:;;„;­;Á;â;ê;à<=4=s=’=¡=­=Ì=ß=ë=ð=ø=9>J>R>\>d>l>t>|>ƒ>›>¿>Ü>??)?1?d?™?§?¯?Ì?å?ï?ü?€ 0 0?0L0T0^0f0n0v0~0—0Ò0ö0 11#1V1‹1’11ª1À1Õ1á1ú122252=2P2363=3R3`3h3r3z3‚3Š3’3™3±3ì34'4.4=4p4¥4¬4·4¿4Ô4à4ù4555N5k5~55«5ø566%6C6W6i6u6|6ˆ6•6á67-7¡8­8Ò8:Ì:ñ:s;†;”;¦;Ã;Ö;¡<©<»<æ<ï<= ==*=A=S=‰=‘=¡=À=Ñ=á=>š>©>°>?"?2?7?L?R?Y?_?d?l?t?|?Ÿ?¤?ª?°?¶?¼?Â?È?Î?Ô?Ú?à?ç?î?ô?ü?(00 00000 0$0(0,000G00‘081—1Å1Ï1Ù1ã1í12252F2e2v2•2¦2(33™3Ñ3â3÷3ü344 444,4M4R4X4]4c4i4n4”4£4À4É4Ö4Ý4ì4ÿ4 5)565O5Z5a5n5‡5­5Ä5Ë5ý56#6/696Q6]6g6Â6Î6Ø6!7-777Í7å7ì7ý7z8„8Ž8˜8¨8²8¼8Æ8Ð8Ú8ä899,9%:6:U:f:…:–:µ:Æ:ë:ø:;&;B;U;g;å;÷; <^>f>x>>†>>˜>¡>¦>¸>Ë>Ù>ó>?? ø22+242F2k2á2ó23343;3H3W3i33’3®3Á3Ý3è34#454;4L4©4×4ç4535G5S5r5„55½5É5Ð5€6–7§7¹7Å78*8X8j8˜8ª8¶8½89929k9u9‡9“9¢9ª9¾9õ9:¥:¬:Í:;W;c;;œ;Ð;ß;B<š<¦<È<Ô<÷<=F=R=g=z=ˆ=”=Í=û=>>>$>.>8>B>L>V>h>l>p>t>x>|>€>„>ˆ>Œ>>”>˜>œ>À>Ò>?&?Z?l?š?¬?°00r0„0¡0³0Ü0û0 1Ã1Ô1 22 2²23"3a3„3Ž3”3Ã3ë3õ3ü3 44.4=4f4’4˜4À4Æ455D5h5z55•5š5Ÿ5«5×5ä5í5ÿ5646=6J6T6b6o6x6‚6›6¥6ä6ê6ó67¥7æ78]9c9i9o9u9{99‡99“9™9Ÿ9¥9«9±9·9½9Ã9É9Ï9Õ9Û9é9ð9ö9: :::":,:2:::D:N:T:`:f:p:v:~:„:Ž:”:œ:¢:¬:²:º:À:Ê:Ð:Ø:â:ì:ò:ú:;;;;&;0;6;C;L;Q;W;h;q;v;|;ˆ;’;˜;¢;¬;¸;¾;Ä;Î;ß;è;í;ø;þ;< <<<%<1<6<<>>>*>4>=>B>H>R>X>^>d>l>r>x>~>„>> >¤>¨>¬>°>´>¸>¼>À>Ä>È>Ì>Ð>Ô>Ø>Ü>à>ä>è>ì>ð>ô>ø>ü>??? ????? ?$?(?,?0?4?ÀÈ0#0*0V0j0q0œ0 0¤0¨0¬0ü01a1p1:2r2Ÿ2Ò2f3¢364r4Š4£4í4’5Ê5Ù5Ð6!7b7Ã7ì8§>½>Ï>ì>E?z?±?Æ?í?Ðì00K0f0A1i1v1ƒ111ª1·1Ä1Ñ1Þ1ë1ø1222*2@2D2H2L2P2T2X2\2`2d2h2l2p2t2x2|2€2„2ˆ2Œ22”2˜2œ2 2¤2¨2¬2°2´2‘4ä4545:5_5w5|5€5„5ˆ5Œ55”5è5H66ÿ67×7þ7"8y8–8¦8½89À9Ù9õ9:f:y:‡:ž:Ý:;;;4;8;<;@;D;¢;¯;Â;Ò;ß;ò;<<"<2!>,>5>>>T>[>i>–>Â>Þ>ø>#?:?b?w?à?ð40-0G0r0‰0±0Æ0&1\1’1Ÿ1­1´1¸1¼1À1Ä1È1Ì1Ð1Ô1Ø1Ü1à1ä1è1ì1Â2Ì2é2N3T3X3\3`3d3‚344 444424²4¸4¼4À4Ä4È4ä4•9œ9 9¤9¨9¬9°9´9¸9¼9Ò9R:X:\:`:d:h:y:€:”:µ:8;F;T;b;p;~;Œ;š;§;´;Õ;â;ï;ü; <<%<3<@T>X>\>`>d>‡>Ž>»>(c0q0x0|0€0„0ˆ0Œ0½0Ä0Ô0á0ï0ý0 11'151C1Q1_1m1z1‡1•1¢1¯1¼1É1ù122"202>2L2Z2g2u2ƒ2‘2˜2œ2 2¤2¨2¬2°2´2¸2¼2À2Ä2È2Ì2Ð2Ô2Ø2Ü2à2ä2è2ì2ð2ô2ø2ü2333 33333 3$3(3,3034383T3h3·4¼4À4Ä4È4Ì4ù45‚5ˆ5Œ55I6P6Ò6Ø6Ü6à6™7 74888<8@8ù89”9˜9œ9 9D:K:i:©:À:;F;Š;¬;°;´;¸; <-<=ƒ>ò>ø>°C0I0¿0Å02 2Ü2ì23A3ð34#4ü415?5l5À5Ä5È5Ì5Ð5ð5616X6ô6747r7‚7Š7”7œ7¤7¬7´7Í78,8>8I8W8Š8¿8Í8Õ8ò8 999$9Z9n9u9Ý9>:K:\:`:d:h:l:p:t:ž;Ã;Ê;7<´<ºD>H>L>P>T> i1q111¦1«1»1Â1×1e2l2 3333 3$3(3é3(4<4C4J4\4n4€4’4¤4´4×4ò4ÿ45555 5$5(5,56 66&6-646«7Ñ7G8X8\8`8d8|8€8„8ˆ8Œ88”8¢9¸9¿9x:ˆ:Œ::”:˜:a;q;;‘;˜;¶;È;Ì;:>K>Q>b>g>o>>¢>Û>ú>???? ?L?U?[?a?j?u??…?£?¨?±?¾?Ñ?Ú?ç?ò?0P0!0E0P0w0€00˜0½0Ä0È0Ì0Ð0Ô0õ0ú01*131Z1c1Š1“1·1À1ä1í1'202K2V2c2l2x2€2†2‘2š2º2Ç2Ì2Ð2Ô2Ø2Ü2à2ä2è2ì2ð23353M3g3u33´3Î3á344 4:4O4i4q4‹4¸4Û4ã4ý4"5>5F5]5r5’5˜5œ5 5¤5Æ5Í5Ò5Û5÷56N6W6Î6×6>7D7H7L7P7T7Ÿ7 88888 8$8í892999C9O9a9®9º9Ñ9Ù9â9ï9:K:n:²:¹:Á:Û:é:ü:];‹;²;º;À;ë;<@<•<Ã<ê=><>“>˜>œ> >¤>¨>¬>°>´>Ø>??? ?????D?r?¶?ò?÷?@¸000,01—1µ1¿1Ó1ä1ñ1ü122œ2Á2q3°3Í3ç34+4_4†4­4´4æ455 5555‰55Á5Ù5ô5~6’6>7·7ö7899&9…9—9¤9:::: :$:(:,:0:4:8:<:@:D:H:L:;>;E;];–;¢;¨;¬;°;´;¸;¼;À;Ä;È;Ì;É<8=}==º=ö=PT00e1u1’1ž1°1Ç122'2;2O2[2d2s2|2½2Ê2è2ó23B3N3a3‰344!4*424;4D4U4]4m4|4…4“4›4¥4¯4¹4Ã4Ì4Ú4ç4ð4þ4555.565?5I5X5`5p5}5‡5—5¤5­5¹5Å5Î5Ý5ê5ð56686@6H6P6]6i6ª6ê6ú67 7:7B7[7i7Ž7”7›7¡7´7Ú7<88š8¯8Æ8Ö8\9a9Ÿ9¤9Þ9ã9/:4:l:Q;c;‘;¤;²;Ä;1<8”>˜>œ> >¤>¨>¬>°>´>¸>¼>À>Ä>È>Ì>Ð>Ô>Ø>Ü>à>ä>è>ì>ð>ô>ø>ü>??? ????? ?$?(?,?0?4?8?.>@>†>”>š>¬>Ä>û> ???3?M?[?a?s??™?­?·?Á?Ë?Õ?ß?é?ó?pÐ0 0"0G0L0b00§0¿0õ01)181E1V1Ž1ª1»1Ê1Ú1ç1ø12Y2h2q2 2I4f4o44­4¾4×4æ4õ455/5T5c5l55Ÿ5¨5º5ú5 66$6˜6Ÿ6¿6Í6ß6>7D7]8b8}8Ž8Ÿ8Æ8Ö8û8;9l9u9Œ9›9¨9À9Ú9ß9æ9ð9 ::#:7:R:]:t:z:ˆ:ª:À:Ñ:Ú:t;;Š;•;_=…=—=ª=Â=Ú=í=€¸~0—0©0¹0Ì0Ý0ù0 11Q1m1y1”1²1Ð1ì1è4q55’5œ5ª5Ó5Ý5ý56%6O6U6Œ66”6˜6œ6 6¤6¨6¬6°6´6¸6¼6À6Ä6È6Ì6Ð6Ô6Ø6Ü6à6ä6è6ì6ð6ô6ø6ü6777 77777 7$7(7,7074787<7@7D7H7L7P7T7X7\7`7d7h7l7p7t7x7|7€7„7ˆ7Œ77”7˜7œ7 7¤7¨7¬7°7´7¸7¼7À7Ä7È7Ì7Ð7Ô7Ø7Ü7à7ä7è7ì7ð7ô7ø7ü7888 88888 8$8(8,8084888<8@8D8H8L8P8T8X8\8`8d8h8l8p8t8x8|8€8„8ˆ8Œ88”8˜8œ8 8¤8¨8¬8°8´8¸8¼8À8Ä8È8Ì8Ð8Ô8Ø8Ü8à8ä8è8ì8ð8ô8ø8ü8999 99999 9$9(9,9094989<9@9D9H9L9P9T9X9\9`9d9h9l9p9t9x9|9€9„9ˆ9Œ99”9˜9œ9 9¤9¨9¬9:::!:B:W:\:e:j:q:x:~:Š::™:ª:»:Á:Ö:Û:å:ð:þ:; ;;);4;C;\;f;r;ƒ;‹;›;¥;«;³;»;Ã;Ë;Ô;Ú;ì;ñ;û;<<<&<,<<>>U>\>k>ž>Ó>Ú>å>í>??'?2?;?@?X?e?k?~?‘?¨?»?À?Ë?Ø?æ?ù? ”6²6Ð6î677+7E7_7y7“7­7Ç7á7û78/8I8c8}8—8±8Ë8å8ÿ89@9D9H9L9P9T9X9\9`9d9h9l9p9t9x9|9€9„9ˆ9Œ99”9˜9œ9 9¤9¨9¬9°9´9¸9¼9À9Ä9È9Ì9Ð9Ô9Ø9Ü9à9ä9è9ì9ð9ô9ø9ü9::: ::::: :$:(:,:0:4:8:<:@:D:H:L:P:T:X:\:`:d:h:l:p:t:x:|:€:„:ˆ:Œ::”:˜:œ: :¤:¨:¬:°:´:¸:¼:À:Ä:È:Ì:Ð:Ô:Ø:Ü:à:ä:è:ì:ð:ô:ø:ü:;;; ;;;;; ;$;(;,;0;4;8;<;@;D;H;L;P;T;X;\;`;d;h;l;p;t;x;|;€;„;ˆ;’;š; ;¯;¸;Á;Ì;Ò;×;Ý;<<<-<—<¨<®<µ<È<ó<ù<==0=5=J=O=^=i=w=~=‰=—==¢=©=¿=É=ä=ë=ð=ö=ü=>>#>.><>Q>\>a>k>q>…>‹>‘>´>º>È>Î>Ý>ê>ð>ö>ý> ???*?/?@?R?Y?`?}?’?š? ?«?½?È?Ö?ð?ú? L00@0I0N0T0[0c0t0ˆ0¢0¬0À0Ð0ñ0û0 11#1.181f1l11•11¢1«1³1¹1Á1É1Ï1Ý1ñ1÷1222 2(2B2i2›2¡2å233š3¤3Á3Õ3Þ3è3÷34 4484?4J4T4f4 4*5i5–5Ÿ5¦5±5Ç5Ü5÷56!6466™6¯6Å6Ú6*7G7O7Y7a7i7q7y7€7š7Õ7ù7 88$8W8Œ8š8¢8¿8Ø8â8é8ó89H9O9g9u9‡9: ::6:F:r:š:÷:;;;Š;Q>>>>(>0>>>I>N>Ÿ>»>æ>.?5?A?K?c?‚?š?Î?ã?ù?°ð000K0^0€0–0«0â0 1!1H1a1¦1¹1À1Ø122"2(2.242:2@2F2L2R2X2^2d2j2p2v2|2‚2ˆ2Ž2”2š2 2¦2¬2²2¸2¾2 333"3/373E3J3O3T3_3l3v3‹3—33¿3Ñ3-4Â4º5Â5È5ç5í5636N6j6¸6¿6Ä6É6Ó6Ø6â6ç6ñ6ö677777#7-727<7A7K7P7Z7_7i7n7x7}7‡7Œ7–7›7¥7ª7´7¹7Ç7Ì7Ö7Û7å7ê7ô7ù78888!8&80858?8D8N8S8]8b8l8q8{8€8Š88™8ž8¨8­8·8¼8Æ8Ë8Ò8×8Þ8ã8ê8ï8ö8û8999999&9+92979>9C9K9n9u9›9¥9´9¸9¼9À9Ä9È9Ì9Ð9Ô9Ø9Ü9à9ä9è9ì9ð9ô9ø9ü9::: ::::: :$:(:,:0:4:8:<:@:D:H:L:P:T:X:\:`:d:!;,;5;?;Q;^;c;i;q;€;‹;œ;¦;µ;¿;Þ;ï;ú;>>>> >(>,>4>8>@>D>L>P>X>\>d>h>p>t>|>€>ˆ>Œ>”>˜> >¤>¬>°>¸>¼>Ä>È>Ð>Ô>Ü>à>è>ì>ô>ø>?? ????$?(?0?4?°ë:°ë6°ë2°ë.°ë*°ë&° ë"° ë° ë° ë° ë°ë°ë °ë°ë ÿ‹å]Ã×2sÛ2sß2sã2sç2së2sï2só2s÷2sû2sÿ2s2s2s 2s2s2s ÌÌÌÌÌÌÌÌÌÌÌÌU‹ìì¸SVWÆ…Lÿÿÿ¹3À}°ó«f«¹3À½Tÿÿÿó«f«‹E3ÉŠ…Éu"‹U3ÀŠB…Àu‹M‹U Šˆ‹M‹U ŠBˆATÿÿÿQ‹U RèñƒÄ…Àu3Àé€hX5s…TÿÿÿPèò5ƒÄ‰E¬¾Tÿÿÿƒù+t ¾•Tÿÿÿƒú-uŠ…Tÿÿÿˆ…LÿÿÿUÿÿÿ‰Hÿÿÿë •Tÿÿÿ‰•Hÿÿÿƒ}¬t‹…Hÿÿÿ¾ƒù0u‹•HÿÿÿƒÂ‰•Hÿÿÿëáƒ}¬uÆE¨ë"½TÿÿÿƒÉÿ3Àò®÷уÁÿ„ Tÿÿÿ+E¬ƒèˆE¨‹M3ÒŠQ‹E¨%ÿ;Ð}5‹MŠQˆU¨‹E¨%ÿ…Àu‹M¬ÆÇE¬ë‹U¨âÿ‹E¬ÆDƒ}¬u‹½HÿÿÿƒÉÿ3Àò®÷уÁÿˆM¤ë‹M¬+Hÿÿÿ‹U¨âÿʈM¤‹E3ÉŠ‹U¤âÿ;Ê}3Àé@ƒ}t/‹E¤%ÿ‹M¨áÿ+Á‹U3ÉŠ ‹U3ÛŠZ+Ë;Á~3Àé ¾…Lÿÿÿƒø-uÆE°-ëÆE°+Æ…PÿÿÿëŠPÿÿÿ€ÁˆPÿÿÿ‹•Pÿÿÿâÿ‹E3ÉŠƒÁ;Ñ}‹•PÿÿÿâÿÆD±0ëÄ‹E3ÉŠÆD ²ƒ}¬u4¿X5s•TÿÿÿƒÉÿ3Àò®÷Ñ+ù‹÷‹Ù‹úƒÉÿ3Àò®ƒÇÿ‹ËÁéó¥‹Ëƒá󤋽HÿÿÿƒÉÿ3Àò®÷уÁÿQ‹E3ÉŠ‹U3ÀŠB+ÈL ±‹U¤âÿ‹E¨%ÿ+Ð+ÊQ‹HÿÿÿQ裎‹UR}°ƒÉÿ3Àò®÷уÁÿQE°PèvƒÄ _^[‹å]ÃÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒìPWE°P‹MQè<ƒÄj‹U Rj}°ƒÉÿ3Àò®÷уÁÿQE°Pj/j脃ąÀ}3Àë¸_‹å]ÃÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒìPW‹E ÇÇ@M°Q‹URè̃Äj‹E Pj}°ƒÉÿ3Àò®÷уÁÿQM°Qj/jèäƒÄ…À}3Àë¸_‹å]ÃÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒìEèP‹MQè}ÿÿÿƒÄ…Àu3Àë=UøR‹EìP‹MèQÿ8q5sƒÄ Ý]ðÝEøèRC‹U ‰‹E ÛÜ]øßàöÄ@u3À븋å]ÃÌU‹ìƒì EèP‹MQèÿÿÿƒÄ…Àu3ÀëJUøR‹EìP‹MèQÿ8q5sƒÄ Ý]ðÝEøèòB‹U ‰‹E ‹‰MàÇEäßmàÜ]øßàöÄ@u3À븋å]ÃÌÌÌÌU‹ììÇ…hÿÿÿ…xÿÿÿ‰EøÇ…äþÿÿèþÿÿ‰tÿÿÿ‹U âÿR…èþÿÿP‹MƒÁQ茋U âÿ‰•lÿÿÿ‹EŠHˆpÿÿÿƒ½lÿÿÿ$‹U3ÀŠB…ÀuÆ…pÿÿÿ‹MøÆ0‹UøƒÂ‰Uøë[ƒ½lÿÿÿ‹…tÿÿÿ3ÉŠ…ÉuëBUüR…lÿÿÿPlÿÿÿQè)ƒÄ ‹Uø‹EüŠˆL5sˆ ‹UøƒÂ‰Uø‹…hÿÿÿƒÀ‰…hÿÿÿ륋M3ÒŠQ9•hÿÿÿ%‹EøŠ L5sˆ‹UøƒÂ‰Uø‹…hÿÿÿƒÀ‰…hÿÿÿëË‹hÿÿÿ‰M‹•pÿÿÿâÿ…Òu‹EÆ-‹MƒÁ‰M‹UƒÂ‰Uƒ½hÿÿÿt`‹E3ÉŠH‹•hÿÿÿ‹…hÿÿÿƒè‰…hÿÿÿ;Ñu!‹MÆ.‹U‰•äþÿÿ‹EƒÀ‰E‹MƒÁ‰M‹Uøƒê‰Uø‹E‹MøŠˆ‹EƒÀ‰Eë—‹M¾ƒú.u‹EÆ‹Mƒé‰M¸‹å]ÃÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒìSÇEüÇEü‹E ‹ƒé‰Møë ‹Uøƒê‰Uøƒ}ø|B‹EüÁà‹M ‹Q‹Mø3ÛŠ ÉEü‹Eü3Ò¹ ÷ñ‹U‹J‹Uøˆ‹Eü3Ò¹ ÷ñ‰Uü믋U‹ƒè‰Eøë ‹Møƒé‰Møƒ}ø~‹U‹B‹Mø3ÒŠ…ÒuëÝ‹EøƒÀ‹M‰‹U‹Eü‰[‹å]ÃÌÌÌÌÌU‹ìƒìTVW¹3À}¬ó«ÇEüë ‹EüƒÀ‰Eüƒ}üP} ‹MüÆD ¬ëçjPU¬Rj‹EPè ýÿÿƒÄ…Àu3Àë(}¬‹U ƒÉÿ3Àò®÷Ñ+ù‹÷‹Á‹úÁéó¥‹Èƒáó¤¸_^‹å]ÃU‹ìƒìÇEìÿÿÿÿ‹EƒÀ‰EüÇEô‹M¾ƒú-uÆEø‹EƒÀ‰Eë‹M¾ƒú+uÆEø‹EƒÀ‰EëÆEøÇEð‹M¾‰Uè‹Eè‹MƒÁ‰M…ÀtXƒ}è tRƒ}è0|ƒ}è9 ‹Uèƒê0‰Uèëƒ}è.u‹Eð‰Eìë¼3Àëbj MôQèaƒÄ‹UèREôPèñƒÄ‹MðƒÁ‰Mðë‹UŠEðˆƒ}ìÿu ‹MÆAë ‹Uð+Uì‹EˆP‹MŠUøˆQ‹EŠMôˆ¸‹å]ÃÌÌÌÌÌÌU‹ìƒìÇEü‹E‹H‰Mð‹Uð‰Uô‹E‹Mô‰Mø‹Uô;UøsC‹Eð3ÉŠ‹U ¯Ñ‹Eü‰Eü‹MðƒÁ‰Mð‹Eü3Ò¹÷ñ‹Eôˆ‹MôƒÁ‰Mô‹UüÁê‰Uü뵃}üt‹EôŠMüˆ‹UôƒÂ‰Uô‹E‹Mô+H‹U‰ ‹å]ÃÌÌÌÌÌU‹ìƒì ‹E‹‰Mô‹U ‰UüÇEøë ‹EøƒÀ‰Eø‹Mø;Mô}A‹Uø;Uô}‹E‹H‹Uø3ÀŠ‹MüȉMü‹Eü3Ò¹÷ñ‹E‹H‹Eøˆ‹MüÁé‰Mü뮃}üt‹U‹B‹MøŠUüˆ‹EøƒÀ‰Eø‹M‹Uø‰‹å]ÃÌÌÌÌÌÌÌU‹ìì¼WÇ…Pþÿÿ\5s¹_3À½Tþÿÿó«‹E P‹MQ‹•PþÿÿR…TþÿÿPÿXq5sƒÄTþÿÿQèbì•TþÿÿRè–íƒÄ½TþÿÿƒÉÿ3Àò®÷уÁÿ‰MЃ}ЄŽhX5s…TþÿÿPèÃ+ƒÄ…Àtv‹MД Sþÿÿ‰Uü‹Eü¾ƒù0u^‹@q5sƒ:~j‹Eü¾HÿQÿDq5sƒÄ‰…Dþÿÿë‹Uü¾Bÿ‹ Hq5s‹3Éf‹ Bƒá‰Dþÿÿƒ½Dþÿÿt‹UüÆ‹Eüƒè‰Eüë—‹MQ½TþÿÿƒÉÿ3Àò®÷уÁÿQ•TþÿÿRèƒÄ _‹å]ÃÌÌÌÌÌÌÌÌÌÌÌU‹ìƒìXVW¹3À}¨ó«ƒ} O~3Àé—j‹EP膋M Q‹URE¨Pÿ‹Mô‹4¸5s‹ЉEøƒ}øt'‹Møƒyu‹Uø‹‚†;Eüu‹MQ‹UøRèïþÿÿƒÄë®hÀ¸5sÿ,p5s‹Eü‹å]ÃÌÌÌÌÌÌÌÌU‹ìƒì‹EPèQ‚…Àu3À鎋Máÿƒùt‹Uâÿƒút‹E%ÿƒøt3ÀëaŠMˆMø€}øt€}øt%€}øt3ëE‹U‹‚’‰Eü‹M‹U ‰‘’‹Eüë*‹EÇ€š¸ë‹MÇš¸ë3À‹å]ÃÌÌÌÌU‹ìƒì ƒ}u3Àët‹EPè§€…Àu5‹M‰Mü‹Uü3ÀŠB|ƒøu ‹Mü3ÒŠQ}ƒút3ÀëC‹Eü‹M ‰ˆ<‹E ë2‹U‰Uø‹EøPèO…Àu3Àë‹Mø‹‘ЉUô‹Eø‹M ‰ˆŠ‹Eô‹å]ÃÌÌÌÌÌÌÌÌU‹ìƒì hà¸5sÿ0p5s¡<¸5s‰Eü‹M‰ <¸5sƒ=4¸5st[ÇEôë ‹UôƒÂ‰Uô‹Eô;”—5ss>‹Mô‹4¸5s‹ЉEøƒ}øt'‹Møƒyu‹Uø‹‚Š;Eüu‹MQ‹UøRèïþÿÿƒÄë®hà¸5sÿ,p5s‹Eü‹å]ÃÌÌÌÌÌÌÌÌU‹ìQWjhHjjèËz‰Eüƒ}üu3Àé8‹EüÆ@|‹MüÆA}‹UüÆB~‹EüÆ@ ‹MüÆ€ ‹UüÆ‚‹EüÆ€‚‹MüÆ„‹UüÆ‚ƒ¿°’5sƒÉÿ3Àò®÷уÁÿ‹EüˆˆØ‹MüÆÞ ‹UüƂߋEüÆ€ÿ‹MüÇ8‹UüÇ‚<‹EüÇ€@ÿÿÿÿ‹MüÇDjhl5s‹UüÂ-Rÿ‹U¿Bƒøt2‹Mf‹‘„fâßÿ‹Ef‰„‹MŠQ€âû‹EˆP¸én ‹M¿Qƒút‹E¿Hƒùt‹U3ÀŠBƒà…À„ü‹M3ÒŠQƒâ…Ò…é‹E¿ˆB…Éu_‹U3ÀŠBƒà@…ÀtP‹Mf‹‘BfƒÂ‹Ef‰B‹MŠQ€â¿‹EˆP‹M¿Qƒúu‹EfÇ@¸é͸éËM¿‘B…ÒtF‹E3ÉŠHƒá@…Ét7‹UŠB$¿‹MˆA‹U¿Bƒøu ¸é‚‹M¿Qƒúu3Àéo‹E3ÉŠHƒá…Éu‹U3ÀŠBƒà…Àt ¸éG‹M¿Qƒúu"‹E3ÉŠHƒá…Ét‹UfÇB¸é‹E¿Hƒùu3Àé‹UÇB0‹EÇ@4‹MÇA8‹U3ÀŠB=Ñt)‹M3ÒŠQúÓt‹E3ÉŠHùýt ‹URè“b‹Ef‹ˆBfƒÁ‹Uf‰ŠB¸…À„‹‹MŠQˆUü‹Eü%ÿ…ÀuMøQ‹UR茧ˆEü‹EŠMüˆHƒ}øu‹UÆB3ÀéI‹Eü%ÿ= u!‹Mƒy$t‹UŠB ‹MˆA¸éUðRŠEüP‹MQè«§…Àu3Àéý‹Uüâÿ‰UÌ‹Ẽè*‰EÌ}ÌÕ‡¸‹UÌ3ÉŠŠ±82sÿ$a82s‹EðP‹MQè?…ƒøt‹URjè|é§é–‹EðP‹MQè¨k…Àu3ÀéŠéy‹Uƒz$t‹EðP‹MQèo…Àu3ÀédéS‹UðR‹EPè5‚…Àu3ÀéGé6‹MðQ‹URè¨b…Àu3Àé*é‹EðP‹MQè«c…Àu3Àé éü‹UðR‹EPèng…Àu3Àéðéß‹MðQ‹URèqc…Àu3ÀéÓé‹EðP‹MQèôe…Àu3Àé¶é¥‹UfÇB‹EŠH€É‹UˆJ‹EŠH€É ‹UˆJ¸é€‹EPèi…Àu3Àélé[‹MQè!h…Àu3ÀéSéB‹UðR‹EPèta…Àu3Àé6é%‹MðQ‹URè÷X…Àu3Àéé‹EðP‹MQèÚW…Àu3ÀéüÇEôéäƒ}ôtÇEôjŠUüR‹EðP‹MQèㄉEøƒ}øûu:‹Uüâÿúþu$‹E3Éf‹ˆ„ƒá …Ét‹UÆB¸é’é‹EÆ@‹Eøé~j‹MðQ‹URjèàs‰Eìƒ}ìu3Àé]‹E‹H3Òf‹Q…Ò„•‹E‹H3Òf‹Q9Uð€‹E‹H3Òf‹‹E‹H3Àf‹A+Ð9Uðb‹MðQ‹U‹B‹M‹Q3Éf‹J‹PÑR‹EìPÿq5sƒÄ ‹M‹Qf‹BfEð‹M‹Qf‰B‹E‹Hf‹Qf+Uð‹E‹Hf‰QÇEÈë‹UðR‹EìP‹MQè–‰Eȃ}Èu3Àé“‹Uì¾BÁà%ÿ‹Mì¾Q ‹Mˆ‹Uì¾BƒÀˆEè‹Mèáÿ‹Uì¾ ƒø_uV‹MÆž‹Uèâÿ‹E‹MìŠTˆŸ‹Eè%ÿ‹M‹UìŠDˆ ‹Mèáÿ‹U‹EìŠLˆŠ¡ë ‹UÆ‚ž‹EìP‹MQè sƒÄéÓ‹UðRŠEüP‹MQèÁˆ…Àu3ÀéÃ鲋Uð‰Uä‹E‹H‹Q‰UÔj‹EäP‹MQjèr‰E܃}Üu3Àé‹‹U‹B3Éf‹H…É„•‹U‹B3Éf‹H9M䇀‹U‹B3Éf‹‹U‹B3Òf‹P+Ê9Mäwb‹EäP‹M‹Q‹E‹H3Àf‹A‹JÈQ‹UÜRÿq5sƒÄ ‹E‹Hf‹QfUä‹E‹Hf‰Q‹U‹Bf‹Hf+Mä‹U‹Bf‰HÇEÄë‹MäQ‹UÜR‹EPè4”‰Eă}Äu‹MÜQ‹URèÞqƒÄ3À鱃}ä$…†‹EäP‹MÜQhp5sÿ q5sƒÄ …Àul‹UÜR‹EPè£qƒÄÇEÜÇEäƒ=¸5su!MàQèà-ƒÄ…Àu3ÀéOǸ5s‹URè?1ƒÄ…Àu3Àé.‹EÇ€Ö‹ d¼5s‰Màj‹UàR‹EPjèzp‰EЃ}Ðuƒ}Üt‹MÜQ‹URèqƒÄ3Àéáh ¸5sEØPMàQ‹UÐR‹EäP‹MÜQ‹URèÒ.ƒÄ…Àu'‹EÜP‹MQèÎpƒÄ‹UÐR‹EPè¾pƒÄ3Àé‘‹MÔÆ‹UàR‹EÐP‹MQè­¢…Àt ‹URèÀ£…Àu$‹EÜP‹MQèpƒÄ‹UÐR‹EPèopƒÄ3ÀëE‹MÜQ‹URè[pƒÄ‹EÐP‹MQèKpƒÄëh'‹URèH‹EfÇ@‹MÆAéhøÿÿ‹å]ÃØ12s~52sÝ22sI32sö22s»12sr22s22s822sU22s32s”12s,32sß32sþ12s22s¬22sŸ52sm32s:82s ÌÌÌÌÌÌÌÌÌU‹ìƒì@ÇEðÇEØÇEè‹EPè¼s…Àuj‹MQè-ïÿÿƒÄéÿ ‹U¸;B,É÷Ù…É„‹UƒzH„‹E‹H8ƒÁ‹U;J4~-‹Eƒx<t$‹MQè®l‹U;B@ujý‹EPèËîÿÿƒÄé ‹M‹Q8ƒÂ‹E;PH¾‹M‹U‹A8;B0Œ¬‹M‹U‹A8;B4š‹Mƒy<„‹U‹B8ƒÀ‹M‰A8‹U‹E‹J8+H0‹U‹B@Lÿ‰Mä‹U‹Eä;B,r ‹M‹Uä+Q,‰Uä‹EäkÀ ‹M‹Q(‹M‹‰‘>‹Eƒ¸>ÿul‹MäkÉ ‹U‹B(‹U‹D‰BDÇEàë ‹MàƒÁ‰Mà‹U¿B"9Eà}‹MàQ‹URè©‘…ÀuÇEØëу}Øuj‹EPè»íÿÿƒÄé飋MäkÉ ‹U‹B(‹U‹D‰BRj‹M‹‘>R‹EPè³w‰Eìƒ}ìuj‹MQèoíÿÿƒÄéAÇEàë ‹UàƒÂ‰Uà‹Eì3Éf‹9Mà}$‹UàR‹E‹ˆ>Q‹URèaž…ÀuÇEØëƃ}Øuj‹EPèíÿÿƒÄéå‹M‹‘>R‹EPèøìÿÿƒÄéÊ‹M¿Qƒút&‹E¿H…Ét ‹U¿Bƒøu"‹M3ÒŠQƒâ…Òujþ‹EPè³ìÿÿƒÄé…‹MQèl…Àu j‹URèãO‹E‹M‹Q4‰P8¸…À„T‹MŠQˆUø‹Eø%ÿ…ÀuMðQ‹URè蛈Eø‹EŠMøˆHƒ}ðu‹UÆBj‹EPè4ìÿÿƒÄé‹Møáÿ‰MÌ‹Ũêy‰UÌ}̆w:‹MÌ3ÀŠÖC2sÿ$…ÎC2sUÔRŠEøP‹MQèû›…Àuj‹URèÜëÿÿƒÄ鮋Eø%ÿ‰EÈ‹Mȃé*‰MÈ}ÈÕ‡c‹EÈ3ÒŠD2sÿ$•]D2s‹MÔQ‹URè„yƒøt‹EPjèÄpP‹MQèzëÿÿƒÄéLé;‹U¸;B,É÷Ù…Ét|‹Uƒz<t$‹EPèi‹M;A@ujý‹URè5ëÿÿƒÄé‹Eƒx0 ‹MÇA0‹URèáh‹M‰A<‹U‹Bÿÿÿÿƒ}Øuj‹EPèöéÿÿƒÄéÈjÿ‹MQèãéÿÿƒÄ鵋UƒzRt ‹EPèùc…Àt ‹MQèì^…Àuj‹URè­éÿÿƒÄé‹E¹;H,Ò÷Ú…Òtg‹Eƒx<t$‹MQèPg‹U;B@ujý‹EPèméÿÿƒÄé?‹Mƒy0 ‹UÇB0‹EPèg‹M‰A<‹U‹B‹Mº;Q,À÷Ø…Àt‹Môáÿ‹U܉ ‹EÜ‹M‹QR‰Pƒ}Øuj‹EPèçÿÿƒÄéÔ‹MôáÿQ‹URèçæÿÿƒÄ鹃}èt‹Eø%ÿ=þu ÇEÀëÇEÀŠMÀˆMЋUøâÿúÿu ÇEèë‹Eø%ÿ=þtÇEè‹Mº;Q,À÷Ø…Àu:‹MÇ>þÿÿÿ‹U3ÀŠB=ÿt‹MÇA0‹UÇB4‹EÇ@8‹MŠQ€âß‹EˆP‹MfÇAŠUÐRŠEøP‹MÔQ‹URèŠu‰Eðƒ}ðûuéÊ‹EÆ@‹MðQ‹URèèåÿÿƒÄ麋EÔP‹MQèI…Àuj‹URèÄåÿÿƒÄé–é…‹EÔP‹MQèêG…Àuj‹URè›åÿÿƒÄëpëb‹EÇ€>þÿÿÿjþ‹MQè|åÿÿƒÄëQ‹UÔRŠEøP‹MQèÆz…Àuj‹URèWåÿÿƒÄë,ëh'‹EPèâj‹MQè7åÿÿƒÄë ‹UÆBéŸøÿÿ‹å]Ãô<2s=2s\C2syC2s9C2sO=2sC2sƒ=2s?2sB2s C2sÌÌÌÌÌÌÌÌÌU‹ìQÇEüƒ}uh'jè3ÀéÕ‹Eƒ¸Îtj‹M‹‘ÎRè¿'ƒÄ‹EPèÓ?ƒÄ‹MQèÇf…Àu3Àé•‹UƒºÖt‹EPè'#ƒÄ‹MÇÖ‹URèÎüƒÄƒøu‹EfPÿXp5sh ¹5sÿ0p5s‹MQèÓjh ¹5sÿ,p5s‹Uƒz tP‹E‹H‹Q@‰Uü‹EüP‹M‹Q R胑ƒøth"'‹EPè0‹M‹Q‹BPPÿ4p5s‹M‹Q RjèbƒÄ‹EPè¶L‹MQèG‹URètG‹Eƒ¸Êt‹MÁÊQèÙ&ƒÄ‹URè=J‹Eƒxt9‹M‹Q‹BPjè£aƒÄ‹M‹Q‹BPjèaƒÄ‹M‹QRjè~aƒÄ‹EPèRJ‹M‹‘NR‹EPè_aƒÄè7i‹M‹‘ÆRÿÔp5s‹EǀƋMQjè/aƒÄ¸‹å]ÃÌÌÌU‹ìƒìWƒ}t ƒ} tƒ}u3ÀéЋE P‹MQ胃ĉEüƒ}üu3Àé°‹} ƒÉÿ3Àò®÷уÁÿ‹UüщUü‹Eü¾…ÉtM‹@q5sƒ:~j‹Eü¾QÿDq5sƒÄ‰Eôë‹Uü¾‹ Hq5s‹3Éf‹ Bƒá‰Môƒ}ôt ‹UüƒÂ‰Uüë©‹Eü¾…Éu3Àé1‹Uü¾ƒø=t3Àé‹Mü¾…Òu3Àé‹EüƒÀ‰Eü‹Mü¾…ÒtL¡@q5sƒ8~j‹Mü¾RÿDq5sƒÄ‰Eðë‹Eü¾‹Hq5s‹3Òf‹Hƒâ‰Uðƒ}ðt ‹EüƒÀ‰Eü몋Mü¾…Òu3ÀéžfÇEø‹Eü¾…É„„‹@q5sƒ:~j‹Eü¾QÿDq5sƒÄ‰Eìë‹Uü¾‹ Hq5s‹3Éf‹ Bƒá‰Mìƒ}ìuB‹Uøâÿÿ‹E%ÿÿ;Ð}-‹M‹UüŠˆ‹MƒÁ‰M‹UüƒÂ‰Uüf‹Eøff‰Eøénÿÿÿ‹MÆ_‹å]ÃÌÌÌÌÌÌÌÌÌÌÌU‹ììXÇEüjj‹EPè“áÿÿƒÄ jj‹MQè£ßÿÿƒÄ Ç…¼þÿÿ‹L—5sR‹EP薃ąÀu颋MQèƒÄ…ÀuéÇ…¼þÿÿ‹URè‚äÿÿƒÄƒøtém‹EPèœïÿÿƒÄƒøÿtéWj‹MQèt ƒÄ‰…Äþÿÿƒ½Äþÿÿué5j‹URè ƒÄ‰…Àþÿÿƒ½Àþÿÿ| ½Àþÿÿÿ~é‹…ÀþÿÿP‹ÄþÿÿQ•üþÿÿRÿRj‹EPè2ƃăøt‹œýÿÿQ‹•ìþÿÿRè÷Qé¡‹…ìþÿÿPèÆX…Àu‹œýÿÿQ‹•ìþÿÿRèÏQéy…¨ýÿÿPh`‘5sÿ q5sƒÄ…Àt¨ýÿÿQhT‘5sÿ q5sƒÄ…Àu ‹UÆ‚‹ë(‹E3ÉŠˆ„ƒá…Ét ‹UÆ‚‹ë ‹EÆ€‹‹ìþÿÿ‹Qf‹BTf‰…°þÿÿ‹ìþÿÿ‹QfÇBTh<‹EP‹ìþÿÿQèŒ|…Àt‹•ìþÿÿRèœ}…ÀuR‹…ìþÿÿ‹Hf‹•°þÿÿf‰QT‹…¤ýÿÿÆh'‹ìþÿÿQèJé‹•ìþÿÿRèžR‹…œýÿÿP‹ìþÿÿQèËPéu‹•ìþÿÿ‹Bf‹°þÿÿf‰HThL‘5sj‹•ìþÿÿRè_ƒÄ hL‘5sj‹…ìþÿÿPèIƒÄ ‹ìþÿÿQèÚ%ƒÄ‹•ìþÿÿR苇…Àu$‹…ìþÿÿPèR‹œýÿÿQ‹•ìþÿÿRèHPéò‹…ìþÿÿŠH€áû‹•ìþÿÿˆJ‹…ìþÿÿPèRÏÿÿƒÄ‰…ðþÿÿƒ½ðþÿÿt/ƒ½ðþÿÿu$‹ìþÿÿQè»Q‹•œýÿÿR‹…ìþÿÿPèèOé’볋œýÿÿQjè#IƒÄ‹•ìþÿÿ3ÀŠƒøB}5hy'‹ìþÿÿQèè‹•ìþÿÿRèdQ‹…œýÿÿP‹ìþÿÿQè‘Oé;‹•ìþÿÿ3ÀŠƒø4ug‹ìþÿÿŠQ€âû‹…ìþÿÿˆP‹ìþÿÿQèŒÎÿÿƒÄ‰…ðþÿÿƒ½ðþÿÿt/ƒ½ðþÿÿu$‹•ìþÿÿRèõP‹…œýÿÿP‹ìþÿÿQè"OéÌë³éÅ‹•ìþÿÿ‹B3Éf‹HV…ÉŽ®‹•ìþÿÿ‹B3Éf‹HV‹•ìþÿÿ‹B3Òf‹PT;Ê„ˆ‹…ìþÿÿPè=ëÿÿƒÄ…Àt‹ìþÿÿ‹Q‹…ìþÿÿ‹Hf‹RVf‰QTj‹…ìþÿÿ‹H3Òf‹QTRjjè1G‰…|ûÿÿj‹…ìþÿÿ‹H3Òf‹QTRjjèG‰…xûÿÿƒ½|ûÿÿt ƒ½xûÿÿuuh'‹…ìþÿÿPè§æ‹ØþÿÿQjè‰GƒÄ‹•œýÿÿRjèxGƒÄ‹…ìþÿÿ‹HQ‹•ìþÿÿRè_GƒÄ‹…ìþÿÿ‹ˆÆQÿÔp5s‹•ìþÿÿRjè;GƒÄé’‹…ìþÿÿ‹H‹QRjèGƒÄ‹…ìþÿÿ‹H‹•|ûÿÿ‰Q‹…ìþÿÿ‹H‹QRjèöFƒÄ‹…ìþÿÿ‹H‹•xûÿÿ‰Q‹…ìþÿÿ‹H‹•ìþÿÿ‹B‹I‰H‹•ìþÿÿ‹B‹ìþÿÿ‹Q‹@‰B‹ìþÿÿ‹Q‹BÆ@"‹ìþÿÿÁfQÿ p5s‹•ìþÿÿRèÂøƒÄ‹E‹ˆDƒá…Ét‹•ìþÿÿRèãëÿÿƒÄ‹…ìþÿÿÇ€~èûD‰…Üþÿÿƒ½Üþÿÿu1h ¸5sj‹ìþÿÿQè ƒÄ h ¸5sj‹•ìþÿÿRèóƒÄ éЃ½Üþÿÿ…Ë…ìþÿÿ3ÉŠƒùBu#‹•ìþÿÿRèÃæÿÿƒÄ…Àt‹…ìþÿÿÇ€~ÿ\p5s…ÀuD‹ìþÿÿ3ÒŠƒúBu33À a–5sƒà …Àu%‹ìþÿÿƒ¹~uh ¸5sj‹•ìþÿÿRèóƒÄ ëC‹…ìþÿÿ3ÉŠƒùBu43ÒŠm–5sƒâ …Òu%‹…ìþÿÿƒ¸~th ¸5sj‹ìþÿÿQè®ƒÄ ‹•ìþÿÿRèY…Àu$‹…ìþÿÿPèM‹œýÿÿQ‹•ìþÿÿRè¼Kéf‹…ìþÿÿPè»/‹ìþÿÿÇF‹•ìþÿÿfÇ‚B‹…ìþÿÿÇ€R‹ìþÿÿÇÊÇ…LûÿÿD‘5s‹UÂÙ‰•Hûÿÿ‹…HûÿÿŠˆGûÿÿ‹•Lûÿÿ: uF€½Gûÿÿt1‹…HûÿÿŠHˆFûÿÿ‹•Lûÿÿ:Ju#ƒ…Hûÿÿƒ…Lûÿÿ€½Fûÿÿu®Ç…@ûÿÿë ÀƒØÿ‰…@ûÿÿ‹@ûÿÿ‰<ûÿÿƒ½<ûÿÿ|C‹•ìþÿÿ3ÀŠ‚žƒøu0‹ìþÿÿ3ÒŠ‘Ÿƒú|‹…ìþÿÿf‹ˆ„€É@‹•ìþÿÿf‰Š„‹…ìþÿÿf‹ˆ„fáÿ÷‹•ìþÿÿf‰Š„ƒ½ ýÿÿt‹… ýÿÿPjè¬CƒÄ‹…ìþÿÿëLƒ½´þÿÿt‹´þÿÿQjèŠCƒÄƒ½äþÿÿt ‹•äþÿÿRÿ4p5sƒ½ ýÿÿt‹… ýÿÿPjèZCƒÄ3À_^[‹å]ÃÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìWƒ} t ‹E ¾…ÉuP‹URèH…Àu3Àë_‹E3ÉŠHƒá…Ét‹U3ÀŠ‚Âƒà…Àu ‹MQè!(‹UŠB$þ‹MˆA¸ë ‹} ƒÉÿ3Àò®÷уÁÿQ‹U R‹EPèƒÄ _]ÃÌÌÌÌÌÌÌÌÌU‹ìQ‹EPè“G…Àu3ÀéN‹M3ÒŠQƒâ…Òt‹E3ÉŠˆÂƒá…Éu ‹URèž'‹EŠH€áþ‹UˆJ‹E‹H‰Müƒ}üt‹Uüƒzt ‹Eü‹H‰Müëæƒ}üt9jj ‹URjèwA‹Mü‰A‹Uüƒzu‹EPjè½G龋Mü‹Q‰Uüë1jj ‹EPjè>A‰Eüƒ}üu‹MQjèŠGé‹‹U‹Eü‰B‹Mü‹U‰Qƒ}tWj‹Eü‹HQ‹URjèù@‹Mü‰‹Uüƒ:u ‹EPjèAGëE‹Mü‹QR‹Eü‹Q‹U Rè B‹EP‹Mü‹R‹EPèæ<‹MüÇA‹UÇ‚F¸‹å]ÃÌÌÌÌÌÌU‹ì‹EPè$F…Àu3Àë4‹MÇA‹URè¹ ƒÄ…Àu‹EÇ@3Àë ‹MQè ƒÄ]ÃÌÌÌÌÌÌU‹ìƒì,ÇEìÇEüÇEäÇEôÇEð‹EPè®E…Àu3ÀéËMŠQ€â‹EˆP‹M3ÒŠQƒâ…Òth6'‹EPè—ß3Àé‹M‹Q3Àf‹BT‰Eü‹Mü‰Mèj‹UüR‹EPjèª?‰Eìƒ}ìu‹MQjèöEéQ‹UÇBV‹EfÇ@‹MÇFº…Ò„ÆEø‹EŠMøˆHUôR‹EPèúoˆEø‹MŠUøˆQƒ}ô……‹E3ÉŠˆZƒá…ÉtZÇEð‹UŠ‚Z$÷‹MˆZ‹URè¾ ƒÄ…Àt ÇEäë$‹EPèU*‹MÆA‹UÇ‚F3ÀéŠë‹EÆ@‹MQ‹UìRèEéo‹Eø%ÿ‰Eà‹Màƒéx‰Mà}à‡w:‹Eà3ÒŠœp2sÿ$•”p2sMèQŠUøR‹EPèŸo…Àuj‹MQ耿ÿÿƒÄé‹Uè;Uü~@‹EìP‹MQèó>ƒÄ‹Uè‰Uüj‹EüP‹MQjè)>‰Eìƒ}ìu‹URjèuDéЋEø%ÿ‰EÜ‹M܃é*‰MÜ}ÜÕ‡T‹EÜ3ÒŠHq2sÿ$•$q2sÇEä‹MfÇA‹U‹B3Éf‹H…É„•‹U‹B3Éf‹H9M耋U‹B3Éf‹‹U‹B3Òf‹P+Ê9Mèb‹EèP‹M‹Q‹E‹H3Àf‹A‹JÈQ‹UìRÿq5sƒÄ ‹E‹Hf‹QfUè‹E‹Hf‰Q‹U‹Bf‹Hf+Mè‹U‹Bf‰HÇEØë‹MèQ‹UìR‹EPè`‰E؃}Ø…¨‹M3ÒŠ‘Zƒâ…ÒtwÇEð‹EŠˆZ€á÷‹UˆŠZ‹EPè ƒÄ…Àt ÇEäë@‹MQè&(‹UÆB‹EÇ€F‹MìQ‹URèE=ƒÄj‹EPè§½ÿÿƒÄé?ë‹MQ‹UìRèÐBP‹EP膽ÿÿƒÄé‹MèQ‹UìR‹EPèíØéì‹MèQ‹URè› …Àu#‹EìP‹MQèÚ<ƒÄj‹URè<½ÿÿƒÄéÔ鳋EèP‹MQèb…Àu#‹UìR‹EPè¡<ƒÄj‹MQè½ÿÿƒÄé›éz‹URèý/…Àu#‹EìP‹MQèl<ƒÄj‹URèμÿÿƒÄéféE‹EŠH€É‹UˆJ‹EìP‹MQè5<ƒÄ‹UäR‹EP蕼ÿÿƒÄé-‹Møáÿùýu1ƒ}äuƒ}ðt%‹UìR‹EPèó;ƒÄ‹MäQ‹URèS¼ÿÿƒÄéë‹E‹H3Òf‹Q…Ò„‹E‹H3Òf‹Qƒú|~‹E‹H3Òf‹‹E‹H3Àf‹A+Ѓú|`j‹M‹Q‹E‹H3Àf‹A‹JÈQ‹UìRÿq5sƒÄ ‹E‹Hf‹QfƒÂ‹E‹Hf‰Q‹U‹Bf‹Hfƒé‹U‹Bf‰HÇEÔëj‹MìQ‹URèi]‰EÔƒ}Ôu‹EP‹MìQèÃ@é‹U쿃à…Àt#‹M‹Uì‹B‰AV‹MŠ‘Z€Ê‹EˆZë‹MŠ‘Z€âþ‹EˆZ‹M쿃â…Òth'‹EPè¾ÙÇEä‹M쿃â…Òt‹Eì¿စÉ„L‹Uì¿%€…Àt‹Mf‹‘„€Ê ‹Ef‰„‹M쿃â…Òu‹EŠH€áï‹UˆJë‹EŠH€É‹UˆJ‹E3ÉŠHƒá…Ét‹Uì¿ƒà …Àu‹MŠQ€Ê‹EˆPëG‹MŠQ€âý‹EˆP‹Møáÿùýu'‹UfÇB‹EŠH€á÷‹UˆJ‹EŠH€É‹UˆJ‹Eø%ÿ=ýt ‹MfÇAë?‹U¿Bƒøt‹MfÇA‹UŠB @‹MˆA‹UŠB$÷‹MˆA‹UŠB ‹MˆA‹UÆB‹EìP‹MQèR9ƒÄ‹UäR‹EPè²¹ÿÿƒÄéJ‹MŠQ€Ê‹EˆP‹Mì¿ƒâ …Òtu‹E쿃á…Éuh‹UŠB$ý‹MˆA‹U3ÀŠBƒà…ÀtI‹MŠQ€â÷‹EˆP‹M¿Qƒút‹EfÇ@‹MŠQ€Ê@‹EˆP‹MŠQ€Ê‹EˆP‹MÆAë<‹Uøâÿúýu)‹EìP‹MQè‹8ƒÄ‹UÆB‹EäP‹MQèä¸ÿÿƒÄëëa‹UìR‹EPè`8ƒÄ‹MäQ‹URèÀ¸ÿÿƒÄë[‹EèPŠMøQ‹URè N…Àu*h'‹EPè8׋MQ‹UìRèË=P‹EPè¸ÿÿƒÄë‹MÆAéß÷ÿÿ‹UìR‹EPèó7ƒÄ‹å]ÃPi2sxi2s>l2súk2sÁk2s/l2sói2sj2sˆk2scl2s5p2sÌÌU‹ìƒì‹EPèA;…Àu3Àéïƒ=h¸5st ‹MQè4éƒÄ‹UŠB ‹MˆA‹U3ÀŠBƒà…Àuh6'‹MQèÕ3À騋U‹B‰Eüƒ}üuh&'‹MQèòÔ3Àé„‹U‹B‹H‰Mø‹U3ÀŠƒø@|‹MøÆë‹UøÆFƒ}üt5‹Eüƒxt!‹Mü‹QR‹Eü‹Q‹URè g…Àu3Àé.‹Eü‹H‰MüëÅ‹URè¡h…Àu3Àé‹Eƒx„šƒ}t3jj‹MQèÖ ƒÄ …Àt‹U‹‚¢‰Eôë ‹ 0¸5s‰Mô‹Uô‰Uðë¡0¸5s‰Eðƒ}ðtI‹M‹QfÇB‹E‹HfÇ‹U‹BfÇ@‹M3ÒŠƒú@|‹E‹H‹QÆë ‹E‹H‹QÆF‹EÇ@‹MÆA‹URèo‹EÆ@‹MfÇB‹U3ÀŠƒø@|‹M‹Q‹BÆë ‹M‹Q‹BÆF‹MÇR‹UÇ‚F¸‹å]ÃÌÌÌU‹ìƒ}}h,'jèKÓ3Àë ‹E£0¸5s¸]ÃÌÌÌÌÌÌÌÌU‹ìƒ}}h,'jèÓ3Àë ‹E£—5s¸]ÃÌÌÌÌÌÌÌÌU‹ìƒìÇEü‹EPèÊ8…Àu3À鸋M‹Q‰Uð‹Eðƒx t ‹Mðƒy u3Àé–‹Uð3Àf‹B‹Mð3Òf‹;Â} ¸éw‹E3Éf‹ˆ„ƒá …Ét%‹U3ÀŠBƒà@…Àu‹M¿Qƒút ¸é?‹E¿Hƒùt‹U¿Bƒøt‹M3ÒŠQƒâ…Ò„¨‹E3ÉŠHƒá…É…•‹U¿‚B…Àu‹M3ÒŠQƒâ@…Òt ¸éÚ‹E¿ˆB…Ét;‹U3ÀŠBƒà@…Àt,‹M¿Qƒúu ¸é§‹E¿Hƒùu ¸é‘‹U3ÀŠBƒà…Àu‹M3ÒŠQƒâ…Òt¸ël‹E¿Hƒùu‹U3ÀŠBƒà…Àt¸ëJƒ=ü¹5sÿt ‹ ü¹5sQèìe‹U‹B‹HD‰Mü‹UüREøP‹MQèŸa‰Eôƒ}ôu ƒ}ø~¸ë3À‹å]ÃÌÌÌU‹ìƒì h ¹5sÿ0p5s¡4¸5s‰Eü‹ ”—5s‹4¸5sЉEøƒ}üt^‹Mü;MøsV‹Uü‹‰Eô‹Mô‹UüƒÂ‰Uü…Ét‹E‹€>‹å]ÃÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ì‹EPèT4…ÀuëL‹Mº;Q,À÷Ø…Àtƒ} }ë1‹M‹U ;Q,| ‹E‹H,ƒé‰M ‹UÇ‚F‹E P‹MQè‚-]ÃU‹ìƒìÇEø‹EPèª3…Àu3Àë3‹M‹Q‰Uüƒ}üu3Àë ƒ}üt‹Eü‹MøH‰Mø‹Uü‹B‰Eüëã‹Eø‹å]ÃÌÌÌÌÌÌÌÌÌÌÌU‹ìƒìƒ}uh4'‹EPè¦Í3ÀéÁMìQUüR‹E P‹MQèúƒÄ‰Eèƒ}ètƒ}üu‹UÆ‹EèéŒÇEðƒ}} ÇEôÿÿÿÿë‹E‰Eôƒ}üt\‹Mð;MôsT‹Uü‹B+Eì‰Eø‹MðMø;Môv ‹Uô+Uð‰Uø‹EøP‹MMðQ‹Uü‹EìPè‡.ÇEì‹MðMø‰Mð‹Uü‹B‰Eüëž‹MMðÆ¸‹å]ÃÌÌÌÌÌÌÌÌÌÌU‹ìƒì EøPMüQ‹U R‹EPè%ƒÄ‰Eôƒ}ôtƒ}üu3Àë‹Mü‹Eø‹å]ÃÌÌÌU‹ìƒì‹EPèa2…Àu3À銃} }h3'‹MQèbÌ3ÀërÇEø‹U‹B‰Eüƒ}üt%‹Mü‹UøQ9U r‹Eü‹MøH‰Mø‹Uü‹B‰EüëÕƒ}üu‹MÇ‹UǸë‹E‹Mü‰‹U +Uø‹E‰¸‹å]ÃÌÌÌÌÌÌÌÌU‹ìQÇEüë ‹EüƒÀ‰Eüƒ}ü}‹MükÉ 3ÒŠ‘¸•5s;Uu‹Eüëë׃Èÿ‹å]ÃÌÌÌU‹ìƒìLVWƒ} cu&‹Ef‹ˆ„€Í‹Uf‰Š„èF¸éá‹E PèƒÿÿÿƒÄ‰E܃}Üÿuh.'‹MQèIË3Àé·ƒ}…wh ¹5sÿ0p5sƒ=4¸5sthÇEàë ‹UàƒÂ‰Uà‹Eà;”—5s}K‹Mà‹4¸5sƒ<Št:h ¹5sÿ,p5s‹EP‹M Q‹Uà¡4¸5s‹ Qè49…Àu3Àé>h ¹5sÿ0p5së¡h ¹5sÿ,p5s‹UÜkÒ 3ÀŠ‚¹•5sƒà…ÀtHƒ}t ‹M¾…Òuh1'‹EPè~Ê3Àéìj‹MQUäRÿ]ÃÌÌÌÌÌÌU‹ìƒìLVWƒ} cu#‹Ef‹ˆ„fáÿû‹Uf‰Š„¸éõ‹E PèûÿÿƒÄ‰E܃}Üÿuh.'‹MQèÜÆ3Àé˃}…’h ¹5sÿ0p5sƒ=4¸5sthÇEàë ‹UàƒÂ‰Uà‹Eà;”—5s}K‹Mà‹4¸5sƒ<Št:h ¹5sÿ,p5s‹EP‹M Q‹Uà¡4¸5s‹ Qè‡A…Àu3ÀéRh ¹5sÿ0p5së¡h ¹5sÿ,p5s‹UÜkÒ 3ÀŠ‚¹•5sƒà…Àu3Àé‹MÜkÉ 3ÒŠ‘¹•5sƒâ…ÒtTƒ}t ‹E¾…Éuh1'‹URèõÅ3Àéä‹}UäƒÉÿ3Àò®÷Ñ+ù‹÷‹Á‹úÁéó¥‹Èƒáó¤MäQèÒ̓Äh`¹5sÿ0p5s‹UÜkÒ Š‚¹•5s4‹MÜkÉ ˆ¹•5s‹UÜkÒ Š‚¹•5s ‹MÜkÉ ˆ¹•5sƒ} …ñÇEØ”‘5sUä‰UÔ‹EÔŠˆMÓ‹UØ: u.€}Ót‹EÔŠHˆMÒ‹UØ:JuƒEÔƒEØ€}ÒuÌÇEÌëÀƒØÿ‰EÌ‹M̉Mȃ}ÈuH‹UÜkÒ 3Àf‹‚•5sƒà…Àuh`¹5sÿ,p5s3Àéæ‹MÜkÉ f‹‘•5sfƒò‹EÜkÀ f‰Â•5sëF‹MÜkÉ 3Òf‹‘•5sƒâ…Òuh`¹5sÿ,p5s3Àéž‹EÜkÀ f‹ˆÂ•5sfƒñ‹UÜkÒ f‰ŠÂ•5sé:ƒ} …ãÇEàë ‹EàƒÀ‰Eàƒ}à Å‹Mà‹””5s‰UÄEä‰EÀ‹MÀŠˆU¿‹EÄ:u.€}¿t‹MÀŠQˆU¾‹EÄ:PuƒEÀƒEÄ€}¾uÌÇE¸ëɃÙÿ‰M¸‹U¸‰U´ƒ}´u\‹EÜkÀ 3Éf‹ˆÂ•5s‹Ñ¸‹MàÓà#Ð…Òuh`¹5sÿ,p5s3À龋UÜkÒ ¸‹MàÓàf‹ŠÂ•5sf3È‹UÜkÒ f‰ŠÂ•5sëé(ÿÿÿëM‹EÜkÀ 3ÉŠˆ¹•5sƒá…Ét8‹UÜkÒ ƒº¾•5st)‹EÜkÀ ‹ˆ¾•5sQ‹URèN$ƒÄ‹EÜkÀ Ç€¾•5sh`¹5sÿ,p5s¸ë/‹MQè)…Àu3Àë‹UÇ‚F‹EP‹M Q‹URè*>_^‹å]ÃÌÌÌÌU‹ì‹EPèÔ(…Àuë ‹MQè ]ÃÌÌÌU‹ì‹EPè´(…Àu3Àë‹MQèã‹URè ƒÄ]ÃÌÌÌÌÌU‹ìƒìl‹E3Éf‹ˆ„ƒá…Ét?‹Uf‹‚„f%þÿ‹Mf‰„jdU˜R‹EPè°úƒÄ ‰E”ƒ}”~ëãƒ}”ÿu3Àë:‹MQèO´ÿÿƒÄ‰Eüƒ}üþt ƒ}üu3Àëƒ}üýuj‹URè¨óÿÿƒÄë˸‹å]ÃÌÌÌÌÌÌÌÌÌÌU‹ìƒì‹EPèá'…Àu3Àé‹M3ÒŠQƒâ…Òt ¸é‹E3ÉŠHƒá…Éu‹URè5Q…Àu3Àéã‹E3ÉŠHစÉt ‹URèŸáÿÿƒÄ‹EPèc¨ÿÿƒÄ‹MQè§‹URèÎþÿÿƒÄ…Àu3À陋EPè7¨ÿÿƒÄ‰Eüƒ}üt ƒ}üu3Àëz‹MQè˜þÿÿƒÄ…Àu3ÀëfëË‹URèâ ‹E‹H‰Mø‹Uø3Àf‹BTP‹Mø‹QRèÃ"‹EøfÇ@‹MøfÇ‹UøfÇB‹EÆ@‹MÇF‹Uø‹BÆF¸‹å]ÃÌÌÌU‹ìƒìPVWƒ}uh/'jè¶À3Àéƒ} t@ƒ} t‹} ƒÉÿ3Àò®÷уÁÿ‰MðëÇEð‹Eð‰Eüƒ}ü~h''jèpÀ3ÀéÈ‹M‰Mì‹Uìƒê‰Uìƒ}ì ‡š‹Eìÿ$…õŠ2sj‹MQèë!‹UüR‹E P‹MQÿj‹MƒÁ>Qè†!‹UüR‹E P‹MƒÁ>Qÿ‰Eøƒ}øu3Àë#‹U‹Eü‰Bn‹MŠ‘Z€Ê‹EˆZ¸‹å]ÂÌÌÌÌÌÌÌÌÌÌU‹ìƒìD‹E¿Hr‰Mô‹U¿‚‚‰EìÇEèÇEÜÆEüÆE؃} u ¸é²j‹M Q‹URjèL‰Eðƒ}ðu‹EPjè˜!鈋M‹Q3Àf‹B…À„•‹M‹Q3Àf‹B9E €‹M‹Q3Àf‹‹M‹Q3Éf‹J+Á9E b‹U R‹E‹H‹U‹B3Òf‹P‹AÂP‹MðQÿq5sƒÄ ‹U‹Bf‹HfM ‹U‹Bf‰H‹M‹Qf‹Bf+E ‹M‹Qf‰BÇEÀë‹E P‹MðQ‹URèi=‰EÀƒ}Àu‹EP‹MðQèà 鳋Uð‰Uø‹E3ÉŠƒù@| ÆEüé'‹Uè;U û‹EøŠˆMÌ‹UøƒÂ‰Uø‹EÌ%ÿ‹MøȉMø‹UÌâÿ‹EèL‰Mè‹Uè;U }Y‹EøŠˆMЋUøƒÂ‰Uø‹EÐ%ÿ‰E¼‹M¼ƒé"‰M¼ƒ}¼Mw(‹E¼3ÒŠ3”2sÿ$•+”2sMÜQŠUÐR‹EøPè=‰EÈëÆEüëÆEü‹Müáÿ…Ét‹Uð‰UøÇEèÇEÜë?‹EÈ+Eø‹MèT‰Uè‹EȉEø‹MøM܉Mø‹UèU܉Uè‹EìƒÀ‰Eì‹MôƒÁ‰Môéùþÿÿ‹Uè;U ~ÆEü‹Eð‰EøÇEèÇEÜ‹Müáÿ…É„ø‹U¿Br‰Eô‹M¿‘‚‰Uì‹Eè;E Õ‹MøŠˆUÌ‹EøƒÀ‰Eø‹MÌáÿ‹UøщUø‹EÌ%ÿ‹MèT‰Uè‹EøŠˆMØ‹UøƒÂ‰Uø‹EèƒÀ‰Eè‹MøƒÁ‰Mø‹UèƒÂ‰Uè‹EøŠˆMЋUøƒÂ‰UøEäPMÜQŠUÐR‹EøPè2-‰EÈ‹MÈ+Mø‹UèD ‰Eè‹MȉMø‹UøU܉Uø‹EèE܉Eè‹MìƒÁ‰Mì‹UØâÿ…Òt ‹EôƒÀ‰Eôéÿÿÿ‹Mè;M ~h'‹URè½·3ÀéK‹Eƒxtt>‹MìÁáQ‹U‹BtP‹MQèÆƒÄ ‰Eøƒ}øu‹URjèé‹E‹Mø‰Htë5j‹UìÁâR‹EPj蛋M‰At‹Uƒztu‹EP‹MðQèßéÏ‹U‹Bt‰EÔ‹Mð‰Mø‹U¿‚‚‰Eàë ‹MàƒÁ‰Mà‹Uà;Uìnjj‹EPjè8‹Mà‹UÔ‰Š‹Eà‹MÔƒ<u‹UR‹EðPèvéf‹MøŠˆUÌ‹EøƒÀ‰Eø‹MÌáÿ…ÉŽŒj‹UÌâÿƒÂR‹EPjèÕ‹Mà‹UÔ‹ Љ‹Uà‹EÔ‹ ƒ9u‹UR‹EðPèéÿ‹MÌáÿQ‹Uà‹EÔ‹ ‹R‹EøPèË‹Mà‹UÔ‹Š‹MÌáÿ‹Æ ‹EÌ%ÿ‹MøȉMø‹Uüâÿ…Òt%‹Eà‹MÔ‹‹EøŠˆJ‹UøƒÂ‰Uø‹EøƒÀ‰Eøë ‹Mà‹UÔ‹ŠÆ@‹Mà‹UÔ‹Š‹MøŠˆP‹EøƒÀ‰Eø‹Müáÿ…Éu(‹Uà‹EÔ‹ ƒÁQ‹Uà‹EÔ‹ ŠQR‹EøPèj‰Eøë*MäQ‹Uà‹EÔ‹ ƒÁQ‹Uà‹EÔ‹ ŠQR‹EøPè~*‰Eø‹Mà‹UÔ‹ŠƒxŽº‹Mà‹UÔ‹Š3ÉŠHƒùlt‹Uà‹EÔ‹ 3ÒŠQƒúj…¸jj‹EPjè_‹Mà‹UÔ‹ ЉA ‹Uà‹EÔ‹ ƒy u‹UR‹EðPè—釋Mà‹UÔ‹Š‹H ‰MÄ‹E䙹è÷ù‹UĈ‹E䙹è÷ùiÀè‹Uä+ЋEĈP‹MÄ‹UøŠˆAj‹MăÁQèN‹Uà‹EÔ‹ ‹QƒêR‹EăÀP‹MøƒÁQèûéÆj‹Uà‹EÔ‹ ‹QR‹EPj蜋Mà‹UÔ‹ ЉA ‹Uà‹EÔ‹ ƒy u‹UR‹EðPèÔéÄ‹Mà‹UÔ‹Š‹HQ‹Uà‹EÔ‹ ‹Q R‹EøP茋Mà‹UÔ‹Š3ÉŠHƒù/t&‹Uà‹EÔ‹ 3ÒŠQƒú't‹Eà‹MÔ‹3ÀŠBƒø#u#‹Mà‹UÔ‹Š‹HQ‹Uà‹EÔ‹ ‹Q R‹EPè`‹Mà‹UÔ‹Š‹MøH‰Møé}üÿÿ‹UðR‹EPè|ƒÄ‹Mf‹Uôf‰Qr‹Ef‹Mìf‰ˆ‚¸‹å]ÂŽ2s(Ž2sÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì‹Eƒxdt‹M‹QdR‹EPèуă} u‹MfÇAb‹UÇBd¸éj‹E P‹MQjèê‰Eüƒ}üu‹URjè6éë‹E‹H3Òf‹Q…Ò„•‹E‹H3Òf‹Q9U €‹E‹H3Òf‹‹E‹H3Àf‹A+Ð9U b‹M Q‹U‹B‹M‹Q3Éf‹J‹PÑR‹EüPÿq5sƒÄ ‹M‹Qf‹BfE ‹M‹Qf‰B‹E‹Hf‹Qf+U ‹E‹Hf‰QÇEøë‹U R‹EüP‹MQè5‰Eøƒ}øu‹UR‹EüPèaë‹M‹Uü‰Qd‹Ef‹M f‰Hb¸‹å]ÂU‹ìƒì ÇEôÇEì‹E ‰Eì‹MQèùƒ} u ¸éYj‹U R‹EPj蜉Eøƒ}øu‹MQjèèé/‹U‹B3Éf‹H…É„•‹U‹B3Éf‹H9M €‹U‹B3Éf‹‹U‹B3Òf‹P+Ê9M b‹E P‹M‹Q‹E‹H3Àf‹A‹JÈQ‹UøRÿq5sƒÄ ‹E‹Hf‹QfU ‹E‹Hf‰Q‹U‹Bf‹Hf+M ‹U‹Bf‰HÇEàë‹M Q‹UøR‹EPè¹3‰Eàƒ}àu‹MQ‹UøRèéZ‹Eø‰Eüƒ}ì~5‹Mü3ÒŠ‰Uä‹EüƒÀ‰Eü‹MüMä‰Mü‹UäƒÂ‹Eì+‰Eì‹MôƒÁ‰MôëÅj‹UôÁâR‹EPjèY‰Eðƒ}ðu‹MQ‹UøRè£éê‹Eø‰EüÇEèë ‹MèƒÁ‰Mè‹Uè;Uô‹Eü3ÉŠ‰Mä‹UüƒÂ‰Uüƒ}ävj‹EäƒÀP‹MQjèí‹Uè‹Mð‰‘‹Uè‹Eðƒ<u‹MQ‹UøRè+ëu‹EäP‹Mè‹Uð‹ŠP‹MüQèò‹Uè‹Eð‹ ‹U䯋EäP‹Mè‹Uð‹ŠP‹MQèû ‹UüUä‰UüéNÿÿÿ‹E‹Mð‰Hj‹Uf‹Eôf‰Bh‹MøQ‹URè ƒÄ¸‹å]ÂÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒìÇEôj‹E P‹MQjè"‰Eøƒ}øu‹URjènéJ‹E‹H3Òf‹Q…Ò„•‹E‹H3Òf‹Q9U €‹E‹H3Òf‹‹E‹H3Àf‹A+Ð9U b‹M Q‹U‹B‹M‹Q3Éf‹J‹PÑR‹EøPÿq5sƒÄ ‹M‹Qf‹BfE ‹M‹Qf‰B‹E‹Hf‹Qf+U ‹E‹Hf‰QÇEäë‹U R‹EøP‹MQè?1‰Eäƒ}äu‹UR‹EøPè™éu‹Mø‰Mü‹Uô;U N‹EüŠˆMì‹UüƒÂ‰Uü‹Eì%ÿ‹M‹Q$‹D‚ü‰Eð‹Müf¶‹Eðf‰P0‹MüƒÁ‰Mü‹Uð‹EüŠˆJ*‹UüƒÂ‰Uü‹EôƒÀ‰Eô‹Mð3ÒŠQ*ƒâ …Ò„µ‹EüŠˆMè‹UüƒÂ‰Uüj‹Eè%ÿƒÀP‹MQjè‹ ‹Uð‰B,‹Eðƒx,u‹MQ‹UøRèÏé«‹Eè%ÿP‹Mð‹Q,R‹EüPè‘‹Mèáÿ‹Uð‹B,Æ‹MèáÿQ‹Uð‹B,P‹MQè” ‹Uèâÿ‹EôL‰Mô‹Uèâÿ‹Eü‰Eü‹Mð3ÒŠQ*ƒâ…Òt‹Ef‹ˆDfƒé‹Uf‰ŠDé¦þÿÿ‹EøP‹MQèw ƒÄ¸‹å]ÂÌÌÌÌÌÌÌÌÌU‹ìƒì ‹E‹H3Òf‹Q…Ò„‹E‹H3Òf‹Qƒú|~‹E‹H3Òf‹‹E‹H3Àf‹A+Ѓú|`j‹M‹Q‹E‹H3Àf‹A‹JÈQUøRÿq5sƒÄ ‹E‹Hf‹QfƒÂ‹E‹Hf‰Q‹U‹Bf‹Hfƒé‹U‹Bf‰HÇEôëjMøQ‹URèè.‰Eôƒ}ôu3Àë‹E‹Mø‰H^¸‹å]ÂÌÌÌÌÌÌÌU‹ìƒì‹E‹H3Òf‹Q…Ò„‹E‹H3Òf‹Qƒú|~‹E‹H3Òf‹‹E‹H3Àf‹A+Ѓú|`j‹M‹Q‹E‹H3Àf‹A‹JÈQUüRÿq5sƒÄ ‹E‹Hf‹QfƒÂ‹E‹Hf‰Q‹U‹Bf‹Hfƒé‹U‹Bf‰HÇEðëjMüQ‹URè.‰Eðƒ}ðu3À锋E‹HZ‰Môƒ}ôt‹Uôƒzt ‹Eô‹H‰Môëæjj‹URjèÖ ‰Eøƒ}øu ‹EPjè"ëLƒ}ôu‹Mø‰Mô‹UƒzZu ‹E‹Mô‰HZë‹Uô‹Eø‰B‹Mô‹Q‰Uô‹Eôf‹Müf‰‹Uôf‹Eþf‰B¸‹å]ÂÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì j‹E P‹MQjèI ‰Eüƒ}üu‹URjè•éâ‹E‹H3Òf‹Q…Ò„•‹E‹H3Òf‹Q9U €‹E‹H3Òf‹‹E‹H3Àf‹A+Ð9U b‹M Q‹U‹B‹M‹Q3Éf‹J‹PÑR‹EüPÿq5sƒÄ ‹M‹Qf‹BfE ‹M‹Qf‰B‹E‹Hf‹Qf+U ‹E‹Hf‰QÇEàë‹U R‹EüP‹MQèf,‰Eàƒ}àu‹UR‹EüPèÀé ‹Mü‰MäÇEìÇEð‹Uì;U }>‹E䊈Mø‹UäƒÂ‰Uä‹Eø%ÿ‹MìT‰Uì‹Eø%ÿ‹MäȉMä‹UðƒÂ‰Uðëºj‹EðÁàP‹MQjèí‰Eôƒ}ôu‹UR‹EüPè7é„ÇEì‹Mü‰Mä‹Uì;Uð4jj<‹EPj誋Mì‹Uô‰Š‹Eì‹Môƒ<uIƒ}ìt!‹Uìƒê‰Uì‹Eì‹Mô‹R‹EPè# ƒÄëÙ‹MôQ‹URè ƒÄ‹EP‹MüQè±éþ‹Uì‹Eô‹ ‹U䊈A‹MäƒÁ‰Mä‹Uì‹Eô‹ ŠQˆUè‹Eì‹Mô‹3ÀŠBƒø~ ‹Mì‹Uô‹ŠÆ@‹Mì‹Uô‹Š3ÉŠHQ‹Uì‹Eô‹ Q‹UäRè! ‹Eì‹Mô‹3ÀŠB‹Mì‹Uô‹ ŠÆ‹Uì‹Eô‹ 3ÒŠQR‹Eì‹Mô‹R‹EPè‹Mèáÿ‹UäщUä‹EìƒÀ‰EìéÀþÿÿ‹M‹Uô‰Q$‹Ef‹Mðf‰H"‹Uf‹Eðf‰‚D‹MüQ‹URèƒÄ¸‹å]ÂÌÌÌÌÌÌÌÌU‹ìQÇEüë ‹EüƒÀ‰Eü‹Mü;MsDjj‹URjè‹Mü‹U ‰Š‹Eü‹M ƒ<u‹URjèS 3Àë‹Eü‹M ‹Çÿÿÿÿë«‹E ‹å] ÌÌÌÌÌU‹ìƒì,ÇEàfÇEèj‹E P‹MQj謉Eøƒ}øu‹URjèø éó‹E‹H3Òf‹Q…Ò„•‹E‹H3Òf‹Q9U €‹E‹H3Òf‹‹E‹H3Àf‹A+Ð9U b‹M Q‹U‹B‹M‹Q3Éf‹J‹PÑR‹EøPÿq5sƒÄ ‹M‹Qf‹BfE ‹M‹Qf‰B‹E‹Hf‹Qf+U ‹E‹Hf‰QÇEØë‹U R‹EøP‹MQèÉ(‰E؃}Øu‹UR‹EøPè# é‹Mø‰Mä‹U‹B$‰Eì‹Mà;M ƒ‹U3ÀŠ‚žƒøu.‹M3ÒŠ‘Ÿƒú|j¿Eè‹M싃 R‹EäEàPè§ë‹MäMà‹‰UÜ¿Eè‹Mì‹f‹EÜf‰B ¿Mè‹U싊‹MäMàŠQˆP$¿Eè‹Mì‹3ÀŠB$‰EÔ‹MÔƒé"‰MÔƒ}ÔX‡É‹EÔ3ÒŠZ¦2sÿ$•6¦2s¿Mè‹U싊Ç@&¿Mè‹U싊‹MäMàŠQˆP6¿Eè‹Mì‹‹EäEàŠHˆJ7‹UàƒÂ‰Uà錿Eè‹Mì‹‹EäEà‹H‰J&‹UàƒÂ ‰Uà‹EäEàf‹f‰Mô‹UàƒÂ‰Uàj¿EôƒÀP‹MQjèf¿Uè‹Mì‹‘‰B2¿Eè‹M싃z2u‹EP‹MøQèœ é—¿UôR‹EäEàP¿Mè‹U싊‹H2Qÿüéì‹M‹Q3Àf‹B…À„Ê‹M ‹Uü‹Š‹M‹Q3Éf‹J9­‹U ‹Eü‹ ‹U‹B3Òf‹‹E‹@3öf‹p+Ö9ƒ‹M ‹Uü‹Š‹Q‹U‹B‹M‹Q3Éf‹J‹PÑR‹E ‹Mü‹‹BPÿq5sƒÄ ‹M‹Q‹E ‹Mü‹f‹Jf‹U‹Bf‰H‹M‹Q‹E ‹Mü‹f‹Jf+‹U‹Bf‰HÇEÀë%‹M ‹Uü‹Š‹Q‹U ‹Eü‹ ‹QR‹EPèɉEÀƒ}Àu3ÀéÜ‹M ‹U苊3ÉŠH$ƒù/t‹U ‹Eè‹ 3ÒŠQ$ƒú'u%‹E ‹Mü‹3Àf‹P‹M ‹Uü‹Š‹HQ‹URèîñ‹E ‹Mè‹3ÀŠB$‰E¼‹M¼ƒé&‰M¼ƒ}¼Iw)‹E¼3ÒŠò³2sÿ$•ê³2s‹M ‹U苊‹M ‹Uü‹ Š‹P&‰‹Eƒ¸Jt7‹M‹‘J‹E ƒ<‚t%‹M¿‘D9U }‹E P‹MQèë…ÀuƒÈÿë¸^‹å]„³2s›³2sÌÌÌÌU‹ìƒì‹Eƒxt‹M‹QR‹EPè!ôƒÄƒ} Žj‹M ƒÁQ‹URjèPó‰Eüƒ}üu‹EPjèœùéé‹M‹Q3Àf‹B…À„•‹M‹Q3Àf‹B9E €‹M‹Q3Àf‹‹M‹Q3Éf‹J+Á9E b‹U R‹E‹H‹U‹B3Òf‹P‹AÂP‹MüQÿq5sƒÄ ‹U‹Bf‹HfM ‹U‹Bf‰H‹M‹Qf‹Bf+E ‹M‹Qf‰BÇEøë‹E P‹MüQ‹URèm‰Eøƒ}øu‹EP‹MüQèÇøë‹UüU Æ‹E‹Mü‰H¸‹å]ÂÌÌÌÌÌÌÌÌU‹ìQh ¹5sÿ0p5sƒ=4¸5suh ¹5sÿ,p5s¸ëLÇEüë ‹EüƒÀ‰Eü‹Mü; ”—5s}"‹Uü¡4¸5sƒ<uh ¹5sÿ,p5s¸ëëÊh ¹5sÿ,p5s3À‹å]ÃÌÌÌÌÌÌU‹ìQh ¹5sÿ0p5sƒ=4¸5su:j¡”—5sÁàPjjè”ñ£4¸5sƒ=4¸5suh ¹5sÿ,p5s‹MQjèÐ÷ëjÇEüë ‹UüƒÂ‰Uü‹Eü;”—5s}2‹Mü‹4¸5sƒ<Šu!‹Eü‹ 4¸5s‹U‰h ¹5sÿ,p5s¸ëëºh ¹5sÿ,p5sh-'‹EPèÆ3À‹å]ÂÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒìÇEüj‹E P‹MQjèÒð‰Eüƒ}üu3Àé\‹U‹B3Éf‹H…É„•‹U‹B3Éf‹H9M €‹U‹B3Éf‹‹U‹B3Òf‹P+Ê9M b‹E P‹M‹Q‹E‹H3Àf‹A‹JÈQ‹UüRÿq5sƒÄ ‹E‹Hf‹QfU ‹E‹Hf‰Q‹U‹Bf‹Hf+M ‹U‹Bf‰HÇEøë‹M Q‹UüR‹EPèø‰Eøƒ}øuj‹MüQèTö鉋U R‹EüP‹MQè~Œ‹U3Àf‹‚„%…ÀtN‹Mü9¢t!‹Uü:H| ‹Eü8H~ ‹Mü9‘Eu"h'‹URèO‹EüP‹MQè2ðƒÄ3Àë‹UüR‹EPèðƒÄ¸‹å]ÂU‹ìƒìÇEô‹E%ÿƒà‰Eüj‹M Q‹URjè4ï‰Eøƒ}øu‹EPjè€õ3Àéã‹M‹Q3Àf‹B…À„‹M‹Q3Àf‹Bƒø|~‹M‹Q3Àf‹‹M‹Q3Éf‹J+Áƒø|`j‹U‹B‹M‹Q3Éf‹J‹PÑR‹EøPÿq5sƒÄ ‹M‹Qf‹Bf‹M‹Qf‰B‹E‹Hf‹Qfƒê‹E‹Hf‰QÇEðëj‹UøR‹EPèW‰Eðƒ}ðu‹MQ‹UøRè±ô3Àé‹Eø¿စÉt‹Uf‹‚„ ‹Mf‰„‹Uø¿ƒà…Àt#‹M‹Uø‹B‰AV‹MŠ‘Z€Ê‹EˆZë$‹Máÿƒá…Éu‹UŠ‚Z$þ‹MˆZƒ}üu ‹UfÇB‹Eø¿ƒá…Ét=‹Uø¿ƒà…Àu‹MøƒytÇEô‹UfÇBëh'‹EPè>ÇEô‹Mø¿ƒâ…ÒuO‹EŠH€áï‹UˆJ‹E3ÉŠHƒá…Ét‹UŠB ‹MˆA‹UfÇBë‹EfÇ@‹MŠQ€Ê‹EˆP‹Mø¿ƒâ …Ò„‹EŠH€áý‹UˆJ‹E3ÉŠHƒá…Étq‹UŠB$÷‹MˆAƒ}üu ‹Uø¿ƒà…Àu‹MŠQ€Ê‹EˆP‹MfÇAƒ}üu‹UŠB$ï‹MˆAƒ}ôtƒ}üu‹UøR‹EPè6íƒÄ‹EôéE‹Mø¿ƒâ…Ò„ ‹EŠH€É‹UˆJƒ}üu:‹EŠH€áû‹UˆJ‹Eø¿ƒá …Ét‹U3ÀŠBƒà…Àu‹MŠQ€Ê‹EˆP‹Máÿùýu&ƒ}ôtƒ}üu‹UøR‹EPè¡ìƒÄ‹Eôé°ë‹MøQ‹URè‡ìƒÄ¸ûÿÿÿ锃}ôu‹EøP‹MQègìƒÄ3Àëz‹U¿Bƒøtƒ}üuS‹MáÿùýuB‹UøR‹EPè0ìƒÄƒ}üu¸ë:‹Mº;Q,À÷Ø…Àu j‹MQèÂϸþÿÿÿë‹UøR‹EPèîëƒÄ¸ûÿÿÿ‹å]ÂU‹ìQ‹E %ÿ‰Eü‹Müƒé"‰Müƒ}üX‡ÿ‹Eü3ÒŠê½2sÿ$•ʽ2s‹MƒÁ‰M‹U3ÀŠiÀè‹M3ÒŠQ‹M‰‹UƒÂ‰U‹E3ÉŠ‹U‰ ‹EƒÀ‰E饋MÇ‹UÇ鎋EÇ‹MÇëz‹UÇ‹EÇëf‹MÇ‹UÇëR‹E3ÉŠ‹U‰ ‹EƒÀ‰E‹M3ÒŠ‹E‰‹MƒÁ‰Më&‹U‹E‹‰ ‹UƒÂ‰U‹E‹M‹‰‹EƒÀ‰E‹E‹å]›½2so½2s½2s3½2sG½2s[½2sÔ¼2sÁ½2sÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì8VÆEìŠE ˆEЀ}Ð9t€}Ðã„õéG‹M‹Q3Àf‹B…À„±‹Mìáÿ‹U‹B3Òf‹P;Ê”‹Eì%ÿ‹M‹Q3Éf‹ ‹U‹R3öf‹r+Î;Áo‹Eì%ÿP‹M‹Q‹E‹H3Àf‹A‹JÈQUðRÿq5sƒÄ ‹E‹Hf¶Uìf‹Af‹M‹Qf‰B‹E‹Hf¶Uìf‹Af+‹M‹Qf‰BÇEÌë‹Eì%ÿPMðQ‹URèo ‰Ẽ}Ìu3Àéeé[j‹EP‹MQjèYè‰Eèƒ}èu3Àé?‹U‹B3Éf‹H…É„•‹U‹B3Éf‹H9M€‹U‹B3Éf‹‹U‹B3Òf‹P+Ê9Mb‹EP‹M‹Q‹E‹H3Àf‹A‹JÈQ‹UèRÿq5sƒÄ ‹E‹Hf‹QfU‹E‹Hf‰Q‹U‹Bf‹Hf+M‹U‹Bf‰HÇEÈë‹MQ‹UèR‹EPè ‰Eȃ}Èu‹MèQ‹URè)èƒÄ3Àëh‹Eè3ÉŠƒùuA‹Uè3ÀŠBP‹MèƒÁQUÔRÿ‹MQ•@ôÿÿRÿ|q5s…Àu3Àë%ÿ\p5s…Àu‹EP‹MQÿxq5s…Àu3À븋å]ÃÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒìjEüPj"‹MQèÿÿÿƒÄ…Àu3Àë;ŠUüˆUø€}ø0t€}ø1t€}ø2të‹E fÇë‹M fÇë‹U fǸ‹å]ÃÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒìjEüPj#‹MQè©þÿÿƒÄ…Àu3Àë+ŠUüˆUø€}ø0t€}ø1t ë‹E fÇë‹M fǸ‹å]ÃÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒìjEüPj‹MQèIþÿÿƒÄ…Àu3Àë7¾Uü‰Uø‹Eøƒè0‰Eøƒ}øw‹Møÿ$íÇ2s‹U fÇë‹E fÇ ¸‹å]ÃÒÇ2sÜÇ2sÒÇ2sÜÇ2sÌÌÌU‹ìj ‹E Pj‹MQèÜýÿÿƒÄ…Àu3Àë¸]ÃÌÌÌÌÌÌÌÌÌÌU‹ìj‹E Pj‹MQè¬ýÿÿƒÄ…Àu3Àë¸]ÃÌÌÌÌÌÌÌÌÌÌU‹ìj‹E Pj‹MQè|ýÿÿƒÄ…Àu3Àë¸]ÃÌÌÌÌÌÌÌÌÌÌU‹ìƒìÇEøÇEüEøPhjh¸‘5sh€ÿp5s…Àu]MüQUðRjjh¨‘5s‹EøPÿp5s‰Eô‹MøQÿ p5sƒ}ôu ‹UüÆDðë3Àë#EðPh¤‘5sÿ q5sƒÄ…Àt3Àë ¸ë3À‹å]ÃÌÌÌÌÌÌÌÌÌÌU‹ì]ÃÌÌÌÌÌÌÌÌÌÌÌU‹ìƒìÇEøÇEüǘ¹5sEøPhjh¸‘5sh€ÿp5s…Àu\MüQUðRjjhè‘5s‹EøPÿp5s‰Eô‹MøQÿ p5sƒ}ôu ‹UüÆDðëë"EðPh¤‘5sÿ q5sƒÄ…Àtë ǘ¹5s‹å]ÃÌÌÌU‹ìƒìÇEøÇü¹5súEøPhjh¸‘5sh€ÿp5s…ÀuMMüQUðREìPjhü‘5s‹MøQÿp5s‰Eô‹UøRÿ p5sƒ}ôuƒ}ìu}ðèvƒ}ðÿu‹Eð£ü¹5s‹å]ÃÌÌÌÌÌÌÌÌÌU‹ìQÇEüƒ}uë/‹E‹H‹Q@‰Uü‹Eƒx t‹MüQ‹U‹B Pè( ‹MÇA‹å]ÂÌÌÌÌÌÌÌÌU‹ìƒìDVÇEðfÇEÜ‹E‹H‰MàfÇEäÇEèÇEøÇEü‹Uð;UM‹Eà3Éf‹H‹Uà3Àf‹;ÈŒr‹M+Mð‹Uà3Àf‹BT;È} ‹M+Mð‰MØë ‹Uà3Àf‹BT‰EØf‹MØf‰Mô‹Uà3Àf‹B…Àu+‹Môáÿÿƒù~‹Uôâÿÿ‰UÔëÇEÔf‹EÔf‰Eô‹Màƒy t ‹Uàƒz u5ƒ}øu*ƒ}øþt$‹Eàƒx uf‹MÜQ‹URèăċEàÇ@ éæ‹MàÇA ƒ}t3jj‹URè%´ÿÿƒÄ …Àt‹E‹ˆ¢‰MÐë ‹0¸5s‰UЋEЉEÌë ‹ 0¸5s‰MÌUøR‹EÌ%ÿÿP‹Mà3Òf‹QTR‹Eô%ÿÿP‹Mà‹QR‹E‹H Q‹U‹BÿP$ƒÄf‰EÜ‹MŠ‘Z€Ê‹EˆZ‹MÜáÿÿ…Éuƒ}øt ‹UàÇB ë(ƒ}ütf‹EÜP‹MQèàƒÄ‹UàÇB ëéDþÿÿƒ}ø…Ñ‹E3ÉŠƒù@ŒÁ‹Uà3ÀŠBXƒø„°‹Mà3ÒŠQX…Ò„ ƒ}t2jj‹EPè³ÿÿƒÄ …Àt‹M‹‘¢‰UÈë¡0¸5s‰EÈ‹MȉMÄë ‹0¸5s‰UÄEøP‹MÄáÿÿQ‹Uà3Àf‹BTP‹Mà3Òf‹QTR‹Eà‹HQ‹U‹B P‹M‹QÿR$ƒÄf‰EÜ‹EŠˆZ€É‹UˆŠZ‹EàÇ@ ‹MÜáÿÿ‹U+Uð;Êéƒ}øþ…“ƒ}üuhh('‹EPèÌy‰Eèƒ}èué&ýÿÿƒ}èuD‹M3ÒŠQƒâ…Òu‹EPè …Àu3Àé[‹MŠ‘Z€Ê‹EˆZÇEüéÜüÿÿë%‹MŠ‘Z€â÷‹EˆZ‹MQè4üÿÿ3Àéƒ}øtFƒ}üu9}øÿÿÿu0h5'‹URè*yƒøuéˆüÿÿh'‹EPèyƒøuépüÿÿ3ÀéÇ‹Mà3Òf‹Q…Ò…À‹Eà3Éf‹‹Uà3Àf‹B+ȃù`‹Mà3Òf‹Q…Ò„‹Eà3Éf‹‹Uà3Àf‹B+È…ÉtT‹MàƒytK‹Uà3Àf‹B‹Mà‹QÐ…Òt6‹Eà3Éf‹‹Uà3Àf‹B+ÈQ‹Mà3Òf‹Q‹Eà‹HÊQ‹Uà‹BPÿq5sƒÄ ‹Mà3Òf‹‹Eà3Éf‹H+Ñ‹Eàf‰‹MàfÇA‹Uà3Àf‹¹+Èf‰MôUøRj‹Eô%ÿÿP‹MôáÿÿQ‹Uà3Àf‹‹Mà‹QÐR‹E‹H Q‹U‹BÿP$ƒÄf‰EÜ‹MÜáÿÿ…Éu!ƒ}øtƒ}üuh'‹URè»w3Àéz‹EÜ%ÿÿ‹Môáÿÿ;Á}ƒ}üuh'‹URè‹w3ÀéJ‹Eàf‹fMô‹Uàf‰ ‹Eà3Éf‹H‹Uà‹B‹UàŠDˆBX‹Mà3Òf‹Q‹Eà‹HʉMì‹Uì3ÀŠ…Àt ‹Mì3ÒŠƒú~‹EÆ4ë8‹M3ÒŠƒúB}‹EÆ@ë$‹MŠˆUÀ€}À4t€}À@t€}ÀBtëë‹EÆ@‹M3ÒŠƒú@|G‹Eì3ÉŠ‰M¼‹U¼ƒê‰U¼ƒ}¼w'‹E¼ÿ$…]Ó2s3À逋MŠQ€âý‹EˆPéúÿÿë3Àéc‹Mà3Òf‹Q‹Eà‹H3Àf‹DÁø%ÿ‹Mà3Òf‹Q‹Mà‹I3öf‹tÁæ ƃè‹Uàf‰B‹Eà3Éf‹H‹Uà3Àf‹BTƒè;È~ƒ}üuh'‹MQè-v3Àéì‹Uà3Àf‹‹Mà3Òf‹QƒÂ;ÂÈ‹Eà3Éf‹HƒÁ‹Uà3Àf‹+Èf‰MôMøQj‹UôâÿÿR‹Eô%ÿÿP‹Mà3Òf‹‹Eà‹HÊQ‹U‹B P‹M‹QÿR$ƒÄf‰EÜ‹EÜ%ÿÿ…Àu!ƒ}øtƒ}üuh'‹MQè‰u3ÀéH‹UÜâÿÿ‹Eô%ÿÿ;Ð}ƒ}üuh'‹MQèYu3Àé‹Uàf‹fEô‹Màf‰‹Uàf‹Bf‹Màf‰A‹Uà3Àf‹‹Mà3Òf‹Q+Âf‰Eä‹E+Eð‹Mäáÿÿ;Á ‹U+Uðf‰Uä‹Eà3Éf‹H‹Uäâÿÿ;Ê} ‹Eàf‹Hf‰Mä‹Uäâÿÿ…ÒtV‹Eä%ÿÿ…ÀtJ‹M Mð…Ét@‹Uà3Àf‹B‹Mà‹QÐ…Òt+‹Eä%ÿÿP‹Mà3Òf‹Q‹Eà‹HÊQ‹U UðRÿq5sƒÄ ‹Eàf‹HfMä‹Uàf‰J‹Eàf‹Hf+Mä‹Uàf‰J‹Eä%ÿÿ‹MðȉMðé§÷ÿÿ¸^‹å] êÐ2sêÐ2sìÐ2sìÐ2sìÐ2sìÐ2sÏÐ2sÖÐ2sÌÌÌU‹ìƒì‹E‹H‰Mø‹Uøf‹E f‰‹MøfÇA‹Uø‹B‰Eü‹Mø‹Uø‹B‰A‹Mø‹Uü‰Q‹EŠˆZ€áû‹UˆŠZ‹å]ÃÌÌÌÌÌÌÌU‹ìƒì$‹E‹H‰MðÇEü‹Uð‹B‰Eø‹M3ÒŠƒú@}\‹Eø3ÉŠƒùu(‹U âÿÿÁúâÿ‹E %ÿÿÁà ЋMøf‰Që&‹UâÿÿÁúâÿ‹E%ÿÿÁà ЋMøf‰Që`‹U âÿÿÁúâÿ‹E %ÿÿÁà ЋMøf‰Q‹UøÆB‹EøfÇ@‹MøŠQ€Â‹EøˆP‹MøÆA‹Uâÿÿ…Òt‹EøÆ@‹Máÿÿ…É„@ƒ}t3jj‹URè%«ÿÿƒÄ …Àt‹E‹ˆ¢‰Mèë ‹0¸5s‰Uè‹Eè‰Eäë ‹ 0¸5s‰Mäƒ}ä…ô‹Uƒz„ç‹Eð‹H‰Mô‹Uð‹Eð‹H‰J‹Uð‹Eô‰Bƒ}t3jj‹MQ讪ÿÿƒÄ …Àt‹U‹‚¢‰Eàë ‹ 0¸5s‰Mà‹Uà‰UÜë¡0¸5s‰EÜMüQ‹UÜâÿÿR‹Eð3Éf‹HTQj¿U R‹Eð‹HQ‹Uð‹BP‹M‹Q R‹E‹HÿQ,ƒÄ ‹Uðf‰‹Eð3Éf‹…Éu ‹UðÇB ë ‹EðÇ@ ‹MðfÇA‹UðfÇB‹EðfÇ@é¶MüQ¿U R‹Eð‹HQ‹U‹B P‹M‹QÿR(ƒÄ%ÿÿ‰Eì‹EðÇ@ ‹Mð‹Q‰Uô‹Eð‹Mð‹Q‰P‹Eð‹Mô‰Hº…Òt+‹Eðƒxt"‹Mðƒytj‹Uð‹BP‹Mð‹QRÿq5sƒÄ ‹EðfÇ@‹M áÿÿ9Mìtƒ}üth)'‹URèÆp3Àëƒ}üth)'‹EPè®p3À븋å] ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒìÆEôÆEõfÇEöfÇEøÆEúÆEû‹E3ÉŠƒù@} ÆEôAÇEðëÇEðUüR‹Eð%ÿÿPMôQ‹U‹B P‹M‹QÿR0ƒÄ%ÿÿ;Eðtƒ}ümu¸ë&h+'‹EPèp3Àë‹MŠQ€Ê‹EˆP¸‹å]ÂÌÌÌÌÌÌÌU‹ìQEüP‹M Q‹URÿUƒÄ ‹å] ÌÌÌÌU‹ìQEüP‹MQÿU ƒÄ‹å]ÂÌÌÌÌÌÌÌÌU‹ìQEüP‹M Q‹U‹B PÿUƒÄ …Àuƒ}üth5'‹MQèoo3À븋å] U‹ìÿU%ÿÿ]ÂÌU‹ì‹E‹HƒyLt!‹UR‹EP‹M Q‹U‹B P‹M‹QÿRLƒÄë3À]ÂÌÌÌÌÌÌÌÌÌÌV‹t$W‹|$Ç‹Ff‹Hf…ÉtFfƒxr?3Òáÿÿf‹+уú|-‹@jÁL$PQÿq5s‹FƒÄ fÿ@‹F_^fÿHŠD$ÂT$jRVèÑñÿÿ…Àu‰ŠD$_^ÂU‹ìƒì‹EÇ‹M áÿƒá0ƒù0u ‹M áÿƒá ÁùºÓâ‹E‰é@‹M áÿƒá …É„,‹U âÿƒâ€…Òu‹E %ÿ=¡t‹M áÿƒù*u ÇEüë/‹U âÿƒâ…Òu‹E %ÿƒà…Àt ÇEüëÇEü‹M‹Q3Àf‹B…À„•‹M‹Q3Àf‹B9Eü€‹M‹Q3Àf‹‹M‹Q3Éf‹J+Á9Eüb‹UüR‹E‹H‹U‹B3Òf‹P‹AÂP‹MQÿq5sƒÄ ‹U‹Bf‹HfMü‹U‹Bf‰H‹M‹Qf‹Bf+Eü‹M‹Qf‰BÇEøë‹EüP‹MQ‹URèMðÿÿ‰Eøƒ}øu3À븋å] ÌÌÌÌÌU‹ìƒì ‹E‹H‰Môƒ}„ð‹Uô3Àf‹B‹Mô3Òf‹QT;Âumj‹Eôf‹HQ‹URèùÿÿ…Àu3ÀéÁ‹E3ÉŠƒù@}A‹Uô‹B‰Eü‹Mü3ÒŠƒút‹EüÆë‹MüŠQ€Â‹EüˆP‹MüŠQ€Ê‹EüˆP‹MüÆëh‹Uô3Àf‹BT‹Mô3Òf‹Q+‰Eø‹E;Eøs‹M‰Mø‹UøR‹Eô3Éf‹H‹Uô‹BÁP‹M Qè Í‹Uôf‹BfEø‹Môf‰A‹U+Uø‰U‹E Eø‰E éÿÿÿ¸‹å] ÌÌÌÌÌÌÌÌÌÌÌÌU‹ìQ‹E‹H‰Mü‹Uü3Àf‹B…À~!‹Müf‹QR‹Eüf‹HQ‹URèý÷ÿÿ…Àu3À븋å]ÂÌÌÌÌÌÌÌÌÌÌU‹ì‹EPÿPp5sf3À]ÂÌÌÌÌÌÌÌÌÌÌÌÌU‹ì‹EPèÔÿÿÿ]ÂU‹ìQ‹E3ÉŠ…É„À‹U3ÀŠƒø0|‹M3ÒŠƒú9Ž–‹E3ÉŠƒù+t ‹U3ÀŠƒø-u ‹MƒÁ‰M벋U3ÀŠƒø uës‹M ‰Mü‹Uüƒê0‰Uüƒ}üëC3Àë?ƒ} u¸zë2ƒ} u¸<ë%3Àë!ƒ} u¸:ëƒ} u¸=ë3Àë‹E‹å]Ã?Þ2sjÞ2sˆÞ2s¦Þ2sÄÞ2sÌÌÌÌÌÌÌU‹ìQƒ}uh4'‹EPèHhƒÈÿ鯋MQ‹U RèþÿÿƒÄ‰E ƒ} t‹E P‹MQèêýÿÿƒÄ‰Eƒ}uh '‹URèhƒÈÿégƒ}tƒ}u‹E P‹MQ‹UR‹EPèw éAƒ} ÿ|ƒ}ÿ}h '‹MQè¸gƒÈÿé‹U‰Uü‹Eüƒè"‰Eüƒ}üX‡õ‹Uü3ÉŠŠ7â2sÿ$â2s‹E P‹MQ‹UR‹EP‹MQ‹U R‹EPè¤DÿÿƒÄéË‹M Q‹UR‹EP‹MQ‹UR‹E P‹MQèë8ƒÄ颋U R‹EP‹MQ‹UR‹EP‹M Q‹URèâ>ƒÄéy‹E P‹MQ‹UR‹EP‹MQ‹U R‹EPèéƒÄéP‹M Q‹UR‹EP‹MQ‹UR‹E P‹MQè@EƒÄé'‹U R‹EP‹MQ‹UR‹EP‹M Q‹URè§JƒÄéþ‹E P‹MQ‹UR‹EP‹MQ‹U R‹EPè~OƒÄéÕ‹M Q‹UR‹EP‹MQ‹UR‹E P‹MQèåSƒÄ鬋U R‹EP‹MQ‹UR‹EP‹M Q‹URè|YƒÄ郋E P‹MQ‹UR‹EP‹MQ‹U R‹EPè£<ƒÄë]‹M Q‹UR‹EP‹MQ‹UR‹E P‹MQè̓Äë7‹U R‹EP‹MQ‹UR‹EP‹M Q‹URè×UƒÄëh '‹EPè”eƒÈÿ‹å]ïà2s4à2sØà2sSá2sá2s¢á2sÈá2s]à2s†à2s*á2s à2s|á2sîá2s      U‹ìQ‹E‰Eü‹Müƒé"‰Müƒ}üXwx‹Eü3ÒŠjã2sÿ$•*ã2s¸ëb3Àë^¸ëW¸ëP¸ëI¸ëB¸ë;¸ë4¸ë-¸ë&¸ ë¸ ë¸ ë¸ ë ¸ ëƒÈÿ‹å]ÂÔâ2sÆâ2sÍâ2séâ2sÂâ2sÛâ2s÷â2sââ2sã2s ã2sþâ2sã2sðâ2s»â2sã2s!ã2s   ÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì‹EPè±þÿÿ‰Eø‹M Qè¥þÿÿ‰Eüƒ}üÿtƒ}øÿu3Àë‹UøÁâ‹Eü3ÉŠŒ¸”5s‹Á‹å]ÃÌÌÌÌÌÌÌÌÌÌU‹ìQƒ}}3Àë%‹EƒÀ4™¹d÷ù‰Eü‹EÁø+Eü‹UüƒÂÁú‹å]ÂÌÌÌÌÌÌÌU‹ì‹E%€yHƒÈü@…Àu‹E™¹d÷ù…Òu‹E™¹÷ù…Òu¸ë3À]ÂÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì ÇEüÇEøÇEôë ‹EôƒÀ‰Eôƒ}ô ‹‹Mô‹U ;Ä’5s~w‹Eô‹M ; …È’5sh‹Uô‹E +•Ä’5s‰Eø‹MôƒÁ‰Mü‹URè@ÿÿÿ…Àt@ƒ}ô|:‹Eøƒè‰Eøƒ}øu+‹Müƒé‰Müƒ}ôu ÇEøë‹U ƒê‹Eô+…À’5s‰Uøëébÿÿÿ‹M‹Uü‰‹E‹Mø‰‹å]ÂÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì }F.ÿÿ}3Àëi‹EºÑ‰E‹E™¹m÷ù‰Eø‹UøRè[þÿÿ‰Eô‹EøiÀmEô‹M+ȉMüƒ}ü|ë ‹Uøƒê‰UøëÍ‹EøÙ‹M ‰‹UüƒÂ‹E‰¸‹å] ÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ì‹EÆ*‹MÆA]ÂÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒ} t ‹E PèÎÿÿÿh'‹MQè0aƒÈÿ]ÂÌÌÌÌÌÌÌÌÌU‹ìƒì‹E‰Eô‹Môƒé0‰Môƒ}ôw?‹Eô3ÒŠëç2sÿ$•Óç2sÇEøë+ÇEøë"ÇEø ëÇEøëÇEøë3Àéüj‹MøƒÁQ‹URjèëÀ‰Eüƒ}üu‹EPjè7Ç3ÀéÍ‹M‰Mð‹Uðƒê0‰Uðƒ}ð‡­‹Mð3ÀŠè2sÿ$…úç2sj ‹UüR‹E 3ÉŠQÿ$q5sƒÄ éƒj ‹UüR‹E 3ÉŠQÿ$q5sƒÄ ëjj ‹UüR‹E ¿Qÿ$q5sƒÄ ëRj ‹UüR‹E ‹Qÿ0q5sƒÄ ë;‹UüRj‹E ‹HQ‹Rÿ,q5sƒÄë ‹EüPj‹M ÙƒìÝ$ÿ,q5sƒÄë3Àë‹Eü‹å] æ2sÁæ2s¦æ2s¯æ2s¸æ2sÊæ2sGç2s+ç2s`ç2sxç2sªç2sç2sÆç2sÌÌÌÌÌÌÌÌÌÌÌU‹ìQ‹E‰Eü‹Müƒé0‰Müƒ}üJw_‹Eü3ÒŠàè2sÿ$•°è2s¸ëH¸ëA¸ë:¸ë3¸ë,¸ë%¸ë¸ë¸ë¸ë ¸ë3À‹å]Âbè2sŒè2siè2spè2s¡è2s“è2s~è2s…è2swè2s[è2sšè2s¨è2s     ÌÌÌÌÌU‹ìƒìƒ}uƒ}} ÇEøë‹E‰Eø‹M‰Mô‹Uôƒê"‰Uôƒ}ôX‡ ‹Mô3ÀŠÏê2sÿ$…“ê2sÇEüé‚ÇEüëyƒ}ÿu ÇEü ëÇEüëaÇEüëXÇEüëOÇEüëFÇEüë=ÇEü ë4ÇEüë+ÇEüë"ÇEüëÇEüëÇEüëÇEüƒ}uh‹U‰Uð‹Eðƒè"‰Eðƒ}ð w5‹Uð3ÉŠŠ0ë2sÿ$(ë2sƒ}uh'jèG]3Àë@‹E Ƹë3‹MQèÍýÿÿ‰Eø‹UøR‹E Pè;‹Eøë‹M Q‹UR‹EüP‹MQè“ü‹å]©é2s‘é2s²é2sÖé2s»é2sÄé2sê2sñé2sßé2sèé2sÍé2s|é2sˆé2súé2s ê2s    7ê2sZê2sÌÌ‹L$‹€8t‹Š€ú0|€ú9~@‰€8uê‹ Š<0| <9¸Â3À‹T$‹L$3ÀSVˆ‹1€>t‹1Š€û0|€û9ˆ‹BC‹ó‰@€>uâ^Æ[ÂSUV‹t$W€>tC‹\$€;t:SVè3bƒÄ…Àu.‹ûƒÉÿò®Š÷ÑI„À‹ùt‹-4q5sWSVÿÕƒÄ …ÀtŠFF„Àuì3À_^][‹Æ_^][ƒìUV‹t$3íW‹=Dq5sŠÆD$„ÀtH¡@q5sƒ8~¾hQÿ׃Äë¡Hq5s¾‹f‹Q%…Àu€> u €~ tþD$ŠFF„Àu¸€>tB‹@q5sƒ:~¾hPÿ׃Äë‹Hq5s¾‹f‹H%…Àtƒý} ŠˆL, EFë¾…íÆD, t&3ÿ¾¹5sT$ VRèÉþÿÿL$ ;ÁtƒÆGþT¹5s|á‹L$_^3ÀÆ]ƒÄ‹T$ŠD$ˆG_^]ƒÄ‹D$ ƒì,‹T$0L$SUVWPjQR3ÿ3í3Ûè]…Àu _^]ƒÈÿ[ƒÄ, öø¹5suJ Àº5s„ÀtD$hÀº5sPè+þÿÿ…Àt ¿‹÷ë) ¼5s„ÀtL$h¼5sQèþÿÿ…Àt ¿3öë‹t$HT$h@º5sRè6`ƒÄ…Àt1½D$ƒý‰D$H……L$HQè?ýÿÿ…Àu_^]ƒÈÿ[ƒÄ, …ÿuÐ_^]ƒÈÿ[ƒÄ, T$D$HRPèNýÿÿ‹-äp5sL$QÿՃąÿuƒø s ë;…öuƒø u3öƒè ë…ötƒø u3Àƒÿuƒø v _^]ƒÈÿ[ƒÄ, …öu»ÁÅ@€€€€ÀD$HÁâPÚè—üÿÿ…Àt3L$T$HQRèÄüÿÿD$PÿՃăø u NT$;òwòFþL$;Áva~ÿhÀº5sWè†ùÿÿ…Àuh¼5sWèwùÿÿ…Àt@ƒîT$;òv€> u ND$;ðwòŠFV< uƒÉÿ3Àò®÷Ñ+ù‹Á‹÷‹úÁéó¥‹Èƒáó¤L$h@º5sQèt[Š Àº5sƒÄ„É‹ðt…ÀuT$hÀº5sRèùÿÿ‹ðŠ ¼5s„Ét…ÀuD$h¼5sPèãøÿÿ‹ð…Àu3Ûë*€8 tL$;Át ŠHÿH€ù uù t „Ét ŠNF€ù uó‹Œ$ƒù…;Ù…¼T$;Âu+Š3ÿ„À‹Öt < uŠBB„Àuô€:u_^]ƒÈÿ[ÄÂT$‹øŠ‹¬$„À‹Ít;×t ˆŠBAB„ÀuñÆ ŠA‹Æ„Òt €ú uŠP@„ÒuóŠ„Òt ˆŠPA@„ÒuõÆ‹ýƒÉÿ3Àò®÷ÑID)ÿŠL)ÿ€ù u ŠHÿH€ù t÷_^Æ@]¸[ÄŠL$‹õ€ù D$u± „Ét ŠH@N€ù tò‹¼$VPWÿ_^]¸[ăùu!…Ût‹Œ$;Æt ŠˆA@;ÆuöƸ_^][ăì‹D$(SU‹l$4V‹t$0W‹|$0ÇEÙÇÇŠ„ÀÆD$ÆD$„ÔL$QWèw÷ÿÿ…À‰D$¿ø¹5sƒâ@…Òu%‹EE ‹MM ŠˆP‹EE Æ0‹M ƒÁ‰M ë ‹U ƒÂ‰U ë ‹E ƒÀ‰E ‹E ]ÃÌÌÌÌÌU‹ìVW¿ø¹5sƒà…ÀuY‹MƒékÉÁ¹5s‹ù‹UU ƒÉÿ3Àò®÷Ñ+ù‹÷‹Á‹úÁéó¥‹Èƒáó¤‹}ƒïkÿǹ5sƒÉÿ3Àò®÷уÁÿ‹U щU ëcj ‹EE P‹MQÿ0q5sƒÄ ƒ} }>¿ø¹5sƒâ@…Òu%‹EE ‹MM ŠˆP‹EE Æ0‹M ƒÁ‰M ë ‹U ƒÂ‰U ë ‹E ƒÀ‰E ‹E _^]ÃÌÌÌÌÌÌÌÌÌÌU‹ìj ‹EE P‹MQÿ0q5sƒÄ ¿ø¹5sƒâƒúu ‹E ƒÀ‰E ë,‹MM ‹UU ŠBˆ‹MM ‹UU ŠBˆA‹M ƒÁ‰M ‹E ]ÃÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì VWÇEø‹E ‰Eü¿ ø¹5sƒá…Éu'ƒ} ~ ‹Uüƒê ‰Uüƒ} u¾Àº5s…ÀtÇEü ‹}ƒÉÿ3Àò®÷уÁÿ‰Møƒ}ü }9‹MMøÆ ‹UøƒÂ‰Uøj ‹EEø‰Eô‹MôQ‹UüR‹EøƒÀ‰Eøÿ0q5sƒÄ ëj ‹MMøQ‹UüRÿ0q5sƒÄ ‹EøƒÀ‰Eø‹MMøQj‹URè4ƒÄ ‹MøȉMøƒ}tƒ}u‹UUøRj‹EPè ƒÄ ‹MøȉMøƒ}u‹UUøRj‹EPèèƒÄ ‹MøȉMø¿ø¹5sƒâ…Ò…ªƒ} |P¾¼5s…ÀtE¿¼5s‹MMø‹ÑƒÉÿ3Àò®÷Ñ+ù‹÷‹Á‹úÁéó¥‹Èƒá󤿼5sƒÉÿ3Àò®÷уÁÿ‹UøщUøëTƒ} }N¾Àº5s…ÀtC¿Àº5s‹MMø‹ÑƒÉÿ3Àò®÷Ñ+ù‹÷‹Á‹úÁéó¥‹Èƒáó¤¿Àº5sƒÉÿ3Àò®÷уÁÿ‹UøщUøƒ} ÿu ‹EEøÆ‹Eø_^‹å]ÂÌÌÌÌÌÌÌU‹ìƒì VWƒ}| }ç~3À錋EŠ @º5sˆ‹UƒÂ‰Uj EôP‹MQÿ0q5sƒÄ ÇEüë ‹UüƒÂ‰Uü}ôƒÉÿ3Àò®÷уÁÿ‹E +Á9Eü}‹MÆ0‹UƒÂ‰UëÍ}ô‹UƒÉÿ3Àò®÷Ñ+ù‹÷‹Á‹úÁéó¥‹Èƒáó¤‹E ƒÀ_^‹å]ÃU‹ìƒìÇEüÇEøë ‹EøƒÀ‰Eø‹Mø;M }1‹UUø3ÀŠ3ÉŠ ¸¹5s;Át‹UUü‹EEøŠˆ ‹UüƒÂ‰Uü뾋Eü‹å]ÂÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì SVWÇEôjhjjè0¥‰Eøƒ}øuƒÈÿéöhø¸5s‹E PèQKƒÄ‰Eüƒ}üu6¿0’5s‹U ƒÉÿ3Àò®÷Ñ+ù‹÷‹Ù‹úƒÉÿ3Àò®ƒÇÿ‹ËÁéó¥‹Ëƒáó¤é‹Eü3ÉŠH…Éu3¿,’5s‹U ƒÉÿ3Àò®÷Ñ+ù‹÷‹Ù‹úƒÉÿ3Àò®ƒÇÿ‹ËÁéó¥‹Ëƒáó¤ë=‹Eü3ÉŠH…Éu1¿(’5s‹U ƒÉÿ3Àò®÷Ñ+ù‹÷‹Ù‹úƒÉÿ3Àò®ƒÇÿ‹ËÁéó¥‹Ëƒáó¤‹Eü3ÉŠH…Ét‹UüÆB‹Eøû‰Eàhø¸5s‹M QègJƒÄƒè‰Eüj‹UüƒÂR‹EøüPÿ‹E¾H…Éu3¿(’5s‹UƒÉÿ3Àò®÷Ñ+ù‹÷‹Ù‹úƒÉÿ3Àò®ƒÇÿ‹ËÁéó¥‹Ëƒáó¤ë>ë<‹EƒÀ‰E늿Œ’5s‹UƒÉÿ3Àò®÷Ñ+ù‹÷‹Ù‹úƒÉÿ3Àò®ƒÇÿ‹ËÁéó¥‹Ëƒáó¤_^[]ÃÌÌÌÌÌU‹ìƒìHVWÇEüÿÿÿÿÇE¼’5sƒ} }"ƒ} ÿtjjh'j‹EPèÚ.ƒÈÿ龋M ‰M¸‹U¸ƒê"‰U¸ƒ}¸X‡v‹M¸3ÀŠÚ3sÿ$…¢3sUÀR‹EPèÚ ÿÿƒÄ}ÀƒÉÿ3Àò®÷уÁÿ‰Müƒ} ÿt‹M ;Mü}‹UR‹EPèúÔÿÿéQƒ} ÿt‹MüQ‹UREÀPè®—ë#}À‹UƒÉÿ3Àò®÷Ñ+ù‹÷‹Á‹úÁéó¥‹Èƒáó¤éôƒ}ÿu‹}ƒÉÿ3Àò®÷уÁÿ‰M‹M;M ~(ƒ} ÿt"h'‹URèÐ5ƒ}$t‹E$‹M‰‹U ‰U‹E P‹MQ‹UR‹EPè7ûÿÿ‰Eüéj MÀQ‹U3ÀŠPÿ$q5sƒÄ }ÀƒÉÿ3Àò®÷уÁÿ‰Müƒ} ÿt‹M ;Mü}‹UR‹EPè Ôÿÿébƒ} ÿt‹MüQ‹UREÀPè¿–ë#}À‹UƒÉÿ3Àò®÷Ñ+ù‹÷‹Á‹úÁéó¥‹Èƒáó¤éj MÀQ‹U¿Pÿ$q5sƒÄ }ÀƒÉÿ3Àò®÷уÁÿ‰Müƒ} ÿt‹M ;Mü}‹UR‹EPè‚ÓÿÿéÙƒ} ÿt‹MüQ‹UREÀPè6–ë#}À‹UƒÉÿ3Àò®÷Ñ+ù‹÷‹Á‹úÁéó¥‹Èƒáó¤é|j MÀQ‹U‹Pÿ0q5sƒÄ }ÀƒÉÿ3Àò®÷уÁÿ‰Müƒ} ÿt‹M ;Mü}‹UR‹EPèúÒÿÿéQƒ} ÿt‹MüQ‹UREÀP讕ë#}À‹UƒÉÿ3Àò®÷Ñ+ù‹÷‹Á‹úÁéó¥‹Èƒáó¤j;MÀQèžÈÿÿ…Àuh}'‹URèì3ƒÈÿéðéÏ‹E‹‰Mô‹P‰Uø‹E‹HQ‹R‹E¼PMÀQÿXq5sƒÄUÀRèúÿÿEÀPèÄûÿÿƒÄ}ÀƒÉÿ3Àò®÷уÁÿ‰Müƒ} ÿt‹M ;Mü}‹UR‹EPè$Òÿÿé{ƒ} ÿt‹MüQ‹UREÀPèØ”ë#}À‹UƒÉÿ3Àò®÷Ñ+ù‹÷‹Á‹úÁéó¥‹Èƒáó¤j>MÀQèÈÇÿÿ…Àuh}'‹URè3ƒÈÿééù‹E Pj‹MQ‹UR‹EPèÒøÿÿ‰Eü‹MÑá9M }ƒ} ÿt j‹URè„Ñÿÿé¿jÿEÀP‹MQ‹URè|òÿÿ‰Eüƒ}üÿuh7'‹EPè¥2‹Eüé©‹M ;Mü}ƒ} ÿt‹UR‹EPè2Ñÿÿ鉃} ÿt‹MüQ‹UREÀPèæ“ë#}À‹UƒÉÿ3Àò®÷Ñ+ù‹÷‹Á‹úÁéó¥‹Èƒáó¤é,ƒ}t‹M3Òf‹‘„â…ÒtÇE(jÿEÀP‹MQ‹U(RèFõÿÿ‰Eüƒ}üÿuh7'‹EPèï1‹Eüéó‹M ;Mü}ƒ} ÿtj‹URè~Ðÿÿƒ}$t‹E$‹Mü‰ƒ} ÿt!‹Uü;U ~‹E ‰Eü‹MüQ‹UREÀPè“ë#}À‹UƒÉÿ3Àò®÷Ñ+ù‹÷‹Á‹úÁéó¥‹Èƒáó¤éajÿMÀQ‹UŠPèøÿÿ‰Eü‹M ;Mü}ƒ} ÿt‹UÆ*j‹EPèîÏÿÿéEƒ} ÿt‹MüQ‹UREÀP袒ë#}À‹UƒÉÿ3Àò®÷Ñ+ù‹÷‹Á‹úÁéó¥‹Èƒáó¤éè‹M‹RèøÿÿÝ]ô‹EøP‹MôQ‹U¼REÀPÿXq5sƒÄMÀQè¨÷ÿÿUÀRèßøÿÿƒÄ}ÀƒÉÿ3Àò®÷уÁÿ‰Müƒ} ÿt‹E ;Eü}‹MQ‹URè?Ïÿÿé–ƒ} ÿt‹EüP‹MQUÀRèó‘ë#}À‹UƒÉÿ3Àò®÷Ñ+ù‹÷‹Á‹úÁéó¥‹Èƒáó¤é9jÿMÀQ‹URèJïÿÿ‰Eüƒ}üÿuh7'‹EPè#0‹Eüé'‹M ;Mü}ƒ} ÿt‹UR‹EPè°Îÿÿéƒ} ÿt‹MüQ‹UREÀPèd‘ë#}À‹UƒÉÿ3Àò®÷Ñ+ù‹÷‹Á‹úÁéó¥‹Èƒáó¤éªjÿMÀQ‹UR‹EPè÷îÿÿ‰Eüƒ}üÿuh7'‹MQè/‹Eü锋U ;Uü}ƒ} ÿt j‹EPèÎÿÿƒ} ÿt!‹Mü;M ~‹U ‰Uü‹EüP‹MQUÀRèÊë#}À‹UƒÉÿ3Àò®÷Ñ+ù‹÷‹Á‹úÁéó¥‹Èƒáó¤ëh '‹MQè/ƒÈÿëƒ}üÿu‹}ƒÉÿ3Àò®÷уÁÿ‹Áë‹Eü_^‹å]Ç3sŒ3sñ3s3s{3s3sÖ3s˜3sÁ3sT3s±3s 3sG3sm3s      ÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìjj‹E P‹MQ‹UR‹EP‹MQ‹U R‹EPè8÷ÿÿƒÄ$]ÃÌÌÌU‹ìj‹E$P‹M Q‹UR‹EP‹MQ‹UR‹E P‹MQè÷ÿÿƒÄ$]ÃÌU‹ìƒìEú‰Eð‹M‰Mô3ÒŠ˜’5s‹Eô3Éf‹ P¯M ‹UâÿʉMø3À ˜’5s‹Môf‹Uøf‰AÇEüë ‹EüƒÀ‰Eüƒ}ü}=‹Mü3ÒŠ‘˜’5s‹Eô3Éf‹ P¯M ‹Uð3Àf‹ȉMø‹Mü3ÒŠ‘˜’5s‹Eôf‹Møf‰ Pë´‹Uð3Àf‹…À¿Mø…É}3À븋å] ÌU‹ìQÇEü‹Eƒ8}ÇEü‹M‹÷Ò‹E‰‹Mƒyt‹U‹B÷ЃÀ‹M‰Aë ‹U‹ƒÀ‹M‰ƒ}üt‹Uƒ:u ‹Eƒxu3À븋å]ÂÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì4WÇEÐÇEØÇEèÇEäÇEÔÇEôÇEÜÇEüÇEì‹E‰Eø‹M Ç‹U ÇBƒ}ÿu‹}øƒÉÿ3Àò®÷уÁÿ‰M‹EÜ;E„z‹Mø¾…Ò„l‹EøŠˆMð‹UøƒÂ‰Uø‹E܃À‰EܾMð¾ø¸5s;Êu2ƒ}èt ¸þÿÿÿé…ÇEèƒ}Ôtƒ}üt ¸þÿÿÿéhé ¾Eð¾ ¸¹5s;ÁuKƒ}äu ¸þÿÿÿéDƒ}Ôtƒ}üt ¸þÿÿÿé.ëÇEÔƒ}ü~ ¸þÿÿÿéÇEüé²¾Uð¾À¹5s;Ð…š¿À¹5sƒÉÿ3Àò®÷уÁÿƒùvQÇEàë ‹MàƒÁ‰Mà¿À¹5sƒÉÿ3Àò®÷уÁÿ9Mà})‹Uø¾‹MྑÀ¹5s‹MøƒÁ‰Mø;Ât ¸þÿÿÿé‘븃}Øu¿ø¹5sƒâ ÷ÚÒ÷Ú3Uä…Òt ¸þÿÿÿéhÇEØéŠEðˆEÌ€}Ì t€}Ì+tB€}Ì-tëbƒ}ätÇEìéÙƒ}Ðu ƒ}äuƒ}ìt ¸þÿÿÿéÇEÐÿÿÿÿ鱃}Ðu ƒ}äuƒ}ìt ¸þÿÿÿéìÇEÐ鉾Mðƒù0|y¾Uðƒú9pƒ}ìt ¸þÿÿÿé¾ÇEäƒ}èt ‹EôƒÀ‰Eôë ‹MüƒÁ‰Müƒ}Ôtƒ}ü~ ¸þÿÿÿ釃}ô~é¤ýÿÿ¾Uðƒê0Rj ‹E PèÚûÿÿ…ÀuƒÈÿë`ë¸þÿÿÿëWézýÿÿƒ}Ôt ƒ}üt¸þÿÿÿë?ƒ}ô}j‹Mô‹œ’5sR‹E Pè”ûÿÿ…ÀuƒÈÿëƒ}Ð}‹M Qè<üÿÿ…ÀuƒÈÿë3À_‹å] ÌÌÌÌÌÌÌÌÌÌU‹ìƒì(ÇEäÇEü€ÇEèÿÿÿ‹Eǃ} }‹M ‰MàëÇEà‹UàREðPj<‹MQ‹UR‹E P‹MQèȃĉEìƒ}ìÿu‹Eì颋U ‰U܃}Ü"tƒ}Ü-të‹Eð‰Eø‹Mô‰Mð‹Uø‰Uôƒ}ð}ÇEäEðPèxûÿÿƒ}ðuƒ}ät‹Mô;Müwƒ}äu‹Uô;Uèvh'‹EPèx(ƒÈÿë1ƒ}ät ‹Mô÷уÁ‰Mô‹U‹Eô‰ƒ}ìv ÇEØë‹Mì‰MØ‹EØ‹å]ÃÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì(‹E ‰Eà‹Màƒé"‰Màƒ}àX‡¬‹Eà3ÒŠ«#3sÿ$•‡#3s‹MQ‹UR‹EPè>ûÿÿ‰Eì锋M Q‹UR‹EPèµÆÿÿ‰Eüƒ}üuƒÈÿé·jÿ‹MQ‹UüRèûÿÿ‰Eì‹EüP‹MQ蕈ƒÄéK‹UÇB‹Eǃ}tƒ}u ¸ég‹M‹‰Uô‹A‰EøÝEôÜÐq5sßàöÄtÝEôÙàÝ]ôÝEôÜr5sßàöÄAuh'‹MQè0'ƒÈÿéÝEôÜr5sßàöÄAtÝEôÜøq5sÝ]ôëÇEô-CëÇEøâ6 CÝEôÜ5ðq5sè^>‹U‰‹EÛÜ ðq5sÜmôÝUôÜ Øq5sè=>‹M‰A‹UÝÜÐq5sßàöÄt#‹EPè|ùÿÿ…Àuh'‹MQèš&ƒÈÿé…¸é{ƒ} ÿu$ƒ}}h'‹URèn&ƒÈÿéY‹E‰Eðë‹M ‰Mðƒ}~‹Uð;U~‹E‰Eðj‹MQè釃}}‹U‰UÜëÇEÜ‹Eð;EÜ}h'‹MQè&‹UðR‹EP‹MQè}‡‹Eðéè‹U‹E‹‰ ‹U‹E‹H‰J¸éÈ‹U‹E‹‰J‹UÇ‹Eƒ8} ‹M‹ƒê‹E‰¸é•‹M‰Mä‹U‰Uè‹EèP‹MäQè™øþÿƒÄ…Àt ¸ékƒÈÿéc‹UÇB‹Eǃ}tƒ}u ¸é:‹MÙÝ]ô‹UÙØìq5sßàöÄtÝEôÙàÝ]ôÝEôÜr5sßàöÄAuh'‹EPè%ƒÈÿéòÝEôÜr5sßàöÄAtÝEôÜøq5sÝ]ôëÇEô-CëÇEøâ6 CÝEôÜ5ðq5sè5<‹M‰‹UÛÜ ðq5sÜmôÝUôÜ Øq5sè<‹M‰A‹UÙØìq5sßàöÄt ‹EPèS÷ÿÿ…Àuh'‹MQèq$ƒÈÿë_¸ëXh '‹URèW$ƒÈÿëE‹Eì‰E؃}Øþt!ƒ}Øÿtƒ}Øt(ë+h'‹MQè*$ƒÈÿëh7'‹URè$ƒÈÿ븋å]Ã!3s‘3sª3s "3s›!3só3sî!3s»!3s+#3sÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒìW‹E‰Eü‹M ‰Môƒ}ÿu‹}üƒÉÿ3Àò®÷уÁÿ‰Mðë‹U‰Uðƒ}ƒ}ÿu*jhˆ’5s‹EPÿ4q5sƒÄ …Àu‹Mðƒé‰Mð‹UüƒÂ‰Uüƒ}ÿu ‹EðÑà‰Eìë‹M‰Mìƒ}ÿt‹UÑâ;Uð}‹EÑà‰Eð‹Eð™+ÂÑø‰Eäƒ}ðŽ;‹MôÆÇEèë ‹UèƒÂ‰Uèƒ}èñ‹EüŠˆMø‹UüƒÂ‰Uü‹Eø%ÿƒø t ‹Møáÿ…ÉuÆEø0‹Uøâÿƒú0| ‹Eø%ÿƒø9~,‹Møáÿá߃ùAŒƒ‹Uøâÿâ߃úFo‹Eø%ÿƒø9~ŠMø€á߈MøŠUø€êˆUøŠEø,0ˆEøƒ}èuŠMøÀáˆMøŠUø€âðˆUøëŠEø$ˆEø‹MôŠUø‹Eôˆƒ}èu‹Mðƒé…Éu¸þÿÿÿë9ë¸þÿÿÿë0éüþÿÿ‹UôƒÂ‰Uô‹Eðƒè‰Eð‹Mìƒé‰Mìƒ}ìuëé»þÿÿ‹Eä_‹å]ÂÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì ‹E ‰Eô‹Môƒé"‰Môƒ}ôX‡c‹Eô3ÒŠ·'3sÿ$•§'3sƒ} ÿt‹EƒÀ™+ÂÑø9E }h'‹MQè+!‹U R‹EP‹MQ‹URè–ýÿÿ‰Eøƒ}øþuh7'‹EPèÿ ƒÈÿé ‹Eøéƒ} ÿu‹M Qè€Áÿÿ‰EüëR‹U ;U~ƒ}}‹E ‰Eüë‹M‰Mü‹U RèVÁÿÿ9Eü~ ‹E PèHÁÿÿ‰Eü‹M Qè<Áÿÿ9Eü}h'‹URè‰ ‹EüP‹MQ‹URèø‹Eü郃} ÿuƒ}}ƒÈÿër‹E‰Eüë‹M ‰Müƒ}~‹Uü;U~‹E‰Eü‹Mü;M}h'‹URè' ƒ} ~ ‹E P‹MQèÄ‹UüR‹EP‹MQ胋Eüëh '‹URèðƒÈÿ‹å]à '3sA&3s¡&3s’'3s‹D$ ƒìƒÀÞƒøX‡æ3ÉŠˆD+3sÿ$ +3sƒ|$0…Á‹T$f‹f=ÿ™f…À§‹T$ h'Rè*3ÀƒÄƒ|$0u0‹D$‹=ÿa…Àp‹T$ h'Rèó3ÀƒÄ‹L$‹=ÿ1=€ÿÿ=‹T$ h'RèÀ3ÀƒÄ‹D$T$RPè‰òþÿƒÄ…À„õƒ|$0…ÛD$ÜHr5sßàöÄA„ÓÜ@r5sßàöÄ…ÂÜ8r5sßàöÄA„±Ü0r5sßàöÄ„¹‹T$ h'Rè<3ÀƒÄ‹D$‹L$ƒø0Ýu;ÜHr5sßàöÄA„kÝÜ@r5sßàöÄ„o‹T$ h'Rèò3ÀƒÄÂÜ8r5sßàöÄA„0ÝÜ0r5sßàöÄ„4‹T$ h'Rè·3ÀƒÄ‹T$L$QRèðÛÿÿÝD$ƒ|$0…±Ü(r5sßàöÄA„×ÝD$ÜÐq5sßàöĄًT$ h'Rè\3ÀƒÄ‹D$‹L$ƒø0ÙuØ r5sßàöÄA„‹ÙØìq5sëaØr5sßàöÄAttÙØr5sëJ‹L$D$PQè´ÛÿÿÝD$ƒ|$0uÜ(r5sßàöÄAtCÝD$ÜÐq5sëÜr5sßàöÄAt*ÝD$Ür5sßàöÄt0‹T$ h'Rè³3ÀƒÄÂÝØ‹T$ h'Rèš3ÀƒÄ¸ƒÄ‹D$ h 'Pèx3ÀƒÄÂþ*3s2(3sn(3s<*3sá)3s\)3sØ(3s}*3s +3sU‹ìƒäøƒì|S‹]3Àƒû0V‹u •À@W‹}ƒþ/‰D$t#ƒþ#tƒþM”Qè>¦ÿÿ…Àuh}'‹UR范Èÿé E”Pÿèp5sƒÄ‹MÝé‹U3ÀЉEˆÛEˆ‹MÝéí‹U¿‰E„ÛE„‹MÝé׋UÛ‹EÝéÈ‹M‹U‹‰‹R‰Q鳋EP‹MQè_Ïÿÿé¡‹U3ÀŠ…Àt‹MÇÇAð?ë‹UÇÇBërƒ}s'ƒ}ÿt!j‹EPètr‹MQ‹UR‹EPè3r‹EëJj‹MQ‹URèrë4‹E‹QèBØÿÿ‹UÝë"‹EP‹MQè.Ïÿÿëh '‹URènƒÈÿë¸_^‹å]õ63s„53s#63s†63s:63sP63só63st63s_63sc53s73s73s       ÌÌÌÌÌU‹ììVW‹E ‰…|ÿÿÿ‹|ÿÿÿƒé"‰|ÿÿÿƒ½|ÿÿÿX‡J‹…|ÿÿÿ3ÒŠˆ:3sÿ$•X:3sM€Q‹URèîâþÿƒÄ…ÀuƒÈÿé1ÝE€Ù]ˆÝE€Üpr5sßàöÄuÝE€Ühr5sßàöÄAuh'‹EPè;ƒÈÿéõ‹M‹Uˆ‰éãƒ}ÿtCƒ}d} ‹E‰…xÿÿÿë Ç…xÿÿÿd‹xÿÿÿ‰Mô‹UôR‹EPMŒQÿ‹|ÿÿÿ3ÀŠäU3sÿ$…ØU3s°ë'U€Rj‹E Pj‹MQè¾ûÿÿƒÄ…Àu2ÀëŠEòë2À‹å]éU3s­U3sÒU3sÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ì‹EƒxRt9‹M‹QR‹E ƒ<‚t*‹M‹QR‹E ‹ ‚ƒyt‹U‹BR‹M ‹ˆ‹B‹Mƒ<ˆu3Àë‹U‹BR‹M ‹ˆ‹B‹M‹ˆ] ÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìQ‹EP‹M Q‹URèË[‰Eüƒ}üuƒÈÿë‹Eü‹H‹U‹D‘ü‹@ ‹å]ÃÌÌÌÌÌÌÌÌÌU‹ìƒì ‹EP‹M Q‹URè‰[‰Eôƒ}ôuƒÈÿë9‹Eô‹H‹U‹D‘ü3ÉŠH‰Mø‹Uô‹B‹M‹Tˆü‹B ‰Eü‹MüQ‹UøR‹EPèòY‹å]ÃÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì ‹EP‹M Q‹URè[‰Eøƒ}øuƒÈÿë+‹Eø‹H‹U‹D‘ü‹H‰Müƒ}üd~‹Uü‰UôëÇEôÿÿÿÿ‹Eô‹å]ÃÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì ‹EP‹M Q‹URè¹Z…Àu3Àë6‹Eƒè‰Eø‹M ƒé‰Mô‹UøR‹EôP‹MQè>þÿÿ‰Eüƒ}üu3Àë‹Uü‹B‹å]ÃÌÌÌÌÌÌÌU‹ìQ‹EP‹M Q‹URè[Z…ÀuƒÈÿëk‹EƒèP‹M ƒéQ‹URèëýÿÿ‰Eüƒ}üuƒÈÿëF‹Eüƒ8~9‹MQ‹U R‹EPètþÿÿƒÄ ƒølt‹MQ‹U R‹EPè[þÿÿƒÄ ƒøju¸ë‹Mü‹‹å]ÃÌÌÌU‹ìQ‹EPè³T…ÀuƒÈÿë'j‹M Q‹URèKZ‰Eüƒ}üuƒÈÿë ‹Eü3Éf‹‹Á‹å]ÃÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìQ‹EP‹M Q‹URè{Y‰Eüƒ}üuƒÈÿë‹Eü‹H‹U‹D‘ü3ÉŠH‹Á‹å]ÃÌÌÌÌÌU‹ìQƒ}u3ÀëR‹EPèT…Àu ‹MÇ3Àë8j‹U R‹EPè©Y‰Eüƒ}üu ‹MÇ3Àë‹Uü3ÀŠB ‹M‰‹Uü‹B ‹å]ÃÌÌÌÌÌÌÌÌÌÌÌÌU‹ìQ‹EP‹M Q‹URèËX‰Eüƒ}üuƒÈÿë‹Eü‹H‹U‹D‘ü3ÉŠH‹Á‹å]ÃÌÌÌÌÌU‹ì‹EPètS…ÀuƒÈÿë‹M¿AL]ÃÌÌU‹ìƒì‹E‹H$‰MüÇEøë ‹UøƒÂ‰Uø‹E¿H"9Mø}V‹Uø‹Eü‹ ¿Q0;U uB‹Eø‹Mü‹3Àf‹B ƒøPu.‹Mø‹Uü‹Š3ÉŠH*ƒá …Ét‹Uø‹Eü‹ ‹A,ë‹Uø‹Eü‹ëë•3À‹å]ÂÌÌÌÌÌU‹ìƒì ÇEü‹E‹H$‰MøÇEôë ‹UôƒÂ‰Uô‹E¿H"9Mô}2‹Uô‹Eø‹ ¿Q0;U u‹Eô‹Mø‹3ÀŠB*ƒà…Àt ‹MüƒÁ‰Mü빋Eü‹å]ÂÌU‹ìƒì‹E P‹MQèR…Àu3ÀëH‹U ƒê‰Uü‹Eƒx$t‹M‹Q$‹Eüƒ<‚u3Àë#‹M‹Q$‹Eü‹ ‚‰Mø‹Uø¿B0P‹MQè@ƒÄ‹å]ÃÌÌÌÌÌÌÌÌÌU‹ì‹EPèäQ…Àu3Àë<‹Mƒyjt"‹U¿Bh9E ƒ} |‹M‹Qj‹E ƒ|‚üu3Àë ‹M‹Qj‹E ‹D‚ü]ÃÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì ‹E P‹MQè½Q…Àu3Àé ‹U‹B$‰Eüƒ}üt#‹M ‹Uüƒ|Šüt‹E ‹Mü‹Tü3ÀŠB*ƒà…Àt3Àëj‹M ‹Uü‹DŠü3ÉŠH*ƒá …Ét.‹U ‹Eü‹Lüƒy,u ÇEøë‹U ‹Eü‹Lü‹Q,‰Uø‹Eøë&‹E ‹Müƒ|üu ÇEôë ‹U ‹Eü‹Lü‰Mô‹Eô‹å]ÃÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ì‹EPè´P…Àu3ÀëG‹M Q‹URè¯þÿÿƒÄ…Àu3Àë/‹E P‹MQè·ýÿÿ…Àu3Àë‹U R‹EPèýÿÿ…Àu3Àë¸]ÃÌÌÌU‹ìƒì‹E P‹MQèP…Àuƒ}t ‹UÇÿÿÿÿ3ÀëO‹E‹H$‹U ‹D‘ü¿H0‰Mø‹UøR‹EPè%þÿÿƒÄ‰Eüƒ}tƒ}üt ‹M‹Uø‰ëƒ}t ‹EÇÿÿÿÿ‹Eü‹å]ÃÌÌÌU‹ì‹EPèÔO…ÀuƒÈÿë‹M¿Ah]ÃÌÌU‹ìƒì‹E‹Ht‰Møƒ}ø„±ÇEüë ‹UüƒÂ‰Uü‹E¿ˆ‚9MüŒ‹Uü‹Eøƒ<t‹Mü‹Uø‹Šƒ8uëÈÇEôp›5s‹Mü‹Uø‹Š‹‰Mð‹UðŠˆEï‹Mô:u.€}ït‹UðŠBˆEî‹Mô:AuƒEðƒEô€}îuÌÇEèëÒƒÚÿ‰Uè‹Eè‰Eäƒ}äu‹EüëéXÿÿÿƒÈÿ‹å]ÂÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìQ‹EPèÓN…Àu3Àë7‹M¿‘‚…Ò3Àë%‹EPèðþÿÿ‰Eüƒ}üÿu3Àë‹M‹Qt‹Eü‹ ‚‹A ‹å]ÃU‹ìQ‹EPèƒN…ÀuƒÈÿë9‹M¿‘‚…ÒƒÈÿë&‹EPèžþÿÿ‰Eüƒ}üÿuƒÈÿë‹M‹Qt‹Eü‹ ‚‹A‹å]ÃÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì ‹EPè!N…Àu3Àé¡‹M¿Qh9U ƒ}} ƒ}ÿt3À邃} tƒ}}h'‹EPèýçÿÿ3Àéaƒ}ÿuƒ}t‹MQ‹URèM‰Eƒ}ÿuh'‹EPèÆçÿÿ3Àé*‹M‹Q$‰Uø‹E‹HD‰Müƒ}øtƒ}üuh'‹URè“çÿÿ3Àé÷ÇEôë ‹EôƒÀ‰Eô‹M¿Q"9UôÓ‹Eô‹Mø‹¿B0;E…¸‹Mô‹Uø‹Š3Éf‹H ƒùP… ‹Uô‹Eü‹ ‹;U}a‹Eô‹Mü‹ƒzt‹Eô‹Mü‹‹BP‹MQè÷GƒÄj‹UR‹EPjè3G‹Mô‹Uü‹ ЉA‹Uô‹Eü‹ ƒyu ‹URjèmMë6‹EP‹Mô‹Uü‹Š‹HQ‹U Rè1H‹Eô‹Mü‹‹E‰¸ëéÿÿÿ3À‹å]ÃÌU‹ìƒì‹E‹Hj‰Müƒ} „šÇEøë ‹UøƒÂ‰Uø‹E¿Hh9Mø}|‹Uø‹Eüƒ<tk‹M ‰Mô‹Uø‹Eü‹ ‰Mð‹UðŠˆEï‹Mô:u.€}ït‹UðŠBˆEî‹Mô:AuƒEðƒEô€}îuÌÇEèëÒƒÚÿ‰Uè‹Eè‰Eäƒ}äu‹EøƒÀëéoÿÿÿƒÈÿ‹å]ÂÌÌÌÌU‹ìƒì WÇEø‹E‹H$‰MüÇEôë ‹UôƒÂ‰Uô‹E¿H"9Mô}<‹Uô‹Eü‹ ¿Q0;U u‹Eô‹Mü‹3ÀŠB*ƒà…Àt ‹MøƒÁ‰Mø‹U;Uøuë믋E;Eøtƒ}t ‹MÇÿÿÿÿ3Àëo‹Uô‹Eü‹ 3ÒŠQ*ƒâ …Òt1ƒ}t‹Eô‹Mü‹‹z,ƒÉÿ3Àò®÷уÁÿ‹E‰‹Mô‹Uü‹Š‹@,ë)ƒ}t‹Mô‹Uü‹<ŠƒÉÿ3Àò®÷уÁÿ‹E‰‹Mô‹Uü‹Š_‹å]ÂÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì ÇEø‹E‹H$‰MüÇEôë ‹UôƒÂ‰Uô‹E¿H"9Mô}<‹Uô‹Eü‹ ¿Q0;U u‹Eô‹Mü‹3ÀŠB*ƒà…Àt ‹MøƒÁ‰Mø‹U;Uøuë믋E;EøtƒÈÿë%‹Mô‹Uü‹Š‹H&Q‹Uô‹Eü‹ 3ÒŠQ$R‹EPèÎM‹å] ÌÌÌÌÌÌÌÌU‹ìƒìÇEô‹E‹H$‰MøÇEðë ‹UðƒÂ‰Uð‹E¿H"9Mð}<‹Uð‹Eø‹ ¿Q0;U u‹Eð‹Mø‹3ÀŠB*ƒà…Àt ‹MôƒÁ‰Mô‹U;Uôuë믋E;Eôtƒ}t ‹MÇ3ÀëD‹U‹BD‰Eüƒ}üuƒ}t ‹MÇ3Àë"ƒ}t‹Uð‹Eü‹ ‹U‹‰‹Mð‹Uü‹Š‹@‹å]ÂÌÌÌÌÌÌÌÌÌÌÌU‹ìƒìPSVWÇEðÇEàÇEЋEPèéH…Àu3Àé*ƒ} ÿu‹MQ‹URè[üÿÿ‰Eèë‹E ‰Eè‹M¿Qh9Uèƒ}è}3Àéó‹E‹H$‰Mìƒ}ìt ‹UƒzDu3ÀéÔ‹EèP‹MQè«õÿÿ‰EôÇE¼ÇEÜë ‹U܃‰UÜ‹E¿H"9MÜ}:‹UÜ‹Eì‹ ¿Q0;Uèu&‹EÜ‹Mì‹3Àf‹B ƒøPu‹M‹QD‹EÜ‹ ‚‹Q‰U¼ë±ƒ}ôtƒ}¼u3ÀéRÇEÜë ‹E܃À‰EÜ‹MÜ;Môçƒ}Ü~ ‹UðƒÂ‰Uð‹EðƒÀ‰Eð‹MÜQ‹UèR‹EPèýÿÿ‰EäMÌQ‹UÜR‹EèP‹MQè÷ûÿÿ‹UðỦUð‹Eä‰E¸‹M¸ƒé"‰M¸ƒ}¸Xw1‹E¸3ÒŠÓk3sÿ$•Ãk3s‹MðƒÁ‰Mðë‹UðƒÂ‰Uðë ‹EðƒÀ‰EðMÄQ‹UÜR‹EèP‹MQèSýÿÿ‹UÄRf‹EÌP‹MÜQ‹UèR‹EPè‰üÿÿPè#D¿È‰MЋUÐ;Uàv‹EЉEà‹MðMЉMðéÿÿÿ‹UðƒÂP‰Uðj‹EðP‹MQjèGA‰EÀƒ}Àu3Àé#j‹UàR‹EPjè&A‰Eøƒ}øu‹MÀQ‹URèÀAƒÄ3Àéò‹EÀ‹ °›5s‰f‹´›5sf‰PŠ ¶›5sˆHÇEÜë ‹U܃‰UÜ‹EÜ;EôMÇEȃ}Ü~3¿¨›5s‹UÀƒÉÿ3Àò®÷Ñ+ù‹÷‹Ù‹úƒÉÿ3Àò®ƒÇÿ‹ËÁéó¥‹Ëƒáó¤ë1¿¤›5s‹UÀƒÉÿ3Àò®÷Ñ+ù‹÷‹Ù‹úƒÉÿ3Àò®ƒÇÿ‹ËÁéó¥‹Ëƒáó¤EÌP‹MÜQ‹UèR‹EPè3úÿÿ‹ø‹UÀƒÉÿ3Àò®÷Ñ+ù‹÷‹Ù‹úƒÉÿ3Àò®ƒÇÿ‹ËÁéó¥‹Ëƒá󤿠›5s‹UÀƒÉÿ3Àò®÷Ñ+ù‹÷‹Ù‹úƒÉÿ3Àò®ƒÇÿ‹ËÁéó¥‹Ëƒáó¤‹EÜP‹MèQ‹URèÓúÿÿ‰EäEÄP‹MÜQ‹UèR‹EPèkûÿÿ‰Eüƒ}Äu6¿˜›5s‹UÀƒÉÿ3Àò®÷Ñ+ù‹÷‹Ù‹úƒÉÿ3Àò®ƒÇÿ‹ËÁéó¥‹Ëƒáó¤éÊ‹Eä‰E´‹M´ƒé"‰M´ƒ}´X‡°‹E´3ÒŠ…Àu3À鉋U‹B$‹M‹Tˆü3ÀŠB$‰Eøƒ}ø#tƒ}ø"th#'‹MQèÓ×ÿÿ3ÀëV‹U‹BD‹M‹Tˆü‰Uüƒ}üt ‹Eüƒxu3Àë3‹Mü‹QƒÂ‰Uôƒ} u j‹EôPè?9ëj‹MôQ‹U Rèþ8¸‹å]ÃÌÌÌÌÌU‹ìƒìSVWjj‹EPèÚÿÿƒÄ …Àu(‹}‹U ƒÉÿ3Àò®÷Ñ+ù‹÷‹Á‹úÁéó¥‹Èƒáó¤éÏ‹MkÉ‹UDÿ‰Eô‹}ƒÉÿ3Àò®÷уÁÿ;Môv#‹MôQ‹UR‹E PÿÿÿÿÿMôQ‹URèVÿÿˆEìƒ}ôuƒÈÿéAjj‹EPjèJ%‰Eðƒ}ðu‹MQjè–+ƒÈÿé‹Uü‹‹Mð‰H‹Uìâÿ…Òu(‹Eü‹Ç‹UÆB‹E‹HHƒÁ‹U‰JH3ÀéÖ‹EðŠMìˆj‹UìâÿR‹EPjèÏ$‹Mð‰A‹Uðƒzu‹EPjè+ƒÈÿé•‹M‹Q3Àf‹B…À„´‹Mìáÿ‹U‹B3Òf‹P;Ê—‹Eì%ÿ‹M‹Q3Éf‹ ‹U‹R3öf‹r+Î;Ár‹Eì%ÿP‹M‹Q‹E‹H3Àf‹A‹JÈQ‹Uð‹BPÿq5sƒÄ ‹M‹Qf¶Eìf‹JfÈ‹U‹Bf‰H‹M‹Qf¶Eìf‹Jf+È‹U‹Bf‰HÇEÔë‹MìáÿQ‹Uð‹BP‹MQè»Fÿÿ‰EÔƒ}ÔuƒÈÿ颋U‹B3Éf‹H…É„–‹U‹B3Éf‹HƒùŒ‹U‹B3Éf‹‹U‹B3Òf‹P+ʃù|cj‹E‹H‹U‹B3Òf‹P‹AÂP‹MðƒÁQÿq5sƒÄ ‹U‹Bf‹HfƒÁ‹U‹Bf‰H‹M‹Qf‹Bf-‹M‹Qf‰BÇEÐëj‹EðƒÀP‹MQèîEÿÿ‰EЃ}ÐuƒÈÿéÕUàR‹E苊Q$R‹EPèTÿÿ…ÀuƒÈÿ鳋Mð‹Uà‰Q‹Eü‹‹Uà‰‹E‹Mà‰Hxë ‹U‹Bx‰Eà‹Mà;M}‹Uà‰UÌë‹E‰EÌ‹M̉Mà‹Uƒºu‹Eà‰EÈë(‹M‹Uà;‘}‹Eà‰EÄë ‹M‹‘‰UÄ‹EĉEÈ‹MȉMàƒ}àu(‹Uü‹Ç‹MÆA‹U‹BHƒÀ‹M‰AH3Àé‹U‹B3Éf‹H…É„•‹U‹B3Éf‹H9Mà€‹U‹B3Éf‹‹U‹B3Òf‹P+Ê9Màb‹EàP‹M‹Q‹E‹H3Àf‹A‹JÈQ‹U Rÿq5sƒÄ ‹E‹Hf‹QfUà‹E‹Hf‰Q‹U‹Bf‹Hf+Mà‹U‹Bf‰HÇEÀë‹MàQ‹U R‹EPèNDÿÿ‰EÀƒ}ÀuƒÈÿé5‹Mè‹3ÀŠB$ƒø#u‹MàQ‹U R‹EPè‹M‹Qx+Uà‹E‰Px‹Mƒyxu‹UÇBxÿÿÿÿ‹E‹HHƒÁ‹U‰JH‹Ef‹ˆ„€É‹Uf‰Š„‹EàéÅ‹EÇ€>þÿÿÿ‹MÇA0‹UÇB4‹EÇ@8‹MŠQ€âß‹EˆP‹MfÇAjŠUøR‹EäP‹MQè'1ÿÿ‰Eôƒ}ôûuëX‹UÆB‹Eô÷ØÀƒÀÿëQ‹EÇ€>þÿÿÿ‹MÇA0‹UÇB4‹EÇ@8¸þÿÿÿëh'‹MQèé¿ÿÿƒÈÿë ‹UÆBé.ùÿÿ^‹å]Ãq3sf3sŽ3sg‡3sÂ3sì3só†3s™‡3sÌÌÌÌÌÌÌU‹ìƒì‹EƒxR„öÇEðë ‹MðƒÁ‰Mð‹U¿BL9EðÁ‹M‹QR‹Eð‹ ‚‰Müƒ}ü„£‹Uüƒz„–‹Eü‹H‰MøÇEôë ‹UôƒÂ‰Uô‹Eü¿H9Mô}L‹Uô‹Eøƒ<t>‹Mô‹Uø‹Šƒxt‹Mô‹Uø‹Š‹HQ‹UR轃ċEô‹Mø‹R‹EP觃Ä럋Mü‹QR‹EP蒃ċMüQ‹UR肃Äé&ÿÿÿ‹E‹HRQ‹URèjƒÄ‹EÇ@R‹å]ÂÌÌÌÌÌÌÌU‹ìƒì‹E‹HN‰Mðƒ}ð„7‹Uð‰Uø‹Eð‹H‰Mð‹Uøƒz„…‹Eø‹H‰MüÇEôë ‹UôƒÂ‰Uô‹Eø3Éf‹9Mô}J‹Uô‹Eüƒ<t<‹Mô‹Uü‹Šƒ8t‹Mô‹Uü‹Š‹Q‹URèăċEô‹Mü‹R‹EP讃Äë ‹Mø‹QR‹EP虃ċMøƒyt\ÇEôë ‹UôƒÂ‰Uô‹Eø3Éf‹9Mô}*‹Uø‹B‹Môƒ<ˆt‹Uø‹B‹Mô‹ˆR‹EPèIƒÄëÀ‹Mø‹QR‹EPè4ƒÄ‹Møƒy t‹Uø‹B P‹MQèƒÄ‹UøR‹EPèƒÄé¿þÿÿ‹MQè‡ýÿÿ‹UÇBN‹EfÇ@L‹å]ÂÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìQ‹Eƒ¸JttÇEüë ‹MüƒÁ‰Mü‹U¿‚D9Eü}0‹M‹‘J‹Eüƒ<‚t‹M‹‘J‹Eü‹ ‚Q‹URètƒÄ븋E‹ˆJQ‹URè\ƒÄ‹EÇ€J‹å]ÂÌÌÌÌÌÌU‹ìƒì‹E‹HD‰Môƒ}ô„DÇEøë ‹UøƒÂ‰Uø‹E¿H"9Mø·‹Uø‹Eôƒ<„¢‹M‹Q$‹Eø‹ ‚3ÒŠQ$‰Uü‹Eø‹Mô‹‹B‰Eðƒ}ðtZƒ}ü#tƒ}ü"u>‹Mð‹Q‰Uìƒ}ìt‹EìP‹MQ褃ċUð‹B‰Eìƒ}ìt‹MìQ‹UR腃ċEðP‹MQèuƒÄ‹Uø‹Eô‹ ÇA‹Uø‹Eô‹ Çÿÿÿÿé0ÿÿÿƒ} te‹URèoþÿÿÇEøë ‹EøƒÀ‰Eø‹M¿Q"9Uø}$‹Eø‹Môƒ<t‹Uø‹Eô‹ Q‹URèƒÄëÇ‹EôP‹MQèðƒÄ‹UÇBD‹å]ÂÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì‹E‹H‰Müƒ}üt;‹Uüƒ:t‹Eü‹Q‹UR褃ċEü‰Eø‹Mü‹Q‰Uü‹EøP‹MQè…ƒÄë¿‹UÇB‹å]ÂU‹ìQ‹E‹H‰Mü‹U‹E‹H‰J‹URè~ÿÿÿ‹EÇ@‹M‹Uü‰Q‹å]ÂÌÌÌÌÌU‹ìƒì‹E‹H$‰Müƒ}ü„¨ÇEøë ‹UøƒÂ‰Uø‹E¿H"9Mø}w‹Uø‹Eüƒ<tf‹Mø‹Uü‹Šƒx2t‹Mø‹Uü‹Š‹H2Q‹URèȃċEø‹Mü‹ƒz,t‹Eø‹Mü‹‹B,P‹MQ蠃ċUø‹Eü‹ Q‹UR芃Äétÿÿÿ‹E‹H$Q‹URèrƒÄ‹EÇ@$‹Mƒyt‹U‹BP‹MQèLƒÄ‹UÇB‹EfÇ@"‹å]ÂU‹ìƒì‹E‹HZ‰Møƒ}øt!‹Uø‰Uü‹Eø‹H‰Mø‹UüR‹EPèÿƒÄëÙ‹MÇAZ‹å]ÂÌÌÌÌÌÌÌÌÌÌU‹ìƒì‹E‹Hj‰Müƒ}üt\ÇEøë ‹UøƒÂ‰Uø‹E¿Hh9Mø}$‹Uø‹Eüƒ<t‹Mø‹Uü‹ŠP‹MQ莃ÄëÇ‹UüR‹EPè|ƒÄ‹MÇAj‹UfÇBh‹å]ÂU‹ìƒì‹Eƒxtué‹M‹Qt‰UüÇEøë ‹EøƒÀ‰Eø‹M¿‘‚9Uø}f‹Eø‹Mü‹ƒ:t‹Eø‹Mü‹‹P‹MQèÿƒÄ‹Uø‹Eü‹ ƒyt‹Uø‹Eü‹ ‹Q R‹EPè׃ċMø‹Uü‹ŠP‹MQèÁƒÄë‚‹U‹BtP‹MQ謃ċUÇBt‹EfÇ@r‹MfÇ‚‹å]ÂÌÌÌÌU‹ìƒìÇEøë ‹EøƒÀ‰Eøƒ}ø}8‹Mø‹U„Ê‚‰Eü‹Müƒyt‹Uü‹BP‹MQè9ƒÄ‹UüÇB빋å]ÂÌÌÌÌU‹ìQ‹Eƒ¸Nuéÿ‹M‹‘N‰Uü‹Eüƒ8t$‹Mü‹R‹EPèèƒÄ‹MüÇ‹UüfÇB‹Eüƒxt‹Mü‹QR‹EP躃ċMüÇA‹Uüƒz t‹Eü‹H Q‹UR蔃ċEüÇ@ ‹Müƒyt‹Uü‹BP‹MQènƒÄ‹UüÇB‹Eüƒxt&‹Mü‹QR‹EPèHƒÄ‹MüÇA‹UüfÇB‹Eüƒxt‹Mü‹QR‹EPèƒÄ‹MüÇA‹å]ÂÌÌÌÌÌÌU‹ìQ‹Eƒx(„›‹M‹Q(‰Uüë ‹EüƒÀ ‰Eü‹M‹Q,kÒ ‹E‹H(Ê9Müs@‹U‹Eü‹H‰JD‹UƒzDt j‹EPèeùÿÿ‹M‹Uü‹B‰AR‹MƒyRt ‹URèöÿÿë¡‹EÇ@D‹MÇAR‹U‹B(P‹MQèaƒÄ‹UÇB(‹å]ÂÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒ}uéu‹E¹;H,Ò÷Ú…Òt ‹Eƒx(u ‹MƒyDt)‹U¸;B,É÷Ù…Ét ‹URèñþÿÿë j‹EPè¤øÿÿ‹MQè«úÿÿ‹URè‚öÿÿ‹EPè™ûÿÿ‹MQèàûÿÿ‹UÇB^‹Eƒxdt‹M‹QdR‹EPèƒÄ‹MÇAd‹URè'üÿÿ‹Eƒxt:‹M3ÒŠ‘Zƒâ…Òu(‹E‹H3Òf‹QTR‹E‹H‹QRè‹E‹HfÇA‹UfÇBb‹EÇ@H‹MÇA0‹UÇB4‹EÇ@8‹MÇA<‹UÇB@‹EÇ€>þÿÿÿ‹MfÇD‹UÇBn‹EŠˆZ€á‹UˆŠZ‹EÇ@V]ÂÌÌÌÌÌÌÌÌÌU‹ìƒìj‹E P‹MQjèé‰Eüƒ}üu‹URjè5éç‹E‹H3Òf‹Q…Ò„•‹E‹H3Òf‹Q9U €‹E‹H3Òf‹‹E‹H3Àf‹A+Ð9U b‹M Q‹U‹B‹M‹Q3Éf‹J‹PÑR‹EüPÿq5sƒÄ ‹M‹Qf‹BfE ‹M‹Qf‰B‹E‹Hf‹Qf+U ‹E‹Hf‰QÇEøë‹U R‹EüP‹MQè5ÿÿ‰Eøƒ}øu‹UR‹EüPè`ë‹MüQ‹UR衃ĸ‹å]ÂÌÌÌU‹ìƒì$ÇEøj‹E P‹MQjè‰Eèƒ}èu‹URjèé ‹E‹H3Òf‹Q…Ò„•‹E‹H3Òf‹Q9U €‹E‹H3Òf‹‹E‹H3Àf‹A+Ð9U b‹M Q‹U‹B‹M‹Q3Éf‹J‹PÑR‹EèPÿq5sƒÄ ‹M‹Qf‹BfE ‹M‹Qf‰B‹E‹Hf‹Qf+U ‹E‹Hf‰QÇEÜë‹U R‹EèP‹MQèß3ÿÿ‰E܃}Üu‹UR‹EèPè9éË‹Mè‰Mü‹Uüf‹f‰Eà‹MüƒÁ‰MüÇEì‹Uì;U }9‹Eü3ÉŠ‰Mô‹UüƒÂ‰Uü‹EìƒÀ‰Eì‹MìMô‰Mì‹UüUô‰Uü‹EøƒÀ‰Eøë¿‹M‹QN‰Uäƒ}ät‹Eäƒxuë ‹Mä‹Q‰Uäëäƒ}äu5jj‹EPjè9‰Eäƒ}äu‹MQ‹UèRèƒé‹E‹Mä‰HNë9jj‹URjè‹Mä‰A‹Uäƒzu‹EP‹MèQèHéÚ‹Uä‹B‰Eä‹Mäf‹Uøf‰‹EèƒÀ‰Eüj‹MøÁáQ‹URj賋Mä‰A‹Uäƒzu‹EP‹MèQè÷鉋Uä‹B‰Eð‹Mäf‹Uàf‰QÇEìë ‹EìƒÀ‰Eì‹Mì;Mø0jj‹URjèQ‹Mì‹Uð‰Š‹Eì‹Mðƒ<u‹UR‹EèPèé!‹Mì‹Uð‹Š‹MüŠˆP‹EüƒÀ‰Eü‹Mì‹Uð‹Š3ÉŠH…É„Åj‹Uì‹Eð‹ 3ÒŠQƒÂR‹EPjèÛ‹Mì‹Uð‹ Š‰‹Uì‹Eð‹ ƒ9u‹UR‹EèPèé§‹Mì‹Uð‹Š3ÉŠHQ‹Uì‹Eð‹ ‹R‹EüPèÌ‹Mì‹Uð‹Š‹Mì‹Uð‹ Š3ÒŠQ‹Æ‹Mì‹Uð‹Š3ÉŠHQ‹Uì‹Eð‹ ‹R‹EPè» ‹Mì‹Uð‹Š3ÉŠH‹UüщUüé»þÿÿ‹EèP‹MQèӃċUf‹BLf‹Mf‰AL¸‹å]ÂÌÌÌU‹ìƒì$ÇEìj‹E P‹MQjèâ ‰Eôƒ}ôu‹URjè.é‹E‹H3Òf‹Q…Ò„•‹E‹H3Òf‹Q9U €‹E‹H3Òf‹‹E‹H3Àf‹A+Ð9U b‹M Q‹U‹B‹M‹Q3Éf‹J‹PÑR‹EôPÿq5sƒÄ ‹M‹Qf‹BfE ‹M‹Qf‰B‹E‹Hf‹Qf+U ‹E‹Hf‰QÇEÜë‹U R‹EôP‹MQèÿ/ÿÿ‰E܃}Üu‹UR‹EôPèYé3‹Mô‰Mø‹Uøf‹f‰Eà‹MøƒÁ‰Mø‹U‹BN‰Eä‹Màáÿÿƒé9Mì}:ƒ}äu h!'‹URèm¬ÿÿ‹EP‹MôQèéÚ‹Uä‹B‰Eä‹MìƒÁ‰Mì뵋Uä3Àf‹B‹Màáÿÿ;Át h!'‹URè#¬ÿÿ‹EP‹MôQè¶é‹Uä‹EøŠˆJ‹UøƒÂ‰Uø‹Eä‹H‰Mèƒ}èu h!'‹URèà«ÿÿ‹EP‹MôQèséMÇEìë ‹UìƒÂ‰Uì‹Eä3Éf‹9M솋Uì‹Eè …Éu h!'‹URè«ÿÿ‹EP‹MôQè#éý‹Uì‹Eè‹ ‹UøŠˆA‹MøƒÁ‰Mø‹Uì‹Eè‹ ‹UøŠˆA‹MøƒÁ‰Mø‹Uì‹Eè‹ ‹Uø3Àf‹‰A‹MøƒÁ‰Mø‹UøƒÂ‰Uø‹E3ÉŠƒù@}D‹Uì‹Eè‹ 3ÒŠQƒê‰Uü‹E¿H"9Mü}$‹U‹B$‹Mü‹ˆ‰Uð‹Eì‹Mè‹‹Eð3Éf‹H ‰J‹Uì‹Eè‹ ‹UøŠˆA‹MøƒÁ‰Mø‹Uì‹Eè‹ ƒÁ Q‹Uì‹Eè‹ ŠQR‹EøPèg ‰Eø‹Mì‹U苊3ÉŠHƒùlt‹Uì‹Eè‹ 3ÒŠQƒújuD‹Eì‹Mè‹‹EøŠˆJ‹UøƒÂ‰Uø‹Eì‹Mè‹‹EøŠˆJ‹UøƒÂ‰Uø‹Eì‹Mè‹ÇB é`þÿÿ‹Eä‹MøŠˆP ‹EøƒÀ‰Eø‹Mä3ÒŠQ …Òt4j‹Eä3ÉŠH Q‹URjè/ ‹Mä‰A ‹Uäƒz u‹EP‹MôQèsëPÇEìë ‹UìƒÂ‰Uì‹Eä3ÉŠH 9Mì}‹Uä‹B ‹Mì‹UøŠˆ‹EøƒÀ‰Eøë΋MôQ‹URèy ƒÄ¸‹å]ÂÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì‹E¿HL‰Mðj‹UðÁâR‹EPjèŒ ‰Eôƒ}ôu‹MQjèØéç‹U‹BN‰EøfÇEüë f‹MüfƒÁf‰Mü¿Uü;Uð¯jj‹EPjè: ¿Mü‹Uô‰Š¿Eü‹Môƒ<u‹URjèxé‡j‹Eø3Éf‹ÁáQ‹URjèú¿Mü‹Uô‹ ЉA¿Uü‹Eô‹ ƒyu ‹URjè2ëD¿EüƒÀ¿Mü‹Uô‹ Šf‰¿Uü‹Eô‹ ‹Uøf‹f‰A‹Mø‹Q‰Uøé8ÿÿÿ‹E‹Mô‰HR¸‹å]ÂÌÌÌÌÌÌU‹ìƒì$V‹E‹H‰Müjj‹URjèa‹M‹Q‹M ‰Š‹U‹B‹M ƒ<ˆu‹URjè›éw‹E‹H‰Mø‹U‹Ef‹f‰J‹U‹Ef‹Hf‰ ‹U ‹Eø‹ Q‹U ‹Eü‹ ŠQR‹EPè#9ÿÿ…Àu3Àé)‹M ‹Uø‹Šƒ8„õ‹M ‹Uü‹Š3ÉŠHƒùlt‹U ‹Eü‹ 3ÒŠQƒúj…zjEäPè jj‹MQjè’‹U ‹Mø‹‘‰B‹E ‹Mø‹ƒzu‹EPjèÌ é¨‹M‹Q3Àf‹B…À„½‹M ‹Uø‹Š‹M‹Q3Éf‹J9 ‹U ‹Eø‹ ‹U‹B3Òf‹‹E‹@3öf‹p+Ö9z‹M ‹Uø‹Š‹Q‹U‹B‹M‹Q3Éf‹J‹PÑREæPÿq5sƒÄ ‹M‹Q‹E ‹Mø‹f‹Jf‹U‹Bf‰H‹M‹Q‹E ‹Mø‹f‹Jf+‹U‹Bf‰HÇEàë‹M ‹Uø‹Š‹QUæR‹EPèm)ÿÿ‰Eàƒ}àu3À鮋M ‹Uü‹ŠŠHˆMä‹U ‹Eü‹ ŠQˆUåj‹E ‹Mø‹‹BPMäQèwéQj‹U ‹Eø‹ ‹R‹EPjè‹M ‹Uø‹ ЉA‹U ‹Eø‹ ƒyu‹URjèS é/‹E‹H3Òf‹Q…Ò„Ê‹E ‹Mø‹‹E‹H3Àf‹A9­‹M ‹Uø‹Š‹M‹Q3Éf‹ ‹U‹R3öf‹r+Î9ƒ‹E ‹Mø‹‹P‹M‹Q‹E‹H3Àf‹A‹JÈQ‹U ‹Eø‹ ‹QRÿq5sƒÄ ‹E‹H‹U ‹Eø‹f‹Af‹M‹Qf‰B‹E‹H‹U ‹Eø‹f‹Af+‹M‹Qf‰BÇEÜë%‹E ‹Mø‹‹P‹M ‹Uø‹Š‹HQ‹URèÞ'ÿÿ‰E܃}Üu3Àë"‹E P‹M¿R‹EPè7…ÀuƒÈÿë¸^‹å]ÂÌÌÌÌÌÌÌÌU‹ìƒì ‹E¹;H,Ò÷Ú…Òt ‹EƒxRu3Àé‚ÇEø‹M‹Q@‰Uüë‹EøƒÀ‰Eø‹MüƒÁ‰Mü‹U‹Eø;B,}Q‹M‹Uü;Q,~ ‹E‹Mü+H,‰Mü‹UükÒ ‹E‹H(Tô‰Uô‹Eôƒ8ÿt‹Môƒ9t‹Uô‹E‹J;HRu¸ëë’3À‹å]ÂÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìjÿÿTp5s]ÃÌÌÌU‹ìjÿÿ¤p5s]ÃÌÌÌU‹ìƒì‹E‹ˆò‹ö‰Mð‰Uô‹E‹ˆú‹þ‰Mø‰Uü‹Eð%ÿƒà…Àtnƒ}thj‹MƒÁQ‹URjèw‰Eì‹EP‹M Q‹UìRÿƒ}uÇE ;‹E ‹å] ’±3sDZ3s‰±3s}±3sq±3sü±3s±±3s›±3s²3sÌÌÌÌÌÌÌÌU‹ìQƒ}uh'jèê”ÿÿ3Àëp‹EPèÍùÿÿ…Àu3Àë_‹Mƒyth'‹URè¾”ÿÿ3ÀëDj‹E P‹MQè;‰Eüƒ}üu3Àë(‹Uü3Àf‹9Eƒ}}h'‹MQè}”ÿÿ3Àë‹Eü‹å] U‹ìƒìÇEøÇEü‹E‹HN‰Møƒ} | ‹U¿BL9E ~ƒ}th!'‹MQè-”ÿÿ3Àë@‹U ƒê9Uü}2ƒ}øuƒ}th!'‹EPè”ÿÿ3Àë‹Mø‹Q‰Uø‹EüƒÀ‰EüëËEø‹å] ÌÌÌU‹ìƒì W‹}ƒÉÿ3Àò®÷уÁÿ‰Mô‹E PèÞÇþÿƒÄ‹M”Á‚‰Uü‹Eüƒxt‹Mü‹QR‹EPè…ôÿÿƒÄ‹MüÇAj‹UôƒÂR‹EPjè´óÿÿ‰Eøƒ}øu ‹MQjèúÿÿë'‹UôR‹EøP‹MQèÍôÿÿ‹UøUôÆ‹E‹Mø‰¸_‹å]ÂU‹ìQSVWjjP‹EPjèZóÿÿ‰Eüƒ}üu3Àé_‹Mü‹œ5s‰f¡œ5sf‰A‹M Qè ÇþÿƒÄkÀ ‹¸º•5s‹UüƒÉÿ3Àò®÷Ñ+ù‹÷‹Ù‹úƒÉÿ3Àò®ƒÇÿ‹ËÁéó¥‹Ëƒáó¤ƒ}t`¿l›5s‹UüƒÉÿ3Àò®÷Ñ+ù‹÷‹Ù‹úƒÉÿ3Àò®ƒÇÿ‹ËÁéó¥‹Ëƒáó¤‹}‹UüƒÉÿ3Àò®÷Ñ+ù‹÷‹Ù‹úƒÉÿ3Àò®ƒÇÿ‹ËÁéó¥‹Ëƒáó¤ƒ}t/‹}‹UüƒÉÿ3Àò®÷Ñ+ù‹÷‹Ù‹úƒÉÿ3Àò®ƒÇÿ‹ËÁéó¥‹Ëƒáó¤¿l›5s‹UüƒÉÿ3Àò®÷Ñ+ù‹÷‹Ù‹úƒÉÿ3Àò®ƒÇÿ‹ËÁéó¥‹Ëƒáó¤‹EüP‹MQ苯þÿƒÄ…Àu‹UüR‹EPè·òÿÿƒÄ3Àë‹MüQ‹URè£òÿÿƒÄ¸_^[‹å]ÂÌÌU‹ìƒìdVWƒ}t ‹E¾…Éu3‹U RèŸÅþÿƒÄkÀ 3ÉŠˆ¹•5sƒá…Éth1'‹URè\‘ÿÿ3Àé&‹E PèlÅþÿƒÄ‹M”Á‚‰Uü‹E ‰E܃}ÜwP‹MÜÿ$i¼3s‹U‰Uø‹Eø¾…Ét6‹Uø¾ƒø0| ‹Mø¾ƒú9~h2'‹EPèòÿÿ3À鼋MøƒÁ‰MøëÀ‹U ‰U؃}Ø‡Š‹EØÿ$…¼3s‹MQÿàp5sƒÄ‰Eä‹U¿Bƒøu3Àétƒ}ä}ÇEädÇEøœ5së‹M‰Møƒ}äuh2'‹URèsÿÿ3Àé=‹EøP‹MüƒÁQ‹U R‹EPètüÿÿ…Àu3Àé‹MüŠ€Ê‹Eüˆ‹Mº;Q,À÷Ø…Àu ‹Mƒy(t ‹URèÛÿÿ‹E‹Mä‰H,éÕ‹URÿäp5sƒÄ‰Eàƒ}àÿt$ƒ}à| }à°vh2'‹EPèÖÿÿ3Àé ‹MQ‹UüƒÂR‹E P‹MQè×ûÿÿ…Àu3Àé}‹U‹Eà‰‚¢‹MüŠ€Ê‹EüˆéZ‹MQÿäp5sƒÄ‰Eàƒ}à}h2'‹URèjÿÿ3Àé4‹EP‹MüƒÁQ‹U R‹EPèkûÿÿ…Àu3Àéj‹MQ‹U R‹EPèýûÿÿ…Àu3Àéó‹MüŠ€Ê‹EüˆéÜ‹MQÿäp5sƒÄ‰Eàƒ}à| }àÿÿÿ~h2'‹URèãŽÿÿ3Àé­‹EP‹MüƒÁQ‹U R‹EPèäúÿÿ…Àu3À銋M‹Uà‰‘‹EüЀɋUüˆ ég¡¼’5sPj‹M Q‹URèVûÿÿ…Àu3ÀéL‹EüЀɋUüˆ é5‹EüЀɋUüˆ é#‹EüЀɋUüˆ jj‹EPè ÇþÿƒÄ é‹MüŠ€Ê‹Eüˆjj‹MQèëÆþÿƒÄ éß‹}ƒÉÿ3Àò®÷уÁÿƒù vh2'‹URèñÿÿ3À黋}UìƒÉÿ3Àò®÷Ñ+ù‹÷‹Á‹úÁéó¥‹Èƒáó¤MìQèΕƒÄÇEèë ‹UèƒÂ‰Uèƒ}è ¶‹Eè‹ …””5s‰MÔUì‰UЋEЊˆMÏ‹UÔ: u.€}Ït‹EЊHˆM΋UÔ:JuƒEЃEÔ€}ÎuÌÇEÈëÀƒØÿ‰EÈ‹MȉMă}ÄuM‹¼’5sREìP‹M Q‹URèóùÿÿ…Àu3Àéé‹EüЀɋUüˆ ¸‹MèÓà‹Müf‹Qf ЋEüf‰Pëé7ÿÿÿƒ}è uh2'‹MQèÕŒÿÿ3ÀéŸé•‹}ƒÉÿ3Àò®÷уÁÿƒùvh2'‹URè§Œÿÿ3Àéq‹}UìƒÉÿ3Àò®÷Ñ+ù‹÷‹Á‹úÁéó¥‹Èƒáó¤MìQè„”ƒÄÇEÀ”‘5sUì‰U¼‹E¼ŠˆM»‹UÀ: u.€}»t‹E¼ŠHˆMº‹UÀ:JuƒE¼ƒEÀ€}ºuÌÇE´ëÀƒØÿ‰E´‹M´‰M°ƒ}°u‹Uüf‹B ‹Müf‰AÆEðé†ÇE¬œ5sUì‰U¨‹E¨ŠˆM§‹U¬: u.€}§t‹E¨ŠHˆM¦‹U¬:JuƒE¨ƒE¬€}¦uÌÇE ëÀƒØÿ‰E ‹M ‰Mœƒ}œu‹Uüf‹B ‹Müf‰AÆEîëh2'‹URèx‹ÿÿ3ÀëE¡¼’5sPMìQ‹U R‹EPè-øÿÿ…Àu3Àë&‹MüŠ€Ê‹Eüˆëh2'‹MQè8‹ÿÿ3Àë¸_^‹å] j¶3s°¶3sj¶3s°¶3sj¶3sj¶3sʶ3s}¹3s¸3sǺ3s€¸3s¸3sõ¸3sõ¸3s'¹3sõ¸3sõ¸3sõ¸3sõ¸3sõ¸3s9¹3s[¹3s'¹3s‡·3sõ¸3sÌÌÌU‹ìƒìÇEèÇEøÇEôÇEðë ‹EðƒÀ‰Eðƒ}ðz‹MðkÉ 3ÒŠ‘¹•5sƒâ…Ò„\‹EðkÀ 3ÉŠˆ¹•5sƒá…Ét‹UðkÒ 3ÀŠ‚¸•5s‰EèÇEøéèƒ}ðua‹MðkÉ 3Òf‹‘•5sƒâ…Òt‹EðkÀ 3ÉŠˆ¸•5s‰MèÇEø”‘5s‹UðkÒ 3Àf‹‚•5sƒà…Àt‹MðkÉ 3ÒŠ‘¸•5s‰UèÇEøœ5séƒ}ðu[ÇEìë ‹EìƒÀ‰Eìƒ}ì }A‹MðkÉ 3Òf‹‘•5s¸‹MìÓà#Ð…Òt ‹MðkÉ 3ÒŠ‘¸•5s‰Uè‹Eì‹ …””5s‰Møëë°ë ‹Uð‰Uè‹EðkÀ 3ÉŠˆ¸•5skÉ ‹‘¾•5s‰Uø‹EøP‹MèQ‹UR襽þÿƒÄ ‹Eè‰Eä‹Mäƒé‰Mäƒ}äw‹Eä3ÒŠî¾3sÿ$•æ¾3sÇEôésþÿÿƒ}ôtT‹MQè°¨þÿƒÄ…Àu3ÀëE‹URè¼oþÿƒÄ‰Eüƒ}ütƒ}üu3Àë&‹EPèÍzþÿƒÄƒøþtëíëÌ‹MQè¸ÅþÿƒÄ¸‹å]Âu¾3s|¾3sU‹ìƒìlVW‹E P蟼þÿƒÄ‰Eèƒ}t ‹M¾…Òu?‹EèkÀ 3ÉŠˆ¹•5sƒá…Ét*‹UèkÒ 3ÀŠ‚¹•5sƒà…Àuh1'‹MQè1ˆÿÿ3Àé‹Uè‹EŒÐ‚‰Mü‹Uü3ÀŠƒà…Àu3Àéö‹M ‰Mäƒ}ä‡ä‹Eä3ÒŠÂ3sÿ$•‰Â3s‹Müƒytj‹Uü‹B‰Eà‹M‰MÜ‹UÜŠˆEÛ‹Mà:u.€}Ût‹UÜŠBˆEÚ‹Mà:AuƒE܃Eà€}ÚuÌÇEÔëÒƒÚÿ‰UÔ‹EÔ‰EЃ}Ðu ¸éaéZ‹Mº;Q,À÷Ø…Àt ¸é?é8¸é0‹}ƒÉÿ3Àò®÷уÁÿƒù vé‹}UðƒÉÿ3Àò®÷Ñ+ù‹÷‹Á‹úÁéó¥‹Èƒáó¤MðQè ƒÄ‹Uü3Àf‹Bƒà…ÀtjÇEÌ”‘5sMð‰MÈ‹UÈŠˆEÇ‹MÌ:u.€}Çt‹UÈŠBˆEÆ‹MÌ:AuƒEȃEÌ€}ÆuÌÇEÀëÒƒÚÿ‰UÀ‹EÀ‰E¼ƒ}¼u ¸épëx‹Mü3Òf‹Qƒâ…ÒthÇE¸œ5sEð‰E´‹M´ŠˆU³‹E¸:u.€}³t‹M´ŠQˆU²‹E¸:PuƒE´ƒE¸€}²uÌÇE¬ëɃÙÿ‰M¬‹U¬‰U¨ƒ}¨u ¸éöéï‹}ƒÉÿ3Àò®÷уÁÿƒù véÖ‹}UðƒÉÿ3Àò®÷Ñ+ù‹÷‹Á‹úÁéó¥‹Èƒáó¤MðQè˃ÄÇEìë ‹UìƒÂ‰Uìƒ}ì ‹‹Eü3Éf‹H‹Ñ¸‹MìÓà#Ð…ÒtkMð‰M¤‹Uì‹•””5s‰E ‹M ŠˆUŸ‹E¤:u.€}Ÿt‹M ŠQˆUž‹E¤:PuƒE ƒE¤€}žuÌÇE˜ëɃÙÿ‰M˜‹U˜‰U”ƒ}”u¸ëébÿÿÿ3À_^‹å] %À3sÁ3s­¿3sQÀ3sGÀ3sU‹ìƒìTVWƒ}t ‹E¾…Éu3‹U Rè߸þÿƒÄkÀ 3ÉŠˆ¹•5sƒá…Éth1'‹UR蜄ÿÿ3Àéê‹E P謸þÿƒÄ‹M”Á‚‰Uü‹Eü3ÉŠƒá…Éuƒ} tƒ} t ¸é­‹U ‰Uèƒ}臆‹Mè3ÀŠ È3sÿ$…íÇ3s‹UÇ‚¢ÿÿÿÿ‹Eüƒxt‹Mü‹QR‹EPèåÿÿƒÄ‹MüÇA‹UüŠ4‹MüˆéB‹U¿Bƒøu3Àé4‹Müƒyt‹Uü‹BP‹MQè¶äÿÿƒÄ‹UüÇBƒ} u‹EÇ€ëVƒ} t!jh(’5s‹M Q‹URèZðÿÿ…Àu3ÀéÔë/‹E¹;H,Ò÷Ú…Òt‹Eƒx(t ‹MQèHÎÿÿ‹UÇB,‹EüŠ€ñ‹Uüˆ 錡À’5sPj‹M Q‹URè÷ïÿÿ…Àu3Àéq‹EüŠ€ñ‹Uüˆ éZ‹EüŠ€ñ‹Uüˆ éH‹}ƒÉÿ3Àò®÷уÁÿƒù vh2'‹EPèÖ‚ÿÿ3Àé$‹}UðƒÉÿ3Àò®÷Ñ+ù‹÷‹Á‹úÁéó¥‹Èƒáó¤MðQ賊ƒÄÇEìë ‹UìƒÂ‰Uìƒ}ì È‹Eì‹ …””5s‰MäUð‰Uà‹EàŠˆMß‹Uä: u.€}ßt‹EàŠHˆMÞ‹Uä:JuƒEàƒEä€}ÞuÌÇEØëÀƒØÿ‰EØ‹M؉MÔƒ}Ôu_‹Uü3Àf‹Bº‹MìÓâ#Â…Àu3ÀéU¡À’5sPMðQ‹U R‹EPè¹îÿÿ…Àu3Àé3º‹MìÓâ‹Eüf‹Hf3Ê‹Uüf‰Jëé%ÿÿÿƒ}ì uh2'‹EPè¨ÿÿ3Àéö‹Mü3Òf‹Q…Òu ‹EüŠ€ñ‹Uüˆ éÒ‹}ƒÉÿ3Àò®÷уÁÿƒùvh2'‹EPè`ÿÿ3À鮋}UðƒÉÿ3Àò®÷Ñ+ù‹÷‹Á‹úÁéó¥‹Èƒáó¤MðQè=‰ƒÄÇEД‘5sUð‰UÌ‹EÌŠˆMË‹UÐ: u.€}Ët‹EÌŠHˆMÊ‹UÐ:JuƒẼEЀ}ÊuÌÇEÄëÀƒØÿ‰EÄ‹MĉMÀƒ}Àu2‹Uü3Àf‹Bƒà…Àu3Àé ‹Müf‹Qfƒò‹Eüf‰PÆEôéœÇE¼œ5sMð‰M¸‹U¸ŠˆE·‹M¼:u.€}·t‹U¸ŠBˆE¶‹M¼:AuƒE¸ƒE¼€}¶uÌÇE°ëÒƒÚÿ‰U°‹E°‰E¬ƒ}¬u,‹Mü3Òf‹Qƒâ…Òu3Àë}‹Eüf‹Hfƒñ‹Uüf‰JÆEòëh2'‹EPè€ÿÿ3ÀëS‹ À’5sQUðR‹E P‹MQè¶ìÿÿ…Àu3Àë3‹Uü3Àf‹B…Àu ‹MüŠ€ò‹Eüˆëh2'‹MQè´ÿÿ3Àë¸_^‹å] žÃ3s˜Ä3s±Ã3sÆ3sTÄ3s†Ä3sZÃ3sÌÌÌÌU‹ìƒì ÇEèÇEì‹EPè3åÿÿ…Àu3Àér‹M¿‘D9U ƒ} }h:'‹EPè%ÿÿ3ÀéH‹M ƒé‰Mô‹U‹B$‹Mô‹ˆ‹B&P‹M‹Q$‹Eô‹ ‚3ÒŠQ$R‹EPèšèÿÿ‰Eü‹MƒyDu3Àé‹UƒºJu@j‹E¿ˆDÁáQ‹URjèðÞÿÿ‹M‰J‹UƒºJu‹EPjè0åÿÿ鵋MÇF‹U‹‚J‹Môƒ<ˆt?‹U‹‚J‹Mô‹ˆR‹EPèCßÿÿƒÄ‹M‹‘J‹EôÇ‚ƒ}u ¸éWƒ}uh<'‹MQè~ÿÿ3Àé<‹U‰Uà‹Eàƒè‰Eàƒ}à‡ì‹Màÿ$¾Ë3sÇEäjÇEøÐ$2séäÇEä/ÇEìp3séÑÇEä-ÇEø&3sé¾ÇEä0ÇEø +3sé«ÇEä4ÇEø +3sé˜ÇEä8ÇEø 03sé…ÇEä>ÇEø053sëuÇEä2ÇEøð:3sëeÇEä<ÇEø`3sëUÇEä=ÇEøø2sëEÇEä;ÇEøÀ73së5ÇEäzÇEø@3së%ÇEä:ÇEøù2sëh9'‹URèÿ|ÿÿ3Àé"‹EäP‹MüQè+ÿÿƒÄ…Àuh;'‹URèÖ|ÿÿ3Àéù‹E‹ˆJ‰Mèjj‹URjèôÜÿÿ‹Mô‹U艊‹Eô‹Mèƒ<u‹URjè4ãÿÿ鹋Eô‹M苉Uð‹Eðf‹M f‰‹Uðf‹Ef‰Bƒ}uaƒ}tƒ} uI‹M‹Q$‹Eô‹ ‚‹Q&Rj‹E‹H$‹Uô‹‘f¶H$Qèßÿÿ¿Ð‹Eð‰Pƒ} u‹Mð‹QƒÂ‹Eð‰Pë ‹MðÇAÿÿÿÿë ‹Uð‹E‰B‹Mð‹U‰Qƒ}ìt ‹Eð‹Mì‰H ë ‹Uð‹Eø‰B ¸‹å]ÃÚÉ3síÉ3sÊ3s´É3sÇÉ3s#Ê3sCÊ3s3Ê3sÊ3s´É3s´É3s´É3sÇÉ3sSÊ3scÊ3ssÊ3s¡É3s¡É3s¡É3s¡É3sÌÌU‹ìƒì‹EPèQáÿÿ…Àu3À醋M¿‘D9U ƒ} }h:'‹EPèC{ÿÿ3Àë_‹M ƒé‰Mü‹UƒºJtƒ}t‹E‹ˆJ‹Uüƒ<‘uh<'‹EPè{ÿÿ3Àë ‹M‹‘J‹Eü‹ ‚‰Mø‹Uø‹E‰B¸‹å]ÃÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì0‹E¿ˆD9M }‹UƒºJt‹E‹ˆJ‹U ƒ<‘u ¸é0‹E‹HD‰Mü‹U‹B$‹M ‹ˆ‹B&P‹M‹Q$‹E ‹ ‚3ÒŠQ$R‹EPèäÿÿ‰Eðƒ}ð"tƒ}ð#u"‹M ‹Uü‹Š‹H‹Q‰UÜ‹E ‹Mü‹‹‰Eäë‹M ‹Uü‹Š‹H‰MÜ‹U ‹Eü‹ ‹‰Uä‹E‹ˆJ‹U ‹‘‰Eè‹Mèƒy u3À錃}ätƒ}ÜuJ‹Uèƒzt ‹Eè‹HÇÿÿÿÿ‹Uè‹BP‹Mè‹QR‹Eè¿HQ‹URè?ƒøÿu3Àé@¸é6‹Eè‹H‰Mø‹Uèƒzt ‹Eè‹HÇ‹Uè¿B‰EЋMЃé‰MЃ}Їò‹UÐÿ$•3Ô3sƒ}øu‹Eè‹HÆé؃}ø~ ‹Uøƒê‰Uø‹Eè‹HQ‹UøR‹Eè‹HQj/‹UäR‹EÜP‹MðQ‹UR‹EèÿP ƒÄ ‰Eìƒ}ìÿu3Àé‘j ‹Mè‹QR‹Eè¿HQ‹UìR‹Eè‹HQèCéf‹UðRj‹EäP‹MÜQ軉Eäƒ}ø|ƒ}ø ÇEøëƒ}ø~ ‹Uøƒê‰Uø‹Eè‹HQ‹UøR‹Eè‹HƒÁQj/‹UäR‹EÜP‹MðQ‹UR‹EèÿP ƒÄ ‰Eìƒ}ìÿu3Àéñ‹Mè‹Qf‹Eìf‰éÚ‹MðQj ‹UäR‹EÜPè/‰Eäƒ}ø|ƒ}ø ÇEøëƒ}ø~ ‹Møƒé‰Mø‹UøR‹Eè‹HƒÁQj-‹UäR‹EÜP‹MðQ‹UR‹EèÿP ƒÄ‰Eìƒ}ìÿu3Àél‹Mè‹Qf‹Eìf‰éU‹MøQ‹Uè‹BPj-‹MäQ‹UÜR‹EðP‹MQ‹UèÿR ƒÄ‰Eìƒ}ìÿu3Àé$j‹EøP‹Mè¿QR‹EìP‹Mè‹QRèÙéü‹EðPj ‹MäQ‹UÜRèQ‰Eä‹EøP‹Mè‹QRj0‹EäP‹MÜQ‹UðR‹EP‹MèÿQ ƒÄƒøÿu3Àé¹é¯‹UðRj ‹EäP‹MÜQè‰Eä‹UøR‹Eè‹HQj4‹UäR‹EÜP‹MðQ‹UR‹EèÿP ƒÄƒøÿu3Àéléb‹MðQj ‹UäR‹EÜPè·‰Eä‹MøQ‹Uè‹BPj8‹MäQ‹UÜR‹EðP‹MQ‹UèÿR ƒÄƒøÿu3Àéé‹EðPj ‹MäQ‹UÜRèj‰Eä‹EøP‹Mè‹QRj>‹EäP‹MÜQ‹UðR‹EP‹MèÿQ ƒÄƒøÿu3ÀéÒéÈ‹UøR‹Eè‹HQj2‹UäR‹EÜP‹MðQ‹UR‹EèÿP ƒÄƒøÿu3Àé›é‘ƒ}ð/t ƒ}ð#tƒ}ð'u_ƒ}ð'uÆEØëÆEØ ‹Mä‰Mà‹Uä‹EÜLÿ‰Môƒ}à~0‹Uô3ÀŠ‹MØáÿ;Áu‹Uô;UÜt‹Eàƒè‰Eà‹Môƒé‰MôëÊ‹Uà‰Uä‹EøP‹Mè‹QRj=‹EäP‹MÜQ‹UðR‹EP‹MèÿQ ƒÄƒøÿu3Àéóéé‹UðRj ‹EäP‹MÜQè>‰Eä‹UøR‹Eè‹HQj<‹UäR‹EÜP‹MðQ‹UR‹EèÿP ƒÄƒøÿu3Àé¦éœ‹Mè‹Q‰UÔ‹EÔÆ‹MÔÆA‹UðRj ‹EäP‹MÜQèÛ‰Eä‹UøR‹Eè‹HQjl‹UäR‹EÜP‹MðQ‹UR‹EèÿP ƒÄƒøÿu3ÀéCé9‹MðQj ‹UäR‹EÜP莉Eä‹MøQ‹Uè‹BPj;‹MäQ‹UÜR‹EðP‹MQ‹UèÿR ƒÄƒøÿu3Àéöéìƒ}ð/t ƒ}ð#tƒ}ð'u^ƒ}ð'uÆEØëÆEØ ‹Eä‰Eà‹Mä‹UÜD ÿ‰Eôƒ}à~/‹Mô3ÒŠ‹EØ%ÿ;Ðu‹Mô;MÜt‹Uàƒê‰Uà‹Eôƒè‰EôëË‹Mà‰Mä‹UøR‹Eè‹HQj:‹UäR‹EÜP‹MðQ‹UR‹EèÿP ƒÄƒøÿu3ÀëRëK‹MðQj ‹UäR‹EÜPè ‰Eä‹MøQ‹Uè‹BPjz‹MäQ‹UÜR‹EðP‹MQ‹UèÿR ƒÄƒøÿu3Àë ë3À븋å]Â,Ð3syÐ3sÆÐ3s_Î3sÓÏ3s`Ñ3s—Ñ3s?Ò3sÑ3s<Î3s<Î3sÂÎ3sNÏ3sïÒ3sÝÓ3s<Ó3s¢Ò3s¢Ò3sŒÒ3sŒÒ3sÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì ÇEø‹E‰Eôƒ}ô#tƒ}ô'tƒ}ô/të?‹M ‹UD ÿ‰Eü‹Mü;Mr‹Uü3ÀŠ‹Máÿ;Áu ‹Uüƒê‰UüëÙ‹Eü+EƒÀë‹E ‹å]ÂÌU‹ìƒìƒ} uy‹E ‹MTÿ‰Uüƒ}ÿt‹E ;E| ‹Müƒé‰Mü‹Uü;Uv‹Eü3ÉŠƒù u ‹Uüƒê‰UüëëëÝ‹Eü;Eu‹Mü3ÒŠƒú u‹EüÆë‹MüƒÁ‰Mü‹UüƸëgƒ} u ‹Eƒè‰Eøë‹M‰Mø‹U ‰Uôë ‹EôƒÀ‰Eô‹Mô;Mø} ‹UUôŠEˆëâƒ} u‹Mô;Mø~‹Uø‰Uðë‹Eô‰Eð‹MMðÆ¸‹å]ÂÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì$ÇEôÇEè‹EP‹M Q‹URèkÜÿÿ‰Eäƒ}äu3Àé‹Eƒè‰Eð‹Mä‹Q‹Eð‹ ‚‹Q R‹Eä‹H‹Uð‹‘3ÉŠHQ‹URè×Úÿÿ‰Eü‹Eäƒxu8j‹Mä3Òf‹ÁâR‹EPjèBÑÿÿ‹Mä‰A‹Uäƒzu‹EPjèˆ×ÿÿ霋MÇF‹Uä‹B‹Mðƒ<ˆt9‹Uä‹B‹Mð‹ˆR‹EPè¡ÑÿÿƒÄ‹Mä‹Q‹EðÇ‚ƒ}u ¸éGƒ}uh<'‹MQèzpÿÿ3Àé,‹U‰UÜ‹E܃è‰E܃}܇ì‹MÜÿ$MÙ3sÇEàlÇEøÐ$2séäÇEà/ÇEèp3séÑÇEà-ÇEø&3sé¾ÇEà0ÇEø +3sé«ÇEà4ÇEø +3sé˜ÇEà8ÇEø 03sé…ÇEà>ÇEø053sëuÇEà2ÇEøð:3sëeÇEà<ÇEø`3sëUÇEà=ÇEøø2sëEÇEà;ÇEøÀ73së5ÇEàzÇEø@3së%ÇEà:ÇEøù2sëh9'‹URè`oÿÿ3Àé‹EàP‹MüQèŒ ÿÿƒÄ…Àuh>'‹URè7oÿÿ3Àéé‹Eä‹H‰Môjj‹URjèXÏÿÿ‹Mð‹Uô‰Š‹Eð‹Môƒ<u‹URjè˜Õÿÿ鬋Eð‹Mô‹‰Uì‹Eìf‹Mf‰‹Uìf‹Ef‰Bƒ}uTƒ}tƒ} u<‹Mä‹Q‹Eð‹ ‚‹Q Rjf‹EüPè„Ñÿÿ¿È‹Uì‰Jƒ} u‹Eì‹HƒÁ‹Uì‰Jë ‹EìÇ@ÿÿÿÿë ‹Mì‹U‰Q‹Eì‹M‰Hƒ}èt ‹Uì‹Eè‰B ë ‹Mì‹Uø‰Q ¸‹å]Ãy×3sŒ×3sŸ×3sS×3sf×3sÂ×3sâ×3sÒ×3s²×3sS×3sS×3sS×3sf×3sò×3sØ3sØ3s@×3s@×3s@×3s@×3sÌÌÌU‹ìƒì ‹EP‹M Q‹URèÙØÿÿ‰Eôƒ}ôu3ÀëV‹Eƒè‰Eü‹Môƒytƒ}t‹Uô‹B‹Müƒ<ˆuh<'‹URè—mÿÿ3Àë‹Eô‹H‹Uü‹‘‰Eø‹Mø‹U‰Q¸‹å]ÃÌÌU‹ìƒì4j‹E P‹MQèëØÿÿ‰E؃}Øu3ÀéB‹U؃zt‹EØ‹H‹Uƒ<‘u ¸é ‹EØ‹H‹U‹‘‹H Q‹UØ‹B‹M‹ˆ3ÀŠBP‹MQè®Öÿÿ‰Eð‹UƒzRt‹E‹HR‹U ‹D‘ü‹H‰Müƒ}üu3ÀéÉ‹U‹Eü‹ ‹Q‰UÜ‹E‹Mü‹‹‰Eä‹MØ‹Q‹E‹ ‚‰Mè‹Uèƒz u3Àéƒ}ätƒ}ÜuJ‹Eèƒxt ‹Mè‹QÇÿÿÿÿ‹Eè‹HQ‹Uè‹BP‹Mè¿QR‹EPèæ ƒøÿu3ÀéA¸é7‹Mè‹Q‰Uø‹Eèƒxt ‹Mè‹QÇ‹Eè¿H‰MÌ‹Ũê‰Ũ}̇ó‹EÌÿ$…á3sƒ}øu‹Mè‹QÆéÙƒ}ø~ ‹Eøƒè‰Eø‹Mè‹QR‹EøP‹Mè‹QRj/‹EäP‹MÜQ‹UðR‹EP‹MèÿQ ƒÄ ‰Eìƒ}ìÿu3Àé’j ‹Uè‹BP‹Mè¿QR‹EìP‹Mè‹QRèêøÿÿég‹EðPj‹MäQ‹UÜRèbøÿÿ‰Eäƒ}ø|ƒ}ø ÇEøëƒ}ø~ ‹Eøƒè‰Eø‹Mè‹QR‹EøP‹Mè‹QƒÂRj/‹EäP‹MÜQ‹UðR‹EP‹MèÿQ ƒÄ ‰Eìƒ}ìÿu3Àéò‹Uè‹Bf‹Mìf‰éÛ‹UðRj ‹EäP‹MÜQèÖ÷ÿÿ‰Eäƒ}ø|ƒ}ø ÇEøëƒ}ø~ ‹Uøƒê‰Uø‹EøP‹Mè‹QƒÂRj-‹EäP‹MÜQ‹UðR‹EP‹MèÿQ ƒÄ‰Eìƒ}ìÿu3Àém‹Uè‹Bf‹Mìf‰éV‹UøR‹Eè‹HQj-‹UäR‹EÜP‹MðQ‹UR‹EèÿP ƒÄ‰Eìƒ}ìÿu3Àé%j‹MøQ‹Uè¿BP‹MìQ‹Uè‹BPè€÷ÿÿéý‹MðQj ‹UäR‹EÜPèøöÿÿ‰Eä‹MøQ‹Uè‹BPj0‹MäQ‹UÜR‹EðP‹MQ‹UèÿR ƒÄƒøÿu3Àéºé°‹EðPj ‹MäQ‹UÜRè«öÿÿ‰Eä‹EøP‹Mè‹QRj4‹EäP‹MÜQ‹UðR‹EP‹MèÿQ ƒÄƒøÿu3Àéméc‹UðRj ‹EäP‹MÜQè^öÿÿ‰Eä‹UøR‹Eè‹HQj8‹UäR‹EÜP‹MðQ‹UR‹EèÿP ƒÄƒøÿu3Àé é‹MðQj ‹UäR‹EÜPèöÿÿ‰Eä‹MøQ‹Uè‹BPj>‹MäQ‹UÜR‹EðP‹MQ‹UèÿR ƒÄƒøÿu3ÀéÓéÉ‹EøP‹Mè‹QRj2‹EäP‹MÜQ‹UðR‹EP‹MèÿQ ƒÄƒøÿu3Àéœé’ƒ}ð/t ƒ}ð#tƒ}ð'u_ƒ}ð'uÆEÔëÆEÔ ‹Uä‰Uà‹Eä‹MÜTÿ‰Uôƒ}à~0‹Eô3ÉŠ‹UÔâÿ;Êu‹Eô;EÜt‹Màƒé‰Mà‹Uôƒê‰UôëÊ‹Eà‰Eä‹MøQ‹Uè‹BPj=‹MäQ‹UÜR‹EðP‹MQ‹UèÿR ƒÄƒøÿu3Àéôéê‹EðPj ‹MäQ‹UÜRèåôÿÿ‰Eä‹EøP‹Mè‹QRj<‹EäP‹MÜQ‹UðR‹EP‹MèÿQ ƒÄƒøÿu3Àé§é‹Uè‹B‰EЋMÐÆ‹UÐÆB‹EðPj ‹MäQ‹UÜRè‚ôÿÿ‰Eä‹EøP‹Mè‹QRjl‹EäP‹MÜQ‹UðR‹EP‹MèÿQ ƒÄƒøÿu3ÀéDé:‹UðRj ‹EäP‹MÜQè5ôÿÿ‰Eä‹UøR‹Eè‹HQj;‹UäR‹EÜP‹MðQ‹UR‹EèÿP ƒÄƒøÿu3Àé÷éíƒ}ð/t ƒ}ð#tƒ}ð'u_ƒ}ð'uÆEÔëÆEÔ ‹Mä‰Mà‹Uä‹EÜLÿ‰Môƒ}à~0‹Uô3ÀŠ‹MÔáÿ;Áu‹Uô;UÜt‹Eàƒè‰Eà‹Môƒé‰MôëÊ‹Uà‰Uä‹EøP‹Mè‹QRj:‹EäP‹MÜQ‹UðR‹EP‹MèÿQ ƒÄƒøÿu3ÀëRëK‹UðRj ‹EäP‹MÜQèFóÿÿ‰Eä‹UøR‹Eè‹HQjz‹UäR‹EÜP‹MðQ‹UR‹EèÿP ƒÄƒøÿu3Àë ë3À븋å] …Ý3sÒÝ3sÞ3s¸Û3s,Ý3s¹Þ3sðÞ3s˜ß3slÞ3s•Û3s•Û3sÜ3s§Ü3sHà3s7á3s•à3sûß3sûß3såß3såß3sÌÌÌU‹ìƒìVW‹EPèËÿÿ…Àu3Àé˃}u3À龋MÇF‹U‹‚N‰Eø‹M‰Mô‹U ‰Uð‹Eðƒè‰Eðƒ}ð wR‹Uð3ÉŠŠáå3sÿ$Íå3sƒ}}3Àék‹E‰Eôë+‹}ƒÉÿ3Àò®÷щMôë‹M¿ƒÂ‰Uôë ‹E¿ƒÁ‰Mô‹U ‰Uì‹Eìƒè‰Eìƒ}ì w3‹Uì3ÉŠŠóå3sÿ$ëå3sj‹EôP‹MQjè Åÿÿ‰Eüƒ}üu3Àéð‹U ‰Uè‹Eèƒè‰Eèƒ}è‡À‹Mèÿ$ýå3s‹U‹EøƒÀJ‹ ‰‹J‰H‹J‰H‹J ‰H f‹Jf‰HŠRˆPé–‹E‹MøƒÁ]‹‰‹P‰Q‹P‰Q‹P ‰Q f‹Pf‰QŠ@ˆAéd‹Møƒ9t‹Uø‹P‹MQè ÅÿÿƒÄ‹Uøf‹Eôf‰B‹MôQ‹UüR‹EPè|Åÿÿ‹Mø‹Uü‰é!‹Eøƒxt‹Mø‹QR‹EPèÆÄÿÿƒÄ‹}‹UüƒÉÿ3Àò®÷Ñ+ù‹÷‹Á‹úÁéó¥‹Èƒáó¤‹Mø‹Uü‰QéÔ‹Eøƒx t‹Mø‹Q R‹EPèyÄÿÿƒÄ‹}‹UüƒÉÿ3Àò®÷Ñ+ù‹÷‹Á‹úÁéó¥‹Èƒáó¤‹Mø‹Uü‰Q 釋Eøƒxt‹Mø‹QR‹EPè,ÄÿÿƒÄ‹MôQ‹UüR‹EPè¨Äÿÿ‹Mø‹Uü‰QéL‹Eøƒxt‹Mø‹QR‹EPèñÃÿÿƒÄ‹MôQ‹UüR‹EPèmÄÿÿ‹Mø‹Uü‰Qé‹Eøƒxt‹Mø‹QR‹EPè¶ÃÿÿƒÄ‹Møf‹Uôf‰Q‹Eø‹Mü‰H‹UôR‹EüP‹MQèÄÿÿéË‹Uø‹EŠˆJ黋Uø‹Ef‹f‰Jé©‹Uø‹E‹‰J 陋Uø‹E‹‰J$‹@‰B(郋Mø‹UŠˆA,ëvj‹MøƒÁ.Q‹URè²Ãÿÿëbj‹EøƒÀ6P‹MQèžÃÿÿëNj‹UøƒÂBR‹EPèŠÃÿÿë:j‹MøƒÁ>Q‹URèvÃÿÿë&j‹EøƒÀFP‹MQèbÃÿÿëh9'‹URèÒaÿÿ3Àë¸_^‹å]ÃOâ3sdâ3sƒâ3suâ3sâ3s¶â3s×â3s÷ä3så3så3s^ã3s±ä3s?å3s`å3sLå3s)å3s¡ã3sîã3s;ä3svä3sœå3sˆå3stå3s,ã3súâ3s,ã3súâ3sÌÌÌU‹ìQjjp‹EPjèmÁÿÿ‰Eüƒ}üu3Àé™jj‹MQjèNÁÿÿ‹Uü‰B‹Eüƒxu3Àëwjj‹MQjè,Áÿÿ‹Uü‰B ‹Eüƒx u3ÀëUjj‹MQjè Áÿÿ‹Uü‰B‹Eüƒxu3Àë3jj‹MQjèèÀÿÿ‹Uü‰B‹Eüƒxu3Àë‹M‹Uü‰‘N¸‹å]ÂÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒìHW‹E‹ˆN‰Møƒ}} ÇEüë‹U‰Uü‹EÇ€F‹M ‰Mð‹Uðƒê‰Uðƒ}ð‡,‹Eðÿ$…¤ì3s‹Mø¿Q‰Uôƒ}ÿt‹E;Eô}h'‹MQèò_ÿÿƒÈÿé÷ƒ}ü~‹Uü;Uô}‹Eü‰Eìë‹Mô‰Mì‹Uì‰Uèë‹Eô‰Eè‹Mè‰Mô‹UôR‹EP‹Mø‹Rè'Áÿÿj 3Àƒ}üœÀH#EüP‹M Q‹UôR‹EPèöìÿÿé‹‹Mø‹yƒÉÿ3Àò®÷уÁÿ‰Môƒ}ÿt‹U;Uô}h'‹EPèP_ÿÿƒÈÿéUƒ}ü~‹Mü;Mô}‹Uü‰Uäë‹Eô‰Eä‹Mä‰Màë‹Uô‰Uà‹Eà‰Eô‹MôQ‹Uø‹BP‹MQÿ‹M‹Uø‹B ‰ÇEôé'‹Mø‹U‹A$‰‹I(‰JÇEôé ‹U‹EøŠH,ˆ ÇEôéój‹UR‹EøƒÀ.PèW½ÿÿÇEôéÕj‹MQ‹UøƒÂ6Rè9½ÿÿÇEôé·j‹EP‹MøƒÁ>Qè½ÿÿÇEôé™j‹UR‹EøƒÀBPèý¼ÿÿÇEôë~‹M‹Uø‹BF‰ÇEôëj‹MøƒÁ]‹U‹‰‹A‰B‹A‰B‹A ‰B f‹Af‰BŠIˆJÇEôë4‹UøƒÂJ‹E‹ ‰‹J‰H‹J‰H‹J ‰H f‹Jf‰HŠRˆPÇEô‹Eô_‹å]Â,ë3sCë3s\ë3sxç3s‰ê3së3sÅë3s§ë3ssë3sè3sÖè3swé3sê3sì3sãë3sì3s0ì3sfì3s0ì3sfì3sÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì‹E‰Eø‹Møƒé"‰Møƒ}øX‡,‹Eø3ÒŠÐî3sÿ$•`î3sÇEüéÇEüé ÇEüéýÇEüéñÇEüéåÇEüéÙÇEüéÍÇEüéÁÇEüéµÇEüé©ÇEüéÇEü é‘ÇEü é…ÇEü ë|ÇEü ësÇEü ëjÇEüëaÇEüëXÇEüëOÇEüëFÇEüë=ÇEüë4ÇEüë+ÇEüë"ÇEüëÇEüëÇEüë¸ ¸5së ‹Mü‹œ–5s‹å]ÃÖí3sµí3sÍí3sßí3s©í3sÁí3sí3sIí3s‘í3sUí3saí3s0î3sBî3smí3s…í3syí3sî3sî3s î3sî3s'î3s1í3s=í3súí3sñí3sèí3s9î3sKî3s   ÌÌÌÌÌÌÌU‹ìQ‹EPè3¾ÿÿ…ÀuƒÈÿëf‹MƒyZuƒÈÿëXƒ}}ƒÈÿëM‹U‹BZ‰Eüƒ}üt;‹Mü3Òf‹Q;U|"‹Eü3Éf‹‹U âÿÿ;Êu ‹Eü3Éf‹H‹Áë‹Uü‹B‰Eü뿃Èÿ‹å]ÃU‹ìƒì VÇEôÇEø¿Eƒø}hY'jè¶Wÿÿ3Àé/h ¹5sÿ0p5s¿M; ”—5s}Sƒ=4¸5stJ‹Uø;”—5s}$‹Eø‹ 4¸5s‹‹EøƒÀ‰Eø…Òt ‹MôƒÁ‰MôëÑ¿U9Uô~h ¹5sÿ,p5s3ÀéÅj¿EÁàPjjèr·ÿÿ‰Eüƒ}üuh ¹5sÿ,p5s3Àé—ÇEô‹Mô‰Møƒ=4¸5su ‹Uü‰4¸5së\‹Eø;”—5s}8‹Mø‹4¸5sƒ<Št‹Eô‹Mü‹Uø‹54¸5s‹–‰‹EôƒÀ‰Eô‹MøƒÁ‰Møë½‹4¸5sRjè•·ÿÿƒÄ‹Eü£4¸5s¿M‰ ”—5sh ¹5sÿ,p5s¸^‹å]ÃÌÌÌÌÌÌÌÌÌÌÌU‹ì¡”—5s]ÃÌÌÌÌÌÌU‹ìƒì WÇEø‹} ƒÉÿ3Àò®÷уÁÿ‹E Lÿ‰Mü‹Uü¾ƒø't ‹Müƒé‰Müëê‹Uüƒê‰Uü‹Eü¾ƒù't‹Uüƒê‰Uü‹EøƒÀ‰Eøëáƒ}ø~ ÇEôë‹Mø‰Mô‹Uô‰Uø‹EøP‹MüƒÁ‰Mü‹UüR‹EPÿë[ÇEô-‹MøÆ0‹UøÆBx‹E܃À‰EÜë<‹Mä‰MÔƒ}Ôtƒ}Ôtƒ}ÔtëÇEô0ëÇEô4ëÇEô8ëÇEô8jÿ‹UÜRj/‹EäP‹MàQ‹UôR‹EPè üþÿƒÄ‹MìQ‹UðR‹EøP‹M ‹U苊3ÉŠH$Qèwûÿÿ‹UøRèûÿÿ‹EøP‹MQè‹ÿÿƒÄ‹UðR‹EPè‹ÿÿƒÄ¸‹å] Å4s¾4sÝ4sg4sO4s[4s¦4ss4sŽ4s4s    ÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì WÇEìÇEôÇEü‹EPè;ÿÿ…Àué‹M‹Q$‰Uðjh‹EPjèw‰ÿÿ‰Eàƒ}àué™ÇEø‹M¿Q"9UìM‹Eì‹Mð‹3ÀŠB*ƒà…Àt ‹MìƒÁ‰MìëЋUì‹Eð‹ 3ÒŠQ‰Uä‹EäP‹Mì‹Uð‹ŠP‹MàQÿþÿƒÄ…Àt"‹URèáþÿƒÄƒøu‹EPèþÿƒÄƒøÿt‹MQèï[þÿƒÄ3Àënj‹URèÍ*ÿÿƒÄ‰Eôƒ}ôu‹EPèÈ[þÿƒÄ3ÀëG‹Mô‹‰Uü‹EPè°þÿƒÄ‰Eøƒ}øþtƒ}øtëã‹MQècþÿƒÄƒøtëíƒ}üu¸ë3À‹å]ÃÌÌÌÌÌÌU‹ìƒì0VW‹EPè?„ÿÿ…Àu3Àë,¹¾ 5s}Ðó¥f¥¤‹M QUÐRèèEÐP‹MQè;_^‹å]ÃÌÌÌÌÌU‹ìì€SVW‹EPèëƒÿÿ…Àu3Àëƒ}}h'‹MQèïÿÿ3Àëg¹¾85s}€ó¥‹U RE€Pè¿èœ5sU€ƒÉÿ3Àò®÷Ñ+ù‹÷‹Ù‹úƒÉÿ3Àò®ƒÇÿ‹ËÁéó¥‹Ëƒáó¤‹EPM€QèAU€R‹EPè”_^[‹å]ÃÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì‹å]ÃÌÌÌÌÌÌÌU‹ìQƒ}tƒ}t ‹E‹H‰MüëÇEüƒ}üt3Àë ‹U3Àƒz$•À‹å]ÃÌÌÌÌU‹ìQƒ}tƒ}t ‹E‹H‰MüëÇEüƒ}üt3Àë ‹U‹‚F‹å]ÃÌÌÌÌÌÌÌU‹ì]ÃÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì‹EP‹MQ‹UR艅Àu3Àër‹EPÿhp5s‰Eüƒ}üs3Àë[ÇEøë ‹MøƒÁ‰Møƒ}ø s@‹Uø‹•\—5sP‹MüQÿ¸p5s‹Uø‹M ‰‘‹Uø‹E ƒ<uƒ}ø s‹MüQÿ4p5s3Àë뱋Eü‹å]ÂÌÌÌÌÌÌÌÌÌU‹ìƒìHSVWÇEü‹E‰EЋMÆ‹U ÆhX5s‹EPÿ q5sƒÄ…Àu ÇE ¸5së.MüQUÔRÿ@p5s…ÀtEÔP‹MQÿ q5sƒÄ…ÀuÇE ¸5sUøRhjh@œ5sh€ÿp5s‰Eôƒ}ô…ØÇEÌEÈPjjj‹MÐQ‹UøRÿp5s‰Eôƒ}ôt }ôêuƒ}Èu:EÈPjjj‹ Œ—5s‰MЋUÐR‹EøPÿp5s‰Eôƒ}ôt }ôêuÇẼ}ôt }ôê…Jj‹MȃÁQjjècvÿÿ‰EÀƒ}Àu3ÀéQUÈR‹EÀPjj‹MÐQ‹UøRÿp5s‰Eôƒ}ô…ó‹E‹ ¸5s‰‹¼5s‰PŠ À5sˆHƒ}Ìt=ƒ}t‹U‰U¼ëÇE¼ ¸5s‹}¼‹U ƒÉÿ3Àò®÷Ñ+ù‹÷‹Á‹úÁéó¥‹Èƒáó¤é“‹MÀMÈÆ‹UÀ‰UÄë ‹EăÀ‰EÄ‹Mľ…Òt.‹Eľƒù,t#‹Uľƒø t‹Mľƒú t ‹Eľƒù të¿‹UÄÆh¬5s‹EÀPÿ q5sƒÄ…Àu‹M ‹¤5s‰ ¨5sˆAéh˜5s‹MÀQÿ q5sƒÄ…Àu‹U ¡5s‰f‹ ”5sf‰Jëph„5s‹UÀRÿ q5sƒÄ…Àu‹E ‹ |5s‰Š€5sˆPëDh`‘5s‹EÀPÿ q5sƒÄ…Àu ‹M ‹x5s‰ë!hl5s‹EÀPÿ q5sƒÄ…Àu ‹M ‹h5s‰‹EăÀ‰EÄ‹Mľ…Òt‹Eľƒù u ‹Uă‰UÄëà‹Eľ…Ét‹UĉU¸ë‹E‰E¸‹}¸‹U ƒÉÿ3Àò®÷Ñ+ù‹÷‹Ù‹úƒÉÿ3Àò®ƒÇÿ‹ËÁéó¥‹Ëƒáó¤‹EÀPjèÞtÿÿƒÄ‹MøQÿ p5sƒ}ôt‹UR‹E P‹MQèƒÄ ¸_^[‹å] ÌÌÌÌÌÌÌÌÌU‹ìQSVW‹E‹ ¸5s‰‹¼5s‰PŠ À5sˆH¿8œ5s‹UƒÉÿ3Àò®÷Ñ+ù‹÷‹Ù‹úƒÉÿ3Àò®ƒÇÿ‹ËÁéó¥‹Ëƒáó¤ƒ}t‹E‰EüëÇEü ¸5s‹}ü‹U ƒÉÿ3Àò®÷Ñ+ù‹÷‹Á‹úÁéó¥‹Èƒáó¤_^[‹å]ÃÌÌÌÌÌÌÌÌÌÌÌÌV‹t$WVè$V…Àu_ƒÈÿ^ˆV‹xÇ@…ÿu_3À^ÃVèû¦þÿ…Àt@ƒÿÿt>VèÌ2þÿƒÄ…Àt.VèùýÿƒÄƒøt…ÀtVè}ùýÿƒÄƒøuî…Àt VèÛf…Àu ƒÏÿjVèìU‹Ç_^ÃS‹\$UVWSè’U…À„ ‹t$0‹»VƒþŒë3Àf‹G$;ðÝ‹G& vŽ‹T$ …ÒH̉L$0u&ö@Íu ‹i …ít‹i…íuhE'Sèÿÿ_^]3À[Ë\$,…ÛuŠX΃û'u»/ë ƒû%u»-‹L$$‹l$(‹D$Q‹L$UPRSQèlf…À„c…íŒ[€?u‹T$hI'Rè¨ÿÿ_^]3À[Àt‹D$hH'PèŒÿÿ_^]3À[ËT$03ÉŠJQSèµ­þÿƒÄ…Àu‹D$h 'Pè_ÿÿ_^]3À[ËG…Àu)3Àjf‹G$ €H‹D$ÁâRPjèsqÿÿ…À‰G„Ç‹D$…Àu‹L$0ŠA<#t<"…¬‹D$…ÀŒ ‹D$ …À}‹T$VSRèíg‰D$ ‹W¶…í F‹D$ tŠÔ‹L$f‹T$‰F‹D$0ˆ‰Nf‰Vf‰n‰F&‰p~;‹F…ÀtP‹D$PèqÿÿƒÄ‹L$jUQjèÍpÿÿ…À‰Ft%‹T$$URPÿq5sƒÄ _^]¸[Ãh'Sèaÿÿ_^]3À[ÃSUVW‹|$WèbS…À„ƒ‹t$0‹¯V…öŒf3Àf‹E$;ðX€}u…öuhT'Wèÿÿ_^]3À[Ãf‹Ef…ÀuhL'Wèêÿÿ_^]3À[ËL$ƒùŒ%ÿÿ;ÈŠD$„Àu…öt‹E& vŽŠLΈL$‹E&v3É<–‹T$ÁçâÿŠLÏQRèY¥þÿ‹\$4‹L$(‹T$,ƒÄˆD$‹D$(P‹D$ SQ‹L$ RPQèÿc…À„ …ötS€}u‹U&‹L$3ÀáÿŠDÎPë‹T$‹E&âÿ3ÉŠLÎRQè]«þÿƒÄ…Àu‹T$h 'Rèÿÿ_^]3À[Ã…Û} ƒûÿ…<‹D$ …À}‹E&‹T$ŠLÎQRèyeƒÄ‰D$ ‹D$$…À}.ŠD$„Àt ‹D$%ÿë ‹E&3ÉŠL΋Á‹T$VPRè e‰D$$‹D$…Û €H‹EŠL$tÔ‹D$$f‹T$ ˆ‰Ff‰Vf‰^~8‹D$jSPjèžnÿÿ…À‰Fu‹L$PQè¬Q_^][ËT$(SPRè»oÿÿ‹D$$ëfÇF€}u3…À~/~òÿw&‹\$jPSjèMnÿÿ…À‰F u PSè_Q_^][ÃÆF*‹D$0…ÀuÇF&_^]¸[ËE&L̸‰N&‹U&‰tà_^][Ãh'Wè· ÿÿ_^]3À[ÃVW‹|$ WèÄP…Àtk‹L$‹—Vƒù|Q3Àf‹B$;ÈG‹D$…À}ƒøÿuE‹R…Òt>4‰…À4qt²Ô}QŠQWè[d…Àu f9Fuf9Ft‰F_¸^Ãh'Wè5 ÿÿ_3À^ÃV‹t$VèEP…ÀtS‹D$‹ŽVƒø|93Òf‹Q$;Â/‹T$ …ÒuhU'Vèõ ÿÿ3À^ËI…Ét4€p^‰Tâ¸Ãh'VèÎ ÿÿ3À^ÃS‹\$VWSèÓO…Àu_^[Ë»V€?thK'Sè• ÿÿ_^3À[Ët$ƒþ}hM'Sè{ ÿÿ_^3À[Ãfƒt_^3À[öj FÁáQSjè”lÿÿ…À‰Gu PSè¦O_^[Ãf‰w_^¸[ÃV‹t$VèEO…À„’‹D$ ‹ŽVPÿƒúwu¸ÿ$• <4s€Ž…^ËT$;Ð|úÿÿf‰Q^ÃfÇAÿÿ^ËT$;Ð}‰A2^ÉQ2^ËT$;Ð} ÇA6ÿÿÿ^ÉQ6^ËT$…Ò}‰A ^ÉQ ^ÉD^Ãh@'Vè‹ ÿÿ3À^ÃIš;4s¸;4sÊ;4sà;4sò;4s‘;4sV‹t$VèuN…ÀuƒÈÿ^ËFSUW‹¾V‹h€u3‹_VÇGèGŸþÿ…ÀtVè+þÿƒÄ…Àt VèàñýÿƒÄ…ÀuƒËÿë3ÛVèÌñýÿƒÄƒøt7…Àt3VèêüýÿƒÄƒøþtVèÜüýÿƒÄƒøþuò…ÀtVèšñýÿƒÄƒøuÎëƒËÿ‹OQVè³5…Àu€uhD'Vèž ÿÿƒËÿ‹W RVè‘5…Àu hQ'Vè‚ ÿÿjVèÚM€>@r ÆE‹F‹HÆ_‹Ã][^ÃSUVW‹|$WèrM…Àu_^][Ë·V‹D$f§„ÿþ3퉆T‹F;ÅuhN'Wè ÿÿ_^]3À[ËH,»;Ít 9ht;Íu9(u8^uhS'Wèì ÿÿ_^‹Ã][Ã9nuWè `…Àu_^][Ã8^ueSh Wjèþiÿÿ‰†ÄƒÈÿ‰®Ð‰®È‰†ØW‰®Ô‰®Ì‰†Ü‰®Àèŋ؋†Ä;ÅtPWèbjÿÿƒÄ‰®ÄëWèñ‹Ø‹D$;Åt 9¯Vt‹N‰;Ýu#9¯Vt‹VRWè44‹F PWè*4_^]3À[ÃWè½ýÿÿƒÄƒøÿu_^]3À[Ãf‹‡„_%^÷ØÀ]÷Ø@[ÃìdSU‹l$pVUèÀnÿÿ…Àu^][ƒÄdËE‹H‹…V…À‰L$ t ^]3À[ƒÄdËD$xT$RPUè¨M…Àu^][ƒÄdËŒ$„ƒùtƒùthW'Uèÿÿ^]3À[ƒÄdËD$|…Àt0€8t+ƒùuQëjPUèš1‹Ø…Ûu$hO'UèIÿÿ^]3À[ƒÄdÃùt ^]3À[ƒÄdÃ3Û‹„$€…Àt3€8t.jPUèW1‹ð…ö‰t$tu'SUè3hP'Uèûÿÿ^]3À[ƒÄdÃÇD$t‹t$tjhXUjèhÿÿ…ÀuSUèÌ2VUèÅ2^]3À[ƒÄdÊ”$„‰…V…Û”ÁWˆ‰p xD¹t$ˆPfÇ@ ‰XÇ@2Ç@6ÿÿÿUó¥3ɤ‰ˆÄ‰ˆD‰ˆTèQQ…À_uSUèU2‹D$tPUèJ2^]3À[ƒÄdËŒ$„¸;Èu€}@r‹L$ Æ‹U‹JÆ^][ƒÄdÃSU‹l$ VWUè"J…Àtl‹\$‹½V…Û|^‹D$…ÀtV€uPf‹G:f…ÀtGf9G €H‹G@4P‹DP…ÀuN j QUè­™þÿ…Àt‹V‹FÓ;ÐvhR'Uè’ÿÿ_^]3À[Ã…Ût‹D$SPUè{™þÿ…Àtå‹V‹NӋ‰V;ÁrfÿG>f‹G>f;G&u‹F&€x&u3ÉŠH‹;Áv ‹V&3ÀŠB‰‹‹D$‰N3Òf‹S$ƒÆ,@;‰D$‚îþÿÿ‹|$]ÿ\p5s÷ØÀ÷ØPWè"_^[ƒÄÃ_^3À[ƒÄËL$…Éuh'Qèÿÿ3ÀÊT$¸:ÐuƂÈ‚ÃìS‹\$ UVWSÇD$è7jÿÿ…À„‹ƒV…À„ó‹|$0…ÿ„ç€?„ÞjjQSjè`dÿÿ‹ð…ö„ÈjWSèM-‹è…í‰l$,uhO'SèøÿÿVSèádÿÿƒÄ3À_^][ƒÄÃVjUSèÚ3ƒø…g€~.…]¾ƒÀЃøu ¾Nƒé0ƒùt%¾D‘5s;Â…7¾F¾ E‘5sƒè0;Á…!jUè£C…À„ëVUè¤D…À„ÜVÿàp5s‹øWS‰|$0è˜öÿÿƒÄ …ÀuUSèJ.VSè3dÿÿƒÄ3À_^][ƒÄÃ…ÿ†ÇD$jUè>C…À„VVUè?D…À„G‹=àp5sVÿ׋L$ ƒÄ;Á…/jUèC…À„ VUè(E…À„ûVè:]„ÀˆD$„éjUèÖB…À„ÄVUè×C…À„µ€>0uŠF„Àu3ÿ‰|$0ëVÿ׃ĉD$0…À„Þ3ÿWUèB…À„mVUè‘C…À„^€>0u ŠF„Àu‰|$ë?Vÿäp5sƒÄ;ljD$„¨‹T$âÿBÞƒøMw3ÉŠˆTH4sÿ$LH4sÇD$ÿÿÿÿWUè!B…À„~VjUSèï1…À„á€>"…ØVjUS‹þèÒ1ƒøu-ŠG<"uGþ;Ær€þ\u;Æv€ý\tWjUSè¥1ƒøtÓ€ÿ"…)VVÆGÿèë_…À„¤‹þƒÉÿ3Àò®÷ÑIPU‰L$(|èˆA…À„KWUè‰B…À„<€?0u ŠG„Àu3íëWÿàp5s‹èƒÄ…í„Ò‹T$,jRèAA…À„ë‹D$,WPè^C…À„Ø‹D$0…Àu ŠD$<'uÆD$/ë <%u ÆD$-ÇD$0‹L$ ‹T$‹D$0‹|$UQ‹L$VRPQWSèmðÿÿƒÄ …Àtw‹D$$‹l$,G‰|$O;ø‚zýÿÿéîÇD$h'éÖ‰|$h'éȉ|$hw'éºÇD$hS'é¨h'SÇD$èHÿÿ‹l$,é’‹l$,ÇD$éhw'SÇD$èÿÿ‹l$,ëhÇD$hw'ëS‰|$hS'ëHhw'Sèðÿþÿ‰|$ë=hw'SèßÿþÿÇD$ë(hu'SèÊÿþÿÇD$ëÇD$hv'Sè­ÿþÿUSè¦*VSè`ÿÿ‹D$ƒÄ_^][ƒÄÃUSè‰*VSèr`ÿÿƒÄhv'Sètÿþÿ_^]3À[ƒÄÃUSèc*VSèL`ÿÿƒÄhu'SèNÿþÿ_^]3À[ƒÄÈE4s€E4sƒìSU‹l$VWUÇD$è§dÿÿ…À„í‹…V…À„ß‹|$(…ÿ„Ó€?„ÊjjaUjèÐ^ÿÿ‹ð…ö„´jWUè½'…À‰D$(uhO'UèjþþÿVUèS_ÿÿƒÄ3À_^][ƒÄÊ D‘5sÆF.€Á0ˆŠE‘5s€Â0ÆF ˆVÆF ‹V‰L$‹Q…Ò‰T$„73Ûf‹Y…Û‰\$„%Fj PSÿ$q5s‹þƒÉÿ3ÀƒÄ ò®÷Ñ‹|$(IVÆ1 ÆD1 ƒÁQWUèƒ0ƒøthD'UèÃýþÿWéÛ3À…Ûޝ‹L$Y@j VP‰D$ ÿ$q5s‹þƒÉÿ3ÀƒÄ ò®÷ÑI¸ ‹Ñ¹+Ê<2‹ÑÁéó«‹ÊƒáóªFPŠCþPèRZ…À„5‹þƒÉÿ3Àò®÷ÑI‹Ñƒú}¹<2+ʸ ‹ÑÁéó«‹Êƒáóª3ÉFf‹Kj PQÿ$q5s‹þƒÉÿ3ÀƒÄ ò®÷ÑI‹Ñƒú}¹<2+ʸ ‹ÑÁéó«‹Êƒáóª‹ Fj PQÿ0q5s‹þƒÉÿ3ÀƒÄ ò®÷ÑI‹Ñƒú&}¹&<2+ʸ ‹ÑÁéó«‹ÊƒáóªÆF&"‹S¿CN'PQRèì\‹þƒÉÿ3Àò®÷ÑI‹ÑÆ2"Bƒú0}¹0<2+ʸ ‹ÑÁéó«‹Êƒáóª‹k$j …íuuF0Pjÿ$q5s‹þƒÉÿ3ÀƒÄ ò®÷ÑI‹ùÿ\p5s…Àu‹L$$jWVQ艃ăÿ8}¹8¸ +Ïþ‹ÑÁéó«‹Êƒá󪋠º5sƒÉÿ‹ú3Àò®÷ÑIF8‹ùWPRës‹T$N0Q‹Í‹z&¸OìÄN+Ï÷éÁú‹ÂÁèLQÿ$q5s‹þƒÉÿ3ÀƒÄ ò®÷ÑI‹Ñƒú8}¹8<2+ʸ ‹ÑÁéó«‹Êƒáóª‹mƒÉÿ‹ý3Àò®÷ÑIF8‹ùWPUèá\ÿÿ‹L$(ƒÇ8VÆ7 ÆD> ƒÇW‹|$,QWèñ-ƒøu!‹D$‹L$ƒÃ,;Á‹ïŒ{ýÿÿë!ÇD$ëhD'Wèûþÿ‹l$$ÇD$‹T$(RUèù%VUèâ[ÿÿ‹D$ƒÄ_^][ƒÄÃPUèÜ%VUèÅ[ÿÿƒÄ_^]3À[ƒÄËD$ö€…uÿ\p5s…Àu ‹D$PPÿ|q5sÃìU‹¬$ VW‹…Vö……‰D$ t €x„˜‹¼$ÿÿ~GjPUjè†Zÿÿ‹ð…ötuët$S‹œ$WSVÿö……t‹L$€yu WVUèwVÿÿ늄$$V<Vuÿxq5sëÿ|q5sWVSÿ‹L>&÷‰L$,3É‹~f9N‰D$‰|$(‰L$ t&3À‰L$f‹FT$RPUSè¦&ƒø…ä‹D$ë3É;ÈÀ÷Ð#ljD$‹L$<…É„û‹N&…É„ð…ÀuT$RVUSèá!ƒÄƒø…œ‹D$‹V …Ò„Ä…À„¼ŠN*„Ét;øs3ë;øs„ÉtRSèWÿÿ‹D$ƒÄ;ÇvjPëjWSjèGVÿÿ‰F ‹D$‹N QPUSèô%‹L$…Ét ƒø…*‹D$‰N‹T$…À‰V†‹M,…Ét‹} ø‰} ‹U$ƒÒ‰U$éò‹‹V3Ò‹¹Èø‹ÌÂPWUSè)…À„çéÄ‹E,…Àt‹E ‹M$ë‹‹V‹È‹‰Ì‰F‹D$‰N"‹T$‹~‰VÇF‹T$‹Ù3É×ËиÈ‹D$H;H‡pr;‡f‹E,…À‹D$™‹ÈtϸÓ‹\$ËЉM ‰U$‹U U$ë&‹D$ÏÓȸÐR‹T$‹@&‰„$€¸8ž‰|$d‰|$8‰|$P‰|$`‰T$H‰\$x‰l$0u €¹Ÿ‰D$ts‰|$t3É3À‰L$h¼$˜‰L$lˆL$p¹@ó«Œ$—D$p‰L$(L ‹ñ‰D$ 3À‹ýÁéó«‹Îƒáóª‹D$x;Ðr 3À‰D$$‰D$Të‰D$T‹D$0L‰L$$‹D$,‹t$03íf9h$‰l$@†žÇD$Lÿq5sLmÇ‹„$€TŠLŠ\<ˆ\$‰|$D‹WŠ_‹GˆL$|…Òˆ\$t!‹L$|°áÿÒà‹L$Š ЈD$ˆéº‹L$2ÀˆD$é©‹|$‹Í‹Ñ3ÀÁéó«‹ÊƒáóªéŽ‹D$ƒÆUVPÿq5sƒÄ év‹L$UVQÿq5sƒÄ éa‹D$%ÿƒÀÛƒøJ‡R3ÉŠˆÌb4sÿ$°b4s3À³/;Ј\$tUfƒzuN‹R€:uF;è~€<0t@;Å|õë5;Å}1‹è@‰D$ë(u ‰D$é ‹þƒÉÿ3ÀÇD$Pò®÷ÑI‹éE‰D$…íŽûŠD.ÿÇD$P< …ûŠL5ÿEÿ€ù u…À~ ŠL0ÿH€ù tòhéÙ³-ˆ\$麋D$<%ÿHtHt ³8ˆ\$é ³4ˆ\$镳0ˆ\$銊D$<³><ˆ\$u|³;ˆ\$ëtŠD$<³<<ˆ\$uf³zˆ\$ë^ŠD$4³=€ûlt9‹L$‹D$‹T$‹œ$œQ‹L$H%ÿRP‹D$@U%ÿVPSÿQ"ƒÄ‹è鈋D$D‹œ$œŠP ŠH!ˆ”$„‹T$ˆŒ$…Œ$„R‹T$8Q‹L$áÿâÿQUVRSÿP"ƒÄƒøÿ„v‹„$„Pèʹýÿ‹T$%ÿ‹èŒ$ŠUQRÿq5sƒÄ닜$œƒ|$Pu8‹T$E;Ð~#‹t$J‹Ê¸ +Í<.‹ñ‰T$Áéó«‹Îƒáóª‹êÇD$P€|$2u=‹t$‹L$|ŠD$áÿŠÒâ ˆD$ˆë‹|$‹Í‹Ñ3ÀÁ鋜$œó«‹Êƒáóª…íŒÔŠD$_^][Ĉ‹L$@QhÉØÿÿSè!_^][Ĉ‹T$@RhÉØÿÿSè_^][Ĉ‹|$(Š„À„‹L$d…ÉtgŠÈGþɉ|$(ˆtŠŠ_:ÃuGþɈuð‰|$(‹D$8…ÀtÿD$ ‹D$ xŠ‹Ø¾7ãÿ;ó~"t$p;þs‹\$ ¾wCG‰\$ ‹Ùãÿ;óÞ„À„ŠL$$Š\$0‹|$(*ËþÀˆ‹L$ ˆD$q;Ès,‹t$ ‹D$$L$q‹ø+ΉL$H‹ÙÁéó¥‹Ëƒáó¤‹|$(‹ËÁë‹D$$Œ$˜;ùs#Œ$˜‹÷+Ï‹ø‰L$H‹ÙÁéó¥‹Ëƒáó¤‹ËÁ‹L$0‹¼$œ‹t$,+Á‰D$\f‰‹T$\ë‹t$,‹¼$œ‰T$\fúª‡s‹D$xâÿÿ;ЇaT$\jRWè¬yþÿ…Àu _^][Ĉ‹D$\‹L$0%ÿÿPQWè†yþÿ…Àu_^]3À[Ĉ‹V‹NB3ÛAf9^<‰V‰N†Ý‰\$8닼$œ‹V@‹D$8‹D…À„½€>t ‹H …É„­‹Œ$ QSW誅Àt”€>uw3Òf‹V<;Úrm‹F‹H,…Ét‹p ‹x$닌$œ‹‘V‹²È‹ºÌ‹”$œL$QjPRèÇ‹è‹D$,‹@‹H,…Ét‰p ‰x$닌$œWVPQè/ƒýdt0‹t$,‹L$83ÒCf‹V<ƒÁ;Ú‰L$8‚)ÿÿÿ_^]¸[ĈÂ_^]¸d[ĈÂUh†ØÿÿWè<_^][ĈÂIïY4s¸Y4s Z4s"Z4súZ4s[4s[Z4s5[4sK[4sa[4sž[4sƒì$‹D$,SUV‹t$4€W3ÿ‹–VX¹‰|$‹Z@‰L$‰T$$‰|$,C‰l$‹]9{u)‹E‹@ ;Çv‰C‹E‰L$‹H ‰M‹p‹x ‰t$<éá‹C ;Ç…Ž‹J‰L$(‹A,;Çt ‹Q ‰T$,‹Q$닺ȋ’̉|$,…À‰T$0t‹C‰A ‹S"‰Q$ë!‹S"‹CRPQVè9…Àu _^][ƒÄ$ ‹t$8‹{ÿv¿jWVjè¼Cÿÿ…À‰D$f‹B>f;Bf‹H>f;H‹M$‹Ç%ÿÿÁà‹TüŠJ$€ù#t€ù"t‹MD‹Tü‹ 霋MD‹Tü‹B‹H銋M$‹Ç%ÿÿÁà‹TüŠJ$€ù#t€ù"t‹MD‹Tü‹Lë]‹MD‹Tü‹B‹@LëJ‰T$醋M$‹Ç%ÿÿÁà‹TüŠJ$€ù#t€ù"t ‹MD‹Tü‹ ë ‹MD‹Tü‹B‹H…ɉL$~‹K0‰L$f‹T$$f9T$t5ùÿ~%jQUjèL>ÿÿ…À‰D$ÇD$0„m‹L$ëD$t‰D$ŠC&f3ÒŠÐf9T$…™ŠC<'t<%t…Éu:‹M$‹Ç%ÿÿÁà‹TüŠJ$€ù#t€ù"t ‹MD‹Tü‹ ë ‹MD‹Tü‹B‹H‰L$‹UDçÿÿÁç‹D:ü‹@…Àt)‹U$‹T:üŠR$€ú#t€ú"t ‰D$龋@‰D$鲋T$‹B ‰D$颅ÉŽ”‹UDçÿÿÁç‹T:ü‰T$<‹R…Òt‹]$‹\;üŠ[$€û#t €û"t‰T$ ë‹Zë‹\$‹[ ‰\$ ‹]$‹|;üŠ_$€û#t €û"t‹T$<‹ë‹RQ‹L$Q‹L$áÿÿ%ÿQR‹T$0RP‹D$LUÿP"‹ÈƒÄ‰L$…ÉŒ0‹D$$f=/tf='t f=#…»…É޳‹T$,‹ºP…ÿt‹D$jQPUèÎáÿÿ‹L$ ‹D$4ƒÄ%ÿÿƒÀƃø@w3ÒŠŒp4sÿ$•€p4s‹|$T$@…É~$3Û‰L$ Џ¹5sоÈ;ËtˆB‹D$ GH‰D$ uè|$@ƒÉÿ3ÀÆò®‹D$T$@÷ÑIQRP‰L$ÿ‹ûƒÉÿ3À‹Öò®‹E(÷ÑIÂQSPÿq5s‹ûƒÉÿ3ÀƒÄ ò®‹U÷ÑIщU‹EƒÐ‰EëI‹ûƒÉÿ3À‹´$€ò®÷ÑISQUVèÍûÿÿë#‹ûƒÉÿ3ÀSò®÷ÑIQ‹Œ$ˆUQè¯ûÿÿ‹´$€…À„ÿq5sÇ‹´$€‹D$3ɉL$@€x…If9H$‰L$ †;‹T$ÇD$ÿÿÿÿÆ„$ˆ‹J…Ét#‹D$ %ÿÿ4€pf¶4f‰t$D‹@‰D$‹D$ ‹R&%ÿÿ‰\$$‰D$4@4°Áæ‰t$4ŠD<"t<#…=‹l$D­lEÁå‹D) …À…·‹T$‹B‰D$8‹P,…Ò„Ù‹P ‹¼$€‰T$P‹P$‰T$Téà‹„$„…À„ÿÿÿ‹4ž5sƒÉÿ¿€»5s3À‰ò®÷Ñ+ù‹÷‹ÑƒÉÿ‹ûò®‹ÊOÁéó¥‹Êƒáó¤ƒÉÿ¿l›5sò®÷Ñ+ù‹Ñ‹÷ƒÉÿ‹ûò®‹ÊOÁéó¥‹Êƒáó¤|$XƒÉÿò®÷Ñ+ù‹÷‹Ñ‹ûƒÉÿò®‹ÊOÁéó¥‹Êƒáó¤¿èœ5sƒÉÿò®÷Ñ+ù‹÷‹Ñ‹ûƒÉÿò®‹ÊOÁéó¥‹Êƒáó¤¿`º5sƒÉÿò®÷Ñ+ù‹÷‹Ñ‹ûƒÉÿò®‹ÊOÁéó¥‹Êj ƒáó¤¿l›5sƒÉÿò®÷Ñ+ù‹÷‹Ñ‹ûƒÉÿò®‹ÊOÁéó¥‹ÊD$\ƒáP󤋌$AQÿ0q5s|$dƒÉÿ3ÀƒÄ ò®÷Ñ+ù‹÷‹Ñ‹ûƒÉÿò®‹ÊOÁéó¥‹Êƒáó¤¿0ž5sƒÉÿò®÷Ñ+ù‹÷‹Ñ‹ûƒÉÿò®‹ÊOÁé󥋄$„‹Êƒá…Àó¤}÷ØPè\¾þÿ‹øƒÉÿ3ÀSò®÷Ñ+ù‹÷‹Ñ‹ûƒÉÿò®‹ÊOÁéó¥‹Êƒáó¤¿(ž5sƒÉÿò®÷Ñ+ù‹÷‹Ñ‹ûƒÉÿò®‹ÊOÁé󥋄$„‹ÊƒáPó¤è_Ëÿÿ‹E,ƒÄ…À„…‹ûƒÉÿ3À‹uò®‹E3Ò÷ÑIÎЉT$LuIùwA‹ûƒÉÿ3À‹Öò®‹E(÷ÑIÂQSPÿq5s‹ûƒÉÿ3ÀƒÄ ò®‹U÷ÑIщU‹EƒÐ‰EéÆüÿÿ‹ûƒÉÿ3À‹´$€ò®÷ÑISQUVè>øÿÿë#‹ûƒÉÿ3ÀSò®÷ÑIQ‹Œ$ˆUQè øÿÿ‹´$€…À…„üÿÿSVèJ&ÿÿƒÄhQ'Vè¬_^][ƒÄl ‹¼$€‹—V‹²È‰t$P‹’̉T$T‹P,…Òt‹T)‰P ‹L)"‰H$ë‹T)"‹L)RQPWè‰øÿÿ…À„‹T$‹B (‹D(=v¾ë¿T$,t;Æv‹ð‹I jVWj‰t$$‰L$Xèð$ÿÿ‹L$Æ„$ˆ‹Q‰D* ‹A‹T$8‹L( QVRWè‰ôÿÿƒø„Ý‹D$‹T$4‹H&€| "u+‹D$V‹H¿D$0‹T) Rj"Ph8ž5sj/Wèì[þÿƒÄ‰D$ë?‹L$¿8ž5s3À‹QƒÉÿò®÷Ñ+ù‹Á‹÷‹|* Áéó¥‹Èƒáó¤¿L$,‰L$‹¼$€‹t$¿L$D‹Áƒè"„>H„­‹T$‹B…À„‹‹T$,’j‹D …À„uhSj/VPQWÇD$LèO[þÿƒÄ‰D$éP‹T$‹B‹l(ýv ¾‰t$ë‹õ‰t$évÿÿÿ‹t)…öt‹l)…ít;îs‹¼$€‹õ‰t$éPÿÿÿ‹t)‹¼$€‰t$é<ÿÿÿFjPWjèr#ÿÿ‹ø…ÿ‰|$0u;‹ž5s‹Ë‰¡ž5s‰A‹ž5s‰Q¡ ž5s‰A f‹$ž5sf‰Q &ž5sˆAéš‹L$‹A…À„‹‹L$‰ Q‹Dˆ …ÀtyVPWÿq5sƒÄ ‰t$‰|$$ëcD6jPWjèç"ÿÿ‹è…í‰l$0u¹¾ž5s‹ûó¥ë:‹T$‹B…Àt/‹L$‰ Q‹Lˆ …ÉtD6PUj/VQj"WèþYþÿƒÄ‰D$‰l$$‹D$…À}&¿8ž5sƒÉÿ3À‹ëò®÷Ñ+ù‹Ñ‹÷‹ûÁéó¥‹Êƒáó¤ë‹D$‹L$$‹éÆ‹T$f‹D$ f;B$s*¿Àœ5sƒÉÿ3Àò®÷Ñ+ù‹÷‹Ñ‹ýƒÉÿò®‹ÊOÁéó¥‹Êƒáó¤‹t$<‹F,…Àtj‹ýƒÉÿ3À‹Vò®‹~÷ÑIωD$(uNùwF‹ýƒÉÿ3Àò®‹~÷ÑIQ‹N(ÏUQÿq5s‹ýƒÉÿ3ÀƒÄ ò®‹V‹¬$€÷ÑIщV‹FƒÐ‰Fë)‹ýƒÉÿ3ÀUò®‹¬$„÷ÑIQVUèýóÿÿƒøtÇD$@‹D$0…Àt PUè!"ÿÿƒÄ‹|$‹D$4‹W&ŠD<"t<#uyŠ„$ˆ‹t$„Àt‹G ¶N‹L QUèä!ÿÿƒÄ‹O¶V‹T$HÁà‰T ‹O‹T …Òu4‹D$8‹H,…Ét‹L$P‹T$T‰H ‰P$ë‹T$T‹L$PRQPUè6ôÿÿ…À„­‹D$ @f;G$‰D$ ‚Ð÷ÿÿ‹l$<‹´$€SVèi!ÿÿ‹E,ƒÄ…ÀtF‹E‹UƒÀƒÒ‰T$Tu4=w-‹E(‹]jÃhÄœ5sPÿq5s‹MƒÄ ƒÁ‰M‹EƒÐ‰EëhÄœ5sjUVèËòÿÿƒøufƒ|$@t hQ'VèÀþÿ‹„$„…À~PVèñ¿þÿ_^]3À[ƒÄl SUVD$W‹|$P3íjWU3ÛèÆïÿÿƒøuT‹5Dq5sŠL$C€ù tM‹@q5sƒ:~¾ÁjPÿÖŠL$ƒÄë¡Hq5s¾Ñ‹ŠPƒà…Àt#L$QjWjèrïÿÿƒøt²_^]3À[½C‹@q5sƒ:~¾ÁjPÿÖŠL$ƒÄë¡Hq5s¾Ñ‹ŠPƒà…Àt€ù u¼ƒû~·‹T$âÿ3Õu©€ù t3‹G,…Àt‹W ƒÈÿЉW ‹O$ȸ‰O$_^][ÂjjjÿWÿp5s_^]¸[‹D$SUVpÿW‹|$h^SjWjè°îÿÿƒøu!ŠFFC<0|!<9;õsSjWjèîÿÿƒøtß_^]3À[€>-uxFVjWjèpîÿÿƒøt _^]3À[€>1t _^]3À[ÂFVjWjèHîÿÿƒøt _^]3À[¡@q5sƒ8~¾jQÿDq5sƒÄë¡Hq5s¾‹ŠQƒà…Àu_^][‹G,…Àt"‹W ƒÈÿЉW ‹O$ȸ‰O$Æ_^][ÂjjjÿWÿp5sÆ_^]¸[ÂSU‹l$‹\$ VWuÿ~WjSjè“íÿÿƒøuJ¡@q5sFGƒ8~3ÉjŠQÿDq5sƒÄë¡Hq5s3ÒŠ‹ŠQƒà…Àu E;ðsWjSjèIíÿÿƒøt¶_^]3À[Â;îu _^]3À[‹C,…Àt"‹S ƒÈÿÐ_‰S ‹K$ȸ‰K$Æ^][ÂjjjÿSÿp5sÆ_^]¸[ÂV‹t$Vèµ"ÿÿ…Àu^‹†V…ÀuhG'V踼þÿ3À^¸^ÂU‹l$V‹µV…ö„m‹FS…ÀW„˜€>uY3Ûf9^v~3ÿ‹F‹D …Àt PUèNÿÿƒÄ‹N‹D…Àt PUè9ÿÿƒÄ‹V‹D…Àt PUè$ÿÿƒÄ3ÀCf‹FƒÇ,;Ør³ë-3Ûf9^$v%3ÿ‹N‹D…Àt PUèõÿÿƒÄ3ÒCf‹V$ƒÇ,;ÚrÝ‹FPUèÚÿÿƒÄ‹F&…ÀtO3Ûf9^$v:3ÿ‹N&‹D9…Àt PUè´ÿÿƒÄ‹V&‹D:…Àt PUèŸÿÿƒÄ3ÀCf‹F$ƒÇ4;ØrÈ‹N&QUè„ÿÿƒÄ‹F._…À[t PUèqÿÿƒÄ‹F@…Àt PUè`ÿÿƒÄ‹F…Àt PUèOÿÿƒÄ‹†T…Àt‹V‰‹FPUèCæÿÿ‹N QUè9æÿÿ‹•VRUèÿÿƒÄÇ…V‹D$…ÀvPUè»þÿ^3À]ÂQ‹T$ SUV…ÒWu‹D$hU'PèDþÿÿ_^][YÂ Š ‹Â„Ét €ù.tŠH@„Éuó€8.t ‹ò3í‰t$ë ‹è+ê@‰D$‹ðŠ„Ét €ù.tŠH@„Éuó€8.t‹Ý3í‰t$‰T$ë‹Ø+Þ@ƒý‰D$spƒûsk‹|$ƒÉÿ3Àò®÷ÑIƒùsX‹t$ ‹=ò®÷Ñ+ù‹Á‹÷‹úÁéó¥‹È¸ƒáó¤_^][Y ‹L$h'QèZýÿÿ_^][Y ƒì‹D$ SV3ö‹˜V‰t$ ‰\$f9s†}UWº‹Æ%ÿÿ €H‹K ‹A&…À„Gf¶p3íÇ@0f¶9fƒþ'u¾/ë fƒþ%u¾-‹êƒytƒyt‰P(‹I‰H0éÙfƒþ#u fƒÿ/t f;þ…½¿#Ç@(é¼fƒÿ-„žfƒÿ"„”fƒÿ/t fƒÿ'…ˆ‹ÎáÿÿƒÁÞƒùXwx3ÛŠ™h4sÿ$H4s‰P(Ç@0(ëd‰P(Ç@0 ëX‰P(Ç@0ëL‰P(Ç@0 ë@‰P(Ç@0ë4‹L$…Étö…t Ç@0‰P(ëÇ@0‰P(ë ‹þëÇ@(‹\$f;þuf;êt‹H0…ÉuÇ@(f‰p,‹t$f‰x.Ff;s‰t$‚Œþÿÿ_]^[ƒÄÂ4s£Ž4sÇŽ4sÓŽ4s»Ž4s¯Ž4s—Ž4s4s‹D$ SUV…ÀWt4‹D$jjPè&ðýÿƒÄ …Àt‹\$f‹ À›5s½“à‰l$f‰ ë‹\$3í‰l$“àÆŠCc{c„À„ëƒÉÿ3Àò®÷Ñ+ù‹÷‹é‹úƒÉÿò®‹ÍOÁéó¥‹D$‹Íƒá…Àó¤t*¿À›5sƒÉÿ3Àò®÷Ñ+ù‹÷‹é‹úƒÉÿò®‹ÍOÁéó¥‹Íƒáó¤¿X5sƒÉÿ3Àò®÷Ñ+ù‹÷‹é‹úƒÉÿò®‹ÍOÁéó¥‹Í‹l$ƒá…íó¤t,¿À›5sƒÉÿò®÷Ñ+ù‹÷‹é‹úƒÉÿò®‹ÍOÁéó¥‹Í‹l$ƒá󤻂ƒÉÿ3Àò®÷Ñ+ù‹÷‹Ù‹úƒÉÿò®‹ËOÁéó¥‹Ëƒá…íó¤t^¿À›5s뻂ƒÉÿ3Àò®÷Ñ+ù‹÷‹Ù‹úƒÉÿò®‹ËOÁéó¥‹Ëƒá…íó¤t(¿À›5sƒÉÿò®÷Ñ+ù‹÷‹Ù‹úƒÉÿò®‹ËOÁéó¥‹Ëƒáó¤_^][Ãì€SU‹¬$ŒVWU‹V‰\$è_`ÿÿ‹øƒÉÿ3ÀƒÄò®÷Ñ+ù“¡‹Á‹÷‹úÁéó¥‹ÈCDƒáó¤€8tPUèètÿÿƒÄ…À„ÄjSUèäýÿÿŠCƒÄ <u‹àQhLž5sUè˜ƒÄ …À„”³àVhœž5sUè{ƒÄ …À„wj"j#VhÜž5sUè`ƒÄ…À„\UèïÔýÿƒÄƒøthX'UèŒøÿÿ_^][Ā€{…ŒUèß›ýÿƒÄƒøthX'Uè\øÿÿ_^][Ä€ÂUèé¦ýÿƒÄƒøÿthX'Uè6øÿÿ_^][Ä€ÂS*jRjUè«ÀþÿƒÄPè2ÿÿC,jPjUè”ÀþÿƒÄPèÿÿU蕦ýÿƒÄƒøþ… UèS›ýÿƒÄƒø…ŽUèq¦ýÿƒÄƒøÿ…|{$jWjUèGÀþÿƒÄPèÎÿÿfƒ?„[Uè>¦ýÿƒÄƒøþ…IUèüšýÿƒÄƒø…7Uè¦ýÿƒÄƒøÿ…%s:jVjUèð¿þÿƒÄPèwÿÿUèñ¥ýÿƒÄƒøþ…üf‹f…Àv#%ÿÿj €HÑâRUjèÿÿ…À‰C@„Ñ€½žuŠ…Ÿ¹˜Ÿ5s<s¹0Ÿ5sƒàPQUèŸƒÄ …À„›Uè.ÓýÿƒÄƒø…‰Uè<šýÿƒÄƒø…w€{u&3À3Éf‹C,f‹K*jT RUjèÿÿ…À‰C.„K3Àjf‹ @ˆÁâRUjè[ÿÿ…À‰D$„&fƒ?‰C&ÇD$†4p"Uèñ¤ýÿƒÄƒøÿ…ü~ájWjUèǾþÿƒÄPèNÿÿD$jPjU课þÿƒÄPè6ÿÿ^àjSjU蘾þÿƒÄPèÿÿ€;?uÆl€;7uÆj3É3ÒŠŠQRèPHþÿ‹L$ˆG#ƒÄ€yuÇ@3sër%ÿƒÀÞƒøXwe3ÒŠð™4sÿ$•¼™4sÇÐ$2sëNÇ`3sëFÇø2së>Ç&3së6Ç +3së.Ç 03së&Ç053sëÇð:3sëÇ@3sëÇù2sëÇÀ73sFßjPjUèØ½þÿƒÄPè_ÿÿ^öjSjUèÁ½þÿƒÄPèHÿÿ‹M$‹ŠB$<#t <"t ‹ED‹‹9ë ‹UD‹‹H‹yWjRUjèÖÿÿ…À‰Fú„¢WPjUèq½þÿƒÄPèøÿÿ‹FúÆ8Š…ž<u7€½Ÿr.NþjQjUè@½þÿƒÄPèÇÿÿVÿjRj Uè)½þÿƒÄPè°ÿÿ‹D$3Éf;Á}‰Nì‹D$÷Øf‰Fðë¿Ð‹D$‹@.‰Fì9 u‰Nè‰NäŠFà<&t^Âjh¬ 5sVÿ×ƒÄ …À…g_°#^‹= q5sjh¤ 5sVÿ×ƒÄ …Àu_°<^Âjhœ 5sVÿ×ƒÄ …À…-_°"^Šj‹M‹U°;Q(u'jj‹EäPèÛqýÿƒÄ jj‹MäQèëoýÿƒÄ ÇEÈÇEèé‹U‹E°;B(u jj‹MäQèqýÿƒÄ jj‹UäRè­oýÿƒÄ ÇEÀ‹EäPèúýÿƒÄ‰Eèƒ}èþ„Dƒ}èué9‹Mä‹QD‰Uü‹Eü‹H‹‰Uă}Äu ÇEèéƒ}ÀuÇEÀjj‹EäPjèÝíþÿ‰E¸ƒ}¸u ÇEèéâ‹MØ‹U¸‰‹E¸ƒÀ‰EØj‹M°‹Q‹EÄLQ‹UäRjèœíþÿ‰Eôƒ}ôu ÇEèé¡‹E¸‹Mô‰‹U°‹BP‹MôQ‹U°‹Pè©îþÿ‹M°‹Q‹EôLÿ‰Mô‹UôÆ.‹EôƒÀ‰Eô‹MÄQ‹UôR‹Eü‹H‹QRèsîþÿ‹EôEĉEô‹MôÆ‹U°‹B‹MÄT‹E¸f‰P‹M̃Á‹U¸f‰J‹E¸fÇ@‹M‹Q4ƒÂ‹E‰P4é£þÿÿƒ}èuë|‹MäQè•~ýÿƒÄ‰Eèƒ}èþt ƒ}èuëëáƒ}èuëU‹UäRè>sýÿƒÄ‹Eà3ÉŠ…Ét ‹UàR‹EäPè£øÿÿ‹MàÆƒ}Àuh]'‹UäRè9ŒþÿÇEèë‹E°‹H‰M°éLùÿÿ‹Uà3ÀŠ…Àt ‹MàQ‹UäRèZøÿÿƒ}èuƒ}Èt‹EìP‹MQ豈‰Eè‹UìR‹EäPèÑìþÿƒÄƒ}èu3À븋å]ÂÌÌÌÌÌÌÌÌÌU‹ìƒì‹E‹‰Mü‹UƒÂ8‰Uô‹E¿H&ƒùthd'‹UüRè‹þÿ3Àéhä 5s‹EüPè*©ýÿƒÄ…À„h£5s‹MüQè©ýÿƒÄ…Àtx‹U‹BP‹MüQèú¨ýÿƒÄ…Àtahl›5s‹UüRèå¨ýÿƒÄ…ÀtLhH¢5s‹EüPèШýÿƒÄ…Àt7‹ È 5sQ‹UüR蹨ýÿƒÄ…Àt ‹EüP詪ýÿƒÄ…Àt‹MüQè¹qýÿƒÄ…Àu3ÀéW‹Uü¿Bhƒè‹Mf‰A,‹U‹Eü‹Hj‰J0‹Uü‹B$‰EøÇEðë ‹MðƒÁ‰Mð‹Uü¿B"9Eð‹Mð‹Uø‹Š3ÉŠH*ƒá…É„âjj‹UüRjè«êþÿ‰Eìƒ}ìu3Àé׋Eô‹M쉋UìƒÂ‰Uôj‹Eð‹Mø‹3ÀŠBƒÀP‹MüQjèkêþÿ‹U쉋Eìƒ8u3Àé“‹Mð‹Uø‹Š3ÉŠHQ‹Uì‹P‹Mð‹Uø‹ŠPèsëþÿ‹Mð‹Uø‹Š3ÉŠH‹Uì‹Æ‹Mð‹Uø‹Š3ÉŠHƒÁ‹Uìf‰J‹Eð‹Mø‹‹Eìf‹J0f‰H‹UìfÇB‹E‹H4ƒÁ‹U‰J4éçþÿÿ‹EüÇ@j¸‹å]ÂÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì ‹E‹‰Môjh‹UôRjèéþÿ‰Eøƒ}øu3Àéºj‹EøPhä 5sè°êþÿÇEì‹MøMì‰Mü‹U‹B8‰EäÇEèë ‹MèƒÁ‰Mè‹U‹Eè;B4ƒ©‹Mä¿Q‹EìLÿ‰Mì}ìv‹UøR‹EôPè¿éþÿƒÄ3Àé?‹M䋉Uàë‹EàƒÀ‰Eà‹MüƒÁ‰Mü‹Uä¿B‹Mä‹Dÿ9Eàs ‹Mü‹UàŠˆëÍ‹Mä‹Q‰Uäƒ}ät'‹EüÆ,‹MüƒÁ‰Mü‹UüÆ ‹EüƒÀ‰Eü‹MìƒÁ‰Mìé?ÿÿÿ‹UüÆ‹EüƒÀ‰Eüj‹MìƒÁQ‹UôRjèjèþÿ‰Eàƒ}àu‹EøP‹MôQèéþÿƒÄ3Àé„‹UìƒÂR‹EàP‹MøQèvéþÿ‹U‹Eà‰B ‹M‹Q R‹EôPè¥ýÿƒÄ…ÀtVhl›5s‹MôQèx¥ýÿƒÄ…ÀtA‹U‹BP‹MôQèa¥ýÿƒÄ…Àt*hl›5s‹UôRèL¥ýÿƒÄ…ÀthH¢5s‹EôPè7¥ýÿƒÄ…Àu‹MøQ‹UôRècèþÿƒÄ3Àéã‹EôPè§ýÿƒÄ…Àt‹MôQè nýÿƒÄ…Àu0‹U¿B,…Àthn'‹MôQè0‡þÿ‹UøR‹EôPèèþÿƒÄ3Àé“‹M‹Q8‰Uä‹Eô‹H$‰MðÇEèë ‹UèƒÂ‰Uè‹E‹Mè;H4sC‹Uè‹Eð‹ ‹Uäf‹A&f‰B ‹Mä¿Q R‹Eè‹Mð‹3ÀŠB$Pjèhðþÿ‹Mä‰A ‹Uä‹B‰Eäë©‹MôQèŽÄýÿƒÄ‹UøR‹EôPè~çþÿƒÄ¸‹å]ÂU‹ìƒì ‹EƒÀ<‰Eø‹M‹‰Uü‹Eøƒ8t%‹Mø‹¿B;E u ¸é½‹Mø‹ƒÂ‰UøëÓjj ‹E‹Qjèkæþÿ‰Eäƒ}äu3Àé‹U‹B(‰EàÇEè‹Mè;M }‹Uà‹B‰Eà‹MèƒÁ‰Mèëäjj‹UüRèbiýÿƒÄ jj‹EüPèrgýÿƒÄ ‹M¿Q,ƒú;‹Eà‹Qh¢5s‹UüRè_GÿÿƒÄ …Àt ‹EüPèO¥ýÿƒÄ…Àt‹MüQè_lýÿƒÄ…Àu\‹UäfÇ‹Eà‹QhX¢5s‹UüRèGÿÿƒÄ …Àt ‹EüPè ¥ýÿƒÄ…Àt‹MüQèlýÿƒÄ…Àu‹UäR‹EüPè(æþÿƒÄ3Àé¢ë‹MäfÇjj‹UüRè—hýÿƒÄ jj‹EüPè§fýÿƒÄ ‹M促â…Ò„Sjj‹EüPjè$åþÿ‰Eìƒ}ìu‹MäQ‹UüRè¾åþÿƒÄ3Àé8j‹Eà‹HƒÁ Q‹UüRjèíäþÿ‹M쉋Uìƒ:u'‹EìP‹MüQèƒåþÿƒÄ‹UäR‹EüPèsåþÿƒÄ3Àéí‹Mü‹Q$‰Uð‹Eà‹HƒéQ‹Uì‹P‹Mà‹RèÕåþÿ‹Eì‹‹Uà‹BÆDÿ.j ‹Mì‹‹EàPRh<¢5sè­åþÿ‹Mà‹QƒÂ ‹Eìf‰P‹Mìf‹U f‰Q‹Eð‹‹Uìf‹A&f‰B ‹Mì¿Q R‹Eð‹3ÒŠQ$Rjè˜íþÿ‹Mì‰A ‹UìfÇB‹Eäf‹M f‰H‹Uä‹Eì‰B‹Mø‹U䉋EäƒÀ‰Eø‹M‹Q@ƒÂ‹E‰P@é‹Mü‹Q$‰UðÇEèë ‹EèƒÀ‰Eè‹Mü¿Q"9UèØ‹Eè‹Mð‹3ÀŠB$ƒø#„¼‹Mè‹Uð‹Š3ÉŠH$ƒù"„¥jj‹UüRjèxãþÿ‰Eìƒ}ìu‹EäP‹MüQèäþÿƒÄ3ÀéŒj‹Uè‹Eð‹ 3ÒŠQ‹Eà‹HTR‹EüPjè2ãþÿ‹M쉋Uìƒ:u'‹EìP‹MüQèÈãþÿƒÄ‹UäR‹EüPè¸ãþÿƒÄ3Àé2‹Mà‹QƒêR‹Eì‹Q‹Uà‹Pè#äþÿ‹Mì‹‹Eà‹HÆD ÿ.‹Uè‹Eð‹ 3ÒŠQR‹Eì‹‹UàJQ‹Eè‹Mð‹Rèéãþÿ‹Eè‹Mð‹3ÀŠB‹Mà¿QD‹Mìf‰A‹Uì¿B‹Mì‹ÆDÿ‹Eìf‹M f‰H‹UìfÇB‹Eè‹Mð‹‹Eìf‹J&f‰H ‹Uì¿B P‹Mè‹Uð‹Š3ÉŠH$Qjè¢ëþÿ‹Uì‰B ƒ}èu&‹EäfÇ‹Mäf‹U f‰Q‹Eä‹Mì‰H‹Uø‹Eä‰ë ‹Mô‹Uì‰Q‹Eì‰Eô‹M‹Q@ƒÂ‹E‰P@éþÿÿ‹MüQè”sýÿƒÄ¸‹å]ÂÌÌÌÌÌÌU‹ìƒì4‹E‹‰Mô‹U‹’‰Eø‹MôQè|Çþÿ‹U3ÀŠBTƒà…Àt ‹M‹QP‰UüëÇEü‹E‹MøŠˆPT‹E3ÉŠHTƒá…Ét#‹U‹Eø‹H‰JP‹UøÇB‹EøŠ€áþ‹Uøˆ EЉEÌj MÐQ‹U Rÿ0q5sƒÄ ‰EÌEÐPj‹MôQè3ïþÿ…Àt ‹UôRèv ýÿƒÄ…Àt‹EôPè†gýÿƒÄ…Àu9‹Mø‹U‹BP‰A‹Mø‹UŠBTˆ‹M‹Uü‰QPƒ}üu‹EŠHT€áþ‹UˆJT3Àëƒ}üt‹EüP‹MôQèSáþÿƒÄ¸‹å]ÂÌÌÌÌÌU‹ìQ‹E ¿H ƒÁ¯M‰Mü}ü@ vha'‹URè$€þÿ3Àë)j‹EüP‹MQjèOàþÿ‹U ‰B‹E ƒxu3À븋å] ÌU‹ìƒì ÇEø@ ƒ} ÿu`‹E‹H8‰Müë ‹Uü‹B‰Eüƒ}ütD‹Mü3Òf‹Q ‹ÊƒÁ¸@ 3Ò÷ñ9Eøs‹Uø‰Uôë‹Eü3Éf‹H ƒÁ¸@ 3Ò÷ñ‰Eô‹Uô‰Uøë­ë‹E ‰Eø‹M‹Q8‰Uüë ‹Eü‹H‰Müƒ}üt‹UøR‹EüP‹M‹Rèúþÿÿ…Àu3ÀëëÔ‹E‹Mø‰HD¸‹å]ÂÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì‹E‹‰Mühl›5s‹UüRè´œýÿƒÄ…Àth¡5s‹EüP蟜ýÿƒÄ…Àu3Àë|‹M‹Q8‰Uøë ‹Eø‹H‰Møƒ}øt]‹Uø‹P‹MüQèkœýÿƒÄ…Àu3ÀëHƒ} uh¡5s‹UüRèLœýÿƒÄ…Àu3Àë)‹Eøƒxthèœ5s‹MüQè*œýÿƒÄ…Àu3Àë딸‹å]ÂÌÌU‹ìƒì ‹E‹‰Mü‹U‹B<‰Eôë ‹Mô‹Q‰Uôƒ}ôtK‹Eô‹H‰Møƒ}øt:hèœ5s‹UüRèË›ýÿƒÄ…Àt‹Eø‹Q‹UüRèµ›ýÿƒÄ…Àu3Àë‹Eø‹H‰MøëÀ릸‹å]ÂÌÌU‹ìƒì‹E‹‰Mühl›5s‹UüRèt›ýÿƒÄ…Àu3Àé9hì 5s‹EüPèX›ýÿƒÄ…Àu3Àéh£5s‹MüQè<›ýÿƒÄ…Àu3ÀéÇEøë ‹UøƒÂ‰Uø‹Eø;EÞƒ}øt8hÔ¢5s‹MüQèüšýÿƒÄ…Àu3ÀéÁh¤›5s‹UüRèàšýÿƒÄ…Àu3À饋E¿H,…Éu ‹U¿B&‰Eìë ‹M¿Q,‰Uì‹Eì‰EðÇEôë ‹MôƒÁ‰Mô‹Uô;UðAj‹EôP‹M MøQ‹URè[…Àu3ÀëF‹Eô;Eðth£5s‹MüQè]šýÿƒÄ…Àu3Àë%ë®h›5s‹UüRèBšýÿƒÄ…Àu3Àë é ÿÿÿ¸‹å] ÌÌÌÌÌÌÌU‹ìƒì ‹E‹‰Mô‹U‹B8‰EðÇEè¹…É„@ë ‹Uð‹B‰Eðƒ}ð„·‹Mð¿Q;Utë߃}èt ÇEèëh£5s‹EôPèµ™ýÿƒÄ…Àu3Àé÷‹Mð¿Qƒút4‹Eð‹Q‹UôR茙ýÿƒÄ…Àth ›5s‹EôPèw™ýÿƒÄ…Àu3Àé¹ëGh¢5s‹MôQèY™ýÿƒÄ…Àt+‹Uð‹P‹MôQèC™ýÿƒÄ…Àthèœ5s‹UôRè.™ýÿƒÄ…Àu3Àép‹Eð¿H ƒÁ¯M ‹Uð‹BÁ‰Eü‹Mð3Òf‹Q…Òu ÇEàë‹Eü‹‰Mà‹Uà‰Uäƒ}ätn‹EüƒÀ‰Eü‹MüQ‹UäR‹Eð‹H Q‹UôRèœ1‰Eøƒ}øu3Àéü‹EøP‹MôQ蟘ýÿƒÄ…Àu‹UøR‹EôPèËÛþÿƒÄ3ÀéÑ‹MøQ‹UôRè´ÛþÿƒÄëhœ¢5s‹EôPèa˜ýÿƒÄ…Àu3À飋Mð¿Qƒúuh›5s‹EôPè9˜ýÿƒÄ…Àu3Àë~é6þÿÿƒ}uëlÇE‹M‹Q<‰Uì‹E¿H,…Éu!ƒ}ìt‹Uì¿B;Euë ‹Mì‹Q‰UìëáëÇEƒ}ìu3Àë$‹Eì‹H‰Mð‹U‹Bpƒè‹M +ȉM é³ýÿÿ¸‹å]ÂÌÌÌÌÌÌÌÌÌÌU‹ìƒì,‹E‹‰MðÇEìƒ} …Ø‹U‹B8‰Eè‹Mf‹Q$€âü‹Ef‰P$‹Mèƒy…Ž‹U¿Bƒøt ‹M¿Q…Òu ‹E‹H‰MàëT‹U¿Bƒøÿu ‹M¿Q‰Uàë<‹E¿H‹U¯Jù@ rha'‹EðPèLyþÿ3ÀéË‹M¿Q‹E¯P‰Uà‹MàQ‹URè7ùÿÿ…Àu3À颋E¿H…Ét ‹U¿Bƒøu ¸éëP‹M¿Qƒúÿt‹E¿H$ƒá…Ét ¸þÿÿÿé[‹Uf‹B$$ü‹Mf‰A$‹Uƒzt‹E‹HL‹U‹BHLÿ‰Mì‹U¿Bƒøÿt*‹M¿Q‹E¯P‹MìTR‹EPèþöÿÿ…Àu3Àéù‹M‹Q R‹EðPè–ýÿƒÄ…Àtmhl›5s‹MðQèþ•ýÿƒÄ…ÀtX‹U‹BP‹MðQèç•ýÿƒÄ…ÀtAhl›5s‹UðRèÒ•ýÿƒÄ…Àt,‹E‹HQ‹UðR軕ýÿƒÄ…Àthl›5s‹EðP覕ýÿƒÄ…Àu3Àén‹Mƒyt#‹U‹BP‹MðQè•ýÿƒÄ…Àu3ÀéG鳃} …“‹Uƒzth£5s‹EðPèK•ýÿƒÄ…Àu3Àéëhì 5s‹MðQè-•ýÿƒÄ…Àu3Àéõj‹URèô…Àthl›5s‹EðPè•ýÿƒÄ…Àu3ÀéÊ‹Mƒyth£5s‹UðRèÝ”ýÿƒÄ…Àu3Àé¥j‹EPèô÷ÿÿ…Àu3Àé‹MðQè°–ýÿƒÄ…Àt‹UðRèÀ]ýÿƒÄ…Àu3Àéhƒ}ìt3ÇEäë ‹EäƒÀ‰Eä‹Mä;Mìs‹UðRè¹hýÿƒÄ…Àu3Àé1ëÖ‹E‹H8‰Mèë ‹Uè‹B‰Eèƒ}èt‹Mè‹Uè‹B‰AëãÇEäë ‹MäƒÁ‰Mä‹U‹Eä;BDƒ¹‹MðQèWhýÿƒÄ‰Eôƒ}ôu3Àéʃ}ôþué’‹U‹B8‰EèÇEàë ‹MàƒÁ‰Mà‹U‹Eà;B4sg‹Mð‹QD‹Eà‹ ‚‰Mü‹Uè‹B‰Eø‹Mü‹‰UÜ‹Eø‹M܉ƒ}Üt‹UÜR‹EøƒÀP‹Mü‹QRèN×þÿ‹Eè‹H‹Uè¿B L‹Uè‰J‹Eè‹H‰Mèë…é/ÿÿÿƒ}ôþt‹UðRè˜gýÿƒÄƒøþu(ƒ} u‹Ef‹H$€É‹Uf‰J$‹Ef‹H$€É‹Uf‰J$‹Eƒxt#‹M¿Q$ƒâ…Òuh`'‹EðPèCuþÿ3Àé‹M¿Qƒúÿu&‹EðPè'gýÿƒÄƒøþtha'‹MðQèuþÿ3Àé‹UðRègýÿƒÄƒøþt3Àë{ƒ} u ÇEØë‹E‹HL‹UJH‰MØ‹E‹M؉HL‹U‹Eä‰BH‹M¿Qƒúÿt:‹EƒxPu ÇEÔë‹M‹QPRÿàp5sƒÄ‰EÔ‹EÔP‹MQèóÿÿ…Àu3À븋å]ÂÌÌÌÌU‹ìƒì4VW‹E‹‰Mð‹U‹B‰EôÇEÜÇEü‹M¿Q‰UÔ‹EÔƒÀ‰EÔƒ}Ôw,‹MÔÿ$ÅØ4sÇEàëÇEàëÇEàëÇEà‹U¿B‰EЋMЃé‰MЃ}Ðw,‹UÐÿ$•ÕØ4sÇEèëÇEèëÇEèëÇEè‹Eð3Éf‹ˆ„စÉt ‹Uð‹B‰EìjhL£5s‹MðQè`8ÿÿƒÄ …Àué”UøRjÿjÿj8jhD£5s‹EðPè:;ÿÿƒÄ…Àuén‹M Q‹} ƒÉÿ3Àò®÷уÁÿQjÿj#jh<£5s‹UðRè;ÿÿƒÄ…Àué:EàPjÿjÿj8jh0£5s‹MðQèà:ÿÿƒÄ…ÀuéUèRjÿjÿj8jh(£5s‹EðPèº:ÿÿƒÄ…ÀuéîMôQjÿjÿj8jh £5s‹UðRè”:ÿÿƒÄ…ÀuéÈ‹Eð3Éf‹ˆ„စÉt&‹Uð‹B‰EØ‹M؃yt ‹UØ‹B‰EØëì‹MØ‹Uì‰Q‹EðPèÃ@ÿÿƒÄ…ÀuéwÇEÜ‹MðQèW’ýÿƒÄ…Àué[‹UðRèYýÿƒÄƒøtéEj‹EðPèJ5ÿÿƒÄ‰Eüƒ}üué)‹M‹Uðf‹‚Df‰Al‹M‹Uðf‹‚Df‰AV‹M‹Uð‹B$‰AX‹M‹Uð‹BD‰Ah‹Mü‹‰UÌ‹Ẽè‰Ẽ}Ìw4‹MÌÿ$åØ4s‹UfÇBë‹EfÇ@ÿÿë‹MfÇAë ‹UfÇBþÿ‹E‹Mô‰HH‹UÇBpÿÿÿÿ‹EÇ€˜‹MðÇAD‹UðÇB$‹EðfÇ€D‹MðfÇA"‹UðRèXýÿƒÄ…ÀuéFÇEÜ‹EðPèf5ÿÿƒÄ…Àt‹MðQèV5ÿÿƒÄƒøté‹UðRè4ÿÿƒÄƒøtéj‹EðPè4ÿÿƒÄ‹M‹‰‘€j‹EðPèï3ÿÿƒÄ‹M‹‰QHj‹E¿HVR‹EðPjèèÐþÿ‹M‰A`‹Uƒz`u餋E¿HV‹U‹B`Ljj‹M¿QVkÒ R‹EðPjè¨Ðþÿ‹M‰Ad‹Uƒzduéd‹E‹Mðf‹Qhf‰P&‹Eðƒxj„B‹Mð¿Qh‹Eð‹Hjƒ|‘üu‹Uf‹B&f-‹Mf‰A&j‹U¿B&ÁàP‹MðQjè;Ðþÿ‹U‰B(‹Eƒx(ué÷ÇEäë ‹MäƒÁ‰Mä‹U¿B&9Eä΋Mð‹Qj‹Eäƒ<‚uEjj‹MðQjèçÏþÿ‹U‹J(‹U䉑‹E‹H(‹Uäƒ<‘ué—‹E‹H(‹Uä‹‘Š ¸5sˆëuj‹Uð‹Bj‹Mä‹<ˆƒÉÿ3Àò®÷ÑQ‹UðRjèŽÏþÿ‹M‹Q(‹M䉊‹U‹B(‹Mäƒ<ˆuëA‹Uð‹Bj‹Mä‹<ˆ‹U‹B(‹M䋈ƒÉÿ3Àò®÷Ñ+ù‹÷‹Á‹úÁéó¥‹Èƒáó¤éÿÿÿ¸ëƒ}Üt‹Mðƒyu ‹UðRèȬýÿƒÄ3À_^‹å]Â…Ó4ssÓ4sjÓ4s|Ó4s¯Ó4s¸Ó4sÁÓ4sÊÓ4sÝÕ4sèÕ4süÕ4sÒÕ4süÕ4süÕ4süÕ4sóÕ4sÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì W‹E‹‰MôÇEüÇEð‹U‹BP‹MôQèŒýÿƒÄ…Àtvhl›5s‹UôRèî‹ýÿƒÄ…Àta‹E‹HQ‹UôRè׋ýÿƒÄ…ÀtJhl›5s‹EôPè‹ýÿƒÄ…Àt5hH¢5s‹MôQè­‹ýÿƒÄ…Àt ‹UôRèýÿƒÄ…Àt‹EôPè­TýÿƒÄ…Àu3Àé‘‹Mô¿‘D‹EP4‰Uø‹M¿Qƒúu ‹E‹MøH@‰Møj‹UøÁâR‹EôPjèÐÍþÿ‹M‰A`‹Uƒz`u3Àé<j‹Eô¿ˆDkÉ Q‹UôRjèŸÍþÿ‹M‰Ad‹Uƒzdu3Àé ‹E‹Môf‹‘Df‰Pl‹Ef‹Møf‰HV‹U‹Eô‹H$‰JX‹U‹Eô‹HD‰Jh‹UôÇBD‹EôÇ@$‹MôfÇD‹UôfÇB"‹E‹H4ƒéiɇ‰Mü‹UøƒêkÒj‹E¿H&ƒéiÉ[щUð‹U‹B8‰Eìë ‹Mì‹Q‰Uìƒ}ìt'‹Eì‹8ƒÉÿ3Àò®÷уÁÿ‹Uì¿B ÈkÉ‹UüщUüëÊ‹E¿Hƒùu]‹U‹B<‰Eèë ‹Mè‹Q‰Uèƒ}ètC‹Eè‹H‰Mìë ‹Uì‹B‰Eìƒ}ìt'‹Mì‹9ƒÉÿ3Àò®÷уÁÿ‹Uì¿B ÈkÉ‹UüщUüëÊ뮋EÇ@x‹M¿Q&ƒú…‹Eƒx~x‹MüÁB‰Mä‹UðÂø‰Uð‹Eü‹MðA‰Uà}àô}K‹EfÇ@|¸ô+Eà™÷}äƒÀ%ÿÿ‹M‰Ax‹Uƒzx2~‹E‹@x™¹2÷ù‹Uf‰B|‹EÇ@x2‹Mƒyxu+‹UðÂ+‰Uð‹EÇ@x‹MðMü¸ô™÷ù‹Uf‰B|¸_‹å]ÂÌÌÌÌÌÌÌU‹ìƒì ‹E‹H<‰Môƒ}ô„΋Uô‹B‰Eøë ‹Mø‹Q‰Uøƒ}ø„¢‹Eøƒxu!‹M‹QR‹EøP‹M‹RèŠêÿÿ…Àu3Àé‹‹Eø¿H ƒÁ¯M ‹Uø‹BÁ‰Eüƒ}u j‹MüQèUÌþÿëG‹U‹ƒ8t+‹M‹‹Eü‹ ‰‹U‹‹Q‹UüƒÂR‹E‹‹QRèðËþÿë ‹EüÇ‹MƒÁ‰MéKÿÿÿ‹Uô‹B‰Eôé(ÿÿÿ¸‹å] ÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì ‹E‹‰Mü‹U¿Bƒøt‹M¿Q…Òt ÇEôëÇEô‹Eô‰Eø‹M‹QR‹EüP蕇ýÿƒÄ…Àu3ÀéÉhèœ5s‹MüQèy‡ýÿƒÄ…Àu3Àé­‹U‹B ƒÀP‹MüQèX‡ýÿƒÄ…Àu3ÀéŒhl›5s‹UüRè<‡ýÿƒÄ…Àu3Àës‹E¿Hƒùu.‹UøR‹EPèëÿÿ…Àu3ÀëRhl›5s‹MüQè‡ýÿƒÄ…Àu3Àë9‹U‹BP‹MüQèç†ýÿƒÄ…Àu3Àë‹UR‹E P‹MQè;ëÿÿ…Àu3À븋å] ÌÌÌÌÌÌÌÌU‹ìƒì‹E‹‰Mü‹U‹B\‹M ƒ<ˆ„^‹Uü‹BD‰Eø‹Müf‹Q"f‰Uì‹Eü‹H$‰Mð‹U‹B\‹Mü‹U ‹‰AD‹Mü‹Uf‹Blf‰A"‹Mü‹U‹BX‰A$‹Mf‹Qlf‰Uôë f‹Eôff‰Eô‹Môáÿÿ‹U¿BV;È}t‹Môáÿÿ‹Uü‹BD‹ ˆƒyt"‹Uôâÿÿ‹Eü‹HD‹‘‹BP‹MüQè"ÉþÿƒÄ‹Uôâÿÿ‹Eü‹HD‹‘R‹EüPèÉþÿƒÄ‹Môáÿÿ‹Uü‹BDLjélÿÿÿ‹Mƒ¹„t‹Uüf‹B"f‹Müf‰A"j‹UüRè|¬þÿ‹Eƒ¸„t‹Müf‹Q"fƒê‹Eüf‰P"‹M‹Q\‹E Ç‚‹Mü‹Uø‰QD‹Eüf‹Mìf‰H"‹Uü‹Eð‰B$‹å]ÂÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì‹E‹‰MøÇEü‹Uø‹E‹H`‰ŠJÇEôë ‹UôƒÂ‰Uô‹E¿Hl9Mô}d‹Uø‹‚J‹Mô‹ˆ‰Uðƒ}ðt,‹EôkÀ ‹M‹QdЉUì‹Eì‹H‹Uð‹E ‹ ‰J‹Uð‹Bƃ}t‹MôQ‹UøRèìþÿ…ÀuÇEü뇋Eü‹å] ÌU‹ìƒì,‹E‹‰MðÇEô‹Uð‹BD‰Eü‹M¿Qƒút‹E¿H…Ét ÇEÔëÇEÔ‹UÔ‰UìÇEäë ‹EäƒÀ‰Eä‹M¿Ql9Uä}j‹EäkÀ ‹M‹QdЉUÜ‹E܃xt‹MäƒÁQ‹UðRèÍrþÿƒÄ‹MÜ‹Q‹M‰Š‹U܃:þu'‹EÜ‹H‹U‹‘‰Eà‹MäƒÁQ‹UðRèçqþÿƒÄ‹Mà‰ë‹Uƒº„…—ƒ}ì…‹E¿HlƒÁ‰Mä‹U‹B8‰Eèë ‹Mè‹Q‰Uèƒ}ètf‹EäP‹MðQè?rþÿƒÄ‰EØ‹Uè¿B ƒÀ¯E ‹Mè‹QЉUø‹Eø‹M؉ƒ}Øt!‹UØR‹EøƒÀP‹MäQ‹UðRèJqþÿƒÄPèÑÆþÿ‹EäƒÀ‰Eäë‹‹Mƒ¹„u‹U¿Bl‹MA4‰Eä‹U‹B\‹M‹Uü‰ˆ‹Eƒ¸„…ø‹Mä‹UüŠP‹MQ‹URèÄùÿÿ‰Eôƒ}ôu3Àé)‹E‹H ‹UÇ‘‹E ƒÀ‹M;AH…¯‹U¿B$ƒà…Àt[‹M‹Q ‹E‹ ‚ƒÉ‹U‹B ‹U‰ ‹E¿H$ƒá…Ét2‹U¿Bƒøÿt ‹M¿Qƒú~‹E‹H ‹U‹‘ ‹M‹Q ‹M‰Š‹U¿Bƒøÿt ‹M¿Qƒú~.‹E ƒÀ%ÿÿ‹M9ADu‹U‹B ‹M‹ˆƒÊ‹E‹H ‹E‰j‹Mð¿Q"ÁâR‹EðPjè;Äþÿ‹Mð‰AD‹UðƒzDt‹Eð¿H"Q‹Uð‹BDP‹MðQèÔ¼ýÿ‹Uð‰BD‹EðƒxDuÇEô‹Eô‹å] ÌÌÌÌÌU‹ìƒì‹E‹‰MøÇEü‹UR‹EPèŽúÿÿj‹MQ‹URèüÿÿ‹EøPèvUýÿƒÄ‰Eüƒ}üÿu‹MQ‹U R‹EPè™üÿÿ‰Eüƒ}üuëJë0ƒ}üþu*‹M‹Q ‹EÇ‚j‹MQ‹URè÷÷ÿÿ‰Eüƒ}üuë‹EøPèUýÿƒÄƒøþtÇEü‹MøÇJ‹Eü‹å] ÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì‹E‹‰MøÇEü‹UøÇ‚Jj‹E P‹MQèøÿÿ‰Eüƒ}üu3ÀëS‹UøRèI‚ýÿƒÄ‰Eüƒ}üu3Àë:‹EøPèPIýÿƒÄ‰Eüƒ}üu3Àë!‹MQ‹U R‹EPè¯þÿÿ‰Eüƒ}üu3Àë‹Eü‹å] ÌÌÌÌÌÌÌÌÌU‹ìƒì,SVW‹E‹‰Mü‹U¿BlƒÀ‰EôÇEøë ‹MøƒÁ‰Mø‹Uø;Uþ‹E‹H8‰Mè‹U Uø‰Uì‹EEø‹M‹Q\ƒ<‚tëÅÇEðë‹EðƒÀ‰Eð‹Mè‹Q‰Uè‹E‹Mð;H4™‹UôUð‰Uä‹EäP‹MüQè>nþÿƒÄ‰EØ‹Uè¿B ƒÀ¯Eì‹Mè‹QЉUà‹Eè3Éf‹H…Éu ÇEÔë‹Uà‹‰EÔ‹MÔ‰MÜ‹UÜ;UØtë6ƒ}Üt+‹EàƒÀ‰Eà‹]Ø‹MäQ‹UüRè"mþÿƒÄ‹ø‹uà‹Ë3Àó¦tëéFÿÿÿ‹M‹Uð;Q4u‹EøëéíþÿÿƒÈÿ_^[‹å]ÂÌÌÌÌÌÌÌÌÌÌU‹ìƒì0‹E‹‰Mø‹U‹Bpƒè‰EôÇEäÇEÜÇEà‹M ‰MìÇEðÇEèÇEü‹UƒzHu‹E‹H Ç ¸é‹Uƒz\u-j‹E‹HÁáQ‹UøRjè§Àþÿ‹M‰A\‹Uƒz\u3ÀéÌ‹EøÇ€JÇEäë ‹MäƒÁ‰Mä‹Uä;U }‹E‹H ‹UäÇ‘‹EäP‹MQè ÷ÿÿëÐÇEÜë ‹U܃‰UÜ‹EÜ;E ’‹MôMÜ‹U;JH|4ƒ}Üu‹E܉EÔë ‹M܃é‰MÔ‹U‹B ‹MÔ‹ˆƒÊ‹E‹H ‹EÔ‰ëP‹M¿Qƒúu?ÇEàë ‹EàƒÀ‰Eà‹M¿Q&9Uà!‹EàP‹MôMÜQ‹URè…Àu3ÀéÝëÊéYÿÿÿë‹EèEð‰Eè‹MôMð‰Môƒ}Ü„eÇEØ‹U؉Uðë ‹E؃À‰EØ‹M3Òf‹Q|9UØ}]‹E‹Hx;MÜ} ‹U‹Bx‰EÐë‹M܉MЋUЉUì‹EìP‹MôMðQ‹URè±ôÿÿ…Àu3ÀéQ‹EðEì‰Eð‹MÜ+Mì‰M܃}Üuë댋UøRèa~ýÿƒÄ…Àu3Àé‹EøPèjEýÿƒÄ…Àu3Àé‹MøQèƒPýÿƒÄƒøÿu{‹UðR‹EèP‹MôQ‹URè&üÿÿ‰Eìƒ}ì}3ÀéÑj‹EèEìP‹MQèÔöÿÿ…Àu3Àé´‹UèUìR‹EôEìP‹MQèb÷ÿÿ‰Eü‹UøÇ‚Jƒ}üu3Àé€étÿÿÿ‹EøPèÇDýÿƒÄ‰Eüƒ}üu3Àëbƒ}ü…QÿÿÿéþÿÿÇEìë ‹MìƒÁ‰Mì‹Uì;Uè}4‹E‹H\‹Uìƒ<‘u‹E‹H ‹UìÇ‘ë‹EìƒÀ%ÿÿ‹M‰At뻸‹å]ÂÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì4‹E‹‰Mð‹U‹B8‰EäÇEô‹M ‰M؃}Øtƒ}Øt"ƒ}Øt ëS¸éÚÇEø„¢5sÇEìë@ÇEøx¢5s‹UƒzHu3À鳋E‹Ht‹U‹BpLþ‰Mìƒ}ì}ÇEìë3À銋U‹B8‰Eäë ‹Mä‹Q‰Uäƒ}ät ‹EäÇ@ëåÇEèë ‹MèƒÁ‰Mè‹U‹Eè;B4þƒ}ôuéóƒ}èth\£5s‹MðQè(zýÿƒÄ‰Eôƒ}ôuéÎh¤›5s‹UðRè zýÿƒÄ…Àu ÇEôé­‹E‹H8‰MäÇEàë ‹UàƒÂ‰Uà‹Eà;Eèe‹Mä¿Q ƒÂ¯Uì‹Eä‹HʉMü‹Uä3Àf‹B…Àu ÇEÔë‹Mü‹‰UÔ‹EÔ‰EÜ‹MüƒÁ‰Mü‹Uä‹P‹MðQèzyýÿƒÄ‰Eôƒ}ôuéÿƒ}Üu;‹Uè;Uàu ÇEа¢5sëÇEФ¢5s‹EÐP‹MðQè>yýÿƒÄ‰Eôƒ}ôuéÃ錋Uäƒzu3‹EüP‹MÜQ‹Uä‹B P‹MðQèç‹Uä‰B‹Eäƒxu ÇEôé‚‹Mè;Màu‹Uø‰UÌëÇEÌ ›5s‹EÌP‹MðQèÈxýÿƒÄ‰Eôƒ}ôuëP‹Uä‹BP‹MðQèªxýÿƒÄ‰Eôƒ}ôuë2‹Uè;UàthÀ¢5s‹EðPè†xýÿƒÄ‰Eôƒ}ôuë‹Mä‹Q‰Uäé†þÿÿh›5s‹EðPè\xýÿƒÄ‰Eôƒ}ôuëéêýÿÿ‹M‹Q8‰Uäë ‹Eä‹H‰Mäƒ}ät(‹Uäƒzt‹Eä‹HQ‹UðRèV»þÿƒÄ‹EäÇ@ëÉ‹Eô‹å]ÂÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒìÇEüƒ} u ‹Ef‹Hf‰Møë ‹U‹BƒÀf‰Eø‹MøáÿÿQ‹URè€Øÿÿ…Àu3Àé}‹E P‹MQèx‰Eìƒ}ì…‹U¿Bƒø…ÿfÇEô‹Môáÿÿ‹U;J¼‹Eô%ÿÿ‹M‹Q ‹‚ƒà…À„ ÇEüfÇEðë f‹MðfƒÁf‰Mð‹Uðâÿÿ‹E3Éf‹H&;Ñ+‹UðâÿÿR‹Eô%ÿÿP‹MQè÷ …Àu ÇEüë볃}üu1‹UôâÿÿR‹Eô%ÿÿP‹MQè6öÿÿ‰Eüƒ}üu f‹UôfƒÂf‰Uôƒ}ütëé/ÿÿÿ‹Eô%ÿÿ…Àt‹Môáÿÿ‹U‰Jtƒ}ütÇEüëƒ}ìu‹Eì‰EüëÇEü‹MƒyPu ÇEèë‹U‹BPPÿàp5sƒÄ‰Eè‹MèQ‹URè×ÿÿ…Àu3Àë‹Eü‹å]ÂÌÌU‹ìƒì@‹E‹‰MðÇEÜ‹Uf‹B$$ü‹Mf‰A$‹U‹EÜ;B}‹M‹Q ‹EÜÇ‚‹M܃Á‰MÜëÚ‹Uƒz\u-j‹E‹HÁáQ‹UðRjèE¸þÿ‹M‰A\‹Uƒz\u3À銋E‹HQ‹UðRèuýÿƒÄ…ÀtDhèœ5s‹EðPèzuýÿƒÄ…Àt/‹M‹Q ƒÂR‹EðPè`uýÿƒÄ…Àthl›5s‹MðQèKuýÿƒÄ…Àu3Àé(‹U¿Bƒøu+j‹MQèÙÿÿ…Àthl›5s‹UðRèuýÿƒÄ…Àu3Àéñ‹E¿Hƒù…‘hô 5s‹UðRèètýÿƒÄ…Àu3ÀéÅ‹E‹H(‰Màë ‹Uà‹B‰Eàƒ}àtY‹Mà‹R‹EðPè±týÿƒÄ…ÀthÈ¢5s‹MðQèœtýÿƒÄ…Àu3Àéy‹Uàƒzthèœ5s‹EðPèwtýÿƒÄ…Àu3ÀéTë˜ë3‹M‹QR‹EðPèUtýÿƒÄ…Àthl›5s‹MðQè@týÿƒÄ…Àu3Àé‹UƒztB‹E‹HQ‹UðRètýÿƒÄ…Àu3Àéöƒ} thd£5s‹EðPè÷sýÿƒÄ…Àu3ÀéÔë"ƒ} thì 5s‹MðQèÓsýÿƒÄ…Àu3Àé°‹U R‹EPè˜øÿÿ…Àu3À阃} t%‹Mƒyth£5s‹UðRèsýÿƒÄ…Àu3Àémhl›5s‹EðPètsýÿƒÄ…Àt‹M Q‹URèÖÿÿ…Àu3Àé@‹EðPèLuýÿƒÄ…Àt‹MðQè\<ýÿƒÄ…Àu3ÀéÇEÐë ‹UЃÂ‰UЋE‹MÐ;Hƒ} u‹UÐâÿÿ‹E‹H+ʃé‰MÜë‹UЉUÜ‹Eð‹M‹Q`‰JÇEÔë ‹EÔƒÀ‰EÔ‹M¿Ql9UÔ}=‹Eð‹ˆJ‹UÔ‹‘‰Eă}Ät#‹MÔkÉ ‹U‹BdÁ‰Eì‹Mì‹Q‹EÄ‹MÜ‹ЉP뮋EðPèÅFýÿƒÄ‰Eôƒ}ôÿtépƒ}Ðua‹MðÇJ‹Uð‹BD‰Eü‹MðÇAD‹Uð‹B$‰Eè‹MQè¼b‹Uð‹Eü‰BD‹Mð‹U‹B`‰J‹Mð‹Uè‰Q$‹Eð‹Mf‹QVf‰P"‹Eð‹HD‰MüÇEÔë ‹Uԃ‰UÔ‹E¿Hl9MÔ}j‹UÔkÒ ‹E‹HdʉMì‹Uìƒzt‹EÔƒÀP‹MðQèœ`þÿƒÄ‹Uì‹J‹U܉‘‹Eìƒ8þu'‹Mì‹Q‹EÜ‹ ‚‰MÈ‹UÔƒÂR‹EðPè¶_þÿƒÄ‹Mȉë‹U‹B ‹MÜLj‹U¿BlƒÀ‰EÔ‹M‹Q8‰Uäë ‹Eä‹H‰Mäƒ}ätf‹UÔR‹EðPè`þÿƒÄ‰EÀ‹Mä¿Q ƒÂ¯UÜ‹Eä‹HʉMø‹Uø‹EÀ‰ƒ}Àt!‹MÀQ‹UøƒÂR‹EÔP‹MðQè#_þÿƒÄP誴þÿ‹Uԃ‰UÔë‹‹E‹H\‹UÜ‹Eü‰‘‹MðÇAD‹U¿Bl‹MA4‰EÔ‹UÔ‹Eü Q‹UÜR‹EPè¯çÿÿ…Àu3Àéoj‹M¿QVÁâR‹EðPjèü²þÿ‹Mð‰AD‹UðƒzDu3ÀéA‹Eð‹HD‰MüÇEÔë ‹Uԃ‰UÔ‹E¿HV9MÔ}6j‹U¿BVÁàP‹MðQjè§²þÿ‹UÔ‹Mü‰‘‹UÔ‹Eüƒ<u3ÀéæëµéÏüÿÿ‹MðÇJ‹UÇBpƒ}Ðt‹EÐ%ÿÿ‹M‰AH‹UÐâÿÿ‹E‰Ptƒ}ô„[ƒ}ôþu0ƒ}Ðu*ƒ} u$hc'‹MðQèàQþÿ‹U‹B Ǹéeƒ}Є‹M‹UÐ;Q€ƒ} …v‹E‹H8‰Mäë ‹Uä‹B‰Eäƒ}ätB‹Mä¿Q ƒÂ‹E‹H+MЯыEä‹HʉMø‹Uä¿B ƒÀ¯EÐP‹Mä‹QR‹EøPèͲþÿ믋Mƒy<t{‹U‹B<‰EØë ‹MØ‹Q‰U؃}Øta‹EØ‹H‰Mäƒ}ätP‹Uä¿B ƒÀ‹M‹Q+UЯ‹Mä‹QЉUø‹Eä¿H ƒÁ‹UЃê¯ÊQ‹Eä‹HQ‹UøRèT²þÿ‹Eä‹H‰MäëªëÇEÜë ‹U܃‰UÜ‹EÜ;EÐ}6‹MÜQ‹UÜR‹EPè¼íÿÿ…Àu‹MÜáÿÿ‹U‰Jt‹EÜ%ÿÿ‹M‰AHë빋U‹B ‹MЋˆƒÊ‹E‹H ‹EЉ‹M‹UÜ;Q}‹E‹H ‹UÜÇ‘‹E܃À‰EÜëÚ郋M‹UÐ;Q|‹EðPèBýÿƒÄƒøþug‹Mf‹Q$€Ê‹Ef‰P$ƒ} u‹Mf‹Q$€Ê‹Ef‰P$ƒ}Ðu‹M‹Q ‹EЋ ‚ƒÉ‹U‹B ‹UЉ ë‹E‹H ‹UЋD‘ü ‹M‹Q ‹MЉDŠüÇEôë‹UÇBp‹EÇ@t‹MÇAH‹UðRè~AýÿƒÄ‰Ẽ}Ìþt ƒ}Ìuëëá‹Eô‹å]ÂÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì‹E‹‰MôÇEø‹UR‹EPèN‰Eìƒ}ìu3À鯋M‹Q8‰Uðë ‹Eð‹H‰Mðƒ}ðt‹Uð¿B;Euëëáƒ}ðu3Àéh<¡5s‹MôQè‰lýÿƒÄ…À„ð‹UìR‹EôPèqlýÿƒÄ…À„Øhl›5s‹MôQèXlýÿƒÄ…À„¿hD¡5s‹UôRè?lýÿƒÄ…À„¦‹Eð‹Q‹UôRè%lýÿƒÄ…À„Œh ›5s‹EôPè lýÿƒÄ…Àtw‹Mð‹R‹EôPèökýÿƒÄ…Àtahl›5s‹MôQèákýÿƒÄ…ÀtLhì 5s‹UôRèÌkýÿƒÄ…Àt7j‹EP‹M Q‹URè’Ñÿÿ…Àt ‹EôPè¥mýÿƒÄ…Àt‹MôQèµ4ýÿƒÄ…Àu ÇEøëz‹Uð¿Bƒà…Àulƒ}ðtf‹Mð¿Q;UuO‹Eð¿Hƒá…ÉtA‹Uð¿B ƒÀ‹M‹Qp‹M Tÿ¯Â‹Mð‹QD‰Eüj‹MüQ‹UôRèqdþÿƒÄPèè®þÿë ‹Eð‹H‰Mð딋Eø‹å] ÌÌU‹ìƒìd‹E‹H(‰MÔ‹U¿B&ƒøu'‹M¿Q,ƒúƒ} t ‹E 3ÉŠ…Éu ¸é&‹U¿B,…À„¡‹M‹Q0‰UüÇEØë ‹E؃À‰EØ‹M¿Q,9UØu‹E ‰EЋMü‹‰UÌ‹EÌŠˆMË‹UÐ: u.€}Ët‹EÌŠHˆMÊ‹UÐ:JuƒẼEЀ}ÊuÌÇEÄëÀƒØÿ‰EÄ‹MĉMÀƒ}Àu‹EØé‰‹UüƒÂ‰Uüévÿÿÿé“ÇEØë ‹E؃À‰EØ‹M¿Q&9UØu‹E ‰E¼‹MÔ‹‰U¸‹E¸ŠˆM·‹U¼: u.€}·t‹E¸ŠHˆM¶‹U¼:JuƒE¸ƒE¼€}¶uÌÇE°ëÀƒØÿ‰E°‹M°‰M¬ƒ}¬u‹EØéñ‹UÔ‹B‰EÔévÿÿÿƒ}„׋ @q5sƒ9~j‹U3ÀŠPÿDq5sƒÄ‰E¨ë‹M3ÒŠ¡Hq5s‹3Àf‹Qƒà‰E¨ƒ}¨t ‹MƒÁ‰Më²jh$¡5s‹URÿ4q5sƒÄ …Àtjh<¡5s‹EPÿ4q5sƒÄ …À…U‹MƒÁ‰M‹@q5sƒ:~j‹E3ÉŠQÿDq5sƒÄ‰E¤ë‹U3ÀŠ‹ Hq5s‹3Éf‹ Bƒá‰M¤ƒ}¤t ‹UƒÂ‰Uë±jh,¡5s‹EPÿ4q5sƒÄ …ÀuX‹MƒÁ‰M‹@q5sƒ:~j‹E3ÉŠQÿDq5sƒÄ‰E ë‹U3ÀŠ‹ Hq5s‹3Éf‹ Bƒá‰M ƒ} t ‹UƒÂ‰Uë±ÇEØë ‹E؃À‰E؃}Ø}\‹ @q5sƒ9~j‹UUØ3ÀŠPÿDq5sƒÄ‰Eœë‹MMØ3ÒŠ¡Hq5s‹3Àf‹Qƒà‰Eœƒ}œtë‹MMØ‹UØŠˆDÜë•‹MØÆD ÜjUÜR‹EPèœüÿÿë3À‹å] ÌÌU‹ìƒì‹E‹H(‰Mø‹U¿B,…Àtƒ} ‹M¿Q,9U ~3Àë:ë3‹E¿H&9M ~3Àë(ÇEü‹Uü;U }‹Eø‹H‰Mø‹UüƒÂ‰Uüëä‹Eø‹‹å]ÂU‹ìì SVWÆEü'ÇEìÇEô‹EPjf‹M Qè"¬þÿ¿Ð‰Uðj‹EðƒÀP‹MQjèh©þÿ‰Eøƒ}øu3Àé ‹Uø‰Uè‹E ‰…pÿÿÿ‹pÿÿÿƒé%‰pÿÿÿƒ½pÿÿÿUw]‹…pÿÿÿ3ÒŠž5sÿ$•Ž5s‹MèŠUüˆÇEì‹EèƒÀ‰Eèë.‹MèÆ0‹UèÆBx‹EèƒÀ‰Eèë‹MèÆ$ÇEô‹UèƒÂ‰Uèj‹EðP‹MèQj/‹UR‹EP‹M Q‹URèSþÿƒÄ ‰Eƒ}ÿu‹EøP‹MQèJ©þÿƒÄ3ÀéE‹UèUÆ‹E ‰…lÿÿÿƒ½lÿÿÿ:tƒ½lÿÿÿ=tƒ½lÿÿÿotéƒ}„…ÇE ¿Àº5sƒÉÿ3Àò®÷уÁÿ‰M˜¿¼5sƒÉÿ3Àò®÷уÁÿ‰M¨‹MðƒÁ‰Mðj‹UðƒÂR‹EPjè¨þÿ‰E”ƒ}”ué+‹}ø‹U”ƒÉÿ3Àò®÷Ñ+ù‹÷‹Á‹úÁéó¥‹Èƒáó¤‹MøQ‹URèz¨þÿƒÄ‹E”‰Eø‹MøƒÁ‰Mè‹}øƒÉÿ3Àò®÷уÁÿ‰Mœ‹U‰U„‹E„‹@kÀ 3Ò¹÷ñ‰E¬‹E¬™¹è÷ù‰U°‹E¬™¹è÷ù‰E¬‹E¬™¹<÷ù‰U¤hÀº5s‹Uœ+U˜‹EøÂPÿ q5sƒÄ…ÀuÇE ƒ} t ‹M˜‰hÿÿÿë ‹U¨‰•hÿÿÿ‹Eœ+…hÿÿÿP‹MøQU´Rÿþÿ3ÀéÒƒ}tjh<¡5s‹EP艠ÿÿ…Àuih<¡5s‹MôQèw\ýÿƒÄ…Àu3À霋UR‹EPèÌôÿÿ‰Eäƒ}äu3Àé‹MäQ‹UôRè?\ýÿƒÄ…Àthl›5s‹EôPè*\ýÿƒÄ…Àu3ÀéOƒ}t5‹MQ‹UôRè \ýÿƒÄ…Àthl›5s‹EôPèô[ýÿƒÄ…Àu3Àéé#‹M¿Q&ƒúu ‹E¿H,ƒù~hl'‹UôRè >þÿ3ÀéçhD¡5s‹EôPè¦[ýÿƒÄ…Àu3ÀéËÇE¼ÇEèë ‹MèƒÁ‰Mè‹U¿Bl9E豃}¼t ÇE¼ëhèœ5s‹MôQèR[ýÿƒÄ…Àu3Àéw‹U‹BX‹M苈‰Uì‹Eì3ÉŠHQUÄR‹EìPèïžþÿ‹Mì3ÒŠQÆDÄEÄP‹MôQè[ýÿƒÄ…Àth ›5s‹UôRèðZýÿƒÄ…Àu3Àé‹E ƒèP‹MèQ‹URèŽúÿÿ…Àu3Àéöé6ÿÿÿ‹E¿HƒùuU‹U‹BP‹MôQè¢ZýÿƒÄ…Àt5j‹U‹Bp‹M TþR‹EPèò¾ÿÿ…Àt‹MQ‹U ƒêR‹EPèªûÿÿ…Àu3Àé’ëKhì 5s‹MôQèOZýÿƒÄ…Àt/‹U¿B3Ƀø”ÁQ‹UR‹E‹Hp‹U DþP‹MQèý¿ÿÿ…Àu3ÀéE‹UôRè \ýÿƒÄ…Àu3Àé.‹EôPè#ýÿƒÄ‰Eøƒ}øtƒ}øu3Àé ëÜ‹M¿Qƒú…´‹E‹H<‰MÀ‹U¿B,…Àuƒ}Àt‹MÀ¿Q;Uuë ‹EÀ‹H‰MÀëáƒ}Àu3À麋UÀ‹B‰Eðƒ}ðt'‹Mð¿Q;Uu‹Eð¿Hƒá…Étë ‹Uð‹B‰EðëÓƒ}ðt8‹Mð¿Q ƒÂ‹E ƒè¯Ð‹Mð‹AL‰Müj‹UüR‹EôPèlRþÿƒÄPèãœþÿ‹MôƒyVuho'‹UôRèL;þÿ3Àë+‹E ƒèP‹M‹Qp‹E LþQ‹URèJØÿÿ…Àu3À븋å]ÂÌÌÌÌÌÌÌU‹ìƒì ‹E‹‰Mø‹Uƒzp~ ‹E‹M ;Ht~3ÀéuhT¡5s‹UøRè‰XýÿƒÄ…Àu3ÀéY‹EP‹MQèÞðÿÿ‰Eôƒ}ôuhk'‹UøRè§:þÿ3Àé.‹EôP‹MøQèCXýÿƒÄ…Àthl›5s‹UøRè.XýÿƒÄ…Àu3Àéþ‹E¿HƒùuU‹U‹BP‹MøQèXýÿƒÄ…Àt5j‹U‹Bp‹M TþR‹EPèT¼ÿÿ…Àt‹MQ‹U ƒêR‹EPè ùÿÿ…Àu3ÀéŸëHhì 5s‹MøQè±WýÿƒÄ…Àt/‹U¿B3Ƀø”ÁQ‹UR‹E‹Hp‹U DþP‹MQè_½ÿÿ…Àu3ÀëU‹UøRènYýÿƒÄ…Àu3ÀëA‹EøPèz ýÿƒÄ‰Eüƒ}üt ƒ}üu3Àë"ëß‹MøƒyVuho'‹UøRè{9þÿ3À븋å] ÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì@‹E‹‰MøÇEìÇEðÇEèƒ}t&jh$¡5s‹URèךÿÿ‰Eìjh4¡5s‹EPèÄšÿÿ‰Eðƒ}ìuwh$¡5s‹MøQè­VýÿƒÄ…Àu3À飋UR‹EPèïÿÿ‰Eäƒ}äuhk'‹MøQèË8þÿ3Àéx‹UäR‹EøPègVýÿƒÄ…Àthl›5s‹MøQèRVýÿƒÄ…Àu3ÀéHƒ}…‹U¿B&ƒøu ‹M¿Q,ƒú~hl'‹EøPèd8þÿ3Àéh¤›5s‹MøQèÿUýÿƒÄ…Àu3ÀéõÇEÀÇEèë ‹UèƒÂ‰Uè‹E¿Hl9Mè}}‹U‹BX‹M苈‰Uôƒ}Àuhèœ5s‹EøPè©UýÿƒÄ…Àu3ÀéŸëÇEÀ‹Mô3ÒŠQREÄP‹MôQèL™þÿ‹Uô3ÀŠBÆDÄMÄQ‹UøRèbUýÿƒÄ…Àu3ÀéXénÿÿÿh›5s‹EøPèAUýÿƒÄ…Àu3Àé7ƒ}ðu1h4¡5s‹MøQèUýÿƒÄ…Àthl›5s‹UøRè UýÿƒÄ…Àu3Àéƒ}t ‹EP‹MøQèéTýÿƒÄ…Àu3Àéßé ÇEÀh¤›5s‹UøRèÁTýÿƒÄ…Àu3Àé·ÇEèë ‹EèƒÀ‰Eè‹M¿Ql9Uè}Fƒ}Àuhèœ5s‹EøPèTýÿƒÄ…Àu3ÀëzëÇEÀ‹M ƒéQ‹UèR‹EPèôÿÿ…Àu3ÀëUë¥h›5s‹MøQèATýÿƒÄ…Àu3Àë:‹UøRè-VýÿƒÄ…Àu3Àë&‹EøPè9ýÿƒÄ‰Eüƒ}üt ƒ}üu3Àëë߸‹å]ÂÌÌÌÌÌÌU‹ìƒìÇEü‹E Pè œþÿ…Àu3Àé=‹M ¿Qƒút‹E 3ÉŠHá°…Ét3Àé‹U ¸;B,É÷Ù…Éthe'‹U RèÙ5þÿ3Àéð‹E ƒxtP‹M 3ÒŠQƒâ…Òt,‹E 3ÉŠˆÂƒá…Éu‹U Rè¿{þÿ‹E ŠH€áþ‹U ˆJëh\'‹E Pè€5þÿ3Àé—‹M ÁfQÿ0p5sƒ}t|‹U‹;E t‹M ÁfQÿ,p5s3Àëc‹U ‹‚^‰Eøë ‹MøƒÁ‰Mø‹U ¿‚\‹M ‹‘^‚9Eøs‹Mø‹;UuÇEüëɃ}üu‹E fPÿ,p5s3À븋å]ÂÌÌÌÌÌÌÌÌÌÌÌÌU‹ì¸]ÃÌÌÌÌÌÌU‹ìƒì WÇEøë ‹EøƒÀ‰Eøƒ}ø}1j‹Mø‹À 5sR‹E Pè;–ÿÿ…Àth^'‹MQèy4þÿ3ÀéÕëÀÇEøë ‹UøƒÂ‰Uøƒ}ø²j‹Eø‹ …Р5sQ‹U Rèî•ÿÿ‰Eüƒ}ü„Š‹Eø‹<…Р5sƒÉÿ3Àò®÷уÁÿ‹UüщUü¡@q5sƒ8~j‹Mü3ÒŠRÿDq5sƒÄ‰Eôë‹Eü3ÉŠ‹Hq5s‹3Òf‹Hƒâ‰Uôƒ}ôt ‹EüƒÀ‰Eü벋Mü3ÒŠƒú(uh_'‹EPè«3þÿ3Àë é;ÿÿÿ¸_‹å]ÃÌÌÌÌÌÌÌÌU‹ìƒìVW‹EPè_™þÿ…Àu3ÀésèŸþÿÿ…Àuhp'‹MQè]3þÿ3ÀéUƒ} t)‹U 3ÀŠ…Àtƒ}ƒ}|ƒ}t ƒ}tƒ}þ}h'‹MQè3þÿ3ÀéÇEü‹U3ÀŠ‚žƒøu4‹M3ÒŠ‘Ÿƒú|$jj‹EPè^kýÿƒÄ …Àuƒ=˜¹5suÇEüƒ}üuƒ}þuh'‹MQè­2þÿ3À饃}üt ƒ}~ÇEÿÿÿÿƒ}üu#‹UÁâú@ vha'‹EPèq2þÿ3Àéi‹MÇ‹} ƒÉÿ3Àò®÷уÁÿ‰Mìj‹UìƒÂR‹EPjè{’þÿ‰Eðƒ}ðu3Àé*‹Mì‹u ‹}ð‹ÑÁéó¥‹Êƒáó¤‹EðEìÆƒ}üu&‹M Q‹URè8ýÿÿƒÄ…Àuj‹EðP膘þÿ3ÀéÞ‹MQjè”ûÿÿ…Àu3ÀéÈjhœ‹URjè÷‘þÿ‰Eèƒ}èu!‹EfPÿ,p5sj‹MðQè4˜þÿ3À錋UèÇ‚€‹Eè‹M‰‹Uèf‹Ef‰B‹Mèf‹Uf‰Q‹Eè‹M‰H‹Uè‹E‰‚”‹Mè‹U‰Q ‹Eè‹Mü‰ˆ„‹UèÆ‚ˆ‹EèÇ€Œ‹Mèǃ}ütV‹UèÇB(‹EèfÇ@&j‹Mè‹QÁâR‹EPjè$‘þÿ‹Mè‰A\‹Uèƒz\ujj‹EðP‹MèQè:3Àé¼é÷‹UðR‹EèPè —ÿÿ…Àt‹MèQèNÿÿ…Àt ‹UèRè!§ÿÿ…Àujj‹EðP‹MèQèÌ93Àétƒ}uIÇEôë ‹UôƒÂ‰Uô‹Eè¿H&9Mô+‹UôR‹EèPèÄ©ÿÿ…Àujj‹MðQ‹UèRè93Àé'ëÀj‹EèPè+¶ÿÿ…Àujj‹MðQ‹UèRèV93Àéþj‹Eè‹HÁáQ‹URjè(þÿ‹Mè‰A\‹Uèƒz\ujj‹EðP‹MèQè93ÀéÀƒ}üu%‹UèRè2Áÿÿ…Àujj‹EðP‹MèQèí83À镃}üt)‹UðR‹EèPè»ÿÿ…Àujj‹MðQ‹UèRè¾83Àéf‹E¿ˆ\…Éubjj‹URjèŠþÿ‰Eøƒ}øujj‹EðP‹MèQè€83Àé(‹Uø‹E艋MfÇ\‹U‹Eø‰‚^‹MÇb@P5séÓÇEôë ‹UôƒÂ‰Uô‹E¿ˆ\9Mô}/‹U‹‚^‹Môƒ<ˆu‹U‹‚^‹Mô‹U艈ÇEôÿÿÿÿë빃}ôÿt}‹E¿ˆ\R‹E‹ˆ^Q‹URè¬þÿƒÄ ‰Eøƒ}øujj‹EðP‹MèQè¯73ÀëZ‹U‹Eø‰‚^‹M¿‘\‹Eø‹Mè‰ ‹Uf‹‚\f‹Mf‰\‹UÂfRÿ,p5s‹EðP‹MQè÷ŽþÿƒÄ‹Eè_^‹å]ÃÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì ‹E‹‰MôÇEü‹U Çÿÿÿÿ‹EÇÿÿÿÿjh ¤5s‹MôQè‰òþÿƒÄ …Àu3ÀéI‹U€Rjÿjÿj8jhD£5s‹EôPè[õþÿƒÄ…Àu3ÀéMüQjÿjÿj8jh¤5s‹UôRè3õþÿƒÄ…Àu3Àéó‹EPjÿjÿj8jh¤5s‹MôQè õþÿƒÄ…Àu3ÀéË‹U Rjÿjÿj8jh¤5s‹EôPèãôþÿƒÄ…Àu3À飋MôQèLûþÿƒÄ…Àu3À錋UôRèåLýÿƒÄ…Àuël‹EôPè£ýÿƒÄ‰Eøƒ}øuëU‹MôQèüðþÿƒÄ…ÀtëCj‹UôRèÈïþÿƒÄ‹M‹‰j‹EôPè³ïþÿƒÄ‹M ‹‰‹EôPèPýÿƒÄ…Àuë¸ë‹MôQèWjýÿƒÄ3À‹å]ÃÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒìÇEü¸ð;5s…Àtƒ} u3Àé4‹M ƒ9t3Àé%UðREìP‹MQè=ƒÄ …Àu3Àé‹U ‹Eì‰B‹M ‹Uð‰Q‹E ‹M‹Qt‰P‹E Ç@‹M3Òƒ¹„•ÂB‹E ‹H Ê‹U ‰J‹E¿H‰Mè‹UèƒÂ‰Uèƒ}èwN‹Eèÿ$…›5s‹M ‹QƒÊ ‹E ‰PëB‹M ‹QƒÊ‹E ‰Pë1‹M ‹QƒÊ‹E ‰Pë ‹M ‹QƒÊ@‹E ‰Pë‹M ‹QƒÊ‹E ‰P‹M¿Q‰Uä‹Eäƒè‰Eäƒ}äwK‹Mäÿ$«5s‹U ‹B €‹M ‰Aë1‹U ‹B€Ì‹M ‰Aë ‹U ‹B€Ì‹M ‰Aë‹U ‹B€Ì‹M ‰A‹Uƒº„t ‹E¿Hƒùt‹U¿B…Àt ‹MƒyHÿt ‹U ÇBëBÇEüEøPMôQ‹URèŸüÿÿƒÄ …Àu3À鈃}ôÿu ‹E Ç@ë ‹M ÇA‹Uƒº„t ‹Eƒ¸˜u ‹M ÇA ë6ƒ}üt ‹U ‹Eø‰B ë%MøQUôR‹EPè/üÿÿƒÄ …Àu3Àë‹M ‹Uø‰Q ‹EÇ€˜¸‹å]Ã-5s 5sú5s5sp5s€5s‘5s¢5sÌÌÌÌÌU‹ìƒìƒ}tƒ}ÿt ƒ}tƒ} u3Àéì‹E‹‰Mü‹UüR‹EPèVóÿÿ…Àu3ÀéÌ‹M¿Ql‹E ‰‹MÇÿÿÿÿ‹Uƒº„u‹E¿H$ƒá…Éu0‹Uƒº„t ‹E¿Hƒùÿt‹Uƒº„t‹E¿Hƒùþu‹U‹BH‰Eø‹M‹Uø‰ëE‹Eƒ¸„t9‹M3ÒŠ‘ˆƒúu)‹E¿Hƒùu‹U¿B$ƒøu‹M‹Qt‰Uø‹E‹Mø‰‹UüÂfRÿ,p5s¸‹å]ÃÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì ƒ}tƒ}ÿtƒ} ~ ‹E¿Hl9M ~3Àéé‹U‹‰Eü‹MüQ‹URè0òÿÿ…Àu3ÀéÉ‹E‹HX‹U ‹D‘ü‰Eøƒ}t7ƒ}ÿt1‹Mø3ÒŠQ…Òt‹Eø3ÉŠHQ‹UR‹EøP觉þÿ‹Mø3ÒŠQ‹Eƃ}tƒ}ÿt ‹Mø3ÒŠQ$‹E‰ƒ}tƒ}ÿt ‹M‹Uø‹B&‰ƒ}t1ƒ}ÿt+‹Mø3Òf‹Q ƒúd~‹Eø3Éf‹H ‰MôëÇEôÿÿÿÿ‹U‹Eô‰‹MüÁfQÿ,p5s¸‹å]ÃÌÌÌÌÌÌÌÌU‹ìƒì$ÇEð‹E ƒè‰EüÇEôƒ}tƒ}ÿu3Àéõ‹M¿QV…Òt‹E¿HV9Mü|3Àé׋U‹‰Eì‹MìQ‹URèíðÿÿ…Àu3Àé·‹Eì‹M‹J;Q`t ‹EìPè(kþÿƒ}…ã‹Mƒyd„¼‹UükÒ ‹E‹HdʉMè‹Uèƒzt ‹EèÇ@‹Mèƒyt#ƒ}u‹Uè‹BP‹MìQ螇þÿƒÄ‹UèÇB‹EèÇ‹Mƒy`tZ‹U‹B`‹Müƒ<ˆtK‹Uì‹E‹H`‰ŠJ‹Uì‹‚J‹Mü‹ˆR‹EìPèH‡þÿƒÄ‹Mì‹‘J‹EüÇ‚‹MìÇJ‹UìÂfRÿ,p5s¸é°‹E¿Hl9Mü|$h:'‹UìRè&þÿ‹EìfPÿ,p5s3À逋MükÉ ‹U‹BdÁ‰Eè‹Mèƒyu7j‹U‹BÁàP‹MìQjèú…þÿ‰Eôƒ}ôu‹UìÂfRÿ,p5s3Àé/ƒ}þu`ƒ}uÇEðÇEäƒ}ðuA‹Eƒx`t8‹M‹Q`‹Eüƒ<‚t)‹M‹Q`‹Eü‹ ‚Q‹UìRè<†þÿƒÄ‹E‹H`‹UüÇ‘é‹E‰EÜ‹M܃é‰M܃}Üw_‹EÜ3ÒŠA$5sÿ$•)$5sÇEäëKƒ}~ }| ÇEðë3‹M‰Mäë+ÇEäë"ÇEäëÇEäëÇEäëÇEðƒ}ð…‹Uì‹Ef‹Hlf‰ŠD‹Uì‹Ef‹Hlf‰J"‹Uì‹E‹HX‰J$‹Uì‹E‹Hh‰JD‹Uì‹E‹H`‰ŠJ‹UR‹EP‹MQ‹U R‹EìPèà¤þÿƒÄ‰Eð‹M‹Uì‹‚J‰A`‹MìÇJƒ}ðul‹Uè‹E‰B‹Mè‹U‰ƒ}ôt ‹Eè‹Mô‰HfÇEà‹U‰Uøë f‹Eàff‰Eà‹Màáÿÿ‹U;J}‹Eà%ÿÿ‹Mè‹Q‹Mø‰ ‚‹UøUä‰UøëÄëƒ}ôt‹EôP‹MìQ虄þÿƒÄ‹UìfÇ‚D‹EìfÇ@"‹MìÇA$‹UìÇBD‹EìfPÿ,p5s‹Eð‹å]ì"5sµ"5s¾"5sŒ"5sÇ"5sƒ"5sÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì@ÇEÜ‹E‹‰Mð‹UÇBt‹EðPèCýÿƒÄ…Àué"‹MðQè3çþÿƒÄ‰Eàƒ}à„Žƒ}à„„ÇEØ‹UðRè¹`ýÿƒÄjh ¤5s‹EðPè†çþÿƒÄ …Àu3Àé‹MÁ€Qjÿjÿj8jhD£5s‹UðRèXêþÿƒÄ…Àu3ÀéëEØPjÿjÿj8jh¤5s‹MðQè0êþÿƒÄ…Àu3ÀéÃUÐRjÿjÿj8jh¤5s‹EðPèêþÿƒÄ…Àu3Àé›MÐQjÿjÿj8jh¤5s‹UðRèàéþÿƒÄ…Àu3Àés‹EðPèIðþÿƒÄ…Àu3Àé\‹MðQèâAýÿƒÄ…Àuéü‹UðRè æþÿƒÄ‰Eàƒ}àtéâ‹EðPèƒýÿƒÄ…ÀuéÍj‹MðQèåþÿƒÄƒø|j‹UðRè©äþÿƒÄ‰EÔƒ}Ôuéž‹EÔƒ8t‹MÔƒ9ÿuhf'‹UðRèZ!þÿé{‹EðPèýÿƒÄ…Àuéf¿M ‰Mȃ}Èt)ƒ}Èt4ƒ}Ètë<‹U‹E‰BÇEø‹M‹Q‰Uäë!‹E‰Eø‹MƒÁ‰MäëÇEø‹U‹B‰Eä‹Mø‰Mèë ‹UèƒÂ‰Uè‹Eè;Eä}‹M‹Q ‹EèÇ‚‹MèQ‹URè³·ÿÿëЋE¿HVƒÁ‹Uðf‰J"‹E¿HVƒÁ‹Uðf‰ŠD‹Eð‹M‹QX‰P$j‹E¿HVR‹EðPj褀þÿ‰Eüƒ}üué|‹Mð‹Uü‰QD‹E¿HVƒÁQ‹UüR‹EðPè5yýÿ‰Eüƒ}üuéM‹Mø‰MèÇEìë ‹UèƒÂ‰Uèƒ}ì…ž‹Eè;Eä’‹Mð‹U‹B`‰Jj‹MèQ‹URèk¸ÿÿ‹EðPèÒýÿƒÄ‰Eô‹MðÇJ‹Uô‰Uă}ÄþtOƒ}Äÿté7‹E¿HV‹Uð‹BD‹ ˆ‹Q‹E‹H ‹E苉‹EèPj‹MQ踸ÿÿ‹U‹BtƒÀ‹M‰Atéø¿Uƒâ…ÒtE‹E¿Hƒùt ‹U¿B…Àu.‹MfÇA$ƒ}èu‹U‹B Çë‹M‹Q ‹EèÇD‚ü ¿Mƒá…É„‹U¿Bƒøÿt‹M¿Qƒúþt ‹E¿H…Éulƒ}èu ÇEÀë ‹Uèƒê‰UÀ‹EÀ‰EÌ‹M‹Q ‹EÌ‹ ‚ƒÉ‹U‹B ‹Ủ ‹E¿Hƒùÿt ‹U¿Bƒøþu‹M‹Q ‹EÌ‹ ‚ƒÉ‹U‹B ‹Ủ é¼é’éOþÿÿ¿Eƒà…ÀtA‹MðQèSýÿƒÄ‰Eôƒ}ôÿt‹U‹B‹M‹Q ÇD‚ü ‹EfÇ@$ë ‹MÇŒ‹UðRèýÿƒÄƒøþtë.‹EðPèÏýÿƒÄ…Àuëj‹MðQè›bþÿ‹UðÇB$¸ëK‹EðPèÁ[ýÿƒÄj‹MðQèsbþÿ‹UðÇB$3Àë&‹EðPèœ[ýÿƒÄj‹MðQèNbþÿ‹UðÇB$¸‹å]ÃÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì0W‹E‹‰Mü‹UÇ‚˜¿Eƒø…Þ‹MƒypŒÑ‹U ‰Uà‹Eàƒè‰Eàƒ}à‡¸‹Màÿ$>05s‹U¿Bƒøu ‹MfÇA$锋U¿Bƒøÿt ‹M¿QƒúþuX‹E‹Hp‹UJt‹E;HH~Dhf'‹MüQèÓþÿÇEäë ‹UäƒÂ‰Uä‹E‹Mä;H}‹U‹B ‹MäLjëÚ3ÀéF‹U¿Bƒøt ‹M¿Q…Òu,‹E¿H$ƒùu ‹U‹B Ç‹MÇAt¸ééÜ‹U¿BƒøuA‹Mƒypu8‹U‹Š”Áá3À‹U‹z ‹ÑÁéó«‹Êƒáóª‹E‹H Ǹ鱋Uƒzpuhf'‹EüPèñþÿ3Àé“‹M¿Qƒúu ‹EfÇ@$ëZ‹M‹U;QHƒ}hf'‹EüPè´þÿ3ÀéVë2‹M‹QpU‰Uèƒ}è~ ‹E‹Mè;HH~hf'‹UüRè€þÿ3Àé"¿Eƒøu0‹M¿Qƒút ‹E¿H…Éu‹U‹BƒÀ‰Eðf‹M€Éf‰Më)ƒ}u¿Uƒúu ÇEðë ‹E‹H‰Mðë‹U‰Uð‹E ‰EÜ‹M܃é‰M܃}܇ð‹UÜÿ$•R05sÇEøéá¿Eƒà…ÀtD‹Mƒypÿu ÇEøë0‹U¿Bƒøt ‹M¿Q…ÒuÇEø ‹E‹H‰MëÇEøëÇEøé†¿Uƒâ…Òt,‹E¿Hƒùt ‹U¿B…ÀuÇEø ‹M‹QkÒÿ‰Uë‹Eƒxpÿu ÇEøëÇEøë4ÇEøë+ÇEøë"ÇEø ëÇEø@ëÇEø€ë3Àé°jh ¤5s‹MüQèÇÞþÿƒÄ …Àu3Àé’‹U€Rjÿjÿj8jhD£5s‹EüPè™áþÿƒÄ…Àu3ÀédMøQjÿjÿj8jh¤5s‹UüRèqáþÿƒÄ…Àu3Àé<EPjÿjÿj8jh¤5s‹MüQèIáþÿƒÄ…Àu3ÀéUðRjÿjÿj8jh¤5s‹EüPè!áþÿƒÄ…Àu3Àéì‹MüQèŠçþÿƒÄ…Àu3ÀéÕ¿Uƒâ…Òt ‹Eðƒè‰EØë‹Mð‰MØf‹UR‹EØPjj‹MQèÊõÿÿƒÄ‰Eôƒ}ôu¿Uƒâ…Òu ‹EÇ@pƒ}ô…V¿Mƒá…É„G‹U ‰UÔ‹EÔƒè‰EÔƒ}Ô‡Û‹MÔÿ$r05s‹UÇBpé‹Eƒxpÿu ‹MÇApë2‹U¿Bƒøu‹M‹Qp‹EPt‹M‰Qpë‹U‹Bp‹MA‹U‰Bpëy‹E‹M‹Pp;Q~‹E‹M‹Pp+Q‹E‰Ppë ‹MÇApëK‹U‹E‰Bpë@‹M‹QpU‹E‰Ppë/‹M‹U‹AH;B ‹MÇApë‹U‹E‹JH+HƒÁ‹U‰Jp¿Eƒà…Àt ‹Mðƒé‰MÐë‹Uð‰UЋEЉEì‹M‹Qp‹EìLÿ‹U;JHu‹E‹H ‹Uì‹D‘ü ‹M‹Q ‹Mì‰DŠüƒ}ôu‹Uƒºu ‹EÇ€‹Eô_‹å]Ãi*5sƒ*5s;+5s½+5så+5sœ,5s¨,5s-5s^-5sg-5sU-5sp-5sy-5só.5s/5sK/5sy/5s„/5s•/5sÌÌÌÌÌÌU‹ìƒì ƒ}tƒ}ÿu3Àéã‹E‹‰Møƒ}}h'‹U‹PèÉþÿ3À龋Mƒ¹„u3Àé«‹U‹E;‚”~3Àé–‹Mƒ¹€t‹U‹P‹MQè?àÿÿ…Àu3Àës‹UÇBt‹EŠˆˆˆMô€}ôt€}ôtë‹UÆ‚ˆë‹EøfPÿ,p5s3Àë0j‹MQ‹UR‹E P‹MQèøÿÿƒÄ‰Eü‹UøÂfRÿ,p5s‹Eü‹å]ÃU‹ìƒì$ƒ}tƒ}ÿu3ÀéÌ‹EŠˆˆˆMä€}ät€}ätë‹UÆ‚ˆë3À韋E‹‰Mð‹U ‰Uà‹Eàƒè‰Eàƒ}à‡È‹Màÿ$y75s‹U¿B…Àt ‹M¿Qƒúuhh'‹EðPèjþÿ3ÀéH锋M¿Qƒút ‹E¿H…Éuhi'‹UðRè9þÿ3Àé‹E¿Hƒùÿt‹U¿Bƒøþt‹M¿Q$ƒâ…Òtë@hi'‹EðPèüþÿ3ÀéÚ‹M¿Q…Òuhg'‹EðPèÜþÿ3Àéºë ë3À鯋Mƒ¹„t`‹UÇBt‹Eƒ¸€t‹MðQ‹URè[Þÿÿ…Àu3Àéujj‹EP‹M Q‹URèûöÿÿƒÄ‰Eø‹EðfPÿ,p5s‹EøéC‹MðQ‹URèÞÿÿ…Àu3Àé+‹Eð‹M‹J;Q`t ‹EðPèLXþÿ‹Mƒypu*ƒ} u$hf'‹UðRèþÿ‹EðfPÿ,p5s3ÀéÞ‹M¿Qƒút ‹E¿H…Éutƒ} u‹UƒzHuÇE ‹E P‹MQè¹ÿÿ‰Eøƒ}øujjj‹URè÷釃}øujjj‹EPèݸéhƒ} u ‹MÇApé>‹U‹Bp‰Eü‹M‹Q‰Uì‹E ‰EÜ‹M܃é‰M܃}܇ƋUÜÿ$•‘75s‹EÇ@p‹MƒyLt#j‹URè+™ÿÿ…Àujjj‹EPèXéèé‹M‹Qp‹EPt‰Uôƒ}ôuÇEô‹M¿Q$ƒâ…Òtn‹E‹Hp‹UJtáÿÿ‹E;HH~Thf'‹MðQè¬þÿÇEèë ‹UèƒÂ‰Uè‹E‹Mè;H}‹U‹B ‹MèLjëÚ‹UðÂfRÿ,p5s3ÀéK‹E‹Mô;HH†Žj‹URè\˜ÿÿ‰Eøƒ}øujjj‹EPè„éƒ}øþuT‹M‹Q ÇÇEèë ‹EèƒÀ‰Eè‹M‹Uè;Q}‹E‹H ‹UèÇ‘ëÚ‹EðfPÿ,p5s¸éº‹MÇApë‹Uôâÿÿ‹E‰Ppé8‹Mƒypu>‹UƒzLhf'‹EðPè•þÿëhb'‹MðQè…þÿ‹UðÂfRÿ,p5s3ÀéS‹E‹M‹Pp;Q~‹E‹M‹Pp+Q‹E‰Ppë ‹MÇApéÀ‹U‹E;BHƒ}%hf'‹MðQèþÿ‹UðÂfRÿ,p5s3Àéì‹E‹M‰Hpë‹U‹BpE‰Eôƒ}ôv ‹M‹Uô;QHv%hf'‹EðPèÑþÿ‹MðÁfQÿ,p5s3À韋U‹Eô‰Bpë2‹M‹U‹AH;B~‹M‹U‹AH+BƒÀ‰EôëÇEô‹M‹Uô‰Qp‹EìP‹MQ耯ÿÿ…Àu<‹U‹Eü‰Bpjj‹MðQèöñüÿƒÄ jjj‹URè”jj‹EðPè×ñüÿƒÄ 3Àë‹MðÁfQÿ,p5s¸‹å]ý25s½25s›25s25s25s225sW45s’45sÛ55sS65s”65sá65sÌÌÌÌÌÌÌU‹ìƒì@W‹E‹‰Müƒ}tN‹UR‹}ƒÉÿ3Àò®÷уÁÿQ‹}ƒÉÿ3Àò®÷уÁÿQj#jh0¤5s‹EüPèe×þÿƒÄ…Àu3Àéx¸énÇEÈë ‹MȃÁ‰MÈ‹U¿Bl9EÈG‹M‹QX‹EÈ‹ ‚‰Mð‹U‹B`‹MÈ‹ˆ‰Uì‹EÈkÀ ‹M‹QdЉUø‹Eü3Éf‹ˆ„ƒá@…Ét&ƒ}ì„ö‹Uðf‹B"fÁèf%%ÿÿ…À„ÚÆEÌ@‹Mð3ÒŠQREÍP‹MðQèYpþÿ‹Uð3ÀŠBÆD̓}ìu3Àé°‹Møƒyt‹Uø‹B‹M ‹ˆ‰Uôë ‹Eì‹H‰Mô‹Uø‹B‹M ‹ˆ‰Uă}ôt*‹Eì¿Hƒù t ‹Uì¿Bƒø u‹}ăÉÿ3Àò®÷уÁÿ‰Mô‹Mð‹Q&R‹Eð3ÉŠH$Q‹UüRèôwþÿ‰EÀ‹EÄP‹MôQjÿ‹UÀRjEÌP‹MüQèôÕþÿƒÄ…Àu3Àë é þÿÿ¸_‹å] ÌÌÌÌÌÌÌÌU‹ìƒìW‹E‹‰Mø‹U ‰Uð‹Eðƒè‰Eðƒ}ðw7‹Mðÿ$Ü;5sÇE ë+ÇE ë"ÇE ëÇE ëÇE ë3ÀéåjhH¤5s‹UøRè^ÒþÿƒÄ …Àu3ÀéÇ‹E€Pjÿjÿj8jhD£5s‹MøQè1ÕþÿƒÄ…Àu3ÀéšU Rjÿjÿj8jh@¤5s‹EøPè ÕþÿƒÄ…Àu3ÀérMQjÿjÿj8jh¤5s‹UøRèáÔþÿƒÄ…Àu3ÀéJƒ} „®ƒ} „¤ƒ}t‹E‰Eü‹}ƒÉÿ3Àò®÷уÁÿ‰MôëÇEü ¸5sÇEô‹MQ‹UôRjÿj/jh8¤5s‹EøPèuÔþÿƒÄ…Àu3ÀéÞƒ} tƒ} u@ƒ}u ÇEìë ‹Mƒé‰Mì‹UR‹EìP‹MQè‚üÿÿ…Àu‹UøRèEJýÿƒÄ3Àé’‹EøPè’ÚþÿƒÄ…Àu3Àë~ƒ} u7ƒ}ujjjj‹MQèêèÿÿƒÄë\jj‹UƒêRj‹EPèÏèÿÿƒÄëA‹MøQèñ+ýÿƒÄ…Àu3Àë-‹UøRèÐþÿƒÄ…Àt3Àë‹EøPè™òüÿƒÄ…Àu3Àë¸_‹å]þ95sÇ95sÐ95sÙ95sâ95sU‹ìƒìWÇEôÇEüƒ}tƒ}ÿu3Àé5‹E‹‰Mð‹UðR‹EPè#Õÿÿ…Àu3Àé‹Mƒ¹„„˃} u0ƒ}u*ƒ}u$h'‹UðRè( þÿ‹EðfPÿ,p5s3ÀéÏ‹MQ‹UR‹EP‹M Q‹URèùüÿÿƒÄ‰Eèƒ}èu*ƒ} tƒ} u‹EðƒxVuho'‹MðQèÊ þÿÇEèƒ}èu)ƒ} u#ƒ}t‹UR‹EP‹MQj‹URèšüÿÿƒÄ‰Eè‹EðfPÿ,p5s‹Eèé:‹Mð‹U‹J;B`t ‹MðQèƒNþÿ‹U‹E;Btƒ}|ƒ} t=ƒ} t7ƒ}u1ƒ} uƒ}t%h'‹MðQè& þÿ‹UðÂfRÿ,p5s3ÀéÌ‹E¿Hƒùu*ƒ} t$hj'‹UðRèï þÿ‹EðfPÿ,p5s3Àé–ƒ}t}‹M3ÒŠ…Òtrƒ} tƒ} uf‹}ƒÉÿ3Àò®÷уÁÿ‰Mìƒ}ìtNj‹EìƒÀP‹MðQjèÐiþÿ‰Eüƒ}üu‹UðÂfRÿ,p5s3Àé-‹EìP‹MüQ‹URèßjþÿ‹EüEìÆ‹M ‰Mä‹Uäƒê‰Uäƒ}䇣‹Eäÿ$…RA5s‹MüQ‹UR‹EPèÒ»ÿÿ‰Eøƒ}øuhk'‹MðQè þÿÇEôézƒ}t ‹U3ÀŠ…Àu&‹M¿Q&ƒúthk'‹EðPèÔþÿÇEôéC‹MüQ‹UøR‹EP‹MQèCÉÿÿ‰Eôé&j‹UR‹EPèL»ÿÿ‰Eøƒ}øuhk'‹MðQè…þÿÇEôéô‹UøR‹EP‹MQèXÍÿÿ‰EôéÛ‹UüR‹EP‹MQèÿºÿÿ‰Eøƒ}øu4ƒ}ütjh$¡5s‹UüRèàiÿÿ…Àuhk'‹EðPèþÿÇEôéƒ}t ‹M3ÒŠ…Òu ƒ}uh'‹EðPèíþÿÇEôé\‹MüQ‹UøR‹EP‹MQèlÎÿÿ‰Eôé?ƒ}t%‹U3ÀŠ…Àth'‹MðQè¥þÿÇEôéƒ}u‹U‹BtP‹MQ蓦ÿÿ‰Eôë@‹Uƒzpu ÇEôë.‹EƒèP‹M‹Qp‹ELþQ‹URèn¤ÿÿ‰Eôƒ}ôþuÇEôé´j‹EP‹MQèÚ¹ÿÿ‰Eøƒ}øuhk'‹UðRèþÿÇEô邃}t ‹Eƒxph'‹MðQèêþÿÇEôë\‹UøR‹E‹Hp‹UDþP‹MQèv·ÿÿ‰Eôƒ}ôu!‹UƒêR‹E‹Hp‹UDþP‹MQè¿£ÿÿ‰Eôëh'‹UðRèŒþÿÇEôƒ}ôujj‹EüP‹MQè¾ë&‹UðÂfRÿ,p5sƒ}üt‹EüP‹MðQè9gþÿƒÄ‹Eô_‹å]Ã]>5så>5s0?5sÌ?5sW@5sÌÌÌÌÌÌÌÌÌÌU‹ìƒì ÇEôÇEøƒ} t‹E ‹ˆ€‰MüëÇEüÿÿÿÿjhT¤5s‹URè±ÊþÿƒÄ …ÀuëhEüPjÿjÿj8jhD£5s‹MQèŽÍþÿƒÄ…ÀuëE‹URèüÓþÿƒÄ…Àuë3ÇEô‹EPè“%ýÿƒÄ…Àuë‹MQèQìüÿƒÄƒøtëÇEøƒ}ôt ‹URèQCýÿƒÄ‹Eø‹å]ÃÌÌÌÌÌÌÌU‹ìQ‹E‹‰Mü‹UüR‹EPè÷Îÿÿ…Àu3ÀëN‹Mƒ¹„t.ƒ} u(‹UR‹EüPèðþÿÿƒÄ…Àu‹MüÁfQÿ,p5s3Àëjjj‹URè6¸‹å]ÃÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒìÇEøƒ}tƒ}ÿu3Àé^‹EPè—iþÿ…Àuj‹MQèHÿÿÿƒÄé>‹U‰UðÇEì‹EðfPÿ0p5sfÇEüë f‹MüfƒÁf‰Müƒ}ìuY¿Uü‹Eð¿ˆ\;Ñ}G¿Uü‹Eð‹ˆ^‹‘‰Uôƒ}ôt,‹Eôƒ¸„t ÇEìj‹MðQèñýÿÿƒÄ…ÀuÇEøë•fÇEüë f‹UüfƒÂf‰Uü¿Eü‹Mð¿‘\;Â}6¿Eü‹Mð‹‘^‹‚‰Eôƒ}ôt‹MìQ‹UôRèeþÿÿƒÄ…ÀuÇEøë¬ƒ}øu;‹Eðƒ¸^t/‹Mð‹‘^R‹EðPèpdþÿƒÄ‹MðÇ^‹UðfÇ‚\‹EðfPÿ,p5s‹Eø‹å]ÃÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì0‹E‹‰Mð‹U‹B(‰EÐÇEè‹MðQè AýÿƒÄÇEÜë ‹U܃‰UÜ‹E¿H&9MÜ‹UЋ‰Eì‹M Æ‹U ‰UÔ‹EЋH‹UìD ÿ‰Eü‹Mü;Mìv‹Uü3ÀŠƒø.t ‹Müƒé‰Müëá‹Uü3ÀŠƒø.u(ë‹MìƒÁ‰Mì‹Uԃ‰UÔ‹Eì;Eüw ‹MÔ‹U슈ëÚj ‹MÔQhl£5sèícþÿ‹UЋP‹M Qhx£5s‹UðRèÄþÿƒÄ…Àt ‹EðPèõ!ýÿƒÄ…Àt‹MðQèéüÿƒÄ…Àu3ÀéRUäRj‹EèPj‹MðQ袂þÿƒÄUøRj‹EèPj‹MðQ节þÿƒÄUàRj‹EèPj‹MðQèr‚þÿƒÄÇEØÇEô‹UðRèÈóüÿƒÄƒøþ„¤ƒ}Ø…‰‹Eøƒà…Àtjj‹MèQj‹UðRè%‚þÿƒÄjj‹EèPj‹MðQè‚þÿƒÄjj‹UèRj‹EðPèùþÿƒÄ‹MðQè]óüÿƒÄƒøþtëíUØR‹EàP‹MäQ‹U܃ÂR‹EÐP‹MQès…Àu3ÀëVë ƒ}ôu‹Uä‰UôéGÿÿÿ‹EðPèßçüÿƒÄƒøu‹MðQèþòüÿƒÄƒøþtëíëÚƒ}Øu3Àë‹UЋB‰EÐéÍýÿÿ¸‹å]ÂÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì‹E‹‰Mô‹UƒÂ8‰Uð‹Eðƒ8t ‹Mð‹ƒÂ‰UðëëÇEèë ‹EèƒÀ‰Eè‹Mè;M‡¨‹UèR‹EP‹M ‹Rhà£5s‹EôPè ÂþÿƒÄ…Àt0‹MôQèúýÿƒÄ…Àt ‹UôRè çüÿƒÄ…Àt‹EôPè*òüÿƒÄ…Àu3ÀéS‹Mô‹QD‰Uü‹Eü‹‹‰Uìƒ}ìt ‹Eǃ}ìu‹MôQèëñüÿƒÄƒøþtëíéQÿÿÿjj‹UôRjè `þÿ‰Eäƒ}äu3Àéô‹Eð‹M䉋UäƒÂ‰Uðj‹E ‹H‹UìD P‹MôQjèÑ_þÿ‰Eøƒ}øu3À鸋Uä‹Eø‰‹M ‹QR‹EøP‹M ‹Rèã`þÿ‹E ‹H‹UøD ÿ‰Eø‹MøÆ.‹UøƒÂ‰Uø‹EìP‹MøQ‹Uü‹‹HQè®`þÿ‹UøUì‰Uø‹EøÆ‹M ‹Q‹EìL‹Uäf‰J‹Eäf‹Mf‰H‹UäfÇB‹E‹H4ƒÁ‹U‰J4‹EôPèßðüÿƒÄƒøþt3Àë éCþÿÿ¸‹å]ÂÌÌÌU‹ìì‹EPèŽdþÿ…Àuh{'‹MQèœþýÿ3ÀéÙ‹U3Àf‹‚„ƒà@…Àu5‹M3ÒŠ‘ ƒú}%‹E3ÉŠˆŸƒù}h{'‹URèTþýÿ3Àé‘‹E‹H3Òf‹Q…Òu…øþÿÿPjÿ‹M‹Q R‹E‹HÿQ8ƒÄ ‹UƒºÊ…¢…ìþÿÿPüþÿÿQè!ƒÄ…Àuh{'‹URèéýýÿ3Àé&‹E‹H‹Q‰•ðþÿÿ‹…ðþÿÿÆ‹ðþÿÿÆA‹•ðþÿÿÆB‹E‹HfÇAh•üþÿÿR‹EPè•ýÿ…Àuh{'‹MQèƒýýÿ3ÀéÀ‹URè“‘ýÿ…Àuh{'‹EPèaýýÿ3Àéž‹MQèIþÿ‹UÆB‹EfÇ€B‹MÇA‹UÆB‹EÇ@‹MÇR‹UÇ‚F‹EPèýÿƒÄ…Àuh{'‹MQèëüýÿ3Àé(‹URè«ãüÿƒÄ…Àuh{'‹EPèÆüýÿ3Àé‹MQè¶îüÿƒÄƒøÿu*j‹URè“þÿƒÄ‰…ôþÿÿj‹EPè/ þÿƒÄ‰…èþÿÿëh{'‹MQèvüýÿ3À鳃} tnfÇ…þþÿÿ•ìþÿÿR‹E PüþÿÿQ‹UÂÊR‹…èþÿÿP‹ôþÿÿQèaƒÄ…Àu!‹URèA9ýÿƒÄh{'‹EPèüýÿ3ÀéM‹MQè 9ýÿƒÄëfÇ…üþÿÿfÇ…þþÿÿ‹U‹B‹H‰ðþÿÿ‹•ðþÿÿÆ‹…ðþÿÿÆ@‹ðþÿÿÆA‹U‹BfÇ@‹þþÿÿáÿÿƒÁQ•üþÿÿR‹EP葎ýÿ…Àuh{'‹MQèûýÿ3À鼋URèýÿ…Àuh{'‹EPè]ûýÿ3Àéš‹MQèýFþÿ‹UÆB‹EfÇ€B‹MÇA‹UÆB‹EÇ@‹MÇR‹UÇ‚F‹EPèüýÿƒÄ…Àuh{'‹MQèçúýÿ3Àë'‹URèªáüÿƒÄ…Àuh{'‹EPèÅúýÿ3À븋å]ÃÌÌÌÌÌÌÌÌU‹ìƒì ÇEôÇEøÇEü‹EPèl`þÿ…Àuh{'‹MQèzúýÿ3Àë~ƒ} u'j‹URè¥ûÿÿƒÄ‰Eüƒ}üuh{'‹EPèKúýÿëNMôQUøR‹EÎPèCƒÄ …Àuh{'‹MQèúýÿ3Àë"‹UøR‹EPèMûÿÿƒÄ‰Eü‹MøQè ƒÄ‹Eü‹å]ÃÌÌÌÌU‹ìƒìW‹}ƒÉÿ3Àò®÷уÁÿ‰MüÇEøë ‹EøƒÀ‰Eø‹Mø;M s+‹Uø;Uüs#‹EEøŠQÿDp5s%ÿ…Àt ‹UøƒÂ‰UøëÄ‹Eø9E À÷Ø_‹å]ÃÌÌÌU‹ìƒì$W‹}ƒÉÿ3Àò®÷уÁÿ‰Mø‹} ƒÉÿ3Àò®÷уÁÿ‰Mô‹Eø;Eôs3ÀéM‹Mø;Môuh‹U ‰Uì‹E‰Eè‹M芈Uç‹Eì:u.€}çt‹MèŠQˆUæ‹Eì:PuƒEèƒEì€}æuÌÇEàëɃÙÿ‰Mà‹Uà‰UÜ‹EÜ÷ØÀ÷Ð#EéÝ‹Eø+Eô‰EüÇEðë‹MƒÁ‰M‹UðƒÂ‰Uð‹Eð;Eüƒ«ë‹MƒÁ‰M‹UðƒÂ‰Uð‹E¾‹U ¾;Èt1‹Mð;Müs)‹UŠPÿDp5s%ÿ…Àt‹MƒÁ‰M‹UðƒÂ‰Uðë­‹Eð;Eüv3ÀëL‹MôQ‹U R‹EPÿ q5sƒÄ …Àu‹Eë.‹MŠRÿDp5s%ÿ…Àt‹EƒÀ‰E‹MðƒÁ‰Mðé7ÿÿÿ3À_‹å]ÃÌÌÌÌU‹ìƒìW‹}ƒÉÿ3Àò®÷уÁÿ‰Mø‹E‰Eü‹Mü¾…Òtaƒ}øv[‹EüŠQÿDp5s%ÿ…Àt‹UüƒÂ‰Uü‹EüƒÀ‰Eü‹Møƒé‰Møë'‹Uü¾Pÿq5sƒÄ‹Müˆ‹UüƒÂ‰Uü‹Eøƒè‰Eøë•‹E_‹å]ÃÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì‹EfPÿ0p5sÇEüë ‹MüƒÁ‰Mü‹U¿‚\9Eü})‹M‹‘^‹Eü‹ ‚‰Møƒ}øtjjj‹UøRèCë¿‹E‹ˆ^Q‹URèÎWþÿƒÄ‹EÇ€^‹MÁfQÿ,p5s‹å]ÂÌÌÌÌÌÌÌÌU‹ìƒì$‹E‹‰Mü‹UƒzPt‹E‹HPQ‹UüRèyWþÿƒÄ‹EÇ@Pƒ} t‹M Q‹UüRèYWþÿƒÄƒ}u1ƒ}üt+‹EüPèq<þÿ‹MüÇJ‹Uüƒzu ‹EüPèR3ýÿƒÄƒ}…œ‹Mƒy t5ƒ}u/ÇEèë ‹UèƒÂ‰Uè‹E‹Mè;H}‹U‹B ‹MèLjëÚ‹U¿Bƒøt ‹M¿Q…Òu ‹EÇ@H‹Mƒy<t4ÇEèë ‹UèƒÂ‰Uè‹E‹Mè;H}j‹UèR‹EPèaŠÿÿ…ÀuëëÕ‹Mƒá…Éu ‹URè¶‹Eƒà…À„è‹Mƒyt‹U‹BP‹MüQè?VþÿƒÄ‹Uƒzt‹E‹HQ‹UüRè#VþÿƒÄ‹Eƒxt‹M‹QR‹EüPèVþÿƒÄ‹Mƒyt‹U‹BP‹MüQèëUþÿƒÄ‹Uƒz t‹E‹H Q‹UüRèÏUþÿƒÄ‹Eƒ¸„tWÇEàë ‹MàƒÁ‰Mà‹U¿B&9Eà}‹M‹Q(‹Eà‹ ‚Q‹UüRèŒUþÿƒÄëЋEƒx(t‹M‹Q(R‹EüPènUþÿƒÄëJ‹M‹Q(‰Uìƒ}ìt;‹Eìƒ8t‹Mì‹R‹EüPèCUþÿƒÄ‹Mì‰Mð‹Uì‹B‰Eì‹MðQ‹UüRè$UþÿƒÄë¿‹Eƒx0tLÇEèë ‹MèƒÁ‰Mè‹U¿B,9Eè}‹M‹Q0‹Eè‹ ‚Q‹UüRèâTþÿƒÄëЋE‹H0Q‹UüRèÍTþÿƒÄƒ}ü„PÇEøÇEä‹Eü‹M‹P$;QXt‹Eü‹H$‰Mø‹Uü¿B"‰Eä‹Mƒ¹„t‹U¿BlƒÀ‰EÜë ‹M¿Ql‰UÜ‹Eüf‹MÜf‰ˆD‹Uü‹Eüf‹ˆDf‰J"‹Uü‹E‹H`‰ŠJ‹Uü‹E‹HX‰J$‹Uü‹E‹Hh‰JD‹Uƒº„t‹Eüf‹ˆDfƒé‹Uüf‰ŠD‹EüPè)7þÿ‹Mƒ¹„t‹Uüf‹‚Df‹Müf‰Dj‹UüRèŠ7þÿ‹EüPè‘9þÿ‹Mƒy\t‹U‹B\P‹MüQè¨SþÿƒÄ‹URèü‹EPèÓƒ}øt‹Mü‹Uø‰Q$‹Eüf‹Mäf‰H"‹UüRè@9þÿ‹Eƒà…Àtn‹Mƒ9tf‹Uü¿‚\…ÀtX‹Mü‹‘^‰UôÇEèë ‹EèƒÀ‰Eè‹Mü¿‘\9Uè}+‹Eü‹ˆ^‹Uè‹‘;Eu‹Mü‹‘^‹EèÇ‚ë뽋Mƒá…Ét‹UR‹EüPèáRþÿƒÄƒ}t‹MüÁfQÿ,p5s‹E‹å]ÂÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì ‹E‹‰Mø‹U‹B\‰Eüj‹MøQèN6þÿƒ}üuéÝ‹Uø‹B$‰Eð‹Mø‹‘J‰Uô‹Eø‹HD‰Mà‹Uø¿B"‰Eì‹MøÇJ‹Uø‹E‹HX‰J$‹Uø‹Ef‹Hlf‰J"‹Uƒº„t‹Eøf‹H"fƒÁ‹Uøf‰J"ÇEèë ‹EèƒÀ‰Eè‹M‹Uè;Q­‹Eø‹Mè‹Uü‹ ЉHD‹UøƒzD„Œ‹E¿Hl‹U¿BV;È}z‹M¿Ql‰Uäë ‹EäƒÀ‰Eä‹M¿QV9Uä}Y‹Eø‹HD‹Uä‹‘ƒxt‹Mø‹QD‹Eä‹ ‚‹QR‹EøPè{QþÿƒÄ‹Mø‹QD‹Eä‹ ‚Q‹UøRèbQþÿƒÄ‹Eø‹HD‹UäÇ‘ë’é;ÿÿÿÇEèë ‹EèƒÀ‰Eè‹M‹Uè;Q}\‹Eø‹Mè‹Uü‹ ЉHD‹Uè‹Eü‹ ;MàuÇEìÇEàÇEðÇEô‹Uè‹EüÇ‹MøƒyDt j‹UøRè‘4þÿë‹Eø‹Mð‰H$‹Uø‹Eà‰BD‹Mø‹Uô‰‘J‹Eøf‹Mìf‰H"‹å]ÂU‹ìƒì‹EƒxdtdÇEøë ‹MøƒÁ‰Mø‹U¿Bl9Eø}1‹MøkÉ ‹U‹BdÁ‰Eü‹Müƒyt‹Uü‹BP‹M‹RèGPþÿƒÄ뺋E‹HdQ‹U‹Pè0PþÿƒÄ‹å]ÂÌÌÌÌÌÌÌU‹ìQ‹E ƒ8t‹M ‹R‹EPèPþÿƒÄ‹M ƒyt‹U ‹BP‹MQèéOþÿƒÄ‹U ‹B‰Eü‹M Q‹URèÐOþÿƒÄ‹Eü‹å]ÂÌÌÌÌU‹ìƒì ‹E‹H8‰Mü‹U‹B<‰Eøƒ}üt‹MüQ‹U‹Pèsÿÿÿ‰Eüëæƒ}øtF‹Mø‹Q‰Uüƒ}üt‹EüP‹M‹RèJÿÿÿ‰Eüëæ‹Eø‰Eô‹Mø‹Q‰Uø‹EôP‹M‹RèGOþÿƒÄë´‹å]ÂÌÌÌÌÌÌÌÌÌÌÌÌU‹ìƒì0SVW‹Eƒ8Hs3ÀéDjMÐQ‹U‹BPÿq5sƒÄ ‹ x¤5s‰MÜ‹|¤5s‰Uàf¡€¤5sf‰Eä}ÐU܃Éÿ3Àò®÷Ñ+ù‹÷‹Ù‹úƒÉÿ3Àò®ƒÇÿ‹ËÁéó¥‹Ëƒáó¤EÜPh<jjjjÿÿxp5s‰Eüƒ}üu3Àé¼jjjj‹MüQÿtp5s£h¸5sƒ=h¸5su3Àé•‹h¸5s‹E‹H‰ ‹h¸5s‹E‹HD‰Jj ‹UƒÂ R¡h¸5sƒÀPÿq5sƒÄ j‹MƒÁ4Q‹h¸5sƒÂ(Rÿq5sƒÄ ¡h¸5s‹M‹Q0‰P8‹E‹H0Q‹U‹B,P‹ h¸5sƒÁ‹L$;t‹Æ‹v…öuóh˜¸5sÿ,p5s3À…ö•À^ËNV‰H‹D$‹V‰ÿ`q5sƒÄh˜¸5sÿ,p5s3À…ö•À^Ãh˜¸5sÿ p5sÃh˜¸5sÿXp5sËD$fÇfÇ@¸ÃìS‹\$VW‹‹|$(…Àt ‰D$ éÈ‹L$(Qhs5sWÿ…À}‹T$,P‰ÿØp5s_^3À[ƒÄËD$(T$Rh¨r5s‹PÿQ …À} ‹L$,P‰ÿØp5s‹D$(P‹ÿR_^3À[ƒÄËD$T$ R‹T$‹R‹T$$RPÿQ‹ð…ö}*VÿØp5s‹D$(P‹ÿQ‹D$P‹ÿR‹D$,_‰0^3À[ƒÄËL$ ‹D$‰ P‹ÿR‹D$(P‹ÿQ‹D$ ‹L$ QWPÿR …À}‹T$,P‰ÿØp5s_^3À[ƒÄËD$ Pÿ\q5s‹ØƒÄ…Ûuh'ÿØp5s‹L$,_^3ÀÇ'[ƒÄËD$ L$ Q‹L$$‹SQWPÿR…À} ‹T$,P‰ÿØp5sSÿ`q5sƒÄ3À_^[ƒÄË|$$‹L$ 3Àf‹G;Ásh¶h¸5shØ·5sÿdq5s‹L$,ƒÄ f‰O‹ÑfÇ‹óƒÇSÁéó¥‹Êƒáó¤ÿ`q5sƒÄ¸_^[ƒÄÃU‹ìƒìfÇEü‹Eƒ8ucƒ=´¸5su è3£´¸5sƒ=´¸5sufÇEüë|‹MQjjjh8s5sjjÿ´¸5sƒÄ‰Eøƒ}ø}‹U‹Eø‰‹MøQÿØp5sfÇEüë;‹U R‹E‹‹U‹‹QÿR ‰Eøƒ}ø}‹E‹Mø‰‹UøRÿØp5sfÇEü¿Eüëëøëö‹å]ÃÌÌÌÌÌÌ‹D$…Àt‹PÿQ‹D$…Àt‹PÿR¸ÃV‹t$‹…Àt ‹PÿQÇ^ËD$…Àt‹PÿQÃÿ%lq5sÌÌÌÌÌÌÌÌÌÌXOLEHLP.DLLDtcGetTransactionManagerVhÐm5sÿhp5s‹ð…öthÜm5sVÿ¸p5s…Àu Vÿ4p5s3À^Ã2xFxxx"xðw®z°uÜuêuúuv*v¤uÌubvvvˆvšv¬v´vru8vHv˜uúv ww$w4wJwXwfwxw„ww¢w¶wÌwŠuÀvÎvÚv:zduèvZu(zJz^ztzŽzLužzÊxÒxÚxâxÂxìxøxy yyy®x¸x\yfypyzy†yŽy˜y y¨ydx¤xŠx~xtxlx2yJyšxÚzÒzÈzzÀyÎyÜyêyøyo990ˆÃ@ðA@F-Cëâ6A-Cëâ6 ?-Cëâ6 CàÀàÿß@€ÇÿÿF€Cðo@ àÀÀÿß@à¿ào@à?àÁàÿÿÿßA­ßŒÇ3ùïGü U&öøïÇÿÿÿÿjr4sðqéiÎ#Ï­`ª§LÍP±A¯Î½+ LOOP S›ÏáE‡Î©ºªl7¤ýAÀν LOOP ¥ýAÀν LOOP Z›ÏáE‡Î©ºªl7 të‡Î€€ÇXR~!të‡Î€€ÇXR~пǀî‡Î€€ÇXR~pÃ<Âï‡Î€€ÇXR~1V ûÞήѪQâÄ1ñ±óÚîήԪQâÄàsâw pÀsVxp t´yàp4uztq,uzlq2xFxxx"xðw®z°uÜuêuúuv*v¤uÌubvvvˆvšv¬v´vru8vHv˜uúv ww$w4wJwXwfwxw„ww¢w¶wÌwŠuÀvÎvÚv:zduèvZu(zJz^ztzŽzLužzÊxÒxÚxâxÂxìxøxy yyy®x¸x\yfypyzy†yŽy˜y y¨ydx¤xŠx~xtxlx2yJyšxÚzÒzÈzzÀyÎyÜyêyøyHeapDestroy£TlsFree¤TlsGetValueUDeleteCriticalSection¥TlsSetValue™HeapAlloc¢TlsAllocªInitializeCriticalSectionGetLastError›HeapCreateuGetVersionExAÁLeaveCriticalSectionfEnterCriticalSection´FreeLibraryÚGetConsoleCP GetEnvironmentVariableAÎGetComputerNameA¹IsDBCSLeadByteGetLocaleInfoAGetLocaleInfoW–Sleep†GlobalFix’GlobalUnfixŸHeapFree¢HeapReAlloc>GetProcAddressÂLoadLibraryAùlstrcatAGetFileSizeÖMapViewOfFile5CreateFileMappingA4CreateFileACloseHandle°UnmapViewOfFileReadFileßWriteFilejSetFilePointeréOpenFileMappingAøGetCurrentProcessIdúGetCurrentThreadIdKERNEL32.dll†RegSetValueExA[RegCloseKey_RegCreateKeyExArRegOpenKeyExA{RegQueryValueExAjRegEnumValueAADVAPI32.dll›modfñ_ftolŽ_pctype_isctypea__mb_cur_max²sprintfÁstrncpyÀstrncmp˜memmoveÐtime=atoi>atol<atof¿strncatÜvsprintfOfflush_iob putcharÈ_errnoÊ_except_handler3_abnormal_termination<_local_unwind2•memchrÓtolowerÙ_ultoaÁ_stricmp4_itoa_getpidô_gcvtF_ltoaÅ_strnicmpMSVCRT.dll«LoadStringAÎOemToCharA+CharToOemA.CharToOemW¬wsprintfAUSER32.dllÓNetbiosNETAPI32.dll\DeviceIoControlvGetVersionExWGetDiskFreeSpaceAGlobalMemoryStatusQueryPerformanceCounterdSetErrorModeqSetLastErrorAllocateLocallyUniqueId _assert^free‘malloc9 ©¦{¼}T€ÀW XÖY°V°YðV È@Y€…°„0ò`Ey`€@e/[@RpRà[ R0ß°,ð,0-€S0Tp,p*pv@ „p- l lÀz ñ0ï@w`,wP/€°-à£ð,€.~P,ò9°XÐTðYð-QðTí`dt°ø`.0.Ð.pò`tÀ†°ïàáð{0t@gg rÐypy°\]€[]à^^@_m m@npoð£ÀÐã/þ@r€45@7à9`:Ð:`;0<0= >€@PAàB )°$$ (P$p)ð% *S òÐe0SP  °  p Ð ð ` `à #P#`Wú@UÌ ÙÐ 1ð;ÀB C°HðòÐò0žÀà "÷0óÀ÷€ø€Q0à)À+°'@ÐvÐHàLPY­¶ÁÒÜåðû‚‚‚'‚0‚9‚F‚R‚^‚g‚t‚†‚“‚Ÿ‚§‚¯‚¹‚Ă͂Ղ߂ê‚ö‚ý‚ƒ ƒƒ!ƒ*ƒ2ƒ;ƒDƒJƒSƒ_ƒiƒrƒ|ƒ‡ƒ“ƒƒ¨ƒ¹ƒÃ˃Ôƒ݃æƒóƒ„„„/„<„K„X„_„k„w„€„‡„•„¥„±„¸„¿„ʄԄà„ë„õ„… ……!…+…9…F…M…W…a…i…s…}…………›…§…®…¸…Ã…Í…×…ä…ð…ú…† ††%†0†@†H†Q†X†c†n†x†‚†‹†•†¡†«†²†¼†ƆІÛ†å†î†÷†‡‡‡)‡6‡D‡N‡W‡a‡o‡y‡‡‹‡”‡‡©‡´‡¾‡ʇÕ‡à‡è‡ð‡þ‡ ˆˆ!ˆ.ˆ4ˆ>ˆLˆVˆbˆnˆzˆ†ˆ‘ˆ¨m•`abcdefghij‘kl’nop†Šx Ÿvyš—Ž –¤Œ>‡¦§! "#$%&ž'(“z)*w+,-./0123‰4567{89˜¡£¢™<=?‹@|}~€ABœ‚ƒ„…›CEDFGHI”JKLMNOPQRSTUVWXYZ¥[ˆ\]^_qrstntwdblib.dllSQLDebugabort_xactbcpDefaultPrefixbcp_batchbcp_bindbcp_colfmtbcp_collenbcp_colptrbcp_columnsbcp_controlbcp_donebcp_execbcp_initbcp_moretextbcp_readfmtbcp_sendrowbcp_setlbcp_writefmtbuild_xact_stringclose_commitcommit_xactdbadatadbadlendbaltbinddbaltcoliddbaltlendbaltopdbalttypedbaltutypedbanullbinddbbcmddbbinddbbylistdbcanceldbcanquerydbchangedbclosedbclrbufdbclroptdbcmddbcmdrowdbcolbrowsedbcolinfodbcollendbcolnamedbcolntypedbcolsourcedbcoltypedbcolutypedbconnectionreaddbconvertdbcountdbcurcmddbcurrowdbcursordbcursorbinddbcursorclosedbcursorcolinfodbcursorfetchdbcursorfetchexdbcursorinfodbcursorinfoexdbcursoropendbdatadbdatareadydbdatecrackdbdatlendbdeaddbenlisttransdbenlistxatransdberrhandledbexitdbfcmddbfirstrowdbfreebufdbfreelogindbfreequaldbgetchardbgetmaxprocsdbgetoffdbgetpacketdbgetrowdbgettimedbgetuserdatadbhasretstatdbinitdbisavaildbiscountdbisoptdblastrowdblocklibdblogindbmorecmdsdbmoretextdbmsghandledbnamedbnextrowdbnullbinddbnumaltsdbnumcolsdbnumcomputedbnumordersdbnumretsdbopendbordercoldbprheaddbprocerrhandledbprocinfodbprocmsghandledbprrowdbprtypedbqualdbreadpagedbreadtextdbresultsdbretdatadbretlendbretnamedbretstatusdbrettypedbrowsdbrowtypedbrpcexecdbrpcinitdbrpcparamdbrpcsenddbrpwclrdbrpwsetdbserverenumdbsetavaildbsetlnamedbsetlogintimedbsetlpacketdbsetmaxprocsdbsetnulldbsetoptdbsettimedbsetuserdatadbsqlexecdbsqlokdbsqlsenddbstrcpydbstrlendbtabbrowsedbtabcountdbtabnamedbtabsourcedbtsnewlendbtsnewvaldbtsputdbtxptrdbtxtimestampdbtxtsnewvaldbtxtsputdbunlocklibdbupdatetextdbusedbvarylendbwillconvertdbwinexitdbwritepagedbwritetextopen_commitremove_xactstart_xactstat_xactDATE0_ONMNY_PREFIXMFMT_SHORTCENT_Y2TIME_12DATE_MDYDATE_DMY0123456789.%23.15f000d5bf8d50-451e-11d1-968d-e4b783000000cp125iso_1charsetSQL Server for Windows NT 4.20BackupServerSOFTWARE\Microsoft\MSSQLServer\Client\BackupServer@pFallbackSvrNamesp_fallback_MS_sel_fb_svr4096DBMSRPCNDBNMPNTWSYBUSER\DB-Library version 8.00.194timeoffonONUseIntlSettingsSOFTWARE\Microsoft\MSSQLServer\Client\DB-LibUseClientCursorsDataReadySleep,’5s0123456789abcdef000.00{ts '%04i-%02i-%02i %02i:%02i:%02i'}{ts '%04i-%02i-%02i %02i:%02i:%02i.%03i'}0x.0%23.15g'èd MSDBLIB`›5sX›5s;Zx—µÔó0NnJanFebMarAprMayJunJulAugSepOctNovDec010203040506070809101112JT›5sX5s ’5s    L›5sD›5s<›5s4›5s,›5s ›5s›5s ›5s›5s ¸5s üš5sðš5s äš5sØš5sÌš5sÀš5s´š5s ¸5s ¬š5s ¤š5s ˜š5s Œš5s „š5s ¸5s ¸5s ¸5spš5s ¸5shš5s\š5sXš5sPš5sHš5s<š5s8š5s0š5s(š5s š5sš5s š5sš5sø™5sè™5sÜ™5sЙ5sÌ™5sÈ™5sÀ™5s¼™5s¸™5s¨™5sœ™5s”™5sŒ™5s„™5s|™5st™5sl™5sd™5s\™5sP™5sD™5s8™5s,™5s ™5s™5s™5sü˜5sð˜5sä˜5sؘ5sȘ5s°˜5sœ˜5s€˜5sl˜5sT˜5sD˜5s4˜5s ˜5s ˜5sü—5sè—5sØ—5sÈ—5s°—5s ¸5s —5s˜—5s<DSQUERYConnectionErrorConnectionCheckForDataConnectionCloseConnectionOpenConnectionStatusConnectionModeConnectionWriteOOBConnectionTransactConnectionWriteConnectionReadConnectionObjectSizeSqlLocalizationFileselect @@microsoftversionselect @@versionexec sp_server_info 18AutoAnsiToOemSQLDECIMALSQLNUMERICSQLDATETIM4SQLDATETIMESQLVARYBINSQLVARYCHARSQLSMALLINTSQLTINYINTSQLMONEY4SQLBINARYSQLMONEYSQLFLT4SQLFLT8SQLCHARSQLINTSQLBITdecimalnumericrealsmallmoneysmalldatetimemaxmincountavgsumfloat-nullmoney-nulldatetime-nullint-nullimagevarbinarybinarytextvarcharcharbitdatetimefloatmoneyintsmallinttinyintquoted_identifierprocidshowplanparseonlynoexecnocountarithignorearithaborttextsizetextlimitstatisticsrowcountoffsetsparamexecuteprocedurestatementcomputeordertablefromselect$ off on ÿÿÿÿ ts, 0x tsequal( and)'NULL = ( and (where txts" with log timestamp = 0x NULL 0xwritetext bulk bulk updatetext set io100ConnectionServerEnum.DLLSOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo51265535, readpage, dbcc dbrepair (%d, %d, writepage, use € - CommitXACT_NAME:, EXECUTE sp_start_xact EXECUTE sp_commit_xact %ldEXECUTE sp_abort_xact EXECUTE sp_remove_xact EXECUTE sp_stat_xact bv:DBMSVINNnp:tcp:DBMSSOCNadsp:DBMSADSNspx:DBMSSPXNDBNETLIBÌ5sH¸5s select * from %s @# : #@ select minlen, maxlen from sysindexes where id = object_id('%s') and indid < 2 select count(id) from syscolumns where id = object_id('%s') select count(id) from syscolumns where id = object_id('%s') and type in (%d, %d) select name, length, offset, colid, type, status, cdefault from syscolumns where id = object_id('%s') select name, length, offset, colid, type, status, cdefault, prec, scale from syscolumns where id = object_id('%s') select x = convert(%s, getdefault('%s', %ld)) insert bulk %s DATETIMVARYCHARSMALLINTNUMERICDECIMALVARYBINTINYINTMONEY4BINARYIMAGEMONEYTEXTFLTCHARø¢5sð¢5sä¢5sÜ¢5sÌ™5sÈ™5sÀ™5s¼™5s¸™5sselect where from group by order by having desc insert into valuesupdate set wheredelete select db_name()sp_tables @table_name = '%s' , @table_owner = '%s' , @table_qualifier = '%s' sp_indexes @table_name = '%s' sp_special_columns @table_name = '%s' VIEWselect timestamp from %s where 0 = 1 timestampwhere 0 = 1 select * from %s where 0 = 1 > >= < <= tsequal( NULL is NULL is not NULL and HOLDLOCK OR union for browse into compute * and ( ) and ( @rows@ccopt@scrollopt@stmt@cursorsp_cursoropen or and (sysindexesselect indid, status, keycnt from %s where indid >= 1 and id = OBJECT_ID('%s') order by indid, keycnt select INDEX_COL('%s', %d, %d) @nrows@rownumber@fetchtypesp_cursorfetch@VALUES@table@optypesp_cursorsp_cursorcloseœ‘5s ‘5sp¤5scontextDBSSDebugsp_sdidebugncharvarbinaryvarcharbinarycharsql_variantntextbitdecimalnumericfloatmoneydatetimeimagetextuniqueidentifiervarbinaryintvarcharsmallmoneybinarychartinyintbigintbitsmallintdecimalintsmalldatetimerealmoneydatetimefloatnumericnvarcharÿÿTUUUUUTUUUUUð„UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUAU UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTUUUUUUUUUUUUUUUUUTUUUUUVUUUÿÿUUUUUUUUUUUUUUUUUUUUUUUUUTUTUÿÿ”UUUUUUUUUUUUU¤VU©UUUðÿÿ¤UUUUUUUUUUUUU V•–€UUUðÿÿPUUUUUUUUUUUUU VUUTðÿÿUUUU•UUUUUUUUUUUUU¤VU™ðÿÿ¤UUUUUUUUUUUUUdV•–UUðÿÿUUUUUUUUUUUUUU¥i¥¦€Àÿÿ¨UUUUUUUUUUUUUUU©VUTUUðÿÿ UUUUUUUUUUUUUUeª–¦hUUðÿÿ UUUUUUUUUUUUUU¥V¥¦€UUðÿÿTUUUUUUUUUUUUUeÿÿTUUUUUUUUUUUUUUU!ÿÿÿÿUUUUUUUUUUUUUUU•UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUPUUUUUUUUPUUª * ªÿ@ÿÿ@PUUUQEEUUUUUUUUUHTU¨ TUUUUUUUUUUUUUUUUUUUU€*TUUUUUUUUUUUUUUUUUUUUU*TUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU@UUQUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUÿÿTUUUUU@TUUUUUPUUVUUUUUUUUUU¥UUUUUUUUUUUUUUUýüü ýýýýýýýýýýýýýýüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýüüüüüüüüüüüüýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýýüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüüýý·5s ·5sø¶5sNetworkAddressLocalNetworkAddressSoftware\Description\Microsoft\Rpc\UuidTemporaryData\\.\NWLINKc:\ÿÿÿÿCount../src/sqlsspi.cnegotiateNTLMInitSecurityInterfaceAsecurity.dllsecur32.dllpEvent->length >= propagationStringLength../src/dtccomn.cpp €ø€€(€@€LX€Rp€Sˆ€X €Y¸€ZЀ[è€\€]€^0€_H€``€ax€r€s¨€tÀ€uØ€vð€w€x €°8€±P€h€ €    ° À Ð à ð     0 @ P ` p €    ° À Ð à ð  ÐÉØĘ̂Ëæ¨hL`$ˆ0¸<ø40Fx$ "È$ð$2P2ÌÐ`Ò¾ ÙVxß\ØçÔ˜ö °îâ¨ÿpŽ Å®®4VS_VERSION_INFO½ïþPÐÂ^?DVarFileInfo$Translation äStringFileInfoê040904E42 PlatformNT INTEL X86LCompanyNameMicrosoft Corporation\FileDescriptionSQL Server Client LibraryBFileVersion2000.080.0194.00 InternalName†1LegalCopyright© 1988-2000 Microsoft Corp. All rights reserved.sLegalTrademarksMicrosoft® is a registered trademark of Microsoft Corporation. Windows(TM) is a trademark of Microsoft CorporationB OriginalFilenameNTWDBLIB.DLLJProductNameMicrosoft SQL Server6 ProductVersion8.00.1942 CommentsNT INTEL X86Error 0No such file or directoryArg list too longExec format errorBad file numberNot enough corePermission denied File existsCross-device linkInvalid argumentToo many open filesNo space left on device Math argumentResult too largeResource deadlock would occur Unknown errorThis error number is unused.%Unable to allocate sufficient memory.#NULL DBPROCESS pointer encountered."NULL Loginrec Pointer encountered.Login incorrect.?Unable to connect: SQL Server is unavailable or does not exist.!DBPROCESS is dead or not enabled.$Attempt to login with NULL LOGINREC.=General SQL Server error: Check messages from the SQL Server.UPossible network error: Bad token from SQL Server: Datastream processing out of sync.%General non-specific DB-Library error4Possible network error: Read from SQL Server failed.Column number out of range.4Attempt to call dbtsput() with an invalid timestamp.3Invalid parameter in DB-LIBRARY function reference.HAttempt to update the timestamp of a table that has no timestamp column.%Data-conversion resulted in overflow.)Requested data-conversion does not exist.+Invalid computeid or compute column number.<Possible network error: Error in closing network connection.<Attempt to get text pointer/timestamp from a non-text columnsAttempt to use dbtxtsput() to put a new text-timestamp into a column whose datatype is neither SQLTEXT or SQLIMAGE.8Attempt to send too much text via the dbmoretext() call.7Attempt to send empty command buffer to the SQL Server.!Name too long for loginrec field. SQL Server connection timed out.3Possible network error: Write to SQL Server Failed.FNetwork connection not in correct mode, invalid SQL Server connection.HPossible network error: Error in sending out-of-band data to SQL Server. Illegal timeout value specified.0Maximum number of DBPROCESSes already allocated. Attempt to use invalid dboption./Attempt to set fields in a null loginrec field.&Attempt to set unknown loginrec field.-NULL parameter not allowed for this dboption.+Invalid or out of range dboption parameter.+Negative starting index passed to dbstrcpy.&Null destination variable not allowed.Unexpected EOF from SQL Server.DAttempt to initiate a new SQL Server operation with results pending.@Attempt to convert data stopped by syntax error in source field.3Db-library network communications layer not loaded.0Unknown bind type passed to DB-LIBRARY function.)Attempt to bind to a non-existent column.DUser attempted a dbbind() with mismatched column and variable types.$Attempt to bind using NULL pointers.<Attempt to bind user variable to a non-existent compute row.GUser attempted a dbaltbind() with mismatched column and variable types.2Server did not grant a distributed transaction ID.-Illegal field number passed to bcp_control().:1000 rows successfully bulk-copied to host-file. %ld total-Batch successfully bulk-copied to SQL Server.'1000 rows sent to SQL Server. %ld total&I/O error while writing bcp data-file.YAttempt to bulk-copy a NULL value into a Server column which does not accept NULL values.8Attempt to bulk-copy an oversized row to the SQL Server.8bcp_init() must be called before any other bcp routines.bcp_bind(), bcp_collen() and bcp_colptr() may be used only after bcp_init() has been called with the copy direction set to DB_IN.Wbcp_bind() may NOT be used after bcp_init() has been passed a non-NULL input file name.cFor bulk copy, all variable-length data must have either a length-prefix or a terminator specified.dbcp_columns() and bcp_colfmt() may be used only after bcp_init() has been passed a valid input file.1bcp_columns() must be called before bcp_colfmt().0Bcp host-files must contain at least one column.Qbcp_exec() may be called only after bcp_init() has been passed a valid host file.#Bcp: Unable to open host data-file.Bcp: Unable to open error-file.'I/O error while writing bcp error-file.?Attempt to send too much TEXT data via the bcp_moretext() call.,Unexpected EOF encountered in BCP data-file.CHost-file columns may be skipped only when copying INto the Server.!NULL program pointer encountered.Cannot seek in data file3Bad bulk-copy direction. Must be either IN or OUT.:Attempt to use Bulk Copy with a non-existent Server table.:Attempt to set maximum number of DBPROCESSes lower than 1.(DB-Library has already been initialized.Invalid cursor statement.PAttempt to call cursor functions when there are commands waiting to be executed.POne of the tables involved in the cursor statement does not have a unique index.kCursor statement contains one of the disallowed phrases 'compute', 'union', 'for browse', or 'select into'.:Aggregate functions are not allowed in a cursor statement.*Cursors are not supported for this server.XThe BCP hostfile '%s' contains only %ld rows. Skipping all of these rows is not allowed.`The BCP hostfile '%s' contains only %ld rows. It was impossible to read the requested %ld rows.NThe table '%s' contains only %ld rows. Copying up to row %ld is not possible.QThe table '%s' contains only %ld rows. Skipping all of these rows is not allowed.3Attempt to read unknown version of BCP format file.6Incorrect host-column number found in bcp format-file.(I/O error while reading BCP format file.@The data stored in the DBNUMERIC/DBDECIMAL structure is invalid.AThe SQL Server's TDS is obsolete with this version of DB-Library.;The row length exceeds SQL Server's maximum allowable size.:Microsoft Distributed Transaction Coordinator call failed.=This function is not supported on this platform at this time.7float conversion attempt failed, the source is invalid.eUnable to connect: SQL Server is unavailable or does not exist -- will attempt a fallback connection.VOnly fully keyset driven cursors can have 'order by', 'group by', or 'having' phrases.LKeyset or window scroll size exceeds the memory limitations of this machine.OKeyset cannot be scrolled backward in mixed cursors with a previous fetch type.&Cursor statement generated no results.KA view cannot be joined with another table or a view in a cursor statement.=Row buffering should not be turned on when using cursor APIs.0Row number to be fetched is outside valid range.@Backward scrolling cannot be used in a forward scrolling cursor.\Fetch types RANDOM and RELATIVE can only be used within the keyset of keyset driven cursors.5Fetch type LAST requires fully keyset driven cursors.BData locking or modifications cannot be made in a READONLY cursor.TTable name must be determined in operations involving data locking or modifications.NUpdate or insert operations using bind variables require single table cursors.RUpdate or insert operations cannot use bind variables when binding type is NOBIND.mThe view used in the cursor statement does not include all the unique index columns of the underlying tables.3Update or delete operation did not affect any rows. Insufficient memory. Access denied. Connection is busy. Connection broken. Connection limit exceeded. Specified SQL server not found." The network has not been started. Insufficient network resources. Network is busy. Network access denied.2 General network error. Check your documentation. Incorrect connection mode.% Name not found in directory service. Invalid connection.' Error reading or writing network data. Too many open file handles.G Unable to connect: SQL Server does not exist or network access denied. SSL Security error.# SQL Server requires Encryption On.( Encryption not supported on SQL Server.JanFebMarAprMayJunJulAugSepOctNovDec010203040506070809101112DATE_MDYTIME_12CENT_Y4 MFMT_SHORT MNY_PREFIX DATE0_OFF$., :AMPMskippedRowColumn8!0<0K0U0g0l0r0{0Š00•0›0 0¦0«0±0¶0¼0Á0Ç0Ò0×0Ý0æ0ý0110171K1Q1V1\1a1g1l1r1w1}1‚1ˆ1“1œ1£1É1Ð1Ö1à1é1ð1ö122*2>2E2R2Y2‚2¬2µ2¾2õ2 3D3[3x3}3Š3˜3¢3©3¶3Ä3Î3×3á3ü3444'4D4I4V4c4i4r4|4—4œ4©4·4¾4Æ4Î4é4î4û4 551565C5Q5X5a5k5r55ˆ5—5ž5­5´5Ã5Ê5Ù5à5ï5ö56 66"61686G6Ì6Ó67!7%7)7-7175797=7A7E7I7M7Q7U7Y78ð9œ;ü;=G= hÐ1û1=2n2ƒ2›2:3;5B5#7'7+7/73777;7?7C7G7K7L8ˆ8É8w:}:‚:Ž:”:²:½:÷:ý:W<]>5>0L‰11i4;6¿6Å6ð67>7}7a8e8i8m8q8u8y8}88…8‰88‘8•8™88¡8¥8©8­8é<ð~>$?•?³?¾?â?í?PX0Q0b0~0‹0œ0©0¸0Å011’2™2ú2Ò3!4V4¡5Å5÷6E7á7y8929B9Æ9æ9ó9:&:u:ß;Û<á•>`,31î1E2[2¶2Ð2ë2303Ê3 5E9L9è9ï9l:=pœ”0˜0$1(1,1014181<1@1D1<2Q3a3M4}4!6*6w6}6‚6‹6‘6Â6È6Ù6ß6å6î6ó677+7Ö;Y<_>">2>g>Ø>è>??(?A?k?w??…?¡?Ã?É?€”Æ0Ì0Ò0ð0û01 1151;1B1H1V1r1Ò1Ø1ä1ò1þ1 22ƒ22•2©2º2Ë2×2Ý2ñ2373 3·3½3Û3ë344$4=4F4L4F7c7—7Ë78I8ƒ8Ç8„9â9S:õ:ù:ý:;; ; ;;;;;!;Ÿ;=>>+4/4h5¶609‰;i< > ,¦1Ê2Ñ2µ366:6>6B6F6J6N6R6V6¤:€;)=@>°h01…2y3€3ê3î35•5›5¡5©5¯5Ñ5Û5æ5ì5ú5666!6+6=6C6K6Q6y6„6“6ž6¤6²6¸6w79É<Ð<Ê=Î=Ò=Ö=Ú=Þ=â=æ=ó>ð?À°€0š0Ø0å01 1.1Y1g11—1 1©1®1³1Õ1Ú1ü12Y2i2w2¢2°2Ù2à2é2ò2ø2ý2 3%3H3M3ú344B4]4m4ˆ4˜4Ç45_5 6'6@6c6|6Š6œ6Î7í7ñ7õ7ù7°8»8Ð8Ú8ç89 9V9j9u9Š9”9¡9¼9Â9Ñ9ï9::%:/:<:_:<<=)=1?ÐTË03]3a3e3i3m3q3u3y355y5‰5˜6Ä8": <¬<³<====€=‡=²=¶=º=¾=4>;>Ë>Ï>Ó>×>Û>àì0022 222222#2'2+2/232°2·2*3.32363:3>3B3F3J3N3R3V3Z3^3b3f3 4é4ø45]5’6™6 7'7;7W7o7†7¡7½7Ó7×7Û7ß7ã7ç7ú7þ788 888P8W8°8´8¸8¼8À8Ä8È8Ì8Ð8Ô8Ø8Ü8q9x9,:3:“:—:›:Ÿ:£:§:«:¯:³:·:»:¿:Ã:Ç:Ë:(;,;ø;>›?÷?ðh00q0”0˜0œ0 0¤01,102?2’2ž2´2Â2Ó24õ4 5’5§8®8\9`9d9h9t;™;û;E.>b>‹>›>? ?x?›?ò?T 0†0ž0§0Ñ0ô0ý0'1ƒ1ž1E2²2Ì23M3œ3Æ3÷4€5÷5$6T6„6™9®9Å9Ý9Ÿ: <*>&>D?U?]?Ð?Ô?Ø?Ü?à?ä?è?ì?ð?ô?ø?ü?0¼h0x0ã0ê0€2“2Z3j3H4X4¦4ª4®4²4¶4º4¾4Â4Æ4Ê4Î4Ò4X5_5³562767:7>7B7F7J7N7R7V7Z7^7ú78,8<8¢89ó9:X:\:`:d:h:l:p:t:x:|:€:„:;;Z<Š<Ö<=;=?=C=G=K=O=S=W=[=_=c=g=ð=ö=>|>Ñ>ì>?u?|?’?ä?ë?ü?@H00(0/0Ä0ß0ö082Ç3Î3745~5Ÿ56c6À7Ç78¢8¦8ª8®8²8¶8º8¾8Â8Æ8Ê8Î8Ò8Pž5¥5Ø5Ü5à5 >`Hî5õ5Ï6Ø6â67H7¼78t8{8€8º8í8à9î9:s:¤:;s;{;Ã;Ç;Ë;Ï;,<0<4<8<Ô>p\—0¹0á0"1*1[1š1ú13 333¥344í47a8i8q8…89z9Û9A:t:°:ì:;[;›;ì;‹l>p>t>x>|>€>„>€([1b1·1¾1£3€4!6½7Á7Å78#8'8+8/8i56p: ê0p2ç3÷3j4„4–4è4556â6P7[7p7{7—7Ÿ7­78 8&8›8©8°8à8ô8û859…9Œ9ï9ó9÷9û9ÿ9::—:ž:ä;è;ì;ð;ô;ø;ü;<<< <<<…<‹<‘<™<Ÿ<¬<³<¹<Û<æ<ö<û<===°Ä#0e0k0q0y00œ0¦0±0·0Á0Ò0Û0á01 11f1m122!2%2)2-2125292‹4“4¬4ã4x56f6Æ6Ð6ý678†8ö8÷9W:";™; >*>3>j>q>æ>ê>1?F?¢?©?À€¬0&12‰22‘2•2™2Û2O3V3õ3U45‘5i6ù6”7í7ñ7õ7ù7ý7889«9¾9Ñ9ä9÷9 ::-:=:M:]:m:}:¾;Â;Æ;Ê;Î;Ò;Ö;Ú;Þ;â;æ;ê;î;ò;ö;ú;þ;<< <8>Ðx3474;4?4C4G4K4O4S4W4[4_4c4g4k4o4s4w4{44<7J7]7p7ƒ7–7©7¼7Ì7Ü7ì7ü7 88M9Q9U9Y9]9a9e9i9m9q9u9y9}99…9‰99‘9•9™9‘;àè1‘1•1™11¡1¥1©1­1±1µ1¹1½1Á1Å1É1Í1Ñ1Õ1Ù1D2K2«2²2ö2Í5Ñ5Õ5Ù5Ý5ë5ï5ý566 6 66666!6%6)6-6165696=6A6E6I6t7‰8b9¤<¨<¬<°<´<¸<¼<À<Ä<È<Ì<Ð<Ô<Ø<Ü<à<ä<è<ì<ð<&=-=L>X>`>d>h>l>p>t>x>|>€>„>ˆ>Œ>>”>˜>œ> >¤>¨>¬>°>´>¸>¼>À>Ä>È>Ì>â?è?ò?ú?ð„00:0@0h0n0ˆ0”0Ÿ0ª0¿0ß0ò0ü011$1Ì12U3ø34‚4¹4Ä45Š566 646A6È6ç6:7K7Á7Ë7ã7þ78U839@9I9R9Z9c9š9ý9½;–G?k?u?¢?Ì?Ö?à? @30Ô0ø0$1û1 2Ø2â23l4ç4G5¯5*6P6Š6Ô67?8?9«9Â9I:U;d<Å?ô?ÿ?0l$0c0m0{0‹00«0»0Æ0ò01+1“1©1±1º1Ø1]2g2w2~2‹2•2¤2­2¸2Â2Ò2Ú2ä2î2þ233!3«3ì3ô3ý34F47; <<<<< <@Dû1½2ã3ö3'4‹4L5u5|5R6L8P8<9K9‘9ï9u:·:J;a;;Ü;ß<ïì>r?pP€0„0ˆ0Ö0Û0j1ž1(2;2Å2Ö25x7:F:í:m;Œ;< <<#¢> ?¨?Ô?€l 0H0r0©0Ú0=1½183R3j4s4|4„4Ž4—4É4ù4F5‰5ú5E7L7h7Ñ7á7ü748O8®8W9h9r9¾9::!:”:5=Œ>“>H?L?P?T?X?\?`?d?ø?À_0‰0»01L1þ1262æ3ï3"595@5F5N5V5^5f5n5v5~5†5Ž5–5l7s7x7À7Å7 88_8g8¬8³8¼9À9Ä9È9Ì9Ð9Ô9Ø9Ü9à9ä9è9ì9L:P:T:¨:®:Ç:*;†;Ž;£;©;¿;í;PV>p>t>x>|>ù>??!?¼?À?Ä?È?Ì?Ð?Ô?Ø? 80<0@0D0H0L0P0T0X0\01 11^1‡1°1´1¸1¼1U2—2ž2¶2ä2ÿ233@3G3^3e3„3‹3£3¨3À3Ø3ö3ý3442494d4h4l4p4t4x4™4 4©4H5L5P5T5X5\5`5d5h5l5p5t5x5|5€5„5ˆ57 7d7h7l7p7t7x7|7€7„7ˆ7Œ778"8¬8°8´8¸8¼8À8Ä8È8Ì8Ð8Ô8Ø8H9]9r9ç9ý9:,:A:V:Ê:*;;;P;e;–;«;À;Þ;ó;<&<;>+>Q>l>î>??'?°8Ä1Ù1î12.2C2Z5;7]7Ž7!818R8‚8²8 <"»?ç?ü?À<Ô12Z3¤68”8ç8 9h9¿9Û9÷97:S:Ö:ñ:~;¼;Ú;<Ò<ú<5?a??è?ÐP010V0ò2f3«3ó34M4s4™4¿4Î58Å8É8Í8Ñ8Õ8Ù8Ý8á8å8é8í8ñ8õ8ù8ý89E9q9†9º=÷=1>à e:u: ;*;è;ñ;g<­<×<ö>¹?è?ðT0K0—0¼0ó0<1`1£1¿1ª8Û8ô8'9R9g9Ñ;æ;ú; <*<8°>„?˜?Xp0‚0Â0ò0.1<1œ1Ø1æ12Š2–2Ž4’4–4š4O6É6C7d7R8{8ª8¼8 9?99á9C:ä:ª<=‚=\>o>†>á>4?Š?ò?P0)0r0²0ò0#2C2¡2÷2D3e3~3“3¨3»4í58x9Ê9ø9 :H:p:N;ö;l<›=Ÿ=£=§=«=¯=³=·=È>ë? <g1š1ë1x224)4-4145494=4Í4û4#5K5s5e:˜<Œ=º=â= >2>ï>0ˆ>0B0F0J0N0R0V0Z0^0b0f0j0n0r0v0z0~0‚0†0T1…1ý1&3Œ3S45­56~6Ë6l7y7}77…7‰77‘7•7™77¡7¥7î7º9õ9":J:r:Ä:Þ:Ü;à;ä;è;ì;s<=v=¬=>Y>S?@001R1V1Z1^1b1¢1Å1“23745.5)7æ=?Y?q?×?P€ 0Q0Î0´5w9€9‰9’9Ü9þ9: ::':>:H:Z:d:l:‰:“:œ:£:Ò:å:î:ö:;A;\;a;;â;ì; <<<)<2<><<á<ø<=+=X=w=‚=?F?L?R?‚?Œ?–?¡?¯?Ñ?Ü?â?`0 0070?000–0«0±0†1³1¹1ø12/2X2—2è2E3~3„3ã3ë3i4o4…4‹4¯4µ4Á4Ç4Ñ4×4÷4ý4555%5,5>5E5[5v5}55Ü5á5ç56 66 6<6K6[6Õ6õ6½7æ7v8~8°8·8Ö8$9?9M9b9h9n9†9Œ9£9©9Å9Ý9è9î9ó9ü9::::#:=:C:b:j:p::‡:‘:—:å:ù:;';`;¾;Ò;æ; <'>>p €2Ì2¼2À2¤3¨3¬3”4˜4œ4 4¤4¨4¬4°4´4º5Æ5Ò5Þ5ê5ö5666&626>6J6V6b6n6z6†6’6œ6 6¤6¨6¬6°6´6¸6¼6À6Ä6È6Ì6Ð6Ô6Ø6Ü6à6ä6è6ì6ð6ô6ø6ü6777 77777 7$7(7,7074787<7@7D7H7L7P7T7X7\7`7d7h7l7p7t7x7|7€7„7ˆ7Œ7Ä=È=  À0Ä0È0Ì0Ð0Ô0Ø0Ü0à0d4h4l4°ì6ð6ô6NB10ª9dll\ntwdblib.pdbib\usa\x86\ntwdblib.pdbsnort-2.9.15.1/src/win32/WIN32-Prj/WanPacket.dll0000555000175200017520000015011613571422610015505 00000000000000MZÿÿ¸@ິ Í!¸LÍ!This program cannot be run in DOS mode. $\ÞÈ‹¿¦Ø¿¦Ø¿¦Ø›£¨Ø¿¦Ø–·ùØ¿¦Ø¿§ØJ¿¦Ø›·ûØ¿¦Ø.™­Ø¿¦Ø.™¬ØY¿¦Øß¹ Ø¿¦ØçŸ¢Ø¿¦ØRich¿¦ØPELNPßKà! `pS%pàÀ|ˆvPÀhÐD qp.textÊS` `.rdataOpp@@.data€2€0€@À.rsrchÀ°@@.reloc´ÐÀ@BƒìD$SVWPÿp‹t$‹|$ jh€–˜VWè©jh€–˜VW‹ØèÙjj RP莋Ð_‹Ã^[ƒÄÃì W‹|$6‹G‹O;Á‰D$„LSUV‹t$6ë‹D$‹|$B@jh@B€‹lG‹\G|GUSè5jh@BoïIUS‰D$$è^nU‰D$ÿ p‹^8C‰^8‹O‹W ‹Q‹NHRPQèÅ ‹Ø‹FLƒÄƒøuƒûu ‹VDRÿpëƒûÿt;_v‹_‹VLƒúuA‹NXʉNX‹F\¹Á‰F\‹G ƒøƒÄéÛ‹T$Rè,‹D$ƒÄ‹;Ë„šƒù‡‘‹@‰‹L$QÿÕVRÿ8pSSjSÿ4p;ÉFD„‹‹~`Wh‹VDƒÄRÿ0p‹Pè© ƒÄNQÿ,pVÿpÿq_°^ËD$…Àt ƒøtƒøt2ÀËL$‰AL°ÃS‹\$UVW{W3ö3í‰|$ÿ p‹D$;Æv}Áè‹þt‹L$f9ÿtGƒÁ;ørñ‹D$WPè) ƒÄ…Àu‹L$Qÿp_^]2À[ÃÁçWVÿ p‹è;îu‹T$Rÿp_^]2À[Ët$‹Ï‹Á‹ýÁéó¥‹Èƒáó¤‹|$3ö‹CH;ÆtPÿp‹K,‰sP‰sXW‰kH‰s ‰s$‰K(‰s4‰s0‰s8‰sT‰s\ÿp_^]°[ÃUW‹|$3í…ÿvƒÿrKWUÿ p‹è…ít=SV‹t$^Sÿ p‹F…ÀtPÿp3ÀS‰n‰~,‰F ‰F$‰~(ÿp^[_°]Ã_2À]ÃSUV‹t$W3í‹F@‹NDPQ3ÛÿDpFP‰D$ÿ p‹FL‹|$;Åu‹T$RWVèAƒÄ ‹Øƒ~Lu_ƒ|$$s‹L$3ÛQÿp_^‹Ã][øfÇG‰G‰G è¥÷ÿÿ‰‰W‹FX»‰G‹N\‰O‹VP‰W‹FT‰G ‰nP‰nX‰nT‰n\‹L$Qÿp_^‹Ã][ÃVW‹|$ wVÿ p‹D$V‰G<ÿp_°^ÃV‹t$W~Wÿ p‹D$‹N0W‰H‹V8‰‹N4‰H Ç@ÿp_°^ÃSVW‹|$…ÿuƒÏÿëƒÿÿu3ÿ‹\$sVÿ pV‰{@ÿp_^°[ËD$‹@DÃS‹\$UV‹CDWP3íÿHp‹L$…Ɇ‹C(‹s,‹T$;ƃî‹C ‹{Ç+Í‹pƒÆ;ñ‡Ö<*¹‹ðƒÅó¥‹K ƒÁ‰K ‹ñ‹K,;ñuÇC ‹s ‹x+Î;ωL$sC‹{÷<*‹ÑÁéó¥‹Êƒáó¤‹H‹s+Ê<*‹T$ú‹ÑÁéó¥‹Ê‹T$ƒáó¤‹H+ʉK ë#‹Ï‹{÷<*‹ÑÁéó¥‹Êƒáó¤‹H‹S щS ‹@‹s PH‹C,ƒâü+Æêƒøs ÈÇC ‹S(Ñ‹L$;͉S(‡ÿÿÿ_‹Å^][ËD$‹T$ V‹p(J;Îv2À^ËH‹t$SU‹h$‰4)‹t$ ÍW‰q‹t$‹~ ;×v‹×‰Q‹~ ‰y ¿f‰y‹X$߉X$‹Ë‹X,;ËuÇ@$‹h$+Ý;Ús;‹x‹6‹Ëý‹éÁéó¥‹Í‹êƒá+ëó¤‹t$‹x‹Í‹6ó‹ÙÁéó¥‹Ëƒáó¤‰h$ë‹x‹6‹Êý‹ÙÁéó¥‹Ëƒáó¤P$‹p,‹X$‹ÎƒÂ+˃ùs ÑÇ@$‹x(‹H<+ú‹×‰x(+ò_];ñ[r ‹PDRÿp°^Ãì@¹3ÀSUV‹t$PW|$…öó«u _^]ƒÈÿ[ƒÄ@Ë\$`‹l$X3À3ÿƒîƒÆ3Éf‹ù±‡—3ÒŠ‘Dÿ$•Œ‹FH;ˇz3Ò3ÉŠ4(ŠL(ŠT(Áâ Ñ3ÉŠL(Áâ Ñ‹Â묋FP;Ó‡I3ÉŠ,(ŠL(‹Áë‘‹F;Ã13ÒŠ(‹Âézÿÿÿ‹D$\éqÿÿÿ‹|$\éhÿÿÿ‹FÇH;ˇ3Ò3ÉŠ4(ŠL(ŠT(Áâ Ñ3ÉŠL(Áâ Ñ‹Âé2ÿÿÿ‹FÇP;Ó‡Í3ÉŠ,(ŠL(‹Áéÿÿÿ‹FÇ;ð3ÒŠ(‹Âéùþÿÿ‹N;Ë™Š )ƒáÁá‹ùéÞþÿÿ‹FéÖþÿÿ‹~éÎþÿÿ‹V‹D”éÂþÿÿ‹N‹|Œé¶þÿÿ‹V‰D”éªþÿÿ‹N‰|Œéžþÿÿ‹V4Öé“þÿÿ;F~ 3ÉŠN4Îéþÿÿ3ÉŠN4Îétþÿÿ;F|î3ÉŠN4Îébþÿÿ;FuÜ3ÉŠN4ÎéPþÿÿ…FtÊ3ÉŠN4Îé>þÿÿ;Çv¹3ÉŠN4Îé-þÿÿ;Çr¨3ÉŠN4Îéþÿÿ;Çë¹…øt“3ÉŠN4ÎéþÿÿÇéþÿÿ+Çéùýÿÿ‹Ï¯Áéïýÿÿ…ÿ„’3Ò÷÷éÞýÿÿ#Çé×ýÿÿ ÇéÐýÿÿ‹ÏÓàéÇýÿÿ‹ÏÓèé¾ýÿÿFé¶ýÿÿ+Fé®ýÿÿ‹V¯Âé£ýÿÿ3Ò÷vé™ýÿÿ#Fé‘ýÿÿ Fé‰ýÿÿ‹NÓàéýÿÿ‹NÓèéuýÿÿ÷Øénýÿÿ‹øégýÿÿ‹Çé`ýÿÿ‹F_^][ƒÄ@Ã3À_^][ƒÄ@Ãø ,8vhÏ tƒÖºù(C*ݘE3bç©nE†¤ÿ¾Ä=øMW\eaoÝ----------- ----- ------------------------------------ -------!---"#--$-------%-------&-------'---()--*--+-----------------------------------------,SU‹l$VƒýW}_^]3À[Ã…í†ÿ‹t$¿»f‹3ɸ(f;u¹ƒÀ=ˆrì…ÉtÁ‹Â%ÿÿ‹Èƒáƒùw°ÿ$4!%à= w3ÉŠˆ`!ÿ$T!9^s‰éƒ%ð=€‡tÿÿÿ3ÉŠˆ"ÿ$"öÂu_‹F…À„UÿÿÿëR%ðƒø@‡Eÿÿÿ3ÒŠ "ÿ$•”"‹FÇ;Ç‚)ÿÿÿ;Ń!ÿÿÿë3ÉŠNÏ;̓ÿÿÿ3ÒŠV×;ÕƒÿÿÿƒÆGGÿ;Å‚ÿÿÿ‹L$3À_^ŠTéø]€â[€ú”ÀÃd d   ‰ º  ! ! !  I !¨  I× î  ÿ%qÿ%qÿ%ôpÿ%üpÿ%øpÌÌSW3ÿ‹D$ À}G‹T$ ÷Ø÷ڃ؉D$‰T$ ‹D$ À}‹T$÷Ø÷ڃ؉D$‰T$ Àu‹L$‹D$3Ò÷ñ‹D$ ÷ñ‹Â3ÒOyNëS‹Ø‹L$‹T$‹D$ ÑëÑÙÑêÑØ Ûuô÷ñ‹È÷d$‘÷d$Ñr;T$wr;D$ v+D$T$+D$ T$Oy÷Ú÷؃Ú_[ÂÌÌÌÌÌÌÌÌÌÌÌÌÌÌWVS3ÿ‹D$ À}G‹T$÷Ø÷ڃ؉D$‰T$‹D$ À}G‹T$÷Ø÷ڃ؉D$‰T$ Àu‹L$‹D$3Ò÷ñ‹Ø‹D$÷ñ‹ÓëA‹Ø‹L$‹T$‹D$ÑëÑÙÑêÑØ Ûuô÷ñ‹ð÷d$‹È‹D$÷æÑr;T$wr;D$vN3Ò‹ÆOu÷Ú÷؃Ú[^_‹D$ƒø…ˆÿPpj£´«èñ …ÀYt<¡´«3ÉŠ µ«%ÿÁ-´«£¼«‰ À«ÁàÁ£¸«èp…Àu è 3ÀërÿLp£x²èõ£ «èÕè™èÛèÿœ«ë>3É;Áu,9 œ«~½ÿ œ«9 ì«uè1èTè[è¨ ë ƒøuQèáYjX U‹ìS‹]V‹u W‹}…öu ƒ=œ«ë&ƒþtƒþu"¡|²…Àt WVSÿÐ…Àt WVSèçþÿÿ…Àu3ÀëNWVSèì ƒþ‰E u …Àu7WPSèÃþÿÿ…ötƒþu&WVSè²þÿÿ…Àu!E ƒ} t¡|²…ÀtWVSÿЉE ‹E _^[] ¡¨«ƒøt …Àuƒ=¬«uè‰ ÿt$è¹ hÿÿYYát²…ÀtÿÐh€h€èêh€h€èÛƒÄÃjjÿt$ èƒÄ ÃjjjèƒÄ ÃWèŸj_9=ð«uÿt$ÿ\pPÿXpƒ|$ S‹\$‰=쫈è«u<¡p²…Àt"‹ l²Vqü;ðr‹…ÀtÿЃî;5p²sí^h€h€èCYYh €h€è2YY…Û[tè_Ãÿt$‰=ð«ÿTp_Ãj èš YÃj èò YÃV‹t$;t$ s ‹…ÀtÿЃÆëí^ÃVèÚ ÿhpƒøÿ£”t:jtjèÌ ‹ðY…öYt)Vÿ5”ÿdp…ÀtVè4Yÿ`pƒNÿj‰X^Ã3À^Ãè° ¡”ƒøÿtPÿlpƒ ”ÿËD$Ç@PƒÇ@ÃVWÿxpÿ5”‹øÿtp‹ð…öu?jtjèA ‹ðY…öYt&Vÿ5”ÿdp…ÀtVè©ÿÿÿYÿ`pƒNÿ‰ëjèÐýÿÿYWÿpp‹Æ_^ᔃøÿ„‘V‹t$…öu Pÿtp‹ð…ötl‹F$…ÀtPè Y‹F(…ÀtPèý Y‹F0…ÀtPèï Y‹F8…ÀtPèá Y‹F@…ÀtPèÓ Y‹FD…ÀtPèÅ Y‹FP=ƒtPè´ YVè­ Yjÿ5”ÿdp^ÃU‹ìƒìHSVWh€èr ‹ðY…öujèýÿÿY‰5`±Ç`² †€;ðs€fƒÿƒfÆF ¡`±ƒÆ$€ëÞE¸Pÿpfƒ}ê„Ñ‹Eì…À„Æ‹8X;‰Eü¸;ø|‹ø9=`²}V¾d±h€èÞ …ÀYt<ƒ`² ‰ˆ€;Ás€`ƒÿƒ`Æ@ ‹ƒÀ$Á€ëàƒÆ9=`²|·ë‹=`²3ö…ÿ~L‹Eü‹ƒùÿt8Ѝt2¨u Qÿp…Àt#‹Î‹ÆÁùƒà‹ `±À‹Mü‹ ‰Š ˆHƒEüFC;÷|´3Û‹ `±Ûƒ<ÿ4uM…ÛÆFujöXë ‹ÃH÷ØÀƒÀõPÿp‹øƒÿÿtWÿp…Àt %ÿ‰>ƒøu€N@ëƒøu €Në€N€Cƒû|—ÿ5`²ÿ|p_^[ÉÃSVW¾`±‹…Àt7‹ø€;øs!_ ƒ{ütSÿ,p‹ƒÇ$€ƒÃ$;ørâÿ6èŸ ƒ&YƒÆþ`²|¸_^[ÃS3Û9h²VWuèä‹5 «3ÿŠ:Ãt<=tGVèx Ytëè½Pè6 ‹ðY;ó‰5Ыuj èÀúÿÿY‹= «8t9UWè> ‹èYE€?=t"Uè ;ÃY‰uj è‘úÿÿYWÿ6è( YƒÆYý8uÉ]ÿ5 «èê Y‰ «‰_^Çd²[ÃU‹ìQQS3Û9h²VWuè&¾ô«hVSÿ„p¡x²‰5à«‹þ8t‹øEøPEüPSSWèM‹Eø‹MüˆPèa ‹ðƒÄ;óujèïùÿÿYEøPEüP‹Eü†PVWè‹EüƒÄH‰5È«_^£Ä«[ÉÃU‹ì‹M‹ESVƒ!‹uW‹} Ç‹E…ÿt‰7ƒÇ‰} €8"uDŠP@€ú"t)„Òt%¶Òö‚A°t ÿ…ötŠˆF@ÿ…ötÕŠˆFëÎÿ…öt€&F€8"uF@ëCÿ…ötŠˆFŠ@¶ÚöƒA°t ÿ…ötŠˆF@€ú t „Òt €ú uÌ„ÒuHë…öt€fÿƒe€8„àŠ€ú t€ú u@ëñ€8„È…ÿt‰7ƒÇ‰} ‹UÿÇE3Û€8\u@Cë÷€8"u,öÃu%3ÿ9}t €x"Pu‹Âë‰}‹} 3Ò9U”‰UÑë‹ÓK…ÒtC…ötÆ\FÿKuóŠ„ÒtJƒ}u €ú t?€ú t:ƒ}t.…öt¶ÚöƒA°tˆF@ÿŠˆFë¶Òö‚A°t@ÿÿ@éXÿÿÿ…öt€&Fÿéÿÿÿ…ÿtƒ'‹E_^[ÿ]ÃQQ¡ø¬SU‹-˜pVW3Û3ö3ÿ;Ãu3ÿÕ‹ð;ót Çø¬ë(ÿ”p‹ø;û„êÇø¬éƒø…;óu ÿÕ‹ð;ó„Âf9‹Æt@@f9uù@@f9uò+Æ‹=pÑøSS@SSPVSS‰D$4ÿ׋è;ët2UèÎ;ÃY‰D$t#SSUPÿt$$VSSÿ×…Àuÿt$èÂY‰\$‹\$VÿŒp‹ÃëSƒøuL;ûu ÿ”p‹ø;ût<8‹Çt @8uû@8uö+Ç@‹èUèg‹ðY;óu3öë UWVèò ƒÄ Wÿˆp‹Æë3À_^][YYÃV‹t$jƒ&ÿœpf8MZu‹H<…Ét ÁŠHˆŠ@ˆF^ÃU‹ì¸,è‘…hÿÿÿSPÇ…hÿÿÿ”ÿ(p…Àtƒ½xÿÿÿuƒ½lÿÿÿrjXé…ÔíÿÿhPhdqÿ p…À„Ð3ÛÔíÿÿ8ÔíÿÿtŠj,Pè"Y;ÃYt0@‹È8t€9;uˆëA8uòj SPèÃƒÄ ƒøtƒøtƒøtEüPè˜þÿÿ€}üYÀƒÀ[ÉÃ3Àj9D$h”ÀPÿ¨p…À£H±t6è“þÿÿƒø£L±u høèLYë ƒøuè…Àuÿ5H±ÿ¤p3ÀÃjXáL±VƒøWufS3Û9¯U‹-°p~@¡ ¯‹=¬pp h@hÿ6ÿ×h€jÿ6ÿ×ÿvjÿ5H±ÿÕƒÆC;¯|Îÿ5 ¯jÿ5H±ÿÕ][ë'ƒøu"¿ „‹÷‹F…Àth€jPÿ¬p‹6;÷uåÿ5H±ÿ¤p_^ÃjX ¡¨«ƒøt …Àu*ƒ=¬«u!hüè¡ü¬Y…ÀtÿÐhÿèYÃU‹ì줋U3ɸÀ;t ƒÀA=P‚rñV‹ñÁæ;–À…¡¨«ƒø„è…Àu ƒ=¬«„×úü„ñ…\þÿÿhPjÿ„p…Àu…\þÿÿhTtPè:YY…\þÿÿWP½\þÿÿè@YƒøWjè|‹øY…ÿujè òÿÿYjèÊÿÿÿƒ>YWu ÿ8p‰>ëègYjè Y_ÿ6ÿ p^]ÃU‹ì‹Eÿ4…P‚ÿp]ÃU‹ìjÿhpth€Ud¡Pd‰%ƒìSVW‹u¯u ‰u ‰uäƒþàw3Û;óuj^ƒÆƒæð‰u ë3Û‰]àƒþà‡¨¡L±ƒøuA‹}ä;=¯w|j èÿÿÿY‰]üWèY‰EàƒMüÿè9]àt^ÿuäëH3Û‹u j èKÿÿÿYÃøuA;5Ĥw9j èÔþÿÿYÇEü‹ÆÁèPècY‰EàƒMüÿèL9]àtVSÿuàèƒÄ 9]àu>Vjÿ5H±ÿ¸p‰Eà9]àu'9x­tVèÐY…À…0ÿÿÿë3Û‹u j èÂþÿÿYËEà‹Mðd‰ _^[ÉÃU‹ìjÿhˆth€Ud¡Pd‰%ƒìSVW‹u…ö„¬¡L±ƒøu;j èþÿÿYƒeüVè¤Y‰Eä…Àt VPèÀYYƒMüÿèƒ}äëQj è=þÿÿYÃøuSj èÎýÿÿYÇEüEàPEØPVè¾ƒÄ ‰EÜ…ÀtPÿuàÿuØèÿƒÄ ƒMüÿè ƒ}Üuÿuë j èåýÿÿYÃVjÿ5H±ÿ°p‹Mðd‰ _^[ÉÃÿ5x­ÿt$èYYÃ|$àw"ÿt$è…ÀYu9D$tÿt$膅ÀYuÞ3ÀÃU‹ìjÿh th€Ud¡Pd‰%ƒì SVW¡L±ƒøuC‹u;5¯‡“j èãüÿÿYƒeüVèÍY‰EäƒMüÿè ‹Eä…Àtmé†j èýÿÿYÃøuZ‹E…Àtpƒæðëj^‰u;5Ĥw.j èüÿÿYÇEü‹ÆÁèPèY‰EäƒMüÿè ‹Eä…Àu-Vë‹uj èºüÿÿYËE…ÀujXƒÀ$ðPjÿ5H±ÿ¸p‹Mðd‰ _^[ÉÃÌÌÌÌW‹|$ëj¤$‹ÿ‹L$W÷ÁtŠA„Àt;÷Áuñ‹ºÿþþ~Ѓðÿ3ƒÁ©tè‹Aü„Àt#„ät©ÿt©ÿtëÍyÿë yþëyýëyü‹L$ ÷ÁtŠA„ÒtdˆG÷Áuî뉃Ǻÿþþ~‹Ѓðÿ3‹ƒÁ©tá„Òt4„öt'÷Âÿt÷Âÿtëlj‹D$_Ãf‰‹D$ÆG_Ãf‰‹D$_È‹D$_ËL$÷ÁtŠA„Àt@÷Áuñ‹ºÿþþ~Ѓðÿ3ƒÁ©tè‹Aü„Àt2„ät$©ÿt©ÿtëÍAÿ‹L$+ÁÃAþ‹L$+ÁÃAý‹L$+ÁÃAü‹L$+ÁÃU‹ìƒìSVWjè«úÿÿÿuè•‹ØY;¯Y‰]u3öép…Û„V3Ò¸¨ƒ9ttƒÀ0B=˜„rñEèPSÿ€pj^;Æ…!j@ƒ%D±Y3À¿@°9uè󫪉¯†ë€}M҄¯¶Aÿ¶Ò;‡”€ˆA°@ëîƒeüj@Y3À¿@°4Ró«Á檞¸ƒ€;‹Ët,ŠQ„Òt%¶¶ú;Çw‹UüŠ’ ƒA°@;ÇvõAA€9uÔÿEüƒÃƒ}ürÁ‹EÇ,¯P£¯è欃¿ ¯¥¥Y£D±¥ëRAA€yÿ…Gÿÿÿ‹Æ€ˆA°@=ÿrñSè•Y£D±‰5,¯ëƒ%,¯3À¿ ¯«««ëƒ=`­tè™è½éŒþÿÿƒÎÿjèwùÿÿY‹Æ_^[ÉËD$ƒ%`­ƒøþuÇ`­ÿ%ÀpƒøýuÇ`­ÿ%¼pƒøüu¡”­Ç`­ËD$-¤t"ƒètƒè t Ht3ÀøøøøÃWj@Y3À¿@°ó«ª3À¿ ¯£¯£,¯£D±«««_ÃU‹ììEìVPÿ5¯ÿ€pƒø…3À¾ˆ„ìþÿÿ@;ÆrôŠEòÆ…ìþÿÿ „Àt7SWUó¶ ¶À;Áw+ȼìþÿÿA¸ ‹ÙÁéó«‹ËƒáóªBBŠBÿ„ÀuÐ_[j…ìúÿÿÿ5D±ÿ5¯P…ìþÿÿVPjèºj…ìýÿÿÿ5¯VP…ìþÿÿVPVÿ5D±èGj…ìüÿÿÿ5¯VP…ìþÿÿVPhÿ5D±èƒÄ\3Àìúÿÿf‹öÂt€ˆA°Š”ìýÿÿˆ@¯ëöÂt€ˆA° Š”ìüÿÿë〠@¯@AA;Ær¿ëI3À¾ƒøArƒøZw€ˆA°ŠÈ€Á ˆˆ@¯ëƒøarƒøzw€ˆA° ŠÈ€é ëà€ @¯@;Ær¾^ÉÃ=h²ujýèüÿÿYÇh²ÃÌU‹ìWV‹u ‹M‹}‹Á‹ÑÆ;þv;ø‚x÷ÇuÁéƒâƒùr)ó¥ÿ$•8>‹Çºƒér ƒàÈÿ$…P=ÿ$H>ÿ$Ì=`=Œ=°=#ÑŠˆŠFˆGŠFÁéˆGƒÆƒÇƒùrÌó¥ÿ$•8>I#ÑŠˆŠFÁéˆGƒÆƒÇƒùr¦ó¥ÿ$•8>#ÑŠˆFÁéGƒùrŒó¥ÿ$•8>I/>>> >>ü=ô=ì=‹DŽä‰Dä‹DŽè‰Dè‹DŽì‰Dì‹DŽð‰Dð‹DŽô‰Dô‹DŽø‰Dø‹DŽü‰Düðøÿ$•8>‹ÿH>P>\>p>‹E^_Éʈ‹E^_ÉʈŠFˆG‹E^_ÉÃIŠˆŠFˆGŠFˆG‹E^_ÉÃt1ü|9ü÷Çu$Áéƒâƒùr ýó¥üÿ$•Ð?‹ÿ÷Ùÿ$€?I‹Çºƒùr ƒà+Èÿ$…Ø>ÿ$Ð?è>?0?ŠF#шGNÁéOƒùr¶ýó¥üÿ$•Ð?IŠF#шGŠFÁéˆGƒîƒïƒùrŒýó¥üÿ$•Ð?ŠF#шGŠFˆGŠFÁéˆGƒîƒïƒù‚Zÿÿÿýó¥üÿ$•Ð?I„?Œ?”?œ?¤?¬?´?Ç?‹DމD‹DމD‹DމD‹DމD‹DŽ ‰D ‹DމD‹DމDðøÿ$•Ð?‹ÿà?è?ø? @‹E^_ÉÊFˆG‹E^_ÉÃIŠFˆGŠFˆG‹E^_ÉÊFˆGŠFˆGŠFˆG‹E^_ÉÃjÿt$ÿt$ÿt$èƒÄÃU‹ìƒì SƒeøVW‹}Šw‰uüƒ=T¨~¶ÃjPèÌYYë‹ H¦¶ÃŠAƒà…ÀtŠFëЀû-‰uüuƒMë€û+uŠF‰uü‹E…ÀŒ‰ƒø„€ƒø$wj…ÀYu$€û0t ÇE ë2Šƒàt }ø€w …Àu,9uøv'èýöEÇ"tƒMøÿë‹E$öØÀ÷ØƉEø…Ût‹Eü‰öEt‹Eø÷؉Eø‹Eøë ‹E …Àt‰83À_^[ÉÃÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌBÿ[ä$d$3ÀŠD$S‹ØÁà‹T$÷ÂtŠ B8ÙtÑ„ÉtQ÷Âuí ØW‹ÃÁãV Ø‹ ¿ÿþþ~‹Á‹÷3Ëðùƒñÿƒðÿ3Ï3ƃÂáu%tÓ%uæ€uÄ^_[3ÀËBü8Øt6„Àtï8Üt'„ätçÁè8Øt„ÀtÜ8Üt„ätÔë–^_Bÿ[ÃBþ^_[ÃBý^_[ÃBü^_[ÃÌÌÌÌ‹L$WSVŠ‹|$„ÒtiŠq„ötO‹÷‹L$ŠF8Ðt„Àt ŠF8Ðt „Àuõ^[_3ÀÊF8ðuë~ÿŠa„ät(ŠƒÆ8àuÄŠA„ÀtŠfÿƒÁ8àtßë±3À^[_ŠÂéÓþÿÿGÿ^[_ËÇ^[_ÃU‹ìWVS‹Mã&‹Ù‹}‹÷3Àò®÷ÙË‹þ‹u ó¦ŠFÿ3É:GÿwtII÷Ñ‹Á[^_ÉÃÌÌÌÌÌÌÌÌQ=L$ré-…=sì+ȋą‹á‹‹@PÃh@jÿ5H±ÿ¸p…À£ ¯uËL$ƒ%¯ƒ%¯j£¯‰ ¯Çø®Xᯠ€¡ ¯ ˆ;Ás‹T$+P úrƒÀëè3ÀÃU‹ìƒì‹MSV‹u ‹AW‹þƒÆü+y Áï‹ÏiÉŒD‰Mð‹IöÁ‰Mü…æ‹11‰Uô‹Vü‰Uø‹Uôö‰] u~ÁúJƒú?vj?Z‹K;KuLƒú s»€‹ÊÓëL÷Ó!\¸Dþ u(‹M!ë!JເÓëL÷Ó!œ¸Äþ u‹M!Y‹Mü‹] ë‹Mü‹S‹[Mô‰Z‹U ‰Mü‹Z‹R‰S‹ÑÁúJƒú?vj?Z‹]øƒã‰]ô…”+uø‹]øÁûj?‰u K^;Þv‹ÞMø‹Ñ‰MüÁúJ;Öv‹Ö;Útc‹M ‹q;qu@ƒû s¾€‹ËÓî÷Ö!t¸DþLu&‹M!1ëKྀÓî÷Ö!´¸ÄþLu‹M!q‹M ‹q‹I‰N‹M ‹q‹I‰N‹u ë‹]ƒ}ôu;Ú„‹Mð‹\Ñ щ^‰N‰q‹N‰q‹N;Nu`ŠLƒú ˆMþÁˆLs%€}u»€‹ÊÓë‹M »€‹ÊÓëD¸D ë)€}uJເÓë‹M YJ຀Óê„¸Ä ‹Eü‰‰D0ü‹Eðÿ…÷¡¯…À„Ü‹ ü®‹5¬pÁáH »€h@SQÿÖ‹ ü®¡¯º€Óê P¡¯‹ ü®‹@ƒ¤ˆÄ¡¯‹@þHC¡¯‹H€yCu ƒ`þ¡¯ƒxÿuiSjÿp ÿÖ¡¯ÿpjÿ5H±ÿ°p¡¯‹ ¯€Áà‹È¡¯+ÈLìQHQPè:‹EƒÄ ÿ ¯;¯vƒm¡ ¯£¯‹E‰=ü®£¯_^[ÉÃU‹ìƒì¡¯‹ ¯SV€W<‚‹E‰}üHƒáð‰MðÁùIƒù }ƒÎÿÓîƒMøÿ‰uôëƒÁàƒÈÿ3öÓè‰uô‰Eø¡¯‹Ø;߉]s‹K‹;#Mø#þ Ïu ƒÃ;]ü‰]rç;]üuy‹Ú;؉]s‹K‹;#Mø#þ ÏuƒÃëæ;ØuY;]üsƒ{uƒÃ‰]ëí;]üu&‹Ú;؉]s ƒ{uƒÃëî;Øuè8‹Ø…Û‰]tSèÚY‹K‰‹Cƒ8ÿu3À鉯‹C‹ƒúÿ‰Uüt‹ŒÄ‹|D#Mø#þ Ïu7‹Ä‹pD#Uø#uôƒeüHD Ö‹uôu‹‘„ÿEü#UøƒÁ‹þ#9 ×té‹Uü‹Ê3ÿiÉŒD‰Mô‹LD#Îu ‹ŒÄj #Mø_…É|ÑáGë÷‹Mô‹Tù‹ +Mð‹ñ‰MøÁþNƒþ?~j?^;÷„ ‹J;Juaƒÿ }+»€‹ÏÓë‹Mü|8÷Ó‰]ì#\ˆD‰\ˆDþu8‹]‹Mì! ë1OເÓë‹Mü|8ŒˆÄ÷Ó!þ‰]ìu ‹]‹Mì!Kë‹]‹J‹zƒ}ø‰y‹J‹z‰y„”‹Mô‹|ñ ñ‰z‰J‰Q‹J‰Q‹J;JudŠLƒþ ˆM })þÁ€} ˆLu ¿€‹ÎÓï ;¿€‹ÎÓï‹Mü |ˆDë/þÁ€} ˆLu Nà¿€Óï {‹Mü¼ˆÄNྀÓî 7‹Mø…Ét ‰ ‰Lüë‹Mø‹uðÑN‰ ‰L2ü‹uô‹…Éy‰>u;¯u‹Mü; ü®uƒ%¯‹Mü‰B_^[Éᯋ ø®VW3ÿ;Áu0D‰PÁàPÿ5 ¯Wÿ5H±ÿÈp;Çtaƒø®£ ¯¡¯‹ ¯hÄAj€ÿ5H±4ÿ¸p;ljFt*jh hWÿÄp;ljF uÿvWÿ5H±ÿ°p3ÀëƒNÿ‰>‰~ÿ¯‹Fƒÿ‹Æ_^ÃU‹ìQ‹MSVW‹q‹A3Û…À|ÑàCë÷‹Ãj?iÀZ„0D‰Eü‰@‰@ƒÀJuô‹ûjÁçy hh€WÿÄp…ÀuƒÈÿé“—p;úwt‹Æ4;ósCŠ„Ûu0jX^€;uCFë÷;òsN;Eüu‰që )u 9U ‚™‹}ü‹Ãë¶óÆ4;ur½q;÷s~;EsvŠ„Àu@j^X€;u%C@ë÷;]s +ò‰‰që ƒaq‰1ˆƒÀë6;Âs)E 9U r4‹óë®¶Àðë§;]s +‰‰Aë ƒaA‰ˆFkÉÁà+Áë3À_^[ÉÃS3Û9h­VWuBhètÿ$p‹ø;ûtg‹5ÌphÜtWÿÖ…À£h­tPhÌtWÿÖh¸tW£l­ÿÖ£p­¡l­…ÀtÿЋ؅Ût¡p­…ÀtSÿЋØÿt$ÿt$ÿt$Sÿh­_^[Ã3ÀëøÌÌÌ‹L$ W…ÉtzVS‹Ù‹t$÷Æ‹|$uÁéuoë!ŠFˆGIt%„Àt)÷Æuë‹ÙÁéuQƒãt ŠFˆG„Àt/Kuó‹D$[^_Ã÷ÇtˆGI„Š÷Çuî‹ÙÁéulˆGKuú[^‹D$_ɃÇIt¯ºÿþþ~‹Ѓðÿ3‹ƒÆ©tÞ„Òt,„öt÷Âÿt ÷ÂÿuƉëâÿÿ‰ëâÿ‰ë3Ò‰ƒÇ3ÀIt 3À‰ƒÇIuøƒãu…‹D$[^_át­…Àtÿt$ÿÐ…ÀYtjXÃ3ÀÃÌÌÌÌÌÌÌ‹T$ ‹L$…ÒtG3ÀŠD$W‹ùƒúr-÷Ùƒát+шGIuú‹ÈÁàÁ‹ÈÁàÁ‹ÊƒâÁétó«…ÒtˆGJuú‹D$_ËD$ÃU‹ìSVWUjjh Tÿuè$]_^[‹å]ËL$÷A¸t‹D$‹T$‰¸ÃSVW‹D$Pjþh¨Tdÿ5d‰%‹D$ ‹X‹p ƒþÿt.;t$$t(4v‹ ³‰L$‰H ƒ|³uh‹D³è@ÿT³ëÃdƒÄ _^[Ã3Àd‹ y¨Tu‹Q ‹R 9Qu¸ÃSQ»Ð¤ë SQ»Ð¤‹M‰K‰C‰k Y[ÂÌÌVC20XC00U‹ìƒìSVWUü‹] ‹E÷@…‚‰Eø‹E‰EüEø‰Cü‹s ‹{ƒþÿta vƒ|tEVUkÿT]^‹] Àt3x<‹{Sè©þÿÿƒÄkVSèÞþÿÿƒÄ vj‹Dèaÿÿÿ‹‰C ÿT‹{ v‹4롸ë¸ëUkjÿSèžþÿÿƒÄ]¸]_^[‹å]ÃU‹L$‹)‹AP‹APèyþÿÿƒÄ]ÂU‹ìjÿhuh€Ud¡Pd‰%ƒìSVW‰eè3ÿ9=œ­uFWWj[Shøt¾VWÿÜp…Àt‰œ­ë"WWShôtVWÿØp…À„"Çœ­9}~ÿuÿuèžYY‰E¡œ­ƒøuÿuÿuÿuÿuÿu ÿuÿØpéÞƒø…Ó9} u¡”­‰E WWÿuÿu‹E$÷ØÀƒà@Pÿu ÿÔp‹Ø‰]ä;ß„œ‰}üƒÀ$üè†ìÿÿ‰eè‹Ä‰E܃MüÿëjXËeè3ÿ‰}܃Müÿ‹]ä9}ÜtfSÿuÜÿuÿujÿu ÿÔp…ÀtMWWSÿuÜÿu ÿuÿÜp‹ð‰uØ;÷t2öE t@9}„²;uÿuÿuSÿuÜÿu ÿuÿÜp…À…3ÀeÈ‹Mðd‰ _^[ÉÃÇEü6ƒÀ$üèÒëÿÿ‰eè‹Ü‰]àƒMüÿëjXËeè3ÿ3ÛƒMüÿ‹uØ;ßt´VSÿuäÿuÜÿu ÿuÿÜp…Àtœ9}WWuWWëÿuÿuVSh ÿu ÿp‹ð;÷„qÿÿÿ‹Æélÿÿÿ‹T$‹D$…ÒVJÿt €8t@‹ñI…öuó€8^u+D$ËÂÃU‹ìjÿhuh€Ud¡Pd‰%ƒìSVW‰eè¡ ­3Û;Ãu>EäPj^VhøtVÿäp…Àt‹ÆëEäPVhôtVSÿàp…À„ÎjX£ ­ƒøu$‹E;Ãu¡„­ÿuÿuÿu ÿuPÿàp韃ø…”9]u¡”­‰ESSÿuÿu ‹E ÷ØÀƒà@PÿuÿÔp‰Eà;Ãtc‰]ü<‹ÇƒÀ$üèUêÿÿ‰eè‹ô‰uÜWSVè•úÿÿƒÄ ë jXËeè3Û3öƒMüÿ;ót)ÿuàVÿuÿu jÿuÿÔp;ÃtÿuPVÿuÿäpë3ÀeÌ‹Mðd‰ _^[ÉÃèÑÍÿÿƒÀÃS3Û9„­u‹D$ƒøa|YƒøzTƒè [ÃV¾ô®WVÿìp9ð®‹=èptVÿ×jèyÙÿÿYj[ÿt$è…ÛY‰D$t jè½ÙÿÿYëVÿ׋D$_^[ÃU‹ìQƒ=„­Su‹EƒøaŒ¯ƒøz¦ƒè éž‹]û}(ƒ=T¨~ jSè…YYë ¡H¦ŠXƒà…Àu‹Ãëk‹H¦‹ÃÁø¶ÈöDJ€t€e ˆEˆ] jë €e ˆ]jXMüjjjQPEPhÿ5„­èFûÿÿƒÄ …Àt©ƒøu¶Eüë ¶Eý¶MüÁà Á[ÉÃU‹ìQ‹EHùw ‹ H¦·AëR‹ÈV‹5H¦Áù¶ÑöDV€^t€eþˆMüˆEýjë €eýˆEüjXM jjjQPEüPjèýÿÿƒÄ…ÀuÉ÷E #E ÉÃÌÌÌÌÌÌÌU‹ìWV‹u ‹M‹}‹Á‹ÑÆ;þv;ø‚x÷ÇuÁéƒâƒùr)ó¥ÿ$•ø\‹Çºƒér ƒàÈÿ$…\ÿ$]ÿ$Œ\ \L\p\#ÑŠˆŠFˆGŠFÁéˆGƒÆƒÇƒùrÌó¥ÿ$•ø\I#ÑŠˆŠFÁéˆGƒÆƒÇƒùr¦ó¥ÿ$•ø\#ÑŠˆFÁéGƒùrŒó¥ÿ$•ø\Iï\Ü\Ô\Ì\Ä\¼\´\¬\‹DŽä‰Dä‹DŽè‰Dè‹DŽì‰Dì‹DŽð‰Dð‹DŽô‰Dô‹DŽø‰Dø‹DŽü‰Düðøÿ$•ø\‹ÿ]]]0]‹E^_Éʈ‹E^_ÉʈŠFˆG‹E^_ÉÃIŠˆŠFˆGŠFˆG‹E^_ÉÃt1ü|9ü÷Çu$Áéƒâƒùr ýó¥üÿ$•^‹ÿ÷Ùÿ$@^I‹Çºƒùr ƒà+Èÿ$…˜]ÿ$^¨]È]ð]ŠF#шGNÁéOƒùr¶ýó¥üÿ$•^IŠF#шGŠFÁéˆGƒîƒïƒùrŒýó¥üÿ$•^ŠF#шGŠFˆGŠFÁéˆGƒîƒïƒù‚Zÿÿÿýó¥üÿ$•^ID^L^T^\^d^l^t^‡^‹DމD‹DމD‹DމD‹DމD‹DŽ ‰D ‹DމD‹DމDðøÿ$•^‹ÿ ^¨^¸^Ì^‹E^_ÉÊFˆG‹E^_ÉÃIŠFˆGŠFˆG‹E^_ÉÊFˆGŠFˆGŠFˆG‹E^_ÉÃÌÌÌÌÌÌÌÌÌÌÌ‹T$‹L$÷Âu<‹:u. Àt&:au% ätÁè:Au Àt:auƒÁƒÂ äuÒ‹ÿ3ÀÃÀÑà@Ëÿ÷ÂtŠB:uéA Àtà÷Ât¨f‹ƒÂ:uÒ ÀtÊ:auÉ ätÁƒÁëŒÌÌÌÌÌÌÌÌÌÌÌÌU‹ìV3ÀPPPPPPPP‹U IŠ ÀtB«$ëó‹uƒÉÿAŠ ÀtF£$sò‹ÁƒÄ ^ÉÃÌÌU‹ìV3ÀPPPPPPPP‹U IŠ ÀtB«$ëó‹uŠ Àt F£$sóFÿƒÄ ^ÉÃÌÌÌÌÌÌU‹ìWVS‹u ‹}|­ƒxu;°ÿ‹ÿ Àt.ŠFŠ'G8Ätò,A<É€á ÁA†à,A<É€á ÁA8àtÒÀÿ¾Àëxðÿô®ƒ=ð®jëðÿ ô®jèAÓÿÿÇ$¸ÿ3Û Àt'ŠFŠG8ØtòPSè,‹ØƒÄè"ƒÄ8ÃtÚÀƒØÿ‹ØX Àu ðÿ ô®ë jèQÓÿÿƒÄ‹Ã[^_ÉÃU‹ìWVS‹M É„é‹u‹} |­ƒxuN·A³Z¶ IŠ& äŠt! ÀtFG8ür8Üwæ8ør8ØwÆ8Äu Iu×3É8Ä„›¹ÿÿÿÿ‚÷Ùé‰ðÿô®ƒ=ð®jëðÿ ô®‹ÙjèQÒÿÿÇ$‹Ë3À3Û‹ÿŠ ÀŠt# ÛtFGQPSè;‹ØƒÄè1ƒÄY;Ãu IuÕ3É;Ãt ¹ÿÿÿÿr÷ÙX Àu ðÿ ô®ë‹ÙjèRÒÿÿƒÄ‹Ë‹Á[^_ÉÃÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌSV‹D$ Àu‹L$‹D$3Ò÷ñ‹Ø‹D$ ÷ñ‹ÓëA‹È‹\$‹T$‹D$ ÑéÑÛÑêÑØ Éuô÷ó‹ð÷d$‹È‹D$÷æÑr;T$wr;D$ vN3Ò‹Æ^[ÂÌÌÌÌÌÌÌÌS‹D$ Àu‹L$‹D$ 3Ò÷ñ‹D$÷ñ‹Â3ÒëP‹È‹\$‹T$ ‹D$ÑéÑÛÑêÑØ Éuô÷ó‹È÷d$‘÷d$Ñr;T$ wr;D$v+D$T$+D$T$ ÷Ú÷؃Ú[ÂU‹ìQƒ=„­SVWu‹EƒøAŒªƒøZ¡ƒÀ 陋]¿j;ß^}%95T¨~ VSè$øÿÿYYë ¡H¦ŠX#Æ…Àu‹Ãëe‹H¦‹ÃÁø¶ÈöDJ€t€e jˆEˆ] Xë €e ˆ]‹ÆVjMüjQPEPWÿ5„­èëòÿÿƒÄ …Àt®;Æu¶Eüë ¶Eý¶MüÁà Á_^[ÉËD$‹L$ È‹L$ u ‹D$÷áÂS÷á‹Ø‹D$÷d$Ø‹D$÷áÓ[Âÿ%Ðp¨z¶z˜zVxdxrxŒx¤x°xÈxØxèxyyy:yByXynyÈyÚyèyöy zz4zBzNzXzhzvz†zÖ{ÈzÞzøz{({@{Z{n{ˆ{–{¤{²{¾{Ê{â{ì{ø{||(|4|J|Z|j|||Ž|¦|x2x$xôwx®yœyŠyNPßKNÐ@êH‚µÎµ¯ªl³}__GLOBAL_HEAP_SELECTED__MSVCRT_HEAP_SELECTruntime error TLOSS error SING error DOMAIN error R6028 - unable to initialize heap R6027 - not enough space for lowio initialization R6026 - not enough space for stdio initialization R6025 - pure virtual function call R6024 - not enough space for _onexit/atexit table R6019 - unable to open console device R6018 - unexpected heap error R6017 - unexpected multithread lock error R6016 - not enough space for thread data abnormal program termination R6009 - not enough space for environment R6008 - not enough space for arguments R6002 - floating point not loaded Microsoft Visual C++ Runtime Library Runtime Error! Program: ...ÿÿÿÿÀ4ÿÿÿÿI5ÿÿÿÿÓ5ÿÿÿÿ+6ÿÿÿÿ÷6ÿÿÿÿS7GetLastActivePopupGetActiveWindowMessageBoxAuser32.dllÿÿÿÿhWlWÿÿÿÿX Xÿÿÿÿ Y¤YH:mm:ssdddd, MMMM dd, yyyyM/d/yyPMAMDecemberNovemberOctoberSeptemberAugustJulyJuneAprilMarchFebruaryJanuaryDecNovOctSepAugJulJunMayAprMarFebJanSaturdayFridayThursdayWednesdayTuesdayMondaySundaySatFriThuWedTueMonSunSunMonTueWedThuFriSatJanFebMarAprMayJunJulAugSepOctNovDecÌwHxôpØv|ypäw¾y q¨z¶z˜zVxdxrxŒx¤x°xÈxØxèxyyy:yByXynyÈyÚyèyöy zz4zBzNzXzhzvz†zÖ{ÈzÞzøz{({@{Z{n{ˆ{–{¤{²{¾{Ê{â{ì{ø{||(|4|J|Z|j|||Ž|¦|x2x$xôwx®yœyŠyDestroyBlobGetNPPBlobTable.SetBoolInBlobCreateBlobCreateNPPInterfaceNPPTools.dllîGlobalAllocõGlobalFreeÀGetSystemTimeAsFileTimeGLeaveCriticalSection SetEventEnterCriticalSectionHLoadLibraryAßGetVersionExAzDeleteCriticalSection.CloseHandleICreateEventAInitializeCriticalSectionISleepƒOutputDebugStringA…WaitForSingleObjectÄResetEventKERNEL32.dllhCoUninitialize;CoInitializeEx:CoInitializeole32.dllGetCommandLineAÞGetVersion¯ExitProcessQTerminateProcess:GetCurrentProcess>GetCurrentThreadIdYTlsSetValueVTlsAllocWTlsFreeSetLastErrorXTlsGetValueiGetLastErrorSetHandleCount±GetStdHandle^GetFileType¯GetStartupInfoAuGetModuleFileNameAíFreeEnvironmentStringsAîFreeEnvironmentStringsW‰WideCharToMultiByteMGetEnvironmentStringsOGetEnvironmentStringsWwGetModuleHandleAPGetEnvironmentVariableA HeapDestroyHeapCreatexVirtualFree HeapFree—WriteFileHeapAllocüGetCPInfoõGetACP‹GetOEMCPuVirtualAllocHeapReAlloc˜GetProcAddressÌRtlUnwindkMultiByteToWideChar:LCMapStringA;LCMapStringW²GetStringTypeAµGetStringTypeWInterlockedDecrement"InterlockedIncrementNPßKV} è|}@}ÐPЀàp pÀd}z}}¢}·}Î}ä}û}~"~:~ WanPacket.dllWanPacketCloseAdapterWanPacketGetReadEventWanPacketGetStatsWanPacketOpenAdapterWanPacketReceivePacketWanPacketSetBpfFilterWanPacketSetBufferSizeWanPacketSetMinToCopyWanPacketSetModeWanPacketSetReadTimeoutWanPacketTestAdapterÓ<LocationDial-up ConnectionNPPConfigIRTCnpp\ndisnpp.dllWanPacketCloseAdapter: Severe error, IRTC::Release failed WanPacketCloseAdapter: Severe error, IRTC::Disconnect failed WanPacketCloseAdapter: Severe error, IRTC::Stop failed `a (0!)1€@HP±%5E-=M ,<\Ll|$4TDdt„‡P&ÿÿÿÿÿÿÿÿ às´s ˆs ds8ssär¸r€rXr rèqÀqx°qy qzqüŒqÿ|q­0­H­­À À–ÀÀŽÀÀÀ‘À’À“Àx ¤`‚y‚!¦ß¡¥Ÿàü@~€ü¨Á£Ú£ þ@þµÁ£Ú£ þAþ¶Ï¢ä¢å¢è¢[þ@~¡þQQÚ^Ú _ÚjÚ2ÓØÞàù1~þ „ „¸„¸„ÿÿÿÿÿÿÿÿðñ „à “        ! 5A CPR S WY l m pr € ‚ ƒ„ ‘)ž ¡¤ § ·Î×  R¦R¦ ((((( H„„„„„„„„„„‚‚‚‚‚‚ .CCCx©Dv@v>”>˜>œ> >¤>¨>¬>°>´>¸>¼>À>Ä>È>Ì>Ð>Ô>Ø>Ü>à>ä>è>ì>ð>ô>ø>ü>??? ????? ?$?(?,?0?4?8?6C6{6‡6Ž6ž6¤6«6µ6Î6Ö6Û6ç6ì6 77I7Q7k7q7‚7›7§7­7º7Ê7Ð7Ø7ö7ü7 8$8.8G8©8Á8Ç8ñ8÷89-9_9f9{9­9·9Ø9í9:;:I:z:€::®:Ó:â:ñ:#;3;v;‚;Œ; ;®;»;À;Æ;!<(>$>c>³>Æ>?!?c?’?˜?Ñ?ø?0l0¤0³0Ö0Ü0è0ø0ÿ01 131?1G1O1_1v1‚1ˆ1–1¥1·1Ý1ê1ø122=2L2Ž2¢2À2Ì2è2ý233$3*323:3B3N3S3_3g3o3w33•33¥3­3À3È3õ34 4&42474„4’4Õ45$525o5t5˜596?6T6–6›6´6Â67s7y7949A9N9a9j9v9¨9º9É9ê9ð9::&:+:3:J:_:e:m:u:€:®:º:Ä:Ï:Ù:ã:é:,;6;;;@;E;^;d;Ó;Ù;÷;<<08><>@>D>ª>µ>Ð>×>Ü>à>ä>?+?]?d?h?l?p?t?x?|?€?Ê?Ð?Ô?Ø?Ü?@ÀV0n01*1B1U144%42494A4G4M4X4`4°6¾6Ä6Þ6ã6ò6ø677%787C7I7N7T7a7~7„77”77¢7²7¸7ü7¢8:š:¢:µ:»:Ñ:Ø:Þ:è:î:ó:ù: ;;,;=;C;V;¸;b:>G>§>Á>B?H?a?Pð0%040•0ê0;1‰2’2˜2¤2©2³2º2Â2È2Ï2Ô2å234”4Õ4>5X5a5^6c6‚66œ6¦6°6¸6Æ6ä67797‘7§7Ú7B8g8­8²8Î8á8è8ú899#969N9n9Ä9Ö9þ9:!:':-:n: :´:È: ;H;W;è;<<<<<$>(>,>0>4>8><>@>Š>>”>˜>œ>`(0V0\0j0¹0é0D1J1X1¶1Ë233(3d3Æ3p x4„44œ4¨4´455555 5€@ 01Ä1Ì1Ô1Ü1ä1ì1ô1ü12 222$2,242<2D2L2T2t2„2”2 4¤4¨4¬4 €À4H6L6p9x9|9€9„9ˆ9Œ99”9˜9œ9 9¤9¨9¬9°9´9¸9¼9À9Ä9È9Ì9Ð9Ô9Ø9Ü9à9ä9è9ì9ð9ô9ø9ü9::: ::::: :0:4:8:<:@:D:H:L:P:T:`:ü:;NB10NPßKD:\temp\winpcap\packetNtx\Dll\WanPacket\Release\WanPacket.pdbsnort-2.9.15.1/src/win32/WIN32-Prj/npptools.dll0000555000175200017520000015300013571422610015501 00000000000000MZÿÿ¸@𺴠Í!¸LÍ!This program cannot be run in DOS mode. $ü½áYÓ²YÓ²YÓ²š’ܲZÓ²š’Ž²VÓ²YÒ²5Ó²š’²XÓ²š’²XÓ²š’Œ²IӲ𒳲SӲ𒉲XÓ²RichYÓ²PEL¡Hà!  ¶0²ÐaË @¿•€¶ ðh  Àø@°¤´.textÕµ¶ `.data8к@ÀFINDSHARà¼@À.rsrch ð ¾@@.relocV  Ê@BMRöDH” HS² H^,¡Hk,¡Hx¡H‚¡HŒ¡H™MFC42u.DLLmsvcrt.dllADVAPI32.dllKERNEL32.dllNTDLL.DLLole32.dllOLEAUT32.dllUSER32.dll«zÝw0{ßw‚|ßw£yßwW×Ýw€BÞw¸ïÝwBxÝw›ßw–QÞwäéÝwlÝw×êÝwzO|_µ€|Óƒ|Û®€|0®€|{€|n¬€|F¾€|ˆœ€|½‘|gî€|ÉNƒ|i8|…Þ€|º€|·¤€|.“€|¸—€|é€|€|j>†|ýI„|˜€|Ÿ€| ®€|°™€| ÿ|Gé€|¤‘|Q¬€|·$€|0%€|þ|×›€||(€|| |•¹€| ”€|€›‘|¹Mƒ|à|Z‘|ÿ?€_èH€_¢KwðHwPIwWw€HwnCB~¶©A~¦ˆA~6žA~­¨A~NJB~ȘB~´B~ÉB~š’B~»ÂB~«GB~«®B~ {ÃMrÃM"ÂÀMNbÃM”\ÂM¿dÃMzÃMPzÃM°rÃMú'ÁMã~ÃM”~ÃMÌÃM1<ÂMa~ÃM¸~ÃMà{ÃMÂÁMÄÁMgÂMØ#ÅMQNÂMøMÂM1ùÂM~Pw‹VH%@@ÿÿÿÿMaQaÿÿÿÿ("a,"a %%%d.%ds---------- %%%d.%ds(%%8.8X) %%%d.%ds%%%d.%ds|%%8.8X| " %%%d.%ds%%%d.%ds|%%8.8X| ->"pCategoryTable[%d]pTagTable[%d]pValue[%d]p?????[%d]pName[%d]EntriesTableTypeMutexpOwnerTableVersionSignature=:%s %02X%02X%02X%02X%02X%02X%dÿÿÿÿ¬6a°6aFALSETRUEÿÿÿÿŽ7a’7aÿÿÿÿP8aT8aNodeNameLinkSpeedCommentTimeStampScaleFactorFlagsMaxFrameSizePModeMacTypeETHERNETTOKENRINGFDDIIP/1394UNKNOWNNetworkInfoCurrentAddressMacAddressNPPLocationDial-up ConnectionATM{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}ÿÿÿÿ’Aa–AaInProcServer32CLSIDClassID%s%d.%d%02X%02X%02X%02X.%02X%02X%02X%02X%02X%02X%d.%d.%d.%d%s,LOCAL ONLYVINES IPHIGHESTXNSIPXIPANY%s,%sANY GROUPÿÿÿÿcHagHa,)NOTIFYSTOPPAUSEÿÿÿÿFJaJJa25 PERCENT50 PERCENT75 PERCENT100 PERCENT,BUFFER CONTENTÿÿÿÿ…La‰La%02x%hdNONEFRAMEEFFECTIVENOTÿÿÿÿ€Oa„Oa%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x,%d,%d,%04xSaps,%02XEtypesConfig,%04XEXCLUDE ALL EXCEPTINCLUDE ALL EXCEPTÿÿÿÿ2Va6VaÿÿÿÿIWaMWaRemoteRemoteComputerINCLUDEEXCLUDE%s%dAddressPairÿÿÿÿ\a \aPatternMatch)),Pattern%d,AND(OR(ÿÿÿÿn_ar_aTrigger4Trigger3Trigger2PATTERN MATCHTrigger1Trigger0DATATriggerÿÿÿÿdada\Local%hsFinderRootJustificationszUrlszMachineszDescriptionszEventNameszSourceNameSysTimeNumColumnsSeverityFlagsEventIdentVersionReservedNameNETMON2__NameSpace\\.\rootroot\Netmon2__ExtrinsicEventbStr%02x dblVallValNMType%S_%dszColumnName__CLASSNMEVENTDATAGetSystemWindowsDirectoryW\kernel32.dll%sIXmtIStsIRTCIESPIDdCHtmlHelpWHHCTRL.OCXNETMON2.CHM/help/%10hs,%10hs, %hs%10hs,%10hs,%hs,%hsNameUnknownDisplayTypesSupportedEventMessageFileSYSTEM\CurrentControlSet\Services\EventLog\Application\*.dll\npp\ProcNameGetConfigBlobDLLNameGetNPPBlobsSpecialsøE:ЉªK.$‡¦ÜsψMªK.$H ÐapaRSDSÞù¨‰k34@ªÚ/Š/¢¸npptools.pdb&³Ñ³à³ï³þ³ ´&´@´jhàaè3–ƒeüjj‹=¬aÿ×P‹¨aÿÓ‹u‰3É;Át4ÇBlob‹Ç@QQQÿ¤a‹‰A ‹ƒx uPjÿ×Pÿ aƒ&ƒMüÿjëYÿœa‹‰AjPjÿ×PÿÓ‹‰A‹‹H3Û;ËuPSÿ×Pÿ a‰jXƒMüÿë Ç‹‹@‰X3Àëè3À@ËeèƒMüÿjLX试ÃÌÌÌÌÌ‹ÿU‹ìV‹u…öu¸èëyS»Blob9t¸éëgW‹=œaÿ×9Ft3ÀPPPÿ¤a…À‰F ujXëAÿ׉Fhèÿv ÿ´aƒøÿuj`ëá9t¿éë ƒ~v¿êÿv ÿ°a‹Çë3À_[^]ÃÌÌÌÌÌ‹ÿU‹ì‹E…Àu¸è]Ã8Blobt¸é]Ãxv¸ê]Ãÿp ÿ°aƒøt]ÿ%¸a3À]ÃÌÌÌÌÌ‹ÿU‹ìQQSV‹u3ÛV‰]øèÿÿÿ;ÃY…ò9]Wtÿuèðþÿÿ‹ø;ûYt Vèxÿÿÿ‹Çé΋v3ÿ9^v^ÿu ÿ3ÿTa…ÀYYtw GƒÃ ;~rä¸î霃eü‹t†ƒ~va~‹E‹€9t‹Øÿ0ÿ7ÿTa…ÀYYt4ƒÃ‹ €9‹Ãuäƒ}ÇEøt‹Ghðÿpÿ7ÿu ÿuèñƒÄÿEü‹EüƒÇ ;Fr¢ƒ}t ÿuè¾þÿÿYÿuèµþÿÿ‹EøH÷ØÀ%üÿÿðY_^[ÉÃÌÌÌÌÌ‹ÿU‹ìƒì W‹}Wèñýÿÿ…ÀY…‹GƒeìƒxS‹¬aV‹5 a‰Eè†ËƒÀ‰Eø‹Eø‹8ƒeðƒ‰}àvxƒÇ‹ƒeôƒx‰Eäv;ƒÀ‰Eü‹EüÿpjÿÓPÿÖ‹Eüÿ0ƒ`jÿÓPÿÖ‹Eüƒ ÿEô‹Eä‹MôƒEü ;HrËÿ7jÿÓPÿÖÿwøƒ'jÿÓPÿÖƒgøÿEð‹Eà‹MðƒÇ ;Hr‹‹Eøÿ0jÿÓPÿÖ‹}øÿwøƒ'jÿÓPÿÖƒgøÿEì‹Eè‹MìƒÇ ;H‰}ø‚>ÿÿÿ‹}PjÿÓPÿÖÿw ÿ¼aÿu3À««««j«ÿÓPÿÖ^3À[_ÉÃÌÌÌÌÌjhðaè/’ƒeäƒeü‹EPŠ@„Éuù+‹ð‰u؃Müÿ…ö„f‹}WèüÿÿY…À…YFVj‹¬aÿÓPÿ¨a‹Ð‰UÜ…Òuj^é‹E+Њˆ @„ÉuöwEäPÿu ÿ6èÙD‹øƒ}äu@jWÿu VèIE‰Eà…ÀtÿuÜjÿÓPÿ a‹uàéÇÁà‹‹TjY‰ ‹‰L ‹6t†EäPÿuÿ6èzD‹øƒ}äu/jWÿuVèêD‰Eà…Àu¡Áà‹‹LÇ‹ÇD ‹6t†EäPÿuÿ6è,D‹ø3À9Eät ‹ÿtŠPÿÓPÿ aëPWÿuVè‡D‰Eà…À…:ÿÿÿÁà‹‹U܉T‹3ö‰t ÿuèØûÿÿY‹Æë3À@ËeèƒMüÿ¸ôèÒÃÌÌÌÌÌ‹ÿU‹ìQQSW‹}3ÛW‰]üè ûÿÿ;ÃYuxV‹wEüPÿu VèŒC9]üu»ìëQ@‹t†EüPÿuVèlC9]ütà@‹t†EüPÿuVèSC9]ütÇ@‹t†‹ÆHŠ@:Óuù+Á‰Eøt­‹E‰0Wè(ûÿÿY‹Ã^_[ÉÃÌÌÌÌÌ‹ÿU‹ìƒì@V3öW‹}W‰uì‰uä‰uà‰uè‰uô‰uü‰uøè\úÿÿ;ÆY…Å‹S‹](‹ƒøÿ‰}È…½9u „¨EøPÿu 3ÛCW‰]ìè¸B9uø‰Eè„w9u@‹|‡tnEøPÿu‰]äWèB9uø‰Eô„O9u@‹|‡tEøPÿu‰]àWèhB9uø‰Eü„'‹}È‹](ÿuàÿuäÿuìè^Eÿuü‰ÿuôÿuèSè}E‹Müë@9utѾíéó9uuñ9uuìëÁMüQMôQMèQMàQMäQMìQPè€E‹MüA‰Mü9uì‹EèPu‹W;‰U؉EðƒŸ@D‡‹}ô‰EÜ9uä‹EÜ‹‰EÀWu‹P;ú‰UÌs]D‰EÐ9uà‹Au‹C;ȉEÔ‹ñs'ILƒ‹P‰UÄŠ@„Òuù+EĉEÄuQFƒÁ ;uÔrà‹EÐ3ÉGƒÀ 3ö;}̉Mü‰EÐr­ƒEÜ 3ÿÿEð‹Eð;E؉}ô‚qÿÿÿ‹](‰3¾ìÿuè'ùÿÿY‹Æ[_^ÉÃVWÿuðÿu(èYD‹Eð‹MÈ‹U @‹D‹M‰‹MÀ‹D‹M‰vƒ‹H‰ ‹@‹M$‰3öë¨ÌÌÌÌÌ‹ÿU‹ìQQV‹uW3ÿV‰}üè&øÿÿ;ÇY…Á‹v;÷‰uøu ¾îé¢SEüPÿu Vè‘@9}ü‹Øu ¾îé‚9}u9}t¾íëqSVèÆBëf[‹|†EüPÿuWèR@ƒ}ü‹ðu¾ïëEƒ}u VWèHBjÿë)v‹|‡EüPÿuWè@ƒ}üu¾ìëPWèÒAVSÿuøèªB3ö[ÿuèô÷ÿÿY‹Æ_^ÉÃÌÌÌÌÌ‹ÿU‹ìQƒeüjEüPjhüaÿuÿÀa÷ØÀ@ÉÂÌÌÌÌÌ‹ÿU‹ìì¡ Ðaƒ¥øýÿÿV‹5¤a‰Eü‹E W‹}…PP…üýÿÿh(aPÿÖha…üýÿÿP…üþÿÿPÿÖ…üþÿÿƒÄHŠ@„Òuù+ÁjøýÿÿQP…üþÿÿPWÿÀa‹Mü÷ØÀ_@^èy‰ÉÂÌÌÌÌÌ‹ÿU‹ìì¡ Ðaƒ¥øýÿÿS‹]V‹5¤a‰Eü‹EW‹} …PP…üýÿÿh<aPÿÖWha…üýÿÿP…üþÿÿPÿÖ…üþÿÿƒÄ pŠ@„ÉuùjøýÿÿQ+ÆP…üþÿÿPSÿÀa‹Mü÷Ø_À^@[èڈɠÌÌÌÌÌ‹ÿU‹ìì¡ Ðaƒ¥øýÿÿS‹]V‹5¤aW‹} ‰Eü‹EjÁàjPP…üýÿÿhPaPÿÖÿu…üýÿÿWhaP…üþÿÿPÿÖ…üþÿÿƒÄ,pŠ@„ÉuùjøýÿÿQ+ÆP…üþÿÿPSÿÀa‹Mü÷Ø_À^@[è8ˆÉÂÌÌÌÌÌ‹ÿU‹ìì ¡ Ðaƒ¥ôýÿÿS‹]V‹5¤a‰Eü‹EW‹} ‰…øýÿÿ‹EjÁàjPP…üýÿÿhpaPÿÖSWha…üýÿÿP…üþÿÿPÿÖ…üþÿÿƒÄ,pŠ@„Éuùj+Æ‹5ÀaôýÿÿQP…üþÿÿPÿµøýÿÿÿÖ…Àt%‹ÃxŠ@„ÉuùjôýÿÿQ+ÇPSÿµøýÿÿÿÖ…Àu3À@ëj…ôýÿÿPjhlaÿµøýÿÿÿÖ÷ØÀ@‹Mü_^[èB‡ÉÂÌÌÌÌÌ‹ÿU‹ìì¡ ÐaS‹] V‹uWÿu‰EüSV‰µðþÿÿèýÿÿÿu‹øVèùüÿÿÿu øÿ3hàaVèþÿÿÿu øVèÜüÿÿÿu øÿshØaVèþÿÿÿu øVè¾üÿÿƒ¥ôþÿÿ øƒ{‰½øþÿÿ†‹5¤a{ÿµôþÿÿ…üþÿÿhÌaPÿÖƒÄ ÿu…üþÿÿÿwøPÿµðþÿÿèGþÿÿÿu …øþÿÿÿµðþÿÿèYüÿÿ …øþÿÿ‹Hÿµôþÿÿt>Ht4H…üþÿÿthÀaë6h´aPÿÖƒÄ ÿu…üþÿÿÿ7Pÿµðþÿÿèíýÿÿë/h¤aëha…üþÿÿPÿÖƒÄ ÿu…üþÿÿÿ7Pÿµðþÿÿèýÿÿÿu …øþÿÿÿµðþÿÿèÎûÿÿ …øþÿÿÿ…ôþÿÿ‹…ôþÿÿƒÇ ;C‚ÿÿÿ‹½øþÿÿ‹µðþÿÿVèpûÿÿ‹Mü Ç_^[èš…É ÌÌÌÌÌ‹ÿU‹ìƒìSV‹u‹FV‰Eðè”òÿÿ3Û;ÃY…GWSh€€jSjh@ÿu ÿÄa‹øƒÿÿu ÿ¸a‹ØéSÿ6haWè`üÿÿSW‹ðèûÿÿSÿu ðWè¬ûÿÿSW ðè ûÿÿS ð‹EÿphaWè.üÿÿSW ðèíúÿÿS ð‹EÿphôaWèüÿÿSW ðèÐúÿÿS ð‹Eÿp hìaWèôûÿÿSW ðè³úÿÿW ðè}úÿÿ Æus‹uðjVWèkýÿÿ;Ãuc9^‰]ôv^ƒÆ‰uø‹Eø‹0jVWèKýÿÿ;ÃuC9^‰]üv'F‰E ‹E ‹jPWè+ýÿÿ;Ãu#ÿEü‹EüƒE ;FrßÿEô‹Eð‹MôƒEø ;Hr­ëjN[Wÿ¼a‹uVèÛñÿÿY‹Ã_^[ÉÂÌÌÌÌÌ‹ÿU‹ìƒìS‹] W3ÿS‰}üèñÿÿ;ÇYuuÿuèñÿÿ;ÇYuhƒMüÿVëÿuøÿuôÿuðÿuìÿuè%ôÿÿ‹ðƒÄ;÷u&EüPEøPEôPEðPEìPWWWSèFöÿÿ‹ðƒÄ$;÷t½ÿuèPñÿÿSèJñÿÿ‹Æ-ì÷ØYÀY#Æ^_[ÉÃÌÌÌÌÌ‹ÿU‹ìS‹]Sèðÿÿ…ÀYuCV‹u WVè¬ïÿÿ…ÀYt‹ðë$Sÿ6è5ÿÿÿ‹ø…ÿYYtSèóðÿÿÿ6èTòÿÿY‹Çë 3öSèßðÿÿ‹ÆY_^[]ÃÌÌÌÌÌ‹ÿU‹ìƒì S3ÛWSEàPSh?SSSÿu ‰]äÿu‰]è‰]ì‰]ô‰]à‰]ü‰]ø‰]ðÿ(a‹ø;û… ÿuèíïÿÿ;ÃY…ûVƒMðÿEðPEôPEìPEèPEäPSSSÿuè:õÿÿ‹5,aéœSEüPSh?SSSÿuäÿuàÿ(a‹ø;û…ƒSEøPSh?SSSÿuèÿuüÿ(a‹ø;ûuc‹EôxŠ@:Ëuù+Ç@PÿuôjSÿuìÿuøÿ0a‹ø;ûu:ÿuøÿÖÿuüÿÖEðPEôPEìPEèPEäPSSSÿu‰]ø‰]üè“ôÿÿƒÄ$…À„Yÿÿÿ9]ütÿuüÿÖ9]øtÿuøÿÖÿuàÿÖÿuè‚ïÿÿY^‹Ç_[ÉÃÌÌÌÌÌ‹ÿU‹ììH‹U¡ Ða‹M S‹aVW‰•Äûÿÿ•àûÿÿR3öh?V‰Eü‹EQ¿P‰µàûÿÿ‰µäûÿÿ‰µÜûÿÿ‰µØûÿÿ‰½èûÿÿÿÓ;Ɖ…Ìûÿÿ…ÿÿµÄûÿÿè•íÿÿ;ÆY…ë…¸ûÿÿPVVV…èûÿÿP…øþÿÿPVé§…äûÿÿPh?V…øþÿÿPÿµàûÿÿ‰µÐûÿÿÿÓ;Ɖ…Ìûÿÿ…‹…¸ûÿÿPVVV…èûÿÿP…ôýÿÿPVé …ÜûÿÿPh?V…ôýÿÿPÿµäûÿÿ‰µÔûÿÿ‰½ÈûÿÿÿÓ;Ɖ…Ìûÿÿ…í…ÈûÿÿP…ìûÿÿP…ÀûÿÿPV…èûÿÿP…ðüÿÿPVëf…ìûÿÿP…ðüÿÿP…ôýÿÿP…øþÿÿP‹…Äûÿÿÿ0èžðÿÿƒÄ…ÀuLÿ…Ôûÿÿ…ÈûÿÿP…ìûÿÿP…ÀûÿÿPV…èûÿÿP…ðüÿÿPÿµÔûÿÿ‰½ÈûÿÿÿµÜûÿÿ‰½èûÿÿÿ a…Àt„ÿµÜûÿÿÿ,aÿ…Ðûÿÿ…¸ûÿÿPVVV…èûÿÿP…ôýÿÿPÿµÐûÿÿÿµäûÿÿ‰½èûÿÿÿ$a…À„Ýþÿÿÿµäûÿÿÿ,aÿ…Øûÿÿ…¸ûÿÿPVVV…èûÿÿP…øþÿÿPÿµØûÿÿ‰½èûÿÿÿµàûÿÿÿ$a…À„Eþÿÿÿµàûÿÿÿ,a‹…Ìûÿÿ‹Mü_^[èKÉÃÌÌÌÌÌ‹ÿU‹ìƒì$Sÿu3Û‰]à‰]ä‰]è‰]ì‰]܉]ô‰]üè8ìÿÿ;ÃY…ËVSh€€jSjh@ÿu ÿÄaƒøÿ‰Eøuÿ¸aÿu‹ðè’ìÿÿ‹ÆéƒMÜÿEÜPEìPEèPEäPEàPSSSÿuèMñÿÿƒÄ$;ÉEð…,‹5ÀaW‹EàxŠ@:ËuùSMôQ+ÇPÿuàÿuøÿÖ…À„óSEôPj¿aWÿuøÿÖ…À„Ù‹EäHŠ@:ÓuùS+ÁMôQPÿuäÿuøÿÖ…À„´SEôPjWÿuøÿÖ…À„Ÿ‹EèxŠ@:ËuùSMôQ+ÇPÿuèÿuøÿÖ…Àt~SEôP3ÿGWhaÿuøÿÖ…Àtp‹EìxŠ@:ËuùSMôQ+ÇPÿuìÿuøÿÖ…ÀtFSEôP3ÿGWhüaÿuøÿÖ…Àt8EÜPEìPEèPEäPEàPSSSÿuè0ðÿÿƒÄ$;ÉEð„êþÿÿë ÇEüë‰}ü_}ðìu9]üu‰]ð9]üt ÿ¸a‰Eðÿuøÿ¼aÿuèþêÿÿ‹EðY^[ÉÃÌÌÌÌÌ‹ÿU‹ìƒì Wÿu3ÿ‰}ìèuéÿÿ;ÇY…ÞSVWh€jWWh€ÿu ÿÄa‹ðƒþÿ‰uôu ÿ¸a‹øéeWWWjWVÿÔa;ljEðuÿ¸aV‹øÿ¼aé=WWWjPÿÐa‹Ø;߉]øu ÿ¸a‹øé EìPVÿÌa‹ðƒþÿ„9}ì… Vjÿ¬aPÿ¨a;ljEüuj_éÄ‹Mø;ȉEàƒƒ‹5Ha¿aë‹]è€;tlÿuühaSÿLa‹EüƒÄ HŠ@„Òuù+ÁWÿuüD‰EèÿÖ‹ØÆCWSÿÖÆ@haP‰EäÿÖÆ@Pÿuä‹ESÿuüÿ0è4ìÿÿƒÄ,…Àu8‹Eà9EèrŒ3ÿÿuüWÿ¬aPÿ aÿuøÿpaÿuô‹5¼aÿÖÿuðÿÖ3Àëa‹øÿuøÿpaÿuô‹5¼aÿÖÿuðÿÖ‹Eÿ0èšêÿÿY‹Çë7ÿ¸aÿuø‹Øÿpaÿuô‹5¼aÿÖÿuðÿÖ‹Eÿ0èjêÿÿ;ßYujXë‹Ã^[_ÉÃÌÌÌÌÌ‹ÿU‹ìì¡ ÐaS‹]V‹u‰Eü‹EW‹} V‰…øþÿÿè)èÿÿ…ÀYu=j …üþÿÿPÿuÿPa…üþÿÿPÿµøþÿÿSWVè0ëÿÿƒÄ …Àt‹øë3ÿVèèÿÿY‹Ç‹Mü_^[èÀzÉÃÌÌÌÌÌ‹ÿU‹ìì ¡ ÐaS‹] ‰Eü‹EV‹uW‹}‰…øþÿÿ‹EW‰…ôþÿÿèžçÿÿ…ÀYu_¶FP¶FP¶FP¶FP¶FP¶P…üþÿÿh aPÿ a…üþÿÿPÿµôþÿÿÿµøþÿÿSWèƒêÿÿƒÄ4…Àt‹ðë3öWèÒçÿÿY‹Æ‹Mü_^[èzÉÃÌÌÌÌÌjh@aèŠ|3ö‰uä‹}WèçÿÿY;ÆuhEäPÿuÿuÿu WèÓëÿÿƒÄ;Æt‹ðë&‰uüÿuh<aÿuäÿLaƒÄ ‰EàƒøtWëƒMüÿWèTçÿÿY‹Æë3À@Ëeèÿuè@çÿÿYƒMüÿ¸òèE|ÃÌÌÌÌÌ‹ÿU‹ìV‹uVè‡æÿÿ…ÀYu09EWthTaëhLaÿuÿuÿu Vè”éÿÿƒÄV‹øèëæÿÿY‹Ç_^]ÃÌÌÌÌÌj h`aè¬{3ö‰uäÿuè1æÿÿY;ÆumEäPÿuÿuÿu ÿuèôêÿÿƒÄ‰uü;ÆuhLaÿuäÿTaYY…Àt ‹EÇë‹E‰0ƒMüÿÿuèræÿÿY3Àë3À@Ëeèÿuè^æÿÿYƒMüÿ¸òèc{ÃÌÌÌÌÌj,hpaè{3ö‰uä‹}WèšåÿÿY;Æ…”EäPÿuÿuÿu Wè[êÿÿƒÄ;Æt‹ðëR‰uüEØPEÔPEÐPEÌPEÈPEÄPh aÿuäÿLaƒÄ ‰EàƒøtWë03À‰EÜ;Eàs ŠL…Ä‹Uˆ @ëëƒMüÿWè°åÿÿY‹Æë3À@ËeèÿuèœåÿÿYƒMüÿ¸òè¡zÃÌÌÌÌÌ‹ÿU‹ìƒìSÿu3Û‰]è‰]ì‰]ð‰]ü‰]ô‰]øèÍäÿÿ;ÃY…܃MøÿEøPEôPEüPEðPEìPSÿuÿu ÿuèêÿÿƒÄ$…À…•VW‹}ë3‹Mü‹ðŠŠÂ:u:ÃtŠQŠÂ:Vu AAFF:Ãuâ3ÀëÀƒØÿ;Ãt.ƒÇ‹8uÇ9]ÇEèthñÿuüÿuÿu ÿuèÙûÿÿƒÄEøPEôPEüPEðPEìPSÿuÿu ÿuè„éÿÿƒÄ$…À„oÿÿÿ_^ÿuèŠäÿÿ‹Eè÷ØÀY%ñ[ÉÃÌÌÌÌÌ‹ÿU‹ìì¡ Ða‰Eü‹EW‹} P‰…ôþÿÿ‰½ðþÿÿè´ãÿÿ…ÀY…Œ‹G(SVÁèƒàPhDa¾8aV»4aSÿµôþÿÿèíüÿÿƒÄ…À‰…øþÿÿ…?Wh(aVSÿµôþÿÿèŠûÿÿƒÄ…À‰…øþÿÿ…GPha¾ aVSÿµôþÿÿè^ûÿÿƒÄ…À‰…øþÿÿ…ï‹G Ht`HtLHt3À»´a‹=HaƒøƒP À4Žfƒf@‰…°þÿÿPhahüa…äþÿÿPÿ¤a…ÔþÿÿP…äþÿÿPh|ah4aÿµàþÿÿè#ÈÿÿƒÄ$…À…ø!EüSÿµÔþÿÿÿ׉…Üþÿÿ+…Ôþÿÿ‰…¼þÿÿÿ…ÜþÿÿSÿµÜþÿÿÿ׉…Ìþÿÿ+…Üþÿÿ‰…´þÿÿÿ…ÌþÿÿSÿµÌþÿÿÿ׉…Ðþÿÿÿ…ÐþÿÿSÿµÐþÿÿÿ׉…Äþÿÿ+…Ðþÿÿ‰…¨þÿÿÿ…Äþÿÿÿµ¼þÿÿhìaÿµÔþÿÿÿ\aƒÄ,…Àu f‹Ff%ûÿë*ÿµ¼þÿÿhôaÿµÔþÿÿÿ\aƒÄ …À…Úf‹Ff f‰Ff f‰F…ÀþÿÿP…ÈþÿÿPFPÿµÌþÿÿÿµ´þÿÿÿµÜþÿÿè±êÿÿ‰…¬þÿÿ…À„ƒ½Èþÿÿt f‹Ff%ýÿf‰F…ÀþÿÿP…ÈþÿÿPF PÿµÄþÿÿÿµ¨þÿÿÿµÐþÿÿèeêÿÿ‰…¬þÿÿ…ÀtGƒ½Àþÿÿt f‹Ff f‰Fƒ½Èþÿÿt f‹Ff%þÿf‰F‹…¸þÿÿÿƒMüÿ‹…°þÿÿ‹µ¸þÿÿéþÿÿÿµàþÿÿè&ÂÿÿYƒ½Øþÿÿt9hò…äþÿÿPh|ah4aÿµØþÿÿèÙÿÿƒÄë3À@ËeèÿµàþÿÿèäÁÿÿYƒMüÿ¸òëÿµàþÿÿèÍÁÿÿY3À‹MäèTèÑVÃÌÌÌÌÌ‹ÿU‹ìì¡ Ða‹M‰Eü‹EV‹u P‰…ðýÿÿ‰µèýÿÿ‰äýÿÿÇ…øýÿÿèãÀÿÿ…ÀY…ËS‹¤aW…üþÿÿhHaPÿÓƒ¥ìýÿÿƒ>YY†5V‰•ôýÿÿƒ½øýÿÿ‡‹ …É„éƒùv½üþÿÿOŠGG„Àuø¾@a¥¤3ö…Ɇzƒ½øýÿÿ‡€…üþÿÿHŠ@„Òuùÿµøýÿÿ+Á„üþÿÿh<aPÿÓÿµøýÿÿ…üýÿÿh4ahüaPÿÓƒÄÿµäýÿÿ…üýÿÿWjPh|ah4aÿµðýÿÿè5òÿÿÿ…øýÿÿ‹…ôýÿÿFƒÇ;0‚sÿÿÿ‹…ôýÿÿƒ8v#…üþÿÿPŠ@„Éuù+„ûþÿÿh0aPÿÓYY‹µèýÿÿÿ…ìýÿÿ‹•ôýÿÿ‹…ìýÿÿƒÂp;‰•ôýÿÿ‚Ýþÿÿƒ½øýÿÿu½üþÿÿOŠGG„Àuø¾,af¥ë#…üþÿÿPŠ@„Éuù+„ûþÿÿh,aPÿÓYY…üþÿÿPhah|ah4aÿµðýÿÿèTÂÿÿÿµðýÿÿè«¿ÿÿƒÄ_3À[‹Mü^èêQÉÃÌÌÌÌÌjhPaèaT3À‰E܉Eà‰Eü‹] ‰‹M‰‹u‹ÆHŠ@„Òuù+Á|0ÿ‰}Ø‹Ç+ƃøŒÈjhHaVÿ\aƒÄ …À…¯ƒÆ‰uä€?)… j^9}䃄‹Ç+Eä;Æ|ZVh@aÿuäÿ\aƒÄ …ÀuDu!Eàuä9}äs&‹Eä€8)tÿuÿuàÿuÜWEäPèyéÿÿ…ÀtHÿEàÿëÕÿEä‹Eä€8,uÿEäëÿuÿuàÿuÜWEäPèKéÿÿ…ÀtÿÿEÜésÿÿÿƒMüÿ3À@ë 3À@ËeèƒMüÿ3ÀèSÂÌÌÌÌÌ‹ÿU‹ìS‹] ƒ;u3ÀéäÿuèÁ½ÿÿ…ÀY…ÓöCVW¾4a¿°at&h¨ahœaWVÿuèÅÀÿÿƒÄ…À‰E tPhœaëChèaëØ¶CHtJHtHtDHt ¾òémÿuÿs%haWVÿuèGêÿÿ…À‰E t8PhaWVÿuèÜÔÿÿ‹u ƒÄé6ÿuC Ph€ahaWVÿuèMïÿÿëÁŠC„À† <v@<t%<…ùÿuC Ph€ahtaWVÿuèïÿÿë/ÿuÿs%htaWVÿuè»éÿÿëÿu3ÀŠCPhtaWVÿuè‘èÿÿ…À‰E t PhtaéUÿÿÿŠC„À†<v"<‡„ÿu3ÀŠCPhhaWVÿuèPèÿÿëC-€8t%PhhaWVÿuè|¿ÿÿƒÄ…À‰E t Phhaé÷þÿÿŠC„Àv6<v.<w.ƒÃ-€;t"S»\aSWVÿuè?¿ÿÿƒÄ…À‰E tPSé¾þÿÿ3öë¾óÿuè¼ÿÿY_‹Æ^[]ÃÌÌÌÌÌjh¸aè?Q3ÿ‰}à‰}Ü‹u ‰>‰~ÿuè¹»ÿÿY;Ç…c‰}üEàPhœa»°aS¿4aWÿuèmÀÿÿƒÄ‰Eä…Àujh¨aÿuàÿdaƒÄ …ÀuƒNëƒfþEàPhaSWÿuè/ÀÿÿƒÄ‰Eä…À…$j h€aÿuàÿdaƒÄ …À…ÆFÿuF Ph€ahaSWÿuèOêÿÿ‰Eä…À…ßEàPhtaSWÿuèÉ¿ÿÿƒÄ‰Eä…À…¾j h€aÿuàÿdaƒÄ …Àue€~„MÆFÿuF Ph€ahtaSWÿuèãéÿÿëujh¸aÿuàÿdaƒÄ …À…ÆFÿuF%PhaSWÿuè‡èÿÿéXÿÿÿjh¸aÿuàÿdaƒÄ …ÀuA€~„ÑÆFÿuF%PhtaSWÿuèGèÿÿ‰Eä…Àt:‹ðÿu諺ÿÿYƒMüÿ‹Æé½ÿuFPhtaSWÿuè-æÿÿ‰Eä…ÀuAÇE܃}ÜuFÿuFPhhaSWÿuèæÿÿ‰Eä…ÀuF-Ph\aë'ƒ}äuÇÿuè9ºÿÿYƒMüÿ‹EäëMF-PhhaSWÿuèd¾ÿÿƒÄ‰Eä=ìuÂÆF-ƒeäë¾¾óéHÿÿÿ3À@Ëeèÿuèì¹ÿÿYƒMüÿ¸òèñNÃÌÌÌÌÌ‹ÿU‹ìì8¡ Ða‹MV‰Eü‹EW‹} 3öP‰…ôþÿÿ‰ðþÿÿ‰µìþÿÿ‰µøþÿÿè¹ÿÿ;ÆY…€j‰7GY‰0ƒÀpIuøS…ìþÿÿPha¾|aV»4aSÿµôþÿÿ褽ÿÿƒÄ=ì„-…Àt‹ðé$…ÈþÿÿPW…øþÿÿPÿµìþÿÿè•ùÿÿ…Àu7ÿµôþÿÿè¹ÿÿƒ½ðþÿÿY¿òtWhaVSÿµðþÿÿè ÐÿÿƒÄ‹ÇéÝjX9…øþÿÿv‰…øþÿÿ3ö9µøþÿÿ†®¡4a‰…üþÿÿ¡8a‰…ÿÿÿ…üþÿÿHŠ@„Òuù+Áj „üþÿÿNPQ‰èþÿÿÿPa‹ÆÁà´Èþÿÿ‹„Ìþÿÿ‹kÀkÉpƒÄ ÿµðþÿÿÇDPj…üþÿÿPh|aSÿµôþÿÿèøæÿÿ…À…öþÿÿ‹‹µèþÿÿkÀpD8ÿÿ;µøþÿÿ‚Rÿÿÿ3öÿµôþÿÿè¸ÿÿY‹Æ[‹Mü_^èUJÉÃÌÌÌÌÌ‹ÿU‹ìQƒeüS‹]ƒ{VWvC{‹u ‹ŠŠÐ:u„ÒtŠAŠÐ:Fu AAFF„Òuâ3ÉëɃÙÿ…Ét )ÿEü‹EüƒÇ ;CrÀ‹Eƒ ‹C_^[É ‹EÇë‹Eƒ ‹EüëãÌÌÌÌÌ‹ÿU‹ìQ‹E ƒeüHŠ@„ÒuùSV‹5¬a+ÁW@PjÿÖ‹=¨aPÿ׋؅Ûte‹E ‹Ó+Њˆ @„Éuöƒ}tjPjÿÖPÿ×…À‰Eüt2‹}ÿ7ÿÜa‹‹J I ;Ás'ƒÀPPRjÿÖPÿØa…ÀuSjÿÖPÿ ajXëP‰‹‹A‹u;Æv +Æ@vÁà ‘PAPƒÁQÿhaƒÄ ‹vÁàƒ}‰\t ‹‹Uü‰T‹?ÿG3À_^[ÉÂÌÌÌÌÌ‹ÿU‹ì‹U V‹u‹FJ;Áv$+Â@ R…ôÿÿÿ ŽPAPƒÁQÿhaƒÄ ÿN^]ÂÌÌÌÌÌ‹ÿU‹ì‹E ‹MSVW‹=¬a@4ÿvjÿ׋ aPÿÓÿvƒfjÿ×PÿÓƒf_^[]étÿÿÿÌÌÌÌÌ‹ÿU‹ì‹MS‹] V[W‹|‹wëVWè•ÿÿÿNƒþÿuóWjÿ¬aPÿ aSÿuè/ÿÿÿ_^[]ÂÌÌÌÌÌ‹ÿU‹ì‹MS‹] V[W‹|‹wëVWè“ÿÿÿNƒþÿuóWjÿ¬aPÿ aSÿuèãþÿÿ_^[]ÂÌÌÌÌÌ‹ÿU‹ì‹E ‹MS‹¬a@V‹t‹EƒøÿW‹= at@‹D†ƒxu*PjÿÓPÿ×ÿuVèþÿÿƒ~uVjÿÓPÿ×ÿu ÿuèwþÿÿ_^[] ÌÌÌÌÌ‹ÿU‹ì3É3À9Mt¸€9M t @9Mt ] ÌÌÌÌÌ‹ÿU‹ì‹U ‹M¸ÿ#ÐÁâ áÿ Ñ‹MV‹1æàÁâ Ö‹u#ð Ö‰^]ÂÌÌÌÌÌ‹ÿU‹ì‹E‹U ‹ÈÁé‰ ‹U‹ÈÁéƒá‰ ‹U‹ÈÁéƒá‰ ‹ÐÁê¹ÿ#ÑV‹u‰‹u‹ÐÁê âÿ#Á‹M ‰‰^]ÂÌÌÌÌÌ‹ÿU‹ìV‹uW~ WÿÈa‹N‹E ÿF‰0‰H‰W‰Fÿàa_^]ÂÌÌÌÌÌ‹ÿU‹ìV‹uW~ WÿÈaÿN‹E ‹‹P‰ ‰QW‰@‰ÿàa_^]ÂÌÌÌÌÌ‹ÿU‹ì‹U3ÀJ8V‹u ;1v@ƒÁ$ƒørð3À^]ÂÀD‚(ëòÌÌÌÌÌ‹ÿU‹ìS‹] V‹uWSVè¸ÿÿÿ‹ø…ÿt|†”;øu9_um‹a‰}jÿuÿÓ…ÀtD‹M 9HsZPÿuÿÓ…Àt2‹M 9HsHÿ†ÈÿG ÿ†ø‹PŽPjÿv$ƒQÿ aƒEG9Er¥ÿ†ÀÿG3À_^[]Âÿ†¼ÿGëîÌÌÌÌÌ‹ÿU‹ìVW‹} ÿwÿuèÿÿÿ‹ð…öt*S‹ÞWSÿa‹ø…ÿtƒÃF;Ørè‹Eÿ€ÄÿF‹Ç[_^]ÂÌÌÌÌÌ‹ÿU‹ìSV‹uW~(ÇE‹ßjSÿa…Àt!ÿ†ø‹PŽPjÿv$ƒQÿ aƒÃG;ØrȃÇ$ÿMu¾_^[]ÂÌÌÌÌÌ‹ÿVWjB¾ ÑaY3À‹þ󫿉=ØÑaÿ¬ah,Ña£DÑa‰5$Ña‰5 Ñaÿ”a‰=ÄÑa_ÇXÑa€Ç|ÑaÇ Ña€^ÃÌÌÌÌÌ‹ÿV¾ ÑaVè$ÿÿÿh,Ña‰5$Ña‰5 Ñaÿäa^ÃÌÌÌÌÌ‹ÿU‹ìV‹u95ØÑash Ñaèëþÿÿ‰5ÄÑa‰5ØÑa^]ÂÌÌÌÌÌ‹ÿU‹ìS‹] ;ØÑaVW¿ Ña‡SWè²ýÿÿ‹ð…ött€}w ¶E‹… Ðaë¡ Ða‰F ‹E‰F‹ESW‰F‰^èHýÿÿ…Àt'=´Ñat öEt‹Ë‹ÑÁé3À~ ó«‹Êƒáóª¿ ÑaÿìÑaðÑaƒôÑaéSWèþüÿÿ…À‰E „þ=´Ñau;Xuf‹@ƒÀ Pÿuÿ5DÑaÿ¨a‹ð…ö„ÒÿøÑa3ÉÒa Òa€}w ¶E‹… Ðaë¡ Ða‰F ‹E‰F‹E‰F‹E ‹@‰FëfC Pÿuÿ5DÑaÿ¨a‹ð…ötsVjÿ5DÑaÿ\aÿøÑa3ÉÒa Òa€}w ¶E‹… Ðaë¡ Ða‰F ‹E‰F‹E‰F‰^‰6‰v‰^ÿìÑaðÑa ôÑaVWè†ûÿÿF ë3À_^[]ÂÌÌÌÌÌ‹ÿU‹ì‹E …ÀVpàtq‹FSWV¿ ÑaW‰E èˆûÿÿ‹^SWè¹ûÿÿ…Àt;Xu VWèŒüÿÿ‹ð…ö_[t%ÿÒa‹F ÒaVjÿ5DÑaƒ$Òaÿ aÿ Òa‹E ÒaƒÒa^]ÂÌÌÌÌÌ‹ÿU‹ì‹E…Àt‹@ø]ÂÌÌÌÌÌ‹ÿU‹ìQQVW‹} …ÿwà‰uüu3Àé÷‹V‹NS‹];Ú‰Møw@€}w ¶E‹… Ðaë¡ Ða‰F ‹E‰F‹E‰^‰F+ÙðÑa‹ÇƒôÑaé¥;Ùw`€}w ¶E‹… Ðaë¡ ÐaöE‰F ‹E‰F‹E‰Ft‹Ë+Ê|2 ‹ÑÁé3Àó«‹Êƒáóª‹E ‰^+]øðÑaƒôÑaéAS¿ ÑaWè™úÿÿ‹Ð…Ò‰U „ ‹N‹ÁÁéz ƒÆ ‰}ó¥‹ÈƒáöEó¤t‹Eü‹p‹Ë+Î| ‹ñÁé3Àó«‹Îƒáóª€}w ¶E‹… Ðaë¡ Ðaÿuü‰B ‹E‰B‹E¾ ÑaV‰B‰Zè¨ùÿÿÿuüVè½úÿÿ+]øÿu ðÑaVƒôÑaèMùÿÿ‹EéˆVWèwùÿÿC PVÿuÿ5DÑaÿØa‹ø…ÿte€}w ¶E‹… Ðaë¡ Ða‰G ‹E‰G‹E‰G‰_‰_ÿÒa‹Ã+GWÒah ÑaƒÒa+]øðÑaƒôÑaèÄøÿÿG ë3À[_^ÉÂÌÌÌÌÌ‹ÿU‹ìSV‹uŠ„ÀWt‹} Š„Ò‹Ït ŠA:Ãt€9uôFŠ„Àuç3À_^[]ÃFëöÌÌÌÌÌ‹ÿU‹ìì ¡ Ða‹M V•øþÿÿRh?3öV‰Eü‹EQP‰…èþÿÿ‰ðþÿÿ‰µøþÿÿÇ…ôþÿÿÿa;ÆuuS‹$aë(…üþÿÿPÿµøþÿÿè”ÿÿÿ;ÆYY‰…ìþÿÿuYÇ…ôþÿÿ…àþÿÿPVVV…ôþÿÿP…üþÿÿPVÿµøþÿÿÿÓ…Àt³ÿµøþÿÿÿ,aÿµðþÿÿÿµèþÿÿÿa[‹Mü^è >ÉÃÿµøþÿÿÿ,a‹…ìþÿÿëàÌÌÌÌÌ‹ÿU‹ìƒìX¡ Ða‹Mƒe¨U¬‰Eü‹E +ÑSŠˆ A„Ûuö…À[t>VW}¬OŠOG„Éuø¾Äaf¥‹ÐŠ@„Éuù}¬+ÂOŠOG„Éuø‹ÈÁé‹òó¥‹Èƒáó¤_^E¨Ph?jE¬Ph€ÿa…Àuÿu¨ÿ,a3À@ë3À‹MüèL=ÉÃÌÌÌÌÌ‹ÿU‹ìì¡ Ða‹U‰Eü‹ES‹] V‰…ôûÿÿ‹E3öüûÿÿ‰…ðûÿÿ‰µøûÿÿ+ÊŠˆB„Àuö;ÞtFW½üûÿÿOŠGG„Àuø¾Äa‹Ãf¥‹ÐŠ@„Éuù½üûÿÿ+ÂOŠOG„Éuø‹ÈÁé‹òó¥‹Èƒáó¤3ö_V…øûÿÿPVh?VVV…üûÿÿPh€ÿ(a…Àt3ÀëF9µôûÿÿt/‹…ôûÿÿHŠ@„Òuù+Á@PÿµôûÿÿjVÿµðûÿÿÿµøûÿÿÿ0aÿµøûÿÿÿ,a3À@‹Mü^[è9<ÉÃÌÌÌÌÌ‹ÿU‹ìQQ‹USV‹u 3ÛÇ ‹ W‰]ø‰]üyŠA:Ãuù+ÏA‹ÁƒàD ‰‹J+ˉ]üt#It It ÇEøéë4EüPÿrè7‹Mü‰Eøë‹RBŠ B:Ëuù+ÐJ‹ÁƒàÈ9]øu‹Eø_^[ÉÂÌÌÌÌÌ‹ÿU‹ìSV‹u‹F@W‹} …3Û‰9^v)F‰Eƒe E Pÿuè2ÿÿÿ…Àu‹E ƒE C;^rÝ3À_^[]ÂÌÌÌÌ̸ѳaè7>ƒì SV‹uW‰eðVèC¨ÿÿ…ÀYu0!Eü!EìEìPÿvèrÿÿÿ…À‰Eèu ‹Eì‹M ƒÀ‰ÿu觨ÿÿ‹EèY‹Mô_^d‰ [ÉÂÇEèé¸LuaÃÌÌÌÌÌ‹ÿU‹ìQ‹M‹A‹UƒeüS‹] ƒc‰Cƒ ‹V‹1W‹þO‰M ŠG„Éuù+} O‹}‰M ø‹ÁÁéó¥‹Èƒá󤋋M‰‹E ƒàE ‹qƒî‹t#Nt Nt¸éëS‹}RW48V‰CÿqèKë=‹q‹þGŠG„Éuù+øO‹:}‰M ‹ÁÁéó¥‹Èƒá󤋉C‹E ƒàE ‹Eü_^[ÉÂÌÌÌÌÌ‹ÿU‹ìV‹u‹NW‹>I‹M ‰9‹~‰y‹}3À•9F‰E v-‰M)uS^‹EWÿuÃPSèÙþÿÿ…ÀuÿE ‹M ƒÃ ;NrÞ[_^]ÂÌÌÌÌ̸à³aè~<ƒì SVW‹}‰eðEìP3ÛW‰]ìè"þÿÿ;Ã…ˆÿuìjÿ¬aPÿ¨a‹ð;óujXëkWèV¦ÿÿ;ÃYu`‹jX‰‹O‰F‰Eè‰N‰^ ‹G‰FEèPVFPÿw‰]üèÿÿÿ;ÉEèu‹E‹Mì‰0‹E ‰ëÇEèé¸hwaË}W芦ÿÿ‹EèY‹Mô_^d‰ [ÉÃÌÌÌÌÌ‹ÿU‹ìQQ‹U‹E ƒeøƒeüV‹uÇ ‹ WÈySŠA„Ûuùƒeü+ÏA‹ùƒçL ‰‹Jƒé[t"It It¸éë7‹RMüQÐPRè2‹Müë‹JÈAŠA„Òuù+ÈA‹ÁƒàÈ‹Eø…Àu_^É ÌÌÌÌÌ‹ÿU‹ìSV‹u‹F@W‹}…3Û‰9^v,F‰EƒeEPÿu ÿuè*ÿÿÿ…Àu‹EƒE C;^rÚ3À_^[] ÌÌÌÌ̸ï³aè¾:QQ‹M‹AƒeüƒeìSVW‰eðUìRÁQPèuÿÿÿ…À‰Eu ‹Eì‹M ƒÀ‰‹Mô‹E_^d‰ [ÉÂÇE鸿xaÃÌÌÌÌÌ‹ÿU‹ìQ‹E ‹H‹UƒeüS‹]ƒc‰Kƒ ‹M‹V‹2ÁW‹øO‰MŠG„Éuù+}O‹}‰Mþ‹ð‹ÁÁé‰}ó¥‹È‹Eƒá󤉋EƒàE‹E ‹pƒî‹ t)Nt Nt¸éëc‹uÿuΉK‹@ERVPQèUëG‹@‹M4‹þGŠG„Éuù+øO‹:}‰M‹ÁÁé‰}ó¥‹È‹Eƒáó¤‰C‹EƒàE‹Eü_^[ÉÂÌÌÌÌÌ‹ÿU‹ìV‹u ‹NW‹>I‹M‰9‹~‰y‹}3À•9F‰Ev0‰u )M SYÿu‹E WÿuÃPSè»þÿÿ…ÀuÿE‹MƒÃ ;NrÛ[_^]ÂÌÌÌÌ̸þ³aèö8ƒì ‹ESVW‹}3Û‰‰eðEìPW‰]ìèþÿÿ;Ã…ÿuìjÿ¬aPÿ¨a‹ð;ó‰uèujXë}‹ÇE‰‹GN‰F‰N‰^ ‹GW‰F‹GURVÇPQ‰]üè ÿÿÿ‹ø;ûu1EèPVèë±ÿÿ‹ø;ûYYu‹Eè‹M‰ëÇEé¸þzaË}‹uè3ÛVSÿ¬aPÿ a‹Ç‹Mô_^d‰ [ÉÃÌÌÌÌÌ‹ÿU‹ì‹EV‹ñƒ&ƒfƒf…À‰F t(W‹} …ÿuG‹ÇÁàPjÿ¬aPÿ¨a…À‰Ft‰>_‹Æ^]ÂÌÌÌÌ̃y t ƒ9t3À@Ã3ÀÃÌÌÌÌÌ‹ÿU‹ìì¡ ÐaS‹]VW3ÿ;߉Eü‹ñu,h…ðýÿÿPhÐÿ5Ñaÿa…Àðýÿÿu»Èa9~v‹FÿtøSÿpa…ÀYYtG;~ræ3À‹Mü_^[è>4É‹F‹øëéÌÌÌÌÌ‹ÿU‹ìVW‹}‹ÇÁàP‹ñÿvjÿ¬aPÿØa…Àt3Àë ƒf3À‰>@_^]ÂÌÌÌÌÌ‹ÿU‹ìQƒeüS‹¬aV‹ñƒ~W‹= av,‹F‹Mü‹DÈ…ÀtPjÿÓPÿ׋F‹MüƒdÈÿEü‹Eü;FrÔÿvjÿÓPÿ׃f_^[ÉÃÌÌÌÌÌ‹ÿU‹ììH¡ ÐaS‹]…ÛV‰Eü‹ñu,h…ðýÿÿPhÐÿ5Ñaÿa…Àðýÿÿu»Èa‹;Fw@P‹Îèÿÿÿ…À„¶Wj 3ÀYÇ…¸ýÿÿÿÿÇ…¼ýÿÿÿÿ½Àýÿÿó«‹=xa!…äýÿÿSÇ…Àýÿÿ‰Ðýÿÿÿ×Y‰…Ôýÿÿ…¸ýÿÿPjh2ÿv ÿ4a…À‰…ìýÿÿtF‹N‹VS‰Êÿ×YDPjÿ¬aPÿ¨a‹N‹V‰DÊ‹F‹N‹DÁ…ÀtSPÿtaÿFYY‹…ìýÿÿ_‹Mü^[èf2ÉÂÌÌÌÌÌ‹ÿU‹ìVÿu‹ñè–ýÿÿ…Àu ÿu‹Îè·þÿÿ^]ÂÌÌÌÌÌ‹ÿU‹ìì¡ Ðaƒ¥øýÿÿV‹ñøýÿÿQhäahÜa‰Eü‹Eh4aPèò£ÿÿƒÄ…Àu+ÿµøýÿÿ…üýÿÿhÔaPÿaƒÄ …üýÿÿP‹Îèlÿÿÿë =ìujëì3À‹Mü^è±1ÉÂÌÌÌÌÌ‹ÿV‹ñ3ÀW‹=øahèa‰‰F‰F‰F ÿ×hØa‰Fÿ×hÀa‰Fÿ×h´a‰Fÿ×h a‰Fÿ×hˆa‰F ÿ×hxa‰F$ÿ×h\a‰F(ÿ×hDa‰F,ÿ×h(a‰F0ÿ×ha‰F4ÿ×ha‰F8ÿ×hìa‰F<ÿ׉F@_‹Æ^ÃÌÌÌÌÌ‹ÿV‹5aW‹ùÿwÿÖÿwÿÖÿwÿÖÿwÿÖÿw ÿÖÿw$ÿÖÿw(ÿÖÿw,ÿÖÿw0ÿÖÿw4ÿÖÿw8ÿÖÿw<ÿÖÿw@ÿÖ_^ÃÌÌÌÌÌ‹ÿU‹ìƒì,SVW‹ùWhèaj3öVhØaÿ¬a‹Ø;Þtÿ5ÈÐaÿ°aéO‹øahDaÿÓ;ƉEì„ë‹‹OQVVVVVVÿuì‰MäPÿR ;ƉEü„AEÔPÿah0a‰uøÿÓ;ƉEè„©‹‹UøRVVVVVVÿuèQÿP ;Æ…ha‰uôÿÓ;ƉEèt{‹Eø‹VUôRVVÿuèPÿQÿuè‰Eüÿa9uüu+‹EôUðRV‰uð‹PÿQ<‰Eü‹Eô‹PÿQ9uüt‹Eô‹PÿQ‹Eø‹PÿQé EÔPÿahafÇEÔÿÓ;ƉEÜu¸€ë~‹Eð‹VUÔRVhüaPÿQEÔPÿüa‹Eø‹VVVÿuðPÿQ8‹Ø;Þt‹Eô‹PÿQ‹Eø‹PÿQ‹Ãë5‹Eð‹PÿQ‹Eø‹PÿQÿuä‹?‹VVVVVVÿuìWÿP ‰Eüÿuìÿa‹Eü_^[ÉÃÌÌÌÌÌ‹ÿVW3ÿ9=ÈÐa‹ñt3Àé«SWWWÿ¤a‹Ø;ßu ¸Ð €éjÿSÿ´aƒøÿu¸Ï €ë{hœaW‰ÈÐaÿ|aYY‹ÎèÓýÿÿ;Çt‹ðëJ‹F‹VRWPÿQ;Çuêh`aÿøa‹Ø;ßu¾€ë ‹F‹WƒÆ VWWSPÿQS‹ðÿa;÷u3öÿ5ÈÐaÿ°a‹Æ[_^ÃÌÌÌÌ̸ ´aè 1QQ¡ÈÐaSVW3ÿ;ljeð‹ñ‰EìtpjÿPÿ´aƒøÿu¸Ï ë]9~‰}üt ‹F‹PÿQ9~t ‹F‹PÿQ‹;Çt‹PÿQ9~ t‹v ‹VÿP븪‚aÃ3ÿÿuì‰=ÈÐaÿ°aÿuìÿ¼a3À‹Mô_^d‰ [ÉÃÌÌÌÌÌ‹ÿU‹ìQS3Û9]u3ÀëXVWÿuÿTa‹ðD6P‰]üèh.‹ø;ûYt'FVWjÿÿuSSÿXa;Ã~Wf‰\Gþÿøa;ÉEüu3Àë Wè$.‹EüY_^[ÉÂÌÌÌÌÌ‹ÿU‹ì쬡 ÐaSV‹5a‰EüW‹}…dÿÿÿP‰`ÿÿÿÿÖ‹…`ÿÿÿ‹@ •xÿÿÿR3ÛS‰xÿÿÿ‹PÿQ8;Ã…´…dÿÿÿPÿÖhüafÇ…dÿÿÿÿøa;É…lÿÿÿ„˜‹…xÿÿÿ‹S•dÿÿÿRShìaPÿQ…Àt3öFéU…dÿÿÿPÿüa‹;ÃtDPfÇ…dÿÿÿèÄþÿÿS•dÿÿÿR‹•`ÿÿÿSÿr‰…lÿÿÿ‹…xÿÿÿ‹PÿQ…Àu®…dÿÿÿPÿüa‹GS•dÿÿÿR‹•`ÿÿÿSÿr‰…lÿÿÿ‹…xÿÿÿfÇ…dÿÿÿ‹PÿQ…À…iÿÿÿ‹G S•dÿÿÿR‹•`ÿÿÿSÿr‰…lÿÿÿ‹…xÿÿÿfÇ…dÿÿÿ‹PÿQ…À…1ÿÿÿ‹G S•dÿÿÿR‹•`ÿÿÿSÿr ‰…lÿÿÿ‹…xÿÿÿfÇ…dÿÿÿ‹PÿQ…À…ùþÿÿŠGS•dÿÿÿR‹•`ÿÿÿSÿrˆ…lÿÿÿ‹…xÿÿÿfÇ…dÿÿÿ‹PÿQ…À…ÁþÿÿŠGS•dÿÿÿR‹•`ÿÿÿSÿr$ˆ…lÿÿÿ‹…xÿÿÿfÇ…dÿÿÿ‹PÿQ…À…‰þÿÿ…dÿÿÿPÿÖ…lÿÿÿPG*PfÇ…dÿÿÿÿa‹…xÿÿÿ‹S•dÿÿÿR‹•`ÿÿÿSÿr(PÿQ…À…@þÿÿ…dÿÿÿPÿüa9_tS…dÿÿÿPÿÖÿwfÇ…dÿÿÿèýÿÿS•dÿÿÿR‹•`ÿÿÿSÿr,‰…lÿÿÿ‹…xÿÿÿ‹PÿQ…À…èýÿÿ…dÿÿÿPÿüa9_tS…dÿÿÿPÿÖÿwfÇ…dÿÿÿèªüÿÿS•dÿÿÿR‹•`ÿÿÿSÿr0‰…lÿÿÿ‹…xÿÿÿ‹PÿQ…À…ýÿÿ…dÿÿÿPÿüa9_tS…dÿÿÿPÿÖÿwfÇ…dÿÿÿèRüÿÿS•dÿÿÿR‹•`ÿÿÿSÿr4‰…lÿÿÿ‹…xÿÿÿ‹PÿQ…À…8ýÿÿ…dÿÿÿPÿüa9_tS…dÿÿÿPÿÖÿwfÇ…dÿÿÿèúûÿÿS•dÿÿÿR‹•`ÿÿÿSÿr8‰…lÿÿÿ‹…xÿÿÿ‹PÿQ…À…àüÿÿ…dÿÿÿPÿüa9_&tS…dÿÿÿPÿÖÿw&fÇ…dÿÿÿè¢ûÿÿS•dÿÿÿR‹•`ÿÿÿSÿr<‰…lÿÿÿ‹…xÿÿÿ‹PÿQ…À…ˆüÿÿ…dÿÿÿPÿüa9_"tS…dÿÿÿPÿÖÿw"fÇ…dÿÿÿèJûÿÿS•dÿÿÿR‹•`ÿÿÿSÿr@‰…lÿÿÿ‹…xÿÿÿ‹PÿQ…À…0üÿÿ…dÿÿÿPÿüa8_‰Xÿÿÿ†JGB‰…\ÿÿÿ‹…\ÿÿÿ9Xø„—…dÿÿÿPÿÖ‹…\ÿÿÿÿpøfÇ…dÿÿÿèÊúÿÿÿµXÿÿÿ‰…lÿÿÿhÐaEœhÄaPÿaƒÄEœPÿøa;É…tÿÿÿ„‹…xÿÿÿ‹S•dÿÿÿRSÿµtÿÿÿPÿQ…À…~ûÿÿÿµtÿÿÿÿa…dÿÿÿPÿüa…dÿÿÿPÿÖÿµXÿÿÿ‹…\ÿÿÿ‹@üh´a‰…lÿÿÿEœhÄaPfÇ…dÿÿÿÿaƒÄEœPÿøa;É…tÿÿÿ„‰‹…xÿÿÿ‹S•dÿÿÿRSÿµtÿÿÿPÿQ…À…ìúÿÿÿµtÿÿÿÿa…dÿÿÿPÿüa‹…\ÿÿÿ‹@üƒø‡Ú¶€}‹aÿ$…m‹a…dÿÿÿPÿÖÿµXÿÿÿ‹…\ÿÿÿ‹fÇ…dÿÿÿh¨aé6…dÿÿÿPÿÖ‹…\ÿÿÿÿµXÿÿÿÝÝlÿÿÿfÇ…dÿÿÿh˜aé …|ÿÿÿ‰…Tÿÿÿ‰tÿÿÿ‹tÿÿÿ‹…\ÿÿÿ¶PhaÿµTÿÿÿÿ a…TÿÿÿƒÄ ÿ…tÿÿÿƒ½tÿÿÿ rÆ…dÿÿÿPÿÖ…|ÿÿÿPfÇ…dÿÿÿèÝøÿÿÿµXÿÿÿ‰…lÿÿÿh„aEœhÄaPÿaƒÄEœPÿøa;É…tÿÿÿ„.‹…xÿÿÿ‹S•dÿÿÿRSÿµtÿÿÿPÿQ…À„‘‹…xÿÿÿ‹PÿQ3À@éè…dÿÿÿPÿÖ‹…\ÿÿÿÿ0fÇ…dÿÿÿèLøÿÿÿµXÿÿÿh„a‰…lÿÿÿEœhÄaPÿaEœƒÄPÿøa;É…tÿÿÿ„‹…xÿÿÿ‹S•dÿÿÿRSÿµtÿÿÿPÿQ…À…ùÿÿÿµtÿÿÿÿa…dÿÿÿPÿüa¶Gÿ…Xÿÿÿƒ…\ÿÿÿ9…XÿÿÿŒ¿üÿÿ…dÿÿÿPÿüa‹…`ÿÿÿ‹@‹•xÿÿÿRjPÿQ ‹ð‹…xÿÿÿ‹PÿQ‹Æ‹Mü_^[èè$ɸ€ëê9‰ac‰a“‰aoŠaÌÌÌÌÌ‹ÿU‹ìƒ=ÈÐaV‹ñuèÀõÿÿjÿÿ5ÈÐaÿ´aƒøÿu¸Ï €ëÿu‹Îè‚÷ÿÿÿ5ÈÐa‹ðÿ°a‹Æ^]ÂÌÌÌÌÌ‹ÿU‹ìÿu¹ÐÐaèšÿÿÿ÷ØÀ@]ÂÌÌÌÌ̹ÐÐaè"öÿÿ÷ØÀ@ÃÌÌÌÌÌ‹ÿU‹ì‹E3ÉÆ@‰H‰H ‰H ˆH‰H"‰H&‰H‰H‰H‰H]ÃÌÌÌÌÌ‹ÿU‹ìì ¡ ÐaV‹uW‰Eüh…ôýÿÿPÿ@a…ôýÿÿh0aPÿ€aYY…ôýÿÿPÿDa‹ø…ÿt)haWÿHa…Àÿu VtÿÐëÿ˜aW‹ðÿPa‹Æ‹Mü_^èx#ÉÂÌÌÌÌÌ‹ÿU‹ìQQVW‹}jWÿa3ö} =þÿÿ‰Eü‰p„¤ƒ} û†´ƒ} ý‡ªS‹hëW‰uÿa‰EøEPÿ³‹EWÿPƒÄ …ÀuW‹E;ÆtP‹;ÎtJ‰u vE‹M ‹|ˆVW‹Ëèã…Àt$VVW‹Ëèa ‹E‹M ‰tˆ‹EüÿpÿuøVWè ÿE ‹E‹M ;r»EPèa[ëhîWÿaVVh Pÿ4a3À_@^É ÌÌÌÌÌ‹ÿU‹ìì$¡ ÐaS‹] V‰Eü‹EW‰…àûÿÿ‹Ej ‹ø¾ˆaY3Òó¦‰ÜûÿÿuDh…ðýÿÿPhº ÿ5Ñaÿa…À„ÍS…ðýÿÿPÿµàûÿÿÿa3ÀƒÄ @é°j ‹ø¾(aY3Òó¦uh…ðýÿÿPh¼ ëªj‹ø¾ÔaY3Òó¦…ý‹ah…äûÿÿPh» ÿ5ÑaÿÓ…À„P‹…Üûÿÿj ¿Üa‹ðY3Òó¦uh…ðýÿÿPhÉ éŽj ¿èa‹ðY3Òó¦uh…ðýÿÿPhÆ ëkj¿ôa‹ðY3Òó¦uh…ðýÿÿPhÈ ëHj¿Xa‹ðY3Òó¦uh…ðýÿÿPhÇ ë%‹ðj¿üaY3Àó¦…§h…ðýÿÿPhÊ ÿ5ÑaÿÓ…À„†…äûÿÿPé®þÿÿj‹ø¾aY3Òó¦uh…ðýÿÿPh½ ésþÿÿj ‹ø¾¼aY3Òó¦uh…ðýÿÿPh¾ éMþÿÿj‹óZ¿Ta‹Ê3Ûó¦…‹ø¾ta‹Ê3Ûó¦uh…ðýÿÿPhÀ éÒ‹ø¾la‹Ê3Ûó¦uh…ðýÿÿPhÁ é­‹ø¾da‹Ê3Ûó¦uh…ðýÿÿPh 鈋ø¾\a‹Ê3Ûó¦uh…ðýÿÿPhà ëf‹Ê‹ø¾Ta3Òó¦uh…ðýÿÿPhÄ ëDj‹ø¾DaY3Òó¦uh…ðýÿÿPh¿ ë!‹øj¾ÌaY3Àó¦u2h…ðýÿÿPhÅ ÿ5Ñaÿa…Àt…ðýÿÿPhLaé;ýÿÿ3À‹Mü_^[è?É ÌÌÌÌÌ‹ÿU‹ììH¡ ÐaSV‹ujV‰Eüÿa} =þÿÿ‹Ø‹E‹‰Ct"ƒ} û† ƒ} ý‡ÿjVÿ$aéñƒìýÿÿÿWhîVÿa‹=4a3öVVh P‰…èýÿÿÿ×Ç…¸ýÿÿ‰µÄýÿÿ‰µÈýÿÿ‰µøýÿÿëi…üýÿÿPÿµôýÿÿÿµðýÿÿèüÿÿƒøuL‹…øýÿÿ‰…¼ýÿÿ…üýÿÿP‰µÀýÿÿ‰…ÌýÿÿÿxaY‰…Ðýÿÿ…¸ýÿÿPVhMÿµèýÿÿÿ׃øÿtCÿ…øýÿÿ…ìýÿÿP…ôýÿÿP…ðýÿÿP…äýÿÿP…àýÿÿPVVh4aÿsè‘ÿÿƒÄ$…À„Zÿÿÿ_‹Mü3À^@[èâÉ ÌÌÌÌÌ‹ÿU‹ìì ¡ Ða‰Eü‹E …ÀS‹]ugVWh…ôýÿÿPè¬ùÿÿ‹=€a…ôýÿÿh¸aPÿ׋5„a…ôýÿÿj\PÿÖƒÄëfÇ/…ôýÿÿj\PÿÖYY…Àuê…ôýÿÿh aPÿ×YY_^ëP…ôýÿÿPÿtaYYhˆaÿDa…Àth|aPÿHa…ÀtjejôýÿÿQSÿЋMü[èÉÂÌÌÌÌÌ‹ÿU‹ìƒì,SV‹uWjVÿa‹}‹Où=þÿÿ‰Eütjƒùý…º»ë9] …¬SVÿa‹54ajj ‹Øh SÿÖ…À„ˆ‰EØEÔPjh>SÇEÔÿÖ…Àtl‹Eø…ÀtePÿwÿuÿPëY»ë9] uOöG8t ‹G\…ÀtPQVëßhîV‹5aÿÖ‹=4ajjh Pÿ׋Eüƒ`SÿuÿÖ‹Mÿqj ÇFÛŒaYÿµðüÿÿ3À‰¤üÿÿÇ…¨üÿÿÿÿ½¬üÿÿó«…üýÿÿhÔaPÇ…¬üÿÿ‰µÐüÿÿÿa…üýÿÿ‰…¼üÿÿ‹…ðüÿÿƒÄ HŠ@„Òuù+Á‰…Àüÿÿ…¤üÿÿPjé¡h…ôüÿÿPhÓÿ5Ñaÿ0a…Àt…ôüÿÿ‰…ìüÿÿë Ç…ìüÿÿ a…àüÿÿPhah8a»4aSWè.‹ÿÿƒÄ…Àt ‹…ìüÿÿ‰…àüÿÿ…ðüÿÿPhÔah aSWè‹ÿÿƒÄ…Àt ‹…ìüÿÿ‰…ðüÿÿƒ¥èüÿÿ…èüÿÿPh|ah aSWèÑŠÿÿƒÄ…Àtƒ¥èüÿÿ…äüÿÿPh(ah8aSW諊ÿÿƒÄ…Àt ‹…ìüÿÿ‰…äüÿÿÿµäüÿÿ3Û9èüÿÿ…üýÿÿt#ÿµèüÿÿÿµàüÿÿÿµðüÿÿhðaPÿaƒÄëÿµàüÿÿÿµðüÿÿhÌaPÿaƒÄ‹…Øüÿÿ‰>‰^ÇF‘a‰…¤üÿÿj 3ÀYÇ…¨üÿÿÿÿ½¬üÿÿó«…üýÿÿPÇ…¬üÿÿ‰µÐüÿÿ‰…¼üÿÿÿxaY‰…Àüÿÿ…¤üÿÿPSh2ÿµÜüÿÿÿ4a3É…À•Á‹Á^‹Mü_[èÅÉÂÌÌÌÌ̸&´aè°QQSVWhëÿuÿa‹u‹‰Eð‰Mè ‹ø3Û;û„‘jè Y‰Eì;É]ütOQÿuð‹ÈèDâÿÿë3ÀƒMüÿ;ÉFtb‹Èèâÿÿ…ÀtWVjÿuÿ8aÿuèÚûÿÿ…Àt?…ÿv&‹MSès…Àtÿvÿuðÿpÿ0èvüÿÿ…ÀtC;ßrÚÿuð‹5@aÿÖÿuÿÖ3À@ë3À‹Mô_^[d‰ É ÌÌÌÌÌ‹ÿU‹ìVjÿuÿa‹ð‹N…Étjè8ûÿÿƒf^]ÂÌÌÌÌÌ‹ÿU‹ì‹E HHthƒèLtSƒèt3-½tHu\‹EÁèPÿu·EPÿuèhúÿÿëCÿuÿuÿuè¨þÿÿë5jÿuÿaÿp ÿuèsøÿÿ3À@ëÿuÿuÿuè4ùÿÿë ÿuèUÿÿÿ3À]ÂÌÌÌÌÌ‹ÿU‹ìƒì‹E ƒeôƒeø‰Eð‹E‰EüEðPhŸ™aÿujeÿ5Ñaÿ<a…À~ ‹E‹Mô‰3ÀëƒÈÿÉÂÌÌÌÌÌ‹ÿU‹ì‹E ƒèt!Hu+ƒ=àa‹E£ÑauèNÑÿÿÿàaë ÿ àauè¤Ñÿÿ3À@] ÌÌÌÌ̸@´aèì(¡ ÐaSV‹uW‹} Ìûÿÿ‰Eì‰eðèfƒeüWVÌûÿÿÆEü較MüÿÌûÿÿ‹ðè`‹Æë¸›aÃMüÿÌûÿÿèGjLX‹Môd‰ ‹Mìè_^[ÉÃÌÌÌÌÌ‹ÿU‹ìì$¡ ÐaS‹]V‹uW‹} ‰EüÜûÿÿèÞjSWVÜûÿÿè;Üûÿÿ‹ðèá‹Mü_‹Æ^[èªÉÃÌÌÌÌÌ‹ÿU‹ìì$¡ ÐaS‹]V‹uW‹} ‰EüÜûÿÿèƒjSWVÜûÿÿè† Üûÿÿ‹ð膋Mü_‹Æ^[èOÉÃÌÌÌÌÌ‹ÿU‹ìV‹u‹…ÀtPjÿ¬aPÿ aƒ&^]ÃÌÌÌÌÌ‹ÿU‹ìƒìƒMèÿS3Û9] ‰]ð‰]ø‰]ô‰]üu3À@éƒVWëT‹5TahÜaÿuø‰]ìÿÖ…ÀYYt;EìPÿuôÿuøÿuðÿuè½…ÿÿƒÄ…Àt‹uüj¿LaY3Àó¦ë ÿuìÿuüÿÖYY…Àu.EèPEüPEôPEøPEðPSSSÿu è†ÿÿƒÄ$…Àt†3À@_^[ÉÃ3Àë÷ÌÌÌÌÌ‹ÿU‹ìƒì SVEôPj3ÛSh°ah€‰]ôÿa‹ð;ó…´W‹=(aEøPEüPSh?SSSÿu‰]øÿuô‰]üÿ׋ð;óu~‹E PŠ@:Ëuù+ƒ}øuPÿu jSSÿuüÿaEøPE PSh?SSSh aÿuü‰] ÿ׋ð;óu+‹EpŠ@:Ëuù+ÆPÿujSSÿu ÿ0aÿu ‹ðÿ,aÿuüÿ,aÿuôÿ,a_‹Æ^[É ÌÌÌÌÌ‹ÿU‹ìì ¡ ÐaS‰Eü‹EV‹5aW‰…ôþÿÿ‹E ‰…äþÿÿ…ìþÿÿPj3ÿWh°ah€‰½ìþÿÿÿÖ‹Ø;ß…È…ðþÿÿPjWÿµôþÿÿ‰½ðþÿÿÿµìþÿÿÿÖ‹Ø;ß…”…ôþÿÿPjWh aÿµðþÿÿ‰½ôþÿÿÿÖ‹Ø;ßue…èþÿÿP…øþÿÿP…àþÿÿPWhœaÿµôþÿÿÇ…èþÿÿ‰½àþÿÿÿa‹Ø;ßu…øþÿÿPÿµäþÿÿÿTa…ÀYYtj{[ÿµôþÿÿÿ,aÿµðþÿÿÿ,aÿµìþÿÿÿ,a‹Mü_^‹Ã[èKÉÂÌÌÌÌÌ‹ÿU‹ìì$¡ Ða‹USVWj‰Eü‹EY‰…Üüÿÿ‹Ej3‰…èüÿÿ¾Ta½ðüÿÿó¥Y3À½(ýÿÿó«¾V…ôýÿÿP3ÛR‰ìüÿÿ‰äüÿÿÿ<a;Äy;Æ„q‹=ˆa…ôýÿÿj\Pÿ×;ÃYYu…ôýÿÿë@•øþÿÿ+Њˆ @:Ëuö…øþÿÿj.Pÿ×;ÃYYtˆ…ðüÿÿPŠ@:Ëuù+‹ø…øþÿÿHŠ@:Óuù+ÁD8;ƃú…øþÿÿ‹ÐŠ@:Ëuù½ðüÿÿ+ÂOŠOG:Ëuø‹ÈÁé‹òó¥‹È…äüÿÿP…ìüÿÿPSh?SSS…ðüÿÿPƒáh€ó¤ÿ(a…Àu_…ôýÿÿÇ…àüÿÿPŠ@:Ëuù‹50a+ÂP…ôýÿÿPjSh@aÿµìüÿÿÿÖj…àüÿÿPjSh0aÿµìüÿÿÿÖÿµìüÿÿÿ,a…øþÿÿPSÿaÿµèüÿÿ‹ðÿµÜüÿÿÿu ÿuSÿuSÿu VÿaV‹øÿ a‹Çë3À‹Mü_^[èJÉÃÌÌÌÌÌ‹ÿU‹ìV‹u‹…Àt4W3ÿ98v‹‹D¸…ÀtPè6~ÿÿY‹G;8rèÿ6jÿ¬aPÿ aƒ&_^]ÂÌÌÌÌÌ‹ÿU‹ìƒì¡ ÐaSVW‹ñj‰Eü‰uèè— ƒ¦¿W^ Sÿ8a…À„Î@;LJŋMè¾”a}ô¥f¥¾Œa}ì¥Á‰Mä)]äf¥‹ÃŠ‹uäˆ@„ÒuóEô‹ðŠ@„Òuù+ÆIŠQA„Òuø‹Uè‹ù‹ÈÁéó¥‹ÈƒáÂó¤‹ò‹Ã+óŠˆ @„ÉuöEô‹ðŠ@„Éuù‹ú+ÆOŠOG„Éuø‹ÈÁéó¥‹ÈƒáEìó¤‹ðŠ@„Éuù+ÆJŠJB„Éuø‹ÈÁé‹úó¥‹Èƒáó¤‹uè‹Mü_‹Æ^[èÝ ÉÃÌÌÌÌÌ‹ÿV‹ñÿ¶èß|ÿÿY‹Î^éè ÌÌÌÌÌ‹ÿU‹ìQS‹] V‹uW‹=Ha3Àh¨aS‰Eü‰‰F‰Fÿ×…Àt>EPhœahÜah4aÿuèhÿÿƒÄ…ÀuÿuSÿ×…Àt‹M‰‰F‰^ÇEü‹Eü_^[É ÌÌÌÌÌ‹ÿU‹ìVÿuÿLa‹ð…öuPPEPjhe€jÿ5ÑaèÌûÿÿƒÄ‹Æ^]ÂÌÌÌÌÌ‹ÿU‹ìì ¡ Ða‹U …Ò‰Eü‹E‰…äþÿÿ‰•ðþÿÿu ‹‰‰ðþÿÿÿµðþÿÿPè øÿÿ…ÀYY‰…èþÿÿ…æ!…àþÿÿSVW…àþÿÿP»ÌaS¿ aW¾4aVÿµðþÿÿèS“ÿÿƒÄƒ½àþÿÿ„¦ƒ¥ìþÿÿ…ìþÿÿPSWVÿµäþÿÿè'“ÿÿ3ÿƒÄ9½ìþÿÿu}…ðþÿÿPh(ah8aVÿµäþÿÿ‰½ðþÿÿè~ÿÿƒÄ9½ðþÿÿu)h…ôþÿÿPhÓÿ5Ñaÿ0a…ôþÿÿ‰…ðþÿÿWW…ðþÿÿPjhh€jÿ5Ñaè’úÿÿƒÄ‰½èþÿÿ_^[‹Mü‹…èþÿÿèº ÉÂÌÌÌÌÌ‹ÿU‹ìì¡ Ðaƒ¥ðþÿÿƒ¥ôþÿÿS‹]V‰Eü‹E W‰…èþÿÿ…ðþÿÿPha¿8aW¾4aVS‰ìþÿÿèV}ÿÿƒÄ…À…³…ôþÿÿPh¸aWVSè7}ÿÿƒÄ…À…”‹…ìþÿÿƒÀ •øþÿÿ+Њˆ @„Éuö½øþÿÿOŠGG„Àuø‹…èþÿÿ¾”a¥f¥‹ÐŠ@„Éuù½øþÿÿ+ÂOŠOG„Éuø‹ÈÁé‹òó¥‹È…øþÿÿPÿµôþÿÿƒáó¤èIøÿÿ…Àt …øþÿÿPÿµðþÿÿÿµôþÿÿè<÷ÿÿ…Àt3Àë3À@‹Mü_^[è ÉÂÌÌÌÌÌ‹ÿU‹ìQQ‹E SV‹u3Û;ó‰Mü‰tw‹;Ëtq‹F;Ãtj9^teURQS‰]ÿÐƒÄ ;ÉEøuK‹E;ÃtD9v7Wÿ6‹|˜‹MüWè)ýÿÿ…Àt‹MüjjW褋Eƒd˜‹E ÿ‹EC;rË_EPèµúÿÿ‹Eøë¸ó^[ÉÂÌÌÌÌÌ‹ÿU‹ìƒì(‹ESV3ÛW‰Mü‰]ì‰è¾‹M ;Ë„÷‹;Äí‰]ô†¡ƒÁ‰Mø‹Eø‹0EìPh¸ahÜah4aVè}{ÿÿƒÄ;ÃuOÿuì‹Mü‰]èè2üÿÿ‹ø;ûtM‹MüEØPWVè£ûÿÿ…Àt ‹MüEèPEØPèÃþÿÿ9]èu ÿuÜÿuàÿuØëWÿPaë=ìuhSSV‹MüètÿEô‹E ‹MôƒEø;‚eÿÿÿ‹Müè|…Àu¸É ë5ÿuEðPÿuü‰]ðÿuè»òÿÿ9]ðu¸Ê ëÿuÿuðèH…ÿÿYYë¸Ë _^[ÉÂÌÌÌÌÌ‹ÿU‹ìƒì‹ÑSŠ‚V‰Mô)EôW‰UðÇEü3ÛŠ‹uôˆ @:Ëuó‹E‹ðŠ@:Ëuùº+ÆOŠOG:Ëuø‹ÈÁéó¥‹Èƒá‚ó¤P‰]øÿLa‹ø;û‰}ìu$SSEPjhe€jÿ5ÑaèÛöÿÿƒÄ3Àé©‹5Hah¨aWÿÖ;Ä¿‹}ðMøQÿ·ÿÐ…ÀYY…IEðPhœahÜah4aÿuøèÂyÿÿƒÄ…À…#ÿu‹Ïÿuøèüÿÿ…À„ªÿuðÿuìÿÖ‹ð;ó„ü‡Ph¸ahÜah4aÿuøèÈwÿÿƒÄ…À…ÓSÿuø‹Ïèdúÿÿ…ÀtVÿuì‹ÏÿuøèÞéßÿuøè]vÿÿYéÈhÀaWÿÖ;ĘMôQ‰]ôÿÐ…ÀY…‹Eô;Ãtz9tvÿu‹MðÿpèRûÿÿ…ÀuSSEPjhg€jÿ5Ñaè£õÿÿ‰]üëg‹Eô3ö9v1‹D°‹MðSP‰EøèÇùÿÿ…Àt‹MðSSÿuøèB‹Eô‰\°‹EôF;0rÏEôPèZ÷ÿÿë%‰]üë SSEPjhf€jÿ5Ña‰]üè7õÿÿƒÄÿuìÿPa‹Eü_^[ÉÂÌÌÌÌÌ‹ÿU‹ììL¡ ÐaSV‹5haW‹ù‰Eü…¼þÿÿ‰½´þÿÿPÇWÿÖƒ¥¸þÿÿ‹Øƒûÿt*ÿ…¸þÿÿ…¼þÿÿPSÿda…ÀuèS‹`aÿÓƒ½¸þÿÿu¸Ì ëN…¼þÿÿPWÿÖ‹ð3ÿƒþÿt2‹´þÿÿ…èþÿÿPèýÿÿ…Àt3ÿG…¼þÿÿPVÿda…ÀuÕVÿÓ…ÿu¸Í ë3À‹Mü_^[è’ÉÃÌÌÌÌÌ‹ÿU‹ìƒì$SV3À‹ñ‹M ‰Eø‰Eô‰Eü‰W†PÿuèßÿÿEøPh¸a»ÜaS¿4aWÿuè;wÿÿƒÄ…À‹ÎuLÿuø!Eðèñ÷ÿÿ…À‰Eìu ¸õéˆMÜQPÿu‹ÎèV÷ÿÿ…ÀtEðPEÜP‹Îèwúÿÿ‰EüÿuìÿPaë èŠþÿÿ…À‰EüuL‹ÎèW…Àu‹Eü…Àu:¸É ë3EôPhÌaSWÿu臋ÿÿƒÄÿuô‹Îè…À‹M ‰uÇEüÉ ‹Eü_^[ÉÂÌÌÌÌÌ‹ÿU‹ìƒì‹ESV3Û‹ñ‰W†Pÿu ‰]øèã€ÿÿEøPh¸ahÜah4aÿu èAvÿÿƒÄ…À‹Îu]ÿuø‰]ôè÷öÿÿ‹ø;ûu ¸õé‰EäPWÿu ‹Îè]öÿÿ…Àt&EôPEäP‹Îè~ùÿÿ9]ôuÿuè‹ÎÿuìÿuäèEëWÿPaë èýÿÿ;Ãu>‹ÎèO…Àu¸É ë,ÿuEüPVÿu‰]üèíÿÿ9]üu¸Ê ë ÿuÿuüè€ÿÿYY_^[ÉÂÌÌÌÌÌ‹ÿU‹ì‹E…Pjÿ¬aPÿ¨a]ÂÌÌÌÌÌ‹ÿU‹ì‹EÁàƒÀPjÿ¬aPÿ¨a]ÂÌÌÌÌÌ‹ÿU‹ìV‹ñƒ&ƒfƒfW‹}…ÿuGWè·ÿÿÿ…À‰Ft‰>_‹Æ^]ÂÌÌÌÌÌ‹ÿU‹ìQSV‹ñ‹F3Û;Ãti‹;Ët^‰]üvYW3ÿ‹D ;ÃtPÿPa‹F‰\ ‹FÇ9Xu ÿpèØqÿÿY‹FÿEü‹Mü‰\‹F‰\ ‹F‰\‹F‰\‹FƒÇ;r«_‹F‰^[ÉÃÌÌÌÌÌ‹A…ÀuËÃÌÌÌÌÌ‹ÿU‹ìSV3ÛW‹ñ3ÿC9~uSèòþÿÿ;ljF„”‰‹N‰~3À99‹}vQ;:t ‹^@ƒÂ;rñë ÁàD‰Fƒ~u<‹;w ÁàƒÀPQjÿ¬aPÿØa…Àt>ÿ‰F‹F‹ÁáD‰F‰8‹Fÿ‹F‹M ‰H‹F‹M‰H‹Fƒ` 3À@_^[] 3ÀëõÌÌÌÌÌ‹ÿU‹ìƒ9t‹I‹E;s ÁàDë3À]ÂÌÌÌÌÌ‹ÿU‹ìQVW3ÿ‹ñ9>‰}ü„‹F‹;Ï„ƒ9}t‰Müë;ÏvuƒÀ‹Ñ9xu98uÿEüƒÀJuî9}ütYQè¦ýÿÿ;ÇtQ‰8‹N99vH3ÒSƒ}uʃy u'ƒyu!‹NÇD‹N‹L‹‰L˜‹Müÿ9t ‹NGƒÂ;9rÀ[ë3À_^ÉÂÌÌÌÌÌ‹ÿV‹ñƒ~tè½ýÿÿÿvjÿ¬aPÿ aƒf^ÃÌÌÌÌÌ‹ÿU‹ìVÿu‹ñÿu ÿuèþÿÿ…Àt‹N…Ét3À@‰A ë3À^] ÌÌÌÌÌ‹ÿU‹ìƒì¡ Ða…Àt=@»uMVEøPÿ€a‹uü3uøÿœa3ðÿ|a3ðÿxa3ðEðPÿta‹Eô3Eð3Æ%ÿÿ^u¸@»£ Ða÷УœÐaÉÃÌÌÌÌÌ;  Ðau ÷ÁÿÿuÃéÌÌÌÌÌ‹ÿU‹ìì0W‰…Øýÿÿ‰Ôýÿÿ‰•Ðýÿÿ‰Ìýÿÿ‰µÈýÿÿ‰½ÄýÿÿfŒ•ðýÿÿfŒäýÿÿfŒÀýÿÿfŒ…¼ýÿÿfŒ¥¸ýÿÿfŒ­´ýÿÿœ…èýÿÿÇ…(ýÿÿ‹E‰…àýÿÿE‰…ìýÿÿE‹@ü‰…ÜýÿÿjY3À½Ðüÿÿó«Ç…Ðüÿÿ À‹E‰…Üüÿÿ…Ðüÿÿ‰Eø…(ýÿÿ‰Eü¡ Ða‰… ýÿÿ¡œÐa‰…$ýÿÿjÿŒaEøPÿˆahÿlaPÿ„a_ÉÃÌÌÌÌÌÿ%ðaÌÌÌÌÌÌÿ%ìaÌÌÌÌÌ‹ÿU‹ìV3ö9u u95Ña~-ÿ Ñaƒ} ¡˜a‹£(Òau=h€ÿa;ÆY£0Òau3Àëg‰0¡0Òah ÐahÐa£,ÒaèàÿÑaYë?9u u;¡0Òa;Æt2ë‹ ,Òa‹ ;ÎtÿÑ¡0Òaƒ-,Òa9,ÒasÞPÿŒa‰50ÒaY3À@^] ÌÌÌÌÌ‹ÿU‹ìS‹]V‹u …öW‹}u ƒ=Ñaë&ƒþtƒþu"¡4Òa…Àt WVSÿÐ…Àt WVSèÿÿÿ…Àu3ÀëNWVSèöçÿÿƒþ‰E u …Àu7WPSèãþÿÿ…ötƒþu&WVSèÒþÿÿ…Àu!E ƒ} t¡4Òa…ÀtWVSÿЉE ‹E _^[] ÌÌÌÌÌh&³ad¡P‹D$‰l$l$+àSVW‹Eø‰eèP‹EüÇEüÿÿÿÿ‰EøEðd£Ã‹Mðd‰ Y_^[ÉQÃÌÌÌÌÌÌÿ%XaÌÌÌÌÌÌÿ%laÌÌÌÌÌÌÌÌjÿPd¡P‹D$ d‰%‰l$ l$ PÃÌÌÌÌÌ‹ÿU‹ìƒ=0Òaÿu]ÿ% ah,Òah0Òaÿuè3ƒÄ ]ÃÌÌÌÌÌ‹ÿU‹ìÿuèÂÿÿÿ÷ØÀ÷ØYH]ÃÌÌÌÌÌÌÿ%”aÌÌÌÌÌÌÿ%œaÌÌÌÌ̸¨´aéWÿÿÿÌÌÌÌ̸ø´aéHÿÿÿÌÌÌÌ̸Hµaé9ÿÿÿÌÌÌÌ̸˜µaé*ÿÿÿÌÌÌÌ̸èµaéÿÿÿÌÌÌÌÌÿuìè>ýÿÿYø ¶aéÿÿÿÌÌÌÌÌÌûÿÿé4îÿÿ¸d¶aéèþÿÿÌÌÌÌ̹ÐÐaèIÊÿÿhj´aè:ÿÿÿYÃÌÌÌÌ̹ÐÐaéÓÊÿÿÿÿÿÿÿÿÿÿiua„´a “t´a”´aÿÿÿÿÿÿÿÿ[waÔ´a “Ä´aä´aÿÿÿÿÿÿÿÿÓxa$µa “µa4µaÿÿÿÿÿÿÿÿñzatµa “dµa„µaÿÿÿÿÿÿÿÿ¤‚aĵa “´µaÔµaÿÿÿÿ´a “¶aÿÿÿÿ5´a›a@¶a “(¶aP¶a ¸ÿÿÿÿÿÿÿÿÔ¸ìh¸ÿÿÿÿÿÿÿÿÚ¹H ·ÿÿÿÿÿÿÿÿäºX·ÿÿÿÿÿÿÿÿ.¾8̸ÿÿÿÿÿÿÿÿP¾¬¸ÿÿÿÿÿÿÿÿZ¾ø0¸ÿÿÿÿÿÿÿÿ(¿`ºÌº¼º¤º’º‚ºtºPº@º0ºººþ¹½½ò¼â¼Ð¼4½ª¼ž¼ˆ¼|¼D½P½`½r½ »†½ ½°½Æ½à½ô½¾2¼H¼¸¼òº»»$»0»B»R»h»x»†»’»¼²»À»Ð»æ»ô»¼d¼7€9€€ €€¸€€ž¾’¾¬¾t¾h¾¾¾Ê¾Ö¾æ¾‚¾¿¿ô¾¹ ¹¹ô¸à¸&¹2¹<¹F¹P¹d¹n¹x¹‚¹Ž¹˜¹¢¹¬¹´¹¾¹Ê¹æ¹ô¹¹<¾MFC42u.DLLí_except_handler3ø_stricmpùsprintfüsscanf strpbrks_ltoaü_strnicmpstrncpystrncmpßmemmoveR__CxxFrameHandler(wcscmp*wcscpy-wcslenôsetlocale&wcscat'wcschr strrchr¥freeØmalloc;_initterm¶_adjust_fdivmsvcrt.dllj__dllonexit´_onexitûRegSetValueExAÊRegCloseKeyÎRegCreateKeyExAØRegEnumKeyExAÛRegEnumValueAäRegOpenKeyExAîRegQueryValueExAãRegOpenKeyAÑRegDeleteKeyAüRegSetValueExW°DeregisterEventSource ReportEventARegisterEventSourceAADVAPI32.dll<GetCurrentProcessId HeapFree]CreateMutexWHeapAllocœGetProcessHeap³ReleaseMutex~WaitForSingleObjecthGetLastError1CloseHandleWriteFileOCreateFileA^UnmapViewOfFile[GetFileSizeZMapViewOfFileQCreateFileMappingWHeapReAllocüGlobalSizeCLeaveCriticalSection–EnterCriticalSectionInterlockedExchangeInitializeCriticalSectionDeleteCriticalSectionHeapSizegMultiByteToWideChar·lstrlenAðFreeLibraryéGetWindowsDirectoryW˜GetProcAddressGLoadLibraryWºGetSystemDirectoryWtGetModuleFileNameA¹GetSystemDirectoryADLoadLibraryAÌFindCloseÙFindNextFileAÐFindFirstFileA;GetCurrentProcess”QueryPerformanceCounterÔGetTickCount>GetCurrentThreadIdÀGetSystemTimeAsFileTimeJTerminateProcess[UnhandledExceptionFilter6SetUnhandledExceptionFilterKERNEL32.dllCoCreateInstanceole32.dllOLEAUT32.dllØwsprintfAÉLoadStringW@SendMessageWÙwsprintfWGetDlgItemoGetWindowLongWÆEndDialogGetFocustGetWindowRectÈLoadStringA»UpdateWindowSetWindowLongWŸDialogBoxParamWUSER32.dllÝMHÀÁ<<h¿XÀHÁŒ•¶AcœÊ,,œ1qHt87+A>6²7fYL›¿šSVV$d‰aW<C"à"mWfÀv/,âi´lonoƒlúnjŸ 3)-†.Œ)%§›æ‹Ð6>5‘5¤WhQD\ˆ_†9™ [rHzû1¹*qqsÍÁÜÁçÁúÁÂÂ(Â6Â@ÂZÂnÂ~‘¢¸ÂÔÂåÂõ à Ã<ÃRÃiÃ{ÎÚãïùÃÈÃ×ÃâÃóÃÄÄ!Ä.Ä?ÄPÄ_ÄrÄĘĢİÄÁÄÐÄäÄþÄÅ-ÅAÅVÅfÅsÅÅŒÅœÅ³ÅÆÅ  !"#$%&'()*+,-./0123456789:;NPPTools.dllClearEventDataCreateBlobCreateNPPInterfaceDestroyBlobDestroyNPPBlobTableDuplicateBlobFilterNPPBlobFindOneOfFindUnknownBlobCategoriesFindUnknownBlobTagsGetBoolFromBlobGetClassIDFromBlobGetDwordFromBlobGetMacAddressFromBlobGetNPPAddressFilterFromBlobGetNPPBlobFromUIGetNPPBlobTableGetNPPEtypeSapFilterGetNPPMacTypeAsNumberGetNPPPatternFilterFromBlobGetNPPTriggerFromBlobGetNetworkInfoFromBlobGetStringFromBlobGetStringsFromBlobIsRemoteNPPLockBlobMarshalBlobMergeBlobNmAddUsedEntryNmHeapAllocateNmHeapFreeNmHeapReallocateNmHeapSetMaxSizeNmHeapSizeNmRemoveUsedEntryRaiseNMEventReadBlobFromFileRegCreateBlobKeyRegOpenBlobKeyReleaseEventSystemRemoveFromBlobSelectNPPBlobFromTableSendEventSetBoolInBlobSetClassIDInBlobSetDwordInBlobSetMacAddressInBlobSetNPPAddressFilterInBlobSetNPPEtypeSapFilterSetNPPPatternFilterInBlobSetNPPTriggerInBlobSetNetworkInfoInBlobSetStringInBlobSubkeyExistsUnMarshalBlobUnlockBlobWriteBlobToFileWriteCrackedBlobToFilerecursiveDeleteKeysetKeyAndValueׯaO´aNMgeNMnpNMapNMpaNMexNMmoNMuiNPwiNPrbNPftNPfdNPniNPbeNPfeNPfiNPedNPntNPbiNPdnNPqiNPblNPboNPbsNPitNPetNPstNPbrNPbtNPebNPsdNPtu¿Dÿÿ@»0€H€ p€ˆ€e €~¸€¼Ð€½è€€€ 0 @ P ` p €ñb@ød¨ø2àù„øò´°ôŒÿÿÀÈ€¥‚Select a networkMS Shell DlgPl2ÿÿ€OKPl2ÿÿ€CancelPl-2ïÿÿ€&Help'P tëSysTreeView32Tree1P±±tîSysListView32List2e€h€@Unable to load library %1. dLibrary %1 did not contain setup procedures. \Unable to add library %1 to the registry ¤Network interface card with MAC Address %1 does not support Promiscuous Mode Œ4VS_VERSION_INFO½ïþˆ( ˆ( ?ìStringFileInfoÈ040904B0LCompanyNameMicrosoft CorporationRFileDescriptionNPP Tools Helper DLLb!FileVersion5.1.2600.5512 (xpsp.080413-0852): InternalNameNPPTools.DLL€.LegalCopyright© Microsoft Corporation. All rights reserved.B OriginalFilenameNPPTools.DLLj%ProductNameMicrosoft® Windows® Operating System@ProductVersion5.1.2600.5512DVarFileInfo$Translation °Local ComputerBlob tagValueUnknown PropertiesLink speed is %hsMac type is %sMac address is %hsCurrent address is %hsMax frame size is %hs#This is a dial-up connection or VPNSupports delayed captureSupports ESP interfaceSupports real time captureSupports network statisticsSupports frame transmitSupports promiscuous mode TOKENRINGATMFDDIETHERNETIP/1394lä1è1ô1ø1D3H3d3h3t3x3”4˜4T5X5|5€5Ì5Ð566¼6À6Ì6Ð677T7X7¼7À74<8<˜<«<´<Ù<ò<=,=Ž= =¿=ç=/>;>ž>ã>Œ?“? px0œ0å0î0H1è1&6/6M6[6y66¾6æ6ø677\7…7—7µ7Ç7þ7'898`8j8—8ì89P9n9ž9²9: :1:8:ó:;;A;^;{;•>Ÿ>0ØF0V0Œ0 0Ö0ê0M1[1£1Õ1L2„2å2ñ2?3O3c3p3y3Š3™3«3È3Ï3õ3ú3 44E4|4ƒ4Œ4•4«4´4Ð4Û4ä45P55ñ5ø5A6‚6‹6ë6ò67Z7c7µ788’9È9Í9Ó9ö9:":W:b:o:z::š:«:¿:Ë:ñ:;=;c;Š;Î;ñ;v<{<€<¡<¦<Ç<è<=="=+=?=H=\=e=y=‚=š=»=Ü=ù=>B>‹>ö>ý>@$.1Â1$2*202m2y2©2Ñ2ç233m3t3}3”3›3¤3Ã3Ê3Ï3Ö3Ý3ä3ë3ò3ù34 4444$4-4B4I4€4‡4¼4Ã455C5J5i5p5„5ˆ5Œ55”5˜5œ5 5¤5¨5¬5°5´5¸5¼5À5Ä5È5á5þ56"6@6^6|6š6¸6Ö6ô67*7E7`7‰77­7¶7Ö7ß78828;8x8|8€8„8ˆ8Œ8«8¼8Ç8ç8÷89p9w9~9¢9Ô9Ý9ñ9 :o:§:Í:ø:;';=;‰;Í;Ö;ê;ó;<"<=<®<;=`=j=Ö=Þ=ç=> ><>Y>v>˜>¢>Ö>?µ?P0+070U0\0c0j0v0—0£0º01¤1«1Ä1Ì1Ó1ã1 2%2+2A2Y2k2‚2§2Æ2õ2ü23O3T3Z33ˆ3 3Ã3Í3á3ì344k4q4v4™4 4´4¿4ã4ì45(5U5^5v5¥5ß5ê5 666Y6~6ƒ6ˆ6©6²6Ê6å677|77†7°7è7ï7888"8u8Æ8Ë8ÿ8 999"9l9v9À9Æ9ç9ì9ù9 ::­:¹:Õ:á:ì;ñ;P<<›<é<)===B=]=b=®=ù=>,>1>6>j>°>·>ì>õ>µ?º?Á?Æ?à?ç?` 0%0F0K0~0ƒ0š0´0Ë0õ01)1K1Œ1¾1Ã1É1ã1ì12%2.2I2N2l2‹2”2µ2º2Í2Ö2ñ23313d3Ž3¨3Ñ304„4‰44ò4-585j5£5›6ª6å677H7°7Ô7ç7:8A8†88´8É8ò9 :+:G:µ:;[;¥;Ê;ó;< <<< >>%>E>K>Q>†>·>À>É>Ï>Ö>Ü>å>ë>M?T?n?v?‘?˜?Ô?Ú?æ?pÀH0O0c0„0‹0®0´0Ë0Ò0í0ù0þ0111}1º1Å1 222J2d2™2Þ2ë23a3µ3ô345q5Á6ô6û6c78Û8I::ˆ:ù: ;;[;b;Ÿ;Ç;Í;Ü;ï;6<=7><>G>e>l>¬>±>Ã>Í>×>á>ë>õ>ÿ> ???'?1?L?«?µ?»?Ç?Í?Ø?Ý?€ô00N0y0Á0Æ0ì0ú0W1p1…1ž1¯1¶1¼1ä1ê122#232?2Y2¥2±2·2À2ó23)3Z3b3­3¼3à3ý3G4‚5µ5 6e6½67m7Å78%8,898v8ƒ8 8®8¾8Ë899.959Z9Š9·9Ã9 :::&:•:£:ª:·:ô:;+;m;q;u;y;™;¬;²;Î;Ö;ï;%>A>U>x>‰> >·>Ý>?#?H?j?‰?¯?Ö?é?ô030X0|0ž0Á0ß0å0õ0 111a1z1€1ò1C2}2¤2¯2¸2é233 333X3ˆ3Ž3û34Q4`4Œ4®4¹4û455Q5e5k55¼5ñ5ø56 6%6C6o6†6Ò6Ø6ô677 70757b7g7ˆ77Ô7Û7ñ7ø7 8M8m88§8 9H9}9ï9G:R:X:Š:“: :¨:À:Ð:;X;³;<]>Œ>¨>Á>Ö>â>î>?9?n?„? ¨N0r0„00±0¿0â0ë0;1B1]1†1Ÿ1ª1£2ª2Å2Ê2Ï2333W3­3³3¹3 44C4I4m4¥4Ñ4Ö4Ü45H5²6·6¼678$898>8k8p8u8»8À8Å8 9\9Å9Ù9ø9:>:I:•:ð:õ:û:W;‡;ì;ñ;ö;b<Ï<Ö<ö<ýJ>Œ?“?à?ö?°¬0 00080?0L0!1,1:1D1O1V1d1p1ˆ11™1 1­1µ1Â1Ç1Ì1Ñ1Ü1é1õ122222G2Y2µ2Õ2(343s3}3‚3‡3¼3È3Ò3á3ð3ÿ34'4A4P4Z4k44¤4°4¸4à4ô45505D5P5X5€5”5 5¨5Ð5ä5ð5ø566,6L6`6l6t6Ð 00snort-2.9.15.1/src/win32/WIN32-Prj/Packet.dll0000555000175200017520000011012413571422610015032 00000000000000MZÿÿ¸@躴 Í!¸LÍ!This program cannot be run in DOS mode. $Ub!z rz rz r’frz r~erz r~erz rz rUz r’rQrz r'\rz rÖ| rz rîZrz rRichz rPELCŠÖMà! @@¿CPðW¿LQ pX€|0QP$.textb4@ `.rdata¯ PP@@.datap``@À.rsrcXpp@@.reloc €€@B‹D$h(`PÿÀPƒÄ…À•ÀáÀd…ÀuèRSUVW‹=Àd…ÿt@‹l$‹õOŠŠŠÐ:Ãu„ÒtŠAŠ^ŠÐ:ÃuƒÁƒÆ„ÒuÜ3ÉëɃÙÿ…Ét‹?…ÿuÄ‹Ç_^][ÃìSUVW¹¾4`|$3À󥤹w|$5ó«f«ª¡ÄdjÿPÿˆP‹Àd‹ú…ÿ‰|$‹ï„ýë‹|$‹´$GŠŠË:u„ÉtŠXŠË:^uƒÀƒÆ„Éuà3ÀëÀƒØÿ…Àt‹‹ï…À‰D$u¹é¯‹„$t$ŠŠË:u„ÉtŠXŠË:^uƒÀƒÆ„Éuà3ÀëÀƒØÿ…Àu‹ ÄdQÿŒP_^]°[ÄÃ;úu ‹‰Àd닉E‹·°‹-”P‹˜P…öt$…öt ‹¾€VÿÓPÿÕVÿÓPÿœP…ÿ‹÷uä‹|$WÿÓPÿÕWÿÓPÿœP‹ ÄdQÿŒP‹”$jR踃Ä<t èè_^]°[ÄÃQD$WPjÇD$ èÜ/ƒø2u2À_YËL$QjÿhPPÿ„P‹ø…ÿu2À_YÃT$VRWè§/‹÷Vè-‹6ƒÄ…öuñ‹5˜PWÿÖPÿ”PWÿÖPÿœP^°_YÃì¡``‹ d`‹h`S‰„$ l`UVW‰Œ$ˆ„$¹|3À¼$‰”$‹œ$ó«f«K”$ªQ¼$ƒÉÿ3Àò®÷ÑI¸R+ÁhX`L$PQèv‹=ÀdƒÄ…ÿt>wD$ŠŠÊ:u„ÉtŠPŠÊ:VuƒÀƒÆ„Éuà3ÀëÀƒØÿ…À„â‹?…ÿu‹ƒ ƒøt%ƒøt D$PèƒÄ…À„·Pè !ƒÄë è&.„À„Ÿh¸jBÿhPPÿ„P‹è…íu _^]2À[ÄÃET$¾ +Њ „Étˆ@Nuóë…öuHÆ“ …¾€+Њ „Étˆ@Nuóë…öuHÆ‹‹‰”‹“”‰•˜‹ƒ˜ì‰…œ‹Ã…Àt‹…Àuú…ÛÇ…°„©{WÿäPƒøÿ„Œhˆj@ÿhPPÿ„P‹ð…ötrW‹=äPÿ×K‰FQfÇÿ׉†„¸f‰†€Ç†ÿÿÿÿf‰†dž€‹°…Éu‰µ°ë‹€…Àt ‹È‹€…Àuô‰±€‹…Û…WÿÿÿUèA‹”$ƒÄ‹‚ ƒøtƒøu Ç…´¡Àd‰E‰-Àd_^]°[ÄÃì ¡``‹ d`‹h`S‰D$ l`UVW‰L$ ˆD$(¹|3À|$)‰T$$3Ûó«f«ª¡Èd;Ä»L$QSSj&SÿЃøot _^]2À[Ä ËT$RjÿhPPÿ„P‹ø;û‰|$u _^]2À[Ä ÃD$PWSj&SÿÈd…Àt'‹5˜PWÿÖPÿ”PWÿÖPÿœP_^]2À[Ä É|$|$ƒÉÿ3À‹”$ ò®‹D$÷Ñ‹@ ItŠŠÊ:u:ËtŠPŠÊ:VuƒÀƒÆ:Ëuà3ÀëÀƒØÿ;Ã…±‹D$‹h;ë„¢‹u ‹}fƒ>…‡hˆj@ÿhPPÿ„P‹Ð;Ó„²‹Ï‹ú‹ÁÁéó¥‹È3Àƒáó¤¹ º€ó«¹ ºó«‹„$ ‰š€‹ˆ°;Ëu‰°ë‹€;Ãt ‹È‹€;Ãuô‰‘€‹m;ë…^ÿÿÿ‹L$‹A;ÉD$…ëþÿÿ‹|$‹5˜PWÿÖPÿ”PWÿÖPÿœP_^]°[Ä Ë|$‹5˜PWÿÖPÿ”PWÿÖPÿœP_^]2À[Ä ÃQSU‹l$VW‹ýƒÉÿ3À3Ûò®÷Ñù ‰\$‡â¡ÄdjÿPÿˆP‹=Àd;ût_‹Ã^[ÃÆ>»z€_‹Ã^[ËD$=ÿÿÿv¸W€ÃS3ÛVW…Àu »W€_‹Ã^[ËL$‹|$pÿD$PQVWÿ°PƒÄ…À|;ÆwufÇw_‹Ã^[ÃfÇw»z€_‹Ã^[ÃQ¡ÄdUjÿPÿˆP‹-Àd…ítaS‹˜PVW‹µ°‹ý‹m‰|$…öt$‹¾€VÿÓPÿ”PVÿÓPÿœP…ÿ‹÷uà‹|$WÿÓPÿ”PWÿÓPÿœP…íu±_^[‰-Àdè èíÿÿè‹ ÄdQÿŒP]YÃì¡``‹ d`‹h`S‰„$  l`UVW‰Œ$0ˆ„$8¹|3À¼$9‰”$4‹-(Pó«L$3öQhf«Vh¤bh€‰t$4ªÿÕ‹,P…À…i‹D$”$,hRVPÿ0P…À…A‹D$FL$‰t$$3öQh”$4VRPÿÕ…À…óL$”$,QRPP‹D$$hŒbPÇD$4ÿP…ÀuŒ$,QèÞéÿÿƒÄ„Àt¾‹D$T$Rhjh|bPÿÕ…Àt ‹L$Q釋L$T$„$,RPjjhtbQÇD$4ÿ$P…ÀuN¼$,ƒÉÿò®÷ÑIƒùrHŒ$4”$,QRhX`D$8hPèçüÿÿL$@VQÆ„$GèäðÿÿƒÄ‹T$RÿÓ‹D$PÿÓ‹t$$‹T$Œ$,hQVRÿ0P…À„¿þÿÿ‹D$PÿÓL$Qhjhbh€ÿÕ…À…Õ‹L$T$ ‹5$PRPD$0Pjh bQÿÖ‹T$ ƒÂRjBÿhPPÿ„P‹è…íu _^]2À[ÄËT$D$ PL$,UQjh bRÿÖ‹D$PÿÓŠE3ö„ÀtI‹ýL.”$,QRhX`D$8hPèâûÿÿƒÉÿ3Àò®÷ÑIPtL$DQèÙïÿÿŠ.<.ƒÄ„Àu¹‹5˜PUÿÖPÿ”PUÿÖPÿœP_^]°[ÄÃì¹3ÀVW¾4`|$󥤹w|$)ó«f«ª¹ ¾@c¼$3Àó¥f¥¤¹u¼$3ó«ªèk„Àu _^ÄáÄdjÿPÿˆP‹=Àd…ÿt>wD$ŠŠÊ:u„ÉtŠPŠÊ:VuƒÀƒÆ„Éuà3ÀëÀƒØÿ…À„‹?…ÿuÂh¸jBÿhPPÿ„P‹ð…öu‹ ÄdQÿŒP_2À^ÄË=¼PT$h FRPÿ׌$h€–QRÿ׎˜dž¨€–˜¸0000dž dž¬dž´‰ƒÄf‰Adž”dž°‹Àd‰‰5Àd¡ÄdPÿŒP_°^ÄËD$ì ƒèVtvHud‹5|PjjjÿÖjjj£ÄdÿÖ£ÔdD$‹Œ$hPQÿ€P…Àvj@T$ h eRè ƒÄ j@hàdhlcèŒƒÄ ¸^Ä  ¡ÄdPÿP¡Àd…ÀtÜS‹˜PU‹-”PW‹°°‹8…ö‰|$t%‹¾€VÿÓPÿÕVÿÓPÿœP…ÿ‹÷uä¡Àd‹|$PÿÓPÿÕ‹ ÀdQÿÓPÿœP‹Ç…ÿ£Àduª_][¸^Ä  ¡ÔdjÿPÿˆP‹ ÌdA‰ Ìd¡Ìdƒøt‹ÔdRÿŒPÃh¤cÿtP…ÀthŒcPÿxP£Èd¡ÔdPÿŒPÃSVW‹|$3À3Ûf‹3öƒÇf…Òt3fƒú.t%fƒú0rMfƒú9wG ¶âÿÿƒÇtJÐf‹Wþf…ÒuÕþÿw& ÝÓæ ƃûuf…Òuëf…Òt Cƒû|ž_^[Ã_^ƒÈÿ[ÃVjjBÿhPPÿ„P‹ð…öu2À^ÃSW‹|$VjWÇÇFè˜VjWÇ艋=˜PƒÄŠØVÿ×Pÿ”PVÿ×PÿœPŠÃ_[^ÃQV‹t$ ‹FH…Àt jÿ@P2À^YÃjjjjÿdP…À‰D$ u2À^YËD$jPjjL$jQhðRÿlP…ÀuÿpP‹ð‹D$ PÿPVÿ@P2À^YËL$ ÇFL‰NH°^YÃì¡ðcSUVW‰„$¹3À¼$¾Ôcó«¹|$ó¥¹y|$,ó«¹¾¸c¼$3í󥤹y¼$)ó«f«h?UU2Ûªÿ P‹ð…öu _^]2À[ÄÃjjjjŒ$ jQjjjT$4hÿ„$8RPVÿP‹=P…ÀuÿpP‹èý1u 3í³ëP³ÿ×Vÿ×Uÿ@P_^ŠÃ][ÄÃì”S‹œ$œUVD$ WPSÇD$è`‹ø…ÿ„oWjÿhPPÿ„P‹ð…ö„U‹L$VWQSè)…À„&T$D$RPh@dVè…À„ ‹D$3É3Òf‹Hf‹QRhôcD$0j@PèÔõÿÿƒÄL$ T$D$$QRPVèÄ…À„Ç‹L$Qèê‹ØƒÉÿ‹û3ÀƒÄ‹”$°ò®÷ÑI;Êr7‹=˜PVÿ׋-”PPÿÕVÿ׋5œPPÿÖSÿ×PÿÕSÿ×PÿÖ_^]3À[Ä”Ãúÿÿÿw(‹„$¬‹ú…Òt‹Ó+Њ „Étˆ@Ouóë…ÿuHÆ‹=˜PVÿ׋-”PPÿÕVÿ׋5œPPÿÖSÿ×PÿÕSÿ×PÿÖ_^]¸[ĔË=˜PVÿ×Pÿ”PVÿ×PÿœP_^]3À[Ä”ÃS‹ÌPV‹t$ WVÿӃăÀPjBÿhPPÿ„PjjV‹øÿӃăÀPWjÿVjjÿDP‹Ç_^[Ãì(¡ðcSUV‰„$4W3À¹¼$<h€PPó«ÿ P‹ø…ÿu ‹-pPÿÕ鉌$8”$8QhŒdhRè›óÿÿƒÄD$Œ$8PhjQh€ÿP‹-pP…À„•èfüÿÿ%ÿ…À„“„$8jPWÿP‹ð…ö„ýL$QVÿ P…Àt ƒ|$„ÙjjVÿP…À…ÆÿÕ= „¹=·„®‹5@PPÿÖWÿPÿÕPÿÖ_^]3À[Ä(ËT$Rÿ,PémÿÿÿèÁûÿÿ%ÿ‰D$t~”$8jRWÿP‹ð…öt^D$PVÿ P…Àtƒ|$t>jjVÿP…Àu/ÿÕ‹Øû t#û·tWÿPSÿ@P_^]3À[Ä(ÃVÿPë ÿÕPÿ@PWÿPhdjBÿhPPÿ„P‹ð…öuÿÕPÿ@P_^]3À[Ä(ÃÇFDÿHP‹œ$<f=‹ûu,ƒÉÿ3Àò®÷ÑIƒùvIKT$4Qh„dhRè¾ñÿÿƒÄë9ƒÉÿ3Àò®÷ÑIƒùvCL$4PhtdhQè’ñÿÿƒÄë ¹A3À|$4ó«3À¹PPjP~PT$HhÀó«Rÿ8Pƒøÿ‰tnVèÁùÿÿƒÄ„ÀuÿÕ‹ø‹PÿPëVVè5ùÿÿFP‹ÓƒÄdž`¿ +Њ „Étˆ@OuóH_Æ‹Æ^][Ä(Ã…ÿuHÆ‹Æ_^][Ä(ÃÿÕ‹ø‹˜PVÿÓPÿ”PVÿÓPÿœPWÿ@P_^]3À[Ä(ø eøàdÃì¡ðcSVW‰D$(3Û¹3À|$,h?SSó«ÿ P‹ø…ÿt3L$(hÿQWÿP‹ð…ötT$ RjVÿPV‹5P‹ØÿÖWÿÖ_‹Ã^[ÄÃQSUVW3ÿ3í‰|$è÷ÿÿ‹\$ŠC„Àt‹óëHSÿÌP‹øƒÄGWj@ÿhPPÿ„P‹ð…öujÿ@P_^]3À[YÃSh´dWVè¯ïÿÿƒÄ¿¡ÄdjÿPÿˆPVèÜÿÿƒÄ…ÀuVèvÜÿÿVèÜÿÿƒÄ…Àt7‹€´ƒøt$ƒøt'…Àu#Vè_ûÿÿ‹èƒÄ…íuÿpP‰D$ëVèDëãÇD$‹ ÄdQÿŒP…ÿtVÿœP‹D$…ÀtPÿ@P_^]3À[YÃ_‹Å^][YÃVWhdjBÿhPPÿ„P‹ð…ötUdž`è …À‰†\tM‹T$ FP¿ +Њ „Étˆ@Ouóë…ÿuHÆ‹†\PèÐ ƒÄ‰FH‹Æ_^ÿWÿ@P_3À^ÃV¿ÿœPWÿ@P_3À^ÃV‹t$…öWtU‹†`ƒøu‹†\Pè ƒÄë…Àu5‹NHQÿt"‹Ë+ÈqŠ „Étˆ@Juóë…ÒuH‹t$Æ‹T$$‹‹T$+Å+Â=ÿÿÿw3‹L$‹ÐÍÏ…Àt%‹Ã+Á°Š„ÀtˆAJuóë…ÒuI‹t$Æ{ƒÉÿ3Àò®÷ÑI»L‰L$ƒÉÿò®‹t$‹|$ ÷ÑIl)‹…Û…7ÿÿÿ‹T$Æ>ÆD:¡ÄdPÿŒP_^]°[ƒÄ Ë ÄdQÿŒPjz‰uÿ@P_^]2À[ƒÄ ÃQ‹D$VWŠH„Ét ‹øÆD$‰|$ëPèïîÿÿƒÄ‰D$ÆD$‹øWèÐÿÿƒÄ„Àu(ŠD$„Àt‹5˜PWÿÖPÿ”PWÿÖPÿœP_2À^YáÄdSjÿPÿˆPWègÏÿÿƒÄ…Àt_‹ˆ°3Ò…Ét ‹‰€B…Éuõ‹\$;}‰‹ ‹€°3ÒU…É~*‹l$…Àt"¹`‹ð‹ýBó¥‹ ‹€€‹|$Å€;Ñ|Ú³]ë2Û‹ ÄdQÿŒPŠD$„Àt‹5˜PWÿÖPÿ”PWÿÖPÿœPŠÃ[_^YáÄdSjÿPÿˆP‹L$ƒÁPQè¤ÎÿÿƒÄ…Àt2‹T$  ³‹‰ ‹H‰J‹H‰J‹@ ‰B ‹ ÄdQÿŒPŠÃ[Ë Äd2ÛQÿŒPŠÃ[Ãÿ%Qÿ%Qÿ% Qÿ%øPÿ%Qÿ%Qÿ%Qÿ%üPÿ%ìPÿ%ôPÿ%ðPÿ%Qÿ%ÜPÿ%ØPÿ%ÔPÌÌÌÌÌÌWVS3ÿ‹D$ À}G‹T$÷Ø÷ڃ؉D$‰T$‹D$ À}G‹T$÷Ø÷ڃ؉D$‰T$ Àu‹L$‹D$3Ò÷ñ‹Ø‹D$÷ñ‹ÓëA‹Ø‹L$‹T$‹D$ÑëÑÙÑêÑØ Ûuô÷ñ‹ð÷d$‹È‹D$÷æÑr;T$wr;D$vN3Ò‹ÆOu÷Ú÷؃Ú[^_ÂÌÌÌÌÌÌ‹D$‹L$ È‹L$ u ‹D$÷áÂS÷á‹Ø‹D$÷d$Ø‹D$÷áÓ[‹D$…Àu9Ðd~.ÿ Ðd‹ ÈPƒø‹ ‰ `eu?h€ÿÄP…ÀY£heu3Àëfƒ ¡heh`h`£deèêÿÐdYYë=…Àu9¡he…Àt0‹ deVqü;ðr‹…ÉtÿÑ¡heƒîëêPÿ¨Pƒ%heY^jX U‹ìS‹]V‹u W‹}…öu ƒ=Ðdë&ƒþtƒþu"¡le…Àt WVSÿÐ…Àt WVSèÿÿÿ…Àu3ÀëNWVSè‘åÿÿƒþ‰E u …Àu7WPSèñþÿÿ…ötƒþu&WVSèàþÿÿ…Àu!E ƒ} t¡le…ÀtWVSÿЉE ‹E _^[] ÿ%¤PUôT0TÎT¾TäTšT„T¬TbTRTDTvTCloseServiceHandledCreateServiceA¬OpenSCManagerWAStartServiceWÁQueryServiceStatus­OpenServiceAâRegOpenKeyExABControlServiceADVAPI32.dllGetAdaptersInfoiphlpapi.dll VerQueryValueWGetFileVersionInfoWGetFileVersionInfoSizeWVERSION.dllíwcsstrÁstrncpyèwcsncmpæwcslenëwcsrchrá_vsnprintfâ_vsnwprintfMSVCRT.dll^free_initterm‘malloc_adjust_fdivõGlobalFreeøGlobalHandleGlobalUnlock¸ReleaseMutex…WaitForSingleObjectùGlobalLockîGlobalAlloc.CloseHandlevGetModuleFileNameW[CreateMutexW˜GetProcAddresszGetModuleHandleWiGetLastErrorƒDeviceIoControlJCreateEventWSetLastError‰WideCharToMultiByteMCreateFileAÞGetVersion SetEvent«ReadFile—WriteFilešQueryPerformanceFrequency™QueryPerformanceCounterbGetFullPathNameWkMultiByteToWideCharKERNEL32.dllCŠÖMXY X˜XY°5@5Ð5P>p<3@@`A;€<ð<ð26 : e3 6p= 6à6Ð;€;P:9À=0<`8°8;P;p<3cYxY‹YœY²YÉYàYóYZZ&Z7ZHZYZkZ€Z’Z¦Z´ZÅZ×ZäZòZ[[*[D[W[e[x[[ž[ packet.dllPacketAllocatePacketPacketCloseAdapterPacketFreePacketPacketGetAdapterNamesPacketGetAirPcapHandlePacketGetDriverVersionPacketGetNetInfoExPacketGetNetTypePacketGetReadEventPacketGetStatsPacketGetStatsExPacketGetVersionPacketInitPacketPacketIsDumpEndedPacketLibraryVersionPacketOpenAdapterPacketReceivePacketPacketRequestPacketSendPacketPacketSendPacketsPacketSetBpfPacketSetBuffPacketSetDumpLimitsPacketSetDumpNamePacketSetHwFilterPacketSetLoopbackBehaviorPacketSetMinToCopyPacketSetModePacketSetNumWritesPacketSetReadTimeoutPacketSetSnapLenPacketStopDriverPACKET.DLL1394\Device\NPF_GenericDialupAdapter%s%s\Device\NPF_SubnetMaskDhcpSubnetMaskDhcpIPAddressIPAddressEnableDHCPUseZeroBroadcastTcpIpParametersSYSTEM\CurrentControlSet\ServicesSYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces%SNPF_bindSYSTEM\CurrentControlSet\Services\Tcpip\LinkageExportLinkageComponentIdSYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}Adapter for generic dialup and VPN capturedrivers\NPF.sysGetAdaptersAddressesIphlpapisystem32\drivers\NPF.sysWinPcap Packet Driver (NPF)NPF\StringFileInfo\%04x%04x\FileVersion\VarFileInfo\Translation\\.\Global\%s\\.\%sSYSTEM\CurrentControlSet\Services\%s%ws€0€H`pôô4VS_VERSION_INFO½ïþÙÙTStringFileInfo0000004b0PCompanyNameCACE Technologies, Inc.t&FileDescriptionpacket.dll (NT5) Dynamic Link Library6 FileVersion4.1.0.17536 InternalNamepacket.dllä`LegalCopyrightCopyright © 2005-2009 CACE Technologies. Copyright © 1999-2005 NetGroup, Politecnico di Torino.(LegalTrademarks> OriginalFilenamepacket.dll0ProductNameWinPcap: ProductVersion4.1.0.1753,Build DescriptionDVarFileInfo$Translation°ð0 0!040 0¼0Å0Ë0g1n1‡1š1 1¾1Ø1Þ1å1I2P2~2ˆ2’2§2­2³2À23,3»3Â3v4Œ4“4 4D5M5g5m5s5}5£5Ö5Ý5666"6°6·6R7\7f7}7‡7‘7×7à7æ70868‡8‘8›8­8´8Á8È8ä8*9J9V9b9w9~9b:o:y:‹:“:š: :·:¾:);3;=;W;];d;¾;à;û;<)<9Y>`>??$?.?8?T?c?q?ÿ? 800;0B0æ0í01 1121A1O1Ù1ò1'2-232<2`2¢2©2Í2×2á2ë2l3v3€3Ú3J4‚4Œ4’44Â4Ì4à4ê4÷4 55'5-535@5l5‚5”5µ5þ5 6?6j6y6¦6ö6737A7T7[7„7«7æ7ð7ú7 8?8s8|8‚8Ñ8Ø8ä8ë8ü8x9€9…9Œ9µ9È9Ï9ç9ö9: :':.:3:>:E:l:w:‡:‘:š:Á:Ê:Ð:×:Ü:ç:î:ô:ú:; ;;;;§;®;é;ø;,>„>>™>ë>ô>?%?/?9?S?k?r??§?Ï?Û?ö?0Ü#0)0T0j0„0ª0´0Ñ0÷0 11>1E1Y1d1k1x11Ž1¨1Ó1ÿ1>2_2½2Ç2Ñ2Ø2ñ233:3Q3e3l3´3Ã3Ê3Ø3æ3ú34L4h4o4z4‰4«4²45*515p5y5‡5‘5›5¶5½5Ø5â5ì5n6‰6Ê67)7h7ó7/8¡8ñ8a99‰9“9¿9Ó9Ý9ç9:#:>:“:Ã:ã:=;Á;!<]<Ç<9=¬=â=é=>'>1>h>q>w>>ˆ>–>ú>@x0 00$0/0†00š0¥0¯0#1*181B1L1a1k1¦1­1·1À1Ò1Ø1Þ1ä1ê1ð1ö1ü122222 2&23&3,373D3L3Z3_3d3i3t33‹3 3¬3²3Ô3æ3B4^4NB10CŠÖMD:\temp\winpcap\packetNtx\Dll\Project\Release_No_AirPcap\Packet.pdbsnort-2.9.15.1/src/win32/WIN32-Prj/snort_installer.nsi0000444000175200017520000002015213571422610017061 00000000000000; $Id$ ; ; NSIS Installation script for Snort 2.9.15.1 Win32 ; Written by Chris Reid ; Updated by Steven Sturges ; ; This script will create a Win32 installer for Snort 2.9.15.1 (Win32 only). ; For more information about NSIS, see their homepage: ; http://nsis.sourceforge.net/ ; ; Note that this NSIS script is designed for NSIS version 2.09. ; Name "Snort 2.9.15.1" CRCCheck On !include "MUI.nsh" !define TEMP $R0 ;-------------------------------- ;Configuration ;General OutFile "Snort_2_9_15_1_Installer.exe" ; The name of the installer executable ;Folder selection page InstallDir "C:\Snort" ;-------------------------------- ;Modern UI Configuration !define MUI_CUSTOMPAGECOMMANDS !define MUI_LICENSEPAGE !define MUI_COMPONENTSPAGE !define MUI_DIRECTORYPAGE !define MUI_ABORTWARNING !define MUI_UNINSTALLER !define MUI_UNCONFIRMPAGE ;-------------------------------- ;Languages !insertmacro MUI_LANGUAGE "English" ;-------------------------------- ;Language Strings ;Description LangString DESC_Snort ${LANG_ENGLISH} "Install snort, configuration files, and rules." LangString DESC_Dynamic ${LANG_ENGLISH} "Install dynamic preprocessor and dynamic engine modules." LangString DESC_Doc ${LANG_ENGLISH} "Install snort documentation." ;-------------------------------- ;Data LicenseData "..\..\..\LICENSE" ;-------------------------------- ;Pages !insertmacro MUI_PAGE_LICENSE "..\..\..\LICENSE" Page custom fnSetHeaderText !insertmacro MUI_PAGE_COMPONENTS Page custom fnSetHeaderText !insertmacro MUI_PAGE_DIRECTORY Page custom fnSetHeaderText !insertmacro MUI_PAGE_INSTFILES ; Call .onDirectoryLeave whenever user leaves ; the directory selection page ;!define MUI_CUSTOMFUNCTION_DIRECTORY_LEAVE onDirectoryLeave ;-------------------------------- ; Event Handlers Function .onInstSuccess StrCpy $0 "Snort has successfully been installed.$\r$\n" StrCpy $0 "$0$\r$\n" StrCpy $0 "$0$\r$\n" StrCpy $0 "$0Snort also requires WinPcap 4.1.1 to be installed on this machine.$\r$\n" StrCpy $0 "$0WinPcap can be downloaded from:$\r$\n" StrCpy $0 "$0 http://www.winpcap.org/ $\r$\n" StrCpy $0 "$0$\r$\n" StrCpy $0 "$0$\r$\n" StrCpy $0 "$0It would also be wise to tighten the security on the Snort installation$\r$\n" StrCpy $0 "$0directory to prevent any malicious modification of the Snort executable.$\r$\n" StrCpy $0 "$0$\r$\n" StrCpy $0 "$0$\r$\n" StrCpy $0 "$0Next, you must manually edit the 'snort.conf' file to$\r$\n" StrCpy $0 "$0specify proper paths to allow Snort to find the rules files$\r$\n" StrCpy $0 "$0and classification files." MessageBox MB_OK $0 FunctionEnd ;-------------------------------- ;Installer Sections Section "Snort" Snort ; -------------------------------------------------------------------- ; NOTE: The installer, as delivered here, will only allow the user ; to install configurations which can optionally be run as a ; Windows Service. ; -------------------------------------------------------------------- ; Search for a space embedded within $INSTDIR StrCpy $R4 0 ; index within $INSTDIR searching_for_space: StrCpy $R5 $INSTDIR 1 $R4 ; copy 1 char from $INSTDIR[$R4] into $R5 StrCmp $R5 " " found_space StrCmp $R5 "" done_searching_for_space IntOp $R4 $R4 + 1 ; increment index Goto searching_for_space found_space: StrCpy $0 "The installation directory appears to contain an$\r$\n" StrCpy $0 "$0embedded space character. You need to be aware that$\r$\n" StrCpy $0 "$0because of this, all paths specified on the command-line$\r$\n" StrCpy $0 "$0and in the 'snort.conf' file must be enclosed within$\r$\n" StrCpy $0 "$0double-quotes.$\r$\n" MessageBox MB_OK $0 done_searching_for_space: CreateDirectory "$INSTDIR" CreateDirectory "$INSTDIR\bin" SetOutPath "$INSTDIR\bin" ; File ".\LibnetNT.dll" File ".\pcre.dll" File ".\zlib1.dll" File ".\ntwdblib.dll" File ".\wpcap.dll" File ".\WanPacket.dll" File ".\npptools.dll" File ".\Packet.dll" CreateDirectory "$INSTDIR\etc" SetOutPath "$INSTDIR\etc" File "..\..\..\etc\*.conf" File "..\..\..\etc\*.config" File "..\..\..\etc\*.map" CreateDirectory "$INSTDIR\rules" SetOutPath "$INSTDIR\rules" ;Rules are no longer part of the distribution ;File /r "..\..\..\rules\*.rules" CreateDirectory "$INSTDIR\preproc_rules" SetOutPath "$INSTDIR\preproc_rules" File "..\..\..\preproc_rules\*.rules" CreateDirectory "$INSTDIR\log" SetOutPath "$INSTDIR\bin" ; -------------------------------------------------------------------- ; Configurations ; -------------------------------------------------------------------- File ".\snort___Win32_Release\snort.exe" ;Create uninstaller SetOutPath "$INSTDIR" WriteUninstaller "$INSTDIR\Uninstall.exe" SectionEnd Section "Dynamic Modules" Dynamic CreateDirectory "$INSTDIR\lib" CreateDirectory "$INSTDIR\lib\snort_dynamicpreprocessor" SetOutPath "$INSTDIR\lib\snort_dynamicpreprocessor" File "..\..\dynamic-preprocessors\ftptelnet\Release\sf_ftptelnet.dll" File "..\..\dynamic-preprocessors\smtp\Release\sf_smtp.dll" File "..\..\dynamic-preprocessors\ssh\Release\sf_ssh.dll" File "..\..\dynamic-preprocessors\dns\Release\sf_dns.dll" File "..\..\dynamic-preprocessors\ssl\Release\sf_ssl.dll" File "..\..\dynamic-preprocessors\dcerpc2\Release\sf_dce2.dll" File "..\..\dynamic-preprocessors\sdf\Release\sf_sdf.dll" File "..\..\dynamic-preprocessors\sip\Release\sf_sip.dll" File "..\..\dynamic-preprocessors\imap\Release\sf_imap.dll" File "..\..\dynamic-preprocessors\pop\Release\sf_pop.dll" File "..\..\dynamic-preprocessors\reputation\Release\sf_reputation.dll" File "..\..\dynamic-preprocessors\modbus\Release\sf_modbus.dll" File "..\..\dynamic-preprocessors\dnp3\Release\sf_dnp3.dll" File "..\..\dynamic-preprocessors\gtp\Release\sf_gtp.dll" CreateDirectory "$INSTDIR\lib\snort_dynamicengine" SetOutPath "$INSTDIR\lib\snort_dynamicengine" File ".\SF_Engine_Release\sf_engine.dll" SectionEnd Section "Documentation" Doc CreateDirectory "$INSTDIR\doc" SetOutPath "$INSTDIR\doc" File "..\..\..\ChangeLog" File "..\..\..\LICENSE" File "..\..\..\RELEASE.NOTES" File "..\..\..\doc\*.*" Delete "$INSTDIR\doc\.cvsignore" CreateDirectory "$INSTDIR\doc\signatures" SetOutPath "$INSTDIR\doc\signatures" ;Rules are no longer part of the distribution ;File "..\..\..\doc\signatures\*.*" SectionEnd ;Display the Finish header ;Insert this macro after the sections if you are not using a finish page ;!insertmacro MUI_SECTIONS_FINISHHEADER ;-------------------------------- ;Descriptions !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN !insertmacro MUI_DESCRIPTION_TEXT ${Snort} $(DESC_Snort) !insertmacro MUI_DESCRIPTION_TEXT ${Dynamic} $(DESC_Dynamic) !insertmacro MUI_DESCRIPTION_TEXT ${Doc} $(DESC_Doc) !insertmacro MUI_FUNCTION_DESCRIPTION_END ;-------------------------------- ; Installer Functions Function fnSetHeaderText !insertmacro MUI_HEADER_TEXT "$(TEXT_IO_PAGETITLE_OPTIONS)" "" FunctionEnd ;-------------------------------- ;Uninstaller Section Section "Uninstall" ; If Snort appears to already be installed as a Windows Service, ; then ask the user if the uninstall should unregister the ; Service. ReadRegStr $1 HKLM "Software\Snort" "CmdLineParamCount" StrCmp $1 "" service_not_registered MessageBox MB_YESNO "It appears that Snort is registered as a Windows Service. Should it be unregistered now?" IDNO finished_unregistering_service ExecWait "net stop snortsvc" ExecWait "$INSTDIR\bin\snort.exe /SERVICE /UNINSTALL" GoTo finished_unregistering_service service_not_registered: MessageBox MB_OK "Snort not installed as a service" finished_unregistering_service: RMDir /r "$INSTDIR" ;!insertmacro MUI_UNFINISHHEADER SectionEnd snort-2.9.15.1/src/win32/WIN32-Prj/snort_installer_options.ini0000444000175200017520000000073513571422610020627 00000000000000; $Id$ ; ; NSIS Installation script for Snort 2.2 Win32 ; Written by Chris Reid ; ; This script will create a Win32 installer for Snort 2.2 (Win32 only). ; For more information about NSIS, see their homepage: ; http://www.nullsoft.com/free/nsis/ ; ; This INI script is intended to be used in conjunction with ; snort_installer.nsi. [Settings] NumFields=1 [Field 1] Type=checkbox Text=Enable IPv6 support. Left=0 Right=-1 Top=120 Bottom=140 State=0 snort-2.9.15.1/src/win32/WIN32-Prj/snort.dep0000444000175200017520000000042613571422610014765 00000000000000# Microsoft Developer Studio Generated Dependency File, included by snort.mak # This file has intentionally been truncated because it includes machine-specific # drive/path information, which break the compile on machines which install # Visual C++ in another location. snort-2.9.15.1/src/win32/WIN32-Prj/snort.dsp0000444000175200017520000015275013571422610015013 00000000000000# Microsoft Developer Studio Project File - Name="snort" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Console Application" 0x0103 CFG=snort - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "snort.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "snort.mak" CFG="snort - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "snort - Win32 Release" (based on "Win32 (x86) Console Application") !MESSAGE "snort - Win32 Debug" (based on "Win32 (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "snort - Win32 Release" # PROP BASE Use_MFC 2 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "snort___Win32_Release0" # PROP BASE Intermediate_Dir "snort___Win32_Release0" # PROP BASE Ignore_Export_Lib 0 # PROP BASE Target_Dir "" # PROP Use_MFC 2 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "snort___Win32_Release" # PROP Intermediate_Dir "snort___Win32_Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "..\..\dynamic-output\plugins" /I "..\Win32-Includes\zlib" /I "..\..\.." /I "..\.." /I "..\..\control" /I "..\..\sfutil" /I "..\..\target-based" /I "..\Win32-Includes" /I "..\Win32-Includes\libnet" /I "..\Win32-Includes\WinPCAP" /I "..\..\output-plugins" /I "..\..\detection-plugins" /I "..\..\dynamic-plugins" /I "..\..\preprocessors" /I "..\..\preprocessors\portscan" /I "..\..\preprocessors\HttpInspect\Include" /I "..\..\preprocessors\Stream5" /I "..\..\..\daq\api" /I "..\..\..\daq\sfbpf" /I "..\Win32-Includes\libdnet" /D "NDEBUG" /D "OUTPUT_DLL" /D "_CONSOLE" /D __BEGIN_DECLS="" /D __END_DECLS="" /D "ENABLE_RESPOND" /D "ENABLE_WIN32_SERVICE" /D "ZLIB" /D "ENABLE_RESPONSE3" /D "_WINDOWS" /D "_USRDLL" /D "ACTIVE_RESPONSE" /D "ENABLE_REACT" /D "GRE" /D "MPLS" /D "TARGET_BASED" /D "PERF_PROFILING" /D "ENABLE_PAF" /D "WIN32" /D "_MBCS" /D "HAVE_CONFIG_H" /D "_AFXDLL" /D SIGNAL_SNORT_READ_ATTR_TBL=30 /FD /c # SUBTRACT BASE CPP /YX # ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\dynamic-output\plugins" /I "..\Win32-Includes\zlib" /I "..\..\.." /I "..\.." /I "..\..\control" /I "..\..\sfutil" /I "..\..\target-based" /I "..\Win32-Includes" /I "..\Win32-Includes\libnet" /I "..\Win32-Includes\WinPCAP" /I "..\..\output-plugins" /I "..\..\detection-plugins" /I "..\..\dynamic-plugins" /I "..\..\preprocessors" /I "..\..\preprocessors\portscan" /I "..\..\preprocessors\HttpInspect\Include" /I "..\..\preprocessors\Stream6" /I "..\..\preprocessors\Session" /I "..\..\..\daq\api" /I "..\..\..\daq\sfbpf" /I "..\Win32-Includes\libdnet" /I "..\..\file-process" /I "..\..\file-process\libs" /I "..\..\side-channel" /D "NDEBUG" /D "OUTPUT_DLL" /D "_CONSOLE" /D __BEGIN_DECLS="" /D __END_DECLS="" /D "ENABLE_RESPOND" /D "ENABLE_WIN32_SERVICE" /D "ZLIB" /D "ENABLE_RESPONSE3" /D "_WINDOWS" /D "_USRDLL" /D "ACTIVE_RESPONSE" /D "ENABLE_REACT" /D "GRE" /D "MPLS" /D "TARGET_BASED" /D "PERF_PROFILING" /D "ENABLE_PAF" /D "WIN32" /D "_MBCS" /D "HAVE_CONFIG_H" /D "_AFXDLL" /D SIGNAL_SNORT_READ_ATTR_TBL=30 /D "NORMALIZER" /D BYTE_ORDER=LITTLE_ENDIAN /FD /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL" # ADD RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 zlib.lib dnet.lib daq.lib Packet.lib iphlpapi.lib wsock32.lib advapi32.lib pcre.lib wpcap.lib /nologo /subsystem:console /machine:I386 /out:"snort___Win32_Release/snort.exe" /libpath:"..\..\..\daq\Release" /libpath:"..\Win32-Libraries" /libpath:"..\Win32-Libraries\libdnet" # SUBTRACT BASE LINK32 /incremental:yes # ADD LINK32 zlib.lib dnet.lib daq.lib Packet.lib iphlpapi.lib wsock32.lib advapi32.lib pcre.lib wpcap.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\daq\Release" /libpath:"..\Win32-Libraries" /libpath:"..\Win32-Libraries\libdnet" # SUBTRACT LINK32 /incremental:yes !ELSEIF "$(CFG)" == "snort - Win32 Debug" # PROP BASE Use_MFC 2 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "snort___Win32_Debug0" # PROP BASE Intermediate_Dir "snort___Win32_Debug0" # PROP BASE Ignore_Export_Lib 0 # PROP BASE Target_Dir "" # PROP Use_MFC 2 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "snort___Win32_Debug" # PROP Intermediate_Dir "snort___Win32_Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\..\dynamic-output\plugins" /I "..\Win32-Includes\mysql" /I "..\Win32-Includes\zlib" /I "..\..\.." /I "..\.." /I "..\..\control" /I "..\..\sfutil" /I "..\..\target-based" /I "..\Win32-Includes" /I "..\Win32-Includes\libnet" /I "..\Win32-Includes\WinPCAP" /I "..\..\output-plugins" /I "..\..\detection-plugins" /I "..\..\dynamic-plugins" /I "..\..\preprocessors" /I "..\..\preprocessors\portscan" /I "..\..\preprocessors\HttpInspect\Include" /I "..\..\preprocessors\Stream5" /I "..\..\..\daq\api" /I "..\..\..\daq\sfbpf" /I "..\Win32-Includes\libdnet" /D "_DEBUG" /D "DEBUG" /D "OUTPUT_DLL" /D "_CONSOLE" /D __BEGIN_DECLS="" /D __END_DECLS="" /D "ENABLE_RESPOND" /D "ENABLE_WIN32_SERVICE" /D "ZLIB" /D "ENABLE_RESPONSE3" /D "_WINDOWS" /D "_USRDLL" /D "ACTIVE_RESPONSE" /D "ENABLE_REACT" /D "GRE" /D "MPLS" /D "TARGET_BASED" /D "PERF_PROFILING" /D "ENABLE_PAF" /D "WIN32" /D "_MBCS" /D "HAVE_CONFIG_H" /D "_AFXDLL" /D SIGNAL_SNORT_READ_ATTR_TBL=30 /FR /FD /GZ /c # SUBTRACT BASE CPP /YX # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\..\dynamic-output\plugins" /I "..\Win32-Includes\zlib" /I "..\..\.." /I "..\.." /I "..\..\control" /I "..\..\sfutil" /I "..\..\target-based" /I "..\Win32-Includes" /I "..\Win32-Includes\libnet" /I "..\Win32-Includes\WinPCAP" /I "..\..\output-plugins" /I "..\..\detection-plugins" /I "..\..\dynamic-plugins" /I "..\..\preprocessors" /I "..\..\preprocessors\portscan" /I "..\..\preprocessors\HttpInspect\Include" /I "..\..\preprocessors\Stream6" /I "..\..\preprocessors\Session" /I "..\..\..\daq\api" /I "..\..\..\daq\sfbpf" /I "..\Win32-Includes\libdnet" /I "..\..\file-process" /I "..\..\file-process\libs" /I "..\..\side-channel" /D "_DEBUG" /D "DEBUG" /D "OUTPUT_DLL" /D "_CONSOLE" /D __BEGIN_DECLS="" /D __END_DECLS="" /D "ENABLE_RESPOND" /D "ENABLE_WIN32_SERVICE" /D "ZLIB" /D "ENABLE_RESPONSE3" /D "_WINDOWS" /D "_USRDLL" /D "ACTIVE_RESPONSE" /D "ENABLE_REACT" /D "GRE" /D "MPLS" /D "TARGET_BASED" /D "PERF_PROFILING" /D "ENABLE_PAF" /D "WIN32" /D "_MBCS" /D "HAVE_CONFIG_H" /D "_AFXDLL" /D SIGNAL_SNORT_READ_ATTR_TBL=30 /D "NORMALIZER" /D BYTE_ORDER=LITTLE_ENDIAN /FR /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL" # ADD RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 zlib.lib dnet.lib daq.lib Packet.lib iphlpapi.lib wsock32.lib advapi32.lib pcre.lib wpcap.lib /nologo /subsystem:console /debug /machine:I386 /out:"snort___Win32_Debug/snort.exe" /pdbtype:sept /libpath:"..\..\..\daq\Debug" /libpath:"..\Win32-Libraries" /libpath:"..\Win32-Libraries\libdnet" # ADD LINK32 zlib.lib dnet.lib daq.lib Packet.lib iphlpapi.lib wsock32.lib advapi32.lib pcre.lib wpcap.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\daq\Debug" /libpath:"..\Win32-Libraries" /libpath:"..\Win32-Libraries\libdnet" !ENDIF # Begin Target # Name "snort - Win32 Release" # Name "snort - Win32 Debug" # Begin Group "Source" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Group "Detection Plugins" # PROP Default_Filter "" # Begin Source File SOURCE="..\..\detection-plugins\detection_options.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\detection_options.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sf_snort_plugin_hdropts.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_asn1.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_asn1.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_asn1_detect.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_asn1_detect.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_base64_data.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_base64_data.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_base64_decode.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_base64_decode.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_byte_check.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_byte_check.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_byte_math.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_byte_math.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_byte_extract.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_byte_extract.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_byte_jump.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_byte_jump.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_clientserver.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_clientserver.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_cvs.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_cvs.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_dsize_check.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_dsize_check.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_file_data.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_file_data.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_file_type.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_file_type.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_flowbits.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_flowbits.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_ftpbounce.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_ftpbounce.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_hdr_opt_wrap.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_hdr_opt_wrap.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_icmp_code_check.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_icmp_code_check.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_icmp_id_check.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_icmp_id_check.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_icmp_seq_check.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_icmp_seq_check.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_icmp_type_check.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_icmp_type_check.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_ip_fragbits.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_ip_fragbits.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_ip_id_check.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_ip_id_check.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_ip_proto.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_ip_proto.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_ip_same_check.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_ip_same_check.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_ip_tos_check.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_ip_tos_check.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_ipoption_check.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_ipoption_check.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_isdataat.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_isdataat.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_pattern_match.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_pattern_match.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_pcre.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_pcre.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_pkt_data.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_pkt_data.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_react.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_react.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_replace.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_replace.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_respond.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_respond3.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_rpc_check.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_rpc_check.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_session.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_session.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_tcp_ack_check.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_tcp_ack_check.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_tcp_flag_check.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_tcp_flag_check.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_tcp_seq_check.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_tcp_seq_check.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_tcp_win_check.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_tcp_win_check.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_ttl_check.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_ttl_check.h" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_urilen_check.c" # End Source File # Begin Source File SOURCE="..\..\detection-plugins\sp_urilen_check.h" # End Source File # End Group # Begin Group "Output Plugins" # PROP Default_Filter "" # Begin Source File SOURCE="..\..\output-plugins\spo_alert_fast.c" # End Source File # Begin Source File SOURCE="..\..\output-plugins\spo_alert_fast.h" # End Source File # Begin Source File SOURCE="..\..\output-plugins\spo_alert_full.c" # End Source File # Begin Source File SOURCE="..\..\output-plugins\spo_alert_full.h" # End Source File # Begin Source File SOURCE="..\..\output-plugins\spo_alert_sf_socket.c" # End Source File # Begin Source File SOURCE="..\..\output-plugins\spo_alert_sf_socket.h" # End Source File # Begin Source File SOURCE="..\..\output-plugins\spo_alert_syslog.c" # End Source File # Begin Source File SOURCE="..\..\output-plugins\spo_alert_syslog.h" # End Source File # Begin Source File SOURCE="..\..\output-plugins\spo_alert_test.c" # End Source File # Begin Source File SOURCE="..\..\output-plugins\spo_alert_test.h" # End Source File # Begin Source File SOURCE="..\..\output-plugins\spo_alert_unixsock.c" # End Source File # Begin Source File SOURCE="..\..\output-plugins\spo_alert_unixsock.h" # End Source File # Begin Source File SOURCE="..\..\output-plugins\spo_csv.c" # End Source File # Begin Source File SOURCE="..\..\output-plugins\spo_csv.h" # End Source File # Begin Source File SOURCE="..\..\output-plugins\spo_log_ascii.c" # End Source File # Begin Source File SOURCE="..\..\output-plugins\spo_log_ascii.h" # End Source File # Begin Source File SOURCE="..\..\output-plugins\spo_log_null.c" # End Source File # Begin Source File SOURCE="..\..\output-plugins\spo_log_null.h" # End Source File # Begin Source File SOURCE="..\..\output-plugins\spo_log_tcpdump.c" # End Source File # Begin Source File SOURCE="..\..\output-plugins\spo_log_tcpdump.h" # End Source File # Begin Source File SOURCE="..\..\output-plugins\spo_unified2.c" # End Source File # Begin Source File SOURCE="..\..\output-plugins\spo_unified2.h" # End Source File # End Group # Begin Group "Parser" # PROP Default_Filter "" # Begin Source File SOURCE=..\..\parser\IpAddrSet.c # End Source File # Begin Source File SOURCE=..\..\parser\IpAddrSet.h # End Source File # End Group # Begin Group "Preprocessors" # PROP Default_Filter "" # Begin Group "HttpInspect" # PROP Default_Filter "" # Begin Group "Anomaly Detection" # PROP Default_Filter "" # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\anomaly_detection\hi_ad.c # End Source File # End Group # Begin Group "Client" # PROP Default_Filter "" # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\client\hi_client.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\client\hi_client_norm.c # End Source File # End Group # Begin Group "Event Output" # PROP Default_Filter "" # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\event_output\hi_eo_log.c # End Source File # End Group # Begin Group "Include" # PROP Default_Filter "" # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\include\file_decomp.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\include\file_decomp_PDF.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\include\file_decomp_SWF.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\include\hi_ad.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\include\hi_client.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\include\hi_client_norm.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\include\hi_cmd_lookup.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\include\hi_eo.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\include\hi_eo_events.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\include\hi_eo_log.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\include\hi_include.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\include\hi_mi.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\include\hi_norm.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\include\hi_paf.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\include\hi_return_codes.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\include\hi_server.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\include\hi_server_norm.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\include\hi_si.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\include\hi_ui_config.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\include\hi_ui_iis_unicode_map.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\include\hi_ui_server_lookup.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\include\hi_util.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\include\hi_util_hbm.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\include\hi_util_kmap.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\include\hi_util_xmalloc.h # End Source File # End Group # Begin Group "Mode Inspection" # PROP Default_Filter "" # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\mode_inspection\hi_mi.c # End Source File # End Group # Begin Group "Normalization" # PROP Default_Filter "" # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\normalization\hi_norm.c # End Source File # End Group # Begin Group "Server" # PROP Default_Filter "" # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\server\hi_server.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\server\hi_server_norm.c # End Source File # End Group # Begin Group "Session Inspection" # PROP Default_Filter "" # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\session_inspection\hi_si.c # End Source File # End Group # Begin Group "User Interface" # PROP Default_Filter "" # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\user_interface\hi_ui_config.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\user_interface\hi_ui_iis_unicode_map.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\user_interface\hi_ui_server_lookup.c # End Source File # End Group # Begin Group "Utils" # PROP Default_Filter "" # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\utils\hi_cmd_lookup.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\utils\hi_paf.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\utils\hi_util_hbm.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\utils\hi_util_kmap.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\utils\hi_util_xmalloc.c # End Source File # End Group # Begin Group "files" # PROP Default_Filter "" # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\files\file_decomp.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\files\file_decomp_PDF.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\HttpInspect\files\file_decomp_SWF.c # End Source File # End Group # End Group # Begin Group "Stream6" # PROP Default_Filter "" # Begin Source File SOURCE=..\..\preprocessors\Stream6\snort_stream_icmp.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\Stream6\snort_stream_icmp.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\Stream6\snort_stream_ip.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\Stream6\snort_stream_ip.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\Stream6\snort_stream_tcp.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\Stream6\snort_stream_tcp.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\Stream6\snort_stream_udp.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\Stream6\snort_stream_udp.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\Stream6\stream_common.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\Stream6\stream_common.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\Stream6\stream_paf.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\Stream6\stream_paf.h # End Source File # End Group # Begin Group "Session" # PROP Default_Filter "" # Begin Source File SOURCE=..\..\preprocessors\Session\session_common.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\Session\session_common.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\Session\session_expect.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\Session\session_expect.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\Session\snort_session.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\Session\snort_session.h # End Source File # End Group # Begin Source File SOURCE=..\..\preprocessors\normalize.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\normalize.h # End Source File # Begin Source File SOURCE="..\..\preprocessors\perf-base.c" # End Source File # Begin Source File SOURCE="..\..\preprocessors\perf-base.h" # End Source File # Begin Source File SOURCE="..\..\preprocessors\perf-event.c" # End Source File # Begin Source File SOURCE="..\..\preprocessors\perf-event.h" # End Source File # Begin Source File SOURCE="..\..\preprocessors\perf-flow.c" # End Source File # Begin Source File SOURCE="..\..\preprocessors\perf-flow.h" # End Source File # Begin Source File SOURCE=..\..\preprocessors\perf.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\perf.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\perf_indicators.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\perf_indicators.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\portscan.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\portscan.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\session_api.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\session_api.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\sfprocpidstats.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\sfprocpidstats.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\snort_httpinspect.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\snort_httpinspect.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\spp_arpspoof.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\spp_arpspoof.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\spp_bo.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\spp_bo.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\spp_frag3.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\spp_frag3.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\spp_httpinspect.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\spp_httpinspect.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\spp_normalize.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\spp_normalize.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\spp_perfmonitor.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\spp_perfmonitor.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\spp_rpc_decode.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\spp_rpc_decode.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\spp_session.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\spp_session.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\spp_sfportscan.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\spp_sfportscan.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\spp_stream6.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\spp_stream6.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\str_search.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\str_search.h # End Source File # Begin Source File SOURCE=..\..\preprocessors\stream_api.c # End Source File # Begin Source File SOURCE=..\..\preprocessors\stream_api.h # End Source File # End Group # Begin Group "SFUtil" # PROP Default_Filter "" # Begin Source File SOURCE=..\..\sfutil\acsmx.c # End Source File # Begin Source File SOURCE=..\..\sfutil\acsmx.h # End Source File # Begin Source File SOURCE=..\..\sfutil\acsmx2.c # End Source File # Begin Source File SOURCE=..\..\sfutil\acsmx2.h # End Source File # Begin Source File SOURCE=..\..\sfutil\asn1.c # End Source File # Begin Source File SOURCE=..\..\sfutil\asn1.h # End Source File # Begin Source File SOURCE=..\..\sfutil\bitop.h # End Source File # Begin Source File SOURCE=..\..\sfutil\bitop_funcs.h # End Source File # Begin Source File SOURCE=..\..\sfutil\bnfa_search.c # End Source File # Begin Source File SOURCE=..\..\sfutil\bnfa_search.h # End Source File # Begin Source File SOURCE=..\..\event_queue.c # End Source File # Begin Source File SOURCE=..\..\event_queue.h # End Source File # Begin Source File SOURCE=..\..\sfutil\getopt.h # End Source File # Begin Source File SOURCE=..\..\sfutil\getopt1.h # End Source File # Begin Source File SOURCE=..\..\sfutil\getopt_long.c # End Source File # Begin Source File SOURCE=..\..\sfutil\ipobj.c # End Source File # Begin Source File SOURCE=..\..\sfutil\ipobj.h # End Source File # Begin Source File SOURCE=..\..\sfutil\md5.c # End Source File # Begin Source File SOURCE=..\..\sfutil\md5.h # End Source File # Begin Source File SOURCE=..\..\sfutil\mpse.c # End Source File # Begin Source File SOURCE=..\..\sfutil\mpse.h # End Source File # Begin Source File SOURCE=..\..\sfutil\sf_base64decode.c # End Source File # Begin Source File SOURCE=..\..\sfutil\sf_base64decode.h # End Source File # Begin Source File SOURCE=..\..\sfutil\sf_email_attach_decode.c # End Source File # Begin Source File SOURCE=..\..\sfutil\sf_email_attach_decode.h # End Source File # Begin Source File SOURCE=..\..\sfutil\sf_ip.c # End Source File # Begin Source File SOURCE=..\..\sfutil\sf_ip.h # End Source File # Begin Source File SOURCE=..\..\sfutil\sf_iph.c # End Source File # Begin Source File SOURCE=..\..\sfutil\sf_ipvar.c # End Source File # Begin Source File SOURCE=..\..\sfutil\sf_ipvar.h # End Source File # Begin Source File SOURCE=..\..\sfutil\sf_sechash.c # End Source File # Begin Source File SOURCE=..\..\sfutil\sf_sechash.h # End Source File # Begin Source File SOURCE=..\..\sfutil\sf_seqnums.h # End Source File # Begin Source File SOURCE=..\..\sfutil\sf_textlog.c # End Source File # Begin Source File SOURCE=..\..\sfutil\sf_textlog.h # End Source File # Begin Source File SOURCE=..\..\sfutil\sf_vartable.c # End Source File # Begin Source File SOURCE=..\..\sfutil\sf_vartable.h # End Source File # Begin Source File SOURCE=..\..\sfutil\sfActionQueue.c # End Source File # Begin Source File SOURCE=..\..\sfutil\sfActionQueue.h # End Source File # Begin Source File SOURCE=..\..\sfutil\sfeventq.c # End Source File # Begin Source File SOURCE=..\..\sfutil\sfeventq.h # End Source File # Begin Source File SOURCE=..\..\sfutil\sfghash.c # End Source File # Begin Source File SOURCE=..\..\sfutil\sfghash.h # End Source File # Begin Source File SOURCE=..\..\sfutil\sfhashfcn.c # End Source File # Begin Source File SOURCE=..\..\sfutil\sfhashfcn.h # End Source File # Begin Source File SOURCE=..\..\sfutil\sfksearch.c # End Source File # Begin Source File SOURCE=..\..\sfutil\sfksearch.h # End Source File # Begin Source File SOURCE=..\..\sfutil\sflsq.c # End Source File # Begin Source File SOURCE=..\..\sfutil\sflsq.h # End Source File # Begin Source File SOURCE=..\..\sfutil\sfmemcap.c # End Source File # Begin Source File SOURCE=..\..\sfutil\sfmemcap.h # End Source File # Begin Source File SOURCE=..\..\sfutil\sfPolicy.c # End Source File # Begin Source File SOURCE=..\..\sfutil\sfPolicy.h # End Source File # Begin Source File SOURCE=..\..\sfutil\sfPolicyData.h # End Source File # Begin Source File SOURCE=..\..\sfutil\sfPolicyUserData.c # End Source File # Begin Source File SOURCE=..\..\sfutil\sfPolicyUserData.h # End Source File # Begin Source File SOURCE=..\..\sfutil\sfportobject.c # End Source File # Begin Source File SOURCE=..\..\sfutil\sfportobject.h # End Source File # Begin Source File SOURCE=..\..\sfutil\sfprimetable.c # End Source File # Begin Source File SOURCE=..\..\sfutil\sfprimetable.h # End Source File # Begin Source File SOURCE=..\..\sfutil\sfrf.c # End Source File # Begin Source File SOURCE=..\..\sfutil\sfrf.h # End Source File # Begin Source File SOURCE=..\..\sfutil\sfrim.c # End Source File # Begin Source File SOURCE=..\..\sfutil\sfrim.h # End Source File # Begin Source File SOURCE=..\..\sfutil\sfrt.c # End Source File # Begin Source File SOURCE=..\..\sfutil\sfrt.h # End Source File # Begin Source File SOURCE=..\..\sfutil\sfrt_dir.c # End Source File # Begin Source File SOURCE=..\..\sfutil\sfrt_dir.h # End Source File # Begin Source File SOURCE=..\..\sfutil\sfrt_trie.h # End Source File # Begin Source File SOURCE=..\..\sfutil\sfsnprintfappend.c # End Source File # Begin Source File SOURCE=..\..\sfutil\sfsnprintfappend.h # End Source File # Begin Source File SOURCE=..\..\sfutil\sfthd.c # End Source File # Begin Source File SOURCE=..\..\sfutil\sfthd.h # End Source File # Begin Source File SOURCE=..\..\sfutil\sfxhash.c # End Source File # Begin Source File SOURCE=..\..\sfutil\sfxhash.h # End Source File # Begin Source File SOURCE=..\..\sfutil\sha2.c # End Source File # Begin Source File SOURCE=..\..\sfutil\sha2.h # End Source File # Begin Source File SOURCE=..\..\sfutil\strvec.c # End Source File # Begin Source File SOURCE=..\..\sfutil\strvec.h # End Source File # Begin Source File SOURCE=..\..\sfutil\Unified2_common.h # End Source File # Begin Source File SOURCE=..\..\sfutil\util_jsnorm.c # End Source File # Begin Source File SOURCE=..\..\sfutil\util_jsnorm.h # End Source File # Begin Source File SOURCE=..\..\sfutil\util_math.c # End Source File # Begin Source File SOURCE=..\..\sfutil\util_math.h # End Source File # Begin Source File SOURCE=..\..\sfutil\util_net.c # End Source File # Begin Source File SOURCE=..\..\sfutil\util_net.h # End Source File # Begin Source File SOURCE=..\..\sfutil\util_str.c # End Source File # Begin Source File SOURCE=..\..\sfutil\util_str.h # End Source File # Begin Source File SOURCE=..\..\sfutil\util_unfold.c # End Source File # Begin Source File SOURCE=..\..\sfutil\util_unfold.h # End Source File # Begin Source File SOURCE=..\..\sfutil\util_utf.c # End Source File # Begin Source File SOURCE=..\..\sfutil\util_utf.h # End Source File # End Group # Begin Group "Dynamic Plugins" # PROP Default_Filter "" # Begin Source File SOURCE="..\..\dynamic-plugins\sf_convert_dynamic.c" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_convert_dynamic.h" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_dynamic_common.h" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_dynamic_detection.h" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_dynamic_engine.h" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_dynamic_meta.h" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_dynamic_plugins.c" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_dynamic_preprocessor.h" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_dynamic_decompression.c" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_dynamic_decompression.h" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sp_dynamic.c" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sp_dynamic.h" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sp_preprocopt.c" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sp_preprocopt.h" # End Source File # End Group # Begin Group "Target-Based" # PROP Default_Filter "" # Begin Source File SOURCE="..\..\target-based\sf_attribute_table.c" # End Source File # Begin Source File SOURCE="..\..\target-based\sf_attribute_table.h" # End Source File # Begin Source File SOURCE="..\..\target-based\sf_attribute_table.y" !IF "$(CFG)" == "snort - Win32 Release" # Begin Custom Build InputPath="..\..\target-based\sf_attribute_table.y" InputName=sf_attribute_table BuildCmds= \ c:\cygwin\bin\bison -d -psfat_ -o../../target-based/$(InputName).c ../../target-based/$(InputName).y "..\..\target-based\$(InputName).c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) "..\..\target-based\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) # End Custom Build !ELSEIF "$(CFG)" == "snort - Win32 Debug" # Begin Custom Build InputPath="..\..\target-based\sf_attribute_table.y" InputName=sf_attribute_table BuildCmds= \ c:\cygwin\bin\bison -d -psfat_ -o../../target-based/$(InputName).c ../../target-based/$(InputName).y "..\..\target-based\$(InputName).c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) "..\..\target-based\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE="..\..\target-based\sf_attribute_table_parser.c" # End Source File # Begin Source File SOURCE="..\..\target-based\sf_attribute_table_parser.l" !IF "$(CFG)" == "snort - Win32 Release" # Begin Custom Build InputPath="..\..\target-based\sf_attribute_table_parser.l" InputName=sf_attribute_table_parser "..\..\target-based\$(InputName).c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" c:\cygwin\bin\flex -i -Psfat -o../../target-based/$(InputName).c ../../target-based/$(InputName).l # End Custom Build !ELSEIF "$(CFG)" == "snort - Win32 Debug" # Begin Custom Build InputPath="..\..\target-based\sf_attribute_table_parser.l" InputName=sf_attribute_table_parser "..\..\target-based\$(InputName).c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" c:\cygwin\bin\flex -i -Psfat -o../../target-based/$(InputName).c ../../target-based/$(InputName).l # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE="..\..\target-based\sftarget_hostentry.c" # End Source File # Begin Source File SOURCE="..\..\target-based\sftarget_hostentry.h" # End Source File # Begin Source File SOURCE="..\..\target-based\sftarget_protocol_reference.c" # End Source File # Begin Source File SOURCE="..\..\target-based\sftarget_protocol_reference.h" # End Source File # Begin Source File SOURCE="..\..\target-based\sftarget_reader.c" # End Source File # Begin Source File SOURCE="..\..\target-based\sftarget_reader.h" # End Source File # End Group # Begin Group "Control" # PROP Default_Filter "" # Begin Source File SOURCE=..\..\control\sfcontrol.c # End Source File # Begin Source File SOURCE=..\..\control\sfcontrol.h # End Source File # Begin Source File SOURCE=..\..\control\sfcontrol_funcs.h # End Source File # End Group # Begin Group "Dynamic Output" # PROP Default_Filter "" # Begin Source File SOURCE="..\..\dynamic-output\plugins\output.h" # End Source File # Begin Source File SOURCE="..\..\dynamic-output\plugins\output_api.h" # End Source File # Begin Source File SOURCE="..\..\dynamic-output\plugins\output_base.c" # End Source File # Begin Source File SOURCE="..\..\dynamic-output\plugins\output_common.h" # End Source File # Begin Source File SOURCE="..\..\dynamic-output\libs\output_lib.c" # End Source File # Begin Source File SOURCE="..\..\dynamic-output\plugins\output_lib.h" # End Source File # Begin Source File SOURCE="..\..\dynamic-output\plugins\output_plugin.c" # ADD BASE CPP /D inline=__inline # ADD CPP /D inline=__inline # End Source File # End Group # Begin Group "File" # PROP Default_Filter "" # Begin Group "Lib" # PROP Default_Filter "" # Begin Source File SOURCE="..\..\file-process\libs\file_config.c" # End Source File # Begin Source File SOURCE="..\..\file-process\libs\file_config.h" # End Source File # Begin Source File SOURCE="..\..\file-process\libs\file_identifier.c" # End Source File # Begin Source File SOURCE="..\..\file-process\libs\file_identifier.h" # End Source File # Begin Source File SOURCE="..\..\file-process\libs\file_lib.c" # End Source File # Begin Source File SOURCE="..\..\file-process\libs\file_lib.h" # End Source File # End Group # Begin Source File SOURCE="..\..\file-process\circular_buffer.c" # End Source File # Begin Source File SOURCE="..\..\file-process\circular_buffer.h" # End Source File # Begin Source File SOURCE="..\..\file-process\file_api.h" # End Source File # Begin Source File SOURCE="..\..\file-process\file_capture.c" # End Source File # Begin Source File SOURCE="..\..\file-process\file_capture.h" # End Source File # Begin Source File SOURCE="..\..\file-process\file_mempool.c" # End Source File # Begin Source File SOURCE="..\..\file-process\file_mempool.h" # End Source File # Begin Source File SOURCE="..\..\file-process\file_segment_process.c" # End Source File # Begin Source File SOURCE="..\..\file-process\file_segment_process.h" # End Source File # Begin Source File SOURCE="..\..\file-process\file_mime_config.c" # End Source File # Begin Source File SOURCE="..\..\file-process\file_mime_config.h" # End Source File # Begin Source File SOURCE="..\..\file-process\file_mime_process.c" # End Source File # Begin Source File SOURCE="..\..\file-process\file_mime_process.h" # End Source File # Begin Source File SOURCE="..\..\file-process\file_resume_block.c" # End Source File # Begin Source File SOURCE="..\..\file-process\file_resume_block.h" # End Source File # Begin Source File SOURCE="..\..\file-process\file_service.c" # End Source File # Begin Source File SOURCE="..\..\file-process\file_service.h" # End Source File # Begin Source File SOURCE="..\..\file-process\file_service_config.c" # End Source File # Begin Source File SOURCE="..\..\file-process\file_service_config.h" # End Source File # Begin Source File SOURCE="..\..\file-process\file_stats.c" # End Source File # Begin Source File SOURCE="..\..\file-process\file_stats.h" # End Source File # End Group # Begin Source File SOURCE=..\..\active.c # End Source File # Begin Source File SOURCE=..\..\active.h # End Source File # Begin Source File SOURCE=..\..\bounds.h # End Source File # Begin Source File SOURCE=..\..\byte_extract.c # End Source File # Begin Source File SOURCE=..\..\byte_extract.h # End Source File # Begin Source File SOURCE=..\..\cdefs.h # End Source File # Begin Source File SOURCE=..\..\checksum.h # End Source File # Begin Source File SOURCE=..\..\debug.c # End Source File # Begin Source File SOURCE=..\..\debug.h # End Source File # Begin Source File SOURCE=..\..\decode.c # End Source File # Begin Source File SOURCE=..\..\decode.h # End Source File # Begin Source File SOURCE=..\..\detect.c !IF "$(CFG)" == "snort - Win32 Release" # ADD CPP /I "..\..\preprocessors\Stream6" /I "..\..\preprocessors\Session" !ELSEIF "$(CFG)" == "snort - Win32 Debug" !ENDIF # End Source File # Begin Source File SOURCE=..\..\detect.h # End Source File # Begin Source File SOURCE=..\..\detection_filter.c # End Source File # Begin Source File SOURCE=..\..\detection_filter.h # End Source File # Begin Source File SOURCE=..\..\detection_util.c # End Source File # Begin Source File SOURCE=..\..\detection_util.h # End Source File # Begin Source File SOURCE=..\..\encode.c # End Source File # Begin Source File SOURCE=..\..\encode.h # End Source File # Begin Source File SOURCE=..\..\event.h # End Source File # Begin Source File SOURCE=..\..\event_wrapper.c # End Source File # Begin Source File SOURCE=..\..\event_wrapper.h # End Source File # Begin Source File SOURCE=..\..\fpcreate.c # End Source File # Begin Source File SOURCE=..\..\fpcreate.h # End Source File # Begin Source File SOURCE=..\..\fpdetect.c # End Source File # Begin Source File SOURCE=..\..\fpdetect.h # End Source File # Begin Source File SOURCE=..\..\generators.h # End Source File # Begin Source File SOURCE=..\..\hashstring.c # End Source File # Begin Source File SOURCE=..\..\hashstring.h # End Source File # Begin Source File SOURCE=..\..\idle_processing.c # End Source File # Begin Source File SOURCE=..\..\idle_processing.h # End Source File # Begin Source File SOURCE=..\..\idle_processing_funcs.h # End Source File # Begin Source File SOURCE=..\..\ipv6_port.h # End Source File # Begin Source File SOURCE=..\..\log.c # End Source File # Begin Source File SOURCE=..\..\log.h # End Source File # Begin Source File SOURCE=..\..\log_text.c # End Source File # Begin Source File SOURCE=..\..\log_text.h # End Source File # Begin Source File SOURCE=..\..\mempool.c # End Source File # Begin Source File SOURCE=..\..\mempool.h # End Source File # Begin Source File SOURCE=..\..\mstring.c # End Source File # Begin Source File SOURCE=..\..\mstring.h # End Source File # Begin Source File SOURCE=..\..\obfuscation.c # End Source File # Begin Source File SOURCE=..\..\obfuscation.h # End Source File # Begin Source File SOURCE=..\..\packet_time.c # End Source File # Begin Source File SOURCE=..\..\packet_time.h # End Source File # Begin Source File SOURCE=..\..\parser.c # End Source File # Begin Source File SOURCE=..\..\parser.h # End Source File # Begin Source File SOURCE=..\..\pcap_pkthdr32.h # End Source File # Begin Source File SOURCE=..\..\pcrm.c # End Source File # Begin Source File SOURCE=..\..\pcrm.h # End Source File # Begin Source File SOURCE=..\..\plugbase.c # End Source File # Begin Source File SOURCE=..\..\plugbase.h # End Source File # Begin Source File SOURCE=..\..\plugin_enum.h # End Source File # Begin Source File SOURCE=..\..\preprocids.h # End Source File # Begin Source File SOURCE=..\..\profiler.c # End Source File # Begin Source File SOURCE=..\..\profiler.h # End Source File # Begin Source File SOURCE=..\..\protocols.h # End Source File # Begin Source File SOURCE=..\..\rate_filter.c # End Source File # Begin Source File SOURCE=..\..\rate_filter.h # End Source File # Begin Source File SOURCE=..\..\rules.h # End Source File # Begin Source File SOURCE=..\..\sf_sdlist.c # End Source File # Begin Source File SOURCE=..\..\sf_sdlist.h # End Source File # Begin Source File SOURCE=..\..\sf_sdlist_types.h # End Source File # Begin Source File SOURCE=..\..\sf_types.h # End Source File # Begin Source File SOURCE=..\..\sfdaq.c # End Source File # Begin Source File SOURCE=..\..\sfdaq.h # End Source File # Begin Source File SOURCE=..\..\sfthreshold.c # End Source File # Begin Source File SOURCE=..\..\sfthreshold.h # End Source File # Begin Source File SOURCE=..\..\signature.c # End Source File # Begin Source File SOURCE=..\..\signature.h # End Source File # Begin Source File SOURCE=..\..\smalloc.h # End Source File # Begin Source File SOURCE=..\..\snort.c # End Source File # Begin Source File SOURCE=..\..\snort.h # End Source File # Begin Source File SOURCE=..\..\snprintf.c # End Source File # Begin Source File SOURCE=..\..\snprintf.h # End Source File # Begin Source File SOURCE=..\..\spo_plugbase.h # End Source File # Begin Source File SOURCE=..\..\strlcatu.c # End Source File # Begin Source File SOURCE=..\..\strlcatu.h # End Source File # Begin Source File SOURCE=..\..\strlcpyu.c # End Source File # Begin Source File SOURCE=..\..\strlcpyu.h # End Source File # Begin Source File SOURCE=..\..\tag.c # End Source File # Begin Source File SOURCE=..\..\tag.h # End Source File # Begin Source File SOURCE=..\..\timersub.h # End Source File # Begin Source File SOURCE=..\..\util.c # End Source File # Begin Source File SOURCE=..\..\util.h # End Source File # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # Begin Source File SOURCE="..\WIN32-Code\MSG00001.bin" # End Source File # Begin Source File SOURCE="..\WIN32-Code\name.mc" # PROP BASE Ignore_Default_Tool 1 # PROP Ignore_Default_Tool 1 # End Source File # Begin Source File SOURCE="..\WIN32-Code\name.rc" # PROP BASE Ignore_Default_Tool 1 # PROP Ignore_Default_Tool 1 # End Source File # End Group # Begin Group "Win32" # PROP Default_Filter "" # Begin Group "WinPCAP" # PROP Default_Filter "" # Begin Source File SOURCE="..\WIN32-Includes\WinPCAP\bittypes.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\WinPCAP\bucket_lookup.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\WinPCAP\count_packets.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\WinPCAP\Devioctl.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\WinPCAP\Gnuc.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\WinPCAP\ip6_misc.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\WinPCAP\memory_t.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\WinPCAP\normal_lookup.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\WinPCAP\Ntddndis.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\WinPCAP\Ntddpack.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\WinPCAP\Packet32.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\WinPCAP\pcap-bpf.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\WinPCAP\pcap-int.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\WinPCAP\pcap-stdinc.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\WinPCAP\pcap.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\WinPCAP\pthread.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\WinPCAP\remote-ext.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\WinPCAP\sched.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\WinPCAP\semaphore.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\WinPCAP\tcp_session.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\WinPCAP\time_calls.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\WinPCAP\tme.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\WinPCAP\Win32-Extensions.h" # End Source File # End Group # Begin Group "ZLib" # PROP Default_Filter "" # Begin Source File SOURCE="..\WIN32-Includes\zlib\zconf.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\zlib\zlib.h" # End Source File # End Group # Begin Source File SOURCE="..\WIN32-Includes\rpc\auth.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\NET\Bpf.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\rpc\clnt.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\config.h" # End Source File # Begin Source File SOURCE="..\WIN32-Code\getopt.c" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\getopt.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\getopt1.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\gnuc.h" # End Source File # Begin Source File SOURCE="..\WIN32-Code\inet_aton.c" # End Source File # Begin Source File SOURCE="..\WIN32-Code\inet_pton.c" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\inttypes.h" # End Source File # Begin Source File SOURCE="..\WIN32-Code\misc.c" # End Source File # Begin Source File SOURCE="..\WIN32-Code\name.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\pcre.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\pcreposix.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\rpc\rpc_msg.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\stdint.h" # End Source File # Begin Source File SOURCE="..\WIN32-Code\strtok_r.c" # End Source File # Begin Source File SOURCE="..\WIN32-Code\syslog.c" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\syslog.h" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\UNISTD.H" # End Source File # Begin Source File SOURCE="..\WIN32-Code\win32_service.c" # End Source File # Begin Source File SOURCE="..\WIN32-Includes\rpc\xdr.h" # End Source File # End Group # End Target # End Project snort-2.9.15.1/src/win32/WIN32-Prj/snort_initialize.dsp0000444000175200017520000001406113571422610017224 00000000000000# Microsoft Developer Studio Project File - Name="snort_initialize" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Generic Project" 0x010a CFG=snort_initialize - Win32 IPv6 Release !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "snort_initialize.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "snort_initialize.mak" CFG="snort_initialize - Win32 IPv6 Release" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "snort_initialize - Win32 Release" (based on "Win32 (x86) Generic Project") !MESSAGE "snort_initialize - Win32 Debug" (based on "Win32 (x86) Generic Project") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" MTL=midl.exe !IF "$(CFG)" == "snort_initialize - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Snort_Initialize_Release" # PROP Intermediate_Dir "Snort_Initialize_Release" # PROP Target_Dir "" !ELSEIF "$(CFG)" == "snort_initialize - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Snort_Initialize_Debug" # PROP Intermediate_Dir "Snort_Initialize_Debug" # PROP Target_Dir "" !ENDIF # Begin Target # Name "snort_initialize - Win32 Release" # Name "snort_initialize - Win32 Debug" # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\sf_snort_packet.h" !IF "$(CFG)" == "snort_initialize - Win32 Release" # Begin Custom Build InputPath="..\..\dynamic-plugins\sf_engine\sf_snort_packet.h" InputName=sf_snort_packet "..\..\detection-plugins\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\detection-plugins # End Custom Build !ELSEIF "$(CFG)" == "snort_initialize - Win32 Debug" # Begin Custom Build InputPath="..\..\dynamic-plugins\sf_engine\sf_snort_packet.h" InputName=sf_snort_packet "..\..\detection-plugins\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\detection-plugins # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\sf_snort_plugin_api.h" !IF "$(CFG)" == "snort_initialize - Win32 Release" # Begin Custom Build InputPath="..\..\dynamic-plugins\sf_engine\sf_snort_plugin_api.h" InputName=sf_snort_plugin_api "..\..\detection-plugins\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\detection-plugins # End Custom Build !ELSEIF "$(CFG)" == "snort_initialize - Win32 Debug" # Begin Custom Build InputPath="..\..\dynamic-plugins\sf_engine\sf_snort_plugin_api.h" InputName=sf_snort_plugin_api "..\..\detection-plugins\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\detection-plugins # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\sf_snort_plugin_hdropts.c" !IF "$(CFG)" == "snort_initialize - Win32 Release" # Begin Custom Build InputPath="..\..\dynamic-plugins\sf_engine\sf_snort_plugin_hdropts.c" InputName=sf_snort_plugin_hdropts BuildCmds= \ copy $(InputPath) ..\..\detection-plugins\$(InputName).c.new \ c:\cygwin\bin\sed -e "s/_ded.errMsg/ErrorMessage/g" -e "s/sf_snort_packet.h/decode.h/g" -e "s/SFSnortPacket/Packet/g" -e "s/ip4_header/iph/g" -e "s/tcp_header/tcph/g" -e "s/proto/ip_proto/g" -e "s/type_service/ip_tos/g" -e "s/time_to_live/ip_ttl/g" -e "s/num_ip_options/ip_option_count/g" -e "s/IPOptions/Options/g" -e "s/option_code/code/g" -e "s/acknowledgement/th_ack/g" -e "s/sequence/th_seq/g" -e "s/tcph->flags/tcph->th_flags/g" -e "s/tcph->window/tcph->th_win/g" -e "s/num_tcp_options/tcp_option_count/g" -e "s/icmp_header/icmph/g" -e "s/ICMP_ECHO_REPLY/ICMP_ECHOREPLY/g" -e "s/ICMP_ECHO_REQUEST/ICMP_ECHO/g" -e "s/icmph_union.echo.id/s_icmp_id/g" -e "s/icmph_union.echo.seq/s_icmp_seq/g" -e "/sf_snort_detection_engine.h/d" ../../detection-plugins/$(InputName).c.new > ../../detection-plugins/$(InputName).c \ "..\..\detection-plugins\$(InputName).c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) "..\..\detection-plugins\$(InputName).c.new" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) # End Custom Build !ELSEIF "$(CFG)" == "snort_initialize - Win32 Debug" # Begin Custom Build InputPath="..\..\dynamic-plugins\sf_engine\sf_snort_plugin_hdropts.c" InputName=sf_snort_plugin_hdropts BuildCmds= \ copy $(InputPath) ..\..\detection-plugins\$(InputName).c.new \ c:\cygwin\bin\sed -e "s/_ded.errMsg/ErrorMessage/g" -e "s/sf_snort_packet.h/decode.h/g" -e "s/SFSnortPacket/Packet/g" -e "s/ip4_header/iph/g" -e "s/tcp_header/tcph/g" -e "s/proto/ip_proto/g" -e "s/type_service/ip_tos/g" -e "s/time_to_live/ip_ttl/g" -e "s/num_ip_options/ip_option_count/g" -e "s/IPOptions/Options/g" -e "s/option_code/code/g" -e "s/acknowledgement/th_ack/g" -e "s/sequence/th_seq/g" -e "s/tcph->flags/tcph->th_flags/g" -e "s/tcph->window/tcph->th_win/g" -e "s/num_tcp_options/tcp_option_count/g" -e "s/icmp_header/icmph/g" -e "s/ICMP_ECHO_REPLY/ICMP_ECHOREPLY/g" -e "s/ICMP_ECHO_REQUEST/ICMP_ECHO/g" -e "s/icmph_union.echo.id/s_icmp_id/g" -e "s/icmph_union.echo.seq/s_icmp_seq/g" ../../detection-plugins/$(InputName).c.new > ../../detection-plugins/$(InputName).c \ "..\..\detection-plugins\$(InputName).c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) "..\..\detection-plugins\$(InputName).c.new" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) # End Custom Build !ENDIF # End Source File # End Target # End Project snort-2.9.15.1/src/win32/WIN32-Prj/build_all.dsp0000444000175200017520000000347713571422610015576 00000000000000# Microsoft Developer Studio Project File - Name="build_all" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Generic Project" 0x010a CFG=build_all - Win32 Release !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "build_all.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "build_all.mak" CFG="build_all - Win32 Release" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "build_all - Win32 Release" (based on "Win32 (x86) Generic Project") !MESSAGE "build_all - Win32 Debug" (based on "Win32 (x86) Generic Project") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" MTL=midl.exe !IF "$(CFG)" == "build_all - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "BuildAll_Release" # PROP Intermediate_Dir "BuildAll_Release" # PROP Target_Dir "" !ELSEIF "$(CFG)" == "build_all - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "BuildAll_Debug" # PROP Intermediate_Dir "BuildAll_Debug" # PROP Target_Dir "" !ENDIF # Begin Target # Name "build_all - Win32 Release" # Name "build_all - Win32 Debug" # End Target # End Project snort-2.9.15.1/src/win32/WIN32-Prj/sf_engine.dsp0000444000175200017520000002432713571422610015601 00000000000000# Microsoft Developer Studio Project File - Name="sf_engine" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=sf_engine - Win32 Release !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "sf_engine.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "sf_engine.mak" CFG="sf_engine - Win32 Release" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "sf_engine - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "sf_engine - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "sf_engine - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 2 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "SF_Engine_Release" # PROP Intermediate_Dir "SF_Engine_Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SF_ENGINE_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\dynamic-plugins" /I "..\..\dynamic-plugins\sf_engine" /I "..\Win32-Includes" /I "..\Win32-Includes\zlib" /I "..\..\..\daq\api" /I "..\..\..\daq\sfbpf" /D "NDEBUG" /D "ENABLE_PAF" /D "SF_SNORT_ENGINE_DLL" /D "_WINDOWS" /D "_USRDLL" /D "ACTIVE_RESPONSE" /D "GRE" /D "MPLS" /D "TARGET_BASED" /D "PERF_PROFILING" /D "ENABLE_RESPOND" /D "ENABLE_REACT" /D "ZLIB" /D "_WINDLL" /D "WIN32" /D "_MBCS" /D "HAVE_CONFIG_H" /D "_AFXDLL" /D SIGNAL_SNORT_READ_ATTR_TBL=30 /D BYTE_ORDER=LITTLE_ENDIAN /FR /FD /c # SUBTRACT CPP /YX # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 zlib1.lib Ws2_32.lib pcre.lib /nologo /dll /machine:I386 /libpath:"..\Win32-Libraries" !ELSEIF "$(CFG)" == "sf_engine - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 2 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "SF_Engine_Debug" # PROP Intermediate_Dir "SF_Engine_Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SF_ENGINE_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\Win32-Includes\zlib" /I "..\..\dynamic-plugins" /I "..\..\dynamic-plugins\sf_engine" /I "..\Win32-Includes" /I "..\..\..\daq\api" /I "..\..\..\daq\sfbpf" /D "_DEBUG" /D "DEBUG" /D "ENABLE_PAF" /D "SF_SNORT_ENGINE_DLL" /D "_WINDOWS" /D "_USRDLL" /D "ACTIVE_RESPONSE" /D "GRE" /D "MPLS" /D "TARGET_BASED" /D "PERF_PROFILING" /D "ENABLE_RESPOND" /D "ENABLE_REACT" /D "ZLIB" /D "_WINDLL" /D "WIN32" /D "_MBCS" /D "HAVE_CONFIG_H" /D "_AFXDLL" /D SIGNAL_SNORT_READ_ATTR_TBL=30 /D BYTE_ORDER=LITTLE_ENDIAN /FR /FD /GZ /c # SUBTRACT CPP /YX # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 zlib1.lib Ws2_32.lib pcre.lib /nologo /dll /debug /machine:I386 /pdbtype:sept /libpath:"..\Win32-Libraries" !ENDIF # Begin Target # Name "sf_engine - Win32 Release" # Name "sf_engine - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\bmh.c" !IF "$(CFG)" == "sf_engine - Win32 Release" # ADD CPP /D "MODULUS_HASH" !ELSEIF "$(CFG)" == "sf_engine - Win32 Debug" !ENDIF # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\md5.c" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\sf_decompression.c" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\sf_sechash.c" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\sf_snort_detection_engine.c" !IF "$(CFG)" == "sf_engine - Win32 Release" # ADD CPP /I "..\..\.." /I "..\Win32-Includes\mysql" /I "..\Win32-Includes\libnet" /I "..\..\output-plugins" /I "..\..\detection-plugins" /I "..\..\preprocessors" /I "..\..\preprocessors\flow" /I "..\..\preprocessors\portscan" /I "..\..\preprocessors\flow\int-snort" /I "..\..\preprocessors\HttpInspect\Include" /D "MODULUS_HASH" !ELSEIF "$(CFG)" == "sf_engine - Win32 Debug" # ADD CPP /I "..\..\.." /I "..\Win32-Includes\mysql" /I "..\Win32-Includes\libnet" /I "..\..\output-plugins" /I "..\..\detection-plugins" /I "..\..\preprocessors" /I "..\..\preprocessors\flow" /I "..\..\preprocessors\portscan" /I "..\..\preprocessors\flow\int-snort" /I "..\..\preprocessors\HttpInspect\Include" !ENDIF # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\sf_snort_plugin_api.c" !IF "$(CFG)" == "sf_engine - Win32 Release" # ADD CPP /I "..\..\.." /I "..\Win32-Includes\mysql" /I "..\Win32-Includes\libnet" /I "..\..\output-plugins" /I "..\..\detection-plugins" /I "..\..\preprocessors" /I "..\..\preprocessors\flow" /I "..\..\preprocessors\portscan" /I "..\..\preprocessors\flow\int-snort" /I "..\..\preprocessors\HttpInspect\Include" /D "MODULUS_HASH" !ELSEIF "$(CFG)" == "sf_engine - Win32 Debug" # ADD CPP /I "..\..\.." /I "..\Win32-Includes\mysql" /I "..\Win32-Includes\libnet" /I "..\..\output-plugins" /I "..\..\detection-plugins" /I "..\..\preprocessors" /I "..\..\preprocessors\flow" /I "..\..\preprocessors\portscan" /I "..\..\preprocessors\flow\int-snort" /I "..\..\preprocessors\HttpInspect\Include" !ENDIF # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\sf_snort_plugin_byte.c" !IF "$(CFG)" == "sf_engine - Win32 Release" # ADD CPP /D "MODULUS_HASH" !ELSEIF "$(CFG)" == "sf_engine - Win32 Debug" !ENDIF # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\sf_snort_plugin_content.c" !IF "$(CFG)" == "sf_engine - Win32 Release" # ADD CPP /D "MODULUS_HASH" !ELSEIF "$(CFG)" == "sf_engine - Win32 Debug" !ENDIF # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\sf_snort_plugin_hdropts.c" !IF "$(CFG)" == "sf_engine - Win32 Release" # ADD CPP /D "MODULUS_HASH" !ELSEIF "$(CFG)" == "sf_engine - Win32 Debug" !ENDIF # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\sf_snort_plugin_loop.c" !IF "$(CFG)" == "sf_engine - Win32 Release" # ADD CPP /D "MODULUS_HASH" !ELSEIF "$(CFG)" == "sf_engine - Win32 Debug" !ENDIF # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\sf_snort_plugin_pcre.c" !IF "$(CFG)" == "sf_engine - Win32 Release" # ADD CPP /D "MODULUS_HASH" !ELSEIF "$(CFG)" == "sf_engine - Win32 Debug" !ENDIF # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\sf_snort_plugin_rc4.c" !IF "$(CFG)" == "sf_engine - Win32 Release" # ADD CPP /D "MODULUS_HASH" !ELSEIF "$(CFG)" == "sf_engine - Win32 Debug" !ENDIF # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\sfghash.c" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\sfhashfcn.c" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\sfprimetable.c" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\sha2.c" # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\bmh.h" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\debug.h" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\ipv6_port.h" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\md5.h" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\sf_decompression.h" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_decompression_define.h" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\sf_ip.h" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\sf_sechash.h" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\sf_snort_detection_engine.h" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\sf_snort_packet.h" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\sf_snort_plugin_api.h" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\sfghash.h" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\sfhashfcn.h" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\sfprimetable.h" # End Source File # Begin Source File SOURCE="..\..\dynamic-plugins\sf_engine\sha2.h" # End Source File # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # End Target # End Project snort-2.9.15.1/src/win32/WIN32-Prj/sf_engine_initialize.dsp0000555000175200017520000004265313571422610020027 00000000000000# Microsoft Developer Studio Project File - Name="sf_engine_initialize" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Generic Project" 0x010a CFG=sf_engine_initialize - Win32 Release !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "sf_engine_initialize.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "sf_engine_initialize.mak" CFG="sf_engine_initialize - Win32 Release" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "sf_engine_initialize - Win32 Release" (based on "Win32 (x86) Generic Project") !MESSAGE "sf_engine_initialize - Win32 Debug" (based on "Win32 (x86) Generic Project") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" MTL=midl.exe !IF "$(CFG)" == "sf_engine_initialize - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "SF_Engine_Initialize_Release" # PROP Intermediate_Dir "SF_Engine_Initialize_Release" # PROP Target_Dir "" !ELSEIF "$(CFG)" == "sf_engine_initialize - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "SF_Engine_Initialize_Debug" # PROP Intermediate_Dir "SF_Engine_Initialize_Debug" # PROP Target_Dir "" !ENDIF # Begin Target # Name "sf_engine_initialize - Win32 Release" # Name "sf_engine_initialize - Win32 Debug" # Begin Source File SOURCE=..\..\ipv6_port.h !IF "$(CFG)" == "sf_engine_initialize - Win32 Release" # Begin Custom Build InputPath=..\..\ipv6_port.h InputName=ipv6_port BuildCmds= \ copy $(InputPath) ..\..\dynamic-plugins\sf_engine\$(InputName).h.new \ c:\cygwin\bin\sed -e "s/->iph->ip_src/->ip4_header->source/" -e "s/->iph->ip_dst/->ip4_header->destination/" -e "s/->iph->/->ip4_header->/" -e "s/->iph$/->ip4_header/" -e "s/orig_iph$/orig_ip4_header/" -e "s/ip_verhl/version_headerlength/" -e "s/ip_tos/type_service/" -e "s/ip_len/data_length/" -e "s/ip_id/identifier/" -e "s/ip_off/offset/" -e "s/ip_ttl/time_to_live/" -e "s/ip_proto/proto/" -e "s/ip_csum/checksum/" -e "s/p->iph$/p->ip4_header/" ../../dynamic-plugins/sf_engine/$(InputName).h.new > ../../dynamic-plugins/sf_engine/$(InputName).h \ "..\..\dynamic-plugins\sf_engine\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) "..\..\dynamic-plugins\sf_engine\$(InputName).h.new" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) # End Custom Build !ELSEIF "$(CFG)" == "sf_engine_initialize - Win32 Debug" # Begin Custom Build InputPath=..\..\ipv6_port.h InputName=ipv6_port BuildCmds= \ copy $(InputPath) ..\..\dynamic-plugins\sf_engine\$(InputName).h.new \ c:\cygwin\bin\sed -e "s/->iph->ip_src/->ip4_header->source/" -e "s/->iph->ip_dst/->ip4_header->destination/" -e "s/->iph->/->ip4_header->/" -e "s/->iph$/->ip4_header/" -e "s/orig_iph$/orig_ip4_header/" -e "s/ip_verhl/version_headerlength/" -e "s/ip_tos/type_service/" -e "s/ip_len/data_length/" -e "s/ip_id/identifier/" -e "s/ip_off/offset/" -e "s/ip_ttl/time_to_live/" -e "s/ip_proto/proto/" -e "s/ip_csum/checksum/" -e "s/p->iph$/p->ip4_header/" ../../dynamic-plugins/sf_engine/$(InputName).h.new > ../../dynamic-plugins/sf_engine/$(InputName).h \ "..\..\dynamic-plugins\sf_engine\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) "..\..\dynamic-plugins\sf_engine\$(InputName).h.new" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=..\..\sfutil\md5.c !IF "$(CFG)" == "sf_engine_initialize - Win32 Release" # Begin Custom Build InputPath=..\..\sfutil\md5.c InputName=md5 "..\..\dynamic-plugins\sf_engine\$(InputName).c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\dynamic-plugins\sf_engine # End Custom Build !ELSEIF "$(CFG)" == "sf_engine_initialize - Win32 Debug" # Begin Custom Build InputPath=..\..\sfutil\md5.c InputName=md5 "..\..\dynamic-plugins\sf_engine\$(InputName).c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\dynamic-plugins\sf_engine # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=..\..\sfutil\md5.h !IF "$(CFG)" == "sf_engine_initialize - Win32 Release" # Begin Custom Build InputPath=..\..\sfutil\md5.h InputName=md5 "..\..\dynamic-plugins\sf_engine\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\dynamic-plugins\sf_engine # End Custom Build !ELSEIF "$(CFG)" == "sf_engine_initialize - Win32 Debug" # Begin Custom Build InputPath=..\..\sfutil\md5.h InputName=md5 "..\..\dynamic-plugins\sf_engine\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\dynamic-plugins\sf_engine # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=..\..\preprocids.h !IF "$(CFG)" == "sf_engine_initialize - Win32 Release" !ELSEIF "$(CFG)" == "sf_engine_initialize - Win32 Debug" # Begin Custom Build InputPath=..\..\preprocids.h InputName=preprocids "..\..\dynamic-plugins\sf_engine\$(InputName).c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\dynamic-plugins\sf_engine # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=..\..\sfutil\sf_ip.c !IF "$(CFG)" == "sf_engine_initialize - Win32 Release" # Begin Custom Build InputPath=..\..\sfutil\sf_ip.c InputName=sf_ip "..\..\dynamic-plugins\sf_engine\$(InputName).c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\dynamic-plugins\sf_engine # End Custom Build !ELSEIF "$(CFG)" == "sf_engine_initialize - Win32 Debug" # Begin Custom Build InputPath=..\..\sfutil\sf_ip.c InputName=sf_ip "..\..\dynamic-plugins\sf_engine\$(InputName).c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\dynamic-plugins\sf_engine # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=..\..\sfutil\sf_ip.h !IF "$(CFG)" == "sf_engine_initialize - Win32 Release" # Begin Custom Build InputPath=..\..\sfutil\sf_ip.h InputName=sf_ip "..\..\dynamic-plugins\sf_engine\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\dynamic-plugins\sf_engine # End Custom Build !ELSEIF "$(CFG)" == "sf_engine_initialize - Win32 Debug" # Begin Custom Build InputPath=..\..\sfutil\sf_ip.h InputName=sf_ip "..\..\dynamic-plugins\sf_engine\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\dynamic-plugins\sf_engine # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=..\..\sf_protocols.h !IF "$(CFG)" == "sf_engine_initialize - Win32 Release" # Begin Custom Build InputPath=..\..\sf_protocols.h InputName=sf_protocols "..\..\dynamic-plugins\sf_engine\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\dynamic-plugins\sf_engine # End Custom Build !ELSEIF "$(CFG)" == "sf_engine_initialize - Win32 Debug" # Begin Custom Build InputPath=..\..\sf_protocols.h InputName=sf_protocols "..\..\dynamic-plugins\sf_engine\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\dynamic-plugins\sf_engine # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=..\..\sfutil\sf_sechash.c !IF "$(CFG)" == "sf_engine_initialize - Win32 Release" # Begin Custom Build InputPath=..\..\sfutil\sf_sechash.c InputName=sf_sechash "..\..\dynamic-plugins\sf_engine\$(InputName).c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\dynamic-plugins\sf_engine # End Custom Build !ELSEIF "$(CFG)" == "sf_engine_initialize - Win32 Debug" # Begin Custom Build InputPath=..\..\sfutil\sf_sechash.c InputName=sf_sechash "..\..\dynamic-plugins\sf_engine\$(InputName).c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\dynamic-plugins\sf_engine # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=..\..\sfutil\sf_sechash.h !IF "$(CFG)" == "sf_engine_initialize - Win32 Release" # Begin Custom Build InputPath=..\..\sfutil\sf_sechash.h InputName=sf_sechash "..\..\dynamic-plugins\sf_engine\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\dynamic-plugins\sf_engine # End Custom Build !ELSEIF "$(CFG)" == "sf_engine_initialize - Win32 Debug" # Begin Custom Build InputPath=..\..\sfutil\sf_sechash.h InputName=sf_sechash "..\..\dynamic-plugins\sf_engine\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\dynamic-plugins\sf_engine # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=..\..\sf_types.h !IF "$(CFG)" == "sf_engine_initialize - Win32 Release" # Begin Custom Build InputPath=..\..\sf_types.h InputName=sf_types "..\..\dynamic-plugins\sf_engine\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\dynamic-plugins\sf_engine # End Custom Build !ELSEIF "$(CFG)" == "sf_engine_initialize - Win32 Debug" # Begin Custom Build InputPath=..\..\sf_types.h InputName=sf_types "..\..\dynamic-plugins\sf_engine\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\dynamic-plugins\sf_engine # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=..\..\sfutil\sfghash.c !IF "$(CFG)" == "sf_engine_initialize - Win32 Release" # Begin Custom Build InputPath=..\..\sfutil\sfghash.c InputName=sfghash "..\..\dynamic-plugins\sf_engine\$(InputName).c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\dynamic-plugins\sf_engine # End Custom Build !ELSEIF "$(CFG)" == "sf_engine_initialize - Win32 Debug" # Begin Custom Build InputPath=..\..\sfutil\sfghash.c InputName=sfghash "..\..\dynamic-plugins\sf_engine\$(InputName).c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\dynamic-plugins\sf_engine # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=..\..\sfutil\sfghash.h !IF "$(CFG)" == "sf_engine_initialize - Win32 Release" # Begin Custom Build InputPath=..\..\sfutil\sfghash.h InputName=sfghash "..\..\dynamic-plugins\sf_engine\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\dynamic-plugins\sf_engine # End Custom Build !ELSEIF "$(CFG)" == "sf_engine_initialize - Win32 Debug" # Begin Custom Build InputPath=..\..\sfutil\sfghash.h InputName=sfghash "..\..\dynamic-plugins\sf_engine\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\dynamic-plugins\sf_engine # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=..\..\sfutil\sfhashfcn.c !IF "$(CFG)" == "sf_engine_initialize - Win32 Release" # Begin Custom Build InputPath=..\..\sfutil\sfhashfcn.c InputName=sfhashfcn BuildCmds= \ copy $(InputPath) ..\..\dynamic-plugins\sf_engine\$(InputName).c.new \ c:\cygwin\bin\sed -e "s/\#ifndef MODULUS_HASH/\#ifdef STATIC_HASH/" ../../dynamic-plugins/sf_engine/$(InputName).c.new > ../../dynamic-plugins/sf_engine/$(InputName).c \ "..\..\dynamic-plugins\sf_engine\$(InputName).c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) "..\..\dynamic-plugins\sf_engine\$(InputName).c.new" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) # End Custom Build !ELSEIF "$(CFG)" == "sf_engine_initialize - Win32 Debug" # Begin Custom Build InputPath=..\..\sfutil\sfhashfcn.c InputName=sfhashfcn BuildCmds= \ copy $(InputPath) ..\..\dynamic-plugins\sf_engine\$(InputName).c.new \ c:\cygwin\bin\sed -e "s/\#ifndef MODULUS_HASH/\#ifdef STATIC_HASH/" ../../dynamic-plugins/sf_engine/$(InputName).c.new > ../../dynamic-plugins/sf_engine/$(InputName).c \ "..\..\dynamic-plugins\sf_engine\$(InputName).c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) "..\..\dynamic-plugins\sf_engine\$(InputName).c.new" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=..\..\sfutil\sfhashfcn.h !IF "$(CFG)" == "sf_engine_initialize - Win32 Release" # Begin Custom Build InputPath=..\..\sfutil\sfhashfcn.h InputName=sfhashfcn "..\..\dynamic-plugins\sf_engine\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\dynamic-plugins\sf_engine # End Custom Build !ELSEIF "$(CFG)" == "sf_engine_initialize - Win32 Debug" # Begin Custom Build InputPath=..\..\sfutil\sfhashfcn.h InputName=sfhashfcn "..\..\dynamic-plugins\sf_engine\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\dynamic-plugins\sf_engine # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=..\..\sfutil\sfprimetable.c !IF "$(CFG)" == "sf_engine_initialize - Win32 Release" # Begin Custom Build InputPath=..\..\sfutil\sfprimetable.c InputName=sfprimetable "..\..\dynamic-plugins\sf_engine\$(InputName).c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\dynamic-plugins\sf_engine # End Custom Build !ELSEIF "$(CFG)" == "sf_engine_initialize - Win32 Debug" # Begin Custom Build InputPath=..\..\sfutil\sfprimetable.c InputName=sfprimetable "..\..\dynamic-plugins\sf_engine\$(InputName).c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\dynamic-plugins\sf_engine # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=..\..\sfutil\sfprimetable.h !IF "$(CFG)" == "sf_engine_initialize - Win32 Release" # Begin Custom Build InputPath=..\..\sfutil\sfprimetable.h InputName=sfprimetable "..\..\dynamic-plugins\sf_engine\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\dynamic-plugins\sf_engine # End Custom Build !ELSEIF "$(CFG)" == "sf_engine_initialize - Win32 Debug" # Begin Custom Build InputPath=..\..\sfutil\sfprimetable.h InputName=sfprimetable "..\..\dynamic-plugins\sf_engine\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\dynamic-plugins\sf_engine # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=..\..\sfutil\sha2.c !IF "$(CFG)" == "sf_engine_initialize - Win32 Release" # Begin Custom Build InputPath=..\..\sfutil\sha2.c InputName=sha2 "..\..\dynamic-plugins\sf_engine\$(InputName).c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\dynamic-plugins\sf_engine # End Custom Build !ELSEIF "$(CFG)" == "sf_engine_initialize - Win32 Debug" # Begin Custom Build InputPath=..\..\sfutil\sha2.c InputName=sha2 "..\..\dynamic-plugins\sf_engine\$(InputName).c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\dynamic-plugins\sf_engine # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=..\..\sfutil\sha2.h !IF "$(CFG)" == "sf_engine_initialize - Win32 Release" # Begin Custom Build InputPath=..\..\sfutil\sha2.h InputName=sha2 "..\..\dynamic-plugins\sf_engine\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\dynamic-plugins\sf_engine # End Custom Build !ELSEIF "$(CFG)" == "sf_engine_initialize - Win32 Debug" # Begin Custom Build InputPath=..\..\sfutil\sha2.h InputName=sha2 "..\..\dynamic-plugins\sf_engine\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy $(InputPath) ..\..\dynamic-plugins\sf_engine # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=..\..\snort_debug.h !IF "$(CFG)" == "sf_engine_initialize - Win32 Release" # Begin Custom Build InputPath=..\..\snort_debug.h InputName=snort_debug BuildCmds= \ copy $(InputPath) ..\..\dynamic-plugins\sf_engine\$(InputName).h.new \ c:\cygwin\bin\sed -e "s/DebugMessageFile = /*_ded.debugMsgFile = /" -e "s/DebugMessageLine = /*_ded.debugMsgLine = /" -e "s/; DebugMessageFunc$/; _ded.debugMsg/" -e "s/; DebugWideMessageFunc$/; _ded.debugWideMsg/" ../../dynamic-plugins\sf_engine\$(InputName).h.new > ../../dynamic-plugins/sf_engine/$(InputName).h \ "..\..\dynamic-plugins\sf_engine\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) "..\..\dynamic-plugins\sf_engine\$(InputName).h.new" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) # End Custom Build !ELSEIF "$(CFG)" == "sf_engine_initialize - Win32 Debug" # Begin Custom Build InputPath=..\..\snort_debug.h InputName=snort_debug BuildCmds= \ copy $(InputPath) ..\..\dynamic-plugins\sf_engine\$(InputName).h.new \ c:\cygwin\bin\sed -e "s/DebugMessageFile = /*_ded.debugMsgFile = /" -e "s/DebugMessageLine = /*_ded.debugMsgLine = /" -e "s/; DebugMessageFunc$/; _ded.debugMsg/" -e "s/; DebugWideMessageFunc$/; _ded.debugWideMsg/" ../../dynamic-plugins/sf_engine/$(InputName).h.new > ../../dynamic-plugins/sf_engine/$(InputName).h \ "..\..\dynamic-plugins\sf_engine\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) "..\..\dynamic-plugins\sf_engine\$(InputName).h.new" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) # End Custom Build !ENDIF # End Source File # End Target # End Project snort-2.9.15.1/src/win32/WIN32-Prj/snort.dsw0000444000175200017520000002173113571422610015014 00000000000000Microsoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "build_all"=".\build_all.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name dynamic_preprocessors End Project Dependency Begin Project Dependency Project_Dep_Name sf_engine End Project Dependency Begin Project Dependency Project_Dep_Name daq End Project Dependency Begin Project Dependency Project_Dep_Name snort End Project Dependency Begin Project Dependency Project_Dep_Name u2spewfoo End Project Dependency }}} ############################################################################### Project: "daq"="..\..\..\daq\daq.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Project: "dynamic_preprocessors"="..\..\dynamic-preprocessors\dynamic_preprocessors.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name sf_ftptelnet End Project Dependency Begin Project Dependency Project_Dep_Name sf_smtp End Project Dependency Begin Project Dependency Project_Dep_Name sf_ssh End Project Dependency Begin Project Dependency Project_Dep_Name sf_dns End Project Dependency Begin Project Dependency Project_Dep_Name sf_ssl End Project Dependency Begin Project Dependency Project_Dep_Name sf_dce2 End Project Dependency Begin Project Dependency Project_Dep_Name sf_sdf End Project Dependency Begin Project Dependency Project_Dep_Name sf_sip End Project Dependency Begin Project Dependency Project_Dep_Name sf_dynamic_initialize End Project Dependency Begin Project Dependency Project_Dep_Name sf_imap End Project Dependency Begin Project Dependency Project_Dep_Name sf_pop End Project Dependency Begin Project Dependency Project_Dep_Name sf_dnp3 End Project Dependency Begin Project Dependency Project_Dep_Name sf_modbus End Project Dependency Begin Project Dependency Project_Dep_Name sf_reputation End Project Dependency Begin Project Dependency Project_Dep_Name sf_gtp End Project Dependency }}} ############################################################################### Project: "sf_dce2"="..\..\dynamic-preprocessors\dcerpc2\sf_dce2.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name sf_dynamic_initialize End Project Dependency }}} ############################################################################### Project: "sf_dnp3"="..\..\dynamic-preprocessors\dnp3\sf_dnp3.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name sf_dynamic_initialize End Project Dependency }}} ############################################################################### Project: "sf_dns"="..\..\dynamic-preprocessors\dns\sf_dns.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name sf_dynamic_initialize End Project Dependency }}} ############################################################################### Project: "sf_dynamic_initialize"="..\..\dynamic-preprocessors\sf_dynamic_initialize\sf_dynamic_initialize.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Project: "sf_engine"=".\sf_engine.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name sf_engine_initialize End Project Dependency }}} ############################################################################### Project: "sf_engine_initialize"=".\sf_engine_initialize.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Project: "sf_ftptelnet"="..\..\dynamic-preprocessors\ftptelnet\sf_ftptelnet.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name sf_dynamic_initialize End Project Dependency }}} ############################################################################### Project: "sf_gtp"="..\..\dynamic-preprocessors\gtp\sf_gtp.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Project: "sf_imap"="..\..\dynamic-preprocessors\imap\sf_imap.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name sf_dynamic_initialize End Project Dependency }}} ############################################################################### Project: "sf_modbus"="..\..\dynamic-preprocessors\modbus\sf_modbus.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name sf_dynamic_initialize End Project Dependency }}} ############################################################################### Project: "sf_pop"="..\..\dynamic-preprocessors\pop\sf_pop.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name sf_dynamic_initialize End Project Dependency }}} ############################################################################### Project: "sf_reputation"="..\..\dynamic-preprocessors\reputation\sf_reputation.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name sf_dynamic_initialize End Project Dependency }}} ############################################################################### Project: "sf_sdf"="..\..\dynamic-preprocessors\sdf\sf_sdf.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name sf_dynamic_initialize End Project Dependency }}} ############################################################################### Project: "sf_sip"="..\..\dynamic-preprocessors\sip\sf_sip.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name sf_dynamic_initialize End Project Dependency }}} ############################################################################### Project: "sf_smtp"="..\..\dynamic-preprocessors\smtp\sf_smtp.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name sf_dynamic_initialize End Project Dependency Begin Project Dependency Project_Dep_Name sfdynamic_preproc_libs End Project Dependency }}} ############################################################################### Project: "sf_ssh"="..\..\dynamic-preprocessors\ssh\sf_ssh.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name sf_dynamic_initialize End Project Dependency }}} ############################################################################### Project: "sf_ssl"="..\..\dynamic-preprocessors\ssl\sf_ssl.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name sf_dynamic_initialize End Project Dependency }}} ############################################################################### Project: "sfdynamic_preproc_libs"="..\..\dynamic-preprocessors\libs\sfdynamic_preproc_libs.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name sf_dynamic_initialize End Project Dependency }}} ############################################################################### Project: "snort"=".\snort.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name snort_initialize End Project Dependency }}} ############################################################################### Project: "snort_initialize"=".\snort_initialize.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Project: "u2spewfoo"="..\..\..\tools\u2spewfoo\u2spewfoo.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### snort-2.9.15.1/src/win32/Makefile.in0000644000000000000000000004015313571425506013614 00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 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@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd 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/win32 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LIBRARIES = $(noinst_LIBRARIES) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = depcomp = am__depfiles_maybe = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CCONFIGFLAGS = @CCONFIGFLAGS@ CFLAGS = @CFLAGS@ CONFIGFLAGS = @CONFIGFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ ICONFIGFLAGS = @ICONFIGFLAGS@ INCLUDES = @INCLUDES@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LUA_CFLAGS = @LUA_CFLAGS@ LUA_LIBS = @LUA_LIBS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIGNAL_SNORT_DUMP_STATS = @SIGNAL_SNORT_DUMP_STATS@ SIGNAL_SNORT_READ_ATTR_TBL = @SIGNAL_SNORT_READ_ATTR_TBL@ SIGNAL_SNORT_RELOAD = @SIGNAL_SNORT_RELOAD@ SIGNAL_SNORT_ROTATE_STATS = @SIGNAL_SNORT_ROTATE_STATS@ STRIP = @STRIP@ VERSION = @VERSION@ XCCFLAGS = @XCCFLAGS@ YACC = @YACC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ 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@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luajit_CFLAGS = @luajit_CFLAGS@ luajit_LIBS = @luajit_LIBS@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ # $Id$ AUTOMAKE_OPTIONS = foreign no-dependencies # find . -type f | grep -ve 'CVS\|Makefile\.\(in\|am\)' EXTRA_DIST = \ ./WIN32-Code/getopt.c \ ./WIN32-Code/getopt_long.c \ ./WIN32-Code/inet_aton.c \ ./WIN32-Code/inet_pton.c \ ./WIN32-Code/misc.c \ ./WIN32-Code/name.aps \ ./WIN32-Code/name.h \ ./WIN32-Code/name.mc \ ./WIN32-Code/name.rc \ ./WIN32-Code/MSG00001.bin \ ./WIN32-Code/strtok_r.c \ ./WIN32-Code/syslog.c \ ./WIN32-Code/win32_service.c \ ./WIN32-Includes/config.h \ ./WIN32-Includes/getopt.h \ ./WIN32-Includes/getopt1.h \ ./WIN32-Includes/gnuc.h \ ./WIN32-Includes/inttypes.h \ ./WIN32-Includes/libdnet/dnet.h \ ./WIN32-Includes/libdnet/dnet/addr.h \ ./WIN32-Includes/libdnet/dnet/arp.h \ ./WIN32-Includes/libdnet/dnet/blob.h \ ./WIN32-Includes/libdnet/dnet/eth.h \ ./WIN32-Includes/libdnet/dnet/fw.h \ ./WIN32-Includes/libdnet/dnet/icmp.h \ ./WIN32-Includes/libdnet/dnet/intf.h \ ./WIN32-Includes/libdnet/dnet/ip.h \ ./WIN32-Includes/libdnet/dnet/ip6.h \ ./WIN32-Includes/libdnet/dnet/os.h \ ./WIN32-Includes/libdnet/dnet/rand.h \ ./WIN32-Includes/libdnet/dnet/route.h \ ./WIN32-Includes/libdnet/dnet/tcp.h \ ./WIN32-Includes/libdnet/dnet/tun.h \ ./WIN32-Includes/libdnet/dnet/udp.h \ ./WIN32-Includes/NET/Bpf.h \ ./WIN32-Includes/NETINET/IF_ETHER.H \ ./WIN32-Includes/NETINET/IN_SYSTM.H \ ./WIN32-Includes/NETINET/IP.H \ ./WIN32-Includes/NETINET/IP_ICMP.H \ ./WIN32-Includes/NETINET/IP_VAR.H \ ./WIN32-Includes/NETINET/TCP.H \ ./WIN32-Includes/NETINET/TCPIP.H \ ./WIN32-Includes/NETINET/TCP_VAR.H \ ./WIN32-Includes/NETINET/UDP.H \ ./WIN32-Includes/NETINET/UDP_VAR.H \ ./WIN32-Includes/pcre.h \ ./WIN32-Includes/pcreposix.h \ ./WIN32-Includes/rpc/auth.h \ ./WIN32-Includes/rpc/auth_unix.h \ ./WIN32-Includes/rpc/clnt.h \ ./WIN32-Includes/rpc/pmap_clnt.h \ ./WIN32-Includes/rpc/pmap_prot.h \ ./WIN32-Includes/rpc/pmap_rmt.h \ ./WIN32-Includes/rpc/rpc_des.h \ ./WIN32-Includes/rpc/rpc.h \ ./WIN32-Includes/rpc/rpc_msg.h \ ./WIN32-Includes/rpc/svc_auth.h \ ./WIN32-Includes/rpc/svc.h \ ./WIN32-Includes/rpc/types.h \ ./WIN32-Includes/rpc/xdr.h \ ./WIN32-Includes/stdint.h \ ./WIN32-Includes/syslog.h \ ./WIN32-Includes/unistd.h \ ./WIN32-Includes/WinPCAP/bittypes.h \ ./WIN32-Includes/WinPCAP/bucket_lookup.h \ ./WIN32-Includes/WinPCAP/count_packets.h \ ./WIN32-Includes/WinPCAP/Devioctl.h \ ./WIN32-Includes/WinPCAP/Gnuc.h \ ./WIN32-Includes/WinPCAP/ip6_misc.h \ ./WIN32-Includes/WinPCAP/memory_t.h \ ./WIN32-Includes/WinPCAP/normal_lookup.h \ ./WIN32-Includes/WinPCAP/Ntddndis.h \ ./WIN32-Includes/WinPCAP/Ntddpack.h \ ./WIN32-Includes/WinPCAP/Packet32.h \ ./WIN32-Includes/WinPCAP/pcap/bluetooth.h \ ./WIN32-Includes/WinPCAP/pcap/bpf.h \ ./WIN32-Includes/WinPCAP/pcap/namedb.h \ ./WIN32-Includes/WinPCAP/pcap/pcap.h \ ./WIN32-Includes/WinPCAP/pcap/sll.h \ ./WIN32-Includes/WinPCAP/pcap/usb.h \ ./WIN32-Includes/WinPCAP/pcap/vlan.h \ ./WIN32-Includes/WinPCAP/pcap-bpf.h \ ./WIN32-Includes/WinPCAP/pcap.h \ ./WIN32-Includes/WinPCAP/pcap-int.h \ ./WIN32-Includes/WinPCAP/pcap-namedb.h \ ./WIN32-Includes/WinPCAP/pcap-stdinc.h \ ./WIN32-Includes/WinPCAP/pthread.h \ ./WIN32-Includes/WinPCAP/remote-ext.h \ ./WIN32-Includes/WinPCAP/sched.h \ ./WIN32-Includes/WinPCAP/semaphore.h \ ./WIN32-Includes/WinPCAP/tcp_session.h \ ./WIN32-Includes/WinPCAP/time_calls.h \ ./WIN32-Includes/WinPCAP/tme.h \ ./WIN32-Includes/WinPCAP/Win32-Extensions.h \ ./WIN32-Includes/zlib/zconf.h \ ./WIN32-Includes/zlib/zlib.h \ ./WIN32-Libraries/libdnet/dnet.lib \ ./WIN32-Libraries/.cvswrappers \ ./WIN32-Libraries/Packet.lib \ ./WIN32-Libraries/pcre.lib \ ./WIN32-Libraries/wpcap.lib \ ./WIN32-Libraries/zlib.lib \ ./WIN32-Libraries/zlib1.lib \ ./WIN32-Prj/build_releases.bat \ ./WIN32-Prj/LibnetNT.dll \ ./WIN32-Prj/pcre.dll \ ./WIN32-Prj/zlib1.dll \ ./WIN32-Prj/wpcap.dll \ ./WIN32-Prj/ntwdblib.dll \ ./WIN32-Prj/WanPacket.dll \ ./WIN32-Prj/npptools.dll \ ./WIN32-Prj/Packet.dll \ ./WIN32-Prj/snort_installer.nsi \ ./WIN32-Prj/snort_installer_options.ini \ ./WIN32-Prj/snort.dep \ ./WIN32-Prj/snort.dsp \ ./WIN32-Prj/snort_initialize.dsp \ ./WIN32-Prj/build_all.dsp \ ./WIN32-Prj/sf_engine.dsp \ ./WIN32-Prj/sf_engine_initialize.dsp \ ./WIN32-Prj/snort.dsw noinst_LIBRARIES = all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/win32/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/win32/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: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$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: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_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-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-noinstLIBRARIES cscopelist-am ctags-am distclean \ distclean-generic distclean-libtool distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ uninstall-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: snort-2.9.15.1/src/win32/Makefile.am0000444000175200017520000001010513571422607013630 00000000000000# $Id$ AUTOMAKE_OPTIONS=foreign no-dependencies # find . -type f | grep -ve 'CVS\|Makefile\.\(in\|am\)' EXTRA_DIST= \ ./WIN32-Code/getopt.c \ ./WIN32-Code/getopt_long.c \ ./WIN32-Code/inet_aton.c \ ./WIN32-Code/inet_pton.c \ ./WIN32-Code/misc.c \ ./WIN32-Code/name.aps \ ./WIN32-Code/name.h \ ./WIN32-Code/name.mc \ ./WIN32-Code/name.rc \ ./WIN32-Code/MSG00001.bin \ ./WIN32-Code/strtok_r.c \ ./WIN32-Code/syslog.c \ ./WIN32-Code/win32_service.c \ ./WIN32-Includes/config.h \ ./WIN32-Includes/getopt.h \ ./WIN32-Includes/getopt1.h \ ./WIN32-Includes/gnuc.h \ ./WIN32-Includes/inttypes.h \ ./WIN32-Includes/libdnet/dnet.h \ ./WIN32-Includes/libdnet/dnet/addr.h \ ./WIN32-Includes/libdnet/dnet/arp.h \ ./WIN32-Includes/libdnet/dnet/blob.h \ ./WIN32-Includes/libdnet/dnet/eth.h \ ./WIN32-Includes/libdnet/dnet/fw.h \ ./WIN32-Includes/libdnet/dnet/icmp.h \ ./WIN32-Includes/libdnet/dnet/intf.h \ ./WIN32-Includes/libdnet/dnet/ip.h \ ./WIN32-Includes/libdnet/dnet/ip6.h \ ./WIN32-Includes/libdnet/dnet/os.h \ ./WIN32-Includes/libdnet/dnet/rand.h \ ./WIN32-Includes/libdnet/dnet/route.h \ ./WIN32-Includes/libdnet/dnet/tcp.h \ ./WIN32-Includes/libdnet/dnet/tun.h \ ./WIN32-Includes/libdnet/dnet/udp.h \ ./WIN32-Includes/NET/Bpf.h \ ./WIN32-Includes/NETINET/IF_ETHER.H \ ./WIN32-Includes/NETINET/IN_SYSTM.H \ ./WIN32-Includes/NETINET/IP.H \ ./WIN32-Includes/NETINET/IP_ICMP.H \ ./WIN32-Includes/NETINET/IP_VAR.H \ ./WIN32-Includes/NETINET/TCP.H \ ./WIN32-Includes/NETINET/TCPIP.H \ ./WIN32-Includes/NETINET/TCP_VAR.H \ ./WIN32-Includes/NETINET/UDP.H \ ./WIN32-Includes/NETINET/UDP_VAR.H \ ./WIN32-Includes/pcre.h \ ./WIN32-Includes/pcreposix.h \ ./WIN32-Includes/rpc/auth.h \ ./WIN32-Includes/rpc/auth_unix.h \ ./WIN32-Includes/rpc/clnt.h \ ./WIN32-Includes/rpc/pmap_clnt.h \ ./WIN32-Includes/rpc/pmap_prot.h \ ./WIN32-Includes/rpc/pmap_rmt.h \ ./WIN32-Includes/rpc/rpc_des.h \ ./WIN32-Includes/rpc/rpc.h \ ./WIN32-Includes/rpc/rpc_msg.h \ ./WIN32-Includes/rpc/svc_auth.h \ ./WIN32-Includes/rpc/svc.h \ ./WIN32-Includes/rpc/types.h \ ./WIN32-Includes/rpc/xdr.h \ ./WIN32-Includes/stdint.h \ ./WIN32-Includes/syslog.h \ ./WIN32-Includes/unistd.h \ ./WIN32-Includes/WinPCAP/bittypes.h \ ./WIN32-Includes/WinPCAP/bucket_lookup.h \ ./WIN32-Includes/WinPCAP/count_packets.h \ ./WIN32-Includes/WinPCAP/Devioctl.h \ ./WIN32-Includes/WinPCAP/Gnuc.h \ ./WIN32-Includes/WinPCAP/ip6_misc.h \ ./WIN32-Includes/WinPCAP/memory_t.h \ ./WIN32-Includes/WinPCAP/normal_lookup.h \ ./WIN32-Includes/WinPCAP/Ntddndis.h \ ./WIN32-Includes/WinPCAP/Ntddpack.h \ ./WIN32-Includes/WinPCAP/Packet32.h \ ./WIN32-Includes/WinPCAP/pcap/bluetooth.h \ ./WIN32-Includes/WinPCAP/pcap/bpf.h \ ./WIN32-Includes/WinPCAP/pcap/namedb.h \ ./WIN32-Includes/WinPCAP/pcap/pcap.h \ ./WIN32-Includes/WinPCAP/pcap/sll.h \ ./WIN32-Includes/WinPCAP/pcap/usb.h \ ./WIN32-Includes/WinPCAP/pcap/vlan.h \ ./WIN32-Includes/WinPCAP/pcap-bpf.h \ ./WIN32-Includes/WinPCAP/pcap.h \ ./WIN32-Includes/WinPCAP/pcap-int.h \ ./WIN32-Includes/WinPCAP/pcap-namedb.h \ ./WIN32-Includes/WinPCAP/pcap-stdinc.h \ ./WIN32-Includes/WinPCAP/pthread.h \ ./WIN32-Includes/WinPCAP/remote-ext.h \ ./WIN32-Includes/WinPCAP/sched.h \ ./WIN32-Includes/WinPCAP/semaphore.h \ ./WIN32-Includes/WinPCAP/tcp_session.h \ ./WIN32-Includes/WinPCAP/time_calls.h \ ./WIN32-Includes/WinPCAP/tme.h \ ./WIN32-Includes/WinPCAP/Win32-Extensions.h \ ./WIN32-Includes/zlib/zconf.h \ ./WIN32-Includes/zlib/zlib.h \ ./WIN32-Libraries/libdnet/dnet.lib \ ./WIN32-Libraries/.cvswrappers \ ./WIN32-Libraries/Packet.lib \ ./WIN32-Libraries/pcre.lib \ ./WIN32-Libraries/wpcap.lib \ ./WIN32-Libraries/zlib.lib \ ./WIN32-Libraries/zlib1.lib \ ./WIN32-Prj/build_releases.bat \ ./WIN32-Prj/LibnetNT.dll \ ./WIN32-Prj/pcre.dll \ ./WIN32-Prj/zlib1.dll \ ./WIN32-Prj/wpcap.dll \ ./WIN32-Prj/ntwdblib.dll \ ./WIN32-Prj/WanPacket.dll \ ./WIN32-Prj/npptools.dll \ ./WIN32-Prj/Packet.dll \ ./WIN32-Prj/snort_installer.nsi \ ./WIN32-Prj/snort_installer_options.ini \ ./WIN32-Prj/snort.dep \ ./WIN32-Prj/snort.dsp \ ./WIN32-Prj/snort_initialize.dsp \ ./WIN32-Prj/build_all.dsp \ ./WIN32-Prj/sf_engine.dsp \ ./WIN32-Prj/sf_engine_initialize.dsp \ ./WIN32-Prj/snort.dsw noinst_LIBRARIES = snort-2.9.15.1/src/output-plugins/0000755000000000000000000000000013571426520013676 500000000000000snort-2.9.15.1/src/output-plugins/Makefile.in0000644000000000000000000004223713571425505015675 00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 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@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd 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@ @BUILD_BUFFER_DUMP_TRUE@am__append_1 = \ @BUILD_BUFFER_DUMP_TRUE@spo_log_buffer_dump.c spo_log_buffer_dump.h subdir = src/output-plugins DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LIBRARIES = $(noinst_LIBRARIES) ARFLAGS = cru AM_V_AR = $(am__v_AR_@AM_V@) am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) am__v_AR_0 = @echo " AR " $@; am__v_AR_1 = libspo_a_AR = $(AR) $(ARFLAGS) libspo_a_LIBADD = am__libspo_a_SOURCES_DIST = 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_log_null.c spo_log_null.h \ spo_log_tcpdump.c spo_log_tcpdump.h spo_unified2.c \ spo_unified2.h spo_log_ascii.c spo_log_ascii.h \ spo_alert_sf_socket.h spo_alert_sf_socket.c spo_alert_test.c \ spo_alert_test.h spo_log_buffer_dump.c spo_log_buffer_dump.h @BUILD_BUFFER_DUMP_TRUE@am__objects_1 = spo_log_buffer_dump.$(OBJEXT) am_libspo_a_OBJECTS = spo_alert_fast.$(OBJEXT) \ spo_alert_full.$(OBJEXT) spo_alert_syslog.$(OBJEXT) \ spo_alert_unixsock.$(OBJEXT) spo_csv.$(OBJEXT) \ spo_log_null.$(OBJEXT) spo_log_tcpdump.$(OBJEXT) \ spo_unified2.$(OBJEXT) spo_log_ascii.$(OBJEXT) \ spo_alert_sf_socket.$(OBJEXT) spo_alert_test.$(OBJEXT) \ $(am__objects_1) libspo_a_OBJECTS = $(am_libspo_a_OBJECTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = am__depfiles_maybe = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libspo_a_SOURCES) DIST_SOURCES = $(am__libspo_a_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CCONFIGFLAGS = @CCONFIGFLAGS@ CFLAGS = @CFLAGS@ CONFIGFLAGS = @CONFIGFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ ICONFIGFLAGS = @ICONFIGFLAGS@ INCLUDES = @INCLUDES@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LUA_CFLAGS = @LUA_CFLAGS@ LUA_LIBS = @LUA_LIBS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIGNAL_SNORT_DUMP_STATS = @SIGNAL_SNORT_DUMP_STATS@ SIGNAL_SNORT_READ_ATTR_TBL = @SIGNAL_SNORT_READ_ATTR_TBL@ SIGNAL_SNORT_RELOAD = @SIGNAL_SNORT_RELOAD@ SIGNAL_SNORT_ROTATE_STATS = @SIGNAL_SNORT_ROTATE_STATS@ STRIP = @STRIP@ VERSION = @VERSION@ XCCFLAGS = @XCCFLAGS@ YACC = @YACC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ 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@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luajit_CFLAGS = @luajit_CFLAGS@ luajit_LIBS = @luajit_LIBS@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ 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_log_null.c spo_log_null.h spo_log_tcpdump.c \ spo_log_tcpdump.h spo_unified2.c spo_unified2.h \ spo_log_ascii.c spo_log_ascii.h spo_alert_sf_socket.h \ spo_alert_sf_socket.c spo_alert_test.c spo_alert_test.h \ $(am__append_1) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/output-plugins/Makefile'; \ $(am__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: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libspo.a: $(libspo_a_OBJECTS) $(libspo_a_DEPENDENCIES) $(EXTRA_libspo_a_DEPENDENCIES) $(AM_V_at)-rm -f libspo.a $(AM_V_AR)$(libspo_a_AR) libspo.a $(libspo_a_OBJECTS) $(libspo_a_LIBADD) $(AM_V_at)$(RANLIB) libspo.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c .c.o: $(AM_V_CC)$(COMPILE) -c $< .c.obj: $(AM_V_CC)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: $(AM_V_CC)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files 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)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$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: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_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-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: 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: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLIBRARIES cscopelist-am ctags \ ctags-am 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-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am 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 tags-am uninstall uninstall-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: snort-2.9.15.1/src/output-plugins/Makefile.am0000444000175200017520000000114113571422607015705 00000000000000## $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_log_null.c spo_log_null.h \ spo_log_tcpdump.c spo_log_tcpdump.h \ spo_unified2.c spo_unified2.h \ spo_log_ascii.c spo_log_ascii.h \ spo_alert_sf_socket.h spo_alert_sf_socket.c \ spo_alert_test.c spo_alert_test.h if BUILD_BUFFER_DUMP libspo_a_SOURCES += \ spo_log_buffer_dump.c spo_log_buffer_dump.h endif INCLUDES = @INCLUDES@ snort-2.9.15.1/src/output-plugins/spo_alert_fast.c0000644000175200017520000002503513571422607017034 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** Copyright (C) 2000,2001 Andrew R. Baker ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ /* spo_alert_fast * * Purpose: output plugin for fast alerting * * Arguments: alert file * * Effect: * * Alerts are written to a file in the snort fast alert format * * Comments: Allows use of fast alerts with other output plugin types * */ /* output plugin header file */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifdef HAVE_STRINGS_H #include #endif #ifndef WIN32 #include #include #include #endif /* !WIN32 */ #include #include "spo_alert_fast.h" #include "event.h" #include "decode.h" #include "snort_debug.h" #include "plugbase.h" #include "spo_plugbase.h" #include "parser.h" #include "util.h" #include "log.h" #include "mstring.h" #include "active.h" #include "sfutil/sf_textlog.h" #include "log_text.h" #include "sf_textlog.h" #include "snort.h" #include "sfdaq.h" /* full buf was chosen to allow printing max size packets * in hex/ascii mode: * each byte => 2 nibbles + space + ascii + overhead */ #define FULL_BUF (4*IP_MAXPACKET) #define FAST_BUF (4*K_BYTES) /* * not defined for backwards compatibility * (default is produced by OpenAlertFile() #define DEFAULT_FILE "alert.fast" */ #define DEFAULT_LIMIT (128*M_BYTES) typedef struct _SpoAlertFastData { TextLog* log; uint8_t packet_flag; } SpoAlertFastData; static void AlertFastInit(struct _SnortConfig *, char *); static SpoAlertFastData *ParseAlertFastArgs(struct _SnortConfig *, char *); static void AlertFastCleanExitFunc(int, void *); static void AlertFast(Packet *, const char *, void *, Event *); /* * Function: SetupAlertFast() * * 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. * * Arguments: None. * * Returns: void function * */ void AlertFastSetup(void) { /* link the preprocessor keyword to the init function in the preproc list */ RegisterOutputPlugin("alert_fast", OUTPUT_TYPE_FLAG__ALERT, AlertFastInit); DEBUG_WRAP(DebugMessage(DEBUG_INIT,"Output plugin: AlertFast is setup...\n");); } /* * Function: AlertFastInit(char *) * * 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 * */ static void AlertFastInit(struct _SnortConfig *sc, char *args) { SpoAlertFastData *data; DEBUG_WRAP(DebugMessage(DEBUG_INIT,"Output: AlertFast Initialized\n");); /* parse the argument list from the rules file */ data = ParseAlertFastArgs(sc, args); DEBUG_WRAP(DebugMessage(DEBUG_INIT,"Linking AlertFast functions to call lists...\n");); /* Set the preprocessor function into the function list */ AddFuncToOutputList(sc, AlertFast, OUTPUT_TYPE__ALERT, data); AddFuncToCleanExitList(AlertFastCleanExitFunc, data); } static const char* s_dispos[] = { " [Allow]", " [CDrop]", " [WDrop]", " [Drop]", " [FDrop]" }; static void AlertFast(Packet *p, const char *msg, void *arg, Event *event) { SpoAlertFastData *data = (SpoAlertFastData *)arg; tActiveDrop dispos = Active_GetDisposition(); LogTimeStamp(data->log, p); if( p != NULL && dispos > ACTIVE_ALLOW ) { if ( dispos > ACTIVE_DROP ) dispos = ACTIVE_DROP; TextLog_Puts(data->log, s_dispos[dispos]); } { #ifdef MARK_TAGGED char c=' '; if ((p != NULL) && (p->packet_flags & PKT_REBUILT_STREAM)) c = 'R'; else if ((p != NULL) && (p->packet_flags & PKT_REBUILT_FRAG)) c = 'F'; TextLog_Print(data->log, " [**] %c ", c); #else TextLog_Puts(data->log, " [**] "); #endif if(event != NULL) { TextLog_Print(data->log, "[%lu:%lu:%lu] ", (unsigned long) event->sig_generator, (unsigned long) event->sig_id, (unsigned long) event->sig_rev); } if (ScAlertInterface()) { TextLog_Print(data->log, " <%s> ", PRINT_INTERFACE(DAQ_GetInterfaceSpec())); } if (msg != NULL) { TextLog_Puts(data->log, msg); TextLog_Puts(data->log, " [**] "); } else { TextLog_Puts(data->log, "[**] "); } } /* print the packet header to the alert file */ if ((p != NULL) && IPH_IS_VALID(p)) { LogPriorityData(data->log, 0); #if defined(FEAT_OPEN_APPID) LogAppID(data->log, event->app_name, 0); #endif TextLog_Print(data->log, "{%s} ", protocol_names[GET_IPH_PROTO(p)]); LogIpAddrs(data->log, p); } if(p && data->packet_flag) { /* Log whether or not this is reassembled data - only indicate * if we're actually going to show any of the payload */ if (ScOutputAppData() && (p->dsize > 0) && PacketWasCooked(p)) { switch ( p->pseudo_type ) { case PSEUDO_PKT_SMB_SEG: TextLog_Print(data->log, "\n%s", "SMB desegmented packet"); break; case PSEUDO_PKT_DCE_SEG: TextLog_Print(data->log, "\n%s", "DCE/RPC desegmented packet"); break; case PSEUDO_PKT_DCE_FRAG: TextLog_Print(data->log, "\n%s", "DCE/RPC defragmented packet"); break; case PSEUDO_PKT_SMB_TRANS: TextLog_Print(data->log, "\n%s", "SMB Transact reassembled packet"); break; case PSEUDO_PKT_DCE_RPKT: TextLog_Print(data->log, "\n%s", "DCE/RPC reassembled packet"); break; case PSEUDO_PKT_TCP: TextLog_Print(data->log, "\n%s", "Stream reassembled packet"); break; case PSEUDO_PKT_IP: TextLog_Print(data->log, "\n%s", "Frag reassembled packet"); break; default: // FIXTHIS do we get here for portscan or sdf? break; } } TextLog_NewLine(data->log); if(IPH_IS_VALID(p)) LogIPPkt(data->log, GET_IPH_PROTO(p), p); #ifndef NO_NON_ETHER_DECODER else if(p->ah) LogArpHeader(data->log, p); #endif } TextLog_NewLine(data->log); TextLog_Flush(data->log); } /* * Function: ParseAlertFastArgs(char *) * * Purpose: Process positional args, if any. Syntax is: * output alert_fast: [ ["packet"] []] * limit ::= ('G'|'M'|K') * * Arguments: args => argument list * * Returns: void function * */ static SpoAlertFastData *ParseAlertFastArgs(struct _SnortConfig *sc, char *args) { char **toks; int num_toks; SpoAlertFastData *data; char* filename = NULL; unsigned long limit = DEFAULT_LIMIT; unsigned int bufSize = FAST_BUF; int i; DEBUG_WRAP(DebugMessage(DEBUG_LOG, "ParseAlertFastArgs: %s\n", args);); data = (SpoAlertFastData *)SnortAlloc(sizeof(SpoAlertFastData)); if ( !data ) { FatalError("alert_fast: unable to allocate memory!\n"); } if ( !args ) args = ""; toks = mSplit((char *)args, " \t", 0, &num_toks, '\\'); for (i = 0; i < num_toks; i++) { const char* tok = toks[i]; char *end; switch (i) { case 0: if ( !strcasecmp(tok, "stdout") ) filename = SnortStrdup(tok); else filename = ProcessFileOption(sc, tok); break; case 1: if ( !strcasecmp("packet", tok) ) { data->packet_flag = 1; bufSize = FULL_BUF; break; } /* in this case, only 2 options allowed */ else i++; /* fall thru so "packet" is optional ... */ case 2: limit = strtol(tok, &end, 10); if ( tok == end ) FatalError("alert_fast error in %s(%i): %s\n", file_name, file_line, tok); if ( end && toupper(*end) == 'G' ) limit <<= 30; /* GB */ else if ( end && toupper(*end) == 'M' ) limit <<= 20; /* MB */ else if ( end && toupper(*end) == 'K' ) limit <<= 10; /* KB */ break; case 3: FatalError("alert_fast: error in %s(%i): %s\n", file_name, file_line, tok); break; } } mSplitFree(&toks, num_toks); #ifdef DEFAULT_FILE if ( !filename ) filename = ProcessFileOption(sc, DEFAULT_FILE); #endif DEBUG_WRAP(DebugMessage( DEBUG_INIT, "alert_fast: '%s' %d %ld\n", filename?filename:"alert", data->packet_flag, limit );); if ((filename == NULL) && (sc->alert_file != NULL)) filename = SnortStrdup(sc->alert_file); data->log = TextLog_Init(filename, bufSize, limit); if (filename != NULL) free(filename); return data; } static void AlertFastCleanup(int signal, void *arg, const char* msg) { SpoAlertFastData *data = (SpoAlertFastData *)arg; DEBUG_WRAP(DebugMessage(DEBUG_LOG, "%s\n", msg);); /*free memory from SpoAlertFastData */ if ( data->log ) TextLog_Term(data->log); free(data); } static void AlertFastCleanExitFunc(int signal, void *arg) { AlertFastCleanup(signal, arg, "AlertFastCleanExitFunc"); } snort-2.9.15.1/src/output-plugins/spo_alert_fast.h0000644000175200017520000000260413571422607017036 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** Copyright (C) 2000,2001 Andrew R. Baker ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ /* This file gets included in plugbase.h when it is integrated into the rest * of the program. Sometime in The Future, I'll whip up a bad ass Perl script * to handle automatically loading all the required info into the plugbase.* * files. */ #ifndef __SPO_ALERT_FAST_H__ #define __SPO_ALERT_FAST_H__ void AlertFastSetup(void); #endif /* __SPO_ALERT_FAST_H__ */ snort-2.9.15.1/src/output-plugins/spo_alert_full.c0000644000175200017520000002061313571422607017036 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** Copyright (C) 2000,2001 Andrew R. Baker ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ /* spo_alert_full * * Purpose: output plugin for full alerting * * Arguments: alert file (eventually) * * Effect: * * Alerts are written to a file in the snort full alert format * * Comments: Allows use of full alerts with other output plugin types * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_STRINGS_H #include #endif #include #include #include "sf_types.h" #include "spo_alert_full.h" #include "event.h" #include "decode.h" #include "plugbase.h" #include "spo_plugbase.h" #include "snort_debug.h" #include "parser.h" #include "util.h" #include "log.h" #include "mstring.h" #include "snort.h" #include "sfutil/sf_textlog.h" #include "log_text.h" #include "sfdaq.h" typedef struct _SpoAlertFullData { TextLog* log; } SpoAlertFullData; static void AlertFullInit(struct _SnortConfig *sc, char *); static SpoAlertFullData *ParseAlertFullArgs(struct _SnortConfig *, char *); static void AlertFull(Packet *, const char *, void *, Event *); static void AlertFullCleanExit(int, void *); /* * not defined for backwards compatibility * (default is produced by OpenAlertFile() #define DEFAULT_FILE "alert.full" */ #define DEFAULT_LIMIT (128*M_BYTES) #define LOG_BUFFER (4*K_BYTES) /* * Function: SetupAlertFull() * * 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. * * Arguments: None. * * Returns: void function * */ void AlertFullSetup(void) { /* link the preprocessor keyword to the init function in the preproc list */ RegisterOutputPlugin("alert_full", OUTPUT_TYPE_FLAG__ALERT, AlertFullInit); DEBUG_WRAP(DebugMessage(DEBUG_INIT,"Output plugin: AlertFull is setup...\n");); } /* * Function: AlertFullInit(char *) * * 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 * */ static void AlertFullInit(struct _SnortConfig *sc, char *args) { SpoAlertFullData *data; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Output: AlertFull Initialized\n");); /* parse the argument list from the rules file */ data = ParseAlertFullArgs(sc, args); DEBUG_WRAP(DebugMessage(DEBUG_INIT,"Linking AlertFull functions to call lists...\n");); /* Set the preprocessor function into the function list */ AddFuncToOutputList(sc, AlertFull, OUTPUT_TYPE__ALERT, data); AddFuncToCleanExitList(AlertFullCleanExit, data); } static void AlertFull(Packet *p, const char *msg, void *arg, Event *event) { SpoAlertFullData *data = (SpoAlertFullData *)arg; { TextLog_Puts(data->log, "[**] "); if(event != NULL) { TextLog_Print(data->log, "[%lu:%lu:%lu] ", (unsigned long) event->sig_generator, (unsigned long) event->sig_id, (unsigned long) event->sig_rev); } if (ScAlertInterface()) { const char* iface = PRINT_INTERFACE(DAQ_GetInterfaceSpec()); TextLog_Print(data->log, " <%s> ", iface); } if(msg != NULL) { TextLog_Puts(data->log, msg); TextLog_Puts(data->log, " [**]\n"); } else { TextLog_Puts(data->log, "[**]\n"); } } if(p && IPH_IS_VALID(p)) { LogPriorityData(data->log, TRUE); #if defined(FEAT_OPEN_APPID) LogAppID(data->log, event->app_name, TRUE); #endif } DEBUG_WRAP(DebugMessage(DEBUG_LOG, "Logging Alert data!\n");); LogTimeStamp(data->log, p); if(p && IPH_IS_VALID(p)) { /* print the packet header to the alert file */ if (ScOutputDataLink()) { Log2ndHeader(data->log, p); } LogIPHeader(data->log, p); /* if this isn't a fragment, print the other header info */ if(!p->frag_flag) { switch(GET_IPH_PROTO(p)) { case IPPROTO_TCP: LogTCPHeader(data->log, p); break; case IPPROTO_UDP: LogUDPHeader(data->log, p); break; case IPPROTO_ICMP: LogICMPHeader(data->log, p); break; default: break; } } LogXrefs(data->log, 1); TextLog_Putc(data->log, '\n'); } /* End of if(p) */ else { TextLog_Puts(data->log, "\n\n"); } TextLog_Flush(data->log); } /* * Function: ParseAlertFullArgs(char *) * * Purpose: Process positional args, if any. Syntax is: * output alert_full: [ []] * limit ::= ('G'|'M'|K') * * Arguments: args => argument list * * Returns: void function */ static SpoAlertFullData *ParseAlertFullArgs(struct _SnortConfig *sc, char *args) { char **toks; int num_toks; SpoAlertFullData *data; char* filename = NULL; unsigned long limit = DEFAULT_LIMIT; int i; DEBUG_WRAP(DebugMessage(DEBUG_LOG, "ParseAlertFullArgs: %s\n", args);); data = (SpoAlertFullData *)SnortAlloc(sizeof(SpoAlertFullData)); if ( !data ) { FatalError("alert_full: unable to allocate memory!\n"); } if ( !args ) args = ""; toks = mSplit((char *)args, " \t", 0, &num_toks, '\\'); for (i = 0; i < num_toks; i++) { const char* tok = toks[i]; char *end; switch (i) { case 0: if ( !strcasecmp(tok, "stdout") ) filename = SnortStrdup(tok); else filename = ProcessFileOption(sc, tok); break; case 1: limit = strtol(tok, &end, 10); if ( tok == end ) FatalError("alert_full error in %s(%i): %s\n", file_name, file_line, tok); if ( end && toupper(*end) == 'G' ) limit <<= 30; /* GB */ else if ( end && toupper(*end) == 'M' ) limit <<= 20; /* MB */ else if ( end && toupper(*end) == 'K' ) limit <<= 10; /* KB */ break; case 2: FatalError("alert_full: error in %s(%i): %s\n", file_name, file_line, tok); break; } } mSplitFree(&toks, num_toks); #ifdef DEFAULT_FILE if ( !filename ) filename = ProcessFileOption(sc, DEFAULT_FILE); #endif DEBUG_WRAP(DebugMessage( DEBUG_INIT, "alert_full: '%s' %ld\n", filename ? filename : "alert", limit );); if ((filename == NULL) && (sc->alert_file != NULL)) filename = SnortStrdup(sc->alert_file); data->log = TextLog_Init(filename, LOG_BUFFER, limit); if (filename != NULL) free(filename); return data; } static void AlertFullCleanup(int signal, void *arg, const char* msg) { SpoAlertFullData *data = (SpoAlertFullData *)arg; DEBUG_WRAP(DebugMessage(DEBUG_LOG, "%s\n", msg);); /* free memory from SpoAlertFullData */ if ( data->log ) TextLog_Term(data->log); free(data); } static void AlertFullCleanExit(int signal, void *arg) { AlertFullCleanup(signal, arg, "AlertFullCleanExit"); } snort-2.9.15.1/src/output-plugins/spo_alert_full.h0000644000175200017520000000260113571422607017040 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** Copyright (C) 2000,2001 Andrew R. Baker ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ /* This file gets included in plugbase.h when it is integrated into the rest * of the program. Sometime in The Future, I'll whip up a bad ass Perl script * to handle automatically loading all the required info into the plugbase.* * files. */ #ifndef __SPO_FULLALERT_H__ #define __SPO_FULLALERT_H__ void AlertFullSetup(void); #endif /* __SPO_FULLALERT_H__ */ snort-2.9.15.1/src/output-plugins/spo_alert_syslog.c0000644000175200017520000004242413571422607017420 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ /* spo_alert_syslog * * Purpose: * * This module sends alerts to the syslog service. * * Arguments: * * Logging mechanism? * * Effect: * * Alerts are written to the syslog service with in the facility indicated by * the module arguments. * * Comments: * * First try * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifdef HAVE_STRINGS_H #include #endif #ifndef WIN32 #include #include #include #endif /* !WIN32 */ #include "decode.h" #include "event.h" #include "rules.h" #include "treenodes.h" #include "plugbase.h" #include "spo_plugbase.h" #include "snort_debug.h" #include "parser.h" #include "mstring.h" #include "util.h" #include "strlcatu.h" #include "strlcpyu.h" #include "util_net.h" #include "snort.h" #include "sfdaq.h" extern OptTreeNode *otn_tmp; typedef struct _SyslogData { int facility; int priority; int options; } SyslogData; static void AlertSyslogInit(struct _SnortConfig *, char *); static SyslogData *ParseSyslogArgs(struct _SnortConfig *, char *); static void AlertSyslog(Packet *, const char *, void *, Event *); static void AlertSyslogCleanExit(int, void *); /* * Function: SetupSyslog() * * 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. * * Arguments: None. * * Returns: void function * */ void AlertSyslogSetup(void) { /* link the preprocessor keyword to the init function in the preproc list */ RegisterOutputPlugin("alert_syslog", OUTPUT_TYPE_FLAG__ALERT, AlertSyslogInit); DEBUG_WRAP(DebugMessage(DEBUG_INIT,"Output plugin: Alert-Syslog is setup...\n");); } /* * Function: AlertSyslogInit(char *) * * 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 * */ static void AlertSyslogInit(struct _SnortConfig *sc, char *args) { SyslogData *data; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Output: Alert-Syslog Initialized\n");); /* parse the argument list from the rules file */ data = ParseSyslogArgs(sc, args); if (ScDaemonMode()) data->options |= LOG_PID; openlog("snort", data->options, data->facility); DEBUG_WRAP(DebugMessage(DEBUG_INIT,"Linking syslog alert function to call list...\n");); /* Set the preprocessor function into the function list */ AddFuncToOutputList(sc, AlertSyslog, OUTPUT_TYPE__ALERT, data); AddFuncToCleanExitList(AlertSyslogCleanExit, data); } /* * Function: ParseSyslogArgs(struct _SnortConfig *, char *) * * Purpose: Process the preprocessor arguments from the rules file and * initialize the preprocessor's data struct. This function doesn't * have to exist if it makes sense to parse the args in the init * function. * * Arguments: args => argument list * * Returns: void function * */ static SyslogData *ParseSyslogArgs(struct _SnortConfig *sc, char *args) { #ifdef WIN32 char *DEFAULT_SYSLOG_HOST = "127.0.0.1"; int DEFAULT_SYSLOG_PORT = 514; char **config_toks; char **host_toks; char *host_string = args; int num_config_toks, num_host_toks; #endif char **facility_toks; char *facility_string = args; int num_facility_toks = 0; int i = 0; SyslogData *data; char *tmp; data = (SyslogData *)SnortAlloc(sizeof(SyslogData)); /* default values for syslog output */ data->options = 0; data->facility = LOG_AUTH; data->priority = LOG_INFO; if(args == NULL) { /* horrible kludge to catch default initialization */ if(file_name != NULL) { LogMessage("%s(%d) => No arguments to alert_syslog preprocessor!\n", file_name, file_line); } return data; } /* * NON-WIN32: Config should be in the format: * output alert_syslog: LOG_AUTH LOG_ALERT * * WIN32: Config can be in any of these formats: * output alert_syslog: LOG_AUTH LOG_ALERT * output alert_syslog: host=hostname, LOG_AUTH LOG_ALERT * output alert_syslog: host=hostname:port, LOG_AUTH LOG_ALERT */ #ifdef WIN32 /* split the host/port part from the facilities/priorities part */ facility_string = NULL; config_toks = mSplit(args, ",", 2, &num_config_toks, '\\'); switch( num_config_toks ) { case 1: /* config consists of only facility/priority info */ LogMessage("alert_syslog output processor is defaulting to syslog " "server on %s port %d!\n", DEFAULT_SYSLOG_HOST, DEFAULT_SYSLOG_PORT); SnortStrncpy(snort_conf->syslog_server, DEFAULT_SYSLOG_HOST, sizeof(snort_conf->syslog_server)); snort_conf->syslog_server_port = DEFAULT_SYSLOG_PORT; facility_string = SnortStrdup(config_toks[0]); break; case 2: /* config consists of host info, and facility/priority info */ host_string = config_toks[0]; facility_string = SnortStrdup(config_toks[1]); /* split host_string into "host" vs. "server" vs. "port" */ host_toks = mSplit(host_string, "=:", 3, &num_host_toks, 0); if(num_host_toks > 0 && strcmp(host_toks[0], "host") != 0 ) { FatalError("%s(%d) => Badly formed alert_syslog 'host' " "argument ('%s')\n", file_name, file_line, host_string); } /* check for empty strings */ if((num_host_toks >= 1 && strlen(host_toks[0]) == 0) || (num_host_toks >= 2 && strlen(host_toks[1]) == 0) || (num_host_toks >= 3 && strlen(host_toks[2]) == 0)) { FatalError("%s(%d) => Badly formed alert_syslog 'host' " "argument ('%s')\n", file_name, file_line, host_string); } switch(num_host_toks) { case 2: /* ie, host=localhost (defaults to port 514) */ SnortStrncpy(snort_conf->syslog_server, host_toks[1], sizeof(snort_conf->syslog_server)); snort_conf->syslog_server_port = DEFAULT_SYSLOG_PORT; /* default */ break; case 3: /* ie. host=localhost:514 */ SnortStrncpy(snort_conf->syslog_server, host_toks[1], sizeof(snort_conf->syslog_server)); snort_conf->syslog_server_port = atoi(host_toks[2]); if (snort_conf->syslog_server_port == 0) { snort_conf->syslog_server_port = DEFAULT_SYSLOG_PORT; /*default*/ LogMessage("WARNING %s(%d) => alert_syslog port " "appears to be non-numeric ('%s'). Defaulting " "to port %d!\n", file_name, file_line, host_toks[2], DEFAULT_SYSLOG_PORT); } break; default: /* badly formed, should never occur */ FatalError("%s(%d) => Badly formed alert_syslog 'host' " "argument ('%s')\n", file_name, file_line, host_string); } mSplitFree(&host_toks, num_host_toks); break; default: FatalError("%s(%d) => Badly formed alert_syslog arguments ('%s')\n", file_name, file_line, args); } DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Logging alerts to syslog " "server %s on port %d\n", snort_conf->syslog_server, snort_conf->syslog_server_port);); mSplitFree(&config_toks, num_facility_toks); #endif /* WIN32 */ /* tokenize the facility/priority argument list */ facility_toks = mSplit(facility_string, " |", 31, &num_facility_toks, '\\'); for(i = 0; i < num_facility_toks; i++) { if(*facility_toks[i] == '$') { if((tmp = VarGet(sc, facility_toks[i]+1)) == NULL) { FatalError("%s(%d) => Undefined variable %s\n", file_name, file_line, facility_toks[i]); } } else { tmp = facility_toks[i]; } /* possible openlog options */ #ifdef LOG_CONS if(!strcasecmp("LOG_CONS", tmp)) { data->options |= LOG_CONS; } else #endif #ifdef LOG_NDELAY if(!strcasecmp("LOG_NDELAY", tmp)) { data->options |= LOG_NDELAY; } else #endif #ifdef LOG_PERROR if(!strcasecmp("LOG_PERROR", tmp)) { data->options |= LOG_PERROR; } else #endif #ifdef LOG_PID if(!strcasecmp("LOG_PID", tmp)) { data->options |= LOG_PID; } else #endif #ifdef LOG_NOWAIT if(!strcasecmp("LOG_NOWAIT", tmp)) { data->options |= LOG_NOWAIT; } else #endif /* possible openlog facilities */ #ifdef LOG_AUTHPRIV if(!strcasecmp("LOG_AUTHPRIV", tmp)) { data->facility = LOG_AUTHPRIV; } else #endif #ifdef LOG_AUTH if(!strcasecmp("LOG_AUTH", tmp)) { data->facility = LOG_AUTH; } else #endif #ifdef LOG_DAEMON if(!strcasecmp("LOG_DAEMON", tmp)) { data->facility = LOG_DAEMON; } else #endif #ifdef LOG_LOCAL0 if(!strcasecmp("LOG_LOCAL0", tmp)) { data->facility = LOG_LOCAL0; } else #endif #ifdef LOG_LOCAL1 if(!strcasecmp("LOG_LOCAL1", tmp)) { data->facility = LOG_LOCAL1; } else #endif #ifdef LOG_LOCAL2 if(!strcasecmp("LOG_LOCAL2", tmp)) { data->facility = LOG_LOCAL2; } else #endif #ifdef LOG_LOCAL3 if(!strcasecmp("LOG_LOCAL3", tmp)) { data->facility = LOG_LOCAL3; } else #endif #ifdef LOG_LOCAL4 if(!strcasecmp("LOG_LOCAL4", tmp)) { data->facility = LOG_LOCAL4; } else #endif #ifdef LOG_LOCAL5 if(!strcasecmp("LOG_LOCAL5", tmp)) { data->facility = LOG_LOCAL5; } else #endif #ifdef LOG_LOCAL6 if(!strcasecmp("LOG_LOCAL6", tmp)) { data->facility = LOG_LOCAL6; } else #endif #ifdef LOG_LOCAL7 if(!strcasecmp("LOG_LOCAL7", tmp)) { data->facility = LOG_LOCAL7; } else #endif #ifdef LOG_USER if(!strcasecmp("LOG_USER", tmp)) { data->facility = LOG_USER; } else #endif /* possible syslog priorities */ #ifdef LOG_EMERG if(!strcasecmp("LOG_EMERG", tmp)) { data->priority = LOG_EMERG; } else #endif #ifdef LOG_ALERT if(!strcasecmp("LOG_ALERT", tmp)) { data->priority = LOG_ALERT; } else #endif #ifdef LOG_CRIT if(!strcasecmp("LOG_CRIT", tmp)) { data->priority = LOG_CRIT; } else #endif #ifdef LOG_ERR if(!strcasecmp("LOG_ERR", tmp)) { data->priority = LOG_ERR; } else #endif #ifdef LOG_WARNING if(!strcasecmp("LOG_WARNING", tmp)) { data->priority = LOG_WARNING; } else #endif #ifdef LOG_NOTICE if(!strcasecmp("LOG_NOTICE", tmp)) { data->priority = LOG_NOTICE; } else #endif #ifdef LOG_INFO if(!strcasecmp("LOG_INFO", tmp)) { data->priority = LOG_INFO; } else #endif #ifdef LOG_DEBUG if(!strcasecmp("LOG_DEBUG", tmp)) { data->priority = LOG_DEBUG; } else #endif { LogMessage("WARNING: %s (%d) => Unrecognized syslog " "facility/priority: %s\n", file_name, file_line, tmp); } } mSplitFree(&facility_toks, num_facility_toks); /* Add facility flags to priority flags for logging to syslog */ data->priority |= data->facility; #ifdef WIN32 if (facility_string != NULL) free(facility_string); #endif return data; } /* * Function: PreprocFunction(Packet *) * * Purpose: Perform the preprocessor's intended function. This can be * simple (statistics collection) or complex (IP defragmentation) * as you like. Try not to destroy the performance of the whole * system by trying to do too much.... * * Arguments: p => pointer to the current packet data struct * * Returns: void function * */ static void AlertSyslog(Packet *p, const char *msg, void *arg, Event *event) { SyslogData *data = (SyslogData *)arg; char event_string[STD_BUF]; if (data == NULL) return; event_string[0] = '\0'; if ((p != NULL) && IPH_IS_VALID(p)) { if (event != NULL) { SnortSnprintfAppend(event_string, sizeof(event_string), "[%lu:%lu:%lu] ", (unsigned long)event->sig_generator, (unsigned long)event->sig_id, (unsigned long)event->sig_rev); } if (msg != NULL) SnortSnprintfAppend(event_string, sizeof(event_string), "%s ", msg); else SnortSnprintfAppend(event_string, sizeof(event_string), "ALERT "); if (otn_tmp != NULL) { if ((otn_tmp->sigInfo.classType != NULL) && (otn_tmp->sigInfo.classType->name != NULL)) { SnortSnprintfAppend(event_string, sizeof(event_string), "[Classification: %s] ", otn_tmp->sigInfo.classType->name); } if (otn_tmp->sigInfo.priority != 0) { SnortSnprintfAppend(event_string, sizeof(event_string), "[Priority: %d] ", otn_tmp->sigInfo.priority); } } if (ScAlertInterface()) { SnortSnprintfAppend(event_string, sizeof(event_string), "<%s> ", PRINT_INTERFACE(DAQ_GetInterfaceSpec())); } if (protocol_names[GET_IPH_PROTO(p)] != NULL) { SnortSnprintfAppend(event_string, sizeof(event_string), "{%s} ", protocol_names[GET_IPH_PROTO(p)]); } else { SnortSnprintfAppend(event_string, sizeof(event_string), "{%d} ", GET_IPH_PROTO(p)); } if (p->frag_flag || ((GET_IPH_PROTO(p) != IPPROTO_TCP) && (GET_IPH_PROTO(p) != IPPROTO_UDP))) { char *ip_fmt = "%s -> %s"; if (ScObfuscate()) { SnortSnprintfAppend(event_string, sizeof(event_string), ip_fmt, ObfuscateIpToText(GET_SRC_ADDR(p)), ObfuscateIpToText(GET_DST_ADDR(p))); } else { SnortSnprintfAppend(event_string, sizeof(event_string), ip_fmt, inet_ntoax(GET_SRC_ADDR(p)), inet_ntoax(GET_DST_ADDR(p))); } } else { char *ip_fmt = "%s:%d -> %s:%d"; if (ScObfuscate()) { SnortSnprintfAppend(event_string, sizeof(event_string), ip_fmt, ObfuscateIpToText(GET_SRC_ADDR(p)), p->sp, ObfuscateIpToText(GET_DST_ADDR(p)), p->dp); } else { SnortSnprintfAppend(event_string, sizeof(event_string), ip_fmt, inet_ntoax(GET_SRC_ADDR(p)), p->sp, inet_ntoax(GET_DST_ADDR(p)), p->dp); } } syslog(data->priority, "%s", event_string); } else { syslog(data->priority, "%s", msg == NULL ? "ALERT!" : msg); } } static void AlertSyslogCleanExit(int signal, void *arg) { SyslogData *data = (SyslogData *)arg; DEBUG_WRAP(DebugMessage(DEBUG_LOG, "AlertSyslogCleanExit\n");); /* free memory from SyslogData */ if(data) free(data); } snort-2.9.15.1/src/output-plugins/spo_alert_syslog.h0000644000175200017520000000247413571422607017426 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ /* This file gets included in plugbase.h when it is integrated into the rest * of the program. Sometime in The Future, I'll whip up a bad ass Perl script * to handle automatically loading all the required info into the plugbase.* * files. */ #ifndef __SPO_SYSLOG_H__ #define __SPO_SYSLOG_H__ void AlertSyslogSetup(void); #endif /* __SPO_SYSLOG_H__ */ snort-2.9.15.1/src/output-plugins/spo_alert_unixsock.c0000644000175200017520000002156213571422607017743 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** Copyright (C) 2000,2001 Andrew R. Baker ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* spo_alert_unixsock * * Purpose: output plugin for Unix Socket alerting * * Arguments: none (yet) * * Effect: ??? * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #ifdef HAVE_STRINGS_H #include #endif #ifndef WIN32 #include #endif /* !WIN32 */ #include #include #include "sf_types.h" #include "event.h" #include "decode.h" #include "plugbase.h" #include "spo_plugbase.h" #include "parser.h" #include "snort_debug.h" #include "util.h" #include "snort.h" #include "spo_alert_unixsock.h" #define UNSOCK_FILE "snort_alert" /* * Win32 does not support Unix sockets (sockaddr_un). This file * will not be compiled on Win32 until a proper patch is supported. */ #ifndef WIN32 /* not used yet */ typedef struct _SpoAlertUnixSockData { char *filename; } SpoAlertUnixSockData; static int alertsd; #ifndef WIN32 static struct sockaddr_un alertaddr; #else static struct sockaddr_in alertaddr; #endif static void AlertUnixSockInit(struct _SnortConfig *, char *); static void AlertUnixSock(Packet *, const char *, void *, Event *); static void ParseAlertUnixSockArgs(char *); static void AlertUnixSockCleanExit(int, void *); static void OpenAlertSock(void); static void CloseAlertSock(void); /* * Function: SetupAlertUnixSock() * * 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. * * Arguments: None. * * Returns: void function * */ void AlertUnixSockSetup(void) { /* link the preprocessor keyword to the init function in the preproc list */ RegisterOutputPlugin("alert_unixsock", OUTPUT_TYPE_FLAG__ALERT, AlertUnixSockInit); DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Output plugin: AlertUnixSock is setup...\n");); } /* * Function: AlertUnixSockInit(char *) * * 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 * */ static void AlertUnixSockInit(struct _SnortConfig *sc, char *args) { DEBUG_WRAP(DebugMessage(DEBUG_INIT,"Output: AlertUnixSock Initialized\n");); /* parse the argument list from the rules file */ ParseAlertUnixSockArgs(args); DEBUG_WRAP(DebugMessage(DEBUG_INIT,"Linking UnixSockAlert functions to call lists...\n");); /* Set the preprocessor function into the function list */ AddFuncToOutputList(sc, AlertUnixSock, OUTPUT_TYPE__ALERT, NULL); AddFuncToCleanExitList(AlertUnixSockCleanExit, NULL); } /* * Function: ParseAlertUnixSockArgs(char *) * * Purpose: Process the preprocessor arguments from the rules file and * initialize the preprocessor's data struct. This function doesn't * have to exist if it makes sense to parse the args in the init * function. * * Arguments: args => argument list * * Returns: void function */ static void ParseAlertUnixSockArgs(char *args) { DEBUG_WRAP(DebugMessage(DEBUG_LOG,"ParseAlertUnixSockArgs: %s\n", args);); /* eventually we may support more than one socket */ OpenAlertSock(); } /**************************************************************************** * * Function: SpoUnixSockAlert(Packet *, char *) * * Arguments: p => pointer to the packet data struct * msg => the message to print in the alert * * Returns: void function * ***************************************************************************/ static void AlertUnixSock(Packet *p, const char *msg, void *arg, Event *event) { static Alertpkt alertpkt; DEBUG_WRAP(DebugMessage(DEBUG_LOG, "Logging Alert data!\n");); memset((char *)&alertpkt,0,sizeof(alertpkt)); if (event) { #if defined(FEAT_OPEN_APPID) memmove((void *)&alertpkt.event,(const void *)event,sizeof(Event) - offsetof(Event, app_name)); #else memmove((void *)&alertpkt.event,(const void *)event,sizeof(Event)); #endif /* defined(FEAT_OPEN_APPID) */ } if(p && p->pkt) { uint32_t snaplen = DAQ_GetSnapLen(); alertpkt.pkth.ts.tv_sec = (uint32_t)p->pkth->ts.tv_sec; alertpkt.pkth.ts.tv_usec = (uint32_t)p->pkth->ts.tv_usec; alertpkt.pkth.caplen = p->pkth->caplen; alertpkt.pkth.len = p->pkth->pktlen; memmove( alertpkt.pkt, (const void *)p->pkt, alertpkt.pkth.caplen > snaplen? snaplen : alertpkt.pkth.caplen); } else alertpkt.val|=NOPACKET_STRUCT; if (msg) { memmove( (void *)alertpkt.alertmsg, (const void *)msg, strlen(msg)>ALERTMSG_LENGTH-1 ? ALERTMSG_LENGTH - 1 : strlen(msg)); } /* some data which will help monitoring utility to dissect packet */ if(!(alertpkt.val & NOPACKET_STRUCT)) { if(p) { if (p->eh) { alertpkt.dlthdr=(char *)p->eh-(char *)p->pkt; } /* we don't log any headers besides eth yet */ if (IPH_IS_VALID(p) && p->pkt && IS_IP4(p)) { alertpkt.nethdr=(char *)p->iph-(char *)p->pkt; switch(GET_IPH_PROTO(p)) { case IPPROTO_TCP: if (p->tcph) { alertpkt.transhdr=(char *)p->tcph-(char *)p->pkt; } break; case IPPROTO_UDP: if (p->udph) { alertpkt.transhdr=(char *)p->udph-(char *)p->pkt; } break; case IPPROTO_ICMP: if (p->icmph) { alertpkt.transhdr=(char *)p->icmph-(char *)p->pkt; } break; default: /* alertpkt.transhdr is null due to initial memset */ alertpkt.val|=NO_TRANSHDR; break; } } if (p->data && p->pkt) alertpkt.data=p->data - p->pkt; } } if(sendto(alertsd,(const void *)&alertpkt,sizeof(Alertpkt), 0,(struct sockaddr *)&alertaddr,sizeof(alertaddr))==-1) { /* whatever we do to sign that some alerts could be missed */ } } /* * Function: OpenAlertSock * * Purpose: Connect to UNIX socket for alert logging.. * * Arguments: none.. * * Returns: void function */ static void OpenAlertSock(void) { char srv[STD_BUF]; #ifdef FREEBSD int buflen=sizeof(Alertpkt); #endif /* srv is our filename workspace. Set it to file UNSOCK_FILE inside the log directory. */ SnortSnprintf(srv, STD_BUF, "%s%s/%s", snort_conf->chroot_dir == NULL ? "" : snort_conf->chroot_dir, snort_conf->log_dir, UNSOCK_FILE); if(access(srv, W_OK)) { ErrorMessage("%s file doesn't exist or isn't writable!\n", srv); } memset((char *) &alertaddr, 0, sizeof(alertaddr)); /* copy path over and preserve a null byte at the end */ strncpy(alertaddr.sun_path, srv, sizeof(alertaddr.sun_path)-1); alertaddr.sun_family = AF_UNIX; if((alertsd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) { FatalError("socket() call failed: %s", strerror(errno)); } #ifdef FREEBSD if(setsockopt(alertsd, SOL_SOCKET, SO_SNDBUF, (char*)&buflen, sizeof(int)) < 0) { FatalError("setsockopt() call failed: %s", strerror(errno)); } #endif } static void AlertUnixSockCleanExit(int signal, void *arg) { DEBUG_WRAP(DebugMessage(DEBUG_LOG,"AlertUnixSockCleanExitFunc\n");); CloseAlertSock(); } static void CloseAlertSock(void) { if(alertsd >= 0) { close(alertsd); } } #endif /* !WIN32 */ snort-2.9.15.1/src/output-plugins/spo_alert_unixsock.h0000644000175200017520000000430613571422607017745 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** Copyright (C) 2000,2001 Andrew R. Baker ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* This file gets included in plugbase.h when it is integrated into the rest * of the program. Sometime in The Future, I'll whip up a bad ass Perl script * to handle automatically loading all the required info into the plugbase.* * files. */ #ifndef __SPO_ALERT_UNIXSOCK_H__ #define __SPO_ALERT_UNIXSOCK_H__ #include #include "event.h" #include "pcap_pkthdr32.h" /* this struct is for the alert socket code.... */ // FIXTHIS alert unix sock supports l2-l3-l4 encapsulations typedef struct _Alertpkt { uint8_t alertmsg[ALERTMSG_LENGTH]; /* variable.. */ struct pcap_pkthdr32 pkth; uint32_t dlthdr; /* datalink header offset. (ethernet, etc.. ) */ uint32_t nethdr; /* network header offset. (ip etc...) */ uint32_t transhdr; /* transport header offset (tcp/udp/icmp ..) */ uint32_t data; uint32_t val; /* which fields are valid. (NULL could be * valids also) */ /* Packet struct --> was null */ #define NOPACKET_STRUCT 0x1 /* no transport headers in packet */ #define NO_TRANSHDR 0x2 uint8_t pkt[65535]; Event event; } Alertpkt; void AlertUnixSockSetup(void); #endif /* __SPO_ALERT_UNIXSOCK_H__ */ snort-2.9.15.1/src/output-plugins/spo_csv.c0000644000175200017520000003512313571422607015502 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** Copyright (C) 2001 Brian Caswell ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ /* spo_csv * * Purpose: output plugin for csv alerting * * Arguments: alert file (eventually) * * Effect: * * Alerts are written to a file in the snort csv alert format * * Comments: Allows use of csv alerts with other output plugin types * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifndef WIN32 #include #include #include #endif /* !WIN32 */ #ifdef HAVE_STRINGS_H #include #endif #include "spo_csv.h" #include "event.h" #include "decode.h" #include "plugbase.h" #include "spo_plugbase.h" #include "parser.h" #include "snort_debug.h" #include "mstring.h" #include "util.h" #include "log.h" #include "snort.h" #include "sfutil/sf_textlog.h" #include "log_text.h" #define DEFAULT_CSV "timestamp,sig_generator,sig_id,sig_rev,msg,proto,src,srcport,dst,dstport,ethsrc,ethdst,ethlen,tcpflags,tcpseq,tcpack,tcpln,tcpwindow,ttl,tos,id,dgmlen,iplen,icmptype,icmpcode,icmpid,icmpseq" #define DEFAULT_FILE "alert.csv" #define DEFAULT_LIMIT (128*M_BYTES) #define LOG_BUFFER (4*K_BYTES) typedef struct _AlertCSVConfig { char *type; struct _AlertCSVConfig *next; } AlertCSVConfig; typedef struct _AlertCSVData { TextLog* log; char * csvargs; char ** args; int numargs; AlertCSVConfig *config; } AlertCSVData; /* list of function prototypes for this preprocessor */ static void AlertCSVInit(struct _SnortConfig *, char *); static AlertCSVData *AlertCSVParseArgs(struct _SnortConfig *, char *); static void AlertCSV(Packet *, const char *, void *, Event *); static void AlertCSVCleanExit(int, void *); static void RealAlertCSV( Packet*, const char* msg, char **args, int numargs, Event*, TextLog* ); /* * Function: SetupCSV() * * 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. * * Arguments: None. * * Returns: void function * */ void AlertCSVSetup(void) { /* link the preprocessor keyword to the init function in the preproc list */ RegisterOutputPlugin("alert_CSV", OUTPUT_TYPE_FLAG__ALERT, AlertCSVInit); DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Output plugin: alert_CSV is setup...\n");); } /* * Function: CSVInit(char *) * * 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 * */ static void AlertCSVInit(struct _SnortConfig *sc, char *args) { AlertCSVData *data; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Output: CSV Initialized\n");); /* parse the argument list from the rules file */ data = AlertCSVParseArgs(sc, args); DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Linking CSV functions to call lists...\n");); /* Set the preprocessor function into the function list */ AddFuncToOutputList(sc, AlertCSV, OUTPUT_TYPE__ALERT, data); AddFuncToCleanExitList(AlertCSVCleanExit, data); } /* * Function: ParseCSVArgs(char *) * * Purpose: Process positional args, if any. Syntax is: * output alert_csv: [ ["default"| []]] * list ::= (,)* * field ::= "dst"|"src"|"ttl" ... * limit ::= ('G'|'M'|K') * * Arguments: args => argument list * * Returns: void function */ static AlertCSVData *AlertCSVParseArgs(struct _SnortConfig *sc, char *args) { char **toks; int num_toks; AlertCSVData *data; char* filename = NULL; unsigned long limit = DEFAULT_LIMIT; int i; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "ParseCSVArgs: %s\n", args);); data = (AlertCSVData *)SnortAlloc(sizeof(AlertCSVData)); if ( !args ) args = ""; toks = mSplit((char *)args, " \t", 4, &num_toks, '\\'); for (i = 0; i < num_toks; i++) { const char* tok = toks[i]; char *end; switch (i) { case 0: if ( !strcasecmp(tok, "stdout") ) filename = SnortStrdup(tok); else filename = ProcessFileOption(sc, tok); break; case 1: if ( !strcasecmp("default", tok) ) data->csvargs = SnortStrdup(DEFAULT_CSV); else data->csvargs = SnortStrdup(toks[i]); break; case 2: limit = strtol(tok, &end, 10); if ( tok == end ) FatalError("alert_csv error in %s(%i): %s\n", file_name, file_line, tok); if ( end && toupper(*end) == 'G' ) limit <<= 30; /* GB */ else if ( end && toupper(*end) == 'M' ) limit <<= 20; /* MB */ else if ( end && toupper(*end) == 'K' ) limit <<= 10; /* KB */ break; case 3: FatalError("alert_csv: error in %s(%i): %s\n", file_name, file_line, tok); break; } } if ( !data->csvargs ) data->csvargs = SnortStrdup(DEFAULT_CSV); if ( !filename ) filename = ProcessFileOption(sc, DEFAULT_FILE); mSplitFree(&toks, num_toks); toks = mSplit(data->csvargs, ",", 0, &num_toks, 0); data->args = toks; data->numargs = num_toks; DEBUG_WRAP(DebugMessage( DEBUG_INIT, "alert_csv: '%s' '%s' %ld\n", filename, data->csvargs, limit );); data->log = TextLog_Init(filename, LOG_BUFFER, limit); if ( filename ) free(filename); return data; } static void AlertCSVCleanup(int signal, void *arg, const char* msg) { AlertCSVData *data = (AlertCSVData *)arg; /* close alert file */ DEBUG_WRAP(DebugMessage(DEBUG_LOG,"%s\n", msg);); if(data) { mSplitFree(&data->args, data->numargs); if (data->log) TextLog_Term(data->log); free(data->csvargs); /* free memory from SpoCSVData */ free(data); } } static void AlertCSVCleanExit(int signal, void *arg) { AlertCSVCleanup(signal, arg, "AlertCSVCleanExit"); } static void AlertCSV(Packet *p, const char *msg, void *arg, Event *event) { AlertCSVData *data = (AlertCSVData *)arg; RealAlertCSV(p, msg, data->args, data->numargs, event, data->log); } /* * * Function: RealAlertCSV(Packet *, char *, FILE *, char *, numargs const int) * * Purpose: Write a user defined CSV message * * Arguments: p => packet. (could be NULL) * msg => the message to send * args => CSV output arguments * numargs => number of arguments * log => Log * Returns: void function * */ static void RealAlertCSV(Packet * p, const char *msg, char **args, int numargs, Event *event, TextLog* log) { int num; char *type; char tcpFlags[9]; if(p == NULL) return; DEBUG_WRAP(DebugMessage(DEBUG_LOG,"Logging CSV Alert data\n");); for (num = 0; num < numargs; num++) { type = args[num]; DEBUG_WRAP(DebugMessage(DEBUG_LOG, "CSV Got type %s %d\n", type, num);); if (!strcasecmp("timestamp", type)) { LogTimeStamp(log, p); } else if (!strcasecmp("sig_generator", type)) { if (event != NULL) TextLog_Print(log, "%lu", (unsigned long) event->sig_generator); } else if (!strcasecmp("sig_id", type)) { if (event != NULL) TextLog_Print(log, "%lu", (unsigned long) event->sig_id); } else if (!strcasecmp("sig_rev", type)) { if (event != NULL) TextLog_Print(log, "%lu", (unsigned long) event->sig_rev); } else if (!strcasecmp("msg", type)) { TextLog_Quote(log, msg); /* Don't fatal */ } else if (!strcasecmp("proto", type)) { if (IPH_IS_VALID(p)) { switch (GET_IPH_PROTO(p)) { case IPPROTO_UDP: TextLog_Puts(log, "UDP"); break; case IPPROTO_TCP: TextLog_Puts(log, "TCP"); break; case IPPROTO_ICMP: TextLog_Puts(log, "ICMP"); break; default: break; } } } else if (!strcasecmp("ethsrc", type)) { if (p->eh != NULL) { TextLog_Print(log, "%02X:%02X:%02X:%02X:%02X:%02X", p->eh->ether_src[0], p->eh->ether_src[1], p->eh->ether_src[2], p->eh->ether_src[3], p->eh->ether_src[4], p->eh->ether_src[5]); } } else if (!strcasecmp("ethdst", type)) { if (p->eh != NULL) { TextLog_Print(log, "%02X:%02X:%02X:%02X:%02X:%02X", p->eh->ether_dst[0], p->eh->ether_dst[1], p->eh->ether_dst[2], p->eh->ether_dst[3], p->eh->ether_dst[4], p->eh->ether_dst[5]); } } else if (!strcasecmp("ethtype", type)) { if (p->eh != NULL) TextLog_Print(log, "0x%X", ntohs(p->eh->ether_type)); } else if (!strcasecmp("udplength", type)) { if (p->udph != NULL) TextLog_Print(log, "%d", ntohs(p->udph->uh_len)); } else if (!strcasecmp("ethlen", type)) { if (p->eh != NULL) TextLog_Print(log, "0x%X", p->pkth->pktlen); } #ifndef NO_NON_ETHER_DECODER else if (!strcasecmp("trheader", type)) { if (p->trh != NULL) LogTrHeader(log, p); } #endif else if (!strcasecmp("srcport", type)) { if (IPH_IS_VALID(p)) { switch (GET_IPH_PROTO(p)) { case IPPROTO_UDP: case IPPROTO_TCP: TextLog_Print(log, "%d", p->sp); break; default: break; } } } else if (!strcasecmp("dstport", type)) { if (IPH_IS_VALID(p)) { switch (GET_IPH_PROTO(p)) { case IPPROTO_UDP: case IPPROTO_TCP: TextLog_Print(log, "%d", p->dp); break; default: break; } } } else if (!strcasecmp("src", type)) { if (IPH_IS_VALID(p)) TextLog_Puts(log, inet_ntoa(GET_SRC_ADDR(p))); } else if (!strcasecmp("dst", type)) { if (IPH_IS_VALID(p)) TextLog_Puts(log, inet_ntoa(GET_DST_ADDR(p))); } else if (!strcasecmp("icmptype", type)) { if (p->icmph != NULL) TextLog_Print(log, "%d", p->icmph->type); } else if (!strcasecmp("icmpcode", type)) { if (p->icmph != NULL) TextLog_Print(log, "%d", p->icmph->code); } else if (!strcasecmp("icmpid", type)) { if (p->icmph != NULL) TextLog_Print(log, "%d", ntohs(p->icmph->s_icmp_id)); } else if (!strcasecmp("icmpseq", type)) { if (p->icmph != NULL) TextLog_Print(log, "%d", ntohs(p->icmph->s_icmp_seq)); } else if (!strcasecmp("ttl", type)) { if (IPH_IS_VALID(p)) TextLog_Print(log, "%d", GET_IPH_TTL(p)); } else if (!strcasecmp("tos", type)) { if (IPH_IS_VALID(p)) TextLog_Print(log, "%d", GET_IPH_TOS(p)); } else if (!strcasecmp("id", type)) { if (IPH_IS_VALID(p)) { TextLog_Print(log, "%u", IS_IP6(p) ? ntohl(GET_IPH_ID(p)) : ntohs((uint16_t)GET_IPH_ID(p))); } } else if (!strcasecmp("iplen", type)) { if (IPH_IS_VALID(p)) TextLog_Print(log, "%d", GET_IPH_LEN(p) << 2); } else if (!strcasecmp("dgmlen", type)) { if (IPH_IS_VALID(p)) { // XXX might cause a bug when IPv6 is printed? TextLog_Print(log, "%d", ntohs(GET_IPH_LEN(p))); } } else if (!strcasecmp("tcpseq", type)) { if (p->tcph != NULL) TextLog_Print(log, "0x%lX", (u_long)ntohl(p->tcph->th_seq)); } else if (!strcasecmp("tcpack", type)) { if (p->tcph != NULL) TextLog_Print(log, "0x%lX", (u_long)ntohl(p->tcph->th_ack)); } else if (!strcasecmp("tcplen", type)) { if (p->tcph != NULL) TextLog_Print(log, "%d", TCP_OFFSET(p->tcph) << 2); } else if (!strcasecmp("tcpwindow", type)) { if (p->tcph != NULL) TextLog_Print(log, "0x%X", ntohs(p->tcph->th_win)); } else if (!strcasecmp("tcpflags",type)) { if (p->tcph != NULL) { CreateTCPFlagString(p, tcpFlags); TextLog_Print(log, "%s", tcpFlags); } } if (num < numargs - 1) TextLog_Putc(log, ','); } TextLog_NewLine(log); TextLog_Flush(log); } snort-2.9.15.1/src/output-plugins/spo_csv.h0000644000175200017520000000254413571422607015510 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** Copyright (C) 2001 Brian Caswell ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ /* This file gets included in plugbase.h when it is integrated into the rest * of the program. Sometime in The Future, I'll whip up a bad ass Perl script * to handle automatically loading all the required info into the plugbase.* * files. */ #ifndef __SPO_CSV_H__ #define __SPO_CSV_H__ void AlertCSVSetup(void); #endif /* __SPO_CSV_H__ */ snort-2.9.15.1/src/output-plugins/spo_log_null.c0000644000175200017520000000477313571422607016531 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ /* spo_log_null * * Purpose: * * This module is a NULL placeholder for people that want to turn off * logging for whatever reason. Please note that logging is separate from * alerting, they are completely separate output facilities within Snort. * * Arguments: * * None. * * Effect: * * None. * * Comments: * */ #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "spo_log_null.h" #include "decode.h" #include "event.h" #include "plugbase.h" #include "spo_plugbase.h" #include "parser.h" #include "snort_debug.h" #include "snort.h" /* list of function prototypes for this output plugin */ static void LogNullInit(struct _SnortConfig *, char *); static void LogNull(Packet *, const char *, void *, Event *); static void LogNullCleanExitFunc(int, void *); void LogNullSetup(void) { /* link the preprocessor keyword to the init function in the preproc list */ RegisterOutputPlugin("log_null", OUTPUT_TYPE_FLAG__LOG, LogNullInit); DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Output plugin: LogNull is setup...\n");); } static void LogNullInit(struct _SnortConfig *sc, char *args) { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Output: LogNull Initialized\n");); /* Set the preprocessor function into the function list */ AddFuncToOutputList(sc, LogNull, OUTPUT_TYPE__LOG, NULL); AddFuncToCleanExitList(LogNullCleanExitFunc, NULL); } static void LogNull(Packet *p, const char *msg, void *arg, Event *event) { return; } static void LogNullCleanExitFunc(int signal, void *arg) { return; } snort-2.9.15.1/src/output-plugins/spo_log_null.h0000644000175200017520000000210613571422607016522 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifndef __SPO_LOG_NULL_H__ #define __SPO_LOG_NULL_H__ void LogNullSetup(void); #endif /* __SPO_LOG_NULL_H__ */ snort-2.9.15.1/src/output-plugins/spo_log_tcpdump.c0000644000175200017520000003264713571422607017234 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ /* spo_log_tcpdump * * Purpose: * * This plugin generates tcpdump formatted binary log files * * Arguments: * * filename of the output log (default: snort.log) * * Effect: * * Packet logs are written (quickly) to a tcpdump formatted output * file * * Comments: * * First logger... * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_STRINGS_H #include #endif #include #include #include #include #include #include #include #include #include "spo_log_tcpdump.h" #include "decode.h" #include "event.h" #include "mstring.h" #include "plugbase.h" #include "spo_plugbase.h" #include "parser.h" #include "snort_debug.h" #include "util.h" #include "snort.h" #include "sfbpf_dlt.h" /* For the traversal of reassembled packets */ #include "stream_api.h" #define M_BYTES (1024*1024) #define DEFAULT_FILE "snort.log" #define DEFAULT_LIMIT (128*M_BYTES) /* * ::= [ ]* * on 64 bit systems, some fields in the are 8 bytes * but still stored on disk as 4 bytes. * eg: (sizeof(*pkth) = 24) > (dumped size = 16) * so we use PCAP_*_HDR_SZ defines in lieu of sizeof(). */ #define PCAP_FILE_HDR_SZ (24) #define PCAP_PKT_HDR_SZ (16) typedef struct _LogTcpdumpData { char *filename; pcap_dumper_t *dumpd; time_t lastTime; size_t size; size_t limit; char logdir[STD_BUF]; } LogTcpdumpData; /* list of function prototypes for this preprocessor */ static void LogTcpdumpInit(struct _SnortConfig *, char *); static LogTcpdumpData *ParseTcpdumpArgs(char *); static void LogTcpdump(Packet *, const char *, void *, Event *); static void TcpdumpInitLogFileFinalize(struct _SnortConfig *sc, int unused, void *arg); static void TcpdumpInitLogFile(LogTcpdumpData *, int); static void TcpdumpRollLogFile(LogTcpdumpData*); static void SpoLogTcpdumpCleanExitFunc(int, void *); static void LogTcpdumpSingle(Packet *, const char *, void *, Event *); static void LogTcpdumpStream(Packet *, const char *, void *, Event *); //static void DirectLogTcpdump(DAQ_PktHdr_t *, uint8_t *); /* If you need to instantiate the plugin's data structure, do it here */ static LogTcpdumpData *log_tcpdump_ptr; /* * Function: SetupLogTcpdump() * * 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. * * Arguments: None. * * Returns: void function * */ void LogTcpdumpSetup(void) { /* link the preprocessor keyword to the init function in the preproc list */ RegisterOutputPlugin("log_tcpdump", OUTPUT_TYPE_FLAG__LOG, LogTcpdumpInit); DEBUG_WRAP(DebugMessage(DEBUG_INIT,"Output plugin: Log-Tcpdump is setup...\n");); } /* * Function: LogTcpdumpInit(char *) * * 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 * */ static void LogTcpdumpInit(struct _SnortConfig *sc, char *args) { LogTcpdumpData *data; DEBUG_WRAP(DebugMessage(DEBUG_INIT,"Output: Log-Tcpdump Initialized\n");); /* parse the argument list from the rules file */ data = ParseTcpdumpArgs(args); log_tcpdump_ptr = data; //TcpdumpInitLogFile(data); AddFuncToPostConfigList(sc, TcpdumpInitLogFileFinalize, data); snort_conf->log_tcpdump = 1; /* Set the preprocessor function into the function list */ AddFuncToOutputList(sc, LogTcpdump, OUTPUT_TYPE__LOG, data); AddFuncToCleanExitList(SpoLogTcpdumpCleanExitFunc, data); } /* * Function: ParseTcpdumpArgs(char *) * * Purpose: Process positional args, if any. Syntax is: * output log_tcpdump: [ []] * limit ::= ('G'|'M'|K') * * Arguments: args => argument list * * Returns: void function */ static LogTcpdumpData *ParseTcpdumpArgs(char *args) { char **toks; int num_toks; LogTcpdumpData *data; int i; DEBUG_WRAP(DebugMessage(DEBUG_LOG, "ParseTcpdumpArgs: %s\n", args);); data = (LogTcpdumpData *) SnortAlloc(sizeof(LogTcpdumpData)); if ( !data ) { FatalError("log_tcpdump: unable to allocate memory!\n"); } data->filename = NULL; data->limit = DEFAULT_LIMIT; if ( !args ) args = ""; toks = mSplit((char*)args, " \t", 0, &num_toks, '\\'); for (i = 0; i < num_toks; i++) { const char* tok = toks[i]; char *end; switch (i) { case 0: data->filename = SnortStrdup(tok); break; case 1: data->limit = strtol(tok, &end, 10); if ( tok == end ) FatalError("log_tcpdump error in %s(%i): %s\n", file_name, file_line, tok); if ( end && toupper(*end) == 'G' ) data->limit <<= 30; /* GB */ else if ( end && toupper(*end) == 'M' ) data->limit <<= 20; /* MB */ else if ( end && toupper(*end) == 'K' ) data->limit <<= 10; /* KB */ break; case 2: FatalError("log_tcpdump: error in %s(%i): %s\n", file_name, file_line, tok); break; } } mSplitFree(&toks, num_toks); if ( !data->filename ) data->filename = SnortStrdup(DEFAULT_FILE); if (ScPcapLogFile() != NULL) { free(data->filename); data->filename = SnortStrdup(ScPcapLogFile()); } DEBUG_WRAP(DebugMessage( DEBUG_INIT, "log_tcpdump: '%s' %ld\n", data->filename, data->limit );); return data; } /* * Function: PreprocFunction(Packet *) * * Purpose: Perform the preprocessor's intended function. This can be * simple (statistics collection) or complex (IP defragmentation) * as you like. Try not to destroy the performance of the whole * system by trying to do too much.... * * Arguments: p => pointer to the current packet data struct * * Returns: void function */ static void LogTcpdump(Packet *p, const char *msg, void *arg, Event *event) { if(p) { if(p->packet_flags & PKT_REBUILT_STREAM) { LogTcpdumpStream(p, msg, arg, event); } else { LogTcpdumpSingle(p, msg, arg, event); } } } static inline size_t SizeOf (const DAQ_PktHdr_t *pkth) { return PCAP_PKT_HDR_SZ + pkth->caplen; } static int SizeOfCallback(DAQ_PktHdr_t *pkth, uint8_t *packet_data, void *userdata) { size_t* pSize = (size_t*)userdata; (*pSize) += SizeOf(pkth); return 0; } static void LogTcpdumpSingle(Packet *p, const char *msg, void *arg, Event *event) { LogTcpdumpData *data = (LogTcpdumpData *)arg; size_t dumpSize = SizeOf(p->pkth); if ( data->size + dumpSize > data->limit ) TcpdumpRollLogFile(data); pcap_dump((u_char *)data->dumpd,(struct pcap_pkthdr*)p->pkth,p->pkt); data->size += dumpSize; if (!ScLineBufferedLogging()) { #ifdef WIN32 fflush( NULL ); /* flush all open output streams */ #else /* we happen to know that pcap_dumper_t* is really just a FILE* */ fflush( (FILE*) data->dumpd ); #endif } } static int LogTcpdumpStreamCallback(DAQ_PktHdr_t *pkth, uint8_t *packet_data, void *userdata) { LogTcpdumpData *data = (LogTcpdumpData *)userdata; pcap_dump((u_char*)data->dumpd, (struct pcap_pkthdr*)pkth, (u_char*)packet_data); return 0; } static void LogTcpdumpStream(Packet *p, const char *msg, void *arg, Event *event) { LogTcpdumpData *data = (LogTcpdumpData *)arg; size_t dumpSize = 0; if (stream_api) stream_api->traverse_reassembled(p, SizeOfCallback, &dumpSize); if ( data->size + dumpSize > data->limit ) TcpdumpRollLogFile(data); if (stream_api) stream_api->traverse_reassembled(p, LogTcpdumpStreamCallback, data); data->size += dumpSize; if (!ScLineBufferedLogging()) { #ifdef WIN32 fflush( NULL ); /* flush all open output streams */ #else /* we happen to know that pcap_dumper_t* is really just a FILE* */ fflush( (FILE*) data->dumpd ); #endif } } static void TcpdumpInitLogFileFinalize(struct _SnortConfig *sc, int unused, void *arg) { TcpdumpInitLogFile((LogTcpdumpData *)arg, ScNoOutputTimestampNewConf(sc)); } /* * Function: TcpdumpInitLogFile() * * Purpose: Initialize the tcpdump log file header * * Arguments: data => pointer to the plugin's reference data struct * * Returns: void function */ static void TcpdumpInitLogFile(LogTcpdumpData *data, int nostamps) { int value; data->lastTime = time(NULL); if (nostamps) { if(data->filename[0] == '/') value = SnortSnprintf(data->logdir, STD_BUF, "%s", data->filename); else value = SnortSnprintf(data->logdir, STD_BUF, "%s/%s", snort_conf->log_dir, data->filename); } else { if(data->filename[0] == '/') value = SnortSnprintf(data->logdir, STD_BUF, "%s.%u", data->filename, (uint32_t)data->lastTime); else value = SnortSnprintf(data->logdir, STD_BUF, "%s/%s.%u", snort_conf->log_dir, data->filename, (uint32_t)data->lastTime); } if(value != SNORT_SNPRINTF_SUCCESS) FatalError("log file logging path and file name are too long\n"); DEBUG_WRAP(DebugMessage(DEBUG_LOG, "Opening %s\n", data->logdir);); if (!ScTestMode()) { pcap_t* pcap; int dlt = DAQ_GetBaseProtocol(); // convert these flavors of raw to the generic // for compatibility with libpcap 1.0.0 if ( dlt == DLT_IPV4 || dlt == DLT_IPV6 ) dlt = DLT_RAW; pcap = pcap_open_dead(dlt, DAQ_GetSnapLen()); data->dumpd = pcap ? pcap_dump_open(pcap, data->logdir) : NULL; if(data->dumpd == NULL) { FatalError("log_tcpdump: Failed to open log file \"%s\": %s\n", data->logdir, strerror(errno)); } pcap_close(pcap); } data->size = PCAP_FILE_HDR_SZ; } static void TcpdumpRollLogFile(LogTcpdumpData* data) { time_t now = time(NULL); /* don't roll over any sooner than resolution * of filename discriminator */ if ( now <= data->lastTime ) return; /* close the output file */ if( data->dumpd != NULL ) { pcap_dump_close(data->dumpd); data->dumpd = NULL; data->size = 0; } /* Have to add stamps now to distinguish files */ TcpdumpInitLogFile(data, 0); } /* * Function: SpoLogTcpdumpCleanExitFunc() * * Purpose: Cleanup at exit time * * Arguments: signal => signal that caused this event * arg => data ptr to reference this plugin's data * * Returns: void function */ static void SpoLogTcpdumpCleanup(int signal, void *arg, const char* msg) { /* cast the arg pointer to the proper type */ LogTcpdumpData *data = (LogTcpdumpData *) arg; DEBUG_WRAP(DebugMessage(DEBUG_LOG,"%s\n", msg);); /* close the output file */ if( data->dumpd != NULL ) { pcap_dump_close(data->dumpd); data->dumpd = NULL; } /* * if we haven't written any data, dump the output file so there aren't * fragments all over the disk */ if(!ScTestMode() && *data->logdir && !pc.log_pkts && !pc.total_alert_pkts) { int ret; ret = unlink(data->logdir); if (ret != 0) { ErrorMessage("Could not remove tcpdump output file %s: %s\n", data->logdir, strerror(errno)); } } if (data->filename) { free (data->filename); } memset(data, 0, sizeof(LogTcpdumpData)); free(data); } static void SpoLogTcpdumpCleanExitFunc(int signal, void *arg) { SpoLogTcpdumpCleanup(signal, arg, "SpoLogTcpdumpCleanExitFunc"); } void LogTcpdumpReset(void) { TcpdumpRollLogFile(log_tcpdump_ptr); } #if 0 /* Not currently used */ void DirectLogTcpdump(DAQ_PktHdr_t *ph, uint8_t *pkt) { size_t dumpSize = SizeOf(ph); if ( log_tcpdump_ptr->size + dumpSize > log_tcpdump_ptr->limit ) TcpdumpRollLogFile(log_tcpdump_ptr); pc.log_pkts++; pcap_dump((u_char *)log_tcpdump_ptr->dumpd, ph, pkt); log_tcpdump_ptr->size += dumpSize; } #endif snort-2.9.15.1/src/output-plugins/spo_log_tcpdump.h0000644000175200017520000000254113571422607017227 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ /* This file gets included in plugbase.h when it is integrated into the rest * of the program. Sometime in The Future, I'll whip up a bad ass Perl script * to handle automatically loading all the required info into the plugbase.* * files. */ #ifndef __SPO_LOG_TCPDUMP_H__ #define __SPO_LOG_TCPDUMP_H__ void LogTcpdumpSetup(void); void LogTcpdumpReset(void); #endif /* __SPO_SYSLOG_H__ */ snort-2.9.15.1/src/output-plugins/spo_unified2.c0000644000175200017520000015464413571422607016426 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2007-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* spo_unified2.c * Adam Keeton * * 09/26/06 * This file is litterally spo_unified.c converted to write unified2 * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifdef HAVE_STRINGS_H #include #endif #include #include #include "sfutil/Unified2_common.h" #include "spo_unified2.h" #include "decode.h" #include "rules.h" #include "treenodes.h" #include "util.h" #include "plugbase.h" #include "spo_plugbase.h" #include "parser.h" #include "snort_debug.h" #include "mstring.h" #include "event.h" #include "generators.h" #include "snort_debug.h" #include "snort_bounds.h" #include "obfuscation.h" #include "active.h" #include "detection_util.h" #include "detect.h" #include "snort.h" #include "pcap_pkthdr32.h" /* For the traversal of reassembled packets */ #include "stream_api.h" #include "snort_httpinspect.h" /* ------------------ Data structures --------------------------*/ typedef struct _Unified2Config { char *base_filename; char filepath[STD_BUF]; uint32_t timestamp; FILE *stream; unsigned int limit; unsigned int current; int nostamp; #ifdef MPLS int mpls_event_types; #endif int vlan_event_types; int base_proto; #if defined(FEAT_OPEN_APPID) int appid_event_types; #endif /* defined(FEAT_OPEN_APPID) */ } Unified2Config; typedef struct _Unified2LogCallbackData { Serial_Unified2Packet *logheader; Unified2Config *config; Event *event; uint32_t num_bytes; } Unified2LogCallbackData; Unified2Config *log_config = NULL; Unified2Config *alert_config = NULL; /* ----------------External variables -------------------- */ /* From fpdetect.c, for logging reassembled packets */ extern OptTreeNode *otn_tmp; /* -------------------- Global Variables ----------------------*/ /* Used for buffering header and payload of unified records so only one * write is necessary. Serial_Unified2IDSEventIPv6_legacy is used as Serial_Unified2IDSEvent_legacy size * since it is the largest */ static uint8_t write_pkt_buffer[sizeof(Serial_Unified2_Header) + sizeof(Serial_Unified2IDSEventIPv6_legacy) + IP_MAXPACKET]; #define write_pkt_end (write_pkt_buffer + sizeof(write_pkt_buffer)) static uint8_t write_pkt_buffer_v2[sizeof(Serial_Unified2_Header) + sizeof(Unified2IDSEventIPv6) + IP_MAXPACKET]; #define write_pkt_end_v2 (write_pkt_buffer_v2 + sizeof(write_pkt_buffer_v2)) #define MAX_XDATA_WRITE_BUF_LEN (MAX_XFF_WRITE_BUF_LENGTH - \ sizeof(struct in6_addr) + DECODE_BLEN) /* This is the buffer to use for I/O. Try to make big enough so the system * doesn't potentially flush in the middle of a record. Every write is * force flushed to disk immediately after the entire record is written so * spoolers get an entire record */ #define UNIFIED2_SETVBUF #ifndef WIN32 /* use the size of the buffer we copy record data into */ static char io_buffer[sizeof(write_pkt_buffer_v2)]; #else # ifdef _MSC_VER # if _MSC_VER <= 1200 /* use maximum size defined by VC++ 6.0 */ static char io_buffer[32768]; # else static char io_buffer[sizeof(write_pkt_buffer_v2)]; # endif /* _MSC_VER <= 1200 */ # else /* no _MSC_VER, don't set I/O buffer */ # undef UNIFIED2_SETVBUF # endif /* _MSC_VER */ #endif /* WIN32 */ /* -------------------- Local Functions -----------------------*/ static Unified2Config * Unified2ParseArgs(char *, char *); static void Unified2CleanExit(int, void *); #ifdef SNORT_RELOAD static void Unified2Reload(struct _SnortConfig *, int, void *); #endif /* Unified2 Output functions */ static void Unified2Init(struct _SnortConfig *, char *); static void Unified2PostConfig(struct _SnortConfig *, int, void *); static void Unified2InitFile(Unified2Config *); static inline void Unified2RotateFile(Unified2Config *); static void Unified2LogAlert(Packet *, const char *, void *, Event *); static void _AlertIP4(Packet *, const char *, Unified2Config *, Event *); static void _AlertIP6(Packet *, const char *, Unified2Config *, Event *); static void Unified2LogPacketAlert(Packet *, const char *, void *, Event *); static void _Unified2LogPacketAlert(Packet *, const char *, Unified2Config *, Event *); static void _Unified2LogStreamAlert(Packet *, const char *, Unified2Config *, Event *); static int Unified2LogStreamCallback(DAQ_PktHdr_t *, uint8_t *, void *); static void Unified2Write(uint8_t *, uint32_t, Unified2Config *); static void _AlertIP4_v2(Packet *, const char *, Unified2Config *, Event *); static void _AlertIP6_v2(Packet *, const char *, Unified2Config *, Event *); /* Unified2 Alert functions (deprecated) */ static void Unified2AlertInit(struct _SnortConfig *, char *); /* Unified2 Packet Log functions (deprecated) */ static void Unified2LogInit(struct _SnortConfig *, char *); static ObRet Unified2LogObfuscationCallback(const DAQ_PktHdr_t *pkth, const uint8_t *packet_data, ob_size_t length, ob_char_t ob_char, void *userdata); static void AlertExtraData(void *ssnptr, void *data, LogFunction *log_funcs, uint32_t max_count, uint32_t xtradata_mask, uint32_t event_id, uint32_t event_second); #define U2_PACKET_FLAG 1 /* Obsolete flag as UI wont check the impact_flag field anymore.*/ #define U2_FLAG_BLOCKED 0x20 /* New flags to set the pad field (corresponds to blocked column in UI) with packet action*/ #define U2_BLOCKED_FLAG_ALLOW 0x00 #define U2_BLOCKED_FLAG_BLOCK 0x01 #define U2_BLOCKED_FLAG_WOULD 0x02 #define U2_BLOCKED_FLAG_CANT 0x03 /* * Function: SetupUnified2() * * 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. * * Arguments: None. * * Returns: void function * */ void Unified2Setup(void) { /* link the preprocessor keyword to the init function in the preproc list */ RegisterOutputPlugin("log_unified2", OUTPUT_TYPE_FLAG__LOG, Unified2LogInit); RegisterOutputPlugin("alert_unified2", OUTPUT_TYPE_FLAG__ALERT, Unified2AlertInit); RegisterOutputPlugin("unified2", OUTPUT_TYPE_FLAG__LOG | OUTPUT_TYPE_FLAG__ALERT, Unified2Init); DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Output plugin: Unified2 " "logging/alerting is setup...\n");); } /* * Function: Unified2Init(char *) * * 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 * */ static void Unified2Init(struct _SnortConfig *sc, char *args) { Unified2Config *config; /* parse the argument list from the rules file */ config = Unified2ParseArgs(args, "snort-unified"); /* Set the preprocessor function into the function list */ AddFuncToOutputList(sc, Unified2LogAlert, OUTPUT_TYPE__ALERT, config); AddFuncToOutputList(sc, Unified2LogPacketAlert, OUTPUT_TYPE__LOG, config); AddFuncToCleanExitList(Unified2CleanExit, config); #ifdef SNORT_RELOAD AddFuncToReloadList(Unified2Reload, config); #endif AddFuncToPostConfigList(sc, Unified2PostConfig, config); } static void Unified2PostConfig(struct _SnortConfig *sc, int unused, void *data) { Unified2Config *config = (Unified2Config *)data; int status; if (config == NULL || config->base_filename == NULL) { FatalError("%s(%d) Could not initialize unified2 file: Unified2 " "configuration data or file name is NULL.\n", __FILE__, __LINE__); } #ifndef WIN32 if (config->base_filename[0] == '/') { status = SnortSnprintf(config->filepath, sizeof(config->filepath), "%s", config->base_filename); } else #endif { status = SnortSnprintf(config->filepath, sizeof(config->filepath), "%s/%s", sc->log_dir, config->base_filename); } if (status != SNORT_SNPRINTF_SUCCESS) { FatalError("%s(%d) Failed to copy unified2 file name\n", __FILE__, __LINE__); } config->base_proto = htonl(DAQ_GetBaseProtocol()); Unified2InitFile(config); if(stream_api) { stream_api->reg_xtra_data_log(AlertExtraData, (void *)config); } } /* * Function: Unified2InitFile() * * Purpose: Initialize the unified2 ouput file * * Arguments: config => pointer to the plugin's reference data struct * * Returns: void function */ static void Unified2InitFile(Unified2Config *config) { char filepath[STD_BUF]; char *fname_ptr; if (config == NULL) { FatalError("%s(%d) Could not initialize unified2 file: Unified2 " "configuration data is NULL.\n", __FILE__, __LINE__); } config->timestamp = (uint32_t)time(NULL); if (!config->nostamp) { if (SnortSnprintf(filepath, sizeof(filepath), "%s.%u", config->filepath, config->timestamp) != SNORT_SNPRINTF_SUCCESS) { FatalError("%s(%d) Failed to copy unified2 file path.\n", __FILE__, __LINE__); } fname_ptr = filepath; } else { fname_ptr = config->filepath; } if ((config->stream = fopen(fname_ptr, "wb")) == NULL) { FatalError("%s(%d) Could not open %s: %s\n", __FILE__, __LINE__, fname_ptr, strerror(errno)); } #ifdef UNIFIED2_SETVBUF /* Set buffer to size of record buffer so the system doesn't flush * part of a record if it's greater than BUFSIZ */ if (setvbuf(config->stream, io_buffer, _IOFBF, sizeof(io_buffer)) != 0) { ErrorMessage("%s(%d) Could not set I/O buffer: %s. " "Using system default.\n", __FILE__, __LINE__, strerror(errno)); } #endif /* If test mode, close and delete the file */ if (ScTestMode()) { fclose(config->stream); config->stream = NULL; if (unlink(fname_ptr) == -1) { ErrorMessage("%s(%d) Running in test mode so we want to remove " "test unified2 file. Could not unlink file \"%s\": %s\n", __FILE__, __LINE__, fname_ptr, strerror(errno)); } } } static inline void Unified2RotateFile(Unified2Config *config) { fclose(config->stream); config->current = 0; Unified2InitFile(config); } static int s_blocked_flag[] = { U2_BLOCKED_FLAG_ALLOW, U2_BLOCKED_FLAG_CANT, U2_BLOCKED_FLAG_WOULD, U2_BLOCKED_FLAG_BLOCK, U2_BLOCKED_FLAG_BLOCK }; static int GetU2Flags(const Packet* p, uint8_t* pimpact) { tActiveDrop dispos = Active_GetDisposition(); if ( dispos >= ACTIVE_DROP ) { *pimpact = U2_FLAG_BLOCKED; return U2_BLOCKED_FLAG_BLOCK; } return s_blocked_flag[dispos]; } static void _AlertIP4(Packet *p, const char *msg, Unified2Config *config, Event *event) { Serial_Unified2_Header hdr; Serial_Unified2IDSEvent_legacy alertdata; uint32_t write_len = sizeof(Serial_Unified2_Header) + sizeof(Serial_Unified2IDSEvent_legacy); memset(&alertdata, 0, sizeof(alertdata)); alertdata.event_id = htonl(event->event_id); alertdata.event_second = htonl(event->ref_time.tv_sec); alertdata.event_microsecond = htonl(event->ref_time.tv_usec); alertdata.generator_id = htonl(event->sig_generator); alertdata.signature_id = htonl(event->sig_id); alertdata.signature_revision = htonl(event->sig_rev); alertdata.classification_id = htonl(event->classification); alertdata.priority_id = htonl(event->priority); if (p != NULL) { alertdata.blocked = GetU2Flags(p, &alertdata.impact_flag); if(IPH_IS_VALID(p)) { alertdata.ip_source = p->iph->ip_src.s_addr; alertdata.ip_destination = p->iph->ip_dst.s_addr; alertdata.protocol = GetEventProto(p); if ((alertdata.protocol == IPPROTO_ICMP) && p->icmph) { alertdata.sport_itype = htons(p->icmph->type); alertdata.dport_icode = htons(p->icmph->code); } else if (!IsPortscanPacket(p)) { alertdata.sport_itype = htons(p->sp); alertdata.dport_icode = htons(p->dp); } } } if ((config->current + write_len) > config->limit) Unified2RotateFile(config); hdr.length = htonl(sizeof(Serial_Unified2IDSEvent_legacy)); hdr.type = htonl(UNIFIED2_IDS_EVENT); if (SafeMemcpy(write_pkt_buffer, &hdr, sizeof(Serial_Unified2_Header), write_pkt_buffer, write_pkt_end) != SAFEMEM_SUCCESS) { ErrorMessage("%s(%d) Failed to copy Serial_Unified2_Header. " "Not writing unified2 event.\n", __FILE__, __LINE__); return; } if (SafeMemcpy(write_pkt_buffer + sizeof(Serial_Unified2_Header), &alertdata, sizeof(Serial_Unified2IDSEvent_legacy), write_pkt_buffer, write_pkt_end) != SAFEMEM_SUCCESS) { ErrorMessage("%s(%d) Failed to copy Serial_Unified2IDSEvent_legacy. " "Not writing unified2 event.\n", __FILE__, __LINE__); return; } Unified2Write(write_pkt_buffer, write_len, config); } static void _AlertIP4_v2(Packet *p, const char *msg, Unified2Config *config, Event *event) { Serial_Unified2_Header hdr; Unified2IDSEvent alertdata; uint32_t write_len = sizeof(Serial_Unified2_Header) + sizeof(Unified2IDSEvent); memset(&alertdata, 0, sizeof(alertdata)); alertdata.event_id = htonl(event->event_id); alertdata.event_second = htonl(event->ref_time.tv_sec); alertdata.event_microsecond = htonl(event->ref_time.tv_usec); alertdata.generator_id = htonl(event->sig_generator); alertdata.signature_id = htonl(event->sig_id); alertdata.signature_revision = htonl(event->sig_rev); alertdata.classification_id = htonl(event->classification); alertdata.priority_id = htonl(event->priority); #if defined(FEAT_OPEN_APPID) memcpy(alertdata.app_name, event->app_name, sizeof(alertdata.app_name)); #endif /* defined(FEAT_OPEN_APPID) */ if(p) { alertdata.blocked = GetU2Flags(p, &alertdata.impact_flag); if(IPH_IS_VALID(p)) { alertdata.ip_source = p->iph->ip_src.s_addr; alertdata.ip_destination = p->iph->ip_dst.s_addr; alertdata.protocol = GetEventProto(p); if ((alertdata.protocol == IPPROTO_ICMP) && p->icmph) { alertdata.sport_itype = htons(p->icmph->type); alertdata.dport_icode = htons(p->icmph->code); } else if (!IsPortscanPacket(p)) { alertdata.sport_itype = htons(p->sp); alertdata.dport_icode = htons(p->dp); } #ifdef MPLS if((p->mpls) && (config->mpls_event_types)) { alertdata.mpls_label = htonl(p->mplsHdr.label); } #endif if(config->vlan_event_types) { if(p->vh) { alertdata.vlanId = htons(VTH_VLAN(p->vh)); } alertdata.pad2 = htons(p->configPolicyId); } #if defined(FEAT_OPEN_APPID) if((event->app_name[0]) && (config->appid_event_types)) { memcpy(alertdata.app_name, event->app_name, sizeof(alertdata.app_name)); } #endif /* defined(FEAT_OPEN_APPID) */ } } if ((config->current + write_len) > config->limit) Unified2RotateFile(config); hdr.length = htonl(sizeof(Unified2IDSEvent)); #if !defined(FEAT_OPEN_APPID) hdr.type = htonl(UNIFIED2_IDS_EVENT_VLAN); #else /* defined(FEAT_OPEN_APPID) */ hdr.type = htonl(UNIFIED2_IDS_EVENT_APPID); #endif /* defined(FEAT_OPEN_APPID) */ if (SafeMemcpy(write_pkt_buffer_v2, &hdr, sizeof(Serial_Unified2_Header), write_pkt_buffer_v2, write_pkt_end_v2) != SAFEMEM_SUCCESS) { ErrorMessage("%s(%d) Failed to copy Serial_Unified2_Header. " "Not writing unified2 event.\n", __FILE__, __LINE__); return; } if (SafeMemcpy(write_pkt_buffer_v2 + sizeof(Serial_Unified2_Header), &alertdata, sizeof(Unified2IDSEvent), write_pkt_buffer_v2, write_pkt_end_v2) != SAFEMEM_SUCCESS) { ErrorMessage("%s(%d) Failed to copy Serial_Unified2IDSEvent_legacy. " "Not writing unified2 event.\n", __FILE__, __LINE__); return; } Unified2Write(write_pkt_buffer_v2, write_len, config); } static void _AlertIP6(Packet *p, const char *msg, Unified2Config *config, Event *event) { Serial_Unified2_Header hdr; Serial_Unified2IDSEventIPv6_legacy alertdata; uint32_t write_len = sizeof(Serial_Unified2_Header) + sizeof(Serial_Unified2IDSEventIPv6_legacy); memset(&alertdata, 0, sizeof(alertdata)); alertdata.event_id = htonl(event->event_id); alertdata.event_second = htonl(event->ref_time.tv_sec); alertdata.event_microsecond = htonl(event->ref_time.tv_usec); alertdata.generator_id = htonl(event->sig_generator); alertdata.signature_id = htonl(event->sig_id); alertdata.signature_revision = htonl(event->sig_rev); alertdata.classification_id = htonl(event->classification); alertdata.priority_id = htonl(event->priority); if(p) { alertdata.blocked = GetU2Flags(p, &alertdata.impact_flag); if(IPH_IS_VALID(p)) { sfaddr_t* ip; ip = GET_SRC_IP(p); alertdata.ip_source = *(struct in6_addr*)sfaddr_get_ip6_ptr(ip); ip = GET_DST_IP(p); alertdata.ip_destination = *(struct in6_addr*)sfaddr_get_ip6_ptr(ip); alertdata.protocol = GetEventProto(p); if ((alertdata.protocol == IPPROTO_ICMP) && p->icmph) { alertdata.sport_itype = htons(p->icmph->type); alertdata.dport_icode = htons(p->icmph->code); } else if (!IsPortscanPacket(p)) { alertdata.sport_itype = htons(p->sp); alertdata.dport_icode = htons(p->dp); } } } if ((config->current + write_len) > config->limit) Unified2RotateFile(config); hdr.length = htonl(sizeof(Serial_Unified2IDSEventIPv6_legacy)); hdr.type = htonl(UNIFIED2_IDS_EVENT_IPV6); if (SafeMemcpy(write_pkt_buffer, &hdr, sizeof(Serial_Unified2_Header), write_pkt_buffer, write_pkt_end) != SAFEMEM_SUCCESS) { ErrorMessage("%s(%d) Failed to copy Serial_Unified2_Header. " "Not writing unified2 event.\n", __FILE__, __LINE__); return; } if (SafeMemcpy(write_pkt_buffer + sizeof(Serial_Unified2_Header), &alertdata, sizeof(Serial_Unified2IDSEventIPv6_legacy), write_pkt_buffer, write_pkt_end) != SAFEMEM_SUCCESS) { ErrorMessage("%s(%d) Failed to copy Serial_Unified2IDSEventIPv6_legacy. " "Not writing unified2 event.\n", __FILE__, __LINE__); return; } Unified2Write(write_pkt_buffer, write_len, config); } static void _AlertIP6_v2(Packet *p, const char *msg, Unified2Config *config, Event *event) { Serial_Unified2_Header hdr; Unified2IDSEventIPv6 alertdata; uint32_t write_len = sizeof(Serial_Unified2_Header) + sizeof(Unified2IDSEventIPv6); memset(&alertdata, 0, sizeof(alertdata)); alertdata.event_id = htonl(event->event_id); alertdata.event_second = htonl(event->ref_time.tv_sec); alertdata.event_microsecond = htonl(event->ref_time.tv_usec); alertdata.generator_id = htonl(event->sig_generator); alertdata.signature_id = htonl(event->sig_id); alertdata.signature_revision = htonl(event->sig_rev); alertdata.classification_id = htonl(event->classification); alertdata.priority_id = htonl(event->priority); #if defined(FEAT_OPEN_APPID) memcpy(alertdata.app_name, event->app_name, sizeof(alertdata.app_name)); #endif /* defined(FEAT_OPEN_APPID) */ if(p) { alertdata.blocked = GetU2Flags(p, &alertdata.impact_flag); if(IPH_IS_VALID(p)) { sfaddr_t* ip; ip = GET_SRC_IP(p); alertdata.ip_source = *(struct in6_addr*)sfaddr_get_ip6_ptr(ip); ip = GET_DST_IP(p); alertdata.ip_destination = *(struct in6_addr*)sfaddr_get_ip6_ptr(ip); alertdata.protocol = GetEventProto(p); if ((alertdata.protocol == IPPROTO_ICMP) && p->icmph) { alertdata.sport_itype = htons(p->icmph->type); alertdata.dport_icode = htons(p->icmph->code); } else if (!IsPortscanPacket(p)) { alertdata.sport_itype = htons(p->sp); alertdata.dport_icode = htons(p->dp); } #ifdef MPLS if((p->mpls) && (config->mpls_event_types)) { alertdata.mpls_label = htonl(p->mplsHdr.label); } #endif if(config->vlan_event_types) { if(p->vh) { alertdata.vlanId = htons(VTH_VLAN(p->vh)); } alertdata.pad2 = htons(p->configPolicyId); } #if defined(FEAT_OPEN_APPID) if((event->app_name[0]) && (config->appid_event_types)) { memcpy(alertdata.app_name, event->app_name, sizeof(alertdata.app_name)); } #endif /* defined(FEAT_OPEN_APPID) */ } } if ((config->current + write_len) > config->limit) Unified2RotateFile(config); hdr.length = htonl(sizeof(Unified2IDSEventIPv6)); #if !defined(FEAT_OPEN_APPID) hdr.type = htonl(UNIFIED2_IDS_EVENT_IPV6_VLAN); #else hdr.type = htonl(UNIFIED2_IDS_EVENT_APPID_IPV6); #endif if (SafeMemcpy(write_pkt_buffer_v2, &hdr, sizeof(Serial_Unified2_Header), write_pkt_buffer_v2, write_pkt_end_v2) != SAFEMEM_SUCCESS) { ErrorMessage("%s(%d) Failed to copy Serial_Unified2_Header. " "Not writing unified2 event.\n", __FILE__, __LINE__); return; } if (SafeMemcpy(write_pkt_buffer_v2 + sizeof(Serial_Unified2_Header), &alertdata, sizeof(Unified2IDSEventIPv6), write_pkt_buffer_v2, write_pkt_end_v2) != SAFEMEM_SUCCESS) { ErrorMessage("%s(%d) Failed to copy Unified2IDSEventIPv6. " "Not writing unified2 event.\n", __FILE__, __LINE__); return; } Unified2Write(write_pkt_buffer_v2, write_len, config); } void _WriteExtraData(Unified2Config *config, uint32_t event_id, uint32_t event_second, uint8_t *buffer, uint32_t len, uint32_t type ) { Serial_Unified2_Header hdr; SerialUnified2ExtraData alertdata; Unified2ExtraDataHdr alertHdr; uint8_t write_buffer[MAX_XDATA_WRITE_BUF_LEN]; uint8_t *write_end = NULL; uint8_t *ptr = NULL; uint32_t write_len; write_len = sizeof(Serial_Unified2_Header) + sizeof(Unified2ExtraDataHdr); alertdata.sensor_id = 0; alertdata.event_id = htonl(event_id); alertdata.event_second = htonl(event_second); alertdata.data_type = htonl(EVENT_DATA_TYPE_BLOB); alertdata.type = htonl(type); alertdata.blob_length = htonl(sizeof(alertdata.data_type) + sizeof(alertdata.blob_length) + len); write_len = write_len + sizeof(alertdata) + len; alertHdr.event_type = htonl(EVENT_TYPE_EXTRA_DATA); alertHdr.event_length = htonl(write_len - sizeof(Serial_Unified2_Header)); if ((config->current + write_len) > config->limit) Unified2RotateFile(config); hdr.length = htonl(write_len - sizeof(Serial_Unified2_Header)); hdr.type = htonl(UNIFIED2_EXTRA_DATA); write_end = write_buffer + sizeof(write_buffer); ptr = write_buffer; if (SafeMemcpy(ptr, &hdr, sizeof(hdr), write_buffer, write_end) != SAFEMEM_SUCCESS) { ErrorMessage("%s(%d) Failed to copy Serial_Unified2_Header. " "Not writing unified2 event.\n", __FILE__, __LINE__); return; } ptr = ptr + sizeof(hdr); if (SafeMemcpy(ptr, &alertHdr, sizeof(alertHdr), write_buffer, write_end) != SAFEMEM_SUCCESS) { ErrorMessage("%s(%d) Failed to copy Unified2ExtraDataHdr. " "Not writing unified2 event.\n", __FILE__, __LINE__); return; } ptr = ptr + sizeof(alertHdr); if (SafeMemcpy(ptr, &alertdata, sizeof(alertdata), write_buffer, write_end) != SAFEMEM_SUCCESS) { ErrorMessage("%s(%d) Failed to copy SerialUnified2ExtraData. " "Not writing unified2 event.\n", __FILE__, __LINE__); return; } ptr = ptr + sizeof(alertdata); if (SafeMemcpy(ptr, buffer, len, write_buffer, write_end) != SAFEMEM_SUCCESS) { ErrorMessage("%s(%d) Failed to copy Gzip Decompressed Buffer. " "Not writing unified2 event.\n", __FILE__, __LINE__); return; } Unified2Write(write_buffer, write_len, config); } static void AlertExtraData( void *ssnptr, void *data, LogFunction *log_funcs, uint32_t max_count, uint32_t xtradata_mask, uint32_t event_id, uint32_t event_second) { Unified2Config *config = (Unified2Config *)data; uint32_t xid; if((config == NULL) || !xtradata_mask || !event_second) return; xid = ffs(xtradata_mask); while ( xid && (xid <= max_count) ) { uint32_t len = 0; uint32_t type = 0; uint8_t *write_buffer; if ( log_funcs[xid-1](ssnptr, &write_buffer, &len, &type) && (len > 0) ) { _WriteExtraData(config, event_id, event_second, write_buffer, len, type); } xtradata_mask ^= BIT(xid); xid = ffs(xtradata_mask); } } static void Unified2LogAlert(Packet *p, const char *msg, void *arg, Event *event) { Unified2Config *config = (Unified2Config *)arg; if (config == NULL) return; if(!event) return; if(IS_IP4(p)) { #ifdef MPLS #if !defined(FEAT_OPEN_APPID) if((config->vlan_event_types) || (config->mpls_event_types)) #else /* defined(FEAT_OPEN_APPID) */ if((config->vlan_event_types) || (config->mpls_event_types) || (config->appid_event_types)) #endif /* defined(FEAT_OPEN_APPID) */ #else #if !defined(FEAT_OPEN_APPID) if(config->vlan_event_types) #else /* defined(FEAT_OPEN_APPID) */ if(config->vlan_event_types || config->appid_event_types) #endif /* defined(FEAT_OPEN_APPID) */ #endif { _AlertIP4_v2(p, msg, config, event); } else _AlertIP4(p, msg, config, event); } else { #ifdef MPLS #if !defined(FEAT_OPEN_APPID) if((config->vlan_event_types) || (config->mpls_event_types)) #else /* defined(FEAT_OPEN_APPID) */ if((config->vlan_event_types) || (config->mpls_event_types) || (config->appid_event_types)) #endif /* defined(FEAT_OPEN_APPID) */ #else #if !defined(FEAT_OPEN_APPID) if(config->vlan_event_types) #else /* defined(FEAT_OPEN_APPID) */ if(config->vlan_event_types || config->appid_event_types) #endif /* defined(FEAT_OPEN_APPID) */ #endif { _AlertIP6_v2(p, msg, config, event); } else _AlertIP6(p, msg, config, event); if(ScLogIPv6Extra() && IS_IP6(p)) { sfaddr_t* ip = GET_SRC_IP(p); _WriteExtraData(config, event->event_id, event->ref_time.tv_sec, (uint8_t*)sfaddr_get_ip6_ptr(ip), sizeof(struct in6_addr), EVENT_INFO_IPV6_SRC); ip = GET_DST_IP(p); _WriteExtraData(config, event->event_id, event->ref_time.tv_sec, (uint8_t*)sfaddr_get_ip6_ptr(ip), sizeof(struct in6_addr), EVENT_INFO_IPV6_DST); } } if ( p->ssnptr ) stream_api->update_session_alert( p->ssnptr, p, event->sig_generator, event->sig_id, event->event_id, event->ref_time.tv_sec); if ( p->xtradata_mask ) { LogFunction *log_funcs; uint32_t max_count = stream_api->get_xtra_data_map(&log_funcs); if ( max_count > 0 ) AlertExtraData( p->ssnptr, config, log_funcs, max_count, p->xtradata_mask, event->event_id, event->ref_time.tv_sec); } return; } static void Unified2LogPacketAlert(Packet *p, const char *msg, void *arg, Event *event) { Unified2Config *config = (Unified2Config *)arg; if (config == NULL) return; if(p) { if ((p->packet_flags & PKT_REBUILT_STREAM) && stream_api) { DEBUG_WRAP(DebugMessage(DEBUG_LOG, "[*] Reassembled packet, dumping stream packets\n");); _Unified2LogStreamAlert(p, msg, config, event); } else { DEBUG_WRAP(DebugMessage(DEBUG_LOG, "[*] Logging unified 2 packets...\n");); _Unified2LogPacketAlert(p, msg, config, event); } } } static void _Unified2LogPacketAlert(Packet *p, const char *msg, Unified2Config *config, Event *event) { Serial_Unified2_Header hdr; Serial_Unified2Packet logheader; uint32_t pkt_length = 0; uint32_t write_len = sizeof(Serial_Unified2_Header) + sizeof(Serial_Unified2Packet) - 4; logheader.sensor_id = 0; logheader.linktype = config->base_proto; if (event != NULL) { logheader.event_id = htonl(event->event_reference); logheader.event_second = htonl(event->ref_time.tv_sec); DEBUG_WRAP(DebugMessage(DEBUG_LOG, "------------\n")); } else { logheader.event_id = 0; logheader.event_second = 0; } if ((p != NULL) && (p->pkt != NULL) && (p->pkth != NULL) && obApi->payloadObfuscationRequired(p)) { Unified2LogCallbackData unifiedData; unifiedData.logheader = &logheader; unifiedData.config = config; unifiedData.event = event; unifiedData.num_bytes = 0; if (obApi->obfuscatePacket(p, Unified2LogObfuscationCallback, (void *)&unifiedData) == OB_RET_SUCCESS) { /* Write the last record */ if (unifiedData.num_bytes != 0) Unified2Write(write_pkt_buffer, unifiedData.num_bytes, config); return; } } if(p && p->pkt && p->pkth) { logheader.packet_second = htonl((uint32_t)p->pkth->ts.tv_sec); logheader.packet_microsecond = htonl((uint32_t)p->pkth->ts.tv_usec); logheader.packet_length = htonl(p->pkth->caplen); pkt_length = p->pkth->caplen; write_len += pkt_length; } else { logheader.packet_second = 0; logheader.packet_microsecond = 0; logheader.packet_length = 0; } if ((config->current + write_len) > config->limit) Unified2RotateFile(config); hdr.length = htonl(sizeof(Serial_Unified2Packet) - 4 + pkt_length); hdr.type = htonl(UNIFIED2_PACKET); if (SafeMemcpy(write_pkt_buffer, &hdr, sizeof(Serial_Unified2_Header), write_pkt_buffer, write_pkt_end) != SAFEMEM_SUCCESS) { ErrorMessage("%s(%d) Failed to copy Serial_Unified2_Header. " "Not writing unified2 event.\n", __FILE__, __LINE__); return; } if (SafeMemcpy(write_pkt_buffer + sizeof(Serial_Unified2_Header), &logheader, sizeof(Serial_Unified2Packet) - 4, write_pkt_buffer, write_pkt_end) != SAFEMEM_SUCCESS) { ErrorMessage("%s(%d) Failed to copy Serial_Unified2Packet. " "Not writing unified2 event.\n", __FILE__, __LINE__); return; } if (pkt_length != 0) { if (SafeMemcpy(write_pkt_buffer + sizeof(Serial_Unified2_Header) + sizeof(Serial_Unified2Packet) - 4, p->pkt, pkt_length, write_pkt_buffer, write_pkt_end) != SAFEMEM_SUCCESS) { ErrorMessage("%s(%d) Failed to copy packet data. " "Not writing unified2 event.\n", __FILE__, __LINE__); return; } } Unified2Write(write_pkt_buffer, write_len, config); } /** * Callback for the Stream reassembler to log packets * */ static int Unified2LogStreamCallback(DAQ_PktHdr_t *pkth, uint8_t *packet_data, void *userdata) { Unified2LogCallbackData *unifiedData = (Unified2LogCallbackData *)userdata; Serial_Unified2_Header hdr; uint32_t write_len = sizeof(Serial_Unified2_Header) + sizeof(Serial_Unified2Packet) - 4; if (!userdata || !pkth || !packet_data) return -1; write_len += pkth->caplen; if ((unifiedData->config->current + write_len) > unifiedData->config->limit) Unified2RotateFile(unifiedData->config); hdr.type = htonl(UNIFIED2_PACKET); hdr.length = htonl(sizeof(Serial_Unified2Packet) - 4 + pkth->caplen); /* Event data will already be set */ unifiedData->logheader->packet_second = htonl((uint32_t)pkth->ts.tv_sec); unifiedData->logheader->packet_microsecond = htonl((uint32_t)pkth->ts.tv_usec); unifiedData->logheader->packet_length = htonl(pkth->caplen); if (SafeMemcpy(write_pkt_buffer, &hdr, sizeof(Serial_Unified2_Header), write_pkt_buffer, write_pkt_end) != SAFEMEM_SUCCESS) { ErrorMessage("%s(%d) Failed to copy Serial_Unified2_Header. " "Not writing unified2 event.\n", __FILE__, __LINE__); return -1; } if (SafeMemcpy(write_pkt_buffer + sizeof(Serial_Unified2_Header), unifiedData->logheader, sizeof(Serial_Unified2Packet) - 4, write_pkt_buffer, write_pkt_end) != SAFEMEM_SUCCESS) { ErrorMessage("%s(%d) Failed to copy Serial_Unified2Packet. " "Not writing unified2 event.\n", __FILE__, __LINE__); return -1; } if (SafeMemcpy(write_pkt_buffer + sizeof(Serial_Unified2_Header) + sizeof(Serial_Unified2Packet) - 4, packet_data, pkth->caplen, write_pkt_buffer, write_pkt_end) != SAFEMEM_SUCCESS) { ErrorMessage("%s(%d) Failed to copy packet data. " "Not writing unified2 event.\n", __FILE__, __LINE__); return -1; } Unified2Write(write_pkt_buffer, write_len, unifiedData->config); #if 0 /* DO NOT DO THIS FOR UNIFIED2. * The event referenced below in the unifiedData is a pointer * to the actual event and this changes its gid & sid to 2:1. * That is baaaaad. */ /* after the first logged packet modify the event headers */ if(!unifiedData->once++) { unifiedData->event->sig_generator = GENERATOR_TAG; unifiedData->event->sig_id = TAG_LOG_PKT; unifiedData->event->sig_rev = 1; unifiedData->event->classification = 0; unifiedData->event->priority = unifiedData->event->priority; /* Note that event_id is now incorrect. * See OldUnified2LogPacketAlert() for details. */ } #endif return 0; } static ObRet Unified2LogObfuscationCallback(const DAQ_PktHdr_t *pkth, const uint8_t *packet_data, ob_size_t length, ob_char_t ob_char, void *userdata) { Unified2LogCallbackData *unifiedData = (Unified2LogCallbackData *)userdata; if (userdata == NULL) return OB_RET_ERROR; if (pkth != NULL) { Serial_Unified2_Header hdr; uint32_t record_len = (pkth->caplen + sizeof(Serial_Unified2_Header) + (sizeof(Serial_Unified2Packet) - 4)); /* Write the last buffer if present. Want to write an entire record * at a time in case of failures, we don't corrupt the log file. */ if (unifiedData->num_bytes != 0) Unified2Write(write_pkt_buffer, unifiedData->num_bytes, unifiedData->config); if ((write_pkt_buffer + record_len) > write_pkt_end) { ErrorMessage("%s(%d) Too much data. Not writing unified2 event.\n", __FILE__, __LINE__); return OB_RET_ERROR; } if ((unifiedData->config->current + record_len) > unifiedData->config->limit) Unified2RotateFile(unifiedData->config); hdr.type = htonl(UNIFIED2_PACKET); hdr.length = htonl((sizeof(Serial_Unified2Packet) - 4) + pkth->caplen); /* Event data will already be set */ unifiedData->logheader->packet_second = htonl((uint32_t)pkth->ts.tv_sec); unifiedData->logheader->packet_microsecond = htonl((uint32_t)pkth->ts.tv_usec); unifiedData->logheader->packet_length = htonl(pkth->caplen); if (SafeMemcpy(write_pkt_buffer, &hdr, sizeof(Serial_Unified2_Header), write_pkt_buffer, write_pkt_end) != SAFEMEM_SUCCESS) { ErrorMessage("%s(%d) Failed to copy Serial_Unified2_Header. " "Not writing unified2 event.\n", __FILE__, __LINE__); return OB_RET_ERROR; } if (SafeMemcpy(write_pkt_buffer + sizeof(Serial_Unified2_Header), unifiedData->logheader, sizeof(Serial_Unified2Packet) - 4, write_pkt_buffer, write_pkt_end) != SAFEMEM_SUCCESS) { ErrorMessage("%s(%d) Failed to copy Serial_Unified2Packet. " "Not writing unified2 event.\n", __FILE__, __LINE__); return OB_RET_ERROR; } /* Reset this for the new record */ unifiedData->num_bytes = (record_len - pkth->caplen); } if (packet_data != NULL) { if (SafeMemcpy(write_pkt_buffer + unifiedData->num_bytes, packet_data, (size_t)length, write_pkt_buffer, write_pkt_end) != SAFEMEM_SUCCESS) { ErrorMessage("%s(%d) Failed to copy packet data " "Not writing unified2 event.\n", __FILE__, __LINE__); return OB_RET_ERROR; } } else { if (SafeMemset(write_pkt_buffer + unifiedData->num_bytes, (uint8_t)ob_char, (size_t)length, write_pkt_buffer, write_pkt_end) != SAFEMEM_SUCCESS) { ErrorMessage("%s(%d) Failed to obfuscate packet data " "Not writing unified2 event.\n", __FILE__, __LINE__); return OB_RET_ERROR; } } unifiedData->num_bytes += length; return OB_RET_SUCCESS; } /** * Log a set of packets stored in the stream reassembler * */ static void _Unified2LogStreamAlert(Packet *p, const char *msg, Unified2Config *config, Event *event) { Unified2LogCallbackData unifiedData; Serial_Unified2Packet logheader; logheader.sensor_id = 0; logheader.linktype = config->base_proto; /* setup the event header */ if (event != NULL) { logheader.event_id = htonl(event->event_reference); logheader.event_second = htonl(event->ref_time.tv_sec); } else { logheader.event_id = 0; logheader.event_second = 0; } /* queue up the stream for logging */ unifiedData.logheader = &logheader; unifiedData.config = config; unifiedData.event = event; unifiedData.num_bytes = 0; if ((p != NULL) && (p->pkt != NULL) && (p->pkth != NULL) && obApi->payloadObfuscationRequired(p)) { if (obApi->obfuscatePacketStreamSegments(p, Unified2LogObfuscationCallback, (void *)&unifiedData) == OB_RET_SUCCESS) { /* Write the last record */ if (unifiedData.num_bytes != 0) Unified2Write(write_pkt_buffer, unifiedData.num_bytes, config); return; } /* Reset since we failed */ unifiedData.num_bytes = 0; } if (!p) return; stream_api->traverse_reassembled(p, Unified2LogStreamCallback, &unifiedData); } /* * Function: Unified2ParseArgs(char *) * * Purpose: Process the preprocessor arguments from the rules file and * initialize the preprocessor's data struct. This function doesn't * have to exist if it makes sense to parse the args in the init * function. * * Arguments: args => argument list * * Returns: void function * */ static Unified2Config * Unified2ParseArgs(char *args, char *default_filename) { Unified2Config *config = (Unified2Config *)SnortAlloc(sizeof(Unified2Config)); /* This is so the if 'nostamps' option is used on the command line, * it will be honored by unified2, and only one variable is used. */ config->nostamp = ScNoOutputTimestamp(); DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Args: %s\n", args);); if(args != NULL) { char **toks; int num_toks; int i = 0; toks = mSplit((char *)args, ",", 31, &num_toks, '\\'); for(i = 0; i < num_toks; ++i) { char **stoks; int num_stoks; char *index = toks[i]; while(isspace((int)*index)) ++index; stoks = mSplit(index, " \t", 2, &num_stoks, 0); if(strcasecmp("filename", stoks[0]) == 0) { if(num_stoks > 1 && config->base_filename == NULL) config->base_filename = SnortStrdup(stoks[1]); else FatalError("Argument Error in %s(%i): %s\n", file_name, file_line, index); } else if(strcasecmp("limit", stoks[0]) == 0) { char *end; if ((num_stoks > 1) && (config->limit == 0)) { config->limit = SnortStrtoul(stoks[1], &end, 10); if ((stoks[1] == end) || (errno == ERANGE)) { FatalError("Argument Error in %s(%i): %s\n", file_name, file_line, index); } } else { FatalError("Argument Error in %s(%i): %s\n", file_name, file_line, index); } } else if(strcasecmp("nostamp", stoks[0]) == 0) { config->nostamp = 1; } #ifdef MPLS else if(strcasecmp("mpls_event_types", stoks[0]) == 0) { config->mpls_event_types = 1; } #endif else if(strcasecmp("vlan_event_types", stoks[0]) == 0) { config->vlan_event_types = 1; #if defined(FEAT_OPEN_APPID) } else if(strcasecmp("appid_event_types", stoks[0]) == 0) { config->appid_event_types = 1; #endif /* defined(FEAT_OPEN_APPID) */ } else { FatalError("Argument Error in %s(%i): %s\n", file_name, file_line, index); } mSplitFree(&stoks, num_stoks); } mSplitFree(&toks, num_toks); } if (config->base_filename == NULL) config->base_filename = SnortStrdup(default_filename); if (config->limit == 0) { config->limit = 128; } else if (config->limit > 512) { LogMessage("spo_unified2 %s(%d)=> Lowering limit of %iMB to 512MB\n", file_name, file_line, config->limit); config->limit = 512; } /* convert the limit to "MB" */ config->limit <<= 20; return config; } /* * Function: Unified2CleanExitFunc() * * Purpose: Cleanup at exit time * * Arguments: signal => signal that caused this event * arg => data ptr to reference this plugin's data * * Returns: void function */ static void Unified2CleanExit(int signal, void *arg) { /* cast the arg pointer to the proper type */ Unified2Config *config = (Unified2Config *)arg; DEBUG_WRAP(DebugMessage(DEBUG_FLOW, "SpoUnified2: CleanExit\n");); /* free up initialized memory */ if (config != NULL) { if (config->stream != NULL) fclose(config->stream); if (config->base_filename != NULL) free(config->base_filename); free(config); } } #ifdef SNORT_RELOAD /* * Function: Reload() * * Purpose: For reloads (SIGHUP usually), over the output * * Arguments: signal => signal that caused this event * arg => data ptr to reference this plugin's data * * Returns: void function */ static void Unified2Reload(struct _SnortConfig *sc, int signal, void *arg) { Unified2Config *config = (Unified2Config *)arg; DEBUG_WRAP(DebugMessage(DEBUG_FLOW, "SpoUnified2: Reload\n");); Unified2RotateFile(config); } #endif /* Unified2 Alert functions (deprecated) */ static void Unified2AlertInit(struct _SnortConfig *sc, char *args) { Unified2Config *config; int signal = 0; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Output: Unified2 Alert Initialized\n");); /* parse the argument list from the rules file */ config = Unified2ParseArgs(args, "snort-unified.alert"); alert_config = config; if(log_config && log_config->base_filename) { if(strcmp(config->base_filename, log_config->base_filename) == 0) { Unified2CleanExit(signal , (void *)log_config); Unified2CleanExit(signal, (void *)config); FatalError("Argument Error in %s(%i). Cannot reuse the filename in config option '%s'\n", file_name, file_line, "alert_unified2"); } } /* Set the preprocessor function into the function list */ AddFuncToOutputList(sc, Unified2LogAlert, OUTPUT_TYPE__ALERT, config); AddFuncToCleanExitList(Unified2CleanExit, config); #ifdef SNORT_RELOAD AddFuncToReloadList(Unified2Reload, config); #endif AddFuncToPostConfigList(sc, Unified2PostConfig, config); } /* Unified2 Packet Log functions (deprecated) */ static void Unified2LogInit(struct _SnortConfig *sc, char *args) { Unified2Config *config; int signal = 0; DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Output: Unified2 Log Initialized\n");); /* parse the argument list from the rules file */ config = Unified2ParseArgs(args, "snort-unified.log"); log_config = config; if(alert_config && alert_config->base_filename) { if(strcmp(config->base_filename, alert_config->base_filename) == 0) { Unified2CleanExit(signal, (void *)alert_config); Unified2CleanExit(signal, (void *)config); FatalError("Argument Error in %s(%i). Cannot reuse the filename in config option '%s'\n", file_name, file_line, "log_unified2"); } } //LogMessage("Unified2LogFilename = %s\n", Unified2Info->filename); /* Set the preprocessor function into the function list */ AddFuncToOutputList(sc, Unified2LogPacketAlert, OUTPUT_TYPE__LOG, config); AddFuncToCleanExitList(Unified2CleanExit, config); #ifdef SNORT_RELOAD AddFuncToReloadList(Unified2Reload, config); #endif AddFuncToPostConfigList(sc, Unified2PostConfig, config); } /****************************************************************************** * Function: Unified2Write() * * Main function for writing to the unified2 file. * * For low level I/O errors, the current unified2 file is closed and a new * one created and a write to the new unified2 file is done. It was found * that when writing to an NFS mounted share that is using a soft mount option, * writes sometimes fail and leave the unified2 file corrupted. If the write * to the newly created unified2 file fails, Snort will fatal error. * * In the case of interrupt errors, the write is retried, but only for a * finite number of times. * * All other errors are treated as non-recoverable and Snort will fatal error. * * Upon successful completion of write, the length of the data written is * added to the current amount of total data written thus far to the * unified2 file. * * Arguments * uint8_t * * The buffer containing the data to write * uint32_t * The length of the data to write * Unified2Config * * A pointer to the unified2 configuration data * * Returns: None * ******************************************************************************/ static void Unified2Write(uint8_t *buf, uint32_t buf_len, Unified2Config *config) { size_t fwcount = 0; int ffstatus = 0; /* Nothing to write or nothing to write to */ if ((buf == NULL) || (config == NULL) || (config->stream == NULL)) return; /* Don't use fsync(). It is a total performance killer */ if (((fwcount = fwrite(buf, (size_t)buf_len, 1, config->stream)) != 1) || ((ffstatus = fflush(config->stream)) != 0)) { /* errno is saved just to avoid other intervening calls * (e.g. ErrorMessage) potentially reseting it to something else. */ int error = errno; int max_retries = 3; /* On iterations other than the first, the only non-zero error will be * EINTR or interrupt. Only iterate a maximum of max_retries times so * there is no chance of infinite looping if for some reason the write * is constantly interrupted */ while ((error != 0) && (max_retries != 0)) { if (config->nostamp) { ErrorMessage("%s(%d) Failed to write to unified2 file (%s): %s\n", __FILE__, __LINE__, config->filepath, strerror(error)); } else { ErrorMessage("%s(%d) Failed to write to unified2 file (%s.%u): %s\n", __FILE__, __LINE__, config->filepath, config->timestamp, strerror(error)); } while ((error == EINTR) && (max_retries != 0)) { max_retries--; /* Supposedly an interrupt can only occur before anything * has been written. Try again */ ErrorMessage("%s(%d) Got interrupt. Retry write to unified2 " "file.\n", __FILE__, __LINE__); if (fwcount != 1) { /* fwrite() failed. Redo fwrite and fflush */ if (((fwcount = fwrite(buf, (size_t)buf_len, 1, config->stream)) == 1) && ((ffstatus = fflush(config->stream)) == 0)) { ErrorMessage("%s(%d) Write to unified2 file succeeded!\n", __FILE__, __LINE__); error = 0; break; } } else if ((ffstatus = fflush(config->stream)) == 0) { ErrorMessage("%s(%d) Write to unified2 file succeeded!\n", __FILE__, __LINE__); error = 0; break; } error = errno; ErrorMessage("%s(%d) Retrying write to unified2 file failed.\n", __FILE__, __LINE__); } /* If we've reached the maximum number of interrupt retries, * just bail out of the main while loop */ if (max_retries == 0) continue; switch (error) { case 0: break; case EIO: ErrorMessage("%s(%d) Unified2 file is possibly corrupt. " "Closing this unified2 file and creating " "a new one.\n", __FILE__, __LINE__); Unified2RotateFile(config); if (config->nostamp) { ErrorMessage("%s(%d) New unified2 file: %s\n", __FILE__, __LINE__, config->filepath); } else { ErrorMessage("%s(%d) New unified2 file: %s.%u\n", __FILE__, __LINE__, config->filepath, config->timestamp); } if (((fwcount = fwrite(buf, (size_t)buf_len, 1, config->stream)) == 1) && ((ffstatus = fflush(config->stream)) == 0)) { ErrorMessage("%s(%d) Write to unified2 file succeeded!\n", __FILE__, __LINE__); error = 0; break; } error = errno; /* Loop again if interrupt */ if (error == EINTR) break; /* Write out error message again, then fall through and fatal */ if (config->nostamp) { ErrorMessage("%s(%d) Failed to write to unified2 file (%s): %s\n", __FILE__, __LINE__, config->filepath, strerror(error)); } else { ErrorMessage("%s(%d) Failed to write to unified2 file (%s.%u): %s\n", __FILE__, __LINE__, config->filepath, config->timestamp, strerror(error)); } /* Fall through */ case EAGAIN: /* We're not in non-blocking mode */ case EBADF: case EFAULT: case EFBIG: case EINVAL: case ENOSPC: case EPIPE: default: FatalError("%s(%d) Cannot write to device.\n", __FILE__, __LINE__); } } if ((max_retries == 0) && (error != 0)) { FatalError("%s(%d) Maximum number of interrupts exceeded. " "Cannot write to device.\n", __FILE__, __LINE__); } } config->current += buf_len; } snort-2.9.15.1/src/output-plugins/spo_unified2.h0000644000175200017520000000423613571422607016422 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifndef __SPO_UNIFIED2_H__ #define __SPO_UNIFIED2_H__ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifndef WIN32 #include #endif #include "decode.h" /* for struct in6_addr -- maybe move to sf_types.h? */ #include "sf_types.h" typedef struct _PESessionEndRecord { uint32_t sensorId; uint8_t ingressZone[16]; uint8_t egressZone[16]; uint8_t ingressIntf[16]; uint8_t egressIntf[16]; uint8_t initiatorIp[16]; uint8_t responderIp[16]; uint8_t policyRevision[16]; uint32_t policyengine_ruleId; uint32_t policyengine_ruleAction; uint16_t initiatorPort; uint16_t responderPort; uint16_t tcpFlags; uint8_t protocol; uint8_t padding; uint8_t netflowSource[16]; uint32_t firstPktsecond; uint32_t lastPktsecond; uint64_t initiatorPkts; uint64_t responderPkts; uint64_t initiatorBytes; uint64_t responderBytes; uint32_t appProtoId; uint32_t webAppId; uint32_t userId; uint32_t urlCategory; uint32_t urlReputation; uint32_t clientId; } PESessionRecord; void Unified2Setup(void); #endif /* __SPO_UNIFIED_H__ */ snort-2.9.15.1/src/output-plugins/spo_log_ascii.c0000644000175200017520000003053613571422607016643 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** Author(s): Martin Roesch ** Andrew R. Baker ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ /* spo_log_ascii * * Purpose: * * This output module provides the default packet logging funtionality * * Arguments: * * None. * * Effect: * * None. * * Comments: * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #ifdef HAVE_STRINGS_H #include #endif #ifndef WIN32 #include #include #include #endif /* ! WIN32 */ #include "spo_log_ascii.h" #include "plugbase.h" #include "spo_plugbase.h" #include "parser.h" #include "snort_debug.h" #include "decode.h" #include "event.h" #include "log.h" #include "util.h" #include "snort.h" /* external globals from rules.c */ extern OptTreeNode *otn_tmp; /* internal functions */ static void LogAsciiInit(struct _SnortConfig *, char *args); static void LogAscii(Packet *p, const char *msg, void *arg, Event *event); static void LogAsciiCleanExit(int signal, void *arg); static char *IcmpFileName(Packet * p); static FILE *OpenLogFile(int mode, Packet * p); #define DUMP 1 #define BOGUS 2 #define NON_IP 3 #define ARP 4 #define GENERIC_LOG 5 void LogAsciiSetup(void) { /* link the preprocessor keyword to the init function in the preproc list */ RegisterOutputPlugin("log_ascii", OUTPUT_TYPE_FLAG__LOG, LogAsciiInit); DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Output: LogAscii is setup\n");); } static void LogAsciiInit(struct _SnortConfig *sc, char *args) { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Output: Ascii logging initialized\n");); /* Set the preprocessor function into the function list */ AddFuncToOutputList(sc, LogAscii, OUTPUT_TYPE__LOG, NULL); AddFuncToCleanExitList(LogAsciiCleanExit, NULL); } static void LogAscii(Packet *p, const char *msg, void *arg, Event *event) { FILE *log_ptr = NULL; DEBUG_WRAP(DebugMessage(DEBUG_LOG, "LogPkt started\n");); if(p) { if(IPH_IS_VALID(p)) log_ptr = OpenLogFile(0, p); #ifndef NO_NON_ETHER_DECODER else if(p->ah) log_ptr = OpenLogFile(ARP, p); #endif else log_ptr = OpenLogFile(NON_IP, p); } else log_ptr = OpenLogFile(GENERIC_LOG, p); if(!log_ptr) FatalError("Unable to open packet log file\n"); if(msg) { fwrite("[**] ", 5, 1, log_ptr); /* * Protect against potential log injection, * check for delimiters and newlines in msg */ if( !strstr(msg,"[**]") && !strchr(msg,'\n') ) { fwrite(msg, strlen(msg), 1, log_ptr); } fwrite(" [**]\n", 6, 1, log_ptr); } if(p) { if(IPH_IS_VALID(p)) PrintIPPkt(log_ptr, GET_IPH_PROTO(p), p); #ifndef NO_NON_ETHER_DECODER else if(p->ah) PrintArpHeader(log_ptr, p); #endif } if(log_ptr) fclose(log_ptr); } static void LogAsciiCleanExit(int signal, void *arg) { return; } static char *logfile[] = { "", "PACKET_FRAG", "PACKET_BOGUS", "PACKET_NONIP", "ARP", "log" }; /* * Function: OpenLogFile() * * Purpose: Create the log directory and file to put the packet log into. * This function sucks, I've got to find a better way to do this * this stuff. * * Arguments: None. * * Returns: FILE pointer on success, else NULL */ static FILE *OpenLogFile(int mode, Packet * p) { char log_path[STD_BUF]; /* path to log file */ char log_file[STD_BUF]; /* name of log file */ char proto[5]; /* logged packet protocol */ char suffix[5]; /* filename suffix */ FILE *log_ptr = NULL; sfaddr_t* ip; #ifdef WIN32 SnortStrncpy(suffix, ".ids", sizeof(suffix)); #else suffix[0] = '\0'; #endif /* zero out our buffers */ memset((char *) log_path, 0, STD_BUF); memset((char *) log_file, 0, STD_BUF); memset((char *) proto, 0, 5); if (mode == GENERIC_LOG || mode == DUMP || mode == BOGUS || mode == NON_IP || mode == ARP) { SnortSnprintf(log_file, STD_BUF, "%s/%s", snort_conf->log_dir, logfile[mode]); log_ptr = fopen(log_file, "a"); if (!log_ptr) { FatalError("OpenLogFile() => fopen(%s) log file: %s\n", log_file, strerror(errno)); } return log_ptr; } if(otn_tmp != NULL) { if(otn_tmp->logto != NULL) { SnortSnprintf(log_file, STD_BUF, "%s/%s", snort_conf->log_dir, otn_tmp->logto); log_ptr = fopen(log_file, "a"); if (!log_ptr) { FatalError("OpenLogFile() => fopen(%s) log file: %s\n", log_file, strerror(errno)); } return log_ptr; } } ip = GET_DST_IP(p); if(sfip_contains(&snort_conf->homenet, ip) == SFIP_CONTAINS) { if(sfip_contains(&snort_conf->homenet, ip) == SFIP_CONTAINS) { SnortSnprintf(log_path, STD_BUF, "%s/%s", snort_conf->log_dir, inet_ntoa(GET_SRC_ADDR(p))); } else { if(p->sp >= p->dp) { SnortSnprintf(log_path, STD_BUF, "%s/%s", snort_conf->log_dir, inet_ntoa(GET_SRC_ADDR(p))); } else { SnortSnprintf(log_path, STD_BUF, "%s/%s", snort_conf->log_dir, inet_ntoa(GET_DST_ADDR(p))); } } } else { ip = GET_SRC_IP(p); if(sfip_contains(&snort_conf->homenet, ip) == SFIP_CONTAINS) { SnortSnprintf(log_path, STD_BUF, "%s/%s", snort_conf->log_dir, inet_ntoa(GET_DST_ADDR(p))); } else { if(p->sp >= p->dp) { SnortSnprintf(log_path, STD_BUF, "%s/%s", snort_conf->log_dir, inet_ntoa(GET_SRC_ADDR(p))); } else { SnortSnprintf(log_path, STD_BUF, "%s/%s", snort_conf->log_dir, inet_ntoa(GET_DST_ADDR(p))); } } } DEBUG_WRAP(DebugMessage(DEBUG_FLOW, "Creating directory: %s\n", log_path);); /* build the log directory */ if(mkdir(log_path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) { if(errno != EEXIST) { FatalError("OpenLogFile() => mkdir(%s) log directory: %s\n", log_path, strerror(errno)); } } DEBUG_WRAP(DebugMessage(DEBUG_FLOW, "Directory Created!\n");); /* build the log filename */ if(GET_IPH_PROTO(p) == IPPROTO_TCP || GET_IPH_PROTO(p) == IPPROTO_UDP) { if(p->frag_flag) { SnortSnprintf(log_file, STD_BUF, "%s/IP_FRAG%s", log_path, suffix); } else { if(p->sp >= p->dp) { #ifdef WIN32 SnortSnprintf(log_file, STD_BUF, "%s/%s_%d-%d%s", log_path, protocol_names[GET_IPH_PROTO(p)], p->sp, p->dp, suffix); #else SnortSnprintf(log_file, STD_BUF, "%s/%s:%d-%d%s", log_path, protocol_names[GET_IPH_PROTO(p)], p->sp, p->dp, suffix); #endif } else { #ifdef WIN32 SnortSnprintf(log_file, STD_BUF, "%s/%s_%d-%d%s", log_path, protocol_names[GET_IPH_PROTO(p)], p->dp, p->sp, suffix); #else SnortSnprintf(log_file, STD_BUF, "%s/%s:%d-%d%s", log_path, protocol_names[GET_IPH_PROTO(p)], p->dp, p->sp, suffix); #endif } } } else { if(p->frag_flag) { SnortSnprintf(log_file, STD_BUF, "%s/IP_FRAG%s", log_path, suffix); } else { if (GET_IPH_PROTO(p) == IPPROTO_ICMP) { SnortSnprintf(log_file, STD_BUF, "%s/%s_%s%s", log_path, "ICMP", IcmpFileName(p), suffix); } else { SnortSnprintf(log_file, STD_BUF, "%s/PROTO%d%s", log_path, GET_IPH_PROTO(p), suffix); } } } DEBUG_WRAP(DebugMessage(DEBUG_FLOW, "Opening file: %s\n", log_file);); /* finally open the log file */ log_ptr = fopen(log_file, "a"); if (!log_ptr) { FatalError("OpenLogFile() => fopen(%s) log file: %s\n", log_file, strerror(errno)); } DEBUG_WRAP(DebugMessage(DEBUG_FLOW, "File opened...\n");); return log_ptr; } /**************************************************************************** * * Function: IcmpFileName(Packet *p) * * Purpose: Set the filename of an ICMP output log according to its type * * Arguments: p => Packet data struct * * Returns: the name of the file to set * ***************************************************************************/ static char *IcmpFileName(Packet * p) { if(p->icmph == NULL) { return "ICMP_TRUNC"; } switch(p->icmph->type) { case ICMP_ECHOREPLY: return "ECHO_REPLY"; case ICMP_DEST_UNREACH: switch(p->icmph->code) { case ICMP_NET_UNREACH: return "NET_UNRCH"; case ICMP_HOST_UNREACH: return "HST_UNRCH"; case ICMP_PROT_UNREACH: return "PROTO_UNRCH"; case ICMP_PORT_UNREACH: return "PORT_UNRCH"; case ICMP_FRAG_NEEDED: return "UNRCH_FRAG_NEEDED"; case ICMP_SR_FAILED: return "UNRCH_SOURCE_ROUTE_FAILED"; case ICMP_NET_UNKNOWN: return "UNRCH_NETWORK_UNKNOWN"; case ICMP_HOST_UNKNOWN: return "UNRCH_HOST_UNKNOWN"; case ICMP_HOST_ISOLATED: return "UNRCH_HOST_ISOLATED"; case ICMP_PKT_FILTERED_NET: return "UNRCH_PKT_FILTERED_NET"; case ICMP_PKT_FILTERED_HOST: return "UNRCH_PKT_FILTERED_HOST"; case ICMP_NET_UNR_TOS: return "UNRCH_NET_UNR_TOS"; case ICMP_HOST_UNR_TOS: return "UNRCH_HOST_UNR_TOS"; case ICMP_PKT_FILTERED: return "UNRCH_PACKET_FILT"; case ICMP_PREC_VIOLATION: return "UNRCH_PREC_VIOL"; case ICMP_PREC_CUTOFF: return "UNRCH_PREC_CUTOFF"; default: return "UNKNOWN"; } case ICMP_SOURCE_QUENCH: return "SRC_QUENCH"; case ICMP_REDIRECT: return "REDIRECT"; case ICMP_ECHO: return "ECHO"; case ICMP_TIME_EXCEEDED: return "TTL_EXCEED"; case ICMP_PARAMETERPROB: return "PARAM_PROB"; case ICMP_TIMESTAMP: return "TIMESTAMP"; case ICMP_TIMESTAMPREPLY: return "TIMESTAMP_RPL"; case ICMP_INFO_REQUEST: return "INFO_REQ"; case ICMP_INFO_REPLY: return "INFO_RPL"; case ICMP_ADDRESS: return "ADDR"; case ICMP_ADDRESSREPLY: return "ADDR_RPL"; default: return "UNKNOWN"; } } snort-2.9.15.1/src/output-plugins/spo_log_ascii.h0000644000175200017520000000211113571422607016634 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** ** Author(s): Andrew R. Baker ** ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifndef __SPO_LOG_ASCII_H__ #define __SPO_LOG_ASCII_H__ void LogAsciiSetup(void); #endif /* __SPO_LOG_ASCII_H__ */ snort-2.9.15.1/src/output-plugins/spo_alert_sf_socket.h0000644000175200017520000000202513571422607020056 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2003-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __SPO_ALERT_SF_SOCKET_H__ #define __SPO_ALERT_SF_SOCKET_H__ void AlertSFSocket_Setup(void); #endif /* __SPO_ALERT_SF_SOCKET_H__ */ snort-2.9.15.1/src/output-plugins/spo_alert_sf_socket.c0000644000175200017520000003141713571422607020060 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2003-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ /* We use some Linux only socket capabilities */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef LINUX #include "sf_types.h" #include "spo_plugbase.h" #include "plugbase.h" #include "event.h" #include "rules.h" #include "treenodes.h" #include "snort_debug.h" #include "util.h" #include "sfPolicy.h" #include #include #include #include #include "generators.h" #include "snort.h" #include "parser.h" /* error result codes */ #define SNORT_SUCCESS 0 #define SNORT_EINVAL 1 #define SNORT_ENOENT 2 #define SNORT_ENOMEM 3 static int configured = 0; static int connected = 0; static int sock = -1; static struct sockaddr_un sockAddr; typedef struct _SnortActionRequest { uint32_t event_id; uint32_t tv_sec; uint32_t generator; uint32_t sid; uint32_t src_ip; uint32_t dest_ip; uint16_t sport; uint16_t dport; uint8_t protocol; } SnortActionRequest; /* For the list of GID/SIDs that are used by the * Finalize routine. */ typedef struct _AlertSFSocketGidSid { uint32_t sidValue; uint32_t gidValue; struct _AlertSFSocketGidSid *next; } AlertSFSocketGidSid; static AlertSFSocketGidSid *sid_list = NULL; static void AlertSFSocket_Init(struct _SnortConfig *, char *args); static void AlertSFSocketSid_Init(struct _SnortConfig *, char *args); void AlertSFSocketSid_InitFinalize(struct _SnortConfig *sc, int unused, void *also_unused); void AlertSFSocket(Packet *packet, const char *msg, void *arg, Event *event); static int AlertSFSocket_Connect(void); static OptTreeNode *OptTreeNode_Search(uint32_t gid, uint32_t sid); static int SignatureAddOutputFunc(uint32_t gid, uint32_t sid, void (*outputFunc)(Packet *, const char *, void *, Event *), void *args); int String2ULong(char *string, unsigned long *result); void AlertSFSocket_Setup(void) { RegisterOutputPlugin("alert_sf_socket", OUTPUT_TYPE_FLAG__ALERT, AlertSFSocket_Init); RegisterOutputPlugin("alert_sf_socket_sid", OUTPUT_TYPE_FLAG__ALERT, AlertSFSocketSid_Init); DEBUG_WRAP(DebugMessage(DEBUG_INIT,"Output plugin: AlertSFSocket " "registered\n");); } /* this is defined in linux/un.h (see aldo sys/un.h) */ #ifndef UNIX_PATH_MAX #define UNIX_PATH_MAX 108 #endif static void AlertSFSocket_Init(struct _SnortConfig *sc, char *args) { /* process argument */ char *sockname; if(!args) FatalError("AlertSFSocket: must specify a socket name\n"); sockname = (char*)args; if(strlen(sockname) == 0) FatalError("AlertSFSocket: must specify a socket name\n"); if(strlen(sockname) > UNIX_PATH_MAX - 1) FatalError("AlertSFSocket: socket name must be less than %i " "characters\n", UNIX_PATH_MAX - 1); /* create socket */ if((sock = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) { FatalError("Unable to create socket: %s\n", strerror(errno)); } memset(&sockAddr, 0, sizeof(sockAddr)); sockAddr.sun_family = AF_UNIX; memcpy(sockAddr.sun_path + 1, sockname, strlen(sockname)); if(AlertSFSocket_Connect() == 0) connected = 1; configured = 1; } /* * Parse 'sidValue' or 'gidValue:sidValue' */ int GidSid2UInt(char * args, uint32_t * sidValue, uint32_t * gidValue) { char gbuff[80]; char sbuff[80]; int i; unsigned long glong,slong; *gidValue=GENERATOR_SNORT_ENGINE; *sidValue=0; i=0; while( args && *args && (i < 20) ) { sbuff[i]=*args; if( sbuff[i]==':' ) break; args++; i++; } sbuff[i]=0; if( i >= 20 ) { return SNORT_EINVAL; } if( *args == ':' ) { memcpy(gbuff,sbuff,i); gbuff[i]=0; if(String2ULong(gbuff,&glong)) { return SNORT_EINVAL; } *gidValue = (uint32_t)glong; args++; i=0; while( args && *args && i < 20 ) { sbuff[i]=*args; args++; i++; } sbuff[i]=0; if( i >= 20 ) { return SNORT_EINVAL; } if(String2ULong(sbuff,&slong)) { return SNORT_EINVAL; } *sidValue = (uint32_t)slong; } else { if(String2ULong(sbuff,&slong)) { return SNORT_EINVAL; } *sidValue=(uint32_t)slong; } return SNORT_SUCCESS; } static void AlertSFSocketSid_Init(struct _SnortConfig *sc, char *args) { uint32_t sidValue; uint32_t gidValue; AlertSFSocketGidSid *new_sid = NULL; /* check configured value */ if(!configured) FatalError("AlertSFSocket must be configured before attaching it to a " "sid"); if (GidSid2UInt((char*)args, &sidValue, &gidValue) ) FatalError("Invalid argument '%s' to alert_sf_socket_sid\n", args); new_sid = (AlertSFSocketGidSid *)SnortAlloc(sizeof(AlertSFSocketGidSid)); new_sid->sidValue = sidValue; new_sid->gidValue = gidValue; if (sid_list) { /* Add this one to the front. */ new_sid->next = sid_list; } else { AddFuncToPostConfigList(sc, AlertSFSocketSid_InitFinalize, NULL); } sid_list = new_sid; } void AlertSFSocketSid_InitFinalize(struct _SnortConfig *sc, int unused, void *also_unused) { AlertSFSocketGidSid *new_sid = sid_list; AlertSFSocketGidSid *next_sid; uint32_t sidValue; uint32_t gidValue; int rval = 0; while (new_sid) { sidValue = new_sid->sidValue; gidValue = new_sid->gidValue; rval = SignatureAddOutputFunc( (uint32_t)gidValue, (uint32_t)sidValue, AlertSFSocket, NULL ); switch(rval) { case SNORT_SUCCESS: DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "SFSocket output enabled for " "sid %u.\n", sidValue);); break; case SNORT_EINVAL: DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Invalid argument " "attempting to attach output for sid %u.\n", sidValue);); break; case SNORT_ENOENT: LogMessage("No entry found. SFSocket output not enabled for " "sid %u.\n", sidValue); break; case SNORT_ENOMEM: FatalError("Out of memory"); break; } /* Save ptr to next one in the list */ next_sid = new_sid->next; /* Free the current one, not needed any more */ free(new_sid); /* Reset the list */ sid_list = new_sid = next_sid; } } static int AlertSFSocket_Connect(void) { /* check sock value */ if(sock == -1) FatalError("AlertSFSocket: Invalid socket\n"); if(connect(sock, (struct sockaddr *)&sockAddr, sizeof(sockAddr)) == -1) { if(errno == ECONNREFUSED || errno == ENOENT) { LogMessage("WARNING: AlertSFSocket: Unable to connect to socket: " "%s.\n", strerror(errno)); return 1; } else { FatalError("AlertSFSocket: Unable to connect to socket " "(%i): %s\n", errno, strerror(errno)); } } return 0; } static SnortActionRequest sar; void AlertSFSocket(Packet *packet, const char *msg, void *arg, Event *event) { int tries = 0; if(!event || !packet || !IPH_IS_VALID(packet)) return; // for now, only support ip4 if ( !IS_IP4(packet) ) return; /* construct the action request */ sar.event_id = event->event_id; sar.tv_sec = packet->pkth->ts.tv_sec; sar.generator = event->sig_generator; sar.sid = event->sig_id; // when ip6 is supported: // * suggest TLV format where T == family, L is implied by // T (and not sent), and V is just the address octets in // network order // * if T is made the 1st octet of struct, bytes to read // can be determined by reading 1 byte // * addresses could be moved to end of struct in uint8_t[32] // and only 1st 8 used for ip4 sar.src_ip = ntohl(sfaddr_get_ip4_value(GET_SRC_IP(packet))); sar.dest_ip = ntohl(sfaddr_get_ip4_value(GET_DST_IP(packet))); sar.protocol = GET_IPH_PROTO(packet); if(sar.protocol == IPPROTO_UDP || sar.protocol == IPPROTO_TCP) { sar.sport = packet->sp; sar.dport = packet->dp; } else { sar.sport = 0; sar.dport = 0; } DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"AlertSFSocket fired for sid %u\n", event->sig_id);); do { tries++; /* connect as needed */ if(!connected) { if(AlertSFSocket_Connect() != 0) break; connected = 1; } /* send request */ if(send(sock, &sar, sizeof(sar), 0) == sizeof(sar)) { /* success */ return; } /* send failed */ if(errno == ENOBUFS) { LogMessage("ERROR: AlertSFSocket: out of buffer space\n"); break; } else if(errno == ECONNRESET) { connected = 0; LogMessage("WARNING: AlertSFSocket: connection reset, will attempt " "to reconnect.\n"); } else if(errno == ECONNREFUSED) { LogMessage("WARNING: AlertSFSocket: connection refused, " "will attempt to reconnect.\n"); connected = 0; } else if(errno == ENOTCONN) { LogMessage("WARNING: AlertSFSocket: not connected, " "will attempt to reconnect.\n"); connected = 0; } else { LogMessage("ERROR: AlertSFSocket: unhandled error '%i' in send(): " "%s\n", errno, strerror(errno)); connected = 0; } } while(tries <= 1); LogMessage("ERROR: AlertSFSocket: Alert not sent\n"); return; } static int SignatureAddOutputFunc( uint32_t gid, uint32_t sid, void (*outputFunc)(Packet *, const char *, void *, Event *), void *args) { OptTreeNode *optTreeNode = NULL; OutputFuncNode *outputFuncs = NULL; if(!outputFunc) return SNORT_EINVAL; /* Invalid argument */ if(!(optTreeNode = OptTreeNode_Search(gid,sid))) { LogMessage("Unable to find OptTreeNode for SID %u\n", sid); return SNORT_ENOENT; } if(!(outputFuncs = (OutputFuncNode *)calloc(1, sizeof(OutputFuncNode)))) { LogMessage("Out of memory adding output function to SID %u\n", sid); return SNORT_ENOMEM; } outputFuncs->func = outputFunc; outputFuncs->arg = args; outputFuncs->next = optTreeNode->outputFuncs; optTreeNode->outputFuncs = outputFuncs; return SNORT_SUCCESS; } /* search for an OptTreeNode by sid in specific policy*/ static OptTreeNode *OptTreeNode_Search(uint32_t gid, uint32_t sid) { SFGHASH_NODE *hashNode; OptTreeNode *otn = NULL; RuleTreeNode *rtn = NULL; if(sid == 0) return NULL; for (hashNode = sfghash_findfirst(snort_conf->otn_map); hashNode; hashNode = sfghash_findnext(snort_conf->otn_map)) { otn = (OptTreeNode *)hashNode->data; rtn = getRuntimeRtnFromOtn(otn); if (rtn) { if ((rtn->proto == IPPROTO_TCP) || (rtn->proto == IPPROTO_UDP) || (rtn->proto == IPPROTO_ICMP) || (rtn->proto == ETHERNET_TYPE_IP)) { if (otn->sigInfo.id == sid) { return otn; } } } } return NULL; } int String2ULong(char *string, unsigned long *result) { unsigned long value; char *endptr; if(!string) return -1; value = strtoul(string, &endptr, 10); if(*endptr != '\0') return -1; *result = value; return 0; } #endif /* LINUX */ snort-2.9.15.1/src/output-plugins/spo_alert_test.c0000644000175200017520000002057513571422607017062 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2007-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ /* spo_alert_test_ * * Purpose: output plugin for test alerting * * Arguments: file , stdout, rebuilt, session, msg * arguments should be comma delimited. * file - specifiy alert file * stdout - no alert file, just print to screen * rebuilt - include info of whether packet was rebuilt or not * S - Stream rebuilt * F - IP frag rebuilt * outputs: : * session - include src/dst IPs and ports * outputs: :-: * msg - include alert message * * Output is tab delimited in the following order: * packet count, gid, sid, rev, msg, session, rebuilt * * Examples: * output alert_test * output alert_test: session * output alert_test: session, msg * output alert_test: rebuilt, session, msg * output alert_test: stdout, rebuilt, session, msg * output alert_test: file test.alert, rebuilt, session, msg * * Effect: * * Alerts are written to a file in the snort test alert format * * Comments: Allows use of test alerts with other output plugin types * */ /* output plugin header file */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sf_types.h" #include "event.h" #include "decode.h" #include "snort_debug.h" #include "plugbase.h" #include "spo_plugbase.h" #include "parser.h" #include "util.h" #include "log.h" #include "mstring.h" #include "snort.h" #include "spo_alert_test.h" #include #include #include #ifdef HAVE_STRINGS_H #include #endif #ifndef WIN32 #include #include #include #endif /* !WIN32 */ #include #define TEST_FLAG_FILE 0x01 #define TEST_FLAG_STDOUT 0x02 #define TEST_FLAG_MSG 0x04 #define TEST_FLAG_SESSION 0x08 #define TEST_FLAG_REBUILT 0x10 typedef struct _SpoAlertTestData { FILE *file; uint8_t flags; } SpoAlertTestData; void AlertTestInit(struct _SnortConfig *, char *); SpoAlertTestData *ParseAlertTestArgs(struct _SnortConfig *, char *); void AlertTestCleanExitFunc(int, void *); void AlertTest(Packet *, const char *, void *, Event *); extern PacketCount pc; /* * Function: SetupAlertTest() * * 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. * * Arguments: None. * * Returns: void function * */ void AlertTestSetup(void) { /* link the preprocessor keyword to the init function in the preproc list */ RegisterOutputPlugin("alert_test", OUTPUT_TYPE_FLAG__ALERT, AlertTestInit); DEBUG_WRAP(DebugMessage(DEBUG_INIT,"Output plugin: AlertTest is setup...\n");); } /* * Function: AlertTestInit(char *) * * 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 AlertTestInit(struct _SnortConfig *sc, char *args) { SpoAlertTestData *data; DEBUG_WRAP(DebugMessage(DEBUG_INIT,"Output: AlertTest Initialized\n");); /* parse the argument list from the rules file */ data = ParseAlertTestArgs(sc, args); DEBUG_WRAP(DebugMessage(DEBUG_INIT,"Linking AlertTest functions to call lists...\n");); /* Set the preprocessor function into the function list */ AddFuncToOutputList(sc, AlertTest, OUTPUT_TYPE__ALERT, data); AddFuncToCleanExitList(AlertTestCleanExitFunc, data); } void AlertTest(Packet *p, const char *msg, void *arg, Event *event) { SpoAlertTestData *data; if (p == NULL || arg == NULL) return; data = (SpoAlertTestData *)arg; fprintf(data->file, "" STDu64 "\t", pc.total_from_daq); if (event != NULL) { fprintf(data->file, "%lu\t%lu\t%lu\t", (unsigned long) event->sig_generator, (unsigned long) event->sig_id, (unsigned long) event->sig_rev); } if (data->flags & TEST_FLAG_MSG) { if (msg != NULL) fprintf(data->file, "%s\t", msg); } if (data->flags & TEST_FLAG_SESSION) PrintIpAddrs(data->file, p); if (data->flags & TEST_FLAG_REBUILT) { if (p->packet_flags & PKT_REBUILT_FRAG) fprintf(data->file, "F:" STDu64 "\t", pc.rebuilt_frags); else if (p->packet_flags & PKT_REBUILT_STREAM) fprintf(data->file, "S:" STDu64 "\t", pc.rebuilt_tcp); } fprintf(data->file, "\n"); fflush(data->file); } /* * Function: ParseAlertTestArgs(char *) * * Purpose: Process the preprocessor arguements from the rules file and * initialize the preprocessor's data struct. This function doesn't * have to exist if it makes sense to parse the args in the init * function. * * Arguments: args => argument list * * Returns: void function * */ SpoAlertTestData * ParseAlertTestArgs(struct _SnortConfig *sc, char *args) { char **toks; int num_toks; SpoAlertTestData *data; int i; data = (SpoAlertTestData *)SnortAlloc(sizeof(SpoAlertTestData)); if (args == NULL) { data->file = OpenAlertFile(NULL); data->flags |= TEST_FLAG_FILE; return data; } DEBUG_WRAP(DebugMessage(DEBUG_LOG, "ParseAlertTestArgs: %s\n", args);); toks = mSplit(args, ",", 0, &num_toks, 0); for (i = 0; i < num_toks; i++) { char *option; char **atoks; int num_atoks; atoks = mSplit(toks[i], " ", 0, &num_atoks, 0); option = atoks[0]; if (!strcasecmp("stdout", option)) { if (data->flags & TEST_FLAG_FILE) ParseError("alert_test: cannot specify both stdout and file\n"); data->file = stdout; data->flags |= TEST_FLAG_STDOUT; } else if (!strcasecmp("session", option)) { data->flags |= TEST_FLAG_SESSION; } else if (!strcasecmp("rebuilt", option)) { data->flags |= TEST_FLAG_REBUILT; } else if (!strcasecmp("msg", option)) { data->flags |= TEST_FLAG_MSG; } else if (!strcasecmp("file", option)) { if (data->flags & TEST_FLAG_STDOUT) ParseError("alert_test: cannot specify both stdout and file\n"); data->flags |= TEST_FLAG_FILE; if (num_atoks == 1) { data->file = OpenAlertFile(NULL); } else if (num_atoks == 2) { char *outfile = ProcessFileOption(sc, atoks[1]); data->file = OpenAlertFile(outfile); free(outfile); } else { ParseError("Invalid \"file\" argument to alert_test: %s", option); } } else { ParseError("Unrecognized alert_test option: %s\n", option); } mSplitFree(&atoks, num_atoks); } /* free toks */ mSplitFree(&toks, num_toks); /* didn't get stdout or a file to log to */ if (!(data->flags & (TEST_FLAG_STDOUT | TEST_FLAG_FILE))) { data->file = OpenAlertFile(NULL); data->flags |= TEST_FLAG_FILE; } return data; } void AlertTestCleanExitFunc(int signal, void *arg) { SpoAlertTestData *data = (SpoAlertTestData *)arg; /* close alert file */ DEBUG_WRAP(DebugMessage(DEBUG_LOG,"AlertTestCleanExitFunc\n");); fclose(data->file); /*free memory from SpoAlertTestData */ free(data); } snort-2.9.15.1/src/output-plugins/spo_alert_test.h0000644000175200017520000000240613571422607017060 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2007-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ /* This file gets included in plugbase.h when it is integrated into the rest * of the program. Sometime in The Future, I'll whip up a bad ass Perl script * to handle automatically loading all the required info into the plugbase.* * files. */ #ifndef __SPO_ALERT_TEST_H__ #define __SPO_ALERT_TEST_H__ void AlertTestSetup(void); #endif /* __SPO_ALERT_FAST_H__ */ snort-2.9.15.1/src/output-plugins/spo_log_buffer_dump.c0000644000175200017520000002331613571422607020047 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** Author: Rahul Burman ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ /* spo_log_buffer_dump * * Purpose: * * This module is used to dump the buffers used by preprocessors during * packet inspection * * Arguments: filename to which buffers are to be dumped * * Effect: None * * Comments: * */ #ifdef DUMP_BUFFER #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "spo_log_buffer_dump.h" #include "decode.h" #include "event.h" #include "plugbase.h" #include "spo_plugbase.h" #include "parser.h" #include "snort_debug.h" #include "preprocids.h" #include "log_text.h" #include "snort.h" #include "strvec.h" #define DEFAULT_FILE "stdout" #define LIMIT (128*M_BYTES) #define LOG_BUFFER (4*K_BYTES) static int maxBuffers[MAX_BUFFER_DUMP_FUNC] = { MAX_HTTP_BUFFER_DUMP, MAX_SMTP_BUFFER_DUMP, MAX_SIP_BUFFER_DUMP, MAX_DNP3_BUFFER_DUMP, MAX_POP_BUFFER_DUMP, MAX_MODBUS_BUFFER_DUMP, MAX_SSH_BUFFER_DUMP, MAX_DNS_BUFFER_DUMP, MAX_DCERPC2_BUFFER_DUMP, MAX_FTPTELNET_BUFFER_DUMP, MAX_IMAP_BUFFER_DUMP, MAX_SSL_BUFFER_DUMP, MAX_GTP_BUFFER_DUMP }; typedef struct _SpoLogBufferDumpData { TextLog* log; } SpoLogBufferDumpData; /* list of function prototypes for this output plugin */ static void LogBufferDumpInit(struct _SnortConfig *, char *); static SpoLogBufferDumpData *InitializeLogBufferDumpOutputStream(SnortConfig *); static void LogBufferDump(Packet *, const char *, void *, Event *); static void LogBufferDumpCleanExitFunc(int, void *); void LogBufferDumpSetup(void) { /* link the preprocessor keyword to the init function in the preproc list */ RegisterOutputPlugin("log_buffer_dump", OUTPUT_TYPE_FLAG__LOG, LogBufferDumpInit); DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Output plugin: LogBufferDump is setup...\n");); } static void LogBufferDumpInit(struct _SnortConfig *sc, char *args) { SpoLogBufferDumpData *data; DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Output: LogBufferDump Initialized\n");); /* parse the argument list from the rules file */ data = InitializeLogBufferDumpOutputStream(sc); /* Set the preprocessor function into the function list */ AddFuncToOutputList(sc, LogBufferDump, OUTPUT_TYPE__LOG, data); AddBDFuncToOutputList(sc, LogBufferDump, OUTPUT_TYPE__LOG, data); AddFuncToCleanExitList(LogBufferDumpCleanExitFunc, data); } /* * Function: InitializeLogBufferDumpOutputStream(SnortConfig *) * * Purpose: Initialize the output stream to which buffers will be dumped. * * Arguments: args => SnortConfig * * Returns: SpoLogBufferDumpData */ static SpoLogBufferDumpData *InitializeLogBufferDumpOutputStream(SnortConfig *sc) { SpoLogBufferDumpData *data; char* filename = NULL; DEBUG_WRAP(DebugMessage(DEBUG_LOG, "Output: LogBufferDump output stream initialized\n");); data = (SpoLogBufferDumpData *)SnortAlloc(sizeof(SpoLogBufferDumpData)); if ( !data ) { FatalError("log buffer dump: unable to allocate memory!\n"); } const char** dump_file = StringVector_GetVector(sc->buffer_dump_file); if (dump_file && dump_file[0]) filename = SnortStrdup(dump_file[0]); else filename = SnortStrdup(DEFAULT_FILE); data->log = TextLog_Init(filename, LOG_BUFFER, LIMIT); if (filename != NULL) free(filename); return data; } static void LogBufferDump(Packet *p, const char *msg, void *arg, Event *event) { // dump the buffers used during packet processing dumped_state = true; SpoLogBufferDumpData *data = (SpoLogBufferDumpData *)arg; TextLog_Puts(data->log, "\n=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+\n"); if (ScOutputAppData() && (p->dsize > 0) && PacketWasCooked(p)) { switch ( p->pseudo_type ) { case PSEUDO_PKT_SMB_SEG: TextLog_Print(data->log, "\n%s", "SMB desegmented packet:"); break; case PSEUDO_PKT_DCE_SEG: TextLog_Print(data->log, "\n%s", "DCE/RPC desegmented packet:"); break; case PSEUDO_PKT_DCE_FRAG: TextLog_Print(data->log, "\n%s", "DCE/RPC defragmented packet:"); break; case PSEUDO_PKT_SMB_TRANS: TextLog_Print(data->log, "\n%s", "SMB Transact reassembled packet:"); break; case PSEUDO_PKT_DCE_RPKT: TextLog_Print(data->log, "\n%s", "DCE/RPC reassembled packet:"); break; case PSEUDO_PKT_TCP: TextLog_Print(data->log, "\n%s", "Stream Reassembled Packet:\n"); break; case PSEUDO_PKT_IP: TextLog_Print(data->log, "\n%s", "Frag reassembled packet:"); break; default: // FIXTHIS do we get here for portscan or sdf? break; } } else { TextLog_Print(data->log, "\n%s", "Raw Packet:\n"); } LogTimeStamp(data->log, p); if(p && IPH_IS_VALID(p)) { if (ScOutputDataLink()) { Log2ndHeader(data->log, p); } LogIPHeader(data->log, p); if(!p->frag_flag) { switch(GET_IPH_PROTO(p)) { case IPPROTO_TCP: LogTCPHeader(data->log, p); break; case IPPROTO_UDP: LogUDPHeader(data->log, p); break; case IPPROTO_ICMP: LogICMPHeader(data->log, p); break; default: break; } } LogXrefs(data->log, 1); TextLog_Putc(data->log, '\n'); } TextLog_Flush(data->log); bool bufferDumpFlag = false; if (p->dsize) { TraceBuffer *bufs; int i, j; for (i = 0; i < MAX_BUFFER_DUMP_FUNC; i++) { if ((bdmask & (UINT64_C(1) << i)) && getBuffers[i]) { bufs = getBuffers[i](); if (bufs != NULL) { for (j = 0; j < maxBuffers[i]; j++) { if (bufs[j].length != 0) { if (!bufferDumpFlag) // To Print Dumping Buffers string only once { bufferDumpFlag = true; TextLog_Print(data->log, "\nDumping Buffers\n"); } if (event != NULL) { TextLog_Print(data->log, "%s [%lu:%lu:%lu]\n", (char *)"Event", (unsigned long) event->sig_generator, (unsigned long) event->sig_id, (unsigned long) event->sig_rev); } LogBuffer(data->log, bufs[j].buf_name, bufs[j].buf_content, bufs[j].length); // free the http buffers after logging if (i == HTTP_BUFFER_DUMP_FUNC) free(bufs[j].buf_content); bufs[j].buf_content = NULL; bufs[j].length = 0; } } } } } } if (!bufferDumpFlag) // No data available in all the files { TextLog_Print(data->log, "\nNo Buffers to Dump\n"); } } static void LogBufferDumpCleanup(int signal, void *arg, const char* msg) { SpoLogBufferDumpData *data = (SpoLogBufferDumpData *)arg; DEBUG_WRAP(DebugMessage(DEBUG_LOG, "%s\n", msg);); /* free memory from SpoLogBufferDumpData */ if ( data->log ) TextLog_Term(data->log); free(data); /* Checkout for any allocated HTTP buffers not freed yet */ TraceBuffer *bufs; int j; if ((bdmask & (UINT64_C(1) << HTTP_BUFFER_DUMP_FUNC)) && getBuffers[HTTP_BUFFER_DUMP_FUNC]) { bufs = getBuffers[HTTP_BUFFER_DUMP_FUNC](); if (bufs != NULL) { for (j = 0; j < maxBuffers[HTTP_BUFFER_DUMP_FUNC]; j++) { if (bufs[j].buf_content) { free(bufs[j].buf_content); bufs[j].buf_content = NULL; bufs[j].length = 0; } } } } } static void LogBufferDumpCleanExitFunc(int signal, void *arg) { LogBufferDumpCleanup(signal, arg, "LogBufferDumpCleanExit"); } #endif snort-2.9.15.1/src/output-plugins/spo_log_buffer_dump.h0000644000175200017520000000225513571422607020053 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** Author: Rahul Burman ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifndef __SPO_LOG_BUFFER_DUMP_H__ #define __SPO_LOG_BUFFER_DUMP_H__ #ifdef DUMP_BUFFER void LogBufferDumpSetup(void); #endif #endif /* __SPO_LOG_BUFFER_DUMP_H__ */ snort-2.9.15.1/src/detection-plugins/0000755000000000000000000000000013571426520014314 500000000000000snort-2.9.15.1/src/detection-plugins/Makefile.in0000644000000000000000000005500013571425503016301 00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 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@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd 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@ @BUILD_REACT_TRUE@am__append_1 = sp_react.c sp_react.h @BUILD_RESPOND3_TRUE@am__append_2 = sp_respond3.c sp_respond.h @FEAT_OPEN_APPID_TRUE@am__append_3 = sp_appid.c sp_appid.h subdir = src/detection-plugins DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LIBRARIES = $(noinst_LIBRARIES) ARFLAGS = cru AM_V_AR = $(am__v_AR_@AM_V@) am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) am__v_AR_0 = @echo " AR " $@; am__v_AR_1 = libspd_a_AR = $(AR) $(ARFLAGS) libspd_a_LIBADD = am__libspd_a_SOURCES_DIST = detection_options.c detection_options.h \ sp_asn1.c sp_asn1.h sp_asn1_detect.c sp_asn1_detect.h \ sp_byte_check.c sp_byte_check.h sp_byte_jump.c sp_byte_jump.h \ sp_byte_extract.c sp_byte_extract.h sp_byte_math.c \ sp_byte_math.h sp_clientserver.c sp_clientserver.h sp_cvs.c \ sp_cvs.h sp_dsize_check.c sp_dsize_check.h sp_flowbits.c \ sp_flowbits.h sp_ftpbounce.c sp_ftpbounce.h sp_hdr_opt_wrap.c \ sp_hdr_opt_wrap.h sp_icmp_code_check.c sp_icmp_code_check.h \ sp_icmp_id_check.c sp_icmp_id_check.h sp_icmp_seq_check.c \ sp_icmp_seq_check.h sp_icmp_type_check.c sp_icmp_type_check.h \ sp_ip_fragbits.c sp_ip_fragbits.h sp_ip_id_check.c \ sp_ip_id_check.h sp_ip_proto.c sp_ip_proto.h \ sp_ip_same_check.c sp_ip_same_check.h sp_ip_tos_check.c \ sp_ip_tos_check.h sp_ipoption_check.c sp_ipoption_check.h \ sp_isdataat.c sp_isdataat.h sp_pattern_match.c \ sp_pattern_match.h sp_pcre.c sp_pcre.h sp_replace.c \ sp_replace.h sp_rpc_check.c sp_rpc_check.h sp_session.c \ sp_session.h sp_tcp_ack_check.c sp_tcp_ack_check.h \ sp_tcp_flag_check.h sp_tcp_flag_check.c sp_tcp_seq_check.c \ sp_tcp_seq_check.h sp_tcp_win_check.c sp_tcp_win_check.h \ sp_ttl_check.c sp_ttl_check.h sp_urilen_check.c \ sp_urilen_check.h sp_file_data.c sp_file_data.h \ sp_base64_decode.c sp_base64_decode.h sp_base64_data.c \ sp_base64_data.h sp_pkt_data.c sp_pkt_data.h sp_file_type.c \ sp_file_type.h sp_react.c sp_react.h sp_respond3.c \ sp_respond.h sp_appid.c sp_appid.h @BUILD_REACT_TRUE@am__objects_1 = sp_react.$(OBJEXT) @BUILD_RESPOND3_TRUE@am__objects_2 = sp_respond3.$(OBJEXT) @FEAT_OPEN_APPID_TRUE@am__objects_3 = sp_appid.$(OBJEXT) am_libspd_a_OBJECTS = detection_options.$(OBJEXT) sp_asn1.$(OBJEXT) \ sp_asn1_detect.$(OBJEXT) sp_byte_check.$(OBJEXT) \ sp_byte_jump.$(OBJEXT) sp_byte_extract.$(OBJEXT) \ sp_byte_math.$(OBJEXT) sp_clientserver.$(OBJEXT) \ sp_cvs.$(OBJEXT) sp_dsize_check.$(OBJEXT) \ sp_flowbits.$(OBJEXT) sp_ftpbounce.$(OBJEXT) \ sp_hdr_opt_wrap.$(OBJEXT) sp_icmp_code_check.$(OBJEXT) \ sp_icmp_id_check.$(OBJEXT) sp_icmp_seq_check.$(OBJEXT) \ sp_icmp_type_check.$(OBJEXT) sp_ip_fragbits.$(OBJEXT) \ sp_ip_id_check.$(OBJEXT) sp_ip_proto.$(OBJEXT) \ sp_ip_same_check.$(OBJEXT) sp_ip_tos_check.$(OBJEXT) \ sp_ipoption_check.$(OBJEXT) sp_isdataat.$(OBJEXT) \ sp_pattern_match.$(OBJEXT) sp_pcre.$(OBJEXT) \ sp_replace.$(OBJEXT) sp_rpc_check.$(OBJEXT) \ sp_session.$(OBJEXT) sp_tcp_ack_check.$(OBJEXT) \ sp_tcp_flag_check.$(OBJEXT) sp_tcp_seq_check.$(OBJEXT) \ sp_tcp_win_check.$(OBJEXT) sp_ttl_check.$(OBJEXT) \ sp_urilen_check.$(OBJEXT) sp_file_data.$(OBJEXT) \ sp_base64_decode.$(OBJEXT) sp_base64_data.$(OBJEXT) \ sp_pkt_data.$(OBJEXT) sp_file_type.$(OBJEXT) $(am__objects_1) \ $(am__objects_2) $(am__objects_3) nodist_libspd_a_OBJECTS = sf_snort_plugin_hdropts.$(OBJEXT) libspd_a_OBJECTS = $(am_libspd_a_OBJECTS) $(nodist_libspd_a_OBJECTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = am__depfiles_maybe = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libspd_a_SOURCES) $(nodist_libspd_a_SOURCES) DIST_SOURCES = $(am__libspd_a_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CCONFIGFLAGS = @CCONFIGFLAGS@ CFLAGS = @CFLAGS@ CONFIGFLAGS = @CONFIGFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ ICONFIGFLAGS = @ICONFIGFLAGS@ INCLUDES = @INCLUDES@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LUA_CFLAGS = @LUA_CFLAGS@ LUA_LIBS = @LUA_LIBS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIGNAL_SNORT_DUMP_STATS = @SIGNAL_SNORT_DUMP_STATS@ SIGNAL_SNORT_READ_ATTR_TBL = @SIGNAL_SNORT_READ_ATTR_TBL@ SIGNAL_SNORT_RELOAD = @SIGNAL_SNORT_RELOAD@ SIGNAL_SNORT_ROTATE_STATS = @SIGNAL_SNORT_ROTATE_STATS@ STRIP = @STRIP@ VERSION = @VERSION@ XCCFLAGS = @XCCFLAGS@ YACC = @YACC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ 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@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luajit_CFLAGS = @luajit_CFLAGS@ luajit_LIBS = @luajit_LIBS@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = detection_leaf_node.c AUTOMAKE_OPTIONS = foreign no-dependencies noinst_LIBRARIES = libspd.a BUILT_SOURCES = sf_snort_plugin_hdropts.c \ sf_snort_packet.h \ sf_snort_plugin_api.h \ sf_decompression.h \ sf_decompression_define.h nodist_libspd_a_SOURCES = sf_snort_plugin_hdropts.c \ sf_snort_packet.h \ sf_snort_plugin_api.h \ sf_decompression.h \ sf_decompression_define.h libspd_a_SOURCES = detection_options.c detection_options.h sp_asn1.c \ sp_asn1.h sp_asn1_detect.c sp_asn1_detect.h sp_byte_check.c \ sp_byte_check.h sp_byte_jump.c sp_byte_jump.h \ sp_byte_extract.c sp_byte_extract.h sp_byte_math.c \ sp_byte_math.h sp_clientserver.c sp_clientserver.h sp_cvs.c \ sp_cvs.h sp_dsize_check.c sp_dsize_check.h sp_flowbits.c \ sp_flowbits.h sp_ftpbounce.c sp_ftpbounce.h sp_hdr_opt_wrap.c \ sp_hdr_opt_wrap.h sp_icmp_code_check.c sp_icmp_code_check.h \ sp_icmp_id_check.c sp_icmp_id_check.h sp_icmp_seq_check.c \ sp_icmp_seq_check.h sp_icmp_type_check.c sp_icmp_type_check.h \ sp_ip_fragbits.c sp_ip_fragbits.h sp_ip_id_check.c \ sp_ip_id_check.h sp_ip_proto.c sp_ip_proto.h \ sp_ip_same_check.c sp_ip_same_check.h sp_ip_tos_check.c \ sp_ip_tos_check.h sp_ipoption_check.c sp_ipoption_check.h \ sp_isdataat.c sp_isdataat.h sp_pattern_match.c \ sp_pattern_match.h sp_pcre.c sp_pcre.h sp_replace.c \ sp_replace.h sp_rpc_check.c sp_rpc_check.h sp_session.c \ sp_session.h sp_tcp_ack_check.c sp_tcp_ack_check.h \ sp_tcp_flag_check.h sp_tcp_flag_check.c sp_tcp_seq_check.c \ sp_tcp_seq_check.h sp_tcp_win_check.c sp_tcp_win_check.h \ sp_ttl_check.c sp_ttl_check.h sp_urilen_check.c \ sp_urilen_check.h sp_file_data.c sp_file_data.h \ sp_base64_decode.c sp_base64_decode.h sp_base64_data.c \ sp_base64_data.h sp_pkt_data.c sp_pkt_data.h sp_file_type.c \ sp_file_type.h $(am__append_1) $(am__append_2) $(am__append_3) copy_files = \ if test -f $$dst_file; then \ x=`diff $$src_file $$dst_file >> /dev/null`; \ if test "$$x" != "0"; then \ echo "Updating " $$dst_file; \ cp $$src_file $$dst_file; \ fi \ else \ echo "Updating " $$dst_file; \ cp $$src_file $$dst_file; \ fi sed_hdropts = \ sed -e "s/_ded.errMsg/ErrorMessage/g" \ -e "s/sf_snort_packet.h/decode.h/g" \ -e "s/SFSnortPacket/Packet/g" \ -e "s/ip4_header/iph/g" \ -e "s/tcp_header/tcph/g" \ -e "s/proto/ip_proto/g" \ -e "s/type_service/ip_tos/g" \ -e "s/time_to_live/ip_ttl/g" \ -e "s/num_ip_options/ip_option_count/g" \ -e "s/IPOptions/Options/g" \ -e "s/option_code/code/g" \ -e "s/acknowledgement/th_ack/g" \ -e "s/sequence/th_seq/g" \ -e "s/tcph->flags/tcph->th_flags/g" \ -e "s/tcph->window/tcph->th_win/g" \ -e "s/num_tcp_options/tcp_option_count/g" \ -e "s/icmp_header/icmph/g" \ -e "s/ICMP_ECHO_REPLY/ICMP_ECHOREPLY/g" \ -e "s/ICMP_ECHO_REQUEST/ICMP_ECHO/g" \ -e "s/icmph_union.echo.id/s_icmp_id/g" \ -e "s/icmph_union.echo.seq/s_icmp_seq/g" \ $$src_file > $$dst_file; all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/detection-plugins/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/detection-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: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libspd.a: $(libspd_a_OBJECTS) $(libspd_a_DEPENDENCIES) $(EXTRA_libspd_a_DEPENDENCIES) $(AM_V_at)-rm -f libspd.a $(AM_V_AR)$(libspd_a_AR) libspd.a $(libspd_a_OBJECTS) $(libspd_a_LIBADD) $(AM_V_at)$(RANLIB) libspd.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c .c.o: $(AM_V_CC)$(COMPILE) -c $< .c.obj: $(AM_V_CC)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: $(AM_V_CC)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files 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)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(LIBRARIES) installdirs: install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) 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: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libtool clean-local \ clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: 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: .MAKE: all check install install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-local clean-noinstLIBRARIES cscopelist-am \ ctags ctags-am 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-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am 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 tags-am uninstall uninstall-am sf_snort_plugin_hdropts.c: ../dynamic-plugins/sf_engine/sf_snort_plugin_hdropts.c @src_file=$?; dst_file=$@; $(sed_hdropts) sf_snort_plugin_api.h: ../dynamic-plugins/sf_engine/sf_snort_plugin_api.h @src_file=$?; dst_file=$@; $(copy_files) sf_decompression.h: ../dynamic-plugins/sf_engine/sf_decompression.h @src_file=$?; dst_file=$@; $(copy_files) sf_decompression_define.h: ../dynamic-plugins/sf_decompression_define.h @src_file=$?; dst_file=$@; $(copy_files) sf_snort_packet.h: ../dynamic-plugins/sf_engine/sf_snort_packet.h @src_file=$?; dst_file=$@; $(copy_files) clean-local: rm -rf sf_snort_plugin_hdropts.c sf_snort_packet.h sf_snort_plugin_api.h sf_decompression.h sf_decompression_define.h # 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: snort-2.9.15.1/src/detection-plugins/Makefile.am0000444000175200017520000000740013571422607016327 00000000000000## $Id EXTRA_DIST=detection_leaf_node.c AUTOMAKE_OPTIONS=foreign no-dependencies noinst_LIBRARIES = libspd.a BUILT_SOURCES = sf_snort_plugin_hdropts.c \ sf_snort_packet.h \ sf_snort_plugin_api.h \ sf_decompression.h \ sf_decompression_define.h nodist_libspd_a_SOURCES = sf_snort_plugin_hdropts.c \ sf_snort_packet.h \ sf_snort_plugin_api.h \ sf_decompression.h \ sf_decompression_define.h libspd_a_SOURCES = \ detection_options.c detection_options.h \ sp_asn1.c sp_asn1.h \ sp_asn1_detect.c sp_asn1_detect.h \ sp_byte_check.c sp_byte_check.h \ sp_byte_jump.c sp_byte_jump.h \ sp_byte_extract.c sp_byte_extract.h \ sp_byte_math.c sp_byte_math.h \ sp_clientserver.c sp_clientserver.h \ sp_cvs.c sp_cvs.h \ sp_dsize_check.c sp_dsize_check.h \ sp_flowbits.c sp_flowbits.h \ sp_ftpbounce.c sp_ftpbounce.h \ sp_hdr_opt_wrap.c sp_hdr_opt_wrap.h \ sp_icmp_code_check.c sp_icmp_code_check.h \ sp_icmp_id_check.c sp_icmp_id_check.h \ sp_icmp_seq_check.c sp_icmp_seq_check.h \ sp_icmp_type_check.c sp_icmp_type_check.h \ sp_ip_fragbits.c sp_ip_fragbits.h \ sp_ip_id_check.c sp_ip_id_check.h \ sp_ip_proto.c sp_ip_proto.h \ sp_ip_same_check.c sp_ip_same_check.h \ sp_ip_tos_check.c sp_ip_tos_check.h \ sp_ipoption_check.c sp_ipoption_check.h \ sp_isdataat.c sp_isdataat.h \ sp_pattern_match.c sp_pattern_match.h \ sp_pcre.c sp_pcre.h \ sp_replace.c sp_replace.h \ sp_rpc_check.c sp_rpc_check.h \ sp_session.c sp_session.h \ sp_tcp_ack_check.c sp_tcp_ack_check.h \ sp_tcp_flag_check.h sp_tcp_flag_check.c \ sp_tcp_seq_check.c sp_tcp_seq_check.h \ sp_tcp_win_check.c sp_tcp_win_check.h \ sp_ttl_check.c sp_ttl_check.h \ sp_urilen_check.c sp_urilen_check.h \ sp_file_data.c sp_file_data.h \ sp_base64_decode.c sp_base64_decode.h \ sp_base64_data.c sp_base64_data.h \ sp_pkt_data.c sp_pkt_data.h \ sp_file_type.c sp_file_type.h if BUILD_REACT libspd_a_SOURCES += sp_react.c sp_react.h endif if BUILD_RESPOND3 libspd_a_SOURCES += sp_respond3.c sp_respond.h endif if FEAT_OPEN_APPID libspd_a_SOURCES += sp_appid.c sp_appid.h endif copy_files = \ if test -f $$dst_file; then \ x=`diff $$src_file $$dst_file >> /dev/null`; \ if test "$$x" != "0"; then \ echo "Updating " $$dst_file; \ cp $$src_file $$dst_file; \ fi \ else \ echo "Updating " $$dst_file; \ cp $$src_file $$dst_file; \ fi sed_hdropts = \ sed -e "s/_ded.errMsg/ErrorMessage/g" \ -e "s/sf_snort_packet.h/decode.h/g" \ -e "s/SFSnortPacket/Packet/g" \ -e "s/ip4_header/iph/g" \ -e "s/tcp_header/tcph/g" \ -e "s/proto/ip_proto/g" \ -e "s/type_service/ip_tos/g" \ -e "s/time_to_live/ip_ttl/g" \ -e "s/num_ip_options/ip_option_count/g" \ -e "s/IPOptions/Options/g" \ -e "s/option_code/code/g" \ -e "s/acknowledgement/th_ack/g" \ -e "s/sequence/th_seq/g" \ -e "s/tcph->flags/tcph->th_flags/g" \ -e "s/tcph->window/tcph->th_win/g" \ -e "s/num_tcp_options/tcp_option_count/g" \ -e "s/icmp_header/icmph/g" \ -e "s/ICMP_ECHO_REPLY/ICMP_ECHOREPLY/g" \ -e "s/ICMP_ECHO_REQUEST/ICMP_ECHO/g" \ -e "s/icmph_union.echo.id/s_icmp_id/g" \ -e "s/icmph_union.echo.seq/s_icmp_seq/g" \ $$src_file > $$dst_file; sf_snort_plugin_hdropts.c: ../dynamic-plugins/sf_engine/sf_snort_plugin_hdropts.c @src_file=$?; dst_file=$@; $(sed_hdropts) sf_snort_plugin_api.h: ../dynamic-plugins/sf_engine/sf_snort_plugin_api.h @src_file=$?; dst_file=$@; $(copy_files) sf_decompression.h: ../dynamic-plugins/sf_engine/sf_decompression.h @src_file=$?; dst_file=$@; $(copy_files) sf_decompression_define.h: ../dynamic-plugins/sf_decompression_define.h @src_file=$?; dst_file=$@; $(copy_files) sf_snort_packet.h: ../dynamic-plugins/sf_engine/sf_snort_packet.h @src_file=$?; dst_file=$@; $(copy_files) clean-local: rm -rf sf_snort_plugin_hdropts.c sf_snort_packet.h sf_snort_plugin_api.h sf_decompression.h sf_decompression_define.h INCLUDES = @INCLUDES@ snort-2.9.15.1/src/detection-plugins/detection_options.c0000644000175200017520000014761213571422607020204 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2007-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** **/ /** ** @file detection_options.c ** ** @author Steven Sturges ** ** @brief Support functions for rule option tree ** ** This implements tree processing for rule options, evaluating common ** detection options only once per pattern match. ** */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sfutil/sfxhash.h" #include "sfutil/sfhashfcn.h" #include "detection_options.h" #include "detection_util.h" #include "rules.h" #include "treenodes.h" #include "util.h" #include "fpcreate.h" #include "parser.h" #include "sp_asn1.h" #include "sp_byte_check.h" #include "sp_byte_jump.h" #include "sp_byte_extract.h" #include "sp_byte_math.h" #include "sp_clientserver.h" #include "sp_cvs.h" #include "sp_dsize_check.h" #include "sp_flowbits.h" #include "sp_ftpbounce.h" #include "sp_icmp_code_check.h" #include "sp_icmp_id_check.h" #include "sp_icmp_seq_check.h" #include "sp_icmp_type_check.h" #include "sp_ip_fragbits.h" #include "sp_ip_id_check.h" #include "sp_ipoption_check.h" #include "sp_ip_proto.h" #include "sp_ip_same_check.h" #include "sp_ip_tos_check.h" #include "sp_file_data.h" #include "sp_base64_decode.h" #include "sp_isdataat.h" #include "sp_pattern_match.h" #include "sp_pcre.h" #ifdef ENABLE_REACT #include "sp_react.h" #endif #include "sp_replace.h" #ifdef ENABLE_RESPOND #include "sp_respond.h" #endif #include "sp_rpc_check.h" #include "sp_session.h" #include "sp_tcp_ack_check.h" #include "sp_tcp_flag_check.h" #include "sp_tcp_seq_check.h" #include "sp_tcp_win_check.h" #include "sp_ttl_check.h" #include "sp_urilen_check.h" #include "sp_hdr_opt_wrap.h" # include "sp_file_type.h" #include "sp_preprocopt.h" #include "sp_dynamic.h" #include "fpdetect.h" #include "ppm.h" #include "profiler.h" #include "sfPolicy.h" #include "detection_filter.h" #include "encode.h" #if defined(FEAT_OPEN_APPID) #include "stream_common.h" #include "sp_appid.h" #endif /* defined(FEAT_OPEN_APPID) */ typedef struct _detection_option_key { option_type_t option_type; void *option_data; } detection_option_key_t; #define HASH_RULE_OPTIONS 16384 #define HASH_RULE_TREE 8192 uint32_t detection_option_hash_func(SFHASHFCN *p, unsigned char *k, int n) { uint32_t hash = 0; detection_option_key_t *key = (detection_option_key_t*)k; switch (key->option_type) { /* Call hash function specific to the key type */ case RULE_OPTION_TYPE_ASN1: hash = Asn1Hash(key->option_data); break; case RULE_OPTION_TYPE_BYTE_TEST: hash = ByteTestHash(key->option_data); break; case RULE_OPTION_TYPE_BYTE_JUMP: hash = ByteJumpHash(key->option_data); break; case RULE_OPTION_TYPE_BYTE_EXTRACT: hash = ByteExtractHash(key->option_data); break; case RULE_OPTION_TYPE_BYTE_MATH: hash = ByteMathHash(key->option_data); break; case RULE_OPTION_TYPE_FLOW: hash = FlowHash(key->option_data); break; case RULE_OPTION_TYPE_CVS: hash = CvsHash(key->option_data); break; case RULE_OPTION_TYPE_DSIZE: hash = DSizeCheckHash(key->option_data); break; case RULE_OPTION_TYPE_FLOWBIT: hash = FlowBitsHash(key->option_data); break; case RULE_OPTION_TYPE_FTPBOUNCE: break; case RULE_OPTION_TYPE_FILE_DATA: hash = FileDataHash(key->option_data); break; case RULE_OPTION_TYPE_BASE64_DECODE: hash = Base64DecodeHash(key->option_data); break; case RULE_OPTION_TYPE_BASE64_DATA: break; case RULE_OPTION_TYPE_PKT_DATA: break; case RULE_OPTION_TYPE_ICMP_CODE: hash = IcmpCodeCheckHash(key->option_data); break; case RULE_OPTION_TYPE_ICMP_ID: hash = IcmpIdCheckHash(key->option_data); break; case RULE_OPTION_TYPE_ICMP_SEQ: hash = IcmpSeqCheckHash(key->option_data); break; case RULE_OPTION_TYPE_ICMP_TYPE: hash = IcmpTypeCheckHash(key->option_data); break; case RULE_OPTION_TYPE_IP_FRAGBITS: hash = IpFragBitsCheckHash(key->option_data); break; case RULE_OPTION_TYPE_IP_FRAG_OFFSET: hash = IpFragOffsetCheckHash(key->option_data); break; case RULE_OPTION_TYPE_IP_ID: hash = IpIdCheckHash(key->option_data); break; case RULE_OPTION_TYPE_IP_OPTION: hash = IpOptionCheckHash(key->option_data); break; case RULE_OPTION_TYPE_IP_PROTO: hash = IpProtoCheckHash(key->option_data); break; case RULE_OPTION_TYPE_IP_SAME: hash = IpSameCheckHash(key->option_data); break; case RULE_OPTION_TYPE_IP_TOS: hash = IpTosCheckHash(key->option_data); break; case RULE_OPTION_TYPE_IS_DATA_AT: hash = IsDataAtHash(key->option_data); break; case RULE_OPTION_TYPE_CONTENT: case RULE_OPTION_TYPE_CONTENT_URI: hash = PatternMatchHash(key->option_data); break; case RULE_OPTION_TYPE_PCRE: hash = PcreHash(key->option_data); break; #ifdef ENABLE_REACT case RULE_OPTION_TYPE_REACT: hash = ReactHash(key->option_data); break; #endif #ifdef ENABLE_RESPOND case RULE_OPTION_TYPE_RESPOND: hash = RespondHash(key->option_data); break; #endif case RULE_OPTION_TYPE_RPC_CHECK: hash = RpcCheckHash(key->option_data); break; case RULE_OPTION_TYPE_SESSION: hash = SessionHash(key->option_data); break; case RULE_OPTION_TYPE_TCP_ACK: hash = TcpAckCheckHash(key->option_data); break; case RULE_OPTION_TYPE_TCP_FLAG: hash = TcpFlagCheckHash(key->option_data); break; case RULE_OPTION_TYPE_TCP_SEQ: hash = TcpSeqCheckHash(key->option_data); break; case RULE_OPTION_TYPE_TCP_WIN: hash = TcpWinCheckHash(key->option_data); break; case RULE_OPTION_TYPE_TTL: hash = TtlCheckHash(key->option_data); break; case RULE_OPTION_TYPE_URILEN: hash = UriLenCheckHash(key->option_data); break; case RULE_OPTION_TYPE_HDR_OPT_CHECK: hash = HdrOptCheckHash(key->option_data); break; case RULE_OPTION_TYPE_FILE_TYPE: hash = FileTypeHash(key->option_data); break; case RULE_OPTION_TYPE_PREPROCESSOR: hash = PreprocessorRuleOptionHash(key->option_data); break; case RULE_OPTION_TYPE_DYNAMIC: hash = DynamicRuleHash(key->option_data); break; case RULE_OPTION_TYPE_LEAF_NODE: hash = 0; break; #if defined(FEAT_OPEN_APPID) case RULE_OPTION_TYPE_APPID: hash = optionAppIdHash(key->option_data); break; #endif /* defined(FEAT_OPEN_APPID) */ } return hash; } int detection_option_key_compare_func(const void *k1, const void *k2, size_t n) { int ret = DETECTION_OPTION_NOT_EQUAL; const detection_option_key_t *key1 = (detection_option_key_t*)k1; const detection_option_key_t *key2 = (detection_option_key_t*)k2; #ifdef KEEP_THEM_ALLOCATED return DETECTION_OPTION_NOT_EQUAL; #endif if (!key1 || !key2) return DETECTION_OPTION_NOT_EQUAL; if (key1->option_type != key2->option_type) return DETECTION_OPTION_NOT_EQUAL; switch (key1->option_type) { /* Call compare function specific to the key type */ case RULE_OPTION_TYPE_LEAF_NODE: /* Leaf node always not equal. */ break; case RULE_OPTION_TYPE_ASN1: ret = Asn1Compare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_BYTE_TEST: ret = ByteTestCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_BYTE_JUMP: ret = ByteJumpCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_BYTE_EXTRACT: ret = ByteExtractCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_BYTE_MATH: ret = ByteMathCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_FLOW: ret = FlowCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_CVS: ret = CvsCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_DSIZE: ret = DSizeCheckCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_FLOWBIT: ret = FlowBitsCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_FTPBOUNCE: break; case RULE_OPTION_TYPE_FILE_DATA: ret = FileDataCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_BASE64_DECODE: ret = Base64DecodeCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_BASE64_DATA: break; case RULE_OPTION_TYPE_PKT_DATA: break; case RULE_OPTION_TYPE_ICMP_CODE: ret = IcmpCodeCheckCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_ICMP_ID: ret = IcmpIdCheckCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_ICMP_SEQ: ret = IcmpSeqCheckCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_ICMP_TYPE: ret = IcmpTypeCheckCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_IP_FRAGBITS: ret = IpFragBitsCheckCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_IP_FRAG_OFFSET: ret = IpFragOffsetCheckCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_IP_ID: ret = IpIdCheckCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_IP_OPTION: ret = IpOptionCheckCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_IP_PROTO: ret = IpProtoCheckCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_IP_SAME: ret = IpSameCheckCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_IP_TOS: ret = IpTosCheckCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_IS_DATA_AT: ret = IsDataAtCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_CONTENT: case RULE_OPTION_TYPE_CONTENT_URI: ret = PatternMatchCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_PCRE: ret = PcreCompare(key1->option_data, key2->option_data); break; #ifdef ENABLE_REACT case RULE_OPTION_TYPE_REACT: ret = ReactCompare(key1->option_data, key2->option_data); break; #endif #ifdef ENABLE_RESPOND case RULE_OPTION_TYPE_RESPOND: ret = RespondCompare(key1->option_data, key2->option_data); break; #endif case RULE_OPTION_TYPE_RPC_CHECK: ret = RpcCheckCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_SESSION: ret = SessionCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_TCP_ACK: ret = TcpAckCheckCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_TCP_FLAG: ret = TcpFlagCheckCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_TCP_SEQ: ret = TcpSeqCheckCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_TCP_WIN: ret = TcpWinCheckCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_TTL: ret = TtlCheckCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_URILEN: ret = UriLenCheckCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_HDR_OPT_CHECK: ret = HdrOptCheckCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_FILE_TYPE: ret = FileTypeCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_PREPROCESSOR: ret = PreprocessorRuleOptionCompare(key1->option_data, key2->option_data); break; case RULE_OPTION_TYPE_DYNAMIC: ret = DynamicRuleCompare(key1->option_data, key2->option_data); break; #if defined(FEAT_OPEN_APPID) case RULE_OPTION_TYPE_APPID: ret = optionAppIdCompare(key1->option_data, key2->option_data); break; #endif /* defined(FEAT_OPEN_APPID) */ } return ret; } int detection_hash_free_func(void *option_key, void *data) { detection_option_key_t *key = (detection_option_key_t*)option_key; switch (key->option_type) { /* Call free function specific to the key type */ case RULE_OPTION_TYPE_ASN1: free(key->option_data); break; case RULE_OPTION_TYPE_BYTE_TEST: free(key->option_data); break; case RULE_OPTION_TYPE_BYTE_JUMP: free(key->option_data); break; case RULE_OPTION_TYPE_BYTE_EXTRACT: ByteExtractFree(key->option_data); break; case RULE_OPTION_TYPE_BYTE_MATH: ByteMathFree(key->option_data); break; case RULE_OPTION_TYPE_FLOW: free(key->option_data); break; case RULE_OPTION_TYPE_CVS: free(key->option_data); break; case RULE_OPTION_TYPE_DSIZE: free(key->option_data); break; case RULE_OPTION_TYPE_FLOWBIT: FlowBitsFree(key->option_data); break; case RULE_OPTION_TYPE_FTPBOUNCE: /* Data is NULL, nothing to free */ break; case RULE_OPTION_TYPE_FILE_DATA: free(key->option_data); break; case RULE_OPTION_TYPE_BASE64_DECODE: free(key->option_data); break; case RULE_OPTION_TYPE_BASE64_DATA: break; case RULE_OPTION_TYPE_PKT_DATA: break; case RULE_OPTION_TYPE_ICMP_CODE: free(key->option_data); break; case RULE_OPTION_TYPE_ICMP_ID: free(key->option_data); break; case RULE_OPTION_TYPE_ICMP_SEQ: free(key->option_data); break; case RULE_OPTION_TYPE_ICMP_TYPE: free(key->option_data); break; case RULE_OPTION_TYPE_IP_FRAGBITS: free(key->option_data); break; case RULE_OPTION_TYPE_IP_FRAG_OFFSET: free(key->option_data); break; case RULE_OPTION_TYPE_IP_ID: free(key->option_data); break; case RULE_OPTION_TYPE_IP_OPTION: free(key->option_data); break; case RULE_OPTION_TYPE_IP_PROTO: free(key->option_data); break; case RULE_OPTION_TYPE_IP_SAME: /* Data is NULL, nothing to free */ break; case RULE_OPTION_TYPE_IP_TOS: free(key->option_data); break; case RULE_OPTION_TYPE_IS_DATA_AT: free(key->option_data); break; case RULE_OPTION_TYPE_CONTENT: case RULE_OPTION_TYPE_CONTENT_URI: PatternMatchFree(key->option_data); break; case RULE_OPTION_TYPE_PCRE: PcreFree(key->option_data); break; #ifdef ENABLE_REACT case RULE_OPTION_TYPE_REACT: ReactFree(key->option_data); break; #endif #ifdef ENABLE_RESPOND case RULE_OPTION_TYPE_RESPOND: free(key->option_data); break; #endif case RULE_OPTION_TYPE_RPC_CHECK: free(key->option_data); break; case RULE_OPTION_TYPE_SESSION: free(key->option_data); break; case RULE_OPTION_TYPE_TCP_ACK: free(key->option_data); break; case RULE_OPTION_TYPE_TCP_FLAG: free(key->option_data); break; case RULE_OPTION_TYPE_TCP_SEQ: free(key->option_data); break; case RULE_OPTION_TYPE_TCP_WIN: free(key->option_data); break; case RULE_OPTION_TYPE_TTL: free(key->option_data); break; case RULE_OPTION_TYPE_URILEN: free(key->option_data); break; case RULE_OPTION_TYPE_HDR_OPT_CHECK: break; case RULE_OPTION_TYPE_FILE_TYPE: FileTypeFree(key->option_data); break; case RULE_OPTION_TYPE_PREPROCESSOR: PreprocessorRuleOptionsFreeFunc(key->option_data); break; case RULE_OPTION_TYPE_DYNAMIC: fpDynamicDataFree(key->option_data); break; case RULE_OPTION_TYPE_LEAF_NODE: break; #if defined(FEAT_OPEN_APPID) case RULE_OPTION_TYPE_APPID: optionAppIdFree(key->option_data); break; #endif /* defined(FEAT_OPEN_APPID) */ } return 0; } SFXHASH * DetectionHashTableNew(void) { SFXHASH *doht = sfxhash_new(HASH_RULE_OPTIONS, sizeof(detection_option_key_t), 0, /* Data size == 0, just store the ptr */ 0, /* Memcap */ 0, /* Auto node recovery */ NULL, /* Auto free function */ detection_hash_free_func, /* User free function */ 1); /* Recycle nodes */ if (doht == NULL) FatalError("Failed to create rule detection option hash table"); sfxhash_set_keyops(doht, detection_option_hash_func, detection_option_key_compare_func); return doht; } void DetectionHashTableFree(SFXHASH *doht) { if (doht != NULL) sfxhash_delete(doht); } int add_detection_option(struct _SnortConfig *sc, option_type_t type, void *option_data, void **existing_data) { detection_option_key_t key; if (sc == NULL) { FatalError("%s(%d) Snort config is NULL.\n", __FILE__, __LINE__); } if (sc->detection_option_hash_table == NULL) sc->detection_option_hash_table = DetectionHashTableNew(); if (!option_data) { /* No option data, no conflict to resolve. */ return DETECTION_OPTION_EQUAL; } key.option_type = type; key.option_data = option_data; *existing_data = sfxhash_find(sc->detection_option_hash_table, &key); if (*existing_data) { return DETECTION_OPTION_EQUAL; } sfxhash_add(sc->detection_option_hash_table, &key, option_data); return DETECTION_OPTION_NOT_EQUAL; } uint32_t detection_option_tree_hash(detection_option_tree_node_t *node) { uint32_t a,b,c; int i; if (!node) return 0; a = b = c = 0; for (i=0;inum_children;i++) { #if (defined(__ia64) || defined(__amd64) || defined(_LP64)) { /* Cleanup warning because of cast from 64bit ptr to 32bit int * warning on 64bit OSs */ uint64_t ptr; /* Addresses are 64bits */ ptr = (uint64_t)node->children[i]->option_data; a += (ptr >> 32); b += (ptr & 0xFFFFFFFF); } #else a += (uint32_t)node->children[i]->option_data; b += 0; #endif c += detection_option_tree_hash(node->children[i]); mix(a,b,c); a += node->children[i]->num_children; mix(a,b,c); #if 0 a += (uint32_t)node->children[i]->option_data; /* Recurse & hash up this guy's children */ b += detection_option_tree_hash(node->children[i]); c += node->children[i]->num_children; mix(a,b,c); #endif } final(a,b,c); return c; } uint32_t detection_option_tree_hash_func(SFHASHFCN *p, unsigned char *k, int n) { detection_option_key_t *key = (detection_option_key_t *)k; detection_option_tree_node_t *node; if (!key || !key->option_data) return 0; node = (detection_option_tree_node_t*)key->option_data; return detection_option_tree_hash(node); } int detection_option_tree_compare(detection_option_tree_node_t *r, detection_option_tree_node_t *l) { int ret = DETECTION_OPTION_NOT_EQUAL; int i; if ((r == NULL) && (l == NULL)) return DETECTION_OPTION_EQUAL; if ((!r && l) || (r && !l)) return DETECTION_OPTION_NOT_EQUAL; if (r->option_data != l->option_data) return DETECTION_OPTION_NOT_EQUAL; if (r->num_children != l->num_children) return DETECTION_OPTION_NOT_EQUAL; for (i=0;inum_children;i++) { /* Recurse & check the children for equality */ ret = detection_option_tree_compare(r->children[i], l->children[i]); if (ret != DETECTION_OPTION_EQUAL) return ret; } return DETECTION_OPTION_EQUAL; } int detection_option_tree_compare_func(const void *k1, const void *k2, size_t n) { detection_option_key_t *key_r = (detection_option_key_t *)k1; detection_option_key_t *key_l = (detection_option_key_t *)k2; detection_option_tree_node_t *r; detection_option_tree_node_t *l; if (!key_r || !key_l) return DETECTION_OPTION_NOT_EQUAL; r = (detection_option_tree_node_t *)key_r->option_data; l = (detection_option_tree_node_t *)key_l->option_data; return detection_option_tree_compare(r, l); } int detection_option_tree_free_func(void *option_key, void *data) { detection_option_tree_node_t *node = (detection_option_tree_node_t *)data; /* In fpcreate.c */ free_detection_option_tree(node); return 0; } void DetectionTreeHashTableFree(SFXHASH *dtht) { if (dtht != NULL) sfxhash_delete(dtht); } SFXHASH * DetectionTreeHashTableNew(void) { SFXHASH *dtht = sfxhash_new(HASH_RULE_TREE, sizeof(detection_option_key_t), 0, /* Data size == 0, just store the ptr */ 0, /* Memcap */ 0, /* Auto node recovery */ NULL, /* Auto free function */ detection_option_tree_free_func, /* User free function */ 1); /* Recycle nodes */ if (dtht == NULL) FatalError("Failed to create rule detection option hash table"); sfxhash_set_keyops(dtht, detection_option_tree_hash_func, detection_option_tree_compare_func); return dtht; } char *option_type_str[] = { "RULE_OPTION_TYPE_LEAF_NODE", "RULE_OPTION_TYPE_ASN1", "RULE_OPTION_TYPE_BYTE_TEST", "RULE_OPTION_TYPE_BYTE_JUMP", "RULE_OPTION_TYPE_BYTE_EXTRACT", "RULE_OPTION_TYPE_FLOW", "RULE_OPTION_TYPE_CVS", "RULE_OPTION_TYPE_DSIZE", "RULE_OPTION_TYPE_FLOWBIT", "RULE_OPTION_TYPE_FTPBOUNCE", "RULE_OPTION_TYPE_ICMP_CODE", "RULE_OPTION_TYPE_ICMP_ID", "RULE_OPTION_TYPE_ICMP_SEQ", "RULE_OPTION_TYPE_ICMP_TYPE", "RULE_OPTION_TYPE_IP_FRAGBITS", "RULE_OPTION_TYPE_IP_FRAG_OFFSET", "RULE_OPTION_TYPE_IP_ID", "RULE_OPTION_TYPE_IP_OPTION", "RULE_OPTION_TYPE_IP_PROTO", "RULE_OPTION_TYPE_IP_SAME", "RULE_OPTION_TYPE_IP_TOS", "RULE_OPTION_TYPE_IS_DATA_AT", "RULE_OPTION_TYPE_FILE_DATA", "RULE_OPTION_TYPE_FILE_TYPE", "RULE_OPTION_TYPE_BASE64_DECODE", "RULE_OPTION_TYPE_BASE64_DATA", "RULE_OPTION_TYPE_PKT_DATA", "RULE_OPTION_TYPE_CONTENT", "RULE_OPTION_TYPE_CONTENT_URI", "RULE_OPTION_TYPE_PCRE", #ifdef ENABLE_REACT "RULE_OPTION_TYPE_REACT", #endif #ifdef ENABLE_RESPOND "RULE_OPTION_TYPE_RESPOND", #endif "RULE_OPTION_TYPE_RPC_CHECK", "RULE_OPTION_TYPE_SESSION", "RULE_OPTION_TYPE_TCP_ACK", "RULE_OPTION_TYPE_TCP_FLAG", "RULE_OPTION_TYPE_TCP_SEQ", "RULE_OPTION_TYPE_TCP_WIN", "RULE_OPTION_TYPE_TTL", "RULE_OPTION_TYPE_URILEN", "RULE_OPTION_TYPE_HDR_OPT_CHECK", "RULE_OPTION_TYPE_PREPROCESSOR", "RULE_OPTION_TYPE_DYNAMIC" #if defined(FEAT_OPEN_APPID) ,"RULE_OPTION_TYPE_APPID" #endif /* defined(FEAT_OPEN_APPID) */ ,"RULE_OPTION_TYPE_BYTE_MATH" }; #ifdef DEBUG_OPTION_TREE void print_option_tree(detection_option_tree_node_t *node, int level) { int i; unsigned int indent = 12 - (11 - level) + strlen(option_type_str[node->option_type]); unsigned int offset = 0; if (level >= 10) offset++; DEBUG_WRAP( DebugMessage(DEBUG_DETECT, "%d%*s%*d 0x%x\n", level, indent - offset, option_type_str[node->option_type], 54 - indent, node->num_children, node->option_data); for (i=0;inum_children;i++) print_option_tree(node->children[i], level+1); ); } #endif int add_detection_option_tree(SnortConfig *sc, detection_option_tree_node_t *option_tree, void **existing_data) { detection_option_key_t key; if (sc == NULL) { FatalError("%s(%d) Snort config for parsing is NULL.\n", __FILE__, __LINE__); } if (sc->detection_option_tree_hash_table == NULL) sc->detection_option_tree_hash_table = DetectionTreeHashTableNew(); if (!option_tree) { /* No option data, no conflict to resolve. */ return DETECTION_OPTION_EQUAL; } key.option_data = (void *)option_tree; key.option_type = RULE_OPTION_TYPE_LEAF_NODE; *existing_data = sfxhash_find(sc->detection_option_tree_hash_table, &key); if (*existing_data) { return DETECTION_OPTION_EQUAL; } sfxhash_add(sc->detection_option_tree_hash_table, &key, option_tree); return DETECTION_OPTION_NOT_EQUAL; } uint64_t rule_eval_pkt_count = 0; /* Include "detection_leaf_node.c" * * Service matches, toggles 'check_ports' and then evaluation * of the leaf nodes (ie. the rule header stuffs). * * This defines the routine "detection_leaf_node_eval($,$)" which * is called from the switch case RULE_OPTION_TYPE_LEAF_NODE below. */ #include "detection_leaf_node.c" int detection_option_node_evaluate(detection_option_tree_node_t *node, detection_option_eval_data_t *eval_data) { int i, result = 0, prior_result = 0; int rval = DETECTION_OPTION_NO_MATCH; const uint8_t *orig_doe_ptr; char tmp_noalert_flag = 0; PatternMatchData dup_content_option_data; PcreData dup_pcre_option_data; const uint8_t *dp = NULL; char continue_loop = 1; char flowbits_setoperation = 0; int loop_count = 0; uint32_t tmp_byte_extract_vars[NUM_BYTE_EXTRACT_VARS]; uint16_t save_dflags = 0; uint64_t cur_eval_pkt_count = (rule_eval_pkt_count + (GetRebuiltPktCount())); NODE_PROFILE_VARS; if (!node || !eval_data || !eval_data->p || !eval_data->pomd) return 0; save_dflags = Get_DetectFlags(); /* see if evaluated it before ... */ if (node->last_check.is_relative == 0) { /* Only matters if not relative... */ if ((node->last_check.ts.tv_usec == eval_data->p->pkth->ts.tv_usec) && (node->last_check.ts.tv_sec == eval_data->p->pkth->ts.tv_sec) && (node->last_check.packet_number == cur_eval_pkt_count) && (node->last_check.rebuild_flag == (eval_data->p->packet_flags & PKT_REBUILT_STREAM)) && (!(eval_data->p->packet_flags & PKT_ALLOW_MULTIPLE_DETECT))) { /* eval'd this rule option before on this packet, * use the cached result. */ if ((node->last_check.flowbit_failed == 0) && !(eval_data->p->packet_flags & PKT_IP_RULE_2ND) && !(eval_data->p->proto_bits & (PROTO_BIT__TEREDO | PROTO_BIT__GTP ))) { return node->last_check.result; } } } NODE_PROFILE_START(node); node->last_check.ts.tv_sec = eval_data->p->pkth->ts.tv_sec; node->last_check.ts.tv_usec = eval_data->p->pkth->ts.tv_usec; node->last_check.packet_number = cur_eval_pkt_count; node->last_check.rebuild_flag = (eval_data->p->packet_flags & PKT_REBUILT_STREAM); node->last_check.flowbit_failed = 0; /* Save some stuff off for repeated pattern tests */ orig_doe_ptr = doe_ptr; if ((node->option_type == RULE_OPTION_TYPE_CONTENT) || (node->option_type == RULE_OPTION_TYPE_CONTENT_URI)) { PatternMatchDuplicatePmd(node->option_data, &dup_content_option_data); if (dup_content_option_data.buffer_func == CHECK_URI_PATTERN_MATCH) { const HttpBuffer* hb = GetHttpBuffer(dup_content_option_data.http_buffer); dp = hb ? hb->buf : NULL; // FIXTHIS set length too } else if (dup_content_option_data.rawbytes == 0) { /* If AltDetect is set by calling the rule options which set it, * we should use the Alt Detect before checking for any other buffers. * Alt Detect will take precedence over the Alt Decode and/or packet data. */ if(Is_DetectFlag(FLAG_ALT_DETECT)) dp = DetectBuffer.data; else if(Is_DetectFlag(FLAG_ALT_DECODE)) dp = (uint8_t *)DecodeBuffer.data; else dp = eval_data->p->data; } else { dp = eval_data->p->data; } } else if (node->option_type == RULE_OPTION_TYPE_PCRE) { unsigned hb_type; PcreDuplicatePcreData(node->option_data, &dup_pcre_option_data); hb_type = dup_pcre_option_data.options & SNORT_PCRE_HTTP_BUFS; if ( hb_type ) { const HttpBuffer* hb = GetHttpBuffer(hb_type); dp = hb ? hb->buf : NULL; // FIXTHIS set length too } else if (!(dup_pcre_option_data.options & SNORT_PCRE_RAWBYTES)) { /* If AltDetect is set by calling the rule options which set it, * we should use the Alt Detect before checking for any other buffers. * Alt Detect will take precedence over the Alt Decode and/or packet data. */ if(Is_DetectFlag(FLAG_ALT_DETECT)) dp = DetectBuffer.data; else if(Is_DetectFlag(FLAG_ALT_DECODE)) dp = (uint8_t *)DecodeBuffer.data; else dp = eval_data->p->data; } else { dp = eval_data->p->data; } } /* No, haven't evaluated this one before... Check it. */ do { switch (node->option_type) { case RULE_OPTION_TYPE_LEAF_NODE: /* Add the match for this otn to the queue. */ { int pattern_size = 0; int eval_rtn_result = 1; int check_ports = 1; OptTreeNode *otn = (OptTreeNode*) node->option_data; PatternMatchData *pmd = (PatternMatchData*) eval_data->pmd; if (pmd) pattern_size = pmd->pattern_size; // See "detection_leaf_node.c" (detection_leaf_node_eval). switch (detection_leaf_node_eval (node, eval_data)) { case Leaf_Abort: eval_rtn_result = 0; break; case Leaf_SkipPorts: check_ports = 0; // fall through case Leaf_CheckPorts: NODE_PROFILE_TMPEND(node); eval_rtn_result = fpEvalRTN (getRuntimeRtnFromOtn (otn), eval_data->p, check_ports); NODE_PROFILE_TMPSTART(node); break; } if (eval_rtn_result) { if ((!otn->detection_filter) || !detection_filter_test( otn->detection_filter, GET_SRC_IP(eval_data->p), GET_DST_IP(eval_data->p), eval_data->p->pkth->ts.tv_sec, eval_data)) { #ifdef PERF_PROFILING if (PROFILING_RULES) otn->matches++; #endif if (!eval_data->flowbit_noalert) { fpAddMatch(eval_data->pomd, pattern_size, otn); } result = rval = DETECTION_OPTION_MATCH; } } } break; case RULE_OPTION_TYPE_CONTENT: if (node->evaluate) { /* This will be set in the fast pattern matcher if we found * a content and the rule option specifies not that * content. Essentially we've already evaluated this rule * option via the content option processing since only not * contents that are not relative in any way will have this * flag set */ if (dup_content_option_data.exception_flag) { if ((dup_content_option_data.last_check.ts.tv_sec == eval_data->p->pkth->ts.tv_sec) && (dup_content_option_data.last_check.ts.tv_usec == eval_data->p->pkth->ts.tv_usec) && (dup_content_option_data.last_check.packet_number == cur_eval_pkt_count) && (dup_content_option_data.last_check.rebuild_flag == (eval_data->p->packet_flags & PKT_REBUILT_STREAM))) { rval = DETECTION_OPTION_NO_MATCH; break; } } rval = node->evaluate(&dup_content_option_data, eval_data->p); } break; case RULE_OPTION_TYPE_CONTENT_URI: if (node->evaluate) { rval = node->evaluate(&dup_content_option_data, eval_data->p); } break; case RULE_OPTION_TYPE_PCRE: if (node->evaluate) { rval = node->evaluate(&dup_pcre_option_data, eval_data->p); } break; case RULE_OPTION_TYPE_PKT_DATA: case RULE_OPTION_TYPE_FILE_DATA: case RULE_OPTION_TYPE_BASE64_DATA: if (node->evaluate) { save_dflags = Get_DetectFlags(); rval = node->evaluate(node->option_data, eval_data->p); } break; case RULE_OPTION_TYPE_FLOWBIT: if (node->evaluate) { flowbits_setoperation = FlowBits_SetOperation(node->option_data); if (!flowbits_setoperation) { rval = node->evaluate(node->option_data, eval_data->p); } else { /* set to match so we don't bail early. */ rval = DETECTION_OPTION_MATCH; } } break; case RULE_OPTION_TYPE_ASN1: case RULE_OPTION_TYPE_BYTE_TEST: case RULE_OPTION_TYPE_BYTE_JUMP: case RULE_OPTION_TYPE_BYTE_EXTRACT: case RULE_OPTION_TYPE_BYTE_MATH: case RULE_OPTION_TYPE_FLOW: case RULE_OPTION_TYPE_CVS: case RULE_OPTION_TYPE_DSIZE: case RULE_OPTION_TYPE_FTPBOUNCE: case RULE_OPTION_TYPE_BASE64_DECODE: case RULE_OPTION_TYPE_ICMP_CODE: case RULE_OPTION_TYPE_ICMP_ID: case RULE_OPTION_TYPE_ICMP_SEQ: case RULE_OPTION_TYPE_ICMP_TYPE: case RULE_OPTION_TYPE_IP_FRAGBITS: case RULE_OPTION_TYPE_IP_FRAG_OFFSET: case RULE_OPTION_TYPE_IP_ID: case RULE_OPTION_TYPE_IP_OPTION: case RULE_OPTION_TYPE_IP_PROTO: case RULE_OPTION_TYPE_IP_SAME: case RULE_OPTION_TYPE_IP_TOS: case RULE_OPTION_TYPE_IS_DATA_AT: #ifdef ENABLE_REACT case RULE_OPTION_TYPE_REACT: #endif #ifdef ENABLE_RESPOND case RULE_OPTION_TYPE_RESPOND: #endif case RULE_OPTION_TYPE_RPC_CHECK: case RULE_OPTION_TYPE_SESSION: case RULE_OPTION_TYPE_TCP_ACK: case RULE_OPTION_TYPE_TCP_FLAG: case RULE_OPTION_TYPE_TCP_SEQ: case RULE_OPTION_TYPE_TCP_WIN: case RULE_OPTION_TYPE_TTL: case RULE_OPTION_TYPE_URILEN: case RULE_OPTION_TYPE_HDR_OPT_CHECK: case RULE_OPTION_TYPE_FILE_TYPE: case RULE_OPTION_TYPE_PREPROCESSOR: if (node->evaluate) rval = node->evaluate(node->option_data, eval_data->p); break; case RULE_OPTION_TYPE_DYNAMIC: if (node->evaluate) rval = node->evaluate(node->option_data, eval_data->p); break; #if defined(FEAT_OPEN_APPID) case RULE_OPTION_TYPE_APPID: if (node->evaluate) rval = node->evaluate(node->option_data, eval_data->p); break; #endif /* defined(FEAT_OPEN_APPID) */ } if (rval == DETECTION_OPTION_NO_MATCH) { node->last_check.result = result; NODE_PROFILE_END_NOMATCH(node); return result; } else if (rval == DETECTION_OPTION_FAILED_BIT) { eval_data->flowbit_failed = 1; /* clear the timestamp so failed flowbit gets eval'd again */ node->last_check.flowbit_failed = 1; node->last_check.result = result; NODE_PROFILE_END_NOMATCH(node); return 0; } else if (rval == DETECTION_OPTION_NO_ALERT) { /* Cache the current flowbit_noalert flag, and set it * so nodes below this don't alert. */ tmp_noalert_flag = eval_data->flowbit_noalert; eval_data->flowbit_noalert = 1; } /* Back up byte_extract vars so they don't get overwritten between rules */ for (i = 0; i < NUM_BYTE_EXTRACT_VARS; i++) { GetByteExtractValue(&(tmp_byte_extract_vars[i]), (int8_t)i); } #ifdef PPM_MGR if( PPM_PKTS_ENABLED() ) { PPM_GET_TIME(); PPM_PACKET_TEST(); if( PPM_PACKET_ABORT_FLAG() ) { /* bail if we exceeded time */ if (result == DETECTION_OPTION_NO_MATCH) { NODE_PROFILE_END_NOMATCH(node); } else { NODE_PROFILE_END_MATCH(node); } node->last_check.result = result; Reset_DetectFlags(save_dflags); return result; } } #endif /* Don't include children's time in this node */ NODE_PROFILE_TMPEND(node); /* Passed, check the children. */ if (node->num_children) { const uint8_t *tmp_doe_ptr = doe_ptr; const uint8_t tmp_doe_flags = doe_buf_flags; for (i=0;inum_children; i++) { int j = 0; detection_option_tree_node_t *child_node = node->children[i]; /* reset the DOE ptr for each child from here */ SetDoePtr(tmp_doe_ptr, tmp_doe_flags); for (j = 0; j < NUM_BYTE_EXTRACT_VARS; j++) { SetByteExtractValue(tmp_byte_extract_vars[j], (int8_t)j); } if (loop_count > 0) { if (child_node->result == DETECTION_OPTION_NO_MATCH) { if (((child_node->option_type == RULE_OPTION_TYPE_CONTENT) || (child_node->option_type == RULE_OPTION_TYPE_PCRE)) && !child_node->last_check.is_relative) { /* If it's a non-relative content or pcre, no reason * to check again. Only increment result once. * Should hit this condition on first loop iteration. */ if (loop_count == 1) result++; continue; } else if ((child_node->option_type == RULE_OPTION_TYPE_CONTENT) && child_node->last_check.is_relative) { PatternMatchData *pmd = (PatternMatchData *)child_node->option_data; /* Check for an unbounded relative search. If this * failed before, it's going to fail again so don't * go down this path again * Check for protected pattern because in this case * we had checked for 'n'bytes only where 'n' is the * length of protected pattern. * */ if (pmd->within == PMD_WITHIN_UNDEFINED && !pmd->protected_pattern) { /* Only increment result once. Should hit this * condition on first loop iteration. */ if (loop_count == 1) result++; continue; } } } else if (child_node->option_type == RULE_OPTION_TYPE_LEAF_NODE) { /* Leaf node matched, don't eval again */ continue; } else if (child_node->result == child_node->num_children) { /* This branch of the tree matched or has options that * don't need to be evaluated again, so don't need to * evaluate this option again */ continue; } } child_node->result = detection_option_node_evaluate(node->children[i], eval_data); if (child_node->option_type == RULE_OPTION_TYPE_LEAF_NODE) { /* Leaf node won't have any children but will return success * or failure */ result += child_node->result; } else if (child_node->result == child_node->num_children) { /* Indicate that the child's tree branches are done */ result++; } #ifdef PPM_MGR if( PPM_PKTS_ENABLED() ) { PPM_GET_TIME(); PPM_PACKET_TEST(); if( PPM_PACKET_ABORT_FLAG() ) { /* bail if we exceeded time */ node->last_check.result = result; Reset_DetectFlags(save_dflags); return result; } } #endif } /* If all children branches matched, we don't need to reeval any of * the children so don't need to reeval this content/pcre rule * option at a new offset. * Else, reset the DOE ptr to last eval for offset/depth, * distance/within adjustments for this same content/pcre * rule option */ if (result == node->num_children) continue_loop = 0; else SetDoePtr(tmp_doe_ptr, tmp_doe_flags); /* Don't need to reset since it's only checked after we've gone * through the loop at least once and the result will have * been set again already */ //for (i = 0; i < node->num_children; i++) // node->children[i]->result; } if (result - prior_result > 0 && node->option_type == RULE_OPTION_TYPE_CONTENT && Replace_OffsetStored(&dup_content_option_data) && ScIpsInlineMode()) { if(!ScDisableReplaceOpt()) { Replace_QueueChange(&dup_content_option_data); prior_result = result; } } NODE_PROFILE_TMPSTART(node); if (rval == DETECTION_OPTION_NO_ALERT) { /* Reset the flowbit_noalert flag in eval data */ eval_data->flowbit_noalert = tmp_noalert_flag; } if (continue_loop && (rval == DETECTION_OPTION_MATCH) && (node->relative_children)) { if ((node->option_type == RULE_OPTION_TYPE_CONTENT) || (node->option_type == RULE_OPTION_TYPE_CONTENT_URI)) { if (dup_content_option_data.exception_flag) { continue_loop = 0; } else { const uint8_t *orig_ptr; if (dup_content_option_data.use_doe) orig_ptr = (orig_doe_ptr == NULL) ? dp : orig_doe_ptr; else orig_ptr = dp; continue_loop = PatternMatchAdjustRelativeOffsets((PatternMatchData *)node->option_data, &dup_content_option_data, doe_ptr, orig_ptr); } } else if (node->option_type == RULE_OPTION_TYPE_PCRE) { if (dup_pcre_option_data.options & SNORT_PCRE_INVERT) { continue_loop = 0; } else { const uint8_t *orig_ptr; if (dup_pcre_option_data.options & SNORT_PCRE_RELATIVE) orig_ptr = (orig_doe_ptr == NULL) ? dp : orig_doe_ptr; else orig_ptr = dp; continue_loop = PcreAdjustRelativeOffsets(&dup_pcre_option_data, doe_ptr - orig_ptr); } } else { continue_loop = 0; } } else { continue_loop = 0; } #ifdef PERF_PROFILING /* We're essentially checking this node again and it potentially * might match again */ if (continue_loop && PROFILING_RULES) node->checks++; #endif loop_count++; if (continue_loop) UpdateDoePtr(orig_doe_ptr, 0); } while (continue_loop); if (flowbits_setoperation && (result == DETECTION_OPTION_MATCH)) { /* Do any setting/clearing/resetting/toggling of flowbits here * given that other rule options matched. */ rval = node->evaluate(node->option_data, eval_data->p); if (rval != DETECTION_OPTION_MATCH) { result = rval; } } if (eval_data->flowbit_failed) { /* something deeper in the tree failed a flowbit test, we may need to * reeval this node. */ node->last_check.flowbit_failed = 1; } node->last_check.result = result; if (result == DETECTION_OPTION_NO_MATCH) { NODE_PROFILE_END_NOMATCH(node); } else { NODE_PROFILE_END_MATCH(node); } Reset_DetectFlags(save_dflags); return result; } #ifdef PERF_PROFILING typedef struct node_profile_stats { uint64_t ticks; uint64_t ticks_match; uint64_t ticks_no_match; uint64_t checks; uint64_t disables; } node_profile_stats_t; static void detection_option_node_update_otn_stats(detection_option_tree_node_t *node, node_profile_stats_t *stats, uint64_t checks #ifdef PPM_MGR , uint64_t disables #endif ) { int i; node_profile_stats_t local_stats; /* cumulative stats for this node */ if (stats) { local_stats.ticks = stats->ticks + node->ticks; local_stats.ticks_match = stats->ticks_match + node->ticks_match; local_stats.ticks_no_match = stats->ticks_no_match + node->ticks_no_match; if (node->checks > stats->checks) local_stats.checks = node->checks; else local_stats.checks = stats->checks; #ifdef PPM_MGR local_stats.disables = disables; #endif } else { local_stats.ticks = node->ticks; local_stats.ticks_match = node->ticks_match; local_stats.ticks_no_match = node->ticks_no_match; local_stats.checks = node->checks; #ifdef PPM_MGR local_stats.disables = disables; #endif } if (node->option_type == RULE_OPTION_TYPE_LEAF_NODE) { OptTreeNode *otn = (OptTreeNode *)node->option_data; /* Update stats for this otn */ otn->ticks += local_stats.ticks; otn->ticks_match += local_stats.ticks_match; otn->ticks_no_match += local_stats.ticks_no_match; if (local_stats.checks > otn->checks) otn->checks = local_stats.checks; #ifdef PPM_MGR otn->ppm_disable_cnt += local_stats.disables; #endif } if (node->num_children) { for (i=0;inum_children; i++) { detection_option_node_update_otn_stats(node->children[i], &local_stats, checks #ifdef PPM_MGR , disables #endif ); } } } void detection_option_tree_update_otn_stats(SFXHASH *doth) { SFXHASH_NODE *hashnode; if (doth == NULL) return; /* Find the first tree root in the table */ hashnode = sfxhash_findfirst(doth); while (hashnode) { detection_option_tree_node_t *node = hashnode->data; if (node->checks) { detection_option_node_update_otn_stats(node, NULL, node->checks #ifdef PPM_MGR , node->ppm_disable_cnt #endif ); } hashnode = sfxhash_findnext(doth); } } #endif snort-2.9.15.1/src/detection-plugins/detection_options.h0000644000175200017520000000670513571422607020206 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2007-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** **/ /** ** @file detection_options.h ** ** @author Steven Sturges ** ** @brief Support functions for rule option tree ** ** This implements tree processing for rule options, evaluating common ** detection options only once per pattern match. ** */ #ifndef DETECTION_OPTIONS_H_ #define DETECTION_OPTIONS_H_ #include "sf_types.h" #include "decode.h" #include "sfutil/sfxhash.h" #include "rule_option_types.h" #define DETECTION_OPTION_EQUAL 0 #define DETECTION_OPTION_NOT_EQUAL 1 #define DETECTION_OPTION_NO_MATCH 0 #define DETECTION_OPTION_MATCH 1 #define DETECTION_OPTION_NO_ALERT 2 #define DETECTION_OPTION_FAILED_BIT 3 #include "sfutil/sfhashfcn.h" typedef int (*eval_func_t)(void *option_data, Packet *p); typedef struct _detection_option_tree_node { void *option_data; option_type_t option_type; eval_func_t evaluate; int num_children; struct _detection_option_tree_node **children; int relative_children; int result; struct { struct timeval ts; uint64_t packet_number; uint32_t rebuild_flag; char result; char is_relative; char flowbit_failed; char pad; /* Keep 4 byte alignment */ } last_check; #ifdef PERF_PROFILING uint64_t ticks; uint64_t ticks_match; uint64_t ticks_no_match; uint64_t checks; #endif #ifdef PPM_MGR uint64_t ppm_disable_cnt; /*PPM */ uint64_t ppm_enable_cnt; /*PPM */ #endif } detection_option_tree_node_t; typedef struct _detection_option_tree_root { int num_children; detection_option_tree_node_t **children; #ifdef PPM_MGR uint64_t ppm_suspend_time; /* PPM */ uint64_t ppm_disable_cnt; /*PPM */ int tree_state; #endif } detection_option_tree_root_t; typedef struct _detection_option_eval_data { void *pomd; void *pmd; Packet *p; char flowbit_failed; char flowbit_noalert; uint8_t detection_filter_count; } detection_option_eval_data_t; int add_detection_option(struct _SnortConfig *, option_type_t type, void *option_data, void **existing_data); int add_detection_option_tree(struct _SnortConfig *, detection_option_tree_node_t *option_tree, void **existing_data); int detection_option_node_evaluate(detection_option_tree_node_t *node, detection_option_eval_data_t *eval_data); void DetectionHashTableFree(SFXHASH *); void DetectionTreeHashTableFree(SFXHASH *); #ifdef DEBUG_OPTION_TREE void print_option_tree(detection_option_tree_node_t *node, int level); #endif #ifdef PERF_PROFILING void detection_option_tree_update_otn_stats(SFXHASH *); #endif #endif /* DETECTION_OPTIONS_H_ */ snort-2.9.15.1/src/detection-plugins/sp_asn1.c0000644000175200017520000002205013571422607016003 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Author: Daniel Roelker ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** ** @file sp_asn1.c ** ** @author Daniel Roelker ** ** @brief Decode and detect ASN.1 types, lengths, and data. ** ** This detection plugin adds ASN.1 detection functions on a per rule ** basis. ASN.1 detection plugins can be added by editing this file and ** providing an interface in the configuration code. ** ** Detection Plugin Interface: ** ** asn1: [detection function],[arguments],[offset type],[size] ** ** Detection Functions: ** ** bitstring_overflow: no arguments ** double_overflow: no arguments ** oversize_length: max size (if no max size, then just return value) ** ** alert udp any any -> any 161 (msg:"foo"; \ ** asn1: oversize_length 10000, absolute_offset 0;) ** ** alert tcp any any -> any 162 (msg:"foo2"; \ ** asn1: bitstring_overflow, oversize_length 500, relative_offset 7;) ** ** ** Note that further general information about ASN.1 can be found in ** the file doc/README.asn1. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "sf_types.h" #include "snort_bounds.h" #include "rules.h" #include "treenodes.h" #include "decode.h" #include "plugbase.h" #include "parser.h" #include "snort_debug.h" #include "util.h" #include "plugin_enum.h" #include "asn1.h" #include "sp_asn1.h" #include "sp_asn1_detect.h" #include "sfhashfcn.h" #include "detection_util.h" #define BITSTRING_OPT "bitstring_overflow" #define DOUBLE_OPT "double_overflow" #define LENGTH_OPT "oversize_length" #define DBL_FREE_OPT "double_free" #define ABS_OFFSET_OPT "absolute_offset" #define REL_OFFSET_OPT "relative_offset" #define PRINT_OPT "print" #define DELIMITERS " ,\t\n" #include "snort.h" #include "profiler.h" #ifdef PERF_PROFILING PreprocStats asn1PerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif #include "sfhashfcn.h" #include "detection_options.h" uint32_t Asn1Hash(void *d) { uint32_t a,b,c; ASN1_CTXT *data = (ASN1_CTXT *)d; a = data->bs_overflow; b = data->double_overflow; c = data->print; mix(a,b,c); a += data->length; b += data->max_length; c += data->offset; mix(a,b,c); a += data->offset_type; b += RULE_OPTION_TYPE_ASN1; final(a,b,c); return c; } int Asn1Compare(void *l, void *r) { ASN1_CTXT *left = (ASN1_CTXT *)l; ASN1_CTXT *right = (ASN1_CTXT *)r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if ((left->bs_overflow == right->bs_overflow) && (left->double_overflow == right->double_overflow) && (left->print == right->print) && (left->length == right->length) && (left->max_length == right->max_length) && (left->offset == right->offset) && (left->offset_type == right->offset_type)) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } /* ** NAME ** Asn1RuleParse:: */ /** ** Parse the detection option arguments. ** - bitstring_overflow ** - double_overflow ** - oversize_length ** - print ** - abs_offset ** - rel_offset ** ** @return void */ static void Asn1RuleParse(char *data, OptTreeNode *otn, ASN1_CTXT *asn1) { char *pcTok; char *endTok; if(!data) { FatalError("%s(%d) => No options to 'asn1' detection plugin.\n", file_name, file_line); } pcTok = strtok(data, DELIMITERS); if(!pcTok) { FatalError("%s(%d) => No options to 'asn1' detection plugin.\n", file_name, file_line); } while(pcTok) { if(!strcasecmp(pcTok, BITSTRING_OPT)) { asn1->bs_overflow = 1; } else if(!strcasecmp(pcTok, DOUBLE_OPT)) { asn1->double_overflow = 1; } else if(!strcasecmp(pcTok, PRINT_OPT)) { asn1->print = 1; } else if(!strcasecmp(pcTok, LENGTH_OPT)) { long int max_length; char *pcEnd; pcTok = strtok(NULL, DELIMITERS); if(!pcTok) { FatalError("%s(%d) => No option to '%s' in 'asn1' detection " "plugin\n", file_name, file_line, LENGTH_OPT); } max_length = SnortStrtolRange(pcTok, &pcEnd, 10, 0, INT32_MAX); if ((pcEnd == pcTok) || (*pcEnd) || (errno == ERANGE)) { FatalError("%s(%d) => Negative size, underflow or overflow " "(of long int) to '%s' in 'asn1' detection plugin. " "Must be positive or zero.\n", file_name, file_line, LENGTH_OPT); } asn1->length = 1; asn1->max_length = (unsigned int)max_length; } else if(!strcasecmp(pcTok, ABS_OFFSET_OPT)) { pcTok = strtok(NULL, DELIMITERS); if(!pcTok) { FatalError("%s(%d) => No option to '%s' in 'asn1' detection " "plugin\n", file_name, file_line, ABS_OFFSET_OPT); } asn1->offset_type = ABS_OFFSET; asn1->offset = SnortStrtol(pcTok, &endTok, 10); if (endTok == pcTok) { FatalError("%s(%d) => Invalid parameter to '%s' in 'asn1' " "detection plugin\n", file_name, file_line, ABS_OFFSET_OPT); } } else if(!strcasecmp(pcTok, REL_OFFSET_OPT)) { pcTok = strtok(NULL, DELIMITERS); if(!pcTok) { FatalError("%s(%d) => No option to '%s' in 'asn1' detection " "plugin\n", file_name, file_line, REL_OFFSET_OPT); } asn1->offset_type = REL_OFFSET; asn1->offset = SnortStrtol(pcTok, &endTok, 10); if (endTok == pcTok) { FatalError("%s(%d) => Invalid parameter to '%s' in 'asn1' " "detection plugin\n", file_name, file_line, pcTok); } } else { FatalError("%s(%d) => Unknown ('%s') asn1 detection option.\n", file_name, file_line, pcTok); } pcTok = strtok(NULL, DELIMITERS); } return; } /* ** NAME ** Asn1Detect:: */ /** ** The main snort detection function. We grab the context ptr from the ** otn and go forth. We check all the offsets to make sure we're in ** bounds, etc. ** ** @return integer ** ** @retval 0 failed ** @retval 1 detected */ int Asn1Detect(void *context, Packet *p) { ASN1_CTXT *ctxt; PROFILE_VARS; /* ** Failed if there is no data to decode. */ if(!p->data) return DETECTION_OPTION_NO_MATCH; PREPROC_PROFILE_START(asn1PerfStats); ctxt = (ASN1_CTXT *)context; if (Asn1DoDetect(p->data, p->dsize, ctxt, doe_ptr)) { PREPROC_PROFILE_END(asn1PerfStats); return DETECTION_OPTION_MATCH; } PREPROC_PROFILE_END(asn1PerfStats); return DETECTION_OPTION_NO_MATCH; } static void Asn1Init(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { ASN1_CTXT *asn1; void *ds_ptr_dup; OptFpList *ofl; /* * allocate the data structure and attach * it to the rule's data struct list */ asn1 = (ASN1_CTXT *)SnortAlloc(sizeof(ASN1_CTXT)); Asn1RuleParse(data, otn, asn1); if (add_detection_option(sc, RULE_OPTION_TYPE_ASN1, (void *)asn1, &ds_ptr_dup) == DETECTION_OPTION_EQUAL) { free(asn1); asn1 = ds_ptr_dup; } ofl = AddOptFuncToList(Asn1Detect, otn); ofl->context = (void *)asn1; ofl->type = RULE_OPTION_TYPE_ASN1; if (asn1->offset_type == REL_OFFSET) ofl->isRelative = 1; } void SetupAsn1(void) { /* map the keyword to an initialization/processing function */ RegisterRuleOption("asn1", Asn1Init, NULL, OPT_TYPE_DETECTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("asn1", &asn1PerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: ASN1 Setup\n");); } snort-2.9.15.1/src/detection-plugins/sp_asn1.h0000644000175200017520000000225513571422607016015 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2004-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #ifndef __SP_ASN1_H__ #define __SP_ASN1_H__ void SetupAsn1(void); uint32_t Asn1Hash(void *d); int Asn1Compare(void *l, void *r); #endif snort-2.9.15.1/src/detection-plugins/sp_asn1_detect.c0000644000175200017520000002423013571422607017335 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Author: Daniel Roelker ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** ** @file sp_asn1_detect.c ** ** @author Daniel Roelker ** ** @brief Decode and detect ASN.1 types, lengths, and data. ** ** This detection plugin adds ASN.1 detection functions on a per rule ** basis. ASN.1 detection plugins can be added by editing this file and ** providing an interface in the configuration code. ** ** Detection Plugin Interface: ** ** asn1: [detection function],[arguments],[offset type],[size] ** ** Detection Functions: ** ** bitstring_overflow: no arguments ** double_overflow: no arguments ** oversize_length: max size (if no max size, then just return value) ** ** alert udp any any -> any 161 (msg:"foo"; \ ** asn1: oversize_length 10000, absolute_offset 0;) ** ** alert tcp any any -> any 162 (msg:"foo2"; \ ** asn1: bitstring_overflow, oversize_length 500, relative_offset 7;) ** ** ** Note that further general information about ASN.1 can be found in ** the file doc/README.asn1. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "sf_types.h" #ifndef SF_SNORT_ENGINE_DLL #include "snort_debug.h" #else /* Ignore debug statements */ #include #define DEBUG_WRAP(x) #endif #include "sfutil/asn1.h" #include "sp_asn1_detect.h" #include "snort.h" /* * Check to make sure that p is less than or equal to the ptr range * pointers * * 1 means it's in bounds, 0 means it's not */ static inline int inBounds( const uint8_t *start, const uint8_t *end, const uint8_t *p) { if(p >= start && p < end) { return 1; } return 0; } /* ** NAME ** BitStringOverflow:: */ /** ** The neccessary info to detect possible bitstring overflows. Thanks ** once again to microsoft for keeping us in business. ** ** @return integer ** ** @retval 0 failed ** @retval 1 detected */ static int BitStringOverflow(ASN1_TYPE *asn1, void * user) { if(!asn1) return 0; /* ** Here's what this means: ** ** If the ASN.1 type is a non-constructed bitstring (meaning that ** there is only one encoding, not multiple encodings). And ** the number of bits to ignore (this is taken from the first byte) ** is greater than the total number of bits, then we have an ** exploit attempt. */ if(asn1->ident.tag == SF_ASN1_TAG_BIT_STR && !asn1->ident.flag) { if(asn1->len.size && asn1->data && (((asn1->len.size - 1)<<3) < (unsigned int)asn1->data[0])) { return 1; } } return 0; } /* ** NAME ** DetectBitStringOverflow:: */ /** ** This is just a wrapper to the traverse function. It's important because ** this allows us to do more with individual nodes in the future. ** ** @return integer ** ** @retval 0 failed ** @rteval 1 detected */ static int DetectBitStringOverflow(ASN1_TYPE *asn1) { return asn1_traverse(asn1, NULL, BitStringOverflow); } /* ** NAME ** DoubleOverflow:: */ /** ** This is the info to detect double overflows. This may not be a ** remotely exploitable (remote services may not call the vulnerable ** microsoft function), but better safe than sorry. ** ** @return integer ** ** @retval 0 failed ** @retval 1 detected */ static int DoubleOverflow(ASN1_TYPE *asn1, void *user) { if(!asn1) return 0; /* ** Here's what this does. ** ** There is a vulnerablity in the MSASN1 library when decoding ** a double (real) type. If the encoding is ASCII (specified by ** not setting bit 7 or 8), and the buffer is greater than 256, ** then you overflow the array in the function. */ if(asn1->ident.tag == SF_ASN1_TAG_REAL && !asn1->ident.flag) { if(asn1->len.size && asn1->data && ((asn1->data[0] & 0xc0) == 0x00) && (asn1->len.size > 256)) { return 1; } } return 0; } /* ** NAME ** DetectDoubleOverflow:: */ /** ** This is just a wrapper to the traverse function. It's important because ** this allows us to do more with individual nodes in the future. ** ** @return integer ** ** @retval 0 failed ** @rteval 1 detected */ static int DetectDoubleOverflow(ASN1_TYPE *asn1) { return asn1_traverse(asn1, NULL, DoubleOverflow); } /* ** NAME ** OversizeLength:: */ /** ** This is the most generic of our ASN.1 detection functionalities. This ** will compare the ASN.1 type lengths against the user defined max ** length and alert if the length is greater than the user supplied length. ** ** @return integer ** ** @retval 0 failed ** @retval 1 detected */ static int OversizeLength(ASN1_TYPE *asn1, void *user) { unsigned int *max_size; if(!asn1 || !user) return 0; max_size = (unsigned int *)user; if(*max_size && *max_size <= asn1->len.size) return 1; return 0; } /* ** NAME ** DetectOversizeLength:: */ /** ** This is just a wrapper to the traverse function. It's important because ** this allows us to do more with individual nodes in the future. ** ** @return integer ** ** @retval 0 failed ** @rteval 1 detected */ static int DetectOversizeLength(ASN1_TYPE *asn1, unsigned int max_size) { return asn1_traverse(asn1, (void *)&max_size, OversizeLength); } /* ** NAME ** Asn1DetectFuncs:: */ /** ** The main function for adding ASN.1 detection type functionality. ** ** @return integer ** ** @retval 0 failed ** @retval 1 detected */ static int Asn1DetectFuncs(ASN1_TYPE *asn1, ASN1_CTXT *ctxt, int dec_ret_val) { int iRet = 0; /* ** Print first, before we do other detection. If print is the only ** option, then we want to evaluate this option as true and continue. ** Otherwise, if another option is wrong, then we */ if(ctxt->print) { asn1_traverse(asn1, NULL, asn1_print_types); iRet = 1; } /* ** Let's check the bitstring overflow. */ if(ctxt->bs_overflow) { iRet = DetectBitStringOverflow(asn1); if(iRet) return 1; } if(ctxt->double_overflow) { iRet = DetectDoubleOverflow(asn1); if(iRet) return 1; } if(ctxt->length) { iRet = DetectOversizeLength(asn1, ctxt->max_length); /* ** If we didn't detect any oversize length in the decoded structs, ** that might be because we had a really overlong length that is ** bigger than our data type could hold. In this case, it's ** overlong too. */ if(!iRet && dec_ret_val == ASN1_ERR_OVERLONG_LEN) iRet = 1; /* ** We add this return in here, so that we follow suit with the ** previous detections. Just trying to short-circuit any future ** problems if we change the code flow here. */ if(iRet) return 1; } return iRet; } /* ** NAME ** Asn1DoDetect:: */ /** ** Workhorse detection function. Does not depend on OTN. ** We check all the offsets to make sure we're in bounds, etc. ** ** @return integer ** ** @retval 0 failed ** @retval 1 detected */ int Asn1DoDetect(const uint8_t *data, uint16_t dsize, ASN1_CTXT *ctxt, const uint8_t *rel_ptr) { ASN1_TYPE *asn1; int iRet; unsigned int size; const uint8_t *start; const uint8_t *end; const uint8_t *offset = NULL; /* ** Failed if there is no data to decode. */ if (data == NULL) return 0; start = data; end = start + dsize; switch(ctxt->offset_type) { case REL_OFFSET: if(!rel_ptr) { DEBUG_WRAP(DebugMessage(DEBUG_ASN1, "[*] No rel_ptr for " "relative offset, so we are bailing.\n");); return 0; } /* ** Check that it is in bounds first. ** Because rel_ptr can be "end" in the last match, ** use end + 1 for upper bound ** Bound checked also after offset is applied */ if(!inBounds(start, end + 1, rel_ptr)) { DEBUG_WRAP(DebugMessage(DEBUG_ASN1, "[*] ASN.1 bounds " "check failed for rel_ptr.\n");); return 0; } offset = rel_ptr+ctxt->offset; if(!inBounds(start, end, offset)) { DEBUG_WRAP(DebugMessage(DEBUG_ASN1, "[*] ASN.1 bounds " "check failed rel_ptr+offset.\n");); return 0; } break; case ABS_OFFSET: default: offset = start+ctxt->offset; if(!inBounds(start, end, offset)) { DEBUG_WRAP(DebugMessage(DEBUG_ASN1, "[*] ASN.1 bounds " "check failed.\n");); return 0; } break; } /* ** Set size for asn1_decode(). This should never be <0 since ** we do the previous in bounds check. */ size = end - offset; iRet = asn1_decode(offset, size, &asn1); if(iRet && !asn1) { DEBUG_WRAP(DebugMessage(DEBUG_ASN1, "[*] ASN.1 decode failed " "miserably.\n");); return 0; } /* ** Let's do detection now. */ return Asn1DetectFuncs(asn1, ctxt, iRet); } snort-2.9.15.1/src/detection-plugins/sp_asn1_detect.h0000644000175200017520000000263013571422607017342 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2005-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ #ifndef __SP_ASN1_DETECT_H__ #define __SP_ASN1_DETECT_H__ #define ABS_OFFSET 1 #define REL_OFFSET 2 typedef struct s_ASN1_CTXT { int bs_overflow; int double_overflow; int print; int length; unsigned int max_length; int offset; int offset_type; } ASN1_CTXT; int Asn1DoDetect(const uint8_t *, uint16_t, ASN1_CTXT *, const uint8_t *); #endif snort-2.9.15.1/src/detection-plugins/sp_byte_check.c0000644000175200017520000006555613571422607017263 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Author: Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* sp_byte_check * * Purpose: * Test a byte field against a specific value (with operator). Capable * of testing binary values or converting represenative byte strings * to their binary equivalent and testing them. * * * Arguments: * Required: * : number of bytes to pick up from the packet * : operation to perform to test the value (<,>,=,!) * : value to test the converted value against * : number of bytes into the payload to start processing * Optional: * ["relative"]: offset relative to last pattern match * ["big"]: process data as big endian (default) * ["little"]: process data as little endian * ["string"]: converted bytes represented as a string needing conversion * ["hex"]: converted string data is represented in hexidecimal * ["dec"]: converted string data is represented in decimal * ["oct"]: converted string data is represented in octal * * sample rules: * alert udp $EXTERNAL_NET any -> $HOME_NET any \ * (msg:"AMD procedure 7 plog overflow "; \ * content: "|00 04 93 F3|"; \ * content: "|00 00 00 07|"; distance: 4; within: 4; \ * byte_test: 4,>, 1000, 20, relative;) * * alert tcp $EXTERNAL_NET any -> $HOME_NET any \ * (msg:"AMD procedure 7 plog overflow "; \ * content: "|00 04 93 F3|"; \ * content: "|00 00 00 07|"; distance: 4; within: 4; \ * byte_test: 4, >,1000, 20, relative;) * * alert udp any any -> any 1234 \ * (byte_test: 4, =, 1234, 0, string, dec; \ * msg: "got 1234!";) * * alert udp any any -> any 1235 \ * (byte_test: 3, =, 123, 0, string, dec; \ * msg: "got 123!";) * * alert udp any any -> any 1236 \ * (byte_test: 2, =, 12, 0, string, dec; \ * msg: "got 12!";) * * alert udp any any -> any 1237 \ * (byte_test: 10, =, 1234567890, 0, string, dec; \ * msg: "got 1234567890!";) * * alert udp any any -> any 1238 \ * (byte_test: 8, =, 0xdeadbeef, 0, string, hex; \ * msg: "got DEADBEEF!";) * * Effect: * * Reads in the indicated bytes, converts them to an numeric * representation and then performs the indicated operation/test on * the data using the value field. Returns 1 if the operation is true, * 0 if it is not. * * Comments: * * Any comments? * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifdef HAVE_STRINGS_H #include #endif #include #include "sf_types.h" #include "snort_bounds.h" #include "byte_extract.h" #include "rules.h" #include "treenodes.h" #include "decode.h" #include "plugbase.h" #include "parser.h" #include "snort_debug.h" #include "util.h" #include "plugin_enum.h" #include "mstring.h" #include "sfhashfcn.h" #include "sp_byte_check.h" #include "sp_byte_extract.h" #include "sp_byte_math.h" #define PARSELEN 10 #define TEXTLEN (PARSELEN + 2) #include "snort.h" #include "profiler.h" #include "sfhashfcn.h" #include "detection_options.h" #include "detection_util.h" #ifdef PERF_PROFILING PreprocStats byteTestPerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif typedef struct _ByteTestOverrideData { char *keyword; char *option; union { RuleOptOverrideFunc fptr; void *void_fptr; } fptr; struct _ByteTestOverrideData *next; } ByteTestOverrideData; ByteTestOverrideData *byteTestOverrideFuncs = NULL; static void ByteTestOverride(char *keyword, char *option, RuleOptOverrideFunc roo_func); static void ByteTestOverrideFuncsFree(void); static void ByteTestInit(struct _SnortConfig *, char *, OptTreeNode *, int); static ByteTestOverrideData * ByteTestParse(char *data, ByteTestData *idx, OptTreeNode *otn); static void ByteTestOverrideCleanup(int, void *); uint32_t ByteTestHash(void *d) { uint32_t a,b,c; ByteTestData *data = (ByteTestData *)d; a = data->bytes_to_compare; b = data->cmp_value; c = data->operator; mix(a,b,c); a += data->offset; b += (data->not_flag << 24 | data->relative_flag << 16 | data->data_string_convert_flag << 8 | data->endianess); c += data->base; mix(a,b,c); a += data->bitmask_val; b += RULE_OPTION_TYPE_BYTE_TEST; c += (data->cmp_value_var << 8 | data->offset_var ); mix(a,b,c); #if (defined(__ia64) || defined(__amd64) || defined(_LP64)) { /* Cleanup warning because of cast from 64bit ptr to 32bit int * warning on 64bit OSs */ uint64_t ptr; /* Addresses are 64bits */ ptr = (uint64_t) data->byte_order_func; a += (ptr >> 32); b += (ptr & 0xFFFFFFFF); } #else a += (uint32_t)data->byte_order_func; #endif final(a,b,c); return c; } int ByteTestCompare(void *l, void *r) { ByteTestData *left = (ByteTestData *)l; ByteTestData *right = (ByteTestData *)r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if (( left->bytes_to_compare == right->bytes_to_compare) && ( left->cmp_value == right->cmp_value) && ( left->operator == right->operator) && ( left->offset == right->offset) && ( left->not_flag == right->not_flag) && ( left->relative_flag == right->relative_flag) && ( left->data_string_convert_flag == right->data_string_convert_flag) && ( left->endianess == right->endianess) && ( left->base == right->base) && ( left->cmp_value_var == right->cmp_value_var) && ( left->offset_var == right->offset_var) && ( left->byte_order_func == right->byte_order_func) && ( left->bitmask_val == right->bitmask_val)) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } static void ByteTestOverride(char *keyword, char *option, RuleOptOverrideFunc roo_func) { ByteTestOverrideData *new = SnortAlloc(sizeof(ByteTestOverrideData)); new->keyword = SnortStrdup(keyword); new->option = SnortStrdup(option); new->func = roo_func; new->next = byteTestOverrideFuncs; byteTestOverrideFuncs = new; } static void ByteTestOverrideFuncsFree(void) { ByteTestOverrideData *node = byteTestOverrideFuncs; while (node != NULL) { ByteTestOverrideData *tmp = node; node = node->next; if (tmp->keyword != NULL) free(tmp->keyword); if (tmp->option != NULL) free(tmp->option); free(tmp); } byteTestOverrideFuncs = NULL; } /**************************************************************************** * Function: SetupByteTest() * * Purpose: Register byte_test name and initialization function * * Arguments: None. * * Returns: void function * ****************************************************************************/ void SetupByteTest(void) { /* map the keyword to an initialization/processing function */ RegisterRuleOption("byte_test", ByteTestInit, ByteTestOverride, OPT_TYPE_DETECTION, NULL); AddFuncToCleanExitList(ByteTestOverrideCleanup, NULL); AddFuncToRuleOptParseCleanupList(ByteTestOverrideFuncsFree); #ifdef PERF_PROFILING RegisterPreprocessorProfile("byte_test", &byteTestPerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: ByteTest Setup\n");); } /**************************************************************************** * * Function: ByteTestInit(char *, OptTreeNode *) * * Purpose: Generic rule configuration function. Handles parsing the rule * information and attaching the associated detection function to * the OTN. * * Arguments: data => rule arguments/data * otn => pointer to the current rule option list node * protocol => protocol the rule is on (we don't care in this case) * * Returns: void function * ****************************************************************************/ static void ByteTestInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { ByteTestData *idx; OptFpList *fpl; ByteTestOverrideData *override; void *idx_dup; /* allocate the data structure and attach it to the rule's data struct list */ idx = (ByteTestData *) calloc(sizeof(ByteTestData), sizeof(char)); if(idx == NULL) { FatalError("%s(%d): Unable to allocate byte_test data node\n", file_name, file_line); } /* this is where the keyword arguments are processed and placed into the rule option's data structure */ override = ByteTestParse(data, idx, otn); if (override) { /* There is an override function */ free(idx); override->func(sc, override->keyword, override->option, data, otn, protocol); return; } fpl = AddOptFuncToList(ByteTest, otn); fpl->type = RULE_OPTION_TYPE_BYTE_TEST; if (add_detection_option(sc, RULE_OPTION_TYPE_BYTE_TEST, (void *)idx, &idx_dup) == DETECTION_OPTION_EQUAL) { #ifdef DEBUG_RULE_OPTION_TREE LogMessage("Duplicate ByteCheck:\n%d %d %d %d %c %c %c %c %d 0x%x\n" "%d %d %d %d %c %c %c %c %d 0x%x\n\n", idx->bytes_to_compare, idx->cmp_value, idx->operator, idx->offset, idx->not_flag, idx->relative_flag, idx->data_string_convert_flag, idx->endianess, idx->base, idx->bitmask_val, ((ByteTestData *)idx_dup)->bytes_to_compare, ((ByteTestData *)idx_dup)->cmp_value, ((ByteTestData *)idx_dup)->operator, ((ByteTestData *)idx_dup)->offset, ((ByteTestData *)idx_dup)->not_flag, ((ByteTestData *)idx_dup)->relative_flag, ((ByteTestData *)idx_dup)->data_string_convert_flag, ((ByteTestData *)idx_dup)->endianess, ((ByteTestData *)idx_dup)->base, ((ByteTestData *)idx_dup)->bitmask_val); #endif free(idx); idx = idx_dup; } /* attach it to the context node so that we can call each instance * individually */ fpl->context = (void *) idx; if (idx->relative_flag == 1) fpl->isRelative = 1; } /**************************************************************************** * * Function: ByteTestParse(char *, ByteTestData *, OptTreeNode *) * * Purpose: This is the function that is used to process the option keyword's * arguments and attach them to the rule's data structures. * * Arguments: data => argument data * idx => pointer to the processed argument storage * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ static ByteTestOverrideData * ByteTestParse(char *data, ByteTestData *idx, OptTreeNode *otn) { char **toks; char *endp; int num_toks; char *cptr; int i =0; RuleOptByteOrderFunc tmp_byte_order_func; toks = mSplit(data, ",", 13, &num_toks, 0); if(num_toks < 4) ParseError(" Bad arguments to byte_test: %s\n",data); /* set how many bytes to process from the packet */ idx->bytes_to_compare = strtol(toks[0], &endp, 10); if(toks[0] == endp) { ParseError(" Unable to parse as byte value %s\n",toks[0]); } if(*endp != '\0') { ParseError("byte_test option has bad value: %s.", toks[0]); } if(idx->bytes_to_compare > PARSELEN || idx->bytes_to_compare == 0) { ParseError(" byte_test can't process more than " "10 bytes!\n"); } cptr = toks[1]; while(isspace((int)*cptr)) {cptr++;} if(*cptr == '!') { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "enabling not flag\n");); idx->not_flag = 1; cptr++; } if (idx->not_flag && strlen(cptr) == 0) { idx->operator = BT_EQUALS; } else { /* set the operator */ switch(*cptr) { case '<': idx->operator = BT_LESS_THAN; cptr++; if (*cptr == '=') idx->operator = BT_LESS_THAN_EQUAL; else cptr--; break; case '=': idx->operator = BT_EQUALS; break; case '>': idx->operator = BT_GREATER_THAN; cptr++; if (*cptr == '=') idx->operator = BT_GREATER_THAN_EQUAL; else cptr--; break; case '&': idx->operator = BT_AND; break; case '^': idx->operator = BT_XOR; break; default: ParseError(" byte_test unknown " "operator ('%c, %s')\n", *cptr, toks[1]); } } /* set the value to test against */ if (isdigit(toks[2][0]) || toks[2][0] == '-') { int64_t rval = SnortStrtoul(toks[2], &endp,0); if (rval > MAX_RVAL) { ParseError("byte_test rule option has invalid rvalue." "Valid rvalue range %u-%u.", MIN_RVAL-1,MAX_RVAL); } idx->cmp_value=rval; idx->cmp_value_var = -1; if(toks[2] == endp) { ParseError(" Unable to parse as comparison value %s\n", toks[2]); } if(*endp != '\0') { ParseError("byte_test option has bad comparison value: %s.", toks[2]); } if(errno == ERANGE) { ParseError("Bad range: %s\n", toks[2]); } } else { if ( bytemath_variable_name && (strcmp(bytemath_variable_name,toks[2]) == 0) ) { idx->cmp_value_var= BYTE_MATH_VAR_INDEX; // 2 } else { idx->cmp_value_var = GetVarByName(toks[2]); if ( idx->cmp_value_var == BYTE_EXTRACT_NO_VAR) ParseError(BYTE_TEST_INVALID_ERR_FMT, "byte_test : value", toks[2]); } } if (isdigit(toks[3][0]) || toks[3][0] == '-') { /* set offset */ idx->offset = strtol(toks[3], &endp, 10); idx->offset_var = -1; if(toks[3] == endp) { ParseError(" Unable to parse as offset value %s\n", toks[3]); } if(*endp != '\0') { ParseError("byte_test option has bad offset: %s.", toks[3]); } } else { if ( bytemath_variable_name && (strcmp(bytemath_variable_name,toks[3]) == 0) ) { idx->offset_var= BYTE_MATH_VAR_INDEX; // 2 } else { idx->offset_var = GetVarByName(toks[3]); if ( idx->offset_var == BYTE_EXTRACT_NO_VAR) ParseError(BYTE_TEST_INVALID_ERR_FMT, "byte_test : offset", toks[3]); } } i = 4; /* is it a relative offset? */ if(num_toks > 4) { while(i < num_toks) { cptr = toks[i]; while(isspace((int)*cptr)) {cptr++;} if(!strcasecmp(cptr, "relative")) { /* the offset is relative to the last pattern match */ idx->relative_flag = 1; } else if(!strcasecmp(cptr, "string")) { /* the data will be represented as a string that needs * to be converted to an int, binary is assumed otherwise */ idx->data_string_convert_flag = 1; } else if(!strcasecmp(cptr, "little")) { idx->endianess = LITTLE; } else if(!strcasecmp(cptr, "big")) { /* this is the default */ idx->endianess = BIG; } else if(!strcasecmp(cptr, "hex")) { idx->base = 16; } else if(!strcasecmp(cptr, "dec")) { idx->base = 10; } else if(!strcasecmp(cptr, "oct")) { idx->base = 8; } else if((tmp_byte_order_func = GetByteOrderFunc(cptr)) != NULL) { idx->byte_order_func = tmp_byte_order_func; } else if(strncasecmp(cptr,"bitmask ",8) == 0) { RuleOptionBitmaskParse(&(idx->bitmask_val), cptr, idx->bytes_to_compare, "BYTE_TEST"); } else { ByteTestOverrideData *override = byteTestOverrideFuncs; while (override != NULL) { if (!strcasecmp(cptr, override->option)) { mSplitFree(&toks, num_toks); return override; } override = override->next; } ParseError("unknown modifier \"%s\"\n",cptr); } i++; } } if (idx->bytes_to_compare > MAX_BYTES_TO_GRAB && !idx->data_string_convert_flag) { ParseError("byte_test rule option cannot extract more than %d bytes without valid string prefix.", MAX_BYTES_TO_GRAB); } /* idx->base is only set if the parameter is specified */ if(!idx->data_string_convert_flag && idx->base) { ParseError("hex, dec and oct modifiers must be used in conjunction \n" " with the 'string' modifier\n"); } if (idx->offset < MIN_BYTE_EXTRACT_OFFSET || idx->offset > MAX_BYTE_EXTRACT_OFFSET) { ParseError("byte_test rule option has invalid offset. " "Valid offsets are between %d and %d.", MIN_BYTE_EXTRACT_OFFSET, MAX_BYTE_EXTRACT_OFFSET); } mSplitFree(&toks, num_toks); return NULL; } /**************************************************************************** * * Function: ByteTest(char *, OptTreeNode *, OptFpList *) * * Purpose: Use this function to perform the particular detection routine * that this rule keyword is supposed to encompass. * * Arguments: p => pointer to the decoded packet * otn => pointer to the current rule's OTN * fp_list => pointer to the function pointer list * * Returns: If the detection test fails, this function *must* return a zero! * On success, it calls the next function in the detection list * ****************************************************************************/ int ByteTest(void *option_data, Packet *p) { ByteTestData *btd = (ByteTestData *)option_data; int rval = DETECTION_OPTION_NO_MATCH; uint32_t value = 0; int success = 0; int dsize; const char *base_ptr, *end_ptr, *start_ptr; int payload_bytes_grabbed; int32_t offset; uint32_t extract_offset, extract_cmp_value; int search_start = 0; PROFILE_VARS; PREPROC_PROFILE_START(byteTestPerfStats); if (Is_DetectFlag(FLAG_ALT_DETECT)) { dsize = DetectBuffer.len; start_ptr = (const char*)DetectBuffer.data; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Using Alternative Detect buffer!\n");); } else if(Is_DetectFlag(FLAG_ALT_DECODE)) { dsize = DecodeBuffer.len; start_ptr = (char *)DecodeBuffer.data; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Using Alternative Decode buffer!\n");); } else { if(IsLimitedDetect(p)) dsize = p->alt_dsize; else dsize = p->dsize; start_ptr = (char *) p->data; } base_ptr = start_ptr; end_ptr = start_ptr + dsize; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "[*] byte test firing...\npayload starts at %p\n", start_ptr);); /* Get values from byte_extract variables, if present. */ if (btd->cmp_value_var >= 0 ) { if(btd->cmp_value_var == BYTE_MATH_VAR_INDEX ) { btd->cmp_value = (int32_t) bytemath_variable; } else { if (btd->cmp_value_var < NUM_BYTE_EXTRACT_VARS) { GetByteExtractValue(&extract_cmp_value, btd->cmp_value_var); btd->cmp_value = (int32_t) extract_cmp_value; } } } if (btd->offset_var >= 0 ) { if(btd->offset_var == BYTE_MATH_VAR_INDEX ) { btd->offset = (int32_t) bytemath_variable; } else { if (btd->offset_var < NUM_BYTE_EXTRACT_VARS) { GetByteExtractValue(&extract_offset, btd->offset_var); btd->offset = (int32_t) extract_offset; } } } if(btd->relative_flag && doe_ptr) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Checking relative offset!\n");); /* @todo: possibly degrade to use the other buffer, seems non-intuitive * Because doe_ptr can be "end" in the last match, * use end + 1 for upper bound * Bound checked also after offset is applied * (see byte_extract() and string_extract()) */ if(!inBounds((const uint8_t *)start_ptr, (const uint8_t *)end_ptr + 1, doe_ptr)) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "[*] byte test bounds check failed..\n");); PREPROC_PROFILE_END(byteTestPerfStats); return rval; } search_start = (doe_ptr - (const uint8_t *)start_ptr) + btd->offset; base_ptr = (const char *)doe_ptr; } else { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "checking absolute offset %d\n", btd->offset);); search_start = btd->offset; base_ptr = start_ptr; } if( search_start < 0 ) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "[*] byte test bounds check failed..\n");); PREPROC_PROFILE_END(byteTestPerfStats); return rval; } base_ptr = base_ptr + btd->offset; /* Use byte_order_func to determine endianess, if present */ if (btd->byte_order_func) { offset = (int32_t) ((const uint8_t *)base_ptr - p->data); btd->endianess = btd->byte_order_func(p, offset); if (btd->endianess == -1) { PREPROC_PROFILE_END(byteTestPerfStats); return DETECTION_OPTION_NO_MATCH; } } /* both of these functions below perform their own bounds checking within * byte_extract.c */ if(!btd->data_string_convert_flag) { if(byte_extract(btd->endianess, btd->bytes_to_compare, (const uint8_t *)base_ptr, (const uint8_t *)start_ptr, (const uint8_t *)end_ptr, &value)) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Byte Extraction Failed\n");); PREPROC_PROFILE_END(byteTestPerfStats); return rval; } payload_bytes_grabbed = (int)btd->bytes_to_compare; } else { payload_bytes_grabbed = string_extract( btd->bytes_to_compare, btd->base, (const uint8_t *)base_ptr, (const uint8_t *)start_ptr, (const uint8_t *)end_ptr, &value); if ( payload_bytes_grabbed < 0 ) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "String Extraction Failed\n");); PREPROC_PROFILE_END(byteTestPerfStats); return rval; } } if(btd->bitmask_val != 0 ) { int num_tailing_zeros_bitmask = getNumberTailingZerosInBitmask(btd->bitmask_val); value = value & btd->bitmask_val ; if ( value && num_tailing_zeros_bitmask ) { value = value >> num_tailing_zeros_bitmask; } } DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Grabbed %d bytes at offset %d cmp_value = 0x%08X(%u) value = 0x%08X(%u)\n", payload_bytes_grabbed, btd->offset, btd->cmp_value,btd->cmp_value,value, value); ); switch(btd->operator) { case BT_LESS_THAN: if(value < btd->cmp_value) success = 1; break; case BT_EQUALS: if(value == btd->cmp_value) success = 1; break; case BT_GREATER_THAN: if(value > btd->cmp_value) success = 1; break; case BT_AND: if ((value & btd->cmp_value) > 0) success = 1; break; case BT_XOR: if ((value ^ btd->cmp_value) > 0) success = 1; break; case BT_GREATER_THAN_EQUAL: if (value >= btd->cmp_value) success = 1; break; case BT_LESS_THAN_EQUAL: if (value <= btd->cmp_value) success = 1; break; case BT_CHECK_ALL: if ((value & btd->cmp_value) == btd->cmp_value) success = 1; break; case BT_CHECK_ATLEASTONE: if ((value & btd->cmp_value) != 0) success = 1; break; case BT_CHECK_NONE: if ((value & btd->cmp_value) == 0) success = 1; break; } if (btd->not_flag) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "checking for not success...flag\n");); if (!success) { rval = DETECTION_OPTION_MATCH; } } else if (success) { rval = DETECTION_OPTION_MATCH; } /* if the test isn't successful, this function *must* return 0 */ PREPROC_PROFILE_END(byteTestPerfStats); return rval; } static void ByteTestOverrideCleanup(int signal, void *data) { if (byteTestOverrideFuncs != NULL) ByteTestOverrideFuncsFree(); } snort-2.9.15.1/src/detection-plugins/sp_byte_check.h0000644000175200017520000000441613571422607017254 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifndef __SP_BYTE_CHECK_H__ #define __SP_BYTE_CHECK_H__ #include "sf_engine/sf_snort_plugin_api.h" #include "decode.h" #include "plugbase.h" #define BT_LESS_THAN CHECK_LT #define BT_EQUALS CHECK_EQ #define BT_GREATER_THAN CHECK_GT #define BT_AND CHECK_AND #define BT_XOR CHECK_XOR #define BT_GREATER_THAN_EQUAL CHECK_GTE #define BT_LESS_THAN_EQUAL CHECK_LTE #define BT_CHECK_ALL CHECK_ALL #define BT_CHECK_ATLEASTONE CHECK_ATLEASTONE #define BT_CHECK_NONE CHECK_NONE #define BIG 0 #define LITTLE 1 #define BYTE_TEST_INVALID_ERR_FMT "Rule option %s uses an undefined byte_extract/byte_math variable name (%s)." //format: rule name, variable name typedef struct _ByteTestData { uint32_t bytes_to_compare; /* number of bytes to compare */ uint32_t cmp_value; uint32_t operator; int32_t offset; uint8_t not_flag; uint8_t relative_flag; uint8_t data_string_convert_flag; int8_t endianess; uint32_t base; int8_t cmp_value_var; int8_t offset_var; RuleOptByteOrderFunc byte_order_func; uint32_t bitmask_val; } ByteTestData; void SetupByteTest(void); uint32_t ByteTestHash(void *d); int ByteTestCompare(void *l, void *r); int ByteTest(void *, Packet *); #endif /* __SP_BYTE_CHECK_H__ */ snort-2.9.15.1/src/detection-plugins/sp_byte_jump.c0000644000175200017520000007005213571422607017144 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Author: Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* sp_byte_jump * * Purpose: * Grab some number of bytes, convert them to their numeric * representation, jump the doe_ptr up that many bytes (for * further pattern matching/byte_testing). * * * Arguments: * Required: * : number of bytes to pick up from the packet * : number of bytes into the payload to grab the bytes * Optional: * ["relative"]: offset relative to last pattern match * ["big"]: process data as big endian (default) * ["little"]: process data as little endian * ["string"]: converted bytes represented as a string needing conversion * ["hex"]: converted string data is represented in hexidecimal * ["dec"]: converted string data is represented in decimal * ["oct"]: converted string data is represented in octal * ["align"]: round the number of converted bytes up to the next * 32-bit boundry * ["post_offset"]: number of bytes to adjust after applying * * sample rules: * alert udp any any -> any 32770:34000 (content: "|00 01 86 B8|"; \ * content: "|00 00 00 01|"; distance: 4; within: 4; \ * byte_jump: 4, 12, relative, align; \ * byte_test: 4, >, 900, 20, relative; \ * msg: "statd format string buffer overflow";) * * Effect: * * Reads in the indicated bytes, converts them to an numeric * representation and then jumps the doe_ptr up * that number of bytes. Returns 1 if the jump is in range (within the * packet) and 0 if it's not. * * Comments: * * Any comments? * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifdef HAVE_STRINGS_H #include #endif #include #include "sf_types.h" #include "snort_bounds.h" #include "rules.h" #include "treenodes.h" #include "decode.h" #include "plugbase.h" #include "parser.h" #include "snort_debug.h" #include "util.h" #include "plugin_enum.h" #include "mstring.h" #include "byte_extract.h" #include "sp_byte_jump.h" #include "sp_byte_extract.h" #include "sp_byte_math.h" #include "sfhashfcn.h" #include "snort.h" #include "profiler.h" #ifdef PERF_PROFILING PreprocStats byteJumpPerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif #include "sfhashfcn.h" #include "detection_options.h" #include "detection_util.h" typedef struct _ByteJumpOverrideData { char *keyword; char *option; union { RuleOptOverrideFunc fptr; void *void_fptr; } fptr; struct _ByteJumpOverrideData *next; } ByteJumpOverrideData; ByteJumpOverrideData *byteJumpOverrideFuncs = NULL; static void ByteJumpOverride(char *keyword, char *option, RuleOptOverrideFunc roo_func); static void ByteJumpOverrideFuncsFree(void); static void ByteJumpInit(struct _SnortConfig *, char *, OptTreeNode *, int); static ByteJumpOverrideData * ByteJumpParse(char *, ByteJumpData *, OptTreeNode *); static void ByteJumpOverrideCleanup(int, void *); uint32_t ByteJumpHash(void *d) { uint32_t a,b,c; ByteJumpData *data = (ByteJumpData *)d; a = data->bytes_to_grab; b = data->offset; c = data->base; mix(a,b,c); a += (data->relative_flag << 24 | data->data_string_convert_flag << 16 | data->from_beginning_flag << 8 | data->align_flag); b += data->bitmask_val; c += data->multiplier; mix(a,b,c); a += RULE_OPTION_TYPE_BYTE_JUMP; b += data->post_offset; c += (data->endianess << 24 | data->offset_var << 16 | data->postoffset_var << 8 | data->from_end_flag); mix(a,b,c); #if (defined(__ia64) || defined(__amd64) || defined(_LP64)) { /* Cleanup warning because of cast from 64bit ptr to 32bit int * warning on 64bit OSs */ uint64_t ptr; /* Addresses are 64bits */ ptr = (uint64_t) data->byte_order_func; a += (ptr >> 32); b += (ptr & 0xFFFFFFFF); } #else a += (uint32_t)data->byte_order_func; #endif final(a,b,c); return c; } int ByteJumpCompare(void *l, void *r) { ByteJumpData *left = (ByteJumpData *)l; ByteJumpData *right = (ByteJumpData *)r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if (( left->bytes_to_grab == right->bytes_to_grab) && ( left->offset == right->offset) && ( left->offset_var == right->offset_var) && ( left->relative_flag == right->relative_flag) && ( left->data_string_convert_flag == right->data_string_convert_flag) && ( left->from_beginning_flag == right->from_beginning_flag) && ( left->from_end_flag == right->from_end_flag) && ( left->align_flag == right->align_flag) && ( left->endianess == right->endianess) && ( left->base == right->base) && ( left->bitmask_val == right->bitmask_val) && ( left->multiplier == right->multiplier) && ( left->post_offset == right->post_offset) && ( left->postoffset_var == right->postoffset_var) && ( left->byte_order_func == right->byte_order_func)) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } static void ByteJumpOverride(char *keyword, char *option, RuleOptOverrideFunc roo_func) { ByteJumpOverrideData *new = SnortAlloc(sizeof(ByteJumpOverrideData)); new->keyword = SnortStrdup(keyword); new->option = SnortStrdup(option); new->func = roo_func; new->next = byteJumpOverrideFuncs; byteJumpOverrideFuncs = new; } static void ByteJumpOverrideFuncsFree(void) { ByteJumpOverrideData *node = byteJumpOverrideFuncs; while (node != NULL) { ByteJumpOverrideData *tmp = node; node = node->next; if (tmp->keyword != NULL) free(tmp->keyword); if (tmp->option != NULL) free(tmp->option); free(tmp); } byteJumpOverrideFuncs = NULL; } /**************************************************************************** * * Function: SetupByteJump() * * Purpose: Load 'er up * * Arguments: None. * * Returns: void function * ****************************************************************************/ void SetupByteJump(void) { /* This list is only used during parsing */ if (byteJumpOverrideFuncs != NULL) ByteJumpOverrideFuncsFree(); /* map the keyword to an initialization/processing function */ RegisterRuleOption("byte_jump", ByteJumpInit, ByteJumpOverride, OPT_TYPE_DETECTION, NULL); AddFuncToCleanExitList(ByteJumpOverrideCleanup, NULL); AddFuncToRuleOptParseCleanupList(ByteJumpOverrideFuncsFree); #ifdef PERF_PROFILING RegisterPreprocessorProfile("byte_jump", &byteJumpPerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: ByteJump Setup\n");); } /**************************************************************************** * * Function: ByteJumpInit(char *, OptTreeNode *) * * Purpose: Generic rule configuration function. Handles parsing the rule * information and attaching the associated detection function to * the OTN. * * Arguments: data => rule arguments/data * otn => pointer to the current rule option list node * protocol => protocol the rule is on (we don't care in this case) * * Returns: void function * ****************************************************************************/ static void ByteJumpInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { ByteJumpData *idx; OptFpList *fpl; ByteJumpOverrideData *override; void *idx_dup; /* allocate the data structure and attach it to the rule's data struct list */ idx = (ByteJumpData *) calloc(sizeof(ByteJumpData), sizeof(char)); if(idx == NULL) { FatalError("%s(%d): Unable to allocate byte_jump data node\n", file_name, file_line); } /* this is where the keyword arguments are processed and placed into the rule option's data structure */ override = ByteJumpParse(data, idx, otn); if (override != NULL) { /* There is an override function */ free(idx); override->func(sc, override->keyword, override->option, data, otn, protocol); return; } fpl = AddOptFuncToList(ByteJump, otn); fpl->type = RULE_OPTION_TYPE_BYTE_JUMP; if (add_detection_option(sc, RULE_OPTION_TYPE_BYTE_JUMP, (void *)idx, &idx_dup) == DETECTION_OPTION_EQUAL) { #ifdef DEBUG_RULE_OPTION_TREE LogMessage("Duplicate ByteJump:\n%d %d %c %c %c %c %c %c %d %d 0x%x %d %c %c\n" "%d %d %c %c %c %c %c %c %d %d 0x%x %d %c %c\n\n", idx->bytes_to_grab, idx->offset, idx->relative_flag, idx->data_string_convert_flag, idx->from_beginning_flag, idx->from_end_flag, idx->align_flag, idx->endianess, idx->base, idx->multiplier, idx->bitmask_val, idx->post_offset, idx->offset_var, idx->postoffset_var, ((ByteJumpData *)idx_dup)->bytes_to_grab, ((ByteJumpData *)idx_dup)->offset, ((ByteJumpData *)idx_dup)->relative_flag, ((ByteJumpData *)idx_dup)->data_string_convert_flag, ((ByteJumpData *)idx_dup)->from_beginning_flag, ((ByteJumpData *)idx_dup)->from_end_flag, ((ByteJumpData *)idx_dup)->align_flag, ((ByteJumpData *)idx_dup)->endianess, ((ByteJumpData *)idx_dup)->base, ((ByteJumpData *)idx_dup)->multiplier, ((ByteJumpData *)idx_dup)->bitmask_val, ((ByteJumpData *)idx_dup)->post_offset; ((ByteJumpData *)idx_dup)->offset_var; ((ByteJumpData *)idx_dup)->postoffset_var); #endif free(idx); idx = idx_dup; } /* attach it to the context node so that we can call each instance * individually */ fpl->context = (void *) idx; if (idx->relative_flag == 1) fpl->isRelative = 1; } /**************************************************************************** * * Function: ByteJumpParse(char *, ByteJumpData *, OptTreeNode *) * * Purpose: This is the function that is used to process the option keyword's * arguments and attach them to the rule's data structures. * * Arguments: data => argument data * idx => pointer to the processed argument storage * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ static ByteJumpOverrideData * ByteJumpParse(char *data, ByteJumpData *idx, OptTreeNode *otn) { char **toks; char *endp; int num_toks; char *cptr; int i =0; RuleOptByteOrderFunc tmp_byte_order_func = NULL; toks = mSplit(data, ",", 14, &num_toks, 0); if(num_toks < 2) ParseError("Bad arguments to byte_jump: %s\n", data); /* set how many bytes to process from the packet */ idx->bytes_to_grab = strtoul(toks[0], &endp, 10); if(endp==toks[0]) { ParseError("Unable to parse as byte value %s\n",toks[0]); } if(*endp != '\0') { ParseError("byte_jump option has bad input: %s.", toks[0]); } if(idx->bytes_to_grab > PARSELEN ) { ParseError("byte_jump can't process more than " "%d bytes!\n",PARSELEN); } /* set offset */ if (isdigit(toks[1][0]) || toks[1][0] == '-') { idx->offset = strtol(toks[1], &endp, 10); idx->offset_var = -1; if(endp==toks[1]) { ParseError("Unable to parse as offset %s\n",toks[1]); } if(*endp != '\0') { ParseError("byte_jump option has bad offset: %s.", toks[1]); } } else { if ( bytemath_variable_name && (strcmp(bytemath_variable_name,toks[1]) == 0) ) { idx->offset_var= BYTE_MATH_VAR_INDEX; // 2 } else { idx->offset_var = GetVarByName(toks[1]); if ( idx->offset_var == BYTE_EXTRACT_NO_VAR) ParseError(BYTE_JUMP_INVALID_ERR_FMT, "byte_jump : offset", toks[1]); } } idx->postoffset_var = -1; i = 2; /* is it a relative offset? */ if(num_toks > 2) { while(i < num_toks) { cptr = toks[i]; while(isspace((int)*cptr)) {cptr++;} if(!strcasecmp(cptr, "relative")) { /* the offset is relative to the last pattern match */ idx->relative_flag = 1; } else if(!strcasecmp(cptr, "from_beginning")) { idx->from_beginning_flag = 1; } else if(!strcasecmp(cptr, "from_end")) { idx->from_end_flag = 1; } else if(!strcasecmp(cptr, "string")) { /* the data will be represented as a string that needs * to be converted to an int, binary is assumed otherwise */ idx->data_string_convert_flag = 1; } else if(!strcasecmp(cptr, "little")) { idx->endianess = LITTLE; } else if(!strcasecmp(cptr, "big")) { /* this is the default */ idx->endianess = BIG; } else if(!strcasecmp(cptr, "hex")) { idx->base = 16; } else if(!strcasecmp(cptr, "dec")) { idx->base = 10; } else if(!strcasecmp(cptr, "oct")) { idx->base = 8; } else if(!strcasecmp(cptr, "align")) { idx->align_flag = 1; } else if(!strncasecmp(cptr, "multiplier ", 11)) { /* Format of this option is multiplier xx. * xx is a positive base 10 number. */ char *mval = &cptr[11]; long factor = 0; int multiplier_len = strlen(cptr); if (multiplier_len > 11) { factor = strtol(mval, &endp, 10); } if ((factor <= 0) || (endp != cptr + multiplier_len)) { ParseError("invalid length multiplier \"%s\"\n",cptr); } idx->multiplier = factor; } else if(!strncasecmp(cptr, "post_offset ", 12)) { /* Format of this option is post_offset xx. * xx is a positive or negative base 10 integer. */ if (!idx->post_offset) { char *mval = &cptr[12]; int32_t factor = 0; int postoffset_len = strlen(cptr); while(isspace((int)*mval)) {mval++;} if (postoffset_len > 12 && (isdigit(*mval) || *mval == '-' )) { factor = strtol(mval, &endp, 10); idx->postoffset_var=-1; if (endp != cptr + postoffset_len) { ParseError("invalid post_offset \"%s\"\n",cptr); } idx->post_offset = factor; } else { if ( bytemath_variable_name && (strcmp(bytemath_variable_name,mval) == 0) ) { idx->postoffset_var= BYTE_MATH_VAR_INDEX; } else { idx->postoffset_var = GetVarByName(mval); if ( idx->postoffset_var == BYTE_EXTRACT_NO_VAR) ParseError(BYTE_JUMP_INVALID_ERR_FMT, "byte_jump : post_offset", mval); } } } else { ParseError("byte_jump option post_offset is already configured in rule once\n"); } } else if ((tmp_byte_order_func = GetByteOrderFunc(cptr)) != NULL) { idx->byte_order_func = tmp_byte_order_func; } else if(strncasecmp(cptr,"bitmask ",8) == 0) { RuleOptionBitmaskParse(&(idx->bitmask_val) , cptr, idx->bytes_to_grab,"BYTE_JUMP"); } else { ByteJumpOverrideData *override = byteJumpOverrideFuncs; while (override != NULL) { if (strcasecmp(cptr, override->option) == 0) { mSplitFree(&toks, num_toks); return override; } override = override->next; } ParseError("unknown modifier \"%s\"\n",cptr); } i++; } } if (idx->bytes_to_grab > MAX_BYTES_TO_GRAB && !idx->data_string_convert_flag) { ParseError("byte_jump rule option cannot extract more than %d bytes without valid string prefix.", MAX_BYTES_TO_GRAB); } /* idx->base is only set if the parameter is specified */ if(!idx->data_string_convert_flag && idx->base) { ParseError("hex, dec and oct modifiers must be used in conjunction \n" " with the 'string' modifier\n"); } if (idx->from_beginning_flag && idx->from_end_flag) { ParseError("from_beginning and from_end options together in a rule is invalid config!\n"); } if (idx->offset < MIN_BYTE_EXTRACT_OFFSET || idx->offset > MAX_BYTE_EXTRACT_OFFSET) { ParseError("byte_jump rule option has invalid offset. " "Valid offsets are between %d and %d.", MIN_BYTE_EXTRACT_OFFSET, MAX_BYTE_EXTRACT_OFFSET); } mSplitFree(&toks, num_toks); return NULL; } /**************************************************************************** * * Function: ByteJump(char *, OptTreeNode *, OptFpList *) * * Purpose: Use this function to perform the particular detection routine * that this rule keyword is supposed to encompass. * * Arguments: p => pointer to the decoded packet * otn => pointer to the current rule's OTN * fp_list => pointer to the function pointer list * * Returns: If the detection test fails, this function *must* return a zero! * On success, it calls the next function in the detection list * ****************************************************************************/ int ByteJump(void *option_data, Packet *p) { ByteJumpData *bjd = (ByteJumpData *)option_data; int rval = DETECTION_OPTION_NO_MATCH; uint32_t value = 0; uint32_t jump_value = 0; uint32_t payload_bytes_grabbed = 0; uint32_t extract_offset,extract_postoffset; int32_t offset, tmp = 0; int dsize; const uint8_t *base_ptr, *end_ptr, *start_ptr; uint8_t rst_doe_flags = 1; int search_start = 0; PROFILE_VARS; PREPROC_PROFILE_START(byteJumpPerfStats); if (Is_DetectFlag(FLAG_ALT_DETECT)) { dsize = DetectBuffer.len; start_ptr = DetectBuffer.data; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Using Alternative Detect buffer!\n");); } else if(Is_DetectFlag(FLAG_ALT_DECODE)) { dsize = DecodeBuffer.len; start_ptr = DecodeBuffer.data; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Using Alternative Decode buffer!\n");); } else { start_ptr = p->data; if(IsLimitedDetect(p)) dsize = p->alt_dsize; else dsize = p->dsize; } /* save off whatever our ending pointer is */ end_ptr = start_ptr + dsize; base_ptr = start_ptr; DEBUG_WRAP( DebugMessage(DEBUG_PATTERN_MATCH,"[*] byte jump firing...\n"); DebugMessage(DEBUG_PATTERN_MATCH,"payload starts at %p\n", start_ptr); DebugMessage(DEBUG_PATTERN_MATCH,"payload ends at %p\n", end_ptr); DebugMessage(DEBUG_PATTERN_MATCH,"doe_ptr %p\n", doe_ptr); ); /* END DEBUG_WRAP */ /* Get values from byte_extract variables, if present. */ if (bjd->offset_var >= 0 ) { if(bjd->offset_var == BYTE_MATH_VAR_INDEX ) { bjd->offset = (int32_t) bytemath_variable; } if ( bjd->offset_var < NUM_BYTE_EXTRACT_VARS) { GetByteExtractValue(&extract_offset, bjd->offset_var); bjd->offset = (int32_t) extract_offset; } } if(bjd->relative_flag && doe_ptr) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Checking relative offset!\n");); /* @todo: possibly degrade to use the other buffer, seems non-intuitive * Because doe_ptr can be "end" in the last match, * use end + 1 for upper bound * Bound checked also after offset is applied * (see byte_extract() and string_extract()) */ if(!inBounds(start_ptr, end_ptr + 1, doe_ptr)) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "[*] byte jump bounds check failed..\n");); PREPROC_PROFILE_END(byteJumpPerfStats); return rval; } search_start = (doe_ptr - start_ptr) + bjd->offset; base_ptr = doe_ptr; rst_doe_flags = 0; } else { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "checking absolute offset %d\n", bjd->offset);); search_start = bjd->offset; base_ptr = start_ptr; } if (search_start < 0) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "[*] byte jump bounds check failed..\n");); PREPROC_PROFILE_END(byteJumpPerfStats); return rval; } base_ptr = base_ptr + bjd->offset; /* Use byte_order_func to determine endianess, if present */ if (bjd->byte_order_func) { offset = (int32_t) (base_ptr - p->data); bjd->endianess = bjd->byte_order_func(p, offset); if (bjd->endianess == -1) { PREPROC_PROFILE_END(byteJumpPerfStats); return DETECTION_OPTION_NO_MATCH; } } /* Both of the extraction functions contain checks to insure the data * is always inbounds */ if(!bjd->data_string_convert_flag && bjd->bytes_to_grab) { if(byte_extract(bjd->endianess, bjd->bytes_to_grab, base_ptr, start_ptr, end_ptr, &value)) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Byte Extraction Failed\n");); PREPROC_PROFILE_END(byteJumpPerfStats); return rval; } payload_bytes_grabbed = bjd->bytes_to_grab; } else if (bjd->data_string_convert_flag) { payload_bytes_grabbed = tmp = string_extract(bjd->bytes_to_grab, bjd->base, base_ptr, start_ptr, end_ptr, &value); if (tmp < 0 && bjd->bytes_to_grab) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Byte Extraction Failed\n");); PREPROC_PROFILE_END(byteJumpPerfStats); return rval; } } DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "grabbed %d of %d bytes, value = %08X\n", payload_bytes_grabbed, bjd->bytes_to_grab, value);); if(bjd->bitmask_val != 0 ) { int num_tailing_zeros_bitmask = getNumberTailingZerosInBitmask(bjd->bitmask_val); value = value & bjd->bitmask_val ; if (value && num_tailing_zeros_bitmask ) { value = value >> num_tailing_zeros_bitmask; } } DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,"post_bitmask operation the extracted value : 0x%08X(%u)\n", value,value);); /* Adjust the jump_value (# bytes to jump forward) with the multiplier. */ if (bjd->multiplier) jump_value = value * bjd->multiplier; else jump_value = value; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "grabbed %d of %d bytes, after multiplier value = %08X\n", payload_bytes_grabbed, bjd->bytes_to_grab, jump_value);); /* if we need to align on 32-bit boundries, round up to the next * 32-bit value */ if(bjd->align_flag) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "offset currently at %d\n", jump_value);); if ((jump_value % 4) != 0) { jump_value += (4 - (jump_value % 4)); } DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "offset aligned to %d\n", jump_value);); } DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Grabbed %d bytes at offset %d, value = 0x%08X\n", payload_bytes_grabbed, bjd->offset, jump_value);); if(bjd->from_beginning_flag) { /* Reset base_ptr if from_beginning */ DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "jumping from beginning 0x%08X(%u) bytes\n", jump_value,jump_value);); base_ptr = start_ptr; /* from base, push doe_ptr ahead "value" number of bytes */ SetDoePtr((base_ptr + jump_value), DOE_BUF_STD); } else if(bjd->from_end_flag) { /* Reset base_ptr if from_end */ DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "jumping from end 0x%08X(%u) bytes\n", jump_value,jump_value);); base_ptr = end_ptr; /* from base, push doe_ptr ahead "value" number of bytes */ SetDoePtr((base_ptr + jump_value), DOE_BUF_STD); } else { UpdateDoePtr((base_ptr + payload_bytes_grabbed + jump_value), rst_doe_flags); } DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,"updated doe_ptr %p\n", doe_ptr);); /* Get values from byte_extract/math variables, if present. */ if (bjd->postoffset_var >=0) { if(bjd->postoffset_var == BYTE_MATH_VAR_INDEX) { bjd->post_offset = (int32_t) bytemath_variable; } if (bjd->postoffset_var < NUM_BYTE_EXTRACT_VARS) { GetByteExtractValue(&extract_postoffset, bjd->postoffset_var); bjd->post_offset = (int32_t) extract_postoffset; } } /* now adjust using post_offset -- before bounds checking */ doe_ptr += bjd->post_offset; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,"after applying post_offset to doe_ptr %p\n", doe_ptr);); if(!inBounds(start_ptr, end_ptr+1, doe_ptr)) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "doe_ptr is not in bounds %p\n", doe_ptr);); PREPROC_PROFILE_END(byteJumpPerfStats); return rval; } else { rval = DETECTION_OPTION_MATCH; } PREPROC_PROFILE_END(byteJumpPerfStats); return rval; } static void ByteJumpOverrideCleanup(int signal, void *data) { if (byteJumpOverrideFuncs != NULL) ByteJumpOverrideFuncsFree(); } snort-2.9.15.1/src/detection-plugins/sp_byte_jump.h0000644000175200017520000000346013571422607017150 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifndef __SP_BYTE_JUMP_H__ #define __SP_BYTE_JUMP_H__ #include "decode.h" #include "plugbase.h" #define BYTE_JUMP_INVALID_ERR_FMT "Rule option %s uses an undefined byte_extract/byte_math variable name (%s)." typedef struct _ByteJumpData { uint32_t bytes_to_grab; /* number of bytes to compare */ int32_t offset; uint8_t relative_flag; uint8_t data_string_convert_flag; uint8_t from_beginning_flag; uint8_t align_flag; int8_t endianess; uint32_t base; uint32_t multiplier; int32_t post_offset; int8_t offset_var; RuleOptByteOrderFunc byte_order_func; uint8_t from_end_flag; int8_t postoffset_var; uint32_t bitmask_val; } ByteJumpData; void SetupByteJump(void); uint32_t ByteJumpHash(void *d); int ByteJumpCompare(void *l, void *r); int ByteJump(void *, Packet *); #endif /* __SP_BYTE_JUMP_H__ */ snort-2.9.15.1/src/detection-plugins/sp_byte_extract.c0000644000175200017520000005665713571422607017662 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2010-2013 Sourcefire, Inc. ** Author: Ryan Jordan ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* sp_byte_extract * * Description goes here. Snort rule interface for byte_extract functionality. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sf_types.h" #include "snort.h" #include "parser.h" #include "plugbase.h" #include "preprocids.h" #include "detection_options.h" #include "detection_util.h" #include "sfhashfcn.h" #include "profiler.h" #include "byte_extract.h" #include "sp_byte_extract.h" #include "sp_byte_math.h" #ifdef PERF_PROFILING PreprocStats byteExtractPerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif extern int file_line; extern char *file_name; uint32_t Byte_Extract_Offset_Var; /* Storage for extracted variables */ static uint32_t extracted_values[NUM_BYTE_EXTRACT_VARS]; static char *variable_names[NUM_BYTE_EXTRACT_VARS]; /* Prototypes */ static void ByteExtractInit(struct _SnortConfig *, char *, OptTreeNode *, int); static void ByteExtractCleanup(int, void *); /* Setup function */ void SetupByteExtract(void) { RegisterRuleOption("byte_extract", ByteExtractInit, NULL, OPT_TYPE_DETECTION, NULL); AddFuncToCleanExitList(ByteExtractCleanup, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("byte_extract", &byteExtractPerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif } /* Clean up some strings left over from parsing */ static void ByteExtractCleanup(int signal, void *data) { int i; for (i = 0; i < NUM_BYTE_EXTRACT_VARS; i++) { free(variable_names[i]); variable_names[i] = NULL; } } #ifdef DEBUG_MSGS /* Print a byte_extract option to console. For debugging purposes. */ void PrintByteExtract(ByteExtractData *data) { if (data == NULL) return; DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "bytes_to_grab = %d, offset = %d, relative = %d, convert = %d, " "align = %d, endianess = %d, base = %d, " "multiplier = %d, var_num = %d, name = %s, bitmask_val = 0x%x\n", data->bytes_to_grab, data->offset, data->relative_flag, data->data_string_convert_flag, data->align, data->endianess, data->base, data->multiplier, data->var_number, data->name, data->bitmask_val);); } #endif /* Hash functions. Make sure to update these when the data struct changes! */ uint32_t ByteExtractHash(void *d) { uint32_t a,b,c; ByteExtractData *data = (ByteExtractData *)d; a = data->bytes_to_grab; b = data->offset; c = data->base; mix(a,b,c); a += (data->relative_flag << 24 | data->data_string_convert_flag << 16 | data->align << 8 | data->endianess); b += data->multiplier; c += data->bitmask_val; mix(a,b,c); a += RULE_OPTION_TYPE_BYTE_EXTRACT; b += data->var_number; mix(a,b,c); #if (defined(__ia64) || defined(__amd64) || defined(_LP64)) { /* Cleanup warning because of cast from 64bit ptr to 32bit int * warning on 64bit OSs */ uint64_t ptr; /* Addresses are 64bits */ ptr = (uint64_t) data->byte_order_func; a += (ptr >> 32); b += (ptr & 0xFFFFFFFF); } #else a += (uint32_t)data->byte_order_func; #endif final(a,b,c); return c; } int ByteExtractCompare(void *l, void *r) { ByteExtractData *left = (ByteExtractData *) l; ByteExtractData *right = (ByteExtractData *) r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if ((left->bytes_to_grab == right->bytes_to_grab) && (left->offset == right->offset) && (left->relative_flag == right->relative_flag) && (left->data_string_convert_flag == right->data_string_convert_flag) && (left->align == right->align) && (left->endianess == right->endianess) && (left->base == right->base) && (left->multiplier == right->multiplier) && (left->var_number == right->var_number) && (left->byte_order_func == right->byte_order_func) && (left->bitmask_val == right->bitmask_val)) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } void ByteExtractFree(void *d) { ByteExtractData *data = (ByteExtractData *)d; free(data->name); free(data); } /* Checks a ByteExtractData instance for errors. */ static int ByteExtractVerify(ByteExtractData *data) { if (data->bytes_to_grab > MAX_BYTES_TO_GRAB && data->data_string_convert_flag == 0) { ParseError("byte_extract rule option cannot extract more than %d bytes.", MAX_BYTES_TO_GRAB); } if (data->bytes_to_grab > PARSELEN && data->data_string_convert_flag == 1) { ParseError("byte_extract rule cannot process more than %d bytes for " "string extraction.", PARSELEN); } if (Byte_Extract_Offset_Var != BYTE_MATH_VAR_INDEX ) { if (data->offset < MIN_BYTE_EXTRACT_OFFSET || data->offset > MAX_BYTE_EXTRACT_OFFSET) { ParseError("byte_extract rule option has invalid offset. " "Valid offsets are between %d and %d.", MIN_BYTE_EXTRACT_OFFSET, MAX_BYTE_EXTRACT_OFFSET); } } if (data->multiplier < MIN_BYTE_EXTRACT_MULTIPLIER || data->multiplier > MAX_BYTE_EXTRACT_MULTIPLIER) { ParseError("byte_extract rule option has invalid multiplier. " "Valid multipliers are between %d and %d.", MIN_BYTE_EXTRACT_MULTIPLIER, MAX_BYTE_EXTRACT_MULTIPLIER); } if (data->bytes_to_grab == 0) ParseError("byte_extract rule option extracts zero bytes. " "\"bytes_to_extract\" must be 1 or greater."); if (data->align != 0 && data->align != 2 && data->align != 4) ParseError("byte_extract rule option has an invalid argument " "to \"align\". Valid arguments are \'2\' and \'4\'."); if (data->offset < 0 && data->relative_flag == 0) ParseError("byte_extract rule option has a negative offset, but does " "not use the \"relative\" option."); if (data->name && isdigit(data->name[0])) { ParseError("byte_extract rule option has a name which starts with a digit. " "Variable names must start with a letter."); } if (data->base && !data->data_string_convert_flag) { ParseError("byte_extract rule option has a string converstion type " "(\"dec\", \"hex\", or \"oct\") without the \"string\" " "argument."); } return BYTE_EXTRACT_SUCCESS; } int numBytesInBitmask(uint32_t bitmask_value) { int num_bytes; if( bitmask_value <= 0xFF ) num_bytes = 1; else if ( bitmask_value <= 0xFFFF ) num_bytes = 2; else if ( bitmask_value <= 0xFFFFFF ) num_bytes = 3; else num_bytes = 4; return num_bytes; } void RuleOptionBitmaskParse(uint32_t* bitmask_val, char *cptr, uint32_t bytes_to_extract,char* ruleOptionName) { char* endp = NULL; char* startp = (cptr + 8); uint32_t bitmask_value; uint32_t num_bytes=0; if(*bitmask_val == 0 ) { if(SnortStrToU32(startp,&endp,&bitmask_value,16) == -1 ) ParseError("%s :: Invalid input value for \"bitmask\" rule option.\n", ruleOptionName); else if( errno == ERANGE ) ParseError("%s :: \"bitmask\" value is OUT OF RANGE.\n", ruleOptionName); else if (bitmask_value == 0 ) ParseError("%s :: \"bitmask\" value is ZERO.\n", ruleOptionName); else if (*endp != '\0') ParseError("%s :: Rule option has invalid argument to \"bitmask\".\n", ruleOptionName); else { num_bytes = numBytesInBitmask(bitmask_value); if (bytes_to_extract <= MAX_BYTES_TO_EXTRACT) { if(bytes_to_extract >= num_bytes ) { *bitmask_val = bitmask_value; } else ParseError("%s :: Number of bytes in \"bitmask\" value is greater than bytes_to_grab.\n", ruleOptionName); } else ParseError("%s :: Number of extracted bytes from packet are more than MAX_BYTES_TO_GRAB.\n", ruleOptionName); } } else ParseError("%s :: Rule option includes the \"bitmask\" argument twice.\n",ruleOptionName); } /* String Validation for all special characters in the varaibale name */ void isvalidstr(char *str,char *feature) { int cnt=0,pos=0; for (;str[pos]!='\0';pos++) { if (!((str[pos] >= 'a' && str[pos] <= 'z') || (str[pos] >= 'A' && str[pos] <= 'Z') || (str[pos] >= '0' && str[pos] <='9'))) cnt++; } if (pos == cnt) ParseError("%s input %s.Complete string with special characters are not allowed in variable name field",feature,str); } /* Parsing function. */ static int ByteExtractParse(ByteExtractData *data, char *args) { char *args_copy = SnortStrdup(args); char *endptr, *saveptr = args_copy; char *token = strtok_r(args_copy, ",", &saveptr); RuleOptByteOrderFunc tmp_byte_order_func = NULL; /* set defaults / sentinels */ data->multiplier = 1; data->endianess = ENDIAN_NONE; /* first: bytes_to_extract */ if (token) { data->bytes_to_grab = SnortStrtoul(token, &endptr, 10); if (*endptr != '\0') ParseError("byte_extract rule option has non-digits in the " "\"bytes_to_extract\" field."); token = strtok_r(NULL, ",", &saveptr); } /* second: offset */ if (token) { if (isdigit(token[0]) || token[0] == '-') { data->offset = SnortStrtoul(token, &endptr, 10); if (*endptr != '\0') ParseError("byte_extract rule option has non-digits in the " "\"offset\" field."); } else { if ( bytemath_variable_name && (!strcmp(bytemath_variable_name,token))) { data->offset = (int32_t) bytemath_variable; Byte_Extract_Offset_Var = BYTE_MATH_VAR_INDEX; } else { ParseError("byte_extract rule option has invalid Variable name in the " "\"offset\" field."); } } token = strtok_r(NULL, ",", &saveptr); } /* third: variable name */ if (token) { if( bytemath_variable_name && (strcmp(bytemath_variable_name, token) == 0) ) { ParseError("byte_extract : variable name is already used in byte_math rule \n"); } else data->name = SnortStrdup(token); isvalidstr(token,"byte_extract"); token = strtok_r(NULL, ",", &saveptr); } /* optional arguments */ while (token) { while(isspace((int)*token)) {token++;} if (strcmp(token, "relative") == 0) { data->relative_flag = 1; } else if (strncmp(token, "align ", 6) == 0) { char *value = (token+6); if (data->align == 0) data->align = (uint8_t)SnortStrtoul(value, &endptr, 10); else ParseError("byte_extract rule option includes the " "\"align\" argument twice."); if (*endptr != '\0') ParseError("byte_extract rule option has non-digits in the " "argument to \"align\". "); } else if (strcmp(token, "little") == 0) { if (data->endianess == ENDIAN_NONE) data->endianess = LITTLE; else ParseError("byte_extract rule option specifies the " "byte order twice. Use only one of \"big\", \"little\", " "or \"dce\"."); } else if (strcmp(token, "big") == 0) { if (data->endianess == ENDIAN_NONE) data->endianess = BIG; else ParseError("byte_extract rule option specifies the " "byte order twice. Use only one of \"big\", \"little\", " "or \"dce\"."); } else if (strncmp(token, "multiplier ", 11) == 0) { char *value = (token+11); if (value[0] == '\0') ParseError("byte_extract rule option has a \"multiplier\" " "argument with no value specified."); if (data->multiplier == 1) { data->multiplier = SnortStrtoul(value, &endptr, 10); if (*endptr != '\0') ParseError("byte_extract rule option has non-digits in the " "argument to \"multiplier\". "); } else ParseError("byte_extract rule option has multiple " "\"multiplier\" arguments. Use only one."); } else if (strcmp(token, "string") == 0) { if (data->data_string_convert_flag == 0) data->data_string_convert_flag = 1; else ParseError("byte_extract rule option has multiple " "\"string\" arguments. Use only one."); } else if (strcmp(token, "dec") == 0) { if (data->base == 0) data->base = 10; else ParseError("byte_extract rule option has multiple arguments " "specifying the type of string conversion. Use only " "one of \"dec\", \"hex\", or \"oct\"."); } else if (strcmp(token, "hex") == 0) { if (data->base == 0) data->base = 16; else ParseError("byte_extract rule option has multiple arguments " "specifying the type of string conversion. Use only " "one of \"dec\", \"hex\", or \"oct\"."); } else if (strcmp(token, "oct") == 0) { if (data->base == 0) data->base = 8; else ParseError("byte_extract rule option has multiple arguments " "specifying the type of string conversion. Use only " "one of \"dec\", \"hex\", or \"oct\"."); } else if ((tmp_byte_order_func = GetByteOrderFunc(token)) != NULL) { if (data->endianess == ENDIAN_NONE) { data->endianess = ENDIAN_FUNC; data->byte_order_func = tmp_byte_order_func; } else { ParseError("byte_extract rule option specifies the " "byte order twice. Use only one of \"big\", \"little\", " "or \"dce\"."); } } else if(strncasecmp(token,"bitmask ",8) == 0) { RuleOptionBitmaskParse(&(data->bitmask_val) , token, data->bytes_to_grab, "BYTE_EXTRACT" ); } else { ParseError("byte_extract rule option has invalid argument \"%s\".", token); } token = strtok_r(NULL, ",", &saveptr); } free(args_copy); /* Need to check this error before the sentinel gets replaced */ if (data->endianess != ENDIAN_NONE && data->data_string_convert_flag == 1) { ParseError("byte_extract rule option can't have \"string\" specified " "at the same time as a byte order (\"big\" or \"little\")."); } /* Replace sentinels with defaults */ if (data->endianess == ENDIAN_NONE) data->endianess = BIG; if (data->data_string_convert_flag && (data->base == 0)) data->base = 10; /* At this point you could verify the data and return something. */ return ByteExtractVerify(data); } /* Given a variable name, retrieve its index. For use by other options. */ int8_t GetVarByName(char *name) { int i; if (name == NULL) return BYTE_EXTRACT_NO_VAR; for (i = 0; i < NUM_BYTE_EXTRACT_VARS; i++) { if (variable_names[i] != NULL && strcmp(variable_names[i], name) == 0) return i; } return BYTE_EXTRACT_NO_VAR; } /* If given an OptFpList with no byte_extracts, clear the variable_names array */ void ClearVarNames(OptFpList *fpl) { int i; while (fpl != NULL) { if (fpl->type == RULE_OPTION_TYPE_BYTE_EXTRACT) return; fpl = fpl->next; } for (i = 0; i < NUM_BYTE_EXTRACT_VARS; i++) { free(variable_names[i]); variable_names[i] = NULL; } } /* Add a variable's name to the variable_names array Returns: variable index */ int8_t AddVarNameToList(ByteExtractData *data) { int i; for (i = 0; i < NUM_BYTE_EXTRACT_VARS; i++) { if (variable_names[i] == NULL) { variable_names[i] = SnortStrdup(data->name); break; } else if ( strcmp(variable_names[i], data->name) == 0 ) { break; } } return i; } /* Inititialization function. Handles rule parsing. */ static void ByteExtractInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { ByteExtractData *idx; OptFpList *fpl; void *idx_dup; idx = (ByteExtractData *) SnortAlloc(sizeof(ByteExtractData)); /* Clear out the variable_names array if this is the first byte_extract in a rule. */ ClearVarNames(otn->opt_func); /* Parse the options */ ByteExtractParse(idx, data); /* There can only be two unique variables names in a rule. */ idx->var_number = AddVarNameToList(idx); if (idx->var_number >= NUM_BYTE_EXTRACT_VARS) { ParseError("Rule has more than %d byte_extract variables.", NUM_BYTE_EXTRACT_VARS); } #ifdef DEBUG_MSGS PrintByteExtract(idx); #endif fpl = AddOptFuncToList(DetectByteExtract, otn); fpl->type = RULE_OPTION_TYPE_BYTE_EXTRACT; if (add_detection_option(sc, RULE_OPTION_TYPE_BYTE_EXTRACT, (void *)idx, &idx_dup) == DETECTION_OPTION_EQUAL) { /* duplicate exists. */ free(idx->name); free(idx); idx = idx_dup; } fpl->context = (void *) idx; if (idx->relative_flag == 1) fpl->isRelative = 1; } uint32_t getNumberTailingZerosInBitmask(uint32_t bitmask) { unsigned int num_tailing_zeros; if (bitmask & 0x1) { num_tailing_zeros = 0; } else { num_tailing_zeros = 1; if ((bitmask & 0xffff) == 0) { bitmask >>= 16; num_tailing_zeros += 16; } if ((bitmask & 0xff) == 0) { bitmask >>= 8; num_tailing_zeros += 8; } if ((bitmask & 0xf) == 0) { bitmask >>= 4; num_tailing_zeros += 4; } if ((bitmask & 0x3) == 0) { bitmask >>= 2; num_tailing_zeros += 2; } num_tailing_zeros -= bitmask & 0x1; } return num_tailing_zeros; } /* Main detection callback */ int DetectByteExtract(void *option_data, Packet *p) { ByteExtractData *data = (ByteExtractData *) option_data; int ret, bytes_read, dsize; const uint8_t *ptr, *start, *end; uint32_t *value; int32_t offset; uint8_t rst_doe_flags = 1; PROFILE_VARS; PREPROC_PROFILE_START(byteExtractPerfStats); if (data == NULL || p == NULL) { PREPROC_PROFILE_END(byteExtractPerfStats); return DETECTION_OPTION_NO_MATCH; } /* setup our fun pointers */ if (Is_DetectFlag(FLAG_ALT_DETECT)) { dsize = DetectBuffer.len; start = DetectBuffer.data; } else if (Is_DetectFlag(FLAG_ALT_DECODE)) { dsize = DecodeBuffer.len; start = DecodeBuffer.data; } else { if(IsLimitedDetect(p)) dsize = p->alt_dsize; else dsize = p->dsize; start = p->data; } if (data->relative_flag) { ptr = doe_ptr; rst_doe_flags = 0; } else ptr = start; ptr += data->offset; end = start + dsize; value = &(extracted_values[data->var_number]); /* check bounds */ if (ptr < start || ptr >= end) { PREPROC_PROFILE_END(byteExtractPerfStats); return DETECTION_OPTION_NO_MATCH; } /* get the endianess at run-time if we have a byte_order_func */ if (data->byte_order_func) { offset = (int32_t) (ptr - start); data->endianess = data->byte_order_func((void *)p, offset); } if (data->endianess == -1) { /* Sometimes the byte_order_func deems that the packet should be skipped */ PREPROC_PROFILE_END(byteExtractPerfStats); return DETECTION_OPTION_NO_MATCH; } if (data->data_string_convert_flag == 0) { ret = byte_extract(data->endianess, data->bytes_to_grab, ptr, start, end, value); if (ret < 0) { PREPROC_PROFILE_END(byteExtractPerfStats); return DETECTION_OPTION_NO_MATCH; } bytes_read = data->bytes_to_grab; } else { ret = string_extract(data->bytes_to_grab, data->base, ptr, start, end, value); if (ret < 0) { PREPROC_PROFILE_END(byteExtractPerfStats); return DETECTION_OPTION_NO_MATCH; } bytes_read = ret; } if(data->bitmask_val != 0 ) { int num_tailing_zeros_bitmask = getNumberTailingZerosInBitmask(data->bitmask_val); *value = (*value) & data->bitmask_val ; if ( (*value) && num_tailing_zeros_bitmask ) { *value = (*value) >> num_tailing_zeros_bitmask; } } /* mulitply */ *value *= data->multiplier; /* align to next 32-bit or 16-bit boundary */ if ((data->align == 4) && (*value % 4)) { *value = *value + 4 - (*value % 4); } else if ((data->align == 2) && (*value % 2)) { *value = *value + 2 - (*value % 2); } /* push doe_ptr */ UpdateDoePtr((ptr + bytes_read), rst_doe_flags); /* this rule option always "matches" if the read is performed correctly */ PREPROC_PROFILE_END(byteExtractPerfStats); return DETECTION_OPTION_MATCH; } /* Setters & Getters for extracted values */ int GetByteExtractValue(uint32_t *dst, int8_t var_number) { if (dst == NULL || var_number >= NUM_BYTE_EXTRACT_VARS) return BYTE_EXTRACT_NO_VAR; *dst = extracted_values[var_number]; return 0; } int SetByteExtractValue(uint32_t value, int8_t var_number) { if (var_number >= NUM_BYTE_EXTRACT_VARS) return BYTE_EXTRACT_NO_VAR; extracted_values[var_number] = value; return 0; } snort-2.9.15.1/src/detection-plugins/sp_byte_extract.h0000644000175200017520000000476613571422607017661 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2010-2013 Sourcefire, Inc. ** Author: Ryan Jordan ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __SP_BYTE_EXTRACT_H__ #define __SP_BYTE_EXTRACT_H__ #include "decode.h" #include "plugbase.h" #define BYTE_EXTRACT_SUCCESS 1 #define BYTE_EXTRACT_FAILURE -1 #define NUM_BYTE_EXTRACT_VARS 2 #define BYTE_EXTRACT_NO_VAR -1 #define BYTE_EXTRACT_INVALID_ERR_FMT "Rule option %s uses an undefined byte_extract variable name (%s)." //format: rule name, variable name #define MAX_BYTES_TO_GRAB 4 #define MAX_BYTES_TO_EXTRACT 10 #define MIN_BYTE_EXTRACT_OFFSET -65535 #define MAX_BYTE_EXTRACT_OFFSET 65535 #define MIN_BYTE_EXTRACT_MULTIPLIER 1 #define MAX_BYTE_EXTRACT_MULTIPLIER 65535 typedef struct _ByteExtractData { uint32_t bytes_to_grab; int32_t offset; uint8_t relative_flag; uint8_t data_string_convert_flag; uint8_t align; int8_t endianess; uint32_t base; uint32_t multiplier; int8_t var_number; char *name; RuleOptByteOrderFunc byte_order_func; uint32_t bitmask_val; } ByteExtractData; void SetupByteExtract(void); uint32_t ByteExtractHash(void *d); int ByteExtractCompare(void *l, void *r); int DetectByteExtract(void *, Packet *); void ByteExtractFree(void *d); void isvalidstr(char *str,char *feature); int8_t GetVarByName(char *name); void ClearVarNames(OptFpList *fpl); int8_t AddVarNameToList(ByteExtractData *data); int GetByteExtractValue(uint32_t *dst, int8_t var_number); int SetByteExtractValue(uint32_t value, int8_t var_number); uint32_t getNumberTailingZerosInBitmask(uint32_t); int numBytesInBitmask(uint32_t ); void RuleOptionBitmaskParse(uint32_t* , char *, uint32_t ,char* ); #endif /* __SP_BYTE_EXTRACT_H__ */ snort-2.9.15.1/src/detection-plugins/sp_byte_math.c0000644000175200017520000007715613571422607017136 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2003-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* * Filename sp_byte_math.c * * Authors Krishnakanth * Seshaiah * * Description * byte math is tied to the other byte operations – byte_test,byte_extract,byte_jump. * allowed operations are +,-,*,/,<<,>> on the data that was extracted. * options order can be change as they are prefix with identifier. * Parser can identify the option with its prefix. * result varaible should mention in the rule along with bytes_to extract,value and offset. * result varaible stores the output of the byte_math opeation * Byte_math output can be given input to Byte_extarct offset, Byte_Jump offset and Byte_test offset and value options *Eg : byte_math: bytes 2, offset 0, oper *, rvalue 10, result area; byte_test:2,>,area,16; * At the zero offset of the paylod, extract 2 bytes and apply multiplication operation with value 10,store result in variable area. The area variable output is given as * input to byte_test value. * * Lets consider 2 bytes of extarcted data in byte_math is 5. * The rvalue is 10. after multiplication operator applied between rvalue and extracted data,it became 50. * result option variable area holds value 50. * the byte_test can use the area varaible as input to it in either offset/value options. * * Rule Examples : * alert tcp any any -> any any (sid :1;byte_math:bytes 4,oper +,rvalue 123, offset 12,result var; msg: "Byte_math_valid";content : "|74 63 6c 61|";) * * alert tcp any any -> any any (sid :1;byte_math:bytes 1,oper <<,rvalue 123, offset 12,result var; msg: "Byte_math_valid";content : "|74 63 6c 61|";) * * alert tcp any any -> any any (msg:"byte_math IT : byte_jump ####### CASE-5 # byte_math byte_extract and byte_jump with bitmask in each rule"; byte_math:oper /,rvalue 2, relative, result OFF1,offset 0, endian big,bytes 1,bitmask 0xA;byte_extract:1,1,OFF2,bitmask 0xA;byte_jump:1,OFF2,bitmask 0xA;byte_extract:1,3,VALUE,bitmask 0x5; byte_test:1,<,VALUE,OFF1,bitmask 0xCB;content:"SKIPME"; sid:2;) */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifdef HAVE_STRINGS_H #include #endif #include #include "limits.h" #include "sf_types.h" #include "snort_bounds.h" #include "byte_extract.h" #include "rules.h" #include "treenodes.h" #include "decode.h" #include "plugbase.h" #include "parser.h" #include "snort_debug.h" #include "util.h" #include "plugin_enum.h" #include "mstring.h" #include "sfhashfcn.h" #include "sp_byte_math.h" #include "sp_byte_extract.h" #define PARSELEN 10 #define TEXTLEN (PARSELEN + 2) #include "snort.h" #include "profiler.h" #include "sfhashfcn.h" #include "detection_options.h" #include "detection_util.h" #ifdef PERF_PROFILING PreprocStats byteMathPerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif typedef struct _ByteMathOverrideData { char *keyword; char *option; union { RuleOptOverrideFunc fptr; void *void_fptr; } fptr; struct _ByteMathOverrideData *next; } ByteMathOverrideData; ByteMathOverrideData *byteMathOverrideFuncs = NULL; static void ByteMathOverride(char *keyword, char *option, RuleOptOverrideFunc roo_func); static void ByteMathOverrideFuncsFree(void); static void ByteMathInit(struct _SnortConfig *, char *, OptTreeNode *, int); static ByteMathOverrideData * ByteMathParse(char *data, ByteMathData *idx, OptTreeNode *otn); static void ByteMathOverrideCleanup(int, void *); static char* ByteMath_tok_extract(char *,char *); void AddVarName_Bytemath(ByteMathData *); char *bytemath_variable_name = NULL; uint32_t bytemath_variable; uint32_t ByteMathHash(void *d) { uint32_t a,b,c; ByteMathData *data = (ByteMathData *)d; a = data->bytes_to_extract; b = data->rvalue; c = data->operator; mix(a,b,c); a += data->offset; b += (data->rvalue_var << 24 | data->relative_flag << 16 | data->data_string_convert_flag << 8 | data->endianess); c += data->base; mix(a,b,c); a += RULE_OPTION_TYPE_BYTE_MATH; b += data->bitmask_val; c += data->offset_var; mix(a,b,c); #if (defined(__ia64) || defined(__amd64) || defined(_LP64)) { /* Cleanup warning because of cast from 64bit ptr to 32bit int * warning on 64bit OSs */ uint64_t ptr; /* Addresses are 64bits */ ptr = (uint64_t) data->byte_order_func; a += (ptr >> 32); b += (ptr & 0xFFFFFFFF); } #else a += (uint32_t)data->byte_order_func; #endif final(a,b,c); return c; } int ByteMathCompare(void *l, void *r) { ByteMathData *left = (ByteMathData *)l; ByteMathData *right = (ByteMathData *)r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if (( left->bytes_to_extract == right->bytes_to_extract) && ( left->rvalue == right->rvalue) && ( left->operator == right->operator) && ( left->offset == right->offset) && ( left->relative_flag == right->relative_flag) && ( left->data_string_convert_flag == right->data_string_convert_flag) && ( left->endianess == right->endianess) && ( left->base == right->base) && ( left->bitmask_val == right->bitmask_val) && ( left->rvalue_var == right->rvalue_var) && ( left->offset_var == right->offset_var) && ( left->byte_order_func == right->byte_order_func)) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } static void ByteMathOverride(char *keyword, char *option, RuleOptOverrideFunc roo_func) { ByteMathOverrideData *new = SnortAlloc(sizeof(ByteMathOverrideData)); new->keyword = SnortStrdup(keyword); new->option = SnortStrdup(option); new->func = roo_func; new->next = byteMathOverrideFuncs; byteMathOverrideFuncs = new; } static void ByteMathOverrideFuncsFree(void) { ByteMathOverrideData *node = byteMathOverrideFuncs; while (node != NULL) { ByteMathOverrideData *tmp = node; node = node->next; if (tmp->keyword != NULL) free(tmp->keyword); if (tmp->option != NULL) free(tmp->option); free(tmp); } byteMathOverrideFuncs = NULL; } static void ByteMathOverrideCleanup(int signal, void *data) { if (byteMathOverrideFuncs != NULL) ByteMathOverrideFuncsFree(); } /**************************************************************************** * Function: SetupByteMath() * * Purpose: Register byte_math name and initialization function * * Arguments: None. * * Returns: void function * ****************************************************************************/ void SetupByteMath(void) { /* map the keyword to an initialization/processing function */ RegisterRuleOption("byte_math", ByteMathInit, ByteMathOverride, OPT_TYPE_DETECTION, NULL); AddFuncToCleanExitList(ByteMathOverrideCleanup, NULL); AddFuncToRuleOptParseCleanupList(ByteMathOverrideFuncsFree); #ifdef PERF_PROFILING RegisterPreprocessorProfile("byte_math", &byteMathPerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: ByteMath Setup\n");); } /**************************************************************************** * * Function: ByteMathInit(char *, OptTreeNode *) * * Purpose: Generic rule configuration function. Handles parsing the rule * information and attaching the associated detection function to * the OTN. * * Arguments: data => rule arguments/data * otn => pointer to the current rule option list node * protocol => protocol the rule is on (we don't care in this case) * * Returns: void function * ****************************************************************************/ static void ByteMathInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { ByteMathData *idx; OptFpList *fpl; ByteMathOverrideData *override; void *idx_dup; /* allocate the data structure and attach it to the rule's data struct list */ idx = (ByteMathData *) calloc(sizeof(ByteMathData), sizeof(char)); if(idx == NULL) { ParseError("Byte_Math Unable to allocate byte_Math data node\n"); } /* this is where the keyword arguments are processed and placed into the rule option's data structure */ override = ByteMathParse(data, idx, otn); if (override) { /* There is an override function */ free(idx->result_var); free(idx); override->func(sc, override->keyword, override->option, data, otn, protocol); return; } AddVarName_Bytemath(idx); fpl = AddOptFuncToList(ByteMath, otn); fpl->type = RULE_OPTION_TYPE_BYTE_MATH; if (add_detection_option(sc, RULE_OPTION_TYPE_BYTE_MATH, (void *)idx, &idx_dup) == DETECTION_OPTION_EQUAL) { #ifdef DEBUG_RULE_OPTION_TREE LogMessage("Byte_Math Duplicate ByteCheck:\n%d %d %c %d %d %c %c %c %c 0x%x %d\n" "%d %d %c %d %d %c %c %c %c 0x%x %d\n\n", idx->bytes_to_extract, idx->rvalue,idx->rvalue_var, idx->operator, idx->offset,idx->offset_var, idx->relative_flag, idx->data_string_convert_flag, idx->endianess, idx->base, idx->bitmask_val, ((ByteMathData *)idx_dup)->bytes_to_extract, ((ByteMathData *)idx_dup)->rvalue, ((ByteMathData *)idx_dup)->rvalue_var, ((ByteMathData *)idx_dup)->operator, ((ByteMathData *)idx_dup)->offset, ((ByteMathData *)idx_dup)->offset_var, ((ByteMathData *)idx_dup)->relative_flag, ((ByteMathData *)idx_dup)->data_string_convert_flag, ((ByteMathData *)idx_dup)->bitmask_val, ((ByteMathData *)idx_dup)->endianess, ((ByteMathData *)idx_dup)->base); #endif free(idx->result_var); free(idx); idx = idx_dup; } /* attach it to the context node so that we can call each instance * individually */ fpl->context = (void *) idx; if (idx->relative_flag == 1) fpl->isRelative = 1; } /**************************************************************************** * * Function: ByteMath_tok_extract(char *,char *) * * Purpose: This function does extracting token content in rule options * * Arguments: src => Input token from the rule * del => Option the token to be mapped * * Returns: On success returns the resultant string address else trigger fatal error * ****************************************************************************/ static char* ByteMath_tok_extract(char *src,char *del) { char *ret_tok=NULL; ret_tok = strtok(src," "); if (ret_tok && !strcmp(ret_tok,del)) { ret_tok = strtok(NULL, ","); if (ret_tok) { while(isspace((int)*ret_tok)) {ret_tok++;} return (ret_tok); } } ParseError("Byte_Math token input[%s] is invalid one for options[%s]\n",ret_tok,del); return ret_tok; } /**************************************************************************** * * Function: ByteMathParse(char *, ByteMathData *, OptTreeNode *) * * Purpose: This is the function that is used to process the option keyword's * arguments and attach them to the rule's data structures. * * Arguments: data => argument data * idx => pointer to the processed argument storage * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ static ByteMathOverrideData * ByteMathParse(char *data, ByteMathData *idx, OptTreeNode *otn) { char **toks; char *endp; int num_toks; char *cptr; int i = 0; bool offset_flag = false; RuleOptByteOrderFunc tmp_byte_order_func; idx->rvalue_var = -1; toks = mSplit(data, ",", 13, &num_toks, 0); while(i < num_toks) { cptr=toks[i]; while(isspace((int)*cptr)) {cptr++;} /* set how many bytes to process from the packet */ if (!strncmp(cptr,"bytes",5)) { if (!idx->bytes_to_extract) { cptr=ByteMath_tok_extract(cptr,"bytes"); idx->bytes_to_extract = strtol(cptr, &endp, 10); if (*endp != '\0') { ParseError("byte_math option has bad input: %s.", cptr); } if(idx->bytes_to_extract > PARSELEN || idx->bytes_to_extract == 0) { ParseError("byte_math option bytes_to_extract has invalid input.valid range is 1 to 10 bytes\n"); } i++; continue; } else { ParseError("byte_math option bytes_to_extract is already configured once\n"); } } else if (!strncmp(cptr,"oper",4)) { if (!idx->operator) { cptr=ByteMath_tok_extract(cptr,"oper"); /* set the operator */ switch(*cptr) { case '+': idx->operator = BM_PLUS; break; case '-': idx->operator = BM_MINUS; break; case '*': idx->operator = BM_MULTIPLY; break; case '/': idx->operator = BM_DIVIDE; break; case '<': cptr++; if (*cptr == '<') idx->operator = BM_LEFT_SHIFT; else ParseError("byte_math unknown operator [%s]\n",--cptr); break; case '>': cptr++; if (*cptr == '>') idx->operator = BM_RIGHT_SHIFT; else ParseError("byte_math unknown operator [%s]\n",--cptr); break; default: ParseError("byte_math unknown operator [%s]\n",cptr); } cptr++; if (*cptr) { ParseError("byte_math unknown operator[%s]\n",--cptr); } i++; continue; } else { ParseError("byte_math option OPERATOR is already configured in rule\n"); } } else if (!strncmp(cptr,"rvalue",6)) { if (!idx->rvalue) { /* set the value to test against */ cptr=ByteMath_tok_extract(cptr,"rvalue"); if (isdigit(*cptr) || *cptr == '-') { int64_t rval = SnortStrtoul(cptr, &endp,0); if (rval > MAX_RVAL || !rval) { ParseError("byte_math rule option has invalid rvalue." "Valid rvalue range %u-%u.", MIN_RVAL,MAX_RVAL); } idx->rvalue=rval; idx->rvalue_var = -1; if(*endp != '\0') { ParseError("byte_math option has bad rvalue: %s", cptr); } } else { idx->rvalue_var = GetVarByName(cptr); if (idx->rvalue_var == BYTE_EXTRACT_NO_VAR) { ParseError(BYTE_EXTRACT_INVALID_ERR_FMT, "byte_Math", cptr); } } i++; continue; } else { ParseError("byte_math rvalue is already configured in rule once\n"); } } else if (!strncmp(cptr,"offset",6)) { if (!idx->offset) { cptr=ByteMath_tok_extract(cptr,"offset"); /* set offset */ if (isdigit(*cptr) || *cptr == '-') { idx->offset = SnortStrtoul(cptr, &endp,0); idx->offset_var = -1; if(*endp != '\0') { ParseError("byte_math option has bad offset: %s", cptr); } } else { idx->offset_var = GetVarByName(cptr); if (idx->offset_var == BYTE_EXTRACT_NO_VAR) { ParseError(BYTE_EXTRACT_INVALID_ERR_FMT, "byte_Math", cptr); } } offset_flag = true; i++; continue; } else { ParseError("byte_math option offset is Already configured in rule once\n"); } } else if (!strncmp(cptr,"result",6)) { if (!idx->result_var) { cptr=ByteMath_tok_extract(cptr,"result"); /* set result variable */ if ( GetVarByName(cptr) == BYTE_EXTRACT_NO_VAR ) { idx->result_var = SnortStrdup(cptr); } else { ParseError("byte_Math:: result variable name is already used in byte_extract rule \n"); } if (!idx->result_var) ParseError("byte_Math::result_var malloc failure"); if (idx->result_var && isdigit(idx->result_var[0])) { free(idx->result_var); ParseError("byte_Math rule option has a name which starts with a digit. " "Variable names must start with a letter."); } isvalidstr(idx->result_var,"byte_math"); i++; continue; } else { ParseError("byte_math result is Already configured in rule once\n"); } } else if (!strncmp(cptr,"relative",8)) { /* the offset is relative to the last pattern match */ idx->relative_flag = 1; i++; continue; } else if(!strncmp(cptr, "string",6)) { if (!idx->data_string_convert_flag ) { /* the data will be represented as a string that needs * to be converted to an int, binary is assumed otherwise */ idx->data_string_convert_flag = 1; cptr=ByteMath_tok_extract(cptr,"string"); if(!strcasecmp(cptr, "hex")) { idx->base = 16; } else if(!strcasecmp(cptr, "dec")) { idx->base = 10; } else if(!strcasecmp(cptr, "oct")) { idx->base = 8; } else { ParseError("byte_math Unable to parse string option\n"); } } else { ParseError("byte_math string is Already configured in rule once\n"); } i++; continue; } else if(strncasecmp(cptr,"bitmask ",8) == 0) { RuleOptionBitmaskParse(&(idx->bitmask_val), cptr, idx->bytes_to_extract,"BYTE_MATH"); i++; continue; } else if(!strncmp(cptr, "endian",6)) { if (!idx->endianess) { cptr=ByteMath_tok_extract(cptr,"endian"); if(!strcasecmp(cptr, "little")) { idx->endianess = LITTLE; } else if(!strcasecmp(cptr, "big")) { /* this is the default */ idx->endianess = BIG; } else { ParseError("byte_math Unable to parse Endian option\n"); } } else { ParseError("byte_math Endian is Already configured in rule\n"); } i++; continue; } else if((tmp_byte_order_func = GetByteOrderFunc(cptr)) != NULL) { idx->byte_order_func = tmp_byte_order_func; i++; continue; } else { ByteMathOverrideData *override = byteMathOverrideFuncs; while (override != NULL) { if (!strcasecmp(cptr, override->option)) { mSplitFree(&toks, num_toks); return override; } override = override->next; } ParseError("byte_math unknown modifier \"%s\"\n",cptr); } } if ( (!idx->bytes_to_extract) || (!idx->operator) || ( (!idx->rvalue) && (idx->rvalue_var == -1) ) || (!idx->result_var) || (!offset_flag) ) { ParseError("Check the bytes_to_extract/operator/offset/rvalue/result variable\n"); } if ( ( (idx->operator == BM_LEFT_SHIFT) || (idx->operator == BM_RIGHT_SHIFT) ) && (idx->rvalue >32) ) { ParseError("Number of bits in rvalue input [%d] should be less than 32 bits for operator\n",idx->rvalue); } if ( ( (idx->operator == BM_LEFT_SHIFT) || (idx->operator == BM_RIGHT_SHIFT) ) && (idx->bytes_to_extract >4) ) { ParseError("for operators << and >> valid bytes_to_extract input range is 1 to 4 bytes\n"); } if (idx->offset < MIN_BYTE_EXTRACT_OFFSET || idx->offset > MAX_BYTE_EXTRACT_OFFSET) { ParseError("byte_math rule option has invalid offset. " "Valid offsets are between %d and %d.", MIN_BYTE_EXTRACT_OFFSET, MAX_BYTE_EXTRACT_OFFSET); } if (idx->bytes_to_extract > MAX_BYTES_TO_GRAB && !idx->data_string_convert_flag) { ParseError("byte_math rule option cannot extract more than %d bytes without valid string prefix.", MAX_BYTES_TO_GRAB); } mSplitFree(&toks, num_toks); return NULL; } /**************************************************************************** * * Function: ByteMath(char *, OptTreeNode *, OptFpList *) * * Purpose: Use this function to perform the particular detection routine * that this rule keyword is supposed to encompass. * * Arguments: p => pointer to the decoded packet * otn => pointer to the current rule's OTN * fp_list => pointer to the function pointer list * * Returns: If the detection test fails, this function *must* return a zero! * On success, it calls the next function in the detection list * ****************************************************************************/ int ByteMath(void *option_data, Packet *p) { ByteMathData *btd = (ByteMathData *)option_data; int rval = DETECTION_OPTION_NO_MATCH; uint32_t *value = 0; int success = 0; int dsize; const char *base_ptr, *end_ptr, *start_ptr; int payload_bytes_grabbed; int32_t offset; uint32_t extract_offset, extract_rvalue; int search_start = 0; PROFILE_VARS; PREPROC_PROFILE_START(byteMathPerfStats); if (Is_DetectFlag(FLAG_ALT_DETECT)) { dsize = DetectBuffer.len; start_ptr = (const char*)DetectBuffer.data; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Using Alternative Detect buffer!\n");); } else if(Is_DetectFlag(FLAG_ALT_DECODE)) { dsize = DecodeBuffer.len; start_ptr = (char *)DecodeBuffer.data; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Using Alternative Decode buffer!\n");); } else { if(IsLimitedDetect(p)) dsize = p->alt_dsize; else dsize = p->dsize; start_ptr = (char *) p->data; } base_ptr = start_ptr; end_ptr = start_ptr + dsize; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "[*] byte Math firing...\n"); DebugMessage(DEBUG_PATTERN_MATCH,"payload starts at %p\n", start_ptr); DebugMessage(DEBUG_PATTERN_MATCH,"payload ends at %p\n", end_ptr); DebugMessage(DEBUG_PATTERN_MATCH,"doe_ptr %p\n", doe_ptr); ); value = &bytemath_variable; /* Get values from byte_extract variables, if present. */ if (btd->rvalue_var >= 0 && btd->rvalue_var < NUM_BYTE_EXTRACT_VARS) { GetByteExtractValue(&extract_rvalue, btd->rvalue_var); btd->rvalue = (int32_t) extract_rvalue; if (!btd->rvalue && (btd->operator == BM_DIVIDE)) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "byte math input value zero for Divide operator is invalid\n");); PREPROC_PROFILE_END(byteMathPerfStats); return DETECTION_OPTION_NO_MATCH; } } if (btd->offset_var >= 0 && btd->offset_var < NUM_BYTE_EXTRACT_VARS) { GetByteExtractValue(&extract_offset, btd->offset_var); btd->offset = (int32_t) extract_offset; } if(btd->relative_flag && doe_ptr) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Checking relative offset!\n");); /* @todo: possibly degrade to use the other buffer, seems non-intuitive * Because doe_ptr can be "end" in the last match, * use end + 1 for upper bound * Bound checked also after offset is applied * (see byte_extract() and string_extract()) */ if(!inBounds((const uint8_t *)start_ptr, (const uint8_t *)end_ptr + 1, doe_ptr)) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "[*] byte Math bounds check failed..\n");); PREPROC_PROFILE_END(byteMathPerfStats); return rval; } search_start = (doe_ptr - (const uint8_t *)start_ptr) + btd->offset; base_ptr = (const char *)doe_ptr; } else { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "checking absolute offset %d\n", btd->offset);); search_start = btd->offset; base_ptr = start_ptr; } if( search_start < 0 ) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "[*] byte Math bounds check failed..\n");); PREPROC_PROFILE_END(byteMathPerfStats); return rval; } base_ptr = base_ptr + btd->offset; /* Use byte_order_func to determine endianess, if present */ if (btd->byte_order_func) { offset = (int32_t) ((const uint8_t *)base_ptr - p->data); btd->endianess = btd->byte_order_func(p, offset); if (btd->endianess == -1) { PREPROC_PROFILE_END(byteMathPerfStats); return DETECTION_OPTION_NO_MATCH; } } /* both of these functions below perform their own bounds checking within * byte_extract.c */ if(!btd->data_string_convert_flag) { if(byte_extract(btd->endianess, btd->bytes_to_extract, (const uint8_t *)base_ptr, (const uint8_t *)start_ptr, (const uint8_t *)end_ptr, value)) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Byte Extraction Failed\n");); PREPROC_PROFILE_END(byteMathPerfStats); return rval; } payload_bytes_grabbed = (int)btd->bytes_to_extract; } else { payload_bytes_grabbed = string_extract( btd->bytes_to_extract, btd->base, (const uint8_t *)base_ptr, (const uint8_t *)start_ptr, (const uint8_t *)end_ptr, value); if ( payload_bytes_grabbed < 0 ) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "String Extraction Failed\n");); PREPROC_PROFILE_END(byteMathPerfStats); return rval; } } if(btd->bitmask_val != 0 ) { int num_tailing_zeros_bitmask = getNumberTailingZerosInBitmask(btd->bitmask_val); *value = (*value) & btd->bitmask_val ; if ( (*value ) && num_tailing_zeros_bitmask ) { *value = (*value) >> num_tailing_zeros_bitmask; } } DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Grabbed %d bytes at offset %d rvalue = 0x%08X(%u) value = 0x%08X(%u)\n", payload_bytes_grabbed, btd->offset, btd->rvalue, btd->rvalue, value, value); ); switch(btd->operator) { case BM_PLUS: if ((UINT_MAX - *value) < btd->rvalue) { LogMessage("Buffer Overflow\n"); return DETECTION_OPTION_NO_MATCH; } else { *value += btd->rvalue; success = 1; break; } case BM_MINUS: if (*value < btd->rvalue) { LogMessage("Buffer Underflow\n"); return DETECTION_OPTION_NO_MATCH; } else { *value -= btd->rvalue; success = 1; break; } case BM_MULTIPLY: *value *= btd->rvalue; success = 1; break; case BM_DIVIDE: *value = (*value/ btd->rvalue); success = 1; break; case BM_LEFT_SHIFT: *value = (*value << btd->rvalue); success = 1; break; case BM_RIGHT_SHIFT: *value = (*value >> btd->rvalue); success = 1; break; } DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "byte_math result final value = 0x%08X(%u)\n", value, value); ); if (success) { rval = DETECTION_OPTION_MATCH; } /* if the test isn't successful, this function *must* return 0 */ PREPROC_PROFILE_END(byteMathPerfStats); return rval; } void ByteMathFree(void *d) { ByteMathData *data = (ByteMathData *)d; if (data) { free(data->result_var); data->result_var=NULL; } if ( bytemath_variable_name != NULL ) { free( bytemath_variable_name ); bytemath_variable_name = NULL; } free(data); } /*for given an OptFpList,clear the variable_name */ void ClearByteMathVarNames(OptFpList *fpl) { while (fpl != NULL) { if (fpl->type == RULE_OPTION_TYPE_BYTE_MATH) return; fpl = fpl->next; } if (bytemath_variable_name != NULL) { free(bytemath_variable_name); bytemath_variable_name = NULL; } } /* Given a variable name, retrieve its index. For use by other options.dynamic-plugin support */ int8_t GetVarByName_check(char *name) { if (name == NULL) return BYTE_EXTRACT_NO_VAR; if (bytemath_variable_name && (!strcmp(bytemath_variable_name,name))) { return 0; } else { return (GetVarByName(name)); } return BYTE_EXTRACT_NO_VAR; } void AddVarName_Bytemath(ByteMathData *data) { if (bytemath_variable_name != NULL) { free(bytemath_variable_name); bytemath_variable_name = NULL; } bytemath_variable_name = SnortStrdup(data->result_var); } int8_t Var_check_byte_math(char *name) { if (!strcmp(bytemath_variable_name,name)) { return 1; } return 0; } snort-2.9.15.1/src/detection-plugins/sp_byte_math.h0000644000175200017520000000253213571422607017125 00000000000000#ifndef __SP_BYTE_MATH_H__ #define __SP_BYTE_MATH_H__ #include "sf_engine/sf_snort_plugin_api.h" #include "decode.h" #include "plugbase.h" #define BM_PLUS CHECK_ADD #define BM_MINUS CHECK_SUB #define BM_MULTIPLY CHECK_MUL #define BM_DIVIDE CHECK_DIV #define BM_LEFT_SHIFT CHECK_LS #define BM_RIGHT_SHIFT CHECK_RS #define BM_CHECK_NONE CHECK_NONE #define BIG 0 #define LITTLE 1 #define BYTE_MATH_VAR_INDEX 2 #define MIN_RVAL 1 #define MAX_RVAL 4294967295 extern char *bytemath_variable_name; extern uint32_t bytemath_variable; typedef struct _ByteMathData { uint32_t bytes_to_extract; /* lvalue : number of bytes to extract */ uint32_t rvalue; uint32_t operator; int32_t offset; uint8_t relative_flag; uint8_t data_string_convert_flag; int8_t endianess; uint32_t base; uint32_t bitmask_val; int8_t rvalue_var; int8_t offset_var; char *result_var; RuleOptByteOrderFunc byte_order_func; } ByteMathData; void SetupByteMath(void); uint32_t ByteMathHash(void *d); int8_t GetVarByName_check(char *name); void ClearByteMathVarNames(OptFpList *fpl); void AddVarName_Bytemath(ByteMathData *data); int ByteMathCompare(void *l, void *r); int ByteMath(void *, Packet *); void ByteMathFree(void *d); #endif /* __SP_BYTE_MATH_H__ */ snort-2.9.15.1/src/detection-plugins/sp_clientserver.c0000644000175200017520000003625213571422607017657 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Author: Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* sp_clientserver * * Purpose: * * Wouldn't be nice if we could tell a TCP rule to only apply if it's going * to or from the client or server side of a connection? Think of all the * false alarms we could elminate! That's what we're doing with this one, * it allows you to write rules that only apply to client or server packets. * One thing though, you *must* have stream4 enabled for it to work! * * Arguments: * * None. * * Effect: * * Test the packet to see if it's coming from the client or the server side * of a connection. * * Comments: * * None. * */ /* put the name of your pluging header file here */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "sf_types.h" #include "rules.h" #include "treenodes.h" #include "decode.h" #include "plugbase.h" #include "parser.h" #include "snort_debug.h" #include "util.h" #include "plugin_enum.h" #include "snort.h" //#include "signature.h" #include "sfhashfcn.h" #include "sp_clientserver.h" #include "stream_api.h" #include "snort.h" #include "profiler.h" #ifdef PERF_PROFILING PreprocStats flowCheckPerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif #include "sfhashfcn.h" #include "detection_options.h" void FlowInit(struct _SnortConfig *, char *, OptTreeNode *, int); void ParseFlowArgs(struct _SnortConfig *, char *, OptTreeNode *); void InitFlowData(OptTreeNode *); int CheckFlow(void *option_data, Packet *p); uint32_t FlowHash(void *d) { uint32_t a,b,c; ClientServerData *data = (ClientServerData *)d; a = data->from_server || data->from_client << 16; b = data->ignore_reassembled || data->only_reassembled << 16; c = data->stateless || data->established << 16; mix(a,b,c); a += data->unestablished; b += RULE_OPTION_TYPE_FLOW; final(a,b,c); return c; } int FlowCompare(void *l, void *r) { ClientServerData *left = (ClientServerData *)l; ClientServerData *right = (ClientServerData *)r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if (( left->from_server == right->from_server) && ( left->from_client == right->from_client) && ( left->ignore_reassembled == right->ignore_reassembled) && ( left->only_reassembled == right->only_reassembled) && ( left->stateless == right->stateless) && ( left->established == right->established) && ( left->unestablished == right->unestablished)) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } int OtnFlowFromServer( OptTreeNode * otn ) { ClientServerData *csd; csd = (ClientServerData *)otn->ds_list[PLUGIN_CLIENTSERVER]; if(csd ) { if( csd->from_server ) return 1; } return 0; } int OtnFlowFromClient( OptTreeNode * otn ) { ClientServerData *csd; csd = (ClientServerData *)otn->ds_list[PLUGIN_CLIENTSERVER]; if(csd ) { if( csd->from_client ) return 1; } return 0; } int OtnFlowIgnoreReassembled( OptTreeNode * otn ) { ClientServerData *csd; csd = (ClientServerData *)otn->ds_list[PLUGIN_CLIENTSERVER]; if( csd ) { if( csd->ignore_reassembled ) return 1; } return 0; } int OtnFlowOnlyReassembled( OptTreeNode * otn ) { ClientServerData *csd; csd = (ClientServerData *)otn->ds_list[PLUGIN_CLIENTSERVER]; if( csd ) { if( csd->only_reassembled ) return 1; } return 0; } /**************************************************************************** * * Function: SetupClientServer() * * Purpose: Generic detection engine plugin template. Registers the * configuration function and links it to a rule keyword. This is * the function that gets called from InitPlugins in plugbase.c. * * Arguments: None. * * Returns: void function * ****************************************************************************/ void SetupClientServer(void) { /* map the keyword to an initialization/processing function */ RegisterRuleOption("flow", FlowInit, NULL, OPT_TYPE_DETECTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("flow", &flowCheckPerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Plugin: ClientServerName(Flow) Setup\n");); } /**************************************************************************** * * Function: FlowInit(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: Configure the flow init option to register the appropriate checks * * Arguments: data => rule arguments/data * otn => pointer to the current rule option list node * * Returns: void function * ****************************************************************************/ void FlowInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { ClientServerData *csd; /* multiple declaration check */ if(otn->ds_list[PLUGIN_CLIENTSERVER]) { FatalError("%s(%d): Multiple flow options in rule\n", file_name, file_line); } InitFlowData(otn); ParseFlowArgs(sc, data, otn); csd = (ClientServerData *)otn->ds_list[PLUGIN_CLIENTSERVER]; if(protocol == IPPROTO_UDP) { if (!stream_api || (stream_api->version != STREAM_API_VERSION5)) { FatalError("%s(%d): Cannot check flow connection " "for UDP traffic\n", file_name, file_line); } } if (protocol == IPPROTO_ICMP) { if ((csd->only_reassembled != ONLY_FRAG) && (csd->ignore_reassembled != IGNORE_FRAG)) { FatalError("%s(%d): Cannot check flow connection " "for ICMP traffic\n", file_name, file_line); } } } static inline void CheckStream(char *token) { if (!stream_api) { FatalError("%s(%d): Stream must be enabled to use the '%s' option.\n", file_name, file_line, token); } } /**************************************************************************** * * Function: ParseFlowArgs(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: parse the arguments to the flow plugin and alter the otn * accordingly * * Arguments: otn => pointer to the current rule option list node * * Returns: void function * ****************************************************************************/ void ParseFlowArgs(struct _SnortConfig *sc, char *data, OptTreeNode *otn) { char *token, *str, *p; ClientServerData *csd; void *idx_dup; OptFpList *fpl = NULL; csd = (ClientServerData *)otn->ds_list[PLUGIN_CLIENTSERVER]; str = SnortStrdup(data); p = str; /* nuke leading whitespace */ while(isspace((int)*p)) p++; token = strtok(p, ","); while(token) { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "parsed %s,(%d)\n", token,strlen(token));); while(isspace((int)*token)) token++; if(!strcasecmp(token, "to_server")) { CheckStream(token); csd->from_client = 1; } else if(!strcasecmp(token, "to_client")) { CheckStream(token); csd->from_server = 1; } else if(!strcasecmp(token, "from_server")) { CheckStream(token); csd->from_server = 1; } else if(!strcasecmp(token, "from_client")) { CheckStream(token); csd->from_client = 1; } else if(!strcasecmp(token, "stateless")) { csd->stateless = 1; otn->stateless = 1; } else if(!strcasecmp(token, "established")) { CheckStream(token); csd->established = 1; otn->established = 1; } else if(!strcasecmp(token, "not_established")) { CheckStream(token); csd->unestablished = 1; otn->unestablished = 1; } else if(!strcasecmp(token, "no_stream")) { CheckStream(token); csd->ignore_reassembled |= IGNORE_STREAM; } else if(!strcasecmp(token, "only_stream")) { CheckStream(token); csd->only_reassembled |= ONLY_STREAM; } else if(!strcasecmp(token, "no_frag")) { csd->ignore_reassembled |= IGNORE_FRAG; } else if(!strcasecmp(token, "only_frag")) { csd->only_reassembled |= ONLY_FRAG; } else { FatalError("%s:%d: Unknown Flow Option: '%s'\n", file_name,file_line,token); } token = strtok(NULL, ","); } if(csd->from_client && csd->from_server) { FatalError("%s:%d: Can't use both from_client" "and flow_from server", file_name, file_line); } if((csd->ignore_reassembled & IGNORE_STREAM) && (csd->only_reassembled & ONLY_STREAM)) { FatalError("%s:%d: Can't use no_stream and" " only_stream", file_name,file_line); } if((csd->ignore_reassembled & IGNORE_FRAG) && (csd->only_reassembled & ONLY_FRAG)) { FatalError("%s:%d: Can't use no_frag and" " only_frag", file_name,file_line); } if(otn->stateless && (csd->from_client || csd->from_server)) { FatalError("%s:%d: Can't use flow: stateless option with" " other options", file_name, file_line); } if(otn->stateless && otn->established) { FatalError("%s:%d: Can't specify established and stateless " "options in same rule\n", file_name, file_line); } if(otn->stateless && otn->unestablished) { FatalError("%s:%d: Can't specify unestablished and stateless " "options in same rule\n", file_name, file_line); } if(otn->established && otn->unestablished) { FatalError("%s:%d: Can't specify unestablished and established " "options in same rule\n", file_name, file_line); } if (add_detection_option(sc, RULE_OPTION_TYPE_FLOW, (void *)csd, &idx_dup) == DETECTION_OPTION_EQUAL) { #ifdef DEBUG_RULE_OPTION_TREE LogMessage("Duplicate Flow:\n%c %c %c %c\n%c %c %c %c\n\n", csd->from_client, csd->from_server, csd->ignore_reassembled, csd->only_reassembled, ((ClientServerData *)idx_dup)->from_client, ((ClientServerData *)idx_dup)->from_server, ((ClientServerData *)idx_dup)->ignore_reassembled, ((ClientServerData *)idx_dup)->only_reassembled); #endif free(csd); csd = otn->ds_list[PLUGIN_CLIENTSERVER] = (ClientServerData *)idx_dup; } fpl = AddOptFuncToList(CheckFlow, otn); if (fpl) { fpl->type = RULE_OPTION_TYPE_FLOW; fpl->context = (void *)csd; } free(str); } /**************************************************************************** * * Function: InitFlowData(OptTreeNode *) * * Purpose: calloc the clientserver data node * * Arguments: otn => pointer to the current rule option list node * * Returns: void function * ****************************************************************************/ void InitFlowData(OptTreeNode * otn) { /* allocate the data structure and attach it to the rule's data struct list */ otn->ds_list[PLUGIN_CLIENTSERVER] = (ClientServerData *) calloc(sizeof(ClientServerData), sizeof(char)); if(otn->ds_list[PLUGIN_CLIENTSERVER] == NULL) { FatalError("FlowData calloc Failed!\n"); } } int CheckFlow(void *option_data, Packet *p) { ClientServerData *csd = (ClientServerData *)option_data; PROFILE_VARS; PREPROC_PROFILE_START(flowCheckPerfStats); /* Check established/unestablished first */ if (ScStateful()) { if ((csd->established == 1) && !(p->packet_flags & PKT_STREAM_EST)) { /* ** This option requires an established connection and it isn't ** in that state yet, so no match. */ PREPROC_PROFILE_END(flowCheckPerfStats); return DETECTION_OPTION_NO_MATCH; } else if ((csd->unestablished == 1) && (p->packet_flags & PKT_STREAM_EST)) { /* ** We're looking for an unestablished stream, and this is ** established, so don't continue processing. */ PREPROC_PROFILE_END(flowCheckPerfStats); return DETECTION_OPTION_NO_MATCH; } } /* Now check from client */ if (csd->from_client) { if (ScStateful()) { if (!(p->packet_flags & PKT_FROM_CLIENT) && (p->packet_flags & PKT_FROM_SERVER)) { /* No match on from_client */ PREPROC_PROFILE_END(flowCheckPerfStats); return DETECTION_OPTION_NO_MATCH; } } } /* And from server */ if (csd->from_server) { if (ScStateful()) { if (!(p->packet_flags & PKT_FROM_SERVER) && (p->packet_flags & PKT_FROM_CLIENT)) { /* No match on from_server */ PREPROC_PROFILE_END(flowCheckPerfStats); return DETECTION_OPTION_NO_MATCH; } } } /* ...ignore_reassembled */ if (csd->ignore_reassembled & IGNORE_STREAM) { if (p->packet_flags & PKT_REBUILT_STREAM) { PREPROC_PROFILE_END(flowCheckPerfStats); return DETECTION_OPTION_NO_MATCH; } } if (csd->ignore_reassembled & IGNORE_FRAG) { if (p->packet_flags & PKT_REBUILT_FRAG) { PREPROC_PROFILE_END(flowCheckPerfStats); return DETECTION_OPTION_NO_MATCH; } } /* ...only_reassembled */ if (csd->only_reassembled & ONLY_STREAM) { if ( !PacketHasPAFPayload(p)) { PREPROC_PROFILE_END(flowCheckPerfStats); return DETECTION_OPTION_NO_MATCH; } } if (csd->only_reassembled & ONLY_FRAG) { if (!(p->packet_flags & PKT_REBUILT_FRAG)) { PREPROC_PROFILE_END(flowCheckPerfStats); return DETECTION_OPTION_NO_MATCH; } } PREPROC_PROFILE_END(flowCheckPerfStats); return DETECTION_OPTION_MATCH; } snort-2.9.15.1/src/detection-plugins/sp_clientserver.h0000644000175200017520000000612713571422607017662 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ /* ClientServer detection plugin header */ #ifndef __SP_CLIENTSERVER_H__ #define __SP_CLIENTSERVER_H__ #define ONLY_STREAM 0x01 #define ONLY_FRAG 0x02 #define IGNORE_STREAM 0x01 #define IGNORE_FRAG 0x02 typedef struct _ClientServerData { uint8_t from_server; uint8_t from_client; uint8_t ignore_reassembled; /* ignore reassembled sessions */ uint8_t only_reassembled; /* ignore reassembled sessions */ uint8_t stateless; uint8_t established; uint8_t unestablished; } ClientServerData; void SetupClientServer(void); int OtnFlowFromServer( OptTreeNode * otn ); int OtnFlowFromClient( OptTreeNode * otn ); int OtnFlowIgnoreReassembled( OptTreeNode * otn ); int OtnFlowOnlyReassembled( OptTreeNode * otn ); uint32_t FlowHash(void *d); int FlowCompare(void *l, void *r); #endif /* __SP_CLIENTSERVER_H__ */ snort-2.9.15.1/src/detection-plugins/sp_cvs.c0000644000175200017520000002675713571422607015756 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2007-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** ** @file sp_cvs.c ** ** @author Taimur Aslam ** @author Todd Wease ** ** @brief Decode and detect CVS vulnerabilities ** ** This CVS detection plugin provides support for detecting published CVS vulnerabilities. The ** vulnerabilities that can be detected are: ** Bugtraq-10384, CVE-2004-0396: "Malformed Entry Modified and Unchanged flag insertion" ** ** Detection Functions: ** ** cvs: invalid-entry; ** */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "sf_types.h" #include "rules.h" #include "treenodes.h" #include "decode.h" #include "plugbase.h" #include "parser.h" #include "snort_debug.h" #include "util.h" #include "mstring.h" #include "snort_bounds.h" #include "sp_cvs.h" #include "profiler.h" #ifdef PERF_PROFILING PreprocStats cvsPerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif #include "sfhashfcn.h" #include "detection_options.h" /* function prototypes */ static void CvsInit(struct _SnortConfig *, char *, OptTreeNode *, int); static void CvsRuleParse(char *, CvsRuleOption *); static int CvsDetect(void *option_data, Packet *p); static int CvsDecode(const uint8_t *, uint16_t, CvsRuleOption *); static void CvsGetCommand(const uint8_t *, const uint8_t *, CvsCommand *); static int CvsCmdCompare(const char *, const uint8_t *, int); static int CvsValidateEntry(const uint8_t *, const uint8_t *); static void CvsGetEOL(const uint8_t *, const uint8_t *, const uint8_t **, const uint8_t **); uint32_t CvsHash(void *d) { uint32_t a,b,c; CvsRuleOption *data = (CvsRuleOption *)d; a = data->type; b = RULE_OPTION_TYPE_CVS; c = 0; final(a,b,c); return c; } int CvsCompare(void *l, void *r) { CvsRuleOption *left = (CvsRuleOption *)l; CvsRuleOption *right = (CvsRuleOption *)r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if (left->type == right->type) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } /* ** NAME ** SetupCvs ** Register the CVS detection plugin. ** */ /** ** ** @return None ** */ void SetupCvs(void) { RegisterRuleOption("cvs", CvsInit, NULL, OPT_TYPE_DETECTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("cvs", &cvsPerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Plugin: CVS Setup\n");); } /* ** NAME ** CvsInit ** Initialize the CVS context and set it up so we can detect commands. ** */ /** ** ** @return None ** */ static void CvsInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { CvsRuleOption *cvs_rule_option; void *ds_ptr_dup; OptFpList *ofl; cvs_rule_option = (CvsRuleOption *)SnortAlloc(sizeof(CvsRuleOption)); CvsRuleParse(data, cvs_rule_option); if (add_detection_option(sc, RULE_OPTION_TYPE_CVS, (void *)cvs_rule_option, &ds_ptr_dup) == DETECTION_OPTION_EQUAL) { free(cvs_rule_option); cvs_rule_option = ds_ptr_dup; } /* Attach detection function to rule's detect function ptr */ ofl = AddOptFuncToList(CvsDetect, otn); ofl->type = RULE_OPTION_TYPE_CVS; ofl->context = (void *)cvs_rule_option; } /* ** NAME ** CvsRuleParse ** Parse the CVS rules and set the threshold criteria. */ /** ** ** @return None ** */ static void CvsRuleParse(char *rule_args, CvsRuleOption *cvs_rule_option) { char **toks; int num_toks = 0; toks = mSplit(rule_args, CVS_CONFIG_DELIMITERS, 2, &num_toks, 0); switch (num_toks) { /* no arguments */ case 1: if (strcasecmp(toks[0], CVS_CONF_INVALID_ENTRY_STR) == 0) { cvs_rule_option->type = CVS_INVALID_ENTRY; } else { FatalError("%s(%d) => Invalid argument specified for CVS rule: %s\n", file_name, file_line, toks[0]); } break; default: FatalError("%s(%d) => No or wrong number of arguments " "specified for CVS rule\n", file_name, file_line); break; } mSplitFree(&toks, num_toks); } /* ** NAME ** CvsDetect ** This function is called on a per rule basis for CVS detection. ** */ /** ** ** @return integer ** @retval CVS_NO_ALERT ** @retval CVS_ALERT ** */ static int CvsDetect(void *option_data, Packet *p) { int ret; int rval = DETECTION_OPTION_NO_MATCH; CvsRuleOption *cvs_rule_option = (CvsRuleOption *)option_data; if (p == NULL) { return rval; } if ((p->tcph == NULL) || (p->data == NULL) || (p->dsize == 0)) { return rval; } if (cvs_rule_option == NULL) { return rval; } DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "CVS begin detection\n");); ret = CvsDecode(p->data, p->dsize, cvs_rule_option); if (ret == CVS_ALERT) { rval = DETECTION_OPTION_MATCH; } return rval; } /* ** NAME ** CvsDecode ** This main decode function. Decode the CVS commands and detect the vulnerabilities. ** */ /** ** ** @return integer ** */ static int CvsDecode(const uint8_t *data, uint16_t data_len, CvsRuleOption *cvs_rule_option) { const uint8_t *line, *end; const uint8_t *eol = NULL, *eolm = NULL; CvsCommand command; int ret; line = data; end = data + data_len; /* loop through data, analyzing a line at a time */ while (line < end) { /* CVS commands are delimited by \n so break them up */ CvsGetEOL(line, end, &eol, &eolm); /* Put command and argument into structure */ CvsGetCommand(line, eolm, &command); /* shouldn't happen as long as line < end, but ... */ if (command.cmd_str == NULL) return CVS_NO_ALERT; DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "CVS command\n" " comand: %.*s\n" "argument: %.*s\n", command.cmd_str_len, (char *)command.cmd_str, command.cmd_arg == NULL ? 4 : command.cmd_arg_len, command.cmd_arg == NULL ? "none" : (char *)command.cmd_arg);); switch (cvs_rule_option->type) { case CVS_INVALID_ENTRY: if (CvsCmdCompare(CVS_ENTRY_STR, command.cmd_str, command.cmd_str_len) == 0) { ret = CvsValidateEntry(command.cmd_arg, (command.cmd_arg + command.cmd_arg_len)); if ((ret == CVS_ENTRY_INVALID)&&(eol < end)) { return CVS_ALERT; } } break; default: break; } line = eol; } return CVS_NO_ALERT; } /* ** NAME ** CvsCmdCompare ** Compares two pointers to char to see if they are equal. ** The first arg is NULL terminated. The second is not and ** it's length is passed in. ** */ /** ** @return 0 if equal ** @return 1 if not equal ** */ static int CvsCmdCompare(const char *cmd, const uint8_t *pkt_cmd, int pkt_cmd_len) { if (((size_t)pkt_cmd_len == strlen(cmd)) && (memcmp(pkt_cmd, cmd, pkt_cmd_len) == 0)) { return 0; } return 1; } /* ** NAME ** CvsGetCommand ** Takes a line and breaks it up into command and argument. ** It modifies the data in the string by replacing the first ** space character it sees with '\0'. A pointer to the string ** created by the replacement is put in the CvsCommand structure's ** command member. A pointer to the rest of the string after ** the replacement '\0' is put into the structure's command ** argument member. If there isn't a space, the entire line ** is put in the command and the command argument is set to ** NULL. ** */ /** ** @return None ** */ static void CvsGetCommand(const uint8_t *line, const uint8_t *end, CvsCommand *cmd) { const uint8_t *cmd_end; if (cmd == NULL) return; /* no line, no command or args */ if (line == NULL) { cmd->cmd_str = NULL; cmd->cmd_str_len = 0; cmd->cmd_arg = NULL; cmd->cmd_arg_len = 0; return; } cmd->cmd_str = line; cmd_end = (const uint8_t *)memchr(line, CVS_COMMAND_SEPARATOR, end - line); if (cmd_end != NULL) { cmd->cmd_str_len = cmd_end - line; cmd->cmd_arg = cmd_end + 1; cmd->cmd_arg_len = end - cmd_end - 1; } else { cmd->cmd_str_len = end - line; cmd->cmd_arg = NULL; cmd->cmd_arg_len = 0; } } /* ** NAME ** CvsValidateEntry ** Checks Entry argument to make sure it is well formed ** An entry sent to the server should look like: ** /file/version/// ** e.g. '/cvs.c/1.5///' ** There should be nothing between the third and ** fourth slashes ** */ /** ** @return CVS_ENTRY_VALID if valid ** @return CVS_ENTRY_INVALID if invalid ** */ static int CvsValidateEntry(const uint8_t *entry_arg, const uint8_t *end_arg) { int slashes = 0; if ((entry_arg == NULL) || (end_arg == NULL)) { return CVS_ENTRY_VALID; } /* There should be exactly 5 slashes in the string */ while (entry_arg < end_arg) { /* if on the 3rd slash, check for next char == '/' or '+' * This is where the heap overflow on multiple Is-Modified * commands occurs */ if (slashes == 3) { if((*entry_arg != '/')&&(*entry_arg != '+')) { return CVS_ENTRY_INVALID; } } if (*entry_arg != '/') { entry_arg = memchr(entry_arg, '/', end_arg - entry_arg); if (entry_arg == NULL) break; } slashes++; entry_arg++; } if (slashes != 5) { return CVS_ENTRY_INVALID; } return CVS_ENTRY_VALID; } /* ** NAME ** CvsGetEOL ** Gets a line from the data string. ** Sets an end-of-line marker to point to the marker ** and an end-of-line pointer to point after marker ** */ /** ** @return void ** */ static void CvsGetEOL(const uint8_t *ptr, const uint8_t *end, const uint8_t **eol, const uint8_t **eolm) { *eolm = (uint8_t *)memchr(ptr, CVS_COMMAND_DELIMITER, end - ptr); if (*eolm == NULL) { *eolm = end; *eol = end; } else { *eol = *eolm + 1; } } snort-2.9.15.1/src/detection-plugins/sp_cvs.h0000644000175200017520000000446713571422607015755 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2007-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** ** @file sp_cvs.h ** ** @author Taimur Aslam ** @author Todd Wease ** ** @brief Decode and detect CVS vulnerabilities ** ** This CVS detection plugin provides support for detecting published CVS vulnerabilities. The ** vulnerabilities that can be detected are: ** Bugtraq-10384, CVE-2004-0396: "Malformed Entry Modified and Unchanged flag insertion" ** ** Detection Functions: ** ** cvs: invalid-entry; ** */ #ifndef __SP_CVS_H__ #define __SP_CVS_H__ /* macros */ #define CVS_CONFIG_DELIMITERS " \t\n" #define CVS_COMMAND_DELIMITER '\n' #define CVS_COMMAND_SEPARATOR ' ' #define CVS_CONF_INVALID_ENTRY_STR "invalid-entry" #define CVS_NO_ALERT 0 #define CVS_ALERT 1 #define CVS_ENTRY_STR "Entry" #define CVS_ENTRY_VALID 0 #define CVS_ENTRY_INVALID 1 /* the types of vulnerabilities it will detect */ typedef enum _CvsTypes { CVS_INVALID_ENTRY = 1, CVS_END_OF_ENUM } CvsTypes; /* encapsulate the rule option */ typedef struct _CvsRuleOption { CvsTypes type; } CvsRuleOption; /* represents a CVS command with argument */ typedef struct _CvsCommand { const uint8_t *cmd_str; /* command string */ int cmd_str_len; const uint8_t *cmd_arg; /* command argument */ int cmd_arg_len; } CvsCommand; /* global function prototypes */ void SetupCvs(void); uint32_t CvsHash(void *d); int CvsCompare(void *l, void *r); #endif snort-2.9.15.1/src/detection-plugins/sp_dsize_check.c0000644000175200017520000002332213571422607017417 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "sf_types.h" #include "rules.h" #include "treenodes.h" #include "decode.h" #include "plugbase.h" #include "snort_debug.h" #include "parser.h" #include "plugin_enum.h" #include "util.h" #include "sfhashfcn.h" #include "snort.h" #include "profiler.h" #ifdef PERF_PROFILING PreprocStats dsizePerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif #include "sfhashfcn.h" #include "detection_options.h" #define DSIZE_EQ 1 #define DSIZE_GT 2 #define DSIZE_LT 3 #define DSIZE_RANGE 4 typedef struct _DsizeCheckData { int dsize; int dsize2; char operator; } DsizeCheckData; void DsizeCheckInit(struct _SnortConfig *, char *, OptTreeNode *, int); void ParseDsize(struct _SnortConfig *, char *, OptTreeNode *); int CheckDsize(void *option_data, Packet *p); uint32_t DSizeCheckHash(void *d) { uint32_t a,b,c; DsizeCheckData *data = (DsizeCheckData *)d; a = data->dsize; b = data->dsize2; c = data->operator; mix(a,b,c); a += RULE_OPTION_TYPE_DSIZE; final(a,b,c); return c; } int DSizeCheckCompare(void *l, void *r) { DsizeCheckData *left = (DsizeCheckData *)l; DsizeCheckData *right = (DsizeCheckData *)r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if (( left->dsize == right->dsize) && ( left->dsize2 == right->dsize2) && ( left->operator == right->operator)) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } /**************************************************************************** * * Function: SetupDsizeCheck() * * Purpose: Attach the dsize keyword to the rule parse function * * Arguments: None. * * Returns: void function * ****************************************************************************/ void SetupDsizeCheck(void) { /* map the keyword to an initialization/processing function */ RegisterRuleOption("dsize", DsizeCheckInit, NULL, OPT_TYPE_DETECTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("dsize_eq", &dsizePerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Plugin: DsizeCheck Initialized\n");); } /**************************************************************************** * * Function: DsizeCheckInit(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: Parse the rule argument and attach it to the rule data struct, * then attach the detection function to the function list * * Arguments: data => rule arguments/data * otn => pointer to the current rule option list node * * Returns: void function * ****************************************************************************/ void DsizeCheckInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { /* multiple declaration check */ if(otn->ds_list[PLUGIN_DSIZE_CHECK]) { FatalError("%s(%d): Multiple dsize options in rule\n", file_name, file_line); } /* allocate the data structure and attach it to the rule's data struct list */ otn->ds_list[PLUGIN_DSIZE_CHECK] = (DsizeCheckData *) SnortAlloc(sizeof(DsizeCheckData)); /* this is where the keyword arguments are processed and placed into the rule option's data structure */ ParseDsize(sc, data, otn); /* NOTE: I moved the AddOptFuncToList call to the parsing function since the linking is best determined within that function */ } /**************************************************************************** * * Function: ParseDsize(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: Parse the dsize function argument and attach the detection * function to the rule list as well. * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ void ParseDsize(struct _SnortConfig *sc, char *data, OptTreeNode *otn) { DsizeCheckData *ds_ptr; /* data struct pointer */ char *pcEnd; char *pcTok; int iDsize = 0; void *ds_ptr_dup; OptFpList *fpl; /* set the ds pointer to make it easier to reference the option's particular data struct */ ds_ptr = (DsizeCheckData *)otn->ds_list[PLUGIN_DSIZE_CHECK]; while(isspace((int)*data)) data++; /* If a range is specified, put min in ds_ptr->dsize and max in ds_ptr->dsize2 */ if(isdigit((int)*data) && strchr(data, '<') && strchr(data, '>')) { pcTok = strtok(data, " <>"); if(!pcTok) { /* ** Fatal */ FatalError("%s(%d): Invalid 'dsize' argument.\n", file_name, file_line); } iDsize = strtol(pcTok, &pcEnd, 10); if(iDsize < 0 || *pcEnd) { FatalError("%s(%d): Invalid 'dsize' argument.\n", file_name, file_line); } ds_ptr->dsize = (unsigned short)iDsize; pcTok = strtok(NULL, " <>"); if(!pcTok) { FatalError("%s(%d): Invalid 'dsize' argument.\n", file_name, file_line); } iDsize = strtol(pcTok, &pcEnd, 10); if(iDsize < 0 || *pcEnd) { FatalError("%s(%d): Invalid 'dsize' argument.\n", file_name, file_line); } ds_ptr->dsize2 = (unsigned short)iDsize; ds_ptr->operator = DSIZE_RANGE; #ifdef DEBUG_MSGS DebugMessage(DEBUG_PLUGIN, "min dsize: %d\n", ds_ptr->dsize); DebugMessage(DEBUG_PLUGIN, "max dsize: %d\n", ds_ptr->dsize2); #endif fpl = AddOptFuncToList(CheckDsize, otn); fpl->type = RULE_OPTION_TYPE_DSIZE; if (add_detection_option(sc, RULE_OPTION_TYPE_DSIZE, (void *)ds_ptr, &ds_ptr_dup) == DETECTION_OPTION_EQUAL) { free(ds_ptr); ds_ptr = otn->ds_list[PLUGIN_DSIZE_CHECK] = ds_ptr_dup; } fpl->context = ds_ptr; return; } else if(*data == '>') { data++; fpl = AddOptFuncToList(CheckDsize, otn); ds_ptr->operator = DSIZE_GT; } else if(*data == '<') { data++; fpl = AddOptFuncToList(CheckDsize, otn); ds_ptr->operator = DSIZE_LT; } else { fpl = AddOptFuncToList(CheckDsize, otn); ds_ptr->operator = DSIZE_EQ; } fpl->type = RULE_OPTION_TYPE_DSIZE; while(isspace((int)*data)) data++; iDsize = strtol(data, &pcEnd, 10); if(iDsize < 0 || *pcEnd) { FatalError("%s(%d): Invalid 'dsize' argument.\n", file_name, file_line); } ds_ptr->dsize = (unsigned short)iDsize; if (add_detection_option(sc, RULE_OPTION_TYPE_DSIZE, (void *)ds_ptr, &ds_ptr_dup) == DETECTION_OPTION_EQUAL) { free(ds_ptr); ds_ptr = otn->ds_list[PLUGIN_DSIZE_CHECK] = ds_ptr_dup; } fpl->context = ds_ptr; DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Payload length = %d\n", ds_ptr->dsize);); } /**************************************************************************** * * Function: CheckDsizeEq(char *, OptTreeNode *) * * Purpose: Test the packet's payload size against the rule payload size value * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: 0 on failure, return value of next list function on success ****************************************************************************/ int CheckDsize(void *option_data, Packet *p) { DsizeCheckData *ds_ptr = (DsizeCheckData *)option_data; int rval = DETECTION_OPTION_NO_MATCH; PROFILE_VARS; if (!ds_ptr) return rval; PREPROC_PROFILE_START(dsizePerfStats); /* fake packet dsizes are always wrong */ /* (unless they are PDUs) */ if ( (p->packet_flags & PKT_REBUILT_STREAM) && !(p->packet_flags & PKT_PDU_HEAD) ) { PREPROC_PROFILE_END(dsizePerfStats); return rval; } switch (ds_ptr->operator) { case DSIZE_EQ: if (ds_ptr->dsize == p->dsize) rval = DETECTION_OPTION_MATCH; break; case DSIZE_GT: if (ds_ptr->dsize < p->dsize) rval = DETECTION_OPTION_MATCH; break; case DSIZE_LT: if (ds_ptr->dsize > p->dsize) rval = DETECTION_OPTION_MATCH; break; case DSIZE_RANGE: if ((ds_ptr->dsize <= p->dsize) && (ds_ptr->dsize2 >= p->dsize)) rval = DETECTION_OPTION_MATCH; break; default: break; } PREPROC_PROFILE_END(dsizePerfStats); return rval; } snort-2.9.15.1/src/detection-plugins/sp_dsize_check.h0000644000175200017520000000223013571422607017417 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifndef __SP_DSIZE_CHECK_H__ #define __SP_DSIZE_CHECK_H__ void SetupDsizeCheck(void); uint32_t DSizeCheckHash(void *d); int DSizeCheckCompare(void *l, void *r); #endif /* __SP_DSIZE_CHECK_H__ */ snort-2.9.15.1/src/detection-plugins/sp_flowbits.c0000644000175200017520000010303213571422607016772 00000000000000/* ** $Id$ ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2003-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * Major rewrite: Hui Cao * * Add flowbits OR support * ** ** sp_flowbits ** ** Purpose: ** ** Wouldn't it be nice if we could do some simple state tracking ** across multiple packets? Well, this allows you to do just that. ** ** Effect: ** ** - [Un]set a bitmask stored with the session ** - Check the value of the bitmask ** * */ #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sf_types.h" #include "rules.h" #include "treenodes.h" #include "decode.h" #include "plugbase.h" #include "parser.h" #include "snort_debug.h" #include "util.h" #include "plugin_enum.h" #include "snort.h" #include "bitop_funcs.h" #include "sfghash.h" #include "sp_flowbits.h" #include "sf_types.h" #include "mstring.h" #include "session_api.h" #include "stream_api.h" #include "snort.h" #include "profiler.h" #ifdef PERF_PROFILING PreprocStats flowBitsPerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif #include "sfhashfcn.h" #include "detection_options.h" #define DEFAULT_FLOWBIT_GROUP "default" #define ALLOWED_SPECIAL_CHARS ".-_" SFGHASH *flowbits_hash = NULL; SFGHASH *flowbits_grp_hash = NULL; SF_QUEUE *flowbits_bit_queue = NULL; uint32_t flowbits_count = 0; uint32_t flowbits_grp_count = 0; int flowbits_toggle = 1; #define DEFAULT_FLOWBIT_SIZE 1024 #define MAX_FLOWBIT_SIZE 2048 #define CONVERT_BITS_TO_BYTES(size) ( (size > 1)?(((size -1) >> 3)+ 1):0) static unsigned int giFlowbitSizeInBytes = CONVERT_BITS_TO_BYTES(DEFAULT_FLOWBIT_SIZE); static unsigned int giFlowbitSize = DEFAULT_FLOWBIT_SIZE; void FlowItemFree(void *); void FlowBitsGrpFree(void *); static void FlowBitsInit(struct _SnortConfig *, char *, OptTreeNode *, int); static void FlowBitsParse(struct _SnortConfig *, char *, FLOWBITS_OP *, OptTreeNode *); static void FlowBitsCleanExit(int, void *); /**************************************************************************** * * Function: FlowBitsHashInit(void) * * Purpose: Initialize the hash table and queue storage for flowbits IDs * * Arguments: None * * Returns: void function * ****************************************************************************/ void FlowBitsHashInit(void) { if (flowbits_hash != NULL) return; flowbits_hash = sfghash_new(10000, 0, 0, FlowItemFree); if (flowbits_hash == NULL) { FatalError("%s(%d) Could not create flowbits hash.\n", __FILE__, __LINE__); } flowbits_bit_queue = sfqueue_new(); if (flowbits_bit_queue == NULL) { FatalError("%s(%d) Could not create flowbits bit queue.\n", __FILE__, __LINE__); } } void FlowBitsGrpHashInit(void) { if (flowbits_grp_hash != NULL) return; flowbits_grp_hash = sfghash_new(10000, 0, 0, FlowBitsGrpFree); if (flowbits_grp_hash == NULL) { FatalError("%s(%d) Could not create flowbits group hash.\n", __FILE__, __LINE__); } } void FlowItemFree(void *d) { FLOWBITS_OBJECT *data = (FLOWBITS_OBJECT *)d; free(data); } void FlowBitsGrpFree(void *d) { FLOWBITS_GRP *data = (FLOWBITS_GRP *)d; boFreeBITOP(&(data->GrpBitOp)); if (data->name) free(data->name); free(data); } void FlowBitsFree(void *d) { FLOWBITS_OP *data = (FLOWBITS_OP *)d; if (data->ids) free(data->ids); if (data->name) free(data->name); if (data->group) free(data->group); free(data); } uint32_t FlowBitsHash(void *d) { uint32_t a,b,c; FLOWBITS_OP *data = (FLOWBITS_OP *)d; int i; int j = 0; a = data->eval; b = data->type; c = RULE_OPTION_TYPE_FLOWBIT; mix(a,b,c); for (i = 0, j = 0; i < data->num_ids; i++, j++) { if (j >= 3) { a += data->ids[i - 2]; b += data->ids[i - 1]; c += data->ids[i]; mix(a,b,c); j -= 3; } } if (1 == j) { a += data->ids[data->num_ids - 1]; b += data->num_ids; } else if (2 == j) { a += data->ids[data->num_ids - 2]; b += data->ids[data->num_ids - 1]|data->num_ids << 16; } c += data->group_id; final(a,b,c); return c; } int FlowBitsCompare(void *l, void *r) { FLOWBITS_OP *left = (FLOWBITS_OP *)l; FLOWBITS_OP *right = (FLOWBITS_OP *)r; int i; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if ((left->num_ids != right->num_ids)|| (left->eval != right->eval)|| (left->type != right->type)|| (left->group_id != right->group_id)) return DETECTION_OPTION_NOT_EQUAL; for (i = 0; i < left->num_ids; i++) { if (left->ids[i] != right->ids[i]) return DETECTION_OPTION_NOT_EQUAL; } return DETECTION_OPTION_EQUAL; } /**************************************************************************** * * Function: SetupFlowBits() * * Purpose: Generic detection engine plugin template. Registers the * configuration function and links it to a rule keyword. This is * the function that gets called from InitPlugins in plugbase.c. * * Arguments: None. * * Returns: void function * * 3/4/05 - man beefed up the hash table size from 100 -> 10000 * ****************************************************************************/ void SetupFlowBits(void) { /* map the keyword to an initialization/processing function */ RegisterRuleOption("flowbits", FlowBitsInit, NULL, OPT_TYPE_DETECTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("flowbits", &flowBitsPerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif AddFuncToCleanExitList(FlowBitsCleanExit, NULL); DEBUG_WRAP(DebugMessage(DEBUG_FLOWBITS, "Plugin: FlowBits Setup\n");); } /**************************************************************************** * * Function: FlowBitsInit(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: Configure the flow init option to register the appropriate checks * * Arguments: data => rule arguments/data * otn => pointer to the current rule option list node * * Returns: void function * ****************************************************************************/ static void FlowBitsInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { FLOWBITS_OP *flowbits; OptFpList *fpl; void *idx_dup; /* Flowbits are now part of the rule stub for .so rules. * We avoid adding the flowbit twice by skipping it here. */ if (otn->sigInfo.generator == 3) return; /* Flow bits are handled by Stream if its enabled */ if( stream_api && stream_api->version != STREAM_API_VERSION5) { if (ScConfErrorOut()) { FatalError("WARNING: %s (%d) => flowbits without Stream. " "Stream must be enabled for this plugin.\n", file_name,file_line); } else { LogMessage("WARNING: %s (%d) => flowbits without Stream. " "Stream must be enabled for this plugin.\n", file_name,file_line); } } /* Auto init hash table and queue */ if (flowbits_hash == NULL) FlowBitsHashInit(); if (flowbits_grp_hash == NULL ) FlowBitsGrpHashInit(); flowbits = (FLOWBITS_OP *) SnortAlloc(sizeof(FLOWBITS_OP)); if (!flowbits) { FatalError("%s (%d): Unable to allocate flowbits node\n", file_name, file_line); } /* Set the ds_list value to 1 (yes, we have flowbits for this rule) */ otn->ds_list[PLUGIN_FLOWBIT] = (void *)1; FlowBitsParse(sc, data, flowbits, otn); if (add_detection_option(sc, RULE_OPTION_TYPE_FLOWBIT, (void *)flowbits, &idx_dup) == DETECTION_OPTION_EQUAL) { char *group_name = ((FLOWBITS_OP *)idx_dup)->group; #ifdef DEBUG_RULE_OPTION_TREE LogMessage("Duplicate FlowBit:\n%d %c\n%d %c\n\n", flowbits->id, flowbits->type, ((FLOWBITS_OP *)idx_dup)->id, ((FLOWBITS_OP *)idx_dup)->type); #endif if (flowbits->group) { if (group_name && strcmp(group_name, flowbits->group)) free(group_name); ((FLOWBITS_OP *)idx_dup)->group = SnortStrdup(flowbits->group); } free(flowbits->ids); free(flowbits->name); free(flowbits->group); free(flowbits); flowbits = idx_dup; } fpl = AddOptFuncToList(FlowBitsCheck, otn); fpl->type = RULE_OPTION_TYPE_FLOWBIT; /* * attach it to the context node so that we can call each instance * individually */ fpl->context = (void *) flowbits; return; } static void udpateFlowBitGroupInfo(FLOWBITS_GRP *flowbits_grp, char *flowbitName, FLOWBITS_OBJECT *flowbits_item) { char *groupName; if (!flowbits_grp) return; groupName = flowbits_grp->name; if (!groupName) return; flowbits_grp->count++; if ( flowbits_grp->max_id < flowbits_item->id ) flowbits_grp->max_id = flowbits_item->id; boSetBit(&(flowbits_grp->GrpBitOp),flowbits_item->id); } static bool validateName(char *name) { unsigned i; if (!name) return false; for (i=0; i flowbits name, * FLOWBITS_OP *flowbits * FLOWBITS_GRP *flowbits_grp * * Returns: FLOWBITS_OBJECT*, whether exist before * ****************************************************************************/ static FLOWBITS_OBJECT* getFlowBitItem(char *flowbitName, FLOWBITS_OP *flowbits, FLOWBITS_GRP *flowbits_grp) { FLOWBITS_OBJECT *flowbits_item; int hstatus; if (!validateName(flowbitName)) { ParseError("Flowbits: flowbits name is limited to any alphanumeric string including %s" , ALLOWED_SPECIAL_CHARS); } flowbits_item = (FLOWBITS_OBJECT *)sfghash_find(flowbits_hash, flowbitName); if (flowbits_item == NULL) { flowbits_item = (FLOWBITS_OBJECT *)SnortAlloc(sizeof(FLOWBITS_OBJECT)); if (sfqueue_count(flowbits_bit_queue) > 0) { flowbits_item->id = (uint16_t)(uintptr_t)sfqueue_remove(flowbits_bit_queue); } else { flowbits_item->id = (uint16_t)flowbits_count; flowbits_count++; if(flowbits_count > giFlowbitSize) { ParseError("The number of flowbit IDs in the " "current ruleset exceeds the maximum number of IDs " "that are allowed (%d).", giFlowbitSize); } } hstatus = sfghash_add(flowbits_hash, flowbitName, flowbits_item); if(hstatus != SFGHASH_OK) { FatalError("Could not add flowbits key (%s) to hash.\n",flowbitName); } } flowbits_item->toggle = flowbits_toggle; flowbits_item->types |= flowbits->type; switch (flowbits->type) { case FLOWBITS_SET: case FLOWBITS_SETX: case FLOWBITS_UNSET: case FLOWBITS_TOGGLE: case FLOWBITS_RESET: flowbits_item->set++; break; case FLOWBITS_ISSET: case FLOWBITS_ISNOTSET: flowbits_item->isset++; break; default: break; } udpateFlowBitGroupInfo(flowbits_grp, flowbitName, flowbits_item); return flowbits_item; } static FLOWBITS_GRP *getFlowBitGroup(char *groupName) { int hstatus; FLOWBITS_GRP *flowbits_grp = NULL; if(!groupName) return NULL; if (!validateName(groupName)) { ParseError("Flowbits: flowbits group name is limited to any alphanumeric string including %s", ALLOWED_SPECIAL_CHARS); } flowbits_grp = (FLOWBITS_GRP *)sfghash_find(flowbits_grp_hash, groupName); /*New group defined, add*/ if (flowbits_grp == NULL) { flowbits_grp = (FLOWBITS_GRP *)SnortAlloc(sizeof(FLOWBITS_GRP)); boInitBITOP(&(flowbits_grp->GrpBitOp), giFlowbitSizeInBytes); boResetBITOP(&(flowbits_grp->GrpBitOp)); hstatus = sfghash_add(flowbits_grp_hash, groupName, flowbits_grp); if(hstatus != SFGHASH_OK) { FatalError("Could not add flowbits group (%s) to hash.\n",groupName); } flowbits_grp_count++; flowbits_grp->group_id = flowbits_grp_count; flowbits_grp->name = SnortStrdup(groupName); } return flowbits_grp; } #ifdef DEBUG_MSGS static void printOutFlowbits(FLOWBITS_OP *flowbits) { int i; DebugMessage(DEBUG_FLOWBITS,"flowbits: type = %d\n",flowbits->type); DebugMessage(DEBUG_FLOWBITS,"flowbits: name = %s\n",flowbits->name); DebugMessage(DEBUG_FLOWBITS,"flowbits: eval = %d\n",flowbits->eval); DebugMessage(DEBUG_FLOWBITS,"flowbits: num_ids = %d\n",flowbits->num_ids); DebugMessage(DEBUG_FLOWBITS,"flowbits: grp_id = %d\n",flowbits->group_id); DebugMessage(DEBUG_FLOWBITS,"flowbits: group_name = %s\n",flowbits->group); for (i = 0; i < flowbits->num_ids; i++) { DebugMessage(DEBUG_FLOWBITS,"flowbits: value = %d\n",flowbits->ids[i]); } } #endif /**************************************************************************** * * Function: processFlowbits(char *, FlowBits *flowbits, OptTreeNode *) * * Purpose: parse the arguments to the flow plugin and alter the otn * accordingly * * Arguments: flowbits => pointer to the current flowbits op * * Returns: void function * ****************************************************************************/ static void processFlowbits(char *flowbits_names, FLOWBITS_GRP *flowbits_grp, FLOWBITS_OP *flowbits) { char **toks; int num_toks; int i; char *flowbits_name; FLOWBITS_OBJECT *flowbits_item; if (!flowbits_names || ((*flowbits_names) == 0)) { return; } DEBUG_WRAP(DebugMessage(DEBUG_FLOWBITS, "flowbits tag id parsing %s\n",flowbits_names);); flowbits_name = SnortStrdup(flowbits_names); if (NULL != strchr(flowbits_name, '|')) { if(NULL != strchr(flowbits_name, '&')) { ParseError("Flowbits: flowbits tag id operator '|' and '&' are used together."); } toks = mSplit(flowbits_name, "|", 0, &num_toks, 0); flowbits->ids = SnortAlloc(num_toks*sizeof(*(flowbits->ids))); flowbits->num_ids = num_toks; for (i = 0; i < num_toks; i++) { flowbits_item = getFlowBitItem(toks[i], flowbits, flowbits_grp); flowbits->ids[i] = flowbits_item->id; } flowbits->eval = FLOWBITS_OR; mSplitFree(&toks, num_toks); } else if (NULL != strchr(flowbits_name, '&')) { toks = mSplit(flowbits_name, "&", 0, &num_toks, 0); flowbits->ids = SnortAlloc(num_toks*sizeof(*(flowbits->ids))); flowbits->num_ids = num_toks; for (i = 0; i < num_toks; i++) { flowbits_item = getFlowBitItem(toks[i], flowbits, flowbits_grp); flowbits->ids[i] = flowbits_item->id; } flowbits->eval = FLOWBITS_AND; mSplitFree(&toks, num_toks); } else if (!strcasecmp(flowbits_name,"all")) { flowbits->eval = FLOWBITS_ALL; } else if (!strcasecmp(flowbits_name,"any")) { flowbits->eval = FLOWBITS_ANY; } else { flowbits_item = getFlowBitItem(flowbits_name, flowbits, flowbits_grp); flowbits->ids = SnortAlloc(sizeof(*(flowbits->ids))); flowbits->num_ids = 1; flowbits->ids[0] = flowbits_item->id; } free(flowbits_name); } void validateFlowbitsSyntax(FLOWBITS_OP *flowbits) { switch (flowbits->type) { case FLOWBITS_SET: if ((flowbits->eval == FLOWBITS_AND) && (flowbits->ids)) break; ParseError("Flowbits: operation set uses syntax: flowbits:set,bit[&bit],[group]."); break; case FLOWBITS_SETX: if ((flowbits->eval == FLOWBITS_AND)&&(flowbits->group) && (flowbits->ids) ) break; ParseError("Flowbits: operation setx uses syntax: flowbits:setx,bit[&bit],group."); break; case FLOWBITS_UNSET: if (((flowbits->eval == FLOWBITS_AND) && (!flowbits->group) && (flowbits->ids)) ||((flowbits->eval == FLOWBITS_ALL) && (flowbits->group))) break; ParseError("Flowbits: operation unset uses syntax: flowbits:unset,bit[&bit] OR" " flowbits:unset, all, group."); break; case FLOWBITS_TOGGLE: if (((flowbits->eval == FLOWBITS_AND) && (!flowbits->group) &&(flowbits->ids)) ||((flowbits->eval == FLOWBITS_ALL) && (flowbits->group))) break; ParseError("Flowbits: operation toggle uses syntax: flowbits:toggle,bit[&bit] OR" " flowbits:toggle,all,group."); break; case FLOWBITS_ISSET: if ((((flowbits->eval == FLOWBITS_AND) || (flowbits->eval == FLOWBITS_OR)) && (!flowbits->group) && flowbits->ids) ||((((flowbits->eval == FLOWBITS_ANY))||(flowbits->eval == FLOWBITS_ALL)) && (flowbits->group))) break; ParseError("Flowbits: operation isset uses syntax: flowbits:isset,bit[&bit] OR " "flowbits:isset,bit[|bit] OR flowbits:isset,all,group OR flowbits:isset,any,group."); break; case FLOWBITS_ISNOTSET: if ((((flowbits->eval == FLOWBITS_AND) || (flowbits->eval == FLOWBITS_OR)) && (!flowbits->group) && flowbits->ids) ||((((flowbits->eval == FLOWBITS_ANY))||(flowbits->eval == FLOWBITS_ALL)) && (flowbits->group))) break; ParseError("Flowbits: operation isnotset uses syntax: flowbits:isnotset,bit[&bit] OR " "flowbits:isnotset,bit[|bit] OR flowbits:isnotset,all,group OR flowbits:isnotset,any,group."); break; case FLOWBITS_RESET: if (flowbits->ids == NULL) break; ParseError("Flowbits: operation unset uses syntax: flowbits:reset OR flowbits:reset, group." ); break; case FLOWBITS_NOALERT: if ((flowbits->ids == NULL) && (flowbits->group == NULL)) break; ParseError("Flowbits: operation noalert uses syntax: flowbits:noalert." ); break; default: ParseError("Flowbits: unknown operator.\n" , file_name, file_line); break; } } void processFlowBitsWithGroup(char *flowbitsName, char *groupName, FLOWBITS_OP *flowbits) { FLOWBITS_GRP *flowbits_grp; if (!flowbits_hash) FlowBitsHashInit(); if ((groupName)&& (!flowbits_grp_hash)) FlowBitsGrpHashInit(); flowbits_grp = getFlowBitGroup(groupName); processFlowbits(flowbitsName,flowbits_grp, flowbits); if (groupName && !(flowbits->group)) { flowbits->group = SnortStrdup(groupName); flowbits->group_id = flowbits_grp->group_id; } validateFlowbitsSyntax(flowbits); DEBUG_WRAP( printOutFlowbits(flowbits)); } /**************************************************************************** * * Function: FlowBitsParse(char *, FlowBits *flowbits, OptTreeNode *) * * Purpose: parse the arguments to the flow plugin and alter the otn * accordingly * * Arguments: otn => pointer to the current rule option list node * * Returns: void function * ****************************************************************************/ static void FlowBitsParse(struct _SnortConfig *sc, char *data, FLOWBITS_OP *flowbits, OptTreeNode *otn) { char **toks; int num_toks; char *typeName = NULL; char *groupName = NULL; char *flowbitsName = NULL; FLOWBITS_GRP *flowbits_grp; if (sc == NULL) { FatalError("%s(%d) Snort config for parsing is NULL.\n", __FILE__, __LINE__); } DEBUG_WRAP(DebugMessage(DEBUG_FLOWBITS, "flowbits parsing %s\n",data);); toks = mSplit(data, ",", 0, &num_toks, 0); if(num_toks < 1) { ParseError("ParseFlowArgs: Must specify flowbits operation."); } else if (num_toks > 3) { ParseError("ParseFlowArgs: Too many arguments."); } typeName = toks[0]; if(!strcasecmp("set",typeName)) { flowbits->type = FLOWBITS_SET; } else if(!strcasecmp("setx",typeName)) { flowbits->type = FLOWBITS_SETX; } else if(!strcasecmp("unset",typeName)) { flowbits->type = FLOWBITS_UNSET; } else if(!strcasecmp("toggle",typeName)) { flowbits->type = FLOWBITS_TOGGLE; } else if(!strcasecmp("isset",typeName)) { flowbits->type = FLOWBITS_ISSET; } else if(!strcasecmp("isnotset",typeName)) { flowbits->type = FLOWBITS_ISNOTSET; } else if(!strcasecmp("noalert", typeName)) { if(num_toks > 1) { ParseError("Flowbits: Do not specify a flowbits tag id for the keyword 'noalert'."); } flowbits->type = FLOWBITS_NOALERT; flowbits->ids = NULL; flowbits->num_ids = 0; flowbits->name = SnortStrdup(typeName); mSplitFree(&toks, num_toks); return; } else if(!strcasecmp("reset",typeName)) { if(num_toks > 2) { ParseError("Flowbits: Too many arguments for the keyword 'reset'."); } if (num_toks == 2) { /*Save the group name*/ groupName = SnortStrdup(toks[1]); flowbits_grp = getFlowBitGroup(groupName); flowbits->group = groupName; flowbits->group_id = flowbits_grp->group_id; } flowbits->type = FLOWBITS_RESET; flowbits->ids = NULL; flowbits->num_ids = 0; flowbits->name = SnortStrdup(typeName); mSplitFree(&toks, num_toks); return; } else { ParseError("Flowbits: Invalid token %s.", typeName); } flowbits->name = SnortStrdup(typeName); /* ** Let's parse the flowbits name */ if( num_toks < 2 ) { ParseError("Flowbit: flowbits tag id must be provided.", file_name, file_line); } flowbitsName = toks[1]; if(num_toks == 3) { groupName = toks[2]; } processFlowBitsWithGroup(flowbitsName, groupName, flowbits); mSplitFree(&toks, num_toks); } static inline int boUnSetGrpBit(BITOP *BitOp, char *group) { FLOWBITS_GRP *flowbits_grp; BITOP *GrpBitOp; unsigned int i, max_bytes; if( group == NULL ) return 0; flowbits_grp = (FLOWBITS_GRP *)sfghash_find(flowbits_grp_hash, group); if( flowbits_grp == NULL ) return 0; if((BitOp == NULL) || (BitOp->uiMaxBits <= flowbits_grp->max_id) || flowbits_grp->count == 0) return 0; GrpBitOp = &(flowbits_grp->GrpBitOp); /* note, max_id is an index, not a count. * Calculate max_bytes by adding 8 to max_id, then dividing by 8. */ max_bytes = (flowbits_grp->max_id + 8) >> 3; for ( i = 0; i < max_bytes; i++ ) { BitOp->pucBitBuffer[i] &= ~GrpBitOp->pucBitBuffer[i]; } return 1; } static inline int boToggleGrpBit(BITOP *BitOp, char *group) { FLOWBITS_GRP *flowbits_grp; BITOP *GrpBitOp; unsigned int i, max_bytes; if( group == NULL ) return 0; flowbits_grp = (FLOWBITS_GRP *)sfghash_find(flowbits_grp_hash, group); if( flowbits_grp == NULL ) return 0; if((BitOp == NULL) || (BitOp->uiMaxBits <= flowbits_grp->max_id) || flowbits_grp->count == 0) return 0; GrpBitOp = &(flowbits_grp->GrpBitOp); /* note, max_id is an index, not a count. * Calculate max_bytes by adding 8 to max_id, then dividing by 8. */ max_bytes = (flowbits_grp->max_id + 8) >> 3; for ( i = 0; i < max_bytes; i++ ) { BitOp->pucBitBuffer[i] ^= GrpBitOp->pucBitBuffer[i]; } return 1; } static inline int boSetxBitsToGrp(BITOP *BitOp, uint16_t *ids, uint16_t num_ids, char *group) { unsigned int i; if (!boUnSetGrpBit(BitOp, group)) return 0; for(i = 0; i < num_ids; i++) boSetBit(BitOp,ids[i]); return 1; } static inline int issetFlowbits(StreamFlowData *flowdata, uint8_t eval, uint16_t *ids, uint16_t num_ids, char *group ) { unsigned int i; FLOWBITS_GRP *flowbits_grp; Flowbits_eval evalType = (Flowbits_eval)eval; switch (evalType) { case FLOWBITS_AND: for(i = 0; i < num_ids; i++) { if(!boIsBitSet(&(flowdata->boFlowbits), ids[i])) return 0; } return 1; break; case FLOWBITS_OR: for(i = 0; i < num_ids; i++) { if(boIsBitSet(&(flowdata->boFlowbits), ids[i])) return 1; } return 0; break; case FLOWBITS_ALL: flowbits_grp = (FLOWBITS_GRP *)sfghash_find(flowbits_grp_hash, group); if( flowbits_grp == NULL ) return 0; for ( i = 0; i <= (unsigned int)(flowbits_grp->max_id >>3) ; i++ ) { uint8_t val = flowdata->boFlowbits.pucBitBuffer[i] & flowbits_grp->GrpBitOp.pucBitBuffer[i]; if (val != flowbits_grp->GrpBitOp.pucBitBuffer[i]) return 0; } return 1; break; case FLOWBITS_ANY: flowbits_grp = (FLOWBITS_GRP *)sfghash_find(flowbits_grp_hash, group); if( flowbits_grp == NULL ) return 0; for ( i = 0; i <= (unsigned int)(flowbits_grp->max_id >>3) ; i++ ) { uint8_t val = flowdata->boFlowbits.pucBitBuffer[i] & flowbits_grp->GrpBitOp.pucBitBuffer[i]; if (val) return 1; } return 0; break; default: return 0; } } /**************************************************************************** * * Function: checkFlowBits * * Purpose: Check flow bits * * Arguments: Packet *p => packet data * uint8_t type, * uint8_t evalType, * uint16_t *ids, * uint16_t num_ids, * char *group * * Returns: 0 on failure * ****************************************************************************/ int checkFlowBits( uint8_t type, uint8_t evalType, uint16_t *ids, uint16_t num_ids, char *group, Packet *p) { int rval = DETECTION_OPTION_NO_MATCH; StreamFlowData *flowdata; Flowbits_eval eval = (Flowbits_eval) evalType; int result = 0; int i; /* Need session pointer to get flowbits */ if ((stream_api == NULL) || (p->ssnptr == NULL)) return rval; flowdata = session_api->get_flow_data(p); if(!flowdata) { DEBUG_WRAP(DebugMessage(DEBUG_FLOWBITS, "No FLOWBITS_DATA");); return rval; } switch(type) { case FLOWBITS_SET: for(i = 0; i < num_ids; i++) boSetBit(&(flowdata->boFlowbits),ids[i]); result = 1; break; case FLOWBITS_SETX: result = boSetxBitsToGrp(&(flowdata->boFlowbits), ids, num_ids, group); break; case FLOWBITS_UNSET: if (eval == FLOWBITS_ALL ) boUnSetGrpBit(&(flowdata->boFlowbits), group); else { for(i = 0; i < num_ids; i++) boClearBit(&(flowdata->boFlowbits),ids[i]); } result = 1; break; case FLOWBITS_RESET: if (!group) boResetBITOP(&(flowdata->boFlowbits)); else boUnSetGrpBit(&(flowdata->boFlowbits), group); result = 1; break; case FLOWBITS_ISSET: if(issetFlowbits(flowdata,(uint8_t)eval, ids, num_ids, group)) { result = 1; } else { rval = DETECTION_OPTION_FAILED_BIT; } break; case FLOWBITS_ISNOTSET: if(!issetFlowbits(flowdata, (uint8_t)eval, ids, num_ids, group)) { result = 1; } else { rval = DETECTION_OPTION_FAILED_BIT; } break; case FLOWBITS_TOGGLE: if (group) boToggleGrpBit(&(flowdata->boFlowbits),group); else { for(i = 0; i < num_ids; i++) { if (boIsBitSet(&(flowdata->boFlowbits),ids[i])) { boClearBit(&(flowdata->boFlowbits),ids[i]); } else { boSetBit(&(flowdata->boFlowbits),ids[i]); } } } result = 1; break; case FLOWBITS_NOALERT: /* ** This logic allows us to put flowbits: noalert any where ** in the detection chain, and still do bit ops after this ** option. */ return DETECTION_OPTION_NO_ALERT; default: /* ** Always return failure here. */ return rval; } /* ** Now return what we found */ if (result == 1) { rval = DETECTION_OPTION_MATCH; } return rval; } /**************************************************************************** * * Function: FlowBitsCheck(Packet *, struct _OptTreeNode *, OptFpList *) * * Purpose: Check flow bits foo * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: 0 on failure * ****************************************************************************/ int FlowBitsCheck(void *option_data, Packet *p) { FLOWBITS_OP *flowbits = (FLOWBITS_OP*)option_data; int rval = DETECTION_OPTION_NO_MATCH; PROFILE_VARS; if (!flowbits) return rval; PREPROC_PROFILE_START(flowBitsPerfStats); rval = checkFlowBits( flowbits->type, (uint8_t)flowbits->eval, flowbits->ids, flowbits->num_ids, flowbits->group, p); PREPROC_PROFILE_END(flowBitsPerfStats); return rval; } /**************************************************************************** * * Function: FlowBitsVerify() * * Purpose: Check flow bits foo to make sure its valid * * Arguments: * * Returns: 0 on failure * ****************************************************************************/ void FlowBitsVerify(void) { SFGHASH_NODE * n; FLOWBITS_OBJECT *fb; int num_flowbits = 0; if (flowbits_hash == NULL) return; for (n = sfghash_findfirst(flowbits_hash); n != NULL; n= sfghash_findnext(flowbits_hash)) { fb = (FLOWBITS_OBJECT *)n->data; if (fb->toggle != flowbits_toggle) { if (sfqueue_add(flowbits_bit_queue, (NODE_DATA)(uintptr_t)fb->id) == -1) { FatalError("%s(%d) Failed to add flow bit id to queue.\n", __FILE__, __LINE__); } sfghash_remove(flowbits_hash, n->key); continue; } if ((fb->set > 0) && (fb->isset == 0)) { LogMessage("WARNING: flowbits key '%s' is set but not ever checked.\n", (char*)n->key); } else if ((fb->isset > 0) && (fb->set == 0)) { LogMessage("WARNING: flowbits key '%s' is checked but not ever set.\n", (char*)n->key); } else if ((fb->set == 0) && (fb->isset == 0)) { continue; /* don't count this bit as used */ } num_flowbits++; } flowbits_toggle ^= 1; LogMessage("%d out of %d flowbits in use.\n", num_flowbits, giFlowbitSize); } static void FlowBitsCleanExit(int signal, void *data) { if (flowbits_hash != NULL) { sfghash_delete(flowbits_hash); flowbits_hash = NULL; } if (flowbits_grp_hash != NULL) { sfghash_delete(flowbits_grp_hash); flowbits_grp_hash = NULL; } if (flowbits_bit_queue != NULL) { sfqueue_free_all(flowbits_bit_queue, NULL); flowbits_bit_queue = NULL; } } void setFlowbitSize(char *args) { char *endptr; long int size; size = SnortStrtol(args, &endptr, 0); if ((errno == ERANGE) || (*endptr != '\0') || (size < 0) || (size > MAX_FLOWBIT_SIZE)) { ParseError("Invalid argument to 'flowbits_size': %s. Must be a " "positive integer and less than %d.", args, MAX_FLOWBIT_SIZE); } giFlowbitSize = size; giFlowbitSizeInBytes = CONVERT_BITS_TO_BYTES(giFlowbitSize); } unsigned int getFlowbitSize(void) { return giFlowbitSize; } unsigned int getFlowbitSizeInBytes(void) { return giFlowbitSizeInBytes; } void FlowbitResetCounts(void) { SFGHASH_NODE *n; FLOWBITS_OBJECT *fb; if (flowbits_hash == NULL) return; for (n = sfghash_findfirst(flowbits_hash); n != NULL; n = sfghash_findnext(flowbits_hash)) { fb = (FLOWBITS_OBJECT *)n->data; fb->set = 0; fb->isset = 0; } } snort-2.9.15.1/src/detection-plugins/sp_flowbits.h0000644000175200017520000000714313571422607017005 00000000000000/* $Id$ */ /**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2004-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* flowbits detection plugin header */ #ifndef __SP_FLOWBITS_H__ #define __SP_FLOWBITS_H__ #include "sfghash.h" #include "sf_types.h" #include "decode.h" #include "bitop_funcs.h" #include "snort_debug.h" /* Normally exported functions, for plugin registration. */ void SetupFlowBits(void); void FlowBitsVerify(void); void FlowBitsFree(void *d); uint32_t FlowBitsHash(void *d); int FlowBitsCompare(void *l, void *r); int FlowBitsCheck(void *, Packet *); void FlowBitsHashInit(void); void FlowbitResetCounts(void); /** ** The FLOWBITS_OBJECT is used to track the different ** flowbit names that set/unset/etc. bits. We use these ** so that we can verify that the rules that use flowbits ** make sense. ** ** The types element tracks all the different operations that ** may occur for a given object. This is different from how ** the type element is used from the FLOWBITS_ITEM structure. */ typedef struct _FLOWBITS_OBJECT { uint16_t id; uint8_t types; int toggle; int set; int isset; } FLOWBITS_OBJECT; typedef enum { FLOWBITS_AND, FLOWBITS_OR, FLOWBITS_ANY, FLOWBITS_ALL }Flowbits_eval; /** ** This structure is the context ptr for each detection option ** on a rule. The id is associated with a FLOWBITS_OBJECT id. ** ** The type element track only one operation. */ typedef struct _FLOWBITS_OP { uint16_t *ids; uint8_t num_ids; uint8_t type; /* Set, Unset, Invert, IsSet, IsNotSet, Reset */ Flowbits_eval eval; /* and , or, all, any*/ char *name; char *group; uint32_t group_id; } FLOWBITS_OP; typedef struct _FLOWBITS_GRP { uint16_t count; uint16_t max_id; char *name; uint32_t group_id; BITOP GrpBitOp; } FLOWBITS_GRP; #define FLOWBITS_SET 0x01 #define FLOWBITS_UNSET 0x02 #define FLOWBITS_TOGGLE 0x04 #define FLOWBITS_ISSET 0x08 #define FLOWBITS_ISNOTSET 0x10 #define FLOWBITS_RESET 0x20 #define FLOWBITS_NOALERT 0x40 #define FLOWBITS_SETX 0x80 void processFlowBitsWithGroup(char *flowbitsName, char *groupName, FLOWBITS_OP *flowbits); int checkFlowBits( uint8_t type, uint8_t evalType, uint16_t *ids, uint16_t num_ids, char *group, Packet *p); static inline int FlowBits_SetOperation(void *option_data) { FLOWBITS_OP *flowbits = (FLOWBITS_OP*)option_data; if (flowbits->type & (FLOWBITS_SET | FLOWBITS_SETX |FLOWBITS_UNSET | FLOWBITS_TOGGLE | FLOWBITS_RESET)) { return 1; } return 0; } void setFlowbitSize(char *); unsigned int getFlowbitSize(void); unsigned int getFlowbitSizeInBytes(void); #endif /* __SP_FLOWBITS_H__ */ snort-2.9.15.1/src/detection-plugins/sp_ftpbounce.c0000644000175200017520000002236513571422607017137 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2005-2013 Sourcefire, Inc. ** Author: Steven Sturges ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* sp_ftpbounce * * Purpose: * Checks the address listed (a,b,c,d format) in the packet * against the source address. * * does not update the doe_ptr * * Arguments: * Required: * None * Optional: * None * * sample rules: * alert tcp any any -> any 21 (content: "PORT"; \ * ftpbounce; * msg: "FTP Bounce attack";) * * Effect: * * Returns 1 if the address matches, 0 if it doesn't. * * Comments: * * Any comments? * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifdef HAVE_STRINGS_H #include #endif #include #include "sf_types.h" #include "snort_bounds.h" #include "rules.h" #include "treenodes.h" #include "decode.h" #include "plugbase.h" #include "parser.h" #include "snort_debug.h" #include "util.h" #include "plugin_enum.h" #include "mstring.h" #include "snort.h" #include "profiler.h" #ifdef PERF_PROFILING PreprocStats ftpBouncePerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif #include "sfhashfcn.h" #include "detection_options.h" #include "detection_util.h" void FTPBounceInit(struct _SnortConfig *, char *, OptTreeNode *, int); void FTPBounceParse(char *, OptTreeNode *); int FTPBounce(void *option_data, Packet *p); uint32_t FTPBounceHash(void *d) { uint32_t a,b,c; /* NO data stored for the option */ a = RULE_OPTION_TYPE_FTPBOUNCE; b = 0; c = 0; final(a,b,c); return c; } int FTPBounceCompare(void *l, void *r) { /* NO data stored for the option */ return DETECTION_OPTION_EQUAL; } /**************************************************************************** * * Function: SetupFTPBounce() * * Purpose: Load 'er up * * Arguments: None. * * Returns: void function * ****************************************************************************/ void SetupFTPBounce(void) { /* map the keyword to an initialization/processing function */ RegisterRuleOption("ftpbounce", FTPBounceInit, NULL, OPT_TYPE_DETECTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("ftpbounce", &ftpBouncePerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: FTPBounce Setup\n");); } /**************************************************************************** * * Function: FTPBounceInit(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: Generic rule configuration function. Handles parsing the rule * information and attaching the associated detection function to * the OTN. * * Arguments: data => rule arguments/data * otn => pointer to the current rule option list node * protocol => protocol the rule is on (we don't care in this case) * * Returns: void function * ****************************************************************************/ void FTPBounceInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { OptFpList *fpl; void *ds_ptr_dup; /* this is where the keyword arguments are processed and placed into the rule option's data structure */ FTPBounceParse(data, otn); fpl = AddOptFuncToList(FTPBounce, otn); fpl->type = RULE_OPTION_TYPE_FTPBOUNCE; /* attach it to the context node so that we can call each instance * individually */ fpl->context = (void *) NULL; if (add_detection_option(sc, RULE_OPTION_TYPE_FTPBOUNCE, (void *)NULL, &ds_ptr_dup) == DETECTION_OPTION_EQUAL) { //otn->ds_list[PLUGIN_FTPBOUNCE] = ds_ptr_dup; } } /**************************************************************************** * * Function: FTPBounceParse(char *, void *, OptTreeNode *) * * Purpose: This is the function that is used to process the option keyword's * arguments and attach them to the rule's data structures. * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ void FTPBounceParse(char *data, OptTreeNode *otn) { if (data != NULL) { FatalError("%s (%d): Bad arguments to ftpbounce: %s\n", file_name, file_line, data); } } /**************************************************************************** * * Function: FTPBounce(char *, OptTreeNode *, OptFpList *) * * Purpose: Use this function to perform the particular detection routine * that this rule keyword is supposed to encompass. * * Arguments: p => pointer to the decoded packet * otn => pointer to the current rule's OTN * fp_list => pointer to the function pointer list * * Returns: If the detection test fails, this function *must* return a zero! * On success, it calls the next function in the detection list * ****************************************************************************/ int FTPBounce(void *option_data, Packet *p) { uint32_t ip = 0; int octet=0; const uint8_t *this_param = doe_ptr; int dsize; const uint8_t *end_ptr, *start_ptr; PROFILE_VARS; if (!doe_ptr) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "[*] ftpbounce no doe_ptr set..\n");); return 0; } PREPROC_PROFILE_START(ftpBouncePerfStats); if (Is_DetectFlag(FLAG_ALT_DETECT)) { dsize = DetectBuffer.len; start_ptr = DetectBuffer.data; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Using Alternative Detect buffer!\n");); } else if(Is_DetectFlag(FLAG_ALT_DECODE)) { dsize = DecodeBuffer.len; start_ptr = DecodeBuffer.data; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Using Alternative Decode buffer!\n");); } else { start_ptr = p->data; if(IsLimitedDetect(p)) dsize = p->alt_dsize; else dsize = p->dsize; } DEBUG_WRAP( DebugMessage(DEBUG_PATTERN_MATCH,"[*] ftpbounce firing...\n"); DebugMessage(DEBUG_PATTERN_MATCH,"payload starts at %p\n", start_ptr); ); /* END DEBUG_WRAP */ /* save off whatever our ending pointer is */ end_ptr = start_ptr + dsize; if(doe_ptr) { /* @todo: possibly degrade to use the other buffer, seems non-intuitive*/ if(!inBounds(start_ptr, end_ptr, doe_ptr)) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "[*] ftpbounce bounds check failed..\n");); PREPROC_PROFILE_END(ftpBouncePerfStats); return DETECTION_OPTION_NO_MATCH; } } while ((this_param < end_ptr) && isspace((int)*this_param)) this_param++; do { int value = 0; do { if (!isdigit((int)*this_param)) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "[*] ftpbounce non digit char failed..\n");); PREPROC_PROFILE_END(ftpBouncePerfStats); return DETECTION_OPTION_NO_MATCH; } value = value * 10 + (*this_param - '0'); this_param++; } while ((this_param < end_ptr) && (*this_param != ',') && (!(isspace((int)*this_param)))); if (value > 0xFF) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "[*] ftpbounce value > 256 ..\n");); PREPROC_PROFILE_END(ftpBouncePerfStats); return DETECTION_OPTION_NO_MATCH; } if (octet < 4) { ip = (ip << 8) + value; } if ((this_param < end_ptr) && !isspace((int)*this_param)) this_param++; octet++; } while ((this_param < end_ptr) && !isspace((int)*this_param) && (octet < 4)); if (octet < 4) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "[*] ftpbounce insufficient data ..\n");); PREPROC_PROFILE_END(ftpBouncePerfStats); return DETECTION_OPTION_NO_MATCH; } if ( ip != ntohl(sfaddr_get_ip4_value(GET_SRC_IP(p))) ) { PREPROC_PROFILE_END(ftpBouncePerfStats); return DETECTION_OPTION_MATCH; } DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "PORT command not being used in bounce\n");); PREPROC_PROFILE_END(ftpBouncePerfStats); return DETECTION_OPTION_NO_MATCH; } snort-2.9.15.1/src/detection-plugins/sp_ftpbounce.h0000644000175200017520000000220613571422607017134 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2005-2013 Sourcefire, Inc. ** Author: Steven Sturges ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifndef __SP_FTP_BOUNCE_H__ #define __SP_FTP_BOUNCE_H__ void SetupFTPBounce(void); uint32_t FTPBounceHash(void *d); int FTPBounceCompare(void *l, void *r); #endif /* __SP_FTP_BOUNCE_H__ */ snort-2.9.15.1/src/detection-plugins/sp_hdr_opt_wrap.c0000644000175200017520000000451413571422607017636 00000000000000/**************************************************************************** * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2008-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* Necessary hash/wrapper functions to put a .so rule's HdrOptCheck option * directly on the rule option tree. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sp_hdr_opt_wrap.h" #include "sf_engine/sf_snort_plugin_api.h" //extern int checkHdrOpt(void *p, HdrOptCheck *optData); uint32_t HdrOptCheckHash(void *d) { uint32_t a, b, c; HdrOptCheck *hdrData = (HdrOptCheck *)d; a = (uint32_t)hdrData->hdrField; b = hdrData->op; c = hdrData->value; mix(a,b,c); a += hdrData->mask_value; b += hdrData->flags; final(a,b,c); return c; } int HdrOptCheckCompare(void *l, void *r) { HdrOptCheck *left = (HdrOptCheck *)l; HdrOptCheck *right = (HdrOptCheck *)r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if ((left->hdrField == right->hdrField) && (left->op == right->op) && (left->value == right->value) && (left->mask_value == right->mask_value) && (left->flags == right->flags)) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } /* This function is a wrapper to call the check function normally used in * .so rules */ int HdrOptEval(void *option_data, Packet *p) { HdrOptCheck *hdrData = (HdrOptCheck *)option_data; return checkHdrOpt(p, hdrData); } snort-2.9.15.1/src/detection-plugins/sp_hdr_opt_wrap.h0000644000175200017520000000272213571422607017642 00000000000000/**************************************************************************** * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2008-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* Necessary hash/wrapper functions to put a .so rule's HdrOptCheck option * directly on the rule option tree. */ #ifndef __SP_HDR_OPT_WRAP_H__ #define __SP_HDR_OPT_WRAP_H__ #include "sf_engine/sf_snort_plugin_api.h" #include "sfhashfcn.h" #include "detection_options.h" uint32_t HdrOptCheckHash(void *d); int HdrOptCheckCompare(void *l, void *r); int HdrOptEval(void *option_data, Packet *p); #endif /* __SP_HDR_OPT_WRAP_H__ */ snort-2.9.15.1/src/detection-plugins/sp_icmp_code_check.c0000644000175200017520000002657613571422607020241 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "sf_types.h" #include "rules.h" #include "treenodes.h" #include "decode.h" #include "plugbase.h" #include "parser.h" #include "util.h" #include "snort_debug.h" #include "plugin_enum.h" #include "sfhashfcn.h" #include "snort.h" #include "profiler.h" #ifdef PERF_PROFILING PreprocStats icmpCodePerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif #include "sfhashfcn.h" #include "detection_options.h" typedef struct _IcmpCodeCheckData { /* the icmp code number */ int icmp_code; int icmp_code2; uint8_t operator; } IcmpCodeCheckData; #define ICMP_CODE_TEST_EQ 1 #define ICMP_CODE_TEST_GT 2 #define ICMP_CODE_TEST_LT 3 #define ICMP_CODE_TEST_RG 4 void IcmpCodeCheckInit(struct _SnortConfig *, char *, OptTreeNode *, int); void ParseIcmpCode(struct _SnortConfig *, char *, OptTreeNode *); int IcmpCodeCheck(void *option_data, Packet *); uint32_t IcmpCodeCheckHash(void *d) { uint32_t a,b,c; IcmpCodeCheckData *data = (IcmpCodeCheckData *)d; a = data->icmp_code; b = data->icmp_code2; c = data->operator; mix(a,b,c); a += RULE_OPTION_TYPE_ICMP_CODE; final(a,b,c); return c; } int IcmpCodeCheckCompare(void *l, void *r) { IcmpCodeCheckData *left = (IcmpCodeCheckData *)l; IcmpCodeCheckData *right = (IcmpCodeCheckData *)r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if ((left->icmp_code == right->icmp_code) && (left->icmp_code2 == right->icmp_code2) && (left->operator == right->operator)) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } /**************************************************************************** * * Function: SetupIcmpCodeCheck() * * Purpose: Register the icode keyword and configuration function * * Arguments: None. * * Returns: void function * ****************************************************************************/ void SetupIcmpCodeCheck(void) { /* map the keyword to an initialization/processing function */ RegisterRuleOption("icode", IcmpCodeCheckInit, NULL, OPT_TYPE_DETECTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("icode", &icmpCodePerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Plugin: IcmpCodeCheck Initialized\n");); } /**************************************************************************** * * Function: IcmpCodeCheckInit(char *, OptTreeNode *) * * Purpose: Initialize the rule data structs and parse the rule argument * data, then link in the detection function * * Arguments: data => rule arguments/data * otn => pointer to the current rule option list node * * Returns: void function * ****************************************************************************/ void IcmpCodeCheckInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { OptFpList *fpl; if(protocol != IPPROTO_ICMP) { FatalError( "%s(%d): ICMP Options on non-ICMP rule\n", file_name, file_line); } /* multiple declaration check */ if(otn->ds_list[PLUGIN_ICMP_CODE]) { FatalError("%s(%d): Multiple icmp code options in rule\n", file_name, file_line); } /* allocate the data structure and attach it to the rule's data struct list */ otn->ds_list[PLUGIN_ICMP_CODE] = (IcmpCodeCheckData *) SnortAlloc(sizeof(IcmpCodeCheckData)); /* this is where the keyword arguments are processed and placed into the rule option's data structure */ ParseIcmpCode(sc, data, otn); /* finally, attach the option's detection function to the rule's detect function pointer list */ fpl = AddOptFuncToList(IcmpCodeCheck, otn); fpl->type = RULE_OPTION_TYPE_ICMP_CODE; fpl->context = otn->ds_list[PLUGIN_ICMP_CODE]; } /**************************************************************************** * * Function: ParseIcmpCode(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: Process the icode argument and stick it in the data struct * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ void ParseIcmpCode(struct _SnortConfig *sc, char *data, OptTreeNode *otn) { char *code; IcmpCodeCheckData *ds_ptr; /* data struct pointer */ void *ds_ptr_dup; char *endptr = NULL; /* set the ds pointer to make it easier to reference the option's particular data struct */ ds_ptr = otn->ds_list[PLUGIN_ICMP_CODE]; /* set a pointer to the data so to leave the original unchanged */ code = data; if(!data) { FatalError("%s (%d): No ICMP Code Specified\n", file_name, file_line); } /* get rid of whitespace before the data */ while(isspace((int)*data)) data++; if (*data == '\0') { FatalError("%s (%d): No ICMP Code Specified\n", file_name, file_line); } /* * If a range is specified, put the min in icmp_code, and the max in * icmp_code2 */ if ((isdigit((int)*data) || (*data == '-') || (*data == '+')) && strstr(data, "<>")) { ds_ptr->icmp_code = strtol(data, &endptr, 10); while (isspace((int)*endptr)) endptr++; if (*endptr != '<') { FatalError("%s (%d): Invalid ICMP icode in rule: %s\n", file_name, file_line, code); } data = endptr; data += 2; /* move past <> */ while (isspace((int)*data)) data++; ds_ptr->icmp_code2 = strtol(data, &endptr, 10); if (*data == '\0' || *endptr != '\0') { FatalError("%s (%d): Invalid ICMP icode in rule: %s\n", file_name, file_line, code); } if( (ds_ptr->icmp_code < -1) || (ds_ptr->icmp_code > 254) ) FatalError("%s (%d): Invalid ICMP icode lower limit in rule: %d\n", file_name, file_line, ds_ptr->icmp_code); if( (ds_ptr->icmp_code2 <= 0) || (ds_ptr->icmp_code2 > 256) ) FatalError("%s (%d): Invalid ICMP icode upper limit in rule: %d\n", file_name, file_line, ds_ptr->icmp_code2); if( (ds_ptr->icmp_code2 - ds_ptr->icmp_code) <= 1 ) FatalError("%s (%d): Invalid ICMP icode (upper-lower) <= 1 in rule: %s\n", file_name, file_line, code); ds_ptr->operator = ICMP_CODE_TEST_RG; } /* otherwise if its greater than... */ else if (*data == '>') { data++; while (isspace((int)*data)) data++; ds_ptr->icmp_code = strtol(data, &endptr, 10); if (*data == '\0' || *endptr != '\0') { FatalError("%s (%d): Invalid ICMP icode in rule: %s\n", file_name, file_line, code); } if( (ds_ptr->icmp_code < 0) || (ds_ptr->icmp_code > 254) ) FatalError("%s (%d): Invalid ICMP icode lower limit in rule: %d\n", file_name, file_line, ds_ptr->icmp_code); ds_ptr->operator = ICMP_CODE_TEST_GT; } /* otherwise if its less than ... */ else if (*data == '<') { data++; while (isspace((int)*data)) data++; ds_ptr->icmp_code = strtol(data, &endptr, 10); if (*data == '\0' || *endptr != '\0') { FatalError("%s (%d): Invalid ICMP icode in rule: %s\n", file_name, file_line, code); } if( (ds_ptr->icmp_code <= 0) || (ds_ptr->icmp_code > 256) ) FatalError("%s (%d): Invalid ICMP icode upper limit in rule: %d\n", file_name, file_line, ds_ptr->icmp_code); ds_ptr->operator = ICMP_CODE_TEST_LT; } /* otherwise check if its a digit */ else { ds_ptr->icmp_code = strtol(data, &endptr, 10); if (*endptr != '\0') { FatalError("%s (%d): Invalid ICMP icode in rule: %s\n", file_name, file_line, code); } if( (ds_ptr->icmp_code < 0) || (ds_ptr->icmp_code > 255) ) FatalError("%s (%d): Invalid ICMP icode upper limit in rule: %d\n", file_name, file_line, ds_ptr->icmp_code); ds_ptr->operator = ICMP_CODE_TEST_EQ; } if (add_detection_option(sc, RULE_OPTION_TYPE_ICMP_CODE, (void *)ds_ptr, &ds_ptr_dup) == DETECTION_OPTION_EQUAL) { otn->ds_list[PLUGIN_ICMP_CODE] = ds_ptr_dup; free(ds_ptr); } return; } /**************************************************************************** * * Function: IcmpCodeCheck(Packet *p, OptTreeNode *, OptFpList *fp_list) * * Purpose: Test the packet's ICMP code field value against the option's * ICMP code * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ int IcmpCodeCheck(void *option_data, Packet *p) { IcmpCodeCheckData *ds_ptr; int rval = DETECTION_OPTION_NO_MATCH; PROFILE_VARS; ds_ptr = (IcmpCodeCheckData *)option_data; /* return 0 if we don't have an icmp header */ if(!p->icmph) return rval; PREPROC_PROFILE_START(icmpCodePerfStats); switch(ds_ptr->operator) { case ICMP_CODE_TEST_EQ: if (ds_ptr->icmp_code == p->icmph->code) rval = DETECTION_OPTION_MATCH; break; case ICMP_CODE_TEST_GT: if (p->icmph->code > ds_ptr->icmp_code) rval = DETECTION_OPTION_MATCH; break; case ICMP_CODE_TEST_LT: if (p->icmph->code < ds_ptr->icmp_code) rval = DETECTION_OPTION_MATCH; break; case ICMP_CODE_TEST_RG: if (p->icmph->code > ds_ptr->icmp_code && p->icmph->code < ds_ptr->icmp_code2) rval = DETECTION_OPTION_MATCH; break; default: break; } DEBUG_WRAP( if (rval == DETECTION_OPTION_MATCH) { DebugMessage(DEBUG_PLUGIN, "Got icmp code match!\n"); } else { DebugMessage(DEBUG_PLUGIN, "Failed icmp code match!\n"); } ); PREPROC_PROFILE_END(icmpCodePerfStats); return rval; } snort-2.9.15.1/src/detection-plugins/sp_icmp_code_check.h0000644000175200017520000000225513571422607020232 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifndef __SP_ICMP_CODE_CHECK_H__ #define __SP_ICMP_CODE_CHECK_H__ void SetupIcmpCodeCheck(void); uint32_t IcmpCodeCheckHash(void *d); int IcmpCodeCheckCompare(void *l, void *r); #endif /* __SP_ICMP_CODE_CHECK_H__ */ snort-2.9.15.1/src/detection-plugins/sp_icmp_id_check.c0000644000175200017520000002004313571422607017702 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ /* sp_icmp_id * * Purpose: * * Test the ID field of ICMP ECHO and ECHO_REPLY packets for specified * values. This is useful for detecting TFN attacks, amongst others. * * Arguments: * * The ICMP ID plugin takes a number as an option argument. * * Effect: * * Tests ICMP ECHO and ECHO_REPLY packet ID field values and returns a * "positive" detection result (i.e. passthrough) upon a value match. * * Comments: * * This plugin was developed to detect TFN distributed attacks. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "sf_types.h" #include "rules.h" #include "treenodes.h" #include "decode.h" #include "plugbase.h" #include "parser.h" #include "snort_debug.h" #include "util.h" #include "plugin_enum.h" #include "snort.h" #include "profiler.h" #ifdef PERF_PROFILING PreprocStats icmpIdPerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif #include "sfhashfcn.h" #include "detection_options.h" typedef struct _IcmpIdCheckData { u_short icmpid; } IcmpIdCheckData; void ParseIcmpId(struct _SnortConfig *, char *, OptTreeNode *); int IcmpIdCheck(void *option_data, Packet *); void IcmpIdCheckInit(struct _SnortConfig *, char *, OptTreeNode *, int); uint32_t IcmpIdCheckHash(void *d) { uint32_t a,b,c; IcmpIdCheckData *data = (IcmpIdCheckData *)d; a = data->icmpid; b = RULE_OPTION_TYPE_ICMP_ID; c = 0; final(a,b,c); return c; } int IcmpIdCheckCompare(void *l, void *r) { IcmpIdCheckData *left = (IcmpIdCheckData *)l; IcmpIdCheckData *right = (IcmpIdCheckData *)r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if (left->icmpid == right->icmpid) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } /**************************************************************************** * * Function: SetupIcmpIdCheck() * * Purpose: Registers the configuration function and links it to a rule * keyword. This is the function that gets called from InitPlugins * in plugbase.c. * * Arguments: None. * * Returns: void function * ****************************************************************************/ void SetupIcmpIdCheck(void) { /* map the keyword to an initialization/processing function */ RegisterRuleOption("icmp_id", IcmpIdCheckInit, NULL, OPT_TYPE_DETECTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("icmp_id", &icmpIdPerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: IcmpIdCheck Setup\n");); } /**************************************************************************** * * Function: IcmpIdCheckInit(char *, OptTreeNode *) * * Purpose: Handles parsing the rule information and attaching the associated * detection function to the OTN. * * Arguments: data => rule arguments/data * otn => pointer to the current rule option list node * * Returns: void function * ****************************************************************************/ void IcmpIdCheckInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { OptFpList *fpl; if(protocol != IPPROTO_ICMP) { FatalError("%s(%d): ICMP Options on non-ICMP rule\n", file_name, file_line); } /* multiple declaration check */ if(otn->ds_list[PLUGIN_ICMP_ID_CHECK]) { FatalError("%s(%d): Multiple icmp id options in rule\n", file_name, file_line); } /* allocate the data structure and attach it to the rule's data struct list */ otn->ds_list[PLUGIN_ICMP_ID_CHECK] = (IcmpIdCheckData *) SnortAlloc(sizeof(IcmpIdCheckData)); /* this is where the keyword arguments are processed and placed into the rule option's data structure */ ParseIcmpId(sc, data, otn); /* finally, attach the option's detection function to the rule's detect function pointer list */ fpl = AddOptFuncToList(IcmpIdCheck, otn); fpl->type = RULE_OPTION_TYPE_ICMP_ID; fpl->context = otn->ds_list[PLUGIN_ICMP_ID_CHECK]; } /**************************************************************************** * * Function: ParseIcmpId(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: Convert the rule option argument to program data. * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ void ParseIcmpId(struct _SnortConfig *sc, char *data, OptTreeNode *otn) { IcmpIdCheckData *ds_ptr; /* data struct pointer */ void *ds_ptr_dup; char *endTok; /* set the ds pointer to make it easier to reference the option's particular data struct */ ds_ptr = otn->ds_list[PLUGIN_ICMP_ID_CHECK]; /* advance past whitespace */ while(isspace((int)*data)) data++; ds_ptr->icmpid = (uint16_t)SnortStrtoulRange(data, &endTok, 10, 0, UINT16_MAX); if ((endTok == data) || (*endTok != '\0')) { FatalError("%s(%d) => Invalid parameter '%s' to icmp_id. " "Must be between 0 & 65535, inclusive\n", file_name, file_line, data); } ds_ptr->icmpid = htons(ds_ptr->icmpid); if (add_detection_option(sc, RULE_OPTION_TYPE_ICMP_ID, (void *)ds_ptr, &ds_ptr_dup) == DETECTION_OPTION_EQUAL) { free(ds_ptr); ds_ptr = otn->ds_list[PLUGIN_ICMP_ID_CHECK] = ds_ptr_dup; } DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Set ICMP ID test value to %d\n", ds_ptr->icmpid);); } /**************************************************************************** * * Function: IcmpIdCheck(char *, OptTreeNode *) * * Purpose: Compare the ICMP ID field to the rule value. * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: If the detection test fails, this function *must* return a zero! * On success, it calls the next function in the detection list * ****************************************************************************/ int IcmpIdCheck(void *option_data, Packet *p) { IcmpIdCheckData *icmpId = (IcmpIdCheckData *)option_data; PROFILE_VARS; if(!p->icmph) return DETECTION_OPTION_NO_MATCH; /* if error occured while icmp header * was processed, return 0 automagically. */ PREPROC_PROFILE_START(icmpIdPerfStats); if( (p->icmph->type == ICMP_ECHO || p->icmph->type == ICMP_ECHOREPLY) || (p->icmph->type == ICMP6_ECHO || p->icmph->type == ICMP6_REPLY) ) { /* test the rule ID value against the ICMP extension ID field */ if(icmpId->icmpid == p->icmph->s_icmp_id) { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "ICMP ID check success\n");); PREPROC_PROFILE_END(icmpIdPerfStats); return DETECTION_OPTION_MATCH; } else { /* you can put debug comments here or not */ DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "ICMP ID check failed\n");); } } PREPROC_PROFILE_END(icmpIdPerfStats); return DETECTION_OPTION_NO_MATCH; } snort-2.9.15.1/src/detection-plugins/sp_icmp_id_check.h0000644000175200017520000000227213571422607017713 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ /* ICMP ping ID field detection plugin */ #ifndef __SP_ICMP_ID_H__ #define __SP_ICMP_ID_H__ void SetupIcmpIdCheck(void); uint32_t IcmpIdCheckHash(void *d); int IcmpIdCheckCompare(void *l, void *r); #endif /* __SP_ICMP_ID_H__ */ snort-2.9.15.1/src/detection-plugins/sp_icmp_seq_check.c0000644000175200017520000002015413571422607020101 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ /* sp_icmp_seq_check * * Purpose: * * Test the Sequence number field of ICMP ECHO and ECHO_REPLY packets for * specified values. This is useful for detecting TFN attacks, amongst others. * * Arguments: * * The ICMP Seq plugin takes a number as an option argument. * * Effect: * * Tests ICMP ECHO and ECHO_REPLY packet Seq field values and returns a * "positive" detection result (i.e. passthrough) upon a value match. * * Comments: * * This plugin was developed to detect TFN distributed attacks. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "sf_types.h" #include "rules.h" #include "treenodes.h" #include "decode.h" #include "plugbase.h" #include "parser.h" #include "snort_debug.h" #include "util.h" #include "plugin_enum.h" #include "snort.h" #include "profiler.h" #ifdef PERF_PROFILING PreprocStats icmpSeqPerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif #include "sfhashfcn.h" #include "detection_options.h" typedef struct _IcmpSeqCheckData { unsigned short icmpseq; } IcmpSeqCheckData; void IcmpSeqCheckInit(struct _SnortConfig *, char *, OptTreeNode *, int); void ParseIcmpSeq(struct _SnortConfig *, char *, OptTreeNode *); int IcmpSeqCheck(void *option_data, Packet *p); uint32_t IcmpSeqCheckHash(void *d) { uint32_t a,b,c; IcmpSeqCheckData *data = (IcmpSeqCheckData *)d; a = data->icmpseq; b = RULE_OPTION_TYPE_ICMP_SEQ; c = 0; final(a,b,c); return c; } int IcmpSeqCheckCompare(void *l, void *r) { IcmpSeqCheckData *left = (IcmpSeqCheckData *)l; IcmpSeqCheckData *right = (IcmpSeqCheckData *)r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if (left->icmpseq == right->icmpseq) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } /**************************************************************************** * * Function: SetupIcmpSeqCheck() * * Purpose: Registers the configuration function and links it to a rule * keyword. This is the function that gets called from InitPlugins * in plugbase.c. * * Arguments: None. * * Returns: void function * ****************************************************************************/ void SetupIcmpSeqCheck(void) { /* map the keyword to an initialization/processing function */ RegisterRuleOption("icmp_seq", IcmpSeqCheckInit, NULL, OPT_TYPE_DETECTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("icmp_seq", &icmpSeqPerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Plugin: IcmpSeqCheck Setup\n");); } /**************************************************************************** * * Function: IcmpSeqCheckInit(char *, OptTreeNode *) * * Purpose: Handles parsing the rule information and attaching the associated * detection function to the OTN. * * Arguments: data => rule arguments/data * otn => pointer to the current rule option list node * * Returns: void function * ****************************************************************************/ void IcmpSeqCheckInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { OptFpList *fpl; if(protocol != IPPROTO_ICMP) { FatalError("%s(%d): ICMP Options on non-ICMP rule\n", file_name, file_line); } /* multiple declaration check */ if(otn->ds_list[PLUGIN_ICMP_SEQ_CHECK]) { FatalError("%s(%d): Multiple ICMP seq options in rule\n", file_name, file_line); } /* allocate the data structure and attach it to the rule's data struct list */ otn->ds_list[PLUGIN_ICMP_SEQ_CHECK] = (IcmpSeqCheckData *) SnortAlloc(sizeof(IcmpSeqCheckData)); /* this is where the keyword arguments are processed and placed into the rule option's data structure */ ParseIcmpSeq(sc, data, otn); /* finally, attach the option's detection function to the rule's detect function pointer list */ fpl = AddOptFuncToList(IcmpSeqCheck, otn); fpl->type = RULE_OPTION_TYPE_ICMP_SEQ; fpl->context = otn->ds_list[PLUGIN_ICMP_SEQ_CHECK]; } /**************************************************************************** * * Function: ParseIcmpSeq(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: Convert the rule option argument to program data. * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ void ParseIcmpSeq(struct _SnortConfig *sc, char *data, OptTreeNode *otn) { IcmpSeqCheckData *ds_ptr; /* data struct pointer */ void *ds_ptr_dup; char *endTok; /* set the ds pointer to make it easier to reference the option's particular data struct */ ds_ptr = otn->ds_list[PLUGIN_ICMP_SEQ_CHECK]; /* advance past whitespace */ while(isspace((int)*data)) data++; ds_ptr->icmpseq = (uint16_t)SnortStrtoulRange(data, &endTok, 10, 0, UINT16_MAX); if ((endTok == data) || (*endTok != '\0')) { FatalError("%s(%d) => Invalid parameter '%s' to icmp_seq. " "Must be between 0 & 65535, inclusive\n", file_name, file_line, data); } ds_ptr->icmpseq = htons(ds_ptr->icmpseq); if (add_detection_option(sc, RULE_OPTION_TYPE_ICMP_SEQ, (void *)ds_ptr, &ds_ptr_dup) == DETECTION_OPTION_EQUAL) { free(ds_ptr); ds_ptr = otn->ds_list[PLUGIN_ICMP_SEQ_CHECK] = ds_ptr_dup; } DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Set ICMP Seq test value to %d\n", ds_ptr->icmpseq);); } /**************************************************************************** * * Function: IcmpSeqCheck(char *, OptTreeNode *) * * Purpose: Compare the ICMP Sequence field to the rule value. * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: If the detection test fails, this function *must* return a zero! * On success, it calls the next function in the detection list * ****************************************************************************/ int IcmpSeqCheck(void *option_data, Packet *p) { IcmpSeqCheckData *icmpSeq = (IcmpSeqCheckData *)option_data; PROFILE_VARS; if(!p->icmph) return DETECTION_OPTION_NO_MATCH; /* if error occured while icmp header * was processed, return 0 automagically. */ PREPROC_PROFILE_START(icmpSeqPerfStats); if( (p->icmph->type == ICMP_ECHO || p->icmph->type == ICMP_ECHOREPLY) || (p->icmph->type == ICMP6_ECHO || p->icmph->type == ICMP6_REPLY) ) { /* test the rule ID value against the ICMP extension ID field */ if(icmpSeq->icmpseq == p->icmph->s_icmp_seq) { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "ICMP ID check success\n");); PREPROC_PROFILE_END(icmpSeqPerfStats); return DETECTION_OPTION_MATCH; } else { /* you can put debug comments here or not */ DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "ICMP ID check failed\n");); } } PREPROC_PROFILE_END(icmpSeqPerfStats); return DETECTION_OPTION_NO_MATCH; } snort-2.9.15.1/src/detection-plugins/sp_icmp_seq_check.h0000644000175200017520000000230113571422607020100 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ /* ICMP ping Seq field detection plugin */ #ifndef __SP_ICMP_SEQ_H__ #define __SP_ICMP_SEQ_H__ void SetupIcmpSeqCheck(void); uint32_t IcmpSeqCheckHash(void *d); int IcmpSeqCheckCompare(void *l, void *r); #endif /* __SP_ICMP_SEQ_H__ */ snort-2.9.15.1/src/detection-plugins/sp_icmp_type_check.c0000644000175200017520000002353213571422607020275 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "sf_types.h" #include "rules.h" #include "treenodes.h" #include "decode.h" #include "plugbase.h" #include "parser.h" #include "snort_debug.h" #include "util.h" #include "plugin_enum.h" #include "sp_icmp_type_check.h" #include "sfhashfcn.h" #include "snort.h" #include "profiler.h" #ifdef PERF_PROFILING PreprocStats icmpTypePerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif #include "sfhashfcn.h" #include "detection_options.h" void IcmpTypeCheckInit(struct _SnortConfig *, char *, OptTreeNode *, int); void ParseIcmpType(struct _SnortConfig *, char *, OptTreeNode *); int IcmpTypeCheck(void *option_data, Packet *p); uint32_t IcmpTypeCheckHash(void *d) { uint32_t a,b,c; IcmpTypeCheckData *data = (IcmpTypeCheckData *)d; a = data->icmp_type; b = data->icmp_type2; c = data->operator; mix(a,b,c); a += RULE_OPTION_TYPE_ICMP_TYPE; final(a,b,c); return c; } int IcmpTypeCheckCompare(void *l, void *r) { IcmpTypeCheckData *left = (IcmpTypeCheckData *)l; IcmpTypeCheckData *right = (IcmpTypeCheckData *)r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if ((left->icmp_type == right->icmp_type) && (left->icmp_type2 == right->icmp_type2) && (left->operator == right->operator)) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } /**************************************************************************** * * Function: SetupIcmpTypeCheck() * * Purpose: Register the itype keyword and configuration function * * Arguments: None. * * Returns: void function * ****************************************************************************/ void SetupIcmpTypeCheck(void) { /* map the keyword to an initialization/processing function */ RegisterRuleOption("itype", IcmpTypeCheckInit, NULL, OPT_TYPE_DETECTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("itype", &icmpTypePerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: IcmpTypeCheck Initialized\n");); } /**************************************************************************** * * Function: IcmpTypeCheckInit(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: Initialize the rule data structs and parse the rule argument * data, then link in the detection function * * Arguments: data => rule arguments/data * otn => pointer to the current rule option list node * * Returns: void function * ****************************************************************************/ void IcmpTypeCheckInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { OptFpList *fpl; if(protocol != IPPROTO_ICMP) { FatalError("%s(%d): ICMP Options on non-ICMP rule\n", file_name, file_line); } /* multiple declaration check */ if(otn->ds_list[PLUGIN_ICMP_TYPE]) { FatalError("%s(%d): Multiple ICMP type options in rule\n", file_name, file_line); } /* allocate the data structure and attach it to the rule's data struct list */ otn->ds_list[PLUGIN_ICMP_TYPE] = (IcmpTypeCheckData *) SnortAlloc(sizeof(IcmpTypeCheckData)); /* this is where the keyword arguments are processed and placed into the rule option's data structure */ ParseIcmpType(sc, data, otn); /* finally, attach the option's detection function to the rule's detect function pointer list */ fpl = AddOptFuncToList(IcmpTypeCheck, otn); fpl->type = RULE_OPTION_TYPE_ICMP_TYPE; fpl->context = otn->ds_list[PLUGIN_ICMP_TYPE]; } /**************************************************************************** * * Function: ParseIcmpType(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: Process the itype argument and stick it in the data struct * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ void ParseIcmpType(struct _SnortConfig *sc, char *data, OptTreeNode *otn) { char *type; IcmpTypeCheckData *ds_ptr; /* data struct pointer */ void *ds_ptr_dup; char *endptr = NULL; /* set the ds pointer to make it easier to reference the option's particular data struct */ ds_ptr = otn->ds_list[PLUGIN_ICMP_TYPE]; /* set a pointer to the data so to leave the original unchanged */ type = data; if(!data) { FatalError("%s (%d): No ICMP Type Specified\n", file_name, file_line); } /* get rid of spaces before the data */ while(isspace((int)*data)) data++; if (*data == '\0') { FatalError("%s (%d): No ICMP Type Specified : %s\n", file_name, file_line, type); } /* * if a range is specified, put the min in icmp_type, and the max in * icmp_type2 */ if (isdigit((int)*data) && strstr(data, "<>")) { ds_ptr->icmp_type = strtol(data, &endptr, 10); while (isspace((int)*endptr)) endptr++; if (*endptr != '<') { FatalError("%s (%d): Invalid ICMP itype in rule: %s\n", file_name, file_line, type); } data = endptr; data += 2; /* move past <> */ while (isspace((int)*data)) data++; ds_ptr->icmp_type2 = strtol(data, &endptr, 10); if (*data == '\0' || *endptr != '\0') { FatalError("%s (%d): Invalid ICMP itype in rule: %s\n", file_name, file_line, type); } ds_ptr->operator = ICMP_TYPE_TEST_RG; } /* otherwise if its greater than... */ else if (*data == '>') { data++; while (isspace((int)*data)) data++; ds_ptr->icmp_type = strtol(data, &endptr, 10); if (*data == '\0' || *endptr != '\0') { FatalError("%s (%d): Invalid ICMP itype in rule: %s\n", file_name, file_line, type); } ds_ptr->operator = ICMP_TYPE_TEST_GT; } /* otherwise if its less than ... */ else if (*data == '<') { data++; while (isspace((int)*data)) data++; ds_ptr->icmp_type = strtol(data, &endptr, 10); if (*data == '\0' || *endptr != '\0') { FatalError("%s (%d): Invalid ICMP itype in rule: %s\n", file_name, file_line, type); } ds_ptr->operator = ICMP_TYPE_TEST_LT; } /* otherwise check if its a digit */ else { ds_ptr->icmp_type = strtol(data, &endptr, 10); if (*endptr != '\0') { FatalError("%s (%d): Invalid ICMP itype in rule: %s\n", file_name, file_line, type); } ds_ptr->operator = ICMP_TYPE_TEST_EQ; } if (add_detection_option(sc, RULE_OPTION_TYPE_ICMP_TYPE, (void *)ds_ptr, &ds_ptr_dup) == DETECTION_OPTION_EQUAL) { free(ds_ptr); ds_ptr = otn->ds_list[PLUGIN_ICMP_TYPE] = ds_ptr_dup; } return; } /**************************************************************************** * * Function: IcmpTypeCheck(char *, OptTreeNode *) * * Purpose: Test the packet's ICMP type field value against the option's * ICMP type * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ int IcmpTypeCheck(void *option_data, Packet *p) { IcmpTypeCheckData *ds_ptr; int rval = DETECTION_OPTION_NO_MATCH; PROFILE_VARS; ds_ptr = (IcmpTypeCheckData *)option_data; /* return 0 if we don't have an icmp header */ if(!p->icmph) return rval; PREPROC_PROFILE_START(icmpTypePerfStats); switch(ds_ptr->operator) { case ICMP_TYPE_TEST_EQ: if (p->icmph->type == ds_ptr->icmp_type) rval = DETECTION_OPTION_MATCH; break; case ICMP_TYPE_TEST_GT: if (p->icmph->type > ds_ptr->icmp_type) rval = DETECTION_OPTION_MATCH; break; case ICMP_TYPE_TEST_LT: if (p->icmph->type < ds_ptr->icmp_type) rval = DETECTION_OPTION_MATCH; break; case ICMP_TYPE_TEST_RG: if (p->icmph->type > ds_ptr->icmp_type && p->icmph->type < ds_ptr->icmp_type2) rval = DETECTION_OPTION_MATCH; break; } DEBUG_WRAP( if (rval == DETECTION_OPTION_MATCH) { DebugMessage(DEBUG_PLUGIN, "Got icmp type match!\n"); } else { DebugMessage(DEBUG_PLUGIN, "Failed icmp type match!\n"); } ); PREPROC_PROFILE_END(icmpTypePerfStats); return rval; } snort-2.9.15.1/src/detection-plugins/sp_icmp_type_check.h0000644000175200017520000000266413571422607020305 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifndef __SP_ICMP_TYPE_CHECK_H__ #define __SP_ICMP_TYPE_CHECK_H__ #define ICMP_TYPE_TEST_EQ 1 #define ICMP_TYPE_TEST_GT 2 #define ICMP_TYPE_TEST_LT 3 #define ICMP_TYPE_TEST_RG 4 typedef struct _IcmpTypeCheckData { /* the icmp type number */ int icmp_type; int icmp_type2; uint8_t operator; } IcmpTypeCheckData; void SetupIcmpTypeCheck(void); uint32_t IcmpTypeCheckHash(void *d); int IcmpTypeCheckCompare(void *l, void *r); #endif /* __SP_ICMP_TYPE_CHECK_H__ */ snort-2.9.15.1/src/detection-plugins/sp_ip_fragbits.c0000644000175200017520000004356313571422607017446 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Snort Detection Plugin Source File for IP Fragment Bits plugin */ /* sp_ip_fragbits * * Purpose: * * Check the fragmentation bits of the IP header for set values. Possible * bits are don't fragment (DF), more fragments (MF), and reserved (RB). * * Arguments: * * The keyword to reference this plugin is "fragbits". Possible arguments are * D, M and R for DF, MF and RB, respectively. * * Effect: * * Inidicates whether any of the specified bits have been set. * * Comments: * * Ofir Arkin should be a little happier now. :) * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "sf_types.h" #include "rules.h" #include "treenodes.h" #include "plugbase.h" #include "decode.h" #include "parser.h" #include "snort_debug.h" #include "util.h" #include "plugin_enum.h" #define GREATER_THAN 1 #define LESS_THAN 2 #define FB_NORMAL 0 #define FB_ALL 1 #define FB_ANY 2 #define FB_NOT 3 #define FB_RB 0x8000 #define FB_DF 0x4000 #define FB_MF 0x2000 #include "snort.h" #include "profiler.h" #ifdef PERF_PROFILING PreprocStats fragBitsPerfStats; PreprocStats fragOffsetPerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif #include "sfhashfcn.h" #include "detection_options.h" typedef struct _FragBitsData { char mode; uint16_t frag_bits; } FragBitsData; typedef struct _FragOffsetData { uint8_t comparison_flag; uint8_t not_flag; uint16_t offset; } FragOffsetData; void FragBitsInit(struct _SnortConfig *, char *, OptTreeNode *, int); void ParseFragBits(struct _SnortConfig *, char *, OptTreeNode *); int CheckFragBits(void *option_data, Packet *p); /* offset checks */ void FragOffsetInit(struct _SnortConfig *, char *, OptTreeNode *, int); void ParseFragOffset(struct _SnortConfig *, char *, OptTreeNode *); int CheckFragOffset(void *option_data, Packet *p); static uint16_t bitmask; uint32_t IpFragBitsCheckHash(void *d) { uint32_t a,b,c; FragBitsData *data = (FragBitsData *)d; a = data->mode; b = data->frag_bits; c = RULE_OPTION_TYPE_IP_FRAGBITS; final(a,b,c); return c; } int IpFragBitsCheckCompare(void *l, void *r) { FragBitsData *left = (FragBitsData *)l; FragBitsData *right = (FragBitsData *)r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if ((left->mode == right->mode) && (left->frag_bits == right->frag_bits)) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } uint32_t IpFragOffsetCheckHash(void *d) { uint32_t a,b,c; FragOffsetData *data = (FragOffsetData *)d; a = data->comparison_flag || (data->not_flag << 8); b = data->offset; c = RULE_OPTION_TYPE_IP_FRAG_OFFSET; final(a,b,c); return c; } int IpFragOffsetCheckCompare(void *l, void *r) { FragOffsetData *left = (FragOffsetData *)l; FragOffsetData *right = (FragOffsetData *)r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if ((left->comparison_flag == right->comparison_flag) && (left->not_flag == right->not_flag) && (left->offset == right->offset)) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } /**************************************************************************** * * Function: SetupFragBits() * * Purpose: Assign the keyword to the rules parser. * * Arguments: None. * * Returns: void function * ****************************************************************************/ void SetupFragBits(void) { /* map the keyword to an initialization/processing function */ RegisterRuleOption("fragbits", FragBitsInit, NULL, OPT_TYPE_DETECTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("fragbits", &fragBitsPerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Plugin: FragBits Setup\n");); } /**************************************************************************** * * Function: FragBitsInit(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: Initialize the detection function and parse the arguments. * * Arguments: data => rule arguments/data * otn => pointer to the current rule option list node * protocol => protocol that must be specified to use this plugin * * Returns: void function * ****************************************************************************/ void FragBitsInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { OptFpList *fpl; /* multiple declaration check */ if(otn->ds_list[PLUGIN_FRAG_BITS]) { FatalError("%s(%d): Multiple fragbits options in rule\n", file_name, file_line); } /* allocate the data structure and attach it to the rule's data struct list */ otn->ds_list[PLUGIN_FRAG_BITS] = (FragBitsData *) SnortAlloc(sizeof(FragBitsData)); /* this is where the keyword arguments are processed and placed into the rule option's data structure */ ParseFragBits(sc, data, otn); /* * set the bitmask needed to mask off the IP offset field * in the check function */ bitmask = htons(0xE000); /* finally, attach the option's detection function to the rule's detect function pointer list */ fpl = AddOptFuncToList(CheckFragBits, otn); fpl->type = RULE_OPTION_TYPE_IP_FRAGBITS; fpl->context = otn->ds_list[PLUGIN_FRAG_BITS]; } /**************************************************************************** * * Function: ParseFragBits(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: This is the function that is used to process the option keyword's * arguments and attach them to the rule's data structures. * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ void ParseFragBits(struct _SnortConfig *sc, char *data, OptTreeNode *otn) { char *fptr; char *fend; FragBitsData *ds_ptr; /* data struct pointer */ void *ds_ptr_dup; /* set the ds pointer to make it easier to reference the option's particular data struct */ ds_ptr = otn->ds_list[PLUGIN_FRAG_BITS]; /* manipulate the option arguments here */ fptr = data; while(isspace((u_char) *fptr)) { fptr++; } if(strlen(fptr) == 0) { FatalError("[!] Line %s (%d): No arguments to the fragbits keyword\n", file_name, file_line); } fend = fptr + strlen(fptr); ds_ptr->mode = FB_NORMAL; /* default value */ while(fptr < fend) { switch((*fptr&0xFF)) { case 'd': case 'D': /* don't frag bit */ ds_ptr->frag_bits |= FB_DF; break; case 'm': case 'M': /* more frags bit */ ds_ptr->frag_bits |= FB_MF; break; case 'r': case 'R': /* reserved bit */ ds_ptr->frag_bits |= FB_RB; break; case '!': /* NOT flag, fire if flags are not set */ ds_ptr->mode = FB_NOT; break; case '*': /* ANY flag, fire on any of these bits */ ds_ptr->mode = FB_ANY; break; case '+': /* ALL flag, fire on these bits plus any others */ ds_ptr->mode = FB_ALL; break; default: FatalError("[!] Line %s (%d): Bad Frag Bits = \"%c\"\n" " Valid options are: RDM+!*\n", file_name, file_line, *fptr); } fptr++; } /* put the bits in network order for fast comparisons */ ds_ptr->frag_bits = htons(ds_ptr->frag_bits); /* set the final option arguments here */ if (add_detection_option(sc, RULE_OPTION_TYPE_IP_FRAGBITS, (void *)ds_ptr, &ds_ptr_dup) == DETECTION_OPTION_EQUAL) { free(ds_ptr); ds_ptr = otn->ds_list[PLUGIN_FRAG_BITS] = ds_ptr_dup; } } /**************************************************************************** * * Function: CheckFragBits(Packet *p, OptTreeNode *otn, OptFpList *fp_list) * * Purpose: This function checks the frag bits in the packets * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: If the mask matches return true, else return 0. * ****************************************************************************/ int CheckFragBits(void *option_data, Packet *p) { FragBitsData *fb = (FragBitsData *)option_data; int rval = DETECTION_OPTION_NO_MATCH; PROFILE_VARS; if(!IPH_IS_VALID(p)) { return rval; } PREPROC_PROFILE_START(fragBitsPerfStats); DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, " CheckFragBits: "); DebugMessage(DEBUG_PLUGIN, "[rule: 0x%X:%d pkt: 0x%X] ", fb->frag_bits, fb->mode, (GET_IPH_OFF(p)&bitmask));); switch(fb->mode) { case FB_NORMAL: /* check if the rule bits match the bits in the packet */ if(fb->frag_bits == (GET_IPH_OFF(p)&bitmask)) { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Got Normal bits match\n");); rval = DETECTION_OPTION_MATCH; } else { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Normal test failed\n");); } break; case FB_NOT: /* check if the rule bits don't match the bits in the packet */ if((fb->frag_bits & (GET_IPH_OFF(p)&bitmask)) == 0) { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Got NOT bits match\n");); rval = DETECTION_OPTION_MATCH; } else { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"NOT test failed\n");); } break; case FB_ALL: /* check if the rule bits are present in the packet */ if((fb->frag_bits & (GET_IPH_OFF(p)&bitmask)) == fb->frag_bits) { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Got ALL bits match\n");); rval = DETECTION_OPTION_MATCH; } else { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"ALL test failed\n");); } break; case FB_ANY: /* check if any of the rule bits match the bits in the packet */ if((fb->frag_bits & (GET_IPH_OFF(p)&bitmask)) != 0) { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Got ANY bits match\n");); rval = DETECTION_OPTION_MATCH; } else { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"ANY test failed\n");); } break; default: break; } /* if the test isn't successful, this function *must* return 0 */ PREPROC_PROFILE_END(fragBitsPerfStats); return rval; } /**************************************************************************** * * Function: SetupFragOffset() * * Purpose: Assign the keyword to the rules parser. * * Arguments: None. * * Returns: void function * ****************************************************************************/ void SetupFragOffset(void) { /* map the keyword to an initialization/processing function */ RegisterRuleOption("fragoffset", FragOffsetInit, NULL, OPT_TYPE_DETECTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("fragoffset", &fragOffsetPerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Plugin: FragOffset Setup\n");); } /**************************************************************************** * * Function: FragOffsetInit(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: Initialize the detection function and parse the arguments. * * Arguments: data => rule arguments/data * otn => pointer to the current rule option list node * protocol => protocol that must be specified to use this plugin * * Returns: void function * ****************************************************************************/ void FragOffsetInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { OptFpList *fpl; /* allocate the data structure and attach it to the rule's data struct list */ otn->ds_list[PLUGIN_FRAG_OFFSET] = (FragOffsetData *)SnortAlloc(sizeof(FragOffsetData)); /* this is where the keyword arguments are processed and placed into the rule option's data structure */ ParseFragOffset(sc, data, otn); /* finally, attach the option's detection function to the rule's detect function pointer list */ fpl = AddOptFuncToList(CheckFragOffset, otn); fpl->type = RULE_OPTION_TYPE_IP_FRAG_OFFSET; fpl->context = otn->ds_list[PLUGIN_FRAG_OFFSET]; } /**************************************************************************** * * Function: ParseFragOffset(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: This is the function that is used to process the option keyword's * arguments and attach them to the rule's data structures. * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ void ParseFragOffset(struct _SnortConfig *sc, char *data, OptTreeNode *otn) { char *fptr; char *endTok; FragOffsetData *ds_ptr; /* data struct pointer */ void *ds_ptr_dup; /* set the ds pointer to make it easier to reference the option's particular data struct */ ds_ptr = otn->ds_list[PLUGIN_FRAG_OFFSET]; /* manipulate the option arguments here */ fptr = data; while(isspace((u_char) *fptr)) { fptr++; } if(strlen(fptr) == 0) { FatalError("[!] Line %s (%d): No arguments to the fragoffset keyword\n", file_name, file_line); } if(*fptr == '!') { ds_ptr->not_flag = 1; fptr++; } if(*fptr == '>') { if(!ds_ptr->not_flag) { ds_ptr->comparison_flag = GREATER_THAN; fptr++; } } if(*fptr == '<') { if(!ds_ptr->comparison_flag && !ds_ptr->not_flag) { ds_ptr->comparison_flag = LESS_THAN; fptr++; } } ds_ptr->offset = (uint16_t)SnortStrtoulRange(fptr, &endTok, 10, 0, UINT16_MAX); if ((endTok == fptr) || (*endTok != '\0')) { FatalError("%s(%d) => Invalid parameter '%s' to fragoffset (not a " "number?) \n", file_name, file_line, fptr); } if (add_detection_option(sc, RULE_OPTION_TYPE_IP_FRAG_OFFSET, (void *)ds_ptr, &ds_ptr_dup) == DETECTION_OPTION_EQUAL) { free(ds_ptr); ds_ptr = otn->ds_list[PLUGIN_FRAG_OFFSET] = ds_ptr_dup; } } /**************************************************************************** * * Function: CheckFragOffset(char *, OptTreeNode *) * * Purpose: Use this function to perform the particular detection routine * that this rule keyword is supposed to encompass. * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: If the detection test fails, this function *must* return a zero! * On success, it calls the next function in the detection list * ****************************************************************************/ int CheckFragOffset(void *option_data, Packet *p) { FragOffsetData *ipd = (FragOffsetData *)option_data; int p_offset = p->frag_offset * 8; int rval = DETECTION_OPTION_NO_MATCH; PROFILE_VARS; if(!IPH_IS_VALID(p)) { return rval; } PREPROC_PROFILE_START(fragOffsetPerfStats); #ifdef DEBUG_MSGS DebugMessage(DEBUG_PLUGIN, "[!] Checking fragoffset %d against %d\n", ipd->offset, p->frag_offset * 8); if(p->frag_flag) { DebugMessage(DEBUG_PLUGIN, "Frag Offset: 0x%04X Frag Size: 0x%04X\n", (p->frag_offset & 0x1FFF) * 8, (ntohs(GET_IPH_LEN(p)) - p->frag_offset - IP_HEADER_LEN)); } #endif if(!ipd->comparison_flag) { if((ipd->offset == p_offset) ^ ipd->not_flag) { rval = DETECTION_OPTION_MATCH; } else { /* you can put debug comments here or not */ DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"No match\n");); } } else { if(ipd->comparison_flag == GREATER_THAN) { if(p_offset > ipd->offset) { rval = DETECTION_OPTION_MATCH; } } else { if(p_offset < ipd->offset) { rval = DETECTION_OPTION_MATCH; } } } /* if the test isn't successful, this function *must* return 0 */ PREPROC_PROFILE_END(fragOffsetPerfStats); return rval; } snort-2.9.15.1/src/detection-plugins/sp_ip_fragbits.h0000644000175200017520000000252513571422607017444 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Snort Detection Plugin Header for IP Fragment Bits plugin*/ #ifndef __SP_IP_FRAGBITS_H__ #define __SP_IP_FRAGBITS_H__ void SetupFragBits(void); void SetupFragOffset(void); uint32_t IpFragBitsCheckHash(void *d); int IpFragBitsCheckCompare(void *l, void *r); uint32_t IpFragOffsetCheckHash(void *d); int IpFragOffsetCheckCompare(void *l, void *r); #endif /* __SP_IP_FRAGBITS_H__ */ snort-2.9.15.1/src/detection-plugins/sp_ip_id_check.c0000644000175200017520000001575113571422607017374 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "sf_types.h" #include "rules.h" #include "treenodes.h" #include "decode.h" #include "parser.h" #include "plugbase.h" #include "snort_debug.h" #include "plugin_enum.h" #include "util.h" #include "snort.h" #include "profiler.h" #ifdef PERF_PROFILING PreprocStats ipIdPerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif #include "sfhashfcn.h" #include "detection_options.h" typedef struct _IpIdCheckData { u_long ip_id; } IpIdCheckData; void IpIdCheckInit(struct _SnortConfig *, char *, OptTreeNode *, int); void ParseIpId(struct _SnortConfig *, char *, OptTreeNode *); int IpIdCheckEq(void *option_data, Packet *p); uint32_t IpIdCheckHash(void *d) { uint32_t a,b,c; IpIdCheckData *data = (IpIdCheckData *)d; a = data->ip_id; b = RULE_OPTION_TYPE_IP_ID; c = 0; final(a,b,c); return c; } int IpIdCheckCompare(void *l, void *r) { IpIdCheckData *left = (IpIdCheckData *)l; IpIdCheckData *right = (IpIdCheckData *)r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if (left->ip_id == right->ip_id) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } /**************************************************************************** * * Function: SetupIpIdCheck() * * Purpose: Associate the id keyword with IpIdCheckInit * * Arguments: None. * * Returns: void function * ****************************************************************************/ void SetupIpIdCheck(void) { /* map the keyword to an initialization/processing function */ RegisterRuleOption("id", IpIdCheckInit, NULL, OPT_TYPE_DETECTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("id", &ipIdPerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: IpIdCheck Initialized\n");); } /**************************************************************************** * * Function: IpIdCheckInit(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: Setup the id data struct and link the function into option * function pointer list * * Arguments: data => rule arguments/data * otn => pointer to the current rule option list node * * Returns: void function * ****************************************************************************/ void IpIdCheckInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { OptFpList *fpl; /* multiple declaration check */ if(otn->ds_list[PLUGIN_IP_ID_CHECK]) { FatalError("%s(%d): Multiple IP id options in rule\n", file_name, file_line); } /* allocate the data structure and attach it to the rule's data struct list */ otn->ds_list[PLUGIN_IP_ID_CHECK] = (IpIdCheckData *) SnortAlloc(sizeof(IpIdCheckData)); /* this is where the keyword arguments are processed and placed into the rule option's data structure */ ParseIpId(sc, data, otn); /* finally, attach the option's detection function to the rule's detect function pointer list */ fpl = AddOptFuncToList(IpIdCheckEq, otn); fpl->type = RULE_OPTION_TYPE_IP_ID; fpl->context = otn->ds_list[PLUGIN_IP_ID_CHECK]; } /**************************************************************************** * * Function: ParseIpId(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: Convert the id option argument to data and plug it into the * data structure * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ void ParseIpId(struct _SnortConfig *sc, char *data, OptTreeNode *otn) { IpIdCheckData *ds_ptr; /* data struct pointer */ void *ds_ptr_dup; int ip_id; char *endTok; /* set the ds pointer to make it easier to reference the option's particular data struct */ ds_ptr = otn->ds_list[PLUGIN_IP_ID_CHECK]; /* get rid of any whitespace */ while(isspace((int)*data)) { data++; } ip_id = SnortStrtolRange(data, &endTok, 10, 0, UINT16_MAX); if ((endTok == data) || (*endTok != '\0')) { FatalError("%s(%d) => Invalid parameter '%s' to id (not a " "number?) \n", file_name, file_line, data); } ds_ptr->ip_id = htons( (u_short) ip_id); if (add_detection_option(sc, RULE_OPTION_TYPE_IP_ID, (void *)ds_ptr, &ds_ptr_dup) == DETECTION_OPTION_EQUAL) { free(ds_ptr); ds_ptr = otn->ds_list[PLUGIN_IP_ID_CHECK] = ds_ptr_dup; } DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"ID set to %ld\n", ds_ptr->ip_id);); } /**************************************************************************** * * Function: IpIdCheckEq(char *, OptTreeNode *) * * Purpose: Test the ip header's id field to see if its value is equal to the * value in the rule. This is useful to detect things like "elite" * numbers, oddly repeating numbers, etc. * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ int IpIdCheckEq(void *option_data, Packet *p) { IpIdCheckData *ipIdCheckData = (IpIdCheckData *)option_data; int rval = DETECTION_OPTION_NO_MATCH; PROFILE_VARS; if(!IPH_IS_VALID(p)) return rval; /* if error occured while ip header * was processed, return 0 automagically. */ PREPROC_PROFILE_START(ipIdPerfStats); if(ipIdCheckData->ip_id == GET_IPH_ID(p)) { /* call the next function in the function list recursively */ rval = DETECTION_OPTION_MATCH; } else { /* you can put debug comments here or not */ DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "No match for sp_ip_id_check\n");); } /* if the test isn't successful, return 0 */ PREPROC_PROFILE_END(ipIdPerfStats); return rval; } snort-2.9.15.1/src/detection-plugins/sp_ip_id_check.h0000644000175200017520000000222513571422607017371 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifndef __SP_IP_ID_CHECK_H__ #define __SP_IP_ID_CHECK_H__ void SetupIpIdCheck(void); uint32_t IpIdCheckHash(void *d); int IpIdCheckCompare(void *l, void *r); #endif /* __SP_IP_ID_CHECK_H__ */ snort-2.9.15.1/src/detection-plugins/sp_ip_proto.c0000644000175200017520000002647113571422607017007 00000000000000/* $Id$ */ /**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2003-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ /* sp_ip_proto * * Purpose: * * Check the IP header's protocol field value. * * Arguments: * * Number, protocol name, ! for negation * * Effect: * * Success on protocol match, failure otherwise * * Comments: * * None. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #ifndef WIN32 #include #endif /* !WIN32 */ #include "rules.h" #include "treenodes.h" #include "decode.h" #include "plugbase.h" #include "parser.h" #include "snort_debug.h" #include "util.h" #include "plugin_enum.h" #include "sp_ip_proto.h" #include "snort.h" #include "profiler.h" #ifdef PERF_PROFILING PreprocStats ipProtoPerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif #include "sfhashfcn.h" #include "detection_options.h" #define IP_PROTO__EQUAL 0 #define IP_PROTO__NOT_EQUAL 1 #define IP_PROTO__GREATER_THAN 2 #define IP_PROTO__LESS_THAN 3 typedef struct _IpProtoData { uint8_t protocol; uint8_t comparison_flag; } IpProtoData; void IpProtoInit(struct _SnortConfig *, char *, OptTreeNode *, int); void IpProtoRuleParseFunction(char *, IpProtoData *); int IpProtoDetectorFunction(void *option_data, Packet *p); uint32_t IpProtoCheckHash(void *d) { uint32_t a,b,c; IpProtoData *data = (IpProtoData *)d; a = data->protocol; b = data->comparison_flag; c = RULE_OPTION_TYPE_IP_PROTO; final(a,b,c); return c; } int IpProtoCheckCompare(void *l, void *r) { IpProtoData *left = (IpProtoData *)l; IpProtoData *right = (IpProtoData *)r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if ((left->protocol == right->protocol) && (left->comparison_flag == right->comparison_flag)) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } /**************************************************************************** * * Function: SetupIpProto() * * Purpose: Generic detection engine plugin ip_proto. Registers the * configuration function and links it to a rule keyword. This is * the function that gets called from InitPlugins in plugbase.c. * * Arguments: None. * * Returns: void function * ****************************************************************************/ void SetupIpProto(void) { /* map the keyword to an initialization/processing function */ RegisterRuleOption("ip_proto", IpProtoInit, NULL, OPT_TYPE_DETECTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("ip_proto", &ipProtoPerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: IpProto Setup\n");); } /**************************************************************************** * * Function: IpProtoInit(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: Generic rule configuration function. Handles parsing the rule * information and attaching the associated detection function to * the OTN. * * Arguments: data => rule arguments/data * otn => pointer to the current rule option list node * * Returns: void function * ****************************************************************************/ void IpProtoInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { OptFpList *ofl; IpProtoData *ipd; void *ds_ptr_dup; /* Rule must be an "ip" rule to use this rule option */ if (protocol != ETHERNET_TYPE_IP) { FatalError("%s(%d): \"ip_proto\" rule option can only be used in an " "\"ip\" rule.\n", file_name, file_line); } /* multiple declaration check */ /*if(otn->ds_list[PLUGIN_IP_PROTO_CHECK]) { FatalError("%s(%d): Multiple ip_proto options in rule\n", file_name, file_line); }*/ ipd = (IpProtoData *) SnortAlloc(sizeof(IpProtoData)); /* allocate the data structure and attach it to the rule's data struct list */ //otn->ds_list[PLUGIN_IP_PROTO_CHECK] = (IpProtoData *) calloc(sizeof(IpProtoData), sizeof(char)); /* this is where the keyword arguments are processed and placed into the rule option's data structure */ IpProtoRuleParseFunction(data, ipd); /* finally, attach the option's detection function to the rule's detect function pointer list */ ofl = AddOptFuncToList(IpProtoDetectorFunction, otn); ofl->type = RULE_OPTION_TYPE_IP_PROTO; /* ** Set the ds_list for the first ip_proto check for a rule. This ** is needed for the high-speed rule optimization. */ if(!otn->ds_list[PLUGIN_IP_PROTO_CHECK]) otn->ds_list[PLUGIN_IP_PROTO_CHECK] = ipd; if (add_detection_option(sc, RULE_OPTION_TYPE_IP_PROTO, (void *)ipd, &ds_ptr_dup) == DETECTION_OPTION_EQUAL) { free(ipd); ipd = otn->ds_list[PLUGIN_IP_PROTO_CHECK] = ds_ptr_dup; } ofl->context = ipd; } /**************************************************************************** * * Function: IpProtoRuleParseFunction(char *, OptTreeNode *) * * Purpose: This is the function that is used to process the option keyword's * arguments and attach them to the rule's data structures. * * Arguments: data => argument data * ds_ptr => pointer to the IpProtoData struct * * Returns: void function * ****************************************************************************/ void IpProtoRuleParseFunction(char *data, IpProtoData *ds_ptr) { /* set the ds pointer to make it easier to reference the option's particular data struct */ //ds_ptr = otn->ds_list[PLUGIN_IP_PROTO_CHECK]; while(isspace((int)*data)) data++; if (*data == '!') { ds_ptr->comparison_flag = IP_PROTO__NOT_EQUAL; data++; } else if (*data == '>') { ds_ptr->comparison_flag = IP_PROTO__GREATER_THAN; data++; } else if (*data == '<') { ds_ptr->comparison_flag = IP_PROTO__LESS_THAN; data++; } else { ds_ptr->comparison_flag = IP_PROTO__EQUAL; } /* check for a number or a protocol name */ if(isdigit((int)*data)) { unsigned long ip_proto; char *endptr; ip_proto = SnortStrtoul(data, &endptr, 10); if ((errno == ERANGE) || (ip_proto >= NUM_IP_PROTOS)) { FatalError("%s(%d) Invalid protocol number for \"ip_proto\" " "rule option. Value must be between 0 and 255.\n", file_name, file_line); } ds_ptr->protocol = (uint8_t)ip_proto; } else { struct protoent *pt = getprotobyname(data); if (pt != NULL) { /* p_proto should be a number less than 256 */ ds_ptr->protocol = (uint8_t)pt->p_proto; } else { FatalError("%s(%d) Invalid protocol name for \"ip_proto\" " "rule option: \"%s\".\n", file_name, file_line, data); } } } /**************************************************************************** * * Function: IpProtoDetectorFunction(char *, OptTreeNode *) * * Purpose: Use this function to perform the particular detection routine * that this rule keyword is supposed to encompass. * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: If the detection test fails, this function *must* return a zero! * On success, it calls the next function in the detection list * ****************************************************************************/ int IpProtoDetectorFunction(void *option_data, Packet *p) { IpProtoData *ipd = (IpProtoData *)option_data; /* data struct pointer */ int rval = DETECTION_OPTION_NO_MATCH; PROFILE_VARS; if(!IPH_IS_VALID(p)) { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Not IP\n");); return rval; } PREPROC_PROFILE_START(ipProtoPerfStats); switch (ipd->comparison_flag) { case IP_PROTO__EQUAL: if (GET_IPH_PROTO(p) == ipd->protocol) rval = DETECTION_OPTION_MATCH; break; case IP_PROTO__NOT_EQUAL: if (GET_IPH_PROTO(p) != ipd->protocol) rval = DETECTION_OPTION_MATCH; break; case IP_PROTO__GREATER_THAN: if (GET_IPH_PROTO(p) > ipd->protocol) rval = DETECTION_OPTION_MATCH; break; case IP_PROTO__LESS_THAN: if (GET_IPH_PROTO(p) < ipd->protocol) rval = DETECTION_OPTION_MATCH; break; default: ErrorMessage("%s(%d) Invalid comparison flag.\n", __FILE__, __LINE__); break; } /* if the test isn't successful, this function *must* return 0 */ PREPROC_PROFILE_END(ipProtoPerfStats); return rval; } int GetIpProtos(void *option_data, uint8_t *proto_array, int pa_size) { IpProtoData *ipd = (IpProtoData *)option_data; int i; if ((proto_array == NULL) || (pa_size < NUM_IP_PROTOS)) return -1; /* IP proto not set. Include them all */ if (option_data == NULL) { memset(proto_array, 1, pa_size); return 0; } memset(proto_array, 0, pa_size); switch (ipd->comparison_flag) { case IP_PROTO__EQUAL: proto_array[ipd->protocol] = 1; break; case IP_PROTO__NOT_EQUAL: for (i = 0; i < ipd->protocol; i++) proto_array[i] = 1; for (i = i + 1; i < NUM_IP_PROTOS; i++) proto_array[i] = 1; break; case IP_PROTO__GREATER_THAN: for (i = ipd->protocol + 1; i < NUM_IP_PROTOS; i++) proto_array[i] = 1; break; case IP_PROTO__LESS_THAN: for (i = 0; i < ipd->protocol; i++) proto_array[i] = 1; break; default: ErrorMessage("%s(%d) Invalid comparison flag.\n", __FILE__, __LINE__); return -1; } return 0; } /* * Extract the IP Protocol field. */ int GetOtnIpProto(OptTreeNode *otn) { IpProtoData *ipd; if (otn == NULL) return -1; ipd = (IpProtoData *)otn->ds_list[PLUGIN_IP_PROTO_CHECK]; if ((ipd != NULL) && (ipd->comparison_flag == IP_PROTO__EQUAL)) return (int)ipd->protocol; return -1; } snort-2.9.15.1/src/detection-plugins/sp_ip_proto.h0000644000175200017520000000243213571422607017003 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifndef __SP_IP_PROTO_H__ #define __SP_IP_PROTO_H__ #include "rules.h" #include "treenodes.h" #include "sf_types.h" void SetupIpProto(void); uint32_t IpProtoCheckHash(void *); int IpProtoCheckCompare(void *, void *); int GetOtnIpProto(OptTreeNode *); int GetIpProtos(void *, uint8_t *, int); #endif /* __SP_IP_PROTO_H__ */ snort-2.9.15.1/src/detection-plugins/sp_ip_same_check.c0000644000175200017520000001524213571422607017720 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** Copyright (C) 2001 Phil Wood ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "sf_types.h" #include "rules.h" #include "treenodes.h" #include "decode.h" #include "plugbase.h" #include "parser.h" #include "snort_debug.h" #include "util.h" #include "plugin_enum.h" #include "snort.h" #include "profiler.h" #ifdef PERF_PROFILING PreprocStats ipSamePerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif #include "detection_options.h" typedef struct _IpSameData { u_char ip_same; } IpSameData; void IpSameCheckInit(struct _SnortConfig *, char *, OptTreeNode *, int); void ParseIpSame(char *, OptTreeNode *); int IpSameCheck(void *option_data, Packet *p); uint32_t IpSameCheckHash(void *d) { uint32_t a,b,c; /* NO data stored for the option */ a = RULE_OPTION_TYPE_IP_SAME; b = 0; c = 0; final(a,b,c); return c; } int IpSameCheckCompare(void *l, void *r) { /* NO data stored for the option */ return DETECTION_OPTION_EQUAL; } /**************************************************************************** * * Function: SetupIpSameCheck() * * Purpose: Associate the same keyword with IpSameCheckInit * * Arguments: None. * * Returns: void function * ****************************************************************************/ void SetupIpSameCheck(void) { /* map the keyword to an initialization/processing function */ RegisterRuleOption("sameip", IpSameCheckInit, NULL, OPT_TYPE_DETECTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("sameip", &ipSamePerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Plugin: IpSameCheck Initialized\n");); } /**************************************************************************** * * Function: IpSameCheckInit(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: Setup the same data struct and link the function into option * function pointer list * * Arguments: data => rule arguments/data * otn => pointer to the current rule option list node * * Returns: void function * ****************************************************************************/ void IpSameCheckInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { OptFpList *fpl; void *ds_ptr_dup; /* multiple declaration check */ if(otn->ds_list[PLUGIN_IP_SAME_CHECK]) { FatalError("%s(%d): Multiple sameip options in rule\n", file_name, file_line); } /* allocate the data structure and attach it to the rule's data struct list */ otn->ds_list[PLUGIN_IP_SAME_CHECK] = (void *)1; /* Just store something there */ //otn->ds_list[PLUGIN_IP_SAME_CHECK] = (IpSameData *) // SnortAlloc(sizeof(IpSameData)); /* this is where the keyword arguments are processed and placed into the rule option's data structure */ ParseIpSame(data, otn); if (add_detection_option(sc, RULE_OPTION_TYPE_IP_SAME, (void *)NULL, &ds_ptr_dup) == DETECTION_OPTION_EQUAL) { //otn->ds_list[PLUGIN_IP_SAME_CHECK] = ds_ptr_dup; } /* finally, attach the option's detection function to the rule's detect function pointer list */ fpl = AddOptFuncToList(IpSameCheck, otn); fpl->type = RULE_OPTION_TYPE_IP_SAME; } /**************************************************************************** * * Function: ParseIpSame(char *, OptTreeNode *) * * Purpose: Convert the id option argument to data and plug it into the * data structure * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ void ParseIpSame(char *data, OptTreeNode *otn) { return; /* the check below bombs. */ #if 0 IpSameData *ds_ptr; /* data struct pointer */ /* set the ds pointer to make it easier to reference the option's particular data struct */ ds_ptr = otn->ds_list[PLUGIN_IP_SAME_CHECK]; /* get rid of any whitespace */ while(isspace((int)*data)) { data++; } if (*data) { FatalError("%s(%d): arg '%s' not required\n", file_name, file_line, data); } #endif } /**************************************************************************** * * Function: IpSameCheck(char *, OptTreeNode *) * * Purpose: Test the ip header's id field to see if its value is equal to the * value in the rule. This is useful to detect things like "elite" * numbers, oddly repeating numbers, etc. * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ int IpSameCheck(void *option_data, Packet *p) { int rval = DETECTION_OPTION_NO_MATCH; PROFILE_VARS; if(!IPH_IS_VALID(p)) return rval; /* if error occured while ip header * was processed, return 0 automagically. */ PREPROC_PROFILE_START(ipSamePerfStats); if (IP_EQUALITY( GET_SRC_IP(p), GET_DST_IP(p))) { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Match! %x ->", sfip_ntoa(GET_SRC_IP(p))); DebugMessage(DEBUG_PLUGIN, " %x\n", sfip_ntoa(GET_DST_IP(p)))); rval = DETECTION_OPTION_MATCH; } else { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"No match! %x ->", sfip_ntoa(GET_SRC_IP(p))); DebugMessage(DEBUG_PLUGIN, " %x\n", sfip_ntoa(GET_DST_IP(p)))); } /* if the test isn't successful, return 0 */ PREPROC_PROFILE_END(ipSamePerfStats); return rval; } snort-2.9.15.1/src/detection-plugins/sp_ip_same_check.h0000644000175200017520000000232013571422607017716 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** Copyright (C) 2001 Phil Wood ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifndef __SP_IP_SAME_CHECK_H__ #define __SP_IP_SAME_CHECK_H__ void SetupIpSameCheck(void); uint32_t IpSameCheckHash(void *d); int IpSameCheckCompare(void *l, void *r); #endif /* __SP_IP_SAME_CHECK_H__ */ snort-2.9.15.1/src/detection-plugins/sp_ip_tos_check.c0000644000175200017520000001752313571422607017604 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #ifdef HAVE_STRINGS_H #include #endif #include "sf_types.h" #include "rules.h" #include "treenodes.h" #include "decode.h" #include "plugbase.h" #include "parser.h" #include "snort_debug.h" #include "plugin_enum.h" #include "util.h" #include "snort.h" #include "profiler.h" #ifdef PERF_PROFILING PreprocStats ipTosPerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif #include "sfhashfcn.h" #include "detection_options.h" typedef struct _IpTosCheckData { uint8_t ip_tos; uint8_t not_flag; } IpTosCheckData; void IpTosCheckInit(struct _SnortConfig *, char *, OptTreeNode *, int); void ParseIpTos(struct _SnortConfig *, char *, OptTreeNode *); int IpTosCheckEq(void *option_data, Packet *p); uint32_t IpTosCheckHash(void *d) { uint32_t a,b,c; IpTosCheckData *data = (IpTosCheckData *)d; a = data->ip_tos; b = data->not_flag; c = RULE_OPTION_TYPE_IP_TOS; final(a,b,c); return c; } int IpTosCheckCompare(void *l, void *r) { IpTosCheckData *left = (IpTosCheckData *)l; IpTosCheckData *right = (IpTosCheckData *)r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if ((left->ip_tos == right->ip_tos) && (left->not_flag == right->not_flag)) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } /**************************************************************************** * * Function: SetupIpTosCheck() * * Purpose: Associate the tos keyword with IpTosCheckInit * * Arguments: None. * * Returns: void function * ****************************************************************************/ void SetupIpTosCheck(void) { /* map the keyword to an initialization/processing function */ RegisterRuleOption("tos", IpTosCheckInit, NULL, OPT_TYPE_DETECTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("tos", &ipTosPerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Plugin: IpTosCheck Initialized\n");); } /**************************************************************************** * * Function: IpTosCheckInit(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: Setup the tos data struct and link the function into option * function pointer list * * Arguments: data => rule arguments/data * otn => pointer to the current rule option list node * * Returns: void function * ****************************************************************************/ void IpTosCheckInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { OptFpList *fpl; /* multiple declaration check */ if(otn->ds_list[PLUGIN_IP_TOS_CHECK]) { FatalError("%s(%d): Multiple IP tos options in rule\n", file_name, file_line); } /* allocate the data structure and attach it to the rule's data struct list */ otn->ds_list[PLUGIN_IP_TOS_CHECK] = (IpTosCheckData *) SnortAlloc(sizeof(IpTosCheckData)); /* this is where the keyword arguments are processed and placed into the rule option's data structure */ ParseIpTos(sc, data, otn); /* finally, attach the option's detection function to the rule's detect function pointer list */ fpl = AddOptFuncToList(IpTosCheckEq, otn); fpl->type = RULE_OPTION_TYPE_IP_TOS; fpl->context = otn->ds_list[PLUGIN_IP_TOS_CHECK]; } /**************************************************************************** * * Function: ParseIpTos(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: Convert the tos option argument to data and plug it into the * data structure * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ void ParseIpTos(struct _SnortConfig *sc, char *data, OptTreeNode *otn) { IpTosCheckData *ds_ptr; /* data struct pointer */ void *ds_ptr_dup; char *endTok; char *start; /* set the ds pointer to make it easier to reference the option's particular data struct */ ds_ptr = otn->ds_list[PLUGIN_IP_TOS_CHECK]; /* get rid of any whitespace */ while(isspace((int)*data)) { data++; } if(data[0] == '!') { ds_ptr->not_flag = 1; start = &data[1]; } else { start = &data[0]; } if(strchr(start, (int) 'x') == NULL && strchr(start, (int)'X') == NULL) { ds_ptr->ip_tos = (uint8_t)SnortStrtoulRange(start, &endTok, 10, 0, UINT8_MAX); if ((endTok == start) || (*endTok != '\0')) { FatalError("%s(%d) => Invalid parameter '%s' to 'tos' (not a " "number?) \n", file_name, file_line, data); } } else { /* hex? */ start = strchr(data,(int)'x'); if(!start) { start = strchr(data,(int)'X'); } if (start) { ds_ptr->ip_tos = (uint8_t)SnortStrtoulRange(start+1, &endTok, 16, 0, UINT8_MAX); } if (!start || (endTok == start+1) || (*endTok != '\0')) { FatalError("%s(%d) => Invalid parameter '%s' to 'tos' (not a " "number?) \n", file_name, file_line, data); } } if (add_detection_option(sc, RULE_OPTION_TYPE_IP_TOS, (void *)ds_ptr, &ds_ptr_dup) == DETECTION_OPTION_EQUAL) { free(ds_ptr); ds_ptr = otn->ds_list[PLUGIN_IP_TOS_CHECK] = ds_ptr_dup; } DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"TOS set to %d\n", ds_ptr->ip_tos);); } /**************************************************************************** * * Function: IpTosCheckEq(char *, OptTreeNode *) * * Purpose: Test the ip header's tos field to see if its value is equal to the * value in the rule. This is useful to detect things like the * "bubonic" DoS tool. * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ int IpTosCheckEq(void *option_data, Packet *p) { IpTosCheckData *ipTosCheckData = (IpTosCheckData *)option_data; int rval = DETECTION_OPTION_NO_MATCH; PROFILE_VARS; if(!IPH_IS_VALID(p)) return rval; /* if error occured while ip header * was processed, return 0 automagically. */ PREPROC_PROFILE_START(ipTosPerfStats); if((ipTosCheckData->ip_tos == GET_IPH_TOS(p)) ^ (ipTosCheckData->not_flag)) { rval = DETECTION_OPTION_MATCH; } else { /* you can put debug comments here or not */ DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"No match\n");); } /* if the test isn't successful, return 0 */ PREPROC_PROFILE_END(ipTosPerfStats); return rval; } snort-2.9.15.1/src/detection-plugins/sp_ip_tos_check.h0000644000175200017520000000223313571422607017601 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifndef __SP_IP_TOS_CHECK_H__ #define __SP_IP_TOS_CHECK_H__ void SetupIpTosCheck(void); uint32_t IpTosCheckHash(void *d); int IpTosCheckCompare(void *l, void *r); #endif /* __SP_IP_TOS_CHECK_H__ */ snort-2.9.15.1/src/detection-plugins/sp_ipoption_check.c0000644000175200017520000002107113571422607020141 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "sf_types.h" #include "rules.h" #include "treenodes.h" #include "decode.h" #include "plugbase.h" #include "parser.h" #include "snort_debug.h" #include "util.h" #include "plugin_enum.h" #include "snort.h" #include "profiler.h" #ifdef PERF_PROFILING PreprocStats ipOptionPerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif #include "sfhashfcn.h" #include "detection_options.h" typedef struct _IpOptionData { u_char ip_option; u_char any_flag; } IpOptionData; void IpOptionInit(struct _SnortConfig *, char *, OptTreeNode *, int); void ParseIpOptionData(struct _SnortConfig *, char *, OptTreeNode *); int CheckIpOptions(void *option_data, Packet *p); uint32_t IpOptionCheckHash(void *d) { uint32_t a,b,c; IpOptionData *data = (IpOptionData *)d; a = data->ip_option; b = data->any_flag; c = RULE_OPTION_TYPE_IP_OPTION; final(a,b,c); return c; } int IpOptionCheckCompare(void *l, void *r) { IpOptionData *left = (IpOptionData *)l; IpOptionData *right = (IpOptionData *)r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if ((left->ip_option == right->ip_option) && (left->any_flag == right->any_flag)) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } /**************************************************************************** * * Function: SetupTemplate() * * Purpose: Generic detection engine plugin template. Registers the * configuration function and links it to a rule keyword. * * Arguments: None. * * Returns: void function * ****************************************************************************/ void SetupIpOptionCheck(void) { /* map the keyword to an initialization/processing function */ RegisterRuleOption("ipopts", IpOptionInit, NULL, OPT_TYPE_DETECTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("ipopts", &ipOptionPerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: IpOptionCheck Initialized\n");); } /**************************************************************************** * * Function: TemplateInit(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: Generic rule configuration function. Handles parsing the rule * information and attaching the associated detection function to * the OTN. * * Arguments: data => rule arguments/data * otn => pointer to the current rule option list node * * Returns: void function * ****************************************************************************/ void IpOptionInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { OptFpList *fpl; /* multiple declaration check */ if(otn->ds_list[PLUGIN_IPOPTION_CHECK]) { FatalError("%s(%d): Multiple ipopts options in rule\n", file_name, file_line); } /* allocate the data structure and attach it to the rule's data struct list */ otn->ds_list[PLUGIN_IPOPTION_CHECK] = (IpOptionData *) SnortAlloc(sizeof(IpOptionData)); /* this is where the keyword arguments are processed and placed into the rule option's data structure */ ParseIpOptionData(sc, data, otn); /* finally, attach the option's detection function to the rule's detect function pointer list */ fpl = AddOptFuncToList(CheckIpOptions, otn); fpl->type = RULE_OPTION_TYPE_IP_OPTION; fpl->context = otn->ds_list[PLUGIN_IPOPTION_CHECK]; } /**************************************************************************** * * Function: ParseIpOptionData(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: This is the function that is used to process the option keyword's * arguments and attach them to the rule's data structures. * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ void ParseIpOptionData(struct _SnortConfig *sc, char *data, OptTreeNode *otn) { IpOptionData *ds_ptr; /* data struct pointer */ void *ds_ptr_dup; /* set the ds pointer to make it easier to reference the option's particular data struct */ ds_ptr = otn->ds_list[PLUGIN_IPOPTION_CHECK]; if(data == NULL) { FatalError("%s(%d): IP Option keyword missing argument!\n", file_name, file_line); } while(isspace((u_char)*data)) data++; if(strcasecmp(data, "rr") == 0) { ds_ptr->ip_option = IPOPT_RR; } else if(strcasecmp(data, "eol") == 0) { ds_ptr->ip_option = IPOPT_EOL; } else if(strcasecmp(data, "nop") == 0) { ds_ptr->ip_option = IPOPT_NOP; } else if(strcasecmp(data, "ts") == 0) { ds_ptr->ip_option = IPOPT_TS; } else if(strcasecmp(data, "esec") == 0) { ds_ptr->ip_option = IPOPT_ESEC; } else if(strcasecmp(data, "sec") == 0) { ds_ptr->ip_option = IPOPT_SECURITY; } else if(strcasecmp(data, "lsrr") == 0) { ds_ptr->ip_option = IPOPT_LSRR; } else if(strcasecmp(data, "lsrre") == 0) { ds_ptr->ip_option = IPOPT_LSRR_E; } else if(strcasecmp(data, "satid") == 0) { ds_ptr->ip_option = IPOPT_SATID; } else if(strcasecmp(data, "ssrr") == 0) { ds_ptr->ip_option = IPOPT_SSRR; } else if(strcasecmp(data, "any") == 0) { ds_ptr->ip_option = 0; ds_ptr->any_flag = 1; } else { FatalError("%s(%d) => Unknown IP option argument: %s!\n", file_name, file_line, data); } if (add_detection_option(sc, RULE_OPTION_TYPE_IP_OPTION, (void *)ds_ptr, &ds_ptr_dup) == DETECTION_OPTION_EQUAL) { free(ds_ptr); ds_ptr = otn->ds_list[PLUGIN_IPOPTION_CHECK] = ds_ptr_dup; } } /**************************************************************************** * * Function: TemplateDetectorFunction(char *, OptTreeNode *) * * Purpose: Use this function to perform the particular detection routine * that this rule keyword is supposed to encompass. * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ int CheckIpOptions(void *option_data, Packet *p) { IpOptionData *ipOptionData = (IpOptionData *)option_data; int rval = DETECTION_OPTION_NO_MATCH; int i; PROFILE_VARS; DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "CheckIpOptions:");); if(!IPH_IS_VALID(p)) return rval; /* if error occured while ip header * was processed, return 0 automagically. */ PREPROC_PROFILE_START(ipOptionPerfStats); if((ipOptionData->any_flag == 1) && (p->ip_option_count > 0)) { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Matched any ip options!\n");); rval = DETECTION_OPTION_MATCH; PREPROC_PROFILE_END(ipOptionPerfStats); return rval; } for(i=0; i< (int) p->ip_option_count; i++) { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "testing pkt(%d):rule(%d)\n", ipOptionData->ip_option, p->ip_options[i].code); ); if(ipOptionData->ip_option == p->ip_options[i].code) { rval = DETECTION_OPTION_MATCH; PREPROC_PROFILE_END(ipOptionPerfStats); return rval; } } /* if the test isn't successful, return 0 */ PREPROC_PROFILE_END(ipOptionPerfStats); return rval; } snort-2.9.15.1/src/detection-plugins/sp_ipoption_check.h0000644000175200017520000000225213571422607020146 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifndef __SP_IPOPTION_CHECK_H__ #define __SP_IPOPTION_CHECK_H__ void SetupIpOptionCheck(void); uint32_t IpOptionCheckHash(void *d); int IpOptionCheckCompare(void *l, void *r); #endif /* __SP_IPOPTION_CHECK_H__ */ snort-2.9.15.1/src/detection-plugins/sp_isdataat.c0000644000175200017520000003055613571422607016745 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 1998-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* sp_isdataat * * Purpose: * Test a specific byte to see if there is data. (Basicly, rule keyword * into inBounds) * * Arguments: * byte location to check if there is data * ["relative"] look for byte location relative to the end of the last * pattern match * ["rawbytes"] force use of the non-normalized buffer. * * Sample: * alert tcp any any -> any 110 (msg:"POP3 user overflow"; \ * content:"USER"; isdataat:30,relative; content:!"|0a|"; within:30;) */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifdef HAVE_STRINGS_H #include #endif #include #include "sf_types.h" #include "snort_bounds.h" #include "rules.h" #include "treenodes.h" #include "decode.h" #include "plugbase.h" #include "parser.h" #include "snort_debug.h" #include "util.h" #include "mstring.h" #include "snort.h" #include "profiler.h" #include "sp_isdataat.h" #include "sp_byte_extract.h" #include "sp_byte_math.h" #ifdef PERF_PROFILING PreprocStats isDataAtPerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif #include "sfhashfcn.h" #include "detection_options.h" #include "detection_util.h" extern char *file_name; /* this is the file name from rules.c, generally used for error messages */ extern int file_line; /* this is the file line number from rules.c that is used to indicate file lines for error messages */ void IsDataAtInit(struct _SnortConfig *, char *, OptTreeNode *, int); void IsDataAtParse(char *, IsDataAtData *, OptTreeNode *); int IsDataAt(void *option_data, Packet *p); uint32_t IsDataAtHash(void *d) { uint32_t a,b,c; IsDataAtData *data = (IsDataAtData *)d; a = data->offset; b = data->flags; c = RULE_OPTION_TYPE_IS_DATA_AT; mix(a,b,c); a += data->offset_var; final(a,b,c); return c; } int IsDataAtCompare(void *l, void *r) { IsDataAtData *left = (IsDataAtData *)l; IsDataAtData *right = (IsDataAtData *)r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if (( left->offset == right->offset) && ( left->flags == right->flags) && ( left->offset_var == right->offset_var) ) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } /**************************************************************************** * * Function: SetupIsDataAt() * * Purpose: Load 'er up * * Arguments: None. * * Returns: void function * ****************************************************************************/ void SetupIsDataAt(void) { /* map the keyword to an initialization/processing function */ RegisterRuleOption("isdataat", IsDataAtInit, NULL, OPT_TYPE_DETECTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("isdataat", &isDataAtPerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: IsDataAt Setup\n");); } /**************************************************************************** * * Function: IsDataAt(struct _SnortConfig *, char *, OptTreeNode *, int protocol) * * Purpose: Generic rule configuration function. Handles parsing the rule * information and attaching the associated detection function to * the OTN. * * Arguments: data => rule arguments/data * otn => pointer to the current rule option list node * protocol => protocol the rule is on (we don't care in this case) * * Returns: void function * ****************************************************************************/ void IsDataAtInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { IsDataAtData *idx; OptFpList *fpl; void *idx_dup; /* allocate the data structure and attach it to the rule's data struct list */ idx = (IsDataAtData *) SnortAlloc(sizeof(IsDataAtData)); if(idx == NULL) { FatalError("%s(%d): Unable to allocate IsDataAt data node\n", file_name, file_line); } /* this is where the keyword arguments are processed and placed into the rule option's data structure */ IsDataAtParse(data, idx, otn); if (add_detection_option(sc, RULE_OPTION_TYPE_IS_DATA_AT, (void *)idx, &idx_dup) == DETECTION_OPTION_EQUAL) { free(idx); idx = idx_dup; } fpl = AddOptFuncToList(IsDataAt, otn); fpl->type = RULE_OPTION_TYPE_IS_DATA_AT; /* attach it to the context node so that we can call each instance * individually */ fpl->context = (void *) idx; if (idx->flags & ISDATAAT_RELATIVE_FLAG) fpl->isRelative = 1; } /**************************************************************************** * * Function: IsDataAt(char *, IsDataAtData *, OptTreeNode *) * * Purpose: This is the function that is used to process the option keyword's * arguments and attach them to the rule's data structures. * * Arguments: data => argument data * idx => pointer to the processed argument storage * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ void IsDataAtParse(char *data, IsDataAtData *idx, OptTreeNode *otn) { char **toks; int num_toks; int i; char *cptr; char *endp; char *offset; if(!data) { FatalError("%s (%d): Bad arguments to IsDataAt: (null)\n", file_name,file_line); } toks = mSplit(data, ",", ISDATAAT_MAX_ARG, &num_toks, 0); if(num_toks > ISDATAAT_MAX_ARG || num_toks < 1) { FatalError("%s (%d): Bad arguments to IsDataAt: %s\n", file_name, file_line, data); } offset = toks[0]; if(*offset == '!') { idx->flags |= ISDATAAT_NOT_FLAG; offset++; while(isspace((int)*offset)) {offset++;} } /* set how many bytes to process from the packet */ if (isdigit(offset[0]) || offset[0] == '-') { idx->offset = strtol(offset, &endp, 10); idx->offset_var = -1; if(offset == endp) { FatalError("%s(%d): Unable to parse as byte value %s\n", file_name, file_line, toks[0]); } if(idx->offset > 65535) { FatalError("%s(%d): IsDataAt offset greater than max IPV4 packet size", file_name, file_line); } } else { if (bytemath_variable_name && (strcmp(bytemath_variable_name,offset) == 0)) idx->offset_var= BYTE_MATH_VAR_INDEX; else { idx->offset_var = GetVarByName(offset); if (idx->offset_var == BYTE_EXTRACT_NO_VAR) ParseError(BYTE_EXTRACT_INVALID_ERR_FMT, "isdataat", toks[0]); } } for (i=1; i< num_toks; i++) { cptr = toks[i]; while(isspace((int)*cptr)) {cptr++;} if(!strcasecmp(cptr, "relative")) { /* the offset is relative to the last pattern match */ idx->flags |= ISDATAAT_RELATIVE_FLAG; } else if(!strcasecmp(cptr, "rawbytes")) { /* the offset is to be applied to the non-normalized buffer */ idx->flags |= ISDATAAT_RAWBYTES_FLAG; } else { FatalError("%s(%d): unknown modifier \"%s\"\n", file_name, file_line, toks[1]); } } mSplitFree(&toks,num_toks); } /**************************************************************************** * * Function: IsDataAt(char *, OptTreeNode *, OptFpList *) * * Purpose: Use this function to perform the particular detection routine * that this rule keyword is supposed to encompass. * * Arguments: p => pointer to the decoded packet * otn => pointer to the current rule's OTN * fp_list => pointer to the function pointer list * * Returns: If the detection test fails, this function *must* return a zero! * On success, it calls the next function in the detection list * ****************************************************************************/ int IsDataAt(void *option_data, Packet *p) { IsDataAtData *isdata = (IsDataAtData *)option_data; int rval = DETECTION_OPTION_NO_MATCH; int dsize; const uint8_t *base_ptr, *end_ptr, *start_ptr; int search_start = 0; PROFILE_VARS; PREPROC_PROFILE_START(isDataAtPerfStats); if (!isdata) { PREPROC_PROFILE_END(isDataAtPerfStats); return rval; } /* Get values from byte_math/byte_extract variables, if present. */ if (isdata->offset_var >= 0 ) { if(isdata->offset_var == BYTE_MATH_VAR_INDEX ) isdata->offset = (int32_t) bytemath_variable; else { if (isdata->offset_var < NUM_BYTE_EXTRACT_VARS) GetByteExtractValue(&(isdata->offset), isdata->offset_var); } } if (isdata->flags & ISDATAAT_RAWBYTES_FLAG) { /* Rawbytes specified, force use of that buffer */ dsize = p->dsize; start_ptr = p->data; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Using RAWBYTES buffer!\n");); } else if (Is_DetectFlag(FLAG_ALT_DETECT)) { dsize = DetectBuffer.len; start_ptr = DetectBuffer.data; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Using Alternative Detect buffer!\n");); } else if(Is_DetectFlag(FLAG_ALT_DECODE)) { /* If normalized buffer available, use it... */ dsize = DecodeBuffer.len; start_ptr = DecodeBuffer.data; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Using Alternative Decode buffer!\n");); } else { if(IsLimitedDetect(p)) dsize = p->alt_dsize; else dsize = p->dsize; start_ptr = p->data; } base_ptr = start_ptr; end_ptr = start_ptr + dsize; if((isdata->flags & ISDATAAT_RELATIVE_FLAG) && doe_ptr) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Checking relative offset!\n");); /* Because doe_ptr can be "end" in the last match, * use end + 1 for upper bound * Bound checked also after offset is applied * */ if(!inBounds(start_ptr, end_ptr + 1, doe_ptr)) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "[*] isdataat bounds check failed..\n");); PREPROC_PROFILE_END(isDataAtPerfStats); return rval; } search_start = ( doe_ptr - start_ptr ) + isdata->offset; base_ptr = doe_ptr; } else { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "checking absolute offset %d\n", isdata->offset);); search_start = isdata->offset; base_ptr = start_ptr; } if ( search_start < 0 ) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "[*] isdataat bounds check failed..\n");); PREPROC_PROFILE_END(isDataAtPerfStats); return rval; } base_ptr = base_ptr + isdata->offset; if(inBounds(start_ptr, end_ptr, base_ptr)) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "[*] IsDataAt succeeded! there is data...\n");); rval = DETECTION_OPTION_MATCH; } if (isdata->flags & ISDATAAT_NOT_FLAG) { rval = !rval; } /* otherwise dump */ PREPROC_PROFILE_END(isDataAtPerfStats); return rval; } snort-2.9.15.1/src/detection-plugins/sp_isdataat.h0000644000175200017520000000304713571422607016745 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2003-2013 Sourcefire, Inc. ** ** Brian Caswell ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifndef __SP_ISDATAAT_H__ #define __SP_ISDATAAT_H__ #define ISDATAAT_RELATIVE_FLAG 0x01 #define ISDATAAT_RAWBYTES_FLAG 0x02 #define ISDATAAT_NOT_FLAG 0x04 #define ISDATAAT_MAX_ARG 3 typedef struct _IsDataAtData { uint32_t offset; /* byte location into the packet */ uint8_t flags; /* relative to the doe_ptr? */ /* rawbytes buffer? */ int8_t offset_var; /* index of byte_extract variable for offset */ } IsDataAtData; void SetupIsDataAt(void); uint32_t IsDataAtHash(void *d); int IsDataAtCompare(void *l, void *r); #endif /* __SP_ISDATAAT_H__ */ snort-2.9.15.1/src/detection-plugins/sp_pattern_match.c0000644000175200017520000030661413571422607020005 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * 06/07/2007 - tw * Commented out 'content-list' code since it's considered broken and there * are no plans to fix it */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #ifdef HAVE_STRINGS_H # include #endif #ifdef DEBUG_MSGS # include #endif #include "sf_types.h" #include "sp_pattern_match.h" #include "sp_replace.h" #include "snort_bounds.h" #include "rules.h" #include "treenodes.h" #include "plugbase.h" #include "snort_debug.h" #include "mstring.h" #include "hashstring.h" #include "util.h" #include "parser.h" #include "plugin_enum.h" #include "checksum.h" #include "sfhashfcn.h" #include "spp_httpinspect.h" #include "snort.h" #include "profiler.h" #include "sfhashfcn.h" #include "detection_options.h" #include "sp_byte_extract.h" #include "sp_byte_math.h" #include "detection_util.h" #include "sf_sechash.h" /******************************************************************** * Macros ********************************************************************/ #define MAX_PATTERN_SIZE 2048 #define PM_FP_ONLY "only" /******************************************************************** * Global variables ********************************************************************/ #ifdef PERF_PROFILING PreprocStats contentPerfStats; PreprocStats uricontentPerfStats; #endif int lastType = PLUGIN_PATTERN_MATCH; #if 0 /* For OR patterns - not currently used */ int list_file_line; /* current line being processed in the list file */ #endif /******************************************************************** * Extern variables ********************************************************************/ #ifdef PERF_PROFILING extern PreprocStats ruleOTNEvalPerfStats; #endif /******************************************************************** * Private function prototypes ********************************************************************/ static void PayloadSearchInit(struct _SnortConfig *, char *, OptTreeNode *, int); static void PayloadSearchUri(struct _SnortConfig *, char *, OptTreeNode *, int); static void PayloadSearchHttpMethod(struct _SnortConfig *, char *, OptTreeNode *, int); static void PayloadSearchHttpUri(struct _SnortConfig *, char *, OptTreeNode *, int); static void PayloadSearchHttpHeader(struct _SnortConfig *, char *, OptTreeNode *, int); static void PayloadSearchHttpCookie(struct _SnortConfig *, char *, OptTreeNode *, int); static void PayloadSearchHttpBody(struct _SnortConfig *, char *, OptTreeNode *, int); static void PayloadSearchHttpRawUri(struct _SnortConfig *, char *, OptTreeNode *, int); static void PayloadSearchHttpRawHeader(struct _SnortConfig *, char *, OptTreeNode *, int); //static void PayloadSearchHttpRawBody(struct _SnortConfig *, char *, OptTreeNode *, int); static void PayloadSearchHttpRawCookie(struct _SnortConfig *, char *, OptTreeNode *, int); static void PayloadSearchHttpStatCode(struct _SnortConfig *, char *, OptTreeNode *, int); static void PayloadSearchHttpStatMsg(struct _SnortConfig *, char *, OptTreeNode *, int); static void PayloadSearchOffset(struct _SnortConfig *, char *, OptTreeNode *, int); static void PayloadSearchDepth(struct _SnortConfig *, char *, OptTreeNode *, int); static void PayloadSearchDistance(struct _SnortConfig *, char *, OptTreeNode *, int); static void PayloadSearchWithin(struct _SnortConfig *, char *, OptTreeNode *, int); static void PayloadSearchNocase(struct _SnortConfig *, char *, OptTreeNode *, int); static void PayloadSearchRawbytes(struct _SnortConfig *, char *, OptTreeNode *, int); static void PayloadSearchFastPattern(struct _SnortConfig *, char *, OptTreeNode *, int); static inline int HasFastPattern(OptTreeNode *, int); static int32_t ParseInt(const char *, const char *); static inline PatternMatchData * GetLastPmdError(OptTreeNode *, int, const char *); static inline PatternMatchData * GetLastPmd(OptTreeNode *, int); static void ValidateHttpContentModifiers(struct _SnortConfig *, PatternMatchData *); static void MovePmdToUriDsList(OptTreeNode *, PatternMatchData *); static char *PayloadExtractParameter(char *, int *); static inline void ValidateContent(struct _SnortConfig *, PatternMatchData *, int); static unsigned int GetMaxJumpSize(char *, int); static int uniSearch(const char *, int, PatternMatchData *); static int uniSearchReal(const char *data, int dlen, PatternMatchData *pmd, int nocase); static int uniSearchHash(const char *data, int dlen, PatternMatchData *pmd); static void PayloadSearchProtected(struct _SnortConfig *, char *, OptTreeNode *, int); static void PayloadSearchHash(struct _SnortConfig *, char *, OptTreeNode *, int); static void PayloadSearchLength(struct _SnortConfig *, char *, OptTreeNode *, int); #if 0 /* Not currently used - DO NOT REMOVE */ static inline int computeDepth(int dlen, PatternMatchData * pmd); static int uniSearchREG(char * data, int dlen, PatternMatchData * pmd); #endif #if 0 static const char *format_uri_buffer_str(int, int, char *); static void PayloadSearchListInit(char *, OptTreeNode *, int); static void ParseContentListFile(char *, OptTreeNode *, int); static void PrintDupDOTPmds(PatternMatchData *pmd, PatternMatchData *pmd_dup, option_type_t type) #endif /******************************************************************** * Setup and parsing functions ********************************************************************/ void SetupPatternMatch(void) { /* initial pmd setup options */ RegisterRuleOption("content", PayloadSearchInit, NULL, OPT_TYPE_DETECTION, NULL); RegisterRuleOption("uricontent", PayloadSearchUri, NULL, OPT_TYPE_DETECTION, NULL); RegisterRuleOption("protected_content", PayloadSearchProtected, NULL, OPT_TYPE_DETECTION, NULL); /* http content modifiers */ RegisterRuleOption("http_method", PayloadSearchHttpMethod, NULL, OPT_TYPE_DETECTION, NULL); RegisterRuleOption("http_uri", PayloadSearchHttpUri, NULL, OPT_TYPE_DETECTION, NULL); RegisterRuleOption("http_header", PayloadSearchHttpHeader, NULL, OPT_TYPE_DETECTION, NULL); RegisterRuleOption("http_cookie", PayloadSearchHttpCookie, NULL, OPT_TYPE_DETECTION, NULL); RegisterRuleOption("http_client_body", PayloadSearchHttpBody, NULL, OPT_TYPE_DETECTION, NULL); RegisterRuleOption("http_raw_uri", PayloadSearchHttpRawUri, NULL, OPT_TYPE_DETECTION, NULL); RegisterRuleOption("http_raw_header", PayloadSearchHttpRawHeader, NULL, OPT_TYPE_DETECTION, NULL); /*RegisterRuleOption("http_raw_client_body", PayloadSearchHttpRawBody, NULL, OPT_TYPE_DETECTION, NULL);*/ RegisterRuleOption("http_raw_cookie", PayloadSearchHttpRawCookie, NULL, OPT_TYPE_DETECTION, NULL); RegisterRuleOption("http_stat_code", PayloadSearchHttpStatCode, NULL, OPT_TYPE_DETECTION, NULL); RegisterRuleOption("http_stat_msg", PayloadSearchHttpStatMsg, NULL, OPT_TYPE_DETECTION, NULL); /* pattern offsets and depths */ RegisterRuleOption("offset", PayloadSearchOffset, NULL, OPT_TYPE_DETECTION, NULL); RegisterRuleOption("depth", PayloadSearchDepth, NULL, OPT_TYPE_DETECTION, NULL); /* distance and within are offset and depth, but relative to last match */ RegisterRuleOption("distance", PayloadSearchDistance, NULL, OPT_TYPE_DETECTION, NULL); RegisterRuleOption("within", PayloadSearchWithin, NULL, OPT_TYPE_DETECTION, NULL); /* other modifiers */ RegisterRuleOption("hash", PayloadSearchHash, NULL, OPT_TYPE_DETECTION, NULL); RegisterRuleOption("length", PayloadSearchLength, NULL, OPT_TYPE_DETECTION, NULL); RegisterRuleOption("nocase", PayloadSearchNocase, NULL, OPT_TYPE_DETECTION, NULL); RegisterRuleOption("rawbytes", PayloadSearchRawbytes, NULL, OPT_TYPE_DETECTION, NULL); RegisterRuleOption("fast_pattern", PayloadSearchFastPattern, NULL, OPT_TYPE_DETECTION, NULL); RegisterRuleOption("replace", PayloadReplaceInit, NULL, OPT_TYPE_DETECTION, NULL); #if 0 /* Not implemented yet */ RegisterRuleOption("content-list", PayloadSearchListInit, NULL, OPT_TYPE_DETECTION, NULL); #endif #ifdef PERF_PROFILING RegisterPreprocessorProfile("content", &contentPerfStats, 3, &ruleOTNEvalPerfStats, NULL); RegisterPreprocessorProfile("uricontent", &uricontentPerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Plugin: PatternMatch Initialized!\n");); } static void PayloadSearchInit(struct _SnortConfig *sc, char *data, OptTreeNode * otn, int protocol) { OptFpList *fpl; PatternMatchData *pmd; char *data_end; char *data_dup; char *opt_data; int opt_len = 0; char *next_opt; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "In PayloadSearchInit()\n");); /* whack a new node onto the list */ pmd = NewNode(otn, PLUGIN_PATTERN_MATCH); lastType = PLUGIN_PATTERN_MATCH; if (!data) ParseError("No Content Pattern specified!"); data_dup = SnortStrdup(data); data_end = data_dup + strlen(data_dup); opt_data = PayloadExtractParameter(data_dup, &opt_len); /* set up the pattern buffer */ ParsePattern(opt_data, otn, PLUGIN_PATTERN_MATCH); next_opt = opt_data + opt_len; /* link the plugin function in to the current OTN */ fpl = AddOptFuncToList(CheckANDPatternMatch, otn); fpl->type = RULE_OPTION_TYPE_CONTENT; pmd->buffer_func = CHECK_AND_PATTERN_MATCH; fpl->context = pmd; pmd->fpl = fpl; // if content is followed by any comma separated options, // we have to parse them here. content related options // separated by semicolons go straight to the callbacks. while (next_opt < data_end) { char **opts; /* dbl ptr for mSplit call, holds rule tokens */ int num_opts; /* holds number of tokens found by mSplit */ char* opt1; next_opt++; if (next_opt == data_end) break; opt_len = 0; opt_data = PayloadExtractParameter(next_opt, &opt_len); if (!opt_data) break; next_opt = opt_data + opt_len; opts = mSplit(opt_data, " \t", 2, &num_opts, 0); if (!opts) continue; opt1 = (num_opts == 2) ? opts[1] : NULL; if (!strcasecmp(opts[0], "offset")) { PayloadSearchOffset(sc, opt1, otn, protocol); } else if (!strcasecmp(opts[0], "depth")) { PayloadSearchDepth(sc, opt1, otn, protocol); } else if (!strcasecmp(opts[0], "nocase")) { PayloadSearchNocase(sc, opt1, otn, protocol); } else if (!strcasecmp(opts[0], "rawbytes")) { PayloadSearchRawbytes(sc, opt1, otn, protocol); } else if (!strcasecmp(opts[0], "http_uri")) { PayloadSearchHttpUri(sc, opt1, otn, protocol); } else if (!strcasecmp(opts[0], "http_client_body")) { PayloadSearchHttpBody(sc, opt1, otn, protocol); } else if (!strcasecmp(opts[0], "http_header")) { PayloadSearchHttpHeader(sc, opt1, otn, protocol); } else if (!strcasecmp(opts[0], "http_method")) { PayloadSearchHttpMethod(sc, opt1, otn, protocol); } else if (!strcasecmp(opts[0], "http_cookie")) { PayloadSearchHttpCookie(sc, opt1, otn, protocol); } else if (!strcasecmp(opts[0], "http_raw_uri")) { PayloadSearchHttpRawUri(sc, opt1, otn, protocol); } else if (!strcasecmp(opts[0], "http_raw_header")) { PayloadSearchHttpRawHeader(sc, opt1, otn, protocol); } else if (!strcasecmp(opts[0], "http_raw_cookie")) { PayloadSearchHttpRawCookie(sc, opt1, otn, protocol); } else if (!strcasecmp(opts[0], "http_stat_code")) { PayloadSearchHttpStatCode(sc, opt1, otn, protocol); } else if (!strcasecmp(opts[0], "http_stat_msg")) { PayloadSearchHttpStatMsg(sc, opt1, otn, protocol); } else if (!strcasecmp(opts[0], "fast_pattern")) { PayloadSearchFastPattern(sc, opt1, otn, protocol); } else if (!strcasecmp(opts[0], "distance")) { PayloadSearchDistance(sc, opt1, otn, protocol); } else if (!strcasecmp(opts[0], "within")) { PayloadSearchWithin(sc, opt1, otn, protocol); } else if (!strcasecmp(opts[0], "replace")) { PayloadReplaceInit(sc, opt1, otn, protocol); } else { ParseError("Invalid Content parameter specified!"); } mSplitFree(&opts, num_opts); } free(data_dup); if(pmd->use_doe == 1) fpl->isRelative = 1; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "OTN function PatternMatch Added to rule!\n");); } static void PayloadSearchUri(struct _SnortConfig *sc, char *data, OptTreeNode * otn, int protocol) { PatternMatchData *pmd = NewNode(otn, PLUGIN_PATTERN_MATCH_URI); OptFpList *fpl; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "In PayloadSearchUri()\n");); lastType = PLUGIN_PATTERN_MATCH_URI; /* set up the pattern buffer */ ParsePattern(data, otn, PLUGIN_PATTERN_MATCH_URI); pmd->http_buffer = HTTP_BUFFER_URI; /* link the plugin function in to the current OTN */ fpl = AddOptFuncToList(CheckUriPatternMatch, otn); fpl->type = RULE_OPTION_TYPE_CONTENT_URI; pmd->buffer_func = CHECK_URI_PATTERN_MATCH; fpl->context = pmd; pmd->fpl = fpl; if (pmd->use_doe == 1) fpl->isRelative = 1; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "OTN function PatternMatch Added to rule!\n");); } void PayloadSearchProtected(struct _SnortConfig *sc, char *data, OptTreeNode * otn, int protocol) { OptFpList *fpl; PatternMatchData *pmd; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "In PayloadSearchProtected()\n");); /* whack a new node onto the list */ pmd = NewNode(otn, PLUGIN_PATTERN_MATCH); lastType = PLUGIN_PATTERN_MATCH; if (!data) ParseError("No Protected Content Pattern specified!"); /* The default secure hash type is set in the SnortConfig */ pmd->pattern_type = sc->Default_Protected_Content_Hash_Type; /* set up the pattern buffer */ ParseProtectedPattern(data, otn, PLUGIN_PATTERN_MATCH); /* link the plugin function in to the current OTN */ fpl = AddOptFuncToList(CheckANDPatternMatch, otn); fpl->type = RULE_OPTION_TYPE_CONTENT; pmd->buffer_func = CHECK_AND_PATTERN_MATCH; pmd->protected_pattern = true; fpl->context = pmd; pmd->fpl = fpl; if(pmd->use_doe == 1) fpl->isRelative = 1; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "OTN function PatternMatchProtected Added to rule!\n");); } static void PayloadSearchHttpMethod(struct _SnortConfig *sc, char *data, OptTreeNode * otn, int protocol) { PatternMatchData *pmd = GetLastPmdError(otn, lastType, "http_method"); if (data != NULL) ParseError("'http_method' does not take an argument"); if ( pmd->http_buffer ) ParseWarning("at most one http buffer can be specified per content option"); pmd->http_buffer = HTTP_BUFFER_METHOD; MovePmdToUriDsList(otn, pmd); } static void PayloadSearchHttpUri(struct _SnortConfig *sc, char *data, OptTreeNode * otn, int protocol) { PatternMatchData *pmd = GetLastPmdError(otn, lastType, "http_uri"); if (data != NULL) ParseError("'http_uri' does not take an argument"); if ( pmd->http_buffer ) ParseWarning("at most one http buffer can be specified per content option"); pmd->http_buffer = HTTP_BUFFER_URI; MovePmdToUriDsList(otn, pmd); } static void PayloadSearchHttpHeader(struct _SnortConfig *sc, char *data, OptTreeNode * otn, int protocol) { PatternMatchData *pmd = GetLastPmdError(otn, lastType, "http_header"); if (data != NULL) ParseError("'http_header' does not take an argument"); if ( pmd->http_buffer ) ParseWarning("at most one http buffer can be specified per content option"); pmd->http_buffer = HTTP_BUFFER_HEADER; MovePmdToUriDsList(otn, pmd); } static void PayloadSearchHttpCookie(struct _SnortConfig *sc, char *data, OptTreeNode * otn, int protocol) { PatternMatchData *pmd = GetLastPmdError(otn, lastType, "http_cookie"); if (data != NULL) ParseError("'http_cookie' does not take an argument"); if ( pmd->http_buffer ) ParseWarning("at most one http buffer can be specified per content option"); pmd->http_buffer = HTTP_BUFFER_COOKIE; MovePmdToUriDsList(otn, pmd); } static void PayloadSearchHttpBody(struct _SnortConfig *sc, char *data, OptTreeNode * otn, int protocol) { PatternMatchData *pmd = GetLastPmdError(otn, lastType, "http_client_body"); if (data != NULL) ParseError("'http_client_body' does not take an argument"); if ( pmd->http_buffer ) ParseWarning("at most one http buffer can be specified per content option"); pmd->http_buffer = HTTP_BUFFER_CLIENT_BODY; MovePmdToUriDsList(otn, pmd); } static void PayloadSearchHttpRawUri(struct _SnortConfig *sc, char *data, OptTreeNode * otn, int protocol) { PatternMatchData *pmd = GetLastPmdError(otn, lastType, "http_raw_uri"); if (data != NULL) ParseError("'http_raw_uri' does not take an argument"); if ( pmd->http_buffer ) ParseWarning("at most one http buffer can be specified per content option"); pmd->http_buffer = HTTP_BUFFER_RAW_URI; MovePmdToUriDsList(otn, pmd); } static void PayloadSearchHttpRawHeader(struct _SnortConfig *sc, char *data, OptTreeNode * otn, int protocol) { PatternMatchData *pmd = GetLastPmdError(otn, lastType, "http_raw_header"); if (data != NULL) ParseError("'http_raw_header' does not take an argument"); if ( pmd->http_buffer ) ParseWarning("at most one http buffer can be specified per content option"); pmd->http_buffer = HTTP_BUFFER_RAW_HEADER; MovePmdToUriDsList(otn, pmd); } static void PayloadSearchHttpRawCookie(struct _SnortConfig *sc, char *data, OptTreeNode * otn, int protocol) { PatternMatchData *pmd = GetLastPmdError(otn, lastType, "http_raw_cookie"); if (data != NULL) ParseError("'http_raw_cookie' does not take an argument"); if ( pmd->http_buffer ) ParseWarning("at most one http buffer can be specified per content option"); pmd->http_buffer = HTTP_BUFFER_RAW_COOKIE; MovePmdToUriDsList(otn, pmd); } static void PayloadSearchHttpStatCode(struct _SnortConfig *sc, char *data, OptTreeNode * otn, int protocol) { PatternMatchData *pmd = GetLastPmdError(otn, lastType, "http_stat_code"); if (data != NULL) ParseError("'http_stat_code' does not take an argument"); if ( pmd->http_buffer ) ParseWarning("at most one http buffer can be specified per content option"); pmd->http_buffer = HTTP_BUFFER_STAT_CODE; MovePmdToUriDsList(otn, pmd); } static void PayloadSearchHttpStatMsg(struct _SnortConfig *sc, char *data, OptTreeNode * otn, int protocol) { PatternMatchData *pmd = GetLastPmdError(otn, lastType, "http_stat_msg"); if (data != NULL) ParseError("'http_stat_msg' does not take an argument"); if ( pmd->http_buffer ) ParseWarning("at most one http buffer can be specified per content option"); pmd->http_buffer = HTTP_BUFFER_STAT_MSG; MovePmdToUriDsList(otn, pmd); } typedef enum { CMF_DISTANCE = 0x1, CMF_WITHIN = 0x2, CMF_OFFSET = 0x4, CMF_DEPTH = 0x8, CMF_PROT = 0x10 } ContentModifierFlags; static unsigned GetCMF (PatternMatchData* pmd) { unsigned cmf = 0; if ( (pmd->distance != 0) || (pmd->distance_var != -1) ) cmf |= CMF_DISTANCE; if ( (pmd->within != PMD_WITHIN_UNDEFINED) || (pmd->within_var != -1) ) cmf |= CMF_WITHIN; if ( (pmd->offset != 0) || (pmd->offset_var != -1) ) cmf |= CMF_OFFSET; if ( (pmd->depth != 0) || (pmd->depth_var != -1) ) cmf |= CMF_DEPTH; if ( pmd->protected_pattern ) cmf |= CMF_PROT; return cmf; } #define BAD_DISTANCE (CMF_DISTANCE | CMF_OFFSET | CMF_DEPTH) #define BAD_WITHIN (CMF_WITHIN | CMF_OFFSET | CMF_DEPTH | CMF_PROT) #define BAD_OFFSET (CMF_OFFSET | CMF_DISTANCE | CMF_WITHIN) #define BAD_DEPTH (CMF_DEPTH | CMF_DISTANCE | CMF_WITHIN | CMF_PROT) static void PayloadSearchOffset(struct _SnortConfig *sc, char *data, OptTreeNode * otn, int protocol) { PatternMatchData *pmd = GetLastPmdError(otn, lastType, "offset"); if ( GetCMF(pmd) & BAD_OFFSET ) ParseError("offset can't be used with itself, distance, or within"); if (data == NULL) ParseError("Missing argument to 'offset' option"); if (isdigit(data[0]) || data[0] == '-') { pmd->offset = ParseInt(data, "offset"); } else { if (bytemath_variable_name && (strcmp(bytemath_variable_name,data) == 0)) pmd->offset_var= BYTE_MATH_VAR_INDEX; else { pmd->offset_var = GetVarByName(data); if (pmd->offset_var == BYTE_EXTRACT_NO_VAR) ParseError(BYTE_EXTRACT_INVALID_ERR_FMT, "offset", data); } } DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "Pattern offset = %d\n", pmd->offset);); } static void PayloadSearchDepth(struct _SnortConfig *sc, char *data, OptTreeNode * otn, int protocol) { PatternMatchData *pmd = GetLastPmdError(otn, lastType, "depth"); if ( GetCMF(pmd) & BAD_DEPTH ) ParseError("depth can't be used with itself, protected, distance, or within"); if (data == NULL) ParseError("Missing argument to 'depth' option"); if (isdigit(data[0]) || data[0] == '-') { pmd->depth = ParseInt(data, "depth"); /* check to make sure that this the depth allows this rule to fire */ if ((!pmd->protected_pattern) && (pmd->depth < (int)pmd->pattern_size)) { ParseError("The depth (%d) is less than the size of the content(%u)!", pmd->depth, pmd->pattern_size); } } else { if (bytemath_variable_name && (strcmp(bytemath_variable_name,data) == 0)) pmd->depth_var= BYTE_MATH_VAR_INDEX; else { pmd->depth_var = GetVarByName(data); if (pmd->depth_var == BYTE_EXTRACT_NO_VAR) ParseError(BYTE_EXTRACT_INVALID_ERR_FMT, "depth", data); } } DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Pattern depth = %d\n", pmd->depth);); } static void PayloadSearchDistance(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { PatternMatchData *pmd = GetLastPmdError(otn, lastType, "distance"); if ( GetCMF(pmd) & BAD_DISTANCE ) ParseError("distance can't be used with itself, offset, or depth"); if (data == NULL) ParseError("Missing argument to 'distance' option"); if (isdigit(data[0]) || data[0] == '-') { pmd->distance = ParseInt(data, "distance"); } else { if (bytemath_variable_name && (strcmp(bytemath_variable_name,data) == 0)) pmd->distance_var= BYTE_MATH_VAR_INDEX; else { pmd->distance_var = GetVarByName(data); if (pmd->distance_var == BYTE_EXTRACT_NO_VAR) ParseError(BYTE_EXTRACT_INVALID_ERR_FMT, "distance", data); } } DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Pattern distance = %d\n", pmd->distance);); /* Only do a relative search if this is a normal content match. */ if (lastType == PLUGIN_PATTERN_MATCH || lastType == PLUGIN_PATTERN_MATCH_URI) { pmd->use_doe = 1; pmd->fpl->isRelative = 1; } } static void PayloadSearchWithin(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { PatternMatchData *pmd = GetLastPmdError(otn, lastType, "within"); if ( GetCMF(pmd) & BAD_WITHIN ) ParseError("within can't be used with itself, protected, offset, or depth"); if (data == NULL) ParseError("Missing argument to 'within' option"); if (isdigit(data[0]) || data[0] == '-') { pmd->within = ParseInt(data, "within"); if (!pmd->protected_pattern && (pmd->within < pmd->pattern_size)) ParseError("within (%d) is smaller than size of pattern", pmd->within); } else { if (bytemath_variable_name && (strcmp(bytemath_variable_name,data) == 0)) pmd->within_var= BYTE_MATH_VAR_INDEX; else { pmd->within_var = GetVarByName(data); if (pmd->within_var == BYTE_EXTRACT_NO_VAR) ParseError(BYTE_EXTRACT_INVALID_ERR_FMT, "within", data); } } DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Pattern within = %d\n", pmd->within);); /* Only do a relative search if this is a normal content match. */ if (lastType == PLUGIN_PATTERN_MATCH || lastType == PLUGIN_PATTERN_MATCH_URI) { pmd->use_doe = 1; pmd->fpl->isRelative = 1; } } static void PayloadSearchNocase(struct _SnortConfig *sc, char *data, OptTreeNode * otn, int protocol) { unsigned int i; PatternMatchData *pmd = GetLastPmdError(otn, lastType, "nocase"); if (data != NULL) ParseError("'nocase' does not take an argument"); if (pmd->protected_pattern) ParseError("'nocase' not useable with protected content"); for (i = 0; i < pmd->pattern_size; i++) pmd->pattern_buf[i] = toupper((int)pmd->pattern_buf[i]); pmd->nocase = 1; pmd->search = uniSearchCI; make_precomp(pmd); } static void PayloadSearchRawbytes(struct _SnortConfig *sc, char *data, OptTreeNode * otn, int protocol) { PatternMatchData *pmd = GetLastPmdError(otn, lastType, "rawbytes"); if (data != NULL) ParseError("'rawbytes' does not take an argument"); /* mark this as inspecting a raw pattern match rather than a * decoded application buffer */ pmd->rawbytes = 1; } static void PayloadSearchFastPattern(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { PatternMatchData *pmd = GetLastPmdError(otn, lastType, "fast_pattern"); /* There can only be one fast pattern content in the rule, whether * normal, http or other */ if (pmd->fp) { ParseError("Cannot set fast_pattern modifier more than once " "for the same \"content\"."); } if( pmd->protected_pattern ) ParseError("Cannot set fast_pattern modifier with protected content"); if (HasFastPattern(otn, PLUGIN_PATTERN_MATCH)) ParseError("Can only use the fast_pattern modifier once in a rule."); if (HasFastPattern(otn, PLUGIN_PATTERN_MATCH_URI)) ParseError("Can only use the fast_pattern modifier once in a rule."); //if (HasFastPattern(otn, PLUGIN_PATTERN_MATCH_OR)) // ParseError("Can only use the fast_pattern modifier once in a rule."); pmd->fp = 1; if (data != NULL) { char *error_str = "Rule option \"fast_pattern\": Invalid parameter: " "\"%s\". Valid parameters are: \"only\" | ,. " "Offset and length must be integers less than 65536, offset cannot " "be negative, length must be positive and (offset + length) must " "evaluate to less than or equal to the actual pattern length. " "Pattern length: %u"; if (isdigit((int)*data)) { /* Specifying offset and length of pattern to use for * fast pattern matcher */ long int offset, length; char *endptr; char **toks; int num_toks; toks = mSplit(data, ",", 0, &num_toks, 0); if (num_toks != 2) { mSplitFree(&toks, num_toks); ParseError(error_str, data, pmd->pattern_size); } offset = SnortStrtol(toks[0], &endptr, 0); if ((errno == ERANGE) || (*endptr != '\0') || (offset < 0) || (offset > UINT16_MAX)) { mSplitFree(&toks, num_toks); ParseError(error_str, data, pmd->pattern_size); } length = SnortStrtol(toks[1], &endptr, 0); if ((errno == ERANGE) || (*endptr != '\0') || (length <= 0) || (length > UINT16_MAX)) { mSplitFree(&toks, num_toks); ParseError(error_str, data, pmd->pattern_size); } mSplitFree(&toks, num_toks); if ((int)pmd->pattern_size < (offset + length)) ParseError(error_str, data, pmd->pattern_size); pmd->fp_offset = (uint16_t)offset; pmd->fp_length = (uint16_t)length; } else { /* Specifies that this content should only be used for * fast pattern matching */ if (strcasecmp(data, PM_FP_ONLY) != 0) ParseError(error_str, data, pmd->pattern_size); pmd->fp_only = 1; } } } static void PayloadSearchHash(struct _SnortConfig *sc, char *data, OptTreeNode * otn, int protocol) { PatternMatchData *pmd = GetLastPmdError(otn, lastType, "hash"); if (data == NULL) ParseError("Missing argument to 'hash' option"); if (!pmd->protected_pattern) ParseError("hash modifier is only valid with protected_content"); /* strip any whitespace for good measure */ while( (*data != '\0') && isspace(*data) ) data += 1; if( (pmd->pattern_type = SecHash_Name2Type((const char *)data)) == SECHASH_NONE ) ParseError("Bad hash type: '%s'", data); DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "Hash type = %d\n", pmd->pattern_type);); } static void PayloadSearchLength(struct _SnortConfig *sc, char *data, OptTreeNode * otn, int protocol) { PatternMatchData *pmd = GetLastPmdError(otn, lastType, "length"); if (data == NULL) ParseError("Missing argument to 'length' option"); if (!pmd->protected_pattern) ParseError("length modifier is only valid with protected_content"); if (isdigit(data[0])) { pmd->protected_length = ParseInt(data, "length"); if( (pmd->protected_length <= 0) || (pmd->protected_length > 65536)) ParseError("length must be greater than zero"); } else { ParseError("Illegal length: %s", data); } DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Plaintext length = %d\n", pmd->protected_length);); } static inline int HasFastPattern(OptTreeNode *otn, int list_type) { PatternMatchData *tmp; if ((otn == NULL) || (otn->ds_list[list_type] == NULL)) return 0; for (tmp = otn->ds_list[list_type]; tmp != NULL; tmp = tmp->next) { if (tmp->fp) return 1; } return 0; } PatternMatchData * NewNode(OptTreeNode *otn, int type) { PatternMatchData *pmd = NULL; if (otn->ds_list[type] == NULL) { otn->ds_list[type] = (PatternMatchData *)SnortAlloc(sizeof(PatternMatchData)); pmd = otn->ds_list[type]; } else { pmd = GetLastPmd(otn, type); if (pmd != NULL) { pmd->next = (PatternMatchData *)SnortAlloc(sizeof(PatternMatchData)); pmd->next->prev = pmd; pmd = pmd->next; } else { return NULL; } } /* Set any non-zero default values here. */ pmd->offset_var = BYTE_EXTRACT_NO_VAR; pmd->depth_var = BYTE_EXTRACT_NO_VAR; pmd->distance_var = BYTE_EXTRACT_NO_VAR; pmd->within_var = BYTE_EXTRACT_NO_VAR; pmd->within = PMD_WITHIN_UNDEFINED; pmd->protected_pattern = false; pmd->protected_length = 0; return pmd; } void PatternMatchFree(void *d) { PatternMatchData *pmd = (PatternMatchData *)d; if (pmd == NULL) return; (void)RemovePmdFromList(pmd); if (pmd->pattern_buf) free(pmd->pattern_buf); if (pmd->replace_buf) free(pmd->replace_buf); if(pmd->skip_stride) free(pmd->skip_stride); if(pmd->shift_stride) free(pmd->shift_stride); free(pmd); } static int32_t ParseInt(const char* data, const char* tag) { int32_t value = 0; char *endptr = NULL; value = SnortStrtol(data, &endptr, 10); if (*endptr) ParseError("Invalid '%s' format.", tag); if (errno == ERANGE) ParseError("Range problem on '%s' value.", tag); if ((value > 65535) || (value < -65535)) ParseError("'%s' must in -65535:65535", tag); return value; } /* Used for content modifiers that are used as rule options - need to get the * last pmd which is the one they are modifying. If there isn't a last pmd * error that a content must be specified before the modifier */ static inline PatternMatchData * GetLastPmdError(OptTreeNode *otn, int type, const char *option) { PatternMatchData *pmd = GetLastPmd(otn, type); if (pmd == NULL) { ParseError("Please place \"content\" rules before \"%s\" modifier", option == NULL ? "unknown" : option); } return pmd; } /* Gets the last pmd in the ds_list specified */ static inline PatternMatchData * GetLastPmd(OptTreeNode *otn, int type) { PatternMatchData *pmd; if ((otn == NULL) || (otn->ds_list[type] == NULL)) return NULL; for (pmd = otn->ds_list[type]; pmd->next != NULL; pmd = pmd->next); return pmd; } static void ValidateProtectedContentModifiers(struct _SnortConfig *sc, PatternMatchData *pmd) { unsigned int length; if (pmd == NULL) ParseError("Please place \"content\" rules before protected content modifiers"); if( (length = SecHash_Type2Length(pmd->pattern_type)) == 0 ) ParseError("Bad pattern type"); if( pmd->pattern_size != length ) ParseError("Bad protected pattern hash digest length"); /* We NEED a specified pattern length (for this implementation) */ if( (pmd->protected_length <= 0) || (pmd->protected_length > 65536)) ParseError("No length or invalid length specified for protected_content rule"); /* At this point, we have a properly specified protected content rule with a pattern length. Since have the pattern size, we can place it in ->pattern_size for the runtime processing. If/when protected content searching expands beyond fixed ('specified') patterns, this approach needs to be revisted. */ pmd->pattern_size = pmd->protected_length; } /* Options that can't be used with http content modifiers. Additionally * http_inspect preprocessor needs to be enabled */ static void ValidateHttpContentModifiers(struct _SnortConfig *sc, PatternMatchData *pmd) { if (pmd == NULL) ParseError("Please place \"content\" rules before http content modifiers"); /* TBD-EDM - verify this is handled correctly */ #if 0 if (!IsPreprocEnabled(sc, PP_HTTPINSPECT)) { ParseError("Please enable the HTTP Inspect preprocessor " "before using the http content modifiers"); } #endif if (pmd->replace_buf != NULL) { ParseError("\"replace\" option is not supported in conjunction with " "http content modifiers"); } if (pmd->rawbytes == 1) { ParseError("Cannot use 'rawbytes' and http content as modifiers for " "the same \"content\""); } } /* This is used if we get an http content modifier, since specifying "content" * defaults to the PLUGIN_PATTERN_MATCH list. We need to move the pmd to the * PLUGIN_PATTERN_MATCH_URI list */ static void MovePmdToUriDsList(OptTreeNode *otn, PatternMatchData *pmd) { int type = PLUGIN_PATTERN_MATCH_URI; /* It's not currently in the correct list */ if (lastType != type) { /* Just in case it's moved from the middle of the list */ if (pmd->prev != NULL) pmd->prev->next = pmd->next; if (pmd->next != NULL) pmd->next->prev = pmd->prev; /* Reset pointers */ pmd->next = NULL; pmd->prev = NULL; if (otn->ds_list[type] == NULL) { otn->ds_list[type] = pmd; } else { /* Make it the last in the URI list */ PatternMatchData *tmp; for (tmp = otn->ds_list[type]; tmp->next != NULL; tmp = tmp->next); tmp->next = pmd; pmd->prev = tmp; } /* Set the last type to the URI list */ lastType = type; /* Reset these to URI type */ pmd->fpl->OptTestFunc = CheckUriPatternMatch; pmd->fpl->type = RULE_OPTION_TYPE_CONTENT_URI; pmd->buffer_func = CHECK_URI_PATTERN_MATCH; } } #if 0 /* Not currently used */ static void PrintDupDOTPmds(PatternMatchData *pmd, PatternMatchData *pmd_dup, option_type_t type) { int i; if ((pmd == NULL) || (pmd_dup == NULL)) return; LogMessage("Duplicate %sContent:\n" "%d %d %d %d %d %d %d %d %d %d\n" "%d %d %d %d %d %d %d %d %d %d\n", option_type == RULE_OPTION_TYPE_CONTENT ? "" : "Uri", pmd->exception_flag, pmd->offset, pmd->depth, pmd->distance, pmd->within, pmd->rawbytes, pmd->nocase, pmd->use_doe, pmd->http_buffer, pmd->pattern_max_jump_size, pmd_dup->exception_flag, pmd_dup->offset, pmd_dup->depth, pmd_dup->distance, pmd_dup->within, pmd_dup->rawbytes, pmd_dup->nocase, pmd_dup->use_doe, pmd_dup->http_buffer, pmd_dup->pattern_max_jump_size); for (i = 0; i < pmd->pattern_size; i++) LogMessage("0x%x 0x%x", pmd->pattern_buf[i], pmd_dup->pattern_buf[i]); LogMessage("\n"); for (i = 0; i < pmd->replace_size; i++) LogMessage("0x%x 0x%x", pmd->replace_buf[i], pmd_dup->replace_buf[i]); LogMessage("\n"); LogMessage("\n"); } #endif /******************************************************************** * Functions for detection option tree hashing and comparison * and other detection option tree uses ********************************************************************/ uint32_t PatternMatchHash(void *d) { uint32_t a,b,c,tmp; unsigned int i,j,k,l; PatternMatchData *pmd = (PatternMatchData *)d; a = pmd->exception_flag; b = pmd->offset; c = pmd->depth; mix(a,b,c); a += pmd->distance; b += pmd->within; c += pmd->rawbytes; mix(a,b,c); a += pmd->nocase; b += pmd->use_doe; c += pmd->http_buffer; mix(a,b,c); a += pmd->pattern_size; b += pmd->replace_size; c += pmd->pattern_max_jump_size; mix(a,b,c); for (i=0,j=0;ipattern_size;i+=4) { tmp = 0; k = pmd->pattern_size - i; if (k > 4) k=4; for (l=0;lpattern_buf + i + l) << l*8; } switch (j) { case 0: a += tmp; break; case 1: b += tmp; break; case 2: c += tmp; break; } j++; if (j == 3) { mix(a,b,c); j = 0; } } for (i=0;ireplace_size;i+=4) { tmp = 0; k = pmd->replace_size - i; if (k > 4) k=4; for (l=0;lreplace_buf + i + l) << l*8; } switch (j) { case 0: a += tmp; break; case 1: b += tmp; break; case 2: c += tmp; break; } j++; if (j == 3) { mix(a,b,c); j = 0; } } if (j != 0) { mix(a,b,c); } if (pmd->http_buffer) { a += RULE_OPTION_TYPE_CONTENT_URI; } else { a += RULE_OPTION_TYPE_CONTENT; } b += pmd->fp; c += pmd->fp_only; mix(a,b,c); a += pmd->fp_offset; b += pmd->fp_length; c += pmd->offset_var; mix(a,b,c); a += pmd->depth_var; b += pmd->distance_var; c += pmd->within_var; if( pmd->protected_pattern ) { mix(a,b,c); a += 1; b += pmd->pattern_type; c += pmd->protected_length; } final(a,b,c); return c; } int PatternMatchCompare(void *l, void *r) { PatternMatchData *left = (PatternMatchData *)l; PatternMatchData *right = (PatternMatchData *)r; unsigned int i; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if (left->buffer_func != right->buffer_func) return DETECTION_OPTION_NOT_EQUAL; /* Sizes will be most different, check that first */ if ((left->pattern_size != right->pattern_size) || (left->replace_size != right->replace_size) || (left->nocase != right->nocase)) return DETECTION_OPTION_NOT_EQUAL; /* Next compare the patterns for uniqueness */ if (left->pattern_size) { if (left->nocase) { /* If nocase is set, do case insensitive compare on pattern */ for (i=0;ipattern_size;i++) { if (toupper(left->pattern_buf[i]) != toupper(right->pattern_buf[i])) { return DETECTION_OPTION_NOT_EQUAL; } } } else { /* If nocase is not set, do case sensitive compare on pattern */ if (memcmp(left->pattern_buf, right->pattern_buf, left->pattern_size) != 0) { return DETECTION_OPTION_NOT_EQUAL; } } } /* Check the replace pattern if exists */ if (left->replace_size) { if (memcmp(left->replace_buf, right->replace_buf, left->replace_size) != 0) { return DETECTION_OPTION_NOT_EQUAL; } } /* Now check the rest of the options */ if ((left->exception_flag == right->exception_flag) && (left->offset == right->offset) && (left->depth == right->depth) && (left->distance == right->distance) && (left->within == right->within) && (left->rawbytes == right->rawbytes) && (left->use_doe == right->use_doe) && (left->http_buffer == right->http_buffer) && (left->search == right->search) && (left->pattern_max_jump_size == right->pattern_max_jump_size) && (left->fp == right->fp) && (left->fp_only == right->fp_only) && (left->fp_offset == right->fp_offset) && (left->fp_length == right->fp_length) && (left->offset_var == right->offset_var) && (left->depth_var == right->depth_var) && (left->distance_var == right->distance_var) && (left->within_var == right->within_var) ) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } /* This function is called in parser.c after the rule has been * completely parsed */ void FinalizeContentUniqueness(struct _SnortConfig *sc, OptTreeNode *otn) { OptFpList *opt_fp = otn->opt_func; while (opt_fp) { if ((opt_fp->type == RULE_OPTION_TYPE_CONTENT) || (opt_fp->type == RULE_OPTION_TYPE_CONTENT_URI)) { PatternMatchData *pmd = (PatternMatchData *)opt_fp->context; option_type_t option_type = opt_fp->type; void *pmd_dup; /* Since each content modifier can be parsed as a rule option, * do this check now that the entire rule has been parsed */ if (option_type == RULE_OPTION_TYPE_CONTENT_URI) ValidateContent(sc, pmd, PLUGIN_PATTERN_MATCH_URI); else ValidateContent(sc, pmd, PLUGIN_PATTERN_MATCH); if (add_detection_option(sc, option_type, (void *)pmd, &pmd_dup) == DETECTION_OPTION_EQUAL) { /* Don't do anything if they are the same pointer. This might happen when * converting an so rule to a text rule via ConvertDynamicRule() in sf_convert_dynamic.c * since we need to iterate through the RTN list in the OTN to verify that for http * contents, the http_inspect preprocessor is enabled in the policy that is using a * rule with http contents. */ if (pmd != pmd_dup) { #if 0 PrintDupDOTPmds(pmd, (PatternMatchData *)pmd_dup, option_type); #endif /* Hack since some places check for non-nullness of ds_list. * Beware of iterating the pmd lists after this point since * they'll be messed up - only check for non-nullness */ if (option_type == RULE_OPTION_TYPE_CONTENT) { if (pmd == otn->ds_list[PLUGIN_PATTERN_MATCH]) otn->ds_list[PLUGIN_PATTERN_MATCH] = pmd_dup; } else { if (pmd == otn->ds_list[PLUGIN_PATTERN_MATCH_URI]) otn->ds_list[PLUGIN_PATTERN_MATCH_URI] = pmd_dup; } PatternMatchFree(pmd); opt_fp->context = pmd_dup; } } #if 0 else { LogMessage("Unique %sContent\n", (opt_fp->OptTestFunc == CheckANDPatternMatch) ? "" : "Uri"); } #endif } opt_fp = opt_fp->next; } } void ValidateFastPattern(OptTreeNode *otn) { OptFpList *fpl = NULL; int fp_only = 0; for(fpl = otn->opt_func; fpl != NULL; fpl = fpl->next) { /* a relative option is following a fast_pattern:only and * there was no resets. */ if (fp_only == 1) { if (fpl->isRelative) ParseWarning("relative rule option used after " "fast_pattern:only"); } /* reset the check if one of these are present. */ if ((fpl->type == RULE_OPTION_TYPE_FILE_DATA) || (fpl->type == RULE_OPTION_TYPE_PKT_DATA) || (fpl->type == RULE_OPTION_TYPE_BASE64_DATA) || (fpl->type == RULE_OPTION_TYPE_PCRE) || (fpl->type == RULE_OPTION_TYPE_BYTE_JUMP) || (fpl->type == RULE_OPTION_TYPE_BYTE_EXTRACT)) { fp_only = 0; } /* set/unset the check on content options. */ if ((fpl->type == RULE_OPTION_TYPE_CONTENT) || (fpl->type == RULE_OPTION_TYPE_CONTENT_URI)) { PatternMatchData *pmd = (PatternMatchData *)fpl->context; if (pmd->fp_only) fp_only = 1; else fp_only = 0; } } } void make_precomp(PatternMatchData * idx) { if(idx->skip_stride) free(idx->skip_stride); if(idx->shift_stride) free(idx->shift_stride); idx->skip_stride = make_skip(idx->pattern_buf, idx->pattern_size); idx->shift_stride = make_shift(idx->pattern_buf, idx->pattern_size); } static char *PayloadExtractParameter(char *data, int *result_len) { char *quote_one = NULL, *quote_two = NULL; char *comma = NULL; quote_one = strchr(data, '"'); if (quote_one) { quote_two = strchr(quote_one+1, '"'); while ( quote_two && quote_two[-1] == '\\' ) quote_two = strchr(quote_two+1, '"'); } if (quote_one && quote_two) { comma = strchr(quote_two, ','); } else if (!quote_one) { comma = strchr(data, ','); } if (comma) { *result_len = comma - data; *comma = '\0'; } else { *result_len = strlen(data); } return data; } /* Since each content modifier can be parsed as a rule option, do this check * after parsing the entire rule in FinalizeContentUniqueness() */ static inline void ValidateContent(struct _SnortConfig *sc, PatternMatchData *pmd, int type) { if (pmd == NULL) return; if (pmd->fp) { if( pmd->protected_pattern ) { ParseError("Cannot use the fast pattern modifier with protected content"); } if ((type == PLUGIN_PATTERN_MATCH_URI) && !IsHttpBufFpEligible(pmd->http_buffer)) { ParseError("Cannot use the fast_pattern content modifier for a lone " "http cookie/http raw uri /http raw header /http raw cookie /status code / status msg /http method buffer content."); } if (pmd->use_doe || (pmd->offset != 0) || (pmd->depth != 0)) { if (pmd->exception_flag) { ParseError("Cannot use the fast_pattern modifier for negated, " "relative or non-zero offset/depth content searches."); } if (pmd->fp_only) { ParseError("Fast pattern only contents cannot be relative or " "have non-zero offset/depth content modifiers."); } } if (pmd->fp_only) { if (pmd->replace_buf != NULL) { ParseError("Fast pattern only contents cannot use " "replace modifier."); } if (pmd->exception_flag) ParseError("Fast pattern only contents cannot be negated."); } } if (type == PLUGIN_PATTERN_MATCH_URI) ValidateHttpContentModifiers(sc, pmd); if (pmd->protected_pattern) ValidateProtectedContentModifiers(sc, pmd); } /**************************************************************************** * * Function: GetMaxJumpSize(char *, int) * * Purpose: Find the maximum number of characters we can jump ahead * from the current offset when checking for this pattern again. * * Arguments: data => the pattern string * data_len => length of pattern string * * Returns: int => number of bytes before pattern repeats within itself * ***************************************************************************/ static unsigned int GetMaxJumpSize(char *data, int data_len) { int i, j; j = 0; for ( i = 1; i < data_len; i++ ) { if ( data[j] != data[i] ) { j = 0; continue; } if ( i == (data_len - 1) ) { return (data_len - j - 1); } j++; } return data_len; } /**************************************************************************** * * Function: ParsePattern(char *) * * Purpose: Process the application layer patterns and attach them to the * appropriate rule. My god this is ugly code. * * Arguments: rule => the pattern string * * Returns: void function * ***************************************************************************/ void ParsePattern(char *rule, OptTreeNode * otn, int type) { char tmp_buf[MAX_PATTERN_SIZE]; /* got enough ptrs for you? */ char *start_ptr; char *end_ptr; char *idx; char *dummy_idx; char *dummy_end; char *tmp; char hex_buf[3]; u_int dummy_size = 0; int size; int hexmode = 0; int hexsize = 0; int pending = 0; int cnt = 0; int literal = 0; int exception_flag = 0; PatternMatchData *ds_idx; /* clear out the temp buffer */ memset(tmp_buf, 0, MAX_PATTERN_SIZE); if (rule == NULL) ParseError("ParsePattern Got Null enclosed in quotation marks (\")!"); while(isspace((int)*rule)) rule++; if(*rule == '!') { exception_flag = 1; while(isspace((int)*++rule)); } /* find the start of the data */ start_ptr = strchr(rule, '"'); if (start_ptr != rule) ParseError("Content data needs to be enclosed in quotation marks (\")!"); /* move the start up from the beggining quotes */ start_ptr++; /* find the end of the data */ end_ptr = strrchr(start_ptr, '"'); if (end_ptr == NULL) ParseError("Content data needs to be enclosed in quotation marks (\")!"); /* Move the null termination up a bit more */ *end_ptr = '\0'; /* Is there anything other than whitespace after the trailing * double quote? */ tmp = end_ptr + 1; while (*tmp != '\0' && isspace ((int)*tmp)) tmp++; if (strlen (tmp) > 0) { ParseError("Bad data (possibly due to missing semicolon) after " "trailing double quote."); } /* how big is it?? */ size = end_ptr - start_ptr; /* uh, this shouldn't happen */ if (size <= 0) ParseError("Bad pattern length!"); /* set all the pointers to the appropriate places... */ idx = start_ptr; /* set the indexes into the temp buffer */ dummy_idx = tmp_buf; dummy_end = (dummy_idx + size); /* why is this buffer so small? */ memset(hex_buf, '0', 2); hex_buf[2] = '\0'; /* BEGIN BAD JUJU..... */ while(idx < end_ptr) { if (dummy_size >= MAX_PATTERN_SIZE-1) { /* Have more data to parse and pattern is about to go beyond end of buffer */ ParseError("ParsePattern() dummy buffer overflow, make a smaller " "pattern please! (Max size = %d)", MAX_PATTERN_SIZE-1); } DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "processing char: %c\n", *idx);); switch(*idx) { case '|': DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "Got bar... ");); if(!literal) { DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "not in literal mode... ");); if(!hexmode) { DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "Entering hexmode\n");); hexmode = 1; } else { DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "Exiting hexmode\n");); /* ** Hexmode is not even. */ if(!hexsize || hexsize % 2) { ParseError("Content hexmode argument has invalid " "number of hex digits. The argument '%s' " "must contain a full even byte string.", start_ptr); } hexmode = 0; pending = 0; } if(hexmode) hexsize = 0; } else { DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "literal set, Clearing\n");); literal = 0; tmp_buf[dummy_size] = start_ptr[cnt]; dummy_size++; } break; case '\\': DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Got literal char... ");); if(!literal) { /* Make sure the next char makes this a valid * escape sequence. */ if (idx [1] != '\0' && strchr ("\\\":;", idx [1]) == NULL) { ParseError("Bad escape sequence starting with \"%s\".", idx); } DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Setting literal\n");); literal = 1; } else { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Clearing literal\n");); tmp_buf[dummy_size] = start_ptr[cnt]; literal = 0; dummy_size++; } break; case '"': if (!literal) ParseError("Non-escaped '\"' character!"); /* otherwise process the character as default */ default: if(hexmode) { if(isxdigit((int) *idx)) { hexsize++; if(!pending) { hex_buf[0] = *idx; pending++; } else { hex_buf[1] = *idx; pending--; if(dummy_idx < dummy_end) { tmp_buf[dummy_size] = (u_char) strtol(hex_buf, (char **) NULL, 16)&0xFF; dummy_size++; memset(hex_buf, '0', 2); hex_buf[2] = '\0'; } else { ParseError("ParsePattern() dummy buffer " "overflow, make a smaller pattern " "please! (Max size = %d)", MAX_PATTERN_SIZE-1); } } } else { if(*idx != ' ') { ParseError("What is this \"%c\"(0x%X) doing in " "your binary buffer? Valid hex values " "only please! (0x0 - 0xF) Position: %d", (char) *idx, (char) *idx, cnt); } } } else { if(*idx >= 0x1F && *idx <= 0x7e) { if(dummy_idx < dummy_end) { tmp_buf[dummy_size] = start_ptr[cnt]; dummy_size++; } else { ParseError("ParsePattern() dummy buffer " "overflow, make a smaller pattern " "please! (Max size = %d)", MAX_PATTERN_SIZE-1); } if(literal) { literal = 0; } } else { if(literal) { tmp_buf[dummy_size] = start_ptr[cnt]; dummy_size++; DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "Clearing literal\n");); literal = 0; } else { ParseError("Character value out of range, try a " "binary buffer."); } } } break; } dummy_idx++; idx++; cnt++; } /* ...END BAD JUJU */ /* error prunning */ if (literal) ParseError("Backslash escape is not completed."); if (hexmode) ParseError("Hexmode is not completed."); ds_idx = (PatternMatchData *) otn->ds_list[type]; while(ds_idx->next != NULL) ds_idx = ds_idx->next; ds_idx->pattern_buf = (char *)SnortAlloc(dummy_size+1); memcpy(ds_idx->pattern_buf, tmp_buf, dummy_size); ds_idx->pattern_size = dummy_size; ds_idx->search = uniSearch; make_precomp(ds_idx); ds_idx->exception_flag = exception_flag; ds_idx->pattern_max_jump_size = GetMaxJumpSize(ds_idx->pattern_buf, ds_idx->pattern_size); } static bool HexToNybble( char Chr, uint8_t *Val ) { if( !isxdigit( (int)Chr ) ) { *Val = 0; return( false ); } if( isdigit( Chr ) ) *Val = (uint8_t)(Chr - '0'); else *Val = (uint8_t)(((char)toupper(Chr) - 'A') + 10); return( true ); } static bool HexToByte( char *Str, uint8_t *Val ) { uint8_t nybble; *Val = 0; if( HexToNybble( *Str++, &nybble ) ) { *Val = ((nybble & 0xf) << 4); if( HexToNybble( *Str, &nybble ) ) { *Val |= (nybble & 0xf); return( true ); } } return( false ); } /**************************************************************************** * * Function: ParseProtectedPattern(char *) * * Purpose: Process the application layer patterns and attach them to the * appropriate rule. * * Arguments: rule => the pattern string * * Returns: void function * ***************************************************************************/ void ParseProtectedPattern(char *rule, OptTreeNode * otn, int type) { uint8_t tmp_buf[MAX_PATTERN_SIZE]; char *tmp; unsigned int pat_idx; int exception_flag = 0; PatternMatchData *ds_idx; /* clear out the temp buffer */ memset(tmp_buf, 0, MAX_PATTERN_SIZE); if (rule == NULL) ParseError("ParsePattern Got Null enclosed in quotation marks (\")!"); while(isspace((int)*rule)) rule++; if( *rule == '!' ) { exception_flag = 1; rule++; } else exception_flag = 0; /* find the start of the data */ while(isspace((int)*rule)) rule++; if (*rule++ != '"') ParseError("Protected content data needs to be enclosed in quotation marks (\")!"); /* find the end of the data */ tmp = strrchr(rule, '"'); if (tmp == NULL) ParseError("Protected content data needs to be enclosed in quotation marks (\")!"); /* Terminate the pattern string */ *tmp = '\0'; /* Is there anything other than whitespace after the trailing * double quote? */ while (*++tmp != '\0') if(!isspace ((int)*tmp)) ParseError("Bad data (possibly due to missing semicolon) after " "trailing double quote."); pat_idx = 0; /* index into the pattern buffer */ while((*rule != '\0') && (pat_idx < MAX_PATTERN_SIZE)) { if( !HexToByte( rule, &(tmp_buf[pat_idx]) ) ) ParseError("Bad protected pattern"); rule += 2; pat_idx += 1; } if( (*rule == '\0') && (pat_idx == 0) ) ParseError("Zero protected pattern size"); if( (*rule != '\0') && (pat_idx == MAX_PATTERN_SIZE) ) ParseError("Protected pattern too long"); ds_idx = (PatternMatchData *) otn->ds_list[type]; while(ds_idx->next != NULL) ds_idx = ds_idx->next; ds_idx->pattern_buf = (char *)SnortAlloc(pat_idx); memcpy(ds_idx->pattern_buf, tmp_buf, pat_idx); ds_idx->pattern_size = pat_idx; ds_idx->search = uniSearchHash; ds_idx->exception_flag = exception_flag; } /* * hash search function. * * data = ptr to buffer to search * dlen = distance to the back of the buffer being tested, validated * against offset + depth before function entry (not distance/within) * pmd = pointer to pattern match data struct * * return 1 for found * return 0 for not found * return -1 for error (search out of bounds) */ static int uniSearchHash(const char *data, int dlen, PatternMatchData *pmd) { /* * in theory computeDepth doesn't need to be called because the * depth + offset adjustments have been made by the calling function */ int depth = dlen; int success = 0; const char *start_ptr = data; const char *end_ptr = data + dlen; const char *base_ptr = start_ptr; uint32_t extract_offset, extract_distance; int search_start = 0; if(pmd->use_doe != 1) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "NOT Using Doe Ptr\n");); UpdateDoePtr(NULL, 0); /* get rid of all our pattern match state */ } /* Get byte_math/byte_extract variables */ if (pmd->offset_var >= 0 ) { if(pmd->offset_var == BYTE_MATH_VAR_INDEX ) pmd->offset = (int32_t) bytemath_variable; else { if (pmd->offset_var < NUM_BYTE_EXTRACT_VARS) { GetByteExtractValue(&extract_offset, pmd->offset_var); pmd->offset = (int32_t) extract_offset; } } } if (pmd->distance_var >= 0 ) { if(pmd->distance_var == BYTE_MATH_VAR_INDEX ) pmd->distance = (int32_t) bytemath_variable; else { if (pmd->distance_var < NUM_BYTE_EXTRACT_VARS) { GetByteExtractValue(&extract_distance, pmd->distance_var); pmd->distance = (int32_t) extract_distance; } } } // Set our initial starting point if (doe_ptr) { // Sanity check to make sure the doe_ptr is within the buffer we're // searching. It could be at the very end of the buffer due to a // previous match, but may have a negative distance here. if (((char *)doe_ptr < start_ptr) || ((char *)doe_ptr > end_ptr)) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Returning because " "doe_ptr isn't within the buffer we're searching: " "start_ptr: %p, end_ptr: %p, doe_ptr: %p\n", start_ptr, end_ptr, doe_ptr);); return -1; } DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Setting base_ptr to doe_ptr (%p)\n", doe_ptr);); base_ptr = (const char *)doe_ptr; depth = dlen - ((char *)doe_ptr - data); } else { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Setting base_ptr to start_ptr (%p)\n", start_ptr);); base_ptr = start_ptr; depth = dlen; } // Adjust base_ptr and depth based on distance // or offset parameters. if (pmd->distance != 0) { // This covers the pmd->distance > buffer case if (pmd->distance > depth) { depth = 0; } else { search_start = (base_ptr - start_ptr) + pmd->distance; base_ptr += pmd->distance; depth -= pmd->distance; } // If the distance is negative and puts us before start_ptr // set base_ptr to start_ptr and adjust depth based on protected_length. if (search_start < 0) { return -1; } else if ((int)pmd->pattern_size < depth) { depth = (int)pmd->pattern_size; } search_start = 0; } else if (pmd->offset != 0) { if (pmd->offset > depth) { depth = 0; } else { search_start = pmd->offset; base_ptr += pmd->offset; depth -= pmd->offset; } // If the distance is negative and puts us before start_ptr // set base_ptr to start_ptr and adjust depth based on pmd->protected_length. if (search_start < 0) { return -1; } else if ((int)pmd->pattern_size < depth) { depth = (int)pmd->pattern_size; } } // If the pattern size is greater than the amount of data we have to // search, there's no way we can match, but return 0 here for the // case where the match is inverted and there is at least some data. if ((int)pmd->pattern_size > depth) { if (pmd->exception_flag && (depth > 0)) return 0; return -1; } #ifdef DEBUG_MSGS { char *hexbuf; assert(depth <= dlen); DebugMessage(DEBUG_PATTERN_MATCH, "uniSearchHash:\n "); hexbuf = hex((u_char *)pmd->pattern_buf, pmd->pattern_size); DebugMessage(DEBUG_PATTERN_MATCH, " p->data: %p\n doe_ptr: %p\n " "base_ptr: %p\n depth: %d\n searching for: %s\n", data, doe_ptr, base_ptr, depth, hexbuf); free(hexbuf); } #endif /* DEBUG_MSGS */ success = hashSearchFixed(base_ptr, pmd->pattern_size, pmd->pattern_type, pmd->pattern_buf); #ifdef DEBUG_MSGS if(success) { DebugMessage(DEBUG_PATTERN_MATCH, "matched, doe_ptr: %p (%d)\n", doe_ptr, ((char *)doe_ptr - data)); } #endif return success; } /******************************************************************** * Runtime functions ********************************************************************/ /* * case sensitive search * * data = ptr to buffer to search * dlen = distance to the back of the buffer being tested, validated * against offset + depth before function entry (not distance/within) * pmd = pointer to pattern match data struct */ static int uniSearch(const char *data, int dlen, PatternMatchData *pmd) { return uniSearchReal(data, dlen, pmd, 0); } /* * case insensitive search * * data = ptr to buffer to search * dlen = distance to the back of the buffer being tested, validated * against offset + depth before function entry (not distance/within) * pmd = pointer to pattern match data struct * * NOTE - this is used in sf_convert_dynamic.c so cannot be static */ int uniSearchCI(const char *data, int dlen, PatternMatchData *pmd) { return uniSearchReal(data, dlen, pmd, 1); } /* * single search function. * * data = ptr to buffer to search * dlen = distance to the back of the buffer being tested, validated * against offset + depth before function entry (not distance/within) * pmd = pointer to pattern match data struct * nocase = 0 means case sensitve, 1 means case insensitive * * return 1 for found * return 0 for not found * return -1 for error (search out of bounds) */ static int uniSearchReal(const char *data, int dlen, PatternMatchData *pmd, int nocase) { /* * in theory computeDepth doesn't need to be called because the * depth + offset adjustments have been made by the calling function */ int depth = dlen; int success = 0; const char *start_ptr = data; const char *end_ptr = data + dlen; const char *base_ptr = start_ptr; uint32_t extract_offset, extract_depth, extract_distance, extract_within; int search_start = 0; if(pmd->use_doe != 1) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "NOT Using Doe Ptr\n");); UpdateDoePtr(NULL, 0); /* get rid of all our pattern match state */ } /* Get byte_math/byte_extract variables */ if (pmd->offset_var >= 0 ) { if(pmd->offset_var == BYTE_MATH_VAR_INDEX ) pmd->offset = (int32_t) bytemath_variable; else { if (pmd->offset_var < NUM_BYTE_EXTRACT_VARS) { GetByteExtractValue(&extract_offset, pmd->offset_var); pmd->offset = (int32_t) extract_offset; } } } if (pmd->depth_var >= 0 ) { if(pmd->depth_var == BYTE_MATH_VAR_INDEX ) pmd->depth = (int32_t) bytemath_variable; else { if (pmd->depth_var < NUM_BYTE_EXTRACT_VARS) { GetByteExtractValue(&extract_depth, pmd->depth_var); pmd->depth = (int32_t) extract_depth; } } } if (pmd->distance_var >= 0 ) { if(pmd->distance_var == BYTE_MATH_VAR_INDEX ) pmd->distance = (int32_t) bytemath_variable; else { if (pmd->distance_var < NUM_BYTE_EXTRACT_VARS) { GetByteExtractValue(&extract_distance, pmd->distance_var); pmd->distance = (int32_t) extract_distance; } } } if (pmd->within_var >= 0 ) { if(pmd->within_var == BYTE_MATH_VAR_INDEX ) pmd->within = (int32_t) bytemath_variable; else { if (pmd->within_var < NUM_BYTE_EXTRACT_VARS) { GetByteExtractValue(&extract_within, pmd->within_var); pmd->within = (int32_t) extract_within; } } } // Set our initial starting point if (doe_ptr) { // Sanity check to make sure the doe_ptr is within the buffer we're // searching. It could be at the very end of the buffer due to a // previous match, but may have a negative distance here. if (((char *)doe_ptr < start_ptr) || ((char *)doe_ptr > end_ptr)) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Returning because " "doe_ptr isn't within the buffer we're searching: " "start_ptr: %p, end_ptr: %p, doe_ptr: %p\n", start_ptr, end_ptr, doe_ptr);); return -1; } DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Setting base_ptr to doe_ptr (%p)\n", doe_ptr);); base_ptr = (const char *)doe_ptr; depth = dlen - ((char *)doe_ptr - data); } else { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Setting base_ptr to start_ptr (%p)\n", start_ptr);); base_ptr = start_ptr; depth = dlen; } // Adjust base_ptr and depth based on distance/within // or offset/depth parameters. if ((pmd->distance != 0) || (pmd->within != PMD_WITHIN_UNDEFINED)) { // This covers the pmd->distance > buffer case if (pmd->distance > depth) { depth = 0; } else if (pmd->distance != 0) { search_start = (base_ptr - start_ptr) + pmd->distance; base_ptr += pmd->distance; depth -= pmd->distance; } // If the distance is negative and puts us before start_ptr // set base_ptr to start_ptr and adjust depth based on within. if (search_start < 0) { int delta = search_start; delta += (pmd->within == PMD_WITHIN_UNDEFINED) ? 0 : (int)pmd->within; // base_ptr is before start_ptr and the within is before start_ptr as well. Cannot re-adjust. if(delta < 0) return -1; base_ptr = start_ptr; depth = ((pmd->within == PMD_WITHIN_UNDEFINED) || (delta > dlen)) ? dlen : delta; } else if ((pmd->within != PMD_WITHIN_UNDEFINED) && ((int)pmd->within < depth)) { depth = (int)pmd->within; } search_start = 0; } else if ((pmd->offset != 0) || (pmd->depth != 0)) { if (pmd->offset > depth) { depth = 0; } else if (pmd->offset != 0) { search_start = pmd->offset; base_ptr += pmd->offset; depth -= pmd->offset; } // If the distance is negative and puts us before start_ptr // set base_ptr to start_ptr and adjust depth based on pmd->depth. if (search_start < 0) { int delta = (int)pmd->depth + search_start; // base_ptr is before start_ptr and the depth is before start_ptr as well. Cannot re-adjust. if(delta < 0) return -1; base_ptr = start_ptr; depth = ((pmd->depth == 0) || (delta > dlen)) ? dlen : delta; } else if ((pmd->depth != 0) && (pmd->depth < depth)) { depth = pmd->depth; } } // If the pattern size is greater than the amount of data we have to // search, there's no way we can match, but return 0 here for the // case where the match is inverted and there is at least some data. if ((int)pmd->pattern_size > depth) { // The condition ((char *)doe_ptr == end_ptr) is for the corner case, // where the pattern match is exactly at the end of the payload and it // is a negated content match. if (pmd->exception_flag && (((char *)doe_ptr == end_ptr) || depth > 0)) return 0; return -1; } #ifdef DEBUG_MSGS { char *hexbuf; assert(depth <= dlen); DebugMessage(DEBUG_PATTERN_MATCH, "uniSearchReal:\n "); hexbuf = hex((u_char *)pmd->pattern_buf, pmd->pattern_size); DebugMessage(DEBUG_PATTERN_MATCH, " p->data: %p\n doe_ptr: %p\n " "base_ptr: %p\n depth: %d\n searching for: %s\n", data, doe_ptr, base_ptr, depth, hexbuf); free(hexbuf); } #endif /* DEBUG_MSGS */ if(nocase) { success = mSearchCI(base_ptr, depth, pmd->pattern_buf, pmd->pattern_size, pmd->skip_stride, pmd->shift_stride); } else { success = mSearch(base_ptr, depth, pmd->pattern_buf, pmd->pattern_size, pmd->skip_stride, pmd->shift_stride); } #ifdef DEBUG_MSGS if(success) { DebugMessage(DEBUG_PATTERN_MATCH, "matched, doe_ptr: %p (%d)\n", doe_ptr, ((char *)doe_ptr - data)); } #endif return success; } int CheckANDPatternMatch(void *option_data, Packet *p) { int rval = DETECTION_OPTION_NO_MATCH; int found = -1; int dsize; const char *dp = NULL; #if 0 int origUseDoe; char *orig_doe; #endif PatternMatchData *idx; PROFILE_VARS; PREPROC_PROFILE_START(contentPerfStats); DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "CheckPatternANDMatch: ");); idx = (PatternMatchData *)option_data; #if 0 origUseDoe = idx->use_doe; #endif if(idx->rawbytes == 0) { if(Is_DetectFlag(FLAG_ALT_DETECT)) { dsize = DetectBuffer.len; dp = (const char*) DetectBuffer.data; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Using Alternative Detect buffer!\n");); } else if(Is_DetectFlag(FLAG_ALT_DECODE)) { dsize = DecodeBuffer.len; dp = (const char *) DecodeBuffer.data; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Using Alternative Decode buffer!\n");); } else { if(IsLimitedDetect(p)) { dsize = p->alt_dsize; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Using Limited Packet Data!\n");); } else { dsize = p->dsize; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Using Full Packet Data!\n");); } dp = (const char *) p->data; } } else { dsize = p->dsize; dp = (const char *) p->data; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Using Full Packet Data!\n");); } #if 0 /* this now takes care of all the special cases where we'd run * over the buffer */ orig_doe = (char *)doe_ptr; #endif if(doe_buf_flags & DOE_BUF_URI) UpdateDoePtr(NULL, 0); doe_buf_flags = DOE_BUF_STD; #ifndef NO_FOUND_ERROR if( p->dsize != 0 ) { found = idx->search(dp, dsize, idx); } if ( found == -1 ) { /* On error, mark as not found. This is necessary to handle !content cases. In that case, a search that is outside the given buffer will return 0, and !0 is 1, so a !content out of bounds will return true, which is not what we want. */ found = 0; } else { found ^= idx->exception_flag; } #else /* Original code. Does not account for searching outside the buffer. */ found = (idx->search(dp, dsize, idx) ^ idx->exception_flag); #endif if ( found ) { if ( idx->replace_buf && !PacketWasCooked(p) ) { //fix the packet buffer to have the new string int detect_depth = (char *)doe_ptr - idx->pattern_size - dp; if (detect_depth < 0) { PREPROC_PROFILE_END(contentPerfStats); return rval; } Replace_StoreOffset(idx, detect_depth); } rval = DETECTION_OPTION_MATCH; DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Pattern match found\n");); } else { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Pattern match failed\n");); } #if 0 while (found) { /* save where we last did the pattern match */ tmp_doe = (char *)doe_ptr; /* save start doe as beginning of this pattern + non-repeating length*/ start_doe = (char *)doe_ptr - idx->pattern_size + idx->pattern_max_jump_size; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Pattern Match successful!\n");); DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Check next functions!\n");); /* PROFILING Don't count rest of options towards content */ PREPROC_PROFILE_TMPEND(contentPerfStats); /* Try evaluating the rest of the rules chain */ next_found= fp_list->next->OptTestFunc(p, otn_idx, fp_list->next); /* PROFILING Don't count rest of options towards content */ PREPROC_PROFILE_TMPSTART(contentPerfStats); if(next_found != 0) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Next functions matched!\n");); /* We found a successful match, return that this rule has fired off */ PREPROC_PROFILE_END(contentPerfStats); return next_found; } else if(tmp_doe != NULL) { int new_dsize = dsize-(start_doe-dp); /* if the next option isn't relative and it failed, we're done */ if (fp_list->next->isRelative == 0) { PREPROC_PROFILE_END(contentPerfStats); return 0; } if(new_dsize <= 0 || new_dsize > dsize) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "The new dsize is less than <= 0 or > " "the the original dsize;returning " "false\n");); idx->use_doe = origUseDoe; PREPROC_PROFILE_END(contentPerfStats); return 0; } if (orig_doe) { /* relative to a previously found pattern */ if (((idx->distance != 0) && (start_doe - orig_doe > idx->distance)) || ((idx->offset != 0) && (start_doe - orig_doe > idx->offset)) ) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "The next starting point to search " "from is beyond the original " "distance;returning false\n");); idx->use_doe = origUseDoe; PREPROC_PROFILE_END(contentPerfStats); return 0; } if (((idx->within != 0) && (start_doe - orig_doe + idx->pattern_size > (unsigned int)idx->within)) || ((idx->depth != 0) && (start_doe - orig_doe + idx->pattern_size > (unsigned int)idx->depth)) ) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "The next starting point to search " "from is beyond the original " "within;returning false\n");); idx->use_doe = origUseDoe; PREPROC_PROFILE_END(contentPerfStats); return 0; } } else { /* relative to beginning of data */ if (((idx->distance != 0) && (start_doe - dp > idx->distance)) || ((idx->offset != 0) && (start_doe - dp > idx->offset)) ) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "The next starting point to search " "from is beyond the original " "distance;returning false\n");); idx->use_doe = origUseDoe; PREPROC_PROFILE_END(contentPerfStats); return 0; } if (((idx->within != 0) && (start_doe - dp + idx->pattern_size > (unsigned int)idx->within)) || ((idx->depth != 0) && (start_doe - dp + idx->pattern_size > (unsigned int)idx->depth)) ) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "The next starting point to search " "from is beyond the original " "within;returning false\n");); idx->use_doe = origUseDoe; PREPROC_PROFILE_END(contentPerfStats); return 0; } } DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "At least ONE of the next functions does to match!\n");); DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Start search again from a next point!\n");); /* Start the search again from the last set of contents, with a new depth and dsize */ doe_ptr = (uint8_t *)start_doe; idx->use_doe = 1; found = (idx->search(start_doe, new_dsize,idx) ^ idx->exception_flag); /* ** If we haven't updated doe since we set it at the beginning ** of the loop, then that means we have already done the exact ** same search previously, and have nothing else to gain from ** doing the same search again. */ if(start_doe == (char *)doe_ptr) { idx->use_doe = origUseDoe; PREPROC_PROFILE_END(contentPerfStats); return 0; } } else { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Returning 0 because tmp_doe is NULL\n");); idx->use_doe = origUseDoe; PREPROC_PROFILE_END(contentPerfStats); return 0; } } #endif //idx->use_doe = origUseDoe; PREPROC_PROFILE_END(contentPerfStats); return rval; } int CheckUriPatternMatch(void *option_data, Packet *p) { int rval = DETECTION_OPTION_NO_MATCH; int found = 0; PatternMatchData *idx = (PatternMatchData *)option_data; const HttpBuffer* hb = GetHttpBuffer(idx->http_buffer); PROFILE_VARS; if ( !hb ) { DEBUG_WRAP(DebugMessage(DEBUG_HTTP_DECODE,"CheckUriPatternMatch: no " "HTTP buffers set, retuning");); return rval; } PREPROC_PROFILE_START(uricontentPerfStats); /* * have to reset the doe_ptr for each new UriBuf */ if(idx->use_doe != 1) UpdateDoePtr(NULL, 0); else if(!(doe_buf_flags & DOE_BUF_URI)) SetDoePtr(hb->buf, DOE_BUF_URI); /* this now takes care of all the special cases where we'd run * over the buffer */ found = idx->search((const char *)hb->buf, hb->length, idx); if (found == -1) found = 0; else found ^= idx->exception_flag; if(found > 0 ) { doe_buf_flags = DOE_BUF_URI; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Pattern Match successful!\n");); /* call the next function in the OTN */ PREPROC_PROFILE_END(uricontentPerfStats); return DETECTION_OPTION_MATCH; } DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Pattern match failed\n");); PREPROC_PROFILE_END(uricontentPerfStats); return rval; } void PatternMatchDuplicatePmd(void *src, PatternMatchData *pmd_dup) { /* Oh, C++ where r u? can't we have a friggin' copy constructor? */ PatternMatchData *pmd_src = (PatternMatchData *)src; if (!pmd_src || !pmd_dup) return; pmd_dup->exception_flag = pmd_src->exception_flag; pmd_dup->offset = pmd_src->offset; pmd_dup->depth = pmd_src->depth; pmd_dup->distance = pmd_src->distance; pmd_dup->within = pmd_src->within; pmd_dup->offset_var = pmd_src->offset_var; pmd_dup->depth_var = pmd_src->depth_var; pmd_dup->distance_var = pmd_src->distance_var; pmd_dup->within_var = pmd_src->within_var; pmd_dup->rawbytes = pmd_src->rawbytes; pmd_dup->nocase = pmd_src->nocase; pmd_dup->use_doe = pmd_src->use_doe; pmd_dup->http_buffer = pmd_src->http_buffer; pmd_dup->buffer_func = pmd_src->buffer_func; pmd_dup->pattern_size = pmd_src->pattern_size; pmd_dup->replace_size = pmd_src->replace_size; pmd_dup->replace_buf = pmd_src->replace_buf; pmd_dup->pattern_buf = pmd_src->pattern_buf; pmd_dup->search = pmd_src->search; pmd_dup->skip_stride = pmd_src->skip_stride; pmd_dup->shift_stride = pmd_src->shift_stride; pmd_dup->pattern_max_jump_size = pmd_src->pattern_max_jump_size; pmd_dup->fp = pmd_src->fp; pmd_dup->fp_only = pmd_src->fp_only; pmd_dup->fp_offset = pmd_src->fp_offset; pmd_dup->fp_length = pmd_src->fp_length; pmd_dup->pattern_type = pmd_src->pattern_type; pmd_dup->protected_pattern = pmd_src->protected_pattern; pmd_dup->protected_length = pmd_src->protected_length; pmd_dup->last_check.ts.tv_sec = pmd_src->last_check.ts.tv_sec; pmd_dup->last_check.ts.tv_usec = pmd_src->last_check.ts.tv_usec; pmd_dup->last_check.packet_number = pmd_src->last_check.packet_number; pmd_dup->last_check.rebuild_flag = pmd_src->last_check.rebuild_flag; pmd_dup->prev = NULL; pmd_dup->next = NULL; pmd_dup->fpl = NULL; Replace_ResetOffset(pmd_dup); } /* current_cursor should be the doe_ptr after this content rule option matched * orig_cursor is the place from where we first did evaluation of this content */ int PatternMatchAdjustRelativeOffsets(PatternMatchData *orig_pmd, PatternMatchData *dup_pmd, const uint8_t *current_cursor, const uint8_t *orig_cursor) { /* Adjust for repeating patterns, e.g. ABAB * This is where the new search for this content should start */ const uint8_t *start_cursor = (current_cursor - dup_pmd->pattern_size) + dup_pmd->pattern_max_jump_size; if (orig_pmd->depth != 0) { /* This was relative to a previously found pattern. No space left to * search, we're done */ if ((start_cursor + dup_pmd->pattern_size) > (orig_cursor + dup_pmd->offset + dup_pmd->depth)) { return 0; } /* Adjust offset and depth to reflect new position */ /* Lop off what we used */ dup_pmd->depth -= start_cursor - (orig_cursor + dup_pmd->offset); /* Make offset where we will start the next search */ dup_pmd->offset = start_cursor - orig_cursor; } else if (orig_pmd->within != PMD_WITHIN_UNDEFINED) { /* This was relative to a previously found pattern. No space left to * search, we're done */ if ((start_cursor + dup_pmd->pattern_size) > (orig_cursor + dup_pmd->distance + dup_pmd->within)) { return 0; } /* Adjust distance and within to reflect new position */ /* Lop off what we used */ dup_pmd->within -= start_cursor - (orig_cursor + dup_pmd->distance); /* Make distance where we will start the next search */ dup_pmd->distance = start_cursor - orig_cursor; } else if (orig_pmd->use_doe) { dup_pmd->distance = start_cursor - orig_cursor; } else { dup_pmd->offset = start_cursor - orig_cursor; } return 1; } #if 0 /* Not currently in use - DO NOT REMOVE */ static inline int computeDepth(int dlen, PatternMatchData * pmd) { /* do some tests to make sure we stay in bounds */ if((pmd->depth + pmd->offset) > dlen) { /* we want to check only depth bytes anyway */ int sub_depth = dlen - pmd->offset; if((sub_depth > 0) && (sub_depth >= (int)pmd->pattern_size)) { return sub_depth; } else { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Pattern Match failed -- sub_depth: %d < " "(int)pmd->pattern_size: %d!\n", sub_depth, (int)pmd->pattern_size);); return -1; } } else { if(pmd->depth && (dlen - pmd->offset > pmd->depth)) { return pmd->depth; } else { return dlen - pmd->offset; } } } static int uniSearchREG(char * data, int dlen, PatternMatchData * pmd) { int depth = computeDepth(dlen, pmd); /* int distance_adjustment = 0; * int depth_adjustment = 0; */ int success = 0; if (depth < 0) return 0; /* XXX DESTROY ME */ /*success = mSearchREG(data + pmd->offset + distance_adjustment, depth_adjustment!=0?depth_adjustment:depth, pmd->pattern_buf, pmd->pattern_size, pmd->skip_stride, pmd->shift_stride);*/ return success; } #endif #if 0 /* XXX Not completetly implemented */ static void PayloadSearchListInit(char *data, OptTreeNode * otn, int protocol) { char *sptr; char *eptr; lastType = PLUGIN_PATTERN_MATCH_OR; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "In PayloadSearchListInit()\n");); /* get the path/file name from the data */ while(isspace((int) *data)) data++; /* grab everything between the starting " and the end one */ sptr = strchr(data, '"'); eptr = strrchr(data, '"'); if(sptr != NULL && eptr != NULL) { /* increment past the first quote */ sptr++; /* zero out the second one */ *eptr = 0; } else { sptr = data; } /* read the content keywords from the list file */ ParseContentListFile(sptr, otn, protocol); /* link the plugin function in to the current OTN */ AddOptFuncToList(CheckORPatternMatch, otn); return; } /**************************************************************************** * * Function: ParseContentListFile(char *, OptTreeNode *, int protocol) * * Purpose: Read the content_list file a line at a time, put the content of * the line into buffer * * Arguments:otn => rule including the list * file => list file filename * protocol => protocol * * Returns: void function * ***************************************************************************/ static void ParseContentListFile(char *file, OptTreeNode * otn, int protocol) { FILE *thefp; /* file pointer for the content_list file */ char buf[STD_BUF+1]; /* file read buffer */ char rule_buf[STD_BUF+1]; /* content keyword buffer */ int frazes_count; /* frazes counter */ #ifdef DEBUG_MSGS PatternMatchData *idx; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Opening content_list file: %s\n", file);); #endif /* DEBUG_MSGS */ /* open the list file */ thefp = fopen(file, "r"); if (thefp == NULL) { ParseError("Unable to open list file: %s", file); } /* clear the line and rule buffers */ memset((char *) buf, 0, STD_BUF); memset((char *) rule_buf, 0, STD_BUF); frazes_count = 0; /* loop thru each list_file line and content to the rule */ while((fgets(buf, STD_BUF-2, thefp)) != NULL) { /* inc the line counter */ list_file_line++; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Got line %d: %s", list_file_line, buf);); /* if it's not a comment or a , send it to the parser */ if((buf[0] != '#') && (buf[0] != 0x0a) && (buf[0] != ';')) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Adding content keyword: %s", buf);); frazes_count++; strip(buf); NewNode(otn, PLUGIN_PATTERN_MATCH_OR); /* check and add content keyword */ ParsePattern(buf, otn, PLUGIN_PATTERN_MATCH_OR); DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Content keyword %s\" added!\n", buf);); } } #ifdef DEBUG_MSGS DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "%d frazes read...\n", frazes_count);); idx = (PatternMatchData *) otn->ds_list[PLUGIN_PATTERN_MATCH_OR]; if(idx == NULL) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "No patterns loaded\n");); } else { while(idx != NULL) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Pattern = %s\n", idx->pattern_buf);); idx = idx->next; } } #endif /* DEBUG_MSGS */ fclose(thefp); return; } int CheckORPatternMatch(Packet * p, OptTreeNode * otn_idx, OptFpList * fp_list) { int found = 0; int dsize; char *dp; PatternMatchData *idx; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "CheckPatternORMatch: ");); idx = otn_idx->ds_list[PLUGIN_PATTERN_MATCH_OR]; while(idx != NULL) { if (Is_DetectFlag(FLAG_ALT_DETECT) && (idx->rawbytes == 0)) { dsize = DetectBuffer.len; dp = (char *)DetectBufffer.data; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Using Alternative Detect buffer!\n");); } else if(Is_DetectFlag(FLAG_ALT_DECODE) && (idx->rawbytes == 0)) { dsize = DecodeBuffer.len; dp = (char *) DecodeBuffer.data; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Using Alternative Decode buffer!\n");); } else { if(IsLimitedDetect(p)) dsize = p->alt_dsize; else dsize = p->dsize; dp = (char *) p->data; } if(idx->offset > dsize) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Initial offset larger than payload!\n");); goto sizetoosmall; } else { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "testing pattern: %s\n", idx->pattern_buf);); found = idx->search(dp, dsize, idx); if(!found) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Pattern Match failed!\n");); } } DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Checking the results\n");); if(found) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Pattern Match " "successful: %s!\n", idx->pattern_buf);); return fp_list->next->OptTestFunc(p, otn_idx, fp_list->next); } else { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Pattern match failed\n");); } DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Stepping to next content keyword\n");); sizetoosmall: idx = idx->next; } DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "No more keywords, exiting... \n");); return 0; } #endif snort-2.9.15.1/src/detection-plugins/sp_pattern_match.h0000644000175200017520000001545213571422607020007 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __SP_PATTERN_MATCH_H__ #define __SP_PATTERN_MATCH_H__ #include #include "snort.h" #include "snort_debug.h" #include "rules.h" /* needed for OptTreeNode defintion */ #include "treenodes.h" #include "detection_util.h" #include "hashstring.h" /******************************************************************** * Macros ********************************************************************/ #define CHECK_AND_PATTERN_MATCH 1 #define CHECK_URI_PATTERN_MATCH 2 #define PMD_WITHIN_UNDEFINED ((unsigned) -1) /******************************************************************** * Data structures ********************************************************************/ typedef struct _PatternMatchData { int offset; /* pattern search start offset */ int depth; /* pattern search depth */ int distance; /* offset to start from based on last match */ u_int within; /* this pattern must be found within X bytes of last match*/ int8_t offset_var; /* byte_extract variable indices for offset, */ int8_t depth_var; /* depth, distance, within */ int8_t distance_var; int8_t within_var; int rawbytes; /* Search the raw bytes rather than any decoded app buffer */ int replace_depth; /* >=0 is offset to start of replace */ int nocase; /* Toggle case insensitity */ int use_doe; /* Use the doe_ptr for relative pattern searching */ HTTP_BUFFER http_buffer;/* Index of the URI buffer */ int buffer_func; /* buffer function CheckAND or CheckUri */ u_int pattern_size; /* size of app layer pattern */ u_int replace_size; /* size of app layer replace pattern */ char *replace_buf; /* app layer pattern to replace with */ char *pattern_buf; /* app layer pattern to match on */ int (*search)(const char *, int, struct _PatternMatchData *); /* search function */ int *skip_stride; /* B-M skip array */ int *shift_stride; /* B-M shift array */ u_int pattern_max_jump_size; /* Maximum distance we can jump to search for * this pattern again. */ OptFpList *fpl; /* Pointer to the OTN FPList for this pattern */ /* Needed to be able to set the isRelative flag */ /* Set if fast pattern matcher found a content in the packet, but the rule option specifies a negated content. Only applies to negative contents that are not relative */ struct { struct timeval ts; uint64_t packet_number; uint32_t rebuild_flag; } last_check; /* For fast_pattern arguments */ uint8_t fp; uint8_t fp_only; uint16_t fp_offset; uint16_t fp_length; uint8_t exception_flag; /* search for "not this pattern" */ /* Used in ds_list - do not try to iterate after parsing a rule * since the detection option tree will eliminate duplicates and * the list may have missing pmds */ struct _PatternMatchData *prev; /* ptr to previous match struct */ struct _PatternMatchData *next; /* ptr to next match struct */ Secure_Hash_Type pattern_type; int protected_length; bool protected_pattern; } PatternMatchData; /******************************************************************** * Public function prototypes ********************************************************************/ void SetupPatternMatch(void); PatternMatchData * NewNode(OptTreeNode *, int); void PatternMatchFree(void *d); uint32_t PatternMatchHash(void *d); int PatternMatchCompare(void *l, void *r); void FinalizeContentUniqueness(struct _SnortConfig *sc, OptTreeNode *otn); void ValidateFastPattern(OptTreeNode *otn); void make_precomp(PatternMatchData *); void ParsePattern(char *, OptTreeNode *, int); void ParseProtectedPattern(char *, OptTreeNode *, int); int uniSearchCI(const char *, int, PatternMatchData *); int CheckANDPatternMatch(void *, Packet *); int CheckUriPatternMatch(void *, Packet *); void PatternMatchDuplicatePmd(void *, PatternMatchData *); int PatternMatchAdjustRelativeOffsets(PatternMatchData *orig_pmd, PatternMatchData *dup_pmd, const uint8_t *current_cursor, const uint8_t *orig_cursor); #if 0 /* Not implemented */ int CheckORPatternMatch(Packet *, OptTreeNode *, OptFpList *); #endif static inline bool IsHttpBufFpEligible (HTTP_BUFFER http_buffer) { switch ( http_buffer ) { case HTTP_BUFFER_URI: case HTTP_BUFFER_HEADER: case HTTP_BUFFER_CLIENT_BODY: return true; default: break; } return false; } static inline PatternMatchData * RemovePmdFromList(PatternMatchData *pmd) { if (pmd == NULL) return NULL; if (pmd->prev) pmd->prev->next = pmd->next; if (pmd->next) pmd->next->prev = pmd->prev; pmd->next = NULL; pmd->prev = NULL; return pmd; } static inline int InsertPmdAtFront(PatternMatchData **head, PatternMatchData *ins) { if (head == NULL) return -1; if (ins == NULL) return 0; ins->next = *head; if (*head != NULL) (*head)->prev = ins; *head = ins; return 0; } static inline int AppendPmdToList(PatternMatchData **head, PatternMatchData *ins) { PatternMatchData *tmp; if (head == NULL) return -1; if (ins == NULL) return 0; if (*head == NULL) { *head = ins; ins->prev = NULL; return 0; } for (tmp = *head; tmp->next != NULL; tmp = tmp->next); tmp->next = ins; ins->prev = tmp; return 0; } static inline void FreePmdList(PatternMatchData *pmd_list) { if (pmd_list == NULL) return; while (pmd_list != NULL) { PatternMatchData *tmp = pmd_list->next; PatternMatchFree((void *)pmd_list); pmd_list = tmp; } } #endif /* __SP_PATTERN_MATCH_H__ */ snort-2.9.15.1/src/detection-plugins/sp_pcre.c0000644000175200017520000005635713571422607016113 00000000000000/* $Id$ */ /* ** Copyright (C) 2003 Brian Caswell ** Copyright (C) 2003 Michael J. Pomraning ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2003-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sf_types.h" #include "snort_bounds.h" #include "rules.h" #include "treenodes.h" #include "snort_debug.h" #include "decode.h" #include "plugbase.h" #include "parser.h" #include "plugin_enum.h" #include "util.h" #include "mstring.h" #include "sfhashfcn.h" #ifdef WIN32 #define PCRE_DEFINITION #endif #include "sp_pcre.h" #include #include "snort.h" #include "profiler.h" #ifdef PERF_PROFILING PreprocStats pcrePerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif #include "sfhashfcn.h" #include "detection_options.h" #include "detection_util.h" /* * we need to specify the vector length for our pcre_exec call. we only care * about the first vector, which if the match is successful will include the * offset to the end of the full pattern match. If we decide to store other * matches, make *SURE* that this is a multiple of 3 as pcre requires it. */ static int s_pcre_init = 1; void SnortPcreInit(struct _SnortConfig *, char *, OptTreeNode *, int); void SnortPcreParse(struct _SnortConfig *, char *, PcreData *, OptTreeNode *); void SnortPcreDump(PcreData *); int SnortPcre(void *option_data, Packet *p); void PcreFree(void *d) { PcreData *data = (PcreData *)d; free(data->expression); free(data->re); free(data->pe); free(data); } uint32_t PcreHash(void *d) { int i,j,k,l,expression_len; uint32_t a,b,c,tmp; PcreData *data = (PcreData *)d; expression_len = strlen(data->expression); a = b = c = 0; for (i=0,j=0;i 4) k=4; for (l=0;lexpression + i + l) << l*8; } switch (j) { case 0: a += tmp; break; case 1: b += tmp; break; case 2: c += tmp; break; } j++; if (j == 3) { mix(a,b,c); j=0; } } if (j != 0) { mix(a,b,c); } a += RULE_OPTION_TYPE_PCRE; b += data->options; final(a,b,c); return c; } int PcreCompare(void *l, void *r) { PcreData *left = (PcreData *)l; PcreData *right = (PcreData *)r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if (( strcmp(left->expression, right->expression) == 0) && ( left->options == right->options)) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } void PcreDuplicatePcreData(void *src, PcreData *pcre_dup) { PcreData *pcre_src = (PcreData *)src; pcre_dup->expression = pcre_src->expression; pcre_dup->options = pcre_src->options; pcre_dup->search_offset = 0; pcre_dup->pe = pcre_src->pe; pcre_dup->re = pcre_src->re; } int PcreAdjustRelativeOffsets(PcreData *pcre, uint32_t search_offset) { if ((pcre->options & (SNORT_PCRE_INVERT | SNORT_PCRE_ANCHORED))) { return 0; /* Don't search again */ } if (pcre->options & ( SNORT_PCRE_HTTP_BUFS )) { return 0; } /* What's coming in has the absolute offset */ pcre->search_offset += search_offset; return 1; /* Continue searcing */ } void SetupPcre(void) { RegisterRuleOption("pcre", SnortPcreInit, NULL, OPT_TYPE_DETECTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("pcre", &pcrePerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif } static void Ovector_Init(struct _SnortConfig *sc, int unused, void *data) { /* Since SO rules are loaded 1 time at startup, regardless of * configuraton, we won't pcre capture count again, so save the max. */ static int s_ovector_max = 0; /* The pcre_fullinfo() function can be used to find out how many * capturing subpatterns there are in a compiled pattern. The * smallest size for ovector that will allow for n captured * substrings, in addition to the offsets of the substring matched * by the whole pattern, is (n+1)*3. */ sc->pcre_ovector_size += 1; sc->pcre_ovector_size *= 3; if (sc->pcre_ovector_size > s_ovector_max) s_ovector_max = sc->pcre_ovector_size; sc->pcre_ovector = (int *) SnortAlloc(s_ovector_max*sizeof(int)); } #if SNORT_RELOAD static void Ovector_Reload(struct _SnortConfig *sc, int unused, void *data) { Ovector_Init(sc, unused, data); } #endif void PcreCapture(struct _SnortConfig *sc, const void *code, const void *extra) { int tmp_ovector_size = 0; pcre_fullinfo((const pcre *)code, (const pcre_extra *)extra, PCRE_INFO_CAPTURECOUNT, &tmp_ovector_size); if (tmp_ovector_size > sc->pcre_ovector_size) sc->pcre_ovector_size = tmp_ovector_size; if (s_pcre_init) { AddFuncToPostConfigList(sc, Ovector_Init, NULL); #if SNORT_RELOAD AddFuncToReloadList(Ovector_Reload, NULL); #endif s_pcre_init = 0; } } void SnortPcreInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { PcreData *pcre_data; OptFpList *fpl; void *pcre_dup; /* * allocate the data structure for pcre */ pcre_data = (PcreData *) SnortAlloc(sizeof(PcreData)); SnortPcreParse(sc, data, pcre_data, otn); otn->pcre_flag = 1; fpl = AddOptFuncToList(SnortPcre, otn); fpl->type = RULE_OPTION_TYPE_PCRE; if (add_detection_option(sc, RULE_OPTION_TYPE_PCRE, (void *)pcre_data, &pcre_dup) == DETECTION_OPTION_EQUAL) { #ifdef DEBUG_RULE_OPTION_TREE LogMessage("Duplicate PCRE:\n%d %s\n%d %s\n\n", pcre_data->options, pcre_data->expression, ((PcreData *)pcre_dup)->options, ((PcreData *)pcre_dup)->expression); #endif if (pcre_data->expression) free(pcre_data->expression); if (pcre_data->pe) free(pcre_data->pe); if (pcre_data->re) free(pcre_data->re); free(pcre_data); pcre_data = pcre_dup; } /* * attach it to the context node so that we can call each instance * individually */ fpl->context = (void *) pcre_data; if (pcre_data->options & SNORT_PCRE_RELATIVE) fpl->isRelative = 1; if (otn->ds_list[PLUGIN_PCRE] == NULL) otn->ds_list[PLUGIN_PCRE] = (void *)pcre_data; return; } static inline void ValidatePcreHttpContentModifiers(PcreData *pcre_data) { if( pcre_data->options & SNORT_PCRE_RELATIVE ) FatalError("%s(%d): PCRE unsupported configuration : both relative & uri options specified\n", file_name, file_line); if( pcre_data->options & SNORT_PCRE_RAWBYTES ) FatalError("%s(%d): PCRE unsupported configuration : both rawbytes & uri options specified\n", file_name, file_line); } void SnortPcreParse(struct _SnortConfig *sc, char *data, PcreData *pcre_data, OptTreeNode *otn) { const char *error; char *re, *free_me; char *opts; char delimit = '/'; int erroffset; int compile_flags = 0; unsigned http = 0; if(data == NULL) { FatalError("%s (%d): pcre requires a regular expression\n", file_name, file_line); } free_me = SnortStrdup(data); re = free_me; /* get rid of starting and ending whitespace */ while (isspace((int)re[strlen(re)-1])) re[strlen(re)-1] = '\0'; while (isspace((int)*re)) re++; if(*re == '!') { pcre_data->options |= SNORT_PCRE_INVERT; re++; while(isspace((int)*re)) re++; } /* now we wrap the RE in double quotes. stupid snort parser.... */ if(*re != '"') { printf("It isn't \"\n"); goto syntax; } re++; if(re[strlen(re)-1] != '"') { printf("It isn't \"\n"); goto syntax; } /* remove the last quote from the string */ re[strlen(re) - 1] = '\0'; /* 'm//' or just '//' */ if(*re == 'm') { re++; if(! *re) goto syntax; /* Space as a ending delimiter? Uh, no. */ if(isspace((int)*re)) goto syntax; /* using R would be bad, as it triggers RE */ if(*re == 'R') goto syntax; delimit = *re; } else if(*re != delimit) goto syntax; pcre_data->expression = SnortStrdup(re); /* find ending delimiter, trim delimit chars */ opts = strrchr(re, delimit); if (opts == NULL) goto syntax; if(!((opts - re) > 1)) /* empty regex(m||) or missing delim not OK */ goto syntax; re++; *opts++ = '\0'; /* process any /regex/ismxR options */ while(*opts != '\0') { switch(*opts) { case 'i': compile_flags |= PCRE_CASELESS; break; case 's': compile_flags |= PCRE_DOTALL; break; case 'm': compile_flags |= PCRE_MULTILINE; break; case 'x': compile_flags |= PCRE_EXTENDED; break; /* * these are pcre specific... don't work with perl */ case 'A': compile_flags |= PCRE_ANCHORED; break; case 'E': compile_flags |= PCRE_DOLLAR_ENDONLY; break; case 'G': compile_flags |= PCRE_UNGREEDY; break; /* * these are snort specific don't work with pcre or perl */ case 'R': pcre_data->options |= SNORT_PCRE_RELATIVE; break; case 'B': pcre_data->options |= SNORT_PCRE_RAWBYTES; break; case 'O': pcre_data->options |= SNORT_OVERRIDE_MATCH_LIMIT; break; case 'U': pcre_data->options |= SNORT_PCRE_HTTP_URI; http++; break; case 'P': pcre_data->options |= SNORT_PCRE_HTTP_BODY; http++; break; case 'H': pcre_data->options |= SNORT_PCRE_HTTP_HEADER; http++; break; case 'M': pcre_data->options |= SNORT_PCRE_HTTP_METHOD; http++; break; case 'C': pcre_data->options |= SNORT_PCRE_HTTP_COOKIE; http++; break; case 'I': pcre_data->options |= SNORT_PCRE_HTTP_RAW_URI; http++; break; case 'D': pcre_data->options |= SNORT_PCRE_HTTP_RAW_HEADER; http++; break; case 'K': pcre_data->options |= SNORT_PCRE_HTTP_RAW_COOKIE; http++; break; case 'S': pcre_data->options |= SNORT_PCRE_HTTP_STAT_CODE; http++; break; case 'Y': pcre_data->options |= SNORT_PCRE_HTTP_STAT_MSG; http++; break; default: FatalError("%s (%d): unknown/extra pcre option encountered\n", file_name, file_line); } opts++; } if ( http > 1 ) ParseWarning("at most one HTTP buffer may be indicated with pcre"); if(pcre_data->options & (SNORT_PCRE_HTTP_BUFS)) ValidatePcreHttpContentModifiers(pcre_data); /* now compile the re */ DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "pcre: compiling %s\n", re);); pcre_data->re = pcre_compile(re, compile_flags, &error, &erroffset, NULL); if(pcre_data->re == NULL) { FatalError("%s(%d) : pcre compile of \"%s\" failed at offset " "%d : %s\n", file_name, file_line, re, erroffset, error); } /* now study it... */ pcre_data->pe = pcre_study(pcre_data->re, 0, &error); if (pcre_data->pe) { if ((ScPcreMatchLimitNewConf(sc) != -1) && !(pcre_data->options & SNORT_OVERRIDE_MATCH_LIMIT)) { if (pcre_data->pe->flags & PCRE_EXTRA_MATCH_LIMIT) { pcre_data->pe->match_limit = ScPcreMatchLimitNewConf(sc); } else { pcre_data->pe->flags |= PCRE_EXTRA_MATCH_LIMIT; pcre_data->pe->match_limit = ScPcreMatchLimitNewConf(sc); } } #ifdef PCRE_EXTRA_MATCH_LIMIT_RECURSION if ((ScPcreMatchLimitRecursionNewConf(sc) != -1) && !(pcre_data->options & SNORT_OVERRIDE_MATCH_LIMIT)) { if (pcre_data->pe->flags & PCRE_EXTRA_MATCH_LIMIT_RECURSION) { pcre_data->pe->match_limit_recursion = ScPcreMatchLimitRecursionNewConf(sc); } else { pcre_data->pe->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION; pcre_data->pe->match_limit_recursion = ScPcreMatchLimitRecursionNewConf(sc); } } #endif } else { if (!(pcre_data->options & SNORT_OVERRIDE_MATCH_LIMIT) && ((ScPcreMatchLimitNewConf(sc) != -1) || (ScPcreMatchLimitRecursionNewConf(sc) != -1))) { pcre_data->pe = (pcre_extra *)SnortAlloc(sizeof(pcre_extra)); if (ScPcreMatchLimitNewConf(sc) != -1) { pcre_data->pe->flags |= PCRE_EXTRA_MATCH_LIMIT; pcre_data->pe->match_limit = ScPcreMatchLimitNewConf(sc); } #ifdef PCRE_EXTRA_MATCH_LIMIT_RECURSION if (ScPcreMatchLimitRecursionNewConf(sc) != -1) { pcre_data->pe->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION; pcre_data->pe->match_limit_recursion = ScPcreMatchLimitRecursionNewConf(sc); } #endif } } if(error != NULL) { FatalError("%s(%d) : pcre study failed : %s\n", file_name, file_line, error); } PcreCapture(sc, pcre_data->re, pcre_data->pe); PcreCheckAnchored(pcre_data); free(free_me); return; syntax: free(free_me); FatalError("%s Line %d => unable to parse pcre regex %s\n", file_name, file_line, data); } void PcreCheckAnchored(PcreData *pcre_data) { int rc; unsigned long int options = 0; if ((pcre_data == NULL) || (pcre_data->re == NULL) || (pcre_data->pe == NULL)) return; rc = pcre_fullinfo(pcre_data->re, pcre_data->pe, PCRE_INFO_OPTIONS, (void *)&options); switch (rc) { /* pcre_fullinfo fails for the following: * PCRE_ERROR_NULL - the argument code was NULL * the argument where was NULL * PCRE_ERROR_BADMAGIC - the "magic number" was not found * PCRE_ERROR_BADOPTION - the value of what was invalid * so a failure here means we passed in bad values and we should * probably fatal error */ case 0: /* This is the success code */ break; case PCRE_ERROR_NULL: FatalError("%s(%d) pcre_fullinfo: code and/or where were NULL.\n", __FILE__, __LINE__); case PCRE_ERROR_BADMAGIC: FatalError("%s(%d) pcre_fullinfo: compiled code didn't have " "correct magic.\n", __FILE__, __LINE__); case PCRE_ERROR_BADOPTION: FatalError("%s(%d) pcre_fullinfo: option type is invalid.\n", __FILE__, __LINE__); default: FatalError("%s(%d) pcre_fullinfo: Unknown error code.\n", __FILE__, __LINE__); } if ((options & PCRE_ANCHORED) && !(options & PCRE_MULTILINE)) { /* This means that this pcre rule option shouldn't be reevaluted * even if any of it's relative children should fail to match. * It is anchored to the cursor set by the previous cursor setting * rule option */ pcre_data->options |= SNORT_PCRE_ANCHORED; } } /** * Perform a search of the PCRE data. * * @param pcre_data structure that options and patterns are passed in * @param buf buffer to search * @param len size of buffer * @param start_offset initial offset into the buffer * @param found_offset pointer to an integer so that we know where the search ended * * *found_offset will be set to -1 when the find is unsucessful OR the routine is inverted * * @return 1 when we find the string, 0 when we don't (unless we've been passed a flag to invert) */ static int pcre_search(const PcreData *pcre_data, const char *buf, int len, int start_offset, int *found_offset) { int matched; int result; if(pcre_data == NULL || buf == NULL || len <= 0 || start_offset < 0 || start_offset >= len || found_offset == NULL) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Returning 0 because we didn't have the required parameters!\n");); return 0; } *found_offset = -1; result = pcre_exec(pcre_data->re, /* result of pcre_compile() */ pcre_data->pe, /* result of pcre_study() */ buf, /* the subject string */ len, /* the length of the subject string */ start_offset, /* start at offset 0 in the subject */ 0, /* options(handled at compile time */ snort_conf->pcre_ovector, /* vector for substring information */ snort_conf->pcre_ovector_size);/* number of elements in the vector */ if(result >= 0) { matched = 1; /* From the PCRE man page: * When a match is successful, information about captured substrings is returned in pairs of integers, * starting at the beginning of ovector, and continuing up to two-thirds of its length at the most. * The first element of a pair is set to the offset of the first character in a substring, and the * second is set to the offset of the first character after the end of a substring. The first pair, * ovector[0] and ovector[1], identify the portion of the subject string matched by the entire pattern. * The next pair is used for the first capturing subpattern, and so on. The value returned by * pcre_exec() is the number of pairs that have been set. If there are no capturing subpatterns, the * return value from a successful match is 1, indicating that just the first pair of offsets has been set. * * In Snort's case, the ovector size only allows for the first pair and a single int for scratch space. */ *found_offset = snort_conf->pcre_ovector[1]; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Setting Doe_ptr and found_offset: %p %d\n", doe_ptr, found_offset);); } else if(result == PCRE_ERROR_NOMATCH) { matched = 0; } else { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "pcre_exec error : %d \n", result);); return 0; } /* invert sense of match */ if(pcre_data->options & SNORT_PCRE_INVERT) { matched = !matched; } return matched; } int SnortPcre(void *option_data, Packet *p) { PcreData *pcre_data = (PcreData *)option_data; int found_offset = -1; /* where is the ending location of the pattern */ const uint8_t *base_ptr, *end_ptr, *start_ptr; int dsize; int length; /* length of the buffer pointed to by base_ptr */ int matched = 0; uint8_t rst_doe_flags = 1; unsigned hb_type; DEBUG_WRAP(char *hexbuf;) PROFILE_VARS; PREPROC_PROFILE_START(pcrePerfStats); //short circuit this for testing pcre performance impact if (ScNoPcre()) { PREPROC_PROFILE_END(pcrePerfStats); return DETECTION_OPTION_NO_MATCH; } /* This is the HTTP case */ if ( (hb_type = pcre_data->options & SNORT_PCRE_HTTP_BUFS) ) { const HttpBuffer* hb = GetHttpBuffer(hb_type); if ( hb ) { matched = pcre_search( pcre_data, (const char*)hb->buf, hb->length, 0, &found_offset); if ( matched ) { /* don't touch doe_ptr on URI contents */ PREPROC_PROFILE_END(pcrePerfStats); return DETECTION_OPTION_MATCH; } } PREPROC_PROFILE_END(pcrePerfStats); return DETECTION_OPTION_NO_MATCH; } /* end of the HTTP case */ if( !(pcre_data->options & SNORT_PCRE_RAWBYTES)) { if(Is_DetectFlag(FLAG_ALT_DETECT)) { dsize = DetectBuffer.len; start_ptr = DetectBuffer.data; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "using alternative detect buffer in pcre!\n");); } else if(Is_DetectFlag(FLAG_ALT_DECODE)) { dsize = DecodeBuffer.len; start_ptr = DecodeBuffer.data; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "using alternative decode buffer in pcre!\n");); } else { if(IsLimitedDetect(p)) dsize = p->alt_dsize; else dsize = p->dsize; start_ptr = p->data; } } else { dsize = p->dsize; start_ptr = p->data; } base_ptr = start_ptr; end_ptr = start_ptr + dsize; /* doe_ptr's would be set by the previous content option */ if(pcre_data->options & SNORT_PCRE_RELATIVE && doe_ptr) { if(!inBounds(start_ptr, end_ptr, doe_ptr)) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "pcre bounds check failed on a relative content match\n");); PREPROC_PROFILE_END(pcrePerfStats); return DETECTION_OPTION_NO_MATCH; } DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "pcre ... checking relative offset\n");); base_ptr = doe_ptr; rst_doe_flags = 0; } else { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "pcre ... checking absolute offset\n");); base_ptr = start_ptr; } length = end_ptr - base_ptr; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "pcre ... base: %p start: %p end: %p doe: %p length: %d\n", base_ptr, start_ptr, end_ptr, doe_ptr, length);); DEBUG_WRAP(hexbuf = hex(base_ptr, length); DebugMessage(DEBUG_PATTERN_MATCH, "pcre payload: %s\n", hexbuf); free(hexbuf); ); matched = pcre_search(pcre_data, (const char *)base_ptr, length, pcre_data->search_offset, &found_offset); /* set the doe_ptr if we have a valid offset */ if(found_offset > 0) { UpdateDoePtr(((uint8_t *) base_ptr + found_offset), rst_doe_flags); } if (matched) { PREPROC_PROFILE_END(pcrePerfStats); return DETECTION_OPTION_MATCH; } /* finally return 0 */ PREPROC_PROFILE_END(pcrePerfStats); return DETECTION_OPTION_NO_MATCH; } snort-2.9.15.1/src/detection-plugins/sp_pcre.h0000644000175200017520000000562113571422607016104 00000000000000/* ** Copyright (C) 2003 Brian Caswell ** Copyright (C) 2003 Michael J. Pomraning ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2003-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* I N C L U D E S **********************************************************/ /* D E F I N E S ************************************************************/ #ifndef __SNORT_PCRE_H__ #define __SNORT_PCRE_H__ // low nibble must be same as HTTP_BUFFER_* // see detection_util.h for enum #define SNORT_PCRE_HTTP_URI 0x00001 // check URI buffers #define SNORT_PCRE_HTTP_HEADER 0x00002 // Check HTTP header buffer #define SNORT_PCRE_HTTP_BODY 0x00003 // Check HTTP body buffer #define SNORT_PCRE_HTTP_METHOD 0x00004 // Check HTTP method buffer #define SNORT_PCRE_HTTP_COOKIE 0x00005 // Check HTTP cookie buffer #define SNORT_PCRE_HTTP_STAT_CODE 0x00006 #define SNORT_PCRE_HTTP_STAT_MSG 0x00007 #define SNORT_PCRE_HTTP_RAW_URI 0x00008 #define SNORT_PCRE_HTTP_RAW_HEADER 0x00009 #define SNORT_PCRE_HTTP_RAW_COOKIE 0x0000A #define SNORT_PCRE_HTTP_BUFS 0x0000F #define SNORT_PCRE_RELATIVE 0x00010 // relative to the end of the last match #define SNORT_PCRE_INVERT 0x00020 // invert detect #define SNORT_PCRE_RAWBYTES 0x00040 // Don't use decoded buffer (if available) #define SNORT_PCRE_ANCHORED 0x00080 #define SNORT_OVERRIDE_MATCH_LIMIT 0x00100 // Override default limits on match & match recursion void SetupPcre(void); #include typedef struct _PcreData { pcre *re; /* compiled regex */ pcre_extra *pe; /* studied regex foo */ int options; /* sp_pcre specfic options (relative & inverse) */ char *expression; uint32_t search_offset; } PcreData; void PcreCapture(struct _SnortConfig *sc, const void *code, const void *extra); void PcreFree(void *d); uint32_t PcreHash(void *d); int PcreCompare(void *l, void *r); void PcreDuplicatePcreData(void *src, PcreData *pcre_dup); int PcreAdjustRelativeOffsets(PcreData *pcre, uint32_t search_offset); void PcreCheckAnchored(PcreData *); #endif /* __SNORT_PCRE_H__ */ snort-2.9.15.1/src/detection-plugins/sp_replace.c0000644000175200017520000003052713571422607016564 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_STRINGS_H #include #endif #include "sf_types.h" #include "snort_bounds.h" #include "snort_debug.h" #include "decode.h" #include "parser.h" #include "sp_replace.h" #include "snort.h" #include "sfdaq.h" #define MAX_PATTERN_SIZE 2048 extern int lastType; static PatternMatchData* Replace_Parse(char*, OptTreeNode*); void PayloadReplaceInit(struct _SnortConfig *sc, char *data, OptTreeNode * otn, int protocol) { static int warned = 0; PatternMatchData *idx; if( !ScIpsInlineModeNewConf(sc) ) return; if ( !DAQ_CanReplace() ) { if ( !warned ) { LogMessage("WARNING: payload replacements disabled because DAQ " " can't replace packets.\n"); warned = 1; } return; } if ( lastType == PLUGIN_PATTERN_MATCH_URI ) { FatalError("%s(%d) => \"replace\" option is not supported " "with uricontent, nor in conjunction with http_uri, " "http_header, http_method http_cookie," "http_raw_uri, http_raw_header, or " "http_raw_cookie modifiers.\n", file_name, file_line); } idx = (PatternMatchData *) otn->ds_list[PLUGIN_PATTERN_MATCH]; if(idx == NULL) { FatalError("%s(%d) => Please place \"content\" rules " "before depth, nocase, replace or offset modifiers.\n", file_name, file_line); } Replace_Parse(data, otn); } static PatternMatchData * Replace_Parse(char *rule, OptTreeNode * otn) { char tmp_buf[MAX_PATTERN_SIZE]; /* got enough ptrs for you? */ char *start_ptr; char *end_ptr; char *idx; const char *dummy_idx; const char *dummy_end; char hex_buf[3]; u_int dummy_size = 0; int size; int hexmode = 0; int hexsize = 0; int pending = 0; int cnt = 0; int literal = 0; PatternMatchData *ds_idx; int ret; if ( !rule ) { FatalError("%s(%d) => missing argument to 'replace' option\n", file_name, file_line); } /* clear out the temp buffer */ memset(tmp_buf, 0, MAX_PATTERN_SIZE); while(isspace((int)*rule)) rule++; /* find the start of the data */ start_ptr = strchr(rule, '"'); if(start_ptr == NULL) { FatalError("%s(%d) => Replace data needs to be " "enclosed in quotation marks (\")!\n", file_name, file_line); } /* move the start up from the beggining quotes */ start_ptr++; /* find the end of the data */ end_ptr = strrchr(start_ptr, '"'); if(end_ptr == NULL) { FatalError("%s(%d) => Replace data needs to be enclosed " "in quotation marks (\")!\n", file_name, file_line); } /* set the end to be NULL */ *end_ptr = '\0'; /* how big is it?? */ size = end_ptr - start_ptr; /* uh, this shouldn't happen */ if(size <= 0) { FatalError("%s(%d) => Replace data has bad pattern length!\n", file_name, file_line); } /* set all the pointers to the appropriate places... */ idx = start_ptr; /* set the indexes into the temp buffer */ dummy_idx = tmp_buf; dummy_end = (dummy_idx + size); /* why is this buffer so small? */ memset(hex_buf, '0', 2); hex_buf[2] = '\0'; /* BEGIN BAD JUJU..... */ while(idx < end_ptr) { if (dummy_size >= MAX_PATTERN_SIZE-1) { /* Have more data to parse and pattern is about to go beyond end of buffer */ FatalError("%s(%d) => Replace buffer overflow, make a " "smaller pattern please! (Max size = %d)\n", file_name, file_line, MAX_PATTERN_SIZE-1); } DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "processing char: %c\n", *idx);); switch(*idx) { case '|': DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "Got bar... ");); if(!literal) { DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "not in literal mode... ");); if(!hexmode) { DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "Entering hexmode\n");); hexmode = 1; } else { DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "Exiting hexmode\n");); hexmode = 0; pending = 0; } if(hexmode) hexsize = 0; } else { DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "literal set, Clearing\n");); literal = 0; tmp_buf[dummy_size] = start_ptr[cnt]; dummy_size++; } break; case '\\': DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "Got literal char... ");); if(!literal) { DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "Setting literal\n");); literal = 1; } else { DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "Clearing literal\n");); tmp_buf[dummy_size] = start_ptr[cnt]; literal = 0; dummy_size++; } break; default: if(hexmode) { if(isxdigit((int) *idx)) { hexsize++; if(!pending) { hex_buf[0] = *idx; pending++; } else { hex_buf[1] = *idx; pending--; if(dummy_idx < dummy_end) { tmp_buf[dummy_size] = (u_char) strtol(hex_buf, (char **) NULL, 16)&0xFF; dummy_size++; memset(hex_buf, '0', 2); hex_buf[2] = '\0'; } else { FatalError("%s(%d) => Replace buffer overflow, make a " "smaller pattern please! (Max size = %d)\n", file_name, file_line, MAX_PATTERN_SIZE-1); } } } else { if(*idx != ' ') { FatalError("%s(%d) => Replace found \"%c\"(0x%X) in " "your binary buffer. Valid hex values only " "please! (0x0 -0xF) Position: %d\n", file_name, file_line, (char) *idx, (char) *idx, cnt); } } } else { if(*idx >= 0x1F && *idx <= 0x7e) { if(dummy_idx < dummy_end) { tmp_buf[dummy_size] = start_ptr[cnt]; dummy_size++; } else { FatalError("%s(%d) => Replace buffer overflow!\n", file_name, file_line); } if(literal) { literal = 0; } } else { if(literal) { tmp_buf[dummy_size] = start_ptr[cnt]; dummy_size++; DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "Clearing literal\n");); literal = 0; } else { FatalError("%s(%d) => Replace found character value out of " "range, only hex characters allowed in binary " "content buffers\n", file_name, file_line); } } } break; } /* end switch */ dummy_idx++; idx++; cnt++; } /* ...END BAD JUJU */ /* error pruning */ if (literal) { FatalError("%s(%d) => Replace backslash escape is not completed\n", file_name, file_line); } if (hexmode) { FatalError("%s(%d) => Replace hexmode is not completed\n", file_name, file_line); } ds_idx = (PatternMatchData *) otn->ds_list[PLUGIN_PATTERN_MATCH]; while(ds_idx->next != NULL) ds_idx = ds_idx->next; if((ds_idx->replace_buf = (char *) calloc(dummy_size+1, sizeof(char))) == NULL) { FatalError("%s(%d) => Replace pattern_buf malloc failed!\n", file_name, file_line); } ret = SafeMemcpy(ds_idx->replace_buf, tmp_buf, dummy_size, ds_idx->replace_buf, (ds_idx->replace_buf+dummy_size)); if (ret == SAFEMEM_ERROR) { FatalError("%s(%d) => Replace SafeMemcpy failed\n", file_name, file_line); } ds_idx->replace_size = dummy_size; DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "ds_idx (%p) replace_size(%d) replace_buf(%s)\n", ds_idx, ds_idx->replace_size, ds_idx->replace_buf);); return ds_idx; } typedef struct { const char* data; int size; int depth; } Replacement; #define MAX_REPLACEMENTS 32 static Replacement rpl[MAX_REPLACEMENTS]; static int num_rpl = 0; void Replace_ResetQueue(void) { num_rpl = 0; } void Replace_QueueChange(PatternMatchData* pmd) { Replacement* r; if ( num_rpl == MAX_REPLACEMENTS ) return; r = rpl + num_rpl++; r->data = pmd->replace_buf; r->size = pmd->replace_size; r->depth = pmd->replace_depth; } static inline void Replace_ApplyChange(Packet *p, Replacement* r) { int err; int rsize; if( (p->data + r->depth + r->size) >= (p->data + p->dsize)) rsize = (p->dsize - r->depth); else rsize = r->size; err = SafeMemcpy( (void *)(p->data + r->depth), r->data, rsize, p->data, (p->data + p->dsize) ); if ( err == SAFEMEM_ERROR ) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Replace_Apply() => SafeMemcpy() failed\n");); return; } } void Replace_ModifyPacket(Packet *p) { int n; if ( num_rpl == 0 ) return; for ( n = 0; n < num_rpl; n++ ) { Replace_ApplyChange(p, rpl+n); } p->packet_flags |= PKT_MODIFIED; num_rpl = 0; } snort-2.9.15.1/src/detection-plugins/sp_replace.h0000644000175200017520000000313113571422607016560 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __SP_REPLACE_H__ #define __SP_REPLACE_H__ #include "sp_pattern_match.h" void PayloadReplaceInit(struct _SnortConfig *, char *, OptTreeNode *, int); extern void Replace_ResetQueue(void); extern void Replace_QueueChange(PatternMatchData*); extern void Replace_ModifyPacket(Packet*); static inline void Replace_ResetOffset(PatternMatchData* pmd) { pmd->replace_depth = -1; } static inline void Replace_StoreOffset(PatternMatchData* pmd, int detect_depth) { pmd->replace_depth = detect_depth; } static inline int Replace_OffsetStored(PatternMatchData* pmd) { return pmd->replace_depth >= 0; } #endif /* __SP_REACT_H__ */ snort-2.9.15.1/src/detection-plugins/sp_rpc_check.c0000644000175200017520000002552513571422607017074 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifndef WIN32 #include #endif /* !WIN32 */ #include "rules.h" #include "treenodes.h" #include "decode.h" #include "plugbase.h" #include "parser.h" #include "snort_debug.h" #include "util.h" #include "plugin_enum.h" #include "sfhashfcn.h" #include "snort.h" #include "profiler.h" #ifdef PERF_PROFILING PreprocStats rpcCheckPerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif #include "sfhashfcn.h" #include "detection_options.h" /* * This is driven by 64-bit Solaris which doesn't * define _LONG * */ #ifndef IXDR_GET_LONG #define IXDR_GET_LONG IXDR_GET_INT32 #endif #define GET_32BITS(buf) (ntohl(*(*(uint32_t **)&(buf))++)) typedef struct _RpcCheckData { u_long program; /* RPC program number */ u_long vers; /* RPC program version */ u_long proc; /* RPC procedure number */ int flags; /* Which of the above fields have been specified */ } RpcCheckData; #define RPC_CHECK_PROG 1 #define RPC_CHECK_VERS 2 #define RPC_CHECK_PROC 4 void RpcCheckInit(struct _SnortConfig *, char *, OptTreeNode *, int); void ParseRpc(struct _SnortConfig *, char *, OptTreeNode *); int CheckRpc(void *option_data, Packet *p); uint32_t RpcCheckHash(void *d) { uint32_t a,b,c; RpcCheckData *data = (RpcCheckData *)d; a = data->program; b = data->vers; c = data->proc; mix(a,b,c); a += data->flags; b += RULE_OPTION_TYPE_RPC_CHECK; final(a,b,c); return c; } int RpcCheckCompare(void *l, void *r) { RpcCheckData *left = (RpcCheckData *)l; RpcCheckData *right = (RpcCheckData *)r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if ((left->program == right->program) && (left->vers == right->vers) && (left->proc == right->proc) && (left->flags == right->flags)) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } /**************************************************************************** * * Function: SetupRpcCheck() * * Purpose: Register the rpc option keyword with its setup function * * Arguments: None. * * Returns: void function * ****************************************************************************/ void SetupRpcCheck(void) { /* map the keyword to an initialization/processing function */ RegisterRuleOption("rpc", RpcCheckInit, NULL, OPT_TYPE_DETECTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("rpc", &rpcCheckPerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Plugin: RPCCheck Initialized\n");); } /**************************************************************************** * * Function: RpcCheckInit(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: Parse the rpc keyword arguments and link the detection module * into the function list * * Arguments: data => rule arguments/data * otn => pointer to the current rule option list node * * Returns: void function * ****************************************************************************/ void RpcCheckInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { OptFpList *fpl; if(protocol != IPPROTO_TCP && protocol != IPPROTO_UDP) { FatalError("%s(%d) => Bad protocol in RPC Check rule...\n", file_name, file_line); } /* multiple declaration check */ if(otn->ds_list[PLUGIN_RPC_CHECK]) { FatalError("%s(%d): Multiple rpc options in rule\n", file_name, file_line); } /* allocate the data structure and attach it to the rule's data struct list */ otn->ds_list[PLUGIN_RPC_CHECK] = (RpcCheckData *) SnortAlloc(sizeof(RpcCheckData)); /* this is where the keyword arguments are processed and placed into the rule option's data structure */ ParseRpc(sc, data, otn); /* finally, attach the option's detection function to the rule's detect function pointer list */ fpl = AddOptFuncToList(CheckRpc, otn); fpl->type = RULE_OPTION_TYPE_RPC_CHECK; fpl->context = otn->ds_list[PLUGIN_RPC_CHECK]; } /**************************************************************************** * * Function: ParseRpc(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: Parse the RPC keyword's arguments * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ void ParseRpc(struct _SnortConfig *sc, char *data, OptTreeNode *otn) { RpcCheckData *ds_ptr; /* data struct pointer */ void *ds_ptr_dup; char *tmp = NULL; /* set the ds pointer to make it easier to reference the option's particular data struct */ ds_ptr = otn->ds_list[PLUGIN_RPC_CHECK]; ds_ptr->flags=0; /* advance past whitespace */ while(isspace((int)*data)) data++; if(*data != '*') { ds_ptr->program = strtoul(data,&tmp,0); ds_ptr->flags|=RPC_CHECK_PROG; DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Set RPC program to %lu\n", ds_ptr->program);); } else { FatalError("%s(%d): Invalid applicaion number in rpc rule option\n",file_name,file_line); } if(*tmp == '\0') return; data=++tmp; if(*data != '*') { ds_ptr->vers = strtoul(data,&tmp,0); ds_ptr->flags|=RPC_CHECK_VERS; DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Set RPC vers to %lu\n", ds_ptr->vers);); } else { tmp++; } if(*tmp == '\0') return; data=++tmp; if(*data != '*') { ds_ptr->proc = strtoul(data,&tmp,0); ds_ptr->flags|=RPC_CHECK_PROC; DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Set RPC proc to %lu\n", ds_ptr->proc);); } if (add_detection_option(sc, RULE_OPTION_TYPE_RPC_CHECK, (void *)ds_ptr, &ds_ptr_dup) == DETECTION_OPTION_EQUAL) { free(ds_ptr); ds_ptr = otn->ds_list[PLUGIN_RPC_CHECK] = ds_ptr_dup; } } /**************************************************************************** * * Function: CheckRpc(char *, OptTreeNode *) * * Purpose: Test if the packet RPC equals the rule option's rpc * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: 0 on failure, return value of next list function on success * ****************************************************************************/ int CheckRpc(void *option_data, Packet *p) { RpcCheckData *ds_ptr = (RpcCheckData *)option_data; unsigned char* c=(unsigned char*)p->data; u_long rpcvers, prog, vers, proc; enum msg_type direction; int rval = DETECTION_OPTION_NO_MATCH; #ifdef DEBUG_MSGS int i; #endif PROFILE_VARS; if(!p->iph_api || (IsTCP(p) && !p->tcph) || (IsUDP(p) && !p->udph)) return 0; /* if error occured while ip header * was processed, return 0 automagically. */ PREPROC_PROFILE_START(rpcCheckPerfStats); if( IsTCP(p) ) { /* offset to rpc_msg */ c+=4; /* Fail if the packet is too short to match */ if(p->dsize<28) { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "RPC packet too small");); PREPROC_PROFILE_END(rpcCheckPerfStats); return rval; } } else { /* must be UDP */ /* Fail if the packet is too short to match */ if(p->dsize<24) { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "RPC packet too small");); PREPROC_PROFILE_END(rpcCheckPerfStats); return rval; } } #ifdef DEBUG_MSGS DebugMessage(DEBUG_PLUGIN,"<---xid---> <---dir---> <---rpc--->" " <---prog--> <---vers--> <---proc-->\n"); for(i=0; i<24; i++) { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "%02X ",c[i]);); } DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"\n");); #endif /* Read xid */ GET_32BITS(c); /* Read direction : CALL or REPLY */ direction = (enum msg_type)GET_32BITS(c); /* We only look at calls */ if(direction != CALL) { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "RPC packet not a call");); PREPROC_PROFILE_END(rpcCheckPerfStats); return rval; } /* Read the RPC message version */ rpcvers = GET_32BITS(c); /* Fail if it is not right */ if(rpcvers != RPC_MSG_VERSION) { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"RPC msg version invalid");); PREPROC_PROFILE_END(rpcCheckPerfStats); return rval; } /* Read the program number, version, and procedure */ prog = GET_32BITS(c); vers = GET_32BITS(c); proc = GET_32BITS(c); DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"RPC decoded to: %lu %lu %lu\n", prog,vers,proc);); DEBUG_WRAP( DebugMessage(DEBUG_PLUGIN, "RPC matching on: %d %d %d\n", ds_ptr->flags & RPC_CHECK_PROG,ds_ptr->flags & RPC_CHECK_VERS, ds_ptr->flags & RPC_CHECK_PROC);); if(!(ds_ptr->flags & RPC_CHECK_PROG) || ds_ptr->program == prog) { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"RPC program matches");); if(!(ds_ptr->flags & RPC_CHECK_VERS) || ds_ptr->vers == vers) { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"RPC version matches");); if(!(ds_ptr->flags & RPC_CHECK_PROC) || ds_ptr->proc == proc) { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"RPC proc matches");); DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Yippee! Found one!");); rval = DETECTION_OPTION_MATCH; } } } else { /* you can put debug comments here or not */ DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"RPC not equal\n");); } /* if the test isn't successful, return 0 */ PREPROC_PROFILE_END(rpcCheckPerfStats); return rval; } snort-2.9.15.1/src/detection-plugins/sp_rpc_check.h0000644000175200017520000000221413571422607017067 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifndef __SP_RPC_CHECK_H__ #define __SP_RPC_CHECK_H__ void SetupRpcCheck(void); uint32_t RpcCheckHash(void *d); int RpcCheckCompare(void *l, void *r); #endif /* __SP_RPC_CHECK_H__ */ snort-2.9.15.1/src/detection-plugins/sp_session.c0000644000175200017520000003025413571422607016631 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Snort Session Logging Plugin */ /* sp_session * * Purpose: * * Drops data (printable or otherwise) into a SESSION file. Useful for * logging user sessions (telnet, http, ftp, etc). * * Arguments: * * This plugin can take two arguments: * printable => only log the "printable" ASCII characters. * all => log all traffic in the session, logging non-printable * chars in "\xNN" hexidecimal format * * Effect: * * Warning, this plugin may slow Snort *way* down! * */ /* put the name of your pluging header file here */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #ifndef WIN32 #include #include #include #endif /* !WIN32 */ #include #include #include #include #ifdef HAVE_STRINGS_H #include #endif #include #include #include "rules.h" #include "treenodes.h" #include "decode.h" #include "plugbase.h" #include "parser.h" #include "snort_debug.h" #include "util.h" #include "plugin_enum.h" #include "snort.h" #include "snort.h" #include "profiler.h" #ifdef PERF_PROFILING PreprocStats sessionPerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif #include "sfhashfcn.h" #include "detection_options.h" #define SESSION_PRINTABLE 1 #define SESSION_ALL 2 #define SESSION_BINARY 3 typedef struct _SessionData { int session_flag; } SessionData; void SessionInit(struct _SnortConfig *, char *, OptTreeNode *, int); void ParseSession(char *, OptTreeNode *); int LogSessionData(void *option_data, Packet *p); void DumpSessionData(FILE *, Packet *, SessionData *); FILE *OpenSessionFile(Packet *); uint32_t SessionHash(void *d) { uint32_t a,b,c; SessionData *data = (SessionData *)d; a = data->session_flag; b = RULE_OPTION_TYPE_SESSION; c = 0; final(a,b,c); return c; } int SessionCompare(void *l, void *r) { SessionData *left = (SessionData *)l; SessionData *right = (SessionData *)r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if (left->session_flag == right->session_flag) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } /**************************************************************************** * * Function: SetupSession() * * Purpose: Init the session plugin module. * * Arguments: None. * * Returns: void function * ****************************************************************************/ void SetupSession(void) { /* map the keyword to an initialization/processing function */ RegisterRuleOption("session", SessionInit, NULL, OPT_TYPE_LOGGING, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("session", &sessionPerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Plugin: Session Setup\n");); } /************************************************************************** * * Function: SessionInit(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: Initialize the sesion plugin, parsing the rule parameters and * setting up any necessary data structures. * * Arguments: data => rule arguments/data * otn => pointer to the current rule option list node * * Returns: void function * *************************************************************************/ void SessionInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { OptFpList *fpl; /* * Theoretically we should only all this plugin to be used when there's a * possibility of a session happening (i.e. TCP), but I get enough * requests that I'm going to pull the verifier so that things should work * for everyone */ /* if(protocol != IPPROTO_TCP) { FatalError("%(%d): Session keyword can not be used in non-TCP rule\n", file_name, file_line); }*/ /* multiple declaration check */ if(otn->ds_list[PLUGIN_SESSION]) { FatalError("%s(%d): Multiple session options in rule\n", file_name, file_line); } /* allocate the data structure and attach it to the rule's data struct list */ otn->ds_list[PLUGIN_SESSION] = (SessionData *) SnortAlloc(sizeof(SessionData)); /* be sure to check that the protocol that is passed in matches the transport layer protocol that you're using for this rule! */ /* this is where the keyword arguments are processed and placed into the rule option's data structure */ ParseSession(data, otn); /* finally, attach the option's detection function to the rule's detect function pointer list */ fpl = AddOptFuncToList(LogSessionData, otn); fpl->context = otn->ds_list[PLUGIN_SESSION]; fpl->type = RULE_OPTION_TYPE_SESSION; } /**************************************************************************** * * Function: ParseSession(char *, OptTreeNode *) * * Purpose: Figure out how much of the session data we're collecting * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ void ParseSession(char *data, OptTreeNode *otn) { SessionData *ds_ptr; /* data struct pointer */ //void *ds_ptr_dup; /* set the ds pointer to make it easier to reference the option's particular data struct */ ds_ptr = otn->ds_list[PLUGIN_SESSION]; /* manipulate the option arguments here */ while(isspace((int)*data)) data++; if(!strncasecmp(data, "printable", 9)) { ds_ptr->session_flag = SESSION_PRINTABLE; return; } if(!strncasecmp(data, "binary", 6)) { ds_ptr->session_flag = SESSION_BINARY; return; } if(!strncasecmp(data, "all", 3)) { ds_ptr->session_flag = SESSION_ALL; return; } FatalError("%s(%d): invalid session modifier: %s\n", file_name, file_line, data); #if 0 if (add_detection_option(sc, RULE_OPTION_TYPE_SESSION, (void *)ds_ptr, &ds_ptr_dup) == DETECTION_OPTION_EQUAL) { free(ds_ptr); ds_ptr = otn->ds_list[PLUGIN_SESSION] = ds_ptr_dup; } #endif } /**************************************************************************** * * Function: LogSessionData(char *, OptTreeNode *) * * Purpose: Dumps the session data to the log file. * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: Always calls the next function (this one doesn't test the data, * it just logs it....) * ****************************************************************************/ int LogSessionData(void *option_data, Packet *p) { SessionData *session_data = (SessionData *)option_data; FILE *session; /* session file ptr */ PROFILE_VARS; PREPROC_PROFILE_START(sessionPerfStats); /* if there's data in this packet */ if(p != NULL) { if((p->dsize != 0 && p->data != NULL) || p->frag_flag != 1) { session = OpenSessionFile(p); if(session == NULL) { PREPROC_PROFILE_END(sessionPerfStats); return DETECTION_OPTION_MATCH; } DumpSessionData(session, p, session_data); fclose(session); } } PREPROC_PROFILE_END(sessionPerfStats); return DETECTION_OPTION_MATCH; } void DumpSessionData(FILE *fp, Packet *p, SessionData *sessionData) { const u_char *idx; const u_char *end; char conv[] = "0123456789ABCDEF"; /* xlation lookup table */ if(p->dsize == 0 || p->data == NULL || p->frag_flag) return; idx = p->data; end = idx + p->dsize; if(sessionData->session_flag == SESSION_PRINTABLE) { while(idx != end) { if((*idx > 0x1f && *idx < 0x7f) || *idx == 0x0a || *idx == 0x0d) { fputc(*idx, fp); } idx++; } } else if(sessionData->session_flag == SESSION_BINARY) { fwrite(p->data, p->dsize, sizeof(char), fp); } else { while(idx != end) { if((*idx > 0x1f && *idx < 0x7f) || *idx == 0x0a || *idx == 0x0d) { /* Escape all occurences of '\' */ if(*idx == '\\') fputc('\\', fp); fputc(*idx, fp); } else { fputc('\\', fp); fputc(conv[((*idx&0xFF) >> 4)], fp); fputc(conv[((*idx&0xFF)&0x0F)], fp); } idx++; } } } FILE *OpenSessionFile(Packet *p) { char filename[STD_BUF]; char log_path[STD_BUF]; char session_file[STD_BUF]; /* name of session file */ sfaddr_t *dst, *src; FILE *ret; if(p->frag_flag) { return NULL; } memset((char *)session_file, 0, STD_BUF); memset((char *)log_path, 0, STD_BUF); /* figure out which way this packet is headed in relation to the homenet */ dst = GET_DST_IP(p); src = GET_SRC_IP(p); if(sfip_contains(&snort_conf->homenet, dst) == SFIP_CONTAINS) { if(sfip_contains(&snort_conf->homenet, src) == SFIP_NOT_CONTAINS) { SnortSnprintf(log_path, STD_BUF, "%s/%s", snort_conf->log_dir, inet_ntoa(GET_SRC_ADDR(p))); } else { if(p->sp >= p->dp) { SnortSnprintf(log_path, STD_BUF, "%s/%s", snort_conf->log_dir, inet_ntoa(GET_SRC_ADDR(p))); } else { SnortSnprintf(log_path, STD_BUF, "%s/%s", snort_conf->log_dir, inet_ntoa(GET_DST_ADDR(p))); } } } else { if(sfip_contains(&snort_conf->homenet, src) == SFIP_CONTAINS) { SnortSnprintf(log_path, STD_BUF, "%s/%s", snort_conf->log_dir, inet_ntoa(GET_DST_ADDR(p))); } else { if(p->sp >= p->dp) { SnortSnprintf(log_path, STD_BUF, "%s/%s", snort_conf->log_dir, inet_ntoa(GET_SRC_ADDR(p))); } else { SnortSnprintf(log_path, STD_BUF, "%s/%s", snort_conf->log_dir, inet_ntoa(GET_DST_ADDR(p))); } } } /* build the log directory */ if(mkdir(log_path,S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) { if(errno != EEXIST) { FatalError("Problem creating directory %s: %s\n", log_path,strerror(errno)); } } if(p->sp >= p->dp) { #ifdef WIN32 SnortSnprintf(session_file, STD_BUF, "%s/SESSION_%d-%d", log_path, p->sp, p->dp); #else SnortSnprintf(session_file, STD_BUF, "%s/SESSION:%d-%d", log_path, p->sp, p->dp); #endif } else { #ifdef WIN32 SnortSnprintf(session_file, STD_BUF, "%s/SESSION_%d-%d", log_path, p->dp, p->sp); #else SnortSnprintf(session_file, STD_BUF, "%s/SESSION:%d-%d", log_path, p->dp, p->sp); #endif } strncpy(filename, session_file, STD_BUF - 1); filename[STD_BUF - 1] = '\0'; ret = fopen(session_file, "a"); if(ret == NULL) { FatalError("OpenSessionFile() => fopen(%s) session file: %s\n", session_file, strerror(errno)); } return ret; } snort-2.9.15.1/src/detection-plugins/sp_session.h0000644000175200017520000000225413571422607016635 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Snort Session Plugin Header File */ #ifndef __SP_SESSION_H__ #define __SP_SESSION_H__ void SetupSession(void); uint32_t SessionHash(void *d); int SessionCompare(void *l, void *r); #endif /* __SP_SESSION_H__ */ snort-2.9.15.1/src/detection-plugins/sp_tcp_ack_check.c0000644000175200017520000001530613571422607017710 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "sf_types.h" #include "rules.h" #include "treenodes.h" #include "decode.h" #include "plugbase.h" #include "parser.h" #include "snort_debug.h" #include "util.h" #include "plugin_enum.h" #include "snort.h" #include "profiler.h" #ifdef PERF_PROFILING PreprocStats tcpAckPerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif #include "sfhashfcn.h" #include "detection_options.h" typedef struct _TcpAckCheckData { u_long tcp_ack; } TcpAckCheckData; void TcpAckCheckInit(struct _SnortConfig *, char *, OptTreeNode *, int); void ParseTcpAck(struct _SnortConfig *, char *, OptTreeNode *); int CheckTcpAckEq(void *option_data, Packet *p); uint32_t TcpAckCheckHash(void *d) { uint32_t a,b,c; TcpAckCheckData *data = (TcpAckCheckData *)d; a = data->tcp_ack; b = RULE_OPTION_TYPE_TCP_ACK; c = 0; final(a,b,c); return c; } int TcpAckCheckCompare(void *l, void *r) { TcpAckCheckData *left = (TcpAckCheckData *)l; TcpAckCheckData *right = (TcpAckCheckData *)r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if (left->tcp_ack == right->tcp_ack) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } /**************************************************************************** * * Function: SetupTcpAckCheck() * * Purpose: Link the ack keyword to the initialization function * * Arguments: None. * * Returns: void function * ****************************************************************************/ void SetupTcpAckCheck(void) { /* map the keyword to an initialization/processing function */ RegisterRuleOption("ack", TcpAckCheckInit, NULL, OPT_TYPE_DETECTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("ack", &tcpAckPerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Plugin: TcpAckCheck Initialized\n");); } /**************************************************************************** * * Function: TcpAckCheckInit(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: Attach the option data to the rule data struct and link in the * detection function to the function pointer list. * * Arguments: data => rule arguments/data * otn => pointer to the current rule option list node * * Returns: void function * ****************************************************************************/ void TcpAckCheckInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { OptFpList *fpl; if(protocol != IPPROTO_TCP) { FatalError("%s(%d) TCP Options on non-TCP rule\n", file_name, file_line); } /* multiple declaration check */ if(otn->ds_list[PLUGIN_TCP_ACK_CHECK]) { FatalError("%s(%d): Multiple TCP ack options in rule\n", file_name, file_line); } /* allocate the data structure and attach it to the rule's data struct list */ otn->ds_list[PLUGIN_TCP_ACK_CHECK] = (TcpAckCheckData *) SnortAlloc(sizeof(TcpAckCheckData)); /* this is where the keyword arguments are processed and placed into the rule option's data structure */ ParseTcpAck(sc, data, otn); /* finally, attach the option's detection function to the rule's detect function pointer list */ fpl = AddOptFuncToList(CheckTcpAckEq, otn); fpl->type = RULE_OPTION_TYPE_TCP_ACK; fpl->context = otn->ds_list[PLUGIN_TCP_ACK_CHECK]; } /**************************************************************************** * * Function: ParseTcpAck(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: Attach the option rule's argument to the data struct. * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ void ParseTcpAck(struct _SnortConfig *sc, char *data, OptTreeNode *otn) { TcpAckCheckData *ds_ptr; /* data struct pointer */ void *ds_ptr_dup; char **ep = NULL; /* set the ds pointer to make it easier to reference the option's particular data struct */ ds_ptr = otn->ds_list[PLUGIN_TCP_ACK_CHECK]; ds_ptr->tcp_ack = strtoul(data, ep, 0); ds_ptr->tcp_ack = htonl(ds_ptr->tcp_ack); if (add_detection_option(sc, RULE_OPTION_TYPE_TCP_ACK, (void *)ds_ptr, &ds_ptr_dup) == DETECTION_OPTION_EQUAL) { free(ds_ptr); ds_ptr = otn->ds_list[PLUGIN_TCP_ACK_CHECK] = ds_ptr_dup; } DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Ack set to %lX\n", ds_ptr->tcp_ack);); } /**************************************************************************** * * Function: CheckTcpAckEq(char *, OptTreeNode *) * * Purpose: Check to see if the packet's TCP ack field is equal to the rule * ack value. * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ int CheckTcpAckEq(void *option_data, Packet *p) { TcpAckCheckData *ackCheckData = (TcpAckCheckData *)option_data; int rval = DETECTION_OPTION_NO_MATCH; PROFILE_VARS; if(!p->tcph) return rval; /* if error appeared when tcp header was processed, * test fails automagically */ PREPROC_PROFILE_START(tcpAckPerfStats); if(ackCheckData->tcp_ack == p->tcph->th_ack) { rval = DETECTION_OPTION_MATCH; } else { /* you can put debug comments here or not */ DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"No match\n");); } /* if the test isn't successful, return 0 */ PREPROC_PROFILE_END(tcpAckPerfStats); return rval; } snort-2.9.15.1/src/detection-plugins/sp_tcp_ack_check.h0000644000175200017520000000224113571422607017707 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifndef __SP_TCP_ACK_CHECK_H__ #define __SP_TCP_ACK_CHECK_H__ void SetupTcpAckCheck(void); uint32_t TcpAckCheckHash(void *d); int TcpAckCheckCompare(void *l, void *r); #endif /* __SP_TCP_ACK_CHECK_H__ */ snort-2.9.15.1/src/detection-plugins/sp_tcp_flag_check.h0000644000175200017520000000224613571422607020067 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifndef __SP_TCP_FLAG_CHECK_H__ #define __SP_TCP_FLAG_CHECK_H__ void SetupTCPFlagCheck(void); uint32_t TcpFlagCheckHash(void *d); int TcpFlagCheckCompare(void *l, void *r); #endif /* __SP_TCP_FLAG_CHECK_H__ */ snort-2.9.15.1/src/detection-plugins/sp_tcp_flag_check.c0000644000175200017520000002627713571422607020074 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "sf_types.h" #include "rules.h" #include "treenodes.h" #include "decode.h" #include "plugbase.h" #include "parser.h" #include "snort_debug.h" #include "util.h" #include "plugin_enum.h" #define M_NORMAL 0 #define M_ALL 1 #define M_ANY 2 #define M_NOT 3 #include "snort.h" #include "profiler.h" #ifdef PERF_PROFILING PreprocStats tcpFlagsPerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif #include "sfhashfcn.h" #include "detection_options.h" typedef struct _TCPFlagCheckData { u_char mode; u_char tcp_flags; u_char tcp_mask; /* Mask to take away from the flags check */ } TCPFlagCheckData; void TCPFlagCheckInit(struct _SnortConfig *, char *, OptTreeNode *, int); void ParseTCPFlags(struct _SnortConfig *, char *, OptTreeNode *); int CheckTcpFlags(void *option_data, Packet *p); uint32_t TcpFlagCheckHash(void *d) { uint32_t a,b,c; TCPFlagCheckData *data = (TCPFlagCheckData *)d; a = data->mode; b = data->tcp_flags || (data->tcp_mask << 8); c = RULE_OPTION_TYPE_TCP_FLAG; final(a,b,c); return c; } int TcpFlagCheckCompare(void *l, void *r) { TCPFlagCheckData *left = (TCPFlagCheckData *)l; TCPFlagCheckData *right = (TCPFlagCheckData *)r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if ((left->mode == right->mode) && (left->tcp_flags == right->tcp_flags) && (left->tcp_mask == right->tcp_mask)) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } void SetupTCPFlagCheck(void) { RegisterRuleOption("flags", TCPFlagCheckInit, NULL, OPT_TYPE_DETECTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("flags", &tcpFlagsPerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Plugin: TCPFlagCheck Initialized!\n");); } void TCPFlagCheckInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { OptFpList *fpl; if(protocol != IPPROTO_TCP) { FatalError("Line %s (%d): TCP Options on non-TCP rule\n", file_name, file_line); } /* multiple declaration check */ if(otn->ds_list[PLUGIN_TCP_FLAG_CHECK]) { FatalError("%s(%d): Multiple TCP flags options in rule\n", file_name, file_line); } otn->ds_list[PLUGIN_TCP_FLAG_CHECK] = (TCPFlagCheckData *) SnortAlloc(sizeof(TCPFlagCheckData)); /* set up the pattern buffer */ ParseTCPFlags(sc, data, otn); DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Adding TCP flag check function (%p) to list\n", CheckTcpFlags);); /* link the plugin function in to the current OTN */ fpl = AddOptFuncToList(CheckTcpFlags, otn); fpl->type = RULE_OPTION_TYPE_TCP_FLAG; fpl->context = otn->ds_list[PLUGIN_TCP_FLAG_CHECK]; DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "OTN function CheckTcpFlags added to rule!\n");); } /**************************************************************************** * * Function: ParseTCPflags(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: Figure out which TCP flags the current rule is interested in * * Arguments: rule => the rule string * * Returns: void function * ***************************************************************************/ void ParseTCPFlags(struct _SnortConfig *sc, char *rule, OptTreeNode *otn) { char *fptr; char *fend; int comma_set = 0; TCPFlagCheckData *idx; void *ds_ptr_dup; idx = otn->ds_list[PLUGIN_TCP_FLAG_CHECK]; fptr = rule; /* make sure there is atleast a split pointer */ if(fptr == NULL) { FatalError("[!] Line %s (%d): Flags missing in TCP flag rule\n", file_name, file_line); } while(isspace((u_char) *fptr)) fptr++; if(strlen(fptr) == 0) { FatalError("[!] Line %s (%d): Flags missing in TCP flag rule\n", file_name, file_line); } /* find the end of the alert string */ fend = fptr + strlen(fptr); idx->mode = M_NORMAL; /* this is the default, unless overridden */ while(fptr < fend && comma_set == 0) { switch(*fptr) { case 'f': case 'F': idx->tcp_flags |= R_FIN; break; case 's': case 'S': idx->tcp_flags |= R_SYN; break; case 'r': case 'R': idx->tcp_flags |= R_RST; break; case 'p': case 'P': idx->tcp_flags |= R_PSH; break; case 'a': case 'A': idx->tcp_flags |= R_ACK; break; case 'u': case 'U': idx->tcp_flags |= R_URG; break; case '0': idx->tcp_flags = 0; break; case '1': /* reserved bit flags */ case 'c': case 'C': idx->tcp_flags |= R_CWR; /* Congestion Window Reduced, RFC 3168 */ break; case '2': /* reserved bit flags */ case 'e': case 'E': idx->tcp_flags |= R_ECE; /* ECN echo, RFC 3168 */ break; case '!': /* not, fire if all flags specified are not present, other are don't care */ idx->mode = M_NOT; break; case '*': /* star or any, fire if any flags specified are present, other are don't care */ idx->mode = M_ANY; break; case '+': /* plus or all, fire if all flags specified are present, other are don't care */ idx->mode = M_ALL; break; case ',': comma_set = 1; break; default: FatalError("%s(%d): bad TCP flag = \"%c\"\n" "Valid otions: UAPRSFCE or 0 for NO flags (e.g. NULL scan)," " and !, + or * for modifiers\n", file_name, file_line, *fptr); } fptr++; } while(isspace((u_char) *fptr)) fptr++; /* create the mask portion now */ while(fptr < fend && comma_set == 1) { switch(*fptr) { case 'f': case 'F': idx->tcp_mask |= R_FIN; break; case 's': case 'S': idx->tcp_mask |= R_SYN; break; case 'r': case 'R': idx->tcp_mask |= R_RST; break; case 'p': case 'P': idx->tcp_mask |= R_PSH; break; case 'a': case 'A': idx->tcp_mask |= R_ACK; break; case 'u': case 'U': idx->tcp_mask |= R_URG; break; case '1': /* reserved bit flags */ case 'c': case 'C': idx->tcp_mask |= R_CWR; /* Congestion Window Reduced, RFC 3168 */ break; case '2': /* reserved bit flags */ case 'e': case 'E': idx->tcp_mask |= R_ECE; /* ECN echo, RFC 3168 */ break; default: FatalError(" Line %s (%d): bad TCP flag = \"%c\"\n Valid otions: UAPRSFCE \n", file_name, file_line, *fptr); } fptr++; } if (add_detection_option(sc, RULE_OPTION_TYPE_TCP_FLAG, (void *)idx, &ds_ptr_dup) == DETECTION_OPTION_EQUAL) { otn->ds_list[PLUGIN_TCP_FLAG_CHECK] = ds_ptr_dup; free(idx); } } int CheckTcpFlags(void *option_data, Packet *p) { TCPFlagCheckData *flagptr = (TCPFlagCheckData *)option_data; int rval = DETECTION_OPTION_NO_MATCH; u_char tcp_flags; PROFILE_VARS; PREPROC_PROFILE_START(tcpFlagsPerfStats); if(!p->tcph) { /* if error appeared when tcp header was processed, * test fails automagically */ PREPROC_PROFILE_END(tcpFlagsPerfStats); return rval; } /* the flags we really want to check are all the ones */ tcp_flags = p->tcph->th_flags & (0xFF ^ flagptr->tcp_mask); DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, " CheckTcpFlags: ");); switch((flagptr->mode)) { case M_NORMAL: if(flagptr->tcp_flags == tcp_flags) /* only these set */ { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Got TCP [default] flag match!\n");); rval = DETECTION_OPTION_MATCH; } else { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"No match\n");); } break; case M_ALL: /* all set */ if((flagptr->tcp_flags & tcp_flags) == flagptr->tcp_flags) { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Got TCP [ALL] flag match!\n");); rval = DETECTION_OPTION_MATCH; } else { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"No match\n");); } break; case M_NOT: if((flagptr->tcp_flags & tcp_flags) == 0) /* none set */ { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Got TCP [NOT] flag match!\n");); rval = DETECTION_OPTION_MATCH; } else { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "No match\n");); } break; case M_ANY: if((flagptr->tcp_flags & tcp_flags) != 0) /* something set */ { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Got TCP [ANY] flag match!\n");); rval = DETECTION_OPTION_MATCH; } else { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"No match\n");); } break; default: /* Should never see this */ DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "TCP flag check went to default case" " for some silly reason\n");); break; } PREPROC_PROFILE_END(tcpFlagsPerfStats); return rval; } snort-2.9.15.1/src/detection-plugins/sp_tcp_seq_check.c0000644000175200017520000001534613571422607017746 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "sf_types.h" #include "rules.h" #include "treenodes.h" #include "decode.h" #include "plugbase.h" #include "parser.h" #include "util.h" #include "snort_debug.h" #include "plugin_enum.h" #include "snort.h" #include "profiler.h" #ifdef PERF_PROFILING PreprocStats tcpSeqPerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif #include "sfhashfcn.h" #include "detection_options.h" typedef struct _TcpSeqCheckData { u_long tcp_seq; } TcpSeqCheckData; void TcpSeqCheckInit(struct _SnortConfig *, char *, OptTreeNode *, int); void ParseTcpSeq(struct _SnortConfig *, char *, OptTreeNode *); int CheckTcpSeqEq(void *option_data, Packet *p); uint32_t TcpSeqCheckHash(void *d) { uint32_t a,b,c; TcpSeqCheckData *data = (TcpSeqCheckData *)d; a = data->tcp_seq; b = RULE_OPTION_TYPE_TCP_SEQ; c = 0; final(a,b,c); return c; } int TcpSeqCheckCompare(void *l, void *r) { TcpSeqCheckData *left = (TcpSeqCheckData *)l; TcpSeqCheckData *right = (TcpSeqCheckData *)r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if (left->tcp_seq == right->tcp_seq) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } /**************************************************************************** * * Function: SetupTcpSeqCheck() * * Purpose: Link the seq keyword to the initialization function * * Arguments: None. * * Returns: void function * ****************************************************************************/ void SetupTcpSeqCheck(void) { /* map the keyword to an initialization/processing function */ RegisterRuleOption("seq", TcpSeqCheckInit, NULL, OPT_TYPE_DETECTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("seq", &tcpSeqPerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: TcpSeqCheck Initialized\n");); } /**************************************************************************** * * Function: TcpSeqCheckInit(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: Attach the option data to the rule data struct and link in the * detection function to the function pointer list. * * Arguments: data => rule arguments/data * otn => pointer to the current rule option list node * * Returns: void function * ****************************************************************************/ void TcpSeqCheckInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { OptFpList *fpl; if(protocol != IPPROTO_TCP) { FatalError("Line %s (%d): TCP Options on non-TCP rule\n", file_name, file_line); } /* multiple declaration check */ if(otn->ds_list[PLUGIN_TCP_SEQ_CHECK]) { FatalError("%s(%d): Multiple TCP seq options in rule\n", file_name, file_line); } /* allocate the data structure and attach it to the rule's data struct list */ otn->ds_list[PLUGIN_TCP_SEQ_CHECK] = (TcpSeqCheckData *) SnortAlloc(sizeof(TcpSeqCheckData)); /* this is where the keyword arguments are processed and placed into the rule option's data structure */ ParseTcpSeq(sc, data, otn); /* finally, attach the option's detection function to the rule's detect function pointer list */ fpl = AddOptFuncToList(CheckTcpSeqEq, otn); fpl->type = RULE_OPTION_TYPE_TCP_SEQ; fpl->context = otn->ds_list[PLUGIN_TCP_SEQ_CHECK]; } /**************************************************************************** * * Function: ParseTcpSeq(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: Attach the option rule's argument to the data struct. * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ void ParseTcpSeq(struct _SnortConfig *sc, char *data, OptTreeNode *otn) { char **ep = NULL; void *ds_ptr_dup; TcpSeqCheckData *ds_ptr; /* data struct pointer */ /* set the ds pointer to make it easier to reference the option's particular data struct */ ds_ptr = otn->ds_list[PLUGIN_TCP_SEQ_CHECK]; ds_ptr->tcp_seq = strtoul(data, ep, 0); ds_ptr->tcp_seq = htonl(ds_ptr->tcp_seq); if (add_detection_option(sc, RULE_OPTION_TYPE_TCP_SEQ, (void *)ds_ptr, &ds_ptr_dup) == DETECTION_OPTION_EQUAL) { otn->ds_list[PLUGIN_TCP_SEQ_CHECK] = ds_ptr_dup; free(ds_ptr); } DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Seq set to %lX\n", ds_ptr->tcp_seq);); } /**************************************************************************** * * Function: CheckTcpSeqEq(char *, OptTreeNode *) * * Purpose: Check to see if the packet's TCP ack field is equal to the rule * ack value. * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ int CheckTcpSeqEq(void *option_data, Packet *p) { TcpSeqCheckData *tcpSeqCheckData = (TcpSeqCheckData *)option_data; int rval = DETECTION_OPTION_NO_MATCH; PROFILE_VARS; if(!p->tcph) return rval; /* if error appeared when tcp header was processed, * test fails automagically */ PREPROC_PROFILE_START(tcpSeqPerfStats); if(tcpSeqCheckData->tcp_seq == p->tcph->th_seq) { rval = DETECTION_OPTION_MATCH; } #ifdef DEBUG_MSGS else { /* you can put debug comments here or not */ DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"No match\n");); } #endif /* if the test isn't successful, return 0 */ PREPROC_PROFILE_END(tcpSeqPerfStats); return rval; } snort-2.9.15.1/src/detection-plugins/sp_tcp_seq_check.h0000644000175200017520000000224113571422607017741 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifndef __SP_TCP_SEQ_CHECK_H__ #define __SP_TCP_SEQ_CHECK_H__ void SetupTcpSeqCheck(void); uint32_t TcpSeqCheckHash(void *d); int TcpSeqCheckCompare(void *l, void *r); #endif /* __SP_TCP_SEQ_CHECK_H__ */ snort-2.9.15.1/src/detection-plugins/sp_tcp_win_check.c0000644000175200017520000001772213571422607017753 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifdef HAVE_STRINGS_H #include #endif #include #include "sf_types.h" #include "rules.h" #include "treenodes.h" #include "decode.h" #include "plugbase.h" #include "parser.h" #include "util.h" #include "snort_debug.h" #include "plugin_enum.h" #include "snort.h" #include "profiler.h" #ifdef PERF_PROFILING PreprocStats tcpWinPerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif #include "sfhashfcn.h" #include "detection_options.h" typedef struct _TcpWinCheckData { uint16_t tcp_win; uint8_t not_flag; } TcpWinCheckData; void TcpWinCheckInit(struct _SnortConfig *, char *, OptTreeNode *, int); void ParseTcpWin(struct _SnortConfig *, char *, OptTreeNode *); int TcpWinCheckEq(void *option_data, Packet *p); uint32_t TcpWinCheckHash(void *d) { uint32_t a,b,c; TcpWinCheckData *data = (TcpWinCheckData *)d; a = data->tcp_win; b = data->not_flag; c = RULE_OPTION_TYPE_TCP_WIN; final(a,b,c); return c; } int TcpWinCheckCompare(void *l, void *r) { TcpWinCheckData *left = (TcpWinCheckData *)l; TcpWinCheckData *right = (TcpWinCheckData *)r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if ((left->tcp_win == right->tcp_win) && (left->not_flag == right->not_flag)) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } /**************************************************************************** * * Function: SetupTcpWinCheck() * * Purpose: Associate the window keyword with TcpWinCheckInit * * Arguments: None. * * Returns: void function * ****************************************************************************/ void SetupTcpWinCheck(void) { /* map the keyword to an initialization/processing function */ RegisterRuleOption("window", TcpWinCheckInit, NULL, OPT_TYPE_DETECTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("window", &tcpWinPerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif } /**************************************************************************** * * Function: TcpWinCheckInit(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: Setup the window data struct and link the function into option * function pointer list * * Arguments: data => rule arguments/data * otn => pointer to the current rule option list node * * Returns: void function * ****************************************************************************/ void TcpWinCheckInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { OptFpList *fpl; if(protocol != IPPROTO_TCP) { FatalError("%s(%d): TCP Options on non-TCP rule\n", file_name, file_line); } /* multiple declaration check */ if(otn->ds_list[PLUGIN_TCP_WIN_CHECK]) { FatalError("%s(%d): Multiple TCP window options in rule\n", file_name, file_line); } /* allocate the data structure and attach it to the rule's data struct list */ otn->ds_list[PLUGIN_TCP_WIN_CHECK] = (TcpWinCheckData *) SnortAlloc(sizeof(TcpWinCheckData)); /* this is where the keyword arguments are processed and placed into the rule option's data structure */ ParseTcpWin(sc, data, otn); /* finally, attach the option's detection function to the rule's detect function pointer list */ fpl = AddOptFuncToList(TcpWinCheckEq, otn); fpl->type = RULE_OPTION_TYPE_TCP_WIN; fpl->context = otn->ds_list[PLUGIN_TCP_WIN_CHECK]; } /**************************************************************************** * * Function: ParseTcpWin(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: Convert the tos option argument to data and plug it into the * data structure * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ void ParseTcpWin(struct _SnortConfig *sc, char *data, OptTreeNode *otn) { TcpWinCheckData *ds_ptr; /* data struct pointer */ void *ds_ptr_dup; int win_size = 0; char *endTok; char *start; /* set the ds pointer to make it easier to reference the option's particular data struct */ ds_ptr = otn->ds_list[PLUGIN_TCP_WIN_CHECK]; /* get rid of any whitespace */ while(isspace((int)*data)) { data++; } if(data[0] == '!') { ds_ptr->not_flag = 1; start = &data[1]; } else { start = &data[0]; } if(strchr(start, (int) 'x') == NULL && strchr(start, (int)'X') == NULL) { win_size = SnortStrtolRange(start, &endTok, 10, 0, UINT16_MAX); if ((endTok == start) || (*endTok != '\0')) { FatalError("%s(%d) => Invalid parameter '%s' to 'window' (not a " "number?) \n", file_name, file_line, data); } } else { /* hex? */ start = strchr(data,(int)'x'); if(!start) { start = strchr(data,(int)'X'); } if (start) { win_size = SnortStrtolRange(start+1, &endTok, 16, 0, UINT16_MAX); } if (!start || (endTok == start+1) || (*endTok != '\0')) { FatalError("%s(%d) => Invalid parameter '%s' to 'window' (not a " "number?) \n", file_name, file_line, data); } } ds_ptr->tcp_win = htons((uint16_t)win_size); #ifdef DEBUG_MSGS DebugMessage(DEBUG_PLUGIN,"TCP Window set to 0x%X\n", ds_ptr->tcp_win); #endif if (add_detection_option(sc, RULE_OPTION_TYPE_TCP_WIN, (void *)ds_ptr, &ds_ptr_dup) == DETECTION_OPTION_EQUAL) { otn->ds_list[PLUGIN_TCP_WIN_CHECK] = ds_ptr_dup; free(ds_ptr); } } /**************************************************************************** * * Function: TcpWinCheckEq(char *, OptTreeNode *) * * Purpose: Test the TCP header's window to see if its value is equal to the * value in the rule. * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ int TcpWinCheckEq(void *option_data, Packet *p) { TcpWinCheckData *tcpWinCheckData = (TcpWinCheckData *)option_data; int rval = DETECTION_OPTION_NO_MATCH; PROFILE_VARS; if(!p->tcph) return rval; /* if error occured while ip header * was processed, return 0 automagically. */ PREPROC_PROFILE_START(tcpWinPerfStats); if((tcpWinCheckData->tcp_win == p->tcph->th_win) ^ (tcpWinCheckData->not_flag)) { rval = DETECTION_OPTION_MATCH; } #ifdef DEBUG_MSGS else { /* you can put debug comments here or not */ DebugMessage(DEBUG_PLUGIN,"No match\n"); } #endif /* if the test isn't successful, return 0 */ PREPROC_PROFILE_END(tcpWinPerfStats); return rval; } snort-2.9.15.1/src/detection-plugins/sp_tcp_win_check.h0000644000175200017520000000224013571422607017745 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifndef __SP_TCP_WIN_CHECK_H__ #define __SP_TCP_WIN_CHECK_H__ void SetupTcpWinCheck(void); uint32_t TcpWinCheckHash(void *d); int TcpWinCheckCompare(void *l, void *r); #endif /* __SP_IP_TOS_CHECK_H__ */ snort-2.9.15.1/src/detection-plugins/sp_ttl_check.c0000644000175200017520000002770513571422607017115 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "sf_types.h" #include "rules.h" #include "treenodes.h" #include "decode.h" #include "snort_debug.h" #include "plugbase.h" #include "parser.h" #include "plugin_enum.h" #include "util.h" #include "sfhashfcn.h" #include "snort.h" #include "profiler.h" #ifdef PERF_PROFILING PreprocStats ttlCheckPerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif #include "sfhashfcn.h" #include "detection_options.h" #define TTL_CHECK_EQ 1 #define TTL_CHECK_GT 2 #define TTL_CHECK_LT 3 #define TTL_CHECK_RG 4 #define TTL_CHECK_GT_EQ 5 #define TTL_CHECK_LT_EQ 6 typedef struct _TtlCheckData { int ttl; int h_ttl; char oper; } TtlCheckData; void TtlCheckInit(struct _SnortConfig *, char *, OptTreeNode *, int); void ParseTtl(struct _SnortConfig *, char *, OptTreeNode *); int CheckTtl(void *option_data, Packet *p); /**************************************************************************** * * Function: SetupTtlCheck() * * Purpose: Register the ttl option keyword with its setup function * * Arguments: None. * * Returns: void function * ****************************************************************************/ void SetupTtlCheck(void) { /* map the keyword to an initialization/processing function */ RegisterRuleOption("ttl", TtlCheckInit, NULL, OPT_TYPE_DETECTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("ttl_check", &ttlCheckPerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Plugin: TTLCheck Initialized\n");); } uint32_t TtlCheckHash(void *d) { uint32_t a,b,c; TtlCheckData *data = (TtlCheckData *)d; a = data->ttl; b = data->h_ttl; c = data->oper; mix(a,b,c); a += RULE_OPTION_TYPE_TTL; final(a,b,c); return c; } int TtlCheckCompare(void *l, void *r) { TtlCheckData *left = (TtlCheckData *)l; TtlCheckData *right = (TtlCheckData *)r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if ((left->ttl == right->ttl) && (left->h_ttl == right->h_ttl) && (left->oper == right->oper)) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } /**************************************************************************** * * Function: TtlCheckInit(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: Parse the ttl keyword arguments and link the detection module * into the function list * * Arguments: data => rule arguments/data * otn => pointer to the current rule option list node * * Returns: void function * ****************************************************************************/ void TtlCheckInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { /* multiple declaration check */ if(otn->ds_list[PLUGIN_TTL_CHECK]) { FatalError("%s(%d): Multiple IP ttl options in rule\n", file_name, file_line); } /* allocate the data structure and attach it to the rule's data struct list */ otn->ds_list[PLUGIN_TTL_CHECK] = (TtlCheckData *) SnortAlloc(sizeof(TtlCheckData)); /* this is where the keyword arguments are processed and placed into the rule option's data structure */ ParseTtl(sc, data, otn); /* NOTE: the AddOptFuncToList call is moved to the parsing function since the linking is best determined within that function */ } /**************************************************************************** * * Function: ParseTtl(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: Parse the TTL keyword's arguments * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ void ParseTtl(struct _SnortConfig *sc, char *data, OptTreeNode *otn) { OptFpList *fpl = NULL; TtlCheckData *ds_ptr; /* data struct pointer */ void *ds_ptr_dup; char ttlrel; char *endTok; int ttl; char *origData = data; char *curPtr = data; int equals_present = 0, rel_present =0; /* set the ds pointer to make it easier to reference the option's particular data struct */ ds_ptr = (TtlCheckData *)otn->ds_list[PLUGIN_TTL_CHECK]; if(data == NULL) { FatalError("%s(%d) => No arguments to 'ttl' \n" , file_name, file_line); } while(isspace((int)*data)) data++; ttlrel = *data; curPtr = data; switch (ttlrel) { case '-': ds_ptr->h_ttl = -1; /* leading dash flag */ data++; rel_present = 1; break; case '>': case '<': curPtr++; while(isspace((int)*curPtr)) curPtr++; if((*curPtr) == '=') { equals_present = 1; data = curPtr; } case '=': data++; rel_present = 1; break; default: ttlrel = '='; } while(isspace((int)*data)) data++; ttl = SnortStrtol(data, &endTok, 10); /* next char after first number must either be - or NULL */ if ((endTok == data) || ((*endTok != '-') && (*endTok != '\0'))) { FatalError("%s(%d) => Invalid parameter '%s' to 'ttl' (not a " "number?) \n", file_name, file_line, origData); } if (ttl< 0 || ttl > 255) { FatalError("%s(%d) => Invalid number '%s' to 'ttl' (should be between 0 to " "255) \n", file_name, file_line, origData); } ds_ptr->ttl = ttl; data = endTok; if (*data == '-') { if(rel_present || (ds_ptr->h_ttl == -1 )) { FatalError("%s(%d) => Invalid parameter '%s' to 'ttl' (not a " "number?) \n", file_name, file_line, origData); } data++; ttlrel = '-'; } switch (ttlrel) { case '>': fpl = AddOptFuncToList(CheckTtl, otn); if(equals_present) ds_ptr->oper = TTL_CHECK_GT_EQ; else ds_ptr->oper = TTL_CHECK_GT; break; case '<': fpl = AddOptFuncToList(CheckTtl, otn); if(equals_present) ds_ptr->oper = TTL_CHECK_LT_EQ; else ds_ptr->oper = TTL_CHECK_LT; break; case '=': fpl = AddOptFuncToList(CheckTtl, otn); ds_ptr->oper = TTL_CHECK_EQ; break; case '-': while(isspace((int)*data)) data++; if (ds_ptr->h_ttl != -1) { if(*data=='\0') { ds_ptr->h_ttl = 255; } else { ttl = SnortStrtol(data, &endTok, 10); if ((endTok == data) || (*endTok != '\0') || (ds_ptr->ttl > ttl)) { FatalError("%s(%d) => Invalid parameter '%s' to 'ttl' " "(not a number or invalid range?) \n", file_name, file_line, origData); } if (ttl< 0 || ttl > 255) { FatalError("%s(%d) => Invalid number '%s' to 'ttl' (should be between 0 to " "255) \n", file_name, file_line, origData); } if (ttl == 0) ds_ptr->h_ttl = 255; else ds_ptr->h_ttl = ttl; } } else /* leading dash*/ { ds_ptr->h_ttl = ds_ptr->ttl; ds_ptr->ttl = 0; } fpl = AddOptFuncToList(CheckTtl, otn); ds_ptr->oper = TTL_CHECK_RG; break; default: /* wtf? */ /* we need at least one statement after "default" or else Visual C++ issues a warning */ break; } if (add_detection_option(sc, RULE_OPTION_TYPE_TTL, (void *)ds_ptr, &ds_ptr_dup) == DETECTION_OPTION_EQUAL) { free(ds_ptr); ds_ptr = otn->ds_list[PLUGIN_TTL_CHECK] = ds_ptr_dup; } if (fpl) { fpl->type = RULE_OPTION_TYPE_TTL; fpl->context = ds_ptr; } DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Set TTL check value to %c%d (%d)\n", ttlrel, ds_ptr->ttl, ds_ptr->h_ttl);); } int CheckTtl(void *option_data, Packet *p) { TtlCheckData *ttlCheckData = (TtlCheckData *)option_data; int rval = DETECTION_OPTION_NO_MATCH; PROFILE_VARS; if(!IPH_IS_VALID(p)) return rval; PREPROC_PROFILE_START(ttlCheckPerfStats); switch (ttlCheckData->oper) { case TTL_CHECK_EQ: if (ttlCheckData->ttl == GET_IPH_TTL(p)) rval = DETECTION_OPTION_MATCH; #ifdef DEBUG_MSGS else { DebugMessage(DEBUG_PLUGIN, "CheckTtlEq: Not equal to %d\n", ttlCheckData->ttl); } #endif break; case TTL_CHECK_GT: if (ttlCheckData->ttl < GET_IPH_TTL(p)) rval = DETECTION_OPTION_MATCH; #ifdef DEBUG_MSGS else { DebugMessage(DEBUG_PLUGIN, "CheckTtlEq: Not greater than %d\n", ttlCheckData->ttl); } #endif break; case TTL_CHECK_LT: if (ttlCheckData->ttl > GET_IPH_TTL(p)) rval = DETECTION_OPTION_MATCH; #ifdef DEBUG_MSGS else { DebugMessage(DEBUG_PLUGIN, "CheckTtlEq: Not less than %d\n", ttlCheckData->ttl); } #endif break; case TTL_CHECK_GT_EQ: if (ttlCheckData->ttl <= GET_IPH_TTL(p)) rval = DETECTION_OPTION_MATCH; #ifdef DEBUG_MSGS else { DebugMessage(DEBUG_PLUGIN, "CheckTtlEq: Not greater than or equal to %d\n", ttlCheckData->ttl); } #endif break; case TTL_CHECK_LT_EQ: if (ttlCheckData->ttl >= GET_IPH_TTL(p)) rval = DETECTION_OPTION_MATCH; #ifdef DEBUG_MSGS else { DebugMessage(DEBUG_PLUGIN, "CheckTtlEq: Not less than or equal to %d\n", ttlCheckData->ttl); } #endif break; case TTL_CHECK_RG: if ((ttlCheckData->ttl <= GET_IPH_TTL(p)) && (ttlCheckData->h_ttl >= GET_IPH_TTL(p))) rval = DETECTION_OPTION_MATCH; #ifdef DEBUG_MSGS else { DebugMessage(DEBUG_PLUGIN, "CheckTtlLT: Not Within the range %d - %d (%d)\n", ttlCheckData->ttl, ttlCheckData->h_ttl, GET_IPH_TTL(p)); } #endif break; default: break; } /* if the test isn't successful, return 0 */ PREPROC_PROFILE_END(ttlCheckPerfStats); return rval; } snort-2.9.15.1/src/detection-plugins/sp_ttl_check.h0000644000175200017520000000221413571422607017106 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* $Id$ */ #ifndef __SP_TTL_CHECK_H__ #define __SP_TTL_CHECK_H__ void SetupTtlCheck(void); uint32_t TtlCheckHash(void *d); int TtlCheckCompare(void *l, void *r); #endif /* __SP_TTL_CHECK_H__ */ snort-2.9.15.1/src/detection-plugins/sp_urilen_check.c0000644000175200017520000002146713571422607017607 00000000000000/* $Id */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2005-2013 Sourcefire, Inc. ** ** 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 nto, write to the Free Software ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, ** USA */ /* * sp_urilen_check.c: Detection plugin to expose URI length to user rules. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "sf_types.h" #include "rules.h" #include "treenodes.h" #include "decode.h" #include "plugbase.h" #include "snort_debug.h" #include "parser.h" #include "plugin_enum.h" #include "util.h" #include "sfhashfcn.h" #include "mstring.h" #include "sp_urilen_check.h" #include "snort.h" #include "profiler.h" #ifdef PERF_PROFILING PreprocStats urilenCheckPerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif #include "sfhashfcn.h" #include "detection_options.h" #include "detection_util.h" void UriLenCheckInit( struct _SnortConfig *, char*, OptTreeNode*, int ); void ParseUriLen( struct _SnortConfig *, char*, OptTreeNode* ); int CheckUriLen(void *option_data, Packet*p); uint32_t UriLenCheckHash(void *d) { uint32_t a,b,c; UriLenCheckData *data = (UriLenCheckData *)d; a = data->urilen; b = data->urilen2; c = data->oper; mix(a,b,c); a += data->uri_buf; b += RULE_OPTION_TYPE_URILEN; final(a,b,c); return c; } int UriLenCheckCompare(void *l, void *r) { UriLenCheckData *left = (UriLenCheckData *)l; UriLenCheckData *right = (UriLenCheckData *)r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if ((left->urilen == right->urilen) && (left->urilen2 == right->urilen2) && (left->oper == right->oper) && (left->uri_buf == right->uri_buf)) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } /* Called from plugbase to register any detection plugin keywords. * * PARAMETERS: None. * * RETURNS: Nothing. */ void SetupUriLenCheck(void) { RegisterRuleOption("urilen", UriLenCheckInit, NULL, OPT_TYPE_DETECTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("urilen_check", &urilenCheckPerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif } /* Parses the urilen rule arguments and attaches info to * the rule data structure for later use. Attaches detection * function to OTN function list. * * PARAMETERS: * * argp: Rule arguments * otnp: Pointer to the current rule option list node * protocol: Pointer specified for the rule currently being parsed * * RETURNS: Nothing. */ void UriLenCheckInit( struct _SnortConfig *sc, char* argp, OptTreeNode* otnp, int protocol ) { /* Sanity check(s) */ if ( !otnp ) return; /* Check if there have been multiple urilen options specified * in the same rule. */ if ( otnp->ds_list[PLUGIN_URILEN_CHECK] ) { FatalError("%s(%d): Multiple urilen options in rule\n", file_name, file_line ); } otnp->ds_list[PLUGIN_URILEN_CHECK] = SnortAlloc(sizeof(UriLenCheckData)); ParseUriLen( sc, argp, otnp ); } /* Parses the urilen rule arguments and attaches the resulting * parameters to the rule data structure. Based on arguments, * attaches the appropriate callback/processing function * to be used when the OTN is evaluated. * * PARAMETERS: * * argp: Pointer to string containing the arguments to be * parsed. * otnp: Pointer to the current rule option list node. * * RETURNS: Nothing. */ void ParseUriLen( struct _SnortConfig *sc, char* argp, OptTreeNode* otnp ) { OptFpList *fpl; UriLenCheckData* datap = (UriLenCheckData*)otnp->ds_list[PLUGIN_URILEN_CHECK]; void *datap_dup; char* curp = NULL; char **toks; int num_toks; toks = mSplit(argp, ",", 2, &num_toks, '\\'); if (!num_toks) { FatalError("%s(%d): 'urilen' requires arguments.\n", file_name, file_line); } curp = toks[0]; /* Parse the string */ if (isdigit((int)*curp) && strstr(curp, "<>")) { char **mtoks; int num_mtoks; char* endp = NULL; long int val; mtoks = mSplit(curp, "<>", 2, &num_mtoks, '\\'); if (num_mtoks != 2) { FatalError("%s(%d): Invalid 'urilen' argument.\n", file_name, file_line); } val = strtol(mtoks[0], &endp, 0); if ((val < 0) || *endp || (val > UINT16_MAX)) { FatalError("%s(%d): Invalid 'urilen' argument.\n", file_name, file_line); } datap->urilen = (uint16_t)val; val = strtol(mtoks[1], &endp, 0); if ((val < 0) || *endp || (val > UINT16_MAX)) { FatalError("%s(%d): Invalid 'urilen' argument.\n", file_name, file_line); } datap->urilen2 = (uint16_t)val; if (datap->urilen2 < datap->urilen) { uint16_t tmp = datap->urilen; datap->urilen = datap->urilen2; datap->urilen2 = tmp; } datap->oper = URILEN_CHECK_RG; mSplitFree(&mtoks, num_mtoks); } else { char* endp = NULL; long int val; if(*curp == '>') { curp++; datap->oper = URILEN_CHECK_GT; } else if(*curp == '<') { curp++; datap->oper = URILEN_CHECK_LT; } else { datap->oper = URILEN_CHECK_EQ; } while(isspace((int)*curp)) curp++; if (!*curp) { FatalError("%s(%d): Invalid 'urilen' argument.\n", file_name, file_line); } val = strtol(curp, &endp, 0); if ((val < 0) || *endp || (val > UINT16_MAX)) { FatalError("%s(%d): Invalid 'urilen' argument.\n", file_name, file_line); } if ((datap->oper == URILEN_CHECK_LT) && (val == 0)) { FatalError("%s(%d): Invalid 'urilen' argument.\n", file_name, file_line); } datap->urilen = (uint16_t)val; } if (num_toks > 1) { if (!strcmp(toks[1], URI_LEN_BUF_NORM)) datap->uri_buf = HTTP_BUFFER_URI; else if (!strcmp(toks[1], URI_LEN_BUF_RAW)) datap->uri_buf = HTTP_BUFFER_RAW_URI; else FatalError("%s(%d): Invalid 'urilen' argument.\n", file_name, file_line); } else { if (strchr(argp, ',')) { FatalError("%s(%d): Invalid 'urilen' argument.\n", file_name, file_line); } datap->uri_buf = HTTP_BUFFER_RAW_URI; } mSplitFree(&toks, num_toks); fpl = AddOptFuncToList(CheckUriLen, otnp); fpl->type = RULE_OPTION_TYPE_URILEN; if (add_detection_option(sc, RULE_OPTION_TYPE_URILEN, (void *)datap, &datap_dup) == DETECTION_OPTION_EQUAL) { otnp->ds_list[PLUGIN_URILEN_CHECK] = datap_dup; free(datap); } fpl->context = otnp->ds_list[PLUGIN_URILEN_CHECK]; } int CheckUriLen(void *option_data, Packet *p) { UriLenCheckData *udata = (UriLenCheckData *)option_data; int rval = DETECTION_OPTION_NO_MATCH; const HttpBuffer* hb = GetHttpBuffer(udata->uri_buf); PROFILE_VARS; PREPROC_PROFILE_START(urilenCheckPerfStats); if ( !hb ) { PREPROC_PROFILE_END(urilenCheckPerfStats); return rval; } switch (udata->oper) { case URILEN_CHECK_EQ: if (udata->urilen == hb->length) rval = DETECTION_OPTION_MATCH; break; case URILEN_CHECK_GT: if (udata->urilen < hb->length) rval = DETECTION_OPTION_MATCH; break; case URILEN_CHECK_LT: if (udata->urilen > hb->length) rval = DETECTION_OPTION_MATCH; break; case URILEN_CHECK_RG: if ((udata->urilen <= hb->length) && (udata->urilen2 >= hb->length)) rval = DETECTION_OPTION_MATCH; break; default: break; } /* if the test isn't successful, return 0 */ PREPROC_PROFILE_END(urilenCheckPerfStats); return rval; } snort-2.9.15.1/src/detection-plugins/sp_urilen_check.h0000644000175200017520000000347613571422607017614 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2005-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * sp_urilen_check.h: Structure definitions/function prototype(s) * for the URI length detection plugin. */ /* $Id */ #ifndef _SP_URILEN_CHECK_H_ #define _SP_URILEN_CHECK_H_ #define URI_LEN_BUF_NORM "norm" #define URI_LEN_BUF_RAW "raw" #define URILEN_CHECK_EQ 1 #define URILEN_CHECK_GT 2 #define URILEN_CHECK_LT 3 #define URILEN_CHECK_RG 4 /* Structure stored in the rule OTN struct for use by URILEN * detection plugin code. */ typedef struct _UriLenCheckData { uint16_t urilen; uint16_t urilen2; char oper; int uri_buf; } UriLenCheckData; /* * Structure stored in the rule OTN struct for use by URINORMLEN * detection plugin code. */ typedef struct _UriNormLenCheckData { int urinormlen; int urinormlen2; } UriNormLenCheckData; extern void SetupUriLenCheck(void); uint32_t UriLenCheckHash(void *d); int UriLenCheckCompare(void *l, void *r); #endif /* _SP_URILEN_CHECK_H_ */ snort-2.9.15.1/src/detection-plugins/sp_file_data.c0000644000175200017520000001547213571422607017063 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 1998-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* sp_file_data * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifdef HAVE_STRINGS_H #include #endif #include #include "sf_types.h" #include "snort_bounds.h" #include "rules.h" #include "decode.h" #include "plugbase.h" #include "parser.h" #include "snort_debug.h" #include "util.h" #include "mstring.h" #include "snort.h" #include "profiler.h" #include "sp_file_data.h" #ifdef PERF_PROFILING PreprocStats fileDataPerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif #include "detection_options.h" #include "detection_util.h" extern char *file_name; /* this is the file name from rules.c, generally used for error messages */ extern int file_line; /* this is the file line number from rules.c that is used to indicate file lines for error messages */ static void FileDataInit(struct _SnortConfig *, char *, OptTreeNode *, int); void FileDataParse(char *, FileData *, OptTreeNode *); int FileDataEval(void *option_data, Packet *p); uint32_t FileDataHash(void *d) { uint32_t a,b,c; FileData *data = (FileData *)d; a = data->mime_decode_flag; b = RULE_OPTION_TYPE_FILE_DATA; c = 0; final(a,b,c); return c; } int FileDataCompare(void *l, void *r) { FileData *left = (FileData *)l; FileData *right = (FileData *)r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if( left->mime_decode_flag == right->mime_decode_flag ) return DETECTION_OPTION_EQUAL; return DETECTION_OPTION_NOT_EQUAL; } /**************************************************************************** * * Function: SetupFileData() * * Purpose: Load 'er up * * Arguments: None. * * Returns: void function * ****************************************************************************/ void SetupFileData(void) { /* map the keyword to an initialization/processing function */ RegisterRuleOption("file_data", FileDataInit, NULL, OPT_TYPE_DETECTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("file_data", &fileDataPerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: file_data Setup\n");); } /**************************************************************************** * * Function: FileDataInit(struct _SnortConfig *, char *, OptTreeNode *, int protocol) * * Purpose: Generic rule configuration function. Handles parsing the rule * information and attaching the associated detection function to * the OTN. * * Arguments: data => rule arguments/data * otn => pointer to the current rule option list node * protocol => protocol the rule is on (we don't care in this case) * * Returns: void function * ****************************************************************************/ static void FileDataInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { FileData *idx; OptFpList *fpl; void *idx_dup; idx = (FileData *) SnortAlloc(sizeof(FileData)); if(idx == NULL) { FatalError("%s(%d): Unable to allocate file_data node\n", file_name, file_line); } otn->ds_list[PLUGIN_FILE_DATA] = (void *)1; FileDataParse(data, idx, otn); if (add_detection_option(sc, RULE_OPTION_TYPE_FILE_DATA, (void *)idx, &idx_dup) == DETECTION_OPTION_EQUAL) { free(idx); idx = idx_dup; } fpl = AddOptFuncToList(FileDataEval, otn); fpl->type = RULE_OPTION_TYPE_FILE_DATA; fpl->context = (void *)idx; return; } /**************************************************************************** * * Function: FileDataParse(char *, OptTreeNode *) * * Purpose: This is the function that is used to process the option keyword's * arguments and attach them to the rule's data structures. * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ void FileDataParse(char *data, FileData *idx, OptTreeNode *otn) { if (IsEmptyStr(data)) { idx->mime_decode_flag = 0; } else if(!strcasecmp("mime",data)) { ParseWarning("The argument 'mime' to 'file_data' rule option is deprecated.\n"); } else { FatalError("%s(%d) file_data: Invalid token %s\n", file_name, file_line, data); } return; } /**************************************************************************** * * Function: FileDataEval(char *, OptTreeNode *, OptFpList *) * * Purpose: Use this function to perform the particular detection routine * that this rule keyword is supposed to encompass. * * Arguments: p => pointer to the decoded packet * otn => pointer to the current rule's OTN * fp_list => pointer to the function pointer list * * Returns: If the detection test fails, this function *must* return a zero! * On success, it calls the next function in the detection list * ****************************************************************************/ int FileDataEval(void *option_data, Packet *p) { int rval = DETECTION_OPTION_NO_MATCH; const uint8_t *data; uint16_t len; FileData *idx; PROFILE_VARS; PREPROC_PROFILE_START(fileDataPerfStats); idx = (FileData *)option_data; data = file_data_ptr.data; len = file_data_ptr.len; if ((p->dsize == 0) || !idx) { PREPROC_PROFILE_END(fileDataPerfStats); return rval; } if ((data == NULL)|| (len == 0)) { data = p->data; len = p->dsize; } if(idx->mime_decode_flag) mime_present = 1; else mime_present = 0; SetDoePtr(data, DOE_BUF_STD); SetAltDetect(data, len); rval = DETECTION_OPTION_MATCH; PREPROC_PROFILE_END(fileDataPerfStats); return rval; } snort-2.9.15.1/src/detection-plugins/sp_file_data.h0000644000175200017520000000215713571422607017064 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2003-2013 Sourcefire, Inc. ** ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __SP_FILE_DATA_H__ #define __SP_FILE_DATA_H__ typedef struct _FileData { uint8_t mime_decode_flag; }FileData; void SetupFileData(void); int FileDataCompare(void *, void *); uint32_t FileDataHash(void *); #endif snort-2.9.15.1/src/detection-plugins/sp_base64_decode.c0000644000175200017520000002647213571422607017544 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 1998-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* sp_base64_decode * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifdef HAVE_STRINGS_H #include #endif #include #include "sf_types.h" #include "snort_bounds.h" #include "rules.h" #include "decode.h" #include "plugbase.h" #include "parser.h" #include "snort_debug.h" #include "util.h" #include "mstring.h" #include "snort.h" #include "profiler.h" #include "sp_base64_decode.h" #include "sfutil/sf_base64decode.h" #ifdef PERF_PROFILING PreprocStats base64DecodePerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif #include "detection_options.h" #include "detection_util.h" extern char *file_name; /* this is the file name from rules.c, generally used for error messages */ extern int file_line; /* this is the file line number from rules.c that is used to indicate file lines for error messages */ void Base64DecodeInit(struct _SnortConfig *, char *, OptTreeNode *, int); void Base64DecodeParse(char *, Base64DecodeData *, OptTreeNode *); int Base64DecodeEval(void *option_data, Packet *p); uint32_t Base64DecodeHash(void *d) { uint32_t a,b,c; Base64DecodeData *data = (Base64DecodeData *)d; a = data->bytes_to_decode; b = data->offset; c = data->flags; mix(a,b,c); a += RULE_OPTION_TYPE_BASE64_DECODE; final(a,b,c); return c; } int Base64DecodeCompare(void *l, void *r) { Base64DecodeData *left = (Base64DecodeData *)l; Base64DecodeData *right = (Base64DecodeData *)r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if ((left->bytes_to_decode == right->bytes_to_decode) && ( left->offset == right->offset) && ( left->flags == right->flags)) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } /**************************************************************************** * * Function: SetupBase64Decode() * * Purpose: Load 'er up * * Arguments: None. * * Returns: void function * ****************************************************************************/ void SetupBase64Decode(void) { /* map the keyword to an initialization/processing function */ RegisterRuleOption("base64_decode", Base64DecodeInit, NULL, OPT_TYPE_DETECTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("base64_decode", &base64DecodePerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: base64_decode Setup\n");); } /**************************************************************************** * * Function: Base64DecodeInit(struct _SnortConfig *, char *, OptTreeNode *, int protocol) * * Purpose: Generic rule configuration function. Handles parsing the rule * information and attaching the associated detection function to * the OTN. * * Arguments: data => rule arguments/data * otn => pointer to the current rule option list node * protocol => protocol the rule is on (we don't care in this case) * * Returns: void function * ****************************************************************************/ void Base64DecodeInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { Base64DecodeData *idx; OptFpList *fpl; void *idx_dup; if(otn->ds_list[PLUGIN_BASE64_DECODE]) { FatalError("%s(%d): Multiple base64_decode options in rule\n", file_name, file_line); } idx = (Base64DecodeData *) SnortAlloc(sizeof(Base64DecodeData)); if(idx == NULL) { FatalError("%s(%d): Unable to allocate Base64Decode data node\n", file_name, file_line); } otn->ds_list[PLUGIN_BASE64_DECODE] = idx; Base64DecodeParse(data, idx, otn); if (add_detection_option(sc, RULE_OPTION_TYPE_BASE64_DECODE, (void *)idx, &idx_dup) == DETECTION_OPTION_EQUAL) { free(idx); idx = otn->ds_list[PLUGIN_BASE64_DECODE] = idx_dup; } fpl = AddOptFuncToList(Base64DecodeEval, otn); fpl->type = RULE_OPTION_TYPE_BASE64_DECODE; fpl->context = (void *) idx; if (idx->flags & BASE64DECODE_RELATIVE_FLAG) fpl->isRelative = 1; } /**************************************************************************** * * Function: Base64DecodeParse(char *, Base64DecodeData *, OptTreeNode *) * * Purpose: This is the function that is used to process the option keyword's * arguments and attach them to the rule's data structures. * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ void Base64DecodeParse(char *data, Base64DecodeData *idx, OptTreeNode *otn) { char **toks; char **toks1; int num_toks; int num_toks1; char *token; int i=0; char *endptr; int value = 0; /*no arguments*/ if (IsEmptyStr(data)) { idx->offset = 0; idx->bytes_to_decode = 0; idx->flags = 0; return; } toks = mSplit(data, ",", 0, &num_toks, 0); if (num_toks > 3 ) { FatalError("%s (%d): Bad arguments to base64_decode.\n", file_name, file_line); } while (i < num_toks ) { token = toks[i]; if( strcmp(token , "relative") == 0 ) { idx->flags |= BASE64DECODE_RELATIVE_FLAG; i++; continue; } toks1 = mSplit(token, " \t", 0, &num_toks1, 0); if ( num_toks1 != 2 ) { FatalError("%s (%d): Bad arguments to base64_decode.\n", file_name, file_line); } if( strcmp(toks1[0], "offset") == 0 ) { value = SnortStrtol(toks1[1], &endptr, 10); if(*endptr || value < 0) { FatalError("%s (%d): Bad arguments to base64_decode.\n", file_name, file_line); } idx->offset = value; } else if( strcmp(toks1[0], "bytes") == 0 ) { value = SnortStrtol(toks1[1], &endptr, 10); if(*endptr || (value < 0) ) { FatalError("%s (%d): Bad arguments to base64_decode.\n", file_name, file_line); } if(!value) { FatalError("%s (%d): \"bytes\" option to base64_decode cannot be" " zero.\n", file_name, file_line); } idx->bytes_to_decode = value; } else { FatalError("%s (%d): Bad arguments to base64_decode.\n", file_name, file_line); } mSplitFree(&toks1,num_toks1); i++; } mSplitFree(&toks,num_toks); if (otn && otn->ds_list[PLUGIN_PATTERN_MATCH_URI]) { PatternMatchData *pmd = (PatternMatchData *)(otn->ds_list[PLUGIN_PATTERN_MATCH_URI]); idx->buffer_type = pmd->http_buffer; } else { idx->buffer_type = HTTP_BUFFER_NONE; } return; } /**************************************************************************** * * Function: Base64DecodeEval(char *, OptTreeNode *, OptFpList *) * * Purpose: Use this function to perform the particular detection routine * that this rule keyword is supposed to encompass. * * Arguments: p => pointer to the decoded packet * otn => pointer to the current rule's OTN * fp_list => pointer to the function pointer list * * Returns: If the detection test fails, this function *must* return a zero! * On success, it calls the next function in the detection list * ****************************************************************************/ int Base64DecodeEval(void *option_data, Packet *p) { int rval = DETECTION_OPTION_NO_MATCH; const uint8_t *start_ptr = NULL; uint8_t base64_buf[DECODE_BLEN]; uint32_t base64_size =0; Base64DecodeData *idx; uint32_t buff_size; PROFILE_VARS; PREPROC_PROFILE_START(base64DecodePerfStats); base64_decode_size = 0; if ((!p->dsize) || (!p->data)) { PREPROC_PROFILE_END(base64DecodePerfStats); return rval; } idx = (Base64DecodeData *)option_data; if(!idx) { PREPROC_PROFILE_END(base64DecodePerfStats); return rval; } if ((idx->flags & BASE64DECODE_RELATIVE_FLAG) && doe_ptr) { int dsize; const uint8_t *doe_start; if (Is_DetectFlag(FLAG_ALT_DETECT)) { dsize = DetectBuffer.len; doe_start = DetectBuffer.data; } else if(Is_DetectFlag(FLAG_ALT_DECODE)) { dsize = DecodeBuffer.len; doe_start = (uint8_t *)DecodeBuffer.data; } else if (doe_buf_flags & DOE_BUF_URI) { const HttpBuffer* hb = GetHttpBuffer(idx->buffer_type); if (!hb) { PREPROC_PROFILE_END(base64DecodePerfStats); return rval; } doe_start = hb->buf; dsize = hb->length; } else { if(IsLimitedDetect(p)) dsize = p->alt_dsize; else dsize = p->dsize; doe_start = (uint8_t *) p->data; } start_ptr = doe_ptr + idx->offset; if(start_ptr >= (doe_start + dsize) || (doe_ptr < doe_start)) { PREPROC_PROFILE_END(base64DecodePerfStats); return rval; } buff_size = doe_start + dsize - start_ptr; } else { start_ptr = p->data + idx->offset; if(start_ptr >= (p->data + p->dsize) ) { PREPROC_PROFILE_END(base64DecodePerfStats); return rval; } buff_size = p->data + p->dsize - start_ptr; } if(sf_unfold_header(start_ptr, buff_size, base64_buf, sizeof(base64_buf), &base64_size, 0, 0) != 0) { PREPROC_PROFILE_END(base64DecodePerfStats); return rval; } if (idx->bytes_to_decode && (base64_size > idx->bytes_to_decode)) { base64_size = idx->bytes_to_decode; } if(sf_base64decode(base64_buf, base64_size, (uint8_t *)base64_decode_buf, sizeof(base64_decode_buf), &base64_decode_size) != 0) { PREPROC_PROFILE_END(base64DecodePerfStats); return rval; } PREPROC_PROFILE_END(base64DecodePerfStats); return DETECTION_OPTION_MATCH; } snort-2.9.15.1/src/detection-plugins/sp_base64_decode.h0000644000175200017520000000244113571422607017537 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2003-2013 Sourcefire, Inc. ** ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __SP_BASE64_DECODE_H__ #define __SP_BASE64_DECODE_H__ #include "sp_pattern_match.h" #define BASE64DECODE_RELATIVE_FLAG 0x01 typedef struct _Base64DecodeData { uint32_t bytes_to_decode; uint32_t offset; uint8_t flags; HTTP_BUFFER buffer_type; }Base64DecodeData; int Base64DecodeCompare(void *, void *); uint32_t Base64DecodeHash(void *); void SetupBase64Decode(void); #endif snort-2.9.15.1/src/detection-plugins/sp_base64_data.c0000644000175200017520000001312313571422607017217 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 1998-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* sp_base64_data * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifdef HAVE_STRINGS_H #include #endif #include #include "sf_types.h" #include "snort_bounds.h" #include "rules.h" #include "decode.h" #include "plugbase.h" #include "parser.h" #include "snort_debug.h" #include "util.h" #include "mstring.h" #include "snort.h" #include "profiler.h" #include "sp_base64_data.h" #ifdef PERF_PROFILING PreprocStats base64DataPerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif #include "detection_options.h" #include "detection_util.h" extern char *file_name; /* this is the file name from rules.c, generally used for error messages */ extern int file_line; /* this is the file line number from rules.c that is used to indicate file lines for error messages */ static void Base64DataInit(struct _SnortConfig *, char *, OptTreeNode *, int); void Base64DataParse(char *, OptTreeNode *); int Base64DataEval(void *option_data, Packet *p); /**************************************************************************** * * Function: SetupBase64Data() * * Purpose: Load 'er up * * Arguments: None. * * Returns: void function * ****************************************************************************/ void SetupBase64Data(void) { /* map the keyword to an initialization/processing function */ RegisterRuleOption("base64_data", Base64DataInit, NULL, OPT_TYPE_DETECTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("base64_data", &base64DataPerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: base64_data Setup\n");); } /**************************************************************************** * * Function: Base64DataInit(struct _SnortConfig *, char *, OptTreeNode *, int protocol) * * Purpose: Generic rule configuration function. Handles parsing the rule * information and attaching the associated detection function to * the OTN. * * Arguments: data => rule arguments/data * otn => pointer to the current rule option list node * protocol => protocol the rule is on (we don't care in this case) * * Returns: void function * ****************************************************************************/ static void Base64DataInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { OptFpList *fpl; if(otn->ds_list[PLUGIN_BASE64_DECODE] == NULL ) { /*use base64_decode before base64_data*/ FatalError("%s(%d): base64_decode needs to be specified before base64_data in a rule\n", file_name, file_line); } Base64DataParse(data, otn); fpl = AddOptFuncToList(Base64DataEval, otn); fpl->type = RULE_OPTION_TYPE_BASE64_DATA; } /**************************************************************************** * * Function: Base64DataParse(char *, OptTreeNode *) * * Purpose: This is the function that is used to process the option keyword's * arguments and attach them to the rule's data structures. * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ void Base64DataParse(char *data, OptTreeNode *otn) { if (!IsEmptyStr(data)) { FatalError("%s(%d): base64_data takes no arguments\n", file_name, file_line); } } /**************************************************************************** * * Function: Base64DataEval(char *, OptTreeNode *, OptFpList *) * * Purpose: Use this function to perform the particular detection routine * that this rule keyword is supposed to encompass. * * Arguments: p => pointer to the decoded packet * otn => pointer to the current rule's OTN * fp_list => pointer to the function pointer list * * Returns: If the detection test fails, this function *must* return a zero! * On success, it calls the next function in the detection list * ****************************************************************************/ int Base64DataEval(void *option_data, Packet *p) { int rval = DETECTION_OPTION_NO_MATCH; PROFILE_VARS; PREPROC_PROFILE_START(base64DataPerfStats); if ((p->dsize == 0) || !base64_decode_size ) { PREPROC_PROFILE_END(base64DataPerfStats); return rval; } SetDoePtr(base64_decode_buf, DOE_BUF_STD); SetAltDetect(base64_decode_buf, (uint16_t)base64_decode_size); rval = DETECTION_OPTION_MATCH; PREPROC_PROFILE_END(base64DataPerfStats); return rval; } snort-2.9.15.1/src/detection-plugins/sp_base64_data.h0000644000175200017520000000175413571422607017233 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2003-2013 Sourcefire, Inc. ** ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __SP_BASE64_DATA_H__ #define __SP_BASE64_DATA_H__ void SetupBase64Data(void); #endif snort-2.9.15.1/src/detection-plugins/sp_pkt_data.c0000644000175200017520000001207513571422607016736 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 1998-2013 Sourcefire, Inc. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* sp_pkt_data * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifdef HAVE_STRINGS_H #include #endif #include #include "sf_types.h" #include "snort_bounds.h" #include "rules.h" #include "decode.h" #include "plugbase.h" #include "parser.h" #include "snort_debug.h" #include "util.h" #include "mstring.h" #include "snort.h" #include "profiler.h" #include "sp_pkt_data.h" #ifdef PERF_PROFILING PreprocStats pktDataPerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif #include "detection_options.h" #include "detection_util.h" extern char *file_name; /* this is the file name from rules.c, generally used for error messages */ extern int file_line; /* this is the file line number from rules.c that is used to indicate file lines for error messages */ static void PktDataInit(struct _SnortConfig *, char *, OptTreeNode *, int); void PktDataParse(char *, OptTreeNode *); int PktDataEval(void *option_data, Packet *p); /**************************************************************************** * * Function: SetupPktData() * * Purpose: Load 'er up * * Arguments: None. * * Returns: void function * ****************************************************************************/ void SetupPktData(void) { /* map the keyword to an initialization/processing function */ RegisterRuleOption("pkt_data", PktDataInit, NULL, OPT_TYPE_DETECTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("pkt_data", &pktDataPerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: pkt_data Setup\n");); } /**************************************************************************** * * Function: PktDataInit(struct _SnortConfig *, char *, OptTreeNode *, int protocol) * * Purpose: Generic rule configuration function. Handles parsing the rule * information and attaching the associated detection function to * the OTN. * * Arguments: data => rule arguments/data * otn => pointer to the current rule option list node * protocol => protocol the rule is on (we don't care in this case) * * Returns: void function * ****************************************************************************/ static void PktDataInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { OptFpList *fpl; PktDataParse(data, otn); fpl = AddOptFuncToList(PktDataEval, otn); fpl->type = RULE_OPTION_TYPE_PKT_DATA; } /**************************************************************************** * * Function: PktDataParse(char *, OptTreeNode *) * * Purpose: This is the function that is used to process the option keyword's * arguments and attach them to the rule's data structures. * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ void PktDataParse(char *data, OptTreeNode *otn) { if (!IsEmptyStr(data)) { FatalError("%s(%d): pkt_data takes no arguments\n", file_name, file_line); } } /**************************************************************************** * * Function: PktDataEval(char *, OptTreeNode *, OptFpList *) * * Purpose: Use this function to perform the particular detection routine * that this rule keyword is supposed to encompass. * * Arguments: p => pointer to the decoded packet * otn => pointer to the current rule's OTN * fp_list => pointer to the function pointer list * * Returns: If the detection test fails, this function *must* return a zero! * On success, it calls the next function in the detection list * ****************************************************************************/ int PktDataEval(void *option_data, Packet *p) { int rval = DETECTION_OPTION_MATCH; PROFILE_VARS; PREPROC_PROFILE_START(pktDataPerfStats); SetDoePtr(NULL, DOE_BUF_STD); DetectFlag_Disable(FLAG_ALT_DETECT); PREPROC_PROFILE_END(pktDataPerfStats); return rval; } snort-2.9.15.1/src/detection-plugins/sp_pkt_data.h0000644000175200017520000000174313571422607016743 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2003-2013 Sourcefire, Inc. ** ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __SP_PKT_DATA_H__ #define __SP_PKT_DATA_H__ void SetupPktData(void); #endif snort-2.9.15.1/src/detection-plugins/sp_file_type.c0000644000175200017520000002460213571422607017126 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2013-2013 Sourcefire, Inc. ** ** 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. */ // // file sp_file_type.c // author Victor Roemer // #include #include #include #include #include #include #include #include "sf_types.h" #include "snort_bounds.h" #include "rules.h" #include "decode.h" #include "plugbase.h" #include "parser.h" #include "snort_debug.h" #include "util.h" #include "mstring.h" #include "strvec.h" #include "file-process/file_api.h" #include "file-process/file_service_config.h" #include "file-process/libs/file_lib.h" #include "file-process/libs/file_config.h" typedef struct _FileTypeOpt { uint32_t *ids; unsigned count; } FileTypeOpt; static void FileType_Init (struct _SnortConfig*, char*, OptTreeNode*, int); static void FileGroup_Init (struct _SnortConfig*, char*, OptTreeNode*, int); static void FileType_Parse (const void*, const char*, FileTypeOpt*); static void FileGroup_Parse (const void*, const char*, FileTypeOpt*); static int FileType_Check (void*, Packet*); #if defined(PERF_PROFILING) PreprocStats _sp_file_type_perf_stats; extern PreprocStats ruleOTNEvalPerfStats; #endif // PERF_PROFILING // qsort() callback static int Compare_Ids(const void *p1, const void *p2) { return (*(const uint32_t *)p1 - *(const uint32_t *)p2); } // Sort the rule option file id's static void Sort_Ids(uint32_t *ids, size_t cnt) { size_t i; assert( ids ); assert( cnt ); qsort(ids, cnt, sizeof(*ids), Compare_Ids); for ( i = 1; i < cnt; ++i ) { // XXX I am not sure that this check is necessary anymore. if ( ids[i] == ids[i-1] ) ParseError("Duplicate file type configured in rule."); } } // Check if 'type' was previously configured in the rule option. static bool isPrevType(const char *type, void *prev_types) { const char * prev; int i = 0; while ( (prev = StringVector_Get(prev_types, i++)) ) if ( prev && strcmp(type, prev) == 0 ) return true; return false; } // Generate a unique digest of the rule option. uint32_t FileTypeHash(const void *option) { uint32_t abc[3]; unsigned i; const FileTypeOpt *opt = (FileTypeOpt*)option; abc[0] = opt->count; abc[1] = RULE_OPTION_TYPE_FILE_TYPE; abc[2] = 0; mix(abc[0], abc[1], abc[2]); for ( i = 0; i < opt->count; ++i ) abc[i % 3] += opt->ids[i]; final(abc[0], abc[1], abc[2]); return abc[2]; } // Compare 2 rule options for duplicity int FileTypeCompare(const void * _left, const void * _right) { unsigned i; const FileTypeOpt *left = (FileTypeOpt*)_left; const FileTypeOpt *right = (FileTypeOpt*)_right; if ( !left || !right ) return DETECTION_OPTION_NOT_EQUAL; if ( left->count != right->count ) return DETECTION_OPTION_NOT_EQUAL; for ( i = 0; i < left->count; ++i ) if ( left->ids[i] != right->ids[i] ) return DETECTION_OPTION_NOT_EQUAL; return DETECTION_OPTION_EQUAL; } // Free options void FileTypeFree(void *option) { FileTypeOpt *opt = (FileTypeOpt*)option; assert( opt ); assert( opt->ids ); assert( opt->count > 0 ); free(opt->ids); free(opt); } // Register options void SetupFileType(void) { RegisterRuleOption("file_type", FileType_Init, NULL, OPT_TYPE_ACTION, NULL); RegisterRuleOption("file_group", FileGroup_Init, NULL, OPT_TYPE_ACTION, NULL); #if defined(PERF_PROFILING) RegisterPreprocessorProfile("file_type", &_sp_file_type_perf_stats, 3, &ruleOTNEvalPerfStats, NULL); #endif // PERF_PROFILING } // Common code used for initialization static void Rule_Init(struct _SnortConfig *conf, OptTreeNode *otn, void *option) { int ret; OptFpList *fpl; void *temp = NULL; // Auto-magically enable file-type detection when no explicit // configuration exists. file_api->enable_file_type(conf, NULL); fpl = AddOptFuncToList(FileType_Check, otn); fpl->type = RULE_OPTION_TYPE_FILE_TYPE; ret = add_detection_option(conf, fpl->type, option, &temp); if ( ret == DETECTION_OPTION_EQUAL ) { FileTypeFree(option); option = temp; } fpl->context = option; } // Initialize the "file_type" rule option static void FileType_Init(struct _SnortConfig *conf, char *in, OptTreeNode *otn, int pro) { FileTypeOpt *opt = SnortAlloc(sizeof(*opt)); FileType_Parse(conf->file_config, in, opt); Rule_Init(conf, otn, opt); } // Initialize the "file_group" rule option static void FileGroup_Init(struct _SnortConfig *conf, char *in, OptTreeNode *otn, int pro) { FileTypeOpt *opt = SnortAlloc(sizeof(*opt)); FileGroup_Parse(conf->file_config, in, opt); Rule_Init(conf, otn, opt); } static int args_look_ok( const char * src, const char **err ) { enum { ST0, ST1, ERR } state; assert( err != NULL ); state = ST0; while ( *src ) { char c = *src; src += 1; switch ( state ) { case ST0: if ( IS_RULE_TYPE_IDENT((int)c) ) { state = ST1; } else { *err = "Expected a file type or version.", state = ERR; } break; case ST1: if ( c == ',' || c == '|' ) { state = ST0; } else if ( !IS_RULE_TYPE_IDENT((int)c) ) { *err = "Expected a file type, version or ',' or '|' character."; state = ERR; } break; case ERR: // Cant get here; silence compiler noise. break; } if ( state == ERR ) return -1; } if ( state == ST0 ) { *err = "Trailing ',' or '|' character."; return -1; } return 0; } // Parse "file_type" keyword static void FileType_Parse(const void *conf, const char *in, FileTypeOpt *opt) { int i; int num_toks = 0; char **toks; void *prev_types; const char *err; toks = mSplit(in, "|", 0, &num_toks, 0); if ( num_toks < 1 ) { ParseError("Missing argument to 'file_type' option."); } if ( args_look_ok(in, &err) == -1 ) { assert( err != NULL ); ParseError("Error found in 'file_type' arguments: %s\n", err); } prev_types = StringVector_New(); for ( i = 0; i < num_toks; ++i ) { char *temp; char **subs; int num_subs = 0; bool found = false; temp = SnortStrdup(toks[i]); subs = mSplit(temp, ",", 0, &num_subs, 0); if ( num_subs >= 2 ) { // Collect all rule ids for a specific version of a type. int j; const char *type = subs[0]; if ( isPrevType(type, prev_types) ) { ParseError("file type \'%s\' was specified multiple times.\n", type); } StringVector_Add(prev_types, type); for ( j = 1; j < num_subs; j++ ) { const char *version = subs[j]; found = file_IDs_from_type_version(conf, type, version, &opt->ids, &opt->count); if ( !found ) { ParseError("\'%s\' version \'%s\' is not a configured " "file type.", type, version); } } } else { const char * type = toks[i]; if ( isPrevType(type, prev_types) ) { ParseError("file type \'%s\' is specified multiple times.\n", type); } StringVector_Add(prev_types, type); // Collect all rule ids for a type. found = file_IDs_from_type(conf, type, &opt->ids, &opt->count); } if ( !found ) { ParseError("\'%s\' is not a configured file type.", toks[i]); } mSplitFree(&subs, num_subs); free(temp); } StringVector_Delete(prev_types); mSplitFree(&toks, num_toks); Sort_Ids(opt->ids, opt->count); } // Parse "file_group" keyword static void FileGroup_Parse(const void *conf, const char *in, FileTypeOpt *opt) { if ( IsEmptyStr(in) ) ParseError("Missing argument to 'file_group' option."); // Collect all rule ids in group. if ( !file_IDs_from_group(conf, in, &opt->ids, &opt->count) ) ParseError("\'%s\' is not a configured file group.", in); Sort_Ids(opt->ids, opt->count); } // Check if the session is transferring the file type static int FileType_Check(void *option, Packet *p) { uint32_t id; const FileTypeOpt *opt = (FileTypeOpt*)option; PROFILE_VARS; PREPROC_PROFILE_START(_sp_file_type_perf_stats); assert( file_api->is_file_service_enabled() ); assert( file_api->get_max_file_depth(NULL, false) >= 0 ); assert( opt->ids ); assert( opt->count > 0 ); if ( !p->ssnptr ) { PREPROC_PROFILE_END(_sp_file_type_perf_stats); return DETECTION_OPTION_NO_MATCH; } id = file_api->get_file_type_id(p->ssnptr); if ( id != SNORT_FILE_TYPE_UNKNOWN ) { void *found = bsearch(&id, opt->ids, opt->count, sizeof(opt->ids[0]), Compare_Ids); if ( found ) { PREPROC_PROFILE_END(_sp_file_type_perf_stats); return DETECTION_OPTION_MATCH; } } PREPROC_PROFILE_END(_sp_file_type_perf_stats); return DETECTION_OPTION_NO_MATCH; } snort-2.9.15.1/src/detection-plugins/sp_file_type.h0000644000175200017520000000243213571422607017130 00000000000000/**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2005-2013 Sourcefire, Inc. * * 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. * ****************************************************************************/ /* file sp_filetype.h * author Victor Roemer */ #ifndef SP_FILE_TYPE_H #define SP_FILE_TYPE_H void SetupFileType( ); uint32_t FileTypeHash(void *); int FileTypeCompare(void *, void *); int FileTypeFree(void *); #endif snort-2.9.15.1/src/detection-plugins/sp_react.c0000644000175200017520000003271113571422607016244 00000000000000/* $Id$ */ /**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2005-2013 Sourcefire, Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ****************************************************************************/ // @file sp_react.c // @author Russ Combs /* The original Snort React Plugin was contributed by Maciej Szarpak, Warsaw * University of Technology. The module has been entirely rewritten by * Sourcefire as part of the effort to overhaul active response. Some of the * changes include: * * - elimination of unworkable warn mode * - elimination of proxy port (rule header has ports) * - integration with unified active response mechanism * - queuing of rule option responses so at most one is issued * - allow override by rule action when action is drop * - addition of http headers to default response * - added custom page option * - and other stuff * * This version will send a web page to the client and then reset both * ends of the session. The web page may be configured or the default * may be used. The web page can have the default warning message * inserted or the message from the rule. * * If you wish to just reset the session, use the resp keyword instead. */ #ifdef ENABLE_REACT #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "sf_types.h" #include "snort_debug.h" #include "decode.h" #include "encode.h" #include "detection_options.h" #include "parser.h" #include "plugbase.h" #include "plugin_enum.h" #include "profiler.h" #include "active.h" #include "rules.h" #include "sfhashfcn.h" #include "sp_react.h" #include "snort.h" #ifdef PERF_PROFILING static PreprocStats reactPerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif static const char* MSG_KEY = "<>"; static const char* MSG_PERCENT = "%"; static const char* DEFAULT_HTTP = "HTTP/1.1 403 Forbidden\r\n" "Connection: close\r\n" "Content-Type: text/html; charset=utf-8\r\n" "Content-Length: %d\r\n" "\r\n"; static const char* DEFAULT_HTML = "\r\n" "\r\n" "\r\n" "\r\n" "Access Denied\r\n" "\r\n" "\r\n" "

Access Denied

\r\n" "

%s

\r\n" "\r\n" "\r\n"; static const char* DEFAULT_MSG = "You are attempting to access a forbidden site.
" "Consult your system administrator for details."; typedef struct _ReactData { uint32_t id; int rule_msg; // 1=>use rule msg; 0=>use DEFAULT_MSG ssize_t buf_len; // length of response char* resp_buf; // response to send const OptTreeNode* otn; } ReactData; static int s_init = 1; static int s_deprecated = 0; static char* s_page = NULL; // When React_Init() is called the rule msg keyword may not have // been processed. This necessitates two things: // // * A unique instance id is used in the hash in lieu of the // message text. The id starts at 1 since 0 is reserved for // the default msg. Assuming all rules have different msg // strings, the id is a valid proxy. // // * React_Config() is installed to instantiate the page after // rule parsing is complete (when for sure the msg is // available). // // Ideally a separate rule configuration callback could be installed // that would be called after all options are parsed and before the // options are finalized. static uint32_t s_id = 1; // callback functions static void React_Init(struct _SnortConfig *, char *, OptTreeNode *, int); static void React_Cleanup(int signal, void *data); static void React_Config (struct _SnortConfig *, void *data); // core functions static void React_GetPage(struct _SnortConfig *); static void React_Parse(char *, OptTreeNode *, ReactData *); static int React_Queue(Packet*, void*); static void React_Send(Packet*, void*); //-------------------------------------------------------------------- // public functions void ReactFree(void *d) { ReactData *data = (ReactData *)d; if (data->resp_buf) free(data->resp_buf); free(data); } uint32_t ReactHash(void *d) { uint32_t a,b,c,tmp; unsigned int i,j,k,l; ReactData *data = (ReactData *)d; const char* s = s_page ? s_page : DEFAULT_HTML; unsigned n = strlen(s); a = data->rule_msg; b = n; c = (data->rule_msg ? data->id : 0); mix(a,b,c); for ( i=0,j=0; i 4) k=4; for (l=0;lbuf_len != right->buf_len) return DETECTION_OPTION_NOT_EQUAL; if (memcmp(left->resp_buf, right->resp_buf, left->buf_len) != 0) return DETECTION_OPTION_NOT_EQUAL; if (left->rule_msg != right->rule_msg) return DETECTION_OPTION_NOT_EQUAL; return DETECTION_OPTION_EQUAL; } void SetupReact(void) { RegisterRuleOption("react", React_Init, NULL, OPT_TYPE_ACTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("react", &reactPerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif } //-------------------------------------------------------------------- // callback functions static void React_Init(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { ReactData* rd; void *idx_dup; if ( otn->ds_list[PLUGIN_RESPONSE] ) FatalError("%s(%d): Multiple response options in rule\n", file_name, file_line); if ( protocol != IPPROTO_TCP ) FatalError("%s(%d): React options on non-TCP rule\n", file_name, file_line); DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"In React_Init()\n");); if ( s_init ) { AddFuncToCleanExitList(React_Cleanup, NULL); React_GetPage(sc); Active_SetEnabled(1); s_init = 0; } /* parse the react keywords */ rd = SnortAlloc(sizeof(*rd)); React_Parse(data, otn, rd); rd->otn = otn; if (add_detection_option(sc, RULE_OPTION_TYPE_REACT, (void*)rd, &idx_dup) == DETECTION_OPTION_EQUAL) { free(rd); rd = idx_dup; } /* finally, attach the option's detection function to the rule's detect function pointer list */ AddRspFuncToList(React_Queue, otn, (void*)rd); AddFuncToPreprocPostConfigList(sc, React_Config, rd); // this prevents multiple response options in rule otn->ds_list[PLUGIN_RESPONSE] = rd; } static void React_Cleanup(int signal, void* data) { if ( s_page ) { free(s_page); s_page = NULL; } s_init = 1; } //-------------------------------------------------------------------- // core functions static void React_GetPage (struct _SnortConfig *sc) { char* msg; char* percent_s; struct stat fs; FILE* fd; size_t n; if ( !sc ) FatalError("react: %s(%d) Snort config for parsing is NULL.\n", file_name, file_line); if ( s_page || !sc->react_page ) return; if ( stat(sc->react_page, &fs) ) FatalError("react: %s(%d) can't stat react page file '%s'.\n", file_name, file_line, sc->react_page); s_page = SnortAlloc(fs.st_size+1); fd = fopen(sc->react_page, "r"); if ( !fd ) FatalError("react: %s(%d) can't open react page file '%s'.\n", file_name, file_line, sc->react_page); n = fread(s_page, 1, fs.st_size, fd); fclose(fd); if ( n != (size_t)fs.st_size ) FatalError("react: %s(%d) can't load react page file '%s'.\n", file_name, file_line, sc->react_page); s_page[n] = '\0'; msg = strstr(s_page, MSG_KEY); if ( msg ) strncpy(msg, "%s", 2); // search for % percent_s = strstr(s_page, MSG_PERCENT); if (percent_s) { percent_s += strlen(MSG_PERCENT); // move past current // search for % again percent_s = strstr(percent_s, MSG_PERCENT); if (percent_s) { FatalError("react: %s(%d) can't specify more than one %%s or other " "printf style formatting characters in react page '%s'.\n", file_name, file_line, sc->react_page); } } } //-------------------------------------------------------------------- static void React_Parse(char* data, OptTreeNode* otn, ReactData* rd) { char* tok = NULL; if ( data ) { while(isspace((int)*data)) data++; tok = strtok(data, ","); } while(tok) { /* parse the react option keywords */ if ( !strncasecmp(tok, "proxy", 5) || !strcasecmp(tok, "block") || !strcasecmp(tok, "warn") ) { if ( !s_deprecated ) { ParseWarning("proxy, block, and warn options are deprecated.\n"); s_deprecated = 1; } } else if ( !strcasecmp(tok, "msg") ) { rd->rule_msg = 1; } else FatalError("%s(%d): invalid react option: %s\n", file_name, file_line, tok); tok = strtok(NULL, ","); /* get rid of spaces */ while ( tok && isspace((int)*tok) ) tok++; } rd->resp_buf = NULL; rd->buf_len = 0; rd->id = s_id++; } //-------------------------------------------------------------------- // format response buffer static void React_Config (struct _SnortConfig *sc, void *data) { ReactData *rd = (ReactData *)data; size_t body_len, head_len, total_len; char dummy; const char* head = DEFAULT_HTTP; const char* body = s_page ? s_page : DEFAULT_HTML; const char* msg = rd->otn->sigInfo.message; if ( !msg || !rd->rule_msg ) msg = DEFAULT_MSG; body_len = snprintf(&dummy, 1, body, msg); head_len = snprintf(&dummy, 1, head, body_len); total_len = head_len + body_len + 1; rd->resp_buf = (char*)SnortAlloc(total_len); SnortSnprintf((char*)rd->resp_buf, head_len+1, head, body_len); SnortSnprintf((char*)rd->resp_buf+head_len, body_len+1, body, msg); // set actual length rd->resp_buf[total_len-1] = '\0'; rd->buf_len = strlen(rd->resp_buf); } //-------------------------------------------------------------------- static int React_Queue (Packet* p, void* pv) { ReactData* rd = (ReactData*)pv; PROFILE_VARS; PREPROC_PROFILE_START(reactPerfStats); if ( Active_IsRSTCandidate(p) ) Active_QueueResponse(React_Send, rd); Active_DropSession(p); if (pkt_trace_enabled) { if (rd && rd->otn) addPktTraceData(VERDICT_REASON_REACT, snprintf(trace_line, MAX_TRACE_LINE, "Snort React: web page %s, gid %u, sid %u, %s\n", Active_IsRSTCandidate(p)? "is sent" : "isn't sent", rd->otn->sigInfo.generator, rd->otn->sigInfo.id, getPktTraceActMsg())); else addPktTraceData(VERDICT_REASON_REACT, snprintf(trace_line, MAX_TRACE_LINE, "Snort React: web page %s, %s\n", Active_IsRSTCandidate(p)? "is sent" : "isn't sent", getPktTraceActMsg())); } else addPktTraceData(VERDICT_REASON_REACT, 0); PREPROC_PROFILE_END(reactPerfStats); return 0; } //-------------------------------------------------------------------- static void React_Send (Packet* p, void* pv) { ReactData* rd = (ReactData*)pv; EncodeFlags df = (p->packet_flags & PKT_FROM_SERVER) ? ENC_FLAG_FWD : 0; EncodeFlags sent = rd->buf_len; EncodeFlags rf; PROFILE_VARS; PREPROC_PROFILE_START(reactPerfStats); Active_IgnoreSession(p); if (p->packet_flags & PKT_STREAM_EST) { Active_SendData(p, df, (uint8_t*)rd->resp_buf, rd->buf_len); // Active_SendData sends a FIN, so need to bump seq by 1. sent++; } rf = df ^ ENC_FLAG_FWD; df |= ENC_FLAG_SEQ | (ENC_FLAG_VAL & sent); Active_SendReset(p, df); Active_SendReset(p, rf); PREPROC_PROFILE_END(reactPerfStats); } #endif /* ENABLE_REACT */ snort-2.9.15.1/src/detection-plugins/sp_react.h0000644000175200017520000000230013571422607016240 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __SP_REACT_H__ #define __SP_REACT_H__ #ifdef ENABLE_REACT void SetupReact(void); void ReactFree(void *d); uint32_t ReactHash(void *d); int ReactCompare(void *l, void *r); #endif /* ENABLE_REACT */ #endif /* __SP_REACT_H__ */ snort-2.9.15.1/src/detection-plugins/sp_respond3.c0000644000175200017520000002115213571422607016700 00000000000000/* $Id$ */ /**************************************************************************** * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2005-2013 Sourcefire, Inc. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * ****************************************************************************/ /* Snort sp_resp3 Detection Plugin * * Perform flexible response on packets matching conditions specified in Snort * rules. * * Shutdown hostile network connections by injecting TCP resets or ICMP * unreachable packets. * * flexresp3 is derived from flexresp and flexresp2. It includes all * configuration options from those modules and has these differences: * * - injects packets with correct encapsulations (doesn't assume * eth+ip+icmp/tcp). * * - uses the wire packet as a prototype, not the packet generating the alert * (which may be reassembled or otherwise generated internally with only the * headers required for logging). * * - queues the injection action so that it is taken only once after detection * regardless of multiple resp3 rules firing. * * - uses the same encoding and injection mechanism as active_response and/or * reject actions. * * - bypasses sequence strafing in inline mode. * * - if a resp3 rule is also a drop rule, the drop processing takes precedence. */ // @file sp_respond3.c // @author Russ Combs #ifdef ENABLE_RESPONSE3 #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sf_types.h" #include "snort_bounds.h" #include "checksum.h" #include "snort_debug.h" #include "decode.h" #include "encode.h" #include "detection_options.h" #include "log.h" #include "mstring.h" #include "parser.h" #include "plugbase.h" #include "plugin_enum.h" #include "profiler.h" #include "active.h" #include "rules.h" #include "sfhashfcn.h" #include "sfxhash.h" #include "snort.h" #include "sp_respond.h" #include "util.h" #define MOD_NAME "sp_resp3" /* plugin name */ #define RESP_RST_SND 0x01 #define RESP_RST_RCV 0x02 #define RESP_UNR_NET 0x04 #define RESP_UNR_HOST 0x08 #define RESP_UNR_PORT 0x10 #define RESP_RST (RESP_RST_SND|RESP_RST_RCV) #define RESP_UNR (RESP_UNR_NET|RESP_UNR_HOST|RESP_UNR_PORT) #ifdef PERF_PROFILING static PreprocStats resp3PerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif // instance data typedef struct { uint32_t mask; uint32_t flags; } Resp3_Data; static int s_init = 1; // callback functions static void Resp3_Init(struct _SnortConfig *, char* data, OptTreeNode*, int protocol); static void Resp3_Cleanup(int signal, void* data); // core functions static int Resp3_Parse(char* type); static int Resp3_Queue(Packet*, void*); static void Resp3_Send(Packet*, void*); //-------------------------------------------------------------------- // public functions // here we use the non '_' versions for consistency ... uint32_t RespondHash(void* d) { uint32_t a,b,c; Resp3_Data* data = (Resp3_Data*)d; a = data->mask; b = RULE_OPTION_TYPE_RESPOND; c = 0; final(a,b,c); return c; } int RespondCompare(void* l, void* r) { Resp3_Data* left = (Resp3_Data*)l; Resp3_Data* right = (Resp3_Data*)r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if (left->mask == right->mask) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } // and here we use the functional name for consistency ... void SetupRespond(void) { RegisterRuleOption("resp", Resp3_Init, NULL, OPT_TYPE_ACTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("resp3", &resp3PerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif } //-------------------------------------------------------------------- // callback functions static void Resp3_Init(struct _SnortConfig *sc, char* data, OptTreeNode* otn, int protocol) { Resp3_Data* rd = NULL; void* idx_dup; if ( otn->ds_list[PLUGIN_RESPONSE] ) FatalError("%s(%d): Multiple response options in rule\n", file_name, file_line); if ( s_init ) { AddFuncToCleanExitList(Resp3_Cleanup, NULL); Active_SetEnabled(1); s_init = 0; } rd = (Resp3_Data*)SnortAlloc(sizeof(*rd)); rd->mask = Resp3_Parse(data); if ( add_detection_option(sc, RULE_OPTION_TYPE_RESPOND, rd, &idx_dup) == DETECTION_OPTION_EQUAL) { free(rd); rd = idx_dup; } // this prevents multiple response options in rule otn->ds_list[PLUGIN_RESPONSE] = rd; AddRspFuncToList(Resp3_Queue, otn, rd); } static void Resp3_Cleanup(int signal, void* data) { s_init = 1; } //-------------------------------------------------------------------- // core functions // TBD conf parsing should be registered and distributed as well as rule // option parsing static int Resp3_Parse(char* type) { char* *toks; uint32_t flags = 0; int num_toks, i; if ( type ) toks = mSplit(type, ",", 6, &num_toks, 0); else FatalError("%s: %s(%d): missing resp modifier", MOD_NAME, file_name, file_line); i = 0; while (i < num_toks) { if ( !strcasecmp(toks[i], "reset_source") || !strcasecmp(toks[i], "rst_snd") ) { flags |= RESP_RST_SND; i++; } else if ( !strcasecmp(toks[i], "reset_dest") || !strcasecmp(toks[i], "rst_rcv") ) { flags |= RESP_RST_RCV; i++; } else if ( !strcasecmp(toks[i], "reset_both") || !strcasecmp(toks[i], "rst_all") ) { flags |= (RESP_RST_RCV | RESP_RST_SND); i++; } else if (!strcasecmp(toks[i], "icmp_net")) { flags |= RESP_UNR_NET; i++; } else if (!strcasecmp(toks[i], "icmp_host")) { flags |= RESP_UNR_HOST; i++; } else if (!strcasecmp(toks[i], "icmp_port")) { flags |= RESP_UNR_PORT; i++; } else if (!strcasecmp(toks[i], "icmp_all")) { flags |= (RESP_UNR_NET | RESP_UNR_HOST | RESP_UNR_PORT); i++; } else FatalError("%s: %s(%d): invalid resp modifier: %s\n", MOD_NAME, file_name, file_line, toks[i]); } mSplitFree(&toks, num_toks); if ( !flags ) FatalError("%s: %s(%d): invalid resp configuration: %s\n", MOD_NAME, file_name, file_line, "no response specified"); return flags; } //-------------------------------------------------------------------- static int Resp3_Queue (Packet* p, void* pv) { Resp3_Data* rd = (Resp3_Data*)pv; PROFILE_VARS; PREPROC_PROFILE_START(resp3PerfStats); rd->flags = 0; if ( Active_IsRSTCandidate(p) ) rd->flags |= (rd->mask & RESP_RST); if ( Active_IsUNRCandidate(p) ) rd->flags |= (rd->mask & RESP_UNR); if ( rd->flags ) Active_QueueResponse(Resp3_Send, rd); PREPROC_PROFILE_END(resp3PerfStats); return 0; } //-------------------------------------------------------------------- static void Resp3_Send (Packet* p, void* pv) { Resp3_Data* rd = (Resp3_Data*)pv; PROFILE_VARS; PREPROC_PROFILE_START(resp3PerfStats); Active_IgnoreSession(p); if ( rd->flags & RESP_RST_SND ) Active_SendReset(p, 0); if ( rd->flags & RESP_RST_RCV ) Active_SendReset(p, ENC_FLAG_FWD); if ( rd->flags & RESP_UNR_NET ) Active_SendUnreach(p, ENC_UNR_NET); if ( rd->flags & RESP_UNR_HOST ) Active_SendUnreach(p, ENC_UNR_HOST); if ( rd->flags & RESP_UNR_PORT ) Active_SendUnreach(p, ENC_UNR_PORT); if (pkt_trace_enabled) addPktTraceData(VERDICT_REASON_RESPONSE, snprintf(trace_line, MAX_TRACE_LINE, "Snort Response: ignoring session, %s\n", getPktTraceActMsg())); else addPktTraceData(VERDICT_REASON_RESPONSE, 0); PREPROC_PROFILE_END(resp3PerfStats); } #endif // ENABLE_RESPONSE3 snort-2.9.15.1/src/detection-plugins/sp_respond.h0000644000175200017520000000231113571422607016616 00000000000000/* $Id$ */ /* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** Copyright (C) 1999,2000,2001 Christian Lademann ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __SP_RESPOND_H__ #define __SP_RESPOND_H__ #ifdef ENABLE_RESPOND void SetupRespond(void); uint32_t RespondHash(void* d); int RespondCompare(void *l, void *r); #endif #endif snort-2.9.15.1/src/detection-plugins/sp_appid.c0000644000175200017520000002640113571422607016242 00000000000000/* * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* sp_appid * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifdef HAVE_STRINGS_H #include #endif #include #include "sf_types.h" #include "snort_bounds.h" #include "rules.h" #include "decode.h" #include "plugbase.h" #include "parser.h" #include "snort_debug.h" #include "util.h" #include "mstring.h" #include "snort.h" #include "profiler.h" #include "sp_appid.h" #include "appIdApi.h" #include "preprocessors/stream_api.h" #ifdef PERF_PROFILING PreprocStats appIdPerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif #define CONF_SEPARATORS ",\t\n\r" #include "detection_options.h" #include "detection_util.h" #include "sftarget_protocol_reference.h" #include "sp_appid.h" //#include "sf_dynamic_preprocessor.h" extern char *file_name; /* this is the file name from rules.c, generally used for error messages */ extern int file_line; /* this is the file line number from rules.c that is used to indicate file lines for error messages */ #define NUM_APPID_IN_RULE_STEP 5 #define MAX_NUM_APPID_IN_RULE 10 static void ParseAppIdData(struct _SnortConfig *sc, char *data, OptTreeNode *otn); static void AppIdInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol); static int CheckAppId (void *option_data, Packet *p); AppIdOptionData* createOptionData(void); void optAppIdFree(AppIdOptionData *optData); extern int32_t getApplicationId(const char * appName); /**************************************************************************** * * Function: SetupAppId() * * Purpose: Load 'er up * * Arguments: None. * * Returns: void function * ****************************************************************************/ void SetupAppId(void) { /* map the keyword to an initialization/processing function */ RegisterRuleOption("appid", AppIdInit, NULL, OPT_TYPE_DETECTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("appid", &appIdPerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: appid Setup\n");); } AppIdOptionData* optionAppIdCreate() { AppIdOptionData *optData = (AppIdOptionData *) SnortAlloc(sizeof(AppIdOptionData)); optData->appid_table = SnortAlloc(sizeof(AppIdInfo) * NUM_APPID_IN_RULE_STEP); optData->num_appid_allocated = NUM_APPID_IN_RULE_STEP; return optData; } // Generate a unique digest of the rule option. uint32_t optionAppIdHash(const void *option) { uint32_t abc[3]; int i; const AppIdOptionData *optData = (AppIdOptionData*)option; abc[0] = optData->num_appid; abc[1] = 0; abc[2] = 0; mix(abc[0], abc[1], abc[2]); //TBD do I need to keep is sorted?? for ( i = 0; i < optData->num_appid; ++i ) abc[i % 3] += optData->appid_table[i].appid_ordinal; final(abc[0], abc[1], abc[2]); return abc[2]; } // Compare 2 rule options for duplicity int optionAppIdCompare(const void * _left, const void * _right) { int i; const AppIdOptionData *left = (AppIdOptionData*)_left; const AppIdOptionData *right = (AppIdOptionData*)_right; if ( !left || !right ) return DETECTION_OPTION_NOT_EQUAL; if ( left->num_appid != right->num_appid ) return DETECTION_OPTION_NOT_EQUAL; for ( i = 0; i < left->num_appid; ++i ) if ( left->appid_table[i].appid_ordinal != right->appid_table[i].appid_ordinal ) return DETECTION_OPTION_NOT_EQUAL; return DETECTION_OPTION_EQUAL; } void optionAppIdFree(AppIdOptionData *optData) { unsigned i; for (i=0; i < optData->num_appid; i++) { free(optData->appid_table[i].appName); } free(optData->appid_table); free(optData); } /**************************************************************************** * * Function: AppIdInit(struct _SnortConfig *, char *, OptTreeNode *, int protocol) * * Purpose: Generic rule configuration function. Handles parsing the rule * information and attaching the associated detection function to * the OTN. * * Arguments: data => rule arguments/data * otn => pointer to the current rule option list node * protocol => protocol the rule is on (we don't care in this case) * * Returns: void function * ****************************************************************************/ static void AppIdInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { OptFpList *fpl; void *ds_ptr_dup; AppIdOptionData *optData; /* multiple declaration check */ if(otn->ds_list[PLUGIN_APPID]) { FatalError("%s(%d): Multiple appid options in rule\n", file_name, file_line); } /* allocate the data structure and attach it to the rule's data struct list */ optData = optionAppIdCreate(); otn->ds_list[PLUGIN_APPID] = optData; /* this is where the keyword arguments are processed and placed into the rule option's data structure */ ParseAppIdData(sc, data, otn); if (add_detection_option(sc, RULE_OPTION_TYPE_APPID, (void *)optData, &ds_ptr_dup) == DETECTION_OPTION_EQUAL) { optionAppIdFree(optData); otn->ds_list[PLUGIN_APPID] = ds_ptr_dup; } /* finally, attach the option's detection function to the rule's detect function pointer list */ fpl = AddOptFuncToList(CheckAppId, otn); fpl->type = RULE_OPTION_TYPE_APPID; fpl->context = otn->ds_list[PLUGIN_APPID]; return; } static int compareIds(const void *p1, const void *p2) { return (((AppIdInfo *)p1)->appid_ordinal - ((AppIdInfo *)p2)->appid_ordinal); } /**************************************************************************** * * Function: ParseIpOptionData(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: This is the function that is used to process the option keyword's * arguments and attach them to the rule's data structures. * * Arguments: data => argument data * otn => pointer to the current rule's OTN * * Returns: void function * ****************************************************************************/ static void ParseAppIdData(struct _SnortConfig *sc, char *data, OptTreeNode *otn) { AppIdOptionData *ds_ptr; /* data struct pointer */ char * appName; boolean noapp = true; boolean found = false; int32_t ordinal; unsigned i; char *appNameEnd; /* set the ds pointer to make it easier to reference the option's particular data struct */ ds_ptr = otn->ds_list[PLUGIN_APPID]; if(data == NULL) { FatalError("%s(%d): appid Option keyword missing argument!\n", file_name, file_line); } while(isspace((u_char)*data)) data++; for (appName = strtok(data, CONF_SEPARATORS); appName; appName = strtok(NULL, CONF_SEPARATORS)) { //strip spaces at beging and end. while (*appName == ' ') appName++; //strip spaces at the end appNameEnd = appName + strlen(appName); while(isspace(*--appNameEnd) && appNameEnd > appName); *(appNameEnd+1) = '\0'; if (ds_ptr->num_appid == ds_ptr->num_appid_allocated) { AppIdInfo* tmp = realloc(ds_ptr->appid_table, (ds_ptr->num_appid_allocated + NUM_APPID_IN_RULE_STEP)*sizeof(*tmp)); if (!tmp) { ParseWarning("Malloc failure, too many appids in ruled %u\n"); break; } ds_ptr->appid_table = tmp; ds_ptr->num_appid_allocated += NUM_APPID_IN_RULE_STEP; } ordinal = appIdApi.getApplicationId(appName); if (!ordinal) { ParseWarning(" appid metadata \"%s\" unknown.\n", appName); return; } for (i=0; i < ds_ptr->num_appid; i++) { if (ds_ptr->appid_table[i].appid_ordinal == ordinal) { found = true; ParseWarning("Duplicate appid metadata \"%s\" found.\n", appName); break; } } if (!found) { noapp = false; ds_ptr->appid_table[ds_ptr->num_appid].appName = SnortStrdup(appName); ds_ptr->appid_table[ds_ptr->num_appid].appid_ordinal = ordinal; ds_ptr->num_appid++; } } if (noapp) { FatalError("%s(%d) => appid must be followed by common separate list of apps: %s!\n", file_name, file_line, data); } qsort(ds_ptr->appid_table, ds_ptr->num_appid, sizeof(*ds_ptr->appid_table), compareIds); } static int matchRuleProtoId( int16_t appProtoId, AppIdOptionData *app_data) { unsigned i; if (appProtoId == 0) return 0; for (i = 0; i < app_data->num_appid && (app_data->appid_table[i].appid_ordinal); i++) { if (appProtoId == app_data->appid_table[i].appid_ordinal) return appProtoId; } return 0; } static int CheckAppId (void *option_data, Packet *p) { AppIdOptionData *app_data = (AppIdOptionData *)option_data; PROFILE_VARS; int16_t serviceProtoId, clientProtoId, payloadProtoId, miscProtoId, matchedProtoId; PREPROC_PROFILE_START(appIdPerfStats); app_data->matched_appid = 0; if (!p->ssnptr) return DETECTION_OPTION_NO_MATCH; stream_api->get_application_id(p->ssnptr, &serviceProtoId, &clientProtoId, &payloadProtoId, &miscProtoId); matchedProtoId = matchRuleProtoId(payloadProtoId, app_data); if (!matchedProtoId) matchedProtoId = matchRuleProtoId(miscProtoId, app_data); if (!matchedProtoId) { if ((p->packet_flags & PKT_FROM_CLIENT)) { matchedProtoId = matchRuleProtoId(clientProtoId, app_data); if (!matchedProtoId) matchedProtoId = matchRuleProtoId(serviceProtoId, app_data); } else { matchedProtoId = matchRuleProtoId(serviceProtoId, app_data); if (!matchedProtoId) matchedProtoId = matchRuleProtoId(clientProtoId, app_data); } } if (matchedProtoId) { app_data->matched_appid = matchedProtoId; DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Got appid %d matched!\n", matchedProtoId);); PREPROC_PROFILE_END(appIdPerfStats); return DETECTION_OPTION_MATCH; } DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"No match\n");); PREPROC_PROFILE_END(appIdPerfStats); return DETECTION_OPTION_NO_MATCH; } snort-2.9.15.1/src/detection-plugins/sp_appid.h0000644000175200017520000000260413571422607016246 00000000000000/* * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __SP_APP_ID_OPTION_H__ #define __SP_APP_ID_OPTION_H__ typedef struct _AppIdInfo { char *appName; int16_t appid_ordinal; } AppIdInfo; typedef struct _AppIdOptionData { int16_t matched_appid; unsigned num_appid; unsigned num_appid_allocated; AppIdInfo* appid_table; } AppIdOptionData; void SetupAppId(void); AppIdOptionData* optionAppIdCreate(); void optionAppIdFree(AppIdOptionData *optData); uint32_t optionAppIdHash(const void *option); int optionAppIdCompare(const void * _left, const void * _right); #endif snort-2.9.15.1/src/detection-plugins/detection_leaf_node.c0000644000175200017520000001013313571422607020410 00000000000000/* ** Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. ** Copyright (C) 2002-2013 Sourcefire, Inc. ** Copyright (C) 1998-2002 Martin Roesch ** ** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* CHANGE HISTORY ============== 2014-10-30 Victor Roemer . REMOVED leaf node evaluation from `detection_options.c'. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sftarget_reader.h" typedef enum _LEAF_STATUS { Leaf_SkipPorts, Leaf_CheckPorts, Leaf_Abort } LEAF_STATUS; #ifdef HACK_DETECTION_LEAF_NODE_C #include #include #include #include // signature.h typedef enum _ServiceOverride { ServiceOverride_ElsePorts = 0, ServiceOverride_AndPorts, ServiceOverride_OrPorts, ServiceOverride_Nil } ServiceOverride; typedef struct _ServiceInfo { uint16_t service_ordinal; } ServiceInfo; typedef struct _SigInfo { ServiceInfo services[8]; unsigned int num_services; ServiceOverride service_override; } SigInfo; // treenodes.h typedef struct { SigInfo sigInfo; } OptTreeNode; // decode.h typedef struct { uint16_t application_protocol_ordinal; } Packet; // detection-plugins/detection_options.h typedef struct { OptTreeNode option_data[1]; } detection_option_tree_node_t; typedef struct { Packet p[1]; } detection_option_eval_data_t; // prototypes static inline LEAF_STATUS leaf_node_check_otn_service (OptTreeNode*, Packet*); static inline LEAF_STATUS detection_leaf_node_eval (detection_option_tree_node_t*, detection_option_eval_data_t*); #endif // DETECTION_LEAF_NODE_C // (detection_option_eval_data_t*) helper(s) #define PacketService(p) (p)->application_protocol_ordinal // (OptTreeNode*) helper(s) #define OtnServiceCount(otn) (otn)->sigInfo.num_services #define OtnAndPorts(otn) ((otn)->sigInfo.service_override == ServiceOverride_AndPorts) #define OtnOrPorts(otn) ((otn)->sigInfo.service_override == ServiceOverride_OrPorts) #define OtnElsePorts(otn) ((otn)->sigInfo.service_override == ServiceOverride_ElsePorts) //#define PortOnlyRule(otn) (OtnServiceCount (otn) == 0) #define PacketUnknown(pkt) (PacketService (pkt) == 0) static inline LEAF_STATUS leaf_node_check_otn_service (OptTreeNode * otn, Packet * packet) { bool service_match = false; unsigned int i; if (PacketUnknown (packet)) { if (OtnAndPorts (otn)) return (Leaf_Abort); return (Leaf_CheckPorts); } for (i = 0; i < OtnServiceCount (otn); i++) { const uint16_t ordinal = otn->sigInfo.services[ i ].service_ordinal; if (PacketService (packet) == ordinal) { service_match = true; } } if (service_match) { // identified service matches the rule if (OtnAndPorts (otn)) return (Leaf_CheckPorts); return (Leaf_SkipPorts); } else { if (!OtnOrPorts (otn)) return (Leaf_Abort); } return (Leaf_CheckPorts); } static inline LEAF_STATUS detection_leaf_node_eval (detection_option_tree_node_t * node, detection_option_eval_data_t * eval_data) { OptTreeNode *otn = (OptTreeNode*) node->option_data; Packet * packet = (Packet*) eval_data->p; if (!IsAdaptiveConfigured()) return (Leaf_CheckPorts); return leaf_node_check_otn_service (otn, packet); } snort-2.9.15.1/src/dynamic-plugins/0000755000000000000000000000000013571426521013763 500000000000000snort-2.9.15.1/src/dynamic-plugins/Makefile.in0000644000000000000000000005134413571425503015756 00000000000000# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 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@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd 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/dynamic-plugins DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LIBRARIES = $(noinst_LIBRARIES) ARFLAGS = cru AM_V_AR = $(am__v_AR_@AM_V@) am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) am__v_AR_0 = @echo " AR " $@; am__v_AR_1 = libdynamic_a_AR = $(AR) $(ARFLAGS) libdynamic_a_LIBADD = am_libdynamic_a_OBJECTS = sf_dynamic_plugins.$(OBJEXT) \ sp_dynamic.$(OBJEXT) sp_preprocopt.$(OBJEXT) \ sf_convert_dynamic.$(OBJEXT) \ sf_dynamic_decompression.$(OBJEXT) libdynamic_a_OBJECTS = $(am_libdynamic_a_OBJECTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = am__depfiles_maybe = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libdynamic_a_SOURCES) DIST_SOURCES = $(libdynamic_a_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CCONFIGFLAGS = @CCONFIGFLAGS@ CFLAGS = @CFLAGS@ CONFIGFLAGS = @CONFIGFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ ICONFIGFLAGS = @ICONFIGFLAGS@ INCLUDES = @INCLUDES@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LUA_CFLAGS = @LUA_CFLAGS@ LUA_LIBS = @LUA_LIBS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SIGNAL_SNORT_DUMP_STATS = @SIGNAL_SNORT_DUMP_STATS@ SIGNAL_SNORT_READ_ATTR_TBL = @SIGNAL_SNORT_READ_ATTR_TBL@ SIGNAL_SNORT_RELOAD = @SIGNAL_SNORT_RELOAD@ SIGNAL_SNORT_ROTATE_STATS = @SIGNAL_SNORT_ROTATE_STATS@ STRIP = @STRIP@ VERSION = @VERSION@ XCCFLAGS = @XCCFLAGS@ YACC = @YACC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 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@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ 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@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luajit_CFLAGS = @luajit_CFLAGS@ luajit_LIBS = @luajit_LIBS@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign no-dependencies noinst_LIBRARIES = libdynamic.a #SUBDIRS = sf_engine libdynamic_a_SOURCES = \ sf_dynamic_common.h \ sf_dynamic_detection.h \ sf_dynamic_engine.h \ sf_dynamic_define.h \ sf_dynamic_meta.h \ sf_dynamic_plugins.c \ sf_dynamic_preprocessor.h \ sf_dynamic_side_channel.h \ sp_dynamic.c \ sp_dynamic.h \ sp_preprocopt.c \ sp_preprocopt.h \ sf_convert_dynamic.c \ sf_convert_dynamic.h \ sf_dynamic_decompression.c \ sf_dynamic_decompression.h \ sf_decompression_define.h \ so_rule_mem_adjust.h SUBDIRS = sf_engine sf_preproc_example all: all-recursive .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/dynamic-plugins/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/dynamic-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: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libdynamic.a: $(libdynamic_a_OBJECTS) $(libdynamic_a_DEPENDENCIES) $(EXTRA_libdynamic_a_DEPENDENCIES) $(AM_V_at)-rm -f libdynamic.a $(AM_V_AR)$(libdynamic_a_AR) libdynamic.a $(libdynamic_a_OBJECTS) $(libdynamic_a_LIBADD) $(AM_V_at)$(RANLIB) libdynamic.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c .c.o: $(AM_V_CC)$(COMPILE) -c $< .c.obj: $(AM_V_CC)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: $(AM_V_CC)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files 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)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(LIBRARIES) installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_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-recursive clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool \ clean-noinstLIBRARIES cscopelist-am ctags ctags-am 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-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-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: snort-2.9.15.1/src/dynamic-plugins/Makefile.am0000444000175200017520000000113113571422607015770 00000000000000## $Id AUTOMAKE_OPTIONS=foreign no-dependencies noinst_LIBRARIES = libdynamic.a #SUBDIRS = sf_engine libdynamic_a_SOURCES = \ sf_dynamic_common.h \ sf_dynamic_detection.h \ sf_dynamic_engine.h \ sf_dynamic_define.h \ sf_dynamic_meta.h \ sf_dynamic_plugins.c \ sf_dynamic_preprocessor.h \ sf_dynamic_side_channel.h \ sp_dynamic.c \ sp_dynamic.h \ sp_preprocopt.c \ sp_preprocopt.h \ sf_convert_dynamic.c \ sf_convert_dynamic.h \ sf_dynamic_decompression.c \ sf_dynamic_decompression.h \ sf_decompression_define.h \ so_rule_mem_adjust.h INCLUDES = @INCLUDES@ SUBDIRS = sf_engine sf_preproc_example snort-2.9.15.1/src/dynamic-plugins/sf_dynamic_common.h0000644000175200017520000000723013571422607017601 00000000000000/* * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2005-2013 Sourcefire, Inc. * */ #ifndef _SF_DYNAMIC_COMMON_H_ #define _SF_DYNAMIC_COMMON_H_ #ifndef WIN32 #include #else #include #endif typedef enum { SF_FLAG_ALT_DECODE = 0x0001, SF_FLAG_ALT_DETECT = 0x0002, SF_FLAG_DETECT_ALL = 0xffff } SFDetectFlagType; #ifdef SF_WCHAR #include typedef void (*DebugWideMsgFunc)(uint64_t, const wchar_t *, ...); #endif typedef uint32_t (*GetSnortInstance)(void); #define STD_BUF 1024 #ifndef DECODE_BLEN #define DECODE_BLEN 65535 #define MAX_URI 8192 /* must be defined the same as in detection_util.h */ typedef enum { HTTP_BUFFER_NONE, HTTP_BUFFER_URI, HTTP_BUFFER_HEADER, HTTP_BUFFER_CLIENT_BODY, HTTP_BUFFER_METHOD, HTTP_BUFFER_COOKIE, HTTP_BUFFER_STAT_CODE, HTTP_BUFFER_STAT_MSG, HTTP_BUFFER_RAW_URI, HTTP_BUFFER_RAW_HEADER, HTTP_BUFFER_RAW_COOKIE, HTTP_BUFFER_MAX } HTTP_BUFFER; #endif /* Reasons for packet verdict indicating snort/preprocessor module that blocks a packet. * Any change here should also be reflected in pkt_trace.c file. */ typedef enum { VERDICT_REASON_INFO, /* Not blocking packet; used by module to send packet information to tracer */ VERDICT_REASON_SSNSTR, /* Not blocking packet; used to update session debug info */ VERDICT_REASON_NO_BLOCK, /* Not blocking packet; all enum defined after this indicates blocking */ VERDICT_REASON_UNKNOWN, /* Module blocking the packet is not known or traced */ VERDICT_REASON_DAQRETRY, /* Wait for another re-transmitted packet from DAQ */ VERDICT_REASON_SNORT, VERDICT_REASON_APPID, VERDICT_REASON_SFSSL, VERDICT_REASON_FIREWALL, VERDICT_REASON_CPORTAL, VERDICT_REASON_SAFESEARCH, VERDICT_REASON_SI, VERDICT_REASON_PREFILTER, VERDICT_REASON_FTP, VERDICT_REASON_STREAM, VERDICT_REASON_SESSION, VERDICT_REASON_DEFRAG, VERDICT_REASON_REACT, VERDICT_REASON_RESPONSE, VERDICT_REASON_REPUTATION, VERDICT_REASON_XLINK2STATE, VERDICT_REASON_BO, VERDICT_REASON_SMB, VERDICT_REASON_FILE, VERDICT_REASON_IPS, MAX_VERDICT_REASON } Verdict_Reason; typedef struct { const uint8_t *data; uint16_t len; } SFDataPointer; typedef struct { uint8_t data[DECODE_BLEN]; uint16_t len; } SFDataBuffer; typedef void (*LogMsgFunc)(const char *, ...); typedef void (*DebugMsgFunc)(uint64_t, const char *, ...); typedef int (*GetAltDetectFunc)(uint8_t **, uint16_t *); typedef void (*SetAltDetectFunc)(uint8_t *,uint16_t ); typedef int (*IsDetectFlagFunc)(SFDetectFlagType); typedef void (*DetectFlagDisableFunc)(SFDetectFlagType); typedef void (*SetHttpBufferFunc)(HTTP_BUFFER, const uint8_t*, unsigned); typedef const uint8_t* (*GetHttpBufferFunc)(HTTP_BUFFER, unsigned*); #endif /* _SF_DYNAMIC_COMMON_H_ */ snort-2.9.15.1/src/dynamic-plugins/sf_dynamic_detection.h0000644000175200017520000000362313571422607020271 00000000000000/* * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2005-2013 Sourcefire, Inc. * * Author: Steven Sturges * * Dynamic Detection Lib function declarations * */ #ifndef _SF_DYNAMIC_DETECTION_H_ #define _SF_DYNAMIC_DETECTION_H_ #include "sf_dynamic_meta.h" #include "snort.h" /* Function prototypes for Dynamic Detection Plugins */ void CloseDynamicDetectionLibs(SnortConfig *sc); void LoadAllDynamicDetectionLibs(SnortConfig *, const char * const path); int LoadDynamicDetectionLib(SnortConfig *, const char * const library_name, int indent); int InitDynamicDetectionPlugins(SnortConfig *); void RemoveDuplicateDetectionPlugins(SnortConfig *sc); typedef int (*DumpDetectionRules)(void); typedef int (*RequiredEngineLibFunc)(DynamicPluginMeta *); void *GetNextEnginePluginVersion(void *p); void *GetNextDetectionPluginVersion(SnortConfig *sc, void *p); void *GetNextPreprocessorPluginVersion(void *p); DynamicPluginMeta *GetDetectionPluginMetaData(void *p); DynamicPluginMeta *GetEnginePluginMetaData(void *p); DynamicPluginMeta *GetPreprocessorPluginMetaData(void *p); #endif /* _SF_DYNAMIC_DETECTION_H_ */ snort-2.9.15.1/src/dynamic-plugins/sf_dynamic_engine.h0000644000175200017520000001735313571422607017565 00000000000000/* * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2005-2013 Sourcefire, Inc. * * Author: Steven Sturges * * Dynamic Library Loading for Snort * */ #ifndef _SF_DYNAMIC_ENGINE_H_ #define _SF_DYNAMIC_ENGINE_H_ #ifndef WIN32 #include #else #include #endif #include "sf_dynamic_define.h" #include "sf_dynamic_meta.h" #include "sf_decompression_define.h" /* specifies that a function does not return * used for quieting Visual Studio warnings */ #ifdef WIN32 #if _MSC_VER >= 1400 #define NORETURN __declspec(noreturn) #else #define NORETURN #endif #else #define NORETURN #endif /* Function prototype used to evaluate a special OTN */ typedef int (*OTNCheckFunction)(void* pPacket, void* pRule); /* flowFlag is FLOW_*; check flowFlag iff non-zero */ typedef int (*OTNHasFunction)(void* pRule, DynamicOptionType, int flowFlag); /* Data struct & function prototype used to get list of * Fast Pattern Content information. */ typedef struct _FPContentInfo { char *content; int length; int offset; int depth; char noCaseFlag; char exception_flag; char is_relative; char fp; char fp_only; char uri_buffer; uint16_t fp_offset; uint16_t fp_length; struct _FPContentInfo *next; } FPContentInfo; typedef int (*GetDynamicContentsFunction)(void *, int, FPContentInfo **); typedef int (*GetDynamicPreprocOptFpContentsFunc)(void *, FPContentInfo **); typedef void (*RuleFreeFunc)(void *); /* ruleInfo is passed to OTNCheckFunction when the fast pattern matches. */ struct _SnortConfig; typedef int (*RegisterRule)( struct _SnortConfig *, uint32_t, uint32_t, void *, OTNCheckFunction, OTNHasFunction, int, GetDynamicContentsFunction, RuleFreeFunc, GetDynamicPreprocOptFpContentsFunc ); typedef void *(*RegisterBit)(void *); typedef void (*UnregisterBit)(void *); typedef int (*CheckFlowbit)(void *, void *); typedef int (*DetectAsn1)(void *, void *, const uint8_t *); typedef int (*PreprocOptionEval)(void *p, const uint8_t **cursor, void *dataPtr); typedef int (*PreprocOptionInit)(struct _SnortConfig *, char *, char *, void **dataPtr); typedef void (*PreprocOptionCleanup)(void *dataPtr); typedef int (*SfUnfold)(const uint8_t *, uint32_t , uint8_t *, uint32_t , uint32_t *); typedef int (*SfBase64Decode)(uint8_t *, uint32_t , uint8_t *, uint32_t , uint32_t *); #define PREPROC_OPT_EQUAL 0 #define PREPROC_OPT_NOT_EQUAL 1 typedef uint32_t (*PreprocOptionHash)(void *); typedef int (*PreprocOptionKeyCompare)(void *, void *); /* Function prototype for rule options that want to add patterns to the * fast pattern matcher */ typedef int (*PreprocOptionFastPatternFunc) (void *rule_opt_data, int protocol, int direction, FPContentInfo **info); typedef int (*PreprocOptionOtnHandler)(struct _SnortConfig *, void *); typedef int (*PreprocOptionByteOrderFunc)(void *, int32_t); typedef int (*RegisterPreprocRuleOpt)( struct _SnortConfig *, char *, PreprocOptionInit, PreprocOptionEval, PreprocOptionCleanup, PreprocOptionHash, PreprocOptionKeyCompare, PreprocOptionOtnHandler, PreprocOptionFastPatternFunc); typedef int (*PreprocRuleOptInit)(struct _SnortConfig *, void *); typedef void (*SessionDataFree)(void *); struct _RuleInformation; typedef int (*SetRuleData)(void *, const struct _RuleInformation *, void *, void *); typedef void (*GetRuleData)(void *, const struct _RuleInformation *, void **, void **); typedef void * (*AllocRuleData)(size_t); typedef void (*FreeRuleData)(void *); typedef void * (*DynamicDecompressInitFunc)(compression_type_t); typedef int (*DynamicDecompressDestroyFunc)(void *state); typedef int (*DynamicDecompressFunc)(void *, uint8_t *, uint32_t, uint8_t *, uint32_t, uint32_t *); /* Info Data passed to dynamic engine plugin must include: * version * Pointer to AltDecodeBuffer * Pointer to HTTP URI Buffers * Pointer to function to register C Rule * Pointer to function to register C Rule flowbits * Pointer to function to check flowbit * Pointer to function to do ASN1 Detection * Pointer to functions to log Messages, Errors, Fatal Errors * Directory path */ #include "sf_dynamic_common.h" #define ENGINE_DATA_VERSION 10 typedef void *(*PCRECompileFunc)(const char *, int, const char **, int *, const unsigned char *); typedef void *(*PCREStudyFunc)(struct _SnortConfig *, const void *, int, const char **); typedef int (*PCREExecFunc)(const void *, const void *, const char *, int, int, int, int *, int); typedef void (*PCRECapture)(struct _SnortConfig *, const void *, const void *); typedef void(*PCREOvectorInfo)(int **, int *); typedef struct _DynamicEngineData { int version; SFDataBuffer *altBuffer; SFDataPointer *altDetect; SFDataPointer *fileDataBuf; RegisterRule ruleRegister; RegisterBit flowbitRegister; CheckFlowbit flowbitCheck; DetectAsn1 asn1Detect; LogMsgFunc logMsg; LogMsgFunc errMsg; LogMsgFunc fatalMsg; char *dataDumpDirectory; PreprocRuleOptInit preprocRuleOptInit; SetRuleData setRuleData; GetRuleData getRuleData; DebugMsgFunc debugMsg; #ifdef SF_WCHAR DebugWideMsgFunc debugWideMsg; #endif char **debugMsgFile; int *debugMsgLine; PCRECompileFunc pcreCompile; PCREStudyFunc pcreStudy; PCREExecFunc pcreExec; SfUnfold sfUnfold; SfBase64Decode sfbase64decode; GetAltDetectFunc GetAltDetect; SetAltDetectFunc SetAltDetect; IsDetectFlagFunc Is_DetectFlag; DetectFlagDisableFunc DetectFlag_Disable; AllocRuleData allocRuleData; FreeRuleData freeRuleData; UnregisterBit flowbitUnregister; PCRECapture pcreCapture; PCREOvectorInfo pcreOvectorInfo; GetHttpBufferFunc getHttpBuffer; DynamicDecompressInitFunc decompressInit; DynamicDecompressDestroyFunc decompressDestroy; DynamicDecompressFunc decompress; } DynamicEngineData; extern DynamicEngineData _ded; /* Function prototypes for Dynamic Engine Plugins */ void CloseDynamicEngineLibs(void); void LoadAllDynamicEngineLibs(struct _SnortConfig *sc, const char * const path); int LoadDynamicEngineLib(struct _SnortConfig *sc, const char * const library_name, int indent); typedef int (*InitEngineLibFunc)(DynamicEngineData *); typedef int (*CompatibilityFunc)(DynamicPluginMeta *meta, DynamicPluginMeta *lib); int InitDynamicEngines(char *); void RemoveDuplicateEngines(void); int DumpDetectionLibRules(struct _SnortConfig *sc); int ValidateDynamicEngines(struct _SnortConfig *sc); /* This was necessary because of static code analysis not recognizing that * fatalMsg did not return - use instead of fatalMsg */ NORETURN void DynamicEngineFatalMessage(const char *format, ...); typedef struct _PreprocessorOptionInfo { PreprocOptionInit optionInit; PreprocOptionEval optionEval; PreprocOptionCleanup optionCleanup; void *data; PreprocOptionHash optionHash; PreprocOptionKeyCompare optionKeyCompare; PreprocOptionOtnHandler otnHandler; PreprocOptionFastPatternFunc optionFpFunc; } PreprocessorOptionInfo; #endif /* _SF_DYNAMIC_ENGINE_H_ */ snort-2.9.15.1/src/dynamic-plugins/sf_dynamic_define.h0000644000175200017520000000745113571422607017550 00000000000000/* * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2007-2013 Sourcefire, Inc. * * Author: Russ Combs * * #defines required by the dynamic engine. These were factored out of * sf_snort_plugin_api.h because they are required by fpcreate.c. They * could have been placed in sf_dynamic_engine.h but that would have * caused all the sf_engine/examples/ *.c to depend on that file. */ #ifndef _SF_DYNAMIC_DEFINE_H_ #define _SF_DYNAMIC_DEFINE_H_ /* the OPTION_TYPE_* and FLOW_* values * are used as args to the hasFunc() * which replaces the prior has*Func()s. * * Try to add values to the end (just before OPTION_TYPE_MAX). Also, look * at OptionConverterArray in sf_convert_dynamic.c to make sure types align. */ typedef enum { OPTION_TYPE_PREPROCESSOR, OPTION_TYPE_CONTENT, OPTION_TYPE_PROTECTED_CONTENT, OPTION_TYPE_PCRE, OPTION_TYPE_FLOWBIT, OPTION_TYPE_FLOWFLAGS, OPTION_TYPE_ASN1, OPTION_TYPE_CURSOR, OPTION_TYPE_HDR_CHECK, OPTION_TYPE_BYTE_TEST, OPTION_TYPE_BYTE_JUMP, OPTION_TYPE_BYTE_EXTRACT, OPTION_TYPE_SET_CURSOR, OPTION_TYPE_LOOP, OPTION_TYPE_FILE_DATA, OPTION_TYPE_PKT_DATA, OPTION_TYPE_BASE64_DATA, OPTION_TYPE_BASE64_DECODE, OPTION_TYPE_BYTE_MATH, OPTION_TYPE_MAX } DynamicOptionType; /* beware: these are redefined from sf_snort_packet.h FLAG_*! */ #define FLOW_ESTABLISHED 0x0008 #define FLOW_FR_SERVER 0x0040 #define FLOW_TO_CLIENT 0x0040 /* Just for convenience */ #define FLOW_TO_SERVER 0x0080 #define FLOW_FR_CLIENT 0x0080 /* Just for convenience */ #define FLOW_IGNORE_REASSEMBLED 0x1000 #define FLOW_ONLY_REASSEMBLED 0x2000 #define FLOW_ONLY_REASSMBLED FLOW_ONLY_REASSEMBLED #define SNORT_PCRE_OVERRIDE_MATCH_LIMIT 0x8000000 #ifndef SF_SO_PUBLIC #if defined _WIN32 || defined __CYGWIN__ # if defined SF_SNORT_ENGINE_DLL || defined SF_SNORT_DETECTION_DLL || \ defined SF_SNORT_PREPROC_DLL # ifdef __GNUC__ # define SF_SO_PUBLIC __attribute__((dllexport)) # else # define SF_SO_PUBLIC __declspec(dllexport) # endif # else # ifdef __GNUC__ # define SF_SO_PUBLIC __attribute__((dllimport)) # else # define SF_SO_PUBLIC __declspec(dllimport) # endif # endif # define DLL_LOCAL #else # ifdef SF_VISIBILITY # define SF_SO_PUBLIC __attribute__ ((visibility("default"))) # define SF_SO_PRIVATE __attribute__ ((visibility("hidden"))) # else # define SF_SO_PUBLIC # define SF_SO_PRIVATE # endif #endif #endif /* Parameters are rule info pointer, int to indicate URI or NORM, * and list pointer */ /* low nibble must be HTTP_BUFFER_* (see sf_dynamic_common.h) */ /* FIXTHIS eliminate these redefines */ #define CONTENT_HTTP_URI 0x00000001 #define CONTENT_HTTP_HEADER 0x00000002 #define CONTENT_HTTP_CLIENT_BODY 0x00000003 #define CONTENT_HTTP_METHOD 0x00000004 #define CONTENT_NORMAL 0x00010000 #define CONTENT_HTTP 0x00000007 #endif /* _SF_DYNAMIC_DEFINE_H_ */ snort-2.9.15.1/src/dynamic-plugins/sf_dynamic_meta.h0000644000175200017520000000335013571422607017236 00000000000000/* * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2005-2013 Sourcefire, Inc. * * Author: Steven Sturges * * Dynamic Library Loading for Snort * */ #ifndef _SF_DYNAMIC_META_H_ #define _SF_DYNAMIC_META_H_ /* Required version and name of the engine */ #ifndef REQ_ENGINE_LIB_MAJOR #define REQ_ENGINE_LIB_MAJOR 3 #endif #ifndef REQ_ENGINE_LIB_MINOR /* FIXTHIS need to update dynamic-plugins/sf_engine/examples/sfsnort_dynamic_detection_lib.c */ #define REQ_ENGINE_LIB_MINOR 1 #endif #define REQ_ENGINE_LIB_NAME "SF_SNORT_DETECTION_ENGINE" #define MAX_NAME_LEN 1024 #define TYPE_ENGINE 0x01 #define TYPE_DETECTION 0x02 #define TYPE_PREPROCESSOR 0x04 #define TYPE_SIDE_CHANNEL 0x08 typedef struct _DynamicPluginMeta { int type; int major; int minor; int build; char uniqueName[MAX_NAME_LEN]; char *libraryPath; } DynamicPluginMeta; typedef int (*LibVersionFunc)(DynamicPluginMeta *); #endif /* _SF_DYNAMIC_META_H_ */ snort-2.9.15.1/src/dynamic-plugins/sf_dynamic_plugins.c0000644000175200017520000030464013571422607017772 00000000000000/* $Id: */ /* * sf_dynamic_plugins.c * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2005-2013 Sourcefire, Inc. * * Author: Steven Sturges * * Dynamic Library Loading for Snort * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifndef WIN32 #include #include #include #include #include #include #include #include #if defined(HPUX) #define MODULE_EXT "*.sl" #else #define MODULE_EXT "*.so*" #endif typedef void * PluginHandle; #else /* !WIN32 */ #include #define MODULE_EXT "dll" typedef HANDLE PluginHandle; /* Of course, WIN32 couldn't do things the unix way... * Define a few of these to get around portability issues. */ #define getcwd _getcwd #ifndef PATH_MAX #define PATH_MAX MAX_PATH #endif #endif /* !WIN32 */ #include #if defined(FEAT_OPEN_APPID) #include #endif #include "config.h" #include "decode.h" #include "encode.h" #include "snort_debug.h" #include "detect.h" #include "util.h" #include "snort.h" #include "memory_stats.h" #include "sf_dynamic_engine.h" #include "sf_dynamic_detection.h" #include "sf_dynamic_preprocessor.h" #include "sf_dynamic_decompression.h" #include "sp_dynamic.h" #include "sp_preprocopt.h" #include "sp_pcre.h" #include "util.h" #include "event_queue.h" #include "plugbase.h" #include "sfthreshold.h" #include "active.h" #include "mstring.h" #include "sfsnprintfappend.h" #include "session_api.h" #include "stream_api.h" #include "sf_iph.h" #include "fpdetect.h" #include "sfportobject.h" #include #include "parser.h" #include "event_wrapper.h" #include "util.h" #include "detection_util.h" #include "sfcontrol_funcs.h" #include "idle_processing_funcs.h" #include "../dynamic-output/plugins/output.h" #include "file_api.h" #include "packet_time.h" #include "perf_indicators.h" #include "reload.h" #include "so_rule_mem_adjust.h" #ifdef SNORT_RELOAD #include "appdata_adjuster.h" #endif #if defined(FEAT_OPEN_APPID) #include "appIdApi.h" #endif /* defined(FEAT_OPEN_APPID) */ #ifdef TARGET_BASED #include "target-based/sftarget_protocol_reference.h" #include "target-based/sftarget_reader.h" #endif #ifdef SIDE_CHANNEL #include "sidechannel.h" #include "sf_dynamic_side_channel.h" #endif #ifndef DEBUG_MSGS char *no_file = "unknown"; int no_line = 0; #endif #ifdef SNORT_RELOAD static APPDATA_ADJUSTER *ada; #endif /* Predeclare this */ void VerifySharedLibUniqueness(); typedef int (*LoadLibraryFunc)(SnortConfig *sc, const char * const path, int indent); typedef struct _DynamicEnginePlugin { PluginHandle handle; DynamicPluginMeta metaData; InitEngineLibFunc initFunc; CompatibilityFunc versCheck; struct _DynamicEnginePlugin *next; struct _DynamicEnginePlugin *prev; } DynamicEnginePlugin; static DynamicEnginePlugin *loadedEngines = NULL; typedef struct _DynamicPreprocessorPlugin { PluginHandle handle; DynamicPluginMeta metaData; InitPreprocessorLibFunc initFunc; struct _DynamicPreprocessorPlugin *next; struct _DynamicPreprocessorPlugin *prev; } DynamicPreprocessorPlugin; static DynamicPreprocessorPlugin *loadedPreprocessorPlugins = NULL; typedef struct _LoadableModule { char *prefix; char *name; struct _LoadableModule *next; } LoadableModule; void CloseDynamicLibrary(PluginHandle handle) { #ifndef WIN32 # ifndef DISABLE_DLCLOSE_FOR_VALGRIND_TESTING dlclose(handle); # endif #else FreeLibrary(handle); #endif } #define NONFATAL 0 #define FATAL 1 typedef void (*dlsym_func)(void); static dlsym_func getSymbol( PluginHandle handle, char *symbol, DynamicPluginMeta *meta, int fatal) { dlsym_func symbolPtr = NULL; if (!handle) return symbolPtr; #ifndef WIN32 symbolPtr = (dlsym_func)dlsym(handle, symbol); #else symbolPtr = (dlsym_func)GetProcAddress(handle, symbol); #endif if (!symbolPtr) { if (fatal) { #ifndef WIN32 FatalError("Failed to find %s() function in %s: %s\n", symbol, meta->libraryPath, dlerror()); #else FatalError("Failed to find %s() function in %s: %d\n", symbol, meta->libraryPath, GetLastError()); #endif } else { #ifndef WIN32 ErrorMessage("Failed to find %s() function in %s: %s\n", symbol, meta->libraryPath, dlerror()); #else ErrorMessage("Failed to find %s() function in %s: %d\n", symbol, meta->libraryPath, GetLastError()); #endif } } return symbolPtr; } void GetPluginVersion(PluginHandle handle, DynamicPluginMeta* meta) { LibVersionFunc libVersionFunc = NULL; libVersionFunc = (LibVersionFunc)getSymbol(handle, "LibVersion", meta, FATAL); if (libVersionFunc != NULL) { libVersionFunc(meta); } } PluginHandle openDynamicLibrary(const char * const library_name, int useGlobal) { PluginHandle handle; #ifndef WIN32 handle = dlopen(library_name, RTLD_NOW | (useGlobal ? RTLD_GLOBAL : RTLD_LOCAL)); #else handle = LoadLibrary(library_name); #endif if (handle == NULL) { #ifndef WIN32 FatalError("Failed to load %s: %s\n", library_name, dlerror()); #else FatalError("Failed to load %s: %d\n", library_name, GetLastError()); #endif } return handle; } void LoadAllLibs(struct _SnortConfig *sc, const char * const path, LoadLibraryFunc loadFunc) { #ifndef WIN32 char path_buf[PATH_MAX]; struct dirent *dir_entry; DIR *directory; int count = 0; LoadableModule *modules = NULL; directory = opendir(path); if (directory != NULL) { dir_entry = readdir(directory); while (dir_entry != NULL) { if (fnmatch(MODULE_EXT, dir_entry->d_name, FNM_PATHNAME | FNM_PERIOD) == 0) { /* Get the string up until the first dot. This will be * considered the file prefix. */ char *dot = strchr(dir_entry->d_name, '.'); if (dot != NULL) { size_t len = (size_t)(dot - dir_entry->d_name); // len >= 0 LoadableModule *tmp = modules; LoadableModule *prev = NULL; while (tmp != NULL) { /* Make sure the prefix lengths are the same */ if (strlen(tmp->prefix) == len) { /* And make sure they are the same string */ if (strncmp(tmp->prefix, dir_entry->d_name, len) == 0) { /* Take the shorter, since the longer probably * has version information and the shorter ones * are generally links to the most recent * version, e.g. * libsf_engine.so.0.0.0 * libsf_engine.so.0 -> libsf_engine.so.0.0.0 * libsf_engine.so -> libsf_engine.so.0.0.0 * Mac seems to do * libsf_engine.0.so * libsf_engine.0.0.0.so -> libsf_engine.0.so * libsf_engine.so -> libsf_engine.0.so * We don't want to load the same same thing * more than once. */ if (strlen(dir_entry->d_name) < strlen(tmp->name)) { /* There will be enough space since at * least the longer of the two will have * been allocated */ strcpy(tmp->name, dir_entry->d_name); } break; } } prev = tmp; tmp = tmp->next; } if (tmp == NULL) { tmp = SnortAlloc(sizeof(LoadableModule)); /* include NULL byte */ tmp->prefix = SnortAlloc(len + 1); /* will be NULL terminated because SnortAlloc uses calloc */ strncpy(tmp->prefix, dir_entry->d_name, len); /* include NULL byte */ tmp->name = SnortAlloc(strlen(dir_entry->d_name) + 1); /* will be NULL terminated because SnortAlloc uses calloc */ strncpy(tmp->name, dir_entry->d_name, strlen(dir_entry->d_name)); tmp->next = NULL; if (modules == NULL) modules = tmp; else if (prev != NULL) prev->next = tmp; } } } dir_entry = readdir(directory); } closedir(directory); while (modules != NULL) { LoadableModule *tmp = modules; SnortSnprintf(path_buf, PATH_MAX, "%s%s%s", path, "/", modules->name); loadFunc(sc, path_buf, 1); count++; modules = modules->next; /* These will all have been allocated together */ free(tmp->prefix); free(tmp->name); free(tmp); } if ( count == 0 ) { LogMessage("WARNING: No dynamic libraries found in directory %s.\n", path); } } else { LogMessage("WARNING: Directory %s does not exist.\n", path); } #else /* Find all shared library files in path */ char path_buf[PATH_MAX]; char dyn_lib_name[PATH_MAX]; char drive[_MAX_DRIVE]; char dir[_MAX_DIR]; char fname[_MAX_FNAME]; char ext[_MAX_EXT]; HANDLE fSearch; WIN32_FIND_DATA FindFileData; int pathLen = 0; const char *directory; int useDrive = 0; if (SnortStrncpy(path_buf, path, PATH_MAX) != SNORT_STRNCPY_SUCCESS) FatalError("Path is too long: %s\n", path); pathLen = SnortStrnlen(path_buf, PATH_MAX); if ((path_buf[pathLen - 1] == '\\') || (path_buf[pathLen - 1] == '/')) { /* A directory was specified with trailing dir character */ _splitpath(path_buf, drive, dir, fname, ext); _makepath(path_buf, drive, dir, "*", MODULE_EXT); directory = &dir[0]; useDrive = 1; } else /* A directory was specified */ { _splitpath(path_buf, drive, dir, fname, ext); if (strcmp(ext, "")) { FatalError("Improperly formatted directory name: %s\n", path); } _makepath(path_buf, "", path_buf, "*", MODULE_EXT); directory = path; } fSearch = FindFirstFile(path_buf, &FindFileData); while (fSearch != NULL && fSearch != (HANDLE)-1) { if (useDrive) _makepath(dyn_lib_name, drive, directory, FindFileData.cFileName, NULL); else _makepath(dyn_lib_name, NULL, directory, FindFileData.cFileName, NULL); loadFunc(dyn_lib_name, 1); if (!FindNextFile(fSearch, &FindFileData)) { break; } } FindClose(fSearch); #endif } void AddEnginePlugin(PluginHandle handle, InitEngineLibFunc initFunc, CompatibilityFunc compatFunc, DynamicPluginMeta *meta) { DynamicEnginePlugin *newPlugin; newPlugin = (DynamicEnginePlugin *)SnortAlloc(sizeof(DynamicEnginePlugin)); newPlugin->handle = handle; if (!loadedEngines) { loadedEngines = newPlugin; } else { newPlugin->next = loadedEngines; loadedEngines->prev = newPlugin; loadedEngines = newPlugin; } memcpy(&(newPlugin->metaData), meta, sizeof(DynamicPluginMeta)); newPlugin->metaData.libraryPath = SnortStrdup(meta->libraryPath); newPlugin->initFunc = initFunc; newPlugin->versCheck = compatFunc; } void RemoveEnginePlugin(DynamicEnginePlugin *plugin) { if (!plugin) return; if (plugin == loadedEngines) { loadedEngines = loadedEngines->next; loadedEngines->prev = NULL; } else { if (plugin->prev) plugin->prev->next = plugin->next; if (plugin->next) plugin->next->prev = plugin->prev; } CloseDynamicLibrary(plugin->handle); if (plugin->metaData.libraryPath != NULL) free(plugin->metaData.libraryPath); free(plugin); } int ValidateDynamicEngines(SnortConfig *sc) { int testNum = 0; DynamicEnginePlugin *curPlugin = loadedEngines; CompatibilityFunc versFunc = NULL; while( curPlugin != NULL) { versFunc = (CompatibilityFunc)curPlugin->versCheck; /* if compatibility checking func is absent, skip validating */ if( versFunc != NULL) { DynamicDetectionPlugin *lib = sc->loadedDetectionPlugins; while( lib != NULL) { if (lib->metaData.type == TYPE_DETECTION) { RequiredEngineLibFunc engineFunc; DynamicPluginMeta reqEngineMeta; engineFunc = (RequiredEngineLibFunc) getSymbol(lib->handle, "EngineVersion", &(lib->metaData), 1); if( engineFunc != NULL) { engineFunc(&reqEngineMeta); } testNum = versFunc(&curPlugin->metaData, &reqEngineMeta); if( testNum ) { FatalError("The dynamic detection library \"%s\" version " "%d.%d compiled with dynamic engine library " "version %d.%d isn't compatible with the current " "dynamic engine library \"%s\" version %d.%d.\n", lib->metaData.libraryPath, lib->metaData.major, lib->metaData.minor, reqEngineMeta.major, reqEngineMeta.minor, curPlugin->metaData.libraryPath, curPlugin->metaData.major, curPlugin->metaData.minor); } } lib = lib->next; } } if( testNum ) break; curPlugin = curPlugin->next; } return(testNum); } int LoadDynamicEngineLib(SnortConfig *sc, const char * const library_name, int indent) { /* Presume here, that library name is full path */ InitEngineLibFunc engineInit; CompatibilityFunc compatFunc; DynamicPluginMeta metaData; PluginHandle handle; #if 0 LogMessage("%sDynamic engine will not be loaded since dynamic detection " "libraries are not yet supported with IPv6.\n", indent?" ":""); return 0; #endif LogMessage("%sLoading dynamic engine %s... ", indent ? " " : "", library_name); handle = openDynamicLibrary(library_name, 1); metaData.libraryPath = (char *) library_name; GetPluginVersion(handle, &metaData); /* Just to ensure that the function exists */ engineInit = (InitEngineLibFunc)getSymbol(handle, "InitializeEngine", &metaData, FATAL); compatFunc = (CompatibilityFunc)getSymbol(handle, "CheckCompatibility", &metaData, NONFATAL); if (metaData.type != TYPE_ENGINE) { CloseDynamicLibrary(handle); LogMessage("failed, not an Engine\n"); return 0; } AddEnginePlugin(handle, engineInit, compatFunc, &metaData); LogMessage("done\n"); return 0; } void LoadAllDynamicEngineLibs(SnortConfig *sc, const char * const path) { LogMessage("Loading all dynamic engine libs from %s...\n", path); LoadAllLibs(sc, path, LoadDynamicEngineLib); LogMessage(" Finished Loading all dynamic engine libs from %s\n", path); } void CloseDynamicEngineLibs(void) { DynamicEnginePlugin *tmpplugin, *plugin = loadedEngines; while (plugin) { tmpplugin = plugin->next; //if (!(plugin->metaData.type & TYPE_DETECTION)) //{ CloseDynamicLibrary(plugin->handle); free(plugin->metaData.libraryPath); free(plugin); //} //else //{ // HUH? // /* NOP, handle will be closed when we close the DetectionLib */ // ; //} plugin = tmpplugin; } loadedEngines = NULL; #ifdef SNORT_RELOAD ada_delete(ada); ada = NULL; #endif } void RemovePreprocessorPlugin(DynamicPreprocessorPlugin *plugin) { if (!plugin) return; if (plugin == loadedPreprocessorPlugins) { loadedPreprocessorPlugins = loadedPreprocessorPlugins->next; loadedPreprocessorPlugins->prev = NULL; } else { if (plugin->prev) plugin->prev->next = plugin->next; if (plugin->next) plugin->next->prev = plugin->prev; } CloseDynamicLibrary(plugin->handle); if (plugin->metaData.libraryPath != NULL) free(plugin->metaData.libraryPath); free(plugin); } void AddPreprocessorPlugin(PluginHandle handle, InitPreprocessorLibFunc initFunc, DynamicPluginMeta *meta) { DynamicPreprocessorPlugin *newPlugin = NULL; newPlugin = (DynamicPreprocessorPlugin *)SnortAlloc(sizeof(DynamicPreprocessorPlugin)); newPlugin->handle = handle; if (!loadedPreprocessorPlugins) { loadedPreprocessorPlugins = newPlugin; } else { newPlugin->next = loadedPreprocessorPlugins; loadedPreprocessorPlugins->prev = newPlugin; loadedPreprocessorPlugins = newPlugin; } memcpy(&(newPlugin->metaData), meta, sizeof(DynamicPluginMeta)); newPlugin->metaData.libraryPath = SnortStrdup(meta->libraryPath); newPlugin->initFunc = initFunc; } void AddDetectionPlugin(SnortConfig *sc, PluginHandle handle, InitDetectionLibFunc initFunc, DynamicPluginMeta *meta) { DynamicDetectionPlugin *newPlugin = NULL; newPlugin = (DynamicDetectionPlugin *)SnortAlloc(sizeof(DynamicDetectionPlugin)); newPlugin->handle = handle; if (!sc->loadedDetectionPlugins) { sc->loadedDetectionPlugins = newPlugin; } else { newPlugin->next = sc->loadedDetectionPlugins; sc->loadedDetectionPlugins->prev = newPlugin; sc->loadedDetectionPlugins = newPlugin; } memcpy(&(newPlugin->metaData), meta, sizeof(DynamicPluginMeta)); newPlugin->metaData.libraryPath = SnortStrdup(meta->libraryPath); newPlugin->initFunc = initFunc; } void RemoveDetectionPlugin(SnortConfig *sc, DynamicDetectionPlugin *plugin) { if (!plugin) return; if (plugin == sc->loadedDetectionPlugins) { sc->loadedDetectionPlugins = sc->loadedDetectionPlugins->next; sc->loadedDetectionPlugins->prev = NULL; } else { if (plugin->prev) plugin->prev->next = plugin->next; if (plugin->next) plugin->next->prev = plugin->prev; } LogMessage("Unloading dynamic detection library %s version %d.%d.%d\n", plugin->metaData.uniqueName, plugin->metaData.major, plugin->metaData.minor, plugin->metaData.build); CloseDynamicLibrary(plugin->handle); if (plugin->metaData.libraryPath != NULL) free(plugin->metaData.libraryPath); free(plugin); } int LoadDynamicDetectionLib(SnortConfig *sc, const char * const library_name, int indent) { DynamicPluginMeta metaData; /* Presume here, that library name is full path */ InitDetectionLibFunc detectionInit; PluginHandle handle; #if 0 LogMessage("%sDynamic detection library \"%s\" will not be loaded. Not " "supported with IPv6.\n", indent ? " " : "", library_name); return 0; #endif LogMessage("%sLoading dynamic detection library %s... ", indent ? " " : "", library_name); handle = openDynamicLibrary(library_name, 0); metaData.libraryPath = (char *) library_name; GetPluginVersion(handle, &metaData); /* Just to ensure that the function exists */ detectionInit = (InitDetectionLibFunc)getSymbol(handle, "InitializeDetection", &metaData, FATAL); if (!(metaData.type & TYPE_DETECTION)) { CloseDynamicLibrary(handle); LogMessage("failed, not a detection library\n"); return 0; } if (metaData.type & TYPE_ENGINE) { /* Do the engine initialization as well */ InitEngineLibFunc engineInit = (InitEngineLibFunc)getSymbol(handle, "InitializeEngine", &metaData, FATAL); CompatibilityFunc compatFunc = (CompatibilityFunc)getSymbol(handle, "CheckCompatibility", &metaData, NONFATAL); AddEnginePlugin(handle, engineInit, compatFunc, &metaData); } AddDetectionPlugin(sc, handle, detectionInit, &metaData); LogMessage("done\n"); return 0; } void CloseDynamicDetectionLibs(SnortConfig *sc) { DynamicDetectionPlugin *tmpplugin, *plugin = sc->loadedDetectionPlugins; while (plugin) { tmpplugin = plugin->next; #ifndef SNORT_RELOAD CloseDynamicLibrary(plugin->handle); #else /* * Even if DISABLE_DLCLOSE_FOR_VALGRIND_TESTING is set * we have to do dlclose() for Dynamic detection libs * during reloading. */ #ifndef WIN32 dlclose(plugin->handle); #else FreeLibrary(plugin->handle); #endif #endif free(plugin->metaData.libraryPath); free(plugin); plugin = tmpplugin; } sc->loadedDetectionPlugins = NULL; } void LoadAllDynamicDetectionLibs(SnortConfig *sc, const char * const path) { LogMessage("Loading all dynamic detection libs from %s...\n", path); LoadAllLibs(sc, path, LoadDynamicDetectionLib); LogMessage(" Finished Loading all dynamic detection libs from %s\n", path); } void RemoveDuplicateEngines(void) { int removed = 0; DynamicEnginePlugin *engine1; DynamicEnginePlugin *engine2; DynamicPluginMeta *meta1; DynamicPluginMeta *meta2; /* First the Detection Engines */ do { removed = 0; engine1 = loadedEngines; while (engine1 != NULL) { engine2 = loadedEngines; while (engine2 != NULL) { /* Obviously, the same ones will be the same */ if (engine1 != engine2) { meta1 = &engine1->metaData; meta2 = &engine2->metaData; if (!strcmp(meta1->uniqueName, meta2->uniqueName)) { /* Uh, same uniqueName. */ if ((meta1->major > meta2->major) || ((meta1->major == meta2->major) && (meta1->minor > meta2->minor)) || ((meta1->major == meta2->major) && (meta1->minor == meta2->minor) && (meta1->build > meta2->build)) ) { /* Lib1 is newer */ RemoveEnginePlugin(engine2); removed = 1; } else if ((meta2->major > meta1->major) || ((meta2->major == meta1->major) && (meta2->minor > meta1->minor)) || ((meta2->major == meta1->major) && (meta2->minor == meta1->minor) && (meta2->build > meta1->build)) ) { /* Lib2 is newer */ RemoveEnginePlugin(engine1); removed = 1; } else if ((meta1->major == meta2->major) && (meta1->minor == meta2->minor) && (meta1->build == meta2->build) ) { /* Duplicate */ RemoveEnginePlugin(engine2); removed = 1; } } } /* If we removed anything, start back at the beginning */ if (removed) break; engine2 = engine2->next; } /* If we removed anything, start back at the beginning */ if (removed) break; engine1 = engine1->next; } } while (removed); } void RemoveDuplicateDetectionPlugins(SnortConfig *sc) { int removed = 0; DynamicDetectionPlugin *lib1 = NULL; DynamicDetectionPlugin *lib2 = NULL; DynamicPluginMeta *meta1; DynamicPluginMeta *meta2; /* Detection Plugins */ do { removed = 0; lib1 = sc->loadedDetectionPlugins; while (lib1 != NULL) { lib2 = sc->loadedDetectionPlugins; while (lib2 != NULL) { /* Obviously, the same ones will be the same */ if (lib1 != lib2) { meta1 = &lib1->metaData; meta2 = &lib2->metaData; if (!strcmp(meta1->uniqueName, meta2->uniqueName)) { /* Uh, same uniqueName. */ if ((meta1->major > meta2->major) || ((meta1->major == meta2->major) && (meta1->minor > meta2->minor)) || ((meta1->major == meta2->major) && (meta1->minor == meta2->minor) && (meta1->build > meta2->build)) ) { /* Lib1 is newer */ RemoveDetectionPlugin(sc, lib2); removed = 1; } else if ((meta2->major > meta1->major) || ((meta2->major == meta1->major) && (meta2->minor > meta1->minor)) || ((meta2->major == meta1->major) && (meta2->minor == meta1->minor) && (meta2->build > meta1->build)) ) { /* Lib2 is newer */ RemoveDetectionPlugin(sc, lib1); removed = 1; } else if ((meta1->major == meta2->major) && (meta1->minor == meta2->minor) && (meta1->build == meta2->build) ) { /* Duplicate */ RemoveDetectionPlugin(sc, lib2); removed = 1; } } } /* If we removed anything, start back at the beginning */ if (removed) break; lib2 = lib2->next; } /* If we removed anything, start back at the beginning */ if (removed) break; lib1 = lib1->next; } } while (removed); } void RemoveDuplicatePreprocessorPlugins(void) { int removed = 0; DynamicPreprocessorPlugin *pp1 = NULL; DynamicPreprocessorPlugin *pp2 = NULL; DynamicPluginMeta *meta1; DynamicPluginMeta *meta2; /* The Preprocessor Plugins */ do { removed = 0; pp1 = loadedPreprocessorPlugins; while (pp1 != NULL) { pp2 = loadedPreprocessorPlugins; while (pp2 != NULL) { /* Obviously, the same ones will be the same */ if (pp1 != pp2) { meta1 = &pp1->metaData; meta2 = &pp2->metaData; if (!strcmp(meta1->uniqueName, meta2->uniqueName)) { /* Uh, same uniqueName. */ if ((meta1->major > meta2->major) || ((meta1->major == meta2->major) && (meta1->minor > meta2->minor)) || ((meta1->major == meta2->major) && (meta1->minor == meta2->minor) && (meta1->build > meta2->build)) ) { /* Lib1 is newer */ RemovePreprocessorPlugin(pp2); removed = 1; } else if ((meta2->major > meta1->major) || ((meta2->major == meta1->major) && (meta2->minor > meta1->minor)) || ((meta2->major == meta1->major) && (meta2->minor == meta1->minor) && (meta2->build > meta1->build)) ) { /* Lib2 is newer */ RemovePreprocessorPlugin(pp1); removed = 1; } else if ((meta1->major == meta2->major) && (meta1->minor == meta2->minor) && (meta1->build == meta2->build) ) { /* Duplicate */ RemovePreprocessorPlugin(pp2); removed = 1; } } } /* If we removed anything, start back at the beginning */ if (removed) break; pp2 = pp2->next; } /* If we removed anything, start back at the beginning */ if (removed) break; pp1 = pp1->next; } } while (removed); } void VerifyDetectionPluginRequirements(SnortConfig *sc) { DynamicDetectionPlugin *lib1 = NULL; /* Remove all the duplicates */ RemoveDuplicateDetectionPlugins(sc); /* Cycle through all of them, and ensure that the required * detection engine is loaded. */ lib1 = sc->loadedDetectionPlugins; while (lib1 != NULL) { /* Do this check if this library is a DETECTION plugin only. * If it also has an internal engine, we're fine. */ if (lib1->metaData.type == TYPE_DETECTION) { RequiredEngineLibFunc engineFunc; DynamicPluginMeta reqEngineMeta; DynamicEnginePlugin *plugin = loadedEngines; int detectionLibOkay = 0; engineFunc = (RequiredEngineLibFunc) getSymbol(lib1->handle, "EngineVersion", &(lib1->metaData), FATAL); engineFunc(&reqEngineMeta); while (plugin != NULL) { /* Exact match. Yes! */ if (!strcmp(plugin->metaData.uniqueName, reqEngineMeta.uniqueName) && plugin->metaData.major == reqEngineMeta.major && plugin->metaData.minor == reqEngineMeta.minor) { detectionLibOkay = 1; break; } /* Major match, minor must be >= */ if (!strcmp(plugin->metaData.uniqueName, reqEngineMeta.uniqueName) && plugin->metaData.major == reqEngineMeta.major && plugin->metaData.minor >= reqEngineMeta.minor) { detectionLibOkay = 1; break; } /* Major must be >= -- this assumes newer engine is * bass-ackwards compatabile */ if (!strcmp(plugin->metaData.uniqueName, reqEngineMeta.uniqueName) && plugin->metaData.major > reqEngineMeta.major) { detectionLibOkay = 1; break; } plugin = plugin->next; } if (!detectionLibOkay) { FatalError("Loaded dynamic detection plugin %s (version %d:%d:%d) " "could not find required engine plugin %s(version %d:%d)\n", lib1->metaData.uniqueName, lib1->metaData.major, lib1->metaData.minor, lib1->metaData.build, reqEngineMeta.uniqueName, reqEngineMeta.major, reqEngineMeta.minor); } } lib1 = lib1->next; } } int InitDynamicEnginePlugins(DynamicEngineData *info) { DynamicEnginePlugin *plugin; RemoveDuplicateEngines(); plugin = loadedEngines; while (plugin) { if (plugin->initFunc(info)) { FatalError("Failed to initialize dynamic engine: %s version %d.%d.%d\n", plugin->metaData.uniqueName, plugin->metaData.major, plugin->metaData.minor, plugin->metaData.build); //return -1; } plugin = plugin->next; } return 0; } typedef struct _DynamicRuleSessionData { uint32_t sid; uint32_t revision; void *data; void *compression_data; struct _DynamicRuleSessionData *next; } DynamicRuleSessionData; static uint32_t so_rule_memory = 0; static size_t SoRuleMemInUse() { return (size_t) so_rule_memory; } /*Only only message will be logged within 60 seconds*/ static ThrottleInfo error_throttleInfo = {0,60,0}; static void * DynamicRuleDataAlloc(size_t size) { size_t alloc_size = size + sizeof(size_t); size_t *ret; if ((ScSoRuleMemcap() > 0) && (so_rule_memory + alloc_size) > ScSoRuleMemcap()) { ErrorMessageThrottled(&error_throttleInfo,"SO rule memcap exceeded: Wanted to allocate " "%u bytes (and %d overhead) with memcap: %u and " "current memory: %u\n", (uint32_t)size, (int)sizeof(size_t), ScSoRuleMemcap(), so_rule_memory); return NULL; } ret = (size_t *)SnortAlloc(alloc_size); ret[0] = alloc_size; so_rule_memory += alloc_size; return (void *)&ret[1]; } static void DynamicRuleDataFree(void *data) { if (data != NULL) { size_t *alloc_data = (size_t *)data - 1; size_t size = alloc_data[0]; /* Just in case of an an imbalance of DynamicRuleDataAlloc * and this function are used */ if (size >= so_rule_memory) so_rule_memory = 0; else so_rule_memory -= size; free(alloc_data); } } static void DynamicRuleDataFreeSession(void *data) { DynamicRuleSessionData *drsd = (DynamicRuleSessionData *)data; while (drsd != NULL) { DynamicRuleSessionData *tmp = drsd; drsd = drsd->next; DynamicRuleDataFree(tmp->data); DynamicRuleDataFree(tmp); #ifdef SNORT_RELOAD ada_appdata_freed(ada, tmp); #endif } } int DynamicSetRuleData(void *p, const RuleInformation *info, void *data, void *compression_data) { Packet *pkt = (Packet *)p; if (stream_api && pkt && pkt->ssnptr) { DynamicRuleSessionData *head = (DynamicRuleSessionData *)session_api->get_application_data(pkt->ssnptr, PP_SHARED_RULES); DynamicRuleSessionData *tmp = head; DynamicRuleSessionData *tail = NULL; /* Can't reset head without setting application data again which * will free what's there already, so have to iterate to end of list * Also need to iterate for duplicates */ while (tmp != NULL) { if (tmp->sid == info->sigID) { /* Not the same data */ if (tmp->data != data) { /* Cleanup the old and replace with the new */ DynamicRuleDataFree(tmp->data); tmp->data = data; } /* Not the same data */ if (tmp->compression_data && tmp->compression_data != compression_data) { /* Cleanup the old */ DynamicDecompressDestroy(tmp->compression_data); } tmp->compression_data = compression_data; tmp->revision = info->revision; return 0; } tail = tmp; tmp = tmp->next; } tmp = (DynamicRuleSessionData *)DynamicRuleDataAlloc(sizeof(DynamicRuleSessionData)); if (tmp == NULL) return -1; tmp->data = data; tmp->sid = info->sigID; tmp->revision = info->revision; if (head == NULL) { if (session_api->set_application_data(pkt->ssnptr, PP_SHARED_RULES, (void *)tmp, DynamicRuleDataFreeSession) != 0) { DynamicRuleDataFree(tmp); return -1; } #ifdef SNORT_RELOAD ada_add( ada, (void *)tmp, pkt->ssnptr ); #endif } else { tail->next = tmp; } return 0; } return -1; } void DynamicGetRuleData(void *p, const RuleInformation *info, void **p_data, void **p_compression_data) { Packet *pkt = (Packet *)p; void *compression_data; if (!p_compression_data) p_compression_data = &compression_data; *p_data = NULL; *p_compression_data = NULL; if (stream_api && pkt && pkt->ssnptr) { DynamicRuleSessionData *head = (DynamicRuleSessionData *)session_api->get_application_data(pkt->ssnptr, PP_SHARED_RULES); while (head != NULL) { if (head->sid == info->sigID) { if (head->revision != info->revision) { DynamicRuleDataFree(head->data); head->data = NULL; if (head->compression_data) { DynamicDecompressDestroy(head->compression_data); head->compression_data = NULL; } } *p_data = head->data; *p_compression_data = head->compression_data; return; } head = head->next; } } } void *pcreCompile(const char *pattern, int options, const char **errptr, int *erroffset, const unsigned char *tableptr) { options &= ~SNORT_PCRE_OVERRIDE_MATCH_LIMIT; return (void *)pcre_compile(pattern, options, errptr, erroffset, tableptr); } void *pcreStudy(struct _SnortConfig *sc, const void *code, int options, const char **errptr) { pcre_extra *extra_extra; int snort_options = options & SNORT_PCRE_OVERRIDE_MATCH_LIMIT; extra_extra = pcre_study((const pcre*)code, 0, errptr); if (extra_extra) { if ((ScPcreMatchLimitNewConf(sc) != -1) && !(snort_options & SNORT_PCRE_OVERRIDE_MATCH_LIMIT)) { if (extra_extra->flags & PCRE_EXTRA_MATCH_LIMIT) { extra_extra->match_limit = ScPcreMatchLimitNewConf(sc); } else { extra_extra->flags |= PCRE_EXTRA_MATCH_LIMIT; extra_extra->match_limit = ScPcreMatchLimitNewConf(sc); } } #ifdef PCRE_EXTRA_MATCH_LIMIT_RECURSION if ((ScPcreMatchLimitRecursionNewConf(sc) != -1) && !(snort_options & SNORT_PCRE_OVERRIDE_MATCH_LIMIT)) { if (extra_extra->flags & PCRE_EXTRA_MATCH_LIMIT_RECURSION) { extra_extra->match_limit_recursion = ScPcreMatchLimitRecursionNewConf(sc); } else { extra_extra->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION; extra_extra->match_limit_recursion = ScPcreMatchLimitRecursionNewConf(sc); } } #endif } else { if (!(snort_options & SNORT_PCRE_OVERRIDE_MATCH_LIMIT) && ((ScPcreMatchLimitNewConf(sc) != -1) || (ScPcreMatchLimitRecursionNewConf(sc) != -1))) { extra_extra = (pcre_extra *)SnortAlloc(sizeof(pcre_extra)); if (ScPcreMatchLimitNewConf(sc) != -1) { extra_extra->flags |= PCRE_EXTRA_MATCH_LIMIT; extra_extra->match_limit = ScPcreMatchLimitNewConf(sc); } #ifdef PCRE_EXTRA_MATCH_LIMIT_RECURSION if (ScPcreMatchLimitRecursionNewConf(sc) != -1) { extra_extra->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION; extra_extra->match_limit_recursion = ScPcreMatchLimitRecursionNewConf(sc); } #endif } } return extra_extra; } /* pcreOvectorInfo * * Get the Ovector configuration for PCRE from the snort.conf */ void pcreOvectorInfo(int **ovector, int *ovector_size) { *ovector = snort_conf->pcre_ovector; *ovector_size = snort_conf->pcre_ovector_size; } int pcreExec(const void *code, const void *extra, const char *subj, int len, int start, int options, int *ovec, int ovecsize) { return pcre_exec((const pcre *)code, (const pcre_extra *)extra, subj, len, start, options, ovec, ovecsize); } static int setFlowId(const void* p, uint32_t id) { return DAQ_ModifyFlowOpaque(p, id); } #ifdef DAQ_MODFLOW_TYPE_PRESERVE_FLOW static int setPreserveFlow(const void* p) { DAQ_ModFlow_t mod; int value = 1; if ( Active_GetTunnelBypass() ) return -1; mod.type = DAQ_MODFLOW_TYPE_PRESERVE_FLOW; mod.length = sizeof(value); mod.value = (void*)&value; DAQ_ModifyFlow(p, &mod); return 0; } #endif static const uint8_t* getHttpBuffer (HTTP_BUFFER hb_type, unsigned* len) { const HttpBuffer* hb = GetHttpBuffer(hb_type); if ( !hb ) return NULL; *len = hb->length; return hb->buf; } int InitDynamicEngines(char *dynamic_rules_path) { DynamicEngineData engineData; engineData.version = ENGINE_DATA_VERSION; engineData.altBuffer = (SFDataBuffer *)&DecodeBuffer; engineData.altDetect = (SFDataPointer *)&DetectBuffer; engineData.fileDataBuf = (SFDataPointer *)&file_data_ptr; /* This is defined in dynamic-plugins/sp_dynamic.h */ engineData.ruleRegister = &RegisterDynamicRule; engineData.flowbitRegister = &DynamicFlowbitRegister; engineData.flowbitCheck = &DynamicFlowbitCheck; engineData.asn1Detect = &DynamicAsn1Detect; if (dynamic_rules_path != NULL) engineData.dataDumpDirectory = SnortStrdup(dynamic_rules_path); else engineData.dataDumpDirectory = NULL; engineData.logMsg = &LogMessage; engineData.errMsg = &ErrorMessage; engineData.fatalMsg = &FatalError; engineData.preprocRuleOptInit = &DynamicPreprocRuleOptInit; engineData.setRuleData = &DynamicSetRuleData; engineData.getRuleData = &DynamicGetRuleData; engineData.sfUnfold = &DynamicsfUnfold; engineData.sfbase64decode = &Dynamicsfbase64decode; engineData.GetAltDetect = &DynamicGetAltDetect; engineData.SetAltDetect = &DynamicSetAltDetect; engineData.Is_DetectFlag = &DynamicIsDetectFlag; engineData.DetectFlag_Disable = &DynamicDetectFlagDisable; engineData.debugMsg = &DebugMessageFunc; #ifdef SF_WCHAR engineData.debugWideMsg = &DebugWideMessageFunc; #endif #ifdef DEBUG_MSGS engineData.debugMsgFile = &DebugMessageFile; engineData.debugMsgLine = &DebugMessageLine; #else engineData.debugMsgFile = &no_file; engineData.debugMsgLine = &no_line; #endif engineData.pcreStudy = &pcreStudy; engineData.pcreCompile = &pcreCompile; engineData.pcreExec = &pcreExec; engineData.allocRuleData = &DynamicRuleDataAlloc; engineData.freeRuleData = &DynamicRuleDataFree; engineData.flowbitUnregister = &DynamicFlowbitUnregister; engineData.pcreCapture = &PcreCapture; engineData.pcreOvectorInfo = &pcreOvectorInfo; engineData.getHttpBuffer = getHttpBuffer; engineData.decompressInit = &DynamicDecompressInit; engineData.decompressDestroy = &DynamicDecompressDestroy; engineData.decompress = &DynamicDecompress; return InitDynamicEnginePlugins(&engineData); } int InitDynamicPreprocessorPlugins(DynamicPreprocessorData *info) { DynamicPreprocessorPlugin *plugin; RemoveDuplicatePreprocessorPlugins(); plugin = loadedPreprocessorPlugins; while (plugin) { int i = plugin->initFunc(info); if (i) { FatalError("Failed to initialize dynamic preprocessor: %s version %d.%d.%d (%d)\n", plugin->metaData.uniqueName, plugin->metaData.major, plugin->metaData.minor, plugin->metaData.build, i); //return -1; } plugin = plugin->next; } #ifdef SNORT_RELOAD if (!ada) { ada = ada_init(SoRuleMemInUse, PP_SHARED_RULES, (size_t) ScSoRuleMemcap()); if (!ada) { FatalError("Failed to initialize so_rule session cache. \n"); } } #endif return 0; } /* Do this to avoid exposing Packet & PreprocessFuncNode from * snort to non-GPL code */ typedef void (*SnortPacketProcessFunc)(Packet *, void *); void *AddPreprocessor(struct _SnortConfig *sc, void (*pp_func)(void *, void *), uint16_t priority, uint32_t preproc_id, uint32_t proto_mask) { SnortPacketProcessFunc preprocessorFunc = (SnortPacketProcessFunc)pp_func; return (void *)AddFuncToPreprocList(sc, preprocessorFunc, priority, preproc_id, proto_mask); } void *AddPreprocessorAllPolicies(struct _SnortConfig *sc, void (*pp_func)(void *, void *), uint16_t priority, uint32_t preproc_id, uint32_t proto_mask) { SnortPacketProcessFunc preprocessorFunc = (SnortPacketProcessFunc)pp_func; AddFuncToPreprocListAllNapPolicies(sc, preprocessorFunc, priority, preproc_id, proto_mask); return NULL; } typedef void (*MetadataProcessFunc)(int, const uint8_t *); void *AddMetaEval(struct _SnortConfig *sc, void (*meta_eval_func)(int, const uint8_t *), uint16_t priority, uint32_t preproc_id) { MetadataProcessFunc metaEvalFunc = (MetadataProcessFunc)meta_eval_func; return (void *)AddFuncToPreprocMetaEvalList(sc, metaEvalFunc, priority, preproc_id); } void *AddDetection(struct _SnortConfig *sc, void (*det_func)(void *, void *), uint16_t priority, uint32_t det_id, uint32_t proto_mask) { SnortPacketProcessFunc detectionFunc = (SnortPacketProcessFunc)det_func; return (void *)AddFuncToDetectionList(sc, detectionFunc, priority, det_id, proto_mask); } void AddPreprocessorCheck(struct _SnortConfig *sc, int (*pp_chk_func)(struct _SnortConfig *sc)) { AddFuncToConfigCheckList(sc, pp_chk_func); } void DynamicDisableDetection( void *p ) { DisableDetect( ( Packet * ) p ); } void DynamicDisableAllDetection( void *p ) { DisableAllDetect( ( Packet * ) p ); } void DynamicEnableContentDetection( void ) { EnableContentDetect(); } void DynamicDisablePacketAnalysis( void *p ) { DisablePacketAnalysis( ( Packet * ) p ); } int DynamicDetect(void *p) { return Detect((Packet *)p); } int DynamicEnablePreprocessor(void *p, uint32_t preprocId) { return EnablePreprocessor((Packet *)p, preprocId); } #ifdef ACTIVE_RESPONSE void DynamicActiveSetEnabled(int on_off) { Active_SetEnabled(on_off); } #endif void *DynamicGetRuleClassByName(char *name) { return (void *)ClassTypeLookupByType(snort_conf, name); } void *DynamicGetRuleClassById(int id) { return (void *)ClassTypeLookupById(snort_conf, id); } void DynamicRegisterPreprocessorProfile(const char *keyword, void *stats, int layer, void *parent, PreprocStatsNodeFreeFunc freefn) { #ifdef PERF_PROFILING RegisterPreprocessorProfile(keyword, (PreprocStats *)stats, layer, (PreprocStats *)parent, freefn); #endif } int DynamicProfilingPreprocs(void) { #ifdef PERF_PROFILING return ScProfilePreprocs(); #else return 0; #endif } int DynamicPreprocess(void *packet) { return Preprocess( ( Packet * ) packet ); } void DynamicDisablePreprocessors(void *p) { DisableAppPreprocessors( ( Packet * ) p ); } void DynamicIP6Build(void *p, const void *hdr, int family) { sfiph_build((Packet *)p, hdr, family); } static inline void DynamicIP6SetCallbacks(void *p, int family, char orig) { set_callbacks((Packet *)p, family, orig); } int DynamicSnortEventqLog(void *p) { return SnortEventqLog(snort_conf->event_queue, (Packet *)p); } tSfPolicyId DynamicGetParserPolicy(struct _SnortConfig *sc) { return getParserPolicy(sc); } tSfPolicyId DynamicGetNapRuntimePolicy(void) { return getNapRuntimePolicy(); } tSfPolicyId DynamicGetIpsRuntimePolicy(void) { return getIpsRuntimePolicy(); } tSfPolicyId DynamicGetDefaultPolicy(void) { return getDefaultPolicy(); } tSfPolicyId DynamicGetPolicyFromId(uint16_t id) { return sfPolicyIdGetBinding(snort_conf->policy_config, id); } void DynamicChangeNapRuntimePolicy(tSfPolicyId new_id, void *scb) { session_api->set_runtime_policy( scb, SNORT_NAP_POLICY, new_id ); setNapRuntimePolicy(new_id); } void DynamicChangeIpsRuntimePolicy(tSfPolicyId new_id, void *p) { Packet *pkt = (Packet *) p; session_api->set_runtime_policy( pkt->ssnptr, SNORT_IPS_POLICY, new_id ); setIpsRuntimePolicy(new_id); pkt->configPolicyId = snort_conf->targeted_policies[new_id]->configPolicyId; } static void DynamicAddPktTraceData(int module, int strLen) { addPktTraceData(module, strLen); } static const char* DynamicGetPktTraceActionMsg() { return getPktTraceActMsg(); } static void* DynamicEncodeNew (void) { return (void*)Encode_New(); } static void DynamicEncodeDelete (void *p) { Encode_Delete((Packet*)p); } static void *DynamicNewGrinderPkt(void *p, void *phdr, uint8_t *pkt) { return (void*)NewGrinderPkt((Packet *)p, (DAQ_PktHdr_t *)phdr, pkt); } static void DynamicDeleteGrinderPkt(void *p) { DeleteGrinderPkt((Packet*)p); } static int DynamicEncodeFormat (uint32_t f, const void* p, void *c, int t) { return Encode_Format(f, (Packet*)p, (Packet*)c, (PseudoPacketType)t); } static void DynamicEncodeUpdate (void* p) { Encode_Update((Packet*)p); } #ifdef ACTIVE_RESPONSE void DynamicSendBlockResponseMsg(void *p, const uint8_t* buffer, uint32_t buffer_len, unsigned flags) { Packet *packet = (Packet *)p; EncodeFlags df = (packet->packet_flags & PKT_FROM_SERVER) ? ENC_FLAG_FWD:0; if ( !packet->data || packet->dsize == 0 ) return; if (flags & SND_BLK_RESP_FLAG_DO_CLIENT) df |= ENC_FLAG_RST_CLNT; if (flags & SND_BLK_RESP_FLAG_DO_SERVER) df |= ENC_FLAG_RST_SRVR; if (packet->packet_flags & PKT_STREAM_EST) Active_SendData(packet, df, buffer, buffer_len); } void DynamicActiveResponseMsg(void *p, const uint8_t* buf, uint32_t blen, unsigned flags) { EncodeFlags df = (SND_BLK_RESP_FLAG_DO_CLIENT) ? 0: ENC_FLAG_FWD; Active_UDPInjectData((Packet *)p, df , buf, blen); } void DynamicActiveInjectData(void *p, uint32_t flags, const uint8_t *buf, uint32_t blen) { Active_InjectData((Packet *)p, (EncodeFlags)flags, buf, blen); } void DynamicActiveSendForwardReset(void *p) { Active_SendReset((Packet *)p, ENC_FLAG_FWD); } int DynamicActiveQueueResponse( Active_ResponseFunc cb, void *data ) { return Active_QueueResponse( cb, data ); } #endif void DynamicDropPacket(void *p) { Active_DropPacket((Packet*)p); } bool DynamicRetryPacket(void *p) { return Active_DAQRetryPacket( ( Packet * ) p ); } bool DynamicActivePacketWasDropped(void) { return Active_PacketWasDropped(); } void DynamicForceDropPacket(void *p) { Active_ForceDropPacket( ); } void DynamicDropSessionAndReset(void *p) { Active_DropSession((Packet*)p); } void DynamicForceDropSession(void *p) { Active_ForceDropSession(); } void DynamicForceDropSessionAndReset(void *p) { Active_ForceDropResetAction((Packet *)p); } void DynamicSetParserPolicy(SnortConfig *sc, tSfPolicyId id) { setParserPolicy(sc, id); } void DynamicSetFileDataPtr(uint8_t *ptr, uint16_t decode_size) { setFileDataPtr((const uint8_t*)ptr, decode_size); } void DynamicDetectResetPtr(uint8_t *ptr, uint16_t decode_size) { DetectReset(ptr, decode_size); } void DynamicSetAltDecode(uint16_t altLen) { SetAltDecode(altLen); } int DynamicGetNapInlineMode(void) { return ScNapInlineMode(); } int DynamicGetIpsInlineMode(void) { return ScIpsInlineMode(); } long DynamicSnortStrtol(const char *nptr, char **endptr, int base) { return SnortStrtol(nptr,endptr,base); } unsigned long DynamicSnortStrtoul(const char *nptr, char **endptr, int base) { return SnortStrtoul(nptr,endptr,base); } const char *DynamicSnortStrnStr(const char *s, int slen, const char *accept) { return SnortStrnStr(s, slen, accept); } const char *DynamicSnortStrcasestr(const char *s, int slen, const char *accept) { return SnortStrcasestr(s, slen, accept); } int DynamicSnortStrncpy(char *dst, const char *src, size_t dst_size) { return SnortStrncpy(dst, src, dst_size); } const char *DynamicSnortStrnPbrk(const char *s, int slen, const char *accept) { return SnortStrnPbrk(s, slen, accept); } int DynamicEvalRTN(void *rtn, void *p, int check_ports) { return fpEvalRTN((RuleTreeNode *)rtn, (Packet *)p, check_ports); } char *DynamicGetLogDirectory(void) { return SnortStrdup(snort_conf->log_dir); } uint32_t DynamicGetSnortInstance(void) { return (snort_conf->event_log_id >> 16); } bool DynamicIsPafEnabled(void) { return ScPafEnabled(); } bool DynamicIsReadMode(void) { return ScReadMode(); } time_t DynamicPktTime(void) { return packet_time(); } void DynamicGetPktTimeOfDay(struct timeval *tv) { packet_gettimeofday(tv); } #ifdef SIDE_CHANNEL bool DynamicIsSCEnabled(void) { return ScSideChannelEnabled(); } int DynamicSCRegisterRXHandler(uint16_t type, SCMProcessMsgFunc processMsgFunc, void *data) { return SideChannelRegisterRXHandler(type, processMsgFunc, data); } int DynamicSCPreallocMessageTX(uint32_t length, SCMsgHdr **hdr_ptr, uint8_t **msg_ptr, void **msg_handle) { return SideChannelPreallocMessageTX(length, hdr_ptr, msg_ptr, msg_handle); } int DynamicSCEnqueueMessageTX(SCMsgHdr *hdr, const uint8_t *msg, uint32_t length, void *msg_handle, SCMQMsgFreeFunc msgFreeFunc) { return SideChannelEnqueueMessageTX(hdr, msg, length, msg_handle, msgFreeFunc); } #endif int DynamicCanWhitelist(void) { return DAQ_CanWhitelist(); } #if defined(DAQ_CAPA_CST_TIMEOUT) bool DynamicCanGetTimeout(void) { return Daq_Capa_Timeout; } #endif int DynamicSnortIsStrEmpty(const char *s) { return IsEmptyStr((char*)s); } static void DynamicDisableAllPolicies(struct _SnortConfig *sc) { DisableAllPolicies(sc); } static int DynamicReenablePreprocBitFunc(struct _SnortConfig *sc, unsigned int preproc_id) { return ReenablePreprocBit(sc, preproc_id); } #ifdef SIDE_CHANNEL static sigset_t DynamicSnortSignalMask(void) { sigset_t mask; sigemptyset(&mask); sigaddset(&mask, SIGTERM); sigaddset(&mask, SIGQUIT); sigaddset(&mask, SIGPIPE); sigaddset(&mask, SIGINT); sigaddset(&mask, SIGNAL_SNORT_RELOAD); sigaddset(&mask, SIGNAL_SNORT_DUMP_STATS); sigaddset(&mask, SIGUSR1); sigaddset(&mask, SIGUSR2); sigaddset(&mask, SIGNAL_SNORT_ROTATE_STATS); sigaddset(&mask, SIGNAL_SNORT_CHILD_READY); #ifdef TARGET_BASED sigaddset(&mask, SIGNAL_SNORT_READ_ATTR_TBL); sigaddset(&mask, SIGVTALRM); #endif pthread_sigmask(SIG_SETMASK, &mask, NULL); return mask; } #endif static SslAppIdLookupFunc sslAppIdLookupFnPtr; static void registerSslAppIdLookup(SslAppIdLookupFunc fnptr) { sslAppIdLookupFnPtr = fnptr; } static int sslAppIdLookup(void *ssnptr, const char * serverName, const char * commonName, int32_t *serviceAppId, int32_t *clientAppId, int32_t *payloadAppId) { if (sslAppIdLookupFnPtr) return (sslAppIdLookupFnPtr)(ssnptr, serverName, commonName, serviceAppId, clientAppId, payloadAppId); return 0; } static GetAppIdFunc getAppIdFnPtr = NULL; static void registerGetAppId(GetAppIdFunc fnptr) { getAppIdFnPtr = fnptr; } static int32_t getAppId(void *ssnptr) { if(getAppIdFnPtr) return (getAppIdFnPtr)(ssnptr); return 0; } static UrlQueryCreateFunc urlQueryCreateFnPtr; static UrlQueryDestroyFunc urlQueryDestroyFnPtr; static UrlQueryMatchFunc urlQueryMatchFnPtr; static UserGroupIdGetFunc userGroupIdGetFnPtr; static GeoIpAddressLookupFunc geoIpAddressLookupFnPtr; static UpdateSSLSSnLogDataFunc updateSSLSSnLogDataFnPtr; static EndSSLSSnLogDataFunc endSSLSSnLogDataFnPtr; static GetSSLActualActionFunc getSSLActualActionFnPtr; static GetIntfDataFunc getIntfDataFnPtr; static ReputationProcessExternalIpFunc reputationProcessExternalIpFnPtr = NULL; void registerReputationProcessExternal(ReputationProcessExternalIpFunc extProcessFn) { reputationProcessExternalIpFnPtr = extProcessFn; } static bool _reputation_process_external_ip(void *p, sfaddr_t* ip) { if(reputationProcessExternalIpFnPtr) { return ((reputationProcessExternalIpFnPtr)(p,ip)); } return false; } void registerUrlQuery(UrlQueryCreateFunc createFn, UrlQueryDestroyFunc destroyFn, UrlQueryMatchFunc matchFn) { urlQueryCreateFnPtr = createFn; urlQueryDestroyFnPtr = destroyFn; urlQueryMatchFnPtr = matchFn; } static struct urlQueryContext* urlQueryCreate(const char *url) { if (urlQueryCreateFnPtr) { return ((urlQueryCreateFnPtr)(url)); } return NULL; } static void urlQueryDestroy(struct urlQueryContext *context) { if (urlQueryDestroyFnPtr) (urlQueryDestroyFnPtr)(context); } static int urlQueryMatch(void *ssnptr, struct urlQueryContext *context, uint16_t inUrlCat, uint16_t inUrlMinRep, uint16_t inUrlMaxRep) { if (urlQueryMatchFnPtr) return (urlQueryMatchFnPtr)(ssnptr, context, inUrlCat, inUrlMinRep, inUrlMaxRep); return -1; } #if defined DAQ_CAPA_CST_TIMEOUT void RegisterGetDaqCapaTimeout(GetDaqCapaTimeOutFunc timeoutFn) { getDaqCapaTimeoutFnPtr = timeoutFn; } #endif static void registerUserGroupIdGet(UserGroupIdGetFunc userIdFn) { userGroupIdGetFnPtr = userIdFn; } static int userGroupIdGet(void *ssnptr, uint32_t *userId, uint32_t *realmId, unsigned *groupIdArray, unsigned groupIdArrayLen) { if (userGroupIdGetFnPtr) return (userGroupIdGetFnPtr)(ssnptr, userId, realmId, groupIdArray, groupIdArrayLen); return -1; } static void registerGeoIpAddressLookup(GeoIpAddressLookupFunc fn) { geoIpAddressLookupFnPtr = fn; } static int geoIpAddressLookup(const sfaddr_t *snortIp, uint16_t* geo) { if (geoIpAddressLookupFnPtr) return (geoIpAddressLookupFnPtr)(snortIp, geo); return -1; } static void registerGetIntfData(GetIntfDataFunc fn) { getIntfDataFnPtr = fn; } static void getIntfData(void *ssnptr, int32_t *ingressIntfIndex, int32_t *egressIntfIndex, int32_t *ingressZoneIndex, int32_t *egressZoneIndex) { if (getIntfDataFnPtr) { (getIntfDataFnPtr)(ssnptr, ingressIntfIndex, egressIntfIndex, ingressZoneIndex, egressZoneIndex); } } static void registerUpdateSSLSSnLogData(UpdateSSLSSnLogDataFunc fn) { updateSSLSSnLogDataFnPtr = fn; } static void updateSSLSSnLogData(void *ssnptr, uint8_t logging_on, uint8_t action_is_block, const char *ssl_cert_fingerprint, uint32_t ssl_cert_fingerprint_len, uint32_t ssl_cert_status, uint8_t *ssl_policy_id, uint32_t ssl_policy_id_len, uint32_t ssl_rule_id, uint16_t ssl_cipher_suite, uint8_t ssl_version, uint16_t ssl_actual_action, uint16_t ssl_expected_action, uint32_t ssl_url_category, uint16_t ssl_flow_status, uint32_t ssl_flow_error, uint32_t ssl_flow_messages, uint64_t ssl_flow_flags, char *ssl_server_name, uint8_t *ssl_session_id, uint8_t session_id_len, uint8_t *ssl_ticket_id, uint8_t ticket_id_len) { if (updateSSLSSnLogDataFnPtr) { (updateSSLSSnLogDataFnPtr)(ssnptr, logging_on, action_is_block, ssl_cert_fingerprint, ssl_cert_fingerprint_len, ssl_cert_status, ssl_policy_id, ssl_policy_id_len, ssl_rule_id, ssl_cipher_suite, ssl_version, ssl_actual_action, ssl_expected_action, ssl_url_category, ssl_flow_status, ssl_flow_error, ssl_flow_messages, ssl_flow_flags, ssl_server_name, ssl_session_id, session_id_len, ssl_ticket_id, ticket_id_len); } } static void registerGetSSLActualAction(GetSSLActualActionFunc fn) { getSSLActualActionFnPtr = fn; } static int getSSLActualAction(void *ssnptr, uint16_t *action) { if (getSSLActualActionFnPtr) { return (getSSLActualActionFnPtr)(ssnptr, action); } return -1; } static void registerEndSSLSSnLogData(EndSSLSSnLogDataFunc fn) { endSSLSSnLogDataFnPtr = fn; } static void endSSLSSnLogData(void *ssnptr, uint32_t ssl_flow_messages, uint64_t ssl_flow_flags) { if (endSSLSSnLogDataFnPtr) { (endSSLSSnLogDataFnPtr)(ssnptr, ssl_flow_messages, ssl_flow_flags); } } static inline bool DynamicReadyForProcess (void* pkt) { Packet *p = (Packet *)pkt; if ( ScPafEnabled() ) return PacketHasPAFPayload(p); return !(p->packet_flags & PKT_STREAM_INSERT); } void DynamicSetSSLCallback(void *p) { SetSSLCallback(p); } void *DynamicGetSSLCallback(void) { return GetSSLCallback(); } /* DynamicIsSSLPolicyEnabled( struct _SnortConfig * ) Notes: Durring reload/init SnortConfig MUST be provided. Durring runtime/packet processing, NULL MUST be provided. Arguments: (struct _SnortConfig*) sc Returns: (bool) true || false */ bool DynamicIsSSLPolicyEnabled( struct _SnortConfig *sc ) { tSfPolicyId policy; if (sc) { policy = getParserPolicy(sc); return (sc->targeted_policies[ policy ]->ssl_policy_enabled); } policy = getNapRuntimePolicy(); return (snort_conf->targeted_policies[ policy ]->ssl_policy_enabled ); } void DynamicSetSSLPolicyEnabled(struct _SnortConfig *sc, tSfPolicyId policy, bool value) { sc->targeted_policies[policy]->ssl_policy_enabled = value; } static ftpGetModefunc ftpGetDataModefnptr; void registerFtpModeQuery(ftpGetModefunc fnptr) { if (!ftpGetDataModefnptr) ftpGetDataModefnptr = fnptr; } static bool ftpGetDataSessionMode(void *ssnptr) { if (ftpGetDataModefnptr) { return ((ftpGetDataModefnptr)(ssnptr)); } return 0; } #ifdef SNORT_RELOAD int DynamicReloadAdjustRegister(SnortConfig* sc, const char* raName, tSfPolicyId raPolicyId, ReloadAdjustFunc raFunc, void* raUserData, ReloadAdjustUserFreeFunc raUserFreeFunc) { return ReloadAdjustRegister(sc, raName, raPolicyId, raFunc, raUserData, raUserFreeFunc); } #endif #if defined(FEAT_OPEN_APPID) typedef struct _IsAppIdRequiredFuncNode { IsAppIdRequiredFunc fn; struct _IsAppIdRequiredFuncNode * next; } IsAppIdRequiredFuncNode; static IsAppIdRequiredFuncNode * isAppIdRequiredFuncList = NULL; static pthread_mutex_t isAppIdRequiredFuncListMutex = PTHREAD_MUTEX_INITIALIZER; static void registerIsAppIdRequired(IsAppIdRequiredFunc fn) { IsAppIdRequiredFuncNode * curr; if (fn == NULL) return; pthread_mutex_lock(&isAppIdRequiredFuncListMutex); curr = isAppIdRequiredFuncList; while (curr != NULL) { if (curr->fn == fn) { pthread_mutex_unlock(&isAppIdRequiredFuncListMutex); return; /* function is already registered */ } curr = curr->next; } curr = malloc(sizeof(IsAppIdRequiredFuncNode)); if (curr == NULL) { pthread_mutex_unlock(&isAppIdRequiredFuncListMutex); return; } curr->fn = fn; curr->next = isAppIdRequiredFuncList; isAppIdRequiredFuncList = curr; pthread_mutex_unlock(&isAppIdRequiredFuncListMutex); } static void unregisterIsAppIdRequired(IsAppIdRequiredFunc fn) { IsAppIdRequiredFuncNode * tmp; IsAppIdRequiredFuncNode ** curr; if (fn == NULL) return; pthread_mutex_lock(&isAppIdRequiredFuncListMutex); curr = &isAppIdRequiredFuncList; while (*curr != NULL) { if ((*curr)->fn == fn) break; curr = &((*curr)->next); } if (*curr == NULL) { pthread_mutex_unlock(&isAppIdRequiredFuncListMutex); return; /* function is not currently registered */ } tmp = *curr; *curr = (*curr)->next; pthread_mutex_unlock(&isAppIdRequiredFuncListMutex); free(tmp); } static bool isAppIdRequired(void) { IsAppIdRequiredFuncNode * curr; pthread_mutex_lock(&isAppIdRequiredFuncListMutex); curr = isAppIdRequiredFuncList; while (curr != NULL) { if ((curr->fn != NULL) && curr->fn()) { pthread_mutex_unlock(&isAppIdRequiredFuncListMutex); return true; } curr = curr->next; } pthread_mutex_unlock(&isAppIdRequiredFuncListMutex); return false; } static const char *dummyGetApplicationName(int32_t appId) { return NULL; } static tAppId dummyGetApplicationId(const char *appName) { return 0; } static tAppId dummyAppIdFFromAppIdData(struct AppIdData *session) { return 0; } static SFGHASH* dummyAppIdMultiPayload(struct AppIdData *session) { return NULL; } static bool dummyCheckAppIdData(struct AppIdData *session) { return false; } static char *dummyGetUserName(struct AppIdData *session, tAppId *service, bool *isLoginSuccessful) { return NULL; } static char *dummyGetClientVersion(struct AppIdData *session) { return NULL; } static uint64_t dummyGetAppIdSessionAttribute(struct AppIdData *session, uint64_t flag) { return 0; } static APPID_FLOW_TYPE dummyGetFlowType(struct AppIdData *appIdData) { return APPID_FLOW_TYPE_IGNORE; } static void dummyGetServiceInfo(struct AppIdData *appIdData, char **serviceVendor, char **serviceVersion, RNAServiceSubtype **serviceSubtype) { } static short dummyGetServicePort(struct AppIdData *appIdData) { return 0; } static sfaddr_t *dummyIpFromAppIdData(struct AppIdData *appIdData) { return NULL; } static struct in6_addr *dummyGetInitiatorIp(struct AppIdData *appIdData) { return NULL; } static char *dummyStringFromAppIdData(struct AppIdData *appIdData) { return NULL; } static char *dummyIndexedStringFromAppIdData(struct AppIdData *appIdData, HTTP_FIELD_ID fieldId) { return NULL; } static void dummyFreeIndexedStringFromAppIdData(struct AppIdData *appIdData, HTTP_FIELD_ID fieldId) { return; } static uint16_t dummyGetHttpFieldOffset(struct AppIdData *appIdData, HTTP_FIELD_ID fieldId) { return 0; } static SEARCH_SUPPORT_TYPE dummySearchTypeFromAppIdData(struct AppIdData *appIdData) { return NOT_A_SEARCH_ENGINE; } static uint16_t dummyOffsetFromAppIdData(struct AppIdData *appIdData) { return 0; } static DhcpFPData *dummyGetDhcpFpData(struct AppIdData *appIdData) { return NULL; } static void dummyFreeDhcpFpData(struct AppIdData *session, DhcpFPData *data) { } static DHCPInfo *dummyGetDhcpInfo(struct AppIdData *session) { return NULL; } static void dummyFreeDhcpInfo(struct AppIdData *session, DHCPInfo *data) { } static FpSMBData *dummyGetSmbFpData(struct AppIdData *session) { return NULL; } static void dummyFreeSmbFpData(struct AppIdData *session, FpSMBData *data) { } static char *dummyGetNetbiosName(struct AppIdData *session) { return NULL; } static uint32_t dummyProduceHAState(void *lwssn, uint8_t *buf) { return 0; } static uint32_t dummyConsumeHAState(void *lwssn, const uint8_t *buf, uint8_t length, uint8_t proto, const struct in6_addr* ip, uint16_t initiatorPort) { return 0; } static struct AppIdData *dummyGetAppIdData(void *lwssn) { return NULL; } static int dummyGetAppIdSessionPacketCount(struct AppIdData * appIdData) { return 0; } static char *dummyGetDNSQuery(struct AppIdData *session, uint8_t *query_len, bool *got_response) { if (query_len) *query_len = 0; if (got_response) *got_response = false; return NULL; } static uint16_t dummyGetDNSOffset(struct AppIdData *session) { return 0; } static uint16_t dummyGetDNSRecordType(struct AppIdData *session) { return 0; } static uint8_t dummyGetDNSResponseType(struct AppIdData *session) { return 0; } static uint32_t dummyGetDNSTTL(struct AppIdData *session) { return 0; } struct AppIdData* dummyRemoveExpectedAppIdData(struct AppIdData *appIdData) { return NULL; } static void dummyDumpDebugHostInfo(void) { } struct AppIdApi appIdApi = { dummyGetApplicationName, /* getApplicationName */ dummyGetApplicationId, /* getApplicationId */ dummyAppIdFFromAppIdData, /* getServiceAppId */ dummyAppIdFFromAppIdData, /* getPortServiceAppId */ dummyAppIdFFromAppIdData, /* getOnlyServiceAppId */ dummyAppIdFFromAppIdData, /* getMiscAppId */ dummyAppIdFFromAppIdData, /* getClientAppId */ dummyAppIdFFromAppIdData, /* getPayloadAppId */ dummyAppIdFFromAppIdData, /* getReferredAppId */ dummyAppIdFFromAppIdData, /* getFwServiceAppId */ dummyAppIdFFromAppIdData, /* getFwMiscAppId */ dummyAppIdFFromAppIdData, /* getFwClientAppId */ dummyAppIdFFromAppIdData, /* getFwPayloadAppId */ dummyAppIdFFromAppIdData, /* getFwReferredAppId */ dummyAppIdMultiPayload, /* getFwMultiPayloadList */ dummyCheckAppIdData, /* isSessionSslDecrypted */ dummyCheckAppIdData, /* isAppIdInspectingSession */ dummyCheckAppIdData, /* isAppIdAvailable */ dummyGetUserName, /* getUserName */ dummyGetClientVersion, /* getClientVersion */ dummyGetAppIdSessionAttribute, /* getAppIdSessionAttribute */ dummyGetFlowType, /* getFlowType */ dummyGetServiceInfo, /* getServiceInfo */ dummyGetServicePort, /* getServicePort */ dummyIpFromAppIdData, /* getServiceIp */ dummyGetInitiatorIp, /* getInitiatorIp */ dummyStringFromAppIdData, /* getHttpUserAgent */ dummyStringFromAppIdData, /* getHttpHost */ dummyStringFromAppIdData, /* getHttpUrl */ dummyStringFromAppIdData, /* getHttpReferer */ dummyStringFromAppIdData, /* getHttpNewUrl */ dummyStringFromAppIdData, /* getHttpUri */ dummyStringFromAppIdData, /* getHttpResponseCode */ dummyStringFromAppIdData, /* getHttpCookie */ dummyStringFromAppIdData, /* getHttpNewCookie */ dummyStringFromAppIdData, /* getHttpContentType */ dummyStringFromAppIdData, /* getHttpLocation */ dummyStringFromAppIdData, /* getHttpBody */ dummyStringFromAppIdData, /* getHttpReqBody */ dummyOffsetFromAppIdData, /* getHttpUriOffset */ dummyOffsetFromAppIdData, /* getHttpUriEndOffset */ dummyOffsetFromAppIdData, /* getHttpCookieOffset */ dummyOffsetFromAppIdData, /* getHttpCookieEndOffset */ dummySearchTypeFromAppIdData, /* getHttpSearch */ dummyIpFromAppIdData, /* getHttpXffAddr */ dummyStringFromAppIdData, /* getTlsHost */ dummyGetDhcpFpData, /* getDhcpFpData */ dummyFreeDhcpFpData, /* freeDhcpFpData */ dummyGetDhcpInfo, /* getDhcpInfo */ dummyFreeDhcpInfo, /* freeDhcpInfo */ dummyGetSmbFpData, /* getSmbFpData */ dummyFreeSmbFpData, /* freeSmbFpData */ dummyGetNetbiosName, /* getNetbiosName */ dummyProduceHAState, /* produceHAState */ dummyConsumeHAState, /* consumeHAState */ dummyGetAppIdData, /* getAppIdData */ dummyGetAppIdSessionPacketCount, /* getAppIdSessionPacketCount */ dummyGetDNSQuery, /* getDNSQuery */ dummyGetDNSOffset, /* getDNSQueryoffset */ dummyGetDNSRecordType, /* getDNSQueryType */ dummyGetDNSResponseType, /* getDNSQueryResponseType */ dummyGetDNSTTL, /* getDNSTTL */ dummyGetDNSOffset, /* getDNSOptionsOffset */ dummyIndexedStringFromAppIdData, /* getHttpNewField */ dummyFreeIndexedStringFromAppIdData, /* freeHttpNewField */ dummyGetHttpFieldOffset, /* getHttpFieldOffset */ dummyGetHttpFieldOffset, /* getHttpFieldEndOffset */ dummyCheckAppIdData, /* isHttpInspectionDone */ dummyDumpDebugHostInfo /* dumpDebugHostInfo */ }; #endif /* defined(FEAT_OPEN_APPID) */ static int GetSnortPerfIndicators( void *p ) { return( PerfIndicator_GetIndicators( (Perf_Indicator_Descriptor_p_t)p ) ); } static uint32_t GetSnortPacketLatency() { #ifdef PI_PACKET_LATENCY_SUPPORT return ( GetPacketLatency() ); #else return 0; #endif } static double GetSnortPacketDropPortion() { #ifdef PI_PACKET_DROPS_SUPPORT return ( GetPacketDropPortion() ); #else return 0; #endif } static bool DynamicIsTestMode(void) { return (ScTestMode()!= 0); } static SnortConfig* GetCurrentSnortConfig(void) { return snort_conf; } static void DynamicSetIPRepUpdateCount(uint8_t count) { return setIPRepUpdateCount(count); } int InitDynamicPreprocessors(void) { DynamicPreprocessorData preprocData; preprocData.version = PREPROCESSOR_DATA_VERSION; preprocData.size = sizeof(DynamicPreprocessorData); preprocData.altBuffer = (SFDataBuffer *)&DecodeBuffer; preprocData.altDetect = (SFDataPointer *)&DetectBuffer; preprocData.fileDataBuf = (SFDataPointer *)&file_data_ptr; preprocData.logMsg = &LogMessage; preprocData.errMsg = &ErrorMessage; preprocData.fatalMsg = &FatalError; preprocData.debugMsg = &DebugMessageFunc; #ifdef SF_WCHAR preprocData.debugWideMsg = &DebugWideMessageFunc; #endif preprocData.registerPreproc = &RegisterPreprocessor; #ifdef SNORT_RELOAD preprocData.getRelatedReloadData = GetRelatedReloadData; #endif #ifdef DUMP_BUFFER preprocData.registerBufferTracer = &RegisterBufferTracer; #endif preprocData.addPreproc = &AddPreprocessor; preprocData.addPreprocAllPolicies = &AddPreprocessorAllPolicies; preprocData.addMetaEval = &AddMetaEval; preprocData.getSnortInstance = DynamicGetSnortInstance; preprocData.addPreprocExit = &AddFuncToPreprocCleanExitList; preprocData.addPreprocConfCheck = &AddPreprocessorCheck; preprocData.preprocOptRegister = &RegisterPreprocessorRuleOption; preprocData.addPreprocProfileFunc = &DynamicRegisterPreprocessorProfile; preprocData.profilingPreprocsFunc = &DynamicProfilingPreprocs; #ifdef PERF_PROFILING preprocData.totalPerfStats = &totalPerfStats; #else preprocData.totalPerfStats = NULL; #endif preprocData.alertAdd = &SnortEventqAdd; preprocData.genSnortEvent = &GenerateSnortEvent; preprocData.thresholdCheck = &sfthreshold_test; preprocData.detect = &DynamicDetect; preprocData.disableDetect = &DynamicDisableDetection; preprocData.disableAllDetect = &DynamicDisableAllDetection; preprocData.enableContentDetect = &DynamicEnableContentDetection; preprocData.disablePacketAnalysis = &DynamicDisablePacketAnalysis; preprocData.enablePreprocessor = &DynamicEnablePreprocessor; preprocData.sessionAPI = session_api; preprocData.streamAPI = stream_api; preprocData.searchAPI = search_api; preprocData.config_file = &file_name; preprocData.config_line = &file_line; preprocData.printfappend = &sfsnprintfappend; preprocData.tokenSplit = &mSplit; preprocData.tokenFree = &mSplitFree; preprocData.getRuleInfoByName = &DynamicGetRuleClassByName; preprocData.getRuleInfoById = &DynamicGetRuleClassById; preprocData.preprocess = &DynamicPreprocess; #ifdef DEBUG_MSGS preprocData.debugMsgFile = &DebugMessageFile; preprocData.debugMsgLine = &DebugMessageLine; #else preprocData.debugMsgFile = &no_file; preprocData.debugMsgLine = &no_line; #endif preprocData.registerPreprocStats = &RegisterPreprocStats; preprocData.addPreprocReset = &AddFuncToPreprocResetList; preprocData.addPreprocResetStats = &AddFuncToPreprocResetStatsList; preprocData.disablePreprocessors = &DynamicDisablePreprocessors; preprocData.ip6Build = &DynamicIP6Build; preprocData.ip6SetCallbacks = &DynamicIP6SetCallbacks; preprocData.logAlerts = &DynamicSnortEventqLog; preprocData.resetAlerts = &SnortEventqReset; preprocData.pushAlerts = SnortEventqPush; preprocData.popAlerts = SnortEventqPop; #ifdef TARGET_BASED preprocData.findProtocolReference = &FindProtocolReference; preprocData.addProtocolReference = &AddProtocolReference; preprocData.isAdaptiveConfigured = &IsAdaptiveConfigured; preprocData.isAdaptiveConfiguredForSnortConfig = &IsAdaptiveConfiguredForSnortConfig; #endif preprocData.preprocOptOverrideKeyword = &RegisterPreprocessorRuleOptionOverride; preprocData.preprocOptByteOrderKeyword = &RegisterPreprocessorRuleOptionByteOrder; preprocData.isPreprocEnabled = &IsPreprocEnabled; preprocData.getNapRuntimePolicy = DynamicGetNapRuntimePolicy; preprocData.getIpsRuntimePolicy = DynamicGetIpsRuntimePolicy; preprocData.getParserPolicy = DynamicGetParserPolicy; preprocData.getDefaultPolicy = DynamicGetDefaultPolicy; preprocData.setParserPolicy = DynamicSetParserPolicy; preprocData.setFileDataPtr = DynamicSetFileDataPtr; preprocData.DetectReset = DynamicDetectResetPtr; preprocData.SetAltDecode = &DynamicSetAltDecode; preprocData.GetAltDetect = &DynamicGetAltDetect; preprocData.SetAltDetect = &DynamicSetAltDetect; preprocData.Is_DetectFlag = &DynamicIsDetectFlag; preprocData.DetectFlag_Disable = &DynamicDetectFlagDisable; preprocData.SnortStrtol = DynamicSnortStrtol; preprocData.SnortStrtoul = DynamicSnortStrtoul; preprocData.SnortStrnStr = DynamicSnortStrnStr; preprocData.SnortStrncpy = DynamicSnortStrncpy; preprocData.SnortStrnPbrk = DynamicSnortStrnPbrk; preprocData.SnortStrcasestr = DynamicSnortStrcasestr; preprocData.portObjectCharPortArray = PortObjectCharPortArray; preprocData.fpEvalRTN = DynamicEvalRTN; preprocData.obApi = obApi; preprocData.encodeNew = DynamicEncodeNew; preprocData.encodeDelete = DynamicEncodeDelete; preprocData.encodeFormat = DynamicEncodeFormat; preprocData.encodeUpdate = DynamicEncodeUpdate; preprocData.newGrinderPkt = DynamicNewGrinderPkt; preprocData.deleteGrinderPkt = DynamicDeleteGrinderPkt; preprocData.portObjectCharPortArray = PortObjectCharPortArray; preprocData.addDetect = &AddDetection; preprocData.getLogDirectory = DynamicGetLogDirectory; preprocData.controlSocketRegisterHandler = &ControlSocketRegisterHandler; preprocData.registerIdleHandler = &IdleProcessingRegisterHandler; preprocData.isPafEnabled = DynamicIsPafEnabled; preprocData.pktTime = DynamicPktTime; preprocData.getPktTimeOfDay = DynamicGetPktTimeOfDay; #ifdef SIDE_CHANNEL preprocData.isSCEnabled = DynamicIsSCEnabled; preprocData.scRegisterRXHandler = &DynamicSCRegisterRXHandler; preprocData.scAllocMessageTX = &DynamicSCPreallocMessageTX; preprocData.scEnqueueMessageTX = &DynamicSCEnqueueMessageTX; #endif preprocData.getPolicyFromId = &DynamicGetPolicyFromId; preprocData.changeNapRuntimePolicy = &DynamicChangeNapRuntimePolicy; preprocData.changeIpsRuntimePolicy = &DynamicChangeIpsRuntimePolicy; preprocData.inlineDropPacket = &DynamicDropPacket; preprocData.inlineRetryPacket = &DynamicRetryPacket; preprocData.inlineForceDropPacket =&DynamicForceDropPacket; preprocData.inlineDropSessionAndReset = &DynamicDropSessionAndReset; preprocData.inlineForceDropSession = &DynamicForceDropSession; preprocData.inlineForceDropSessionAndReset = &DynamicForceDropSessionAndReset; preprocData.active_PacketWasDropped = &DynamicActivePacketWasDropped; #ifdef ACTIVE_RESPONSE preprocData.activeSetEnabled = &DynamicActiveSetEnabled; #endif preprocData.SnortIsStrEmpty = DynamicSnortIsStrEmpty; #ifdef ACTIVE_RESPONSE preprocData.dynamicSendBlockResponse = &DynamicSendBlockResponseMsg; #endif preprocData.dynamicSetFlowId = &setFlowId; #ifdef HAVE_DAQ_EXT_MODFLOW preprocData.dynamicModifyFlow = &DAQ_ModifyFlow; #endif #ifdef HAVE_DAQ_QUERYFLOW preprocData.dynamicQueryFlow = &DAQ_QueryFlow; #endif #if defined(DAQ_VERSION) && DAQ_VERSION > 8 preprocData.dynamicDebugPkt = &DAQ_DebugPkt; #endif #if defined(DAQ_VERSION) && DAQ_VERSION > 9 preprocData.dynamicIoctl = &DAQ_Ioctl; #endif preprocData.addPeriodicCheck = &AddFuncToPeriodicCheckList; preprocData.addPostConfigFunc = &AddFuncToPreprocPostConfigList; preprocData.addFuncToPostConfigList = &AddFuncToPostConfigList; preprocData.snort_conf_dir = &snort_conf_dir; preprocData.addOutputModule = &output_load_module; preprocData.canWhitelist = DynamicCanWhitelist; preprocData.fileAPI = file_api; preprocData.disableAllPolicies = &DynamicDisableAllPolicies; preprocData.reenablePreprocBit = &DynamicReenablePreprocBitFunc; preprocData.checkValueInRange = &CheckValueInRange; preprocData.setHttpBuffer = SetHttpBuffer; preprocData.getHttpBuffer = getHttpBuffer; #ifdef ACTIVE_RESPONSE preprocData.activeInjectData = &DynamicActiveInjectData; preprocData.activeSendResponse = &DynamicActiveResponseMsg; preprocData.activeSendForwardReset = &DynamicActiveSendForwardReset; preprocData.activeQueueResponse = &DynamicActiveQueueResponse; #endif preprocData.readyForProcess = &DynamicReadyForProcess; preprocData.getSSLCallback = &DynamicGetSSLCallback; preprocData.setSSLCallback = &DynamicSetSSLCallback; preprocData.sslAppIdLookup = &sslAppIdLookup; preprocData.registerSslAppIdLookup = ®isterSslAppIdLookup; preprocData.getAppId = &getAppId; preprocData.registerGetAppId = ®isterGetAppId; preprocData.urlQueryCreate = &urlQueryCreate; preprocData.urlQueryDestroy = &urlQueryDestroy; preprocData.urlQueryMatch = &urlQueryMatch; preprocData.registerUrlQuery = ®isterUrlQuery; preprocData.userGroupIdGet = &userGroupIdGet; preprocData.registerUserGroupIdGet = ®isterUserGroupIdGet; preprocData.geoIpAddressLookup = &geoIpAddressLookup; preprocData.registerGeoIpAddressLookup = ®isterGeoIpAddressLookup; preprocData.updateSSLSSnLogData = &updateSSLSSnLogData; preprocData.registerUpdateSSLSSnLogData = ®isterUpdateSSLSSnLogData; preprocData.endSSLSSnLogData = &endSSLSSnLogData; preprocData.registerEndSSLSSnLogData = ®isterEndSSLSSnLogData; preprocData.registerGetSSLActualAction = ®isterGetSSLActualAction; preprocData.getSSLActualAction = &getSSLActualAction; preprocData.getIntfData = &getIntfData; preprocData.registerGetIntfData = ®isterGetIntfData; preprocData.isSSLPolicyEnabled = &DynamicIsSSLPolicyEnabled; preprocData.setSSLPolicyEnabled = &DynamicSetSSLPolicyEnabled; preprocData.getPerfIndicators = &GetSnortPerfIndicators; preprocData.getPacketLatency = &GetSnortPacketLatency; preprocData.getPacketDropPortion = &GetSnortPacketDropPortion; preprocData.loadAllLibs = &LoadAllLibs; preprocData.openDynamicLibrary = &openDynamicLibrary; preprocData.getSymbol = &getSymbol; preprocData.closeDynamicLibrary = &CloseDynamicLibrary; preprocData.getHttpXffFields = &GetHttpXffFields; #if defined(FEAT_OPEN_APPID) preprocData.appIdApi = &appIdApi; preprocData.registerIsAppIdRequired = ®isterIsAppIdRequired; preprocData.unregisterIsAppIdRequired = &unregisterIsAppIdRequired; preprocData.isAppIdRequired = &isAppIdRequired; #endif /* defined(FEAT_OPEN_APPID) */ preprocData.isReadMode = DynamicIsReadMode; preprocData.isTestMode = &DynamicIsTestMode; preprocData.getCurrentSnortConfig = GetCurrentSnortConfig; preprocData.pkt_tracer_enabled = &pkt_trace_enabled; preprocData.trace = trace_line; preprocData.traceMax = MAX_TRACE_LINE; preprocData.addPktTrace = DynamicAddPktTraceData; preprocData.getPktTraceActionMsg = DynamicGetPktTraceActionMsg; preprocData.setIPRepUpdateCount = DynamicSetIPRepUpdateCount; #if defined(DAQ_CAPA_CST_TIMEOUT) preprocData.canGetTimeout = DynamicCanGetTimeout; preprocData.registerGetDaqCapaTimeout = RegisterGetDaqCapaTimeout; #endif #ifdef SNORT_RELOAD preprocData.reloadAdjustRegister = DynamicReloadAdjustRegister; #endif #ifdef DAQ_MODFLOW_TYPE_PRESERVE_FLOW preprocData.setPreserveFlow = setPreserveFlow; #endif preprocData.registerMemoryStatsFunc = RegisterMemoryStatsFunction; preprocData.snortAlloc = SnortPreprocAlloc; preprocData.snortFree = SnortPreprocFree; preprocData.registerReputationProcessExternal = ®isterReputationProcessExternal; preprocData.reputation_process_external_ip = &_reputation_process_external_ip; preprocData.registerFtpmodeQuery = ®isterFtpModeQuery; preprocData.ftpGetMode = &ftpGetDataSessionMode; return InitDynamicPreprocessorPlugins(&preprocData); } int InitDynamicDetectionPlugins(SnortConfig *sc) { DynamicDetectionPlugin *plugin; if (sc == NULL) return -1; VerifyDetectionPluginRequirements(sc); plugin = sc->loadedDetectionPlugins; while (plugin) { if (plugin->initFunc(sc)) { ErrorMessage("Failed to initialize dynamic detection library: " "%s version %d.%d.%d\n", plugin->metaData.uniqueName, plugin->metaData.major, plugin->metaData.minor, plugin->metaData.build); return -1; } plugin = plugin->next; } return 0; } int DumpDetectionLibRules(SnortConfig *sc) { DynamicDetectionPlugin *plugin = sc->loadedDetectionPlugins; DumpDetectionRules ruleDumpFunc = NULL; int retVal = 0; int dumped = 0; LogMessage("Dumping dynamic rules...\n"); while (plugin) { ruleDumpFunc = (DumpDetectionRules) getSymbol(plugin->handle, "DumpSkeletonRules", &(plugin->metaData), NONFATAL); LogMessage("Dumping dynamic rules for Library %s %d.%d.%d\n", plugin->metaData.uniqueName, plugin->metaData.major, plugin->metaData.minor, plugin->metaData.build); if (ruleDumpFunc != NULL) { if (ruleDumpFunc()) { LogMessage("Failed to dump the rules for Library %s %d.%d.%d\n", plugin->metaData.uniqueName, plugin->metaData.major, plugin->metaData.minor, plugin->metaData.build); dumped = 1; } } plugin = plugin->next; } if( dumped == 0) { LogMessage(" Finished dumping dynamic rules.\n"); } return retVal; } int LoadDynamicPreprocessor(SnortConfig *sc, const char * const library_name, int indent) { DynamicPluginMeta metaData; /* Presume here, that library name is full path */ InitPreprocessorLibFunc preprocInit; PluginHandle handle; LogMessage("%sLoading dynamic preprocessor library %s... ", indent ? " " : "", library_name); handle = openDynamicLibrary(library_name, 0); metaData.libraryPath = (char *) library_name; GetPluginVersion(handle, &metaData); /* Just to ensure that the function exists */ preprocInit = (InitPreprocessorLibFunc) getSymbol(handle, "InitializePreprocessor", &metaData, FATAL); if (metaData.type != TYPE_PREPROCESSOR) { CloseDynamicLibrary(handle); LogMessage("failed, not a preprocessor library\n"); return 0; } AddPreprocessorPlugin(handle, preprocInit, &metaData); LogMessage("done\n"); return 0; } void LoadAllDynamicPreprocessors(SnortConfig *sc, const char * const path) { LogMessage("Loading all dynamic preprocessor libs from %s...\n", path); LoadAllLibs(sc, path, LoadDynamicPreprocessor); LogMessage(" Finished Loading all dynamic preprocessor libs from %s\n", path); } void CloseDynamicPreprocessorLibs(void) { DynamicPreprocessorPlugin *tmpplugin, *plugin = loadedPreprocessorPlugins; while (plugin) { tmpplugin = plugin->next; CloseDynamicLibrary(plugin->handle); free(plugin->metaData.libraryPath); free(plugin); plugin = tmpplugin; } loadedPreprocessorPlugins = NULL; } void *GetNextEnginePluginVersion(void *p) { DynamicEnginePlugin *lib = (DynamicEnginePlugin *) p; if ( lib != NULL ) { lib = lib->next; } else { lib = loadedEngines; } if ( lib == NULL ) { return lib; } return (void *) lib; } void *GetNextDetectionPluginVersion(SnortConfig *sc, void *p) { DynamicDetectionPlugin *lib = (DynamicDetectionPlugin *) p; if ( lib != NULL ) { lib = lib->next; } else { lib = sc->loadedDetectionPlugins; } if ( lib == NULL ) { return lib; } return (void *) lib; } void *GetNextPreprocessorPluginVersion(void *p) { DynamicPreprocessorPlugin *lib = (DynamicPreprocessorPlugin *) p; if ( lib != NULL ) { lib = lib->next; } else { lib = loadedPreprocessorPlugins; } if ( lib == NULL ) { return lib; } return (void *) lib; } DynamicPluginMeta *GetDetectionPluginMetaData(void *p) { DynamicDetectionPlugin *lib = (DynamicDetectionPlugin *) p; DynamicPluginMeta *meta; meta = &(lib->metaData); return meta; } DynamicPluginMeta *GetEnginePluginMetaData(void *p) { DynamicEnginePlugin *lib = (DynamicEnginePlugin *) p; DynamicPluginMeta *meta; meta = &(lib->metaData); return meta; } DynamicPluginMeta *GetPreprocessorPluginMetaData(void *p) { DynamicPreprocessorPlugin *lib = (DynamicPreprocessorPlugin *) p; DynamicPluginMeta *meta; meta = &(lib->metaData); return meta; } #ifdef SIDE_CHANNEL /* * Dynamic Side Channel Plugin Support */ typedef struct _DynamicSideChannelPlugin { PluginHandle handle; DynamicPluginMeta metaData; InitSideChannelLibFunc initFunc; struct _DynamicSideChannelPlugin *next; struct _DynamicSideChannelPlugin *prev; } DynamicSideChannelPlugin; static DynamicSideChannelPlugin *loadedSideChannelPlugins = NULL; void AddSideChannelPlugin(PluginHandle handle, InitSideChannelLibFunc initFunc, DynamicPluginMeta *meta) { DynamicSideChannelPlugin *newPlugin = NULL; newPlugin = (DynamicSideChannelPlugin *)SnortAlloc(sizeof(DynamicSideChannelPlugin)); newPlugin->handle = handle; if (!loadedSideChannelPlugins) { loadedSideChannelPlugins = newPlugin; } else { newPlugin->next = loadedSideChannelPlugins; loadedSideChannelPlugins->prev = newPlugin; loadedSideChannelPlugins = newPlugin; } memcpy(&(newPlugin->metaData), meta, sizeof(DynamicPluginMeta)); newPlugin->metaData.libraryPath = SnortStrdup(meta->libraryPath); newPlugin->initFunc = initFunc; } void RemoveSideChannelPlugin(DynamicSideChannelPlugin *plugin) { if (!plugin) return; if (plugin == loadedSideChannelPlugins) { loadedSideChannelPlugins = loadedSideChannelPlugins->next; loadedSideChannelPlugins->prev = NULL; } else { if (plugin->prev) plugin->prev->next = plugin->next; if (plugin->next) plugin->next->prev = plugin->prev; } LogMessage("Unloading dynamic side channel library %s version %d.%d.%d\n", plugin->metaData.uniqueName, plugin->metaData.major, plugin->metaData.minor, plugin->metaData.build); CloseDynamicLibrary(plugin->handle); if (plugin->metaData.libraryPath != NULL) free(plugin->metaData.libraryPath); free(plugin); } int LoadDynamicSideChannelLib(SnortConfig *sc, const char * const library_name, int indent) { DynamicPluginMeta metaData; /* Presume here, that library name is full path */ InitSideChannelLibFunc sideChannelInit; PluginHandle handle; LogMessage("%sLoading dynamic side channel library %s... ", indent ? " " : "", library_name); handle = openDynamicLibrary(library_name, 0); metaData.libraryPath = (char *) library_name; GetPluginVersion(handle, &metaData); /* Just to ensure that the function exists */ sideChannelInit = (InitSideChannelLibFunc)getSymbol(handle, "InitializeSideChannel", &metaData, FATAL); if (!(metaData.type & TYPE_SIDE_CHANNEL)) { CloseDynamicLibrary(handle); LogMessage("failed, not a side channel library\n"); return 0; } AddSideChannelPlugin(handle, sideChannelInit, &metaData); LogMessage("done\n"); return 0; } void CloseDynamicSideChannelLibs(void) { DynamicSideChannelPlugin *tmpplugin, *plugin = loadedSideChannelPlugins; while (plugin) { tmpplugin = plugin->next; CloseDynamicLibrary(plugin->handle); free(plugin->metaData.libraryPath); free(plugin); plugin = tmpplugin; } loadedSideChannelPlugins = NULL; } void LoadAllDynamicSideChannelLibs(SnortConfig *sc, const char * const path) { LogMessage("Loading all dynamic side channel libs from %s...\n", path); LoadAllLibs(sc, path, LoadDynamicSideChannelLib); LogMessage(" Finished Loading all dynamic side channel libs from %s\n", path); } int InitDynamicSideChannelPlugins(void) { DynamicSideChannelPlugin *plugin; DynamicSideChannelData sideChannelData; RemoveDuplicateSideChannelPlugins(); sideChannelData.version = SIDE_CHANNEL_DATA_VERSION; sideChannelData.size = sizeof(DynamicSideChannelData); sideChannelData.registerModule = &RegisterSideChannelModule; sideChannelData.registerRXHandler = &SideChannelRegisterRXHandler; sideChannelData.registerTXHandler = &SideChannelRegisterTXHandler; sideChannelData.unregisterRXHandler = &SideChannelUnregisterRXHandler; sideChannelData.unregisterTXHandler = &SideChannelUnregisterTXHandler; sideChannelData.allocMessageRX = &SideChannelPreallocMessageRX; sideChannelData.allocMessageTX = &SideChannelPreallocMessageTX; sideChannelData.discardMessageRX = &SideChannelDiscardMessageRX; sideChannelData.discardMessageTX = &SideChannelDiscardMessageTX; sideChannelData.enqueueMessageRX = &SideChannelEnqueueMessageRX; sideChannelData.enqueueMessageTX = &SideChannelEnqueueMessageTX; sideChannelData.enqueueDataRX = &SideChannelEnqueueDataRX; sideChannelData.enqueueDataTX = &SideChannelEnqueueDataTX; sideChannelData.getSnortInstance = &DynamicGetSnortInstance; sideChannelData.snortSignalMask = &DynamicSnortSignalMask; sideChannelData.logMsg = &LogMessage; sideChannelData.errMsg = &ErrorMessage; sideChannelData.fatalMsg = &FatalError; sideChannelData.debugMsg = &DebugMessageFunc; plugin = loadedSideChannelPlugins; while (plugin) { if (plugin->initFunc(&sideChannelData)) { ErrorMessage("Failed to initialize dynamic side channel library: %s version %d.%d.%d\n", plugin->metaData.uniqueName, plugin->metaData.major, plugin->metaData.minor, plugin->metaData.build); return -1; } plugin = plugin->next; } return 0; } void *GetNextSideChannelPluginVersion(void *p) { DynamicSideChannelPlugin *lib = (DynamicSideChannelPlugin *) p; if (lib != NULL) lib = lib->next; else lib = loadedSideChannelPlugins; if (lib == NULL) return lib; return (void *) lib; } DynamicPluginMeta *GetSideChannelPluginMetaData(void *p) { DynamicSideChannelPlugin *lib = (DynamicSideChannelPlugin *) p; DynamicPluginMeta *meta; meta = &(lib->metaData); return meta; } void RemoveDuplicateSideChannelPlugins(void) { int removed = 0; DynamicSideChannelPlugin *lib1 = NULL; DynamicSideChannelPlugin *lib2 = NULL; DynamicPluginMeta *meta1; DynamicPluginMeta *meta2; /* Side Channel Plugins */ do { removed = 0; lib1 = loadedSideChannelPlugins; while (lib1 != NULL) { lib2 = loadedSideChannelPlugins; while (lib2 != NULL) { /* Obviously, the same ones will be the same */ if (lib1 != lib2) { meta1 = &lib1->metaData; meta2 = &lib2->metaData; if (!strcmp(meta1->uniqueName, meta2->uniqueName)) { /* Uh, same uniqueName. */ if ((meta1->major > meta2->major) || ((meta1->major == meta2->major) && (meta1->minor > meta2->minor)) || ((meta1->major == meta2->major) && (meta1->minor == meta2->minor) && (meta1->build > meta2->build)) ) { /* Lib1 is newer */ RemoveSideChannelPlugin(lib2); removed = 1; break; } else if ((meta2->major > meta1->major) || ((meta2->major == meta1->major) && (meta2->minor > meta1->minor)) || ((meta2->major == meta1->major) && (meta2->minor == meta1->minor) && (meta2->build > meta1->build)) ) { /* Lib2 is newer */ RemoveSideChannelPlugin(lib1); removed = 1; break; } else if ((meta1->major == meta2->major) && (meta1->minor == meta2->minor) && (meta1->build == meta2->build) ) { /* Duplicate */ RemoveSideChannelPlugin(lib2); removed = 1; break; } } } /* If we removed anything, start back at the beginning */ if (removed) break; lib2 = lib2->next; } /* If we removed anything, start back at the beginning */ if (removed) break; lib1 = lib1->next; } } while (removed); } #endif /* SIDE_CHANNEL */ #ifdef SNORT_RELOAD void AdjustSoRuleMemory(SnortConfig *new_config, SnortConfig *old_config) { tSfPolicyId policy_id = getParserPolicy(new_config); ada_reload_adjust_register(ada, policy_id, (void *) new_config, "so_rule", (size_t) new_config->so_rule_memcap); } void ReloadDynamicDetectionLibs(SnortConfig *sc) { uint32_t i; if (sc->dyn_rules != NULL) { /* Load the dynamic detection libs */ for (i = 0; i < sc->dyn_rules->count; i++) { switch (sc->dyn_rules->lib_paths[i]->ptype) { case PATH_TYPE__FILE: LoadDynamicDetectionLib(sc, sc->dyn_rules->lib_paths[i]->path, 0); break; case PATH_TYPE__DIRECTORY: LoadAllDynamicDetectionLibs(sc, sc->dyn_rules->lib_paths[i]->path); break; } } } } #endif snort-2.9.15.1/src/dynamic-plugins/sf_dynamic_preprocessor.h0000644000175200017520000006204113571422607021040 00000000000000/* * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2005-2013 Sourcefire, Inc. * * Author: Steven Sturges * * Dynamic Library Loading for Snort * */ #ifndef _SF_DYNAMIC_PREPROCESSOR_H_ #define _SF_DYNAMIC_PREPROCESSOR_H_ #include #ifdef SF_WCHAR #include #endif #include "sf_dynamic_meta.h" #include "ipv6_port.h" #include "obfuscation.h" /* specifies that a function does not return * used for quieting Visual Studio warnings */ #ifdef WIN32 #if _MSC_VER >= 1400 #define NORETURN __declspec(noreturn) #else #define NORETURN #endif #else #define NORETURN #endif #ifdef PERF_PROFILING #ifndef PROFILE_PREPROCS_NOREDEF /* Don't redefine this from the main area */ #ifdef PROFILING_PREPROCS #undef PROFILING_PREPROCS #endif #define PROFILING_PREPROCS _dpd.profilingPreprocsFunc() #endif #endif #define PREPROCESSOR_DATA_VERSION 25 #include "sf_dynamic_common.h" #include "sf_dynamic_engine.h" #include "session_api.h" #include "stream_api.h" #include "str_search.h" #include "obfuscation.h" /*#include "sfportobject.h" */ #include "sfcontrol.h" #ifdef SIDE_CHANNEL #include "sidechannel_define.h" #endif #include "idle_processing.h" #include "file_api.h" #include "reload_api.h" struct _PreprocStats; #define MINIMUM_DYNAMIC_PREPROC_ID 10000 typedef void (*PreprocessorInitFunc)(struct _SnortConfig *, char *); typedef void * (*AddPreprocFunc)(struct _SnortConfig *, void (*pp_func)(void *, void *), uint16_t, uint32_t, uint32_t); typedef void * (*AddMetaEvalFunc)(struct _SnortConfig *, void (*meta_eval_func)(int, const uint8_t *), uint16_t priority, uint32_t preproc_id); typedef void (*AddPreprocExit)(void (*pp_exit_func) (int, void *), void *arg, uint16_t, uint32_t); typedef void (*AddPreprocUnused)(void (*pp_unused_func) (int, void *), void *arg, uint16_t, uint32_t); typedef void (*AddPreprocConfCheck)(struct _SnortConfig *, int (*pp_conf_chk_func) (struct _SnortConfig *)); typedef void (*AddToPostConfList)(struct _SnortConfig *sc, void (*post_config_func)(struct _SnortConfig *, int , void *), void *arg); typedef int (*AlertQueueAdd)(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, const char *, void *); typedef uint32_t (*GenSnortEvent)(Packet *p, uint32_t gid, uint32_t sid, uint32_t rev, uint32_t classification, uint32_t priority, const char *msg); #ifdef SNORT_RELOAD typedef void (*PreprocessorReloadFunc)(struct _SnortConfig *, char *, void **); typedef int (*PreprocessorReloadVerifyFunc)(struct _SnortConfig *, void *); typedef void * (*PreprocessorReloadSwapFunc)(struct _SnortConfig *, void *); typedef void (*PreprocessorReloadSwapFreeFunc)(void *); #endif #ifndef SNORT_RELOAD typedef void (*PreprocRegisterFunc)(const char *, PreprocessorInitFunc); #else typedef void (*PreprocRegisterFunc)(const char *, PreprocessorInitFunc, PreprocessorReloadFunc, PreprocessorReloadVerifyFunc, PreprocessorReloadSwapFunc, PreprocessorReloadSwapFreeFunc); typedef void *(*GetRelatedReloadDataFunc)(struct _SnortConfig *, const char *); #endif typedef int (*ThresholdCheckFunc)(unsigned int, unsigned int, sfaddr_t*, sfaddr_t*, long); typedef void (*InlineDropFunc)(void *); typedef bool (*ActivePacketWasDroppedFunc)(void); typedef bool (*InlineRetryFunc)(void *); typedef void (*ActiveEnableFunc)(int); typedef void (*DisableDetectFunc)(void *); typedef void (*EnableDetectFunc)(void ); typedef int (*EnablePreprocessorFunc)(void *, uint32_t); typedef int (*DetectFunc)(void *); typedef void *(*GetRuleInfoByNameFunc)(char *); typedef void *(*GetRuleInfoByIdFunc)(int); typedef int (*printfappendfunc)(char *, int, const char *, ...); typedef char ** (*TokenSplitFunc)(const char *, const char *, const int, int *, const char); typedef void (*TokenFreeFunc)(char ***, int); typedef void (*PreprocStatsNodeFreeFunc)(struct _PreprocStats *stats); typedef void (*AddPreprocProfileFunc)(const char *, void *, int, void *, PreprocStatsNodeFreeFunc freefn); typedef int (*ProfilingFunc)(void); typedef int (*PreprocessFunc)(void *); #ifdef DUMP_BUFFER typedef void (*BufferDumpRegisterFunc)(TraceBuffer * (*)(), unsigned int); #endif typedef void (*PreprocStatsRegisterFunc)(const char *, void (*pp_stats_func)(int)); typedef void (*AddPreprocReset)(void (*pp_rst_func) (int, void *), void *arg, uint16_t, uint32_t); typedef void (*AddPreprocResetStats)(void (*pp_rst_stats_func) (int, void *), void *arg, uint16_t, uint32_t); typedef void (*AddPreprocReassemblyPktFunc)(void * (*pp_reass_pkt_func)(void), uint32_t); typedef int (*SetPreprocReassemblyPktBitFunc)(void *, uint32_t); typedef void (*DisablePreprocessorsFunc)(void *); typedef char** (*DynamicGetHttpXffFieldsFunc)(int* nFields); #ifdef TARGET_BASED typedef int16_t (*FindProtocolReferenceFunc)(const char *); typedef int16_t (*AddProtocolReferenceFunc)(const char *); #if defined(FEAT_OPEN_APPID) typedef const char * (*FindProtocolNameFunc)(int16_t); #endif /* defined(FEAT_OPEN_APPID) */ typedef int (*IsAdaptiveConfiguredFunc)(void); typedef int (*IsAdaptiveConfiguredForSnortConfigFunc)(struct _SnortConfig *); #endif typedef void (*IP6BuildFunc)(void *, const void *, int); #define SET_CALLBACK_IP 0 #define SET_CALLBACK_ICMP_ORIG 1 typedef void (*IP6SetCallbacksFunc)(void *, int, char); typedef void (*AddKeywordOverrideFunc)(struct _SnortConfig *, char *, char *, PreprocOptionInit, PreprocOptionEval, PreprocOptionCleanup, PreprocOptionHash, PreprocOptionKeyCompare, PreprocOptionOtnHandler, PreprocOptionFastPatternFunc); typedef void (*AddKeywordByteOrderFunc)(char *, PreprocOptionByteOrderFunc); typedef int (*IsPreprocEnabledFunc)(struct _SnortConfig *, uint32_t); typedef char * (*PortArrayFunc)(char *, PortObject *, int *); typedef int (*AlertQueueLog)(void *); typedef void (*AlertQueueControl)(void); /* reset, push, and pop */ typedef void (*SetPolicyFunc)(struct _SnortConfig *, tSfPolicyId); typedef tSfPolicyId (*GetPolicyFromIdFunc)(uint16_t ); typedef void (*ChangePolicyFunc)(tSfPolicyId, void *p); typedef void (*SetFileDataPtrFunc)(uint8_t *,uint16_t ); typedef void (*DetectResetFunc)(uint8_t *,uint16_t ); typedef void (*SetAltDecodeFunc)(uint16_t ); typedef void (*DetectFlagEnableFunc)(SFDetectFlagType); typedef long (*DynamicStrtol)(const char *, char **, int); typedef unsigned long(*DynamicStrtoul)(const char *, char **, int); typedef const char* (*DynamicStrnStr)(const char *, int, const char *); typedef const char* (*DynamicStrcasestr)(const char *, int, const char *); typedef int (*DynamicStrncpy)(char *, const char *, size_t ); typedef const char* (*DynamicStrnPbrk)(const char *, int , const char *); typedef int (*EvalRTNFunc)(void *rtn, void *p, int check_ports); typedef void* (*EncodeNew)(void); typedef void (*EncodeDelete)(void*); typedef void (*EncodeUpdate)(void*); typedef int (*EncodeFormat)(uint32_t, const void*, void*, int); typedef void* (*NewGrinderPktPtr)(void *, void *, uint8_t *); typedef void (*DeleteGrinderPktPtr)(void*); typedef bool (*PafEnabledFunc)(void); typedef time_t (*SCPacketTimeFunc)(void); typedef void (*SCGetPktTimeOfDay)(struct timeval *tv); #ifdef SIDE_CHANNEL typedef bool (*SCEnabledFunc)(void); typedef int (*SCRegisterRXHandlerFunc)(uint16_t type, SCMProcessMsgFunc processMsgFunc, void *data); typedef int (*SCPreallocMessageTXFunc)(uint32_t length, SCMsgHdr **hdr, uint8_t **msg_ptr, void **msg_handle); typedef int (*SCEnqueueMessageTXFunc)(SCMsgHdr *hdr, const uint8_t *msg, uint32_t length, void *msg_handle, SCMQMsgFreeFunc msgFreeFunc); #endif typedef char* (*GetLogDirectory)(void); typedef int (*ControlSocketRegisterHandlerFunc)(uint16_t, OOBPreControlFunc, IBControlFunc, OOBPostControlFunc); typedef int (*RegisterIdleHandler)(IdleProcessingHandler); #ifdef ACTIVE_RESPONSE #define SND_BLK_RESP_FLAG_DO_CLIENT 1 #define SND_BLK_RESP_FLAG_DO_SERVER 2 typedef void (*DynamicSendBlockResponse)(void *packet, const uint8_t* buffer, uint32_t buffer_len, unsigned flags); typedef void (*ActiveInjectDataFunc)(void *, uint32_t, const uint8_t *, uint32_t); typedef void (*ActiveSendForwardResetFunc)(void *); typedef void (*ActiveResponseFunc )(void *, const uint8_t *, uint32_t , uint32_t); // NOTE: DynamicActive_ResponseFunc must match func ptr def Active_ResponseFunc in active.h typedef void (*DynamicActive_ResponseFunc)(Packet *packet, void* data); typedef int (*ActiveQueueResponseFunc )(DynamicActive_ResponseFunc cb, void *); #endif typedef int (*DynamicSetFlowId)(const void* p, uint32_t id); #ifdef HAVE_DAQ_EXT_MODFLOW typedef int (*DynamicModifyFlow)(const DAQ_PktHdr_t *hdr, const DAQ_ModFlow_t* mod); #endif #ifdef HAVE_DAQ_QUERYFLOW typedef int (*DynamicQueryFlow)(const DAQ_PktHdr_t *hdr, DAQ_QueryFlow_t* query); #endif #if defined(DAQ_VERSION) && DAQ_VERSION > 8 typedef void (*DynamicDebugPkt)(uint8_t moduleId, uint8_t logLevel, const DAQ_Debug_Packet_Params_t *params, const char *msg, ...); #endif #if defined(DAQ_VERSION) && DAQ_VERSION > 9 typedef int (*DynamicIoctl)(unsigned int type, char *buffer, size_t *len); #endif typedef int (*DynamicIsStrEmpty)(const char * ); typedef void (*AddPeriodicCheck)(void (*pp_check_func) (int, void *), void *arg, uint16_t, uint32_t, uint32_t); typedef void (*AddPostConfigFuncs)(struct _SnortConfig *, void (*pp_post_config_func) (struct _SnortConfig *, void *), void *arg); typedef int (*AddOutPutModule)(const char *filename); typedef int (*CanWhitelist)(void); #if defined(DAQ_CAPA_CST_TIMEOUT) typedef bool (*CanGetTimeout)(void); typedef void (*GetDaqCapaTimeOutFunc)(bool); typedef void (*RegisterGetDaqCapaTimeoutFunc)(GetDaqCapaTimeOutFunc); GetDaqCapaTimeOutFunc getDaqCapaTimeoutFnPtr; #endif typedef void (*DisableAllPoliciesFunc)(struct _SnortConfig *); typedef int (*ReenablePreprocBitFunc)(struct _SnortConfig *, unsigned int preproc_id); typedef int (*DynamicCheckValueInRangeFunc)(const char *, char *, unsigned long lo, unsigned long hi, unsigned long *value); typedef bool (*DynamicReadyForProcessFunc) (void* pkt); typedef int (*SslAppIdLookupFunc)(void * ssnptr, const char * serverName, const char * commonName, int32_t *serviceAppId, int32_t *clientAppId, int32_t *payloadAppId); typedef void (*RegisterSslAppIdLookupFunc)(SslAppIdLookupFunc); typedef int32_t (*GetAppIdFunc)(void *ssnptr); typedef void (*RegisterGetAppIdFunc)(GetAppIdFunc); typedef struct urlQueryContext* (*UrlQueryCreateFunc)(const char *url); typedef void (*UrlQueryDestroyFunc)(struct urlQueryContext *context); typedef int (*UrlQueryMatchFunc)(void *ssnptr, struct urlQueryContext *context, uint16_t inUrlCat, uint16_t inUrlMinRep, uint16_t inUrlMaxRep); typedef void (*RegisterUrlQueryFunc)(UrlQueryCreateFunc, UrlQueryDestroyFunc,UrlQueryMatchFunc); typedef int (*UserGroupIdGetFunc)(void *ssnptr, uint32_t *userId, uint32_t *realmId, unsigned *groupIdArray, unsigned groupIdArrayLen); typedef void (*RegisterUserGroupIdGetFunc)(UserGroupIdGetFunc); typedef int (*GeoIpAddressLookupFunc)(const sfaddr_t *snortIp, uint16_t *geo); typedef void (*RegisterGeoIpAddressLookupFunc)(GeoIpAddressLookupFunc); typedef void (*UpdateSSLSSnLogDataFunc)(void *ssnptr, uint8_t logging_on, uint8_t action_is_block, const char *ssl_cert_fingerprint, uint32_t ssl_cert_fingerprint_len, uint32_t ssl_cert_status, uint8_t *ssl_policy_id, uint32_t ssl_policy_id_len, uint32_t ssl_rule_id, uint16_t ssl_cipher_suite, uint8_t ssl_version, uint16_t ssl_actual_action, uint16_t ssl_expected_action, uint32_t ssl_url_category, uint16_t ssl_flow_status, uint32_t ssl_flow_error, uint32_t ssl_flow_messages, uint64_t ssl_flow_flags, char *ssl_server_name, uint8_t *ssl_session_id, uint8_t session_id_len, uint8_t *ssl_ticket_id, uint8_t ticket_id_len); typedef void (*RegisterUpdateSSLSSnLogDataFunc)(UpdateSSLSSnLogDataFunc); typedef void (*EndSSLSSnLogDataFunc)(void *ssnptr, uint32_t ssl_flow_messages, uint64_t ssl_flow_flags) ; typedef void (*RegisterEndSSLSSnLogDataFunc)(EndSSLSSnLogDataFunc); typedef int (*GetSSLActualActionFunc)(void *ssnptr, uint16_t *action); typedef void (*RegisterGetSSLActualActionFunc)(GetSSLActualActionFunc); typedef void (*GetIntfDataFunc)(void *ssnptr,int32_t *ingressIntfIndex, int32_t *egressIntfIndex, int32_t *ingressZoneIndex, int32_t *egressZoneIndex) ; typedef void (*RegisterGetIntfDataFunc)(GetIntfDataFunc); // // SSL Callbacks // typedef bool (*DynamicIsSSLPolicyEnabledFunc)(struct _SnortConfig *sc); typedef void (*DynamicSetSSLPolicyEnabledFunc)(struct _SnortConfig *sc, tSfPolicyId policy, bool value); typedef void (*SetSSLCallbackFunc)(void *); typedef void* (*GetSSLCallbackFunc)(void); typedef int (*_LoadLibraryFunc)(struct _SnortConfig *sc, const char * const path, int indent); typedef void (*LoadAllLibsFunc)(struct _SnortConfig *sc, const char * const path, _LoadLibraryFunc loadFunc); typedef void * _PluginHandle; typedef _PluginHandle (*OpenDynamicLibraryFunc)(const char * const library_name, int useGlobal); typedef void (*_dlsym_func)(void); typedef _dlsym_func (*GetSymbolFunc)(_PluginHandle handle, char * symbol, DynamicPluginMeta * meta, int fatal); typedef void (*CloseDynamicLibraryFunc)(_PluginHandle handle); #if defined(FEAT_OPEN_APPID) typedef bool (*IsAppIdRequiredFunc)(void); typedef void (*RegisterIsAppIdRequiredFunc)(IsAppIdRequiredFunc); typedef void (*UnregisterIsAppIdRequiredFunc)(IsAppIdRequiredFunc); struct AppIdApi; #endif /* defined(FEAT_OPEN_APPID) */ typedef bool (*ReadModeFunc)(void); typedef int (*GetPerfIndicatorsFunc)(void *Request); typedef uint32_t (*GetSnortPacketLatencyFunc)(void); typedef double (*GetSnortPacketDropPortionFunc)(void); typedef bool (*IsTestModeFunc)(void); typedef struct _SnortConfig* (*GetCurrentSnortConfigFunc)(void); typedef void (*AddPktTraceDataFunc)(int module, int traceLen); typedef const char* (*GetPktTraceActionMsgFunc)(); #ifdef SNORT_RELOAD typedef int (*ReloadAdjustRegisterFunc)(struct _SnortConfig* sc, const char* raName, tSfPolicyId raPolicyId, ReloadAdjustFunc raFunc, void *raUserData, ReloadAdjustUserFreeFunc raUserFreeFunc); #endif typedef int (*DynamicSetPreserveFlow)(const void* p); // IPrep Last update count typedef void (*IprepUpdateCountFunc)(uint8_t); typedef int (*RegisterMemoryStatsFunc)(uint preproc, char* preproc_name, int (*MemoryStatsDisplayFunc)(char *buffer)); typedef void* (*SnortAllocFunc)(int num, unsigned long size, uint32_t preproc, bool data); typedef void (*SnortFreeFunc)(void * ptr, uint32_t size, uint32_t preproc, bool data); typedef bool (*ReputationProcessExternalIpFunc)(void *p, sfaddr_t* ip); typedef void (*RegisterReputationProcessExternalFunc)(ReputationProcessExternalIpFunc); /* FTP data transfer mode */ typedef bool (*ftpGetModefunc)(void *ssnptr); typedef void (*RegisterFtpQueryModefunc)(ftpGetModefunc); #define ENC_DYN_FWD 0x80000000 #define ENC_DYN_NET 0x10000000 /* Info Data passed to dynamic preprocessor plugin must include: * version * Pointer to AltDecodeBuffer * Pointer to HTTP URI Buffers * Pointer to functions to log Messages, Errors, Fatal Errors * Pointer to function to add preprocessor to list of configure Preprocs * Pointer to function to regsiter preprocessor configuration keyword * Pointer to function to create preprocessor alert */ typedef struct _DynamicPreprocessorData { int version; int size; SFDataBuffer *altBuffer; SFDataPointer *altDetect; SFDataPointer *fileDataBuf; LogMsgFunc logMsg; LogMsgFunc errMsg; LogMsgFunc fatalMsg; DebugMsgFunc debugMsg; PreprocRegisterFunc registerPreproc; #ifdef SNORT_RELOAD GetRelatedReloadDataFunc getRelatedReloadData; #endif AddPreprocFunc addPreproc; AddPreprocFunc addPreprocAllPolicies; GetSnortInstance getSnortInstance; AddPreprocExit addPreprocExit; AddPreprocConfCheck addPreprocConfCheck; RegisterPreprocRuleOpt preprocOptRegister; AddPreprocProfileFunc addPreprocProfileFunc; ProfilingFunc profilingPreprocsFunc; void *totalPerfStats; AlertQueueAdd alertAdd; GenSnortEvent genSnortEvent; ThresholdCheckFunc thresholdCheck; #ifdef ACTIVE_RESPONSE ActiveEnableFunc activeSetEnabled; #endif DetectFunc detect; DisableDetectFunc disableDetect; DisableDetectFunc disableAllDetect; DisableDetectFunc disablePacketAnalysis; EnableDetectFunc enableContentDetect; EnablePreprocessorFunc enablePreprocessor; SessionAPI *sessionAPI; StreamAPI *streamAPI; SearchAPI *searchAPI; char **config_file; int *config_line; printfappendfunc printfappend; TokenSplitFunc tokenSplit; TokenFreeFunc tokenFree; GetRuleInfoByNameFunc getRuleInfoByName; GetRuleInfoByIdFunc getRuleInfoById; #ifdef SF_WCHAR DebugWideMsgFunc debugWideMsg; #endif PreprocessFunc preprocess; #ifdef DUMP_BUFFER BufferDumpRegisterFunc registerBufferTracer; #endif char **debugMsgFile; int *debugMsgLine; PreprocStatsRegisterFunc registerPreprocStats; AddPreprocReset addPreprocReset; AddPreprocResetStats addPreprocResetStats; DisablePreprocessorsFunc disablePreprocessors; IP6BuildFunc ip6Build; IP6SetCallbacksFunc ip6SetCallbacks; AlertQueueLog logAlerts; AlertQueueControl resetAlerts; AlertQueueControl pushAlerts; AlertQueueControl popAlerts; #ifdef TARGET_BASED FindProtocolReferenceFunc findProtocolReference; AddProtocolReferenceFunc addProtocolReference; IsAdaptiveConfiguredFunc isAdaptiveConfigured; IsAdaptiveConfiguredForSnortConfigFunc isAdaptiveConfiguredForSnortConfig; #endif AddKeywordOverrideFunc preprocOptOverrideKeyword; AddKeywordByteOrderFunc preprocOptByteOrderKeyword; IsPreprocEnabledFunc isPreprocEnabled; PortArrayFunc portObjectCharPortArray; GetPolicyFunc getNapRuntimePolicy; GetPolicyFunc getIpsRuntimePolicy; GetParserPolicyFunc getParserPolicy; GetPolicyFunc getDefaultPolicy; SetPolicyFunc setParserPolicy; SetFileDataPtrFunc setFileDataPtr; DetectResetFunc DetectReset; SetAltDecodeFunc SetAltDecode; GetAltDetectFunc GetAltDetect; SetAltDetectFunc SetAltDetect; IsDetectFlagFunc Is_DetectFlag; DetectFlagDisableFunc DetectFlag_Disable; DynamicStrtol SnortStrtol; DynamicStrtoul SnortStrtoul; DynamicStrnStr SnortStrnStr; DynamicStrncpy SnortStrncpy; DynamicStrnPbrk SnortStrnPbrk; DynamicStrcasestr SnortStrcasestr; EvalRTNFunc fpEvalRTN; ObfuscationApi *obApi; EncodeNew encodeNew; EncodeDelete encodeDelete; EncodeFormat encodeFormat; EncodeUpdate encodeUpdate; NewGrinderPktPtr newGrinderPkt; DeleteGrinderPktPtr deleteGrinderPkt; AddPreprocFunc addDetect; PafEnabledFunc isPafEnabled; SCPacketTimeFunc pktTime; SCGetPktTimeOfDay getPktTimeOfDay; #ifdef SIDE_CHANNEL SCEnabledFunc isSCEnabled; SCRegisterRXHandlerFunc scRegisterRXHandler; SCPreallocMessageTXFunc scAllocMessageTX; SCEnqueueMessageTXFunc scEnqueueMessageTX; #endif GetLogDirectory getLogDirectory; ControlSocketRegisterHandlerFunc controlSocketRegisterHandler; RegisterIdleHandler registerIdleHandler; GetPolicyFromIdFunc getPolicyFromId; ChangePolicyFunc changeNapRuntimePolicy; ChangePolicyFunc changeIpsRuntimePolicy; InlineDropFunc inlineDropPacket; InlineDropFunc inlineForceDropPacket; InlineDropFunc inlineDropSessionAndReset; InlineDropFunc inlineForceDropSession; InlineDropFunc inlineForceDropSessionAndReset; ActivePacketWasDroppedFunc active_PacketWasDropped; InlineRetryFunc inlineRetryPacket; DynamicIsStrEmpty SnortIsStrEmpty; AddMetaEvalFunc addMetaEval; #ifdef ACTIVE_RESPONSE DynamicSendBlockResponse dynamicSendBlockResponse; #endif DynamicSetFlowId dynamicSetFlowId; #ifdef HAVE_DAQ_EXT_MODFLOW DynamicModifyFlow dynamicModifyFlow; #endif #ifdef HAVE_DAQ_QUERYFLOW DynamicQueryFlow dynamicQueryFlow; #endif #if defined(DAQ_VERSION) && DAQ_VERSION > 8 DynamicDebugPkt dynamicDebugPkt; #endif #if defined(DAQ_VERSION) && DAQ_VERSION > 9 DynamicIoctl dynamicIoctl; #endif AddPeriodicCheck addPeriodicCheck; AddPostConfigFuncs addPostConfigFunc; AddToPostConfList addFuncToPostConfigList; char **snort_conf_dir; AddOutPutModule addOutputModule; CanWhitelist canWhitelist; FileAPI *fileAPI; DisableAllPoliciesFunc disableAllPolicies; ReenablePreprocBitFunc reenablePreprocBit; DynamicCheckValueInRangeFunc checkValueInRange; SetHttpBufferFunc setHttpBuffer; GetHttpBufferFunc getHttpBuffer; #ifdef ACTIVE_RESPONSE ActiveInjectDataFunc activeInjectData; ActiveResponseFunc activeSendResponse; ActiveSendForwardResetFunc activeSendForwardReset; ActiveQueueResponseFunc activeQueueResponse; #endif GetSSLCallbackFunc getSSLCallback; SetSSLCallbackFunc setSSLCallback; SslAppIdLookupFunc sslAppIdLookup; RegisterSslAppIdLookupFunc registerSslAppIdLookup; GetAppIdFunc getAppId; RegisterGetAppIdFunc registerGetAppId; UrlQueryCreateFunc urlQueryCreate; UrlQueryDestroyFunc urlQueryDestroy; UrlQueryMatchFunc urlQueryMatch; RegisterUrlQueryFunc registerUrlQuery; UserGroupIdGetFunc userGroupIdGet; RegisterUserGroupIdGetFunc registerUserGroupIdGet; GeoIpAddressLookupFunc geoIpAddressLookup; RegisterGeoIpAddressLookupFunc registerGeoIpAddressLookup; UpdateSSLSSnLogDataFunc updateSSLSSnLogData; RegisterUpdateSSLSSnLogDataFunc registerUpdateSSLSSnLogData; EndSSLSSnLogDataFunc endSSLSSnLogData; RegisterEndSSLSSnLogDataFunc registerEndSSLSSnLogData; GetSSLActualActionFunc getSSLActualAction; RegisterGetSSLActualActionFunc registerGetSSLActualAction; GetIntfDataFunc getIntfData; RegisterGetIntfDataFunc registerGetIntfData; DynamicReadyForProcessFunc readyForProcess; DynamicIsSSLPolicyEnabledFunc isSSLPolicyEnabled; DynamicSetSSLPolicyEnabledFunc setSSLPolicyEnabled; /* Preproc's fetch Snort performance indicators. Used by IAB. */ GetPerfIndicatorsFunc getPerfIndicators; GetSnortPacketLatencyFunc getPacketLatency; GetSnortPacketDropPortionFunc getPacketDropPortion; LoadAllLibsFunc loadAllLibs; OpenDynamicLibraryFunc openDynamicLibrary; GetSymbolFunc getSymbol; CloseDynamicLibraryFunc closeDynamicLibrary; DynamicGetHttpXffFieldsFunc getHttpXffFields; #if defined(FEAT_OPEN_APPID) struct AppIdApi *appIdApi; RegisterIsAppIdRequiredFunc registerIsAppIdRequired; UnregisterIsAppIdRequiredFunc unregisterIsAppIdRequired; IsAppIdRequiredFunc isAppIdRequired; #endif /* defined(FEAT_OPEN_APPID) */ ReadModeFunc isReadMode; IsTestModeFunc isTestMode; GetCurrentSnortConfigFunc getCurrentSnortConfig; bool *pkt_tracer_enabled; char *trace; uint32_t traceMax; AddPktTraceDataFunc addPktTrace; GetPktTraceActionMsgFunc getPktTraceActionMsg; #ifdef SNORT_RELOAD ReloadAdjustRegisterFunc reloadAdjustRegister; #endif #ifdef DAQ_MODFLOW_TYPE_PRESERVE_FLOW DynamicSetPreserveFlow setPreserveFlow; #endif IprepUpdateCountFunc setIPRepUpdateCount; RegisterMemoryStatsFunc registerMemoryStatsFunc; SnortAllocFunc snortAlloc; SnortFreeFunc snortFree; #if defined(DAQ_CAPA_CST_TIMEOUT) CanGetTimeout canGetTimeout; RegisterGetDaqCapaTimeoutFunc registerGetDaqCapaTimeout; #endif ReputationProcessExternalIpFunc reputation_process_external_ip; RegisterReputationProcessExternalFunc registerReputationProcessExternal; RegisterFtpQueryModefunc registerFtpmodeQuery; ftpGetModefunc ftpGetMode; } DynamicPreprocessorData; /* Function prototypes for Dynamic Preprocessor Plugins */ void CloseDynamicPreprocessorLibs(void); int LoadDynamicPreprocessor(struct _SnortConfig *sc, const char * const library_name, int indent); void LoadAllDynamicPreprocessors(struct _SnortConfig *sc, const char * const path); typedef int (*InitPreprocessorLibFunc)(DynamicPreprocessorData *); int InitDynamicPreprocessors(void); void RemoveDuplicatePreprocessorPlugins(void); /* This was necessary because of static code analysis not recognizing that * fatalMsg did not return - use instead of fatalMsg */ NORETURN void DynamicPreprocessorFatalMessage(const char *format, ...); extern DynamicPreprocessorData _dpd; #endif /* _SF_DYNAMIC_PREPROCESSOR_H_ */ snort-2.9.15.1/src/dynamic-plugins/sf_dynamic_side_channel.h0000644000175200017520000000754313571422607020734 00000000000000/* * * 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. * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2012-2013 Sourcefire, Inc. * * Author: Michael Altizer * * Dynamic Side Channel Lib function declarations * */ #ifndef _SF_DYNAMIC_SIDE_CHANNEL_H_ #define _SF_DYNAMIC_SIDE_CHANNEL_H_ #include #include "sf_dynamic_common.h" #include "sf_dynamic_meta.h" #include "sidechannel_define.h" #define SIDE_CHANNEL_DATA_VERSION 1 struct _SnortConfig; typedef int (*RegisterRXHandler)(uint16_t type, SCMProcessMsgFunc processMsgFunc, void *data); typedef int (*RegisterTXHandler)(uint16_t type, SCMProcessMsgFunc processMsgFunc, void *data); typedef void (*UnregisterRXHandler)(uint16_t type, SCMProcessMsgFunc processMsgFunc); typedef void (*UnregisterTXHandler)(uint16_t type, SCMProcessMsgFunc processMsgFunc); typedef int (*PreallocMessageRX)(uint32_t length, SCMsgHdr **hdr, uint8_t **msg_ptr, void **msg_handle); typedef int (*PreallocMessageTX)(uint32_t length, SCMsgHdr **hdr, uint8_t **msg_ptr, void **msg_handle); typedef int (*DiscardMessageRX)(void *msg_handle); typedef int (*DiscardMessageTX)(void *msg_handle); typedef int (*EnqueueMessageRX)(SCMsgHdr *hdr, const uint8_t *msg, uint32_t length, void *msg_handle, SCMQMsgFreeFunc msgFreeFunc); typedef int (*EnqueueMessageTX)(SCMsgHdr *hdr, const uint8_t *msg, uint32_t length, void *msg_handle, SCMQMsgFreeFunc msgFreeFunc); typedef int (*EnqueueDataRX)(SCMsgHdr *hdr, uint8_t *msg, uint32_t length, SCMQMsgFreeFunc msgFreeFunc); typedef int (*EnqueueDataTX)(SCMsgHdr *hdr, uint8_t *msg, uint32_t length, SCMQMsgFreeFunc msgFreeFunc); typedef void (*RegisterModule)(const char *keyword, SCMFunctionBundle *funcs); typedef sigset_t (*SnortSignalMask)(void); typedef struct _DynamicSideChannelData { int version; int size; RegisterModule registerModule; RegisterRXHandler registerRXHandler; RegisterTXHandler registerTXHandler; UnregisterRXHandler unregisterRXHandler; UnregisterTXHandler unregisterTXHandler; PreallocMessageRX allocMessageRX; PreallocMessageTX allocMessageTX; DiscardMessageRX discardMessageRX; DiscardMessageRX discardMessageTX; EnqueueMessageRX enqueueMessageRX; EnqueueMessageTX enqueueMessageTX; EnqueueDataRX enqueueDataRX; EnqueueDataTX enqueueDataTX; LogMsgFunc logMsg; LogMsgFunc errMsg; LogMsgFunc fatalMsg; DebugMsgFunc debugMsg; GetSnortInstance getSnortInstance; SnortSignalMask snortSignalMask; } DynamicSideChannelData; /* Function prototypes for Dynamic Detection Plugins */ int LoadDynamicSideChannelLib(struct _SnortConfig *sc, const char * const library_name, int indent); void CloseDynamicSideChannelLibs(void); void LoadAllDynamicSideChannelLibs(struct _SnortConfig *sc, const char * const path); void RemoveDuplicateSideChannelPlugins(void); int InitDynamicSideChannelPlugins(void); typedef int (*InitSideChannelLibFunc)(DynamicSideChannelData *dscd); void *GetNextSideChannelPluginVersion(void *p); DynamicPluginMeta *GetSideChannelPluginMetaData(void *p); extern DynamicSideChannelData _dscd; #endif /* _SF_DYNAMIC_SIDE_CHANNEL_H_ */ snort-2.9.15.1/src/dynamic-plugins/sp_dynamic.c0000644000175200017520000005347213571422607016247 00000000000000/* $Id$ */ /* * sp_dynamic.c * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Copyright (C) 2014-2019 Cisco and/or its affiliates. All rights reserved. * Copyright (C) 2005-2013 Sourcefire, Inc. * * Author: Steven Sturges * * Purpose: * Supports dynamically loaded detection plugin to check the packet. * * does not update the doe_ptr * * Arguments: * Required: * None * Optional: * None * * sample rules: * alert tcp any any -> any any (msg: "DynamicRuleCheck"; ); * * Effect: * * Returns 1 if the dynamic detection plugin matches, 0 if it doesn't. * * Comments: * * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifdef HAVE_STRINGS_H #include #endif #include #include "sf_types.h" #include "rules.h" #include "treenodes.h" #include "decode.h" #include "bitop_funcs.h" #include "plugbase.h" #include "parser.h" #include "snort_debug.h" #include "util.h" #include "plugin_enum.h" #include "sp_dynamic.h" #include "sf_dynamic_engine.h" #include "detection-plugins/sp_flowbits.h" #include "detection-plugins/sp_asn1_detect.h" #include "dynamic-plugins/sf_engine/sf_snort_plugin_api.h" #include "sf_convert_dynamic.h" #include "sfhashfcn.h" #include "sp_preprocopt.h" #include "sfutil/sf_base64decode.h" #include "detection_util.h" #include "stream_api.h" #include "snort.h" #include "profiler.h" #include "reload.h" #ifdef PERF_PROFILING PreprocStats dynamicRuleEvalPerfStats; extern PreprocStats ruleOTNEvalPerfStats; #endif extern SFGHASH *flowbits_hash; extern SF_QUEUE *flowbits_bit_queue; extern uint32_t flowbits_count; void DynamicInit(struct _SnortConfig *, char *, OptTreeNode *, int); void DynamicParse(char *, OptTreeNode *); int DynamicCheck(void *option_data, Packet *p); uint32_t DynamicRuleHash(void *d) { uint32_t a,b,c; DynamicData *dynData = (DynamicData *)d; #if (defined(__ia64) || defined(__amd64) || defined(_LP64)) { /* Cleanup warning because of cast from 64bit ptr to 32bit int * warning on 64bit OSs */ uint64_t ptr; /* Addresses are 64bits */ ptr = (uint64_t)dynData->contextData; a = (ptr >> 32); b = (ptr & 0xFFFFFFFF); ptr = (uint64_t)dynData->checkFunction; c = (ptr >> 32); mix (a,b,c); a += (ptr & 0xFFFFFFFF); ptr = (uint64_t)dynData->hasOptionFunction; b += (ptr >> 32); c += (ptr & 0xFFFFFFFF); ptr = (uint64_t)dynData->getDynamicContents; a += (ptr >> 32); b += (ptr & 0xFFFFFFFF); c += dynData->contentFlags; mix (a,b,c); a += RULE_OPTION_TYPE_DYNAMIC; } #else { a = (uint32_t)dynData->contextData; b = (uint32_t)dynData->checkFunction; c = (uint32_t)dynData->hasOptionFunction; mix(a,b,c); a += (uint32_t)dynData->getDynamicContents; b += dynData->contentFlags; c += RULE_OPTION_TYPE_DYNAMIC; } #endif final(a,b,c); return c; } int DynamicRuleCompare(void *l, void *r) { DynamicData *left = (DynamicData *)l; DynamicData *right = (DynamicData *)r; if (!left || !right) return DETECTION_OPTION_NOT_EQUAL; if ((left->contextData == right->contextData) && (left->checkFunction == right->checkFunction) && (left->hasOptionFunction == right->hasOptionFunction) && (left->getDynamicContents == right->getDynamicContents) && (left->contentFlags == right->contentFlags)) { return DETECTION_OPTION_EQUAL; } return DETECTION_OPTION_NOT_EQUAL; } /**************************************************************************** * * Function: SetupDynamic() * * Purpose: Load it up * * Arguments: None. * * Returns: void function * ****************************************************************************/ void SetupDynamic(void) { /* map the keyword to an initialization/processing function */ RegisterRuleOption("dynamic", DynamicInit, NULL, OPT_TYPE_DETECTION, NULL); #ifdef PERF_PROFILING RegisterPreprocessorProfile("dynamic_rule", &dynamicRuleEvalPerfStats, 3, &ruleOTNEvalPerfStats, NULL); #endif DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: Dynamic Setup\n");); } /**************************************************************************** * * Function: DynamicInit(struct _SnortConfig *, char *, OptTreeNode *) * * Purpose: Configuration function. Handles parsing the rule * information and attaching the associated detection function to * the OTN. * * Arguments: data => rule arguments/data * otn => pointer to the current rule option list node * protocol => protocol the rule is on (we don't care in this case) * * Returns: void function * ****************************************************************************/ void DynamicInit(struct _SnortConfig *sc, char *data, OptTreeNode *otn, int protocol) { OptFpList *fpl; DynamicData *dynData; void *option_dup; dynData = (DynamicData *)otn->ds_list[PLUGIN_DYNAMIC]; fpl = AddOptFuncToList(DynamicCheck, otn); /* attach it to the context node so that we can call each instance * individually */ fpl->context = (void *) dynData; if (add_detection_option(sc, RULE_OPTION_TYPE_DYNAMIC, (void *)dynData, &option_dup) == DETECTION_OPTION_EQUAL) { free(dynData); fpl->context = dynData = option_dup; } fpl->type = RULE_OPTION_TYPE_DYNAMIC; } /**************************************************************************** * * Function: DynamicCheck(char *, OptTreeNode *, OptFpList *) * * Purpose: Use this function to perform the particular detection routine * that this rule keyword is supposed to encompass. * * Arguments: p => pointer to the decoded packet * otn => pointer to the current rule's OTN * fp_list => pointer to the function pointer list * * Returns: If the detection test fails, this function *must* return a zero! * On success, it calls the next function in the detection list * ****************************************************************************/ int DynamicCheck(void *option_data, Packet *p) { DynamicData *dynData = (DynamicData *)option_data; int result = 0; PROFILE_VARS; PREPROC_PROFILE_START(dynamicRuleEvalPerfStats); if (!dynData) { LogMessage("Dynamic Rule with no context data available"); PREPROC_PROFILE_END(dynamicRuleEvalPerfStats); return DETECTION_OPTION_NO_MATCH; } result = dynData->checkFunction((void *)p, dynData->contextData); if (result) { PREPROC_PROFILE_END(dynamicRuleEvalPerfStats); return result; } /* Detection failed */ PREPROC_PROFILE_END(dynamicRuleEvalPerfStats); return DETECTION_OPTION_NO_MATCH; } void DynamicRuleListFree(DynamicRuleNode *head) { while (head != NULL) { DynamicRuleNode *tmp = head->next; /* * Clean up will be executed only when snort exits or * dynamic libs have changed */ if (head->freeFunc) { head->freeFunc((void *)head->rule); } free(head); head = tmp; } } /**************************************************************************** * * Function: RegisterDynamicRule(Snortconfig *, uint32_t, uint32_t, char *, * void *, * OTNCheckFunction, int, GetFPContentFunction) * * Purpose: A dynamically loaded detection engine library can use this * function to register a dynamically loaded rule/preprocessor. It * provides a pointer to context specific data for the * rule/preprocessor and a reference to the function used to * check the rule. * * Arguments: sid => Signature ID * gid => Generator ID * info => context specific data * chkFunc => Function to call to check if the rule matches * has*Funcs => Functions used to categorize this rule * contentFlags => Flags indicating which contents are available * contentsFunc => Function to call to get list of rule contents * * Returns: 0 on success * ****************************************************************************/ int RegisterDynamicRule( SnortConfig *sc, uint32_t sid, uint32_t gid, void *info, OTNCheckFunction chkFunc, OTNHasFunction hasFunc, int contentFlags, GetDynamicContentsFunction contentsFunc, RuleFreeFunc freeFunc, GetDynamicPreprocOptFpContentsFunc preprocFpFunc ) { DynamicData *dynData; struct _OptTreeNode *otn = NULL; OptFpList *idx; /* index pointer */ OptFpList *fpl; char done_once = 0; void *option_dup; DynamicRuleNode *node = NULL; if (sc == NULL) { FatalError("%s(%d) Snort config is NULL.\n", __FILE__, __LINE__); } if ( SnortDynamicLibsChanged() || SnortIsInitializing() ) { node = (DynamicRuleNode *)SnortAlloc(sizeof(DynamicRuleNode)); if (sc->dynamic_rules == NULL) { sc->dynamic_rules = node; } else { DynamicRuleNode *tmp = sc->dynamic_rules; while (tmp->next != NULL) tmp = tmp->next; tmp->next = node; } node->rule = (Rule *)info; node->chkFunc = chkFunc; node->hasFunc = hasFunc; node->contentFlags = contentFlags; node->contentsFunc = contentsFunc; node->freeFunc = freeFunc; node->preprocFpContentsFunc = preprocFpFunc; } /* Get OTN/RTN from SID */ otn = SoRuleOtnLookup(sc->so_rule_otn_map, gid, sid); if (!otn) { if (ScConfErrorOut()) { FatalError("DynamicPlugin: Rule [%u:%u] not enabled in configuration.\n", gid, sid); } else { #ifndef SOURCEFIRE LogMessage("DynamicPlugin: Rule [%u:%u] not enabled in " "configuration, rule will not be used.\n", gid, sid); #endif } return -1; } /* If this dynamic rule can be expressed as a regular rule, break it down * and convert it to use the rule option tree. */ if (ConvertDynamicRule(sc, (Rule *)info, otn) > 0) { if (node != NULL) node->converted = 1; return 0; } /* allocate the data structure and attach it to the * rule's data struct list */ dynData = (DynamicData *)SnortAlloc(sizeof(DynamicData)); dynData->contextData = info; dynData->checkFunction = chkFunc; dynData->hasOptionFunction = hasFunc; dynData->getDynamicContents = contentsFunc; dynData->contentFlags = contentFlags; dynData->getPreprocFpContents = preprocFpFunc; while (otn) { OptFpList *prev = NULL; otn->ds_list[PLUGIN_DYNAMIC] = (void *)dynData; /* And add this function into the tail of the list */ fpl = AddOptFuncToList(DynamicCheck, otn); fpl->context = dynData; fpl->type = RULE_OPTION_TYPE_DYNAMIC; if (done_once == 0) { if (add_detection_option(sc, RULE_OPTION_TYPE_DYNAMIC, (void *)dynData, &option_dup) == DETECTION_OPTION_EQUAL) { free(dynData); fpl->context = dynData = option_dup; } done_once = 1; } /* Arrgh. Because we read this rule in earlier, there is * already an OptListEnd node there. Need to move this new * one to just before it. */ DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Adding new rule to list\n");); /* set the index pointer to the start of this OTN's function list */ idx = otn->opt_func; /* if there are no nodes on the function list... */ while(idx != NULL) { if (idx->next == fpl) /* The last one in the list before us */ { if (prev) { prev->next = fpl; fpl->next = idx; idx->next = NULL; } else /* idx is the head of the list */ { otn->opt_func = fpl; fpl->next = idx; idx->next = NULL; } } prev = idx; idx = idx->next; } otn = SoRuleOtnLookupNext(gid, sid); } return 0; } #ifdef SNORT_RELOAD int ReloadDynamicRules(SnortConfig *sc) { /* * We are registering the dynamic rules from old * snort config to new one. Hence this should be * snort_conf. This code will not be execute if * dynamic detection has changed. */ DynamicRuleNode *node = snort_conf->dynamic_rules; sc->dynamic_rules = snort_conf->dynamic_rules; sc->loadedDetectionPlugins = snort_conf->loadedDetectionPlugins; snort_conf->loadedDetectionPlugins = NULL; snort_conf->dynamic_rules = NULL; for (; node != NULL; node = node->next) { int i; if (node->rule == NULL || (!node->rule->initialized) || node->rule->options == NULL) continue; for (i = 0; node->rule->options[i] != NULL; i++) { RuleOption *option = node->rule->options[i]; switch (option->optionType) { case OPTION_TYPE_FLOWBIT: { FlowBitsInfo *flowbits = option->option_u.flowBit; flowbits = DynamicFlowbitRegister(flowbits); } break; default: break; } } if (RegisterDynamicRule(sc, node->rule->info.sigID, node->rule->info.genID, (void *)node->rule, node->chkFunc, node->hasFunc, node->contentFlags, node->contentsFunc, node->freeFunc, node->preprocFpContentsFunc) == -1) { for (i = 0; node->rule->options[i] != NULL; i++) { RuleOption *option = node->rule->options[i]; switch (option->optionType) { case OPTION_TYPE_FLOWBIT: { FlowBitsInfo *flowbits = option->option_u.flowBit; DynamicFlowbitUnregister(flowbits); } break; default: break; } } } } return 0; } #endif int DynamicPreprocRuleOptInit(struct _SnortConfig *sc, void *opt) { PreprocessorOption *preprocOpt = (PreprocessorOption *)opt; PreprocOptionInit optionInit; PreprocOptionOtnHandler otnHandler; char *option_name = NULL; char *option_params = NULL; char *tmp; int result; if (preprocOpt == NULL) return -1; if (preprocOpt->optionName == NULL) return -1; result = GetPreprocessorRuleOptionFuncs(sc, (char *)preprocOpt->optionName, &preprocOpt->optionInit, &preprocOpt->optionEval, &otnHandler, &preprocOpt->optionFpFunc, &preprocOpt->optionCleanup); if (!result) return -1; optionInit = (PreprocOptionInit)preprocOpt->optionInit; option_name = SnortStrdup(preprocOpt->optionName); /* XXX Hack right now for override options where the rule * option is stored as