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

📄 ip_write.c

📁 最新Minix3源码
💻 C
📖 第 1 页 / 共 2 页
字号:
#if DEBUG & 256 { where(); printf("processing arp_pack\n"); }#endif		assert (ip_port->ip_dl.dl_eth.de_arp_pack);		ip_port->ip_dl.dl_eth.de_wr_ipaddr= (ipaddr_t)0;		ip_port->ip_dl.dl_eth.de_wr_ethaddr= ip_port->ip_dl.			dl_eth.de_arp_ethaddr;		ip_port->ip_dl.dl_eth.de_wr_frag= ip_port->ip_dl.dl_eth.			de_arp_pack;		ip_port->ip_dl.dl_eth.de_flags &= ~IEF_ARP_MASK;		return;	}	for (i=0, ip_fd= ip_fd_table; i<IP_FD_NR; i++, ip_fd++)	{		if (!(ip_fd->if_flags & IFF_INUSE))			continue;		if (!(ip_fd->if_flags & IFF_DLL_WR_IP))			continue;		if (ip_fd->if_wr_port != ip_port)			continue;#if DEBUG & 256 { where(); printf("calling restart_fd_write\n"); }#endif		restart_fd_write(ip_fd);		if (ip_port->ip_dl.dl_eth.de_wr_frag)			return;	}}PRIVATE void restart_netbroad_fd(ip_fd)ip_fd_t *ip_fd;{	assert (!(netbroad_flags & NF_INUSE));	assert (ip_fd->if_flags & IFF_NETBROAD_IP);	ip_fd->if_flags &= ~IFF_NETBROAD_IP;	netbroad_flags |= NF_INUSE;	netbroad_dst= ip_fd->if_wr_dstaddr;	netbroad_netmask= ip_get_netmask(netbroad_dst);	netbroad_pack= get_packet(ip_fd, (int)get_time());	if (!netbroad_pack)	{		netbroad_flags &= ~NF_INUSE;		return;	}	netbroad_port= ip_port_table;	restart_netbroadcast();	error_reply(ip_fd, ip_fd->if_wr_count);}PRIVATE void restart_fd_write(ip_fd)ip_fd_t *ip_fd;{	ip_port_t *ip_port;	ipaddr_t dstaddr;	acc_t *pack;	int result;	assert (ip_fd->if_flags & IFF_DLL_WR_IP);	ip_port= ip_fd->if_wr_port;	dstaddr= ip_fd->if_wr_dstaddr;	result= dll_ready(ip_port, dstaddr);	if (result == NW_SUSPEND)	{		return;	}	if (result == EDSTNOTRCH)	{#if DEBUG { where(); printf("dll_ready returned EDSTNOTRCH, gateway= ");	writeIpAddr(ip_fd->if_wr_dstaddr); printf(", the packet was %s\n",	(ip_fd->if_flags & IFF_ROUTED) ? "routed" : "not routed"); }#endif		if (!(ip_fd->if_flags & IFF_ROUTED))		{			error_reply (ip_fd, result);			return;		}		else		{			ipr_gateway_down (ip_fd->if_wr_dstaddr,				IPR_GW_DOWN_TIMEOUT);			error_reply(ip_fd, NW_OK);			return;		}	}assert (result == NW_OK);	ip_fd->if_flags &= ~IFF_DLL_WR_IP;	ip_port->ip_frame_id++;	pack= get_packet(ip_fd, ip_port->ip_frame_id);	if (!pack)	{		return;	}	dll_write(ip_port, dstaddr, pack);	error_reply(ip_fd, ip_fd->if_wr_count);}PRIVATE void ip_remroute_addr(ip_fd, ttl)ip_fd_t *ip_fd;u8_t ttl;{	ipaddr_t dstaddr, nexthop;	ip_port_t *ip_port;	int result, port;	dstaddr= ip_fd->if_wr_dstaddr;	result= iproute_frag (dstaddr, ttl, &nexthop, &port);#if DEBUG & 256 { where(); printf("ip_remroute_addr("); writeIpAddr(dstaddr); 	printf(", %d)= %d\n", ttl, result); }#endif	if (result>0)	{		ip_port= &ip_port_table[port];		ip_fd->if_flags |= IFF_DLL_WR_IP|IFF_ROUTED;		ip_fd->if_wr_dstaddr= nexthop;		ip_fd->if_wr_port= ip_port;#if DEBUG & 256 { where(); printf("calling restart_fd_write\n"); }#endif		restart_fd_write(ip_fd);		return;	}	if (result<0)	{		error_reply (ip_fd, result);		return;	}#if IP_ROUTER	ip_panic(( "not implemented" ));#else	ip_panic(( "shouldn't be here" ));#endif}PRIVATE acc_t *ip_split_pack (ref_last, first_size)acc_t **ref_last;int first_size;{	int pack_siz;	ip_hdr_t *first_hdr, *second_hdr;	int first_hdr_len, second_hdr_len;	int first_data_len, second_data_len;	int new_first_data_len;	int first_opt_size, second_opt_size;	acc_t *first_pack, *second_pack, *tmp_pack, *tmp_pack1;	u8_t *first_optptr, *second_optptr;	int i, optlen;	first_pack= *ref_last;	*ref_last= 0;	second_pack= 0;	first_pack= bf_packIffLess(first_pack, IP_MIN_HDR_SIZE);	assert (first_pack->acc_length >= IP_MIN_HDR_SIZE);	first_hdr= (ip_hdr_t *)ptr2acc_data(first_pack);#if DEBUG & 256 { where(); writeIpAddr(first_hdr->ih_dst); printf("\n"); }#endif	first_hdr_len= (first_hdr->ih_vers_ihl & IH_IHL_MASK) * 4;#if DEBUG & 256 { where(); printf("fist_hdr_len= %d\n", first_hdr_len); }#endif	pack_siz= bf_bufsize(first_pack);	if (pack_siz > first_size)	{#if DEBUG & 256 { where(); printf("splitting pack\n"); }#endif		if (first_hdr->ih_flags_fragoff & HTONS(IH_DONT_FRAG))		{assert (!(first_hdr->ih_flags_fragoff) & HTONS(IH_FRAGOFF_MASK));			icmp_dont_frag(first_pack);			return 0;		}		first_data_len= ntohs(first_hdr->ih_length) - first_hdr_len;		new_first_data_len= (first_size- first_hdr_len) & ~7;			/* data goes in 8 byte chuncks */		second_data_len= first_data_len-new_first_data_len;		second_pack= bf_cut(first_pack, first_hdr_len+			new_first_data_len, second_data_len);		tmp_pack= first_pack;		first_data_len= new_first_data_len;		first_pack= bf_cut (tmp_pack, 0, first_hdr_len+first_data_len);		bf_afree(tmp_pack);		tmp_pack= bf_memreq(first_hdr_len);		tmp_pack->acc_next= second_pack;		second_pack= tmp_pack;		second_hdr= (ip_hdr_t *)ptr2acc_data(second_pack);		*second_hdr= *first_hdr;		second_hdr->ih_flags_fragoff= htons(			ntohs(first_hdr->ih_flags_fragoff)+(first_data_len/8));		first_opt_size= first_hdr_len-IP_MIN_HDR_SIZE;		second_opt_size= 0;		if (first_opt_size)		{			first_pack= bf_packIffLess (first_pack,				first_hdr_len);			first_hdr= (ip_hdr_t *)ptr2acc_data(first_pack);			assert (first_pack->acc_length>=first_hdr_len);			first_optptr= (u8_t *)ptr2acc_data(first_pack)+				IP_MIN_HDR_SIZE;			second_optptr= (u8_t *)ptr2acc_data(				second_pack)+IP_MIN_HDR_SIZE;			i= 0;			while (i<first_opt_size)			{				switch (*first_optptr & IP_OPT_NUMBER)				{				case 0:				case 1:					optlen= 1;					break;				default:					optlen= first_optptr[1];					break;				}				assert (i + optlen <= first_opt_size);				i += optlen;				if (*first_optptr & IP_OPT_COPIED)				{					second_opt_size += optlen;					while (optlen--)						*second_optptr++=							*first_optptr++;				}				else					first_optptr += optlen;			}			while (second_opt_size & 3)			{				*second_optptr++= 0;				second_opt_size++;			}		}		second_hdr_len= IP_MIN_HDR_SIZE + second_opt_size;#if DEBUG & 256 { where(); printf("second_opt_size= %d, second_hdr_len= %d\n",	second_opt_size, second_hdr_len); }#endif		second_hdr->ih_vers_ihl= second_hdr->ih_vers_ihl & 0xf0			+ (second_hdr_len/4);		second_hdr->ih_length= htons(second_data_len+			second_hdr_len);		second_pack->acc_length= second_hdr_len;		if (first_pack->acc_buffer->buf_linkC>1)		{			tmp_pack= bf_cut(first_pack, 0,				IP_MIN_HDR_SIZE);			tmp_pack1= bf_cut(first_pack, IP_MIN_HDR_SIZE,				bf_bufsize(first_pack)-				IP_MIN_HDR_SIZE);			bf_afree(first_pack);#if DEBUG { where(); printf("calling bf_pack\n"); }#endif			first_pack= bf_pack(tmp_pack);			first_pack->acc_next= tmp_pack1;			first_hdr= (ip_hdr_t *)ptr2acc_data(				first_pack);		}		assert (first_pack->acc_buffer->buf_linkC == 1);		first_hdr->ih_flags_fragoff |= HTONS(IH_MORE_FRAGS);		first_hdr->ih_length= htons(first_data_len+			first_hdr_len);assert (!(second_hdr->ih_flags_fragoff & HTONS(IH_DONT_FRAG)));	}	if (first_pack->acc_buffer->buf_linkC>1)	{		tmp_pack= bf_cut(first_pack, 0,	IP_MIN_HDR_SIZE);		tmp_pack1= bf_cut(first_pack, IP_MIN_HDR_SIZE,			bf_bufsize(first_pack)-IP_MIN_HDR_SIZE);		bf_afree(first_pack);#if DEBUG { where(); printf("calling bf_pack\n"); }#endif		first_pack= bf_pack(tmp_pack);		first_pack->acc_next= tmp_pack1;		first_hdr= (ip_hdr_t *)ptr2acc_data(first_pack);	}	assert (first_hdr->ih_ttl);#if DEBUG & 256 { where(); printf("ip_write.c: ip_split_pack: first_hdr_len= %d\n",	first_hdr_len); }#endif	first_hdr->ih_hdr_chk= 0;	first_hdr->ih_hdr_chk= ~oneC_sum (0, (u16_t *)first_hdr,		first_hdr_len);	*ref_last= second_pack;	return first_pack;}PRIVATE void restart_netbroadcast(){	int was_suspended, result, i;	ip_port_t *ip_port, *hi_port;	ip_fd_t *ip_fd;	assert (netbroad_flags & NF_INUSE);	was_suspended= !!(netbroad_flags & NF_SUSPENDED);	hi_port= &ip_port_table[IP_PORT_NR];	for (; netbroad_port < hi_port; netbroad_port++)	{		if (!(netbroad_port->ip_flags & IPF_IPADDRSET))			continue;		if (!((netbroad_dst ^ netbroad_port->ip_ipaddr) &			netbroad_netmask))			continue;		result= dll_ready (netbroad_port, (ipaddr_t)-1);		if (result == NW_SUSPEND)		{			netbroad_flags |= NF_SUSPENDED;			return;		}assert (result >= 0);		netbroad_pack->acc_linkC++;#if DEBUG { where(); printf("calling dll_write\n"); }#endif		dll_write (netbroad_port, (ipaddr_t)(-1),			netbroad_pack);	}	netbroad_flags &= ~NF_INUSE;	bf_afree(netbroad_pack);	netbroad_pack= 0;	if (!was_suspended)		return;	for (i=0, ip_fd= ip_fd_table; i<IP_FD_NR; i++, ip_fd++)	{		if (!(ip_fd->if_flags & IFF_INUSE) ||			!(ip_fd->if_flags & IFF_NETBROAD_IP))			continue;		restart_netbroad_fd(ip_fd);		if (netbroad_flags & NF_INUSE)			return;	}}PRIVATE void error_reply (ip_fd, error)ip_fd_t *ip_fd;int error;{	ip_fd->if_flags &= ~IFF_WRITE_MASK;	if ((*ip_fd->if_get_userdata)(ip_fd->if_srfd, (size_t)error,		(size_t)0, FALSE))		ip_panic(( "can't error_reply" ));}PRIVATE acc_t *get_packet (ip_fd, id)ip_fd_t *ip_fd;u16_t id;{	acc_t *pack, *tmp_pack, *tmp_pack1;	ip_hdr_t *hdr, *tmp_hdr;	int pack_len, hdr_len, hdr_opt_len, error;	pack_len= ip_fd->if_wr_count;	pack= (*ip_fd->if_get_userdata)(ip_fd->if_srfd, (size_t)0,		pack_len, FALSE);	if (!pack)		return pack;assert(pack_len == bf_bufsize(pack));	if (ip_fd->if_ipopt.nwio_flags & NWIO_RWDATONLY)	{		tmp_pack= bf_memreq (IP_MIN_HDR_SIZE);		tmp_pack->acc_next= pack;		pack= tmp_pack;		pack_len += IP_MIN_HDR_SIZE;	}	if (pack_len<IP_MIN_HDR_SIZE)	{		bf_afree(pack);		error_reply(ip_fd, EPACKSIZE);		return 0;	}	pack= bf_packIffLess(pack, IP_MIN_HDR_SIZE);assert (pack->acc_length >= IP_MIN_HDR_SIZE);	hdr= (ip_hdr_t *)ptr2acc_data(pack);	if (pack->acc_linkC != 1 || pack->acc_buffer->buf_linkC != 1)	{		tmp_pack= bf_memreq(IP_MIN_HDR_SIZE);		tmp_hdr= (ip_hdr_t *)ptr2acc_data(tmp_pack);		*tmp_hdr= *hdr;		tmp_pack->acc_next= bf_cut(pack, IP_MIN_HDR_SIZE,			pack_len-IP_MIN_HDR_SIZE);		bf_afree(pack);		hdr= tmp_hdr;#if DEBUG & 256 { where(); printf("ih_vers_ihl= 0x%x\n", hdr->ih_vers_ihl); }#endif		pack= tmp_pack;assert (pack->acc_length >= IP_MIN_HDR_SIZE);	}assert (pack->acc_linkC == 1 && pack->acc_buffer->buf_linkC == 1);	if (ip_fd->if_ipopt.nwio_flags & NWIO_HDR_O_SPEC)	{#if DEBUG & 256 { where(); printf("ih_vers_ihl= 0x%x\n", hdr->ih_vers_ihl); }#endif		hdr_opt_len= ip_fd->if_ipopt.nwio_hdropt.iho_opt_siz;		if (hdr_opt_len)		{			tmp_pack= bf_cut(pack, 0, IP_MIN_HDR_SIZE);			tmp_pack1= bf_cut (pack, IP_MIN_HDR_SIZE,				pack_len-IP_MIN_HDR_SIZE);			bf_afree(pack);			pack= bf_packIffLess(tmp_pack, IP_MIN_HDR_SIZE);			hdr= (ip_hdr_t *)ptr2acc_data(pack); { where(); printf("ih_vers_ihl= 0x%x\n", hdr->ih_vers_ihl); }			tmp_pack= bf_memreq (hdr_opt_len);			memcpy (ptr2acc_data(tmp_pack), ip_fd->if_ipopt.				nwio_hdropt.iho_data, hdr_opt_len); { where(); printf("ih_vers_ihl= 0x%x\n", hdr->ih_vers_ihl); }			pack->acc_next= tmp_pack;			tmp_pack->acc_next= tmp_pack1;			hdr_len= IP_MIN_HDR_SIZE+hdr_opt_len;		}		else			hdr_len= IP_MIN_HDR_SIZE;		hdr->ih_vers_ihl= hdr_len/4;#if DEBUG & 256 { where(); printf("ih_vers_ihl= 0x%x\n", hdr->ih_vers_ihl); }#endif		hdr->ih_tos= ip_fd->if_ipopt.nwio_tos;		hdr->ih_flags_fragoff= 0;		if (ip_fd->if_ipopt.nwio_df)			hdr->ih_flags_fragoff |= HTONS(IH_DONT_FRAG);		hdr->ih_ttl= ip_fd->if_ipopt.nwio_ttl;#if DEBUG & 256 { where(); printf("ih_vers_ihl= 0x%x\n", hdr->ih_vers_ihl); }#endif	}	else	{assert (ip_fd->if_ipopt.nwio_flags & NWIO_HDR_O_ANY);		hdr_len= (hdr->ih_vers_ihl & IH_IHL_MASK)*4;#if DEBUG & 256 { where(); printf("ih_vers_ihl= 0x%x\n", hdr->ih_vers_ihl); }#endif		error= NW_OK;		if (hdr_len<IP_MIN_HDR_SIZE)			error= EINVAL;		else if (hdr_len>pack_len)			error= EPACKSIZE;		else if (!hdr->ih_ttl)			error= EINVAL;		if (error<0)		{			bf_afree(pack);			error_reply (ip_fd, error);			return 0;		}		pack= bf_packIffLess(pack, hdr_len);		hdr= (ip_hdr_t *)ptr2acc_data(pack);#if DEBUG & 256 { where(); printf("ih_vers_ihl= 0x%x\n", hdr->ih_vers_ihl); }#endif		if (hdr_len != IP_MIN_HDR_SIZE)		{			error= ip_chk_hdropt((u8_t *)(ptr2acc_data(pack) +				IP_MIN_HDR_SIZE),				hdr_len-IP_MIN_HDR_SIZE);			if (error<0)			{				bf_afree(pack);				error_reply (ip_fd, error);				return 0;			}		}#if DEBUG & 256 { where(); printf("ih_vers_ihl= 0x%x\n", hdr->ih_vers_ihl); }#endif	}#if DEBUG & 256 if (hdr->ih_flags_fragoff & HTONS(IH_DONT_FRAG)) { where(); printf("proto= %d\n", hdr->ih_proto); }#endifassert (!(hdr->ih_flags_fragoff & HTONS(IH_DONT_FRAG)));#if DEBUG & 256 { where(); printf("ih_vers_ihl= 0x%x\n", hdr->ih_vers_ihl); }#endif	hdr->ih_vers_ihl= (hdr->ih_vers_ihl & IH_IHL_MASK) |		(IP_VERSION << 4);#if DEBUG & 256 { where(); printf("ih_vers_ihl= 0x%x\n", hdr->ih_vers_ihl); }#endif	hdr->ih_length= htons(pack_len);	hdr->ih_flags_fragoff &= ~HTONS(IH_FRAGOFF_MASK |		IH_FLAGS_UNUSED | IH_MORE_FRAGS);	if (ip_fd->if_ipopt.nwio_flags & NWIO_PROTOSPEC)		hdr->ih_proto= ip_fd->if_ipopt.nwio_proto;	hdr->ih_id= htons(id);	hdr->ih_src= ip_fd->if_port->ip_ipaddr;	if (ip_fd->if_ipopt.nwio_flags & NWIO_REMSPEC)		hdr->ih_dst= ip_fd->if_ipopt.nwio_rem;	else	{assert (ip_fd->if_ipopt.nwio_flags & NWIO_REMANY);		error= chk_dstaddr(hdr->ih_dst);		if (error<0)		{			bf_afree(pack);			error_reply(ip_fd, error);			return 0;		}	}	return pack;}PRIVATE chk_dstaddr (dst)ipaddr_t dst;{	ipaddr_t hostrep_dst, netmask;	hostrep_dst= ntohl(dst);	if (hostrep_dst == (ipaddr_t)-1)		return NW_OK;	if ((hostrep_dst & 0xe0000000l) == 0xe0000000l)		return EBADDEST;	netmask= ip_get_netmask(dst);	if (!(dst & ~netmask))		return EBADDEST;	return NW_OK;}

⌨️ 快捷键说明

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