Пример #1
0
class Packet(ProcData):
    """数据包(未拆包)"""
    _head = None
    _buff = None
    name = "Packet"

    def __init__(self):
        super(ProcData, self).__init__()
        self._buff = BytesBuffer()

    def parse(self, data):
        """
        解析包数据
        :param data: 字节数据
        :return:    data,size
        """
        size = len(data)
        assert size > 0
        if self._head is None:
            self._head = PacketHead(data)
            size -= 16
            data = data[16:]
        if size > 0:
            _bs = len(self._buff)
            if _bs + size < self._head.incl:
                self._buff.write(data)
                size = 0
                data = None
            else:
                offset = self._head.incl - _bs
                self._buff.write(data[:offset])
                data = data[offset:]
                size -= offset
                assert len(data) == size
        return data, size

    def __del__(self):
        self._buff.close()

    @property
    def head(self):
        return self._head

    @property
    def data(self):
        return MAC(self._buff.getvalue(),None)

    def finish(self):
        return len(self._buff) == self._head.incl
Пример #2
0
 def parse(self, file, buffSize=2048):
     """
     解析pcap文件,返回值为一个生成器 yield
     :param file:缓冲文件大小
     :param buffSize:
     :return:返回一个生成器(用于处理大包)
     """
     assert file != ""
     _buff = BytesBuffer()
     _packet = None
     ret = 0
     with open(file, "rb") as o:
         ctx = None
         while 1:
             # 优先处理缓冲区数据(如果缓存数据超过了指定大小)
             bsize = len(_buff)
             if bsize > 0:
                 if bsize >= buffSize:
                     ctx = _buff.getvalue()
                 else:
                     _buff.write(o.read(buffSize))
                     ctx = _buff.getvalue()
                 _buff.clear()
             else:
                 ctx = o.read(buffSize)
             size = len(ctx)
             if size > 0:
                 if self.__head is None:
                     # 文件头占24字节
                     if size >= 24:
                         self.__head = PcapHead(ctx[:24])
                         size -= 24
                         ctx = ctx[24:]
                     else:
                         _buff.write(ctx)
                 # 分析包头(包头占16字节)
                 if size > 16:
                     if _packet is None:
                         _packet = Packet()
                         ctx, size = _packet.parse(ctx)
                         if _packet.finish():
                             yield _packet
                             ret += 1
                             _packet = None
                         if size > 0:
                             _buff.write(ctx)
                     else:
                         ctx, size = _packet.parse(ctx)
                         if _packet.finish():
                             yield _packet
                             ret += 1
                             _packet = None
                         if size > 0:
                             _buff.write(ctx)
                 else:
                     _buff.write(ctx)
             else:
                 break
         del ctx
     del _buff
     self.__ret = ret
Пример #3
0
 def __init__(self):
     self._c1 = BytesBuffer()
     self._c2 = BytesBuffer()
     self._s1 = BytesBuffer()
     self._s2 = BytesBuffer()
     self._buff = BytesBuffer()
Пример #4
0
class RTMP(AppProcData):
    """
        尝试rtmp协议解析,默认端口1935
        参考文档:https://www.cnblogs.com/android-blogs/p/5650771.html
    """
    c0 = None
    _c1 = None
    _c2 = None
    s0 = None
    _s1 = None
    _s2 = None
    _buff = None
    _chunk = None

    __prev_rtmp = {}
    __fn = None
    __ins = None

    def __init__(self):
        self._c1 = BytesBuffer()
        self._c2 = BytesBuffer()
        self._s1 = BytesBuffer()
        self._s2 = BytesBuffer()
        self._buff = BytesBuffer()

    def bind(self, fn):
        """
        绑定回调函数
        :param fn:  回调函数    callback_rtmp(ins, msg, fr)
        :return:
        """
        self.__fn = fn

    @property
    def c1(self):
        return _RTMP_c1s1(self._c1.getvalue())

    @property
    def s1(self):
        return _RTMP_c1s1(self._s1.getvalue())

    def _process(self, data, fr=0):
        self._chunk = RTMP_Chunk(data)
        return self.__fn(self, self._chunk, fr)

    def _except_c2s2(self, fr):
        """特别处理rtmp握手过程中在c2s2中包含控制信息的数据(1536随机数据中)"""
        if fr == RTMP_CLIENT:
            print([hex(i) for i in self._c2.getvalue()])
            pass
        elif fr == RTMP_SERVER:
            pass
        pass

    @staticmethod
    def find(tcp, fn):
        """
        校验数据并完成初始化,成功返回self,链式调用
        :param tcp:     上层调用者tcp对象
        :param fn:      回调函数
        :return:
        """
        assert fn is not None
        data = tcp.data
        size = len(data)
        if size > 0:
            # 4元祖确定连接
            only_id = OnlyId.build(tcp.upper.src, tcp.upper.dst, tcp.src,
                                   tcp.dst)
            if tcp.dst == RTMP_PORT:
                if only_id not in RTMP.__prev_rtmp:
                    # 每一个链路触发一个对象
                    ins = RTMP()
                    ins.bind(fn)
                    if data[0] == RTMP_VERSION:
                        ins.c0 = data[0]
                        ins.__fn(ins, "C0", RTMP_CLIENT)
                        size, data = size - 1, data[1:]
                        # 剩下最大值mss也不够1536
                        if size > 0:
                            ins._c1.write(data)
                        RTMP.__prev_rtmp[only_id] = ins
                else:
                    tmp = RTMP.__prev_rtmp.get(only_id)
                    c1_size = len(tmp._c1)
                    if c1_size == 1536:
                        c2_size = len(tmp._c2)
                        if c2_size == 1536:
                            tmp._process(data, RTMP_CLIENT)
                        else:
                            last_c2size = 1536 - c2_size
                            if last_c2size >= size:
                                tmp._c2.write(data[:size])
                                data = data[size:]
                            else:
                                tmp._c2.write(data[:(size - last_c2size)])
                                size = size - last_c2size
                                data = data[size:]
                            if len(tmp._c2) == 1536:
                                # 写入c2
                                tmp._except_c2s2(RTMP_CLIENT)
                                tmp.__fn(tmp, "C2", RTMP_CLIENT)
                                assert len(data) == 0
                    else:
                        last_c1size = 1536 - c1_size
                        if last_c1size >= size:
                            tmp._c1.write(data[:size])
                            data = data[size:]
                        else:
                            tmp._c1.write(data[:last_c1size])
                            data = data[last_c1size:]
                        if len(tmp._c1) == 1536:
                            tmp.__fn(tmp, "C1", RTMP_SERVER)
                        if len(data) > 0:
                            tmp._c2.write(data)
            elif tcp.src == RTMP_PORT:
                # server
                if only_id not in RTMP.__prev_rtmp:
                    if data[0] == RTMP_VERSION:
                        ins = RTMP()
                        ins.bind(fn)
                        ins.s0 = data[0]
                        ins.__fn(ins, "S0", RTMP_SERVER)
                        data = data[1:]
                        size -= 1
                        # 剩下最大值mss也不够1536,就不用判断了
                        if size > 0:
                            ins._s1.write(data)
                        RTMP.__prev_rtmp[only_id] = ins
                else:
                    tmp = RTMP.__prev_rtmp.get(only_id)
                    s1_size = len(tmp._s1)
                    if s1_size == 1536:
                        s2_size = len(tmp._s2)
                        if s2_size == 1536:
                            # 握手完成,处理数据
                            tmp._process(data, RTMP_SERVER)
                        else:
                            last_s2size = 1536 - s2_size
                            if last_s2size >= size:
                                tmp._s2.write(data[:size])
                                data = data[size:]
                            else:
                                tmp._s2.write(data[:(size - last_s2size)])
                                data = data[size - last_s2size:]
                            if len(tmp._s2) == 1536:
                                # 写入c2
                                tmp._except_c2s2(RTMP_SERVER)
                                tmp.__fn(tmp, "S2", RTMP_SERVER)
                                assert len(data) == 0
                    else:
                        last_s1size = 1536 - s1_size
                        if last_s1size >= size:
                            tmp._s1.write(data[:size])
                            data = data[size:]
                        else:
                            tmp._s1.write(data[:last_s1size])
                            data = data[last_s1size:]
                        if len(tmp._s1) == 1536:
                            # 写入s1
                            tmp.__fn(tmp, "S1", RTMP_SERVER)
                        if len(data) > 0:
                            tmp._s2.write(data)
            else:
                return False
        return True
Пример #5
0
 def __init__(self):
     super(ProcData, self).__init__()
     self._buff = BytesBuffer()