Beispiel #1
0
static long unpack_tpis(Octstr *data, long bitpos, WTP_PDU *pdu) {
	long length;
	int type;
	Octstr *tpidata;
	int another;

	do {
		another = octstr_get_bits(data, bitpos, 1);
		type = octstr_get_bits(data, bitpos + 1, 4);
		if (octstr_get_bits(data, bitpos + 5, 1)) {
			/* Long TPI */
			length = octstr_get_bits(data, bitpos + 8, 8);
			bitpos += 16;
		} else {
			/* Short TPI */
			length = octstr_get_bits(data, bitpos + 6, 2);
			bitpos += 8;
		}
		gw_assert(bitpos % 8 == 0);
		tpidata = octstr_copy(data, bitpos / 8, length);
		bitpos += 8 * length;
		wtp_pdu_append_tpi(pdu, type, tpidata);
	} while (another);

	return bitpos;
}
Beispiel #2
0
int wtls_payload_guess_length(Octstr* data) {

        int type = 0, lengthFlag = 0, lengthSize = 0, pdu_length = 0;
        long lengthOffset = 1;
        
        /* Is the fragment length indicator on? */
        lengthFlag = octstr_get_bits(data, 0, 1);
        if (lengthFlag) {
                lengthSize = 2;
        }
        
        /* Is the sequence number indicator on? */
        if (octstr_get_bits(data, 1, 1)) {
                /* Yes, so hop over two extra bytes when reading the length */
                lengthOffset += 2;
        }
        /* the message type */
        type = octstr_get_bits(data, 4, 4);
        
        /* If fragment length is turned on, jump to the necessary spot */
        if (lengthFlag == 1) {
                /* After this, lengthOffset + pdu_length == the total length of the PDU */
                pdu_length = unpack_int16(data, &lengthOffset);             
        }

        /* Oh great, so it's not switched on. How considerate. We'll have to make
           a reasonable guess as to what it might be. */
        else {
                switch (type) {
                case ChangeCipher_PDU:
                        /* They're really short */
                        pdu_length = 1;
                        break;
                        
                case Alert_PDU:
                        /* They're a bit longer */
                        pdu_length = 6;
                        break;

                default:
                        /* Otherwise just give up and play dead */
                        pdu_length = -1;
                        break;
                }
        }

        /* And that's the length of the contents, now just add the other doodads on */
        if (pdu_length == -1) {
                return -1;
        }
        else {
                /* The pdu length, plus the sequence number, plus the length of the length value,
                   plus the actual header byte */
                return (pdu_length + lengthOffset);
        }
}
Beispiel #3
0
/******************************************************************************
 *
 * EXTERNAL FUNCTIONS:
 *
 * Handles a possible concatenated message. Creates a list of wap events.
 */
List *wtp_unpack_wdp_datagram(WAPEvent *datagram)
{
     List *events = NULL;
     WAPEvent *event = NULL;
     WAPEvent *subdgram = NULL;
     Octstr *data = NULL;
     long pdu_len;

     gw_assert(datagram->type == T_DUnitdata_Ind);

     events = gwlist_create();
        
     if (concatenated_message(datagram->u.T_DUnitdata_Ind.user_data)) {
        data = octstr_duplicate(datagram->u.T_DUnitdata_Ind.user_data);
        octstr_delete(data, 0, 1);

        while (octstr_len(data) != 0) {

            if (octstr_get_bits(data, 0, 1) == 0) {
                pdu_len = octstr_get_char(data, 0);
                octstr_delete(data, 0, 1);
            } else {
                pdu_len = octstr_get_bits(data, 1, 15);
                octstr_delete(data, 0, 2);
            }
      
            subdgram = wap_event_duplicate(datagram);
            octstr_destroy(subdgram->u.T_DUnitdata_Ind.user_data);
            subdgram->u.T_DUnitdata_Ind.user_data = octstr_copy(data, 0, pdu_len);
            wap_event_assert(subdgram);
            if ((event = unpack_wdp_datagram_real(subdgram)) != NULL) {
                wap_event_assert(event);
                gwlist_append(events, event);
            }
            octstr_delete(data, 0, pdu_len);
            wap_event_destroy(subdgram);
        }

        octstr_destroy(data);

    } else if ((event = unpack_wdp_datagram_real(datagram)) != NULL) { 
        wap_event_assert(event);
        gwlist_append(events, event);
    } else {
        warning(0, "WTP: Dropping unhandled datagram data:");
        octstr_dump(datagram->u.T_DUnitdata_Ind.user_data, 0, GW_WARNING);
    }

    return events;
}
Beispiel #4
0
static WAPEvent *unpack_ack(WTP_PDU *pdu, WAPAddrTuple *addr_tuple)
{
    WAPEvent *event;
    WTP_TPI *tpi;
    int	i, num_tpis;

    event = wap_event_create(RcvAck);
    event->u.RcvAck.tid = pdu->u.Ack.tid;
    event->u.RcvAck.tid_ok = pdu->u.Ack.tidverify;
    event->u.RcvAck.rid = pdu->u.Ack.rid;
    event->u.RcvAck.addr_tuple = wap_addr_tuple_duplicate(addr_tuple);

    /* Set default to 0 because Ack on 1 piece message has no tpi */
    event->u.RcvAck.psn = 0;
    num_tpis = gwlist_len(pdu->options);

    for (i = 0; i < num_tpis; i++) {
        tpi = gwlist_get(pdu->options, i);
        if (tpi->type == TPI_PSN) {
            event->u.RcvAck.psn = octstr_get_bits(tpi->data,0,8);
            break;
        }
    }

    return event;
}
Beispiel #5
0
wtls_Payload *wtls_payload_unpack(Octstr *data) {
        wtls_Payload *payload = NULL;
		Octstr *buffer;
        long bitpos = 0, charpos = 0;
        int msg_length;
        
        gw_assert(data != NULL);

        payload = gw_malloc(sizeof(wtls_Payload));

        /* the record field length flag */
        payload->rlen = octstr_get_bits(data, bitpos, 1);
        bitpos += 1;
        /* the sequence number flag */
        payload->seqnum = octstr_get_bits(data, bitpos, 1);
        bitpos += 1;
        /* the cipher usage flag */
        payload->cipher = octstr_get_bits(data, bitpos, 1);
        bitpos += 1;
        /* the reserved bit */
        payload->reserved = octstr_get_bits(data, bitpos, 1);
        bitpos += 1;
        /* the message type */
        payload->type = octstr_get_bits(data, bitpos, 4);
        bitpos += 4;
        charpos += 1;
        
        /* get the sequence number if present */
        if(payload->seqnum) {
                seqnum = unpack_int16(data, &charpos);
        }
        
        /* get the WTLS plaintext length if present */
        if(payload->rlen) {
                msg_length = unpack_int16(data, &charpos);
        }

		/* the part of data that has just been processed is not
		   needed anymore. We delete it. What is left of data is
		   the payload. */
		octstr_delete(data, 0, charpos);
		payload->data = data;
		
		return payload;
}
Beispiel #6
0
static int deduce_tid(Octstr *user_data)
{ 
    return octstr_get_bits(user_data, 8, 16);
}