Skip to content

Commit 45d7478

Browse files
committed
untested. ported networking from https://github.com/szhou42/osdev, but it seems unfinished.
1 parent 02db9e0 commit 45d7478

File tree

24 files changed

+1292
-12
lines changed

24 files changed

+1292
-12
lines changed

TODO

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,9 @@ runtime dynamic linker for binaries, instead of implementing userland and syscal
4949
- when a binary is loaded, the linker would resolve the syscalls or whatever, but how, id need my own exec format, so i can know when and where something unresolved would be called, this can bite me in the back later, and i will need to replace it further down the line. but it seems like a quick and easy way to get `outside` programs running from fs
5050
https://forum.osdev.org/viewtopic.php?t=57631
5151
- this guy did something, and can exec shit right away, maybe it would be useful if i could actually run things not specifically compiled for my os only, POSIX compliance? there has to be more than that
52+
53+
54+
c9:
55+
- c9 seems to work, but there is no way to forward COM1 to the internet, id need a network driver, and a socket model, thats pretty overkill rn
56+
- port the rtl8139, arp, dhcp, udp drivers
57+
https://github.com/szhou42/osdev/blob/master/src/kernel/network/udp.c#L12

drivers/arp.c

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
#include "arp.h"
2+
#include "libc/heap.h"
3+
#include "libc/mem.h"
4+
#include "network.h"
5+
#include "rtl8139.h"
6+
#include "serial.h"
7+
8+
arp_table_entry_t arp_table[512];
9+
int arp_table_size;
10+
int arp_table_curr;
11+
12+
uint8_t broadcast_mac_address[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
13+
14+
void arp_handle_packet(arp_packet_t *arp_packet) {
15+
uint8_t dst_hardware_addr[6];
16+
uint8_t dst_protocol_addr[4];
17+
// save some packet field
18+
memcpy(dst_hardware_addr, arp_packet->src_hardware_addr, 6);
19+
memcpy(dst_protocol_addr, arp_packet->src_protocol_addr, 4);
20+
// reply arp request, if the ip address matches(have to hard code the IP
21+
// eveywhere, because I don't have dhcp yet)
22+
if (ntohs(arp_packet->opcode) == ARP_REQUEST) {
23+
// qemu_printf("Got ARP REQUEST......................");
24+
uint32_t my_ip = 0x0e02000a;
25+
if (memcmp(arp_packet->dst_protocol_addr, (uint8_t *)&my_ip, 4)) {
26+
27+
// set source MAC address, IP address (hardcode the IP address as 10.2.2.3
28+
// until we really get one..)
29+
get_mac_addr(arp_packet->src_hardware_addr);
30+
arp_packet->src_protocol_addr[0] = 10;
31+
arp_packet->src_protocol_addr[1] = 0;
32+
arp_packet->src_protocol_addr[2] = 2;
33+
arp_packet->src_protocol_addr[3] = 14;
34+
35+
// set destination MAC address, IP address
36+
memcpy(arp_packet->dst_hardware_addr, dst_hardware_addr, 6);
37+
memcpy(arp_packet->dst_protocol_addr, dst_protocol_addr, 4);
38+
39+
// set opcode
40+
arp_packet->opcode = htons(ARP_REPLY);
41+
42+
// set lengths
43+
arp_packet->hardware_addr_len = 6;
44+
arp_packet->protocol_addr_len = 4;
45+
46+
// set hardware type
47+
arp_packet->hardware_type = htons(HARDWARE_TYPE_ETHERNET);
48+
49+
// set protocol = IPv4
50+
arp_packet->protocol = htons(ETHERNET_TYPE_IP);
51+
52+
// now send it with ethernet
53+
ethernet_send_packet(dst_hardware_addr, (uint8_t *)arp_packet,
54+
sizeof(arp_packet_t), ETHERNET_TYPE_ARP);
55+
56+
// qemu_printf("Replied Arp, the reply looks like this\n");
57+
}
58+
} else if (ntohs(arp_packet->opcode) == ARP_REPLY) {
59+
// may be we can handle the case where we get a reply after sending a
60+
// request, but i don't think my os will ever need to do so...
61+
// qemu_printf("Got ARP REPLY......................");
62+
} else {
63+
serial_printff("Got unknown ARP, opcode = %d\n", arp_packet->opcode);
64+
}
65+
66+
// now, store the ip-mac address mapping relation
67+
memcpy(&arp_table[arp_table_curr].ip_addr, dst_protocol_addr, 4);
68+
memcpy(&arp_table[arp_table_curr].mac_addr, dst_hardware_addr, 6);
69+
if (arp_table_size < 512)
70+
arp_table_size++;
71+
// wrap around
72+
if (arp_table_curr >= 512)
73+
arp_table_curr = 0;
74+
}
75+
76+
void arp_send_packet(uint8_t *dst_hardware_addr, uint8_t *dst_protocol_addr) {
77+
arp_packet_t arp_packet = {0};
78+
79+
// set source MAC address, IP address (hardcode the IP address as 10.2.2.3
80+
// until we really get one..)
81+
get_mac_addr(arp_packet.src_hardware_addr);
82+
arp_packet.src_protocol_addr[0] = 10;
83+
arp_packet.src_protocol_addr[1] = 0;
84+
arp_packet.src_protocol_addr[2] = 2;
85+
arp_packet.src_protocol_addr[3] = 14;
86+
87+
// set destination MAC address, IP address
88+
memcpy(arp_packet.dst_hardware_addr, dst_hardware_addr, 6);
89+
memcpy(arp_packet.dst_protocol_addr, dst_protocol_addr, 4);
90+
91+
// set opcode
92+
arp_packet.opcode = htons(ARP_REQUEST);
93+
94+
// set lengths
95+
arp_packet.hardware_addr_len = 6;
96+
arp_packet.protocol_addr_len = 4;
97+
98+
// set hardware type
99+
arp_packet.hardware_type = htons(HARDWARE_TYPE_ETHERNET);
100+
101+
// set protocol = IPv4
102+
arp_packet.protocol = htons(ETHERNET_TYPE_IP);
103+
104+
// now send it with ethernet
105+
ethernet_send_packet(broadcast_mac_address, (uint8_t *)&arp_packet,
106+
sizeof(arp_packet_t), ETHERNET_TYPE_ARP);
107+
}
108+
109+
void arp_lookup_add(uint8_t *ret_hardware_addr, uint8_t *ip_addr) {
110+
memcpy(&arp_table[arp_table_curr].ip_addr, ip_addr, 4);
111+
memcpy(&arp_table[arp_table_curr].mac_addr, ret_hardware_addr, 6);
112+
if (arp_table_size < 512)
113+
arp_table_size++;
114+
// wrap around
115+
if (arp_table_curr >= 512)
116+
arp_table_curr = 0;
117+
}
118+
119+
int arp_lookup(uint8_t *ret_hardware_addr, uint8_t *ip_addr) {
120+
uint32_t ip_entry = *((uint32_t *)(ip_addr));
121+
for (int i = 0; i < 512; i++) {
122+
if (arp_table[i].ip_addr == ip_entry) {
123+
memcpy(ret_hardware_addr, &arp_table[i].mac_addr, 6);
124+
return 1;
125+
}
126+
}
127+
return 0;
128+
}
129+
130+
void arp_init() {
131+
uint8_t broadcast_ip[4];
132+
uint8_t broadcast_mac[6];
133+
134+
memset(broadcast_ip, 0xff, 4);
135+
memset(broadcast_mac, 0xff, 6);
136+
arp_lookup_add(broadcast_mac, broadcast_ip);
137+
}

drivers/arp.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#pragma once
2+
#include "libc/types.h"
3+
4+
#define ARP_REQUEST 1
5+
#define ARP_REPLY 2
6+
7+
typedef struct arp_packet {
8+
uint16_t hardware_type;
9+
uint16_t protocol;
10+
uint8_t hardware_addr_len;
11+
uint8_t protocol_addr_len;
12+
uint16_t opcode;
13+
uint8_t src_hardware_addr[6];
14+
uint8_t src_protocol_addr[4];
15+
uint8_t dst_hardware_addr[6];
16+
uint8_t dst_protocol_addr[4];
17+
} __attribute__((packed)) arp_packet_t;
18+
19+
typedef struct arp_table_entry {
20+
uint32_t ip_addr;
21+
uint64_t mac_addr;
22+
} arp_table_entry_t;
23+
24+
void arp_handle_packet(arp_packet_t *arp_packet);
25+
void arp_send_packet(uint8_t *dst_hardware_addr, uint8_t *dst_protocol_addr);
26+
int arp_lookup(uint8_t *ret_hardware_addr, uint8_t *ip_addr);
27+
void arp_lookup_add(uint8_t *ret_hardware_addr, uint8_t *ip_addr);
28+
void arp_init();

drivers/dhcp.c

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
#include "dhcp.h"
2+
#include "libc/heap.h"
3+
#include "libc/mem.h"
4+
#include "libc/string.h"
5+
#include "network.h"
6+
#include "rtl8139.h"
7+
#include "udp.h"
8+
9+
char ip_addr[4];
10+
int is_ip_allocated;
11+
12+
/*
13+
* getter for IP address obtained from dhcp server
14+
* */
15+
int gethostaddr(char *addr) {
16+
memcpy(addr, ip_addr, 4);
17+
if (!is_ip_allocated) {
18+
return 0;
19+
}
20+
return 1;
21+
}
22+
23+
/*
24+
* broadcast a dhcp discover
25+
* */
26+
void dhcp_discover() {
27+
uint8_t request_ip[4];
28+
uint8_t dst_ip[4];
29+
memset(request_ip, 0x0, 4);
30+
memset(dst_ip, 0xff, 4);
31+
dhcp_packet_t *packet = (dhcp_packet_t *)kmalloc(sizeof(dhcp_packet_t));
32+
memset(packet, 0, sizeof(dhcp_packet_t));
33+
make_dhcp_packet(packet, 1, request_ip);
34+
udp_send_packet(dst_ip, 68, 67, packet, sizeof(dhcp_packet_t));
35+
}
36+
37+
/*
38+
* broadcast a dhcp request
39+
* */
40+
// uint8_t??
41+
void dhcp_request(uint8_t *request_ip) {
42+
uint8_t dst_ip[4];
43+
memset(dst_ip, 0xff, 4);
44+
dhcp_packet_t *packet = (dhcp_packet_t *)kmalloc(sizeof(dhcp_packet_t));
45+
memset(packet, 0, sizeof(dhcp_packet_t));
46+
make_dhcp_packet(packet, 3, request_ip);
47+
udp_send_packet(dst_ip, 68, 67, packet, sizeof(dhcp_packet_t));
48+
}
49+
50+
/*
51+
* handle DHCP offer packet
52+
* */
53+
void dhcp_handle_packet(dhcp_packet_t *packet) {
54+
// uint8_t *options = packet->options + 4;
55+
if (packet->op == DHCP_REPLY) {
56+
// DHCP Offer or ACK ?
57+
uint8_t *type = get_dhcp_options(packet, 53);
58+
if (*type == 2) {
59+
// offer, return a request
60+
dhcp_request((uint8_t *)&packet->your_ip); // uint8_t??
61+
} else if (*type == 5) {
62+
// ACK, save necessary info(IP for example)
63+
memcpy(ip_addr, &packet->your_ip, 4);
64+
is_ip_allocated = 1;
65+
}
66+
}
67+
}
68+
69+
/*
70+
* search for the value of a type in options
71+
* */
72+
void *get_dhcp_options(dhcp_packet_t *packet, uint8_t type) {
73+
uint8_t *options = packet->options + 4;
74+
uint8_t curr_type = *options;
75+
while (curr_type != 0xff) {
76+
uint8_t len = *(options + 1);
77+
if (curr_type == type) {
78+
// found type, return value
79+
void *ret = (void *)kmalloc(len);
80+
memcpy(ret, options + 2, len);
81+
return ret;
82+
}
83+
options += (2 + len);
84+
}
85+
return 0;
86+
}
87+
88+
void make_dhcp_packet(dhcp_packet_t *packet, uint8_t msg_type,
89+
uint8_t *request_ip) {
90+
packet->op = DHCP_REQUEST;
91+
packet->hardware_type = HARDWARE_TYPE_ETHERNET;
92+
packet->hardware_addr_len = 6;
93+
packet->hops = 0;
94+
packet->xid = htonl(DHCP_TRANSACTION_IDENTIFIER);
95+
packet->flags = htons(0x8000);
96+
get_mac_addr(packet->client_hardware_addr);
97+
98+
// send dhcp packet using UDP
99+
uint8_t dst_ip[4];
100+
memset(dst_ip, 0xff, 4);
101+
102+
// Ooptions specific to DHCP Discover (required)
103+
104+
// magic cookie
105+
uint8_t *options = packet->options;
106+
*((uint32_t *)(options)) = htonl(0x63825363);
107+
options += 4;
108+
109+
// first option, message type = DHCP_DISCOVER/DHCP_REQUEST
110+
*(options++) = 53;
111+
*(options++) = 1;
112+
*(options++) = msg_type;
113+
114+
// client identifier
115+
*(options++) = 61;
116+
*(options++) = 0x07;
117+
*(options++) = 0x01;
118+
get_mac_addr(options);
119+
options += 6;
120+
121+
// requested IP address
122+
*(options++) = 50;
123+
*(options++) = 0x04;
124+
*((uint32_t *)(options)) = htonl(0x0a00020e);
125+
memcpy((uint32_t *)(options), request_ip, 4);
126+
options += 4;
127+
128+
// host Name
129+
*(options++) = 12;
130+
*(options++) = 0x09;
131+
memcpy(options, "simpleos", strlen("simpleos"));
132+
options += strlen("simpleos");
133+
*(options++) = 0x00;
134+
135+
// parameter request list
136+
*(options++) = 55;
137+
*(options++) = 8;
138+
*(options++) = 0x1;
139+
*(options++) = 0x3;
140+
*(options++) = 0x6;
141+
*(options++) = 0xf;
142+
*(options++) = 0x2c;
143+
*(options++) = 0x2e;
144+
*(options++) = 0x2f;
145+
*(options++) = 0x39;
146+
*(options++) = 0xff;
147+
}

drivers/dhcp.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#pragma once
2+
#include "libc/types.h"
3+
4+
#define DHCP_REQUEST 1
5+
#define DHCP_REPLY 2
6+
7+
#define DHCP_TRANSACTION_IDENTIFIER 0x55555555
8+
9+
typedef struct dhcp_packet {
10+
uint8_t op;
11+
uint8_t hardware_type;
12+
uint8_t hardware_addr_len;
13+
uint8_t hops;
14+
uint32_t xid;
15+
uint16_t seconds;
16+
uint16_t flags; // may be broken
17+
uint32_t client_ip; //
18+
uint32_t your_ip;
19+
uint32_t server_ip;
20+
uint32_t gateway_ip;
21+
uint8_t client_hardware_addr[16];
22+
uint8_t server_name[64];
23+
uint8_t file[128];
24+
uint8_t options[64];
25+
} __attribute__((packed)) dhcp_packet_t;
26+
27+
int gethostaddr(char *addr);
28+
void dhcp_discover();
29+
void dhcp_request(uint8_t *request_ip);
30+
void dhcp_handle_packet(dhcp_packet_t *packet);
31+
void *get_dhcp_options(dhcp_packet_t *packet, uint8_t type);
32+
void make_dhcp_packet(dhcp_packet_t *packet, uint8_t msg_type,
33+
uint8_t *request_ip);

0 commit comments

Comments
 (0)