static void icmp_timestamp(struct icmphdr *icmph, struct sk_buff *skb, int len) { struct timeval tv; __u32 times[3]; /* So the new timestamp works on ALPHA's.. */ struct icmp_bxm icmp_param; /* * Too short. */ if(len<12) { icmp_statistics.IcmpInErrors++; return; } /* * Fill in the current time as ms since midnight UT: */ do_gettimeofday(&tv); times[1] = htonl((tv.tv_sec % 86400) * 1000 + tv.tv_usec / 1000); times[2] = times[1]; memcpy((void *)×[0], icmph+1, 4); /* Incoming stamp */ icmp_param.icmph=*icmph; icmp_param.icmph.type=ICMP_TIMESTAMPREPLY; icmp_param.icmph.code=0; icmp_param.data_ptr=× icmp_param.data_len=12; icmp_reply(&icmp_param, skb); }
int icmp_input(struct nm_if *nmif, char *buf, int len) { int icmp_len, hlen; struct icmp *icmp; struct ip *ip; ip = (struct ip *)buf; hlen = ip->ip_hl << 2; icmp_len = len - hlen; if (icmp_len < ICMP_MINLEN || icmp_len < sizeof(struct icmphdr)) { DPRINTF("%s: packet too short, discading (%d).\n", __func__, icmp_len); pktcnt.icmp_drop++; return (-1); } icmp = (struct icmp *)(buf + hlen); if (in_cksum(buf + hlen, len - hlen)) { DPRINTF("%s: bad checksum, discarding the packet.\n", __func__); pktcnt.icmp_drop++; return (-1); } if (icmp->icmp_type != ICMP_ECHO || icmp->icmp_code != 0) { DPRINTF("%s: unknown ICMP type and code, discading the packet (%#x:%d).\n", __func__, icmp->icmp_type, icmp->icmp_code); pktcnt.icmp_unknown++; return (-1); } /* XXX - rate */ pktcnt.icmp_echo++; return (icmp_reply(nmif, buf, len)); }
static void icmp_echo(struct icmphdr *icmph, struct sk_buff *skb, int len) { if (!sysctl_icmp_echo_ignore_all) { struct icmp_bxm icmp_param; icmp_param.icmph=*icmph; icmp_param.icmph.type=ICMP_ECHOREPLY; icmp_param.data_ptr=(icmph+1); icmp_param.data_len=len; icmp_reply(&icmp_param, skb); } }