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> 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 endpoint_t lwip_ep; 27 28 static minix_timer_t tcp_ftmr, tcp_stmr, arp_tmr; 29 static int arp_ticks, tcp_fticks, tcp_sticks; 30 31 static struct netif * netif_lo; 32 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; 36 37 static void sys_init(void) 38 { 39 } 40 41 static void arp_watchdog(__unused minix_timer_t *tp) 42 { 43 etharp_tmr(); 44 set_timer(&arp_tmr, arp_ticks, arp_watchdog, 0); 45 } 46 47 static void tcp_fwatchdog(__unused minix_timer_t *tp) 48 { 49 tcp_fasttmr(); 50 set_timer(&tcp_ftmr, tcp_fticks, tcp_fwatchdog, 0); 51 } 52 53 static void tcp_swatchdog(__unused minix_timer_t *tp) 54 { 55 tcp_slowtmr(); 56 set_timer(&tcp_ftmr, tcp_sticks, tcp_swatchdog, 0); 57 } 58 59 static int sef_cb_init_fresh(__unused int type, __unused sef_init_info_t *info) 60 { 61 int err; 62 unsigned int hz; 63 64 char my_name[16]; 65 int my_priv; 66 67 err = sys_whoami(&lwip_ep, my_name, sizeof(my_name), &my_priv); 68 if (err != OK) 69 panic("Cannot get own endpoint"); 70 71 nic_init_all(); 72 inet_read_conf(); 73 74 /* init lwip library */ 75 stats_init(); 76 sys_init(); 77 mem_init(); 78 memp_init(); 79 pbuf_init(); 80 81 hz = sys_hz(); 82 83 arp_ticks = ARP_TMR_INTERVAL / (1000 / hz); 84 tcp_fticks = TCP_FAST_INTERVAL / (1000 / hz); 85 tcp_sticks = TCP_SLOW_INTERVAL / (1000 / hz); 86 87 etharp_init(); 88 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); 92 93 netif_init(); 94 netif_lo = netif_find(__UNCONST("lo0")); 95 96 /* Read configuration. */ 97 #if 0 98 nw_conf(); 99 100 /* Get a random number */ 101 timerand= 1; 102 fd = open(RANDOM_DEV_NAME, O_RDONLY | O_NONBLOCK); 103 if (fd != -1) 104 { 105 err= read(fd, randbits, sizeof(randbits)); 106 if (err == sizeof(randbits)) 107 timerand= 0; 108 else 109 { 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"); 113 } 114 close(fd); 115 } 116 else 117 { 118 printf("inet: unable to open random device %s: %s\n", 119 RANDOM_DEV_NAME, strerror(errno)); 120 } 121 if (timerand) 122 { 123 printf("inet: using current time for random-number seed\n"); 124 err= gettimeofday(&tv, NULL); 125 if (err == -1) 126 { 127 printf("sysutime failed: %s\n", strerror(errno)); 128 exit(1); 129 } 130 memcpy(randbits, &tv, sizeof(tv)); 131 } 132 init_rand256(randbits); 133 #endif 134 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")); 139 140 /* Announce we are up. LWIP announces its presence to VFS just like 141 * any other character driver. 142 */ 143 chardriver_announce(); 144 145 return(OK); 146 } 147 148 static void sef_local_startup(void) 149 { 150 /* Register init callbacks. */ 151 sef_setcb_init_fresh(sef_cb_init_fresh); 152 sef_setcb_init_restart(sef_cb_init_fresh); 153 154 /* No live update support for now. */ 155 156 /* Let SEF perform startup. */ 157 sef_startup(); 158 } 159 160 static void ds_event(void) 161 { 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; 170 171 prefix_len = strlen(driver_prefix); 172 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. 175 */ 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; 181 } 182 183 /* Only check for network driver up events. */ 184 if(strncmp(key, driver_prefix, prefix_len) 185 || value != DS_DRIVER_UP) { 186 return; 187 } 188 189 /* The driver label comes after the prefix. */ 190 label = key + strlen(driver_prefix); 191 192 /* A driver is (re)started. */ 193 driver_up(label, owner_endpoint); 194 } 195 196 if(r != ENOENT) 197 printf("LWIP : ds_event: ds_check failed: %d\n", r); 198 } 199 200 static void netif_poll_lo(void) 201 { 202 if (netif_lo == NULL) 203 return; 204 205 while (netif_lo->loop_first) 206 netif_poll(netif_lo); 207 } 208 209 int socket_open(devminor_t minor) 210 { 211 struct sock_ops * ops; 212 struct socket * sock; 213 int ret = OK; 214 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); 228 229 printf("LWIP unknown socket type %d\n", minor); 230 return EINVAL; 231 } 232 233 sock = get_unused_sock(); 234 if (!sock) { 235 printf("LWIP : no free socket\n"); 236 return EAGAIN; 237 } 238 239 sock->ops = ops; 240 sock->select_ep = NONE; 241 sock->recv_data_size = 0; 242 243 if (sock->ops && sock->ops->open) 244 ret = sock->ops->open(sock); 245 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? */ 252 } 253 return ret; 254 } 255 256 int main(__unused int argc, __unused char ** argv) 257 { 258 sef_local_startup(); 259 260 for(;;) { 261 int err, ipc_status; 262 message m; 263 264 netif_poll_lo(); 265 266 mq_process(); 267 268 if ((err = sef_receive_status(ANY, &m, &ipc_status)) != OK) { 269 printf("LWIP : sef_receive_status errr %d\n", err); 270 continue; 271 } 272 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; 290 } 291 } else 292 /* all other request can be from drivers only */ 293 driver_request(&m); 294 } 295 296 return 0; 297 } 298