コード例 #1
0
ファイル: control24d.py プロジェクト: tormodvm/ReaControl24
def pcap_packet_tostring(pcp):
    msg = 'to:{} from:{} {} prot:{} data:{}'.format(
        hexl(pcp.struc.ethheader.macdest),
        hexl(pcp.struc.ethheader.macsrc.vendor),
        hexl(pcp.struc.ethheader.macsrc.device),
        hexl(pcp.struc.ethheader.protocol), hexl(pcp.struc.packetdata))
    return msg
コード例 #2
0
ファイル: control24d.py プロジェクト: tormodvm/ReaControl24
def pcap_packetr_tostring(pcp):
    msg = 'to:{} from:{} {} prot:{} b:{} c:{} r:{} nc:{} data:{}'.format(
        hexl(pcp.struc.ethheader.macdest),
        hexl(pcp.struc.ethheader.macsrc.vendor),
        hexl(pcp.struc.ethheader.macsrc.device),
        hexl(pcp.struc.ethheader.protocol), pcp.struc.c24header.numbytes,
        pcp.struc.c24header.cmdcounter, pcp.struc.c24header.retry,
        pcp.struc.numcommands, hexl(pcp.struc.packetdata))
    return msg
コード例 #3
0
 def receive_handler(self, buff, ncmds, buffsz):
     LOG.debug('MP recv: c:%d s:%d d:%s', ncmds, buffsz,
               hexl(buff[:buffsz]))
     pkt_data_len = buffsz  # len(buff)
     pkt_data = (c_ubyte * pkt_data_len).from_buffer_copy(buff)
     totalwait = 0.0
     while not self.sendlock.wait(TIMING_WAIT_DESC_ACK):
         totalwait += TIMING_WAIT_DESC_ACK
         LOG.warn('Waiting for DESK ACK %d', totalwait)
         #TODO implement daw-desk retry packets
     LOG.debug('TODESK CMD %d', self.sendcounter)
     if not self.mac_control24 is None:
         packet = self._prepare_packetr(pkt_data, pkt_data_len, ncmds)
         self.send_packet(packet)
         self.sendlock.clear()
     else:
         LOG.warn(
             'MP received but no desk to send to. Establish a session. %s',
             hexl(pkt_data))
コード例 #4
0
 def send_packet(self, pkt):
     """sesion wrapper around pcap_sendpacket
     so we can pass in session and trap error"""
     LOG.debug("Sending Packet of %d bytes: %s", pkt.pkt_tot_len,
               hexl(pkt.raw))
     buf = pkt.to_buffer()
     pcap_status = self.pcap_sess.sendpacket(buf)
     if pcap_status != pkt.pkt_tot_len:
         LOG.warn("Error sending packet: %s", self.pcap_sess.geterr())
     else:
         self.pcap_last_sent = tick()
         self.pcap_last_packet = pkt
コード例 #5
0
ファイル: control24d.py プロジェクト: tormodvm/ReaControl24
    def _packet_handler(self, param, header, pkt_data):
        """PCAP Packet Handler: Async method called on packet capture"""
        broadcast = False
        # build a dynamic class and load the data into it
        pcl = c24packet_factory(header.contents.len)
        pcp = POINTER(pcl)
        #TODO try loading right into raw
        packet = cast(pkt_data, pcp).contents

        #Detailed traffic logging
        #LOG.debug('l:%d %s', int(header.contents.len),
        #          hexl(packet))

        # Decode any broadcast packets
        if compare_ctype_array(packet.struc.ethheader.macdest.vendor,
                               C_BROADCAST):
            broadcast = True
            pbp = POINTER(C24BcastData)
            bcast_data = cast(packet.struc.packetdata, pbp).contents
            LOG.debug('%s', pcap_packetb_tostring(bcast_data))

        if self.mac_control24 is None:
            macsrc = packet.struc.ethheader.macsrc
            if broadcast and compare_ctype_array(macsrc.vendor, C_VENDOR):
                LOG.info('Control24 Broadcast detected from: %s', hexl(macsrc))
                # copy the mac address from the packet to the session
                self.mac_control24 = MacAddress.from_buffer_copy(macsrc)
                self.ack.struc.ethheader.macdest = self.mac_control24
                #TODO extractmethod
                init1 = AckPacket()
                init1.struc.ethheader = self.ack.struc.ethheader
                init1.struc.c24header.sendcounter = 1
                init1.struc.c24header.numbytes = 0x10
                init1.struc.ayoh = 0xE2
                # second init packet
                init2data = (c_ubyte * 15)(0xF0, 0x13, 0x01, 0x30, 0x19, 0x00,
                                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                           0x00, 0x00, 0xf7)
                init2 = self._prepare_packetr(init2data, 15, 1,
                                              (c_ubyte * 2)(0x02, 0x44))
                #init2[0].struc.c24header.unknown1 = (c_ubyte * 2)(0x02, 0x44)
                self._send_packet(init1.raw, 31)
                self._send_packet(*init2)
        else:
            if int(header.contents.len) > 30 and not broadcast:

                # Look first to see if this is an ACK
                # indicated by finding the 0xA) byte in the number of commands/control commands byte
                if packet.struc.numcommands == 0xa000:
                    LOG.debug('FROMDESK ACK')
                    if not self.backoff.is_alive():
                        self.sendlock.set()
                else:
                    # At this point an ACK is pending so lock all sending
                    self.sendlock.clear()
                    # Check to see if this is retry
                    retry = packet.struc.c24header.retry
                    self.current_retry_desk = retry
                    if retry != 0:
                        LOG.warn('Retry packets from desk: %d', retry)
                        # While ironing out kinks, we will kick into debug logging
                        # if we see retry packets to try and determine why
                        # LOG.LOGLEVEL = logging.DEBUG
                        # Try a send lock if desk is panicking, back off for a
                        # bit of time to let 'er breathe
                        self.sendlock.clear()
                        self.backoff = threading.Timer(TIMING_BACKOFF,
                                                       self._backoff)
                        self.backoff.start()
                    if packet.struc.packetdata[0] in ECHOCMDS:
                        cmdnumber = packet.struc.c24header.sendcounter
                        #TODO need an updated str method
                        #LOG.debug('Packet: %s', pcap_packetr_tostring(packet.struc))
                        LOG.debug('FROMDESK %d', cmdnumber)
                        # this counter changes to the value the DESK sends to us so we can ACK it
                        self.cmdcounter = cmdnumber
                        if not self.mp_conn is None:
                            try:
                                self.mp_conn.send_bytes(
                                    packet.struc.packetdata)
                            except (IOError, EOFError):
                                # Client broke the pipe?
                                LOG.info('MP Listener broken pipe from %s',
                                         self.mp_listener.last_accepted)
                                self.mp_conn.close()
                                self.mp_is_connected = False
                                self.mp_conn = None
                        #sleept = TIMING_BEFORE_ACK_INCR * self.current_retry_desk + TIMING_BEFORE_ACKT
                        #TODO short circuit this for a while
                        sleept = TIMING_BEFORE_ACKT
                        LOG.debug('TODESK ACK: %d %f', self.cmdcounter, sleept)
                        time.sleep(sleept)
                        self._send_packet(*self._prepare_ackt())
                        if not self.backoff.is_alive():
                            self.sendlock.set()
                    else:
                        LOG.warn('FROMDESK unhandled :%02x',
                                 packet.struc.packetdata[0])
                        LOG.debug('     unhandled: %s', hexl(packet.raw))
コード例 #6
0
ファイル: control24d.py プロジェクト: tormodvm/ReaControl24
 def __str__(self):
     msg = 'to:{} from:{} {} prot:{} data:{}'.format(
         hexl(self.macdest), hexl(self.macsrc.vendor),
         hexl(self.macsrc.device), hexl(self.protocol),
         hexl(self.packetdata))
     return msg
コード例 #7
0
 def packet_handler(self, timestamp, pkt_data):
     """PCAP Packet Handler: Async method called on packet capture"""
     broadcast = False
     pkt_len = len(pkt_data)
     # build a dynamic class and load the data into it
     pcl = c24packet_factory(prm_tot_len=pkt_len)
     packet = pcl()
     packet = pcl.from_buffer_copy(pkt_data)
     #Detailed traffic logging
     LOG.debug('Packet Received: %s', str(packet))
     # Decode any broadcast packets
     if packet.is_broadcast():
         broadcast = True
         pbp = POINTER(C24BcastData)
         bcast_data = cast(packet.struc.packetdata, pbp).contents
         LOG.debug('%s', str(bcast_data))
     if self.mac_control24 is None:
         macsrc = packet.struc.ethheader.macsrc
         if broadcast and macsrc.is_vendor():
             LOG.info('Desk detected: %s %s at %s', bcast_data.device,
                      bcast_data.version, hexl(macsrc))
             # copy the mac address from the packet to the session
             self.mac_control24 = MacAddress.from_buffer_copy(macsrc)
             self.ethheader.macdest = self.mac_control24
             # initialise the desk by sending the init command
             # and wiping the clock display
             init1 = self._prepare_packetr(None,
                                           0,
                                           0,
                                           c24cmd=COMMANDS['online'])
             init2data = (c_ubyte * 15)(0xF0, 0x13, 0x01, 0x30, 0x19, 0x00,
                                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                        0x00, 0x00, 0xf7)
             init2 = self._prepare_packetr(init2data, 15, 1,
                                           (c_ubyte * 2)(0x02, 0x44))
             self.send_packet(init1)
             self.send_packet(init2)
     else:
         if pkt_len > 30 and not broadcast:
             # Look first to see if this is an ACK
             if packet.struc.c24header.c24cmd == COMMANDS['ack']:
                 LOG.debug('FROMDESK ACK')
                 if not self.backoff.is_alive():
                     self.sendlock.set()
             else:
                 # At this point an ACK is pending so lock all sending
                 self.sendlock.clear()
                 # Check to see if this is retry
                 if packet.is_retry():
                     self.current_retry_desk = retry = packet.struc.c24header.retry
                     LOG.warn('Retry packets from desk: %d', retry)
                     # Try a send lock if desk is panicking, back off for a
                     # bit of time to let 'er breathe
                     self.sendlock.clear()
                     self.backoff = threading.Timer(TIMING_BACKOFF,
                                                    self._backoff)
                     self.backoff.start()
                 if packet.struc.c24header.numcommands > 0:
                     cmdnumber = packet.struc.c24header.sendcounter
                     LOG.debug('FROMDESK %d', cmdnumber)
                     # this counter changes to the value the DESK sends to us so we can ACK it
                     self.cmdcounter = cmdnumber
                     # forward it to the Multiprocessing clients
                     self.thread_listener.mpsend(packet.struc.packetdata)
                     LOG.debug('TODESK ACK: %d', self.cmdcounter)
                     time.sleep(TIMING_BEFORE_ACKT)
                     self.send_packet(self._prepare_ackt())
                     if not self.backoff.is_alive():
                         self.sendlock.set()
                 else:
                     LOG.warn('FROMDESK unhandled :%02x',
                              packet.struc.packetdata[0])
                     LOG.debug('     unhandled: %s', hexl(packet.raw))
コード例 #8
0
 def __str__(self):
     return '{} {} {}'.format(str(self.struc.ethheader),
                              str(self.struc.c24header),
                              hexl(self.struc.packetdata))
コード例 #9
0
 def __str__(self):
     return 'BCAST d:{} v:{} u1:{}'.format(self.device, self.version,
                                           hexl(self.unknown1))
コード例 #10
0
 def __str__(self):
     return 'to:{} from:{} {} prot:{}'.format(hexl(self.macdest),
                                              hexl(self.macsrc.vendor),
                                              hexl(self.macsrc.device),
                                              hexl(self.protocol))