From 0a3c006289ef04a1bebd8c707f498b0a8c36bdd2 Mon Sep 17 00:00:00 2001 From: James Stronz Date: Wed, 4 Sep 2019 03:05:42 -0500 Subject: [PATCH 01/23] First pass on porting nidsmodule to python 3 --- nidsmodule.c | 68 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 13 deletions(-) diff --git a/nidsmodule.c b/nidsmodule.c index 101bdd1..249cb10 100644 --- a/nidsmodule.c +++ b/nidsmodule.c @@ -34,6 +34,42 @@ #else #define DBG(p, ...) #endif /* DEBUG */ +// initial 2to3 +#if PY_MAJOR_VERSION >= 3 + + #define PyInt_AsLong PyLong_AsLong + #define PyInt_AS_LONG PyLong_AS_LONG + #define PyInt_Check PyLong_Check + #define PyInt_FromLong PyLong_FromLong + #define PyInt_Type PyLong_Type + #define PyString_AsStringAndSize PyBytes_AsStringAndSize +// #define PyString_AsString PyBytes_AsString + #define PyString_AS_STRING PyBytes_AS_STRING + #define PyString_AsString PyUnicode_AsString +// #define PyString_Check PyBytes_Check + #define PyString_Check PyUnicode_Check + #define PyString_FromFormat PyUnicode_FromFormat + #define PyString_FromFormatV PyUnicode_FromFormatV +// #define PyString_FromStringAndSize PyBytes_FromStringAndSize + #define PyString_FromStringAndSize PyUnicode_FromStringAndSize +// #define PyString_FromString PyBytes_FromString + #define PyString_FromString PyUnicode_FromString + #define PyString_Join PyUnicode_Join +// #define PyString_Size PyBytes_Size + #define PyString_Size PyUnicode_Size + #define PyString_Type PyUnicode_Type + #define Py_TPFLAGS_HAVE_ITER 0 + #define PyUnicode_AsString(x) PyBytes_AsString(PyUnicode_AsEncodedString((x), "utf-8", "strict")) + #define TEXT_T Py_UNICODE + + +inline void PyString_ConcatAndDel(PyObject** lhs, PyObject* rhs) +{ + PyUnicode_Concat(*lhs, rhs); + Py_DECREF(rhs); +} + +#endif #ifndef Py_RETURN_NONE # define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None @@ -66,8 +102,8 @@ typedef struct { struct half_stream *hlfs; } HalfStream; -staticforward PyTypeObject TcpStream_Type; -staticforward PyTypeObject HalfStream_Type; +static PyTypeObject TcpStream_Type; +static PyTypeObject HalfStream_Type; /* wrapHalfStream used by TcpStream getter */ static HalfStream *wrapHalfStream(struct half_stream *); @@ -283,7 +319,7 @@ static PyGetSetDef TcpStream_getsets[] = { {NULL} /* Sentinel */ }; -statichere PyTypeObject TcpStream_Type = { +static PyTypeObject TcpStream_Type = { /* The ob_type field must be initialized in the module init function * to be portable to Windows without using C++. */ PyObject_HEAD_INIT(NULL) @@ -307,7 +343,7 @@ statichere PyTypeObject TcpStream_Type = { PyObject_GenericGetAttr, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ - Py_TPFLAGS_HAVE_CLASS, /*tp_flags*/ + 0, /*tp_flags*/ 0, /*tp_doc*/ 0, /*tp_traverse*/ 0, /*tp_clear*/ @@ -402,7 +438,7 @@ static PyGetSetDef HalfStream_getsets[] = { {NULL} /* Sentinel */ }; -statichere PyTypeObject HalfStream_Type = { +static PyTypeObject HalfStream_Type = { /* The ob_type field must be initialized in the module init function * to be portable to Windows without using C++. */ PyObject_HEAD_INIT(NULL) @@ -426,7 +462,7 @@ statichere PyTypeObject HalfStream_Type = { PyObject_GenericGetAttr, /*tp_getattro*/ PyObject_GenericSetAttr, /*tp_setattro*/ 0, /*tp_as_buffer*/ - Py_TPFLAGS_HAVE_CLASS, /*tp_flags*/ + 0, /*tp_flags*/ 0, /*tp_doc*/ 0, /*tp_traverse*/ 0, /*tp_clear*/ @@ -984,23 +1020,28 @@ static PyMethodDef pynids_methods[] = { }; #undef mkMethod - +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, /* m_base */ + "nids", /* m_name */ + pynidsmodule__doc__, /* m_doc */ + -1, /* m_size */ + pynids_methods /* m_methods */ +}; /* ====================================================================== */ /* Module Initialization */ /* ====================================================================== */ -DL_EXPORT(void) -initnids(void) -{ +PyMODINIT_FUNC PyInit_nids(void) { PyObject *m; /* Initialize the type of the new type object here; doing it here * is required for portability to Windows without requiring C++. */ - TcpStream_Type.ob_type = &PyType_Type; - HalfStream_Type.ob_type = &PyType_Type; +Py_TYPE(& TcpStream_Type) = &PyType_Type; +Py_TYPE(& HalfStream_Type) = &PyType_Type; /* Create the module and add the functions */ - m = Py_InitModule3("nids", pynids_methods, pynidsmodule__doc__); + + m = PyModule_Create(&moduledef); /* Initialize, add our exception object */ pynids_error = PyErr_NewException("nids.error", NULL, NULL); @@ -1029,6 +1070,7 @@ initnids(void) /* Save the original nids_params */ origNidsParams = nids_params; + return m; } /* From 961d2555e0588dd3f53c4e25d0d72fc9a753d068 Mon Sep 17 00:00:00 2001 From: James Stronz Date: Wed, 4 Sep 2019 03:31:26 -0500 Subject: [PATCH 02/23] Ported Example from 2 to 3 --- Example => Example.py | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) rename Example => Example.py (64%) diff --git a/Example b/Example.py similarity index 64% rename from Example rename to Example.py index 215dc5a..5085be3 100644 --- a/Example +++ b/Example.py @@ -1,38 +1,41 @@ -#! /usr/bin/env python2 +#! /usr/bin/env python # pynids Example # $Id: Example,v 1.3 2005/01/27 04:53:45 mjp Exp $ -import os, pwd +import os +import pwd import sys import nids NOTROOT = "nobody" # edit to taste end_states = (nids.NIDS_CLOSE, nids.NIDS_TIMEOUT, nids.NIDS_RESET) + def handleTcpStream(tcp): - print "tcps -", str(tcp.addr), " state:", tcp.nids_state + print("tcps -", str(tcp.addr), " state:", tcp.nids_state) if tcp.nids_state == nids.NIDS_JUST_EST: # new to us, but do we care? ((src, sport), (dst, dport)) = tcp.addr - print tcp.addr + print(tcp.addr) if dport in (80, 8000, 8080): - print "collecting..." + print("collecting...") tcp.client.collect = 1 tcp.server.collect = 1 elif tcp.nids_state == nids.NIDS_DATA: # keep all of the stream's new data - tcp.discard(0) + tcp.discard(0) elif tcp.nids_state in end_states: - print "addr:", tcp.addr - print "To server:" - print tcp.server.data[:tcp.server.count] # WARNING - may be binary - print "To client:" - print tcp.client.data[:tcp.client.count] # WARNING - as above + print("addr:", tcp.addr) + print("To server:") + print(tcp.server.data[:tcp.server.count]) # WARNING - may be binary + print("To client:") + print(tcp.client.data[:tcp.client.count]) # WARNING - as above + def main(): - #nids.param("pcap_filter", "tcp") # bpf restrict to TCP only, note + # nids.param("pcap_filter", "tcp") # bpf restrict to TCP only, note # libnids caution about fragments nids.param("scan_num_hosts", 0) # disable portscan detection @@ -45,24 +48,25 @@ def main(): nids.init() (uid, gid) = pwd.getpwnam(NOTROOT)[2:4] - os.setgroups([gid,]) + os.setgroups([gid, ]) os.setgid(gid) os.setuid(uid) if 0 in [os.getuid(), os.getgid()] + list(os.getgroups()): - print "error - drop root, please!" + print("error - drop root, please!") sys.exit(1) nids.register_tcp(handleTcpStream) - print "pid", os.getpid() + print("pid", os.getpid()) # Loop forever (network device), or until EOF (pcap file) # Note that an exception in the callback will break the loop! try: nids.run() - except nids.error, e: - print "nids/pcap error:", e - except Exception, e: - print "misc. exception (runtime error in user callback?):", e + except nids.error as e: + print("nids/pcap error:", e) + except Exception as e: + print("misc. exception (runtime error in user callback?):", e) + if __name__ == '__main__': main() From cb08ec59786759d4bec603c10c70d0fb326308e6 Mon Sep 17 00:00:00 2001 From: James Stronz Date: Sun, 22 Sep 2019 17:28:14 -0500 Subject: [PATCH 03/23] Added .clang-format to make style in nidsmodule.c consistent --- .clang-format | 121 ++++++++++++++++++++++++++++++++++++++++++ nidsmodule.c | 143 +++++++++++++++++++++++++++----------------------- 2 files changed, 197 insertions(+), 67 deletions(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..d30c5da --- /dev/null +++ b/.clang-format @@ -0,0 +1,121 @@ +--- +Language: Cpp +# BasedOnStyle: LLVM +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Right +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: MultiLine +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Attach +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + - Regex: '.*' + Priority: 1 +IncludeIsMainRegex: '(Test)?$' +IndentCaseLabels: false +IndentPPDirectives: None +IndentWidth: 2 +IndentWrappedFunctionNames: false +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Right +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 8 +UseTab: Never +... + diff --git a/nidsmodule.c b/nidsmodule.c index 249cb10..bf5af21 100644 --- a/nidsmodule.c +++ b/nidsmodule.c @@ -1,23 +1,32 @@ /* - nidsmodule.c - C implementation of pynids - Copyright (c) 2003 Michael J. Pomraning - $Id: nidsmodule.c,v 1.11 2005/02/01 05:50:06 mjp Exp $ - - This file is part of the pynids package, a python interface to libnids. - - 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. + * nidsmodule.c - C implementation of pynids + * Copyright (c) 2003 Michael J. Pomraning + * $Id: nidsmodule.c,v 1.11 2005/02/01 05:50:06 mjp Exp $ + * + * This file is part of the pynids package, a python interface to libnids. + * + * 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, USA + */ - You 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, USA +/* Porting Module to Python 3: + * Resources: + * + https://docs.python.org/3/howto/cporting.html + * + https://docs.python.org/3/c-api/ + * + * + * */ #include "Python.h" @@ -109,55 +118,55 @@ static PyTypeObject HalfStream_Type; static HalfStream *wrapHalfStream(struct half_stream *); static char pynidsmodule__doc__[] = -"A wrapper around the libnids Network Intrusion Detection library.\n\ -\n\ -Functions:\n\ -\n\ -param() -- set various libnids parameters\n\ -init() -- open the capture stream, prepare internal \n\ -getfd() -- return the file descriptor associated with the capture stream\n\ -get_pkt_ts() -- return the timestamp of the most recently received packet\n\ -get_pcap_stats() -- return num packets rcvd, num pkts dropped,\n\ - num pkts dropped by interface as a tuple\n\ -register_ip_frag() -- install a callback for IP fragment processing\n\ -register_ip() -- install a callback for reassembled IP packet processing\n\ -register_tcp() -- install a callback for reaseembled TCP packet processing\n\ -register_udp() -- install a callback for reassembled UDP packet processing\n\ -chksum_ctl() -- control whether packets are checksum by source address\n\ -next() -- process one packet from the capture stream, invoking callbacks\n\ -run() -- process all packets from the capture stream, invoking callbacks\n\ -\n\ -Special objects and classes:\n\ -\n\ -error -- exception raised for serious libnids/pcap errors\n\ -TcpStream -- class of argument to TCP callback function. Features:\n\ - addr -- Connection tuple: ((src, sport), (dst, dport))\n\ - discard(n) -- purge n bytes from the data buffer\n\ - kill() -- send symmetric RSTs to tear down the connection\n\ - nids_state -- see 'Constants,' below\n\ - client -- half of the connection; a TcpStream object\n\ - server -- half of the connection; a TcpStream object\n\ -HalfStream -- class of TcpStream 'client' and 'server' members. Features:\n\ - collect -- boolean controlling whether data is collected\n\ - collect_urg -- boolean controlling URG data collection\n\ - count -- number of bytes appended to 'data' since creation\n\ - count_new -- number of newly collected bytes in 'data'\n\ - count_new_urg -- number of new urgent bytes\n\ - data -- string buffer of normal (non-urgent) data\n\ - urgdata -- one-byte string buffer\n\ - offset -- offset of newly collected bytes in 'data'\n\ - state -- [*] numeric socket state\n\ -\n\ - * TCP state constants (e.g., TCP_ESTABLISHED) are not supplied by pynids\n\ -\n\ -See the libnids documentation or the pynids README for more information\n\ -on the TcpStream and HalfStream objects.\n\ -\n\ -Constants:\n\ -\n\ -NIDS_CLOSE, NIDS_DATA, NIDS_EXITING, NIDS_JUST_EST, NIDS_RESET,\n\ -NIDS_TIMED_OUT, NIDS_TIMEOUT -- possible values of the 'nids_state' member\n\ -of a TcpStream object.\n"; + "A wrapper around the libnids Network Intrusion Detection library.\n" + "\n" + "Functions:\n" + "\n" + "param() -- set various libnids parameters\n" + "init() -- open the capture stream, prepare internal \n" + "getfd() -- return the file descriptor associated with the capture stream\n" + "get_pkt_ts() -- return the timestamp of the most recently received packet\n" + "get_pcap_stats() -- return num packets rcvd, num pkts dropped,\n" + " num pkts dropped by interface as a tuple\n" + "register_ip_frag() -- install a callback for IP fragment processing\n" + "register_ip() -- install a callback for reassembled IP packet processing\n" + "register_tcp() -- install a callback for reaseembled TCP packet processing\n" + "register_udp() -- install a callback for reassembled UDP packet processing\n" + "chksum_ctl() -- control whether packets are checksum by source address\n" + "next() -- process one packet from the capture stream, invoking callbacks\n" + "run() -- process all packets from the capture stream, invoking callbacks\n" + "\n" + "Special objects and classes:\n" + "\n" + "error -- exception raised for serious libnids/pcap errors\n" + "TcpStream -- class of argument to TCP callback function. Features:\n" + " addr -- Connection tuple: ((src, sport), (dst, dport))\n" + " discard(n) -- purge n bytes from the data buffer\n" + " kill() -- send symmetric RSTs to tear down the connection\n" + " nids_state -- see 'Constants,' below\n" + " client -- half of the connection; a TcpStream object\n" + " server -- half of the connection; a TcpStream object\n" + "HalfStream -- class of TcpStream 'client' and 'server' members. Features:\n" + " collect -- boolean controlling whether data is collected\n" + " collect_urg -- boolean controlling URG data collection\n" + " count -- number of bytes appended to 'data' since creation\n" + " count_new -- number of newly collected bytes in 'data'\n" + " count_new_urg -- number of new urgent bytes\n" + " data -- string buffer of normal (non-urgent) data\n" + " urgdata -- one-byte string buffer\n" + " offset -- offset of newly collected bytes in 'data'\n" + " state -- [*] numeric socket state\n" + "\n" + " * TCP state constants (e.g., TCP_ESTABLISHED) are not supplied by pynids\n" + "\n" + "See the libnids documentation or the pynids README for more information\n" + "on the TcpStream and HalfStream objects.\n" + "\n" + "Constants:\n" + "\n" + "NIDS_CLOSE, NIDS_DATA, NIDS_EXITING, NIDS_JUST_EST, NIDS_RESET,\n" + "NIDS_TIMED_OUT, NIDS_TIMEOUT -- possible values of the 'nids_state' member\n" + "of a TcpStream object.\n"; static PyObject * raisePynidsError(void) From f194a2d27b2817022912189d31f28d262c1ff81e Mon Sep 17 00:00:00 2001 From: James Stronz Date: Sun, 22 Sep 2019 17:28:43 -0500 Subject: [PATCH 04/23] Ran clang-format and cleaned up docstrings --- nidsmodule.c | 1470 +++++++++++++++++++++++++------------------------- 1 file changed, 724 insertions(+), 746 deletions(-) diff --git a/nidsmodule.c b/nidsmodule.c index bf5af21..2813e08 100644 --- a/nidsmodule.c +++ b/nidsmodule.c @@ -30,85 +30,82 @@ */ #include "Python.h" -#include +#include #include #include #include -#include #include #include +#include #ifdef DEBUG -#define DBG(f, ...) fprintf(stderr, f, ##__VA_ARGS__) +#define DBG(f, ...) fprintf(stderr, f, ##__VA_ARGS__) #else -#define DBG(p, ...) +#define DBG(p, ...) #endif /* DEBUG */ // initial 2to3 #if PY_MAJOR_VERSION >= 3 - #define PyInt_AsLong PyLong_AsLong - #define PyInt_AS_LONG PyLong_AS_LONG - #define PyInt_Check PyLong_Check - #define PyInt_FromLong PyLong_FromLong - #define PyInt_Type PyLong_Type - #define PyString_AsStringAndSize PyBytes_AsStringAndSize +#define PyInt_AsLong PyLong_AsLong +#define PyInt_AS_LONG PyLong_AS_LONG +#define PyInt_Check PyLong_Check +#define PyInt_FromLong PyLong_FromLong +#define PyInt_Type PyLong_Type +#define PyString_AsStringAndSize PyBytes_AsStringAndSize // #define PyString_AsString PyBytes_AsString - #define PyString_AS_STRING PyBytes_AS_STRING - #define PyString_AsString PyUnicode_AsString +#define PyString_AS_STRING PyBytes_AS_STRING +#define PyString_AsString PyUnicode_AsString // #define PyString_Check PyBytes_Check - #define PyString_Check PyUnicode_Check - #define PyString_FromFormat PyUnicode_FromFormat - #define PyString_FromFormatV PyUnicode_FromFormatV +#define PyString_Check PyUnicode_Check +#define PyString_FromFormat PyUnicode_FromFormat +#define PyString_FromFormatV PyUnicode_FromFormatV // #define PyString_FromStringAndSize PyBytes_FromStringAndSize - #define PyString_FromStringAndSize PyUnicode_FromStringAndSize +#define PyString_FromStringAndSize PyUnicode_FromStringAndSize // #define PyString_FromString PyBytes_FromString - #define PyString_FromString PyUnicode_FromString - #define PyString_Join PyUnicode_Join +#define PyString_FromString PyUnicode_FromString +#define PyString_Join PyUnicode_Join // #define PyString_Size PyBytes_Size - #define PyString_Size PyUnicode_Size - #define PyString_Type PyUnicode_Type - #define Py_TPFLAGS_HAVE_ITER 0 - #define PyUnicode_AsString(x) PyBytes_AsString(PyUnicode_AsEncodedString((x), "utf-8", "strict")) - #define TEXT_T Py_UNICODE - - -inline void PyString_ConcatAndDel(PyObject** lhs, PyObject* rhs) -{ - PyUnicode_Concat(*lhs, rhs); - Py_DECREF(rhs); +#define PyString_Size PyUnicode_Size +#define PyString_Type PyUnicode_Type +#define Py_TPFLAGS_HAVE_ITER 0 +#define PyUnicode_AsString(x) \ + PyBytes_AsString(PyUnicode_AsEncodedString((x), "utf-8", "strict")) +#define TEXT_T Py_UNICODE + +inline void PyString_ConcatAndDel(PyObject **lhs, PyObject *rhs) { + PyUnicode_Concat(*lhs, rhs); + Py_DECREF(rhs); } #endif #ifndef Py_RETURN_NONE -# define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None +#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None #endif /* Py_RETURN_NONE */ /* ====================================================================== */ /* Module Globals and Utility Functions */ /* ====================================================================== */ -static PyObject *pynids_error; /* nids.error */ +static PyObject *pynids_error; /* nids.error */ -static int pynids_offline_read = 0; /* see nids.init(), nids.next() */ +static int pynids_offline_read = 0; /* see nids.init(), nids.next() */ -static PyObject *tcpFunc = NULL; -static PyObject *udpFunc = NULL; -static PyObject *ipFunc = NULL; +static PyObject *tcpFunc = NULL; +static PyObject *udpFunc = NULL; +static PyObject *ipFunc = NULL; static PyObject *fragFunc = NULL; static struct nids_prm origNidsParams; typedef struct { - PyObject_HEAD - struct tcp_stream *tcps; - PyObject *client; - PyObject *server; + PyObject_HEAD struct tcp_stream *tcps; + PyObject *client; + PyObject *server; } TcpStream; typedef struct { - PyObject_HEAD - struct half_stream *hlfs; + PyObject_HEAD struct half_stream *hlfs; } HalfStream; static PyTypeObject TcpStream_Type; @@ -125,13 +122,16 @@ static char pynidsmodule__doc__[] = "param() -- set various libnids parameters\n" "init() -- open the capture stream, prepare internal \n" "getfd() -- return the file descriptor associated with the capture stream\n" - "get_pkt_ts() -- return the timestamp of the most recently received packet\n" + "get_pkt_ts() -- return the timestamp of the most recently received " + "packet\n" "get_pcap_stats() -- return num packets rcvd, num pkts dropped,\n" - " num pkts dropped by interface as a tuple\n" + " num pkts dropped by interface as a tuple\n" "register_ip_frag() -- install a callback for IP fragment processing\n" "register_ip() -- install a callback for reassembled IP packet processing\n" - "register_tcp() -- install a callback for reaseembled TCP packet processing\n" - "register_udp() -- install a callback for reassembled UDP packet processing\n" + "register_tcp() -- install a callback for reaseembled TCP packet " + "processing\n" + "register_udp() -- install a callback for reassembled UDP packet " + "processing\n" "chksum_ctl() -- control whether packets are checksum by source address\n" "next() -- process one packet from the capture stream, invoking callbacks\n" "run() -- process all packets from the capture stream, invoking callbacks\n" @@ -146,7 +146,8 @@ static char pynidsmodule__doc__[] = " nids_state -- see 'Constants,' below\n" " client -- half of the connection; a TcpStream object\n" " server -- half of the connection; a TcpStream object\n" - "HalfStream -- class of TcpStream 'client' and 'server' members. Features:\n" + "HalfStream -- class of TcpStream 'client' and 'server' members. " + "Features:\n" " collect -- boolean controlling whether data is collected\n" " collect_urg -- boolean controlling URG data collection\n" " count -- number of bytes appended to 'data' since creation\n" @@ -157,7 +158,8 @@ static char pynidsmodule__doc__[] = " offset -- offset of newly collected bytes in 'data'\n" " state -- [*] numeric socket state\n" "\n" - " * TCP state constants (e.g., TCP_ESTABLISHED) are not supplied by pynids\n" + " * TCP state constants (e.g., TCP_ESTABLISHED) are not supplied by " + "pynids\n" "\n" "See the libnids documentation or the pynids README for more information\n" "on the TcpStream and HalfStream objects.\n" @@ -165,16 +167,15 @@ static char pynidsmodule__doc__[] = "Constants:\n" "\n" "NIDS_CLOSE, NIDS_DATA, NIDS_EXITING, NIDS_JUST_EST, NIDS_RESET,\n" - "NIDS_TIMED_OUT, NIDS_TIMEOUT -- possible values of the 'nids_state' member\n" - "of a TcpStream object.\n"; + "NIDS_TIMED_OUT, NIDS_TIMEOUT -- possible values of the 'nids_state' " + "member\n" + "of a TcpStream object.\n"; -static PyObject * -raisePynidsError(void) -{ - extern char nids_errbuf[]; +static PyObject *raisePynidsError(void) { + extern char nids_errbuf[]; - PyErr_SetString(pynids_error, nids_errbuf); - return NULL; + PyErr_SetString(pynids_error, nids_errbuf); + return NULL; } /* nids_dispatch_exc() @@ -188,43 +189,41 @@ raisePynidsError(void) * -1 exception thrown (either in user callback or in nids/pcap) * */ -static int -nids_dispatch_exc(int n) -{ - int ret; - - DBG("nids_dispatch_exc(%d)\n", n); - ret = nids_dispatch(n); - if (ret == -1) { /* pcap error trumps user callback exception */ - raisePynidsError(); - return -1; - } - if (PyErr_Occurred()) return -1; /* check for callback exception */ - return ret; +static int nids_dispatch_exc(int n) { + int ret; + + DBG("nids_dispatch_exc(%d)\n", n); + ret = nids_dispatch(n); + if (ret == -1) { /* pcap error trumps user callback exception */ + raisePynidsError(); + return -1; + } + if (PyErr_Occurred()) + return -1; /* check for callback exception */ + return ret; } /* pytuple4(tuple4): ((src, sport), (dst, dport)) */ -static PyObject * -pytuple4(struct tuple4 *addr) -{ - struct in_addr in; - PyObject *t1, *t2, *ret; - - in.s_addr = addr->saddr; - t1 = Py_BuildValue("si", inet_ntoa(in), addr->source); - if (! t1) return NULL; - - in.s_addr = addr->daddr; - t2 = Py_BuildValue("si", inet_ntoa(in), addr->dest); - if (! t2) { - Py_DECREF(t1); - return NULL; - } - - ret = Py_BuildValue("OO", t1, t2); - Py_DECREF(t1); - Py_DECREF(t2); - return ret; +static PyObject *pytuple4(struct tuple4 *addr) { + struct in_addr in; + PyObject *t1, *t2, *ret; + + in.s_addr = addr->saddr; + t1 = Py_BuildValue("si", inet_ntoa(in), addr->source); + if (!t1) + return NULL; + + in.s_addr = addr->daddr; + t2 = Py_BuildValue("si", inet_ntoa(in), addr->dest); + if (!t2) { + Py_DECREF(t1); + return NULL; + } + + ret = Py_BuildValue("OO", t1, t2); + Py_DECREF(t1); + Py_DECREF(t2); + return ret; } /* ====================================================================== */ @@ -232,138 +231,130 @@ pytuple4(struct tuple4 *addr) /* ====================================================================== */ /* TcpStream ctor -- called by callTcpFunc, not user */ -static TcpStream * -wrapTcpStream(struct tcp_stream *t) -{ - TcpStream *self; - self = PyObject_New(TcpStream, &TcpStream_Type); - if (self == NULL) return NULL; - self->tcps = t; - self->client = NULL; - self->server = NULL; - DBG("TcpStream_ctor(%p)\n", self); - /* - * wrap half streams on demand, if demanded... - self->client = (PyObject *) wrapHalfStream(&t->client); - self->server = (PyObject *) wrapHalfStream(&t->server); - */ - return self; +static TcpStream *wrapTcpStream(struct tcp_stream *t) { + TcpStream *self; + self = PyObject_New(TcpStream, &TcpStream_Type); + if (self == NULL) + return NULL; + self->tcps = t; + self->client = NULL; + self->server = NULL; + DBG("TcpStream_ctor(%p)\n", self); + /* + * wrap half streams on demand, if demanded... + self->client = (PyObject *) wrapHalfStream(&t->client); + self->server = (PyObject *) wrapHalfStream(&t->server); + */ + return self; } -static void -TcpStream_dealloc(TcpStream *self) -{ - DBG("TcpStream_dealloc(%p)\n", self); - self->tcps = NULL; /* libnids will free this when approp. */ - if (self->client) { - Py_DECREF(self->client); - self->client = NULL; - } - if (self->server) { - Py_DECREF(self->server); - self->server = NULL; - } - PyObject_Del(self); +static void TcpStream_dealloc(TcpStream *self) { + DBG("TcpStream_dealloc(%p)\n", self); + self->tcps = NULL; /* libnids will free this when approp. */ + if (self->client) { + Py_DECREF(self->client); + self->client = NULL; + } + if (self->server) { + Py_DECREF(self->server); + self->server = NULL; + } + PyObject_Del(self); } /* ====================================================================== */ /* TcpStreams: ctor, dtor, methods, members and type */ /* ====================================================================== */ -static PyObject * -TcpStream_discard(TcpStream *self, PyObject *args) -{ - int i; - if (!PyArg_ParseTuple(args, "i:discard", &i)) - return NULL; - - nids_discard(self->tcps, i); - - Py_RETURN_NONE; +static PyObject *TcpStream_discard(TcpStream *self, PyObject *args) { + int i; + if (!PyArg_ParseTuple(args, "i:discard", &i)) + return NULL; + + nids_discard(self->tcps, i); + + Py_RETURN_NONE; } -static PyObject * -TcpStream_kill(TcpStream *self, PyObject *args) -{ - if (!PyArg_ParseTuple(args, ":kill")) return NULL; - - nids_killtcp(self->tcps); +static PyObject *TcpStream_kill(TcpStream *self, PyObject *args) { + if (!PyArg_ParseTuple(args, ":kill")) + return NULL; + + nids_killtcp(self->tcps); - Py_RETURN_NONE; + Py_RETURN_NONE; } static PyMethodDef TcpStream_methods[] = { - {"discard", (PyCFunction)TcpStream_discard, METH_VARARGS}, - {"kill", (PyCFunction)TcpStream_kill, METH_VARARGS}, - {NULL, NULL} /* sentinel */ + {"discard", (PyCFunction)TcpStream_discard, METH_VARARGS}, + {"kill", (PyCFunction)TcpStream_kill, METH_VARARGS}, + {NULL, NULL} /* sentinel */ }; -#define TS_GET_HLFS(ATTR) \ - static PyObject * ts_get_##ATTR(TcpStream *self, void *unused) { \ - if (!self->ATTR) { \ - self->ATTR = (PyObject *) wrapHalfStream(&self->tcps->ATTR); \ - if (!self->ATTR) return NULL; \ - } \ - Py_INCREF(self->ATTR); \ - return self->ATTR; \ - } +#define TS_GET_HLFS(ATTR) \ + static PyObject *ts_get_##ATTR(TcpStream *self, void *unused) { \ + if (!self->ATTR) { \ + self->ATTR = (PyObject *)wrapHalfStream(&self->tcps->ATTR); \ + if (!self->ATTR) \ + return NULL; \ + } \ + Py_INCREF(self->ATTR); \ + return self->ATTR; \ + } /* RO attributes */ TS_GET_HLFS(client) TS_GET_HLFS(server) -static PyObject * -ts_get_addr(TcpStream *self, void *unused) { - return pytuple4(&self->tcps->addr); +static PyObject *ts_get_addr(TcpStream *self, void *unused) { + return pytuple4(&self->tcps->addr); } -static PyObject * -ts_get_nids_state(TcpStream *self, void *unused) { - return PyInt_FromLong((long)self->tcps->nids_state); +static PyObject *ts_get_nids_state(TcpStream *self, void *unused) { + return PyInt_FromLong((long)self->tcps->nids_state); } static PyGetSetDef TcpStream_getsets[] = { - {"client", (getter)ts_get_client}, - {"server", (getter)ts_get_server}, - {"addr", (getter)ts_get_addr}, - {"nids_state", (getter)ts_get_nids_state}, - {NULL} /* Sentinel */ + {"client", (getter)ts_get_client}, + {"server", (getter)ts_get_server}, + {"addr", (getter)ts_get_addr}, + {"nids_state", (getter)ts_get_nids_state}, + {NULL} /* Sentinel */ }; static PyTypeObject TcpStream_Type = { - /* The ob_type field must be initialized in the module init function - * to be portable to Windows without using C++. */ - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ - "TcpStream", /*tp_name*/ - sizeof(TcpStream), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)TcpStream_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - PyObject_GenericGetAttr, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - 0, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - TcpStream_methods, /*tp_methods*/ - 0, /*tp_members*/ - TcpStream_getsets, /*tp_getset*/ - 0, /*tp_base*/ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ + "TcpStream", /*tp_name*/ + sizeof(TcpStream), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)TcpStream_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + PyObject_GenericGetAttr, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + 0, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + TcpStream_methods, /*tp_methods*/ + 0, /*tp_members*/ + TcpStream_getsets, /*tp_getset*/ + 0, /*tp_base*/ }; /* ====================================================================== */ @@ -372,44 +363,44 @@ static PyTypeObject TcpStream_Type = { static HalfStream * wrapHalfStream(struct half_stream *h) { /* called by TcpStream ctor */ - HalfStream *self; - self = PyObject_New(HalfStream, &HalfStream_Type); - if (self == NULL) return NULL; - self->hlfs = h; - DBG("HalfStream_ctor(%p)\n", self); - return self; + HalfStream *self; + self = PyObject_New(HalfStream, &HalfStream_Type); + if (self == NULL) + return NULL; + self->hlfs = h; + DBG("HalfStream_ctor(%p)\n", self); + return self; } -static void -HalfStream_dealloc(HalfStream *self) { - DBG("HalfStream_dealloc(%p, %d)\n", self, self->ob_refcnt); - self->hlfs = NULL; - PyObject_Del(self); +static void HalfStream_dealloc(HalfStream *self) { + DBG("HalfStream_dealloc(%p, %d)\n", self, self->ob_refcnt); + self->hlfs = NULL; + PyObject_Del(self); } -#define HS_GET_INT(ATTR) \ - static PyObject * hs_get_##ATTR(HalfStream *self, void *unused) { \ - return PyInt_FromLong((long)self->hlfs->ATTR); \ - } +#define HS_GET_INT(ATTR) \ + static PyObject *hs_get_##ATTR(HalfStream *self, void *unused) { \ + return PyInt_FromLong((long)self->hlfs->ATTR); \ + } /* FIXME - true bool support */ -#define HS_GET_BOOL(ATTR) \ - static PyObject * hs_get_##ATTR(HalfStream *self, void *unused) { \ - return PyInt_FromLong(self->hlfs->ATTR ? 1L : 0L); \ - } - -#define HS_SET_BOOL(ATTR) \ - static int hs_set_##ATTR(HalfStream *self, PyObject *val, void *closure) { \ - if (val == NULL) { \ - PyErr_SetString(PyExc_TypeError, \ - "Cannot delete the " #ATTR "attribute"); \ - return -1; \ - } \ - DBG("hs_set_" #ATTR "(HalfStream * %p, bool %d)\n", \ - self, PyObject_IsTrue(val)); \ - self->hlfs->ATTR = PyObject_IsTrue(val); \ - return 0; /* success */ \ - } +#define HS_GET_BOOL(ATTR) \ + static PyObject *hs_get_##ATTR(HalfStream *self, void *unused) { \ + return PyInt_FromLong(self->hlfs->ATTR ? 1L : 0L); \ + } + +#define HS_SET_BOOL(ATTR) \ + static int hs_set_##ATTR(HalfStream *self, PyObject *val, void *closure) { \ + if (val == NULL) { \ + PyErr_SetString(PyExc_TypeError, \ + "Cannot delete the " #ATTR "attribute"); \ + return -1; \ + } \ + DBG("hs_set_" #ATTR "(HalfStream * %p, bool %d)\n", self, \ + PyObject_IsTrue(val)); \ + self->hlfs->ATTR = PyObject_IsTrue(val); \ + return 0; /* success */ \ + } /* RW attributes */ HS_GET_BOOL(collect) @@ -419,15 +410,16 @@ HS_SET_BOOL(collect_urg) /* RO attributes */ HS_GET_INT(state) static PyObject *hs_get_data(HalfStream *self, void *unused) { - /* data may not be allocated if the conn/libnids has seen no data */ - if (! self->hlfs->data) return PyString_FromStringAndSize("", 0); - /* bufsize is an undocumented member */ - return PyString_FromStringAndSize(self->hlfs->data, self->hlfs->bufsize); + /* data may not be allocated if the conn/libnids has seen no data */ + if (!self->hlfs->data) + return PyString_FromStringAndSize("", 0); + /* bufsize is an undocumented member */ + return PyString_FromStringAndSize(self->hlfs->data, self->hlfs->bufsize); } static PyObject *hs_get_urgdata(HalfStream *self, void *unused) { - /* u_char urgdata */ - return PyString_FromStringAndSize(&(self->hlfs->urgdata), - sizeof(self->hlfs->urgdata)); + /* u_char urgdata */ + return PyString_FromStringAndSize(&(self->hlfs->urgdata), + sizeof(self->hlfs->urgdata)); } HS_GET_INT(count) HS_GET_INT(offset) @@ -435,120 +427,111 @@ HS_GET_INT(count_new) HS_GET_INT(count_new_urg) static PyGetSetDef HalfStream_getsets[] = { - {"state", (getter)hs_get_state}, - {"collect", (getter)hs_get_collect, (setter)hs_set_collect}, - {"collect_urg", (getter)hs_get_collect_urg, (setter)hs_set_collect_urg}, - {"data", (getter)hs_get_data}, - {"urgdata", (getter)hs_get_urgdata}, - {"count", (getter)hs_get_count}, - {"offset", (getter)hs_get_offset}, - {"count_new", (getter)hs_get_count_new}, - {"count_new_urg", (getter)hs_get_count_new_urg}, - {NULL} /* Sentinel */ + {"state", (getter)hs_get_state}, + {"collect", (getter)hs_get_collect, (setter)hs_set_collect}, + {"collect_urg", (getter)hs_get_collect_urg, (setter)hs_set_collect_urg}, + {"data", (getter)hs_get_data}, + {"urgdata", (getter)hs_get_urgdata}, + {"count", (getter)hs_get_count}, + {"offset", (getter)hs_get_offset}, + {"count_new", (getter)hs_get_count_new}, + {"count_new_urg", (getter)hs_get_count_new_urg}, + {NULL} /* Sentinel */ }; static PyTypeObject HalfStream_Type = { - /* The ob_type field must be initialized in the module init function - * to be portable to Windows without using C++. */ - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ - "HalfStream", /*tp_name*/ - sizeof(HalfStream), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)HalfStream_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - PyObject_GenericGetAttr, /*tp_getattro*/ - PyObject_GenericSetAttr, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - 0, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - 0, /*tp_methods*/ - 0, /*tp_members*/ - HalfStream_getsets, /*tp_getset*/ - 0, /*tp_base*/ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ + "HalfStream", /*tp_name*/ + sizeof(HalfStream), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)HalfStream_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + PyObject_GenericGetAttr, /*tp_getattro*/ + PyObject_GenericSetAttr, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + 0, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + HalfStream_getsets, /*tp_getset*/ + 0, /*tp_base*/ }; /* ====================================================================== */ /* User-Defined libnids Handler Hooks */ /* ====================================================================== */ -static void -callTcpFunc(struct tcp_stream *ts, void **param) -{ - PyObject *ret = NULL; - TcpStream *tso = NULL; - - DBG("callTcpFunc - init tso\n"); - tso = wrapTcpStream(ts); - if (! tso) return; - - DBG("callTcpFunc - call func %p(%p)\n", tcpFunc, tso); - ret = PyObject_CallFunction(tcpFunc, "O", tso); - - DBG("callTcpFunc - dealloc tso (ret: %p)\n", ret); - Py_DECREF(tso); - if (ret) { - Py_DECREF(ret); - } - return; +static void callTcpFunc(struct tcp_stream *ts, void **param) { + PyObject *ret = NULL; + TcpStream *tso = NULL; + + DBG("callTcpFunc - init tso\n"); + tso = wrapTcpStream(ts); + if (!tso) + return; + + DBG("callTcpFunc - call func %p(%p)\n", tcpFunc, tso); + ret = PyObject_CallFunction(tcpFunc, "O", tso); + + DBG("callTcpFunc - dealloc tso (ret: %p)\n", ret); + Py_DECREF(tso); + if (ret) { + Py_DECREF(ret); + } + return; } -static void -callUdpFunc(struct tuple4 *addr, u_char *data, int len, struct ip *pkt) -{ - PyObject *ret = NULL; - - DBG("callUdpFunc...\n"); - ret = PyObject_CallFunction(udpFunc, "(Ns#s#)", - pytuple4(addr), - data, len, - pkt, ntohs(pkt->ip_len)); - if (ret) { - Py_DECREF(ret); - } - return; +static void callUdpFunc(struct tuple4 *addr, u_char *data, int len, + struct ip *pkt) { + PyObject *ret = NULL; + + DBG("callUdpFunc...\n"); + ret = PyObject_CallFunction(udpFunc, "(Ns#s#)", pytuple4(addr), data, len, + pkt, ntohs(pkt->ip_len)); + if (ret) { + Py_DECREF(ret); + } + return; } -static void -callIpFunc(struct ip *pkt) -{ - PyObject *ret = NULL; - - DBG("callIpFunc...\n"); - ret = PyObject_CallFunction(ipFunc, "s#", pkt, ntohs(pkt->ip_len)); - if (ret) { - Py_DECREF(ret); - } - return; +static void callIpFunc(struct ip *pkt) { + PyObject *ret = NULL; + + DBG("callIpFunc...\n"); + ret = PyObject_CallFunction(ipFunc, "s#", pkt, ntohs(pkt->ip_len)); + if (ret) { + Py_DECREF(ret); + } + return; } -static void -callFragFunc(struct ip *pkt) -{ - PyObject *ret = NULL; +static void callFragFunc(struct ip *pkt) { + PyObject *ret = NULL; - ret = PyObject_CallFunction(fragFunc, "s#", pkt, ntohs(pkt->ip_len)); - if (ret) { - Py_DECREF(ret); - } - return; + ret = PyObject_CallFunction(fragFunc, "s#", pkt, ntohs(pkt->ip_len)); + if (ret) { + Py_DECREF(ret); + } + return; } /* makeRegisterFunc(type, static PyFunction ptr, dispatch) @@ -561,37 +544,35 @@ callFragFunc(struct ip *pkt) * ip_frag fragFunc callFragFunc */ -#define makeRegisterFunc(WHAT, FP, PYDISPATCH) \ - \ -static char pynids_register_##WHAT##__doc__[] = \ -"register_" #WHAT "(func) -> None\n" \ -"\n" \ -"Register the given user-defined function as a callback handler.\n"; \ - \ -static PyObject * \ -pynids_register_##WHAT (PyObject *na, PyObject *args) \ -{ \ - PyObject *pyFunc = NULL; \ - if (!PyArg_ParseTuple(args, "O:register_" #WHAT, &pyFunc)) \ - return NULL; \ - \ - if (FP != NULL) { \ - /* (re-)set single, global func ptr */ \ - PyObject_Del(FP); \ - } \ - nids_register_##WHAT(PYDISPATCH); \ - DBG("Inside register_" #WHAT "(%p)\n", pyFunc); \ - FP = pyFunc; \ - Py_INCREF(FP); \ - Py_RETURN_NONE; \ -} +#define makeRegisterFunc(WHAT, FP, PYDISPATCH) \ + \ + static char pynids_register_##WHAT##__doc__[] = \ + "register_" #WHAT "(func) -> None\n" \ + "\n" \ + "Register the given user-defined function as a callback handler.\n"; \ + \ + static PyObject *pynids_register_##WHAT(PyObject *na, PyObject *args) { \ + PyObject *pyFunc = NULL; \ + if (!PyArg_ParseTuple(args, "O:register_" #WHAT, &pyFunc)) \ + return NULL; \ + \ + if (FP != NULL) { \ + /* (re-)set single, global func ptr */ \ + PyObject_Del(FP); \ + } \ + nids_register_##WHAT(PYDISPATCH); \ + DBG("Inside register_" #WHAT "(%p)\n", pyFunc); \ + FP = pyFunc; \ + Py_INCREF(FP); \ + Py_RETURN_NONE; \ + } /* What PyFunc * C-level Dispatch */ /* ---- -------- ---------------- */ -makeRegisterFunc(tcp, tcpFunc, callTcpFunc); -makeRegisterFunc(udp, udpFunc, callUdpFunc); -makeRegisterFunc(ip, ipFunc, callIpFunc); +makeRegisterFunc(tcp, tcpFunc, callTcpFunc); +makeRegisterFunc(udp, udpFunc, callUdpFunc); +makeRegisterFunc(ip, ipFunc, callIpFunc); makeRegisterFunc(ip_frag, fragFunc, callFragFunc); /* ====================================================================== */ @@ -599,7 +580,7 @@ makeRegisterFunc(ip_frag, fragFunc, callFragFunc); /* ====================================================================== */ static char pynids_chksum_ctl__doc__[] = -"chksum_ctl([(addr1, True), (addr2, False)], ...) -> None\n\ + "chksum_ctl([(addr1, True), (addr2, False)], ...) -> None\n\ \n\ takes as arguments an list of tuples where a tuple should have the\n\ following format:\n\ @@ -612,404 +593,406 @@ be checksummed if the apply boolean is set to True, or not checksummed if\n\ the boolean is set to False. If the packet matches none of the list\n\ elements, the default action is to perform checksumming.\n"; -static int -_parse_prefix(char *prefix, u_int *netaddr, u_int *mask) -{ - struct in_addr in; - char *ptr, *data; - u_int m; - - /* eat up white space */ - data = prefix; - while (*data == ' ' && *data == '\t') - data++; - - /* find end */ - ptr = data; - while (*ptr != '/' && *ptr != '\n' && *ptr != '\0') - ptr++; - - if (*ptr == '/') - { - *ptr = '\0'; - ptr++; - - /* convert the ip to binary */ - if (inet_pton(AF_INET, data, &in) < 0) - { - PyErr_SetFromErrno(PyExc_OSError); - return -1; - } - *netaddr = in.s_addr; - - /* get mask */ - m = 32 - atoi(ptr); - *mask = (m >= 32) ? 0 : htonl((0xffffffff >> m) << m); - } - else if (strlen(data) >= 7) - { - /* convert the ip to binary */ - if (inet_pton(AF_INET, data, &in) < 0) - { - PyErr_SetFromErrno(PyExc_OSError); - return -1; - } - *netaddr = in.s_addr; - *mask = 0xffffffff; - } - - return 0; +static int _parse_prefix(char *prefix, u_int *netaddr, u_int *mask) { + struct in_addr in; + char *ptr, *data; + u_int m; + + /* eat up white space */ + data = prefix; + while (*data == ' ' && *data == '\t') + data++; + + /* find end */ + ptr = data; + while (*ptr != '/' && *ptr != '\n' && *ptr != '\0') + ptr++; + + if (*ptr == '/') { + *ptr = '\0'; + ptr++; + + /* convert the ip to binary */ + if (inet_pton(AF_INET, data, &in) < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + *netaddr = in.s_addr; + + /* get mask */ + m = 32 - atoi(ptr); + *mask = (m >= 32) ? 0 : htonl((0xffffffff >> m) << m); + } else if (strlen(data) >= 7) { + /* convert the ip to binary */ + if (inet_pton(AF_INET, data, &in) < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + *netaddr = in.s_addr; + *mask = 0xffffffff; + } + + return 0; } -static int -_parse_chksum_tuple(struct nids_chksum_ctl *ctl, int i, PyObject *tuple) -{ - PyObject *addr, *action; - - addr = PyTuple_GET_ITEM(tuple, 0); - if (PyString_Check(addr) <= 0) - { - PyErr_SetString(PyExc_TypeError, - "in (cidr_address, action) cidr_address must be string"); - return -1; - } - if (_parse_prefix(PyString_AS_STRING(addr), &ctl[i].netaddr, - &ctl[i].mask) < 0) - return -1; - - action = PyTuple_GET_ITEM(tuple, 1); - if (PyBool_Check(action) <= 0) - { - PyErr_SetString(PyExc_TypeError, - "in (cidr_address, action) action must be boolean"); - return -1; - } - if (action == Py_False) - ctl[i].action = NIDS_DONT_CHKSUM; - else - ctl[i].action = NIDS_DO_CHKSUM; - - return 0; +static int _parse_chksum_tuple(struct nids_chksum_ctl *ctl, int i, + PyObject *tuple) { + PyObject *addr, *action; + + addr = PyTuple_GET_ITEM(tuple, 0); + if (PyString_Check(addr) <= 0) { + PyErr_SetString(PyExc_TypeError, + "in (cidr_address, action) cidr_address must be string"); + return -1; + } + if (_parse_prefix(PyString_AS_STRING(addr), &ctl[i].netaddr, &ctl[i].mask) < + 0) + return -1; + + action = PyTuple_GET_ITEM(tuple, 1); + if (PyBool_Check(action) <= 0) { + PyErr_SetString(PyExc_TypeError, + "in (cidr_address, action) action must be boolean"); + return -1; + } + if (action == Py_False) + ctl[i].action = NIDS_DONT_CHKSUM; + else + ctl[i].action = NIDS_DO_CHKSUM; + + return 0; } -static PyObject * -pynids_chksum_ctl(PyObject *na, PyObject *args) -{ - PyObject *items, *tuple; - int i, n; - struct nids_chksum_ctl *ctl = NULL; - - /* parse args */ - if (!PyArg_ParseTuple(args, "O:chksum_ctl", &items)) - return NULL; - - /* parse list of address/action tuples */ - if (PyList_Check(items) > 0) - { - n = PyList_Size(items); - ctl = (struct nids_chksum_ctl *) \ - malloc(sizeof(struct nids_chksum_ctl) * n); - if (ctl == NULL) - { - PyErr_SetString(PyExc_OSError, - "could not allocate temp memory storage"); - return NULL; - } - for (i=0; i 0) { + n = PyList_Size(items); + ctl = (struct nids_chksum_ctl *)malloc(sizeof(struct nids_chksum_ctl) * n); + if (ctl == NULL) { + PyErr_SetString(PyExc_OSError, "could not allocate temp memory storage"); + return NULL; + } + for (i = 0; i < n; i++) { + tuple = PyList_GetItem(items, i); + if (PyTuple_Check(tuple) <= 0 || PyTuple_GET_SIZE(tuple) != 2) { + PyErr_SetString(PyExc_TypeError, + "list must contain (cidr_address, action) tuples"); + free(ctl); + return NULL; + } + if (_parse_chksum_tuple(ctl, i, tuple) < 0) { + free(ctl); + return NULL; + } + } + } else { + PyErr_SetString(PyExc_TypeError, "chksum_ctl requires a list param"); + return NULL; + } + + nids_register_chksum_ctl(ctl, n); + + Py_RETURN_NONE; } static char pynids_param__doc__[] = -"param(name[, new_value]) -> old_value\n\ -\n\ -If new_value is specified, set the named nids attribute to the new value.\n\ -Returns the previous value in any case. Supported parameters and their\n\ -defaults are:\n\ -\n\ -device -- network device to use as input (None); see also 'filename'\n\ -filename -- pcap filename to use as input (None); see also 'device'\n\ -dev_addon -- number of bytes in struct sk_buff for layer 2 info (-1)\n\ -one_loop_less -- undocumented\n\ -n_hosts -- size of IP defragmentation info hash table (256)\n\ -n_tcp_streams -- size of TCP connection hash table (1024)\n\ -pcap_filter -- pcap filter string applied to unassembled packets (None)\n" -#if (NIDS_MAJOR > 1 || (NIDS_MAJOR == 1 && NIDS_MINOR >= 19)) -"pcap_timeout -- pcap capture timeout, in milliseconds (1024)\n" -#endif /* libnids >= 1.19 */ -"promisc -- non-zero if promiscuous mode is desired on capture device (1)\n\ -sk_buff_size -- size of struct skbuff, used for queueing packets (168)\n\ -syslog_level -- log level used when syslogging events (LOG_ALERT)\n\ -scan_num_hosts -- hash table size for portscan detection (256)\n\ -scan_num_ports -- minimum ports per src. host to qualify as a portscan (10)\n\ -scan_delay -- maximum delay in milliseconds between (3000)\n\ -tcp_flow_timeout -- timeout in seconds to distinguish flows with sample tuple\n\ -\n\ -Either 'device' or 'filename' must be specified before calling nids_init().\n\ -Portscan detection may be disabled by setting 'scan_num_hosts' to zero. See\n\ -the libnids documentation for more details.\n"; - -static PyObject * -pynids_param(PyObject *na, PyObject *args) -{ - PyObject *v = NULL; - PyObject *ret = NULL; - int *int_p = NULL; - char **char_pp = NULL; - char *name; - - if (!PyArg_ParseTuple(args, "s|O", &name, &v)) return NULL; - - /* is it an int parameter? */ - if (!strcmp(name, "n_tcp_streams")) - int_p = &nids_params.n_tcp_streams; - else if (!strcmp(name, "n_hosts")) - int_p = &nids_params.n_hosts; - else if (!strcmp(name, "sk_buff_size")) - int_p = &nids_params.sk_buff_size; - else if (!strcmp(name, "dev_addon")) - int_p = &nids_params.dev_addon; - else if (!strcmp(name, "syslog_level")) - int_p = &nids_params.syslog_level; - else if (!strcmp(name, "scan_num_hosts")) - int_p = &nids_params.scan_num_hosts; - else if (!strcmp(name, "scan_num_ports")) - int_p = &nids_params.scan_num_ports; - else if (!strcmp(name, "scan_delay")) - int_p = &nids_params.scan_delay; - else if (!strcmp(name, "promisc")) - int_p = &nids_params.promisc; - else if (!strcmp(name, "one_loop_less")) - int_p = &nids_params.one_loop_less; + "param(name[, new_value]) -> old_value\n" + "\n" + "If new_value is specified, set the named nids attribute to the new " + "value.\n" + "Returns the previous value in any case. Supported parameters and their\n" + "defaults are:\n" + "\n" + "device -- network device to use as input (None); see also 'filename'\n" + "filename -- pcap filename to use as input (None); see also 'device'\n" + "dev_addon -- number of bytes in struct sk_buff for layer 2 info (-1)\n" + "one_loop_less -- undocumented\n" + "n_hosts -- size of IP defragmentation info hash table (256)\n" + "n_tcp_streams -- size of TCP connection hash table (1024)\n" + "pcap_filter -- pcap filter string applied to unassembled packets (None)\n" + "#if (NIDS_MAJOR > 1 || (NIDS_MAJOR == 1 && NIDS_MINOR >= 19)) + " " pcap_timeout-- pcap capture timeout, + in milliseconds(1024)\n " + "#endif /* libnids >= 1.19 */ + " " promisc-- non + - zero if promiscuous mode is desired on capture device(1)\n + " + "sk_buff_size -- size of struct skbuff, used for queueing " + "packets (168)\n" + "syslog_level -- log level used when syslogging events " + "(LOG_ALERT)\n" + "scan_num_hosts -- hash table size for portscan detection " + "(256)\n" + "scan_num_ports -- minimum ports per src. host to qualify as a " + "portscan (10)\n" + "scan_delay -- maximum delay in milliseconds between (3000)\n" + "tcp_flow_timeout -- timeout in seconds to distinguish flows " + "with sample tuple\n" + "\n" + "Either 'device' or 'filename' must be specified before " + "calling nids_init().\n" + "Portscan detection may be disabled by setting " + "'scan_num_hosts' to zero. See\n" + "the libnids documentation for more details.\n"; + +static PyObject *pynids_param(PyObject *na, PyObject *args) { + PyObject *v = NULL; + PyObject *ret = NULL; + int *int_p = NULL; + char **char_pp = NULL; + char *name; + + if (!PyArg_ParseTuple(args, "s|O", &name, &v)) + return NULL; + + /* is it an int parameter? */ + if (!strcmp(name, "n_tcp_streams")) + int_p = &nids_params.n_tcp_streams; + else if (!strcmp(name, "n_hosts")) + int_p = &nids_params.n_hosts; + else if (!strcmp(name, "sk_buff_size")) + int_p = &nids_params.sk_buff_size; + else if (!strcmp(name, "dev_addon")) + int_p = &nids_params.dev_addon; + else if (!strcmp(name, "syslog_level")) + int_p = &nids_params.syslog_level; + else if (!strcmp(name, "scan_num_hosts")) + int_p = &nids_params.scan_num_hosts; + else if (!strcmp(name, "scan_num_ports")) + int_p = &nids_params.scan_num_ports; + else if (!strcmp(name, "scan_delay")) + int_p = &nids_params.scan_delay; + else if (!strcmp(name, "promisc")) + int_p = &nids_params.promisc; + else if (!strcmp(name, "one_loop_less")) + int_p = &nids_params.one_loop_less; #if (NIDS_MAJOR > 1 || (NIDS_MAJOR == 1 && NIDS_MINOR >= 19)) - else if (!strcmp(name, "pcap_timeout")) - int_p = &nids_params.pcap_timeout; + else if (!strcmp(name, "pcap_timeout")) + int_p = &nids_params.pcap_timeout; #endif /* libnids >= 1.19 */ - else if (!strcmp(name, "tcp_flow_timeout")) - int_p = &nids_params.tcp_flow_timeout; - - if (int_p) { - /* FIXME - type check val for intishness */ - ret = PyInt_FromLong((long) *int_p); - if (v) *int_p = (int) PyInt_AsLong(v); - return ret; - } - - /* is it a char * param? */ - if (!strcmp(name, "device")) - char_pp = &nids_params.device; - else if (!strcmp(name, "pcap_filter")) - char_pp = &nids_params.pcap_filter; - else if (!strcmp(name, "filename")) - char_pp = &nids_params.filename; - - if (char_pp) { - /* XXX - error checking, PyMem alloc/free */ - ret = Py_BuildValue("s", *char_pp); - if (v) { - /* free previous strdup -- fortunately libnids inits these to - * NULL... - */ - if (*char_pp) free(*char_pp); - *char_pp = (v == Py_None) ? NULL : strdup(PyString_AsString(v)); - } - return ret; - } - - /****** - if (!strcmp(name, "syslog")) - func_pp = &nids.syslog; - else if (!strcmp(name, "ip_filter")) - func_pp = &nids.ip_filter; - else if (!strcmp(name, "no_mem")) - func_pp = &nids.no_mem; - ******/ - - Py_RETURN_NONE; + else if (!strcmp(name, "tcp_flow_timeout")) + int_p = &nids_params.tcp_flow_timeout; + + if (int_p) { + /* FIXME - type check val for intishness */ + ret = PyInt_FromLong((long)*int_p); + if (v) + *int_p = (int)PyInt_AsLong(v); + return ret; + } + + /* is it a char * param? */ + if (!strcmp(name, "device")) + char_pp = &nids_params.device; + else if (!strcmp(name, "pcap_filter")) + char_pp = &nids_params.pcap_filter; + else if (!strcmp(name, "filename")) + char_pp = &nids_params.filename; + + if (char_pp) { + /* XXX - error checking, PyMem alloc/free */ + ret = Py_BuildValue("s", *char_pp); + if (v) { + /* free previous strdup -- fortunately libnids inits these to + * NULL... + */ + if (*char_pp) + free(*char_pp); + *char_pp = (v == Py_None) ? NULL : strdup(PyString_AsString(v)); + } + return ret; + } + + /****** + if (!strcmp(name, "syslog")) + func_pp = &nids.syslog; + else if (!strcmp(name, "ip_filter")) + func_pp = &nids.ip_filter; + else if (!strcmp(name, "no_mem")) + func_pp = &nids.no_mem; +******/ + + Py_RETURN_NONE; } static char pynids_getfd__doc__[] = -"getfd() -> fd\n\ -\n\ -Returns the integral file descriptor of the live capture device or pcap\n\ -savefile specified during the call to init(). The resultant fd is suitable\n\ -for I/O polling with select.select(), for example.\n"; - -static PyObject * -pynids_getfd(PyObject *na, PyObject *args) -{ - int pcap_fd; - - if (!PyArg_ParseTuple(args, ":getfd")) return NULL; - - if ((pcap_fd = nids_getfd()) == -1) return raisePynidsError(); - return PyInt_FromLong((long) pcap_fd); + "getfd() -> fd\n" + "\n" + "Returns the integral file descriptor of the live capture device or pcap\n" + "savefile specified during the call to init(). The resultant fd is " + "suitable\n" + "for I/O polling with select.select(), for example.\n"; + +static PyObject *pynids_getfd(PyObject *na, PyObject *args) { + int pcap_fd; + + if (!PyArg_ParseTuple(args, ":getfd")) + return NULL; + + if ((pcap_fd = nids_getfd()) == -1) + return raisePynidsError(); + return PyInt_FromLong((long)pcap_fd); } -static char pynids_next__doc__[] = -"next() -> r\n\ -\n\ -Attempt to process one packet, returning 1 if a packet was processed and 0\n\ -on timeout or EOF, as appropriate to the capture stream. Serious errors in\n\ -pcap raise a nids.error exception.\n"; +static char pynids_next__doc__[] = "next() -> r\n" + "\n" + "Attempt to process one packet, returning 1 " + "if a packet was processed and 0\n" + "on timeout or EOF, as appropriate to the " + "capture stream. Serious errors in\n" + "pcap raise a nids.error exception.\n"; -static PyObject * -pynids_next(PyObject *na, PyObject *args) -{ - int ret; +static PyObject *pynids_next(PyObject *na, PyObject *args) { + int ret; - if (!PyArg_ParseTuple(args, ":next")) return NULL; + if (!PyArg_ParseTuple(args, ":next")) + return NULL; - ret = nids_dispatch_exc(1); - if (PyErr_Occurred()) return NULL; /* python callback error */ + ret = nids_dispatch_exc(1); + if (PyErr_Occurred()) + return NULL; /* python callback error */ - return PyInt_FromLong((long) ret); + return PyInt_FromLong((long)ret); } static char pynids_dispatch__doc__[] = -"dispatch(cnt) -> processed\n\ -\n\ -UNDOCUMENTED -- this function does not exist in libnids <= 1.19.\n"; + "dispatch(cnt) -> processed\n" + "\n" + "UNDOCUMENTED -- this function does not exist in libnids <= 1.19.\n"; -static PyObject * -pynids_dispatch(PyObject *na, PyObject *args) -{ - int ret, cnt; +static PyObject *pynids_dispatch(PyObject *na, PyObject *args) { + int ret, cnt; - if (!PyArg_ParseTuple(args, "i:dispatch", &cnt)) return NULL; + if (!PyArg_ParseTuple(args, "i:dispatch", &cnt)) + return NULL; - ret = nids_dispatch_exc(cnt); - if (ret == -1) return NULL; + ret = nids_dispatch_exc(cnt); + if (ret == -1) + return NULL; - return PyInt_FromLong((long) ret); + return PyInt_FromLong((long)ret); } static char pynids_run__doc__[] = -"run() -> None\n\ -\n\ -On a live capture, process packets ad infinitum; on an offline read, process\n\ -packets until EOF. In either case, an exception thrown in a user callback\n\ -or in nids/pcap (as nids.error) may abort processing.\n"; - -static PyObject * -pynids_run(PyObject *na, PyObject *args) -{ - int r; - - if (!PyArg_ParseTuple(args, ":run")) return NULL; - - if (pynids_offline_read) { - /* read until EOF, checking for exceptions along the way */ - do { r = nids_dispatch_exc(1); } while (r > 0); - } else { - /* read forever, checking for exceptions along the way */ - do { r = nids_dispatch_exc(1); } while (r >= 0); - } - - if (r == -1) return NULL; + "run() -> None\n" + "\n" + "On a live capture, process packets ad infinitum; on an offline read, " + "process\n" + "packets until EOF. In either case, an exception thrown in a user " + "callback\n" + "or in nids/pcap (as nids.error) may abort processing.\n"; + +static PyObject *pynids_run(PyObject *na, PyObject *args) { + int r; + + if (!PyArg_ParseTuple(args, ":run")) + return NULL; + + if (pynids_offline_read) { + /* read until EOF, checking for exceptions along the way */ + do { + r = nids_dispatch_exc(1); + } while (r > 0); + } else { + /* read forever, checking for exceptions along the way */ + do { + r = nids_dispatch_exc(1); + } while (r >= 0); + } + + if (r == -1) + return NULL; #if 0 - if (r != 0) runtime error! + if (r != 0) runtime error! #endif - Py_RETURN_NONE; + Py_RETURN_NONE; } static char pynids_init__doc__[] = -"init() -> None\n\ -\n\ -Initialize the nids library, as specified by previous calls to param(). In\n\ -particular, the capture device 'device' or pcap savefile 'filename' is\n\ -opened, the 'pcap_filter' compiled, and various internal mechanisms prepared.\n\ -\n\ -It is appropriate and recommended to drop process privileges after making\n\ -this call.\n"; + "init() -> None\n" + "\n" + "Initialize the nids library, as specified by previous calls to param(). " + "In\n" + "particular, the capture device 'device' or pcap savefile 'filename' is\n" + "opened, the 'pcap_filter' compiled, and various internal mechanisms " + "prepared.\n" + "\n" + "It is appropriate and recommended to drop process privileges after " + "making\n" + "this call.\n"; + +static PyObject *pynids_init(PyObject *na, PyObject *args) { + int ok; + if (!PyArg_ParseTuple(args, ":init")) + return NULL; + + ok = nids_init(); + if (!ok) + return raisePynidsError(); + if (nids_params.filename) + pynids_offline_read = 1; + else + pynids_offline_read = 0; + + Py_RETURN_NONE; +} -static PyObject * -pynids_init(PyObject *na, PyObject *args) -{ - int ok; - if (!PyArg_ParseTuple(args, ":init")) return NULL; +static char pynids_get_pkt_ts__doc__[] = + "get_pkt_time() -> float\n" + "\n" + "Returns the timestamp of the most recent packet as a float.\n"; - ok = nids_init(); - if (! ok) return raisePynidsError(); - if (nids_params.filename) pynids_offline_read = 1; - else pynids_offline_read = 0; +static PyObject *pynids_get_pkt_ts(PyObject *na, PyObject *args) { + double pkt_time; - Py_RETURN_NONE; -} + if (!PyArg_ParseTuple(args, ":get_pkt_ts")) + return NULL; -static char pynids_get_pkt_ts__doc__[] = -"get_pkt_time() -> float\n\ -\n\ -Returns the timestamp of the most recent packet as a float.\n"; - -static PyObject * -pynids_get_pkt_ts(PyObject *na, PyObject *args) -{ - double pkt_time; - - if (!PyArg_ParseTuple(args, ":get_pkt_ts")) return NULL; - - pkt_time = nids_last_pcap_header->ts.tv_sec + - (nids_last_pcap_header->ts.tv_usec / 1000000.0); - return PyFloat_FromDouble(pkt_time); + pkt_time = nids_last_pcap_header->ts.tv_sec + + (nids_last_pcap_header->ts.tv_usec / 1000000.0); + return PyFloat_FromDouble(pkt_time); } static char pynids_get_pcap_stats__doc__[] = -"get_pcap_stats() -> tuple\n\ -\n\ -Returns the pcap recv, drop and interface drop statistics as a tuple.\n"; - -static PyObject * -pynids_get_pcap_stats(PyObject *na, PyObject *args) -{ - static struct pcap_stat ps; - PyObject *pcap_stats_tuple; - - if (!PyArg_ParseTuple(args, ":get_pcap_stats")) return NULL; - - if (nids_params.pcap_desc == NULL || - pcap_stats(nids_params.pcap_desc, &ps) != 0) { - raisePynidsError(); - return NULL; - } + "get_pcap_stats() -> tuple\n" + "\n" + "Returns the pcap recv, drop and interface drop statistics as a tuple.\n"; + +static PyObject *pynids_get_pcap_stats(PyObject *na, PyObject *args) { + static struct pcap_stat ps; + PyObject *pcap_stats_tuple; + + if (!PyArg_ParseTuple(args, ":get_pcap_stats")) + return NULL; - pcap_stats_tuple = Py_BuildValue("III", ps.ps_recv, ps.ps_drop, - ps.ps_ifdrop); + if (nids_params.pcap_desc == NULL || + pcap_stats(nids_params.pcap_desc, &ps) != 0) { + raisePynidsError(); + return NULL; + } - if (! pcap_stats_tuple) return NULL; + pcap_stats_tuple = Py_BuildValue("III", ps.ps_recv, ps.ps_drop, ps.ps_ifdrop); - return pcap_stats_tuple; + if (!pcap_stats_tuple) + return NULL; + + return pcap_stats_tuple; } /* List of functions defined in the module */ -#define mkMethod(x) \ - {#x, pynids_##x, METH_VARARGS, pynids_##x##__doc__} +#define mkMethod(x) \ + { #x, pynids_##x, METH_VARARGS, pynids_##x##__doc__ } static PyMethodDef pynids_methods[] = { mkMethod(run), @@ -1025,63 +1008,58 @@ static PyMethodDef pynids_methods[] = { mkMethod(param), mkMethod(get_pkt_ts), mkMethod(get_pcap_stats), - {NULL, NULL} /* sentinel */ + {NULL, NULL} /* sentinel */ }; #undef mkMethod static struct PyModuleDef moduledef = { - PyModuleDef_HEAD_INIT, /* m_base */ - "nids", /* m_name */ - pynidsmodule__doc__, /* m_doc */ - -1, /* m_size */ - pynids_methods /* m_methods */ + PyModuleDef_HEAD_INIT, /* m_base */ + "nids", /* m_name */ + pynidsmodule__doc__, /* m_doc */ + -1, /* m_size */ + pynids_methods /* m_methods */ }; /* ====================================================================== */ /* Module Initialization */ /* ====================================================================== */ PyMODINIT_FUNC PyInit_nids(void) { - PyObject *m; + PyObject *m; - /* Initialize the type of the new type object here; doing it here - * is required for portability to Windows without requiring C++. */ -Py_TYPE(& TcpStream_Type) = &PyType_Type; -Py_TYPE(& HalfStream_Type) = &PyType_Type; + /* Initialize the type of the new type object here; doing it here + * is required for portability to Windows without requiring C++. */ + Py_TYPE(&TcpStream_Type) = &PyType_Type; + Py_TYPE(&HalfStream_Type) = &PyType_Type; - /* Create the module and add the functions */ + /* Create the module and add the functions */ - m = PyModule_Create(&moduledef); + m = PyModule_Create(&moduledef); - /* Initialize, add our exception object */ - pynids_error = PyErr_NewException("nids.error", NULL, NULL); - Py_INCREF(pynids_error); - PyModule_AddObject(m, "error", pynids_error); + /* Initialize, add our exception object */ + pynids_error = PyErr_NewException("nids.error", NULL, NULL); + Py_INCREF(pynids_error); + PyModule_AddObject(m, "error", pynids_error); - /* Add versioning info */ - PyModule_AddStringConstant(m, "__version__", "0.6.2"); - PyModule_AddObject(m, "__nids_version__", - PyString_FromFormat("%d.%d", NIDS_MAJOR, NIDS_MINOR)); + /* Add versioning info */ + PyModule_AddStringConstant(m, "__version__", "0.6.2"); + PyModule_AddObject(m, "__nids_version__", + PyString_FromFormat("%d.%d", NIDS_MAJOR, NIDS_MINOR)); - /* Add NIDS_ symbolic constants to the module */ -#define setConst(CONST) \ - PyModule_AddIntConstant(m, #CONST, CONST) + /* Add NIDS_ symbolic constants to the module */ +#define setConst(CONST) PyModule_AddIntConstant(m, #CONST, CONST) - setConst(NIDS_JUST_EST); - setConst(NIDS_DATA); - setConst(NIDS_CLOSE); - setConst(NIDS_RESET); - setConst(NIDS_TIMED_OUT); + setConst(NIDS_JUST_EST); + setConst(NIDS_DATA); + setConst(NIDS_CLOSE); + setConst(NIDS_RESET); + setConst(NIDS_TIMED_OUT); #ifndef NIDS_TIMEOUT #define NIDS_TIMEOUT NIDS_TIMED_OUT #endif - setConst(NIDS_TIMEOUT); /* compat. w/ manpage */ - setConst(NIDS_EXITING); + setConst(NIDS_TIMEOUT); /* compat. w/ manpage */ + setConst(NIDS_EXITING); - /* Save the original nids_params */ - origNidsParams = nids_params; - return m; + /* Save the original nids_params */ + origNidsParams = nids_params; + return m; } - -/* - * vim:noet:ts=4: - */ From 283d5481bae86e4109558bea13f7b80e6f5dbc7f Mon Sep 17 00:00:00 2001 From: James Stronz Date: Sun, 22 Sep 2019 17:38:18 -0500 Subject: [PATCH 05/23] Fix incorrect sed change due to docstring macro and change in multiline char array style --- nidsmodule.c | 45 +++++++++++++++++++++------------------------ 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/nidsmodule.c b/nidsmodule.c index 2813e08..ee22156 100644 --- a/nidsmodule.c +++ b/nidsmodule.c @@ -718,30 +718,27 @@ static char pynids_param__doc__[] = "n_hosts -- size of IP defragmentation info hash table (256)\n" "n_tcp_streams -- size of TCP connection hash table (1024)\n" "pcap_filter -- pcap filter string applied to unassembled packets (None)\n" - "#if (NIDS_MAJOR > 1 || (NIDS_MAJOR == 1 && NIDS_MINOR >= 19)) - " " pcap_timeout-- pcap capture timeout, - in milliseconds(1024)\n " - "#endif /* libnids >= 1.19 */ - " " promisc-- non - - zero if promiscuous mode is desired on capture device(1)\n - " - "sk_buff_size -- size of struct skbuff, used for queueing " - "packets (168)\n" - "syslog_level -- log level used when syslogging events " - "(LOG_ALERT)\n" - "scan_num_hosts -- hash table size for portscan detection " - "(256)\n" - "scan_num_ports -- minimum ports per src. host to qualify as a " - "portscan (10)\n" - "scan_delay -- maximum delay in milliseconds between (3000)\n" - "tcp_flow_timeout -- timeout in seconds to distinguish flows " - "with sample tuple\n" - "\n" - "Either 'device' or 'filename' must be specified before " - "calling nids_init().\n" - "Portscan detection may be disabled by setting " - "'scan_num_hosts' to zero. See\n" - "the libnids documentation for more details.\n"; +#if (NIDS_MAJOR > 1 || (NIDS_MAJOR == 1 && NIDS_MINOR >= 19)) + "pcap_timeout-- pcap capture timeout, in milliseconds(1024)\n" +#endif /* libnids >= 1.19 */ + "promisc-- non-zero if promiscuous mode is desired on capture device(1)\n" + "sk_buff_size -- size of struct skbuff, used for queueing " + "packets (168)\n" + "syslog_level -- log level used when syslogging events " + "(LOG_ALERT)\n" + "scan_num_hosts -- hash table size for portscan detection " + "(256)\n" + "scan_num_ports -- minimum ports per src. host to qualify as a " + "portscan (10)\n" + "scan_delay -- maximum delay in milliseconds between (3000)\n" + "tcp_flow_timeout -- timeout in seconds to distinguish flows " + "with sample tuple\n" + "\n" + "Either 'device' or 'filename' must be specified before " + "calling nids_init().\n" + "Portscan detection may be disabled by setting " + "'scan_num_hosts' to zero. See\n" + "the libnids documentation for more details.\n"; static PyObject *pynids_param(PyObject *na, PyObject *args) { PyObject *v = NULL; From 6d51fef07fbe0f6550cc8b2ebe65ef7ae948ff95 Mon Sep 17 00:00:00 2001 From: James Stronz Date: Sun, 22 Sep 2019 17:47:57 -0500 Subject: [PATCH 06/23] Cleanup macros for long/int unification in the C-API for python 3 --- nidsmodule.c | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/nidsmodule.c b/nidsmodule.c index ee22156..51775d9 100644 --- a/nidsmodule.c +++ b/nidsmodule.c @@ -43,14 +43,8 @@ #else #define DBG(p, ...) #endif /* DEBUG */ -// initial 2to3 -#if PY_MAJOR_VERSION >= 3 - -#define PyInt_AsLong PyLong_AsLong -#define PyInt_AS_LONG PyLong_AS_LONG -#define PyInt_Check PyLong_Check -#define PyInt_FromLong PyLong_FromLong -#define PyInt_Type PyLong_Type + +// Macros for initial pass on module port to Python 3 #define PyString_AsStringAndSize PyBytes_AsStringAndSize // #define PyString_AsString PyBytes_AsString #define PyString_AS_STRING PyBytes_AS_STRING @@ -65,8 +59,8 @@ #define PyString_FromString PyUnicode_FromString #define PyString_Join PyUnicode_Join // #define PyString_Size PyBytes_Size -#define PyString_Size PyUnicode_Size -#define PyString_Type PyUnicode_Type +#define PyString_Size PyBytes_Size +#define PyString_Type PyBytes_Type #define Py_TPFLAGS_HAVE_ITER 0 #define PyUnicode_AsString(x) \ PyBytes_AsString(PyUnicode_AsEncodedString((x), "utf-8", "strict")) @@ -77,7 +71,6 @@ inline void PyString_ConcatAndDel(PyObject **lhs, PyObject *rhs) { Py_DECREF(rhs); } -#endif #ifndef Py_RETURN_NONE #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None @@ -309,7 +302,7 @@ static PyObject *ts_get_addr(TcpStream *self, void *unused) { return pytuple4(&self->tcps->addr); } static PyObject *ts_get_nids_state(TcpStream *self, void *unused) { - return PyInt_FromLong((long)self->tcps->nids_state); + return PyLong_FromLong((long)self->tcps->nids_state); } static PyGetSetDef TcpStream_getsets[] = { @@ -380,13 +373,13 @@ static void HalfStream_dealloc(HalfStream *self) { #define HS_GET_INT(ATTR) \ static PyObject *hs_get_##ATTR(HalfStream *self, void *unused) { \ - return PyInt_FromLong((long)self->hlfs->ATTR); \ + return PyLong_FromLong((long)self->hlfs->ATTR); \ } /* FIXME - true bool support */ #define HS_GET_BOOL(ATTR) \ static PyObject *hs_get_##ATTR(HalfStream *self, void *unused) { \ - return PyInt_FromLong(self->hlfs->ATTR ? 1L : 0L); \ + return PyLong_FromLong(self->hlfs->ATTR ? 1L : 0L); \ } #define HS_SET_BOOL(ATTR) \ @@ -780,9 +773,9 @@ static PyObject *pynids_param(PyObject *na, PyObject *args) { if (int_p) { /* FIXME - type check val for intishness */ - ret = PyInt_FromLong((long)*int_p); + ret = PyLong_FromLong((long)*int_p); if (v) - *int_p = (int)PyInt_AsLong(v); + *int_p = (int)PyLong_AsLong(v); return ret; } @@ -836,7 +829,7 @@ static PyObject *pynids_getfd(PyObject *na, PyObject *args) { if ((pcap_fd = nids_getfd()) == -1) return raisePynidsError(); - return PyInt_FromLong((long)pcap_fd); + return PyLong_FromLong((long)pcap_fd); } static char pynids_next__doc__[] = "next() -> r\n" @@ -857,7 +850,7 @@ static PyObject *pynids_next(PyObject *na, PyObject *args) { if (PyErr_Occurred()) return NULL; /* python callback error */ - return PyInt_FromLong((long)ret); + return PyLong_FromLong((long)ret); } static char pynids_dispatch__doc__[] = @@ -875,7 +868,7 @@ static PyObject *pynids_dispatch(PyObject *na, PyObject *args) { if (ret == -1) return NULL; - return PyInt_FromLong((long)ret); + return PyLong_FromLong((long)ret); } static char pynids_run__doc__[] = From c0697f1c747520bc74c0b1dc1216941cc2045252 Mon Sep 17 00:00:00 2001 From: James Stronz Date: Sun, 22 Sep 2019 17:52:40 -0500 Subject: [PATCH 07/23] Removed some unused macros copied when trying to get a working compile point --- nidsmodule.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/nidsmodule.c b/nidsmodule.c index 51775d9..26c376c 100644 --- a/nidsmodule.c +++ b/nidsmodule.c @@ -57,20 +57,6 @@ #define PyString_FromStringAndSize PyUnicode_FromStringAndSize // #define PyString_FromString PyBytes_FromString #define PyString_FromString PyUnicode_FromString -#define PyString_Join PyUnicode_Join -// #define PyString_Size PyBytes_Size -#define PyString_Size PyBytes_Size -#define PyString_Type PyBytes_Type -#define Py_TPFLAGS_HAVE_ITER 0 -#define PyUnicode_AsString(x) \ - PyBytes_AsString(PyUnicode_AsEncodedString((x), "utf-8", "strict")) -#define TEXT_T Py_UNICODE - -inline void PyString_ConcatAndDel(PyObject **lhs, PyObject *rhs) { - PyUnicode_Concat(*lhs, rhs); - Py_DECREF(rhs); -} - #ifndef Py_RETURN_NONE #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None From 0a48bc7a0193af3b76f60299b21d502df1da42dd Mon Sep 17 00:00:00 2001 From: James Stronz Date: Sun, 22 Sep 2019 18:00:39 -0500 Subject: [PATCH 08/23] Replaced PyString_FromStringAndSize with PyBytes_FromStringAndSize. As packet headers are binary, bytes is likely the desired type per https://docs.python.org/3/howto/cporting.html#str-unicode-unification --- nidsmodule.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/nidsmodule.c b/nidsmodule.c index 26c376c..55c627c 100644 --- a/nidsmodule.c +++ b/nidsmodule.c @@ -53,10 +53,9 @@ #define PyString_Check PyUnicode_Check #define PyString_FromFormat PyUnicode_FromFormat #define PyString_FromFormatV PyUnicode_FromFormatV -// #define PyString_FromStringAndSize PyBytes_FromStringAndSize -#define PyString_FromStringAndSize PyUnicode_FromStringAndSize +// #define PyBytes_FromStringAndSize PyBytes_FromStringAndSize +#define PyBytes_FromStringAndSize PyUnicode_FromStringAndSize // #define PyString_FromString PyBytes_FromString -#define PyString_FromString PyUnicode_FromString #ifndef Py_RETURN_NONE #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None @@ -391,13 +390,13 @@ HS_GET_INT(state) static PyObject *hs_get_data(HalfStream *self, void *unused) { /* data may not be allocated if the conn/libnids has seen no data */ if (!self->hlfs->data) - return PyString_FromStringAndSize("", 0); + return PyBytes_FromStringAndSize("", 0); /* bufsize is an undocumented member */ - return PyString_FromStringAndSize(self->hlfs->data, self->hlfs->bufsize); + return PyBytes_FromStringAndSize(self->hlfs->data, self->hlfs->bufsize); } static PyObject *hs_get_urgdata(HalfStream *self, void *unused) { /* u_char urgdata */ - return PyString_FromStringAndSize(&(self->hlfs->urgdata), + return PyBytes_FromStringAndSize(&(self->hlfs->urgdata), sizeof(self->hlfs->urgdata)); } HS_GET_INT(count) From 9d858d9a0c03c5d9bc7b1c022bb46065856d0163 Mon Sep 17 00:00:00 2001 From: James Stronz Date: Sun, 22 Sep 2019 18:01:52 -0500 Subject: [PATCH 09/23] Remove absurd redefinition of Bytes to Unicode that was copied of GitHub somewhere... --- nidsmodule.c | 1 - 1 file changed, 1 deletion(-) diff --git a/nidsmodule.c b/nidsmodule.c index 55c627c..d2f13fe 100644 --- a/nidsmodule.c +++ b/nidsmodule.c @@ -54,7 +54,6 @@ #define PyString_FromFormat PyUnicode_FromFormat #define PyString_FromFormatV PyUnicode_FromFormatV // #define PyBytes_FromStringAndSize PyBytes_FromStringAndSize -#define PyBytes_FromStringAndSize PyUnicode_FromStringAndSize // #define PyString_FromString PyBytes_FromString #ifndef Py_RETURN_NONE From 59c4fad9a380a4031f79ad3e7bf6b25dc82a7e41 Mon Sep 17 00:00:00 2001 From: James Stronz Date: Sun, 22 Sep 2019 18:03:28 -0500 Subject: [PATCH 10/23] Remove more nonsensical define macros: PyString_FromFormat and PyString_FromFormatV --- nidsmodule.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/nidsmodule.c b/nidsmodule.c index d2f13fe..ac089b7 100644 --- a/nidsmodule.c +++ b/nidsmodule.c @@ -51,10 +51,6 @@ #define PyString_AsString PyUnicode_AsString // #define PyString_Check PyBytes_Check #define PyString_Check PyUnicode_Check -#define PyString_FromFormat PyUnicode_FromFormat -#define PyString_FromFormatV PyUnicode_FromFormatV -// #define PyBytes_FromStringAndSize PyBytes_FromStringAndSize -// #define PyString_FromString PyBytes_FromString #ifndef Py_RETURN_NONE #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None From d107361c685e6e2b71caa94e26d5385c27ee48ee Mon Sep 17 00:00:00 2001 From: James Stronz Date: Sun, 22 Sep 2019 18:10:27 -0500 Subject: [PATCH 11/23] Removed macro for PyString_Check since PyErr_SetString requires that addr is a string within _parse_chksum_tuple --- nidsmodule.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/nidsmodule.c b/nidsmodule.c index ac089b7..8103582 100644 --- a/nidsmodule.c +++ b/nidsmodule.c @@ -49,8 +49,6 @@ // #define PyString_AsString PyBytes_AsString #define PyString_AS_STRING PyBytes_AS_STRING #define PyString_AsString PyUnicode_AsString -// #define PyString_Check PyBytes_Check -#define PyString_Check PyUnicode_Check #ifndef Py_RETURN_NONE #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None From f23e733518a5edb5599ec5743eebe198029649ad Mon Sep 17 00:00:00 2001 From: James Stronz Date: Sun, 22 Sep 2019 18:15:59 -0500 Subject: [PATCH 12/23] Remove last remaing conversion macros and cleaned seemingly ineffectual PyString_AS_STRING use... I miss unit tests --- nidsmodule.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/nidsmodule.c b/nidsmodule.c index 8103582..715469d 100644 --- a/nidsmodule.c +++ b/nidsmodule.c @@ -44,11 +44,6 @@ #define DBG(p, ...) #endif /* DEBUG */ -// Macros for initial pass on module port to Python 3 -#define PyString_AsStringAndSize PyBytes_AsStringAndSize -// #define PyString_AsString PyBytes_AsString -#define PyString_AS_STRING PyBytes_AS_STRING -#define PyString_AsString PyUnicode_AsString #ifndef Py_RETURN_NONE #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None @@ -616,7 +611,7 @@ static int _parse_chksum_tuple(struct nids_chksum_ctl *ctl, int i, "in (cidr_address, action) cidr_address must be string"); return -1; } - if (_parse_prefix(PyString_AS_STRING(addr), &ctl[i].netaddr, &ctl[i].mask) < + if (_parse_prefix(addr, &ctl[i].netaddr, &ctl[i].mask) < 0) return -1; From 97fb2d6b9969e5ee59370b3d88d9ecbe5f6a5119 Mon Sep 17 00:00:00 2001 From: James Stronz Date: Sun, 22 Sep 2019 18:18:08 -0500 Subject: [PATCH 13/23] Change line length limit from 80 to 120 since I do not have IBM punch cards and too short of line lengths negatively impact reading speed---justification of personal preference. --- .clang-format | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.clang-format b/.clang-format index d30c5da..f3a7fed 100644 --- a/.clang-format +++ b/.clang-format @@ -45,7 +45,7 @@ BreakConstructorInitializersBeforeComma: false BreakConstructorInitializers: BeforeColon BreakAfterJavaFieldAnnotations: false BreakStringLiterals: true -ColumnLimit: 80 +ColumnLimit: 120 CommentPragmas: '^ IWYU pragma:' CompactNamespaces: false ConstructorInitializerAllOnOneLineOrOnePerLine: false From 0cb75c3b8738c0acf902e32fa1b4f907cf24986d Mon Sep 17 00:00:00 2001 From: James Stronz Date: Sun, 22 Sep 2019 18:19:30 -0500 Subject: [PATCH 14/23] Ran clang-format after change of 80 to 120 char per line --- nidsmodule.c | 389 ++++++++++++++++++++++++--------------------------- 1 file changed, 179 insertions(+), 210 deletions(-) diff --git a/nidsmodule.c b/nidsmodule.c index 715469d..5f1f12f 100644 --- a/nidsmodule.c +++ b/nidsmodule.c @@ -44,7 +44,6 @@ #define DBG(p, ...) #endif /* DEBUG */ - #ifndef Py_RETURN_NONE #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None #endif /* Py_RETURN_NONE */ @@ -80,62 +79,61 @@ static PyTypeObject HalfStream_Type; /* wrapHalfStream used by TcpStream getter */ static HalfStream *wrapHalfStream(struct half_stream *); -static char pynidsmodule__doc__[] = - "A wrapper around the libnids Network Intrusion Detection library.\n" - "\n" - "Functions:\n" - "\n" - "param() -- set various libnids parameters\n" - "init() -- open the capture stream, prepare internal \n" - "getfd() -- return the file descriptor associated with the capture stream\n" - "get_pkt_ts() -- return the timestamp of the most recently received " - "packet\n" - "get_pcap_stats() -- return num packets rcvd, num pkts dropped,\n" - " num pkts dropped by interface as a tuple\n" - "register_ip_frag() -- install a callback for IP fragment processing\n" - "register_ip() -- install a callback for reassembled IP packet processing\n" - "register_tcp() -- install a callback for reaseembled TCP packet " - "processing\n" - "register_udp() -- install a callback for reassembled UDP packet " - "processing\n" - "chksum_ctl() -- control whether packets are checksum by source address\n" - "next() -- process one packet from the capture stream, invoking callbacks\n" - "run() -- process all packets from the capture stream, invoking callbacks\n" - "\n" - "Special objects and classes:\n" - "\n" - "error -- exception raised for serious libnids/pcap errors\n" - "TcpStream -- class of argument to TCP callback function. Features:\n" - " addr -- Connection tuple: ((src, sport), (dst, dport))\n" - " discard(n) -- purge n bytes from the data buffer\n" - " kill() -- send symmetric RSTs to tear down the connection\n" - " nids_state -- see 'Constants,' below\n" - " client -- half of the connection; a TcpStream object\n" - " server -- half of the connection; a TcpStream object\n" - "HalfStream -- class of TcpStream 'client' and 'server' members. " - "Features:\n" - " collect -- boolean controlling whether data is collected\n" - " collect_urg -- boolean controlling URG data collection\n" - " count -- number of bytes appended to 'data' since creation\n" - " count_new -- number of newly collected bytes in 'data'\n" - " count_new_urg -- number of new urgent bytes\n" - " data -- string buffer of normal (non-urgent) data\n" - " urgdata -- one-byte string buffer\n" - " offset -- offset of newly collected bytes in 'data'\n" - " state -- [*] numeric socket state\n" - "\n" - " * TCP state constants (e.g., TCP_ESTABLISHED) are not supplied by " - "pynids\n" - "\n" - "See the libnids documentation or the pynids README for more information\n" - "on the TcpStream and HalfStream objects.\n" - "\n" - "Constants:\n" - "\n" - "NIDS_CLOSE, NIDS_DATA, NIDS_EXITING, NIDS_JUST_EST, NIDS_RESET,\n" - "NIDS_TIMED_OUT, NIDS_TIMEOUT -- possible values of the 'nids_state' " - "member\n" - "of a TcpStream object.\n"; +static char pynidsmodule__doc__[] = "A wrapper around the libnids Network Intrusion Detection library.\n" + "\n" + "Functions:\n" + "\n" + "param() -- set various libnids parameters\n" + "init() -- open the capture stream, prepare internal \n" + "getfd() -- return the file descriptor associated with the capture stream\n" + "get_pkt_ts() -- return the timestamp of the most recently received " + "packet\n" + "get_pcap_stats() -- return num packets rcvd, num pkts dropped,\n" + " num pkts dropped by interface as a tuple\n" + "register_ip_frag() -- install a callback for IP fragment processing\n" + "register_ip() -- install a callback for reassembled IP packet processing\n" + "register_tcp() -- install a callback for reaseembled TCP packet " + "processing\n" + "register_udp() -- install a callback for reassembled UDP packet " + "processing\n" + "chksum_ctl() -- control whether packets are checksum by source address\n" + "next() -- process one packet from the capture stream, invoking callbacks\n" + "run() -- process all packets from the capture stream, invoking callbacks\n" + "\n" + "Special objects and classes:\n" + "\n" + "error -- exception raised for serious libnids/pcap errors\n" + "TcpStream -- class of argument to TCP callback function. Features:\n" + " addr -- Connection tuple: ((src, sport), (dst, dport))\n" + " discard(n) -- purge n bytes from the data buffer\n" + " kill() -- send symmetric RSTs to tear down the connection\n" + " nids_state -- see 'Constants,' below\n" + " client -- half of the connection; a TcpStream object\n" + " server -- half of the connection; a TcpStream object\n" + "HalfStream -- class of TcpStream 'client' and 'server' members. " + "Features:\n" + " collect -- boolean controlling whether data is collected\n" + " collect_urg -- boolean controlling URG data collection\n" + " count -- number of bytes appended to 'data' since creation\n" + " count_new -- number of newly collected bytes in 'data'\n" + " count_new_urg -- number of new urgent bytes\n" + " data -- string buffer of normal (non-urgent) data\n" + " urgdata -- one-byte string buffer\n" + " offset -- offset of newly collected bytes in 'data'\n" + " state -- [*] numeric socket state\n" + "\n" + " * TCP state constants (e.g., TCP_ESTABLISHED) are not supplied by " + "pynids\n" + "\n" + "See the libnids documentation or the pynids README for more information\n" + "on the TcpStream and HalfStream objects.\n" + "\n" + "Constants:\n" + "\n" + "NIDS_CLOSE, NIDS_DATA, NIDS_EXITING, NIDS_JUST_EST, NIDS_RESET,\n" + "NIDS_TIMED_OUT, NIDS_TIMEOUT -- possible values of the 'nids_state' " + "member\n" + "of a TcpStream object.\n"; static PyObject *raisePynidsError(void) { extern char nids_errbuf[]; @@ -257,23 +255,21 @@ static PyMethodDef TcpStream_methods[] = { {NULL, NULL} /* sentinel */ }; -#define TS_GET_HLFS(ATTR) \ - static PyObject *ts_get_##ATTR(TcpStream *self, void *unused) { \ - if (!self->ATTR) { \ - self->ATTR = (PyObject *)wrapHalfStream(&self->tcps->ATTR); \ - if (!self->ATTR) \ - return NULL; \ - } \ - Py_INCREF(self->ATTR); \ - return self->ATTR; \ +#define TS_GET_HLFS(ATTR) \ + static PyObject *ts_get_##ATTR(TcpStream *self, void *unused) { \ + if (!self->ATTR) { \ + self->ATTR = (PyObject *)wrapHalfStream(&self->tcps->ATTR); \ + if (!self->ATTR) \ + return NULL; \ + } \ + Py_INCREF(self->ATTR); \ + return self->ATTR; \ } /* RO attributes */ TS_GET_HLFS(client) TS_GET_HLFS(server) -static PyObject *ts_get_addr(TcpStream *self, void *unused) { - return pytuple4(&self->tcps->addr); -} +static PyObject *ts_get_addr(TcpStream *self, void *unused) { return pytuple4(&self->tcps->addr); } static PyObject *ts_get_nids_state(TcpStream *self, void *unused) { return PyLong_FromLong((long)self->tcps->nids_state); } @@ -327,8 +323,7 @@ static PyTypeObject TcpStream_Type = { /* HalfStreams: ctor, dtor, methods, members and type */ /* ====================================================================== */ -static HalfStream * -wrapHalfStream(struct half_stream *h) { /* called by TcpStream ctor */ +static HalfStream *wrapHalfStream(struct half_stream *h) { /* called by TcpStream ctor */ HalfStream *self; self = PyObject_New(HalfStream, &HalfStream_Type); if (self == NULL) @@ -344,28 +339,22 @@ static void HalfStream_dealloc(HalfStream *self) { PyObject_Del(self); } -#define HS_GET_INT(ATTR) \ - static PyObject *hs_get_##ATTR(HalfStream *self, void *unused) { \ - return PyLong_FromLong((long)self->hlfs->ATTR); \ - } +#define HS_GET_INT(ATTR) \ + static PyObject *hs_get_##ATTR(HalfStream *self, void *unused) { return PyLong_FromLong((long)self->hlfs->ATTR); } /* FIXME - true bool support */ -#define HS_GET_BOOL(ATTR) \ - static PyObject *hs_get_##ATTR(HalfStream *self, void *unused) { \ - return PyLong_FromLong(self->hlfs->ATTR ? 1L : 0L); \ - } - -#define HS_SET_BOOL(ATTR) \ - static int hs_set_##ATTR(HalfStream *self, PyObject *val, void *closure) { \ - if (val == NULL) { \ - PyErr_SetString(PyExc_TypeError, \ - "Cannot delete the " #ATTR "attribute"); \ - return -1; \ - } \ - DBG("hs_set_" #ATTR "(HalfStream * %p, bool %d)\n", self, \ - PyObject_IsTrue(val)); \ - self->hlfs->ATTR = PyObject_IsTrue(val); \ - return 0; /* success */ \ +#define HS_GET_BOOL(ATTR) \ + static PyObject *hs_get_##ATTR(HalfStream *self, void *unused) { return PyLong_FromLong(self->hlfs->ATTR ? 1L : 0L); } + +#define HS_SET_BOOL(ATTR) \ + static int hs_set_##ATTR(HalfStream *self, PyObject *val, void *closure) { \ + if (val == NULL) { \ + PyErr_SetString(PyExc_TypeError, "Cannot delete the " #ATTR "attribute"); \ + return -1; \ + } \ + DBG("hs_set_" #ATTR "(HalfStream * %p, bool %d)\n", self, PyObject_IsTrue(val)); \ + self->hlfs->ATTR = PyObject_IsTrue(val); \ + return 0; /* success */ \ } /* RW attributes */ @@ -384,8 +373,7 @@ static PyObject *hs_get_data(HalfStream *self, void *unused) { } static PyObject *hs_get_urgdata(HalfStream *self, void *unused) { /* u_char urgdata */ - return PyBytes_FromStringAndSize(&(self->hlfs->urgdata), - sizeof(self->hlfs->urgdata)); + return PyBytes_FromStringAndSize(&(self->hlfs->urgdata), sizeof(self->hlfs->urgdata)); } HS_GET_INT(count) HS_GET_INT(offset) @@ -466,13 +454,11 @@ static void callTcpFunc(struct tcp_stream *ts, void **param) { return; } -static void callUdpFunc(struct tuple4 *addr, u_char *data, int len, - struct ip *pkt) { +static void callUdpFunc(struct tuple4 *addr, u_char *data, int len, struct ip *pkt) { PyObject *ret = NULL; DBG("callUdpFunc...\n"); - ret = PyObject_CallFunction(udpFunc, "(Ns#s#)", pytuple4(addr), data, len, - pkt, ntohs(pkt->ip_len)); + ret = PyObject_CallFunction(udpFunc, "(Ns#s#)", pytuple4(addr), data, len, pkt, ntohs(pkt->ip_len)); if (ret) { Py_DECREF(ret); } @@ -510,27 +496,26 @@ static void callFragFunc(struct ip *pkt) { * ip_frag fragFunc callFragFunc */ -#define makeRegisterFunc(WHAT, FP, PYDISPATCH) \ - \ - static char pynids_register_##WHAT##__doc__[] = \ - "register_" #WHAT "(func) -> None\n" \ - "\n" \ - "Register the given user-defined function as a callback handler.\n"; \ - \ - static PyObject *pynids_register_##WHAT(PyObject *na, PyObject *args) { \ - PyObject *pyFunc = NULL; \ - if (!PyArg_ParseTuple(args, "O:register_" #WHAT, &pyFunc)) \ - return NULL; \ - \ - if (FP != NULL) { \ - /* (re-)set single, global func ptr */ \ - PyObject_Del(FP); \ - } \ - nids_register_##WHAT(PYDISPATCH); \ - DBG("Inside register_" #WHAT "(%p)\n", pyFunc); \ - FP = pyFunc; \ - Py_INCREF(FP); \ - Py_RETURN_NONE; \ +#define makeRegisterFunc(WHAT, FP, PYDISPATCH) \ + \ + static char pynids_register_##WHAT##__doc__[] = "register_" #WHAT "(func) -> None\n" \ + "\n" \ + "Register the given user-defined function as a callback handler.\n"; \ + \ + static PyObject *pynids_register_##WHAT(PyObject *na, PyObject *args) { \ + PyObject *pyFunc = NULL; \ + if (!PyArg_ParseTuple(args, "O:register_" #WHAT, &pyFunc)) \ + return NULL; \ + \ + if (FP != NULL) { \ + /* (re-)set single, global func ptr */ \ + PyObject_Del(FP); \ + } \ + nids_register_##WHAT(PYDISPATCH); \ + DBG("Inside register_" #WHAT "(%p)\n", pyFunc); \ + FP = pyFunc; \ + Py_INCREF(FP); \ + Py_RETURN_NONE; \ } /* What PyFunc * C-level Dispatch */ @@ -545,8 +530,7 @@ makeRegisterFunc(ip_frag, fragFunc, callFragFunc); /* Module Functions */ /* ====================================================================== */ -static char pynids_chksum_ctl__doc__[] = - "chksum_ctl([(addr1, True), (addr2, False)], ...) -> None\n\ +static char pynids_chksum_ctl__doc__[] = "chksum_ctl([(addr1, True), (addr2, False)], ...) -> None\n\ \n\ takes as arguments an list of tuples where a tuple should have the\n\ following format:\n\ @@ -601,24 +585,20 @@ static int _parse_prefix(char *prefix, u_int *netaddr, u_int *mask) { return 0; } -static int _parse_chksum_tuple(struct nids_chksum_ctl *ctl, int i, - PyObject *tuple) { +static int _parse_chksum_tuple(struct nids_chksum_ctl *ctl, int i, PyObject *tuple) { PyObject *addr, *action; addr = PyTuple_GET_ITEM(tuple, 0); if (PyString_Check(addr) <= 0) { - PyErr_SetString(PyExc_TypeError, - "in (cidr_address, action) cidr_address must be string"); + PyErr_SetString(PyExc_TypeError, "in (cidr_address, action) cidr_address must be string"); return -1; } - if (_parse_prefix(addr, &ctl[i].netaddr, &ctl[i].mask) < - 0) + if (_parse_prefix(addr, &ctl[i].netaddr, &ctl[i].mask) < 0) return -1; action = PyTuple_GET_ITEM(tuple, 1); if (PyBool_Check(action) <= 0) { - PyErr_SetString(PyExc_TypeError, - "in (cidr_address, action) action must be boolean"); + PyErr_SetString(PyExc_TypeError, "in (cidr_address, action) action must be boolean"); return -1; } if (action == Py_False) @@ -649,8 +629,7 @@ static PyObject *pynids_chksum_ctl(PyObject *na, PyObject *args) { for (i = 0; i < n; i++) { tuple = PyList_GetItem(items, i); if (PyTuple_Check(tuple) <= 0 || PyTuple_GET_SIZE(tuple) != 2) { - PyErr_SetString(PyExc_TypeError, - "list must contain (cidr_address, action) tuples"); + PyErr_SetString(PyExc_TypeError, "list must contain (cidr_address, action) tuples"); free(ctl); return NULL; } @@ -669,42 +648,41 @@ static PyObject *pynids_chksum_ctl(PyObject *na, PyObject *args) { Py_RETURN_NONE; } -static char pynids_param__doc__[] = - "param(name[, new_value]) -> old_value\n" - "\n" - "If new_value is specified, set the named nids attribute to the new " - "value.\n" - "Returns the previous value in any case. Supported parameters and their\n" - "defaults are:\n" - "\n" - "device -- network device to use as input (None); see also 'filename'\n" - "filename -- pcap filename to use as input (None); see also 'device'\n" - "dev_addon -- number of bytes in struct sk_buff for layer 2 info (-1)\n" - "one_loop_less -- undocumented\n" - "n_hosts -- size of IP defragmentation info hash table (256)\n" - "n_tcp_streams -- size of TCP connection hash table (1024)\n" - "pcap_filter -- pcap filter string applied to unassembled packets (None)\n" +static char pynids_param__doc__[] = "param(name[, new_value]) -> old_value\n" + "\n" + "If new_value is specified, set the named nids attribute to the new " + "value.\n" + "Returns the previous value in any case. Supported parameters and their\n" + "defaults are:\n" + "\n" + "device -- network device to use as input (None); see also 'filename'\n" + "filename -- pcap filename to use as input (None); see also 'device'\n" + "dev_addon -- number of bytes in struct sk_buff for layer 2 info (-1)\n" + "one_loop_less -- undocumented\n" + "n_hosts -- size of IP defragmentation info hash table (256)\n" + "n_tcp_streams -- size of TCP connection hash table (1024)\n" + "pcap_filter -- pcap filter string applied to unassembled packets (None)\n" #if (NIDS_MAJOR > 1 || (NIDS_MAJOR == 1 && NIDS_MINOR >= 19)) - "pcap_timeout-- pcap capture timeout, in milliseconds(1024)\n" + "pcap_timeout-- pcap capture timeout, in milliseconds(1024)\n" #endif /* libnids >= 1.19 */ - "promisc-- non-zero if promiscuous mode is desired on capture device(1)\n" - "sk_buff_size -- size of struct skbuff, used for queueing " - "packets (168)\n" - "syslog_level -- log level used when syslogging events " - "(LOG_ALERT)\n" - "scan_num_hosts -- hash table size for portscan detection " - "(256)\n" - "scan_num_ports -- minimum ports per src. host to qualify as a " - "portscan (10)\n" - "scan_delay -- maximum delay in milliseconds between (3000)\n" - "tcp_flow_timeout -- timeout in seconds to distinguish flows " - "with sample tuple\n" - "\n" - "Either 'device' or 'filename' must be specified before " - "calling nids_init().\n" - "Portscan detection may be disabled by setting " - "'scan_num_hosts' to zero. See\n" - "the libnids documentation for more details.\n"; + "promisc-- non-zero if promiscuous mode is desired on capture device(1)\n" + "sk_buff_size -- size of struct skbuff, used for queueing " + "packets (168)\n" + "syslog_level -- log level used when syslogging events " + "(LOG_ALERT)\n" + "scan_num_hosts -- hash table size for portscan detection " + "(256)\n" + "scan_num_ports -- minimum ports per src. host to qualify as a " + "portscan (10)\n" + "scan_delay -- maximum delay in milliseconds between (3000)\n" + "tcp_flow_timeout -- timeout in seconds to distinguish flows " + "with sample tuple\n" + "\n" + "Either 'device' or 'filename' must be specified before " + "calling nids_init().\n" + "Portscan detection may be disabled by setting " + "'scan_num_hosts' to zero. See\n" + "the libnids documentation for more details.\n"; static PyObject *pynids_param(PyObject *na, PyObject *args) { PyObject *v = NULL; @@ -786,13 +764,12 @@ static PyObject *pynids_param(PyObject *na, PyObject *args) { Py_RETURN_NONE; } -static char pynids_getfd__doc__[] = - "getfd() -> fd\n" - "\n" - "Returns the integral file descriptor of the live capture device or pcap\n" - "savefile specified during the call to init(). The resultant fd is " - "suitable\n" - "for I/O polling with select.select(), for example.\n"; +static char pynids_getfd__doc__[] = "getfd() -> fd\n" + "\n" + "Returns the integral file descriptor of the live capture device or pcap\n" + "savefile specified during the call to init(). The resultant fd is " + "suitable\n" + "for I/O polling with select.select(), for example.\n"; static PyObject *pynids_getfd(PyObject *na, PyObject *args) { int pcap_fd; @@ -826,10 +803,9 @@ static PyObject *pynids_next(PyObject *na, PyObject *args) { return PyLong_FromLong((long)ret); } -static char pynids_dispatch__doc__[] = - "dispatch(cnt) -> processed\n" - "\n" - "UNDOCUMENTED -- this function does not exist in libnids <= 1.19.\n"; +static char pynids_dispatch__doc__[] = "dispatch(cnt) -> processed\n" + "\n" + "UNDOCUMENTED -- this function does not exist in libnids <= 1.19.\n"; static PyObject *pynids_dispatch(PyObject *na, PyObject *args) { int ret, cnt; @@ -844,14 +820,13 @@ static PyObject *pynids_dispatch(PyObject *na, PyObject *args) { return PyLong_FromLong((long)ret); } -static char pynids_run__doc__[] = - "run() -> None\n" - "\n" - "On a live capture, process packets ad infinitum; on an offline read, " - "process\n" - "packets until EOF. In either case, an exception thrown in a user " - "callback\n" - "or in nids/pcap (as nids.error) may abort processing.\n"; +static char pynids_run__doc__[] = "run() -> None\n" + "\n" + "On a live capture, process packets ad infinitum; on an offline read, " + "process\n" + "packets until EOF. In either case, an exception thrown in a user " + "callback\n" + "or in nids/pcap (as nids.error) may abort processing.\n"; static PyObject *pynids_run(PyObject *na, PyObject *args) { int r; @@ -881,18 +856,17 @@ static PyObject *pynids_run(PyObject *na, PyObject *args) { Py_RETURN_NONE; } -static char pynids_init__doc__[] = - "init() -> None\n" - "\n" - "Initialize the nids library, as specified by previous calls to param(). " - "In\n" - "particular, the capture device 'device' or pcap savefile 'filename' is\n" - "opened, the 'pcap_filter' compiled, and various internal mechanisms " - "prepared.\n" - "\n" - "It is appropriate and recommended to drop process privileges after " - "making\n" - "this call.\n"; +static char pynids_init__doc__[] = "init() -> None\n" + "\n" + "Initialize the nids library, as specified by previous calls to param(). " + "In\n" + "particular, the capture device 'device' or pcap savefile 'filename' is\n" + "opened, the 'pcap_filter' compiled, and various internal mechanisms " + "prepared.\n" + "\n" + "It is appropriate and recommended to drop process privileges after " + "making\n" + "this call.\n"; static PyObject *pynids_init(PyObject *na, PyObject *args) { int ok; @@ -910,10 +884,9 @@ static PyObject *pynids_init(PyObject *na, PyObject *args) { Py_RETURN_NONE; } -static char pynids_get_pkt_ts__doc__[] = - "get_pkt_time() -> float\n" - "\n" - "Returns the timestamp of the most recent packet as a float.\n"; +static char pynids_get_pkt_ts__doc__[] = "get_pkt_time() -> float\n" + "\n" + "Returns the timestamp of the most recent packet as a float.\n"; static PyObject *pynids_get_pkt_ts(PyObject *na, PyObject *args) { double pkt_time; @@ -921,15 +894,13 @@ static PyObject *pynids_get_pkt_ts(PyObject *na, PyObject *args) { if (!PyArg_ParseTuple(args, ":get_pkt_ts")) return NULL; - pkt_time = nids_last_pcap_header->ts.tv_sec + - (nids_last_pcap_header->ts.tv_usec / 1000000.0); + pkt_time = nids_last_pcap_header->ts.tv_sec + (nids_last_pcap_header->ts.tv_usec / 1000000.0); return PyFloat_FromDouble(pkt_time); } -static char pynids_get_pcap_stats__doc__[] = - "get_pcap_stats() -> tuple\n" - "\n" - "Returns the pcap recv, drop and interface drop statistics as a tuple.\n"; +static char pynids_get_pcap_stats__doc__[] = "get_pcap_stats() -> tuple\n" + "\n" + "Returns the pcap recv, drop and interface drop statistics as a tuple.\n"; static PyObject *pynids_get_pcap_stats(PyObject *na, PyObject *args) { static struct pcap_stat ps; @@ -938,8 +909,7 @@ static PyObject *pynids_get_pcap_stats(PyObject *na, PyObject *args) { if (!PyArg_ParseTuple(args, ":get_pcap_stats")) return NULL; - if (nids_params.pcap_desc == NULL || - pcap_stats(nids_params.pcap_desc, &ps) != 0) { + if (nids_params.pcap_desc == NULL || pcap_stats(nids_params.pcap_desc, &ps) != 0) { raisePynidsError(); return NULL; } @@ -954,7 +924,7 @@ static PyObject *pynids_get_pcap_stats(PyObject *na, PyObject *args) { /* List of functions defined in the module */ -#define mkMethod(x) \ +#define mkMethod(x) \ { #x, pynids_##x, METH_VARARGS, pynids_##x##__doc__ } static PyMethodDef pynids_methods[] = { @@ -1005,8 +975,7 @@ PyMODINIT_FUNC PyInit_nids(void) { /* Add versioning info */ PyModule_AddStringConstant(m, "__version__", "0.6.2"); - PyModule_AddObject(m, "__nids_version__", - PyString_FromFormat("%d.%d", NIDS_MAJOR, NIDS_MINOR)); + PyModule_AddObject(m, "__nids_version__", PyString_FromFormat("%d.%d", NIDS_MAJOR, NIDS_MINOR)); /* Add NIDS_ symbolic constants to the module */ #define setConst(CONST) PyModule_AddIntConstant(m, #CONST, CONST) From 0b5595282db034fe9346c3411497a5cc7bcc3b39 Mon Sep 17 00:00:00 2001 From: James Stronz Date: Sun, 22 Sep 2019 18:30:35 -0500 Subject: [PATCH 15/23] Removed comment block on resources for C-API and C porting after book marking... the official docs are not too hard to find --- nidsmodule.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/nidsmodule.c b/nidsmodule.c index 5f1f12f..c8e36f0 100644 --- a/nidsmodule.c +++ b/nidsmodule.c @@ -19,16 +19,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA */ - -/* Porting Module to Python 3: - * Resources: - * + https://docs.python.org/3/howto/cporting.html - * + https://docs.python.org/3/c-api/ - * - * - * - */ - #include "Python.h" #include #include From f43e198df8b106f30b3483197976bad490b73e7f Mon Sep 17 00:00:00 2001 From: James Stronz Date: Sun, 22 Sep 2019 18:32:54 -0500 Subject: [PATCH 16/23] Changed indent width to 4 in clang-format --- .clang-format | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.clang-format b/.clang-format index f3a7fed..b7a9641 100644 --- a/.clang-format +++ b/.clang-format @@ -71,7 +71,7 @@ IncludeCategories: IncludeIsMainRegex: '(Test)?$' IndentCaseLabels: false IndentPPDirectives: None -IndentWidth: 2 +IndentWidth: 4 IndentWrappedFunctionNames: false JavaScriptQuotes: Leave JavaScriptWrapImports: true From fe16ea3f8e2f5b36c826b80602b1a309e914efd7 Mon Sep 17 00:00:00 2001 From: James Stronz Date: Sun, 22 Sep 2019 18:33:50 -0500 Subject: [PATCH 17/23] Ran clang-format with new indent width of 4 --- nidsmodule.c | 825 ++++++++++++++++++++++++++------------------------- 1 file changed, 414 insertions(+), 411 deletions(-) diff --git a/nidsmodule.c b/nidsmodule.c index c8e36f0..8553bad 100644 --- a/nidsmodule.c +++ b/nidsmodule.c @@ -54,13 +54,13 @@ static PyObject *fragFunc = NULL; static struct nids_prm origNidsParams; typedef struct { - PyObject_HEAD struct tcp_stream *tcps; - PyObject *client; - PyObject *server; + PyObject_HEAD struct tcp_stream *tcps; + PyObject *client; + PyObject *server; } TcpStream; typedef struct { - PyObject_HEAD struct half_stream *hlfs; + PyObject_HEAD struct half_stream *hlfs; } HalfStream; static PyTypeObject TcpStream_Type; @@ -126,10 +126,10 @@ static char pynidsmodule__doc__[] = "A wrapper around the libnids Network Intrus "of a TcpStream object.\n"; static PyObject *raisePynidsError(void) { - extern char nids_errbuf[]; + extern char nids_errbuf[]; - PyErr_SetString(pynids_error, nids_errbuf); - return NULL; + PyErr_SetString(pynids_error, nids_errbuf); + return NULL; } /* nids_dispatch_exc() @@ -144,40 +144,40 @@ static PyObject *raisePynidsError(void) { * */ static int nids_dispatch_exc(int n) { - int ret; - - DBG("nids_dispatch_exc(%d)\n", n); - ret = nids_dispatch(n); - if (ret == -1) { /* pcap error trumps user callback exception */ - raisePynidsError(); - return -1; - } - if (PyErr_Occurred()) - return -1; /* check for callback exception */ - return ret; + int ret; + + DBG("nids_dispatch_exc(%d)\n", n); + ret = nids_dispatch(n); + if (ret == -1) { /* pcap error trumps user callback exception */ + raisePynidsError(); + return -1; + } + if (PyErr_Occurred()) + return -1; /* check for callback exception */ + return ret; } /* pytuple4(tuple4): ((src, sport), (dst, dport)) */ static PyObject *pytuple4(struct tuple4 *addr) { - struct in_addr in; - PyObject *t1, *t2, *ret; + struct in_addr in; + PyObject *t1, *t2, *ret; - in.s_addr = addr->saddr; - t1 = Py_BuildValue("si", inet_ntoa(in), addr->source); - if (!t1) - return NULL; + in.s_addr = addr->saddr; + t1 = Py_BuildValue("si", inet_ntoa(in), addr->source); + if (!t1) + return NULL; - in.s_addr = addr->daddr; - t2 = Py_BuildValue("si", inet_ntoa(in), addr->dest); - if (!t2) { - Py_DECREF(t1); - return NULL; - } + in.s_addr = addr->daddr; + t2 = Py_BuildValue("si", inet_ntoa(in), addr->dest); + if (!t2) { + Py_DECREF(t1); + return NULL; + } - ret = Py_BuildValue("OO", t1, t2); - Py_DECREF(t1); - Py_DECREF(t2); - return ret; + ret = Py_BuildValue("OO", t1, t2); + Py_DECREF(t1); + Py_DECREF(t2); + return ret; } /* ====================================================================== */ @@ -186,34 +186,34 @@ static PyObject *pytuple4(struct tuple4 *addr) { /* TcpStream ctor -- called by callTcpFunc, not user */ static TcpStream *wrapTcpStream(struct tcp_stream *t) { - TcpStream *self; - self = PyObject_New(TcpStream, &TcpStream_Type); - if (self == NULL) - return NULL; - self->tcps = t; - self->client = NULL; - self->server = NULL; - DBG("TcpStream_ctor(%p)\n", self); - /* - * wrap half streams on demand, if demanded... - self->client = (PyObject *) wrapHalfStream(&t->client); - self->server = (PyObject *) wrapHalfStream(&t->server); - */ - return self; + TcpStream *self; + self = PyObject_New(TcpStream, &TcpStream_Type); + if (self == NULL) + return NULL; + self->tcps = t; + self->client = NULL; + self->server = NULL; + DBG("TcpStream_ctor(%p)\n", self); + /* + * wrap half streams on demand, if demanded... + self->client = (PyObject *) wrapHalfStream(&t->client); + self->server = (PyObject *) wrapHalfStream(&t->server); + */ + return self; } static void TcpStream_dealloc(TcpStream *self) { - DBG("TcpStream_dealloc(%p)\n", self); - self->tcps = NULL; /* libnids will free this when approp. */ - if (self->client) { - Py_DECREF(self->client); - self->client = NULL; - } - if (self->server) { - Py_DECREF(self->server); - self->server = NULL; - } - PyObject_Del(self); + DBG("TcpStream_dealloc(%p)\n", self); + self->tcps = NULL; /* libnids will free this when approp. */ + if (self->client) { + Py_DECREF(self->client); + self->client = NULL; + } + if (self->server) { + Py_DECREF(self->server); + self->server = NULL; + } + PyObject_Del(self); } /* ====================================================================== */ @@ -221,22 +221,22 @@ static void TcpStream_dealloc(TcpStream *self) { /* ====================================================================== */ static PyObject *TcpStream_discard(TcpStream *self, PyObject *args) { - int i; - if (!PyArg_ParseTuple(args, "i:discard", &i)) - return NULL; + int i; + if (!PyArg_ParseTuple(args, "i:discard", &i)) + return NULL; - nids_discard(self->tcps, i); + nids_discard(self->tcps, i); - Py_RETURN_NONE; + Py_RETURN_NONE; } static PyObject *TcpStream_kill(TcpStream *self, PyObject *args) { - if (!PyArg_ParseTuple(args, ":kill")) - return NULL; + if (!PyArg_ParseTuple(args, ":kill")) + return NULL; - nids_killtcp(self->tcps); + nids_killtcp(self->tcps); - Py_RETURN_NONE; + Py_RETURN_NONE; } static PyMethodDef TcpStream_methods[] = { @@ -246,22 +246,22 @@ static PyMethodDef TcpStream_methods[] = { }; #define TS_GET_HLFS(ATTR) \ - static PyObject *ts_get_##ATTR(TcpStream *self, void *unused) { \ - if (!self->ATTR) { \ - self->ATTR = (PyObject *)wrapHalfStream(&self->tcps->ATTR); \ - if (!self->ATTR) \ - return NULL; \ - } \ - Py_INCREF(self->ATTR); \ - return self->ATTR; \ - } + static PyObject *ts_get_##ATTR(TcpStream *self, void *unused) { \ + if (!self->ATTR) { \ + self->ATTR = (PyObject *)wrapHalfStream(&self->tcps->ATTR); \ + if (!self->ATTR) \ + return NULL; \ + } \ + Py_INCREF(self->ATTR); \ + return self->ATTR; \ + } /* RO attributes */ TS_GET_HLFS(client) TS_GET_HLFS(server) static PyObject *ts_get_addr(TcpStream *self, void *unused) { return pytuple4(&self->tcps->addr); } static PyObject *ts_get_nids_state(TcpStream *self, void *unused) { - return PyLong_FromLong((long)self->tcps->nids_state); + return PyLong_FromLong((long)self->tcps->nids_state); } static PyGetSetDef TcpStream_getsets[] = { @@ -314,38 +314,40 @@ static PyTypeObject TcpStream_Type = { /* ====================================================================== */ static HalfStream *wrapHalfStream(struct half_stream *h) { /* called by TcpStream ctor */ - HalfStream *self; - self = PyObject_New(HalfStream, &HalfStream_Type); - if (self == NULL) - return NULL; - self->hlfs = h; - DBG("HalfStream_ctor(%p)\n", self); - return self; + HalfStream *self; + self = PyObject_New(HalfStream, &HalfStream_Type); + if (self == NULL) + return NULL; + self->hlfs = h; + DBG("HalfStream_ctor(%p)\n", self); + return self; } static void HalfStream_dealloc(HalfStream *self) { - DBG("HalfStream_dealloc(%p, %d)\n", self, self->ob_refcnt); - self->hlfs = NULL; - PyObject_Del(self); + DBG("HalfStream_dealloc(%p, %d)\n", self, self->ob_refcnt); + self->hlfs = NULL; + PyObject_Del(self); } #define HS_GET_INT(ATTR) \ - static PyObject *hs_get_##ATTR(HalfStream *self, void *unused) { return PyLong_FromLong((long)self->hlfs->ATTR); } + static PyObject *hs_get_##ATTR(HalfStream *self, void *unused) { return PyLong_FromLong((long)self->hlfs->ATTR); } /* FIXME - true bool support */ #define HS_GET_BOOL(ATTR) \ - static PyObject *hs_get_##ATTR(HalfStream *self, void *unused) { return PyLong_FromLong(self->hlfs->ATTR ? 1L : 0L); } + static PyObject *hs_get_##ATTR(HalfStream *self, void *unused) { \ + return PyLong_FromLong(self->hlfs->ATTR ? 1L : 0L); \ + } #define HS_SET_BOOL(ATTR) \ - static int hs_set_##ATTR(HalfStream *self, PyObject *val, void *closure) { \ - if (val == NULL) { \ - PyErr_SetString(PyExc_TypeError, "Cannot delete the " #ATTR "attribute"); \ - return -1; \ - } \ - DBG("hs_set_" #ATTR "(HalfStream * %p, bool %d)\n", self, PyObject_IsTrue(val)); \ - self->hlfs->ATTR = PyObject_IsTrue(val); \ - return 0; /* success */ \ - } + static int hs_set_##ATTR(HalfStream *self, PyObject *val, void *closure) { \ + if (val == NULL) { \ + PyErr_SetString(PyExc_TypeError, "Cannot delete the " #ATTR "attribute"); \ + return -1; \ + } \ + DBG("hs_set_" #ATTR "(HalfStream * %p, bool %d)\n", self, PyObject_IsTrue(val)); \ + self->hlfs->ATTR = PyObject_IsTrue(val); \ + return 0; /* success */ \ + } /* RW attributes */ HS_GET_BOOL(collect) @@ -355,15 +357,15 @@ HS_SET_BOOL(collect_urg) /* RO attributes */ HS_GET_INT(state) static PyObject *hs_get_data(HalfStream *self, void *unused) { - /* data may not be allocated if the conn/libnids has seen no data */ - if (!self->hlfs->data) - return PyBytes_FromStringAndSize("", 0); - /* bufsize is an undocumented member */ - return PyBytes_FromStringAndSize(self->hlfs->data, self->hlfs->bufsize); + /* data may not be allocated if the conn/libnids has seen no data */ + if (!self->hlfs->data) + return PyBytes_FromStringAndSize("", 0); + /* bufsize is an undocumented member */ + return PyBytes_FromStringAndSize(self->hlfs->data, self->hlfs->bufsize); } static PyObject *hs_get_urgdata(HalfStream *self, void *unused) { - /* u_char urgdata */ - return PyBytes_FromStringAndSize(&(self->hlfs->urgdata), sizeof(self->hlfs->urgdata)); + /* u_char urgdata */ + return PyBytes_FromStringAndSize(&(self->hlfs->urgdata), sizeof(self->hlfs->urgdata)); } HS_GET_INT(count) HS_GET_INT(offset) @@ -425,55 +427,55 @@ static PyTypeObject HalfStream_Type = { /* ====================================================================== */ static void callTcpFunc(struct tcp_stream *ts, void **param) { - PyObject *ret = NULL; - TcpStream *tso = NULL; + PyObject *ret = NULL; + TcpStream *tso = NULL; - DBG("callTcpFunc - init tso\n"); - tso = wrapTcpStream(ts); - if (!tso) - return; + DBG("callTcpFunc - init tso\n"); + tso = wrapTcpStream(ts); + if (!tso) + return; - DBG("callTcpFunc - call func %p(%p)\n", tcpFunc, tso); - ret = PyObject_CallFunction(tcpFunc, "O", tso); + DBG("callTcpFunc - call func %p(%p)\n", tcpFunc, tso); + ret = PyObject_CallFunction(tcpFunc, "O", tso); - DBG("callTcpFunc - dealloc tso (ret: %p)\n", ret); - Py_DECREF(tso); - if (ret) { - Py_DECREF(ret); - } - return; + DBG("callTcpFunc - dealloc tso (ret: %p)\n", ret); + Py_DECREF(tso); + if (ret) { + Py_DECREF(ret); + } + return; } static void callUdpFunc(struct tuple4 *addr, u_char *data, int len, struct ip *pkt) { - PyObject *ret = NULL; - - DBG("callUdpFunc...\n"); - ret = PyObject_CallFunction(udpFunc, "(Ns#s#)", pytuple4(addr), data, len, pkt, ntohs(pkt->ip_len)); - if (ret) { - Py_DECREF(ret); - } - return; + PyObject *ret = NULL; + + DBG("callUdpFunc...\n"); + ret = PyObject_CallFunction(udpFunc, "(Ns#s#)", pytuple4(addr), data, len, pkt, ntohs(pkt->ip_len)); + if (ret) { + Py_DECREF(ret); + } + return; } static void callIpFunc(struct ip *pkt) { - PyObject *ret = NULL; - - DBG("callIpFunc...\n"); - ret = PyObject_CallFunction(ipFunc, "s#", pkt, ntohs(pkt->ip_len)); - if (ret) { - Py_DECREF(ret); - } - return; + PyObject *ret = NULL; + + DBG("callIpFunc...\n"); + ret = PyObject_CallFunction(ipFunc, "s#", pkt, ntohs(pkt->ip_len)); + if (ret) { + Py_DECREF(ret); + } + return; } static void callFragFunc(struct ip *pkt) { - PyObject *ret = NULL; + PyObject *ret = NULL; - ret = PyObject_CallFunction(fragFunc, "s#", pkt, ntohs(pkt->ip_len)); - if (ret) { - Py_DECREF(ret); - } - return; + ret = PyObject_CallFunction(fragFunc, "s#", pkt, ntohs(pkt->ip_len)); + if (ret) { + Py_DECREF(ret); + } + return; } /* makeRegisterFunc(type, static PyFunction ptr, dispatch) @@ -488,25 +490,26 @@ static void callFragFunc(struct ip *pkt) { #define makeRegisterFunc(WHAT, FP, PYDISPATCH) \ \ - static char pynids_register_##WHAT##__doc__[] = "register_" #WHAT "(func) -> None\n" \ - "\n" \ - "Register the given user-defined function as a callback handler.\n"; \ + static char pynids_register_##WHAT##__doc__[] = \ + "register_" #WHAT "(func) -> None\n" \ + "\n" \ + "Register the given user-defined function as a callback handler.\n"; \ \ - static PyObject *pynids_register_##WHAT(PyObject *na, PyObject *args) { \ - PyObject *pyFunc = NULL; \ - if (!PyArg_ParseTuple(args, "O:register_" #WHAT, &pyFunc)) \ - return NULL; \ + static PyObject *pynids_register_##WHAT(PyObject *na, PyObject *args) { \ + PyObject *pyFunc = NULL; \ + if (!PyArg_ParseTuple(args, "O:register_" #WHAT, &pyFunc)) \ + return NULL; \ \ - if (FP != NULL) { \ - /* (re-)set single, global func ptr */ \ - PyObject_Del(FP); \ - } \ - nids_register_##WHAT(PYDISPATCH); \ - DBG("Inside register_" #WHAT "(%p)\n", pyFunc); \ - FP = pyFunc; \ - Py_INCREF(FP); \ - Py_RETURN_NONE; \ - } + if (FP != NULL) { \ + /* (re-)set single, global func ptr */ \ + PyObject_Del(FP); \ + } \ + nids_register_##WHAT(PYDISPATCH); \ + DBG("Inside register_" #WHAT "(%p)\n", pyFunc); \ + FP = pyFunc; \ + Py_INCREF(FP); \ + Py_RETURN_NONE; \ + } /* What PyFunc * C-level Dispatch */ /* ---- -------- ---------------- */ @@ -534,108 +537,108 @@ the boolean is set to False. If the packet matches none of the list\n\ elements, the default action is to perform checksumming.\n"; static int _parse_prefix(char *prefix, u_int *netaddr, u_int *mask) { - struct in_addr in; - char *ptr, *data; - u_int m; - - /* eat up white space */ - data = prefix; - while (*data == ' ' && *data == '\t') - data++; - - /* find end */ - ptr = data; - while (*ptr != '/' && *ptr != '\n' && *ptr != '\0') - ptr++; - - if (*ptr == '/') { - *ptr = '\0'; - ptr++; - - /* convert the ip to binary */ - if (inet_pton(AF_INET, data, &in) < 0) { - PyErr_SetFromErrno(PyExc_OSError); - return -1; + struct in_addr in; + char *ptr, *data; + u_int m; + + /* eat up white space */ + data = prefix; + while (*data == ' ' && *data == '\t') + data++; + + /* find end */ + ptr = data; + while (*ptr != '/' && *ptr != '\n' && *ptr != '\0') + ptr++; + + if (*ptr == '/') { + *ptr = '\0'; + ptr++; + + /* convert the ip to binary */ + if (inet_pton(AF_INET, data, &in) < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + *netaddr = in.s_addr; + + /* get mask */ + m = 32 - atoi(ptr); + *mask = (m >= 32) ? 0 : htonl((0xffffffff >> m) << m); + } else if (strlen(data) >= 7) { + /* convert the ip to binary */ + if (inet_pton(AF_INET, data, &in) < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + *netaddr = in.s_addr; + *mask = 0xffffffff; } - *netaddr = in.s_addr; - - /* get mask */ - m = 32 - atoi(ptr); - *mask = (m >= 32) ? 0 : htonl((0xffffffff >> m) << m); - } else if (strlen(data) >= 7) { - /* convert the ip to binary */ - if (inet_pton(AF_INET, data, &in) < 0) { - PyErr_SetFromErrno(PyExc_OSError); - return -1; - } - *netaddr = in.s_addr; - *mask = 0xffffffff; - } - return 0; + return 0; } static int _parse_chksum_tuple(struct nids_chksum_ctl *ctl, int i, PyObject *tuple) { - PyObject *addr, *action; - - addr = PyTuple_GET_ITEM(tuple, 0); - if (PyString_Check(addr) <= 0) { - PyErr_SetString(PyExc_TypeError, "in (cidr_address, action) cidr_address must be string"); - return -1; - } - if (_parse_prefix(addr, &ctl[i].netaddr, &ctl[i].mask) < 0) - return -1; - - action = PyTuple_GET_ITEM(tuple, 1); - if (PyBool_Check(action) <= 0) { - PyErr_SetString(PyExc_TypeError, "in (cidr_address, action) action must be boolean"); - return -1; - } - if (action == Py_False) - ctl[i].action = NIDS_DONT_CHKSUM; - else - ctl[i].action = NIDS_DO_CHKSUM; - - return 0; + PyObject *addr, *action; + + addr = PyTuple_GET_ITEM(tuple, 0); + if (PyString_Check(addr) <= 0) { + PyErr_SetString(PyExc_TypeError, "in (cidr_address, action) cidr_address must be string"); + return -1; + } + if (_parse_prefix(addr, &ctl[i].netaddr, &ctl[i].mask) < 0) + return -1; + + action = PyTuple_GET_ITEM(tuple, 1); + if (PyBool_Check(action) <= 0) { + PyErr_SetString(PyExc_TypeError, "in (cidr_address, action) action must be boolean"); + return -1; + } + if (action == Py_False) + ctl[i].action = NIDS_DONT_CHKSUM; + else + ctl[i].action = NIDS_DO_CHKSUM; + + return 0; } static PyObject *pynids_chksum_ctl(PyObject *na, PyObject *args) { - PyObject *items, *tuple; - int i, n; - struct nids_chksum_ctl *ctl = NULL; - - /* parse args */ - if (!PyArg_ParseTuple(args, "O:chksum_ctl", &items)) - return NULL; + PyObject *items, *tuple; + int i, n; + struct nids_chksum_ctl *ctl = NULL; - /* parse list of address/action tuples */ - if (PyList_Check(items) > 0) { - n = PyList_Size(items); - ctl = (struct nids_chksum_ctl *)malloc(sizeof(struct nids_chksum_ctl) * n); - if (ctl == NULL) { - PyErr_SetString(PyExc_OSError, "could not allocate temp memory storage"); - return NULL; - } - for (i = 0; i < n; i++) { - tuple = PyList_GetItem(items, i); - if (PyTuple_Check(tuple) <= 0 || PyTuple_GET_SIZE(tuple) != 2) { - PyErr_SetString(PyExc_TypeError, "list must contain (cidr_address, action) tuples"); - free(ctl); + /* parse args */ + if (!PyArg_ParseTuple(args, "O:chksum_ctl", &items)) return NULL; - } - if (_parse_chksum_tuple(ctl, i, tuple) < 0) { - free(ctl); + + /* parse list of address/action tuples */ + if (PyList_Check(items) > 0) { + n = PyList_Size(items); + ctl = (struct nids_chksum_ctl *)malloc(sizeof(struct nids_chksum_ctl) * n); + if (ctl == NULL) { + PyErr_SetString(PyExc_OSError, "could not allocate temp memory storage"); + return NULL; + } + for (i = 0; i < n; i++) { + tuple = PyList_GetItem(items, i); + if (PyTuple_Check(tuple) <= 0 || PyTuple_GET_SIZE(tuple) != 2) { + PyErr_SetString(PyExc_TypeError, "list must contain (cidr_address, action) tuples"); + free(ctl); + return NULL; + } + if (_parse_chksum_tuple(ctl, i, tuple) < 0) { + free(ctl); + return NULL; + } + } + } else { + PyErr_SetString(PyExc_TypeError, "chksum_ctl requires a list param"); return NULL; - } } - } else { - PyErr_SetString(PyExc_TypeError, "chksum_ctl requires a list param"); - return NULL; - } - nids_register_chksum_ctl(ctl, n); + nids_register_chksum_ctl(ctl, n); - Py_RETURN_NONE; + Py_RETURN_NONE; } static char pynids_param__doc__[] = "param(name[, new_value]) -> old_value\n" @@ -675,83 +678,83 @@ static char pynids_param__doc__[] = "param(name[, new_value]) -> old_value\n" "the libnids documentation for more details.\n"; static PyObject *pynids_param(PyObject *na, PyObject *args) { - PyObject *v = NULL; - PyObject *ret = NULL; - int *int_p = NULL; - char **char_pp = NULL; - char *name; + PyObject *v = NULL; + PyObject *ret = NULL; + int *int_p = NULL; + char **char_pp = NULL; + char *name; - if (!PyArg_ParseTuple(args, "s|O", &name, &v)) - return NULL; + if (!PyArg_ParseTuple(args, "s|O", &name, &v)) + return NULL; - /* is it an int parameter? */ - if (!strcmp(name, "n_tcp_streams")) - int_p = &nids_params.n_tcp_streams; - else if (!strcmp(name, "n_hosts")) - int_p = &nids_params.n_hosts; - else if (!strcmp(name, "sk_buff_size")) - int_p = &nids_params.sk_buff_size; - else if (!strcmp(name, "dev_addon")) - int_p = &nids_params.dev_addon; - else if (!strcmp(name, "syslog_level")) - int_p = &nids_params.syslog_level; - else if (!strcmp(name, "scan_num_hosts")) - int_p = &nids_params.scan_num_hosts; - else if (!strcmp(name, "scan_num_ports")) - int_p = &nids_params.scan_num_ports; - else if (!strcmp(name, "scan_delay")) - int_p = &nids_params.scan_delay; - else if (!strcmp(name, "promisc")) - int_p = &nids_params.promisc; - else if (!strcmp(name, "one_loop_less")) - int_p = &nids_params.one_loop_less; + /* is it an int parameter? */ + if (!strcmp(name, "n_tcp_streams")) + int_p = &nids_params.n_tcp_streams; + else if (!strcmp(name, "n_hosts")) + int_p = &nids_params.n_hosts; + else if (!strcmp(name, "sk_buff_size")) + int_p = &nids_params.sk_buff_size; + else if (!strcmp(name, "dev_addon")) + int_p = &nids_params.dev_addon; + else if (!strcmp(name, "syslog_level")) + int_p = &nids_params.syslog_level; + else if (!strcmp(name, "scan_num_hosts")) + int_p = &nids_params.scan_num_hosts; + else if (!strcmp(name, "scan_num_ports")) + int_p = &nids_params.scan_num_ports; + else if (!strcmp(name, "scan_delay")) + int_p = &nids_params.scan_delay; + else if (!strcmp(name, "promisc")) + int_p = &nids_params.promisc; + else if (!strcmp(name, "one_loop_less")) + int_p = &nids_params.one_loop_less; #if (NIDS_MAJOR > 1 || (NIDS_MAJOR == 1 && NIDS_MINOR >= 19)) - else if (!strcmp(name, "pcap_timeout")) - int_p = &nids_params.pcap_timeout; + else if (!strcmp(name, "pcap_timeout")) + int_p = &nids_params.pcap_timeout; #endif /* libnids >= 1.19 */ - else if (!strcmp(name, "tcp_flow_timeout")) - int_p = &nids_params.tcp_flow_timeout; - - if (int_p) { - /* FIXME - type check val for intishness */ - ret = PyLong_FromLong((long)*int_p); - if (v) - *int_p = (int)PyLong_AsLong(v); - return ret; - } - - /* is it a char * param? */ - if (!strcmp(name, "device")) - char_pp = &nids_params.device; - else if (!strcmp(name, "pcap_filter")) - char_pp = &nids_params.pcap_filter; - else if (!strcmp(name, "filename")) - char_pp = &nids_params.filename; - - if (char_pp) { - /* XXX - error checking, PyMem alloc/free */ - ret = Py_BuildValue("s", *char_pp); - if (v) { - /* free previous strdup -- fortunately libnids inits these to - * NULL... - */ - if (*char_pp) - free(*char_pp); - *char_pp = (v == Py_None) ? NULL : strdup(PyString_AsString(v)); + else if (!strcmp(name, "tcp_flow_timeout")) + int_p = &nids_params.tcp_flow_timeout; + + if (int_p) { + /* FIXME - type check val for intishness */ + ret = PyLong_FromLong((long)*int_p); + if (v) + *int_p = (int)PyLong_AsLong(v); + return ret; } - return ret; - } - - /****** - if (!strcmp(name, "syslog")) - func_pp = &nids.syslog; - else if (!strcmp(name, "ip_filter")) - func_pp = &nids.ip_filter; - else if (!strcmp(name, "no_mem")) - func_pp = &nids.no_mem; -******/ - - Py_RETURN_NONE; + + /* is it a char * param? */ + if (!strcmp(name, "device")) + char_pp = &nids_params.device; + else if (!strcmp(name, "pcap_filter")) + char_pp = &nids_params.pcap_filter; + else if (!strcmp(name, "filename")) + char_pp = &nids_params.filename; + + if (char_pp) { + /* XXX - error checking, PyMem alloc/free */ + ret = Py_BuildValue("s", *char_pp); + if (v) { + /* free previous strdup -- fortunately libnids inits these to + * NULL... + */ + if (*char_pp) + free(*char_pp); + *char_pp = (v == Py_None) ? NULL : strdup(PyString_AsString(v)); + } + return ret; + } + + /* + * if (!strcmp(name, "syslog")) + * func_pp = &nids.syslog; + * else if (!strcmp(name, "ip_filter")) + * func_pp = &nids.ip_filter; + * else if (!strcmp(name, "no_mem")) + * func_pp = &nids.no_mem; + */ + + Py_RETURN_NONE; } static char pynids_getfd__doc__[] = "getfd() -> fd\n" @@ -762,14 +765,14 @@ static char pynids_getfd__doc__[] = "getfd() -> fd\n" "for I/O polling with select.select(), for example.\n"; static PyObject *pynids_getfd(PyObject *na, PyObject *args) { - int pcap_fd; + int pcap_fd; - if (!PyArg_ParseTuple(args, ":getfd")) - return NULL; + if (!PyArg_ParseTuple(args, ":getfd")) + return NULL; - if ((pcap_fd = nids_getfd()) == -1) - return raisePynidsError(); - return PyLong_FromLong((long)pcap_fd); + if ((pcap_fd = nids_getfd()) == -1) + return raisePynidsError(); + return PyLong_FromLong((long)pcap_fd); } static char pynids_next__doc__[] = "next() -> r\n" @@ -781,16 +784,16 @@ static char pynids_next__doc__[] = "next() -> r\n" "pcap raise a nids.error exception.\n"; static PyObject *pynids_next(PyObject *na, PyObject *args) { - int ret; + int ret; - if (!PyArg_ParseTuple(args, ":next")) - return NULL; + if (!PyArg_ParseTuple(args, ":next")) + return NULL; - ret = nids_dispatch_exc(1); - if (PyErr_Occurred()) - return NULL; /* python callback error */ + ret = nids_dispatch_exc(1); + if (PyErr_Occurred()) + return NULL; /* python callback error */ - return PyLong_FromLong((long)ret); + return PyLong_FromLong((long)ret); } static char pynids_dispatch__doc__[] = "dispatch(cnt) -> processed\n" @@ -798,16 +801,16 @@ static char pynids_dispatch__doc__[] = "dispatch(cnt) -> processed\n" "UNDOCUMENTED -- this function does not exist in libnids <= 1.19.\n"; static PyObject *pynids_dispatch(PyObject *na, PyObject *args) { - int ret, cnt; + int ret, cnt; - if (!PyArg_ParseTuple(args, "i:dispatch", &cnt)) - return NULL; + if (!PyArg_ParseTuple(args, "i:dispatch", &cnt)) + return NULL; - ret = nids_dispatch_exc(cnt); - if (ret == -1) - return NULL; + ret = nids_dispatch_exc(cnt); + if (ret == -1) + return NULL; - return PyLong_FromLong((long)ret); + return PyLong_FromLong((long)ret); } static char pynids_run__doc__[] = "run() -> None\n" @@ -819,31 +822,31 @@ static char pynids_run__doc__[] = "run() -> None\n" "or in nids/pcap (as nids.error) may abort processing.\n"; static PyObject *pynids_run(PyObject *na, PyObject *args) { - int r; + int r; - if (!PyArg_ParseTuple(args, ":run")) - return NULL; + if (!PyArg_ParseTuple(args, ":run")) + return NULL; - if (pynids_offline_read) { - /* read until EOF, checking for exceptions along the way */ - do { - r = nids_dispatch_exc(1); - } while (r > 0); - } else { - /* read forever, checking for exceptions along the way */ - do { - r = nids_dispatch_exc(1); - } while (r >= 0); - } - - if (r == -1) - return NULL; + if (pynids_offline_read) { + /* read until EOF, checking for exceptions along the way */ + do { + r = nids_dispatch_exc(1); + } while (r > 0); + } else { + /* read forever, checking for exceptions along the way */ + do { + r = nids_dispatch_exc(1); + } while (r >= 0); + } + + if (r == -1) + return NULL; #if 0 if (r != 0) runtime error! #endif - Py_RETURN_NONE; + Py_RETURN_NONE; } static char pynids_init__doc__[] = "init() -> None\n" @@ -859,19 +862,19 @@ static char pynids_init__doc__[] = "init() -> None\n" "this call.\n"; static PyObject *pynids_init(PyObject *na, PyObject *args) { - int ok; - if (!PyArg_ParseTuple(args, ":init")) - return NULL; + int ok; + if (!PyArg_ParseTuple(args, ":init")) + return NULL; - ok = nids_init(); - if (!ok) - return raisePynidsError(); - if (nids_params.filename) - pynids_offline_read = 1; - else - pynids_offline_read = 0; + ok = nids_init(); + if (!ok) + return raisePynidsError(); + if (nids_params.filename) + pynids_offline_read = 1; + else + pynids_offline_read = 0; - Py_RETURN_NONE; + Py_RETURN_NONE; } static char pynids_get_pkt_ts__doc__[] = "get_pkt_time() -> float\n" @@ -879,13 +882,13 @@ static char pynids_get_pkt_ts__doc__[] = "get_pkt_time() -> float\n" "Returns the timestamp of the most recent packet as a float.\n"; static PyObject *pynids_get_pkt_ts(PyObject *na, PyObject *args) { - double pkt_time; + double pkt_time; - if (!PyArg_ParseTuple(args, ":get_pkt_ts")) - return NULL; + if (!PyArg_ParseTuple(args, ":get_pkt_ts")) + return NULL; - pkt_time = nids_last_pcap_header->ts.tv_sec + (nids_last_pcap_header->ts.tv_usec / 1000000.0); - return PyFloat_FromDouble(pkt_time); + pkt_time = nids_last_pcap_header->ts.tv_sec + (nids_last_pcap_header->ts.tv_usec / 1000000.0); + return PyFloat_FromDouble(pkt_time); } static char pynids_get_pcap_stats__doc__[] = "get_pcap_stats() -> tuple\n" @@ -893,29 +896,29 @@ static char pynids_get_pcap_stats__doc__[] = "get_pcap_stats() -> tuple\n" "Returns the pcap recv, drop and interface drop statistics as a tuple.\n"; static PyObject *pynids_get_pcap_stats(PyObject *na, PyObject *args) { - static struct pcap_stat ps; - PyObject *pcap_stats_tuple; + static struct pcap_stat ps; + PyObject *pcap_stats_tuple; - if (!PyArg_ParseTuple(args, ":get_pcap_stats")) - return NULL; + if (!PyArg_ParseTuple(args, ":get_pcap_stats")) + return NULL; - if (nids_params.pcap_desc == NULL || pcap_stats(nids_params.pcap_desc, &ps) != 0) { - raisePynidsError(); - return NULL; - } + if (nids_params.pcap_desc == NULL || pcap_stats(nids_params.pcap_desc, &ps) != 0) { + raisePynidsError(); + return NULL; + } - pcap_stats_tuple = Py_BuildValue("III", ps.ps_recv, ps.ps_drop, ps.ps_ifdrop); + pcap_stats_tuple = Py_BuildValue("III", ps.ps_recv, ps.ps_drop, ps.ps_ifdrop); - if (!pcap_stats_tuple) - return NULL; + if (!pcap_stats_tuple) + return NULL; - return pcap_stats_tuple; + return pcap_stats_tuple; } /* List of functions defined in the module */ #define mkMethod(x) \ - { #x, pynids_##x, METH_VARARGS, pynids_##x##__doc__ } + { #x, pynids_##x, METH_VARARGS, pynids_##x##__doc__ } static PyMethodDef pynids_methods[] = { mkMethod(run), @@ -947,41 +950,41 @@ static struct PyModuleDef moduledef = { /* ====================================================================== */ PyMODINIT_FUNC PyInit_nids(void) { - PyObject *m; + PyObject *m; - /* Initialize the type of the new type object here; doing it here - * is required for portability to Windows without requiring C++. */ - Py_TYPE(&TcpStream_Type) = &PyType_Type; - Py_TYPE(&HalfStream_Type) = &PyType_Type; + /* Initialize the type of the new type object here; doing it here + * is required for portability to Windows without requiring C++. */ + Py_TYPE(&TcpStream_Type) = &PyType_Type; + Py_TYPE(&HalfStream_Type) = &PyType_Type; - /* Create the module and add the functions */ + /* Create the module and add the functions */ - m = PyModule_Create(&moduledef); + m = PyModule_Create(&moduledef); - /* Initialize, add our exception object */ - pynids_error = PyErr_NewException("nids.error", NULL, NULL); - Py_INCREF(pynids_error); - PyModule_AddObject(m, "error", pynids_error); + /* Initialize, add our exception object */ + pynids_error = PyErr_NewException("nids.error", NULL, NULL); + Py_INCREF(pynids_error); + PyModule_AddObject(m, "error", pynids_error); - /* Add versioning info */ - PyModule_AddStringConstant(m, "__version__", "0.6.2"); - PyModule_AddObject(m, "__nids_version__", PyString_FromFormat("%d.%d", NIDS_MAJOR, NIDS_MINOR)); + /* Add versioning info */ + PyModule_AddStringConstant(m, "__version__", "0.6.2"); + PyModule_AddObject(m, "__nids_version__", PyString_FromFormat("%d.%d", NIDS_MAJOR, NIDS_MINOR)); - /* Add NIDS_ symbolic constants to the module */ + /* Add NIDS_ symbolic constants to the module */ #define setConst(CONST) PyModule_AddIntConstant(m, #CONST, CONST) - setConst(NIDS_JUST_EST); - setConst(NIDS_DATA); - setConst(NIDS_CLOSE); - setConst(NIDS_RESET); - setConst(NIDS_TIMED_OUT); + setConst(NIDS_JUST_EST); + setConst(NIDS_DATA); + setConst(NIDS_CLOSE); + setConst(NIDS_RESET); + setConst(NIDS_TIMED_OUT); #ifndef NIDS_TIMEOUT #define NIDS_TIMEOUT NIDS_TIMED_OUT #endif - setConst(NIDS_TIMEOUT); /* compat. w/ manpage */ - setConst(NIDS_EXITING); + setConst(NIDS_TIMEOUT); /* compat. w/ manpage */ + setConst(NIDS_EXITING); - /* Save the original nids_params */ - origNidsParams = nids_params; - return m; + /* Save the original nids_params */ + origNidsParams = nids_params; + return m; } From 2d38aeeff6aafe9ff7671da07b86fdf61ca67c9d Mon Sep 17 00:00:00 2001 From: James Stronz Date: Sun, 22 Sep 2019 18:36:49 -0500 Subject: [PATCH 18/23] Made pynids_chksum_ctl__doc__ consistent with changes to other doc strings --- nidsmodule.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/nidsmodule.c b/nidsmodule.c index 8553bad..d1cf7b1 100644 --- a/nidsmodule.c +++ b/nidsmodule.c @@ -523,18 +523,18 @@ makeRegisterFunc(ip_frag, fragFunc, callFragFunc); /* Module Functions */ /* ====================================================================== */ -static char pynids_chksum_ctl__doc__[] = "chksum_ctl([(addr1, True), (addr2, False)], ...) -> None\n\ -\n\ -takes as arguments an list of tuples where a tuple should have the\n\ -following format:\n\ - (Source address in CIDR format, Boolean whether to apply checksum)\n\ - e.g. (\"192.168.1.10/24\", True)\n\ -Internal checksumming functions will first check elements of this\n\ -list one by one, and if the source ip of the current packet\n\ -matches the source address and mask of a tuple then the packet with either\n\ -be checksummed if the apply boolean is set to True, or not checksummed if\n\ -the boolean is set to False. If the packet matches none of the list\n\ -elements, the default action is to perform checksumming.\n"; +static char pynids_chksum_ctl__doc__[] = "chksum_ctl([(addr1, True), (addr2, False)], ...) -> None\n" + "\n" + "takes as arguments an list of tuples where a tuple should have the\n" + "following format:\n" + " (Source address in CIDR format, Boolean whether to apply checksum)\n" + " e.g. (\"192.168.1.10/24\", True)\n" + "Internal checksumming functions will first check elements of this\n" + "list one by one, and if the source ip of the current packet\n" + "matches the source address and mask of a tuple then the packet with either\n" + "be checksummed if the apply boolean is set to True, or not checksummed if\n" + "the boolean is set to False. If the packet matches none of the list\n" + "elements, the default action is to perform checksumming.\n"; static int _parse_prefix(char *prefix, u_int *netaddr, u_int *mask) { struct in_addr in; From 8deba1320c97e64f4273a7a32509e868fa25df4f Mon Sep 17 00:00:00 2001 From: James Stronz Date: Sun, 22 Sep 2019 20:22:44 -0500 Subject: [PATCH 19/23] Cleaned up PyTypeObject structs and fixed type warnings --- nidsmodule.c | 92 ++++++++++++++-------------------------------------- 1 file changed, 25 insertions(+), 67 deletions(-) diff --git a/nidsmodule.c b/nidsmodule.c index d1cf7b1..68746a1 100644 --- a/nidsmodule.c +++ b/nidsmodule.c @@ -275,38 +275,15 @@ static PyGetSetDef TcpStream_getsets[] = { static PyTypeObject TcpStream_Type = { /* The ob_type field must be initialized in the module init function * to be portable to Windows without using C++. */ - PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ - "TcpStream", /*tp_name*/ - sizeof(TcpStream), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)TcpStream_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - PyObject_GenericGetAttr, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - 0, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - TcpStream_methods, /*tp_methods*/ - 0, /*tp_members*/ - TcpStream_getsets, /*tp_getset*/ - 0, /*tp_base*/ + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "TcpStream", + .tp_basicsize = sizeof(TcpStream), + .tp_itemsize = 0, + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_dealloc = (destructor)TcpStream_dealloc, + .tp_getattro = PyObject_GenericGetAttr, + .tp_methods = TcpStream_methods, + .tp_getset = TcpStream_getsets, }; /* ====================================================================== */ @@ -388,38 +365,16 @@ static PyGetSetDef HalfStream_getsets[] = { static PyTypeObject HalfStream_Type = { /* The ob_type field must be initialized in the module init function * to be portable to Windows without using C++. */ - PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ - "HalfStream", /*tp_name*/ - sizeof(HalfStream), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)HalfStream_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - PyObject_GenericGetAttr, /*tp_getattro*/ - PyObject_GenericSetAttr, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - 0, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - 0, /*tp_methods*/ - 0, /*tp_members*/ - HalfStream_getsets, /*tp_getset*/ - 0, /*tp_base*/ + + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "HalfStream", + .tp_basicsize = sizeof(HalfStream), + .tp_itemsize = 0, + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_dealloc = (destructor)HalfStream_dealloc, + .tp_getattro = PyObject_GenericGetAttr, + .tp_setattro = PyObject_GenericSetAttr, + .tp_getset = HalfStream_getsets, }; /* ====================================================================== */ @@ -582,11 +537,14 @@ static int _parse_chksum_tuple(struct nids_chksum_ctl *ctl, int i, PyObject *tup PyObject *addr, *action; addr = PyTuple_GET_ITEM(tuple, 0); - if (PyString_Check(addr) <= 0) { + + if (PyUnicode_Check(addr) > 0) + addr = PyBytes_FromObject(addr); + if (PyBytes_Check(addr) <= 0) { PyErr_SetString(PyExc_TypeError, "in (cidr_address, action) cidr_address must be string"); return -1; } - if (_parse_prefix(addr, &ctl[i].netaddr, &ctl[i].mask) < 0) + if (_parse_prefix(PyBytes_AS_STRING( addr), &ctl[i].netaddr, &ctl[i].mask) < 0) return -1; action = PyTuple_GET_ITEM(tuple, 1); @@ -740,7 +698,7 @@ static PyObject *pynids_param(PyObject *na, PyObject *args) { */ if (*char_pp) free(*char_pp); - *char_pp = (v == Py_None) ? NULL : strdup(PyString_AsString(v)); + *char_pp = (v == Py_None) ? NULL : strdup(PyBytes_AsString(v)); } return ret; } From 4ea45067c3c1fdca7d2581057f90eada6fea92a8 Mon Sep 17 00:00:00 2001 From: James Stronz Date: Sun, 22 Sep 2019 20:47:48 -0500 Subject: [PATCH 20/23] Fixed warning about u_char for urgdata --- nidsmodule.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/nidsmodule.c b/nidsmodule.c index 68746a1..2041157 100644 --- a/nidsmodule.c +++ b/nidsmodule.c @@ -341,8 +341,10 @@ static PyObject *hs_get_data(HalfStream *self, void *unused) { return PyBytes_FromStringAndSize(self->hlfs->data, self->hlfs->bufsize); } static PyObject *hs_get_urgdata(HalfStream *self, void *unused) { - /* u_char urgdata */ - return PyBytes_FromStringAndSize(&(self->hlfs->urgdata), sizeof(self->hlfs->urgdata)); + /* since hlfs->urgdata is a u_char and given the same object representation, + * it is okay to use the address of urgdata and store it within a char * + */ + return PyBytes_FromStringAndSize((char *)&(self->hlfs->urgdata), sizeof(self->hlfs->urgdata)); } HS_GET_INT(count) HS_GET_INT(offset) From b1c87a0368d7bde8cbffd040133a57f7243650c8 Mon Sep 17 00:00:00 2001 From: James Stronz Date: Sun, 22 Sep 2019 20:49:48 -0500 Subject: [PATCH 21/23] Replaced missed PyString_* --- nidsmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nidsmodule.c b/nidsmodule.c index 2041157..6913cf5 100644 --- a/nidsmodule.c +++ b/nidsmodule.c @@ -928,7 +928,7 @@ PyMODINIT_FUNC PyInit_nids(void) { /* Add versioning info */ PyModule_AddStringConstant(m, "__version__", "0.6.2"); - PyModule_AddObject(m, "__nids_version__", PyString_FromFormat("%d.%d", NIDS_MAJOR, NIDS_MINOR)); + PyModule_AddObject(m, "__nids_version__", PyUnicode_FromFormat("%d.%d", NIDS_MAJOR, NIDS_MINOR)); /* Add NIDS_ symbolic constants to the module */ #define setConst(CONST) PyModule_AddIntConstant(m, #CONST, CONST) From b6b6d04645fd9cfa516d488e23ae01bd915112a1 Mon Sep 17 00:00:00 2001 From: James Stronz Date: Wed, 25 Sep 2019 00:40:35 -0500 Subject: [PATCH 22/23] Fixed addr type check in _parse_chksum_tuple --- nidsmodule.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/nidsmodule.c b/nidsmodule.c index 6913cf5..c84cde3 100644 --- a/nidsmodule.c +++ b/nidsmodule.c @@ -372,7 +372,6 @@ static PyTypeObject HalfStream_Type = { .tp_name = "HalfStream", .tp_basicsize = sizeof(HalfStream), .tp_itemsize = 0, - .tp_flags = Py_TPFLAGS_DEFAULT, .tp_dealloc = (destructor)HalfStream_dealloc, .tp_getattro = PyObject_GenericGetAttr, .tp_setattro = PyObject_GenericSetAttr, @@ -539,10 +538,7 @@ static int _parse_chksum_tuple(struct nids_chksum_ctl *ctl, int i, PyObject *tup PyObject *addr, *action; addr = PyTuple_GET_ITEM(tuple, 0); - - if (PyUnicode_Check(addr) > 0) - addr = PyBytes_FromObject(addr); - if (PyBytes_Check(addr) <= 0) { + if (PyUnicode_Check(addr) <= 0) { PyErr_SetString(PyExc_TypeError, "in (cidr_address, action) cidr_address must be string"); return -1; } @@ -568,8 +564,9 @@ static PyObject *pynids_chksum_ctl(PyObject *na, PyObject *args) { struct nids_chksum_ctl *ctl = NULL; /* parse args */ - if (!PyArg_ParseTuple(args, "O:chksum_ctl", &items)) + if (!PyArg_ParseTuple(args, "O:chksum_ctl", &items)){ return NULL; + } /* parse list of address/action tuples */ if (PyList_Check(items) > 0) { @@ -678,8 +675,9 @@ static PyObject *pynids_param(PyObject *na, PyObject *args) { if (int_p) { /* FIXME - type check val for intishness */ ret = PyLong_FromLong((long)*int_p); - if (v) + if (v) { *int_p = (int)PyLong_AsLong(v); + } return ret; } From 6c271b26a9ec7b377d9bb3205c9318e2c087391d Mon Sep 17 00:00:00 2001 From: James Stronz Date: Wed, 25 Sep 2019 00:42:32 -0500 Subject: [PATCH 23/23] Changed nidsmodule to nids in setup.py to fix import --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 9b76260..73fee6c 100644 --- a/setup.py +++ b/setup.py @@ -63,7 +63,7 @@ def run(self): ''', cmdclass = {'build': nidsMaker}, ext_modules = [ Extension( - "nidsmodule", + "nids", #define_macros = [ ("DEBUG", None), ], sources=["nidsmodule.c"], include_dirs = INCLUDE_DIRS,