📄 icmp.c
字号:
#include "debug.h"
#include "true_false.h"
#include "stdlib.h"
#include "typedef.h"
#include "mem_man.h"
#include "rtl8019.h"
#include "netif.h"
#include "etherif.h"
#include "ip.h"
#include "arp.h"
#include "utilities.h"
#include "tcp.h"
#include "icmp.h"
static u16_t GlobalID=0;
static u8_t state=PING_OK;
/* MemHead->pStart is point to ICMP hea */
void ICMPInput(struct SMemHead*MemHead)
{
IP_ADDR ipaddr ;
struct SIPHead*pIPHead ;
struct SICMPEchoHead*pICMPHead ;
/* which type of icmp */
switch(((struct SICMPEchoHead*)(MemHead->pStart))->type)
{
case ICMP_TYPE_QUERY :
/* chage type */
((struct SICMPEchoHead*)(MemHead->pStart))->type=ICMP_TYPE_REPLY ;
/* adjust checksum. refer to lwip: if change type from 8 to 0,
for checksum, that is increasing 0x8000 and add flowed hight bit
to bit 0.*/
if(((struct SICMPEchoHead*)(MemHead->pStart))->CheckSum>=htons(0xffff-(((WORD)ICMP_TYPE_QUERY)<<8)))
((struct SICMPEchoHead*)(MemHead->pStart))->CheckSum+=htons(((WORD)ICMP_TYPE_QUERY)<<8)+1 ;
else
((struct SICMPEchoHead*)(MemHead->pStart))->CheckSum+=htons(((WORD)ICMP_TYPE_QUERY)<<8);
/*
*send this packet back, first fill some of IPHead field
*/
/* dec pStart and get ip head */
pIPHead=(struct SIPHead*)(MemHead->pStart-=IP_HEAD_MIN_LEN);
/* exchange ipdest and ipscr */
ipaddr=pIPHead->IPDest ;
pIPHead->IPDest=pIPHead->IPScr ;
pIPHead->IPScr=ipaddr ;
/* ip total length not change */
/* protocol */
pIPHead->Protocol=IP_PROTOCOL_ICMP ;
IPOutput(MemHead);
/* whether send success or not free this packet */
MemFree(MemHead);
break ;
case ICMP_TYPE_REPLY :
/*ICMP校验和只覆盖ICMP报文*/
pICMPHead=(struct SICMPEchoHead*)(MemHead->pStart) ;
if(CheckSum((u16_t*)pICMPHead,MemHead->pEnd-MemHead->pStart,0)!=0)
{
#ifdef debug_icmp
Uart_Printf("ICMP:RCV A REPLY FRAME BUT CHECKSUM IS ERROR!\n");
#endif
}
else
{
#ifdef debug_icmp
Uart_Printf("globalid =%d seq=%d\n",GlobalID,ntohs(pICMPHead->seq));
#endif
if(GlobalID==ntohs(pICMPHead->seq))
{
if(state==PING_WAIT)
state=PING_OK;
/*the ringht ping_reply we are look for*/
}
}
MemFree(MemHead);
break ;
default :
MemFree(MemHead);
}
}
BOOL PINGOut(IP_ADDR IPScr,IP_ADDR IPDest,u16_t len)
{
struct SMemHead*MemHead ;
struct SIPHead*pIPHead ;
struct SICMPEchoHead*pICMPHead ;
BOOL ret=FALSE;
if (len>1450) len=1450;
/*alloate some memory for the ping packet*/
MemHead=MemAllocate(len+ICMP_HEAD_MIN_LEN+IP_HEAD_MIN_LEN+NETIF_HEAD_MAX_LEN);
if(MemHead==NULL) return FALSE ;
/*fill icmp head*/
pICMPHead=(struct SICMPEchoHead*)
(MemHead->pStart+IP_HEAD_MIN_LEN+NETIF_HEAD_MAX_LEN);
pICMPHead->type=ICMP_TYPE_QUERY ;
pICMPHead->ICMPCode=0 ;
pICMPHead->CheckSum=0 ;
pICMPHead->id=htons(512) ;
pICMPHead->seq=htons(++GlobalID);
pICMPHead->CheckSum=CheckSum((u16_t*)(u8_t*)pICMPHead,
MemHead->pEnd-MemHead->pStart-IP_HEAD_MIN_LEN-NETIF_HEAD_MAX_LEN,
0);
/*fill ip head*/
pIPHead=(struct SIPHead*)(MemHead->pStart+NETIF_HEAD_MAX_LEN);
pIPHead->IPDest=htonl(IPDest) ;
pIPHead->IPScr=htonl(IPScr) ;
pIPHead->TotalLen=htons(MemHead->pEnd-MemHead->pStart-NETIF_HEAD_MAX_LEN);
pIPHead->Protocol=IP_PROTOCOL_ICMP ;
MemHead->pStart=(BYTE*)pIPHead ;
state=PING_WAIT;
ret=IPOutput(MemHead);
/* whether send success or not free this packet */
MemFree(MemHead);
return ret;
}
u8_t get_state(){
return state;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -