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

📄 clnp_output.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
					IFDEBUG(D_OUTPUT)						printf("clnp_output: no mbufs to allocate to cache\n");					ENDDEBUG					flags  |= CLNP_NOCACHE;					clcp = &clc;				} else {					clcp = mtod(isop->isop_clnpcache, struct clnp_cache *);				}			} else {				/*				 *	A clnpcache mbuf exists. If the clc_hdr is not null,				 *	we must free it, as a new one is about to be created.				 */				clcp = mtod(isop->isop_clnpcache, struct clnp_cache *);				if (clcp->clc_hdr != NULL) {					/*					 *	The clc_hdr is not null but a clnpcache mbuf exists.					 *	This means that there was a cache, but the existing					 *	copy of the hdr is no longer valid. Free it now					 *	before we lose the pointer to it.					 */					IFDEBUG(D_OUTPUT)						printf("clnp_output: freeing old clc_hdr 0x%x\n",						clcp->clc_hdr);					ENDDEBUG					m_free(clcp->clc_hdr);					IFDEBUG(D_OUTPUT)						printf("clnp_output: freed old clc_hdr (done)\n");					ENDDEBUG				}			}		}		IFDEBUG(D_OUTPUT)			printf("clnp_output: NEW clcp x%x\n",clcp);		ENDDEBUG		bzero((caddr_t)clcp, sizeof(struct clnp_cache));		if (isop->isop_optindex)			oidx = mtod(isop->isop_optindex, struct clnp_optidx *);		/*		 *	Don't allow packets with security, quality of service,		 *	priority, or error report options to be sent.		 */		if ((isop->isop_options) && (oidx)) {			if ((oidx->cni_securep) ||				(oidx->cni_priorp) ||				(oidx->cni_qos_formatp) ||				(oidx->cni_er_reason != ER_INVALREAS)) {				IFDEBUG(D_OUTPUT)					printf("clnp_output: pkt dropped - option unsupported\n");				ENDDEBUG				m_freem(m0);				return(EINVAL);			}		}		/*		 *	Don't allow any invalid flags to be set		 */		if ((flags & (CLNP_VFLAGS)) != flags) {			IFDEBUG(D_OUTPUT)				printf("clnp_output: packet dropped - flags unsupported\n");			ENDDEBUG			INCSTAT(cns_odropped);			m_freem(m0);			return(EINVAL);		}		/*		 *	Don't allow funny lengths on dst; src may be zero in which		 *	case we insert the source address based upon the interface		 */		if ((src->isoa_len > sizeof(struct iso_addr)) || 			(dst->isoa_len == 0) ||			(dst->isoa_len > sizeof(struct iso_addr))) {			m_freem(m0);			INCSTAT(cns_odropped);			return(ENAMETOOLONG);		}		/*		 *	Grab mbuf to contain header		 */		MGETHDR(m, M_DONTWAIT, MT_HEADER);		if (m == 0) {			m_freem(m0);			INCSTAT(cns_odropped);			return(ENOBUFS);		}		INCSTAT(cns_sent);		m->m_next = m0;		clnp = mtod(m, struct clnp_fixed *);		clcp->clc_segoff = 0;		/*		 *	Fill in all of fixed hdr except lengths and checksum		 */		if (flags & CLNP_SEND_RAW) {			*clnp = raw_template;		} else if (flags & CLNP_ECHO) {			*clnp = echo_template;		} else if (flags & CLNP_ECHOR) {			*clnp = echor_template;		} else {			*clnp = dt_template;		}		if (flags & CLNP_NO_SEG)			clnp->cnf_type &= ~CNF_SEG_OK;		if (flags & CLNP_NO_ER)			clnp->cnf_type &= ~CNF_ERR_OK;		/*		 *	Route packet; special case for source rt		 */		if ((isop->isop_options) && CLNPSRCRT_VALID(oidx)) {			IFDEBUG(D_OUTPUT)				printf("clnp_output: calling clnp_srcroute\n");			ENDDEBUG			error = clnp_srcroute(isop->isop_options, oidx, &isop->isop_route,				&clcp->clc_firsthop, &clcp->clc_ifa, dst);		} else {			IFDEBUG(D_OUTPUT)			ENDDEBUG			error = clnp_route(dst, &isop->isop_route, flags, 				&clcp->clc_firsthop, &clcp->clc_ifa);		}		if (error || (clcp->clc_ifa == 0)) {			IFDEBUG(D_OUTPUT)				printf("clnp_output: route failed, errno %d\n", error);				printf("@clcp:\n");				dump_buf(clcp, sizeof (struct clnp_cache));			ENDDEBUG			goto bad;		}		clcp->clc_rt = isop->isop_route.ro_rt;	/* XXX */		clcp->clc_ifp = clcp->clc_ifa->ia_ifp;  /* XXX */		IFDEBUG(D_OUTPUT)			printf("clnp_output: packet routed to %s\n", 				clnp_iso_addrp(					&((struct sockaddr_iso *)clcp->clc_firsthop)->siso_addr));		ENDDEBUG				/*		 *	If src address is not yet specified, use address of 		 *	interface. NOTE: this will now update the laddr field in		 *	the isopcb. Is this desirable? RAH?		 */		if (src->isoa_len == 0) {			src = &(clcp->clc_ifa->ia_addr.siso_addr);			IFDEBUG(D_OUTPUT)				printf("clnp_output: new src %s\n", clnp_iso_addrp(src));			ENDDEBUG		}		/*		 *	Insert the source and destination address,		 */		hoff = (caddr_t)clnp + sizeof(struct clnp_fixed);		CLNP_INSERT_ADDR(hoff, *dst);		CLNP_INSERT_ADDR(hoff, *src);		/*		 *	Leave room for the segment part, if segmenting is selected		 */		if (clnp->cnf_type & CNF_SEG_OK) {			clcp->clc_segoff = hoff - (caddr_t)clnp;			hoff += sizeof(struct clnp_segment);		}		clnp->cnf_hdr_len = m->m_len = (u_char)(hoff - (caddr_t)clnp);		hdrlen = clnp->cnf_hdr_len;#ifdef	DECBIT		/*		 *	Add the globally unique QOS (with room for congestion experienced		 *	bit). I can safely assume that this option is not in the options		 *	mbuf below because I checked that the option was not specified		 *	previously		 */		if ((m->m_len + sizeof(qos_option)) < MLEN) {			bcopy((caddr_t)qos_option, hoff, sizeof(qos_option));			clnp->cnf_hdr_len += sizeof(qos_option);			hdrlen += sizeof(qos_option);			m->m_len += sizeof(qos_option);		}#endif	/* DECBIT */		/*		 *	If an options mbuf is present, concatenate a copy to the hdr mbuf.		 */		if (isop->isop_options) {			struct mbuf *opt_copy = m_copy(isop->isop_options, 0, (int)M_COPYALL);			if (opt_copy == NULL) {				error = ENOBUFS;				goto bad;			}			/* Link in place */			opt_copy->m_next = m->m_next;			m->m_next = opt_copy;			/* update size of header */			clnp->cnf_hdr_len += opt_copy->m_len;			hdrlen += opt_copy->m_len;		}		if (hdrlen > CLNP_HDR_MAX) {			error = EMSGSIZE;			goto bad;		}		/*		 *	Now set up the cache entry in the pcb		 */		if ((flags & CLNP_NOCACHE) == 0) {			if (clcp->clc_hdr = m_copy(m, 0, (int)clnp->cnf_hdr_len)) {				clcp->clc_dst  = *dst;				clcp->clc_flags = flags;				clcp->clc_options = isop->isop_options;			}		}	}	/*	 *	If small enough for interface, send directly	 *	Fill in segmentation part of hdr if using the full protocol	 */	total_len = clnp->cnf_hdr_len + datalen;	if (clnp->cnf_type & CNF_SEG_OK) {		struct clnp_segment	seg_part;		/* segment part of hdr */		seg_part.cng_id = htons(clnp_id++);		seg_part.cng_off = htons(0);		seg_part.cng_tot_len = htons(total_len);		(void) bcopy((caddr_t)&seg_part, (caddr_t) clnp + clcp->clc_segoff, 			sizeof(seg_part));	}	if (total_len <= SN_MTU(clcp->clc_ifp, clcp->clc_rt)) {		HTOC(clnp->cnf_seglen_msb, clnp->cnf_seglen_lsb, total_len);		m->m_pkthdr.len = total_len;		/*		 *	Compute clnp checksum (on header only)		 */		if (flags & CLNP_NO_CKSUM) {			HTOC(clnp->cnf_cksum_msb, clnp->cnf_cksum_lsb, 0);		} else {			iso_gen_csum(m, CLNP_CKSUM_OFF, (int)clnp->cnf_hdr_len);		}		IFDEBUG(D_DUMPOUT)			struct mbuf *mdump = m;			printf("clnp_output: sending dg:\n");			while (mdump != NULL) {				dump_buf(mtod(mdump, caddr_t), mdump->m_len);				mdump = mdump->m_next;			}		ENDDEBUG		error = SN_OUTPUT(clcp, m);		goto done;	} else {		/*		 * Too large for interface; fragment if possible.		 */		error = clnp_fragment(clcp->clc_ifp, m, clcp->clc_firsthop,							total_len, clcp->clc_segoff, flags, clcp->clc_rt);		goto done;	}bad:	m_freem(m);done:	if (error) {		clnp_stat.cns_sent--;		clnp_stat.cns_odropped++;	}	return (error);}int clnp_ctloutput(){}

⌨️ 快捷键说明

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