char *mid_pretty_print(mid_t *mid) { int size = 0; int oid_size = 0; int raw_size = 0; char *oid_str = NULL; char *raw_str; char *result = NULL; char *cursor = NULL; DTNMP_DEBUG_ENTRY("mid_pretty_print","(%#llx)", (unsigned long) mid); /* Step 0: Sanity Check. */ if(mid == NULL) { DTNMP_DEBUG_ERR("mid_pretty_print","NULL MID.",NULL); DTNMP_DEBUG_EXIT("mid_pretty_print","->NULL.",NULL); return NULL; } /* Step 1: Grab the pretty-print of the encapsulated OID. We will need to * do this anyway and it will help with the sizing. */ if(mid->oid != NULL) { oid_str = oid_pretty_print(mid->oid); oid_size = strlen((char *)oid_str) + 1; } if(oid_str == NULL) { oid_size = strlen("NULL_OID") + 1; if((oid_str = (char *) MTAKE(oid_size)) != NULL) { memset(oid_str,0,oid_size); strncpy((char *)oid_str,"NULL OID",oid_size); } else { DTNMP_DEBUG_ERR("mid_pretty_print","Can't alloc %d bytes for OID.", oid_size); DTNMP_DEBUG_EXIT("mid_pretty_print","->NULL.",NULL); return NULL; } } /* Step 2: Grab the raw version of the MID string. */ if((raw_str = mid_to_string(mid)) == NULL) { raw_size = strlen("NO RAW!") + 1; if((raw_str = (char *) MTAKE(raw_size)) != NULL) { memset(raw_str, 0, raw_size); strncpy(raw_str,"NO RAW!", raw_size); } else { DTNMP_DEBUG_ERR("mid_pretty_print","Can't alloc %d bytes for RAW.", raw_size); MRELEASE(oid_str); DTNMP_DEBUG_EXIT("mid_pretty_print","->NULL.",NULL); return NULL; } } else { raw_size = strlen((char*)raw_str) + 1; } /* Step 3: Guestimate size. This is, at best, a dark art and prone to * exaggeration. Numerics are assumed to take 5 bytes, unless I * think they will take 3 instead (indices vs. values). Other * values are based on constant strings in the function. One must * update this calculation if one changes string constants, else * one will be sorry. */ size = 28 + /* BANNER------ */ 14 + /* Flag : <...> */ 18 + /* Type : <...> */ 17 + /* Cat : <...> */ 17 + /* ISS : <...> */ 7 + oid_size + /* OID : <...> */ 17 + /* Tag : <...> */ 7 + raw_size + /* Raw : <...> */ 28; /* BANNER ----- */ /* Step 4: Allocate the string. */ if((result = (char*)MTAKE(size)) == NULL) { DTNMP_DEBUG_ERR("mid_pretty_print", "Can't alloc %d bytes.", size); MRELEASE(oid_str); MRELEASE(raw_str); DTNMP_DEBUG_EXIT("mid_pretty_print","->NULL",NULL); return NULL; } else { memset(result,0,size); } /* Step 5: Populate the allocated string. Keep an eye on the size. */ cursor = result; cursor += sprintf(cursor,"MID:\n---------------------\nFlag: %#x",mid->flags); cursor += sprintf(cursor,"\nType : "); switch(mid->type) { case 0: cursor += sprintf(cursor,"DATA\n"); break; case 1: cursor += sprintf(cursor,"CONTROL\n"); break; case 2: cursor += sprintf(cursor,"LITERAL\n"); break; case 3: cursor += sprintf(cursor,"OPERATOR\n"); break; default: cursor += sprintf(cursor,"UNKNOWN\n"); break; } cursor += sprintf(cursor,"Cat: "); switch(mid->category) { case 0: cursor += sprintf(cursor,"ATOMIC\n"); break; case 1: cursor += sprintf(cursor,"COMPUTED\n"); break; case 2: cursor += sprintf(cursor,"COLLECTION\n"); break; default: cursor += sprintf(cursor,"UNKNOWN\n"); break; } if(MID_GET_FLAG_ISS(mid->flags)) { cursor += sprintf(cursor,UVAST_FIELDSPEC"\n",mid->issuer); } else { cursor += sprintf(cursor,"None.\n"); } cursor += sprintf(cursor,"OID : %s", oid_str); MRELEASE(oid_str); if(MID_GET_FLAG_TAG(mid->flags)) { cursor += sprintf(cursor,UVAST_FIELDSPEC"\n",mid->tag); } else { cursor += sprintf(cursor,"None.\n"); } cursor += sprintf(cursor,"RAW : %s", raw_str); MRELEASE(raw_str); /* Step 6: Sanity check. */ if((cursor - result) > size) { DTNMP_DEBUG_ERR("mid_pretty_print", "OVERWROTE! Alloc %d, wrote %llu.", size, (cursor-result)); MRELEASE(result); DTNMP_DEBUG_EXIT("mid_pretty_print","->NULL",NULL); return NULL; } DTNMP_DEBUG_INFO("mid_pretty_print","Wrote %llu into %d string.", (cursor -result), size); DTNMP_DEBUG_EXIT("mid_pretty_print","->%#llx",result); return result; }
/****************************************************************************** * * \par Function Name: mid_deserialize * * \par Extracts a MID from a byte buffer. * * \retval NULL - Failure * !NULL - The created/deserialized MID. * * \param[in] buffer The byte buffer holding the MID data * \param[in] buffer_size The # bytes available in the buffer * \param[out] bytes_used The # of bytes consumed in the deserialization. * * \par Notes: * \todo: Allow a NULL bytes_used for cases where we are not deserializing * from a larger stream. * * Modification History: * MM/DD/YY AUTHOR DESCRIPTION * -------- ------------ --------------------------------------------- * 10/22/12 E. Birrane Initial implementation, * 06/25/13 E. Birrane Removed references to priority field. *****************************************************************************/ mid_t *mid_deserialize(unsigned char *buffer, uint32_t buffer_size, uint32_t *bytes_used) { mid_t *result = NULL; unsigned char *cursor = NULL; int sdnv_len = 0; uint32_t cur_bytes = 0; uint32_t bytes_left=0; DTNMP_DEBUG_ENTRY("mid_deserialize","(%#llx, %d, %#llx)", (unsigned long) buffer, (unsigned long) buffer_size, (unsigned long) bytes_used); *bytes_used = 0; /* Step 1: Sanity checks. */ if((buffer == NULL) || (buffer_size == 0) || (bytes_used == NULL)) { DTNMP_DEBUG_ERR("mid_deserialize","Bad params.",NULL); DTNMP_DEBUG_EXIT("mid_deserialize","-> NULL", NULL); return NULL; } else { *bytes_used = 0; cursor = buffer; bytes_left = buffer_size; } /* Step 2: Allocate/Zero the MID. */ if((result = (mid_t *) MTAKE(sizeof(mid_t))) == NULL) { DTNMP_DEBUG_ERR("mid_deserialize","Cannot allocate MID of size %d", sizeof(mid_t)); DTNMP_DEBUG_EXIT("mid_deserialize","-> NULL", NULL); return NULL; } else { memset(result,0,sizeof(mid_t)); } /* Step 3: Grab the MID flag */ if(utils_grab_byte(cursor, bytes_left, &(result->flags)) != 1) { DTNMP_DEBUG_ERR("mid_deserialize","Can't grab flag byte.", NULL); mid_release(result); DTNMP_DEBUG_EXIT("mid_deserialize","-> NULL", NULL); return NULL; } else { cursor += 1; bytes_left -= 1; *bytes_used += 1; } /* Step 4: Break out flag...*/ result->type = MID_GET_FLAG_TYPE(result->flags); result->category = MID_GET_FLAG_CAT(result->flags); /* Step 5: Grab issuer, if present. Issuers MUST exist for non-atomic.*/ if(MID_GET_FLAG_ISS(result->flags)) { cur_bytes = utils_grab_sdnv(cursor, bytes_left, &(result->issuer)); if( cur_bytes == 0) { DTNMP_DEBUG_ERR("mid_deserialize","Can't grab issuer.", NULL); mid_release(result); DTNMP_DEBUG_EXIT("mid_deserialize","-> NULL", NULL); return NULL; } else { cursor += cur_bytes; bytes_left -= cur_bytes; *bytes_used += cur_bytes; } } /* Step 6: Grab the OID. */ switch(MID_GET_FLAG_OID(result->flags)) { case OID_TYPE_FULL: result->oid = oid_deserialize_full(cursor, bytes_left, &cur_bytes); break; case OID_TYPE_PARAM: result->oid = oid_deserialize_param(cursor, bytes_left, &cur_bytes); break; case OID_TYPE_COMP_FULL: result->oid = oid_deserialize_comp(cursor, bytes_left, &cur_bytes); break; case OID_TYPE_COMP_PARAM: result->oid = oid_deserialize_comp_param(cursor, bytes_left, &cur_bytes); break; default: result->oid = NULL; cur_bytes = 0; break; } if(result->oid == NULL) { DTNMP_DEBUG_ERR("mid_deserialize","Can't grab oid.", NULL); mid_release(result); DTNMP_DEBUG_EXIT("mid_deserialize","-> NULL", NULL); return NULL; } else { cursor += cur_bytes; bytes_left -= cur_bytes; *bytes_used += cur_bytes; result->oid->type = MID_GET_FLAG_OID(result->flags); } /* Step 7: Populate Tag if preset. */ if(MID_GET_FLAG_TAG(result->flags)) { cur_bytes = utils_grab_sdnv(cursor, bytes_left, &(result->tag)); if( cur_bytes == 0) { DTNMP_DEBUG_ERR("mid_deserialize","Can't grab tag.", NULL); mid_release(result); DTNMP_DEBUG_EXIT("mid_deserialize","-> NULL", NULL); return NULL; } else { cursor += cur_bytes; bytes_left -= cur_bytes; *bytes_used += cur_bytes; } } /* Step 8: Is this a sane MID? */ if(mid_sanity_check(result) == 0) { DTNMP_DEBUG_ERR("mid_deserialize","Flags Sanity Check Failed.", NULL); mid_release(result); DTNMP_DEBUG_EXIT("mid_deserialize","-> NULL", NULL); return NULL; } /* Step 9: Copy MID into the raw value. */ if((result->raw = (unsigned char *) MTAKE(*bytes_used)) == NULL) { DTNMP_DEBUG_ERR("mid_deserialize","Can't TAKE raw mid of size (%d)", *bytes_used); mid_release(result); DTNMP_DEBUG_EXIT("mid_deserialize","-> NULL", NULL); return NULL; } memcpy(result->raw, buffer, *bytes_used); result->raw_size = *bytes_used; DTNMP_DEBUG_EXIT("mid_deserialize","-> %#llx", (unsigned long) result); return result; }
int mid_internal_serialize(mid_t *mid) { Sdnv iss; Sdnv tag; uint32_t oid_size = 0; uint8_t *oid_val = NULL; uint8_t *cursor = NULL; DTNMP_DEBUG_ENTRY("mid_internal_serialize","(%#llx)",(unsigned long) mid); /* Step 0: Sanity Check. */ if(mid == NULL) { DTNMP_DEBUG_ERR("mid_internal_serialize","Bad args.",NULL); DTNMP_DEBUG_EXIT("mid_internal_serialize","->0",NULL); return 0; } /* Step 1: Serialize the OID for sizing. */ if((oid_val = oid_serialize(mid->oid, &oid_size)) == NULL) { DTNMP_DEBUG_ERR("mid_internal_serialize","Can't serialize OID.",NULL); DTNMP_DEBUG_EXIT("mid_internal_serialize","->0",NULL); return 0; } /* Step 2: If there is a serialized version of the MID already, wipe it.*/ if(mid->raw != NULL) { MRELEASE(mid->raw); mid->raw = NULL; } mid->raw_size = 0; /* Step 3: Build the SDNVs. */ encodeSdnv(&iss, mid->issuer); encodeSdnv(&tag, mid->tag); /* Step 4: Figure out the size of the serialized MID. */ mid->raw_size = 1 + oid_size; /* Add issuer if present. */ if(MID_GET_FLAG_ISS(mid->flags)) { mid->raw_size += iss.length; } /* Add tag if present. */ if(MID_GET_FLAG_TAG(mid->flags)) { mid->raw_size += tag.length; } /* Step 5: Allocate space for the serialized MID. */ if((mid->raw = (uint8_t *)MTAKE(mid->raw_size)) == NULL) { DTNMP_DEBUG_ERR("mid_internal_serialize","Can't alloc %d bytes.", mid->raw_size); mid->raw_size = 0; MRELEASE(oid_val); DTNMP_DEBUG_EXIT("mid_internal_serialize","->0",NULL); return 0; } /* Step 6: Populate the serialized MID. */ cursor = mid->raw; *cursor = mid->flags; cursor++; /* Add issuer if present. */ if(MID_GET_FLAG_ISS(mid->flags)) { memcpy(cursor, iss.text, iss.length); cursor += iss.length; } /* Copy the OID. */ memcpy(cursor,oid_val, oid_size); cursor += oid_size; /* Add tag if present. */ if(MID_GET_FLAG_TAG(mid->flags)) { memcpy(cursor, tag.text, tag.length); cursor += tag.length; } /* Step 7: Final sanity check. */ if((cursor - mid->raw) != mid->raw_size) { DTNMP_DEBUG_ERR("mid_internal_serialize","Copied %d bytes, expected %d bytes.", (cursor - mid->raw), mid->raw_size); mid->raw_size = 0; MRELEASE(mid->raw); mid->raw = NULL; MRELEASE(oid_val); DTNMP_DEBUG_EXIT("mid_internal_serialize","->0",NULL); return 0; } DTNMP_DEBUG_EXIT("mid_internal_serialize","->1",NULL); return 1; }
/* * We need to find out a description for the entry so we can print it out. * So, if entry is <RPT MID> <int d1><int d2><int d3> we need to match the items * to elements of the report definition. * */ void ui_print_entry(rpt_entry_t *entry, uvast *mid_sizes, uvast *data_sizes) { LystElt elt = NULL; def_gen_t *cur_def = NULL; uint8_t del_def = 0; if((entry == NULL) || (mid_sizes == NULL) || (data_sizes == NULL)) { AMP_DEBUG_ERR("ui_print_entry","Bad Args.", NULL); return; } /* Step 1: Calculate sizes...*/ *mid_sizes = *mid_sizes + entry->id->raw_size; for(elt = lyst_first(entry->contents->datacol); elt; elt = lyst_next(elt)) { blob_t *cur = lyst_data(elt); *data_sizes = *data_sizes + cur->length; } *data_sizes = *data_sizes + entry->contents->hdr.length; /* Step 1: Print the MID associated with the Entry. */ printf(" ("); ui_print_mid(entry->id); printf(") has %d values.", entry->contents->hdr.length); /* * Step 2: Try and find the metadata associated with each * value in the TDC. Since the TDC is already typed, the * needed meta-data information is simply the * "name" of the data. * * i Only computed data definitions, reports, and macros * need names. Literals, controls, and atomic data do * not (currently) define extra meta-data for their * definitions. * * \todo: Consider printing names for each return * value from a control. */ cur_def = NULL; if(MID_GET_FLAG_ID(entry->id->flags) == MID_ATOMIC) { adm_datadef_t *ad_entry = adm_find_datadef(entry->id); /* Fake a def_gen_t for now. */ if(ad_entry != NULL) { Lyst tmp = lyst_create(); lyst_insert(tmp,mid_copy(ad_entry->mid)); cur_def = def_create_gen(mid_copy(ad_entry->mid), ad_entry->type, tmp); del_def = 1; } } else if(MID_GET_FLAG_ID(entry->id->flags) == MID_COMPUTED) { var_t *cd = NULL; if(MID_GET_FLAG_ISS(entry->id->flags) == 0) { cd = var_find_by_id(gAdmComputed, NULL, entry->id); } else { cd = var_find_by_id(gMgrVDB.compdata, &(gMgrVDB.compdata_mutex), entry->id); } // Fake a def_gen just for this CD item. if(cd != NULL) { Lyst tmp = lyst_create(); lyst_insert(tmp,mid_copy(cd->id)); cur_def = def_create_gen(mid_copy(cd->id), cd->value.type, tmp); del_def = 1; } } else if(MID_GET_FLAG_ID(entry->id->flags) == MID_REPORT) { if(MID_GET_FLAG_ISS(entry->id->flags) == 0) { cur_def = def_find_by_id(gAdmRpts, NULL, entry->id); } else { cur_def = def_find_by_id(gMgrVDB.reports, &(gMgrVDB.reports_mutex), entry->id); } } else if(MID_GET_FLAG_ID(entry->id->flags) == MID_MACRO) { if(MID_GET_FLAG_ISS(entry->id->flags) == 0) { cur_def = def_find_by_id(gAdmMacros, NULL, entry->id); } else { cur_def = def_find_by_id(gMgrVDB.macros, &(gMgrVDB.macros_mutex), entry->id); } } /* Step 3: Print the TDC holding data for the entry. */ ui_print_tdc(entry->contents, cur_def); if(del_def) { def_release_gen(cur_def); } return; }