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/features | |
parent | 431c88102153b8b41a15a1105e291ecf161c030e (diff) |
Added browser and many networking things
Diffstat (limited to 'kernel/features')
-rw-r--r-- | kernel/features/net.c | 83 | ||||
-rw-r--r-- | kernel/features/proc.c | 10 | ||||
-rw-r--r-- | kernel/features/syscall.c | 8 |
3 files changed, 70 insertions, 31 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; |