/* * 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; }
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; }
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; }
/* * 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; }
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; } }
/* 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); }