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

📄 psip.c

📁 Minix比较全的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
		psip_port->pp_rd_head= psip_fd;	else		psip_port->pp_rd_tail->pf_rd_next= psip_fd;	psip_fd->pf_rd_next= NULL;	psip_port->pp_rd_tail= psip_fd;	psip_fd->pf_flags |= PFF_READ_IP;	if (!(psip_fd->pf_flags & PFF_PROMISC))		ipps_get(psip_port->pp_ipdev);	if (psip_fd->pf_flags & PFF_READ_IP)		return NW_SUSPEND;	return NW_OK;}PRIVATE int psip_write(fd, count)int fd;size_t count;{	psip_port_t *psip_port;	psip_fd_t *psip_fd;	acc_t *pack, *hdr_pack;	psip_io_hdr_t *hdr;	size_t pack_len;	ipaddr_t nexthop;	assert(fd >= 0 && fd < PSIP_FD_NR);	psip_fd= &psip_fd_table[fd];	psip_port= psip_fd->pf_port;	pack= (*psip_fd->pf_get_userdata)(psip_fd->pf_srfd, (size_t)0,		count, FALSE);	if (pack == NULL)	{		pack= (*psip_fd->pf_get_userdata)(psip_fd->pf_srfd, 			(size_t)EFAULT, (size_t)0, FALSE);		assert(pack == NULL);		return NW_OK;	}	if (psip_fd->pf_flags & PFF_NEXTHOP)	{		pack_len= bf_bufsize(pack);		if (pack_len <= sizeof(nexthop))		{			/* Something strange */			bf_afree(pack); pack= NULL;			pack= (*psip_fd->pf_get_userdata)(psip_fd->pf_srfd,				(size_t)EPACKSIZE, (size_t)0, FALSE);			assert(pack == NULL);			return NW_OK;		}		pack= bf_packIffLess(pack, sizeof(nexthop));		nexthop= *(ipaddr_t *)ptr2acc_data(pack);		pack= bf_delhead(pack, sizeof(nexthop));		/* Map multicast to broadcast */		if ((nexthop & HTONL(0xE0000000)) == HTONL(0xE0000000))			nexthop= HTONL(0xffffffff);	}	else	{		/* Assume point to point */		nexthop= HTONL(0x00000000);	}	if (psip_port->pp_flags & PPF_PROMISC)	{		/* Deal with promiscuous mode. */		hdr_pack= bf_memreq(sizeof(*hdr));		hdr= (psip_io_hdr_t *)ptr2acc_data(hdr_pack);		memset(hdr, '\0', sizeof(*hdr));		hdr->pih_flags |= PF_REM2LOC;		hdr->pih_nexthop= nexthop;		pack->acc_linkC++;		hdr_pack->acc_next= pack;		hdr_pack->acc_ext_link= NULL;		if (psip_port->pp_promisc_head)		{			/* Append at the end. */			psip_port->pp_promisc_tail->acc_ext_link= hdr_pack;			psip_port->pp_promisc_tail= hdr_pack;		}		else		{			/* First packet. */			psip_port->pp_promisc_head= hdr_pack;			psip_port->pp_promisc_tail= hdr_pack;			if (psip_port->pp_rd_head)				promisc_restart_read(psip_port);		}	}	ipps_put(psip_port->pp_ipdev, nexthop, pack);	pack= (*psip_fd->pf_get_userdata)(psip_fd->pf_srfd, (size_t)count,		(size_t)0, FALSE);	assert(pack == NULL);	return NW_OK;}PRIVATE int psip_select(fd, operations)int fd;unsigned operations;{	printf("psip_select: not implemented\n");	return 0;}PRIVATE void psip_close(fd)int fd;{	psip_port_t *psip_port;	psip_fd_t *psip_fd;	assert(fd >= 0 && fd < PSIP_FD_NR);	psip_fd= &psip_fd_table[fd];	psip_port= psip_fd->pf_port;	if (psip_fd->pf_flags & PFF_PROMISC)	{		/* Check if the port should still be in promiscuous mode.		 */		psip_fd->pf_flags &= ~PFF_PROMISC;		check_promisc(psip_fd->pf_port);	}	assert(psip_port->pp_opencnt >0);	psip_port->pp_opencnt--;	psip_fd->pf_flags= PFF_EMPTY;	ipps_get(psip_port->pp_ipdev);}PRIVATE int psip_cancel(fd, which_operation)int fd;int which_operation;{	psip_port_t *psip_port;	psip_fd_t *psip_fd, *prev_fd, *tmp_fd;	int result;	DBLOCK(1, printf("psip_cancel(%d, %d)\n", fd, which_operation));	assert(fd >= 0 && fd < PSIP_FD_NR);	psip_fd= &psip_fd_table[fd];	psip_port= psip_fd->pf_port;	switch(which_operation)	{	case SR_CANCEL_IOCTL:		ip_panic(( "should not be here" ));	case SR_CANCEL_READ:		assert(psip_fd->pf_flags & PFF_READ_IP);		for (prev_fd= NULL, tmp_fd= psip_port->pp_rd_head; tmp_fd;			prev_fd= tmp_fd, tmp_fd= tmp_fd->pf_rd_next)		{			if (tmp_fd == psip_fd)				break;		}		if (tmp_fd == NULL)			ip_panic(( "unable to find to request to cancel" ));		if (prev_fd == NULL)			psip_port->pp_rd_head= psip_fd->pf_rd_next;		else			prev_fd->pf_rd_next= psip_fd->pf_rd_next;		if (psip_fd->pf_rd_next == NULL)			psip_port->pp_rd_tail= prev_fd;		psip_fd->pf_flags &= ~PFF_READ_IP;		result= (*psip_fd->pf_put_userdata)(psip_fd->pf_srfd,						(size_t)EINTR, NULL, FALSE);		assert(result == NW_OK);		break;	case SR_CANCEL_WRITE:		ip_panic(( "should not be here" ));	default:		ip_panic(( "invalid operation for cancel" ));	}	return NW_OK;}PRIVATE void promisc_restart_read(psip_port)psip_port_t *psip_port;{	psip_fd_t *psip_fd, *prev, *next;	acc_t *pack;	size_t buf_size;	int result, result1;	/* Overkill at the moment: just one reader in promiscious mode is	 * allowed.	 */	pack= psip_port->pp_promisc_head;	if (!pack)		return;	assert(pack->acc_ext_link == NULL);	for(psip_fd= psip_port->pp_rd_head, prev= NULL; psip_fd;		prev= psip_fd, psip_fd= psip_fd->pf_rd_next)	{again:		if (!(psip_fd->pf_flags & PFF_PROMISC))			continue;		next= psip_fd->pf_rd_next;		if (prev)			prev->pf_rd_next= next;		else			psip_port->pp_rd_head= next;		if (!next)			psip_port->pp_rd_tail= prev;		assert(psip_fd->pf_flags & PFF_READ_IP);		psip_fd->pf_flags &= ~PFF_READ_IP;		buf_size= bf_bufsize(pack);		if (buf_size <= psip_fd->pf_rd_count)		{			psip_port->pp_promisc_head= pack->acc_ext_link;			result= (*psip_fd->pf_put_userdata)(psip_fd->pf_srfd, 				(size_t)0, pack, FALSE);			if (result == NW_OK)				result= buf_size;		}		else			result= EPACKSIZE;		result1= (*psip_fd->pf_put_userdata)(psip_fd->pf_srfd,				(size_t)result, NULL, FALSE);		assert(result1 == NW_OK);		if (psip_port->pp_promisc_head)		{			/* Restart from the beginning */			assert(result == EPACKSIZE);			psip_fd= psip_port->pp_rd_head;			prev= NULL;			goto again;		}		break;	}}PRIVATE int psip_setopt(psip_fd, newoptp)psip_fd_t *psip_fd;nwio_psipopt_t *newoptp;{	nwio_psipopt_t oldopt;	unsigned int new_en_flags, new_di_flags, old_en_flags, old_di_flags;	unsigned long new_flags;	oldopt= psip_fd->pf_psipopt;	old_en_flags= oldopt.nwpo_flags & 0xffff;	old_di_flags= (oldopt.nwpo_flags >> 16) & 0xffff;	new_en_flags= newoptp->nwpo_flags & 0xffff;	new_di_flags= (newoptp->nwpo_flags >> 16) & 0xffff;	if (new_en_flags & new_di_flags)		return EBADMODE;	/* NWUO_LOCADDR_MASK */	if (!((new_en_flags | new_di_flags) & NWPO_PROMISC_MASK))	{		new_en_flags |= (old_en_flags & NWPO_PROMISC_MASK);		new_di_flags |= (old_di_flags & NWPO_PROMISC_MASK);	}	new_flags= ((unsigned long)new_di_flags << 16) | new_en_flags;	if ((new_flags & NWPO_EN_PROMISC) &&		(psip_fd->pf_port->pp_flags & PPF_PROMISC))	{		printf("psip_setopt: EBUSY for port %d, flags 0x%x\n",			psip_fd->pf_port - psip_port_table,			psip_fd->pf_port->pp_flags);		/* We can support only one at a time. */		return EBUSY;	}	psip_fd->pf_psipopt= *newoptp;	psip_fd->pf_psipopt.nwpo_flags= new_flags;	return NW_OK;}PRIVATE void check_promisc(psip_port)psip_port_t *psip_port;{	int i;	psip_fd_t *psip_fd;	acc_t *acc, *acc_next;	/* Check if the port should still be in promiscuous mode.  Overkill	 * at the moment.	 */	if (!(psip_port->pp_flags & PPF_PROMISC))		return;	psip_port->pp_flags &= ~PPF_PROMISC;	for (i= 0, psip_fd= psip_fd_table; i<PSIP_FD_NR; i++, psip_fd++)	{		if ((psip_fd->pf_flags & (PFF_INUSE|PFF_PROMISC)) !=			(PFF_INUSE|PFF_PROMISC))		{			continue;		}		if (psip_fd->pf_port != psip_port)			continue;		printf("check_promisc: setting PROMISC for port %d\n",			psip_port-psip_port_table);		psip_port->pp_flags |= PPF_PROMISC;		break;	}	if (!(psip_port->pp_flags & PPF_PROMISC))	{		/* Delete queued packets. */		acc= psip_port->pp_promisc_head;		psip_port->pp_promisc_head= NULL;		while (acc)		{			acc_next= acc->acc_ext_link;			bf_afree(acc);			acc= acc_next;		}	}}PRIVATE void psip_buffree (priority)int priority;{	int i;	psip_port_t *psip_port;	acc_t *tmp_acc, *next_acc;	if (priority == PSIP_PRI_EXP_PROMISC)	{		for (i=0, psip_port= psip_port_table; i<psip_conf_nr;			i++, psip_port++)		{			if (!(psip_port->pp_flags & PPF_CONFIGURED) )				continue;			if (psip_port->pp_promisc_head)			{				tmp_acc= psip_port->pp_promisc_head;				while(tmp_acc)				{					next_acc= tmp_acc->acc_ext_link;					bf_afree(tmp_acc);					tmp_acc= next_acc;				}				psip_port->pp_promisc_head= NULL;			}		}	}}#ifdef BUF_CONSISTENCY_CHECKPRIVATE void psip_bufcheck(){	int i;	psip_port_t *psip_port;	acc_t *tmp_acc;	for (i= 0, psip_port= psip_port_table; i<psip_conf_nr;		i++, psip_port++)	{		for (tmp_acc= psip_port->pp_promisc_head; tmp_acc; 			tmp_acc= tmp_acc->acc_ext_link)		{			bf_check_acc(tmp_acc);		}	}}#endif/*reply_thr_put*/PRIVATE void reply_thr_put(psip_fd, reply, for_ioctl)psip_fd_t *psip_fd;int reply;int for_ioctl;{	int result;	result= (*psip_fd->pf_put_userdata)(psip_fd->pf_srfd, reply,		(acc_t *)0, for_ioctl);	assert(result == NW_OK);}/*reply_thr_get*/PRIVATE void reply_thr_get(psip_fd, reply, for_ioctl)psip_fd_t *psip_fd;int reply;int for_ioctl;{	acc_t *result;	result= (*psip_fd->pf_get_userdata)(psip_fd->pf_srfd, reply,		(size_t)0, for_ioctl);	assert (!result);}/* * $PchId: psip.c,v 1.15 2005/06/28 14:19:29 philip Exp $ */

⌨️ 快捷键说明

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