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

📄 update386.c

📁 arm9软件自动升级功能的例子。 实现arm9软件的自动升级
💻 C
📖 第 1 页 / 共 2 页
字号:
/*Copyright 当代天启(北京) 2008主要功能:维护下接的386软件版本,实现386软件在线升级作者:周天民生成日期:2008年10月23日修改记录:*/#include <stdio.h>#include <unistd.h>#include <sys/stat.h>#include <sys/types.h>#include <fcntl.h>#include <pthread.h>#include <stdlib.h>#include "debug_level.h"#include "pcap.h"#include "lcom.h"#include <net/ethernet.h>#include <net/if.h>#include <sys/ioctl.h>  #include <string.h>#include <sys/socket.h>#include "../dhcp/sniff.h"/*for byte's orderliness when allloc a buffer of a package */#define ALLIGNMENT(addr)  (u_char*)((uint32_t)(addr) - (uint32_t)(addr) % 4 + 4)  /*588的386ip*/#define IPADDR_386GATE 0x0102a8c0/*令牌信号宏定义*/#define GIVETOKEN SIGCONT/*386数量最大值宏定义*/#define MAX386NUM 8/*主线程通信端口宏定义*/#define MAINTHREADUPDPORT 4455/*第一个升级线程通信端口宏定义*/#define FIRSTTHREADUPDPORT 4456/*文件名全局变量 */char *g386version = "/tmp/588/version386.conf";char *g386software = "/tmp/588/soft386.bin";/*当前最新的386版本*/char cur386ver[10] = {0};/*发包缓存,初始化时设置包头各字段*/u_char up386sbuf[2][ETH_HLEN + IP_HLEN +UDP_HLEN +16];/*线程相关,mac386表示该线程对应的386的mac;udpport表示该线程使用的udp端口ifbeused表示该线程是否已经被使用,0表示未使用,非0表示正在使用*/struct stThread{		unsigned char mac386[6];	unsigned short udpPort;	char ifBeUsed;};struct stThread threadbook[MAX386NUM];/*本地socket通信id*/static int update386_local_sock_fd= 0;/*调试信息级别第2位*/#define DEBUGLEVEL2 2/*操作命令字*/#define UP386_ASKIFNEED 1 /*询问升级命令,占用十个字节(由juno288发送)*/#define UP386_NEEDNOTPDATE 2 /*通知juno288不需要升级(由588发送)*/#define UP386_NEEDUPDATE 3 /*通知juno288需要升级(由588发送)*/#define UP386_PLEASESEND 4 /*通知588现在可以开始发送升级包(由juno288发送)*/#define UP386_ALLPACKEND 5 /*通知juno288升级包发送结束(由588发送)*/#define UP386_DOWNLOADEND 6 /*通知588已经全部下载结束(由juno288发送)*/#define UP386_DATAACK 7 /*正常数据包的ack(由juno288发送)*/#define UP386_DATA 8 /*正常数据包(由588发送)*//*ip头序号*/static u_short ipheadid=0;static pcap_t *pup386 = NULL ; char update386filter_exp[] = "udp dst port 4455 && dst host 192.168.2.1";char update386dev[] = "eth0";unsigned short checksum(unsigned short *buf,int nword){	unsigned long sum;	for(sum=0;nword>0;nword--)		sum += *buf++;	sum = (sum>>16) + (sum&0xffff);	sum += (sum>>16);	return ~sum;}pcap_t* pcap_start(const char* dev, char *filter_exp){	char errbuf[PCAP_ERRBUF_SIZE];		/* error buffer */	pcap_t *handle;				/* packet capture handle */	struct bpf_program fp;			/* compiled filter program (expression) */	bpf_u_int32 mask;			/* subnet mask */	bpf_u_int32 net;			/* ip */	if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {		fprintf(stderr, "Couldn't get netmask for device %s: %s\n",				dev, errbuf);		net = 0;		mask = 0;	}	/* print capture info */	pd(DEBUGLEVEL2,"Device: %s\n", dev);	pd(DEBUGLEVEL2,"Filter expression: %s\n", filter_exp);	/* open capture device */	handle = pcap_open_live(dev, SNAP_LEN, 0, 1000, errbuf);	if (handle == NULL) {		fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);		exit(EXIT_FAILURE);	}	pd(DEBUGLEVEL2,"cpcap_open_live ok!\n");	/* make sure we're capturing on an Ethernet device [2] */	if (pcap_datalink(handle) != DLT_EN10MB) {		fprintf(stderr, "%s is not an Ethernet\n", dev);		exit(EXIT_FAILURE);	}	pd(DEBUGLEVEL2,"pcap_datalink ok!\n");	/* compile the filter expression */	if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {		fprintf(stderr, "Couldn't parse filter %s: %s\n",				filter_exp, pcap_geterr(handle));		exit(EXIT_FAILURE);	}	pd(DEBUGLEVEL2,"pcap_compile ok!\n");	/* apply the compiled filter */	if (pcap_setfilter(handle, &fp) == -1) {		fprintf(stderr, "Couldn't install filter %s: %s\n",				filter_exp, pcap_geterr(handle));		exit(EXIT_FAILURE);	}	pd(DEBUGLEVEL2,"pcap_setfilter ok!\n");	return handle;}/*主要功能:比较两个版本,决定是否需要升级输入:cur ,收到的版本,newver,保存的版本输出:NULL返回值:1表示需要升级,-1表示版本号错误,其他值表示不需升级*/int vercmp386(char *cur, char * newver){	if(( strcmp(cur,newver) )<0)		return 1;	if(( strcmp(cur,newver) )>0)		return 0;	return 0;}/*get version ,return 0:ok; return -1:error*/int get386Version(char *ver){	struct stat *fstat = NULL;	FILE* f = NULL;			char line[128] = {0}; //read a line from file	/*open ipfile*/	fstat = (struct stat* )malloc(sizeof(struct stat));	if (fstat  == NULL) 	{		pd(DEBUGLEVEL2,"can't malloc space for struct stat\n");		return -1;	}	if (( stat(g386version,fstat) < 0) )	{		pd(DEBUGLEVEL2,"read version  file %s err\n",g386version);		pe("stat:");				free(fstat);		return -1;	}	f = fopen(g386version,"r");	if ( f== NULL)	{		pd(DEBUGLEVEL2,"open version file %s err\n",g386version);		pe("fopen");				free(fstat);		return -1;	}	file_rlock(fileno(f));	while (fscanf(f,"%s\n",line) >0)	{		pd(DEBUGLEVEL2,"line = %s, ",line);		strcpy(ver,line);	}		free(fstat);	fclose(f);	return 0;}/*主要功能:初始化线程记录数组输入:null输出:null返回值:null*/void init_thread_book(){	int i = 0;	unsigned short thisudpport = FIRSTTHREADUPDPORT;	for(i = 0;i<MAX386NUM;i++)	{		memset(threadbook[i].mac386,0,6);		threadbook[i].udpPort = thisudpport++;		threadbook[i].ifBeUsed = 0;	}	return;}/*主要功能:初始化发包缓存,设置各个公用字段输入:null输出:null返回值:null*/void sbuf_init(){	struct ether_header *eth_out = NULL;	struct sniff_ip *ip_out = NULL;	struct udphdr *udp_out = NULL;	u_char * buf = NULL;		int i = 0;	int sock,   ret;   	struct ifreq ifr;   	sock   =   socket(   AF_INET,   SOCK_STREAM,   0   );   	if   (   sock   <   0   )  	{   		pe("getmac socket");		return;   	}   	memset(   &ifr,   0,   sizeof(ifr)   );   	strcpy(   ifr.ifr_name,   "eth0"   );   	ret   =   ioctl(   sock,   SIOCGIFHWADDR,   &ifr,   sizeof(ifr)   );   	if   (   ret   !=   0   )   	{   		pe("get mac error");		return;	}   		for (i=0;i<2;i++) 	{		buf = ALLIGNMENT(up386sbuf[i]) + 2;		eth_out = (struct ether_header *)buf;		ip_out = (struct sniff_ip *) (buf + ETH_HLEN);		udp_out = (struct udphdr *) (buf +ETH_HLEN + IP_HLEN);		memcpy(eth_out->ether_shost,ifr.ifr_hwaddr.sa_data,ETH_ALEN);		memset(eth_out->ether_dhost,0xff,ETH_ALEN);		eth_out->ether_type = htons(0x0800);		ip_out->ip_vhl = 0x45;		ip_out->ip_tos = 0x00;		ip_out->ip_len = htons(IP_HLEN + UDP_HLEN + 4);		ip_out->ip_id = 0;		ip_out->ip_off = 0x00;		ip_out->ip_ttl = 128;		ip_out->ip_p = 0x11;		ip_out->ip_sum = 0;  //need to add check sum		ip_out->ip_dst.s_addr = 0;		ip_out->ip_src.s_addr = 0;		udp_out->source = htons(MAINTHREADUPDPORT);		udp_out->dest = htons(MAINTHREADUPDPORT);		udp_out->len = htons(UDP_HLEN + 4);		udp_out->check = 0;				pd(DEBUGLEVEL2,"init sbuf%d:\n",i); 	}	return;}/** *主要功能:开始升级 *输入:NULL *输出:NULL *返回值:NULL */void *startUpdate(void * arg){	int xb= *((int *)arg);	unsigned short udpport  =  threadbook[xb].udpPort;	int sockfd;	struct sockaddr_in servaddr, cliaddr;	char rec[128] = {0};		int reclen = sizeof(cliaddr);	int n,i,j;	char *ptmp = rec;	int time0,time1;	int fd;	int readlen=0;	int sendret = 0;	char updateend = UP386_ALLPACKEND;	unsigned long sendbuf[256] ;	unsigned char *sendhead = sendbuf ;	unsigned short * packnum = (unsigned short * )(sendhead +2);	unsigned short * packlen = (unsigned short * )(sendhead +4);	char *senddata = sendhead + 6;	unsigned short packnumcount =0;	int enable = 1;	sockfd = socket(AF_INET, SOCK_DGRAM, 0); /* create a socket */		/* init servaddr */	bzero(&(servaddr.sin_zero), 8);	servaddr.sin_family = AF_INET;	servaddr.sin_addr.s_addr = htonl(0xc0a80201);	servaddr.sin_port = htons(udpport);		/* bind address and port to socket */	if(bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) <0)	{		pe("bind\n"); 		goto endthread;	}	pd(DEBUGLEVEL2,"bindok,port = %d\n",udpport);	/*等待juno288请求升级的命令,5秒内收不到请求升级包,则关闭该线程*/	time0=time(NULL);	while(1)	{		n = recvfrom(sockfd, rec, 128, 0,(struct sockaddr *)(&cliaddr), &reclen);		pd(DEBUGLEVEL2,"got a pack from port :%d\n",udpport);		if((n>=0)&&(rec[0] == UP386_PLEASESEND))		{			break;		}		time1 = time(NULL);		if(time1-time0>50)		{			pd(DEBUGLEVEL2,"has wait 5sec ,not rec a PLEASESEND PACK");			goto endthread;		}		sleep(1);	};	pd(DEBUGLEVEL2,"recv please pack\n");	/*开始发送升级包*/	fd = open(g386software, O_RDWR);	if (fd < 0) 	{		pe("Can't open %s", g386software);		goto endthread;	}	pd(DEBUGLEVEL2,"open ok ,start to send pack :%s\n",g386software);	while((readlen = read(fd,(void *)senddata,256))>0)	{		packnumcount +=1;		*packnum = packnumcount;		pd(DEBUGLEVEL2,"\npacknumcount = %d,fuwanzhi = %d\n",packnumcount,*packnum);		*packlen = readlen;		sendhead[0] = UP386_DATA;		for(i = 0; i<3;i++)		{			sendret = sendto(sockfd, sendbuf, readlen + 6, 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr));			if(sendret != readlen+6)			{				pe("sendto");				continue;			}			sleep(2);			pd(DEBUGLEVEL2,"send a pack,count = %d\n",packnumcount);			for(j = 0;j<sendret;j++)			{				pd(DEBUGLEVEL2,"%2x  ",sendhead[j]);			}			n = recvfrom(sockfd, rec, 128, 0,(struct sockaddr *)(&cliaddr), &reclen);			pd(DEBUGLEVEL2,"recv a pack,count = %d\n",n);			for(j = 0;j<n;j++)			{				pd(DEBUGLEVEL2,"%2x  ",rec[j]);			}			if((n>=4)&&(rec[0] == UP386_DATAACK))			{				ptmp = rec;				ptmp +=2;				if(*((unsigned short *)ptmp) == packnumcount)				{					break;				}				pd(DEBUGLEVEL2,"\nsend count %d ,rec count %d\n ",packnumcount,*((unsigned short *)ptmp) );			}		}		if(i >=3)		{

⌨️ 快捷键说明

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