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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 47f5a77 was 30c5d13, checked in by Martin Decky <martin@…>, 12 years ago

restore accidentally removed iaf_addr lookup functionality

  • Property mode set to 100644
File size: 7.3 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, link) {
118 inet_addrobj_t *naddr = list_get_instance(link,
119 inet_addrobj_t, addr_list);
120
121 switch (find) {
122 case iaf_net:
123 if (inet_naddr_compare_mask(&naddr->naddr, addr)) {
124 fibril_mutex_unlock(&addr_list_lock);
125 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find: found %p",
126 naddr);
127 return naddr;
128 }
129 break;
130 case iaf_addr:
131 if (inet_naddr_compare(&naddr->naddr, addr)) {
132 fibril_mutex_unlock(&addr_list_lock);
133 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find: found %p",
134 naddr);
135 return naddr;
136 }
137 break;
138 }
139 }
140
141 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find: Not found");
142 fibril_mutex_unlock(&addr_list_lock);
143
144 return NULL;
145}
146
147/** Find address object on a link, with a specific name.
148 *
149 * @param name Address object name
150 * @param ilink Inet link
151 * @return Address object
152 */
153static inet_addrobj_t *inet_addrobj_find_by_name_locked(const char *name, inet_link_t *ilink)
154{
155 assert(fibril_mutex_is_locked(&addr_list_lock));
156
157 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find_by_name_locked('%s', '%s')",
158 name, ilink->svc_name);
159
160 list_foreach(addr_list, link) {
161 inet_addrobj_t *naddr = list_get_instance(link,
162 inet_addrobj_t, addr_list);
163
164 if (naddr->ilink == ilink && str_cmp(naddr->name, name) == 0) {
165 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find_by_name_locked: found %p",
166 naddr);
167 return naddr;
168 }
169 }
170
171 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find_by_name_locked: Not found");
172
173 return NULL;
174}
175
176
177/** Find address object on a link, with a specific name.
178 *
179 * @param name Address object name
180 * @param ilink Inet link
181 * @return Address object
182 */
183inet_addrobj_t *inet_addrobj_find_by_name(const char *name, inet_link_t *ilink)
184{
185 inet_addrobj_t *aobj;
186
187 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find_by_name('%s', '%s')",
188 name, ilink->svc_name);
189
190 fibril_mutex_lock(&addr_list_lock);
191 aobj = inet_addrobj_find_by_name_locked(name, ilink);
192 fibril_mutex_unlock(&addr_list_lock);
193
194 return aobj;
195}
196
197/** Find address object with the given ID.
198 *
199 * @param id Address object ID
200 * @return Address object
201 */
202inet_addrobj_t *inet_addrobj_get_by_id(sysarg_t id)
203{
204 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_get_by_id(%zu)", (size_t)id);
205
206 fibril_mutex_lock(&addr_list_lock);
207
208 list_foreach(addr_list, link) {
209 inet_addrobj_t *naddr = list_get_instance(link,
210 inet_addrobj_t, addr_list);
211
212 if (naddr->id == id) {
213 fibril_mutex_unlock(&addr_list_lock);
214 return naddr;
215 }
216 }
217
218 fibril_mutex_unlock(&addr_list_lock);
219
220 return NULL;
221}
222
223/** Send datagram from address object */
224int inet_addrobj_send_dgram(inet_addrobj_t *addr, inet_addr_t *ldest,
225 inet_dgram_t *dgram, uint8_t proto, uint8_t ttl, int df)
226{
227 inet_addr_t lsrc_addr;
228 inet_naddr_addr(&addr->naddr, &lsrc_addr);
229
230 addr32_t lsrc_v4;
231 addr128_t lsrc_v6;
232 uint16_t lsrc_af = inet_addr_get(&lsrc_addr, &lsrc_v4, &lsrc_v6);
233
234 addr32_t ldest_v4;
235 addr128_t ldest_v6;
236 uint16_t ldest_af = inet_addr_get(ldest, &ldest_v4, &ldest_v6);
237
238 if (lsrc_af != ldest_af)
239 return EINVAL;
240
241 int rc;
242 addr48_t ldest_mac;
243
244 switch (ldest_af) {
245 case AF_INET:
246 return inet_link_send_dgram(addr->ilink, lsrc_v4, ldest_v4,
247 dgram, proto, ttl, df);
248 case AF_INET6:
249 /*
250 * Translate local destination IPv6 address.
251 */
252 rc = ndp_translate(lsrc_v6, ldest_v6, ldest_mac, addr->ilink);
253 if (rc != EOK)
254 return rc;
255
256 return inet_link_send_dgram6(addr->ilink, ldest_mac, dgram,
257 proto, ttl, df);
258 }
259
260 return ENOTSUP;
261}
262
263/** Get IDs of all address objects. */
264int inet_addrobj_get_id_list(sysarg_t **rid_list, size_t *rcount)
265{
266 sysarg_t *id_list;
267 size_t count, i;
268
269 fibril_mutex_lock(&addr_list_lock);
270 count = list_count(&addr_list);
271
272 id_list = calloc(count, sizeof(sysarg_t));
273 if (id_list == NULL) {
274 fibril_mutex_unlock(&addr_list_lock);
275 return ENOMEM;
276 }
277
278 i = 0;
279 list_foreach(addr_list, link) {
280 inet_addrobj_t *addr = list_get_instance(link,
281 inet_addrobj_t, addr_list);
282
283 id_list[i++] = addr->id;
284 }
285
286 fibril_mutex_unlock(&addr_list_lock);
287
288 *rid_list = id_list;
289 *rcount = count;
290
291 return EOK;
292}
293
294/** @}
295 */
Note: See TracBrowser for help on using the repository browser.