[BACK]Return to net.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / distrib / utils / sysinst

Annotation of src/distrib/utils/sysinst/net.c, Revision 1.120

1.120   ! ad          1: /*     $NetBSD: net.c,v 1.119 2008/11/06 15:30:23 christos Exp $       */
1.1       phil        2:
                      3: /*
                      4:  * Copyright 1997 Piermont Information Systems Inc.
                      5:  * All rights reserved.
                      6:  *
                      7:  * Written by Philip A. Nelson for Piermont Information Systems Inc.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. Redistributions in binary form must reproduce the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer in the
                     16:  *    documentation and/or other materials provided with the distribution.
                     17:  * 3. All advertising materials mentioning features or use of this software
                     18:  *    must display the following acknowledgement:
1.46      cgd        19:  *      This product includes software developed for the NetBSD Project by
1.1       phil       20:  *      Piermont Information Systems Inc.
                     21:  * 4. The name of Piermont Information Systems Inc. may not be used to endorse
                     22:  *    or promote products derived from this software without specific prior
                     23:  *    written permission.
                     24:  *
                     25:  * THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS''
                     26:  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     27:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1.87      dsl        28:  * ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE
                     29:  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     30:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1.1       phil       31:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     32:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     33:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1.87      dsl        34:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
1.1       phil       35:  * THE POSSIBILITY OF SUCH DAMAGE.
                     36:  *
                     37:  */
                     38:
                     39: /* net.c -- routines to fetch files off the network. */
                     40:
                     41: #include <stdio.h>
                     42: #include <stdlib.h>
                     43: #include <string.h>
                     44: #include <curses.h>
1.29      thorpej    45: #include <time.h>
1.1       phil       46: #include <unistd.h>
1.21      simonb     47: #include <sys/param.h>
1.63      fvdl       48: #include <sys/stat.h>
1.120   ! ad         49: #include <sys/statvfs.h>
1.56      itojun     50: #ifdef INET6
                     51: #include <sys/sysctl.h>
1.61      itojun     52: #endif
1.56      itojun     53: #include <sys/socket.h>
1.105     dsl        54: #include <sys/ioctl.h>
1.56      itojun     55: #include <netinet/in.h>
1.87      dsl        56: #include <net/if.h>
1.105     dsl        57: #include <net/if_media.h>
1.61      itojun     58: #include <arpa/inet.h>
1.1       phil       59: #include "defs.h"
                     60: #include "md.h"
                     61: #include "msg_defs.h"
                     62: #include "menu_defs.h"
                     63: #include "txtwalk.h"
                     64:
1.106     christos   65: #include <sys/wait.h>
                     66: #include <sys/resource.h>
1.118     christos   67: #include <sys/sysctl.h>
1.106     christos   68:
1.27      fvdl       69: int network_up = 0;
1.87      dsl        70: /* Access to network information */
                     71: static char *net_devices;
                     72: static char *net_up;
                     73: static char net_dev[STRSIZE];
                     74: static char net_domain[STRSIZE];
                     75: static char net_host[STRSIZE];
1.107     dsl        76: static char net_ip[SSTRSIZE];
                     77: static char net_srv_ip[SSTRSIZE];
                     78: static char net_mask[SSTRSIZE];
1.87      dsl        79: static char net_namesvr[STRSIZE];
                     80: static char net_defroute[STRSIZE];
                     81: static char net_media[STRSIZE];
1.106     christos   82: static char sl_flags[STRSIZE];
1.87      dsl        83: static int net_dhcpconf;
                     84: #define DHCPCONF_IPADDR         0x01
                     85: #define DHCPCONF_NAMESVR        0x02
                     86: #define DHCPCONF_HOST           0x04
                     87: #define DHCPCONF_DOMAIN         0x08
                     88: #ifdef INET6
                     89: static char net_ip6[STRSIZE];
1.88      abs        90: char net_namesvr6[STRSIZE];
1.87      dsl        91: static int net_ip6conf;
                     92: #define IP6CONF_AUTOHOST        0x01
                     93: #endif
                     94:
1.8       phil       95:
1.38      perry      96: /* URL encode unsafe characters.  */
                     97:
1.104     dsl        98: static char *url_encode (char *dst, const char *src, const char *ep,
1.45      cgd        99:                                const char *safe_chars,
1.67      mrg       100:                                int encode_leading_slash);
1.38      perry     101:
1.51      cgd       102: static void write_etc_hosts(FILE *f);
                    103:
1.58      cyber     104: #define DHCLIENT_EX "/sbin/dhclient"
                    105: #include <signal.h>
1.87      dsl       106: static int config_dhcp(char *);
1.93      itojun    107: static void get_dhcp_value(char *, size_t, const char *);
1.58      cyber     108:
1.57      itojun    109: #ifdef INET6
1.67      mrg       110: static int is_v6kernel (void);
                    111: static void init_v6kernel (int);
                    112: static int get_v6wait (void);
1.57      itojun    113: #endif
1.51      cgd       114:
1.38      perry     115: /*
                    116:  * URL encode unsafe characters.  See RFC 1738.
                    117:  *
                    118:  * Copies src string to dst, encoding unsafe or reserved characters
                    119:  * in %hex form as it goes, and returning a pointer to the result.
                    120:  * The result is always a nul-terminated string even if it had to be
                    121:  * truncated to avoid overflowing the available space.
                    122:  *
1.53      cgd       123:  * This url_encode() function does not operate on complete URLs, it
                    124:  * operates on strings that make up parts of URLs.  For example, in a
                    125:  * URL like "ftp://username:password@host/path", the username, password,
                    126:  * host and path should each be encoded separately before they are
                    127:  * joined together with the punctuation characters.
                    128:  *
                    129:  * In most ordinary use, the path portion of a URL does not start with
                    130:  * a slash; the slash is a separator between the host portion and the
                    131:  * path portion, and is dealt with by software outside the url_encode()
                    132:  * function.  However, it is valid for url_encode() to be passed a
                    133:  * string that does begin with a slash.  For example, the string might
                    134:  * represent a password, or a path part of a URL that the user really
                    135:  * does want to begin with a slash.
                    136:  *
1.38      perry     137:  * len is the length of the destination buffer.  The result will be
                    138:  * truncated if necessary to fit in the destination buffer.
                    139:  *
1.45      cgd       140:  * safe_chars is a string of characters that should not be encoded.  If
                    141:  * safe_chars is non-NULL, any characters in safe_chars as well as any
                    142:  * alphanumeric characters will be copied from src to dst without
                    143:  * encoding.  Some potentially useful settings for this parameter are:
1.38      perry     144:  *
1.45      cgd       145:  *     NULL            Everything is encoded (even alphanumerics)
                    146:  *     ""              Everything except alphanumerics are encoded
1.38      perry     147:  *     "/"             Alphanumerics and '/' remain unencoded
                    148:  *     "$-_.+!*'(),"   Consistent with a strict reading of RFC 1738
                    149:  *     "$-_.+!*'(),/"  As above, except '/' is not encoded
                    150:  *     "-_.+!,/"       As above, except shell special characters are encoded
                    151:  *
1.53      cgd       152:  * encode_leading_slash is a flag that determines whether or not to
                    153:  * encode a leading slash in a string.  If this flag is set, and if the
                    154:  * first character in the src string is '/', then the leading slash will
                    155:  * be encoded (as "%2F"), even if '/' is one of the characters in the
                    156:  * safe_chars string.  Note that only the first character of the src
                    157:  * string is affected by this flag, and that leading slashes are never
                    158:  * deleted, but either retained unchanged or encoded.
                    159:  *
1.38      perry     160:  * Unsafe and reserved characters are defined in RFC 1738 section 2.2.
                    161:  * The most important parts are:
                    162:  *
                    163:  *      The characters ";", "/", "?", ":", "@", "=" and "&" are the
                    164:  *      characters which may be reserved for special meaning within a
                    165:  *      scheme. No other characters may be reserved within a scheme.
                    166:  *      [...]
                    167:  *
                    168:  *      Thus, only alphanumerics, the special characters "$-_.+!*'(),",
                    169:  *      and reserved characters used for their reserved purposes may be
                    170:  *      used unencoded within a URL.
                    171:  *
                    172:  */
                    173:
                    174: #define RFC1738_SAFE                           "$-_.+!*'(),"
                    175: #define RFC1738_SAFE_LESS_SHELL                        "-_.+!,"
                    176: #define RFC1738_SAFE_LESS_SHELL_PLUS_SLASH     "-_.+!,/"
                    177:
                    178: static char *
1.104     dsl       179: url_encode(char *dst, const char *src, const char *ep,
1.45      cgd       180:        const char *safe_chars, int encode_leading_slash)
1.38      perry     181: {
1.102     dsl       182:        int ch;
1.45      cgd       183:
1.104     dsl       184:        ep--;
                    185:
                    186:        for (; dst < ep; src++) {
1.102     dsl       187:                ch = *src & 0xff;
                    188:                if (ch == 0)
                    189:                        break;
1.45      cgd       190:                if (safe_chars != NULL &&
1.102     dsl       191:                    (ch != '/' || !encode_leading_slash) &&
                    192:                    (isalnum(ch) || strchr(safe_chars, ch))) {
1.104     dsl       193:                        *dst++ = ch;
1.38      perry     194:                } else {
                    195:                        /* encode this char */
1.104     dsl       196:                        if (ep - dst < 3)
1.38      perry     197:                                break;
1.104     dsl       198:                        snprintf(dst, ep - dst, "%%%02X", ch);
                    199:                        dst += 3;
1.38      perry     200:                }
1.102     dsl       201:                encode_leading_slash = 0;
1.38      perry     202:        }
1.104     dsl       203:        *dst = '\0';
1.38      perry     204:        return dst;
                    205: }
                    206:
1.104     dsl       207:
1.48      cgd       208: static const char *ignored_if_names[] = {
                    209:        "eon",                  /* netiso */
                    210:        "gre",                  /* net */
                    211:        "ipip",                 /* netinet */
1.54      mycroft   212:        "gif",                  /* netinet6 */
                    213:        "faith",                /* netinet6 */
1.48      cgd       214:        "lo",                   /* net */
                    215: #if 0
                    216:        "mdecap",               /* netinet -- never in IF list (?) XXX */
                    217: #endif
                    218:        "nsip",                 /* netns */
                    219:        "ppp",                  /* net */
1.106     christos  220: #if 0
1.48      cgd       221:        "sl",                   /* net */
1.106     christos  222: #endif
1.48      cgd       223:        "strip",                /* net */
                    224:        "tun",                  /* net */
                    225:        /* XXX others? */
                    226:        NULL,
                    227: };
                    228:
1.30      mrg       229: static void
1.86      dsl       230: get_ifconfig_info(void)
1.1       phil      231: {
                    232:        char *textbuf;
1.87      dsl       233:        char *t, *nt;
1.48      cgd       234:        const char **ignore;
1.81      christos  235:        int textsize;
1.87      dsl       236:        ulong fl;
                    237:        char *cp;
                    238:
                    239:        free(net_devices);
                    240:        net_devices = NULL;
                    241:        free(net_up);
                    242:        net_up = NULL;
1.1       phil      243:
                    244:        /* Get ifconfig information */
1.87      dsl       245:
                    246:        textsize = collect(T_OUTPUT, &textbuf, "/sbin/ifconfig -a 2>/dev/null");
1.1       phil      247:        if (textsize < 0) {
1.36      garbled   248:                if (logging)
1.80      fvdl      249:                        (void)fprintf(logfp,
                    250:                            "Aborting: Could not run ifconfig.\n");
1.30      mrg       251:                (void)fprintf(stderr, "Could not run ifconfig.");
                    252:                exit(1);
1.1       phil      253:        }
1.48      cgd       254:
1.87      dsl       255:        for (t = textbuf; t != NULL && *t != 0; t = nt) {
                    256:                /* find entry for next interface */
                    257:                for (nt = t; (nt = strchr(nt, '\n')); ) {
                    258:                        if (*++nt != '\t')
                    259:                                break;
                    260:                }
                    261:                if (memcmp(t, "lo0:", 4) == 0)
                    262:                        /* completely ignore loopback interface */
                    263:                        continue;
                    264:                cp = strchr(t, '=');
                    265:                if (cp == NULL)
                    266:                        break;
                    267:                /* get interface flags */
                    268:                fl = strtoul(cp + 1, &cp, 16);
                    269:                if (*cp != '<')
                    270:                        break;
1.112     martin    271:
                    272:                for (ignore = ignored_if_names; *ignore != NULL; ignore++) {
                    273:                        size_t len = strlen(*ignore);
                    274:                        if (strncmp(t, *ignore, len) == 0 &&
                    275:                            isdigit((unsigned char)t[len]))
                    276:                                break;
                    277:                }
                    278:                if (*ignore != NULL)
                    279:                        continue;
                    280:
1.87      dsl       281:                if (fl & IFF_UP) {
                    282:                        /* This interface might be connected to the server */
                    283:                        cp = strchr(t, ':');
                    284:                        if (cp == NULL)
                    285:                                break;
                    286:                        asprintf(&cp, "%s%.*s ",
                    287:                            net_up ? net_up : "", (int)(cp - t), t);
                    288:                        free(net_up);
                    289:                        net_up = cp;
                    290:                }
                    291:
                    292:                cp = strchr(t, ':');
                    293:                if (cp == NULL)
                    294:                        break;
                    295:                asprintf(&cp, "%s%.*s ",
                    296:                    net_devices ? net_devices : "", (int)(cp - t), t);
                    297:                free(net_devices);
                    298:                net_devices = cp;
1.48      cgd       299:        }
1.30      mrg       300:        free(textbuf);
1.1       phil      301: }
                    302:
1.105     dsl       303: static int
1.110     martin    304: do_ifreq(struct ifmediareq *ifmr, unsigned long cmd)
1.105     dsl       305: {
                    306:        int sock;
                    307:        int rval;
                    308:
                    309:        sock = socket(PF_INET, SOCK_DGRAM, 0);
                    310:        if (sock == -1)
                    311:                return -1;
                    312:
                    313:        memset(ifmr, 0, sizeof *ifmr);
                    314:        strncpy(ifmr->ifm_name, net_dev, sizeof ifmr->ifm_name);
                    315:        rval = ioctl(sock, cmd, ifmr);
                    316:        close(sock);
                    317:
                    318:        return rval;
                    319: }
                    320:
1.21      simonb    321: /* Fill in defaults network values for the selected interface */
1.30      mrg       322: static void
1.86      dsl       323: get_ifinterface_info(void)
1.21      simonb    324: {
1.105     dsl       325:        struct ifmediareq ifmr;
                    326:        struct sockaddr_in *sa_in = (void *)&((struct ifreq *)&ifmr)->ifr_addr;
                    327:        int modew;
                    328:        const char *media_opt;
                    329:        const char *sep;
                    330:
                    331:        if (do_ifreq(&ifmr, SIOCGIFADDR) == 0 && sa_in->sin_addr.s_addr != 0)
                    332:                strlcpy(net_ip, inet_ntoa(sa_in->sin_addr), sizeof net_ip);
                    333:
                    334:        if (do_ifreq(&ifmr, SIOCGIFNETMASK) == 0 && sa_in->sin_addr.s_addr != 0)
                    335:                strlcpy(net_mask, inet_ntoa(sa_in->sin_addr), sizeof net_mask);
                    336:
                    337:        if (do_ifreq(&ifmr, SIOCGIFMEDIA) == 0) {
                    338:                /* Get the name of the media word */
                    339:                modew = ifmr.ifm_current;
1.116     jmmv      340:                strlcpy(net_media, get_media_subtype_string(modew),
1.105     dsl       341:                    sizeof net_media);
                    342:                /* and add any media options */
                    343:                sep = " mediaopt ";
                    344:                while ((media_opt = get_media_option_string(&modew)) != NULL) {
                    345:                        strlcat(net_media, sep, sizeof net_media);
                    346:                        strlcat(net_media, media_opt, sizeof net_media);
                    347:                        sep = ",";
                    348:                }
                    349:        }
                    350: }
                    351:
                    352: #ifndef INET6
                    353: #define get_if6interface_info()
                    354: #else
                    355: static void
                    356: get_if6interface_info(void)
                    357: {
                    358:        char *textbuf, *t;
1.21      simonb    359:        int textsize;
                    360:
1.56      itojun    361:        textsize = collect(T_OUTPUT, &textbuf,
                    362:            "/sbin/ifconfig %s inet6 2>/dev/null", net_dev);
                    363:        if (textsize >= 0) {
                    364:                char *p;
                    365:
                    366:                (void)strtok(textbuf, "\n"); /* ignore first line */
                    367:                while ((t = strtok(NULL, "\n")) != NULL) {
                    368:                        if (strncmp(t, "\tinet6 ", 7) != 0)
                    369:                                continue;
                    370:                        t += 7;
                    371:                        if (strstr(t, "tentative") || strstr(t, "duplicated"))
                    372:                                continue;
                    373:                        if (strncmp(t, "fe80:", 5) == 0)
                    374:                                continue;
                    375:
                    376:                        p = t;
                    377:                        while (*p && *p != ' ' && *p != '\n')
                    378:                                p++;
                    379:                        *p = '\0';
1.93      itojun    380:                        strlcpy(net_ip6, t, sizeof(net_ip6));
1.56      itojun    381:                        break;
                    382:                }
                    383:        }
1.87      dsl       384:        free(textbuf);
1.105     dsl       385: }
1.56      itojun    386: #endif
1.21      simonb    387:
1.105     dsl       388: static void
                    389: get_host_info(void)
                    390: {
                    391:        char hostname[MAXHOSTNAMELEN + 1];
                    392:        char *dot;
                    393:
1.21      simonb    394:        /* Check host (and domain?) name */
1.102     dsl       395:        if (gethostname(hostname, sizeof(hostname)) == 0 && hostname[0] != 0) {
1.87      dsl       396:                hostname[sizeof(hostname) - 1] = 0;
1.58      cyber     397:                /* check for a . */
                    398:                dot = strchr(hostname, '.');
1.87      dsl       399:                if (dot == NULL) {
1.58      cyber     400:                        /* if not found its just a host, punt on domain */
1.87      dsl       401:                        strlcpy(net_host, hostname, sizeof net_host);
1.58      cyber     402:                } else {
                    403:                        /* split hostname into host/domain parts */
1.87      dsl       404:                        *dot++ = 0;
                    405:                        strlcpy(net_host, hostname, sizeof net_host);
                    406:                        strlcpy(net_domain, dot, sizeof net_domain);
1.58      cyber     407:                }
1.31      mrg       408:        }
1.21      simonb    409: }
                    410:
1.96      perry     411: /*
1.105     dsl       412:  * recombine name parts split in get_host_info and config_network
1.96      perry     413:  * (common code moved here from write_etc_hosts)
                    414:  */
                    415: static char *
                    416: recombine_host_domain(void)
                    417: {
                    418:        static char recombined[MAXHOSTNAMELEN + 1];
                    419:        int l = strlen(net_host) - strlen(net_domain);
                    420:
                    421:        strlcpy(recombined, net_host, sizeof(recombined));
                    422:
                    423:        if (l <= 0 ||
                    424:            net_host[l - 1] != '.' ||
                    425:            strcasecmp(net_domain, net_host + l) != 0) {
                    426:                /* net_host isn't an FQDN. */
                    427:                strlcat(recombined, ".", sizeof(recombined));
                    428:                strlcat(recombined, net_domain, sizeof(recombined));
                    429:        }
                    430:        return recombined;
                    431: }
                    432:
1.56      itojun    433: #ifdef INET6
                    434: static int
1.86      dsl       435: is_v6kernel(void)
1.56      itojun    436: {
                    437:        int s;
                    438:
                    439:        s = socket(PF_INET6, SOCK_DGRAM, 0);
                    440:        if (s < 0)
                    441:                return 0;
1.87      dsl       442:        close(s);
                    443:        return 1;
1.56      itojun    444: }
                    445:
                    446: /*
                    447:  * initialize as v6 client.
                    448:  * we are sure that we will never become router with boot floppy :-)
                    449:  * (include and use sysctl(8) if you are willing to)
                    450:  */
                    451: static void
1.86      dsl       452: init_v6kernel(int autoconf)
1.56      itojun    453: {
                    454:        int v;
                    455:        int mib[4] = {CTL_NET, PF_INET6, IPPROTO_IPV6, 0};
                    456:
                    457:        mib[3] = IPV6CTL_FORWARDING;
                    458:        v = 0;
1.113     he        459:        (void)sysctl(mib, 4, NULL, NULL, (void *)&v, sizeof(v));
1.56      itojun    460:
                    461:        mib[3] = IPV6CTL_ACCEPT_RTADV;
                    462:        v = autoconf ? 1 : 0;
1.113     he        463:        (void)sysctl(mib, 4, NULL, NULL, (void *)&v, sizeof(v));
1.56      itojun    464: }
                    465:
                    466: static int
1.86      dsl       467: get_v6wait(void)
1.56      itojun    468: {
1.94      mrg       469:        size_t len = sizeof(int);
1.56      itojun    470:        int v;
                    471:        int mib[4] = {CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_DAD_COUNT};
                    472:
                    473:        len = sizeof(v);
1.94      mrg       474:        if (sysctl(mib, 4, (void *)&v, &len, NULL, 0) < 0) {
1.56      itojun    475:                /* warn("sysctl(net.inet6.ip6.dadcount)"); */
                    476:                return 1;       /* guess */
                    477:        }
                    478:        return v;
                    479: }
                    480: #endif
                    481:
1.118     christos  482: static int
                    483: handle_license(const char *dev)
                    484: {
                    485:        static struct {
                    486:                const char *dev;
                    487:                const char *lic;
                    488:        } licdev[] = {
                    489:                { "iwi", "/libdata/firmware/if_iwi/LICENSE.ipw2200-fw" },
                    490:                { "ipw", "/libdata/firmware/if_ipw/LICENSE" },
                    491:        };
                    492:
                    493:        size_t i;
                    494:
                    495:        for (i = 0; i < __arraycount(licdev); i++)
                    496:                if (strncmp(dev, licdev[i].dev, 3) == 0) {
                    497:                        char buf[64];
                    498:                        int val;
                    499:                        size_t len = sizeof(int);
                    500:                        (void)snprintf(buf, sizeof(buf), "hw.%s.accept_eula",
                    501:                            licdev[i].dev);
                    502:                        if (sysctlbyname(buf, &val, &len, NULL, 0) != -1
                    503:                            && val != 0)
                    504:                                return 1;
                    505:                        msg_display(MSG_license, dev, licdev[i].lic);
                    506:                        process_menu(MENU_yesno, NULL);
                    507:                        if (yesno) {
                    508:                                val = 1;
                    509:                                if (sysctlbyname(buf, NULL, NULL, &val,
                    510:                                    0) == -1)
                    511:                                        return 0;
1.119     christos  512:                                add_sysctl_conf("%s=1", buf);
1.118     christos  513:                                return 1;
                    514:                        } else
                    515:                                return 0;
                    516:                }
                    517:        return 1;
                    518: }
                    519:
1.30      mrg       520: /*
                    521:  * Get the information to configure the network, configure it and
                    522:  * make sure both the gateway and the name server are up.
                    523:  */
                    524: int
1.86      dsl       525: config_network(void)
                    526: {
                    527:        char *tp;
1.87      dsl       528:        char *defname;
                    529:        const char *prompt;
1.105     dsl       530:        char *textbuf;
1.1       phil      531:        int  octet0;
1.107     dsl       532:        int  dhcp_config;
1.106     christos  533:
1.118     christos  534:        int  slip = 0;
1.106     christos  535:        int  pid, status;
                    536:        char **ap, *slcmd[10], *in_buf;
                    537:        char buffer[STRSIZE];
                    538:
1.87      dsl       539:        int l;
1.102     dsl       540:        char dhcp_host[STRSIZE];
1.81      christos  541: #ifdef INET6
                    542:        int v6config = 1;
                    543: #endif
1.1       phil      544:
                    545:        FILE *f;
1.12      jonathan  546:        time_t now;
1.1       phil      547:
1.8       phil      548:        if (network_up)
1.30      mrg       549:                return (1);
1.8       phil      550:
1.30      mrg       551:        get_ifconfig_info();
1.50      cgd       552:
1.92      dsl       553:        if (net_up != NULL) {
1.107     dsl       554:                /* XXX: some retry loops come here... */
1.87      dsl       555:                /* active interfaces found */
                    556:                msg_display(MSG_netup, net_up);
                    557:                process_menu(MENU_yesno, NULL);
1.111     martin    558:                if (!yesno)
                    559:                        return 0;
1.87      dsl       560:        }
1.92      dsl       561:
                    562:        if (net_devices == NULL) {
                    563:                /* No network interfaces found! */
                    564:                msg_display(MSG_nonet);
                    565:                process_menu(MENU_ok, NULL);
                    566:                return (-1);
                    567:        }
                    568:        network_up = 1;
1.87      dsl       569:
1.70      mrg       570: again:
1.87      dsl       571:        tp = strchr(net_devices, ' ');
                    572:        asprintf(&defname, "%.*s", (int)(tp - net_devices), net_devices);
                    573:        for (prompt = MSG_asknetdev;; prompt = MSG_badnet) {
                    574:                msg_prompt(prompt, defname, net_dev, sizeof net_dev - 1,
                    575:                    net_devices);
                    576:                l = strlen(net_dev);
                    577:                net_dev[l] = ' ';
                    578:                net_dev[l + 1] = 0;
                    579:                tp = strstr(net_devices, net_dev);
                    580:                if (tp == NULL)
                    581:                        continue;
                    582:                if (tp != net_devices && tp[-1] != ' ')
                    583:                        continue;
                    584:                net_dev[l] = 0;
                    585:                break;
1.1       phil      586:        }
1.87      dsl       587:        free(defname);
1.118     christos  588:        if (!handle_license(net_dev))
                    589:                goto done;
1.56      itojun    590:
1.107     dsl       591:        slip = net_dev[0] == 's' && net_dev[1] == 'l' &&
                    592:            isdigit((unsigned char)net_dev[2]);
1.61      itojun    593:
1.107     dsl       594:        if (slip)
                    595:                dhcp_config = 0;
                    596:        else {
1.106     christos  597:                /* Preload any defaults we can find */
1.83      jmc       598:                get_ifinterface_info();
1.105     dsl       599:                get_if6interface_info();
                    600:                get_host_info();
1.83      jmc       601:
1.106     christos  602:                /* domain and host */
                    603:                msg_display(MSG_netinfo);
1.61      itojun    604:
1.106     christos  605:                /* ethernet medium */
                    606:                for (;;) {
                    607:                        msg_prompt_add(MSG_net_media, net_media, net_media,
                    608:                                        sizeof net_media);
                    609:
                    610:                        /*
                    611:                         * ifconfig does not allow media specifiers on
                    612:                         * IFM_MANUAL interfaces.  Our UI gives no way
                    613:                         * to set an option back
                    614:                         * to null-string if it gets accidentally set.
                    615:                         * Check for plausible alternatives.
                    616:                         */
                    617:                        if (strcmp(net_media, "<default>") == 0 ||
                    618:                            strcmp(net_media, "default") == 0 ||
                    619:                            strcmp(net_media, "<manual>") == 0 ||
                    620:                            strcmp(net_media, "manual") == 0 ||
                    621:                            strcmp(net_media, "<none>") == 0 ||
                    622:                            strcmp(net_media, "none") == 0 ||
                    623:                            strcmp(net_media, " ") == 0) {
                    624:                                *net_media = '\0';
                    625:                        }
1.58      cyber     626:
1.106     christos  627:                        if (*net_media == '\0')
                    628:                                break;
                    629:                        /*
                    630:                         * We must set the media type here - to give dhcp
                    631:                         * a chance
                    632:                         */
                    633:                        if (run_program(0, "/sbin/ifconfig %s media %s",
                    634:                                    net_dev, net_media) == 0)
                    635:                                break;
                    636:                        /* Failed to set - output the supported values */
                    637:                        if (collect(T_OUTPUT, &textbuf, "/sbin/ifconfig -m %s |"
                    638:                                    "while IFS=; read line;"
                    639:                                    " do [ \"$line\" = \"${line#*media}\" ] || "
                    640:                                    "echo $line;"
                    641:                                    " done", net_dev ) > 0)
                    642:                                msg_display(textbuf);
                    643:                        free(textbuf);
                    644:                }
                    645:
1.117     reed      646:                net_dhcpconf = 0;
1.106     christos  647:                /* try a dhcp configuration */
                    648:                dhcp_config = config_dhcp(net_dev);
                    649:                if (dhcp_config) {
                    650:                        /* Get newly configured data off interface. */
                    651:                        get_ifinterface_info();
                    652:                        get_if6interface_info();
                    653:                        get_host_info();
                    654:
                    655:                        net_dhcpconf |= DHCPCONF_IPADDR;
                    656:
                    657:                        /*
                    658:                         * Extract default route from output of
                    659:                         * 'route -n show'
                    660:                         */
                    661:                        if (collect(T_OUTPUT, &textbuf,
                    662:                                    "/sbin/route -n show | "
                    663:                                    "while read dest gateway flags;"
                    664:                                    " do [ \"$dest\" = default ] && {"
                    665:                                        " echo $gateway; break; };"
                    666:                                    " done" ) > 0)
                    667:                                strlcpy(net_defroute, textbuf,
                    668:                                    sizeof net_defroute);
                    669:                        free(textbuf);
                    670:
                    671:                        /* pull nameserver info out of /etc/resolv.conf */
                    672:                        if (collect(T_OUTPUT, &textbuf,
                    673:                                    "cat /etc/resolv.conf 2>/dev/null |"
                    674:                                    " while read keyword address rest;"
                    675:                                    " do [ \"$keyword\" = nameserver "
                    676:                                        " -a \"${address#*:}\" = "
                    677:                                        "\"${address}\" ] && {"
                    678:                                            " echo $address; break; };"
                    679:                                    " done" ) > 0)
                    680:                                strlcpy(net_namesvr, textbuf,
                    681:                                    sizeof net_namesvr);
                    682:                        free(textbuf);
                    683:                        if (net_namesvr[0] != '\0')
                    684:                                net_dhcpconf |= DHCPCONF_NAMESVR;
                    685:
                    686:                        /* pull domainname out of leases file */
                    687:                        get_dhcp_value(net_domain, sizeof(net_domain),
                    688:                            "domain-name");
                    689:                        if (net_domain[0] != '\0')
                    690:                                net_dhcpconf |= DHCPCONF_DOMAIN;
                    691:
                    692:                        /* pull hostname out of leases file */
                    693:                        dhcp_host[0] = 0;
                    694:                        get_dhcp_value(dhcp_host, sizeof(dhcp_host),
1.115     is        695:                            "host-name");
1.106     christos  696:                        if (dhcp_host[0] != '\0') {
                    697:                                net_dhcpconf |= DHCPCONF_HOST;
                    698:                                strlcpy(net_host, dhcp_host, sizeof net_host);
                    699:                        }
1.102     dsl       700:                }
1.107     dsl       701:        }
1.56      itojun    702:
1.87      dsl       703:        msg_prompt_add(MSG_net_domain, net_domain, net_domain,
                    704:            sizeof net_domain);
                    705:        msg_prompt_add(MSG_net_host, net_host, net_host, sizeof net_host);
1.56      itojun    706:
1.61      itojun    707:        if (!dhcp_config) {
                    708:                /* Manually configure IPv4 */
1.87      dsl       709:                msg_prompt_add(MSG_net_ip, net_ip, net_ip, sizeof net_ip);
1.107     dsl       710:                if (slip)
                    711:                        msg_prompt_add(MSG_net_srv_ip, net_srv_ip, net_srv_ip,
                    712:                            sizeof net_srv_ip);
                    713:                else {
                    714:                        /* We don't want netmasks for SLIP */
1.106     christos  715:                        octet0 = atoi(net_ip);
1.107     dsl       716:                        if (!net_mask[0]) {
1.106     christos  717:                                if (0 <= octet0 && octet0 <= 127)
                    718:                                        strlcpy(net_mask, "0xff000000",
                    719:                                        sizeof(net_mask));
                    720:                                else if (128 <= octet0 && octet0 <= 191)
                    721:                                        strlcpy(net_mask, "0xffff0000",
                    722:                                        sizeof(net_mask));
                    723:                                else if (192 <= octet0 && octet0 <= 223)
                    724:                                        strlcpy(net_mask, "0xffffff00",
                    725:                                        sizeof(net_mask));
                    726:                        }
                    727:                        msg_prompt_add(MSG_net_mask, net_mask, net_mask,
1.107     dsl       728:                            sizeof net_mask);
                    729:                }
1.61      itojun    730:                msg_prompt_add(MSG_net_defroute, net_defroute, net_defroute,
1.87      dsl       731:                    sizeof net_defroute);
1.102     dsl       732:        }
1.107     dsl       733:
1.102     dsl       734:        if (!dhcp_config || net_namesvr[0] == 0)
1.61      itojun    735:                msg_prompt_add(MSG_net_namesrv, net_namesvr, net_namesvr,
1.87      dsl       736:                    sizeof net_namesvr);
1.56      itojun    737:
                    738: #ifdef INET6
                    739:        /* IPv6 autoconfiguration */
1.60      itojun    740:        if (!is_v6kernel())
1.56      itojun    741:                v6config = 0;
1.77      itojun    742:        else if (v6config) {
1.105     dsl       743:                process_menu(MENU_noyes, deconst(MSG_Perform_IPv6_autoconfiguration));
1.56      itojun    744:                v6config = yesno ? 1 : 0;
1.72      itojun    745:                net_ip6conf |= yesno ? IP6CONF_AUTOHOST : 0;
1.56      itojun    746:        }
                    747:
                    748:        if (v6config) {
1.84      dsl       749:                process_menu(MENU_namesrv6, NULL);
1.1       phil      750:                if (!yesno)
1.56      itojun    751:                        msg_prompt_add(MSG_net_namesrv6, net_namesvr6,
1.87      dsl       752:                            net_namesvr6, sizeof net_namesvr6);
1.56      itojun    753:        }
                    754: #endif
                    755:
                    756:        /* confirm the setting */
1.106     christos  757:        if (slip)
                    758:                msg_display(MSG_netok_slip, net_domain, net_host, net_dev,
                    759:                        *net_ip == '\0' ? "<none>" : net_ip,
1.107     dsl       760:                        *net_srv_ip == '\0' ? "<none>" : net_srv_ip,
1.106     christos  761:                        *net_mask == '\0' ? "<none>" : net_mask,
                    762:                        *net_namesvr == '\0' ? "<none>" : net_namesvr,
                    763:                        *net_defroute == '\0' ? "<none>" : net_defroute,
                    764:                        *net_media == '\0' ? "<default>" : net_media);
                    765:        else
                    766:                msg_display(MSG_netok, net_domain, net_host, net_dev,
                    767:                        *net_ip == '\0' ? "<none>" : net_ip,
                    768:                        *net_mask == '\0' ? "<none>" : net_mask,
                    769:                        *net_namesvr == '\0' ? "<none>" : net_namesvr,
                    770:                        *net_defroute == '\0' ? "<none>" : net_defroute,
                    771:                        *net_media == '\0' ? "<default>" : net_media);
1.56      itojun    772: #ifdef INET6
1.70      mrg       773:        msg_display_add(MSG_netokv6,
1.56      itojun    774:                     !is_v6kernel() ? "<not supported>" :
                    775:                        (v6config ? "yes" : "no"),
1.70      mrg       776:                     *net_namesvr6 == '\0' ? "<none>" : net_namesvr6);
1.56      itojun    777: #endif
1.118     christos  778: done:
1.102     dsl       779:        process_menu(MENU_yesno, deconst(MSG_netok_ok));
1.56      itojun    780:        if (!yesno)
                    781:                msg_display(MSG_netagain);
                    782:        if (!yesno)
                    783:                goto again;
                    784:
                    785:        /*
                    786:         * we may want to perform checks against inconsistent configuration,
                    787:         * like IPv4 DNS server without IPv4 configuration.
                    788:         */
1.1       phil      789:
1.20      simonb    790:        /* Create /etc/resolv.conf if a nameserver was given */
1.96      perry     791:        if (net_namesvr[0] != '\0'
1.56      itojun    792: #ifdef INET6
1.96      perry     793:            || net_namesvr6[0] != '\0'
1.56      itojun    794: #endif
                    795:                ) {
1.30      mrg       796:                f = fopen("/etc/resolv.conf", "w");
1.20      simonb    797:                if (f == NULL) {
1.36      garbled   798:                        if (logging)
1.80      fvdl      799:                                (void)fprintf(logfp,
                    800:                                    "%s", msg_string(MSG_resolv));
1.20      simonb    801:                        (void)fprintf(stderr, "%s", msg_string(MSG_resolv));
                    802:                        exit(1);
                    803:                }
1.70      mrg       804:                scripting_fprintf(NULL, "cat <<EOF >/etc/resolv.conf\n");
1.20      simonb    805:                time(&now);
                    806:                /* NB: ctime() returns a string ending in  '\n' */
1.87      dsl       807:                scripting_fprintf(f, ";\n; BIND data file\n; %s %s;\n",
                    808:                    "Created by NetBSD sysinst on", ctime(&now));
1.97      perry     809:                if (net_domain[0] != '\0')
                    810:                        scripting_fprintf(f, "search %s\n", net_domain);
1.96      perry     811:                if (net_namesvr[0] != '\0')
1.70      mrg       812:                        scripting_fprintf(f, "nameserver %s\n", net_namesvr);
1.56      itojun    813: #ifdef INET6
1.96      perry     814:                if (net_namesvr6[0] != '\0')
1.70      mrg       815:                        scripting_fprintf(f, "nameserver %s\n", net_namesvr6);
1.56      itojun    816: #endif
1.70      mrg       817:                scripting_fprintf(NULL, "EOF\n");
1.36      garbled   818:                fflush(NULL);
1.30      mrg       819:                fclose(f);
1.1       phil      820:        }
                    821:
1.100     dsl       822:        run_program(0, "/sbin/ifconfig lo0 127.0.0.1");
1.35      jonathan  823:
1.56      itojun    824: #ifdef INET6
                    825:        if (v6config) {
                    826:                init_v6kernel(1);
1.100     dsl       827:                run_program(0, "/sbin/ifconfig %s up", net_dev);
1.56      itojun    828:                sleep(get_v6wait() + 1);
1.100     dsl       829:                run_program(RUN_DISPLAY, "/sbin/rtsol -D %s", net_dev);
1.56      itojun    830:                sleep(get_v6wait() + 1);
                    831:        }
                    832: #endif
                    833:
1.96      perry     834:        if (net_ip[0] != '\0') {
1.106     christos  835:                if (slip) {
1.107     dsl       836:                        /* XXX: needs 'ifconfig sl0 create' much earlier */
1.106     christos  837:                        /* Set SLIP interface UP */
1.107     dsl       838:                        run_program(0, "/sbin/ifconfig %s inet %s %s up",
                    839:                            net_dev, net_ip, net_srv_ip);
1.106     christos  840:                        strcpy(sl_flags, "-s 115200 -l /dev/tty00");
1.107     dsl       841:                        msg_prompt_win(MSG_slattach, -1, 12, 70, 0,
                    842:                                sl_flags, sl_flags, 255);
1.106     christos  843:
1.107     dsl       844:                        /* XXX: wtf isn't run_program() used here? */
1.106     christos  845:                        pid = fork();
                    846:                        if (pid == 0) {
                    847:                                strcpy(buffer, "/sbin/slattach ");
                    848:                                strcat(buffer, sl_flags);
                    849:                                in_buf = buffer;
                    850:
                    851:                                for (ap = slcmd; (*ap = strsep(&in_buf, " ")) != NULL;)
                    852:                                if (**ap != '\0')
                    853:                                        ++ap;
                    854:
                    855:                                execvp(slcmd[0], slcmd);
                    856:                        } else
                    857:                                wait4(pid, &status, WNOHANG, 0);
1.56      itojun    858:                } else {
1.106     christos  859:                        if (net_mask[0] != '\0') {
                    860:                                run_program(0, "/sbin/ifconfig %s inet %s netmask %s",
                    861:                                    net_dev, net_ip, net_mask);
                    862:                        } else {
                    863:                                run_program(0, "/sbin/ifconfig %s inet %s",
                    864:                                net_dev, net_ip);
                    865:                        }
1.56      itojun    866:                }
                    867:        }
1.3       phil      868:
1.28      jonathan  869:        /* Set host name */
1.96      perry     870:        if (net_host[0] != '\0')
1.28      jonathan  871:                sethostname(net_host, strlen(net_host));
                    872:
1.20      simonb    873:        /* Set a default route if one was given */
1.96      perry     874:        if (net_defroute[0] != '\0') {
1.101     dsl       875:                run_program(RUN_DISPLAY | RUN_PROGRESS,
                    876:                                "/sbin/route -n flush -inet");
                    877:                run_program(RUN_DISPLAY | RUN_PROGRESS,
                    878:                                "/sbin/route -n add default %s", net_defroute);
1.20      simonb    879:        }
1.75      mrg       880:
                    881:        /*
                    882:         * wait a couple of seconds for the interface to go live.
                    883:         */
1.89      dsl       884:        msg_display_add(MSG_wait_network);
1.75      mrg       885:        sleep(5);
1.20      simonb    886:
1.36      garbled   887:        /*
                    888:         * ping should be verbose, so users can see the cause
                    889:         * of a network failure.
                    890:         */
1.56      itojun    891:
                    892: #ifdef INET6
                    893:        if (v6config && network_up) {
1.100     dsl       894:                network_up = !run_program(RUN_DISPLAY | RUN_PROGRESS,
1.59      itojun    895:                    "/sbin/ping6 -v -c 3 -n -I %s ff02::2", net_dev);
1.56      itojun    896:
1.96      perry     897:                if (net_namesvr6[0] != '\0')
1.100     dsl       898:                        network_up = !run_program(RUN_DISPLAY | RUN_PROGRESS,
1.56      itojun    899:                            "/sbin/ping6 -v -c 3 -n %s", net_namesvr6);
                    900:        }
                    901: #endif
1.36      garbled   902:
1.96      perry     903:        if (net_namesvr[0] != '\0' && network_up)
1.100     dsl       904:                network_up = !run_program(RUN_DISPLAY | RUN_PROGRESS,
1.87      dsl       905:                    "/sbin/ping -v -c 5 -w 5 -o -n %s", net_namesvr);
                    906:
1.96      perry     907:        if (net_defroute[0] != '\0' && network_up)
1.100     dsl       908:                network_up = !run_program(RUN_DISPLAY | RUN_PROGRESS,
1.87      dsl       909:                    "/sbin/ping -v -c 5 -w 5 -o -n %s", net_defroute);
1.36      garbled   910:        fflush(NULL);
1.8       phil      911:
                    912:        return network_up;
1.1       phil      913: }
                    914:
1.107     dsl       915: static int
                    916: ftp_fetch(const char *set_name)
1.87      dsl       917: {
1.107     dsl       918:        const char *ftp_opt;
1.38      perry     919:        char ftp_user_encoded[STRSIZE];
                    920:        char ftp_dir_encoded[STRSIZE];
1.102     dsl       921:        char *cp;
1.107     dsl       922:        int rval;
                    923:
                    924:        /*
                    925:         * Invoke ftp to fetch the file.
                    926:         *
                    927:         * ftp.pass is quite likely to contain unsafe characters
                    928:         * that need to be encoded in the URL (for example,
                    929:         * "@", ":" and "/" need quoting).  Let's be
                    930:         * paranoid and also encode ftp.user and ftp.dir.  (For
                    931:         * example, ftp.dir could easily contain '~', which is
                    932:         * unsafe by a strict reading of RFC 1738).
                    933:         */
                    934:        if (strcmp("ftp", ftp.user) == 0 && ftp.pass[0] == 0) {
                    935:                /* do anon ftp */
                    936:                ftp_opt = "-a ";
                    937:                ftp_user_encoded[0] = 0;
                    938:        } else {
                    939:                ftp_opt = "";
                    940:                cp = url_encode(ftp_user_encoded, ftp.user,
                    941:                        ftp_user_encoded + sizeof ftp_user_encoded - 1,
                    942:                        RFC1738_SAFE_LESS_SHELL, 0);
                    943:                *cp++ = ':';
                    944:                cp = url_encode(cp, ftp.pass,
                    945:                        ftp_user_encoded + sizeof ftp_user_encoded - 1,
                    946:                        NULL, 0);
                    947:                *cp++ = '@';
                    948:                *cp = 0;
                    949:        }
                    950:
                    951:        cp = url_encode(ftp_dir_encoded, ftp.dir,
                    952:                        ftp_dir_encoded + sizeof ftp_dir_encoded - 1,
                    953:                        RFC1738_SAFE_LESS_SHELL_PLUS_SLASH, 1);
                    954:        if (set_dir[0] != '/')
                    955:                *cp++ = '/';
                    956:        url_encode(cp, set_dir,
                    957:                        ftp_dir_encoded + sizeof ftp_dir_encoded,
                    958:                        RFC1738_SAFE_LESS_SHELL_PLUS_SLASH, 0);
                    959:
                    960:        rval = run_program(RUN_DISPLAY | RUN_PROGRESS | RUN_XFER_DIR,
                    961:                    "/usr/bin/ftp %s%s://%s%s/%s/%s%s",
                    962:                    ftp_opt, ftp.xfer_type, ftp_user_encoded, ftp.host,
                    963:                    ftp_dir_encoded, set_name, dist_postfix);
                    964:
                    965:        return rval ? SET_RETRY : SET_OK;
                    966: }
                    967:
                    968: static int
                    969: do_config_network(void)
                    970: {
                    971:        int ret;
1.1       phil      972:
1.50      cgd       973:        while ((ret = config_network()) <= 0) {
                    974:                if (ret < 0)
                    975:                        return (-1);
1.30      mrg       976:                msg_display(MSG_netnotup);
1.84      dsl       977:                process_menu(MENU_yesno, NULL);
1.76      mrg       978:                if (!yesno) {
                    979:                        msg_display(MSG_netnotup_continueanyway);
1.84      dsl       980:                        process_menu(MENU_yesno, NULL);
1.76      mrg       981:                        if (!yesno)
1.107     dsl       982:                                return -1;
1.76      mrg       983:                        network_up = 1;
1.107     dsl       984:                        break;
1.76      mrg       985:                }
1.3       phil      986:        }
1.107     dsl       987:        return 0;
                    988: }
1.10      phil      989:
1.107     dsl       990: int
                    991: get_via_ftp(const char *xfer_type)
                    992: {
                    993:
                    994:        if (do_config_network() != 0)
                    995:                return SET_RETRY;
1.10      phil      996:
1.103     dsl       997:        process_menu(MENU_ftpsource, deconst(xfer_type));
1.42      bouyer    998:
1.107     dsl       999:        /* We'll fetch each file just before installing it */
                   1000:        fetch_fn = ftp_fetch;
                   1001:        ftp.xfer_type = xfer_type;
1.108     dsl      1002:        snprintf(ext_dir, sizeof ext_dir, "%s/%s", target_prefix(),
                   1003:            xfer_dir + (*xfer_dir == '/'));
1.102     dsl      1004:
1.107     dsl      1005:        return SET_OK;
1.1       phil     1006: }
                   1007:
1.5       phil     1008: int
1.86      dsl      1009: get_via_nfs(void)
1.1       phil     1010: {
1.120   ! ad       1011:        struct statvfs sb;
1.30      mrg      1012:
1.107     dsl      1013:        if (do_config_network() != 0)
                   1014:                return SET_RETRY;
1.5       phil     1015:
1.120   ! ad       1016:        /* If root is on NFS and we have sets, skip this step. */
        !          1017:        if (statvfs(set_dir, &sb) == 0 &&
        !          1018:            strcmp(sb.f_fstypename, "nfs") == 0) {
        !          1019:                strlcpy(ext_dir, set_dir, sizeof ext_dir);
        !          1020:                return SET_OK;
        !          1021:        }
        !          1022:
1.1       phil     1023:        /* Get server and filepath */
1.84      dsl      1024:        process_menu(MENU_nfssource, NULL);
1.5       phil     1025:
1.1       phil     1026:        /* Mount it */
1.100     dsl      1027:        if (run_program(0, "/sbin/mount -r -o -2,-i,-r=1024 -t nfs %s:%s /mnt2",
1.107     dsl      1028:            nfs_host, nfs_dir))
                   1029:                return SET_RETRY;
                   1030:
1.95      dsl      1031:        mnt2_mounted = 1;
1.24      jonathan 1032:
1.102     dsl      1033:        snprintf(ext_dir, sizeof ext_dir, "/mnt2/%s", set_dir);
                   1034:
1.5       phil     1035:        /* return location, don't clean... */
1.107     dsl      1036:        return SET_OK;
1.8       phil     1037: }
                   1038:
1.13      jonathan 1039: /*
1.51      cgd      1040:  * write the new contents of /etc/hosts to the specified file
                   1041:  */
                   1042: static void
                   1043: write_etc_hosts(FILE *f)
                   1044: {
1.70      mrg      1045:        scripting_fprintf(f, "#\n");
                   1046:        scripting_fprintf(f, "# Added by NetBSD sysinst\n");
                   1047:        scripting_fprintf(f, "#\n");
1.51      cgd      1048:
1.97      perry    1049:        if (net_domain[0] != '\0')
                   1050:                scripting_fprintf(f, "127.0.0.1 localhost.%s\n", net_domain);
1.51      cgd      1051:
1.70      mrg      1052:        scripting_fprintf(f, "%s\t", net_ip);
1.97      perry    1053:        if (net_domain[0] != '\0')
                   1054:                scripting_fprintf(f, "%s ", recombine_host_domain());
                   1055:        scripting_fprintf(f, "%s\n", net_host);
1.51      cgd      1056: }
                   1057:
                   1058: /*
1.13      jonathan 1059:  * Write the network config info the user entered via menus into the
                   1060:  * config files in the target disk.  Be careful not to lose any
                   1061:  * information we don't immediately add back, in case the install
1.87      dsl      1062:  * target is the currently-active root.
1.13      jonathan 1063:  */
1.8       phil     1064: void
                   1065: mnt_net_config(void)
                   1066: {
1.87      dsl      1067:        char ifconfig_fn[STRSIZE];
1.74      itojun   1068:        FILE *ifconf = NULL;
1.8       phil     1069:
1.61      itojun   1070:        if (!network_up)
                   1071:                return;
1.102     dsl      1072:        process_menu(MENU_yesno, deconst(MSG_mntnetconfig));
                   1073:        if (!yesno)
1.61      itojun   1074:                return;
                   1075:
1.82      shin     1076:        /* Write hostname to /etc/rc.conf */
1.70      mrg      1077:        if ((net_dhcpconf & DHCPCONF_HOST) == 0)
1.96      perry    1078:                add_rc_conf("hostname=%s\n", recombine_host_domain());
1.61      itojun   1079:
                   1080:        /* If not running in target, copy resolv.conf there. */
                   1081:        if ((net_dhcpconf & DHCPCONF_NAMESVR) == 0) {
1.72      itojun   1082: #ifndef INET6
1.96      perry    1083:                if (net_namesvr[0] != '\0')
1.61      itojun   1084:                        dup_file_into_target("/etc/resolv.conf");
1.72      itojun   1085: #else
                   1086:                /*
                   1087:                 * not sure if it is a good idea, to allow dhcp config to
                   1088:                 * override IPv6 configuration
                   1089:                 */
1.96      perry    1090:                if (net_namesvr[0] != '\0' || net_namesvr6[0] != '\0')
1.72      itojun   1091:                        dup_file_into_target("/etc/resolv.conf");
                   1092: #endif
                   1093:        }
                   1094:
                   1095:        /*
                   1096:         * bring the interface up, it will be necessary for IPv6, and
                   1097:         * it won't make trouble with IPv4 case either
                   1098:         */
1.87      dsl      1099:        snprintf(ifconfig_fn, sizeof ifconfig_fn, "/etc/ifconfig.%s", net_dev);
1.74      itojun   1100:        ifconf = target_fopen(ifconfig_fn, "w");
                   1101:        if (ifconf != NULL) {
1.72      itojun   1102:                scripting_fprintf(NULL, "cat <<EOF >>%s%s\n",
                   1103:                    target_prefix(), ifconfig_fn);
1.74      itojun   1104:                scripting_fprintf(ifconf, "up\n");
1.114     martin   1105:                if (*net_media != '\0')
                   1106:                        scripting_fprintf(ifconf, "media %s\n", net_media);
1.72      itojun   1107:                scripting_fprintf(NULL, "EOF\n");
1.61      itojun   1108:        }
                   1109:
                   1110:        if ((net_dhcpconf & DHCPCONF_IPADDR) == 0) {
1.74      itojun   1111:                FILE *hosts;
                   1112:
1.72      itojun   1113:                /* Write IPaddr and netmask to /etc/ifconfig.if[0-9] */
1.74      itojun   1114:                if (ifconf != NULL) {
1.72      itojun   1115:                        scripting_fprintf(NULL, "cat <<EOF >>%s%s\n",
                   1116:                            target_prefix(), ifconfig_fn);
                   1117:                        if (*net_media != '\0')
1.74      itojun   1118:                                scripting_fprintf(ifconf,
                   1119:                                    "%s netmask %s media %s\n",
1.72      itojun   1120:                                    net_ip, net_mask, net_media);
                   1121:                        else
1.74      itojun   1122:                                scripting_fprintf(ifconf, "%s netmask %s\n",
                   1123:                                    net_ip, net_mask);
1.72      itojun   1124:                        scripting_fprintf(NULL, "EOF\n");
                   1125:                }
                   1126:
1.87      dsl      1127:                /*
1.61      itojun   1128:                 * Add IPaddr/hostname to  /etc/hosts.
                   1129:                 * Be careful not to clobber any existing contents.
1.105     dsl      1130:                 * Relies on ordered search of /etc/hosts. XXX YP?
1.61      itojun   1131:                 */
1.74      itojun   1132:                hosts = target_fopen("/etc/hosts", "a");
                   1133:                if (hosts != 0) {
1.70      mrg      1134:                        scripting_fprintf(NULL, "cat <<EOF >>%s/etc/hosts\n",
                   1135:                            target_prefix());
1.74      itojun   1136:                        write_etc_hosts(hosts);
                   1137:                        (void)fclose(hosts);
1.70      mrg      1138:                        scripting_fprintf(NULL, "EOF\n");
1.74      itojun   1139:
                   1140:                        fclose(hosts);
1.61      itojun   1141:                }
1.12      jonathan 1142:
1.70      mrg      1143:                add_rc_conf("defaultroute=\"%s\"\n", net_defroute);
1.68      jdc      1144:        } else {
1.70      mrg      1145:                add_rc_conf("dhclient=YES\n");
1.71      dogcow   1146:                add_rc_conf("dhclient_flags=\"%s\"\n", net_dev);
1.70      mrg      1147:         }
1.72      itojun   1148:
                   1149: #ifdef INET6
                   1150:        if ((net_ip6conf & IP6CONF_AUTOHOST) != 0) {
                   1151:                add_rc_conf("ip6mode=autohost\n");
1.74      itojun   1152:                if (ifconf != NULL) {
                   1153:                        scripting_fprintf(NULL, "cat <<EOF >>%s%s\n",
                   1154:                            target_prefix(), ifconfig_fn);
1.77      itojun   1155:                        scripting_fprintf(ifconf, "!rtsol $int\n");
1.74      itojun   1156:                        scripting_fprintf(NULL, "EOF\n");
                   1157:                }
1.72      itojun   1158:        }
                   1159: #endif
1.74      itojun   1160:
                   1161:        if (ifconf)
                   1162:                fclose(ifconf);
1.72      itojun   1163:
1.61      itojun   1164:        fflush(NULL);
1.1       phil     1165: }
1.58      cyber    1166:
                   1167: int
1.86      dsl      1168: config_dhcp(char *inter)
1.58      cyber    1169: {
                   1170:        int dhcpautoconf;
                   1171:        int result;
                   1172:        char *textbuf;
                   1173:        int pid;
                   1174:
                   1175:        /* check if dhclient is running, if so, kill it */
                   1176:        result = collect(T_FILE, &textbuf, "/tmp/dhclient.pid");
1.87      dsl      1177:        if (result >= 0) {
1.58      cyber    1178:                pid = atoi(textbuf);
                   1179:                if (pid > 0) {
1.87      dsl      1180:                        kill(pid, 15);
1.58      cyber    1181:                        sleep(1);
1.87      dsl      1182:                        kill(pid, 9);
1.58      cyber    1183:                }
                   1184:        }
1.87      dsl      1185:        free(textbuf);
1.58      cyber    1186:
1.63      fvdl     1187:        if (!file_mode_match(DHCLIENT_EX, S_IFREG))
1.58      cyber    1188:                return 0;
1.102     dsl      1189:        process_menu(MENU_yesno, deconst(MSG_Perform_DHCP_autoconfiguration));
1.58      cyber    1190:        if (yesno) {
                   1191:                /* spawn off dhclient and wait for parent to exit */
1.101     dsl      1192:                dhcpautoconf = run_program(RUN_DISPLAY | RUN_PROGRESS,
1.105     dsl      1193:                    "%s -q -pf /tmp/dhclnt.pid -lf /tmp/dhclient.leases %s",
1.87      dsl      1194:                    DHCLIENT_EX, inter);
                   1195:                return dhcpautoconf ? 0 : 1;
1.58      cyber    1196:        }
                   1197:        return 0;
                   1198: }
                   1199:
1.61      itojun   1200: static void
1.93      itojun   1201: get_dhcp_value(char *targ, size_t l, const char *line)
1.58      cyber    1202: {
                   1203:        int textsize;
                   1204:        char *textbuf;
                   1205:        char *t;
1.81      christos 1206:        char *walkp;
1.58      cyber    1207:
                   1208:        textsize = collect(T_FILE, &textbuf, "/tmp/dhclient.leases");
                   1209:        if (textsize < 0) {
                   1210:                if (logging)
1.80      fvdl     1211:                        (void)fprintf(logfp,
                   1212:                            "Could not open file /tmp/dhclient.leases.\n");
1.58      cyber    1213:                (void)fprintf(stderr, "Could not open /tmp/dhclient.leases\n");
                   1214:                /* not fatal, just assume value not found */
                   1215:        }
1.61      itojun   1216:        if (textsize >= 0) {
1.58      cyber    1217:                (void)strtok(textbuf, " \t\n"); /* jump past 'lease' */
1.87      dsl      1218:                while ((t = strtok(NULL, " \t\n")) != NULL) {
1.58      cyber    1219:                        if (strcmp(t, line) == 0) {
                   1220:                                t = strtok(NULL, " \t\n");
                   1221:                                /* found the tag, extract the value */
                   1222:                                /* last char should be a ';' */
1.81      christos 1223:                                walkp = strrchr(t, ';');
                   1224:                                if (walkp != NULL) {
                   1225:                                        *walkp = '\0';
1.58      cyber    1226:                                }
                   1227:                                /* strip any " from the string */
1.81      christos 1228:                                walkp = strrchr(t, '"');
                   1229:                                if (walkp != NULL) {
                   1230:                                        *walkp = '\0';
1.58      cyber    1231:                                        t++;
                   1232:                                }
1.93      itojun   1233:                                strlcpy(targ, t, l);
1.87      dsl      1234:                                break;
1.58      cyber    1235:                        }
                   1236:                }
                   1237:        }
1.87      dsl      1238:        free(textbuf);
1.58      cyber    1239:        return;
                   1240: }

CVSweb <webmaster@jp.NetBSD.org>