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
6 The valid messages and their parameters are:
9 __________________________________________________________________
11 | m_type | DEVICE | PROC_NR | COUNT | POSITION | ADDRESS |
12 |_______________|___________|_________|_______|__________|_________|
14 | DEV_OPEN | minor dev | proc nr | mode | | |
15 |_______________|___________|_________|_______|__________|_________|
17 | DEV_CLOSE | minor dev | proc nr | | | |
18 |_______________|___________|_________|_______|__________|_________|
20 | DEV_IOCTL_S | minor dev | proc nr | | NWIO.. | address |
21 |_______________|___________|_________|_______|__________|_________|
23 | DEV_READ_S | minor dev | proc nr | count | | address |
24 |_______________|___________|_________|_______|__________|_________|
26 | DEV_WRITE_S | minor dev | proc nr | count | | address |
27 |_______________|___________|_________|_______|__________|_________|
29 | CANCEL | minor dev | proc nr | | | |
30 |_______________|___________|_________|_______|__________|_________|
38 #define _MINIX_SOURCE 1
42 #include <sys/svrctl.h>
44 #include <minix/endpoint.h>
45 #include <minix/chardriver.h>
47 #include <sys/types.h>
53 #include "generic/type.h"
55 #include "generic/arp.h"
56 #include "generic/assert.h"
57 #include "generic/buf.h"
58 #include "generic/clock.h"
59 #include "generic/eth.h"
60 #include "generic/event.h"
61 #include "generic/ip.h"
62 #include "generic/psip.h"
63 #include "generic/rand256.h"
64 #include "generic/sr.h"
65 #include "generic/tcp.h"
66 #include "generic/udp.h"
70 #define RANDOM_DEV_NAME "/dev/random"
72 endpoint_t this_proc
; /* Process number of this server. */
77 #ifdef BUF_CONSISTENCY_CHECK
78 extern int inet_buf_debug
;
85 static void nw_conf(void);
86 static void nw_init(void);
87 static void ds_event(void);
89 /* SEF functions and variables. */
90 static void sef_local_startup(void);
91 static int sef_cb_init_fresh(int type
, sef_init_info_t
*info
);
93 int main(int argc
, char *argv
[])
101 /* SEF local startup. */
106 #ifdef BUF_CONSISTENCY_CHECK
109 static int buf_debug_count
= 0;
111 if (++buf_debug_count
>= inet_buf_debug
)
114 if (!bf_consistency_check())
124 if (clck_call_expire
)
126 clck_expire_timers();
131 ip_panic(("out of messages"));
133 r
= sef_receive_status(ANY
, &mq
->mq_mess
, &ipc_status
);
136 ip_panic(("unable to receive: %d", r
));
139 source
= mq
->mq_mess
.m_source
;
140 m_type
= mq
->mq_mess
.m_type
;
141 if (source
== VFS_PROC_NR
)
145 else if (is_ipc_notify(ipc_status
))
149 clck_tick(&mq
->mq_mess
);
152 else if (source
== PM_PROC_NR
)
155 /* probably SIGTERM */
158 else if (source
== DS_PROC_NR
)
160 /* DS notifies us of an event. */
166 printf("inet: got unexpected notify from %d\n",
167 mq
->mq_mess
.m_source
);
171 else if (m_type
== DL_CONF_REPLY
|| m_type
== DL_TASK_REPLY
||
172 m_type
== DL_STAT_REPLY
)
174 eth_rec(&mq
->mq_mess
);
179 printf("inet: got bad message type 0x%x from %d\n",
180 mq
->mq_mess
.m_type
, mq
->mq_mess
.m_source
);
184 ip_panic(("task is not allowed to terminate"));
188 /*===========================================================================*
189 * sef_local_startup *
190 *===========================================================================*/
191 static void sef_local_startup()
193 /* Register init callbacks. */
194 sef_setcb_init_fresh(sef_cb_init_fresh
);
195 sef_setcb_init_restart(sef_cb_init_fresh
);
197 /* No live update support for now. */
199 /* Let SEF perform startup. */
203 /*===========================================================================*
204 * sef_cb_init_fresh *
205 *===========================================================================*/
206 static int sef_cb_init_fresh(int type
, sef_init_info_t
*info
)
208 /* Initialize the inet server. */
216 printf("Starting inet...\n");
217 printf("%s\n", version
);
221 system_hz
= sys_hz();
224 /* Read configuration. */
227 /* Get a random number */
229 fd
= open(RANDOM_DEV_NAME
, O_RDONLY
| O_NONBLOCK
);
232 r
= read(fd
, randbits
, sizeof(randbits
));
233 if (r
== sizeof(randbits
))
237 printf("inet: unable to read random data from %s: %s\n",
238 RANDOM_DEV_NAME
, r
== -1 ? strerror(errno
) :
239 r
== 0 ? "EOF" : "not enough data");
245 printf("inet: unable to open random device %s: %s\n",
246 RANDOM_DEV_NAME
, strerror(errno
));
250 printf("inet: using current time for random-number seed\n");
251 r
= gettimeofday(&tv
, NULL
);
254 printf("sysutime failed: %s\n", strerror(errno
));
257 memcpy(randbits
, &tv
, sizeof(tv
));
259 init_rand256(randbits
);
261 /* Our new identity as a server. */
262 this_proc
= info
->endpoint
;
264 #ifdef BUF_CONSISTENCY_CHECK
265 inet_buf_debug
= (getenv("inetbufdebug") &&
266 (strcmp(getenv("inetbufdebug"), "on") == 0));
270 ip_warning(( "buffer consistency check enabled" ));
274 if (getenv("killerinet"))
276 ip_warning(( "killer inet active" ));
282 /* Subscribe to driver events for network drivers. */
283 r
= ds_subscribe("drv\\.net\\..*", DSF_INITIAL
| DSF_OVERWRITE
);
285 ip_panic(("inet: can't subscribe to driver events"));
288 /* Drop root privileges */
289 if ((pw
= getpwnam(SERVICE_LOGIN
)) == NULL
) {
290 printf("inet: unable to retrieve uid of SERVICE_LOGIN, "
291 "still running as root");
292 } else if (setuid(pw
->pw_uid
) != 0) {
293 ip_panic(("inet: unable to drop privileges"));
296 /* Announce we are up. INET announces its presence to VFS just like
297 * any other character driver.
299 chardriver_announce();
304 static void nw_conf()
315 static void nw_init()
330 /*===========================================================================*
332 *===========================================================================*/
333 static void ds_event()
335 char key
[DS_MAX_KEYLEN
];
336 char *driver_prefix
= "drv.net.";
340 endpoint_t owner_endpoint
;
344 prefix_len
= strlen(driver_prefix
);
346 /* We may get one notification for multiple updates from DS. Get events
347 * and owners from DS, until DS tells us that there are no more.
349 while ((r
= ds_check(key
, &type
, &owner_endpoint
)) == OK
) {
350 r
= ds_retrieve_u32(key
, &value
);
352 printf("inet: ds_event: ds_retrieve_u32 failed\n");
356 /* Only check for network driver up events. */
357 if(strncmp(key
, driver_prefix
, prefix_len
)
358 || value
!= DS_DRIVER_UP
) {
362 /* The driver label comes after the prefix. */
363 label
= key
+ prefix_len
;
365 /* A driver is (re)started. */
366 eth_check_driver(label
, owner_endpoint
);
370 printf("inet: ds_event: ds_check failed: %d\n", r
);
373 void panic0(file
, line
)
377 printf("panic at %s, %d: ", file
, line
);
382 printf("\ninet stacktrace: ");
384 (panic
)("aborted due to a panic");
389 void bad_assertion(file
, line
, what
)
395 printf("assertion \"%s\" failed", what
);
400 void bad_compare(file
, line
, lhs
, what
, rhs
)
408 printf("compare (%d) %s (%d) failed", lhs
, what
, rhs
);
414 * $PchId: inet.c,v 1.23 2005/06/28 14:27:22 philip Exp $