Exemplo n.º 1
0
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
Exemplo n.º 2
0
def l2_frame_from_to(source, destination, vlans = [], seq = 10, size = 64, pattern = '\0', framing = "Ethernet II"):
	""" Create a frame using interfaces MACs.
	@param source            Name of the source interface, or source MAC address.
	                         It can also be:
	                         * 'unicast' to use a random unicast address as source MAC.
	@param destination       Name of the destination interface, or destination MAC address.
	                         It can also be:
	                         * 'broadcast' to use 'FF:FF:FF:FF:FF:FF' as destination MAC.
	                         * 'multicast' to use a random multicast address as destination MAC.
	                         * 'unicast' to use a random unicast address as destination 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.
	@param seq               [optional] Number of sequence
	@param size              [optional] Size of created frame. A padding based on 'pattern' is added to complete
	                         the frame until size is reached (counting 4 bytes of FCS)
	@param pattern           [optional] Pattern string used to fill payload. Default is '\0'.
	                         * 'random' to fill the payload with random bytes.
	@param framing           [optional] Type of frame:
	                         * "Ethernet II" : Ethertype > 1535 and hold information about next layer.
	                         * "802.3" : Ethertype <= 1500 represent payload length. Next header is LLC.
	"""

	if "eth" in destination:
		dst_mac = mac_address(destination)
	elif destination == 'broadcast':
		dst_mac = 'FF:FF:FF:FF:FF:FF'
	elif destination == 'multicast':
		dst_mac = str(random_mac('multicast'))
	elif destination == 'unicast':
		dst_mac = str(random_mac('unicast'))
	else:
		dst_mac = str(destination)

	if "eth" in source:
		src_mac = str(mac_address(source))
	elif source == 'unicast':
		src_mac = str(random_mac('unicast'))
	else:
		src_mac = str(source)

	# When the next layer is Dot1Q, Dot3 will be evaluated as Ether anyway (0x8100 > 1536),
	# To keep consistency between creation and dissection, already use Ether even for 802.3 framing.
	# The difference will be made as Dot1Q will be followed by LLC header.

	if framing == "Ethernet II" or vlans:
		frame = Ether(src = src_mac, dst = dst_mac)
	elif framing == "802.3":
		frame = Dot3(src = src_mac, dst = dst_mac)
	else:
		raise ValueError("Excpected only 'Ethernet II' or '802.3' as framing types.")

	for v in vlans:
		if type(v) == int:
			frame = frame / Dot1Q(vlan = v)
		elif type(v) == tuple:
			frame = frame / Dot1Q(vlan = v[0], prio = v[1])
		else:
			raise TypeError("Expected list with int or tuple for VLANs parameter.")

	if framing == "802.3":
		frame = frame / LLC() / SNAP()

	if seq != None:
		frame = frame / L2T(l2t_seq = seq)

	return add_payload(frame, size, pattern)