def create_vxlan_packet(self, outer_da, outer_sa, outer_dip, outer_sip, vni, inner_da, inner_dip, inner_sa="00:11:22:33:55:66", inner_sip="192.168.0.44", is_inner_vlan=False, vlan_id=1): out_ether = scapy.Ether(dst=outer_da, src=outer_sa) out_ip = scapy.IP(dst=outer_dip, src=outer_sip) out_udp = scapy.UDP(dport=4789, sport=random.randint( 49152, 65535 - NUM_CONTINUOUS_PKT_COUNT)) vxlan = scapy.VXLAN(vni=vni) ether = scapy.Ether(dst=inner_da, src=inner_sa) dot1q = scapy.Dot1Q(vlan=vlan_id) ip = scapy.IP(dst=inner_dip, src=inner_sip) udp = scapy.UDP(dport=22222, sport=11111) # minimum packet for untagged payload = "\0" * (64 - 4 - len(ether / ip / udp)) packet_vxlan = out_ether / out_ip / out_udp / vxlan / ether / ip / udp / payload if is_inner_vlan: packet_inner = ether / dot1q / ip / udp / payload else: packet_inner = ether / ip / udp / payload return packet_vxlan, packet_inner
def create_dhcp_discover_relayed_packet(self): my_chaddr = ''.join( [chr(int(octet, 16)) for octet in self.client_mac.split(':')]) # Relay modifies the DHCPDISCOVER message in the following ways: # 1.) Increments the hops count in the DHCP header # 2.) Updates the gateway IP address in hte BOOTP header (if it is 0.0.0.0) # 3.) Replaces the source IP with the IP of the interface which the relay # received the broadcast DHCPDISCOVER message on # 4.) Replaces the destination IP with the IP address of the DHCP server # each message is being forwarded to # Here, the actual destination MAC should be the MAC of the leaf the relay # forwards through and the destination IP should be the IP of the DHCP server # the relay is forwarding to. We don't need to confirm these, so we'll # just mask them off later # # TODO: In IP layer, DHCP relay also replaces source IP with IP of interface on # which it received the broadcast DHCPDISCOVER from client. This appears to # be loopback. We could pull from minigraph and check here. ether = scapy.Ether(dst=self.BROADCAST_MAC, src=self.uplink_mac, type=0x0800) ip = scapy.IP(src=self.DEFAULT_ROUTE_IP, dst=self.BROADCAST_IP, len=328, ttl=64) udp = scapy.UDP(sport=self.DHCP_SERVER_PORT, dport=self.DHCP_SERVER_PORT, len=308) bootp = scapy.BOOTP(op=1, htype=1, hlen=6, hops=1, xid=0, secs=0, flags=0x8000, ciaddr=self.DEFAULT_ROUTE_IP, yiaddr=self.DEFAULT_ROUTE_IP, siaddr=self.DEFAULT_ROUTE_IP, giaddr=self.relay_iface_ip if not self.dual_tor else self.switch_loopback_ip, chaddr=my_chaddr) bootp /= scapy.DHCP( options=[('message-type', 'discover'), ('relay_agent_Information', self.option82), ('end')]) # If our bootp layer is too small, pad it pad_bytes = self.DHCP_PKT_BOOTP_MIN_LEN - len(bootp) if pad_bytes > 0: bootp /= scapy.PADDING('\x00' * pad_bytes) pkt = ether / ip / udp / bootp return pkt
def create_dhcp_ack_relayed_packet(self): my_chaddr = ''.join( [chr(int(octet, 16)) for octet in self.client_mac.split(':')]) # Relay modifies the DHCPACK message in the following ways: # 1.) Replaces the source MAC with the MAC of the interface it received it on # 2.) Replaces the destination MAC with boradcast (ff:ff:ff:ff:ff:ff) # 3.) Replaces the source IP with the IP of the interface which the relay # received it on # 4.) Replaces the destination IP with broadcast (255.255.255.255) # 5.) Replaces the destination port with the DHCP client port (68) ether = scapy.Ether(dst=self.BROADCAST_MAC, src=self.relay_iface_mac, type=0x0800) ip = scapy.IP(src=self.relay_iface_ip, dst=self.BROADCAST_IP, len=290, ttl=64) udp = scapy.UDP(sport=self.DHCP_SERVER_PORT, dport=self.DHCP_CLIENT_PORT, len=262) bootp = scapy.BOOTP(op=2, htype=1, hlen=6, hops=0, xid=0, secs=0, flags=0x8000, ciaddr=self.DEFAULT_ROUTE_IP, yiaddr=self.client_ip, siaddr=self.server_ip, giaddr=self.relay_iface_ip if not self.dual_tor else self.switch_loopback_ip, chaddr=my_chaddr) bootp /= scapy.DHCP(options=[( 'message-type', 'ack'), ('server_id', self.server_ip), ( 'lease_time', self.LEASE_TIME), ('subnet_mask', self.client_subnet), ('end')]) # TODO: Need to add this to the packet creation functions in PTF code first! # If our bootp layer is too small, pad it #pad_bytes = self.DHCP_PKT_BOOTP_MIN_LEN - len(bootp) #if pad_bytes > 0: # bootp /= scapy.PADDING('\x00' * pad_bytes) pkt = ether / ip / udp / bootp return pkt
def create_dhcp_discover_relayed_packet(self): my_chaddr = ''.join([ chr(int(octet, 16)) for octet in self.client_iface_mac.split(':') ]) # Relay modifies the DHCPDISCOVER message in the following ways: # 1.) Increments the hops count in the DHCP header # 2.) Updates the gateway IP address in hte BOOTP header (if it is 0.0.0.0) # 3.) Replaces the source IP with the IP of the interface which the relay # received the broadcast DHCPDISCOVER message on # 4.) Replaces the destination IP with the IP address of the DHCP server # each message is being forwarded to # Here, the actual destination MAC should be the MAC of the leaf the relay # forwards through and the destination IP should be the IP of the DHCP server # the relay is forwarding to. We don't need to confirm these, so we'll # just mask them off later # # TODO: Relay also replaces source IP with IP of interface on which it received the # broadcast DHCPDISCOVER from client. This appears to be loopback. # We could pull from minigraph and check here. pkt = scapy.Ether(dst=self.BROADCAST_MAC, src=self.relay_iface_mac, type=0x0800) pkt /= scapy.IP(src=self.DEFAULT_ROUTE_IP, dst=self.BROADCAST_IP, len=328, ttl=64) pkt /= scapy.UDP(sport=self.DHCP_SERVER_PORT, dport=self.DHCP_SERVER_PORT, len=308) pkt /= scapy.BOOTP(op=1, htype=1, hlen=6, hops=1, xid=0, secs=0, flags=0x8000, ciaddr=self.DEFAULT_ROUTE_IP, yiaddr=self.DEFAULT_ROUTE_IP, siaddr=self.DEFAULT_ROUTE_IP, giaddr=self.relay_iface_ip, chaddr=my_chaddr) pkt /= scapy.DHCP(options=[( 'message-type', 'discover'), ('relay_agent_Information', self.relay_agent_info), ('end')]) # The isc-dhcp-relay adds 44 bytes of padding to our discover packet pkt /= scapy.PADDING('\x00' * 44) return pkt
def create_dhcp_request_relayed_packet(self): my_chaddr = ''.join( [chr(int(octet, 16)) for octet in self.client_mac.split(':')]) # Here, the actual destination MAC should be the MAC of the leaf the relay # forwards through and the destination IP should be the IP of the DHCP server # the relay is forwarding to. We don't need to confirm these, so we'll # just mask them off later # # TODO: In IP layer, DHCP relay also replaces source IP with IP of interface on # which it received the broadcast DHCPREQUEST from client. This appears to # be loopback. We could pull from minigraph and check here. ether = scapy.Ether(dst=self.BROADCAST_MAC, src=self.uplink_mac, type=0x0800) ip = scapy.IP(src=self.DEFAULT_ROUTE_IP, dst=self.BROADCAST_IP, len=336, ttl=64) udp = scapy.UDP(sport=self.DHCP_SERVER_PORT, dport=self.DHCP_SERVER_PORT, len=316) bootp = scapy.BOOTP(op=1, htype=1, hlen=6, hops=1, xid=0, secs=0, flags=0x8000, ciaddr=self.DEFAULT_ROUTE_IP, yiaddr=self.DEFAULT_ROUTE_IP, siaddr=self.DEFAULT_ROUTE_IP, giaddr=self.relay_iface_ip if not self.dual_tor else self.switch_loopback_ip, chaddr=my_chaddr) bootp /= scapy.DHCP(options=[( 'message-type', 'request'), ( 'requested_addr', self.client_ip), ( 'server_id', self.server_ip), ('relay_agent_Information', self.option82), ('end')]) # If our bootp layer is too small, pad it pad_bytes = self.DHCP_PKT_BOOTP_MIN_LEN - len(bootp) if pad_bytes > 0: bootp /= scapy.PADDING('\x00' * pad_bytes) pkt = ether / ip / udp / bootp return pkt
def createDhcpRequestRelayedPacket(self, dutMac): """ Helper function that creates DHCP Request packet destined to DUT Args: dutMac(str): MAC address of DUT Returns: packet: DHCP Request packet """ ether = scapy.Ether(dst=dutMac, src=self.DHCP_RELAY["mac"], type=0x0800) ip = scapy.IP(src=self.DHCP_RELAY["loopback"], dst=self.DHCP_SERVER["ip"], len=328, ttl=64) udp = scapy.UDP(sport=self.DHCP_SERVER["port"], dport=self.DHCP_SERVER["port"], len=308) bootp = scapy.BOOTP(op=1, htype=1, hlen=6, hops=1, xid=0, secs=0, flags=0x8000, ciaddr=str(INADDR_ANY), yiaddr=str(INADDR_ANY), siaddr=str(INADDR_ANY), giaddr=self.DHCP_RELAY["ip"], chaddr=''.join([ chr(int(octet, 16)) for octet in self.DHCP_CLIENT["mac"].split(':') ])) bootp /= scapy.DHCP( options=[("message-type", "request"), ("requested_addr", self.DHCP_CLIENT["ip"] ), ("server_id", self.DHCP_SERVER["ip"]), ("end")]) pad_bytes = self.DHCP_PKT_BOOTP_MIN_LEN - len(bootp) if pad_bytes > 0: bootp /= scapy.PADDING("\x00" * pad_bytes) pkt = ether / ip / udp / bootp return pkt
def create_dhcp_request_relayed_packet(self): my_chaddr = ''.join([ chr(int(octet, 16)) for octet in self.client_iface_mac.split(':') ]) # Here, the actual destination MAC should be the MAC of the leaf the relay # forwards through and the destination IP should be the IP of the DHCP server # the relay is forwarding to. We don't need to confirm these, so we'll # just mask them off later # # TODO: Relay also replaces source IP with IP of interface on which it received the # broadcast DHCPDISCOVER from client. This appears to be loopback. # We could pull from minigraph and check here. pkt = scapy.Ether(dst=self.BROADCAST_MAC, src=self.relay_iface_mac, type=0x0800) pkt /= scapy.IP(src=self.DEFAULT_ROUTE_IP, dst=self.BROADCAST_IP, len=328, ttl=64) pkt /= scapy.UDP(sport=self.DHCP_SERVER_PORT, dport=self.DHCP_SERVER_PORT, len=308) pkt /= scapy.BOOTP(op=1, htype=1, hlen=6, hops=1, xid=0, secs=0, flags=0x8000, ciaddr=self.DEFAULT_ROUTE_IP, yiaddr=self.DEFAULT_ROUTE_IP, siaddr=self.DEFAULT_ROUTE_IP, giaddr=self.relay_iface_ip, chaddr=my_chaddr) pkt /= scapy.DHCP(options=[( 'message-type', 'request'), ('requested_addr', self.client_ip), ('server_id', self.server_ip), ('relay_agent_Information', self.relay_agent_info), ('end')]) # The isc-dhcp-relay adds 32 bytes of padding to our request pkt /= scapy.PADDING('\x00' * 32) return pkt