Ejemplo n.º 1
0
/**
 * @brief  解析IP头
 * @param  ptr: IP头结构体指针,用来存放解析后的数据 
 * @param  offset: 偏移量指针,表示IP头信息在buffer中的偏移量
 * @retval 错误标志,mIP_OK: 成功, mIP_ERROR: 失败
 */
mIPErr IP_analyzeHead(IPHeadStruct *ptr, UINT32 *offset)
{
	UINT8 *buf = mIP.buf + *offset;

	ptr->version = (UINT8)(*buf >> 4);
	ptr->headLength = *buf++ & 0x0F;
    ptr->diffServices = *buf++;
	ptr->totalLength = MKUINT16BIG(buf);
	buf += 2;
	ptr->identification = MKUINT16BIG(buf);
	buf += 2;
	ptr->flag = *buf >> 5;
	ptr->offset = ((UINT16)(*buf & 0x1F) << 8) | (UINT16)(*(buf + 1));
	buf += 2;
	ptr->timeToLive = *buf++;
	ptr->protocol = *buf++;
	ptr->checkSum = MKUINT16BIG(buf);
	buf += 2;
	bufCopy(ptr->srcAdd, buf, 4);
	buf += 4;
	bufCopy(ptr->dstAdd, buf, 4);
	buf += 4;
    *offset += ptr->headLength * 4;
	
	return mIP_OK;
}
Ejemplo n.º 2
0
/**
 * @brief  通过IP头结构体制作IP头到buffer中
 * @param  ptr: IP头结构体指针
 * @param  offset: buffer中偏移量指针 
 * @retval none
 */
void IP_makeHead(IPHeadStruct *ptr, UINT32 *offset)
{
	UINT8 *buf = mIP.buf + *offset;
	UINT16 sum;
	
	*buf++ = (ptr->version << 4) | ptr->headLength;
	*buf++ = ptr->diffServices;
	UINT16TOPTRBIG(buf, ptr->totalLength);
	buf += 2;
	UINT16TOPTRBIG(buf, ptr->identification);
	buf += 2;
	UINT16TOPTRBIG( buf, (((UINT16)ptr->flag << 5) | (ptr->offset & 0x1FFF)) );
	buf += 2;
	*buf++ = ptr->timeToLive;
	*buf++ = ptr->protocol;
	UINT16TOPTRBIG(buf, 0x0000);  /* 首部校验和先设置为0 */
	buf += 2;
	bufCopy(buf, ptr->srcAdd, 4);
	buf += 4;
	bufCopy(buf, ptr->dstAdd, 4);
	buf += 4;
	
	sum = calcuCheckSum(mIP.buf + *offset, ptr->headLength * 4); /* 计算首部校验和 */
	UINT16TOPTRBIG((mIP.buf + *offset + 10), sum);

	*offset = buf - mIP.buf;
}
Ejemplo n.º 3
0
/**
 * @brief  解析ARP首部 
 * @param  ptr: ARP首部结构体指针,接收解析后数据
 * @param  offset: buffer偏移量指针
 * @retval 错误标志,mIP_OK: 成功, mIP_ERROR: 失败
 */
static mIPErr ARP_analyzeHead(ARPHeadStruct *ptr, UINT32 *offset)
{
	UINT8 *buf = mIP.buf + *offset;

	ptr->hardwareType = MKUINT16BIG(buf);
	buf += 2;
	ptr->protocolType = MKUINT16BIG(buf);
	buf += 2;
	ptr->hardwareSize = *buf;
	buf += 1;
	ptr->protocolSize = *buf;
	buf += 1;
	ptr->opCode = MKUINT16BIG(buf);
	buf += 2;
	bufCopy(ptr->senderMACAdd, buf, 6);
	buf += 6;
	bufCopy(ptr->senderIPAdd, buf, 4);
	buf += 4;
	bufCopy(ptr->targetMACAdd, buf, 6);
	buf += 6;
	bufCopy(ptr->targetIPAdd, buf, 4);
	buf += 4;
	*offset = buf - mIP.buf;

	return mIP_OK;
}
Ejemplo n.º 4
0
/**
 * @brief  添加一条IP和MAC到ARP高速缓存中,如果缓存已满则清空缓存并添加到起始位置 
 * @param  addIP: 添加的IP
 * @param  macBuf: 对应IP的MAC地址
 * @retval none
 */
void ARP_addCache(UINT8 *addIP, UINT8 *macBuf)
{
	if(mIP.arpCache.num >= ARP_CACHE_MAXNUM) { /* 如果超过了缓存最大允许条目,则设置缓存条目为0(清空缓存) */
		mIP.arpCache.num = 0;
		mIP.arpCache.arpUpdataTime = myTCPIP_getTime(); /* 更新缓存时间 */
	}
	/* 把刚查询的IP,MAC信息记录到缓存中 */
	bufCopy(mIP.arpCache.ip[mIP.arpCache.num], addIP, 4);
	bufCopy(mIP.arpCache.mac[mIP.arpCache.num], macBuf, 6);
	mIP.arpCache.num++;
}
Ejemplo n.º 5
0
/**
 * @brief  IP处理
 * @param  offset: buffer中偏移量指针 
 * @retval none
 */
void IP_process(UINT32 *offset)
{
	IPHeadStruct ip;
	UINT16 sum;
	
	sum = calcuCheckSum(mIP.buf + *offset, 20); /* IP只检验头部 */
	if(sum != 0) return; /* 校验不通过,丢弃此包 */

	IP_analyzeHead(&ip, offset); /* 解析IP固定的20byte头 */
	if(ARP_checkCache(ip.srcAdd, mIP.macTmp) == 0) { /* 检查请求的客户端的IP与MAC是否在ARP缓存中,如果不在则追加 */
		ARP_addCache(ip.srcAdd, mIP.macTmp);
	}
	
	if(bufMatch(ip.dstAdd, mIP.ip, 4) == 0) { /* 如果目标地址不是本机IP,丢弃 */
		return;
	}
	bufCopy(mIP.ipTmp, ip.srcAdd, 4); /* 临时存储客户端IP */ 
	
	if(ip.protocol == IP_PROTOCOL_ICMP) { /* 如果是ICMP协议(一般情况是ping本机) */
		ICMP_process(&ip, offset);
	}
	if((ip.protocol == IP_PROTOCOL_UDP) && (mIP.enFlag & ENFLAG_UDP)) {  /* UDP协议 */
		UDP_process(&ip, offset);
	}
	if((ip.protocol == IP_PROTOCOL_TCP) && (mIP.enFlag & ENFLAG_TCP)) {  /* TCP协议 */
		TCP_process(&ip, offset);
	}
}
Ejemplo n.º 6
0
/**
 * @brief  制作默认IP头,默认版本号为IPv4,首部大小为20byte,源IP为本机IP,生存时间为128
 * @param  totalLength: 数据的大小 
 * @param  identification: 标识符,维护在mIP.identification中,在分片发送时用同一标识符以便区分
 * @param  flag: 标志,只有3位有效,0x00或0x20表示后面没有分片, 0x01表示后面还有分片
 * @param  fOffset: 偏移量,表示不同分片在数据中的偏移量,只有13位有效,以8byte为单位,这样每个分片的长度位8字节的整数倍
 * @param  protocol: 高层使用的协议
 * @param  offset: buffer中偏移量指针
 * @retval none
 */
void IP_makeHeadDefault(UINT16 datLen, UINT16 identification, UINT8 flag, UINT16 fOffset, UINT8 protocol, UINT32 *offset)
{
	IPHeadStruct ip;
	ip.version = 4;
	ip.headLength = 5;
	ip.diffServices = 0x00;
	ip.totalLength = datLen + 20;
	ip.identification = identification;
	ip.flag = flag;
	ip.offset = fOffset;
	ip.timeToLive = 0x80;
	ip.protocol = protocol;
	ip.checkSum = 0x0000;
	bufCopy(ip.srcAdd, mIP.ip, 4);
	bufCopy(ip.dstAdd, mIP.ipTmp, 4);
	IP_makeHead(&ip, offset);         
}
Ejemplo n.º 7
0
/**
 * @brief  发送一个ARP查询,然后等待回应或超时
 * @param  dstIP: 目标IP地址
 * @param  macBuf: 用来接收目标IP对应的MAC地址
 * @retval 错误标志,mIP_OK: 成功, mIP_ERROR: 失败
 */
mIPErr ARP_request(UINT8 *dstIP, UINT8 *macBuf)
{
	ETHHeadStruct ethTmp;
	ARPHeadStruct arp;
	UINT32 offset = 0, len = 0, time = 0;
	UINT8  dstEthMac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
	UINT8  dstArpMac[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
	
	/* 载入ETH头 */
	bufCopy(ethTmp.dstAdd, dstEthMac, 6);
	bufCopy(ethTmp.srcAdd, mIP.mac, 6);
	ethTmp.type = PROTOCOL_TYPE_ARP;
	offset = 0;
	ETH_makeHead(&ethTmp, &offset);
	
	/* 载入ARP头 */
	arp.hardwareType = HARDWARE_TYPE_ETH;
	arp.protocolType = PROTOCOL_TYPE_IP;
	arp.hardwareSize = 6;
	arp.protocolSize = 4;
	arp.opCode       = ARP_OPCODE_REQ; /* 请求 */
	bufCopy(arp.senderMACAdd, mIP.mac, 6);
	bufCopy(arp.senderIPAdd, mIP.ip, 4);
	bufCopy(arp.targetMACAdd, dstArpMac, 6);
	bufCopy(arp.targetIPAdd, dstIP, 4);
	ARP_makeHead(&arp, &offset);	
    /* 发送ARP查询 */
	myTCPIP_sendPacket(mIP.buf, offset);
	
	/* 等待主机的回应 */
	time = myTCPIP_getTime();
	while(1) {
		len = myTCPIP_getPacket(mIP.buf, myICPIP_bufSize);
		if(len == 0) {
			if(myTCPIP_getTime() - time > ARP_TIMEWAIT || 
			mIP.arpCache.arpUpdataTime > myTCPIP_getTime()) { /* 如果等待超时或定时器溢出,则认为没有此主机 */
				return mIP_NOACK;
			}
			continue;
		}
		
		offset = 0; /* 设置buf的偏移量为0 */
		ETH_analyzeHead(&ETHHead, &offset);
		if(ETHHead.type == PROTOCOL_TYPE_ARP) { /* ARP协议 */
			ARP_analyzeHead(&arp, &offset);
			if(arp.opCode == ARP_OPCODE_REPLY) { /* 如果是回应操作 */
				if(bufMatch(arp.targetIPAdd, mIP.ip, 4)) { /* 如果请求的IP与本机相匹配 */
					bufCopy(macBuf, arp.senderMACAdd, 6);
					break;
				}
			}
		}
	}

	return mIP_OK;
}
Ejemplo n.º 8
0
/**
 * @brief  通过ARP首部结构体制作ARP首部到buffer中
 * @param  ptr: ARP首部结构体指针
 * @param  offset: buffer偏移量指针
 * @retval none
 */
static void ARP_makeHead(ARPHeadStruct *ptr, UINT32 *offset)
{
	UINT8 *buf = mIP.buf + *offset;
	
	UINT16TOPTRBIG(buf, ptr->hardwareType);
	buf += 2;
	UINT16TOPTRBIG(buf, ptr->protocolType);
	buf += 2;
	*buf++ = ptr->hardwareSize;
	*buf++ = ptr->protocolSize;
	UINT16TOPTRBIG(buf, ptr->opCode);
	buf += 2;
	bufCopy(buf, ptr->senderMACAdd, 6);
	buf += 6;
	bufCopy(buf, ptr->senderIPAdd, 4);
	buf += 4;
	bufCopy(buf, ptr->targetMACAdd, 6);
	buf += 6;
	bufCopy(buf, ptr->targetIPAdd, 4);	
	buf += 4;
	*offset = buf - mIP.buf;
}
Ejemplo n.º 9
0
/**
 * @brief  检查ARP高速缓存中是否有dstIP对应的MAC地址,并检查是否需要更新缓存 
 * @param  dstIP: 目标IP
 * @param  macBuf: 接收目标IP对应的MAC地址
 * @retval 1: 查询并获取成功 0:目标IP不在缓存中
 */
UINT8 ARP_checkCache(UINT8 *dstIP, UINT8 *macBuf)
{
	UINT16 i;
	
	/* 检查是否缓存是否过期 */
	if(myTCPIP_getTime() - mIP.arpCache.arpUpdataTime > (ARP_CACHE_UPDATETIME * 1000) || 
	mIP.arpCache.arpUpdataTime > myTCPIP_getTime()) { /* 如果到了缓存更新时间或者定时器溢出,清空缓存 */
		mIP.arpCache.num = 0;
		mIP.arpCache.arpUpdataTime = myTCPIP_getTime(); /* 更新缓存时间 */
		return 0;
	}
	
	/* 检查缓存中是否有对应IP */
	for(i = 0; i < mIP.arpCache.num; i++) {
		if(bufMatch(dstIP, mIP.arpCache.ip[i], 4)) {
			bufCopy(macBuf, mIP.arpCache.mac[i], 6);
			return 1;
		}
	}
	
	return 0;
}
Ejemplo n.º 10
0
/**
 * @brief  ARP回应,发送本机mac地址
 * @param  ptr: ARP首部结构体
 * @retval none
 */
static void ARP_reply(ARPHeadStruct *ptr)
{
	ETHHeadStruct ethTmp;
	UINT32 offset = 0;
	
	/* 载入ETH头 */
	bufCopy(ethTmp.dstAdd, ptr->senderMACAdd, 6);
	bufCopy(ethTmp.srcAdd, mIP.mac, 6);
	ethTmp.type = PROTOCOL_TYPE_ARP;
	offset = 0;
	ETH_makeHead(&ethTmp, &offset);
	
	/* 载入ARP头 */
	ptr->opCode = ARP_OPCODE_REPLY; /* 响应操作 */
	bufCopy(ptr->targetMACAdd, ptr->senderMACAdd, 6);
	bufCopy(ptr->targetIPAdd, ptr->senderIPAdd, 4);
	bufCopy(ptr->senderMACAdd, mIP.mac, 6);
	bufCopy(ptr->senderIPAdd, mIP.ip, 4);
	ARP_makeHead(ptr, &offset);
	/* 发送ARP响应 */
	myTCPIP_sendPacket(mIP.buf, offset);
}     
Ejemplo n.º 11
0
void
httpParseStream(HTTP *http, App *app, unsigned char *url)
{
	Buf		*buf;
	unsigned short	c;
	unsigned char	*contentType;
	int		chunked;
	int		i;
	unsigned char	*line;
	unsigned int	size;

	chunked = 0;
	c = httpReadHeaders(http, app, http->in, url, &contentType, &chunked);

	if (chunked)
	{
		buf = bufAlloc(-1);
		while (1)
		{
			bufMark(http->in, 0);
			c = bufGetByte(http->in);
			c = readLine(http->in, c);
			bufMark(http->in, -1);
			line = bufCopy(http->in);
			size = 0;
			sscanf((char *) line, "%x", &size);
			free(line);
			if (!size)
			{
				break;
			}
			bufUnGetByte(http->in);
			for (i = 0; i < size; i++)
			{
				c = bufGetByte(http->in);
				if (c == 256)
				{
					break;
				}
				else
				{
					bufPutChar(buf, c);
				}
			}
			c = bufGetByte(http->in);
			if (c != '\r')
			{
				break;
			}
			c = bufGetByte(http->in);
			if (c != '\n')
			{
				break;
			}
		}
		bufSet(buf, 0);
		bufMark(buf, 0);
	}
	else
	{
		buf = http->in;
	}
	http->body = bufCurrent(buf);

	if (contentType)
	{
		if
		(
			(contentType != emptyHTTPResponse) &&
			(contentType != http09Response) &&
			(contentType != locationURLWasAdded)
		)
		{
			app->contentType(app, contentType);
			if (!strcasecmp((char *) contentType, "text/html"))
			{
				htmlRead(app, buf, url);
			}
			else
			{
				httpDefaultType(http, app);
			}
			free(contentType);
		}
	}
	else
	{
		httpDefaultType(http, app);
	}

	if (chunked)
	{
		bufFree(buf);
	}

	app->printHTML(app, "</pre>");
}
Ejemplo n.º 12
0
static unsigned short
httpReadHeaders(HTTP *http, App *app, Buf *buf, unsigned char *url,
	unsigned char **ct, int *chunked)
{
	unsigned short	c;
	unsigned char	*charset;
	unsigned char	*contentType;
	int		locationFound;
	unsigned char	*name;
	URL		*rel;
	ContentType	*type;
	unsigned char	*value;
	char		*version;

	app->printHTML(app, "<h4>Response</h4>");
	app->printHTML(app, "<pre>");

	contentType = NULL;
	locationFound = 0;

	bufMark(buf, 0);
	c = bufGetByte(buf);
	if (c == 256)
	{
		*ct = emptyHTTPResponse;
		return c;
	}
	nonEmptyHTTPResponseCount++;
	c = readNonWhiteSpace(buf, c);
	bufMark(buf, -1);
	app->httpResponse(app, buf);
	version = (char *) bufCopy(buf);
	if (!strcmp(version, "HTTP/1.0"))
	{
	}
	else if (!strcmp(version, "HTTP/1.1"))
	{
	}
	else if (!strncmp(version, "HTTP/", 5))
	{
	}
	else
	{
		/* XXX deal with HTTP/0.9? */
		*ct = http09Response;
		return c;
	}
	free(version);
	http10OrGreaterCount++;
	c = readSpaceTab(buf, c);
	c = readNumber(buf, c, &http->status);
	c = readLine(buf, c);
	while (1)
	{
		if (c == 256)
		{
			bufMark(buf, 0);
			app->httpResponse(app, buf);
			break;
		}
		bufMark(buf, -1);
		app->httpResponse(app, buf);
		if ((c == '\r') || (c == '\n'))
		{
			readLine(buf, c);
			bufUnGetByte(buf);
			bufMark(buf, 0);
			app->httpResponse(app, buf);
			break;
		}
		while
		(
			(c != 256) &&
			(c != '\r') &&
			(c != '\n') &&
			(c != ':')
		)
		{
			c = bufGetByte(buf);
		}
		if (c != ':')
		{
			bufMark(buf, -1);
			fprintf(stderr, "no colon in HTTP header \"%s\": %s\n",
				bufCopy(buf), url);
			*ct = NULL;
			return c;
		}
		bufMark(buf, -1);
		app->httpResponseHeaderName(app, buf);
		name = bufCopyLower(buf);
		c = readSpaceTab(buf, bufGetByte(buf));
		bufMark(buf, -1);
		app->httpResponse(app, buf);
		c = readLine(buf, c);
		if ((c == ' ') || (c == '\t'))
		{
			do
			{
				c = readLine(buf, c);
			} while ((c == ' ') || (c == '\t'));
		}
		c = bufTrimTrailingWhiteSpace(buf);
		bufMark(buf, -1);
		value = bufCopy(buf);
		if (!strcasecmp((char *) name, "content-type"))
		{
			app->httpResponseHeaderValue(app, buf, NULL);
			type = mimeParseContentType(value);
			contentType = mimeGetContentType(type);
			charset = mimeGetContentTypeParameter(type, "charset");
			if (charset)
			{
				app->httpResponseCharSet(app, charset);
				free(charset);
			}
			mimeFreeContentType(type);
		}
		else if (!strcasecmp((char *) name, "location"))
		{
			/* XXX supposed to be absolute URL? */
			rel = urlRelative(url, value);
			addURL(app, rel->url);
			app->httpResponseHeaderValue(app, buf, rel->url);
			urlFree(rel);
			locationFound = 1;
		}
		else if (!strcasecmp((char *) name, "transfer-encoding"))
		{
			app->httpResponseHeaderValue(app, buf, NULL);
			if (!strcasecmp((char *) value, "chunked"))
			{
				*chunked = 1;
			}
		}
		else
		{
			app->httpResponseHeaderValue(app, buf, NULL);
		}
		free(name);
		free(value);
		c = readLine(buf, c);
		bufMark(buf, -1);
		app->httpResponse(app, buf);
	}

	if (!contentType)
	{
		if (locationFound)
		{
			*ct = locationURLWasAdded;
			return c;
		}
	}

	*ct = contentType;

	return c;
}