2017-10-11 92 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

相关问题