-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
299 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
/output | ||
/bin | ||
*.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Compiler | ||
CC := gcc | ||
|
||
# Compiler flags | ||
CFLAGS := -Wall -Wextra -I include/ | ||
|
||
# Source files | ||
SRCS := $(wildcard src/*.c) | ||
OBJS := $(SRCS:.c=.o) | ||
|
||
# Target executable | ||
TARGET := bin/main | ||
|
||
# Build the executable | ||
$(TARGET): $(OBJS) | ||
$(CC) $(CFLAGS) -o $(TARGET) $(OBJS) | ||
|
||
|
||
# Clean up object files and the executable | ||
clean: | ||
rm -f $(OBJS) $(TARGET) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/* | ||
Implementation of a doubly linked list for skbuff (*next/*prev | ||
elements) seen in the linux src here: | ||
https://lxr.linux.no/linux+v2.6.20/include/linux/skbuff.h#L184 | ||
See this diagram from 61B for the implementation: | ||
https://docs.google.com/presentation/d/1jjivjdvD4mx6qb4bd4rUKB6FDZbYtveJ5NKeyVeA1lk/edit#slide=id.g829fe3f43_0_376 | ||
https://github.com/Berkeley-CS61B-Student/sp24-s1085/blob/main/proj1a/src/LinkedListDeque61B.java | ||
*/ | ||
|
||
#ifndef _LIST_H | ||
#define _LIST_H | ||
|
||
#include <stddef.h> | ||
|
||
struct list_head { | ||
struct list_head *next; | ||
struct list_head *prev; | ||
}; | ||
|
||
#define LIST_HEAD(name) struct list_head name = {&(name), &(name)} | ||
|
||
// define all static inline functions in the header file: | ||
// https://stackoverflow.com/questions/5526461/gcc-warning-function-used-but-not-defined | ||
|
||
static inline void list_init(struct list_head *head) { | ||
head->next = head; | ||
head->prev = head; | ||
} | ||
|
||
static inline void add_first(struct list_head *new_element, struct list_head *head) { | ||
new_element->next = head->next; | ||
new_element->prev = head; | ||
head->next->prev = new_element; | ||
head->next = new_element; | ||
} | ||
|
||
static inline void add_last(struct list_head *new_element, struct list_head *head) { | ||
new_element->next = head; | ||
new_element->prev = head->prev; | ||
head->prev->next = new_element; | ||
head->prev = new_element; | ||
} | ||
|
||
static inline void remove_elem(struct list_head *elem_to_remove) { | ||
elem_to_remove->prev->next = elem_to_remove->next; | ||
elem_to_remove->next->prev = elem_to_remove->prev; | ||
} | ||
|
||
static inline int is_list_empty(struct list_head *head) { | ||
return head->next == head; | ||
} | ||
|
||
#define get_list_item(ptr, type, member) \ | ||
((type *)((char *)(ptr) - offsetof(type, member))) | ||
|
||
#define get_list_first_entry(ptr, type, member) \ | ||
get_list_item((ptr)->next, type, member) | ||
|
||
#define list_for_each(pos, head) \ | ||
for (pos = (head)->next; pos != (head); pos = pos->next) | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
/* | ||
defs for ethernet frame struct & code | ||
The following is helpful for interpreting our internet frame. | ||
This data should come from our TAP driver | ||
https://medium.com/kernel-space/unpacking-a-raw-packet-ethernet-frame-part-1-e91033e745a4 | ||
- Heres a chart! Note that preamble is "omitted" | ||
We will be implementing 802.3 frame structure | ||
Here is the original standard: | ||
https://ethernethistory.typepad.com/papers/EthernetSpec.pdf (page 27) | ||
Linux provides a struct for the ethernet frame header as a guide also: | ||
https://github.com/torvalds/linux/blob/master/include/uapi/linux/if_ether.h#L174 | ||
https://stackoverflow.com/questions/35306080/parsing-ethernet-frames-and-data-types | ||
*/ | ||
|
||
#ifndef ETH_H_ | ||
#define ETH_H_ | ||
|
||
#include "syshead.h" | ||
#include "skbuff.h" | ||
|
||
#define ETH_ALEN 6 | ||
|
||
struct eth_hdr { | ||
u_int8_t ether_dhost[ETH_ALEN]; // destination mac | ||
u_int8_t ether_shost[ETH_ALEN]; // source mac | ||
u_int16_t ether_type; | ||
// uint8_t payload[]; // not in official implementation | ||
} __attribute__ ((packed)); | ||
|
||
|
||
static inline struct eth_hdr *unpack_eth_hdr(struct sk_buff *skb) { | ||
struct eth_hdr *eth_hdr = (struct eth_hdr *)(skb->head); | ||
// convert ether_type from big endian -> small endian | ||
eth_hdr->ether_type = ntohs(eth_hdr->ether_type); | ||
return eth_hdr; | ||
}; | ||
|
||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#ifndef NET_DIR_H | ||
#define NET_DIR_H | ||
|
||
#include "syshead.h" | ||
|
||
void net_dir_receive(); | ||
|
||
#endif |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/* | ||
what we need in our skbuff is documented here: | ||
https://dev.to/amrelhusseiny/linux-networking-part-1-kernel-net-stack-180l | ||
https://lxr.linux.no/linux+v2.6.20/include/linux/skbuff.h#L184 | ||
*/ | ||
#ifndef SK_BUFF_H | ||
#define SK_BUFF_H | ||
|
||
#include "dl_list.h" | ||
#include "route.h" | ||
#include "net_dir.h" | ||
#include <pthread.h> | ||
#include <stdint.h> | ||
|
||
struct sk_buff { | ||
struct list_head list; // implements *next *prev | ||
// struct routing_table_entry *rt; | ||
// struct outgoing_eth_pack_meta *dev; | ||
uint32_t interface; | ||
uint16_t protocol; // 2 byte identifier | ||
uint8_t *head; | ||
uint8_t *data; | ||
uint8_t *tail; | ||
uint8_t *end; | ||
}; | ||
|
||
struct sk_buff_head { | ||
struct list_head head; | ||
int len; | ||
}; | ||
|
||
struct sk_buff *alloc_skb(unsigned int size); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,6 +29,7 @@ | |
#include <sys/un.h> | ||
#include <time.h> | ||
#include <unistd.h> | ||
#include <linux/if_ether.h> | ||
|
||
#endif | ||
|
||
|
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,12 @@ | ||
# TCP | ||
|
||
|
||
|
||
## Include path | ||
``` | ||
${workspaceFolder}/** | ||
/usr/include/x86_64-linux-gnu | ||
${workspaceFolder}/include | ||
/usr/include | ||
/usr/lib/gcc/x86_64-linux-gnu/13/include | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,22 @@ | ||
#include "syshead.h" | ||
#include "tuntap_interface.h" | ||
#include "net_dir.h" | ||
|
||
int RUNNING = 1; | ||
|
||
int main() { | ||
tun_init(); | ||
|
||
char buf[1600]; | ||
|
||
while (1) { | ||
int read_bytes = tun_read(buf, sizeof(buf)); | ||
printf("read bytes: %d\n", read_bytes); | ||
printf("read values: %x\n", buf); | ||
} | ||
// char buf[1600]; | ||
|
||
// while (1) { | ||
// int read_bytes = tun_read(buf, sizeof(buf)); | ||
// printf("read bytes: %d\n", read_bytes); | ||
// printf("read values: %x\n", buf); | ||
// } | ||
// free_tun(); | ||
|
||
net_dir_receive(); | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* | ||
This file will handle ethernet frame receive parsing & transmit | ||
we need to implement both incoming & outgoing. incoming is a bit easier to implement imo | ||
for receiving/incoming: | ||
- each incoming packet gets stored in a new allocated sk_buff - data will live in sk_buff as it gets passed up the pipeline | ||
*/ | ||
#include "syshead.h" | ||
#include "tuntap_interface.h" | ||
#include "skbuff.h" | ||
#include "eth.h" | ||
|
||
// https://ethernethistory.typepad.com/papers/EthernetSpec.pdf - page 32 | ||
#define MAX_FRAME_SIZE 1600 | ||
|
||
extern int RUNNING; | ||
|
||
|
||
void net_dir_receive() { | ||
while (RUNNING) { | ||
/* | ||
allocate skbuff | ||
read from tap + check for error read | ||
if err, free skbuff, end | ||
otherwise: | ||
cast to eth struct defined in eth.h (eth.h will take care of big endian -> little endian) | ||
look at ethertype, send to the correct place (ARP/IP) | ||
*/ | ||
|
||
struct sk_buff *skb = alloc_skb(MAX_FRAME_SIZE); | ||
|
||
if (tun_read((char *) skb->data, MAX_FRAME_SIZE) < 0) { | ||
perror("err reading from tun_read"); | ||
free(skb); | ||
// return NULL; | ||
exit(1); | ||
} | ||
|
||
struct eth_hdr *header = unpack_eth_hdr(skb); | ||
|
||
if (header->ether_type == ETH_P_ARP) { // direct to ARP receive | ||
|
||
printf("DIRECTING TO ARP\n"); | ||
// print the ARP packet | ||
printf("ARP PACKET\n"); | ||
printf("SRC MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", header->ether_shost[0], header->ether_shost[1], header->ether_shost[2], header->ether_shost[3], header->ether_shost[4], header->ether_shost[5]); | ||
printf("DEST MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", header->ether_dhost[0], header->ether_dhost[1], header->ether_dhost[2], header->ether_dhost[3], header->ether_dhost[4], header->ether_dhost[5]); | ||
|
||
} else if (header->ether_type == ETH_P_IP) { // direct to IP receive | ||
|
||
printf("DIRECTING TO IP\n"); | ||
|
||
} | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
/* | ||
Reimplementation of Linux's skbuff data structure. | ||
https://docs.kernel.org/networking/skbuff.html | ||
struct defs: https://docs.kernel.org/networking/kapi.html#c.sk_buff | ||
why do we need skbuff? can't we just pass our raw data into some raw thing? | ||
https://wiki.linuxfoundation.org/networking/sk_buff#:~:text=However%2C%20sk_buff%20provides%20an%20additional,need%20to%20be%20copied%20around. | ||
essentially: | ||
we are reimplementing a doubly-linked list + the additional functions that skbuff implements (ex: skb_put(), skb_put(), etc) | ||
- for the doubly linked list implementation, see dl_list.c/h | ||
skbuff will be the main carrier that carries our network data through the networking layers. | ||
*/ | ||
|
||
#include "skbuff.h" | ||
#include "dl_list.h" | ||
|
||
struct sk_buff *alloc_skb(unsigned int size) { | ||
struct sk_buff *skb = calloc(1, sizeof(struct sk_buff)); | ||
skb->head = malloc(size); | ||
skb->data = skb->head; | ||
skb->tail = skb->head; | ||
skb->end = skb->head + size; | ||
|
||
list_init(&skb->list); | ||
|
||
return skb; | ||
} |