Pau Espin Pedrol | c90e6f8 | 2021-10-19 14:45:17 +0200 | [diff] [blame] | 1 | /* csn1_enc.c |
Ivan Kluchnikov | 487a141 | 2011-12-21 13:17:53 +0300 | [diff] [blame] | 2 | * Routines for CSN1 dissection in wireshark. |
| 3 | * |
| 4 | * Copyright (C) 2011 Ivan Klyuchnikov |
| 5 | * |
| 6 | * By Vincent Helfre, based on original code by Jari Sassi |
| 7 | * with the gracious authorization of STE |
| 8 | * Copyright (c) 2011 ST-Ericsson |
| 9 | * |
| 10 | * $Id: packet-csn1.c 39140 2011-09-25 22:01:50Z wmeier $ |
| 11 | * |
| 12 | * Wireshark - Network traffic analyzer |
| 13 | * By Gerald Combs <gerald@wireshark.org> |
| 14 | * Copyright 1998 Gerald Combs |
| 15 | * |
| 16 | * This program is free software; you can redistribute it and/or |
| 17 | * modify it under the terms of the GNU General Public License |
| 18 | * as published by the Free Software Foundation; either version 2 |
| 19 | * of the License, or (at your option) any later version. |
| 20 | * |
| 21 | * This program is distributed in the hope that it will be useful, |
| 22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 24 | * GNU General Public License for more details. |
| 25 | * |
| 26 | * You should have received a copy of the GNU General Public License |
| 27 | * along with this program; if not, write to the Free Software |
| 28 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| 29 | */ |
| 30 | |
Ivan Kluchnikov | 835f91e | 2012-04-30 18:00:36 +0400 | [diff] [blame] | 31 | #include <assert.h> |
| 32 | #include <string.h> |
Holger Hans Peter Freyther | cf0265a | 2013-07-28 15:57:20 +0200 | [diff] [blame] | 33 | #define __STDC_FORMAT_MACROS |
| 34 | #include <inttypes.h> |
Ivan Kluchnikov | 487a141 | 2011-12-21 13:17:53 +0300 | [diff] [blame] | 35 | #include "csn1.h" |
Ivan Kluchnikov | a9f1ff2 | 2012-05-24 22:25:06 +0400 | [diff] [blame] | 36 | #include <gprs_debug.h> |
Ivan Kluchnikov | 487a141 | 2011-12-21 13:17:53 +0300 | [diff] [blame] | 37 | |
Pau Espin Pedrol | d636f74 | 2020-02-03 15:37:08 +0100 | [diff] [blame] | 38 | #include <osmocom/core/logging.h> |
| 39 | #include <osmocom/core/utils.h> |
Ivan Kluchnikov | 487a141 | 2011-12-21 13:17:53 +0300 | [diff] [blame] | 40 | |
Pau Espin Pedrol | c90e6f8 | 2021-10-19 14:45:17 +0200 | [diff] [blame] | 41 | const unsigned char ixBitsTab[] = {0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5}; |
Ivan Kluchnikov | 487a141 | 2011-12-21 13:17:53 +0300 | [diff] [blame] | 42 | |
| 43 | /* Returns no_of_bits (up to 8) masked with 0x2B */ |
Pau Espin Pedrol | c90e6f8 | 2021-10-19 14:45:17 +0200 | [diff] [blame] | 44 | guint8 |
Vadim Yanitskiy | 39a6505 | 2020-01-25 01:24:59 +0700 | [diff] [blame] | 45 | get_masked_bits8(struct bitvec *vector, unsigned *readIndex, gint bit_offset, const gint no_of_bits) |
Ivan Kluchnikov | 487a141 | 2011-12-21 13:17:53 +0300 | [diff] [blame] | 46 | { |
| 47 | static const guint8 maskBits[] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF}; |
| 48 | //gint byte_offset = bit_offset >> 3; /* divide by 8 */ |
| 49 | gint relative_bit_offset = bit_offset & 0x07; /* modulo 8 */ |
| 50 | guint8 result; |
| 51 | gint bit_shift = 8 - relative_bit_offset - (gint) no_of_bits; |
Vadim Yanitskiy | 39a6505 | 2020-01-25 01:24:59 +0700 | [diff] [blame] | 52 | *readIndex -= relative_bit_offset; |
Ivan Kluchnikov | 487a141 | 2011-12-21 13:17:53 +0300 | [diff] [blame] | 53 | if (bit_shift >= 0) |
| 54 | { |
Vadim Yanitskiy | 39a6505 | 2020-01-25 01:24:59 +0700 | [diff] [blame] | 55 | result = (0x2B ^ ((guint8)bitvec_read_field(vector, readIndex, 8))) >> bit_shift; |
| 56 | *readIndex-= bit_shift; |
Ivan Kluchnikov | 487a141 | 2011-12-21 13:17:53 +0300 | [diff] [blame] | 57 | result &= maskBits[no_of_bits]; |
| 58 | } |
| 59 | else |
Pau Espin Pedrol | f960d5b | 2020-01-23 19:05:00 +0100 | [diff] [blame] | 60 | { |
Vadim Yanitskiy | 39a6505 | 2020-01-25 01:24:59 +0700 | [diff] [blame] | 61 | guint8 hight_part = (0x2B ^ ((guint8)bitvec_read_field(vector, readIndex, 8))) & maskBits[8 - relative_bit_offset]; |
Ivan Kluchnikov | 487a141 | 2011-12-21 13:17:53 +0300 | [diff] [blame] | 62 | hight_part = (guint8) (hight_part << (-bit_shift)); |
Vadim Yanitskiy | 39a6505 | 2020-01-25 01:24:59 +0700 | [diff] [blame] | 63 | result = (0x2B ^ ((guint8)bitvec_read_field(vector, readIndex, 8))) >> (8 + bit_shift); |
| 64 | *readIndex = *readIndex - (8 - (-bit_shift)); |
Ivan Kluchnikov | 487a141 | 2011-12-21 13:17:53 +0300 | [diff] [blame] | 65 | result |= hight_part; |
| 66 | } |
| 67 | return result; |
| 68 | } |
| 69 | |
| 70 | /** |
| 71 | * ================================================================================================ |
| 72 | * set initial/start values in help data structure used for packing/unpacking operation |
| 73 | * ================================================================================================ |
| 74 | */ |
| 75 | void |
| 76 | csnStreamInit(csnStream_t* ar, gint bit_offset, gint remaining_bits_len) |
| 77 | { |
| 78 | ar->remaining_bits_len = remaining_bits_len; |
| 79 | ar->bit_offset = bit_offset; |
Ivan Kluchnikov | 1b51734 | 2013-12-30 14:26:06 +0400 | [diff] [blame] | 80 | ar->direction = 0; |
Ivan Kluchnikov | 487a141 | 2011-12-21 13:17:53 +0300 | [diff] [blame] | 81 | } |
| 82 | |
Pau Espin Pedrol | d636f74 | 2020-02-03 15:37:08 +0100 | [diff] [blame] | 83 | static const struct value_string csn1_error_names[] = { |
| 84 | { CSN_OK, "General 0" }, |
| 85 | { CSN_ERROR_GENERAL, "General -1" }, |
| 86 | { CSN_ERROR_DATA_NOT_VALID, "DATA_NOT VALID" }, |
| 87 | { CSN_ERROR_IN_SCRIPT, "IN SCRIPT" }, |
| 88 | { CSN_ERROR_INVALID_UNION_INDEX, "INVALID UNION INDEX" }, |
| 89 | { CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, "NEED_MORE BITS TO UNPACK" }, |
Vadim Yanitskiy | fee767f | 2020-02-11 05:28:02 +0700 | [diff] [blame] | 90 | { CSN_ERROR_ILLEGAL_BIT_VALUE, "ILLEGAL BIT VALUE" }, |
| 91 | { CSN_ERROR_INTERNAL, "INTERNAL" }, |
Pau Espin Pedrol | d636f74 | 2020-02-03 15:37:08 +0100 | [diff] [blame] | 92 | { CSN_ERROR_STREAM_NOT_SUPPORTED, "STREAM_NOT_SUPPORTED" }, |
| 93 | { CSN_ERROR_MESSAGE_TOO_LONG, "MESSAGE_TOO_LONG" }, |
| 94 | { 0, NULL } |
Ivan Kluchnikov | 487a141 | 2011-12-21 13:17:53 +0300 | [diff] [blame] | 95 | }; |
| 96 | |
Pau Espin Pedrol | d636f74 | 2020-02-03 15:37:08 +0100 | [diff] [blame] | 97 | |
Pau Espin Pedrol | c90e6f8 | 2021-10-19 14:45:17 +0200 | [diff] [blame] | 98 | gint16 ProcessError_impl(const char *file, int line, unsigned *readIndex, |
Pau Espin Pedrol | d636f74 | 2020-02-03 15:37:08 +0100 | [diff] [blame] | 99 | const char* sz, gint16 err, const CSN_DESCR* pDescr) |
Ivan Kluchnikov | 487a141 | 2011-12-21 13:17:53 +0300 | [diff] [blame] | 100 | { |
Pau Espin Pedrol | ac2b866 | 2020-02-03 18:58:24 +0100 | [diff] [blame] | 101 | /* Don't add trailing newline, top caller is responsible for appending it */ |
Pau Espin Pedrol | d636f74 | 2020-02-03 15:37:08 +0100 | [diff] [blame] | 102 | if (err != CSN_OK) |
Vadim Yanitskiy | 1553049 | 2020-02-17 19:38:22 +0700 | [diff] [blame] | 103 | LOGPSRC(DCSN1, LOGL_ERROR, file, line, "%s: error %s (%d) at %s (idx %u)", |
Pau Espin Pedrol | d636f74 | 2020-02-03 15:37:08 +0100 | [diff] [blame] | 104 | sz, get_value_string(csn1_error_names, err), err, |
Vadim Yanitskiy | 39a6505 | 2020-01-25 01:24:59 +0700 | [diff] [blame] | 105 | pDescr ? pDescr->sz : "-", *readIndex); |
Ivan Kluchnikov | 487a141 | 2011-12-21 13:17:53 +0300 | [diff] [blame] | 106 | return err; |
| 107 | } |