def sendPacket(self, hardwareType=codec.HARDWARE_TYPE, protocolType=AdapterEthernet.IPv4, op=codec.OP_REQUEST, hardwareLen=codec.HARDWARE_LEN, protocolLen=codec.PROTOCOL_LEN, senderIp='0.0.0.0', senderMac='00:00:00:00:00:00', targetIp='0.0.0.0', targetMac='00:00:00:00:00:00', ethernetDstMac='FF:FF:FF:FF:FF:FF'): """ Send ARP packet @param hardwareType: SutAdapters.ARP.HARDWARE_TYPE (default) @type hardwareType: strconstant @param protocolType: SutAdapters.Ethernet.IPv4 (default) @type protocolType: strconstant @param op: SutAdapters.ARP.OP_REQUEST (default) | SutAdapters.ARP.OP_REPLY @type op: strconstant @param hardwareLen: SutAdapters.ARP.HARDWARE_LEN (default) @type hardwareLen: strconstant @param protocolLen: SutAdapters.ARP.PROTOCOL_LEN (default) @type protocolLen: strconstant @param senderIp: sender ip (default=0.0.0.0) @type senderIp: string @param targetIp: target ip (default=0.0.0.0) @type targetIp: string @param senderMac: sender mac (default=00:00:00:00:00:00) @type senderMac: string @param targetMac: target mac (default=00:00:00:00:00:00) @type targetMac: string @param ethernetDstMac: ethernet destination mac (default=FF:FF:FF:FF:FF:FF) @type ethernetDstMac: string """ try: self.__sender_mac = senderMac self.__sender_ip = senderIp arp_tpl = templates.arp(hrd=hardwareType, pro=protocolType, hln=hardwareLen, pln=protocolLen, op=op, sha=senderMac, spa=senderIp, tha=targetMac, tpa=targetIp) try: (pkt, summary) = self.arpCodec.encode(arp_tpl=arp_tpl) except Exception as e: raise Exception("Cannot encode arp: %s" % str(e)) else: # Send packet try: lower = self.ether.sendFrame( data=pkt, dstMac=ethernetDstMac, protocolType=AdapterEthernet.ARP) except Exception as e: raise Exception("send frame failed: %s" % str(e)) else: lower.addLayer(arp_tpl) arp_tpl.addRaw(raw=pkt) if self.logEventSent: self.logSentEvent(shortEvt=summary, tplEvt=lower) except Exception as e: raise Exception('Unable to send arp packet: %s' % str(e))
def decode(self, arp): """ """ # fixed header, H + H + B + B + H = 8 arp_len_fixed = 8 arp_header = struct.unpack('!HHBBH', arp[:arp_len_fixed]) ## 16.bit Hardware address space arp_hrd = arp_header[0] ## 16.bit Protocol address space arp_pro = arp_header[1] ## 8.bit byte length of each hardware address arp_hln = arp_header[2] ## 8.bit byte length of each protocol address arp_pln = arp_header[3] ## 16.bit opcode arp_op = arp_header[4] ## extract addresses, variable part addrs_len = 2*int(arp_hln) + 2*int(arp_pln) arp_addresses = struct.unpack( '!%sB%sB%sB%sB' %(int(arp_hln), int(arp_pln), int(arp_hln), int(arp_pln)), arp[arp_len_fixed:arp_len_fixed+addrs_len ] ) data_upper = arp[ arp_len_fixed+addrs_len :] ## Hardware address of sender arp_sha = arp_addresses[ 0:int(arp_hln) ] ## Protocol address of sender arp_spa = arp_addresses[ int(arp_hln): int(arp_hln) + int(arp_pln) ] ## Hardware address of target arp_tha = arp_addresses[ int(arp_hln) + int(arp_pln): 2 * int(arp_hln) + int(arp_pln) ] ## Protocol address of target arp_tpa = arp_addresses[ 2 * int(arp_hln) + int(arp_pln):2 * int(arp_hln) + 2*int(arp_pln)] # convert values arp_hrd = "0x%0.4X" % arp_hrd arp_pro = "0x%0.4X" % arp_pro arp_hln = "0x%0.2X" % arp_hln arp_pln = "0x%0.2X" % arp_pln arp_op = "0x%0.4X" % arp_op arp_sha = ':'.join( [ "%0.2X" % ch for ch in arp_sha ] ) arp_spa = '.'.join( [ str(d) for d in arp_spa ] ) arp_tha = ':'.join( [ "%0.2X" % ch for ch in arp_tha ] ) arp_tpa = '.'.join( [ str(d) for d in arp_tpa ] ) # add human values op_str = self.getOp(op=arp_op) # Decode OK, create template arp_tpl = templates.arp(hrd=arp_hrd, pro=arp_pro, hln=arp_hln, pln=arp_pln, op=arp_op, sha=arp_sha, spa=arp_spa, tha=arp_tha, tpa=arp_tpa, opString=op_str) # add padding if exist if len(data_upper): arp_tpl.addKey('padding', data_upper ) arp_tpl.addKey('padding-length', len(data_upper) ) # add the raw data to the layer arp_tpl.addRaw(arp) # finally prepare the summary if arp_op == OP_REQUEST: summary = 'Who has %s? Tell %s' % (arp_tpa, arp_spa) elif arp_op == OP_REPLY: summary = '%s is at %s' % (arp_spa, arp_sha) else: summary = 'unknown op %s' % arp_op return arp_tpl, summary
def hasReceivedPacket(self, timeout=1.0, op=None, dstEthernet=None, srcEthernet=None, targetIp=None, senderIp=None, targetMac=None, senderMac=None): """ Wait event until the end of the timeout @param timeout: time max to wait to receive event in second (default=1s) @type timeout: float @param op: SutAdapters.ARP.OP_REQUEST (default) | SutAdapters.ARP.OP_REPLY @type op: none/strconstant/operator @param dstEthernet: ethernet destination mac @type dstEthernet: none/string/operator @param srcEthernet: ethernet source mac @type srcEthernet: none/string/operator @param targetIp: arp target ip @type targetIp: none/string/operator @param senderIp: arp sender ip @type senderIp: none/string/operator @param targetMac: arp target mac @type targetMac: none/string/operator @param senderMac: arp sender ip @type senderMac: none/string/operator @return: an event matching with the template or None otherwise @rtype: templatemessage """ TestAdapterLib.check_timeout(caller=TestAdapterLib.caller(), timeout=timeout) expected = TestTemplatesLib.TemplateMessage() if self.cfg['agent-support']: layer_agent = TestTemplatesLib.TemplateLayer('AGENT') layer_agent.addKey(name='name', data=self.cfg['agent']['name']) layer_agent.addKey(name='type', data=self.cfg['agent']['type']) expected.addLayer(layer_agent) layer_ether = AdapterEthernet.ethernet(destAddr=dstEthernet, srcAddr=srcEthernet) expected.addLayer(layer=layer_ether) layer_arp = templates.arp(op=op, sha=senderMac, spa=senderIp, tha=targetMac, tpa=targetIp) expected.addLayer(layer=layer_arp) # try to match the template evt = self.received(expected=expected, timeout=timeout) return evt