RADIUS_PDU *radius_pdu_unpack(Octstr *data_without_len) { RADIUS_PDU *pdu; int type, ident; long len, pos; ParseContext *context; Octstr *authenticator; len = octstr_len(data_without_len); if (len < 20) { error(0, "RADIUS: PDU was too short (%ld bytes).", octstr_len(data_without_len)); return NULL; } context = parse_context_create(data_without_len); type = parse_get_char(context); ident = parse_get_char(context); pdu = radius_pdu_create(type, NULL); if (pdu == NULL) return NULL; len = decode_integer(data_without_len, 2, 2) - 19; parse_skip(context, 2); debug("radius", 0, "RADIUS: Attributes len is %ld", len); authenticator = parse_get_octets(context, 16); octstr_dump_short(authenticator, 0, "RADIUS: Authenticator (md5) is:"); /* skipping back to context start for macro magic */ parse_context_destroy(context); context = parse_context_create(data_without_len); switch (type) { #define INTEGER(name, octets) \ pos = octstr_len(data_without_len) - parse_octets_left(context); \ p->name = decode_integer(data_without_len, pos, octets); \ parse_skip(context, octets); #define OCTETS(name, field_giving_octets) \ p->name = parse_get_octets(context, field_giving_octets); #define PDU(name, id, fields) \ case id: { struct name *p = &pdu->u.name; fields; \ radius_attr_unpack(&context, &pdu); } break; #include "radius_pdu.def" default: error(0, "Unknown RADIUS_PDU type, internal error while unpacking."); } parse_context_destroy(context); octstr_destroy(authenticator); return pdu; }
int mime_decompile(Octstr *binary_mime, Octstr **mime) { char *boundary = "kannel_boundary"; ParseContext *context; long mime_parts; long i, j; unsigned long headers_len, data_len; i = mime_parts = headers_len = data_len = 0; debug("wap.wsp.multipart.form.data", 0, "MIMEDEC: begining decoding"); if(binary_mime == NULL || octstr_len(binary_mime) < 1) { warning(0, "MIMEDEC: invalid mime, ending"); return -1; } *mime = octstr_create(""); /* already dumped in deconvert_content debug("mime", 0, "MMSDEC: binary mime dump:"); octstr_dump(binary_mime, 0); */ context = parse_context_create(binary_mime); debug("mime", 0, "MIMEDEC: context created"); mime_parts = parse_get_uintvar(context); debug("mime", 0, "MIMEDEC: mime has %ld multipart entities", mime_parts); if(mime_parts == 0) { debug("mime", 0, "MIMEDEC: mime has none multipart entities, ending"); return 0; } while(parse_octets_left(context) > 0) { Octstr *headers, *data; List *gwlist_headers; i++; octstr_append(*mime, octstr_imm("--")); octstr_append(*mime, octstr_imm(boundary)); octstr_append(*mime, octstr_imm("\n")); headers_len = parse_get_uintvar(context); data_len = parse_get_uintvar(context); debug("mime", 0, "MIMEDEC[%ld]: headers length <0x%02lx>, " "data length <0x%02lx>", i, headers_len, data_len); if((headers = parse_get_octets(context, headers_len)) != NULL) { gwlist_headers = wsp_headers_unpack(headers, 1); for(j=0; j<gwlist_len(gwlist_headers);j++) { octstr_append(*mime, gwlist_get(gwlist_headers, j)); octstr_append(*mime, octstr_imm("\n")); } } else { error(0, "MIMEDEC[%ld]: headers length is out of range, ending", i); return -1; } if((data = parse_get_octets(context, data_len)) != NULL || (i = mime_parts && /* XXX SE-T610 eats last byte, which is generally null */ (data = parse_get_octets(context, data_len - 1)) != NULL)) { debug("mime", 0, "MMSDEC[%ld]: body [%s]", i, octstr_get_cstr(data)); octstr_append(*mime, octstr_imm("\n")); octstr_append(*mime, data); octstr_append(*mime, octstr_imm("\n")); } else { error(0, "MIMEDEC[%ld]: data length is out of range, ending", i); return -1; } } octstr_append(*mime, octstr_imm("--")); octstr_append(*mime, octstr_imm(boundary)); octstr_append(*mime, octstr_imm("--\n")); /* already dumped in deconvert_content debug("mime", 0, "MMSDEC: text mime dump:"); octstr_dump(*mime, 0); */ return 0; }