def get_info(self, binary, endian): icmp_header, binary = a3_functions.get_next_bytes(binary, SIZE_OF_ICMP_HEADER) # Type self.get_type(icmp_header[0:1], endian) # Code self.get_code(icmp_header[1:2], endian) # Check Sum # Additional info raw self.add_info_raw = icmp_header[4:8] if self.type in [11, 3]: # ICMP that have IP under add info area # IP Header ip_head = IPHeader() binary = ip_head.get_info(binary, endian) self.inner_protocols["IP4"] = ip_head if ip_head.protocol == 17: # IP type is UDP so let's do that udp_head = UDPHeader() binary = udp_head.get_info(binary, endian) self.inner_protocols["UDP"] = udp_head return binary
def __init__(self): self.IP_header = IPHeader() self.inner_protocol = None # self.pcap_hd_info = pcap_ph_info() self.inner_protocol_type = None self.timestamp = 0 self.packet_No = 0 self.RTT_value = 0.0 self.RTT_flag = False self.buffer = None self.orig_time = Packet.orig_time self.incl_len = 0 self.fragmented = False self.last_frag_offset = None
def __init__(self, src_mac, dst_mac, src_ip, dst_ip, interface, src_port, dst_port): self.src_mac = src_mac self.dst_mac = dst_mac self.src_ip = src_ip self.dst_ip = dst_ip self.interface = interface self.src_port = src_port self.dst_port = dst_port self.timeout = 5 # Construct the Ethernet header self.eth_header = EthernetHeader(dst_mac=dst_mac, src_mac=src_mac, type=0x86dd) self.eth_packet = self.eth_header.assembly() # Construct the IPv6 header self.ip_header = IPHeader(version=6, traffic_class=0, flow_label=1, payload_len=20, next_header=socket.IPPROTO_TCP, hop_limit=255, src_address=self.src_ip, dst_address=self.dst_ip) self.ip_packet = self.ip_header.assembly() # Construct the TCP header self.tcp_header = TCPHeader(src_port=self.src_port, dst_port=self.dst_port, seq_num=0, ack_seq=0, header_len=5, fin=0, syn=1, rst=0, psh=0, ack=1, urg=0, window=5840, checksum=0, urg_ptr=0) self.tcp_packet = self.tcp_header.assembly()
class Packet: # pcap_hd_info = None IP_header = None inner_protocol = None inner_protocol_type = None timestamp = 0 packet_No = 0 RTT_value = 0 RTT_flag = False buffer = None orig_time = 0 incl_len = 0 orig_len = 0 fragmented = None last_frag_offset = None def __init__(self): self.IP_header = IPHeader() self.inner_protocol = None # self.pcap_hd_info = pcap_ph_info() self.inner_protocol_type = None self.timestamp = 0 self.packet_No = 0 self.RTT_value = 0.0 self.RTT_flag = False self.buffer = None self.orig_time = Packet.orig_time self.incl_len = 0 self.fragmented = False self.last_frag_offset = None # def get_bytes(self): # header_size = self.IP_header.ip_header_len + self.TCP_header.data_offset # len_with_no_buffer = self.IP_header.total_len # return len_with_no_buffer - header_size def get_info(self, header_binary, endian, micro_sec): ts_sec = header_binary[0:4] ts_usec = header_binary[4:8] incl_len = struct.unpack(endian + "I", header_binary[8:12])[0] # orig_len = struct.unpack(endian + "I", header_binary[12:])[0] self.timestamp_set(ts_sec, ts_usec, self.orig_time, micro_sec) self.packet_No_set() self.incl_len = incl_len return incl_len def packet_data(self, binary, endian): # ethernet header binary_after_e = binary[SIZE_OF_ETHERNET_HEADER:] # check to make sure we are using ip4 in the next part binary = self.IP_header.get_info(binary_after_e, endian) if binary != binary_after_e: # binary is remaining packet data minus the # print(self.IP_header) if self.IP_header.protocol == 1: # ICMP self.inner_protocol = ICMPHeader() # Look to see fragmented or not if self.IP_header.flags["mf"]: self.fragmented = True self.inner_protocol_type = "ICMP" else: binary = self.inner_protocol.get_info(binary, endian) self.last_frag_offset = self.IP_header.fragment_offset # TODO: any logic that gets rid of redundant ICMP packets if self.inner_protocol.type in [ 11, 3, 8, 0, 13, 14, 3, 5, 12, 10, ]: self.inner_protocol_type = "ICMP" else: self.inner_protocol_type = None # print("This is a ICMP") # print(self.inner_protocol) # print(self.inner_protocol.IP_header) # print(self.inner_protocol.UDP_header) elif self.IP_header.protocol == 17: # UDP self.inner_protocol = UDPHeader() # Look to see fragmented or not if self.IP_header.flags["mf"]: self.fragmented = True self.inner_protocol_type = "UDP" else: # if self.packet_No == 22: # print(self) # print(self.IP_header) # print(binary) # print(self.inner_protocol) binary = self.inner_protocol.get_info(binary, endian) # Now check to see if port is in range # if self.packet_No == 22: # print(self) # print(self.IP_header) # print(self.inner_protocol) if (self.inner_protocol.dst_port >= 33434) and (self.inner_protocol.dst_port <= 33625): self.inner_protocol_type = "UDP" self.last_frag_offset = self.IP_header.fragment_offset # print("This is a valid UDP") # print("IP PROTOCOL:") # print(self.IP_header.protocol) else: self.inner_protocol_type = None # print(self.inner_protocol) elif self.IP_header.protocol == 6: # Ip4 self.inner_protocol = TCPHeader() binary = self.inner_protocol.get_info(binary) self.inner_protocol_type = "IP" else: # not a ip4 header so we will set up header and tcp header to None self.IP_header = None # self.TCP_header = None # ip_4 header def timestamp_set(self, buffer1, buffer2, orig_time, micro): seconds = struct.unpack("I", buffer1)[0] if micro: microseconds = struct.unpack("<I", buffer2)[0] nanoseconds = 0 else: microseconds = 0 nanoseconds = struct.unpack("<I", buffer2)[0] self.timestamp = round( (seconds + (microseconds * 0.000001) + (nanoseconds * 0.000000001)) - orig_time, 6, ) # print(self.timestamp,self.packet_No) def packet_No_set(self): Packet.packet_No += 1 self.packet_No = Packet.packet_No if self.packet_No == 1: Packet.orig_time = self.timestamp self.orig_time = self.timestamp self.timestamp = 0 # print(self.packet_No) def get_RTT_value(self, p): rtt = p.timestamp - self.timestamp self.RTT_value = round(rtt, 8) # def get_unique_tuple(self): # return ( # [self.IP_header.src_ip, self.TCP_header.src_port], # [self.IP_header.dst_ip, self.TCP_header.dst_port], # ) def __str__(self): return str(self.__class__) + ": " + str(self.__dict__)
class SYNACK: """ SYN/ACK - An SYN message is sent to a port - If the port is open, an RST will be received; else the port is close """ def __init__(self, src_mac, dst_mac, src_ip, dst_ip, interface, src_port, dst_port): self.src_mac = src_mac self.dst_mac = dst_mac self.src_ip = src_ip self.dst_ip = dst_ip self.interface = interface self.src_port = src_port self.dst_port = dst_port self.timeout = 5 # Construct the Ethernet header self.eth_header = EthernetHeader(dst_mac=dst_mac, src_mac=src_mac, type=0x86dd) self.eth_packet = self.eth_header.assembly() # Construct the IPv6 header self.ip_header = IPHeader(version=6, traffic_class=0, flow_label=1, payload_len=20, next_header=socket.IPPROTO_TCP, hop_limit=255, src_address=self.src_ip, dst_address=self.dst_ip) self.ip_packet = self.ip_header.assembly() # Construct the TCP header self.tcp_header = TCPHeader(src_port=self.src_port, dst_port=self.dst_port, seq_num=0, ack_seq=0, header_len=5, fin=0, syn=1, rst=0, psh=0, ack=1, urg=0, window=5840, checksum=0, urg_ptr=0) self.tcp_packet = self.tcp_header.assembly() def start(self): listen = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(3)) listen.setblocking(0) # send syn sendeth(self.__packet(), self.interface) flags = 0 timeout_start = time.time() while time.time() < timeout_start + self.timeout: # Receive packet try: raw_packet = listen.recvfrom(128) packet = raw_packet[0] # Get ethernet header eth_header = packet[0:14] # Get protocol type; 0x86dd for IPv6 protocol_type = unpack('!6B6BH', eth_header)[12] # Check for IPv6 only if (protocol_type == int(0x86dd)): # Get TCP header tcp_header = unpack('!HHLLBBHHH', packet[54:74]) # Get the TCP destionation and source ports tcp_src_port = tcp_header[0] tcp_dst_port = tcp_header[1] if tcp_dst_port == self.src_port and tcp_src_port == self.dst_port: # Return the received flags flags = int(tcp_header[5]) break except: pass # if open, flags = rst if flags == 4: # 0b000100 print('[INFO] Port [:{}] is '.format(self.dst_port) + \ bcolors.OKGREEN + 'OPEN' + bcolors.ENDC) # else close else: print('[INFO] Port [:{}] is '.format(self.dst_port) + \ bcolors.FAIL + 'CLOSE' + bcolors.ENDC) def __packet(self): # pseudo header fields placeholder = 0 protocol = socket.IPPROTO_TCP tcp_length = len(self.tcp_packet) psh = self.ip_header.src_address_ipv6 + \ self.ip_header.dst_address_ipv6 + \ pack('!BBH', placeholder, protocol, tcp_length) psh = psh + self.tcp_packet # make the tcp header again and fill the correct checksum self.tcp_header.checksum = checksum(psh) self.tcp_packet = self.tcp_header.assembly() # final full packet - syn packets dont have any data packet = self.eth_packet + self.ip_packet + self.tcp_packet return packet
def parse_header(self, raw_buffer): if len(raw_buffer) < header_min_size: return None return IPHeader(raw_buffer)