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

📄 text_param.c

📁 iscsi源代码 UNH的progect 有initiator端和target端的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Called to get pointer to table entry for key identified by its special flag*/struct parameter_type * __attribute__ ((no_instrument_function))find_flag_parameter(__u64 key_flag,		    struct parameter_type p_param_tbl[MAX_CONFIG_PARAMS]){	struct parameter_type *p, *result = NULL;	int i;	for (i = 0, p = p_param_tbl; i < MAX_CONFIG_PARAMS; i++, p++) {		if (p->special_key_flag & key_flag) {			result = p;			break;		}	}	return result;}/*	Called to set max_recv_length to value we sent to target in a *	MaxRecvDataSegmentLength key */voidset_connection_recv_length(struct parameter_type p_param_tbl[MAX_CONFIG_PARAMS],			   int *max_recv_length){	struct parameter_type *p;	TRACE(TRACE_ENTER_LEAVE, "Enter set_connection_recv_length\n");	if ((p =	     find_flag_parameter(MAXRECVDATASEGMENTLENGTH_FLAG, p_param_tbl))	    && IS_KEY_SENT_TO_OTHER_SIDE(p->neg_info)) {		/* we did send this key to the other side */		*max_recv_length = p->int_value;	}	TRACE(TRACE_ENTER_LEAVE, "Leave set_connection_recv_length\n");}voidset_digestflags(struct parameter_type p_param_tbl[MAX_CONFIG_PARAMS],		__u32 * connection_flags){	struct parameter_type *p;	if ((p = find_flag_parameter(HEADERDIGEST_FLAG, p_param_tbl))) {		if (strcmp(p->str_value, CRC32C) == 0) {			*connection_flags |= USE_HEADERDIGEST;			TRACE(TRACE_ISCSI, "Enabling Header Digests\n");		}	}	if ((p = find_flag_parameter(DATADIGEST_FLAG, p_param_tbl))) {		if (strcmp(p->str_value, CRC32C) == 0) {			*connection_flags |= USE_DATADIGEST;			TRACE(TRACE_ISCSI, "Enabling Data Digests\n");		}	}}/*	Check that a number is within legal bounds depending on its type. *	Returns 1 if ok, 0 if error */int __attribute__ ((no_instrument_function))check_bounds(struct parameter_type *p, int int_value, int who_called){	int retval = 1;	if (IS_ONE_TO_65535(p->type)) {		if ((int_value < 1) || (int_value > 65535)) {			TRACE_ERROR("illegal number %d - "				    "should be between 1 and 65535\n",				    int_value);			retval = 0;		}	} else if (IS_ZERO_TO_65535(p->type)) {		if ((int_value < 0) || (int_value > 65535)) {			TRACE_ERROR("illegal number %d - "				    "should be between 0 and 65535\n",				    int_value);			retval = 0;		}	} else if (IS_N512_TO_16777215(p->type)) {		if ((int_value < 512) || (int_value > 16777215)) {			if (who_called == MANAGEMENT &&			    (p->special_key_flag & (MAXBURSTLENGTH_FLAG |						    FIRSTBURSTLENGTH_FLAG))) {				/* Burst limits depend on draft, 					do it at run time */			} else {				TRACE_ERROR("illegal number %d - "					    "should be between 512 and 16777215\n",					    int_value);				retval = 0;			}		}	} else if (IS_ZERO_TO_3600(p->type)) {		if ((int_value < 0) || (int_value > 3600)) {			TRACE_ERROR("illegal number %d - "				    "should be between 0 and 3600\n",				    int_value);			retval = 0;		}	} else if (IS_ZERO_TO_2(p->type)) {		if ((int_value < 0) || (int_value > 2)) {			TRACE_ERROR("illegal number %d - "				    "should be between 0 and 2\n", int_value);			retval = 0;		}	}	return retval;}/*	This is a range, check both numbers and their order. *	Returns first number in range if ok, -1 if error */int __attribute__ ((no_instrument_function))check_range(char *value_list, int value){	char *endptr;	int lower, upper;	lower = simple_strtoul(value_list, &endptr, 0);	if (*endptr == '~') {		/* first number followed by ~ must be 			followed by another number */		upper = simple_strtoul(endptr + 1, &endptr, 0);	} else {		/* only 1 value was specified, which is ok */		upper = lower;	}	if (strspn(endptr, WHITE_SPACE) != strlen(endptr) || lower > upper) {		TRACE_ERROR("illegal range \"%s\"\n", value_list);		return -1;	}	if (value >= 0 && (value < lower || value > upper)) {		TRACE_ERROR("value %d out of range \"%s\"\n", value,			    value_list);		return -1;	}	return lower;}/* * Checks correctness of the type of parameter with the value passed	 * The main types are defined in "text_param.h"	 * If the value is NULL, no checks made. * On return, a flag is set in p->neg_info if a fatal error occured * Called only from check_correctness */static void __attribute__ ((no_instrument_function))check_type_correctness(struct parameter_type *p,		       char *value, int who_called, int *int_value){	char *dummy;	char *endptr = NULL;	TRACE(TRACE_ENTER_LEAVE, "Enter check_type_correctness\n");	TRACE(TRACE_ENTER_LEAVE, "Parameter: %s, value: %s\n",	      p->parameter_name, value);	/* If the value is inquiry, ignore it */	if (!strcmp(value, "?"))		goto out;	/* look for value = "Reject" or "Irrelevant" or "NotUnderstood" */	if (!strcmp(value, key_table->reject)) {		if (!IS_KEY_SENT_TO_OTHER_SIDE(p->neg_info)) {			/* Reject always fatal as an offer */			TRACE_ERROR("illegal offer: %s=%s\n", p->parameter_name,				    value);			p->neg_info |= KEY_BAD;		} else if (p->			   special_key_flag & (OFMARKINT_FLAG | IFMARKINT_FLAG))		{			/* Reject is not fatal as a reply to 			 * OFMarkInt/IFMarkInt keys 			 *  Draft 20, Section A.3.2 OFMarkInt, IFMarkInt			 *  "When the interval is unacceptable the responder 			 *  answers with "Reject".  Reject is resetting 			 *  the marker function in the			 *  specified direction (Output or Input) to No."			 */			/* so we can do a reset later */			p->neg_info |= KEY_REJECT;			} else {			/* Reject always fatal as a reply to all other keys */			TRACE_ERROR("got key: %s=%s\n", p->parameter_name,				    value);			p->neg_info |= KEY_BAD;		}		goto out;	}	if (!strcmp(value, key_table->irrelevant)) {		if (!IS_KEY_SENT_TO_OTHER_SIDE(p->neg_info)) {			/* Irrelevant always fatal as an offer */			TRACE_ERROR("illegal offer: %s=%s\n", p->parameter_name,				    value);			p->neg_info |= KEY_BAD;		} else {			/* Irrelevant is a legal reply in all negotiations */			if (TRACE_TEST(TRACE_ISCSI)) {				TRACE_WARNING("got key: %s=%s\n",						p->parameter_name, value);			}			p->neg_info |= KEY_IRRELEVANT;		}		goto out;	}	/*  Draft 20, Section 5.2 Text Mode Negotiation	 *  "All keys in this document, except for the X extension formats, 	 *  MUST be supported by iSCSI initiators and targets when used 	 *  as specified here.	 *  If used as specified, these keys MUST NOT be answered with	 *  NotUnderstood."	 */	if (!strcmp(value, key_table->notunderstood)) {		if (!IS_KEY_SENT_TO_OTHER_SIDE(p->neg_info)) {			/* NotUnderstood always fatal as an offer */			TRACE_ERROR("illegal offer: %s=%s\n", p->parameter_name,				    value);			p->neg_info |= KEY_BAD;		} else if ((p->special_key_flag & X_EXTENSIONKEY_FLAG)) {			/* target not expected to understand this 				anyway, consider its response irrelevant */			p->neg_info |= KEY_IRRELEVANT;		} else {			/* NotUnderstood always fatal as a reply to 				a standard key */			TRACE_ERROR			    ("standard key \"%s\" MUST NOT be answered with "			     "\"%s\"\n", p->parameter_name,			     key_table->notunderstood);			p->neg_info |= KEY_BAD;		}		goto out;	}	if (IS_STRING(p->type)) {		/*  key value is a string, just check its total length */		/*  Draft 20, Section 5.1 Text Format		 *  "If not otherwise specified, the maximum length of a 		 *  simple-value (not its encoded representation) is 255 		 *  bytes not including the delimiter (comma or zero byte)."		 *		 *  Draft 20, Section 3.2.6.1  iSCSI Name Properties		 *  "Each iSCSI node, whether an initiator or target, 		 *  MUST have an iSCSI name.		 *		 *  Initiators and targets MUST support the receipt of iSCSI		 *  names of up to the maximum length of 223 bytes. "		 */		char *tptr;		int len = strlen(value);		int t_num;		if (len > MAX_KEY_VALUE_LENGTH) {			TRACE_ERROR			    ("value of key \"%s\" longer than %d characters\n",			     p->parameter_name,			     (IS_ISCSI_NAME(p->type) ? MAX_ISCSI_NAME_LENGTH :			      MAX_KEY_VALUE_LENGTH));			p->neg_info |= KEY_BAD;		}		/* check ISCSI_NAME type */		if (IS_ISCSI_NAME(p->type)) {			if (who_called == TARGET &&			    p->special_key_flag & TARGETNAME_FLAG) {				/* check TargetName sent by the initiator */				p->int_value = 0;	/* assume an error */				if ((strncmp(TARGETNAME_HEADER, value,					     strlen(TARGETNAME_HEADER)) != 0)				    || (tptr = strchr(value, ':')) == NULL) {					TRACE_WARNING					    ("invalid %s \"%s\". "					    "Use Discovery session"					    " to get proper %s.\n",					     p->parameter_name, value,					     p->parameter_name);					goto out;				}				tptr++;		/* point at char after ':' */				if (strspn(tptr, WHITE_SPACE) == strlen(tptr)) {					TRACE_ERROR					    ("no target number in %s \"%s\"\n",					    p->parameter_name, value);					p->neg_info |= KEY_BAD;					goto out;				}				t_num = simple_strtoul(tptr, &endptr, 10);				if (t_num < 0 || *endptr != '\0') {					TRACE_ERROR					    ("bad target number \"%s\" "					    "in %s \"%s\"\n",					    tptr, p->parameter_name, value);					p->neg_info |= KEY_BAD;					goto out;				}				/* check target number from the target name */				if (!target_in_use(t_num)) {					TRACE_ERROR					    ("target number %d not in use "					     "in %s \"%s\"\n",					     t_num, p->parameter_name, value);					p->neg_info |= KEY_BAD;					goto out;				}				/* target number ok, save it for pickup later */				p->int_value = t_num;			}			/*  check the format of the iSCSI name */			/*  Draft 20, 3.2.6.3  iSCSI Name Structure			 *  "The type designator strings currently defined are:			 *      iqn.  - iSCSI Qualified name			 *      eui.  - Remainder of the string is an 			 *              IEEE EUI-64 identifier, in 			 *              ASCII-encoded hexadecimal."			 */			if (len == 20 && strncmp(value, "eui.", 4) == 0) {				/* IEEE format world wide unique name -- 				   16 hex digits must follow */				if (strspn(value + 4, "0123456789abcdefABCDEF")				    == 16)					/* ok, have exactly 16 hex 						digits following the "eui." */					goto out;			} else if (len > 12 && len <= MAX_ISCSI_NAME_LENGTH &&				   strncmp(value, "iqn.", 4) == 0) {				/* iSCSI qualified name -- must get "yyyy-mm." 				   then alphanums, ., - */				if (strspn(value + 4, "0123456789") == 4				    && *(value + 8) == '-'				    && strspn(value + 9, "0123456789") == 2				    && *(value + 11) == '.'				    && strspn(value + 12,					     "0123456789abcdefghijklmnopqrstuvwxyz-.:") == len - 12) {					/* ok, have iqn.yyyy-mm.xxx with xxx 					 * all digits, lower-case letters, 					 * * '-', '.', ':' 					 */					goto out;				}			}			/* If reach here have invalid iSCSI name */			if (TRACE_TEST(TRACE_ISCSI)) {			    TRACE_WARNING("invalid iSCSI name \"%s\"\n", value);			}			goto out;		}	}	/* the following are to be tested for each value in the list    */	do {		endptr = NULL;		/* extract just a single value */		dummy = strchr(value, ',');		if (dummy) {			/* found a comma so value contains list of 				values -- is this ok? */			if (!IS_KEY_MULTI_VALUE(p->type)			    && !(p->special_key_flag & TARGETADDRESS_FLAG)) {				/* this key cannot accept a list of values */				TRACE_ERROR				    ("key \"%s\" does not accept a list of values "				     "\"%s\"\n", p->parameter_name, value);				p->neg_info |= KEY_BAD;				break;			}			/* terminate first item in the list so it 				is a string by itself */			*dummy = '\0';		}		TRACE(TRACE_DEBUG, "value: %s\n", value);		/*  Check for length of the key value. */		/*  Draft 20, Section 5.1 Text Format		 *  "If not otherwise specified, the maximum length of 		 *  a simple-value (not its encoded representation) is 		 *  255 bytes not including the		 *  delimiter (comma or zero byte)."		 */		if (strlen(value) > MAX_KEY_VALUE_LENGTH) {			if (TRACE_TEST(TRACE_ISCSI)) {			      TRACE_WARNING("value of key \"%s\" "					"exceeds %d characters\n",					p->parameter_name,MAX_KEY_VALUE_LENGTH);			}		}		if (*value == '\0' && !IS_KEY_NO_VALUE(p->type)) {			TRACE_ERROR("no value after '=' for key \"%s\"\n",				    p->parameter_name);			p->neg_info |= KEY_BAD;			break;		}		else if (IS_NUMBER(p->type) ||			 (IS_NUMBER_RANGE(p->type) &&			  IS_KEY_SENT_TO_OTHER_SIDE(p->neg_info))) {			/* a number or a reply to a range */			*int_value = simple_strtoul(value, &endptr, 0);			if (strspn(endptr, WHITE_SPACE) != strlen(endptr)) {				TRACE_ERROR("illegal number \"%s\"\n", value);				p->neg_info |= KEY_BAD;				break;			}			if (!check_bounds(p, *int_value, who_called)) {				p->neg_info |= KEY_BAD;				break;			}		}		else if (IS_BOOLEAN(p->type)) {			if (strcmp(value, key_table->yes)			    && strcmp(value, key_table->no)) {				TRACE_ERROR("illegal value \"%s\" - expected "					    "\"%s\" or \"%s\"\n", value,					    key_table->yes, key_table->no);				p->neg_info |= KEY_BAD;				break;			}		}		else if (IS_ENUMERATED(p->type)) {			if (IS_AUTH_PARAM(p->type)) {				if (strcmp(value, KRB5) && strcmp(value, SPKM1)				    && strcmp(value, SPKM2)				    && strcmp(value, SRP)				    && strcmp(value, CHAP)				    && strcmp(value, key_table->none)) {					TRACE_ERROR					    ("illegal value \"%s\" - expected "					 "\"KRB5\" or "					 "\"SPKM1\" or \"SPKM2\" or \"SRP\" or "					     "\"CHAP\" or \"%s\"\n", value,					     key_table->none);					p->neg_info |= KEY_BAD;					break;				}			} else if (IS_DISCOVERY_NORMAL(p->type)) {				if (strcmp(value, key_table->discovery)				    && strcmp(value, key_table->normal)) {					TRACE_ERROR					    ("illegal value \"%s\" - expected "					     "\"%s\" or \"%s\"\n", value,					     key_table->discovery,					     key_table->normal);					p->neg_info |= KEY_BAD;					break;				}			}		}		else if (IS_NUMBER_RANGE(p->type)			 && !IS_KEY_SENT_TO_OTHER_SIDE(p->neg_info)) {			/* is an offer of a numeric range */			if ((*int_value = check_range(value, -1)) < 0			    || !check_bounds(p, *int_value, who_called)) {				p->neg_info |= KEY_BAD;				break;			}		}

⌨️ 快捷键说明

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