使用Node_pcap解码UDP数据

时间:2017-07-30 22:13:50

标签: node.js udp pcap

我正在尝试构建快速的nodejs脚本来查看网络中的一些数据。使用node_pcap我设法解码除了通过UDP协议结束的有效载荷数据之外的几乎所有内容。这是我的代码(相当基本,但给我标题和有效负载)

const interface = 'en0';
let filter = 'udp';
const pcap = require('pcap'),
  pcap_session = pcap.createSession(interface, filter),

  pcap_session.on('packet', function (raw_packet) {
    let packet = pcap.decode.packet(raw_packet);
    let data = packet.payload.payload.payload.data;
    console.log(data.toString()); // not full data
  });

当我尝试使用toString()方法打印数据时,它为我提供了大部分数据,但开头。我有这样的印刷品:

Li?��ddn-�*ys�{"Id":13350715,...我已经删除了其余的JSON数据。

但是我怀疑我无法读取的数据包含一些有用的信息,例如有多少数据包,偏移数据包等等。

我设法从有效负载的缓冲区中获取部分内容: 00 00 00 01 52 8f 0b 4a 4d 3f cb de 08 00 01 00 00 00 04 a4 00 00 26 02 00 00 26 02 00 00 00 03 00 00 00 00 00 00 09 2d 00 00 00 00 f3 03 01 00 00 2a 00 02 00 79 00 05 73 01 d2

虽然我知道它可以是什么样的数据,但我不知道它的结构。

有没有办法可以解码缓冲区的这一位?我试着查看一些缓冲方法,例如readInt32LEreadInt16LE但是徒劳无功。是否有某些阅读可以指导我完成解码过程?

[编辑]我越是研究它,我越怀疑数据是BSON而不是JSON,这可以解释为什么我可以阅读一些但不是一切。有人设法从数据包解码BSON吗?

1 个答案:

答案 0 :(得分:1)

库如何知道要使用哪个数据包解码器?

通过识别使用哪个协议https://github.com/node-pcap/node_pcap/blob/master/decode/pcap_packet.js#L29-L56

,从TCP / IP堆栈的第2层开始
switch (this.link_type) {
case "LINKTYPE_ETHERNET":
    this.payload = new EthernetPacket(this.emitter).decode(buf, 0);
    break;
case "LINKTYPE_NULL":
    this.payload = new NullPacket(this.emitter).decode(buf, 0);
    break;
case "LINKTYPE_RAW":
    this.payload = new Ipv4(this.emitter).decode(buf, 0);
    break;
case "LINKTYPE_IEEE802_11_RADIO":
    this.payload = new RadioPacket(this.emitter).decode(buf, 0);
    break;
case "LINKTYPE_LINUX_SLL":
    this.payload = new SLLPacket(this.emitter).decode(buf, 0);
    break;
default:
    console.log("node_pcap: PcapPacket.decode - Don't yet know how to decode link type " + this.link_type);
}

然后它上升并尝试根据它在https://github.com/node-pcap/node_pcap/blob/master/decode/ipv4.js#L12-L17

的特定情况下在标题IPv4 protocol中找到的标记解码正确的协议
IPFlags.prototype.decode = function (raw_flags) {
    this.reserved = Boolean((raw_flags & 0x80) >> 7);
    this.doNotFragment = Boolean((raw_flags & 0x40) > 0);
    this.moreFragments = Boolean((raw_flags & 0x20) > 0);
    return this;
};

然后在你的情况下,它将与udp协议https://github.com/node-pcap/node_pcap/blob/master/decode/ip_protocols.js#L15

匹配
protocols[17]  = require("./udp");

因此,如果您检查https://github.com/node-pcap/node_pcap/blob/master/decode/udp.js#L32,数据包会自动解码并显示toString方法

UDP.prototype.toString = function () {
    var ret = "UDP " + this.sport + "->" + this.dport + " len " + this.length;
    if (this.sport === 53 || this.dport === 53) {
        ret += (new DNS().decode(this.data, 0, this.data.length).toString());
    }
    return ret;
};

这对你意味着什么?

为了解码udp(任意)数据包,您只需调用高级别api pcap.decode.packet(raw_packet),然后调用toString方法显示已解码的正文有效负载

pcap_session.on('packet', function (raw_packet) {
    let packet = pcap.decode.packet(raw_packet);
    console.log(packet.toString());
});