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

📄 clnp_frag.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	return(1);}/* * FUNCTION:		clnp_insert_frag * * PURPOSE:			Insert fragment into list headed by 'cf'. * * RETURNS:			nothing * * SIDE EFFECTS:	 * * NOTES:			This is the 'guts' of the reassembly algorithm. *					Each fragment in this list contains a clnp_frag *					structure followed by the data of the fragment. *					The clnp_frag structure actually lies on top of *					part of the old clnp header. */clnp_insert_frag(cfh, m, seg)struct clnp_fragl	*cfh;	/* header of list of packet fragments */struct mbuf 		*m;		/* new fragment */struct clnp_segment	*seg;	/* segment part of fragment header */{	register struct clnp_fixed	*clnp;	/* clnp hdr of fragment */	register struct clnp_frag	*cf;	/* generic fragment ptr */	register struct clnp_frag 	*cf_sub = NULL;	/* frag subsequent to new one */	register struct clnp_frag 	*cf_prev = NULL; /* frag previous to new one */	u_short						first;	/* offset of first byte of initial pdu*/	u_short						last;	/* offset of last byte of initial pdu */	u_short						fraglen;/* length of fragment */		clnp = mtod(m, struct clnp_fixed *);	first = seg->cng_off;	CTOH(clnp->cnf_seglen_msb, clnp->cnf_seglen_lsb, fraglen);	fraglen -= clnp->cnf_hdr_len;	last = (first + fraglen) - 1;	IFDEBUG(D_REASS)		printf("clnp_insert_frag: New fragment: [%d ... %d], len %d\n",			first, last, fraglen);		printf("clnp_insert_frag: current fragments:\n");		for (cf = cfh->cfl_frags; cf != NULL; cf = cf->cfr_next) {			printf("\tcf x%x: [%d ... %d]\n", cf, cf->cfr_first, cf->cfr_last);		}	ENDDEBUG	if (cfh->cfl_frags != NULL) {		/*		 *	Find fragment which begins after the new one		 */		for (cf = cfh->cfl_frags; cf != NULL; cf_prev = cf, cf = cf->cfr_next) {			if (cf->cfr_first > first) {				cf_sub = cf;				break;			}		}		IFDEBUG(D_REASS)			printf("clnp_insert_frag: Previous frag is ");			if (cf_prev == NULL)				printf("NULL\n");			else 				printf("[%d ... %d]\n", cf_prev->cfr_first, cf_prev->cfr_last);			printf("clnp_insert_frag: Subsequent frag is ");			if (cf_sub == NULL)				printf("NULL\n");			else 				printf("[%d ... %d]\n", cf_sub->cfr_first, cf_sub->cfr_last);		ENDDEBUG		/*		 *	If there is a fragment before the new one, check if it		 *	overlaps the new one. If so, then trim the end of the		 *	previous one.		 */		if (cf_prev != NULL) {			if (cf_prev->cfr_last > first) {				u_short overlap = cf_prev->cfr_last - first;				IFDEBUG(D_REASS)					printf("clnp_insert_frag: previous overlaps by %d\n",						overlap);				ENDDEBUG				if (overlap > fraglen) {					/*					 *	The new fragment is entirely contained in the					 *	preceeding one. We can punt on the new frag					 *	completely.					 */					m_freem(m);					return;				} else {					/* Trim data off of end of previous fragment */					/* inc overlap to prevent duplication of last byte */					overlap++;					m_adj(cf_prev->cfr_data, -(int)overlap);					cf_prev->cfr_last -= overlap;				}			}		}		/*		 *	For all fragments past the new one, check if any data on		 *	the new one overlaps data on existing fragments. If so,		 *	then trim the extra data off the end of the new one.		 */		for (cf = cf_sub; cf != NULL; cf = cf->cfr_next) {			if (cf->cfr_first < last) {				u_short overlap = last - cf->cfr_first;				IFDEBUG(D_REASS)					printf("clnp_insert_frag: subsequent overlaps by %d\n",						overlap);				ENDDEBUG				if (overlap > fraglen) {					/*					 *	The new fragment is entirely contained in the					 *	succeeding one. This should not happen, because					 *	early on in this code we scanned for the fragment					 *	which started after the new one!					 */					m_freem(m);					printf("clnp_insert_frag: internal error!\n");					return;				} else {					/* Trim data off of end of new fragment */					/* inc overlap to prevent duplication of last byte */					overlap++;					m_adj(m, -(int)overlap);					last -= overlap;				}			}		}	}	/*	 *	Insert the new fragment beween cf_prev and cf_sub	 *	 *	Note: the clnp hdr is still in the mbuf. 	 *	If the data of the mbuf is not word aligned, shave off enough	 *	so that it is. Then, cast the clnp_frag structure on top	 *	of the clnp header. 	 *	The clnp_hdr will not be used again (as we already have	 *	saved a copy of it).	 *	 *	Save in cfr_bytes the number of bytes to shave off to get to	 *	the data of the packet. This is used when we coalesce fragments;	 *	the clnp_frag structure must be removed before joining mbufs.	 */	{		int	pad;		u_int	bytes;		/* determine if header is not word aligned */		pad = (int)clnp % 4;		if (pad < 0)			pad = -pad;		/* bytes is number of bytes left in front of data */		bytes = clnp->cnf_hdr_len - pad;		IFDEBUG(D_REASS)			printf("clnp_insert_frag: clnp x%x requires %d alignment\n",				clnp, pad);		ENDDEBUG		/* make it word aligned if necessary */		if (pad)			m_adj(m, pad);		cf = mtod(m, struct clnp_frag *);		cf->cfr_bytes = bytes;		IFDEBUG(D_REASS)			printf("clnp_insert_frag: cf now x%x, cfr_bytes %d\n", cf,				cf->cfr_bytes);		ENDDEBUG	}	cf->cfr_first = first;	cf->cfr_last = last;	/*	 *	The data is the mbuf itself, although we must remember that the	 *	first few bytes are actually a clnp_frag structure	 */	cf->cfr_data = m;	/* link into place */	cf->cfr_next = cf_sub;	if (cf_prev == NULL)		cfh->cfl_frags = cf;	else		cf_prev->cfr_next = cf;}/* * FUNCTION:		clnp_comp_pdu * * PURPOSE:			Scan the list of fragments headed by cfh. Merge *					any contigious fragments into one. If, after *					traversing all the fragments, it is determined that *					the packet is complete, then return a pointer to *					the packet (with header prepended). Otherwise, *					return NULL. * * RETURNS:			NULL, or a pointer to the assembled pdu in an mbuf chain. * * SIDE EFFECTS:	Will colapse contigious fragments into one. * * NOTES:			This code assumes that there are no overlaps of *					fragment pdus. */struct mbuf *clnp_comp_pdu(cfh)struct clnp_fragl	*cfh;		/* fragment header */{	register struct clnp_frag	*cf = cfh->cfl_frags;	while (cf->cfr_next != NULL) {		register struct clnp_frag	*cf_next = cf->cfr_next;		IFDEBUG(D_REASS)			printf("clnp_comp_pdu: comparing: [%d ... %d] to [%d ... %d]\n",				cf->cfr_first, cf->cfr_last, cf_next->cfr_first, 				cf_next->cfr_last);		ENDDEBUG		if (cf->cfr_last == (cf_next->cfr_first - 1)) {			/*			 *	Merge fragment cf and cf_next			 *			 *	- update cf header			 *	- trim clnp_frag structure off of cf_next			 *	- append cf_next to cf			 */			struct clnp_frag	cf_next_hdr;			struct clnp_frag	*next_frag;			cf_next_hdr = *cf_next;			next_frag = cf_next->cfr_next;			IFDEBUG(D_REASS)				struct mbuf *mdump;				int l;				printf("clnp_comp_pdu: merging fragments\n");				printf("clnp_comp_pdu: 1st: [%d ... %d] (bytes %d)\n", 					cf->cfr_first, cf->cfr_last, cf->cfr_bytes);				mdump = cf->cfr_data;				l = 0;				while (mdump != NULL) {					printf("\tmbuf x%x, m_len %d\n", mdump, mdump->m_len);					l += mdump->m_len;					mdump = mdump->m_next;				}				printf("\ttotal len: %d\n", l);				printf("clnp_comp_pdu: 2nd: [%d ... %d] (bytes %d)\n", 					cf_next->cfr_first, cf_next->cfr_last, cf_next->cfr_bytes);				mdump = cf_next->cfr_data;				l = 0;				while (mdump != NULL) {					printf("\tmbuf x%x, m_len %d\n", mdump, mdump->m_len);					l += mdump->m_len;					mdump = mdump->m_next;				}				printf("\ttotal len: %d\n", l);			ENDDEBUG			cf->cfr_last = cf_next->cfr_last;			/*			 *	After this m_adj, the cf_next ptr is useless because we			 *	have adjusted the clnp_frag structure away...			 */			IFDEBUG(D_REASS)				printf("clnp_comp_pdu: shaving off %d bytes\n", 					cf_next_hdr.cfr_bytes);			ENDDEBUG			m_adj(cf_next_hdr.cfr_data, (int)cf_next_hdr.cfr_bytes);			m_cat(cf->cfr_data, cf_next_hdr.cfr_data);			cf->cfr_next = next_frag;		} else {			cf = cf->cfr_next;		}	}	cf = cfh->cfl_frags;	IFDEBUG(D_REASS)		struct mbuf *mdump = cf->cfr_data;		printf("clnp_comp_pdu: first frag now: [%d ... %d]\n", cf->cfr_first,			cf->cfr_last);		printf("clnp_comp_pdu: data for frag:\n");		while (mdump != NULL) {			printf("mbuf x%x, m_len %d\n", mdump, mdump->m_len);/* 			dump_buf(mtod(mdump, caddr_t), mdump->m_len);*/			mdump = mdump->m_next;		}	ENDDEBUG	/* Check if datagram is complete */	if ((cf->cfr_first == 0) && (cf->cfr_last == cfh->cfl_last)) {		/*		 *	We have a complete pdu!		 *	- Remove the frag header from (only) remaining fragment		 *		(which is not really a fragment anymore, as the datagram is		 *		complete).		 *	- Prepend a clnp header		 */		struct mbuf	*data = cf->cfr_data;		struct mbuf	*hdr = cfh->cfl_orighdr;		struct clnp_fragl *scan;		IFDEBUG(D_REASS)			printf("clnp_comp_pdu: complete pdu!\n");		ENDDEBUG		m_adj(data, (int)cf->cfr_bytes);		m_cat(hdr, data);		IFDEBUG(D_DUMPIN)			struct mbuf *mdump = hdr;			printf("clnp_comp_pdu: pdu is:\n");			while (mdump != NULL) {				printf("mbuf x%x, m_len %d\n", mdump, mdump->m_len);/* 				dump_buf(mtod(mdump, caddr_t), mdump->m_len);*/				mdump = mdump->m_next;			}		ENDDEBUG		/*		 *	Remove cfh from the list of fragmented pdus		 */		if (clnp_frags == cfh) {			clnp_frags = cfh->cfl_next;		} else {			for (scan = clnp_frags; scan != NULL; scan = scan->cfl_next) {				if (scan->cfl_next == cfh) {					scan->cfl_next = cfh->cfl_next;					break;				}			}		}		/* free cfh */		m_freem(dtom(cfh));		return(hdr);	}	return(NULL);}#ifdef	TROLLstatic int troll_cnt;#include <sys/time.h>/* * FUNCTION:		troll_random * * PURPOSE:			generate a pseudo-random number between 0 and 1 * * RETURNS:			the random number * * SIDE EFFECTS:	 * * NOTES:			This is based on the clock. */float troll_random(){	extern struct timeval time;	long	t = time.tv_usec % 100;	return((float)t / (float) 100);}/* * FUNCTION:		troll_output * * PURPOSE:			Do something sneaky with the datagram passed. Possible *					operations are: *						Duplicate the packet *						Drop the packet *						Trim some number of bytes from the packet *						Munge some byte in the packet * * RETURNS:			0, or unix error code * * SIDE EFFECTS:	 * * NOTES:			The operation of this procedure is regulated by the *					troll control structure (Troll). */troll_output(ifp, m, dst, rt)struct ifnet	*ifp;struct mbuf		*m;struct sockaddr	*dst;struct rtentry *rt;{	int	err = 0;	troll_cnt++;	if (trollctl.tr_ops & TR_DUPPKT) {		/*		 *	Duplicate every Nth packet		 *	TODO: random?		 */		float	f_freq = troll_cnt * trollctl.tr_dup_freq;		int		i_freq = troll_cnt * trollctl.tr_dup_freq;		if (i_freq == f_freq) {			struct mbuf *dup = m_copy(m, 0, (int)M_COPYALL);			if (dup != NULL)				err = (*ifp->if_output)(ifp, dup, dst, rt);		}		if (!err)			err = (*ifp->if_output)(ifp, m, dst, rt);		return(err);	} else if (trollctl.tr_ops & TR_DROPPKT) {	} else if (trollctl.tr_ops & TR_CHANGE) {		struct clnp_fixed *clnp = mtod(m, struct clnp_fixed *);		clnp->cnf_cksum_msb = 0;		err = (*ifp->if_output)(ifp, m, dst, rt);		return(err);	} else {		err = (*ifp->if_output)(ifp, m, dst, rt);		return(err);	}}#endif	/* TROLL */

⌨️ 快捷键说明

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