• zeek学习(三)——包获取


    重要类

    • iosource::Manager
    • timer_mgr

    问题

    1. 包是从何时开始捕获的?其包的函数流程?

    IOSource

    class IOSource
    {
        // 构造函数,
        IOSource(bool process_fd = false)
        
        // 返回该source是否是打开状态即可读取状态
        bool IsOpen()
        
        // 如果是packet的Source则返回true
        virtual bool IsPacketSource()
        
        // 对source进行初始化,此函数在派生类中被重写
        virtual void InitSource()
            
        // 在关闭source时执行,可以在派生类中重写
        virtual void Done()
        
        // 返回此source的超时值。具有超时类的可以重写此函数
    	virtual double GetNextTimeout() = 0;
    
    	// 处理并使用下一个数据项
    	virtual void Process() = 0;
    
    	/ 可选的处理方法,运行IOSource只处理文件描述符,如果实现此方法则构造时必须传true
    	virtual void ProcessFd(int fd, int flags) { }
        
    	bool ImplementsProcessFd() const { return implements_process_fd; }
    
    	// 返回改源的描述信息
    	virtual const char* Tag() = 0;
    
    protected:
    	// 当close时的回调函数
    	void SetClosed(bool is_closed) { closed = is_closed; }
            
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    timer_mgr


    PCAP

    void init_run(const std::optional<std::string>& interface,
                  const std::optional<std::string>& pcap_input_file,
                  const std::optional<std::string>& pcap_output_file, bool do_watchdog)
    {
        if ( pcap_input_file )// 初始化pcap文件
        {
            reading_live = pseudo_realtime > 0.0;
            reading_traces = true;
    
            iosource::PktSrc* ps = iosource_mgr->OpenPktSrc(*pcap_input_file, false);
            assert(ps);
    
            if ( ! ps->IsOpen() )
                reporter->FatalError("problem with trace file %s (%s)", pcap_input_file->c_str(),
                                     ps->ErrorMsg());
        }
        else if ( interface ) // 初始化网络接口
        {
            reading_live = true;
            reading_traces = false;
    
            iosource::PktSrc* ps = iosource_mgr->OpenPktSrc(*interface, true);
            assert(ps);
    
            if ( ! ps->IsOpen() )
                reporter->FatalError("problem with interface %s (%s)", interface->c_str(),
                                     ps->ErrorMsg());
        }
        else
            // have_pending_timers = true, possibly.  We don't set
            // that here, though, because at this point we don't know
            // whether the user's zeek_init() event will indeed set
            // a timer.
            reading_traces = reading_live = false;
    
        if ( pcap_output_file ) //输出
        {
            const char* writefile = pcap_output_file->data();
            pkt_dumper = iosource_mgr->OpenPktDumper(writefile, false);
            assert(pkt_dumper);
    
            if ( ! pkt_dumper->IsOpen() )
                reporter->FatalError("problem opening dump file %s (%s)", writefile,
                                     pkt_dumper->ErrorMsg());
    
            if ( const auto& id = zeek::detail::global_scope()->Find("trace_output_file") )
                id->SetVal(make_intrusive<StringVal>(writefile));
            else
                reporter->Error("trace_output_file not defined");
        }
    
        zeek::detail::init_ip_addr_anonymizers();
    
        session_mgr = new session::Manager();
    
        if ( do_watchdog )
        {
            // Set up the watchdog to make sure we don't wedge.
            (void)setsignal(SIGALRM, watchdog);
            (void)alarm(zeek::detail::watchdog_interval);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    PcapSource

    类图

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o1hgnrw8-1660489984249)(https://cdn.nlark.com/yuque/__puml/8d2aa40217f934d218907956836d1c01.svg#lake_card_v2=eyJ0eXBlIjoicHVtbCIsImNvZGUiOiJAc3RhcnR1bWxcbmNsYXNzIElPU291cmNle1xuXHQrIElPU291cmNlKHByb2Nlc3NfZmQpXG5cdCsgfklPU291cmNlKClcblx0KyBib29sIElzT3BlbigpXG5cdCsge2Fic3RyYWN0fSBib29sIElzUGFja2V0U291cmNlKClcblx0KyB7YWJzdHJhY3R9IHZvaWQgSW5pdFNvdXJjZSgpXG5cdCsge2Fic3RyYWN0fSB2b2lkIERvbmUoKVxuXHQrIHthYnN0cmFjdH0gZG91YmxlIEdldE5leHRUaW1lb3V0KClcblx0KyB7YWJzdHJhY3R9IHZvaWQgUHJvY2VzcygpIFxuXHQrIHthYnN0cmFjdH0gdm9pZCBQcm9jZXNzRmQoaW50IGZkLCBpbnQgZmxhZ3MpXG5cdCsgYm9vbCBJbXBsZW1lbnRzUHJvY2Vzc0ZkKCkgXG5cdCsge2Fic3RyYWN0fSBjb25zdCBjaGFyKiBUYWcoKVxuXHQjIHZvaWQgU2V0Q2xvc2VkKGJvb2wgaXNfY2xvc2VkKVxuXHRcblx0LSBjbG9zZWRcblx0LSBpbXBsZW1lbnRzX3Byb2Nlc3NfZmRcbn1cblxuY2xhc3MgUGt0U3JjIHtcblx0KyBQa3RTcmMoKVxuXHQrIH5Qa3RTcmMoKVxuXHQrIGNvbnN0IHN0ZDo6c3RyaW5nJiBQYXRoKClcblx0KyBib29sIElzTGl2ZSgpXG5cdCsgaW50IExpbmtUeXBlKClcblx0KyB1aW50MzJfdCBOZXRtYXNrKClcblx0KyBib29sIElzRXJyb3IoKVxuXHQrIGNvbnN0IGNoYXIqIEVycm9yTXNnKClcblx0KyBib29sIFByZWNvbXBpbGVCUEZGaWx0ZXIoaW50IGluZGV4LCBjb25zdCBzdGQ6OnN0cmluZyYgZmlsdGVyKVxuXHQrIGRldGFpbDo6QlBGX1Byb2dyYW0qIEdldEJQRkZpbHRlcihpbnQgaW5kZXgpXG5cdCsgYm9vbCBBcHBseUJQRkZpbHRlcihpbnQgaW5kZXgsIGNvbnN0IHN0cnVjdCBwY2FwX3BrdGhkciogaGRyLCBjb25zdCB1X2NoYXIqIHBrdClcblx0KyBib29sIEdldEN1cnJlbnRQYWNrZXQoY29uc3QgUGFja2V0KiogaGRyKSBcblx0KyB7YWJzdHJhY3R9IGJvb2wgUHJlY29tcGlsZUZpbHRlcihpbnQgaW5kZXgsIGNvbnN0IHN0ZDo6c3RyaW5nJiBmaWx0ZXIpXG5cdCsge2Fic3RyYWN0fSBib29sIFNldEZpbHRlcihpbnQgaW5kZXgpXG5cdCsge2Fic3RyYWN0fSB2b2lkIFN0YXRpc3RpY3MoU3RhdHMqIHN0YXRzKVxuXHQrIHthYnN0cmFjdH0gZG91YmxlIEdldE5leHRUaW1lb3V0KCkgXG5cdCMgdm9pZCBPcGVuZWQoY29uc3QgUHJvcGVydGllcyYgcHJvcHMpXG5cdCMgdm9pZCBDbG9zZWQoKVxuXHQjIHZvaWQgSW5mbyhjb25zdCBzdGQ6OnN0cmluZyYgbXNnKVxuXHQjIHZvaWQgRXJyb3IoY29uc3Qgc3RkOjpzdHJpbmcmIG1zZylcblx0IyB2b2lkIFdlaXJkKGNvbnN0IHN0ZDo6c3RyaW5nJiBtc2csIGNvbnN0IFBhY2tldCogcGt0KVxuXHQjIHZvaWQgSW50ZXJuYWxFcnJvcihjb25zdCBzdGQ6OnN0cmluZyYgbXNnKVxuXHQjIHZvaWQgT3BlbigpXG5cdCMgdm9pZCBDbG9zZSgpXG5cdCMgYm9vbCBFeHRyYWN0TmV4dFBhY2tldChQYWNrZXQqIHBrdClcblx0IyB2b2lkIERvbmVXaXRoUGFja2V0KClcblx0LVx0Ym9vbCBFeHRyYWN0TmV4dFBhY2tldEludGVybmFsKClcblx0LSB2b2lkIEluaXRTb3VyY2UoKSBvdmVycmlkZVxuXHQtIHZvaWQgRG9uZSgpIG92ZXJyaWRlXG5cdC0gdm9pZCBQcm9jZXNzKCkgb3ZlcnJpZGVcblx0LSBjb25zdCBjaGFyKiBUYWcoKSBvdmVycmlkZVxuXHQtIFByb3BlcnRpZXMgcHJvcHNcbiAgLSBib29sIGhhdmVfcGFja2V0XG5cdC0gUGFja2V0IGN1cnJlbnRfcGFja2V0XG5cdC0gc3RkOjp2ZWN0b3I8ZGV0YWlsOjpCUEZfUHJvZ3JhbSo-IGZpbHRlcnNcblx0LSBzdGQ6OnN0cmluZyBlcnJidWZcblx0fTtcbn1cblxuY2xhc3MgUGNhcFNvdXJjZSB7XG5cdCsgUGNhcFNvdXJjZShjb25zdCBzdGQ6OnN0cmluZyYgcGF0aCwgYm9vbCBpc19saXZlKVxuXHQrIH5QY2FwU291cmNlKCkgb3ZlcnJpZGU7XG5cblx0KyB7c3RhdGljfSBQa3RTcmMqIEluc3RhbnRpYXRlKGNvbnN0IHN0ZDo6c3RyaW5nJiBwYXRoLCBib29sIGlzX2xpdmUpXG5cblx0IyB2b2lkIE9wZW4oKSBvdmVycmlkZVxuXHQjIHZvaWQgQ2xvc2UoKSBvdmVycmlkZVxuXHQjIGJvb2wgRXh0cmFjdE5leHRQYWNrZXQoUGFja2V0KiBwa3QpIG92ZXJyaWRlXG5cdCMgdm9pZCBEb25lV2l0aFBhY2tldCgpIG92ZXJyaWRlXG5cdCMgYm9vbCBQcmVjb21waWxlRmlsdGVyKGludCBpbmRleCwgY29uc3Qgc3RkOjpzdHJpbmcmIGZpbHRlcikgb3ZlcnJpZGVcblx0IyBib29sIFNldEZpbHRlcihpbnQgaW5kZXgpIG92ZXJyaWRlXG5cdCMgdm9pZCBTdGF0aXN0aWNzKFN0YXRzKiBzdGF0cykgb3ZlcnJpZGVcblxuXHQtIHZvaWQgT3BlbkxpdmUoKVxuXHQtIHZvaWQgT3Blbk9mZmxpbmUoKVxuXHQtIHZvaWQgUGNhcEVycm9yKGNvbnN0IGNoYXIqIHdoZXJlID0gbnVsbHB0cilcblxuXHQtIFByb3BlcnRpZXMgcHJvcHM7XG5cdC0gU3RhdHMgc3RhdHM7XG5cdC0gcGNhcF90KiBwZDtcbn1cblxuSU9Tb3VyY2UgLT4gUGt0U3JjXG5Qa3RTcmMgLT4gUGNhcFNvdXJjZVxuXG5cbkBlbmR1bWwiLCJ1cmwiOiJodHRwczovL2Nkbi5ubGFyay5jb20veXVxdWUvX19wdW1sLzhkMmFhNDAyMTdmOTM0ZDIxODkwNzk1NjgzNmQxYzAxLnN2ZyIsImlkIjoienVIbzQiLCJtYXJnaW4iOnsidG9wIjp0cnVlLCJib3R0b20iOnRydWV9LCJjYXJkIjoiZGlhZ3JhbSJ9)]

    构造函数

    堆栈信息

    zeek::iosource::pcap::PcapSource::PcapSource Source.cc:26
    zeek::iosource::pcap::PcapSource::Instantiate Source.cc:358
    zeek::iosource::Manager::OpenPktSrc Manager.cc:442
    zeek::run_state::detail::init_run RunState.cc:165
    zeek::detail::setup zeek-setup.cc:853
    main main.cc:13
    __libc_start_main 0x00007ffff5e62083
    _start 0x000055555619e1be
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. 创建
    PktSrc* Manager::OpenPktSrc(const std::string& path, bool is_live)
    {
    	std::pair<std::string, std::string> t = split_prefix(path);
    	const auto& prefix = t.first;
    	const auto& npath = t.second;
    
    	// Find the component providing packet sources of the requested prefix.
    
    	PktSrcComponent* component = nullptr;
    
    	std::list<PktSrcComponent*> all_components = plugin_mgr->Components<PktSrcComponent>();
    	for ( const auto& c : all_components )
        {
    		if ( c->HandlesPrefix(prefix) &&
    		     ((is_live && c->DoesLive()) || (! is_live && c->DoesTrace())) )
            {
    			component = c;
    			break;
            }
        }
    
    	if ( ! component )
    		reporter->FatalError("type of packet source '%s' not recognized, or mode not supported",
    		                     prefix.c_str());
    
    	// 初始化PktSrc    
    	PktSrc* ps = (*component->Factory())(npath, is_live);
    	assert(ps);
    
    	DBG_LOG(DBG_PKTIO, "Created packet source of type %s for %s", component->Name().c_str(),
    	        npath.c_str());
    
    	Register(ps);
    	return ps;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    1. 构造PcapSource
    iosource::PktSrc* PcapSource::Instantiate(const std::string& path, bool is_live)
    {
    	return new PcapSource(path, is_live);
    }
    
    PcapSource::PcapSource(const std::string& path, bool is_live)
    {
    	props.path = path;
    	props.is_live = is_live;
    	pd = nullptr;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    open

    堆栈信息

    zeek::iosource::pcap::PcapSource::Open Source.cc:34
    zeek::iosource::PktSrc::InitSource PktSrc.cc:137
    zeek::iosource::Manager::Register Manager.cc:369
    zeek::iosource::Manager::Register Manager.cc:393
    zeek::iosource::Manager::OpenPktSrc Manager.cc:448
    zeek::run_state::detail::init_run RunState.cc:165
    zeek::detail::setup zeek-setup.cc:853
    main main.cc:13
    __libc_start_main 0x00007ffff5e62083
    _start 0x000055555619e1be
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    1. zeek::iosource::Manager::Register Manager.cc:393
    void Manager::Register(PktSrc* src)
    {
    	pkt_src = src;
    
    	// The poll interval gets defaulted to 100 which is good for cases like reading
    	// from pcap files and when there isn't a packet source, but is a little too
    	// infrequent for live sources (especially fast live sources). Set it down a
    	// little bit for those sources.
    	if ( src->IsLive() )
    		poll_interval = 10;
    	else if ( run_state::pseudo_realtime )
    		poll_interval = 1;
    
    	Register(src, false);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    1. zeek::iosource::Manager::Register Manager.cc:369

    void Manager::Register_(IOSource* src, bool dont_count, bool manage_lifetime)_

    void Manager::Register(IOSource* src, bool dont_count, bool manage_lifetime)
    {
    	// First see if we already have registered that source. If so, just
    	// adjust dont_count.
    	for ( const auto& iosrc : sources )
    		{
    		if ( iosrc->src == src )
    			{
    			if ( iosrc->dont_count != dont_count )
    				// Adjust the global counter.
    				dont_counts += (dont_count ? 1 : -1);
    
    			return;
    			}
    		}
    
    	src->InitSource();
    	Source* s = new Source;
    	s->src = src;
    	s->dont_count = dont_count;
    	s->manage_lifetime = manage_lifetime;
    	if ( dont_count )
    		++dont_counts;
    
    	sources.push_back(s);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    1. zeek::iosource::PktSrc::InitSource PktSrc.cc:137
    void PktSrc::InitSource()
    {
    	Open();
    }
    void PcapSource::Open()
    {
    	if ( props.is_live )
    		OpenLive();
    	else
    		OpenOffline();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    1. 打开网络接口
    void PcapSource::OpenLive()
    {
    	char errbuf[PCAP_ERRBUF_SIZE];
    
    	// Determine interface if not specified.
    	if ( props.path.empty() )
        {
    		pcap_if_t* devs;
    
    		if ( pcap_findalldevs(&devs, errbuf) < 0 )
            {
    			Error(util::fmt("pcap_findalldevs: %s", errbuf));
    			return;
            }
    
    		if ( devs )
            {
    			props.path = devs->name;
    			pcap_freealldevs(devs);
    
    			if ( props.path.empty() )
                {
    				Error("pcap_findalldevs: empty device name");
    				return;
                }
            }
    		else
            {
    			Error("pcap_findalldevs: no devices found");
    			return;
            }
        }
    
    	// Determine network and netmask.
    	uint32_t net;
    	if ( pcap_lookupnet(props.path.c_str(), &net, &props.netmask, errbuf) < 0 )
        {
    		// ### The lookup can fail if no address is assigned to
    		// the interface; and libpcap doesn't have any useful notion
    		// of error codes, just error std::strings - how bogus - so we
    		// just kludge around the error :-(.
    		// sprintf(errbuf, "pcap_lookupnet %s", errbuf);
    		// return;
    		props.netmask = 0xffffff00;
        }
    
    #ifdef PCAP_NETMASK_UNKNOWN
    	// Defined in libpcap >= 1.1.1
    	if ( props.netmask == PCAP_NETMASK_UNKNOWN )
    		props.netmask = PktSrc::NETMASK_UNKNOWN;
    #endif
    
    	pd = pcap_create(props.path.c_str(), errbuf);
    
    	if ( ! pd )
        {
    		PcapError("pcap_create");
    		return;
        }
    
    	if ( pcap_set_snaplen(pd, BifConst::Pcap::snaplen) )
        {
    		PcapError("pcap_set_snaplen");
    		return;
        }
    
    	if ( pcap_set_promisc(pd, 1) )
        {
    		PcapError("pcap_set_promisc");
    		return;
        }
    
    	// We use the smallest time-out possible to return almost immediately
    	// if no packets are available. (We can't use set_nonblocking() as
    	// it's broken on FreeBSD: even when select() indicates that we can
    	// read something, we may get nothing if the store buffer hasn't
    	// filled up yet.)
    	//
    	// TODO: The comment about FreeBSD is pretty old and may not apply
    	// anymore these days.
    	if ( pcap_set_timeout(pd, 1) )
        {
    		PcapError("pcap_set_timeout");
    		return;
        }
    
    	if ( pcap_set_buffer_size(pd, BifConst::Pcap::bufsize * 1024 * 1024) )
        {
    		PcapError("pcap_set_buffer_size");
    		return;
        }
    
    	if ( pcap_activate(pd) )
        {
    		PcapError("pcap_activate");
    		return;
        }
    
    #ifdef HAVE_LINUX
    	if ( pcap_setnonblock(pd, 1, errbuf) < 0 )
        {
    		PcapError("pcap_setnonblock");
    		return;
        }
    #endif
    
    #ifdef HAVE_PCAP_INT_H
    	Info(util::fmt("pcap bufsize = %d\n", ((struct pcap*)pd)->bufsize));
    #endif
    
    	props.selectable_fd = pcap_get_selectable_fd(pd);
    
    	props.link_type = pcap_datalink(pd);
    	props.is_live = true;
    
    	Opened(props);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    1. 打开pcap文件
    void PcapSource::OpenOffline()
    {
        char errbuf[PCAP_ERRBUF_SIZE];
    
        pd = pcap_open_offline(props.path.c_str(), errbuf);
    
        if (!pd)
        {
            Error(errbuf);
            return;
        }
    
        props.selectable_fd = fileno(pcap_file(pd));
    
        if (props.selectable_fd < 0)
            InternalError("OS does not support selectable pcap fd");
    
        props.link_type = pcap_datalink(pd);
        props.is_live = false;
    
        Opened(props);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    PcapDumper

    class PcapDumper : public PktDumper
    {
    public:
        PcapDumper(const std::string& path, bool append);
        ~PcapDumper() override;
    
        static PktDumper* Instantiate(const std::string& path, bool appen);
    
    protected:
        // PktDumper interface.
        void Open() override;
        void Close() override;
        bool Dump(const Packet* pkt) override;
    
    private:
        Properties props;
    
        bool append;
        pcap_dumper_t* dumper;
        pcap_t* pd;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    构造

    1. init_run
        if ( pcap_output_file ) //输出
        {
            const char* writefile = pcap_output_file->data();
            pkt_dumper = iosource_mgr->OpenPktDumper(writefile, false);
            assert(pkt_dumper);
    
            if ( ! pkt_dumper->IsOpen() )
                reporter->FatalError("problem opening dump file %s (%s)", writefile,
                                     pkt_dumper->ErrorMsg());
    
            if ( const auto& id = zeek::detail::global_scope()->Find("trace_output_file") )
                id->SetVal(make_intrusive<StringVal>(writefile));
            else
                reporter->Error("trace_output_file not defined");
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    1. OpenPktDumper
    PktDumper* Manager::OpenPktDumper(const std::string& path, bool append)
    {
        std::pair<std::string, std::string> t = split_prefix(path);
        std::string prefix = t.first;
        std::string npath = t.second;
    
        // Find the component providing packet dumpers of the requested prefix.
    
        PktDumperComponent* component = nullptr;
    
        std::list<PktDumperComponent*> all_components = plugin_mgr->Components<PktDumperComponent>();
        for (const auto& c : all_components)
        {
            if (c->HandlesPrefix(prefix))
            {
                component = c;
                break;
            }
        }
    
        if (!component)
            reporter->FatalError("type of packet dumper '%s' not recognized", prefix.c_str());
    
        // Instantiate packet dumper.
        //调用构造
        PktDumper* pd = (*component->Factory())(npath, append);
        assert(pd);
    
        if (!pd->IsOpen() && pd->IsError())
            // Set an error message if it didn't open successfully.
            pd->Error("could not open");
    
        DBG_LOG(DBG_PKTIO, "Created packer dumper of type %s for %s", component->Name().c_str(), npath.c_str());
    
        pd->Init();
        pkt_dumpers.push_back(pd);
    
        return pd;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    1. 构造
    iosource::PktDumper* PcapDumper::Instantiate(const std::string& path, bool append)
    {
    	return new PcapDumper(path, append);
    }
    
    • 1
    • 2
    • 3
    • 4

    Init

    1. Init
    void PktDumper::Init()
    {
        Open();
    }
    
    • 1
    • 2
    • 3
    • 4
    1. Open
    void PcapDumper::Open()
    {
        int linktype = -1;
    
        pd = pcap_open_dead(DLT_EN10MB, BifConst::Pcap::snaplen);
    
        if (!pd)
        {
            Error("error for pcap_open_dead");
            return;
        }
    
        if (props.path.empty())
        {
            Error("no filename given");
            return;
        }
    
        struct stat s;
        int exists = 0;
    
        if (append)
        {
            // See if output file already exists (and is non-empty).
            exists = stat(props.path.c_str(), &s);
    
            if (exists < 0 && errno != ENOENT)
            {
                Error(util::fmt("can't stat file %s: %s", props.path.c_str(), strerror(errno)));
                return;
            }
        }
    
        if (!append || exists < 0 || s.st_size == 0)
        {
            // Open new file.
            dumper = pcap_dump_open(pd, props.path.c_str());
            if (!dumper)
            {
                Error(pcap_geterr(pd));
                return;
            }
        }
    
        else
        {
    #ifdef HAVE_PCAP_DUMP_OPEN_APPEND
            dumper = pcap_dump_open_append(pd, props.path.c_str());
    #else
            // Old file and we need to append, which, unfortunately,
            // is not supported by libpcap. So, we have to hack a
            // little bit, knowing that pcap_dumper_t is, in fact,
            // a FILE ... :-(
            dumper = (pcap_dumper_t*)fopen(props.path.c_str(), "a");
    #endif
            if (!dumper)
            {
                Error(util::fmt("can't open dump %s: %s", props.path.c_str(), strerror(errno)));
                return;
            }
        }
    
        props.open_time = run_state::network_time;
        Opened(props);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    Analyzer

    ![image.png](https://img-blog.csdnimg.cn/img_convert/76495bce0676077e2119484ded85daa6.png#clientId=uce7ab961-f53a-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u1765d083&margin=[object Object]&name=image.png&originHeight=424&originWidth=999&originalType=url&ratio=1&rotation=0&showTitle=false&size=28441&status=done&style=none&taskId=u8a111149-90b9-4e89-bc7a-a948b823a04&title=)
    Zeek的动态分析框架是将分析器树与每个连接相关联。这棵树可以包含任意数量的分析器在各种群体,并且在连接的整个生命周期内都可以进行修改。并且zeek提供了两种关键的能力:

    • 独立于端口进行协议分析。通过一组与协议内容匹配的特征,zeek可以通过器payload找到正确的分析器。当特征匹配时会使用对应的分析器。
    • 当分析器解析错误的协议时,可以关闭分析器,并且我们可以使用多个分析器。

    所有分析器都派生自类Analyzer。我们将 分析器树与每个连接相关联,它反映了数据包分析期间的数据流,分析器根据哪些分析器执行其分析。每个数据包首先被传递到树的根节点,该根节点将其(可能转换的)输入传递给它的所有子节点。每个孩子依次将数据传递给其继任者。

    根节点必须始终是TransportLayerAnalyzer类型。例如TCPUDPICMP分析器。应用层分析器要么派生自TCP_ApplicationAnalyzer(对于TCP 协议),要么派生自通用Analyzer类(对于所有非TCP 协议)。

    当连接开始时,初始分析器树由全局analyzer::Manager实例化。初始树始终包含相应的TransportLayerAnalyzer。对于TCP和UDP,它还分别包含PIA_TCP或PIA_UDP类的实例。PIA 负责在连接进行时检测协议。最重要的是,它们执行签名匹配。根据是否使用任何已知端口,初始树可能立即包含也可能不包含任何应用层分析器。

    分析器可以支持两种输入方法之一(或两者):分组方式或流方式。分析器可以通过一种方法(例如,分组方式)接受输入,并通过另一种方法(例如,流方式)将其传递给它的孩子。例如TCP_Analyzer将数据包重新组合成字节流,因此所有TCP_ApplicationAnalyzer只能看到流式输入。

    Analyzer的接口

        // 初始化analyzer
        void Init()
    
        // 清楚analyer
        void Done()
    
        //分组输入接口
        // len  数据长度
        // data 指向数据的指针
        // orig 数据来自连接发起者为true
        // seq  数据相关的序号,如果没有则为-1
        // ip   如果有IP相关的数据包头,如果没有则为空
        // caplen ip的长度?
        void DeliverPacket(int len, const u_char* data, bool orig, uint64 seq, const IP_Hdr* ip, int caplen)
            
        // 流式输入的接口    
        // len 数据长度
        // data 指向数据的指针
        // orig 数据来自连接发起者为true
        void DeliverStream(int len, const u_char* data, bool orig)
            
        // 取消seq的报文
        void Undelivered(uint64 seq, int len, bool orig)
        // 返回分析器当前使用的内存字节数。
        unsigned int MemoryAllocation() const
        // 返回分析器类的新实例
        static Analyzer* InstantiateAnalyzer(Connection* conn)
        // 如果分析器完全禁用并且不考虑任何连接,则返回 false。(通常情况下,如果没有为分析器定义事件处理程序,就会出现这种情况。)
        static bool Available()
        // 给定的端点是否已经传输完成
        void EndpointEOF(bool is_orig)
        // 每当端点进入TCP_CLOSED或TCP_RESET时调用。
        void ConnectionFinished(int half_finished)
        // 连接重置时调用    
        void ConnectionReset()
        // 每当看到RST数据包时调用(有时调用 ConnectionReset会延迟)
        void PacketWithRST()
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    Analyzer如果构建?
    Analyzer如何调度,如何形成链式?

    Connection

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pPXGuU0z-1660489984252)(https://cdn.nlark.com/yuque/__puml/544ea3f957a363da4150f42434905c49.svg#lake_card_v2=eyJ0eXBlIjoicHVtbCIsImNvZGUiOiJAc3RhcnR1bWxcblxuY2xhc3MgT2JqIHtcblx0XG59XG5cblxuQGVuZHVtbCIsInVybCI6Imh0dHBzOi8vY2RuLm5sYXJrLmNvbS95dXF1ZS9fX3B1bWwvNTQ0ZWEzZjk1N2EzNjNkYTQxNTBmNDI0MzQ5MDVjNDkuc3ZnIiwiaWQiOiJRTTdFViIsIm1hcmdpbiI6eyJ0b3AiOnRydWUsImJvdHRvbSI6dHJ1ZX0sImNhcmQiOiJkaWFncmFtIn0=)]

    启动

    run_loop

    void run_loop()
    {
        util::detail::set_processing_status("RUNNING", "run_loop");
    
        iosource::Manager::ReadySources ready;
        ready.reserve(iosource_mgr->TotalSize());
    
        while (iosource_mgr->Size() || (BifConst::exit_only_after_terminate && !terminating))
        {
            time_updated = false;
            iosource_mgr->FindReadySources(&ready);
    
    #ifdef DEBUG
            static int loop_counter = 0;
    
            // If no source is ready, we log only every 100th cycle,
            // starting with the first.
            if (!ready.empty() || loop_counter++ % 100 == 0)
            {
                DBG_LOG(DBG_MAINLOOP, "realtime=%.6f ready_count=%zu", util::current_time(), ready.size());
    
                if (!ready.empty())
                    loop_counter = 0;
            }
    #endif
            current_iosrc = nullptr;
            auto communication_enabled = broker_mgr->Active();
    
            if (!ready.empty())
            {
                for (const auto& src : ready)
                {
                    auto* iosrc = src.src;
    
                    DBG_LOG(DBG_MAINLOOP, "processing source %s", iosrc->Tag());
                    current_iosrc = iosrc;
                    if (iosrc->ImplementsProcessFd() && src.fd != -1)
                        iosrc->ProcessFd(src.fd, src.flags);
                    else
                        iosrc->Process();
                }
            }
            else if ((have_pending_timers || communication_enabled || BifConst::exit_only_after_terminate) && !pseudo_realtime)
            {
                // Take advantage of the lull to get up to
                // date on timers and events.  Because we only
                // have timers as sources, going to sleep here
                // doesn't risk blocking on other inputs.
                update_network_time(util::current_time());
                expire_timers();
            }
    
            // Ensure that the time gets updated every pass if we're reading live.
            // This is necessary for e.g. packet sources that don't have a selectable
            // file descriptor. They'll always be ready on a very short timeout, but
            // won't necessarily have a packet to process. In these case, sometimes
            // the time won't get updated for a long time and timers don't function
            // correctly.
            if ((!time_updated && reading_live))
            {
                update_network_time(util::current_time());
                expire_timers();
            }
    
            event_mgr.Drain();
    
            processing_start_time = 0.0; // = "we're not processing now"
            current_dispatched = 0;
            current_iosrc = nullptr;
    
            if (::signal_val == SIGTERM || ::signal_val == SIGINT)
                // We received a signal while processing the
                // current packet and its related events.
                // Should we put the signal handling into an IOSource?
                zeek_terminate_loop("received termination signal");
    
            if (!reading_traces)
                // Check whether we have timers scheduled for
                // the future on which we need to wait.
                have_pending_timers = zeek::detail::timer_mgr->Size() > 0;
    
            if (pseudo_realtime && communication_enabled)
            {
                auto have_active_packet_source = false;
    
                iosource::PktSrc* ps = iosource_mgr->GetPktSrc();
                if (ps && ps->IsOpen())
                    have_active_packet_source = true;
    
                if (!have_active_packet_source)
                    // Can turn off pseudo realtime now
                    pseudo_realtime = 0.0;
            }
        }
    
        // Get the final statistics now, and not when finish_run() is
        // called, since that might happen quite a bit in the future
        // due to expiring pending timers, and we don't want to ding
        // for any packets dropped beyond this point.
        get_final_stats();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101

    Process

    void PktSrc::Process()
    {
        if (!IsOpen())
            return;
    
        if (!ExtractNextPacketInternal())
            return;
    
        run_state::detail::dispatch_packet(&current_packet, this);
    
        have_packet = false;
        DoneWithPacket();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    ExtractNextPacketInternal

    bool PktSrc::ExtractNextPacketInternal()
    {
        if (have_packet)
            return true;
    
        have_packet = false;
    
        // Don't return any packets if processing is suspended (except for the
        // very first packet which we need to set up times).
        if (run_state::is_processing_suspended() && run_state::detail::first_timestamp)
            return false;
    
        if (run_state::pseudo_realtime)
            run_state::detail::current_wallclock = util::current_time(true);
    
        if (ExtractNextPacket(&current_packet))
        {
            if (current_packet.time < 0)
            {
                Weird("negative_packet_timestamp", &current_packet);
                return false;
            }
    
            if (!run_state::detail::first_timestamp)
                run_state::detail::first_timestamp = current_packet.time;
    
            have_packet = true;
            return true;
        }
    
        if (run_state::pseudo_realtime && !IsOpen())
        {
            if (broker_mgr->Active())
                iosource_mgr->Terminate();
        }
    
        return false;
    }
    
    bool PcapSource::ExtractNextPacket(Packet* pkt)
    {
        if (!pd)
            return false;
    
        const u_char* data;
        pcap_pkthdr* header;
    
        int res = pcap_next_ex(pd, &header, &data);
    
        switch (res)
        {
        case PCAP_ERROR_BREAK: // -2
            // Exhausted pcap file, no more packets to read.
            assert(!props.is_live);
            Close();
            return false;
        case PCAP_ERROR: // -1
            // Error occurred while reading the packet.
            if (props.is_live)
                reporter->Error("failed to read a packet from %s: %s", props.path.data(), pcap_geterr(pd));
            else
                reporter->FatalError("failed to read a packet from %s: %s", props.path.data(), pcap_geterr(pd));
            return false;
        case 0:
            // Read from live interface timed out (ok).
            return false;
        case 1:
            // Read a packet without problem.
            // Although, some libpcaps may claim to have read a packet, but either did
            // not really read a packet or at least provide no way to access its
            // contents, so the following check for null-data helps handle those cases.
            if (!data)
            {
                reporter->Weird("pcap_null_data_packet");
                return false;
            }
            break;
        default:
            reporter->InternalError("unhandled pcap_next_ex return value: %d", res);
            return false;
        }
    
        pkt->Init(props.link_type, &header->ts, header->caplen, header->len, data);
    
        if (header->len == 0 || header->caplen == 0)
        {
            Weird("empty_pcap_header", pkt);
            return false;
        }
    
        ++stats.received;
        stats.bytes_received += header->len;
    
        // Some versions of libpcap (myricom) are somewhat broken and will return a duplicate
        // packet if there are no more packets available. Namely, it returns the exact same
        // packet structure (including the header) out of the library without reinitializing
        // any of the values. If we set the header lengths to zero here, we can keep from
        // processing it a second time.
        header->len = 0;
        header->caplen = 0;
    
        return true;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103

    dispatch_packet

    void dispatch_packet(Packet* pkt, iosource::PktSrc* pkt_src)
    {
        double t = run_state::pseudo_realtime ? check_pseudo_time(pkt) : pkt->time;
    
        if (!zeek_start_network_time)
        {
            zeek_start_network_time = t;
    
            if (network_time_init)
                event_mgr.Enqueue(network_time_init, Args{});
        }
    
        current_iosrc = pkt_src;
    #pragma GCC diagnostic push
    #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
        current_pktsrc = pkt_src;
    #pragma GCC diagnostic pop
    
        // network_time never goes back.
        update_network_time(zeek::detail::timer_mgr->Time() < t ? t : zeek::detail::timer_mgr->Time());
        processing_start_time = t;
        expire_timers();
    
        zeek::detail::SegmentProfiler* sp = nullptr;
    
        if (load_sample)
        {
            static uint32_t load_freq = 0;
    
            if (load_freq == 0)
                load_freq = uint32_t(0xffffffff) / uint32_t(zeek::detail::load_sample_freq);
    
            if (uint32_t(util::detail::random_number() & 0xffffffff) < load_freq)
            {
                // Drain the queued timer events so they're not
                // charged against this sample.
                event_mgr.Drain();
    
                zeek::detail::sample_logger = new zeek::detail::SampleLogger();
                sp = new zeek::detail::SegmentProfiler(zeek::detail::sample_logger, "load-samp");
            }
        }
        //处理包
        packet_mgr->ProcessPacket(pkt);
        event_mgr.Drain();
    
        if (sp)
        {
            delete sp;
            delete zeek::detail::sample_logger;
            zeek::detail::sample_logger = nullptr;
        }
    
        processing_start_time = 0.0; // = "we're not processing now"
        current_dispatched = 0;
    
        if (pseudo_realtime && !first_wallclock)
            first_wallclock = util::current_time(true);
    
        current_iosrc = nullptr;
    #pragma GCC diagnostic push
    #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
        current_pktsrc = nullptr;
    #pragma GCC diagnostic pop
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    process_packet

    void Manager::ProcessPacket(Packet* packet)
    {
    #ifdef DEBUG
        static size_t counter = 0;
        DBG_LOG(DBG_PACKET_ANALYSIS, "Analyzing packet %ld, ts=%.3f...", ++counter, packet->time);
    #endif
    
        zeek::detail::SegmentProfiler prof(detail::segment_logger, "dispatching-packet");
        if (pkt_profiler)
            pkt_profiler->ProfilePkt(zeek::run_state::processing_start_time, packet->cap_len);
    
        ++num_packets_processed;
    
        bool dumped_packet = false;
        if (packet->dump_packet || zeek::detail::record_all_packets)
        {
            DumpPacket(packet, packet->dump_size);
            dumped_packet = true;
        }
    
        // Start packet analysis
        root_analyzer->ForwardPacket(packet->cap_len, packet->data, packet, packet->link_type);
    
        if (!packet->processed)
        {
            if (packet_not_processed)
                event_mgr.Enqueue(packet_not_processed, Packet::ToVal(packet));
    
            plugin_mgr->HookUnprocessedPacket(packet);
    
            if (unprocessed_dumper)
                unprocessed_dumper->Dump(packet);
    
            total_not_processed++;
        }
    
        if (raw_packet)
            event_mgr.Enqueue(raw_packet, packet->ToRawPktHdrVal());
    
        // Check whether packet should be recorded based on session analysis
        if (packet->dump_packet && !dumped_packet)
            DumpPacket(packet, packet->dump_size);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    ForwardPacket

    
    bool Analyzer::ForwardPacket(size_t len, const uint8_t* data, Packet* packet) const
    {
        AnalyzerPtr inner_analyzer = nullptr;
    
        for (const auto& child : analyzers_to_detect)
        {
            if (child->DetectProtocol(len, data, packet))
            {
                DBG_LOG(DBG_PACKET_ANALYSIS, "Protocol detection in %s succeeded, next layer analyzer is %s", GetAnalyzerName(),
                        child->GetAnalyzerName());
                inner_analyzer = child;
                break;
            }
        }
    
        if (!inner_analyzer)
            inner_analyzer = default_analyzer;
    
        if (!inner_analyzer)
        {
            DBG_LOG(DBG_PACKET_ANALYSIS, "Analysis in %s stopped, no default analyzer available.", GetAnalyzerName());
    
            if (report_unknown_protocols)
                Weird("no_suitable_analyzer_found", packet);
    
            return false;
        }
    
        return inner_analyzer->AnalyzePacket(len, data, packet);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    EthernetAnalyzer::AnalyzePacket

    bool EthernetAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
    {
        // Make sure that we actually got an entire ethernet header before trying
        // to pull bytes out of it.
        if (16 >= len)
        {
            Weird("truncated_ethernet_frame", packet);
            return false;
        }
    
        // Skip past Cisco FabricPath to encapsulated ethernet frame.
        if (data[12] == 0x89 && data[13] == 0x03)
        {
            auto constexpr cfplen = 16;
    
            if (cfplen + 14 >= len)
            {
                Weird("truncated_link_header_cfp", packet);
                return false;
            }
    
            data += cfplen;
            len -= cfplen;
        }
    
        // Get protocol being carried from the ethernet frame.
        uint32_t protocol = (data[12] << 8) + data[13];
    
        packet->eth_type = protocol;
        packet->l2_dst = data;
        packet->l2_src = data + 6;
    
        // Ethernet II frames
        if (protocol >= 1536)
            return ForwardPacket(len - 14, data + 14, packet, protocol);
    
        // Other ethernet frame types
        if (protocol <= 1500)
        {
            if (16 >= len)
            {
                Weird("truncated_ethernet_frame", packet);
                return false;
            }
    
            // Let specialized analyzers take over for non Ethernet II frames.
            // Note that pdata remains at the start of the ethernet frame.
    
            AnalyzerPtr eth_analyzer = nullptr;
    
            if (data[14] == 0xAA && data[15] == 0xAA)
                // IEEE 802.2 SNAP
                eth_analyzer = SNAPAnalyzer;
            else if (data[14] == 0xFF && data[15] == 0xFF)
                // Novell raw IEEE 802.3
                eth_analyzer = NovellRawAnalyzer;
            else
                // IEEE 802.2 LLC
                eth_analyzer = LLCAnalyzer;
    
            if (eth_analyzer)
                return eth_analyzer->AnalyzePacket(len, data, packet);
    
            return true;
        }
    
        // Undefined (1500 < EtherType < 1536)
        Weird("undefined_ether_type", packet);
        return false;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71

    IPAnalyzer::AnalyzePacket

    bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
    {
        // Check to make sure we have enough data left for an IP header to be here. Note we only
        // check ipv4 here. We'll check ipv6 later once we determine we have an ipv6 header.
        if (len < sizeof(struct ip))
        {
            Weird("truncated_IP", packet);
            return false;
        }
    
        int32_t hdr_size = static_cast<int32_t>(data - packet->data);
    
        // Cast the current data pointer to an IP header pointer so we can use it to get some
        // data about the header.
        auto ip = (const struct ip*)data;
        uint32_t protocol = ip->ip_v;
    
        // This is a unique pointer because of the mass of early returns from this method.
        if (protocol == 4)
        {
            packet->ip_hdr = std::make_shared<IP_Hdr>(ip, false);
            packet->l3_proto = L3_IPV4;
        }
        else if (protocol == 6)
        {
            if (len < sizeof(struct ip6_hdr))
            {
                Weird("truncated_IP", packet);
                return false;
            }
    
            packet->ip_hdr = std::make_shared<IP_Hdr>((const struct ip6_hdr*)data, false, len);
            packet->l3_proto = L3_IPV6;
        }
        else
        {
            Weird("unknown_ip_version", packet);
            return false;
        }
    
        // If there's an encapsulation stack in this packet, meaning this packet is part of a chain
        // of tunnels, make sure to store the IP header in the last flow in the stack so it can be
        // used by previous analyzers as we return up the chain.
        if (packet->encap)
        {
            if (auto* ec = packet->encap->Last())
                ec->ip_hdr = packet->ip_hdr;
        }
    
        const struct ip* ip4 = packet->ip_hdr->IP4_Hdr();
    
        // TotalLen() returns the full length of the IP portion of the packet, including
        // the IP header and payload.
        uint32_t total_len = packet->ip_hdr->TotalLen();
        if (total_len == 0)
        {
            // TCP segmentation offloading can zero out the ip_len field.
            Weird("ip_hdr_len_zero", packet);
    
            if (detail::ignore_checksums)
                // Cope with the zero'd out ip_len field by using the caplen.
                total_len = packet->cap_len - hdr_size;
            else
                // If this is caused by segmentation offloading, the checksum will
                // also be incorrect. If checksum validation is enabled - jus tbail here.
                return false;
        }
    
        if (packet->len < total_len + hdr_size)
        {
            Weird("truncated_IPv6", packet);
            return false;
        }
    
        // For both of these it is safe to pass ip_hdr because the presence
        // is guaranteed for the functions that pass data to us.
        uint16_t ip_hdr_len = packet->ip_hdr->HdrLen();
        if (ip_hdr_len > total_len)
        {
            Weird("invalid_IP_header_size", packet);
            return false;
        }
    
        if (ip_hdr_len > len)
        {
            Weird("internally_truncated_header", packet);
            return false;
        }
    
        if (packet->ip_hdr->IP4_Hdr())
        {
            if (ip_hdr_len < sizeof(struct ip))
            {
                Weird("IPv4_min_header_size", packet);
                return false;
            }
        }
        else
        {
            if (ip_hdr_len < sizeof(struct ip6_hdr))
            {
                Weird("IPv6_min_header_size", packet);
                return false;
            }
        }
    
        // Ignore if packet matches packet filter.
        detail::PacketFilter* packet_filter = packet_mgr->GetPacketFilter(false);
        if (packet_filter && packet_filter->Match(packet->ip_hdr, total_len, len))
            return false;
    
        if (!packet->l2_checksummed && !detail::ignore_checksums && ip4
            && !IPBasedAnalyzer::GetIgnoreChecksumsNets()->Contains(packet->ip_hdr->IPHeaderSrcAddr())
            && detail::in_cksum(reinterpret_cast<const uint8_t*>(ip4), ip_hdr_len) != 0xffff)
        {
            Weird("bad_IP_checksum", packet);
            return false;
        }
    
        if (discarder && discarder->NextPacket(packet->ip_hdr, total_len, len))
            return false;
    
        detail::FragReassembler* f = nullptr;
    
        if (packet->ip_hdr->IsFragment())
        {
            packet->dump_packet = true; // always record fragments
    
            if (len < total_len)
            {
                Weird("incompletely_captured_fragment", packet);
    
                // Don't try to reassemble, that's doomed.
                // Discard all except the first fragment (which
                // is useful in analyzing header-only traces)
                if (packet->ip_hdr->FragOffset() != 0)
                    return false;
            }
            else
            {
                f = detail::fragment_mgr->NextFragment(run_state::processing_start_time, packet->ip_hdr, packet->data + hdr_size);
                std::shared_ptr<IP_Hdr> ih = f->ReassembledPkt();
    
                if (!ih)
                    // It didn't reassemble into anything yet.
                    return true;
    
                ip4 = ih->IP4_Hdr();
    
                // Switch the stored ip header over to the one from the
                // fragmented packet.
                packet->ip_hdr = std::move(ih);
    
                len = total_len = packet->ip_hdr->TotalLen();
                ip_hdr_len = packet->ip_hdr->HdrLen();
                packet->cap_len = total_len + hdr_size;
    
                if (ip_hdr_len > total_len)
                {
                    Weird("invalid_IP_header_size", packet);
                    return false;
                }
            }
        }
    
        detail::FragReassemblerTracker frt(f);
    
        // We stop building the chain when seeing IPPROTO_ESP so if it's
        // there, it's always the last.
        if (packet->ip_hdr->LastHeader() == IPPROTO_ESP)
        {
            packet->dump_packet = true;
            if (esp_packet)
                event_mgr.Enqueue(esp_packet, packet->ip_hdr->ToPktHdrVal());
    
            // Can't do more since upper-layer payloads are going to be encrypted.
            return true;
        }
    
        // We stop building the chain when seeing IPPROTO_MOBILITY so it's always
        // last if present.
        if (packet->ip_hdr->LastHeader() == IPPROTO_MOBILITY)
        {
            packet->dump_packet = true;
    
            if (!detail::ignore_checksums && mobility_header_checksum(packet->ip_hdr.get()) != 0xffff)
            {
                Weird("bad_MH_checksum", packet);
                return false;
            }
    
            if (mobile_ipv6_message)
                event_mgr.Enqueue(mobile_ipv6_message, packet->ip_hdr->ToPktHdrVal());
    
            if (packet->ip_hdr->NextProto() != IPPROTO_NONE)
                Weird("mobility_piggyback", packet);
    
            return true;
        }
    
        // Set the data pointer to match the payload from the IP header. This makes sure that it's also
        // pointing at the reassembled data for a fragmented packet.
        data = packet->ip_hdr->Payload();
        len -= ip_hdr_len;
    
        // Session analysis assumes that the header size stored in the packet does not include the IP
        // header size. There are two reasons for this: 1) Packet::ToRawPktHdrVal() wants to look at the
        // IP header for reporting, and 2) The VXLAN analyzer uses the header position to create the
        // next packet in the tunnel chain. Once the TCP/UDP work is done and the VXLAN analyzer can
        // move into packet analysis, this can change, but for now we leave it as it is.
    
        bool return_val = true;
        int proto = packet->ip_hdr->NextProto();
    
        packet->proto = proto;
    
        // Double check the lengths one more time before forwarding this on.
        if (total_len < packet->ip_hdr->HdrLen())
        {
            Weird("bogus_IP_header_lengths", packet);
            return false;
        }
    
        switch (proto)
        {
        case IPPROTO_NONE:
            // If the packet is encapsulated in Teredo, then it was a bubble and
            // the Teredo analyzer may have raised an event for that, else we're
            // not sure the reason for the No Next header in the packet.
            if (!(packet->encap && packet->encap->LastType() == BifEnum::Tunnel::TEREDO))
            {
                Weird("ipv6_no_next", packet);
                return_val = false;
            }
            break;
        default:
            packet->proto = proto;
    
            // For everything else, pass it on to another analyzer. If there's no one to handle
            // that, it'll report a Weird.
            return_val = ForwardPacket(len, data, packet, proto);
            break;
        }
    
        if (f)
            f->DeleteTimer();
    
        return return_val;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249

    IPBasedAnalyzer::AnalyzePacket

    bool IPBasedAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* pkt)
    {
        ConnTuple tuple;
        if (!BuildConnTuple(len, data, pkt, tuple))
            return false;
    
        const std::shared_ptr<IP_Hdr>& ip_hdr = pkt->ip_hdr;
        detail::ConnKey key(tuple);
    
        Connection* conn = session_mgr->FindConnection(key);
    
        if (!conn)
        {
            conn = NewConn(&tuple, key, pkt);
            if (conn)
                session_mgr->Insert(conn, false);
        }
        else
        {
            if (conn->IsReuse(run_state::processing_start_time, ip_hdr->Payload()))
            {
                conn->Event(connection_reused, nullptr);
    
                session_mgr->Remove(conn);
                conn = NewConn(&tuple, key, pkt);
                if (conn)
                    session_mgr->Insert(conn, false);
            }
            else
            {
                conn->CheckEncapsulation(pkt->encap);
            }
        }
    
        if (!conn)
            return false;
    
        // If we successfuly made a connection for this packet that means it'll eventually
        // get logged, which means we can mark this packet as having been processed.
        pkt->processed = true;
    
        bool is_orig = (tuple.src_addr == conn->OrigAddr()) && (tuple.src_port == conn->OrigPort());
        pkt->is_orig = is_orig;
    
        conn->CheckFlowLabel(is_orig, ip_hdr->FlowLabel());
    
        zeek::ValPtr pkt_hdr_val;
    
        if (ipv6_ext_headers && ip_hdr->NumHeaders() > 1)
        {
            pkt_hdr_val = ip_hdr->ToPktHdrVal();
            conn->EnqueueEvent(ipv6_ext_headers, nullptr, conn->GetVal(), pkt_hdr_val);
        }
    
        if (new_packet)
            conn->EnqueueEvent(new_packet, nullptr, conn->GetVal(), pkt_hdr_val ? std::move(pkt_hdr_val) : ip_hdr->ToPktHdrVal());
    
        conn->SetRecordPackets(true);
        conn->SetRecordContents(true);
    
        const u_char* payload = pkt->ip_hdr->Payload();
    
        run_state::current_timestamp = run_state::processing_start_time;
        run_state::current_pkt = pkt;
    
        // TODO: Does this actually mean anything?
        if (conn->GetSessionAdapter()->Skipping())
            return true;
    
        DeliverPacket(conn, run_state::processing_start_time, is_orig, len, pkt);
    
        run_state::current_timestamp = 0;
        run_state::current_pkt = nullptr;
    
        // If the packet is reassembled, disable packet dumping because the
        // pointer math to dump the data wouldn't work.
        if (pkt->ip_hdr->Reassembled())
            pkt->dump_packet = false;
        else if (conn->RecordPackets())
        {
            pkt->dump_packet = true;
    
            // If we don't want the content, set the dump size to include just
            // the header.
            if (!conn->RecordContents())
                pkt->dump_size = payload - pkt->data;
        }
    
        return true;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90

    IPBasedAnalyzer::NewConn

    zeek::Connection* IPBasedAnalyzer::NewConn(const ConnTuple* id, const detail::ConnKey& key, const Packet* pkt)
    {
        int src_h = ntohs(id->src_port);
        int dst_h = ntohs(id->dst_port);
        bool flip = false;
    
        if (!WantConnection(src_h, dst_h, pkt->ip_hdr->Payload(), flip))
            return nullptr;
    
        Connection* conn = new Connection(key, run_state::processing_start_time, id, pkt->ip_hdr->FlowLabel(), pkt);
        conn->SetTransport(transport);
    
        if (flip)
            conn->FlipRoles();
    
        BuildSessionAnalyzerTree(conn);
    
        if (new_connection)
            conn->Event(new_connection, nullptr);
    
        return conn;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    IPBasedAnalyzer::BuildSessionAnalyzerTree

    void IPBasedAnalyzer::BuildSessionAnalyzerTree(Connection* conn)
    {
        SessionAdapter* root = MakeSessionAdapter(conn);
        analyzer::pia::PIA* pia = MakePIA(conn);
    
        bool scheduled = analyzer_mgr->ApplyScheduledAnalyzers(conn, false, root);
    
        // Hmm... Do we want *just* the expected analyzer, or all
        // other potential analyzers as well?  For now we only take
        // the scheduled ones.
        if (!scheduled)
        { // Let's see if it's a port we know.
            if (!analyzers_by_port.empty() && !zeek::detail::dpd_ignore_ports)
            {
                int resp_port = ntohs(conn->RespPort());
                std::set<zeek::Tag>* ports = LookupPort(resp_port, false);
    
                if (ports)
                {
                    for (const auto& port : *ports)
                    {
                        analyzer::Analyzer* analyzer = analyzer_mgr->InstantiateAnalyzer(port, conn);
    
                        if (!analyzer)
                            continue;
    
                        root->AddChildAnalyzer(analyzer, false);
                        DBG_ANALYZER_ARGS(conn, "activated %s analyzer due to port %d", analyzer_mgr->GetComponentName(port).c_str(),
                                          resp_port);
                    }
                }
            }
        }
    
        root->AddExtraAnalyzers(conn);
    
        if (pia)
            root->AddChildAnalyzer(pia->AsAnalyzer());
    
        conn->SetSessionAdapter(root, pia);
        root->Init();
        root->InitChildren();
    
        PLUGIN_HOOK_VOID(HOOK_SETUP_ANALYZER_TREE, HookSetupAnalyzerTree(conn));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    Manager::InstantiateAnalyzer

    Analyzer* Manager::InstantiateAnalyzer(const char* name, Connection* conn)
    {
        zeek::Tag tag = GetComponentTag(name);
        return tag ? InstantiateAnalyzer(tag, conn) : nullptr;
    }
    
    Analyzer* Manager::InstantiateAnalyzer(const zeek::Tag& tag, Connection* conn)
    {
        Component* c = Lookup(tag);
    
        if (!c)
        {
            reporter->InternalWarning("request to instantiate unknown analyzer");
            return nullptr;
        }
    
        if (!c->Enabled())
            return nullptr;
    
        if (!c->Factory())
        {
            reporter->InternalWarning("analyzer %s cannot be instantiated dynamically", GetComponentName(tag).c_str());
            return nullptr;
        }
    
        Analyzer* a = c->Factory()(conn);
    
        if (!a)
        {
            reporter->InternalWarning("analyzer instantiation failed");
            return nullptr;
        }
    
        a->SetAnalyzerTag(tag);
    
        return a;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    HTTP

    zeek::analyzer::http::HTTP_Analyzer::HTTP_Analyzer HTTP.cc:816
    zeek::analyzer::http::HTTP_Analyzer::Instantiate HTTP.h:216
    zeek::analyzer::Manager::InstantiateAnalyzer Manager.cc:315
    zeek::packet_analysis::IP::IPBasedAnalyzer::BuildSessionAnalyzerTree IPBasedAnalyzer.cc:206
    zeek::packet_analysis::IP::IPBasedAnalyzer::NewConn IPBasedAnalyzer.cc:177
    zeek::packet_analysis::IP::IPBasedAnalyzer::AnalyzePacket IPBasedAnalyzer.cc:42
    zeek::packet_analysis::Analyzer::ForwardPacket Analyzer.cc:113
    zeek::packet_analysis::IP::IPAnalyzer::AnalyzePacket IP.cc:276
    zeek::packet_analysis::Analyzer::ForwardPacket Analyzer.cc:113
    zeek::packet_analysis::Ethernet::EthernetAnalyzer::AnalyzePacket Ethernet.cc:54
    zeek::packet_analysis::Analyzer::ForwardPacket Analyzer.cc:113
    zeek::packet_analysis::Manager::ProcessPacket Manager.cc:112
    zeek::run_state::detail::dispatch_packet RunState.cc:259
    zeek::iosource::PktSrc::Process PktSrc.cc:154
    zeek::run_state::detail::run_loop RunState.cc:322
    main main.cc:59
    __libc_start_main 0x00007ffff5e62083
    _start 0x000055555619e1be
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    done

    zeek::analyzer::http::HTTP_Analyzer::Done HTTP.cc:848
    zeek::analyzer::Analyzer::Done Analyzer.cc:198
    zeek::packet_analysis::TCP::TCPSessionAdapter::Done TCPSessionAdapter.cc:66
    zeek::Connection::Done Conn.cc:143
    zeek::session::Manager::Remove Manager.cc:128
    zeek::packet_analysis::IP::IPBasedAnalyzer::AnalyzePacket IPBasedAnalyzer.cc:52
    zeek::packet_analysis::Analyzer::ForwardPacket Analyzer.cc:113
    zeek::packet_analysis::IP::IPAnalyzer::AnalyzePacket IP.cc:276
    zeek::packet_analysis::Analyzer::ForwardPacket Analyzer.cc:113
    zeek::packet_analysis::Ethernet::EthernetAnalyzer::AnalyzePacket Ethernet.cc:54
    zeek::packet_analysis::Analyzer::ForwardPacket Analyzer.cc:113
    zeek::packet_analysis::Manager::ProcessPacket Manager.cc:112
    zeek::run_state::detail::dispatch_packet RunState.cc:259
    zeek::iosource::PktSrc::Process PktSrc.cc:154
    zeek::run_state::detail::run_loop RunState.cc:322
    main main.cc:59
    __libc_start_main 0x00007ffff5e62083
    _start 0x000055555619e1be
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    undeliverd

    [zeek] zeek::analyzer::http::HTTP_Analyzer::Undelivered HTTP.cc:1059
    [zeek] zeek::analyzer::SupportAnalyzer::ForwardUndelivered Analyzer.cc:913
    [zeek] zeek::analyzer::tcp::ContentLine_Analyzer::Undelivered ContentLine.cc:117
    [zeek] zeek::analyzer::Analyzer::NextUndelivered Analyzer.cc:272
    [zeek] zeek::analyzer::Analyzer::NextUndelivered Analyzer.cc:266
    [zeek] zeek::analyzer::Analyzer::ForwardUndelivered Analyzer.cc:355
    [zeek] zeek::analyzer::tcp::TCP_Reassembler::Gap TCP_Reassembler.cc:153
    [zeek] zeek::analyzer::tcp::TCP_Reassembler::Undelivered TCP_Reassembler.cc:250
    [zeek] zeek::DataBlockList::Trim Reassem.cc:219
    [zeek] zeek::Reassembler::TrimToSeq Reassem.cc:354
    [zeek] zeek::analyzer::tcp::TCP_Reassembler::AckReceived TCP_Reassembler.cc:527
    [zeek] zeek::analyzer::tcp::TCP_Endpoint::AckReceived TCP_Endpoint.cc:243
    [zeek] zeek::packet_analysis::TCP::TCPSessionAdapter::Process TCPSessionAdapter.cc:668
    [zeek] zeek::packet_analysis::TCP::TCPAnalyzer::DeliverPacket TCP.cc:121
    [zeek] zeek::packet_analysis::IP::IPBasedAnalyzer::AnalyzePacket IPBasedAnalyzer.cc:99
    [zeek] zeek::packet_analysis::Analyzer::ForwardPacket Analyzer.cc:113
    [zeek] zeek::packet_analysis::IP::IPAnalyzer::AnalyzePacket IP.cc:276
    [zeek] zeek::packet_analysis::Analyzer::ForwardPacket Analyzer.cc:113
    [zeek] zeek::packet_analysis::Ethernet::EthernetAnalyzer::AnalyzePacket Ethernet.cc:54
    [zeek] zeek::packet_analysis::Analyzer::ForwardPacket Analyzer.cc:113
    [zeek] zeek::packet_analysis::Manager::ProcessPacket Manager.cc:112
    [zeek] zeek::run_state::detail::dispatch_packet RunState.cc:259
    [zeek] zeek::iosource::PktSrc::Process PktSrc.cc:154
    [zeek] zeek::run_state::detail::run_loop RunState.cc:321
    [zeek] main main.cc:59
    [libc.so.6] __libc_start_main 0x00007ffff5a1b083
    [zeek] _start 0x00005555561bc07e
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    RegisterComponet

    [zeek] zeek::plugin::ComponentManager<zeek::packet_analysis::Component>::RegisterComponent ComponentManager.h:244
    [zeek] zeek::packet_analysis::Component::Initialize Component.cc:21
    [zeek] zeek::plugin::Plugin::InitializeComponents Plugin.cc:450
    [zeek] zeek::plugin::Manager::InitPreScript Manager.cc:472
    [zeek] zeek::detail::setup zeek-setup.cc:699
    [zeek] main main.cc:13
    [libc.so.6] __libc_start_main 0x00007ffff5a1c083
    [zeek] _start 0x00005555561bc07e
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    推荐一个零声学院免费公开课程,个人觉得老师讲得不错,分享给大家:[Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,点击立即学习]

  • 相关阅读:
    第四章. Pandas进阶—时间序列
    深度学习微调
    【面试八股】IP协议八股
    支持向量机 (SVM):初学者指南
    洛谷P2196 [NOIP1996 提高组] 挖地雷【动态规划思路分析】看完直接举一反三!
    基于Matlab2012a的LineStretcher测线编号程序开发
    多线程总结(线程池 & 线程安全 & 常见锁)
    ARM mkv210_image.c 文件详解
    Mysql5.7深入学习 2.MySQL 8.0 中的新增功能
    P3~P6函数模板
  • 原文地址:https://blog.csdn.net/hzb869168467/article/details/126338120