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

📄 ip_output.c

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
		 * 0 is used to remove a previous selection.		 * When no interface is selected, a default one is		 * chosen every time a multicast packet is sent.		 */		if (ifIndex == 0) {			imo->imo_multicast_ifp = NULL;			break;		}		/*		 * The selected interface is identified by its interface index		 * Find the interface and confirm that it supports 		 * multicasting.		 */		IFINDEX_TO_IFP(ifIndex, ifp);		if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {			error = EINVAL;			break;		}		imo->imo_multicast_ifp = ifp;		break;#endif /* ROUTER_STACK */	case IP_MULTICAST_IF:		/*		 * Select the interface for outgoing multicast packets.		 */		if (m == NULL || m->m_len != sizeof(struct in_addr)) {			error = EINVAL;			break;		}		addr = *(mtod(m, struct in_addr *));		/*		 * INADDR_ANY is used to remove a previous selection.		 * When no interface is selected, a default one is		 * chosen every time a multicast packet is sent.		 */		if (addr.s_addr == INADDR_ANY) {			imo->imo_multicast_ifp = NULL;			break;		}		/*		 * The selected interface is identified by its local		 * IP address.  Find the interface and confirm that		 * it supports multicasting.		 */		INADDR_TO_IFP(addr, ifp);		if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {			error = EADDRNOTAVAIL;			break;		}		imo->imo_multicast_ifp = ifp;		break;	case IP_MULTICAST_TTL:		/*		 * Set the IP time-to-live for outgoing multicast packets.		 */		if (m == NULL || m->m_len != 1) {			error = EINVAL;			break;		}		imo->imo_multicast_ttl = *(mtod(m, u_char *));		break;	case IP_MULTICAST_LOOP:		/*		 * Set the loopback flag for outgoing multicast packets.		 * Must be zero or one.		 */		if (m == NULL || m->m_len != 1 ||		   (loop = *(mtod(m, u_char *))) > 1) {			error = EINVAL;			break;		}		imo->imo_multicast_loop = loop;		break;	case IP_ADD_MEMBERSHIP:#ifdef ROUTER_STACK	case IP_ADD_MEMBERSHIP_INDEX:#endif /* ROUTER_STACK */		/*		 * Add a multicast group membership.		 * Group must be a valid IP multicast address.		 */		if (m == NULL || m->m_len != sizeof(struct ip_mreq)) {			error = EINVAL;			break;		}		mreq = mtod(m, struct ip_mreq *);		if (!IN_MULTICAST(ntohl(mreq->imr_multiaddr.s_addr))) {			error = EINVAL;			break;		}#ifdef ROUTER_STACK		if ((optname == IP_ADD_MEMBERSHIP && 		     mreq->imr_interface.s_addr == INADDR_ANY) ||		    (optname == IP_ADD_MEMBERSHIP_INDEX &&		     mreq->imr_index == 0)) {#else		if (mreq->imr_interface.s_addr == INADDR_ANY) {#endif /* ROUTER_STACK */			/* 			 * If no interface index (or address) was provided, 			 * use the interface of the route to the given 			 * multicast address. 			 */			ro.ro_rt = NULL;			dst = (struct sockaddr_in *)&ro.ro_dst;			dst->sin_len = sizeof(*dst);			dst->sin_family = AF_INET;			dst->sin_addr = mreq->imr_multiaddr;			rtalloc(&ro);			if (ro.ro_rt == NULL) {				error = EADDRNOTAVAIL;				break;			}			ifp = ro.ro_rt->rt_ifp;			rtfree(ro.ro_rt);		}		else {			if (optname == IP_ADD_MEMBERSHIP)  				INADDR_TO_IFP(mreq->imr_interface, ifp);#ifdef ROUTER_STACK			else 				IFINDEX_TO_IFP(mreq->imr_index, ifp);#endif /* ROUTER_STACK */		}		/*		 * See if we found an interface, and confirm that it		 * supports multicast.		 */		if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {			error = EADDRNOTAVAIL;			break;		}                ppMblk = &imo->pInmMblk;                while (*ppMblk)                    {                    pInMulti = mtod (*ppMblk, struct in_multi*);                    if ((pInMulti->inm_ifp == ifp) &&                        (pInMulti->inm_addr.s_addr ==                         mreq->imr_multiaddr.s_addr))                        break;		/* jump out of the while loop */                    ppMblk = &(*ppMblk)->mBlkHdr.mNext;                    }                if (*ppMblk == NULL)                    {                    if ((pInmMblk = in_addmulti (&mreq->imr_multiaddr,                                                 ifp, pInPcb)) == NULL)                        {			error = ENOBUFS;                        break;                        }                    *ppMblk = pInmMblk;		/* add to the list */                    ++imo->imo_num_memberships;                    }                else                    error = EADDRINUSE;                break;	case IP_DROP_MEMBERSHIP:#ifdef ROUTER_STACK	case IP_DROP_MEMBERSHIP_INDEX:#endif /* ROUTER_STACK */		/*		 * Drop a multicast group membership.		 * Group must be a valid IP multicast address.		 */		if (m == NULL || m->m_len != sizeof(struct ip_mreq)) {			error = EINVAL;			break;		}		mreq = mtod(m, struct ip_mreq *);		if (!IN_MULTICAST(ntohl(mreq->imr_multiaddr.s_addr))) {			error = EINVAL;			break;		}#ifdef ROUTER_STACK		/*		 * If an interface address (or index) was specified, 		 * get a pointer to its ifnet structure.		 */		if ((optname == IP_DROP_MEMBERSHIP && 		     mreq->imr_interface.s_addr == INADDR_ANY) ||		    (optname == IP_DROP_MEMBERSHIP_INDEX &&		     mreq->imr_index == 0))#else		if (mreq->imr_interface.s_addr == INADDR_ANY)#endif /* ROUTER_STACK */			ifp = NULL;		else {			if (optname == IP_DROP_MEMBERSHIP)  				INADDR_TO_IFP(mreq->imr_interface, ifp);#ifdef ROUTER_STACK			else 				IFINDEX_TO_IFP(mreq->imr_index, ifp);#endif /* ROUTER_STACK */			if (ifp == NULL) {				error = EADDRNOTAVAIL;				break;			}		}                ppMblk = &imo->pInmMblk;                while (*ppMblk)                    {                    pInMulti = mtod (*ppMblk, struct in_multi*);                    if ((ifp == NULL || pInMulti->inm_ifp == ifp) &&                        (pInMulti->inm_addr.s_addr ==                         mreq->imr_multiaddr.s_addr))                        {                        pInmMblk = *ppMblk;                        /* delete from the list */                        *ppMblk = (*ppMblk)->mBlkHdr.mNext;                         break;		/* jump out of the while loop */                        }                    ppMblk = &(*ppMblk)->mBlkHdr.mNext;                    }                if (pInmMblk == NULL)                    {                    error = EADDRNOTAVAIL;                    break;                    }                		/*		 * Give up the multicast address record to which the		 * membership points.		 */		in_delmulti (pInmMblk, pInPcb);		--imo->imo_num_memberships;                		break;	default:		error = EOPNOTSUPP;		break;	}	/*	 * If all options have default values, no need to keep the mbuf.	 */	if (imo->imo_multicast_ifp == NULL &&	    imo->imo_multicast_ttl == IP_DEFAULT_MULTICAST_TTL &&	    imo->imo_multicast_loop == IP_DEFAULT_MULTICAST_LOOP &&	    imo->imo_num_memberships == 0) {		 FREE(*imop, MT_IPMOPTS);		*imop = NULL;	}	return (error);}/* * Return the IP multicast options in response to user getsockopt(). */intip_getmoptions(optname, imo, mp)	int optname;	register struct ip_moptions *imo;	register struct mbuf **mp;{	u_char *ttl;	u_char *loop;	struct in_addr *addr;	struct in_ifaddr *ia;	*mp = mBufClGet(M_WAIT, MT_SOOPTS, CL_SIZE_128, TRUE);	if (*mp == NULL)	    return (ENOBUFS);	    	switch (optname) {	case IP_MULTICAST_IF:		addr = mtod(*mp, struct in_addr *);		(*mp)->m_len = sizeof(struct in_addr);		if (imo == NULL || imo->imo_multicast_ifp == NULL)			addr->s_addr = INADDR_ANY;		else {			IFP_TO_IA(imo->imo_multicast_ifp, ia);			addr->s_addr = (ia == NULL) ? INADDR_ANY					: IA_SIN(ia)->sin_addr.s_addr;		}		return (0);	case IP_MULTICAST_TTL:		ttl = mtod(*mp, u_char *);		(*mp)->m_len = 1;		*ttl = (imo == NULL) ? IP_DEFAULT_MULTICAST_TTL				     : imo->imo_multicast_ttl;		return (0);	case IP_MULTICAST_LOOP:		loop = mtod(*mp, u_char *);		(*mp)->m_len = 1;		*loop = (imo == NULL) ? IP_DEFAULT_MULTICAST_LOOP				      : imo->imo_multicast_loop;		return (0);	default:		return (EOPNOTSUPP);	}}/* * Discard the IP multicast options. */voidip_freemoptions(imo, pInPcb)	register struct ip_moptions *imo;	struct inpcb * 	pInPcb;        {        M_BLK_ID	pInmMblk;        M_BLK_ID	pInmMblkNext;	if (imo != NULL) {                pInmMblk = imo->pInmMblk;                pInmMblkNext = imo->pInmMblk;        	while ((pInmMblk = pInmMblkNext) != NULL)                    {                    pInmMblkNext = pInmMblk->mBlkHdr.mNext;                     in_delmulti (pInmMblk, pInPcb);                    }		FREE(imo, MT_IPMOPTS);	}}/* * Routine called from ip_output() to loop back a copy of an IP multicast * packet to the input queue of a specified interface.  Note that this * calls the output routine of the loopback "driver", but with an interface * pointer that might NOT be &loif -- easier than replicating that code here. */voidip_mloopback(ifp, m, dst, rt)	struct ifnet *ifp;	register struct mbuf *m;	register struct sockaddr_in *dst;	struct rtentry *rt;{	register struct ip *ip;	struct mbuf *copym;        struct mbuf * pMbuf;#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_INFO event */    WV_NET_EVENT_0 (NET_AUX_EVENT, WV_NET_INFO, 12, 7,                    WV_NETEVENT_IPMLOOP_START, WV_NET_RECV)#endif  /* INCLUDE_WVNET */#endif	copym = m_copy(m, 0, M_COPYALL);	if (copym != NULL) {		/*		 * We don't bother to fragment if the IP length is greater		 * than the interface's MTU.  Can this possibly matter?		 */		ip = mtod(copym, struct ip *);                /*                 * This copying of ip header is done because the same                 * ip header is shared by looutput and the code under the                 * the label sendit: in ip_output. so a fresh mbuf has to be                 * linked to the data.                 */                if ((pMbuf = mBufClGet (M_DONTWAIT, MT_DATA, sizeof(struct ip),                                   TRUE)) == NULL)                    {                    m_freem (copym);                     return;                    }                /* copy the ip header */                bcopy ((char *)ip , (char *)(mtod(pMbuf, char *)),                       sizeof(struct ip));                pMbuf->m_len   = sizeof (struct ip);                 pMbuf->m_flags = copym->m_flags;	/* copy the flags */                pMbuf->m_pkthdr = copym->m_pkthdr;	/* copy the pkt hdr */                pMbuf->m_next = copym;                                copym->m_flags &= ~M_PKTHDR;                copym->m_len -= sizeof(struct ip);                copym->m_data += sizeof(struct ip);		ip = mtod(pMbuf, struct ip *);                copym = pMbuf; 		ip->ip_len = htons((u_short)ip->ip_len);		ip->ip_off = htons((u_short)ip->ip_off);                ip->ip_sum = 0;                if (_ipCfgFlags & IP_DO_CHECKSUM_SND)                    ip->ip_sum = in_cksum(copym, ip->ip_hl << 2);		(void) looutput(ifp, copym, (struct sockaddr *)dst, rt);	}}

⌨️ 快捷键说明

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