📄 tinyicmp.c
字号:
len = in_GetHdrlenBytes(ip);
Move(ip, &rxpkt, (len + ip->length));
icmp = (icmp_pkt*)(&(rxpkt.icmp));
len = wfix(rxpkt.in.length) - len;
if (checksum(icmp, len) != 0xffff )
{
return;
}
code = icmp->unused.code;
ret = & (icmp->ip.ip);
switch (icmp->unused.type)
{
case 0 :
/* icmp echo reply received */
ping_tcache_end = t_get() - ping_tcache_start;
ping_tcache = GetUSecs(ping_tcache_end);
ping_number = wfix(icmp->echo.identifier);
ipaddr = lfix(rxpkt.in.source);
sys_sprintf(sip_address, "%d.%d.%d.%d", ((ipaddr>>24) & 0xff), ((ipaddr>>16) & 0xff), ((ipaddr>>8) & 0xff), (ipaddr & 0xff));
sys_printf("Reply from %s: icmp_seq=%d time=%d microsecs.\n", sip_address, ping_number, ping_tcache);
ping_tcache_end = ping_tcache_start = 0;
break;
case 8 :
/* icmp echo request */
/* don't reply if the request was made by ourselves */
if (rxpkt.in.source == lfix(sin_lclINAddr))
return;
if (rxpkt.in.destination != lfix(sin_lclINAddr))
return;
/* do arp and create packet */
if ( !sar_MapIn2Eth(lfix(rxpkt.in.source), &dest))
{
return;
}
/* format the packet with the request's hardware address */
pkt = (struct _pkt *)sed_FormatPacket(dest, 0x800);
newicmp = &(pkt->icmp);
MoveW(icmp, newicmp, len);
newicmp->echo.type = 0;
newicmp->echo.code = code;
/* use supplied ip values in case we ever multi-home */
/* note that ip values are still in network order */
icmp_Reply(pkt, lfix(rxpkt.in.destination), lfix(rxpkt.in.source), len);
break;
#if 0
case 3 :
/* destination unreachable message */
case 4 :
/* source quench */
case 5 :
/* redirect */
break;
case 11 :
/* time exceeded message */
case 12 :
/* parameter problem message */
case 13 :
/* timestamp message */
/* send reply */
case 14 :
/* timestamp reply */
/* should store */
case 15 :
/* info request */
/* send reply */
case 16 :
/* info reply */
break;
#endif
}
}
int send_ping(longword host, longword count, longword size)
{
eth_HwAddress dest;
struct _pkt *p;
in_Header *ip;
struct icmp_echo *icmp;
longword total_length, icmp_timeout, ping_delay;
byte *buf;
byte ch;
int i, ret;
if ((host & 0xff) == 0xff) {
sys_printf("Cannot ping a network!\n");
return -1;
}
if ( !sar_MapIn2Eth(host, &dest))
{
sys_printf("Cannot resolve the ARP\n");
return -1;
}
if (size >= icmp_MaxBufSize)
{
sys_printf("Size is more than allowed size, defaulting to %d\n", icmp_MaxBufSize);
size = icmp_MaxBufSize;
}
icmp_id = 0;
do
{
p = (struct _pkt *)sed_FormatPacket(dest, 0x800);
ip = &p->in;
sys_memset(ip, 0, sizeof(in_Header));
icmp = &p->icmp.echo;
icmp->type = 8;
icmp->code = 0;
icmp->identifier = wfix(icmp_id);
buf = &p->data[0];
for (i = 0, ch = 'a'; i < size; i++, ch++)
{
*buf++ = ch;
if (ch == 'z')
ch = 'a';
}
total_length = sizeof(struct icmp_echo) + size;
/* finish the icmp checksum portion */
icmp->checksum = 0;
icmp->checksum = wfix(~checksum(icmp, total_length));
/* encapsulate into a nice ip packet */
ip->vht = wfix(0x4500); /* Version 4, hdrlen = 5 tos 0 */
ip->length = wfix(sizeof(in_Header) + total_length);
ip->identification = wfix(icmp_id);
ip->ttlProtocol = wfix((250<<8) + ICMP_PROTO);
ip->checksum = 0;
ip->source = lfix(sin_lclINAddr);
ip->destination = lfix(host);
ip->checksum = wfix(~checksum(ip, sizeof(in_Header)));
sed_Send(wfix(ip->length));
t_clear();
ping_tcache_start = t_get();
icmp_timeout = ping_tcache_start + GetTicks(ICMP_TIMEOUT);
ret = ip_Handler();
while (( ret == 0) && t_get() < icmp_timeout)
{
ret = ip_Handler();
}
if (ret == 0)
sys_printf("icmp_seq=%d: Request timedout.\n", icmp_id);
t_clear();
ping_delay = t_get() + GetTicks(PING_DELAY);
while (t_get() < ping_delay);
count--;
icmp_id++;
}
while (count);
icmp_id = 0;
return(count);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -