diff options
author | Marvin Borner | 2020-11-18 17:53:31 +0100 |
---|---|---|
committer | Marvin Borner | 2020-11-18 17:53:31 +0100 |
commit | a5a04ef3de6ad3f81d37a04fede23eb3b4b348b1 (patch) | |
tree | 555496762aaa15e810bf3038bd2d444d68931d65 /kernel | |
parent | 431c88102153b8b41a15a1105e291ecf161c030e (diff) |
Added browser and many networking things
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/features/net.c | 83 | ||||
-rw-r--r-- | kernel/features/proc.c | 10 | ||||
-rw-r--r-- | kernel/features/syscall.c | 8 | ||||
-rw-r--r-- | kernel/inc/net.h | 13 | ||||
-rw-r--r-- | kernel/inc/proc.h | 2 |
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; |