pcicmp.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 561 行 · 第 1/2 页
C
561 行
if (block_icmp) /* application is handling ICMP; not needed */
return;
len = in_GetHdrLen (ip);
icmp = (union icmp_pkt*) ((BYTE*)ip + len);
len = intel16 (ip->length) - len;
for_me = (DWORD) (intel(ip->destination) - my_ip_addr) <= multihomes;
if (!for_me || broadcast) /* drop broadcast pings.. */
return;
if (len < sizeof(icmp->info))
{
STAT (icmpstats.icps_tooshort++);
return;
}
if (checksum(icmp,len) != 0xFFFF)
{
STAT (icmpstats.icps_checksum++);
icmp_print (1, _LANG("bad checksum"), ip->source);
return;
}
type = icmp->unused.type;
code = icmp->unused.code;
orig_ip = &icmp->ip.ip;
i_orig = is_local_addr (intel(orig_ip->source));
if (type == ICMP_MASKREPLY)
{
if (!_domask_req)
return;
i_orig = TRUE;
}
/* !! this needs work
*/
if (!i_orig &&
(type != ICMP_ECHOREPLY && type != ICMP_ECHO &&
type != ICMP_IREQREPLY && type != ICMP_TSTAMP))
{
icmp_bogus (ip, type, NULL);
return;
}
switch (type)
{
case ICMP_ECHOREPLY: /* check if we were waiting for it */
STAT (icmpstats.icps_inhist[ICMP_ECHOREPLY]++);
ping_hcache = intel (ip->source);
ping_tcache = set_timeout (1000) - *(DWORD*)&icmp->echo.identifier;
if (ping_tcache > 0x7FFFFFFFL)
ping_tcache += 0x1800B0L;
ping_number = *(DWORD*)(((BYTE*)&icmp->echo.identifier) + 4);
return;
case ICMP_UNREACH:
STAT (icmpstats.icps_inhist[ICMP_UNREACH]++);
if (code < DIM(icmp_unreach_str))
{
icmp_print (1, msg = icmp_unreach_str[code], ip->source);
#if !defined(USE_UDP_ONLY)
if (orig_ip->proto == TCP_PROTO)
_tcp_cancel (orig_ip, type, msg, 0);
else
#endif
if (orig_ip->proto == UDP_PROTO)
_udp_cancel (orig_ip, type, msg, 0);
}
else
STAT (icmpstats.icps_badcode++);
return;
case ICMP_SOURCEQUENCH:
STAT (icmpstats.icps_inhist[ICMP_SOURCEQUENCH]++);
#if !defined(USE_UDP_ONLY)
if (orig_ip->proto == TCP_PROTO)
{
icmp_print (1, _LANG("Source Quench"), ip->source);
_tcp_cancel (orig_ip, type, NULL, 0);
}
#endif
return;
case ICMP_REDIRECT:
STAT (icmpstats.icps_inhist[ICMP_REDIRECT]++);
if (code < 4)
{
DWORD new_gw = intel (icmp->ip.ipaddr);
/* Check if new gateway is on our subnet
*/
if ((new_gw ^ my_ip_addr) & sin_mask)
{
char buf[100], adr[20];
strcpy (buf, ", GW = ");
strcat (buf, _inet_ntoa(adr,new_gw));
icmp_bogus (ip, type, buf);
return;
}
icmp_print (1, msg = icmp_redirect_str[code], ip->source);
switch (orig_ip->proto)
{
#if !defined(USE_UDP_ONLY)
case TCP_PROTO:
if (do_redirect.tcp) /* do it to some socket */
_tcp_cancel (orig_ip, type, msg, new_gw);
break;
#endif
case UDP_PROTO:
if (do_redirect.udp)
_udp_cancel (orig_ip, type, msg, new_gw);
break;
case ICMP_PROTO:
if (do_redirect.icmp)
{
_ip_recursion = 1;
_arp_register (new_gw, intel(orig_ip->destination), 0);
_ip_recursion = 0;
}
break;
case IGMP_PROTO:
if (do_redirect.igmp)
{
_ip_recursion = 1;
_arp_register (new_gw, intel(orig_ip->destination), 0);
_ip_recursion = 0;
}
break;
}
}
else
STAT (icmpstats.icps_badcode++);
return;
case ICMP_ECHO:
STAT (icmpstats.icps_inhist[ICMP_ECHO]++);
icmp_print (2, _LANG("PING requested of us"), ip->source);
{
/* Extract eth-address and create Echo reply packet.
*/
struct _pkt *pkt;
union icmp_pkt *newicmp;
if (!icmp_chk_src(ip,ICMP_ECHO))
return;
pkt = (struct _pkt*) _eth_formatpacket (MAC_SRC(ip), IP_TYPE);
newicmp = &pkt->icmp;
/* Don't let a huge reassembled ICMP-packet kill us.
*/
len = min (len, mtu - sizeof(*ip));
memcpy (newicmp, icmp, len);
newicmp->echo.type = ICMP_ECHOREPLY;
newicmp->echo.code = code;
/* Use supplied ip values in case we ever multi-home.
* Note that ip values are still in network order.
*/
icmp_send (pkt, ip->destination, ip->source, len);
icmp_print (2, _LANG("PING reply sent"), 0);
}
return;
case ICMP_TIMXCEED:
if (code >= DIM(icmp_exceed_str))
{
STAT (icmpstats.icps_badcode++);
return;
}
STAT (icmpstats.icps_inhist[ICMP_TIMXCEED]++);
if (code != 1)
switch (orig_ip->proto)
{
#if !defined(USE_UDP_ONLY)
case TCP_PROTO:
icmp_print (1, icmp_exceed_str[code], ip->source);
_tcp_cancel (orig_ip, ICMP_TIMXCEED, NULL, 0);
break;
#endif
case UDP_PROTO:
icmp_print (1, icmp_exceed_str[code], ip->source);
_udp_cancel (orig_ip, ICMP_TIMXCEED, NULL, 0);
break;
}
return;
case ICMP_PARAMPROB:
STAT (icmpstats.icps_inhist[ICMP_PARAMPROB]++);
switch (orig_ip->proto)
{
#if !defined(USE_UDP_ONLY)
case TCP_PROTO:
icmp_print (0, _LANG(icmp_type_str[type]), ip->source);
_tcp_cancel (orig_ip, type, NULL, 0);
break;
#endif
case UDP_PROTO:
icmp_print (0, _LANG(icmp_type_str[type]), ip->source);
_udp_cancel (orig_ip, type, NULL, 0);
break;
}
return;
case ICMP_ROUTERADVERT: /* todo !! */
STAT (icmpstats.icps_inhist[ICMP_ROUTERADVERT]++);
icmp_print (1, _LANG(icmp_type_str[type]), ip->source);
return;
case ICMP_ROUTERSOLICIT: /* todo !! */
STAT (icmpstats.icps_inhist[ICMP_ROUTERSOLICIT]++);
icmp_print (1, _LANG(icmp_type_str[type]), ip->source);
return;
case ICMP_TSTAMP:
STAT (icmpstats.icps_inhist[ICMP_TSTAMP]++);
icmp_print (1, _LANG(icmp_type_str[type]), ip->source);
/* todo!!, send reply? */
return;
case ICMP_TSTAMPREPLY:
STAT (icmpstats.icps_inhist[ICMP_TSTAMPREPLY]++);
icmp_print (1, _LANG(icmp_type_str[type]), ip->source);
/* todo!!, should store */
return;
case ICMP_IREQ:
STAT (icmpstats.icps_inhist[ICMP_IREQ]++);
icmp_print (1, _LANG(icmp_type_str[type]), ip->source);
/* todo!!, send reply */
return;
case ICMP_IREQREPLY:
STAT (icmpstats.icps_inhist[ICMP_IREQREPLY]++);
icmp_print (1, _LANG(icmp_type_str[type]), ip->source);
/* todo!!, send reply upwards */
return;
case ICMP_MASKREQ:
STAT (icmpstats.icps_inhist[ICMP_MASKREQ]++);
break;
case ICMP_MASKREPLY:
STAT (icmpstats.icps_inhist[ICMP_MASKREPLY]++);
icmp_print (0, _LANG(icmp_type_str[type]), ip->source);
if ((icmp->mask.identifier == addr_mask_id) &&
(icmp->mask.sequence == addr_mask_seq-1) &&
sin_mask != intel(icmp->mask.mask))
outsnl ("Conflicting net-mask from \"ICMP Addr Mask Reply\"\7");
addr_mask_id = 0;
return;
}
}
/*
* Determine which protocols we shall act upon when
* ICMP redirect is received
*/
void icmp_redirect (const char *value)
{
char *val = strdup (value);
if (val)
{
strupr (val);
do_redirect.icmp = (strstr(val,"ICMP") != NULL);
do_redirect.igmp = (strstr(val,"IGMP") != NULL);
do_redirect.udp = (strstr(val,"UDP") != NULL);
do_redirect.tcp = (strstr(val,"TCP") != NULL);
free (val);
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?