1 /*
2 * Copyright 1999-2001 Red Hat, Inc.
3 *
4 * All Rights Reserved.
5 *
6 * The above copyright notice and this permission notice shall be included in
7 * all copies or substantial portions of the Software.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
10 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
12 * OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
13 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15 *
16 * Except as contained in this notice, the name of Red Hat shall not be
17 * used in advertising or otherwise to promote the sale, use or other dealings
18 * in this Software without prior written authorization from Red Hat.
19 *
20 */
21
22 #include <arpa/inet.h>
23 #include <errno.h>
24 #include <popt.h>
25 #include <resolv.h>
26 #include <net/if.h>
27 #include <newt.h>
28 #include <stdlib.h>
29 #include <string.h>
30
31 #ifdef __STANDALONE__
32 #include <netdb.h>
33 #include <libintl.h>
34 #include <locale.h>
35
36 #define _(String) gettext((String))
37 #define N_(String) String
38
39 #define LOADER_BACK 2
40 #define LOADER_OK 0
41 #define LOADER_ERROR -1;
42
43 #include "net.h"
44 #include "pump.h"
45
46 #else
47
48 # include "isys/dns.h"
49
50 #include "kickstart.h"
51 #include "lang.h"
52 #include "loader.h"
53 #include "log.h"
54 #include "net.h"
55 #include "windows.h"
56
57 #endif /* __STANDALONE__ */
58
59 struct intfconfig_s {
60 newtComponent ipEntry, nmEntry, gwEntry, nsEntry;
61 char * ip, * nm, * gw, * ns;
62 };
63
64 typedef int int32;
65
66 char * hwaddr = NULL;
67 char * desc = NULL;
68
69 #ifdef __STANDALONE__
70 static FILE * logfile = NULL;
71
72 #define FL_TESTING(foo) 1
73
logMessage(const char * s,...)74 void logMessage(const char * s, ...) {
75 va_list args;
76
77 if (!logfile) return;
78 va_start(args, s);
79
80 fprintf(logfile, "* ");
81 vfprintf(logfile, s, args);
82 fprintf(logfile, "\n");
83 fflush(logfile);
84
85 va_end(args);
86
87 return;
88 }
89
90 /* yawn. This really should be in newt. */
winStatus(int width,int height,char * title,char * text,...)91 void winStatus(int width, int height, char * title,
92 char * text, ...) {
93 newtComponent t, f;
94 char * buf = NULL;
95 int size = 0;
96 int i = 0;
97 va_list args;
98
99 va_start(args, text);
100
101 do {
102 size += 1000;
103 if (buf) free(buf);
104 buf = malloc(size);
105 i = vsnprintf(buf, size, text, args);
106 } while (i == size);
107
108 va_end(args);
109
110 newtCenteredWindow(width, height, title);
111
112 t = newtTextbox(1, 1, width - 2, height - 2, NEWT_TEXTBOX_WRAP);
113 newtTextboxSetText(t, buf);
114 f = newtForm(NULL, NULL, 0);
115
116 free(buf);
117
118 newtFormAddComponent(f, t);
119
120 newtDrawForm(f);
121 newtRefresh();
122 newtFormDestroy(f);
123 }
124
125 #endif
126
ipCallback(newtComponent co,void * dptr)127 static void ipCallback(newtComponent co, void * dptr) {
128 struct intfconfig_s * data = dptr;
129 struct in_addr ipaddr, nmaddr, addr;
130 char * ascii;
131 int broadcast, network;
132
133 if (co == data->ipEntry) {
134 if (strlen(data->ip) && !strlen(data->nm)) {
135 if (inet_aton(data->ip, &ipaddr)) {
136 ipaddr.s_addr = ntohl(ipaddr.s_addr);
137 if (((ipaddr.s_addr & 0xFF000000) >> 24) <= 127)
138 ascii = "255.0.0.0";
139 else if (((ipaddr.s_addr & 0xFF000000) >> 24) <= 191)
140 ascii = "255.255.0.0";
141 else
142 ascii = "255.255.255.0";
143 newtEntrySet(data->nmEntry, ascii, 1);
144 }
145 }
146 } else if (co == data->nmEntry) {
147 if (!strlen(data->ip) || !strlen(data->nm)) return;
148 if (!inet_aton(data->ip, &ipaddr)) return;
149 if (!inet_aton(data->nm, &nmaddr)) return;
150
151 network = ipaddr.s_addr & nmaddr.s_addr;
152 broadcast = (ipaddr.s_addr & nmaddr.s_addr) | (~nmaddr.s_addr);
153
154 if (!strlen(data->gw)) {
155 addr.s_addr = htonl(ntohl(broadcast) - 1);
156 newtEntrySet(data->gwEntry, inet_ntoa(addr), 1);
157 }
158
159 if (!strlen(data->ns)) {
160 addr.s_addr = htonl(ntohl(network) + 1);
161 newtEntrySet(data->nsEntry, inet_ntoa(addr), 1);
162 }
163 }
164 }
165
166 #ifndef __STANDALONE__
nfsGetSetup(char ** hostptr,char ** dirptr)167 int nfsGetSetup(char ** hostptr, char ** dirptr) {
168 struct newtWinEntry entries[3];
169 char * newServer = *hostptr ? strdup(*hostptr) : NULL;
170 char * newDir = *dirptr ? strdup(*dirptr) : NULL;
171 int rc;
172
173 entries[0].text = _("NFS server name:");
174 entries[0].value = &newServer;
175 entries[0].flags = NEWT_FLAG_SCROLL;
176 entries[1].text = _("Red Hat directory:");
177 entries[1].value = &newDir;
178 entries[1].flags = NEWT_FLAG_SCROLL;
179 entries[2].text = NULL;
180 entries[2].value = NULL;
181
182 rc = newtWinEntries(_("NFS Setup"),
183 _("Please enter the following information:\n"
184 "\n"
185 " o the name or IP number of your NFS server\n"
186 " o the directory on that server containing\n"
187 " Red Hat Linux for your architecture"), 60, 5, 15,
188 24, entries, _("OK"), _("Back"), NULL);
189
190 if (rc == 2) {
191 if (newServer) free(newServer);
192 if (newDir) free(newDir);
193 return LOADER_BACK;
194 }
195
196 if (*hostptr) free(*hostptr);
197 if (*dirptr) free(*dirptr);
198 *hostptr = newServer;
199 *dirptr = newDir;
200
201 return 0;
202 }
203 #endif
204
fillInIpInfo(struct networkDeviceConfig * cfg)205 static void fillInIpInfo(struct networkDeviceConfig * cfg) {
206 int32 * i;
207 char * nm;
208
209 if (!(cfg->dev.set & PUMP_INTFINFO_HAS_NETMASK)) {
210 i = (int32 *) &cfg->dev.ip;
211
212 if (((*i & 0xFF000000) >> 24) <= 127)
213 nm = "255.0.0.0";
214 else if (((*i & 0xFF000000) >> 24) <= 191)
215 nm = "255.255.0.0";
216 else
217 nm = "255.255.255.0";
218
219 inet_aton(nm, &cfg->dev.netmask);
220 cfg->dev.set |= PUMP_INTFINFO_HAS_NETMASK;
221 }
222
223 if (!(cfg->dev.set & PUMP_INTFINFO_HAS_BROADCAST)) {
224 *((int32 *) &cfg->dev.broadcast) = (*((int32 *) &cfg->dev.ip) &
225 *((int32 *) &cfg->dev.netmask)) |
226 ~(*((int32 *) &cfg->dev.netmask));
227 cfg->dev.set |= PUMP_INTFINFO_HAS_BROADCAST;
228 }
229
230 if (!(cfg->dev.set & PUMP_INTFINFO_HAS_NETWORK)) {
231 *((int32 *) &cfg->dev.network) =
232 *((int32 *) &cfg->dev.ip) &
233 *((int32 *) &cfg->dev.netmask);
234 cfg->dev.set |= PUMP_INTFINFO_HAS_NETWORK;
235 }
236 }
237
238 #ifndef __STANDALONE__
initLoopback(void)239 void initLoopback(void) {
240 struct pumpNetIntf dev;
241
242 strcpy(dev.device, "lo");
243 inet_aton("127.0.0.1", &dev.ip);
244 inet_aton("255.0.0.0", &dev.netmask);
245 inet_aton("127.0.0.0", &dev.network);
246 dev.set = PUMP_INTFINFO_HAS_NETMASK | PUMP_INTFINFO_HAS_IP
247 | PUMP_INTFINFO_HAS_NETWORK;
248
249 pumpSetupInterface(&dev);
250 }
251 #endif
252
dhcpBoxCallback(newtComponent co,void * ptr)253 static void dhcpBoxCallback(newtComponent co, void * ptr) {
254 struct intfconfig_s * c = ptr;
255
256 newtEntrySetFlags(c->ipEntry, NEWT_FLAG_DISABLED, NEWT_FLAGS_TOGGLE);
257 newtEntrySetFlags(c->gwEntry, NEWT_FLAG_DISABLED, NEWT_FLAGS_TOGGLE);
258 newtEntrySetFlags(c->nmEntry, NEWT_FLAG_DISABLED, NEWT_FLAGS_TOGGLE);
259 newtEntrySetFlags(c->nsEntry, NEWT_FLAG_DISABLED, NEWT_FLAGS_TOGGLE);
260 }
261
getDnsServers(struct networkDeviceConfig * cfg)262 static int getDnsServers(struct networkDeviceConfig * cfg) {
263 int rc;
264 char * ns = "";
265 struct newtWinEntry entry[] = { { N_("Nameserver IP"), &ns, 0 },
266 { NULL, NULL, 0 } };
267
268 do {
269 rc = newtWinEntries(_("Nameserver"),
270 _("Your dynamic IP request returned IP configuration "
271 "information, but it did not include a DNS nameserver. "
272 "If you know what your nameserver is, please enter it "
273 "now. If you don't have this information, you can leave "
274 "this field blank and the install will continue."),
275 40, 5, 10, 25, entry, _("OK"), _("Back"), NULL);
276
277 if (rc == 2) return LOADER_BACK;
278
279 if (ns && *ns && !inet_aton(ns, &cfg->dev.dnsServers[0])) {
280 newtWinMessage(_("Invalid IP Information"), _("Retry"),
281 _("You entered an invalid IP address."));
282 rc = 2;
283 }
284
285 } while (rc == 2);
286
287 cfg->dev.set |= PUMP_NETINFO_HAS_DNS;
288 cfg->dev.numDns = 1;
289
290 return LOADER_OK;
291 }
292
readNetConfig(char * device,struct networkDeviceConfig * cfg,int flags)293 int readNetConfig(char * device, struct networkDeviceConfig * cfg, int flags) {
294 newtComponent text, f, okay, back, answer, dhcpCheckbox;
295 newtGrid grid, subgrid, buttons;
296 struct networkDeviceConfig newCfg;
297 struct intfconfig_s c;
298 int i;
299 struct in_addr addr;
300 char dhcpChoice;
301 char * chptr;
302
303 text = newtTextboxReflowed(-1, -1,
304 _("Please enter the IP configuration for this machine. Each "
305 "item should be entered as an IP address in dotted-decimal "
306 "notation (for example, 1.2.3.4)."), 50, 5, 10, 0);
307
308 subgrid = newtCreateGrid(2, 4);
309 newtGridSetField(subgrid, 0, 0, NEWT_GRID_COMPONENT,
310 newtLabel(-1, -1, _("IP address:")),
311 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
312 newtGridSetField(subgrid, 0, 1, NEWT_GRID_COMPONENT,
313 newtLabel(-1, -1, _("Netmask:")),
314 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
315 newtGridSetField(subgrid, 0, 2, NEWT_GRID_COMPONENT,
316 newtLabel(-1, -1, _("Default gateway (IP):")),
317 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
318 newtGridSetField(subgrid, 0, 3, NEWT_GRID_COMPONENT,
319 newtLabel(-1, -1, _("Primary nameserver:")),
320 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
321
322 c.ipEntry = newtEntry(-1, -1, NULL, 16, &c.ip, 0);
323 c.nmEntry = newtEntry(-1, -1, NULL, 16, &c.nm, 0);
324 c.gwEntry = newtEntry(-1, -1, NULL, 16, &c.gw, 0);
325 c.nsEntry = newtEntry(-1, -1, NULL, 16, &c.ns, 0);
326
327 if (!cfg->isDynamic) {
328 if (cfg->dev.set & PUMP_INTFINFO_HAS_IP)
329 newtEntrySet(c.ipEntry, inet_ntoa(cfg->dev.ip), 1);
330
331 if (cfg->dev.set & PUMP_INTFINFO_HAS_NETMASK)
332 newtEntrySet(c.nmEntry, inet_ntoa(cfg->dev.netmask), 1);
333
334 if (cfg->dev.set & PUMP_NETINFO_HAS_GATEWAY)
335 newtEntrySet(c.gwEntry, inet_ntoa(cfg->dev.gateway), 1);
336
337 if (cfg->dev.numDns)
338 newtEntrySet(c.nsEntry, inet_ntoa(cfg->dev.dnsServers[0]), 1);
339
340 dhcpChoice = ' ';
341 } else {
342 dhcpChoice = '*';
343 }
344
345 dhcpCheckbox = newtCheckbox(-1, -1,
346 _("Use dynamic IP configuration (BOOTP/DHCP)"),
347 dhcpChoice, NULL, &dhcpChoice);
348 newtComponentAddCallback(dhcpCheckbox, dhcpBoxCallback, &c);
349 if (dhcpChoice == '*') dhcpBoxCallback(dhcpCheckbox, &c);
350
351 newtGridSetField(subgrid, 1, 0, NEWT_GRID_COMPONENT, c.ipEntry,
352 1, 0, 0, 0, 0, 0);
353 newtGridSetField(subgrid, 1, 1, NEWT_GRID_COMPONENT, c.nmEntry,
354 1, 0, 0, 0, 0, 0);
355 newtGridSetField(subgrid, 1, 2, NEWT_GRID_COMPONENT, c.gwEntry,
356 1, 0, 0, 0, 0, 0);
357 newtGridSetField(subgrid, 1, 3, NEWT_GRID_COMPONENT, c.nsEntry,
358 1, 0, 0, 0, 0, 0);
359
360 buttons = newtButtonBar(_("OK"), &okay, _("Back"), &back, NULL);
361
362 grid = newtCreateGrid(1, 4);
363 newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text,
364 0, 0, 0, 1, 0, 0);
365 newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, dhcpCheckbox,
366 0, 0, 0, 1, 0, 0);
367 newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, subgrid,
368 0, 0, 0, 1, 0, 0);
369 newtGridSetField(grid, 0, 3, NEWT_GRID_SUBGRID, buttons,
370 0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX);
371
372 f = newtForm(NULL, NULL, 0);
373 newtGridAddComponentsToForm(grid, f, 1);
374 newtGridWrappedWindow(grid, _("Configure TCP/IP"));
375 newtGridFree(grid, 1);
376
377 newtComponentAddCallback(c.ipEntry, ipCallback, &c);
378 newtComponentAddCallback(c.nmEntry, ipCallback, &c);
379
380 do {
381 answer = newtRunForm(f);
382
383 if (answer == back) {
384 newtFormDestroy(f);
385 newtPopWindow();
386 return LOADER_BACK;
387 }
388
389 if (dhcpChoice == ' ') {
390 i = 0;
391 memset(&newCfg, 0, sizeof(newCfg));
392 if (*c.ip && inet_aton(c.ip, &addr)) {
393 i++;
394 newCfg.dev.ip = addr;
395 newCfg.dev.set |= PUMP_INTFINFO_HAS_IP;
396 }
397
398 if (*c.nm && inet_aton(c.nm, &addr)) {
399 i++;
400 newCfg.dev.netmask = addr;
401 newCfg.dev.set |= PUMP_INTFINFO_HAS_NETMASK;
402 }
403
404 if (i != 2) {
405 newtWinMessage(_("Missing Information"), _("Retry"),
406 _("You must enter both a valid IP address and a "
407 "netmask."));
408 }
409
410 strcpy(newCfg.dev.device, device);
411 newCfg.isDynamic = 0;
412 } else {
413 if (!FL_TESTING(flags)) {
414 winStatus(50, 3, _("Dynamic IP"),
415 _("Sending request for IP information..."),
416 0);
417 chptr = pumpDhcpRun(device, 0, 0, NULL, &newCfg.dev, NULL);
418 newtPopWindow();
419 } else {
420 chptr = NULL;
421 }
422
423 if (!chptr) {
424 newCfg.isDynamic = 1;
425 #ifdef __STANDALONE__
426 i = 2;
427 #else
428 if (!(newCfg.dev.set & PUMP_NETINFO_HAS_DNS)) {
429 logMessage("pump worked, but didn't return a DNS server");
430 i = getDnsServers(&newCfg);
431 i = i ? 0 : 2;
432 } else {
433 i = 2;
434 }
435 #endif
436 } else {
437 logMessage("pump told us: %s", chptr);
438 i = 0;
439 }
440 }
441 } while (i != 2);
442
443 #ifdef __STANDALONE__
444 if (!newCfg.isDynamic)
445 #endif
446 cfg->dev = newCfg.dev;
447 cfg->isDynamic = newCfg.isDynamic;
448
449 fillInIpInfo(cfg);
450
451 if (!(cfg->dev.set & PUMP_NETINFO_HAS_GATEWAY)) {
452 if (*c.gw && inet_aton(c.gw, &addr)) {
453 cfg->dev.gateway = addr;
454 cfg->dev.set |= PUMP_NETINFO_HAS_GATEWAY;
455 }
456 }
457
458 if (!(cfg->dev.numDns)) {
459 if (*c.ns && inet_aton(c.ns, &addr)) {
460 cfg->dev.dnsServers[0] = addr;
461 cfg->dev.numDns = 1;
462 }
463 }
464
465 newtPopWindow();
466
467 if (!FL_TESTING(flags)) {
468 configureNetwork(cfg);
469 findHostAndDomain(cfg, flags);
470 writeResolvConf(cfg);
471 }
472
473 #ifdef __STANDALONE__
474 writeResolvConf(cfg);
475 #endif
476 return 0;
477 }
478
configureNetwork(struct networkDeviceConfig * dev)479 int configureNetwork(struct networkDeviceConfig * dev) {
480 pumpSetupInterface(&dev->dev);
481
482 if (dev->dev.set & PUMP_NETINFO_HAS_GATEWAY)
483 pumpSetupDefaultGateway(&dev->dev.gateway);
484
485 return 0;
486 }
487
writeNetInfo(const char * fn,struct networkDeviceConfig * dev,struct knownDevices * kd)488 int writeNetInfo(const char * fn, struct networkDeviceConfig * dev,
489 struct knownDevices * kd) {
490 FILE * f;
491 #ifndef __STANDALONE__
492 int i;
493 #endif
494
495 #ifndef __STANDALONE__
496 for (i = 0; i < kd->numKnown; i++)
497 if (!strcmp(kd->known[i].name, dev->dev.device)) break;
498 #endif
499
500 if (!(f = fopen(fn, "w"))) return -1;
501
502 if (desc) {
503 fprintf(f, "# %s\n", desc);
504 }
505
506 fprintf(f, "DEVICE=%s\n", dev->dev.device);
507
508 #ifndef __STANDALONE__
509 if (i < kd->numKnown && kd->known[i].code == CODE_PCMCIA)
510 fprintf(f, "ONBOOT=no\n");
511 else
512 #endif
513 fprintf(f, "ONBOOT=yes\n");
514
515 if (dev->isDynamic) {
516 fprintf(f, "BOOTPROTO=dhcp\n");
517 } else {
518 fprintf(f, "BOOTPROTO=static\n");
519 fprintf(f, "IPADDR=%s\n", inet_ntoa(dev->dev.ip));
520 fprintf(f, "NETMASK=%s\n", inet_ntoa(dev->dev.netmask));
521 if (dev->dev.set & PUMP_NETINFO_HAS_GATEWAY)
522 fprintf(f, "GATEWAY=%s\n", inet_ntoa(dev->dev.gateway));
523 }
524
525 if (dev->dev.set & PUMP_NETINFO_HAS_HOSTNAME)
526 fprintf(f, "HOSTNAME=%s\n", dev->dev.hostname);
527 if (dev->dev.set & PUMP_NETINFO_HAS_DOMAIN)
528 fprintf(f, "DOMAIN=%s\n", dev->dev.domain);
529
530 if (hwaddr) {
531 fprintf(f, "HWADDR=%s\n",hwaddr);
532 }
533
534 fclose(f);
535
536 return 0;
537 }
538
writeResolvConf(struct networkDeviceConfig * net)539 int writeResolvConf(struct networkDeviceConfig * net) {
540 char * filename = "/etc/resolv.conf";
541 FILE * f;
542 int i;
543
544 if (!(net->dev.set & PUMP_NETINFO_HAS_DOMAIN) && !net->dev.numDns)
545 return LOADER_ERROR;
546
547 f = fopen(filename, "w");
548 if (!f) {
549 logMessage("Cannot create %s: %s\n", filename, strerror(errno));
550 return LOADER_ERROR;
551 }
552
553 if (net->dev.set & PUMP_NETINFO_HAS_DOMAIN)
554 fprintf(f, "search %s\n", net->dev.domain);
555
556 for (i = 0; i < net->dev.numDns; i++)
557 fprintf(f, "nameserver %s\n", inet_ntoa(net->dev.dnsServers[i]));
558
559 fclose(f);
560
561 res_init(); /* reinit the resolver so DNS changes take affect */
562
563 return 0;
564 }
565
findHostAndDomain(struct networkDeviceConfig * dev,int flags)566 int findHostAndDomain(struct networkDeviceConfig * dev, int flags) {
567 char * name, * chptr;
568 #ifdef __STANDALONE__
569 struct hostent * he;
570 #endif
571
572 if (!FL_TESTING(flags)) {
573 writeResolvConf(dev);
574 }
575
576 if (!(dev->dev.set & PUMP_NETINFO_HAS_HOSTNAME)) {
577 winStatus(40, 3, _("Hostname"),
578 _("Determining host name and domain..."));
579 #ifdef __STANDALONE__
580 he = gethostbyaddr( (char *) &dev->dev.ip, sizeof (dev->dev.ip), AF_INET);
581 name = he ? he->h_name : 0;
582 #else
583 name = mygethostbyaddr(inet_ntoa(dev->dev.ip));
584 #endif
585 newtPopWindow();
586
587 if (!name) {
588 logMessage("reverse name lookup failed");
589 return 1;
590 }
591
592 logMessage("reverse name lookup worked");
593
594 dev->dev.hostname = strdup(name);
595 dev->dev.set |= PUMP_NETINFO_HAS_HOSTNAME;
596 } else {
597 name = dev->dev.hostname;
598 }
599
600 if (!(dev->dev.set & PUMP_NETINFO_HAS_DOMAIN)) {
601 for (chptr = name; *chptr && (*chptr != '.'); chptr++) ;
602 if (*chptr == '.') {
603 if (dev->dev.domain) free(dev->dev.domain);
604 dev->dev.domain = strdup(chptr + 1);
605 dev->dev.set |= PUMP_NETINFO_HAS_DOMAIN;
606 }
607 }
608
609 return 0;
610 }
611
612 #ifndef __STANDALONE__
kickstartNetwork(char ** devicePtr,struct networkDeviceConfig * netDev,char * bootProto,int flags)613 int kickstartNetwork(char ** devicePtr, struct networkDeviceConfig * netDev,
614 char * bootProto, int flags) {
615 char ** ksArgv;
616 int ksArgc;
617 int netSet, rc;
618 char * arg, * chptr;
619 char * kshostname=NULL;
620 poptContext optCon;
621 struct in_addr * parseAddress;
622 int noDns = 0;
623 char * device;
624 struct poptOption ksOptions[] = {
625 { "bootproto", '\0', POPT_ARG_STRING, &bootProto, 0 },
626 { "device", '\0', POPT_ARG_STRING, devicePtr, 0 },
627 { "gateway", '\0', POPT_ARG_STRING, NULL, 'g' },
628 { "ip", '\0', POPT_ARG_STRING, NULL, 'i' },
629 { "nameserver", '\0', POPT_ARG_STRING, NULL, 'n' },
630 { "netmask", '\0', POPT_ARG_STRING, NULL, 'm' },
631 { "nodns", '\0', POPT_ARG_NONE, &noDns, 0 },
632 { "hostname", '\0', POPT_ARG_STRING, NULL, 'h'},
633 { 0, 0, 0, 0, 0 }
634 };
635
636 if (!bootProto) {
637 if (ksGetCommand(KS_CMD_NETWORK, NULL, &ksArgc, &ksArgv)) {
638 /* This is for compatibility with RH 5.0 */
639 ksArgv = alloca(sizeof(*ksArgv) * 1);
640 ksArgv[0] = "network";
641 ksArgc = 1;
642 }
643
644 optCon = poptGetContext(NULL, ksArgc, (const char **) ksArgv, ksOptions, 0);
645 while ((rc = poptGetNextOpt(optCon)) >= 0) {
646 parseAddress = NULL;
647 netSet = 0;
648
649 arg = (char *) poptGetOptArg(optCon);
650
651 switch (rc) {
652 case 'g':
653 parseAddress = &netDev->dev.gateway;
654 netSet = PUMP_NETINFO_HAS_GATEWAY;
655 break;
656
657 case 'i':
658 parseAddress = &netDev->dev.ip;
659 netSet = PUMP_INTFINFO_HAS_IP;
660 break;
661
662 case 'n':
663 parseAddress = &netDev->dev.dnsServers[netDev->dev.numDns++];
664 netSet = PUMP_NETINFO_HAS_DNS;
665 break;
666
667 case 'm':
668 parseAddress = &netDev->dev.netmask;
669 netSet = PUMP_INTFINFO_HAS_NETMASK;
670 break;
671
672 case 'h':
673 if (kshostname)
674 free(kshostname);
675 kshostname = strdup(arg);
676 logMessage("netDev->dev.hostname = %s", kshostname);
677 break;
678 }
679
680 if (parseAddress && !inet_aton(arg, parseAddress)) {
681 logMessage("bad ip number in network command: %s", arg);
682 return -1;
683 }
684
685 netDev->dev.set |= netSet;
686 }
687
688 if (rc < -1) {
689 newtWinMessage(_("kickstart"), _("OK"),
690 _("bad argument to kickstart network command %s: %s"),
691 poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
692 poptStrerror(rc));
693 } else {
694 poptFreeContext(optCon);
695 }
696 }
697
698 device = *devicePtr;
699
700 if (!bootProto)
701 bootProto = "dhcp";
702
703 if (!strcmp(bootProto, "dhcp") || !strcmp(bootProto, "bootp")) {
704 logMessage("sending dhcp request through device %s", device);
705 winStatus(50, 3, _("Dynamic IP"),
706 _("Sending request for IP information..."),
707 0);
708
709 chptr = pumpDhcpRun(device, 0, 0, NULL, &netDev->dev, NULL);
710 newtPopWindow();
711 if (chptr) {
712 logMessage("pump told us: %s", chptr);
713 return -1;
714 }
715 netDev->isDynamic = 1;
716 } else if (!strcmp(bootProto, "static")) {
717 strcpy(netDev->dev.device, device);
718 } else if (!strcmp(bootProto, "query")) {
719 strcpy(netDev->dev.device, device);
720 readNetConfig("eth0", netDev, flags);
721 } else {
722 newtWinMessage(_("kickstart"), _("OK"),
723 _("Bad bootproto %s specified in network command"),
724 bootProto);
725 return -1;
726 }
727
728 fillInIpInfo(netDev);
729 configureNetwork(netDev);
730
731 logMessage("nodns is %d", noDns);
732
733 if (kshostname) {
734 logMessage("setting ks specified hostname of %s", kshostname);
735 netDev->dev.hostname=strdup(kshostname);
736 netDev->dev.set |= PUMP_NETINFO_HAS_HOSTNAME;
737 }
738
739 if (!noDns)
740 findHostAndDomain(netDev, flags);
741
742 writeResolvConf(netDev);
743
744 return 0;
745 }
746 #endif
747
748 #ifdef __STANDALONE__
749
main(int argc,const char ** argv)750 int main(int argc, const char **argv) {
751 int netSet, rc;
752 int x;
753 int noDns = 0;
754 char * bootProto = NULL;
755 char * device = NULL;
756 char * hostname = NULL;
757 char * domain = NULL;
758 const char * arg;
759 char path[256];
760 char roottext[80];
761 poptContext optCon;
762 struct networkDeviceConfig *netDev;
763 struct in_addr * parseAddress;
764 struct poptOption Options[] = {
765 POPT_AUTOHELP
766 { "bootproto", '\0', POPT_ARG_STRING, &bootProto, 0,
767 _("Boot protocol to use"), "(dhcp|bootp|none)" },
768 { "gateway", '\0', POPT_ARG_STRING, NULL, 'g',
769 _("Network gateway"), NULL },
770 { "ip", '\0', POPT_ARG_STRING, NULL, 'i',
771 _("IP address"), NULL },
772 { "nameserver", '\0', POPT_ARG_STRING, NULL, 'n',
773 _("Nameserver"), NULL },
774 { "netmask", '\0', POPT_ARG_STRING, NULL, 'm',
775 _("Netmask"), NULL },
776 { "hostname", '\0', POPT_ARG_STRING, &hostname, 0,
777 _("Hostname"), NULL
778 },
779 { "domain", '\0', POPT_ARG_STRING, &domain, 0,
780 _("Domain name"), NULL
781 },
782 { "device", 'd', POPT_ARG_STRING, &device, 0,
783 _("Network device"), NULL
784 },
785 { "nodns", '\0', POPT_ARG_NONE, &noDns, 0,
786 _("No DNS lookups"), NULL
787 },
788 { "hwaddr", '\0', POPT_ARG_STRING, &hwaddr, 0,
789 _("Ethernet hardware address"), NULL
790 },
791 { "description", '\0', POPT_ARG_STRING, &desc, 0,
792 _("Description of the device"), NULL
793 },
794 { 0, 0, 0, 0, 0 }
795 };
796
797 bindtextdomain("pump", "/usr/share/locale");
798 textdomain("pump");
799
800 netDev = malloc(sizeof(struct networkDeviceConfig));
801 memset(netDev,'\0',sizeof(struct networkDeviceConfig));
802 optCon = poptGetContext("netconfig", argc, argv, Options, 0);
803 while ((rc = poptGetNextOpt(optCon)) >= 0) {
804 parseAddress = NULL;
805 netSet = 0;
806
807 arg = poptGetOptArg(optCon);
808
809 switch (rc) {
810 case 'g':
811 parseAddress = &netDev->dev.gateway;
812 netSet = PUMP_NETINFO_HAS_GATEWAY;
813 break;
814
815 case 'i':
816 parseAddress = &netDev->dev.ip;
817 netSet = PUMP_INTFINFO_HAS_IP;
818 break;
819
820 case 'n':
821 parseAddress = &netDev->dev.dnsServers[netDev->dev.numDns++];
822 netSet = PUMP_NETINFO_HAS_DNS;
823 break;
824
825 case 'm':
826 parseAddress = &netDev->dev.netmask;
827 netSet = PUMP_INTFINFO_HAS_NETMASK;
828 break;
829 }
830
831 if (!inet_aton(arg, parseAddress)) {
832 logMessage("bad ip number in network command: %s", arg);
833 return -1;
834 }
835
836 netDev->dev.set |= netSet;
837 }
838
839 if (rc < -1) {
840 fprintf(stderr, "%s: %s\n",
841 poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
842 poptStrerror(rc));
843 } else {
844 poptFreeContext(optCon);
845 }
846
847 if (netDev->dev.set ||
848 (bootProto && (!strcmp(bootProto, "dhcp") || !strcmp(bootProto, "bootp")))) {
849 if (!device) device="eth0";
850 if (bootProto && (!strcmp(bootProto, "dhcp") || !strcmp(bootProto, "bootp")))
851 netDev->isDynamic++;
852 strncpy(netDev->dev.device,device,10);
853 if (hostname) {
854 netDev->dev.hostname=strdup(hostname);
855 netDev->dev.set |= PUMP_NETINFO_HAS_HOSTNAME;
856 }
857 if (domain) {
858 netDev->dev.domain=strdup(domain);
859 netDev->dev.set |= PUMP_NETINFO_HAS_DOMAIN;
860 }
861 snprintf(path,256,"/etc/sysconfig/network-scripts/ifcfg-%s",device);
862 writeNetInfo(path,netDev, NULL);
863 } else {
864 newtInit();
865 newtCls();
866 newtPushHelpLine(_(" <Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen"));
867 snprintf(roottext,80,_("netconfig %s (C) 1999 Red Hat, Inc."), VERSION);
868 newtDrawRootText(0, 0, roottext);
869 if (!device) {
870 x=newtWinChoice(_("Network configuration"),_("Yes"),_("No"),
871 _("Would you like to set up networking?"));
872 if (x==2) {
873 newtFinished();
874 exit(0);
875 }
876 device = "eth0";
877 }
878 strncpy(netDev->dev.device,device,10);
879 if (readNetConfig(device,netDev,0) != LOADER_BACK) {
880 snprintf(path,256,"/etc/sysconfig/network-scripts/ifcfg-%s",device);
881 writeNetInfo(path,netDev, NULL);
882 }
883 newtFinished();
884 }
885 exit(0);
886 }
887 #endif
888