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 /** @} */
struct nl_addr * nl_addr_clone(const struct nl_addr *addr)
Clone existing abstract address object.
Definition: addr.c:494
Dump object briefly on one line.
Definition: types.h:22
void * nlmsg_data(const struct nlmsghdr *nlh)
Return pointer to message payload.
Definition: msg.c:107
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
void nl_object_get(struct nl_object *obj)
Acquire a reference on a object.
Definition: object.c:205
char * idiagnl_exts2str(uint8_t attrs, char *buf, size_t len)
Convert inet diag extension flags to a string.
Definition: idiag.c:207
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
struct nl_addr * nl_addr_get(struct nl_addr *addr)
Increase the reference counter of an abstract address.
Definition: addr.c:524
Dump all attributes but no statistics.
Definition: types.h:23
void nl_object_put(struct nl_object *obj)
Release a reference from an object.
Definition: object.c:216
void nl_addr_put(struct nl_addr *addr)
Decrease the reference counter of an abstract address.
Definition: addr.c:540
Dumping parameters.
Definition: types.h:33
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
Definition: utils.c:962
char * idiagnl_state2str(int state, char *buf, size_t len)
Convert inet diag socket states to strings.
Definition: idiag.c:110
Dump all attributes including statistics.
Definition: types.h:24
char * nl_addr2str(const struct nl_addr *addr, char *buf, size_t size)
Convert abstract address object to character string.
Definition: addr.c:1000