📄 tftp.c
字号:
util_strcpy(tftp_server_MAC,server_MAC); new_connection = TRUE; block_buff_curr = NULL;}/****************************** Routine: Description: See tftp.h for more info. ******************************/void disconnect_tftp(void){ unsigned short num_bytes; // Let the remote TFTP server know that we've // received and processed the last byte of that // file we've been dragging across. build_tftp_datagram(do_ACK, // in data_gram, // out &num_bytes); // out udp_submit(SEND, // in NORM_TFTP_PORT, // in reply_port, // in tftp_device_IP, // in tftp_server_IP, // in tftp_device_MAC, // in, can be NULL only if our net stack has ARP. tftp_server_MAC, // in, can be NULL only if our net stack has ARP. (void *)data_gram, // in &num_bytes, // in &reply_port); // out}/****************************** Routine: Description: ******************************/static void get_block_buff(tftp_datagram_t *dg, // in unsigned short num_bytes, // in unsigned char **buff_curr, // out unsigned char **buff_end) // out{ unsigned short opcode; unsigned short buff_len; unsigned short block_num; *buff_end = *buff_curr = NULL; if (!dg) return; // sanity check. if (0 == num_bytes) return; // sanity check. // First two bytes are the TFTP opcode. opcode = ntohs(dg->opcode); switch (opcode) { case TFTP_DATA: // --Normal Path-- block_num = ntohs(dg->DATA.block_num); if (block_num == expected_block_num) { expected_block_num++; *buff_curr = (unsigned char *)dg + sizeof(dg->DATA.opcode) + sizeof(dg->DATA.block_num); buff_len = num_bytes - (*buff_curr - (unsigned char *)dg); if (buff_len > 0) { *buff_end = *buff_curr + (buff_len - 1); if (buff_len < 512) { // a tftp block of less than 512 bytes indicates that // these are the last bytes of the file. If last bytes // fall on a 512 boundary then last data message will // have a zero byte data field. Whole_file_xferred = TRUE; } } else { // A zero byte data field indicates whole file already xferred. Whole_file_xferred = TRUE; } } else if (block_num == (expected_block_num-1)) { // A repeated block; duplicate. // util_printf("TFTP_DATA: ignoring duplicate block: %d\n",block_num); } else { SYSTEM_FATAL("TFTP_DATA: Cant handle out-of-order tftp blocks"); } break; case TFTP_RRQ: case TFTP_WRQ: case TFTP_ACK: // Why did we receive this type of // message from the remote TFTP server?? SYSTEM_FATAL("Logic Error"); break; case TFTP_ERROR: SYSTEM_FATAL("Aborting"); break; default: break; }}/****************************** Routine: Description: ******************************/void get_next_tftp_block(void){ unsigned short num_bytes; unsigned short tftp_dest_port; if (TRUE == new_connection) { // flush the net channel of any pending data. Start_Of_Session = TRUE; udp_submit(FLUSH, // in NORM_TFTP_PORT, // in NORM_TFTP_PORT, // in tftp_device_IP, // in tftp_server_IP, // in tftp_device_MAC, // in, can be NULL only if chipset has built in MAC. tftp_server_MAC, // in, can be NULL only if our net stack has ARP. NULL, // n/a NULL, // n/a NULL); // n/a // All new tftp sessions start with this // message to the remote TFTP server. build_tftp_datagram(do_RRQ, // in data_gram, // out &num_bytes); // out tftp_dest_port = NORM_TFTP_PORT; new_connection = FALSE; expected_block_num = 1; Whole_file_xferred = FALSE; } else { // A datagram to tell the remote TFTP server that we're ready // for the next block of bytes from the file we're retrieving. build_tftp_datagram(do_ACK, // in data_gram, // out &num_bytes); // out tftp_dest_port = reply_port; } if (Whole_file_xferred) { // util_printf("tftp: udp_submit-final 0x%X\n",data_gram); // *revisit-skranz* temp. udp_submit(SEND, // in NORM_TFTP_PORT, // in, src port tftp_dest_port, // in, dest port tftp_device_IP, // in tftp_server_IP, // in tftp_device_MAC, // in, can be NULL only if chipset has built in MAC. tftp_server_MAC, // in, can be NULL only if our net stack has ARP. (void *)data_gram, // in &num_bytes, // in &reply_port); // n/a } else { // Next, the data_gram buffer does double duty here. // Once the data_gram contents go out, the buffer contents are then // replaced with the incoming response. The datagram is already // sized to hold the larger of the two as well as providing reserved // space in front of the data_gram which the UDP/IP/Ether levels can // use to add their particular protocol headers. Eventually a // full_ether_frame_t is built up before our outgoing datagram hits // the underlying ether chip set. // util_printf("data_gram = 0x%X\n",data_gram); // *revisit-skranz* temp. // util_printf("tftp: udp_submit 0x%X\n",data_gram); // *revisit-skranz* temp. udp_submit(SEND_AND_GET_REPLY,// in NORM_TFTP_PORT, // in, src port tftp_dest_port, // in, dest port tftp_device_IP, // in tftp_server_IP, // in tftp_device_MAC, // in, can be NULL only if chipset has built in MAC. tftp_server_MAC, // in, can be NULL only if our net stack has ARP. (void *)data_gram, // in/out &num_bytes, // in/out &reply_port); // out. // Okay, we've got a datagram from the remote server and a block // of file bytes is contained within. Get that buffer now. // util_printf("tftp: data_gram = 0x%X\n",data_gram); // *revisit-skranz* temp. get_block_buff(data_gram, // in num_bytes, // in &block_buff_curr, // out &block_buff_end); // out Start_Of_Session = FALSE; } if (!Whole_file_xferred && !block_buff_curr) { // Try again. recursive call. // util_printf("TFTP retry\n"); get_next_tftp_block(); }}/****************************** Routine: Description: See tftp.h for more info. ******************************/unsigned char getchar_tftp(void){ unsigned char ret_val; if (!block_buff_curr) { // The following establishes block_buff_curr and block_buff_end. get_next_tftp_block(); // if there is one.... } if (block_buff_curr) { ret_val = *block_buff_curr; block_buff_curr++; if (block_buff_curr > block_buff_end) { // we've just grabbed the last byte from this particular block // so we will have to send/receive another TFTP datagram for // any future client requests. This continues for as many blocks // as it takes to xfer the whole file. block_buff_curr = NULL; } } else { // No more bytes available. Possibly client has attempted // to read more bytes than existed in the file or possibly // a network error has occured which terminated our xfer // session. ret_val = 0; // Eventually the client will realize that // the data they are getting doesn't make // sense and excercise error paths already // built into upper levels of the system. } return ret_val;}/****************************** Routine: Description: See tftp.h for more info. ******************************/void tftp_init(void){ if (sizeof(full_ether_frame_t) != SIZEFULLFRAME) { util_printf("size of tftp_datagram_t = %d\n",sizeof(tftp_datagram_t)); util_printf("size of udp_hdr_t = %d\n",sizeof(udp_hdr_t)); util_printf("size of ip_hdr_t = %d\n",sizeof(ip_hdr_t)); util_printf("size of ether_hdr_t = %d\n",sizeof(ether_hdr_t)); util_printf("sizefullframe = %d, full_ether_frame = %d\n",SIZEFULLFRAME,sizeof(full_ether_frame)); SYSTEM_FATAL("Bummer, has your compiler padded the full_ether_frame buffer?"); } data_gram = &(full_ether_frame.tftp_data_gram); new_connection = TRUE; block_buff_curr = NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -