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 în frame_data continutul unui cadru L2 de Ethernet. În cazul nostru, frame_data va fi structurat astfel: |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ă. */ size_t recv_from_any_link(char *frame_data, size_t *length); /* 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(size_t length, char *frame_data, size_t interface);
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ă:
/* 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:
int read_rtable(const char *filepath, struct route_table_entry *rtable);
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ă:
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:
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:
/* 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(size_t interface, uint8_t *mac);
Argumentul
mac
trebuie să indice către o zonă de memorie cu cel puțin șase octeți alocați.