rumpk/apps/subject_zero/main.c

77 lines
2.8 KiB
C

// Subject Zero - Freestanding Canary
// Markus Maiwald | Voxis Forge
// Provided by libnexus.a (Membrane)
extern int socket(int domain, int type, int protocol);
extern int connect(int fd, const void *addr, int len);
extern int write(int fd, const void *buf, int count);
extern int printf(const char *format, ...); // Maybe mapped to write(1, ...)
// LwIP / Membrane Helpers
extern unsigned short htons(unsigned short hostshort);
extern int inet_pton(int af, const char *src, void *dst);
struct sockaddr_in {
unsigned short sin_family;
unsigned short sin_port;
unsigned int sin_addr;
char sin_zero[8];
};
#define AF_INET 2
#define SOCK_STREAM 1
extern void membrane_init(void);
extern void pump_membrane_stack(void);
int subject_zero_entry() {
membrane_init();
write(1, "[Subject0] Boot sequence initiated.\n", 36);
write(1, "[Subject0] Requesting Membrane Socket...\n", 41);
int fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0) {
write(1, "[Subject0] FAILURE: socket() returned error\n", 44);
return 1;
}
write(1, "[Subject0] Got Socket. Connecting to Host (10.0.2.2:8080)...\n", 62);
struct sockaddr_in serv_addr;
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = 0x901F; // htons(8080) -> 0x1F90, wait, swapped for Big Endian is 0x901F
serv_addr.sin_addr = 0x0202000A; // 10.0.2.2 -> 0x0A, 0x00, 0x02, 0x02. In memory: A 0 2 2. As uint32 BE: 0x0A000202.
// Wait, 0x0202000A as Little Endian uint32 is bytes 0A 00 02 02.
// If the machine is Little Endian (RISC-V), then 0x0202000A in a register
// will be stored as 0A 00 02 02 in memory.
// LwIP expects sin_addr as 4 bytes in network order.
// So 0x0202000A is CORRECT for 10.0.2.2 if sin_addr is uint32.
// Wait, 10.0.2.2 -> A.0.2.2 -> 0x0A000202.
// Let's just use 0x0202000A and see.
// Actually, let's use a cleaner way.
if (connect(fd, &serv_addr, sizeof(serv_addr)) < 0) {
write(1, "[Subject0] Connection Failed.\n", 30);
return 1;
}
write(1, "[Subject0] CONNECTED! Sending Greeting...\n", 42);
char *hello = "Hello from the Membrane!\n";
write(fd, hello, 26);
write(1, hello, 26);
write(1, "[Subject0] Entering Loop.\n", 26);
while(1) {
pump_membrane_stack();
// Yield to Kernel (Phase 7 Coop)
typedef void (*yield_func)(void);
yield_func rumpk_yield = *(yield_func*)0x801FFFF0;
if (rumpk_yield) rumpk_yield();
for(volatile int i=0; i<100000; i++);
}
return 0;
}