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; }
int unpack_item(uint16_t type, uint16_t id, void * inbuf, uint16_t length, tlv_t * outtlv) { uint32_t outsize = 0; int ret = 0; void * value = NULL; message_t * newmsg = NULL; value = malloc(length); if (NULL == value) { return -1; } switch (id) { case TLV_TYPE_INT8: case TLV_TYPE_UINT8: outsize = length; ret = pack_int8((uint8_t *)inbuf, (uint8_t *)value, &outsize); break; case TLV_TYPE_INT16: case TLV_TYPE_UINT16: outsize = length; ret = unpack_int16((uint16_t *)inbuf, (uint16_t *)value, &outsize); break; case TLV_TYPE_INT32: case TLV_TYPE_UINT32: outsize = length; ret = unpack_int32((uint32_t *)inbuf, (uint32_t *)value, &outsize); break; case TLV_TYPE_BYTES: outsize = length; ret = pack_bytes(inbuf, length, value, &outsize); break; case TLV_TYPE_MSG: newmsg = msg_unpack((uint8_t *)inbuf, length); if (NULL == newmsg) { free(value); return -1; } memcpy(value, newmsg, MSG_SIZE(newmsg)); free(newmsg); break; default: free(value); return -1; } if (0 != ret) { free(value); } outtlv->id = id; outtlv->type = type; outtlv->length = length; outtlv->value = value; return ret; }
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); } }
int unpack_value(tlv_type_t type, uint16_t id, void *inbuf, uint16_t length, tlv_t *out_tlv) { int b = 0; uint32_t out_sz = 0; void *value = NULL; if (NULL == inbuf || NULL == out_tlv) { return -1; } value = malloc(length); if (NULL == value) { return -1; } switch(type) { case TLV_TYPE_INT8: case TLV_TYPE_UINT8: b = pack_int8((uint8_t*)inbuf, (uint8_t*)value, &out_sz); break; case TLV_TYPE_INT16: case TLV_TYPE_UINT16: b = unpack_int16((uint16_t*)inbuf, (uint16_t*)value, &out_sz); break; case TLV_TYPE_INT32: case TLV_TYPE_UINT32: b = unpack_int32((uint32_t*)inbuf, (uint32_t*)value, &out_sz); break; case TLV_TYPE_BYTES: out_sz = length; b = pack_bytes(inbuf, length, value, &out_sz); break; default: b = -1; break; } if (b != 0) { free(value); return -1; } out_tlv->id = id; out_tlv->type = type; out_tlv->length = length; out_tlv->value = value; return b; }
// Assuming http://www.seg.org/documents/10161/77915/seg_y_rev1.pdf int opesci_read_model_segy(const char *filename, std::vector<float> &array, int dim[], float spacing[]) { std::ifstream infile(filename); if(!infile.good()) { std::cerr<<"ERROR ("<<__FILE__<<", "<<__LINE__<<"): Failed to open SEG-Y file "<<filename<<std::endl; return -1; } // Get the size of the file. infile.seekg (0, infile.end); long filesize = infile.tellg(); // Read in header char header_buffer[3600]; infile.seekg(0, infile.beg); infile.read(header_buffer, 3600); bool swap_endian=false; int ntraces, tracesize, format_code; int Nx, Ny, Nz; for(int i=0; i<2; i++) { // Enables a re-try of header read. // 3201 - 3204 Job identification number. // 3205 - 3208 Line number. // 3209 - 3212 Reel number. // 3213 - 3214 Number of data traces per record. Nx = unpack_int16(header_buffer+3212, swap_endian); // 3215 - 3216 Number of auxiliary traces per record. // 3217 - 3218 Sample interval, microseconds, this file (reel). // 3219 - 3220 Sample interval, microseconds, original field recording. // 3221 - 3222 Number of samples per data trace, this file (reel). Nz = unpack_int16(header_buffer+3220, swap_endian); // 3223 - 3224 Number of samples per data trace, original field recording. // 3225 - 3226 Data sample format code: 1 = 4-byte IBM floating-point // 2 = 4-byte, two's complement integer // 3 = 2-byte, two's complement integer // 4 = 4-byte fixed-point with gain (obsolete) // 5 = 4-byte IEEE floating-point // 6 = Not currently used // 7 = Not currently used // 8 = 1-byte, two's complement integer format_code = unpack_int16(header_buffer+3224, swap_endian); if(format_code<1 || format_code>8) { swap_endian = true; format_code = unpack_int16(header_buffer+3224, swap_endian); // Try again... if(format_code<1 || format_code>8) { std::cerr<<"ERROR: unsupported data sample format code "<<format_code<<std::endl; return -1; } continue; // restart header read } // 3227 - 3228 CDP fold. // 3229 - 3230 Trace sorting code: Trace sorting code (i.e. type of ensemble) : // -1 = Other (should be explained in user Extended Textual File Header stanza // 0 = Unknown // 1 = As recorded (no sorting) // 2 = CDP ensemble // 3 = Single fold continuous profile // 4 = Horizontally stacked // 5 = Common source point // 6 = Common receiver point // 7 = Common offset point // 8 = Common mid-point // 9 = Common conversion point // 3231 - 3232 Vertical sum code: 1 = no sum 2 = two sum ... N = N sum (N = 32,767) // 3233 - 3234 Sweep frequency at start. // 3235 - 3236 Sweep frequency at end. // 3237 - 3238 Sweep length, ms. // 3239 - 3240 Sweep type code: 1 = linear // 2 = parabolic // 3 = exponential // 4 = other // 3241 - 3242 Trace number of sweep channel. // 3243 - 3244 Sweep trace taper length, ms, at start if tapered. // 3245 - 3246 Sweep trace taper length, ms, at end. // 3247 - 3248 Taper type: 1 = linear 2 = cos 3 = other // 3249 - 3250 Correlated data traces: 1 = no 2 = yes // 3251 - 3252 Binary gain recovered: 1 = yes 2 = no // 3253 - 3254 Amplitude recovery method: 1 = none 2 = spherical divergence 3 = AGC 4 = other // 3255 - 3256 Measurement system: 1 = meters 2 = feet // 3257 - 3258 Impulse signal: 1 = Upward = negative number. // 2 = Upward = positive number. // 3259 - 3260 Vibratory polarity code - seismic signal lags pilot signal by: 1 = 337.5 - 22.5 degrees // 2 = 22.5 - 67.5 degrees // 3 = 67.5 - 112.5 degrees // 4 = 112.5 - 157.5 degrees // 5 = 157.5 - 202.5 degrees // 6 = 202.5 - 247.5 degrees // Set tracesize tracesize = 240+4*Nz; // Get number of traces. ntraces = (filesize-3600)/tracesize; Ny = ntraces/Nx; break; } dim[0] = Nx; dim[1] = Ny; dim[2] = Nz; int xysize=dim[0]*dim[1]; int zysize=dim[2]*dim[1]; array.resize(dim[0]*dim[1]*dim[2]); if(format_code==1) { char trace_buffer[tracesize]; float x0[2], x1[2], scale_xy; for(int i=0; i<ntraces; i++) { // See Trace header in http://www.seg.org/documents/10161/77915/seg_y_rev1.pdf infile.read(trace_buffer, tracesize); int ix = i%Nx; int iy = i/Nx; if(i==0) { scale_xy = unpack_int16(trace_buffer+70, swap_endian); if(scale_xy<0) scale_xy = 1.0/fabs(scale_xy); x0[0] = scale_xy*unpack_int32(trace_buffer+72, swap_endian); x0[1] = scale_xy*unpack_int32(trace_buffer+76, swap_endian); } else if(i==1) { x1[0] = scale_xy*unpack_int32(trace_buffer+72, swap_endian); x1[1] = scale_xy*unpack_int32(trace_buffer+76, swap_endian); float dx = std::max(fabs(x0[0]-x1[0]), fabs(x0[1]-x1[1])); spacing[0] = dx; spacing[1] = dx; spacing[2] = scale_xy*unpack_int16(trace_buffer+116, swap_endian); // For model data this is overloaded as meters. } assert(unpack_int16(trace_buffer+114, swap_endian)==Nz); #ifndef NDEBUG if(i>0) { int _ix = (scale_xy*unpack_int32(trace_buffer+72, swap_endian)-x0[0])/spacing[0] + 0.5; // +0.5 to protext against round-off int _iy = (scale_xy*unpack_int32(trace_buffer+76, swap_endian)-x0[1])/spacing[1] + 0.5; assert(ix==_ix); assert(iy==_iy); } #endif for(int iz=0; iz<Nz; iz++) { char *next = trace_buffer+240+iz*4; array[ix+iy*Nx+iz*xysize] = unpack_ibmfloat(next, swap_endian); } } } else { std::cerr<<"ERROR: format code "<<format_code<<" not yet supported"<<std::endl; return -1; } return 0; }
wtls_PDU *wtls_pdu_unpack(wtls_Payload *payload, WTLSMachine* wtls_machine) { wtls_PDU *pdu = NULL; Octstr *buffer; long bitpos = 0, charpos = 0; int msg_length; gw_assert(payload->data != NULL); pdu = gw_malloc(sizeof(*pdu)); pdu->type = payload->type; pdu->reserved = payload->reserved; pdu->cipher = payload->cipher; pdu->seqnum = payload->seqnum; pdu->rlen = payload->rlen; /* is the PDU encrypted ? */ /* if(pdu->cipher) { buffer = wtls_decrypt(payload->data, wtls_machine); } else { */ buffer = payload->data; /* } */ switch (pdu->type) { case ChangeCipher_PDU: pdu->u.cc.change = octstr_get_char(buffer, charpos); charpos += 1; break; case Alert_PDU: pdu->u.alert.level = octstr_get_char(buffer, charpos); charpos += 1; pdu->u.alert.desc = octstr_get_char(buffer, charpos); charpos += 1; pdu->u.alert.chksum = unpack_octstr_fixed(buffer, &charpos, 4); break; case Handshake_PDU: pdu->u.handshake.msg_type = octstr_get_char(buffer, charpos); charpos += 1; pdu->u.handshake.length = unpack_int16(buffer, &charpos); switch (pdu->u.handshake.msg_type) { case hello_request: break; case client_hello: pdu->u.handshake.client_hello = (ClientHello *)gw_malloc(sizeof(ClientHello)); pdu->u.handshake.client_hello->clientversion = octstr_get_char(buffer, charpos); charpos += 1; pdu->u.handshake.client_hello->random = unpack_random(buffer, &charpos); pdu->u.handshake.client_hello->session_id = unpack_octstr(buffer, &charpos); /* pack the list of keys */ pdu->u.handshake.client_hello->client_key_ids = unpack_key_list(buffer, &charpos); pdu->u.handshake.client_hello->trusted_key_ids = unpack_key_list(buffer, &charpos); /* pack the list of CipherSuites */ pdu->u.handshake.client_hello->ciphersuites = unpack_ciphersuite_list(buffer, &charpos); /* CompressionMethods */ pdu->u.handshake.client_hello->comp_methods = unpack_compression_method_list(buffer, &charpos); pdu->u.handshake.client_hello->snmode = octstr_get_char(buffer, charpos); charpos += 1; pdu->u.handshake.client_hello->krefresh = octstr_get_char(buffer, charpos); charpos += 1; break; case server_hello: pdu->u.handshake.server_hello = (ServerHello *)gw_malloc(sizeof(ServerHello)); pdu->u.handshake.server_hello->serverversion = octstr_get_char(buffer, charpos); charpos += 1; pdu->u.handshake.server_hello->random = unpack_random(buffer, &charpos); pdu->u.handshake.server_hello->session_id = unpack_octstr(buffer, &charpos); charpos += 1; pdu->u.handshake.server_hello->client_key_id = octstr_get_char(buffer, charpos); charpos += 1; /* CypherSuite */ pdu->u.handshake.server_hello->ciphersuite->bulk_cipher_algo = octstr_get_char(buffer, charpos); charpos += 1; pdu->u.handshake.server_hello->ciphersuite->mac_algo = octstr_get_char(buffer, charpos); charpos += 1; /* CompressionMethod */ pdu->u.handshake.server_hello->comp_method = octstr_get_char(buffer, charpos); charpos += 1; pdu->u.handshake.server_hello->snmode = octstr_get_char(buffer, charpos); charpos += 1; pdu->u.handshake.server_hello->krefresh = octstr_get_char(buffer, charpos); charpos += 1; break; case certificate: pdu->u.handshake.certificate = (Certificate *)gw_malloc(sizeof(Certificate)); pdu->u.handshake.certificate->certificateformat = octstr_get_char(buffer, charpos); charpos += 1; switch (pdu->u.handshake.certificate->certificateformat) { case WTLSCert: pdu->u.handshake.certificate->wtls_certificate = unpack_wtls_certificate(buffer, &charpos); break; case X509Cert: pdu->u.handshake.certificate->x509_certificate = unpack_octstr16(buffer, &charpos); break; case X968Cert: pdu->u.handshake.certificate->x968_certificate = unpack_octstr16(buffer, &charpos); break; } break; case server_key_exchange: pdu->u.handshake.server_key_exchange = (ServerKeyExchange *)gw_malloc(sizeof(ServerKeyExchange)); /* unpack the ParameterSpecifier and ParameterSet*/ pdu->u.handshake.server_key_exchange->param_spec = unpack_param_spec(buffer, &charpos); switch (client_key_exchange_algo) { case rsa_anon: pdu->u.handshake.server_key_exchange->rsa_params = unpack_rsa_pubkey(buffer, &charpos); break; case dh_anon: pdu->u.handshake.server_key_exchange->dh_params = unpack_dh_pubkey(buffer, &charpos); break; case ecdh_anon: pdu->u.handshake.server_key_exchange->ecdh_params = unpack_ec_pubkey(buffer, &charpos); break; } break; case client_key_exchange: pdu->u.handshake.client_key_exchange = (ClientKeyExchange *)gw_malloc(sizeof(ClientKeyExchange)); switch (client_key_exchange_algo) { case rsa: case rsa_anon: pdu->u.handshake.client_key_exchange->rsa_params = unpack_rsa_encrypted_secret(buffer, &charpos); break; case dh_anon: pdu->u.handshake.client_key_exchange->dh_anon_params = unpack_dh_pubkey(buffer, &charpos); break; case ecdh_anon: case ecdh_ecdsa: pdu->u.handshake.client_key_exchange->ecdh_params = unpack_ec_pubkey(buffer, &charpos); break; } break; case server_hello_done: /* empty */ break; case finished: pdu->u.handshake.finished = (Finished *)gw_malloc(sizeof(Finished)); pdu->u.handshake.finished->verify_data = unpack_octstr_fixed(buffer, &charpos, 12); octstr_dump(pdu->u.handshake.finished->verify_data, 0); break; } break; case Application_PDU: /* application message */ pdu->u.application.data = octstr_duplicate(buffer); break; default: debug("wap.wtls", 0, "%*sPDU: ", 0, ""); octstr_dump(buffer, 0); panic(0, "Unpacking unknown WTLS PDU type %ld", (long) pdu->type); } return pdu; }
int unpack_item(tlv_type_t type, uint16_t id, void * inbuf, uint16_t length, tlv_t * outtlv) { uint32_t outsize = 0; int ret = 0; void * value = NULL; message_t * newmsg = NULL; if ((NULL == inbuf) || (NULL == outtlv)) { return -1; } value = malloc(length); if (NULL == value) { return -1; } switch (type) { case TLV_TYPE_INT8: case TLV_TYPE_UINT8: outsize = length; ret = pack_int8((uint8_t *)inbuf, (uint8_t *)value, &outsize); break; case TLV_TYPE_INT16: case TLV_TYPE_UINT16: outsize = length; ret = unpack_int16((uint16_t *)inbuf, (uint16_t *)value, &outsize); break; case TLV_TYPE_INT32: case TLV_TYPE_UINT32: outsize = length; ret = unpack_int32((uint32_t *)inbuf, (uint32_t *)value, &outsize); break; case TLV_TYPE_BYTES: outsize = length; ret = pack_bytes(inbuf, length, value, &outsize); break; case TLV_TYPE_MSG: newmsg = msg_unpack((uint8_t *)inbuf, length); if (NULL == newmsg) { ret = -1; break; } free(value); value = (void *)newmsg; ret = 0; break; default: ret = -1; } if (0 != ret) { free(value); goto exit; } outtlv->id = id; outtlv->type = type; outtlv->length = length; outtlv->value = value; exit: return ret; }