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

📄 udp_usrreq.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
                    {                    /*                     * No matching pcb found; discard datagram.                     * (No need to send an ICMP Port Unreachable                     * for a broadcast or multicast datgram.)                     */#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_WARNING event */            WV_NET_PORTIN_EVENT_4 (NET_CORE_EVENT, WV_NET_WARNING, 18, 8,                                   uh->uh_sport, uh->uh_dport,                                   WV_NETEVENT_UDPIN_SEARCHFAIL, WV_NET_RECV,                                   ip->ip_src.s_addr, uh->uh_sport,                                   ip->ip_dst.s_addr, uh->uh_dport)#endif  /* INCLUDE_WVNET */#endif                    udpstat.udps_noportbcast++;                    goto bad;                    }#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_INFO event */            WV_NET_PORTIN_EVENT_4 (NET_CORE_EVENT, WV_NET_INFO, 56, 18,                                   uh->uh_sport, uh->uh_dport,                                   WV_NETEVENT_UDPIN_PCBGOOD, WV_NET_RECV,                                   ip->ip_src.s_addr, uh->uh_sport,                                   last->so_fd, uh->uh_dport)#endif  /* INCLUDE_WVNET */#endif		if (sbappendaddr(&last->so_rcv, (struct sockaddr *)&udp_in,                                 m, (struct mbuf *)0) == 0)                    {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_WARNING event */            WV_NET_PORTIN_EVENT_1 (NET_CORE_EVENT, WV_NET_WARNING, 17, 7,                                   uh->uh_sport, uh->uh_dport,                                   WV_NETEVENT_UDPIN_FULLSOCK, WV_NET_RECV,                                   last->so_fd)#endif  /* INCLUDE_WVNET */#endif                    udpstat.udps_fullsock++;                    goto bad;                    }		sorwakeup(last);		return;                }            }        	if (in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) {		struct socket *last;		/*		 * Deliver a multicast or broadcast datagram to *all* sockets		 * for which the local and remote addresses and ports match		 * those of the incoming datagram.  This allows more than		 * one process to receive multi/broadcasts on the same port.		 * (This really ought to be done for unicast datagrams as		 * well, but that would cause problems with existing		 * applications that open both address-specific sockets and		 * a wildcard socket listening to the same port -- they would		 * end up receiving duplicates of every unicast datagram.		 * Those applications open the multiple sockets to overcome an		 * inadequacy of the UDP socket interface, but for backwards		 * compatibility we avoid the problem here rather than		 * fixing the interface.  Maybe 4.5BSD will remedy this?)		 */		/*		 * Construct sockaddr format source address.		 */		udp_in.sin_port = uh->uh_sport;		udp_in.sin_addr = ip->ip_src;		m->m_len -= sizeof (struct udpiphdr);		m->m_data += sizeof (struct udpiphdr);		/*		 * Locate pcb(s) for datagram.		 * (Algorithm copied from raw_intr().)		 */		last = NULL;		for (inp = udb.lh_first; inp != NULL;                     inp = inp->inp_list.le_next) {			if (inp->inp_lport != uh->uh_dport)				continue;			if (inp->inp_laddr.s_addr != INADDR_ANY) {				if (inp->inp_laddr.s_addr !=				    ip->ip_dst.s_addr)					continue;			}			if (inp->inp_faddr.s_addr != INADDR_ANY) {				if (inp->inp_faddr.s_addr !=				    ip->ip_src.s_addr ||				    inp->inp_fport != uh->uh_sport)					continue;			}			if (last != NULL) {				struct mbuf *n;				if ((n = m_copy(m, 0, M_COPYALL)) != NULL) {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_INFO event */            WV_NET_PORTIN_EVENT_4 (NET_CORE_EVENT, WV_NET_INFO, 56, 18,                                   uh->uh_sport, uh->uh_dport,                                   WV_NETEVENT_UDPIN_PCBGOOD, WV_NET_RECV,                                   ip->ip_src.s_addr, uh->uh_sport,                                   last->so_fd, uh->uh_dport)#endif  /* INCLUDE_WVNET */#endif					if (sbappendaddr(&last->so_rcv,						(struct sockaddr *)&udp_in,						n, (struct mbuf *)0) == 0) {						m_freem(n);#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_WARNING event */            WV_NET_PORTIN_EVENT_1 (NET_CORE_EVENT, WV_NET_WARNING, 17, 7,                                   uh->uh_sport, uh->uh_dport,                                   WV_NETEVENT_UDPIN_FULLSOCK, WV_NET_RECV,                                   last->so_fd)#endif  /* INCLUDE_WVNET */#endif						udpstat.udps_fullsock++;					} else						sorwakeup(last);				}			}			last = inp->inp_socket;			/*			 * Don't look for additional matches if this one does			 * not have either the SO_REUSEPORT or SO_REUSEADDR			 * socket options set.  This heuristic avoids searching			 * through all pcbs in the common case of a non-shared			 * port.  It * assumes that an application will never			 * clear these options after setting them.			 */			if ((last->so_options & (SO_REUSEPORT|SO_REUSEADDR))                            == 0)				break;		}		if (last == NULL) {			/*			 * No matching pcb found; discard datagram.			 * (No need to send an ICMP Port Unreachable			 * for a broadcast or multicast datgram.)			 */#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_WARNING event */            WV_NET_PORTIN_EVENT_4 (NET_CORE_EVENT, WV_NET_WARNING, 18, 8,                                   uh->uh_sport, uh->uh_dport,                                   WV_NETEVENT_UDPIN_SEARCHFAIL, WV_NET_RECV,                                   ip->ip_src.s_addr, uh->uh_sport,                                   ip->ip_dst.s_addr, uh->uh_dport)#endif  /* INCLUDE_WVNET */#endif			udpstat.udps_noportbcast++;			goto bad;		}#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_INFO event */            WV_NET_PORTIN_EVENT_4 (NET_CORE_EVENT, WV_NET_INFO, 56, 18,                                   uh->uh_sport, uh->uh_dport,                                   WV_NETEVENT_UDPIN_PCBGOOD, WV_NET_RECV,                                   ip->ip_src.s_addr, uh->uh_sport,                                   last->so_fd, uh->uh_dport)#endif  /* INCLUDE_WVNET */#endif		if (sbappendaddr(&last->so_rcv, (struct sockaddr *)&udp_in,		     m, (struct mbuf *)0) == 0) {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_WARNING event */            WV_NET_PORTIN_EVENT_1 (NET_CORE_EVENT, WV_NET_WARNING, 17, 7,                                   uh->uh_sport, uh->uh_dport,                                   WV_NETEVENT_UDPIN_FULLSOCK, WV_NET_RECV,                                   last->so_fd)#endif  /* INCLUDE_WVNET */#endif			udpstat.udps_fullsock++;			goto bad;		}		sorwakeup(last);		return;	}	/*	 * Locate pcb for datagram. use the cached pcb if it matches.	 */	inp = udp_last_inpcb;        if ((inp != NULL) &&            (inp->inp_lport == uh->uh_dport) &&	    (inp->inp_fport == uh->uh_sport) &&	    (inp->inp_faddr.s_addr == ip->ip_src.s_addr) &&            (inp->inp_laddr.s_addr == ip->ip_dst.s_addr))            {            goto pcbMatchFound;            }        else            {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_VERBOSE event */            WV_NET_PORTIN_EVENT_4 (NET_CORE_EVENT, WV_NET_VERBOSE, 44, 17,                                   uh->uh_sport, uh->uh_dport,                                   WV_NETEVENT_UDPIN_CACHEMISS, WV_NET_RECV,                                   ip->ip_src.s_addr, uh->uh_sport,                                   ip->ip_dst.s_addr, uh->uh_dport)#endif  /* INCLUDE_WVNET */#endif            udpstat.udpps_pcbcachemiss++;            /*             * Locate pcb for datagram.             */            inp = in_pcblookuphash(&udbinfo, ip->ip_src, uh->uh_sport,                                       ip->ip_dst, uh->uh_dport, 1);            if (inp == NULL)                { /* look up for the wildcard match, hash look up failed */                udpstat.udpps_pcbhashmiss++;                udpstat.udps_noport++;#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_WARNING event */            WV_NET_PORTIN_EVENT_4 (NET_CORE_EVENT, WV_NET_WARNING, 18, 8,                                   uh->uh_sport, uh->uh_dport,                                   WV_NETEVENT_UDPIN_SEARCHFAIL, WV_NET_RECV,                                   ip->ip_src.s_addr, uh->uh_sport,                                   ip->ip_dst.s_addr, uh->uh_dport)#endif  /* INCLUDE_WVNET */#endif                if (m->m_flags & (M_BCAST | M_MCAST))                    {                    udpstat.udps_noportbcast++;                    goto bad;                    }#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_WARNING event */            WV_NET_PORTIN_EVENT_4 (NET_CORE_EVENT, WV_NET_WARNING, 19, 9,                                   uh->uh_sport, uh->uh_dport,                                   WV_NETEVENT_UDPIN_NOPORT, WV_NET_RECV,                                   ip->ip_src.s_addr, uh->uh_sport,                                   ip->ip_dst.s_addr, uh->uh_dport)#endif  /* INCLUDE_WVNET */#endif                *ip = save_ip;                /* bug fix mentioned in Stevens VolII page774,(vinai) */                /* ip->ip_len += iphlen; */                if (_icmpErrorHook != NULL)                    (*_icmpErrorHook) (m, ICMP_UNREACH, ICMP_UNREACH_PORT,                                        0, 0);                return;                }            }        udp_last_inpcb = inp;        pcbMatchFound:#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_INFO event */            WV_NET_PORTIN_EVENT_4 (NET_CORE_EVENT, WV_NET_INFO, 56, 18,                                   uh->uh_sport, uh->uh_dport,                                   WV_NETEVENT_UDPIN_PCBGOOD, WV_NET_RECV,                                   ip->ip_src.s_addr, uh->uh_sport,                                   inp->inp_socket->so_fd, uh->uh_dport)#endif  /* INCLUDE_WVNET */#endif	/*	 * Construct sockaddr format source address.	 * Stuff source address and datagram in user buffer.	 */	udp_in.sin_port = uh->uh_sport;	udp_in.sin_addr = ip->ip_src;	if (inp->inp_flags & INP_CONTROLOPTS) {		struct mbuf **mp = &opts;		if (inp->inp_flags & INP_RECVDSTADDR) {			*mp = udp_saveopt((caddr_t) &ip->ip_dst,			    sizeof(struct in_addr), IP_RECVDSTADDR);			if (*mp)				mp = &(*mp)->m_next;		}#ifdef notyet		/* options were tossed above */		if (inp->inp_flags & INP_RECVOPTS) {			*mp = udp_saveopt((caddr_t) opts_deleted_above,			    sizeof(struct in_addr), IP_RECVOPTS);			if (*mp)				mp = &(*mp)->m_next;		}		/* ip_srcroute doesn't do what we want here, need to fix */		if (inp->inp_flags & INP_RECVRETOPTS) {			*mp = udp_saveopt((caddr_t) ip_srcroute(),			    sizeof(struct in_addr), IP_RECVRETOPTS);			if (*mp)				mp = &(*mp)->m_next;		}#endif	}	iphlen += sizeof(struct udphdr);	m->m_len -= iphlen;	m->m_pkthdr.len -= iphlen;	m->m_data += iphlen;	if (sbappendaddr(&inp->inp_socket->so_rcv, (struct sockaddr *)&udp_in,	    m, opts) == 0) {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_WARNING event */            WV_NET_PORTIN_EVENT_1 (NET_CORE_EVENT, WV_NET_WARNING, 17, 7,                                   uh->uh_sport, uh->uh_dport,                                   WV_NETEVENT_UDPIN_FULLSOCK, WV_NET_RECV,                                   inp->inp_socket->so_fd)#endif  /* INCLUDE_WVNET */#endif		udpstat.udps_fullsock++;		goto bad;	}	sorwakeup(inp->inp_socket);	return;bad:	m_freem(m);	if (opts)		m_freem(opts);}/* * Create a "control" mbuf containing the specified data * with the specified type for presentation with a datagram. */struct mbuf *udp_saveopt(p, size, type)	caddr_t p;	register int size;	int type;{	register struct cmsghdr *cp;	struct mbuf *m;	if ((m = mBufClGet(M_DONTWAIT, MT_CONTROL, CL_SIZE_128, TRUE)) == NULL)		return ((struct mbuf *) NULL);	cp = (struct cmsghdr *) mtod(m, struct cmsghdr *);	bcopy(p, CMSG_DATA(cp), size);	size += sizeof(*cp);	m->m_len = size;	cp->cmsg_len = size;	cp->cmsg_level = IPPROTO_IP;	cp->cmsg_type = type;	return (m);}/* * Notify a udp user of an asynchronous error; * just wake up so that he can collect error status. */static voidudp_notify(inp, error)	register struct inpcb *inp;	int error;{#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_INFO event */    WV_NET_MARKER_2 (NET_AUX_EVENT, WV_NET_INFO, 48, 12,                     WV_NETEVENT_UDPNOTIFY_START,                     inp->inp_socket->so_fd, error)#endif  /* INCLUDE_WVNET */#endif	inp->inp_socket->so_error = error;	sorwakeup(inp->inp_socket);

⌨️ 快捷键说明

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