コード例 #1
0
ファイル: icmp.c プロジェクト: 0xcc/tapip
void icmp_in(struct pkbuf *pkb)
{
	struct ip *iphdr = pkb2ip(pkb);
	struct icmp *icmphdr = ip2icmp(iphdr);
	int icmplen, type;
	/* sanity check */
	icmplen = ipdlen(iphdr);
	icmpdbg("%d bytes", icmplen);
	if (icmplen < ICMP_HRD_SZ) {
		icmpdbg("icmp header is too small");
		goto drop_pkb;
	}

	if (icmp_chksum((unsigned short *)icmphdr, icmplen) != 0) {
		icmpdbg("icmp checksum is error");
		goto drop_pkb;
	}

	type = icmphdr->icmp_type;
	if (type > ICMP_T_MAXNUM) {
		icmpdbg("unknown icmp type %d code %d",
					type, icmphdr->icmp_code);
		goto drop_pkb;
	}
	/* handle icmp type */
	icmp_table[type].handler(&icmp_table[type], pkb);
	return;
drop_pkb:
	free_pkb(pkb);
}
コード例 #2
0
ファイル: icmp.c プロジェクト: 0xcc/tapip
static void icmp_echo_request(struct icmp_desc *icmp_desc, struct pkbuf *pkb)
{
	struct ip *iphdr = pkb2ip(pkb);
	struct icmp *icmphdr = ip2icmp(iphdr);
	icmpdbg("echo request data %d bytes icmp_id %d icmp_seq %d",
			(int)(iphdr->ip_len - iphlen(iphdr) - ICMP_HRD_SZ),
			_ntohs(icmphdr->icmp_id),
			_ntohs(icmphdr->icmp_seq));
	if (icmphdr->icmp_code) {
		icmpdbg("echo request packet corrupted");
		free_pkb(pkb);
		return;
	}
	icmphdr->icmp_type = ICMP_T_ECHORLY;
	/*
	 * adjacent the checksum:
	 * If  ~ >>> (cksum + x + 8) >>> == 0
	 * let ~ >>> (cksum` + x ) >>> == 0
	 * then cksum` = cksum + 8
	 */
	if (icmphdr->icmp_cksum >= 0xffff - ICMP_T_ECHOREQ)
		icmphdr->icmp_cksum += ICMP_T_ECHOREQ + 1;
	else
		icmphdr->icmp_cksum += ICMP_T_ECHOREQ;
	iphdr->ip_dst = iphdr->ip_src;	/* ip_src is set by ip_send_out() */
	ip_hton(iphdr);
	/* init reused input packet */
	pkb->pk_rtdst = NULL;
	pkb->pk_indev = NULL;
	pkb->pk_type = PKT_NONE;
	ip_send_out(pkb);
}
コード例 #3
0
ファイル: icmp.c プロジェクト: 0xcc/tapip
static void icmp_drop_reply(struct icmp_desc *icmp_desc, struct pkbuf *pkb)
{
	struct ip *iphdr = pkb2ip(pkb);
	struct icmp *icmphdr = ip2icmp(iphdr);
	icmpdbg("icmp type %d code %d (dropped)",
			icmphdr->icmp_type, icmphdr->icmp_code);
	if (icmp_desc->info)
		icmpdbg("%s", icmp_desc->info);
	free_pkb(pkb);
}
コード例 #4
0
ファイル: icmp.c プロジェクト: 0xcc/tapip
static void icmp_echo_reply(struct icmp_desc *icmp_desc, struct pkbuf *pkb)
{
	struct ip *iphdr = pkb2ip(pkb);
	struct icmp *icmphdr = ip2icmp(iphdr);
	icmpdbg("from "IPFMT" id %d seq %d ttl %d",
			ipfmt(iphdr->ip_src),
			_ntohs(icmphdr->icmp_id),
			_ntohs(icmphdr->icmp_seq),
			iphdr->ip_ttl);
	free_pkb(pkb);
}
コード例 #5
0
ファイル: icmp.c プロジェクト: 0xcc/tapip
/* NOTE: icmp dont drop @ipkb */
void icmp_send(unsigned char type, unsigned char code,
		unsigned int data, struct pkbuf *pkb_in)
{
	struct pkbuf *pkb;
	struct ip *iphdr = pkb2ip(pkb_in);
	struct icmp *icmphdr;
	int paylen = _ntohs(iphdr->ip_len);	/* icmp payload length */
	if (paylen < iphlen(iphdr) + 8)
		return;
	/*
	 * RFC 1812 Section 4.3.2.7 for sanity check
	 * An ICMP error message MUST NOT be sent as the result of receiving:
	 * 1. A packet sent as a Link Layer broadcast or multicast
	 * 2. A packet destined to an IP broadcast or IP multicast address
	 *[3] A packet whose source address has a network prefix of zero or is an
	 *      invalid source address (as defined in Section [5.3.7])
	 * 4. Any fragment of a datagram other then the first fragment (i.e., a
	 *      packet for which the fragment offset in the IP header is nonzero).
	 * 5. An ICMP error message
	 */
	if (pkb_in->pk_type != PKT_LOCALHOST)
		return;
	if (MULTICAST(iphdr->ip_dst) || BROADCAST(iphdr->ip_dst))
		return;
	if (iphdr->ip_fragoff & _htons(IP_FRAG_OFF))
		return;

	if (icmp_type_error(type) && iphdr->ip_pro == IP_P_ICMP) {
		icmphdr = ip2icmp(iphdr);
		if (icmphdr->icmp_type > ICMP_T_MAXNUM || icmp_error(icmphdr))
			return;
	}
	/* build icmp packet and send */
	/* ip packet size must be smaller than 576 bytes */
	if (IP_HRD_SZ + ICMP_HRD_SZ + paylen > 576)
		paylen = 576 - IP_HRD_SZ - ICMP_HRD_SZ;
	pkb = alloc_pkb(ETH_HRD_SZ + IP_HRD_SZ + ICMP_HRD_SZ + paylen);
	icmphdr = (struct icmp *)(pkb2ip(pkb)->ip_data);
	icmphdr->icmp_type = type;
	icmphdr->icmp_code = code;
	icmphdr->icmp_cksum = 0;
	icmphdr->icmp_undata = data;
	memcpy(icmphdr->icmp_data, (unsigned char *)iphdr, paylen);
	icmphdr->icmp_cksum =
		icmp_chksum((unsigned short *)icmphdr, ICMP_HRD_SZ + paylen);
	icmpdbg("to "IPFMT"(payload %d) [type %d code %d]\n",
		ipfmt(iphdr->ip_src), paylen, type, code);
	ip_send_info(pkb, 0, IP_HRD_SZ + ICMP_HRD_SZ + paylen,
						0, IP_P_ICMP, iphdr->ip_src);
}
コード例 #6
0
ファイル: icmp.c プロジェクト: 0xcc/tapip
static void icmp_redirect(struct icmp_desc *icmp_desc, struct pkbuf *pkb)
{
	struct ip *iphdr = pkb2ip(pkb);
	struct icmp *icmphdr = ip2icmp(iphdr);

	if (icmphdr->icmp_code > 4)
		icmpdbg("Redirect code %d is error", icmphdr->icmp_code);
	else
		icmpdbg("from " IPFMT " %s(new nexthop "IPFMT")",
					ipfmt(iphdr->ip_src),
					redirectstr[icmphdr->icmp_code],
					ipfmt(icmphdr->icmp_gw));
	free_pkb(pkb);
}
コード例 #7
0
ファイル: ping.c プロジェクト: OoOverflow/tapip
static void recv_packet(void)
{
	struct pkbuf *pkb;
	struct ip *iphdr;
	struct icmp *icmphdr;
	while (!finite || recv > 0) {
		pkb = _recv(sock);
		if (!pkb)
			break;
		iphdr = pkb2ip(pkb);
		icmphdr = ip2icmp(iphdr);
		if (iphdr->ip_pro == IP_P_ICMP &&
			_ntohs(icmphdr->icmp_id) == id &&
			icmphdr->icmp_type == ICMP_T_ECHORLY) {
			recv--;
			printf("%d bytes from " IPFMT ": icmp_seq=%d ttl=%d\n",
				ipdlen(iphdr), ipfmt(iphdr->ip_src),
				_ntohs(icmphdr->icmp_seq), iphdr->ip_ttl);
			precv++;
		}
		free_pkb(pkb);
	}
}