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