source: mainline/uspace/srv/net/loopip/loopip.c@ 1d24ad3

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 1d24ad3 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: 5.8 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 loopip
30 * @{
31 */
32/**
33 * @file
34 * @brief Loopback IP link provider
35 */
36
37#include <adt/prodcons.h>
38#include <async.h>
39#include <errno.h>
40#include <inet/iplink_srv.h>
41#include <inet/addr.h>
42#include <io/log.h>
43#include <loc.h>
44#include <stdio.h>
45#include <stdlib.h>
46
47#define NAME "loopip"
48
49static int loopip_open(iplink_srv_t *srv);
50static int loopip_close(iplink_srv_t *srv);
51static int loopip_send(iplink_srv_t *srv, iplink_sdu_t *sdu);
52static int loopip_get_mtu(iplink_srv_t *srv, size_t *mtu);
53static int loopip_addr_add(iplink_srv_t *srv, inet_addr_t *addr);
54static int loopip_addr_remove(iplink_srv_t *srv, inet_addr_t *addr);
55
56static void loopip_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg);
57
58static iplink_ops_t loopip_iplink_ops = {
59 .open = loopip_open,
60 .close = loopip_close,
61 .send = loopip_send,
62 .get_mtu = loopip_get_mtu,
63 .addr_add = loopip_addr_add,
64 .addr_remove = loopip_addr_remove
65};
66
67static iplink_srv_t loopip_iplink;
68static prodcons_t loopip_rcv_queue;
69
70typedef struct {
71 link_t link;
72
73 uint16_t af;
74 iplink_recv_sdu_t sdu;
75} rqueue_entry_t;
76
77static int loopip_recv_fibril(void *arg)
78{
79 while (true) {
80 log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip_recv_fibril(): Wait for one item");
81 link_t *link = prodcons_consume(&loopip_rcv_queue);
82 rqueue_entry_t *rqe =
83 list_get_instance(link, rqueue_entry_t, link);
84
85 (void) iplink_ev_recv(&loopip_iplink, &rqe->sdu, rqe->af);
86
87 free(rqe->sdu.data);
88 free(rqe);
89 }
90
91 return 0;
92}
93
94static int loopip_init(void)
95{
96 async_set_client_connection(loopip_client_conn);
97
98 int rc = loc_server_register(NAME);
99 if (rc != EOK) {
100 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering server.");
101 return rc;
102 }
103
104 iplink_srv_init(&loopip_iplink);
105 loopip_iplink.ops = &loopip_iplink_ops;
106 loopip_iplink.arg = NULL;
107
108 prodcons_initialize(&loopip_rcv_queue);
109
110 const char *svc_name = "net/loopback";
111 service_id_t sid;
112 rc = loc_service_register(svc_name, &sid);
113 if (rc != EOK) {
114 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering service %s.",
115 svc_name);
116 return rc;
117 }
118
119 category_id_t iplink_cat;
120 rc = loc_category_get_id("iplink", &iplink_cat, IPC_FLAG_BLOCKING);
121 if (rc != EOK) {
122 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed resolving category 'iplink'.");
123 return rc;
124 }
125
126 rc = loc_service_add_to_cat(sid, iplink_cat);
127 if (rc != EOK) {
128 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed adding %s to category.",
129 svc_name);
130 return rc;
131 }
132
133 fid_t fid = fibril_create(loopip_recv_fibril, NULL);
134 if (fid == 0)
135 return ENOMEM;
136
137 fibril_add_ready(fid);
138
139 return EOK;
140}
141
142static void loopip_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
143{
144 log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip_client_conn()");
145 iplink_conn(iid, icall, &loopip_iplink);
146}
147
148static int loopip_open(iplink_srv_t *srv)
149{
150 log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip_open()");
151 return EOK;
152}
153
154static int loopip_close(iplink_srv_t *srv)
155{
156 log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip_close()");
157 return EOK;
158}
159
160static int loopip_send(iplink_srv_t *srv, iplink_sdu_t *sdu)
161{
162 log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip_send()");
163
164 addr32_t src_v4;
165 addr128_t src_v6;
166 uint16_t src_af = inet_addr_get(&sdu->src, &src_v4, &src_v6);
167
168 addr32_t dest_v4;
169 addr128_t dest_v6;
170 uint16_t dest_af = inet_addr_get(&sdu->dest, &dest_v4, &dest_v6);
171
172 if (src_af != dest_af)
173 return EINVAL;
174
175 rqueue_entry_t *rqe = calloc(1, sizeof(rqueue_entry_t));
176 if (rqe == NULL)
177 return ENOMEM;
178
179 /*
180 * Clone SDU
181 */
182 rqe->af = src_af;
183 rqe->sdu.data = malloc(sdu->size);
184 if (rqe->sdu.data == NULL) {
185 free(rqe);
186 return ENOMEM;
187 }
188
189 memcpy(rqe->sdu.data, sdu->data, sdu->size);
190 rqe->sdu.size = sdu->size;
191
192 /*
193 * Insert to receive queue
194 */
195 prodcons_produce(&loopip_rcv_queue, &rqe->link);
196
197 return EOK;
198}
199
200static int loopip_get_mtu(iplink_srv_t *srv, size_t *mtu)
201{
202 log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip_get_mtu()");
203 *mtu = 1500;
204 return EOK;
205}
206
207static int loopip_addr_add(iplink_srv_t *srv, inet_addr_t *addr)
208{
209 return EOK;
210}
211
212static int loopip_addr_remove(iplink_srv_t *srv, inet_addr_t *addr)
213{
214 return EOK;
215}
216
217int main(int argc, char *argv[])
218{
219 printf("%s: HelenOS loopback IP link provider\n", NAME);
220
221 int rc = log_init(NAME);
222 if (rc != EOK) {
223 printf("%s: Failed to initialize logging.\n", NAME);
224 return rc;
225 }
226
227 rc = loopip_init();
228 if (rc != EOK)
229 return rc;
230
231 printf("%s: Accepting connections.\n", NAME);
232 task_retval(0);
233 async_manager();
234
235 /* Not reached */
236 return 0;
237}
238
239/** @}
240 */
Note: See TracBrowser for help on using the repository browser.