diff options
35 files changed, 520 insertions, 209 deletions
diff --git a/release/Makefile b/release/Makefile index 4713e38..8314b71 100644 --- a/release/Makefile +++ b/release/Makefile @@ -503,7 +503,7 @@ release.8: write_mfs_in_kernel @cd ${.CURDIR} && $(MAKE) installCRUNCH CRUNCH=boot \ DIR=${RD}/mfsfd/stand ZIP=false ( cd ${RD}/trees/bin/dev && \ - ls console tty bpf0 ttyv0 ttyv1 ttyv2 ttyv3 null zero card0 card1 card2 card3 usb usb0 uhid0 ums0 ulpt0 ugen0 kbd0 | \ + ls console tty bpf0 ttyv0 ttyv1 ttyv2 ttyv3 null zero card0 card1 card2 card3 usb usb0 uhid0 ums0 ulpt0 ugen0 kbd0 kmem mem | \ cpio -dump ${RD}/mfsfd/dev ) ( cd ${RD}/mfsfd/dev && rm -f *[swo]d*[bdefgh] ) ( cd ${RD}/mfsfd && mkdir -p bin sbin && ln -s /stand/sh bin/sh ) diff --git a/release/alpha/boot_crunch.conf b/release/alpha/boot_crunch.conf index e81fbae..533768b 100644 --- a/release/alpha/boot_crunch.conf +++ b/release/alpha/boot_crunch.conf @@ -9,6 +9,7 @@ progs pwd ppp progs sysinstall newfs minigzip cpio fsck ifconfig route slattach progs mount_nfs progs dhclient arp hostname +progs rtsol progs pccardc pccardd progs usbd usbdevs ln minigzip gzip diff --git a/release/alpha/dokern.sh b/release/alpha/dokern.sh index 79e0a96..598015c 100755 --- a/release/alpha/dokern.sh +++ b/release/alpha/dokern.sh @@ -9,9 +9,10 @@ sed -e '/pty/d' \ -e '/pass/d' \ -e '/apm0/d' \ -e '/ppp/d' \ + -e '/gif/d' \ + -e '/faith/d' \ -e '/gzip/d' \ -e '/splash/d' \ - -e '/IPv6/d' \ -e '/PROCFS/d' \ -e '/KTRACE/d' \ -e '/SYSVMSG/d' \ @@ -31,9 +32,10 @@ sed -e '/pty/d' \ -e '/pass/d' \ -e '/apm0/d' \ -e '/ppp/d' \ + -e '/gif/d' \ + -e '/faith/d' \ -e '/gzip/d' \ -e '/splash/d' \ - -e '/IPv6/d' \ -e '/PROCFS/d' \ -e '/KTRACE/d' \ -e '/SYSV/d' \ diff --git a/release/amd64/boot_crunch.conf b/release/amd64/boot_crunch.conf index e81fbae..533768b 100644 --- a/release/amd64/boot_crunch.conf +++ b/release/amd64/boot_crunch.conf @@ -9,6 +9,7 @@ progs pwd ppp progs sysinstall newfs minigzip cpio fsck ifconfig route slattach progs mount_nfs progs dhclient arp hostname +progs rtsol progs pccardc pccardd progs usbd usbdevs ln minigzip gzip diff --git a/release/amd64/dokern.sh b/release/amd64/dokern.sh index 79e0a96..598015c 100755 --- a/release/amd64/dokern.sh +++ b/release/amd64/dokern.sh @@ -9,9 +9,10 @@ sed -e '/pty/d' \ -e '/pass/d' \ -e '/apm0/d' \ -e '/ppp/d' \ + -e '/gif/d' \ + -e '/faith/d' \ -e '/gzip/d' \ -e '/splash/d' \ - -e '/IPv6/d' \ -e '/PROCFS/d' \ -e '/KTRACE/d' \ -e '/SYSVMSG/d' \ @@ -31,9 +32,10 @@ sed -e '/pty/d' \ -e '/pass/d' \ -e '/apm0/d' \ -e '/ppp/d' \ + -e '/gif/d' \ + -e '/faith/d' \ -e '/gzip/d' \ -e '/splash/d' \ - -e '/IPv6/d' \ -e '/PROCFS/d' \ -e '/KTRACE/d' \ -e '/SYSV/d' \ diff --git a/release/boot_crunch.conf b/release/boot_crunch.conf index e81fbae..533768b 100644 --- a/release/boot_crunch.conf +++ b/release/boot_crunch.conf @@ -9,6 +9,7 @@ progs pwd ppp progs sysinstall newfs minigzip cpio fsck ifconfig route slattach progs mount_nfs progs dhclient arp hostname +progs rtsol progs pccardc pccardd progs usbd usbdevs ln minigzip gzip diff --git a/release/i386/boot_crunch.conf b/release/i386/boot_crunch.conf index e81fbae..533768b 100644 --- a/release/i386/boot_crunch.conf +++ b/release/i386/boot_crunch.conf @@ -9,6 +9,7 @@ progs pwd ppp progs sysinstall newfs minigzip cpio fsck ifconfig route slattach progs mount_nfs progs dhclient arp hostname +progs rtsol progs pccardc pccardd progs usbd usbdevs ln minigzip gzip diff --git a/release/i386/dokern.sh b/release/i386/dokern.sh index 79e0a96..598015c 100755 --- a/release/i386/dokern.sh +++ b/release/i386/dokern.sh @@ -9,9 +9,10 @@ sed -e '/pty/d' \ -e '/pass/d' \ -e '/apm0/d' \ -e '/ppp/d' \ + -e '/gif/d' \ + -e '/faith/d' \ -e '/gzip/d' \ -e '/splash/d' \ - -e '/IPv6/d' \ -e '/PROCFS/d' \ -e '/KTRACE/d' \ -e '/SYSVMSG/d' \ @@ -31,9 +32,10 @@ sed -e '/pty/d' \ -e '/pass/d' \ -e '/apm0/d' \ -e '/ppp/d' \ + -e '/gif/d' \ + -e '/faith/d' \ -e '/gzip/d' \ -e '/splash/d' \ - -e '/IPv6/d' \ -e '/PROCFS/d' \ -e '/KTRACE/d' \ -e '/SYSV/d' \ diff --git a/release/pc98/boot_crunch.conf b/release/pc98/boot_crunch.conf index e81fbae..533768b 100644 --- a/release/pc98/boot_crunch.conf +++ b/release/pc98/boot_crunch.conf @@ -9,6 +9,7 @@ progs pwd ppp progs sysinstall newfs minigzip cpio fsck ifconfig route slattach progs mount_nfs progs dhclient arp hostname +progs rtsol progs pccardc pccardd progs usbd usbdevs ln minigzip gzip diff --git a/release/pc98/dokern.sh b/release/pc98/dokern.sh index 79e0a96..598015c 100755 --- a/release/pc98/dokern.sh +++ b/release/pc98/dokern.sh @@ -9,9 +9,10 @@ sed -e '/pty/d' \ -e '/pass/d' \ -e '/apm0/d' \ -e '/ppp/d' \ + -e '/gif/d' \ + -e '/faith/d' \ -e '/gzip/d' \ -e '/splash/d' \ - -e '/IPv6/d' \ -e '/PROCFS/d' \ -e '/KTRACE/d' \ -e '/SYSVMSG/d' \ @@ -31,9 +32,10 @@ sed -e '/pty/d' \ -e '/pass/d' \ -e '/apm0/d' \ -e '/ppp/d' \ + -e '/gif/d' \ + -e '/faith/d' \ -e '/gzip/d' \ -e '/splash/d' \ - -e '/IPv6/d' \ -e '/PROCFS/d' \ -e '/KTRACE/d' \ -e '/SYSV/d' \ diff --git a/release/scripts/dokern.sh b/release/scripts/dokern.sh index 79e0a96..598015c 100755 --- a/release/scripts/dokern.sh +++ b/release/scripts/dokern.sh @@ -9,9 +9,10 @@ sed -e '/pty/d' \ -e '/pass/d' \ -e '/apm0/d' \ -e '/ppp/d' \ + -e '/gif/d' \ + -e '/faith/d' \ -e '/gzip/d' \ -e '/splash/d' \ - -e '/IPv6/d' \ -e '/PROCFS/d' \ -e '/KTRACE/d' \ -e '/SYSVMSG/d' \ @@ -31,9 +32,10 @@ sed -e '/pty/d' \ -e '/pass/d' \ -e '/apm0/d' \ -e '/ppp/d' \ + -e '/gif/d' \ + -e '/faith/d' \ -e '/gzip/d' \ -e '/splash/d' \ - -e '/IPv6/d' \ -e '/PROCFS/d' \ -e '/KTRACE/d' \ -e '/SYSV/d' \ diff --git a/release/sysinstall/config.c b/release/sysinstall/config.c index 503679f..c0320c6 100644 --- a/release/sysinstall/config.c +++ b/release/sysinstall/config.c @@ -677,7 +677,7 @@ int configResolv(dialogMenuItem *ditem) { FILE *fp; - char *cp, *dp, *hp; + char *cp, *c6p, *dp, *hp; cp = variable_get(VAR_NAMESERVER); if (!cp || !*cp) @@ -696,18 +696,25 @@ configResolv(dialogMenuItem *ditem) skip: dp = variable_get(VAR_DOMAINNAME); cp = variable_get(VAR_IPADDR); + c6p = variable_get(VAR_IPV6ADDR); hp = variable_get(VAR_HOSTNAME); /* Tack ourselves into /etc/hosts */ fp = fopen("/etc/hosts", "w"); if (!fp) return DITEM_FAILURE; /* Add an entry for localhost */ + if (!variable_cmp(VAR_IPV6_ENABLE, "YES")) { + if (dp) + fprintf(fp, "::1\t\t\tlocalhost.%s localhost\n", dp); + else + fprintf(fp, "::1\t\t\tlocalhost\n"); + } if (dp) fprintf(fp, "127.0.0.1\t\tlocalhost.%s localhost\n", dp); else fprintf(fp, "127.0.0.1\t\tlocalhost\n"); /* Now the host entries, if applicable */ - if (cp && cp[0] != '0' && hp) { + if (((cp && cp[0] != '0') || (c6p && c6p[0] != '0')) && hp) { char cp2[255]; if (!index(hp, '.')) @@ -716,8 +723,14 @@ skip: SAFE_STRCPY(cp2, hp); *(index(cp2, '.')) = '\0'; } - fprintf(fp, "%s\t\t%s %s\n", cp, hp, cp2); - fprintf(fp, "%s\t\t%s.\n", cp, hp); + if (c6p && c6p[0] != '0') { + fprintf(fp, "%s\t%s %s\n", c6p, hp, cp2); + fprintf(fp, "%s\t%s.\n", c6p, hp); + } + if (cp && cp[0] != '0') { + fprintf(fp, "%s\t\t%s %s\n", cp, hp, cp2); + fprintf(fp, "%s\t\t%s.\n", cp, hp); + } } fclose(fp); if (isDebug()) diff --git a/release/sysinstall/ftp.c b/release/sysinstall/ftp.c index b32f80a..9c0deb8 100644 --- a/release/sysinstall/ftp.c +++ b/release/sysinstall/ftp.c @@ -73,7 +73,7 @@ netDown(Device *dev) Boolean mediaInitFTP(Device *dev) { - int i, code; + int i, code, af; char *cp, *rel, *hostname, *dir; char *user, *login_name, password[80]; @@ -121,8 +121,9 @@ try: user = pw ? pw->pw_name : "ftp"; sprintf(password, "%s@%s", user, variable_get(VAR_HOSTNAME)); } + af = variable_cmp(VAR_IPV6_ENABLE, "YES") ? AF_INET : AF_UNSPEC; msgNotify("Logging in to %s@%s..", login_name, hostname); - if ((OpenConn = ftpLogin(hostname, login_name, password, FtpPort, isDebug(), &code)) == NULL) { + if ((OpenConn = ftpLoginAf(hostname, af, login_name, password, FtpPort, isDebug(), &code)) == NULL) { msgConfirm("Couldn't open FTP connection to %s:\n %s.", hostname, ftpErrString(code)); goto punt; } diff --git a/release/sysinstall/http.c b/release/sysinstall/http.c index 14220bb..1dfcbf5 100644 --- a/release/sysinstall/http.c +++ b/release/sysinstall/http.c @@ -5,8 +5,6 @@ #include <sys/param.h> #include <netdb.h> -int HttpPort; - Boolean mediaInitHTTP(Device *dev) { @@ -19,32 +17,33 @@ mediaInitHTTP(Device *dev) * is reverted in distExtract(). */ - extern int h_errno; - int rv,s; + int rv, s, af; bool el; /* end of header line */ char *cp, buf[PATH_MAX], req[BUFSIZ]; - struct sockaddr_in peer; - struct hostent *peer_in; + struct addrinfo hints, *res, *res0; - s=socket(PF_INET, SOCK_STREAM, 6); /* tcp */ - if (s == -1) { - msgConfirm("Network error"); + af = variable_cmp(VAR_IPV6_ENABLE, "YES") ? AF_INET : AF_UNSPEC; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = af; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = 0; + if ((rv = getaddrinfo(variable_get(VAR_HTTP_HOST), + variable_get(VAR_HTTP_PORT), &hints, &res0)) != 0) { + msgConfirm("%s", gai_strerror(rv)); return FALSE; } - - peer_in=gethostbyname(variable_get(VAR_HTTP_HOST)); - if (peer_in == NULL) { - msgConfirm("%s",hstrerror(h_errno)); - return FALSE; + s = -1; + for (res = res0; res; res = res->ai_next) { + if ((s = socket(res->ai_family, res->ai_socktype, + res->ai_protocol)) < 0) + continue; + if (connect(s, res->ai_addr, res->ai_addrlen) >= 0) + break; + close(s); + s = -1; } - - peer.sin_len=peer_in->h_length; - peer.sin_family=peer_in->h_addrtype; - peer.sin_port=htons((u_short) HttpPort); - bcopy(peer_in->h_addr_list[0], &peer.sin_addr, peer_in->h_length); - - rv=connect(s,(struct sockaddr *)&peer,sizeof(peer)); - if (rv == -1) { + freeaddrinfo(res0); + if (s == -1) { msgConfirm("Couldn't connect to proxy %s:%s", variable_get(VAR_HTTP_HOST),variable_get(VAR_HTTP_PORT)); return FALSE; @@ -94,28 +93,35 @@ FILE * mediaGetHTTP(Device *dev, char *file, Boolean probe) { FILE *fp; - int rv,s; + int rv, s, af; bool el; /* end of header line */ char *cp, buf[PATH_MAX], req[BUFSIZ]; - struct sockaddr_in peer; - struct hostent *peer_in; + struct addrinfo hints, *res, *res0; - s=socket(PF_INET, SOCK_STREAM, 6); /* tcp */ - if (s == -1) { - msgConfirm("Network error"); + af = variable_cmp(VAR_IPV6_ENABLE, "YES") ? AF_INET : AF_UNSPEC; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = af; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = 0; + if ((rv = getaddrinfo(variable_get(VAR_HTTP_HOST), + variable_get(VAR_HTTP_PORT), &hints, &res0)) != 0) { + msgConfirm("%s", gai_strerror(rv)); return NULL; } - - peer_in=gethostbyname(variable_get(VAR_HTTP_HOST)); - peer.sin_len=peer_in->h_length; - peer.sin_family=peer_in->h_addrtype; - peer.sin_port=htons((u_short) HttpPort); - bcopy(peer_in->h_addr_list[0], &peer.sin_addr, peer_in->h_length); - - rv=connect(s,(struct sockaddr *)&peer,sizeof(peer)); - if (rv == -1) { + s = -1; + for (res = res0; res; res = res->ai_next) { + if ((s = socket(res->ai_family, res->ai_socktype, + res->ai_protocol)) < 0) + continue; + if (connect(s, res->ai_addr, res->ai_addrlen) >= 0) + break; + close(s); + s = -1; + } + freeaddrinfo(res0); + if (s == -1) { msgConfirm("Couldn't connect to proxy %s:%s", - variable_get(VAR_HTTP_HOST),variable_get(VAR_FTP_PORT)); + variable_get(VAR_HTTP_HOST),variable_get(VAR_HTTP_PORT)); return NULL; } diff --git a/release/sysinstall/install.c b/release/sysinstall/install.c index 655991d..ac3b013 100644 --- a/release/sysinstall/install.c +++ b/release/sysinstall/install.c @@ -1086,6 +1086,7 @@ installVarDefaults(dialogMenuItem *self) variable_set2(VAR_INSTALL_ROOT, "/", 0); variable_set2(VAR_INSTALL_CFG, "install.cfg", 0); variable_set2(VAR_TRY_DHCP, "NO", 0); /* For now */ + variable_set2(VAR_TRY_RTSOL, "NO", 0); /* For now */ cp = getenv("EDITOR"); if (!cp) cp = "/usr/bin/ee"; diff --git a/release/sysinstall/media.c b/release/sysinstall/media.c index 9be0b5b..320efc2 100644 --- a/release/sysinstall/media.c +++ b/release/sysinstall/media.c @@ -313,7 +313,9 @@ int mediaSetFTP(dialogMenuItem *self) { static Device ftpDevice; - char *cp, hostname[MAXHOSTNAMELEN], *dir; + char *cp, hbuf[MAXHOSTNAMELEN], *hostname, *dir; + struct addrinfo hints, *res; + int af; extern int FtpPort; static Device *networkDev = NULL; @@ -352,7 +354,8 @@ mediaSetFTP(dialogMenuItem *self) return DITEM_FAILURE; } SAFE_STRCPY(ftpDevice.name, cp); - SAFE_STRCPY(hostname, cp + 6); + SAFE_STRCPY(hbuf, cp + 6); + hostname = hbuf; if (!networkDev || msgYesNo("You've already done the network configuration once,\n" "would you like to skip over it now?") != 0) { @@ -369,7 +372,14 @@ mediaSetFTP(dialogMenuItem *self) variable_unset(VAR_FTP_PATH); return DITEM_FAILURE; } - if ((cp = index(hostname, ':')) != NULL) { + if (*hostname == '[' && (cp = index(hostname + 1, ']')) != NULL && + (*++cp == '\0' || *cp == '/' || *cp == ':')) { + ++hostname; + *(cp - 1) = '\0'; + } + else + cp = index(hostname, ':'); + if (cp != NULL && *cp == ':') { *(cp++) = '\0'; FtpPort = strtol(cp, 0, 0); } @@ -388,12 +398,18 @@ mediaSetFTP(dialogMenuItem *self) msgDebug("Starting DNS.\n"); kickstart_dns(); if (isDebug()) - msgDebug("Looking up hostname, %s, using inet_addr().\n", hostname); - if (inet_addr(hostname) == INADDR_NONE) { - if (isDebug()) - msgDebug("Looking up hostname, %s, using gethostbyname().\n", - hostname); - if (gethostbyname(hostname) == NULL) { + msgDebug("Looking up hostname, %s, using getaddrinfo(AI_NUMERICHOST).\n", hostname); + af = variable_cmp(VAR_IPV6_ENABLE, "YES") ? AF_INET : AF_UNSPEC; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = af; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; + if (getaddrinfo(hostname, NULL, &hints, &res) != 0) { + if (isDebug()) + msgDebug("Looking up hostname, %s, using getaddrinfo().\n", + hostname); + hints.ai_flags = AI_PASSIVE; + if (getaddrinfo(hostname, NULL, &hints, &res) != 0) { msgConfirm("Cannot resolve hostname `%s'! Are you sure that" " your\nname server, gateway and network interface are" " correctly configured?", hostname); @@ -404,6 +420,7 @@ mediaSetFTP(dialogMenuItem *self) return DITEM_FAILURE; } } + freeaddrinfo(res); if (isDebug()) msgDebug("Found DNS entry for %s successfully..\n", hostname); } @@ -436,8 +453,8 @@ mediaSetFTPPassive(dialogMenuItem *self) int mediaSetHTTP(dialogMenuItem *self) { int result; - char *cp, *idx, hostname[MAXHOSTNAMELEN], *var_hostname; - extern int HttpPort; + char *cp, *idx, hbuf[MAXHOSTNAMELEN], *hostname, *var_hostname; + int HttpPort; int what = DITEM_RESTORE; @@ -454,8 +471,15 @@ int mediaSetHTTP(dialogMenuItem *self) " hostname:port (the ':port' is optional, default is 3128)",0); if (!cp) return DITEM_FAILURE; - SAFE_STRCPY(hostname, cp); - if (!(idx = index(hostname, ':'))) + SAFE_STRCPY(hbuf, cp); + hostname = hbuf; + if (*hostname == '[' && (idx = index(hostname + 1, ']')) != NULL && + (*++idx == '\0' || *idx == ':')) { + ++hostname; + *(idx - 1) = '\0'; + } else + idx = index(hostname, ':'); + if (idx == NULL || *cp != ':') HttpPort = 3128; /* try this as default */ else { *(idx++) = '\0'; diff --git a/release/sysinstall/menus.c b/release/sysinstall/menus.c index 7c8c984..15f51fb 100644 --- a/release/sysinstall/menus.c +++ b/release/sysinstall/menus.c @@ -553,6 +553,8 @@ DMenu MenuMediaFTP = { VAR_FTP_PATH _AS("=ftp://current.freebsd.org/pub/FreeBSD/snapshots/") }, { " 4.0 SNAP Server", "releng4.freebsd.org", NULL, dmenuSetVariable, NULL, VAR_FTP_PATH _AS("=ftp://releng4.freebsd.org/pub/FreeBSD/snapshots/") }, + { " IPv6 Ready", "ftp7.jp.freebsd.org", NULL, dmenuSetVariable, NULL, + VAR_FTP_PATH _AP("=ftp://ftp7.jp.freebsd.org") }, { "Argentina", "ftp.ar.freebsd.org", NULL, dmenuSetVariable, NULL, VAR_FTP_PATH _AP("=ftp://ftp.ar.freebsd.org") }, { " Australia", "ftp.au.freebsd.org", NULL, dmenuSetVariable, NULL, @@ -639,6 +641,8 @@ DMenu MenuMediaFTP = { VAR_FTP_PATH _AP("=ftp://ftp5.jp.freebsd.org") }, { " Japan #6", "ftp6.jp.freebsd.org", NULL, dmenuSetVariable, NULL, VAR_FTP_PATH _AP("=ftp://ftp6.jp.freebsd.org") }, + { " Japan #7", "ftp7.jp.freebsd.org", NULL, dmenuSetVariable, NULL, + VAR_FTP_PATH _AP("=ftp://ftp7.jp.freebsd.org") }, { "Korea", "ftp.kr.freebsd.org", NULL, dmenuSetVariable, NULL, VAR_FTP_PATH _AP("=ftp://ftp.kr.freebsd.org") }, { " Korea #2", "ftp2.kr.freebsd.org", NULL, dmenuSetVariable, NULL, diff --git a/release/sysinstall/network.c b/release/sysinstall/network.c index 81296e4..a48b066 100644 --- a/release/sysinstall/network.c +++ b/release/sysinstall/network.c @@ -125,31 +125,32 @@ mediaInitNetwork(Device *dev) snprintf(ifconfig, 255, "%s%s", VAR_IFCONFIG, dev->name); cp = variable_get(ifconfig); - if (!cp) { + if (cp) { + if (strcmp(cp, "DHCP")) { + msgDebug("ifconfig %s %s", dev->name, cp); + i = vsystem("ifconfig %s %s", dev->name, cp); + if (i) { + msgConfirm("Unable to configure the %s interface!\n" + "This installation method cannot be used.", + dev->name); + return FALSE; + } + rp = variable_get(VAR_GATEWAY); + if (!rp || *rp == '0') { + msgConfirm("No gateway has been set. You may be unable to access hosts\n" + "not on your local network"); + } + else { + msgDebug("Adding default route to %s.", rp); + vsystem("route -n add default %s", rp); + } + } + } else if ((cp = variable_get(VAR_IPV6ADDR)) == NULL || *cp == '\0') { msgConfirm("The %s device is not configured. You will need to do so\n" "in the Networking configuration menu before proceeding.", dev->name); return FALSE; } - else if (!strcmp(cp, "DHCP")) - goto bail; - msgDebug("ifconfig %s %s", dev->name, cp); - i = vsystem("ifconfig %s %s", dev->name, cp); - if (i) { - msgConfirm("Unable to configure the %s interface!\n" - "This installation method cannot be used.", dev->name); - return FALSE; - } - rp = variable_get(VAR_GATEWAY); - if (!rp || *rp == '0') { - msgConfirm("No gateway has been set. You may be unable to access hosts\n" - "not on your local network"); - } - else { - msgDebug("Adding default route to %s.", rp); - vsystem("route -n add default %s", rp); - } -bail: if (isDebug()) msgDebug("Network initialized successfully.\n"); networkInitialized = TRUE; diff --git a/release/sysinstall/options.c b/release/sysinstall/options.c index b6fed23..ae640f6 100644 --- a/release/sysinstall/options.c +++ b/release/sysinstall/options.c @@ -118,6 +118,8 @@ static Option Options[] = { OPT_IS_VAR, NULL, VAR_NO_CONFIRM, varCheck }, { "DHCP", "Attempt automatic DHCP configuration of interfaces", OPT_IS_VAR, NULL, VAR_TRY_DHCP, varCheck }, +{ "IPv6", "Attempt IPv6 configuration of interfaces", + OPT_IS_VAR, NULL, VAR_TRY_RTSOL, varCheck }, { "FTP username", "Username and password to use instead of anonymous", OPT_IS_FUNC, mediaSetFTPUserPass, VAR_FTP_USER, varCheck }, { "Editor", "Which text editor to use during installation", diff --git a/release/sysinstall/sysinstall.h b/release/sysinstall/sysinstall.h index 0563473..e34735a 100644 --- a/release/sysinstall/sysinstall.h +++ b/release/sysinstall/sysinstall.h @@ -123,6 +123,8 @@ #define VAR_INSTALL_CFG "installConfig" #define VAR_INSTALL_ROOT "installRoot" #define VAR_IPADDR "ipaddr" +#define VAR_IPV6_ENABLE "ipv6_enable" +#define VAR_IPV6ADDR "ipv6addr" #define VAR_KEYMAP "keymap" #define VAR_KGET "kget" #define VAR_LABEL "label" @@ -167,6 +169,7 @@ #define VAR_SWAP_SIZE "swapSize" #define VAR_TAPE_BLOCKSIZE "tapeBlocksize" #define VAR_TRY_DHCP "tryDHCP" +#define VAR_TRY_RTSOL "tryRTSOL" #define VAR_UFS_PATH "ufs" #define VAR_USR_SIZE "usrSize" #define VAR_VAR_SIZE "varSize" @@ -327,6 +330,7 @@ typedef int (*commandFunc)(char *key, void *data); /* This is the structure that Network devices carry around in their private, erm, structures */ typedef struct _devPriv { + int use_rtsol; int use_dhcp; char ipaddr[IPADDR_FIELD_LEN]; char netmask[IPADDR_FIELD_LEN]; diff --git a/release/sysinstall/tcpip.c b/release/sysinstall/tcpip.c index 18e9287..3a946f94 100644 --- a/release/sysinstall/tcpip.c +++ b/release/sysinstall/tcpip.c @@ -39,6 +39,9 @@ #include "sysinstall.h" #include <sys/param.h> +#include <sys/sysctl.h> +#include <sys/socket.h> +#include <netinet/in.h> #include <netdb.h> /* The help file for the TCP/IP setup screen */ @@ -47,9 +50,10 @@ /* These are nasty, but they make the layout structure a lot easier ... */ static char hostname[HOSTNAME_FIELD_LEN], domainname[HOSTNAME_FIELD_LEN], - gateway[IPADDR_FIELD_LEN], nameserver[IPADDR_FIELD_LEN]; + gateway[IPADDR_FIELD_LEN], nameserver[INET6_ADDRSTRLEN]; static int okbutton, cancelbutton; static char ipaddr[IPADDR_FIELD_LEN], netmask[IPADDR_FIELD_LEN], extras[EXTRAS_FIELD_LEN]; +static char ipv6addr[INET6_ADDRSTRLEN]; /* What the screen size is meant to be */ #define TCP_DIALOG_Y 0 @@ -69,17 +73,17 @@ static Layout layout[] = { domainname, STRINGOBJ, NULL }, #define LAYOUT_GATEWAY 2 { 5, 2, 18, IPADDR_FIELD_LEN - 1, - "Gateway:", - "IP address of host forwarding packets to non-local destinations", + "IPv4 Gateway:", + "IPv4 address of host forwarding packets to non-local destinations", gateway, STRINGOBJ, NULL }, #define LAYOUT_NAMESERVER 3 - { 5, 35, 18, IPADDR_FIELD_LEN - 1, - "Name server:", "IP address of your local DNS server", + { 5, 35, 18, INET6_ADDRSTRLEN - 1, + "Name server:", "IPv4 or IPv6 address of your local DNS server", nameserver, STRINGOBJ, NULL }, #define LAYOUT_IPADDR 4 { 10, 10, 18, IPADDR_FIELD_LEN - 1, - "IP Address:", - "The IP address to be used for this interface", + "IPv4 Address:", + "The IPv4 address to be used for this interface", ipaddr, STRINGOBJ, NULL }, #define LAYOUT_NETMASK 5 { 10, 35, 18, IPADDR_FIELD_LEN - 1, @@ -126,6 +130,22 @@ verifyIP(char *ip) return 0; } +static int +verifyIP6(char *ip) +{ + struct addrinfo hints, *res; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET6; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; + if (getaddrinfo(ip, NULL, &hints, &res) == 0) { + freeaddrinfo(res); + return 1; + } + return 0; +} + /* Check for the settings on the screen - the per-interface stuff is moved to the main handling code now to do it on the fly - sigh */ static int @@ -134,13 +154,13 @@ verifySettings(void) if (!hostname[0]) feepout("Must specify a host name of some sort!"); else if (gateway[0] && strcmp(gateway, "NO") && !verifyIP(gateway)) - feepout("Invalid gateway IP address specified"); - else if (nameserver[0] && !verifyIP(nameserver)) + feepout("Invalid gateway IPv4 address specified"); + else if (nameserver[0] && !verifyIP(nameserver) && !verifyIP6(nameserver)) feepout("Invalid name server IP address specified"); else if (netmask[0] && (netmask[0] < '0' && netmask[0] > '3')) feepout("Invalid netmask value"); else if (ipaddr[0] && !verifyIP(ipaddr)) - feepout("Invalid IP address"); + feepout("Invalid IPv4 address"); else return 1; return 0; @@ -169,7 +189,7 @@ dhcpGetInfo(Device *devp) msgDebug("DHCP configured interface returns %s\n", data); /* XXX This is gross as it assumes a certain ordering to ifconfig's output! XXX */ - if ((cp = strstr(data, "inet")) != NULL) { + if ((cp = strstr(data, "inet ")) != NULL) { i = 0; cp += 5; /* move over keyword */ while (*cp != ' ') @@ -193,6 +213,32 @@ dhcpGetInfo(Device *devp) variable_set2(VAR_HOSTNAME, hostname, 0); } +static void +rtsolGetInfo(Device *devp) +{ + FILE *ifp; + char *cp, cmd[256], data[2048]; + int i; + + snprintf(cmd, sizeof cmd, "ifconfig %s", devp->name); + if ((ifp = popen(cmd, "r")) == NULL) + return; + while (fgets(data, sizeof(data), ifp) != NULL) { + if (isDebug()) + msgDebug("RTSOL configured interface returns %s", data); + if ((cp = strstr(data, "inet6 ")) != NULL) { + cp += 6; /* move over keyword */ + if (strncmp(cp, "fe80:", 5)) { + i = 0; + while (*cp != ' ') + ipv6addr[i++] = *(cp++); + ipv6addr[i] = '\0'; + } + } + } + fclose(ifp); +} + /* This is it - how to get TCP setup values */ int tcpOpenDialog(Device *devp) @@ -202,6 +248,7 @@ tcpOpenDialog(Device *devp) int n = 0, filled = 0, cancel = FALSE; int max, ret = DITEM_SUCCESS; int use_dhcp = FALSE; + int use_rtsol = FALSE; char *tmp; char title[80]; @@ -214,10 +261,30 @@ tcpOpenDialog(Device *devp) SAFE_STRCPY(netmask, di->netmask); SAFE_STRCPY(extras, di->extras); use_dhcp = di->use_dhcp; + use_rtsol = di->use_rtsol; } else { /* See if there are any defaults */ char *cp; + /* Try a RTSOL scan if such behavior is desired */ + if (!variable_cmp(VAR_TRY_RTSOL, "YES") || !msgYesNo("Do you want to try IPv6 configuration of the interface?")) { + int i; + + i = 0; + sysctlbyname("net.inet6.ip6.forwarding", NULL, 0, &i, sizeof(i)); + i = 1; + sysctlbyname("net.inet6.ip6.accept_rtadv", NULL, 0, &i, sizeof(i)); + vsystem("ifconfig %s up", devp->name); + Mkdir("/var/run"); + msgNotify("Scanning for RA servers..."); + if (0 == vsystem("rtsol %s", devp->name)) { + sleep(3); + rtsolGetInfo(devp); + use_rtsol = TRUE; + } else + use_rtsol = FALSE; + } + /* First try a DHCP scan if such behavior is desired */ if (!variable_cmp(VAR_TRY_DHCP, "YES") || !msgYesNo("Do you want to try DHCP configuration of the interface?")) { Mkdir("/var/db"); @@ -298,7 +365,10 @@ tcpOpenDialog(Device *devp) dialog_clear_norefresh(); /* We need a curses window */ - if (!(ds_win = openLayoutDialog(TCP_HELPFILE, " Network Configuration ", + tmp = " Network Configuration "; + if (ipv6addr[0]) + tmp = string_concat(tmp, "(IPv6 ready) "); + if (!(ds_win = openLayoutDialog(TCP_HELPFILE, tmp, TCP_DIALOG_X, TCP_DIALOG_Y, TCP_DIALOG_WIDTH, TCP_DIALOG_HEIGHT))) { beep(); msgConfirm("Cannot open TCP/IP dialog window!!"); @@ -361,6 +431,7 @@ netconfig: char temp[512], ifn[255]; char *ifaces; char *pccard; + int ipv4_enable = FALSE; if (hostname[0]) { variable_set2(VAR_HOSTNAME, hostname, 1); @@ -374,6 +445,8 @@ netconfig: variable_set2(VAR_NAMESERVER, nameserver, 0); if (ipaddr[0]) variable_set2(VAR_IPADDR, ipaddr, 0); + if (ipv6addr[0]) + variable_set2(VAR_IPV6ADDR, ipv6addr, 0); if (!devp->private) devp->private = (DevInfo *)safe_malloc(sizeof(DevInfo)); @@ -382,15 +455,21 @@ netconfig: SAFE_STRCPY(di->netmask, netmask); SAFE_STRCPY(di->extras, extras); di->use_dhcp = use_dhcp; - - sprintf(ifn, "%s%s", VAR_IFCONFIG, devp->name); - if (use_dhcp) - sprintf(temp, "DHCP"); - else - sprintf(temp, "inet %s %s netmask %s", ipaddr, extras, netmask); - variable_set2(ifn, temp, 1); + di->use_rtsol = use_rtsol; + + if (use_dhcp || ipaddr[0]) + ipv4_enable = TRUE; + if (ipv4_enable) { + sprintf(ifn, "%s%s", VAR_IFCONFIG, devp->name); + if (use_dhcp) + sprintf(temp, "DHCP"); + else + sprintf(temp, "inet %s %s netmask %s", + ipaddr, extras, netmask); + variable_set2(ifn, temp, 1); + } pccard = variable_get("_pccard_install"); - if (pccard && strcmp(pccard, "YES") == 0) { + if (pccard && strcmp(pccard, "YES") == 0 && ipv4_enable) { variable_set2("pccard_ifconfig", temp, 1); } ifaces = variable_get(VAR_INTERFACES); @@ -401,6 +480,8 @@ netconfig: sprintf(ifn, "%s %s", devp->name, ifaces); variable_set2(VAR_INTERFACES, ifn, 1); } + if (use_rtsol) + variable_set2(VAR_IPV6_ENABLE, "YES", 1); if (!use_dhcp) configResolv(NULL); /* XXX this will do it on the MFS copy XXX */ ret = DITEM_SUCCESS; diff --git a/usr.sbin/sade/config.c b/usr.sbin/sade/config.c index 503679f..c0320c6 100644 --- a/usr.sbin/sade/config.c +++ b/usr.sbin/sade/config.c @@ -677,7 +677,7 @@ int configResolv(dialogMenuItem *ditem) { FILE *fp; - char *cp, *dp, *hp; + char *cp, *c6p, *dp, *hp; cp = variable_get(VAR_NAMESERVER); if (!cp || !*cp) @@ -696,18 +696,25 @@ configResolv(dialogMenuItem *ditem) skip: dp = variable_get(VAR_DOMAINNAME); cp = variable_get(VAR_IPADDR); + c6p = variable_get(VAR_IPV6ADDR); hp = variable_get(VAR_HOSTNAME); /* Tack ourselves into /etc/hosts */ fp = fopen("/etc/hosts", "w"); if (!fp) return DITEM_FAILURE; /* Add an entry for localhost */ + if (!variable_cmp(VAR_IPV6_ENABLE, "YES")) { + if (dp) + fprintf(fp, "::1\t\t\tlocalhost.%s localhost\n", dp); + else + fprintf(fp, "::1\t\t\tlocalhost\n"); + } if (dp) fprintf(fp, "127.0.0.1\t\tlocalhost.%s localhost\n", dp); else fprintf(fp, "127.0.0.1\t\tlocalhost\n"); /* Now the host entries, if applicable */ - if (cp && cp[0] != '0' && hp) { + if (((cp && cp[0] != '0') || (c6p && c6p[0] != '0')) && hp) { char cp2[255]; if (!index(hp, '.')) @@ -716,8 +723,14 @@ skip: SAFE_STRCPY(cp2, hp); *(index(cp2, '.')) = '\0'; } - fprintf(fp, "%s\t\t%s %s\n", cp, hp, cp2); - fprintf(fp, "%s\t\t%s.\n", cp, hp); + if (c6p && c6p[0] != '0') { + fprintf(fp, "%s\t%s %s\n", c6p, hp, cp2); + fprintf(fp, "%s\t%s.\n", c6p, hp); + } + if (cp && cp[0] != '0') { + fprintf(fp, "%s\t\t%s %s\n", cp, hp, cp2); + fprintf(fp, "%s\t\t%s.\n", cp, hp); + } } fclose(fp); if (isDebug()) diff --git a/usr.sbin/sade/install.c b/usr.sbin/sade/install.c index 655991d..ac3b013 100644 --- a/usr.sbin/sade/install.c +++ b/usr.sbin/sade/install.c @@ -1086,6 +1086,7 @@ installVarDefaults(dialogMenuItem *self) variable_set2(VAR_INSTALL_ROOT, "/", 0); variable_set2(VAR_INSTALL_CFG, "install.cfg", 0); variable_set2(VAR_TRY_DHCP, "NO", 0); /* For now */ + variable_set2(VAR_TRY_RTSOL, "NO", 0); /* For now */ cp = getenv("EDITOR"); if (!cp) cp = "/usr/bin/ee"; diff --git a/usr.sbin/sade/menus.c b/usr.sbin/sade/menus.c index 7c8c984..15f51fb 100644 --- a/usr.sbin/sade/menus.c +++ b/usr.sbin/sade/menus.c @@ -553,6 +553,8 @@ DMenu MenuMediaFTP = { VAR_FTP_PATH _AS("=ftp://current.freebsd.org/pub/FreeBSD/snapshots/") }, { " 4.0 SNAP Server", "releng4.freebsd.org", NULL, dmenuSetVariable, NULL, VAR_FTP_PATH _AS("=ftp://releng4.freebsd.org/pub/FreeBSD/snapshots/") }, + { " IPv6 Ready", "ftp7.jp.freebsd.org", NULL, dmenuSetVariable, NULL, + VAR_FTP_PATH _AP("=ftp://ftp7.jp.freebsd.org") }, { "Argentina", "ftp.ar.freebsd.org", NULL, dmenuSetVariable, NULL, VAR_FTP_PATH _AP("=ftp://ftp.ar.freebsd.org") }, { " Australia", "ftp.au.freebsd.org", NULL, dmenuSetVariable, NULL, @@ -639,6 +641,8 @@ DMenu MenuMediaFTP = { VAR_FTP_PATH _AP("=ftp://ftp5.jp.freebsd.org") }, { " Japan #6", "ftp6.jp.freebsd.org", NULL, dmenuSetVariable, NULL, VAR_FTP_PATH _AP("=ftp://ftp6.jp.freebsd.org") }, + { " Japan #7", "ftp7.jp.freebsd.org", NULL, dmenuSetVariable, NULL, + VAR_FTP_PATH _AP("=ftp://ftp7.jp.freebsd.org") }, { "Korea", "ftp.kr.freebsd.org", NULL, dmenuSetVariable, NULL, VAR_FTP_PATH _AP("=ftp://ftp.kr.freebsd.org") }, { " Korea #2", "ftp2.kr.freebsd.org", NULL, dmenuSetVariable, NULL, diff --git a/usr.sbin/sade/sade.h b/usr.sbin/sade/sade.h index 0563473..e34735a 100644 --- a/usr.sbin/sade/sade.h +++ b/usr.sbin/sade/sade.h @@ -123,6 +123,8 @@ #define VAR_INSTALL_CFG "installConfig" #define VAR_INSTALL_ROOT "installRoot" #define VAR_IPADDR "ipaddr" +#define VAR_IPV6_ENABLE "ipv6_enable" +#define VAR_IPV6ADDR "ipv6addr" #define VAR_KEYMAP "keymap" #define VAR_KGET "kget" #define VAR_LABEL "label" @@ -167,6 +169,7 @@ #define VAR_SWAP_SIZE "swapSize" #define VAR_TAPE_BLOCKSIZE "tapeBlocksize" #define VAR_TRY_DHCP "tryDHCP" +#define VAR_TRY_RTSOL "tryRTSOL" #define VAR_UFS_PATH "ufs" #define VAR_USR_SIZE "usrSize" #define VAR_VAR_SIZE "varSize" @@ -327,6 +330,7 @@ typedef int (*commandFunc)(char *key, void *data); /* This is the structure that Network devices carry around in their private, erm, structures */ typedef struct _devPriv { + int use_rtsol; int use_dhcp; char ipaddr[IPADDR_FIELD_LEN]; char netmask[IPADDR_FIELD_LEN]; diff --git a/usr.sbin/sysinstall/config.c b/usr.sbin/sysinstall/config.c index 503679f..c0320c6 100644 --- a/usr.sbin/sysinstall/config.c +++ b/usr.sbin/sysinstall/config.c @@ -677,7 +677,7 @@ int configResolv(dialogMenuItem *ditem) { FILE *fp; - char *cp, *dp, *hp; + char *cp, *c6p, *dp, *hp; cp = variable_get(VAR_NAMESERVER); if (!cp || !*cp) @@ -696,18 +696,25 @@ configResolv(dialogMenuItem *ditem) skip: dp = variable_get(VAR_DOMAINNAME); cp = variable_get(VAR_IPADDR); + c6p = variable_get(VAR_IPV6ADDR); hp = variable_get(VAR_HOSTNAME); /* Tack ourselves into /etc/hosts */ fp = fopen("/etc/hosts", "w"); if (!fp) return DITEM_FAILURE; /* Add an entry for localhost */ + if (!variable_cmp(VAR_IPV6_ENABLE, "YES")) { + if (dp) + fprintf(fp, "::1\t\t\tlocalhost.%s localhost\n", dp); + else + fprintf(fp, "::1\t\t\tlocalhost\n"); + } if (dp) fprintf(fp, "127.0.0.1\t\tlocalhost.%s localhost\n", dp); else fprintf(fp, "127.0.0.1\t\tlocalhost\n"); /* Now the host entries, if applicable */ - if (cp && cp[0] != '0' && hp) { + if (((cp && cp[0] != '0') || (c6p && c6p[0] != '0')) && hp) { char cp2[255]; if (!index(hp, '.')) @@ -716,8 +723,14 @@ skip: SAFE_STRCPY(cp2, hp); *(index(cp2, '.')) = '\0'; } - fprintf(fp, "%s\t\t%s %s\n", cp, hp, cp2); - fprintf(fp, "%s\t\t%s.\n", cp, hp); + if (c6p && c6p[0] != '0') { + fprintf(fp, "%s\t%s %s\n", c6p, hp, cp2); + fprintf(fp, "%s\t%s.\n", c6p, hp); + } + if (cp && cp[0] != '0') { + fprintf(fp, "%s\t\t%s %s\n", cp, hp, cp2); + fprintf(fp, "%s\t\t%s.\n", cp, hp); + } } fclose(fp); if (isDebug()) diff --git a/usr.sbin/sysinstall/ftp.c b/usr.sbin/sysinstall/ftp.c index b32f80a..9c0deb8 100644 --- a/usr.sbin/sysinstall/ftp.c +++ b/usr.sbin/sysinstall/ftp.c @@ -73,7 +73,7 @@ netDown(Device *dev) Boolean mediaInitFTP(Device *dev) { - int i, code; + int i, code, af; char *cp, *rel, *hostname, *dir; char *user, *login_name, password[80]; @@ -121,8 +121,9 @@ try: user = pw ? pw->pw_name : "ftp"; sprintf(password, "%s@%s", user, variable_get(VAR_HOSTNAME)); } + af = variable_cmp(VAR_IPV6_ENABLE, "YES") ? AF_INET : AF_UNSPEC; msgNotify("Logging in to %s@%s..", login_name, hostname); - if ((OpenConn = ftpLogin(hostname, login_name, password, FtpPort, isDebug(), &code)) == NULL) { + if ((OpenConn = ftpLoginAf(hostname, af, login_name, password, FtpPort, isDebug(), &code)) == NULL) { msgConfirm("Couldn't open FTP connection to %s:\n %s.", hostname, ftpErrString(code)); goto punt; } diff --git a/usr.sbin/sysinstall/http.c b/usr.sbin/sysinstall/http.c index 14220bb..1dfcbf5 100644 --- a/usr.sbin/sysinstall/http.c +++ b/usr.sbin/sysinstall/http.c @@ -5,8 +5,6 @@ #include <sys/param.h> #include <netdb.h> -int HttpPort; - Boolean mediaInitHTTP(Device *dev) { @@ -19,32 +17,33 @@ mediaInitHTTP(Device *dev) * is reverted in distExtract(). */ - extern int h_errno; - int rv,s; + int rv, s, af; bool el; /* end of header line */ char *cp, buf[PATH_MAX], req[BUFSIZ]; - struct sockaddr_in peer; - struct hostent *peer_in; + struct addrinfo hints, *res, *res0; - s=socket(PF_INET, SOCK_STREAM, 6); /* tcp */ - if (s == -1) { - msgConfirm("Network error"); + af = variable_cmp(VAR_IPV6_ENABLE, "YES") ? AF_INET : AF_UNSPEC; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = af; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = 0; + if ((rv = getaddrinfo(variable_get(VAR_HTTP_HOST), + variable_get(VAR_HTTP_PORT), &hints, &res0)) != 0) { + msgConfirm("%s", gai_strerror(rv)); return FALSE; } - - peer_in=gethostbyname(variable_get(VAR_HTTP_HOST)); - if (peer_in == NULL) { - msgConfirm("%s",hstrerror(h_errno)); - return FALSE; + s = -1; + for (res = res0; res; res = res->ai_next) { + if ((s = socket(res->ai_family, res->ai_socktype, + res->ai_protocol)) < 0) + continue; + if (connect(s, res->ai_addr, res->ai_addrlen) >= 0) + break; + close(s); + s = -1; } - - peer.sin_len=peer_in->h_length; - peer.sin_family=peer_in->h_addrtype; - peer.sin_port=htons((u_short) HttpPort); - bcopy(peer_in->h_addr_list[0], &peer.sin_addr, peer_in->h_length); - - rv=connect(s,(struct sockaddr *)&peer,sizeof(peer)); - if (rv == -1) { + freeaddrinfo(res0); + if (s == -1) { msgConfirm("Couldn't connect to proxy %s:%s", variable_get(VAR_HTTP_HOST),variable_get(VAR_HTTP_PORT)); return FALSE; @@ -94,28 +93,35 @@ FILE * mediaGetHTTP(Device *dev, char *file, Boolean probe) { FILE *fp; - int rv,s; + int rv, s, af; bool el; /* end of header line */ char *cp, buf[PATH_MAX], req[BUFSIZ]; - struct sockaddr_in peer; - struct hostent *peer_in; + struct addrinfo hints, *res, *res0; - s=socket(PF_INET, SOCK_STREAM, 6); /* tcp */ - if (s == -1) { - msgConfirm("Network error"); + af = variable_cmp(VAR_IPV6_ENABLE, "YES") ? AF_INET : AF_UNSPEC; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = af; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = 0; + if ((rv = getaddrinfo(variable_get(VAR_HTTP_HOST), + variable_get(VAR_HTTP_PORT), &hints, &res0)) != 0) { + msgConfirm("%s", gai_strerror(rv)); return NULL; } - - peer_in=gethostbyname(variable_get(VAR_HTTP_HOST)); - peer.sin_len=peer_in->h_length; - peer.sin_family=peer_in->h_addrtype; - peer.sin_port=htons((u_short) HttpPort); - bcopy(peer_in->h_addr_list[0], &peer.sin_addr, peer_in->h_length); - - rv=connect(s,(struct sockaddr *)&peer,sizeof(peer)); - if (rv == -1) { + s = -1; + for (res = res0; res; res = res->ai_next) { + if ((s = socket(res->ai_family, res->ai_socktype, + res->ai_protocol)) < 0) + continue; + if (connect(s, res->ai_addr, res->ai_addrlen) >= 0) + break; + close(s); + s = -1; + } + freeaddrinfo(res0); + if (s == -1) { msgConfirm("Couldn't connect to proxy %s:%s", - variable_get(VAR_HTTP_HOST),variable_get(VAR_FTP_PORT)); + variable_get(VAR_HTTP_HOST),variable_get(VAR_HTTP_PORT)); return NULL; } diff --git a/usr.sbin/sysinstall/install.c b/usr.sbin/sysinstall/install.c index 655991d..ac3b013 100644 --- a/usr.sbin/sysinstall/install.c +++ b/usr.sbin/sysinstall/install.c @@ -1086,6 +1086,7 @@ installVarDefaults(dialogMenuItem *self) variable_set2(VAR_INSTALL_ROOT, "/", 0); variable_set2(VAR_INSTALL_CFG, "install.cfg", 0); variable_set2(VAR_TRY_DHCP, "NO", 0); /* For now */ + variable_set2(VAR_TRY_RTSOL, "NO", 0); /* For now */ cp = getenv("EDITOR"); if (!cp) cp = "/usr/bin/ee"; diff --git a/usr.sbin/sysinstall/media.c b/usr.sbin/sysinstall/media.c index 9be0b5b..320efc2 100644 --- a/usr.sbin/sysinstall/media.c +++ b/usr.sbin/sysinstall/media.c @@ -313,7 +313,9 @@ int mediaSetFTP(dialogMenuItem *self) { static Device ftpDevice; - char *cp, hostname[MAXHOSTNAMELEN], *dir; + char *cp, hbuf[MAXHOSTNAMELEN], *hostname, *dir; + struct addrinfo hints, *res; + int af; extern int FtpPort; static Device *networkDev = NULL; @@ -352,7 +354,8 @@ mediaSetFTP(dialogMenuItem *self) return DITEM_FAILURE; } SAFE_STRCPY(ftpDevice.name, cp); - SAFE_STRCPY(hostname, cp + 6); + SAFE_STRCPY(hbuf, cp + 6); + hostname = hbuf; if (!networkDev || msgYesNo("You've already done the network configuration once,\n" "would you like to skip over it now?") != 0) { @@ -369,7 +372,14 @@ mediaSetFTP(dialogMenuItem *self) variable_unset(VAR_FTP_PATH); return DITEM_FAILURE; } - if ((cp = index(hostname, ':')) != NULL) { + if (*hostname == '[' && (cp = index(hostname + 1, ']')) != NULL && + (*++cp == '\0' || *cp == '/' || *cp == ':')) { + ++hostname; + *(cp - 1) = '\0'; + } + else + cp = index(hostname, ':'); + if (cp != NULL && *cp == ':') { *(cp++) = '\0'; FtpPort = strtol(cp, 0, 0); } @@ -388,12 +398,18 @@ mediaSetFTP(dialogMenuItem *self) msgDebug("Starting DNS.\n"); kickstart_dns(); if (isDebug()) - msgDebug("Looking up hostname, %s, using inet_addr().\n", hostname); - if (inet_addr(hostname) == INADDR_NONE) { - if (isDebug()) - msgDebug("Looking up hostname, %s, using gethostbyname().\n", - hostname); - if (gethostbyname(hostname) == NULL) { + msgDebug("Looking up hostname, %s, using getaddrinfo(AI_NUMERICHOST).\n", hostname); + af = variable_cmp(VAR_IPV6_ENABLE, "YES") ? AF_INET : AF_UNSPEC; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = af; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; + if (getaddrinfo(hostname, NULL, &hints, &res) != 0) { + if (isDebug()) + msgDebug("Looking up hostname, %s, using getaddrinfo().\n", + hostname); + hints.ai_flags = AI_PASSIVE; + if (getaddrinfo(hostname, NULL, &hints, &res) != 0) { msgConfirm("Cannot resolve hostname `%s'! Are you sure that" " your\nname server, gateway and network interface are" " correctly configured?", hostname); @@ -404,6 +420,7 @@ mediaSetFTP(dialogMenuItem *self) return DITEM_FAILURE; } } + freeaddrinfo(res); if (isDebug()) msgDebug("Found DNS entry for %s successfully..\n", hostname); } @@ -436,8 +453,8 @@ mediaSetFTPPassive(dialogMenuItem *self) int mediaSetHTTP(dialogMenuItem *self) { int result; - char *cp, *idx, hostname[MAXHOSTNAMELEN], *var_hostname; - extern int HttpPort; + char *cp, *idx, hbuf[MAXHOSTNAMELEN], *hostname, *var_hostname; + int HttpPort; int what = DITEM_RESTORE; @@ -454,8 +471,15 @@ int mediaSetHTTP(dialogMenuItem *self) " hostname:port (the ':port' is optional, default is 3128)",0); if (!cp) return DITEM_FAILURE; - SAFE_STRCPY(hostname, cp); - if (!(idx = index(hostname, ':'))) + SAFE_STRCPY(hbuf, cp); + hostname = hbuf; + if (*hostname == '[' && (idx = index(hostname + 1, ']')) != NULL && + (*++idx == '\0' || *idx == ':')) { + ++hostname; + *(idx - 1) = '\0'; + } else + idx = index(hostname, ':'); + if (idx == NULL || *cp != ':') HttpPort = 3128; /* try this as default */ else { *(idx++) = '\0'; diff --git a/usr.sbin/sysinstall/menus.c b/usr.sbin/sysinstall/menus.c index 7c8c984..15f51fb 100644 --- a/usr.sbin/sysinstall/menus.c +++ b/usr.sbin/sysinstall/menus.c @@ -553,6 +553,8 @@ DMenu MenuMediaFTP = { VAR_FTP_PATH _AS("=ftp://current.freebsd.org/pub/FreeBSD/snapshots/") }, { " 4.0 SNAP Server", "releng4.freebsd.org", NULL, dmenuSetVariable, NULL, VAR_FTP_PATH _AS("=ftp://releng4.freebsd.org/pub/FreeBSD/snapshots/") }, + { " IPv6 Ready", "ftp7.jp.freebsd.org", NULL, dmenuSetVariable, NULL, + VAR_FTP_PATH _AP("=ftp://ftp7.jp.freebsd.org") }, { "Argentina", "ftp.ar.freebsd.org", NULL, dmenuSetVariable, NULL, VAR_FTP_PATH _AP("=ftp://ftp.ar.freebsd.org") }, { " Australia", "ftp.au.freebsd.org", NULL, dmenuSetVariable, NULL, @@ -639,6 +641,8 @@ DMenu MenuMediaFTP = { VAR_FTP_PATH _AP("=ftp://ftp5.jp.freebsd.org") }, { " Japan #6", "ftp6.jp.freebsd.org", NULL, dmenuSetVariable, NULL, VAR_FTP_PATH _AP("=ftp://ftp6.jp.freebsd.org") }, + { " Japan #7", "ftp7.jp.freebsd.org", NULL, dmenuSetVariable, NULL, + VAR_FTP_PATH _AP("=ftp://ftp7.jp.freebsd.org") }, { "Korea", "ftp.kr.freebsd.org", NULL, dmenuSetVariable, NULL, VAR_FTP_PATH _AP("=ftp://ftp.kr.freebsd.org") }, { " Korea #2", "ftp2.kr.freebsd.org", NULL, dmenuSetVariable, NULL, diff --git a/usr.sbin/sysinstall/network.c b/usr.sbin/sysinstall/network.c index 81296e4..a48b066 100644 --- a/usr.sbin/sysinstall/network.c +++ b/usr.sbin/sysinstall/network.c @@ -125,31 +125,32 @@ mediaInitNetwork(Device *dev) snprintf(ifconfig, 255, "%s%s", VAR_IFCONFIG, dev->name); cp = variable_get(ifconfig); - if (!cp) { + if (cp) { + if (strcmp(cp, "DHCP")) { + msgDebug("ifconfig %s %s", dev->name, cp); + i = vsystem("ifconfig %s %s", dev->name, cp); + if (i) { + msgConfirm("Unable to configure the %s interface!\n" + "This installation method cannot be used.", + dev->name); + return FALSE; + } + rp = variable_get(VAR_GATEWAY); + if (!rp || *rp == '0') { + msgConfirm("No gateway has been set. You may be unable to access hosts\n" + "not on your local network"); + } + else { + msgDebug("Adding default route to %s.", rp); + vsystem("route -n add default %s", rp); + } + } + } else if ((cp = variable_get(VAR_IPV6ADDR)) == NULL || *cp == '\0') { msgConfirm("The %s device is not configured. You will need to do so\n" "in the Networking configuration menu before proceeding.", dev->name); return FALSE; } - else if (!strcmp(cp, "DHCP")) - goto bail; - msgDebug("ifconfig %s %s", dev->name, cp); - i = vsystem("ifconfig %s %s", dev->name, cp); - if (i) { - msgConfirm("Unable to configure the %s interface!\n" - "This installation method cannot be used.", dev->name); - return FALSE; - } - rp = variable_get(VAR_GATEWAY); - if (!rp || *rp == '0') { - msgConfirm("No gateway has been set. You may be unable to access hosts\n" - "not on your local network"); - } - else { - msgDebug("Adding default route to %s.", rp); - vsystem("route -n add default %s", rp); - } -bail: if (isDebug()) msgDebug("Network initialized successfully.\n"); networkInitialized = TRUE; diff --git a/usr.sbin/sysinstall/options.c b/usr.sbin/sysinstall/options.c index b6fed23..ae640f6 100644 --- a/usr.sbin/sysinstall/options.c +++ b/usr.sbin/sysinstall/options.c @@ -118,6 +118,8 @@ static Option Options[] = { OPT_IS_VAR, NULL, VAR_NO_CONFIRM, varCheck }, { "DHCP", "Attempt automatic DHCP configuration of interfaces", OPT_IS_VAR, NULL, VAR_TRY_DHCP, varCheck }, +{ "IPv6", "Attempt IPv6 configuration of interfaces", + OPT_IS_VAR, NULL, VAR_TRY_RTSOL, varCheck }, { "FTP username", "Username and password to use instead of anonymous", OPT_IS_FUNC, mediaSetFTPUserPass, VAR_FTP_USER, varCheck }, { "Editor", "Which text editor to use during installation", diff --git a/usr.sbin/sysinstall/sysinstall.h b/usr.sbin/sysinstall/sysinstall.h index 0563473..e34735a 100644 --- a/usr.sbin/sysinstall/sysinstall.h +++ b/usr.sbin/sysinstall/sysinstall.h @@ -123,6 +123,8 @@ #define VAR_INSTALL_CFG "installConfig" #define VAR_INSTALL_ROOT "installRoot" #define VAR_IPADDR "ipaddr" +#define VAR_IPV6_ENABLE "ipv6_enable" +#define VAR_IPV6ADDR "ipv6addr" #define VAR_KEYMAP "keymap" #define VAR_KGET "kget" #define VAR_LABEL "label" @@ -167,6 +169,7 @@ #define VAR_SWAP_SIZE "swapSize" #define VAR_TAPE_BLOCKSIZE "tapeBlocksize" #define VAR_TRY_DHCP "tryDHCP" +#define VAR_TRY_RTSOL "tryRTSOL" #define VAR_UFS_PATH "ufs" #define VAR_USR_SIZE "usrSize" #define VAR_VAR_SIZE "varSize" @@ -327,6 +330,7 @@ typedef int (*commandFunc)(char *key, void *data); /* This is the structure that Network devices carry around in their private, erm, structures */ typedef struct _devPriv { + int use_rtsol; int use_dhcp; char ipaddr[IPADDR_FIELD_LEN]; char netmask[IPADDR_FIELD_LEN]; diff --git a/usr.sbin/sysinstall/tcpip.c b/usr.sbin/sysinstall/tcpip.c index 18e9287..3a946f94 100644 --- a/usr.sbin/sysinstall/tcpip.c +++ b/usr.sbin/sysinstall/tcpip.c @@ -39,6 +39,9 @@ #include "sysinstall.h" #include <sys/param.h> +#include <sys/sysctl.h> +#include <sys/socket.h> +#include <netinet/in.h> #include <netdb.h> /* The help file for the TCP/IP setup screen */ @@ -47,9 +50,10 @@ /* These are nasty, but they make the layout structure a lot easier ... */ static char hostname[HOSTNAME_FIELD_LEN], domainname[HOSTNAME_FIELD_LEN], - gateway[IPADDR_FIELD_LEN], nameserver[IPADDR_FIELD_LEN]; + gateway[IPADDR_FIELD_LEN], nameserver[INET6_ADDRSTRLEN]; static int okbutton, cancelbutton; static char ipaddr[IPADDR_FIELD_LEN], netmask[IPADDR_FIELD_LEN], extras[EXTRAS_FIELD_LEN]; +static char ipv6addr[INET6_ADDRSTRLEN]; /* What the screen size is meant to be */ #define TCP_DIALOG_Y 0 @@ -69,17 +73,17 @@ static Layout layout[] = { domainname, STRINGOBJ, NULL }, #define LAYOUT_GATEWAY 2 { 5, 2, 18, IPADDR_FIELD_LEN - 1, - "Gateway:", - "IP address of host forwarding packets to non-local destinations", + "IPv4 Gateway:", + "IPv4 address of host forwarding packets to non-local destinations", gateway, STRINGOBJ, NULL }, #define LAYOUT_NAMESERVER 3 - { 5, 35, 18, IPADDR_FIELD_LEN - 1, - "Name server:", "IP address of your local DNS server", + { 5, 35, 18, INET6_ADDRSTRLEN - 1, + "Name server:", "IPv4 or IPv6 address of your local DNS server", nameserver, STRINGOBJ, NULL }, #define LAYOUT_IPADDR 4 { 10, 10, 18, IPADDR_FIELD_LEN - 1, - "IP Address:", - "The IP address to be used for this interface", + "IPv4 Address:", + "The IPv4 address to be used for this interface", ipaddr, STRINGOBJ, NULL }, #define LAYOUT_NETMASK 5 { 10, 35, 18, IPADDR_FIELD_LEN - 1, @@ -126,6 +130,22 @@ verifyIP(char *ip) return 0; } +static int +verifyIP6(char *ip) +{ + struct addrinfo hints, *res; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET6; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; + if (getaddrinfo(ip, NULL, &hints, &res) == 0) { + freeaddrinfo(res); + return 1; + } + return 0; +} + /* Check for the settings on the screen - the per-interface stuff is moved to the main handling code now to do it on the fly - sigh */ static int @@ -134,13 +154,13 @@ verifySettings(void) if (!hostname[0]) feepout("Must specify a host name of some sort!"); else if (gateway[0] && strcmp(gateway, "NO") && !verifyIP(gateway)) - feepout("Invalid gateway IP address specified"); - else if (nameserver[0] && !verifyIP(nameserver)) + feepout("Invalid gateway IPv4 address specified"); + else if (nameserver[0] && !verifyIP(nameserver) && !verifyIP6(nameserver)) feepout("Invalid name server IP address specified"); else if (netmask[0] && (netmask[0] < '0' && netmask[0] > '3')) feepout("Invalid netmask value"); else if (ipaddr[0] && !verifyIP(ipaddr)) - feepout("Invalid IP address"); + feepout("Invalid IPv4 address"); else return 1; return 0; @@ -169,7 +189,7 @@ dhcpGetInfo(Device *devp) msgDebug("DHCP configured interface returns %s\n", data); /* XXX This is gross as it assumes a certain ordering to ifconfig's output! XXX */ - if ((cp = strstr(data, "inet")) != NULL) { + if ((cp = strstr(data, "inet ")) != NULL) { i = 0; cp += 5; /* move over keyword */ while (*cp != ' ') @@ -193,6 +213,32 @@ dhcpGetInfo(Device *devp) variable_set2(VAR_HOSTNAME, hostname, 0); } +static void +rtsolGetInfo(Device *devp) +{ + FILE *ifp; + char *cp, cmd[256], data[2048]; + int i; + + snprintf(cmd, sizeof cmd, "ifconfig %s", devp->name); + if ((ifp = popen(cmd, "r")) == NULL) + return; + while (fgets(data, sizeof(data), ifp) != NULL) { + if (isDebug()) + msgDebug("RTSOL configured interface returns %s", data); + if ((cp = strstr(data, "inet6 ")) != NULL) { + cp += 6; /* move over keyword */ + if (strncmp(cp, "fe80:", 5)) { + i = 0; + while (*cp != ' ') + ipv6addr[i++] = *(cp++); + ipv6addr[i] = '\0'; + } + } + } + fclose(ifp); +} + /* This is it - how to get TCP setup values */ int tcpOpenDialog(Device *devp) @@ -202,6 +248,7 @@ tcpOpenDialog(Device *devp) int n = 0, filled = 0, cancel = FALSE; int max, ret = DITEM_SUCCESS; int use_dhcp = FALSE; + int use_rtsol = FALSE; char *tmp; char title[80]; @@ -214,10 +261,30 @@ tcpOpenDialog(Device *devp) SAFE_STRCPY(netmask, di->netmask); SAFE_STRCPY(extras, di->extras); use_dhcp = di->use_dhcp; + use_rtsol = di->use_rtsol; } else { /* See if there are any defaults */ char *cp; + /* Try a RTSOL scan if such behavior is desired */ + if (!variable_cmp(VAR_TRY_RTSOL, "YES") || !msgYesNo("Do you want to try IPv6 configuration of the interface?")) { + int i; + + i = 0; + sysctlbyname("net.inet6.ip6.forwarding", NULL, 0, &i, sizeof(i)); + i = 1; + sysctlbyname("net.inet6.ip6.accept_rtadv", NULL, 0, &i, sizeof(i)); + vsystem("ifconfig %s up", devp->name); + Mkdir("/var/run"); + msgNotify("Scanning for RA servers..."); + if (0 == vsystem("rtsol %s", devp->name)) { + sleep(3); + rtsolGetInfo(devp); + use_rtsol = TRUE; + } else + use_rtsol = FALSE; + } + /* First try a DHCP scan if such behavior is desired */ if (!variable_cmp(VAR_TRY_DHCP, "YES") || !msgYesNo("Do you want to try DHCP configuration of the interface?")) { Mkdir("/var/db"); @@ -298,7 +365,10 @@ tcpOpenDialog(Device *devp) dialog_clear_norefresh(); /* We need a curses window */ - if (!(ds_win = openLayoutDialog(TCP_HELPFILE, " Network Configuration ", + tmp = " Network Configuration "; + if (ipv6addr[0]) + tmp = string_concat(tmp, "(IPv6 ready) "); + if (!(ds_win = openLayoutDialog(TCP_HELPFILE, tmp, TCP_DIALOG_X, TCP_DIALOG_Y, TCP_DIALOG_WIDTH, TCP_DIALOG_HEIGHT))) { beep(); msgConfirm("Cannot open TCP/IP dialog window!!"); @@ -361,6 +431,7 @@ netconfig: char temp[512], ifn[255]; char *ifaces; char *pccard; + int ipv4_enable = FALSE; if (hostname[0]) { variable_set2(VAR_HOSTNAME, hostname, 1); @@ -374,6 +445,8 @@ netconfig: variable_set2(VAR_NAMESERVER, nameserver, 0); if (ipaddr[0]) variable_set2(VAR_IPADDR, ipaddr, 0); + if (ipv6addr[0]) + variable_set2(VAR_IPV6ADDR, ipv6addr, 0); if (!devp->private) devp->private = (DevInfo *)safe_malloc(sizeof(DevInfo)); @@ -382,15 +455,21 @@ netconfig: SAFE_STRCPY(di->netmask, netmask); SAFE_STRCPY(di->extras, extras); di->use_dhcp = use_dhcp; - - sprintf(ifn, "%s%s", VAR_IFCONFIG, devp->name); - if (use_dhcp) - sprintf(temp, "DHCP"); - else - sprintf(temp, "inet %s %s netmask %s", ipaddr, extras, netmask); - variable_set2(ifn, temp, 1); + di->use_rtsol = use_rtsol; + + if (use_dhcp || ipaddr[0]) + ipv4_enable = TRUE; + if (ipv4_enable) { + sprintf(ifn, "%s%s", VAR_IFCONFIG, devp->name); + if (use_dhcp) + sprintf(temp, "DHCP"); + else + sprintf(temp, "inet %s %s netmask %s", + ipaddr, extras, netmask); + variable_set2(ifn, temp, 1); + } pccard = variable_get("_pccard_install"); - if (pccard && strcmp(pccard, "YES") == 0) { + if (pccard && strcmp(pccard, "YES") == 0 && ipv4_enable) { variable_set2("pccard_ifconfig", temp, 1); } ifaces = variable_get(VAR_INTERFACES); @@ -401,6 +480,8 @@ netconfig: sprintf(ifn, "%s %s", devp->name, ifaces); variable_set2(VAR_INTERFACES, ifn, 1); } + if (use_rtsol) + variable_set2(VAR_IPV6_ENABLE, "YES", 1); if (!use_dhcp) configResolv(NULL); /* XXX this will do it on the MFS copy XXX */ ret = DITEM_SUCCESS; |