2017-10-11 243 views
0

我正在寫分析器,它分析一個pcapng文件(一個wire shark pcap下一代文件)。雖然有解決方案,但我找不到NPM生態系統中存在的解決方案。所以我決定旋轉我自己的。目前爲止這個工作很好,我可以成功破譯所有不同的塊。Nodejs - 使用JavaScript來計算兩個32位字的日期

當前使用節點6.11。

雖然我正在努力確定一個增強型數據包塊的時間戳。每文檔,這就是包括EHP:

0     1     2     3 
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
    +---------------------------------------------------------------+ 
0 |     Block Type = 0x00000006     | 
    +---------------------------------------------------------------+ 
4 |      Block Total Length      | 
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
8 |       Interface ID       | 
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
12 |      Timestamp (High)      | 
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
16 |      Timestamp (Low)      | 
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
20 |     Captured Packet Length      | 
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
24 |     Original Packet Length      | 
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
28/               /
/      Packet Data      /
/   variable length, padded to 32 bits    /
/               /
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
/               /
/     Options (variable)      /
/               /
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
    |      Block Total Length      | 
    +---------------------------------------------------------------+ 

時間戳(高)和時間戳(低):高32位和64位時間戳的低32位。時間戳是一個64位無符號整數,表示自1970-01-01 00:00:00 UTC以來經過的時間單位數。時間單位的長度由該包引用的接口描述塊的'if_tsresol'選項(見圖10)指定。請注意,與libpcap文件格式中的時間戳不同,增強型數據包塊中的時間戳不會保存爲兩個32位值,它們表示自1970-01-01 00:00:00 UTC以來經過的秒數和微秒數。增強型數據包塊中的時間戳保存爲兩個32位字,表示單個64位數量的高32位和低32位。

那麼,我該如何去弄清楚這裏的時間戳呢?顯然這是由兩個32位字組成的,以創建一個64位數字。但是,JavaScript不處理64位整數。

我確實嘗試過使用node-int64,但一直沒有成功。已經產生了infinity的結果。

這裏是緩衝的特定切片我使用:

Uint8Array[8] 
0:46 
1:89 
2:5 
3:0 
4:9 
5:12 
6:15 
7:31 

,它的十六進制表示...

timeBuffer.toString('hex') 
"2e590500090c0f1f" 

這個緩衝區實際上是第4個字節的時間戳(高),並且字節4-8將是時間戳(低)。

本質上我試圖確定這裏的實際時間戳。例如,我可以通過將一個數字值傳遞給new Date(12345678789)來實現。只是不能用這種方式來包裹我的頭。一個人如何獲得兩個32位的單詞,並將它們粘合在一起,這樣我就可以抽出自1970年以來的時間?

回答

0

對,JS不支持64位整數,但你總是可以使用浮點數。該微秒部分將不準確的,由於舍入誤差,但因爲你是標準的js日期,其中只有毫秒的分辨率後,這不應該是一個問題:

buf = Buffer.from("2e590500090c0f1f", 'hex') 

h = buf.readUInt32LE(0); 
l = buf.readUInt32LE(4); 

t = h * 0x100000000 + l; 

console.log(new Date(t/1000)); // 2017-09-14T22:51:48.000Z 

你的其他解決方案不工作可能是因爲格式有點令人困惑:64位數字存儲大端(最高部分第一),而其部分(32位字)是小端。

+0

感謝您指出endianness!絕對令人困惑。有沒有辦法保存微秒?我們的wireshark捕獲次數儲存到微秒(即12.003997)。通過解析數據包塊,可以在JavaScript中計算出這些數據。 – dvsoukup

+0

在上面的代碼中,'t%1000'給你μs,但這可能是不準確的。 – georg

+0

好的,太棒了!今天晚些時候我會檢查一下。非常感謝您的幫助。 – dvsoukup