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

📄 ip.c

📁 Minix3.11的源码。[MINIX 3是一个为高可靠性应用而设计的自由且简洁的类UNIX系统。]
💻 C
字号:
/*ip.cCopyright 1995 Philip Homburg*/#include "inet.h"#include "buf.h"#include "event.h"#include "type.h"#include "arp.h"#include "assert.h"#include "clock.h"#include "eth.h"#include "icmp.h"#include "icmp_lib.h"#include "io.h"#include "ip.h"#include "ip_int.h"#include "ipr.h"#include "sr.h"THIS_FILEFORWARD void ip_close ARGS(( int fd ));FORWARD int ip_cancel ARGS(( int fd, int which_operation ));FORWARD int ip_select ARGS(( int fd, unsigned operations ));FORWARD void ip_buffree ARGS(( int priority ));#ifdef BUF_CONSISTENCY_CHECKFORWARD void ip_bufcheck ARGS(( void ));#endifFORWARD void ip_bad_callback ARGS(( struct ip_port *ip_port ));PUBLIC ip_port_t *ip_port_table;PUBLIC ip_fd_t ip_fd_table[IP_FD_NR];PUBLIC ip_ass_t ip_ass_table[IP_ASS_NR];PUBLIC void ip_prep(){	ip_port_table= alloc(ip_conf_nr * sizeof(ip_port_table[0]));	icmp_prep();}PUBLIC void ip_init(){	int i, j, result;	ip_ass_t *ip_ass;	ip_fd_t *ip_fd;	ip_port_t *ip_port;	struct ip_conf *icp;	assert (BUF_S >= sizeof(struct nwio_ethopt));	assert (BUF_S >= IP_MAX_HDR_SIZE + ETH_HDR_SIZE);	assert (BUF_S >= sizeof(nwio_ipopt_t));	assert (BUF_S >= sizeof(nwio_route_t));	for (i=0, ip_ass= ip_ass_table; i<IP_ASS_NR; i++, ip_ass++)	{		ip_ass->ia_frags= 0;		ip_ass->ia_first_time= 0;		ip_ass->ia_port= 0;	}	for (i=0, ip_fd= ip_fd_table; i<IP_FD_NR; i++, ip_fd++)	{		ip_fd->if_flags= IFF_EMPTY;		ip_fd->if_rdbuf_head= 0;	}	for (i=0, ip_port= ip_port_table, icp= ip_conf;		i<ip_conf_nr; i++, ip_port++, icp++)	{		ip_port->ip_port= i;		ip_port->ip_flags= IPF_EMPTY;		ip_port->ip_dev_main= (ip_dev_t)ip_bad_callback;		ip_port->ip_dev_set_ipaddr= (ip_dev_t)ip_bad_callback;		ip_port->ip_dev_send= (ip_dev_send_t)ip_bad_callback;		ip_port->ip_dl_type= icp->ic_devtype;		ip_port->ip_mtu= IP_DEF_MTU;		ip_port->ip_mtu_max= IP_MAX_PACKSIZE;		switch(ip_port->ip_dl_type)		{		case IPDL_ETH:			ip_port->ip_dl.dl_eth.de_port= icp->ic_port;			result= ipeth_init(ip_port);			if (result == -1)				continue;			assert(result == NW_OK);			break;		case IPDL_PSIP:			ip_port->ip_dl.dl_ps.ps_port= icp->ic_port;			result= ipps_init(ip_port);			if (result == -1)				continue;			assert(result == NW_OK);			break;		default:			ip_panic(( "unknown ip_dl_type %d", 							ip_port->ip_dl_type ));			break;		}		ip_port->ip_loopb_head= NULL;		ip_port->ip_loopb_tail= NULL;		ev_init(&ip_port->ip_loopb_event);		ip_port->ip_routeq_head= NULL;		ip_port->ip_routeq_tail= NULL;		ev_init(&ip_port->ip_routeq_event);		ip_port->ip_flags |= IPF_CONFIGURED;		ip_port->ip_proto_any= NULL;		for (j= 0; j<IP_PROTO_HASH_NR; j++)			ip_port->ip_proto[j]= NULL;	}#ifndef BUF_CONSISTENCY_CHECK	bf_logon(ip_buffree);#else	bf_logon(ip_buffree, ip_bufcheck);#endif	icmp_init();	ipr_init();	for (i=0, ip_port= ip_port_table; i<ip_conf_nr; i++, ip_port++)	{		if (!(ip_port->ip_flags & IPF_CONFIGURED))			continue;		ip_port->ip_frame_id= (u16_t)get_time();		sr_add_minor(if2minor(ip_conf[i].ic_ifno, IP_DEV_OFF),			i, ip_open, ip_close, ip_read,			ip_write, ip_ioctl, ip_cancel, ip_select);		(*ip_port->ip_dev_main)(ip_port);	}}PRIVATE int ip_cancel (fd, which_operation)int fd;int which_operation;{	ip_fd_t *ip_fd;	acc_t *repl_res;	int result;	ip_fd= &ip_fd_table[fd];	switch (which_operation)	{	case SR_CANCEL_IOCTL:		assert (ip_fd->if_flags & IFF_IOCTL_IP);		ip_fd->if_flags &= ~IFF_IOCTL_IP;		repl_res= (*ip_fd->if_get_userdata)(ip_fd->if_srfd, 			(size_t)EINTR, (size_t)0, TRUE);		assert (!repl_res);		break;	case SR_CANCEL_READ:		assert (ip_fd->if_flags & IFF_READ_IP);		ip_fd->if_flags &= ~IFF_READ_IP;		result= (*ip_fd->if_put_userdata)(ip_fd->if_srfd, 			(size_t)EINTR, (acc_t *)0, FALSE);		assert (!result);		break;#if 0	case SR_CANCEL_WRITE:		assert(0);		assert (ip_fd->if_flags & IFF_WRITE_MASK);		ip_fd->if_flags &= ~IFF_WRITE_MASK;		repl_res= (*ip_fd->if_get_userdata)(ip_fd->if_srfd, 			(size_t)EINTR, (size_t)0, FALSE);		assert (!repl_res);		break;#endif	default:		ip_panic(( "unknown cancel request" ));		break;	}	return NW_OK;}PRIVATE int ip_select(fd, operations)int fd;unsigned operations;{	printf("ip_select: not implemented\n");	return 0;}PUBLIC int ip_open (port, srfd, get_userdata, put_userdata, put_pkt,	select_res)int port;int srfd;get_userdata_t get_userdata;put_userdata_t put_userdata;put_pkt_t put_pkt;select_res_t select_res;{	int i;	ip_fd_t *ip_fd;	ip_port_t *ip_port;	ip_port= &ip_port_table[port];	if (!(ip_port->ip_flags & IPF_CONFIGURED))		return ENXIO;	for (i=0; i<IP_FD_NR && (ip_fd_table[i].if_flags & IFF_INUSE);		i++);	if (i>=IP_FD_NR)	{		DBLOCK(1, printf("out of fds\n"));		return EAGAIN;	}	ip_fd= &ip_fd_table[i];	ip_fd->if_flags= IFF_INUSE;	ip_fd->if_ipopt.nwio_flags= NWIO_DEFAULT;	ip_fd->if_ipopt.nwio_tos= 0;	ip_fd->if_ipopt.nwio_df= FALSE;	ip_fd->if_ipopt.nwio_ttl= 255;	ip_fd->if_ipopt.nwio_hdropt.iho_opt_siz= 0;	ip_fd->if_port= ip_port;	ip_fd->if_srfd= srfd;	assert(ip_fd->if_rdbuf_head == NULL);	ip_fd->if_get_userdata= get_userdata;	ip_fd->if_put_userdata= put_userdata;	ip_fd->if_put_pkt= put_pkt;	return i;}PRIVATE void ip_close (fd)int fd;{	ip_fd_t *ip_fd;	acc_t *pack;	ip_fd= &ip_fd_table[fd];	assert ((ip_fd->if_flags & IFF_INUSE) &&		!(ip_fd->if_flags & IFF_BUSY));	if (ip_fd->if_flags & IFF_OPTSET)		ip_unhash_proto(ip_fd);	while (ip_fd->if_rdbuf_head)	{		pack= ip_fd->if_rdbuf_head;		ip_fd->if_rdbuf_head= pack->acc_ext_link;		bf_afree(pack);	}	ip_fd->if_flags= IFF_EMPTY;}PRIVATE void ip_buffree(priority)int priority;{	int i;	ip_port_t *ip_port;	ip_fd_t *ip_fd;	ip_ass_t *ip_ass;	acc_t *pack, *next_pack;	for (i= 0, ip_port= ip_port_table; i<ip_conf_nr; i++, ip_port++)	{		if (ip_port->ip_dl_type == IPDL_ETH)		{			/* Can't free de_frame.			 * bf_check_acc(ip_port->ip_dl.dl_eth.de_frame);			 */			if (priority == IP_PRI_PORTBUFS)			{				next_pack= ip_port->ip_dl.dl_eth.de_arp_head;				while(next_pack != NULL)				{					pack= next_pack;					next_pack= pack->acc_ext_link;					bf_afree(pack);				}				ip_port->ip_dl.dl_eth.de_arp_head= next_pack;				next_pack= ip_port->ip_dl.dl_eth.de_q_head;				while(next_pack != NULL)				{					pack= next_pack;					next_pack= pack->acc_ext_link;					bf_afree(pack);				}				ip_port->ip_dl.dl_eth.de_q_head= next_pack;			}		}		else if (ip_port->ip_dl_type == IPDL_PSIP)		{			if (priority == IP_PRI_PORTBUFS)			{				next_pack= ip_port->ip_dl.dl_ps.ps_send_head;				while (next_pack != NULL)				{					pack= next_pack;					next_pack= pack->acc_ext_link;					bf_afree(pack);				}				ip_port->ip_dl.dl_ps.ps_send_head= next_pack;			}		}		if (priority == IP_PRI_PORTBUFS)		{			next_pack= ip_port->ip_loopb_head;			while(next_pack && next_pack->acc_ext_link)			{				pack= next_pack;				next_pack= pack->acc_ext_link;				bf_afree(pack);			}			if (next_pack)			{				if (ev_in_queue(&ip_port->ip_loopb_event))				{#if DEBUG					printf("not freeing ip_loopb_head, ip_loopb_event enqueued\n");#endif				}				else				{					bf_afree(next_pack);					next_pack= NULL;				}			}			ip_port->ip_loopb_head= next_pack;			next_pack= ip_port->ip_routeq_head;			while(next_pack && next_pack->acc_ext_link)			{				pack= next_pack;				next_pack= pack->acc_ext_link;				bf_afree(pack);			}			if (next_pack)			{				if (ev_in_queue(&ip_port->ip_routeq_event))				{#if DEBUG					printf("not freeing ip_loopb_head, ip_routeq_event enqueued\n");#endif				}				else				{					bf_afree(next_pack);					next_pack= NULL;				}			}			ip_port->ip_routeq_head= next_pack;		}	}	if (priority == IP_PRI_FDBUFS_EXTRA)	{		for (i= 0, ip_fd= ip_fd_table; i<IP_FD_NR; i++, ip_fd++)		{			while (ip_fd->if_rdbuf_head &&				ip_fd->if_rdbuf_head->acc_ext_link)			{				pack= ip_fd->if_rdbuf_head;				ip_fd->if_rdbuf_head= pack->acc_ext_link;				bf_afree(pack);			}		}	}	if (priority == IP_PRI_FDBUFS)	{		for (i= 0, ip_fd= ip_fd_table; i<IP_FD_NR; i++, ip_fd++)		{			while (ip_fd->if_rdbuf_head)			{				pack= ip_fd->if_rdbuf_head;				ip_fd->if_rdbuf_head= pack->acc_ext_link;				bf_afree(pack);			}		}	}	if (priority == IP_PRI_ASSBUFS)	{		for (i= 0, ip_ass= ip_ass_table; i<IP_ASS_NR; i++, ip_ass++)		{			next_pack= ip_ass->ia_frags;			while(ip_ass->ia_frags != NULL)			{				pack= ip_ass->ia_frags;				ip_ass->ia_frags= pack->acc_ext_link;				bf_afree(pack);			}			ip_ass->ia_first_time= 0;		}	}}#ifdef BUF_CONSISTENCY_CHECKPRIVATE void ip_bufcheck(){	int i;	ip_port_t *ip_port;	ip_fd_t *ip_fd;	ip_ass_t *ip_ass;	acc_t *pack;	for (i= 0, ip_port= ip_port_table; i<ip_conf_nr; i++, ip_port++)	{		if (ip_port->ip_dl_type == IPDL_ETH)		{			bf_check_acc(ip_port->ip_dl.dl_eth.de_frame);			for (pack= ip_port->ip_dl.dl_eth.de_q_head; pack;				pack= pack->acc_ext_link)			{				bf_check_acc(pack);			}			for (pack= ip_port->ip_dl.dl_eth.de_arp_head; pack;				pack= pack->acc_ext_link)			{				bf_check_acc(pack);			}		}		else if (ip_port->ip_dl_type == IPDL_PSIP)		{			for (pack= ip_port->ip_dl.dl_ps.ps_send_head; pack;				pack= pack->acc_ext_link)			{				bf_check_acc(pack);			}		}		for (pack= ip_port->ip_loopb_head; pack;			pack= pack->acc_ext_link)		{			bf_check_acc(pack);		}		for (pack= ip_port->ip_routeq_head; pack;			pack= pack->acc_ext_link)		{			bf_check_acc(pack);		}	}	for (i= 0, ip_fd= ip_fd_table; i<IP_FD_NR; i++, ip_fd++)	{		for (pack= ip_fd->if_rdbuf_head; pack;			pack= pack->acc_ext_link)		{			bf_check_acc(pack);		}	}	for (i= 0, ip_ass= ip_ass_table; i<IP_ASS_NR; i++, ip_ass++)	{		for (pack= ip_ass->ia_frags; pack; pack= pack->acc_ext_link)			bf_check_acc(pack);	}}#endif /* BUF_CONSISTENCY_CHECK */PRIVATE void ip_bad_callback(ip_port)struct ip_port *ip_port;{	ip_panic(( "no callback filled in for port %d", ip_port->ip_port ));}/* * $PchId: ip.c,v 1.19 2005/06/28 14:17:40 philip Exp $ */

⌨️ 快捷键说明

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