예제 #1
0
  def parse(bytedata: bytes) -> tuple:
    """
    :param bytedata data, from the dns packet stream
    :return: tuple(AnswerItem, rest of bytedata)
    :rtype AnswerItem, bytes
    """

    name_field, bytedata = bread(bytedata, 2)
    name_field = int.from_bytes(name_field, byteorder="big")

    # 0bXY00000000000000 - X: 1 Y: 1 -> 11, X:0 Y:1 -> 1, X:1 Y:0 -> 10
    name_type = 10 * ((name_field >> 15) & 0b1) + ((name_field >> 14) & 0b1)
    name_offset = name_field & 0b001111111111111

    assert name_type == 11

    _type, bytedata = bread(bytedata, 2)
    _type = int.from_bytes(_type, byteorder="big")

    _class, bytedata = bread(bytedata, 2)
    _class = int.from_bytes(_class, byteorder="big")

    _ttl, bytedata = bread(bytedata, 4)
    _ttl = int.from_bytes(_ttl, byteorder="big")

    rdlen, bytedata = bread(bytedata, 2)
    rdlen = int.from_bytes(rdlen, byteorder="big")

    rddata, bytedata = bread(bytedata, rdlen)
    rddata = QuestionTypes.unpack(_type, rddata)

    return AnswerItem(QuestionItem(name_offset, _type, _class), _type, rddata, _ttl), bytedata
예제 #2
0
  def parse(bytedata: bytes) -> tuple:
    """
    :param bytedata data, from the dns packet stream
    :return: tuple(QuestionItem, rest of bytedata)
    :rtype QuestionItem, bytes
    """
    domain = []
    count = -1

    while count != 0:
      count, bytedata = bread(bytedata, 1)
      count = int.from_bytes(count, byteorder="big")
      if count != 0:
        domain_part, bytedata = bread(bytedata, count)
        domain.append(domain_part.decode())

    qtype, bytedata = bread(bytedata, 2)
    qtype = int.from_bytes(qtype, byteorder="big")

    qclass, bytedata = bread(bytedata, 2)
    qclass = int.from_bytes(qclass, byteorder="big")

    return QuestionItem(domain, qtype, qclass), bytedata
예제 #3
0
  def __init__(self, _msg=None):
    """
    :type _msg byte
    :param _msg Get byte array as input and form structured data
    """
    if _msg is None:
      self.message_id = generate_message_id()
      self.header = Header()
      self.question_section = []
      self.answer_section = []
      self.authority_section = []
      self.additional_section = []
      return

    offset = 0

    #  parse data packet
    self.message_id, _msg, offset = bread(_msg, 2, offset)

    _pack1, _msg, offset = bread(_msg, 2, offset, data_fx=lambda x: int.from_bytes(x, byteorder="big"))

    # declare sections
    _size, _msg, offset = bread(_msg, 2, offset, data_fx=lambda x: int.from_bytes(x, byteorder="big"))
    self.question_section = [None] * _size
    # required to store question section offsets for answer_section "name"
    question_offset_grid = [None] * _size

    _size, _msg, offset = bread(_msg, 2, offset, data_fx=lambda x: int.from_bytes(x, byteorder="big"))
    self.answer_section = [None] * _size

    _size, _msg, offset = bread(_msg, 2, offset, data_fx=lambda x: int.from_bytes(x, byteorder="big"))
    self.authority_section = [None] * _size

    _size, _msg, offset = bread(_msg, 2, offset, data_fx=lambda x: int.from_bytes(x, byteorder="big"))
    self.additional_section = [None] * _size

    #  decode header section
    self.header = Header(_pack1)

    # decode Question section
    for i in range(0, len(self.question_section)):
      la = len(_msg)
      item, _msg = QuestionItem.parse(_msg)
      lb = len(_msg)
      question_offset_grid[i] = offset
      self.question_section[i] = item
      offset += la - lb

    # decode Answer section
    for i in range(0, len(self.answer_section)):
      la = len(_msg)
      item, _msg = AnswerItem.parse(_msg)
      lb = len(_msg)

      # here we will get answer name from the offset
      loffset = item.name
      for x in range(0, len(question_offset_grid)):
        if question_offset_grid[x] <= loffset:
          item.name = self.question_section[x].qname

      self.answer_section[i] = item
      offset += la - lb

    # decode Authority section
    for i in range(0, len(self.authority_section)):
      la = len(_msg)
      item, _msg = AnswerItem.parse(_msg)
      lb = len(_msg)

      # here we will get answer name from the offset
      loffset = item.name
      for x in range(0, len(question_offset_grid)):
        if question_offset_grid[x] <= loffset:
          item.name = self.question_section[x].qname

      self.authority_section[i] = item
      offset += la - lb