libnl 3.7.0
idiag_req_obj.c
1/* SPDX-License-Identifier: LGPL-2.1-only */
2/*
3 * Copyright (c) 2013 Sassano Systems LLC <joe@sassanosystems.com>
4 */
5
6#include <netlink-private/netlink.h>
7#include <netlink/idiag/req.h>
8#include <linux/inet_diag.h>
9
10/**
11 * @ingroup idiag
12 * @defgroup idiagnl_req Inet Diag Requests
13 *
14 * @details
15 * @idiagnl_doc{idiagnl_req, Inet Diag Request Documentation}
16 * @{
17 */
18struct idiagnl_req *idiagnl_req_alloc(void)
19{
20 return (struct idiagnl_req *) nl_object_alloc(&idiagnl_req_obj_ops);
21}
22
23void idiagnl_req_get(struct idiagnl_req *req)
24{
25 nl_object_get((struct nl_object *) req);
26}
27
28void idiagnl_req_put(struct idiagnl_req *req)
29{
30 nl_object_put((struct nl_object *) req);
31}
32
33/**
34 * @name Attributes
35 * @{
36 */
37
38uint8_t idiagnl_req_get_family(const struct idiagnl_req *req)
39{
40 return req->idiag_family;
41}
42
43void idiagnl_req_set_family(struct idiagnl_req *req, uint8_t family)
44{
45 req->idiag_family = family;
46}
47
48uint8_t idiagnl_req_get_ext(const struct idiagnl_req *req)
49{
50 return req->idiag_ext;
51}
52
53void idiagnl_req_set_ext(struct idiagnl_req *req, uint8_t ext)
54{
55 req->idiag_ext = ext;
56}
57
58uint32_t idiagnl_req_get_ifindex(const struct idiagnl_req *req)
59{
60 return req->idiag_ifindex;
61}
62
63void idiagnl_req_set_ifindex(struct idiagnl_req *req, uint32_t ifindex)
64{
65 req->idiag_ifindex = ifindex;
66}
67
68uint32_t idiagnl_req_get_states(const struct idiagnl_req *req)
69{
70 return req->idiag_states;
71}
72
73void idiagnl_req_set_states(struct idiagnl_req *req, uint32_t states)
74{
75 req->idiag_states = states;
76}
77
78uint32_t idiagnl_req_get_dbs(const struct idiagnl_req *req)
79{
80 return req->idiag_dbs;
81}
82
83void idiagnl_req_set_dbs(struct idiagnl_req *req, uint32_t dbs)
84{
85 req->idiag_dbs = dbs;
86}
87
88struct nl_addr *idiagnl_req_get_src(const struct idiagnl_req *req)
89{
90 return req->idiag_src;
91}
92
93int idiagnl_req_set_src(struct idiagnl_req *req, struct nl_addr *addr)
94{
95 if (req->idiag_src)
96 nl_addr_put(req->idiag_src);
97
98 nl_addr_get(addr);
99 req->idiag_src = addr;
100
101 return 0;
102}
103
104struct nl_addr *idiagnl_req_get_dst(const struct idiagnl_req *req)
105{
106 return req->idiag_dst;
107}
108
109int idiagnl_req_set_dst(struct idiagnl_req *req, struct nl_addr *addr)
110{
111 if (req->idiag_dst)
112 nl_addr_put(req->idiag_dst);
113
114 nl_addr_get(addr);
115 req->idiag_dst = addr;
116
117 return 0;
118}
119
120/** @} */
121
122static void idiag_req_dump_line(struct nl_object *a, struct nl_dump_params *p)
123{
124 struct idiagnl_req *req = (struct idiagnl_req *) a;
125 char buf[64] = { 0 };
126
127 nl_dump_line(p, "%s ", nl_af2str(req->idiag_family, buf, sizeof(buf)));
128 nl_dump(p, "src %s ", nl_addr2str(req->idiag_src, buf, sizeof(buf)));
129 nl_dump(p, "dst %s ", nl_addr2str(req->idiag_dst, buf, sizeof(buf)));
130 nl_dump(p, "iif %d ", req->idiag_ifindex);
131 nl_dump(p, "\n");
132}
133
134static void idiag_req_dump_details(struct nl_object *a, struct nl_dump_params *p)
135{
136 struct idiagnl_req *req = (struct idiagnl_req *) a;
137 char buf[64];
138
139 nl_dump_line(p, " ");
140 nl_dump(p, "%s ", nl_af2str(req->idiag_family, buf, sizeof(buf)));
141 nl_dump(p, "exts %s ",
142 idiagnl_exts2str(req->idiag_ext, buf, sizeof(buf)));
143 nl_dump(p, "src %s ", nl_addr2str(req->idiag_src, buf, sizeof(buf)));
144 nl_dump(p, "dst %s ", nl_addr2str(req->idiag_dst, buf, sizeof(buf)));
145 nl_dump(p, "iif %d ", req->idiag_ifindex);
146 nl_dump(p, "states %s ", idiagnl_state2str(req->idiag_states, buf,
147 sizeof(buf)));
148 nl_dump(p, "dbs %d", req->idiag_dbs);
149 nl_dump(p, "\n");
150}
151
152static void idiag_req_dump_stats(struct nl_object *obj, struct nl_dump_params *p)
153{
154 idiag_req_dump_details(obj, p);
155}
156
157static void idiagnl_req_free(struct nl_object *a)
158{
159 struct idiagnl_req *req = (struct idiagnl_req *) a;
160 if (a == NULL)
161 return;
162
163 nl_addr_put(req->idiag_src);
164 nl_addr_put(req->idiag_dst);
165}
166
167static int idiagnl_req_clone(struct nl_object *_dst, struct nl_object *_src)
168{
169 struct idiagnl_req *dst = (struct idiagnl_req *) _dst;
170 struct idiagnl_req *src = (struct idiagnl_req *) _src;
171
172 src->idiag_src = NULL;
173 src->idiag_dst = NULL;
174
175 if (src->idiag_src)
176 if (!(dst->idiag_src = nl_addr_clone(src->idiag_src)))
177 return -NLE_NOMEM;
178
179 if (src->idiag_dst)
180 if (!(dst->idiag_dst = nl_addr_clone(src->idiag_dst)))
181 return -NLE_NOMEM;
182
183 return 0;
184}
185
186int idiagnl_req_parse(struct nlmsghdr *nlh, struct idiagnl_req **result)
187{
188 struct idiagnl_req *req = NULL;
189 struct inet_diag_req *raw_req = NULL;
190 struct nl_addr *src = NULL, *dst = NULL;
191 int err = 0;
192
193 req = idiagnl_req_alloc();
194 if (!req)
195 goto errout_nomem;
196
197 raw_req = nlmsg_data(nlh);
198 req->idiag_family = raw_req->idiag_family;
199 req->idiag_ext = raw_req->idiag_ext;
200 req->idiag_states = raw_req->idiag_states;
201 req->idiag_dbs = raw_req->idiag_dbs;
202 req->idiag_ifindex = raw_req->id.idiag_if;
203
204 dst = nl_addr_build(raw_req->idiag_family, raw_req->id.idiag_dst,
205 sizeof(raw_req->id.idiag_dst));
206 if (!dst)
207 goto errout_nomem;
208
209 err = idiagnl_req_set_dst(req, dst);
210 if (err < 0)
211 goto errout;
212
213 nl_addr_put(dst);
214
215 src = nl_addr_build(raw_req->idiag_family, raw_req->id.idiag_src,
216 sizeof(raw_req->id.idiag_src));
217 if (!src)
218 goto errout_nomem;
219
220 err = idiagnl_req_set_src(req, src);
221 if (err < 0)
222 goto errout;
223
224 nl_addr_put(src);
225
226 *result = req;
227 return 0;
228
229errout:
230 idiagnl_req_put(req);
231 return err;
232
233errout_nomem:
234 err = -NLE_NOMEM;
235 goto errout;
236}
237
238/** @cond SKIP */
239struct nl_object_ops idiagnl_req_obj_ops = {
240 .oo_name = "idiag/idiag_req",
241 .oo_size = sizeof(struct idiagnl_req),
242 .oo_free_data = idiagnl_req_free,
243 .oo_clone = idiagnl_req_clone,
244 .oo_dump = {
245 [NL_DUMP_LINE] = idiag_req_dump_line,
246 [NL_DUMP_DETAILS] = idiag_req_dump_details,
247 [NL_DUMP_STATS] = idiag_req_dump_stats,
248 },
249};
250/** @endcond */
251
252/** @} */
struct nl_addr * nl_addr_get(struct nl_addr *addr)
Increase the reference counter of an abstract address.
Definition: addr.c:522
struct nl_addr * nl_addr_build(int family, const void *buf, size_t size)
Allocate abstract address based on a binary address.
Definition: addr.c:211
struct nl_addr * nl_addr_clone(const struct nl_addr *addr)
Clone existing abstract address object.
Definition: addr.c:492
char * nl_addr2str(const struct nl_addr *addr, char *buf, size_t size)
Convert abstract address object to character string.
Definition: addr.c:998
void nl_addr_put(struct nl_addr *addr)
Decrease the reference counter of an abstract address.
Definition: addr.c:538
char * idiagnl_state2str(int state, char *buf, size_t len)
Convert inet diag socket states to strings.
Definition: idiag.c:103
char * idiagnl_exts2str(uint8_t attrs, char *buf, size_t len)
Convert inet diag extension flags to a string.
Definition: idiag.c:200
void * nlmsg_data(const struct nlmsghdr *nlh)
Return pointer to message payload.
Definition: msg.c:100
void nl_object_put(struct nl_object *obj)
Release a reference from an object.
Definition: object.c:214
void nl_object_get(struct nl_object *obj)
Acquire a reference on a object.
Definition: object.c:203
struct nl_object * nl_object_alloc(struct nl_object_ops *ops)
Allocate a new object of kind specified by the operations handle.
Definition: object.c:48
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
Definition: utils.c:955
@ NL_DUMP_STATS
Dump all attributes including statistics.
Definition: types.h:18
@ NL_DUMP_LINE
Dump object briefly on one line.
Definition: types.h:16
@ NL_DUMP_DETAILS
Dump all attributes but no statistics.
Definition: types.h:17
Dumping parameters.
Definition: types.h:28