4 Created: Nov 11, 1992 by Philip Homburg
6 Modified: Apr 07, 2001 by Kees J. Bot
7 Read the configuration file and fill in the xx_conf[] arrays.
9 Copyright 1995 Philip Homburg
12 #define _MINIX_SOURCE 1
13 #define _POSIX_SOURCE 1
20 #include <sys/types.h>
22 #include <minix/type.h>
23 #include <minix/sysutil.h>
24 #include <minix/syslib.h>
25 #include "inet_config.h"
30 struct eth_conf eth_conf
[IP_PORT_MAX
];
31 struct psip_conf psip_conf
[IP_PORT_MAX
];
32 struct ip_conf ip_conf
[IP_PORT_MAX
];
33 struct tcp_conf tcp_conf
[IP_PORT_MAX
];
34 struct udp_conf udp_conf
[IP_PORT_MAX
];
43 int ip_forward_directed_bcast
= 0; /* Default is off */
45 static u8_t iftype
[IP_PORT_MAX
]; /* Interface in use as? */
46 static int ifdefault
= -1; /* Default network interface. */
48 static void fatal(char *label
)
50 printf("init: %s: %s\n", label
, strerror(errno
));
54 static void check_rm(char *device
)
55 /* Check if a device is not among the living. */
57 if (unlink(device
) < 0) {
58 if (errno
== ENOENT
) return;
61 printf("rm %s\n", device
);
64 static void check_mknod(char *device
, mode_t mode
, int minor
)
65 /* Check if a device exists with the proper device number. */
70 dev
= (ip_dev
& 0xFF00) | minor
;
72 if (stat(device
, &st
) < 0) {
73 if (errno
!= ENOENT
) fatal(device
);
75 if (S_ISCHR(st
.st_mode
) && st
.st_rdev
== dev
) return;
76 if (unlink(device
) < 0) fatal(device
);
79 if (mknod(device
, S_IFCHR
| mode
, dev
) < 0) fatal(device
);
80 printf("mknod %s c %d %d\n", device
, (ip_dev
>> 8), minor
);
83 static void check_ln(char *old
, char *new)
84 /* Check if 'old' and 'new' are still properly linked. */
86 struct stat st_old
, st_new
;
88 if (stat(old
, &st_old
) < 0) fatal(old
);
89 if (stat(new, &st_new
) < 0) {
90 if (errno
!= ENOENT
) fatal(new);
92 if (st_new
.st_dev
== st_old
.st_dev
93 && st_new
.st_ino
== st_old
.st_ino
) {
96 if (unlink(new) < 0) fatal(new);
99 if (link(old
, new) < 0) fatal(new);
100 printf("ln %s %s\n", old
, new);
103 static void check_dev(int type
, int ifno
)
104 /* Check if the device group with interface number 'ifno' exists and has the
105 * proper device numbers. If 'type' is -1 then the device group must be
109 static struct devlist
{
114 { "/dev/eth", 0600, ETH_DEV_OFF
},
115 { "/dev/psip", 0600, PSIP_DEV_OFF
},
116 { "/dev/ip", 0600, IP_DEV_OFF
},
117 { "/dev/tcp", 0666, TCP_DEV_OFF
},
118 { "/dev/udp", 0666, UDP_DEV_OFF
},
122 char device
[sizeof("/dev/psip99")];
125 for (i
= 0; i
< sizeof(devlist
) / sizeof(devlist
[0]); i
++) {
127 strcpy(device
, dvp
->defname
);
128 dp
= device
+ strlen(device
);
129 if (ifno
>= 10) *dp
++ = '0' + (ifno
/ 10);
130 *dp
++ = '0' + (ifno
% 10);
134 || (i
== 0 && type
!= NETTYPE_ETH
)
135 || (i
== 1 && type
!= NETTYPE_PSIP
)
138 if (ifno
== ifdefault
) check_rm(dvp
->defname
);
140 check_mknod(device
, dvp
->mode
,
141 if2minor(ifno
, dvp
->minor_off
));
142 if (ifno
== ifdefault
) check_ln(device
, dvp
->defname
);
145 check_mknod(IPSTAT_DEV
, IPSTAT_MODE
, IPSTAT_MINOR
);
149 static char word
[16];
150 static unsigned line
;
152 static void error(void)
154 printf("inet: error on line %u\n", line
);
158 static void token(int need
)
160 /* Read a word from the configuration file. Return a null string on
161 * EOF. Return a punctiation as a one character word. If 'need' is
162 * true then an actual word is expected at this point, so err out if
166 static unsigned char c
= '\n';
168 wp
= (unsigned char *) word
;
172 if (c
== '\n') line
++;
173 if (read(cfg_fd
, &c
, 1) != 1) {
180 if (wp
< (unsigned char *) word
+ sizeof(word
)-1) *wp
++ = c
;
181 if (read(cfg_fd
, &c
, 1) != 1) c
= ' ';
182 if (word
[0] == ';' || word
[0] == '{' || word
[0] == '}') {
186 } while (c
> ' ' && c
!= ';' && c
!= '{' && c
!= '}');
190 static unsigned number(char *str
, unsigned max
)
192 /* Interpret a string as an unsigned decimal number, no bigger than
193 * 'max'. Return this number.
200 while ((d
= (*s
- '0')) < 10 && n
<= max
) {
204 if (*s
!= 0 || n
> max
) {
205 printf("inet: '%s' is not a number <= %u\n", str
, max
);
213 int i
, j
, ifno
, type
, port
, enable
;
214 struct eth_conf
*ecp
;
215 struct psip_conf
*pcp
;
219 { static int first
= 1;
220 if (!first
) ip_panic(( "read_conf: called a second time" ));
223 *(u8_t
*)0 = 0xcc; /* INT 3 */
228 /* Open the configuration file. */
229 if ((cfg_fd
= open(PATH_INET_CONF
, O_RDONLY
)) == -1)
230 fatal(PATH_INET_CONF
);
236 while (token(0), word
[0] != 0) {
237 if (strncmp(word
, "eth", 3) == 0) {
238 ecp
->ec_ifno
= ifno
= number(word
+3, IP_PORT_MAX
-1);
242 if (strcmp(word
, "vlan") == 0) {
244 ecp
->ec_vlan
= number(word
, (1<<12)-1);
246 if (strncmp(word
, "eth", 3) != 0) {
248 "inet: VLAN eth%d can't be built on %s\n",
252 ecp
->ec_port
= number(word
+3, IP_PORT_MAX
-1);
254 ecp
->ec_task
= alloc(strlen(word
)+1);
255 strcpy(ecp
->ec_task
, word
);
257 ecp
->ec_port
= number(word
, IP_PORT_MAX
-1);
262 if (strncmp(word
, "psip", 4) == 0) {
263 pcp
->pc_ifno
= ifno
= number(word
+4, IP_PORT_MAX
-1);
269 printf("inet: Unknown device '%s'\n", word
);
274 icp
->ic_devtype
= type
;
276 tcp_conf
[tcp_conf_nr
].tc_port
= ip_conf_nr
;
277 udp_conf
[udp_conf_nr
].uc_port
= ip_conf_nr
;
279 enable
= 7; /* 1 = IP, 2 = TCP, 4 = UDP */
282 if (word
[0] == '{') {
284 while (word
[0] != '}') {
285 if (strcmp(word
, "default") == 0) {
286 if (ifdefault
!= -1) {
288 "inet: ip%d and ip%d can't both be default\n",
295 if (strcmp(word
, "no") == 0) {
297 if (strcmp(word
, "ip") == 0) {
300 if (strcmp(word
, "tcp") == 0) {
303 if (strcmp(word
, "udp") == 0) {
307 "inet: Can't do 'no %s'\n",
313 printf("inet: Unknown option '%s'\n",
317 if (word
[0] == ';') token(0);
319 if (word
[0] != '}') error();
323 if (word
[0] != ';' && word
[0] != 0) error();
325 if (enable
& 1) icp
++, ip_conf_nr
++;
326 if (enable
& 2) tcp_conf_nr
++;
327 if (enable
& 4) udp_conf_nr
++;
330 if (ifdefault
== -1) {
331 printf("inet: No networks or no default network defined\n");
335 /* Translate VLAN network references to port numbers. */
336 for (i
= 0; i
< eth_conf_nr
; i
++) {
338 if (eth_is_vlan(ecp
)) {
339 for (j
= 0; j
< eth_conf_nr
; j
++) {
340 if (eth_conf
[j
].ec_ifno
== ecp
->ec_port
341 && !eth_is_vlan(ð_conf
[j
])
347 if (j
== eth_conf_nr
) {
349 "inet: VLAN eth%d can't be built on eth%d\n",
350 ecp
->ec_ifno
, ecp
->ec_port
);
356 /* Set umask 0 so we can creat mode 666 devices. */
359 /* See what the device number of /dev/ip is. That's what we
360 * used last time for the network devices, so we keep doing so.
362 if (stat("/dev/ip", &st
) < 0) fatal("/dev/ip");
365 for (i
= 0; i
< IP_PORT_MAX
; i
++) {
366 /* Create network devices. */
367 check_dev(iftype
[i
], i
);
371 void *alloc(size_t size
)
373 /* Allocate memory on the heap with sbrk(). */
379 * $PchId: inet_config.c,v 1.10 2003/08/21 09:26:02 philip Exp $