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