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