aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorMarvin Borner2020-11-18 17:53:31 +0100
committerMarvin Borner2020-11-18 17:53:31 +0100
commita5a04ef3de6ad3f81d37a04fede23eb3b4b348b1 (patch)
tree555496762aaa15e810bf3038bd2d444d68931d65 /kernel
parent431c88102153b8b41a15a1105e291ecf161c030e (diff)
Added browser and many networking things
Diffstat (limited to 'kernel')
-rw-r--r--kernel/features/net.c83
-rw-r--r--kernel/features/proc.c10
-rw-r--r--kernel/features/syscall.c8
-rw-r--r--kernel/inc/net.h13
-rw-r--r--kernel/inc/proc.h2
5 files changed, 73 insertions, 43 deletions
diff --git a/kernel/features/net.c b/kernel/features/net.c
index 01e8721..b58c1da 100644
--- a/kernel/features/net.c
+++ b/kernel/features/net.c
@@ -374,23 +374,6 @@ static void icmp_handle_packet(struct icmp_packet *request_packet, u32 dst)
free(packet);
}
-// TODO: Less magic numbers :)
-static void dns_handle_packet(struct dns_packet *packet)
-{
- print("DNS!\n");
- u16 flags = htons(packet->flags);
- u8 reply_code = flags & 0xf;
- if (reply_code != DNS_NOERROR) {
- printf("DNS error: %d\n", reply_code);
- return;
- }
-
- u8 *start = &packet->data[1] + strlen((char *)&packet->data[1]);
- printf("TTL of %s: %ds\n", &packet->data[1], (u32)start[14]);
- u8 *ip = &start[17];
- printf("IP: %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
-}
-
static void dhcp_handle_packet(struct dhcp_packet *packet)
{
print("DHCP!\n");
@@ -510,10 +493,16 @@ static void tcp_handle_packet(struct tcp_packet *packet, u32 dst, int len)
tcp->state++;
return;
} else if (tcp->state == 6 && (flags & 0xff) == (TCP_FLAG_ACK | TCP_FLAG_PSH)) {
- for (u32 i = 0; i < data_length; ++i) {
- if (packet->data[i])
- printf("%c", packet->data[i]);
+ struct socket_data *sdata = malloc(sizeof(*sdata));
+ sdata->length = data_length;
+ if (sdata->length) {
+ sdata->data = malloc(data_length);
+ memcpy(sdata->data, packet->data, data_length);
+ } else {
+ sdata->data = NULL;
}
+ list_add(socket->packets, sdata);
+ proc_from_pid(socket->pid)->state = PROC_RUNNING;
tcp->ack_no += data_length;
tcp->seq_no = recv_ack;
@@ -539,14 +528,11 @@ static void udp_handle_packet(struct udp_packet *packet)
{
printf("UDP Port: %d\n", ntohs(packet->dst_port));
- void *data_ptr = (u8 *)packet + sizeof(*packet);
+ void *data_ptr = packet->data;
if (ntohs(packet->dst_port) == DHCP_PORT) {
dhcp_handle_packet(data_ptr);
return;
- } else if (ntohs(packet->dst_port) == DNS_PORT) {
- dns_handle_packet(data_ptr);
- return;
}
struct socket *socket = NULL;
@@ -557,7 +543,16 @@ static void udp_handle_packet(struct udp_packet *packet)
}
// TODO: Socket event to process
- (void)socket;
+ struct socket_data *sdata = malloc(sizeof(*sdata));
+ sdata->length = ntohs(packet->length);
+ if (sdata->length) {
+ sdata->data = malloc(sdata->length);
+ memcpy(sdata->data, packet->data, sdata->length);
+ } else {
+ sdata->data = NULL;
+ }
+ list_add(socket->packets, sdata);
+ proc_from_pid(socket->pid)->state = PROC_RUNNING;
}
static void ip_handle_packet(struct ip_packet *packet, int len)
@@ -716,6 +711,8 @@ struct socket *net_open(enum socket_type type)
socket->type = type;
socket->state = S_OPEN;
+ socket->packets = list_new();
+ socket->pid = proc_current()->pid;
return socket;
}
@@ -727,7 +724,7 @@ void net_close(struct socket *socket)
int net_connect(struct socket *socket, u32 ip_addr, u16 dst_port)
{
- if (!socket || socket->state != S_OPEN)
+ if (!socket || socket->state != S_OPEN || !ip_addr || !dst_port)
return 0;
socket->ip_addr = ip_addr;
@@ -741,6 +738,7 @@ int net_connect(struct socket *socket, u32 ip_addr, u16 dst_port)
socket->prot.tcp.ack_no = 0;
socket->prot.tcp.state = 0;
socket->state = S_CONNECTING;
+ // TODO: Don't block kernel
tcp_send_packet(socket, TCP_FLAG_SYN, NULL, 0);
sti();
u32 time = timer_get();
@@ -776,6 +774,37 @@ void net_send(struct socket *socket, void *data, u32 len)
}
}
+int net_data_available(struct socket *socket)
+{
+ if (socket && socket->packets && socket->packets->head &&
+ ((struct socket_data *)socket->packets->head->data)->length > 0)
+ return 1;
+ else
+ return 0;
+}
+
+int net_receive(struct socket *socket, void *buf, u32 len)
+{
+ if (!socket || !socket->packets)
+ return 0;
+
+ u32 offset = 0;
+ struct node *iterator = socket->packets->head;
+ while (iterator != NULL) {
+ struct socket_data *sdata = iterator->data;
+ u32 length = sdata->length;
+ if (offset + length < len) {
+ memcpy((u8 *)buf + offset, sdata->data, length);
+ offset += length;
+ } else {
+ break;
+ };
+ iterator = iterator->next;
+ }
+
+ return offset;
+}
+
/**
* Install
*/
@@ -820,8 +849,6 @@ void net_install(void)
}
// Request
- /* dns_request("google", "de"); */
-
/* struct socket *socket = net_open(S_TCP); */
/* if (socket && net_connect(socket, ip(91, 89, 253, 227), 80)) */
/* net_send(socket, strdup(http_req), strlen(http_req)); */
diff --git a/kernel/features/proc.c b/kernel/features/proc.c
index 76f552b..ffe0af0 100644
--- a/kernel/features/proc.c
+++ b/kernel/features/proc.c
@@ -36,14 +36,18 @@ void scheduler(struct regs *regs)
if (current)
memcpy(&((struct proc *)current->data)->regs, regs, sizeof(struct regs));
- if (priority_proc) {
+ if (priority_proc && priority_proc->state == PROC_RUNNING) {
current = list_first_data(proc_list, priority_proc);
priority_proc = NULL;
assert(current);
- } else if (current && current->next) {
+ } else if (current && current->next &&
+ ((struct proc *)current->next->data)->state == PROC_RUNNING) {
current = current->next;
- } else {
+ } else if (((struct proc *)proc_list->head->data)->state == PROC_RUNNING) {
current = proc_list->head;
+ } else {
+ print("TODO: All processes are sleeping!\n"); // TODO!
+ /* loop(); */
}
memcpy(regs, &((struct proc *)current->data)->regs, sizeof(struct regs));
diff --git a/kernel/features/syscall.c b/kernel/features/syscall.c
index b601d96..3ee5a82 100644
--- a/kernel/features/syscall.c
+++ b/kernel/features/syscall.c
@@ -108,6 +108,14 @@ void syscall_handler(struct regs *r)
net_send((void *)r->ebx, (void *)r->ecx, r->edx);
break;
}
+ case SYS_NET_RECEIVE: {
+ if (!net_data_available((void *)r->ebx)) {
+ proc_current()->state = PROC_SLEEPING;
+ proc_yield(r);
+ }
+ r->eax = net_receive((void *)r->ebx, (void *)r->ecx, r->edx);
+ break;
+ }
default: {
print("Unknown syscall!\n");
break;
diff --git a/kernel/inc/net.h b/kernel/inc/net.h
index 5630e97..0c36691 100644
--- a/kernel/inc/net.h
+++ b/kernel/inc/net.h
@@ -40,17 +40,6 @@
#define DHCP_REPLY 2
#define DHCP_TRANSACTION_IDENTIFIER 0x18122002
-#define DNS_NOERROR 0
-#define DNS_FORMERR 1
-#define DNS_SERVFAIL 2
-#define DNS_NXDOMAIN 3
-#define DNS_NOTIMP 4
-#define DNS_REFUSED 5
-#define DNS_YXDOMAIN 6
-#define DNS_XRRSET 7
-#define DNS_NOTAUTH 8
-#define DNS_NOTZONE 9
-
#define HARDWARE_TYPE_ETHERNET 0x01
// Hardcoded ports - TODO!
@@ -171,6 +160,8 @@ struct socket *net_open(enum socket_type type);
void net_close(struct socket *socket);
int net_connect(struct socket *socket, u32 ip_addr, u16 dst_port);
void net_send(struct socket *socket, void *data, u32 len);
+int net_receive(struct socket *socket, void *buf, u32 len);
+int net_data_available(struct socket *socket);
void net_install(void);
diff --git a/kernel/inc/proc.h b/kernel/inc/proc.h
index ad95104..dc12369 100644
--- a/kernel/inc/proc.h
+++ b/kernel/inc/proc.h
@@ -17,7 +17,7 @@
#define GDT_USER_CODE_OFFSET 0x1b // User code segment offset in GDT (with ring3 mask)
#define GDT_USER_DATA_OFFSET 0x23 // User data segment offset in GDT (with ring3 mask)
-enum proc_state { PROC_RUNNING };
+enum proc_state { PROC_RUNNING, PROC_SLEEPING };
struct proc {
u32 pid;