source: mainline/uspace/lib/c/generic/inetping6.c@ 671b546

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

more IPv6 stub code

  • Property mode set to 100644
File size: 5.2 KB
Line 
1/*
2 * Copyright (c) 2013 Martin Decky
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#include <async.h>
30#include <assert.h>
31#include <errno.h>
32#include <inet/inetping6.h>
33#include <ipc/inet.h>
34#include <ipc/services.h>
35#include <loc.h>
36#include <stdlib.h>
37#include <str.h>
38
39static void inetping6_cb_conn(ipc_callid_t, ipc_call_t *, void *);
40static void inetping6_ev_recv(ipc_callid_t, ipc_call_t *);
41
42static async_sess_t *inetping6_sess = NULL;
43static inetping6_ev_ops_t *inetping6_ev_ops;
44
45int inetping6_init(inetping6_ev_ops_t *ev_ops)
46{
47 assert(inetping6_sess == NULL);
48
49 inetping6_ev_ops = ev_ops;
50
51 service_id_t inetping6_svc;
52 int rc = loc_service_get_id(SERVICE_NAME_INETPING6, &inetping6_svc,
53 IPC_FLAG_BLOCKING);
54 if (rc != EOK)
55 return ENOENT;
56
57 inetping6_sess = loc_service_connect(EXCHANGE_SERIALIZE, inetping6_svc,
58 IPC_FLAG_BLOCKING);
59 if (inetping6_sess == NULL)
60 return ENOENT;
61
62 async_exch_t *exch = async_exchange_begin(inetping6_sess);
63
64 rc = async_connect_to_me(exch, 0, 0, 0, inetping6_cb_conn, NULL);
65 async_exchange_end(exch);
66
67 if (rc != EOK) {
68 async_hangup(inetping6_sess);
69 inetping6_sess = NULL;
70 return rc;
71 }
72
73 return EOK;
74}
75
76int inetping6_send(inetping6_sdu_t *sdu)
77{
78 async_exch_t *exch = async_exchange_begin(inetping6_sess);
79
80 ipc_call_t answer;
81 aid_t req = async_send_3(exch, INETPING6_SEND, (sysarg_t) sdu->src,
82 (sysarg_t) sdu->dest, sdu->seq_no, &answer);
83 sysarg_t retval = async_data_write_start(exch, sdu->data, sdu->size);
84
85 async_exchange_end(exch);
86
87 if (retval != EOK) {
88 async_forget(req);
89 return retval;
90 }
91
92 async_wait_for(req, &retval);
93 return retval;
94}
95
96int inetping6_get_srcaddr(addr128_t remote, addr128_t local)
97{
98 async_exch_t *exch = async_exchange_begin(inetping6_sess);
99
100 ipc_call_t answer;
101 aid_t req = async_send_0(exch, INETPING6_GET_SRCADDR, &answer);
102
103 int rc = async_data_write_start(exch, remote, sizeof(addr128_t));
104 if (rc != EOK) {
105 async_exchange_end(exch);
106 async_forget(req);
107 return rc;
108 }
109
110 ipc_call_t answer_local;
111 aid_t req_local = async_data_read(exch, local, sizeof(addr128_t),
112 &answer_local);
113
114 async_exchange_end(exch);
115
116 sysarg_t retval_local;
117 async_wait_for(req_local, &retval_local);
118
119 if (retval_local != EOK) {
120 async_forget(req);
121 return (int) retval_local;
122 }
123
124 sysarg_t retval;
125 async_wait_for(req, &retval);
126
127 return (int) retval;
128}
129
130static void inetping6_ev_recv(ipc_callid_t iid, ipc_call_t *icall)
131{
132 inetping6_sdu_t sdu;
133
134 sdu.seq_no = IPC_GET_ARG1(*icall);
135
136 ipc_callid_t callid;
137 size_t size;
138 if (!async_data_write_receive(&callid, &size)) {
139 async_answer_0(callid, EREFUSED);
140 async_answer_0(iid, EREFUSED);
141 return;
142 }
143
144 if (size != sizeof(inet_addr_t)) {
145 async_answer_0(callid, EINVAL);
146 async_answer_0(iid, EINVAL);
147 return;
148 }
149
150 int rc = async_data_write_finalize(callid, &sdu.src, size);
151 if (rc != EOK) {
152 async_answer_0(callid, rc);
153 async_answer_0(iid, rc);
154 return;
155 }
156
157 if (!async_data_write_receive(&callid, &size)) {
158 async_answer_0(callid, EREFUSED);
159 async_answer_0(iid, EREFUSED);
160 return;
161 }
162
163 if (size != sizeof(inet_addr_t)) {
164 async_answer_0(callid, EINVAL);
165 async_answer_0(iid, EINVAL);
166 return;
167 }
168
169 rc = async_data_write_finalize(callid, &sdu.dest, size);
170 if (rc != EOK) {
171 async_answer_0(callid, rc);
172 async_answer_0(iid, rc);
173 return;
174 }
175
176 rc = async_data_write_accept(&sdu.data, false, 0, 0, 0, &sdu.size);
177 if (rc != EOK) {
178 async_answer_0(iid, rc);
179 return;
180 }
181
182 rc = inetping6_ev_ops->recv(&sdu);
183 free(sdu.data);
184 async_answer_0(iid, rc);
185}
186
187static void inetping6_cb_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
188{
189 while (true) {
190 ipc_call_t call;
191 ipc_callid_t callid = async_get_call(&call);
192
193 if (!IPC_GET_IMETHOD(call)) {
194 /* TODO: Handle hangup */
195 return;
196 }
197
198 switch (IPC_GET_IMETHOD(call)) {
199 case INETPING6_EV_RECV:
200 inetping6_ev_recv(callid, &call);
201 break;
202 default:
203 async_answer_0(callid, ENOTSUP);
204 }
205 }
206}
207
208/** @}
209 */
Note: See TracBrowser for help on using the repository browser.