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

📄 msgparser.c

📁 mobile ip 在linux下的一种实现
💻 C
📖 第 1 页 / 共 2 页
字号:
		(struct generalized_fa_fa_key_rep_ext *) *msg_pos;	switch (key->subtype) {	default:		DEBUG(DEBUG_FLAG, "Unknown generalized FA-FA key reply "		      "extension subtype\n");		print_gen_key_spi("FA_FA_KEY_REP(unknown)", "FA-FA", key);		return -1;	}	*msg_pos += GET_GEN_FA_FA_KEY_REP_EXT_LEN(key);	return 0;}/* handle Normal Vendor/Organization Specific Extension */static int handle_vendor_ext(char **msg_pos, struct msg_extensions *ext){	struct vendor_ext_header *vendor_head;	unsigned char *c;	int vendor_id, subtype;	vendor_head = (struct vendor_ext_header *) *msg_pos;	/* at least Sparc doesn't seem to like non-aligned data reading	 * so this hack is needed to avoid a possible Bus error.	 * The data is in network byte order, so make sure it converted to	 * host byte order here. */	c = (unsigned char *) &vendor_head->vendor_id;	vendor_id = (*c << 24) + (*(c+1) << 16) + (*(c+2) << 8) + *(c+3);	if (vendor_id == VENDOR_ID_DYNAMICS) {		c = (unsigned char *) &vendor_head->sub_type;		subtype = (*c << 8) + *(c+1);		switch (subtype) {		case VENDOR_EXT_DYNAMICS_OPTIONS:			ext->ext_dyn = (struct registration_ext_dynamics *)				vendor_head;			DEBUG(DEBUG_FLAG, "\tdyn_options: type %i, length %i, "			      "vendor_id %i, sub_type %i, version %i,\n"			      "\t\topts %i, seq %u\n",			      ext->ext_dyn->type, ext->ext_dyn->length,			      vendor_id, subtype,			      ext->ext_dyn->version,			      ext->ext_dyn->opts,			      (u32) ntohl(ext->ext_dyn->seq));			*msg_pos += vendor_head->length + 2;			break;		case VENDOR_EXT_DYNAMICS_FA_KEYREQ:			if (get_key_ext(&ext->fa_keyreq, "fa_keyreq",					msg_pos) != 0)				return -2;			break;		case VENDOR_EXT_DYNAMICS_FA_PUBKEY:			if (get_key_ext(&ext->fa_pubkey, "fa_pubkey",					msg_pos) != 0)				return -2;			break;		case VENDOR_EXT_DYNAMICS_MN_KEYREQ:			if (get_key_ext(&ext->mn_keyreq, "mn_keyreq",					msg_pos) != 0)				return -2;			break;		case VENDOR_EXT_DYNAMICS_MN_KEYREP:			if (get_key_ext(&ext->mn_keyrep, "mn_keyrep",					msg_pos) != 0)				return -2;			break;		case VENDOR_EXT_DYNAMICS_FA_KEYREP:			if (get_key_ext(&ext->fa_keyrep, "fa_keyrep",					msg_pos) != 0)				return -2;			break;		case VENDOR_EXT_DYNAMICS_FA_PUBKEYREP:			if (get_key_ext(&ext->fa_pubkeyrep, "fa_pubkeyrep",					msg_pos) != 0)				return -2;			break;		case VENDOR_EXT_DYNAMICS_PUBKEY_HASH:			if (get_key_ext(&ext->pubkey_hash, "pubkey_hash",					msg_pos) != 0)				return -2;			break;		case VENDOR_EXT_DYNAMICS_FF_AUTH:			if (ext->ff_auth) {				ext->double_auth_ext |= DOUBLE_FF_AUTH;				DEBUG(DEBUG_FLAG, "double FF_AUTH\n");			}			ext->ff_auth = (struct vendor_msg_auth *) *msg_pos;			print_msg_auth_vendor(ext->ff_auth, "ff_auth");			*msg_pos += GET_VENDOR_AUTH_EXT_LEN(ext->ff_auth);			break;		case VENDOR_EXT_DYNAMICS_SK_AUTH:			if (ext->sk_auth) {				ext->double_auth_ext |= DOUBLE_SK_AUTH;				DEBUG(DEBUG_FLAG, "double SK_AUTH\n");				return -2;			}			ext->sk_auth = (struct vendor_msg_auth *) *msg_pos;			print_msg_auth_vendor(ext->sk_auth, "sk_auth");			*msg_pos += GET_VENDOR_AUTH_EXT_LEN(ext->sk_auth);			break;		case VENDOR_EXT_DYNAMICS_SHA_HA_AUTH:			if (ext->sha_ha_auth) {				ext->double_auth_ext |= DOUBLE_SHA_HA_AUTH;				DEBUG(DEBUG_FLAG, "double SHA_HA_AUTH\n");				return -2;			}			ext->sha_ha_auth = (struct vendor_msg_auth *) *msg_pos;			print_msg_auth_vendor(ext->sha_ha_auth, "sha_ha_auth");			*msg_pos += GET_VENDOR_AUTH_EXT_LEN(ext->sha_ha_auth);			break;		case VENDOR_EXT_DYNAMICS_FA_NAI:			if (ext->fa_nai) {				DEBUG(DEBUG_FLAG, "double FA_NAI\n");				return -2;			}			ext->fa_nai = (struct fa_nai_ext *) *msg_pos;			print_nai_ext(ext->fa_nai, "fa_nai");			*msg_pos += GET_NAI_EXT_LEN(ext->fa_nai);			break;		case VENDOR_EXT_DYNAMICS_PREVIOUS_FA_NAI:			if (ext->prev_fa_nai) {				DEBUG(DEBUG_FLAG, "double PREV_FA_NAI\n");				return -2;			}			ext->prev_fa_nai = (struct fa_nai_ext *) *msg_pos;			print_nai_ext(ext->prev_fa_nai, "prev_fa_nai");			*msg_pos += GET_NAI_EXT_LEN(ext->prev_fa_nai);			break;		case VENDOR_EXT_DYNAMICS_GRE_KEY:			if (ext->gre_key) {				DEBUG(DEBUG_FLAG, "double GRE_KEY\n");				return -2;			}			ext->gre_key = (struct gre_key_ext *) *msg_pos;			print_gre_key(ext->gre_key);			*msg_pos += GET_GRE_KEY_EXT_LEN(ext->gre_key);			break;		case VENDOR_EXT_DYNAMICS_SFA_DEBUG:			if (ext->sfa_debug) {				DEBUG(DEBUG_FLAG, "double SFA_DEBUG\n");				return -2;			}			ext->sfa_debug = (struct sfa_debug_ext *) *msg_pos;			print_sfa_debug(ext->sfa_debug);			*msg_pos += GET_SFA_DEBUG_EXT_LEN(ext->sfa_debug);			break;		case VENDOR_EXT_DYNAMICS_PRIV_HA:			if (ext->priv_ha) {				DEBUG(DEBUG_FLAG, "double PRIV_HA\n");				return -2;			}			ext->priv_ha = (struct priv_ha_ext *) *msg_pos;			print_priv_ha(ext->priv_ha);			*msg_pos += GET_PRIV_HA_EXT_LEN(ext->priv_ha);			break;		case VENDOR_EXT_DYNAMICS_NONCE:			if (ext->nonce) {				DEBUG(DEBUG_FLAG, "double nonce\n");				return -2;			}			ext->nonce = (struct nonce_ext *) *msg_pos;			print_nonce(ext->nonce);			*msg_pos += GET_NONCE_EXT_LEN(ext->nonce);			break;		default:			DEBUG(DEBUG_FLAG, "Unknown Dynamics "			      "extension subtype %i\n", subtype);			*msg_pos += vendor_head->length + 2;		}	} else {		DEBUG(DEBUG_FLAG, "Unknown vendor ID %i - "		      "ignoring extension\n", vendor_id);		*msg_pos += vendor_head->length + 2;	}	return 0;}/** * parse_msg: * @msg_start: pointer to the start of the message data * @len: length of the message * @ext: pointer to a memory area that will be filled with pointers to parsed * extensions. Extensions that were not present have pointers set to NULL. * * Parses a received Mobile IP registration request or reply. Note that the * message data is not copied and @ext contains pointers to the original data, * i.e., the original data area must not be modified or freed as long as the * message extensions are used. * * Returns: *    0 success, *   -1 an unindentified extension is present, *   -2 the message is malformed, *   -3 a request contains an unknown/unsupported vendor ID in Critical *	Vendor/Organization Specific Extension (CVSE) before MN-HA auth *   -4 a request contains an unknown/unsupported vendor ID in CVSE *	after MN-HA auth *   -5 a reply contains an unknown/unsupport vendor ID in CVSE */int parse_msg(char *msg_start, int len, struct msg_extensions *ext){	char *msg_pos = msg_start;	struct msg_auth *auth;	unsigned char ext_type, ext_len;	int ret;	assert(msg_start && ext);	if (len < 1) {	       DEBUG(DEBUG_FLAG, "parse_msg: too short message\n");	       return -2;	}	memset(ext, 0, sizeof(struct msg_extensions));	ext->start = msg_start;	ext->len = len;	switch ((unsigned char) msg_pos[0]) {	case REG_REQ:		ext->req = (struct reg_req *)msg_pos;		print_reg_req(ext->req);		msg_pos += sizeof(struct reg_req);		break;	case REG_REP:		ext->rep = (struct reg_rep *)msg_pos;		print_reg_rep(ext->rep);		msg_pos += sizeof(struct reg_rep);		break;	case FA_REQ:		ext->fa_req = (struct fa_reg_req *)msg_pos;		print_fa_reg_req(ext->fa_req);		msg_pos += sizeof(struct fa_reg_req);		break;	case FA_REP:		ext->fa_rep = (struct fa_reg_rep *)msg_pos;		print_fa_reg_rep(ext->fa_rep);		msg_pos += sizeof(struct fa_reg_rep);		break;	default:		DEBUG(DEBUG_FLAG, "parse_msg: unknown message type %i\n",		      (unsigned char) msg_pos[0]);		return -2;	}	while (msg_pos < msg_start + len) {		unsigned int extlen;		switch ((unsigned char) msg_pos[0]) {		case ONE_BYTE_PADDING:			extlen = 1;			break;		case GENERALIZED_AUTH_EXT:		case GENERALIZED_MN_FA_KEY_REQ_EXT:		case GENERALIZED_MN_FA_KEY_REP_EXT:		case GENERALIZED_MN_HA_KEY_REQ_EXT:		case GENERALIZED_MN_HA_KEY_REP_EXT:		case GENERALIZED_FA_HA_KEY_REP_EXT:		case GENERALIZED_FA_FA_KEY_REP_EXT:			if (msg_pos + 3 >= msg_start + len) {				DEBUG(DEBUG_FLAG, "parse_msg: gen. auth. ext "				      "too short\n");				return -2;			}			extlen = ((unsigned char) msg_pos[2] << 8) +				(unsigned char) msg_pos[3];			break;		default:			if (msg_pos + 1 >= msg_start + len) {				DEBUG(DEBUG_FLAG, "parse_msg: ext too "				      "short\n");				return -2;			}			extlen = (unsigned char) msg_pos[1];		}		if (msg_pos + extlen > msg_start + len) {			char *c;			DEBUG(DEBUG_FLAG, "parse_msg: message too short for "			      "current extension (extlen=%i, over=%i)\n",			      extlen, msg_pos + extlen - msg_start - len);			DEBUG(DEBUG_FLAG, "dump:");			c = msg_pos;			while (c < msg_start + len) {				DEBUG(DEBUG_FLAG, " %02X",				      (unsigned char) *c++);			}			DEBUG(DEBUG_FLAG, "\n");			return -2;		}		switch ((unsigned char)msg_pos[0]) {		case MH_AUTH:		case MF_AUTH:		case FH_AUTH:			auth = (struct msg_auth *)msg_pos;			if (auth->length < SPI_LEN) {				DEBUG(DEBUG_FLAG,				      "parse_msg: AUTH too short\n");				return -2;			}			break;		}		switch ((unsigned char)msg_pos[0]) {		case ONE_BYTE_PADDING:			msg_pos++;			break;		case MH_AUTH:			if (ext->mh_auth) {				DEBUG(DEBUG_FLAG,				      "parse_msg: double MH_AUTH\n");				ext->double_auth_ext |= DOUBLE_MH_AUTH;			}			ext->mh_auth = (struct msg_auth *)msg_pos;			print_msg_auth(ext->mh_auth, "mh_auth");			msg_pos += GET_AUTH_EXT_LEN(ext->mh_auth);			break;		case MF_AUTH:			if (ext->mf_auth) {				DEBUG(DEBUG_FLAG,				      "parse_msg: double MF_AUTH\n");				ext->double_auth_ext |= DOUBLE_MF_AUTH;			}			ext->mf_auth = (struct msg_auth *)msg_pos;			print_msg_auth(ext->mf_auth, "mf_auth");			msg_pos += GET_AUTH_EXT_LEN(ext->mf_auth);			break;		case FH_AUTH:			if (ext->fh_auth) {				DEBUG(DEBUG_FLAG,				      "parse_msg: double FH_AUTH\n");				ext->double_auth_ext |= DOUBLE_FH_AUTH;			}			ext->fh_auth = (struct msg_auth *)msg_pos;			print_msg_auth(ext->fh_auth, "fh_auth");			msg_pos += GET_AUTH_EXT_LEN(ext->fh_auth);			break;		case GENERALIZED_AUTH_EXT:			ret = handle_gen_auth_ext(&msg_pos, ext);			if (ret != 0)				return ret;			break;		case GENERALIZED_MN_FA_KEY_REQ_EXT:			ret = handle_gen_mn_fa_key_req_ext(&msg_pos, ext);			if (ret != 0)				return ret;			break;		case GENERALIZED_MN_FA_KEY_REP_EXT:			ret = handle_gen_mn_fa_key_rep_ext(&msg_pos, ext);			if (ret != 0)				return ret;			break;		case GENERALIZED_MN_HA_KEY_REQ_EXT:			ret = handle_gen_mn_ha_key_req_ext(&msg_pos, ext);			if (ret != 0)				return ret;			break;		case GENERALIZED_MN_HA_KEY_REP_EXT:			ret = handle_gen_mn_ha_key_rep_ext(&msg_pos, ext);			if (ret != 0)				return ret;			break;		case GENERALIZED_FA_HA_KEY_REP_EXT:			ret = handle_gen_fa_ha_key_rep_ext(&msg_pos, ext);			if (ret != 0)				return ret;			break;		case GENERALIZED_FA_FA_KEY_REP_EXT:			ret = handle_gen_fa_fa_key_rep_ext(&msg_pos, ext);			if (ret != 0)				return ret;			break;		case MN_NAI_EXT:			if (ext->mn_nai) {				DEBUG(DEBUG_FLAG, "double MN_NAI_EXT\n");				print_mn_nai((struct mn_nai_ext *) msg_pos);				return -2;			}			ext->mn_nai = (struct mn_nai_ext *) msg_pos;			print_mn_nai(ext->mn_nai);			msg_pos += GET_MN_NAI_EXT_LEN(ext->mn_nai);			break;		case MN_FA_CHALLENGE_EXT:			if (ext->challenge) {				DEBUG(DEBUG_FLAG,				      "double MN_FA_CHALLENGE_EXT\n");				print_challenge((struct challenge_ext *)						msg_pos);				return -2;			}			ext->challenge = (struct challenge_ext *) msg_pos;			print_challenge(ext->challenge);			msg_pos += GET_CHALLENGE_EXT_LEN(ext->challenge);			break;		case ENCAPS_DELIVERY_EXT:			ext->encaps_del =				(struct encaps_delivery_ext *) msg_pos;			if (!ext->req || ext->encaps_del->length != 0) {				DEBUG(DEBUG_FLAG,				      "parse_msg: ENCAPS_DELIVERY\n");				return -2;			}			DEBUG(DEBUG_FLAG, "\tencaps_delivery\n");			msg_pos += 2 + ext->encaps_del->length;			break;		case VENDOR_EXT_TYPE1:			DEBUG(DEBUG_FLAG, "\tunknown CVSE\n");			ext->unknown_cvse = 1;			if (ext->req) {				if (ext->mh_auth)					return -4;				else					return -3;			}			return -5;		case VENDOR_EXT_TYPE2:			if (handle_vendor_ext(&msg_pos, ext) != 0)				return -2;			break;		default:			ext_type = (unsigned char) msg_pos[0];			ext_len = (unsigned char) msg_pos[1];			DEBUG(DEBUG_FLAG,			      "Unknown extension type %i, len %i - ",			      (unsigned char) ext_type, ext_len);			/* RFC2002, section 1.9:			 * unknown 0..127 ==> discard message			 * unknown 128..255 ==> ignore extension but process			 *                      the rest of the message */			if (ext_type < 128) {				DEBUG(DEBUG_FLAG, "discarding message\n");				return -1;			} else {				DEBUG(DEBUG_FLAG, "ignoring extension\n");				msg_pos += ext_len + 2;				break;			}		}	}	/* check that the extensions have not been too long */	if (msg_pos > msg_start + len) {		DEBUG(DEBUG_FLAG, "parse_msg: too long extensions\n");		return -2;	}	return 0;}

⌨️ 快捷键说明

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