📄 ip.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 + -