API
Pentru rezolvarea temei vă punem la dispoziție un schelet de cod care implementeze unele funcționalități esențiale pentru rezolvarea cerințelor, precum și unele funcții ajutătoare a căror utilizare este opțională. În protocols.h găsiți structuri pentru protocoalele cu care vom interacționa. În lib.h veți găsi mai mulți funcții auxiliare utile, printre care:
-
Recepționare/trimitere pachete: aveți la dispoziție următoarele două funcții de la nivelul Datalink:
/* 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) Returneaza interfata pe care cadrul a fost primit. Functia este blocanta. */ 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. */ int send_to_link(int interface, char *frame_data, int len);
Pentru a primii punctajul pe tema, trebuie sa folositi acest API de send/recv
-
Intrări în tabela de routare: puteți modela o intrare în tabela de routare folosind următoarea structură:
struct route_table_entry;
-
Parsare tabela de routare: pentru a parsa tabela de routare, puteți folosi funcția:
int read_rtable(const char *filepath, struct route_table_entry *rtable);
Intrarile in 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ă:
struct arp_table_entry;
-
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:
void parse_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:
/* 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 protocolului ARP, veți avea nevoie să folosiți o coadă pentru pachete. Vă punem la dispoziție implementarea unei cozi cu elemente generice; urmăriți comentariile din
include/queue.h
. -
Determinarea MAC interfață proprie: pentru a determina adresa MAC a unei interfețe a routerului, folosiți funcția:
void get_interface_mac(int interface, uint8_t *mac);
Argumentul
mac
trebuie să indice către o zonă de memorie cu cel puțin șase octeți alocați.