source: mainline/uspace/srv/net/inetsrv/addrobj.c@ b8b1adb1

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since b8b1adb1 was feeac0d, checked in by Jiri Svoboda <jiri@…>, 12 years ago

Simplify use of list_foreach.

  • Property mode set to 100644
File size: 7.1 KB
Line 
1/*
2 * Copyright (c) 2012 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup inet
30 * @{
31 */
32/**
33 * @file
34 * @brief
35 */
36
37#include <bitops.h>
38#include <errno.h>
39#include <fibril_synch.h>
40#include <io/log.h>
41#include <ipc/loc.h>
42#include <stdlib.h>
43#include <str.h>
44#include <net/socket_codes.h>
45#include "addrobj.h"
46#include "inetsrv.h"
47#include "inet_link.h"
48#include "ndp.h"
49
50static inet_addrobj_t *inet_addrobj_find_by_name_locked(const char *, inet_link_t *);
51
52static FIBRIL_MUTEX_INITIALIZE(addr_list_lock);
53static LIST_INITIALIZE(addr_list);
54static sysarg_t addr_id = 0;
55
56inet_addrobj_t *inet_addrobj_new(void)
57{
58 inet_addrobj_t *addr = calloc(1, sizeof(inet_addrobj_t));
59
60 if (addr == NULL) {
61 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed allocating address object. "
62 "Out of memory.");
63 return NULL;
64 }
65
66 link_initialize(&addr->addr_list);
67 fibril_mutex_lock(&addr_list_lock);
68 addr->id = ++addr_id;
69 fibril_mutex_unlock(&addr_list_lock);
70
71 return addr;
72}
73
74void inet_addrobj_delete(inet_addrobj_t *addr)
75{
76 if (addr->name != NULL)
77 free(addr->name);
78 free(addr);
79}
80
81int inet_addrobj_add(inet_addrobj_t *addr)
82{
83 inet_addrobj_t *aobj;
84
85 fibril_mutex_lock(&addr_list_lock);
86 aobj = inet_addrobj_find_by_name_locked(addr->name, addr->ilink);
87 if (aobj != NULL) {
88 /* Duplicate address name */
89 fibril_mutex_unlock(&addr_list_lock);
90 return EEXISTS;
91 }
92
93 list_append(&addr->addr_list, &addr_list);
94 fibril_mutex_unlock(&addr_list_lock);
95
96 return EOK;
97}
98
99void inet_addrobj_remove(inet_addrobj_t *addr)
100{
101 fibril_mutex_lock(&addr_list_lock);
102 list_remove(&addr->addr_list);
103 fibril_mutex_unlock(&addr_list_lock);
104}
105
106/** Find address object matching address @a addr.
107 *
108 * @param addr Address
109 * @oaram find iaf_net to find network (using mask),
110 * iaf_addr to find local address (exact match)
111 *
112 */
113inet_addrobj_t *inet_addrobj_find(inet_addr_t *addr, inet_addrobj_find_t find)
114{
115 fibril_mutex_lock(&addr_list_lock);
116
117 list_foreach(addr_list, addr_list, inet_addrobj_t, naddr) {
118 switch (find) {
119 case iaf_net:
120 if (inet_naddr_compare_mask(&naddr->naddr, addr)) {
121 fibril_mutex_unlock(&addr_list_lock);
122 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find: found %p",
123 naddr);
124 return naddr;
125 }
126 break;
127 case iaf_addr:
128 if (inet_naddr_compare(&naddr->naddr, addr)) {
129 fibril_mutex_unlock(&addr_list_lock);
130 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find: found %p",
131 naddr);
132 return naddr;
133 }
134 break;
135 }
136 }
137
138 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find: Not found");
139 fibril_mutex_unlock(&addr_list_lock);
140
141 return NULL;
142}
143
144/** Find address object on a link, with a specific name.
145 *
146 * @param name Address object name
147 * @param ilink Inet link
148 * @return Address object
149 */
150static inet_addrobj_t *inet_addrobj_find_by_name_locked(const char *name, inet_link_t *ilink)
151{
152 assert(fibril_mutex_is_locked(&addr_list_lock));
153
154 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find_by_name_locked('%s', '%s')",
155 name, ilink->svc_name);
156
157 list_foreach(addr_list, addr_list, inet_addrobj_t, naddr) {
158 if (naddr->ilink == ilink && str_cmp(naddr->name, name) == 0) {
159 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find_by_name_locked: found %p",
160 naddr);
161 return naddr;
162 }
163 }
164
165 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find_by_name_locked: Not found");
166
167 return NULL;
168}
169
170
171/** Find address object on a link, with a specific name.
172 *
173 * @param name Address object name
174 * @param ilink Inet link
175 * @return Address object
176 */
177inet_addrobj_t *inet_addrobj_find_by_name(const char *name, inet_link_t *ilink)
178{
179 inet_addrobj_t *aobj;
180
181 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find_by_name('%s', '%s')",
182 name, ilink->svc_name);
183
184 fibril_mutex_lock(&addr_list_lock);
185 aobj = inet_addrobj_find_by_name_locked(name, ilink);
186 fibril_mutex_unlock(&addr_list_lock);
187
188 return aobj;
189}
190
191/** Find address object with the given ID.
192 *
193 * @param id Address object ID
194 * @return Address object
195 */
196inet_addrobj_t *inet_addrobj_get_by_id(sysarg_t id)
197{
198 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_get_by_id(%zu)", (size_t)id);
199
200 fibril_mutex_lock(&addr_list_lock);
201
202 list_foreach(addr_list, addr_list, inet_addrobj_t, naddr) {
203 if (naddr->id == id) {
204 fibril_mutex_unlock(&addr_list_lock);
205 return naddr;
206 }
207 }
208
209 fibril_mutex_unlock(&addr_list_lock);
210
211 return NULL;
212}
213
214/** Send datagram from address object */
215int inet_addrobj_send_dgram(inet_addrobj_t *addr, inet_addr_t *ldest,
216 inet_dgram_t *dgram, uint8_t proto, uint8_t ttl, int df)
217{
218 inet_addr_t lsrc_addr;
219 inet_naddr_addr(&addr->naddr, &lsrc_addr);
220
221 addr32_t lsrc_v4;
222 addr128_t lsrc_v6;
223 uint16_t lsrc_af = inet_addr_get(&lsrc_addr, &lsrc_v4, &lsrc_v6);
224
225 addr32_t ldest_v4;
226 addr128_t ldest_v6;
227 uint16_t ldest_af = inet_addr_get(ldest, &ldest_v4, &ldest_v6);
228
229 if (lsrc_af != ldest_af)
230 return EINVAL;
231
232 int rc;
233 addr48_t ldest_mac;
234
235 switch (ldest_af) {
236 case AF_INET:
237 return inet_link_send_dgram(addr->ilink, lsrc_v4, ldest_v4,
238 dgram, proto, ttl, df);
239 case AF_INET6:
240 /*
241 * Translate local destination IPv6 address.
242 */
243 rc = ndp_translate(lsrc_v6, ldest_v6, ldest_mac, addr->ilink);
244 if (rc != EOK)
245 return rc;
246
247 return inet_link_send_dgram6(addr->ilink, ldest_mac, dgram,
248 proto, ttl, df);
249 }
250
251 return ENOTSUP;
252}
253
254/** Get IDs of all address objects. */
255int inet_addrobj_get_id_list(sysarg_t **rid_list, size_t *rcount)
256{
257 sysarg_t *id_list;
258 size_t count, i;
259
260 fibril_mutex_lock(&addr_list_lock);
261 count = list_count(&addr_list);
262
263 id_list = calloc(count, sizeof(sysarg_t));
264 if (id_list == NULL) {
265 fibril_mutex_unlock(&addr_list_lock);
266 return ENOMEM;
267 }
268
269 i = 0;
270 list_foreach(addr_list, addr_list, inet_addrobj_t, addr) {
271 id_list[i++] = addr->id;
272 }
273
274 fibril_mutex_unlock(&addr_list_lock);
275
276 *rid_list = id_list;
277 *rcount = count;
278
279 return EOK;
280}
281
282/** @}
283 */
Note: See TracBrowser for help on using the repository browser.