Пример #1
0
/*
 * NB: This data includes bearer information. We use IPv4 values. Address Type
 * is defined in wsp, table 16, p. 65
 */
static Octstr *pack_server_address(void)
{
    Octstr *address,
           *ip_address;
    unsigned char address_len;
    long port;
    int bearer_type;

    bearer_type = GSM_CSD_IPV4;
    port = CONNECTED_PORT;

    mutex_lock(bearerbox->mutex);  
    ip_address = octstr_duplicate(bearerbox->address);
    address_len = octstr_len(bearerbox->address);
    mutex_unlock(bearerbox->mutex);  

    address = octstr_create("");
    octstr_append_char(address, address_len);
    octstr_set_bits(address, 0, 1, 1); /* bearer type included */
    octstr_set_bits(address, 1, 1, 1); /* port number included */
    octstr_append_char(address, bearer_type);
    octstr_append_decimal(address, port);
    octstr_append(address, ip_address);
    octstr_destroy(ip_address);
    
    return address;
}
Пример #2
0
Octstr *wtls_payload_pack(wtls_Payload *payload) {
        Octstr *data;
        long bitpos, charpos;
        long messageSizePos, sizepos;
        /* Used for length calculations */
        int size;
        
        /* We rely on octstr_set_bits to lengthen our octstr as needed. */
        data = octstr_create("");
        bitpos = 0;
        charpos = 0;
        sizepos = 0;
        
        /* the record field length flag - always present*/
        octstr_set_bits(data, bitpos, 1, 1);
        bitpos += 1;
        /* the sequence number flag */
        octstr_set_bits(data, bitpos, 1, payload->seqnum);
        bitpos += 1;
        /* the cipher usage flag */
        octstr_set_bits(data, bitpos, 1, payload->cipher);
        bitpos += 1;
        /* the reserved bit */
        octstr_set_bits(data, bitpos, 1, payload->reserved);
        bitpos += 1;

        /* set the message type */
        octstr_set_bits(data, bitpos, 4, payload->type);
        bitpos += 4;
        charpos += 1;

        /* set the sequence number if present */
        if(payload->seqnum) {
                charpos = pack_int16(data, charpos, payload->seqnum);
        }

        /* set the WTLS length  */
        charpos = pack_int16(data, charpos, payload->rlen);
        
        /* append the data from the wtls_PDU */
        octstr_insert(data, payload->data, octstr_len(data)); 
        
        return data;
}
Пример #3
0
static long pack_tpis(Octstr *data, long bitpos, List *tpis) {
	long length;
	WTP_TPI *tpi;
	int i;
	int num_tpis;

	num_tpis = gwlist_len(tpis);
	for (i = 0; i < num_tpis; i++) {
		tpi = gwlist_get(tpis, i);
		length = octstr_len(tpi->data);
		octstr_set_bits(data, bitpos, 1, i + 1 < num_tpis);
		octstr_set_bits(data, bitpos + 1, 4, tpi->type);
		if (length >= 4) {
			/* Long TPI */
			octstr_set_bits(data, bitpos + 5, 1, 1);
			octstr_set_bits(data, bitpos + 8, 8, length);
			bitpos += 16;
		} else {
			/* Short TPI */
			octstr_set_bits(data, bitpos + 5, 1, 0);
			octstr_set_bits(data, bitpos + 6, 2, length);
			bitpos += 8;
		}
		gw_assert(bitpos % 8 == 0);
		octstr_append(data, tpi->data);
		bitpos += 8 * length;
	}

	return bitpos;
}
Пример #4
0
/*
 * Tokenises an OSI date. Procedure is defined in si, chapter 9.2.2. Validate
 * OSI date as specified in 9.2.1.1. Returns NULL when error, a tokenised date 
 * string otherwise.
 */
static Octstr *tokenize_date(Octstr *date)
{
    Octstr *date_token;
    long j;
    size_t i,
           date_len;
    unsigned char c;

    if (!parse_date(date)) {
        return NULL;
    }

    date_token = octstr_create("");
    octstr_append_char(date_token, WBXML_OPAQUE);

    i = 0;
    j = 0;
    date_len = octstr_len(date);
    while (i < date_len) {
        c = octstr_get_char(date, i);
        if (c != 'T' && c != 'Z' && c != '-' && c != ':') {
            if (isdigit(c)) {
                octstr_set_bits(date_token, 4*j + 8, 4, c & 0x0f);
                ++j;
            } else {
                octstr_destroy(date_token);
                return NULL;
            }
        }  
        ++i; 
    }

    octstr_drop_trailing_zeros(&date_token);
    flag_date_length(&date_token);

    return date_token;
}
Пример #5
0
static void sanitize_capabilities(List *caps, WSPMachine *m) {
	long i;
	Capability *cap;
	unsigned long ui;

	for (i = 0; i < gwlist_len(caps); i++) {
		cap = gwlist_get(caps, i);

		/* We only know numbered capabilities.  Let the application
		 * layer negotiate whatever it wants for unknown ones. */
		if (cap->name != NULL)
			continue;

		switch (cap->id) {
		case WSP_CAPS_CLIENT_SDU_SIZE:
			/* Check if it's a valid uintvar.  The value is the
			 * max SDU size we will send, and there's no
			 * internal limit to that, so accept any value. */
			if (cap->data != NULL &&
			    octstr_extract_uintvar(cap->data, &ui, 0) < 0)
				goto bad_cap;
			else
				m->client_SDU_size = ui;
			break;

		case WSP_CAPS_SERVER_SDU_SIZE:
			/* Check if it's a valid uintvar */
			if (cap->data != NULL &&
			    (octstr_extract_uintvar(cap->data, &ui, 0) < 0))
				goto bad_cap;
			/* XXX Our MRU is not quite unlimited, since we
			 * use signed longs in the library functions --
			 * should we make sure we limit the reply value
			 * to LONG_MAX?  (That's already a 2GB packet) */
			break;

		case WSP_CAPS_PROTOCOL_OPTIONS:
			/* Currently we don't support any Push, nor
			 * session resume, nor acknowledgement headers,
			 * so make sure those bits are not set. */
			if (cap->data != NULL && octstr_len(cap->data) > 0
			   && (octstr_get_char(cap->data, 0) & 0xf0) != 0) {
				warning(0, "WSP: Application layer tried to "
					"negotiate protocol options.");
				octstr_set_bits(cap->data, 0, 4, 0);
			}
			break;

		case WSP_CAPS_EXTENDED_METHODS:
			/* XXX Check format here */
			break;

		
		case WSP_CAPS_HEADER_CODE_PAGES:
			/* We don't support any yet, so don't let this
			 * be negotiated. */
			if (cap->data)
				goto bad_cap;
			break;
		}
		continue;

	bad_cap:
		error(0, "WSP: Found illegal value in capabilities reply.");
		wsp_cap_dump(cap);
		gwlist_delete(caps, i, 1);
		i--;
		wsp_cap_destroy(cap);
		continue;
	}
}
Пример #6
0
/* Set the U/P flag on an Invoke PDU */
static void set_user_ack(Octstr *pdu) {
	octstr_set_bits(pdu, 3 * 8 + 3, 1, 1);
}