def confirmation(self, pdu): if _debug: SnifferNode._debug("confirmation(%s) %r", self.name, pdu) # it's an NPDU npdu = NPDU() npdu.decode(pdu) # decode as a generic APDU apdu = APDU() apdu.decode(npdu) # "lift" the source and destination address if npdu.npduSADR: apdu.pduSource = npdu.npduSADR else: apdu.pduSource = npdu.pduSource if npdu.npduDADR: apdu.pduDestination = npdu.npduDADR else: apdu.pduDestination = npdu.pduDestination # make a more focused interpretation atype = apdu_types.get(apdu.apduType) if _debug: SnifferNode._debug(" - atype: %r", atype) xpdu = apdu apdu = atype() apdu.decode(xpdu) print(repr(apdu)) apdu.debug_contents() print("")
def response(self, response_apdu, npdu, bvlpdu, address): if response_apdu is None: return apdu = APDU() response_apdu.encode(apdu) apdu.encode(npdu) npdu.encode(bvlpdu) pdu = PDU() bvlpdu.bvlciLength = len(bvlpdu.pduData) + 4 bvlpdu.encode(pdu) apdu_type = apdu_types.get(response_apdu.apduType) if isinstance(response_apdu, RejectPDU) or isinstance( response_apdu, ErrorPDU): self.datagram_server.sendto(pdu.pduData, address) logger.info('Bacnet Error or Reject response sent to %s (%s:%s)', response_apdu.pduDestination, apdu_type.__name__, self._response_service) else: if pdu.pduDestination == '*:*': # broadcast # sendto operates under lock self.datagram_server.sendto(pdu.pduData, ('', address[1])) else: # sendto operates under lock self.datagram_server.sendto(pdu.pduData, address) logger.info('Bacnet response sent to %s (%s:%s)', response_apdu.pduDestination, apdu_type.__name__, self._response_service)
def response(self, response_apdu, address): if response_apdu is None: return apdu = APDU() response_apdu.encode(apdu) pdu = PDU() apdu.encode(pdu) if isinstance(response_apdu, RejectPDU) or isinstance( response_apdu, ErrorPDU): self.datagram_server.sendto(pdu.pduData, address) else: apdu_type = apdu_types.get(response_apdu.apduType) if pdu.pduDestination == "*:*": # broadcast # sendto operates under lock self.datagram_server.sendto(pdu.pduData, ("", address[1])) else: # sendto operates under lock self.datagram_server.sendto(pdu.pduData, address) logger.info( "Bacnet response sent to %s (%s:%s)", response_apdu.pduDestination, apdu_type.__name__, self._response_service, )
def response(self, response_apdu, address): if response_apdu is None: return apdu = APDU() response_apdu.encode(apdu) pdu = PDU() apdu.encode(pdu) if isinstance(response_apdu, RejectPDU) or isinstance(response_apdu, ErrorPDU): self.datagram_server.sendto(pdu.pduData, address) else: apdu_type = apdu_types.get(response_apdu.apduType) if pdu.pduDestination == '*:*': # broadcast # sendto operates under lock self.datagram_server.sendto(pdu.pduData, ('', address[1])) else: # sendto operates under lock self.datagram_server.sendto(pdu.pduData, address) logger.info('Bacnet response sent to %s (%s:%s)', response_apdu.pduDestination, apdu_type.__name__, self._response_service)
def response(self, response_apdu, address): if response_apdu is None: return apdu = APDU() response_apdu.encode(apdu) pdu = PDU() apdu.encode(pdu) if isinstance(response_apdu, RejectPDU) or isinstance(response_apdu, ErrorPDU): self.sock.sendto(pdu.pduData, address) else: apdu_type = apdu_types.get(response_apdu.apduType) if pdu.pduDestination == '*:*': # broadcast self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) self.sock.sendto(pdu.pduData, ('', address[1])) else: # unicast self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 0) self.sock.sendto(pdu.pduData, address) logger.info('Bacnet response sent to %s (%s:%s)', response_apdu.pduDestination, apdu_type.__name__, self._response_service)
def confirmation(self, pdu): if _debug: SnifferStateMachine._debug("confirmation(%s) %r", self.name, pdu) # it's an NPDU npdu = NPDU() npdu.decode(pdu) # filter out network layer traffic if there is any, probably not if npdu.npduNetMessage is not None: if _debug: SnifferStateMachine._debug(" - network message: %r", npdu.npduNetMessage) return # decode as a generic APDU apdu = APDU() apdu.decode(npdu) # "lift" the source and destination address if npdu.npduSADR: apdu.pduSource = npdu.npduSADR else: apdu.pduSource = npdu.pduSource if npdu.npduDADR: apdu.pduDestination = npdu.npduDADR else: apdu.pduDestination = npdu.pduDestination # make a more focused interpretation atype = apdu_types.get(apdu.apduType) if _debug: SnifferStateMachine._debug(" - atype: %r", atype) xpdu = apdu apdu = atype() apdu.decode(xpdu) if _debug: SnifferStateMachine._debug(" - apdu: %r", apdu) # pass to the state machine self.receive(apdu)
def indication(self, apdu, address, device): """logging the received PDU type and Service request""" request = None apdu_type = apdu_types.get(apdu.apduType) invoke_key = apdu.apduInvokeID logger.info('Bacnet PDU received from %s:%d. (%s)', address[0], address[1], apdu_type.__name__) if apdu_type.pduType == 0x0: # Confirmed request handling apdu_service = confirmed_request_types.get(apdu.apduService) logger.info('Bacnet indication from %s:%d. (%s)', address[0], address[1], apdu_service.__name__) try: request = apdu_service() request.decode(apdu) except (AttributeError, RuntimeError, InvalidParameterDatatype) as e: logger.warning( 'Bacnet indication: Invalid service. Error: %s' % e) return except bacpypes.errors.DecodingError: pass for key, value in list( ConfirmedServiceChoice.enumerations.items()): if apdu_service.serviceChoice == value: try: getattr(self, key)(request, address, invoke_key, device) break except AttributeError: logger.error('Not implemented Bacnet command') self._response = None return else: logger.info( 'Bacnet indication: Invalid confirmed service choice (%s)', apdu_service.__name__) self._response = None return # Unconfirmed request handling elif apdu_type.pduType == 0x1: apdu_service = unconfirmed_request_types.get(apdu.apduService) logger.info('Bacnet indication from %s:%d. (%s)', address[0], address[1], apdu_service.__name__) try: request = apdu_service() request.decode(apdu) except (AttributeError, RuntimeError): logger.exception('Bacnet indication: Invalid service.') self._response = None return except bacpypes.errors.DecodingError: pass for key, value in list( UnconfirmedServiceChoice.enumerations.items()): if apdu_service.serviceChoice == value: try: getattr(self, key)(request, address, invoke_key, device) break except AttributeError: logger.error('Not implemented Bacnet command') self._response = None return else: # Unrecognized services logger.info( 'Bacnet indication: Invalid unconfirmed service choice (%s)', apdu_service) self._response_service = 'ErrorPDU' self._response = ErrorPDU() self._response.pduDestination = address return # ignore the following elif apdu_type.pduType == 0x2: # simple ack pdu self._response = None return elif apdu_type.pduType == 0x3: # complex ack pdu self._response = None return elif apdu_type.pduType == 0x4: # segment ack self._response = None return elif apdu_type.pduType == 0x5: # error pdu self._response = None return elif apdu_type.pduType == 0x6: # reject pdu self._response = None return elif apdu_type.pduType == 0x7: # abort pdu self._response = None return elif 0x8 <= apdu_type.pduType <= 0xf: # reserved self._response = None return else: # non-BACnet PDU types logger.info('Bacnet Unrecognized service') self._response = None return
def indication(self, apdu, address, device): """logging the received PDU type and Service request""" request = None apdu_type = apdu_types.get(apdu.apduType) invoke_key = apdu.apduInvokeID logger.info('Bacnet PDU received from %s:%d. (%s)', address[0], address[1], apdu_type.__name__) if apdu_type.pduType == 0x0: # Confirmed request handling apdu_service = confirmed_request_types.get(apdu.apduService) logger.info('Bacnet indication from %s:%d. (%s)', address[0], address[1], apdu_service.__name__) try: request = apdu_service() request.decode(apdu) except (AttributeError, RuntimeError, InvalidParameterDatatype) as e: logger.warning('Bacnet indication: Invalid service. Error: %s' % e) return except bacpypes.errors.DecodingError: pass for key, value in list(ConfirmedServiceChoice.enumerations.items()): if apdu_service.serviceChoice == value: try: getattr(self, key)( request, address, invoke_key, device) break except AttributeError: logger.error('Not implemented Bacnet command') self._response = None return else: logger.info('Bacnet indication: Invalid confirmed service choice (%s)', apdu_service.__name__) self._response = None return # Unconfirmed request handling elif apdu_type.pduType == 0x1: apdu_service = unconfirmed_request_types.get(apdu.apduService) logger.info('Bacnet indication from %s:%d. (%s)', address[0], address[1], apdu_service.__name__) try: request = apdu_service() request.decode(apdu) except (AttributeError, RuntimeError): logger.exception('Bacnet indication: Invalid service.') self._response = None return except bacpypes.errors.DecodingError: pass for key, value in list(UnconfirmedServiceChoice.enumerations.items()): if apdu_service.serviceChoice == value: try: getattr(self, key)( request, address, invoke_key, device) break except AttributeError: logger.error('Not implemented Bacnet command') self._response = None return else: # Unrecognized services logger.info( 'Bacnet indication: Invalid unconfirmed service choice (%s)', apdu_service) self._response_service = 'ErrorPDU' self._response = ErrorPDU() self._response.pduDestination = address return # ignore the following elif apdu_type.pduType == 0x2: # simple ack pdu self._response = None return elif apdu_type.pduType == 0x3: # complex ack pdu self._response = None return elif apdu_type.pduType == 0x4: # segment ack self._response = None return elif apdu_type.pduType == 0x5: # error pdu self._response = None return elif apdu_type.pduType == 0x6: # reject pdu self._response = None return elif apdu_type.pduType == 0x7: # abort pdu self._response = None return elif 0x8 <= apdu_type.pduType <= 0xf: # reserved self._response = None return else: # non-BACnet PDU types logger.info('Bacnet Unrecognized service') self._response = None return
def decode_packet(data, destination): """decode the data, return some kind of PDU.""" if _debug: decode_packet._debug("decode_packet %r %r", data, destination) # build a PDU pdu = PDU(data, destination=destination) # check for a BVLL header if pdu.pduData[0] == 0x84: if _debug: decode_packet._debug(" - BVLL header found") xpdu = BVLPDU() xpdu.decode(pdu) pdu = xpdu # make a more focused interpretation atype = bvl_pdu_types.get(pdu.bvlciFunction) if not atype: if _debug: decode_packet._debug(" - unknown BVLL type: %r", pdu.bvlciFunction) return pdu # decode it as one of the basic types try: xpdu = pdu bpdu = atype() bpdu.decode(pdu) if _debug: decode_packet._debug(" - bpdu: %r", bpdu) pdu = bpdu # source address in the packet pdu.pduSource = pdu.bvlciAddress # no deeper decoding for some if atype not in (OriginalUnicastNPDU, OriginalBroadcastNPDU): return pdu except Exception as err: if _debug: decode_packet._debug(" - decoding Error: %r", err) return xpdu # check for version number if pdu.pduData[0] != 0x01: if _debug: decode_packet._debug( " - not a version 1 packet: %s...", btox(pdu.pduData[:30], ".") ) return None # it's an NPDU try: npdu = NPDU() npdu.decode(pdu) except Exception as err: if _debug: decode_packet._debug(" - decoding Error: %r", err) return None # application or network layer message if npdu.npduNetMessage is None: if _debug: decode_packet._debug(" - not a network layer message, try as an APDU") # decode as a generic APDU try: xpdu = APDU() xpdu.decode(npdu) apdu = xpdu except Exception as err: if _debug: decode_packet._debug(" - decoding Error: %r", err) return npdu # "lift" the source and destination address if npdu.npduSADR: apdu.pduSource = npdu.npduSADR else: apdu.pduSource = npdu.pduSource if npdu.npduDADR: apdu.pduDestination = npdu.npduDADR else: apdu.pduDestination = npdu.pduDestination # make a more focused interpretation atype = apdu_types.get(apdu.apduType) if not atype: if _debug: decode_packet._debug(" - unknown APDU type: %r", apdu.apduType) return apdu # decode it as one of the basic types try: xpdu = apdu apdu = atype() apdu.decode(xpdu) except Exception as err: if _debug: decode_packet._debug(" - decoding Error: %r", err) return xpdu # decode it at the next level if isinstance(apdu, ConfirmedRequestPDU): atype = confirmed_request_types.get(apdu.apduService) if not atype: if _debug: decode_packet._debug( " - no confirmed request decoder: %r", apdu.apduService ) return apdu elif isinstance(apdu, UnconfirmedRequestPDU): atype = unconfirmed_request_types.get(apdu.apduService) if not atype: if _debug: decode_packet._debug( " - no unconfirmed request decoder: %r", apdu.apduService ) return apdu elif isinstance(apdu, SimpleAckPDU): atype = None elif isinstance(apdu, ComplexAckPDU): atype = complex_ack_types.get(apdu.apduService) if not atype: if _debug: decode_packet._debug( " - no complex ack decoder: %r", apdu.apduService ) return apdu elif isinstance(apdu, SegmentAckPDU): atype = None elif isinstance(apdu, ErrorPDU): atype = error_types.get(apdu.apduService) if not atype: if _debug: decode_packet._debug(" - no error decoder: %r", apdu.apduService) return apdu elif isinstance(apdu, RejectPDU): atype = None elif isinstance(apdu, AbortPDU): atype = None if _debug: decode_packet._debug(" - atype: %r", atype) # deeper decoding try: if atype: xpdu = apdu apdu = atype() apdu.decode(xpdu) except Exception as err: if _debug: decode_packet._debug(" - decoding error: %r", err) return xpdu # success return apdu else: # make a more focused interpretation ntype = npdu_types.get(npdu.npduNetMessage) if not ntype: if _debug: decode_packet._debug( " - no network layer decoder: %r", npdu.npduNetMessage ) return npdu if _debug: decode_packet._debug(" - ntype: %r", ntype) # deeper decoding try: xpdu = npdu npdu = ntype() npdu.decode(xpdu) except Exception as err: if _debug: decode_packet._debug(" - decoding error: %r", err) return xpdu # success return npdu
except Exception, err: if _debug: decode_packet._debug(" - decoding Error: %r", err) return npdu # "lift" the source and destination address if npdu.npduSADR: apdu.pduSource = npdu.npduSADR else: apdu.pduSource = npdu.pduSource if npdu.npduDADR: apdu.pduDestination = npdu.npduDADR else: apdu.pduDestination = npdu.pduDestination # make a more focused interpretation atype = apdu_types.get(apdu.apduType) if not atype: if _debug: decode_packet._debug(" - unknown APDU type: %r", apdu.apduType) return apdu # decode it as one of the basic types try: xpdu = apdu apdu = atype() apdu.decode(xpdu) if _debug: decode_packet._debug(" - apdu: %r", apdu) except Exception, err: if _debug: decode_packet._debug(" - decoding Error: %r", err) return xpdu