def protocol_frame(protocol, source='unicast', vlans=[]): """ Create a frame that has the minimum fields to be recognized as a determined protocol. It's not intended to be a valid PDU, only to be seen as one by the switch filter. @param protocol Protocol name. Valid options are: * stp, lldp, lacp, marker, oam, lbd, cdp, pagp, udld, vtp, pvst, dtp, gvrp, gmrp, dot1x @param source Name of the source interface, or source MAC address. * 'unicast' to use a random unicast address as source MAC. @param vlans [optional] List of VLAN Tags. List can be composed by single integer representing VLAN, or tuple (int, int) for VLAN and prio. Ex: [(100, 3), 20] will add two tags, one with VLAN 100, prio 3 and another with VLAN 20, prio 0. """ if protocol not in pdu_info: raise Exception("Unknown protocol name {0}".format(protocol)) info = pdu_info[protocol] # Define source MAC address. if "eth" in source: src_mac = str(mac_address(source)) elif source == 'unicast': src_mac = str(random_mac('unicast')) else: src_mac = str(source) if protocol == 'eaps': src_mac = "00:e0:2b:00:00:01" if 'type' in info or vlans: pdu = Ether(src=src_mac, dst=info['mac']) for v in vlans: if type(v) == int: pdu = pdu / Dot1Q(vlan=v) elif type(v) == tuple: pdu = pdu / Dot1Q(vlan=v[0], prio=v[1]) else: raise TypeError( "Expected list with int or tuple for VLANs parameter.") if 'type' in info: pdu.lastlayer().type = info['type'] else: pdu = Dot3(src=src_mac, dst=info['mac']) pdu = pdu / info['load'] # Process PDU so length field is correctly calculated. pdu = Ether(str(pdu)) # Add Padding and return. padding = 64 - len(pdu) + 4 #FCS if padding > 0: pdu = pdu / Padding(load='\0' * padding) return pdu
def send_frame(self, frame_body, slow_protocol=True): PACKET = Ether() PACKET.dst = self.dst PACKET.src = self.getHwAddr(self.interface) if self.stag: # WARNING: September/2016: This should be 0x88a8, but the Intel 10G # hardware I am currently using does not support receiving a TPID of # 0x88a8. So, I send double CTAGs, and I usually set this to 0x8100. # (NOTE: The Intel hardware can send a TPID of 0x88a8) PACKET.type = 0x8100 if self.ctag: PACKET /= Dot1Q(type=0x8100, vlan=int(self.stag)) PACKET /= Dot1Q(type=self.etype, vlan=int(self.ctag)) else: PACKET /= Dot1Q(prio=7, type=self.etype, vlan=int(self.stag)) else: if self.ctag: PACKET.type = 0x8100 PACKET /= Dot1Q(type=self.etype, vlan=int(self.ctag)) else: PACKET.type = self.etype # PACKET/=Dot1Q(type=self.etype, vlan=int(self.ctag)) if slow_protocol: PACKET /= SlowProtocolsSubtype() / FlagsBytes() / OAMPDU() PACKET /= frame_body PACKET /= EndOfPDU() else: PACKET.lastlayer().type = 0x9001 PACKET /= frame_body if (self.verbose == True): PACKET.show() print '###[ Frame Length %d (before padding) ]###' % len(PACKET) if (self.hexdump == True): print hexdump(str(PACKET)) if (self.dryrun != True): sendp(PACKET, iface=self.interface) time.sleep(self.sleep) return PACKET