Esempio n. 1
0
Octstr *radius_pdu_pack(RADIUS_PDU *pdu)
{
    Octstr *os,*oos;
    Octstr *temp;

    os = octstr_create("");

    gw_assert(pdu != NULL);

    /*
    switch (pdu->type) {
    #define INTEGER(name, octets) p = *(&p);
    #define NULTERMINATED(name, max_octets) p = *(&p);
    #define OCTETS(name, field_giving_octets) \
    	p->field_giving_octets = octstr_len(p->name);
    #define PDU(name, id, fields) \
    	case id: { struct name *p = &pdu->u.name; fields } break;
    #include "radius_pdu.def"
    default:
    	error(0, "Unknown RADIUS_PDU type, internal error while packing.");
    }
    */

    switch (pdu->type) {
    #define INTEGER(name, octets) \
    	append_encoded_integer(os, p->name, octets);
    #define OCTETS(name, field_giving_octets) \
    	octstr_append(os, p->name);
    #define PDU(name, id, fields) \
    	case id: { struct name *p = &pdu->u.name; fields; oos = radius_attr_pack(pdu); \
                   octstr_append(os, oos);octstr_destroy(oos); } break;
    #include "radius_pdu.def"
    default:
    	error(0, "Unknown RADIUS_PDU type, internal error while packing.");
    }

    /* now set PDU length */
    temp = octstr_create("");
    append_encoded_integer(temp, octstr_len(os), 2);
    octstr_delete(os, 2, 2);
    octstr_insert(os, temp, 2);
    octstr_destroy(temp);
    
    return os;
}
Esempio n. 2
0
Octstr *smpp_pdu_pack(SMPP_PDU *pdu)
{
    Octstr *os;
    Octstr *temp;

    os = octstr_create("");

    gw_assert(pdu != NULL);

    /*
     * Fix lengths of octet string fields.
     */
    switch (pdu->type) {
    #define OPTIONAL_BEGIN
    #define TLV_INTEGER(name, octets)
    #define TLV_NULTERMINATED(name, max_len)
    #define TLV_OCTETS(name, min_len, max_len)
    #define OPTIONAL_END
    #define INTEGER(name, octets) p = *(&p);
    #define NULTERMINATED(name, max_octets) p = *(&p);
    #define OCTETS(name, field_giving_octets) \
    	p->field_giving_octets = octstr_len(p->name);
    #define PDU(name, id, fields) \
    	case id: { struct name *p = &pdu->u.name; fields } break;
    #include "smpp_pdu.def"
    default:
    	error(0, "Unknown SMPP_PDU type, internal error while packing.");
    }

    switch (pdu->type) {
    #define TL(name, octets) \
        append_encoded_integer(os, SMPP_##name, 2); \
        append_encoded_integer(os, octets, 2);
    #define OPTIONAL_BEGIN
    #define TLV_INTEGER(name, octets) \
        if (p->name != -1) { \
            TL(name, octets); \
            INTEGER(name, octets) \
        }
    #define TLV_NULTERMINATED(name, max_len) \
        if (p->name != NULL) { \
            TL(name, (octstr_len(p->name) > max_len ? max_len : octstr_len(p->name))); \
            NULTERMINATED(name, max_len) \
        }
    #define TLV_OCTETS(name, min_len, max_len) \
        if (p->name != NULL) { \
            unsigned long len = octstr_len(p->name); \
            if (len > max_len || len < min_len) { \
                error(0, "SMPP: Optional field (%s) with invalid length (%ld) (should be %d - %d) dropped.", \
                    #name, len, min_len, max_len);\
            } else { \
                TL(name, len); \
                octstr_append(os, p->name); \
            } \
        }
    #define OPTIONAL_END
    #define INTEGER(name, octets) \
    	append_encoded_integer(os, p->name, octets);
    #define NULTERMINATED(name, max_octets) \
        if (p->name != NULL) { \
            if (octstr_len(p->name) >= max_octets) { \
                warning(0, "SMPP: PDU element <%s> too long " \
                        "(length is %ld, should be %d)", \
                        #name, octstr_len(p->name), max_octets-1); \
                temp = octstr_copy(p->name, 0, max_octets-1); \
            } else \
                temp = octstr_duplicate(p->name); \
            octstr_append(os, temp); \
            octstr_destroy(temp); \
        } \
        octstr_append_char(os, '\0');
    #define OCTETS(name, field_giving_octets) \
        if (p->name) octstr_append(os, p->name);
    #define PDU(name, id, fields) \
    	case id: { struct name *p = &pdu->u.name; fields } break;
    #include "smpp_pdu.def"
    default:
    	error(0, "Unknown SMPP_PDU type, internal error while packing.");
    }

    temp = octstr_create("");
    append_encoded_integer(temp, octstr_len(os) + 4, 4);
    octstr_insert(os, temp, 0);
    octstr_destroy(temp);

    return os;
}
Esempio n. 3
0
Octstr *smpp_pdu_pack(Octstr *smsc_id, SMPP_PDU *pdu)
{
    Octstr *os;
    Octstr *temp;

    os = octstr_create("");

    gw_assert(pdu != NULL);

    /*
     * Fix lengths of octet string fields.
     */
    switch (pdu->type) {
    #define OPTIONAL_BEGIN
    #define TLV_INTEGER(name, octets)
    #define TLV_NULTERMINATED(name, max_len)
    #define TLV_OCTETS(name, min_len, max_len)
    #define OPTIONAL_END
    #define INTEGER(name, octets) p = *(&p);
    #define NULTERMINATED(name, max_octets) p = *(&p);
    #define OCTETS(name, field_giving_octets) \
    	p->field_giving_octets = octstr_len(p->name);
    #define PDU(name, id, fields) \
    	case id: { struct name *p = &pdu->u.name; fields } break;
    #include "smpp_pdu.def"
    default:
    	error(0, "Unknown SMPP_PDU type, internal error while packing.");
    }

    switch (pdu->type) {
    #define TL(name, octets) \
        append_encoded_integer(os, SMPP_##name, 2); \
        append_encoded_integer(os, octets, 2);
    #define OPTIONAL_BEGIN
    #define TLV_INTEGER(name, octets) \
        if (p->name >= 0) { \
            TL(name, octets); \
            INTEGER(name, octets) \
        }
    #define TLV_NULTERMINATED(name, max_len) \
        if (p->name != NULL) { \
            TL(name, (octstr_len(p->name) > max_len ? max_len : octstr_len(p->name) + 1)); \
            NULTERMINATED(name, max_len) \
        }
    #define TLV_OCTETS(name, min_len, max_len) \
        if (p->name != NULL) { \
            unsigned long len = octstr_len(p->name); \
            if (len > max_len || len < min_len) { \
                error(0, "SMPP: Optional field (%s) with invalid length (%ld) (should be %d - %d) dropped.", \
                    #name, len, min_len, max_len);\
            } else { \
                TL(name, len); \
                octstr_append(os, p->name); \
            } \
        }
    #define OPTIONAL_END \
        if (p->tlv != NULL) { \
            Octstr *key; \
            List *keys; \
            struct smpp_tlv *tlv; \
            keys = dict_keys(p->tlv); \
            while(keys != NULL && (key = gwlist_extract_first(keys)) != NULL) { \
                tlv = smpp_tlv_get_by_name(smsc_id, key); \
                if (tlv == NULL) { \
                    error(0, "SMPP: Unknown TLV `%s', don't send.", octstr_get_cstr(key)); \
                    octstr_destroy(key); \
                    continue; \
                } \
                switch(tlv->type) { \
                case SMPP_TLV_INTEGER: { \
                    long val = atol(octstr_get_cstr(dict_get(p->tlv, key))); \
                    append_encoded_integer(os, tlv->tag, 2); \
                    append_encoded_integer(os, tlv->length, 2); \
                    append_encoded_integer(os, val, tlv->length); \
                    break; \
                } \
                case SMPP_TLV_OCTETS: \
                case SMPP_TLV_NULTERMINATED: { \
                    Octstr *val = dict_get(p->tlv, key); \
                    unsigned long len = octstr_len(val); \
                    if (len > tlv->length) { \
                        error(0, "SMPP: Optional field (%s) with invalid length (%ld) (should be %ld) dropped.", \
                              octstr_get_cstr(key), len, tlv->length);\
                        octstr_destroy(key); \
                        continue; \
                    } \
                    append_encoded_integer(os, tlv->tag, 2); \
                    if (tlv->type == SMPP_TLV_NULTERMINATED) \
                        append_encoded_integer(os, len + 1, 2); \
                    else \
                        append_encoded_integer(os, len, 2); \
                    octstr_append(os, val); \
                    if (tlv->type == SMPP_TLV_NULTERMINATED) \
                        octstr_append_char(os, '\0'); \
                    break; \
                } \
                default: \
                    panic(0, "SMPP: Internal error, unknown configured TLV type %d.", tlv->type); \
                    break; \
                } \
                octstr_destroy(key); \
            } \
            gwlist_destroy(keys, octstr_destroy_item); \
        }
    #define INTEGER(name, octets) \
        append_encoded_integer(os, p->name, octets);
    #define NULTERMINATED(name, max_octets) \
        if (p->name != NULL) { \
            if (octstr_len(p->name) >= max_octets) { \
                warning(0, "SMPP: PDU element <%s> too long " \
                        "(length is %ld, should be %d)", \
                        #name, octstr_len(p->name), max_octets-1); \
                temp = octstr_copy(p->name, 0, max_octets-1); \
            } else \
                temp = octstr_duplicate(p->name); \
            octstr_append(os, temp); \
            octstr_destroy(temp); \
        } \
        octstr_append_char(os, '\0');
    #define OCTETS(name, field_giving_octets) \
        if (p->name) octstr_append(os, p->name);
    #define PDU(name, id, fields) \
        case id: { struct name *p = &pdu->u.name; fields } break;
    #include "smpp_pdu.def"
    default:
        error(0, "Unknown SMPP_PDU type 0x%08lx, internal error while packing.", pdu->type);
        break;
    }

    temp = octstr_create("");
    append_encoded_integer(temp, octstr_len(os) + 4, 4);
    octstr_insert(os, temp, 0);
    octstr_destroy(temp);

    return os;
}