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

📄 text_param.c

📁 iscsi源代码 UNH的progect 有initiator端和target端的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	struct parameter_type *FBp = NULL, *MBp = NULL;	TRACE(TRACE_ENTER_LEAVE, "Enter scan_input_and_process\n");	ALLOCATE_MAX_TEXT_LEN(dummy_string);	ALLOCATE_MAX_TEXT_LEN(input_str);	output_string = outputpdu->text + outputpdu->text_length;	/* Copy the input text to a local buffer */	memcpy(input_str, inputpdu->text, inputpdu->text_length);	input_string = input_str;	/* point at first char */	last_input = input_str + inputpdu->text_length;	/* point beyond 								last char */	*last_input = '\0';	/* ensure '\0' at end of last */	while (input_string < last_input) {		key_value_len = strlen(input_string);		TRACE(TRACE_DEBUG, "key_value_len = %d\n", key_value_len);		TRACE(TRACE_DEBUG, "FBLength %x MBLength %x\n",				FBLength,MBLength);		/* assume no reply will be sent */		resp_len = 0;		value = NULL;		int_value = -1;		if ((p = check_correctness(input_string, &value, p_param_tbl,					   role, when_called, flags, &int_value,					   unknown_key_list)) == NULL) {			/* We don't understand the request. */			if (value == NULL) {	/* Error is fatal */				out_length = -1;				goto out;			}			if (!((process_these_types & SECURITY_PARAM))			    || (!is_securitykey(input_string))) {				resp_len = sprintf(dummy_string,						   "%s=%s", input_string,						   value);			}		} else if (IS_KEY_BAD(p->neg_info)) {			out_length = -1;			goto out;		} else if (!IS_KEY_IRRELEVANT(p->neg_info)) {			/* p is the pointer to the table entry for the 			 * received parameter and value points to the 			 * string following the "=" in the input 			 */			TRACE(TRACE_DEBUG,			      "Process input param: %s, value: %s\n",			      p->parameter_name, value);			/* check if this is a Full Feature Only key */			if (IS_FULL_FEATURE_ONLY(p->type)) {					/* protocol error */				TRACE_ERROR				    ("%p only valid in full feature phase\n",				     p->parameter_name);				out_length = -1;				goto out;			}			if (p->special_key_flag & flags_to_be_set) {				/* caller wants to know that this key 				 * was processed				 */				*login_flags |= p->special_key_flag;				if (p->special_key_flag & SESSIONTYPE_FLAG) {					/* set the DISCOVERY_FLAG when 					 * get SessionType=Discovery					 */					if (!strcmp					    (value, key_table->discovery)) {						*login_flags |= DISCOVERY_FLAG;					}				}			}			if ((p->type & process_these_types)) {				/* handle key enquiry by replying with 					our current value */				if (!strcmp(value, "?")) {					/* inquiry no longer accepted in 						draft 11 and after */					TRACE_ERROR					    ("inquiry no longer accepted "					     "param: %s, value: %s\n",					     p->parameter_name, value);					resp_len =					    sprintf(dummy_string, "%s=%s",						    p->parameter_name,						    key_table->reject);					/* do not consider this param as 						"gotten from other side" */					p = NULL;				} else if (p->str_value					   && !strcmp(p->str_value, "?")) {					/* we sent an inquiry and this is 					 * the response 					 * Note this should never happen 					 * for draft 11 and after 					 */					printk					    ("iscsi response to inquiry: %s=%s\n",					     p->parameter_name, value);				} else {					/* neither an inquiry or a reply to 					 * an inquiry .					 * First convert boolean to yes or 					 * no result 					 */					if (IS_BOOLEAN(p->type)) {						handle_boolean_param(p, &value);					}					if (p->special_key_flag &					    MAXRECVDATASEGMENTLENGTH_FLAG) {						/* this is 						 * MaxRecvDataSegmentLength 						 * that other side wants to 						 * receive, i.e., the max 						 * size PDU we should send. 						 * No reply is necessary for 						 * this key.						 */						if (int_value < 512						    || int_value > 16777215) {							if (TRACE_TEST								(TRACE_ISCSI)) {							    TRACE_WARNING							    ("%s %d out of "							    "bounds "							    "[512..16777215]\n",							    p->parameter_name,							    int_value);							}						} else {							/* value is within 							 * bounds, pass it back							 * to caller after 							 * forcing it to be a 							 * multiple of 512 							 */							int_value /= 512;							*max_send_length =							    512 * int_value;						}					} else					    if (!IS_KEY_SENT_TO_OTHER_SIDE						(p->neg_info)) {						handle_params_noexch(p,								p_param_tbl,								flags,								int_value,								value,								dummy_string,								&resp_len,								&FBLength ,								&FBp,								&MBLength,								&MBp);					} else {						if (handle_params_resp(p,							value,							int_value,							&out_length) < 0 ){							TRACE_ERROR					    	("handle_params_resp !\n");								goto out;						}					}				}			} else {				if (IS_SECURITY_PARAM(p->type)) {					TRACE_ERROR					    ("not in security phase when "					      " received input "					     "param: %s, value: %s\n",					     p->parameter_name, value);					out_length = -1;					goto out;				} else if (IS_OPERATIONAL_PARAM(p->type)) {					TRACE_ERROR					    ("not in operational phase when "					    	" received input "					     "param: %s, value: %s\n",					     p->parameter_name, value);					out_length = -1;					goto out;				} else if (IS_INFORMATIONAL_PARAM(p->type)) {					TRACE_ERROR					    ("not processing informational "					      " parameters when "					     "recv input param: %s,value: %s\n",					     p->parameter_name, value);					out_length = -1;					goto out;				} else {					TRACE_ERROR					    ("recv unclassied input param: %s, "					     "value: %s\n", p->parameter_name,					     value);					out_length = -1;					goto out;				}			}		}		/* Always check if the response length exceeds MAX_TEXT_LEN */		/* Then the remaining parameters have to be sent in a     */		/* separate text command/response */		TRACE(TRACE_DEBUG, "resp_len = %d\n", resp_len);		if (resp_len) {			if (check_out_length(out_length, resp_len)) {				*login_flags |= MORE_TO_SEND_FLAG;				break;			} else {				/* Update resp_len and the pointer 					to output_string */				sprintf(output_string, "%s", dummy_string);				output_string += resp_len + 1;				TRACE(TRACE_ISCSI, "Attach key: %s\n",				      dummy_string);				/* update out_length */				out_length += resp_len + 1;				if (p) {	/* set sent-to-other-side bit */					p->neg_info |= KEY_SENT_TO_OTHER_SIDE;				}				resp_len = 0;			}		}		if (p) {	/* set got-from-other-side bit */			p->neg_info |= KEY_GOT_FROM_OTHER_SIDE;		}		/* Goto the next key=value pair */		this_key = input_string;	/* remember where this 			key started */		/* this should be start of next key */		input_string += key_value_len + 1;		/*  In Drafts 9 and before, Section 3.10.4 Text		 *  "Every key=value pair (including the last or only pair) MUST		 *  be followed by at least one null (0x00) delimiter."		 * 		 *  This implied there could be more than one null (0x00) at the		 *  end of a string, so skip over these extra nulls now		 */		while (*input_string == '\0' && input_string < last_input) {			input_string++;		}		/*  In final Draft 20, Section 5.1 Text Format		 *  "Every key=value pair, including the last or only 		 *   pair in a LTDS,  MUST be followed by one null (0x00) 		 *  delimiter."		 * 		 *  This implies that there can NOT be more than one 		 *  null (0x00) at the		 *  end of a string, so if there were extra nulls, 		 *  give a warning now.		 */		n = (input_string - this_key) - (key_value_len + 1);		if (n > 0) {			if (TRACE_TEST(TRACE_ISCSI)) {			      TRACE_WARNING("%d extra nulls (0x00) found after"						" key \"%s\"\n", n, this_key);			}		}	}	/* process FirstBurstLength and MaxBurstLength if their 		reply was delayed */	TRACE(TRACE_DEBUG, "FBLength %x MBLength %x\n",FBLength,MBLength);	if (FBLength > 0 && MBLength > 0) {		/* both keys were offered by other side in this pdu */		if (FBLength <= MBLength) {			/* ok */			/* MaxBurstLength is bigger than 				FirstBurstLength, all ok */		} else {			/* FirstBurstLength bigger than MaxBurstLength, 				fix it */			FBp->int_value = FBLength = MBLength;			TRACE (TRACE_DEBUG, "Updated FBp %p\n",FBp);		}	} else if (FBLength > 0) {		/* only FirstBurstLength was received in this pdu */		if ((MBp =		     find_flag_parameter(MAXBURSTLENGTH_FLAG,					 p_param_tbl)) != NULL) {			if (FBLength > MBp->int_value) {				/* The received FirstBurstLength is 					bigger than our current				   MaxBurstLength */				if (IS_KEY_SENT_TO_OTHER_SIDE(MBp->neg_info)) {					/* MaxBurstLength already sent, 						can't be fixed */					TRACE_ERROR					    ("FirstBurstLength %d bigger "					    " than negotiated "					     "MaxBurstLength %d", FBLength,					     MBp->int_value);					out_length = -1;					goto out;				}				/* The unsent MaxBurstLength is smaller 				 * than the received FirstBurstLength, 				 * reduce the FirstBurstLength to the				 * MaxBurstLength and send both 				 */				FBLength = FBp->int_value = MBLength =				    MBp->int_value;				TRACE (TRACE_DEBUG, "Updated FBLength %u\n",					FBLength);			} else {				/* The received FirstBurstLength not 				 * bigger than our current				 * MaxBurstLength, send MaxBurstLength only if 				 * negotiation needed. 				 */				if ((IS_KEY_TO_BE_NEGOTIATED(MBp->neg_info)				     || IS_KEY_GOT_FROM_OTHER_SIDE(MBp->								   neg_info))				    && !IS_KEY_SENT_TO_OTHER_SIDE(MBp->								  neg_info)) {					MBLength = MBp->int_value;				}			}		}	} else if (MBLength > 0) {		/* only MaxBurstLength was received in this pdu */		if ((FBp = find_flag_parameter(FIRSTBURSTLENGTH_FLAG,					       p_param_tbl)) != NULL) {			/* must have MaxBurstLength > FirstBurstLength */			if (MBLength < FBp->int_value) {				/* MaxBurstLength is smaller than 					FirstBurstLength */				if (IS_KEY_SENT_TO_OTHER_SIDE(FBp->neg_info)) {					/* FirstBurstLength already sent, 						can't be fixed */					TRACE_ERROR					    ("MaxBurstLength %d smaller than "					      " negotiated "					     "FirstBurstLength %d", MBLength,					     FBp->int_value);					out_length = -1;					goto out;				}				/* FirstBurstLength has not been sent yet,				 *  so force it to be equal to 				 * MaxBurstLength and offer it now 				 */				FBLength = FBp->int_value = MBLength;				TRACE (TRACE_DEBUG, "Updated FBLength %u\n",						FBLength);			} else {				/* MaxBurstLength not smaller than 				 * FirstBurstLength, send				 * FirstBurstLength only if it still needs 				 * to be negotiated 				 */				if ((IS_KEY_TO_BE_NEGOTIATED(FBp->neg_info)				     || IS_KEY_GOT_FROM_OTHER_SIDE(FBp->								   neg_info))				    && !IS_KEY_SENT_TO_OTHER_SIDE(FBp->								  neg_info)) {					FBLength = FBp->int_value;				}			}		}	}	if (FBLength > 0) {		/* reply to or offer the FirstBurstLength */		TRACE(TRACE_DEBUG, "FBLength %x FBp %p\n",FBLength,FBp);		FBp->neg_info |= KEY_SENT_TO_OTHER_SIDE;		if (!IS_KEY_GOT_FROM_OTHER_SIDE(FBp->neg_info))			outputpdu->flags &= (~T_BIT);		resp_len =		    sprintf(dummy_string, "%s=%d", FIRSTBURSTLENGTH, FBLength);		sprintf(output_string, "%s", dummy_string);		output_string += resp_len + 1;		TRACE(TRACE_ISCSI, "Attach key, %s\n", dummy_string);		/* update out_length */		out_length += resp_len + 1;		resp_len = 0;		FBLength = -1;	}	if (MBLength > 0) {		/* reply to or offer the MaxBurstLength */		TRACE(TRACE_DEBUG, "MBLength %x MBp %p\n",MBLength,MBp);		MBp->neg_info |= KEY_SENT_TO_OTHER_SIDE;		if (!IS_KEY_GOT_FROM_OTHER_SIDE(MBp->neg_info))			outputpdu->flags &= (~T_BIT);		resp_len =		    sprintf(dummy_string, "%s=%d", MAXBURSTLENGTH, MBLength);		sprintf(output_string, "%s", dummy_string);		output_string += resp_len + 1;		TRACE(TRACE_ISCSI, "Attach key, %s\n", dummy_string);		/* update out_length */		out_length += resp_len + 1;		MBLength = -1;	}      out:	FREE_STRING(dummy_string);	FREE_STRING(input_str);	TRACE(TRACE_ENTER_LEAVE,	      "Leave scan_input_and_process, out_length %d\n", out_length);	/* return the length added to the output_string */	return out_length;}/* * Populates "value" with the approprite return value * that we expect back from the other end. */static void __attribute__ ((no_instrument_function))handle_boolean_param(struct parameter_type *p, char **value){	int receiver_value;	int sender_value;	TRACE(TRACE_ENTER_LEAVE, "Enter handle_boolean_param %s=%s\n",		p->parameter_name, *value);	if (!strcmp(*value, key_table->yes))		sender_value = 1;	else		sender_value = 0;	if (!strcmp(p->str_value, key_table->yes))		receiver_value = 1;	else		receiver_value = 0;	if (IS_BOOL_AND(p->type)) {		/* Boolean AND function */		if (sender_value & receiver_value) {			/* both sides said YES so result is YES */			*value = key_table->yes;		} else {			/* either (or both) of the sides said NO */			*value = key_table->no;			if (sender_value == 0) {				/* sender sent NO, so reply is optional				 *				 *  Draft 20, Section 5.2.2 Simple-value				 *  Negotiations				 *  "Specifically, the two cases in 				 *  which answers are OPTIONAL are:				 *				 *  - The boolean functi

⌨️ 快捷键说明

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