⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 netflash.c

📁 通过网络刷新flash的工具源代码.linux下使用的
💻 C
📖 第 1 页 / 共 4 页
字号:
	if (lhdr.magic != htons(LITTLE_CRYPTO_MAGIC)) {#ifdef CONFIG_USER_NETFLASH_CRYPTO_OPTIONAL		add_data(file_length, (char *)&lhdr,				sizeof(struct little_header));		file_length += sizeof(struct little_header);		return;#else		error("size magic incorrect");		exit_failed(BAD_CRYPT_MAGIC);#endif	}	{		unsigned short hlen = ntohs(lhdr.hlen);		char tmp[hlen];		char t2[hlen];		int len;		extract_data(hlen, tmp);		len = RSA_public_decrypt(hlen, tmp, t2,				pkey, RSA_PKCS1_PADDING);		if (len == -1) {			error("decrypt failed");			exit_failed(BAD_DECRYPT);		}		if (len != sizeof(struct header)) {			error("Length mismatch %d %d\n", (int)sizeof(struct header), len);		}		memcpy(&hdr, t2, sizeof(struct header));	}	RSA_free(pkey);	if (hdr.magic != htonl(CRYPTO_MAGIC)) {		error("image not cryptographically enabled");		exit_failed(NO_CRYPT);	}	/* Decrypt image if needed */	if (hdr.flags & FLAG_ENCRYPTED) {		aes_context ac;		char cin[AES_BLOCK_SIZE];		char cout[AES_BLOCK_SIZE];		unsigned long s;		if ((file_length % AES_BLOCK_SIZE) != 0) {			error("image size not miscable with cryptography");			exit_failed(BAD_CRYPT);		}		aes_set_key(&ac, hdr.aeskey, AESKEYSIZE, 0);		/* Convert the body of the file */		for (fb = fileblocks, s = 0; s<file_length; s += AES_BLOCK_SIZE) {			get_block(fb, s, cin, AES_BLOCK_SIZE);			aes_decrypt(&ac, cin, cout);			fb = put_block(fb, s, cout, AES_BLOCK_SIZE);		}	}	/* Remove padding */	if (hdr.padsize) remove_data(hdr.padsize);	/* Check MD5 sum if required */	{		MD5_CTX ctx;		unsigned char hash[16];		if (fileblocks != NULL && file_length >= 16) {			MD5_Init(&ctx);			for (fb = fileblocks; fb != NULL; fb = fb->next)				MD5_Update(&ctx, fb->data, fb->length);			MD5_Final(hash, &ctx);			if (memcmp(hdr.md5, hash, MD5_DIGEST_LENGTH) != 0) {				error("bad MD5 signature");				exit_failed(BAD_MD5_SIG);			}		}	}	printf("netflash: signed image approved\n");}#endif#ifdef CONFIG_USER_NETFLASH_DECOMPRESS/* Read the decompressed size from the gzip format */int decompress_size(){    unsigned char *sp = 0, *ep;    int	i, total, size;    struct fileblock_t *fb;    /* Get a pointer to the start of the inflated size */    total = 0;    size = 0;    if (fileblocks != NULL && file_length >= 4) {		for (fb = fileblocks; fb != NULL; fb = fb->next) {			if ((total + fb->length) >= (file_length - 4)) {				sp = fb->data + (file_length - total - 4);				break;			}			total += fb->length;		}		if (fb) {			ep = fb->data + fb->length;			for (i = 0; i < 4; i++) {				if (sp >= ep) {					fb = fb->next;					sp = fb->data;					ep = sp + fb->length;				}				size |= (*sp++) << (8*i);			}		}    }    return size;}/* *	Skip bytes, ensuring at least 1 byte remains to be read. *	Don't use this to skip past the last byte in the file. */int decompress_skip_bytes(int pos, int num){    while (zfb) {		if (pos + num < zfb->length)			return pos + num;				num -= zfb->length - pos;		pos = 0;		zfb = zfb->next;    }    error("compressed image is too short");	exit_failed(IMAGE_SHORT);	return 0;}int decompress_init(){    int pos, flg, xlen, size;    zfb = fileblocks;    pos = 0;	    /* Skip over gzip header */    pos = decompress_skip_bytes(pos, 2);	    if (zfb->data[pos] != 8) {		error("image is compressed, unknown compression method");		exit_failed(UNKNOWN_COMP);    }    pos = decompress_skip_bytes(pos, 1);	    flg = zfb->data[pos];    pos = decompress_skip_bytes(pos, 1);	    /* Skip mod time, extended flag, and os */    pos = decompress_skip_bytes(pos, 6);	    /* Skip extra field */    if (flg & 0x04) {		xlen = zfb->data[pos];		pos = decompress_skip_bytes(pos, 1);		xlen += zfb->data[pos]<<8;		pos = decompress_skip_bytes(pos, 1+xlen);    }	    /* Skip file name */    if (flg & 0x08) {		while (zfb->data[pos])			pos = decompress_skip_bytes(pos, 1);		pos = decompress_skip_bytes(pos, 1);    }	    /* Skip comment */    if (flg & 0x10) {		while (zfb->data[pos])			pos = decompress_skip_bytes(pos, 1);		pos = decompress_skip_bytes(pos, 1);    }	    /* Skip CRC */    if (flg & 0x02) {		pos = decompress_skip_bytes(pos, 2);    }	    z.next_in = zfb->data + pos;    z.avail_in = zfb->length - pos;    z.zalloc = Z_NULL;    z.zfree = Z_NULL;    z.opaque = Z_NULL;    if (inflateInit2(&z, -MAX_WBITS) != Z_OK) {		error("image is compressed, decompression failed");		exit_failed(BAD_DECOMP);    }        size = decompress_size();    if (size <= 0) {		error("image is compressed, decompressed length is invalid");		exit_failed(BAD_DECOMP);    }    return size;}int decompress(char* data, int length){    int rc;    z.next_out = data;    z.avail_out = length;    for (;;) {		while (z.avail_in == 0) {			zfb = zfb->next;			if (!zfb) {				error("unexpected end of file for decompression");				exit_failed(BAD_DECOMP);			}			z.next_in = zfb->data;			z.avail_in = zfb->length;		}		rc = inflate(&z, Z_SYNC_FLUSH);				if (rc == Z_OK) {			if (z.avail_out == 0)				return length;						if (z.avail_in != 0) {				/* Note: This shouldn't happen, but if it does then				 * need to add code to add another level of buffering				 * that we append file blocks to...				 */				error("decompression deadlock");				exit_failed(BAD_DECOMP);			}		}		else if (rc == Z_STREAM_END) {			return length - z.avail_out;		}		else {			error("error during decompression: %x", rc);			exit_failed(BAD_DECOMP);		}    }}int check_decompression(int doinflate){	if (doinflate) {		if (fileblocks->length >= 2				&& fileblocks->data[0] == gz_magic[0]				&& fileblocks->data[1] == gz_magic[1]) {			image_length = decompress_init();			notice("image is compressed, decompressed length=%ld\n",					image_length);		} else {			notice("image is not compressed");		}	}#ifdef CONFIG_USER_NETFLASH_AUTODECOMPRESS	else if (fileblocks->length >= 2			&& fileblocks->data[0] == gz_magic[0]			&& fileblocks->data[1] == gz_magic[1]) {		doinflate = 1;		image_length = decompress_init();		notice("image is compressed, decompressed length=%ld\n",				image_length);	}#endif	else {		image_length = file_length;	}	return doinflate;}#endif/****************************************************************************//* *	Local copies of the open/close/write used by tftp loader. *	The idea is that we get tftp to do all the work of getting *	the file over the network. The following code back ends *	that process, preparing the read data for FLASH programming. */int local_creat(char *name, int flags){	return(fileno(nfd));}FILE *local_fdopen(int fd, char *flags){	return(nfd);}FILE *local_fopen(const char *name, const char *flags){	return(nfd);}int local_fclose(FILE *fp){	printf("\n");	fflush(stdout);	sleep(1);	return(0);}int local_fseek(FILE *fp, int offset, int whence){	/* Shouldn't happen... */	return(0);}int local_putc(int ch, FILE *fp){	/* Shouldn't happen... */	return(0);}int local_write(int fd, char *buf, int count){  add_data(file_offset, buf, count);  file_offset += count;  if (file_offset > file_length)	  file_length = file_offset;  return(count);}/****************************************************************************/ extern int tftpmain(int argc, char *argv[]);extern int tftpsetbinary(int argc, char *argv[]);extern int tftpget(int argc, char *argv[]);/* * Call to tftp. This will initialize tftp and do a get operation. * This will call the local_write() routine with the data that is * fetched, and it will create the ioctl structure. */int tftpfetch(char *srvname, char *filename){  char	*tftpargv[8];  int	tftpmainargc = 0;  tftpverbose = 0;	/* Set to 1 for tftp trace info */  tftpargv[tftpmainargc++] = "tftp";  tftpargv[tftpmainargc++] = srvname;#ifdef CONFIG_USER_NETFLASH_SETSRC  if (srcaddr != NULL)	tftpargv[tftpmainargc++] = srcaddr;#endif  tftpmain(tftpmainargc, tftpargv);  tftpsetbinary(1, tftpargv);    notice("fetching file \"%s\" from %s\n", filename, srvname);  tftpargv[0] = "get";  tftpargv[1] = filename;  tftpget(2, tftpargv);  return(0);}/****************************************************************************/ extern int ftpmain(int argc, char *argv[]);extern void setbinary(void);extern void get(int argc, char *argv[]);extern void quit(void);/* * Call to ftp. This will initialize ftp and do a get operation. * This will call the local_write() routine with the data that is * fetched, and it will create the ioctl structure. */int ftpconnect(char *srvname){#ifdef FTP  char	*ftpargv[4];  ftpverbose = 0;	/* Set to 1 for ftp trace info */  notice("login to remote host %s", srvname);  ftpargv[0] = "ftp";  ftpargv[1] = srvname;  ftpmain(2, ftpargv);  return(0);#else  error("no ftp support builtin");  return(-1);#endif /* FTP */}int ftpfetch(char *srvname, char *filename){#ifdef FTP  char	*ftpargv[4];  ftpverbose = 0;	/* Set to 1 for ftp trace info */  notice("ftping file \"%s\" from %s", filename, srvname);  setbinary(); /* make sure we are in binary mode */  ftpargv[0] = "get";  ftpargv[1] = filename;  get(2, ftpargv);  quit();  return(0);#else  error("no ftp support builtin");  return(-1);#endif /* FTP */}/****************************************************************************/extern int openhttp(char *url);/* *	When fetching file we need to even number of bytes in write *	buffers. Otherwise FLASH programming will fail. This is mostly *	only a problem with http for some reason. */int filefetch(char *filename){  int fd, i, j;  unsigned char buf[1024];  if (strncmp(filename, "http://", 7) == 0)    fd = openhttp(filename);  else    fd = open(filename, O_RDONLY);  if (fd < 0)    return(-1);  for (;;) {    printf(".");    if ((i = read(fd, buf, sizeof(buf))) <= 0)      break;    if (i & 0x1) {	/* Read more to make even sized buffer */	if ((j = read(fd, &buf[i], 1)) > 0)		i += j;    }    add_data(file_offset, buf, i);	file_offset += i;	file_length = file_offset;  }  close(fd);  printf("\n");  return(0);}/****************************************************************************/int samedev(struct stat *stat_dev, struct stat *stat_rootfs){	if (S_ISBLK(stat_dev->st_mode)) {		if (stat_dev->st_rdev == stat_rootfs->st_dev) {			return 1;		}#if defined(CONFIG_NFTL_RW)		/* Check for writing to nftla, with an nftla partition		 * as the root device. */		else if (major(stat_dev->st_rdev) == NFTL_MAJOR				&& major(stat_rootfs->st_dev) == NFTL_MAJOR				&& minor(stat_dev->st_rdev) == 0) {			return 1;		}#endif	}#if defined(CONFIG_MTD) || defined(CONFIG_MTD_MODULES)	/* Check for matching block/character mtd devices. */	else if (S_ISCHR(stat_dev->st_mode)) {		if (major(stat_dev->st_rdev) == MTD_CHAR_MAJOR				&& major(stat_rootfs->st_dev) == MTD_BLOCK_MAJOR				&& (minor(stat_dev->st_rdev) >> 1)					== minor(stat_rootfs->st_dev)) {			return 1;		}	}#endif	return 0;}/* *	Check if we are writing to the root filesystem. */int flashing_rootfs(char *rdev){	static struct stat stat_rootfs, stat_flash;	/* First a generic check:	 * is the rootfs device the same as the flash device?	 */	if (stat("/", &stat_rootfs) != 0) {		error("stat(\"/\") failed (errno=%d)", errno);		exit_failed(BAD_ROOTFS);	}	if (samedev(&stat_rdev, &stat_rootfs))		return 1;	/* Secondly, a platform specific check:	 * /dev/flash/all and /dev/flash/image and /dev/flash/rootfs	 * can overlap, check if we are writing to any of these, and the	 * root device is /dev/flash/image or /dev/flash/rootfs.	 * XXX: checking device numbers would be better than strcmp */	else if (!strcmp(rdev, "/dev/flash/all")			|| !strcmp(rdev, "/dev/flash/image")			|| !strcmp(rdev, "/dev/flash/rootfs")) {		if (stat("/dev/flash/image", &stat_flash) == 0				&& samedev(&stat_flash, &stat_rootfs))			return 1;		if (stat("/dev/flash/rootfs", &stat_flash) == 0				&& samedev(&stat_flash, &stat_rootfs))			return 1;	}	return 0;}/****************************************************************************//* *	Search for a process and send a signal to it. */int killprocname(const char *name, int signo){	DIR *dir;	struct dirent *entry;	FILE *f;	char path[32];	char line[64];	int ret = 0;	dir = opendir("/proc");	if (!dir)		return 0;	while ((entry = readdir(dir)) != NULL) {		if (!isdigit(*entry->d_name))			continue;		sprintf(path, "/proc/%s/status", entry->d_name);		if ((f = fopen(path, "r")) == NULL)			continue;		while (fgets(line, sizeof(line), f) != NULL) {			if (line[strlen(line)-1] == '\n') {				line[strlen(line)-1] = '\0';				if (strncmp(line, "Name:\t", 6) == 0						&& strcmp(line+6, name) == 0) {					kill(atoi(entry->d_name), signo);					ret = 1;				}			}		}		fclose(f);	}	closedir(dir);	return ret;}/****************************************************************************//* *  Read a process pid file and send a signal to it. */void killprocpid(char *file, int signo){    FILE* f;    pid_t pid;	char value[16];    f = fopen(file, "r");    if (f == NULL)        return;    if (fread(value, 1, sizeof(value), f) > 0) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -