void //brcm begin tftpd_receive (int peer, struct tftphdr *first_pkt, int pkt_len, int buffersize) { // brcm FILE *file=NULL; char buffer[TFTP_BLOCKSIZE_DEFAULT+4]; struct tftphdr *pkt; int block, inbytes; char *list[64]; int listcount; //brcm begin PARSE_RESULT imageType = NO_IMAGE_FORMAT; int byteRd = 0; char tag[TAG_LEN]; int tagSize = 0; int size = 0; char *curPtr = NULL; unsigned int totalAllocatedSize = 0; int socketPid = 0; int fNeedReset = FALSE; char *imagePtr = NULL; int uploadSize = 0; int i = 0; //printf("tftpd_receive, peer = %d, pkt_len = %d, buffersize=%d\n", peer, pkt_len, buffersize); pkt=(struct tftphdr *)buffer; listcount = tftpd_options (first_pkt->th_stuff, pkt_len, list ,64); /* get the size of the file (remember, chroot() supposed to point us in the right directory) */ //printf ("mode= %s, file= %s\n", list[1], list[0]); if (strcasecmp(list[1],"octet")!=0) { printf("Only support 'bin' mode. Type 'bin' at tftp client\n"); tftpd_nak(peer,EBADOP); close(peer); exit(0); } #if 0//brcm file = fopen (list[0], "w"); if (file == NULL) { tftpd_nak (peer, EACCESS); close(peer); exit(0); } #endif //brcm block=0; socketPid = bcmSocketIfPid(); // kill the app first so that when there are heavy traffic, the UDP packet will not be lost. killAllApps(socketPid, SKIP_HTTPD_APP, 0, 0); // skip kill httpd for xml config. update printf("Done removing processes\n"); fNeedReset = TRUE; do { tftpd_ack(peer,block); block++; // if duplicate pkt, (for slow ack on 38R board) discard it. for (i = 0; i < DUP_PKT_CHECK_COUNT; i++) { inbytes=tftpd_getdata(peer,block,buffer,TFTP_BLOCKSIZE_DEFAULT+4, fNeedReset); if (block == (int) (*(short*)(buffer+2))) break; } // brcm fwrite(pkt->th_msg,1,inbytes-4,file); byteRd=inbytes-4; // brcm begin if (curPtr == NULL) { if (byteRd < TFTP_BLOCKSIZE_DEFAULT) // not enough data for a valid first packet and exit { uploadSize = byteRd; break; } // The first data that is downloaded is the FILE_TAG structure. // After the entire FILE_TAG structure has been downloaded, use // the totalImageSize field to determine the size of pkt->th_msg to // allocate. if( tagSize + byteRd > TAG_LEN) size = TAG_LEN - tagSize; else size = byteRd; memcpy(tag + tagSize, pkt->th_msg, size); tagSize += size; byteRd -= size; if( tagSize == TAG_LEN ) { PFILE_TAG pTag = (PFILE_TAG) tag; if (verifyTag(pTag, 1) == UPLOAD_OK) { // if chip id mismatched. if (checkChipId(pTag->chipId, pTag->signiture_2) != 0) myExit(fNeedReset, peer); int totalImageSize = atoi(pTag->totalImageLen); // add tag len plus some pkt->th_msg for over flow during the sending... totalAllocatedSize = totalImageSize + TAG_LEN + 8; printf( "Allocating %d bytes for broadcom image.\n", totalAllocatedSize ); curPtr = (char *) malloc(totalImageSize + TAG_LEN + 8); if (curPtr == NULL) { printf("Not enough memory error."); myExit(fNeedReset, peer); } else { printf("Memory allocated\n"); imagePtr = curPtr; memcpy(curPtr, tag, TAG_LEN); curPtr += TAG_LEN; uploadSize += TAG_LEN; memcpy(curPtr, pkt->th_msg + size, byteRd); curPtr += byteRd; } } // try to allocate the memory for .w image, same as flash size + some overhead else { totalAllocatedSize = sysFlashSizeGet() + TOKEN_LEN; printf("Allocating %d bytes for flash image.\n", totalAllocatedSize); curPtr = (char *) malloc(totalAllocatedSize); if(curPtr == NULL) { printf("Not enough memory error."); myExit(fNeedReset, peer); } else { printf("Memory allocated\n"); imagePtr = curPtr; byteRd += TAG_LEN; // add back the tag size memcpy(curPtr, pkt->th_msg, byteRd); curPtr += byteRd; } } // else alloc memory for .w image } //tagSize == TAG_LEN } // if curPtr == NULL else { // not first block of data memcpy(curPtr, pkt->th_msg, byteRd); curPtr += byteRd; } uploadSize += byteRd; //printf("Current uploadSize= %d\n", uploadSize); if (uploadSize > totalAllocatedSize) // try not to over flow the pkt->th_msg { printf("Failed on data corruption during file transfer or over sized image.\n"); printf("Upload size = %d, size allowed = %d\n", uploadSize, totalAllocatedSize); myExit(fNeedReset, peer); } // brcm end } while (inbytes==(TFTP_BLOCKSIZE_DEFAULT+4)); tftpd_ack(peer,block); /* final acknowledge */ // brcm fclose(file); printf("Total size: %d\n", uploadSize); if ((imagePtr != NULL) && ((imageType = parseImageData(imagePtr, uploadSize, BUF_ALL_TYPES)) != NO_IMAGE_FORMAT)) { printf("Tftp image done.\n"); flashImage(imagePtr, imageType, uploadSize); if (imagePtr) free(imagePtr); } else printf("Tftp Image failed: Illegal image.\n"); // no reset if psi update (need httpd to process xml file) if (imageType == PSI_IMAGE_FORMAT) fNeedReset=FALSE; myExit(fNeedReset, peer); }
// upLoadImage // process the image file uploading // return: UPLOAD_RESULT // UPLOAD_RESULT upLoadImage(FILE *stream, int upload_len, int upload_type, char **imageBufPtrPtr, PARSE_RESULT *imageType, int *imageLen, int *fNeedReset) { char buf[BUF_SIZE]; char bound[BOUND_SIZE]; char myTag[16] = {0}; int boundSize = 0; unsigned int uploadSize = 0; int byteRd = 0; char *pdest = NULL; UPLOAD_RESULT result = UPLOAD_OK; char *curPtr = NULL; int flashSize = 0; bound[0] = '\0'; buf[0] = '\0'; fgets(bound, BOUND_SIZE, stream); boundSize = strlen(bound) - 2; if (boundSize <= 0) { printf("Failed to find bound !!!\n"); return UPLOAD_FATAL; // fatal } bound[boundSize] = '\0'; // get Content-Disposition: form-data; name="filename"; filename="test" // check filename, if "", user click no filename and report fgets(buf, BUF_SIZE, stream); if ((pdest = strstr(buf, FN_TOKEN)) == NULL) { printf("No filename ? \n"); return UPLOAD_FATAL; // fatal } else { pdest += (FN_TOKEN_LEN - 1); if (*pdest == '"' && *(pdest + 1) == '"') { printf("No filename selected\n"); result = UPLOAD_FAIL_NO_FILENAME; } else printf("\nfilename = %s\n", pdest); } // get [Content-Type: application/octet-stream] and NL (cr/lf) and discard them fgets(buf, BUF_SIZE, stream); fgets(buf, BUF_SIZE, stream); //Get prevail digital signature fgets(buf, 17, stream); memcpy(myTag, buf, 16); // add some overhead for the w image and sub bound size from upload_len upload_len -= boundSize; flashSize = sysFlashSizeGet(); if (upload_len > flashSize) { printf("Size is over by %d\n", upload_len - flashSize); result = UPLOAD_FAIL_ILLEGAL_IMAGE; *fNeedReset = FALSE; } else if (upload_len < MIN_UPLOAD_LEN && upload_type == WEB_UPLOAD_IMAGE) // for fake file or just the path without file name. { if( UPLOAD_FAIL_NO_FILENAME != result ) { printf("Wrong file or illegal size [%d]\n", upload_len); result = UPLOAD_FAIL_ILLEGAL_IMAGE; } *fNeedReset = FALSE; } else if( verifyTag(myTag, 16) == BOOL_FALSE ) { dumpHex((unsigned char *)myTag, 16); printf("Wrong file formet\n"); result = UPLOAD_FAIL_ILLEGAL_IMAGE; *fNeedReset = FALSE; } else if (result == UPLOAD_OK) { printf("upload start with len = %d with flash size = %d ****\n", upload_len, flashSize); // only kill processes when upload image (but not for upload configurations) if ( upload_type == WEB_UPLOAD_IMAGE ) { bcmKillAllApps(); printf("Done removing processes\n"); *fNeedReset = TRUE; } printf("Allocating %d byte buffer\n", upload_len); curPtr = (char *) malloc(upload_len); if( curPtr == NULL ) { printf("Failed to allocate memory for the image. Size required: [%d]\n", upload_len); result = UPLOAD_FAIL_NO_MEM; } else { *imageBufPtrPtr = curPtr; printf("Memory allocated\n"); memcpy(curPtr, myTag, 16); curPtr += 16; uploadSize += 16; } } while(fgets(buf, BUF_SIZE, stream)) { pdest = memchr(buf, 0xa, BUF_SIZE); if (pdest == NULL) byteRd = BUF_SIZE - 1; // last byte not count! else byteRd = pdest - buf + 1; // include 0xa // search for bound... if ((pdest = memchr(buf, '-', byteRd)) != NULL) { if (strstr(buf, bound) != NULL) { if (byteRd > (boundSize + 2) && *(buf + boundSize) == '-' && *(buf + boundSize + 1) == '-') { //printf("bound is found in %s with len = %d.\n", buf, byteRd); uploadSize -= 2; break; } else printf("Failed finding bound ?\n"); } } if (result != UPLOAD_OK) continue; // just throw away the data and search for end of bound else // move the data to the imageBuf { memcpy(curPtr, buf, byteRd); curPtr += byteRd; uploadSize += byteRd; if (uploadSize > upload_len) // try not to over flow the buffer { printf("Failed on over sized image ?\n"); result = UPLOAD_FAIL_ILLEGAL_IMAGE; } } } printf("upload size = %d\n", uploadSize); #ifdef DEBUG_UPLOAD if( uploadSize > 0 ) { if( *imageBufPtrPtr ) { dumpHex((unsigned char *)*imageBufPtrPtr, (uploadSize<64)?uploadSize:64); } } #endif // parse the image data if (result == UPLOAD_OK) { *imageType = BROADCOM_IMAGE_FORMAT; *imageLen = uploadSize; *fNeedReset = TRUE; } if (result != UPLOAD_OK && *fNeedReset == TRUE) result = UPLOAD_FATAL; printf("result = %d\n", result); return result; }