[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.126

1.126   ! ahoka       1: /*     $NetBSD: net.c,v 1.125 2010/02/01 00:06:18 ahoka 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:
1.125     ahoka      41: #include <sys/ioctl.h>
1.21      simonb     42: #include <sys/param.h>
1.125     ahoka      43: #include <sys/resource.h>
                     44: #include <sys/socket.h>
1.63      fvdl       45: #include <sys/stat.h>
1.120     ad         46: #include <sys/statvfs.h>
1.125     ahoka      47: #include <sys/statvfs.h>
1.56      itojun     48: #include <sys/sysctl.h>
1.125     ahoka      49: #include <sys/wait.h>
1.126   ! ahoka      50: #include <arpa/inet.h>
        !            51: #include <net/if.h>
        !            52: #include <net/if_media.h>
        !            53: #include <netinet/in.h>
        !            54:
        !            55: #include <err.h>
        !            56: #include <stdio.h>
        !            57: #include <stdlib.h>
        !            58: #include <string.h>
        !            59: #include <curses.h>
        !            60: #include <time.h>
        !            61: #include <unistd.h>
1.125     ahoka      62:
1.1       phil       63: #include "defs.h"
                     64: #include "md.h"
                     65: #include "msg_defs.h"
                     66: #include "menu_defs.h"
                     67: #include "txtwalk.h"
                     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.122     joerg     104: #define DHCPCD "/sbin/dhcpcd"
1.58      cyber     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.124     martin    304: do_ifreq(struct ifreq *ifr, unsigned long cmd)
                    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(ifr, 0, sizeof *ifr);
                    314:        strncpy(ifr->ifr_name, net_dev, sizeof ifr->ifr_name);
                    315:        rval = ioctl(sock, cmd, ifr);
                    316:        close(sock);
                    317:
                    318:        return rval;
                    319: }
                    320:
                    321: static int
                    322: do_ifmreq(struct ifmediareq *ifmr, unsigned long cmd)
1.105     dsl       323: {
                    324:        int sock;
                    325:        int rval;
                    326:
                    327:        sock = socket(PF_INET, SOCK_DGRAM, 0);
                    328:        if (sock == -1)
                    329:                return -1;
                    330:
                    331:        memset(ifmr, 0, sizeof *ifmr);
                    332:        strncpy(ifmr->ifm_name, net_dev, sizeof ifmr->ifm_name);
                    333:        rval = ioctl(sock, cmd, ifmr);
                    334:        close(sock);
                    335:
                    336:        return rval;
                    337: }
                    338:
1.21      simonb    339: /* Fill in defaults network values for the selected interface */
1.30      mrg       340: static void
1.86      dsl       341: get_ifinterface_info(void)
1.21      simonb    342: {
1.124     martin    343:        struct ifreq ifr;
1.105     dsl       344:        struct ifmediareq ifmr;
1.124     martin    345:        struct sockaddr_in *sa_in = (void*)&ifr.ifr_addr;
1.105     dsl       346:        int modew;
                    347:        const char *media_opt;
                    348:        const char *sep;
                    349:
1.124     martin    350:        if (do_ifreq(&ifr, SIOCGIFADDR) == 0 && sa_in->sin_addr.s_addr != 0)
1.105     dsl       351:                strlcpy(net_ip, inet_ntoa(sa_in->sin_addr), sizeof net_ip);
                    352:
1.124     martin    353:        if (do_ifreq(&ifr, SIOCGIFNETMASK) == 0 && sa_in->sin_addr.s_addr != 0)
1.105     dsl       354:                strlcpy(net_mask, inet_ntoa(sa_in->sin_addr), sizeof net_mask);
                    355:
1.124     martin    356:        if (do_ifmreq(&ifmr, SIOCGIFMEDIA) == 0) {
1.105     dsl       357:                /* Get the name of the media word */
                    358:                modew = ifmr.ifm_current;
1.116     jmmv      359:                strlcpy(net_media, get_media_subtype_string(modew),
1.105     dsl       360:                    sizeof net_media);
                    361:                /* and add any media options */
                    362:                sep = " mediaopt ";
                    363:                while ((media_opt = get_media_option_string(&modew)) != NULL) {
                    364:                        strlcat(net_media, sep, sizeof net_media);
                    365:                        strlcat(net_media, media_opt, sizeof net_media);
                    366:                        sep = ",";
                    367:                }
                    368:        }
                    369: }
                    370:
                    371: #ifndef INET6
                    372: #define get_if6interface_info()
                    373: #else
                    374: static void
                    375: get_if6interface_info(void)
                    376: {
                    377:        char *textbuf, *t;
1.21      simonb    378:        int textsize;
                    379:
1.56      itojun    380:        textsize = collect(T_OUTPUT, &textbuf,
                    381:            "/sbin/ifconfig %s inet6 2>/dev/null", net_dev);
                    382:        if (textsize >= 0) {
                    383:                char *p;
                    384:
                    385:                (void)strtok(textbuf, "\n"); /* ignore first line */
                    386:                while ((t = strtok(NULL, "\n")) != NULL) {
                    387:                        if (strncmp(t, "\tinet6 ", 7) != 0)
                    388:                                continue;
                    389:                        t += 7;
                    390:                        if (strstr(t, "tentative") || strstr(t, "duplicated"))
                    391:                                continue;
                    392:                        if (strncmp(t, "fe80:", 5) == 0)
                    393:                                continue;
                    394:
                    395:                        p = t;
                    396:                        while (*p && *p != ' ' && *p != '\n')
                    397:                                p++;
                    398:                        *p = '\0';
1.93      itojun    399:                        strlcpy(net_ip6, t, sizeof(net_ip6));
1.56      itojun    400:                        break;
                    401:                }
                    402:        }
1.87      dsl       403:        free(textbuf);
1.105     dsl       404: }
1.56      itojun    405: #endif
1.21      simonb    406:
1.105     dsl       407: static void
                    408: get_host_info(void)
                    409: {
                    410:        char hostname[MAXHOSTNAMELEN + 1];
                    411:        char *dot;
                    412:
1.21      simonb    413:        /* Check host (and domain?) name */
1.102     dsl       414:        if (gethostname(hostname, sizeof(hostname)) == 0 && hostname[0] != 0) {
1.87      dsl       415:                hostname[sizeof(hostname) - 1] = 0;
1.58      cyber     416:                /* check for a . */
                    417:                dot = strchr(hostname, '.');
1.87      dsl       418:                if (dot == NULL) {
1.58      cyber     419:                        /* if not found its just a host, punt on domain */
1.87      dsl       420:                        strlcpy(net_host, hostname, sizeof net_host);
1.58      cyber     421:                } else {
                    422:                        /* split hostname into host/domain parts */
1.87      dsl       423:                        *dot++ = 0;
                    424:                        strlcpy(net_host, hostname, sizeof net_host);
                    425:                        strlcpy(net_domain, dot, sizeof net_domain);
1.58      cyber     426:                }
1.31      mrg       427:        }
1.21      simonb    428: }
                    429:
1.96      perry     430: /*
1.105     dsl       431:  * recombine name parts split in get_host_info and config_network
1.96      perry     432:  * (common code moved here from write_etc_hosts)
                    433:  */
                    434: static char *
                    435: recombine_host_domain(void)
                    436: {
                    437:        static char recombined[MAXHOSTNAMELEN + 1];
                    438:        int l = strlen(net_host) - strlen(net_domain);
                    439:
                    440:        strlcpy(recombined, net_host, sizeof(recombined));
                    441:
                    442:        if (l <= 0 ||
                    443:            net_host[l - 1] != '.' ||
                    444:            strcasecmp(net_domain, net_host + l) != 0) {
                    445:                /* net_host isn't an FQDN. */
                    446:                strlcat(recombined, ".", sizeof(recombined));
                    447:                strlcat(recombined, net_domain, sizeof(recombined));
                    448:        }
                    449:        return recombined;
                    450: }
                    451:
1.56      itojun    452: #ifdef INET6
                    453: static int
1.86      dsl       454: is_v6kernel(void)
1.56      itojun    455: {
                    456:        int s;
                    457:
                    458:        s = socket(PF_INET6, SOCK_DGRAM, 0);
                    459:        if (s < 0)
                    460:                return 0;
1.87      dsl       461:        close(s);
                    462:        return 1;
1.56      itojun    463: }
                    464:
                    465: /*
                    466:  * initialize as v6 client.
                    467:  * we are sure that we will never become router with boot floppy :-)
                    468:  * (include and use sysctl(8) if you are willing to)
                    469:  */
                    470: static void
1.86      dsl       471: init_v6kernel(int autoconf)
1.56      itojun    472: {
                    473:        int v;
                    474:        int mib[4] = {CTL_NET, PF_INET6, IPPROTO_IPV6, 0};
                    475:
                    476:        mib[3] = IPV6CTL_FORWARDING;
                    477:        v = 0;
1.113     he        478:        (void)sysctl(mib, 4, NULL, NULL, (void *)&v, sizeof(v));
1.56      itojun    479:
                    480:        mib[3] = IPV6CTL_ACCEPT_RTADV;
                    481:        v = autoconf ? 1 : 0;
1.113     he        482:        (void)sysctl(mib, 4, NULL, NULL, (void *)&v, sizeof(v));
1.56      itojun    483: }
                    484:
                    485: static int
1.86      dsl       486: get_v6wait(void)
1.56      itojun    487: {
1.94      mrg       488:        size_t len = sizeof(int);
1.56      itojun    489:        int v;
                    490:        int mib[4] = {CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_DAD_COUNT};
                    491:
                    492:        len = sizeof(v);
1.94      mrg       493:        if (sysctl(mib, 4, (void *)&v, &len, NULL, 0) < 0) {
1.56      itojun    494:                /* warn("sysctl(net.inet6.ip6.dadcount)"); */
                    495:                return 1;       /* guess */
                    496:        }
                    497:        return v;
                    498: }
                    499: #endif
                    500:
1.118     christos  501: static int
                    502: handle_license(const char *dev)
                    503: {
                    504:        static struct {
                    505:                const char *dev;
                    506:                const char *lic;
                    507:        } licdev[] = {
                    508:                { "iwi", "/libdata/firmware/if_iwi/LICENSE.ipw2200-fw" },
                    509:                { "ipw", "/libdata/firmware/if_ipw/LICENSE" },
                    510:        };
                    511:
                    512:        size_t i;
                    513:
                    514:        for (i = 0; i < __arraycount(licdev); i++)
                    515:                if (strncmp(dev, licdev[i].dev, 3) == 0) {
                    516:                        char buf[64];
                    517:                        int val;
                    518:                        size_t len = sizeof(int);
                    519:                        (void)snprintf(buf, sizeof(buf), "hw.%s.accept_eula",
                    520:                            licdev[i].dev);
                    521:                        if (sysctlbyname(buf, &val, &len, NULL, 0) != -1
                    522:                            && val != 0)
                    523:                                return 1;
                    524:                        msg_display(MSG_license, dev, licdev[i].lic);
                    525:                        process_menu(MENU_yesno, NULL);
                    526:                        if (yesno) {
                    527:                                val = 1;
                    528:                                if (sysctlbyname(buf, NULL, NULL, &val,
                    529:                                    0) == -1)
                    530:                                        return 0;
1.119     christos  531:                                add_sysctl_conf("%s=1", buf);
1.118     christos  532:                                return 1;
                    533:                        } else
                    534:                                return 0;
                    535:                }
                    536:        return 1;
                    537: }
                    538:
1.30      mrg       539: /*
                    540:  * Get the information to configure the network, configure it and
                    541:  * make sure both the gateway and the name server are up.
                    542:  */
                    543: int
1.86      dsl       544: config_network(void)
                    545: {
                    546:        char *tp;
1.87      dsl       547:        char *defname;
                    548:        const char *prompt;
1.105     dsl       549:        char *textbuf;
1.1       phil      550:        int  octet0;
1.107     dsl       551:        int  dhcp_config;
1.121     ad        552:        int  nfs_root = 0;
1.118     christos  553:        int  slip = 0;
1.106     christos  554:        int  pid, status;
                    555:        char **ap, *slcmd[10], *in_buf;
                    556:        char buffer[STRSIZE];
1.121     ad        557:        struct statvfs sb;
1.106     christos  558:
1.87      dsl       559:        int l;
1.102     dsl       560:        char dhcp_host[STRSIZE];
1.81      christos  561: #ifdef INET6
                    562:        int v6config = 1;
                    563: #endif
1.1       phil      564:
                    565:        FILE *f;
1.12      jonathan  566:        time_t now;
1.1       phil      567:
1.8       phil      568:        if (network_up)
1.30      mrg       569:                return (1);
1.8       phil      570:
1.30      mrg       571:        get_ifconfig_info();
1.50      cgd       572:
1.92      dsl       573:        if (net_up != NULL) {
1.107     dsl       574:                /* XXX: some retry loops come here... */
1.87      dsl       575:                /* active interfaces found */
                    576:                msg_display(MSG_netup, net_up);
                    577:                process_menu(MENU_yesno, NULL);
1.111     martin    578:                if (!yesno)
                    579:                        return 0;
1.87      dsl       580:        }
1.92      dsl       581:
                    582:        if (net_devices == NULL) {
                    583:                /* No network interfaces found! */
                    584:                msg_display(MSG_nonet);
                    585:                process_menu(MENU_ok, NULL);
                    586:                return (-1);
                    587:        }
                    588:        network_up = 1;
1.87      dsl       589:
1.70      mrg       590: again:
1.87      dsl       591:        tp = strchr(net_devices, ' ');
                    592:        asprintf(&defname, "%.*s", (int)(tp - net_devices), net_devices);
                    593:        for (prompt = MSG_asknetdev;; prompt = MSG_badnet) {
                    594:                msg_prompt(prompt, defname, net_dev, sizeof net_dev - 1,
                    595:                    net_devices);
                    596:                l = strlen(net_dev);
                    597:                net_dev[l] = ' ';
                    598:                net_dev[l + 1] = 0;
                    599:                tp = strstr(net_devices, net_dev);
                    600:                if (tp == NULL)
                    601:                        continue;
                    602:                if (tp != net_devices && tp[-1] != ' ')
                    603:                        continue;
                    604:                net_dev[l] = 0;
                    605:                break;
1.1       phil      606:        }
1.87      dsl       607:        free(defname);
1.118     christos  608:        if (!handle_license(net_dev))
                    609:                goto done;
1.56      itojun    610:
1.107     dsl       611:        slip = net_dev[0] == 's' && net_dev[1] == 'l' &&
                    612:            isdigit((unsigned char)net_dev[2]);
1.61      itojun    613:
1.121     ad        614:        /* If root is on NFS do not reconfigure the interface. */
                    615:        if (statvfs("/", &sb) == 0 && strcmp(sb.f_fstypename, "nfs") == 0) {
                    616:                nfs_root = 1;
                    617:                dhcp_config = 0;
                    618:                get_ifinterface_info();
                    619:                get_if6interface_info();
                    620:                get_host_info();
                    621:        } else if (slip) {
1.107     dsl       622:                dhcp_config = 0;
1.121     ad        623:        } else {
1.106     christos  624:                /* Preload any defaults we can find */
1.83      jmc       625:                get_ifinterface_info();
1.105     dsl       626:                get_if6interface_info();
                    627:                get_host_info();
1.83      jmc       628:
1.106     christos  629:                /* domain and host */
                    630:                msg_display(MSG_netinfo);
1.61      itojun    631:
1.106     christos  632:                /* ethernet medium */
                    633:                for (;;) {
                    634:                        msg_prompt_add(MSG_net_media, net_media, net_media,
                    635:                                        sizeof net_media);
                    636:
                    637:                        /*
                    638:                         * ifconfig does not allow media specifiers on
                    639:                         * IFM_MANUAL interfaces.  Our UI gives no way
                    640:                         * to set an option back
                    641:                         * to null-string if it gets accidentally set.
                    642:                         * Check for plausible alternatives.
                    643:                         */
                    644:                        if (strcmp(net_media, "<default>") == 0 ||
                    645:                            strcmp(net_media, "default") == 0 ||
                    646:                            strcmp(net_media, "<manual>") == 0 ||
                    647:                            strcmp(net_media, "manual") == 0 ||
                    648:                            strcmp(net_media, "<none>") == 0 ||
                    649:                            strcmp(net_media, "none") == 0 ||
                    650:                            strcmp(net_media, " ") == 0) {
                    651:                                *net_media = '\0';
                    652:                        }
1.58      cyber     653:
1.106     christos  654:                        if (*net_media == '\0')
                    655:                                break;
                    656:                        /*
                    657:                         * We must set the media type here - to give dhcp
                    658:                         * a chance
                    659:                         */
                    660:                        if (run_program(0, "/sbin/ifconfig %s media %s",
                    661:                                    net_dev, net_media) == 0)
                    662:                                break;
                    663:                        /* Failed to set - output the supported values */
                    664:                        if (collect(T_OUTPUT, &textbuf, "/sbin/ifconfig -m %s |"
                    665:                                    "while IFS=; read line;"
                    666:                                    " do [ \"$line\" = \"${line#*media}\" ] || "
                    667:                                    "echo $line;"
                    668:                                    " done", net_dev ) > 0)
                    669:                                msg_display(textbuf);
                    670:                        free(textbuf);
                    671:                }
                    672:
1.117     reed      673:                net_dhcpconf = 0;
1.106     christos  674:                /* try a dhcp configuration */
                    675:                dhcp_config = config_dhcp(net_dev);
                    676:                if (dhcp_config) {
                    677:                        /* Get newly configured data off interface. */
                    678:                        get_ifinterface_info();
                    679:                        get_if6interface_info();
                    680:                        get_host_info();
                    681:
                    682:                        net_dhcpconf |= DHCPCONF_IPADDR;
                    683:
                    684:                        /*
                    685:                         * Extract default route from output of
                    686:                         * 'route -n show'
                    687:                         */
                    688:                        if (collect(T_OUTPUT, &textbuf,
                    689:                                    "/sbin/route -n show | "
                    690:                                    "while read dest gateway flags;"
                    691:                                    " do [ \"$dest\" = default ] && {"
                    692:                                        " echo $gateway; break; };"
                    693:                                    " done" ) > 0)
                    694:                                strlcpy(net_defroute, textbuf,
                    695:                                    sizeof net_defroute);
                    696:                        free(textbuf);
                    697:
                    698:                        /* pull nameserver info out of /etc/resolv.conf */
                    699:                        if (collect(T_OUTPUT, &textbuf,
                    700:                                    "cat /etc/resolv.conf 2>/dev/null |"
                    701:                                    " while read keyword address rest;"
                    702:                                    " do [ \"$keyword\" = nameserver "
                    703:                                        " -a \"${address#*:}\" = "
                    704:                                        "\"${address}\" ] && {"
                    705:                                            " echo $address; break; };"
                    706:                                    " done" ) > 0)
                    707:                                strlcpy(net_namesvr, textbuf,
                    708:                                    sizeof net_namesvr);
                    709:                        free(textbuf);
                    710:                        if (net_namesvr[0] != '\0')
                    711:                                net_dhcpconf |= DHCPCONF_NAMESVR;
                    712:
                    713:                        /* pull domainname out of leases file */
                    714:                        get_dhcp_value(net_domain, sizeof(net_domain),
                    715:                            "domain-name");
                    716:                        if (net_domain[0] != '\0')
                    717:                                net_dhcpconf |= DHCPCONF_DOMAIN;
                    718:
                    719:                        /* pull hostname out of leases file */
                    720:                        dhcp_host[0] = 0;
                    721:                        get_dhcp_value(dhcp_host, sizeof(dhcp_host),
1.115     is        722:                            "host-name");
1.106     christos  723:                        if (dhcp_host[0] != '\0') {
                    724:                                net_dhcpconf |= DHCPCONF_HOST;
                    725:                                strlcpy(net_host, dhcp_host, sizeof net_host);
                    726:                        }
1.102     dsl       727:                }
1.107     dsl       728:        }
1.56      itojun    729:
1.87      dsl       730:        msg_prompt_add(MSG_net_domain, net_domain, net_domain,
                    731:            sizeof net_domain);
                    732:        msg_prompt_add(MSG_net_host, net_host, net_host, sizeof net_host);
1.56      itojun    733:
1.61      itojun    734:        if (!dhcp_config) {
                    735:                /* Manually configure IPv4 */
1.121     ad        736:                if (!nfs_root)
                    737:                        msg_prompt_add(MSG_net_ip, net_ip, net_ip,
                    738:                            sizeof net_ip);
1.107     dsl       739:                if (slip)
                    740:                        msg_prompt_add(MSG_net_srv_ip, net_srv_ip, net_srv_ip,
                    741:                            sizeof net_srv_ip);
1.121     ad        742:                else if (!nfs_root) {
1.107     dsl       743:                        /* We don't want netmasks for SLIP */
1.106     christos  744:                        octet0 = atoi(net_ip);
1.107     dsl       745:                        if (!net_mask[0]) {
1.106     christos  746:                                if (0 <= octet0 && octet0 <= 127)
                    747:                                        strlcpy(net_mask, "0xff000000",
                    748:                                        sizeof(net_mask));
                    749:                                else if (128 <= octet0 && octet0 <= 191)
                    750:                                        strlcpy(net_mask, "0xffff0000",
                    751:                                        sizeof(net_mask));
                    752:                                else if (192 <= octet0 && octet0 <= 223)
                    753:                                        strlcpy(net_mask, "0xffffff00",
                    754:                                        sizeof(net_mask));
                    755:                        }
                    756:                        msg_prompt_add(MSG_net_mask, net_mask, net_mask,
1.107     dsl       757:                            sizeof net_mask);
                    758:                }
1.61      itojun    759:                msg_prompt_add(MSG_net_defroute, net_defroute, net_defroute,
1.87      dsl       760:                    sizeof net_defroute);
1.102     dsl       761:        }
1.107     dsl       762:
1.102     dsl       763:        if (!dhcp_config || net_namesvr[0] == 0)
1.61      itojun    764:                msg_prompt_add(MSG_net_namesrv, net_namesvr, net_namesvr,
1.87      dsl       765:                    sizeof net_namesvr);
1.56      itojun    766:
                    767: #ifdef INET6
                    768:        /* IPv6 autoconfiguration */
1.60      itojun    769:        if (!is_v6kernel())
1.56      itojun    770:                v6config = 0;
1.77      itojun    771:        else if (v6config) {
1.105     dsl       772:                process_menu(MENU_noyes, deconst(MSG_Perform_IPv6_autoconfiguration));
1.56      itojun    773:                v6config = yesno ? 1 : 0;
1.72      itojun    774:                net_ip6conf |= yesno ? IP6CONF_AUTOHOST : 0;
1.56      itojun    775:        }
                    776:
                    777:        if (v6config) {
1.84      dsl       778:                process_menu(MENU_namesrv6, NULL);
1.1       phil      779:                if (!yesno)
1.56      itojun    780:                        msg_prompt_add(MSG_net_namesrv6, net_namesvr6,
1.87      dsl       781:                            net_namesvr6, sizeof net_namesvr6);
1.56      itojun    782:        }
                    783: #endif
                    784:
                    785:        /* confirm the setting */
1.106     christos  786:        if (slip)
                    787:                msg_display(MSG_netok_slip, net_domain, net_host, net_dev,
                    788:                        *net_ip == '\0' ? "<none>" : net_ip,
1.107     dsl       789:                        *net_srv_ip == '\0' ? "<none>" : net_srv_ip,
1.106     christos  790:                        *net_mask == '\0' ? "<none>" : net_mask,
                    791:                        *net_namesvr == '\0' ? "<none>" : net_namesvr,
                    792:                        *net_defroute == '\0' ? "<none>" : net_defroute,
                    793:                        *net_media == '\0' ? "<default>" : net_media);
                    794:        else
                    795:                msg_display(MSG_netok, net_domain, net_host, net_dev,
                    796:                        *net_ip == '\0' ? "<none>" : net_ip,
                    797:                        *net_mask == '\0' ? "<none>" : net_mask,
                    798:                        *net_namesvr == '\0' ? "<none>" : net_namesvr,
                    799:                        *net_defroute == '\0' ? "<none>" : net_defroute,
                    800:                        *net_media == '\0' ? "<default>" : net_media);
1.56      itojun    801: #ifdef INET6
1.70      mrg       802:        msg_display_add(MSG_netokv6,
1.56      itojun    803:                     !is_v6kernel() ? "<not supported>" :
                    804:                        (v6config ? "yes" : "no"),
1.70      mrg       805:                     *net_namesvr6 == '\0' ? "<none>" : net_namesvr6);
1.56      itojun    806: #endif
1.118     christos  807: done:
1.102     dsl       808:        process_menu(MENU_yesno, deconst(MSG_netok_ok));
1.56      itojun    809:        if (!yesno)
                    810:                msg_display(MSG_netagain);
                    811:        if (!yesno)
                    812:                goto again;
                    813:
                    814:        /*
                    815:         * we may want to perform checks against inconsistent configuration,
                    816:         * like IPv4 DNS server without IPv4 configuration.
                    817:         */
1.1       phil      818:
1.20      simonb    819:        /* Create /etc/resolv.conf if a nameserver was given */
1.96      perry     820:        if (net_namesvr[0] != '\0'
1.56      itojun    821: #ifdef INET6
1.96      perry     822:            || net_namesvr6[0] != '\0'
1.56      itojun    823: #endif
                    824:                ) {
1.30      mrg       825:                f = fopen("/etc/resolv.conf", "w");
1.20      simonb    826:                if (f == NULL) {
1.36      garbled   827:                        if (logging)
1.80      fvdl      828:                                (void)fprintf(logfp,
                    829:                                    "%s", msg_string(MSG_resolv));
1.20      simonb    830:                        (void)fprintf(stderr, "%s", msg_string(MSG_resolv));
                    831:                        exit(1);
                    832:                }
1.70      mrg       833:                scripting_fprintf(NULL, "cat <<EOF >/etc/resolv.conf\n");
1.20      simonb    834:                time(&now);
                    835:                /* NB: ctime() returns a string ending in  '\n' */
1.87      dsl       836:                scripting_fprintf(f, ";\n; BIND data file\n; %s %s;\n",
                    837:                    "Created by NetBSD sysinst on", ctime(&now));
1.97      perry     838:                if (net_domain[0] != '\0')
                    839:                        scripting_fprintf(f, "search %s\n", net_domain);
1.96      perry     840:                if (net_namesvr[0] != '\0')
1.70      mrg       841:                        scripting_fprintf(f, "nameserver %s\n", net_namesvr);
1.56      itojun    842: #ifdef INET6
1.96      perry     843:                if (net_namesvr6[0] != '\0')
1.70      mrg       844:                        scripting_fprintf(f, "nameserver %s\n", net_namesvr6);
1.56      itojun    845: #endif
1.70      mrg       846:                scripting_fprintf(NULL, "EOF\n");
1.36      garbled   847:                fflush(NULL);
1.30      mrg       848:                fclose(f);
1.1       phil      849:        }
                    850:
1.100     dsl       851:        run_program(0, "/sbin/ifconfig lo0 127.0.0.1");
1.35      jonathan  852:
1.56      itojun    853: #ifdef INET6
1.121     ad        854:        if (v6config && !nfs_root) {
1.56      itojun    855:                init_v6kernel(1);
1.100     dsl       856:                run_program(0, "/sbin/ifconfig %s up", net_dev);
1.56      itojun    857:                sleep(get_v6wait() + 1);
1.100     dsl       858:                run_program(RUN_DISPLAY, "/sbin/rtsol -D %s", net_dev);
1.56      itojun    859:                sleep(get_v6wait() + 1);
                    860:        }
                    861: #endif
                    862:
1.96      perry     863:        if (net_ip[0] != '\0') {
1.106     christos  864:                if (slip) {
1.107     dsl       865:                        /* XXX: needs 'ifconfig sl0 create' much earlier */
1.106     christos  866:                        /* Set SLIP interface UP */
1.107     dsl       867:                        run_program(0, "/sbin/ifconfig %s inet %s %s up",
                    868:                            net_dev, net_ip, net_srv_ip);
1.106     christos  869:                        strcpy(sl_flags, "-s 115200 -l /dev/tty00");
1.107     dsl       870:                        msg_prompt_win(MSG_slattach, -1, 12, 70, 0,
                    871:                                sl_flags, sl_flags, 255);
1.106     christos  872:
1.107     dsl       873:                        /* XXX: wtf isn't run_program() used here? */
1.106     christos  874:                        pid = fork();
                    875:                        if (pid == 0) {
                    876:                                strcpy(buffer, "/sbin/slattach ");
                    877:                                strcat(buffer, sl_flags);
                    878:                                in_buf = buffer;
                    879:
                    880:                                for (ap = slcmd; (*ap = strsep(&in_buf, " ")) != NULL;)
                    881:                                if (**ap != '\0')
                    882:                                        ++ap;
                    883:
                    884:                                execvp(slcmd[0], slcmd);
                    885:                        } else
                    886:                                wait4(pid, &status, WNOHANG, 0);
1.121     ad        887:                } else if (!nfs_root) {
1.106     christos  888:                        if (net_mask[0] != '\0') {
                    889:                                run_program(0, "/sbin/ifconfig %s inet %s netmask %s",
                    890:                                    net_dev, net_ip, net_mask);
                    891:                        } else {
                    892:                                run_program(0, "/sbin/ifconfig %s inet %s",
                    893:                                net_dev, net_ip);
                    894:                        }
1.56      itojun    895:                }
                    896:        }
1.3       phil      897:
1.28      jonathan  898:        /* Set host name */
1.96      perry     899:        if (net_host[0] != '\0')
1.28      jonathan  900:                sethostname(net_host, strlen(net_host));
                    901:
1.20      simonb    902:        /* Set a default route if one was given */
1.121     ad        903:        if (!nfs_root && net_defroute[0] != '\0') {
1.101     dsl       904:                run_program(RUN_DISPLAY | RUN_PROGRESS,
                    905:                                "/sbin/route -n flush -inet");
                    906:                run_program(RUN_DISPLAY | RUN_PROGRESS,
                    907:                                "/sbin/route -n add default %s", net_defroute);
1.20      simonb    908:        }
1.75      mrg       909:
                    910:        /*
                    911:         * wait a couple of seconds for the interface to go live.
                    912:         */
1.121     ad        913:        if (!nfs_root) {
                    914:                msg_display_add(MSG_wait_network);
                    915:                sleep(5);
                    916:        }
1.20      simonb    917:
1.36      garbled   918:        /*
                    919:         * ping should be verbose, so users can see the cause
                    920:         * of a network failure.
                    921:         */
1.56      itojun    922:
                    923: #ifdef INET6
                    924:        if (v6config && network_up) {
1.100     dsl       925:                network_up = !run_program(RUN_DISPLAY | RUN_PROGRESS,
1.59      itojun    926:                    "/sbin/ping6 -v -c 3 -n -I %s ff02::2", net_dev);
1.56      itojun    927:
1.96      perry     928:                if (net_namesvr6[0] != '\0')
1.100     dsl       929:                        network_up = !run_program(RUN_DISPLAY | RUN_PROGRESS,
1.56      itojun    930:                            "/sbin/ping6 -v -c 3 -n %s", net_namesvr6);
                    931:        }
                    932: #endif
1.36      garbled   933:
1.96      perry     934:        if (net_namesvr[0] != '\0' && network_up)
1.100     dsl       935:                network_up = !run_program(RUN_DISPLAY | RUN_PROGRESS,
1.87      dsl       936:                    "/sbin/ping -v -c 5 -w 5 -o -n %s", net_namesvr);
                    937:
1.96      perry     938:        if (net_defroute[0] != '\0' && network_up)
1.100     dsl       939:                network_up = !run_program(RUN_DISPLAY | RUN_PROGRESS,
1.87      dsl       940:                    "/sbin/ping -v -c 5 -w 5 -o -n %s", net_defroute);
1.36      garbled   941:        fflush(NULL);
1.8       phil      942:
                    943:        return network_up;
1.1       phil      944: }
                    945:
1.107     dsl       946: static int
                    947: ftp_fetch(const char *set_name)
1.87      dsl       948: {
1.107     dsl       949:        const char *ftp_opt;
1.38      perry     950:        char ftp_user_encoded[STRSIZE];
                    951:        char ftp_dir_encoded[STRSIZE];
1.123     joerg     952:        char *cp, *set_dir2;
1.107     dsl       953:        int rval;
                    954:
                    955:        /*
                    956:         * Invoke ftp to fetch the file.
                    957:         *
                    958:         * ftp.pass is quite likely to contain unsafe characters
                    959:         * that need to be encoded in the URL (for example,
                    960:         * "@", ":" and "/" need quoting).  Let's be
                    961:         * paranoid and also encode ftp.user and ftp.dir.  (For
                    962:         * example, ftp.dir could easily contain '~', which is
                    963:         * unsafe by a strict reading of RFC 1738).
                    964:         */
                    965:        if (strcmp("ftp", ftp.user) == 0 && ftp.pass[0] == 0) {
                    966:                /* do anon ftp */
                    967:                ftp_opt = "-a ";
                    968:                ftp_user_encoded[0] = 0;
                    969:        } else {
                    970:                ftp_opt = "";
                    971:                cp = url_encode(ftp_user_encoded, ftp.user,
                    972:                        ftp_user_encoded + sizeof ftp_user_encoded - 1,
                    973:                        RFC1738_SAFE_LESS_SHELL, 0);
                    974:                *cp++ = ':';
                    975:                cp = url_encode(cp, ftp.pass,
                    976:                        ftp_user_encoded + sizeof ftp_user_encoded - 1,
                    977:                        NULL, 0);
                    978:                *cp++ = '@';
                    979:                *cp = 0;
                    980:        }
                    981:
                    982:        cp = url_encode(ftp_dir_encoded, ftp.dir,
                    983:                        ftp_dir_encoded + sizeof ftp_dir_encoded - 1,
                    984:                        RFC1738_SAFE_LESS_SHELL_PLUS_SLASH, 1);
1.123     joerg     985:        if (cp != ftp_dir_encoded && cp[-1] != '/')
1.107     dsl       986:                *cp++ = '/';
1.123     joerg     987:
                    988:        set_dir2 = set_dir;
                    989:        while (*set_dir2 == '/')
                    990:                ++set_dir2;
                    991:
                    992:        url_encode(cp, set_dir2,
1.107     dsl       993:                        ftp_dir_encoded + sizeof ftp_dir_encoded,
                    994:                        RFC1738_SAFE_LESS_SHELL_PLUS_SLASH, 0);
                    995:
                    996:        rval = run_program(RUN_DISPLAY | RUN_PROGRESS | RUN_XFER_DIR,
                    997:                    "/usr/bin/ftp %s%s://%s%s/%s/%s%s",
                    998:                    ftp_opt, ftp.xfer_type, ftp_user_encoded, ftp.host,
                    999:                    ftp_dir_encoded, set_name, dist_postfix);
                   1000:
                   1001:        return rval ? SET_RETRY : SET_OK;
                   1002: }
                   1003:
                   1004: static int
                   1005: do_config_network(void)
                   1006: {
                   1007:        int ret;
1.1       phil     1008:
1.50      cgd      1009:        while ((ret = config_network()) <= 0) {
                   1010:                if (ret < 0)
                   1011:                        return (-1);
1.30      mrg      1012:                msg_display(MSG_netnotup);
1.84      dsl      1013:                process_menu(MENU_yesno, NULL);
1.76      mrg      1014:                if (!yesno) {
                   1015:                        msg_display(MSG_netnotup_continueanyway);
1.84      dsl      1016:                        process_menu(MENU_yesno, NULL);
1.76      mrg      1017:                        if (!yesno)
1.107     dsl      1018:                                return -1;
1.76      mrg      1019:                        network_up = 1;
1.107     dsl      1020:                        break;
1.76      mrg      1021:                }
1.3       phil     1022:        }
1.107     dsl      1023:        return 0;
                   1024: }
1.10      phil     1025:
1.107     dsl      1026: int
                   1027: get_via_ftp(const char *xfer_type)
                   1028: {
                   1029:
                   1030:        if (do_config_network() != 0)
                   1031:                return SET_RETRY;
1.10      phil     1032:
1.103     dsl      1033:        process_menu(MENU_ftpsource, deconst(xfer_type));
1.42      bouyer   1034:
1.107     dsl      1035:        /* We'll fetch each file just before installing it */
                   1036:        fetch_fn = ftp_fetch;
                   1037:        ftp.xfer_type = xfer_type;
1.108     dsl      1038:        snprintf(ext_dir, sizeof ext_dir, "%s/%s", target_prefix(),
                   1039:            xfer_dir + (*xfer_dir == '/'));
1.102     dsl      1040:
1.107     dsl      1041:        return SET_OK;
1.1       phil     1042: }
                   1043:
1.5       phil     1044: int
1.86      dsl      1045: get_via_nfs(void)
1.1       phil     1046: {
1.120     ad       1047:        struct statvfs sb;
1.30      mrg      1048:
1.107     dsl      1049:        if (do_config_network() != 0)
                   1050:                return SET_RETRY;
1.5       phil     1051:
1.120     ad       1052:        /* If root is on NFS and we have sets, skip this step. */
                   1053:        if (statvfs(set_dir, &sb) == 0 &&
                   1054:            strcmp(sb.f_fstypename, "nfs") == 0) {
                   1055:                strlcpy(ext_dir, set_dir, sizeof ext_dir);
                   1056:                return SET_OK;
                   1057:        }
                   1058:
1.1       phil     1059:        /* Get server and filepath */
1.84      dsl      1060:        process_menu(MENU_nfssource, NULL);
1.5       phil     1061:
1.1       phil     1062:        /* Mount it */
1.100     dsl      1063:        if (run_program(0, "/sbin/mount -r -o -2,-i,-r=1024 -t nfs %s:%s /mnt2",
1.107     dsl      1064:            nfs_host, nfs_dir))
                   1065:                return SET_RETRY;
                   1066:
1.95      dsl      1067:        mnt2_mounted = 1;
1.24      jonathan 1068:
1.102     dsl      1069:        snprintf(ext_dir, sizeof ext_dir, "/mnt2/%s", set_dir);
                   1070:
1.5       phil     1071:        /* return location, don't clean... */
1.107     dsl      1072:        return SET_OK;
1.8       phil     1073: }
                   1074:
1.13      jonathan 1075: /*
1.51      cgd      1076:  * write the new contents of /etc/hosts to the specified file
                   1077:  */
                   1078: static void
                   1079: write_etc_hosts(FILE *f)
                   1080: {
1.70      mrg      1081:        scripting_fprintf(f, "#\n");
                   1082:        scripting_fprintf(f, "# Added by NetBSD sysinst\n");
                   1083:        scripting_fprintf(f, "#\n");
1.51      cgd      1084:
1.97      perry    1085:        if (net_domain[0] != '\0')
                   1086:                scripting_fprintf(f, "127.0.0.1 localhost.%s\n", net_domain);
1.51      cgd      1087:
1.70      mrg      1088:        scripting_fprintf(f, "%s\t", net_ip);
1.97      perry    1089:        if (net_domain[0] != '\0')
                   1090:                scripting_fprintf(f, "%s ", recombine_host_domain());
                   1091:        scripting_fprintf(f, "%s\n", net_host);
1.51      cgd      1092: }
                   1093:
                   1094: /*
1.13      jonathan 1095:  * Write the network config info the user entered via menus into the
                   1096:  * config files in the target disk.  Be careful not to lose any
                   1097:  * information we don't immediately add back, in case the install
1.87      dsl      1098:  * target is the currently-active root.
1.13      jonathan 1099:  */
1.8       phil     1100: void
                   1101: mnt_net_config(void)
                   1102: {
1.87      dsl      1103:        char ifconfig_fn[STRSIZE];
1.74      itojun   1104:        FILE *ifconf = NULL;
1.8       phil     1105:
1.61      itojun   1106:        if (!network_up)
                   1107:                return;
1.102     dsl      1108:        process_menu(MENU_yesno, deconst(MSG_mntnetconfig));
                   1109:        if (!yesno)
1.61      itojun   1110:                return;
                   1111:
1.82      shin     1112:        /* Write hostname to /etc/rc.conf */
1.70      mrg      1113:        if ((net_dhcpconf & DHCPCONF_HOST) == 0)
1.96      perry    1114:                add_rc_conf("hostname=%s\n", recombine_host_domain());
1.61      itojun   1115:
                   1116:        /* If not running in target, copy resolv.conf there. */
                   1117:        if ((net_dhcpconf & DHCPCONF_NAMESVR) == 0) {
1.72      itojun   1118: #ifndef INET6
1.96      perry    1119:                if (net_namesvr[0] != '\0')
1.61      itojun   1120:                        dup_file_into_target("/etc/resolv.conf");
1.72      itojun   1121: #else
                   1122:                /*
                   1123:                 * not sure if it is a good idea, to allow dhcp config to
                   1124:                 * override IPv6 configuration
                   1125:                 */
1.96      perry    1126:                if (net_namesvr[0] != '\0' || net_namesvr6[0] != '\0')
1.72      itojun   1127:                        dup_file_into_target("/etc/resolv.conf");
                   1128: #endif
                   1129:        }
                   1130:
                   1131:        /*
                   1132:         * bring the interface up, it will be necessary for IPv6, and
                   1133:         * it won't make trouble with IPv4 case either
                   1134:         */
1.87      dsl      1135:        snprintf(ifconfig_fn, sizeof ifconfig_fn, "/etc/ifconfig.%s", net_dev);
1.74      itojun   1136:        ifconf = target_fopen(ifconfig_fn, "w");
                   1137:        if (ifconf != NULL) {
1.72      itojun   1138:                scripting_fprintf(NULL, "cat <<EOF >>%s%s\n",
                   1139:                    target_prefix(), ifconfig_fn);
1.74      itojun   1140:                scripting_fprintf(ifconf, "up\n");
1.114     martin   1141:                if (*net_media != '\0')
                   1142:                        scripting_fprintf(ifconf, "media %s\n", net_media);
1.72      itojun   1143:                scripting_fprintf(NULL, "EOF\n");
1.61      itojun   1144:        }
                   1145:
                   1146:        if ((net_dhcpconf & DHCPCONF_IPADDR) == 0) {
1.74      itojun   1147:                FILE *hosts;
                   1148:
1.72      itojun   1149:                /* Write IPaddr and netmask to /etc/ifconfig.if[0-9] */
1.74      itojun   1150:                if (ifconf != NULL) {
1.72      itojun   1151:                        scripting_fprintf(NULL, "cat <<EOF >>%s%s\n",
                   1152:                            target_prefix(), ifconfig_fn);
                   1153:                        if (*net_media != '\0')
1.74      itojun   1154:                                scripting_fprintf(ifconf,
                   1155:                                    "%s netmask %s media %s\n",
1.72      itojun   1156:                                    net_ip, net_mask, net_media);
                   1157:                        else
1.74      itojun   1158:                                scripting_fprintf(ifconf, "%s netmask %s\n",
                   1159:                                    net_ip, net_mask);
1.72      itojun   1160:                        scripting_fprintf(NULL, "EOF\n");
                   1161:                }
                   1162:
1.87      dsl      1163:                /*
1.61      itojun   1164:                 * Add IPaddr/hostname to  /etc/hosts.
                   1165:                 * Be careful not to clobber any existing contents.
1.105     dsl      1166:                 * Relies on ordered search of /etc/hosts. XXX YP?
1.61      itojun   1167:                 */
1.74      itojun   1168:                hosts = target_fopen("/etc/hosts", "a");
                   1169:                if (hosts != 0) {
1.70      mrg      1170:                        scripting_fprintf(NULL, "cat <<EOF >>%s/etc/hosts\n",
                   1171:                            target_prefix());
1.74      itojun   1172:                        write_etc_hosts(hosts);
                   1173:                        (void)fclose(hosts);
1.70      mrg      1174:                        scripting_fprintf(NULL, "EOF\n");
1.74      itojun   1175:
                   1176:                        fclose(hosts);
1.61      itojun   1177:                }
1.12      jonathan 1178:
1.70      mrg      1179:                add_rc_conf("defaultroute=\"%s\"\n", net_defroute);
1.68      jdc      1180:        } else {
1.122     joerg    1181:                add_rc_conf("ifconfig_%s=dhcp\n", net_dev);
1.70      mrg      1182:         }
1.72      itojun   1183:
                   1184: #ifdef INET6
                   1185:        if ((net_ip6conf & IP6CONF_AUTOHOST) != 0) {
                   1186:                add_rc_conf("ip6mode=autohost\n");
1.74      itojun   1187:                if (ifconf != NULL) {
                   1188:                        scripting_fprintf(NULL, "cat <<EOF >>%s%s\n",
                   1189:                            target_prefix(), ifconfig_fn);
1.77      itojun   1190:                        scripting_fprintf(ifconf, "!rtsol $int\n");
1.74      itojun   1191:                        scripting_fprintf(NULL, "EOF\n");
                   1192:                }
1.72      itojun   1193:        }
                   1194: #endif
1.74      itojun   1195:
                   1196:        if (ifconf)
                   1197:                fclose(ifconf);
1.72      itojun   1198:
1.61      itojun   1199:        fflush(NULL);
1.1       phil     1200: }
1.58      cyber    1201:
                   1202: int
1.86      dsl      1203: config_dhcp(char *inter)
1.58      cyber    1204: {
                   1205:        int dhcpautoconf;
                   1206:
1.122     joerg    1207:        /*
                   1208:         * Don't bother checking for an existing instance of dhcpcd, just
                   1209:         * ask it to renew the lease.  It will fork and daemonize if there
                   1210:         * wasn't already an instance.
                   1211:         */
1.58      cyber    1212:
1.122     joerg    1213:        if (!file_mode_match(DHCPCD, S_IFREG))
1.58      cyber    1214:                return 0;
1.102     dsl      1215:        process_menu(MENU_yesno, deconst(MSG_Perform_DHCP_autoconfiguration));
1.58      cyber    1216:        if (yesno) {
1.122     joerg    1217:                /* spawn off dhcpcd and wait for parent to exit */
1.101     dsl      1218:                dhcpautoconf = run_program(RUN_DISPLAY | RUN_PROGRESS,
1.122     joerg    1219:                    "%s -d -n %s", DHCPCD, inter);
1.87      dsl      1220:                return dhcpautoconf ? 0 : 1;
1.58      cyber    1221:        }
                   1222:        return 0;
                   1223: }
                   1224:
1.61      itojun   1225: static void
1.122     joerg    1226: get_dhcp_value(char *targ, size_t l, const char *var)
1.58      cyber    1227: {
1.122     joerg    1228:        static const char *lease_data = "/tmp/dhcpcd-lease";
                   1229:        FILE *fp;
                   1230:        char *line;
                   1231:        size_t len, var_len;
                   1232:
                   1233:        if ((fp = fopen(lease_data, "r")) == NULL) {
                   1234:                warn("Could not open %s", lease_data);
                   1235:                *targ = '\0';
                   1236:                return;
                   1237:        }
                   1238:
                   1239:        var_len = strlen(var);
1.58      cyber    1240:
1.122     joerg    1241:        while ((line = fgetln(fp, &len)) != NULL) {
                   1242:                if (line[len - 1] == '\n')
                   1243:                        --len;
                   1244:                if (len <= var_len)
                   1245:                        continue;
                   1246:                if (memcmp(line, var, var_len))
                   1247:                        continue;
                   1248:                if (line[var_len] != '=')
                   1249:                        continue;
                   1250:                line += var_len + 1;
                   1251:                len -= var_len + 1;
                   1252:                strlcpy(targ, line, l > len ? len + 1: l);
                   1253:                break;
1.58      cyber    1254:        }
1.122     joerg    1255:
                   1256:        fclose(fp);
1.58      cyber    1257: }

CVSweb <webmaster@jp.NetBSD.org>