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

📄 ip_read.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*ip_read.c*/#include "inet.h"#include "buf.h"#include "clock.h"#include "type.h"#include "assert.h"#include "icmp_lib.h"#include "io.h"#include "ip.h"#include "ip_int.h"INIT_PANIC();FORWARD ip_ass_t *find_ass_ent ARGS(( ip_port_t *port, U16_t id,	int proto, ipaddr_t src, ipaddr_t dst ));FORWARD acc_t *merge_frags ARGS(( acc_t *first, acc_t *second ));FORWARD int net_broad ARGS(( ipaddr_t hoaddr, ipaddr_t netaddr,	ipaddr_t netmask ));FORWARD int ip_frag_chk ARGS(( acc_t *pack ));FORWARD acc_t *reassemble ARGS(( ip_port_t *port, acc_t *pack, 	ip_hdr_t *ip_hdr ));FORWARD int ok_for_port ARGS(( ip_port_t *port, ipaddr_t ipaddr,	int *ref_broad_all ));PUBLIC int ip_read (fd, count)int fd;size_t count;{	ip_fd_t *ip_fd;	ip_fd= &ip_fd_table[fd];	if (!(ip_fd->if_flags & IFF_OPTSET))		return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, EBADMODE,			(acc_t *)0, FALSE);	ip_fd->if_rd_count= count;	if (ip_fd->if_rd_buf)	{		if (get_time() <= ip_fd->if_exp_tim)			return ip_packet2user (ip_fd);	 where();		bf_afree(ip_fd->if_rd_buf);	 where();		ip_fd->if_rd_buf= 0;	}	ip_fd->if_flags |= IFF_READ_IP;#if DEBUG & 256 { where(); printf("ip_fd_table[%d].if_flags= 0x%x\n",	ip_fd-ip_fd_table, ip_fd->if_flags); }#endif	return NW_SUSPEND;}PRIVATE acc_t *reassemble (port, pack, pack_hdr)ip_port_t *port;acc_t *pack;ip_hdr_t *pack_hdr;{	ip_ass_t *ass_ent;	size_t pack_hdr_len, pack_data_len, pack_offset, tmp_offset;	u16_t pack_flags_fragoff;	acc_t *prev_head, *new_head, *new_tail, *tmp_acc;	acc_t swap_acc;	ip_hdr_t *tmp_hdr;	time_t first_time;#if DEBUG & 256 { where(); printf("in reassemble()\n"); }#endif	ass_ent= find_ass_ent (port, pack_hdr->ih_id,		pack_hdr->ih_proto, pack_hdr->ih_src, pack_hdr->ih_dst);#if DEBUG & 256 { where(); ip_print_frags(ass_ent->ia_frags); printf("\n"); }#endif	pack_flags_fragoff= ntohs(pack_hdr->ih_flags_fragoff);	pack_hdr_len= (pack_hdr->ih_vers_ihl & IH_IHL_MASK) * 4;	pack_data_len= ntohs(pack_hdr->ih_length)-pack_hdr_len;	pack_offset= (pack_flags_fragoff & IH_FRAGOFF_MASK)*8;	pack->acc_ext_link= NULL;#if DEBUG & 256 { where(); ip_print_frags(pack); printf("\n"); }#endif	new_head= 0;	for (prev_head= ass_ent->ia_frags, ass_ent->ia_frags= NULL; prev_head;		prev_head= prev_head->acc_ext_link)	{		tmp_hdr= (ip_hdr_t *)ptr2acc_data(prev_head);		tmp_offset= (ntohs(tmp_hdr->ih_flags_fragoff) &			IH_FRAGOFF_MASK)*8;#if DEBUG & 256 { where(); printf("tmp_offset= %d, pack_offset= %d\n", tmp_offset, 	pack_offset); }#endif		if (tmp_offset >= pack_offset)			break;		if (new_head)			new_tail->acc_ext_link= prev_head;		else			new_head= prev_head;		new_tail= prev_head;	}	if (prev_head)	{where();		pack= merge_frags(pack, prev_head);	}	if (new_head)	{		pack= merge_frags(new_tail, pack);		if (pack != new_tail)		{			swap_acc= *pack;			*pack= *new_tail;			*new_tail= swap_acc;		}	}	else	{		new_head= pack;		new_tail= pack;	}	ass_ent->ia_frags= new_head;#if DEBUG & 256 { where(); ip_print_frags(ass_ent->ia_frags); printf("\n"); }#endif	pack= ass_ent->ia_frags;	pack_hdr= (ip_hdr_t *)ptr2acc_data(pack);	pack_flags_fragoff= ntohs(pack_hdr->ih_flags_fragoff);#if DEBUG & 256 { where(); printf(		"merge_pack: flags_fragoff= %u, vers_ihl= 0x%x, length= %u\n",	pack_flags_fragoff, pack_hdr->ih_vers_ihl,	ntohs(pack_hdr->ih_length)); }#endif	if (!(pack_flags_fragoff & (IH_FRAGOFF_MASK|IH_MORE_FRAGS)))		/* it's now a complete packet */	{#if DEBUG & 256 { where(); printf("got a complete packet now\n"); }#endif		first_time= ass_ent->ia_first_time;		ass_ent->ia_frags= 0;		ass_ent->ia_first_time= 0;		while (pack->acc_ext_link)		{ { where(); printf("strange\n"); }			tmp_acc= pack->acc_ext_link;			pack->acc_ext_link= tmp_acc->acc_ext_link;			bf_afree(tmp_acc);		}		if ((ass_ent->ia_min_ttl) * HZ + first_time <			get_time())			icmp_frag_ass_tim(pack);		else			return pack;	}	return NULL;}PRIVATE acc_t *merge_frags (first, second)acc_t *first, *second;{	ip_hdr_t *first_hdr, *second_hdr;	size_t first_hdr_size, second_hdr_size, first_datasize, second_datasize,		first_offset, second_offset;	acc_t *cut_second, *tmp_acc;#if DEBUG & 256 { where(); ip_print_frags(first); printf(" , "); ip_print_frags(second); }#endif	if (!second)	{		first->acc_ext_link= NULL;		return first;	}assert (first->acc_length >= IP_MIN_HDR_SIZE);assert (second->acc_length >= IP_MIN_HDR_SIZE);	first_hdr= (ip_hdr_t *)ptr2acc_data(first);	first_offset= (ntohs(first_hdr->ih_flags_fragoff) &		IH_FRAGOFF_MASK) * 8;	first_hdr_size= (first_hdr->ih_vers_ihl & IH_IHL_MASK) * 4;	first_datasize= ntohs(first_hdr->ih_length) - first_hdr_size;	for (;;)	{		second_hdr= (ip_hdr_t *)ptr2acc_data(second);		second_offset= (ntohs(second_hdr->ih_flags_fragoff) &			IH_FRAGOFF_MASK) * 8;		second_hdr_size= (second_hdr->ih_vers_ihl & IH_IHL_MASK) * 4;		second_datasize= ntohs(second_hdr->ih_length) - second_hdr_size;#if DEBUG if (second_offset <= first_offset) { where(); printf ("first_offset= %u, second_offset= %u\n",	first_offset, second_offset); printf ("first_hdr_size= %u, second_hdr_size= %u\n",	first_hdr_size, second_hdr_size); printf ("first_datasize= %u, second_datasize= %u\n",	first_datasize, second_datasize); }#endifassert (first_hdr_size + first_datasize == bf_bufsize(first));assert (second_hdr_size + second_datasize == bf_bufsize(second));assert (second_offset > first_offset);		if (second_offset > first_offset+first_datasize)		{			first->acc_ext_link= second;			return first;		}		if (second_offset + second_datasize <= first_offset +			first_datasize)		{			first->acc_ext_link= second->acc_ext_link;			bf_afree(second);			break;		}		if (!(second_hdr->ih_flags_fragoff & HTONS(IH_MORE_FRAGS)))			first_hdr->ih_flags_fragoff &= ~HTONS(IH_MORE_FRAGS);		second_datasize= second_offset+second_datasize-(first_offset+			first_datasize);		cut_second= bf_cut(second, second_hdr_size + first_offset+			first_datasize-second_offset, second_datasize);		tmp_acc= second->acc_ext_link;		bf_afree(second);		second= tmp_acc;		first_datasize += second_datasize;		first_hdr->ih_length= htons(first_hdr_size + first_datasize);		first= bf_append (first, cut_second);		if (!second)		{			first->acc_ext_link= NULL;			break;		}assert (first->acc_length >= IP_MIN_HDR_SIZE);		first_hdr= (ip_hdr_t *)ptr2acc_data(first);	}assert (first_hdr_size + first_datasize == bf_bufsize(first));	return first;}PRIVATE ip_ass_t *find_ass_ent (port, id, proto, src, dst)ip_port_t *port;u16_t id;ipproto_t proto;ipaddr_t src;ipaddr_t dst;{	ip_ass_t *new_ass_ent, *tmp_ass_ent;	int i;	acc_t *tmp_acc, *curr_acc;#if DEBUG & 256 { where(); printf("find_ass_ent (.., id= %u, proto= %u, src= ",	id, ntohs(proto)); writeIpAddr(src); printf(" dst= ");	writeIpAddr(dst); printf(")\n"); }#endif	new_ass_ent= 0;	for (i=0, tmp_ass_ent= ip_ass_table; i<IP_ASS_NR; i++,		tmp_ass_ent++)	{		if (!tmp_ass_ent->ia_frags && tmp_ass_ent->			ia_first_time)		{#if DEBUG { where(); printf("ip.c: strange ip_ass entry (can be a race condition)\n"); }#endif			continue;		}		if ((tmp_ass_ent->ia_srcaddr == src) &&			(tmp_ass_ent->ia_dstaddr == dst) &&			(tmp_ass_ent->ia_proto == proto) &&			(tmp_ass_ent->ia_id == id) &&			(tmp_ass_ent->ia_port == port))		{#if DEBUG & 256 { where(); printf("found an ass_ent\n"); }#endif			return tmp_ass_ent;		}		if (!new_ass_ent || tmp_ass_ent->ia_first_time <			new_ass_ent->ia_first_time)			new_ass_ent= tmp_ass_ent;	}#if DEBUG & 256 { where(); printf("made an ass_ent\n"); }#endif	new_ass_ent->ia_min_ttl= IP_MAX_TTL;	new_ass_ent->ia_port= port;	new_ass_ent->ia_first_time= get_time();	new_ass_ent->ia_srcaddr= src;	new_ass_ent->ia_dstaddr= dst;	new_ass_ent->ia_proto= proto;	new_ass_ent->ia_id= id;	if (new_ass_ent->ia_frags)	{		curr_acc= new_ass_ent->ia_frags->acc_ext_link;		while (curr_acc)		{			tmp_acc= curr_acc->acc_ext_link;			bf_afree(curr_acc);			curr_acc= tmp_acc;		}		curr_acc= new_ass_ent->ia_frags;		new_ass_ent->ia_frags= 0;		icmp_frag_ass_tim(curr_acc);	}	return new_ass_ent;}PUBLIC void ip_eth_arrived(ip_port, pack)ip_port_t *ip_port;acc_t *pack;{	ip_hdr_t *ip_hdr;	int for_this_port, broadcast_allowed, broadcast_pack;	int ip_frag_len, ip_hdr_len;	acc_t *ip_acc, *eth_acc;	ether_addr_t eth_dst, eth_src;	eth_hdr_t *eth_hdr;	size_t pack_size;#if DEBUG & 256 { where(); printf("ip_eth_arrived(&ip_port_table[%d], packet_length= %d)\n",	ip_port-ip_port_table, bf_bufsize(pack)); }#endif	pack= bf_packIffLess(pack, ETH_HDR_SIZE);assert (pack->acc_length >= ETH_HDR_SIZE);	eth_hdr= (eth_hdr_t *)ptr2acc_data(pack);	eth_dst= eth_hdr->eh_dst;	eth_src= eth_hdr->eh_src;	if (eth_dst.ea_addr[0] & 0x01)		broadcast_pack= TRUE;	else		broadcast_pack= FALSE;	pack_size= bf_bufsize(pack);	eth_acc= bf_cut(pack, 0, ETH_HDR_SIZE);	ip_acc= bf_cut(pack, ETH_HDR_SIZE, pack_size-ETH_HDR_SIZE);	pack_size -= ETH_HDR_SIZE;#if DEBUG & 256 { where(); printf("packet_length= %d\n", bf_bufsize(ip_acc)); }#endif	bf_afree(pack);	if (pack_size < IP_MIN_HDR_SIZE)	{#if DEBUG { where(); printf("wrong acc_length\n"); }#endif		bf_afree(ip_acc);		bf_afree(eth_acc);		return;	}	ip_acc= bf_packIffLess(ip_acc, IP_MIN_HDR_SIZE);assert (ip_acc->acc_length >= IP_MIN_HDR_SIZE);	ip_hdr= (ip_hdr_t *)ptr2acc_data(ip_acc);	ip_hdr_len= (ip_hdr->ih_vers_ihl & IH_IHL_MASK) << 2;	if (ip_hdr_len>IP_MIN_HDR_SIZE)	{		ip_acc= bf_packIffLess(ip_acc, ip_hdr_len);		ip_hdr= (ip_hdr_t *)ptr2acc_data(ip_acc);	}#if DEBUG & 256 { where(); printf("ih_vers_ihl= 0x%x\n", ip_hdr->ih_vers_ihl); }#endif	ip_frag_len= ntohs(ip_hdr->ih_length);	if (ip_frag_len<pack_size)	{		pack= ip_acc;		ip_acc= bf_cut(pack, 0, ip_frag_len);		bf_afree(pack);	}#if DEBUG & 256 { where(); printf("ip_frag_len= %d, packet length= %d\n", ip_frag_len, bf_bufsize(ip_acc)); }#endif	if (!ip_frag_chk(ip_acc))

⌨️ 快捷键说明

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