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

📄 udp.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		/* access modes can't be disabled */	}	if (!(new_en_flags & NWUO_ACC_MASK))		new_en_flags |= (old_en_flags & NWUO_ACC_MASK);	/* NWUO_LOCPORT_MASK */	if (new_di_flags & NWUO_LOCPORT_MASK)	{#if DEBUG { where(); printf("returning EBADMODE\n"); }#endif		reply_thr_get(udp_fd, EBADMODE, TRUE);		return NW_OK;		/* the loc ports can't be disabled */	}	if (!(new_en_flags & NWUO_LOCPORT_MASK))	{		new_en_flags |= (old_en_flags & NWUO_LOCPORT_MASK);		newopt.nwuo_locport= oldopt.nwuo_locport;	}	else if ((new_en_flags & NWUO_LOCPORT_MASK) == NWUO_LP_SEL)	{		newopt.nwuo_locport= find_unused_port(udp_fd-udp_fd_table);	}	else if ((new_en_flags & NWUO_LOCPORT_MASK) == NWUO_LP_SET)	{		if (!newopt.nwuo_locport)		{#if DEBUG { where(); printf("returning EBADMODE\n"); }#endif			reply_thr_get(udp_fd, EBADMODE, TRUE);			return NW_OK;		}	}	/* NWUO_LOCADDR_MASK */	if (!((new_en_flags | new_di_flags) & NWUO_LOCADDR_MASK))	{		new_en_flags |= (old_en_flags & NWUO_LOCADDR_MASK);		new_di_flags |= (old_di_flags & NWUO_LOCADDR_MASK);	}	/* NWUO_BROAD_MASK */	if (!((new_en_flags | new_di_flags) & NWUO_BROAD_MASK))	{		new_en_flags |= (old_en_flags & NWUO_BROAD_MASK);		new_di_flags |= (old_di_flags & NWUO_BROAD_MASK);	}	/* NWUO_REMPORT_MASK */	if (!((new_en_flags | new_di_flags) & NWUO_REMPORT_MASK))	{		new_en_flags |= (old_en_flags & NWUO_REMPORT_MASK);		new_di_flags |= (old_di_flags & NWUO_REMPORT_MASK);		newopt.nwuo_remport= oldopt.nwuo_remport;	}#if DEBUG & 256 { where(); printf("newopt.nwuo_remport= %d\n", ntohs(newopt.nwuo_remport)); }#endif		/* NWUO_REMADDR_MASK */	if (!((new_en_flags | new_di_flags) & NWUO_REMADDR_MASK))	{		new_en_flags |= (old_en_flags & NWUO_REMADDR_MASK);		new_di_flags |= (old_di_flags & NWUO_REMADDR_MASK);		newopt.nwuo_remaddr= oldopt.nwuo_remaddr;	}	/* NWUO_RW_MASK */	if (!((new_en_flags | new_di_flags) & NWUO_RW_MASK))	{		new_en_flags |= (old_en_flags & NWUO_RW_MASK);		new_di_flags |= (old_di_flags & NWUO_RW_MASK);	}	/* NWUO_IPOPT_MASK */	if (!((new_en_flags | new_di_flags) & NWUO_IPOPT_MASK))	{		new_en_flags |= (old_en_flags & NWUO_IPOPT_MASK);		new_di_flags |= (old_di_flags & NWUO_IPOPT_MASK);	}	new_flags= ((unsigned long)new_di_flags << 16) | new_en_flags;	if ((new_flags & NWUO_RWDATONLY) && 		((new_flags & NWUO_LOCPORT_MASK) == NWUO_LP_ANY || 		(new_flags & (NWUO_RP_ANY|NWUO_RA_ANY|NWUO_EN_IPOPT))))	{#if DEBUG { where(); printf("returning EBADMODE\n"); }#endif		reply_thr_get(udp_fd, EBADMODE, TRUE);		return NW_OK;	}	/* Let's check the access modes */	if ((new_flags & NWUO_LOCPORT_MASK) == NWUO_LP_SEL ||		(new_flags & NWUO_LOCPORT_MASK) == NWUO_LP_SET)	{		for (i= 0, fd_ptr= udp_fd_table; i<UDP_FD_NR; i++, fd_ptr++)		{			if (fd_ptr == udp_fd)				continue;			if (!(fd_ptr->uf_flags & UFF_INUSE))				continue;			flags= fd_ptr->uf_udpopt.nwuo_flags;			if ((flags & NWUO_LOCPORT_MASK) != NWUO_LP_SEL &&				(flags & NWUO_LOCPORT_MASK) != NWUO_LP_SET)				continue;			if (fd_ptr->uf_udpopt.nwuo_locport !=				newopt.nwuo_locport)				continue;			if ((flags & NWUO_ACC_MASK) != 				(new_flags & NWUO_ACC_MASK))			{#if DEBUG { where(); printf("address inuse: new fd= %d, old_fd= %d, port= %u\n",	udp_fd-udp_fd_table, fd_ptr-udp_fd_table, newopt.nwuo_locport); }#endif				reply_thr_get(udp_fd, EADDRINUSE, TRUE);				return NW_OK;			}		}	}	newopt.nwuo_flags= new_flags;	udp_fd->uf_udpopt= newopt;	all_flags= new_en_flags | new_di_flags;#if DEBUG & 256 { where();	printf("NWUO_ACC_MASK: %s set\n", all_flags & NWUO_ACC_MASK ? "" : "not"); 	printf("NWUO_LOCADDR_MASK: %s set\n", all_flags & NWUO_LOCADDR_MASK ? "" : "not"); 	printf("NWUO_BROAD_MASK: %s set\n", all_flags & NWUO_BROAD_MASK ? "" : "not"); 	printf("NWUO_REMPORT_MASK: %s set\n", all_flags & NWUO_REMPORT_MASK ? "" : "not"); 	printf("NWUO_REMADDR_MASK: %s set\n", all_flags & NWUO_REMADDR_MASK ? "" : "not"); 	printf("NWUO_RW_MASK: %s set\n", all_flags & NWUO_RW_MASK ? "" : "not"); 	printf("NWUO_IPOPT_MASK: %s set\n", all_flags & NWUO_IPOPT_MASK ? "" : "not");  }#endif	if ((all_flags & NWUO_ACC_MASK) && (all_flags & NWUO_LOCPORT_MASK) &&		(all_flags & NWUO_LOCADDR_MASK) &&		(all_flags & NWUO_BROAD_MASK) &&		(all_flags & NWUO_REMPORT_MASK) &&		(all_flags & NWUO_REMADDR_MASK) &&		(all_flags & NWUO_RW_MASK) &&		(all_flags & NWUO_IPOPT_MASK))		udp_fd->uf_flags |= UFF_OPTSET;	else	{		udp_fd->uf_flags &= ~UFF_OPTSET;	}	reply_thr_get(udp_fd, NW_OK, TRUE);	return NW_OK;}PRIVATE udpport_t find_unused_port(fd)int fd;{	udpport_t port, nw_port;	for (port= 0x8000; port < 0xffff-UDP_FD_NR; port+= UDP_FD_NR)	{		nw_port= htons(port);		if (is_unused_port(nw_port))			return nw_port;	}	for (port= 0x8000; port < 0xffff; port++)	{		nw_port= htons(port);		if (is_unused_port(nw_port))			return nw_port;	}	ip_panic(( "unable to find unused port (shouldn't occur)" ));	return 0;}/*reply_thr_put*/PRIVATE int reply_thr_put(udp_fd, reply, for_ioctl)udp_fd_t *udp_fd;int reply;int for_ioctl;{#if DEBUG { where(); printf("reply_thr_put(&udp_fd_table[%d], %d, %d) called\n",	udp_fd-udp_fd_table, reply, for_ioctl); }#endif#if DEBUG & 2 { where(); printf("calling 0x%x\n", udp_fd->uf_put_userdata); }#endifassert (udp_fd);	return (*udp_fd->uf_put_userdata)(udp_fd->uf_srfd, reply,		(acc_t *)0, for_ioctl);}/*reply_thr_get*/PRIVATE void reply_thr_get(udp_fd, reply, for_ioctl)udp_fd_t *udp_fd;int reply;int for_ioctl;{	acc_t *result;#if DEBUG & 256 { where(); printf("reply_thr_get(&udp_fd_table[%d], %d, %d) called\n",	udp_fd-udp_fd_table, reply, for_ioctl); }#endif	result= (*udp_fd->uf_get_userdata)(udp_fd->uf_srfd, reply,		(size_t)0, for_ioctl);	assert (!result);}PRIVATE int is_unused_port(port)udpport_t port;{	int i;	udp_fd_t *udp_fd;	for (i= 0, udp_fd= udp_fd_table; i<UDP_FD_NR; i++,		udp_fd++)	{		if (!(udp_fd->uf_flags & UFF_OPTSET))			continue;		if (udp_fd->uf_udpopt.nwuo_locport == port)			return FALSE;	}	return TRUE;}PRIVATE void read_ip_packets(udp_port)udp_port_t *udp_port;{	int result;	do	{		udp_port->up_flags |= UPF_READ_IP;#if DEBUG & 256 { where(); printf("doing ip_read\n"); }#endif		result= ip_read(udp_port->up_ipfd, UDP_MAX_DATAGRAM);		if (result == NW_SUSPEND)		{			udp_port->up_flags |= UPF_READ_SP;			return;		}assert(result == NW_OK);		udp_port->up_flags &= ~UPF_READ_IP;	} while(!(udp_port->up_flags & UPF_READ_IP));}PUBLIC int udp_read (fd, count)int fd;size_t count;{	udp_fd_t *udp_fd;	udp_fd= &udp_fd_table[fd];	if (!(udp_fd->uf_flags & UFF_OPTSET))		return reply_thr_put(udp_fd, EBADMODE, FALSE);	udp_fd->uf_rd_count= count;	if (udp_fd->uf_rd_buf)	{		if (get_time() <= udp_fd->uf_exp_tim)			return udp_packet2user (udp_fd);		bf_afree(udp_fd->uf_rd_buf);		udp_fd->uf_rd_buf= 0;	}	udp_fd->uf_flags |= UFF_READ_IP;#if DEBUG & 256 { where(); printf("udp_fd_table[%d].uf_flags= 0x%x\n",	udp_fd-udp_fd_table, udp_fd->uf_flags); }#endif	return NW_SUSPEND;}PRIVATE int udp_packet2user (udp_fd)udp_fd_t *udp_fd;{	acc_t *pack, *tmp_pack;	udp_io_hdr_t *hdr;	int result, hdr_len;	size_t size, transf_size;	pack= udp_fd->uf_rd_buf;	udp_fd->uf_rd_buf= 0;	size= bf_bufsize (pack);	if (udp_fd->uf_udpopt.nwuo_flags & NWUO_RWDATONLY)	{		pack= bf_packIffLess (pack, UDP_IO_HDR_SIZE);assert (pack->acc_length >= UDP_IO_HDR_SIZE);		hdr= (udp_io_hdr_t *)ptr2acc_data(pack);		hdr_len= UDP_IO_HDR_SIZE+hdr->uih_ip_opt_len;assert (size>= hdr_len);		size -= hdr_len;		tmp_pack= bf_cut(pack, hdr_len, size);		bf_afree(pack);		pack= tmp_pack;	}	if (size>udp_fd->uf_rd_count)	{		tmp_pack= bf_cut (pack, 0, udp_fd->uf_rd_count);		bf_afree(pack);		pack= tmp_pack;		transf_size= udp_fd->uf_rd_count;	}	else		transf_size= size;	result= (*udp_fd->uf_put_userdata)(udp_fd->uf_srfd,		(size_t)0, pack, FALSE);	if (result >= 0)		if (size > transf_size)			result= EPACKSIZE;		else			result= transf_size;	udp_fd->uf_flags &= ~UFF_READ_IP;	result= (*udp_fd->uf_put_userdata)(udp_fd->uf_srfd, result,			(acc_t *)0, FALSE);assert (result == 0);	return result;}PRIVATE void process_inc_fragm(udp_port, pack)udp_port_t *udp_port;acc_t *pack;{	udp_fd_t *udp_fd, *share_fd;	acc_t *ip_acc, *udp_acc, *ipopt_pack, *no_ipopt_pack, *tmp_acc;	ip_hdr_t *ip_hdr;	udp_hdr_t *udp_hdr;	udp_io_hdr_t *udp_io_hdr;	size_t pack_size, ip_hdr_size;	size_t udp_size;	ipaddr_t src_addr, dst_addr;	u8_t u16[2];	u16_t chksum;	unsigned long dst_type, flags;	time_t  exp_tim;	udpport_t src_port, dst_port;	int i;#if DEBUG & 256 { where(); printf("in process_inc_fragm\n"); }#endif	pack_size= bf_bufsize(pack);	pack= bf_packIffLess(pack, IP_MIN_HDR_SIZE);assert (pack->acc_length >= IP_MIN_HDR_SIZE);	ip_hdr= (ip_hdr_t *)ptr2acc_data(pack);	ip_hdr_size= (ip_hdr->ih_vers_ihl & IH_IHL_MASK) << 2;	ip_acc= bf_cut(pack, (size_t)0, ip_hdr_size);	src_addr= ip_hdr->ih_src;	dst_addr= ip_hdr->ih_dst;	udp_acc= bf_cut(pack, ip_hdr_size, pack_size-ip_hdr_size);	bf_afree(pack);	pack_size -= ip_hdr_size;	if (pack_size < UDP_HDR_SIZE)	{#if DEBUG { where(); printf("packet too small\n"); }#endif		bf_afree(ip_acc);		bf_afree(udp_acc);		return;	}	udp_acc= bf_packIffLess(udp_acc, UDP_HDR_SIZE);	udp_hdr= (udp_hdr_t *)ptr2acc_data(udp_acc);	udp_size= ntohs(udp_hdr->uh_length);	if (udp_size > pack_size)	{#if DEBUG { where(); printf("packet too large\n"); }#endif		bf_afree(ip_acc);		bf_afree(udp_acc);		return;	}	if (udp_hdr->uh_chksum)	{		u16[0]= 0;		u16[1]= ip_hdr->ih_proto;		chksum= pack_oneCsum(udp_acc);		chksum= oneC_sum(chksum, (u16_t *)&src_addr, sizeof(ipaddr_t));		chksum= oneC_sum(chksum, (u16_t *)&dst_addr, sizeof(ipaddr_t));		chksum= oneC_sum(chksum, (u16_t *)u16, sizeof(u16));		chksum= oneC_sum(chksum, (u16_t *)&udp_hdr->uh_length, 			sizeof(udp_hdr->uh_length));		if (~chksum & 0xffff)		{#if DEBUG  { where(); printf("udp chksum error\n"); }#endif			bf_afree(ip_acc);			bf_afree(udp_acc);			return;		}	}	exp_tim= get_time() + UDP_READ_EXP_TIME;	src_port= udp_hdr->uh_src_port;	dst_port= udp_hdr->uh_dst_port;	if (dst_addr == udp_port->up_ipaddr)		dst_type= NWUO_EN_LOC;	else		dst_type= NWUO_EN_BROAD;	share_fd= 0;	ipopt_pack= 0;	no_ipopt_pack= 0;	for (i=0, udp_fd=udp_fd_table; i<UDP_FD_NR; i++, udp_fd++)	{		if (!(udp_fd->uf_flags & UFF_INUSE))		{#if DEBUG & 256 { where(); printf("%d: not inuse\n", i); }#endif			continue;		}		if (!(udp_fd->uf_flags & UFF_OPTSET))		{#if DEBUG { where(); printf("%d: options not set\n", i); }#endif			continue;		}		flags= udp_fd->uf_udpopt.nwuo_flags;		if (!(flags & dst_type))		{#if DEBUG & 256 { where(); printf("%d: wrong type\n", i); }#endif			continue;		}		if ((flags & (NWUO_LP_SEL|NWUO_LP_SET)) &&			udp_fd->uf_udpopt.nwuo_locport != dst_port)		{#if DEBUG & 256 { where(); printf("%d: wrong loc port, got %d, expected %d\n", i,	dst_port, udp_fd->uf_udpopt.nwuo_locport); }#endif			continue;		}		if ((flags & NWUO_RP_SET) && 			udp_fd->uf_udpopt.nwuo_remport != src_port)		{#if DEBUG { where(); printf("%d: wrong rem port, I got %d, expected %d\n", i,	ntohs(src_port), ntohs(udp_fd->uf_udpopt.nwuo_remport)); }#endif			continue;		}		if ((flags & NWUO_RA_SET) && 			udp_fd->uf_udpopt.nwuo_remaddr != src_addr)		{#if DEBUG { where(); printf("%d: wrong rem addr\n", i); }#endif			continue;		}		if (!no_ipopt_pack)		{			no_ipopt_pack= bf_memreq(UDP_IO_HDR_SIZE);			udp_io_hdr= (udp_io_hdr_t *)ptr2acc_data(no_ipopt_pack);			udp_io_hdr->uih_src_addr= src_addr;			udp_io_hdr->uih_dst_addr= dst_addr;			udp_io_hdr->uih_src_port= src_port;			udp_io_hdr->uih_dst_port= dst_port;			udp_io_hdr->uih_ip_opt_len= 0;			udp_io_hdr->uih_data_len= udp_size-UDP_HDR_SIZE;			no_ipopt_pack->acc_next= bf_cut(udp_acc, 				UDP_HDR_SIZE, udp_io_hdr->uih_data_len);			if (ip_hdr_size == IP_MIN_HDR_SIZE)			{				ipopt_pack= no_ipopt_pack;				ipopt_pack->acc_linkC++;			}			else				ipopt_pack= 0;		}		if (flags & NWUO_EN_IPOPT)		{			if (!ipopt_pack)			{				ipopt_pack= bf_memreq(UDP_IO_HDR_SIZE);

⌨️ 快捷键说明

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