📄 tftp.c
字号:
#include "_stdio.h"#include "env.h"#include "tinyip.h"#include "support.h"#include "flashop.h"#include "srloader.h"#include "shell.h"#include "revision.h"#include "tftp.h"#include "hw.h"#include "main.h" //Addition by Charles for check code pattern promet 04-30-2004// by Oleg commented #include <code_pattern.h>#define DEBUG_TFTP 0#ifdef TFTP_SERVER_SUPPORT#define BOOT_SECTOR 0x01 #define CODE_SECTOR 0x02int tftp_update = 0;static int update_flag = 0;static int update_type = 0;static int tftp_block = 0;static longword rcv_ipaddress;static char ackbuf[256];static bit32 tftp_flashAddress;static bit32u tftp_flashOffset = 0;static bit32 tftp_endAddress;static int tftp_dlen = 0;static bit32u tftp_ramAddress = 0;static bit32 tftp_ramLen = 0;static bit32u tftp_ramBaseAddr;#ifdef DEBUG_TFTPstatic int total_len = 0;#endif//By Charles addition for Used Golbal Variable Check Code Pattern 05-04-2004#if defined (CHECK_GOLBAL) extern char *cCheckPatternStr;#endif /* CHECK_GOLBAL Endif*/int Delay(int x){ int sum = 0x10000; int j = 0; int i = 0; for (i = 0; i < x; i++) for (j = 0; j < sum; j++); return 0;}int tftp_flashStore(byte *dp, int len){ if ((tftp_dlen == 0) && (dp)) { if (FWBValid((bit32u)tftp_flashAddress) == 0) { return FALSE; } if (FWBOpen((bit32u)tftp_flashAddress) == 0) { return FALSE; } tftp_flashAddress += tftp_flashOffset; sys_printf("\n"); } if ((tftp_flashAddress + len) > tftp_endAddress) return FALSE; if ((dp) && (len)) { //ramStore(dp, len); WriteToFlash((UINT8 *)tftp_flashAddress, (UINT8 *)dp, len); tftp_dlen += len; tftp_flashAddress += len; } return TRUE;}unsigned short htons(unsigned short x){ unsigned short result = 0; result = ((x & 0x00ff) << 8) | ((x & 0xff00) >> 8); //result = x; return result;}unsigned short ntohs(unsigned short x){ unsigned short result = 0; result = ((x & 0x00ff) << 8) | ((x & 0xff00) >> 8); return result;}void tftp_send_error(unsigned short error, const char *msg){ struct tftphdr *tp; unsigned int len = 0; sys_memset((void *)ackbuf, 0, sizeof(ackbuf)); tp = (struct tftphdr *)ackbuf; tp->th_opcode = htons(TFTP_ERR); tp->th_code = htons(error); len = strlen(msg) + 1; //sys_memcpy(&ackbuf[4], msg, len); sys_memcpy(&(tp->th_data), msg, len); tp->th_data[len] = '\0'; len += 4; ackbuf[len] = 0; udp_send(rcv_ipaddress, len, ackbuf); }void tftp_send_ack(unsigned short block){ struct tftphdr *tp; int size = 0; sys_memset((void *)ackbuf, 0, sizeof(ackbuf)); tp = (struct tftphdr *)ackbuf; tp->th_opcode = htons(TFTP_ACK); tp->th_block = htons(block); ackbuf[4] = '\0'; size = 4; udp_send(rcv_ipaddress, size, ackbuf); }void code_data_process(unsigned char *rxpacket, int len){ int result; int block_number = 0; short *data; data = (short *)((char *)rxpacket); block_number = ntohs(data[1]); if (block_number != tftp_block) { sys_printf("block number error!\n"); tftp_block--; return; } /* move ptr to delete tftp head */ rxpacket += 4; len -= 4;#if 1 if (tftp_block == 1) { bit32u recTag; char cp[5]; sys_memset((void *)cp, 0, sizeof(cp)); /* first block, get rid of total size and code pattern */ sys_memcpy(cp, rxpacket, 4); cp[4] = 0;// by Oleg it seems this check must be commented if (strcmp(cp, CODE_PATTERN_STRING)) { tftp_block = 0; update_flag = 0; sys_printf("Code Pattern should be:%s , but Upgrade Code Pattern is:%s!!!\n",CODE_PATTERN_STRING,cp); tftp_send_error(4, "Wrong Code Pattern"); return ; } else sys_printf("Code Pattern Correct!\n"); rxpacket += 48; /* code_header + total_size (32 + 16) */ len -= 48; if (getf32((bit32u)rxpacket, &recTag, FALSE) == 4) { if (recTag != TAG_WANTED) { sys_printf("Error: file for wrong endian\n"); tftp_send_error(4, "Wrong Endian for File"); update_flag = 0; tftp_block = 0; return; } } }#endif sys_memcpy(tftp_ramAddress, rxpacket, len); tftp_ramAddress += len; tftp_ramLen += len;#if 0 result = tftp_flashStore(rxpacket, len); Delay(30); #endif tftp_send_ack(tftp_block);}void tftpserver_Handler(void){ unsigned char rxpacket[516]; struct tftphdr *tp; int len = 0; short op_code = 0; char buff[128]; char *cp; char password[64]; int i = 0; len = udp_receive(&rcv_ipaddress, &rxpacket, sizeof(rxpacket), FALSE); if (len == 0) { sys_printf("tftp server receive data error\n"); return; } tp = (struct tftphdr *)rxpacket; op_code = ntohs(tp->th_opcode); if ((op_code == TFTP_WRQ) && (update_flag == 0)) { sys_memcpy(buff, (rxpacket + 2), sizeof(buff)); update_flag = 1; //tftp updating... tftp_block = 0; tftp_dlen = 0; for (cp = buff; *cp != 0; cp++) { if ((*cp >= 'A') && (*cp <= 'Z')) *cp = *cp + 'a' -'A'; } cp = buff; for (i = 0; i < 2; cp++) { if (*cp == 0) i++; } sys_memcpy((char *)password, (char *)cp, sizeof(password));#ifdef DEBUG_TFTP sys_printf("password: %s\n", password); sys_printf("filename: %s\n", buff);#endif if (strstr(buff, "code.bin") != NULL) { update_type = CODE_SECTOR; } else if (strstr(buff, "boot.bin") != NULL) { update_flag = 0; tftp_send_error(4, "Can't write boot.bin in boot"); return ; } else { update_flag = 0; tftp_send_error(1, "Invalid filename");#ifdef DEBUG_TFTP sys_printf("Invalid filename\n"); return;#endif } #if 0 if (strcmp((char *)password, "admin") != 0) { update_flag = 0; tftp_send_error(2, "Invalid Password"); return; }#endif if (update_type == CODE_SECTOR) { char *start ; char *end ; start = sys_getenv("mtd4"); #ifdef DEBUG_TFTP sys_printf("start : %s\n", start);#endif end = strtok(start, ','); #ifdef DEBUG_TFTP sys_printf("start: %s end: %s\n", start, end);#endif tftp_flashAddress = 0; tftp_endAddress = 0; if (( end == NULL) || (start == NULL) || (myatox(start, &tftp_flashAddress) == 0) || (myatox(end, &tftp_endAddress) == 0)) { sys_printf("invalid blockname\n"); tftp_send_error(4, "invalid blockname"); update_flag = 0; return; } tftp_flashAddress &= 0x1fffffff; tftp_flashAddress |= 0xa0000000; tftp_endAddress &= 0x1fffffff; tftp_endAddress |= 0xa0000000; tftp_flashOffset = 0; tftp_dlen = 0;#ifdef DEBUG_TFTP sys_printf("flashAddress = %x\n", tftp_flashAddress); sys_printf("endAddress = %x\n", tftp_endAddress);#endif tftp_ramAddress = CACHED(CS1_BASE + (4 * 1024 * 1024)); tftp_ramBaseAddr = tftp_ramAddress; tftp_ramLen = 0; sys_printf("tftp_ramAddress = %x\n", tftp_ramAddress); } tftp_update = 1; tftp_send_ack(0); } else if ((op_code == TFTP_DATA) && (update_flag == 1)) { tftp_block++; if (update_type == CODE_SECTOR) code_data_process(rxpacket, len); if (len < 516) { bit32u resetAddr; if (erase(tftp_flashAddress, tftp_endAddress) != 0) { sys_printf("Erase Error \n"); return; } Delay(100); tftp_flashStore(tftp_ramBaseAddr, tftp_ramLen); tftp_block = 0; update_flag = 0; resetAddr = 0x08611600 & 0x1fffffff; resetAddr |= 0xa0000000; resetAddr += 0x4; *(volatile bit32u *)resetAddr = 1; } } }int tftpserver_init(void){ if (!udplib_init(sin_lclINAddr)) return 0; if (!udplib_open(69, 69, tftpserver_Handler)) return 0; return 1;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -