source: mainline/uspace/srv/net/loopip/loopip.c@ 84a1a54

Last change on this file since 84a1a54 was 84a1a54, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

Wrap returns of errno from main() with EXIT_RC().

Returns of error code from main() prevent type checking when errno_t
and int are considered incompatible. In order to avoid the philosophical
discussion of what should and shouldn't be returned for main(), we simply
wrap the error values and leave the answer to the question for future
generations to decide.

  • Property mode set to 100644
File size: 6.6 KB
RevLine 
[606c369]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>
[c1694b6b]40#include <str_error.h>
[606c369]41#include <inet/iplink_srv.h>
[02a09ed]42#include <inet/addr.h>
[606c369]43#include <io/log.h>
44#include <loc.h>
45#include <stdio.h>
46#include <stdlib.h>
[1c635d6]47#include <task.h>
[606c369]48
[257feec]49#define NAME "loopip"
[606c369]50
51static int loopip_open(iplink_srv_t *srv);
52static int loopip_close(iplink_srv_t *srv);
[02a09ed]53static int loopip_send(iplink_srv_t *srv, iplink_sdu_t *sdu);
[a17356fd]54static int loopip_send6(iplink_srv_t *srv, iplink_sdu6_t *sdu);
[606c369]55static int loopip_get_mtu(iplink_srv_t *srv, size_t *mtu);
[a17356fd]56static int loopip_get_mac48(iplink_srv_t *srv, addr48_t *mac);
[02a09ed]57static int loopip_addr_add(iplink_srv_t *srv, inet_addr_t *addr);
58static int loopip_addr_remove(iplink_srv_t *srv, inet_addr_t *addr);
[606c369]59
60static void loopip_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg);
61
62static iplink_ops_t loopip_iplink_ops = {
63 .open = loopip_open,
64 .close = loopip_close,
65 .send = loopip_send,
[a17356fd]66 .send6 = loopip_send6,
[606c369]67 .get_mtu = loopip_get_mtu,
[a17356fd]68 .get_mac48 = loopip_get_mac48,
[606c369]69 .addr_add = loopip_addr_add,
70 .addr_remove = loopip_addr_remove
71};
72
73static iplink_srv_t loopip_iplink;
74static prodcons_t loopip_rcv_queue;
75
76typedef struct {
77 link_t link;
[02a09ed]78
[417a2ba1]79 /* XXX Version should be part of SDU */
80 ip_ver_t ver;
[02a09ed]81 iplink_recv_sdu_t sdu;
[606c369]82} rqueue_entry_t;
83
84static int loopip_recv_fibril(void *arg)
85{
86 while (true) {
[a1a101d]87 log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip_recv_fibril(): Wait for one item");
[606c369]88 link_t *link = prodcons_consume(&loopip_rcv_queue);
[02a09ed]89 rqueue_entry_t *rqe =
90 list_get_instance(link, rqueue_entry_t, link);
91
[417a2ba1]92 (void) iplink_ev_recv(&loopip_iplink, &rqe->sdu, rqe->ver);
[02a09ed]93
94 free(rqe->sdu.data);
95 free(rqe);
[606c369]96 }
[257feec]97
[606c369]98 return 0;
99}
100
101static int loopip_init(void)
102{
[b688fd8]103 async_set_fallback_port_handler(loopip_client_conn, NULL);
[1038a9c]104
[02a09ed]105 int rc = loc_server_register(NAME);
[606c369]106 if (rc != EOK) {
[a1a101d]107 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering server.");
[606c369]108 return rc;
109 }
[257feec]110
[606c369]111 iplink_srv_init(&loopip_iplink);
112 loopip_iplink.ops = &loopip_iplink_ops;
113 loopip_iplink.arg = NULL;
[257feec]114
[606c369]115 prodcons_initialize(&loopip_rcv_queue);
[02a09ed]116
117 const char *svc_name = "net/loopback";
118 service_id_t sid;
[606c369]119 rc = loc_service_register(svc_name, &sid);
120 if (rc != EOK) {
[02a09ed]121 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering service %s.",
122 svc_name);
[606c369]123 return rc;
124 }
[02a09ed]125
126 category_id_t iplink_cat;
[606c369]127 rc = loc_category_get_id("iplink", &iplink_cat, IPC_FLAG_BLOCKING);
128 if (rc != EOK) {
[a1a101d]129 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed resolving category 'iplink'.");
[606c369]130 return rc;
131 }
[257feec]132
[606c369]133 rc = loc_service_add_to_cat(sid, iplink_cat);
134 if (rc != EOK) {
[02a09ed]135 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed adding %s to category.",
136 svc_name);
[606c369]137 return rc;
138 }
[257feec]139
[606c369]140 fid_t fid = fibril_create(loopip_recv_fibril, NULL);
141 if (fid == 0)
142 return ENOMEM;
[257feec]143
[606c369]144 fibril_add_ready(fid);
[257feec]145
[606c369]146 return EOK;
147}
148
149static void loopip_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
150{
[a1a101d]151 log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip_client_conn()");
[606c369]152 iplink_conn(iid, icall, &loopip_iplink);
153}
154
155static int loopip_open(iplink_srv_t *srv)
156{
[a1a101d]157 log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip_open()");
[606c369]158 return EOK;
159}
160
161static int loopip_close(iplink_srv_t *srv)
162{
[a1a101d]163 log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip_close()");
[606c369]164 return EOK;
165}
166
[02a09ed]167static int loopip_send(iplink_srv_t *srv, iplink_sdu_t *sdu)
[606c369]168{
[a1a101d]169 log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip_send()");
[02a09ed]170
[a17356fd]171 rqueue_entry_t *rqe = calloc(1, sizeof(rqueue_entry_t));
172 if (rqe == NULL)
173 return ENOMEM;
174
175 /*
176 * Clone SDU
177 */
[417a2ba1]178 rqe->ver = ip_v4;
[a17356fd]179 rqe->sdu.data = malloc(sdu->size);
180 if (rqe->sdu.data == NULL) {
181 free(rqe);
182 return ENOMEM;
183 }
184
185 memcpy(rqe->sdu.data, sdu->data, sdu->size);
186 rqe->sdu.size = sdu->size;
[02a09ed]187
[a17356fd]188 /*
189 * Insert to receive queue
190 */
191 prodcons_produce(&loopip_rcv_queue, &rqe->link);
[02a09ed]192
[a17356fd]193 return EOK;
194}
195
196static int loopip_send6(iplink_srv_t *srv, iplink_sdu6_t *sdu)
197{
198 log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip6_send()");
[02a09ed]199
200 rqueue_entry_t *rqe = calloc(1, sizeof(rqueue_entry_t));
[606c369]201 if (rqe == NULL)
202 return ENOMEM;
[257feec]203
[606c369]204 /*
205 * Clone SDU
206 */
[417a2ba1]207 rqe->ver = ip_v6;
[606c369]208 rqe->sdu.data = malloc(sdu->size);
209 if (rqe->sdu.data == NULL) {
210 free(rqe);
211 return ENOMEM;
212 }
[257feec]213
[606c369]214 memcpy(rqe->sdu.data, sdu->data, sdu->size);
215 rqe->sdu.size = sdu->size;
[257feec]216
[606c369]217 /*
218 * Insert to receive queue
219 */
220 prodcons_produce(&loopip_rcv_queue, &rqe->link);
[257feec]221
[606c369]222 return EOK;
223}
224
225static int loopip_get_mtu(iplink_srv_t *srv, size_t *mtu)
226{
[a1a101d]227 log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip_get_mtu()");
[606c369]228 *mtu = 1500;
229 return EOK;
230}
231
[a17356fd]232static int loopip_get_mac48(iplink_srv_t *src, addr48_t *mac)
233{
234 log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip_get_mac48()");
235 return ENOTSUP;
236}
237
[02a09ed]238static int loopip_addr_add(iplink_srv_t *srv, inet_addr_t *addr)
[606c369]239{
240 return EOK;
241}
242
[02a09ed]243static int loopip_addr_remove(iplink_srv_t *srv, inet_addr_t *addr)
[606c369]244{
245 return EOK;
246}
247
248int main(int argc, char *argv[])
249{
[02a09ed]250 printf("%s: HelenOS loopback IP link provider\n", NAME);
251
252 int rc = log_init(NAME);
253 if (rc != EOK) {
[c1694b6b]254 printf("%s: Failed to initialize logging: %s.\n", NAME, str_error(rc));
[84a1a54]255 return EXIT_RC(rc);
[606c369]256 }
[257feec]257
[606c369]258 rc = loopip_init();
[c1694b6b]259 if (rc != EOK) {
260 printf("%s: Failed to initialize loopip: %s.\n", NAME, str_error(rc));
[84a1a54]261 return EXIT_RC(rc);
[c1694b6b]262 }
[02a09ed]263
264 printf("%s: Accepting connections.\n", NAME);
[606c369]265 task_retval(0);
266 async_manager();
[257feec]267
[606c369]268 /* Not reached */
269 return 0;
270}
271
272/** @}
273 */
Note: See TracBrowser for help on using the repository browser.