diff --git a/distrib/utils/sysinst/net.c b/distrib/utils/sysinst/net.c index ec76a4f2f5da..0a3a36b5497f 100644 --- a/distrib/utils/sysinst/net.c +++ b/distrib/utils/sysinst/net.c @@ -1,4 +1,4 @@ -/* $NetBSD: net.c,v 1.86 2003/06/16 19:42:14 dsl Exp $ */ +/* $NetBSD: net.c,v 1.87 2003/07/18 09:42:59 dsl Exp $ */ /* * Copyright 1997 Piermont Information Systems Inc. @@ -25,13 +25,13 @@ * THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * */ @@ -51,6 +51,7 @@ #endif #include #include +#include #include #include "defs.h" #include "md.h" @@ -59,6 +60,29 @@ #include "txtwalk.h" int network_up = 0; +/* Access to network information */ +static char *net_devices; +static char *net_up; +static char net_dev[STRSIZE]; +static char net_domain[STRSIZE]; +static char net_host[STRSIZE]; +static char net_ip[STRSIZE]; +static char net_mask[STRSIZE]; +static char net_namesvr[STRSIZE]; +static char net_defroute[STRSIZE]; +static char net_media[STRSIZE]; +static int net_dhcpconf; +#define DHCPCONF_IPADDR 0x01 +#define DHCPCONF_NAMESVR 0x02 +#define DHCPCONF_HOST 0x04 +#define DHCPCONF_DOMAIN 0x08 +#ifdef INET6 +static char net_ip6[STRSIZE]; +static char net_namesvr6[STRSIZE]; +static int net_ip6conf; +#define IP6CONF_AUTOHOST 0x01 +#endif + /* URL encode unsafe characters. */ @@ -68,16 +92,15 @@ static char *url_encode (char *dst, const char *src, size_t len, /* Get the list of network interfaces. */ -static void get_ifconfig_info (void); static void get_ifinterface_info (void); static void write_etc_hosts(FILE *f); #define DHCLIENT_EX "/sbin/dhclient" #include -static int config_dhcp (char *); -static void get_command_out (char *, int, char *, char *); -static void get_dhcp_value (char *, char *); +static int config_dhcp(char *); +static void get_command_out(char *, int, char *, char *); +static void get_dhcp_value(char *, char *); #ifdef INET6 static int is_v6kernel (void); @@ -208,13 +231,20 @@ static void get_ifconfig_info(void) { char *textbuf; - char *t, *nt, *ndest; + char *t, *nt; const char **ignore; int textsize; + ulong fl; + char *cp; + + free(net_devices); + net_devices = NULL; + free(net_up); + net_up = NULL; /* Get ifconfig information */ - - textsize = collect(T_OUTPUT, &textbuf, "/sbin/ifconfig -l 2>/dev/null"); + + textsize = collect(T_OUTPUT, &textbuf, "/sbin/ifconfig -a 2>/dev/null"); if (textsize < 0) { if (logging) (void)fprintf(logfp, @@ -222,26 +252,50 @@ get_ifconfig_info(void) (void)fprintf(stderr, "Could not run ifconfig."); exit(1); } - (void)strtok(textbuf,"\n"); - nt = textbuf; - ndest = net_devices; - *ndest = '\0'; - while ((t = strsep(&nt, " ")) != NULL) { + for (t = textbuf; t != NULL && *t != 0; t = nt) { + /* find entry for next interface */ + for (nt = t; (nt = strchr(nt, '\n')); ) { + if (*++nt != '\t') + break; + } + if (memcmp(t, "lo0:", 4) == 0) + /* completely ignore loopback interface */ + continue; + cp = strchr(t, '='); + if (cp == NULL) + break; + /* get interface flags */ + fl = strtoul(cp + 1, &cp, 16); + if (*cp != '<') + break; + if (fl & IFF_UP) { + /* This interface might be connected to the server */ + cp = strchr(t, ':'); + if (cp == NULL) + break; + asprintf(&cp, "%s%.*s ", + net_up ? net_up : "", (int)(cp - t), t); + free(net_up); + net_up = cp; + } + for (ignore = ignored_if_names; *ignore != NULL; ignore++) { size_t len = strlen(*ignore); if (strncmp(t, *ignore, len) == 0 && isdigit((unsigned char)t[len])) - goto loop; + break; } + if (*ignore != NULL) + continue; - if (strlen(ndest) + 1 + strlen(t) + 1 > STRSIZE) - break; /* would overflow */ - - strcat(ndest, t); - strcat(ndest, " "); /* net_devices needs trailing space! */ -loop: - t = nt; + cp = strchr(t, ':'); + if (cp == NULL) + break; + asprintf(&cp, "%s%.*s ", + net_devices ? net_devices : "", (int)(cp - t), t); + free(net_devices); + net_devices = cp; } free(textbuf); } @@ -266,11 +320,15 @@ get_ifinterface_info(void) t = strtok(NULL, " \t\n"); if (strcmp(t, "0.0.0.0") != 0) strcpy(net_ip, t); - } else if (strcmp(t, "netmask") == 0) { + continue; + } + if (strcmp(t, "netmask") == 0) { t = strtok(NULL, " \t\n"); if (strcmp(t, "0x0") != 0) strcpy(net_mask, t); - } else if (strcmp(t, "media:") == 0) { + continue; + } + if (strcmp(t, "media:") == 0) { t = strtok(NULL, " \t\n"); /* handle "media: Ethernet manual" */ if (strcmp(t, "Ethernet") == 0) @@ -281,6 +339,7 @@ get_ifinterface_info(void) } } } + free(textbuf); #ifdef INET6 textsize = collect(T_OUTPUT, &textbuf, "/sbin/ifconfig %s inet6 2>/dev/null", net_dev); @@ -305,26 +364,22 @@ get_ifinterface_info(void) break; } } + free(textbuf); #endif /* Check host (and domain?) name */ if (gethostname(hostname, sizeof(hostname)) == 0) { - hostname[sizeof(hostname) - 1] = '\0'; + hostname[sizeof(hostname) - 1] = 0; /* check for a . */ dot = strchr(hostname, '.'); - if ( dot == NULL ) { + if (dot == NULL) { /* if not found its just a host, punt on domain */ - strncpy(net_host, hostname, sizeof(net_host)); + strlcpy(net_host, hostname, sizeof net_host); } else { /* split hostname into host/domain parts */ - size_t max_len = dot - hostname; - max_len = (sizeof(net_host) /dev/null", "nameserver"); - if (strlen(net_namesvr) != 0) + if (net_namesvr[0] != 0) net_dhcpconf |= DHCPCONF_NAMESVR; /* pull domainname out of leases file */ get_dhcp_value(net_domain, "domain-name"); - if (strlen(net_domain) != 0) + if (net_domain[0] != 0) net_dhcpconf |= DHCPCONF_DOMAIN; /* pull hostname out of leases file */ get_dhcp_value(net_host, "hostname"); - if (strlen(net_host) != 0) + if (net_host[0] != 0) net_dhcpconf |= DHCPCONF_HOST; } - msg_prompt_add(MSG_net_domain, net_domain, net_domain, STRSIZE); - msg_prompt_add(MSG_net_host, net_host, net_host, STRSIZE); + msg_prompt_add(MSG_net_domain, net_domain, net_domain, + sizeof net_domain); + msg_prompt_add(MSG_net_host, net_host, net_host, sizeof net_host); if (!dhcp_config) { /* Manually configure IPv4 */ - msg_prompt_add(MSG_net_ip, net_ip, net_ip, STRSIZE); + msg_prompt_add(MSG_net_ip, net_ip, net_ip, sizeof net_ip); octet0 = atoi(net_ip); if (!pass) { if (0 <= octet0 && octet0 <= 127) @@ -489,11 +551,12 @@ again: else if (192 <= octet0 && octet0 <= 223) strcpy(net_mask, "0xffffff00"); } - msg_prompt_add(MSG_net_mask, net_mask, net_mask, STRSIZE); + msg_prompt_add(MSG_net_mask, net_mask, net_mask, + sizeof net_mask); msg_prompt_add(MSG_net_defroute, net_defroute, net_defroute, - STRSIZE); + sizeof net_defroute); msg_prompt_add(MSG_net_namesrv, net_namesvr, net_namesvr, - STRSIZE); + sizeof net_namesvr); } #ifdef INET6 @@ -510,7 +573,7 @@ again: process_menu(MENU_namesrv6, NULL); if (!yesno) msg_prompt_add(MSG_net_namesrv6, net_namesvr6, - net_namesvr6, STRSIZE); + net_namesvr6, sizeof net_namesvr6); } #endif @@ -540,9 +603,9 @@ again: */ /* Create /etc/resolv.conf if a nameserver was given */ - if (strcmp(net_namesvr, "") != 0 + if (net_namesvr[0] != 0 #ifdef INET6 - || strcmp(net_namesvr6, "") != 0 + || net_namesvr6[0] != 0 #endif ) { #ifdef DEBUG @@ -560,12 +623,12 @@ again: scripting_fprintf(NULL, "cat </etc/resolv.conf\n"); time(&now); /* NB: ctime() returns a string ending in '\n' */ - scripting_fprintf(f, ";\n; BIND data file\n; %s %s;\n", - "Created by NetBSD sysinst on", ctime(&now)); - if (strcmp(net_namesvr, "") != 0) + scripting_fprintf(f, ";\n; BIND data file\n; %s %s;\n", + "Created by NetBSD sysinst on", ctime(&now)); + if (net_namesvr[0] != 0) scripting_fprintf(f, "nameserver %s\n", net_namesvr); #ifdef INET6 - if (strcmp(net_namesvr6, "") != 0) + if (net_namesvr6[0] != 0) scripting_fprintf(f, "nameserver %s\n", net_namesvr6); #endif scripting_fprintf(f, "search %s\n", net_domain); @@ -578,9 +641,8 @@ again: /* * ifconfig does not allow media specifiers on IFM_MANUAL interfaces. - * Our UI gies no way to set an option back to null-string if it + * Our UI gives no way to set an option back to null-string if it * gets accidentally set. - * good way to reset the media to null-string. * Check for plausible alternatives. */ if (strcmp(net_media, "") == 0 || @@ -607,28 +669,26 @@ again: } #endif - if (strcmp(net_ip, "") != 0) { - if (strcmp(net_mask, "") != 0) { - run_prog(0, NULL, + if (net_ip[0] != 0) { + if (net_mask[0] != 0) { + run_prog(0, NULL, "/sbin/ifconfig %s inet %s netmask %s", net_dev, net_ip, net_mask); } else { - run_prog(0, NULL, + run_prog(0, NULL, "/sbin/ifconfig %s inet %s", net_dev, net_ip); } } /* Set host name */ - if (strcmp(net_host, "") != 0) + if (net_host[0] != 0) sethostname(net_host, strlen(net_host)); /* Set a default route if one was given */ - if (strcmp(net_defroute, "") != 0) { - run_prog(0, NULL, - "/sbin/route -n flush -inet"); - run_prog(0, NULL, - "/sbin/route -n add default %s", - net_defroute); + if (net_defroute[0] != 0) { + run_prog(0, NULL, "/sbin/route -n flush -inet"); + run_prog(0, NULL, + "/sbin/route -n add default %s", net_defroute); } /* @@ -643,24 +703,22 @@ again: #ifdef INET6 if (v6config && network_up) { - network_up = !run_prog(0, NULL, + network_up = !run_prog(0, NULL, "/sbin/ping6 -v -c 3 -n -I %s ff02::2", net_dev); - if (strcmp(net_namesvr6, "") != 0) - network_up = !run_prog(RUN_DISPLAY, NULL, + if (net_namesvr6[0] != 0) + network_up = !run_prog(RUN_DISPLAY, NULL, "/sbin/ping6 -v -c 3 -n %s", net_namesvr6); } #endif - if (strcmp(net_namesvr, "") != 0 && network_up) - network_up = !run_prog(0, NULL, - "/sbin/ping -v -c 5 -w 5 -o -n %s", - net_namesvr); + if (net_namesvr[0] != 0 && network_up) + network_up = !run_prog(0, NULL, + "/sbin/ping -v -c 5 -w 5 -o -n %s", net_namesvr); - if (strcmp(net_defroute, "") != 0 && network_up) - network_up = !run_prog(0, NULL, - "/sbin/ping -v -c 5 -w 5 -o -n %s", - net_defroute); + if (net_defroute[0] != 0 && network_up) + network_up = !run_prog(0, NULL, + "/sbin/ping -v -c 5 -w 5 -o -n %s", net_defroute); fflush(NULL); return network_up; @@ -668,7 +726,7 @@ again: int get_via_ftp(void) -{ +{ distinfo *list; char ftp_user_encoded[STRSIZE]; char ftp_pass_encoded[STRSIZE]; @@ -700,7 +758,7 @@ get_via_ftp(void) list++; continue; } - (void)snprintf(filename, SSTRSIZE, "%s%s", list->name, + (void)snprintf(filename, sizeof filename, "%s%s", list->name, dist_postfix); /* * Invoke ftp to fetch the file. @@ -712,22 +770,26 @@ get_via_ftp(void) * example, ftp_dir could easily contain '~', which is * unsafe by a strict reading of RFC 1738). */ - if (strcmp ("ftp", ftp_user) == 0) - ret = run_prog(RUN_DISPLAY, NULL, + if (strcmp("ftp", ftp_user) == 0) + ret = run_prog(RUN_DISPLAY, NULL, "/usr/bin/ftp -a ftp://%s/%s/%s", ftp_host, - url_encode(ftp_dir_encoded, ftp_dir, STRSIZE, + url_encode(ftp_dir_encoded, ftp_dir, + sizeof ftp_dir_encoded, RFC1738_SAFE_LESS_SHELL_PLUS_SLASH, 1), filename); else { - ret = run_prog(RUN_DISPLAY, NULL, + ret = run_prog(RUN_DISPLAY, NULL, "/usr/bin/ftp ftp://%s:%s@%s/%s/%s", - url_encode(ftp_user_encoded, ftp_user, STRSIZE, + url_encode(ftp_user_encoded, ftp_user, + sizeof ftp_user_encoded, RFC1738_SAFE_LESS_SHELL, 0), - url_encode(ftp_pass_encoded, ftp_pass, STRSIZE, + url_encode(ftp_pass_encoded, ftp_pass, + sizeof ftp_pass_encoded, NULL, 0), ftp_host, - url_encode(ftp_dir_encoded, ftp_dir, STRSIZE, + url_encode(ftp_dir_encoded, ftp_dir, + sizeof ftp_dir_encoded, RFC1738_SAFE_LESS_SHELL_PLUS_SLASH, 1), filename); } @@ -746,7 +808,7 @@ get_via_ftp(void) process_menu(MENU_ftpsource, NULL); else return 0; - } else + } else list++; } @@ -784,11 +846,11 @@ get_via_nfs(void) process_menu(MENU_nfssource, NULL); again: - run_prog(0, NULL, + run_prog(0, NULL, "/sbin/umount /mnt2"); - + /* Mount it */ - if (run_prog(0, NULL, + if (run_prog(0, NULL, "/sbin/mount -r -o -2,-i,-r=1024 -t nfs %s:%s /mnt2", nfs_host, nfs_dir)) { msg_display(MSG_nfsbadmount, nfs_host, nfs_dir); @@ -845,19 +907,20 @@ write_etc_hosts(FILE *f) * Write the network config info the user entered via menus into the * config files in the target disk. Be careful not to lose any * information we don't immediately add back, in case the install - * target is the currently-active root. + * target is the currently-active root. */ void mnt_net_config(void) { - char ans [5] = "y"; - char ifconfig_fn [STRSIZE]; + char ans[8]; + char ifconfig_fn[STRSIZE]; FILE *ifconf = NULL; + const char *yes = msg_string(MSG_Yes); if (!network_up) return; - msg_prompt(MSG_mntnetconfig, ans, ans, 5); - if (*ans != 'y') + msg_prompt(MSG_mntnetconfig, yes, ans, sizeof ans); + if (strcmp(ans, yes) != 0) return; /* Write hostname to /etc/rc.conf */ @@ -867,15 +930,14 @@ mnt_net_config(void) /* If not running in target, copy resolv.conf there. */ if ((net_dhcpconf & DHCPCONF_NAMESVR) == 0) { #ifndef INET6 - if (strcmp(net_namesvr, "") != 0) + if (net_namesvr[0] != 0) dup_file_into_target("/etc/resolv.conf"); #else /* * not sure if it is a good idea, to allow dhcp config to * override IPv6 configuration */ - if (strcmp(net_namesvr, "") != 0 || - strcmp(net_namesvr6, "") != 0) + if (net_namesvr[0] != 0 || net_namesvr6[0] != 0) dup_file_into_target("/etc/resolv.conf"); #endif } @@ -884,7 +946,7 @@ mnt_net_config(void) * bring the interface up, it will be necessary for IPv6, and * it won't make trouble with IPv4 case either */ - snprintf(ifconfig_fn, STRSIZE, "/etc/ifconfig.%s", net_dev); + snprintf(ifconfig_fn, sizeof ifconfig_fn, "/etc/ifconfig.%s", net_dev); ifconf = target_fopen(ifconfig_fn, "w"); if (ifconf != NULL) { scripting_fprintf(NULL, "cat <>%s%s\n", @@ -910,7 +972,7 @@ mnt_net_config(void) scripting_fprintf(NULL, "EOF\n"); } - /* + /* * Add IPaddr/hostname to /etc/hosts. * Be careful not to clobber any existing contents. * Relies on ordered seach of /etc/hosts. XXX YP? @@ -960,22 +1022,25 @@ config_dhcp(char *inter) /* check if dhclient is running, if so, kill it */ result = collect(T_FILE, &textbuf, "/tmp/dhclient.pid"); - if (result >=0) { + if (result >= 0) { pid = atoi(textbuf); if (pid > 0) { - kill(pid,15); + kill(pid, 15); sleep(1); - kill(pid,9); + kill(pid, 9); } } + free(textbuf); if (!file_mode_match(DHCLIENT_EX, S_IFREG)) return 0; process_menu(MENU_dhcpautoconf, NULL); if (yesno) { /* spawn off dhclient and wait for parent to exit */ - dhcpautoconf = run_prog(RUN_DISPLAY, NULL, "%s -pf /tmp/dhclient.pid -lf /tmp/dhclient.leases %s", DHCLIENT_EX,inter); - return dhcpautoconf?0:1; + dhcpautoconf = run_prog(RUN_DISPLAY, NULL, + "%s -pf /tmp/dhclient.pid -lf /tmp/dhclient.leases %s", + DHCLIENT_EX, inter); + return dhcpautoconf ? 0 : 1; } return 0; } @@ -1012,6 +1077,7 @@ get_command_out(char *targ, int af, char *command, char *search) } } } + free(textbuf); return; } @@ -1033,7 +1099,7 @@ get_dhcp_value(char *targ, char *line) } if (textsize >= 0) { (void)strtok(textbuf, " \t\n"); /* jump past 'lease' */ - while ((t=strtok(NULL, " \t\n")) !=NULL) { + while ((t = strtok(NULL, " \t\n")) != NULL) { if (strcmp(t, line) == 0) { t = strtok(NULL, " \t\n"); /* found the tag, extract the value */ @@ -1049,9 +1115,10 @@ get_dhcp_value(char *targ, char *line) t++; } strcpy(targ, t); - return; + break; } } } + free(textbuf); return; }