64-bit VFS_LSEEK_OFF
[minix3.git] / servers / inet / inet.c
blobc18dd58cc6938fcc9c5e030286603d697262ac0e
1 /* this file contains the interface of the network software with rest of
2 minix. Furthermore it contains the main loop of the network task.
4 Copyright 1995 Philip Homburg
5 */
7 #include "inet.h"
9 #include <fcntl.h>
10 #include <unistd.h>
11 #include <sys/svrctl.h>
12 #include <minix/ds.h>
13 #include <minix/endpoint.h>
14 #include <minix/chardriver.h>
15 #include <minix/rs.h>
16 #include <sys/types.h>
17 #include <pwd.h>
19 #include "mq.h"
20 #include "qp.h"
21 #include "proto.h"
22 #include "generic/type.h"
24 #include "generic/arp.h"
25 #include "generic/assert.h"
26 #include "generic/buf.h"
27 #include "generic/clock.h"
28 #include "generic/eth.h"
29 #include "generic/event.h"
30 #include "generic/ip.h"
31 #include "generic/psip.h"
32 #include "generic/rand256.h"
33 #include "generic/sr.h"
34 #include "generic/tcp.h"
35 #include "generic/udp.h"
37 THIS_FILE
39 #define RANDOM_DEV_NAME "/dev/random"
41 endpoint_t this_proc; /* Process number of this server. */
43 /* Killing Solaris */
44 int killer_inet= 0;
46 #ifdef BUF_CONSISTENCY_CHECK
47 extern int inet_buf_debug;
48 #endif
50 #if HZ_DYNAMIC
51 u32_t system_hz;
52 #endif
54 static void nw_conf(void);
55 static void nw_init(void);
56 static void ds_event(void);
58 /* SEF functions and variables. */
59 static void sef_local_startup(void);
60 static int sef_cb_init_fresh(int type, sef_init_info_t *info);
62 int main(int argc, char *argv[])
64 message mess;
65 int ipc_status;
66 int r;
68 /* SEF local startup. */
69 sef_local_startup();
71 while (TRUE)
73 #ifdef BUF_CONSISTENCY_CHECK
74 if (inet_buf_debug)
76 static int buf_debug_count= 0;
78 if (++buf_debug_count >= inet_buf_debug)
80 buf_debug_count= 0;
81 if (!bf_consistency_check())
82 break;
85 #endif
86 if (ev_head)
88 ev_process();
89 continue;
91 if (clck_call_expire)
93 clck_expire_timers();
94 continue;
97 r= sef_receive_status(ANY, &mess, &ipc_status);
98 if (r<0)
100 ip_panic(("unable to receive: %d", r));
102 reset_time();
103 if (mess.m_source == VFS_PROC_NR)
105 sr_rec(&mess, ipc_status);
107 else if (is_ipc_notify(ipc_status))
109 if (mess.m_source == CLOCK)
111 clck_tick(&mess);
113 else if (mess.m_source == DS_PROC_NR)
115 /* DS notifies us of an event. */
116 ds_event();
118 else
120 printf("inet: got unexpected notify from %d\n",
121 mess.m_source);
124 else if (mess.m_type == DL_CONF_REPLY ||
125 mess.m_type == DL_TASK_REPLY ||
126 mess.m_type == DL_STAT_REPLY)
128 eth_rec(&mess);
130 else
132 printf("inet: got bad message type 0x%x from %d\n",
133 mess.m_type, mess.m_source);
136 ip_panic(("task is not allowed to terminate"));
137 return 1;
140 /*===========================================================================*
141 * sef_local_startup *
142 *===========================================================================*/
143 static void sef_local_startup()
145 /* Register init callbacks. */
146 sef_setcb_init_fresh(sef_cb_init_fresh);
147 sef_setcb_init_restart(sef_cb_init_fresh);
149 /* No live update support for now. */
151 /* Let SEF perform startup. */
152 sef_startup();
155 /*===========================================================================*
156 * sef_cb_init_fresh *
157 *===========================================================================*/
158 static int sef_cb_init_fresh(int type, sef_init_info_t *info)
160 /* Initialize the inet server. */
161 int r;
162 int timerand, fd;
163 u8_t randbits[32];
164 struct timeval tv;
165 struct passwd *pw;
167 #if DEBUG
168 printf("Starting inet...\n");
169 printf("%s\n", version);
170 #endif
172 #if HZ_DYNAMIC
173 system_hz = sys_hz();
174 #endif
176 /* Read configuration. */
177 nw_conf();
179 /* Get a random number */
180 timerand= 1;
181 fd= open(RANDOM_DEV_NAME, O_RDONLY | O_NONBLOCK);
182 if (fd != -1)
184 r= read(fd, randbits, sizeof(randbits));
185 if (r == sizeof(randbits))
186 timerand= 0;
187 else
189 printf("inet: unable to read random data from %s: %s\n",
190 RANDOM_DEV_NAME, r == -1 ? strerror(errno) :
191 r == 0 ? "EOF" : "not enough data");
193 close(fd);
195 else
197 printf("inet: unable to open random device %s: %s\n",
198 RANDOM_DEV_NAME, strerror(errno));
200 if (timerand)
202 printf("inet: using current time for random-number seed\n");
203 r= gettimeofday(&tv, NULL);
204 if (r == -1)
206 printf("sysutime failed: %s\n", strerror(errno));
207 exit(1);
209 memcpy(randbits, &tv, sizeof(tv));
211 init_rand256(randbits);
213 /* Our new identity as a server. */
214 this_proc= info->endpoint;
216 #ifdef BUF_CONSISTENCY_CHECK
217 inet_buf_debug= (getenv("inetbufdebug") &&
218 (strcmp(getenv("inetbufdebug"), "on") == 0));
219 inet_buf_debug= 100;
220 if (inet_buf_debug)
222 ip_warning(( "buffer consistency check enabled" ));
224 #endif
226 if (getenv("killerinet"))
228 ip_warning(( "killer inet active" ));
229 killer_inet= 1;
232 nw_init();
234 /* Subscribe to driver events for network drivers. */
235 r = ds_subscribe("drv\\.net\\..*", DSF_INITIAL | DSF_OVERWRITE);
236 if(r != OK) {
237 ip_panic(("inet: can't subscribe to driver events"));
240 /* Drop root privileges */
241 if ((pw = getpwnam(SERVICE_LOGIN)) == NULL) {
242 printf("inet: unable to retrieve uid of SERVICE_LOGIN, "
243 "still running as root");
244 } else if (setuid(pw->pw_uid) != 0) {
245 ip_panic(("inet: unable to drop privileges"));
248 /* Announce we are up. INET announces its presence to VFS just like
249 * any other character driver.
251 chardriver_announce();
253 return(OK);
256 static void nw_conf()
258 read_conf();
259 eth_prep();
260 arp_prep();
261 psip_prep();
262 ip_prep();
263 tcp_prep();
264 udp_prep();
267 static void nw_init()
269 mq_init();
270 bf_init();
271 clck_init();
272 sr_init();
273 qp_init();
274 eth_init();
275 arp_init();
276 psip_init();
277 ip_init();
278 tcp_init();
279 udp_init();
282 /*===========================================================================*
283 * ds_event *
284 *===========================================================================*/
285 static void ds_event()
287 char key[DS_MAX_KEYLEN];
288 char *driver_prefix = (char *) "drv.net.";
289 char *label;
290 u32_t value;
291 int type;
292 endpoint_t owner_endpoint;
293 int r;
294 int prefix_len;
296 prefix_len = strlen(driver_prefix);
298 /* We may get one notification for multiple updates from DS. Get events
299 * and owners from DS, until DS tells us that there are no more.
301 while ((r = ds_check(key, &type, &owner_endpoint)) == OK) {
302 r = ds_retrieve_u32(key, &value);
303 if(r != OK) {
304 printf("inet: ds_event: ds_retrieve_u32 failed\n");
305 return;
308 /* Only check for network driver up events. */
309 if(strncmp(key, driver_prefix, prefix_len)
310 || value != DS_DRIVER_UP) {
311 return;
314 /* The driver label comes after the prefix. */
315 label = key + prefix_len;
317 /* A driver is (re)started. */
318 eth_check_driver(label, owner_endpoint);
321 if(r != ENOENT)
322 printf("inet: ds_event: ds_check failed: %d\n", r);
325 void panic0(file, line)
326 char *file;
327 int line;
329 printf("panic at %s, %d: ", file, line);
332 __dead
333 void inet_panic(void)
335 printf("\ninet stacktrace: ");
336 util_stacktrace();
337 (panic)("aborted due to a panic");
338 for(;;);
341 #if !NDEBUG
342 __dead
343 void bad_assertion(file, line, what)
344 char *file;
345 int line;
346 char *what;
348 panic0(file, line);
349 printf("assertion \"%s\" failed", what);
350 panic("help");
354 __dead
355 void bad_compare(file, line, lhs, what, rhs)
356 char *file;
357 int line;
358 int lhs;
359 char *what;
360 int rhs;
362 panic0(file, line);
363 printf("compare (%d) %s (%d) failed", lhs, what, rhs);
364 panic("help");
366 #endif /* !NDEBUG */
369 * $PchId: inet.c,v 1.23 2005/06/28 14:27:22 philip Exp $