Ejemplo n.º 1
0
def handle_uri(id_pb):
    uri = trackURI
    print_info('Got uri request for {}, replying with {}',
               id_pb.id.hex(),
               uri,
               color='magenta')
    return Devialet.AudioSource.Uri(uri=uri)
Ejemplo n.º 2
0
    def CallUnknownMethod(self, serviceId, subTypeId, request, done, typeId=0):
        print_info('Calling unknown method #{} from service #{} on port {}',
                   subTypeId, serviceId, self.port)
        reqUUID = uuid.uuid4().bytes
        cmm_request = Devialet.CallMeMaybe.Request(serverId=self.serverId,
                                                   serviceId=serviceId,
                                                   requestId=reqUUID,
                                                   type=typeId,
                                                   subTypeId=subTypeId)
        self.request_queue[reqUUID] = (None, None,
                                       DevialetController(self.conn),
                                       done if done else self.unblock_call)
        self.write_rpc(cmm_request.SerializeToString(),
                       request.SerializeToString())

        if done is None:
            # Blocking call
            self.blocking_response = None
            while self.blocking_response is None and self.receive():
                # print_info("Waiting for response on unknown method (serviceId {}, subTypeId {})",
                #            serviceId, subTypeId)
                # time.sleep(1)
                pass
            if self.blocking_response is None:
                self.close()
                print_error("Server hung up before response")
            return self.blocking_response
Ejemplo n.º 3
0
    def CallMethod(self, method_descriptor, rpc_controller, request,
                   response_class, done):
        # Handle events and requests differently: events broadcast to every client;
        # Requests just register callback for later use
        # (Opposite of DevialetClient)

        if method_descriptor.GetOptions(
        ).Extensions[dvltMethodOptions].isNotification:
            # For events, broadcast immediately, don't use callback
            serviceId = rpc_controller.parent_service.service_id if hasattr(
                rpc_controller.parent_service,
                'service_id') else self.find_service_id(
                    method_descriptor.containing_service)
            # Special PropertyUpdate event: how do we get the property id???
            typeId, subTypeId = (
                1, request.id
            ) if method_descriptor.name == 'propertyUpdate' else (
                0, method_descriptor.index)
            cmm_event = Devialet.CallMeMaybe.Event(serverId=self.serverId,
                                                   serviceId=serviceId,
                                                   type=typeId,
                                                   subTypeId=subTypeId)

            print_info('Sending event {}', method_descriptor.full_name)

            for addrport in self.clientsocks.keys():
                self.write_event_to_addr(addrport,
                                         cmm_event.SerializeToString(),
                                         request.SerializeToString())
        else:
            # For request methods, only register callback, don't send anything
            self.request_callbacks[method_descriptor.full_name] = (
                dvlt_pool.messages[method_descriptor.input_type.full_name],
                done)
Ejemplo n.º 4
0
 def register_endpoint(self, srv):
     if (srv.hostUid, srv.port) not in self.endpoints:
         print_info('Registering endpoint {}', (srv.hostUid, srv.port))
         self.endpoints[(srv.hostUid, srv.port)] = srv
     else:
         print_error('uid {} port {} already used by endpoint', srv.hostUid,
                     srv.port)
Ejemplo n.º 5
0
    def __init__(self, dirname):
        DevialetManyFlows.__init__(self)
        self.dirname = dirname

        for capture in sorted(os.listdir(self.dirname)):
            time, port = re.match('^([0-9]+)_([0-9]+).dat$', capture).groups()
            if (port, port) in self.flows:
                flow = self.flows[(port, port)]
            else:
                flow = DevialetFlow(name=capture, phantom_port=port, spark_port=port, start_time=datetime.fromtimestamp(int(time)/1000))
                self.add_flow(flow)

            it = self.packet_iter(os.path.join(self.dirname, capture))
            try:
                first_packet = next(it)
                # If first packet is incoming, then rpc server is Spark
                flow.rpc_server_is_phantom = not first_packet['direction']
                flow.decode(first_packet['data'], time=first_packet['time'], incoming=False)
                if not flow.rpc_server_is_phantom:
                    print_info('Found flow where Spark appears to be RPC server')
                for packet in it:
                    # Switch incoming/outgoing if rpc server is spark
                    is_incoming = packet['direction'] ^ (not flow.rpc_server_is_phantom)
                    flow.decode(packet['data'], time=packet['time'], incoming=is_incoming)
            except:
                # Empty flow
                pass

        for key in self.flows:
            self.flows[key].close()
            self.flows[key].rpc_walk()
Ejemplo n.º 6
0
    def rpc_walk(self, consume_incoming=True, verbose=True):
        # Each section should correspond to a RPC request/reply,
        # with 2 outgoing protobufs and 2 (or more for propertyget/multipart) incoming,
        # or an RPC event, with 2 (or more?) incoming, and no outgoing

        if verbose or len(self.incoming_sections) != 0:
            print_info('Walking {}', self.name)
            print_data('=' * 32)
        if not self.rpc_server_is_phantom:
            print_warning('RPC server appears to be Spark here')

        if consume_incoming:
            for i in range(len(self.incoming_sections)):
                print_data('-' * 16)
                incoming_section = self.incoming_sections.popleft()
                self.rpc_walk_one_section(incoming_section)

            # Useless?
            if len(self.incoming_sections) != 0:
                print_error('There were {} incoming sections remaining', len(self.incoming_sections))

        else:
            for incoming_section in self.incoming_sections:
                print_data('-' * 16)
                self.rpc_walk_one_section(incoming_section)

        if len(self.outgoing_sections) != 0:
            print_error('There were {} outgoing sections remaining', len(self.outgoing_sections))
Ejemplo n.º 7
0
    def open(self):
        try:
            self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            # Port 0 means system-chosen port
            self.sock.bind((self.addr, self.port))
            self.addr, self.port = self.sock.getsockname()
            self.sock.listen(5)

            self.register_service(self.conn)
            ctrl = DevialetController(self.conn)
            # Register callback for client connection requests
            self.conn.openConnection(ctrl, None, self.open_connection)
            self.conn.ping(ctrl, None, self.pong)

            # # No Callback - does a blocking RPC
            # conn_reply = self.conn.openConnection(ctrl, Devialet.CallMeMaybe.ConnectionRequest(version=1), None)
            # self.serverId = conn_reply.serverId
            # self.service_list = Devialet.CallMeMaybe.ServicesList(services=conn_reply.services)
            # # Register event callbacks for added/deleted services
            # self.conn.serviceAdded(ctrl, None, self.add_service)
            # self.conn.serviceRemoved(ctrl, None, self.remove_service)
            # self.conn.serverQuit(ctrl, None, self.close)
            print_info('Listening on port {}', self.port)

            # Add to endpoint database of parent whatsup servers
            self.wu_server.register_endpoint(self)

            return True
        except ConnectionRefusedError:
            exc_type, exc_obj, exc_tb = sys.exc_info()
            print_error("Can't Connect to {} on port {}, error {}", self.addr,
                        self.port, exc_obj)
            self.sock = None
            return False
Ejemplo n.º 8
0
    def CallMethod(self,
                   method_descriptor,
                   rpc_controller,
                   request,
                   response_class,
                   done,
                   timeout=2):
        # For event methods, only register callback, don't send anything
        if method_descriptor.GetOptions(
        ).Extensions[dvltMethodOptions].isNotification:
            # For events, response class is always empty, request class is the actual class of the event
            self.event_callbacks[method_descriptor.full_name] = (
                dvlt_pool.messages[method_descriptor.input_type.full_name],
                done)
        else:
            reqUUID = uuid.uuid4().bytes
            serviceId = rpc_controller.parent_service.service_id if hasattr(
                rpc_controller.parent_service,
                'service_id') else self.find_service_id(
                    method_descriptor.containing_service)
            typeId, subTypeId = (
                1,
                0xFFFFFFFF) if method_descriptor.name == 'propertyGet' else (
                    0, method_descriptor.index)
            cmm_request = Devialet.CallMeMaybe.Request(serverId=self.serverId,
                                                       serviceId=serviceId,
                                                       requestId=reqUUID,
                                                       type=typeId,
                                                       subTypeId=subTypeId)
            # First add the callback to the queue...
            self.request_queue[reqUUID] = (method_descriptor, response_class,
                                           rpc_controller,
                                           done if done else self.unblock_call)
            if done is None:
                # Blocking Call
                self.blocked.clear()
            # ...Then send the actual request bytes
            self.write_rpc(cmm_request.SerializeToString(),
                           request.SerializeToString())
            print_info('Calling method {} from service {} ({})...',
                       method_descriptor.name,
                       rpc_controller.parent_service.serviceName, serviceId)
            print_data('... with argument:', request)

            if done is None:
                # Wait for callback to be executed or socket to die
                while self.sock is not None and not self.shutdown_signal and not self.blocked.wait(
                        timeout=timeout):
                    # Wait for blocked event to be unset
                    print_warning('Still blocked on method {}...',
                                  method_descriptor.full_name)
                if self.blocking_response is None:
                    # self.close()
                    print_error("Server hung up before response")
                return self.blocking_response
Ejemplo n.º 9
0
 def add_wu_services(self, wu_services):
     self.wu_service_list.services.extend(wu_services.services)
     for wu_service in wu_services.services:
         m = re.match('tcp://127.0.0.1:([0-9]+)', wu_service.endpoint)
         truncated_name = '.'.join(wu_service.name.split('.')[:-1])
         if m is not None:
             port = int(m.groups()[0])
             self.services_by_port.setdefault(port,
                                              []).append(truncated_name)
             self.ports_by_service.setdefault(truncated_name,
                                              []).append(port)
     print_info("New WhatsUp services added: {}", wu_services)
Ejemplo n.º 10
0
 def connect(self):
     self.conn = Devialet.CallMeMaybe.Connection(self)
     ctrl = DevialetController(self.conn)
     # No Callback - does a blocking RPC
     conn_reply = self.conn.openConnection(
         ctrl, Devialet.CallMeMaybe.ConnectionRequest(version=1), None)
     self.serverId = conn_reply.serverId
     self.service_list = Devialet.CallMeMaybe.ServicesList(
         services=conn_reply.services)
     # Register event callbacks for added/deleted services
     self.conn.serviceAdded(ctrl, None, self.add_service)
     self.conn.serviceRemoved(ctrl, None, self.remove_service)
     self.conn.serverQuit(ctrl, None, self.close)
     print_info('Opened connection to {} on port {}', self.addr, self.port)
     print_data('List of services:', self.service_list)
Ejemplo n.º 11
0
 def find_service(self, rep):
     service_name = 'com.devialet.callmemaybe.connection'
     try:
         if rep.serviceId != 0 or self.service_list.services:
             service_lowercase_name = [service.name for service in self.service_list.services if service.id == rep.serviceId][0]
             # PlayThatFunkyMusic is nowhere in protobufs
             # service_lowercase_name = service_lowercase_name.replace('playthatfunkymusic', 'toomanyflows')
             service_name = '.'.join(service_lowercase_name.split('.')[:-1])
             while service_name not in dvlt_pool.service_by_name and len(service_name.split('.')) > 1:
                 service_name = '.'.join(service_name.split('.')[:-1])
                 print_info('truncating {} to {}'.format(service_lowercase_name, service_name))
     except IndexError:
         print_error('Service ID {} not in list {}', rep.serviceId, ' '.join(str(self.service_list.services).split('\n')))
         return None
     return service_name
Ejemplo n.º 12
0
 def remove_wu_services(self, wu_removal):
     for srv in wu_removal.services:
         try:
             self.wu_service_list.services.remove(srv)
             m = re.match('tcp://127.0.0.1:([0-9]+)', srv.endpoint)
             truncated_name = '.'.join(srv.name.split('.')[:-1])
             if m is not None:
                 port = int(m.groups()[0])
                 self.services_by_port[port].remove(truncated_name)
                 self.ports_by_service[truncated_name].remove(port)
                 if not self.services_by_port[port]:
                     self.services_by_port.pop(port)
                 if not self.ports_by_service[truncated_name]:
                     self.ports_by_service.pop(truncated_name)
             print_info('WhatsUp service "{}" removed', srv.name)
         except ValueError:
             print_errordata('WhatsUp service could not be removed', srv)
             print_errordata('From list', self.wu_service_list)
Ejemplo n.º 13
0
    def run(self):
        print_info('Searching for Devialet Device...')
        while not self.shutdown_signal:
            ready = select([self.sock], [], [], self.period)
            if self.shutdown_signal:
                break
            if ready[0]:
                data, (sender_addr, sender_port) = self.sock.recvfrom(1024)

                if len(data) >= 12:
                    magic, serial_len = struct.unpack('>8sI', data[:12])
                    serial = data[12:]
                    if magic == b'DVL\x01HERE' and len(
                            data) == 12 + serial_len:
                        if serial not in self.database or self.database[
                                serial] != sender_addr:
                            self.database[serial] = sender_addr
                            print_info(
                                'Found Devialet Device with serial {} at address {}',
                                serial, sender_addr)
                            self.queue.put((serial, sender_addr))
                            if self.callback is not None:
                                self.callback(serial, sender_addr)
                    elif magic == b'DVL\x01BYE!' and len(
                            data) == 12 + serial_len:
                        print_info(
                            'Device with serial {} at address {} exited',
                            serial, sender_addr)
                        self.database.pop(serial)
                    else:
                        print_warning('Unknown data: {}', data.hex())
                        # Warning: Unknown data: 44564c014259452100000010066787a949a24d37a99c26d3ff193a5a
                elif data == b'DVL\x01WHO?':
                    print_info('Got Discovery request')
                else:
                    print_warning('Discovery message too short: {}',
                                  data.hex())
            else:
                if self.advertise:
                    print_info('Advertising...')
                    self.sock.sendto(
                        b'DVL\x01HERE\x00\x00\x00' +
                        bytes([len(self.serial)]) + self.serial,
                        ('255.255.255.255', self.port))
Ejemplo n.º 14
0
 def run(self):
     # self.open()
     timeout = 2
     while not self.shutdown_signal:
         # print_info('One spin of SERVER loop...')
         socks = [s for s, f, c in self.clientsocks.values()] + [self.sock]
         readable, writable, errored = select(socks, [], [], timeout)
         if self.shutdown_signal:
             break
         # if errored:
         #     print_warning('Shutting down server on port {}', self.port)
         #     break
         # print_info('One spin of SERVER loop!')
         for s in readable:
             if s is self.sock:
                 clientsock, (clientaddr, clientport) = self.sock.accept()
                 if self.shutdown_signal:
                     break
                 clientfile = clientsock.makefile(mode='wb')
                 self.clientsocks[(clientaddr,
                                   clientport)] = (clientsock, clientfile,
                                                   False)
                 self.flows[(clientaddr, clientport)] = DevialetFlow(
                     name='{}:{}'.format(clientaddr, clientport),
                     spark_port=self.port,
                     phantom_port=clientport)
                 print_info('Client {} on port {} connected to us!',
                            clientaddr, clientport)
             else:
                 addrport = [
                     a for a, (ss, f, c) in self.clientsocks.items()
                     if ss is s
                 ][0]
                 data = s.recv(2048)
                 # print_warning('data from {}: {}', addr, data)
                 if data:
                     print_info('Received {} on client socket {}',
                                data.hex(), addrport)
                     self.flows[addrport].decode(data, incoming=False)
                     self.find_requests(addrport)
                 else:
                     self.close_client(addrport)
Ejemplo n.º 15
0
    def close(self):
        rest_incoming = self.incoming_buf.read()
        rest_outgoing = self.outgoing_buf.read()

        if rest_incoming:
            self.warnings.append('Found garbage at end of incoming flow: {}...'.format(
                ' '.join('{:02x}'.format(x) for x in rest_incoming[:50])))

        if rest_outgoing:
            self.warnings.append('Found garbage at end of outgoing flow: {}...'.format(
                ' '.join('{:02x}'.format(x) for x in rest_outgoing[:50])))

        if self.warnings:
            print_warning(self.warnings)

        print_info('flow {} has {} incoming and {} outgoing sections',
                   self.name, len(self.incoming_sections), len(self.outgoing_sections))

        self.incoming_buf.close()
        self.outgoing_buf.close()
Ejemplo n.º 16
0
 def try_to_find_service(self, service_name, port=None):
     try:
         ports = self.ports_by_service[service_name]
         if len(ports) > 1:
             print_warning(
                 'More than one possible endpoint match for service {}: {}',
                 service_name, ports)
         if port is None:
             port = ports[0]
         elif port not in ports:
             print_warning('Requested port not in list of matches')
             port = ports[0]
         print_info('Using port {} for service {}', port, service_name)
         svc_class = dvlt_pool.service_by_name[service_name]._concrete_class
         client = DevialetClient(name=service_name + ' client',
                                 port=port,
                                 addr=self.addr)
         return client, svc_class(client)
     except KeyError:
         print_error("Can't find service {} in whatsup services",
                     service_name)
     pass
Ejemplo n.º 17
0
import r2pipe
import os
import json
from google.protobuf.descriptor_pb2 import FileDescriptorProto
import google.protobuf.message
from dvlt_output import print_info, print_error, print_warning

dll_dir = '/path/to/spark_dlls'
out_dir = './protoc_new/'

for filename in os.listdir(dll_dir):
    if filename.endswith('.dll'):
        filename = os.path.join(dll_dir, filename)
        print_info('Exploring file {}...', filename)
        f = open(filename, 'rb').read()
        r2 = r2pipe.open(filename)
        r2.cmd('aaa')
        # print_info('Finished analysis')
        sections = json.loads(r2.cmd('Sj'))
        xrefs = r2.cmd('axF InternalAddGeneratedFile|cut -d" " -f2|sort -u').split()

        def get_paddr(vaddr):
            for section in sections:
                if vaddr >= section['vaddr'] and vaddr < section['vaddr'] + section['size']:
                    return vaddr - section['vaddr'] + section['paddr']
            print_error("Can't find virtual address {}", vaddr)
            return 0

        for xref in xrefs:
            disasm = json.loads(r2.cmd('pdj -2 @ ' + xref))
            if disasm[0]['type'] == 'push' and disasm[1]['type'] == 'push':
Ejemplo n.º 18
0
 def pong(self, empty):
     print_info('Server {} ({}): Pong', self.hostUid, self.port)
     return Devialet.CallMeMaybe.Empty()
Ejemplo n.º 19
0
 def open_connection(self, conn_request):
     print_info('Client trying to open connection, ver {}',
                conn_request.version)
     return Devialet.CallMeMaybe.ConnectionReply(
         serverId=self.serverId, services=self.service_list.services)
Ejemplo n.º 20
0
 def get_host_list(self, empty):
     print_info('Got host list request')
     return Devialet.WhatsUp.WhatsUpHostsList()
Ejemplo n.º 21
0
    def rpc_walk_one_section(self, incoming_section):
        incoming_pb = incoming_section.raw_protobufs

        if incoming_section.magic == 0xC3:
            # Event?
            try:
                evt = dvlt_pool.interpret_as(incoming_pb[0], 'Devialet.CallMeMaybe.Event')
                service_name = self.find_service(evt)

                method, input_pb, outputs_pb = dvlt_pool.process_rpc(service_name, evt, incoming_pb[1], incoming_pb[1:], is_event=True)
                if method.containing_service.full_name == 'Devialet.CallMeMaybe.Connection':
                    if method.name == 'serviceAdded':
                        print_info('Extending list of services')
                        self.service_list.services.add(name=input_pb.name, id=input_pb.id)

                # The 'uid' parameter in the section, when present (== when magic is C3, and only on incoming packets)
                # should be equal to the server ID
                print_info('in_time:{} evt:{} {}/{:>10d}/{:>12d}{:31s} {} E',
                           incoming_section.time,
                           evt.serverId[:4].hex(), evt.type, evt.subTypeId, evt.serviceId,
                           '',
                           incoming_section.uid[:4].hex())
            except IndexError:
                print_error('not enough incoming protos for event ({}) < 2', len(incoming_pb))
            except AttributeError:
                pass

        else:
            try:
                outgoing_section = self.outgoing_sections.popleft()
                outgoing_pb = outgoing_section.raw_protobufs
                req = dvlt_pool.interpret_as(outgoing_pb[0], 'Devialet.CallMeMaybe.Request')
                rep = dvlt_pool.interpret_as(incoming_pb[0], 'Devialet.CallMeMaybe.Reply')
                bad_reqs = deque()

                # print('UUID {}'.format(req.requestId.hex()))

                # (First two bytes (or more) of request id appear to be sequential)
                while rep.requestId != req.requestId:
                    bad_reqs.appendleft(outgoing_section)
                    print_warning('Request id {} out of order', req.requestId.hex())
                    # print_errordata('Full Request:', req)
                    try:
                        outgoing_section = self.outgoing_sections.popleft()
                        outgoing_pb = outgoing_section.raw_protobufs
                        req = dvlt_pool.interpret_as(outgoing_pb[0], 'Devialet.CallMeMaybe.Request')
                    except IndexError:
                        # Reached end of outgoing_sections
                        # print_error("Couldn't find request for reply {}", rep.requestId.hex())
                        break
                self.outgoing_sections.extendleft(bad_reqs)

                if not rep.isMultipart and len(incoming_pb) > 2:
                    print_warning('we got more incoming protobufs than we should have, not Multipart')

                if len(outgoing_pb) > 2:
                    print_error('we got more than 2 outgoing protobufs')

                if len(outgoing_pb) < 2:
                    print_error('we got less than 2 outgoing protobufs')

                if len(incoming_pb) < 2:
                    print_error('we got less than 2 incoming protobufs')

                service_name = self.find_service(rep)
                method, input_pb, outputs_pb = dvlt_pool.process_rpc(
                    service_name, rep, outgoing_pb[1], incoming_pb[1:])

                if method.containing_service.full_name == 'Devialet.CallMeMaybe.Connection':
                    if method.name == 'openConnection':
                        self.service_list = outputs_pb[0]

                print_info('out_time:{} in_time:{} req:{}/{}/{:>10d}/{:>12d}, rep:{}/{}/{:>10d}/{:>12d} {}{}{}',
                           outgoing_section.time, incoming_section.time,
                           req.requestId[:4].hex(), req.type, req.subTypeId, req.serviceId, rep.requestId[:4].hex(), rep.type, rep.subTypeId, rep.serviceId,
                           'M' if rep.isMultipart else ' ',
                           ' ' if method.name == 'ping' else 'C' if method.name == 'openConnection' else '.',
                           '<' if rep.requestId != req.requestId else ' ')

            except IndexError:
                print_error('Stream ended prematurely, missing outgoing section')
            except Exception as e:
                print_error('Unexpected {} {}', type(e), e)
Ejemplo n.º 22
0
    def find_requests(self, addrport):
        flow = self.flows[addrport]
        while flow.outgoing_sections:
            outgoing_section = flow.outgoing_sections.popleft()
            outgoing_pb = outgoing_section.raw_protobufs

            # print_warning("Found Request")
            req = Devialet.CallMeMaybe.Request.FromString(outgoing_pb[0])
            if req.serverId != self.serverId and req.serverId != b'\x00' * 16:
                print_warning(
                    'Oops, this request is not for us (unless this is inital conenction request): we are {}, sent to {}',
                    self.serverId.hex(), req.serverId.hex())
            try:
                srv = self.services[req.serviceId]
                if req.type == 0:
                    try:
                        method_desc = srv.methods_by_id[req.subTypeId]
                        if method_desc.full_name in self.request_callbacks:
                            (request_class, callback
                             ) = self.request_callbacks[method_desc.full_name]
                            response = callback(
                                request_class.FromString(outgoing_pb[1]))
                            rep = Devialet.CallMeMaybe.Reply(
                                serverId=self.serverId,
                                serviceId=req.serviceId,
                                requestId=req.requestId,
                                type=0,
                                subTypeId=req.subTypeId,
                                errorCode=0,
                                isMultipart=False)
                            self.write_response_to_addr(
                                addrport, rep.SerializeToString(),
                                response.SerializeToString())
                        else:
                            print_error('Unhandled method {} from {}',
                                        method_desc.full_name, addrport)

                    except KeyError:
                        print_errordata(
                            'Method id {} not in service method dict:'.format(
                                req.subTypeId), {
                                    k: v.full_name
                                    for (k, v) in srv.methods_by_id.items()
                                })
                elif req.type == 1 and req.subTypeId == 0xFFFFFFFF:
                    # PropertyGet special request
                    rep = Devialet.CallMeMaybe.Reply(serverId=self.serverId,
                                                     serviceId=req.serviceId,
                                                     requestId=req.requestId,
                                                     type=1,
                                                     subTypeId=0xFFFFFFFF,
                                                     errorCode=0,
                                                     isMultipart=True)
                    print_info('Got PropertyGet request:')
                    for name, prop in srv.properties.items():
                        print_data(name, prop)
                    self.write_responses_to_addr(
                        addrport, rep.SerializeToString(),
                        [p.SerializeToString() for p in srv.get_properties()])
                elif req.type == 1:
                    # PropertySet special request
                    # TODO
                    print_errordata(
                        'Unhandled propertyset subtypeId={}'.format(
                            req.subTypeId), [x.hex() for x in outgoing_pb])
                    pass
                else:
                    print_error('Unknown request type {}', req.type)
            except KeyError:
                print_error(
                    'Service ID {} not in list {}', req.serviceId,
                    ' '.join(str(self.service_list.services).split('\n')))

        self.flows[addrport].outgoing_sections.clear()
Ejemplo n.º 23
0
# tmf_client.keep_receiving()

# Init WhatsUp server
wu_srv = WhatsUpServer(hostUid=hostUid)
wu_srv.open()
dscvr.start_advertising()
wu_srv.start()


def pingback(arg):
    print_info("Pong <--")


try:
    while True:  # ~ 20 ms round-trip for pings
        time.sleep(1)
        print_info("Ping -->")
        wu_client.conn.ping(DevialetController(wu_client.conn),
                            Devialet.CallMeMaybe.Empty(), pingback)
except KeyboardInterrupt:
    wu_client.shutdown()
    wu_srv.shutdown()
    dscvr.shutdown()

    print_info('join()ing client...')
    wu_client.join()
    print_info('join()ing server...')
    wu_srv.join()
    print_info('join()ing discovery..')
    dscvr.join()
Ejemplo n.º 24
0
def pingback(arg):
    print_info("Pong <--")
Ejemplo n.º 25
0
 def add_service(self, service):
     print_info("New Service added: {}", service.name)
     self.service_list.services.extend([service])
Ejemplo n.º 26
0
import sys
from datetime import datetime
from collections import deque
from dvlt_output import print_warning, print_info, print_error, print_data
from dvlt_decode import DevialetManyFlows, DevialetFlow

print_info('Loading scapy...')
from scapy.all import *


class SeqData:
    def __init__(self):
        self.seq = 0
        self.isn = 0
        self.ood = deque()


class PcapFlows(DevialetManyFlows):
    def __init__(self, filename, spark_addr, phantom_addr, decode_by_flow=False):
        DevialetManyFlows.__init__(self)
        self.filename = filename
        self.spark_addr = spark_addr
        self.phantom_addr = phantom_addr
        self.decode_by_flow = decode_by_flow

        # print_info('Loading file...')
        # capture = scapy.all.rdpcap(filename)
        # self.sessions = capture[TCP].sessions()
        with PcapReader(filename) as pcap_reader:
            for packet in pcap_reader:
                # print(packet)
Ejemplo n.º 27
0
 def remove_service(self, service):
     print_info("Service {} removed", service.name)
     self.service_list.services.remove(service)
Ejemplo n.º 28
0
 def unblock_call(self, response):
     self.blocking_response = response
     print_info('Unblocking')
     self.blocked.set()
Ejemplo n.º 29
0
    def __init__(self, filename, spark_addr, phantom_addr, decode_by_flow=False):
        DevialetManyFlows.__init__(self)
        self.filename = filename
        self.spark_addr = spark_addr
        self.phantom_addr = phantom_addr
        self.decode_by_flow = decode_by_flow

        # print_info('Loading file...')
        # capture = scapy.all.rdpcap(filename)
        # self.sessions = capture[TCP].sessions()
        with PcapReader(filename) as pcap_reader:
            for packet in pcap_reader:
                # print(packet)
                if packet.haslayer(TCP):
            # for packet in capture[TCP]:
                    time = datetime.fromtimestamp(packet.time)
                    # print(packet)
                    # if packet.
                    spark_port = -1
                    if packet[IP].src == self.spark_addr and packet[IP].dst == self.phantom_addr:
                        spark_port = packet[TCP].sport
                        phantom_port = packet[TCP].dport
                        phantom_to_spark = False
                    elif packet[IP].src == self.phantom_addr and packet[IP].dst == self.spark_addr:
                        spark_port = packet[TCP].dport
                        phantom_port = packet[TCP].sport
                        phantom_to_spark = True
                    if spark_port >= 0:
                        if (phantom_port, spark_port) in self.flows:
                            flow = self.flows[(phantom_port, spark_port)]
                        else:
                            print_warning('New Flow phantom {}, spark {}, time {}', phantom_port, spark_port, time)
                            flow = DevialetFlow(name='phantom {}, spark {}'.format(phantom_port, spark_port),
                                                phantom_port=phantom_port, spark_port=spark_port, start_time=time)
                            flow.phantom = SeqData()
                            flow.spark = SeqData()
                            # if first packet is from phantom to spark, rpc server is probably spark
                            if phantom_to_spark:
                                print_info('Found flow where Spark appears to be RPC server: phantom {}, spark {}',
                                           phantom_port, spark_port)
                                flow.rpc_server_is_phantom = False
                            self.add_flow(flow)
                        # Reverse direction if rpc server is Spark
                        srv_to_client = phantom_to_spark ^ (not flow.rpc_server_is_phantom)
                        tcplen = packet[IP].len - packet[IP].ihl*4 - packet[TCP].dataofs*4
                        sending = (flow.phantom if phantom_to_spark else flow.spark)
                        receiving = (flow.spark if phantom_to_spark else flow.phantom)

                        if 'S' in packet.sprintf('%TCP.flags%') or 'F' in packet.sprintf('%TCP.flags%'):
                            # if SYN, synchronize sequence numbers
                            print_info('Sp {:6d} {} Ph {:6d} Len {:5d} Seq {:12d} Ack {:12d} Diff {:12d} Flags {}',
                                       spark_port, '<- ' if phantom_to_spark else ' ->', phantom_port, tcplen,
                                       packet[TCP].seq - sending.isn,
                                       packet[TCP].ack - receiving.isn,
                                       0, packet.sprintf('%TCP.flags%'),
                                       color='red')
                            sending.isn = packet[TCP].seq
                            sending.seq = packet[TCP].seq + 1
                            if sending.ood:
                                print_error('{} remaining in {} OOD queue', len(sending.ood),
                                            'Phantom' if phantom_to_spark else 'Spark')
                                sending.ood.clear()
                        else:
                            # print(packet[TCP].load[:12].hex())
                            diff = packet[TCP].seq - sending.seq
                            print_info('Sp {:6d} {} Ph {:6d} Len {:5d} Seq {:12d} Ack {:12d} Diff {:12d} Flags {}',
                                       spark_port, '<- ' if phantom_to_spark else ' ->', phantom_port, tcplen,
                                       packet[TCP].seq - sending.isn,
                                       packet[TCP].ack - receiving.isn,
                                       diff, packet.sprintf('%TCP.flags%'),
                                       color='blue' if phantom_to_spark else 'green',
                                       reverse=(diff != 0))
                            if diff == 0:
                                sending.seq = packet[TCP].seq + tcplen
                                if tcplen:
                                    flow.decode(packet[TCP].load[:tcplen], time=time, incoming=srv_to_client)
                                    if not self.decode_by_flow:
                                        flow.rpc_walk(verbose=False)
                                for p in list(sending.ood):
                                    l = p[IP].len - p[IP].ihl*4 - p[TCP].dataofs*4
                                    d = p[TCP].seq - sending.seq
                                    if d == 0:
                                        sending.seq = p[TCP].seq + l
                                        if l:
                                            flow.decode(p[TCP].load[:l], time=time, incoming=srv_to_client)
                                            if not self.decode_by_flow:
                                                flow.rpc_walk(verbose=False)
                                        sending.ood.remove(p)
                                        print_info('Sp {:6d} {} Ph {:6d} Len {:5d} Seq {:12d} Ack {:12d} Diff {:12d} Flags {:3} Reordered',
                                                   spark_port, '<- ' if phantom_to_spark else ' ->', phantom_port, l,
                                                   p[TCP].seq - sending.isn, p[TCP].ack - receiving.isn,
                                                   d, p.sprintf('%TCP.flags%'), color='magenta')
                                    else:
                                        # print_warning('{:6d} {} Ph {:6d} Len {:5d} Seq {:12d} Ack {:12d} Diff {:12d} Flags {:3} OOD',
                                        #               spark_port, '<- ' if phantom_to_spark else ' ->', phantom_port, l,
                                        #               p[TCP].seq - sending.isn, p[TCP].ack - receiving.isn,
                                        #               d, p.sprintf('%TCP.flags%'))
                                        pass
                            else:
                                sending.ood.append(packet)
Ejemplo n.º 30
0
            Devialet.TooManyFlows.TrackMsg(index=0, url=trackURL)
        ]), callback_test))

# tmf_playlist.tracksAdded(DevialetController(tmf_playlist), None, lambda empty: tmf_playback.play(
#     DevialetController(tmf_playback), Devialet.CallMeMaybe.Empty(), callback_test))

tmf_meta.propertyUpdate(
    DevialetController(tmf_meta), None,
    lambda empty: tmf_playback.play(DevialetController(
        tmf_playback), Devialet.CallMeMaybe.Empty(), callback_test))

# GO
tmf_playlist.clear(DevialetController(tmf_playlist),
                   Devialet.CallMeMaybe.Empty(), callback_test)

print_info('Successfully cleared playlist', color='green')
# tmf_client.shutdown()

# time.sleep(3)

# time.sleep(10)
print_info('Successfully pressed play', color='green')


def pingback(arg):
    print_info("Pong <--")


try:
    while True:  # ~ 20 ms round-trip for pings
        time.sleep(1)