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

📄 udp_usrreq.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	sowwakeup(inp->inp_socket);}voidudp_ctlinput(cmd, sa, ip)	int cmd;	struct sockaddr *sa;	register struct ip *ip;{	register struct udphdr *uh;	extern struct in_addr zeroin_addr;	extern u_char inetctlerrmap[];#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_INFO event */    WV_NET_MARKER_1 (NET_AUX_EVENT, WV_NET_INFO, 49, 13,                     WV_NETEVENT_UDPCTLIN_START, cmd)#endif  /* INCLUDE_WVNET */#endif	if (!PRC_IS_REDIRECT(cmd) &&	    ((unsigned)cmd >= PRC_NCMDS || inetctlerrmap[cmd] == 0))		return;	if (ip) {		uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));		in_pcbnotify(&udb, sa, uh->uh_dport, ip->ip_src, uh->uh_sport,			cmd, udp_notify);	} else		in_pcbnotify(&udb, sa, 0, zeroin_addr, 0, cmd, udp_notify);}intudp_output(inp, m, addr, control)	register struct inpcb *inp;	register struct mbuf *m;	struct mbuf *addr, *control;{        struct rtentry *rt;	register struct udpiphdr *ui;	register int len = m->m_pkthdr.len;	struct in_addr laddr;	int s = 0, error = 0;	if (control)		m_freem(control);		/* XXX */	if (addr) {		laddr = inp->inp_laddr;		if (inp->inp_faddr.s_addr != INADDR_ANY) {			error = EISCONN;			goto release;		}		/*		 * Must block input while temporarily connected.		 */		s = splnet();		error = in_pcbconnect(inp, addr);		if (error) {			splx(s);			goto release;		}	} else {		if (inp->inp_faddr.s_addr == INADDR_ANY) {			error = ENOTCONN;			goto release;		}	}	/*	 * Calculate data length and get a mbuf	 * for UDP and IP headers.	 */	M_PREPEND(m, sizeof(struct udpiphdr), M_DONTWAIT);	if (m == 0) {		error = ENOBUFS;		if (addr)		    {                    in_pcbdisconnect(inp);		    splx (s);		    }		goto release;	}	/*	 * Fill in mbuf with extended UDP header	 * and addresses and length put into network format.	 */	ui = mtod(m, struct udpiphdr *);	ui->ui_next = ui->ui_prev = 0;	ui->ui_x1 = 0;	ui->ui_pr = IPPROTO_UDP;	ui->ui_len = htons((u_short)len + sizeof (struct udphdr));	ui->ui_src = inp->inp_laddr;	ui->ui_dst = inp->inp_faddr;	ui->ui_sport = inp->inp_lport;	ui->ui_dport = inp->inp_fport;	ui->ui_ulen = ui->ui_len;	/*	 * Stuff checksum and output datagram.	 */	ui->ui_sum = 0;	if (udpcksum) {	    if ((ui->ui_sum = in_cksum(m, sizeof (struct udpiphdr) + len)) == 0)		ui->ui_sum = 0xffff;	}	((struct ip *)ui)->ip_len = sizeof (struct udpiphdr) + len;	((struct ip *)ui)->ip_ttl = inp->inp_ip.ip_ttl;	/* XXX */	((struct ip *)ui)->ip_tos = inp->inp_ip.ip_tos;	/* XXX */	udpstat.udps_opackets++;        /*         * Prevent fragmentation to continue (or trigger) path MTU discovery         * if the required routing entry and path MTU estimate are available         * and path MTU discovery is enabled for this socket. Since UDP         * produces a single datagram for each send operation, the application         * which enables path MTU discovery must send datagrams equal to         * the current MTU estimate or the process will not complete.         */        rt = inp->inp_route.ro_rt;        if (rt && (rt->rt_flags & RTF_UP) && !(rt->rt_rmx.rmx_locks & RTV_MTU))            {            if (inp->inp_socket->so_options & SO_USEPATHMTU)                ( (struct ip *)ui)->ip_off |= IP_DF;            }	error = ip_output(m, inp->inp_options, &inp->inp_route,	    inp->inp_socket->so_options & (SO_DONTROUTE | SO_BROADCAST),	    inp->inp_moptions);#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_NOTICE event */    WV_NET_PORTOUT_EVENT_4 (NET_CORE_EVENT, WV_NET_NOTICE, 22, 11,                            inp->inp_lport, inp->inp_fport,                            WV_NETEVENT_UDPOUT_FINISH, WV_NET_SEND,                            inp->inp_socket->so_fd, error,                            inp->inp_lport, inp->inp_fport)#endif  /* INCLUDE_WVNET */#endif	if (addr) {		in_pcbdisconnect(inp);		inp->inp_laddr = laddr;		splx(s);	}	return (error);release:#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_ERROR event */    WV_NET_EVENT_2 (NET_CORE_EVENT, WV_NET_ERROR, 41, 2,                    WV_NETEVENT_UDPOUT_FAIL, WV_NET_SEND,                    inp->inp_socket->so_fd, error)#endif  /* INCLUDE_WVNET */#endif	m_freem(m);	return (error);}/*ARGSUSED*/intudp_usrreq(so, req, m, addr, control)	struct socket *so;	int req;	struct mbuf *m, *addr, *control;{	struct inpcb *inp = sotoinpcb(so);	int error = 0;	int s;#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_INFO event */    WV_NET_MARKER_2 (NET_AUX_EVENT, WV_NET_INFO, 50, 14,                     WV_NETEVENT_UDPREQ_START, so->so_fd, req)#endif  /* INCLUDE_WVNET */#endif	if (req == PRU_CONTROL)		return (in_control(so, (u_long)m, (caddr_t)addr,			(struct ifnet *)control));	if (inp == NULL && req != PRU_ATTACH) {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_ERROR event */        WV_NET_MARKER_2 (NET_AUX_EVENT, WV_NET_ERROR, 42, 3,                        WV_NETEVENT_UDPREQ_NOPCB, so->so_fd, req)#endif  /* INCLUDE_WVNET */#endif		error = EINVAL;		goto release;	}	/*	 * Note: need to block udp_input while changing	 * the udp pcb queue and/or pcb addresses.	 */	switch (req) {	case PRU_ATTACH:		if (inp != NULL) {			error = EINVAL;			break;		}		s = splnet();		error = in_pcballoc(so, &udbinfo);		splx(s);		if (error)			break;		error = soreserve(so, udp_sendspace, udp_recvspace);		if (error)			break;		((struct inpcb *) so->so_pcb)->inp_ip.ip_ttl = ip_defttl;		break;	case PRU_DETACH:		udp_detach(inp);		break;	case PRU_BIND:		s = splnet();		error = in_pcbbind(inp, addr);		splx(s);		break;	case PRU_LISTEN:		error = EOPNOTSUPP;		break;	case PRU_CONNECT:		if (inp->inp_faddr.s_addr != INADDR_ANY) {			error = EISCONN;			break;		}		s = splnet();		error = in_pcbconnect(inp, addr);		splx(s);		if (error == 0)			soisconnected(so);		break;	case PRU_CONNECT2:		error = EOPNOTSUPP;		break;	case PRU_ACCEPT:		error = EOPNOTSUPP;		break;	case PRU_DISCONNECT:		if (inp->inp_faddr.s_addr == INADDR_ANY) {			error = ENOTCONN;			break;		}		s = splnet();		in_pcbdisconnect(inp);		inp->inp_laddr.s_addr = INADDR_ANY;		splx(s);		so->so_state &= ~SS_ISCONNECTED;		/* XXX */		break;	case PRU_SHUTDOWN:		socantsendmore(so);		break;	case PRU_SEND:		return (udp_output(inp, m, addr, control));	case PRU_ABORT:		soisdisconnected(so);		udp_detach(inp);		break;	case PRU_SOCKADDR:		in_setsockaddr(inp, addr);		break;	case PRU_PEERADDR:		in_setpeeraddr(inp, addr);		break;	case PRU_SENSE:		/*		 * stat: don't bother with a blocksize.		 */		return (0);	case PRU_SENDOOB:	case PRU_FASTTIMO:	case PRU_SLOWTIMO:	case PRU_PROTORCV:	case PRU_PROTOSEND:		error =  EOPNOTSUPP;		break;	case PRU_RCVD:	case PRU_RCVOOB:		return (EOPNOTSUPP);	/* do not free mbuf's */	default:#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_EMERGENCY event */            WV_NET_MARKER_2 (NET_AUX_EVENT, WV_NET_EMERGENCY, 32, 1,                             WV_NETEVENT_UDPREQ_PANIC, so->so_fd, req)#endif  /* INCLUDE_WVNET */#endif		panic("udp_usrreq");	}release:	if (control) {		printf("udp control data unexpectedly retained\n");		m_freem(control);	}	if (m)		m_freem(m);	return (error);}static voidudp_detach(inp)	struct inpcb *inp;{	int s = splnet();	if (inp == udp_last_inpcb)            udp_last_inpcb = NULL;	in_pcbdetach(inp);	splx(s);}#ifdef SYSCTL_SUPPORT/* * Sysctl for udp variables. */udp_sysctl(name, namelen, oldp, oldlenp, newp, newlen)	int *name;	u_int namelen;	void *oldp;	size_t *oldlenp;	void *newp;	size_t newlen;{/* * XXX - This event cannot currently occur: the udp_sysctl() routine *       is only called by the Unix sysctl command which is not supported *       by VxWorks#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /@ WV_NET_INFO event @/    WV_NET_MARKER_1 (NET_AUX_EVENT, WV_NET_INFO, 51, 15,                     WV_NETEVENT_UDPCTRL_START, name[0])#endif  /@ INCLUDE_WVNET @/#endif * XXX - end of unused event */	/* All sysctl names at this level are terminal. */	if (namelen != 1)		return (ENOTDIR);	switch (name[0]) {	case UDPCTL_CHECKSUM:		return (sysctl_int(oldp, oldlenp, newp, newlen, &udpcksum));	default:		return (ENOPROTOOPT);	}	/* NOTREACHED */}#endif /* SYSCTL_SUPPORT */

⌨️ 快捷键说明

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