41#include <sys/socket.h>
43#include <netinet/in.h>
45#include <sys/select.h>
54#ifdef LOSCFG_NET_LWIP_SACK_TFTP
58 u32_t ulMode, TFTPC_PACKET_S *pstPacket);
62 TFTPC_PACKET_S *pstRecvBuf,
64 struct sockaddr_in *pstServerAddr,
65 TFTPC_PACKET_S *pstSendBuf);
68 TFTPC_PACKET_S *pstSendBuf,
69 struct sockaddr_in *pstServerAddr);
73 TFTPC_PACKET_S *pstRecvBuf,
74 u16_t usCurrBlk, u32_t *pulResendPkt,
75 struct sockaddr_in *pstServerAddr);
78 u32_t ulSendSize, u16_t usCurrBlk,
79 struct sockaddr_in *pstServerAddr);
82 struct sockaddr_in *pstServerAddr, TFTPC_PACKET_S *pstSendBuf);
89 struct sockaddr_in stClientAddr;
91 u32_t set_non_block_socket = 1;
94 *piSocketID =
lwip_socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
95 if (*piSocketID == -1) {
96 LWIP_DEBUGF(TFTP_DEBUG, (
"lwip_tftp_create_bind_socket : lwip_socket create socket failed\n"));
97 return TFTPC_SOCKET_FAILURE;
101 retval = lwip_ioctl(*piSocketID, (
long)FIONBIO, &set_non_block_socket);
103 (
void)lwip_close(*piSocketID);
104 *piSocketID = TFTP_NULL_INT32;
105 return TFTPC_IOCTLSOCKET_FAILURE;
108 ulTempClientIp = INADDR_ANY;
111 (
void)memset_s(&stClientAddr,
sizeof(stClientAddr), 0,
sizeof(stClientAddr));
112 stClientAddr.sin_family = AF_INET;
113 stClientAddr.sin_port = 0;
114 stClientAddr.sin_addr.s_addr = htonl(ulTempClientIp);
116 retval =
lwip_bind(*piSocketID, (
struct sockaddr *)&stClientAddr,
sizeof(stClientAddr));
118 (
void)lwip_close(*piSocketID);
119 *piSocketID = TFTP_NULL_INT32;
121 return TFTPC_BIND_FAILURE;
139 pstPacket->usOpcode = htons(usOpcode);
140 pcCp = pstPacket->u.ucName_Mode;
145 (
void)strncpy_s((
char *)pcCp, TFTP_MAX_PATH_LENGTH, (
char *)szFileName, (TFTP_MAX_PATH_LENGTH - 1));
146 pcCp[(TFTP_MAX_PATH_LENGTH - 1)] =
'\0';
148 pcCp += (strlen((
char *)szFileName) + 1);
149 if (ulMode == TRANSFER_MODE_BINARY) {
150 (
void)strncpy_s((
char *)pcCp, TFTP_MAX_MODE_SIZE,
"octet", (TFTP_MAX_MODE_SIZE - 1));
151 pcCp[(TFTP_MAX_MODE_SIZE - 1)] =
'\0';
152 }
else if (ulMode == TRANSFER_MODE_ASCII) {
153 (
void)strncpy_s((
char *)pcCp, TFTP_MAX_MODE_SIZE,
"netascii", (TFTP_MAX_MODE_SIZE - 1));
154 pcCp[(TFTP_MAX_MODE_SIZE - 1)] =
'\0';
157 pcCp += (strlen((
char *)pcCp) + 1);
159 return (pcCp - (s8_t *)pstPacket);
170 struct sockaddr_in *pstServerAddr, TFTPC_PACKET_S *pstSendBuf)
173 socklen_t slFromAddrLen;
174 struct sockaddr_in stFromAddr;
176 struct timeval stTimeout;
180 slFromAddrLen =
sizeof(stFromAddr);
181 stTimeout.tv_sec = TFTPC_TIMEOUT_PERIOD;
182 stTimeout.tv_usec = 0;
186 FD_SET(iSockNum, &stReadfds);
188 iRet = select((s32_t)(iSockNum + 1), &stReadfds, 0, 0, &stTimeout);
190 return TFTPC_SELECT_ERROR;
191 }
else if (iRet == 0) {
192 return TFTPC_TIMEOUT_ERROR;
195 if (!FD_ISSET(iSockNum, &stReadfds)) {
196 return TFTPC_TIMEOUT_ERROR;
200 iRet = lwip_recvfrom(iSockNum, (s8_t *)pstRecvBuf, TFTP_PKTSIZE, 0,
201 (
struct sockaddr *)&stFromAddr, &slFromAddrLen);
203 return TFTPC_RECVFROM_ERROR;
207 if (iRet < TFTPC_FOUR) {
210 TFTPC_PROTOCOL_PROTO_ERROR,
211 "Packet size < min size",
212 pstServerAddr, pstSendBuf);
214 return TFTPC_PKT_SIZE_ERROR;
218 usOpcode = ntohs(pstRecvBuf->usOpcode);
220 if (usOpcode == TFTPC_OP_ERROR) {
221 ulError = ntohs (pstRecvBuf->u.stTFTP_Err.usErrNum);
228 case TFTPC_PROTOCOL_USER_DEFINED:
229 ulError = TFTPC_ERROR_NOT_DEFINED;
231 case TFTPC_PROTOCOL_FILE_NOT_FOUND:
232 ulError = TFTPC_FILE_NOT_FOUND;
234 case TFTPC_PROTOCOL_ACCESS_ERROR:
235 ulError = TFTPC_ACCESS_ERROR;
237 case TFTPC_PROTOCOL_DISK_FULL:
238 ulError = TFTPC_DISK_FULL;
240 case TFTPC_PROTOCOL_PROTO_ERROR:
241 ulError = TFTPC_PROTO_ERROR;
243 case TFTPC_PROTOCOL_UNKNOWN_TRANSFER_ID:
244 ulError = TFTPC_UNKNOWN_TRANSFER_ID;
246 case TFTPC_PROTOCOL_FILE_EXISTS:
247 ulError = TFTPC_FILE_EXISTS;
249 case TFTPC_PROTOCOL_CANNOT_RESOLVE_HOSTNAME:
250 ulError = TFTPC_CANNOT_RESOLVE_HOSTNAME;
253 ulError = TFTPC_ERROR_NOT_DEFINED;
258 pstRecvBuf->u.stTFTP_Err.ucErrMesg[TFTP_MAXERRSTRSIZE - 1] =
'\0';
260 LWIP_DEBUGF(TFTP_DEBUG, (
"lwip_tftp_recv_from_server : ERROR pkt received: %s\n",
261 pstRecvBuf->u.stTFTP_Err.ucErrMesg));
268 *pulSize = (u32_t)iRet;
273 if (((usOpcode == TFTPC_OP_DATA) &&
274 (ntohs(pstRecvBuf->u.stTFTP_Data.usBlknum) == 1)) ||
275 ((usOpcode == TFTPC_OP_ACK) &&
276 (ntohs(pstRecvBuf->u.usBlknum) == 0))) {
278 if (stFromAddr.sin_addr.s_addr == pstServerAddr->sin_addr.s_addr) {
280 pstServerAddr->sin_port = stFromAddr.sin_port;
283 LWIP_DEBUGF(TFTP_DEBUG,
284 (
"lwip_tftp_recv_from_server : Received 1st packet from wrong Server or unknown server\n"));
292 if ((stFromAddr.sin_addr.s_addr != pstServerAddr->sin_addr.s_addr) ||
293 (pstServerAddr->sin_port != stFromAddr.sin_port)) {
295 LWIP_DEBUGF(TFTP_DEBUG,
296 (
"lwip_tftp_recv_from_server : Received a packet from wrong Server or unknown server\n"));
314 TFTPC_PACKET_S *pstSendBuf,
315 struct sockaddr_in *pstServerAddr)
322 (
struct sockaddr *)pstServerAddr,
323 sizeof(
struct sockaddr_in));
325 if ((iRet == TFTP_NULL_INT32) || ((u32_t)iRet != ulSize)) {
326 return TFTPC_SENDTO_ERROR;
343 TFTPC_PACKET_S *pstRecvBuf,
346 struct sockaddr_in *pstServerAddr)
349 struct timeval stTimeout;
350 struct sockaddr_in stFromAddr;
351 socklen_t ulFromAddrLen;
352 s32_t iRecvLen = (s32_t)*pulSize;
357 ulFromAddrLen =
sizeof(stFromAddr);
360 if (memcpy_s((
void *)&stFromAddr,
sizeof(
struct sockaddr_in), (
void *)pstServerAddr,
sizeof(stFromAddr)) != 0) {
361 LWIP_DEBUGF(TFTP_DEBUG, (
"lwip_tftp_validate_data_pkt : memcpy_s error\n"));
362 return TFTPC_MEMCPY_FAILURE;
366 usBlknum = ntohs(pstRecvBuf->u.stTFTP_Data.usBlknum);
368 if (usBlknum != usCurrBlk) {
370 stTimeout.tv_sec = 1;
371 stTimeout.tv_usec = 0;
375 FD_SET(iSockNum, &stReadfds);
377 iError = select((s32_t)(iSockNum + 1),
378 &stReadfds, 0, 0, &stTimeout);
381 while ((iError != TFTP_NULL_INT32) && (iError != 0)) {
388 if (ulLoopCnt > TFTPC_MAX_WAIT_IN_LOOP) {
389 LWIP_DEBUGF(TFTP_DEBUG, (
"lwip_tftp_validate_data_pkt : unexpected packets are received repeatedly\n"));
390 *pulSize = TFTP_NULL_UINT32;
391 return TFTPC_PKT_SIZE_ERROR;
395 FD_SET(iSockNum, &stReadfds);
397 iRecvLen = lwip_recvfrom(iSockNum,
400 (
struct sockaddr *)&stFromAddr,
402 if (iRecvLen == -1) {
403 *pulSize = TFTP_NULL_UINT32;
406 return TFTPC_RECVFROM_ERROR;
409 stTimeout.tv_sec = 1;
410 stTimeout.tv_usec = 0;
411 iError = select((s32_t)(iSockNum + 1), &stReadfds, 0, 0, &stTimeout);
415 if (iRecvLen < TFTPC_FOUR) {
416 return TFTPC_PKT_SIZE_ERROR;
422 if ((stFromAddr.sin_addr.s_addr != pstServerAddr->sin_addr.s_addr) ||
423 (pstServerAddr->sin_port != stFromAddr.sin_port)) {
426 LWIP_DEBUGF(TFTP_DEBUG, (
"lwip_tftp_validate_data_pkt : Received pkt from unknown server\n"));
432 if (TFTPC_OP_DATA != ntohs(pstRecvBuf->usOpcode)) {
433 LWIP_DEBUGF(TFTP_DEBUG, (
"lwip_tftp_validate_data_pkt : Received pkt not a DATA pkt\n"));
437 return TFTPC_PROTO_ERROR;
440 usBlknum = ntohs(pstRecvBuf->u.stTFTP_Data.usBlknum);
443 if (usBlknum == (usCurrBlk - 1)) {
446 LWIP_DEBUGF(TFTP_DEBUG, (
"lwip_tftp_validate_data_pkt : Received previous DATA pkt\n"));
453 if (usBlknum != usCurrBlk) {
454 LWIP_DEBUGF(TFTP_DEBUG,
455 (
"lwip_tftp_validate_data_pkt : Received DATA pkt no. %"S32_F
" instead of pkt no.%"S32_F
"\n",
456 usBlknum, usCurrBlk));
458 return TFTPC_SYNC_FAILURE;
462 *pulSize = (u32_t)iRecvLen;
473 struct sockaddr_in *pstServerAddr, TFTPC_PACKET_S *pstSendBuf)
475 u16_t usOpCode = TFTPC_OP_ERROR;
477 if (memset_s((
void *)pstSendBuf,
sizeof(TFTPC_PACKET_S), 0,
sizeof(TFTPC_PACKET_S)) != 0) {
478 LWIP_DEBUGF(TFTP_DEBUG, (
"lwip_tftp_send_error : memset_s error\n"));
483 pstSendBuf->usOpcode = htons(usOpCode);
484 pstSendBuf->u.stTFTP_Err.usErrNum = htons((u16_t)ulError);
486 if (strncpy_s((
char *)(pstSendBuf->u.stTFTP_Err.ucErrMesg), TFTP_MAXERRSTRSIZE,
487 (
char *)szErrMsg, (TFTP_MAXERRSTRSIZE - 1)) != EOK) {
488 LWIP_DEBUGF(TFTP_DEBUG, (
"lwip_tftp_send_error : strncpy_s error\n"));
491 pstSendBuf->u.stTFTP_Err.ucErrMesg[(TFTP_MAXERRSTRSIZE - 1)] =
'\0';
495 sizeof(TFTPC_PACKET_S),
497 pstServerAddr) != ERR_OK) {
498 LWIP_DEBUGF(TFTP_DEBUG, (
"lwip_tftp_send_to_server error."));
509 u16_t usTftpServPort,
510 u8_t ucTftpTransMode,
514 s32_t iSockNum = TFTP_NULL_INT32;
518 u32_t ulRecvSize = TFTP_NULL_UINT32;
522 u16_t usTempServPort;
523 s8_t *pszTempDestName = NULL;
524 s8_t *szTempSrcName = NULL;
526 u32_t ulResendPkt = 0;
527 u32_t ulIgnorePkt = 0;
528 u32_t ulTotalTime = 0;
529 u32_t isLocalFileOpened =
false;
531 TFTPC_PACKET_S *pstSendBuf = NULL;
532 TFTPC_PACKET_S *pstRecvBuf = NULL;
533 struct sockaddr_in stServerAddr;
535 u32_t IsDirExist = 0;
539 if ((szSrcFileName == NULL) || (szDestDirPath == NULL)) {
540 return TFTPC_INVALID_PARAVALUE;
543 if ((ucTftpTransMode != TRANSFER_MODE_BINARY) && (ucTftpTransMode != TRANSFER_MODE_ASCII)) {
544 return TFTPC_INVALID_PARAVALUE;
549 if (!(((ulHostAddr >= TFTPC_IP_ADDR_MIN) &&
550 (ulHostAddr <= TFTPC_IP_ADDR_EX_RESV)) ||
551 ((ulHostAddr >= TFTPC_IP_ADDR_CLASS_B) &&
552 (ulHostAddr <= TFTPC_IP_ADDR_EX_CLASS_DE)))) {
553 return TFTPC_IP_NOT_WITHIN_RANGE;
557 ulSrcStrLen = strlen((
char *)szSrcFileName);
558 if ((ulSrcStrLen == 0) || (ulSrcStrLen >= TFTP_MAX_PATH_LENGTH)) {
559 return TFTPC_SRC_FILENAME_LENGTH_ERROR;
563 ulDestStrLen = strlen((
char *)szDestDirPath);
564 if ((ulDestStrLen >= TFTP_MAX_PATH_LENGTH) || (ulDestStrLen == 0)) {
565 return TFTPC_DEST_PATH_LENGTH_ERROR;
568 pstSendBuf = (TFTPC_PACKET_S *)mem_malloc(
sizeof(TFTPC_PACKET_S));
569 if (pstSendBuf == NULL) {
570 return TFTPC_MEMALLOC_ERROR;
573 pstRecvBuf = (TFTPC_PACKET_S *)mem_malloc(
sizeof(TFTPC_PACKET_S));
574 if (pstRecvBuf == NULL) {
575 mem_free(pstSendBuf);
576 return TFTPC_MEMALLOC_ERROR;
579 pszTempDestName = (s8_t *)mem_malloc(TFTP_MAX_PATH_LENGTH);
580 if (pszTempDestName == NULL) {
581 mem_free(pstSendBuf);
582 mem_free(pstRecvBuf);
583 return TFTPC_MEMALLOC_ERROR;
587 (
void)memset_s((
void *)pstSendBuf,
sizeof(TFTPC_PACKET_S), 0,
sizeof(TFTPC_PACKET_S));
588 (
void)memset_s((
void *)pstRecvBuf,
sizeof(TFTPC_PACKET_S), 0,
sizeof(TFTPC_PACKET_S));
592 if ((0 != strchr((
char *)szSrcFileName,
'/')) || (0 != strchr((
char *)szSrcFileName,
'\\'))) {
594 szTempSrcName = szSrcFileName + (ulSrcStrLen - 1);
596 while (((*(szTempSrcName - 1) !=
'/') &&
597 (*(szTempSrcName - 1) !=
'\\')) &&
598 (szTempSrcName != szSrcFileName)) {
603 ulSrcStrLen = strlen((
char *)szTempSrcName);
606 szTempSrcName = szSrcFileName;
609 (
void)memset_s(pszTempDestName, TFTP_MAX_PATH_LENGTH, 0, TFTP_MAX_PATH_LENGTH);
610 if (strncpy_s((
char *)pszTempDestName, TFTP_MAX_PATH_LENGTH, (
char *)szDestDirPath, TFTP_MAX_PATH_LENGTH - 1) !=
612 ulErrCode = TFTPC_MEMCPY_FAILURE;
615 pszTempDestName[TFTP_MAX_PATH_LENGTH - 1] =
'\0';
617 if (stat((
char *)pszTempDestName, &sb) == 0 && S_ISDIR(sb.st_mode)) {
621 if (IsDirExist == 1) {
623 if ((ulDestStrLen + ulSrcStrLen) >= TFTP_MAX_PATH_LENGTH) {
625 ulErrCode = TFTPC_DEST_PATH_LENGTH_ERROR;
630 if ((pszTempDestName[ulDestStrLen - 1] !=
'/') &&
631 (pszTempDestName[ulDestStrLen - 1] !=
'\\')) {
632 if ((ulDestStrLen + ulSrcStrLen + 1) >= TFTP_MAX_PATH_LENGTH) {
634 ulErrCode = TFTPC_DEST_PATH_LENGTH_ERROR;
639 if (strncat_s((
char *)pszTempDestName, (TFTP_MAX_PATH_LENGTH - strlen((
char *)pszTempDestName)),
640 "/", TFTP_MAX_PATH_LENGTH - strlen((
char *)pszTempDestName) - 1) != 0) {
641 ulErrCode = TFTPC_ERROR_NOT_DEFINED;
647 if (strncat_s((
char *)pszTempDestName, (TFTP_MAX_PATH_LENGTH - strlen((
char *)pszTempDestName)),
648 (
char *)szTempSrcName, TFTP_MAX_PATH_LENGTH - strlen((
char *)pszTempDestName) - 1) != 0) {
649 ulErrCode = TFTPC_ERROR_NOT_DEFINED;
655 if (ulErrCode != ERR_OK) {
659 if (usTftpServPort == 0) {
660 usTftpServPort = TFTPC_SERVER_PORT;
663 usTempServPort = usTftpServPort;
666 (
void)memset_s(&stServerAddr,
sizeof(stServerAddr), 0,
sizeof(stServerAddr));
667 stServerAddr.sin_family = AF_INET;
668 stServerAddr.sin_port = htons(usTempServPort);
669 stServerAddr.sin_addr.s_addr = htonl(ulHostAddr);
673 (u32_t)ucTftpTransMode,
676 pstSendBuf, &stServerAddr);
677 if (ulErrCode != ERR_OK) {
679 (
void)lwip_close(iSockNum);
684 if (ulIgnorePkt > 0) {
689 &ulIgnorePkt, &stServerAddr, pstSendBuf);
691 if (ulErrCode == TFTPC_TIMEOUT_ERROR) {
693 if (ulTotalTime < TFTPC_MAX_SEND_REQ_ATTEMPTS) {
696 pstSendBuf, &stServerAddr);
697 if (ulErrCode != ERR_OK) {
698 (
void)lwip_close(iSockNum);
699 if (isLocalFileOpened ==
true) {
708 (
void)lwip_close(iSockNum);
709 if (isLocalFileOpened ==
true) {
712 ulErrCode = TFTPC_TIMEOUT_ERROR;
715 }
else if (ulErrCode != ERR_OK) {
716 (
void)lwip_close(iSockNum);
717 if (isLocalFileOpened ==
true) {
724 if (ulIgnorePkt > 0) {
730 if (ntohs (pstRecvBuf->usOpcode) != TFTPC_OP_DATA) {
733 TFTPC_PROTOCOL_PROTO_ERROR,
735 &stServerAddr, pstSendBuf);
737 (
void)lwip_close(iSockNum);
738 if (isLocalFileOpened ==
true) {
742 LWIP_DEBUGF(TFTP_DEBUG, (
"lwip_tftp_get_file_by_filename : Received pkt not DATA pkt\n"));
744 ulErrCode = TFTPC_PROTO_ERROR;
753 pstRecvBuf, (u16_t)ulCurrBlk,
756 if (ulErrCode != ERR_OK) {
758 if (ulErrCode != TFTPC_RECVFROM_ERROR) {
760 TFTPC_PROTOCOL_PROTO_ERROR,
761 "Received unexpected packet",
762 &stServerAddr, pstSendBuf);
765 (
void)lwip_close(iSockNum);
766 if (isLocalFileOpened ==
true) {
774 if (ulResendPkt > 0) {
778 pstSendBuf, &stServerAddr);
779 if (ulErrCode != ERR_OK) {
780 (
void)lwip_close(iSockNum);
781 if (isLocalFileOpened ==
true) {
793 ulRecvSize -= TFTP_HDRSIZE;
796 if (ulRecvSize > TFTP_BLKSIZE) {
799 TFTPC_PROTOCOL_PROTO_ERROR,
800 "Packet size > max size",
801 &stServerAddr, pstSendBuf);
803 (
void)lwip_close(iSockNum);
804 if (isLocalFileOpened ==
true) {
808 LWIP_DEBUGF(TFTP_DEBUG, (
"lwip_tftp_get_file_by_filename : Packet size > max size\n"));
810 ulErrCode = TFTPC_PKT_SIZE_ERROR;
814 usReadReq = (u16_t)TFTPC_OP_ACK;
815 pstSendBuf->usOpcode = htons(usReadReq);
816 pstSendBuf->u.usBlknum = htons((u16_t)ulCurrBlk);
817 ulSize = TFTP_HDRSIZE;
819 if (isLocalFileOpened ==
false) {
820 fp = open((
char *)pszTempDestName, (O_WRONLY | O_CREAT | O_TRUNC), DEFFILEMODE);
821 if (fp == TFTP_NULL_INT32) {
822 ulErrCode = TFTPC_FILECREATE_ERROR;
823 (
void)lwip_close(iSockNum);
826 isLocalFileOpened =
true;
829 if (ulRecvSize != TFTP_BLKSIZE) {
833 if (ulRecvSize != 0) {
835 iErrCode = write(fp, (
void *)pstRecvBuf->u.stTFTP_Data.ucDataBuf, (
size_t)ulRecvSize);
836 if (ulRecvSize != (u32_t)iErrCode) {
839 TFTPC_PROTOCOL_USER_DEFINED,
840 "Write to file failed",
841 &stServerAddr, pstSendBuf);
843 (
void)lwip_close(iSockNum);
847 ulErrCode = TFTPC_FILEWRITE_ERROR;
854 (
void)lwip_close(iSockNum);
861 pstSendBuf, &stServerAddr);
862 if (ulErrCode != ERR_OK) {
863 (
void)lwip_close(iSockNum);
868 iErrCode = write(fp, (
void *)pstRecvBuf->u.stTFTP_Data.ucDataBuf, (
size_t)ulRecvSize);
869 if (ulRecvSize != (u32_t)iErrCode) {
872 TFTPC_PROTOCOL_USER_DEFINED,
873 "Write to file failed",
874 &stServerAddr, pstSendBuf);
876 (
void)lwip_close(iSockNum);
880 ulErrCode = TFTPC_FILEWRITE_ERROR;
889 if (ulCurrBlk > TFTP_MAX_BLK_NUM) {
892 TFTPC_PROTOCOL_USER_DEFINED,
894 &stServerAddr, pstSendBuf);
896 (
void)lwip_close(iSockNum);
898 LWIP_DEBUGF(TFTP_DEBUG, (
"lwip_tftp_get_file_by_filename : Data block number exceeded max value\n"));
900 ulErrCode = TFTPC_FILE_TOO_BIG;
906 mem_free(pstSendBuf);
907 mem_free(pstRecvBuf);
908 mem_free(pszTempDestName);
919 s8_t *szSrcFileName, s8_t *szDestDirPath)
923 s32_t iSockNum = TFTP_NULL_INT32;
926 u16_t usTempServPort;
927 TFTPC_PACKET_S *pstSendBuf = NULL;
931 s8_t *szTempDestName = NULL;
935 struct sockaddr_in stServerAddr;
940 if ((szSrcFileName == NULL) || (szDestDirPath == NULL)) {
941 return TFTPC_INVALID_PARAVALUE;
944 if ((ucTftpTransMode != TRANSFER_MODE_BINARY) && (ucTftpTransMode != TRANSFER_MODE_ASCII)) {
945 return TFTPC_INVALID_PARAVALUE;
950 if (!(((ulHostAddr >= TFTPC_IP_ADDR_MIN) &&
951 (ulHostAddr <= TFTPC_IP_ADDR_EX_RESV)) ||
952 ((ulHostAddr >= TFTPC_IP_ADDR_CLASS_B) &&
953 (ulHostAddr <= TFTPC_IP_ADDR_EX_CLASS_DE)))) {
954 return TFTPC_IP_NOT_WITHIN_RANGE;
958 ulSrcStrLen = strlen((
char *)szSrcFileName);
959 if ((ulSrcStrLen == 0) || (ulSrcStrLen >= TFTP_MAX_PATH_LENGTH)) {
960 return TFTPC_SRC_FILENAME_LENGTH_ERROR;
964 if (stat((
char *)szSrcFileName, &buffer) != 0) {
965 return TFTPC_FILE_NOT_EXIST;
969 if (buffer.st_size >= (off_t)(TFTP_MAX_BLK_NUM * TFTP_BLKSIZE)) {
970 return TFTPC_FILE_TOO_BIG;
974 ulDestStrLen = strlen((
char *)szDestDirPath);
976 if (ulDestStrLen >= TFTP_MAX_PATH_LENGTH) {
977 return TFTPC_DEST_PATH_LENGTH_ERROR;
980 pstSendBuf = (TFTPC_PACKET_S *)mem_malloc(
sizeof(TFTPC_PACKET_S));
981 if (pstSendBuf == NULL) {
982 return TFTPC_MEMALLOC_ERROR;
986 (
void)memset_s((
void *)pstSendBuf,
sizeof(TFTPC_PACKET_S), 0,
sizeof(TFTPC_PACKET_S));
993 if (ulDestStrLen != 0) {
995 szTempDestName = szDestDirPath;
1000 if ((strchr((
char *)szSrcFileName,
'/') != 0) ||
1001 (strchr((
char *)szSrcFileName,
'\\') != 0)) {
1003 szTempDestName = szSrcFileName + (ulSrcStrLen - 1);
1005 while (((*(szTempDestName - 1) !=
'/') && (*(szTempDestName - 1) !=
'\\')) &&
1006 (szTempDestName != szSrcFileName)) {
1011 szTempDestName = szSrcFileName;
1017 if (ulErrCode != EOK) {
1022 if (usTftpServPort == 0) {
1023 usTftpServPort = TFTPC_SERVER_PORT;
1026 usTempServPort = usTftpServPort;
1029 (
void)memset_s(&stServerAddr,
sizeof(stServerAddr), 0,
sizeof(stServerAddr));
1030 stServerAddr.sin_family = AF_INET;
1031 stServerAddr.sin_port = htons(usTempServPort);
1032 stServerAddr.sin_addr.s_addr = htonl(ulHostAddr);
1041 pstSendBuf, &stServerAddr);
1042 if (ulErrCode != ERR_OK) {
1044 (
void)lwip_close(iSockNum);
1051 usCurrBlk, &stServerAddr);
1052 if (ulErrCode != ERR_OK) {
1054 (
void)lwip_close(iSockNum);
1056 LWIP_DEBUGF(TFTP_DEBUG, (
"lwip_tftp_put_file_by_filename : Failed to send request packet\n"));
1062 pucBuffer = mem_malloc(TFTP_BLKSIZE);
1063 if (pucBuffer == NULL) {
1066 TFTPC_PROTOCOL_USER_DEFINED,
1067 "Memory allocation failed.",
1068 &stServerAddr, pstSendBuf);
1070 (
void)lwip_close(iSockNum);
1071 ulErrCode = TFTPC_MEMALLOC_ERROR;
1075 (
void)memset_s((
void *)pucBuffer, TFTP_BLKSIZE, 0, TFTP_BLKSIZE);
1077 fp = open((
char *)szSrcFileName, O_RDONLY);
1078 if (TFTP_NULL_INT32 == fp) {
1081 TFTPC_PROTOCOL_USER_DEFINED,
1083 &stServerAddr, pstSendBuf);
1085 (
void)lwip_close(iSockNum);
1086 mem_free(pucBuffer);
1088 ulErrCode = TFTPC_FILEOPEN_ERROR;
1092 iErrCode = read(fp, pucBuffer, TFTP_BLKSIZE);
1096 TFTPC_PROTOCOL_USER_DEFINED,
1098 &stServerAddr, pstSendBuf);
1100 (
void)lwip_close(iSockNum);
1102 mem_free(pucBuffer);
1104 ulErrCode = TFTPC_FILEREAD_ERROR;
1111 if (((u32_t)usCurrBlk + 1) > TFTP_MAX_BLK_NUM) {
1113 TFTPC_PROTOCOL_USER_DEFINED,
1115 &stServerAddr, pstSendBuf);
1117 (
void)lwip_close(iSockNum);
1119 mem_free(pucBuffer);
1120 LWIP_DEBUGF(TFTP_DEBUG, (
"lwip_tftp_put_file_by_filename : Data block number exceeded max value\n"));
1122 ulErrCode = TFTPC_FILE_TOO_BIG;
1129 ulSize = (u32_t)iErrCode + TFTP_HDRSIZE;
1132 usReadReq = (u16_t)TFTPC_OP_DATA;
1133 pstSendBuf->usOpcode = htons(usReadReq);
1134 pstSendBuf->u.stTFTP_Data.usBlknum = htons(usCurrBlk);
1135 if (memcpy_s((
void *)pstSendBuf->u.stTFTP_Data.ucDataBuf, TFTP_BLKSIZE,
1136 (
void *)pucBuffer, (u32_t)iErrCode) != EOK) {
1137 (
void)lwip_close(iSockNum);
1139 mem_free(pucBuffer);
1144 pstSendBuf, &stServerAddr);
1145 if ((ulErrCode != ERR_OK) || (memset_s((
void *)pucBuffer, TFTP_BLKSIZE, 0, TFTP_BLKSIZE) != 0)) {
1146 (
void)lwip_close(iSockNum);
1148 mem_free(pucBuffer);
1153 iErrCode = read(fp, pucBuffer, TFTP_BLKSIZE);
1157 &stServerAddr, pstSendBuf);
1159 (
void)lwip_close(iSockNum);
1161 mem_free(pucBuffer);
1162 ulErrCode = TFTPC_FILEREAD_ERROR;
1168 usCurrBlk, &stServerAddr);
1169 if (ulErrCode != ERR_OK) {
1171 (
void)lwip_close(iSockNum);
1173 mem_free(pucBuffer);
1174 LWIP_DEBUGF(TFTP_DEBUG, (
"lwip_tftp_put_file_by_filename : Sending file to server failed\n"));
1177 }
while (ulSize == (TFTP_BLKSIZE + TFTP_HDRSIZE));
1180 (
void)lwip_close(iSockNum);
1182 mem_free(pucBuffer);
1186 mem_free(pstSendBuf);
1198 TFTPC_PACKET_S *pstSendBuf,
1201 struct sockaddr_in *pstServerAddr)
1207 socklen_t iFromAddrLen;
1208 u32_t ulTotalTime = 0;
1210 struct sockaddr_in stFromAddr;
1211 struct timeval stTimeout;
1212 TFTPC_PACKET_S *pstRecvBuf = NULL;
1213 u32_t ulIgnorePkt = 0;
1215 u32_t ulLoopCnt = 0;
1217 iFromAddrLen =
sizeof(stFromAddr);
1219 pstRecvBuf = (TFTPC_PACKET_S *)mem_malloc(
sizeof(TFTPC_PACKET_S));
1220 if (pstRecvBuf == NULL) {
1221 return TFTPC_MEMALLOC_ERROR;
1225 (
void)memset_s((
void *)pstRecvBuf,
sizeof(TFTPC_PACKET_S), 0,
sizeof(TFTPC_PACKET_S));
1228 if (memcpy_s((
void *)&stFromAddr,
sizeof(
struct sockaddr_in),
1229 (
void *)pstServerAddr,
sizeof(stFromAddr)) != EOK) {
1230 ulError = TFTPC_MEMCPY_FAILURE;
1236 pstRecvBuf, &ulIgnorePkt,
1237 pstServerAddr, pstSendBuf);
1239 if (ulError == TFTPC_TIMEOUT_ERROR) {
1241 if (ulTotalTime < TFTPC_MAX_SEND_REQ_ATTEMPTS) {
1244 pstSendBuf, pstServerAddr);
1245 if (ulError != ERR_OK) {
1252 ulError = TFTPC_TIMEOUT_ERROR;
1255 }
else if (ulError != ERR_OK) {
1261 if (ulIgnorePkt > 0) {
1269 if (TFTPC_OP_ACK != ntohs(pstRecvBuf->usOpcode)) {
1271 TFTPC_PROTOCOL_PROTO_ERROR,
1273 pstServerAddr, pstSendBuf);
1275 LWIP_DEBUGF(TFTP_DEBUG, (
"lwip_tftp_inner_put_file : Received pkt not Ack pkt\n"));
1277 ulError = TFTPC_PROTO_ERROR;
1284 usBlknum = ntohs(pstRecvBuf->u.usBlknum);
1285 iRecvLen = (
int)ulPktSize;
1288 if (usBlknum != usCurrBlk) {
1291 stTimeout.tv_sec = 1;
1292 stTimeout.tv_usec = 0;
1294 FD_ZERO(&stReadfds);
1295 FD_SET(iSockNum, &stReadfds);
1302 iError = select((s32_t)(iSockNum + 1), &stReadfds, 0, 0, &stTimeout);
1305 while ((iError != -1) && (iError != 0)) {
1312 if (ulLoopCnt > TFTPC_MAX_WAIT_IN_LOOP) {
1313 LWIP_DEBUGF(TFTP_DEBUG,
1314 (
"lwip_tftp_inner_put_file : unexpected packets are received repeatedly\n"));
1315 ulError = TFTPC_PKT_SIZE_ERROR;
1319 FD_ZERO(&stReadfds);
1320 FD_SET(iSockNum, &stReadfds);
1321 iRecvLen = lwip_recvfrom(iSockNum,
1324 (
struct sockaddr *)&stFromAddr,
1326 if (TFTP_NULL_INT32 == iRecvLen) {
1327 ulError = TFTPC_RECVFROM_ERROR;
1331 stTimeout.tv_sec = 1;
1332 stTimeout.tv_usec = 0;
1333 iError = select((s32_t)(iSockNum + 1),
1334 &stReadfds, 0, 0, &stTimeout);
1341 if (iRecvLen < TFTPC_FOUR) {
1343 TFTPC_PROTOCOL_PROTO_ERROR,
1344 "Packet size < min packet size",
1345 pstServerAddr, pstSendBuf);
1347 LWIP_DEBUGF(TFTP_DEBUG, (
"lwip_tftp_inner_put_file : Received pkt not Ack pkt\n"));
1349 ulError = TFTPC_PKT_SIZE_ERROR;
1356 if ((stFromAddr.sin_addr.s_addr != pstServerAddr->sin_addr.s_addr) ||
1357 (pstServerAddr->sin_port != stFromAddr.sin_port)) {
1359 LWIP_DEBUGF(TFTP_DEBUG, (
"lwip_tftp_inner_put_file : Received pkt from unknown server\n"));
1364 if (TFTPC_OP_ACK != ntohs(pstRecvBuf->usOpcode)) {
1366 TFTPC_PROTOCOL_PROTO_ERROR,
1368 pstServerAddr, pstSendBuf);
1370 LWIP_DEBUGF(TFTP_DEBUG, (
"lwip_tftp_inner_put_file : Received pkt not Ack pkt\n"));
1372 ulError = TFTPC_PROTO_ERROR;
1376 usBlknum = ntohs(pstRecvBuf->u.usBlknum);
1388 if ((usCurrBlk - 1) == usBlknum) {
1397 if (usBlknum != usCurrBlk) {
1399 TFTPC_PROTOCOL_PROTO_ERROR,
1400 "Received unexpected packet",
1401 pstServerAddr, pstSendBuf);
1403 LWIP_DEBUGF(TFTP_DEBUG,
1404 (
"lwip_tftp_inner_put_file : Received DATA pkt no. %"S32_F
"instead of pkt no. %"S32_F
"\n",
1405 usBlknum, usCurrBlk));
1407 ulError = TFTPC_SYNC_FAILURE;
1417 mem_free(pstRecvBuf);
1421#ifdef TFTP_TO_RAWMEM
1432 u16_t usTftpServPort,
1433 u8_t ucTftpTransMode,
1434 s8_t *szSrcFileName,
1435 s8_t *szDestMemAddr,
1436 u32_t *ulFileLength)
1438 s32_t iSockNum = TFTP_NULL_INT32;
1442 u32_t ulRecvSize = TFTP_NULL_UINT32;
1446 u16_t usTempServPort;
1447 u32_t ulCurrBlk = 1;
1448 u32_t ulResendPkt = 0;
1449 u32_t ulIgnorePkt = 0;
1450 u32_t ulTotalTime = 0;
1452 TFTPC_PACKET_S *pstSendBuf = NULL;
1453 TFTPC_PACKET_S *pstRecvBuf = NULL;
1454 struct sockaddr_in stServerAddr;
1455 u32_t ulMemOffset = 0;
1458 if ((szSrcFileName == NULL) || (szDestMemAddr == NULL) || (*ulFileLength == 0)) {
1459 return TFTPC_INVALID_PARAVALUE;
1462 if ((ucTftpTransMode != TRANSFER_MODE_BINARY) && (ucTftpTransMode != TRANSFER_MODE_ASCII)) {
1463 return TFTPC_INVALID_PARAVALUE;
1468 if (!(((ulHostAddr >= TFTPC_IP_ADDR_MIN) &&
1469 (ulHostAddr <= TFTPC_IP_ADDR_EX_RESV)) ||
1470 ((ulHostAddr >= TFTPC_IP_ADDR_CLASS_B) &&
1471 (ulHostAddr <= TFTPC_IP_ADDR_EX_CLASS_DE)))) {
1472 return TFTPC_IP_NOT_WITHIN_RANGE;
1476 ulSrcStrLen = strlen(szSrcFileName);
1477 if ((ulSrcStrLen == 0) || (ulSrcStrLen >= TFTP_MAX_PATH_LENGTH)) {
1478 return TFTPC_SRC_FILENAME_LENGTH_ERROR;
1481 pstSendBuf = (TFTPC_PACKET_S *)mem_malloc(
sizeof(TFTPC_PACKET_S));
1482 if (pstSendBuf == NULL) {
1483 return TFTPC_MEMALLOC_ERROR;
1486 pstRecvBuf = (TFTPC_PACKET_S *)mem_malloc(
sizeof(TFTPC_PACKET_S));
1487 if (pstRecvBuf == NULL) {
1488 mem_free(pstSendBuf);
1489 return TFTPC_MEMALLOC_ERROR;
1493 (
void)memset_s((
void *)pstSendBuf,
sizeof(TFTPC_PACKET_S), 0,
sizeof(TFTPC_PACKET_S));
1494 (
void)memset_s((
void *)pstRecvBuf,
sizeof(TFTPC_PACKET_S), 0,
sizeof(TFTPC_PACKET_S));
1497 if (ulErrCode != EOK) {
1501 if (usTftpServPort == 0) {
1502 usTftpServPort = TFTPC_SERVER_PORT;
1505 usTempServPort = usTftpServPort;
1508 (
void)memset_s(&stServerAddr,
sizeof(stServerAddr), 0,
sizeof(stServerAddr));
1509 stServerAddr.sin_family = AF_INET;
1510 stServerAddr.sin_port = htons(usTempServPort);
1511 stServerAddr.sin_addr.s_addr = htonl(ulHostAddr);
1516 if (ulErrCode != ERR_OK) {
1518 (
void)lwip_close(iSockNum);
1523 if (ulIgnorePkt > 0) {
1528 &stServerAddr, pstSendBuf);
1530 if (ulErrCode == TFTPC_TIMEOUT_ERROR) {
1532 if (ulTotalTime < TFTPC_MAX_SEND_REQ_ATTEMPTS) {
1535 pstSendBuf, &stServerAddr);
1536 if (ulErrCode != ERR_OK) {
1537 (
void)lwip_close(iSockNum);
1544 (
void)lwip_close(iSockNum);
1545 ulErrCode = TFTPC_TIMEOUT_ERROR;
1548 }
else if (ulErrCode != ERR_OK) {
1549 (
void)lwip_close(iSockNum);
1554 if (ulIgnorePkt > 0) {
1560 if (ntohs (pstRecvBuf->usOpcode) != TFTPC_OP_DATA) {
1563 TFTPC_PROTOCOL_PROTO_ERROR,
1565 &stServerAddr, pstSendBuf);
1567 (
void)lwip_close(iSockNum);
1569 LWIP_DEBUGF(TFTP_DEBUG, (
"lwip_tftp_get_file_by_filename : Received pkt not DATA pkt\n"));
1571 ulErrCode = TFTPC_PROTO_ERROR;
1580 pstRecvBuf, (u16_t)ulCurrBlk,
1583 if (ulErrCode != ERR_OK) {
1585 if (ulErrCode != TFTPC_RECVFROM_ERROR) {
1587 TFTPC_PROTOCOL_PROTO_ERROR,
1588 "Received unexpected packet",
1589 &stServerAddr, pstSendBuf);
1592 (
void)lwip_close(iSockNum);
1598 if (ulResendPkt > 0) {
1602 pstSendBuf, &stServerAddr);
1603 if (ulErrCode != ERR_OK) {
1604 (
void)lwip_close(iSockNum);
1614 ulRecvSize -= TFTP_HDRSIZE;
1617 if (ulRecvSize > TFTP_BLKSIZE) {
1620 TFTPC_PROTOCOL_PROTO_ERROR,
1621 "Packet size > max size",
1622 &stServerAddr, pstSendBuf);
1624 (
void)lwip_close(iSockNum);
1626 LWIP_DEBUGF(TFTP_DEBUG, (
"lwip_tftp_get_file_by_filename : Packet size > max size\n"));
1628 ulErrCode = TFTPC_PKT_SIZE_ERROR;
1632 usReadReq = (u16_t)TFTPC_OP_ACK;
1633 pstSendBuf->usOpcode = htons(usReadReq);
1634 pstSendBuf->u.usBlknum = htons((u16_t)ulCurrBlk);
1635 ulSize = TFTP_HDRSIZE;
1637 if (ulRecvSize != TFTP_BLKSIZE) {
1639 pstSendBuf, &stServerAddr);
1642 if (ulRecvSize != 0) {
1644 if (*ulFileLength < (ulMemOffset + ulRecvSize)) {
1645 ulErrCode = TFTPC_MEMCPY_FAILURE;
1646 (
void)lwip_close(iSockNum);
1647 *ulFileLength = ulMemOffset;
1651 if (memcpy_s(szDestMemAddr + ulMemOffset, TFTP_MAX_BLK_NUM * TFTP_BLKSIZE,
1652 (
void *)pstRecvBuf->u.stTFTP_Data.ucDataBuf, (
size_t)ulRecvSize) != EOK) {
1653 ulErrCode = TFTPC_MEMCPY_FAILURE;
1654 (
void)lwip_close(iSockNum);
1655 *ulFileLength = ulMemOffset;
1658 ulMemOffset += ulRecvSize;
1663 (
void)lwip_close(iSockNum);
1665 *ulFileLength = ulMemOffset;
1670 pstSendBuf, &stServerAddr);
1671 if (ulErrCode != ERR_OK) {
1672 (
void)lwip_close(iSockNum);
1677 if (*ulFileLength < ulRecvSize * ulCurrBlk) {
1678 ulErrCode = TFTPC_MEMCPY_FAILURE;
1679 (
void)lwip_close(iSockNum);
1680 *ulFileLength = ulMemOffset;
1683 if (memcpy_s(szDestMemAddr + ulMemOffset, TFTP_MAX_BLK_NUM * TFTP_BLKSIZE,
1684 (
void *)pstRecvBuf->u.stTFTP_Data.ucDataBuf, (
size_t)ulRecvSize) != EOK) {
1685 ulErrCode = TFTPC_MEMCPY_FAILURE;
1686 (
void)lwip_close(iSockNum);
1687 *ulFileLength = ulMemOffset;
1691 ulMemOffset += ulRecvSize;
1696 if (ulCurrBlk > TFTP_MAX_BLK_NUM) {
1699 TFTPC_PROTOCOL_USER_DEFINED,
1701 &stServerAddr, pstSendBuf);
1703 (
void)lwip_close(iSockNum);
1705 LWIP_DEBUGF(TFTP_DEBUG, (
"lwip_tftp_get_file_by_filename : Data block number exceeded max value\n"));
1707 ulErrCode = TFTPC_FILE_TOO_BIG;
1713 mem_free(pstSendBuf);
1714 mem_free(pstRecvBuf);
ssize_t lwip_sendto(int s, const void *dataptr, size_t size, int flags, const struct sockaddr *to, socklen_t tolen)
int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen)
int lwip_socket(int domain, int type, int protocol)
ARG_NUM_3 ARG_NUM_1 ARG_NUM_2 ARG_NUM_2 ARG_NUM_3 ARG_NUM_1 ARG_NUM_4 ARG_NUM_2 ARG_NUM_2 ARG_NUM_5 ARG_NUM_2 void
static s32_t lwip_tftp_make_tftp_packet(u16_t usOpcode, s8_t *szFileName, u32_t ulMode, TFTPC_PACKET_S *pstPacket)
u32_t lwip_tftp_get_file_by_filename_to_rawmem(u32_t ulHostAddr, u16_t usTftpServPort, u8_t ucTftpTransMode, s8_t *szSrcFileName, s8_t *szDestMemAddr, u32_t *ulFileLength)
static void lwip_tftp_send_error(s32_t iSockNum, u32_t ulError, const char *szErrMsg, struct sockaddr_in *pstServerAddr, TFTPC_PACKET_S *pstSendBuf)
u32_t lwip_tftp_put_file_by_filename(u32_t ulHostAddr, u16_t usTftpServPort, u8_t ucTftpTransMode, s8_t *szSrcFileName, s8_t *szDestDirPath)
static u32_t lwip_tftp_create_bind_socket(s32_t *piSocketID)
static u32_t lwip_tftp_validate_data_pkt(s32_t iSockNum, u32_t *pulSize, TFTPC_PACKET_S *pstRecvBuf, u16_t usCurrBlk, u32_t *pulResendPkt, struct sockaddr_in *pstServerAddr)
u32_t lwip_tftp_get_file_by_filename(u32_t ulHostAddr, u16_t usTftpServPort, u8_t ucTftpTransMode, s8_t *szSrcFileName, s8_t *szDestDirPath)
static u32_t lwip_tftp_recv_from_server(s32_t iSockNum, u32_t *pulSize, TFTPC_PACKET_S *pstRecvBuf, u32_t *pulIgnorePkt, struct sockaddr_in *pstServerAddr, TFTPC_PACKET_S *pstSendBuf)
static u32_t lwip_tftp_send_to_server(s32_t iSockNum, u32_t ulSize, TFTPC_PACKET_S *pstSendBuf, struct sockaddr_in *pstServerAddr)
static u32_t lwip_tftp_inner_put_file(s32_t iSockNum, TFTPC_PACKET_S *pstSendBuf, u32_t ulSendSize, u16_t usCurrBlk, struct sockaddr_in *pstServerAddr)