def hasReceivedFrame(self, timeout=1.0, dstMac=None, srcMac=None, protocolType=None, data=None): """ Waits to receive "frame" event until the end of the timeout @param timeout: time max to wait to receive event in second (default=1s) @type timeout: float @return: an event matching with the template or None otherwise @rtype: templatemessage """ TestAdapterLib.check_timeout(caller=TestAdapterLib.caller(), timeout=timeout) ether_tpl = templates.ethernet(destAddr=dstMac, srcAddr=srcMac, etherType=protocolType, data=data) expected = self.encapsule(layer_ether=ether_tpl) evt = self.received(expected=expected, timeout=timeout) if evt is None: return None return evt
def hasReceivedFrame(self, timeout=1.0, dstMac=None, srcMac=None, protocolType=None, data=None): """ Waits to receive "frame" event until the end of the timeout @param timeout: time max to wait to receive event in second (default=1s) @type timeout: float @return: an event matching with the template or None otherwise @rtype: templatemessage """ if not (isinstance(timeout, int) or isinstance(timeout, float)) or isinstance(timeout, bool): raise TestAdapterLib.ValueException( TestAdapterLib.caller(), "timeout argument is not a float or integer (%s)" % type(timeout)) ether_tpl = templates.ethernet(destAddr=dstMac, srcAddr=srcMac, etherType=protocolType, data=data) expected = self.encapsule(layer_ether=ether_tpl) evt = self.received(expected=expected, timeout=timeout) if evt is None: return None return evt
def onStartSniffingFailed(self, e): """ """ self.debug(e) # log event ether_tpl = templates.ethernet(more=templates.sniffing_failed( err=str(e), interface=self.cfg['src-eth'])) frame_tpl = self.encapsule(layer_ether=ether_tpl) self.logRecvEvent(shortEvt="sniffing failed", tplEvt=frame_tpl)
def onStopListening(self): """ """ self.debug('on stop sniffing called') # log event ether_tpl = templates.ethernet(more=templates.stopped( interface=self.cfg['src-eth'])) frame_tpl = self.encapsule(layer_ether=ether_tpl) self.logRecvEvent(shortEvt="stopped", tplEvt=frame_tpl)
def decode(self, frame): """ """ # Unpack the first fourteen octets which are present in every ethernet frame hdrs_len = 14 # B = 1 octet # H = 2 octets # 6*B + 6*B + H = 12 ether_header = struct.unpack('!6B6BH', frame[:hdrs_len]) data_upper = frame[hdrs_len:] ## Destination Address. 6 bytes. ## The address(es) are specified for a unicast, multicast (subgroup), or broadcast (an entire group). dst_mac = ether_header[0:6] dst_mac_str = ':'.join(["%0.2X" % ch for ch in dst_mac]) key_dst = ':'.join(["%0.2X" % ch for ch in dst_mac[0:3]]) ## Source Address. 6 bytes. ## The address is for a unicast (single computer or device). src_mac = ether_header[6:12] src_mac_str = ':'.join(["%0.2X" % ch for ch in src_mac]) key_src = ':'.join(["%0.2X" % ch for ch in src_mac[0:3]]) ## EtherType. 16 bits. ## Which upper layer protocol will utilized the Ethernet frame. ethertype = ether_header[12:][0] ethertype = "0x%0.4X" % ethertype protocolUpper = None if ETHER_TYPE_MAP.has_key(ethertype): protocolUpper = ETHER_TYPE_MAP[ethertype] # set vendors vendorSrc = None vendorDst = None if self.mac_resolution: if OUI.has_key(key_dst): vendorDst = OUI[key_dst].title() if OUI.has_key(key_src): vendorSrc = OUI[key_src].title() # Decode OK, create template ether_tpl = templates.ethernet(destAddr=dst_mac_str, srcAddr=src_mac_str, etherType=ethertype, vendorDst=vendorDst, vendorSrc=vendorSrc, protocolUpper=protocolUpper, data=data_upper, size_data=len(data_upper)) # add the raw data without upper data ether_tpl.addRaw(frame[:hdrs_len]) return data_upper, ether_tpl
def onSocketError(self, e): """ """ self.error("socket error: %s" % str(e)) # log event ether_tpl = templates.ethernet(more=templates.sniffing_failed( err=str(e))) frame_tpl = self.encapsule(layer_ether=ether_tpl) self.logRecvEvent(shortEvt="error", tplEvt=frame_tpl) # clean the socket self.cleanSocket()
def onStartSniffing(self): """ """ self.debug('on start listening called') if self.cfg['agent-support']: self.sniffing = True # log event ether_tpl = templates.ethernet(more=templates.sniffing( macSrc=self.getSourceMac(), interface=self.cfg['src-eth'])) frame_tpl = self.encapsule(layer_ether=ether_tpl) self.logRecvEvent(shortEvt="sniffing", tplEvt=frame_tpl)
def isStopped(self, timeout=1.0): """ Waits to receive "stopped" event until the end of the timeout @param timeout: time max to wait to receive event in second (default=1s) @type timeout: float @return: an event matching with the template or None otherwise @rtype: templatemessage """ TestAdapterLib.check_timeout(caller=TestAdapterLib.caller(), timeout=timeout) ether_tpl = templates.ethernet(more=templates.stopped()) expected = self.encapsule(layer_ether=ether_tpl) # try to match the template evt = self.received(expected=expected, timeout=timeout) return evt
def isStopped(self, timeout=1.0): """ Waits to receive "stopped" event until the end of the timeout @param timeout: time max to wait to receive event in second (default=1s) @type timeout: float @return: an event matching with the template or None otherwise @rtype: templatemessage """ if not (isinstance(timeout, int) or isinstance(timeout, float)) or isinstance(timeout, bool): raise TestAdapterLib.ValueException( TestAdapterLib.caller(), "timeout argument is not a float or integer (%s)" % type(timeout)) ether_tpl = templates.ethernet(more=templates.stopped()) expected = self.encapsule(layer_ether=ether_tpl) # try to match the template evt = self.received(expected=expected, timeout=timeout) return evt
def stopListening(self): """ Stop listening """ self.debug('acquire the mutex') self.__mutex__.acquire() if self.sniffing: self.debug('stopping to sniff') # log event ether_tpl = templates.ethernet(more=templates.stopping( interface=self.cfg['src-eth'])) frame_tpl = self.encapsule(layer_ether=ether_tpl) self.logSentEvent(shortEvt="stopping", tplEvt=frame_tpl) if self.cfg['agent-support']: self.cleanSocket() else: self.cleanSocket() self.onStopListening() self.__mutex__.release() self.debug('release the mutex')
def sendFrame(self, data, dstMac, protocolType): """ Send a frame, with automatic data padding support @param data: upper data @type data: hexa @param dstMac: destination mac address @type dstMac: string @param protocolType: SutAdapters.Ethernet.IPv4 | SutAdapters.Ethernet.IPv6 | SutAdapters.Ethernet.ARP | SutAdapters.Ethernet.RARP | SutAdapters.Ethernet.DOT1Q | SutAdapters.Ethernet.SNMP @type protocolType: strconstant @return: template message @rtype: template """ if not self.sniffing: self.debug("not sniffing") return if not isinstance(dstMac, str): raise Exception('Adapter>sendFrame: bad destination mac type: %s' % type(dstMac)) if not len(dstMac): raise Exception( 'Adapter>sendFrame: destination mac address can not be empty') # The padding is necessary to avoid collisions. Ethernet packets must at least # have a size of 60 bytes without the Frame Check Sequence (FCS, 4 bytes). padding = None if self.padding: minSize = 60 - (2 * 6 + 2) if len(data) < minSize: padding = "\x00" * (minSize - len(data)) data += padding ether_tpl = templates.ethernet(destAddr=dstMac, srcAddr=self.src_mac, etherType=protocolType, data=data, padding=padding) frame_tpl = self.encapsule(layer_ether=ether_tpl) try: frame, ether_hdr = self.etherCodec.encode(frame_tpl=frame_tpl) # add the raw data without upper data ether_tpl.addRaw(ether_hdr) except Exception as e: raise Exception("Cannot encode the frame: %s" % str(e)) else: frame_tpl.addRaw(frame) dst_mac_tpl = ether_tpl.get('mac-destination') dst_mac = dst_mac_tpl.getName() dst_summary = 'To %s' % dst_mac vendor_dst = dst_mac_tpl.get('vendor') if vendor_dst is not None: dst_summary = 'To %s:%s' % (vendor_dst.replace( ' ', ''), ':'.join(dst_mac.split(':')[3:])) if self.logEventSent: self.logSentEvent(shortEvt=dst_summary, tplEvt=frame_tpl) else: self.onSending(lower=frame_tpl) # enqueue pdu self.debug('sending frame') if self.cfg['agent-support']: remote_cfg = {'cmd': 'send-data', 'payload': frame} self.sendNotifyToAgent(data=remote_cfg) else: if self.socket is not None: self.socket.send(frame) return frame_tpl
def startListening(self, eth, srcMac=None): """ Start listening @param eth: device @type eth: string @param srcMac: source mac address @type srcMac: none/string """ if self.sniffing: self.debug('already sniffing') return self.cfg['src-eth'] = eth # log event ether_tpl = templates.ethernet(more=templates.starting( interface=self.cfg['src-eth'])) frame_tpl = self.encapsule(layer_ether=ether_tpl) self.logSentEvent(shortEvt="starting", tplEvt=frame_tpl) if self.cfg['agent-support']: if srcMac is not None: if not isinstance(srcMac, str) and not isinstance( srcMac, unicode): raise Exception( 'Adapter>startListening: bad source mac type: %s' % type(srcMac)) if not len(srcMac): raise Exception( 'Adapter>startListening: source mac address can not be empty' ) self.src_mac = srcMac remote_cfg = { 'cmd': 'connect', 'sock-type': 'raw', 'src-eth': self.cfg['src-eth'] } #self.parent.sendInitToAgent(adapterId=self.getAdapterId(), agentName=self.cfg['agent-name'], agentData=remote_cfg) self.sendNotifyToAgent(data=remote_cfg) self.setRunning() else: try: # Create the socket: ethernet protocol, raw Linux packet socket self.socket = TestAdapterLib.getSocket( sockType=TestAdapterLib.RAW_PACKET_SOCKET) self.socket.bind((eth, socket.SOCK_RAW)) # save source mac addr if srcMac is not None: if not isinstance(srcMac, str) and not isinstance( srcMac, unicode): raise Exception( 'Adapter>startListening: bad source mac type: %s' % type(srcMac)) if not len(srcMac): raise Exception( 'Adapter>startListening: source mac address can not be empty' ) self.src_mac = srcMac else: self.src_mac = ':'.join([ "%02X" % (ord(ch), ) for ch in self.socket.getsockname()[-1] ]) self.debug("source mac: %s" % self.src_mac) self.sniffing = True # start thread self.onStartSniffing() self.setRunning() except socket.error, e: self.onStartSniffingFailed(e) except Exception as e: self.error("listen error: %s" % str(e)) self.stopListening()