source: mainline/uspace/srv/ethip/ethip.c@ fe4310f

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since fe4310f was 4f64a523, checked in by Jiri Svoboda <jiri@…>, 14 years ago

Need to limit iplink to a single client connection.

  • Property mode set to 100644
File size: 5.7 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 ethip
30 * @{
31 */
32/**
33 * @file
34 * @brief IP link provider for Ethernet
35 *
36 * Based on the IETF RFC 894 standard.
37 */
38
39#include <async.h>
40#include <errno.h>
41#include <inet/iplink_srv.h>
42#include <io/log.h>
43#include <loc.h>
44#include <stdio.h>
45#include <stdlib.h>
46
47#include "ethip.h"
48#include "ethip_nic.h"
49#include "pdu.h"
50#include "std.h"
51
52#define NAME "eth"
53
54static int ethip_open(iplink_srv_t *srv);
55static int ethip_close(iplink_srv_t *srv);
56static int ethip_send(iplink_srv_t *srv, iplink_srv_sdu_t *sdu);
57static int ethip_get_mtu(iplink_srv_t *srv, size_t *mtu);
58
59static void ethip_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg);
60
61static iplink_ops_t ethip_iplink_ops = {
62 .open = ethip_open,
63 .close = ethip_close,
64 .send = ethip_send,
65 .get_mtu = ethip_get_mtu
66};
67
68static int ethip_init(void)
69{
70 int rc;
71
72 async_set_client_connection(ethip_client_conn);
73
74 rc = loc_server_register(NAME);
75 if (rc != EOK) {
76 log_msg(LVL_ERROR, "Failed registering server.");
77 return rc;
78 }
79
80 rc = ethip_nic_discovery_start();
81 if (rc != EOK)
82 return rc;
83
84 return EOK;
85}
86
87int ethip_iplink_init(ethip_nic_t *nic)
88{
89 int rc;
90 service_id_t sid;
91 category_id_t iplink_cat;
92 static unsigned link_num = 0;
93 char *svc_name = NULL;
94
95 log_msg(LVL_DEBUG, "ethip_iplink_init()");
96
97 iplink_srv_init(&nic->iplink);
98 nic->iplink.ops = &ethip_iplink_ops;
99 nic->iplink.arg = nic;
100
101 rc = asprintf(&svc_name, "net/eth%u", ++link_num);
102 if (rc < 0) {
103 log_msg(LVL_ERROR, "Out of memory.");
104 goto error;
105 }
106
107 rc = loc_service_register(svc_name, &sid);
108 if (rc != EOK) {
109 log_msg(LVL_ERROR, "Failed registering service %s.", svc_name);
110 goto error;
111 }
112
113 nic->iplink_sid = sid;
114
115 rc = loc_category_get_id("iplink", &iplink_cat, IPC_FLAG_BLOCKING);
116 if (rc != EOK) {
117 log_msg(LVL_ERROR, "Failed resolving category 'iplink'.");
118 goto error;
119 }
120
121 rc = loc_service_add_to_cat(sid, iplink_cat);
122 if (rc != EOK) {
123 log_msg(LVL_ERROR, "Failed adding %s to category.", svc_name);
124 goto error;
125 }
126
127 return EOK;
128
129error:
130 if (svc_name != NULL)
131 free(svc_name);
132 return rc;
133}
134
135static void ethip_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
136{
137 ethip_nic_t *nic;
138 service_id_t sid;
139
140 sid = (service_id_t)IPC_GET_ARG1(*icall);
141 log_msg(LVL_DEBUG, "ethip_client_conn(%u)", (unsigned)sid);
142 nic = ethip_nic_find_by_iplink_sid(sid);
143 if (nic == NULL) {
144 log_msg(LVL_WARN, "Uknown service ID.");
145 return;
146 }
147
148 iplink_conn(iid, icall, &nic->iplink);
149}
150
151static int ethip_open(iplink_srv_t *srv)
152{
153 log_msg(LVL_DEBUG, "ethip_open()");
154 return EOK;
155}
156
157static int ethip_close(iplink_srv_t *srv)
158{
159 log_msg(LVL_DEBUG, "ethip_close()");
160 return EOK;
161}
162
163static int ethip_send(iplink_srv_t *srv, iplink_srv_sdu_t *sdu)
164{
165 ethip_nic_t *nic = (ethip_nic_t *)srv->arg;
166 eth_frame_t frame;
167 void *data;
168 size_t size;
169 int rc;
170
171 log_msg(LVL_DEBUG, "ethip_send()");
172
173 frame.dest.addr = 0xdeeedeeedeee;
174 frame.src.addr = 0xaafeedfaceee;
175 frame.etype_len = ETYPE_IP;
176 frame.data = sdu->data;
177 frame.size = sdu->size;
178
179 rc = eth_pdu_encode(&frame, &data, &size);
180 if (rc != EOK)
181 return rc;
182
183 rc = ethip_nic_send(nic, data, size);
184 free(data);
185
186 return rc;
187}
188
189int ethip_received(iplink_srv_t *srv, void *data, size_t size)
190{
191 log_msg(LVL_DEBUG, "ethip_received(): srv=%p", srv);
192 ethip_nic_t *nic = (ethip_nic_t *)srv->arg;
193 eth_frame_t frame;
194 iplink_srv_sdu_t sdu;
195 int rc;
196
197 log_msg(LVL_DEBUG, "ethip_received()");
198
199 log_msg(LVL_DEBUG, " - eth_pdu_decode");
200 rc = eth_pdu_decode(data, size, &frame);
201 if (rc != EOK) {
202 log_msg(LVL_DEBUG, " - eth_pdu_decode failed");
203 return rc;
204 }
205
206 log_msg(LVL_DEBUG, " - construct SDU");
207 sdu.lsrc.ipv4 = (192 << 24) | (168 << 16) | (0 << 8) | 1;
208 sdu.ldest.ipv4 = (192 << 24) | (168 << 16) | (0 << 8) | 4;
209 sdu.data = frame.data;
210 sdu.size = frame.size;
211 log_msg(LVL_DEBUG, " - call iplink_ev_recv");
212 rc = iplink_ev_recv(&nic->iplink, &sdu);
213
214 free(frame.data);
215 return rc;
216}
217
218static int ethip_get_mtu(iplink_srv_t *srv, size_t *mtu)
219{
220 log_msg(LVL_DEBUG, "ethip_get_mtu()");
221 *mtu = 1500;
222 return EOK;
223}
224
225int main(int argc, char *argv[])
226{
227 int rc;
228
229 printf(NAME ": HelenOS IP over Ethernet service\n");
230
231 if (log_init(NAME, LVL_DEBUG) != EOK) {
232 printf(NAME ": Failed to initialize logging.\n");
233 return 1;
234 }
235
236 rc = ethip_init();
237 if (rc != EOK)
238 return 1;
239
240 printf(NAME ": Accepting connections.\n");
241 task_retval(0);
242 async_manager();
243
244 /* Not reached */
245 return 0;
246}
247
248/** @}
249 */
Note: See TracBrowser for help on using the repository browser.