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

📄 eth.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	eth_fd->ef_rd_buf= 0;}PRIVATE int eth_checkopt (eth_fd)eth_fd_t *eth_fd;{/* bug: we don't check access modes yet */	unsigned long flags;	unsigned int en_di_flags;	eth_port_t *eth_port;	acc_t *acc, *acc2;	eth_port= eth_fd->ef_port;	flags= eth_fd->ef_ethopt.nweo_flags;#if DEBUG & 256 { where(); printf("eth_fd_table[%d].ef_ethopt.nweo_flags= 0x%x\n",	eth_fd-eth_fd_table, flags); }#endif	en_di_flags= (flags >>16) | (flags & 0xffff);	if ((en_di_flags & NWEO_ACC_MASK) &&		(en_di_flags & NWEO_LOC_MASK) &&		(en_di_flags & NWEO_BROAD_MASK) &&		(en_di_flags & NWEO_MULTI_MASK) &&		(en_di_flags & NWEO_PROMISC_MASK) &&		(en_di_flags & NWEO_REM_MASK) &&		(en_di_flags & NWEO_TYPE_MASK) &&		(en_di_flags & NWEO_RW_MASK))	{		eth_fd->ef_flags |= EFF_OPTSET;		eth_fd->ef_pack_stat= EPS_EMPTY;		if (flags & NWEO_EN_LOC)			eth_fd->ef_pack_stat |= EPS_LOC;		if (flags & NWEO_EN_BROAD)			eth_fd->ef_pack_stat |= EPS_BROAD;		if (flags & NWEO_EN_MULTI)			eth_fd->ef_pack_stat |= EPS_MULTI;		if (flags & NWEO_EN_PROMISC)			eth_fd->ef_pack_stat |= (EPS_PROMISC|EPS_MULTI|				EPS_BROAD);	}	else		eth_fd->ef_flags &= ~EFF_OPTSET;		for (acc= eth_fd->ef_rd_buf; acc;)	{		acc2= acc->acc_ext_link;		bf_afree(acc);		acc= acc2;	}	eth_fd->ef_rd_buf= 0;	return NW_OK;}PUBLIC int eth_get_work(eth_port)eth_port_t *eth_port;{	eth_fd_t *eth_fd;	int i;#if DEBUG & 256 { where(); printf("eth_get_work called\n"); }#endif	if (eth_port->etp_wr_pack)		return 0;	if (!(eth_port->etp_flags & EPF_MORE2WRITE))		return 0;	for (i=0, eth_fd= eth_fd_table; i<ETH_FD_NR; i++, eth_fd++)	{		if ((eth_fd->ef_flags & (EFF_INUSE|EFF_WRITE_IP)) !=			(EFF_INUSE|EFF_WRITE_IP))			continue;		if (eth_fd->ef_port != eth_port)			continue;#if DEBUG & 256 { where(); printf("eth_get_work calling restart_write_fd\n"); }#endif		restart_write_fd(eth_fd);		if (eth_port->etp_wr_pack)			return 1;	}	eth_port->etp_flags &= ~EPF_MORE2WRITE;	return 0;}PUBLIC void eth_arrive (eth_port, pack)eth_port_t *eth_port;acc_t *pack;{	time_t exp_tim;	eth_hdr_t *eth_hdr;	static ether_addr_t broadcast= {255, 255, 255, 255, 255, 255},		multi_addr, rem_addr, packaddr;	int pack_stat;	ether_type_t type;	eth_fd_t *eth_fd, *share_fd;	acc_t *acc;	int i;#if DEBUG & 256 { where(); printf("eth_arrive(0x%x, 0x%x) called\n", eth_port, pack); }#endifassert(pack->acc_linkC);	exp_tim= get_time() + EXPIRE_TIME;	pack= bf_packIffLess(pack, ETH_HDR_SIZE);	eth_hdr= (eth_hdr_t*)ptr2acc_data(pack);#if DEBUG & 256 { where(); printf("src= "); writeEtherAddr(&eth_hdr->eh_src); printf(" dst= "); 	writeEtherAddr(&eth_hdr->eh_dst);	printf(" proto= 0x%x\n", ntohs(eth_hdr->eh_proto));	printf(" my addr= "); writeEtherAddr(&eth_port->etp_ethaddr);	printf("\n"); }#endif	packaddr= eth_hdr->eh_dst;	if (packaddr.ea_addr[0] & 0x01)	{		/* multi cast or broadcast */		if (!eth_addrcmp(packaddr, broadcast))			pack_stat= EPS_BROAD;		else		{			pack_stat= EPS_MULTI;#if DEBUG { where(); printf("Got a multicast packet\n"); }#endif		}	}	else	{		if (!eth_addrcmp (packaddr, eth_port->etp_ethaddr))			pack_stat= EPS_LOC;		else			pack_stat= EPS_PROMISC;	}	type= eth_hdr->eh_proto;#if DEBUG & 256 { where(); printf("pack_stat= 0x%x\n", pack_stat); }#endif	share_fd= 0;	for (i=0, eth_fd=eth_fd_table; i<ETH_FD_NR; i++, eth_fd++)	{		if (!(eth_fd->ef_flags & EFF_OPTSET))		{#if DEBUG & 256 { where(); printf("fd %d doesn't have EFF_OPTSET\n", i); }#endif			continue;		}		if (eth_fd->ef_port != eth_port)		{#if DEBUG { where(); printf("fd %d uses port %d, packet is on port %d\n", i, 	eth_fd->ef_port-eth_port_table, eth_port-eth_port_table); }#endif			continue;		}		if (!(eth_fd->ef_pack_stat & pack_stat))		{#if DEBUG & 256 { where(); printf("fd %d has ef_pack_stat 0x%x, expecting 0x%x\n", i,	eth_fd->ef_pack_stat, pack_stat); }#endif			continue;		}		if ((eth_fd->ef_ethopt.nweo_flags & NWEO_TYPESPEC) &&			type != eth_fd->ef_ethopt.nweo_type)		{#if DEBUG & 256 { where(); printf("fd %d uses type 0x%x, expecting 0x%x\n", i,	eth_fd->ef_ethopt.nweo_type, type); }#endif			continue;		}#if DEBUG & 256 { where(); printf("multi OK\n"); }#endif		if (eth_fd->ef_ethopt.nweo_flags & NWEO_REMSPEC)		{			rem_addr= eth_fd->ef_ethopt.nweo_rem;			if (eth_addrcmp (eth_hdr->eh_src,				rem_addr))				continue;		}#if DEBUG & 256 { where(); printf("rem NW_OK\n"); }#endif		if (eth_fd->ef_rd_buf)		{			if (eth_fd->ef_ethopt.nweo_flags == NWEO_SHARED)			{				share_fd= eth_fd;				continue;			}		}		acc= bf_dupacc(pack);		acc->acc_ext_link= NULL;		if (!eth_fd->ef_rd_buf)		{			eth_fd->ef_rd_buf= acc;			eth_fd->ef_exp_tim= exp_tim;		}		else			eth_fd->ef_rd_tail->acc_ext_link= acc;		eth_fd->ef_rd_tail= acc;		if (eth_fd->ef_flags & EFF_READ_IP)			packet2user(eth_fd);		if ((eth_fd->ef_ethopt.nweo_flags & NWEO_ACC_MASK) != NWEO_COPY)		{			bf_afree(pack);			pack= 0;			break;		}	}	if (share_fd && pack)	{		acc= bf_dupacc(pack);		acc->acc_ext_link= NULL;		if (!share_fd->ef_rd_buf)		{			share_fd->ef_rd_buf= acc;			share_fd->ef_exp_tim= exp_tim;		}		else			share_fd->ef_rd_tail->acc_ext_link= acc;		share_fd->ef_rd_tail= acc;	}	if (pack)		bf_afree(pack);}PRIVATE int packet2user (eth_fd)eth_fd_t *eth_fd;{	acc_t *pack, *header;	int result;	size_t size;#if DEBUG & 256 { where(); printf("packet2user() called\n"); }#endif	pack= eth_fd->ef_rd_buf;	eth_fd->ef_rd_buf= pack->acc_ext_link;	if (eth_fd->ef_ethopt.nweo_flags & NWEO_RWDATONLY)	{		pack= bf_packIffLess (pack, ETH_HDR_SIZE);		assert (pack->acc_length >= ETH_HDR_SIZE);		if (pack->acc_linkC >1)		{			header= bf_dupacc (pack);			bf_afree(pack);			pack= header;		}		assert (pack->acc_linkC == 1);		pack->acc_offset += ETH_HDR_SIZE;		pack->acc_length -= ETH_HDR_SIZE;	}	size= bf_bufsize (pack);	eth_fd->ef_flags &= ~EFF_READ_IP;	result= (*eth_fd->ef_put_userdata)(eth_fd->ef_srfd, (size_t)0, pack,		FALSE);	if (result >=0)		reply_thr_put(eth_fd, size, FALSE);	return result<0 ? result : NW_OK;}PRIVATE int ok_for_me (eth_fd, pack)eth_fd_t *eth_fd;acc_t *pack;{	eth_port_t *eth_port;	eth_hdr_t *eth_hdr;	ether_type_t type;	static ether_addr_t broadcast= {255, 255, 255, 255, 255, 255},		packaddr, portaddr, multi_addr, rem_addr;	int pack_kind;	assert (pack->acc_length >= ETH_HDR_SIZE);	eth_port= eth_fd->ef_port;	eth_hdr= (eth_hdr_t *)ptr2acc_data(pack);	packaddr= eth_hdr->eh_dst;	if (packaddr.ea_addr[0] & 0x01)		/* multi cast or broadcast */		if (!eth_addrcmp (packaddr, broadcast))			pack_kind= EPS_BROAD;		else			pack_kind= EPS_MULTI;	else	{		portaddr= eth_port->etp_ethaddr;		if (!eth_addrcmp(packaddr, portaddr))			pack_kind= EPS_LOC;		else			pack_kind= EPS_PROMISC;	}	pack_kind &= eth_fd->ef_pack_stat;	if (!pack_kind)		return FALSE;	type= eth_hdr->eh_proto;	if ((eth_fd->ef_ethopt.nweo_flags & NWEO_TYPESPEC) &&		type != eth_fd->ef_ethopt.nweo_type)		return FALSE;	if (eth_fd->ef_ethopt.nweo_flags & NWEO_REMSPEC)	{		rem_addr= eth_fd->ef_ethopt.nweo_rem;		if (eth_addrcmp(eth_hdr->eh_src, rem_addr))			return FALSE;	}	return TRUE;}PRIVATE void eth_buffree (priority, reqsize)int priority;size_t reqsize;{	int i, once_more;	time_t curr_tim;	acc_t *acc;	if (priority <ETH_PRI_EXP_FDBUFS)		return;#if DEBUG & 256 { where(); printf("eth_buffree called\n"); }#endif	curr_tim= get_time();	for (i=0; i<ETH_FD_NR; i++)	{		if (!(eth_fd_table[i].ef_flags & EFF_INUSE) )			continue;		acc= eth_fd_table[i].ef_rd_buf;		if (acc && eth_fd_table[i].ef_exp_tim < curr_tim)		{			eth_fd_table[i].ef_rd_buf= acc->acc_ext_link;			bf_afree(acc);			if (bf_free_buffsize >= reqsize)				return;		}	}	if (priority <ETH_PRI_FDBUFS)		return;	once_more= 1;	while (once_more)	{		once_more= 0;		for (i=0; i<ETH_FD_NR; i++)		{			if (!(eth_fd_table[i].ef_flags & EFF_INUSE))				continue;			acc= eth_fd_table[i].ef_rd_buf;			if (acc)			{				eth_fd_table[i].ef_rd_buf= acc->acc_ext_link;				bf_afree(acc);				if (bf_free_buffsize >= reqsize)					return;				once_more= 1;			}		}	}}PRIVATE void restart_write_fd(eth_fd)eth_fd_t *eth_fd;{	eth_port_t *eth_port;	acc_t *user_data, *header;	int size;	unsigned long nweo_flags;	eth_hdr_t *eth_hdr;	eth_port= eth_fd->ef_port;	if (eth_port->etp_wr_pack)	{		eth_port->etp_flags |= EPF_MORE2WRITE;		return;	}assert (eth_fd->ef_flags & EFF_WRITE_IP);	eth_fd->ef_flags &= ~EFF_WRITE_IP;assert (!eth_port->etp_wr_pack);#if DEBUG & 256 { where(); printf("calling *get_userdata\n"); }#endif	user_data= (*eth_fd->ef_get_userdata)(eth_fd->ef_srfd, 0,		eth_fd->ef_write_count, FALSE);	if (!user_data)	{		eth_fd->ef_flags &= ~EFF_WRITE_IP;		reply_thr_get (eth_fd, EFAULT, FALSE);		return;	}	size= bf_bufsize (user_data);	nweo_flags= eth_fd->ef_ethopt.nweo_flags;	if (nweo_flags & NWEO_RWDATONLY)	{		header= bf_memreq(ETH_HDR_SIZE);		header->acc_next= user_data;		user_data= header;	}	user_data= bf_packIffLess (user_data, ETH_HDR_SIZE);	eth_hdr= (eth_hdr_t *)ptr2acc_data(user_data);	if (nweo_flags & NWEO_REMSPEC)		eth_hdr->eh_dst= eth_fd->ef_ethopt.nweo_rem;	eth_hdr->eh_src= eth_port->etp_ethaddr;	if (nweo_flags & NWEO_TYPESPEC)		eth_hdr->eh_proto= eth_fd->ef_ethopt.nweo_type;assert (!eth_port->etp_wr_pack);	eth_port->etp_wr_pack= user_data;	if (!(eth_port->etp_flags & EPF_WRITE_IP))	{		eth_write_port(eth_port);	}	reply_thr_get (eth_fd, size, FALSE);}PRIVATE void reply_thr_get (eth_fd, result, for_ioctl)eth_fd_t *eth_fd;size_t result;int for_ioctl;{	acc_t *data;#if DEBUG & 256 { where(); printf("calling *get_userdata(fd= %d, %d, 0)\n", eth_fd->	ef_srfd, result, 0); }#endif	data= (*eth_fd->ef_get_userdata)(eth_fd->ef_srfd, result, 0, for_ioctl);assert (!data);	}PRIVATE void reply_thr_put (eth_fd, result, for_ioctl)eth_fd_t *eth_fd;size_t result;int for_ioctl;{	int error;	error= (*eth_fd->ef_put_userdata)(eth_fd->ef_srfd, result, (acc_t *)0,		for_ioctl);assert(!error);}

⌨️ 快捷键说明

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