libnl 3.5.0

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