/* Send a message through network. The caller must make sure that the message * can be injected in the network, with a previous call to 'net_can_send'. * When the message reaches the head of the input buffer in 'dst_node', event * 'receive_event' will be scheduled, and object 'msg' will be accessible. The * message needs to be removed by the caller with an additional call to * 'net_receive', which will invalidate and free the 'msg' object. */ struct net_msg_t *net_send_ev(struct net_t *net, struct net_node_t *src_node, struct net_node_t *dst_node, int size, int receive_event, void *receive_stack) { struct net_stack_t *stack; struct net_msg_t *msg; /* Check nodes */ if (src_node->kind != net_node_end || dst_node->kind != net_node_end) fatal("%s: not end nodes.\n%s", __FUNCTION__, net_err_end_nodes); /* Create message */ msg = net_msg_create(net, src_node, dst_node, size); /* Insert message into hash table of in-flight messages */ net_msg_table_insert(net, msg); /* Start event-driven simulation */ stack = net_stack_create(net, ESIM_EV_NONE, NULL); stack->msg = msg; stack->ret_event = receive_event; stack->ret_stack = receive_stack; esim_execute_event(EV_NET_SEND, stack); /* Return created message */ return msg; }
int dispatcher_active_io (buffer_state_t * read_buffer_state, buffer_state_t * write_buffer_state, void ** state) { dispatcher_state_t * dispatcher_state = *(dispatcher_state_t **)state; int rc = 0; net_msg_t * recv_msg = NULL; /* Dispatcher connection state initialization */ if (dispatcher_state == NULL) { scar_log (1, "%s: Error: the dispatcher_state object was not yet created!\n", __func__); rc = NET_RC_DISCONNECT; goto finalize_message_handling; } #ifdef DEBUG scar_log (3, " << %s\n", read_buffer_state -> buffer); #endif /* Handle PASS message */ /* if ((rc = handle_ftp_PASS (ftp_state, read_buffer_state, write_buffer_state)) != NET_RC_UNHANDLED) */ /* goto finalize_message_handling; */ /* Push message to the inbox_q */ if (read_buffer_state && (read_buffer_state -> num_bytes > 0)) { recv_msg = net_msg_create (NULL, read_buffer_state -> num_bytes); if (!recv_msg) { scar_log (1, "%s: Error: Couldn't create a net_message object. Out of memory\n", __func__); rc = NET_RC_DISCONNECT; goto finalize_message_handling; } /* Returning 0 is ok, 1 is not ok */ copy_buffer_to_buffer (read_buffer_state, recv_msg -> msg); } finalize_message_handling: #ifdef DEBUG scar_log (3, " >> %s\n", write_buffer_state -> buffer); #endif *state = (void *) dispatcher_state; return rc; }
int handle_ftp_LIST (ftp_state_t * ftp_state, buffer_state_t * read_buffer_state, buffer_state_t * write_buffer_state) { const char * cmd_trigger = "LIST"; unsigned char * bufp = &(read_buffer_state -> buffer)[read_buffer_state -> bytes_commited]; char * output = NULL; /* char * listed_info = NULL; */ net_msg_t * msg = NULL; if (strncasecmp ((char *) bufp, cmd_trigger, strlen (cmd_trigger)) != 0) { /* No match */ return NET_RC_UNHANDLED; } else { /* Handle stat */ if (!ftp_state) { write_buffer_state -> num_bytes = snprintf ((char *) write_buffer_state -> buffer, write_buffer_state -> buffer_size, "500 Unrecoverable error!\r\n"); } /* listed_info = malloc (sizeof (unsigned char) * PATH_MAX); */ /* Building a dynamic format string, based on the PATH_MAX information */ if (strncmp ((char *) read_buffer_state -> buffer, cmd_trigger, strlen(cmd_trigger) != 0)) { return NET_RC_UNHANDLED; } else { /* Fetch output based on path */ if (ftp_state -> vfs_cwd == NULL) ftp_state -> vfs_cwd = ftp_state -> vfs_root; if ((output = VFS_list_by_full_path (ftp_state -> vfs_cwd))) { /* Open data port to send bytes */ /* Start Data thread */ msg = net_msg_create (ftp_state -> mailbox_handle, strlen (output)); if (!msg) { write_buffer_state -> num_bytes = snprintf ((char *) write_buffer_state -> buffer, write_buffer_state -> buffer_size, "550 Directory is empty.\r\n"); } else { /* Pushing message to the outbox */ net_msg_set_dst_id (msg, CAT_FTP_MOVERS); net_msg_push_to_outbox (ftp_state -> mailbox_handle, msg); /* HACK */ /* msg -> msg -> num_bytes = snprintf ((char *) msg -> msg -> buffer, msg -> msg -> buffer_size, "226 transfer finished.\r\n"); */ } /* Must free output */ free(output); write_buffer_state -> num_bytes = snprintf ((char *) write_buffer_state -> buffer, write_buffer_state -> buffer_size, "150 Opening ASCII mode data connection for /bin/ls\r\n"); if (write_buffer_state -> num_bytes >= write_buffer_state -> buffer_size) { /* Buffer overrun */ return NET_RC_DISCONNECT; } else { return NET_RC_MUST_WRITE; } } else { write_buffer_state -> num_bytes = snprintf ((char *) write_buffer_state -> buffer, write_buffer_state -> buffer_size, "550 Directory is empty.\r\n"); } } /* Move commited bytes to next command in the buffer (if there) */ move_bytes_commited_to_next_command (read_buffer_state); if (write_buffer_state -> num_bytes >= write_buffer_state -> buffer_size) { /* Buffer overrun */ return NET_RC_DISCONNECT; } else { return NET_RC_MUST_WRITE; } } }
int handle_ftp_PORT (ftp_state_t * ftp_state, buffer_state_t * read_buffer_state, buffer_state_t * write_buffer_state) { const char * cmd_trigger = "PORT"; unsigned char * short_host_port = NULL; unsigned char * bufp = &(read_buffer_state -> buffer)[read_buffer_state -> bytes_commited]; char * host = NULL; unsigned short port = 0; net_msg_t * msg = NULL; if (strncasecmp ((char *) bufp, cmd_trigger, strlen (cmd_trigger)) != 0) { /* No match */ return NET_RC_UNHANDLED; } else { short_host_port = malloc (sizeof (char) * 256); if (sscanf ((char *) bufp, "PORT %255s*s", short_host_port) <= 0) { /* No match */ free(short_host_port); return NET_RC_UNHANDLED; } else { /* Move commited bytes to next command in the buffer (if there) */ move_bytes_commited_to_next_command (read_buffer_state); PORT_to_host_port (short_host_port, &host, &port); if (host != NULL) { scar_log (5, "%s: Got PORT information: %s:%d\n", __func__, host, port); /* Make Outbox message for a Data-Mover or VFS query */ msg = net_msg_create (ftp_state -> mailbox_handle, 100); if (!msg) { write_buffer_state -> num_bytes = snprintf ((char *) write_buffer_state -> buffer, write_buffer_state -> buffer_size, "500 PORT Failed due to other stuff\r\n"); } else { /* Fire off a connection back to the Client on the given host and port info */ /* s = firstTCPSocketConnectingCorrectly (host, port); */ /* Write message to open a port to the client - Active FTP */ msg -> msg -> num_bytes = snprintf ((char *) msg -> msg -> buffer, msg -> msg -> buffer_size, "PORT %s:%d\r\n", host, port); /* Set undefined category, as you don't know what command will follow */ net_msg_set_category_id (msg, CAT_UNDEFINED); /* Directly respond to the client with an OK */ write_buffer_state -> num_bytes = snprintf ((char *) write_buffer_state -> buffer, write_buffer_state -> buffer_size, "200 PORT Command succesful\r\n"); } } else { scar_log (2, "%s: Parse error in PORT information.\n", __func__); write_buffer_state -> num_bytes = snprintf ((char *) write_buffer_state -> buffer, write_buffer_state -> buffer_size, "501 Error in IP Address or Port number in PORT message\r\n"); } /* parse_short_host_port (short_host_port, &ft); */ if (write_buffer_state -> num_bytes >= write_buffer_state -> buffer_size) { /* Buffer overrun */ free(short_host_port); return NET_RC_DISCONNECT; } else { free(short_host_port); return NET_RC_MUST_WRITE; } } } }