minor fixes for safecopy & safemap tests
[minix.git] / servers / lwip / lwip.c
blob32fa6c41738265a197bfefbebf224260a80ca96c
1 #include <unistd.h>
2 #include <timers.h>
3 #include <sys/svrctl.h>
4 #include <minix/ds.h>
5 #include <minix/endpoint.h>
6 #include <errno.h>
7 #include <minix/sef.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <minix/chardriver.h>
12 #include <minix/syslib.h>
13 #include <minix/sysutil.h>
14 #include <minix/timers.h>
15 #include <minix/netsock.h>
17 #include "proto.h"
19 #include <lwip/mem.h>
20 #include <lwip/pbuf.h>
21 #include <lwip/stats.h>
22 #include <lwip/netif.h>
23 #include <netif/etharp.h>
24 #include <lwip/tcp_impl.h>
26 endpoint_t lwip_ep;
28 static timer_t tcp_ftmr, tcp_stmr, arp_tmr;
29 static int arp_ticks, tcp_fticks, tcp_sticks;
31 static struct netif * netif_lo;
33 extern struct sock_ops sock_udp_ops;
34 extern struct sock_ops sock_tcp_ops;
35 extern struct sock_ops sock_raw_ip_ops;
37 void sys_init(void)
41 static void arp_watchdog(__unused timer_t *tp)
43 etharp_tmr();
44 set_timer(&arp_tmr, arp_ticks, arp_watchdog, 0);
47 static void tcp_fwatchdog(__unused timer_t *tp)
49 tcp_fasttmr();
50 set_timer(&tcp_ftmr, tcp_fticks, tcp_fwatchdog, 0);
53 static void tcp_swatchdog(__unused timer_t *tp)
55 tcp_slowtmr();
56 set_timer(&tcp_ftmr, tcp_sticks, tcp_swatchdog, 0);
59 static int sef_cb_init_fresh(__unused int type, __unused sef_init_info_t *info)
61 int err;
62 unsigned hz;
64 char my_name[16];
65 int my_priv;
67 err = sys_whoami(&lwip_ep, my_name, sizeof(my_name), &my_priv);
68 if (err != OK)
69 panic("Cannot get own endpoint");
71 nic_init_all();
72 inet_read_conf();
74 /* init lwip library */
75 stats_init();
76 sys_init();
77 mem_init();
78 memp_init();
79 pbuf_init();
81 hz = sys_hz();
83 arp_ticks = ARP_TMR_INTERVAL / (1000 / hz);
84 tcp_fticks = TCP_FAST_INTERVAL / (1000 / hz);
85 tcp_sticks = TCP_SLOW_INTERVAL / (1000 / hz);
87 etharp_init();
89 set_timer(&arp_tmr, arp_ticks, arp_watchdog, 0);
90 set_timer(&tcp_ftmr, tcp_fticks, tcp_fwatchdog, 0);
91 set_timer(&tcp_stmr, tcp_sticks, tcp_swatchdog, 0);
93 netif_init();
94 netif_lo = netif_find("lo0");
96 /* Read configuration. */
97 #if 0
98 nw_conf();
100 /* Get a random number */
101 timerand= 1;
102 fd = open(RANDOM_DEV_NAME, O_RDONLY | O_NONBLOCK);
103 if (fd != -1)
105 err= read(fd, randbits, sizeof(randbits));
106 if (err == sizeof(randbits))
107 timerand= 0;
108 else
110 printf("inet: unable to read random data from %s: %s\n",
111 RANDOM_DEV_NAME, err == -1 ? strerror(errno) :
112 err == 0 ? "EOF" : "not enough data");
114 close(fd);
116 else
118 printf("inet: unable to open random device %s: %s\n",
119 RANDOM_DEV_NAME, strerror(errno));
121 if (timerand)
123 printf("inet: using current time for random-number seed\n");
124 err= gettimeofday(&tv, NULL);
125 if (err == -1)
127 printf("sysutime failed: %s\n", strerror(errno));
128 exit(1);
130 memcpy(randbits, &tv, sizeof(tv));
132 init_rand256(randbits);
133 #endif
135 /* Subscribe to driver events for network drivers. */
136 if ((err = ds_subscribe("drv\\.net\\..*",
137 DSF_INITIAL | DSF_OVERWRITE)) != OK)
138 panic(("inet: can't subscribe to driver events"));
140 /* Announce we are up. LWIP announces its presence to VFS just like
141 * any other character driver.
143 chardriver_announce();
145 return(OK);
148 static void sef_local_startup()
150 /* Register init callbacks. */
151 sef_setcb_init_fresh(sef_cb_init_fresh);
152 sef_setcb_init_restart(sef_cb_init_fresh);
154 /* No live update support for now. */
156 /* Let SEF perform startup. */
157 sef_startup();
160 static void ds_event(void)
162 char key[DS_MAX_KEYLEN];
163 char *driver_prefix = "drv.net.";
164 char *label;
165 u32_t value;
166 int type;
167 endpoint_t owner_endpoint;
168 int r;
170 /* We may get one notification for multiple updates from DS. Get events
171 * and owners from DS, until DS tells us that there are no more.
173 while ((r = ds_check(key, &type, &owner_endpoint)) == OK) {
174 r = ds_retrieve_u32(key, &value);
175 if(r != OK) {
176 printf("LWIP : ds_event: ds_retrieve_u32 failed\n");
177 return;
180 /* Only check for network driver up events. */
181 if(strncmp(key, driver_prefix, sizeof(driver_prefix))
182 || value != DS_DRIVER_UP)
183 return;
185 /* The driver label comes after the prefix. */
186 label = key + strlen(driver_prefix);
188 /* A driver is (re)started. */
189 driver_up(label, owner_endpoint);
192 if(r != ENOENT)
193 printf("LWIP : ds_event: ds_check failed: %d\n", r);
196 static void netif_poll_lo(void)
198 if (netif_lo == NULL)
199 return;
201 while (netif_lo->loop_first)
202 netif_poll(netif_lo);
205 void socket_open(message * m)
207 struct sock_ops * ops;
208 struct socket * sock;
209 int ret = OK;
211 switch (m->DEVICE) {
212 case SOCK_TYPE_TCP:
213 ops = &sock_tcp_ops;
214 break;
215 case SOCK_TYPE_UDP:
216 ops = &sock_udp_ops;
217 break;
218 case SOCK_TYPE_IP:
219 ops = &sock_raw_ip_ops;
220 break;
221 default:
222 if (m->DEVICE - SOCK_TYPES < MAX_DEVS) {
223 m->DEVICE -= SOCK_TYPES;
224 nic_open(m);
225 return;
227 printf("LWIP unknown socket type %d\n", m->DEVICE);
228 send_reply_open(m, EINVAL);
229 return;
232 sock = get_unused_sock();
233 if (!sock) {
234 printf("LWIP : no free socket\n");
235 send_reply_open(m, EAGAIN);
236 return;
239 sock->ops = ops;
240 sock->select_ep = NONE;
241 sock->recv_data_size = 0;
243 if (sock->ops && sock->ops->open)
244 ret = sock->ops->open(sock, m);
246 if (ret == OK) {
247 debug_print("new socket %ld", get_sock_num(sock));
248 send_reply_open(m, get_sock_num(sock));
249 } else {
250 debug_print("failed %d", ret);
251 send_reply_open(m, ret);
255 int main(__unused int argc, __unused char ** argv)
257 sef_local_startup();
259 for(;;) {
260 int err, ipc_status;
261 message m;
263 netif_poll_lo();
265 mq_process();
267 if ((err = sef_receive_status(ANY, &m, &ipc_status)) != OK) {
268 printf("LWIP : sef_receive_status errr %d\n", err);
269 continue;
272 if (m.m_source == VFS_PROC_NR)
273 socket_request(&m);
274 else if (is_ipc_notify(ipc_status)) {
275 switch (m.m_source) {
276 case CLOCK:
277 expire_timers(m.NOTIFY_TIMESTAMP);
278 break;
279 case DS_PROC_NR:
280 ds_event();
281 break;
282 case PM_PROC_NR:
283 panic("LWIP : unhandled event from PM");
284 break;
285 default:
286 printf("LWIP : unexpected notify from %d\n",
287 m.m_source);
288 continue;
290 } else
291 /* all other request can be from drivers only */
292 driver_request(&m);
295 return 0;