def listen_packets_loop(): """Initializes the socket used to interface with the C program, and listen for any incoming packets. When we hear one, parse it with scapy and update the display to show information about packet. """ global packet global c_socket print 'Listening for packets...' while True: # Receive any packet that the C side has sent over. print 'Sending request' c_packet = SEASIDE.request_SEASIDE(c_socket, c_socket_lock, SEASIDE_FLAGS.GET_PACKET.value) if c_packet != '': # Parse packet with scapy so we can pull it apart easier. packet = scapy.Ether(c_packet) num_packets_received = SEASIDE.request_SEASIDE( c_socket, c_socket_lock, SEASIDE_FLAGS.NUM_PACKETS.value) num_packets_received = struct.unpack('=I', num_packets_received) update_packet_info(packet, num_packets_received) time.sleep(2)
def command(self, command, data): """Sends the C side a command. The flags can be found in SEASIDE. Args: command (int): The flag to send to the C side. data (str): Any additional data to send with the flag. TODO: Clean up the types / documentation. TODO: Remove the eval. """ SEASIDE.send_SEASIDE(c_socket, c_socket_lock, int(command), eval(data))
def upload_pcap_file(self, file_data): """Takes a pcap file, and sends it to the C side for sending. Args: file_data (File): A CherryPy representation of a file. TODO: Find a way to remove that NamedTemporaryFile middleman. """ pcap_file = tempfile.NamedTemporaryFile() pcap_file.write(bytearray(file_data.file.read())) pcap_file.seek(0) packet = rdpcap(pcap_file.name)[0] packet = conversions.convert_packet_int_array(packet) SEASIDE.send_SEASIDE(c_socket, c_socket_lock, 0, packet)
def update_statistics_loop(): """Gets cpu usage and bandwidth and displays it on the LCD. """ global c_socket_lock while True: d_bytes = SEASIDE.request_SEASIDE(c_socket, c_socket_lock, SEASIDE_FLAGS.GET_BANDWIDTH.value) print repr(d_bytes) d_bytes = struct.unpack('=Q', d_bytes) d_bytes = d_bytes[0] bw, bw_unit = conversions.convert_bandwidth_units(d_bytes) bandwidth_output = 'Bw:%5.1f %s' % (bw, bw_unit) thread_lcd.lock_and_display_bandwidth_LED(lcd, lcd_lock, bw, bw_unit) screen_output[Screens.Summary.value][1] = bandwidth_output avg_cpu_usage, per_core_cpu_usage = computations.read_cpu_usage() screen_output[Screens.CPU.value][0] = \ 'CPU Usage: %4.1f%%' % (avg_cpu_usage) screen_output[Screens.CPU.value][1] = \ '%2.0f%% %2.0f%% %2.0f%% %2.0f%%' % tuple(per_core_cpu_usage) time.sleep(1)
def command_and_respond(self, command, size): """Sends a command to the C side, and gets the response. Some flags are used for getting info from the C side, such as getting bandwidth, or the structure of the current packet. Args: command (int): The flag to send to the C side. size (str): The size of the reponse that you're expecting. See https://docs.python.org/2/library/struct.html for different sizes. Returns: str: The response that was received, encoded in hex format. The format looks like this: 12abc4394fa. I.e. there's no dashes or spaces in between each byte, and no \\x or equivalent. As a sidenote, that \\x used to have only one slash, but it threw errors, because apparently it couldn't be parsed... TODO: What if the value returned isn't an int? Make it more generic. """ temp = SEASIDE.request_SEASIDE(c_socket, c_socket_lock, int(command)) temp = struct.unpack('=' + size, temp)[0] temp = struct.pack('!' + size, temp) return temp.encode('hex')
def update_statistics_loop(): """Gets cpu usage and bandwidth and displays it on the LCD. """ global c_socket_lock while True: d_bytes = SEASIDE.request_SEASIDE(c_socket, c_socket_lock, SEASIDE_FLAGS.GET_BANDWIDTH.value) print repr(d_bytes) d_bytes = struct.unpack('=Q', d_bytes) d_bytes = d_bytes[0] bw, bw_unit = conversions.convert_bandwidth_units(d_bytes) bandwidth_output = 'Bw:%5.1f %s' % (bw, bw_unit) thread_lcd.lock_and_display_bandwidth_LED( lcd, lcd_lock, bw, bw_unit) screen_output[Screens.Summary.value][1] = bandwidth_output avg_cpu_usage, per_core_cpu_usage = computations.read_cpu_usage() screen_output[Screens.CPU.value][0] = \ 'CPU Usage: %4.1f%%' % (avg_cpu_usage) screen_output[Screens.CPU.value][1] = \ '%2.0f%% %2.0f%% %2.0f%% %2.0f%%' % tuple(per_core_cpu_usage) time.sleep(1)
def load_pcap_file(self, filename): """Takes a filename, and attempts to load it from pcap_files/. Reads the files, takes the first packet that is specified in that file, and then sends it over to the C side for sending. Args: filename (str): Name of the file located in the pcap_files dir. """ if filename == '': return try: packet = rdpcap('pcap_files/' + filename)[0] except IOError: print filename, "doesn't exist." return packet = conversions.convert_packet_int_array(packet) SEASIDE.send_SEASIDE(c_socket, c_socket_lock, 0, packet)
def packet_config(self, packet_layers): """Takes the configured layers and sends it to the C side. Takes the packet_layers (in a JSON format, see configure_packet_layers above), turns it into a legitimate Scapy packet, and then sends it to the C side. Args: packet_layers (JSON): The packet layers in a string of JSON. See configure_packet_layers above for an example of what this would look like. """ # If the user didn't even configure a packet, but just clicked the # "Done configuring" button like the silly user they are. if packet_layers == '[]': return # Turn it into a Scapy packet. packet = configure_packet_layers(packet_layers) # Turn it into the corresponding int array. packet = conversions.convert_packet_int_array(packet) # Send it to the C side, using the SEASIDE format. SEASIDE.send_SEASIDE(c_socket, c_socket_lock, 0, packet)
def listen_packets_loop(): """Initializes the socket used to interface with the C program, and listen for any incoming packets. When we hear one, parse it with scapy and update the display to show information about packet. """ global packet global c_socket print 'Listening for packets...' while True: # Receive any packet that the C side has sent over. print 'Sending request' c_packet = SEASIDE.request_SEASIDE(c_socket, c_socket_lock, SEASIDE_FLAGS.GET_PACKET.value) if c_packet != '': # Parse packet with scapy so we can pull it apart easier. packet = scapy.Ether(c_packet) num_packets_received = SEASIDE.request_SEASIDE(c_socket, c_socket_lock, SEASIDE_FLAGS.NUM_PACKETS.value) num_packets_received = struct.unpack('=I', num_packets_received) update_packet_info(packet, num_packets_received) time.sleep(2)
def update_statistics_loop(c_socket, c_socket_lock): """Update the values of bandwidth and CPU use. Calculates bandwidth using change in bytes received over time, which is provided by the C-side. Calculates CPU using psutil. """ while True: d_bytes = SEASIDE.request_SEASIDE(c_socket, c_socket_lock, SEASIDE_FLAGS.GET_BANDWIDTH.value) print "D_bytes:", repr(d_bytes) d_bytes = struct.unpack('=Q', d_bytes) d_bytes = d_bytes[0] bw, bw_unit = conversions.convert_bandwidth_units(d_bytes) cpu, percore = computations.read_cpu_usage() # percore unused screen_output[0] = 'Bw:%2.1f %s' % (bw, bw_unit) screen_output[1] = 'CPU:%2.1f%%' % (cpu) time.sleep(1)
def update_statistics_loop(c_socket, c_socket_lock): """Update the values of bandwidth and CPU use. Calculates bandwidth using change in bytes received over time. Calculates CPU using psutil. """ while True: d_bytes = SEASIDE.request_SEASIDE(c_socket, c_socket_lock, SEASIDE_FLAGS.GET_BANDWIDTH.value) d_bytes = struct.unpack('=Q', d_bytes) d_bytes = d_bytes[0] bw, bw_unit = conversions.convert_bandwidth_units(d_bytes) cpu, percore = computations.read_cpu_usage() # percore unused screen_output[0] = 'Bw:%2.1f %s' % (bw, bw_unit) screen_output[1] = 'CPU:%2.1f%%' % (cpu) time.sleep(1)
def user_interaction(lcd, lcd_lock, c_socket, c_socket_lock): """Uses the LCD screen to interact with the user. Waits for the user to press a button and then performs the corresponding action. While it is waiting, update_display_loop has control of the screen and is displaying the statistics screen. When the user enters a configuration option, that function takes control of the screen and update_display_loop waits until it has released the lock to resume control. The SEASIDE protocol is used for communication between the C and Python programs. For more information about SEASIDE, see shared_files/SEASIDE.py. Args: lcd (LCD_Input_Wrapper object): the lcd screen to use. lcd_lock (RLock object): the lock associated with the screen. c_socket (socket object): the socket used for SEASIDE communication c_socket_lock (RLock object): the lock associated with the socket. """ led_state = (0, 1, 0) # (r, g, b) for the screen LED is_sending = False global packet delay_seconds, delay_useconds = 1, 0 delay_bytes = conversions.convert_delay_bytes(delay_seconds, delay_useconds) while True: if lcd.is_pressed(LCD.SELECT): # Configure packet packet_temp = pgen.configure_packet(lcd, lcd_lock) if packet_temp is None: time.sleep(0.3) continue packet = conversions.convert_packet_int_array(packet_temp) SEASIDE.send_SEASIDE(c_socket, c_socket_lock, SEASIDE_FLAGS.DELAY.value, delay_bytes) time.sleep(1) # TODO: This separates sends. Make it unnecessary. SEASIDE.send_SEASIDE(c_socket, c_socket_lock, SEASIDE_FLAGS.PACKET.value, packet) led_state = (0, 1, 0) elif lcd.is_pressed(LCD.UP): # Begin sending SEASIDE.send_SEASIDE(c_socket, c_socket_lock, SEASIDE_FLAGS.START.value) is_sending = True elif lcd.is_pressed(LCD.DOWN): # Stop sending SEASIDE.send_SEASIDE(c_socket, c_socket_lock, SEASIDE_FLAGS.STOP.value) is_sending = False elif lcd.is_pressed(LCD.LEFT): # Send single packet SEASIDE.send_SEASIDE(c_socket, c_socket_lock, SEASIDE_FLAGS.SINGLE_PACKET.value) threaded_lcd.flash_led(lcd, lcd_lock, *led_state) elif lcd.is_pressed(LCD.RIGHT): # Configure delay delay_seconds, delay_useconds = pgen.configure_delay(lcd, lcd_lock) delay_bytes = conversions.convert_delay_bytes(delay_seconds, delay_useconds) SEASIDE.send_SEASIDE(c_socket, c_socket_lock, SEASIDE_FLAGS.DELAY.value, delay_bytes) threaded_lcd.flash_led(lcd, lcd_lock, 0, 0, 1) if is_sending: # Ensures the LED always stays the right color. threaded_lcd.lock_and_set_led_color(lcd, lcd_lock, *led_state) else: # Turns it off if we've stopped sending threaded_lcd.lock_and_set_led_color(lcd, lcd_lock, 0, 0, 0) time.sleep(0.3) # Prevents duplicate presses
def user_interaction(lcd, lcd_lock, c_socket, c_socket_lock): led_state = (0, 1, 0) is_sending = False global packet delay_seconds, delay_useconds = 1, 0 delay_bytes = conversions.convert_delay_bytes(delay_seconds, delay_useconds) while True: if lcd.is_pressed(LCD.SELECT): # Configure packet packet_temp = pgen.configure_packet(lcd, lcd_lock) if packet_temp is None: time.sleep(0.3) continue packet = conversions.convert_packet_int_array(packet_temp) SEASIDE.send_SEASIDE(c_socket, c_socket_lock, SEASIDE_FLAGS.DELAY.value, delay_bytes) time.sleep(1) # TODO: Fix needing this sleep function SEASIDE.send_SEASIDE(c_socket, c_socket_lock, SEASIDE_FLAGS.PACKET.value, packet) led_state = (0, 1, 0) elif lcd.is_pressed(LCD.UP): # Begin sending SEASIDE.send_SEASIDE(c_socket, c_socket_lock, SEASIDE_FLAGS.START.value) is_sending = True elif lcd.is_pressed(LCD.RIGHT): # Configure delay delay_seconds, delay_useconds = pgen.configure_delay(lcd, lcd_lock) delay_bytes = conversions.convert_delay_bytes( delay_seconds, delay_useconds) SEASIDE.send_SEASIDE(c_socket, c_socket_lock, SEASIDE_FLAGS.DELAY.value, delay_bytes) threaded_lcd.flash_led(lcd, lcd_lock, 0, 0, 1) elif lcd.is_pressed(LCD.LEFT): # Send single packet SEASIDE.send_SEASIDE(c_socket, c_socket_lock, SEASIDE_FLAGS.SINGLE_PACKET.value) threaded_lcd.flash_led(lcd, lcd_lock, *led_state) elif lcd.is_pressed(LCD.DOWN): # Stop sending SEASIDE.send_SEASIDE(c_socket, c_socket_lock, SEASIDE_FLAGS.STOP.value) is_sending = False if is_sending: threaded_lcd.lock_and_set_led_color(lcd, lcd_lock, *led_state) else: threaded_lcd.lock_and_set_led_color(lcd, lcd_lock, 0, 0, 0) time.sleep(0.3)
def load_pcap_file(self, filename): if filename == '': return packet = rdpcap('pcap_files/' + filename)[0] packet = conversions.convert_packet_int_array(packet) SEASIDE.send_SEASIDE(c_socket, c_socket_lock, 0, packet)