libnl  3.5.0
data.c
1 /* SPDX-License-Identifier: LGPL-2.1-only */
2 /*
3  * lib/data.c Abstract Data
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation version 2.1
8  * of the License.
9  *
10  * Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
11  */
12 
13 /**
14  * @ingroup core_types
15  * @defgroup data Abstract Data
16  *
17  * Abstract data type representing a binary data blob.
18  *
19  * Related sections in the development guide:
20  * - @core_doc{_abstract_data, Abstract Data}
21  *
22  * @{
23  *
24  * Header
25  * ------
26  * ~~~~{.c}
27  * #include <netlink/data.h>
28  * ~~~~
29  */
30 
31 #include <netlink-private/netlink.h>
32 #include <netlink/netlink.h>
33 #include <netlink/utils.h>
34 #include <linux/socket.h>
35 
36 /**
37  * @name General
38  * @{
39  */
40 
41 /**
42  * Allocate a new abstract data object.
43  * @arg buf Data buffer containing the actual data.
44  * @arg size Size of data buffer.
45  *
46  * Allocates a new abstract data and copies the specified data
47  * buffer into the new handle.
48  *
49  * @return Newly allocated data handle or NULL
50  */
51 struct nl_data *nl_data_alloc(const void *buf, size_t size)
52 {
53  struct nl_data *data;
54 
55  data = calloc(1, sizeof(*data));
56  if (!data)
57  goto errout;
58 
59  data->d_data = calloc(1, size);
60  if (!data->d_data) {
61  free(data);
62  goto errout;
63  }
64 
65  data->d_size = size;
66 
67  if (buf)
68  memcpy(data->d_data, buf, size);
69 
70  return data;
71 errout:
72  return NULL;
73 }
74 
75 /**
76  * Allocate abstract data object based on netlink attribute.
77  * @arg nla Netlink attribute of unspecific type.
78  *
79  * Allocates a new abstract data and copies the payload of the
80  * attribute to the abstract data object.
81  *
82  * @see nla_data_alloc
83  * @return Newly allocated data handle or NULL
84  */
85 struct nl_data *nl_data_alloc_attr(const struct nlattr *nla)
86 {
87  return nl_data_alloc(nla_data(nla), nla_len(nla));
88 }
89 
90 /**
91  * Clone an abstract data object.
92  * @arg src Abstract data object
93  *
94  * @return Cloned object or NULL
95  */
96 struct nl_data *nl_data_clone(const struct nl_data *src)
97 {
98  return nl_data_alloc(src->d_data, src->d_size);
99 }
100 
101 /**
102  * Append data to an abstract data object.
103  * @arg data Abstract data object.
104  * @arg buf Data buffer containing the data to be appended.
105  * @arg size Size of data to be apppended.
106  *
107  * Reallocates an abstract data and copies the specified data
108  * buffer into the new handle.
109  *
110  * @return 0 on success or a negative error code
111  */
112 int nl_data_append(struct nl_data *data, const void *buf, size_t size)
113 {
114  if (size > 0) {
115  char *d_data = realloc(data->d_data, data->d_size + size);
116  if (!d_data)
117  return -NLE_NOMEM;
118 
119  if (buf)
120  memcpy(d_data + data->d_size, buf, size);
121  else
122  memset(d_data + data->d_size, 0, size);
123 
124  data->d_data = d_data;
125  data->d_size += size;
126  }
127 
128  return 0;
129 }
130 
131 /**
132  * Free an abstract data object.
133  * @arg data Abstract data object.
134  */
135 void nl_data_free(struct nl_data *data)
136 {
137  if (data)
138  free(data->d_data);
139 
140  free(data);
141 }
142 
143 /** @} */
144 
145 /**
146  * @name Attribute Access
147  * @{
148  */
149 
150 /**
151  * Get data buffer of abstract data object.
152  * @arg data Abstract data object.
153  * @return Data buffer or NULL if empty.
154  */
155 void *nl_data_get(const struct nl_data *data)
156 {
157  if (data->d_size > 0)
158  return (void*)data->d_data;
159  return NULL;
160 }
161 
162 /**
163  * Get size of data buffer of abstract data object.
164  * @arg data Abstract data object.
165  * @return Size of data buffer.
166  */
167 size_t nl_data_get_size(const struct nl_data *data)
168 {
169  return data->d_size;
170 }
171 
172 /** @} */
173 
174 /**
175  * @name Misc
176  * @{
177  */
178 
179 /**
180  * Compare two abstract data objects.
181  * @arg a Abstract data object.
182  * @arg b Another abstract data object.
183  * @return An integer less than, equal to, or greater than zero if
184  * a is found, respectively, to be less than, to match, or
185  * be greater than b.
186  */
187 int nl_data_cmp(const struct nl_data *a, const struct nl_data *b)
188 {
189  const void *a_ = nl_data_get(a);
190  const void *b_ = nl_data_get(b);
191 
192  if (a_ && b_)
193  return memcmp(a_, b_, nl_data_get_size(a));
194  else
195  return -1;
196 }
197 
198 /** @} */
199 /** @} */
void * nl_data_get(const struct nl_data *data)
Get data buffer of abstract data object.
Definition: data.c:155
size_t nl_data_get_size(const struct nl_data *data)
Get size of data buffer of abstract data object.
Definition: data.c:167
struct nl_data * nl_data_alloc_attr(const struct nlattr *nla)
Allocate abstract data object based on netlink attribute.
Definition: data.c:85
int nl_data_append(struct nl_data *data, const void *buf, size_t size)
Append data to an abstract data object.
Definition: data.c:112
void * nla_data(const struct nlattr *nla)
Return pointer to the payload section.
Definition: attr.c:121
int nla_len(const struct nlattr *nla)
Return length of the payload .
Definition: attr.c:132
struct nl_data * nl_data_clone(const struct nl_data *src)
Clone an abstract data object.
Definition: data.c:96
struct nl_data * nl_data_alloc(const void *buf, size_t size)
Allocate a new abstract data object.
Definition: data.c:51
int nl_data_cmp(const struct nl_data *a, const struct nl_data *b)
Compare two abstract data objects.
Definition: data.c:187
void nl_data_free(struct nl_data *data)
Free an abstract data object.
Definition: data.c:135