153 lines
3.8 KiB
Python
153 lines
3.8 KiB
Python
import socket
|
|
import struct
|
|
import logging
|
|
import threading
|
|
|
|
from pytun import TunTapDevice, IFF_TAP
|
|
|
|
|
|
########################## Defining global variables
|
|
|
|
|
|
ADDRESS = "127.0.0.1"; # Address to connect to
|
|
PORT = 9999; # Port to connect to
|
|
|
|
NIC_NAME = "client"; # Name for the TAP interface that gonna be created
|
|
|
|
CONFIGURE_NIC = True; # If you prefer to set up the interface manualy set it to False
|
|
|
|
NIC_IP = "10.0.0.2"; # IP to be set for the interface
|
|
NIC_NETMASK = "255.255.255.0"; # Netmask to be used with the interface
|
|
|
|
MTU = 1500; # MTU that gonna be set for the interface, please don't change it if you don't know what you are doing
|
|
|
|
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s %(message)s\n') # Sets logging level and format. Possible levels: DEBUG, INFO, WARNING, ERROR, CRITICAL Read python logging module documentation for more detailes
|
|
|
|
|
|
# Don't change if you don't know what are you doing
|
|
connected = False # Stores the connection status
|
|
FRAME_SIZE = MTU + 42 # MTU is the size of payload, frame itself take 42 more bytes
|
|
|
|
########################## Defining global variables (END)
|
|
|
|
|
|
|
|
|
|
|
|
########################## Defining functions
|
|
|
|
|
|
def recive(socket, NIC): # A function that reads socket for new data and writes this data to the NIC
|
|
|
|
global FRAME_SIZE # Read what they are used for in "Defining global variables" section above
|
|
global connected
|
|
|
|
buffer_ = " " # Setting buffer to " " so it's not empty and the loop can start
|
|
|
|
while buffer_ != b'': # If buffer_ is b'' that meas the server closed the socket
|
|
|
|
buffer_ = socket.recv(FRAME_SIZE) # reciving data from the server
|
|
|
|
if buffer_ != b'': # If buffer_ is still not empty, write it to the NIC
|
|
|
|
NIC.write(buffer_)
|
|
|
|
logging.debug(f'Recived: {buffer_}')
|
|
|
|
logging.info("Connection with the server lost. Reconnecting...")
|
|
connection = False
|
|
|
|
|
|
|
|
|
|
def send(socket, NIC): # The function reads the NIC for new frames and send them to the server
|
|
|
|
global FRAME_SIZE # Read what they are used for in "Defining global variables" section above
|
|
global connected
|
|
|
|
while connected == True:
|
|
|
|
buffer_ = NIC.read(FRAME_SIZE) # Reads outgoing frames
|
|
socket.send(buffer_) # Sends the frames
|
|
|
|
logging.debug(f'Sent: {buffer_}')
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
global NIC_NAME # Read what they are used for in "Defining global variables" section above
|
|
global MTU
|
|
global CONFIGURE_NIC
|
|
global NIC_IP
|
|
global NIC_NETMASK
|
|
global ADDRESS
|
|
global PORT
|
|
global connected
|
|
|
|
|
|
|
|
|
|
# Setting up a TAP interface
|
|
NIC = TunTapDevice(flags=IFF_TAP, name=NIC_NAME)
|
|
NIC.mtu = MTU
|
|
|
|
if CONFIGURE_NIC:
|
|
|
|
NIC.addr = NIC_IP
|
|
NIC.netmask = NIC_NETMASK
|
|
|
|
NIC.up()
|
|
|
|
|
|
|
|
|
|
# Setting up a socket
|
|
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
|
|
|
|
logging.info(f'Connecting to {ADDRESS}:{PORT}')
|
|
|
|
while True:
|
|
|
|
try:
|
|
|
|
client_socket.connect((ADDRESS, PORT))
|
|
|
|
connected = True
|
|
|
|
logging.info(f'Connected {ADDRESS}:{PORT}')
|
|
|
|
sending_thread = threading.Thread(target=send, args=(client_socket, NIC))
|
|
sending_thread.start()
|
|
|
|
recive(client_socket, NIC)
|
|
|
|
except Exception: # If there is an error execute the code below
|
|
|
|
logging.debug("An error occurred during connection. Reconnecting")
|
|
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Recreating socket
|
|
|
|
except KeyboardInterrupt: # if there is a keyboard interrupt (CTRL + C) it gonna close the socket and the NIC and break the loop
|
|
|
|
NIC.close()
|
|
client_socket.close()
|
|
break
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
########################## Defining functions (END)
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__': # Starting the main function
|
|
main()
|
|
|