blob: 638cdb6c9e57eed9b12a2973ae9668ba6134de04 [file] [log] [blame]
Harald Welte2d4f2bd2016-01-03 17:14:54 +01001/* helper functions to dela with asn1c data types */
2
3/* (C) 2014-2015 by Harald Welte <laforge@gnumonks.org>
4 * All Rights Reserved
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Affero General Public License for more details.
15 *
16 * You should have received a copy of the GNU Affero General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21#include <string.h>
22#include <errno.h>
23#include <arpa/inet.h>
24
25#include <osmocom/core/utils.h>
26
27#include "asn1helpers.h"
28#include "asn_internal.h"
29
30void asn1_u32_to_bitstring(BIT_STRING_t *bitstr, uint32_t *buf, uint32_t in)
31{
32 *buf = htonl(in);
33 bitstr->buf = (uint8_t *) buf;
34 bitstr->size = sizeof(uint32_t);
35 bitstr->bits_unused = 0;
36}
37
38void asn1_u28_to_bitstring(BIT_STRING_t *bitstr, uint32_t *buf, uint32_t in)
39{
40 *buf = htonl(in<<4);
41 bitstr->buf = (uint8_t *) buf;
42 bitstr->size = sizeof(uint32_t);
43 bitstr->bits_unused = 4;
44}
45
46void asn1_u24_to_bitstring(BIT_STRING_t *bitstr, uint32_t *buf, uint32_t in)
47{
48 *buf = htonl(in<<8);
49 bitstr->buf = (uint8_t *) buf;
50 bitstr->size = 24/8;
51 bitstr->bits_unused = 0;
52}
53
54int BIT_STRING_fromBuf(BIT_STRING_t *st, const uint8_t *str, unsigned int bit_len)
55{
56 void *buf;
57 unsigned int len = bit_len / 8;
58
59 if (bit_len % 8)
60 len++;
61
62 if (!st || (!str && len)) {
63 errno = EINVAL;
64 return -1;
65 }
66
67 if (!str) {
68 FREEMEM(st->buf);
69 st->buf = 0;
70 st->size = 0;
71 st->bits_unused = 0;
72 return 0;
73 }
74
75 if (len < 0)
76 len = strlen(str);
77
78 buf = MALLOC(len);
79 if (!buf) {
80 errno = ENOMEM;
81 return -1;
82 }
83
84 memcpy(buf, str, len);
85 FREEMEM(st->buf);
86 st->buf = buf;
87 st->size = len;
88 st->bits_unused = (len * 8) - bit_len;
89
90 return 0;
91}
92
Daniel Willmann95a112f2016-02-02 16:38:40 +010093void asn1_u32_to_str(OCTET_STRING_t *str, uint32_t *buf, uint32_t in)
94{
95 *buf = htonl(in);
96 str->buf = (uint8_t *) buf;
97 str->size = sizeof(uint32_t);
98}
99
Harald Welte2d4f2bd2016-01-03 17:14:54 +0100100void asn1_u16_to_str(OCTET_STRING_t *str, uint16_t *buf, uint16_t in)
101{
102 *buf = htons(in);
103 str->buf = (uint8_t *) buf;
104 str->size = sizeof(uint16_t);
105}
106
107void asn1_u8_to_str(OCTET_STRING_t *str, uint8_t *buf, uint8_t in)
108{
109 *buf = in;
110 str->buf = buf;
111 str->size = sizeof(uint8_t);
112}
113
114int asn1_strncpy(char *out, const OCTET_STRING_t *in, size_t n)
115{
116 size_t cpylen = n-1;
117
118 if (in->size < cpylen)
119 cpylen = in->size;
120
121 strncpy(out, (char *)in->buf, cpylen);
122 out[cpylen] = '\0';
123
124 return cpylen;
125}
126
Daniel Willmann95a112f2016-02-02 16:38:40 +0100127uint32_t asn1str_to_u32(const OCTET_STRING_t *in)
128{
129 OSMO_ASSERT(in && in->size == sizeof(uint32_t));
130 return ntohl(*(uint32_t *)in->buf);
131}
132
Harald Welte2d4f2bd2016-01-03 17:14:54 +0100133uint16_t asn1str_to_u16(const OCTET_STRING_t *in)
134{
135 OSMO_ASSERT(in && in->size == sizeof(uint16_t));
136 return ntohs(*(uint16_t *)in->buf);
137}
138
139uint8_t asn1str_to_u8(const OCTET_STRING_t *in)
140{
141 OSMO_ASSERT(in && in->size == sizeof(uint8_t));
142 return *(uint8_t *)in->buf;
143}
144
145uint32_t asn1bitstr_to_u32(const BIT_STRING_t *in)
146{
147 OSMO_ASSERT(in && in->size == sizeof(uint32_t));
148
149 return ntohl(*(uint32_t *)in->buf);
150}
151
152uint32_t asn1bitstr_to_u28(const BIT_STRING_t *in)
153{
154 OSMO_ASSERT(in && in->size == sizeof(uint32_t) && in->bits_unused == 4);
155
156 return ntohl(*(uint32_t *)in->buf) >> 4;
157}
158
159uint32_t asn1bitstr_to_u24(const BIT_STRING_t *in)
160{
161 OSMO_ASSERT(in && in->size == 3);
162
163 return ntohl(*(uint32_t *)in->buf) >> 8;
164}