LINUX.ORG.RU
ФорумAdmin

Как получить unixtime в виде числа в lua скрипте для wireshark?

 ,


0

1

Доброго времени суток

Сабж. Мне нужно из дампа выбрать кто куда обращался и сколько времени продолжалось соединение. Проблема в формате хранения времени в wireshark.

type ( timestamp ) говорит, что это userdata. В строку преобразуется через tostring ( timestamp ), но вот как бы получить обычный человеческий unixtime в виде числа?

З.Ы. всё это мне нужно для анализа производительности сложного комплекса ПО.

proof of concept, выдаёт информацию о соединениях: адреса и порты, количество пакетов, время первого и последнего пакета

do
    -- какие поля будем брать из пакетов
    -- frame
    local frame_time = Field.new("frame.time")
    local frame_number = Field.new("frame.number")
    -- tcp
    local tcp_dstport = Field.new("tcp.dstport")
    local tcp_srcport = Field.new("tcp.srcport")
    local tcp_stream = Field.new("tcp.stream")
    -- ipv4
    local ip_dst = Field.new("ip.dst")
    local ip_src = Field.new("ip.src")

    local library = { }
    local function init_listener()
        local tap = Listener.new("tcp")
        function tap.reset()
            print("tap reset")
        end
        -- вызывается для каждого пакета
        function tap.packet(pinfo,tvb)
            -- print("tap.packet")
            local ipsrc = ip_src()
            local ipdst = ip_dst()
            local tcpstream = tcp_stream()
            local tcpsrcport = tcp_srcport()
            local tcpdstport = tcp_dstport()
            local frametime = frame_time()

            local stream = tostring(tcpstream)
            -- уже знаем об этом соединении?
            -- да
            if library[stream] then
                library[stream].endtime = tostring( frametime )
                library[stream].packets = library[stream].packets + 1
            -- нет, это первый пакет нового соединения
            else
                library[stream] = {
                    -- starttime = type ( frametime ),
                    starttime = tostring ( frametime ),
                    endtime = tostring ( frametime ),
                    packets = '1',
                    info = tostring(ipsrc) .. ':' .. tostring(tcpsrcport) .. " -> " .. tostring(ipdst) .. ':' .. tostring(tcpdstport)
                }
            end
        end
        -- вызывается после обработки всех пакетов
        function tap.draw()
            -- print("tap.draw")
            for key, val in pairs(library) do
                io.write( string.format("%10i: %s ( %s, %s, %s )\n", key, val.info, val.packets, val.starttime, val.endtime ) )
            end
        end
    end
    init_listener()
end

запускать с любым дампом так:

tshark -r dump.raw -X lua_script:script.lua -q

★★★★★

Последнее исправление: router (всего исправлений: 1)
Ответ на: комментарий от annulen

К сожалению, не работает. Насколько я понимаю, проблема в том что это userdata, и функции для приведения типов есть только для строки. http://wiki.wireshark.org/LuaAPI/Utils#format_date.28timestamp.29

Как расковырять userdata для его изучения я пока тоже не знаю, слишком мало опыта в lua

tshark: Lua: Error During execution of Listener Packet Callback:
[string "test.lua"]:51: bad argument #5 to 'format' (string expected, got nil)

** (process:29627): WARNING **: Runtime error while calling a listener's draw(): (null)
router ★★★★★
() автор топика
Ответ на: комментарий от arturpub

Почему, заполнен. Вывод через io.write - лучшее доказательство

Добавил в заколовок команду, которой нужно запускать tshark с дампом и скриптом

router ★★★★★
() автор топика
Последнее исправление: router (всего исправлений: 1)
Ответ на: комментарий от router

Как расковырять userdata для его изучения я пока тоже не знаю

Только со стороны С

annulen ★★★★★
()

Ладно, c lua достаточно того, что он выдаст мне данные из wireshark. Дальше буду обрабатывать на perl.

#!/usr/bin/perl

use strict;

use DateTime::Format::Strptime;
while ( $_ = <> ) {
    if ( m/^\s*(\S+):\s*(\S+):(\S+)\s*\-\>\s*(\S+):(\S+)\s*\(\s*(\d+),\s"([^\"]+)",\s*"([^\"]+)"\s*\)/ ) {
        my ( $stream_id, $src_ip, $src_port, $dst_ip, $dst_port, $pkt_cnt, $start_time_str, $end_time_str ) = ( $1, $2, $3, $4, $5, $6, $7, $8 );
        # преобразуем из строки wireshark в DateTime
        my $strp = DateTime::Format::Strptime->new(
            pattern => '%b %e, %Y %H:%M:%S.%N %Z',
            time_zone => 'local',
        );

        # преобразуем из DateTime в unixtime
        my $ut_strp = DateTime::Format::Strptime->new(
            pattern => '%s',
            time_zone => 'local',
        );

        my $start_time = $ut_strp->format_datetime( $strp->parse_datetime($start_time_str) );
        my $end_time = $ut_strp->format_datetime( $strp->parse_datetime($end_time_str) );

        # результат
        printf "%s:%s -> %s:%s ( %i )\n",
            $src_ip, $src_port,
            $dst_ip, $dst_port,
            $end_time - $start_time ;
    }
}

Да, код в заголовке топика - лишь PoC, дальше будет сильно дорабатываться. В частности, добавлять в library только тогда, когда исследуемый пакет действительно открывает соединение ( SYN, not ACK ). Сейчас для сессий, начатых до сбора дампа, перепутаны местами source и destination.

Потом будет ещё обработка и построение графиков, но к сабжу уже никак не относится

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

Как вариант, сделай фичреквест в Wireshark, чтобы дали tonumber

annulen ★★★★★
()
29 октября 2014 г.

поздний ответ

local frameepochtime = tonumber(tostring(frame_epochtime()))

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.