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

📄 ip_output.c

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
	ip->ip_len += optlen;	return (m);}/* * Copy options from ip to jp, * omitting those not copied during fragmentation. */intip_optcopy(ip, jp)	struct ip *ip, *jp;{	register u_char *cp, *dp;	int opt, optlen, cnt;	cp = (u_char *)(ip + 1);	dp = (u_char *)(jp + 1);	cnt = (ip->ip_hl << 2) - sizeof (struct ip);	for (; cnt > 0; cnt -= optlen, cp += optlen) {		opt = cp[0];		if (opt == IPOPT_EOL)			break;		if (opt == IPOPT_NOP) {			/* Preserve for IP mcast tunnel's LSRR alignment. */			*dp++ = IPOPT_NOP;			optlen = 1;			continue;		} else			optlen = cp[IPOPT_OLEN];		/* bogus lengths should have been caught by ip_dooptions */		if (optlen > cnt)			optlen = cnt;		if (IPOPT_COPIED(opt)) {			bcopy((caddr_t)cp, (caddr_t)dp, (unsigned)optlen);			dp += optlen;		}	}	for (optlen = dp - (u_char *)(jp+1); optlen & 0x3; optlen++)		*dp++ = IPOPT_EOL;	return (optlen);}/* * IP socket option processing. */intip_ctloutput(op, so, level, optname, mp)	int op;	struct socket *so;	int level, optname;	struct mbuf **mp;{	register struct inpcb *inp = sotoinpcb(so);	register struct mbuf *m = *mp;	register int optval = 0;	int error = 0;#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_INFO event */    WV_NET_MARKER_4 (NET_AUX_EVENT, WV_NET_INFO, 11, 6,                     WV_NETEVENT_IPOUTCTRL_START,                     so->so_fd, op, level, optname)#endif  /* INCLUDE_WVNET */#endif	if (level != IPPROTO_IP) {		error = EINVAL;		if (op == PRCO_SETOPT && *mp)			(void) m_free(*mp);	} else switch (op) {	case PRCO_SETOPT:		switch (optname) {		case IP_OPTIONS:#ifdef notyet		case IP_RETOPTS:			return (ip_pcbopts(optname, &inp->inp_options, m));#else			return (ip_pcbopts(&inp->inp_options, m));#endif		case IP_TOS:		case IP_TTL:		case IP_RECVOPTS:		case IP_RECVRETOPTS:		case IP_RECVDSTADDR:			if (m->m_len != sizeof(int))				error = EINVAL;			else {				optval = *mtod(m, int *);				switch (optname) {				case IP_TOS:					inp->inp_ip.ip_tos = optval;					break;				case IP_TTL:					inp->inp_ip.ip_ttl = optval;					break;#define	OPTSET(bit) \	if (optval) \		inp->inp_flags |= bit; \	else \		inp->inp_flags &= ~bit;				case IP_RECVOPTS:					OPTSET(INP_RECVOPTS);					break;				case IP_RECVRETOPTS:					OPTSET(INP_RECVRETOPTS);					break;				case IP_RECVDSTADDR:					OPTSET(INP_RECVDSTADDR);					break;				}			}			break;#undef OPTSET		case IP_MULTICAST_IF:		case IP_MULTICAST_TTL:		case IP_MULTICAST_LOOP:		case IP_ADD_MEMBERSHIP:		case IP_DROP_MEMBERSHIP:#ifdef ROUTER_STACK		case IP_MULTICAST_IFINDEX:		case IP_ADD_MEMBERSHIP_INDEX:		case IP_DROP_MEMBERSHIP_INDEX:#endif /* ROUTER_STACK */			error = ip_setmoptions(optname, inp, m);			break;		default:#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_ERROR event */                    WV_NET_MARKER_4 (NET_AUX_EVENT, WV_NET_ERROR, 30, 5,                                     WV_NETEVENT_IPOUTCTRL_BADCMD,                                     so->so_fd, op, level, optname)#endif  /* INCLUDE_WVNET */#endif			error = ENOPROTOOPT;			break;		}		if (m)			(void)m_free(m);		break;	case PRCO_GETOPT:		switch (optname) {		case IP_OPTIONS:		case IP_RETOPTS:			*mp = m = mBufClGet(M_WAIT, MT_SOOPTS, CL_SIZE_128,					    TRUE);			if (m == NULL)			    {			    error = ENOBUFS;			    break;			    }			if (inp->inp_options) {				m->m_len = inp->inp_options->m_len;				bcopy(mtod(inp->inp_options, caddr_t),				    mtod(m, caddr_t), (unsigned)m->m_len);			} else				m->m_len = 0;			break;		case IP_TOS:		case IP_TTL:		case IP_RECVOPTS:		case IP_RECVRETOPTS:		case IP_RECVDSTADDR:			*mp = m = mBufClGet(M_WAIT, MT_SOOPTS, CL_SIZE_128,					    TRUE);			if (m == NULL)			    {			    error = ENOBUFS;			    break;			    }			m->m_len = sizeof(int);			switch (optname) {			case IP_TOS:				optval = inp->inp_ip.ip_tos;				break;			case IP_TTL:				optval = inp->inp_ip.ip_ttl;				break;#define	OPTBIT(bit)	(inp->inp_flags & bit ? 1 : 0)			case IP_RECVOPTS:				optval = OPTBIT(INP_RECVOPTS);				break;			case IP_RECVRETOPTS:				optval = OPTBIT(INP_RECVRETOPTS);				break;			case IP_RECVDSTADDR:				optval = OPTBIT(INP_RECVDSTADDR);				break;			}			*mtod(m, int *) = optval;			break;		case IP_MULTICAST_IF:		case IP_MULTICAST_TTL:		case IP_MULTICAST_LOOP:		case IP_ADD_MEMBERSHIP:		case IP_DROP_MEMBERSHIP:#ifdef ROUTER_STACK		case IP_MULTICAST_IFINDEX:		case IP_ADD_MEMBERSHIP_INDEX:		case IP_DROP_MEMBERSHIP_INDEX:#endif /* ROUTER_STACK */			error = ip_getmoptions(optname, inp->inp_moptions, mp);			break;		default:#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_ERROR event */                    WV_NET_MARKER_4 (NET_AUX_EVENT, WV_NET_ERROR, 30, 5,                                     WV_NETEVENT_IPOUTCTRL_BADCMD,                                     so->so_fd, op, level, optname)#endif  /* INCLUDE_WVNET */#endif			error = ENOPROTOOPT;			break;		}		break;	}	return (error);}/* * Set up IP options in pcb for insertion in output packets. * Store in mbuf with pointer in pcbopt, adding pseudo-option * with destination address if source routed. */int#ifdef notyetip_pcbopts(optname, pcbopt, m)	int optname;#elseip_pcbopts(pcbopt, m)#endif	struct mbuf **pcbopt;	register struct mbuf *m;{	register int cnt, optlen;	register u_char *cp;	u_char opt;	/* turn off any old options */	if (*pcbopt)		(void)m_free(*pcbopt);	*pcbopt = 0;	if (m == (struct mbuf *)0 || m->m_len == 0) {		/*		 * Only turning off any previous options.		 */		if (m)			(void)m_free(m);		return (0);	}#ifndef	vax	if (m->m_len % sizeof(long))		goto bad;#endif	/*	 * IP first-hop destination address will be stored before	 * actual options; move other options back	 * and clear it when none present.	 */#if 0 /*XXX changed for default cluster support vinai*/	if (m->m_data + m->m_len + sizeof(struct in_addr) >= &m->m_dat[MLEN])		goto bad;#else	if (m->m_data + m->m_len + sizeof(struct in_addr) >= 	    (m->m_extBuf + m->m_extSize))		goto bad;#endif	cnt = m->m_len;	m->m_len += sizeof(struct in_addr);	cp = mtod(m, u_char *) + sizeof(struct in_addr);	ovbcopy(mtod(m, caddr_t), (caddr_t)cp, (unsigned)cnt);	bzero(mtod(m, caddr_t), sizeof(struct in_addr));	for (; cnt > 0; cnt -= optlen, cp += optlen) {		opt = cp[IPOPT_OPTVAL];		if (opt == IPOPT_EOL)			break;		if (opt == IPOPT_NOP)			optlen = 1;		else {			optlen = cp[IPOPT_OLEN];			if (optlen <= IPOPT_OLEN || optlen > cnt)				goto bad;		}		switch (opt) {		default:			break;		case IPOPT_LSRR:		case IPOPT_SSRR:			/*			 * user process specifies route as:			 *	->A->B->C->D			 * D must be our final destination (but we can't			 * check that since we may not have connected yet).			 * A is first hop destination, which doesn't appear in			 * actual IP option, but is stored before the options.			 */			if (optlen < IPOPT_MINOFF - 1 + sizeof(struct in_addr))				goto bad;			m->m_len -= sizeof(struct in_addr);			cnt -= sizeof(struct in_addr);			optlen -= sizeof(struct in_addr);			cp[IPOPT_OLEN] = optlen;			/*			 * Move first hop before start of options.			 */			bcopy((caddr_t)&cp[IPOPT_OFFSET+1], mtod(m, caddr_t),			    sizeof(struct in_addr));			/*			 * Then copy rest of options back			 * to close up the deleted entry.			 */			ovbcopy((caddr_t)(&cp[IPOPT_OFFSET+1] +			    sizeof(struct in_addr)),			    (caddr_t)&cp[IPOPT_OFFSET+1],			    (unsigned)cnt + sizeof(struct in_addr));			break;		}	}	if (m->m_len > MAX_IPOPTLEN + sizeof(struct in_addr))		goto bad;	*pcbopt = m;	return (0);bad:	(void)m_free(m);	return (EINVAL);}/* * Set the IP multicast options in response to user setsockopt(). */static int ip_setmoptions    (    int			optname,    struct inpcb * 	pInPcb,    struct mbuf *	m    ){	register int error = 0;	u_char loop;#ifdef ROUTER_STACK        int ifIndex;#endif /* ROUTER_STACK */	struct in_addr addr;	register struct ip_mreq *mreq;	register struct ifnet *ifp = NULL;        register struct ip_moptions ** imop = &pInPcb->inp_moptions;	register struct ip_moptions *imo = *imop;	struct route ro;	register struct sockaddr_in *dst;        struct in_multi * 	pInMulti;        M_BLK_ID 		pInmMblk = NULL;        M_BLK **		ppMblk;	if (imo == NULL) {		/*		 * No multicast option buffer attached to the pcb;		 * allocate one and initialize to default values.		 */		MALLOC(imo,struct ip_moptions *, sizeof (*imo),		       MT_IPMOPTS, M_WAIT);		if (imo == NULL)			return (ENOBUFS);		*imop = imo;		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;                imo->pInmMblk = NULL; 	}	switch (optname) {#ifdef ROUTER_STACK	case IP_MULTICAST_IFINDEX:		/*		 * Select the interface for outgoing multicast packets.		 */		if (m == NULL || m->m_len != sizeof(short)) {			error = EINVAL;			break;		}		ifIndex = *(mtod(m, unsigned short *));		/*

⌨️ 快捷键说明

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