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

Last change on this file since eec201d was 09ab0a9a, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Fix vertical spacing with new Ccheck revision.

  • Property mode set to 100644
File size: 7.1 KB
RevLine 
[ceba4bed]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>
[0e94b979]38#include <errno.h>
[ceba4bed]39#include <fibril_synch.h>
40#include <io/log.h>
41#include <ipc/loc.h>
42#include <stdlib.h>
[fa101c4]43#include <str.h>
[ceba4bed]44#include "addrobj.h"
[b4ec1ea]45#include "inetsrv.h"
[ceba4bed]46#include "inet_link.h"
[a17356fd]47#include "ndp.h"
[ceba4bed]48
[bf9e6fc]49static inet_addrobj_t *inet_addrobj_find_by_name_locked(const char *, inet_link_t *);
50
[ceba4bed]51static FIBRIL_MUTEX_INITIALIZE(addr_list_lock);
52static LIST_INITIALIZE(addr_list);
[0e94b979]53static sysarg_t addr_id = 0;
[ceba4bed]54
55inet_addrobj_t *inet_addrobj_new(void)
56{
57 inet_addrobj_t *addr = calloc(1, sizeof(inet_addrobj_t));
58
59 if (addr == NULL) {
[a1a101d]60 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed allocating address object. "
[ceba4bed]61 "Out of memory.");
62 return NULL;
63 }
64
65 link_initialize(&addr->addr_list);
[0e94b979]66 fibril_mutex_lock(&addr_list_lock);
67 addr->id = ++addr_id;
68 fibril_mutex_unlock(&addr_list_lock);
[ceba4bed]69
70 return addr;
71}
72
73void inet_addrobj_delete(inet_addrobj_t *addr)
74{
[0e94b979]75 if (addr->name != NULL)
76 free(addr->name);
[ceba4bed]77 free(addr);
78}
79
[b7fd2a0]80errno_t inet_addrobj_add(inet_addrobj_t *addr)
[ceba4bed]81{
[bf9e6fc]82 inet_addrobj_t *aobj;
83
[ceba4bed]84 fibril_mutex_lock(&addr_list_lock);
[bf9e6fc]85 aobj = inet_addrobj_find_by_name_locked(addr->name, addr->ilink);
86 if (aobj != NULL) {
87 /* Duplicate address name */
88 fibril_mutex_unlock(&addr_list_lock);
[8a637a4]89 return EEXIST;
[bf9e6fc]90 }
91
[ceba4bed]92 list_append(&addr->addr_list, &addr_list);
93 fibril_mutex_unlock(&addr_list_lock);
[bf9e6fc]94
95 return EOK;
[ceba4bed]96}
97
98void inet_addrobj_remove(inet_addrobj_t *addr)
99{
100 fibril_mutex_lock(&addr_list_lock);
101 list_remove(&addr->addr_list);
102 fibril_mutex_unlock(&addr_list_lock);
103}
104
[e767dbf]105/** Find address object matching address @a addr.
106 *
[02a09ed]107 * @param addr Address
108 * @oaram find iaf_net to find network (using mask),
109 * iaf_addr to find local address (exact match)
110 *
[e767dbf]111 */
112inet_addrobj_t *inet_addrobj_find(inet_addr_t *addr, inet_addrobj_find_t find)
[ceba4bed]113{
114 fibril_mutex_lock(&addr_list_lock);
[a35b458]115
[feeac0d]116 list_foreach(addr_list, addr_list, inet_addrobj_t, naddr) {
[30c5d13]117 switch (find) {
118 case iaf_net:
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 break;
126 case iaf_addr:
127 if (inet_naddr_compare(&naddr->naddr, addr)) {
128 fibril_mutex_unlock(&addr_list_lock);
129 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find: found %p",
130 naddr);
131 return naddr;
132 }
133 break;
[ceba4bed]134 }
135 }
[a35b458]136
[a1a101d]137 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find: Not found");
[ceba4bed]138 fibril_mutex_unlock(&addr_list_lock);
[a35b458]139
[ceba4bed]140 return NULL;
141}
142
[fa101c4]143/** Find address object on a link, with a specific name.
144 *
145 * @param name Address object name
146 * @param ilink Inet link
147 * @return Address object
148 */
[bf9e6fc]149static inet_addrobj_t *inet_addrobj_find_by_name_locked(const char *name, inet_link_t *ilink)
[fa101c4]150{
[bf9e6fc]151 assert(fibril_mutex_is_locked(&addr_list_lock));
[fa101c4]152
[a1a101d]153 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find_by_name_locked('%s', '%s')",
[bf9e6fc]154 name, ilink->svc_name);
[fa101c4]155
[feeac0d]156 list_foreach(addr_list, addr_list, inet_addrobj_t, naddr) {
[fa101c4]157 if (naddr->ilink == ilink && str_cmp(naddr->name, name) == 0) {
[a1a101d]158 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find_by_name_locked: found %p",
[fa101c4]159 naddr);
160 return naddr;
161 }
162 }
163
[a1a101d]164 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find_by_name_locked: Not found");
[fa101c4]165
166 return NULL;
167}
168
[bf9e6fc]169/** Find address object on a link, with a specific name.
170 *
171 * @param name Address object name
172 * @param ilink Inet link
173 * @return Address object
174 */
175inet_addrobj_t *inet_addrobj_find_by_name(const char *name, inet_link_t *ilink)
176{
177 inet_addrobj_t *aobj;
178
[a1a101d]179 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find_by_name('%s', '%s')",
[bf9e6fc]180 name, ilink->svc_name);
181
182 fibril_mutex_lock(&addr_list_lock);
183 aobj = inet_addrobj_find_by_name_locked(name, ilink);
184 fibril_mutex_unlock(&addr_list_lock);
185
186 return aobj;
187}
188
[8bf672d]189/** Find address object with the given ID.
[0e94b979]190 *
191 * @param id Address object ID
192 * @return Address object
193 */
194inet_addrobj_t *inet_addrobj_get_by_id(sysarg_t id)
195{
[a1a101d]196 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_get_by_id(%zu)", (size_t)id);
[0e94b979]197
198 fibril_mutex_lock(&addr_list_lock);
199
[feeac0d]200 list_foreach(addr_list, addr_list, inet_addrobj_t, naddr) {
[0e94b979]201 if (naddr->id == id) {
202 fibril_mutex_unlock(&addr_list_lock);
203 return naddr;
204 }
205 }
206
207 fibril_mutex_unlock(&addr_list_lock);
208
209 return NULL;
210}
211
[8bf672d]212/** Send datagram from address object */
[b7fd2a0]213errno_t inet_addrobj_send_dgram(inet_addrobj_t *addr, inet_addr_t *ldest,
[8bf672d]214 inet_dgram_t *dgram, uint8_t proto, uint8_t ttl, int df)
[ceba4bed]215{
216 inet_addr_t lsrc_addr;
[a2e3ee6]217 inet_naddr_addr(&addr->naddr, &lsrc_addr);
[f023251]218
[a17356fd]219 addr32_t lsrc_v4;
220 addr128_t lsrc_v6;
[f023251]221 ip_ver_t lsrc_ver = inet_addr_get(&lsrc_addr, &lsrc_v4, &lsrc_v6);
222
[a17356fd]223 addr32_t ldest_v4;
224 addr128_t ldest_v6;
[f023251]225 ip_ver_t ldest_ver = inet_addr_get(ldest, &ldest_v4, &ldest_v6);
226
227 if (lsrc_ver != ldest_ver)
[a17356fd]228 return EINVAL;
[f023251]229
[b7fd2a0]230 errno_t rc;
[a17356fd]231 addr48_t ldest_mac;
[f023251]232
233 switch (ldest_ver) {
234 case ip_v4:
[a17356fd]235 return inet_link_send_dgram(addr->ilink, lsrc_v4, ldest_v4,
236 dgram, proto, ttl, df);
[f023251]237 case ip_v6:
[a17356fd]238 /*
239 * Translate local destination IPv6 address.
240 */
241 rc = ndp_translate(lsrc_v6, ldest_v6, ldest_mac, addr->ilink);
242 if (rc != EOK)
243 return rc;
[f023251]244
[a17356fd]245 return inet_link_send_dgram6(addr->ilink, ldest_mac, dgram,
246 proto, ttl, df);
[f023251]247 default:
248 assert(false);
249 break;
[a17356fd]250 }
[f023251]251
[a17356fd]252 return ENOTSUP;
[ceba4bed]253}
254
[0e94b979]255/** Get IDs of all address objects. */
[b7fd2a0]256errno_t inet_addrobj_get_id_list(sysarg_t **rid_list, size_t *rcount)
[0e94b979]257{
258 sysarg_t *id_list;
259 size_t count, i;
260
261 fibril_mutex_lock(&addr_list_lock);
262 count = list_count(&addr_list);
263
264 id_list = calloc(count, sizeof(sysarg_t));
265 if (id_list == NULL) {
266 fibril_mutex_unlock(&addr_list_lock);
267 return ENOMEM;
268 }
269
270 i = 0;
[feeac0d]271 list_foreach(addr_list, addr_list, inet_addrobj_t, addr) {
[0e94b979]272 id_list[i++] = addr->id;
273 }
274
275 fibril_mutex_unlock(&addr_list_lock);
276
277 *rid_list = id_list;
278 *rcount = count;
279
280 return EOK;
281}
282
[ceba4bed]283/** @}
284 */
Note: See TracBrowser for help on using the repository browser.