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

📄 clnp_options.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
 *					the offset from the beginning of the mbuf data, not the *					actual address. */clnp_opt_sanity(m, opts, len, oidx)struct mbuf 		*m;		/* mbuf options reside in */caddr_t				opts;	/* ptr to buffer containing options */int					len;	/* length of buffer */struct clnp_optidx	*oidx;	/* RETURN: filled in with option idx info */{	u_char	opcode;			/* code of particular option */	u_char	oplen;			/* length of a particular option */	caddr_t	opts_end;		/* ptr to end of options */	u_char	pad = 0, secure = 0, srcrt = 0, recrt = 0, qos = 0, prior = 0;							/* flags for catching duplicate options */		IFDEBUG(D_OPTIONS)		printf("clnp_opt_sanity: checking %d bytes of data:\n", len);		dump_buf(opts, len);	ENDDEBUG	/* clear option index field if passed */	bzero((caddr_t)oidx, sizeof(struct clnp_optidx));	/*	 *	We need to indicate whether the ER option is present. This is done	 *	by overloading the er_reason field to also indicate presense of	 *	the option along with the option value. I would like ER_INVALREAS	 *	to have value 0, but alas, 0 is a valid er reason...	 */	oidx->cni_er_reason = ER_INVALREAS;	opts_end = opts + len;	while (opts < opts_end) {		/* must have at least 2 bytes per option (opcode and len) */		if (opts + 2 > opts_end)			return(GEN_INCOMPLETE);				opcode = *opts++;		oplen = *opts++;		IFDEBUG(D_OPTIONS)			printf("clnp_opt_sanity: opcode is %x and oplen %d\n",				opcode, oplen);			printf("clnp_opt_sanity: clnpoval_SRCRT is %x\n", CLNPOVAL_SRCRT);				switch (opcode) {					case CLNPOVAL_PAD: {						printf("CLNPOVAL_PAD\n");					} break;					case CLNPOVAL_SECURE: {						printf("CLNPOVAL_SECURE\n");					} break;					case CLNPOVAL_SRCRT: {							printf("CLNPOVAL_SRCRT\n");					} break;					case CLNPOVAL_RECRT: {						printf("CLNPOVAL_RECRT\n");					} break;					case CLNPOVAL_QOS: {						printf("CLNPOVAL_QOS\n");					} break;					case CLNPOVAL_PRIOR: {						printf("CLNPOVAL_PRIOR\n");					} break;					case CLNPOVAL_ERREAS: {						printf("CLNPOVAL_ERREAS\n");					} break;					default:						printf("UKNOWN option %x\n", opcode);				}		ENDDEBUG		/* don't allow crazy length values */		if (opts + oplen > opts_end)			return(GEN_INCOMPLETE);		switch (opcode) {			case CLNPOVAL_PAD:				/*				 *	Padding: increment pointer by length of padding				 */				if (pad++)						/* duplicate ? */					return(GEN_DUPOPT);				opts += oplen;				break;			case CLNPOVAL_SECURE: {				u_char	format = *opts;				if (secure++)					/* duplicate ? */					return(GEN_DUPOPT);				/*				 *	Security: high 2 bits of first octet indicate format				 *	(00 in high bits is reserved).				 *	Remaining bits must be 0. Remaining octets indicate				 *	actual security				 */				if (((format & 0x3f) > 0) ||	/* low 6 bits set ? */					((format & 0xc0) == 0))		/* high 2 bits zero ? */					return(GEN_HDRSYNTAX);				oidx->cni_securep = CLNP_OPTTOOFF(m, opts);				oidx->cni_secure_len = oplen;				opts += oplen;			} break;			case CLNPOVAL_SRCRT: {				u_char	type, offset;	/* type of rt, offset of start */				caddr_t	route_end;		/* address of end of route option */				IFDEBUG(D_OPTIONS)					printf("clnp_opt_sanity: SRC RT\n");				ENDDEBUG				if (srcrt++)					/* duplicate ? */					return(GEN_DUPOPT);				/* 				 *	source route: There must be 2 bytes following the length				 *	field: type and offset. The type must be either				 *	partial route or complete route. The offset field must				 *	be within the option. A single exception is made, however.				 *	The offset may be 1 greater than the length. This case 				 *	occurs when the last source route record is consumed. 				 *	In this case, we ignore the source route option.				 *	RAH? You should be able to set offset to 'ff' like in record				 *	route!				 *	Following this is a series of address fields. 				 *	Each address field is composed of a (length, address) pair.				 *	Insure that the offset and each address length is reasonable				 */				route_end = opts + oplen;				if (opts + 2 > route_end)					return(SRCRT_SYNTAX);				type = *opts;				offset = *(opts+1);				/* type must be partial or complete */				if (!((type == CLNPOVAL_PARTRT) || (type == CLNPOVAL_COMPRT)))					return(SRCRT_SYNTAX);								oidx->cni_srcrt_s = CLNP_OPTTOOFF(m, opts);				oidx->cni_srcrt_len = oplen;				opts += offset-1;	/*set opts to first addr in rt */				/* 				 *	Offset must be reasonable:				 *	less than end of options, or equal to end of options				 */				if (opts >= route_end) {					if (opts == route_end) {						IFDEBUG(D_OPTIONS)							printf("clnp_opt_sanity: end of src route info\n");						ENDDEBUG						break;					} else 						return(SRCRT_SYNTAX);				}				while (opts < route_end) {					u_char	addrlen = *opts++;					if (opts + addrlen > route_end)						return(SRCRT_SYNTAX);					opts += addrlen;				}			} break;			case CLNPOVAL_RECRT: {				u_char	type, offset;	/* type of rt, offset of start */				caddr_t	record_end;		/* address of end of record option */				if (recrt++)					/* duplicate ? */					return(GEN_DUPOPT);				/*				 *	record route: after the length field, expect a				 *	type and offset. Type must be partial or complete.				 *	Offset indicates where to start recording. Insure it				 *	is within the option. All ones for offset means				 *	recording is terminated.				 */				record_end = opts + oplen;				oidx->cni_recrtp = CLNP_OPTTOOFF(m, opts);				oidx->cni_recrt_len = oplen;				if (opts + 2 > record_end)					return(GEN_INCOMPLETE);				type = *opts;				offset = *(opts+1);				/* type must be partial or complete */				if (!((type == CLNPOVAL_PARTRT) || (type == CLNPOVAL_COMPRT)))					return(GEN_HDRSYNTAX);								/* offset must be reasonable */				if ((offset < 0xff) && (opts + offset > record_end))					return(GEN_HDRSYNTAX);				opts += oplen;			} break;			case CLNPOVAL_QOS: {				u_char	format = *opts;				if (qos++)					/* duplicate ? */					return(GEN_DUPOPT);				/*				 *	qos: high 2 bits of first octet indicate format				 *	(00 in high bits is reserved).				 *	Remaining bits must be 0 (unless format indicates				 *	globally unique qos, in which case remaining bits indicate				 *	qos (except bit 6 which is reserved)).  Otherwise,				 *	remaining octets indicate actual qos.				 */				if (((format & 0xc0) == 0) ||	/* high 2 bits zero ? */					(((format & 0xc0) != CLNPOVAL_GLOBAL) && 						((format & 0x3f) > 0))) /* not global,low bits used ? */					return(GEN_HDRSYNTAX);								oidx->cni_qos_formatp = CLNP_OPTTOOFF(m, opts);				oidx->cni_qos_len = oplen;				opts += oplen;			} break;			case CLNPOVAL_PRIOR: {				if (prior++)				/* duplicate ? */					return(GEN_DUPOPT);				/*				 *	priority: value must be one byte long				 */				if (oplen != 1)					return(GEN_HDRSYNTAX);								oidx->cni_priorp = CLNP_OPTTOOFF(m, opts);				opts += oplen;			} break;			case CLNPOVAL_ERREAS: {				/*				 *	er reason: value must be two bytes long				 */				if (oplen != 2)					return(GEN_HDRSYNTAX);				oidx->cni_er_reason = *opts;				opts += oplen;			} break;			default: {				IFDEBUG(D_OPTIONS)					printf("clnp_opt_sanity: UNKNOWN OPTION 0x%x\n", opcode);				ENDDEBUG				return(DISC_UNSUPPOPT);			}		}	}		IFDEBUG(D_OPTIONS)			printf("clnp_opt_sanity: return(0)\n", opcode);		ENDDEBUG	return(0);}#endif	/* ISO */

⌨️ 快捷键说明

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