示例#1
0
int
tags_equal(fru_tag_t t1, fru_tag_t t2)
{
	return ((get_tag_type(&t1) == get_tag_type(&t2)) &&
	    (get_tag_dense(&t1) == get_tag_dense(&t2)) &&
	    (get_payload_length(&t1) == get_payload_length(&t2)));
}
示例#2
0
const fru_regdef_t *
fru_reg_lookup_def_by_tag(fru_tag_t tag)
{
	fru_regdef_t *ret_def = NULL;
	int i = 0;
	for (i = 0; i < max_data_element_count; i++) {
		ret_def = &(Element_Defs[i]);
		if (ret_def->tagType == get_tag_type(&tag) &&
			ret_def->tagDense == get_tag_dense(&tag) &&
			ret_def->payloadLen == get_payload_length(&tag)) {
			return (ret_def);
		}
	}
	return (NULL);
}
示例#3
0
static int
ikev2_process_cfg_request_attribs(struct ikev2_sa *ike_sa,
				  struct ikev2_child_sa *child_sa,
				  struct ikev2payl_config *cfg,
				  struct ikev2_child_param *param)
{
	struct ikev2cfg_attrib *attr;
	size_t bytes;
	int attr_type;
	unsigned int attr_len;
	int ip4_address = 0;
	int ip6_address = 0;
	int af;
	size_t addrsize;
	uint8_t *addrbits;
	struct rcf_address *addr;
	int address_fail = 0;
	int address_success = 0;
#ifdef DEBUG_TRACE
	char addrstr[INET6_ADDRSTRLEN];
#endif

	for (bytes = get_payload_length(cfg) - sizeof(*cfg),
		 attr = (struct ikev2cfg_attrib *)(cfg + 1);
	     bytes > 0;
	     bytes -= IKEV2CFG_ATTR_TOTALLENGTH(attr),
		 attr = IKEV2CFG_ATTR_NEXT(attr)) {
		attr_type = IKEV2CFG_ATTR_TYPE(attr);
		attr_len = IKEV2CFG_ATTR_LENGTH(attr);
		TRACE((PLOGLOC, "attribute type %d length %d\n",
		       attr_type, attr_len));
		assert(bytes >= sizeof(struct ikev2cfg_attrib));

		switch (attr_type) {
		case IKEV2_CFG_INTERNAL_IP4_ADDRESS:
			TRACE((PLOGLOC, "INTERNAL_IP4_ADDRESS\n"));
			if (++ip4_address > ike_max_ip4_alloc(ike_sa->rmconf)) {
				TRACE((PLOGLOC,
				       "INTERNAL_IP4_ADDRESS request exceeds allocation limit (%d)\n",
				       ike_max_ip4_alloc(ike_sa->rmconf)));
				++address_fail;
				break;
			}

			af = AF_INET;
			addrsize = sizeof(struct in_addr);
			addrbits = (uint8_t *)(attr + 1);
			if (attr_len != 0 && attr_len < addrsize) {
				TRACE((PLOGLOC,
				       "bogus attribute length %d, ignoring content\n",
				       attr_len));
				goto alloc_addr;
			}

			if (attr_len == 0 ||
			    get_uint32((uint32_t *)addrbits) == INADDR_ANY)
				goto alloc_addr;

		    try_assign:
			TRACE((PLOGLOC, "trying peer-specified address %s\n",
			       inet_ntop(af, addrbits, addrstr, sizeof(addrstr))));
			addr = rc_addrpool_assign(ikev2_addresspool(ike_sa->rmconf),
					       af, addrbits);
			if (addr) {
				TRACE((PLOGLOC, "OK.\n"));
				goto alloc_success;
			}

			TRACE((PLOGLOC, "failed, trying to allocate different address\n"));
			/* go on */
		    alloc_addr:
			addr = rc_addrpool_alloc_any(ikev2_addresspool(ike_sa->rmconf), af);
			if (!addr) {
				TRACE((PLOGLOC, "no address available for lease\n"));
				++address_fail;
				break;
			}

			TRACE((PLOGLOC, "allocated %s\n",
			       inet_ntop(af, addr->address, addrstr, sizeof(addrstr))));
		    alloc_success:
			++address_success;
			LIST_INSERT_HEAD(&child_sa->lease_list, addr, link_sa);
			break;

		case IKEV2_CFG_INTERNAL_IP6_ADDRESS:
			if (++ip6_address > ike_max_ip6_alloc(ike_sa->rmconf)) {
				TRACE((PLOGLOC,
				       "INTERNAL_IP6_ADDRESS request exceeds allocation limit (%d)\n",
				       ike_max_ip6_alloc(ike_sa->rmconf)));
				++address_fail;
				break;
			}
			af = AF_INET6;
			addrsize = sizeof(struct in6_addr);
			addrbits = (uint8_t *)(attr + 1);

			if (attr_len != 0 &&
			    attr_len < sizeof(struct ikev2cfg_ip6addr)) {
				TRACE((PLOGLOC,
				       "bogus attribute length %d, ignoring content\n",
				       attr_len));
				goto alloc_addr;
			}

			/* :: */
			if (attr_len == 0 ||
			    IN6_IS_ADDR_UNSPECIFIED((struct in6_addr *)addrbits))
				goto alloc_addr;

			/* ::xxxx:yyyy:zzzz:qqqq/64 */
			/* XXX not sure about prefix, ignore for now */
			if (/* ((struct ikev2cfg_ip6addr *)(attr + 1))->prefixlen == 64 && */
			    memcmp(addrbits, &in6addr_any, 64/8) == 0) {
				TRACE((PLOGLOC,
				       "peer-specified interface identifier %s/%d\n",
				       inet_ntop(af, addrbits, addrstr, sizeof(addrstr)),
				       64));
				addr = rc_addrpool_assign_ip6intf(ikev2_addresspool(ike_sa->rmconf), addrbits);
				if (addr)
					goto alloc_success;

				TRACE((PLOGLOC, "assign failed\n"));
			}

			/* aaaa:bbbb:cccc:dddd:eeee:ffff:gggg:hhhh/64 */
			/* XXX again, prefix ignored */
			if (!IN6_IS_ADDR_UNSPECIFIED((struct in6_addr *)addrbits))
				goto try_assign;

			goto alloc_addr;

		case IKEV2_CFG_APPLICATION_VERSION:
			++param->cfg_application_version;
			break;
		case IKEV2_CFG_INTERNAL_IP4_DNS:
			++param->cfg_ip4_dns;
			break;
		case IKEV2_CFG_INTERNAL_IP6_DNS:
			++param->cfg_ip6_dns;
			break;
		case IKEV2_CFG_INTERNAL_IP4_DHCP:
			++param->cfg_ip4_dhcp;
			break;
		case IKEV2_CFG_INTERNAL_IP6_DHCP:
			++param->cfg_ip6_dhcp;
			break;
		case IKEV2_CFG_SUPPORTED_ATTRIBUTES:
			++param->cfg_supported_attributes;
			break;
		case IKEV2_CFG_MIP6_HOME_PREFIX:
			++param->cfg_mip6_home_prefix;
			break;
		default:
			TRACE((PLOGLOC, "ignored\n"));
			break;
		}
	}
	if (address_fail > 0 && address_success == 0)
		return IKEV2_INTERNAL_ADDRESS_FAILURE;
	return 0;
}
示例#4
0
static fru_errno_t
frt_for_each_packet(fru_seghdl_t node,
    int (*function)(fru_tag_t *tag, uint8_t *payload, size_t length,
	void *args), void *args)
{
	int rc_num;
	int status;
	char *rc_tags;
	char *rc_data;
	int i;
	packet_t *packets = NULL;
	segment_list_t *tmp_list;
	fru_segdesc_t *descriptor;

	tmp_list = g_raw->segs;

	/* num of packet */
	rc_num = fru_get_num_packets(node, NULL);
	if (rc_num == -1) {
		return (map_errno(errno));
	} else if (rc_num == 0) {
		return (FRU_SUCCESS);
	}
	while (tmp_list) {
		if (node == tmp_list->segment->handle) {
			break;
		}
		tmp_list = tmp_list->next;
	}
	if (tmp_list) {
		descriptor = (fru_segdesc_t *)&tmp_list->segment->descriptor;
		if (descriptor->field.opaque) {
			return (FRU_SUCCESS);
		}

		if (descriptor->field.encrypted && (encrypt_func == NULL)) {
			return (FRU_SUCCESS);
		}
	}

	packets = malloc(sizeof (*packets) * (rc_num));
	if (packets == NULL) {
		return (FRU_FAILURE);
	}
	/* get all packets */
	if (fru_get_packets(node, packets, rc_num, NULL) == -1) {
		free(packets);
		return (map_errno(errno));
	}

	rc_tags = malloc(sizeof (*rc_tags) * (rc_num));
	if (rc_tags == NULL) {
		free(packets);
		return (FRU_FAILURE);
	}

	/* number of tags */
	for (i = 0; i < rc_num; i++) {
		size_t rc_len =
		    get_payload_length((fru_tag_t *)&packets[i].tag);

		rc_data = malloc(sizeof (*rc_data) * (rc_len));
		if (rc_data == NULL) {
			free(packets);
			return (FRU_FAILURE);
		}
		/* get the payload data */
		(void) fru_get_payload(packets[i].handle, (void *)rc_data,
		    rc_len, NULL);

		if (tmp_list) {
			descriptor =
			    (fru_segdesc_t *)&tmp_list->segment->descriptor;

			if ((descriptor->field.encrypted) &&
			    ((status = encrypt_func(FRU_DECRYPT,
			    (void *)rc_data, rc_len))
			    != FRU_SUCCESS)) {
				return (status);
			}
		}
		/* print packet */
		if ((status = function((fru_tag_t *)&packets[i].tag,
		    (uint8_t *)rc_data, rc_len, args)) != FRU_SUCCESS) {
			free(rc_data);
			free(packets);
			return (status);
		}
		free(rc_data);
	}
	return (FRU_SUCCESS);

}
示例#5
0
		void readFrom(const char *buffer, std::size_t length) {
			if (buffer == NULL)
				throw nrpe::nrpe_exception("No buffer.");
			if (length != get_packet_length())
				throw nrpe::nrpe_exception("Invalid packet length: " + strEx::s::xtos(length) + " != " + strEx::s::xtos(get_packet_length()) + " configured payload is: " + strEx::s::xtos(get_payload_length()));
			const nrpe::data::packet *p = reinterpret_cast<const nrpe::data::packet*>(buffer);
			type_ = swap_bytes::ntoh<int16_t>(p->packet_type);
			if ((type_ != nrpe::data::queryPacket)&&(type_ != nrpe::data::responsePacket))
				throw nrpe::nrpe_exception("Invalid packet type: " + strEx::s::xtos(type_));
			version_ = swap_bytes::ntoh<int16_t>(p->packet_version);
			if (version_ != nrpe::data::version2)
				throw nrpe::nrpe_exception("Invalid packet version." + strEx::s::xtos(version_));
			crc32_ = swap_bytes::ntoh<u_int32_t>(p->crc32_value);
			// Verify CRC32
			// @todo Fix this, currently we need a const buffer so we cannot change the CRC to 0.
			char * tb = new char[length+1];
			memcpy(tb, buffer, length);
			nrpe::data::packet *p2 = reinterpret_cast<nrpe::data::packet*>(tb);
			p2->crc32_value = 0;
			calculatedCRC32_ = calculate_crc32(tb, get_packet_length());
			delete [] tb;
			if (crc32_ != calculatedCRC32_) 
				throw nrpe::nrpe_exception("Invalid checksum in NRPE packet: " + strEx::s::xtos(crc32_) + "!=" + strEx::s::xtos(calculatedCRC32_));
			// Verify CRC32 end
			result_ = swap_bytes::ntoh<int16_t>(p->result_code);
			payload_ = fetch_payload(p);
		}
示例#6
0
static int
get_packets(hash_obj_t *seg_hash, raw_list_t *rawlist, int offset, int length)
{
	int tag_size;
	int paylen;
	int retval;
	int seg_limit = 0;
	int pktcnt = 0;
	char *data;
	uint32_t crc;
	uint32_t origcrc;
	fru_tag_t tag;
	hash_obj_t *pkt_hash_obj;
	hash_obj_t *sec_hash;
	fru_segdesc_t *segdesc;
	fru_tagtype_t tagtype;
	char *ignore_flag;

	retval = get_packet(rawlist, &tag, sizeof (fru_tag_t), offset);
	if (retval == -1) {
		return (-1);
	}

	/* section hash object */
	sec_hash = lookup_handle_object(seg_hash->u.seg_obj->section_hdl,
	    SECTION_TYPE);

	if (sec_hash == NULL) {
		return (-1);
	}

	seg_hash->u.seg_obj->trailer_offset = offset;

	data = (char *)&tag;
	while (data[0] != SEG_TRAILER_TAG) {
		tagtype	= get_tag_type(&tag); /* verify tag type */
		if (tagtype == -1) {
			return (-1);
		}

		tag_size = get_tag_size(tagtype);
		if (tag_size == -1) {
			return (-1);
		}

		seg_limit += tag_size;
		if (seg_limit > length) {
			return (-1);
		}

		paylen = get_payload_length((void *)&tag);
		if (paylen == -1) {
			return (-1);
		}

		seg_limit += paylen;
		if (seg_limit > length) {
			return (-1);
		}
		if ((offset + tag_size + paylen) >
		    (sec_hash->u.sec_obj->section.offset +
		    sec_hash->u.sec_obj->section.length)) {
			return (-1);
		}

		pkt_hash_obj = create_packet_hash_object();
		if (pkt_hash_obj == NULL) {
			return (-1);
		}

		pkt_hash_obj->u.pkt_obj->payload = malloc(paylen);
		if (pkt_hash_obj->u.pkt_obj->payload == NULL) {
			free(pkt_hash_obj);
			return (-1);
		}

		offset += tag_size;

		retval = raw_memcpy(pkt_hash_obj->u.pkt_obj->payload, rawlist,
		    offset, paylen);

		if (retval != paylen) {
			free(pkt_hash_obj->u.pkt_obj->payload);
			free(pkt_hash_obj);
			return (-1);
		}

		/* don't change this */
		pkt_hash_obj->u.pkt_obj->tag.raw_data = 0;
		(void) memcpy(&pkt_hash_obj->u.pkt_obj->tag, &tag, tag_size);
		pkt_hash_obj->u.pkt_obj->paylen = paylen;
		pkt_hash_obj->u.pkt_obj->tag_size = tag_size;
		pkt_hash_obj->u.pkt_obj->payload_offset = offset;

		offset += paylen;

		add_hashobject_to_hashtable(pkt_hash_obj);
		add_to_pkt_object_list(seg_hash, pkt_hash_obj);

		pktcnt++;

		retval = get_packet(rawlist, &tag, sizeof (fru_tag_t),
		    offset);
		if (retval == -1) {
			return (retval);
		}

		data = (char *)&tag;
	}

	segdesc	= (fru_segdesc_t *)&seg_hash->u.seg_obj->segment.descriptor;

	seg_hash->u.seg_obj->trailer_offset = offset;

	if (!segdesc->field.ignore_checksum)  {
		crc = get_checksum_crc(seg_hash, seg_limit);
		offset = seg_hash->u.seg_obj->segment.offset;

		retval = raw_memcpy(&origcrc, rawlist, offset + seg_limit + 1,
		    sizeof (origcrc));

		ignore_flag = getenv(IGNORE_CHECK);
		if (ignore_flag != NULL) {
			return (pktcnt);
		}

		if (retval != sizeof (origcrc)) {
			return (-1);
		}

		origcrc = BE_32(origcrc);
		if (origcrc != crc) {
			seg_hash->u.seg_obj->trailer_offset = offset;
			return (-1);
		}
	}

	return (pktcnt);
}