/** * Handle system calls. Interrupts are enabled when this function is * called. * * @param user_context The userland context (CPU registers as they * where when system call instruction was called in userland) */ void syscall_handle(context_t *user_context) { /* When a syscall is executed in userland, register a0 contains * the number of the syscall. Registers a1, a2 and a3 contain the * arguments of the syscall. The userland code expects that after * returning from the syscall instruction the return value of the * syscall is found in register v0. Before entering this function * the userland context has been saved to user_context and after * returning from this function the userland context will be * restored from user_context. */ int retval; switch(user_context->cpu_regs[MIPS_REGISTER_A0]) { case SYSCALL_HALT: halt_kernel(); break; case SYSCALL_EXEC: retval = (int) process_spawn((char*) user_context->cpu_regs[MIPS_REGISTER_A1]); user_context->cpu_regs[MIPS_REGISTER_V0] = retval; break; case SYSCALL_EXIT: /* Resources are cleaned up in process_finish(...) */ process_finish(user_context->cpu_regs[MIPS_REGISTER_A1]); break; case SYSCALL_JOIN: retval = process_join(user_context->cpu_regs[MIPS_REGISTER_A1]); user_context->cpu_regs[MIPS_REGISTER_V0] = retval; break; case SYSCALL_READ: { int fhandle = user_context->cpu_regs[MIPS_REGISTER_A1]; int buffer = user_context->cpu_regs[MIPS_REGISTER_A2]; int length = user_context->cpu_regs[MIPS_REGISTER_A3]; int retval = syscall_read(fhandle, (void *)buffer, length); user_context->cpu_regs[MIPS_REGISTER_V0] = retval; } break; case SYSCALL_WRITE: { int fhandle = user_context->cpu_regs[MIPS_REGISTER_A1]; int buffer = user_context->cpu_regs[MIPS_REGISTER_A2]; int length = user_context->cpu_regs[MIPS_REGISTER_A3]; int retval = syscall_write(fhandle, (void *)buffer, length); user_context->cpu_regs[MIPS_REGISTER_V0] = retval; } break; default: KERNEL_PANIC("Unhandled system call\n"); } /* Move to next instruction after system call */ user_context->pc += 4; }
/** * Handle system calls. Interrupts are enabled when this function is * called. * * @param user_context The userland context (CPU registers as they * where when system call instruction was called in userland) */ void syscall_handle(context_t *user_context) { int retval; /* When a syscall is executed in userland, register a0 contains * the number of the syscall. Registers a1, a2 and a3 contain the * arguments of the syscall. The userland code expects that after * returning from the syscall instruction the return value of the * syscall is found in register v0. Before entering this function * the userland context has been saved to user_context and after * returning from this function the userland context will be * restored from user_context. */ switch(user_context->cpu_regs[MIPS_REGISTER_A0]) { case SYSCALL_HALT: halt_kernel(); break; case SYSCALL_READ: retval = read_file((int)user_context->cpu_regs[MIPS_REGISTER_A1], (void *)user_context->cpu_regs[MIPS_REGISTER_A2], (int)user_context->cpu_regs[MIPS_REGISTER_A3]); user_context->cpu_regs[MIPS_REGISTER_V0] = retval; break; case SYSCALL_WRITE: retval = write_file((int)user_context->cpu_regs[MIPS_REGISTER_A1], (void *)user_context->cpu_regs[MIPS_REGISTER_A2], (int)user_context->cpu_regs[MIPS_REGISTER_A3]); user_context->cpu_regs[MIPS_REGISTER_V0] = retval; break; case SYSCALL_EXIT: process_finish(user_context->cpu_regs[MIPS_REGISTER_A1]); break; case SYSCALL_EXEC: retval = exec((char *)user_context->cpu_regs[MIPS_REGISTER_A1]); user_context->cpu_regs[MIPS_REGISTER_V0] = retval; break; case SYSCALL_JOIN: retval = join((int)user_context->cpu_regs[MIPS_REGISTER_A1]); user_context->cpu_regs[MIPS_REGISTER_V0] = retval; break; default: KERNEL_PANIC("Unhandled system call\n"); } /* Move to next instruction after system call */ user_context->pc += 4; }
static void hash_command_handler(void *cmd_body, size_t cmd_size, size_t *response_size) { int mode; int hash_mode; int handle; uint16_t text_len; uint8_t *cmd; size_t response_room = *response_size; TPM_ALG_ID alg; cmd = cmd_body; /* * Empty response is sent as a success indication when the digest is * not yet expected (i.e. in response to 'start' and 'cont' commands, * as defined below). * * Single byte responses indicate errors, test successes are * communicated as responses of the size of the appropriate digests. */ *response_size = 0; /* * Command structure, shared out of band with the test driver running * on the host: * * field | size | note * =================================================================== * mode | 1 | 0 - start, 1 - cont., 2 - finish, 3 - single * hash_mode | 1 | 0 - sha1, 1 - sha256 * handle | 1 | seassion handle, ignored in 'single' mode * text_len | 2 | size of the text to process, big endian * text | text_len | text to hash */ mode = *cmd++; hash_mode = *cmd++; handle = *cmd++; text_len = *cmd++; text_len = text_len * 256 + *cmd++; switch (hash_mode) { case 0: alg = TPM_ALG_SHA1; break; case 1: alg = TPM_ALG_SHA256; break; default: return; } switch (mode) { case 0: /* Start a new hash context. */ process_start(alg, handle, cmd_body, response_size); if (*response_size) break; /* Something went wrong. */ process_continue(handle, cmd, text_len, cmd_body, response_size); break; case 1: process_continue(handle, cmd, text_len, cmd_body, response_size); break; case 2: process_continue(handle, cmd, text_len, cmd_body, response_size); if (*response_size) break; /* Something went wrong. */ process_finish(handle, cmd_body, response_size); CPRINTF("%s:%d response size %d\n", __func__, __LINE__, *response_size); break; case 3: /* Process a buffer in a single shot. */ if (!text_len) break; /* * Error responses are just 1 byte in size, valid responses * are of various hash sizes. */ *response_size = _cpri__HashBlock(alg, text_len, cmd, response_room, cmd_body); CPRINTF("%s:%d response size %d\n", __func__, __LINE__, *response_size); break; default: break; } }
int main(void) { BYTE flgRestart = FALSE; // if TRUE, restart main loop struct ifreq interface; // ioctls to configure network interface struct sockaddr_in myinterface; // Interface address struct sockaddr_in mynetmask; // Interface netmask struct sockaddr_in mybroadcast; // Interface broadcast address int server_sockfd; // Server socket struct sockaddr_in server_address; // Server address and port int heartbeat_sockfd; // Heartbeat socket struct sockaddr_in heartbeat_addr; // Heartbeat address and port int tx_sockfd; // Tx socket int optval, optlen; // Vars for socket options time_t timenow; // Current time time_t xaptick; // Last tick time_t heartbeattick; // Time for next hearbeat tick char heartbeat_msg[1500]; // Buffer for heartbeat messages char buff[1500]; // Buffer for messages fd_set rdfs; // Vars for attent to clients struct timeval tv; struct sockaddr_in client_address; // client address and port socklen_t client_len; int i; // Auxiliary variable // Header verbage //printf("\nHomected xAP-Hub Connector\n"); //printf("Copyright (C) Jose Luis Galindo, 2012\n"); // Create shared memory areas if (!hubSharedMemSetup()) { syslog(LOG_ERR, "main: Error allocating shared resources"); logError("main: Error allocating shared resources"); } // Initialize application init(); logInit(LOG_EVENTS_FILE, LOG_ERRORS_FILE); LIBXML_TEST_VERSION // Create the process process_init("xap-hub", pid_filepath); while(process_state == PROC_RUNNING) { // Load xml file with general settings if (parseXmlSettings(SETTINGS_FILE) > 0) { syslog(LOG_ERR, "main: Failed to parse xml settings document, default values loaded"); logError("main: Failed to parse xml settings document, default values loaded"); if (saveXmlSettings(SETTINGS_FILE) > 0) { syslog(LOG_ERR, "main: Error saving settings file"); logError("main: Error saving settings file"); } } // Use the server socket to get interface properties server_sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (server_sockfd == -1) { syslog(LOG_ERR, "main: Error trying to get interface properties"); logError("main: Error trying to get interface properties"); unlink(pid_filepath); exit(EXIT_FAILURE); } // Set options for the socket optval=1; optlen=sizeof(int); if (setsockopt(server_sockfd, SOL_SOCKET, SO_BROADCAST, (char*)&optval, optlen)) { syslog(LOG_ERR, "main: Error trying to get interface properties"); logError("main: Error trying to get interface properties"); unlink(pid_filepath); exit(EXIT_FAILURE); } optval=1; optlen=sizeof(int); if (setsockopt(server_sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&optval, optlen)) { syslog(LOG_ERR, "main: Error trying to get interface properties"); logError("main: Error trying to get interface properties"); unlink(pid_filepath); exit(EXIT_FAILURE); } // Query the low-level capabilities of the network interface to get address and netmask memset((char*)&interface, sizeof(interface),0); strcpy(interface.ifr_name, hubConfig->interfacename); // Get the interface address interface.ifr_addr.sa_family = AF_INET; if (ioctl(server_sockfd, SIOCGIFADDR, &interface) != 0) { syslog(LOG_ERR, "main: Could not determine IP address for interface %s", hubConfig->interfacename); logError("main: Could not determine IP address for interface %s", hubConfig->interfacename); unlink(pid_filepath); exit(EXIT_FAILURE); } myinterface.sin_addr.s_addr = ((struct sockaddr_in*)&interface.ifr_broadaddr)->sin_addr.s_addr; //printf("%s: address %s\n", interface.ifr_name, inet_ntoa(((struct sockaddr_in*)&interface.ifr_addr)->sin_addr)); logEvent(TRUE, "main: %s: address %s", interface.ifr_name, inet_ntoa(((struct sockaddr_in*)&interface.ifr_addr)->sin_addr)); // Get the interface netmask interface.ifr_broadaddr.sa_family = AF_INET; if (ioctl(server_sockfd, SIOCGIFNETMASK, &interface) != 0) { syslog(LOG_ERR, "Unable to determine netmask for interface %s", hubConfig->interfacename); logError("main: Unable to determine netmask for interface %s", hubConfig->interfacename); unlink(pid_filepath); exit(EXIT_FAILURE); } mynetmask.sin_addr.s_addr = ((struct sockaddr_in*)&interface.ifr_broadaddr)->sin_addr.s_addr; //printf("%s: netmask %s\n", interface.ifr_name, inet_ntoa(((struct sockaddr_in*)&interface.ifr_netmask)->sin_addr)); logEvent(TRUE, "main: %s: netmask %s", interface.ifr_name, inet_ntoa(((struct sockaddr_in*)&interface.ifr_netmask)->sin_addr)); // Determine the interface broadcast address long int inverted_netmask; inverted_netmask=~mynetmask.sin_addr.s_addr; mybroadcast.sin_addr.s_addr = inverted_netmask | myinterface.sin_addr.s_addr; //printf("%s: broadcast %s\n", interface.ifr_name, inet_ntoa(mybroadcast.sin_addr)); logEvent(TRUE, "main: %s: broadcast %s", interface.ifr_name, inet_ntoa(mybroadcast.sin_addr)); // Set the server socket server_sockfd = socket(AF_INET, SOCK_DGRAM, 0); // Set server address and port memset((char *) &server_address, 0, sizeof(server_address)); server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = htonl(INADDR_ANY); // Receive from any address server_address.sin_port = htons(hubConfig->xap_port); // on this port (Default 3639) // Bind the server socket with the server IP address and port fcntl(server_sockfd, F_SETFL, O_NONBLOCK); if (bind(server_sockfd, (struct sockaddr*)&server_address, sizeof(server_address)) !=0 ) { // if fails then we can assume that a hub is active on this host syslog(LOG_ERR, "main: Port %d is in use", hubConfig->xap_port); syslog(LOG_ERR, "main: Assuming other local hub is active on this host"); logError("main: Port %d is in use", hubConfig->xap_port); logError("main: Assuming other local hub is active on this host"); unlink(pid_filepath); exit(EXIT_FAILURE); } //printf("Listening for messages on port %d\n", g_xap_port); logEvent(TRUE, "main: Listening for messages on port %d", hubConfig->xap_port); // Set the server socket to listen listen(server_sockfd, MAX_QUEUE_BACKLOG); // Set up the Tx socket tx_sockfd = socket(AF_INET, SOCK_DGRAM, 0); // Set up the heartbeat socket, on which we tell the world we are alive and well heartbeat_sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (heartbeat_sockfd == -1) { syslog(LOG_ERR, "main: Heartbeat socket cannot be created"); logError("main: Heartbeat socket cannot be created"); unlink(pid_filepath); exit(EXIT_FAILURE); } // Set options for the heartbeat socket optval = 1; optlen = sizeof(int); if (setsockopt(heartbeat_sockfd, SOL_SOCKET, SO_BROADCAST, (char*)&optval, optlen)) { syslog(LOG_ERR, "main: Unable to set heartbeat socket options"); logError("main: Unable to set heartbeat socket options"); unlink(pid_filepath); exit(EXIT_FAILURE); } // Set up heartbeat address and port memset((char *) &heartbeat_addr, 0, sizeof(heartbeat_addr)); heartbeat_addr.sin_family = AF_INET; heartbeat_addr.sin_port = htons(hubConfig->xap_port); heartbeat_addr.sin_addr.s_addr = mybroadcast.sin_addr.s_addr; //printf("Set heartbeat broadcast on %s:%d\n", inet_ntoa(heartbeat_addr.sin_addr), g_xap_port); logEvent(TRUE, "main: Set heartbeat broadcast on %s:%d", inet_ntoa(heartbeat_addr.sin_addr), hubConfig->xap_port); xaptick = time((time_t*)0); heartbeattick = time((time_t*)0); // force heartbeat on startup //printf("Running...\n"); logEvent(TRUE, "main: Running..."); // Parse heartbeat messages received on broadcast interface // If they originated from this host, add the port number to the list of known ports // Otherwise ignore. // If ordinary header then pass to all known listeners while (!flgRestart && (process_state == PROC_RUNNING)) { // Get current time timenow = time((time_t*)0); // Hub tick, check for alive devices if (timenow - xaptick >= 1) { xaphub_tick(timenow - xaptick); xaptick = timenow; } // Heartbeat tick if (timenow >= heartbeattick) { //printf("Outgoing heartbeat tick %d\n",(int)timenow); logEvent(TRUE, "main: Outgoing heartbeat tick %d",(int)timenow); // Create the heartbeat message xaphub_build_heartbeat(heartbeat_msg); //printf("%s", heartbeat_msg); // Send heartbeat to all external listeners sendto(heartbeat_sockfd, heartbeat_msg, strlen(heartbeat_msg), 0, (struct sockaddr *) &heartbeat_addr, sizeof(heartbeat_addr)); // Send heartbeat to all locally connected apps xaphub_relay(tx_sockfd, heartbeat_msg); // Set next tick heartbeattick = timenow + hubConfig->xap_hbeat; } // Prepare to attent to the clients FD_ZERO(&rdfs); FD_SET(server_sockfd, &rdfs); tv.tv_sec = hubConfig->xap_hbeat; tv.tv_usec = 0; select(server_sockfd + 1, &rdfs, NULL, NULL, &tv); // Select either timed out, or there was data - go look for it. client_len = sizeof(struct sockaddr); i = recvfrom(server_sockfd, buff, sizeof(buff), 0, (struct sockaddr*) &client_address, &client_len); // Check if a message was received if (i != -1) { buff[i]='\0'; // Add NULL to the end of message //printf("Message from client %s:%d\n", inet_ntoa(client_address.sin_addr), ntohs(client_address.sin_port)); logEvent(TRUE, "main: Message from client %s:%d", inet_ntoa(client_address.sin_addr), ntohs(client_address.sin_port)); // Message from my interface if (client_address.sin_addr.s_addr == myinterface.sin_addr.s_addr) { //printf("Message originated from my interface\n"); // If the message received is a heartbeat message, add the client to the relay list xap_handler(buff); // Relay the message to all local apps, the originator will see his own message xaphub_relay(tx_sockfd, buff); } // Message from local client received else if (client_address.sin_addr.s_addr == inet_addr("127.0.0.1")) { //printf("Message from local client\n"); } // Remote message else { //printf("Message originated remotely, relay\n"); // Relay the message to all local apps xaphub_relay(tx_sockfd, buff); } // Clear message memset(buff, 0, sizeof(buff)); } // Check if has to save settings if (hubConfig->saveFlag) { hubConfig->saveFlag = FALSE; // Reset flag if (saveXmlSettings(SETTINGS_FILE) > 0) { syslog(LOG_ERR, "main: Error saving settings file"); logError("main: Error saving settings file"); } } // Check if has to restart if (hubConfig->restartFlag) { hubConfig->restartFlag = FALSE; // Reset flag flgRestart = TRUE; } } // Restore flgRestart flgRestart = FALSE; // Save xml settings if (saveXmlSettings(SETTINGS_FILE) > 0) { syslog(LOG_ERR, "main: Error saving settings file"); logError("main: Error saving settings file"); } // Build a xAP shutdown message xaphub_build_heartbeat_shutdown(heartbeat_msg); // Send shutdown heartbeat message to all external listeners sendto(heartbeat_sockfd, heartbeat_msg, strlen(heartbeat_msg), 0, (struct sockaddr *) &heartbeat_addr, sizeof(heartbeat_addr)); // Send shutdown heartbeat message to all locally connected apps xaphub_relay(tx_sockfd, heartbeat_msg); // Close xAP communications close(server_sockfd); // Close Server socket close(heartbeat_sockfd); // Close Heartbeat socket close(tx_sockfd); // Close Tx socket } // Close shared memory areas hubSharedMemClose(); // Destroy the process process_finish(); return 0; }
void syscall_exit(int retval){ process_finish(retval); }
void run_process(void *ptr, unsigned long num) { (void)num; int result; vaddr_t entrypoint, stackptr; // extract and free passed-in context struct new_process_context *ctxt = (struct new_process_context *)ptr; struct process *proc = ctxt->proc; struct vnode *v = ctxt->executable; int nargs = ctxt->nargs; char **args = ctxt->args; kfree(ctxt); // attach process to thread curthread->t_proc = proc; proc->ps_thread = curthread; // Activate address space as_activate(proc->ps_addrspace); // Load the executable result = load_elf(v, &entrypoint); if (result) { vfs_close(v); kprintf("runprogram failed: %s\n", strerror(result)); // alert the kernel menu that the process aborted process_finish(proc, _MKWAIT_SIG(SIGABRT)); return; } // Done with the file now vfs_close(v); // Define the user stack in the address space result = as_define_stack(proc->ps_addrspace, &stackptr); if (result) { kprintf("runprogram failed: %s\n", strerror(result)); // alert the kernel menu that the process aborted process_finish(proc, _MKWAIT_SIG(SIGABRT)); return; } // Copy out arguments userptr_t uargv[nargs + 1]; for (int i = 0; i < nargs; i++) { int aligned_length = WORD_ALIGN(strlen(args[i]) + 1); stackptr -= aligned_length; uargv[i] = (userptr_t)stackptr; size_t arg_len; result = copyoutstr(args[i], uargv[i], strlen(args[i]) + 1, &arg_len); if (result) { kprintf("runprogram failed: %s\n", strerror(result)); // alert the kernel menu that the process aborted process_finish(proc, _MKWAIT_SIG(SIGABRT)); return; } } uargv[nargs] =(userptr_t)NULL; // Copy out the argv array itself stackptr -= (nargs + 1) * sizeof(userptr_t); result = copyout(uargv, (userptr_t)stackptr, (nargs + 1) * sizeof(userptr_t)); if (result) { kprintf("runprogram failed: %s\n", strerror(result)); // alert the kernel menu that the process aborted process_finish(proc, _MKWAIT_SIG(SIGABRT)); return; } enter_new_process(nargs, (userptr_t)stackptr, stackptr, entrypoint); // enter_new_process() does not return panic("enter_new_process returned\n"); }
int main(void) { BYTE flgRestart = FALSE; // if TRUE, restart main loop time_t timenow; // Current time time_t cosmtick; // Time for next upload time_t newvalue; t_UPDATER_MSG updater_msg; // Messsage for updater // Header verbage #ifdef DEBUG_APP printf("\nHomected xAP-Cosm Connector (Updater)\n"); printf("Copyright (C) Jose Luis Galindo, 2012\n"); #endif // Create shared memory areas if (!cosmSharedMemSetup()) { #ifdef DEBUG_APP printf("Error allocating shared resources\n"); #endif logError("main: Error allocating shared resources"); unlink(pid_filepath); exit(EXIT_FAILURE); } // Initialize application purge_update_list(); logInit(LOG_EVENTS_FILE, LOG_ERRORS_FILE); LIBXML_TEST_VERSION // Connect to the message queue to communicate with xap-cosm if ((g_msg_queue = msgget(COSM_MSGQUEUE, 0644)) == -1) { #ifdef DEBUG_APP printf("Error connecting to message queue\n"); #endif logError("main: Error connecting to message queue"); unlink(pid_filepath); exit(EXIT_FAILURE); } // Create the process #ifndef DEBUG_APP process_init("xap-cosm-updater", pid_filepath); #endif while(process_state == PROC_RUNNING) { #ifdef DEBUG_APP printf("Running...\n"); #endif logEvent(TRUE, "updater: Running..."); while (!flgRestart && (process_state == PROC_RUNNING)) { // Wait for application enabled if (!cosmConfig->enabled) { #ifdef DEBUG_APP printf("Device is not enabled, wait\n"); #endif logEvent(TRUE, "main: Device is not enabled, wait"); while(!cosmConfig->enabled) sleep(1); } // Get current time timenow = time((time_t*)0); // Wait for an incomining message if (msgrcv(g_msg_queue, (struct msgbuf *)&updater_msg, sizeof(updater_msg.ds)+sizeof(updater_msg.timestamp)+sizeof(updater_msg.curr_value), COSM_MSGQUEUE_MSG_ID, IPC_NOWAIT) != -1) { // Add message data to update list g_update_list[g_update_list_count].sent = FALSE; g_update_list[g_update_list_count].ds = updater_msg.ds; g_update_list[g_update_list_count].timestamp = updater_msg.timestamp; strcpy(g_update_list[g_update_list_count].curr_value, updater_msg.curr_value); #ifdef DEBUG_APP printf("ds:%d added value %s to Cosm update list queue (pos=%d)\n", g_update_list[g_update_list_count].ds, g_update_list[g_update_list_count].curr_value, g_update_list_count); #endif logEvent(TRUE, "updater: (ds:%d) added value %s to Cosm update list queue (pos=%d)", g_update_list[g_update_list_count].ds, g_update_list[g_update_list_count].curr_value, g_update_list_count); g_update_list_count++; } usleep(10000); //convert to microseconds // Cosm tick if (timenow >= cosmtick) { #ifdef DEBUG_APP printf("Outgoing cosm tick %d\n",(int)timenow); #endif logEvent(TRUE, "updater: Outgoing cosm tick %d",(int)timenow); // Upload update list to cosm send_list_to_cosm(); // Clear update list purge_update_list(); // Set next tick cosmtick = timenow + cosmConfig->updatef; } // Check if has to restart if (cosmConfig->restartFlag) { cosmConfig->restartFlag = FALSE; // Reset flag flgRestart = TRUE; } } // Restore flgRestart flgRestart = FALSE; } // Close shared memory areas cosmSharedMemClose(); // Destroy the process #ifndef DEBUG_APP process_finish(); #endif return 0; }