This shows you the differences between two versions of the page.
|
isrm:laboratoare:v2:01 [2024/06/27 22:23] mbarbulescu created |
isrm:laboratoare:v2:01 [2024/06/28 09:48] (current) mbarbulescu [Task 03: Basic plot] |
||
|---|---|---|---|
| Line 48: | Line 48: | ||
| </code> | </code> | ||
| + | ===== Despre ns-3 ===== | ||
| + | ''ns-3'' este un simulator de rețele (''Ethernet'', ''Wi-Fi'', ''4G'' etc.) ce oferă: | ||
| + | * modele pentru studiul circulației unui pachet în rețea | ||
| + | * un engine pentru simulări de rețele complexe (noduri, modele de propagare, trafic ''UDP''/''TCP'' etc.) | ||
| + | * un mecanism de tracing atat in format text, cat și în format pcap. | ||
| + | Simulatorul este scris în ''C++'', iar modelele se pot dezvolta în ''C++'' sau ''Python''. In cadrul laboratoarelor vom folosi și vom dezvolta modele în ''C++'' deoarece capabilitatile si suportul oferite in ''ns-3'' sunt mai bune decat cele pentru ''Python''. | ||
| + | **Obiectiv:** Acest laborator oferă o idee de bază a modului în care funcționează simulatorul: | ||
| + | * cum se pregătește o simulare, unde se găsesc componentele interne | ||
| + | * cum se configurează componentele de rețea. | ||
| + | * in principal vom discuta experimente simple, familiare unui student care a luat un curs introductiv de rețele. | ||
| + | |||
| + | Cele mai importante pagini de parcurs despre ''ns-3'' la început, dar și în timpul laboratoarelor sunt: | ||
| + | * [[https://www.nsnam.org/docs/tutorial/html/index.html|Tutorial pentru utilizatori]] | ||
| + | * [[https://www.nsnam.org/docs/manual/html/index.html|Development & Manual]] | ||
| + | |||
| + | |||
| + | ===== Task 00: Rulare exemple existente ===== | ||
| + | |||
| + | Pentru inceput, puteti parcurge [[https://www.nsnam.org/docs/tutorial/html/index.html|Tutorial ns-3]], indeosebi urmatoarele sectiuni: | ||
| + | - [[https://www.nsnam.org/docs/tutorial/html/conceptual-overview.html|Conceptual Overview]] | ||
| + | - [[https://www.nsnam.org/docs/tutorial/html/building-topologies.html|Building Topologies]] | ||
| + | - [[https://www.nsnam.org/docs/tutorial/html/tracing.html|Tracing]] | ||
| + | |||
| + | În cadrul laboratorului ne vom concentra pe simulări Wi-Fi (''IEEE 802.11''). Puteti gasi exemple de simulări (în afara celor pe care le veți primi pentru laboratorul de ISRM) în ''ns3/examples/wireless'' | ||
| + | |||
| + | Ne propunem să rulăm un exemplu simplu: ''ns3/examples/wireless/wifi-tcp.cc''. Acesta constă dintr-o stație (''STA'') care se conectează la un access point (''AP'') folosind ''802.11n''. Traficul este ''uplink'' de la ''STA'' la ''AP''. Putem rula orice exemplu astfel: | ||
| + | |||
| + | <code bash> | ||
| + | ./enter-img.sh isrm2024 | ||
| + | |||
| + | root@isrm-vm:/home/student/isrm$ ./ns3 run wifi-tcp | ||
| + | 1.1s: 46.2797 Mbit/s | ||
| + | 1.2s: 55.2294 Mbit/s | ||
| + | (...) | ||
| + | 10.8s: 55.465 Mbit/s | ||
| + | 10.9s: 44.9843 Mbit/s | ||
| + | |||
| + | Average throughput: 52.15 Mbit/s | ||
| + | </code> | ||
| + | |||
| + | Dacă vrem să transmitem parametrii în linia de comandă simulării (deoarece ''wifi-tcp'' suportă), o putem face cu ghilimele: | ||
| + | |||
| + | <code bash> | ||
| + | root@isrm-vm:/home/student/isrm$ ./ns3 run "wifi-tcp --pcap --simulationTime=3" | ||
| + | 1.1s: 45.8086 Mbit/s | ||
| + | 1.2s: 55.3472 Mbit/s | ||
| + | (...) | ||
| + | 3.9s: 52.7565 Mbit/s | ||
| + | |||
| + | Average throughput: 52.9017 Mbit/s | ||
| + | </code> | ||
| + | |||
| + | Întrucât opțiunea ''%%--%%pcap'' activează mecanismul de [[https://www.nsnam.org/docs/tutorial/html/tracing.html#pcap|pcap tracing din ns-3]] (vom discuta mai târziu despre acesta), putem vizualiza cu wireshark următoarele capturi care se generează în directorul curent: | ||
| + | |||
| + | <code bash> | ||
| + | root@isrm-vm:/home/student/isrm# ls *.pcap | ||
| + | AccessPoint-0-0.pcap Station-1-0.pcap | ||
| + | </code> | ||
| + | |||
| + | ===== Task 01: Analiza PCAP ===== | ||
| + | |||
| + | <code bash> | ||
| + | root@isrm-vm:/home/student/isrm$ ls *.pcap | ||
| + | AccessPoint-0-0.pcap Station-1-0.pcap | ||
| + | </code> | ||
| + | |||
| + | <note important> | ||
| + | Dacă vreți să accesați de pe mașina fizică/virtuală din care rulați docker image-ul fișierele din interiorul docker image, acestea sunt montate prin [[https://docs.docker.com/storage/storagedriver/overlayfs-driver/|overlayfs]] și sunt configurate să fie accesibile din folderul: ''~/.isrm2024/merge'' | ||
| + | |||
| + | (presupunând că ați rulat scriptul de build cu parametru numele mașinii ''isrm2024'') | ||
| + | </note> | ||
| + | |||
| + | Filtrați și afișați doar pachetele TCP. Fără a citi codul simulării și nici descrierea de la începutul sursei, ci doar PCAP-urile, care credeți că e direcția traficului? Sunt două noduri: 0 și 1 - 0->1 sau 1->0? | ||
| + | |||
| + | <note tip> | ||
| + | Primul număr din numele PCAP-ului generat este indexul nodului din simulare, iar al doilea număr e interfața de rețea (un nod poate avea mai multe interfețe de rețea). În simulare nodul 0 e AP (access point) și 1 este stație mobilă (STA). Un pachet care ajunge la STA (nodul 1) dar care a fost aruncat nu va putea fi văzut în captura ''Station-1-0.pcap'' dar în ''AccessPoint-0-0.pcap'' îl vom putea vedea. | ||
| + | |||
| + | Acest lucru e util când vom analiza de ce se pierd pachete în WiFi | ||
| + | </note> | ||
| + | |||
| + | Determinați canalul routerului și frecvența centrală a lui analizând câmpurile din secțiunea ''802.11 radio information'' sau ''Radiotap Header''. | ||
| + | |||
| + | |||
| + | <note tip>Filtre Wireshark: | ||
| + | * [[https://hackertarget.com/tshark-tutorial-and-filter-examples/|Exemple filtre]] | ||
| + | * Documentația filtrelor de [[https://www.wireshark.org/docs/dfref/w/wlan_mgt.html|WLAN în Wireshark]] | ||
| + | * Cheatsheet filtre Wifi în Wireshark/tshark: {{:isrm:laboratoare:new:wireshark_802.11_filters_-_reference_sheet.pdf|}} | ||
| + | |||
| + | </note> | ||
| + | |||
| + | |||
| + | Exemplu rulare: | ||
| + | |||
| + | <code bash> | ||
| + | root@isrm-vm:/home/student/isrm$ tshark -T fields -e frame.time_epoch \ | ||
| + | -e frame.number -e ip.src \ -r ./AccessPoint-0-0.pcap '(ip.proto == 6) && (ip.src == 10.0.0.1)' > frames.txt | ||
| + | </code> | ||
| + | |||
| + | * ''-T fields'' indică câmpurile din pachete care se doresc printate | ||
| + | |||
| + | Colecție de câmpuri de interes: | ||
| + | |||
| + | ^ opțiune pentru -e ^ semnificație ^ | ||
| + | | frame.time_epoch | timpul de la începutul simulării | | ||
| + | | frame.number | numărul cadrului | | ||
| + | | ip.src | adresa IP sursă | | ||
| + | | ip.id | IP identifier field | | ||
| + | | ip.ttl | câmpul TTL din headerul de IP | | ||
| + | | wlan.flags | câmpul flags din headerul WLAN | | ||
| + | | wlan.seq | numărul de secvență WLAN | | ||
| + | | wlan.fcs_good | cadrul WLAN este validat de câmpul FCS | | ||
| + | |||
| + | |||
| + | * ''(ip.proto == 6) && (ip.src == 10.0.0.1)'' indică condiția de filtrare a pachetelor din .pcap - pachete de tip TCP (proto=6) și IP sursă; folosește acelasi limbaj ca și wireshark | ||
| + | |||
| + | Exerciții: | ||
| + | |||
| + | * Folosind ''tshark'' cu filtrul ''wlan.fc.type_subtype == 0x08'' extrageți și numărați câte pachete de tip beacon trimite AP-ul din captura ''./AccessPoint-0-0.pcap'' | ||
| + | * Hint: pentru contorizare în bash puteți folosi ''wc -l'' | ||
| + | * Folosiți câmpurile ''frame.time_epoch'' de la câteva linii consecutive și determinați la ce interval de timp (în ''ms'') AP-ul (access point-ul) trimite beacon-uri | ||
| + | |||
| + | * Folosind ''tshark'' extrageți în 2 fișiere separate, fiecare fișier având filtrul ''wlan.fc.type_subtype <= 0x0011'' (subtipul mai mic sau egal cu 0x0011) și celălalt ''wlan.fc.type_subtype == 0x0028'' următoarele câmpuri: ''frame.time_epoch'', ''wlan_radio.phy'', ''frame.number''. | ||
| + | * Ce puteți spune despre PHY type-ul din primul fișier, dar al doilea? Ce credeți că se întâmplă | ||
| + | * Dacă sunteți curioși ce inseamna type/subtype, consultați [[https://community.cisco.com/t5/wireless-mobility-documents/802-11-frames-a-starter-guide-to-learn-wireless-sniffer-traces/ta-p/3110019#toc-hId--1447989924|acest tabel din standardul 802.11]] | ||
| + | |||
| + | <note tip> | ||
| + | Veți vedea și la curs și vom vedea și pe parcursul laboratoarelor: cadrele de date se trimit cu cel mai mare MCS posibil (în anumite condiții) iar cele de management/control (e.g. beacon, probe request) cu cel mai mic MCS stabilit intre AP și STA - motivul este că pentru acestea vrem o constelație robustă deoarece pierderile nu sunt acceptabile pentru cadre de control. | ||
| + | </note> | ||
| + | |||
| + | ===== Task 02: Analiza trace-ului ASCII ===== | ||
| + | |||
| + | Mecanismul de [[https://www.nsnam.org/docs/tutorial/html/tracing.html|tracing din ns-3]] ne permite să logăm și în format ASCII evenimentele. Rulați simularea: | ||
| + | |||
| + | <code bash> | ||
| + | ./waf --run "lab3 --numberOfNodes=2 --payloadSize=1400 \ | ||
| + | --offeredRate=11Mbps --phyRate=DsssRate11Mbps --simulationTime=2 --tracing=true" | ||
| + | </code> | ||
| + | |||
| + | Vom obține două trace-uri: unul PCAP (cum am analizat mai sus) și unul text: ''wifi-lab3.tr''. Deschideți și inspectați fișierul. | ||
| + | |||
| + | Explicația conținutului fișierului: | ||
| + | |||
| + | Prima literă este: | ||
| + | |||
| + | <code bash> | ||
| + | r for received | ||
| + | d for dropped | ||
| + | + for enqueued | ||
| + | - for dequeued | ||
| + | t is for transmitted #Relevant for WiFi tracefiles | ||
| + | </code> | ||
| + | |||
| + | A doua coloană reprezintă timestamp. | ||
| + | |||
| + | A treia coloană are următoarea semnificație: | ||
| + | |||
| + | <note>name of the event in the configuration namespace, sometimes called the configuration path name. The NodeList value represents the node (A=0, etc), the DeviceList represents the interface, and the final part of the name repeats the action: Drop, MacRx, Enqueue, Dequeue.</note> | ||
| + | |||
| + | Apoi urmează o serie de nume de clase din [[https://www.nsnam.org/doxygen/group__attribute.html|sistemul de atribute al ns-3]] (''ns3::Ipv4Header, ns3::TcpHeader'') și cu o listă de trace-uri specifice clasei respective. | ||
| + | |||
| + | ===== Task 03: Basic plot ===== | ||
| + | |||
| + | Ne propunem să validăm și că funcționează generarea de grafice, lucru pe care îl vom folosi la toate laboratoarele. | ||
| + | |||
| + | Descarcati fișierul de date numit **plotting_data1.csv** ce conține: | ||
| + | <file csv plotting_data1.csv> | ||
| + | # comentarii | ||
| + | # X Y | ||
| + | 1 2 | ||
| + | 2 3 | ||
| + | 3 2 | ||
| + | 4 1 | ||
| + | </file> | ||
| + | |||
| + | Pe baza acestor date, graficul poate fi construit folosind urmatorul template (pe care il puteti folosi si la restul laboratoarelor): | ||
| + | |||
| + | <code python> | ||
| + | import copy | ||
| + | import numpy as np | ||
| + | import matplotlib | ||
| + | import matplotlib.pyplot as plt | ||
| + | |||
| + | # Calea absoluta catre fisierul de date din care citim | ||
| + | # TODO - trebuie inlocuita cu calea corecta | ||
| + | DATA_FILE = 'plotting_data1.csv' | ||
| + | columns = ['x', 'y'] | ||
| + | |||
| + | # Citim datele din fisier | ||
| + | # Argumentul delimiter precizeaza care este delimitatorul dintre coloane | ||
| + | # Argumentul skip_header precizeaza cate linii nu vor fi citite pornind cu inceputul fisierului | ||
| + | # Argumentul names este unul foarte util deoarece permite asocierea de nume pentru coloanele din fisier si | ||
| + | # de asemenea duce la un acces foarte usor al datelor in script. In acest exemplu, names va fi egal cu ['x', 'y'] | ||
| + | # ceea ce inseamna ca putem accesa valorile din prima coloana prin sim_data['x']. | ||
| + | # Argumentul dtype setat specifica modul in care vor fi interpretate coloanele (string-urile ca string-uri, float-urile ca float-uri). | ||
| + | # In absenta acestui argument, valorile din coloane vor fi interpretate ca float. | ||
| + | sim_data = np.genfromtxt(DATA_FILE, delimiter=' ', skip_header=2, names=columns, dtype=None) | ||
| + | |||
| + | def plot_data(sim_data): | ||
| + | data = copy.deepcopy(sim_data) | ||
| + | |||
| + | # Apelul subplots poate fi folosit pentru a crea mai multe subgrafice in cadrul aceluiasi grafic sau in cadrul unor grafice diferite | ||
| + | # Prin figsize se specifica dimensiunea graficului | ||
| + | fig, ax = plt.subplots(figsize=(12,12)) | ||
| + | # Valori stilistice pentru grafic | ||
| + | ax.grid(color='b', alpha=0.5, linestyle='dashed', linewidth=0.5) | ||
| + | # Denumirile axelor Ox si Oy, precum si titlul graficului | ||
| + | plt.xlabel('X values') | ||
| + | plt.ylabel('Y values') | ||
| + | plt.title('A very nice looking plot') | ||
| + | |||
| + | # Aici este construit efectiv graficul. Campul label va fi folosit in cadrul legendei graficului | ||
| + | ax.plot(data['x'], data['y'], label='My plot') | ||
| + | ax.legend() | ||
| + | | ||
| + | plt.savefig("l1t3.png") | ||
| + | |||
| + | if __name__ == '__main__': | ||
| + | plot_data(sim_data) | ||
| + | </code> | ||
| + | |||
| + | Verificați după rulare că în folderul din docker aveți fișierul ''l1t3.png''. De asemenea, pentru că folosim [[https://docs.docker.com/storage/storagedriver/overlayfs-driver/|overlayfs]] puteți accesa de pe mașina fizică/virtuală din care rulați docker-ul din folderul: ''~/.isrm2024/merge/l1t3.png'' presupunând că la build ati folosit ca parametru numele docker image-ului ''isrm2024''. | ||