hadoop pcap lib字段类型

p8ekf7hl  于 2021-05-30  发布在  Hadoop
关注(0)|答案(1)|浏览(472)

我正在尝试创建一个protobuf类,它可以更有效地流式传输使用tcpdump捕获的dnspackes。
我想知道这个库中提供的所有可能字段的类型:

DNSPacket Fields:
    QUERYID
    QR
    OPCODE
    RCODE
    QUESTION
    QNAME
    QTYPE
    ANSWER
    AUTHORITY
    ADDITIONAL
Packet Fields:
    TIMESTAMP
    TIMESTAMP_USEC
    TIMESTAMP_MICROS
    TTL
    IP_VERSION
    IP_HEADER_LENGTH
    IP_FLAGS_DF
    IP_FLAGS_MF
    IPV6_FLAGS_M
    FRAGMENT_OFFSET
    FRAGMENT
    LAST_FRAGMENT
    PROTOCOL
    SRC
    DST
    ID
    SRC_PORT
    DST_PORT
    TCP_HEADER_LENGTH
    TCP_SEQ
    TCP_ACK
    LEN
    UDPSUM
    UDP_LENGTH
    TCP_FLAG_NS
    TCP_FLAG_CWR
    TCP_FLAG_ECE
    TCP_FLAG_URG
    TCP_FLAG_ACK
    TCP_FLAG_PSH
    TCP_FLAG_RST
    TCP_FLAG_SYN
    TCP_FLAG_FIN
    /*Not sure bout these two*/
    REASSEMBLED_TCP_FRAGMENTS 
    REASSEMBLED_DATAGRAM_FRAGMENTS

我的应用程序在scala中,我尝试对捕获的一些数据包进行简单的反射,但是许多字段都是空的,这是没有帮助的。
这个库可以在github上找到
有没有一个简单的方法可以得到所有这些字段的类型(以编程方式或通过文本源)
谢谢,rds

qhhrdooz

qhhrdooz1#

我用最直接的方式来处理这个问题。
我决定使用大量的数据包来解决这个问题,使用wireshark捕获了大约100000个dns数据包,然后将捕获保存为 .pcap 文件。
然后,我对该文件运行了以下命令:

try {
  var dataInStream: DataInputStream = null
  //Open the file and set up the DataInputStream
  val f = new File(pCapFileName)
  if (f.getAbsoluteFile.exists) {
    val fis = new FileInputStream(f)
    dataInStream = new DataInputStream(fis)
    val dnsPcapReader = new DnsPcapReader(dataInStream)
    val pktIter = dnsPcapReader.iterator
    var counter = 0
    while (pktIter.hasNext) {
      counter += 1
      if (counter % 100 == 0) println(counter)
      val pCapFile = pktIter.next.asInstanceOf[DnsPacket]
      for (i <- 0 until types.length) {
        val tuple = types(i)
        val fieldName = tuple._1
        var className = Option(pCapFile.get(fieldName)).map(_.getClass).toString
        var numOccurances = tuple._3
        if(className.equals("None"))
          className = tuple._2.asInstanceOf[String]
        else
          numOccurances += 1
        val newTuple = (fieldName, className, numOccurances)
        types = types.updated(i, newTuple)
      }
    }
  }
  for {
    tuple <- types
  } printf("%s%-25s%-25s%-25s\n%s\n", "\t", tuple._1 + ":", tuple._2,
    "[" + tuple._3 + "]", spacer)
  //Close the stream
  dataInStream.close
} catch {
  case e: Exception => e.printStackTrace()
}

本质上,它为每个字段名检查一个值,然后也检查该值的类。每次更新列表中相应的空间以反映字段(不太优雅,但它以合理的方式获得结果)。此外,可以方便地查看哪些字段是公共的,哪些字段不是。
结果如下:

dst:                     Some(class java.lang.String)[98823]
dst_port:                Some(class java.lang.Integer)[98614]
fragment:                Some(class java.lang.Boolean)[98823]
fragment_offset:         Some(class java.lang.Long)[98799]
id:                      Some(class java.lang.Long)[98799]
ip_flags_df:             Some(class java.lang.Boolean)[98799]
ip_flags_mf:             Some(class java.lang.Boolean)[98799]
ip_header_length:        Some(class java.lang.Integer)[98823]
ip_version:              Some(class java.lang.Integer)[98823]
ipv6_flags_m:            null                     [0]
last_fragment:           null                     [0]
len:                     Some(class java.lang.Integer)[98823]
protocol:                Some(class java.lang.String)[98618]
reassembled_datagram_fragments:null                     [0]
reassembled_tcp_fragments:Some(class java.lang.Integer)[835]
src:                     Some(class java.lang.String)[98823]
src_port:                Some(class java.lang.Integer)[98614]
tcp_ack:                 Some(class java.lang.Long)[96106]
tcp_flag_ack:            Some(class java.lang.Boolean)[96106]
tcp_flag_cwr:            Some(class java.lang.Boolean)[96106]
tcp_flag_ece:            Some(class java.lang.Boolean)[96106]
tcp_flag_fin:            Some(class java.lang.Boolean)[96106]
tcp_flag_ns:             Some(class java.lang.Boolean)[96106]
tcp_flag_psh:            Some(class java.lang.Boolean)[96106]
tcp_flag_rst:            Some(class java.lang.Boolean)[96106]
tcp_flag_syn:            Some(class java.lang.Boolean)[96106]
tcp_flag_urg:            Some(class java.lang.Boolean)[96106]
tcp_header_length:       Some(class java.lang.Integer)[96106]
tcp_seq:                 Some(class java.lang.Long)[96106]
ts:                      Some(class java.lang.Long)[100258]
ts_micros:               Some(class java.lang.Long)[100258]
ts_usec:                 Some(class java.lang.Double)[100258]
ttl:                     Some(class java.lang.Integer)[98823]
udp_length:              Some(class java.lang.Integer)[2508]
udpsum:                  Some(class java.lang.Integer)[2508]
dns_additional:          Some(class java.util.ArrayList)[320]
dns_answer:              Some(class java.util.ArrayList)[320]
dns_authority:           Some(class java.util.ArrayList)[320]
dns_flags:               Some(class java.lang.String)[320]
dns_opcode:              Some(class java.lang.String)[320]
dns_qname:               Some(class java.lang.String)[320]
dns_qr:                  Some(class java.lang.Boolean)[320]
dns_qtype:               Some(class java.lang.Integer)[320]
dns_queryid:             Some(class java.lang.Integer)[320]
dns_question:            Some(class java.lang.String)[320]
dns_rcode:               Some(class java.lang.String)[320]

有三个字段仍然出现0次,因此它们的类类型仍然未知: ipv6_flags_m , last_fragment ,和 reassembled_datagram_fragments 视为 ipv6_flags_m 是一个标志,它很可能是一个布尔值,我假设它是留下两个字段的。由于100000个数据包中没有出现这些字段,因此我认为这些字段无关紧要,并将它们从列表中完全删除。

相关问题