diff options
-rw-r--r-- | usr.sbin/eeprom/Makefile | 12 | ||||
-rw-r--r-- | usr.sbin/eeprom/eeprom.8 | 668 | ||||
-rw-r--r-- | usr.sbin/eeprom/eeprom.c | 153 | ||||
-rw-r--r-- | usr.sbin/eeprom/ofw_options.c | 314 | ||||
-rw-r--r-- | usr.sbin/eeprom/ofw_options.h | 34 |
5 files changed, 1181 insertions, 0 deletions
diff --git a/usr.sbin/eeprom/Makefile b/usr.sbin/eeprom/Makefile new file mode 100644 index 0000000..fa5f411 --- /dev/null +++ b/usr.sbin/eeprom/Makefile @@ -0,0 +1,12 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../ofwdump + +PROG= eeprom +MAN= eeprom.8 +MANSUBDIR= /sparc64 +SRCS= eeprom.c ofw_options.c ofw_util.c +WARNS?= 6 +CFLAGS+= -I${.CURDIR}/../ofwdump + +.include <bsd.prog.mk> diff --git a/usr.sbin/eeprom/eeprom.8 b/usr.sbin/eeprom/eeprom.8 new file mode 100644 index 0000000..637e15a --- /dev/null +++ b/usr.sbin/eeprom/eeprom.8 @@ -0,0 +1,668 @@ +.\" Copyright (c) 1996 The NetBSD Foundation, Inc. +.\" Copyright (c) 2004 Marius Strobl +.\" All rights reserved. +.\" +.\" This code is derived from software contributed to The NetBSD Foundation +.\" by Jason R. Thorpe. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the NetBSD +.\" Foundation, Inc. and its contributors. +.\" 4. Neither the name of The NetBSD Foundation nor the names of its +.\" contributors may be used to endorse or promote products derived +.\" from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +.\" POSSIBILITY OF SUCH DAMAGE. +.\" +.\" from: NetBSD: eeprom.8,v 1.11 2003/03/31 01:31:39 perry Exp +.\" $FreeBSD$ +.\" +.Dd May 16, 2004 +.Dt EEPROM 8 sparc64 +.Os +.Sh NAME +.Nm eeprom +.Nd "display or modify contents of the EEPROM or NVRAM" +.Sh SYNOPSIS +.Nm +.Fl a +.Nm +.Op Fl +.Ar name Ns Op = Ns Ar value +.Ar ... +.Sh DESCRIPTION +The +.Nm +utility provides an interface for displaying and changing the system's +configuration variables contained in EEPROM or NVRAM. +In the first synopsis form, all available configuration variables and their +current values are printed. +In the second form, only the variable selected by +.Ar name +and its value is printed or changed if +.Ar name +is followed by +.Ql = +and a +.Ar value . +.Pp +The following options are available: +.Bl -tag -width indent +.It Fl +Commands for displaying or changing variables are taken from stdin, allowing +one +.Ar name +or one +.Ar name +and +.Ar value +pair per line. +The output is printed on stdout. +.It Fl a +Print all available configuration variables and their current values. +.El +.Sh VARIABLES AND VALUES +Below are variables and values that one is likely to find on a system equipped +with OpenBoot 3.x and Open Firmware respectively. +.Pp +Note: the attempt to set a variable to an illegal value results in the +Open Firmware setting it to some legal value instead. +The +.Nm +utility will detect this, try to recover the previous value of the variable +and issue a warning telling that the requested value could not be set. +.Bl -tag -width ".Va last-hardware-update" +.It Va auto-boot? +If +.Dq Li true , +the system will try to boot automatically from the devices listed in +.Va boot-device +and +.Va diag-device +respectively, using the command specified in +.Va boot-command +at power-up. +Default: +.Dq Li true . +.It Va auto-boot-retry? +If set to +.Dq Li true +and +.Va auto-boot? +is also set to +.Dq Li true , +the system will try to boot from the specified boot devices forever. +Default: +.Dq Li false . +.It Va ansi-terminal? +If +.Dq Li false , +.Tn ANSI +escape sequences are not interpreted by the terminal emulator. +Default: +.Dq Li true . +.It Va boot-command +Command executed when +.Va auto-boot? +is set to +.Dq Li true . +Default: +.Dq Li boot . +.It Va boot-device +Default device to boot from if +.Va diag-switch? +is set to +.Dq Li false . +Takes one or more device aliases or device paths. +The boot devices are sequentially tried to boot from, beginning with the first +one specified. +Default: +.Dq Li "net disk" . +.It Va cpci-probe-list +Digits in the format +.Dq Li 0,1,2 +specifying in which order to probe the devices on the CompactPCI bus at +power-up. +Default: system-dependent. +.It Va boot-file +Default arguments for boot when +.Va diag-switch? +is set to +.Dq Li false . +When empty, the secondary boot loader will choose the file to boot. +Default: empty string. +.It Va diag-device +Like +.Va boot-device . +Used when +.Va diag-switch? +is set to +.Dq Li true . +Default: +.Dq Li net . +.It Va diag-file +Like +.Va boot-file . +Used when +.Va diag-switch? +is set to +.Dq Li true . +Default: empty string. +.It Va diag-level +Level of diagnostics to run when +.Va diag-switch? +is set to +.Dq Li true . +Possible values are +.Dq Li max , +.Dq Li menus , +.Dq Li min +and +.Dq Li off +(depending on the system model). +When set to +.Dq Li off , +the Power-On Self Test (POST) is not run. +The other values are interpreted by the POST. +Default: +.Dq Li min +or +.Dq Li max +(system-dependent). +.It Va diag-switch? +If +.Dq Li true , +the system will boot and run in diagnostic mode. +Default: +.Dq Li false +or +.Dq Li true +(system-dependent). +.It Va env-monitor +Enables or disables the Advanced System Monitoring (ASM). +Possible values are +.Dq Li enabled +and +.Dq Li disabled . +Default: +.Dq Li enabled . +.It Va fcode-debug? +Used for debugging FCode programs. +If set to +.Dq Li true , +names of additional FCodes are registered in the Forth dictionary. +Default: +.Dq Li false . +.It Va hardware-revision +A string describing the system hardware version. +Default: system-dependent. +.It Va input-device +One of the strings +.Dq Li keyboard , +.Dq Li ttya , +or +.Dq Li ttyb , +specifying the default console input device. +Default: +.Dq Li keyboard +or +.Dq Li ttya +(system-dependent). +.It Va keyboard-click? +If set to +.Dq Li true , +the keys click annoyingly. +Default: +.Dq Li false . +.It Va keymap +Keymap for a custom keyboard. +Default: empty string. +.It Va last-hardware-update +Similar to +.Va hardware-revision , +describing when the hardware was last updated. +Default: system-dependent. +.It Va last-poweroff-cause +Cause of the last power-off. +Used internally by the OpenBoot PROM. +Default: +.Dq Li 0 . +.It Va load-base +Default address where client programs are loaded to. +It is unlikely that this value should ever be changed. +Default: +.Dq Li 16384 . +.It Va local-mac-address? +If set to +.Dq Li false , +all Ethernet devices will use the system default MAC address. +If set to +.Dq Li true , +Ethernet devices which have a unique MAC address will use it rather +than the system's default MAC address. +Default: +.Dq Li false . +.It Va mfg-mode +Manufacture test mode interpreted by the POST. +Possible values are +.Dq Li chamber +and +.Dq Li off . +Default: +.Dq Li off . +.It Va mfg-switch? +If set to +.Dq Li true , +manufacturing tests are repeated until stopped by pressing STOP-A. +Default: +.Dq Li off . +.It Va net-timeout +If set to +.Dq Li 0 , +the system will try to boot forever when the boot device used is a network +device. +Any non-zero value is interpreted as minutes to try a network boot. +Default: +.Dq Li 0 . +.It Va nvramrc +Contents of the NVRAMRC. +Default: empty string. +.Pp +While +.Va nvramrc +can be set using +.Nm , +it is preferred to use +.Ic nvedit +in the boot monitor instead. +.It Va oem-banner +A string displayed at power-up, rather than the default banner. +Used when +.Va oem-banner? +is set to +.Dq Li true . +Default: system-dependent. +.It Va oem-banner? +If set to +.Dq Li true , +the string stored in +.Va oem-banner +is displayed at power-up rather than the default banner. +Default: system-dependent. +.It Va oem-logo +A logo displayed at power-up when +.Va oem-logo? +is set to +.Dq Li true , +rather than the default logo. +The logo has to be 512 bytes in size, containing a 64x64-bit monochrome image +in Sun Raster format without the leading 32-byte header. +Default: system-dependent. +.Pp +To set the logo with +.Nm , +give the pathname of the file containing the image as the +.Ar value . +Using an empty +.Ar value +will remove the image. +.It Va oem-logo? +If set to +.Dq Li true , +the logo stored in +.Va oem-logo +is displayed at power-up rather than the default logo. +.It Va output-device +One of the strings +.Dq Li screen , +.Dq Li ttya , +or +.Dq Li ttyb , +specifying the default console output device. +Default: +.Dq Li screen +or +.Dq Li ttya +(system-dependent). +.It Va pcia-probe-list +Digits in the format +.Dq Li 1,2,3 +specifying in which order to probe the devices on the PCI bus A. +Default: system-dependent. +.It Va pcib-probe-list +Like +.Va pcia-probe-list , +but for PCI bus B. +Default: system-dependent. +.It Va #power-cycles +Number of power-cycles. +Automatically incremented on each power-cycle. +Default: system-dependent. +.It Va sbus-probe-list +Digits in the format +.Dq Li 0123 +specifying in which order to probe the SBus slots at power-up. +Default: system-dependent. +.It Va screen-#columns +An integer specifying the screen width in characters per line. +Default: +.Dq Li 80 . +.It Va screen-#rows +An integer specifying the scren height in lines. +Default: +.Dq Li 34 . +.It Va scsi-initiator-id +The SCSI ID of SCSI controllers in the range of [0-7] or [0-f] (depending +on the controller). +A SCSI controller may or may not adhere to this setting, depending on its +FCode and device driver. +Default: +.Dq Li 7 . +.It Va security-#badlogins +Number of incorrect password attempts when +.Va security-mode +is set to +.Dq Li command +or +.Dq Li full . +Default: +.Dq Li 0 . +.It Va security-mode +Boot monitor security level. +One of the three possible values +.Dq Li full , +.Dq Li command , +or +.Dq Li none . +When set to +.Dq Li full , +all boot monitor commands except for +.Ic go +require the password. +When set to +.Dq Li command , +all boot monitor commands except for +.Ic boot +and +.Ic go +require the password. +When set to +.Dq Li none , +no password is required. +Default: +.Dq Li none . +.Pp +When +.Nm +is used to set +.Va security-mode +to +.Dq Li full +or +.Dq Li command , +you will be prompted for the password. +When +.Va security-mode +is set to +.Dq Li none , +.Nm +will clear the password. +.It Va security-password +The password used when +.Va security-mode +is set to +.Dq Li full +or +.Dq Li command . +The maximum length for this password is 8 characters. +All characters exceeding this length will be ignored. +The value displayed for +.Va security-password +is always an empty string, even when a password is set. +Default: empty string. +.Pp +When +.Va security-mode +is set to +.Dq Li full +or +.Dq Li command , +.Nm +can be used to enter a new password using any +.Ar value +for +.Va security-password +on the command line. +You will be prompted by +.Nm +to type in the new password in this case. +Trying to set +.Va security-password +when +.Va security-mode +is set to +.Dq Li none +using +.Nm +has no effect. +.It Va selftest-#megs +An integer specifying the number of megabytes of memory to test upon +power-up when +.Va diag-switch? +is set to +.Dq Li false . +Default: +.Dq Li 1 . +.It Va shutdown-temperature +Temperature at which the ASM issues an over-temperature shutdown. +Default: system-dependent. +.It Va silent-mode +If set to +.Dq Li true , +memory test messages will not be displayed at power-up. +Default: +.Dq Li false . +.It Va sunmon-compat? +If set to +.Dq Li true , +the old bootROM interface will be used while in the boot monitor, +rather than the OpenBoot PROM interface. +Default: +.Dq Li false . +.It Va system-board-date +Manufacturing date of the system board. +Default: system-dependent. +.It Va system-board-serial# +Serial number of the system board. +Default: system-dependent. +.It Va tpe-link-test? +Enable link test on 10baseT and 100baseTX Ethernet devices. +Default: +.Dq Li true . +.It Va ttya-mode +A string of five comma separated fields in the format +.Dq Li 9600,8,n,1,- . +The first field is the baud rate. +The second field is the number of data bits. +The third field is the parity; acceptable values for parity are +.Ql n +(none), +.Ql e +(even), +.Ql o +(odd), +.Ql m +(mark), and +.Ql s +(space). +The fourth field is the number of stop bits. +The fifth field is the +.Dq handshake +field; acceptable values are +.Ql - +(none), +.Ql h +(RTS/CTS), and +.Ql s +(Xon/Xoff). +Default: +.Dq Li 9600,8,n,1,- . +.It Va ttya-ignore-cd +If set to +.Dq Li true , +the system will ignore carrier detect. +Default: +.Dq Li true . +.It Va ttya-rts-dtr-off +If set to +.Dq Li true , +the system will ignore RTS/DTR. +Default: +.Dq Li false . +.It Va ttyb-mode +Like +.Va ttya-mode , +but for ttyb. +Default: +.Dq Li 9600,8,n,1,- . +.It Va ttyb-ignore-cd +Like +.Va ttya-ignore-cd , +but for ttyb. +Default: +.Dq Li true . +.It Va ttyb-rts-dtr-off +Like +.Va ttya-rts-dtr-off , +but for ttyb. +Default: +.Dq Li false . +.It Va use-boot-table? +Use boot table defined by the OEM. +Default: system-dependent. +.It Va use-nvramrc? +If set to +.Dq Li true , +the script stored in +.Va nvramrc +will be executed during start-up. +Default: +.Dq Li false . +.It Va warning-temperature +Temperature at which the ASM issues an over-temperature warning. +Default: system-dependent. +.It Va watchdog-enable +Enables or disables the system watchdog timer. +Default: +.Dq Li false . +.It Va watchdog-reboot? +If set to +.Dq Li true , +the system will reboot upon terminal count of the system watchdog timer. +If set to +.Dq Li false , +the system will fall into the boot monitor. +Default: +.Dq Li false . +.It Va watchdog-timeout +Expiry limit for the system watchdog timer. +Range and unit depend on the system model. +Default: system-dependent. +.El +.Sh EXAMPLES +Print all available configuration variables and their current values: +.Pp +.Dl "eeprom -a" +.Pp +Print the current value of the +.Va local-mac-address? +variable: +.Pp +.Dl "eeprom local-mac-address\e?" +.Pp +Set the value of the +.Va local-mac-address? +variable to +.Dq Li true : +.Pp +.Dl "eeprom local-mac-address\e?=true" +.Pp +Note that the +.Ql \e +in the above examples is used to keep the shell from interpreting the +.Ql \&? . +.Pp +Write an image to the +.Va oem-logo +variable: +.Pp +.Dl "eeprom oem-logo=/path/to/image.raw" +.Pp +Remove the image from the +.Va oem-logo +variable again: +.Pp +.Dl "eeprom oem-logo=" +.Pp +Set the value of the +.Va security-mode +variable to +.Dq Li full , +and set the password: +.Bd -literal -offset indent +eeprom security-mode=full +New password: +Retype new password: +.Ed +.Pp +Remember that the maximum length for the password is 8 characters. +All characters exceeding this length will be ignored. +.Pp +Set a new password when the +.Va security-mode +variable is set to +.Dq Li command +or +.Dq Li full : +.Bd -literal -offset indent +eeprom security-password= +New password: +Retype new password: +.Ed +.Sh SEE ALSO +.Xr ofwdump 8 +.Sh HISTORY +The +.Nm +utility first appeared in +.Fx 5.3 . +It is inspired by the +.Nx +.Xr eeprom 8 +and SunOS/Solaris +.Xr eeprom 1M +utilities. +.Sh BUGS +Currently, +.Nm +only supports systems equipped with Open Firmware and is only tested on Sun +Microsystems sun4u machines. diff --git a/usr.sbin/eeprom/eeprom.c b/usr.sbin/eeprom/eeprom.c new file mode 100644 index 0000000..ecd9267 --- /dev/null +++ b/usr.sbin/eeprom/eeprom.c @@ -0,0 +1,153 @@ +/*- + * Copyright (c) 1996 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * from: NetBSD: main.c,v 1.15 2001/02/19 23:22:42 cgd Exp + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sysexits.h> +#include <unistd.h> + +#include "ofw_options.h" + +static int action(char *); +static void dump_config(void); +static void usage(void); + +static void +usage(void) +{ + + fprintf(stderr, + "usage: eeprom -a\n" + " eeprom [-] name[=value] ...\n"); + exit(EX_USAGE); +} + +int +main(int argc, char *argv[]) +{ + int do_stdin, opt; + int aflag, rv; + char *cp; + char line[BUFSIZ]; + + aflag = do_stdin = 0; + rv = EX_OK; + while ((opt = getopt(argc, argv, "-a")) != -1) { + switch (opt) { + case '-': + if (aflag) + usage(); + do_stdin = 1; + break; + case 'a': + if (do_stdin) + usage(); + aflag = 1; + break; + case '?': + default: + usage(); + /* NOTREACHED */ + } + } + argc -= optind; + argv += optind; + + if (aflag) { + if (argc != 0) + usage(); + dump_config(); + } else { + if (do_stdin) { + while (fgets(line, BUFSIZ, stdin) != NULL && + rv == EX_OK) { + if (line[0] == '\n') + continue; + if ((cp = strrchr(line, '\n')) != NULL) + *cp = '\0'; + rv = action(line); + } + if (ferror(stdin)) + err(EX_NOINPUT, "stdin"); + } else { + if (argc == 0) + usage(); + while (argc && rv == EX_OK) { + rv = action(*argv); + ++argv; + --argc; + } + } + } + return (rv); +} + +static int +action(char *line) +{ + int rv; + char *keyword, *arg; + + keyword = strdup(line); + if (keyword == NULL) + err(EX_OSERR, "malloc() failed"); + if ((arg = strrchr(keyword, '=')) != NULL) + *arg++ = '\0'; + switch (rv = ofwo_action(keyword, arg)) { + case EX_UNAVAILABLE: + warnx("nothing available for '%s'.", keyword); + break; + case EX_DATAERR: + warnx("invalid value '%s' for '%s'.", arg, keyword); + break; + } + free(keyword); + return(rv); +} + +static void +dump_config() +{ + + ofwo_dump(); +} diff --git a/usr.sbin/eeprom/ofw_options.c b/usr.sbin/eeprom/ofw_options.c new file mode 100644 index 0000000..d04e61a --- /dev/null +++ b/usr.sbin/eeprom/ofw_options.c @@ -0,0 +1,314 @@ +/*- + * Copyright (c) 2004 Marius Strobl + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +/* + * Handlers for Open Firmware /options node. + */ + +#include <sys/types.h> + +#include <dev/ofw/openfirm.h> + +#include <err.h> +#include <fcntl.h> +#include <readpassphrase.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sysexits.h> +#include <unistd.h> + +#include "ofw_options.h" +#include "ofw_util.h" + +#define OFWO_LOGO 512 +#define OFWO_MAXPROP 31 +#define OFWO_MAXPWD 8 + +struct ofwo_extabent { + const char *ex_prop; + int (*ex_handler)(struct ofwo_extabent *, int, const void *, + int, const char *); +}; + +static int ofwo_oemlogo(struct ofwo_extabent *, int, const void *, int, + const char *); +static int ofwo_secmode(struct ofwo_extabent *, int, const void *, int, + const char *); +static int ofwo_secpwd(struct ofwo_extabent *, int, const void *, int, + const char *); + +static struct ofwo_extabent ofwo_extab[] = { + { "oem-logo", ofwo_oemlogo }, + { "security-mode", ofwo_secmode }, + { "security-password", ofwo_secpwd }, + { NULL, NULL } +}; + +static int ofwo_setpass(int); +static __inline void ofwo_printprop(const char *, const char*, int); +static int ofwo_setstr(int, const void *, int, const char *, + const char *); + +static int +ofwo_oemlogo(struct ofwo_extabent *exent, int fd, const void *buf, int buflen, + const char *val) +{ + int lfd; + char logo[OFWO_LOGO + 1]; + + if (val) { + if (val[0] == '\0') + ofw_setprop(fd, ofw_optnode(fd), exent->ex_prop, "", 1); + else { + if ((lfd = open(val, O_RDONLY)) == -1) { + warn("could not open '%s'", val); + return (EX_USAGE); + } + if (read(lfd, logo, OFWO_LOGO) != OFWO_LOGO || + lseek(lfd, 0, SEEK_END) != OFWO_LOGO) { + close(lfd); + warnx("logo '%s' has wrong size.", val); + return (EX_USAGE); + } + close(lfd); + logo[OFWO_LOGO] = '\0'; + if (ofw_setprop(fd, ofw_optnode(fd), exent->ex_prop, + logo, OFWO_LOGO + 1) != OFWO_LOGO) + errx(EX_IOERR, "writing logo failed."); + } + } else + if (buflen != 0) + printf("%s: <logo data>\n", exent->ex_prop); + else + ofwo_printprop(exent->ex_prop, (const char *)buf, + buflen); + return (EX_OK); +} + +static int +ofwo_secmode(struct ofwo_extabent *exent, int fd, const void *buf, int buflen, + const char *val) +{ + int res; + + if (val) { + if (strcmp(val, "full") == 0 || strcmp(val, "command") == 0) { + if ((res = ofwo_setpass(fd)) != EX_OK) + return (res); + if ((res = ofwo_setstr(fd, buf, buflen, exent->ex_prop, + val)) != EX_OK) + ofw_setprop(fd, ofw_optnode(fd), + "security-password", "", 1); + return (res); + } + if (strcmp(val, "none") == 0) { + ofw_setprop(fd, ofw_optnode(fd), "security-password", + "", 1); + return (ofwo_setstr(fd, buf, buflen, exent->ex_prop, + val)); + } + return (EX_DATAERR); + } else + ofwo_printprop(exent->ex_prop, (const char *)buf, buflen); + return (EX_OK); +} + +static int +ofwo_secpwd(struct ofwo_extabent *exent, int fd __unused, + const void *buf __unused, __unused int buflen, const char *val) +{ + void *pbuf; + int len, pblen, rv; + + pblen = 0; + rv = EX_OK; + pbuf = NULL; + if (val) { + len = ofw_getprop_alloc(fd, ofw_optnode(fd), "security-mode", + &pbuf, &pblen, 1); + if (len <= 0 || strncmp("none", (char *)pbuf, len) == 0) { + rv = EX_CONFIG; + warnx("no security mode set."); + } else if (strncmp("command", (char *)pbuf, len) == 0 || + strncmp("full", (char *)pbuf, len) == 0) { + rv = ofwo_setpass(fd); + } else { + rv = EX_CONFIG; + warnx("invalid security mode."); + } + } else + ofwo_printprop(exent->ex_prop, (const char *)buf, buflen); + if (pbuf != NULL) + free(pbuf); + return (rv); +} + +static int +ofwo_setpass(int fd) +{ + char pwd1[OFWO_MAXPWD + 1], pwd2[OFWO_MAXPWD + 1]; + + if (readpassphrase("New password:", pwd1, sizeof(pwd1), + RPP_ECHO_OFF | RPP_REQUIRE_TTY) == NULL || + readpassphrase("Retype new password:", pwd2, sizeof(pwd2), + RPP_ECHO_OFF | RPP_REQUIRE_TTY) == NULL) + errx(EX_USAGE, "failed to get password."); + if (strlen(pwd1) == 0) { + printf("Password unchanged.\n"); + return (EX_OK); + } + if (strcmp(pwd1, pwd2) != 0) { + printf("Mismatch - password unchanged.\n"); + return (EX_USAGE); + } + ofw_setprop(fd, ofw_optnode(fd), "security-password", pwd1, + strlen(pwd1) + 1); + return (EX_OK); +} + +static void +ofwo_printprop(const char *prop, const char* buf, int buflen) +{ + + printf("%s: %.*s\n", prop, buflen, buf); +} + +static int +ofwo_setstr(int fd, const void *buf, int buflen, const char *prop, + const char *val) +{ + void *pbuf; + int len, pblen, rv; + phandle_t optnode; + char *oval; + + pblen = 0; + rv = EX_OK; + pbuf = NULL; + optnode = ofw_optnode(fd); + ofw_setprop(fd, optnode, prop, val, strlen(val) + 1); + len = ofw_getprop_alloc(fd, optnode, prop, &pbuf, &pblen, 1); + if (len < 0 || strncmp(val, (char *)pbuf, len) != 0) { + /* + * The value is too long for this property and the OFW has + * truncated it to fit or the value is illegal and a legal + * one has been written instead (e.g. attempted to write + * "foobar" to a "true"/"false"-property) - try to recover + * the old value. + */ + rv = EX_DATAERR; + if ((oval = malloc(buflen + 1)) == NULL) + err(EX_OSERR, "malloc() failed."); + strncpy(oval, buf, buflen); + oval[buflen] = '\0'; + len = ofw_setprop(fd, optnode, prop, oval, buflen + 1); + if (len != buflen) + errx(EX_IOERR, "recovery of old value failed."); + free(oval); + goto out; + } + printf("%s: %.*s%s->%s%.*s\n", prop, buflen, (const char *)buf, + buflen > 0 ? " " : "", len > 0 ? " " : "", len, (char *)pbuf); +out: + if (pbuf != NULL) + free(pbuf); + return (rv); +} + +void +ofwo_dump(void) +{ + void *pbuf; + int fd, len, nlen, pblen; + phandle_t optnode; + char prop[OFWO_MAXPROP + 1]; + struct ofwo_extabent *ex; + + pblen = 0; + pbuf = NULL; + fd = ofw_open(O_RDONLY); + optnode = ofw_optnode(fd); + for (nlen = ofw_firstprop(fd, optnode, prop, sizeof(prop)); nlen != 0; + nlen = ofw_nextprop(fd, optnode, prop, prop, sizeof(prop))) { + len = ofw_getprop_alloc(fd, optnode, prop, &pbuf, &pblen, 1); + if (len < 0) + continue; + if (strcmp(prop, "name") == 0) + continue; + for (ex = ofwo_extab; ex->ex_prop != NULL; ++ex) + if (strcmp(ex->ex_prop, prop) == 0) + break; + if (ex->ex_prop != NULL) + (*ex->ex_handler)(ex, fd, pbuf, len, NULL); + else + ofwo_printprop(prop, (char *)pbuf, len); + } + if (pbuf != NULL) + free(pbuf); + ofw_close(fd); +} + +int +ofwo_action(const char *prop, const char *val) +{ + void *pbuf; + int fd, len, pblen, rv; + phandle_t optnode; + struct ofwo_extabent *ex; + + pblen = 0; + rv = EX_OK; + pbuf = NULL; + if (strcmp(prop, "name") == 0) + return (EX_UNAVAILABLE); + if (val) + fd = ofw_open(O_RDWR); + else + fd = ofw_open(O_RDONLY); + optnode = ofw_optnode(fd); + len = ofw_getprop_alloc(fd, optnode, prop, &pbuf, &pblen, 1); + if (len < 0) { + rv = EX_UNAVAILABLE; + goto out; + } + for (ex = ofwo_extab; ex->ex_prop != NULL; ++ex) + if (strcmp(ex->ex_prop, prop) == 0) + break; + if (ex->ex_prop != NULL) + rv = (*ex->ex_handler)(ex, fd, pbuf, len, val); + else if (val) + rv = ofwo_setstr(fd, pbuf, len, prop, val); + else + ofwo_printprop(prop, (char *)pbuf, len); +out: + if (pbuf != NULL) + free(pbuf); + ofw_close(fd); + return (rv); +} diff --git a/usr.sbin/eeprom/ofw_options.h b/usr.sbin/eeprom/ofw_options.h new file mode 100644 index 0000000..5bc6656 --- /dev/null +++ b/usr.sbin/eeprom/ofw_options.h @@ -0,0 +1,34 @@ +/*- + * Copyright (c) 2004 Marius Strobl + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef OFW_OPTIONS_H +#define OFW_OPTIONS_H + +void ofwo_dump(void); +int ofwo_action(const char *prop, const char *val); + +#endif /* OFW_OPTIONS_H */ |