source: mainline/uspace/srv/net/loopip/loopip.c@ edf0d27

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

cstyle (no change in functionality)

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