// Receive data on the given socket. return_type ipv4_receive(ipc_structure_type *ipv4_structure, ipv4_receive_type *receive, ipv4_socket_id_type socket_id, void **data, unsigned int *length) { message_parameter_type message_parameter; message_parameter.protocol = IPC_PROTOCOL_IPV4; message_parameter.message_class = IPC_IPV4_RECEIVE; message_parameter.data = &socket_id; message_parameter.length = sizeof(ipv4_socket_id_type); message_parameter.block = TRUE; ipc_send(ipv4_structure->output_mailbox_id, &message_parameter); message_parameter.length = *length; message_parameter.data = *data; ipc_receive(ipv4_structure->input_mailbox_id, &message_parameter, length); *data = message_parameter.data; *length = message_parameter.length; message_parameter.data = receive; message_parameter.length = sizeof(ipv4_receive_type); ipc_receive(ipv4_structure->input_mailbox_id, &message_parameter, NULL); return IPV4_RETURN_SUCCESS; }
int main(void) { int i = 0; // ipc_msg_config_t config = (ipc_msg_config_t){.coid = (process_id_t){2}, .flags = WAITING_SEND, .size = sizeof(i)}; _SYSTEM_CALL(4, (void*)"Program 1 calling mmap, trying to remap 0xb00040\r\n", NULL, NULL); void* test = mmap((void*)0xb00040); _SYSTEM_CALL(4, (void*)"Program 1 has called mmap, mapped to: ", NULL, NULL); _SYSTEM_CALL(5, test, NULL, NULL); _SYSTEM_CALL(4, (void*)"\r\n", NULL, NULL); _SYSTEM_CALL(4, (void*)"Calling driver_register\r\n", NULL, NULL); driver_register("test"); _SYSTEM_CALL(4, (void*)"Program 1 has called driver_register\r\n ", NULL, NULL); while(1) { /* _SYSTEM_CALL(4, (void*)"Program 1 sending: ", NULL, NULL); _SYSTEM_CALL(5, (void*)i,NULL, NULL); _SYSTEM_CALL(4, (void*)"\r\n", NULL, NULL); ipc_send( &i, &config); if(config.flags & COID_NOT_FOUND){ _SYSTEM_CALL(4, (void*)"Program 1 send: COID_NOT_FOUND\r\n", NULL, NULL); } _SYSTEM_CALL(4, (void*)"Program 1 sending complete\r\n", NULL, NULL); i++; */ int flags = 0; _SYSTEM_CALL(4, (void*)"Calling receive\r\n", NULL, NULL); process_id_t sender = ipc_receive( NULL, 0, &flags); _SYSTEM_CALL(4, (void*)"got msg from: ", NULL, NULL); _SYSTEM_CALL(5, (void*)sender.id_number, NULL, NULL); } return 0; }
int main() { struct ipc_message m; struct calc_msg cm; while(ipc_receive(IPC_ANY,&m)==IPC_SUCCESS) { //mem_copy((addr_t)m.data,(addr_t)&cm,sizeof(struct calc_msg)); switch(cm.op_code) { case 1: cm.op_res = cm.op_1 + cm.op_2; break; case 2: cm.op_res = cm.op_1 * cm.op_2; break; default: cm.op_res = 0; } //mem_copy((addr_t)&cm,(addr_t)m.data,sizeof(struct calc_msg)); ipc_notify(m.from); ipc_send(m.from,&m); } //while(1){} return 0; }
int main(void) { char * read_string; int aux_size; pthread_t thread_id, receive_thread_id; thread_status_t thread_info; signal(SIGINT, server_close); init_processes(TRUE); init(); client_header_t header = calloc(1, sizeof(struct client_header)); pthread_create(&receive_thread_id, NULL, &run_server_receive, NULL); printf("Running server...\n"); while(1) { server_params->msg_type = PRE_HEADER; if(ipc_receive(server_params, header, sizeof (struct client_header)) > 0) { read_string = calloc(1, header->program_size); server_params->msg_type = PROGRAM_STRING; while(ipc_receive(server_params, read_string, header->program_size) == 0) sleep(1); printf("Received program from client: %d, program name: %s\n", header->client_id, read_string); thread_info = calloc(1, sizeof(struct thread_status)); thread_info->file = read_string; thread_info->client_id = header->client_id; pthread_create(&thread_id, NULL, &run_program, thread_info); pthread_join(thread_id, NULL); free(read_string); free(thread_info); } sleep(1); } return 0; }
int main(void) { status c_program; init_processes(); ipc_open(endif_process->params, O_RDONLY); while(1) if (ipc_receive(endif_process->params, &c_program, sizeof(struct status)) > 0) run_process(&c_program, &execute_endif); return 0; }
static int process_until_go(struct migensim_softc *sc) { int r; sc->has_go = 0; while(!sc->has_go) { r = ipc_receive(sc->ipc); if(r != 1) return r; } return 1; }
int main(void) { char * read_string; int aux_size; pthread_t thread_id; thread_status_t thread_info; init_processes(); init(); client_header_t header = calloc(1, sizeof(struct client_header)); printf("Running server...\n"); while(1) { server_params->msg_type = PRE_HEADER; if(ipc_receive(server_params, header, sizeof (struct client_header)) > 0) { read_string = calloc(1, header->program_size); printf("%d %d\n", header->client_id, header->program_size); server_params->msg_type = PROGRAM_STRING; while(ipc_receive(server_params, read_string, header->program_size) == 0) sleep(1); printf("Recibi programa del cliente: %d, programa: %s\n", header->client_id, read_string); thread_info = calloc(1, sizeof(struct thread_status)); thread_info->file = read_string; thread_info->client_id = header->client_id; pthread_create(&thread_id, NULL, &run_program, thread_info); } } return 0; }
int main(void) { status c_program; init_processes(FALSE); signal(SIGINT, end_process); ipc_open(if_process->params, O_RDONLY); while(1) if (ipc_receive(if_process->params, &c_program, sizeof(struct status)) > 0) run_process(&c_program, &execute_if); return 0; }
// Get the host name of the system. return_type ipv4_host_name_get(ipc_structure_type *ipv4_structure, char *host_name) { message_parameter_type message_parameter; message_parameter.protocol = IPC_PROTOCOL_IPV4; message_parameter.message_class = IPC_IPV4_GET_HOST_NAME; message_parameter.data = host_name; message_parameter.length = 0; ipc_send(ipv4_structure->output_mailbox_id, &message_parameter); message_parameter.length = IPV4_HOST_NAME_LENGTH; ipc_receive(ipv4_structure->input_mailbox_id, &message_parameter, NULL); return IPV4_RETURN_SUCCESS; }
// Get flags. return_type ipv4_get_flags(ipc_structure_type *ipv4_structure, unsigned int *flags) { message_parameter_type message_parameter; message_parameter.protocol = IPC_PROTOCOL_IPV4; message_parameter.message_class = IPC_IPV4_GET_FLAGS; message_parameter.data = flags; message_parameter.length = 0; message_parameter.block = TRUE; ipc_send(ipv4_structure->output_mailbox_id, &message_parameter); message_parameter.length = sizeof(unsigned int); ipc_receive(ipv4_structure->input_mailbox_id, &message_parameter, NULL); return IPV4_RETURN_SUCCESS; }
int main(int argc, char ** argv){ char * program_name; struct status cl_program; int i; ipc_params_t client_params; init_processes(); if(argc > 1){ program_name = argv[1]; }else{ printf("Entrada incorrecta\n"); return 0; } client_params = get_params_from_pid(getpid(), PROGRAM_STATUS, sizeof(struct status)); client_header_t header = calloc(1, sizeof(struct client_header)); header->program_size = strlen(program_name); header->client_id = getpid(); ipc_open(server_params, O_WRONLY); server_params->msg_type = PRE_HEADER; ipc_send(server_params, header, sizeof(struct client_header)); server_params->msg_type = PROGRAM_STRING; ipc_send(server_params, program_name, header->program_size); ipc_close(server_params); ipc_create(client_params); ipc_open(client_params, O_RDONLY); while (!ipc_receive(client_params, &cl_program, sizeof(struct status))); ipc_close(client_params); ipc_destroy(client_params); for (i = 0; i < MEM_SIZE; i++){ printf("%d ", cl_program.mem[i]); } printf("\n"); return 0; }
// Connect to a remote host (in the case of TCP), or just bind the port (in the case of UDP). return_type ipv4_connect(ipc_structure_type *ipv4_structure, ipv4_connect_type *connect, ipv4_socket_id_type *socket_id) { message_parameter_type message_parameter; message_parameter.protocol = IPC_PROTOCOL_IPV4; message_parameter.message_class = IPC_IPV4_CONNECT; message_parameter.data = connect; message_parameter.length = sizeof(ipv4_connect_type); message_parameter.block = TRUE; ipc_send(ipv4_structure->output_mailbox_id, &message_parameter); message_parameter.data = socket_id; message_parameter.length = sizeof(ipv4_socket_id_type); message_parameter.block = TRUE; ipc_receive(ipv4_structure->input_mailbox_id, &message_parameter, NULL); return IPV4_RETURN_SUCCESS; }
void * run_program(void * program_stat) { ipc_params_t client_params; stack_t c_stack; graph_t c_graph; int memkey, i; status client_program; process_t process_type; thread_status_t thread_info = (thread_status_t)program_stat; c_stack = parse_file((char*)thread_info->file); c_graph = build_graph(c_stack); if (c_graph != NULL) { create_sh_graph(c_graph, get_graph_size(c_graph), &memkey, &client_program.g_header); client_program.cursor = 0; client_program.flag = FALSE; for(i = 0; i < MEM_SIZE; i++) { client_program.mem[i] = 0; } process_type = c_graph->first->instruction_process->instruction_type; client_program.mtype = process_type->params->unique_mq_id; ipc_send(process_type->params, &client_program, sizeof(struct status)); } else { printf("Entrada incorrecta\n"); } while(!ipc_receive(server_receive_params, &client_program, sizeof(struct status))) sleep(1); client_params = get_params_from_pid(thread_info->client_id, PROGRAM_STATUS, sizeof(struct status)); ipc_open(client_params, O_WRONLY); ipc_send(client_params, &client_program, sizeof(struct status)); ipc_close(client_params); }
void * run_server_receive(void * params){ ipc_params_t client_params; status client_final; ipc_create(server_receive_params); ipc_open(server_receive_params, O_RDONLY|O_NONBLOCK); while(1){ if(ipc_receive(server_receive_params, &client_final, sizeof(struct status))){ client_params = get_params_from_pid(client_final.client_id, PROGRAM_STATUS, sizeof(struct status), server_params->semid); client_params->socklistener = TRUE; printf("Answering to client: %d\n", client_final.client_id); ipc_open(client_params, O_WRONLY); ipc_send(client_params, &client_final, sizeof(struct status)); ipc_close(client_params); free(client_params->file); free(client_params); } sleep(1); } }
int main() { int a; handle = crt_open(); crt_printf(handle,"Creating port %d\n",P); if (ipc_create_port(P) != IPC_OK) { crt_printf(handle,"Error creating port!\n"); return 0; } crt_printf(handle,"Port Created\n"); while (1) { crt_printf(handle,"Starting to Receive\n"); if (ipc_receive(P,x,M_SIZE) != IPC_OK) { crt_printf(handle,"ipc_receive didnt return OK!\n"); return 0; } crt_printf(handle,"Got send, Verifying x[] with f1\n"); if (!verify(x,f1)) { crt_printf(handle,"ERROR!! Didnt get correct answer!\n"); return 0; } crt_printf(handle,"Verify good.\nReplying\n"); if (ipc_reply(P,&a,sizeof(int)) != IPC_OK) { crt_printf(handle,"ipc_reply didnt return OK!\n"); return 0; } crt_printf(handle,"Done reply\n\n"); } crt_printf(handle,"Closing port %d\n",P); ipc_close_port(P); crt_printf(handle,"Port closed\nTerminating\n"); return 0; }
// Handle the connection to the console service. static void handle_connection(ipc_structure_type *ipc_structure) { bool done = FALSE; uint32_t *data; unsigned int data_size = 8192; memory_allocate((void **) &data, data_size); // Accept the connection. message_parameter_type message_parameter; message_parameter.data = data; message_parameter.block = TRUE; message_parameter.protocol = IPC_PROTOCOL_VIDEO; while (!done) { message_parameter.message_class = IPC_CLASS_NONE; message_parameter.length = data_size; if (ipc_receive(ipc_structure->input_mailbox_id, &message_parameter, &data_size) != STORM_RETURN_SUCCESS) { continue; } switch (message_parameter.message_class) { // Place the text mode cursor. case IPC_VIDEO_CURSOR_PLACE: { video_cursor_type *cursor = (video_cursor_type *) message_parameter.data; vga_cursor_place(cursor->x, cursor->y); break; } // Set the font. case IPC_VIDEO_FONT_SET: { // FIXME: Do security checks here. vga_font_set((uint8_t *) data, message_parameter.length); break; } // Set a video mode. case IPC_VIDEO_MODE_SET: { video_mode_type *video_mode = (video_mode_type *) message_parameter.data; return_type *return_value = (return_type *) message_parameter.data; if (video_mode != NULL) { message_parameter.length = sizeof (return_type); if (mode_set(video_mode->width, video_mode->height, video_mode->depth, video_mode->mode_type)) { if (video_mode->mode_type == VIDEO_MODE_TYPE_TEXT) { for (int index = 0; index < 16; index++) { vga_palette_set_entry(index, &text_palette[index]); } vga_font_set(font_8x8, sizeof(font_8x8)); } else if (video_mode->mode_type == VIDEO_MODE_TYPE_GRAPHIC && video_mode->depth == 8) { for (int index = 0; index < 256; index++) { vga_palette_entry_type entry; entry.red = ((index & 0xE0) >> 5) << 3; entry.green = ((index & 0x1C) >> 2) << 3; entry.blue = ((index & 0x03) >> 0) << 4; vga_palette_set_entry(index, &entry); } } *return_value = IPC_VIDEO_RETURN_SUCCESS; } else { *return_value = IPC_VIDEO_RETURN_MODE_UNAVAILABLE; } } else { *return_value = IPC_VIDEO_RETURN_MODE_UNAVAILABLE; } ipc_send(ipc_structure->output_mailbox_id, &message_parameter); break; }
void handle_connection(mailbox_id_type *reply_mailbox_id) { system_thread_name_set("Handling connection"); message_parameter_type message_parameter; bool done = FALSE; bool mounted = FALSE; fat_info_type fat_info; ipc_structure_type ipc_structure; uint8_t *data; uint8_t **data_pointer = &data; unsigned int data_size = 16384; memory_allocate((void **) data_pointer, data_size); // Accept the connection. ipc_structure.output_mailbox_id = *reply_mailbox_id; if (ipc_connection_establish(&ipc_structure) != IPC_RETURN_SUCCESS) { return; } message_parameter.block = TRUE; while (!done) { message_parameter.data = data; message_parameter.protocol = IPC_PROTOCOL_FILE; message_parameter.message_class = IPC_CLASS_NONE; message_parameter.length = data_size; if (ipc_receive(ipc_structure.input_mailbox_id, &message_parameter, &data_size) != IPC_RETURN_SUCCESS) { continue; } switch (message_parameter.message_class) { // Read one or more directory entries. case IPC_FILE_DIRECTORY_ENTRY_READ: { if (mounted) { file_directory_entry_read_type *directory_entry_read = (file_directory_entry_read_type *) data; if (!fat_directory_entry_read(directory_entry_read, &fat_info)) { directory_entry_read->entries = 0; } message_parameter.length = sizeof(file_directory_entry_read_type) + sizeof(file_directory_entry_type) * directory_entry_read->entries ; // log_print_formatted (0, PACKAGE, "Successfully read %u entries", // directory_entry_read->entries); // log_print_formatted (0, PACKAGE, "max: %u\n", directory_entry_read->entries); ipc_send(ipc_structure.output_mailbox_id, &message_parameter); } break; } case IPC_FILE_GET_INFO: { if (mounted) { file_verbose_directory_entry_type *directory_entry = (file_verbose_directory_entry_type *) data; if (!fat_file_get_info(&fat_info, directory_entry)) { return_type return_value = FILE_RETURN_FILE_ABSENT; log_print_formatted(&log_structure, LOG_URGENCY_ERROR, "IPC_FILE_GET_INFO failed"); message_parameter.message_class = IPC_FILE_RETURN_VALUE; message_parameter.data = &return_value; message_parameter.length = sizeof(return_type); } ipc_send(ipc_structure.output_mailbox_id, &message_parameter); } break; } case IPC_FILE_MOUNT_VOLUME: { mailbox_id_type *mailbox = (mailbox_id_type *) data; fat_info.block_structure.output_mailbox_id = *mailbox; if (ipc_service_connection_request(&fat_info.block_structure) != IPC_RETURN_SUCCESS) { break; } // Check if we have a FAT file system at this location. if (!detect_fat(&fat_info)) { log_print(&log_structure, LOG_URGENCY_ERROR, "No FAT filesystem detected."); break; } mounted = TRUE; break; } case IPC_FILE_OPEN: { ipc_file_open_type *open = (ipc_file_open_type *) data; if (!fat_file_open(&fat_info, open)) { log_print(&log_structure, LOG_URGENCY_ERROR, "Failed to open file."); } ipc_send(ipc_structure.output_mailbox_id, &message_parameter); break; } case IPC_FILE_READ: { file_read_type *read = (file_read_type *) data; uint8_t *read_buffer; uint8_t **read_buffer_pointer = &read_buffer; memory_allocate((void **) read_buffer_pointer, read->bytes); if (!fat_file_read(&fat_info, read->file_handle, read_buffer, read->bytes)) { log_print(&log_structure, LOG_URGENCY_ERROR, "Failed to read from file."); } message_parameter.data = read_buffer; message_parameter.length = read->bytes; #ifdef DEBUG log_print_formatted(&log_structure, LOG_URGENCY_DEBUG, "Sending %lu", read->bytes); #endif ipc_send(ipc_structure.output_mailbox_id, &message_parameter); memory_deallocate((void **) read_buffer_pointer); break; } // Unsupported functions. case IPC_FILE_CLOSE: case IPC_FILE_SEEK: case IPC_FILE_WRITE: case IPC_FILE_ACL_READ: case IPC_FILE_ACL_WRITE: case IPC_FILE_UNMOUNT_VOLUME: default: { return_type return_value = IPC_RETURN_FILE_FUNCTION_UNSUPPORTED; message_parameter.data = &return_value; message_parameter.length = sizeof(return_type); ipc_send(ipc_structure.output_mailbox_id, &message_parameter); break; } } } }
static void hard_drive_handle_connection (ata_drive_type *ata_drive, mailbox_id_type reply_mailbox_id) { message_parameter_type message_parameter; ipc_structure_type ipc_structure; bool done = FALSE; u32 *data; unsigned int data_size = 1024; memory_allocate ((void **) &data, data_size); /* Accept the connection. */ ipc_structure.output_mailbox_id = reply_mailbox_id; ipc_connection_establish (&ipc_structure); message_parameter.block = TRUE; while (!done) { message_parameter.protocol = IPC_PROTOCOL_BLOCK; message_parameter.message_class = IPC_CLASS_NONE; message_parameter.length = data_size; message_parameter.data = data; if (ipc_receive (ipc_structure.input_mailbox_id, &message_parameter, &data_size) != IPC_RETURN_SUCCESS) { continue; } switch (message_parameter.message_class) { case IPC_BLOCK_READ: { ipc_block_read_type *ipc_block_read = (ipc_block_read_type *) data; /* FIXME: Do some boundary checking. */ #ifdef DEBUG log_print_formatted (&log_structure, LOG_URGENCY_DEBUG, "Reading blocks %u-%u data.", ipc_block_read->start_block_number, ipc_block_read->start_block_number + ipc_block_read->number_of_blocks); #endif ata_read_block (ata_drive, ipc_block_read->start_block_number, message_parameter.data, ipc_block_read->number_of_blocks); message_parameter.length = ipc_block_read->number_of_blocks; message_parameter.block = TRUE; ipc_send (ipc_structure.output_mailbox_id, &message_parameter); break; } case IPC_BLOCK_WRITE: { break; } case IPC_BLOCK_GET_INFO: { break; } } } }
static void handle_connection (ipc_structure_type *ipc_structure) { message_parameter_type message_parameter; bool done = FALSE; uint8_t *data; unsigned int data_size = 16384; file_mount_type mount = { "servicefs" }; memory_allocate ((void **) &data, data_size); /* Mount ourselves. */ message_parameter.block = TRUE; message_parameter.data = &mount; message_parameter.protocol = IPC_PROTOCOL_FILE; message_parameter.message_class = IPC_FILE_MOUNT_VOLUME; message_parameter.length = sizeof (file_mount_type); ipc_send (ipc_structure->output_mailbox_id, &message_parameter); message_parameter.block = TRUE; while (!done) { message_parameter.data = data; message_parameter.protocol = IPC_PROTOCOL_FILE; message_parameter.message_class = IPC_CLASS_NONE; message_parameter.length = data_size; if (ipc_receive (ipc_structure->input_mailbox_id, &message_parameter, &data_size) != IPC_RETURN_SUCCESS) { continue; } switch (message_parameter.message_class) { /* Read one or more directory entries. */ case IPC_FILE_DIRECTORY_ENTRY_READ: { file_directory_entry_read_type *directory_entry_read = (file_directory_entry_read_type *) data; service_protocol_type *protocol_info; unsigned int protocols = 50; unsigned int output_index = 0; unsigned int max_entries = directory_entry_read->entries; unsigned int input_index; char *path[10]; unsigned int elements = 10; path_split (directory_entry_read->path_name, path, &elements); log_print_formatted (&log_structure, LOG_URGENCY_DEBUG, "%u", elements); /* TODO: Do something more with the path array here. */ directory_entry_read->entries = 0; memory_allocate ((void **) &protocol_info, protocols * sizeof (service_protocol_type)); system_call_service_protocol_get (&protocols, protocol_info); for (input_index = directory_entry_read->start_entry; input_index < (directory_entry_read->start_entry + max_entries) && input_index < protocols; input_index++) { string_copy (directory_entry_read->entry[output_index].name, protocol_info[input_index].name); directory_entry_read->entry[output_index].type = FILE_ENTRY_TYPE_DIRECTORY; directory_entry_read->entries++; output_index++; } if (input_index == protocols) { directory_entry_read->end_reached = TRUE; } else { directory_entry_read->end_reached = FALSE; } message_parameter.length = (sizeof (file_directory_entry_read_type) + sizeof (file_directory_entry_type) * directory_entry_read->entries); ipc_send (ipc_structure->output_mailbox_id, &message_parameter); break; } /* Get verbose information about the given file entry. */ case IPC_FILE_GET_INFO: { file_verbose_directory_entry_type *verbose_directory_entry = (file_verbose_directory_entry_type *) data; unsigned int protocols = 50; unsigned int index; service_protocol_type *protocol_info; memory_allocate ((void **) &protocol_info, protocols * sizeof (service_protocol_type)); system_call_service_protocol_get (&protocols, protocol_info); verbose_directory_entry->success = FALSE; for (index = 0; index < protocols; index++) { if (string_length (verbose_directory_entry->path_name) > 1 && string_compare (protocol_info[index].name, verbose_directory_entry->path_name + 1) == 0) { verbose_directory_entry->success = TRUE; verbose_directory_entry->type = FILE_ENTRY_TYPE_DIRECTORY; verbose_directory_entry->time = time_get (); verbose_directory_entry->size = protocol_info[index].number_of_services; break; } } message_parameter.length = sizeof (file_verbose_directory_entry_type); ipc_send (ipc_structure->output_mailbox_id, &message_parameter); break; } /* Unsupported functions. */ case IPC_FILE_OPEN: /* FIXME: For READ, we first create a buffer, fills it with the content of the 'file' and then pass the requested part of the file to the caller. */ case IPC_FILE_READ: case IPC_FILE_CLOSE: case IPC_FILE_SEEK: case IPC_FILE_WRITE: case IPC_FILE_ACL_READ: case IPC_FILE_ACL_WRITE: case IPC_FILE_MOUNT_VOLUME: case IPC_FILE_UNMOUNT_VOLUME: default: { return_type return_value = IPC_RETURN_FILE_FUNCTION_UNSUPPORTED; message_parameter.data = &return_value; message_parameter.length = sizeof (return_type); ipc_send (ipc_structure->output_mailbox_id, &message_parameter); break; } } } }
static void handle_connection (mailbox_id_type reply_mailbox_id, realtek_device_type *device) { message_parameter_type message_parameter; ipc_structure_type ipc_structure; bool done = FALSE; unsigned int data_size = 1024; u32 *data; memory_allocate ((void **) &data, data_size); /* Accept the connection. */ ipc_structure.output_mailbox_id = reply_mailbox_id; ipc_connection_establish (&ipc_structure); message_parameter.data = data; message_parameter.block = TRUE; message_parameter.protocol = IPC_PROTOCOL_ETHERNET; while (!done) { message_parameter.message_class = IPC_CLASS_NONE; message_parameter.length = data_size; if (ipc_receive (ipc_structure.input_mailbox_id, &message_parameter, &data_size) != STORM_RETURN_SUCCESS) { continue; } switch (message_parameter.message_class) { case IPC_ETHERNET_REGISTER_TARGET: { /* FIXME: Check if the protocol is already registered */ device->target[device->number_of_targets].mailbox_id = ipc_structure.output_mailbox_id; device->target[device->number_of_targets].protocol_type = system_byte_swap_u16 (data[0]); device->number_of_targets++; break; } case IPC_ETHERNET_PACKET_SEND: { if (!realtek_start_transmit ((u8 *) data, message_parameter.length, device)) { log_print (&log_structure, LOG_URGENCY_ERROR, "Failed to send an ethernet packet."); /* FIXME: Do something. */ } break; } case IPC_ETHERNET_ADDRESS_GET: { memory_copy (data, &device->ethernet_address, 6); message_parameter.length = 6; system_call_mailbox_send (ipc_structure.output_mailbox_id, &message_parameter); break; } default: { log_print (&log_structure, LOG_URGENCY_ERROR, "Unknown IPC command received."); break; } } } }
/** * main - Main program * * Parses command line options and enters either daemon or client mode. * * In daemon mode, acquires multicast routing sockets, opens IPC socket * and goes in receive-execute command loop. * * In client mode, creates commands from command line and sends them to * the daemon. */ int main(int argc, const char *argv[]) { int i, num_opts, result = 0; int start_daemon = 0; int background = 1; uint8 buf[MX_CMDPKT_SZ]; const char *arg; unsigned int cmdnum = 0; struct cmd *cmdv[16]; /* init syslog */ openlog(__progname, LOG_PID, LOG_DAEMON); if (argc <= 1) return usage(); /* Parse command line options */ for (num_opts = 1; (num_opts = num_option_arguments(argv += num_opts));) { if (num_opts < 0) /* error */ return usage(); /* handle option */ arg = argv[0]; switch (arg[1]) { case 'a': /* add route */ if (num_opts < 5) return usage(); break; case 'r': /* remove route */ if (num_opts < 4) return usage(); break; case 'j': /* join */ case 'l': /* leave */ if (num_opts != 3) return usage(); break; case 'k': /* kill daemon */ if (num_opts != 1) return usage(); break; case 'h': /* help */ return usage(); case 'v': /* verbose */ fputs(version_info, stderr); log_stderr = LOG_DEBUG; continue; case 'd': /* daemon */ start_daemon = 1; continue; case 'n': /* run daemon in foreground, i.e., do not fork */ background = 0; continue; case 'f': if (num_opts != 2) return usage(); conf_file = argv[1]; continue; case 'D': do_debug_logging = 1; continue; default: /* unknown option */ return usage(); } /* Check and build command argument list. */ if (cmdnum >= ARRAY_ELEMENTS(cmdv)) { fprintf(stderr, "Too many command options\n"); return usage(); } cmdv[cmdnum] = cmd_build(arg[1], argv + 1, num_opts - 1); if (!cmdv[cmdnum]) { perror("Failed parsing command"); for (i = 0; i < cmdnum; i++) free(cmdv[i]); return 1; } cmdnum++; } if (start_daemon) { /* only daemon parent enters */ if (geteuid() != 0) { smclog(LOG_ERR, 0, "Need root privileges to start %s", __progname); return 1; } start_server(background); if (!background) return 0; } /* Client or daemon parent only, the daemon never reaches this point */ /* send commands */ if (cmdnum) { int retry_count = 30; openlog(argv[0], LOG_PID, LOG_USER); /* connect to daemon */ while (ipc_client_init()) { switch (errno) { case EACCES: smclog(LOG_ERR, EACCES, "Need root privileges to connect to daemon"); break; case ENOENT: case ECONNREFUSED: /* When starting daemon, give it 30 times a 1/10 second to get ready */ if (start_daemon && --retry_count) { usleep(100000); continue; } smclog(LOG_WARNING, errno, "Daemon not running"); result = 1; break; default: smclog(LOG_WARNING, errno, "Failed connecting to daemon"); result = 1; break; } } for (i = 0; !result && i < cmdnum; i++) { int slen, rlen; struct cmd *command = cmdv[i]; /* Send command */ slen = ipc_send(command, command->len); /* Wait here for reply */ rlen = ipc_receive(buf, sizeof(buf)); if (slen < 0 || rlen < 0) { smclog(LOG_WARNING, errno, "Communication with daemon failed"); result = 1; } if (rlen != 1 || *buf != '\0') { fprintf(stderr, "Daemon error: %s\n", buf); result = 1; } } for (i = 0; i < cmdnum; i++) free(cmdv[i]); } return result; }