⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 icmp.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#endif		bf_afree(ip_data);		bf_afree(icmp_data);		return;	}	if (icmp_len < ICMP_MIN_HDR_LEN + sizeof(icmp_id_seq_t))	{#if DEBUG { where(); printf("got an incomplete icmp echo request\n"); }#endif		bf_afree(ip_data);		bf_afree(icmp_data);		return;	}#if DEBUG & 256 { where(); printf("got an icmp echo request, ident= %u, seq= %u\n",	ntohs(icmp_hdr->ih_hun.ihh_idseq.iis_id),	ntohs(icmp_hdr->ih_hun.ihh_idseq.iis_seq)); }#endif	repl_ip_hdr= make_repl_ip(ip_hdr, ip_len);	repl_icmp= bf_memreq (ICMP_MIN_HDR_LEN);assert (repl_icmp->acc_length == ICMP_MIN_HDR_LEN);	repl_icmp_hdr= (icmp_hdr_t *)ptr2acc_data(repl_icmp);	repl_icmp_hdr->ih_type= ICMP_TYPE_ECHO_REPL;	repl_icmp_hdr->ih_code= 0;	tmp_chksum= ~icmp_hdr->ih_chksum - *(u16_t *)&icmp_hdr->ih_type+		*(u16_t *)&repl_icmp_hdr->ih_type;	tmp_chksum= (tmp_chksum >> 16) + (tmp_chksum & 0xffff);	tmp_chksum= (tmp_chksum >> 16) + (tmp_chksum & 0xffff);	repl_icmp_hdr->ih_chksum= ~tmp_chksum;	repl_ip_hdr->acc_next= repl_icmp;	repl_icmp->acc_next= bf_cut (icmp_data, ICMP_MIN_HDR_LEN,		icmp_len - ICMP_MIN_HDR_LEN);	bf_afree(ip_data);	bf_afree(icmp_data);	enqueue_pack(icmp_port, repl_ip_hdr);}PRIVATE u16_t icmp_pack_oneCsum(icmp_pack)acc_t *icmp_pack;{	u16_t prev;	int odd_byte;	char *data_ptr;	int length;	char byte_buf[2];	assert (icmp_pack);	prev= 0;	odd_byte= FALSE;	for (; icmp_pack; icmp_pack= icmp_pack->acc_next)	{				data_ptr= ptr2acc_data(icmp_pack);		length= icmp_pack->acc_length;		if (!length)			continue;		if (odd_byte)		{			byte_buf[1]= *data_ptr;			prev= oneC_sum(prev, (u16_t *)byte_buf, 2);			data_ptr++;			length--;			odd_byte= FALSE;		}		if (length & 1)		{			odd_byte= TRUE;			length--;			byte_buf[0]= data_ptr[length];		}		if (!length)			continue;		prev= oneC_sum (prev, (u16_t *)data_ptr, length);	}	if (odd_byte)		prev= oneC_sum (prev, (u16_t *)byte_buf, 1);	return prev;}PRIVATE acc_t *make_repl_ip(ip_hdr, ip_len)ip_hdr_t *ip_hdr;int ip_len;{	ip_hdr_t *repl_ip_hdr;	acc_t *repl;	int repl_hdr_len;	if (ip_len>IP_MIN_HDR_SIZE)	{#if DEBUG { where(); printf("ip_hdr options NOT supported (yet?)\n"); }#endif		ip_len= IP_MIN_HDR_SIZE;	}	repl_hdr_len= IP_MIN_HDR_SIZE;	repl= bf_memreq(repl_hdr_len);assert (repl->acc_length == repl_hdr_len);	repl_ip_hdr= (ip_hdr_t *)ptr2acc_data(repl);	repl_ip_hdr->ih_vers_ihl= repl_hdr_len >> 2;	repl_ip_hdr->ih_tos= ip_hdr->ih_tos;	repl_ip_hdr->ih_ttl= ICMP_DEF_TTL;	repl_ip_hdr->ih_proto= IPPROTO_ICMP;	repl_ip_hdr->ih_dst= ip_hdr->ih_src;	repl_ip_hdr->ih_flags_fragoff= 0;	return repl;}PRIVATE void enqueue_pack(icmp_port, reply_ip_hdr)icmp_port_t *icmp_port;acc_t *reply_ip_hdr;{	reply_ip_hdr->acc_ext_link= 0;	if (icmp_port->icp_head_queue)	{		icmp_port->icp_tail_queue->acc_ext_link=			reply_ip_hdr;	}	else	{		icmp_port->icp_head_queue= reply_ip_hdr;		icmp_port->icp_tail_queue= reply_ip_hdr;	}	if (!(icmp_port->icp_flags & ICPF_WRITE_IP))		icmp_write(icmp_port);}PRIVATE void icmp_write(icmp_port)icmp_port_t *icmp_port;{	int result;assert (!(icmp_port->icp_flags & (ICPF_WRITE_IP|ICPF_WRITE_SP) || 	(icmp_port->icp_flags & (ICPF_WRITE_IP|ICPF_WRITE_SP)) ==	(ICPF_WRITE_IP|ICPF_WRITE_SP)));	for (;icmp_port->icp_head_queue;)	{		icmp_port->icp_write_pack= icmp_port->icp_head_queue;		icmp_port->icp_head_queue= icmp_port->icp_head_queue->			acc_ext_link;		icmp_port->icp_flags |= ICPF_WRITE_IP;		icmp_port->icp_flags &= ~ICPF_WRITE_SP;#if DEBUG & 256 { where(); printf("calling ip_write\n"); }#endif		result= ip_write(icmp_port->icp_ipfd,			bf_bufsize(icmp_port->icp_write_pack));		if (result == NW_SUSPEND)		{#if DEBUG & 256 { where(); printf("ip_write replied NW_SUSPEND\n"); }#endif			icmp_port->icp_flags |= ICPF_WRITE_SP;			return;		}#if DEBUG & 256 { where(); printf("ip_write done\n"); }#endif	}	icmp_port->icp_flags &= ~ICPF_WRITE_IP;}PRIVATE void icmp_buffree(priority, reqsize)int priority;size_t reqsize;{	acc_t *tmp_acc;	int donesomething,i;	icmp_port_t *icmp_port;	donesomething= 0;	if (priority < ICMP_PRI_QUEUE)		return;	while (bf_free_buffsize < reqsize)	{		for (i=0, icmp_port= icmp_port_table; i<ICMP_PORT_NR;			i++, icmp_port++)		{			if (icmp_port->icp_head_queue)			{				tmp_acc= icmp_port->icp_head_queue;				icmp_port->icp_head_queue= tmp_acc->					acc_ext_link;				bf_afree(tmp_acc);				if (bf_free_buffsize >= reqsize)					break;				donesomething= 1;			}		}		if (!donesomething)			break;	}}static void icmp_dst_unreach(icmp_port, ip_pack, ip_hdr_len, ip_hdr, icmp_pack,	icmp_len, icmp_hdr)icmp_port_t *icmp_port;acc_t *ip_pack;int ip_hdr_len;ip_hdr_t *ip_hdr;acc_t *icmp_pack;int icmp_len;icmp_hdr_t *icmp_hdr;{	acc_t *old_ip_pack;	ip_hdr_t *old_ip_hdr;	if (icmp_len < 8 + IP_MIN_HDR_SIZE)	{#if DEBUG { where(); printf("dest unrch with wrong size\n"); }#endif		return;	}	old_ip_pack= bf_cut (icmp_pack, 8, icmp_len-8);	old_ip_pack= bf_packIffLess(old_ip_pack, IP_MIN_HDR_SIZE);	old_ip_hdr= (ip_hdr_t *)ptr2acc_data(old_ip_pack);	if (old_ip_hdr->ih_src != ip_hdr->ih_dst)	{#if DEBUG { where(); printf("dest unrch based on wrong packet\n"); }#endif		bf_afree(old_ip_pack);		return;	}	switch(icmp_hdr->ih_code)	{	case ICMP_NET_UNRCH:		ipr_destunrch (old_ip_hdr->ih_dst,			ip_get_netmask(old_ip_hdr->ih_dst), IPR_UNRCH_TIMEOUT);		break;	case ICMP_HOST_UNRCH:		ipr_destunrch (old_ip_hdr->ih_dst, (ipaddr_t)-1,			IPR_UNRCH_TIMEOUT);		break;	default:#if DEBUG { where(); printf("got strange code: %d\n", icmp_hdr->ih_code); }#endif		break;	}	bf_afree(old_ip_pack);}static void icmp_time_exceeded(icmp_port, ip_pack, ip_hdr_len, ip_hdr,	icmp_pack, icmp_len, icmp_hdr)icmp_port_t *icmp_port;acc_t *ip_pack;int ip_hdr_len;ip_hdr_t *ip_hdr;acc_t *icmp_pack;int icmp_len;icmp_hdr_t *icmp_hdr;{	acc_t *old_ip_pack;	ip_hdr_t *old_ip_hdr;	if (icmp_len < 8 + IP_MIN_HDR_SIZE)	{#if DEBUG { where(); printf("time exceeded with wrong size\n"); }#endif		return;	}	old_ip_pack= bf_cut (icmp_pack, 8, icmp_len-8);	old_ip_pack= bf_packIffLess(old_ip_pack, IP_MIN_HDR_SIZE);	old_ip_hdr= (ip_hdr_t *)ptr2acc_data(old_ip_pack);	if (old_ip_hdr->ih_src != ip_hdr->ih_dst)	{#if DEBUG { where(); printf("time exceeded based on wrong packet\n"); }#endif		bf_afree(old_ip_pack);		return;	}	switch(icmp_hdr->ih_code)	{	case ICMP_TTL_EXC:		ipr_ttl_exc (old_ip_hdr->ih_dst, (ipaddr_t)-1,			IPR_TTL_TIMEOUT);		break;	default:		where();		printf("got strange code: %d\n", icmp_hdr->ih_code);		break;	}	bf_afree(old_ip_pack);}static void icmp_router_advertisement(icmp_port, icmp_pack, icmp_len, icmp_hdr)icmp_port_t *icmp_port;acc_t *icmp_pack;int icmp_len;icmp_hdr_t *icmp_hdr;{	int entries;	int entry_size;	u16_t lifetime;	int i;	char *bufp;	if (icmp_len < 8)	{#if DEBUG { where(); printf("router advertisement with wrong size (%d)\n", icmp_len); }#endif		return;	}	if (icmp_hdr->ih_code != 0)	{#if DEBUG { where(); printf("router advertisement with wrong code (%d)\n", 							icmp_hdr->ih_code); }#endif		return;	}	entries= icmp_hdr->ih_hun.ihh_ram.iram_na;	entry_size= icmp_hdr->ih_hun.ihh_ram.iram_aes * 4;	if (entries < 1)	{#if DEBUG { where(); printf("router advertisement with wrong number of entries (%d)\n", 							entries); }#endif		return;	}	if (entry_size < 8)	{#if DEBUG { where(); printf("router advertisement with wrong entry size (%d)\n", 							entry_size); }#endif		return;	}	if (icmp_len < 8 + entries * entry_size)	{#if DEBUG { where(); printf("router advertisement with wrong size\n"); 	printf("\t(entries= %d, entry_size= %d, icmp_len= %d)\n", entries,						entry_size, icmp_len); }#endif		return;	}	lifetime= ntohs(icmp_hdr->ih_hun.ihh_ram.iram_lt);	if (lifetime > 9000)	{#if DEBUG { where(); printf("router advertisement with wrong lifetime (%d)\n",								lifetime); }#endif		return;	}	for (i= 0, bufp= (char *)&icmp_hdr->ih_dun.uhd_data[0]; i< entries; i++,		bufp += entry_size)	{		ipr_add_route(HTONL(0L), HTONL(0L), *(ipaddr_t *)bufp,			icmp_port->icp_ipport, lifetime * HZ, 1, 0, 			ntohl(*(i32_t *)(bufp+4)));	}}		static void icmp_redirect(icmp_port, ip_hdr, icmp_pack, icmp_len, icmp_hdr)icmp_port_t *icmp_port;ip_hdr_t *ip_hdr;acc_t *icmp_pack;int icmp_len;icmp_hdr_t *icmp_hdr;{	acc_t *old_ip_pack;	ip_hdr_t *old_ip_hdr;	int port;	if (icmp_len < 8 + IP_MIN_HDR_SIZE)	{#if DEBUG { where(); printf("redirect with wrong size\n"); }#endif		return;	}	old_ip_pack= bf_cut (icmp_pack, 8, icmp_len-8);	old_ip_pack= bf_packIffLess(old_ip_pack, IP_MIN_HDR_SIZE);	old_ip_hdr= (ip_hdr_t *)ptr2acc_data(old_ip_pack);	port= icmp_port->icp_ipport;	switch(icmp_hdr->ih_code)	{	case ICMP_REDIRECT_NET:		ipr_redirect (old_ip_hdr->ih_dst,			ip_get_netmask(old_ip_hdr->ih_dst),			ip_hdr->ih_src, icmp_hdr->ih_hun.ihh_gateway, port, 			IPR_REDIRECT_TIMEOUT);		break;	case ICMP_REDIRECT_HOST:		ipr_redirect (old_ip_hdr->ih_dst, (ipaddr_t)-1,			ip_hdr->ih_src, icmp_hdr->ih_hun.ihh_gateway, port, 			IPR_REDIRECT_TIMEOUT);		break;	default:		where();		printf("got strange code: %d\n", icmp_hdr->ih_code);		break;	}	bf_afree(old_ip_pack);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -