tools/llvm: Do not build with symbols
[minix3.git] / minix / net / lwip / lwip.c
blob0edd7af5130d912c026502a2af06b4f23d05ed40
1 #include <unistd.h>
2 #include <minix/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 minix_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 static void sys_init(void)
41 static void arp_watchdog(__unused minix_timer_t *tp)
43 etharp_tmr();
44 set_timer(&arp_tmr, arp_ticks, arp_watchdog, 0);
47 static void tcp_fwatchdog(__unused minix_timer_t *tp)
49 tcp_fasttmr();
50 set_timer(&tcp_ftmr, tcp_fticks, tcp_fwatchdog, 0);
53 static void tcp_swatchdog(__unused minix_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 int 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(__UNCONST("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(void)
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 const char *driver_prefix = "drv.net.";
164 char *label;
165 u32_t value;
166 int type;
167 endpoint_t owner_endpoint;
168 int r;
169 int prefix_len;
171 prefix_len = strlen(driver_prefix);
173 /* We may get one notification for multiple updates from DS. Get events
174 * and owners from DS, until DS tells us that there are no more.
176 while ((r = ds_check(key, &type, &owner_endpoint)) == OK) {
177 r = ds_retrieve_u32(key, &value);
178 if(r != OK) {
179 printf("LWIP : ds_event: ds_retrieve_u32 failed\n");
180 return;
183 /* Only check for network driver up events. */
184 if(strncmp(key, driver_prefix, prefix_len)
185 || value != DS_DRIVER_UP) {
186 return;
189 /* The driver label comes after the prefix. */
190 label = key + strlen(driver_prefix);
192 /* A driver is (re)started. */
193 driver_up(label, owner_endpoint);
196 if(r != ENOENT)
197 printf("LWIP : ds_event: ds_check failed: %d\n", r);
200 static void netif_poll_lo(void)
202 if (netif_lo == NULL)
203 return;
205 while (netif_lo->loop_first)
206 netif_poll(netif_lo);
209 int socket_open(devminor_t minor)
211 struct sock_ops * ops;
212 struct socket * sock;
213 int ret = OK;
215 switch (minor) {
216 case SOCK_TYPE_TCP:
217 ops = &sock_tcp_ops;
218 break;
219 case SOCK_TYPE_UDP:
220 ops = &sock_udp_ops;
221 break;
222 case SOCK_TYPE_IP:
223 ops = &sock_raw_ip_ops;
224 break;
225 default:
226 if (minor - SOCK_TYPES < MAX_DEVS)
227 return nic_open(minor - SOCK_TYPES);
229 printf("LWIP unknown socket type %d\n", minor);
230 return EINVAL;
233 sock = get_unused_sock();
234 if (!sock) {
235 printf("LWIP : no free socket\n");
236 return EAGAIN;
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);
246 if (ret == OK) {
247 debug_print("new socket %ld", get_sock_num(sock));
248 ret = get_sock_num(sock);
249 } else {
250 debug_print("failed %d", ret);
251 /* FIXME: shouldn't sock be freed now? */
253 return ret;
256 int main(__unused int argc, __unused char ** argv)
258 sef_local_startup();
260 for(;;) {
261 int err, ipc_status;
262 message m;
264 netif_poll_lo();
266 mq_process();
268 if ((err = sef_receive_status(ANY, &m, &ipc_status)) != OK) {
269 printf("LWIP : sef_receive_status errr %d\n", err);
270 continue;
273 if (m.m_source == VFS_PROC_NR)
274 socket_request(&m, ipc_status);
275 else if (is_ipc_notify(ipc_status)) {
276 switch (m.m_source) {
277 case CLOCK:
278 expire_timers(m.m_notify.timestamp);
279 break;
280 case DS_PROC_NR:
281 ds_event();
282 break;
283 case PM_PROC_NR:
284 panic("LWIP : unhandled event from PM");
285 break;
286 default:
287 printf("LWIP : unexpected notify from %d\n",
288 m.m_source);
289 continue;
291 } else
292 /* all other request can be from drivers only */
293 driver_request(&m);
296 return 0;