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

📄 clnp_input.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
 *					 * NOTES: *	TODO: I would like to make seg_part a pointer into the mbuf, but  *	will it be correctly aligned? */clnp_input(m, shp)struct mbuf		*m;		/* ptr to first mbuf of pkt */struct snpa_hdr	*shp;	/* subnetwork header */{	register struct clnp_fixed	*clnp;	/* ptr to fixed part of header */	struct sockaddr_iso			source; /* source address of pkt */	struct sockaddr_iso			target; /* destination address of pkt */#define src	source.siso_addr#define dst	target.siso_addr	caddr_t						hoff;	/* current offset in packet */	caddr_t						hend;	/* address of end of header info */	struct clnp_segment			seg_part; /* segment part of hdr */	int							seg_off=0; /* offset of segment part of hdr */	int							seg_len;/* length of packet data&hdr in bytes */	struct clnp_optidx			oidx, *oidxp = NULL;	/* option index */	extern int 					iso_systype;	/* used by ESIS config resp */	extern struct sockaddr_iso	blank_siso;		/* used for initializing */	int							need_afrin = 0; 										/* true if congestion experienced */										/* which means you need afrin nose */										/* spray. How clever! */	IFDEBUG(D_INPUT)		printf(		   "clnp_input: proccessing dg; First mbuf m_len %d, m_type x%x, %s\n", 			m->m_len, m->m_type, IS_CLUSTER(m) ? "cluster" : "normal");	ENDDEBUG	need_afrin = 0;	/*	 *	If no iso addresses have been set, there is nothing	 *	to do with the packet.	 */	if (iso_ifaddr == NULL) {		clnp_discard(m, ADDR_DESTUNREACH);		return;	}		INCSTAT(cns_total);	clnp = mtod(m, struct clnp_fixed *);	IFDEBUG(D_DUMPIN)		struct mbuf *mhead;		int			total_len = 0;		printf("clnp_input: clnp header:\n");		dump_buf(mtod(m, caddr_t), clnp->cnf_hdr_len);		printf("clnp_input: mbuf chain:\n");		for (mhead = m; mhead != NULL; mhead=mhead->m_next) {			printf("m x%x, len %d\n", mhead, mhead->m_len);			total_len += mhead->m_len;		}		printf("clnp_input: total length of mbuf chain %d:\n", total_len);	ENDDEBUG	/*	 *	Compute checksum (if necessary) and drop packet if	 *	checksum does not match	 */	if (CKSUM_REQUIRED(clnp) && iso_check_csum(m, (int)clnp->cnf_hdr_len)) {		INCSTAT(cns_badcsum);		clnp_discard(m, GEN_BADCSUM);		return;	}	if (clnp->cnf_vers != ISO8473_V1) {		INCSTAT(cns_badvers);		clnp_discard(m, DISC_UNSUPPVERS);		return;	} 	/* check mbuf data length: clnp_data_ck will free mbuf upon error */	CTOH(clnp->cnf_seglen_msb, clnp->cnf_seglen_lsb, seg_len);	if ((m = clnp_data_ck(m, seg_len)) == 0)		return;		clnp = mtod(m, struct clnp_fixed *);	hend = (caddr_t)clnp + clnp->cnf_hdr_len;	/* 	 *	extract the source and destination address	 *	drop packet on failure	 */	source = target = blank_siso;	hoff = (caddr_t)clnp + sizeof(struct clnp_fixed);	CLNP_EXTRACT_ADDR(dst, hoff, hend);	if (hoff == (caddr_t)0) {		INCSTAT(cns_badaddr);		clnp_discard(m, GEN_INCOMPLETE);		return;	}	CLNP_EXTRACT_ADDR(src, hoff, hend);	if (hoff == (caddr_t)0) {		INCSTAT(cns_badaddr);		clnp_discard(m, GEN_INCOMPLETE);		return;	}	IFDEBUG(D_INPUT)		printf("clnp_input: from %s", clnp_iso_addrp(&src));		printf(" to %s\n", clnp_iso_addrp(&dst));	ENDDEBUG	/*	 *	extract the segmentation information, if it is present.	 *	drop packet on failure	 */	if (((clnp->cnf_type & CNF_TYPE) != CLNP_ER) &&		(clnp->cnf_type & CNF_SEG_OK)) {		if (hoff + sizeof(struct clnp_segment) > hend) {			INCSTAT(cns_noseg);			clnp_discard(m, GEN_INCOMPLETE);			return;		} else {			(void) bcopy(hoff, (caddr_t)&seg_part, sizeof(struct clnp_segment));			/* make sure segmentation fields are in host order */			seg_part.cng_id = ntohs(seg_part.cng_id);			seg_part.cng_off = ntohs(seg_part.cng_off);			seg_part.cng_tot_len = ntohs(seg_part.cng_tot_len);			seg_off = hoff - (caddr_t)clnp;			hoff += sizeof(struct clnp_segment);		}	}	/*	 *	process options if present. If clnp_opt_sanity returns	 *	false (indicating an error was found in the options) or	 *	an unsupported option was found	 *	then drop packet and emit an ER.	 */	if (hoff < hend) {		int		errcode;		oidxp = &oidx;		errcode = clnp_opt_sanity(m, hoff, hend-hoff, oidxp);		/* we do not support security */		if ((errcode == 0) && (oidxp->cni_securep))			errcode = DISC_UNSUPPSECURE;		/* the er option is valid with ER pdus only */		if ((errcode == 0) && (oidxp->cni_er_reason != ER_INVALREAS) && 			((clnp->cnf_type & CNF_TYPE) != CLNP_ER))			errcode = DISC_UNSUPPOPT;#ifdef	DECBIT		/* check if the congestion experienced bit is set */		if (oidxp->cni_qos_formatp) {			caddr_t	qosp = CLNP_OFFTOOPT(m, oidxp->cni_qos_formatp);			u_char	qos = *qosp;			need_afrin = ((qos & (CLNPOVAL_GLOBAL|CLNPOVAL_CONGESTED)) ==				(CLNPOVAL_GLOBAL|CLNPOVAL_CONGESTED));			if (need_afrin)				INCSTAT(cns_congest_rcvd);		}#endif	/* DECBIT */		if (errcode != 0) {			clnp_discard(m, (char)errcode);			IFDEBUG(D_INPUT)				printf("clnp_input: dropped (err x%x) due to bad options\n",					errcode);			ENDDEBUG			return;		}	}		/*	 *	check if this packet is for us. if not, then forward	 */	if (clnp_ours(&dst) == 0) {		IFDEBUG(D_INPUT)			printf("clnp_input: forwarding packet not for us\n");		ENDDEBUG 		clnp_forward(m, seg_len, &dst, oidxp, seg_off, shp);		return;	}	/*	 *	ESIS Configuration Response Function	 *	 *	If the packet received was sent to the multicast address	 *	all end systems, then send an esh to the source	 */	if ((shp->snh_flags & M_MCAST) && (iso_systype == SNPA_ES)) {		extern short esis_holding_time;		esis_shoutput(shp->snh_ifp, ESIS_ESH, esis_holding_time,			shp->snh_shost, 6, &dst);	}	/*	 *	If this is a fragment, then try to reassemble it. If clnp_reass	 *	returns non NULL, the packet has been reassembled, and should	 *	be give to TP. Otherwise the fragment has been delt with	 *	by the reassembly code (either stored or deleted). In either case	 *	we should have nothing more to do with it.	 */	if (((clnp->cnf_type & CNF_TYPE) != CLNP_ER) &&		(clnp->cnf_type & CNF_SEG_OK) &&		(seg_len != seg_part.cng_tot_len)) {		struct mbuf	*m0;		if ((m0 = clnp_reass(m, &src, &dst, &seg_part)) != NULL) {			m = m0;			clnp = mtod(m, struct clnp_fixed *);			INCSTAT(cns_reassembled);		} else {			return;		}	}		/*	 *	give the packet to the higher layer	 *	 *	Note: the total length of packet	 *	is the total length field of the segmentation part,	 *	or, if absent, the segment length field of the	 *	header.	 */	INCSTAT(cns_delivered);	switch (clnp->cnf_type & CNF_TYPE) {	case CLNP_ER:		/*		 *	This ER must have the er option.		 *	If the option is not present, discard datagram.		 */		if (oidxp == NULL || oidxp->cni_er_reason == ER_INVALREAS) {			clnp_discard(m, GEN_HDRSYNTAX);		} else {			clnp_er_input(m, &src, oidxp->cni_er_reason);		}		break;	case CLNP_DT:		(*isosw[clnp_protox[ISOPROTO_TP]].pr_input)(m, &source, &target,			clnp->cnf_hdr_len, need_afrin);		break; 	case CLNP_RAW:	case CLNP_ECR:		IFDEBUG(D_INPUT)			printf("clnp_input: raw input of %d bytes\n",				clnp->cnf_type & CNF_SEG_OK ? seg_part.cng_tot_len : seg_len);		ENDDEBUG		(*isosw[clnp_protox[ISOPROTO_RAW]].pr_input)(m, &source, &target,					clnp->cnf_hdr_len);		break;	case CLNP_EC:		IFDEBUG(D_INPUT)			printf("clnp_input: echoing packet\n");		ENDDEBUG		(void)clnp_echoreply(m,			(clnp->cnf_type & CNF_SEG_OK ? (int)seg_part.cng_tot_len : seg_len),			&source, &target, oidxp);		break;	default: 		printf("clnp_input: unknown clnp pkt type %d\n",			clnp->cnf_type & CNF_TYPE);		clnp_stat.cns_delivered--;		clnp_stat.cns_noproto++;		clnp_discard(m, GEN_HDRSYNTAX); 		break;	}}#endif /* ISO */

⌨️ 快捷键说明

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