Skip to content
Snippets Groups Projects
Commit 8fe28043 authored by Mihai-Valentin DUMITRU's avatar Mihai-Valentin DUMITRU
Browse files

fix small typos

parent ae993fce
No related branches found
No related tags found
No related merge requests found
Pipeline #55283 passed
......@@ -12,7 +12,7 @@
- [ICMP](icmp.md)
- [Endianess](endianess.md)
- [API](api.md)
- [Cerinte](exercises.md)
- [Cerințe](exercises.md)
- [Testare](testing.md)
- [Trimitere](sending.md)
- [FAQ](faq.md)
......
......@@ -3,23 +3,30 @@
În cadrul temei vom implementa dataplane-ul unui router. Un router are două
părți:
- Dataplane - partea care implementează procesul de dirijare,
propriu-zis, acesta se întâmplă local, pe fiecare router. **Tema constă în
implementarea acestei componente.** În cele ce urmează, în lipsa altor
precizări, toate referințele la router din textul temei se referă la data plane.
- Control plane - componenta care implementează algoritmii de rutare
(e.g. RIP, OSPF, BGP); acești algoritmi distribuiți calculează
rutele pentru fiecare rețea destinație și le inserează în dataplane. **NU**
va fi nevoie să implementați acești algoritmi pentru
temă. Routerul va funcționa cu o tabelă de rutare statică, primită
într-un fișier de intrare, și care nu se va schimba pe parcursul
rulării.
- Dataplane - partea care implementează procesul de dirijare propriu-zis, pe
baza intrărilor din tabela de routare.
- Control plane - partea care implementează algoritmii de rutare (e.g. RIP,
OSPF, BGP); acești algoritmi distribuiți calculează intrările din
tabela de rutare.
**Tema constă în implementarea componentei de dataplane**.
În cele ce urmează, în lipsa altor precizări, toate referințele la router din
textul temei se referă la dataplane.
**NU** va fi nevoie să implementați acești algoritmi în cadrul temei; vom lucra
strict din perspectiva dataplane-ului, pentru care tabelele de rutare sunt deja
populate.
Routerul nostru va funcționa cu o tabelă de rutare statică, primită într-un
fișier de intrare, și care nu se va schimba pe parcursul rulării.
Un router are mai multe interfețe și poate recepționa pachete pe oricare dintre
acestea. Routerul trebuie să transmită pachetul mai departe, către un calculator
sau către alt router direct conectat, în funcție de regulile din tabela de
rutare. **Tema poate fi implementată în C sau C++**.
rutare.
**Tema poate fi implementată în C sau C++**.
## Lectură tema
......@@ -39,11 +46,11 @@ Approach (6th
Edition)](https://eclass.teicrete.gr/modules/document/file.php/TP326/%CE%98%CE%B5%CF%89%CF%81%CE%AF%CE%B1%20(Lectures)/Computer_Networking_A_Top-Down_Approach.pdf)
## Deadline
Deadline-ul temei este specificat pe moodle.
Vă reamintim părțile relevante din
[regulamentul](https://curs.upb.ro/2021/pluginfile.php/493725/mod_resource/content/0/Regulament_PC_2021_2022.pdf)
cursului de PCom:
Vă reamintim părțile relevante din [regulamentul cursului de
PCom](https://curs.upb.ro/2023/pluginfile.php/270568/mod_resource/content/1/Regulament_PC_2023_2024.pdf):
- După expirarea acestui termen limită se mai pot trimite teme un
interval de maxim 3 zile, cu următoarele depunctări: 10p în prima
......@@ -66,9 +73,9 @@ cursului de PCom:
# Setup
Pentru a simula o retea virtuala vom folosi [Mininet](http://mininet.org/).
Mininet este un simulator de retele ce foloseste in simulare implementari reale
de kernel, switch si cod de aplicatii.
Pentru a simula o rețea virtuală vom folosi [Mininet](http://mininet.org/).
Mininet este un simulator de rețele ce folosește în simulare implementari reale
de kernel, switch și cod de aplicații.
```bash
sudo apt update
......@@ -76,8 +83,8 @@ sudo apt install mininet openvswitch-testcontroller tshark python3-click python3
sudo pip3 install mininet
```
Dupa ce am instalat Mininet, vom folosi urmatoarea comanda pentru a creste
dimensiunea fontului in terminalele pe care le vom deschide.
După ce am instalat Mininet, vom folosi următoarea comandă pentru a crește
dimensiunea fontului în terminalele pe care le vom deschide.
```bash
echo "xterm*font: *-fixed-*-*-*-18-*" >> ~/.Xresources
......
......@@ -9,53 +9,71 @@ precum și unele funcții ajutătoare a căror utilizare este opțională. În
- **Recepționare/trimitere pachete:** aveți la dispoziție următoarele
două funcții de la nivelul Datalink:
```c
/* Scrie in frame_data continutul unui cadru L1 de Ethernet. In cazul nostru, frame_data
va fi structurat astfel: Ethernet L2 frame|IP or ARP| Alte protocoale
encapsulate de IP (e.g. ICMP)
/* Scrie în frame_data continutul unui cadru L2 de Ethernet. În cazul nostru, frame_data
va fi structurat astfel:
Returneaza interfata pe care cadrul a fost primit. Functia este blocanta.
|Alte protocoale encapsulate de IP (e.g. ICMP)|
|IP or ARP|
|Ethernet L2 frame| |<IP or ARP>|
Returnează interfața pe care cadrul a fost primit. Funcția este blocantă.
*/
int recv_from_any_link(char *frame_data, size_t *length);
/* Trimite buffer ca si payload al unui cadru Ethernet L1.
Link-ul pe care il va trimite este identificat de interfata.
/* Trimite frame_data ca payload al unui cadru Ethernet L2.
Link-ul pe care îl va trimite este identificat de interfață.
*/
int send_to_link(int interface, char *frame_data, int len);
int send_to_link(int interface, char *frame_data, int length);
```
> Pentru a primii punctajul pe tema, trebuie sa folositi acest API de send/recv
> Pentru a primi punctajul pe temă, trebuie să folosiți acest API de send/recv
- **Intrări în tabela de routare:** puteți modela o intrare în tabela
de routare folosind următoarea structură:
```c
struct route_table_entry;
/* Route table entry */
struct route_table_entry {
uint32_t prefix;
uint32_t next_hop;
uint32_t mask;
int interface;
} __attribute__((packed));
```
- **Parsare tabela de routare:** pentru a parsa tabela de routare,
puteți folosi funcția:
```c
int read_rtable(const char *filepath, struct route_table_entry *rtable);
```
> Intrarile in tabela de rutare sunt deja in network order
> Intrările din tabela de rutare sunt deja in network order.
- **Intrări în tabela ARP:** puteți modela o intrare în tabela ARP
folosind următoarea structură:
```c
struct arp_table_entry;
struct arp_table_entry {
uint32_t ip;
uint8_t mac[6];
};
```
- **Parsare tabela statică ARP:** în cazul în care doriți să folosiți
tabela statică de ARP, puteți să o parsați folosind funcția:
```c
void parse_arp_table();
int parse_arp_table(char *path, struct arp_table_entry *arp_table);
```
- **Calcul sume de control:** pentru a realiza calcularea/verificarea
sumelor de control din IPv4, respectiv ICMP, puteți folosi
următoarea funcție:
```c
/* Atunci cand calculam checksum-ul header-ului, vom pune
campul checksum din header pe 0. */
uint16_t checksum(uint16_t *data, size_t len);
```
- **Coadă de pachete:** după cum este menționat în [descrierea
......
# Protocolul ARP
După ce un router a determinat următorul hop pentru un pachet folosind LPM,
trebuie să-l trimită mai departe, actualizând pachetul astfel încât adresa MAC
destinație să fie cea a următorului hop. Cum știe routerul această adresă? O
opțiune ar fi ca această să fie reținută static, într-un tabel.
trebuie să-l trimită mai departe, încapsulându-l într-un cadru cu adresa MAC
destinație setată ca cea a următorului hop. Cum știe routerul această adresă?
ta opțiune este ca această să fie reținută static, într-un tabel.
În realitate, însă, din mai multe motive (e.g. flexibilitate), routerul
*nu știe* aceste adrese, ci trebuie să le determine folosind protocolul
......@@ -102,13 +103,13 @@ Pașii relevanți pentru dirijarea unui pachet IPv4 sunt următorii:
va parcurge lista de pachete care așteaptă răspunsuri ARP și le va
trimite pe cele pentru care adresa următorului hop este cunoscută.
> Un `ARP Request` catre router poate avea ca destinatie broadcast sau adresa MAC a interfetei router-ului.
> Un `ARP Request` către router poate avea ca destinație broadcast sau adresa MAC a interfeței router-ului.
In slideshow-ul de mai jos gasiti un exemplu de utilizare a protocolului ARP
pentru a determina adresa MAC a unui dispozitiv la care suntem direct conectati.
În slideshow-ul de mai jos găsiți un exemplu de utilizare a protocolului ARP
pentru a determina adresa MAC a unui dispozitiv la care suntem direct conectați.
<iframe class="is-fullwidth" height="600" marginheight="0" marginwidth="0" src="slides/index.html">
</iframe>
> In mod normal, hostii sunt conectati la un switch, astfel ARP Request-ul
> În mod normal, hoștii sunt conectați la un switch, astfel ARP Request-ul
este trimis la mai mai multe dispozitive, nu doar la router.
......@@ -20,7 +20,7 @@ care a fost trimis acest cadru.
În cadrul laboratorului puteți folosi următoarea structura pentru un
cadru Ethernet.
``` C
```C
struct ether_header {
uint8_t ether_dhost[6]; // MAC destinație
uint8_t ether_shost[6]; // MAC sursă
......@@ -33,11 +33,12 @@ struct ether_header {
ethertype le poate lua. În cazul nostru, ne interesează IPv4 (0x0800) și ARP (0x0806).
Noi vom folosi API-ul de nivel 2 pentru a trimite cadre Ethernet L2 peste protocolul de L1 Ethernet ce se ocupa cu
framing, checksums etc. [Aici](https://en.wikipedia.org/wiki/Ethernet_frame) gasiti o descriere completa
a structurii Ethernet. In payload-ul cadrului de Ethernet vom avea encapsulat fie protocolul ARP, fie protocolul IP.
framing, checksums etc. [Aici](https://en.wikipedia.org/wiki/Ethernet_frame) găsiți o descriere completă
a structurii Ethernet.
În payload-ul cadrului de Ethernet vom avea encapsulat fie protocolul ARP, fie protocolul IP.
In figura de mai jos, gasim o captura Wireshark ce surprinde un cadru ethernet de L2 in care avem encapsulat
IP si ICMP peste IP.
În figura de mai jos, găsim o captură Wireshark ce surprinde un cadru ethernet de L2 în care avem encapsulat
IP și ICMP peste IP.
![image](icmp_capture_wireshark.png)
......
......@@ -5,7 +5,7 @@
Pentru rezolvarea temei, trebuie să implementați dataplane-ul unui
router.
**Va recomandăm să folosiți cel puțin `ping` pentru a testa
implementarea și `Wireshark` pentru depanare și analiză corectitudinii.**
implementarea și `Wireshark` sau `tcpdump` pentru depanare și analiza corectitudinii.**
Punctajul este împărțit în mai multe componente, după cum urmează:
- **Procesul de dirijare (30p).** Va trebui să implementați pașii
......@@ -17,13 +17,13 @@ Punctajul este împărțit în mai multe componente, după cum urmează:
implementat LPM folosind o căutare liniară, i.e. trecând de fiecare
dată prin toate întrările din tabel. În practică, o tabelă de
routare poate conține foarte multe întrări [^1] -- astfel de căutare
este ineficientă. O abordare mai bună este să folosim
[trie](https://www.lewuathe.com/longest-prefix-match-with-trie-tree.html)
este ineficientă. O abordare mai bună este să folosim o
[trie](https://www.lewuathe.com/longest-prefix-match-with-trie-tree.html).
Orice implementare mai eficientă decât căutarea liniară valorează 16
puncte.
- **Protocolul ARP (33p).** Vom implementa pașii din [sectiuena ARP](arp.html) pentru
- **Protocolul ARP (33p).** Vom implementa pașii din [secțiunea ARP](arp.md) pentru
a popula dinamic tabela ARP. Va trebui să
implementați și funcționalitatea de caching; după ce primiți un răspuns ARP,
rețineți adresa MAC a hostului interogat. În realitate, intrările dintr-un
......@@ -32,7 +32,7 @@ Punctajul este împărțit în mai multe componente, după cum urmează:
**Pentru a nu bloca routerul, pachetele pentru care așteptăm un `ARP Reply`
vor fi puse într-o coadă.**
Va recomandăm să folosiți comanda `arping` pentru a face cereri ARP. Comanda
Vă recomandăm să folosiți comanda `arping` pentru a face cereri ARP. Comanda
`arp` afișează tabela ARP a unui host.
Tema se poate preda și cu o tabelă de ARP
......@@ -41,13 +41,13 @@ Punctajul este împărțit în mai multe componente, după cum urmează:
checkerul din a rula teste de ARP, deci nu veți primi puncte pe ele.
Dacă ați implementat protocolul ARP, nu adăugați fișierul
`arp_table.txt`**.
> Este normal ca testul forward sa pice daca folositi tabela statica de ARP.
> Este normal ca testul forward să pice daca folositi tabela statica de ARP.
- **Protocolul ICMP (21p).** Implementați pe router funcționalitatea descrisă
în [secțiunea ICMP](icmp.html). Puteți folosi `ping -t 1` pentru a trimite
un pachet cu TTL 1. Va recomandăm să testați și cu `traceroute`.
Pentru a fi punctata o tema, in README trebuie prezentata solutia voastra pe scurt. De asemenea, trebuie mentionat si ce subcerințe ați rezolvat.
Pentru a fi punctată o temă, în README trebuie prezentată soluția voastră, pe scurt. De asemenea, trebuie menționat și ce subcerințe ați rezolvat.
**Notă:** Puteți scrie implementarea în C sau C++.
......
......@@ -6,7 +6,7 @@ efectueze următoarele acțiuni:
1. **Parsarea pachetului:** din fluxul de octeți ce reprezintă
pachetul, routerul trebuie să afle ce antete sunt prezente și ce
valori conțîn câmpurile acestora, construind și inițializând
valori conțin câmpurile acestora, construind și inițializând
structuri interne corespunzătoare. La acest pas, dacă routerul
descoperă că un pachet primit e malformat (e.g. prea scurt), îl
aruncă.
......@@ -21,10 +21,10 @@ efectueze următoarele acțiuni:
3. **Inspectarea următorului header:** routerul inspectează câmpul
`Ether Type` din header-ul Ethernet pentru a descoperi următorul antet
prezent. În cadrul temei, ne vor interesa doar două posibilități:
[IPv4] și [ARP]. Următoarele acțiuni ale routerului vor
[IPv4](ip.md) și [ARP](arp.md). Următoarele acțiuni ale routerului vor
depinde de tipul acestui header. Orice alt fel de pachet trebuie
ignorat.
> În cele ce urmează, vom studia protocoalele implicate în procesul de dirijare
> În continuare, vom studia protocoalele implicate în procesul de dirijare
și vom prezenta cum acestea sunt folosite de către router.
src/icmp_capture_wireshark.png

49.8 KiB | W: | H:

src/icmp_capture_wireshark.png

33 KiB | W: | H:

src/icmp_capture_wireshark.png
src/icmp_capture_wireshark.png
src/icmp_capture_wireshark.png
src/icmp_capture_wireshark.png
  • 2-up
  • Swipe
  • Onion skin
# Protocolul IPv4
Protocolul IP este utitilzat pentru a permite dispozitivelor conectate în rețele diferite să schimbe informații prin intermediul unui dispozitiv intermediar numit router.
O descriere completă a header-ului de IPv4 o găsiți [aici](https://en.wikipedia.org/wiki/Internet_Protocol_version_4#Header). Header-ul unui pachet (packet) IP este următorul:
Protocolul IP este utilizat pentru a permite dispozitivelor conectate în rețele
diferite să schimbe informații prin intermediul unui dispozitiv intermediar
numit router.
O descriere completă a header-ului de IPv4 o găsiți
[aici](https://en.wikipedia.org/wiki/Internet_Protocol_version_4#Header).
Header-ul unui pachet (packet) IP este următorul:
```
+----+---------------+---------------+---------------+---------------+
|Word| 1 | 2 | 3 | 4 |
......@@ -19,27 +25,29 @@ O descriere completă a header-ului de IPv4 o găsiți [aici](https://en.wikiped
+----+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
```
Următoarea strucura poate fi folosită pentru a reprezenta un pachet IPV4.
``` C
Următoarea strucură poate fi folosită pentru a reprezenta un pachet IPV4.
```C
struct iphdr {
// version este pe 4 biți, ihl este pe 4 biți
uint8_t version:4,
ihl:4; // Nu vom implementa protocolul IP cu opțiuni,
așa că 5 × 32 bits = 160 bits = 20 bytes (internet header length)
uint8_t tos; // Nu este relevant pentru temă (set pe 0)
uint16_t tot_len; // dimensiunea totală a header + date
uint16_t id; // Nu este relevant pentru temă, (set pe 1)
uint16_t frag_off; // Nu este relevant pentru temă, (set pe 0)
uint8_t ttl; // Time to live
uint8_t protocol; // Identificator al protocolului encapsulat (e.g. ICMP)
uint16_t check; // checksum of the iphdr, we checksum = 0 when computing
uint32_t saddr; // Adresa IP sursă
uint32_t daddr; // Adresa IP destinație
ihl:4; // Nu vom implementa protocolul IP cu opțiuni,
// așa că 5 × 32 bits = 160 bits = 20 bytes
// (internet header length)
uint8_t tos; // Nu este relevant pentru temă (set pe 0)
uint16_t tot_len; // dimensiunea totală a header + date
uint16_t id; // Nu este relevant pentru temă, (set pe 1)
uint16_t frag_off; // Nu este relevant pentru temă, (set pe 0)
uint8_t ttl; // Time to live
uint8_t protocol; // Identificator al protocolului encapsulat (e.g. ICMP)
uint16_t check; // checksum of the iphdr, we checksum = 0 when computing
uint32_t saddr; // Adresa IP sursă
uint32_t daddr; // Adresa IP destinație
};
```
De notat faptul că noi nu suntem interesați de diferite funcționalități din IP
precum fragmentarea. Astfel, în cazul în care construiți un pachet IP de la 0,
**Nu suntem interesați de anumite funcționalități din IP precum fragmentarea**.
Astfel, în cazul în care construiți un pachet IP de la 0,
vom seta următoarele:
```
......@@ -51,19 +59,19 @@ id = 1
```
În [RFC 990 pagina 24](https://www.rfc-editor.org/rfc/rfc990) gășiți o listă de identificatori pentru diversele
protocoale ce pot fi encapsulate în IP. Vom folosi aceste valori pentru a completa câmpul Protocol
protocoale ce pot fi encapsulate în IP. Vom folosi aceste valori pentru a completa câmpul `protocol`.
Când un router primește un pachet de tip IPv4 trebuie să realizeze
Când un router primește un pachet de tip IPv4, trebuie să realizeze
următoarele acțiuni:
1. **Verificarea dacă el este destinația:** deși un intermediar, routerul este
1. **Verifică dacă el este destinația:** deși un intermediar, routerul este
de asemenea o entitate cu interfețe de rețea și adrese IP asociate acestora,
deci poate fi destinatarul unui pachet. În acest caz, routerul nu trebuie să
trimită mai departe pachetul, ci să îi înțeleagă conținutul pentru a putea
acționa în consecință. În cadrul acestei teme, routerul va răspunde doar
la mesaje de tip **ICMP**.
2. **Verificare checksum:** routerul trebuie să recalculeze suma de
2. **Verifică checksum:** routerul trebuie să recalculeze suma de
control a pachetului, și să o compare cu cea primită în antetul de IP; dacă
sumele diferă, pachetul a fost corupt și trebuie aruncat.
......
......@@ -15,5 +15,4 @@ prefixul:
Odată ce routerul găsește toate prefixele care se potrivesc adresei
destinație din pachet, va alege intrarea din tabela de rutare
corespunzătoare prefixului cei mai lung (masca cea mai mare).
corespunzătoare celui mai lung prefix (masca cea mai mare).
......@@ -27,5 +27,5 @@ Prefix Next hop Mask Interface
```
În contextul temei, este suficient să considerați că numărul maxim de
intrări din tabela de rutare este de 100000 de intrări.
intrări din tabela de rutare este de 100 000 de intrări.
......@@ -10,10 +10,9 @@ rula pentru a realiza setupul de testare. Acesta trebuie rulat ca
$ sudo python3 checker/topo.py
Astfel, se va inițializa topologia virtuală și se va deschide câte un
terminal pentru fiecare host, câte un terminal pentru fiecare router și
unul pentru controller (cu care nu vom interacționa); terminalele pot fi
identificate după titlu.
Astfel, se va inițializa topologia virtuală și se va deschide câte un terminal
pentru fiecare host și câte un terminal pentru fiecare router; terminalele pot
fi identificate după titlu.
Fiecare host e o simplă mașină Linux, din al cărei terminal puteți rula
comenzi care generează trafic IP pentru a testa funcționalitatea
......@@ -21,17 +20,17 @@ routerului implementat. Vă recomandăm
[arping](http://man7.org/linux/man-pages/man8/arping.8.html),
[ping](https://linux.die.net/man/8/ping) și
[netcat](https://howto.lintel.în/listen-arbitrary-port-print-data-coming-using-netcat/).
Mai mult, din terminal putem rula **Wireshark** sau tcpdump pentru a
Mai mult, din terminal putem rula `wireshark` sau `tcpdump` pentru a
face inspecția de pachete.
Pentru a compila codul vom folosi `make` care creeaza binarul router.
Pentru a compila codul vom folosi `make` care creează binarul `router`.
Pentru a porni routerele manual folosim următoarele comenzi, prima pe
router 0 și a doua pe router 1:
```bash
make run_router0 # din terminalul lui router 0
make run_router1 # din terminalul lui router 1
make run_router0 # din terminalul lui router0
make run_router1 # din terminalul lui router1
```
Ca sa nu scrieti manual ip-ul unui host, puteti folosii `h0`, `h1`, `h2` si `h3` in
......@@ -56,7 +55,7 @@ să găsiți utilă informația de aici, mai ales cea din fișierele de
pe care îl puteți inspecta apoi în `Wireshark` (captura este făcută pe toate
interfețele routerului, deci pachetele dirijate vor apărea de două ori; urmăriți
indicațiile de [aici](https://osqa-ask.wireshark.org/questions/30636/traces-from-multiple-interface/)
pentru a obține o vizualizare mai bună)
pentru a obține o vizualizare mai bună).
Puteți rula un singur test folosind argumentul run <testname>. De exemplu:
......@@ -67,7 +66,7 @@ sudo python3 checker/topo.py run router_arp_reply
Nu veți primi un raport *PASS/FAIL*, dar veți putea obține ușor outputul din `host_output`.
**Notă:** Scopul testelor este de a ajuta cu dezvoltarea și evaluarea
> **Notă:** Scopul testelor este de a ajuta cu dezvoltarea și evaluarea
temei. Mai presus de rezultatul acestora, important este să implementați
*cerința*. Astfel, punctajul final poate diferi de cel tentativ acordat
de teste, în situațiile în care cerința temei nu este respectată (un caz
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment