LINUX.ORG.RU

[python][libnetfilter_conntrack] conntrack_events.py

 


0

0

По аналогии с conntrack_events.c.

#!/usr/bin/env python

import sys
from ctypes import *

nfct = CDLL('libnetfilter_conntrack.so')
libc = CDLL('libc.so.6')


NFCT_CALLBACK = CFUNCTYPE(c_int, c_int, c_void_p, c_void_p)

# conntrack
CONNTRACK = 1
EXPECT = 2

# netlink groups
NF_NETLINK_CONNTRACK_NEW         = 0x00000001
NF_NETLINK_CONNTRACK_UPDATE      = 0x00000002
NF_NETLINK_CONNTRACK_DESTROY     = 0x00000004
NF_NETLINK_CONNTRACK_EXP_NEW     = 0x00000008
NF_NETLINK_CONNTRACK_EXP_UPDATE  = 0x00000010
NF_NETLINK_CONNTRACK_EXP_DESTROY = 0x00000020

NFCT_ALL_CT_GROUPS = (NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_UPDATE \
    | NF_NETLINK_CONNTRACK_DESTROY)

# nfct_*printf output format
NFCT_O_PLAIN = 0
NFCT_O_DEFAULT = NFCT_O_PLAIN
NFCT_O_XML = 1
NFCT_O_MAX = 2

# output flags
NFCT_OF_SHOW_LAYER3_BIT = 0
NFCT_OF_SHOW_LAYER3 = (1 << NFCT_OF_SHOW_LAYER3_BIT)
NFCT_OF_TIME_BIT = 1
NFCT_OF_TIME = (1 << NFCT_OF_TIME_BIT)
NFCT_OF_ID_BIT = 2
NFCT_OF_ID = (1 << NFCT_OF_ID_BIT)

# callback return code
NFCT_CB_FAILURE = -1   # failure
NFCT_CB_STOP = 0       # stop the query
NFCT_CB_CONTINUE = 1   # keep iterating through data
NFCT_CB_STOLEN = 2     # like continue, but ct is not freed

# message type
NFCT_T_UNKNOWN = 0
NFCT_T_NEW_BIT = 0
NFCT_T_NEW = (1 << NFCT_T_NEW_BIT)
NFCT_T_UPDATE_BIT = 1
NFCT_T_UPDATE = (1 << NFCT_T_UPDATE_BIT)
NFCT_T_DESTROY_BIT = 2
NFCT_T_DESTROY = (1 << NFCT_T_DESTROY_BIT)
NFCT_T_ALL = NFCT_T_NEW | NFCT_T_UPDATE | NFCT_T_DESTROY
NFCT_T_ERROR_BIT = 31
NFCT_T_ERROR = (1 << NFCT_T_ERROR_BIT)

def event_callback(type, ct, data):
    buf = create_string_buffer(1024)
    nfct.nfct_snprintf(buf, 1024, ct, type, NFCT_O_XML, NFCT_OF_TIME)
    sys.stdout.write("%s\n" % buf.value)
    return NFCT_CB_STOP

h = nfct.nfct_open(CONNTRACK, NFCT_ALL_CT_GROUPS)
if h == 0:
    libc.perror("nfct_open")

nfct.nfct_callback_register(h, NFCT_T_NEW | NFCT_T_DESTROY, NFCT_CALLBACK(event_callback), 0)
ret = nfct.nfct_catch(h)

sys.stdout.write("Ready\n")

if ret == -1:
    sys.stdout.write("Error\n")
else:
    sys.stdout.write("Ok\n")

nfct.nfct_close(h)

Выдает

# python conntrack_events.py
<flow type="destroy"><meta direction="original"><layer3 protonum="2" protoname="ipv4"><src>195.54.14.98</src><dst>194.144.16.73</dst></layer3><layer4 protonum="6" protoname="tcp"><sport>37123</sport><dport>13999</dport></layer4><counters><packets>3</packets><bytes>180</bytes></counters></meta><meta direction="reply"><layer3 protonum="2" protoname="ipv4"><src>194.144.16.73</src><dst>195.54.14.98</dst></layer3><layer4 protonum="6" protoname="tcp"><sport>13999</sport><dport>37123</dport></layer4><counters><packets>0</packets><bytes>0</bytes></counters></meta><meta direction="independent"><id>3790149744</id><unreplied/></meta><when><hour>4</hour><min>54</min><sec>24</sec><wday>2</wday><day>18</day><month>1</month><year>2010</year></when></flow>
Ошибка сегментирования

А иногда просто «Ошибка сегментирования». Куда копать? Чем пользоваться?

★★★★★

блин. refcount то поддерживать надо, откуда питон знает что в libnetfilter_conntrack.so референс остался если я тут его нигде не сохранил

очевидно же! три часа <вырезано цензурой>

ei-grad ★★★★★
() автор топика
Ответ на: комментарий от ei-grad

и valgrind об этом же говорил... блин...

ei-grad ★★★★★
() автор топика

Вот что получилось:

#!/usr/bin/env python
#
# Copyright (c) 2009 Andrew Grigorev <andrew@ei-grad.ru>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# 
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
# 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#


import sys
from ctypes import *
from threading import Thread


nfct = CDLL('libnetfilter_conntrack.so')
libc = CDLL('libc.so.6')


NFCT_CALLBACK = CFUNCTYPE(c_int, c_int, c_void_p, c_void_p)

# conntrack
CONNTRACK = 1
EXPECT = 2

# netlink groups
NF_NETLINK_CONNTRACK_NEW         = 0x00000001
NF_NETLINK_CONNTRACK_UPDATE      = 0x00000002
NF_NETLINK_CONNTRACK_DESTROY     = 0x00000004
NF_NETLINK_CONNTRACK_EXP_NEW     = 0x00000008
NF_NETLINK_CONNTRACK_EXP_UPDATE  = 0x00000010
NF_NETLINK_CONNTRACK_EXP_DESTROY = 0x00000020

NFCT_ALL_CT_GROUPS = (NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_UPDATE \
    | NF_NETLINK_CONNTRACK_DESTROY)

# nfct_*printf output format
NFCT_O_PLAIN = 0
NFCT_O_DEFAULT = NFCT_O_PLAIN
NFCT_O_XML = 1
NFCT_O_MAX = 2

# output flags
NFCT_OF_SHOW_LAYER3_BIT = 0
NFCT_OF_SHOW_LAYER3 = (1 << NFCT_OF_SHOW_LAYER3_BIT)
NFCT_OF_TIME_BIT = 1
NFCT_OF_TIME = (1 << NFCT_OF_TIME_BIT)
NFCT_OF_ID_BIT = 2
NFCT_OF_ID = (1 << NFCT_OF_ID_BIT)

# callback return code
NFCT_CB_FAILURE = -1   # failure
NFCT_CB_STOP = 0       # stop the query
NFCT_CB_CONTINUE = 1   # keep iterating through data
NFCT_CB_STOLEN = 2     # like continue, but ct is not freed

# message type
NFCT_T_UNKNOWN = 0
NFCT_T_NEW_BIT = 0
NFCT_T_NEW = (1 << NFCT_T_NEW_BIT)
NFCT_T_UPDATE_BIT = 1
NFCT_T_UPDATE = (1 << NFCT_T_UPDATE_BIT)
NFCT_T_DESTROY_BIT = 2
NFCT_T_DESTROY = (1 << NFCT_T_DESTROY_BIT)
NFCT_T_ALL = NFCT_T_NEW | NFCT_T_UPDATE | NFCT_T_DESTROY
NFCT_T_ERROR_BIT = 31
NFCT_T_ERROR = (1 << NFCT_T_ERROR_BIT)


class ConntrackEventListener(Thread):
    def __init__(self, callback, msg_types=NFCT_T_NEW|NFCT_T_DESTROY):
        Thread.__init__(self)
        
        self.h = nfct.nfct_open(CONNTRACK, NFCT_ALL_CT_GROUPS)

        if self.h == 0:
            libc.perror("nfct_open")
            raise Exception("nfct_open failed!")
        
        buf = create_string_buffer(1024)
        self._stop = False

        def event_callback_closure(type, ct, data):
            nfct.nfct_snprintf(buf, 1024, ct, type, NFCT_O_XML, NFCT_OF_TIME)
            callback(buf.value)
            if self._stop:
                return NFCT_CB_STOP
            return NFCT_CB_CONTINUE

        self.cb = NFCT_CALLBACK(event_callback_closure)

        nfct.nfct_callback_register(self.h, msg_types, self.cb, 0)

    def run(self):
        ret = nfct.nfct_catch(self.h)
        
        nfct.nfct_callback_unregister(self.h)
        nfct.nfct_close(self.h)
        
        if ret == -1:
            libc.perror()
            raise Exception("nfct_catch failed!")

    def stop(self):
        self._stop = True

__all__ = ["ConntrackEventListener", "NFCT_T_NEW", "NFCT_T_UPDATE", "NFCT_T_DESTROY", "NFCT_T_ERROR"]

if __name__ == "__main__":
    l = ConntrackEventListener(lambda x: sys.stdout.write("%s\n" % x))
    l.start()
    try:
        input()
    except:
        pass
    sys.stdout.write("Terminating (waiting for last event...)\n")
    l.stop()
    l.join()
ei-grad ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.