def send_query(query: Message, ip: str) -> Message: s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.sendto(query.to_bytes(), (ip, 53)) # not sure whether the max size is standard. This is big (TM) so it should be alright for simple queries. msg_bytes, _ = s.recvfrom(65535) msg = parse_message(msg_bytes) return msg
def test_parse_message_query(): # according to wireshark there's an additional record (whose use I'm not sure of). additional_record = b"\x00\x00\x29\x10\x00\x00\x00\x00\x00\x00\x0c\x00\x0a\x00\x08\x0b\xeb\x72\x45\x28\xb4\xa2\x3d" dig_recurse_query = ( b"\x33\x83\x01\x20\x00\x01\x00\x00\x00\x00\x00\x01\x07\x72\x65\x63" b"\x75\x72\x73\x65\x03\x63\x6f\x6d\x00\x00\x01\x00\x01" + additional_record) m = parse_message(dig_recurse_query) assert m.header.qr == Message.FLAG_QR_QUERY assert m.header.opcode == 0 assert m.header.aa == 0 assert m.header.tc == 0 assert m.header.rd == 1 assert m.header.ra == 0 assert m.header.z == 2 assert m.header.rcode == 0 assert m.header.qd_count == 1 assert m.header.an_count == 0 assert m.header.ns_count == 0 assert m.header.ar_count == 1 assert m.question[0].qname == labels_from_domain("recurse.com") assert m.question[0].qclass == QClasses.IN assert m.question[0].qtype == QTypes.A_RECORD encoded = m.to_bytes() assert encoded == dig_recurse_query
def msg_handler(self, msg, client): msg = message.parse_message(msg) if msg['id'] == 0: self.choke_handler() elif msg['id'] == 1: self.unchoke_handler(client) elif msg['id'] == 4: self.have_handler(msg['payload'], client) elif msg['id'] == 5: self.bitfield_handler(msg['payload'], client) elif msg['id'] == 7: self.piece_handler(msg['payload'], client)
def test_parse_root_server_response(): response_bytes = b"\xcb)\x80\x00\x00\x01\x00\x00\x00\r\x00\x0e\x07recurse\x03com\x00\x00\x01\x00\x01\xc0\x14\x00\x02\x00\x01\x00\x02\xa3\x00\x00\x14\x01a\x0cgtld-servers\x03net\x00\xc0\x14\x00\x02\x00\x01\x00\x02\xa3\x00\x00\x04\x01b\xc0+\xc0\x14\x00\x02\x00\x01\x00\x02\xa3\x00\x00\x04\x01c\xc0+\xc0\x14\x00\x02\x00\x01\x00\x02\xa3\x00\x00\x04\x01d\xc0+\xc0\x14\x00\x02\x00\x01\x00\x02\xa3\x00\x00\x04\x01e\xc0+\xc0\x14\x00\x02\x00\x01\x00\x02\xa3\x00\x00\x04\x01f\xc0+\xc0\x14\x00\x02\x00\x01\x00\x02\xa3\x00\x00\x04\x01g\xc0+\xc0\x14\x00\x02\x00\x01\x00\x02\xa3\x00\x00\x04\x01h\xc0+\xc0\x14\x00\x02\x00\x01\x00\x02\xa3\x00\x00\x04\x01i\xc0+\xc0\x14\x00\x02\x00\x01\x00\x02\xa3\x00\x00\x04\x01j\xc0+\xc0\x14\x00\x02\x00\x01\x00\x02\xa3\x00\x00\x04\x01k\xc0+\xc0\x14\x00\x02\x00\x01\x00\x02\xa3\x00\x00\x04\x01l\xc0+\xc0\x14\x00\x02\x00\x01\x00\x02\xa3\x00\x00\x04\x01m\xc0+\xc0)\x00\x01\x00\x01\x00\x02\xa3\x00\x00\x04\xc0\x05\x06\x1e\xc0I\x00\x01\x00\x01\x00\x02\xa3\x00\x00\x04\xc0!\x0e\x1e\xc0Y\x00\x01\x00\x01\x00\x02\xa3\x00\x00\x04\xc0\x1a\\\x1e\xc0i\x00\x01\x00\x01\x00\x02\xa3\x00\x00\x04\xc0\x1fP\x1e\xc0y\x00\x01\x00\x01\x00\x02\xa3\x00\x00\x04\xc0\x0c^\x1e\xc0\x89\x00\x01\x00\x01\x00\x02\xa3\x00\x00\x04\xc0#3\x1e\xc0\x99\x00\x01\x00\x01\x00\x02\xa3\x00\x00\x04\xc0*]\x1e\xc0\xa9\x00\x01\x00\x01\x00\x02\xa3\x00\x00\x04\xc06p\x1e\xc0\xb9\x00\x01\x00\x01\x00\x02\xa3\x00\x00\x04\xc0+\xac\x1e\xc0\xc9\x00\x01\x00\x01\x00\x02\xa3\x00\x00\x04\xc00O\x1e\xc0\xd9\x00\x01\x00\x01\x00\x02\xa3\x00\x00\x04\xc04\xb2\x1e\xc0\xe9\x00\x01\x00\x01\x00\x02\xa3\x00\x00\x04\xc0)\xa2\x1e\xc0\xf9\x00\x01\x00\x01\x00\x02\xa3\x00\x00\x04\xc07S\x1e\xc0)\x00\x1c\x00\x01\x00\x02\xa3\x00\x00\x10 \x01\x05\x03\xa8>\x00\x00\x00\x00\x00\x00\x00\x02\x000" m = parse_message(response_bytes) assert m.header.transaction_id == 52009 # Not sure why this is marked as a 'Query' and not a response. Would need to re-record the bytes. # assert m.header.qr == Message.FLAG_QR_RESPONSE assert m.header.an_count == 0 assert m.header.ns_count == 13 assert m.header.ar_count == 14
def dataReceived(self, data): self._buffer += data if not self.shook_hand: peer_handshake, self._buffer = parse_handshake(self._buffer) if peer_handshake: # if successful, will set shook hands to true if not self.client.is_valid_handshake(peer_handshake): self.client.handle_invalid_handshake(self) return self.client.handle_valid_handshake(self) # parse buffer for messages msgs, self._buffer = parse_message(self._buffer) self.client.handle_messages(self, msgs) # parse buffer for messages else: msgs, self._buffer = parse_message(self._buffer) self.client.handle_messages(self, msgs)
def handle_query(s: socket.socket, data, emitter): m = parse_message(data) if m.question[0].qtype != QTypes.A_RECORD or m.question[ 0].qclass != QClasses.IN: raise ValueError( "I don't handle these kind of queries. Only basic baby-dns queries please." ) ip, ttl = get_ip(m.question[0].qname) response = construct_response(m.header.transaction_id, m.question[0].qname, ip, ttl) s.sendto(response.to_bytes(), emitter)
def test_parse_message(): # data copied from wireshark (copy dns message 'as escaped string') and values checked in wireshark. dig_recurse_response = ( b"\x33\x83\x81\x80\x00\x01\x00\x02\x00\x00\x00\x01\x07\x72\x65\x63" b"\x75\x72\x73\x65\x03\x63\x6f\x6d\x00\x00\x01\x00\x01\xc0\x0c\x00" b"\x01\x00\x01\x00\x00\x00\x3b\x00\x04\x03\x5c\x09\xbd\xc0\x0c\x00" b"\x01\x00\x01\x00\x00\x00\x3b\x00\x04\x22\xc4\x1d\x1f\x00\x00\x29" b"\x02\x00\x00\x00\x00\x00\x00\x00") domain_name_part = b"\x07\x72\x65\x63\x75\x72\x73\x65\x03\x63\x6f\x6d\x00" m = parse_message(dig_recurse_response) assert m.header.qr == 1 assert m.header.opcode == 0 assert m.header.aa == 0 assert m.header.tc == 0 assert m.header.rd == 1 assert m.header.ra == 1 assert m.header.z == 0 assert m.header.rcode == 0 assert m.header.qd_count == 1 assert m.header.an_count == 2 assert m.header.ns_count == 0 assert m.header.ar_count == 1 assert m.question[0].qname == labels_from_domain("recurse.com") assert m.question[0].qclass == QClasses.IN assert m.question[0].qtype == QTypes.A_RECORD encoded = m.to_bytes() # replace pointers with the full labels since we don't compress labels when encoding assert encoded == dig_recurse_response.replace(b"\xc0\x0c", domain_name_part, -1) # check 'recursion available' flag is preserved m.header.ra = 1 encoded = m.to_bytes() decoded = parse_message(encoded) assert decoded.header.ra == 1
def __call__(self, msg_data, completion_callback): msg = message.parse_message(msg_data, "task_result") logger.debug("[%s] Got command task result: %s rc=%s logfile=%s" % (self.get_log_tag(), msg.status, msg.rc, msg.logfile)) if msg.output: for line in msg.output: logger.info("[%s] %s" % (self.worker_node["name"], line.rstrip())) if not msg.comment: reason = "Return code was %s, Logfile is at %s" % \ (msg.rc, msg.logfile) else: reason = msg.comment completion_callback(self, msg.status, reason=reason)
def post(self): global token _args = dict( token=token, timestamp=self.request.get('timestamp'), nonce=self.request.get('nonce'), signature=self.request.get('signature') ) if not checkSignure(**_args): return webapp2.abort(403) message = parse_message(self.request.body) reply = generate_reply(message) self.response.content_type = 'application/xml' self.response.write(to_unicode(reply.to_xml()))
def main(argv): if len(argv) != 2: print "Usage", argv[0], "<firmware.ili>" return 1 ili_parser = IliParser(argv[1]) while True: rec_len = sys.stdin.read(1) if not rec_len: break record = sys.stdin.read(ord(rec_len)) try: msg_id, params = parse_message(record) print ili_parser.format_msg(msg_id, params) except: print "Could not parse message", repr(record)
def parse_message(self, buff): """Returns a tuple of a list of Msg's and the remaining bytes. Note: if a Msg cannot be formed out of buff (i.e. buff isn't large enough), ([], buff) is returned. Args: buff (str) Returns: tuple ([Msg, ...], str) """ msgs = [] while True: msg, buff = message.parse_message(buff) if msg is None: break msgs.append(msg) return msgs, buff