xref: /minix3/minix/net/lwip/lwip.c (revision dd41186aac5f9c05e657f127b7e5d33f375d1686)
1 #include <unistd.h>
2 #include <minix/timers.h>
3 #include <minix/ds.h>
4 #include <minix/endpoint.h>
5 #include <errno.h>
6 #include <minix/sef.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <minix/chardriver.h>
11 #include <minix/syslib.h>
12 #include <minix/sysutil.h>
13 #include <minix/timers.h>
14 #include <minix/netsock.h>
15 #include <minix/rmib.h>
16 
17 #include "proto.h"
18 
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>
25 
26 static minix_timer_t tcp_ftmr, tcp_stmr, arp_tmr;
27 static int arp_ticks, tcp_fticks, tcp_sticks;
28 
29 static struct netif * netif_lo;
30 
31 extern struct sock_ops sock_udp_ops;
32 extern struct sock_ops sock_tcp_ops;
33 extern struct sock_ops sock_raw_ip_ops;
34 
35 static void sys_init(void)
36 {
37 }
38 
39 static void arp_watchdog(int arg __unused)
40 {
41 	etharp_tmr();
42 	set_timer(&arp_tmr, arp_ticks, arp_watchdog, 0);
43 }
44 
45 static void tcp_fwatchdog(int arg __unused)
46 {
47 	tcp_fasttmr();
48 	set_timer(&tcp_ftmr, tcp_fticks, tcp_fwatchdog, 0);
49 }
50 
51 static void tcp_swatchdog(int arg __unused)
52 {
53 	tcp_slowtmr();
54 	set_timer(&tcp_ftmr, tcp_sticks, tcp_swatchdog, 0);
55 }
56 
57 static int sef_cb_init_fresh(__unused int type, __unused sef_init_info_t *info)
58 {
59 	int err;
60 	unsigned int hz;
61 
62 	nic_init_all();
63 	inet_read_conf();
64 
65 	/* init lwip library */
66 	stats_init();
67 	sys_init();
68 	mem_init();
69 	memp_init();
70 	pbuf_init();
71 
72 	hz = sys_hz();
73 
74 	arp_ticks = ARP_TMR_INTERVAL / (1000 / hz);
75 	tcp_fticks = TCP_FAST_INTERVAL / (1000 / hz);
76 	tcp_sticks = TCP_SLOW_INTERVAL / (1000 / hz);
77 
78 	etharp_init();
79 
80 	set_timer(&arp_tmr, arp_ticks, arp_watchdog, 0);
81 	set_timer(&tcp_ftmr, tcp_fticks, tcp_fwatchdog, 0);
82 	set_timer(&tcp_stmr, tcp_sticks, tcp_swatchdog, 0);
83 
84 	netif_init();
85 	netif_lo = netif_find(__UNCONST("lo0"));
86 
87 	/* Read configuration. */
88 #if 0
89 	nw_conf();
90 
91 	/* Get a random number */
92 	timerand= 1;
93 	fd = open(RANDOM_DEV_NAME, O_RDONLY | O_NONBLOCK);
94 	if (fd != -1)
95 	{
96 		err= read(fd, randbits, sizeof(randbits));
97 		if (err == sizeof(randbits))
98 			timerand= 0;
99 		else
100 		{
101 			printf("inet: unable to read random data from %s: %s\n",
102 				RANDOM_DEV_NAME, err == -1 ? strerror(errno) :
103 				err == 0 ? "EOF" : "not enough data");
104 		}
105 		close(fd);
106 	}
107 	else
108 	{
109 		printf("inet: unable to open random device %s: %s\n",
110 				RANDOM_DEV_NAME, strerror(errno));
111 	}
112 	if (timerand)
113 	{
114 		printf("inet: using current time for random-number seed\n");
115 		err= gettimeofday(&tv, NULL);
116 		if (err == -1)
117 		{
118 			printf("sysutime failed: %s\n", strerror(errno));
119 			exit(1);
120 		}
121 		memcpy(randbits, &tv, sizeof(tv));
122 	}
123 	init_rand256(randbits);
124 #endif
125 
126 	/* Subscribe to driver events for network drivers. */
127 	if ((err = ds_subscribe("drv\\.net\\..*",
128 					DSF_INITIAL | DSF_OVERWRITE)) != OK)
129 		panic(("inet: can't subscribe to driver events"));
130 
131 	/* Announce we are up. LWIP announces its presence to VFS just like
132 	 * any other character driver.
133 	 */
134 	chardriver_announce();
135 
136 	/* Register net.route RMIB subtree with the MIB service. */
137 	rtinfo_init();
138 
139 	return(OK);
140 }
141 
142 static void sef_local_startup(void)
143 {
144 	/* Register init callbacks. */
145 	sef_setcb_init_fresh(sef_cb_init_fresh);
146 	sef_setcb_init_restart(sef_cb_init_fresh);
147 
148 	/* Let SEF perform startup. */
149 	sef_startup();
150 }
151 
152 static void ds_event(void)
153 {
154 	char key[DS_MAX_KEYLEN];
155 	const char *driver_prefix = "drv.net.";
156 	char *label;
157 	u32_t value;
158 	int type;
159 	endpoint_t owner_endpoint;
160 	int r;
161         int prefix_len;
162 
163         prefix_len = strlen(driver_prefix);
164 
165 	/* We may get one notification for multiple updates from DS. Get events
166 	 * and owners from DS, until DS tells us that there are no more.
167 	 */
168 	while ((r = ds_check(key, &type, &owner_endpoint)) == OK) {
169 		r = ds_retrieve_u32(key, &value);
170 		if(r != OK) {
171 			printf("LWIP : ds_event: ds_retrieve_u32 failed\n");
172 			return;
173 		}
174 
175 		/* Only check for network driver up events. */
176 		if(strncmp(key, driver_prefix, prefix_len)
177 		  || value != DS_DRIVER_UP) {
178 			return;
179 		}
180 
181 		/* The driver label comes after the prefix. */
182 		label = key + strlen(driver_prefix);
183 
184 		/* A driver is (re)started. */
185 		driver_up(label, owner_endpoint);
186 	}
187 
188 	if(r != ENOENT)
189 		printf("LWIP : ds_event: ds_check failed: %d\n", r);
190 }
191 
192 static void netif_poll_lo(void)
193 {
194 	if (netif_lo == NULL)
195 		return;
196 
197 	while (netif_lo->loop_first)
198 		netif_poll(netif_lo);
199 }
200 
201 int socket_open(devminor_t minor)
202 {
203         struct sock_ops * ops;
204         struct socket * sock;
205         int ret = OK;
206 
207         switch (minor) {
208         case SOCK_TYPE_TCP:
209                 ops = &sock_tcp_ops;
210                 break;
211         case SOCK_TYPE_UDP:
212                 ops = &sock_udp_ops;
213                 break;
214         case SOCK_TYPE_IP:
215                 ops = &sock_raw_ip_ops;
216                 break;
217         default:
218                 if (minor - SOCK_TYPES  < MAX_DEVS)
219 			return nic_open(minor - SOCK_TYPES);
220 
221                 printf("LWIP unknown socket type %d\n", minor);
222                 return EINVAL;
223         }
224 
225         sock = get_unused_sock();
226         if (!sock) {
227                 printf("LWIP : no free socket\n");
228                 return EAGAIN;
229         }
230 
231         sock->ops = ops;
232         sock->select_ep = NONE;
233         sock->recv_data_size = 0;
234 
235         if (sock->ops && sock->ops->open)
236                 ret = sock->ops->open(sock);
237 
238         if (ret == OK) {
239                 debug_print("new socket %ld", get_sock_num(sock));
240                 ret = get_sock_num(sock);
241         } else {
242                 debug_print("failed %d", ret);
243 		/* FIXME: shouldn't sock be freed now? */
244         }
245 	return ret;
246 }
247 
248 int main(__unused int argc, __unused char ** argv)
249 {
250 	sef_local_startup();
251 
252 	for(;;) {
253 		int err, ipc_status;
254 		message m;
255 
256 		netif_poll_lo();
257 
258 		mq_process();
259 
260 		if ((err = sef_receive_status(ANY, &m, &ipc_status)) != OK) {
261 			printf("LWIP : sef_receive_status errr %d\n", err);
262 			continue;
263 		}
264 
265 		if (m.m_source == VFS_PROC_NR)
266 			socket_request(&m, ipc_status);
267 		else if (is_ipc_notify(ipc_status)) {
268 			switch (m.m_source) {
269 			case CLOCK:
270 				expire_timers(m.m_notify.timestamp);
271 				break;
272 			case DS_PROC_NR:
273 				ds_event();
274 				break;
275 			case PM_PROC_NR:
276 				panic("LWIP : unhandled event from PM");
277 				break;
278 			default:
279 				printf("LWIP : unexpected notify from %d\n",
280 								m.m_source);
281 				continue;
282 			}
283 		} else if (m.m_source == MIB_PROC_NR)
284 			rmib_process(&m, ipc_status);
285 		else
286 			/* all other request can be from drivers only */
287 			driver_request(&m);
288 	}
289 
290 	return 0;
291 }
292