Beispiel #1
0
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);
}
Beispiel #2
0
// 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;
}