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))); }
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); }
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; }
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); }
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); }
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); }