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