def create_pkt(pkt_str, type="Ether"): for i in range(0, len(pkt_str)): pkt_str[i] = int(pkt_str[i],16) packet = bytes(pkt_str) if(type == "Ether"): return Ether(raw(packet)) elif(type == "0x800"): return IP(raw(packet)) elif(type == "0x6"): return TCP(raw(packet)) elif(type == "0x11"): return UDP(raw(packet)) elif(type == "0x84"): return SCTP(raw(packet)) else: return None
class scapy(object): SCAPY_LAYERS = { 'ether': Ether(dst="ff:ff:ff:ff:ff:ff"), 'vlan': Dot1Q(), 'etag': None, '1588': Ether(type=0x88f7), 'arp': ARP(), 'ipv4': IP(), 'ipv4ihl': IP(ihl=10), 'ipv4_ext': IP(frag=5), 'ipv6': IPv6(src="::1"), 'ipv6_ext': IPv6(src="::1", nh=43) / IPv6ExtHdrRouting(), 'ipv6_ext2': IPv6() / IPv6ExtHdrRouting(), 'udp': UDP(), 'tcp': TCP(), 'sctp': SCTP(), 'icmp': ICMP(), 'gre': GRE(), 'raw': Raw(), 'vxlan': Vxlan(), 'inner_mac': Ether(), 'inner_vlan': Dot1Q(), 'inner_ipv4': IP(), 'inner_ipv4_ext': IP(), 'inner_ipv6': IPv6(src="::1"), 'inner_ipv6_ext': IPv6(src="::1"), 'inner_tcp': TCP(), 'inner_udp': UDP(), 'inner_sctp': SCTP(), 'inner_icmp': ICMP(), 'lldp': None, 'ip_frag': IP(frag=5), 'ipv6_frag': IPv6(src="::1") / IPv6ExtHdrFragment(), 'ip_in_ip': IP() / IP(), 'ip_in_ip_frag': IP() / IP(frag=5), 'ipv6_in_ip': IP() / IPv6(src="::1"), 'ipv6_frag_in_ip': IP() / IPv6(src="::1", nh=44) / IPv6ExtHdrFragment(), 'nvgre': None, 'geneve': "Not Implement", } def __init__(self): self.pkt = None pass def assign_pkt(self, pkt): self.pkt = pkt def add_layers(self, layers): self.pkt = None for layer in layers: if self.pkt is not None: self.pkt = self.pkt / self.SCAPY_LAYERS[layer] else: self.pkt = self.SCAPY_LAYERS[layer] def ether(self, pkt_layer, dst="ff:ff:ff:ff:ff:ff", src="00:00:20:00:00:00", type=None): if pkt_layer.name != "Ethernet": return pkt_layer.dst = dst pkt_layer.src = src if type is not None: pkt_layer.type = type def vlan(self, pkt_layer, vlan, prio=0, type=None): if pkt_layer.name != "802.1Q": return pkt_layer.vlan = int(vlan) pkt_layer.prio = prio if type is not None: pkt_layer.type = type def strip_vlan(self, element): value = None if self.pkt.haslayer('Dot1Q') is 0: return None if element == 'vlan': value = int(str(self.pkt[Dot1Q].vlan)) return value def etag(self, pkt_layer, ECIDbase=0, prio=0, type=None): if pkt_layer.name != "802.1BR": return pkt_layer.ECIDbase = int(ECIDbase) pkt_layer.prio = prio if type is not None: pkt_layer.type = type def strip_etag(self, element): value = None if self.pkt.haslayer('Dot1BR') is 0: return None if element == 'ECIDbase': value = int(str(self.pkt[Dot1BR].ECIDbase)) return value def strip_layer2(self, element): value = None layer = self.pkt.getlayer(0) if layer is None: return None if element == 'src': value = layer.src elif element == 'dst': value = layer.dst elif element == 'type': value = layer.type return value def strip_layer3(self, element): value = None layer = self.pkt.getlayer(1) if layer is None: return None if element == 'src': value = layer.src elif element == 'dst': value = layer.dst else: value = layer.getfieldval(element) return value def strip_layer4(self, element): value = None layer = self.pkt.getlayer(2) if layer is None: return None if element == 'src': value = layer.sport elif element == 'dst': value = layer.dport else: value = layer.getfieldval(element) return value def ipv4(self, pkt_layer, frag=0, src="127.0.0.1", proto=None, tos=0, dst="127.0.0.1", chksum=None, len=None, version=4, flags=None, ihl=None, ttl=64, id=1, options=None): pkt_layer.frag = frag pkt_layer.src = src if proto is not None: pkt_layer.proto = proto pkt_layer.tos = tos pkt_layer.dst = dst if chksum is not None: pkt_layer.chksum = chksum if len is not None: pkt_layer.len = len pkt_layer.version = version if flags is not None: pkt_layer.flags = flags if ihl is not None: pkt_layer.ihl = ihl pkt_layer.ttl = ttl pkt_layer.id = id if options is not None: pkt_layer.options = options def ipv6(self, pkt_layer, version=6, tc=0, fl=0, plen=0, nh=0, hlim=64, src="::1", dst="::1"): """ Configure IPv6 protocal. """ pkt_layer.version = version pkt_layer.tc = tc pkt_layer.fl = fl if plen: pkt_layer.plen = plen if nh: pkt_layer.nh = nh pkt_layer.src = src pkt_layer.dst = dst def tcp(self, pkt_layer, src=53, dst=53, flags=None, len=None, chksum=None): pkt_layer.sport = src pkt_layer.dport = dst if flags is not None: pkt_layer.flags = flags if len is not None: pkt_layer.len = len if chksum is not None: pkt_layer.chksum = chksum def udp(self, pkt_layer, src=53, dst=53, len=None, chksum=None): pkt_layer.sport = src pkt_layer.dport = dst if len is not None: pkt_layer.len = len if chksum is not None: pkt_layer.chksum = chksum def sctp(self, pkt_layer, src=53, dst=53, tag=None, len=None, chksum=None): pkt_layer.sport = src pkt_layer.dport = dst if tag is not None: pkt_layer.tag = tag if len is not None: pkt_layer.len = len if chksum is not None: pkt_layer.chksum = chksum def raw(self, pkt_layer, payload=None): if payload is not None: pkt_layer.load = '' for hex1, hex2 in payload: pkt_layer.load += struct.pack("=B", int('%s%s' % (hex1, hex2), 16)) def gre(self, pkt_layer, proto=None): if proto is not None: pkt_layer.proto = proto def vxlan(self, pkt_layer, vni=0): pkt_layer.vni = vni def read_pcap(self, file): pcap_pkts = [] try: pcap_pkts = rdpcap(file) except: pass return pcap_pkts def write_pcap(self, file): try: wrpcap(file, self.pkt) except: pass def send_pcap_pkt(self, crb=None, file='', intf='', count=1): if intf == '' or file == '' or crb is None: print "Invalid option for send packet by scapy" return content = 'pkts=rdpcap(\"%s\");sendp(pkts, iface=\"%s\", count=\"%s\" );exit()' % ( file, intf, count) cmd_file = '/tmp/scapy_%s.cmd' % intf crb.create_file(content, cmd_file) crb.send_expect("scapy -c scapy_%s.cmd &" % intf, "# ") def print_summary(self): print "Send out pkt %s" % self.pkt.summary() def send_pkt(self, intf='', count=1): self.print_summary() if intf != '': # wait few seconds for link ready countdown = 600 while countdown: link_st = subprocess.check_output("ip link show %s" % intf, stderr=subprocess.STDOUT, shell=True) if "LOWER_UP" in link_st: break else: time.sleep(0.01) countdown -= 1 continue # fix fortville can't receive packets with 00:00:00:00:00:00 if self.pkt.getlayer(0).src == "00:00:00:00:00:00": self.pkt.getlayer(0).src = get_if_hwaddr(intf) sendp(self.pkt, iface=intf, count=count)
def create_pcap(self): """ Create pcap file in config.pcap_file Return scapy packet object for later usage """ """ inner package = L2/[Vlan]/L3/L4/Payload """ if self.inner_l4_type == 'SCTP': self.inner_payload = SCTPChunkData(data='X' * 16) else: self.inner_payload = ("X" * self.payload_size) if self.inner_l4_type == 'TCP': inner_l4 = TCP() elif self.inner_l4_type == 'UDP': inner_l4 = UDP() elif self.inner_l4_type == 'SCTP': inner_l4 = SCTP() if self.inner_l3_type == 'IPv4': inner_l3 = IP() else: inner_l3 = IPv6() if self.inner_vlan != 'N/A': inner = Ether() / Dot1Q( ) / inner_l3 / inner_l4 / self.inner_payload inner[Dot1Q].vlan = self.inner_vlan else: if self.inner_l4_type == "None": inner = Ether() / inner_l3 / self.inner_payload else: inner = Ether() / inner_l3 / inner_l4 / self.inner_payload inner[Ether].src = self.inner_mac_src inner[Ether].dst = self.inner_mac_dst if self.inner_l3_type == 'IPv4': inner[inner_l3.name].src = self.inner_ip_src inner[inner_l3.name].dst = self.inner_ip_dst else: inner[inner_l3.name].src = self.inner_ip6_src inner[inner_l3.name].dst = self.inner_ip6_dst if self.inner_l4_type == "UDP" or self.inner_l4_type == "TCP": inner[inner_l4.name].dport = 1021 inner[inner_l4.name].sport = 1021 if self.inner_l3_type == 'IPv4' and self.inner_ip_invalid == 1: inner[inner_l3.name].chksum = 0x1234 if self.inner_l4_invalid == 1: if self.inner_l4_type == 'SCTP': inner[SCTP].chksum = 0 elif self.inner_l4_type == "UDP" or self.inner_l4_type == "TCP": inner[self.inner_l4_type].chksum = 0x1234 """ Outer package = L2/[Vlan]/L3 """ if self.outer_l3_type == 'IPv4': outer_l3 = IP() else: outer_l3 = IPv6() if self.outer_vlan != 'N/A': outer = Ether() / Dot1Q() / outer_l3 outer[Dot1Q].vlan = self.outer_vlan else: outer = Ether() / outer_l3 outer[Ether].src = self.outer_mac_src outer[Ether].dst = self.outer_mac_dst if self.outer_l3_type == 'IPv4': outer[outer_l3.name].src = self.outer_ip_src outer[outer_l3.name].dst = self.outer_ip_dst outer[outer_l3.name].proto = self.outer_ip_proto else: outer[outer_l3.name].src = self.outer_ip6_src outer[outer_l3.name].dst = self.outer_ip6_dst outer[outer_l3.name].nh = self.outer_ip_proto if self.outer_l3_type == 'IPv4' and self.outer_ip_invalid == 1: outer[outer_l3.name].chksum = 0x1234 """ GRE package: outer/GRE header/inner """ if self.outer_ip_proto == 47: self.pkt = outer / NVGRE() / inner else: self.pkt = outer / ("X" * self.payload_size) wrpcap(self.pcap_file, self.pkt) return self.pkt