• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
idiagnl_req_alloc(void)24 struct idiagnl_req *idiagnl_req_alloc(void)
25 {
26 	return (struct idiagnl_req *) nl_object_alloc(&idiagnl_req_obj_ops);
27 }
28 
idiagnl_req_get(struct idiagnl_req * req)29 void idiagnl_req_get(struct idiagnl_req *req)
30 {
31 	nl_object_get((struct nl_object *) req);
32 }
33 
idiagnl_req_put(struct idiagnl_req * req)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 
idiagnl_req_get_family(const struct idiagnl_req * req)44 uint8_t idiagnl_req_get_family(const struct idiagnl_req *req)
45 {
46 	return req->idiag_family;
47 }
48 
idiagnl_req_set_family(struct idiagnl_req * req,uint8_t family)49 void idiagnl_req_set_family(struct idiagnl_req *req, uint8_t family)
50 {
51 	req->idiag_family = family;
52 }
53 
idiagnl_req_get_ext(const struct idiagnl_req * req)54 uint8_t idiagnl_req_get_ext(const struct idiagnl_req *req)
55 {
56 	return req->idiag_ext;
57 }
58 
idiagnl_req_set_ext(struct idiagnl_req * req,uint8_t ext)59 void idiagnl_req_set_ext(struct idiagnl_req *req, uint8_t ext)
60 {
61 	req->idiag_ext = ext;
62 }
63 
idiagnl_req_get_ifindex(const struct idiagnl_req * req)64 uint32_t idiagnl_req_get_ifindex(const struct idiagnl_req *req)
65 {
66 	return req->idiag_ifindex;
67 }
68 
idiagnl_req_set_ifindex(struct idiagnl_req * req,uint32_t ifindex)69 void idiagnl_req_set_ifindex(struct idiagnl_req *req, uint32_t ifindex)
70 {
71 	req->idiag_states = ifindex;
72 }
73 
idiagnl_req_get_states(const struct idiagnl_req * req)74 uint32_t idiagnl_req_get_states(const struct idiagnl_req *req)
75 {
76 	return req->idiag_states;
77 }
78 
idiagnl_req_set_states(struct idiagnl_req * req,uint32_t states)79 void idiagnl_req_set_states(struct idiagnl_req *req, uint32_t states)
80 {
81 	req->idiag_states = states;
82 }
83 
idiagnl_req_get_dbs(const struct idiagnl_req * req)84 uint32_t idiagnl_req_get_dbs(const struct idiagnl_req *req)
85 {
86 	return req->idiag_dbs;
87 }
88 
idiagnl_req_set_dbs(struct idiagnl_req * req,uint32_t dbs)89 void idiagnl_req_set_dbs(struct idiagnl_req *req, uint32_t dbs)
90 {
91 	req->idiag_dbs = dbs;
92 }
93 
idiagnl_req_get_src(const struct idiagnl_req * req)94 struct nl_addr *idiagnl_req_get_src(const struct idiagnl_req *req)
95 {
96 	return req->idiag_src;
97 }
98 
idiagnl_req_set_src(struct idiagnl_req * req,struct nl_addr * addr)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 
idiagnl_req_get_dst(const struct idiagnl_req * req)110 struct nl_addr *idiagnl_req_get_dst(const struct idiagnl_req *req)
111 {
112 	return req->idiag_dst;
113 }
114 
idiagnl_req_set_dst(struct idiagnl_req * req,struct nl_addr * addr)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 
idiag_req_dump_line(struct nl_object * a,struct nl_dump_params * p)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 
idiag_req_dump_details(struct nl_object * a,struct nl_dump_params * p)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 
idiag_req_dump_stats(struct nl_object * obj,struct nl_dump_params * p)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 
idiagnl_req_free(struct nl_object * a)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 
idiagnl_req_clone(struct nl_object * _dst,struct nl_object * _src)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 
idiagnl_req_parse(struct nlmsghdr * nlh,struct idiagnl_req ** result)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 /** @} */
256