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