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

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

add basic infrastructure for IPv6 (inactive)
make inet_addr_t a universal address type

  • Property mode set to 100644
File size: 6.4 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 "addrobj.h"
45#include "inetsrv.h"
46#include "inet_link.h"
47
48static inet_addrobj_t *inet_addrobj_find_by_name_locked(const char *, inet_link_t *);
49
50static FIBRIL_MUTEX_INITIALIZE(addr_list_lock);
51static LIST_INITIALIZE(addr_list);
52static sysarg_t addr_id = 0;
53
54inet_addrobj_t *inet_addrobj_new(void)
55{
56 inet_addrobj_t *addr = calloc(1, sizeof(inet_addrobj_t));
57
58 if (addr == NULL) {
59 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed allocating address object. "
60 "Out of memory.");
61 return NULL;
62 }
63
64 link_initialize(&addr->addr_list);
65 fibril_mutex_lock(&addr_list_lock);
66 addr->id = ++addr_id;
67 fibril_mutex_unlock(&addr_list_lock);
68
69 return addr;
70}
71
72void inet_addrobj_delete(inet_addrobj_t *addr)
73{
74 if (addr->name != NULL)
75 free(addr->name);
76 free(addr);
77}
78
79int inet_addrobj_add(inet_addrobj_t *addr)
80{
81 inet_addrobj_t *aobj;
82
83 fibril_mutex_lock(&addr_list_lock);
84 aobj = inet_addrobj_find_by_name_locked(addr->name, addr->ilink);
85 if (aobj != NULL) {
86 /* Duplicate address name */
87 fibril_mutex_unlock(&addr_list_lock);
88 return EEXISTS;
89 }
90
91 list_append(&addr->addr_list, &addr_list);
92 fibril_mutex_unlock(&addr_list_lock);
93
94 return EOK;
95}
96
97void inet_addrobj_remove(inet_addrobj_t *addr)
98{
99 fibril_mutex_lock(&addr_list_lock);
100 list_remove(&addr->addr_list);
101 fibril_mutex_unlock(&addr_list_lock);
102}
103
104/** Find address object matching address @a addr.
105 *
106 * @param addr Address
107 * @oaram find iaf_net to find network (using mask),
108 * iaf_addr to find local address (exact match)
109 *
110 */
111inet_addrobj_t *inet_addrobj_find(inet_addr_t *addr, inet_addrobj_find_t find)
112{
113 fibril_mutex_lock(&addr_list_lock);
114
115 list_foreach(addr_list, link) {
116 inet_addrobj_t *naddr = list_get_instance(link,
117 inet_addrobj_t, addr_list);
118
119 if (inet_naddr_compare_mask(&naddr->naddr, addr)) {
120 fibril_mutex_unlock(&addr_list_lock);
121 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find: found %p",
122 naddr);
123 return naddr;
124 }
125 }
126
127 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find: Not found");
128 fibril_mutex_unlock(&addr_list_lock);
129
130 return NULL;
131}
132
133/** Find address object on a link, with a specific name.
134 *
135 * @param name Address object name
136 * @param ilink Inet link
137 * @return Address object
138 */
139static inet_addrobj_t *inet_addrobj_find_by_name_locked(const char *name, inet_link_t *ilink)
140{
141 assert(fibril_mutex_is_locked(&addr_list_lock));
142
143 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find_by_name_locked('%s', '%s')",
144 name, ilink->svc_name);
145
146 list_foreach(addr_list, link) {
147 inet_addrobj_t *naddr = list_get_instance(link,
148 inet_addrobj_t, addr_list);
149
150 if (naddr->ilink == ilink && str_cmp(naddr->name, name) == 0) {
151 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find_by_name_locked: found %p",
152 naddr);
153 return naddr;
154 }
155 }
156
157 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find_by_name_locked: Not found");
158
159 return NULL;
160}
161
162
163/** Find address object on a link, with a specific name.
164 *
165 * @param name Address object name
166 * @param ilink Inet link
167 * @return Address object
168 */
169inet_addrobj_t *inet_addrobj_find_by_name(const char *name, inet_link_t *ilink)
170{
171 inet_addrobj_t *aobj;
172
173 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find_by_name('%s', '%s')",
174 name, ilink->svc_name);
175
176 fibril_mutex_lock(&addr_list_lock);
177 aobj = inet_addrobj_find_by_name_locked(name, ilink);
178 fibril_mutex_unlock(&addr_list_lock);
179
180 return aobj;
181}
182
183/** Find address object with the given ID.
184 *
185 * @param id Address object ID
186 * @return Address object
187 */
188inet_addrobj_t *inet_addrobj_get_by_id(sysarg_t id)
189{
190 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_get_by_id(%zu)", (size_t)id);
191
192 fibril_mutex_lock(&addr_list_lock);
193
194 list_foreach(addr_list, link) {
195 inet_addrobj_t *naddr = list_get_instance(link,
196 inet_addrobj_t, addr_list);
197
198 if (naddr->id == id) {
199 fibril_mutex_unlock(&addr_list_lock);
200 return naddr;
201 }
202 }
203
204 fibril_mutex_unlock(&addr_list_lock);
205
206 return NULL;
207}
208
209/** Send datagram from address object */
210int inet_addrobj_send_dgram(inet_addrobj_t *addr, inet_addr_t *ldest,
211 inet_dgram_t *dgram, uint8_t proto, uint8_t ttl, int df)
212{
213 inet_addr_t lsrc_addr;
214 inet_naddr_addr(&addr->naddr, &lsrc_addr);
215
216 return inet_link_send_dgram(addr->ilink, &lsrc_addr, ldest, dgram,
217 proto, ttl, df);
218}
219
220/** Get IDs of all address objects. */
221int inet_addrobj_get_id_list(sysarg_t **rid_list, size_t *rcount)
222{
223 sysarg_t *id_list;
224 size_t count, i;
225
226 fibril_mutex_lock(&addr_list_lock);
227 count = list_count(&addr_list);
228
229 id_list = calloc(count, sizeof(sysarg_t));
230 if (id_list == NULL) {
231 fibril_mutex_unlock(&addr_list_lock);
232 return ENOMEM;
233 }
234
235 i = 0;
236 list_foreach(addr_list, link) {
237 inet_addrobj_t *addr = list_get_instance(link,
238 inet_addrobj_t, addr_list);
239
240 id_list[i++] = addr->id;
241 }
242
243 fibril_mutex_unlock(&addr_list_lock);
244
245 *rid_list = id_list;
246 *rcount = count;
247
248 return EOK;
249}
250
251/** @}
252 */
Note: See TracBrowser for help on using the repository browser.