summaryrefslogtreecommitdiffstats
path: root/sbin
diff options
context:
space:
mode:
Diffstat (limited to 'sbin')
-rw-r--r--sbin/devd/devd.cc5
-rw-r--r--sbin/devfs/devfs.85
-rw-r--r--sbin/mount/Makefile2
-rw-r--r--sbin/mount/mount.83
-rw-r--r--sbin/mount/mount.c5
-rw-r--r--sbin/mount/mount.conf.8252
-rw-r--r--sbin/mount_nfs/mount_nfs.826
-rw-r--r--sbin/nvmecontrol/devlist.c27
-rw-r--r--sbin/nvmecontrol/firmware.c156
-rw-r--r--sbin/nvmecontrol/identify.c61
-rw-r--r--sbin/nvmecontrol/logpage.c103
-rw-r--r--sbin/nvmecontrol/nvmecontrol.c83
-rw-r--r--sbin/nvmecontrol/nvmecontrol.h3
-rw-r--r--sbin/nvmecontrol/perftest.c15
-rw-r--r--sbin/nvmecontrol/reset.c14
-rw-r--r--sbin/recoverdisk/recoverdisk.16
-rw-r--r--sbin/route/Makefile19
-rw-r--r--sbin/route/route.c558
18 files changed, 777 insertions, 566 deletions
diff --git a/sbin/devd/devd.cc b/sbin/devd/devd.cc
index 0f11a83..447ab87 100644
--- a/sbin/devd/devd.cc
+++ b/sbin/devd/devd.cc
@@ -124,7 +124,8 @@ static volatile sig_atomic_t romeo_must_die = 0;
static const char *configfile = CF;
-static void devdlog(int priority, const char* message, ...);
+static void devdlog(int priority, const char* message, ...)
+ __printflike(2, 3);
static void event_loop(void);
static void usage(void);
@@ -969,7 +970,7 @@ event_loop(void)
}
rv = select(max_fd, &fds, NULL, NULL, &tv);
if (got_siginfo) {
- devdlog(LOG_INFO, "Events received so far=%ld\n",
+ devdlog(LOG_INFO, "Events received so far=%u\n",
total_events);
got_siginfo = 0;
}
diff --git a/sbin/devfs/devfs.8 b/sbin/devfs/devfs.8
index 6e0c210..8bbdfcc 100644
--- a/sbin/devfs/devfs.8
+++ b/sbin/devfs/devfs.8
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd April 21, 2013
+.Dd July 12, 2013
.Dt DEVFS 8
.Os
.Sh NAME
@@ -190,6 +190,7 @@ Nodes may later be revived manually with
or with the
.Cm unhide
action.
+Hiding a directory node effectively hides all of its child nodes.
.It Cm include Ar ruleset
Apply all the rules in ruleset number
.Ar ruleset
@@ -213,6 +214,8 @@ which may be a user name
or number.
.It Cm unhide
Unhide the node.
+If the node resides in a subdirectory,
+all parent directory nodes must be visible to be able to access the node.
.El
.Sh IMPLEMENTATION NOTES
Rulesets are created by the kernel at the first reference
diff --git a/sbin/mount/Makefile b/sbin/mount/Makefile
index 8f6299a..c4d98f0 100644
--- a/sbin/mount/Makefile
+++ b/sbin/mount/Makefile
@@ -3,7 +3,7 @@
PROG= mount
SRCS= mount.c mount_fs.c getmntopts.c vfslist.c
-MAN= mount.8
+MAN= mount.8 mount.conf.8
# We do NOT install the getmntopts.3 man page.
DPADD= ${LIBUTIL}
diff --git a/sbin/mount/mount.8 b/sbin/mount/mount.8
index 5b670ee..50c5a8b 100644
--- a/sbin/mount/mount.8
+++ b/sbin/mount/mount.8
@@ -118,6 +118,9 @@ When used in conjunction with the
.Fl a
option, also mount those file systems which are marked as
.Dq Li late .
+.It Fl n
+For compatibility with some other implementations, this flag is
+currently a no-op.
.It Fl o
Options are specified with a
.Fl o
diff --git a/sbin/mount/mount.c b/sbin/mount/mount.c
index 6284822..91c7d7c 100644
--- a/sbin/mount/mount.c
+++ b/sbin/mount/mount.c
@@ -253,7 +253,7 @@ main(int argc, char *argv[])
options = NULL;
vfslist = NULL;
vfstype = "ufs";
- while ((ch = getopt(argc, argv, "adF:fLlo:prt:uvw")) != -1)
+ while ((ch = getopt(argc, argv, "adF:fLlno:prt:uvw")) != -1)
switch (ch) {
case 'a':
all = 1;
@@ -274,6 +274,9 @@ main(int argc, char *argv[])
case 'l':
late = 1;
break;
+ case 'n':
+ /* For compatibility with the Linux version of mount. */
+ break;
case 'o':
if (*optarg) {
options = catopt(options, optarg);
diff --git a/sbin/mount/mount.conf.8 b/sbin/mount/mount.conf.8
new file mode 100644
index 0000000..c3296c3
--- /dev/null
+++ b/sbin/mount/mount.conf.8
@@ -0,0 +1,252 @@
+.\" Copyright (c) 2013 Marcel Moolenaar
+.\" Copyright (c) 2013 Craig Rodrigues
+.\" 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 AUTHORS 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 AUTHORS 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$
+.\"
+.\"
+.Dd July 7, 2013
+.Dt MOUNT.CONF 8
+.Os
+.Sh NAME
+.Nm mount.conf
+.Nd root file system mount configuration file
+.Sh SYNOPSIS
+.Pa /.mount.conf
+.Sh DESCRIPTION
+During the bootup process, the
+.Fx
+kernel will try to mount the root file system
+using the logic in the
+.Fn vfs_mountroot
+function in
+.Pa src/sys/kern/vfs_mountroot.c .
+The root mount logic can be described as follows:
+.Bl -enum
+.It
+The kernel will synthesize in memory a config file
+with default directives for mounting
+the root file system.
+The logic for this is in
+.Fn vfs_mountroot_conf0 .
+.It
+The kernel will first mount
+.Xr devfs 8
+as the root file system.
+.It
+Next, the kernel will parse the in-memory config file created in step 1
+and try to mount the actual root file system.
+See
+.Sx FILE FORMAT
+for the format of the config file.
+.It
+When the actual root file system is mounted,
+.Xr devfs
+will be re-mounted on the
+.Pa /dev
+directory.
+.It
+If a
+.Pa /.mount.conf
+file does not exist in the root file system which was
+just mounted, the root mount logic stops here.
+.It
+If a
+.Pa /.mount.conf
+file exists in the root file system which was just mounted,
+this file will be parsed, and the kernel will use this new config
+file to try to re-mount the root file system.
+See
+.Sx FILE FORMAT
+for the format of the config file.
+.It
+If the new root file system has a
+.Pa /.mount
+directory, the old root file system will be re-mounted
+on
+.Pa /.mount .
+.It
+The root mount logic will go back to step 4.
+.El
+.Pp
+The root mount logic is recursive, and step 8 will
+be repeated as long as each new root file system
+which is mounted has a
+.Pa /.mount.conf
+file.
+.Sh FILE FORMAT
+The kernel parses each line in
+.Pa .mount.conf
+and then tries to perform the action specified on that line as soon as it is parsed.
+.Bl -tag -width "XXXXXXXXXX"
+.It Ic #
+A line beginning with a # is a comment and is ignored.
+.It Ic {FS}:{MOUNTPOINT} {OPTIONS}
+The kernel will try to mount this in an
+operation equivalent to:
+.Bd -literal -offset indent
+mount -t {FS} -o {OPTIONS} {MOUNTPOINT} /
+.Ed
+.Pp
+If this is successfully mounted,
+further lines in
+.Pa .mount.conf
+are ignored.
+If all lines in
+.Pa .mount.conf
+have been processed and no root file system has been successfully
+mounted, then the action specified by
+.Ic .onfail
+is performed.
+.It Ic .ask
+When the kernel processes this line, a
+.Li mountroot>
+command-line prompt is displayed.
+At this prompt, the operator can enter the
+the root mount.
+.It Ic .md Ar file
+Create a memory backed
+.Xr md 4
+virtual disk, using
+.Ar file
+as the backing store.
+.It Ic .onfail Ar [panic|reboot|retry|continue]
+If after parsing all the lines in
+.Pa .mount.conf
+the kernel is unable to mount a root file system,
+the
+.Ic .onfail
+directive tells the kernel what action to perform.
+.It Ic .timeout Ar N
+Before trying to mount a root file system,
+if the root mount device does not exist, wait at most
+.Ar N
+seconds for the device to appear before trying to mount it.
+If
+.Ic .timeout
+is not specified, the default timeout is 3 seconds.
+.El
+.Sh EXAMPLES
+The following example
+.Pa .mount.conf
+will direct the kernel to try mounting the root file system
+first as an ISO CD9660 file system on
+.Pa /dev/cd0 ,
+then if that does not work, as an ISO CD9660 file system on
+.Pa /dev/acd0 ,
+and then if that does not work, as a UFS file system on
+.Pa /dev/ada0s1a .
+If that does not work, a
+.Li mountroot>
+command-line prompt will be displayed where the operator
+can manually enter the root file system to mount.
+Finally if that does not work, the kernel will panic.
+.Bd -literal -offset indent
+.Li .onfail panic
+.Li .timeout 3
+cd9660:/dev/cd0 ro
+.Li .timeout 0
+cd9660:/dev/acd0 ro
+.Li .timeout 3
+ufs:/dev/ada0s1a
+.Li .ask
+.Ed
+.Pp
+The following example
+.Pa .mount.conf
+will direct the kernel to create a
+.Xr md 4
+memory disk attached to the file
+.Pa /data/OS-1.0.iso
+and then mount the ISO CD9660 file system
+on the md device which was just created.
+The last line is a comment which is ignored.
+.Bd -literal -offset indent
+.Li .timeout 3
+.Li .md /data/OS-1.0.iso
+.Li cd9600:/dev/md# ro
+.Li # Can also use cd9660:/dev/md0 ro
+.Ed
+.Pp
+The following example
+.Pa .mount.conf
+will direct the kernel to create a
+.Xr md 4
+memory disk attached to the file
+.Pa /data/base.ufs.uzip
+and then mount the UFS file system
+on the md uzip device which was just created
+by the
+.Xr geom_uzip 4
+driver.
+.Bd -literal -offset indent
+.Li .md /data/base.ufs.uzip
+.Li ufs:/dev/md#.uzip ro
+.Li # Can also use ufs:/dev/md0.uzip ro
+.Ed
+.Pp
+The following example
+.Pa .mount.conf
+will direct the kernel to do a unionfs
+mount on a directory
+.Pa /jail/freebsd-8-stable
+which has a
+.Xr chroot 2
+environment.
+.Bd -literal -offset indent
+.Li .timeout 3
+.Li unionfs:/jail/freebsd-8-stable
+.Ed
+.Sh NOTES
+For each root file system which is mounted, a
+.Pa /dev
+directory
+.Em must
+exist so that the root mount logic can properly re-mount
+.Xr devfs 8 .
+If this directory does not exist, the system
+may hang during the bootup process.
+.Sh SEE ALSO
+.Xr nmount 2 ,
+.Xr md 4 ,
+.Xr boot.config 5 ,
+.Xr fstab 5 ,
+.Xr boot 8 ,
+.Xr loader 8 ,
+.Xr mount 8
+.Sh HISTORY
+The
+.Nm
+file first appeared in
+.Fx 9.0 .
+.Sh AUTHORS
+.An -nosplit
+The root mount logic in the
+.Fx
+kernel which parses
+.Pa /.mount.conf
+was written by
+.An Marcel Moolenaar Aq marcel@FreeBSD.org .
+This man page was written by
+.An Craig Rodrigues Aq rodrigc@FreeBSD.org .
diff --git a/sbin/mount_nfs/mount_nfs.8 b/sbin/mount_nfs/mount_nfs.8
index 26ed091..216b248 100644
--- a/sbin/mount_nfs/mount_nfs.8
+++ b/sbin/mount_nfs/mount_nfs.8
@@ -28,7 +28,7 @@
.\" @(#)mount_nfs.8 8.3 (Berkeley) 3/29/95
.\" $FreeBSD$
.\"
-.Dd December 9, 2012
+.Dd July 8, 2013
.Dt MOUNT_NFS 8
.Os
.Sh NAME
@@ -118,6 +118,13 @@ for regular files, and 30 -> 60 seconds for directories.
The algorithm to calculate the timeout is based on the age of the file.
The older the file,
the longer the cache is considered valid, subject to the limits above.
+.It Cm allgssname
+This option can be used along with
+.Fl o Cm gssname
+to specify that all operations should use the host-based initiator
+credential.
+This may be used for clients that run system daemons that need to
+access files on the NFSv4 mounted volume.
.It Cm bg
If an initial attempt to contact the server fails, fork off a child to keep
trying the mount in the background.
@@ -138,6 +145,23 @@ short.
.It Cm fg
Same as not specifying
.Cm bg .
+.It Cm gssname Ns = Ns Aq Ar service-principal-name
+This option can be used with the KerberosV security flavors for NFSv4 mounts
+to specify the
+.Dq "service-principal-name"
+of a host-based entry in the default
+keytab file that is used for system operations.
+It allows the mount to be performed by
+.Dq "root"
+and avoids problems with
+cached credentials for the system operations expiring.
+The
+.Dq "service-prinicpal-name"
+should be specified without instance or domain and is typically
+.Dq "host" ,
+.Dq "nfs"
+or
+.Dq "root" .
.It Cm hard
Same as not specifying
.Cm soft .
diff --git a/sbin/nvmecontrol/devlist.c b/sbin/nvmecontrol/devlist.c
index 8c99c99..29c0475 100644
--- a/sbin/nvmecontrol/devlist.c
+++ b/sbin/nvmecontrol/devlist.c
@@ -29,13 +29,14 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <err.h>
#include <errno.h>
#include <fcntl.h>
+#include <paths.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sysexits.h>
#include <unistd.h>
#include "nvmecontrol.h"
@@ -45,7 +46,7 @@ devlist_usage(void)
{
fprintf(stderr, "usage:\n");
fprintf(stderr, DEVLIST_USAGE);
- exit(EX_USAGE);
+ exit(1);
}
static inline uint32_t
@@ -62,9 +63,7 @@ devlist(int argc, char *argv[])
struct nvme_namespace_data nsdata;
char name[64];
uint32_t i;
- int ch, ctrlr, exit_code, fd, found;
-
- exit_code = EX_OK;
+ int ch, ctrlr, fd, found, ret;
while ((ch = getopt(argc, argv, "")) != -1) {
switch ((char)ch) {
@@ -80,19 +79,19 @@ devlist(int argc, char *argv[])
ctrlr++;
sprintf(name, "%s%d", NVME_CTRLR_PREFIX, ctrlr);
- exit_code = open_dev(name, &fd, 0, 0);
+ ret = open_dev(name, &fd, 0, 0);
- if (exit_code == EX_NOINPUT)
- break;
- else if (exit_code == EX_NOPERM) {
- printf("Could not open /dev/%s, errno = %d (%s)\n",
- name, errno, strerror(errno));
- continue;
+ if (ret != 0) {
+ if (ret == EACCES) {
+ warnx("could not open "_PATH_DEV"%s\n", name);
+ continue;
+ } else
+ break;
}
found++;
read_controller_data(fd, &cdata);
- printf("%6s: %s\n", name, cdata.mn);
+ printf("%6s: %.*s\n", name, NVME_MODEL_NUMBER_LENGTH, cdata.mn);
for (i = 0; i < cdata.nn; i++) {
sprintf(name, "%s%d%s%d", NVME_CTRLR_PREFIX, ctrlr,
@@ -111,5 +110,5 @@ devlist(int argc, char *argv[])
if (found == 0)
printf("No NVMe controllers found.\n");
- exit(EX_OK);
+ exit(1);
}
diff --git a/sbin/nvmecontrol/firmware.c b/sbin/nvmecontrol/firmware.c
index 4678301..cb7fb0f 100644
--- a/sbin/nvmecontrol/firmware.c
+++ b/sbin/nvmecontrol/firmware.c
@@ -36,14 +36,14 @@ __FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <ctype.h>
-#include <errno.h>
+#include <err.h>
#include <fcntl.h>
+#include <inttypes.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sysexits.h>
#include <unistd.h>
#include "nvmecontrol.h"
@@ -64,60 +64,58 @@ slot_has_valid_firmware(int fd, int slot)
}
static void
-read_image_file(char *path, void **buf, ssize_t *size)
+read_image_file(char *path, void **buf, int32_t *size)
{
struct stat sb;
+ int32_t filesize;
int fd;
*size = 0;
*buf = NULL;
- if ((fd = open(path, O_RDONLY)) < 0) {
- fprintf(stderr, "Unable to open '%s'.\n", path);
- exit(EX_IOERR);
- }
- if (fstat(fd, &sb) < 0) {
- fprintf(stderr, "Unable to stat '%s'.\n", path);
- close(fd);
- exit(EX_IOERR);
- }
- if ((*buf = malloc(sb.st_size)) == NULL) {
- fprintf(stderr, "Unable to malloc %jd bytes.\n",
- sb.st_size);
- close(fd);
- exit(EX_IOERR);
- }
- if ((*size = read(fd, *buf, sb.st_size)) < 0) {
- fprintf(stderr, "Error reading '%s', errno=%d (%s)\n",
- path, errno, strerror(errno));
- close(fd);
- exit(EX_IOERR);
- }
- if (*size != sb.st_size) {
- fprintf(stderr, "Error reading '%s', "
- "read %zd bytes, requested %jd bytes\n",
- path, *size, sb.st_size);
- close(fd);
- exit(EX_IOERR);
- }
+ if ((fd = open(path, O_RDONLY)) < 0)
+ err(1, "unable to open '%s'", path);
+ if (fstat(fd, &sb) < 0)
+ err(1, "unable to stat '%s'", path);
+
+ /*
+ * The NVMe spec does not explicitly state a maximum firmware image
+ * size, although one can be inferred from the dword size limitation
+ * for the size and offset fields in the Firmware Image Download
+ * command.
+ *
+ * Technically, the max is UINT32_MAX * sizeof(uint32_t), since the
+ * size and offsets are specified in terms of dwords (not bytes), but
+ * realistically INT32_MAX is sufficient here and simplifies matters
+ * a bit.
+ */
+ if (sb.st_size > INT32_MAX)
+ errx(1, "size of file '%s' is too large (%jd bytes)",
+ path, (intmax_t)sb.st_size);
+ filesize = (int32_t)sb.st_size;
+ if ((*buf = malloc(filesize)) == NULL)
+ errx(1, "unable to malloc %d bytes", filesize);
+ if ((*size = read(fd, *buf, filesize)) < 0)
+ err(1, "error reading '%s'", path);
+ /* XXX assuming no short reads */
+ if (*size != filesize)
+ errx(1,
+ "error reading '%s' (read %d bytes, requested %d bytes)",
+ path, *size, filesize);
}
static void
-update_firmware(int fd, uint8_t *payload, uint32_t payload_size)
+update_firmware(int fd, uint8_t *payload, int32_t payload_size)
{
struct nvme_pt_command pt;
- size_t size;
+ int32_t off, resid, size;
void *chunk;
- uint32_t off, resid;
- int exit_code = EX_OK;
off = 0;
resid = payload_size;
- if ((chunk = malloc((size_t)NVME_MAX_XFER_SIZE)) == NULL) {
- printf("Unable to malloc %d bytes.\n", NVME_MAX_XFER_SIZE);
- exit(EX_IOERR);
- }
+ if ((chunk = malloc(NVME_MAX_XFER_SIZE)) == NULL)
+ errx(1, "unable to malloc %d bytes", NVME_MAX_XFER_SIZE);
while (resid > 0) {
size = (resid >= NVME_MAX_XFER_SIZE) ?
@@ -132,26 +130,15 @@ update_firmware(int fd, uint8_t *payload, uint32_t payload_size)
pt.len = size;
pt.is_read = 0;
- if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) {
- printf("Firmware image download request failed. "
- "errno=%d (%s)\n",
- errno, strerror(errno));
- exit_code = EX_IOERR;
- break;
- }
+ if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
+ err(1, "firmware download request failed");
- if (nvme_completion_is_error(&pt.cpl)) {
- printf("Passthrough command returned error.\n");
- exit_code = EX_IOERR;
- break;
- }
+ if (nvme_completion_is_error(&pt.cpl))
+ errx(1, "firmware download request returned error");
resid -= size;
off += size;
}
-
- if (exit_code != EX_OK)
- exit(exit_code);
}
static void
@@ -164,16 +151,11 @@ activate_firmware(int fd, int slot, int activate_action)
pt.cmd.cdw10 = (activate_action << 3) | slot;
pt.is_read = 0;
- if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) {
- printf("Firmware activate request failed. errno=%d (%s)\n",
- errno, strerror(errno));
- exit(EX_IOERR);
- }
+ if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
+ err(1, "firmware activate request failed");
- if (nvme_completion_is_error(&pt.cpl)) {
- printf("Passthrough command returned error.\n");
- exit(EX_IOERR);
- }
+ if (nvme_completion_is_error(&pt.cpl))
+ errx(1, "firmware activate request returned error");
}
static void
@@ -181,7 +163,7 @@ firmware_usage(void)
{
fprintf(stderr, "usage:\n");
fprintf(stderr, FIRMWARE_USAGE);
- exit(EX_USAGE);
+ exit(1);
}
void
@@ -192,7 +174,7 @@ firmware(int argc, char *argv[])
char ch, *p, *image = NULL;
char *controller = NULL, prompt[64];
void *buf = NULL;
- ssize_t size;
+ int32_t size = 0;
struct nvme_controller_data cdata;
a_flag = s_flag = f_flag = false;
@@ -252,34 +234,27 @@ firmware(int argc, char *argv[])
open_dev(controller, &fd, 1, 1);
read_controller_data(fd, &cdata);
- if (cdata.oacs.firmware == 0) {
- fprintf(stderr,
- "Controller does not support firmware "
- "activate/download.\n");
- exit(EX_IOERR);
- }
+ if (cdata.oacs.firmware == 0)
+ errx(1,
+ "controller does not support firmware activate/download");
- if (f_flag && slot == 1 && cdata.frmw.slot1_ro) {
- fprintf(stderr, "Slot %d is marked as read only.\n", slot);
- exit(EX_IOERR);
- }
+ if (f_flag && slot == 1 && cdata.frmw.slot1_ro)
+ errx(1, "slot %d is marked as read only", slot);
- if (slot > cdata.frmw.num_slots) {
- fprintf(stderr,
- "Slot %d was specified but controller only "
- "supports %d firmware slots.\n",
+ if (slot > cdata.frmw.num_slots)
+ errx(1,
+ "slot %d specified but controller only supports %d slots",
slot, cdata.frmw.num_slots);
- exit(EX_IOERR);
- }
- if (!slot_has_valid_firmware(fd, slot)) {
- fprintf(stderr,
- "Slot %d does not contain valid firmware.\n"
- "Try 'nvmecontrol logpage -p 3 %s' to get a list "
- "of available firmware images.\n",
+ if (a_flag && !f_flag && !slot_has_valid_firmware(fd, slot))
+ errx(1,
+ "slot %d does not contain valid firmware,\n"
+ "try 'nvmecontrol logpage -p 3 %s' to get a list "
+ "of available images\n",
slot, controller);
- exit(EX_IOERR);
- }
+
+ if (f_flag)
+ read_image_file(image, &buf, &size);
if (f_flag && a_flag)
printf("You are about to download and activate "
@@ -305,12 +280,11 @@ firmware(int argc, char *argv[])
if (strncasecmp(prompt, "yes", 3) == 0)
break;
if (strncasecmp(prompt, "no", 2) == 0)
- exit(EX_OK);
+ exit(1);
printf("Please answer \"yes\" or \"no\". ");
}
if (f_flag) {
- read_image_file(image, &buf, &size);
update_firmware(fd, buf, size);
if (a_flag)
activate_firmware(fd, slot,
@@ -331,5 +305,5 @@ firmware(int argc, char *argv[])
}
close(fd);
- exit(EX_OK);
+ exit(0);
}
diff --git a/sbin/nvmecontrol/identify.c b/sbin/nvmecontrol/identify.c
index afe5ac0..6585430 100644
--- a/sbin/nvmecontrol/identify.c
+++ b/sbin/nvmecontrol/identify.c
@@ -30,13 +30,12 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <ctype.h>
-#include <errno.h>
+#include <err.h>
#include <fcntl.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sysexits.h>
#include <unistd.h>
#include "nvmecontrol.h"
@@ -48,9 +47,12 @@ print_controller(struct nvme_controller_data *cdata)
printf("================================\n");
printf("Vendor ID: %04x\n", cdata->vid);
printf("Subsystem Vendor ID: %04x\n", cdata->ssvid);
- printf("Serial Number: %s\n", cdata->sn);
- printf("Model Number: %s\n", cdata->mn);
- printf("Firmware Version: %s\n", cdata->fr);
+ printf("Serial Number: %.*s\n",
+ NVME_SERIAL_NUMBER_LENGTH, cdata->sn);
+ printf("Model Number: %.*s\n",
+ NVME_MODEL_NUMBER_LENGTH, cdata->mn);
+ printf("Firmware Version: %.*s\n",
+ NVME_FIRMWARE_REVISION_LENGTH, cdata->fr);
printf("Recommended Arb Burst: %d\n", cdata->rab);
printf("IEEE OUI Identifier: %02x %02x %02x\n",
cdata->ieee[0], cdata->ieee[1], cdata->ieee[2]);
@@ -125,13 +127,11 @@ print_namespace(struct nvme_namespace_data *nsdata)
printf("Thin Provisioning: %s\n",
nsdata->nsfeat.thin_prov ? "Supported" : "Not Supported");
printf("Number of LBA Formats: %d\n", nsdata->nlbaf+1);
- printf("Current LBA Format: LBA Format #%d\n",
+ printf("Current LBA Format: LBA Format #%02d\n",
nsdata->flbas.format);
- for (i = 0; i <= nsdata->nlbaf; i++) {
- printf("LBA Format #%d:\n", i);
- printf(" LBA Data Size: %d\n",
- 1 << nsdata->lbaf[i].lbads);
- }
+ for (i = 0; i <= nsdata->nlbaf; i++)
+ printf("LBA Format #%02d: Data Size: %5d Metadata Size: %5d\n",
+ i, 1 << nsdata->lbaf[i].lbads, nsdata->lbaf[i].ms);
}
static void
@@ -139,7 +139,7 @@ identify_usage(void)
{
fprintf(stderr, "usage:\n");
fprintf(stderr, IDENTIFY_USAGE);
- exit(EX_USAGE);
+ exit(1);
}
static void
@@ -177,16 +177,16 @@ identify_ctrlr(int argc, char *argv[])
hexlength = offsetof(struct nvme_controller_data,
reserved5);
print_hex(&cdata, hexlength);
- exit(EX_OK);
+ exit(0);
}
if (verboseflag == 1) {
- printf("-v not currently supported without -x.\n");
+ fprintf(stderr, "-v not currently supported without -x\n");
identify_usage();
}
print_controller(&cdata);
- exit(EX_OK);
+ exit(0);
}
static void
@@ -194,7 +194,6 @@ identify_ns(int argc, char *argv[])
{
struct nvme_namespace_data nsdata;
char path[64];
- char *nsloc;
int ch, fd, hexflag = 0, hexlength, nsid;
int verboseflag = 0;
@@ -224,24 +223,12 @@ identify_ns(int argc, char *argv[])
close(fd);
/*
- * Pull the namespace id from the string. +2 skips past the "ns" part
- * of the string. Don't search past 10 characters into the string,
- * otherwise we know it is malformed.
- */
- nsloc = strnstr(argv[optind], NVME_NS_PREFIX, 10);
- if (nsloc != NULL)
- nsid = strtol(nsloc + 2, NULL, 10);
- if (nsloc == NULL || (nsid == 0 && errno != 0)) {
- printf("Invalid namespace ID %s.\n", argv[optind]);
- exit(EX_IOERR);
- }
-
- /*
* We send IDENTIFY commands to the controller, not the namespace,
- * since it is an admin cmd. So the path should only include the
- * nvmeX part of the nvmeXnsY string.
+ * since it is an admin cmd. The namespace ID will be specified in
+ * the IDENTIFY command itself. So parse the namespace's device node
+ * string to get the controller substring and namespace ID.
*/
- snprintf(path, nsloc - argv[optind] + 1, "%s", argv[optind]);
+ parse_ns_str(argv[optind], path, &nsid);
open_dev(path, &fd, 1, 1);
read_namespace_data(fd, nsid, &nsdata);
close(fd);
@@ -253,16 +240,16 @@ identify_ns(int argc, char *argv[])
hexlength = offsetof(struct nvme_namespace_data,
reserved6);
print_hex(&nsdata, hexlength);
- exit(EX_OK);
+ exit(0);
}
if (verboseflag == 1) {
- printf("-v not currently supported without -x.\n");
+ fprintf(stderr, "-v not currently supported without -x\n");
identify_usage();
}
print_namespace(&nsdata);
- exit(EX_OK);
+ exit(0);
}
void
@@ -275,6 +262,10 @@ identify(int argc, char *argv[])
while (getopt(argc, argv, "vx") != -1) ;
+ /* Check that a controller or namespace was specified. */
+ if (optind >= argc)
+ identify_usage();
+
target = argv[optind];
optreset = 1;
diff --git a/sbin/nvmecontrol/logpage.c b/sbin/nvmecontrol/logpage.c
index dbc0e6b..e330988 100644
--- a/sbin/nvmecontrol/logpage.c
+++ b/sbin/nvmecontrol/logpage.c
@@ -34,14 +34,13 @@ __FBSDID("$FreeBSD$");
#include <sys/ioccom.h>
#include <ctype.h>
-#include <errno.h>
+#include <err.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sysexits.h>
#include <unistd.h>
#include "nvmecontrol.h"
@@ -52,14 +51,13 @@ __FBSDID("$FreeBSD$");
typedef void (*print_fn_t)(void *buf, uint32_t size);
static void *
-get_log_buffer(size_t size)
+get_log_buffer(uint32_t size)
{
void *buf;
- if ((buf = malloc(size)) == NULL) {
- fprintf(stderr, "Unable to malloc %zd bytes\n", size);
- exit(EX_IOERR);
- }
+ if ((buf = malloc(size)) == NULL)
+ errx(1, "unable to malloc %u bytes", size);
+
memset(buf, 0, size);
return (buf);
}
@@ -79,16 +77,11 @@ read_logpage(int fd, uint8_t log_page, int nsid, void *payload,
pt.len = payload_size;
pt.is_read = 1;
- if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) {
- printf("Get log page request failed. errno=%d (%s)\n",
- errno, strerror(errno));
- exit(EX_IOERR);
- }
+ if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
+ err(1, "get log page request failed");
- if (nvme_completion_is_error(&pt.cpl)) {
- printf("Passthrough command returned error.\n");
- exit(EX_IOERR);
- }
+ if (nvme_completion_is_error(&pt.cpl))
+ errx(1, "get log page request returned error");
}
static void
@@ -242,19 +235,18 @@ logpage_usage(void)
{
fprintf(stderr, "usage:\n");
fprintf(stderr, LOGPAGE_USAGE);
- exit(EX_USAGE);
+ exit(1);
}
void
logpage(int argc, char *argv[])
{
- int fd, nsid, len;
+ int fd, nsid;
int log_page = 0, pageflag = false;
- int hexflag = false;
- int allow_ns = false;
- char ch, *p, *nsloc = NULL;
- char *cname = NULL;
- size_t size;
+ int hexflag = false, ns_specified;
+ char ch, *p;
+ char cname[64];
+ uint32_t size;
void *buf;
struct logpage_function *f;
struct nvme_controller_data cdata;
@@ -296,54 +288,31 @@ logpage(int argc, char *argv[])
if (optind >= argc)
logpage_usage();
+ if (strstr(argv[optind], NVME_NS_PREFIX) != NULL) {
+ ns_specified = true;
+ parse_ns_str(argv[optind], cname, &nsid);
+ open_dev(cname, &fd, 1, 1);
+ } else {
+ ns_specified = false;
+ nsid = NVME_GLOBAL_NAMESPACE_TAG;
+ open_dev(argv[optind], &fd, 1, 1);
+ }
+
/*
* The log page attribtues indicate whether or not the controller
* supports the SMART/Health information log page on a per
* namespace basis.
*/
- cname = malloc(strlen(NVME_CTRLR_PREFIX) + 2);
- len = strlen(NVME_CTRLR_PREFIX) + 1;
- cname = strncpy(cname, argv[optind], len);
- open_dev(cname, &fd, 1, 1);
- read_controller_data(fd, &cdata);
-
- if (log_page == NVME_LOG_HEALTH_INFORMATION && cdata.lpa.ns_smart != 0)
- allow_ns = true;
-
- /* If a namespace id was specified, validate it's use */
- if (strstr(argv[optind], NVME_NS_PREFIX) != NULL) {
- if (!allow_ns) {
- if (log_page != NVME_LOG_HEALTH_INFORMATION) {
- fprintf(stderr,
- "Namespace ID not valid for log page %d.\n",
- log_page);
- } else if (cdata.lpa.ns_smart == 0) {
- fprintf(stderr,
- "Controller does not support per "
- "namespace SMART/Health information.\n");
- }
- close(fd);
- exit(EX_IOERR);
- }
- nsloc = strnstr(argv[optind], NVME_NS_PREFIX, 10);
- if (nsloc != NULL)
- nsid = strtol(nsloc + 2, NULL, 10);
- if (nsloc == NULL || (nsid == 0 && errno != 0)) {
- fprintf(stderr,
- "Invalid namespace ID %s.\n",
- argv[optind]);
- close(fd);
- exit(EX_IOERR);
- }
-
- /*
- * User is asking for per namespace log page information
- * so close the controller and open up the namespace.
- */
- close(fd);
- open_dev(argv[optind], &fd, 1, 1);
- } else
- nsid = NVME_GLOBAL_NAMESPACE_TAG;
+ if (ns_specified) {
+ if (log_page != NVME_LOG_HEALTH_INFORMATION)
+ errx(1, "log page %d valid only at controller level",
+ log_page);
+ read_controller_data(fd, &cdata);
+ if (cdata.lpa.ns_smart == 0)
+ errx(1,
+ "controller does not support per namespace "
+ "smart/health information");
+ }
print_fn = print_hex;
if (!hexflag) {
@@ -384,5 +353,5 @@ logpage(int argc, char *argv[])
print_fn(buf, size);
close(fd);
- exit(EX_OK);
+ exit(0);
}
diff --git a/sbin/nvmecontrol/nvmecontrol.c b/sbin/nvmecontrol/nvmecontrol.c
index c7452a1..4dee190 100644
--- a/sbin/nvmecontrol/nvmecontrol.c
+++ b/sbin/nvmecontrol/nvmecontrol.c
@@ -32,14 +32,15 @@ __FBSDID("$FreeBSD$");
#include <sys/stat.h>
#include <ctype.h>
+#include <err.h>
#include <errno.h>
#include <fcntl.h>
+#include <paths.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sysexits.h>
#include <unistd.h>
#include "nvmecontrol.h"
@@ -71,7 +72,7 @@ usage(void)
fprintf(stderr, "%s", f->usage);
f++;
}
- exit(EX_USAGE);
+ exit(1);
}
static void
@@ -134,16 +135,11 @@ read_controller_data(int fd, struct nvme_controller_data *cdata)
pt.len = sizeof(*cdata);
pt.is_read = 1;
- if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) {
- printf("Identify request failed. errno=%d (%s)\n",
- errno, strerror(errno));
- exit(EX_IOERR);
- }
+ if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
+ err(1, "identify request failed");
- if (nvme_completion_is_error(&pt.cpl)) {
- printf("Passthrough command returned error.\n");
- exit(EX_IOERR);
- }
+ if (nvme_completion_is_error(&pt.cpl))
+ errx(1, "identify request returned error");
}
void
@@ -158,58 +154,63 @@ read_namespace_data(int fd, int nsid, struct nvme_namespace_data *nsdata)
pt.len = sizeof(*nsdata);
pt.is_read = 1;
- if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) {
- printf("Identify request failed. errno=%d (%s)\n",
- errno, strerror(errno));
- exit(EX_IOERR);
- }
+ if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
+ err(1, "identify request failed");
- if (nvme_completion_is_error(&pt.cpl)) {
- printf("Passthrough command returned error.\n");
- exit(EX_IOERR);
- }
+ if (nvme_completion_is_error(&pt.cpl))
+ errx(1, "identify request returned error");
}
int
open_dev(const char *str, int *fd, int show_error, int exit_on_error)
{
- struct stat devstat;
char full_path[64];
if (!strnstr(str, NVME_CTRLR_PREFIX, strlen(NVME_CTRLR_PREFIX))) {
if (show_error)
- fprintf(stderr,
- "Controller/namespace IDs must begin with '%s'.\n",
+ warnx("controller/namespace ids must begin with '%s'",
NVME_CTRLR_PREFIX);
if (exit_on_error)
- exit(EX_USAGE);
- else
- return (EX_USAGE);
- }
-
- snprintf(full_path, sizeof(full_path), "/dev/%s", str);
- if (stat(full_path, &devstat) != 0) {
- if (show_error)
- fprintf(stderr, "Could not stat %s. errno=%d (%s)\n",
- full_path, errno, strerror(errno));
- if (exit_on_error)
- exit(EX_NOINPUT);
+ exit(1);
else
- return (EX_NOINPUT);
+ return (EINVAL);
}
+ snprintf(full_path, sizeof(full_path), _PATH_DEV"%s", str);
*fd = open(full_path, O_RDWR);
if (*fd < 0) {
if (show_error)
- fprintf(stderr, "Could not open %s. errno=%d (%s)\n",
- full_path, errno, strerror(errno));
+ warn("could not open %s", full_path);
if (exit_on_error)
- exit(EX_NOPERM);
+ exit(1);
else
- return (EX_NOPERM);
+ return (errno);
}
- return (EX_OK);
+ return (0);
+}
+
+void
+parse_ns_str(const char *ns_str, char *ctrlr_str, int *nsid)
+{
+ char *nsloc;
+
+ /*
+ * Pull the namespace id from the string. +2 skips past the "ns" part
+ * of the string. Don't search past 10 characters into the string,
+ * otherwise we know it is malformed.
+ */
+ nsloc = strnstr(ns_str, NVME_NS_PREFIX, 10);
+ if (nsloc != NULL)
+ *nsid = strtol(nsloc + 2, NULL, 10);
+ if (nsloc == NULL || (*nsid == 0 && errno != 0))
+ errx(1, "invalid namespace ID '%s'", ns_str);
+
+ /*
+ * The controller string will include only the nvmX part of the
+ * nvmeXnsY string.
+ */
+ snprintf(ctrlr_str, nsloc - ns_str + 1, "%s", ns_str);
}
int
diff --git a/sbin/nvmecontrol/nvmecontrol.h b/sbin/nvmecontrol/nvmecontrol.h
index f7a35b4..8401dd7 100644
--- a/sbin/nvmecontrol/nvmecontrol.h
+++ b/sbin/nvmecontrol/nvmecontrol.h
@@ -38,7 +38,7 @@
" nvmecontrol devlist\n"
#define IDENTIFY_USAGE \
-" nvmecontrol identify <controller id|namespace id>\n"
+" nvmecontrol identify [-x [-v]] <controller id|namespace id>\n"
#define PERFTEST_USAGE \
" nvmecontrol perftest <-n num_threads> <-o read|write>\n" \
@@ -63,6 +63,7 @@ void logpage(int argc, char *argv[]);
void firmware(int argc, char *argv[]);
int open_dev(const char *str, int *fd, int show_error, int exit_on_error);
+void parse_ns_str(const char *ns_str, char *ctrlr_str, int *nsid);
void read_controller_data(int fd, struct nvme_controller_data *cdata);
void read_namespace_data(int fd, int nsid, struct nvme_namespace_data *nsdata);
void print_hex(void *data, uint32_t length);
diff --git a/sbin/nvmecontrol/perftest.c b/sbin/nvmecontrol/perftest.c
index c69da79..a7339bf 100644
--- a/sbin/nvmecontrol/perftest.c
+++ b/sbin/nvmecontrol/perftest.c
@@ -31,14 +31,13 @@ __FBSDID("$FreeBSD$");
#include <sys/ioccom.h>
#include <ctype.h>
-#include <errno.h>
+#include <err.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sysexits.h>
#include <unistd.h>
#include "nvmecontrol.h"
@@ -72,7 +71,7 @@ perftest_usage(void)
{
fprintf(stderr, "usage:\n");
fprintf(stderr, PERFTEST_USAGE);
- exit(EX_USAGE);
+ exit(1);
}
void
@@ -168,14 +167,10 @@ perftest(int argc, char *argv[])
perftest_usage();
open_dev(argv[optind], &fd, 1, 1);
- if (ioctl(fd, ioctl_cmd, &io_test) < 0) {
- fprintf(stderr, "NVME_IO_TEST failed. errno=%d (%s)\n", errno,
- strerror(errno));
- close(fd);
- exit(EX_IOERR);
- }
+ if (ioctl(fd, ioctl_cmd, &io_test) < 0)
+ err(1, "ioctl NVME_IO_TEST failed");
close(fd);
print_perftest(&io_test, perthread);
- exit(EX_OK);
+ exit(0);
}
diff --git a/sbin/nvmecontrol/reset.c b/sbin/nvmecontrol/reset.c
index a96722c..8ce597e 100644
--- a/sbin/nvmecontrol/reset.c
+++ b/sbin/nvmecontrol/reset.c
@@ -30,12 +30,11 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/ioccom.h>
-#include <errno.h>
+#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sysexits.h>
#include <unistd.h>
#include "nvmecontrol.h"
@@ -45,7 +44,7 @@ reset_usage(void)
{
fprintf(stderr, "usage:\n");
fprintf(stderr, RESET_USAGE);
- exit(EX_USAGE);
+ exit(1);
}
void
@@ -65,11 +64,8 @@ reset(int argc, char *argv[])
reset_usage();
open_dev(argv[optind], &fd, 1, 1);
- if (ioctl(fd, NVME_RESET_CONTROLLER) < 0) {
- printf("Reset request to %s failed. errno=%d (%s)\n",
- argv[optind], errno, strerror(errno));
- exit(EX_IOERR);
- }
+ if (ioctl(fd, NVME_RESET_CONTROLLER) < 0)
+ err(1, "reset request to %s failed", argv[optind]);
- exit(EX_OK);
+ exit(0);
}
diff --git a/sbin/recoverdisk/recoverdisk.1 b/sbin/recoverdisk/recoverdisk.1
index ef1241b..1661ab8 100644
--- a/sbin/recoverdisk/recoverdisk.1
+++ b/sbin/recoverdisk/recoverdisk.1
@@ -125,9 +125,9 @@ recoverdisk -b 0 /dev/ad3 /somewhere
.Ed
.Sh SEE ALSO
.Xr dd 1 ,
-.Xr ada 4,
-.Xr cam 4,
-.Xr cd 4,
+.Xr ada 4 ,
+.Xr cam 4 ,
+.Xr cd 4 ,
.Xr da 4
.Sh HISTORY
The
diff --git a/sbin/route/Makefile b/sbin/route/Makefile
index 0f4cd67..569d21a 100644
--- a/sbin/route/Makefile
+++ b/sbin/route/Makefile
@@ -7,24 +7,21 @@ PROG= route
MAN= route.8
SRCS= route.c keywords.h
WARNS?= 3
-CLEANFILES+=keywords.h _keywords.tmp
+CLEANFILES+=keywords.h
CFLAGS+= -DNS
-
+.if ${MK_INET_SUPPORT} != "no"
+CFLAGS+= -DINET
+.endif
.if ${MK_INET6_SUPPORT} != "no"
CFLAGS+= -DINET6
.endif
-
CFLAGS+= -I.
keywords.h: keywords
- sed -e '/^#/d' -e '/^$$/d' ${.CURDIR}/keywords > _keywords.tmp
- LC_ALL=C tr 'a-z' 'A-Z' < _keywords.tmp | paste _keywords.tmp - | \
- awk '{ \
- if (NF > 1) \
- printf "#define\tK_%s\t%d\n\t{\"%s\", K_%s},\n", \
- $$2, NR, $$1, $$2 }' \
- > ${.TARGET}
- rm -f _keywords.tmp
+ LC_ALL=C awk '!/^#|^$$/ { \
+ printf "#define\tK_%s\t%d\n\t{\"%s\", K_%s},\n", \
+ toupper($$1), ++L, $$1, toupper($$1); \
+ }' < ${.CURDIR}/keywords > ${.TARGET} || (rm -f ${.TARGET}; false)
.include <bsd.prog.mk>
diff --git a/sbin/route/route.c b/sbin/route/route.c
index c751657..b829bd2 100644
--- a/sbin/route/route.c
+++ b/sbin/route/route.c
@@ -70,7 +70,7 @@ __FBSDID("$FreeBSD$");
#include <unistd.h>
#include <ifaddrs.h>
-struct keytab {
+static struct keytab {
const char *kt_cp;
int kt_i;
} keywords[] = {
@@ -78,42 +78,33 @@ struct keytab {
{0, 0}
};
-union sockunion {
- struct sockaddr sa;
- struct sockaddr_in sin;
-#ifdef INET6
- struct sockaddr_in6 sin6;
-#endif
- struct sockaddr_at sat;
- struct sockaddr_dl sdl;
- struct sockaddr_storage ss; /* added to avoid memory overrun */
-} so_dst, so_gate, so_mask, so_genmask, so_ifa, so_ifp;
-
-typedef union sockunion *sup;
-int pid, rtm_addrs;
-int s;
-int forcehost, forcenet, doflush, nflag, af, qflag, tflag;
-int verbose, aflen = sizeof (struct sockaddr_in);
-int locking, lockrest, debugonly;
-struct rt_metrics rt_metrics;
-u_long rtm_inits;
-uid_t uid;
+static struct sockaddr_storage so[RTAX_MAX];
+static int pid, rtm_addrs;
+static int s;
+static int forcehost, forcenet, nflag, af, qflag, tflag;
+static int verbose, aflen;
+static int locking, lockrest, debugonly;
+static struct rt_metrics rt_metrics;
+static u_long rtm_inits;
+static uid_t uid;
static int defaultfib;
static int numfibs;
static int atalk_aton(const char *, struct at_addr *);
static char *atalk_ntoa(struct at_addr);
-static void bprintf(FILE *, int, u_char *);
+static void printb(int, const char *);
static void flushroutes(int argc, char *argv[]);
static int flushroutes_fib(int);
static int getaddr(int, char *, struct hostent **, int);
static int keyword(const char *);
-static void inet_makenetandmask(u_long, struct sockaddr_in *, u_long);
+#ifdef INET
+static void inet_makenetandmask(u_long, struct sockaddr_in *,
+ struct sockaddr_in *, u_long);
+#endif
#ifdef INET6
-static int inet6_makenetandmask(struct sockaddr_in6 *, const char *);
+static int inet6_makenetandmask(struct sockaddr_in6 *, const char *);
#endif
static void interfaces(void);
-static void mask_addr(void);
static void monitor(int, char*[]);
static const char *netname(struct sockaddr *);
static void newroute(int, char **);
@@ -127,9 +118,8 @@ static const char *routename(struct sockaddr *);
static int rtmsg(int, int, int);
static void set_metric(char *, int);
static int set_sofib(int);
-static int set_procfib(int);
-static void sockaddr(char *, struct sockaddr *);
-static void sodump(sup, const char *);
+static void sockaddr(char *, struct sockaddr *, size_t);
+static void sodump(struct sockaddr *, const char *);
extern char *iso_ntoa(void);
struct fibl {
@@ -139,7 +129,7 @@ struct fibl {
int fl_error;
int fl_errno;
};
-TAILQ_HEAD(fibl_head_t, fibl) fibl_head;
+static TAILQ_HEAD(fibl_head_t, fibl) fibl_head;
static int fiboptlist_csv(const char *, struct fibl_head_t *);
static int fiboptlist_range(const char *, struct fibl_head_t *);
@@ -151,9 +141,7 @@ usage(const char *cp)
{
if (cp != NULL)
warnx("bad keyword: %s", cp);
- (void) fprintf(stderr,
- "usage: route [-dnqtv] command [[modifiers] args]\n");
- exit(EX_USAGE);
+ errx(EX_USAGE, "usage: route [-dnqtv] command [[modifiers] args]");
/* NOTREACHED */
}
@@ -247,15 +235,6 @@ set_sofib(int fib)
}
static int
-set_procfib(int fib)
-{
-
- if (fib < 0)
- return (0);
- return (setfib(fib));
-}
-
-static int
fiboptlist_range(const char *arg, struct fibl_head_t *flh)
{
struct fibl *fl;
@@ -313,6 +292,7 @@ fiboptlist_csv(const char *arg, struct fibl_head_t *flh)
char *str0, *str, *token, *endptr;
int fib, error;
+ str0 = str = NULL;
if (strcmp("all", arg) == 0) {
str = calloc(1, ALLSTRLEN);
if (str == NULL) {
@@ -362,7 +342,8 @@ fiboptlist_csv(const char *arg, struct fibl_head_t *flh)
}
}
fiboptlist_csv_ret:
- free(str0);
+ if (str0 != NULL)
+ free(str0);
return (error);
}
@@ -376,9 +357,8 @@ flushroutes(int argc, char *argv[])
struct fibl *fl;
int error;
- if (uid != 0 && !debugonly && !tflag) {
+ if (uid != 0 && !debugonly && !tflag)
errx(EX_NOPERM, "must be root to alter routing table");
- }
shutdown(s, SHUT_RD); /* Don't want to read back our messages */
TAILQ_INIT(&fibl_head);
@@ -388,9 +368,11 @@ flushroutes(int argc, char *argv[])
if (**argv != '-')
usage(*argv);
switch (keyword(*argv + 1)) {
+#ifdef INET
case K_INET:
af = AF_INET;
break;
+#endif
#ifdef INET6
case K_INET6:
af = AF_INET6;
@@ -428,11 +410,10 @@ flushroutes_fib(int fib)
struct rt_msghdr *rtm;
size_t needed;
char *buf, *next, *lim;
- int mib[6], rlen, seqno, count = 0;
+ int mib[7], rlen, seqno, count = 0;
int error;
error = set_sofib(fib);
- error += set_procfib(fib);
if (error) {
warn("fib number %d is ignored", fib);
return (error);
@@ -442,14 +423,15 @@ retry:
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
mib[2] = 0; /* protocol */
- mib[3] = 0; /* wildcard address family */
+ mib[3] = AF_UNSPEC;
mib[4] = NET_RT_DUMP;
mib[5] = 0; /* no flags */
- if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
+ mib[6] = fib;
+ if (sysctl(mib, nitems(mib), NULL, &needed, NULL, 0) < 0)
err(EX_OSERR, "route-sysctl-estimate");
if ((buf = malloc(needed)) == NULL)
errx(EX_OSERR, "malloc failed");
- if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
+ if (sysctl(mib, nitems(mib), buf, &needed, NULL, 0) < 0) {
if (errno == ENOMEM && count++ < 10) {
warnx("Routing table grew, retrying");
sleep(1);
@@ -460,7 +442,7 @@ retry:
}
lim = buf + needed;
if (verbose)
- (void) printf("Examining routing table from sysctl\n");
+ (void)printf("Examining routing table from sysctl\n");
seqno = 0; /* ??? */
for (next = buf; next < lim; next += rtm->rtm_msglen) {
rtm = (struct rt_msghdr *)next;
@@ -483,7 +465,7 @@ retry:
err(1, "write to routing socket");
if (rlen < (int)rtm->rtm_msglen) {
warn("write to routing socket");
- (void) printf("got only %d for rlen\n", rlen);
+ (void)printf("got only %d for rlen\n", rlen);
free(buf);
goto retry;
break;
@@ -513,7 +495,9 @@ routename(struct sockaddr *sa)
{
const char *cp;
static char line[MAXHOSTNAMELEN + 1];
+#ifdef INET
struct hostent *hp;
+#endif
static char domain[MAXHOSTNAMELEN + 1];
static int first = 1, n;
@@ -522,19 +506,22 @@ routename(struct sockaddr *sa)
if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
(cp = strchr(domain, '.'))) {
domain[MAXHOSTNAMELEN] = '\0';
- (void) strcpy(domain, cp + 1);
+ (void)strcpy(domain, cp + 1);
} else
- domain[0] = 0;
+ domain[0] = '\0';
}
- if (sa->sa_len == 0)
+ if (sa->sa_len == 0) {
strcpy(line, "default");
- else switch (sa->sa_family) {
-
+ return (line);
+ }
+ switch (sa->sa_family) {
+#ifdef INET
case AF_INET:
- { struct in_addr in;
- in = ((struct sockaddr_in *)sa)->sin_addr;
+ {
+ struct in_addr in;
+ in = ((struct sockaddr_in *)sa)->sin_addr;
cp = NULL;
if (in.s_addr == INADDR_ANY || sa->sa_len < 4)
cp = "default";
@@ -554,10 +541,11 @@ routename(struct sockaddr *sa)
strncpy(line, cp, sizeof(line) - 1);
line[sizeof(line) - 1] = '\0';
} else
- (void) sprintf(line, "%s", inet_ntoa(in));
+ (void)sprintf(line, "%s", inet_ntoa(in));
break;
- }
+ }
+#endif
#ifdef INET6
case AF_INET6:
{
@@ -574,17 +562,18 @@ routename(struct sockaddr *sa)
line, sizeof(line), NULL, 0, niflags) != 0)
strncpy(line, "invalid", sizeof(line));
- return(line);
+ return (line);
}
#endif
case AF_APPLETALK:
- (void) snprintf(line, sizeof(line), "atalk %s",
- atalk_ntoa(((struct sockaddr_at *)sa)->sat_addr));
+ (void)snprintf(line, sizeof(line), "atalk %s",
+ atalk_ntoa(((struct sockaddr_at *)sa)->sat_addr));
break;
case AF_LINK:
return (link_ntoa((struct sockaddr_dl *)sa));
+ break;
default:
{
@@ -611,18 +600,21 @@ routename(struct sockaddr *sa)
const char *
netname(struct sockaddr *sa)
{
- const char *cp = NULL;
static char line[MAXHOSTNAMELEN + 1];
+ int n;
+#ifdef INET
struct netent *np = NULL;
+ const char *cp = NULL;
u_long i;
- int n;
+#endif
switch (sa->sa_family) {
-
+#ifdef INET
case AF_INET:
- { struct in_addr in;
- in = ((struct sockaddr_in *)sa)->sin_addr;
+ {
+ struct in_addr in;
+ in = ((struct sockaddr_in *)sa)->sin_addr;
i = in.s_addr = ntohl(in.s_addr);
if (in.s_addr == 0)
cp = "default";
@@ -635,30 +627,30 @@ netname(struct sockaddr *sa)
if (cp != NULL)
strncpy(line, cp, sizeof(line));
else if ((in.s_addr & 0xffffff) == 0)
- (void) sprintf(line, "%u", C(in.s_addr >> 24));
+ (void)sprintf(line, "%u", C(in.s_addr >> 24));
else if ((in.s_addr & 0xffff) == 0)
- (void) sprintf(line, "%u.%u", C(in.s_addr >> 24),
+ (void)sprintf(line, "%u.%u", C(in.s_addr >> 24),
C(in.s_addr >> 16));
else if ((in.s_addr & 0xff) == 0)
- (void) sprintf(line, "%u.%u.%u", C(in.s_addr >> 24),
+ (void)sprintf(line, "%u.%u.%u", C(in.s_addr >> 24),
C(in.s_addr >> 16), C(in.s_addr >> 8));
else
- (void) sprintf(line, "%u.%u.%u.%u", C(in.s_addr >> 24),
+ (void)sprintf(line, "%u.%u.%u.%u", C(in.s_addr >> 24),
C(in.s_addr >> 16), C(in.s_addr >> 8),
C(in.s_addr));
#undef C
break;
- }
-
+ }
+#endif
#ifdef INET6
case AF_INET6:
{
- struct sockaddr_in6 sin6; /* use static var for safety */
+ struct sockaddr_in6 sin6;
int niflags = 0;
memset(&sin6, 0, sizeof(sin6));
memcpy(&sin6, sa, sa->sa_len);
- sin6.sin6_len = sizeof(struct sockaddr_in6);
+ sin6.sin6_len = sizeof(sin6);
sin6.sin6_family = AF_INET6;
if (nflag)
niflags |= NI_NUMERICHOST;
@@ -671,13 +663,13 @@ netname(struct sockaddr *sa)
#endif
case AF_APPLETALK:
- (void) snprintf(line, sizeof(line), "atalk %s",
- atalk_ntoa(((struct sockaddr_at *)sa)->sat_addr));
+ (void)snprintf(line, sizeof(line), "atalk %s",
+ atalk_ntoa(((struct sockaddr_at *)sa)->sat_addr));
break;
case AF_LINK:
return (link_ntoa((struct sockaddr_dl *)sa));
-
+ break;
default:
{
@@ -738,10 +730,8 @@ newroute(int argc, char **argv)
const char *dest, *gateway, *errmsg;
int key, error, flags, nrflags, fibnum;
- if (uid != 0 && !debugonly && !tflag) {
+ if (uid != 0 && !debugonly && !tflag)
errx(EX_NOPERM, "must be root to alter routing table");
- }
-
dest = NULL;
gateway = NULL;
flags = RTF_STATIC;
@@ -752,7 +742,6 @@ newroute(int argc, char **argv)
cmd = argv[0];
if (*cmd != 'g' && *cmd != 's')
shutdown(s, SHUT_RD); /* Don't want to read back our messages */
-
while (--argc > 0) {
if (**(++argv)== '-') {
switch (key = keyword(1 + *argv)) {
@@ -760,10 +749,12 @@ newroute(int argc, char **argv)
af = AF_LINK;
aflen = sizeof(struct sockaddr_dl);
break;
+#ifdef INET
case K_INET:
af = AF_INET;
aflen = sizeof(struct sockaddr_in);
break;
+#endif
#ifdef INET6
case K_INET6:
af = AF_INET6;
@@ -776,7 +767,7 @@ newroute(int argc, char **argv)
break;
case K_SA:
af = PF_ROUTE;
- aflen = sizeof(union sockunion);
+ aflen = sizeof(struct sockaddr_storage);
break;
case K_IFACE:
case K_INTERFACE:
@@ -912,7 +903,7 @@ newroute(int argc, char **argv)
#ifdef INET6
if (af == AF_INET6) {
rtm_addrs &= ~RTA_NETMASK;
- memset((void *)&so_mask, 0, sizeof(so_mask));
+ memset(&so[RTAX_NETMASK], 0, sizeof(so[RTAX_NETMASK]));
}
#endif
}
@@ -1035,11 +1026,12 @@ newroute_fib(int fib, char *cmd, int flags)
return (error);
}
+#ifdef INET
static void
-inet_makenetandmask(u_long net, struct sockaddr_in *sin, u_long bits)
+inet_makenetandmask(u_long net, struct sockaddr_in *sin,
+ struct sockaddr_in *sin_mask, u_long bits)
{
u_long mask = 0;
- char *cp;
rtm_addrs |= RTA_NETMASK;
@@ -1056,7 +1048,8 @@ inet_makenetandmask(u_long net, struct sockaddr_in *sin, u_long bits)
*/
if ((bits == 0) && (net != 0)) {
u_long i, j;
- for(i=0,j=0xff; i<4; i++) {
+
+ for(i = 0, j = 0xff; i < 4; i++) {
if (net & j) {
break;
}
@@ -1069,15 +1062,11 @@ inet_makenetandmask(u_long net, struct sockaddr_in *sin, u_long bits)
mask = 0xffffffff << (32 - bits);
sin->sin_addr.s_addr = htonl(net);
- sin = &so_mask.sin;
- sin->sin_addr.s_addr = htonl(mask);
- sin->sin_len = 0;
- sin->sin_family = 0;
- cp = (char *)(&sin->sin_addr + 1);
- while (*--cp == 0 && cp > (char *)sin)
- ;
- sin->sin_len = 1 + cp - (char *)sin;
+ sin_mask->sin_addr.s_addr = htonl(mask);
+ sin_mask->sin_len = sizeof(struct sockaddr_in);
+ sin_mask->sin_family = AF_INET;
}
+#endif
#ifdef INET6
/*
@@ -1116,31 +1105,66 @@ inet6_makenetandmask(struct sockaddr_in6 *sin6, const char *plen)
static int
getaddr(int which, char *str, struct hostent **hpp, int nrflags)
{
- sup su;
+ struct sockaddr *sa;
+#if defined(INET)
+ struct sockaddr_in *sin;
struct hostent *hp;
struct netent *np;
u_long val;
char *q;
- int afamily; /* local copy of af so we can change it */
+#elif defined(INET6)
+ char *q;
+#endif
if (af == 0) {
+#if defined(INET)
af = AF_INET;
aflen = sizeof(struct sockaddr_in);
+#elif defined(INET6)
+ af = AF_INET6;
+ aflen = sizeof(struct sockaddr_in6);
+#else
+ af = AF_LINK;
+ aflen = sizeof(struct sockaddr_dl);
+#endif
}
- afamily = af;
rtm_addrs |= which;
+
switch (which) {
case RTA_DST:
- su = &so_dst;
+ sa = (struct sockaddr *)&so[RTAX_DST];
+ break;
+ case RTA_GATEWAY:
+ sa = (struct sockaddr *)&so[RTAX_GATEWAY];
+ break;
+ case RTA_NETMASK:
+ sa = (struct sockaddr *)&so[RTAX_NETMASK];
+ break;
+ case RTA_GENMASK:
+ sa = (struct sockaddr *)&so[RTAX_GENMASK];
+ break;
+ case RTA_IFA:
+ sa = (struct sockaddr *)&so[RTAX_IFA];
+ break;
+ case RTA_IFP:
+ sa = (struct sockaddr *)&so[RTAX_IFP];
break;
+ default:
+ usage("internal error");
+ /*NOTREACHED*/
+ }
+ sa->sa_family = af;
+ sa->sa_len = aflen;
+
+ switch (which) {
case RTA_GATEWAY:
- su = &so_gate;
if (nrflags & F_INTERFACE) {
struct ifaddrs *ifap, *ifa;
+ struct sockaddr_dl *sdl0 = (struct sockaddr_dl *)sa;
struct sockaddr_dl *sdl = NULL;
if (getifaddrs(&ifap))
- err(1, "getifaddrs");
+ err(EX_OSERR, "getifaddrs");
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
if (ifa->ifa_addr->sa_family != AF_LINK)
@@ -1154,37 +1178,20 @@ getaddr(int which, char *str, struct hostent **hpp, int nrflags)
/* If we found it, then use it */
if (sdl != NULL) {
/*
- * Copy is safe since we have a
- * sockaddr_storage member in sockunion{}.
* Note that we need to copy before calling
* freeifaddrs().
*/
- memcpy(&su->sdl, sdl, sdl->sdl_len);
+ memcpy(sdl0, sdl, sdl->sdl_len);
}
freeifaddrs(ifap);
if (sdl != NULL)
return(1);
}
break;
- case RTA_NETMASK:
- su = &so_mask;
- break;
- case RTA_GENMASK:
- su = &so_genmask;
- break;
case RTA_IFP:
- su = &so_ifp;
- afamily = AF_LINK;
- break;
- case RTA_IFA:
- su = &so_ifa;
+ sa->sa_family = AF_LINK;
break;
- default:
- usage("internal error");
- /*NOTREACHED*/
}
- su->sa.sa_len = aflen;
- su->sa.sa_family = afamily; /* cases that don't want it have left already */
if (strcmp(str, "default") == 0) {
/*
* Default is net 0.0.0.0/0
@@ -1192,20 +1199,12 @@ getaddr(int which, char *str, struct hostent **hpp, int nrflags)
switch (which) {
case RTA_DST:
forcenet++;
-#if 0
- bzero(su, sizeof(*su)); /* for readability */
-#endif
getaddr(RTA_NETMASK, str, 0, nrflags);
break;
-#if 0
- case RTA_NETMASK:
- case RTA_GENMASK:
- bzero(su, sizeof(*su)); /* for readability */
-#endif
}
return (0);
}
- switch (afamily) {
+ switch (sa->sa_family) {
#ifdef INET6
case AF_INET6:
{
@@ -1216,46 +1215,48 @@ getaddr(int which, char *str, struct hostent **hpp, int nrflags)
if (which == RTA_DST && (q = strchr(str, '/')) != NULL)
*q = '\0';
memset(&hints, 0, sizeof(hints));
- hints.ai_family = afamily; /*AF_INET6*/
- hints.ai_socktype = SOCK_DGRAM; /*dummy*/
+ hints.ai_family = sa->sa_family;
+ hints.ai_socktype = SOCK_DGRAM;
ecode = getaddrinfo(str, NULL, &hints, &res);
if (ecode != 0 || res->ai_family != AF_INET6 ||
- res->ai_addrlen != sizeof(su->sin6)) {
- (void) fprintf(stderr, "%s: %s\n", str,
- gai_strerror(ecode));
- exit(1);
- }
- memcpy(&su->sin6, res->ai_addr, sizeof(su->sin6));
+ res->ai_addrlen != sizeof(struct sockaddr_in6))
+ errx(EX_OSERR, "%s: %s", str, gai_strerror(ecode));
+ memcpy(sa, res->ai_addr, res->ai_addrlen);
freeaddrinfo(res);
if (q != NULL)
*q++ = '/';
if (which == RTA_DST)
- return (inet6_makenetandmask(&su->sin6, q));
+ return (inet6_makenetandmask((struct sockaddr_in6 *)sa,
+ q));
return (0);
}
#endif /* INET6 */
case AF_APPLETALK:
- if (!atalk_aton(str, &su->sat.sat_addr))
+ {
+ struct sockaddr_at *sat = (struct sockaddr_at *)sa;
+
+ if (!atalk_aton(str, &sat->sat_addr))
errx(EX_NOHOST, "bad address: %s", str);
rtm_addrs |= RTA_NETMASK;
- return(forcehost || su->sat.sat_addr.s_node != 0);
-
+ return(forcehost || sat->sat_addr.s_node != 0);
+ }
case AF_LINK:
- link_addr(str, &su->sdl);
+ link_addr(str, (struct sockaddr_dl *)sa);
return (1);
-
case PF_ROUTE:
- su->sa.sa_len = sizeof(*su);
- sockaddr(str, &su->sa);
+ sockaddr(str, sa, sizeof(struct sockaddr_storage));
return (1);
-
+#ifdef INET
case AF_INET:
+#endif
default:
break;
}
+#ifdef INET
+ sin = (struct sockaddr_in *)sa;
if (hpp == NULL)
hpp = &hp;
*hpp = NULL;
@@ -1264,17 +1265,18 @@ getaddr(int which, char *str, struct hostent **hpp, int nrflags)
if (q != NULL && which == RTA_DST) {
*q = '\0';
if ((val = inet_network(str)) != INADDR_NONE) {
- inet_makenetandmask(
- val, &su->sin, strtoul(q+1, 0, 0));
+ inet_makenetandmask(val, sin,
+ (struct sockaddr_in *)&so[RTAX_NETMASK],
+ strtoul(q+1, 0, 0));
return (0);
}
*q = '/';
}
if ((which != RTA_DST || forcenet == 0) &&
- inet_aton(str, &su->sin.sin_addr)) {
- val = su->sin.sin_addr.s_addr;
+ inet_aton(str, &sin->sin_addr)) {
+ val = sin->sin_addr.s_addr;
if (which != RTA_DST || forcehost ||
- inet_lnaof(su->sin.sin_addr) != INADDR_ANY)
+ inet_lnaof(sin->sin_addr) != INADDR_ANY)
return (1);
else {
val = ntohl(val);
@@ -1285,17 +1287,19 @@ getaddr(int which, char *str, struct hostent **hpp, int nrflags)
((val = inet_network(str)) != INADDR_NONE ||
((np = getnetbyname(str)) != NULL && (val = np->n_net) != 0))) {
netdone:
- inet_makenetandmask(val, &su->sin, 0);
+ inet_makenetandmask(val, sin,
+ (struct sockaddr_in *)&so[RTAX_NETMASK], 0);
return (0);
}
hp = gethostbyname(str);
if (hp != NULL) {
*hpp = hp;
- su->sin.sin_family = hp->h_addrtype;
- memmove((char *)&su->sin.sin_addr, hp->h_addr,
- MIN((size_t)hp->h_length, sizeof(su->sin.sin_addr)));
+ sin->sin_family = hp->h_addrtype;
+ memmove((char *)&sin->sin_addr, hp->h_addr,
+ MIN((size_t)hp->h_length, sizeof(sin->sin_addr)));
return (1);
}
+#endif
errx(EX_NOHOST, "bad address: %s", str);
}
@@ -1310,28 +1314,39 @@ prefixlen(const char *str)
switch (af) {
#ifdef INET6
case AF_INET6:
+ {
+ struct sockaddr_in6 *sin6 =
+ (struct sockaddr_in6 *)&so[RTAX_NETMASK];
+
max = 128;
- p = (char *)&so_mask.sin6.sin6_addr;
+ p = (char *)&sin6->sin6_addr;
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_len = sizeof(*sin6);
break;
+ }
#endif
+#ifdef INET
case AF_INET:
+ {
+ struct sockaddr_in *sin =
+ (struct sockaddr_in *)&so[RTAX_NETMASK];
+
max = 32;
- p = (char *)&so_mask.sin.sin_addr;
+ p = (char *)&sin->sin_addr;
+ sin->sin_family = AF_INET;
+ sin->sin_len = sizeof(*sin);
break;
+ }
+#endif
default:
- fprintf(stderr, "prefixlen not supported in this af\n");
- exit(1);
+ errx(EX_OSERR, "prefixlen not supported in this af");
}
- if (len < 0 || max < len) {
- fprintf(stderr, "%s: bad value\n", str);
- exit(1);
- }
+ if (len < 0 || max < len)
+ errx(EX_USAGE, "%s: invalid prefixlen", str);
q = len >> 3;
r = len & 7;
- so_mask.sa.sa_family = af;
- so_mask.sa.sa_len = aflen;
memset((void *)p, 0, max / 8);
if (q > 0)
memset((void *)p, 0xff, q);
@@ -1355,14 +1370,14 @@ retry2:
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
mib[2] = 0; /* protocol */
- mib[3] = 0; /* wildcard address family */
+ mib[3] = AF_UNSPEC;
mib[4] = NET_RT_IFLIST;
mib[5] = 0; /* no flags */
- if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
+ if (sysctl(mib, nitems(mib), NULL, &needed, NULL, 0) < 0)
err(EX_OSERR, "route-sysctl-estimate");
if ((buf = malloc(needed)) == NULL)
errx(EX_OSERR, "malloc failed");
- if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
+ if (sysctl(mib, nitems(mib), buf, &needed, NULL, 0) < 0) {
if (errno == ENOMEM && count++ < 10) {
warnx("Routing table grew, retrying");
sleep(1);
@@ -1422,12 +1437,12 @@ monitor(int argc, char *argv[])
time_t now;
n = read(s, msg, 2048);
now = time(NULL);
- (void) printf("\ngot message of size %d on %s", n, ctime(&now));
+ (void)printf("\ngot message of size %d on %s", n, ctime(&now));
print_rtmsg((struct rt_msghdr *)msg, n);
}
}
-struct {
+static struct {
struct rt_msghdr m_rtm;
char m_space[512];
} m_rtmsg;
@@ -1440,10 +1455,16 @@ rtmsg(int cmd, int flags, int fib)
char *cp = m_rtmsg.m_space;
int l;
-#define NEXTADDR(w, u) \
- if (rtm_addrs & (w)) {\
- l = SA_SIZE(&(u.sa)); memmove(cp, &(u), l); cp += l;\
- if (verbose) sodump(&(u),#u);\
+#define NEXTADDR(w, u) \
+ if (rtm_addrs & (w)) { \
+ l = (((struct sockaddr *)&(u))->sa_len == 0) ? \
+ sizeof(long) : \
+ 1 + ((((struct sockaddr *)&(u))->sa_len - 1) \
+ | (sizeof(long) - 1)); \
+ memmove(cp, (char *)&(u), l); \
+ cp += l; \
+ if (verbose) \
+ sodump((struct sockaddr *)&(u), #w); \
}
errno = 0;
@@ -1454,9 +1475,9 @@ rtmsg(int cmd, int flags, int fib)
cmd = RTM_CHANGE;
else if (cmd == 'g' || cmd == 's') {
cmd = RTM_GET;
- if (so_ifp.sa.sa_family == 0) {
- so_ifp.sa.sa_family = AF_LINK;
- so_ifp.sa.sa_len = sizeof(struct sockaddr_dl);
+ if (so[RTAX_IFP].ss_family == 0) {
+ so[RTAX_IFP].ss_family = AF_LINK;
+ so[RTAX_IFP].ss_len = sizeof(struct sockaddr_dl);
rtm_addrs |= RTA_IFP;
}
} else
@@ -1470,14 +1491,12 @@ rtmsg(int cmd, int flags, int fib)
rtm.rtm_rmx = rt_metrics;
rtm.rtm_inits = rtm_inits;
- if (rtm_addrs & RTA_NETMASK)
- mask_addr();
- NEXTADDR(RTA_DST, so_dst);
- NEXTADDR(RTA_GATEWAY, so_gate);
- NEXTADDR(RTA_NETMASK, so_mask);
- NEXTADDR(RTA_GENMASK, so_genmask);
- NEXTADDR(RTA_IFP, so_ifp);
- NEXTADDR(RTA_IFA, so_ifa);
+ NEXTADDR(RTA_DST, so[RTAX_DST]);
+ NEXTADDR(RTA_GATEWAY, so[RTAX_GATEWAY]);
+ NEXTADDR(RTA_NETMASK, so[RTAX_NETMASK]);
+ NEXTADDR(RTA_GENMASK, so[RTAX_GENMASK]);
+ NEXTADDR(RTA_IFP, so[RTAX_IFP]);
+ NEXTADDR(RTA_IFA, so[RTAX_IFA]);
rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;
if (verbose)
print_rtmsg(&rtm, l);
@@ -1502,38 +1521,7 @@ rtmsg(int cmd, int flags, int fib)
return (0);
}
-static void
-mask_addr(void)
-{
- int olen = so_mask.sa.sa_len;
- char *cp1 = olen + (char *)&so_mask, *cp2;
-
- for (so_mask.sa.sa_len = 0; cp1 > (char *)&so_mask; )
- if (*--cp1 != 0) {
- so_mask.sa.sa_len = 1 + cp1 - (char *)&so_mask;
- break;
- }
- if ((rtm_addrs & RTA_DST) == 0)
- return;
- switch (so_dst.sa.sa_family) {
- case AF_INET:
-#ifdef INET6
- case AF_INET6:
-#endif
- case AF_APPLETALK:
- case 0:
- return;
- }
- cp1 = so_mask.sa.sa_len + 1 + (char *)&so_dst;
- cp2 = so_dst.sa.sa_len + 1 + (char *)&so_dst;
- while (cp2 > cp1)
- *--cp2 = 0;
- cp2 = so_mask.sa.sa_len + 1 + (char *)&so_mask;
- while (cp1 > so_dst.sa.sa_data)
- *--cp1 &= *--cp2;
-}
-
-const char *msgtypes[] = {
+static const char *msgtypes[] = {
"",
"RTM_ADD: Add Route",
"RTM_DELETE: Delete Route",
@@ -1555,23 +1543,23 @@ const char *msgtypes[] = {
"RTM_IEEE80211: IEEE 802.11 wireless event",
};
-char metricnames[] =
-"\011weight\010rttvar\7rtt\6ssthresh\5sendpipe\4recvpipe\3expire"
-"\1mtu";
-char routeflags[] =
-"\1UP\2GATEWAY\3HOST\4REJECT\5DYNAMIC\6MODIFIED\7DONE"
-"\012XRESOLVE\013LLINFO\014STATIC\015BLACKHOLE"
-"\017PROTO2\020PROTO1\021PRCLONING\022WASCLONED\023PROTO3"
-"\025PINNED\026LOCAL\027BROADCAST\030MULTICAST\035STICKY";
-char ifnetflags[] =
-"\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5PTP\6b6\7RUNNING\010NOARP"
-"\011PPROMISC\012ALLMULTI\013OACTIVE\014SIMPLEX\015LINK0\016LINK1"
-"\017LINK2\020MULTICAST";
-char addrnames[] =
-"\1DST\2GATEWAY\3NETMASK\4GENMASK\5IFP\6IFA\7AUTHOR\010BRD";
+static const char metricnames[] =
+ "\011weight\010rttvar\7rtt\6ssthresh\5sendpipe\4recvpipe\3expire"
+ "\1mtu";
+static const char routeflags[] =
+ "\1UP\2GATEWAY\3HOST\4REJECT\5DYNAMIC\6MODIFIED\7DONE"
+ "\012XRESOLVE\013LLINFO\014STATIC\015BLACKHOLE"
+ "\017PROTO2\020PROTO1\021PRCLONING\022WASCLONED\023PROTO3"
+ "\025PINNED\026LOCAL\027BROADCAST\030MULTICAST\035STICKY";
+static const char ifnetflags[] =
+ "\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5PTP\6b6\7RUNNING\010NOARP"
+ "\011PPROMISC\012ALLMULTI\013OACTIVE\014SIMPLEX\015LINK0\016LINK1"
+ "\017LINK2\020MULTICAST";
+static const char addrnames[] =
+ "\1DST\2GATEWAY\3NETMASK\4GENMASK\5IFP\6IFA\7AUTHOR\010BRD";
static const char errfmt[] =
-"\n%s: truncated route message, only %zu bytes left\n";
+ "\n%s: truncated route message, only %zu bytes left\n";
static void
print_rtmsg(struct rt_msghdr *rtm, size_t msglen)
@@ -1587,7 +1575,7 @@ print_rtmsg(struct rt_msghdr *rtm, size_t msglen)
if (verbose == 0)
return;
if (rtm->rtm_version != RTM_VERSION) {
- (void) printf("routing message version %d not understood\n",
+ (void)printf("routing message version %d not understood\n",
rtm->rtm_version);
return;
}
@@ -1608,7 +1596,7 @@ print_rtmsg(struct rt_msghdr *rtm, size_t msglen)
case RTM_IFINFO:
REQUIRE(struct if_msghdr);
ifm = (struct if_msghdr *)rtm;
- (void) printf("if# %d, ", ifm->ifm_index);
+ (void)printf("if# %d, ", ifm->ifm_index);
switch (ifm->ifm_data.ifi_link_state) {
case LINK_STATE_DOWN:
state = "down";
@@ -1620,16 +1608,16 @@ print_rtmsg(struct rt_msghdr *rtm, size_t msglen)
state = "unknown";
break;
}
- (void) printf("link: %s, flags:", state);
- bprintf(stdout, ifm->ifm_flags, ifnetflags);
+ (void)printf("link: %s, flags:", state);
+ printb(ifm->ifm_flags, ifnetflags);
pmsg_addrs((char *)(ifm + 1), ifm->ifm_addrs, msglen);
break;
case RTM_NEWADDR:
case RTM_DELADDR:
REQUIRE(struct ifa_msghdr);
ifam = (struct ifa_msghdr *)rtm;
- (void) printf("metric %d, flags:", ifam->ifam_metric);
- bprintf(stdout, ifam->ifam_flags, routeflags);
+ (void)printf("metric %d, flags:", ifam->ifam_metric);
+ printb(ifam->ifam_flags, routeflags);
pmsg_addrs((char *)(ifam + 1), ifam->ifam_addrs, msglen);
break;
#ifdef RTM_NEWMADDR
@@ -1643,10 +1631,10 @@ print_rtmsg(struct rt_msghdr *rtm, size_t msglen)
case RTM_IFANNOUNCE:
REQUIRE(struct if_announcemsghdr);
ifan = (struct if_announcemsghdr *)rtm;
- (void) printf("if# %d, what: ", ifan->ifan_index);
+ (void)printf("if# %d, what: ", ifan->ifan_index);
switch (ifan->ifan_what) {
case IFAN_ARRIVAL:
- printf("arrival");
+ (void)printf("arrival");
break;
case IFAN_DEPARTURE:
printf("departure");
@@ -1660,9 +1648,9 @@ print_rtmsg(struct rt_msghdr *rtm, size_t msglen)
break;
default:
- (void) printf("pid: %ld, seq %d, errno %d, flags:",
+ printf("pid: %ld, seq %d, errno %d, flags:",
(long)rtm->rtm_pid, rtm->rtm_seq, rtm->rtm_errno);
- bprintf(stdout, rtm->rtm_flags, routeflags);
+ printb(rtm->rtm_flags, routeflags);
pmsg_common(rtm, msglen);
}
@@ -1682,8 +1670,8 @@ print_getmsg(struct rt_msghdr *rtm, int msglen, int fib)
char *cp;
int i;
- (void) printf(" route to: %s\n",
- routename((struct sockaddr *)&so_dst));
+ (void)printf(" route to: %s\n",
+ routename((struct sockaddr *)&so[RTAX_DST]));
if (rtm->rtm_version != RTM_VERSION) {
warnx("routing message version %d not understood",
rtm->rtm_version);
@@ -1740,12 +1728,12 @@ print_getmsg(struct rt_msghdr *rtm, int msglen, int fib)
(void)printf(" interface: %.*s\n",
ifp->sdl_nlen, ifp->sdl_data);
(void)printf(" flags: ");
- bprintf(stdout, rtm->rtm_flags, routeflags);
+ printb(rtm->rtm_flags, routeflags);
#define lock(f) ((rtm->rtm_rmx.rmx_locks & __CONCAT(RTV_,f)) ? 'L' : ' ')
#define msec(u) (((u) + 500) / 1000) /* usec to msec */
- (void) printf("\n%s\n", "\
+ printf("\n%s\n", "\
recvpipe sendpipe ssthresh rtt,msec mtu weight expire");
printf("%8ld%c ", rtm->rtm_rmx.rmx_recvpipe, lock(RPIPE));
printf("%8ld%c ", rtm->rtm_rmx.rmx_sendpipe, lock(SPIPE));
@@ -1762,8 +1750,8 @@ print_getmsg(struct rt_msghdr *rtm, int msglen, int fib)
if (verbose)
pmsg_common(rtm, msglen);
else if (rtm->rtm_addrs &~ RTA_IGN) {
- (void) printf("sockaddrs: ");
- bprintf(stdout, rtm->rtm_addrs, addrnames);
+ (void)printf("sockaddrs: ");
+ printb(rtm->rtm_addrs, addrnames);
putchar('\n');
}
#undef RTA_IGN
@@ -1772,15 +1760,16 @@ print_getmsg(struct rt_msghdr *rtm, int msglen, int fib)
static void
pmsg_common(struct rt_msghdr *rtm, size_t msglen)
{
- (void) printf("\nlocks: ");
- bprintf(stdout, rtm->rtm_rmx.rmx_locks, metricnames);
- (void) printf(" inits: ");
- bprintf(stdout, rtm->rtm_inits, metricnames);
+
+ (void)printf("\nlocks: ");
+ printb(rtm->rtm_rmx.rmx_locks, metricnames);
+ (void)printf(" inits: ");
+ printb(rtm->rtm_inits, metricnames);
if (msglen > sizeof(struct rt_msghdr))
pmsg_addrs(((char *)(rtm + 1)), rtm->rtm_addrs,
msglen - sizeof(struct rt_msghdr));
else
- (void) fflush(stdout);
+ (void)fflush(stdout);
}
static void
@@ -1790,29 +1779,29 @@ pmsg_addrs(char *cp, int addrs, size_t len)
int i;
if (addrs == 0) {
- (void) putchar('\n');
+ (void)putchar('\n');
return;
}
- (void) printf("\nsockaddrs: ");
- bprintf(stdout, addrs, addrnames);
- (void) putchar('\n');
+ (void)printf("\nsockaddrs: ");
+ printb(addrs, addrnames);
+ putchar('\n');
for (i = 1; i != 0; i <<= 1)
if (i & addrs) {
sa = (struct sockaddr *)cp;
if (len == 0 || len < SA_SIZE(sa)) {
- (void) printf(errfmt, __func__, len);
+ (void)printf(errfmt, __func__, len);
break;
}
- (void) printf(" %s", routename(sa));
+ (void)printf(" %s", routename(sa));
len -= SA_SIZE(sa);
cp += SA_SIZE(sa);
}
- (void) putchar('\n');
- (void) fflush(stdout);
+ (void)putchar('\n');
+ (void)fflush(stdout);
}
static void
-bprintf(FILE *fp, int b, u_char *str)
+printb(int b, const char *str)
{
int i;
int gotsome = 0;
@@ -1825,16 +1814,16 @@ bprintf(FILE *fp, int b, u_char *str)
i = '<';
else
i = ',';
- (void) putc(i, fp);
+ putchar(i);
gotsome = 1;
for (; (i = *str) > 32; str++)
- (void) putc(i, fp);
+ putchar(i);
} else
while (*str > 32)
str++;
}
if (gotsome)
- (void) putc('>', fp);
+ putchar('>');
}
int
@@ -1848,23 +1837,36 @@ keyword(const char *cp)
}
static void
-sodump(sup su, const char *which)
+sodump(struct sockaddr *sa, const char *which)
{
- switch (su->sa.sa_family) {
+#ifdef INET6
+ char nbuf[INET6_ADDRSTRLEN];
+#endif
+
+ switch (sa->sa_family) {
case AF_LINK:
- (void) printf("%s: link %s; ",
- which, link_ntoa(&su->sdl));
+ (void)printf("%s: link %s; ", which,
+ link_ntoa((struct sockaddr_dl *)sa));
break;
+#ifdef INET
case AF_INET:
- (void) printf("%s: inet %s; ",
- which, inet_ntoa(su->sin.sin_addr));
+ (void)printf("%s: inet %s; ", which,
+ inet_ntoa(((struct sockaddr_in *)sa)->sin_addr));
break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ (void)printf("%s: inet6 %s; ", which, inet_ntop(sa->sa_family,
+ &((struct sockaddr_in6 *)sa)->sin6_addr, nbuf,
+ sizeof(nbuf)));
+ break;
+#endif
case AF_APPLETALK:
- (void) printf("%s: atalk %s; ",
- which, atalk_ntoa(su->sat.sat_addr));
+ (void)printf("%s: atalk %s; ", which,
+ atalk_ntoa(((struct sockaddr_at *)sa)->sat_addr));
break;
}
- (void) fflush(stdout);
+ (void)fflush(stdout);
}
/* States*/
@@ -1877,10 +1879,9 @@ sodump(sup su, const char *which)
#define DELIM (4*2)
static void
-sockaddr(char *addr, struct sockaddr *sa)
+sockaddr(char *addr, struct sockaddr *sa, size_t size)
{
char *cp = (char *)sa;
- int size = sa->sa_len;
char *cplim = cp + size;
int byte = 0, state = VIRGIN, new = 0 /* foil gcc */;
@@ -1936,6 +1937,7 @@ atalk_ntoa(struct at_addr at)
{
static char buf[20];
- (void) snprintf(buf, sizeof(buf), "%u.%u", ntohs(at.s_net), at.s_node);
+ (void)snprintf(buf, sizeof(buf), "%u.%u", ntohs(at.s_net), at.s_node);
+ buf[sizeof(buf) - 1] = '\0';
return(buf);
}
OpenPOWER on IntegriCloud