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

📄 ip.c

📁 包括EPA协议栈
💻 C
字号:
#include "router.h"
#include "stimer.h"
#include <string.h>
#include "Ether_dev.h"


static uint16 gIpID = 1;

static uint8 RetryOutput(uint32 para, void* pdata);

uint8 IPInput(PSock psock) {
	uint8 version, protocol, err;
	uint16 hdrlen, chksum, length;
	uint32 srcip, dstip;
	
	version = (psock->payload[0] & 0xF0) >> 4;
	n2h16(psock->payload + 2, &length);
	protocol = psock->payload[9];
	n2h16(psock->payload + 10, &chksum);
	n2h32(psock->payload + 12, &srcip);
	n2h32(psock->payload + 16, &dstip);

	hdrlen = (psock->payload[0] & 0x0F) << 2;

#if IP_VALIDCHK_EN > 0
	if(psock->length != length && psock->length > 46) {
		return 1;
	}
	
	if(ChkSum(psock->payload, hdrlen)) {
		return 2;
	}

	if((version >> 4) != 0x04) {
		return 3;
	}
#endif	// IP_VALIDCHK_EN

	psock->payload += hdrlen;
	psock->length = length - hdrlen;
	psock->src_ip = srcip;
	psock->dst_ip = dstip;
	err = IPFilter(psock->pni, psock->dst_ip, psock);
	if (err == IP_ADDR_ERR) {
		PutSock(psock);
		return IP_ADDR_ERR;
	}
	if (err == IP_NO_ROUTE)
	{
	    return IP_NO_ROUTE;
	}
	if (err == IP_ADDR_ROUTE) {
	    IPRouter(psock->src_ip,psock->dst_ip,psock);
	    return IP_ADDR_ROUTE;
	}
	switch(protocol) {
		case UDP_PROTOCOL:
			return (UDPInput(psock));
		case TCP_PROTOCOL:
			PutSock(psock);
			break;
		case ICMP_PROTOCOL:
			return (ICMPInput(psock));
		case IGMP_PROTOCOL:
			PutSock(psock);
			break;
		default:
			PutSock(psock);
	}
	return (1);
}

uint8 IPOutput(PSock psock, uint8 protocol) {
	
	
	uint8 hw_id;
	uint8 mac[6] = {BMAC0, BMAC1, BMAC2, BMAC3, BMAC4, BMAC5};
	ShiftSock(psock, PROTOCOL_UDP_OR_ICMP, PROTOCOL_IP_OR_ARP);
	psock->payload[0] = (4 << 4) | (20 / 4);
	psock->payload[1] = 0;
	h2n16(psock->length, psock->payload + 2);
	h2n16(gIpID++, psock->payload + 4);
	h2n16(0, psock->payload + 6);
	psock->payload[8] = 32;
	psock->payload[9] = protocol;
	h2n16(0, psock->payload + 10);
	h2n32(psock->pni->ip, psock->payload + 12);
	h2n32(psock->dst_ip, psock->payload + 16);
	h2n16(ChkSum(psock->payload, 20), psock->payload + 10);

	ShiftSock(psock, PROTOCOL_IP_OR_ARP, PROTOCOL_ETHER);
	memcpy(psock->buff + 6, psock->pni->mac, 6);
	if(psock->dst_ip == Groupcast)
	{
	memcpy(psock->buff, mac, 6);
	}
	else
	{
	memcpy(psock->buff,psock->dst_mac,6);
	}
	h2n16(IP_TYPE, psock->buff + 12);
	
//	if(AddrResolve(psock, psock->pni) != IP_MAC_NOT_FOUND) {
//		return (psock->pni->output(psock));
//	}
//	else {
//#if ST_MODULE_EN > 0
//		psock->retrys = IP_RETRY_TIMES;
//		AddSt(IP_RETRY_INTERVAL, 0, (void*)psock, RetryOutput);
//		ArpOutput(psock->dst_ip, (uint8*)0, ARP_OP_QUERY);
//#else
//		PutSock(psock);
//#endif	// ST_MODULE_EN
//		return IP_MAC_NOT_FOUND;
//	}
	hw_id = psock->pni->hw_id;
	return( EtherOutput(psock->buff, psock->length, hw_id) );
}

uint16 ChkSum(uint8* payload, uint16 length) {
	uint32 sum;
	uint16 index;
	uint16 steps;
	uint16 tmp;

	sum = 0;
	steps = length >> 1;
	for(index = 0; index < steps; ++index) {
		n2h16(payload, &tmp);
		sum += tmp;
		payload += 2;
	}
	if(length & 0x01) {
		sum += (payload[0] << 8);
	}
	sum =(sum & 0xFFFF) + ((sum>>16) & 0xFFFF);
	return (~sum);
}

static uint8 RetryOutput(uint32 para, void* pdata) {
	PSock psock = pdata;

	if(ArpSeek(psock, psock->pni) != IP_MAC_NOT_FOUND) {
		return (psock->pni->output(psock));
	}
	else {
		if(!(--(psock->retrys))) {
			PutSock(psock);
			return IP_RETRY_REACHED_LIMIT;
		}
		AddSt(IP_RETRY_INTERVAL, 0, pdata, RetryOutput);
		ArpOutput(psock->dst_ip, (uint8*)0, ARP_OP_QUERY);
		return IP_MAC_NOT_FOUND;
	}
}

⌨️ 快捷键说明

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