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

📄 udp.c

📁 minix3的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
			if (udp_fd->uf_flags & UFF_READ_IP)				udp_packet2user(udp_fd);		}		if (share_fd)		{			flags= share_fd->uf_udpopt.nwuo_flags;			if (flags & NWUO_EN_IPOPT)				pack= ipopt_pack;			else				pack= no_ipopt_pack;			pack->acc_linkC++;			udp_rd_enqueue(share_fd, pack, exp_tim);			if (share_fd->uf_flags & UFF_READ_IP)				udp_packet2user(share_fd);		}	}	if (ipopt_pack)		bf_afree(ipopt_pack);	if (no_ipopt_pack)		bf_afree(no_ipopt_pack);	if (!delivered)	{		DBLOCK(0x2, printf("udp: could not deliver packet from ");			writeIpAddr(src_addr);			printf(".%u to ", ntohs(src_port));			writeIpAddr(dst_addr);			printf(".%u\n", ntohs(dst_port)));		pack= bf_append(ip_hdr_acc, udp_acc);		ip_hdr_acc= NULL;		udp_acc= NULL;		icmp_snd_unreachable(udp_port->up_ipdev, pack,			ICMP_PORT_UNRCH);		return;	}	assert (ip_hdr_acc);	bf_afree(ip_hdr_acc);	assert (udp_acc);	bf_afree(udp_acc);}PUBLIC void udp_close(fd)int fd;{	udp_fd_t *udp_fd;	acc_t *tmp_acc, *next_acc;	udp_fd= &udp_fd_table[fd];	assert (udp_fd->uf_flags & UFF_INUSE);	if (udp_fd->uf_flags & UFF_OPTSET)		unhash_fd(udp_fd);	udp_fd->uf_flags= UFF_EMPTY;	tmp_acc= udp_fd->uf_rdbuf_head;	while (tmp_acc)	{		next_acc= tmp_acc->acc_ext_link;		bf_afree(tmp_acc);		tmp_acc= next_acc;	}	udp_fd->uf_rdbuf_head= NULL;}PUBLIC int udp_write(fd, count)int fd;size_t count;{	udp_fd_t *udp_fd;	udp_port_t *udp_port;	udp_fd= &udp_fd_table[fd];	udp_port= udp_fd->uf_port;	if (!(udp_fd->uf_flags & UFF_OPTSET))	{		reply_thr_get (udp_fd, EBADMODE, FALSE);		return NW_OK;	}assert (!(udp_fd->uf_flags & UFF_WRITE_IP));	udp_fd->uf_wr_count= count;	udp_fd->uf_flags |= UFF_WRITE_IP;	restart_write_fd(udp_fd);	if (udp_fd->uf_flags & UFF_WRITE_IP)	{		DBLOCK(1, printf("replying NW_SUSPEND\n"));		return NW_SUSPEND;	}	else	{		return NW_OK;	}}PRIVATE void restart_write_fd(udp_fd)udp_fd_t *udp_fd;{	udp_port_t *udp_port;	acc_t *pack, *ip_hdr_pack, *udp_hdr_pack, *ip_opt_pack, *user_data;	udp_hdr_t *udp_hdr;	udp_io_hdr_t *udp_io_hdr;	ip_hdr_t *ip_hdr;	size_t ip_opt_size, user_data_size;	unsigned long flags;	u16_t chksum;	u8_t u16[2];	int result;	udp_port= udp_fd->uf_port;	if (udp_port->up_flags & UPF_WRITE_IP)	{		udp_port->up_flags |= UPF_MORE2WRITE;		return;	}assert (udp_fd->uf_flags & UFF_WRITE_IP);	udp_fd->uf_flags &= ~UFF_WRITE_IP;assert (!udp_port->up_wr_pack);	pack= (*udp_fd->uf_get_userdata)(udp_fd->uf_srfd, 0,		udp_fd->uf_wr_count, FALSE);	if (!pack)	{		udp_fd->uf_flags &= ~UFF_WRITE_IP;		reply_thr_get (udp_fd, EFAULT, FALSE);		return;	}	flags= udp_fd->uf_udpopt.nwuo_flags;	ip_hdr_pack= bf_memreq(IP_MIN_HDR_SIZE);	ip_hdr= (ip_hdr_t *)ptr2acc_data(ip_hdr_pack);	udp_hdr_pack= bf_memreq(UDP_HDR_SIZE);	udp_hdr= (udp_hdr_t *)ptr2acc_data(udp_hdr_pack);	if (flags & NWUO_RWDATALL)	{		pack= bf_packIffLess(pack, UDP_IO_HDR_SIZE);		udp_io_hdr= (udp_io_hdr_t *)ptr2acc_data(pack);#if CONF_UDP_IO_NW_BYTE_ORDER		ip_opt_size= ntohs(udp_io_hdr->uih_ip_opt_len);#else		ip_opt_size= udp_io_hdr->uih_ip_opt_len;#endif		if (UDP_IO_HDR_SIZE+ip_opt_size>udp_fd->uf_wr_count)		{			bf_afree(ip_hdr_pack);			bf_afree(udp_hdr_pack);			bf_afree(pack);			reply_thr_get (udp_fd, EINVAL, FALSE);			return;		}		if (ip_opt_size & 3)		{			bf_afree(ip_hdr_pack);			bf_afree(udp_hdr_pack);			bf_afree(pack);			reply_thr_get (udp_fd, EFAULT, FALSE);			return;		}		if (ip_opt_size)			ip_opt_pack= bf_cut(pack, UDP_IO_HDR_SIZE, ip_opt_size);		else			ip_opt_pack= 0;		user_data_size= udp_fd->uf_wr_count-UDP_IO_HDR_SIZE-			ip_opt_size;		user_data= bf_cut(pack, UDP_IO_HDR_SIZE+ip_opt_size, 			user_data_size);		bf_afree(pack);	}	else	{		udp_io_hdr= 0;		ip_opt_size= 0;		user_data_size= udp_fd->uf_wr_count;		ip_opt_pack= 0;		user_data= pack;	}	ip_hdr->ih_vers_ihl= (IP_MIN_HDR_SIZE+ip_opt_size) >> 2;	ip_hdr->ih_tos= UDP_TOS;	ip_hdr->ih_flags_fragoff= HTONS(UDP_IP_FLAGS);	ip_hdr->ih_ttl= IP_DEF_TTL;	ip_hdr->ih_proto= IPPROTO_UDP;	if (flags & NWUO_RA_SET)	{		ip_hdr->ih_dst= udp_fd->uf_udpopt.nwuo_remaddr;	}	else	{assert (udp_io_hdr);		ip_hdr->ih_dst= udp_io_hdr->uih_dst_addr;	}	if ((flags & NWUO_LOCPORT_MASK) != NWUO_LP_ANY)		udp_hdr->uh_src_port= udp_fd->uf_udpopt.nwuo_locport;	else	{assert (udp_io_hdr);		udp_hdr->uh_src_port= udp_io_hdr->uih_src_port;	}	if (flags & NWUO_RP_SET)		udp_hdr->uh_dst_port= udp_fd->uf_udpopt.nwuo_remport;	else	{assert (udp_io_hdr);		udp_hdr->uh_dst_port= udp_io_hdr->uih_dst_port;	}	udp_hdr->uh_length= htons(UDP_HDR_SIZE+user_data_size);	udp_hdr->uh_chksum= 0;	udp_hdr_pack->acc_next= user_data;	chksum= pack_oneCsum(udp_hdr_pack);	chksum= oneC_sum(chksum, (u16_t *)&udp_fd->uf_port->up_ipaddr,		sizeof(ipaddr_t));	chksum= oneC_sum(chksum, (u16_t *)&ip_hdr->ih_dst, sizeof(ipaddr_t));	u16[0]= 0;	u16[1]= IPPROTO_UDP;	chksum= oneC_sum(chksum, (u16_t *)u16, sizeof(u16));	chksum= oneC_sum(chksum, (u16_t *)&udp_hdr->uh_length, sizeof(u16_t));	if (~chksum)		chksum= ~chksum;	udp_hdr->uh_chksum= chksum;		if (ip_opt_pack)	{		ip_opt_pack= bf_packIffLess(ip_opt_pack, ip_opt_size);		ip_opt_pack->acc_next= udp_hdr_pack;		udp_hdr_pack= ip_opt_pack;	}	ip_hdr_pack->acc_next= udp_hdr_pack;assert (!udp_port->up_wr_pack);assert (!(udp_port->up_flags & UPF_WRITE_IP));	udp_port->up_wr_pack= ip_hdr_pack;	udp_port->up_flags |= UPF_WRITE_IP;	result= ip_write(udp_port->up_ipfd, bf_bufsize(ip_hdr_pack));	if (result == NW_SUSPEND)	{		udp_port->up_flags |= UPF_WRITE_SP;		udp_fd->uf_flags |= UFF_WRITE_IP;		udp_port->up_write_fd= udp_fd;	}	else if (result<0)		reply_thr_get(udp_fd, result, FALSE);	else		reply_thr_get (udp_fd, udp_fd->uf_wr_count, FALSE);}PRIVATE u16_t pack_oneCsum(pack)acc_t *pack;{	u16_t prev;	int odd_byte;	char *data_ptr;	int length;	char byte_buf[2];	assert (pack);	prev= 0;	odd_byte= FALSE;	for (; pack; pack= pack->acc_next)	{				data_ptr= ptr2acc_data(pack);		length= pack->acc_length;		if (!length)			continue;		if (odd_byte)		{			byte_buf[1]= *data_ptr;			prev= oneC_sum(prev, (u16_t *)byte_buf, 2);			data_ptr++;			length--;			odd_byte= FALSE;		}		if (length & 1)		{			odd_byte= TRUE;			length--;			byte_buf[0]= data_ptr[length];		}		if (!length)			continue;		prev= oneC_sum (prev, (u16_t *)data_ptr, length);	}	if (odd_byte)	{		byte_buf[1]= 0;		prev= oneC_sum (prev, (u16_t *)byte_buf, 1);	}	return prev;}PRIVATE void udp_restart_write_port(udp_port )udp_port_t *udp_port;{	udp_fd_t *udp_fd;	int i;assert (!udp_port->up_wr_pack);assert (!(udp_port->up_flags & (UPF_WRITE_IP|UPF_WRITE_SP)));	while (udp_port->up_flags & UPF_MORE2WRITE)	{		udp_port->up_flags &= ~UPF_MORE2WRITE;		for (i= 0, udp_fd= udp_port->up_next_fd; i<UDP_FD_NR;			i++, udp_fd++)		{			if (udp_fd == &udp_fd_table[UDP_FD_NR])				udp_fd= udp_fd_table;			if (!(udp_fd->uf_flags & UFF_INUSE))				continue;			if (!(udp_fd->uf_flags & UFF_WRITE_IP))				continue;			if (udp_fd->uf_port != udp_port)				continue;			restart_write_fd(udp_fd);			if (udp_port->up_flags & UPF_WRITE_IP)			{				udp_port->up_next_fd= udp_fd+1;				udp_port->up_flags |= UPF_MORE2WRITE;				return;			}		}	}}PUBLIC int udp_cancel(fd, which_operation)int fd;int which_operation;{	udp_fd_t *udp_fd;	DBLOCK(0x10, printf("udp_cancel(%d, %d)\n", fd, which_operation));	udp_fd= &udp_fd_table[fd];	switch (which_operation)	{	case SR_CANCEL_READ:assert (udp_fd->uf_flags & UFF_READ_IP);		udp_fd->uf_flags &= ~UFF_READ_IP;		reply_thr_put(udp_fd, EINTR, FALSE);		break;	case SR_CANCEL_WRITE:assert (udp_fd->uf_flags & UFF_WRITE_IP);		udp_fd->uf_flags &= ~UFF_WRITE_IP;		if (udp_fd->uf_port->up_write_fd == udp_fd)			udp_fd->uf_port->up_write_fd= NULL;		reply_thr_get(udp_fd, EINTR, FALSE);		break;	case SR_CANCEL_IOCTL:assert (udp_fd->uf_flags & UFF_IOCTL_IP);		udp_fd->uf_flags &= ~UFF_IOCTL_IP;		udp_fd->uf_flags &= ~UFF_PEEK_IP;		reply_thr_get(udp_fd, EINTR, TRUE);		break;	default:		ip_panic(( "got unknown cancel request" ));	}	return NW_OK;}PRIVATE void udp_buffree (priority)int priority;{	int i;	udp_fd_t *udp_fd;	acc_t *tmp_acc;	if (priority ==  UDP_PRI_FDBUFS_EXTRA)	{		for (i=0, udp_fd= udp_fd_table; i<UDP_FD_NR; i++, udp_fd++)		{			while (udp_fd->uf_rdbuf_head &&				udp_fd->uf_rdbuf_head->acc_ext_link)			{				tmp_acc= udp_fd->uf_rdbuf_head;				udp_fd->uf_rdbuf_head= tmp_acc->acc_ext_link;				bf_afree(tmp_acc);			}		}	}	if (priority  == UDP_PRI_FDBUFS)	{		for (i=0, udp_fd= udp_fd_table; i<UDP_FD_NR; i++, udp_fd++)		{			while (udp_fd->uf_rdbuf_head)			{				tmp_acc= udp_fd->uf_rdbuf_head;				udp_fd->uf_rdbuf_head= tmp_acc->acc_ext_link;				bf_afree(tmp_acc);			}		}	}}PRIVATE void udp_rd_enqueue(udp_fd, pack, exp_tim)udp_fd_t *udp_fd;acc_t *pack;clock_t exp_tim;{	acc_t *tmp_acc;	int result;	if (pack->acc_linkC != 1)	{		tmp_acc= bf_dupacc(pack);		bf_afree(pack);		pack= tmp_acc;	}	pack->acc_ext_link= NULL;	if (udp_fd->uf_rdbuf_head == NULL)	{		udp_fd->uf_exp_tim= exp_tim;		udp_fd->uf_rdbuf_head= pack;	}	else		udp_fd->uf_rdbuf_tail->acc_ext_link= pack;	udp_fd->uf_rdbuf_tail= pack;	if (udp_fd->uf_flags & UFF_PEEK_IP)	{		pack= bf_cut(udp_fd->uf_rdbuf_head, 0,			sizeof(udp_io_hdr_t));		result= (*udp_fd->uf_put_userdata)(udp_fd->uf_srfd,			(size_t)0, pack, TRUE);		udp_fd->uf_flags &= ~UFF_IOCTL_IP;		udp_fd->uf_flags &= ~UFF_PEEK_IP;		result= (*udp_fd->uf_put_userdata)(udp_fd->uf_srfd,			result, (acc_t *)0, TRUE);		assert (result == 0);	}	if (udp_fd->uf_flags & UFF_SEL_READ)	{		udp_fd->uf_flags &= ~UFF_SEL_READ;		if (udp_fd->uf_select_res)			udp_fd->uf_select_res(udp_fd->uf_srfd, SR_SELECT_READ);		else			printf("udp_rd_enqueue: no select_res\n");	}}PRIVATE void hash_fd(udp_fd)udp_fd_t *udp_fd;{	udp_port_t *udp_port;	int hash;	udp_port= udp_fd->uf_port;	if ((udp_fd->uf_udpopt.nwuo_flags & NWUO_LOCPORT_MASK) ==		NWUO_LP_ANY)	{		udp_fd->uf_port_next= udp_port->up_port_any;		udp_port->up_port_any= udp_fd;	}	else	{		hash= udp_fd->uf_udpopt.nwuo_locport;		hash ^= (hash >> 8);		hash &= (UDP_PORT_HASH_NR-1);		udp_fd->uf_port_next= udp_port->up_port_hash[hash];		udp_port->up_port_hash[hash]= udp_fd;	}}PRIVATE void unhash_fd(udp_fd)udp_fd_t *udp_fd;{	udp_port_t *udp_port;	udp_fd_t *prev, *curr, **udp_fd_p;	int hash;	udp_port= udp_fd->uf_port;	if ((udp_fd->uf_udpopt.nwuo_flags & NWUO_LOCPORT_MASK) ==		NWUO_LP_ANY)	{		udp_fd_p= &udp_port->up_port_any;	}	else	{		hash= udp_fd->uf_udpopt.nwuo_locport;		hash ^= (hash >> 8);		hash &= (UDP_PORT_HASH_NR-1);		udp_fd_p= &udp_port->up_port_hash[hash];	}	for (prev= NULL, curr= *udp_fd_p; curr;		prev= curr, curr= curr->uf_port_next)	{		if (curr == udp_fd)			break;	}	assert(curr);	if (prev)		prev->uf_port_next= curr->uf_port_next;	else		*udp_fd_p= curr->uf_port_next;}#ifdef BUF_CONSISTENCY_CHECKPRIVATE void udp_bufcheck(){	int i;	udp_port_t *udp_port;	udp_fd_t *udp_fd;	acc_t *tmp_acc;	for (i= 0, udp_port= udp_port_table; i<udp_conf_nr; i++, udp_port++)	{		if (udp_port->up_wr_pack)			bf_check_acc(udp_port->up_wr_pack);	}	for (i= 0, udp_fd= udp_fd_table; i<UDP_FD_NR; i++, udp_fd++)	{		for (tmp_acc= udp_fd->uf_rdbuf_head; tmp_acc; 			tmp_acc= tmp_acc->acc_ext_link)		{			bf_check_acc(tmp_acc);		}	}}#endif/* * $PchId: udp.c,v 1.25 2005/06/28 14:14:44 philip Exp $ */

⌨️ 快捷键说明

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