mirror of
https://github.com/BoredDevNL/BoredOS.git
synced 2026-05-15 10:48:38 +00:00
Network commands port to userspace
This commit is contained in:
parent
304c2e1383
commit
8a6928b5c9
22 changed files with 680 additions and 69 deletions
BIN
boredos.iso
BIN
boredos.iso
Binary file not shown.
BIN
build/cmd.o
BIN
build/cmd.o
Binary file not shown.
BIN
build/icmp.o
BIN
build/icmp.o
Binary file not shown.
BIN
build/main.o
BIN
build/main.o
Binary file not shown.
BIN
build/network.o
BIN
build/network.o
Binary file not shown.
|
|
@ -1,33 +0,0 @@
|
|||
src/kernel/wm.c: In function 'wm_handle_click':
|
||||
src/kernel/wm.c:1491:29: warning: this 'if' clause does not guard... [-Wmisleading-indentation]
|
||||
1491 | if (col < 0) col = 0; if (row < 0) row = 0;
|
||||
| ^~
|
||||
src/kernel/wm.c:1491:51: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'
|
||||
1491 | if (col < 0) col = 0; if (row < 0) row = 0;
|
||||
| ^~
|
||||
src/kernel/wm.c: In function 'wm_handle_mouse':
|
||||
src/kernel/wm.c:1884:17: error: implicit declaration of function 'cli_cmd_shutdown' [-Wimplicit-function-declaration]
|
||||
1884 | cli_cmd_shutdown(NULL);
|
||||
| ^~~~~~~~~~~~~~~~
|
||||
src/kernel/wm.c:1886:17: error: implicit declaration of function 'cli_cmd_reboot' [-Wimplicit-function-declaration]
|
||||
1886 | cli_cmd_reboot(NULL);
|
||||
| ^~~~~~~~~~~~~~
|
||||
src/kernel/wm.c:2083:41: warning: this 'if' clause does not guard... [-Wmisleading-indentation]
|
||||
2083 | if (col < 0) col = 0; if (row < 0) row = 0;
|
||||
| ^~
|
||||
src/kernel/wm.c:2083:63: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'
|
||||
2083 | if (col < 0) col = 0; if (row < 0) row = 0;
|
||||
| ^~
|
||||
src/kernel/wm.c: At top level:
|
||||
src/kernel/wm.c:1057:13: warning: 'erase_cursor' defined but not used [-Wunused-function]
|
||||
1057 | static void erase_cursor(int x, int y) {
|
||||
| ^~~~~~~~~~~~
|
||||
src/kernel/wm.c:976:13: warning: 'draw_dock_editor' defined but not used [-Wunused-function]
|
||||
976 | static void draw_dock_editor(int x, int y) {
|
||||
| ^~~~~~~~~~~~~~~~
|
||||
src/kernel/wm.c:82:13: warning: 'cursor_visible' defined but not used [-Wunused-variable]
|
||||
82 | static bool cursor_visible = true;
|
||||
| ^~~~~~~~~~~~~~
|
||||
src/kernel/wm.c:79:12: warning: 'desktop_refresh_timer' defined but not used [-Wunused-variable]
|
||||
79 | static int desktop_refresh_timer = 0;
|
||||
| ^~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
@ -89,4 +89,62 @@ void cli_cmd_ping(char *args) {
|
|||
}
|
||||
}
|
||||
is_pinging = false;
|
||||
}
|
||||
|
||||
// Syscall version of ping for userland - returns success/failure
|
||||
int cli_cmd_ping_syscall(ipv4_address_t *dest) {
|
||||
if (!dest) return -1;
|
||||
|
||||
// Check if network is initialized
|
||||
if (!network_is_initialized()) {
|
||||
return -2; // Network not initialized
|
||||
}
|
||||
|
||||
ipv4_address_t dest_ip = *dest;
|
||||
|
||||
is_pinging = true;
|
||||
const int payload_size = 8;
|
||||
uint8_t packet[sizeof(icmp_header_t) + payload_size];
|
||||
icmp_header_t *icmp = (icmp_header_t *)packet;
|
||||
int success_count = 0;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
current_ping_id = ++ping_id_counter;
|
||||
icmp->type = 8; // Echo Request
|
||||
icmp->code = 0;
|
||||
icmp->id = htons(current_ping_id);
|
||||
icmp->sequence = htons(i + 1);
|
||||
icmp->checksum = 0;
|
||||
|
||||
// Fill payload
|
||||
for (int j = 0; j < payload_size; j++) {
|
||||
packet[sizeof(icmp_header_t) + j] = (uint8_t)('a' + (j % 26));
|
||||
}
|
||||
|
||||
icmp->checksum = net_checksum(packet, sizeof(packet));
|
||||
|
||||
ping_reply_received = false;
|
||||
ip_send_packet(dest_ip, IP_PROTO_ICMP, packet, sizeof(packet));
|
||||
|
||||
uint32_t start_ticks = wm_get_ticks();
|
||||
while (!ping_reply_received && (wm_get_ticks() - start_ticks) < 180) { // 3 seconds timeout
|
||||
network_process_frames();
|
||||
}
|
||||
|
||||
if (ping_reply_received) {
|
||||
success_count++;
|
||||
}
|
||||
|
||||
if (i < 3) {
|
||||
// Wait a bit before next ping
|
||||
uint32_t wait_start = wm_get_ticks();
|
||||
while ((wm_get_ticks() - wait_start) < 60) {
|
||||
network_process_frames();
|
||||
}
|
||||
}
|
||||
}
|
||||
is_pinging = false;
|
||||
|
||||
// Return number of successful replies
|
||||
return success_count;
|
||||
}
|
||||
10
src/kernel/icmp.h
Normal file
10
src/kernel/icmp.h
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef ICMP_H
|
||||
#define ICMP_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "network.h"
|
||||
|
||||
void icmp_handle_packet(ipv4_address_t src, void *data, uint16_t len);
|
||||
int cli_cmd_ping_syscall(ipv4_address_t *dest);
|
||||
|
||||
#endif
|
||||
|
|
@ -46,13 +46,6 @@ static volatile struct limine_request *const requests_start_marker[] = {
|
|||
NULL
|
||||
};
|
||||
|
||||
__attribute__((used, section(".requests")))
|
||||
static volatile struct limine_stack_size_request stack_size_request = {
|
||||
.id = LIMINE_STACK_SIZE_REQUEST,
|
||||
.revision = 0,
|
||||
.stack_size = 1024 * 1024 // 1MB stack
|
||||
};
|
||||
|
||||
__attribute__((used, section(".requests_end")))
|
||||
static volatile struct limine_request *const requests_end_marker[] = {
|
||||
NULL
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@ void create_man_entries(void) {
|
|||
fat32_mkdir("A:/Library");
|
||||
fat32_mkdir("A:/Library/man");
|
||||
|
||||
write_man_file("ping", "PING - Send ICMP echo requests\n\nUsage: ping <ip>\n\nSends ICMP echo requests to the specified IP address and displays the response times.");
|
||||
write_man_file("net", "NET - Network utilities\n\nUsage: net init\nnet info\nnet ipset >ip<\nnet udpsend >ip< >port< >message< net ping >ip< net help\n\nA collection of network-related commands.");
|
||||
write_man_file("ls", "LS - List directory contents\n\nUsage: ls [path]\n\nLists files and directories in the current or specified directory.");
|
||||
write_man_file("cat", "CAT - Concatenate and display file contents\n\nUsage: cat <filename>\n\nDisplays the text content of the specified file.");
|
||||
write_man_file("man", "MAN - Display manual pages\n\nUsage: man <command>\n\nDisplays help information for the specified command.");
|
||||
|
|
|
|||
|
|
@ -51,8 +51,8 @@ void process_create(void* entry_point, bool is_user) {
|
|||
if (!new_proc->pml4_phys) return;
|
||||
|
||||
// 2. Allocate aligned stack
|
||||
void* stack = kmalloc_aligned(524288, 4096); // 512KB for kernel threads
|
||||
void* kernel_stack = kmalloc_aligned(126976, 16384); // 128KB for ringswitch
|
||||
void* stack = kmalloc_aligned(4096, 4096);
|
||||
void* kernel_stack = kmalloc_aligned(16384, 16384); // Needed for when user interrupts to Ring 0
|
||||
|
||||
if (is_user) {
|
||||
// Map user stack to 0x800000
|
||||
|
|
@ -66,7 +66,7 @@ void process_create(void* entry_point, bool is_user) {
|
|||
|
||||
// Build initial stack frame for iretq
|
||||
// Stack grows down, start at top
|
||||
uint64_t* stack_ptr = (uint64_t*)((uint64_t)kernel_stack + 126976);
|
||||
uint64_t* stack_ptr = (uint64_t*)((uint64_t)kernel_stack + 16384);
|
||||
|
||||
*(--stack_ptr) = 0x1B; // SS (User Data)
|
||||
*(--stack_ptr) = 0x800000 + 4096; // RSP
|
||||
|
|
@ -79,11 +79,11 @@ void process_create(void* entry_point, bool is_user) {
|
|||
// Push 15 zeros for general purpose registers (r15 -> rax)
|
||||
for (int i = 0; i < 15; i++) *(--stack_ptr) = 0;
|
||||
|
||||
new_proc->kernel_stack = (uint64_t)kernel_stack + 126976;
|
||||
new_proc->kernel_stack = (uint64_t)kernel_stack + 16384;
|
||||
new_proc->rsp = (uint64_t)stack_ptr;
|
||||
} else {
|
||||
// Kernel thread
|
||||
uint64_t* stack_ptr = (uint64_t*)((uint64_t)stack + 524288);
|
||||
uint64_t* stack_ptr = (uint64_t*)((uint64_t)stack + 4096);
|
||||
*(--stack_ptr) = 0x10; // SS (Kernel Data)
|
||||
stack_ptr--;
|
||||
*stack_ptr = (uint64_t)stack_ptr; // RSP
|
||||
|
|
@ -134,18 +134,17 @@ process_t* process_create_elf(const char* filepath, const char* args_str) {
|
|||
}
|
||||
|
||||
// 3. Allocate generic User stack and Kernel stack for interrupts
|
||||
void* stack = kmalloc_aligned(2097152, 4096); // 2MB for user apps
|
||||
void* kernel_stack = kmalloc_aligned(126976, 16384); // 128KB for interrupts
|
||||
void* stack = kmalloc_aligned(65536, 4096);
|
||||
void* kernel_stack = kmalloc_aligned(16384, 16384);
|
||||
|
||||
// Map User stack to 0x800000 (starting from 0x600000 for 2MB)
|
||||
for (uint64_t i = 0; i < 512; i++) {
|
||||
paging_map_page(new_proc->pml4_phys, 0x800000 - 2097152 + (i * 4096), v2p((uint64_t)stack + (i * 4096)), PT_PRESENT | PT_RW | PT_USER);
|
||||
// Map User stack to 0x800000 (starting from 0x7F0000 for 64KB)
|
||||
for (uint64_t i = 0; i < 16; i++) {
|
||||
paging_map_page(new_proc->pml4_phys, 0x800000 - 65536 + (i * 4096), v2p((uint64_t)stack + (i * 4096)), PT_PRESENT | PT_RW | PT_USER);
|
||||
}
|
||||
|
||||
// Parse arguments and push them to the user stack
|
||||
// We'll place the strings at the very high end of the user stack
|
||||
|
||||
int argc = 1;
|
||||
char *args_buf = (char *)stack + 2097152;
|
||||
char *args_buf = (char *)stack + 65536;
|
||||
uint64_t user_args_buf = 0x800000;
|
||||
|
||||
// Copy filepath as argv[0]
|
||||
|
|
@ -197,7 +196,7 @@ process_t* process_create_elf(const char* filepath, const char* args_str) {
|
|||
// Align stack to 8 bytes before pushing argv array
|
||||
uint64_t current_user_sp = user_args_buf;
|
||||
current_user_sp &= ~7ULL;
|
||||
args_buf = (char *)((uint64_t)stack + (current_user_sp - (0x800000 - 2097152)));
|
||||
args_buf = (char *)((uint64_t)stack + (current_user_sp - (0x800000 - 65536)));
|
||||
|
||||
// Push argv array
|
||||
int argv_size = (argc + 1) * sizeof(uint64_t);
|
||||
|
|
@ -215,7 +214,7 @@ process_t* process_create_elf(const char* filepath, const char* args_str) {
|
|||
current_user_sp &= ~15ULL;
|
||||
|
||||
// 4. Build Stack Frame for context switch via IRETQ
|
||||
uint64_t* stack_ptr = (uint64_t*)((uint64_t)kernel_stack + 126976);
|
||||
uint64_t* stack_ptr = (uint64_t*)((uint64_t)kernel_stack + 16384);
|
||||
*(--stack_ptr) = 0x1B; // SS (User Mode Data)
|
||||
*(--stack_ptr) = current_user_sp; // RSP (Updated user stack pointer)
|
||||
*(--stack_ptr) = 0x202; // RFLAGS (Interrupts Enabled)
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@
|
|||
#include "io.h"
|
||||
#include "pci.h"
|
||||
#include "kutils.h"
|
||||
#include "network.h"
|
||||
#include "icmp.h"
|
||||
|
||||
// Read MSR
|
||||
static inline uint64_t rdmsr(uint32_t msr) {
|
||||
|
|
@ -671,6 +673,54 @@ uint64_t syscall_handler_c(uint64_t syscall_num, uint64_t arg1, uint64_t arg2, u
|
|||
return 0;
|
||||
}
|
||||
return -1;
|
||||
} else if (cmd == 18) { // SYSTEM_CMD_NETWORK_DHCP
|
||||
return network_dhcp_acquire();
|
||||
} else if (cmd == 19) { // SYSTEM_CMD_NETWORK_GET_MAC
|
||||
mac_address_t *mac = (mac_address_t *)arg2;
|
||||
if (!mac) return -1;
|
||||
return network_get_mac_address(mac);
|
||||
} else if (cmd == 20) { // SYSTEM_CMD_NETWORK_GET_IP
|
||||
ipv4_address_t *ip = (ipv4_address_t *)arg2;
|
||||
if (!ip) return -1;
|
||||
return network_get_ipv4_address(ip);
|
||||
} else if (cmd == 21) { // SYSTEM_CMD_NETWORK_SET_IP
|
||||
ipv4_address_t *ip = (ipv4_address_t *)arg2;
|
||||
if (!ip) return -1;
|
||||
return network_set_ipv4_address(ip);
|
||||
} else if (cmd == 22) { // SYSTEM_CMD_UDP_SEND
|
||||
ipv4_address_t *dest_ip = (ipv4_address_t *)arg2;
|
||||
uint32_t ports = (uint32_t)arg3; // dest_port in lower 16, src_port in upper 16
|
||||
uint16_t dest_port = ports & 0xFFFF;
|
||||
uint16_t src_port = (ports >> 16) & 0xFFFF;
|
||||
const void *data = (const void *)arg4;
|
||||
size_t data_len = (size_t)arg5;
|
||||
if (!dest_ip || !data) return -1;
|
||||
return udp_send_packet(dest_ip, dest_port, src_port, data, data_len);
|
||||
} else if (cmd == 23) { // SYSTEM_CMD_NETWORK_GET_STATS
|
||||
int stat_type = (int)arg2;
|
||||
switch (stat_type) {
|
||||
case 0: return network_get_frames_received();
|
||||
case 1: return network_get_udp_packets_received();
|
||||
case 2: return network_get_udp_callbacks_called();
|
||||
case 3: return network_get_e1000_receive_calls();
|
||||
case 4: return network_get_e1000_receive_empty();
|
||||
case 5: return network_get_process_calls();
|
||||
default: return -1;
|
||||
}
|
||||
} else if (cmd == 24) { // SYSTEM_CMD_NETWORK_GET_GATEWAY
|
||||
ipv4_address_t *ip = (ipv4_address_t *)arg2;
|
||||
if (!ip) return -1;
|
||||
return network_get_gateway_ip(ip);
|
||||
} else if (cmd == 25) { // SYSTEM_CMD_NETWORK_GET_DNS
|
||||
ipv4_address_t *ip = (ipv4_address_t *)arg2;
|
||||
if (!ip) return -1;
|
||||
return network_get_dns_ip(ip);
|
||||
} else if (cmd == 26) { // SYSTEM_CMD_ICMP_PING
|
||||
ipv4_address_t *dest_ip = (ipv4_address_t *)arg2;
|
||||
if (!dest_ip) return -1;
|
||||
return cli_cmd_ping_syscall(dest_ip);
|
||||
} else if (cmd == 27) { // SYSTEM_CMD_NETWORK_IS_INIT
|
||||
return network_is_initialized() ? 1 : 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -191,17 +191,13 @@ static void calculator_click(int x, int y) {
|
|||
if (calc_decimal_divisor > 10) {
|
||||
calc_decimal_divisor /= 10;
|
||||
long long unit = SCALE / calc_decimal_divisor;
|
||||
// This removes the last decimal digit
|
||||
calc_curr = (calc_curr / (unit * 10)) * (unit * 10);
|
||||
} else {
|
||||
// Backspace on the dot itself or first decimal
|
||||
calc_decimal_mode = false;
|
||||
calc_decimal_divisor = 10;
|
||||
// Ensure the fractional part is cleared
|
||||
calc_curr = (calc_curr / SCALE) * SCALE;
|
||||
}
|
||||
} else {
|
||||
// Integer backspace: remove last digit of integer part
|
||||
calc_curr = (calc_curr / SCALE / 10) * SCALE;
|
||||
}
|
||||
}
|
||||
|
|
@ -240,11 +236,9 @@ int main(void) {
|
|||
calc_new_entry = true;
|
||||
update_display();
|
||||
|
||||
// First paint
|
||||
calculator_paint();
|
||||
ui_mark_dirty(win_calculator, 0, 0, 180, 230);
|
||||
|
||||
// Check events from Kernel User Interface queue
|
||||
gui_event_t ev;
|
||||
while (1) {
|
||||
if (ui_get_event(win_calculator, &ev)) {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,6 @@
|
|||
|
||||
int main(int argc, char **argv) {
|
||||
(void)argc; (void)argv;
|
||||
sys_system(10, 0, 0, 0, 0); // SYSTEM_CMD_CLEAR_SCREEN
|
||||
sys_system(10, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@
|
|||
int main(int argc, char **argv) {
|
||||
char *msg = (char*)"Bored!";
|
||||
if (argc > 1) {
|
||||
// Simple concatenation of args for now
|
||||
// For simplicity in this demo, just use the first arg
|
||||
msg = argv[1];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
int main(int argc, char **argv) {
|
||||
(void)argc; (void)argv;
|
||||
printf("BoredOS CLI Help (Userspace)\n");
|
||||
printf("BoredOS CLI Help\n");
|
||||
printf("---------------------------\n");
|
||||
printf("ls [path] - List directory contents\n");
|
||||
printf("cd <path> - Change current directory (built-in)\n");
|
||||
|
|
@ -27,6 +27,6 @@ int main(int argc, char **argv) {
|
|||
printf("man <cmd> - Show manual page\n");
|
||||
printf("clear - Clear the screen\n");
|
||||
printf("exit - Exit the terminal\n");
|
||||
printf("\nHint: Use Ctrl+C to force quit any running .elf app.\n");
|
||||
printf("\nHint: Use Ctrl+C to force quit any running application.\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ uint32_t sys_size(int fd) {
|
|||
return (uint32_t)syscall2(SYS_FS, FS_CMD_SIZE, (uint64_t)fd);
|
||||
}
|
||||
|
||||
int sys_list(const char *path, struct FAT32_FileInfo *entries, int max_entries) {
|
||||
int sys_list(const char *path, FAT32_FileInfo *entries, int max_entries) {
|
||||
return (int)syscall4(SYS_FS, FS_CMD_LIST, (uint64_t)path, (uint64_t)entries, (uint64_t)max_entries);
|
||||
}
|
||||
|
||||
|
|
@ -133,3 +133,49 @@ void sys_kill(int pid) {
|
|||
syscall1(SYS_KILL, (uint64_t)pid);
|
||||
}
|
||||
|
||||
// Network API implementations
|
||||
int sys_network_init(void) {
|
||||
return (int)syscall2(SYS_SYSTEM, SYSTEM_CMD_NETWORK_INIT, 0);
|
||||
}
|
||||
|
||||
int sys_network_dhcp_acquire(void) {
|
||||
return (int)syscall2(SYS_SYSTEM, SYSTEM_CMD_NETWORK_DHCP, 0);
|
||||
}
|
||||
|
||||
int sys_network_get_mac(net_mac_address_t *mac) {
|
||||
return (int)syscall2(SYS_SYSTEM, SYSTEM_CMD_NETWORK_GET_MAC, (uint64_t)mac);
|
||||
}
|
||||
|
||||
int sys_network_get_ip(net_ipv4_address_t *ip) {
|
||||
return (int)syscall2(SYS_SYSTEM, SYSTEM_CMD_NETWORK_GET_IP, (uint64_t)ip);
|
||||
}
|
||||
|
||||
int sys_network_set_ip(const net_ipv4_address_t *ip) {
|
||||
return (int)syscall2(SYS_SYSTEM, SYSTEM_CMD_NETWORK_SET_IP, (uint64_t)ip);
|
||||
}
|
||||
|
||||
int sys_network_get_stat(int stat_type) {
|
||||
return (int)syscall2(SYS_SYSTEM, SYSTEM_CMD_NETWORK_GET_STATS, (uint64_t)stat_type);
|
||||
}
|
||||
|
||||
int sys_network_get_gateway(net_ipv4_address_t *ip) {
|
||||
return (int)syscall2(SYS_SYSTEM, SYSTEM_CMD_NETWORK_GET_GATEWAY, (uint64_t)ip);
|
||||
}
|
||||
|
||||
int sys_network_get_dns(net_ipv4_address_t *ip) {
|
||||
return (int)syscall2(SYS_SYSTEM, SYSTEM_CMD_NETWORK_GET_DNS, (uint64_t)ip);
|
||||
}
|
||||
|
||||
int sys_udp_send(const net_ipv4_address_t *dest_ip, uint16_t dest_port, uint16_t src_port, const void *data, size_t data_len) {
|
||||
uint32_t ports = (dest_port & 0xFFFF) | ((src_port & 0xFFFF) << 16);
|
||||
return (int)syscall5(SYS_SYSTEM, SYSTEM_CMD_UDP_SEND, (uint64_t)dest_ip, (uint64_t)ports, (uint64_t)data, (uint64_t)data_len);
|
||||
}
|
||||
|
||||
int sys_icmp_ping(const net_ipv4_address_t *dest_ip) {
|
||||
return (int)syscall2(SYS_SYSTEM, SYSTEM_CMD_ICMP_PING, (uint64_t)dest_ip);
|
||||
}
|
||||
|
||||
int sys_network_is_initialized(void) {
|
||||
return (int)syscall2(SYS_SYSTEM, SYSTEM_CMD_NETWORK_IS_INIT, 0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#define SYSCALL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
// Standard syscalls available from Kernel mode
|
||||
#define SYS_EXIT 0
|
||||
|
|
@ -27,6 +28,35 @@
|
|||
#define FS_CMD_GETCWD 12
|
||||
#define FS_CMD_CHDIR 13
|
||||
|
||||
// System Commands (via SYS_SYSTEM)
|
||||
#define SYSTEM_CMD_SET_BG_COLOR 1
|
||||
#define SYSTEM_CMD_SET_BG_PATTERN 2
|
||||
#define SYSTEM_CMD_SET_WALLPAPER 3
|
||||
#define SYSTEM_CMD_SET_DESKTOP_PROP 4
|
||||
#define SYSTEM_CMD_SET_MOUSE_SPEED 5
|
||||
#define SYSTEM_CMD_NETWORK_INIT 6
|
||||
#define SYSTEM_CMD_GET_DESKTOP_PROP 7
|
||||
#define SYSTEM_CMD_GET_MOUSE_SPEED 8
|
||||
#define SYSTEM_CMD_GET_WALLPAPER_THUMB 9
|
||||
#define SYSTEM_CMD_CLEAR_SCREEN 10
|
||||
#define SYSTEM_CMD_RTC_GET 11
|
||||
#define SYSTEM_CMD_REBOOT 12
|
||||
#define SYSTEM_CMD_SHUTDOWN 13
|
||||
#define SYSTEM_CMD_BEEP 14
|
||||
#define SYSTEM_CMD_MEMINFO 15
|
||||
#define SYSTEM_CMD_UPTIME 16
|
||||
#define SYSTEM_CMD_PCI_LIST 17
|
||||
#define SYSTEM_CMD_NETWORK_DHCP 18
|
||||
#define SYSTEM_CMD_NETWORK_GET_MAC 19
|
||||
#define SYSTEM_CMD_NETWORK_GET_IP 20
|
||||
#define SYSTEM_CMD_NETWORK_SET_IP 21
|
||||
#define SYSTEM_CMD_UDP_SEND 22
|
||||
#define SYSTEM_CMD_NETWORK_GET_STATS 23
|
||||
#define SYSTEM_CMD_NETWORK_GET_GATEWAY 24
|
||||
#define SYSTEM_CMD_NETWORK_GET_DNS 25
|
||||
#define SYSTEM_CMD_ICMP_PING 26
|
||||
#define SYSTEM_CMD_NETWORK_IS_INIT 27
|
||||
|
||||
// Internal assembly entry into Ring 0
|
||||
extern uint64_t syscall0(uint64_t sys_num);
|
||||
extern uint64_t syscall1(uint64_t sys_num, uint64_t arg1);
|
||||
|
|
@ -67,4 +97,20 @@ typedef struct {
|
|||
|
||||
int sys_list(const char *path, FAT32_FileInfo *entries, int max_entries);
|
||||
|
||||
// Network API
|
||||
typedef struct { uint8_t bytes[6]; } net_mac_address_t;
|
||||
typedef struct { uint8_t bytes[4]; } net_ipv4_address_t;
|
||||
|
||||
int sys_network_init(void);
|
||||
int sys_network_dhcp_acquire(void);
|
||||
int sys_network_get_mac(net_mac_address_t *mac);
|
||||
int sys_network_get_ip(net_ipv4_address_t *ip);
|
||||
int sys_network_set_ip(const net_ipv4_address_t *ip);
|
||||
int sys_network_get_stat(int stat_type);
|
||||
int sys_network_get_gateway(net_ipv4_address_t *ip);
|
||||
int sys_network_get_dns(net_ipv4_address_t *ip);
|
||||
int sys_udp_send(const net_ipv4_address_t *dest_ip, uint16_t dest_port, uint16_t src_port, const void *data, size_t data_len);
|
||||
int sys_icmp_ping(const net_ipv4_address_t *dest_ip);
|
||||
int sys_network_is_initialized(void);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ int main(int argc, char **argv) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
// Simplification: use cp then rm
|
||||
int fd_in = sys_open(argv[1], "r");
|
||||
if (fd_in < 0) {
|
||||
printf("Error: Cannot open source %s\n", argv[1]);
|
||||
|
|
|
|||
376
src/kernel/userland/net.c
Normal file
376
src/kernel/userland/net.c
Normal file
|
|
@ -0,0 +1,376 @@
|
|||
#include <stdlib.h>
|
||||
#include <syscall.h>
|
||||
|
||||
// Helper function to print a MAC address
|
||||
static void print_mac(const net_mac_address_t* mac) {
|
||||
char buf[64];
|
||||
int p = 0;
|
||||
for (int i = 0; i < 6; i++) {
|
||||
int v = mac->bytes[i];
|
||||
int hi = (v >> 4) & 0xF;
|
||||
int lo = v & 0xF;
|
||||
buf[p++] = (hi < 10) ? ('0' + hi) : ('A' + (hi - 10));
|
||||
buf[p++] = (lo < 10) ? ('0' + lo) : ('A' + (lo - 10));
|
||||
if (i < 5) buf[p++] = ':';
|
||||
}
|
||||
buf[p] = 0;
|
||||
printf("%s", buf);
|
||||
}
|
||||
|
||||
// Helper to parse integer from string
|
||||
static int string_to_int(const char *str) {
|
||||
int result = 0;
|
||||
int sign = 1;
|
||||
if (*str == '-') {
|
||||
sign = -1;
|
||||
str++;
|
||||
}
|
||||
while (*str >= '0' && *str <= '9') {
|
||||
result = result * 10 + (*str - '0');
|
||||
str++;
|
||||
}
|
||||
return result * sign;
|
||||
}
|
||||
|
||||
// Helper to get string length
|
||||
static int string_length(const char *str) {
|
||||
int len = 0;
|
||||
while (str[len]) len++;
|
||||
return len;
|
||||
}
|
||||
|
||||
// Command: netinit - Initialize network and acquire DHCP
|
||||
static void cmd_netinit(void) {
|
||||
int r = sys_network_init();
|
||||
if (r == 0) {
|
||||
printf("Network initialized\n");
|
||||
int d = sys_network_dhcp_acquire();
|
||||
if (d == 0) {
|
||||
printf("DHCP acquired\n");
|
||||
} else {
|
||||
printf("DHCP failed\n");
|
||||
}
|
||||
} else {
|
||||
printf("Network init failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Command: netinfo - Display network information
|
||||
static void cmd_netinfo(void) {
|
||||
if (!sys_network_is_initialized()) {
|
||||
printf("Error: Network not initialized. Run 'net init' first.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
net_mac_address_t mac;
|
||||
net_ipv4_address_t ip;
|
||||
|
||||
if (sys_network_get_mac(&mac) == 0) {
|
||||
printf("MAC: ");
|
||||
print_mac(&mac);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (sys_network_get_ip(&ip) == 0) {
|
||||
printf("IP: ");
|
||||
for (int i = 0; i < 4; i++) {
|
||||
printf("%d", ip.bytes[i]);
|
||||
if (i < 3) printf(".");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
printf("Frames: %d\n", sys_network_get_stat(0));
|
||||
printf("UDP packets: %d\n", sys_network_get_stat(1));
|
||||
printf("UDP callbacks: %d\n", sys_network_get_stat(2));
|
||||
printf("E1000 receive calls: %d\n", sys_network_get_stat(3));
|
||||
printf("E1000 receive empty: %d\n", sys_network_get_stat(4));
|
||||
printf("Process calls: %d\n", sys_network_get_stat(5));
|
||||
}
|
||||
|
||||
// Command: ipset - Set IP address manually
|
||||
static void cmd_ipset(const char *args) {
|
||||
if (!sys_network_is_initialized()) {
|
||||
printf("Error: Network not initialized. Run 'net init' first.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!args || !*args) {
|
||||
printf("Usage: NET IPSET a.b.c.d\n");
|
||||
return;
|
||||
}
|
||||
|
||||
net_ipv4_address_t ip = {{0, 0, 0, 0}};
|
||||
int part = 0;
|
||||
int val = 0;
|
||||
int i = 0;
|
||||
|
||||
while (args[i]) {
|
||||
char ch = args[i++];
|
||||
if (ch >= '0' && ch <= '9') {
|
||||
val = val * 10 + (ch - '0');
|
||||
if (val > 255) {
|
||||
printf("Invalid IP\n");
|
||||
return;
|
||||
}
|
||||
} else if (ch == '.') {
|
||||
if (part > 3) {
|
||||
printf("Invalid IP\n");
|
||||
return;
|
||||
}
|
||||
ip.bytes[part++] = (uint8_t)val;
|
||||
val = 0;
|
||||
} else {
|
||||
printf("Invalid IP\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (part != 3) {
|
||||
printf("Invalid IP\n");
|
||||
return;
|
||||
}
|
||||
ip.bytes[3] = (uint8_t)val;
|
||||
|
||||
if (sys_network_set_ip(&ip) == 0) {
|
||||
printf("IP set\n");
|
||||
} else {
|
||||
printf("IP set failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Command: udpsend - Send UDP packet
|
||||
static void cmd_udpsend(const char *args) {
|
||||
if (!sys_network_is_initialized()) {
|
||||
printf("Error: Network not initialized. Run 'net init' first.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!args || !*args) {
|
||||
printf("Usage: NET UDPSEND ip port data\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse IP address
|
||||
char ipstr[32];
|
||||
int pos = 0;
|
||||
while (args[pos] && args[pos] != ' ') {
|
||||
ipstr[pos] = args[pos];
|
||||
pos++;
|
||||
}
|
||||
ipstr[pos] = 0;
|
||||
|
||||
while (args[pos] == ' ') pos++;
|
||||
|
||||
// Parse port
|
||||
char portstr[16];
|
||||
int p = 0;
|
||||
while (args[pos] && args[pos] != ' ') {
|
||||
portstr[p++] = args[pos++];
|
||||
}
|
||||
portstr[p] = 0;
|
||||
|
||||
while (args[pos] == ' ') pos++;
|
||||
|
||||
// Get data
|
||||
const char *datastr = args + pos;
|
||||
|
||||
// Parse IP
|
||||
net_ipv4_address_t ip = {{0, 0, 0, 0}};
|
||||
int idx = 0;
|
||||
int val = 0;
|
||||
int j = 0;
|
||||
|
||||
while (ipstr[j]) {
|
||||
char ch = ipstr[j++];
|
||||
if (ch >= '0' && ch <= '9') {
|
||||
val = val * 10 + (ch - '0');
|
||||
if (val > 255) {
|
||||
printf("Invalid IP\n");
|
||||
return;
|
||||
}
|
||||
} else if (ch == '.') {
|
||||
if (idx > 3) {
|
||||
printf("Invalid IP\n");
|
||||
return;
|
||||
}
|
||||
ip.bytes[idx++] = (uint8_t)val;
|
||||
val = 0;
|
||||
} else {
|
||||
printf("Invalid IP\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (idx != 3) {
|
||||
printf("Invalid IP\n");
|
||||
return;
|
||||
}
|
||||
ip.bytes[3] = (uint8_t)val;
|
||||
|
||||
// Parse port
|
||||
int port = 0;
|
||||
int k = 0;
|
||||
while (portstr[k]) {
|
||||
char ch = portstr[k++];
|
||||
if (ch < '0' || ch > '9') {
|
||||
printf("Invalid port\n");
|
||||
return;
|
||||
}
|
||||
port = port * 10 + (ch - '0');
|
||||
}
|
||||
|
||||
if (port <= 0 || port > 65535) {
|
||||
printf("Invalid port\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int len = string_length(datastr);
|
||||
if (len <= 0) {
|
||||
printf("No data\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int r = sys_udp_send(&ip, (uint16_t)port, 12345, datastr, (size_t)len);
|
||||
if (r == 0) {
|
||||
printf("Sent\n");
|
||||
} else {
|
||||
printf("Send failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Command: ping - Send ICMP ping request
|
||||
static void cmd_ping(const char *args) {
|
||||
if (!sys_network_is_initialized()) {
|
||||
printf("Error: Network not initialized. Run 'net init' first.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!args || !*args) {
|
||||
printf("Usage: NET PING a.b.c.d\n");
|
||||
return;
|
||||
}
|
||||
|
||||
net_ipv4_address_t ip = {{0, 0, 0, 0}};
|
||||
int idx = 0;
|
||||
int val = 0;
|
||||
int j = 0;
|
||||
|
||||
while (args[j]) {
|
||||
char ch = args[j++];
|
||||
if (ch >= '0' && ch <= '9') {
|
||||
val = val * 10 + (ch - '0');
|
||||
if (val > 255) {
|
||||
printf("Invalid IP\n");
|
||||
return;
|
||||
}
|
||||
} else if (ch == '.') {
|
||||
if (idx > 3) {
|
||||
printf("Invalid IP\n");
|
||||
return;
|
||||
}
|
||||
ip.bytes[idx++] = (uint8_t)val;
|
||||
val = 0;
|
||||
} else if (ch == ' ' || ch == '\t') {
|
||||
// Skip whitespace
|
||||
while (args[j] == ' ' || args[j] == '\t') j++;
|
||||
j--;
|
||||
} else {
|
||||
printf("Invalid IP\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (idx != 3) {
|
||||
printf("Invalid IP\n");
|
||||
return;
|
||||
}
|
||||
ip.bytes[3] = (uint8_t)val;
|
||||
|
||||
printf("Pinging ");
|
||||
for (int i = 0; i < 4; i++) {
|
||||
printf("%d", ip.bytes[i]);
|
||||
if (i < 3) printf(".");
|
||||
}
|
||||
printf("...\n");
|
||||
|
||||
int result = sys_icmp_ping(&ip);
|
||||
|
||||
if (result == -2) {
|
||||
printf("Error: Network not initialized. Run 'net init' first.\n");
|
||||
} else if (result < 0) {
|
||||
printf("Error: Failed to send ping request.\n");
|
||||
} else {
|
||||
printf("Ping complete: %d/%d replies received\n", result, 4);
|
||||
}
|
||||
}
|
||||
|
||||
// Command: help
|
||||
static void cmd_help(void) {
|
||||
printf("Network Commands:\n");
|
||||
printf(" NET INIT - Initialize network and acquire DHCP\n");
|
||||
printf(" NET INFO - Display network information\n");
|
||||
printf(" NET IPSET a.b.c.d - Set IP address\n");
|
||||
printf(" NET UDPSEND ip port data - Send UDP packet\n");
|
||||
printf(" NET PING a.b.c.d - Send ICMP ping request\n");
|
||||
printf(" NET HELP - Show this help\n");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc < 2) {
|
||||
cmd_help();
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *cmd = argv[1];
|
||||
|
||||
// Convert command to uppercase for easier comparison
|
||||
char cmd_upper[32];
|
||||
int i = 0;
|
||||
while (cmd[i] && i < 31) {
|
||||
char c = cmd[i];
|
||||
cmd_upper[i] = (c >= 'a' && c <= 'z') ? (c - 'a' + 'A') : c;
|
||||
i++;
|
||||
}
|
||||
cmd_upper[i] = 0;
|
||||
|
||||
// Parse arguments if provided
|
||||
const char *args = "";
|
||||
if (argc > 2) {
|
||||
args = argv[2];
|
||||
}
|
||||
|
||||
if ((string_length(cmd_upper) == 4 &&
|
||||
cmd_upper[0] == 'I' && cmd_upper[1] == 'N' && cmd_upper[2] == 'I' && cmd_upper[3] == 'T') ||
|
||||
(string_length(cmd_upper) == 7 &&
|
||||
cmd_upper[0] == 'N' && cmd_upper[1] == 'E' && cmd_upper[2] == 'T' &&
|
||||
cmd_upper[3] == 'I' && cmd_upper[4] == 'N' && cmd_upper[5] == 'I' && cmd_upper[6] == 'T')) {
|
||||
cmd_netinit();
|
||||
} else if ((string_length(cmd_upper) == 4 &&
|
||||
cmd_upper[0] == 'I' && cmd_upper[1] == 'N' && cmd_upper[2] == 'F' && cmd_upper[3] == 'O') ||
|
||||
(string_length(cmd_upper) == 7 &&
|
||||
cmd_upper[0] == 'N' && cmd_upper[1] == 'E' && cmd_upper[2] == 'T' &&
|
||||
cmd_upper[3] == 'I' && cmd_upper[4] == 'N' && cmd_upper[5] == 'F' && cmd_upper[6] == 'O')) {
|
||||
cmd_netinfo();
|
||||
} else if (string_length(cmd_upper) == 5 &&
|
||||
cmd_upper[0] == 'I' && cmd_upper[1] == 'P' && cmd_upper[2] == 'S' &&
|
||||
cmd_upper[3] == 'E' && cmd_upper[4] == 'T') {
|
||||
cmd_ipset(args);
|
||||
} else if (string_length(cmd_upper) == 7 &&
|
||||
cmd_upper[0] == 'U' && cmd_upper[1] == 'D' && cmd_upper[2] == 'P' &&
|
||||
cmd_upper[3] == 'S' && cmd_upper[4] == 'E' && cmd_upper[5] == 'N' && cmd_upper[6] == 'D') {
|
||||
cmd_udpsend(args);
|
||||
} else if (string_length(cmd_upper) == 4 &&
|
||||
cmd_upper[0] == 'P' && cmd_upper[1] == 'I' && cmd_upper[2] == 'N' && cmd_upper[3] == 'G') {
|
||||
cmd_ping(args);
|
||||
} else if (string_length(cmd_upper) == 4 &&
|
||||
cmd_upper[0] == 'H' && cmd_upper[1] == 'E' && cmd_upper[2] == 'L' && cmd_upper[3] == 'P') {
|
||||
cmd_help();
|
||||
} else {
|
||||
printf("Unknown command: %s\n", cmd);
|
||||
cmd_help();
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@ typedef struct {
|
|||
|
||||
int main(int argc, char **argv) {
|
||||
(void)argc; (void)argv;
|
||||
int count = sys_system(17, 0, 0, 0, 0); // Get count
|
||||
int count = sys_system(17, 0, 0, 0, 0);
|
||||
if (count < 0) {
|
||||
printf("Error: Could not retrieve PCI device count.\n");
|
||||
return 1;
|
||||
|
|
|
|||
73
src/kernel/userland/ping.c
Normal file
73
src/kernel/userland/ping.c
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
#include <stdlib.h>
|
||||
#include <syscall.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc < 2) {
|
||||
printf("Usage: ping a.b.c.d\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!sys_network_is_initialized()) {
|
||||
printf("Error: Network not initialized. Run 'net init' first.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *args = argv[1];
|
||||
|
||||
net_ipv4_address_t ip = {{0, 0, 0, 0}};
|
||||
int idx = 0;
|
||||
int val = 0;
|
||||
int j = 0;
|
||||
|
||||
while (args[j]) {
|
||||
char ch = args[j++];
|
||||
if (ch >= '0' && ch <= '9') {
|
||||
val = val * 10 + (ch - '0');
|
||||
if (val > 255) {
|
||||
printf("Invalid IP\n");
|
||||
return 1;
|
||||
}
|
||||
} else if (ch == '.') {
|
||||
if (idx > 3) {
|
||||
printf("Invalid IP\n");
|
||||
return 1;
|
||||
}
|
||||
ip.bytes[idx++] = (uint8_t)val;
|
||||
val = 0;
|
||||
} else if (ch == ' ' || ch == '\t') {
|
||||
// Skip whitespace
|
||||
while (args[j] == ' ' || args[j] == '\t') j++;
|
||||
j--;
|
||||
} else {
|
||||
printf("Invalid IP\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (idx != 3) {
|
||||
printf("Invalid IP\n");
|
||||
return 1;
|
||||
}
|
||||
ip.bytes[3] = (uint8_t)val;
|
||||
|
||||
printf("Pinging ");
|
||||
for (int i = 0; i < 4; i++) {
|
||||
printf("%d", ip.bytes[i]);
|
||||
if (i < 3) printf(".");
|
||||
}
|
||||
printf("...\n");
|
||||
|
||||
int result = sys_icmp_ping(&ip);
|
||||
|
||||
if (result == -2) {
|
||||
printf("Error: Network not initialized. Run 'net init' first.\n");
|
||||
return 1;
|
||||
} else if (result < 0) {
|
||||
printf("Error: Failed to send ping request.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Ping complete: %d/%d replies received\n", result, 4);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in a new issue