Skip to content

Commit d0e34a4

Browse files
committed
add *
0 parents  commit d0e34a4

16 files changed

+130149
-0
lines changed

Diff for: Makefile

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
PROJECT=router
2+
SOURCES=router.c lib/queue.c lib/list.c lib/lib.c
3+
LIBRARY=nope
4+
INCPATHS=include
5+
LIBPATHS=.
6+
LDFLAGS=
7+
CFLAGS=-c -Wall -Werror -Wno-error=unused-variable
8+
CC=gcc
9+
10+
# Automatic generation of some important lists
11+
OBJECTS=$(SOURCES:.c=.o)
12+
INCFLAGS=$(foreach TMP,$(INCPATHS),-I$(TMP))
13+
LIBFLAGS=$(foreach TMP,$(LIBPATHS),-L$(TMP))
14+
15+
# Set up the output file names for the different output types
16+
BINARY=$(PROJECT)
17+
18+
all: $(SOURCES) $(BINARY)
19+
20+
$(BINARY): $(OBJECTS)
21+
$(CC) $(LIBFLAGS) $(OBJECTS) $(LDFLAGS) -o $@
22+
23+
.c.o:
24+
$(CC) $(INCFLAGS) $(CFLAGS) -fPIC $< -o $@
25+
26+
clean:
27+
rm -rf $(OBJECTS) router hosts_output router_*
28+
29+
run_router0: all
30+
./router rtable0.txt rr-0-1 r-0 r-1
31+
32+
run_router1: all
33+
./router rtable1.txt rr-0-1 r-0 r-1

Diff for: README

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Router Dataplane
2+
Author: Radut Dragos 321CD
3+
4+
## Structures
5+
Toate structurile cu instantiere unica se initializeaza inainte de intrarea in loop-ul de "listen" : route table, arp_cache, list (packet queue) si root (LPM trie).
6+
7+
## Forwarding
8+
### Workflow:
9+
* se verifica L2 data <=> pachetul are ca destinatie router-ul curent sau broadcast
10+
* se verifica tipul pachetului: ARP / ICMP (necesita interpretare)
11+
* se verifica checksum, ttl
12+
* se cauta datele necesare pentru modificari
13+
* se fac modificarile necesare la nivelul IP (ttl si checksum) si ethernet (destinatie si sursa)
14+
* reconstructia pachetului: ` ETH_HDR | IP_HDR | PAYLOAD` care se va trimite spre next_hop pe interfata corecta
15+
16+
## LPM
17+
### Trie implementation
18+
* initializarea sa realizeaza prin functia parse_trie() introduce pentru fiecare linie din tabela de rutare nodurile noi
19+
* o adresa introdusa se interpreteaza pe modelul arborelui binar
20+
* diferentierea la niveul mastii se face prin lungimea mastii
21+
* astfel, adresa "addr" cu masca /len se reprezinta ca primii len biti din forma binara a addr
22+
* introducand practic prefixul impreuna cu masca, cautarea se va realiza eficient, parcurgand doar arborele prin urmarea adresei cautate pana la o frunza
23+
24+
## ARP
25+
### Received
26+
* router-ul poate interpreta REQUEST/REPLY
27+
* pentru REPLY, router-ul memoreaza in cache mac-ul primit si trimite pachetele aflate in asteprate pe acea adreasa
28+
* pentru REQUEST, router-ul va interpreta doar in cazul in care el este destinatia si va trimite un ARP REPLY
29+
### Sent
30+
* router-ul va trimite un ARP REQUEST in cazul in care mac-ul asociat adresei ip destinatie nu este cunoscut, punand in coada de asteptare pachetele cu destinatia respectiva
31+
* va trimite un ARP REPLY daca el este target-ul request-ului primit
32+
33+
## ICMP
34+
* in cazul in care router-ul este destinatia unui pachet icmp, va trimite un icmp_reply()
35+
* va trimite TIMEOUT in cazul unui ttl < 2
36+
* va trimite DESTINATION UNREACHABLE in cazul in care nu gaseste intrarea in tabela de rutare

Diff for: include/arp_table.txt

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
192.168.0.2 de:ad:be:ef:00:00
2+
192.168.1.2 de:ad:be:ef:00:01
3+
192.168.2.2 de:ad:be:ef:00:02
4+
192.168.3.2 de:ad:be:ef:00:03
5+
192.0.1.1 ca:fe:ba:be:00:01
6+
192.0.1.2 ca:fe:ba:be:01:00

Diff for: include/lib.h

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#ifndef _SKEL_H_
2+
#define _SKEL_H_
3+
4+
#include <unistd.h>
5+
#include <stdint.h>
6+
#include <stdio.h>
7+
#include <stdlib.h>
8+
9+
#define MAX_PACKET_LEN 1600
10+
#define ROUTER_NUM_INTERFACES 3
11+
12+
int send_to_link(int interface, char *frame_data, size_t length);
13+
14+
/*
15+
* @brief Receives a packet. Blocking function, blocks if there is no packet to
16+
* be received.
17+
*
18+
* @param frame_data - region of memory in which the data will be copied; should
19+
* have at least MAX_PACKET_LEN bytes allocated
20+
* @param length - will be set to the total number of bytes received.
21+
* Returns: the interface it has been received from.
22+
*/
23+
int recv_from_any_link(char *frame_data, size_t *length);
24+
25+
/* Route table entry */
26+
struct route_table_entry {
27+
uint32_t prefix;
28+
uint32_t next_hop;
29+
uint32_t mask;
30+
int interface;
31+
} __attribute__((packed));
32+
33+
/* ARP table entry when skipping the ARP exercise */
34+
struct arp_entry {
35+
uint32_t ip;
36+
uint8_t mac[6];
37+
};
38+
39+
char *get_interface_ip(int interface);
40+
41+
/**
42+
* @brief Get the interface mac object. The function writes
43+
* the MAC at the pointer mac. uint8_t *mac should be allocated.
44+
*
45+
* @param interface
46+
* @param mac
47+
*/
48+
void get_interface_mac(int interface, uint8_t *mac);
49+
50+
/**
51+
* @brief Homework infrastructure function.
52+
*
53+
* @param argc
54+
* @param argv
55+
*/
56+
57+
/**
58+
* @brief IPv4 checksum per RFC 791. To compute the checksum
59+
* of an IP header we must set the checksum to 0 beforehand.
60+
*
61+
* also works as ICMP checksum per RFC 792. To compute the checksum
62+
* of an ICMP header we must set the checksum to 0 beforehand.
63+
64+
* @param data memory area to checksum
65+
* @param size in bytes
66+
*/
67+
uint16_t checksum(uint16_t *data, size_t len);
68+
69+
/**
70+
* hwaddr_aton - Convert ASCII string to MAC address (colon-delimited format)
71+
* @txt: MAC address as a string (e.g., "00:11:22:33:44:55")
72+
* @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
73+
* Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
74+
*/
75+
int hwaddr_aton(const char *txt, uint8_t *addr);
76+
77+
/* Populates a route table from file, rtable should be allocated
78+
* e.g. rtable = malloc(sizeof(struct route_table_entry) * 80000);
79+
* This function returns the size of the route table.
80+
*/
81+
int read_rtable(const char *path, struct route_table_entry *rtable);
82+
83+
/* Parses a static mac table from path and populates arp_table.
84+
* arp_table should be allocated and have enough space. This
85+
* function returns the size of the arp table.
86+
* */
87+
int parse_arp_table(char *path, struct arp_entry *arp_table);
88+
89+
void init(int argc, char *argv[]);
90+
91+
#define DIE(condition, message, ...) \
92+
do { \
93+
if ((condition)) { \
94+
fprintf(stderr, "[(%s:%d)]: " # message "\n", __FILE__, __LINE__, ##__VA_ARGS__); \
95+
perror(""); \
96+
exit(1); \
97+
} \
98+
} while (0)
99+
100+
#endif /* _SKEL_H_ */

Diff for: include/list.h

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#ifndef _LIST_H_
2+
#define _LIST_H_
3+
4+
typedef struct cell *list;
5+
6+
struct cell
7+
{
8+
void *element;
9+
list next;
10+
};
11+
12+
extern list cons(void *element, list l);
13+
extern list cdr_and_free(list l);
14+
15+
#endif /* _LIST_H_ */

Diff for: include/protocols.h

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#include <unistd.h>
2+
#include <stdint.h>
3+
4+
/* Ethernet ARP packet from RFC 826 */
5+
struct arp_header {
6+
uint16_t htype; /* Format of hardware address */
7+
uint16_t ptype; /* Format of protocol address */
8+
uint8_t hlen; /* Length of hardware address */
9+
uint8_t plen; /* Length of protocol address */
10+
uint16_t op; /* ARP opcode (command) */
11+
uint8_t sha[6]; /* Sender hardware address */
12+
uint32_t spa; /* Sender IP address */
13+
uint8_t tha[6]; /* Target hardware address */
14+
uint32_t tpa; /* Target IP address */
15+
} __attribute__((packed));
16+
17+
/* Ethernet frame header*/
18+
struct ether_header {
19+
uint8_t ether_dhost[6]; //adresa mac destinatie
20+
uint8_t ether_shost[6]; //adresa mac sursa
21+
uint16_t ether_type; // identificator protocol encapsulat
22+
};
23+
24+
/* IP Header */
25+
struct iphdr {
26+
// this means that version uses 4 bits, and ihl 4 bits
27+
uint8_t ihl:4, version:4; // we use version = 4
28+
uint8_t tos; // we don't use this, set to 0
29+
uint16_t tot_len; // total length = ipheader + data
30+
uint16_t id; // id of this packet
31+
uint16_t frag_off; // we don't use fragmentation, set to 0
32+
uint8_t ttl; // Time to Live -> to avoid loops, we will decrement
33+
uint8_t protocol; // don't care
34+
uint16_t check; // checksum -> Since we modify TTL,
35+
// we need to recompute the checksum
36+
uint32_t saddr; // source address
37+
uint32_t daddr; // the destination of the packet
38+
};
39+
40+
struct icmphdr
41+
{
42+
uint8_t type; /* message type */
43+
uint8_t code; /* type sub-code */
44+
uint16_t checksum;
45+
union
46+
{
47+
struct
48+
{
49+
uint16_t id;
50+
uint16_t sequence;
51+
} echo; /* echo datagram */
52+
uint32_t gateway; /* gateway address */
53+
struct
54+
{
55+
uint16_t __unused;
56+
uint16_t mtu;
57+
} frag; /* path mtu discovery */
58+
} un;
59+
};

Diff for: include/queue.h

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#ifndef QUEUE_H
2+
#define QUEUE_H
3+
4+
struct queue;
5+
typedef struct queue *queue;
6+
7+
/* create an empty queue */
8+
extern queue queue_create(void);
9+
10+
/* insert an element at the end of the queue */
11+
extern void queue_enq(queue q, void *element);
12+
13+
/* delete the front element on the queue and return it */
14+
extern void *queue_deq(queue q);
15+
16+
/* return a true value if and only if the queue is empty */
17+
extern int queue_empty(queue q);
18+
19+
#endif

0 commit comments

Comments
 (0)