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
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
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))
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
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))
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
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))
def __str__(self): return '{} {} {}'.format(str(self.struc.ethheader), str(self.struc.c24header), hexl(self.struc.packetdata))
def __str__(self): return 'BCAST d:{} v:{} u1:{}'.format(self.device, self.version, hexl(self.unknown1))
def __str__(self): return 'to:{} from:{} {} prot:{}'.format(hexl(self.macdest), hexl(self.macsrc.vendor), hexl(self.macsrc.device), hexl(self.protocol))