Advertisement
Guest User

Untitled

a guest
Jan 22nd, 2020
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.61 KB | None | 0 0
  1. #! /usr/bin/env  python
  2. # -*- coding: utf-8 -*-
  3.  
  4. """
  5. Script in python for the project in CPL.
  6. Date: 27.12.2019
  7. Last modification: 21.01.2020
  8. Author: Michael da Silva & Nenad Rajic
  9. Version Python: 2.7.15+
  10. Version script: 0.4.3
  11. """
  12.  
  13. from scapy.all import *
  14.  
  15. OWN_ADDR = "0101" #Unicast address of the user
  16. MULTI_ADDR = "1011" #Multicast address of the user
  17. BROADCAST = "1111" #Broadcast address
  18. SIZE_ROW = 7
  19. SIZE_COLUMN = 6
  20. SIZE_ADDR = 4 #Size of destination and source address
  21. MAX_INT_42_BITS = 4398046511103
  22. BITS_FOR_SIZE = 6
  23.  
  24. """
  25. Crée un payload contenant des bits aléatoires (juqu'à 42 bits)
  26. """
  27. def RandomPayload():
  28.     number = random.randint(0, MAX_INT_42_BITS)
  29.     number = "{0:b}".format(number) #Transforme un integer en chiffre binaire
  30.     return number
  31. """
  32. Corrige le bit érroné grâce au numéro de ligne et numéro de colonne
  33. """
  34. def CorrectErrorPayload(bits, row, column):
  35.     bits_corrected = bits
  36.     bits_corrected[(row*(SIZE_ROW+1)) + column] = 0 if bits[(row*(SIZE_ROW+1)) + column] else 1
  37.     print("Error corrected")
  38.     return bits_corrected
  39. """
  40. Ajoute des bits de bourrage au payload s'il n'a pas assez de bits (42 bits de data demandé)
  41. """
  42. def FillPayload(payload):
  43.     while len(payload) != SIZE_ROW * SIZE_COLUMN:
  44.         payload.append(0)
  45.     return payload
  46. """
  47. Transforme une liste de int en une chaîne de caractère
  48. """
  49. def BinaryToString(frame):
  50.     s = ''.join([str(i) for i in frame])
  51.     return s
  52. """
  53. Transforme une chaîne de caractère en liste de integer
  54. """
  55. def StringToBinary(frame):
  56.     int_array = list(map(int, frame))
  57.     return int_array
  58. """
  59. Retourne en binaire la longueur réelle d'un payload (sans bit de bourrage)
  60. """
  61. def PayloadSize(length):
  62.     binary = "{0:b}".format(length)
  63.     while len(binary) != BITS_FOR_SIZE:
  64.         binary = "0" + binary
  65.     return binary
  66. """
  67. Vérifie les parités du payload
  68. """
  69. def HVParityCheck(payload):
  70.     matrix = []
  71.     errors_row = []
  72.     errors_column = []
  73.    
  74.     while payload: #Création d'une matrice pour faciliter la vérification
  75.         matrix.append(payload[:(SIZE_ROW + 1)])
  76.         payload = payload[(SIZE_ROW + 1):]
  77.    
  78.     for i in range(len(matrix)):
  79.         if SimpleParityCheck(matrix[i]): #Vérification des parités horizontales
  80.             errors_row.append(i)
  81.  
  82.     for j in range(len(matrix[0])):
  83.         column = [] #Création d'une colomne pour la vérification des parités verticales
  84.         for i in range(len(matrix)):
  85.             column.append(matrix[i][j])
  86.         if SimpleParityCheck(column):
  87.             errors_column.append(j)
  88.    
  89.     if len(errors_row) > 1 or len(errors_column) > 1:
  90.         print("Error in data. Can't correct it (2-3 bits error or 8 bits burst)")
  91.         return [-1]
  92.     elif len(errors_row) == 1 & len(errors_column) == 1:
  93.         print("1 error to correct")
  94.         return [errors_row[0], errors_column[0]] #Renvoie des numéros de ligne et colomne
  95.     else:
  96.         print("No error detected")
  97.         return []
  98. """
  99. Calcule les parités verticales et horizontales pour le payload
  100. """
  101. def HVParityCalculate(payload):
  102.     result = []
  103.     matrix = []
  104.    
  105.     for i in range(SIZE_COLUMN):
  106.         matrix.append(SimpleParityCalculate(payload[i*SIZE_ROW:(i+1)*SIZE_ROW])) #Calcul des parités horizontales
  107.  
  108.     parity_line = []
  109.     parity = 0
  110.    
  111.     for i in range(SIZE_ROW):
  112.         for row in matrix:
  113.             parity += row[i] #Calcul de la dernière ligne contenant les parités verticales
  114.         parity_line.append(parity % 2)
  115.         parity = 0
  116.    
  117.     matrix.append(SimpleParityCalculate(parity_line)) #Calcul de la parité de la dernière ligne
  118.     result = [bit for row in matrix for bit in row] #Transformation de la matrice en tableau à une dimension
  119.     return result
  120. """
  121. Enlève les bits de parité du payload et le renvoie nettoyé
  122. """
  123. def CleanPayload(payload):
  124.     payload_cleaned = []
  125.  
  126.     for i in range(SIZE_COLUMN):
  127.         payload_cleaned.append(payload[:(SIZE_ROW)]) #Nouveau payload sans bit de parité
  128.         payload = payload[(SIZE_ROW + 1):]
  129.     result = []
  130.     for i in payload_cleaned: #Nouvelle liste des bits
  131.         for j in i:
  132.             result.append(j)
  133.    
  134.     return result
  135. """
  136. Vérifie la parité d'une trame donnée et renvoie si la parité est juste ou non
  137. """
  138. def SimpleParityCheck(frame):
  139.     parity_to_check = frame[-1]
  140.     parity = 0
  141.    
  142.     for i in frame[:-1]:
  143.         parity += i
  144.  
  145.     parity %= 2
  146.  
  147.     if parity_to_check == parity:
  148.         return 0
  149.     else:
  150.         return -1
  151. """
  152. Calcule la parité d'une trame donnée et renvoie la trame contenant la parité
  153. """
  154. def SimpleParityCalculate(frame):
  155.     frame_with_parity = frame
  156.    
  157.     total = 0
  158.     for i in frame:
  159.         total += i
  160.  
  161.     frame_with_parity.append(total % 2)
  162.     return frame_with_parity
  163. """
  164. Envoie automatiquement une payload avec l'adresse de destination, l'adresse source et la longueur du payload (permet d'enlever les bits de bourrage)
  165. """
  166. def SendFrameAutom(destination, payload):
  167.     length = 0 
  168.     destination = StringToBinary(destination)
  169.     source = StringToBinary(OWN_ADDR)
  170.     payload = StringToBinary(payload)
  171.    
  172.     if len(payload) < SIZE_ROW * SIZE_COLUMN:
  173.         length = len(payload)
  174.         print("Payload too small")
  175.         print("Bits filling...")
  176.         payload = FillPayload(payload) #Bourrage du payload si bits manquant (n'atteint pas la taille de 42 bits)
  177.         print("Done!")
  178.     elif len(payload) == (SIZE_ROW * SIZE_COLUMN):
  179.         length = SIZE_ROW * SIZE_COLUMN
  180.  
  181.     length = PayloadSize(length) #Taille du payload en binaire
  182.     length = SimpleParityCalculate(StringToBinary(length))
  183.    
  184.     print("Calculating the parity of destination address...")
  185.     destination = SimpleParityCalculate(destination) #Calcul de la parité de l'adresse de destination
  186.     print("Done!")
  187.     print("Calculating the parity of source address...")
  188.     source = SimpleParityCalculate(source) #Calcul de la parité de l'adresse source
  189.     print("Done!")
  190.     print("Calculating the parity of payload...")
  191.     payload = HVParityCalculate(payload) #Calcul de les parités du payload
  192.     print("Done!")
  193.     #Transformation des informations de binaire à chaîne de caractère (pour la fonction SendFrame)
  194.     destination = BinaryToString(destination)
  195.     source = BinaryToString(source)
  196.     length = BinaryToString(length)
  197.     payload = BinaryToString(payload)
  198.    
  199.     print("Sending packet...")
  200.     SendFrame(destination, source, length, payload)
  201. """
  202. Reçoit un paquet et retire les informations telle que l'adresse de destination, l'adresse source, la longueur du payload et le payload
  203. """
  204. def ReceiveFrameAutom(packet):
  205.     if packet.load[:SIZE_ADDR] == OWN_ADDR or packet.load[:SIZE_ADDR] == MULTI_ADDR or packet.load[:SIZE_ADDR] == BROADCAST: # Vérification de l'adresse de destination
  206.         print("Packet received with one of the valid addresses")
  207.         destination = packet.load[:(SIZE_ADDR+1)]
  208.         source = packet.load[(SIZE_ADDR+1):(SIZE_ADDR+1)*2]
  209.         length = packet.load[(SIZE_ADDR+1)*2:((SIZE_ADDR+1)*2)+(BITS_FOR_SIZE+1)]
  210.         payload = packet.load[((SIZE_ADDR+1)*2)+(BITS_FOR_SIZE+1):]
  211.        
  212.         print("Checking parity of the destination address...")
  213.         test_dst = SimpleParityCheck(StringToBinary(destination)) # Test de la parité de l'adresse de destination
  214.    
  215.         if test_dst:
  216.             print("Error in destination, packet dropped")
  217.             return
  218.         else:
  219.             print("Destination correct!")
  220.             destination = destination[:-1]
  221.  
  222.         test_src = SimpleParityCheck(StringToBinary(source)) # Test de la parité de l'adresse source
  223.         if test_src:
  224.             print("Error in destination, packet dropped")
  225.             return
  226.         else:
  227.             print("Destination correct!")
  228.             source = source[:-1]
  229.  
  230.         test_size = SimpleParityCheck(StringToBinary(length)) # Test de la parité de la taille du payload
  231.         if test_size:
  232.             print("Error in size of payload, packet dropped")
  233.             return
  234.         else:
  235.             length = length[:-1]
  236.  
  237.         print("Checking parity of the payload...")
  238.         test_payload = HVParityCheck(StringToBinary(payload)) # Test des parités du payload
  239.        
  240.         if len(test_payload) == 1: # Rejette le paquet s'il y a plus d'une erreur dans le payload
  241.             return
  242.         elif len(test_payload) == 2:
  243.             payload = CorrectErrorBinary(payload, test_payload[0], test_payload[1])
  244.        
  245.         print("Cleaning the payload from the parity bits...")
  246.         payload = BinaryToString(CleanPayload(payload))
  247.         print("Done!")
  248.  
  249.         payload = payload[:int(length, 2)] # Le payload ne garde que les bits d'information reçu, pas les bits de bourrage
  250.    
  251.         print("\n\n----------Packet received----------\n")
  252.         print("Destination: " + destination)
  253.         print("Source: " + source)
  254.         print("Payload: " + payload)
  255.         print("\n-----------------------------------\n\n")
  256. """
  257. Envoie une trame via le protocole Ethernet en broadcast (notre protocole gère les adresses de destination)
  258. """
  259. def SendFrame(destination, source, length, payload):
  260.     data = destination + source + length + payload
  261.     sendp(Ether(dst="ff:ff:ff:ff:ff:ff")/data)
  262. """
  263. Permet de voir les paquets envoyé sur le réseau et de récupérer ceux ayant comme destinataire l'adresse de broadcast
  264. """
  265. def Sniff():
  266.     sniff(filter = "ether dst ffffffffffff", prn = ReceiveFrameAutom) # Renvoi du paquet capturé à la fonction ReceiveFrameAutom
  267. """
  268. Fonction main du script avec quelques tests
  269. """
  270. def Main():
  271.     """print("Receive(r) or Send(s) ?: ")
  272.     choice = raw_input()
  273.  
  274.     if choice == "s":
  275.         while 1:
  276.             print("Destination: ")
  277.             dest = raw_input()
  278.             print("Data (if you type enter without data, a random one is created): ")
  279.             data = raw_input()
  280.            
  281.             if not len(data):
  282.                 data = RandomPayload()
  283.             SendFrameAutom(dest, data)
  284.     elif choice == "r":
  285.         Sniff()"""
  286.  
  287.     # Test pour la détection et correction d'erreur
  288.     """
  289.     data = "00000000000000000000000000000000000000000000000000000000"
  290.     data_1error = "00000000000000000000000000000010000000000000000000000000"
  291.     data_2errors = "00000000000000000000000000000000000010100000000000000000"
  292.     data_3errors = "00000000000000000001011000000000000000000000000000000000"
  293.     data_8burst = "00000000000001000000100000000000000000000000000000000000"
  294.    
  295.     print(data_8burst)
  296.     test = HVParityCheck(StringToBinary(data_8burst))
  297.     if len(test) == 2:
  298.         payload = CorrectErrorPayload(StringToBinary(data_1error), test[0], test[1])
  299.         print(BinaryToString(payload))
  300.     elif len(test) == 1:
  301.         return
  302.     """
  303.     # Test pour le calcul de parité simple et vérification
  304.     """
  305.     data = "10010"
  306.     test = SimpleParityCalculate(StringToBinary(data))
  307.     print(BinaryToString(test))
  308.     if SimpleParityCheck(test) < 0:
  309.         print("Error in parity")
  310.     else:
  311.         print("Parity correct")
  312.     """
  313.     # Test pour le calcul et la vérification des parités d'un payload
  314.     """
  315.     data = RandomPayload()
  316.     print(data)
  317.     data = FillPayload(data)
  318.     test = HVParityCalculate(StringToBinary(data))
  319.     print(BinaryToString(test))
  320.     HVParityCheck(test)
  321.     """
  322.     # Test pour le calcul de la taille réelle d'un payload (aucun bit de bourrage)
  323.     """
  324.     data = "11"
  325.     length = len(data)
  326.     data = BinaryToString(FillPayload(StringToBinary(data)))
  327.     print(data)
  328.     length = PayloadSize(length)
  329.     data = data[:int(length, 2)]
  330.     print(data)
  331.     """
  332. Main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement