diff --git a/sbin/chown/Makefile b/sbin/chown/Makefile deleted file mode 100644 index e3a535757..000000000 --- a/sbin/chown/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# from: @(#)Makefile 8.1 (Berkeley) 6/6/93 -# $NetBSD: Makefile,v 1.6 2011/01/13 23:44:11 haad Exp $ - -PROG= chown -CPPFLAGS+=-DSUPPORT_DOT -MAN= chgrp.1 chown.8 -SYMLINKS+= ${BINDIR}/chown /bin/chgrp - -SYMLINKS+= ${BINDIR}/chown /usr/bin/chgrp -SYMLINKS+= ${BINDIR}/chown /usr/sbin/chown - -.include diff --git a/sbin/chown/chgrp.1 b/sbin/chown/chgrp.1 deleted file mode 100644 index 4a7f418f9..000000000 --- a/sbin/chown/chgrp.1 +++ /dev/null @@ -1,171 +0,0 @@ -.\" Copyright (c) 1983, 1990, 1993, 1994, 2003 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" the Institute of Electrical and Electronics Engineers, Inc. -.\" -.\" 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. Neither the name of the University 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 REGENTS 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 REGENTS 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: @(#)chgrp.1 8.3 (Berkeley) 3/31/94 -.\" $NetBSD: chgrp.1,v 1.6 2013/12/17 09:54:08 apb Exp $ -.\" -.Dd October 22, 2012 -.Dt CHGRP 1 -.Os -.Sh NAME -.Nm chgrp -.Nd change group -.Sh SYNOPSIS -.Nm -.Oo -.Fl R -.Op Fl H | Fl L | Fl P -.Oc -.Op Fl fhv -.Ar group -.Ar -.Nm -.Oo -.Fl R -.Op Fl H | Fl L | Fl P -.Oc -.Op Fl fhv -.Fl Fl reference=rfile -.Ar -.Sh DESCRIPTION -The -.Nm -utility sets the group ID of the file named by each -.Ar file -operand to the -.Ar group -ID specified by the group operand, -or to the group of the given -.Ar rfile , -specified by the -.Fl Fl reference -argument. -.Pp -Options: -.Bl -tag -width Ds -.It Fl H -If the -.Fl R -option is specified, symbolic links on the command line are followed. -(Symbolic links encountered in the tree traversal are not followed.) -.It Fl L -If the -.Fl R -option is specified, all symbolic links are followed. -.It Fl P -If the -.Fl R -option is specified, no symbolic links are followed. -.It Fl R -Change the group ID for the file hierarchies rooted -in the files instead of just the files themselves. -.It Fl f -The force option ignores errors, except for usage errors and doesn't -query about strange modes (unless the user does not have proper permissions). -.It Fl h -If -.Ar file -is a symbolic link, the group of the link is changed. -.It Fl v -Cause -.Nm -to be verbose, showing files as they are processed. -.El -.Pp -If -.Fl h -is not given, unless the -.Fl H -or -.Fl L -option is set, -.Nm -on a symbolic link always succeeds and has no effect. -The -.Fl H , -.Fl L -and -.Fl P -options are ignored unless the -.Fl R -option is specified. -In addition, these options override each other and the -command's actions are determined by the last one specified. -The default is as if the -.Fl P -option had been specified. -.Pp -The -.Ar group -operand can be either a group name from the group database, -or a numeric group ID. -Since it is valid to have a group name that is numeric (and -doesn't have the numeric ID that matches its name) the name lookup -is always done first. -Preceding the ID with a ``#'' character will force it to be taken -as a number. -.Pp -The user invoking -.Nm -must belong to the specified group and be the owner of the file, -or be the super-user. -.Pp -Unless invoked by the super-user, -.Nm -clears the set-user-id and set-group-id bits on a file to prevent -accidental or mischievous creation of set-user-id or set-group-id -programs. -.Pp -The -.Nm -utility exits 0 on success, and \*[Gt]0 if an error occurs. -.Sh FILES -.Bl -tag -width /etc/group -compact -.It Pa /etc/group -Group ID file -.El -.Sh SEE ALSO -.Xr chown 2 , -.Xr lchown 2 , -.Xr fts 3 , -.Xr group 5 , -.Xr passwd 5 , -.Xr symlink 7 , -.Xr chown 8 -.Sh STANDARDS -The -.Nm -utility is expected to be POSIX 1003.2 compatible. -.Pp -The -.Fl v -option and the use of ``#'' to force a numeric group ID -are extensions to -.St -p1003.2 . diff --git a/sbin/chown/chown.8 b/sbin/chown/chown.8 deleted file mode 100644 index b6c2c9f2d..000000000 --- a/sbin/chown/chown.8 +++ /dev/null @@ -1,186 +0,0 @@ -.\" Copyright (c) 1990, 1991, 1993, 1994, 2003 -.\" The Regents of the University of California. 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. -.\" 3. Neither the name of the University 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 REGENTS 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 REGENTS 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: @(#)chown.8 8.3 (Berkeley) 3/31/94 -.\" $NetBSD: chown.8,v 1.10 2016/09/11 01:23:26 sevan Exp $ -.\" -.Dd September 11, 2016 -.Dt CHOWN 8 -.Os -.Sh NAME -.Nm chown -.Nd change file owner and group -.Sh SYNOPSIS -.Nm -.Oo -.Fl R -.Op Fl H | Fl L | Fl P -.Oc -.Op Fl fhv -.Ar owner Ns Op Ar :group -.Ar -.Nm -.Oo -.Fl R -.Op Fl H | Fl L | Fl P -.Oc -.Op Fl fhv -.Ar :group -.Ar -.Nm -.Oo -.Fl R -.Op Fl H | Fl L | Fl P -.Oc -.Op Fl fhv -.Fl Fl reference=rfile -.Ar -.Sh DESCRIPTION -.Nm -sets the user ID and/or the group ID of the specified files. -Symbolic links named by arguments are silently left unchanged unless -.Fl h -is used. -.Pp -The options are as follows: -.Bl -tag -width Ds -.It Fl H -If the -.Fl R -option is specified, symbolic links on the command line are followed. -(Symbolic links encountered in the tree traversal are not followed.) -.It Fl L -If the -.Fl R -option is specified, all symbolic links are followed. -.It Fl P -If the -.Fl R -option is specified, no symbolic links are followed. -.It Fl R -Change the user ID and/or the group ID for the file hierarchies rooted -in the files instead of just the files themselves. -.It Fl f -Do not report any failure to change file owner or group, nor modify -the exit status to reflect such failures. -.It Fl h -If -.Ar file -is a symbolic link, the owner and/or group of the link is changed. -.It Fl v -Cause -.Nm -to be verbose, showing files as they are processed. -.El -.Pp -The -.Fl H , -.Fl L -and -.Fl P -options are ignored unless the -.Fl R -option is specified. -In addition, these options override each other and the -command's actions are determined by the last one specified. -The default is as if the -.Fl P -option had been specified. -.Pp -The -.Fl L -option cannot be used together with the -.Fl h -option. -.Pp -The -.Ar owner -and -.Ar group -operands are both optional, however, one must be specified; alternatively, -both the owner and group may be specified using a reference -.Ar rfile -specified using the -.Fl Fl reference -argument. -If the -.Ar group -operand is specified, it must be preceded by a colon (``:'') character. -.Pp -The -.Ar owner -may be either a user name or a numeric user ID. -The -.Ar group -may be either a group name or a numeric group ID. -Since it is valid to have a user or group name that is numeric (and -does not have the numeric ID that matches its name) the name lookup -is always done first. -Preceding an ID with a ``#'' character will force it to be taken -as a number. -.Pp -The ownership of a file may only be altered by a super-user for -obvious security reasons. -.Pp -Unless invoked by the super-user, -.Nm -clears the set-user-id and set-group-id bits on a file to prevent -accidental or mischievous creation of set-user-id and set-group-id -programs. -.Pp -The -.Nm -utility exits 0 on success, and \*[Gt]0 if an error occurs. -.Sh COMPATIBILITY -Previous versions of the -.Nm -utility used the dot (``.'') character to distinguish the group name. -This has been changed to be a colon (``:'') character so that user and -group names may contain the dot character. -.Sh SEE ALSO -.Xr chflags 1 , -.Xr chgrp 1 , -.Xr find 1 , -.Xr chown 2 , -.Xr lchown 2 , -.Xr fts 3 , -.Xr symlink 7 -.Sh HISTORY -A -.Nm -utility appeared in -.At v1 . -.Sh STANDARDS -The -.Nm -command is expected to be POSIX 1003.2 compliant. -.Pp -The -.Fl v -option and the use of ``#'' to force a numeric lookup -are extensions to -.St -p1003.2 . diff --git a/sbin/chown/chown.c b/sbin/chown/chown.c deleted file mode 100644 index ee46eee35..000000000 --- a/sbin/chown/chown.c +++ /dev/null @@ -1,302 +0,0 @@ -/* $NetBSD: chown.c,v 1.8 2012/10/24 01:12:51 enami Exp $ */ - -/* - * Copyright (c) 1988, 1993, 1994, 2003 - * The Regents of the University of California. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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 -#ifndef lint -__COPYRIGHT("@(#) Copyright (c) 1988, 1993, 1994, 2003\ - The Regents of the University of California. All rights reserved."); -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)chown.c 8.8 (Berkeley) 4/4/94"; -#else -__RCSID("$NetBSD: chown.c,v 1.8 2012/10/24 01:12:51 enami Exp $"); -#endif -#endif /* not lint */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static void a_gid(const char *); -static void a_uid(const char *); -static id_t id(const char *, const char *); -__dead static void usage(void); - -static uid_t uid; -static gid_t gid; -static int ischown; -static const char *myname; - -struct option chown_longopts[] = { - { "reference", required_argument, 0, - 1 }, - { NULL, 0, 0, - 0 }, -}; - -int -main(int argc, char **argv) -{ - FTS *ftsp; - FTSENT *p; - int Hflag, Lflag, Rflag, ch, fflag, fts_options, hflag, rval, vflag; - char *cp, *reference; - int (*change_owner)(const char *, uid_t, gid_t); - - setprogname(*argv); - - (void)setlocale(LC_ALL, ""); - - myname = getprogname(); - ischown = (myname[2] == 'o'); - reference = NULL; - - Hflag = Lflag = Rflag = fflag = hflag = vflag = 0; - while ((ch = getopt_long(argc, argv, "HLPRfhv", - chown_longopts, NULL)) != -1) - switch (ch) { - case 1: - reference = optarg; - break; - case 'H': - Hflag = 1; - Lflag = 0; - break; - case 'L': - Lflag = 1; - Hflag = 0; - break; - case 'P': - Hflag = Lflag = 0; - break; - case 'R': - Rflag = 1; - break; - case 'f': - fflag = 1; - break; - case 'h': - /* - * In System V the -h option causes chown/chgrp to - * change the owner/group of the symbolic link. - * 4.4BSD's symbolic links didn't have owners/groups, - * so it was an undocumented noop. - * In NetBSD 1.3, lchown(2) is introduced. - */ - hflag = 1; - break; - case 'v': - vflag = 1; - break; - case '?': - default: - usage(); - } - argv += optind; - argc -= optind; - - if (argc == 0 || (argc == 1 && reference == NULL)) - usage(); - - fts_options = FTS_PHYSICAL; - if (Rflag) { - if (Hflag) - fts_options |= FTS_COMFOLLOW; - if (Lflag) { - if (hflag) - errx(EXIT_FAILURE, - "the -L and -h options " - "may not be specified together."); - fts_options &= ~FTS_PHYSICAL; - fts_options |= FTS_LOGICAL; - } - } else if (!hflag) - fts_options |= FTS_COMFOLLOW; - - uid = (uid_t)-1; - gid = (gid_t)-1; - if (reference == NULL) { - if (ischown) { - if ((cp = strchr(*argv, ':')) != NULL) { - *cp++ = '\0'; - a_gid(cp); - } -#ifdef SUPPORT_DOT - else if ((cp = strrchr(*argv, '.')) != NULL) { - if (uid_from_user(*argv, &uid) == -1) { - *cp++ = '\0'; - a_gid(cp); - } - } -#endif - a_uid(*argv); - } else - a_gid(*argv); - argv++; - } else { - struct stat st; - - if (stat(reference, &st) == -1) - err(EXIT_FAILURE, "Cannot stat `%s'", reference); - if (ischown) - uid = st.st_uid; - gid = st.st_gid; - } - - if ((ftsp = fts_open(argv, fts_options, NULL)) == NULL) - err(EXIT_FAILURE, "fts_open"); - - for (rval = EXIT_SUCCESS; (p = fts_read(ftsp)) != NULL;) { - change_owner = chown; - switch (p->fts_info) { - case FTS_D: - if (!Rflag) /* Change it at FTS_DP. */ - fts_set(ftsp, p, FTS_SKIP); - continue; - case FTS_DNR: /* Warn, chown, continue. */ - warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); - rval = EXIT_FAILURE; - break; - case FTS_ERR: /* Warn, continue. */ - case FTS_NS: - warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); - rval = EXIT_FAILURE; - continue; - case FTS_SL: /* Ignore unless -h. */ - /* - * All symlinks we found while doing a physical - * walk end up here. - */ - if (!hflag) - continue; - /* - * Note that if we follow a symlink, fts_info is - * not FTS_SL but FTS_F or whatever. And we should - * use lchown only for FTS_SL and should use chown - * for others. - */ - change_owner = lchown; - break; - case FTS_SLNONE: /* Ignore. */ - /* - * The only symlinks that end up here are ones that - * don't point to anything. Note that if we are - * doing a phisycal walk, we never reach here unless - * we asked to follow explicitly. - */ - continue; - default: - break; - } - - if ((*change_owner)(p->fts_accpath, uid, gid) && !fflag) { - warn("%s", p->fts_path); - rval = EXIT_FAILURE; - } else { - if (vflag) - printf("%s\n", p->fts_path); - } - } - if (errno) - err(EXIT_FAILURE, "fts_read"); - exit(rval); - /* NOTREACHED */ -} - -static void -a_gid(const char *s) -{ - struct group *gr; - - if (*s == '\0') /* Argument was "uid[:.]". */ - return; - gr = *s == '#' ? NULL : getgrnam(s); - if (gr == NULL) - gid = id(s, "group"); - else - gid = gr->gr_gid; - return; -} - -static void -a_uid(const char *s) -{ - if (*s == '\0') /* Argument was "[:.]gid". */ - return; - if (*s == '#' || uid_from_user(s, &uid) == -1) { - uid = id(s, "user"); - } - return; -} - -static id_t -id(const char *name, const char *type) -{ - id_t val; - char *ep; - - errno = 0; - if (*name == '#') - name++; - val = (id_t)strtoul(name, &ep, 10); - if (errno) - err(EXIT_FAILURE, "%s", name); - if (*ep != '\0') - errx(EXIT_FAILURE, "%s: invalid %s name", name, type); - return (val); -} - -static void -usage(void) -{ - - (void)fprintf(stderr, - "Usage: %s [-R [-H | -L | -P]] [-fhv] %s file ...\n" - "\t%s [-R [-H | -L | -P]] [-fhv] --reference=rfile file ...\n", - myname, ischown ? "owner:group|owner|:group" : "group", - myname); - exit(EXIT_FAILURE); -} diff --git a/sbin/ifconfig/Makefile b/sbin/ifconfig/Makefile deleted file mode 100644 index 928025d39..000000000 --- a/sbin/ifconfig/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -# $NetBSD: Makefile,v 1.56 2015/05/19 08:14:38 ozaki-r Exp $ -# @(#)Makefile 8.1 (Berkeley) 6/5/93 - -# when making a change to this file, please check if the change is -# also needed for src/distrib/utils/x_ifconfig. -# such stuff should be into Makefile.inc. - -.include - -RUMPPRG=ifconfig -MAN= ifconfig.8 - -.if defined(__MINIX) -CWARNFLAGS.gcc+= -Wno-unused-but-set-variable -.endif # defined(__MINIX) -#DBG+=-g -SRCS= af_atalk.c af_link.c carp.c -.if (${USE_INET6} != "no") -CPPFLAGS+= -DINET6 -SRCS+= af_inet6.c -.endif - -.include "Makefile.inc" - -.PATH: ${.CURDIR}/../../lib/libc/net -RUMPSRCS= getifaddrs.c getnameinfo.c if_indextoname.c -.if (${MKRUMP} != "no") -CPPFLAGS+= -DRUMP_ACTION -.endif - -.ifdef SMALLPROG -CPPFLAGS+=-DSMALL -.endif - -CPPFLAGS+=-I${NETBSDSRCDIR}/sys/dist/pf/ -SRCS+= pfsync.c - -.if ${MACHINE_ARCH} == "m68000" -# XXX workaround for gcc -O1 bug (PR bin/40036 and toolchain/40066) -COPTS.ifconfig.c+= -fno-loop-optimize -.endif - -.include diff --git a/sbin/ifconfig/af_inetany.c b/sbin/ifconfig/af_inetany.c deleted file mode 100644 index 7c4066bc1..000000000 --- a/sbin/ifconfig/af_inetany.c +++ /dev/null @@ -1,179 +0,0 @@ -/* $NetBSD: af_inetany.c,v 1.17 2012/12/30 22:52:35 christos Exp $ */ - -/*- - * Copyright (c) 2008 David Young. 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 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 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 -#ifndef lint -__RCSID("$NetBSD: af_inetany.c,v 1.17 2012/12/30 22:52:35 christos Exp $"); -#endif /* not lint */ - -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "env.h" -#include "extern.h" -#include "af_inetany.h" -#include "prog_ops.h" - -static void * -loadbuf(const struct apbuf *b, const struct paddr_prefix *pfx) -{ - return memcpy(b->buf, &pfx->pfx_addr, - MIN(b->buflen, pfx->pfx_addr.sa_len)); -} - -void -commit_address(prop_dictionary_t env, prop_dictionary_t oenv, - const struct afparam *param) -{ - const char *ifname; - int af, rc, s; - bool alias, delete, replace; - prop_data_t d; - const struct paddr_prefix *addr, *brd, *dst, *mask; - unsigned short flags; - - if ((af = getaf(env)) == -1) - af = AF_INET; - - if ((s = getsock(af)) == -1) - err(EXIT_FAILURE, "%s: getsock", __func__); - - if ((ifname = getifname(env)) == NULL) - err(EXIT_FAILURE, "%s: getifname", __func__); - - strlcpy(param->name[0].buf, ifname, param->name[0].buflen); - strlcpy(param->name[1].buf, ifname, param->name[1].buflen); - - if ((d = (prop_data_t)prop_dictionary_get(env, "address")) != NULL) - addr = prop_data_data_nocopy(d); - else if (!prop_dictionary_get_bool(env, "alias", &alias) || alias || - param->gifaddr.cmd == 0) - return; - else if (prog_ioctl(s, param->gifaddr.cmd, param->dgreq.buf) == -1) - err(EXIT_FAILURE, "%s", param->gifaddr.desc); - else if (prog_ioctl(s, param->difaddr.cmd, param->dgreq.buf) == -1) - err(EXIT_FAILURE, "%s", param->difaddr.desc); - else - return; - - if ((d = (prop_data_t)prop_dictionary_get(env, "dst")) != NULL) - dst = prop_data_data_nocopy(d); - else - dst = NULL; - - if ((d = (prop_data_t)prop_dictionary_get(env, "netmask")) != NULL) - mask = prop_data_data_nocopy(d); - else - mask = NULL; - - if ((d = (prop_data_t)prop_dictionary_get(env, "broadcast")) != NULL) - brd = prop_data_data_nocopy(d); - else - brd = NULL; - - if (!prop_dictionary_get_bool(env, "alias", &alias)) { - delete = false; - replace = (param->gifaddr.cmd != 0); - } else { - replace = false; - delete = !alias; - } - - loadbuf(¶m->addr, addr); - - /* TBD: read matching ifaddr from kernel, use the netmask as default - * TBD: handle preference - */ - if (getifflags(env, oenv, &flags) == -1) - err(EXIT_FAILURE, "%s: getifflags", __func__); - - switch (flags & (IFF_BROADCAST|IFF_POINTOPOINT)) { - case IFF_BROADCAST: - if (brd != NULL) - loadbuf(¶m->brd, brd); - /*FALLTHROUGH*/ - case 0: - break; - case IFF_POINTOPOINT: - if (brd != NULL) { - errx(EXIT_FAILURE, "%s is not a broadcast interface", - ifname); - } - if (dst != NULL) - loadbuf(¶m->dst, dst); - break; - case IFF_BROADCAST|IFF_POINTOPOINT: - errx(EXIT_FAILURE, "unsupported interface flags"); - } - if (param->mask.buf == NULL) { - if (mask != NULL) - errx(EXIT_FAILURE, "netmask not supported"); - } else if (mask != NULL) - loadbuf(¶m->mask, mask); - else if (param->defmask.buf != NULL) { - memcpy(param->mask.buf, param->defmask.buf, - MIN(param->mask.buflen, param->defmask.buflen)); - } - if (replace) { - if (prog_ioctl(s, param->gifaddr.cmd, param->dgreq.buf) == 0) { - rc = prog_ioctl(s, param->difaddr.cmd, param->dgreq.buf); - if (rc == -1) - err(EXIT_FAILURE, "%s", param->difaddr.desc); - } else if (errno == EADDRNOTAVAIL) - ; /* No address was assigned yet. */ - else - err(EXIT_FAILURE, "%s", param->gifaddr.desc); - } else if (delete) { - loadbuf(¶m->dgaddr, addr); - if (prog_ioctl(s, param->difaddr.cmd, param->dgreq.buf) == -1) - err(EXIT_FAILURE, "%s", param->difaddr.desc); - return; - } - if (param->pre_aifaddr != NULL && - (*param->pre_aifaddr)(env, param) == -1) - err(EXIT_FAILURE, "pre-%s", param->aifaddr.desc); - if (prog_ioctl(s, param->aifaddr.cmd, param->req.buf) == -1) - err(EXIT_FAILURE, "%s", param->aifaddr.desc); -} diff --git a/sbin/ifconfig/agr.c b/sbin/ifconfig/agr.c deleted file mode 100644 index fec580050..000000000 --- a/sbin/ifconfig/agr.c +++ /dev/null @@ -1,195 +0,0 @@ -/* $NetBSD: agr.c,v 1.15 2008/07/15 21:27:58 dyoung Exp $ */ - -/*- - * Copyright (c)2005 YAMAMOTO Takashi, - * 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 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 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 -#if !defined(lint) -__RCSID("$NetBSD: agr.c,v 1.15 2008/07/15 21:27:58 dyoung Exp $"); -#endif /* !defined(lint) */ - -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "env.h" -#include "extern.h" -#include "parse.h" -#include "util.h" - -static int agrsetport(prop_dictionary_t, prop_dictionary_t); -static void agr_constructor(void) __attribute__((constructor)); -static int checkifname(prop_dictionary_t); -static void assertifname(prop_dictionary_t); - -static struct piface agrif = PIFACE_INITIALIZER(&agrif, "agr interface", - agrsetport, "agrport", &command_root.pb_parser); - -static const struct kwinst agrkw[] = { - {.k_word = "agrport", .k_type = KW_T_INT, .k_int = AGRCMD_ADDPORT, - .k_nextparser = &agrif.pif_parser} - , {.k_word = "-agrport", .k_type = KW_T_INT, .k_int = AGRCMD_REMPORT, - .k_nextparser = &agrif.pif_parser} -}; - -struct pkw agr = PKW_INITIALIZER(&agr, "agr", NULL, "agrcmd", - agrkw, __arraycount(agrkw), NULL); - -static int -checkifname(prop_dictionary_t env) -{ - const char *ifname; - - if ((ifname = getifname(env)) == NULL) - return 1; - - return strncmp(ifname, "agr", 3) != 0 || - !isdigit((unsigned char)ifname[3]); -} - -static void -assertifname(prop_dictionary_t env) -{ - if (checkifname(env)) - errx(EXIT_FAILURE, "valid only with agr(4) interfaces"); -} - -int -agrsetport(prop_dictionary_t env, prop_dictionary_t oenv) -{ - char buf[IFNAMSIZ]; - struct agrreq ar; - const char *port; - int64_t cmd; - - if (!prop_dictionary_get_int64(env, "agrcmd", &cmd)) { - warnx("%s.%d", __func__, __LINE__); - errno = ENOENT; - return -1; - } - - if (!prop_dictionary_get_cstring_nocopy(env, "agrport", &port)) { - warnx("%s.%d", __func__, __LINE__); - errno = ENOENT; - return -1; - } - strlcpy(buf, port, sizeof(buf)); - - assertifname(env); - memset(&ar, 0, sizeof(ar)); - ar.ar_version = AGRREQ_VERSION; - ar.ar_cmd = cmd; - ar.ar_buf = buf; - ar.ar_buflen = strlen(buf); - - if (indirect_ioctl(env, SIOCSETAGR, &ar) == -1) - err(EXIT_FAILURE, "SIOCSETAGR"); - return 0; -} - -static void -agr_status(prop_dictionary_t env, prop_dictionary_t oenv) -{ - struct agrreq ar; - void *buf = NULL; - size_t buflen = 0; - struct agrportlist *apl; - struct agrportinfo *api; - int i; - - if (checkifname(env)) - return; - -again: - memset(&ar, 0, sizeof(ar)); - ar.ar_version = AGRREQ_VERSION; - ar.ar_cmd = AGRCMD_PORTLIST; - ar.ar_buf = buf; - ar.ar_buflen = buflen; - - if (indirect_ioctl(env, SIOCGETAGR, &ar) == -1) { - if (errno != E2BIG) { - warn("SIOCGETAGR"); - return; - } - - free(buf); - buf = NULL; - buflen = 0; - goto again; - } - - if (buf == NULL) { - buflen = ar.ar_buflen; - buf = malloc(buflen); - if (buf == NULL) { - err(EXIT_FAILURE, "agr_status"); - } - goto again; - } - - apl = buf; - api = (void *)(apl + 1); - - for (i = 0; i < apl->apl_nports; i++) { - char tmp[256]; - - snprintb(tmp, sizeof(tmp), AGRPORTINFO_BITS, api->api_flags); - printf("\tagrport: %s, flags=%s\n", api->api_ifname, tmp); - api++; - } -} - -static status_func_t status; -static usage_func_t usage; -static cmdloop_branch_t branch; - -static void -agr_usage(prop_dictionary_t env) -{ - fprintf(stderr, "\t[ agrport i ] [ -agrport i ]\n"); -} - -static void -agr_constructor(void) -{ - status_func_init(&status, agr_status); - usage_func_init(&usage, agr_usage); - register_status(&status); - register_usage(&usage); - cmdloop_branch_init(&branch, &agr.pk_parser); - register_cmdloop_branch(&branch); -} diff --git a/sbin/ifconfig/carp.c b/sbin/ifconfig/carp.c deleted file mode 100644 index e9fcf2c8a..000000000 --- a/sbin/ifconfig/carp.c +++ /dev/null @@ -1,295 +0,0 @@ -/* $NetBSD: carp.c,v 1.13 2009/09/11 23:22:28 dyoung Exp $ */ - -/* - * Copyright (c) 2002 Michael Shalayeff. All rights reserved. - * Copyright (c) 2003 Ryan McBride. 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 HIS RELATIVES 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 MIND, 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 -#ifndef lint -__RCSID("$NetBSD: carp.c,v 1.13 2009/09/11 23:22:28 dyoung Exp $"); -#endif /* not lint */ - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "env.h" -#include "parse.h" -#include "extern.h" - -static status_func_t status; -static usage_func_t usage; -static cmdloop_branch_t branch; - -static void carp_constructor(void) __attribute__((constructor)); -static void carp_status(prop_dictionary_t, prop_dictionary_t); -static int setcarp_advbase(prop_dictionary_t, prop_dictionary_t); -static int setcarp_advskew(prop_dictionary_t, prop_dictionary_t); -static int setcarp_passwd(prop_dictionary_t, prop_dictionary_t); -static int setcarp_vhid(prop_dictionary_t, prop_dictionary_t); -static int setcarp_state(prop_dictionary_t, prop_dictionary_t); -static int setcarpdev(prop_dictionary_t, prop_dictionary_t); - -static const char *carp_states[] = { CARP_STATES }; - -struct kwinst carpstatekw[] = { - {.k_word = "INIT", .k_nextparser = &command_root.pb_parser} - , {.k_word = "BACKUP", .k_nextparser = &command_root.pb_parser} - , {.k_word = "MASTER", .k_nextparser = &command_root.pb_parser} -}; - -struct pinteger parse_advbase = PINTEGER_INITIALIZER1(&parse_advbase, "advbase", - 0, 255, 10, setcarp_advbase, "advbase", &command_root.pb_parser); - -struct pinteger parse_advskew = PINTEGER_INITIALIZER1(&parse_advskew, "advskew", - 0, 254, 10, setcarp_advskew, "advskew", &command_root.pb_parser); - -struct piface carpdev = PIFACE_INITIALIZER(&carpdev, "carpdev", setcarpdev, - "carpdev", &command_root.pb_parser); - -struct pkw carpstate = PKW_INITIALIZER(&carpstate, "carp state", setcarp_state, - "carp_state", carpstatekw, __arraycount(carpstatekw), - &command_root.pb_parser); - -struct pstr pass = PSTR_INITIALIZER(&pass, "pass", setcarp_passwd, - "pass", &command_root.pb_parser); - -struct pinteger parse_vhid = PINTEGER_INITIALIZER1(&vhid, "vhid", - 0, 255, 10, setcarp_vhid, "vhid", &command_root.pb_parser); - -static const struct kwinst carpkw[] = { - {.k_word = "advbase", .k_nextparser = &parse_advbase.pi_parser} - , {.k_word = "advskew", .k_nextparser = &parse_advskew.pi_parser} - , {.k_word = "carpdev", .k_nextparser = &carpdev.pif_parser} - , {.k_word = "-carpdev", .k_key = "carpdev", .k_type = KW_T_STR, - .k_str = "", .k_exec = setcarpdev, - .k_nextparser = &command_root.pb_parser} - , {.k_word = "pass", .k_nextparser = &pass.ps_parser} - , {.k_word = "state", .k_nextparser = &carpstate.pk_parser} - , {.k_word = "vhid", .k_nextparser = &parse_vhid.pi_parser} -}; - -struct pkw carp = PKW_INITIALIZER(&carp, "CARP", NULL, NULL, - carpkw, __arraycount(carpkw), NULL); - -static void -carp_set(prop_dictionary_t env, struct carpreq *carpr) -{ - if (indirect_ioctl(env, SIOCSVH, carpr) == -1) - err(EXIT_FAILURE, "SIOCSVH"); -} - -static int -carp_get1(prop_dictionary_t env, struct carpreq *carpr) -{ - memset(carpr, 0, sizeof(*carpr)); - - return indirect_ioctl(env, SIOCGVH, carpr); -} - -static void -carp_get(prop_dictionary_t env, struct carpreq *carpr) -{ - if (carp_get1(env, carpr) == -1) - err(EXIT_FAILURE, "SIOCGVH"); -} - -static void -carp_status(prop_dictionary_t env, prop_dictionary_t oenv) -{ - const char *state; - struct carpreq carpr; - - if (carp_get1(env, &carpr) == -1) - return; - - if (carpr.carpr_vhid <= 0) - return; - if (carpr.carpr_state > CARP_MAXSTATE) - state = ""; - else - state = carp_states[carpr.carpr_state]; - - printf("\tcarp: %s carpdev %s vhid %d advbase %d advskew %d\n", - state, carpr.carpr_carpdev[0] != '\0' ? - carpr.carpr_carpdev : "none", carpr.carpr_vhid, - carpr.carpr_advbase, carpr.carpr_advskew); -} - -int -setcarp_passwd(prop_dictionary_t env, prop_dictionary_t oenv) -{ - struct carpreq carpr; - prop_data_t data; - - data = (prop_data_t)prop_dictionary_get(env, "pass"); - if (data == NULL) { - errno = ENOENT; - return -1; - } - - carp_get(env, &carpr); - - memset(carpr.carpr_key, 0, sizeof(carpr.carpr_key)); - /* XXX Should hash the password into the key here, perhaps? */ - strlcpy((char *)carpr.carpr_key, prop_data_data_nocopy(data), - MIN(CARP_KEY_LEN, prop_data_size(data))); - - carp_set(env, &carpr); - return 0; -} - -int -setcarp_vhid(prop_dictionary_t env, prop_dictionary_t oenv) -{ - struct carpreq carpr; - int64_t vhid; - - if (!prop_dictionary_get_int64(env, "vhid", &vhid)) { - errno = ENOENT; - return -1; - } - - carp_get(env, &carpr); - - carpr.carpr_vhid = vhid; - - carp_set(env, &carpr); - return 0; -} - -int -setcarp_advskew(prop_dictionary_t env, prop_dictionary_t oenv) -{ - struct carpreq carpr; - int64_t advskew; - - if (!prop_dictionary_get_int64(env, "advskew", &advskew)) { - errno = ENOENT; - return -1; - } - - carp_get(env, &carpr); - - carpr.carpr_advskew = advskew; - - carp_set(env, &carpr); - return 0; -} - -/* ARGSUSED */ -int -setcarp_advbase(prop_dictionary_t env, prop_dictionary_t oenv) -{ - struct carpreq carpr; - int64_t advbase; - - if (!prop_dictionary_get_int64(env, "advbase", &advbase)) { - errno = ENOENT; - return -1; - } - - carp_get(env, &carpr); - - carpr.carpr_advbase = advbase; - - carp_set(env, &carpr); - return 0; -} - -/* ARGSUSED */ -static int -setcarp_state(prop_dictionary_t env, prop_dictionary_t oenv) -{ - struct carpreq carpr; - int64_t carp_state; - - if (!prop_dictionary_get_int64(env, "carp_state", &carp_state)) { - errno = ENOENT; - return -1; - } - - carp_get(env, &carpr); - - carpr.carpr_state = carp_state; - - carp_set(env, &carpr); - return 0; -} - -/* ARGSUSED */ -int -setcarpdev(prop_dictionary_t env, prop_dictionary_t oenv) -{ - struct carpreq carpr; - prop_string_t s; - - s = (prop_string_t)prop_dictionary_get(env, "carpdev"); - if (s == NULL) { - errno = ENOENT; - return -1; - } - - carp_get(env, &carpr); - - strlcpy(carpr.carpr_carpdev, prop_string_cstring_nocopy(s), - sizeof(carpr.carpr_carpdev)); - - carp_set(env, &carpr); - return 0; -} - -static void -carp_usage(prop_dictionary_t env) -{ - fprintf(stderr, - "\t[ advbase n ] [ advskew n ] [ carpdev iface ] " - "[ pass passphrase ] [ state state ] [ vhid n ]\n"); - -} - -static void -carp_constructor(void) -{ - cmdloop_branch_init(&branch, &carp.pk_parser); - register_cmdloop_branch(&branch); - status_func_init(&status, carp_status); - usage_func_init(&usage, carp_usage); - register_status(&status); - register_usage(&usage); -} diff --git a/sbin/ifconfig/extern.h b/sbin/ifconfig/extern.h deleted file mode 100644 index d8ef47990..000000000 --- a/sbin/ifconfig/extern.h +++ /dev/null @@ -1,93 +0,0 @@ -/* $NetBSD: extern.h,v 1.14 2009/08/07 18:53:37 dyoung Exp $ */ - -/* - * Copyright (c) 1983, 1993 - * The Regents of the University of California. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ -#ifndef _IFCONFIG_EXTERN_H -#define _IFCONFIG_EXTERN_H - -#include -#include "util.h" - -#define RIDADDR 0 -#define ADDR 1 -#define MASK 2 -#define DSTADDR 3 - -typedef void (*usage_cb_t)(prop_dictionary_t); -typedef void (*status_cb_t)(prop_dictionary_t, prop_dictionary_t); -typedef void (*statistics_cb_t)(prop_dictionary_t); - -enum flag_type { - FLAG_T_MOD = 0 - , FLAG_T_CMD = 1 -}; - -typedef enum flag_type flag_type_t; - -struct statistics_func { - SIMPLEQ_ENTRY(statistics_func) f_next; - statistics_cb_t f_func; -}; - -struct usage_func { - SIMPLEQ_ENTRY(usage_func) f_next; - usage_cb_t f_func; -}; - -struct status_func { - SIMPLEQ_ENTRY(status_func) f_next; - status_cb_t f_func; -}; - -struct cmdloop_branch { - SIMPLEQ_ENTRY(cmdloop_branch) b_next; - struct parser *b_parser; -}; - - -typedef struct statistics_func statistics_func_t; -typedef struct status_func status_func_t; -typedef struct usage_func usage_func_t; -typedef struct cmdloop_branch cmdloop_branch_t; - -void cmdloop_branch_init(cmdloop_branch_t *, struct parser *); -int register_family(struct afswtch *); -int register_cmdloop_branch(cmdloop_branch_t *); -void statistics_func_init(statistics_func_t *, statistics_cb_t); -void status_func_init(status_func_t *, status_cb_t); -void usage_func_init(usage_func_t *, usage_cb_t); -int register_statistics(statistics_func_t *); -int register_status(status_func_t *); -int register_usage(usage_func_t *); -int register_flag(int); -bool get_flag(int); - -extern bool lflag, Nflag, vflag, zflag; - -#endif /* _IFCONFIG_EXTERN_H */ diff --git a/sbin/ifconfig/ieee80211.c b/sbin/ifconfig/ieee80211.c deleted file mode 100644 index b20364ca2..000000000 --- a/sbin/ifconfig/ieee80211.c +++ /dev/null @@ -1,1375 +0,0 @@ -/* $NetBSD: ieee80211.c,v 1.28 2015/04/28 15:14:57 christos Exp $ */ - -/* - * Copyright (c) 1983, 1993 - * The Regents of the University of California. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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 -#ifndef lint -__RCSID("$NetBSD: ieee80211.c,v 1.28 2015/04/28 15:14:57 christos Exp $"); -#endif /* not lint */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "extern.h" -#include "parse.h" -#include "env.h" -#include "util.h" -#include "prog_ops.h" - -static void ieee80211_statistics(prop_dictionary_t); -static void ieee80211_status(prop_dictionary_t, prop_dictionary_t); -static void ieee80211_constructor(void) __attribute__((constructor)); -static int set80211(prop_dictionary_t env, uint16_t, int16_t, int16_t, - u_int8_t *); -static u_int ieee80211_mhz2ieee(u_int, u_int); -static int getmaxrate(const uint8_t [15], u_int8_t); -static const char * getcaps(int); -static void printie(const char*, const uint8_t *, size_t, int); -static int copy_essid(char [], size_t, const u_int8_t *, size_t); -static void scan_and_wait(prop_dictionary_t); -static void list_scan(prop_dictionary_t); -static int mappsb(u_int , u_int); -static int mapgsm(u_int , u_int); - -static int sethidessid(prop_dictionary_t, prop_dictionary_t); -static int setapbridge(prop_dictionary_t, prop_dictionary_t); -static int setifssid(prop_dictionary_t, prop_dictionary_t); -static int setifnwkey(prop_dictionary_t, prop_dictionary_t); -static int unsetifnwkey(prop_dictionary_t, prop_dictionary_t); -static int unsetifbssid(prop_dictionary_t, prop_dictionary_t); -static int setifbssid(prop_dictionary_t, prop_dictionary_t); -static int setifchan(prop_dictionary_t, prop_dictionary_t); -static int setiffrag(prop_dictionary_t, prop_dictionary_t); -static int setifpowersave(prop_dictionary_t, prop_dictionary_t); -static int setifpowersavesleep(prop_dictionary_t, prop_dictionary_t); -static int setifrts(prop_dictionary_t, prop_dictionary_t); -static int scan_exec(prop_dictionary_t, prop_dictionary_t); - -static void printies(const u_int8_t *, int, int); -static void printwmeparam(const char *, const u_int8_t *, size_t , int); -static void printwmeinfo(const char *, const u_int8_t *, size_t , int); -static const char * wpa_cipher(const u_int8_t *); -static const char * wpa_keymgmt(const u_int8_t *); -static void printwpaie(const char *, const u_int8_t *, size_t , int); -static const char * rsn_cipher(const u_int8_t *); -static const char * rsn_keymgmt(const u_int8_t *); -static void printrsnie(const char *, const u_int8_t *, size_t , int); -static void printssid(const char *, const u_int8_t *, size_t , int); -static void printrates(const char *, const u_int8_t *, size_t , int); -static void printcountry(const char *, const u_int8_t *, size_t , int); -static int iswpaoui(const u_int8_t *); -static int iswmeinfo(const u_int8_t *); -static int iswmeparam(const u_int8_t *); -static const char * iename(int); - -extern struct pinteger parse_chan, parse_frag, parse_rts; -extern struct pstr parse_bssid, parse_ssid, parse_nwkey; -extern struct pinteger parse_powersavesleep; - -static const struct kwinst ieee80211boolkw[] = { - {.k_word = "hidessid", .k_key = "hidessid", .k_neg = true, - .k_type = KW_T_BOOL, .k_bool = true, .k_negbool = false, - .k_exec = sethidessid} - , {.k_word = "apbridge", .k_key = "apbridge", .k_neg = true, - .k_type = KW_T_BOOL, .k_bool = true, .k_negbool = false, - .k_exec = setapbridge} - , {.k_word = "powersave", .k_key = "powersave", .k_neg = true, - .k_type = KW_T_BOOL, .k_bool = true, .k_negbool = false, - .k_exec = setifpowersave} -}; - -static const struct kwinst listskw[] = { - {.k_word = "scan", .k_exec = scan_exec} -}; - -static struct pkw lists = PKW_INITIALIZER(&lists, "ieee80211 lists", NULL, - "list", listskw, __arraycount(listskw), &command_root.pb_parser); - -static const struct kwinst kw80211kw[] = { - {.k_word = "bssid", .k_nextparser = &parse_bssid.ps_parser} - , {.k_word = "-bssid", .k_exec = unsetifbssid, - .k_nextparser = &command_root.pb_parser} - , {.k_word = "chan", .k_nextparser = &parse_chan.pi_parser} - , {.k_word = "-chan", .k_key = "chan", .k_type = KW_T_UINT, - .k_uint = IEEE80211_CHAN_ANY, .k_exec = setifchan, - .k_nextparser = &command_root.pb_parser} - , {.k_word = "frag", .k_nextparser = &parse_frag.pi_parser} - , {.k_word = "-frag", .k_key = "frag", .k_type = KW_T_INT, - .k_int = IEEE80211_FRAG_MAX, .k_exec = setiffrag, - .k_nextparser = &command_root.pb_parser} - , {.k_word = "list", .k_nextparser = &lists.pk_parser} - , {.k_word = "nwid", .k_nextparser = &parse_ssid.ps_parser} - , {.k_word = "nwkey", .k_nextparser = &parse_nwkey.ps_parser} - , {.k_word = "-nwkey", .k_exec = unsetifnwkey, - .k_nextparser = &command_root.pb_parser} - , {.k_word = "rts", .k_nextparser = &parse_rts.pi_parser} - , {.k_word = "-rts", .k_key = "rts", .k_type = KW_T_INT, - .k_int = IEEE80211_RTS_MAX, .k_exec = setifrts, - .k_nextparser = &command_root.pb_parser} - , {.k_word = "ssid", .k_nextparser = &parse_ssid.ps_parser} - , {.k_word = "powersavesleep", - .k_nextparser = &parse_powersavesleep.pi_parser} -}; - -struct pkw kw80211 = PKW_INITIALIZER(&kw80211, "802.11 keywords", NULL, NULL, - kw80211kw, __arraycount(kw80211kw), NULL); - -struct pkw ieee80211bool = PKW_INITIALIZER(&ieee80211bool, "ieee80211 boolean", - NULL, NULL, ieee80211boolkw, __arraycount(ieee80211boolkw), - &command_root.pb_parser); - -struct pinteger parse_chan = PINTEGER_INITIALIZER1(&parse_chan, "chan", - 0, UINT16_MAX, 10, setifchan, "chan", &command_root.pb_parser); - -struct pinteger parse_rts = PINTEGER_INITIALIZER1(&parse_rts, "rts", - IEEE80211_RTS_MIN, IEEE80211_RTS_MAX, 10, - setifrts, "rts", &command_root.pb_parser); - -struct pinteger parse_frag = PINTEGER_INITIALIZER1(&parse_frag, "frag", - IEEE80211_FRAG_MIN, IEEE80211_FRAG_MAX, 10, - setiffrag, "frag", &command_root.pb_parser); - -struct pstr parse_ssid = PSTR_INITIALIZER(&parse_pass, "ssid", setifssid, - "ssid", &command_root.pb_parser); - -struct pinteger parse_powersavesleep = - PINTEGER_INITIALIZER1(&parse_powersavesleep, "powersavesleep", - 0, INT_MAX, 10, setifpowersavesleep, "powersavesleep", - &command_root.pb_parser); - -struct pstr parse_nwkey = PSTR_INITIALIZER1(&parse_nwkey, "nwkey", setifnwkey, - "nwkey", false, &command_root.pb_parser); - -struct pstr parse_bssid = PSTR_INITIALIZER1(&parse_bssid, "bssid", setifbssid, - "bssid", false, &command_root.pb_parser); - -static int -set80211(prop_dictionary_t env, uint16_t type, int16_t val, int16_t len, - u_int8_t *data) -{ - struct ieee80211req ireq; - - memset(&ireq, 0, sizeof(ireq)); - ireq.i_type = type; - ireq.i_val = val; - ireq.i_len = len; - ireq.i_data = data; - if (direct_ioctl(env, SIOCS80211, &ireq) == -1) { - warn("SIOCS80211"); - return -1; - } - return 0; -} - -static int -sethidessid(prop_dictionary_t env, prop_dictionary_t oenv) -{ - bool on, rc; - - rc = prop_dictionary_get_bool(env, "hidessid", &on); - assert(rc); - return set80211(env, IEEE80211_IOC_HIDESSID, on ? 1 : 0, 0, NULL); -} - -static int -setapbridge(prop_dictionary_t env, prop_dictionary_t oenv) -{ - bool on, rc; - - rc = prop_dictionary_get_bool(env, "apbridge", &on); - assert(rc); - return set80211(env, IEEE80211_IOC_APBRIDGE, on ? 1 : 0, 0, NULL); -} - -static enum ieee80211_opmode -get80211opmode(prop_dictionary_t env) -{ - struct ifmediareq ifmr; - - memset(&ifmr, 0, sizeof(ifmr)); - if (direct_ioctl(env, SIOCGIFMEDIA, &ifmr) == -1) - ; - else if (ifmr.ifm_current & IFM_IEEE80211_ADHOC) - return IEEE80211_M_IBSS; /* XXX ahdemo */ - else if (ifmr.ifm_current & IFM_IEEE80211_HOSTAP) - return IEEE80211_M_HOSTAP; - else if (ifmr.ifm_current & IFM_IEEE80211_MONITOR) - return IEEE80211_M_MONITOR; - - return IEEE80211_M_STA; -} - -static int -setifssid(prop_dictionary_t env, prop_dictionary_t oenv) -{ - struct ieee80211_nwid nwid; - ssize_t len; - - memset(&nwid, 0, sizeof(nwid)); - if ((len = getargdata(env, "ssid", nwid.i_nwid, - sizeof(nwid.i_nwid))) == -1) - errx(EXIT_FAILURE, "%s: SSID too long", __func__); - nwid.i_len = (uint8_t)len; - if (indirect_ioctl(env, SIOCS80211NWID, &nwid) == -1) - err(EXIT_FAILURE, "SIOCS80211NWID"); - return 0; -} - -static int -unsetifbssid(prop_dictionary_t env, prop_dictionary_t oenv) -{ - struct ieee80211_bssid bssid; - - memset(&bssid, 0, sizeof(bssid)); - - if (direct_ioctl(env, SIOCS80211BSSID, &bssid) == -1) - err(EXIT_FAILURE, "SIOCS80211BSSID"); - return 0; -} - -static int -setifbssid(prop_dictionary_t env, prop_dictionary_t oenv) -{ - char buf[24]; - struct ieee80211_bssid bssid; - struct ether_addr *ea; - - if (getargstr(env, "bssid", buf, sizeof(buf)) == -1) - errx(EXIT_FAILURE, "%s: BSSID too long", __func__); - - ea = ether_aton(buf); - if (ea == NULL) { - errx(EXIT_FAILURE, "malformed BSSID: %s", buf); - return -1; - } - memcpy(&bssid.i_bssid, ea->ether_addr_octet, - sizeof(bssid.i_bssid)); - - if (direct_ioctl(env, SIOCS80211BSSID, &bssid) == -1) - err(EXIT_FAILURE, "SIOCS80211BSSID"); - return 0; -} - -static int -setifrts(prop_dictionary_t env, prop_dictionary_t oenv) -{ - bool rc; - int16_t val; - - rc = prop_dictionary_get_int16(env, "rts", &val); - assert(rc); - if (set80211(env, IEEE80211_IOC_RTSTHRESHOLD, val, 0, NULL) == -1) - err(EXIT_FAILURE, "IEEE80211_IOC_RTSTHRESHOLD"); - return 0; -} - -static int -setiffrag(prop_dictionary_t env, prop_dictionary_t oenv) -{ - bool rc; - int16_t val; - - rc = prop_dictionary_get_int16(env, "frag", &val); - assert(rc); - if (set80211(env, IEEE80211_IOC_FRAGTHRESHOLD, val, 0, NULL) == -1) - err(EXIT_FAILURE, "IEEE80211_IOC_FRAGTHRESHOLD"); - return 0; -} - -static int -setifchan(prop_dictionary_t env, prop_dictionary_t oenv) -{ - bool rc; - struct ieee80211chanreq channel; - - rc = prop_dictionary_get_uint16(env, "chan", &channel.i_channel); - assert(rc); - if (direct_ioctl(env, SIOCS80211CHANNEL, &channel) == -1) - err(EXIT_FAILURE, "SIOCS80211CHANNEL"); - return 0; -} - -static int -setifnwkey(prop_dictionary_t env, prop_dictionary_t oenv) -{ - const char *val; - char buf[256]; - struct ieee80211_nwkey nwkey; - int i; - u_int8_t keybuf[IEEE80211_WEP_NKID][16]; - - if (getargstr(env, "nwkey", buf, sizeof(buf)) == -1) - errx(EXIT_FAILURE, "%s: nwkey too long", __func__); - - val = buf; - - nwkey.i_wepon = IEEE80211_NWKEY_WEP; - nwkey.i_defkid = 1; - for (i = 0; i < IEEE80211_WEP_NKID; i++) { - nwkey.i_key[i].i_keylen = sizeof(keybuf[i]); - nwkey.i_key[i].i_keydat = keybuf[i]; - } - if (strcasecmp("persist", val) == 0) { - /* use all values from persistent memory */ - nwkey.i_wepon |= IEEE80211_NWKEY_PERSIST; - nwkey.i_defkid = 0; - for (i = 0; i < IEEE80211_WEP_NKID; i++) - nwkey.i_key[i].i_keylen = -1; - } else if (strncasecmp("persist:", val, 8) == 0) { - val += 8; - /* program keys in persistent memory */ - nwkey.i_wepon |= IEEE80211_NWKEY_PERSIST; - goto set_nwkey; - } else { - set_nwkey: - if (isdigit((unsigned char)val[0]) && val[1] == ':') { - /* specifying a full set of four keys */ - nwkey.i_defkid = val[0] - '0'; - val += 2; - for (i = 0; i < IEEE80211_WEP_NKID; i++) { - val = get_string(val, ",", keybuf[i], - &nwkey.i_key[i].i_keylen, true); - if (val == NULL) { - errno = EINVAL; - return -1; - } - } - if (*val != '\0') { - errx(EXIT_FAILURE, "SIOCS80211NWKEY: too many keys."); - } - } else { - val = get_string(val, NULL, keybuf[0], - &nwkey.i_key[0].i_keylen, true); - if (val == NULL) { - errno = EINVAL; - return -1; - } - i = 1; - } - } - for (; i < IEEE80211_WEP_NKID; i++) - nwkey.i_key[i].i_keylen = 0; - - if (direct_ioctl(env, SIOCS80211NWKEY, &nwkey) == -1) - err(EXIT_FAILURE, "SIOCS80211NWKEY"); - return 0; -} - -static int -unsetifnwkey(prop_dictionary_t env, prop_dictionary_t oenv) -{ - struct ieee80211_nwkey nwkey; - int i; - - nwkey.i_wepon = 0; - nwkey.i_defkid = 1; - for (i = 0; i < IEEE80211_WEP_NKID; i++) { - nwkey.i_key[i].i_keylen = 0; - nwkey.i_key[i].i_keydat = NULL; - } - - if (direct_ioctl(env, SIOCS80211NWKEY, &nwkey) == -1) - err(EXIT_FAILURE, "SIOCS80211NWKEY"); - return 0; -} - -static int -setifpowersave(prop_dictionary_t env, prop_dictionary_t oenv) -{ - struct ieee80211_power power; - bool on, rc; - - if (direct_ioctl(env, SIOCG80211POWER, &power) == -1) - err(EXIT_FAILURE, "SIOCG80211POWER"); - - rc = prop_dictionary_get_bool(env, "powersave", &on); - assert(rc); - - power.i_enabled = on ? 1 : 0; - if (direct_ioctl(env, SIOCS80211POWER, &power) == -1) { - warn("SIOCS80211POWER"); - return -1; - } - return 0; -} - -static int -setifpowersavesleep(prop_dictionary_t env, prop_dictionary_t oenv) -{ - struct ieee80211_power power; - int64_t maxsleep; - bool rc; - - rc = prop_dictionary_get_int64(env, "powersavesleep", &maxsleep); - assert(rc); - - if (direct_ioctl(env, SIOCG80211POWER, &power) == -1) - err(EXIT_FAILURE, "SIOCG80211POWER"); - - power.i_maxsleep = maxsleep; - if (direct_ioctl(env, SIOCS80211POWER, &power) == -1) - err(EXIT_FAILURE, "SIOCS80211POWER"); - return 0; -} - -static int -scan_exec(prop_dictionary_t env, prop_dictionary_t oenv) -{ - struct ifreq ifr; - - if (direct_ioctl(env, SIOCGIFFLAGS, &ifr) == -1) { - warn("ioctl(SIOCGIFFLAGS)"); - return -1; - } - - if ((ifr.ifr_flags & IFF_UP) == 0) - errx(EXIT_FAILURE, "The interface must be up before scanning."); - - scan_and_wait(env); - list_scan(env); - - return 0; -} - -static void -ieee80211_statistics(prop_dictionary_t env) -{ -#ifndef SMALL - struct ieee80211_stats stats; - struct ifreq ifr; - - memset(&ifr, 0, sizeof(ifr)); - ifr.ifr_buflen = sizeof(stats); - ifr.ifr_buf = (caddr_t)&stats; - if (direct_ioctl(env, (zflag) ? SIOCG80211ZSTATS : SIOCG80211STATS, - &ifr) == -1) - return; -#define STAT_PRINT(_member, _desc) \ - printf("\t" _desc ": %" PRIu32 "\n", stats._member) - - STAT_PRINT(is_rx_badversion, "rx frame with bad version"); - STAT_PRINT(is_rx_tooshort, "rx frame too short"); - STAT_PRINT(is_rx_wrongbss, "rx from wrong bssid"); - STAT_PRINT(is_rx_dup, "rx discard 'cuz dup"); - STAT_PRINT(is_rx_wrongdir, "rx w/ wrong direction"); - STAT_PRINT(is_rx_mcastecho, "rx discard 'cuz mcast echo"); - STAT_PRINT(is_rx_notassoc, "rx discard 'cuz sta !assoc"); - STAT_PRINT(is_rx_noprivacy, "rx w/ wep but privacy off"); - STAT_PRINT(is_rx_unencrypted, "rx w/o wep and privacy on"); - STAT_PRINT(is_rx_wepfail, "rx wep processing failed"); - STAT_PRINT(is_rx_decap, "rx decapsulation failed"); - STAT_PRINT(is_rx_mgtdiscard, "rx discard mgt frames"); - STAT_PRINT(is_rx_ctl, "rx discard ctrl frames"); - STAT_PRINT(is_rx_beacon, "rx beacon frames"); - STAT_PRINT(is_rx_rstoobig, "rx rate set truncated"); - STAT_PRINT(is_rx_elem_missing, "rx required element missing"); - STAT_PRINT(is_rx_elem_toobig, "rx element too big"); - STAT_PRINT(is_rx_elem_toosmall, "rx element too small"); - STAT_PRINT(is_rx_elem_unknown, "rx element unknown"); - STAT_PRINT(is_rx_badchan, "rx frame w/ invalid chan"); - STAT_PRINT(is_rx_chanmismatch, "rx frame chan mismatch"); - STAT_PRINT(is_rx_nodealloc, "rx frame dropped"); - STAT_PRINT(is_rx_ssidmismatch, "rx frame ssid mismatch "); - STAT_PRINT(is_rx_auth_unsupported, "rx w/ unsupported auth alg"); - STAT_PRINT(is_rx_auth_fail, "rx sta auth failure"); - STAT_PRINT(is_rx_auth_countermeasures, "rx auth discard 'cuz CM"); - STAT_PRINT(is_rx_assoc_bss, "rx assoc from wrong bssid"); - STAT_PRINT(is_rx_assoc_notauth, "rx assoc w/o auth"); - STAT_PRINT(is_rx_assoc_capmismatch, "rx assoc w/ cap mismatch"); - STAT_PRINT(is_rx_assoc_norate, "rx assoc w/ no rate match"); - STAT_PRINT(is_rx_assoc_badwpaie, "rx assoc w/ bad WPA IE"); - STAT_PRINT(is_rx_deauth, "rx deauthentication"); - STAT_PRINT(is_rx_disassoc, "rx disassociation"); - STAT_PRINT(is_rx_badsubtype, "rx frame w/ unknown subtyp"); - STAT_PRINT(is_rx_nobuf, "rx failed for lack of buf"); - STAT_PRINT(is_rx_decryptcrc, "rx decrypt failed on crc"); - STAT_PRINT(is_rx_ahdemo_mgt, "rx discard ahdemo mgt fram"); - STAT_PRINT(is_rx_bad_auth, "rx bad auth request"); - STAT_PRINT(is_rx_unauth, "rx on unauthorized port"); - STAT_PRINT(is_rx_badkeyid, "rx w/ incorrect keyid"); - STAT_PRINT(is_rx_ccmpreplay, "rx seq# violation (CCMP)"); - STAT_PRINT(is_rx_ccmpformat, "rx format bad (CCMP)"); - STAT_PRINT(is_rx_ccmpmic, "rx MIC check failed (CCMP)"); - STAT_PRINT(is_rx_tkipreplay, "rx seq# violation (TKIP)"); - STAT_PRINT(is_rx_tkipformat, "rx format bad (TKIP)"); - STAT_PRINT(is_rx_tkipmic, "rx MIC check failed (TKIP)"); - STAT_PRINT(is_rx_tkipicv, "rx ICV check failed (TKIP)"); - STAT_PRINT(is_rx_badcipher, "rx failed 'cuz key type"); - STAT_PRINT(is_rx_nocipherctx, "rx failed 'cuz key !setup"); - STAT_PRINT(is_rx_acl, "rx discard 'cuz acl policy"); - - STAT_PRINT(is_tx_nobuf, "tx failed for lack of buf"); - STAT_PRINT(is_tx_nonode, "tx failed for no node"); - STAT_PRINT(is_tx_unknownmgt, "tx of unknown mgt frame"); - STAT_PRINT(is_tx_badcipher, "tx failed 'cuz key type"); - STAT_PRINT(is_tx_nodefkey, "tx failed 'cuz no defkey"); - STAT_PRINT(is_tx_noheadroom, "tx failed 'cuz no space"); - STAT_PRINT(is_tx_fragframes, "tx frames fragmented"); - STAT_PRINT(is_tx_frags, "tx fragments created"); - - STAT_PRINT(is_scan_active, "active scans started"); - STAT_PRINT(is_scan_passive, "passive scans started"); - STAT_PRINT(is_node_timeout, "nodes timed out inactivity"); - STAT_PRINT(is_crypto_nomem, "no memory for crypto ctx"); - STAT_PRINT(is_crypto_tkip, "tkip crypto done in s/w"); - STAT_PRINT(is_crypto_tkipenmic, "tkip en-MIC done in s/w"); - STAT_PRINT(is_crypto_tkipdemic, "tkip de-MIC done in s/w"); - STAT_PRINT(is_crypto_tkipcm, "tkip counter measures"); - STAT_PRINT(is_crypto_ccmp, "ccmp crypto done in s/w"); - STAT_PRINT(is_crypto_wep, "wep crypto done in s/w"); - STAT_PRINT(is_crypto_setkey_cipher, "cipher rejected key"); - STAT_PRINT(is_crypto_setkey_nokey, "no key index for setkey"); - STAT_PRINT(is_crypto_delkey, "driver key delete failed"); - STAT_PRINT(is_crypto_badcipher, "unknown cipher"); - STAT_PRINT(is_crypto_nocipher, "cipher not available"); - STAT_PRINT(is_crypto_attachfail, "cipher attach failed"); - STAT_PRINT(is_crypto_swfallback, "cipher fallback to s/w"); - STAT_PRINT(is_crypto_keyfail, "driver key alloc failed"); - STAT_PRINT(is_crypto_enmicfail, "en-MIC failed"); - STAT_PRINT(is_ibss_capmismatch, "merge failed-cap mismatch"); - STAT_PRINT(is_ibss_norate, "merge failed-rate mismatch"); - STAT_PRINT(is_ps_unassoc, "ps-poll for unassoc. sta"); - STAT_PRINT(is_ps_badaid, "ps-poll w/ incorrect aid"); - STAT_PRINT(is_ps_qempty, "ps-poll w/ nothing to send"); - STAT_PRINT(is_ff_badhdr, "fast frame rx'd w/ bad hdr"); - STAT_PRINT(is_ff_tooshort, "fast frame rx decap error"); - STAT_PRINT(is_ff_split, "fast frame rx split error"); - STAT_PRINT(is_ff_decap, "fast frames decap'd"); - STAT_PRINT(is_ff_encap, "fast frames encap'd for tx"); - STAT_PRINT(is_rx_badbintval, "rx frame w/ bogus bintval"); -#endif -} - -static void -ieee80211_status(prop_dictionary_t env, prop_dictionary_t oenv) -{ - int i, nwkey_verbose; - struct ieee80211_nwid nwid; - struct ieee80211_nwkey nwkey; - struct ieee80211_power power; - u_int8_t keybuf[IEEE80211_WEP_NKID][16]; - struct ieee80211_bssid bssid; - struct ieee80211chanreq channel; - struct ieee80211req ireq; - struct ether_addr ea; - static const u_int8_t zero_macaddr[IEEE80211_ADDR_LEN]; - enum ieee80211_opmode opmode = get80211opmode(env); - - memset(&bssid, 0, sizeof(bssid)); - memset(&nwkey, 0, sizeof(nwkey)); - memset(&nwid, 0, sizeof(nwid)); - memset(&nwid, 0, sizeof(nwid)); - - if (indirect_ioctl(env, SIOCG80211NWID, &nwid) == -1) - return; - if (nwid.i_len > IEEE80211_NWID_LEN) { - errx(EXIT_FAILURE, "SIOCG80211NWID: wrong length of nwid (%d)", nwid.i_len); - } - printf("\tssid "); - print_string(nwid.i_nwid, nwid.i_len); - - if (opmode == IEEE80211_M_HOSTAP) { - ireq.i_type = IEEE80211_IOC_HIDESSID; - if (direct_ioctl(env, SIOCG80211, &ireq) != -1) { - if (ireq.i_val) - printf(" [hidden]"); - else if (vflag) - printf(" [shown]"); - } - - ireq.i_type = IEEE80211_IOC_APBRIDGE; - if (direct_ioctl(env, SIOCG80211, &ireq) != -1) { - if (ireq.i_val) - printf(" apbridge"); - else if (vflag) - printf(" -apbridge"); - } - } - - ireq.i_type = IEEE80211_IOC_RTSTHRESHOLD; - if (direct_ioctl(env, SIOCG80211, &ireq) == -1) - ; - else if (ireq.i_val < IEEE80211_RTS_MAX) - printf(" rts %d", ireq.i_val); - else if (vflag) - printf(" -rts"); - - ireq.i_type = IEEE80211_IOC_FRAGTHRESHOLD; - if (direct_ioctl(env, SIOCG80211, &ireq) == -1) - ; - else if (ireq.i_val < IEEE80211_FRAG_MAX) - printf(" frag %d", ireq.i_val); - else if (vflag) - printf(" -frag"); - - memset(&nwkey, 0, sizeof(nwkey)); - /* show nwkey only when WEP is enabled */ - if (direct_ioctl(env, SIOCG80211NWKEY, &nwkey) == -1 || - nwkey.i_wepon == 0) { - printf("\n"); - goto skip_wep; - } - - printf(" nwkey "); - /* try to retrieve WEP keys */ - for (i = 0; i < IEEE80211_WEP_NKID; i++) { - nwkey.i_key[i].i_keydat = keybuf[i]; - nwkey.i_key[i].i_keylen = sizeof(keybuf[i]); - } - if (direct_ioctl(env, SIOCG80211NWKEY, &nwkey) == -1) { - printf("*****"); - } else { - nwkey_verbose = 0; - /* check to see non default key or multiple keys defined */ - if (nwkey.i_defkid != 1) { - nwkey_verbose = 1; - } else { - for (i = 1; i < IEEE80211_WEP_NKID; i++) { - if (nwkey.i_key[i].i_keylen != 0) { - nwkey_verbose = 1; - break; - } - } - } - /* check extra ambiguity with keywords */ - if (!nwkey_verbose) { - if (nwkey.i_key[0].i_keylen >= 2 && - isdigit(nwkey.i_key[0].i_keydat[0]) && - nwkey.i_key[0].i_keydat[1] == ':') - nwkey_verbose = 1; - else if (nwkey.i_key[0].i_keylen >= 7 && - strncasecmp("persist", - (const char *)nwkey.i_key[0].i_keydat, 7) == 0) - nwkey_verbose = 1; - } - if (nwkey_verbose) - printf("%d:", nwkey.i_defkid); - for (i = 0; i < IEEE80211_WEP_NKID; i++) { - if (i > 0) - printf(","); - if (nwkey.i_key[i].i_keylen < 0) - printf("persist"); - else - print_string(nwkey.i_key[i].i_keydat, - nwkey.i_key[i].i_keylen); - if (!nwkey_verbose) - break; - } - } - printf("\n"); - - skip_wep: - if (direct_ioctl(env, SIOCG80211POWER, &power) == -1) - goto skip_power; - printf("\tpowersave "); - if (power.i_enabled) - printf("on (%dms sleep)", power.i_maxsleep); - else - printf("off"); - printf("\n"); - - skip_power: - if (direct_ioctl(env, SIOCG80211BSSID, &bssid) == -1) - return; - if (direct_ioctl(env, SIOCG80211CHANNEL, &channel) == -1) - return; - if (memcmp(bssid.i_bssid, zero_macaddr, IEEE80211_ADDR_LEN) == 0) { - if (channel.i_channel != (u_int16_t)-1) - printf("\tchan %d\n", channel.i_channel); - } else { - memcpy(ea.ether_addr_octet, bssid.i_bssid, - sizeof(ea.ether_addr_octet)); - printf("\tbssid %s", ether_ntoa(&ea)); - if (channel.i_channel != IEEE80211_CHAN_ANY) - printf(" chan %d", channel.i_channel); - printf("\n"); - } -} - -static void -scan_and_wait(prop_dictionary_t env) -{ - int sroute; - - sroute = prog_socket(PF_ROUTE, SOCK_RAW, 0); - if (sroute < 0) { - warn("socket(PF_ROUTE,SOCK_RAW)"); - return; - } - /* NB: only root can trigger a scan so ignore errors */ - if (set80211(env, IEEE80211_IOC_SCAN_REQ, 0, 0, NULL) >= 0) { - char buf[2048]; - struct if_announcemsghdr *ifan; - struct rt_msghdr *rtm; - - do { - if (prog_read(sroute, buf, sizeof(buf)) < 0) { - warn("read(PF_ROUTE)"); - break; - } - rtm = (struct rt_msghdr *) buf; - if (rtm->rtm_version != RTM_VERSION) - break; - ifan = (struct if_announcemsghdr *) rtm; - } while (rtm->rtm_type != RTM_IEEE80211 || - ifan->ifan_what != RTM_IEEE80211_SCAN); - } - prog_close(sroute); -} - -static void -list_scan(prop_dictionary_t env) -{ - u_int8_t buf[24*1024]; - struct ieee80211req ireq; - char ssid[IEEE80211_NWID_LEN+1]; - const u_int8_t *cp; - int len, ssidmax; - - memset(&ireq, 0, sizeof(ireq)); - ireq.i_type = IEEE80211_IOC_SCAN_RESULTS; - ireq.i_data = buf; - ireq.i_len = sizeof(buf); - if (direct_ioctl(env, SIOCG80211, &ireq) < 0) - errx(EXIT_FAILURE, "unable to get scan results"); - len = ireq.i_len; - if (len < (int)sizeof(struct ieee80211req_scan_result)) - return; - - ssidmax = IEEE80211_NWID_LEN; - printf("%-*.*s %-17.17s %4s %4s %-7s %3s %4s\n" - , ssidmax, ssidmax, "SSID" - , "BSSID" - , "CHAN" - , "RATE" - , "S:N" - , "INT" - , "CAPS" - ); - cp = buf; - do { - const struct ieee80211req_scan_result *sr; - const uint8_t *vp; - - sr = (const struct ieee80211req_scan_result *) cp; - vp = (const u_int8_t *)(sr+1); - printf("%-*.*s %s %3d %3dM %3d:%-3d %3d %-4.4s" - , ssidmax - , copy_essid(ssid, ssidmax, vp, sr->isr_ssid_len) - , ssid - , ether_ntoa((const struct ether_addr *) sr->isr_bssid) - , ieee80211_mhz2ieee(sr->isr_freq, sr->isr_flags) - , getmaxrate(sr->isr_rates, sr->isr_nrates) - , sr->isr_rssi, sr->isr_noise - , sr->isr_intval - , getcaps(sr->isr_capinfo) - ); - printies(vp + sr->isr_ssid_len, sr->isr_ie_len, 24); - printf("\n"); - cp += sr->isr_len, len -= sr->isr_len; - } while (len >= (int)sizeof(struct ieee80211req_scan_result)); -} -/* - * Convert MHz frequency to IEEE channel number. - */ -static u_int -ieee80211_mhz2ieee(u_int isrfreq, u_int isrflags) -{ - if ((isrflags & IEEE80211_CHAN_GSM) || (907 <= isrfreq && isrfreq <= 922)) - return mapgsm(isrfreq, isrflags); - if (isrfreq == 2484) - return 14; - if (isrfreq < 2484) - return (isrfreq - 2407) / 5; - if (isrfreq < 5000) { - if (isrflags & (IEEE80211_CHAN_HALF|IEEE80211_CHAN_QUARTER)) - return mappsb(isrfreq, isrflags); - else if (isrfreq > 4900) - return (isrfreq - 4000) / 5; - else - return 15 + ((isrfreq - 2512) / 20); - } - return (isrfreq - 5000) / 5; -} - -static int -getmaxrate(const u_int8_t rates[15], u_int8_t nrates) -{ - int i, maxrate = -1; - - for (i = 0; i < nrates; i++) { - int rate = rates[i] & IEEE80211_RATE_VAL; - if (rate > maxrate) - maxrate = rate; - } - return maxrate / 2; -} - -static const char * -getcaps(int capinfo) -{ - static char capstring[32]; - char *cp = capstring; - - if (capinfo & IEEE80211_CAPINFO_ESS) - *cp++ = 'E'; - if (capinfo & IEEE80211_CAPINFO_IBSS) - *cp++ = 'I'; - if (capinfo & IEEE80211_CAPINFO_CF_POLLABLE) - *cp++ = 'c'; - if (capinfo & IEEE80211_CAPINFO_CF_POLLREQ) - *cp++ = 'C'; - if (capinfo & IEEE80211_CAPINFO_PRIVACY) - *cp++ = 'P'; - if (capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) - *cp++ = 'S'; - if (capinfo & IEEE80211_CAPINFO_PBCC) - *cp++ = 'B'; - if (capinfo & IEEE80211_CAPINFO_CHNL_AGILITY) - *cp++ = 'A'; - if (capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME) - *cp++ = 's'; - if (capinfo & IEEE80211_CAPINFO_RSN) - *cp++ = 'R'; - if (capinfo & IEEE80211_CAPINFO_DSSSOFDM) - *cp++ = 'D'; - *cp = '\0'; - return capstring; -} - -static void -printie(const char* tag, const uint8_t *ie, size_t ielen, int maxlen) -{ - printf("%s", tag); - - maxlen -= strlen(tag)+2; - if ((int)(2*ielen) > maxlen) - maxlen--; - printf("<"); - for (; ielen > 0; ie++, ielen--) { - if (maxlen-- <= 0) - break; - printf("%02x", *ie); - } - if (ielen != 0) - printf("-"); - printf(">"); -} - -#define LE_READ_2(p) \ - ((u_int16_t) \ - ((((const u_int8_t *)(p))[0] ) | \ - (((const u_int8_t *)(p))[1] << 8))) -#define LE_READ_4(p) \ - ((u_int32_t) \ - ((((const u_int8_t *)(p))[0] ) | \ - (((const u_int8_t *)(p))[1] << 8) | \ - (((const u_int8_t *)(p))[2] << 16) | \ - (((const u_int8_t *)(p))[3] << 24))) - -/* - * NB: The decoding routines assume a properly formatted ie - * which should be safe as the kernel only retains them - * if they parse ok. - */ - -static void -printwmeparam(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen) -{ -#define MS(_v, _f) (((_v) & _f) >> _f##_S) - static const char *acnames[] = { "BE", "BK", "VO", "VI" }; - const struct ieee80211_wme_param *wme = - (const struct ieee80211_wme_param *) ie; - int i; - - printf("%s", tag); - if (!vflag) - return; - printf("param_qosInfo); - ie += offsetof(struct ieee80211_wme_param, params_acParams); - for (i = 0; i < WME_NUM_AC; i++) { - const struct ieee80211_wme_acparams *ac = - &wme->params_acParams[i]; - - printf(" %s[%saifsn %u cwmin %u cwmax %u txop %u]" - , acnames[i] - , MS(ac->acp_aci_aifsn, WME_PARAM_ACM) ? "acm " : "" - , MS(ac->acp_aci_aifsn, WME_PARAM_AIFSN) - , MS(ac->acp_logcwminmax, WME_PARAM_LOGCWMIN) - , MS(ac->acp_logcwminmax, WME_PARAM_LOGCWMAX) - , LE_READ_2(&ac->acp_txop) - ); - } - printf(">"); -#undef MS -} - -static void -printwmeinfo(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen) -{ - printf("%s", tag); - if (vflag) { - const struct ieee80211_wme_info *wme = - (const struct ieee80211_wme_info *) ie; - printf("", - wme->wme_version, wme->wme_info); - } -} - -static const char * -wpa_cipher(const u_int8_t *sel) -{ -#define WPA_SEL(x) (((x)<<24)|WPA_OUI) - u_int32_t w = LE_READ_4(sel); - - switch (w) { - case WPA_SEL(WPA_CSE_NULL): - return "NONE"; - case WPA_SEL(WPA_CSE_WEP40): - return "WEP40"; - case WPA_SEL(WPA_CSE_WEP104): - return "WEP104"; - case WPA_SEL(WPA_CSE_TKIP): - return "TKIP"; - case WPA_SEL(WPA_CSE_CCMP): - return "AES-CCMP"; - } - return "?"; /* NB: so 1<< is discarded */ -#undef WPA_SEL -} - -static const char * -wpa_keymgmt(const u_int8_t *sel) -{ -#define WPA_SEL(x) (((x)<<24)|WPA_OUI) - u_int32_t w = LE_READ_4(sel); - - switch (w) { - case WPA_SEL(WPA_ASE_8021X_UNSPEC): - return "8021X-UNSPEC"; - case WPA_SEL(WPA_ASE_8021X_PSK): - return "8021X-PSK"; - case WPA_SEL(WPA_ASE_NONE): - return "NONE"; - } - return "?"; -#undef WPA_SEL -} - -static void -printwpaie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen) -{ - u_int8_t len = ie[1]; - - printf("%s", tag); - if (vflag) { - const char *sep; - int n; - - ie += 6, len -= 4; /* NB: len is payload only */ - - printf(" 0; n--) { - printf("%s%s", sep, wpa_cipher(ie)); - ie += 4, len -= 4; - sep = "+"; - } - - /* key management algorithms */ - n = LE_READ_2(ie); - ie += 2, len -= 2; - sep = " km:"; - for (; n > 0; n--) { - printf("%s%s", sep, wpa_keymgmt(ie)); - ie += 4, len -= 4; - sep = "+"; - } - - if (len > 2) /* optional capabilities */ - printf(", caps 0x%x", LE_READ_2(ie)); - printf(">"); - } -} - -static const char * -rsn_cipher(const u_int8_t *sel) -{ -#define RSN_SEL(x) (((x)<<24)|RSN_OUI) - u_int32_t w = LE_READ_4(sel); - - switch (w) { - case RSN_SEL(RSN_CSE_NULL): - return "NONE"; - case RSN_SEL(RSN_CSE_WEP40): - return "WEP40"; - case RSN_SEL(RSN_CSE_WEP104): - return "WEP104"; - case RSN_SEL(RSN_CSE_TKIP): - return "TKIP"; - case RSN_SEL(RSN_CSE_CCMP): - return "AES-CCMP"; - case RSN_SEL(RSN_CSE_WRAP): - return "AES-OCB"; - } - return "?"; -#undef WPA_SEL -} - -static const char * -rsn_keymgmt(const u_int8_t *sel) -{ -#define RSN_SEL(x) (((x)<<24)|RSN_OUI) - u_int32_t w = LE_READ_4(sel); - - switch (w) { - case RSN_SEL(RSN_ASE_8021X_UNSPEC): - return "8021X-UNSPEC"; - case RSN_SEL(RSN_ASE_8021X_PSK): - return "8021X-PSK"; - case RSN_SEL(RSN_ASE_NONE): - return "NONE"; - } - return "?"; -#undef RSN_SEL -} - -static void -printrsnie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen) -{ - const char *sep; - int n; - - printf("%s", tag); - if (!vflag) - return; - - ie += 2, ielen -= 2; - - printf(" 0; n--) { - printf("%s%s", sep, rsn_cipher(ie)); - ie += 4, ielen -= 4; - sep = "+"; - } - - /* key management algorithms */ - n = LE_READ_2(ie); - ie += 2, ielen -= 2; - sep = " km:"; - for (; n > 0; n--) { - printf("%s%s", sep, rsn_keymgmt(ie)); - ie += 4, ielen -= 4; - sep = "+"; - } - - if (ielen > 2) /* optional capabilities */ - printf(", caps 0x%x", LE_READ_2(ie)); - /* XXXPMKID */ - printf(">"); -} - -/* - * Copy the ssid string contents into buf, truncating to fit. If the - * ssid is entirely printable then just copy intact. Otherwise convert - * to hexadecimal. If the result is truncated then replace the last - * three characters with "...". - */ -static int -copy_essid(char buf[], size_t bufsize, const u_int8_t *essid, size_t essid_len) -{ - const u_int8_t *p; - size_t maxlen, i; - - if (essid_len > bufsize) - maxlen = bufsize; - else - maxlen = essid_len; - /* determine printable or not */ - for (i = 0, p = essid; i < maxlen; i++, p++) { - if (*p < ' ' || *p > 0x7e) - break; - } - if (i != maxlen) { /* not printable, print as hex */ - if (bufsize < 3) - return 0; - strlcpy(buf, "0x", bufsize); - bufsize -= 2; - p = essid; - for (i = 0; i < maxlen && bufsize >= 2; i++) { - sprintf(&buf[2+2*i], "%02x", p[i]); - bufsize -= 2; - } - if (i != essid_len) - memcpy(&buf[2+2*i-3], "...", 3); - } else { /* printable, truncate as needed */ - memcpy(buf, essid, maxlen); - if (maxlen != essid_len) - memcpy(&buf[maxlen-3], "...", 3); - } - return maxlen; -} - -static void -printssid(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen) -{ - char ssid[2*IEEE80211_NWID_LEN+1]; - - printf("%s<%.*s>", tag, copy_essid(ssid, maxlen, ie+2, ie[1]), ssid); -} - -static void -printrates(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen) -{ - const char *sep; - size_t i; - - printf("%s", tag); - sep = "<"; - for (i = 2; i < ielen; i++) { - printf("%s%s%d", sep, - ie[i] & IEEE80211_RATE_BASIC ? "B" : "", - ie[i] & IEEE80211_RATE_VAL); - sep = ","; - } - printf(">"); -} - -static void -printcountry(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen) -{ - const struct ieee80211_country_ie *cie = - (const struct ieee80211_country_ie *) ie; - int i, nbands, schan, nchan; - - printf("%s<%c%c%c", tag, cie->cc[0], cie->cc[1], cie->cc[2]); - nbands = (cie->len - 3) / sizeof(cie->band[0]); - for (i = 0; i < nbands; i++) { - schan = cie->band[i].schan; - nchan = cie->band[i].nchan; - if (nchan != 1) - printf(" %u-%u,%u", schan, schan + nchan-1, - cie->band[i].maxtxpwr); - else - printf(" %u,%u", schan, cie->band[i].maxtxpwr); - } - printf(">"); -} - -/* unaligned little endian access */ -#define LE_READ_4(p) \ - ((u_int32_t) \ - ((((const u_int8_t *)(p))[0] ) | \ - (((const u_int8_t *)(p))[1] << 8) | \ - (((const u_int8_t *)(p))[2] << 16) | \ - (((const u_int8_t *)(p))[3] << 24))) - -static int -iswpaoui(const u_int8_t *frm) -{ - return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI); -} - -static int -iswmeinfo(const u_int8_t *frm) -{ - return frm[1] > 5 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI) && - frm[6] == WME_INFO_OUI_SUBTYPE; -} - -static int -iswmeparam(const u_int8_t *frm) -{ - return frm[1] > 5 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI) && - frm[6] == WME_PARAM_OUI_SUBTYPE; -} - -static const char * -iename(int elemid) -{ - switch (elemid) { - case IEEE80211_ELEMID_FHPARMS: return " FHPARMS"; - case IEEE80211_ELEMID_CFPARMS: return " CFPARMS"; - case IEEE80211_ELEMID_TIM: return " TIM"; - case IEEE80211_ELEMID_IBSSPARMS:return " IBSSPARMS"; - case IEEE80211_ELEMID_CHALLENGE:return " CHALLENGE"; - case IEEE80211_ELEMID_PWRCNSTR: return " PWRCNSTR"; - case IEEE80211_ELEMID_PWRCAP: return " PWRCAP"; - case IEEE80211_ELEMID_TPCREQ: return " TPCREQ"; - case IEEE80211_ELEMID_TPCREP: return " TPCREP"; - case IEEE80211_ELEMID_SUPPCHAN: return " SUPPCHAN"; - case IEEE80211_ELEMID_CHANSWITCHANN:return " CSA"; - case IEEE80211_ELEMID_MEASREQ: return " MEASREQ"; - case IEEE80211_ELEMID_MEASREP: return " MEASREP"; - case IEEE80211_ELEMID_QUIET: return " QUIET"; - case IEEE80211_ELEMID_IBSSDFS: return " IBSSDFS"; - case IEEE80211_ELEMID_TPC: return " TPC"; - case IEEE80211_ELEMID_CCKM: return " CCKM"; - } - return " ???"; -} - -static void -printies(const u_int8_t *vp, int ielen, int maxcols) -{ - while (ielen > 0) { - switch (vp[0]) { - case IEEE80211_ELEMID_SSID: - if (vflag) - printssid(" SSID", vp, 2+vp[1], maxcols); - break; - case IEEE80211_ELEMID_RATES: - case IEEE80211_ELEMID_XRATES: - if (vflag) - printrates(vp[0] == IEEE80211_ELEMID_RATES ? - " RATES" : " XRATES", vp, 2+vp[1], maxcols); - break; - case IEEE80211_ELEMID_DSPARMS: - if (vflag) - printf(" DSPARMS<%u>", vp[2]); - break; - case IEEE80211_ELEMID_COUNTRY: - if (vflag) - printcountry(" COUNTRY", vp, 2+vp[1], maxcols); - break; - case IEEE80211_ELEMID_ERP: - if (vflag) - printf(" ERP<0x%x>", vp[2]); - break; - case IEEE80211_ELEMID_VENDOR: - if (iswpaoui(vp)) - printwpaie(" WPA", vp, 2+vp[1], maxcols); - else if (iswmeinfo(vp)) - printwmeinfo(" WME", vp, 2+vp[1], maxcols); - else if (iswmeparam(vp)) - printwmeparam(" WME", vp, 2+vp[1], maxcols); - else if (vflag) - printie(" VEN", vp, 2+vp[1], maxcols); - break; - case IEEE80211_ELEMID_RSN: - printrsnie(" RSN", vp, 2+vp[1], maxcols); - break; - default: - if (vflag) - printie(iename(vp[0]), vp, 2+vp[1], maxcols); - break; - } - ielen -= 2+vp[1]; - vp += 2+vp[1]; - } -} - -static int -mapgsm(u_int isrfreq, u_int isrflags) -{ - isrfreq *= 10; - if (isrflags & IEEE80211_CHAN_QUARTER) - isrfreq += 5; - else if (isrflags & IEEE80211_CHAN_HALF) - isrfreq += 10; - else - isrfreq += 20; - /* NB: there is no 907/20 wide but leave room */ - return (isrfreq - 906*10) / 5; -} - -static int -mappsb(u_int isrfreq, u_int isrflags) -{ - return 37 + ((isrfreq * 10) + ((isrfreq % 5) == 2 ? 5 : 0) - 49400) / 5; -} - -static status_func_t status; -static usage_func_t usage; -static statistics_func_t statistics; -static cmdloop_branch_t branch[2]; - -static void -ieee80211_usage(prop_dictionary_t env) -{ - fprintf(stderr, - "\t[ nwid network_id ] [ nwkey network_key | -nwkey ]\n" - "\t[ list scan ]\n" - "\t[ powersave | -powersave ] [ powersavesleep duration ]\n" - "\t[ hidessid | -hidessid ] [ apbridge | -apbridge ]\n"); -} - -static void -ieee80211_constructor(void) -{ - cmdloop_branch_init(&branch[0], &ieee80211bool.pk_parser); - cmdloop_branch_init(&branch[1], &kw80211.pk_parser); - register_cmdloop_branch(&branch[0]); - register_cmdloop_branch(&branch[1]); - status_func_init(&status, ieee80211_status); - statistics_func_init(&statistics, ieee80211_statistics); - usage_func_init(&usage, ieee80211_usage); - register_status(&status); - register_statistics(&statistics); - register_usage(&usage); -} diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8 deleted file mode 100644 index 5357cb56d..000000000 --- a/sbin/ifconfig/ifconfig.8 +++ /dev/null @@ -1,920 +0,0 @@ -.\" $NetBSD: ifconfig.8,v 1.109 2014/10/20 14:50:09 roy Exp $ -.\" -.\" Copyright (c) 1983, 1991, 1993 -.\" The Regents of the University of California. 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. -.\" 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. -.\" -.\" @(#)ifconfig.8 8.4 (Berkeley) 6/1/94 -.\" -.Dd October 12, 2014 -.Dt IFCONFIG 8 -.Os -.Sh NAME -.Nm ifconfig -.Nd configure network interface parameters -.Sh SYNOPSIS -.Nm -.Op Fl N -.Ar interface address_family -.Oo -.Ar address -.Op Ar dest_address -.Oc -.Op Ar parameters -.Nm -.Op Fl hLmNvz -.Ar interface -.Op Ar protocol_family -.Nm -.Fl a -.Op Fl bdhLNmsuvz -.Op Ar protocol_family -.Nm -.Fl l -.Op Fl bdsu -.Nm -.Fl s -.Ar interface -.Nm -.Fl w -.Ar secs -.Nm -.Fl C -.Sh DESCRIPTION -.Nm -is used to assign an address -to a network interface and/or configure -network interface parameters. -.Nm -must be used at boot time to define the network address -of each interface present on a machine; it may also be used at -a later time to redefine an interface's address -or other operating parameters. -.Pp -Available operands for -.Nm : -.Bl -tag -width Ds -.It Ar address -For the -.Tn DARPA-Internet -family, -the address is either a host name present in the host name data -base, -.Xr hosts 5 , -or a -.Tn DARPA -Internet address expressed in the Internet standard -.Dq dot notation . -For the Xerox Network Systems(tm) family, -addresses are -.Ar net:a.b.c.d.e.f , -where -.Ar net -is the assigned network number -.Pq in decimal , -and each of the six bytes of the host number, -.Ar a -through -.Ar f , -are specified in hexadecimal. -The host number may be omitted on Ethernet interfaces, -which use the hardware physical address, -and on interfaces other than the first. -For the -.Tn ISO -family, addresses are specified as a long hexadecimal string, -as in the Xerox family. -However, two consecutive dots imply a zero -byte, and the dots are optional, if the user wishes to -.Pq carefully -count out long strings of digits in network byte order. -.It Ar address_family -Specifies the -.Ar address_family -which affects interpretation of the remaining parameters. -Since an interface can receive transmissions in differing protocols -with different naming schemes, specifying the address family is recommended. -The address or protocol families currently -supported are -.Dq inet , -.Dq inet6 , -.Dq atalk , -.Dq iso , -and -.Dq link . -.It Ar interface -The -.Ar interface -parameter is a string of the form -.Dq name unit , -for example, -.Dq en0 -.El -.Pp -The following parameters may be set with -.Nm : -.Bl -tag -width dest_addressxx -.It Cm active -This keyword applies when -.Nm -adds or modifies any link-layer address. -It indicates that -.Nm -should -.Dq activate -the address. -Activation makes an address the default source for transmissions -on the interface. -You may not delete the active address from an interface. -You must activate some other address, first. -.It Cm advbase Ar n -If the driver is a -.Xr carp 4 -pseudo-device, set the base advertisement interval to -.Ar n -seconds. -This ia an 8-bit number; the default value is 1 second. -.It Cm advskew Ar n -If the driver is a -.Xr carp 4 -pseudo-device, skew the advertisement interval by -.Ar n . -This is an 8-bit number; the default value is 0. -.Pp -Taken together the -.Cm advbase -indicate how frequently, in seconds, the host will advertise the fact that it -considers itself the master of the virtual host. -The formula is -.Cm advbase -+ -.Pf ( Cm advskew -/ 256). -If the master does not advertise within three times this interval, this host -will begin advertising as master. -.It Cm alias -Establish an additional network address for this interface. -This is sometimes useful when changing network numbers, and -one wishes to accept packets addressed to the old interface. -.It Fl alias -Remove the specified network address alias. -.It Cm arp -Enable the use of the Address Resolution Protocol in mapping -between network level addresses and link level addresses -.Pq default . -This is currently implemented for mapping between -.Tn DARPA -Internet -addresses and Ethernet addresses. -.It Fl arp -Disable the use of the Address Resolution Protocol. -.It Cm anycast -.Pq inet6 only -Set the IPv6 anycast address bit. -.It Fl anycast -.Pq inet6 only -Clear the IPv6 anycast address bit. -.It Cm broadcast Ar mask -.Pq Inet only -Specify the address to use to represent broadcasts to the -network. -The default broadcast address is the address with a host part of all 1's. -.It Cm carpdev Ar iface -If the driver is a -.Xr carp 4 -pseudo-device, attach it to -.Ar iface . -If not specified, the kernel will attempt to select an interface with -a subnet matching that of the carp interface. -.It Cm debug -Enable driver dependent debugging code; usually, this turns on -extra console error logging. -.It Fl debug -Disable driver dependent debugging code. -.It Cm delete -Remove the network address specified. -This would be used if you incorrectly specified an alias, or it -was no longer needed. -If you have incorrectly set an NS address having the side effect -of specifying the host portion, removing all NS addresses will -allow you to respecify the host portion. -.Cm delete -does not work for IPv6 addresses. -Use -.Fl alias -with explicit IPv6 address instead. -.It Ar dest_address -Specify the address of the correspondent on the other end -of a point to point link. -.It Cm down -Mark an interface ``down''. -When an interface is -marked ``down'', the system will not attempt to -transmit messages through that interface. -If possible, the interface will be reset to disable reception as well. -This action does not automatically disable routes using the interface. -.It Cm ipdst -This is used to specify an Internet host who is willing to receive -ip packets encapsulating NS packets bound for a remote network. -An apparent point to point link is constructed, and -the address specified will be taken as the NS address and network -of the destination. -IP encapsulation of -.Tn CLNP -packets is done differently. -.It Cm media Ar type -Set the media type of the interface to -.Ar type . -Some interfaces support the mutually exclusive use of one of several -different physical media connectors. -For example, a 10Mb/s Ethernet -interface might support the use of either -.Tn AUI -or twisted pair connectors. -Setting the media type to -.Dq 10base5 -or -.Dq AUI -would change the currently active connector to the AUI port. -Setting it to -.Dq 10baseT -or -.Dq UTP -would activate twisted pair. -Refer to the interfaces' driver -specific man page for a complete list of the available types -and the -.Xr ifmedia 4 -manual page for a list of media types. -See the -.Fl m -flag below. -.It Cm mediaopt Ar opts -Set the specified media options on the interface. -.Ar opts -is a comma delimited list of options to apply to the interface. -Refer to the interfaces' driver specific man page for a complete -list of available options. -Also see the -.Xr ifmedia 4 -manual page for a list of media options. -.It Fl mediaopt Ar opts -Disable the specified media options on the interface. -.It Cm mode Ar mode -If the driver supports the media selection system, set the specified -operating mode on the interface to -.Ar mode . -For IEEE 802.11 wireless interfaces that support multiple operating modes -this directive is used to select between 802.11a -.Pq Dq 11a , -802.11b -.Pq Dq 11b , -and 802.11g -.Pq Dq 11g -operating modes. -.It Cm instance Ar minst -Set the media instance to -.Ar minst . -This is useful for devices which have multiple physical layer interfaces -.Pq PHYs . -Setting the instance on such devices may not be strictly required -by the network interface driver as the driver may take care of this -automatically; see the driver's manual page for more information. -.It Cm metric Ar n -Set the routing metric of the interface to -.Ar n , -default 0. -The routing metric is used by the routing protocol -.Pq Xr routed 8 . -Higher metrics have the effect of making a route -less favorable; metrics are counted as addition hops -to the destination network or host. -.It Cm mtu Ar n -Set the maximum transmission unit of the interface to -.Ar n . -Most interfaces don't support this option. -.It Cm netmask Ar mask -.Pq inet, inet6, and ISO -Specify how much of the address to reserve for subdividing -networks into sub-networks. -The mask includes the network part of the local address -and the subnet part, which is taken from the host field of the address. -The mask can be specified as a single hexadecimal number -with a leading 0x, with a dot-notation Internet address, -or with a pseudo-network name listed in the network table -.Xr networks 5 . -The mask contains 1's for the bit positions in the 32-bit address -which are to be used for the network and subnet parts, -and 0's for the host part. -The mask should contain at least the standard network portion, -and the subnet field should be contiguous with the network -portion. -.Pp -For INET and INET6 addresses, the netmask can also be given with -slash-notation after the address -.Pq e.g 192.168.17.3/24 . -.\" see -.\" Xr eon 5 . -.It Cm nsellength Ar n -.Pf ( Tn ISO -only) -This specifies a trailing number of bytes for a received -.Tn NSAP -used for local identification, the remaining leading part of which is -taken to be the -.Tn NET -.Pq Network Entity Title . -The default value is 1, which is conformant to US -.Tn GOSIP . -When an ISO address is set in an ifconfig command, -it is really the -.Tn NSAP -which is being specified. -For example, in -.Tn US GOSIP , -20 hex digits should be -specified in the -.Tn ISO NSAP -to be assigned to the interface. -There is some evidence that a number different from 1 may be useful -for -.Tn AFI -37 type addresses. -.It Cm state Ar state -Explicitly force the -.Xr carp 4 -pseudo-device to enter this state. -Valid states are -.Ar init , -.Ar backup , -and -.Ar master . -.It Cm frag Ar threshold -.Pq IEEE 802.11 devices only -Configure the fragmentation threshold for IEEE 802.11-based wireless -network interfaces. -.It Cm rts Ar threshold -.Pq IEEE 802.11 devices only -Configure the RTS/CTS threshold for IEEE 802.11-based wireless -network interfaces. -This controls the number of bytes used for the RTS/CTS handshake boundary. -The -.Ar threshold -can be any value between 0 and 2347. -The default is 2347, which indicates the RTS/CTS mechanism should not be used. -.It Cm ssid Ar id -.Pq IEEE 802.11 devices only -Configure the Service Set Identifier (a.k.a. the network name) -for IEEE 802.11-based wireless network interfaces. -The -.Ar id -can either be any text string up to 32 characters in length, -or a series of up to 64 hexadecimal digits preceded by -.Dq 0x . -Setting -.Ar id -to the empty string allows the interface to connect to any available -access point. -.It Cm nwid Ar id -Synonym for -.Dq ssid . -.It Cm hidessid -.Pq IEEE 802.11 devices only -When operating as an access point, do not broadcast the SSID -in beacon frames or respond to probe request frames unless -they are directed to the ap (i.e., they include the ap's SSID). -By default, the SSID is included in beacon frames and -undirected probe request frames are answered. -.It Fl hidessid -.Pq IEEE 802.11 devices only -When operating as an access point, broadcast the SSID -in beacon frames and answer and respond to undirected probe -request frames (default). -.It Cm nwkey Ar key -.Pq IEEE 802.11 devices only -Enable WEP encryption for IEEE 802.11-based wireless network interfaces -with the -.Ar key . -The -.Ar key -can either be a string, a series of hexadecimal digits preceded by -.Dq 0x , -or a set of keys in the form -.Ar n:k1,k2,k3,k4 , -where -.Ar n -specifies which of keys will be used for all transmitted packets, -and four keys, -.Ar k1 -through -.Ar k4 , -are configured as WEP keys. -Note that the order must be match within same network if multiple keys -are used. -For IEEE 802.11 wireless network, the length of each key is restricted to -40 bits, i.e. 5-character string or 10 hexadecimal digits, -while the WaveLAN/IEEE Gold cards accept the 104 bits -.Pq 13 characters -key. -.It Cm nwkey Cm persist -.Pq IEEE 802.11 devices only -Enable WEP encryption for IEEE 802.11-based wireless network interfaces -with the persistent key written in the network card. -.It Cm nwkey Cm persist: Ns Ar key -.Pq IEEE 802.11 devices only -Write the -.Ar key -to the persistent memory of the network card, and -enable WEP encryption for IEEE 802.11-based wireless network interfaces -with the -.Ar key . -.It Fl nwkey -.Pq IEEE 802.11 devices only -Disable WEP encryption for IEEE 802.11-based wireless network interfaces. -.It Cm apbridge -.Pq IEEE 802.11 devices only -When operating as an access point, pass packets between -wireless clients directly (default). -.It Fl apbridge -.Pq IEEE 802.11 devices only -When operating as an access point, pass packets through -the system so that they can be forwared using some other mechanism. -Disabling the internal bridging is useful when traffic -is to be processed with packet filtering. -.It Cm pass Ar passphrase -If the driver is a -.Xr carp 4 -pseudo-device, set the authentication key to -.Ar passphrase . -There is no passphrase by default -.It Cm powersave -.Pq IEEE 802.11 devices only -Enable 802.11 power saving mode. -.It Fl powersave -.Pq IEEE 802.11 devices only -Disable 802.11 power saving mode. -.It Cm powersavesleep Ar duration -.Pq IEEE 802.11 devices only -Set the receiver sleep duration in milliseconds for 802.11 power saving mode. -.It Cm bssid Ar bssid -.Pq IEEE 802.11 devices only -Set the desired BSSID for IEEE 802.11-based wireless network interfaces. -.It Fl bssid -.Pq IEEE 802.11 devices only -Unset the desired BSSID for IEEE 802.11-based wireless network interfaces. -The interface will automatically select a BSSID in this mode, which is -the default. -.It Cm chan Ar chan -.Pq IEEE 802.11 devices only -Select the channel -.Pq radio frequency -to be used for IEEE 802.11-based wireless network interfaces. -.It Fl chan -.Pq IEEE 802.11 devices only -Unset the desired channel to be used -for IEEE 802.11-based wireless network interfaces. -It doesn't affect the channel to be created for IBSS or hostap mode. -.It Cm list scan -.Pq IEEE 802.11 devices only -Display the access points and/or ad-hoc neighbors -located in the vicinity. -The -.Fl v -flag may be used to display long SSIDs. -.Fl v -also causes received information elements to be displayed symbolically. -The interface must be up before any scanning operation. -Only the super-user can use this command. -.It Cm tunnel Ar src_addr Ns Oo Ar ,src_port Oc Ar dest_addr Ns Oo Ar ,dest_port -.Oc -.Pq IP tunnel devices only -Configure the physical source and destination address for IP tunnel -interfaces, including -.Xr gif 4 . -The arguments -.Ar src_addr -and -.Ar dest_addr -are interpreted as the outer source/destination for the encapsulating -IPv4/IPv6 header. -.Pp -On a -.Xr gre 4 -interface in UDP mode, the arguments -.Ar src_port -and -.Ar dest_port -are interpreted as the outer source/destination port for the encapsulating -UDP header. -.It Cm deletetunnel -Unconfigure the physical source and destination address for IP tunnel -interfaces previously configured with -.Cm tunnel . -.It Cm create -Create the specified network pseudo-device. -.It Cm destroy -Destroy the specified network pseudo-device. -.It Cm pltime Ar n -.Pq inet6 only -Set preferred lifetime for the address. -.It Cm prefixlen Ar n -.Pq inet and inet6 only -Effect is similar to -.Cm netmask . -but you can specify by prefix length by digits. -.It Cm deprecated -.Pq inet6 only -Set the IPv6 deprecated address bit. -.It Fl deprecated -.Pq inet6 only -Clear the IPv6 deprecated address bit. -.It Cm eui64 -.Pq inet6 only -Fill interface index -.Pq lowermost 64bit of an IPv6 address -automatically. -.It Cm link[0-2] -Enable special processing of the link level of the interface. -These three options are interface specific in actual effect, however, -they are in general used to select special modes of operation. -An example -of this is to enable SLIP compression, or to select the connector type -for some Ethernet cards. -Refer to the man page for the specific driver -for more information. -.It Fl link[0-2] -Disable special processing at the link level with the specified interface. -.It Cm linkstr -Set a link-level string parameter for the interface. -This functionality varies from interface to interface. -Refer to the man page for the specific driver -for more information. -.It Fl linkstr -Remove an interface link-level string parameter. -.It Cm up -Mark an interface ``up''. -This may be used to enable an interface after an ``ifconfig down.'' -It happens automatically when setting the first address on an interface. -If the interface was reset when previously marked down, -the hardware will be re-initialized. -.It Cm vhid Ar n -If the driver is a -.Xr carp 4 -pseudo-device, set the virtual host ID to -.Ar n . -Acceptable values are 1 to 255. -.It Cm vlan Ar vid -If the interface is a -.Xr vlan 4 -pseudo-interface, set the VLAN identifier to -.Ar vid . -These are the first 12 bits (0-4095) from a 16-bit integer used -to create an 802.1Q VLAN header for packets sent from the -.Xr vlan 4 -interface. -Note that -.Cm vlan -and -.Cm vlanif -must be set at the same time. -.It Cm vlanif Ar iface -If the interface is a -.Xr vlan 4 -pseudo-interface, associate the physical interface -.Ar iface -with it. -Packets transmitted through the -.Xr vlan 4 -interface will be diverted to the specified physical interface -.Ar iface -with 802.1Q VLAN encapsulation. -Packets with 802.1Q encapsulation received -by the physical interface with the correct VLAN tag will be diverted to the -associated -.Xr vlan 4 -pseudo-interface. -The VLAN interface is assigned a copy of the physical -interface's flags and -.Tn Ethernet -address. -If the -.Xr vlan 4 -interface already has a physical interface associated with it, this command -will fail. -To change the association to another physical interface, the -existing association must be cleared first. -Note that -.Cm vlanif -and -.Cm vlan -must be set at the same time. -.It Cm -vlanif Ar iface -Dissociate -.Ar iface -from the -.Xr vlan 4 -interface. -.It Cm agrport Ar iface -Add -.Ar iface -to the -.Xr agr 4 -interface. -.It Cm -agrport Ar iface -Remove -.Ar iface -from the -.Xr agr 4 -interface. -.It Cm vltime Ar n -.Pq inet6 only -Set valid lifetime for the address. -.It Cm ip4csum -Shorthand of -.Dq ip4csum-tx ip4csum-rx -.It Cm -ip4csum -Shorthand of -.Dq -ip4csum-tx -ip4csum-rx -.It Cm tcp4csum -Shorthand of -.Dq tcp4csum-tx tcp4csum-rx -.It Cm -tcp4csum -Shorthand of -.Dq -tcp4csum-tx -tcp4csum-rx -.It Cm udp4csum -Shorthand of -.Dq udp4csum-tx udp4csum-rx -.It Cm -udp4csum -Shorthand of -.Dq -udp4csum-tx -udp4csum-rx -.It Cm tcp6csum -Shorthand of -.Dq tcp6csum-tx tcp6csum-rx -.It Cm -tcp6csum -Shorthand of -.Dq -tcp6csum-tx -tcp6csum-rx -.It Cm udp6csum -Shorthand of -.Dq udp6csum-tx udp6csum-rx -.It Cm -udp6csum -Shorthand of -.Dq -udp6csum-tx -udp6csum-rx -.It Cm ip4csum-tx -Enable hardware-assisted IPv4 header checksums for the out-bound direction. -.It Cm -ip4csum-tx -Disable hardware-assisted IPv4 header checksums for the out-bound direction. -.It Cm ip4csum-rx -Enable hardware-assisted IPv4 header checksums for the in-bound direction. -.It Cm -ip4csum-rx -Disable hardware-assisted IPv4 header checksums for the in-bound direction. -.It Cm tcp4csum-tx -Enable hardware-assisted TCP/IPv4 checksums for the out-bound direction. -.It Cm -tcp4csum-tx -Disable hardware-assisted TCP/IPv4 checksums for the out-bound direction. -.It Cm tcp4csum-rx -Enable hardware-assisted TCP/IPv4 checksums for the in-bound direction. -.It Cm -tcp4csum-rx -Disable hardware-assisted TCP/IPv4 checksums for the in-bound direction. -.It Cm udp4csum-tx -Enable hardware-assisted UDP/IPv4 checksums for the out-bound direction. -.It Cm -udp4csum-tx -Disable hardware-assisted UDP/IPv4 checksums for the out-bound direction. -.It Cm udp4csum-rx -Enable hardware-assisted UDP/IPv4 checksums for the in-bound direction. -.It Cm -udp4csum-rx -Disable hardware-assisted UDP/IPv4 checksums for the in-bound direction. -.It Cm tcp6csum-tx -Enable hardware-assisted TCP/IPv6 checksums for the out-bound direction. -.It Cm -tcp6csum-tx -Disable hardware-assisted TCP/IPv6 checksums for the out-bound direction. -.It Cm tcp6csum-rx -Enable hardware-assisted TCP/IPv6 checksums for the in-bound direction. -.It Cm -tcp6csum-rx -Disable hardware-assisted TCP/IPv6 checksums for the in-bound direction. -.It Cm udp6csum-tx -Enable hardware-assisted UDP/IPv6 checksums for the out-bound direction. -.It Cm -udp6csum-tx -Disable hardware-assisted UDP/IPv6 checksums for the out-bound direction. -.It Cm udp6csum-rx -Enable hardware-assisted UDP/IPv6 checksums for the in-bound direction. -.It Cm -udp6csum-rx -Disable hardware-assisted UDP/IPv6 checksums for the in-bound direction. -.It Cm tso4 -Enable hardware-assisted TCP/IPv4 segmentation on interfaces that -support it. -.It Cm -tso4 -Disable hardware-assisted TCP/IPv4 segmentation on interfaces that -support it. -.It Cm tso6 -Enable hardware-assisted TCP/IPv6 segmentation on interfaces that -support it. -.It Cm -tso6 -Disable hardware-assisted TCP/IPv6 segmentation on interfaces that -support it. -.It Cm maxupd Ar n -If the driver is a -.Xr pfsync 4 -pseudo-device, indicate the maximum number -of updates for a single state which can be collapsed into one. -This is an 8-bit number; the default value is 128. -.It Cm syncdev Ar iface -If the driver is a -.Xr pfsync 4 -pseudo-device, use the specified interface -to send and receive pfsync state synchronisation messages. -.It Fl syncdev -If the driver is a -.Xr pfsync 4 -pseudo-device, stop sending pfsync state -synchronisation messages over the network. -.It Cm syncpeer Ar peer_address -If the driver is a -.Xr pfsync 4 -pseudo-device, make the pfsync link point-to-point rather than using -multicast to broadcast the state synchronisation messages. -The peer_address is the IP address of the other host taking part in -the pfsync cluster. -With this option, -.Xr pfsync 4 -traffic can be protected using -.Xr ipsec 4 . -.It Fl syncpeer -If the driver is a -.Xr pfsync 4 -pseudo-device, broadcast the packets using multicast. -.El -.Pp -.Nm -displays the current configuration for a network interface -when no optional parameters are supplied. -If a protocol family is specified, -.Nm -will report only the details specific to that protocol -family. -.Pp -If the -.Fl s -flag is passed before an interface name, -.Nm -will attempt to query the interface for its media status. -If the -interface supports reporting media status, and it reports that it does -not appear to be connected to a network, -.Nm -will exit with status of 1 -.Pq false ; -otherwise, it will exit with a -zero -.Pq true -exit status. -Not all interface drivers support media -status reporting. -.Pp -If the -.Fl m -flag is passed before an interface name, -.Nm -will display all of the supported media for the specified interface. -If the -.Fl L -flag is supplied, address lifetime is displayed for IPv6 addresses, -as time offset string. -.Pp -Optionally, the -.Fl a -flag may be used instead of an interface name. -This flag instructs -.Nm -to display information about all interfaces in the system. -This is also the default behaviour when no arguments are given to -.Nm -on the command line. -When -.Fl a -is used, the output can be modified by adding more flags: -.Fl d -limits this to interfaces that are down, -.Fl u -limits this to interfaces that are up, -.Fl b -limits this to broadcast interfaces, and -.Fl s -omits interfaces which appear not to be connected to a network. -.Pp -The -.Fl l -flag may be used to list all available interfaces on the system, with -no other additional information. -Use of this flag is mutually exclusive -with all other flags and commands, except for -.Fl d -.Pq only list interfaces that are down , -.Fl u -.Pq only list interfaces that are up , -.Fl s -.Pq only list interfaces that may be connected , -.Fl b -.Pq only list broadcast interfaces . -.Pp -The -.Fl C -flag may be used to list all of the interface cloners available on -the system, with no additional information. -Use of this flag is -mutually exclusive with all other flags and commands. -.Pp -The -.Fl v -flag prints statistics on packets sent and received on the given -interface. -If -.Fl h -is used in conjunction with -.Fl v , -the byte statistics will be printed in "human-readable" format. -The -.Fl z -flag is identical to the -.Fl v -flag except that it zeros the interface input and output statistics -after printing them. -.Pp -The -.Fl w -flag may be used to wait -.Ar seconds -seconds for the -.Cm tentative -flag to be removed from all addresses. -0 seconds means to wait indefinitely until all addresses no longer have the -.Cm tentative -flag. -.Pp -The -.Fl N -flag is just the opposite of the -.Fl n -flag in -.Xr netstat 1 -or in -.Xr route 8 : -it tells -.Nm -to try to resolve numbers to hostnames or to service names. -The default -.Nm -behavior is to print numbers instead of names. -.Pp -Only the super-user may modify the configuration of a network interface. -.Sh EXAMPLES -Add a link-layer (MAC) address to an Ethernet: -.Pp -.Ic ifconfig sip0 link 00:11:22:33:44:55 -.Pp -Add and activate a link-layer (MAC) address: -.Pp -.Ic ifconfig sip0 link 00:11:22:33:44:55 active -.Sh DIAGNOSTICS -Messages indicating the specified interface does not exist, the -requested address is unknown, or the user is not privileged and -tried to alter an interface's configuration. -.Sh SEE ALSO -.Xr netstat 1 , -.Xr agr 4 , -.Xr carp 4 , -.Xr ifmedia 4 , -.Xr netintro 4 , -.Xr pfsync 4 , -.Xr vlan 4 , -.Xr ifconfig.if 5 , -.\" .Xr eon 5 , -.Xr rc 8 , -.Xr routed 8 -.Sh HISTORY -The -.Nm -command appeared in -.Bx 4.2 . diff --git a/sbin/ifconfig/media.c b/sbin/ifconfig/media.c deleted file mode 100644 index b945cb348..000000000 --- a/sbin/ifconfig/media.c +++ /dev/null @@ -1,464 +0,0 @@ -#include -#ifndef lint -__RCSID("$NetBSD: media.c,v 1.6 2011/08/29 14:35:00 joerg Exp $"); -#endif /* not lint */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include - -#include "env.h" -#include "extern.h" -#include "media.h" -#include "parse.h" -#include "util.h" -#include "prog_ops.h" - -static void init_current_media(prop_dictionary_t, prop_dictionary_t); -static void media_constructor(void) __attribute__((constructor)); -static int setmedia(prop_dictionary_t, prop_dictionary_t); -static int setmediainst(prop_dictionary_t, prop_dictionary_t); -static int setmediamode(prop_dictionary_t, prop_dictionary_t); -static int setmediaopt(prop_dictionary_t, prop_dictionary_t); -static int unsetmediaopt(prop_dictionary_t, prop_dictionary_t); - -/* - * Media stuff. Whenever a media command is first performed, the - * currently select media is grabbed for this interface. If `media' - * is given, the current media word is modifed. `mediaopt' commands - * only modify the set and clear words. They then operate on the - * current media word later. - */ -static int media_current; -static int mediaopt_set; -static int mediaopt_clear; - -static struct usage_func usage; - -static const int ifm_status_valid_list[] = IFM_STATUS_VALID_LIST; - -static const struct ifmedia_status_description ifm_status_descriptions[] = - IFM_STATUS_DESCRIPTIONS; - -static struct pstr mediamode = PSTR_INITIALIZER1(&mediamode, "mediamode", - setmediamode, "mediamode", false, &command_root.pb_parser); - -static struct pinteger mediainst = PINTEGER_INITIALIZER1(&mediainst, - "mediainst", 0, IFM_INST_MAX, 10, setmediainst, "mediainst", - &command_root.pb_parser); - -static struct pstr unmediaopt = PSTR_INITIALIZER1(&unmediaopt, "-mediaopt", - unsetmediaopt, "unmediaopt", false, &command_root.pb_parser); - -static struct pstr mediaopt = PSTR_INITIALIZER1(&mediaopt, "mediaopt", - setmediaopt, "mediaopt", false, &command_root.pb_parser); - -static struct pstr media = PSTR_INITIALIZER1(&media, "media", setmedia, "media", - false, &command_root.pb_parser); - -static const struct kwinst mediakw[] = { - {.k_word = "instance", .k_key = "anymedia", .k_type = KW_T_BOOL, - .k_bool = true, .k_act = "media", .k_deact = "mediainst", - .k_nextparser = &mediainst.pi_parser} - , {.k_word = "inst", .k_key = "anymedia", .k_type = KW_T_BOOL, - .k_bool = true, .k_act = "media", .k_deact = "mediainst", - .k_nextparser = &mediainst.pi_parser} - , {.k_word = "media", .k_key = "anymedia", .k_type = KW_T_BOOL, - .k_bool = true, .k_deact = "media", .k_altdeact = "anymedia", - .k_nextparser = &media.ps_parser} - , {.k_word = "mediaopt", .k_key = "anymedia", .k_type = KW_T_BOOL, - .k_bool = true, .k_deact = "mediaopt", .k_altdeact = "instance", - .k_nextparser = &mediaopt.ps_parser} - , {.k_word = "-mediaopt", .k_key = "anymedia", .k_type = KW_T_BOOL, - .k_bool = true, .k_deact = "unmediaopt", .k_altdeact = "media", - .k_nextparser = &unmediaopt.ps_parser} - , {.k_word = "mode", .k_key = "anymedia", .k_type = KW_T_BOOL, - .k_bool = true, .k_deact = "mode", - .k_nextparser = &mediamode.ps_parser} -}; - -struct pkw kwmedia = PKW_INITIALIZER(&kwmedia, "media keywords", NULL, NULL, - mediakw, __arraycount(mediakw), NULL); - -__dead static void -media_error(int type, const char *val, const char *opt) -{ - errx(EXIT_FAILURE, "unknown %s media %s: %s", - get_media_type_string(type), opt, val); -} - -void -init_current_media(prop_dictionary_t env, prop_dictionary_t oenv) -{ - const char *ifname; - struct ifmediareq ifmr; - - if ((ifname = getifname(env)) == NULL) - err(EXIT_FAILURE, "getifname"); - - /* - * If we have not yet done so, grab the currently-selected - * media. - */ - - if (prop_dictionary_get(env, "initmedia") == NULL) { - memset(&ifmr, 0, sizeof(ifmr)); - - if (direct_ioctl(env, SIOCGIFMEDIA, &ifmr) == -1) { - /* - * If we get E2BIG, the kernel is telling us - * that there are more, so we can ignore it. - */ - if (errno != E2BIG) - err(EXIT_FAILURE, "SIOCGIFMEDIA"); - } - - if (!prop_dictionary_set_bool(oenv, "initmedia", true)) { - err(EXIT_FAILURE, "%s: prop_dictionary_set_bool", - __func__); - } - media_current = ifmr.ifm_current; - } - - /* Sanity. */ - if (IFM_TYPE(media_current) == 0) - errx(EXIT_FAILURE, "%s: no link type?", ifname); -} - -void -process_media_commands(prop_dictionary_t env) -{ - struct ifreq ifr; - - if (prop_dictionary_get(env, "media") == NULL && - prop_dictionary_get(env, "mediaopt") == NULL && - prop_dictionary_get(env, "unmediaopt") == NULL && - prop_dictionary_get(env, "mediamode") == NULL) { - /* Nothing to do. */ - return; - } - - /* - * Media already set up, and commands sanity-checked. Set/clear - * any options, and we're ready to go. - */ - media_current |= mediaopt_set; - media_current &= ~mediaopt_clear; - - memset(&ifr, 0, sizeof(ifr)); - ifr.ifr_media = media_current; - - if (direct_ioctl(env, SIOCSIFMEDIA, &ifr) == -1) - err(EXIT_FAILURE, "SIOCSIFMEDIA"); -} - -static int -setmedia(prop_dictionary_t env, prop_dictionary_t oenv) -{ - int type, subtype, inst; - prop_data_t data; - char *val; - - init_current_media(env, oenv); - - data = (prop_data_t)prop_dictionary_get(env, "media"); - assert(data != NULL); - - /* Only one media command may be given. */ - /* Must not come after mode commands */ - /* Must not come after mediaopt commands */ - - /* - * No need to check if `instance' has been issued; setmediainst() - * craps out if `media' has not been specified. - */ - - type = IFM_TYPE(media_current); - inst = IFM_INST(media_current); - - val = strndup(prop_data_data_nocopy(data), prop_data_size(data)); - if (val == NULL) - return -1; - - /* Look up the subtype. */ - subtype = get_media_subtype(type, val); - if (subtype == -1) - media_error(type, val, "subtype"); - - /* Build the new current media word. */ - media_current = IFM_MAKEWORD(type, subtype, 0, inst); - - /* Media will be set after other processing is complete. */ - return 0; -} - -static int -setmediaopt(prop_dictionary_t env, prop_dictionary_t oenv) -{ - char *invalid; - prop_data_t data; - char *val; - - init_current_media(env, oenv); - - data = (prop_data_t)prop_dictionary_get(env, "mediaopt"); - assert(data != NULL); - - /* Can only issue `mediaopt' once. */ - /* Can't issue `mediaopt' if `instance' has already been issued. */ - - val = strndup(prop_data_data_nocopy(data), prop_data_size(data)); - if (val == NULL) - return -1; - - mediaopt_set = get_media_options(media_current, val, &invalid); - free(val); - if (mediaopt_set == -1) - media_error(media_current, invalid, "option"); - - /* Media will be set after other processing is complete. */ - return 0; -} - -static int -unsetmediaopt(prop_dictionary_t env, prop_dictionary_t oenv) -{ - char *invalid, *val; - prop_data_t data; - - init_current_media(env, oenv); - - data = (prop_data_t)prop_dictionary_get(env, "unmediaopt"); - if (data == NULL) { - errno = ENOENT; - return -1; - } - - val = strndup(prop_data_data_nocopy(data), prop_data_size(data)); - if (val == NULL) - return -1; - - /* - * No need to check for A_MEDIAINST, since the test for A_MEDIA - * implicitly checks for A_MEDIAINST. - */ - - mediaopt_clear = get_media_options(media_current, val, &invalid); - free(val); - if (mediaopt_clear == -1) - media_error(media_current, invalid, "option"); - - /* Media will be set after other processing is complete. */ - return 0; -} - -static int -setmediainst(prop_dictionary_t env, prop_dictionary_t oenv) -{ - int type, subtype, options; - int64_t inst; - bool rc; - - init_current_media(env, oenv); - - rc = prop_dictionary_get_int64(env, "mediainst", &inst); - assert(rc); - - /* Can only issue `instance' once. */ - /* Must have already specified `media' */ - - type = IFM_TYPE(media_current); - subtype = IFM_SUBTYPE(media_current); - options = IFM_OPTIONS(media_current); - - media_current = IFM_MAKEWORD(type, subtype, options, inst); - - /* Media will be set after other processing is complete. */ - return 0; -} - -static int -setmediamode(prop_dictionary_t env, prop_dictionary_t oenv) -{ - int type, subtype, options, inst, mode; - prop_data_t data; - char *val; - - init_current_media(env, oenv); - - data = (prop_data_t)prop_dictionary_get(env, "mediamode"); - assert(data != NULL); - - type = IFM_TYPE(media_current); - subtype = IFM_SUBTYPE(media_current); - options = IFM_OPTIONS(media_current); - inst = IFM_INST(media_current); - - val = strndup(prop_data_data_nocopy(data), prop_data_size(data)); - if (val == NULL) - return -1; - - mode = get_media_mode(type, val); - if (mode == -1) - media_error(type, val, "mode"); - - free(val); - - media_current = IFM_MAKEWORD(type, subtype, options, inst) | mode; - - /* Media will be set after other processing is complete. */ - return 0; -} - -void -print_media_word(int ifmw, const char *opt_sep) -{ - const char *str; - - printf("%s", get_media_subtype_string(ifmw)); - - /* Find mode. */ - if (IFM_MODE(ifmw) != 0) { - str = get_media_mode_string(ifmw); - if (str != NULL) - printf(" mode %s", str); - } - - /* Find options. */ - for (; (str = get_media_option_string(&ifmw)) != NULL; opt_sep = ",") - printf("%s%s", opt_sep, str); - - if (IFM_INST(ifmw) != 0) - printf(" instance %d", IFM_INST(ifmw)); -} - -void -media_status(prop_dictionary_t env, prop_dictionary_t oenv) -{ - struct ifmediareq ifmr; - int af, i, s; - int *media_list; - const char *ifname; - - if ((ifname = getifname(env)) == NULL) - err(EXIT_FAILURE, "getifname"); - if ((af = getaf(env)) == -1) - af = AF_UNSPEC; - - /* get out early if the family is unsupported by the kernel */ - if ((s = getsock(af)) == -1) - err(EXIT_FAILURE, "%s: getsock", __func__); - - memset(&ifmr, 0, sizeof(ifmr)); - estrlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name)); - - if (prog_ioctl(s, SIOCGIFMEDIA, &ifmr) == -1) { - /* - * Interface doesn't support SIOC{G,S}IFMEDIA. - */ - return; - } - - if (ifmr.ifm_count == 0) { - warnx("%s: no media types?", ifname); - return; - } - - media_list = (int *)malloc(ifmr.ifm_count * sizeof(int)); - if (media_list == NULL) - err(EXIT_FAILURE, "malloc"); - ifmr.ifm_ulist = media_list; - - if (prog_ioctl(s, SIOCGIFMEDIA, &ifmr) == -1) - err(EXIT_FAILURE, "SIOCGIFMEDIA"); - - printf("\tmedia: %s ", get_media_type_string(ifmr.ifm_current)); - print_media_word(ifmr.ifm_current, " "); - if (ifmr.ifm_active != ifmr.ifm_current) { - printf(" ("); - print_media_word(ifmr.ifm_active, " "); - printf(")"); - } - printf("\n"); - - if (ifmr.ifm_status & IFM_STATUS_VALID) { - const struct ifmedia_status_description *ifms; - int bitno, found = 0; - - printf("\tstatus: "); - for (bitno = 0; ifm_status_valid_list[bitno] != 0; bitno++) { - for (ifms = ifm_status_descriptions; - ifms->ifms_valid != 0; ifms++) { - if (ifms->ifms_type != - IFM_TYPE(ifmr.ifm_current) || - ifms->ifms_valid != - ifm_status_valid_list[bitno]) - continue; - printf("%s%s", found ? ", " : "", - IFM_STATUS_DESC(ifms, ifmr.ifm_status)); - found = 1; - - /* - * For each valid indicator bit, there's - * only one entry for each media type, so - * terminate the inner loop now. - */ - break; - } - } - - if (found == 0) - printf("unknown"); - printf("\n"); - } - - if (get_flag('m')) { - int type, printed_type; - - for (type = IFM_NMIN; type <= IFM_NMAX; type += IFM_NMIN) { - for (i = 0, printed_type = 0; i < ifmr.ifm_count; i++) { - if (IFM_TYPE(media_list[i]) != type) - continue; - if (printed_type == 0) { - printf("\tsupported %s media:\n", - get_media_type_string(type)); - printed_type = 1; - } - printf("\t\tmedia "); - print_media_word(media_list[i], " mediaopt "); - printf("\n"); - } - } - } - - free(media_list); -} - -static void -media_usage(prop_dictionary_t env) -{ - fprintf(stderr, - "\t[ media type ] [ mediaopt opts ] [ -mediaopt opts ] " - "[ instance minst ]\n"); -} - -static void -media_constructor(void) -{ - if (register_flag('m') != 0) - err(EXIT_FAILURE, __func__); - usage_func_init(&usage, media_usage); - register_usage(&usage); -} diff --git a/sbin/ifconfig/prog_ops.h b/sbin/ifconfig/prog_ops.h deleted file mode 100644 index 9d707ce37..000000000 --- a/sbin/ifconfig/prog_ops.h +++ /dev/null @@ -1,61 +0,0 @@ -/* $NetBSD: prog_ops.h,v 1.3 2010/12/13 21:48:01 pooka Exp $ */ - -/* - * Copyright (c) 2010 The NetBSD Foundation, Inc. - * 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 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. - */ - -#ifndef _PROG_OPS_H_ -#define _PROG_OPS_H_ - -#include - -/* ifconfig is compiled outside of src/sbin/ifconfig too */ -#ifndef CRUNCHOPS -struct prog_ops { - int (*op_init)(void); - - int (*op_socket)(int, int, int); - - int (*op_ioctl)(int, unsigned long, ...); - ssize_t (*op_read)(int, void *, size_t); - - int (*op_close)(int); -}; -extern const struct prog_ops prog_ops; - -#define prog_init prog_ops.op_init -#define prog_socket prog_ops.op_socket -#define prog_ioctl prog_ops.op_ioctl -#define prog_read prog_ops.op_read -#define prog_close prog_ops.op_close -#else -#define prog_init ((int (*)(void))NULL) -#define prog_socket socket -#define prog_ioctl ioctl -#define prog_read read -#define prog_close close -#endif - -#endif /* _PROG_OPS_H_ */ diff --git a/sbin/ifconfig/util.c b/sbin/ifconfig/util.c deleted file mode 100644 index 5bba576dc..000000000 --- a/sbin/ifconfig/util.c +++ /dev/null @@ -1,346 +0,0 @@ -/* $NetBSD: util.c,v 1.17 2013/10/19 00:35:30 christos Exp $ */ - -/*- - * Copyright (c) 2008 David Young. 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 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 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 -#ifndef lint -__RCSID("$NetBSD: util.c,v 1.17 2013/10/19 00:35:30 christos Exp $"); -#endif /* not lint */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include /* XXX */ - -#include "env.h" -#include "extern.h" -#include "util.h" -#include "prog_ops.h" - -int -getsock(int naf) -{ - static int oaf = -1, s; - - if (oaf == naf || (oaf != -1 && naf == AF_UNSPEC)) - return s; - - if (oaf != -1) - prog_close(s); - - if (naf == AF_UNSPEC) - naf = AF_INET; - - s = prog_socket(naf, SOCK_DGRAM, 0); - if (s == -1) - oaf = -1; - else - oaf = naf; - return s; -} - -const char * -get_string(const char *val, const char *sep, u_int8_t *buf, int *lenp, - bool hexok) -{ - int len; - bool hexstr; - u_int8_t *p; - - len = *lenp; - p = buf; - hexstr = hexok && val[0] == '0' && tolower((u_char)val[1]) == 'x'; - if (hexstr) - val += 2; - for (;;) { - if (*val == '\0') - break; - if (sep != NULL && strchr(sep, *val) != NULL) { - val++; - break; - } - if (hexstr) { - if (!isxdigit((u_char)val[0]) || - !isxdigit((u_char)val[1])) { - warnx("bad hexadecimal digits"); - return NULL; - } - } - if (p >= buf + len) { - if (hexstr) - warnx("hexadecimal digits too long"); - else - warnx("strings too long"); - return NULL; - } - if (hexstr) { -#define tohex(x) (isdigit(x) ? (x) - '0' : tolower(x) - 'a' + 10) - *p++ = (tohex((u_char)val[0]) << 4) | - tohex((u_char)val[1]); -#undef tohex - val += 2; - } else - *p++ = *val++; - } - len = p - buf; - if (len < *lenp) - memset(p, 0, *lenp - len); - *lenp = len; - return val; -} - -void -print_string(const u_int8_t *buf, int len) -{ - int i; - bool hasspc; - - i = 0; - hasspc = false; - if (len < 2 || buf[0] != '0' || tolower(buf[1]) != 'x') { - for (; i < len; i++) { - if (!isprint(buf[i])) - break; - if (isspace(buf[i])) - hasspc = true; - } - } - if (i == len) { - if (hasspc || len == 0) - printf("\"%.*s\"", len, buf); - else - printf("%.*s", len, buf); - } else { - printf("0x"); - for (i = 0; i < len; i++) - printf("%02x", buf[i]); - } -} - -struct paddr_prefix * -prefixlen_to_mask(int af, int plen) -{ - union { - struct sockaddr sa; - struct sockaddr_in sin; - struct sockaddr_in6 sin6; - } u; - struct paddr_prefix *pfx; - size_t addrlen; - uint8_t *addr; - int nbit; - - memset(&u, 0, sizeof(u)); - - switch (af) { - case AF_INET: - addrlen = sizeof(u.sin.sin_addr); - addr = (uint8_t *)&u.sin.sin_addr; - u.sa.sa_len = sizeof(u.sin); - break; - case AF_INET6: - addrlen = sizeof(u.sin6.sin6_addr); - addr = (uint8_t *)&u.sin6.sin6_addr; - u.sa.sa_len = sizeof(u.sin6); - break; - default: - errno = EINVAL; - return NULL; - } - u.sa.sa_family = af; - - if (plen < 0 || (size_t)plen > addrlen * NBBY) { - errno = EINVAL; - return NULL; - } - - if (plen == 0) - plen = addrlen * NBBY; - - memset(addr, 0xff, (plen + NBBY - 1) / NBBY); - - nbit = plen % NBBY; - if (nbit != 0) - addr[plen / NBBY] &= ~((uint8_t)0xff >> nbit); - pfx = malloc(offsetof(struct paddr_prefix, pfx_addr) + u.sa.sa_len); - if (pfx == NULL) - return NULL; - pfx->pfx_len = plen; - memcpy(&pfx->pfx_addr, &u.sa, u.sa.sa_len); - - return pfx; -} - -int -direct_ioctl(prop_dictionary_t env, unsigned long cmd, void *data) -{ - const char *ifname; - int s; - - if ((s = getsock(AF_UNSPEC)) == -1) - err(EXIT_FAILURE, "getsock"); - - if ((ifname = getifname(env)) == NULL) - err(EXIT_FAILURE, "getifname"); - - estrlcpy(data, ifname, IFNAMSIZ); - - return prog_ioctl(s, cmd, data); -} - -int -indirect_ioctl(prop_dictionary_t env, unsigned long cmd, void *data) -{ - struct ifreq ifr; - - memset(&ifr, 0, sizeof(ifr)); - - ifr.ifr_data = data; - - return direct_ioctl(env, cmd, &ifr); -} - -void -print_link_addresses(prop_dictionary_t env, bool print_active_only) -{ - char hbuf[NI_MAXHOST]; - const char *ifname; - int s; - struct ifaddrs *ifa, *ifap; - const struct sockaddr_dl *sdl; - struct if_laddrreq iflr; - - if ((ifname = getifname(env)) == NULL) - err(EXIT_FAILURE, "%s: getifname", __func__); - - if ((s = getsock(AF_LINK)) == -1) - err(EXIT_FAILURE, "%s: getsock", __func__); - - if (getifaddrs(&ifap) == -1) - err(EXIT_FAILURE, "%s: getifaddrs", __func__); - - memset(&iflr, 0, sizeof(iflr)); - - strlcpy(iflr.iflr_name, ifname, sizeof(iflr.iflr_name)); - - for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { - if (strcmp(ifname, ifa->ifa_name) != 0) - continue; - if (ifa->ifa_addr->sa_family != AF_LINK) - continue; - - sdl = satocsdl(ifa->ifa_addr); - - memcpy(&iflr.addr, ifa->ifa_addr, MIN(ifa->ifa_addr->sa_len, - sizeof(iflr.addr))); - iflr.flags = IFLR_PREFIX; - iflr.prefixlen = sdl->sdl_alen * NBBY; - - if (prog_ioctl(s, SIOCGLIFADDR, &iflr) == -1) - err(EXIT_FAILURE, "%s: ioctl", __func__); - - if (((iflr.flags & IFLR_ACTIVE) != 0) != print_active_only) - continue; - - if (getnameinfo(ifa->ifa_addr, ifa->ifa_addr->sa_len, - hbuf, sizeof(hbuf), NULL, 0, - Nflag ? 0 : NI_NUMERICHOST) == 0 && - hbuf[0] != '\0') { - printf("\t%s %s\n", - print_active_only ? "address:" : "link", hbuf); - } - } - freeifaddrs(ifap); -} - -int16_t -ifa_get_preference(const char *ifname, const struct sockaddr *sa) -{ - struct if_addrprefreq ifap; - int s; - - if ((s = getsock(sa->sa_family)) == -1) { - if (errno == EPROTONOSUPPORT) - return 0; - err(EXIT_FAILURE, "socket"); - } - memset(&ifap, 0, sizeof(ifap)); - estrlcpy(ifap.ifap_name, ifname, sizeof(ifap.ifap_name)); - memcpy(&ifap.ifap_addr, sa, MIN(sizeof(ifap.ifap_addr), sa->sa_len)); - if (prog_ioctl(s, SIOCGIFADDRPREF, &ifap) == -1) { - if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) - return 0; - warn("SIOCGIFADDRPREF"); - } - return ifap.ifap_preference; -} - -void -ifa_print_preference(const char *ifname, const struct sockaddr *sa) -{ - int16_t preference; - - if (lflag) - return; - - preference = ifa_get_preference(ifname, sa); - printf(" preference %" PRId16, preference); -} - -bool -ifa_any_preferences(const char *ifname, struct ifaddrs *ifap, int family) -{ - struct ifaddrs *ifa; - - /* Print address preference numbers if any address has a non-zero - * preference assigned. - */ - for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { - if (strcmp(ifname, ifa->ifa_name) != 0) - continue; - if (ifa->ifa_addr->sa_family != family) - continue; - if (ifa_get_preference(ifa->ifa_name, ifa->ifa_addr) != 0) - return true; - } - return false; -} diff --git a/sbin/ifconfig/vlan.c b/sbin/ifconfig/vlan.c deleted file mode 100644 index a5ddbcf13..000000000 --- a/sbin/ifconfig/vlan.c +++ /dev/null @@ -1,190 +0,0 @@ -/* $NetBSD: vlan.c,v 1.14 2014/09/15 06:46:04 ozaki-r Exp $ */ - -/* - * Copyright (c) 1983, 1993 - * The Regents of the University of California. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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 -#ifndef lint -__RCSID("$NetBSD: vlan.c,v 1.14 2014/09/15 06:46:04 ozaki-r Exp $"); -#endif /* not lint */ - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "env.h" -#include "extern.h" -#include "util.h" - -static status_func_t status; -static usage_func_t usage; -static cmdloop_branch_t branch; - -static void vlan_constructor(void) __attribute__((constructor)); -static void vlan_status(prop_dictionary_t, prop_dictionary_t); - -static int setvlan(prop_dictionary_t, prop_dictionary_t); -static int setvlanif(prop_dictionary_t, prop_dictionary_t); - -struct pinteger vlantag = PINTEGER_INITIALIZER1(&vlantag, "VLAN tag", - 0, USHRT_MAX, 10, setvlan, "vlantag", &command_root.pb_parser); - -struct piface vlanif = PIFACE_INITIALIZER(&vlanif, "vlanif", setvlanif, - "vlanif", &command_root.pb_parser); - -static const struct kwinst vlankw[] = { - {.k_word = "vlan", .k_nextparser = &vlantag.pi_parser} - , {.k_word = "vlanif", .k_act = "vlantag", - .k_nextparser = &vlanif.pif_parser} - , {.k_word = "-vlanif", .k_key = "vlanif", .k_type = KW_T_STR, - .k_str = "", .k_exec = setvlanif} -}; - -struct pkw vlan = PKW_INITIALIZER(&vlan, "vlan", NULL, NULL, - vlankw, __arraycount(vlankw), NULL); - -static int -checkifname(prop_dictionary_t env) -{ - const char *ifname; - - if ((ifname = getifname(env)) == NULL) - return 1; - - return strncmp(ifname, "vlan", 4) != 0 || - !isdigit((unsigned char)ifname[4]); -} - -static int -getvlan(prop_dictionary_t env, struct vlanreq *vlr, bool quiet) -{ - memset(vlr, 0, sizeof(*vlr)); - - if (checkifname(env)) { - if (quiet) - return -1; - errx(EXIT_FAILURE, "valid only with vlan(4) interfaces"); - } - - if (indirect_ioctl(env, SIOCGETVLAN, vlr) == -1) - return -1; - - return 0; -} - -int -setvlan(prop_dictionary_t env, prop_dictionary_t oenv) -{ - struct vlanreq vlr; - int64_t tag; - - if (getvlan(env, &vlr, false) == -1) - err(EXIT_FAILURE, "%s: getvlan", __func__); - - if (!prop_dictionary_get_int64(env, "vlantag", &tag)) { - errno = ENOENT; - return -1; - } - - vlr.vlr_tag = tag; - - if (indirect_ioctl(env, SIOCSETVLAN, &vlr) == -1) - err(EXIT_FAILURE, "SIOCSETVLAN"); - return 0; -} - -int -setvlanif(prop_dictionary_t env, prop_dictionary_t oenv) -{ - struct vlanreq vlr; - const char *parent; - int64_t tag; - - if (getvlan(env, &vlr, false) == -1) - err(EXIT_FAILURE, "%s: getsock", __func__); - - if (!prop_dictionary_get_cstring_nocopy(env, "vlanif", &parent)) { - errno = ENOENT; - return -1; - } - strlcpy(vlr.vlr_parent, parent, sizeof(vlr.vlr_parent)); - if (strcmp(parent, "") == 0) - ; - else if (!prop_dictionary_get_int64(env, "vlantag", &tag)) { - errno = ENOENT; - return -1; - } else - vlr.vlr_tag = (unsigned short)tag; - - if (indirect_ioctl(env, SIOCSETVLAN, &vlr) == -1) - err(EXIT_FAILURE, "SIOCSETVLAN"); - return 0; -} - -static void -vlan_status(prop_dictionary_t env, prop_dictionary_t oenv) -{ - struct vlanreq vlr; - - if (getvlan(env, &vlr, true) == -1) - return; - - if (vlr.vlr_tag || vlr.vlr_parent[0] != '\0') - printf("\tvlan: %d parent: %s\n", - vlr.vlr_tag, vlr.vlr_parent[0] == '\0' ? - "" : vlr.vlr_parent); -} - -static void -vlan_usage(prop_dictionary_t env) -{ - fprintf(stderr, "\t[ vlan n vlanif i ] [ -vlanif i ]\n"); -} - -static void -vlan_constructor(void) -{ - cmdloop_branch_init(&branch, &vlan.pk_parser); - register_cmdloop_branch(&branch); - status_func_init(&status, vlan_status); - usage_func_init(&usage, vlan_usage); - register_status(&status); - register_usage(&usage); -} diff --git a/sbin/newfs_msdos/Makefile b/sbin/newfs_msdos/Makefile deleted file mode 100644 index 1a6dfbff7..000000000 --- a/sbin/newfs_msdos/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# $NetBSD: Makefile,v 1.6 2013/01/21 20:28:38 christos Exp $ -# From: $FreeBSD: src/sbin/newfs_msdos/Makefile,v 1.5 2001/03/26 14:33:18 ru Exp $ - -.include - -PROG= newfs_msdos -MAN= newfs_msdos.8 -SRCS= newfs_msdos.c partutil.c mkfs_msdos.c - -LDADD+= -lutil -DPADD+= ${LIBUTIL} - -LDADD+=-lprop -DPADD+=${LIBPROP} - -FSCK=${NETBSDSRCDIR}/sbin/fsck -CPPFLAGS+=-I${.CURDIR} -I${FSCK} -.PATH: ${FSCK} - - -.if ${MACHINE} == "pc98" -CFLAGS+= -DPC98 -.endif - -.include diff --git a/sbin/newfs_msdos/mkfs_msdos.c b/sbin/newfs_msdos/mkfs_msdos.c deleted file mode 100644 index 05ae2c102..000000000 --- a/sbin/newfs_msdos/mkfs_msdos.c +++ /dev/null @@ -1,997 +0,0 @@ -/* $NetBSD: mkfs_msdos.c,v 1.13 2017/04/14 15:39:29 christos Exp $ */ - -/* - * Copyright (c) 1998 Robert Nordier - * 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(S) ``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(S) 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. - */ - -#if HAVE_NBTOOL_CONFIG_H -#include "nbtool_config.h" -#endif - -#include -#ifndef lint -#if 0 -static const char rcsid[] = - "$FreeBSD: src/sbin/newfs_msdos/newfs_msdos.c,v 1.15 2000/10/10 01:49:37 wollman Exp $"; -#else -__RCSID("$NetBSD: mkfs_msdos.c,v 1.13 2017/04/14 15:39:29 christos Exp $"); -#endif -#endif /* not lint */ - -#include -#include -#include -#include -#ifndef MAKEFS -#include -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#ifndef MAKEFS -#include "partutil.h" -#endif -#include "mkfs_msdos.h" - -#define MAXU16 0xffff /* maximum unsigned 16-bit quantity */ -#define BPN 4 /* bits per nibble */ -#define NPB 2 /* nibbles per byte */ - -#define DOSMAGIC 0xaa55 /* DOS magic number */ -#define MINBPS 512 /* minimum bytes per sector */ -#define MAXSPC 128 /* maximum sectors per cluster */ -#define MAXNFT 16 /* maximum number of FATs */ -#define DEFBLK 4096 /* default block size */ -#define DEFBLK16 2048 /* default block size FAT16 */ -#define DEFRDE 512 /* default root directory entries */ -#define RESFTE 2 /* reserved FAT entries */ -#define MINCLS12 1 /* minimum FAT12 clusters */ -#define MINCLS16 0xff5 /* minimum FAT16 clusters */ -#define MINCLS32 0xfff5 /* minimum FAT32 clusters */ -#define MAXCLS12 0xff4 /* maximum FAT12 clusters */ -#define MAXCLS16 0xfff4 /* maximum FAT16 clusters */ -#define MAXCLS32 0xffffff4 /* maximum FAT32 clusters */ - -#define mincls(fat_type) ((fat_type) == 12 ? MINCLS12 : \ - (fat_type) == 16 ? MINCLS16 : \ - MINCLS32) - -#define maxcls(fat_type) ((fat_type) == 12 ? MAXCLS12 : \ - (fat_type) == 16 ? MAXCLS16 : \ - MAXCLS32) - -#define mk1(p, x) \ - (p) = (u_int8_t)(x) - -#define mk2(p, x) \ - (p)[0] = (u_int8_t)(x), \ - (p)[1] = (u_int8_t)((x) >> 010) - -#define mk4(p, x) \ - (p)[0] = (u_int8_t)(x), \ - (p)[1] = (u_int8_t)((x) >> 010), \ - (p)[2] = (u_int8_t)((x) >> 020), \ - (p)[3] = (u_int8_t)((x) >> 030) - -struct bs { - u_int8_t jmp[3]; /* bootstrap entry point */ - u_int8_t oem[8]; /* OEM name and version */ -}; - -struct bsbpb { - u_int8_t bps[2]; /* bytes per sector */ - u_int8_t spc; /* sectors per cluster */ - u_int8_t res[2]; /* reserved sectors */ - u_int8_t nft; /* number of FATs */ - u_int8_t rde[2]; /* root directory entries */ - u_int8_t sec[2]; /* total sectors */ - u_int8_t mid; /* media descriptor */ - u_int8_t spf[2]; /* sectors per FAT */ - u_int8_t spt[2]; /* sectors per track */ - u_int8_t hds[2]; /* drive heads */ - u_int8_t hid[4]; /* hidden sectors */ - u_int8_t bsec[4]; /* big total sectors */ -}; - -struct bsxbpb { - u_int8_t bspf[4]; /* big sectors per FAT */ - u_int8_t xflg[2]; /* FAT control flags */ - u_int8_t vers[2]; /* file system version */ - u_int8_t rdcl[4]; /* root directory start cluster */ - u_int8_t infs[2]; /* file system info sector */ - u_int8_t bkbs[2]; /* backup boot sector */ - u_int8_t rsvd[12]; /* reserved */ -}; - -struct bsx { - u_int8_t drv; /* drive number */ - u_int8_t rsvd; /* reserved */ - u_int8_t sig; /* extended boot signature */ - u_int8_t volid[4]; /* volume ID number */ - u_int8_t label[11]; /* volume label */ - u_int8_t type[8]; /* file system type */ -}; - -struct de { - u_int8_t namext[11]; /* name and extension */ - u_int8_t attr; /* attributes */ - u_int8_t rsvd[10]; /* reserved */ - u_int8_t time[2]; /* creation time */ - u_int8_t date[2]; /* creation date */ - u_int8_t clus[2]; /* starting cluster */ - u_int8_t size[4]; /* size */ -}; - -struct bpb { - u_int bps; /* bytes per sector */ - u_int spc; /* sectors per cluster */ - u_int res; /* reserved sectors */ - u_int nft; /* number of FATs */ - u_int rde; /* root directory entries */ - u_int sec; /* total sectors */ - u_int mid; /* media descriptor */ - u_int spf; /* sectors per FAT */ - u_int spt; /* sectors per track */ - u_int hds; /* drive heads */ - u_int hid; /* hidden sectors */ - u_int bsec; /* big total sectors */ - u_int bspf; /* big sectors per FAT */ - u_int rdcl; /* root directory start cluster */ - u_int infs; /* file system info sector */ - u_int bkbs; /* backup boot sector */ -}; - -#define INIT(a, b, c, d, e, f, g, h, i, j) \ - { .bps = a, .spc = b, .res = c, .nft = d, .rde = e, \ - .sec = f, .mid = g, .spf = h, .spt = i, .hds = j, } -static struct { - const char *name; - struct bpb bpb; -} stdfmt[] = { - {"160", INIT(512, 1, 1, 2, 64, 320, 0xfe, 1, 8, 1)}, - {"180", INIT(512, 1, 1, 2, 64, 360, 0xfc, 2, 9, 1)}, - {"320", INIT(512, 2, 1, 2, 112, 640, 0xff, 1, 8, 2)}, - {"360", INIT(512, 2, 1, 2, 112, 720, 0xfd, 2, 9, 2)}, - {"640", INIT(512, 2, 1, 2, 112, 1280, 0xfb, 2, 8, 2)}, - {"720", INIT(512, 2, 1, 2, 112, 1440, 0xf9, 3, 9, 2)}, - {"1200", INIT(512, 1, 1, 2, 224, 2400, 0xf9, 7, 15, 2)}, - {"1232", INIT(1024,1, 1, 2, 192, 1232, 0xfe, 2, 8, 2)}, - {"1440", INIT(512, 1, 1, 2, 224, 2880, 0xf0, 9, 18, 2)}, - {"2880", INIT(512, 2, 1, 2, 240, 5760, 0xf0, 9, 36, 2)} -}; - -static u_int8_t bootcode[] = { - 0xfa, /* cli */ - 0x31, 0xc0, /* xor ax,ax */ - 0x8e, 0xd0, /* mov ss,ax */ - 0xbc, 0x00, 0x7c, /* mov sp,7c00h */ - 0xfb, /* sti */ - 0x8e, 0xd8, /* mov ds,ax */ - 0xe8, 0x00, 0x00, /* call $ + 3 */ - 0x5e, /* pop si */ - 0x83, 0xc6, 0x19, /* add si,+19h */ - 0xbb, 0x07, 0x00, /* mov bx,0007h */ - 0xfc, /* cld */ - 0xac, /* lodsb */ - 0x84, 0xc0, /* test al,al */ - 0x74, 0x06, /* jz $ + 8 */ - 0xb4, 0x0e, /* mov ah,0eh */ - 0xcd, 0x10, /* int 10h */ - 0xeb, 0xf5, /* jmp $ - 9 */ - 0x30, 0xe4, /* xor ah,ah */ - 0xcd, 0x16, /* int 16h */ - 0xcd, 0x19, /* int 19h */ - 0x0d, 0x0a, - 'N', 'o', 'n', '-', 's', 'y', 's', 't', - 'e', 'm', ' ', 'd', 'i', 's', 'k', - 0x0d, 0x0a, - 'P', 'r', 'e', 's', 's', ' ', 'a', 'n', - 'y', ' ', 'k', 'e', 'y', ' ', 't', 'o', - ' ', 'r', 'e', 'b', 'o', 'o', 't', - 0x0d, 0x0a, - 0 -}; - -static int got_siginfo = 0; /* received a SIGINFO */ - -#ifndef MAKEFS -static int check_mounted(const char *, mode_t); -#endif -static int getstdfmt(const char *, struct bpb *); -static int getbpbinfo(int, const char *, const char *, int, struct bpb *, off_t); -static void print_bpb(struct bpb *); -static int ckgeom(const char *, u_int, const char *); -static int oklabel(const char *); -static void mklabel(u_int8_t *, const char *); -static void setstr(u_int8_t *, const char *, size_t); -static void infohandler(int sig); - -int -mkfs_msdos(const char *fname, const char *dtype, const struct msdos_options *op) -{ - char buf[MAXPATHLEN]; - struct stat sb; - struct timeval tv; - struct bpb bpb; - struct tm *tm; - struct bs *bs; - struct bsbpb *bsbpb; - struct bsxbpb *bsxbpb; - struct bsx *bsx; - struct de *de; - u_int8_t *img; - const char *bname; - ssize_t n; - time_t now; - u_int bss, rds, cls, dir, lsn, x, x1, x2; - int ch, fd, fd1; - struct msdos_options o = *op; - int oflags = O_RDWR | O_CREAT; - - if (o.block_size && o.sectors_per_cluster) { - warnx("Cannot specify both block size and sectors per cluster"); - return -1; - } - if (o.OEM_string && strlen(o.OEM_string) > 8) { - warnx("%s: bad OEM string", o.OEM_string); - return -1; - } - if (o.create_size) { - if (o.no_create) { - warnx("create (-C) is incompatible with -N"); - return -1; - } - if (o.offset == 0) - oflags |= O_TRUNC; - fd = open(fname, oflags, 0644); - if (fd == -1) { - warnx("failed to create %s", fname); - return -1; - } - (void)lseek(fd, o.create_size - 1, SEEK_SET); - if (write(fd, "\0", 1) != 1) { - warn("failed to set file size"); - return -1; - } - (void)lseek(fd, 0, SEEK_SET); - } else if ((fd = open(fname, o.no_create ? O_RDONLY : O_RDWR)) == -1 || - fstat(fd, &sb)) { - warn("%s", fname); - return -1; - } -#ifndef MAKEFS - if (!o.no_create) - if (check_mounted(fname, sb.st_mode) == -1) - return -1; -#endif - if (!S_ISCHR(sb.st_mode) && !o.create_size) { - warnx("warning, %s is not a character device", fname); - return -1; - } - if (o.offset && o.offset != lseek(fd, o.offset, SEEK_SET)) { - warnx("cannot seek to %jd", (intmax_t)o.offset); - return -1; - } - memset(&bpb, 0, sizeof(bpb)); - if (o.floppy) { - if (getstdfmt(o.floppy, &bpb) == -1) - return -1; - bpb.bsec = bpb.sec; - bpb.sec = 0; - bpb.bspf = bpb.spf; - bpb.spf = 0; - } - if (o.drive_heads) - bpb.hds = o.drive_heads; - if (o.sectors_per_track) - bpb.spt = o.sectors_per_track; - if (o.bytes_per_sector) - bpb.bps = o.bytes_per_sector; - if (o.size) - bpb.bsec = o.size; - if (o.hidden_sectors_set) - bpb.hid = o.hidden_sectors; - if (!(o.floppy || (o.drive_heads && o.sectors_per_track && - o.bytes_per_sector && o.size && o.hidden_sectors_set))) { - if (getbpbinfo(fd, fname, dtype, o.hidden_sectors_set, &bpb, - o.create_size) == -1) - return -1; - bpb.bsec -= (o.offset / bpb.bps); - if (bpb.spc == 0) { /* set defaults */ - /* minimum cluster size */ - switch (o.fat_type) { - case 12: - bpb.spc = 1; /* use 512 bytes */ - x = 2; /* up to 2MB */ - break; - case 16: - bpb.spc = 1; /* use 512 bytes */ - x = 32; /* up to 32MB */ - break; - default: - bpb.spc = 8; /* use 4k */ - x = 8192; /* up to 8GB */ - break; - } - x1 = howmany(bpb.bsec, (1048576 / 512)); /* -> MB */ - while (bpb.spc < 128 && x < x1) { - x *= 2; - bpb.spc *= 2; - } - } - } - - if (o.volume_label && !oklabel(o.volume_label)) { - warnx("%s: bad volume label", o.volume_label); - return -1; - } - - switch (o.fat_type) { - case 0: - if (o.floppy) - o.fat_type = 12; - else if (!o.directory_entries && (o.info_sector || o.backup_sector)) - o.fat_type = 32; - break; - case 12: - case 16: - if (o.info_sector) { - warnx("Cannot specify info sector with FAT%u", o.fat_type); - return -1; - } - if (o.backup_sector) { - warnx("Cannot specify backup sector with FAT%u", o.fat_type); - return -1; - } - break; - case 32: - if (o.directory_entries) { - warnx("Cannot specify directory entries with FAT32"); - return -1; - } - break; - default: - warnx("%d: bad FAT type", o.fat_type); - return -1; - } - if (!powerof2(bpb.bps)) { - warnx("bytes/sector (%u) is not a power of 2", bpb.bps); - return -1; - } - if (bpb.bps < MINBPS) { - warnx("bytes/sector (%u) is too small; minimum is %u", - bpb.bps, MINBPS); - return -1; - } - - if (o.floppy && o.fat_type == 32) - bpb.rde = 0; - if (o.block_size) { - if (!powerof2(o.block_size)) { - warnx("block size (%u) is not a power of 2", o.block_size); - return -1; - } - if (o.block_size < bpb.bps) { - warnx("block size (%u) is too small; minimum is %u", - o.block_size, bpb.bps); - return -1; - } - if (o.block_size > bpb.bps * MAXSPC) { - warnx("block size (%u) is too large; maximum is %u", - o.block_size, bpb.bps * MAXSPC); - return -1; - } - bpb.spc = o.block_size / bpb.bps; - } - if (o.sectors_per_cluster) { - if (!powerof2(o.sectors_per_cluster)) { - warnx("sectors/cluster (%u) is not a power of 2", - o.sectors_per_cluster); - return -1; - } - bpb.spc = o.sectors_per_cluster; - } - if (o.reserved_sectors) - bpb.res = o.reserved_sectors; - if (o.num_FAT) { - if (o.num_FAT > MAXNFT) { - warnx("number of FATs (%u) is too large; maximum is %u", - o.num_FAT, MAXNFT); - return -1; - } - bpb.nft = o.num_FAT; - } - if (o.directory_entries) - bpb.rde = o.directory_entries; - if (o.media_descriptor_set) { - if (o.media_descriptor < 0xf0) { - warnx("illegal media descriptor (%#x)", o.media_descriptor); - return -1; - } - bpb.mid = o.media_descriptor; - } - if (o.sectors_per_fat) - bpb.bspf = o.sectors_per_fat; - if (o.info_sector) - bpb.infs = o.info_sector; - if (o.backup_sector) - bpb.bkbs = o.backup_sector; - bss = 1; - bname = NULL; - fd1 = -1; - if (o.bootstrap) { - bname = o.bootstrap; - if (!strchr(bname, '/')) { - snprintf(buf, sizeof(buf), "/boot/%s", bname); - if (!(bname = strdup(buf))) { - warn(NULL); - return -1; - } - } - if ((fd1 = open(bname, O_RDONLY)) == -1 || fstat(fd1, &sb)) { - warn("%s", bname); - return -1; - } - if (!S_ISREG(sb.st_mode) || sb.st_size % bpb.bps || - sb.st_size < bpb.bps || sb.st_size > bpb.bps * MAXU16) { - warnx("%s: inappropriate file type or format", bname); - return -1; - } - bss = sb.st_size / bpb.bps; - } - if (!bpb.nft) - bpb.nft = 2; - if (!o.fat_type) { - if (bpb.bsec < (bpb.res ? bpb.res : bss) + - howmany((RESFTE + (bpb.spc ? MINCLS16 : MAXCLS12 + 1)) * - ((bpb.spc ? 16 : 12) / BPN), bpb.bps * NPB) * - bpb.nft + - howmany(bpb.rde ? bpb.rde : DEFRDE, - bpb.bps / sizeof(struct de)) + - (bpb.spc ? MINCLS16 : MAXCLS12 + 1) * - (bpb.spc ? bpb.spc : howmany(DEFBLK, bpb.bps))) - o.fat_type = 12; - else if (bpb.rde || bpb.bsec < - (bpb.res ? bpb.res : bss) + - howmany((RESFTE + MAXCLS16) * 2, bpb.bps) * bpb.nft + - howmany(DEFRDE, bpb.bps / sizeof(struct de)) + - (MAXCLS16 + 1) * - (bpb.spc ? bpb.spc : howmany(8192, bpb.bps))) - o.fat_type = 16; - else - o.fat_type = 32; - } - x = bss; - if (o.fat_type == 32) { - if (!bpb.infs) { - if (x == MAXU16 || x == bpb.bkbs) { - warnx("no room for info sector"); - return -1; - } - bpb.infs = x; - } - if (bpb.infs != MAXU16 && x <= bpb.infs) - x = bpb.infs + 1; - if (!bpb.bkbs) { - if (x == MAXU16) { - warnx("no room for backup sector"); - return -1; - } - bpb.bkbs = x; - } else if (bpb.bkbs != MAXU16 && bpb.bkbs == bpb.infs) { - warnx("backup sector would overwrite info sector"); - return -1; - } - if (bpb.bkbs != MAXU16 && x <= bpb.bkbs) - x = bpb.bkbs + 1; - } - if (!bpb.res) - bpb.res = o.fat_type == 32 ? MAX(x, MAX(16384 / bpb.bps, 4)) : x; - else if (bpb.res < x) { - warnx("too few reserved sectors (need %d have %d)", x, bpb.res); - return -1; - } - if (o.fat_type != 32 && !bpb.rde) - bpb.rde = DEFRDE; - rds = howmany(bpb.rde, bpb.bps / sizeof(struct de)); - if (!bpb.spc) - for (bpb.spc = howmany(o.fat_type == 16 ? DEFBLK16 : DEFBLK, bpb.bps); - bpb.spc < MAXSPC && - bpb.res + - howmany((RESFTE + maxcls(o.fat_type)) * (o.fat_type / BPN), - bpb.bps * NPB) * bpb.nft + - rds + - (u_int64_t)(maxcls(o.fat_type) + 1) * bpb.spc <= bpb.bsec; - bpb.spc <<= 1); - if (o.fat_type != 32 && bpb.bspf > MAXU16) { - warnx("too many sectors/FAT for FAT12/16"); - return -1; - } - x1 = bpb.res + rds; - x = bpb.bspf ? bpb.bspf : 1; - if (x1 + (u_int64_t)x * bpb.nft > bpb.bsec) { - warnx("meta data exceeds file system size"); - return -1; - } - x1 += x * bpb.nft; - x = (u_int64_t)(bpb.bsec - x1) * bpb.bps * NPB / - (bpb.spc * bpb.bps * NPB + o.fat_type / BPN * bpb.nft); - x2 = howmany((RESFTE + MIN(x, maxcls(o.fat_type))) * (o.fat_type / BPN), - bpb.bps * NPB); - if (!bpb.bspf) { - bpb.bspf = x2; - x1 += (bpb.bspf - 1) * bpb.nft; - } - cls = (bpb.bsec - x1) / bpb.spc; - x = (u_int64_t)bpb.bspf * bpb.bps * NPB / (o.fat_type / BPN) - RESFTE; - if (cls > x) - cls = x; - if (bpb.bspf < x2) { - warnx("warning: sectors/FAT limits file system to %u clusters", - cls); - return -1; - } - if (cls < mincls(o.fat_type)) { - warnx("%u clusters too few clusters for FAT%u, need %u", cls, - o.fat_type, mincls(o.fat_type)); - return -1; - } - if (cls > maxcls(o.fat_type)) { - cls = maxcls(o.fat_type); - bpb.bsec = x1 + (cls + 1) * bpb.spc - 1; - warnx("warning: FAT type limits file system to %u sectors", - bpb.bsec); - return -1; - } - printf("%s: %u sector%s in %u FAT%u cluster%s " - "(%u bytes/cluster)\n", fname, cls * bpb.spc, - cls * bpb.spc == 1 ? "" : "s", cls, o.fat_type, - cls == 1 ? "" : "s", bpb.bps * bpb.spc); - if (!bpb.mid) - bpb.mid = !bpb.hid ? 0xf0 : 0xf8; - if (o.fat_type == 32) - bpb.rdcl = RESFTE; - if (bpb.hid + bpb.bsec <= MAXU16) { - bpb.sec = bpb.bsec; - bpb.bsec = 0; - } - if (o.fat_type != 32) { - bpb.spf = bpb.bspf; - bpb.bspf = 0; - } - ch = 0; - if (o.fat_type == 12) - ch = 1; /* 001 Primary DOS with 12 bit FAT */ - else if (o.fat_type == 16) { - if (bpb.bsec == 0) - ch = 4; /* 004 Primary DOS with 16 bit FAT <32M */ - else - ch = 6; /* 006 Primary 'big' DOS, 16-bit FAT (> 32MB) */ - /* - * XXX: what about: - * 014 DOS (16-bit FAT) - LBA - * ? - */ - } else if (o.fat_type == 32) { - ch = 11; /* 011 Primary DOS with 32 bit FAT */ - /* - * XXX: what about: - * 012 Primary DOS with 32 bit FAT - LBA - * ? - */ - } - if (ch != 0) - printf("MBR type: %d\n", ch); - print_bpb(&bpb); - if (!o.no_create) { - if (o.timestamp_set) { - tv.tv_sec = now = o.timestamp; - tv.tv_usec = 0; - tm = gmtime(&now); - } else { - gettimeofday(&tv, NULL); - now = tv.tv_sec; - tm = localtime(&now); - } - if (!(img = malloc(bpb.bps))) - err(1, NULL); - dir = bpb.res + (bpb.spf ? bpb.spf : bpb.bspf) * bpb.nft; -#ifdef SIGINFO - signal(SIGINFO, infohandler); -#endif - for (lsn = 0; lsn < dir + (o.fat_type == 32 ? bpb.spc : rds); lsn++) { - if (got_siginfo) { - fprintf(stderr,"%s: writing sector %u of %u (%u%%)\n", - fname,lsn,(dir + (o.fat_type == 32 ? bpb.spc : rds)), - (lsn*100)/(dir + (o.fat_type == 32 ? bpb.spc : rds))); - got_siginfo = 0; - } - x = lsn; - if (o.bootstrap && - o.fat_type == 32 && bpb.bkbs != MAXU16 && - bss <= bpb.bkbs && x >= bpb.bkbs) { - x -= bpb.bkbs; - if (!x && lseek(fd1, o.offset, SEEK_SET)) { - warn("%s", bname); - return -1; - } - } - if (o.bootstrap && x < bss) { - if ((n = read(fd1, img, bpb.bps)) == -1) { - warn("%s", bname); - return -1; - } - if ((size_t)n != bpb.bps) { - warnx("%s: can't read sector %u", bname, x); - return -1; - } - } else - memset(img, 0, bpb.bps); - if (!lsn || - (o.fat_type == 32 && bpb.bkbs != MAXU16 && lsn == bpb.bkbs)) { - x1 = sizeof(struct bs); - bsbpb = (struct bsbpb *)(img + x1); - mk2(bsbpb->bps, bpb.bps); - mk1(bsbpb->spc, bpb.spc); - mk2(bsbpb->res, bpb.res); - mk1(bsbpb->nft, bpb.nft); - mk2(bsbpb->rde, bpb.rde); - mk2(bsbpb->sec, bpb.sec); - mk1(bsbpb->mid, bpb.mid); - mk2(bsbpb->spf, bpb.spf); - mk2(bsbpb->spt, bpb.spt); - mk2(bsbpb->hds, bpb.hds); - mk4(bsbpb->hid, bpb.hid); - mk4(bsbpb->bsec, bpb.bsec); - x1 += sizeof(struct bsbpb); - if (o.fat_type == 32) { - bsxbpb = (struct bsxbpb *)(img + x1); - mk4(bsxbpb->bspf, bpb.bspf); - mk2(bsxbpb->xflg, 0); - mk2(bsxbpb->vers, 0); - mk4(bsxbpb->rdcl, bpb.rdcl); - mk2(bsxbpb->infs, bpb.infs); - mk2(bsxbpb->bkbs, bpb.bkbs); - x1 += sizeof(struct bsxbpb); - } - bsx = (struct bsx *)(img + x1); - mk1(bsx->sig, 0x29); - if (o.volume_id_set) - x = o.volume_id; - else - x = (((u_int)(1 + tm->tm_mon) << 8 | - (u_int)tm->tm_mday) + - ((u_int)tm->tm_sec << 8 | - (u_int)(tv.tv_usec / 10))) << 16 | - ((u_int)(1900 + tm->tm_year) + - ((u_int)tm->tm_hour << 8 | - (u_int)tm->tm_min)); - mk4(bsx->volid, x); - mklabel(bsx->label, o.volume_label ? o.volume_label : "NO NAME"); - snprintf(buf, sizeof(buf), "FAT%u", o.fat_type); - setstr(bsx->type, buf, sizeof(bsx->type)); - if (!o.bootstrap) { - x1 += sizeof(struct bsx); - bs = (struct bs *)img; - mk1(bs->jmp[0], 0xeb); - mk1(bs->jmp[1], x1 - 2); - mk1(bs->jmp[2], 0x90); - setstr(bs->oem, o.OEM_string ? o.OEM_string : "NetBSD", - sizeof(bs->oem)); - memcpy(img + x1, bootcode, sizeof(bootcode)); - mk2(img + MINBPS - 2, DOSMAGIC); - } - } else if (o.fat_type == 32 && bpb.infs != MAXU16 && - (lsn == bpb.infs || - (bpb.bkbs != MAXU16 && - lsn == bpb.bkbs + bpb.infs))) { - mk4(img, 0x41615252); - mk4(img + MINBPS - 28, 0x61417272); - mk4(img + MINBPS - 24, 0xffffffff); - mk4(img + MINBPS - 20, 0xffffffff); - mk2(img + MINBPS - 2, DOSMAGIC); - } else if (lsn >= bpb.res && lsn < dir && - !((lsn - bpb.res) % - (bpb.spf ? bpb.spf : bpb.bspf))) { - mk1(img[0], bpb.mid); - for (x = 1; x < o.fat_type * (o.fat_type == 32 ? 3U : 2U) / 8U; x++) - mk1(img[x], o.fat_type == 32 && x % 4 == 3 ? 0x0f : 0xff); - } else if (lsn == dir && o.volume_label) { - de = (struct de *)img; - mklabel(de->namext, o.volume_label); - mk1(de->attr, 050); - x = (u_int)tm->tm_hour << 11 | - (u_int)tm->tm_min << 5 | - (u_int)tm->tm_sec >> 1; - mk2(de->time, x); - x = (u_int)(tm->tm_year - 80) << 9 | - (u_int)(tm->tm_mon + 1) << 5 | - (u_int)tm->tm_mday; - mk2(de->date, x); - } - if ((n = write(fd, img, bpb.bps)) == -1) { - warn("%s", fname); - return -1; - } - if ((size_t)n != bpb.bps) { - warnx("%s: can't write sector %u", fname, lsn); - return -1; - } - } - } - return 0; -} - -#ifndef MAKEFS -/* - * return -1 with error if file system is mounted. - */ -static int -check_mounted(const char *fname, mode_t mode) -{ - struct statvfs *mp; - const char *s1, *s2; - size_t len; - int n, r; - - if (!(n = getmntinfo(&mp, MNT_NOWAIT))) { - warn("getmntinfo"); - return -1; - } - len = strlen(_PATH_DEV); - s1 = fname; - if (!strncmp(s1, _PATH_DEV, len)) - s1 += len; - r = S_ISCHR(mode) && s1 != fname && *s1 == 'r'; - for (; n--; mp++) { - s2 = mp->f_mntfromname; - if (!strncmp(s2, _PATH_DEV, len)) - s2 += len; - if ((r && s2 != mp->f_mntfromname && !strcmp(s1 + 1, s2)) || - !strcmp(s1, s2)) { - warnx("%s is mounted on %s", fname, mp->f_mntonname); - return -1; - } - } - return 0; -} -#endif - -/* - * Get a standard format. - */ -static int -getstdfmt(const char *fmt, struct bpb *bpb) -{ - u_int x, i; - - x = sizeof(stdfmt) / sizeof(stdfmt[0]); - for (i = 0; i < x && strcmp(fmt, stdfmt[i].name); i++); - if (i == x) { - warnx("%s: unknown standard format", fmt); - return -1; - } - *bpb = stdfmt[i].bpb; - return 0; -} - -/* - * Get disk slice, partition, and geometry information. - */ -static int -getbpbinfo(int fd, const char *fname, const char *dtype, int iflag, - struct bpb *bpb, off_t create_size) -{ - const char *s1, *s2; - int part; - - part = -1; - s1 = fname; - if ((s2 = strrchr(s1, '/'))) - s1 = s2 + 1; - for (s2 = s1; *s2 && !isdigit((unsigned char)*s2); s2++); - if (!*s2 || s2 == s1) - s2 = NULL; - else - while (isdigit((unsigned char)*++s2)); - s1 = s2; - -#ifndef MAKEFS - int maxpartitions = getmaxpartitions(); - struct disk_geom geo; - struct dkwedge_info dkw; - - // XXX: Does not work with wedges - if (s2 && *s2 >= 'a' && *s2 <= 'a' + maxpartitions - 1) { - part = *s2++ - 'a'; - } -#endif - - if (!(((part != -1) && ((!iflag && part != -1) || !bpb->bsec)) || - !bpb->bps || !bpb->spt || !bpb->hds)) { - return 0; - } - - u_int sector_size = 512; - u_int nsectors = 63; - u_int ntracks = 255; - u_int size; - - if (create_size == 0) { -#ifndef MAKEFS - if (getdiskinfo(fname, fd, NULL, &geo, &dkw) != -1) { - sector_size = geo.dg_secsize; - nsectors = geo.dg_nsectors; - ntracks = geo.dg_ntracks; - size = dkw.dkw_size; - } else -#endif - { - struct stat st; - - if (fstat(fd, &st) == -1) { - warnx("Can't get disk size for `%s'", fname); - return -1; - } - size = st.st_size / sector_size; - } - } else { - size = create_size / sector_size; - } - - if (!bpb->bps) { - if (ckgeom(fname, sector_size, "bytes/sector") == -1) - return -1; - bpb->bps = sector_size; - } - - if (nsectors > 63) { - /* - * The kernel doesn't accept BPB with spt > 63. - * (see sys/fs/msdosfs/msdosfs_vfsops.c:msdosfs_mountfs()) - * If values taken from disklabel don't match these - * restrictions, use popular BIOS default values instead. - */ - nsectors = 63; - } - if (!bpb->spt) { - if (ckgeom(fname, nsectors, "sectors/track") == -1) - return -1; - bpb->spt = nsectors; - } - if (!bpb->hds) - if (ckgeom(fname, ntracks, "drive heads") == -1) - return -1; - bpb->hds = ntracks; - if (!bpb->bsec) - bpb->bsec = size; - - return 0; -} - -/* - * Print out BPB values. - */ -static void -print_bpb(struct bpb *bpb) -{ - printf("bps=%u spc=%u res=%u nft=%u", bpb->bps, bpb->spc, bpb->res, - bpb->nft); - if (bpb->rde) - printf(" rde=%u", bpb->rde); - if (bpb->sec) - printf(" sec=%u", bpb->sec); - printf(" mid=%#x", bpb->mid); - if (bpb->spf) - printf(" spf=%u", bpb->spf); - printf(" spt=%u hds=%u hid=%u", bpb->spt, bpb->hds, bpb->hid); - if (bpb->bsec) - printf(" bsec=%u", bpb->bsec); - if (!bpb->spf) { - printf(" bspf=%u rdcl=%u", bpb->bspf, bpb->rdcl); - printf(" infs="); - printf(bpb->infs == MAXU16 ? "%#x" : "%u", bpb->infs); - printf(" bkbs="); - printf(bpb->bkbs == MAXU16 ? "%#x" : "%u", bpb->bkbs); - } - printf("\n"); -} - -/* - * Check a disk geometry value. - */ -static int -ckgeom(const char *fname, u_int val, const char *msg) -{ - if (!val) { - warnx("%s: no default %s", fname, msg); - return -1; - } - if (val > MAXU16) { - warnx("%s: illegal %s", fname, msg); - return -1; - } - return 0; -} -/* - * Check a volume label. - */ -static int -oklabel(const char *src) -{ - int c, i; - - for (i = 0; i <= 11; i++) { - c = (u_char)*src++; - if (c < ' ' + !i || strchr("\"*+,./:;<=>?[\\]|", c)) - break; - } - return i && !c; -} - -/* - * Make a volume label. - */ -static void -mklabel(u_int8_t *dest, const char *src) -{ - int c, i; - - for (i = 0; i < 11; i++) { - c = *src ? toupper((unsigned char)*src++) : ' '; - *dest++ = !i && c == '\xe5' ? 5 : c; - } -} - -/* - * Copy string, padding with spaces. - */ -static void -setstr(u_int8_t *dest, const char *src, size_t len) -{ - while (len--) - *dest++ = *src ? *src++ : ' '; -} - -static void -infohandler(int sig) -{ - got_siginfo = 1; -} diff --git a/sbin/newfs_msdos/mkfs_msdos.h b/sbin/newfs_msdos/mkfs_msdos.h deleted file mode 100644 index ed31bd144..000000000 --- a/sbin/newfs_msdos/mkfs_msdos.h +++ /dev/null @@ -1,70 +0,0 @@ -/* $NetBSD: mkfs_msdos.h,v 1.6 2017/02/17 09:29:35 wiz Exp $ */ - -/*- - * Copyright (c) 2013 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Christos Zoulas. - * - * 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 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. - */ - -#include -#include -#define ALLOPTS \ -AOPT('@', off_t, offset, 0, "Offset in device") \ -AOPT('B', char *, bootstrap, -1, "Bootstrap file") \ -AOPT('C', off_t, create_size, 0, "Create file") \ -AOPT('F', uint8_t, fat_type, 12, "FAT type (12, 16, or 32)") \ -AOPT('I', uint32_t, volume_id, 0, "Volume ID") \ -AOPT('L', char *, volume_label, -1, "Volume Label") \ -AOPT('N', bool, no_create, -2, "Don't create file system, print params only") \ -AOPT('O', char *, OEM_string, -1, "OEM string") \ -AOPT('S', uint16_t, bytes_per_sector, 1, "Bytes per sector") \ -AOPT('a', uint32_t, sectors_per_fat, 1, "Sectors per FAT") \ -AOPT('b', uint32_t, block_size, 1, "Block size") \ -AOPT('c', uint8_t, sectors_per_cluster, 1, "Sectors per cluster") \ -AOPT('e', uint16_t, directory_entries, 1, "Directory entries") \ -AOPT('f', char *, floppy, -1, "Standard format floppies (160,180,320,360,640,720,1200,1232,1440,2880)") \ -AOPT('h', uint16_t, drive_heads, 1, "Drive heads") \ -AOPT('i', uint16_t, info_sector, 1, "Info sector") \ -AOPT('k', uint16_t, backup_sector, 1, "Backup sector") \ -AOPT('m', uint8_t, media_descriptor, 0, "Media descriptor") \ -AOPT('n', uint8_t, num_FAT, 1, "Number of FATs") \ -AOPT('o', uint32_t, hidden_sectors, 0, "Hidden sectors") \ -AOPT('r', uint16_t, reserved_sectors, 1, "Reserved sectors") \ -AOPT('s', uint32_t, size, 1, "File System size") \ -AOPT('u', uint16_t, sectors_per_track, 1, "Sectors per track") - -struct msdos_options { -#define AOPT(_opt, _type, _name, _min, _desc) _type _name; -ALLOPTS -#undef AOPT - time_t timestamp; - uint32_t timestamp_set:1; - uint32_t volume_id_set:1; - uint32_t media_descriptor_set:1; - uint32_t hidden_sectors_set:1; -}; - -int mkfs_msdos(const char *, const char *, const struct msdos_options *); diff --git a/sbin/newfs_msdos/newfs_msdos.8 b/sbin/newfs_msdos/newfs_msdos.8 deleted file mode 100644 index a848388c7..000000000 --- a/sbin/newfs_msdos/newfs_msdos.8 +++ /dev/null @@ -1,253 +0,0 @@ -.\" $NetBSD: newfs_msdos.8,v 1.23 2017/02/17 09:29:35 wiz Exp $ -.\" -.\" Copyright (c) 1998 Robert Nordier -.\" 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(S) ``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(S) 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: $FreeBSD: src/sbin/newfs_msdos/newfs_msdos.8,v 1.13 2001/08/14 10:01:48 ru Exp $ -.\" -.Dd February 16, 2017 -.Dt NEWFS_MSDOS 8 -.Os -.Sh NAME -.Nm newfs_msdos -.Nd construct a new MS-DOS (FAT) file system -.Sh SYNOPSIS -.Nm -.Op Fl N -.Op Fl @ Ar offset -.Op Fl B Ar boot -.Op Fl C Ar create-size -.Op Fl F Ar FAT-type -.Op Fl I Ar volid -.Op Fl L Ar label -.Op Fl O Ar OEM -.Op Fl S Ar sector-size -.Op Fl a Ar FAT-size -.Op Fl b Ar block-size -.Op Fl c Ar cluster-size -.Op Fl e Ar dirents -.Op Fl f Ar format -.Op Fl h Ar heads -.Op Fl i Ar info -.Op Fl k Ar backup -.Op Fl m Ar media -.Op Fl n Ar FATs -.Op Fl o Ar hidden -.Op Fl r Ar reserved -.Op Fl s Ar total -.Op Fl T Ar timestamp -.Op Fl u Ar track-size -.Ar special -.Op Ar disktype -.Sh DESCRIPTION -The -.Nm -utility creates a FAT12, FAT16, or FAT32 file system on device or file named -.Ar special , -using -.Xr disktab 5 -entry -.Ar disktype -to determine geometry, if required. -.Pp -The options are as follow: -.Bl -tag -width indent -.It Fl N -Do not create a file system: just print out parameters. -.It Fl @ Ar offset -Build the file system at the specified offset in bytes in the device or file. -A suffix s, k, m, g (lower or upper case) -appended to the offset specifies that the -number is in sectors, kilobytes, megabytes or gigabytes, respectively. -.It Fl B Ar boot -Get bootstrap from file. -.It Fl C Ar create-size -Create the image file with the specified size. -A suffix character appended to the size is interpreted as for the -.Fl @ -option. -The file is created by truncating any existing file with the -same name, seeking just before the required size and writing -a single 0 byte. -As a consequence, the space occupied on disk -may be smaller than the size specified as a parameter. -.It Fl F Ar FAT-type -FAT type (one of 12, 16, or 32). -.It Fl I Ar volid -Volume ID. -.It Fl L Ar label -Volume label (up to 11 characters). -The label should consist of only those characters permitted -in regular DOS (8+3) filenames. -The default is -.Qq Li "NO NAME" . -.It Fl O Ar OEM -OEM string (up to 8 characters). -The default is -.Qq Li "NetBSD" . -.It Fl S Ar sector-size -Number of bytes per sector. -Acceptable values are powers of 2 in the range 512 through 32768. -.It Fl a Ar FAT-size -Number of sectors per FAT. -.It Fl b Ar block-size -File system block size (bytes per cluster). -This should resolve to an acceptable number of sectors -per cluster (see below). -.It Fl c Ar cluster-size -Sectors per cluster. -Acceptable values are powers of 2 in the range 1 through 128. -If the block or cluster size are not specified, the code -uses a cluster between 512 bytes and 32K depending on -the file system size. -.It Fl e Ar dirents -Number of root directory entries (FAT12 and FAT16 only). -.It Fl f Ar format -Specify a standard (floppy disk) format. -The standard formats are (capacities in kilobytes): -160, 180, 320, 360, 640, 720, 1200, 1232, 1440, 2880. -.It Fl h Ar heads -Number of drive heads. -.It Fl i Ar info -Location of the file system info sector (FAT32 only). -A value of 0xffff signifies no info sector. -.It Fl k Ar backup -Location of the backup boot sector (FAT32 only). -A value of 0xffff signifies no backup sector. -.It Fl m Ar media -Media descriptor (acceptable range 0xf0 to 0xff). -.It Fl n Ar FATs -Number of FATs. -Acceptable values are 1 to 16 inclusive. -The default is 2. -.It Fl o Ar hidden -Number of hidden sectors. -.It Fl r Ar reserved -Number of reserved sectors. -.It Fl s Ar total -File system size. -.It Fl T At timestamp -Specify a timestamp to be used for file system creation so that -it can be consistent for reproducible builds. -The timestamp can be a pathname, where the timestamps are derived from -that file, a parseable date for parsedate(3) (this option is not -yet available in the tools build), or an integer value interpreted -as the number of seconds from the Epoch. -.It Fl u Ar track-size -Number of sectors per track. -.El -.Pp -If -.Nm -receives a -.Dv SIGINFO -signal -(see the -.Sy status -argument for -.Xr stty 1 ) , -a line will be written to the standard error output indicating -the name of the device currently being formatted, the sector -number being written, and the total number of sectors to be written. -.Sh NOTES -If some parameters (e.g. size, number of sectors, etc.) are not specified -through options or disktype, the program tries to generate them -automatically. -In particular, the size is determined as the -device or file size minus the offset specified with the -.Fl @ -option. -When the geometry is not available, it is assumed to be -63 sectors, 255 heads. -The size is then rounded to become -a multiple of the track size and avoid complaints by some file system code. -.Pp -FAT file system parameters occupy a "Boot Sector BPB (BIOS Parameter -Block)" in the first of the "reserved" sectors which precede the actual -file system. -For reference purposes, this structure is presented below. -.Bd -literal -struct bsbpb { - u_int16_t bps; /* [-S] bytes per sector */ - u_int8_t spc; /* [-c] sectors per cluster */ - u_int16_t res; /* [-r] reserved sectors */ - u_int8_t nft; /* [-n] number of FATs */ - u_int16_t rde; /* [-e] root directory entries */ - u_int16_t sec; /* [-s] total sectors */ - u_int8_t mid; /* [-m] media descriptor */ - u_int16_t spf; /* [-a] sectors per FAT */ - u_int16_t spt; /* [-u] sectors per track */ - u_int16_t hds; /* [-h] drive heads */ - u_int32_t hid; /* [-o] hidden sectors */ - u_int32_t bsec; /* [-s] big total sectors */ -}; -/* FAT32 extensions */ -struct bsxbpb { - u_int32_t bspf; /* [-a] big sectors per FAT */ - u_int16_t xflg; /* control flags */ - u_int16_t vers; /* file system version */ - u_int32_t rdcl; /* root directory start cluster */ - u_int16_t infs; /* [-i] file system info sector */ - u_int16_t bkbs; /* [-k] backup boot sector */ -}; -.Ed -.Sh EXAMPLES -.Bd -literal -offset indent -newfs_msdos /dev/rwd1a -.Ed -.Pp -Create a file system, using default parameters, on -.Pa /dev/rwd1a . -.Bd -literal -offset indent -newfs_msdos -f 1440 -L foo /dev/rfd0a -.Ed -.Pp -Create a standard 1.44M file system, with volume label -.Ar foo , -on -.Pa /dev/rfd0a . -Create a 30MB image file, with the FAT partition starting -63 sectors within the image file: -.Bd -literal -offset indent -newfs_msdos -C 30M -@63s ./somefile -.Ed -.Sh DIAGNOSTICS -Exit status is 0 on success and 1 on error. -.Sh SEE ALSO -.Xr disktab 5 , -.Xr disklabel 8 , -.Xr fdisk 8 , -.Xr newfs 8 -.Sh HISTORY -A -.Nm -utility appeared in -.Fx 3.0 . -The -.Nm -command first appeared in -.Nx 1.3 . -.Sh AUTHORS -.An Robert Nordier Aq Mt rnordier@FreeBSD.org . diff --git a/sbin/newfs_msdos/newfs_msdos.c b/sbin/newfs_msdos/newfs_msdos.c deleted file mode 100644 index 9f333b4f9..000000000 --- a/sbin/newfs_msdos/newfs_msdos.c +++ /dev/null @@ -1,283 +0,0 @@ -/* $NetBSD: newfs_msdos.c,v 1.45 2017/02/16 22:42:25 christos Exp $ */ - -/* - * Copyright (c) 1998 Robert Nordier - * 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(S) ``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(S) 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 -#ifndef lint -#if 0 -static const char rcsid[] = - "$FreeBSD: src/sbin/newfs_msdos/newfs_msdos.c,v 1.15 2000/10/10 01:49:37 wollman Exp $"; -#else -__RCSID("$NetBSD: newfs_msdos.c,v 1.45 2017/02/16 22:42:25 christos Exp $"); -#endif -#endif /* not lint */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "mkfs_msdos.h" - -#define argto1(arg, lo, msg) argtou(arg, lo, 0xff, msg) -#define argto2(arg, lo, msg) argtou(arg, lo, 0xffff, msg) -#define argto4(arg, lo, msg) argtou(arg, lo, 0xffffffff, msg) -#define argtox(arg, lo, msg) argtou(arg, lo, UINT_MAX, msg) - -__dead static void usage(void); -static u_int argtou(const char *, u_int, u_int, const char *); -static off_t argtooff(const char *, const char *); - -static time_t -get_tstamp(const char *b) -{ - struct stat st; - char *eb; - long long l; -#ifndef HAVE_NBTOOL_CONFIG_H - time_t when; -#endif - - if (stat(b, &st) != -1) - return (time_t)st.st_mtime; - -#ifndef HAVE_NBTOOL_CONFIG_H - errno = 0; - if ((when = parsedate(b, NULL, NULL)) != -1 || errno == 0) - return when; -#endif - errno = 0; - l = strtoll(b, &eb, 0); - if (b == eb || *eb || errno) - errx(EXIT_FAILURE, "Can't parse timestamp `%s'", b); - return (time_t)l; -} - -/* - * Construct a FAT12, FAT16, or FAT32 file system. - */ -int -main(int argc, char *argv[]) -{ - static const char opts[] = "@:NB:C:F:I:L:O:S:a:b:c:e:f:h:i:k:m:n:o:r:s:T:u:"; - struct msdos_options o; - char *fname, *dtype; - char buf[MAXPATHLEN]; - int ch; - - memset(&o, 0, sizeof(o)); - - while ((ch = getopt(argc, argv, opts)) != -1) - switch (ch) { - case '@': - o.offset = argtooff(optarg, "offset"); - break; - case 'N': - o.no_create = 1; - break; - case 'B': - o.bootstrap = optarg; - break; - case 'C': - o.create_size = argtooff(optarg, "create size"); - break; - case 'F': - o.fat_type = atoi(optarg); - break; - case 'I': - o.volume_id = argto4(optarg, 0, "volume ID"); - o.volume_id_set = 1; - break; - case 'L': - o.volume_label = optarg; - break; - case 'O': - o.OEM_string = optarg; - break; - case 'S': - o.bytes_per_sector = argto2(optarg, 1, "bytes/sector"); - break; - case 'a': - o.sectors_per_fat = argto4(optarg, 1, "sectors/FAT"); - break; - case 'b': - o.block_size = argtox(optarg, 1, "block size"); - break; - case 'c': - o.sectors_per_cluster = argto1(optarg, 1, "sectors/cluster"); - break; - case 'e': - o.directory_entries = argto2(optarg, 1, "directory entries"); - break; - case 'f': - o.floppy = optarg; - break; - case 'h': - o.drive_heads = argto2(optarg, 1, "drive heads"); - break; - case 'i': - o.info_sector = argto2(optarg, 1, "info sector"); - break; - case 'k': - o.backup_sector = argto2(optarg, 1, "backup sector"); - break; - case 'm': - o.media_descriptor = argto1(optarg, 0, "media descriptor"); - o.media_descriptor_set = 1; - break; - case 'n': - o.num_FAT = argto1(optarg, 1, "number of FATs"); - break; - case 'o': - o.hidden_sectors = argto4(optarg, 0, "hidden sectors"); - o.hidden_sectors_set = 1; - break; - case 'r': - o.reserved_sectors = argto2(optarg, 1, "reserved sectors"); - break; - case 's': - o.size = argto4(optarg, 1, "file system size"); - break; - case 'T': - o.timestamp_set = 1; - o.timestamp = get_tstamp(optarg); - break; - case 'u': - o.sectors_per_track = argto2(optarg, 1, "sectors/track"); - break; - default: - usage(); - } - argc -= optind; - argv += optind; - if (argc < 1 || argc > 2) - usage(); - fname = *argv++; - if (!strchr(fname, '/') && !o.create_size) { - snprintf(buf, sizeof(buf), "%sr%s", _PATH_DEV, fname); - if (!(fname = strdup(buf))) - err(1, NULL); - } - dtype = *argv; - return mkfs_msdos(fname, dtype, &o); -} - -/* - * Convert and check a numeric option argument. - */ -static u_int -argtou(const char *arg, u_int lo, u_int hi, const char *msg) -{ - off_t x; - - errno = 0; - x = argtooff(arg, msg); - if (x < lo || x > hi) - errx(1, "%s: bad %s", arg, msg); - return (u_int)x; -} - -/* - * Same for off_t, with optional skmgpP suffix - */ -static off_t -argtooff(const char *arg, const char *msg) -{ - char *s; - off_t x; - - errno = 0; - x = strtoll(arg, &s, 0); - /* allow at most one extra char */ - if (errno || x < 0 || (s[0] && s[1]) ) - errx(1, "%s: bad %s", arg, msg); - if (*s) { /* the extra char is the multiplier */ - switch (*s) { - default: - errx(1, "%s: bad %s", arg, msg); - /* notreached */ - - case 's': /* sector */ - case 'S': - x <<= 9; /* times 512 */ - break; - - case 'k': /* kilobyte */ - case 'K': - x <<= 10; /* times 1024 */ - break; - - case 'm': /* megabyte */ - case 'M': - x <<= 20; /* times 1024*1024 */ - break; - - case 'g': /* gigabyte */ - case 'G': - x <<= 30; /* times 1024*1024*1024 */ - break; - - case 'p': /* partition start */ - case 'P': /* partition start */ - case 'l': /* partition length */ - case 'L': /* partition length */ - errx(1, "%s: not supported yet %s", arg, msg); - return -1; - /* notreached */ - } - } - return x; -} - -/* - * Print usage message. - */ -static void -usage(void) -{ - fprintf(stderr, - "usage: %s [ -options ] special [disktype]\n", getprogname()); - fprintf(stderr, "where the options are:\n"); -static struct { - char o; - const char *h; -} opts[] = { -#define AOPT(_opt, _type, _name, _min, _desc) { _opt, _desc }, -ALLOPTS -#undef AOPT -}; - for (size_t i = 0; i < __arraycount(opts); i++) - fprintf(stderr, "\t-%c %s\n", opts[i].o, opts[i].h); - exit(1); -} diff --git a/sbin/newfs_udf/Makefile b/sbin/newfs_udf/Makefile deleted file mode 100644 index f9ec40c8a..000000000 --- a/sbin/newfs_udf/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# $NetBSD: Makefile,v 1.5 2014/03/18 18:20:39 riastradh Exp $ - -.include - -PROG= newfs_udf -MAN= newfs_udf.8 -SRCS= newfs_udf.c udf_create.c udf_write.c udf_osta.c fattr.c - -MOUNT= ${NETBSDSRCDIR}/sbin/mount -KUDF= ${NETBSDSRCDIR}/sys/fs/udf -CPPFLAGS+= -I${MOUNT} -I${KUDF} -I${NETBSDSRCDIR}/sys -.PATH: ${MOUNT} ${KUDF} - -DPADD+=${LIBUTIL} -LDADD+=-lutil - -.include diff --git a/sbin/newfs_udf/newfs_udf.8 b/sbin/newfs_udf/newfs_udf.8 deleted file mode 100644 index 2660fb4e7..000000000 --- a/sbin/newfs_udf/newfs_udf.8 +++ /dev/null @@ -1,191 +0,0 @@ -.\" $NetBSD: newfs_udf.8,v 1.18 2013/08/06 12:15:20 wiz Exp $ -.\" -.\" Copyright (c) 2008 Reinoud Zandijk -.\" 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(S) ``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(S) 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. -.\" -.\" -.Dd August 2, 2013 -.Dt NEWFS_UDF 8 -.Os -.Sh NAME -.Nm newfs_udf -.Nd construct a new UDF file system -.Sh SYNOPSIS -.Nm -.Op Fl cFM -.Op Fl B Ar blockingsize -.Op Fl L Ar loglabel -.Op Fl P Ar discid -.Op Fl p Ar percentage -.Op Fl S Ar sectorsize -.Op Fl s Ar size -.Op Fl t Ar gmtoff -.Op Fl V Ar max_udf -.Op Fl v Ar min_udf -.Ar special -.Sh DESCRIPTION -The -.Nm -utility creates an UDF file system on device -.Ar special -suitable for the media currently inserted. -.Pp -The options are as follow: -.Bl -tag -width indent -.It Fl B Ar blockingsize -When creating image files, specify the blocking size or packetsize of the media -to -.Ar blockingsize . -.It Fl c -Perform a crude surface check first to weed out disc faults on rewritable -media. -.It Fl F -Force file system construction on non-empty recordable media or create an -image file. -.It Fl L Ar loglabel -Set the disc logical label to the specified -.Ar loglabel . -.It Fl M -Disable metadata partition creation when selected UDF version or media dictates -this. -For strict conformance and interchange, don't disable this unless -its causing problems. -.It Fl P Ar discid -Set the physical disc label to the specified -.Ar discid . -.Pp -Prepend -.Ar discid -with volsetname separated with a ':' if wanted. -For strict conformance and interchange, don't set this manually unless it has -a unique hex number in the first 8 character positions. -.It Fl p Ar percentage -Percentage of partition to be initially reserved for metadata on the Metadata -partition. -It defaults to 20 %. -.It Fl S Ar sectorsize -Set the sectorsize for image files. -For strict conformance and interchange, don't set this manually. -.It Fl s Ar size -For image files, set the file size to the humanized size -.Ar size . -.It Fl t Ar gmtoff -Use the specified -.Ar gmtoff -as gmt time offset for recording times on the disc. -.It Fl V Ar max_udf -Select -.Ar max_udf -as the maximum UDF version to be supported. -For UDF version 2.50, use -.Dq 0x250 -or -.Dq 2.50 . -.It Fl v Ar min_udf -Select -.Ar min_udf -as the minimum UDF version to be supported. -For UDF version 2.01, use -.Dq 0x201 -or -.Dq 2.01 . -.El -.Sh NOTES -The UDF file system is defined for the entire optical medium. -It can only function on the entire CD/DVD/BD so the raw partition -has to be specified for read/write actions. -For -.Nm -this means specifying the raw device with the raw partition, i.e. -.Pa /dev/rcd0d -or -.Pa /dev/rcd0c . -.Pp -Some rewritable optical media needs to be formatted first before it can be -used by UDF. -This can be done using -.Xr mmcformat 8 . -.Pp -The default UDF version is version 2.01. -.Sh EXAMPLES -Create a file system, using the specified names on the device -.Pa /dev/rcd0d -with the default UDF version : -.Bd -literal -offset indent -newfs_udf -P "Encyclopedia:copy-nr-1" -L "volume 2" /dev/rcd0d -.Ed -.Pp -Create a 4.8 GiB sparse file and configure it using -.Xr vnconfig 8 -to be a 2048 sector size disc and create a new UDF file system on -.Pa /dev/rvnd0d -: -.Bd -literal -offset indent -dd if=/dev/zero of=bigdisk.2048.udf seek=9999999 count=1 -vnconfig -c vnd0 bigdisk.2048.udf 2048/1/1/1 -newfs_udf -L bigdisk /dev/rvnd0d -.Ed -.Pp -Create a 2 GiB file and create a new UDF file system on it using the default -512 byte sector size : -.Bd -literal -offset indent -newfs_udf -L bigdisk2 -F -s 2G bigdisk2.iso -.Ed -.Pp -Create a 200 MiB file and create a new UDF file system on it using a sector size -of 2048 : -.Bd -literal -offset indent -newfs_udf -L bigdisk2 -F -s 200M -S 2048 bigdisk3.iso -.Ed -.Pp -Create a new UDF file system on the inserted USB stick using its -native sectorsize of 512 : -.Bd -literal -offset indent -newfs_udf -L "My USB stick" /dev/rsd0d -.Ed -.Sh SEE ALSO -.Xr disktab 5 , -.Xr disklabel 8 , -.Xr mmcformat 8 , -.Xr newfs 8 -.Sh HISTORY -The -.Nm -command first appeared in -.Nx 5.0 . -.Sh AUTHORS -.An Reinoud Zandijk Aq Mt reinoud@NetBSD.org -.Sh BUGS -The -.Ar P -and the -.Ar S -arguments have changed meaning. -The meaning of -.Ar S -has been merged into -.Ar P -since -.Nx 6.1 . diff --git a/sbin/newfs_udf/newfs_udf.c b/sbin/newfs_udf/newfs_udf.c deleted file mode 100644 index eaab2b144..000000000 --- a/sbin/newfs_udf/newfs_udf.c +++ /dev/null @@ -1,896 +0,0 @@ -/* $NetBSD: newfs_udf.c,v 1.18 2013/08/09 15:11:08 reinoud Exp $ */ - -/* - * Copyright (c) 2006, 2008, 2013 Reinoud Zandijk - * 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 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. - * - */ - -/* - * TODO - * - implement metadata formatting for BD-R - * - implement support for a read-only companion partition? - */ - -#define _EXPOSE_MMC -#if 0 -# define DEBUG -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "mountprog.h" -#include "udf_create.h" -#include "udf_write.h" -#include "newfs_udf.h" - -/* prototypes */ -int newfs_udf(int argc, char **argv); -static void usage(void) __attribute__((__noreturn__)); - - -/* queue for temporary storage of sectors to be written out */ -struct wrsect { - uint64_t sectornr; - uint8_t *sector_data; - TAILQ_ENTRY(wrsect) next; -}; - -/* write queue and track blocking skew */ -TAILQ_HEAD(wrsect_list, wrsect) write_queue; - - -/* global variables describing disc and format requests */ -int fd; /* device: file descriptor */ -char *dev; /* device: name */ -struct mmc_discinfo mmc_discinfo; /* device: disc info */ - -char *format_str; /* format: string representation */ -int format_flags; /* format: attribute flags */ -int media_accesstype; /* derived from current mmc cap */ -int check_surface; /* for rewritables */ -int imagefile_secsize; /* for files */ -int emul_packetsize; /* for discs and files */ - -int wrtrack_skew; -int meta_perc = UDF_META_PERC; -float meta_fract = (float) UDF_META_PERC / 100.0; - - -/* --------------------------------------------------------------------- */ - -/* - * write queue implementation - */ - -int -udf_write_sector(void *sector, uint64_t location) -{ - struct wrsect *pos, *seekpos; - - - /* search location */ - TAILQ_FOREACH_REVERSE(seekpos, &write_queue, wrsect_list, next) { - if (seekpos->sectornr <= location) - break; - } - if ((seekpos == NULL) || (seekpos->sectornr != location)) { - pos = calloc(1, sizeof(struct wrsect)); - if (pos == NULL) - return ENOMEM; - /* allocate space for copy of sector data */ - pos->sector_data = calloc(1, context.sector_size); - if (pos->sector_data == NULL) - return ENOMEM; - pos->sectornr = location; - - if (seekpos) { - TAILQ_INSERT_AFTER(&write_queue, seekpos, pos, next); - } else { - TAILQ_INSERT_HEAD(&write_queue, pos, next); - } - } else { - pos = seekpos; - } - memcpy(pos->sector_data, sector, context.sector_size); - - return 0; -} - - -/* - * Now all write requests are queued in the TAILQ, write them out to the - * disc/file image. Special care needs to be taken for devices that are only - * strict overwritable i.e. only in packet size chunks - * - * XXX support for growing vnd? - */ - -int -writeout_write_queue(void) -{ - struct wrsect *pos; - uint64_t offset; - uint64_t line_start, new_line_start; - uint32_t line_len, line_offset, relpos; - uint32_t blockingnr; - uint8_t *linebuf, *adr; - - blockingnr = layout.blockingnr; - line_len = blockingnr * context.sector_size; - line_offset = wrtrack_skew * context.sector_size; - - linebuf = malloc(line_len); - if (linebuf == NULL) - return ENOMEM; - - pos = TAILQ_FIRST(&write_queue); - bzero(linebuf, line_len); - - /* - * Always writing out in whole lines now; this is slightly wastefull - * on logical overwrite volumes but it reduces complexity and the loss - * is near zero compared to disc size. - */ - line_start = (pos->sectornr - wrtrack_skew) / blockingnr; - TAILQ_FOREACH(pos, &write_queue, next) { - new_line_start = (pos->sectornr - wrtrack_skew) / blockingnr; - if (new_line_start != line_start) { - /* write out */ - offset = (uint64_t) line_start * line_len + line_offset; -#ifdef DEBUG - printf("WRITEOUT %08"PRIu64" + %02d -- " - "[%08"PRIu64"..%08"PRIu64"]\n", - offset / context.sector_size, blockingnr, - offset / context.sector_size, - offset / context.sector_size + blockingnr-1); -#endif - if (pwrite(fd, linebuf, line_len, offset) < 0) { - perror("Writing failed"); - return errno; - } - line_start = new_line_start; - bzero(linebuf, line_len); - } - - relpos = (pos->sectornr - wrtrack_skew) % blockingnr; - adr = linebuf + relpos * context.sector_size; - memcpy(adr, pos->sector_data, context.sector_size); - } - /* writeout last chunk */ - offset = (uint64_t) line_start * line_len + line_offset; -#ifdef DEBUG - printf("WRITEOUT %08"PRIu64" + %02d -- [%08"PRIu64"..%08"PRIu64"]\n", - offset / context.sector_size, blockingnr, - offset / context.sector_size, - offset / context.sector_size + blockingnr-1); -#endif - if (pwrite(fd, linebuf, line_len, offset) < 0) { - perror("Writing failed"); - return errno; - } - - /* success */ - return 0; -} - -/* --------------------------------------------------------------------- */ - -/* - * mmc_discinfo and mmc_trackinfo readers modified from origional in udf main - * code in sys/fs/udf/ - */ - -#ifdef DEBUG -static void -udf_dump_discinfo(struct mmc_discinfo *di) -{ - char bits[128]; - - printf("Device/media info :\n"); - printf("\tMMC profile 0x%02x\n", di->mmc_profile); - printf("\tderived class %d\n", di->mmc_class); - printf("\tsector size %d\n", di->sector_size); - printf("\tdisc state %d\n", di->disc_state); - printf("\tlast ses state %d\n", di->last_session_state); - printf("\tbg format state %d\n", di->bg_format_state); - printf("\tfrst track %d\n", di->first_track); - printf("\tfst on last ses %d\n", di->first_track_last_session); - printf("\tlst on last ses %d\n", di->last_track_last_session); - printf("\tlink block penalty %d\n", di->link_block_penalty); - snprintb(bits, sizeof(bits), MMC_DFLAGS_FLAGBITS, (uint64_t) di->disc_flags); - printf("\tdisc flags %s\n", bits); - printf("\tdisc id %x\n", di->disc_id); - printf("\tdisc barcode %"PRIx64"\n", di->disc_barcode); - - printf("\tnum sessions %d\n", di->num_sessions); - printf("\tnum tracks %d\n", di->num_tracks); - - snprintb(bits, sizeof(bits), MMC_CAP_FLAGBITS, di->mmc_cur); - printf("\tcapabilities cur %s\n", bits); - snprintb(bits, sizeof(bits), MMC_CAP_FLAGBITS, di->mmc_cap); - printf("\tcapabilities cap %s\n", bits); - printf("\n"); - printf("\tlast_possible_lba %d\n", di->last_possible_lba); - printf("\n"); -} -#else -#define udf_dump_discinfo(a); -#endif - -/* --------------------------------------------------------------------- */ - -static int -udf_update_discinfo(struct mmc_discinfo *di) -{ - struct stat st; - struct disklabel disklab; - struct partition *dp; - off_t size, sectors, secsize; - int partnr, error; - - memset(di, 0, sizeof(struct mmc_discinfo)); - - /* check if we're on a MMC capable device, i.e. CD/DVD */ - error = ioctl(fd, MMCGETDISCINFO, di); - if (error == 0) - return 0; - - /* (re)fstat the file */ - fstat(fd, &st); - - if (S_ISREG(st.st_mode)) { - /* file support; we pick the minimum sector size allowed */ - size = st.st_size; - secsize = imagefile_secsize; - sectors = size / secsize; - } else { - /* - * disc partition support; note we can't use DIOCGPART in - * userland so get disc label and use the stat info to get the - * partition number. - */ - if (ioctl(fd, DIOCGDINFO, &disklab) == -1) { - /* failed to get disclabel! */ - perror("disklabel"); - return errno; - } - - /* get disk partition it refers to */ - fstat(fd, &st); - partnr = DISKPART(st.st_rdev); - dp = &disklab.d_partitions[partnr]; - - /* TODO problem with last_possible_lba on resizable VND */ - if (dp->p_size == 0) { - perror("faulty disklabel partition returned, " - "check label\n"); - return EIO; - } - - sectors = dp->p_size; - secsize = disklab.d_secsize; - } - - /* set up a disc info profile for partitions */ - di->mmc_profile = 0x01; /* disc type */ - di->mmc_class = MMC_CLASS_DISC; - di->disc_state = MMC_STATE_CLOSED; - di->last_session_state = MMC_STATE_CLOSED; - di->bg_format_state = MMC_BGFSTATE_COMPLETED; - di->link_block_penalty = 0; - - di->mmc_cur = MMC_CAP_RECORDABLE | MMC_CAP_REWRITABLE | - MMC_CAP_ZEROLINKBLK | MMC_CAP_HW_DEFECTFREE; - di->mmc_cap = di->mmc_cur; - di->disc_flags = MMC_DFLAGS_UNRESTRICTED; - - di->last_possible_lba = sectors - 1; - di->sector_size = secsize; - - di->num_sessions = 1; - di->num_tracks = 1; - - di->first_track = 1; - di->first_track_last_session = di->last_track_last_session = 1; - - return 0; -} - - -int -udf_update_trackinfo(struct mmc_discinfo *di, struct mmc_trackinfo *ti) -{ - int error, class; - - class = di->mmc_class; - if (class != MMC_CLASS_DISC) { - /* tracknr specified in struct ti */ - error = ioctl(fd, MMCGETTRACKINFO, ti); - return error; - } - - /* discs partition support */ - if (ti->tracknr != 1) - return EIO; - - /* create fake ti (TODO check for resized vnds) */ - ti->sessionnr = 1; - - ti->track_mode = 0; /* XXX */ - ti->data_mode = 0; /* XXX */ - ti->flags = MMC_TRACKINFO_LRA_VALID | MMC_TRACKINFO_NWA_VALID; - - ti->track_start = 0; - ti->packet_size = emul_packetsize; - - /* TODO support for resizable vnd */ - ti->track_size = di->last_possible_lba; - ti->next_writable = di->last_possible_lba; - ti->last_recorded = ti->next_writable; - ti->free_blocks = 0; - - return 0; -} - - -static int -udf_setup_writeparams(struct mmc_discinfo *di) -{ - struct mmc_writeparams mmc_writeparams; - int error; - - if (di->mmc_class == MMC_CLASS_DISC) - return 0; - - /* - * only CD burning normally needs setting up, but other disc types - * might need other settings to be made. The MMC framework will set up - * the nessisary recording parameters according to the disc - * characteristics read in. Modifications can be made in the discinfo - * structure passed to change the nature of the disc. - */ - memset(&mmc_writeparams, 0, sizeof(struct mmc_writeparams)); - mmc_writeparams.mmc_class = di->mmc_class; - mmc_writeparams.mmc_cur = di->mmc_cur; - - /* - * UDF dictates first track to determine track mode for the whole - * disc. [UDF 1.50/6.10.1.1, UDF 1.50/6.10.2.1] - * To prevent problems with a `reserved' track in front we start with - * the 2nd track and if that is not valid, go for the 1st. - */ - mmc_writeparams.tracknr = 2; - mmc_writeparams.data_mode = MMC_DATAMODE_DEFAULT; /* XA disc */ - mmc_writeparams.track_mode = MMC_TRACKMODE_DEFAULT; /* data */ - - error = ioctl(fd, MMCSETUPWRITEPARAMS, &mmc_writeparams); - if (error) { - mmc_writeparams.tracknr = 1; - error = ioctl(fd, MMCSETUPWRITEPARAMS, &mmc_writeparams); - } - return error; -} - - -static void -udf_synchronise_caches(void) -{ - struct mmc_op mmc_op; - - bzero(&mmc_op, sizeof(struct mmc_op)); - mmc_op.operation = MMC_OP_SYNCHRONISECACHE; - - /* this device might not know this ioct, so just be ignorant */ - (void) ioctl(fd, MMCOP, &mmc_op); -} - -/* --------------------------------------------------------------------- */ - -static int -udf_prepare_disc(void) -{ - struct mmc_trackinfo ti; - struct mmc_op op; - int tracknr, error; - - /* If the last track is damaged, repair it */ - ti.tracknr = mmc_discinfo.last_track_last_session; - error = udf_update_trackinfo(&mmc_discinfo, &ti); - if (error) - return error; - - if (ti.flags & MMC_TRACKINFO_DAMAGED) { - /* - * Need to repair last track before anything can be done. - * this is an optional command, so ignore its error but report - * warning. - */ - memset(&op, 0, sizeof(op)); - op.operation = MMC_OP_REPAIRTRACK; - op.mmc_profile = mmc_discinfo.mmc_profile; - op.tracknr = ti.tracknr; - error = ioctl(fd, MMCOP, &op); - - if (error) - (void)printf("Drive can't explicitly repair last " - "damaged track, but it might autorepair\n"); - } - /* last track (if any) might not be damaged now, operations are ok now */ - - /* setup write parameters from discinfo */ - error = udf_setup_writeparams(&mmc_discinfo); - if (error) - return error; - - /* if the drive is not sequential, we're done */ - if ((mmc_discinfo.mmc_cur & MMC_CAP_SEQUENTIAL) == 0) - return 0; - -#ifdef notyet - /* if last track is not the reserved but an empty track, unreserve it */ - if (ti.flags & MMC_TRACKINFO_BLANK) { - if (ti.flags & MMC_TRACKINFO_RESERVED == 0) { - memset(&op, 0, sizeof(op)); - op.operation = MMC_OP_UNRESERVETRACK; - op.mmc_profile = mmc_discinfo.mmc_profile; - op.tracknr = ti.tracknr; - error = ioctl(fd, MMCOP, &op); - if (error) - return error; - - /* update discinfo since it changed by the operation */ - error = udf_update_discinfo(&mmc_discinfo); - if (error) - return error; - } - } -#endif - - /* close the last session if its still open */ - if (mmc_discinfo.last_session_state == MMC_STATE_INCOMPLETE) { - printf("Closing last open session if present\n"); - /* close all associated tracks */ - tracknr = mmc_discinfo.first_track_last_session; - while (tracknr <= mmc_discinfo.last_track_last_session) { - ti.tracknr = tracknr; - error = udf_update_trackinfo(&mmc_discinfo, &ti); - if (error) - return error; - printf("\tClosing open track %d\n", tracknr); - memset(&op, 0, sizeof(op)); - op.operation = MMC_OP_CLOSETRACK; - op.mmc_profile = mmc_discinfo.mmc_profile; - op.tracknr = tracknr; - error = ioctl(fd, MMCOP, &op); - if (error) - return error; - tracknr ++; - } - printf("Closing session\n"); - memset(&op, 0, sizeof(op)); - op.operation = MMC_OP_CLOSESESSION; - op.mmc_profile = mmc_discinfo.mmc_profile; - op.sessionnr = mmc_discinfo.num_sessions; - error = ioctl(fd, MMCOP, &op); - if (error) - return error; - - /* update discinfo since it changed by the operations */ - error = udf_update_discinfo(&mmc_discinfo); - if (error) - return error; - } - - if (format_flags & FORMAT_TRACK512) { - /* get last track again */ - ti.tracknr = mmc_discinfo.last_track_last_session; - error = udf_update_trackinfo(&mmc_discinfo, &ti); - if (error) - return error; - - /* Split up the space at 512 for iso cd9660 hooking */ - memset(&op, 0, sizeof(op)); - op.operation = MMC_OP_RESERVETRACK_NWA; /* UPTO nwa */ - op.mmc_profile = mmc_discinfo.mmc_profile; - op.extent = 512; /* size */ - error = ioctl(fd, MMCOP, &op); - if (error) - return error; - } - - return 0; -} - -/* --------------------------------------------------------------------- */ - -int -udf_surface_check(void) -{ - uint32_t loc, block_bytes; - uint32_t sector_size, blockingnr, bpos; - uint8_t *buffer; - int error, num_errors; - - sector_size = context.sector_size; - blockingnr = layout.blockingnr; - - block_bytes = layout.blockingnr * sector_size; - if ((buffer = malloc(block_bytes)) == NULL) - return ENOMEM; - - /* set all one to not kill Flash memory? */ - for (bpos = 0; bpos < block_bytes; bpos++) - buffer[bpos] = 0x00; - - printf("\nChecking disc surface : phase 1 - writing\n"); - num_errors = 0; - loc = layout.first_lba; - while (loc <= layout.last_lba) { - /* write blockingnr sectors */ - error = pwrite(fd, buffer, block_bytes, loc*sector_size); - printf(" %08d + %d (%02d %%)\r", loc, blockingnr, - (int)((100.0 * loc)/layout.last_lba)); - fflush(stdout); - if (error == -1) { - /* block is bad */ - printf("BAD block at %08d + %d \n", - loc, layout.blockingnr); - if ((error = udf_register_bad_block(loc))) { - free(buffer); - return error; - } - num_errors ++; - } - loc += layout.blockingnr; - } - - printf("\nChecking disc surface : phase 2 - reading\n"); - num_errors = 0; - loc = layout.first_lba; - while (loc <= layout.last_lba) { - /* read blockingnr sectors */ - error = pread(fd, buffer, block_bytes, loc*sector_size); - printf(" %08d + %d (%02d %%)\r", loc, blockingnr, - (int)((100.0 * loc)/layout.last_lba)); - fflush(stdout); - if (error == -1) { - /* block is bad */ - printf("BAD block at %08d + %d \n", - loc, layout.blockingnr); - if ((error = udf_register_bad_block(loc))) { - free(buffer); - return error; - } - num_errors ++; - } - loc += layout.blockingnr; - } - printf("Scan complete : %d bad blocks found\n", num_errors); - free(buffer); - - return 0; -} - - -/* --------------------------------------------------------------------- */ - -static int -udf_do_newfs(void) -{ - int error; - - error = udf_do_newfs_prefix(); - if (error) - return error; - error = udf_do_rootdir(); - if (error) - return error; - error = udf_do_newfs_postfix(); - - return error; -} - - - -/* --------------------------------------------------------------------- */ - -static void -usage(void) -{ - (void)fprintf(stderr, "Usage: %s [-cFM] [-L loglabel] " - "[-P discid] [-S sectorsize] [-s size] [-p perc] " - "[-t gmtoff] [-v min_udf] [-V max_udf] special\n", getprogname()); - exit(EXIT_FAILURE); -} - - -int -main(int argc, char **argv) -{ - struct tm *tm; - struct stat st; - time_t now; - off_t setsize; - char scrap[255], *colon; - int ch, req_enable, req_disable, force; - int error; - - setprogname(argv[0]); - - /* initialise */ - format_str = strdup(""); - req_enable = req_disable = 0; - format_flags = FORMAT_INVALID; - force = 0; - check_surface = 0; - setsize = 0; - imagefile_secsize = 512; /* minimum allowed sector size */ - emul_packetsize = 32; /* reasonable default */ - - srandom((unsigned long) time(NULL)); - udf_init_create_context(); - context.app_name = "*NetBSD newfs"; - context.app_version_main = APP_VERSION_MAIN; - context.app_version_sub = APP_VERSION_SUB; - context.impl_name = IMPL_NAME; - - /* minimum and maximum UDF versions we advise */ - context.min_udf = 0x201; - context.max_udf = 0x201; - - /* use user's time zone as default */ - (void)time(&now); - tm = localtime(&now); - context.gmtoff = tm->tm_gmtoff; - - /* process options */ - while ((ch = getopt(argc, argv, "cFL:Mp:P:s:S:B:t:v:V:")) != -1) { - switch (ch) { - case 'c' : - check_surface = 1; - break; - case 'F' : - force = 1; - break; - case 'L' : - if (context.logvol_name) free(context.logvol_name); - context.logvol_name = strdup(optarg); - break; - case 'M' : - req_disable |= FORMAT_META; - break; - case 'p' : - meta_perc = a_num(optarg, "meta_perc"); - /* limit to `sensible` values */ - meta_perc = MIN(meta_perc, 99); - meta_perc = MAX(meta_perc, 1); - meta_fract = (float) meta_perc/100.0; - break; - case 'v' : - context.min_udf = a_udf_version(optarg, "min_udf"); - if (context.min_udf > context.max_udf) - context.max_udf = context.min_udf; - break; - case 'V' : - context.max_udf = a_udf_version(optarg, "max_udf"); - if (context.min_udf > context.max_udf) - context.min_udf = context.max_udf; - break; - case 'P' : - /* check if there is a ':' in the name */ - if ((colon = strstr(optarg, ":"))) { - if (context.volset_name) - free(context.volset_name); - *colon = 0; - context.volset_name = strdup(optarg); - optarg = colon+1; - } - if (context.primary_name) - free(context.primary_name); - if ((strstr(optarg, ":"))) { - perror("primary name can't have ':' in its name"); - return EXIT_FAILURE; - } - context.primary_name = strdup(optarg); - break; - case 's' : - /* support for files, set file size */ - /* XXX support for formatting recordables on vnd/file? */ - if (dehumanize_number(optarg, &setsize) < 0) { - perror("can't parse size argument"); - return EXIT_FAILURE; - } - setsize = MAX(0, setsize); - break; - case 'S' : - imagefile_secsize = a_num(optarg, "secsize"); - imagefile_secsize = MAX(512, imagefile_secsize); - break; - case 'B' : - emul_packetsize = a_num(optarg, - "blockingnr, packetsize"); - emul_packetsize = MAX(emul_packetsize, 1); - emul_packetsize = MIN(emul_packetsize, 32); - break; - case 't' : - /* time zone overide */ - context.gmtoff = a_num(optarg, "gmtoff"); - break; - default : - usage(); - /* NOTREACHED */ - } - } - - if (optind + 1 != argc) - usage(); - - /* get device and directory specifier */ - dev = argv[optind]; - - /* open device */ - if ((fd = open(dev, O_RDWR, 0)) == -1) { - /* check if we need to create a file */ - fd = open(dev, O_RDONLY, 0); - if (fd > 0) { - perror("device is there but can't be opened for read/write"); - return EXIT_FAILURE; - } - if (!force) { - perror("can't open device"); - return EXIT_FAILURE; - } - if (setsize == 0) { - perror("need to create image file but no size specified"); - return EXIT_FAILURE; - } - /* need to create a file */ - fd = open(dev, O_RDWR | O_CREAT | O_TRUNC, 0777); - if (fd == -1) { - perror("can't create image file"); - return EXIT_FAILURE; - } - } - - /* stat the device */ - if (fstat(fd, &st) != 0) { - perror("can't stat the device"); - close(fd); - return EXIT_FAILURE; - } - - if (S_ISREG(st.st_mode)) { - if (setsize == 0) - setsize = st.st_size; - /* sanitise arguments */ - imagefile_secsize &= ~511; - setsize &= ~(imagefile_secsize-1); - - if (ftruncate(fd, setsize)) { - perror("can't resize file"); - return EXIT_FAILURE; - } - } - - /* formatting can only be done on raw devices */ - if (!S_ISREG(st.st_mode) && !S_ISCHR(st.st_mode)) { - printf("%s is not a raw device\n", dev); - close(fd); - return EXIT_FAILURE; - } - - /* just in case something went wrong, synchronise the drive's cache */ - udf_synchronise_caches(); - - /* get 'disc' information */ - error = udf_update_discinfo(&mmc_discinfo); - if (error) { - perror("can't retrieve discinfo"); - close(fd); - return EXIT_FAILURE; - } - - /* derive disc identifiers when not specified and check given */ - error = udf_proces_names(); - if (error) { - /* error message has been printed */ - close(fd); - return EXIT_FAILURE; - } - - /* derive newfs disc format from disc profile */ - error = udf_derive_format(req_enable, req_disable, force); - if (error) { - /* error message has been printed */ - close(fd); - return EXIT_FAILURE; - } - - udf_dump_discinfo(&mmc_discinfo); - printf("Formatting disc compatible with UDF version %x to %x\n\n", - context.min_udf, context.max_udf); - (void)snprintb(scrap, sizeof(scrap), FORMAT_FLAGBITS, - (uint64_t) format_flags); - printf("UDF properties %s\n", scrap); - printf("Volume set `%s'\n", context.volset_name); - printf("Primary volume `%s`\n", context.primary_name); - printf("Logical volume `%s`\n", context.logvol_name); - if (format_flags & FORMAT_META) - printf("Metadata percentage %d %%\n", meta_perc); - printf("\n"); - - /* prepare disc if nessisary (recordables mainly) */ - error = udf_prepare_disc(); - if (error) { - perror("preparing disc failed"); - close(fd); - return EXIT_FAILURE; - }; - - /* setup sector writeout queue's */ - TAILQ_INIT(&write_queue); - - /* perform the newfs itself */ - error = udf_do_newfs(); - if (!error) { - /* write out sectors */ - error = writeout_write_queue(); - } - - /* in any case, synchronise the drive's cache to prevent lockups */ - udf_synchronise_caches(); - - close(fd); - if (error) - return EXIT_FAILURE; - - return EXIT_SUCCESS; -} - -/* --------------------------------------------------------------------- */ - diff --git a/sbin/newfs_udf/newfs_udf.h b/sbin/newfs_udf/newfs_udf.h deleted file mode 100644 index 1c21a0b48..000000000 --- a/sbin/newfs_udf/newfs_udf.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2006, 2008, 2013 Reinoud Zandijk - * 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 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. - * - */ - -#ifndef _FS_UDF_NEWFS_UDF_H_ -#define _FS_UDF_NEWFS_UDF_H_ - -/* general settings */ -#define UDF_512_TRACK 0 /* NOT recommended */ -#define UDF_META_PERC 20 /* picked */ - -/* Identifying myself */ -#define APP_VERSION_MAIN 0 -#define APP_VERSION_SUB 5 -#define IMPL_NAME "*NetBSD userland UDF" - - -/* global variables describing disc and format requests */ -extern int fd; /* device: file descriptor */ -extern char *dev; /* device: name */ -extern struct mmc_discinfo mmc_discinfo;/* device: disc info */ - -extern char *format_str; /* format: string representation */ -extern int format_flags; /* format: attribute flags */ -extern int media_accesstype; /* derived from current mmc cap */ -extern int check_surface; /* for rewritables */ - -extern int wrtrack_skew; -extern int meta_perc; -extern float meta_fract; - - -/* shared structure between udf_create.c users */ -struct udf_create_context context; -struct udf_disclayout layout; - -/* prototypes */ -int udf_write_sector(void *sector, uint64_t location); -int udf_update_trackinfo(struct mmc_discinfo *di, struct mmc_trackinfo *ti); - -/* tmp */ -int writeout_write_queue(void); -int udf_surface_check(void); - -#endif /* _FS_UDF_UDF_WRITE_H_ */ diff --git a/sbin/newfs_udf/udf_create.c b/sbin/newfs_udf/udf_create.c deleted file mode 100644 index ef92874af..000000000 --- a/sbin/newfs_udf/udf_create.c +++ /dev/null @@ -1,2403 +0,0 @@ -/* $NetBSD: udf_create.c,v 1.25 2015/06/16 23:18:55 christos Exp $ */ - -/* - * Copyright (c) 2006, 2008 Reinoud Zandijk - * 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 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. - * - */ -#if HAVE_NBTOOL_CONFIG_H -#include "nbtool_config.h" -#endif - -#include -__RCSID("$NetBSD: udf_create.c,v 1.25 2015/06/16 23:18:55 christos Exp $"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "unicode.h" -#include "udf_create.h" - - -#if 0 -# ifndef DEBUG -# define DEBUG -# endif -#endif - -/* - * NOTE that there is some overlap between this code and the udf kernel fs. - * This is intentially though it might better be factored out one day. - */ - -void -udf_init_create_context(void) -{ - /* clear */ - memset(&context, 0, sizeof(struct udf_create_context)); - - /* fill with defaults currently known */ - context.dscrver = 3; - context.min_udf = 0x0102; - context.max_udf = 0x0260; - context.serialnum = 1; /* default */ - - context.gmtoff = 0; - context.sector_size = 512; /* minimum for UDF */ - - context.logvol_name = NULL; - context.primary_name = NULL; - context.volset_name = NULL; - context.fileset_name = NULL; - - /* most basic identification */ - context.app_name = "*NetBSD"; - context.app_version_main = 0; - context.app_version_sub = 0; - context.impl_name = "*NetBSD"; - - context.vds_seq = 0; /* first one starts with zero */ - - /* Minimum value of 16 : UDF 3.2.1.1, 3.3.3.4. */ - context.unique_id = 0x10; - - context.num_files = 0; - context.num_directories = 0; - - context.data_part = 0; - context.metadata_part = 0; - context.metadata_alloc_pos = 0; - context.data_alloc_pos = 0; -} - - -/* version can be specified as 0xabc or a.bc */ -static int -parse_udfversion(const char *pos, uint32_t *version) { - int hex = 0; - char c1, c2, c3, c4; - - *version = 0; - if (*pos == '0') { - pos++; - /* expect hex format */ - hex = 1; - if (*pos++ != 'x') - return 1; - } - - c1 = *pos++; - if (c1 < '0' || c1 > '9') - return 1; - c1 -= '0'; - - c2 = *pos++; - if (!hex) { - if (c2 != '.') - return 1; - c2 = *pos++; - } - if (c2 < '0' || c2 > '9') - return 1; - c2 -= '0'; - - c3 = *pos++; - if (c3 < '0' || c3 > '9') - return 1; - c3 -= '0'; - - c4 = *pos++; - if (c4 != 0) - return 1; - - *version = c1 * 0x100 + c2 * 0x10 + c3; - return 0; -} - - -/* parse a given string for an udf version */ -int -a_udf_version(const char *s, const char *id_type) -{ - uint32_t version; - - if (parse_udfversion(s, &version)) - errx(1, "unknown %s id %s; specify as hex or float", id_type, s); - return version; -} - - -static uint32_t -udf_space_bitmap_len(uint32_t part_size) -{ - return sizeof(struct space_bitmap_desc)-1 + - part_size/8; -} - - -static uint32_t -udf_bytes_to_sectors(uint64_t bytes) -{ - uint32_t sector_size = layout.sector_size; - return (bytes + sector_size -1) / sector_size; -} - - -int -udf_calculate_disc_layout(int format_flags, int min_udf, - uint32_t wrtrack_skew, - uint32_t first_lba, uint32_t last_lba, - uint32_t sector_size, uint32_t blockingnr, - uint32_t sparable_blocks, float meta_fract) -{ - uint64_t kbsize, bytes; - uint32_t sparable_blockingnr; - uint32_t align_blockingnr; - uint32_t pos, mpos; - - /* clear */ - memset(&layout, 0, sizeof(layout)); - - /* fill with parameters */ - layout.wrtrack_skew = wrtrack_skew; - layout.first_lba = first_lba; - layout.last_lba = last_lba; - layout.sector_size = sector_size; - layout.blockingnr = blockingnr; - layout.sparable_blocks = sparable_blocks; - - /* start disc layouting */ - - /* - * location of iso9660 vrs is defined as first sector AFTER 32kb, - * minimum `sector size' 2048 - */ - layout.iso9660_vrs = ((32*1024 + sector_size - 1) / sector_size) - + first_lba; - - /* anchor starts at specified offset in sectors */ - layout.anchors[0] = first_lba + 256; - if (format_flags & FORMAT_TRACK512) - layout.anchors[0] = first_lba + 512; - layout.anchors[1] = last_lba - 256; - layout.anchors[2] = last_lba; - - /* update workable space */ - first_lba = layout.anchors[0] + blockingnr; - last_lba = layout.anchors[1] - 1; - - /* XXX rest of anchor packet can be added to unallocated space descr */ - - /* reserve space for VRS and VRS copy and associated tables */ - layout.vds_size = MAX(16, blockingnr); /* UDF 2.2.3.1+2 */ - layout.vds1 = first_lba; - first_lba += layout.vds_size; /* next packet */ - - if (format_flags & FORMAT_SEQUENTIAL) { - /* for sequential, append them ASAP */ - layout.vds2 = first_lba; - first_lba += layout.vds_size; - } else { - layout.vds2 = layout.anchors[1] - layout.vds_size; - last_lba = layout.vds2 - 1; /* XXX -1 ?? */ - } - - /* reserve space for logvol integrity sequence */ - layout.lvis_size = MAX(8192/sector_size, 2 * blockingnr); - if (format_flags & FORMAT_VAT) - layout.lvis_size = 2; - if (format_flags & FORMAT_WORM) - layout.lvis_size = 64 * blockingnr; - - /* TODO skip bad blocks in LVID sequence; for now use f.e. */ -//first_lba+=128; - layout.lvis = first_lba; - first_lba += layout.lvis_size; - - /* initial guess of UDF partition size */ - layout.part_start_lba = first_lba; - layout.part_size_lba = last_lba - layout.part_start_lba; - - /* all non sequential media needs an unallocated space bitmap */ - layout.alloc_bitmap_dscr_size = 0; - if ((format_flags & (FORMAT_SEQUENTIAL | FORMAT_READONLY)) == 0) { - bytes = udf_space_bitmap_len(layout.part_size_lba); - layout.alloc_bitmap_dscr_size = udf_bytes_to_sectors(bytes); - - /* XXX freed space map when applicable */ - } - - /* - * Note that for (bug) compatibility with version UDF 2.00 (fixed in - * 2.01 and higher) the blocking size needs to be 32 sectors otherwise - * the drive's blockingnr. - */ - - sparable_blockingnr = blockingnr; - if (min_udf <= 0x200) - sparable_blockingnr = 32; - - align_blockingnr = blockingnr; - if (format_flags & (FORMAT_SPARABLE | FORMAT_META)) - align_blockingnr = sparable_blockingnr; - - layout.align_blockingnr = align_blockingnr; - layout.sparable_blockingnr = sparable_blockingnr; - - /* - * Align partition LBA space to blocking granularity. Not strickly - * nessisary for non sparables but safer for the VRS data since it is - * not updated sporadically - */ - - if ((format_flags & (FORMAT_SEQUENTIAL | FORMAT_READONLY)) == 0) { -#ifdef DEBUG - printf("Lost %d slack sectors at start\n", UDF_ROUNDUP( - first_lba - wrtrack_skew, align_blockingnr) - - (first_lba - wrtrack_skew)); - printf("Lost %d slack sectors at end\n", - (first_lba - wrtrack_skew) - UDF_ROUNDDOWN( - first_lba - wrtrack_skew, align_blockingnr)); -#endif - - first_lba = UDF_ROUNDUP( first_lba - wrtrack_skew, - align_blockingnr); - last_lba = UDF_ROUNDDOWN(last_lba - wrtrack_skew, - align_blockingnr); - } - - if ((format_flags & FORMAT_SPARABLE) == 0) - layout.sparable_blocks = 0; - - if (format_flags & FORMAT_SPARABLE) { - layout.sparable_area_size = - layout.sparable_blocks * sparable_blockingnr; - - /* a sparing table descriptor is a whole blockingnr sectors */ - layout.sparing_table_dscr_lbas = sparable_blockingnr; - - /* place the descriptors at the start and end of the area */ - layout.spt_1 = first_lba; - first_lba += layout.sparing_table_dscr_lbas; - - layout.spt_2 = last_lba - layout.sparing_table_dscr_lbas; - last_lba -= layout.sparing_table_dscr_lbas; - - /* allocate sparable section */ - layout.sparable_area = first_lba; - first_lba += layout.sparable_area_size; - } - - /* update guess of UDF partition size */ - layout.part_start_lba = first_lba; - layout.part_size_lba = last_lba - layout.part_start_lba; - - /* determine partition selection for data and metadata */ - context.data_part = 0; - context.metadata_part = context.data_part; - if ((format_flags & FORMAT_VAT) || (format_flags & FORMAT_META)) - context.metadata_part = context.data_part + 1; - - /* - * Pick fixed logical space sector numbers for main FSD, rootdir and - * unallocated space. The reason for this pre-allocation is that they - * are referenced in the volume descriptor sequence and hence can't be - * allocated later. - */ - pos = 0; - layout.unalloc_space = pos; - pos += layout.alloc_bitmap_dscr_size; - - /* claim metadata descriptors and partition space [UDF 2.2.10] */ - if (format_flags & FORMAT_META) { - /* note: all in backing partition space */ - layout.meta_file = pos++; - layout.meta_bitmap = pos++;; - layout.meta_mirror = layout.part_size_lba-1; - layout.meta_alignment = MAX(blockingnr, sparable_blockingnr); - layout.meta_blockingnr = MAX(layout.meta_alignment, 32); - - /* calculate our partition length and store in sectors */ - layout.meta_part_size_lba = layout.part_size_lba * meta_fract; - layout.meta_part_size_lba = MAX(layout.meta_part_size_lba, 32); - layout.meta_part_size_lba = - UDF_ROUNDDOWN(layout.meta_part_size_lba, layout.meta_blockingnr); - - /* calculate positions */ - bytes = udf_space_bitmap_len(layout.meta_part_size_lba); - layout.meta_bitmap_dscr_size = udf_bytes_to_sectors(bytes); - - layout.meta_bitmap_space = pos; - pos += layout.meta_bitmap_dscr_size; - - layout.meta_part_start_lba = UDF_ROUNDUP(pos, layout.meta_alignment); - } - - mpos = (context.metadata_part == context.data_part) ? pos : 0; - layout.fsd = mpos; mpos += 1; - layout.rootdir = mpos; mpos += 1; - layout.vat = mpos; mpos += 1; /* if present */ - -#if 0 - printf("Summary so far\n"); - printf("\tiso9660_vrs\t\t%d\n", layout.iso9660_vrs); - printf("\tanchor0\t\t\t%d\n", layout.anchors[0]); - printf("\tanchor1\t\t\t%d\n", layout.anchors[1]); - printf("\tanchor2\t\t\t%d\n", layout.anchors[2]); - printf("\tvds_size\t\t%d\n", layout.vds_size); - printf("\tvds1\t\t\t%d\n", layout.vds1); - printf("\tvds2\t\t\t%d\n", layout.vds2); - printf("\tlvis_size\t\t%d\n", layout.lvis_size); - printf("\tlvis\t\t\t%d\n", layout.lvis); - if (format_flags & FORMAT_SPARABLE) { - printf("\tsparable size\t\t%d\n", layout.sparable_area_size); - printf("\tsparable\t\t%d\n", layout.sparable_area); - } - printf("\tpartition start lba\t%d\n", layout.part_start_lba); - printf("\tpartition size\t\t%d KiB, %d MiB\n", - (layout.part_size_lba * sector_size) / 1024, - (layout.part_size_lba * sector_size) / (1024*1024)); - if ((format_flags & FORMAT_SEQUENTIAL) == 0) { - printf("\tpart bitmap start\t%d\n", layout.unalloc_space); - printf("\t\tfor %d lba\n", layout.alloc_bitmap_dscr_size); - } - if (format_flags & FORMAT_META) { - printf("\tmeta blockingnr\t\t%d\n", layout.meta_blockingnr); - printf("\tmeta alignment\t\t%d\n", layout.meta_alignment); - printf("\tmeta size\t\t%d KiB, %d MiB\n", - (layout.meta_part_size_lba * sector_size) / 1024, - (layout.meta_part_size_lba * sector_size) / (1024*1024)); - printf("\tmeta file\t\t%d\n", layout.meta_file); - printf("\tmeta mirror\t\t%d\n", layout.meta_mirror); - printf("\tmeta bitmap\t\t%d\n", layout.meta_bitmap); - printf("\tmeta bitmap start\t%d\n", layout.meta_bitmap_space); - printf("\t\tfor %d lba\n", layout.meta_bitmap_dscr_size); - printf("\tmeta space start\t%d\n", layout.meta_part_start_lba); - printf("\t\tfor %d lba\n", layout.meta_part_size_lba); - } - printf("\n"); -#endif - - kbsize = (uint64_t) last_lba * sector_size; - printf("Total space on this medium approx. " - "%"PRIu64" KiB, %"PRIu64" MiB\n", - kbsize/1024, kbsize/(1024*1024)); - kbsize = (uint64_t)(layout.part_size_lba - layout.alloc_bitmap_dscr_size - - layout.meta_bitmap_dscr_size) * sector_size; - printf("Free space on this volume approx. " - "%"PRIu64" KiB, %"PRIu64" MiB\n\n", - kbsize/1024, kbsize/(1024*1024)); - - return 0; -} - - -int -udf_validate_tag_sum(union dscrptr *dscr) -{ - struct desc_tag *tag = &dscr->tag; - uint8_t *pos, sum, cnt; - - /* calculate TAG header checksum */ - pos = (uint8_t *) tag; - sum = 0; - - for(cnt = 0; cnt < 16; cnt++) { - if (cnt != 4) sum += *pos; - pos++; - }; - tag->cksum = sum; /* 8 bit */ - - return 0; -} - - -/* assumes sector number of descriptor to be allready present */ -int -udf_validate_tag_and_crc_sums(union dscrptr *dscr) -{ - struct desc_tag *tag = &dscr->tag; - uint16_t crc; - - /* check payload CRC if applicable */ - if (udf_rw16(tag->desc_crc_len) > 0) { - crc = udf_cksum(((uint8_t *) tag) + UDF_DESC_TAG_LENGTH, - udf_rw16(tag->desc_crc_len)); - tag->desc_crc = udf_rw16(crc); - }; - - /* calculate TAG header checksum */ - return udf_validate_tag_sum(dscr); -} - - -void -udf_inittag(struct desc_tag *tag, int tagid, uint32_t loc) -{ - tag->id = udf_rw16(tagid); - tag->descriptor_ver = udf_rw16(context.dscrver); - tag->cksum = 0; - tag->reserved = 0; - tag->serial_num = udf_rw16(context.serialnum); - tag->tag_loc = udf_rw32(loc); -} - - -int -udf_create_anchor(int num) -{ - struct anchor_vdp *avdp; - uint32_t vds_extent_len = layout.vds_size * context.sector_size; - - if ((avdp = calloc(1, context.sector_size)) == NULL) - return ENOMEM; - - udf_inittag(&avdp->tag, TAGID_ANCHOR, layout.anchors[num]); - - avdp->main_vds_ex.loc = udf_rw32(layout.vds1); - avdp->main_vds_ex.len = udf_rw32(vds_extent_len); - - avdp->reserve_vds_ex.loc = udf_rw32(layout.vds2); - avdp->reserve_vds_ex.len = udf_rw32(vds_extent_len); - - /* CRC length for an anchor is 512 - tag length; defined in Ecma 167 */ - avdp->tag.desc_crc_len = udf_rw16(512-UDF_DESC_TAG_LENGTH); - - context.anchors[num] = avdp; - return 0; -} - - -void -udf_create_terminator(union dscrptr *dscr, uint32_t loc) -{ - memset(dscr, 0, context.sector_size); - udf_inittag(&dscr->tag, TAGID_TERM, loc); - - /* CRC length for an anchor is 512 - tag length; defined in Ecma 167 */ - dscr->tag.desc_crc_len = udf_rw16(512-UDF_DESC_TAG_LENGTH); -} - - -void -udf_osta_charset(struct charspec *charspec) -{ - memset(charspec, 0, sizeof(*charspec)); - charspec->type = 0; - strcpy((char *) charspec->inf, "OSTA Compressed Unicode"); -} - - -void -udf_encode_osta_id(char *osta_id, uint16_t len, char *text) -{ - uint16_t u16_name[1024]; - uint8_t *pos; - uint16_t *pos16; - - memset(osta_id, 0, len); - if (!text || (strlen(text) == 0)) return; - - memset(u16_name, 0, sizeof(uint16_t) * 1023); - - /* convert ascii to 16 bits unicode */ - pos = (uint8_t *) text; - pos16 = u16_name; - while (*pos) { - *pos16 = *pos; - pos++; pos16++; - }; - *pos16 = 0; - - udf_CompressUnicode(len, 8, (unicode_t *) u16_name, (byte *) osta_id); - - /* Ecma 167/7.2.13 states that length is recorded in the last byte */ - osta_id[len-1] = strlen(text)+1; -} - - -/* first call udf_set_regid and then the suffix */ -void -udf_set_regid(struct regid *regid, char const *name) -{ - memset(regid, 0, sizeof(*regid)); - regid->flags = 0; /* not dirty and not protected */ - strcpy((char *) regid->id, name); -} - - -void -udf_add_domain_regid(struct regid *regid) -{ - uint16_t *ver; - - ver = (uint16_t *) regid->id_suffix; - *ver = udf_rw16(context.min_udf); -} - - -void -udf_add_udf_regid(struct regid *regid) -{ - uint16_t *ver; - - ver = (uint16_t *) regid->id_suffix; - *ver = udf_rw16(context.min_udf); - - regid->id_suffix[2] = 4; /* unix */ - regid->id_suffix[3] = 8; /* NetBSD */ -} - - -void -udf_add_impl_regid(struct regid *regid) -{ - regid->id_suffix[0] = 4; /* unix */ - regid->id_suffix[1] = 8; /* NetBSD */ -} - - -void -udf_add_app_regid(struct regid *regid) -{ - regid->id_suffix[0] = context.app_version_main; - regid->id_suffix[1] = context.app_version_sub; -} - - -/* - * Fill in timestamp structure based on clock_gettime(). Time is reported back - * as a time_t accompanied with a nano second field. - * - * The husec, usec and csec could be relaxed in type. - */ -static void -udf_timespec_to_timestamp(struct timespec *timespec, struct timestamp *timestamp) -{ - struct tm tm; - uint64_t husec, usec, csec; - - memset(timestamp, 0, sizeof(*timestamp)); - gmtime_r(×pec->tv_sec, &tm); - - /* - * Time type and time zone : see ECMA 1/7.3, UDF 2., 2.1.4.1, 3.1.1. - * - * Lower 12 bits are two complement signed timezone offset if bit 12 - * (method 1) is clear. Otherwise if bit 12 is set, specify timezone - * offset to -2047 i.e. unsigned `zero' - */ - - /* set method 1 for CUT/GMT */ - timestamp->type_tz = udf_rw16((1<<12) + 0); - timestamp->year = udf_rw16(tm.tm_year + 1900); - timestamp->month = tm.tm_mon + 1; /* `tm' uses 0..11 for months */ - timestamp->day = tm.tm_mday; - timestamp->hour = tm.tm_hour; - timestamp->minute = tm.tm_min; - timestamp->second = tm.tm_sec; - - usec = (timespec->tv_nsec + 500) / 1000; /* round */ - husec = usec / 100; - usec -= husec * 100; /* only 0-99 in usec */ - csec = husec / 100; /* only 0-99 in csec */ - husec -= csec * 100; /* only 0-99 in husec */ - - /* in rare cases there is overflow in csec */ - csec = MIN(99, csec); - husec = MIN(99, husec); - usec = MIN(99, usec); - - timestamp->centisec = csec; - timestamp->hund_usec = husec; - timestamp->usec = usec; -} - - -void -udf_set_timestamp_now(struct timestamp *timestamp) -{ - struct timespec now; - -#ifdef CLOCK_REALTIME - (void)clock_gettime(CLOCK_REALTIME, &now); -#else - struct timeval time_of_day; - - (void)gettimeofday(&time_of_day, NULL); - now.tv_sec = time_of_day.tv_sec; - now.tv_nsec = time_of_day.tv_usec * 1000; -#endif - udf_timespec_to_timestamp(&now, timestamp); -} - - -/* some code copied from sys/fs/udf */ - -static void -udf_set_timestamp(struct timestamp *timestamp, time_t value) -{ - struct timespec t; - - memset(&t, 0, sizeof(struct timespec)); - t.tv_sec = value; - t.tv_nsec = 0; - udf_timespec_to_timestamp(&t, timestamp); -} - - -static uint32_t -unix_mode_to_udf_perm(mode_t mode) -{ - uint32_t perm; - - perm = ((mode & S_IRWXO) ); - perm |= ((mode & S_IRWXG) << 2); - perm |= ((mode & S_IRWXU) << 4); - perm |= ((mode & S_IWOTH) << 3); - perm |= ((mode & S_IWGRP) << 5); - perm |= ((mode & S_IWUSR) << 7); - - return perm; -} - -/* end of copied code */ - - -int -udf_create_primaryd(void) -{ - struct pri_vol_desc *pri; - uint16_t crclen; - - pri = calloc(1, context.sector_size); - if (pri == NULL) - return ENOMEM; - - memset(pri, 0, context.sector_size); - udf_inittag(&pri->tag, TAGID_PRI_VOL, /* loc */ 0); - pri->seq_num = udf_rw32(context.vds_seq); context.vds_seq++; - - pri->pvd_num = udf_rw32(0); /* default serial */ - udf_encode_osta_id(pri->vol_id, 32, context.primary_name); - - /* set defaults for single disc volumes as UDF prescribes */ - pri->vds_num = udf_rw16(1); - pri->max_vol_seq = udf_rw16(1); - pri->ichg_lvl = udf_rw16(2); - pri->max_ichg_lvl = udf_rw16(3); - pri->flags = udf_rw16(0); - - pri->charset_list = udf_rw32(1); /* only CS0 */ - pri->max_charset_list = udf_rw32(1); /* only CS0 */ - - udf_encode_osta_id(pri->volset_id, 128, context.volset_name); - udf_osta_charset(&pri->desc_charset); - udf_osta_charset(&pri->explanatory_charset); - - udf_set_regid(&pri->app_id, context.app_name); - udf_add_app_regid(&pri->app_id); - - udf_set_regid(&pri->imp_id, context.impl_name); - udf_add_impl_regid(&pri->imp_id); - - udf_set_timestamp_now(&pri->time); - - crclen = sizeof(struct pri_vol_desc) - UDF_DESC_TAG_LENGTH; - pri->tag.desc_crc_len = udf_rw16(crclen); - - context.primary_vol = pri; - - return 0; -} - - -/* XXX no support for unallocated or freed space tables yet (!) */ -int -udf_create_partitiond(int part_num, int part_accesstype) -{ - struct part_desc *pd; - struct part_hdr_desc *phd; - uint32_t sector_size, bitmap_bytes; - uint16_t crclen; - - sector_size = context.sector_size; - bitmap_bytes = layout.alloc_bitmap_dscr_size * sector_size; - - if (context.partitions[part_num]) { - printf("Internal error: partition %d allready defined\n", - part_num); - return EINVAL; - } - - pd = calloc(1, context.sector_size); - if (pd == NULL) - return ENOMEM; - phd = &pd->_impl_use.part_hdr; - - udf_inittag(&pd->tag, TAGID_PARTITION, /* loc */ 0); - pd->seq_num = udf_rw32(context.vds_seq); context.vds_seq++; - - pd->flags = udf_rw16(1); /* allocated */ - pd->part_num = udf_rw16(part_num); /* only one physical partition */ - - if (context.dscrver == 2) { - udf_set_regid(&pd->contents, "+NSR02"); - } else { - udf_set_regid(&pd->contents, "+NSR03"); - } - udf_add_app_regid(&pd->contents); - - phd->unalloc_space_bitmap.len = udf_rw32(bitmap_bytes); - phd->unalloc_space_bitmap.lb_num = udf_rw32(layout.unalloc_space); - - if (layout.freed_space) { - phd->freed_space_bitmap.len = udf_rw32(bitmap_bytes); - phd->freed_space_bitmap.lb_num = udf_rw32(layout.freed_space); - } - - pd->access_type = udf_rw32(part_accesstype); - pd->start_loc = udf_rw32(layout.part_start_lba); - pd->part_len = udf_rw32(layout.part_size_lba); - - udf_set_regid(&pd->imp_id, context.impl_name); - udf_add_impl_regid(&pd->imp_id); - - crclen = sizeof(struct part_desc) - UDF_DESC_TAG_LENGTH; - pd->tag.desc_crc_len = udf_rw16(crclen); - - context.partitions[part_num] = pd; - - return 0; -} - - -int -udf_create_unalloc_spaced(void) -{ - struct unalloc_sp_desc *usd; - uint16_t crclen; - - usd = calloc(1, context.sector_size); - if (usd == NULL) - return ENOMEM; - - udf_inittag(&usd->tag, TAGID_UNALLOC_SPACE, /* loc */ 0); - usd->seq_num = udf_rw32(context.vds_seq); context.vds_seq++; - - /* no default entries */ - usd->alloc_desc_num = udf_rw32(0); /* no entries */ - - crclen = sizeof(struct unalloc_sp_desc) - sizeof(struct extent_ad); - crclen -= UDF_DESC_TAG_LENGTH; - usd->tag.desc_crc_len = udf_rw16(crclen); - - context.unallocated = usd; - - return 0; -} - - -static int -udf_create_base_logical_dscr(void) -{ - struct logvol_desc *lvd; - uint32_t sector_size; - uint16_t crclen; - - sector_size = context.sector_size; - - lvd = calloc(1, sector_size); - if (lvd == NULL) - return ENOMEM; - - udf_inittag(&lvd->tag, TAGID_LOGVOL, /* loc */ 0); - lvd->seq_num = udf_rw32(context.vds_seq); context.vds_seq++; - - udf_osta_charset(&lvd->desc_charset); - udf_encode_osta_id(lvd->logvol_id, 128, context.logvol_name); - lvd->lb_size = udf_rw32(context.sector_size); - - udf_set_regid(&lvd->domain_id, "*OSTA UDF Compliant"); - udf_add_domain_regid(&lvd->domain_id); - - /* no partition mappings/entries yet */ - lvd->mt_l = udf_rw32(0); - lvd->n_pm = udf_rw32(0); - - udf_set_regid(&lvd->imp_id, context.impl_name); - udf_add_impl_regid(&lvd->imp_id); - - lvd->integrity_seq_loc.loc = udf_rw32(layout.lvis); - lvd->integrity_seq_loc.len = udf_rw32(layout.lvis_size * sector_size); - - /* just one fsd for now */ - lvd->lv_fsd_loc.len = udf_rw32(sector_size); - lvd->lv_fsd_loc.loc.part_num = udf_rw32(context.metadata_part); - lvd->lv_fsd_loc.loc.lb_num = udf_rw32(layout.fsd); - - crclen = sizeof(struct logvol_desc) - 1 - UDF_DESC_TAG_LENGTH; - lvd->tag.desc_crc_len = udf_rw16(crclen); - - context.logical_vol = lvd; - context.vtop_tp[UDF_VTOP_RAWPART] = UDF_VTOP_TYPE_RAW; - context.vtop_offset[UDF_VTOP_RAWPART] = 0; - - return 0; -} - - -static void -udf_add_logvol_part_physical(uint16_t phys_part) -{ - struct logvol_desc *logvol = context.logical_vol; - union udf_pmap *pmap; - uint8_t *pmap_pos; - uint16_t crclen; - uint32_t pmap1_size, log_part; - - log_part = udf_rw32(logvol->n_pm); - pmap_pos = logvol->maps + udf_rw32(logvol->mt_l); - pmap1_size = sizeof(struct part_map_1); - - pmap = (union udf_pmap *) pmap_pos; - pmap->pm1.type = 1; - pmap->pm1.len = sizeof(struct part_map_1); - pmap->pm1.vol_seq_num = udf_rw16(1); /* no multi-volume */ - pmap->pm1.part_num = udf_rw16(phys_part); - - context.vtop [log_part] = phys_part; - context.vtop_tp [log_part] = UDF_VTOP_TYPE_PHYS; - context.vtop_offset[log_part] = layout.part_start_lba; - context.part_size[log_part] = layout.part_size_lba; - context.part_free[log_part] = layout.part_size_lba; - - /* increment number of partitions and length */ - logvol->n_pm = udf_rw32(log_part + 1); - logvol->mt_l = udf_rw32(udf_rw32(logvol->mt_l) + pmap1_size); - - crclen = udf_rw16(logvol->tag.desc_crc_len) + pmap1_size; - logvol->tag.desc_crc_len = udf_rw16(crclen); -} - - -static void -udf_add_logvol_part_virtual(uint16_t phys_part) -{ - union udf_pmap *pmap; - struct logvol_desc *logvol = context.logical_vol; - uint8_t *pmap_pos; - uint16_t crclen; - uint32_t pmapv_size, log_part; - - log_part = udf_rw32(logvol->n_pm); - pmap_pos = logvol->maps + udf_rw32(logvol->mt_l); - pmapv_size = sizeof(struct part_map_2); - - pmap = (union udf_pmap *) pmap_pos; - pmap->pmv.type = 2; - pmap->pmv.len = pmapv_size; - - udf_set_regid(&pmap->pmv.id, "*UDF Virtual Partition"); - udf_add_udf_regid(&pmap->pmv.id); - - pmap->pmv.vol_seq_num = udf_rw16(1); /* no multi-volume */ - pmap->pmv.part_num = udf_rw16(phys_part); - - context.vtop [log_part] = phys_part; - context.vtop_tp [log_part] = UDF_VTOP_TYPE_VIRT; - context.vtop_offset[log_part] = context.vtop_offset[phys_part]; - context.part_size[log_part] = 0xffffffff; - context.part_free[log_part] = 0xffffffff; - - /* increment number of partitions and length */ - logvol->n_pm = udf_rw32(log_part + 1); - logvol->mt_l = udf_rw32(udf_rw32(logvol->mt_l) + pmapv_size); - - crclen = udf_rw16(logvol->tag.desc_crc_len) + pmapv_size; - logvol->tag.desc_crc_len = udf_rw16(crclen); -} - - -/* sparing table size is in bytes */ -static void -udf_add_logvol_part_sparable(uint16_t phys_part) -{ - union udf_pmap *pmap; - struct logvol_desc *logvol = context.logical_vol; - uint32_t *st_pos, sparable_bytes, pmaps_size; - uint8_t *pmap_pos, num; - uint16_t crclen; - uint32_t log_part; - - log_part = udf_rw32(logvol->n_pm); - pmap_pos = logvol->maps + udf_rw32(logvol->mt_l); - pmaps_size = sizeof(struct part_map_2); - sparable_bytes = layout.sparable_area_size * context.sector_size; - - pmap = (union udf_pmap *) pmap_pos; - pmap->pms.type = 2; - pmap->pms.len = pmaps_size; - - udf_set_regid(&pmap->pmv.id, "*UDF Sparable Partition"); - udf_add_udf_regid(&pmap->pmv.id); - - pmap->pms.vol_seq_num = udf_rw16(1); /* no multi-volume */ - pmap->pms.part_num = udf_rw16(phys_part); - - pmap->pms.packet_len = udf_rw16(layout.sparable_blockingnr); - pmap->pms.st_size = udf_rw32(sparable_bytes); - - /* enter spare tables */ - st_pos = &pmap->pms.st_loc[0]; - *st_pos++ = udf_rw32(layout.spt_1); - *st_pos++ = udf_rw32(layout.spt_2); - - num = 2; - if (layout.spt_2 == 0) num--; - if (layout.spt_1 == 0) num--; - pmap->pms.n_st = num; /* 8 bit */ - - /* the vtop_offset needs to explicitly set since there is no phys. */ - context.vtop [log_part] = phys_part; - context.vtop_tp [log_part] = UDF_VTOP_TYPE_SPARABLE; - context.vtop_offset[log_part] = layout.part_start_lba; - context.part_size[log_part] = layout.part_size_lba; - context.part_free[log_part] = layout.part_size_lba; - - /* increment number of partitions and length */ - logvol->n_pm = udf_rw32(log_part + 1); - logvol->mt_l = udf_rw32(udf_rw32(logvol->mt_l) + pmaps_size); - - crclen = udf_rw16(logvol->tag.desc_crc_len) + pmaps_size; - logvol->tag.desc_crc_len = udf_rw16(crclen); -} - - -int -udf_create_sparing_tabled(void) -{ - struct udf_sparing_table *spt; - struct spare_map_entry *sme; - uint32_t loc, cnt; - uint32_t crclen; /* XXX: should be 16; need to detect overflow */ - - spt = calloc(context.sector_size, layout.sparing_table_dscr_lbas); - if (spt == NULL) - return ENOMEM; - - /* a sparing table descriptor is a whole sparable_blockingnr sectors */ - udf_inittag(&spt->tag, TAGID_SPARING_TABLE, /* loc */ 0); - - udf_set_regid(&spt->id, "*UDF Sparing Table"); - udf_add_udf_regid(&spt->id); - - spt->rt_l = udf_rw16(layout.sparable_blocks); - spt->seq_num = udf_rw32(0); /* first generation */ - - for (cnt = 0; cnt < layout.sparable_blocks; cnt++) { - sme = &spt->entries[cnt]; - loc = layout.sparable_area + cnt * layout.sparable_blockingnr; - sme->org = udf_rw32(0xffffffff); /* open for reloc */ - sme->map = udf_rw32(loc); - } - - /* calculate crc len for actual size */ - crclen = sizeof(struct udf_sparing_table) - UDF_DESC_TAG_LENGTH; - crclen += (layout.sparable_blocks-1) * sizeof(struct spare_map_entry); -/* XXX ensure crclen doesn't exceed UINT16_MAX ? */ - spt->tag.desc_crc_len = udf_rw16((uint16_t)crclen); - - context.sparing_table = spt; - - return 0; -} - - -static void -udf_add_logvol_part_meta(uint16_t phys_part) -{ - union udf_pmap *pmap; - struct logvol_desc *logvol = context.logical_vol; - uint8_t *pmap_pos; - uint32_t pmapv_size, log_part; - uint16_t crclen; - - log_part = udf_rw32(logvol->n_pm); - pmap_pos = logvol->maps + udf_rw32(logvol->mt_l); - pmapv_size = sizeof(struct part_map_2); - - pmap = (union udf_pmap *) pmap_pos; - pmap->pmm.type = 2; - pmap->pmm.len = pmapv_size; - - udf_set_regid(&pmap->pmm.id, "*UDF Metadata Partition"); - udf_add_udf_regid(&pmap->pmm.id); - - pmap->pmm.vol_seq_num = udf_rw16(1); /* no multi-volume */ - pmap->pmm.part_num = udf_rw16(phys_part); - - /* fill in meta data file(s) and alloc/alignment unit sizes */ - pmap->pmm.meta_file_lbn = udf_rw32(layout.meta_file); - pmap->pmm.meta_mirror_file_lbn = udf_rw32(layout.meta_mirror); - pmap->pmm.meta_bitmap_file_lbn = udf_rw32(layout.meta_bitmap); - pmap->pmm.alloc_unit_size = udf_rw32(layout.meta_blockingnr); - pmap->pmm.alignment_unit_size = udf_rw16(layout.meta_alignment); - pmap->pmm.flags = 0; /* METADATA_DUPLICATED */ - - context.vtop [log_part] = phys_part; - context.vtop_tp [log_part] = UDF_VTOP_TYPE_META; - context.vtop_offset[log_part] = - context.vtop_offset[phys_part] + layout.meta_part_start_lba; - context.part_size[log_part] = layout.meta_part_size_lba; - context.part_free[log_part] = layout.meta_part_size_lba; - - /* increment number of partitions and length */ - logvol->n_pm = udf_rw32(log_part + 1); - logvol->mt_l = udf_rw32(udf_rw32(logvol->mt_l) + pmapv_size); - - crclen = udf_rw16(logvol->tag.desc_crc_len) + pmapv_size; - logvol->tag.desc_crc_len = udf_rw16(crclen); -} - - -int -udf_create_logical_dscr(int format_flags) -{ - int error; - - if ((error = udf_create_base_logical_dscr())) - return error; - - /* we pass data_part for there might be a read-only part one day */ - if (format_flags & FORMAT_SPARABLE) { - /* sparable partition mapping has no physical mapping */ - udf_add_logvol_part_sparable(context.data_part); - } else { - udf_add_logvol_part_physical(context.data_part); - } - - if (format_flags & FORMAT_VAT) { - /* add VAT virtual mapping; reflects on datapart */ - udf_add_logvol_part_virtual(context.data_part); - } - if (format_flags & FORMAT_META) { - /* add META data mapping; reflects on datapart */ - udf_add_logvol_part_meta(context.data_part); - } - - return 0; -} - - -int -udf_create_impvold(char *field1, char *field2, char *field3) -{ - struct impvol_desc *ivd; - struct udf_lv_info *lvi; - uint16_t crclen; - - ivd = calloc(1, context.sector_size); - if (ivd == NULL) - return ENOMEM; - lvi = &ivd->_impl_use.lv_info; - - udf_inittag(&ivd->tag, TAGID_IMP_VOL, /* loc */ 0); - ivd->seq_num = udf_rw32(context.vds_seq); context.vds_seq++; - - udf_set_regid(&ivd->impl_id, "*UDF LV Info"); - udf_add_udf_regid(&ivd->impl_id); - - /* fill in UDF specific part */ - udf_osta_charset(&lvi->lvi_charset); - udf_encode_osta_id(lvi->logvol_id, 128, context.logvol_name); - - udf_encode_osta_id(lvi->lvinfo1, 36, field1); - udf_encode_osta_id(lvi->lvinfo2, 36, field2); - udf_encode_osta_id(lvi->lvinfo3, 36, field3); - - udf_set_regid(&lvi->impl_id, context.impl_name); - udf_add_impl_regid(&lvi->impl_id); - - crclen = sizeof(struct impvol_desc) - UDF_DESC_TAG_LENGTH; - ivd->tag.desc_crc_len = udf_rw16(crclen); - - context.implementation = ivd; - - return 0; -} - - -/* XXX might need to be sanitised a bit later */ -void -udf_update_lvintd(int type) -{ - struct logvol_int_desc *lvid; - struct udf_logvol_info *lvinfo; - struct logvol_desc *logvol; - uint32_t *pos; - uint32_t cnt, l_iu, num_partmappings; - uint32_t crclen; /* XXX: should be 16; need to detect overflow */ - - lvid = context.logvol_integrity; - logvol = context.logical_vol; - - assert(lvid); - assert(logvol); - - lvid->integrity_type = udf_rw32(type); - - num_partmappings = udf_rw32(logvol->n_pm); - - udf_set_timestamp_now(&lvid->time); - - lvinfo = (struct udf_logvol_info *) - (lvid->tables + num_partmappings * 2); - udf_set_regid(&lvinfo->impl_id, context.impl_name); - udf_add_impl_regid(&lvinfo->impl_id); - - lvinfo->num_files = udf_rw32(context.num_files); - lvinfo->num_directories = udf_rw32(context.num_directories); - - lvid->lvint_next_unique_id = udf_rw64(context.unique_id); - - /* XXX sane enough ? */ - lvinfo->min_udf_readver = udf_rw16(context.min_udf); - lvinfo->min_udf_writever = udf_rw16(context.min_udf); - lvinfo->max_udf_writever = udf_rw16(context.max_udf); - - lvid->num_part = udf_rw32(num_partmappings); - - /* no impl. use needed */ - l_iu = sizeof(struct udf_logvol_info); - lvid->l_iu = udf_rw32(l_iu); - - pos = &lvid->tables[0]; - for (cnt = 0; cnt < num_partmappings; cnt++) { - *pos++ = udf_rw32(context.part_free[cnt]); - } - for (cnt = 0; cnt < num_partmappings; cnt++) { - *pos++ = udf_rw32(context.part_size[cnt]); - } - - crclen = sizeof(struct logvol_int_desc) -4 -UDF_DESC_TAG_LENGTH + l_iu; - crclen += num_partmappings * 2 * 4; -/* XXX ensure crclen doesn't exceed UINT16_MAX ? */ - lvid->tag.desc_crc_len = udf_rw16(crclen); - - context.logvol_info = lvinfo; -} - - -int -udf_create_lvintd(int type) -{ - struct logvol_int_desc *lvid; - - lvid = calloc(1, context.sector_size); - if (lvid == NULL) - return ENOMEM; - - udf_inittag(&lvid->tag, TAGID_LOGVOL_INTEGRITY, /* loc */ 0); - - context.logvol_integrity = lvid; - - udf_update_lvintd(type); - - return 0; -} - - -int -udf_create_fsd(void) -{ - struct fileset_desc *fsd; - uint16_t crclen; - - fsd = calloc(1, context.sector_size); - if (fsd == NULL) - return ENOMEM; - - udf_inittag(&fsd->tag, TAGID_FSD, /* loc */ 0); - - udf_set_timestamp_now(&fsd->time); - fsd->ichg_lvl = udf_rw16(3); /* UDF 2.3.2.1 */ - fsd->max_ichg_lvl = udf_rw16(3); /* UDF 2.3.2.2 */ - - fsd->charset_list = udf_rw32(1); /* only CS0 */ - fsd->max_charset_list = udf_rw32(1); /* only CS0 */ - - fsd->fileset_num = udf_rw32(0); /* only one fsd */ - fsd->fileset_desc_num = udf_rw32(0); /* origional */ - - udf_osta_charset(&fsd->logvol_id_charset); - udf_encode_osta_id(fsd->logvol_id, 128, context.logvol_name); - - udf_osta_charset(&fsd->fileset_charset); - udf_encode_osta_id(fsd->fileset_id, 32, context.fileset_name); - - /* copyright file and abstract file names obmitted */ - - fsd->rootdir_icb.len = udf_rw32(context.sector_size); - fsd->rootdir_icb.loc.lb_num = udf_rw32(layout.rootdir); - fsd->rootdir_icb.loc.part_num = udf_rw16(context.metadata_part); - - udf_set_regid(&fsd->domain_id, "*OSTA UDF Compliant"); - udf_add_domain_regid(&fsd->domain_id); - - /* next_ex stays zero */ - /* no system streamdirs yet */ - - crclen = sizeof(struct fileset_desc) - UDF_DESC_TAG_LENGTH; - fsd->tag.desc_crc_len = udf_rw16(crclen); - - context.fileset_desc = fsd; - - return 0; -} - - -int -udf_create_space_bitmap(uint32_t dscr_size, uint32_t part_size_lba, - struct space_bitmap_desc **sbdp) -{ - struct space_bitmap_desc *sbd; - uint32_t cnt; - uint16_t crclen; - - *sbdp = NULL; - sbd = calloc(context.sector_size, dscr_size); - if (sbd == NULL) - return ENOMEM; - - udf_inittag(&sbd->tag, TAGID_SPACE_BITMAP, /* loc */ 0); - - sbd->num_bits = udf_rw32(part_size_lba); - sbd->num_bytes = udf_rw32((part_size_lba + 7)/8); - - /* fill space with 0xff to indicate free */ - for (cnt = 0; cnt < udf_rw32(sbd->num_bytes); cnt++) - sbd->data[cnt] = 0xff; - - /* set crc to only cover the header (UDF 2.3.1.2, 2.3.8.1) */ - crclen = sizeof(struct space_bitmap_desc) -1 - UDF_DESC_TAG_LENGTH; - sbd->tag.desc_crc_len = udf_rw16(crclen); - - *sbdp = sbd; - return 0; -} - - -/* --------------------------------------------------------------------- */ - -int -udf_register_bad_block(uint32_t location) -{ - struct udf_sparing_table *spt; - struct spare_map_entry *sme, *free_sme; - uint32_t cnt; - - spt = context.sparing_table; - if (spt == NULL) { - printf("internal error: adding bad block to non sparable\n"); - return EINVAL; - } - - /* find us a free spare map entry */ - free_sme = NULL; - for (cnt = 0; cnt < layout.sparable_blocks; cnt++) { - sme = &spt->entries[cnt]; - /* if we are allready in it, bail out */ - if (udf_rw32(sme->org) == location) - return 0; - if (udf_rw32(sme->org) == 0xffffffff) { - free_sme = sme; - break; - } - } - if (free_sme == NULL) { - printf("Disc relocation blocks full; disc too damanged\n"); - return EINVAL; - } - free_sme->org = udf_rw32(location); - - return 0; -} - - -void -udf_mark_allocated(uint32_t start_lb, int partnr, uint32_t blocks) -{ - union dscrptr *dscr; - uint8_t *bpos; - uint32_t cnt, bit; - - /* account for space used on underlying partition */ - context.part_free[partnr] -= blocks; -#ifdef DEBUG - printf("mark allocated : partnr %d, start_lb %d for %d blocks\n", - partnr, start_lb, blocks); -#endif - - switch (context.vtop_tp[partnr]) { - case UDF_VTOP_TYPE_VIRT: - /* nothing */ - break; - case UDF_VTOP_TYPE_PHYS: - case UDF_VTOP_TYPE_SPARABLE: - case UDF_VTOP_TYPE_META: - if (context.part_unalloc_bits[context.vtop[partnr]] == NULL) { - context.part_free[partnr] = 0; - break; - } -#ifdef DEBUG - printf("Marking %d+%d as used\n", start_lb, blocks); -#endif - dscr = (union dscrptr *) (context.part_unalloc_bits[partnr]); - for (cnt = start_lb; cnt < start_lb + blocks; cnt++) { - bpos = &dscr->sbd.data[cnt / 8]; - bit = cnt % 8; - *bpos &= ~(1<< bit); - } - break; - default: - printf("internal error: reality check in mapping type %d\n", - context.vtop_tp[partnr]); - exit(EXIT_FAILURE); - } -} - - -void -udf_advance_uniqueid(void) -{ - /* Minimum value of 16 : UDF 3.2.1.1, 3.3.3.4. */ - context.unique_id++; - if (context.unique_id < 0x10) - context.unique_id = 0x10; -} - -/* --------------------------------------------------------------------- */ - -static void -unix_to_udf_name(char *result, uint8_t *result_len, - char const *name, int name_len, struct charspec *chsp) -{ - uint16_t *raw_name; - uint16_t *outchp; - const char *inchp; - const char *osta_id = "OSTA Compressed Unicode"; - int udf_chars, is_osta_typ0, bits; - size_t cnt; - - /* allocate temporary unicode-16 buffer */ - raw_name = malloc(1024); - assert(raw_name); - - /* convert utf8 to unicode-16 */ - *raw_name = 0; - inchp = name; - outchp = raw_name; - bits = 8; - for (cnt = name_len, udf_chars = 0; cnt;) { - *outchp = wget_utf8(&inchp, &cnt); - if (*outchp > 0xff) - bits=16; - outchp++; - udf_chars++; - } - /* null terminate just in case */ - *outchp++ = 0; - - is_osta_typ0 = (chsp->type == 0); - is_osta_typ0 &= (strcmp((char *) chsp->inf, osta_id) == 0); - if (is_osta_typ0) { - udf_chars = udf_CompressUnicode(udf_chars, bits, - (unicode_t *) raw_name, - (byte *) result); - } else { - printf("unix to udf name: no CHSP0 ?\n"); - /* XXX assume 8bit char length byte latin-1 */ - *result++ = 8; udf_chars = 1; - strncpy(result, name + 1, name_len); - udf_chars += name_len; - } - *result_len = udf_chars; - free(raw_name); -} - - -#define UDF_SYMLINKBUFLEN (64*1024) /* picked */ -int -udf_encode_symlink(uint8_t **pathbufp, uint32_t *pathlenp, char *target) -{ - struct charspec osta_charspec; - struct pathcomp pathcomp; - char *pathbuf, *pathpos, *compnamepos; -// char *mntonname; -// int mntonnamelen; - int pathlen, len, compnamelen; - int error; - - /* process `target' to an UDF structure */ - pathbuf = malloc(UDF_SYMLINKBUFLEN); - assert(pathbuf); - - *pathbufp = NULL; - *pathlenp = 0; - - pathpos = pathbuf; - pathlen = 0; - udf_osta_charset(&osta_charspec); - - if (*target == '/') { - /* symlink starts from the root */ - len = UDF_PATH_COMP_SIZE; - memset(&pathcomp, 0, len); - pathcomp.type = UDF_PATH_COMP_ROOT; - -#if 0 - /* XXX how to check for in makefs? */ - /* check if its mount-point relative! */ - mntonname = udf_node->ump->vfs_mountp->mnt_stat.f_mntonname; - mntonnamelen = strlen(mntonname); - if (strlen(target) >= mntonnamelen) { - if (strncmp(target, mntonname, mntonnamelen) == 0) { - pathcomp.type = UDF_PATH_COMP_MOUNTROOT; - target += mntonnamelen; - } - } else { - target++; - } -#else - target++; -#endif - - memcpy(pathpos, &pathcomp, len); - pathpos += len; - pathlen += len; - } - - error = 0; - while (*target) { - /* ignore multiple '/' */ - while (*target == '/') { - target++; - } - if (!*target) - break; - - /* extract component name */ - compnamelen = 0; - compnamepos = target; - while ((*target) && (*target != '/')) { - target++; - compnamelen++; - } - - /* just trunc if too long ?? (security issue) */ - if (compnamelen >= 127) { - error = ENAMETOOLONG; - break; - } - - /* convert unix name to UDF name */ - len = sizeof(struct pathcomp); - memset(&pathcomp, 0, len); - pathcomp.type = UDF_PATH_COMP_NAME; - len = UDF_PATH_COMP_SIZE; - - if ((compnamelen == 2) && (strncmp(compnamepos, "..", 2) == 0)) - pathcomp.type = UDF_PATH_COMP_PARENTDIR; - if ((compnamelen == 1) && (*compnamepos == '.')) - pathcomp.type = UDF_PATH_COMP_CURDIR; - - if (pathcomp.type == UDF_PATH_COMP_NAME) { - unix_to_udf_name( - (char *) &pathcomp.ident, &pathcomp.l_ci, - compnamepos, compnamelen, - &osta_charspec); - len = UDF_PATH_COMP_SIZE + pathcomp.l_ci; - } - - if (pathlen + len >= UDF_SYMLINKBUFLEN) { - error = ENAMETOOLONG; - break; - } - - memcpy(pathpos, &pathcomp, len); - pathpos += len; - pathlen += len; - } - - if (error) { - /* aparently too big */ - free(pathbuf); - return error; - } - - /* return status of symlink contents writeout */ - *pathbufp = (uint8_t *) pathbuf; - *pathlenp = pathlen; - - return 0; - -} -#undef UDF_SYMLINKBUFLEN - - -int -udf_fidsize(struct fileid_desc *fid) -{ - uint32_t size; - - if (udf_rw16(fid->tag.id) != TAGID_FID) - errx(EINVAL, "got udf_fidsize on non FID"); - - size = UDF_FID_SIZE + fid->l_fi + udf_rw16(fid->l_iu); - size = (size + 3) & ~3; - - return size; -} - - -int -udf_create_parentfid(struct fileid_desc *fid, struct long_ad *parent) -{ - /* the size of an empty FID is 38 but needs to be a multiple of 4 */ - int fidsize = 40; - - udf_inittag(&fid->tag, TAGID_FID, udf_rw32(parent->loc.lb_num)); - fid->file_version_num = udf_rw16(1); /* UDF 2.3.4.1 */ - fid->file_char = UDF_FILE_CHAR_DIR | UDF_FILE_CHAR_PAR; - fid->icb = *parent; - fid->icb.longad_uniqueid = parent->longad_uniqueid; - fid->tag.desc_crc_len = udf_rw16(fidsize - UDF_DESC_TAG_LENGTH); - - /* we have to do the fid here explicitly for simplicity */ - udf_validate_tag_and_crc_sums((union dscrptr *) fid); - - return fidsize; -} - - -void -udf_create_fid(uint32_t diroff, struct fileid_desc *fid, char *name, - int file_char, struct long_ad *ref) -{ - struct charspec osta_charspec; - uint32_t endfid; - uint32_t fidsize, lb_rest; - - memset(fid, 0, sizeof(*fid)); - udf_inittag(&fid->tag, TAGID_FID, udf_rw32(ref->loc.lb_num)); - fid->file_version_num = udf_rw16(1); /* UDF 2.3.4.1 */ - fid->file_char = file_char; - fid->l_iu = udf_rw16(0); - fid->icb = *ref; - fid->icb.longad_uniqueid = ref->longad_uniqueid; - - udf_osta_charset(&osta_charspec); - unix_to_udf_name((char *) fid->data, &fid->l_fi, name, strlen(name), - &osta_charspec); - - /* - * OK, tricky part: we need to pad so the next descriptor header won't - * cross the sector boundary - */ - endfid = diroff + udf_fidsize(fid); - lb_rest = context.sector_size - (endfid % context.sector_size); - if (lb_rest < sizeof(struct desc_tag)) { - /* add at least 32 */ - fid->l_iu = udf_rw16(32); - udf_set_regid((struct regid *) fid->data, context.impl_name); - udf_add_impl_regid((struct regid *) fid->data); - - unix_to_udf_name((char *) fid->data + udf_rw16(fid->l_iu), - &fid->l_fi, name, strlen(name), &osta_charspec); - } - - fidsize = udf_fidsize(fid); - fid->tag.desc_crc_len = udf_rw16(fidsize - UDF_DESC_TAG_LENGTH); - - /* make sure the header sums stays correct */ - udf_validate_tag_and_crc_sums((union dscrptr *)fid); -} - - -static void -udf_append_parentfid(union dscrptr *dscr, struct long_ad *parent_icb) -{ - struct file_entry *fe; - struct extfile_entry *efe; - struct fileid_desc *fid; - uint32_t l_ea; - uint32_t fidsize, crclen; - uint8_t *bpos, *data; - - fe = NULL; - efe = NULL; - if (udf_rw16(dscr->tag.id) == TAGID_FENTRY) { - fe = &dscr->fe; - data = fe->data; - l_ea = udf_rw32(fe->l_ea); - } else if (udf_rw16(dscr->tag.id) == TAGID_EXTFENTRY) { - efe = &dscr->efe; - data = efe->data; - l_ea = udf_rw32(efe->l_ea); - } else { - errx(1, "Bad tag passed to udf_append_parentfid"); - } - - /* create '..' */ - bpos = data + l_ea; - fid = (struct fileid_desc *) bpos; - fidsize = udf_create_parentfid(fid, parent_icb); - - /* record fidlength information */ - if (fe) { - fe->inf_len = udf_rw64(fidsize); - fe->l_ad = udf_rw32(fidsize); - fe->logblks_rec = udf_rw64(0); /* intern */ - crclen = sizeof(struct file_entry); - } else { - efe->inf_len = udf_rw64(fidsize); - efe->obj_size = udf_rw64(fidsize); - efe->l_ad = udf_rw32(fidsize); - efe->logblks_rec = udf_rw64(0); /* intern */ - crclen = sizeof(struct extfile_entry); - } - crclen -= 1 + UDF_DESC_TAG_LENGTH; - crclen += l_ea + fidsize; - dscr->tag.desc_crc_len = udf_rw16(crclen); - - /* make sure the header sums stays correct */ - udf_validate_tag_and_crc_sums(dscr); -} - - - -/* - * Order of extended attributes : - * ECMA 167 EAs - * Non block aligned Implementation Use EAs - * Block aligned Implementation Use EAs (not in newfs_udf) - * Application Use EAs (not in newfs_udf) - * - * no checks for doubles, must be called in-order - */ -static void -udf_extattr_append_internal(union dscrptr *dscr, struct extattr_entry *extattr) -{ - struct file_entry *fe; - struct extfile_entry *efe; - struct extattrhdr_desc *extattrhdr; - struct impl_extattr_entry *implext; - uint32_t impl_attr_loc, appl_attr_loc, l_ea, a_l, exthdr_len; - uint32_t *l_eap, l_ad; - uint16_t *spos; - uint8_t *bpos, *data; - - if (udf_rw16(dscr->tag.id) == TAGID_FENTRY) { - fe = &dscr->fe; - data = fe->data; - l_eap = &fe->l_ea; - l_ad = udf_rw32(fe->l_ad); - } else if (udf_rw16(dscr->tag.id) == TAGID_EXTFENTRY) { - efe = &dscr->efe; - data = efe->data; - l_eap = &efe->l_ea; - l_ad = udf_rw32(efe->l_ad); - } else { - errx(1, "Bad tag passed to udf_extattr_append_internal"); - } - - /* should have a header! */ - extattrhdr = (struct extattrhdr_desc *) data; - l_ea = udf_rw32(*l_eap); - if (l_ea == 0) { -#if !defined(NDEBUG) && defined(__minix) - assert(l_ad == 0); -#else - if (l_ad != 0) { - printf("%s:%d: l_ad != 0\n", __func__, __LINE__); - abort(); - } -#endif /* !defined(NDEBUG) && defined(__minix) */ - /* create empty extended attribute header */ - exthdr_len = sizeof(struct extattrhdr_desc); - - udf_inittag(&extattrhdr->tag, TAGID_EXTATTR_HDR, /* loc */ 0); - extattrhdr->impl_attr_loc = udf_rw32(exthdr_len); - extattrhdr->appl_attr_loc = udf_rw32(exthdr_len); - extattrhdr->tag.desc_crc_len = udf_rw16(8); - - /* record extended attribute header length */ - l_ea = exthdr_len; - *l_eap = udf_rw32(l_ea); - } - - /* extract locations */ - impl_attr_loc = udf_rw32(extattrhdr->impl_attr_loc); - appl_attr_loc = udf_rw32(extattrhdr->appl_attr_loc); - if (impl_attr_loc == UDF_IMPL_ATTR_LOC_NOT_PRESENT) - impl_attr_loc = l_ea; - if (appl_attr_loc == UDF_IMPL_ATTR_LOC_NOT_PRESENT) - appl_attr_loc = l_ea; - - /* Ecma 167 EAs */ - if (udf_rw32(extattr->type) < 2048) { - assert(impl_attr_loc == l_ea); - assert(appl_attr_loc == l_ea); - } - - /* implementation use extended attributes */ - if (udf_rw32(extattr->type) == 2048) { - assert(appl_attr_loc == l_ea); - - /* calculate and write extended attribute header checksum */ - implext = (struct impl_extattr_entry *) extattr; - assert(udf_rw32(implext->iu_l) == 4); /* [UDF 3.3.4.5] */ - spos = (uint16_t *) implext->data; - *spos = udf_rw16(udf_ea_cksum((uint8_t *) implext)); - } - - /* application use extended attributes */ - assert(udf_rw32(extattr->type) != 65536); - assert(appl_attr_loc == l_ea); - - /* append the attribute at the end of the current space */ - bpos = data + udf_rw32(*l_eap); - a_l = udf_rw32(extattr->a_l); - - /* update impl. attribute locations */ - if (udf_rw32(extattr->type) < 2048) { - impl_attr_loc = l_ea + a_l; - appl_attr_loc = l_ea + a_l; - } - if (udf_rw32(extattr->type) == 2048) { - appl_attr_loc = l_ea + a_l; - } - - /* copy and advance */ - memcpy(bpos, extattr, a_l); - l_ea += a_l; - *l_eap = udf_rw32(l_ea); - - /* do the `dance` again backwards */ - if (context.dscrver != 2) { - if (impl_attr_loc == l_ea) - impl_attr_loc = UDF_IMPL_ATTR_LOC_NOT_PRESENT; - if (appl_attr_loc == l_ea) - appl_attr_loc = UDF_APPL_ATTR_LOC_NOT_PRESENT; - } - - /* store offsets */ - extattrhdr->impl_attr_loc = udf_rw32(impl_attr_loc); - extattrhdr->appl_attr_loc = udf_rw32(appl_attr_loc); - - /* make sure the header sums stays correct */ - udf_validate_tag_and_crc_sums((union dscrptr *) extattrhdr); -} - - -int -udf_create_new_fe(struct file_entry **fep, int file_type, struct stat *st) -{ - struct file_entry *fe; - struct icb_tag *icb; - struct timestamp birthtime; - struct filetimes_extattr_entry *ft_extattr; - uint32_t crclen; /* XXX: should be 16; need to detect overflow */ - uint16_t icbflags; - - *fep = NULL; - fe = calloc(1, context.sector_size); - if (fe == NULL) - return ENOMEM; - - udf_inittag(&fe->tag, TAGID_FENTRY, /* loc */ 0); - icb = &fe->icbtag; - - /* - * Always use strategy type 4 unless on WORM wich we don't support - * (yet). Fill in defaults and set for internal allocation of data. - */ - icb->strat_type = udf_rw16(4); - icb->max_num_entries = udf_rw16(1); - icb->file_type = file_type; /* 8 bit */ - icb->flags = udf_rw16(UDF_ICB_INTERN_ALLOC); - - fe->perm = udf_rw32(0x7fff); /* all is allowed */ - fe->link_cnt = udf_rw16(0); /* explicit setting */ - - fe->ckpoint = udf_rw32(1); /* user supplied file version */ - - udf_set_timestamp_now(&birthtime); - udf_set_timestamp_now(&fe->atime); - udf_set_timestamp_now(&fe->attrtime); - udf_set_timestamp_now(&fe->mtime); - - /* set attributes */ - if (st) { -#if !HAVE_NBTOOL_CONFIG_H - udf_set_timestamp(&birthtime, st->st_birthtime); -#else - udf_set_timestamp(&birthtime, 0); -#endif - udf_set_timestamp(&fe->atime, st->st_atime); - udf_set_timestamp(&fe->attrtime, st->st_ctime); - udf_set_timestamp(&fe->mtime, st->st_mtime); - fe->uid = udf_rw32(st->st_uid); - fe->gid = udf_rw32(st->st_gid); - - fe->perm = unix_mode_to_udf_perm(st->st_mode); - - icbflags = udf_rw16(fe->icbtag.flags); - icbflags &= ~UDF_ICB_TAG_FLAGS_SETUID; - icbflags &= ~UDF_ICB_TAG_FLAGS_SETGID; - icbflags &= ~UDF_ICB_TAG_FLAGS_STICKY; - if (st->st_mode & S_ISUID) - icbflags |= UDF_ICB_TAG_FLAGS_SETUID; - if (st->st_mode & S_ISGID) - icbflags |= UDF_ICB_TAG_FLAGS_SETGID; - if (st->st_mode & S_ISVTX) - icbflags |= UDF_ICB_TAG_FLAGS_STICKY; - fe->icbtag.flags = udf_rw16(icbflags); - } - - udf_set_regid(&fe->imp_id, context.impl_name); - udf_add_impl_regid(&fe->imp_id); - fe->unique_id = udf_rw64(context.unique_id); - udf_advance_uniqueid(); - - fe->l_ea = udf_rw32(0); - - /* create extended attribute to record our creation time */ - ft_extattr = calloc(1, UDF_FILETIMES_ATTR_SIZE(1)); - ft_extattr->hdr.type = udf_rw32(UDF_FILETIMES_ATTR_NO); - ft_extattr->hdr.subtype = 1; /* [4/48.10.5] */ - ft_extattr->hdr.a_l = udf_rw32(UDF_FILETIMES_ATTR_SIZE(1)); - ft_extattr->d_l = udf_rw32(UDF_TIMESTAMP_SIZE); /* one item */ - ft_extattr->existence = UDF_FILETIMES_FILE_CREATION; - ft_extattr->times[0] = birthtime; - - udf_extattr_append_internal((union dscrptr *) fe, - (struct extattr_entry *) ft_extattr); - free(ft_extattr); - - /* record fidlength information */ - fe->inf_len = udf_rw64(0); - fe->l_ad = udf_rw32(0); - fe->logblks_rec = udf_rw64(0); /* intern */ - - crclen = sizeof(struct file_entry) - 1 - UDF_DESC_TAG_LENGTH; - crclen += udf_rw32(fe->l_ea); - - /* make sure the header sums stays correct */ - fe->tag.desc_crc_len = udf_rw16(crclen); - udf_validate_tag_and_crc_sums((union dscrptr *) fe); - - *fep = fe; - return 0; -} - - -int -udf_create_new_efe(struct extfile_entry **efep, int file_type, struct stat *st) -{ - struct extfile_entry *efe; - struct icb_tag *icb; - uint32_t crclen; /* XXX: should be 16; need to detect overflow */ - uint16_t icbflags; - - *efep = NULL; - efe = calloc(1, context.sector_size); - if (efe == NULL) - return ENOMEM; - - udf_inittag(&efe->tag, TAGID_EXTFENTRY, /* loc */ 0); - icb = &efe->icbtag; - - /* - * Always use strategy type 4 unless on WORM wich we don't support - * (yet). Fill in defaults and set for internal allocation of data. - */ - icb->strat_type = udf_rw16(4); - icb->max_num_entries = udf_rw16(1); - icb->file_type = file_type; /* 8 bit */ - icb->flags = udf_rw16(UDF_ICB_INTERN_ALLOC); - - efe->perm = udf_rw32(0x7fff); /* all is allowed */ - efe->link_cnt = udf_rw16(0); /* explicit setting */ - - efe->ckpoint = udf_rw32(1); /* user supplied file version */ - - udf_set_timestamp_now(&efe->ctime); - udf_set_timestamp_now(&efe->atime); - udf_set_timestamp_now(&efe->attrtime); - udf_set_timestamp_now(&efe->mtime); - - /* set attributes */ - if (st) { -#if !HAVE_NBTOOL_CONFIG_H - udf_set_timestamp(&efe->ctime, st->st_birthtime); -#else - udf_set_timestamp(&efe->ctime, 0); -#endif - udf_set_timestamp(&efe->atime, st->st_atime); - udf_set_timestamp(&efe->attrtime, st->st_ctime); - udf_set_timestamp(&efe->mtime, st->st_mtime); - efe->uid = udf_rw32(st->st_uid); - efe->gid = udf_rw32(st->st_gid); - - efe->perm = unix_mode_to_udf_perm(st->st_mode); - - icbflags = udf_rw16(efe->icbtag.flags); - icbflags &= ~UDF_ICB_TAG_FLAGS_SETUID; - icbflags &= ~UDF_ICB_TAG_FLAGS_SETGID; - icbflags &= ~UDF_ICB_TAG_FLAGS_STICKY; - if (st->st_mode & S_ISUID) - icbflags |= UDF_ICB_TAG_FLAGS_SETUID; - if (st->st_mode & S_ISGID) - icbflags |= UDF_ICB_TAG_FLAGS_SETGID; - if (st->st_mode & S_ISVTX) - icbflags |= UDF_ICB_TAG_FLAGS_STICKY; - efe->icbtag.flags = udf_rw16(icbflags); - } - - udf_set_regid(&efe->imp_id, context.impl_name); - udf_add_impl_regid(&efe->imp_id); - - efe->unique_id = udf_rw64(context.unique_id); - udf_advance_uniqueid(); - - /* record fidlength information */ - efe->inf_len = udf_rw64(0); - efe->obj_size = udf_rw64(0); - efe->l_ad = udf_rw32(0); - efe->logblks_rec = udf_rw64(0); - - crclen = sizeof(struct extfile_entry) - 1 - UDF_DESC_TAG_LENGTH; - - /* make sure the header sums stays correct */ - efe->tag.desc_crc_len = udf_rw16(crclen); - udf_validate_tag_and_crc_sums((union dscrptr *) efe); - - *efep = efe; - return 0; -} - -/* --------------------------------------------------------------------- */ - -/* for METADATA file appending only */ -static void -udf_append_meta_mapping_part_to_efe(struct extfile_entry *efe, - struct short_ad *mapping) -{ - struct icb_tag *icb; - uint64_t inf_len, obj_size, logblks_rec; - uint32_t l_ad, l_ea; - uint16_t crclen; - uint8_t *bpos; - - inf_len = udf_rw64(efe->inf_len); - obj_size = udf_rw64(efe->obj_size); - logblks_rec = udf_rw64(efe->logblks_rec); - l_ad = udf_rw32(efe->l_ad); - l_ea = udf_rw32(efe->l_ea); - crclen = udf_rw16(efe->tag.desc_crc_len); - icb = &efe->icbtag; - - /* set our allocation to shorts if not already done */ - icb->flags = udf_rw16(UDF_ICB_SHORT_ALLOC); - - /* append short_ad */ - bpos = (uint8_t *) efe->data + l_ea + l_ad; - memcpy(bpos, mapping, sizeof(struct short_ad)); - - l_ad += sizeof(struct short_ad); - crclen += sizeof(struct short_ad); - inf_len += UDF_EXT_LEN(udf_rw32(mapping->len)); - obj_size += UDF_EXT_LEN(udf_rw32(mapping->len)); - logblks_rec = UDF_ROUNDUP(inf_len, context.sector_size) / - context.sector_size; - - efe->l_ad = udf_rw32(l_ad); - efe->inf_len = udf_rw64(inf_len); - efe->obj_size = udf_rw64(obj_size); - efe->logblks_rec = udf_rw64(logblks_rec); - efe->tag.desc_crc_len = udf_rw16(crclen); -} - - -/* for METADATA file appending only */ -static void -udf_append_meta_mapping_to_efe(struct extfile_entry *efe, - uint16_t partnr, uint32_t lb_num, - uint64_t len) -{ - struct short_ad mapping; - uint64_t max_len, part_len; - - /* calculate max length meta allocation sizes */ - max_len = UDF_EXT_MAXLEN / context.sector_size; /* in sectors */ - max_len = (max_len / layout.meta_blockingnr) * layout.meta_blockingnr; - max_len = max_len * context.sector_size; - - memset(&mapping, 0, sizeof(mapping)); - while (len) { - part_len = MIN(len, max_len); - mapping.lb_num = udf_rw32(lb_num); - mapping.len = udf_rw32(part_len); - - udf_append_meta_mapping_part_to_efe(efe, &mapping); - - lb_num += part_len / context.sector_size; - len -= part_len; - } -} - - -int -udf_create_meta_files(void) -{ - struct extfile_entry *efe; - struct long_ad meta_icb; - uint64_t bytes; - uint32_t sector_size; - int filetype, error; - - sector_size = context.sector_size; - - memset(&meta_icb, 0, sizeof(meta_icb)); - meta_icb.len = udf_rw32(sector_size); - meta_icb.loc.part_num = udf_rw16(context.data_part); - - /* create metadata file */ - meta_icb.loc.lb_num = udf_rw32(layout.meta_file); - filetype = UDF_ICB_FILETYPE_META_MAIN; - error = udf_create_new_efe(&efe, filetype, NULL); - if (error) - return error; - context.meta_file = efe; - - /* create metadata mirror file */ - meta_icb.loc.lb_num = udf_rw32(layout.meta_mirror); - filetype = UDF_ICB_FILETYPE_META_MIRROR; - error = udf_create_new_efe(&efe, filetype, NULL); - if (error) - return error; - context.meta_mirror = efe; - - /* create metadata bitmap file */ - meta_icb.loc.lb_num = udf_rw32(layout.meta_bitmap); - filetype = UDF_ICB_FILETYPE_META_BITMAP; - error = udf_create_new_efe(&efe, filetype, NULL); - if (error) - return error; - context.meta_bitmap = efe; - - /* patch up files */ - context.meta_file->unique_id = udf_rw64(0); - context.meta_mirror->unique_id = udf_rw64(0); - context.meta_bitmap->unique_id = udf_rw64(0); - - /* restart unique id */ - context.unique_id = 0x10; - - /* XXX no support for metadata mirroring yet */ - /* insert extents */ - efe = context.meta_file; - udf_append_meta_mapping_to_efe(efe, context.data_part, - layout.meta_part_start_lba, - (uint64_t) layout.meta_part_size_lba * sector_size); - - efe = context.meta_mirror; - udf_append_meta_mapping_to_efe(efe, context.data_part, - layout.meta_part_start_lba, - (uint64_t) layout.meta_part_size_lba * sector_size); - - efe = context.meta_bitmap; - bytes = udf_space_bitmap_len(layout.meta_part_size_lba); - udf_append_meta_mapping_to_efe(efe, context.data_part, - layout.meta_bitmap_space, bytes); - - return 0; -} - - -/* --------------------------------------------------------------------- */ - -int -udf_create_new_rootdir(union dscrptr **dscr) -{ - struct file_entry *fe; - struct extfile_entry *efe; - struct long_ad root_icb; - int filetype, error; - -#if defined(__minix) - /* LSC: -Werror=maybe-uninitialized when compiling with -O3 */ - fe = NULL; -#endif /*defined(__minix) */ - memset(&root_icb, 0, sizeof(root_icb)); - root_icb.len = udf_rw32(context.sector_size); - root_icb.loc.lb_num = udf_rw32(layout.rootdir); - root_icb.loc.part_num = udf_rw16(context.metadata_part); - - filetype = UDF_ICB_FILETYPE_DIRECTORY; - if (context.dscrver == 2) { - error = udf_create_new_fe(&fe, filetype, NULL); - *dscr = (union dscrptr *) fe; - } else { - error = udf_create_new_efe(&efe, filetype, NULL); - *dscr = (union dscrptr *) efe; - } - if (error) - return error; - - /* append '..' */ - udf_append_parentfid(*dscr, &root_icb); - - /* rootdir has explicit only one link on creation; '..' is no link */ - if (context.dscrver == 2) { - fe->link_cnt = udf_rw16(1); - } else { - efe->link_cnt = udf_rw16(1); - } - - context.num_directories++; - assert(context.num_directories == 1); - - return 0; -} - - -void -udf_prepend_VAT_file(void) -{ - /* old style VAT has no prepend */ - if (context.dscrver == 2) { - context.vat_start = 0; - context.vat_size = 0; - return; - } - - context.vat_start = offsetof(struct udf_vat, data); - context.vat_size = offsetof(struct udf_vat, data); -} - - -void -udf_vat_update(uint32_t virt, uint32_t phys) -{ - uint32_t *vatpos; - uint32_t new_size; - - if (context.vtop_tp[context.metadata_part] != UDF_VTOP_TYPE_VIRT) - return; - - new_size = MAX(context.vat_size, - (context.vat_start + (virt+1)*sizeof(uint32_t))); - - if (new_size > context.vat_allocated) { - context.vat_allocated = - UDF_ROUNDUP(new_size, context.sector_size); - context.vat_contents = realloc(context.vat_contents, - context.vat_allocated); - assert(context.vat_contents); - /* XXX could also report error */ - } - vatpos = (uint32_t *) (context.vat_contents + context.vat_start); - vatpos[virt] = udf_rw32(phys); - - context.vat_size = MAX(context.vat_size, - (context.vat_start + (virt+1)*sizeof(uint32_t))); -} - - -int -udf_append_VAT_file(void) -{ - struct udf_oldvat_tail *oldvat_tail; - struct udf_vat *vathdr; - int32_t len_diff; - - /* new style VAT has VAT LVInt analog in front */ - if (context.dscrver == 3) { - /* set up VATv2 descriptor */ - vathdr = (struct udf_vat *) context.vat_contents; - vathdr->header_len = udf_rw16(sizeof(struct udf_vat) - 1); - vathdr->impl_use_len = udf_rw16(0); - memcpy(vathdr->logvol_id, context.logical_vol->logvol_id, 128); - vathdr->prev_vat = udf_rw32(UDF_NO_PREV_VAT); - vathdr->num_files = udf_rw32(context.num_files); - vathdr->num_directories = udf_rw32(context.num_directories); - - vathdr->min_udf_readver = udf_rw16(context.min_udf); - vathdr->min_udf_writever = udf_rw16(context.min_udf); - vathdr->max_udf_writever = udf_rw16(context.max_udf); - - return 0; - } - - /* old style VAT has identifier appended */ - - /* append "*UDF Virtual Alloc Tbl" id and prev. VAT location */ - len_diff = context.vat_allocated - context.vat_size; - assert(len_diff >= 0); - if (len_diff < (int32_t) sizeof(struct udf_oldvat_tail)) { - context.vat_allocated += context.sector_size; - context.vat_contents = realloc(context.vat_contents, - context.vat_allocated); - assert(context.vat_contents); - /* XXX could also report error */ - } - - oldvat_tail = (struct udf_oldvat_tail *) (context.vat_contents + - context.vat_size); - - udf_set_regid(&oldvat_tail->id, "*UDF Virtual Alloc Tbl"); - udf_add_udf_regid(&oldvat_tail->id); - oldvat_tail->prev_vat = udf_rw32(UDF_NO_PREV_VAT); - - context.vat_size += sizeof(struct udf_oldvat_tail); - - return 0; -} - - -int -udf_create_VAT(union dscrptr **vat_dscr) -{ - struct file_entry *fe; - struct extfile_entry *efe; - struct impl_extattr_entry *implext; - struct vatlvext_extattr_entry *vatlvext; - struct long_ad dataloc, *allocpos; - uint8_t *bpos, *extattr; - uint32_t ea_len, inf_len, vat_len, blks; - int filetype; - int error; - - assert((layout.rootdir < 2) && (layout.fsd < 2)); - - memset(&dataloc, 0, sizeof(dataloc)); - dataloc.len = udf_rw32(context.vat_size); - dataloc.loc.part_num = udf_rw16(context.data_part); - dataloc.loc.lb_num = udf_rw32(layout.vat); - - if (context.dscrver == 2) { - /* old style VAT */ - filetype = UDF_ICB_FILETYPE_UNKNOWN; - error = udf_create_new_fe(&fe, filetype, NULL); - if (error) - return error; - - /* append VAT LVExtension attribute */ - ea_len = sizeof(struct impl_extattr_entry) - 1 + - sizeof(struct vatlvext_extattr_entry) + 4; - - extattr = calloc(1, ea_len); - - implext = (struct impl_extattr_entry *) extattr; - implext->hdr.type = udf_rw32(2048); /* [4/48.10.8] */ - implext->hdr.subtype = 1; /* [4/48.10.8.2] */ - implext->hdr.a_l = udf_rw32(ea_len); /* VAT LVext EA size */ - /* use 4 bytes of imp use for UDF checksum [UDF 3.3.4.5] */ - implext->iu_l = udf_rw32(4); - udf_set_regid(&implext->imp_id, "*UDF VAT LVExtension"); - udf_add_udf_regid(&implext->imp_id); - - /* VAT LVExtension data follows UDF IU space */ - bpos = ((uint8_t *) implext->data) + 4; - vatlvext = (struct vatlvext_extattr_entry *) bpos; - - vatlvext->unique_id_chk = udf_rw64(fe->unique_id); - vatlvext->num_files = udf_rw32(context.num_files); - vatlvext->num_directories = udf_rw32(context.num_directories); - memcpy(vatlvext->logvol_id, context.logical_vol->logvol_id,128); - - udf_extattr_append_internal((union dscrptr *) fe, - (struct extattr_entry *) extattr); - - free(extattr); - - fe->icbtag.flags = udf_rw16(UDF_ICB_LONG_ALLOC); - - allocpos = (struct long_ad *) (fe->data + udf_rw32(fe->l_ea)); - *allocpos = dataloc; - - /* set length */ - inf_len = context.vat_size; - fe->inf_len = udf_rw64(inf_len); - fe->l_ad = udf_rw32(sizeof(struct long_ad)); - blks = UDF_ROUNDUP(inf_len, context.sector_size) / - context.sector_size; - fe->logblks_rec = udf_rw32(blks); - - /* update vat descriptor's CRC length */ - vat_len = sizeof(struct file_entry) - 1 - UDF_DESC_TAG_LENGTH; - vat_len += udf_rw32(fe->l_ad) + udf_rw32(fe->l_ea); - fe->tag.desc_crc_len = udf_rw16(vat_len); - - *vat_dscr = (union dscrptr *) fe; - } else { - /* new style VAT */ - filetype = UDF_ICB_FILETYPE_VAT; - error = udf_create_new_efe(&efe, filetype, NULL); - if (error) - return error; - - efe->icbtag.flags = udf_rw16(UDF_ICB_LONG_ALLOC); - - allocpos = (struct long_ad *) efe->data; - *allocpos = dataloc; - - /* set length */ - inf_len = context.vat_size; - efe->inf_len = udf_rw64(inf_len); - efe->obj_size = udf_rw64(inf_len); - efe->l_ad = udf_rw32(sizeof(struct long_ad)); - blks = UDF_ROUNDUP(inf_len, context.sector_size) / - context.sector_size; - efe->logblks_rec = udf_rw32(blks); - - vat_len = sizeof(struct extfile_entry)-1 - UDF_DESC_TAG_LENGTH; - vat_len += udf_rw32(efe->l_ad); - efe->tag.desc_crc_len = udf_rw16(vat_len); - - *vat_dscr = (union dscrptr *) efe; - } - - return 0; -} - diff --git a/sbin/newfs_udf/udf_create.h b/sbin/newfs_udf/udf_create.h deleted file mode 100644 index 001d64eec..000000000 --- a/sbin/newfs_udf/udf_create.h +++ /dev/null @@ -1,283 +0,0 @@ -/* $NetBSD: udf_create.h,v 1.7 2013/08/09 15:11:08 reinoud Exp $ */ - -/* - * Copyright (c) 2006, 2008 Reinoud Zandijk - * 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 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. - * - */ - -#ifndef _FS_UDF_UDF_CREATE_H_ -#define _FS_UDF_UDF_CREATE_H_ - -#include -#include -#if !HAVE_NBTOOL_CONFIG_H -#include -#else -#include "../../sys/fs/udf/ecma167-udf.h" -#endif -#include "udf_bswap.h" -#include "udf_osta.h" - - -/* format flags indicating properties of disc to create */ -#define FORMAT_WRITEONCE 0x00001 -#define FORMAT_SEQUENTIAL 0x00002 -#define FORMAT_REWRITABLE 0x00004 -#define FORMAT_SPARABLE 0x00008 -#define FORMAT_META 0x00010 -#define FORMAT_LOW 0x00020 -#define FORMAT_VAT 0x00040 -#define FORMAT_WORM 0x00080 -#define FORMAT_TRACK512 0x00100 -#define FORMAT_INVALID 0x00200 -#define FORMAT_READONLY 0x00400 -#define FORMAT_FLAGBITS \ - "\10\1WRITEONCE\2SEQUENTIAL\3REWRITABLE\4SPARABLE\5META\6LOW" \ - "\7VAT\10WORM\11TRACK512\12INVALID\13READONLY" - - -/* structure space */ -#define UDF_ANCHORS 4 /* 256, 512, N-256, N */ -#define UDF_PARTITIONS 4 /* overkill */ -#define UDF_PMAPS 4 /* overkill */ - -/* misc constants */ -#define UDF_MAX_NAMELEN 255 /* as per SPEC */ - -/* translation constants */ -#define UDF_VTOP_RAWPART UDF_PMAPS /* [0..UDF_PMAPS> are normal */ - -/* virtual to physical mapping types */ -#define UDF_VTOP_TYPE_RAW 0 -#define UDF_VTOP_TYPE_UNKNOWN 0 -#define UDF_VTOP_TYPE_PHYS 1 -#define UDF_VTOP_TYPE_VIRT 2 -#define UDF_VTOP_TYPE_SPARABLE 3 -#define UDF_VTOP_TYPE_META 4 - -#define UDF_TRANS_ZERO ((uint64_t) -1) -#define UDF_TRANS_UNMAPPED ((uint64_t) -2) -#define UDF_TRANS_INTERN ((uint64_t) -3) -#define UDF_MAX_SECTOR ((uint64_t) -10) /* high water mark */ - -/* handys */ -#define UDF_ROUNDUP(val, gran) \ - ((uint64_t) (gran) * (((uint64_t)(val) + (gran)-1) / (gran))) - -#define UDF_ROUNDDOWN(val, gran) \ - ((uint64_t) (gran) * (((uint64_t)(val)) / (gran))) - - -/* disc offsets for various structures and their sizes */ -struct udf_disclayout { - uint32_t wrtrack_skew; - - uint32_t iso9660_vrs; - uint32_t anchors[UDF_ANCHORS]; - uint32_t vds_size, vds1, vds2; - uint32_t lvis_size, lvis; - - uint32_t first_lba, last_lba; - uint32_t sector_size; - uint32_t blockingnr, align_blockingnr, sparable_blockingnr; - uint32_t meta_blockingnr, meta_alignment; - - /* sparables */ - uint32_t sparable_blocks; - uint32_t sparable_area, sparable_area_size; - uint32_t sparing_table_dscr_lbas; - uint32_t spt_1, spt_2; - - /* bitmaps */ - uint32_t alloc_bitmap_dscr_size; - uint32_t unalloc_space, freed_space; - - uint32_t meta_bitmap_dscr_size; - uint32_t meta_bitmap_space; - - /* metadata partition */ - uint32_t meta_file, meta_mirror, meta_bitmap; - uint32_t meta_part_start_lba, meta_part_size_lba; - - /* main partition */ - uint32_t part_start_lba, part_size_lba; - - uint32_t fsd, rootdir, vat; - -}; - - -/* all info about discs and descriptors building */ -struct udf_create_context { - /* descriptors */ - int dscrver; /* 2 or 3 */ - int min_udf; /* hex */ - int max_udf; /* hex */ - int serialnum; /* format serialno */ - - int gmtoff; /* in minutes */ - - /* XXX to layout? */ - uint32_t sector_size; - - /* identification */ - char *logvol_name; - char *primary_name; - char *volset_name; - char *fileset_name; - - char const *app_name; - char const *impl_name; - int app_version_main; - int app_version_sub; - - /* building */ - int vds_seq; /* for building functions */ - int unique_id; /* only first few are used */ - - /* constructed structures */ - struct anchor_vdp *anchors[UDF_ANCHORS]; /* anchors to VDS */ - struct pri_vol_desc *primary_vol; /* identification */ - struct logvol_desc *logical_vol; /* main mapping v->p */ - struct unalloc_sp_desc *unallocated; /* free UDF space */ - struct impvol_desc *implementation; /* likely reduntant */ - struct logvol_int_desc *logvol_integrity; /* current integrity */ - struct part_desc *partitions[UDF_PARTITIONS]; /* partitions */ - - /* XXX to layout? */ - int data_part; - int metadata_part; - - /* block numbers as offset in partition */ - uint32_t metadata_alloc_pos; - uint32_t data_alloc_pos; - - /* derived; points *into* other structures */ - struct udf_logvol_info *logvol_info; /* inside integrity */ - - /* fileset and root directories */ - struct fileset_desc *fileset_desc; /* normally one */ - - /* logical to physical translations */ - int vtop[UDF_PMAPS+1]; /* vpartnr trans */ - int vtop_tp[UDF_PMAPS+1]; /* type of trans */ - uint64_t vtop_offset[UDF_PMAPS+1]; /* offset in lb */ - - /* sparable */ - struct udf_sparing_table*sparing_table; /* replacements */ - - /* VAT file */ - uint32_t vat_size; /* length */ - uint32_t vat_allocated; /* allocated length */ - uint32_t vat_start; /* offset 1st entry */ - uint8_t *vat_contents; /* the VAT */ - - /* meta data partition */ - struct extfile_entry *meta_file; - struct extfile_entry *meta_mirror; - struct extfile_entry *meta_bitmap; - - /* lvint */ - int num_files; - int num_directories; - uint32_t part_size[UDF_PARTITIONS]; - uint32_t part_free[UDF_PARTITIONS]; - - struct space_bitmap_desc*part_unalloc_bits[UDF_PARTITIONS]; - struct space_bitmap_desc*part_freed_bits [UDF_PARTITIONS]; -}; - - -/* globals */ - -extern struct udf_create_context context; -extern struct udf_disclayout layout; - -/* prototypes */ -void udf_init_create_context(void); -int a_udf_version(const char *s, const char *id_type); - -int udf_calculate_disc_layout(int format_flags, int min_udf, - uint32_t wrtrack_skew, - uint32_t first_lba, uint32_t last_lba, - uint32_t sector_size, uint32_t blockingnr, - uint32_t sparable_blocks, - float meta_fract); - -void udf_osta_charset(struct charspec *charspec); -void udf_encode_osta_id(char *osta_id, uint16_t len, char *text); - -void udf_set_regid(struct regid *regid, char const *name); -void udf_add_domain_regid(struct regid *regid); -void udf_add_udf_regid(struct regid *regid); -void udf_add_impl_regid(struct regid *regid); -void udf_add_app_regid(struct regid *regid); - -int udf_validate_tag_sum(union dscrptr *dscr); -int udf_validate_tag_and_crc_sums(union dscrptr *dscr); - -void udf_set_timestamp_now(struct timestamp *timestamp); - -void udf_inittag(struct desc_tag *tag, int tagid, uint32_t loc); -int udf_create_anchor(int num); - -void udf_create_terminator(union dscrptr *dscr, uint32_t loc); -int udf_create_primaryd(void); -int udf_create_partitiond(int part_num, int part_accesstype); -int udf_create_unalloc_spaced(void); -int udf_create_sparing_tabled(void); -int udf_create_space_bitmap(uint32_t dscr_size, uint32_t part_size_lba, - struct space_bitmap_desc **sbdp); -int udf_create_logical_dscr(int format_flags); -int udf_create_impvold(char *field1, char *field2, char *field3); -int udf_create_fsd(void); -int udf_create_lvintd(int type); -void udf_update_lvintd(int type); - -int udf_register_bad_block(uint32_t location); -void udf_mark_allocated(uint32_t start_lb, int partnr, uint32_t blocks); - -int udf_create_new_fe(struct file_entry **fep, int file_type, - struct stat *st); -int udf_create_new_efe(struct extfile_entry **efep, int file_type, - struct stat *st); - -int udf_encode_symlink(uint8_t **pathbufp, uint32_t *pathlenp, char *target); - -void udf_advance_uniqueid(void); -int udf_fidsize(struct fileid_desc *fid); -void udf_create_fid(uint32_t diroff, struct fileid_desc *fid, - char *name, int namelen, struct long_ad *ref); -int udf_create_parentfid(struct fileid_desc *fid, struct long_ad *parent); - -int udf_create_meta_files(void); -int udf_create_new_rootdir(union dscrptr **dscr); - -int udf_create_VAT(union dscrptr **vat_dscr); -void udf_prepend_VAT_file(void); -void udf_vat_update(uint32_t virt, uint32_t phys); -int udf_append_VAT_file(void); - -#endif /* _FS_UDF_UDF_CREATE_H_ */ - diff --git a/sbin/newfs_udf/udf_write.c b/sbin/newfs_udf/udf_write.c deleted file mode 100644 index b287eaa82..000000000 --- a/sbin/newfs_udf/udf_write.c +++ /dev/null @@ -1,908 +0,0 @@ -/* $NetBSD: udf_write.c,v 1.9 2015/01/02 21:01:12 reinoud Exp $ */ - -/* - * Copyright (c) 2006, 2008, 2013 Reinoud Zandijk - * 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 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. - * - */ -#if HAVE_NBTOOL_CONFIG_H -#include "nbtool_config.h" -#endif - -#include -__RCSID("$NetBSD: udf_write.c,v 1.9 2015/01/02 21:01:12 reinoud Exp $"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if !HAVE_NBTOOL_CONFIG_H -#define _EXPOSE_MMC -#include -#else -#include "udf/cdio_mmc_structs.h" -#endif - -#include "udf_create.h" -#include "udf_write.h" -#include "newfs_udf.h" - - -union dscrptr *terminator_dscr; - -static int -udf_write_phys(void *blob, uint32_t location, uint32_t sects) -{ - uint32_t phys, cnt; - uint8_t *bpos; - int error; - - for (cnt = 0; cnt < sects; cnt++) { - bpos = (uint8_t *) blob; - bpos += context.sector_size * cnt; - - phys = location + cnt; - error = udf_write_sector(bpos, phys); - if (error) - return error; - } - return 0; -} - - -static int -udf_write_dscr_phys(union dscrptr *dscr, uint32_t location, - uint32_t sects) -{ - dscr->tag.tag_loc = udf_rw32(location); - (void) udf_validate_tag_and_crc_sums(dscr); - - return udf_write_phys(dscr, location, sects); -} - - -int -udf_write_dscr_virt(union dscrptr *dscr, uint32_t location, uint32_t vpart, - uint32_t sects) -{ - struct file_entry *fe; - struct extfile_entry *efe; - struct extattrhdr_desc *extattrhdr; - uint32_t phys; - - extattrhdr = NULL; - if (udf_rw16(dscr->tag.id) == TAGID_FENTRY) { - fe = (struct file_entry *) dscr; - if (udf_rw32(fe->l_ea) > 0) - extattrhdr = (struct extattrhdr_desc *) fe->data; - } - if (udf_rw16(dscr->tag.id) == TAGID_EXTFENTRY) { - efe = (struct extfile_entry *) dscr; - if (udf_rw32(efe->l_ea) > 0) - extattrhdr = (struct extattrhdr_desc *) efe->data; - } - if (extattrhdr) { - extattrhdr->tag.tag_loc = udf_rw32(location); - udf_validate_tag_and_crc_sums((union dscrptr *) extattrhdr); - } - - dscr->tag.tag_loc = udf_rw32(location); - udf_validate_tag_and_crc_sums(dscr); - - /* determine physical location */ - phys = context.vtop_offset[vpart]; - if (context.vtop_tp[vpart] == UDF_VTOP_TYPE_VIRT) { - udf_vat_update(location, context.data_alloc_pos); - phys += context.data_alloc_pos++; - } else { - phys += location; - } - - return udf_write_phys(dscr, phys, sects); -} - - -void -udf_metadata_alloc(int nblk, struct long_ad *pos) -{ - memset(pos, 0, sizeof(*pos)); - pos->len = udf_rw32(nblk * context.sector_size); - pos->loc.lb_num = udf_rw32(context.metadata_alloc_pos); - pos->loc.part_num = udf_rw16(context.metadata_part); - - udf_mark_allocated(context.metadata_alloc_pos, context.metadata_part, - nblk); - - context.metadata_alloc_pos += nblk; - if (context.metadata_part == context.data_part) - context.data_alloc_pos = context.metadata_alloc_pos; -} - - -void -udf_data_alloc(int nblk, struct long_ad *pos) -{ - memset(pos, 0, sizeof(*pos)); - pos->len = udf_rw32(nblk * context.sector_size); - pos->loc.lb_num = udf_rw32(context.data_alloc_pos); - pos->loc.part_num = udf_rw16(context.data_part); - - udf_mark_allocated(context.data_alloc_pos, context.data_part, nblk); - context.data_alloc_pos += nblk; - if (context.metadata_part == context.data_part) - context.metadata_alloc_pos = context.data_alloc_pos; -} - - - -/* --------------------------------------------------------------------- */ - -/* - * udf_derive_format derives the format_flags from the disc's mmc_discinfo. - * The resulting flags uniquely define a disc format. Note there are at least - * 7 distinct format types defined in UDF. - */ - -#define UDF_VERSION(a) \ - (((a) == 0x100) || ((a) == 0x102) || ((a) == 0x150) || ((a) == 0x200) || \ - ((a) == 0x201) || ((a) == 0x250) || ((a) == 0x260)) - -int -udf_derive_format(int req_enable, int req_disable, int force) -{ - /* disc writability, formatted, appendable */ - if ((mmc_discinfo.mmc_cur & MMC_CAP_RECORDABLE) == 0) { - (void)printf("Can't newfs readonly device\n"); - return EROFS; - } - if (mmc_discinfo.mmc_cur & MMC_CAP_SEQUENTIAL) { - /* sequentials need sessions appended */ - if (mmc_discinfo.disc_state == MMC_STATE_CLOSED) { - (void)printf("Can't append session to a closed disc\n"); - return EROFS; - } - if ((mmc_discinfo.disc_state != MMC_STATE_EMPTY) && !force) { - (void)printf("Disc not empty! Use -F to force " - "initialisation\n"); - return EROFS; - } - } else { - /* check if disc (being) formatted or has been started on */ - if (mmc_discinfo.disc_state == MMC_STATE_EMPTY) { - (void)printf("Disc is not formatted\n"); - return EROFS; - } - } - - /* determine UDF format */ - format_flags = 0; - if (mmc_discinfo.mmc_cur & MMC_CAP_REWRITABLE) { - /* all rewritable media */ - format_flags |= FORMAT_REWRITABLE; - if (context.min_udf >= 0x0250) { - /* standard dictates meta as default */ - format_flags |= FORMAT_META; - } - - if ((mmc_discinfo.mmc_cur & MMC_CAP_HW_DEFECTFREE) == 0) { - /* sparables for defect management */ - if (context.min_udf >= 0x150) - format_flags |= FORMAT_SPARABLE; - } - } else { - /* all once recordable media */ - format_flags |= FORMAT_WRITEONCE; - if (mmc_discinfo.mmc_cur & MMC_CAP_SEQUENTIAL) { - format_flags |= FORMAT_SEQUENTIAL; - - if (mmc_discinfo.mmc_cur & MMC_CAP_PSEUDOOVERWRITE) { - /* logical overwritable */ - format_flags |= FORMAT_LOW; - } else { - /* have to use VAT for overwriting */ - format_flags |= FORMAT_VAT; - } - } else { - /* rare WORM devices, but BluRay has one, strat4096 */ - format_flags |= FORMAT_WORM; - } - } - - /* enable/disable requests */ - if (req_disable & FORMAT_META) { - format_flags &= ~(FORMAT_META | FORMAT_LOW); - req_disable &= ~FORMAT_META; - } - if ((format_flags & FORMAT_VAT) & UDF_512_TRACK) - format_flags |= FORMAT_TRACK512; - - if (req_enable & FORMAT_READONLY) { - format_flags |= FORMAT_READONLY; - } - - /* determine partition/media access type */ - media_accesstype = UDF_ACCESSTYPE_NOT_SPECIFIED; - if (mmc_discinfo.mmc_cur & MMC_CAP_REWRITABLE) { - media_accesstype = UDF_ACCESSTYPE_OVERWRITABLE; - if (mmc_discinfo.mmc_cur & MMC_CAP_ERASABLE) - media_accesstype = UDF_ACCESSTYPE_REWRITEABLE; - } else { - /* all once recordable media */ - media_accesstype = UDF_ACCESSTYPE_WRITE_ONCE; - } - if (mmc_discinfo.mmc_cur & MMC_CAP_PSEUDOOVERWRITE) - media_accesstype = UDF_ACCESSTYPE_PSEUDO_OVERWITE; - - /* patch up media accesstype */ - if (req_enable & FORMAT_READONLY) { - /* better now */ - media_accesstype = UDF_ACCESSTYPE_READ_ONLY; - } - - /* adjust minimum version limits */ - if (format_flags & FORMAT_VAT) - context.min_udf = MAX(context.min_udf, 0x0150); - if (format_flags & FORMAT_SPARABLE) - context.min_udf = MAX(context.min_udf, 0x0150); - if (format_flags & FORMAT_META) - context.min_udf = MAX(context.min_udf, 0x0250); - if (format_flags & FORMAT_LOW) - context.min_udf = MAX(context.min_udf, 0x0260); - - /* adjust maximum version limits not to tease or break things */ - if (!(format_flags & (FORMAT_META | FORMAT_LOW)) && - (context.max_udf > 0x200)) - context.max_udf = 0x201; - - if ((format_flags & (FORMAT_VAT | FORMAT_SPARABLE)) == 0) - if (context.max_udf <= 0x150) - context.min_udf = 0x102; - - /* limit Ecma 167 descriptor if possible/needed */ - context.dscrver = 3; - if ((context.min_udf < 0x200) || (context.max_udf < 0x200)) { - context.dscrver = 2; - context.max_udf = 0x150; /* last version < 0x200 */ - } - - /* is it possible ? */ - if (context.min_udf > context.max_udf) { - (void)printf("Initialisation prohibited by specified maximum " - "UDF version 0x%04x. Minimum version required 0x%04x\n", - context.max_udf, context.min_udf); - return EPERM; - } - - if (!UDF_VERSION(context.min_udf) || !UDF_VERSION(context.max_udf)) { - printf("Choose UDF version numbers from " - "0x102, 0x150, 0x200, 0x201, 0x250 and 0x260\n"); - printf("Default version is 0x201\n"); - return EPERM; - } - - return 0; -} - -#undef UDF_VERSION - - -/* --------------------------------------------------------------------- */ - -int -udf_proces_names(void) -{ - struct timeval time_of_day; - uint32_t primary_nr; - uint64_t volset_nr; - - if (context.logvol_name == NULL) - context.logvol_name = strdup("anonymous"); - if (context.primary_name == NULL) { - if (mmc_discinfo.disc_flags & MMC_DFLAGS_DISCIDVALID) { - primary_nr = mmc_discinfo.disc_id; - } else { - primary_nr = (uint32_t) random(); - } - context.primary_name = calloc(32, 1); - sprintf(context.primary_name, "%08"PRIx32, primary_nr); - } - if (context.volset_name == NULL) { - if (mmc_discinfo.disc_flags & MMC_DFLAGS_BARCODEVALID) { - volset_nr = mmc_discinfo.disc_barcode; - } else { - (void)gettimeofday(&time_of_day, NULL); - volset_nr = (uint64_t) random(); - volset_nr |= ((uint64_t) time_of_day.tv_sec) << 32; - } - context.volset_name = calloc(128,1); - sprintf(context.volset_name, "%016"PRIx64, volset_nr); - } - if (context.fileset_name == NULL) - context.fileset_name = strdup("anonymous"); - - /* check passed/created identifiers */ - if (strlen(context.logvol_name) > 128) { - (void)printf("Logical volume name too long\n"); - return EINVAL; - } - if (strlen(context.primary_name) > 32) { - (void)printf("Primary volume name too long\n"); - return EINVAL; - } - if (strlen(context.volset_name) > 128) { - (void)printf("Volume set name too long\n"); - return EINVAL; - } - if (strlen(context.fileset_name) > 32) { - (void)printf("Fileset name too long\n"); - return EINVAL; - } - - /* signal all OK */ - return 0; -} - -/* --------------------------------------------------------------------- */ - -static int -udf_write_iso9660_vrs(void) -{ - struct vrs_desc *iso9660_vrs_desc; - uint32_t pos; - int error, cnt, dpos; - - /* create ISO/Ecma-167 identification descriptors */ - if ((iso9660_vrs_desc = calloc(1, context.sector_size)) == NULL) - return ENOMEM; - - /* - * All UDF formats should have their ISO/Ecma-167 descriptors written - * except when not possible due to track reservation in the case of - * VAT - */ - if ((format_flags & FORMAT_TRACK512) == 0) { - dpos = (2048 + context.sector_size - 1) / context.sector_size; - - /* wipe at least 6 times 2048 byte `sectors' */ - for (cnt = 0; cnt < 6 *dpos; cnt++) { - pos = layout.iso9660_vrs + cnt; - if ((error = udf_write_sector(iso9660_vrs_desc, pos))) { - free(iso9660_vrs_desc); - return error; - } - } - - /* common VRS fields in all written out ISO descriptors */ - iso9660_vrs_desc->struct_type = 0; - iso9660_vrs_desc->version = 1; - pos = layout.iso9660_vrs; - - /* BEA01, NSR[23], TEA01 */ - memcpy(iso9660_vrs_desc->identifier, "BEA01", 5); - if ((error = udf_write_sector(iso9660_vrs_desc, pos))) { - free(iso9660_vrs_desc); - return error; - } - pos += dpos; - - if (context.dscrver == 2) - memcpy(iso9660_vrs_desc->identifier, "NSR02", 5); - else - memcpy(iso9660_vrs_desc->identifier, "NSR03", 5); - ; - if ((error = udf_write_sector(iso9660_vrs_desc, pos))) { - free(iso9660_vrs_desc); - return error; - } - pos += dpos; - - memcpy(iso9660_vrs_desc->identifier, "TEA01", 5); - if ((error = udf_write_sector(iso9660_vrs_desc, pos))) { - free(iso9660_vrs_desc); - return error; - } - } - - free(iso9660_vrs_desc); - /* return success */ - return 0; -} - - -/* --------------------------------------------------------------------- */ - -/* - * Main function that creates and writes out disc contents based on the - * format_flags's that uniquely define the type of disc to create. - */ - -int -udf_do_newfs_prefix(void) -{ - union dscrptr *zero_dscr; - union dscrptr *dscr; - struct mmc_trackinfo ti; - uint32_t sparable_blocks; - uint32_t sector_size, blockingnr; - uint32_t cnt, loc, len; - int sectcopy; - int error, integrity_type; - int data_part, metadata_part; - - /* init */ - sector_size = mmc_discinfo.sector_size; - - /* determine span/size */ - ti.tracknr = mmc_discinfo.first_track_last_session; - error = udf_update_trackinfo(&mmc_discinfo, &ti); - if (error) - return error; - - if (mmc_discinfo.sector_size < context.sector_size) { - fprintf(stderr, "Impossible to format: sectorsize too small\n"); - return EIO; - } - context.sector_size = sector_size; - - /* determine blockingnr */ - blockingnr = ti.packet_size; - if (blockingnr <= 1) { - /* paranoia on blockingnr */ - switch (mmc_discinfo.mmc_profile) { - case 0x08 : /* CDROM */ - case 0x09 : /* CD-R */ - case 0x0a : /* CD-RW */ - blockingnr = 32; /* UDF requirement */ - break; - case 0x10 : /* DVDROM */ - case 0x11 : /* DVD-R (DL) */ - case 0x12 : /* DVD-RAM */ - case 0x1b : /* DVD+R */ - case 0x2b : /* DVD+R Dual layer */ - case 0x13 : /* DVD-RW restricted overwrite */ - case 0x14 : /* DVD-RW sequential */ - blockingnr = 16; /* SCSI definition */ - break; - case 0x40 : /* BDROM */ - case 0x41 : /* BD-R Sequential recording (SRM) */ - case 0x42 : /* BD-R Random recording (RRM) */ - case 0x43 : /* BD-RE */ - case 0x51 : /* HD DVD-R */ - case 0x52 : /* HD DVD-RW */ - blockingnr = 32; /* SCSI definition */ - break; - default: - break; - } - } - if (blockingnr <= 0) { - printf("Can't fixup blockingnumber for device " - "type %d\n", mmc_discinfo.mmc_profile); - - printf("Device is not returning valid blocking" - " number and media type is unknown.\n"); - - return EINVAL; - } - wrtrack_skew = ti.track_start % blockingnr; - - if (mmc_discinfo.mmc_class == MMC_CLASS_CD) { - /* not too much for CD-RW, still 20MiB */ - sparable_blocks = 32; - } else { - /* take a value for DVD*RW mainly, BD is `defect free' */ - sparable_blocks = 512; - } - - /* get layout */ - error = udf_calculate_disc_layout(format_flags, context.min_udf, - wrtrack_skew, - ti.track_start, mmc_discinfo.last_possible_lba, - context.sector_size, blockingnr, sparable_blocks, - meta_fract); - - /* cache partition for we need it often */ - data_part = context.data_part; - metadata_part = context.metadata_part; - - /* Create sparing table descriptor if applicable */ - if (format_flags & FORMAT_SPARABLE) { - if ((error = udf_create_sparing_tabled())) - return error; - - if (check_surface) { - if ((error = udf_surface_check())) - return error; - } - } - - /* Create a generic terminator descriptor (later reused) */ - terminator_dscr = calloc(1, sector_size); - if (terminator_dscr == NULL) - return ENOMEM; - udf_create_terminator(terminator_dscr, 0); - - /* - * Start with wipeout of VRS1 upto start of partition. This allows - * formatting for sequentials with the track reservation and it - * cleans old rubbish on rewritables. For sequentuals without the - * track reservation all is wiped from track start. - */ - if ((zero_dscr = calloc(1, context.sector_size)) == NULL) - return ENOMEM; - - loc = (format_flags & FORMAT_TRACK512) ? layout.vds1 : ti.track_start; - for (; loc < layout.part_start_lba; loc++) { - if ((error = udf_write_sector(zero_dscr, loc))) { - free(zero_dscr); - return error; - } - } - free(zero_dscr); - - /* Create anchors */ - for (cnt = 0; cnt < 3; cnt++) { - if ((error = udf_create_anchor(cnt))) { - return error; - } - } - - /* - * Create the two Volume Descriptor Sets (VDS) each containing the - * following descriptors : primary volume, partition space, - * unallocated space, logical volume, implementation use and the - * terminator - */ - - /* start of volume recognision sequence building */ - context.vds_seq = 0; - - /* Create primary volume descriptor */ - if ((error = udf_create_primaryd())) - return error; - - /* Create partition descriptor */ - if ((error = udf_create_partitiond(context.data_part, media_accesstype))) - return error; - - /* Create unallocated space descriptor */ - if ((error = udf_create_unalloc_spaced())) - return error; - - /* Create logical volume descriptor */ - if ((error = udf_create_logical_dscr(format_flags))) - return error; - - /* Create implementation use descriptor */ - /* TODO input of fields 1,2,3 and passing them */ - if ((error = udf_create_impvold(NULL, NULL, NULL))) - return error; - - /* write out what we've created so far */ - - /* writeout iso9660 vrs */ - if ((error = udf_write_iso9660_vrs())) - return error; - - /* Writeout anchors */ - for (cnt = 0; cnt < 3; cnt++) { - dscr = (union dscrptr *) context.anchors[cnt]; - loc = layout.anchors[cnt]; - if ((error = udf_write_dscr_phys(dscr, loc, 1))) - return error; - - /* sequential media has only one anchor */ - if (format_flags & FORMAT_SEQUENTIAL) - break; - } - - /* write out main and secondary VRS */ - for (sectcopy = 1; sectcopy <= 2; sectcopy++) { - loc = (sectcopy == 1) ? layout.vds1 : layout.vds2; - - /* primary volume descriptor */ - dscr = (union dscrptr *) context.primary_vol; - error = udf_write_dscr_phys(dscr, loc, 1); - if (error) - return error; - loc++; - - /* partition descriptor(s) */ - for (cnt = 0; cnt < UDF_PARTITIONS; cnt++) { - dscr = (union dscrptr *) context.partitions[cnt]; - if (dscr) { - error = udf_write_dscr_phys(dscr, loc, 1); - if (error) - return error; - loc++; - } - } - - /* unallocated space descriptor */ - dscr = (union dscrptr *) context.unallocated; - error = udf_write_dscr_phys(dscr, loc, 1); - if (error) - return error; - loc++; - - /* logical volume descriptor */ - dscr = (union dscrptr *) context.logical_vol; - error = udf_write_dscr_phys(dscr, loc, 1); - if (error) - return error; - loc++; - - /* implementation use descriptor */ - dscr = (union dscrptr *) context.implementation; - error = udf_write_dscr_phys(dscr, loc, 1); - if (error) - return error; - loc++; - - /* terminator descriptor */ - error = udf_write_dscr_phys(terminator_dscr, loc, 1); - if (error) - return error; - loc++; - } - - /* writeout the two sparable table descriptors (if needed) */ - if (format_flags & FORMAT_SPARABLE) { - for (sectcopy = 1; sectcopy <= 2; sectcopy++) { - loc = (sectcopy == 1) ? layout.spt_1 : layout.spt_2; - dscr = (union dscrptr *) context.sparing_table; - len = layout.sparing_table_dscr_lbas; - - /* writeout */ - error = udf_write_dscr_phys(dscr, loc, len); - if (error) - return error; - } - } - - /* - * Create unallocated space bitmap descriptor. Sequential recorded - * media report their own free/used space; no free/used space tables - * should be recorded for these. - */ - if ((format_flags & (FORMAT_SEQUENTIAL | FORMAT_READONLY)) == 0) { - error = udf_create_space_bitmap( - layout.alloc_bitmap_dscr_size, - layout.part_size_lba, - &context.part_unalloc_bits[data_part]); - if (error) - return error; - /* TODO: freed space bitmap if applicable */ - - /* mark space allocated for the unallocated space bitmap */ - udf_mark_allocated(layout.unalloc_space, data_part, - layout.alloc_bitmap_dscr_size); - } - - /* - * Create metadata partition file entries and allocate and init their - * space and free space maps. - */ - if (format_flags & FORMAT_META) { - error = udf_create_space_bitmap( - layout.meta_bitmap_dscr_size, - layout.meta_part_size_lba, - &context.part_unalloc_bits[metadata_part]); - if (error) - return error; - - error = udf_create_meta_files(); - if (error) - return error; - - /* mark space allocated for meta partition and its bitmap */ - udf_mark_allocated(layout.meta_file, data_part, 1); - udf_mark_allocated(layout.meta_mirror, data_part, 1); - udf_mark_allocated(layout.meta_bitmap, data_part, 1); - udf_mark_allocated(layout.meta_part_start_lba, data_part, - layout.meta_part_size_lba); - - /* mark space allocated for the unallocated space bitmap */ - udf_mark_allocated(layout.meta_bitmap_space, data_part, - layout.meta_bitmap_dscr_size); - } - - /* create logical volume integrity descriptor */ - context.num_files = 0; - context.num_directories = 0; - integrity_type = UDF_INTEGRITY_OPEN; - if ((error = udf_create_lvintd(integrity_type))) - return error; - - /* writeout initial open integrity sequence + terminator */ - loc = layout.lvis; - dscr = (union dscrptr *) context.logvol_integrity; - error = udf_write_dscr_phys(dscr, loc, 1); - if (error) - return error; - loc++; - error = udf_write_dscr_phys(terminator_dscr, loc, 1); - if (error) - return error; - - /* create VAT if needed */ - if (format_flags & FORMAT_VAT) { - context.vat_allocated = context.sector_size; - context.vat_contents = malloc(context.vat_allocated); - assert(context.vat_contents); - - udf_prepend_VAT_file(); - } - - /* create FSD and writeout */ - if ((error = udf_create_fsd())) - return error; - udf_mark_allocated(layout.fsd, metadata_part, 1); - - dscr = (union dscrptr *) context.fileset_desc; - error = udf_write_dscr_virt(dscr, layout.fsd, metadata_part, 1); - - return error; -} - - -/* specific routine for newfs to create empty rootdirectory */ -int -udf_do_rootdir(void) { - union dscrptr *root_dscr; - int error; - - /* create root directory and write out */ - assert(context.unique_id == 0x10); - context.unique_id = 0; - if ((error = udf_create_new_rootdir(&root_dscr))) - return error; - udf_mark_allocated(layout.rootdir, context.metadata_part, 1); - - error = udf_write_dscr_virt(root_dscr, - layout.rootdir, context.metadata_part, 1); - - free(root_dscr); - - return error; -} - - -int -udf_do_newfs_postfix(void) -{ - union dscrptr *vat_dscr; - union dscrptr *dscr; - struct long_ad vatdata_pos; - uint32_t loc, len, phys, sects; - int data_part, metadata_part; - int error; - - /* cache partition for we need it often */ - data_part = context.data_part; - metadata_part = context.metadata_part; - - if ((format_flags & FORMAT_SEQUENTIAL) == 0) { - /* update lvint and mark it closed */ - udf_update_lvintd(UDF_INTEGRITY_CLOSED); - - /* overwrite initial terminator */ - loc = layout.lvis+1; - dscr = (union dscrptr *) context.logvol_integrity; - error = udf_write_dscr_phys(dscr, loc, 1); - if (error) - return error; - loc++; - - /* mark end of integrity desciptor sequence again */ - error = udf_write_dscr_phys(terminator_dscr, loc, 1); - if (error) - return error; - } - - /* write out unallocated space bitmap on non sequential media */ - if ((format_flags & (FORMAT_SEQUENTIAL | FORMAT_READONLY)) == 0) { - /* writeout unallocated space bitmap */ - loc = layout.unalloc_space; - dscr = (union dscrptr *) (context.part_unalloc_bits[data_part]); - len = layout.alloc_bitmap_dscr_size; - error = udf_write_dscr_virt(dscr, loc, data_part, len); - if (error) - return error; - } - - if (format_flags & FORMAT_META) { - loc = layout.meta_file; - dscr = (union dscrptr *) context.meta_file; - error = udf_write_dscr_virt(dscr, loc, data_part, 1); - if (error) - return error; - - loc = layout.meta_mirror; - dscr = (union dscrptr *) context.meta_mirror; - error = udf_write_dscr_virt(dscr, loc, data_part, 1); - if (error) - return error; - - loc = layout.meta_bitmap; - dscr = (union dscrptr *) context.meta_bitmap; - error = udf_write_dscr_virt(dscr, loc, data_part, 1); - if (error) - return error; - - /* writeout unallocated space bitmap */ - loc = layout.meta_bitmap_space; - dscr = (union dscrptr *) - (context.part_unalloc_bits[metadata_part]); - len = layout.meta_bitmap_dscr_size; - error = udf_write_dscr_virt(dscr, loc, data_part, len); - if (error) - return error; - } - - /* create a VAT and account for FSD+root */ - vat_dscr = NULL; - if (format_flags & FORMAT_VAT) { - /* update lvint to reflect the newest values (no writeout) */ - udf_update_lvintd(UDF_INTEGRITY_CLOSED); - - error = udf_append_VAT_file(); - if (error) - return error; - - /* write out VAT data */ - sects = UDF_ROUNDUP(context.vat_size, context.sector_size) / - context.sector_size; - layout.vat = context.data_alloc_pos; - udf_data_alloc(sects, &vatdata_pos); - - loc = udf_rw32(vatdata_pos.loc.lb_num); - phys = context.vtop_offset[context.data_part] + loc; - - error = udf_write_phys(context.vat_contents, phys, sects); - if (error) - return error; - loc += sects; - - /* create new VAT descriptor */ - error = udf_create_VAT(&vat_dscr); - if (error) - return error; - context.data_alloc_pos++; - loc++; - - error = udf_write_dscr_virt(vat_dscr, loc, metadata_part, 1); - free(vat_dscr); - if (error) - return error; - } - - /* done */ - return 0; -} diff --git a/sbin/newfs_udf/udf_write.h b/sbin/newfs_udf/udf_write.h deleted file mode 100644 index d2fd8ac0c..000000000 --- a/sbin/newfs_udf/udf_write.h +++ /dev/null @@ -1,54 +0,0 @@ -/* $NetBSD: udf_write.h,v 1.4 2013/08/05 20:52:08 reinoud Exp $ */ - -/* - * Copyright (c) 2006, 2008, 2013 Reinoud Zandijk - * 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 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. - * - */ - -#ifndef _FS_UDF_UDF_WRITE_H_ -#define _FS_UDF_UDF_WRITE_H_ - -#include "udf_create.h" -#if !HAVE_NBTOOL_CONFIG_H -#define _EXPOSE_MMC -#include -#else -#include "udf/cdio_mmc_structs.h" -#endif - -/* prototypes */ - -int udf_write_dscr_virt(union dscrptr *dscr, uint32_t location, uint32_t vpart, - uint32_t sects); -void udf_metadata_alloc(int nblk, struct long_ad *pos); -void udf_data_alloc(int nblk, struct long_ad *pos); - -int udf_derive_format(int req_enable, int req_disable, int force); -int udf_proces_names(void); - -int udf_do_newfs_prefix(void); -int udf_do_rootdir(void); -int udf_do_newfs_postfix(void); - -#endif /* _FS_UDF_UDF_WRITE_H_ */ diff --git a/sbin/newfs_udf/unicode.h b/sbin/newfs_udf/unicode.h deleted file mode 100644 index f54f32076..000000000 --- a/sbin/newfs_udf/unicode.h +++ /dev/null @@ -1,161 +0,0 @@ -/* $NetBSD: unicode.h,v 1.1 2013/08/05 14:11:30 reinoud Exp $ */ - -/*- - * Copyright (c) 2001, 2004 The NetBSD Foundation, Inc. - * 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 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. - */ - -/*- - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Paul Borman at Krystal Technologies. - * - * 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 University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -/* - * Routines for handling Unicode encoded in UTF-8 form, code derived from - * src/lib/libc/locale/utf2.c. - */ -static u_int16_t wget_utf8(const char **, size_t *) __unused; -static int wput_utf8(char *, size_t, u_int16_t) __unused; - -/* - * Read one UTF8-encoded character off the string, shift the string pointer - * and return the character. - */ -static u_int16_t -wget_utf8(const char **str, size_t *sz) -{ - unsigned int c; - u_int16_t rune = 0; - const char *s = *str; - static const int _utf_count[16] = { - 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 2, 2, 3, 0, - }; - - /* must be called with at least one byte remaining */ - assert(*sz > 0); - - c = _utf_count[(s[0] & 0xf0) >> 4]; - if (c == 0 || c > *sz) { - decoding_error: - /* - * The first character is in range 128-255 and doesn't - * mark valid a valid UTF-8 sequence. There is not much - * we can do with this, so handle by returning - * the first character as if it would be a correctly - * encoded ISO-8859-1 character. - */ - c = 1; - } - - switch (c) { - case 1: - rune = s[0] & 0xff; - break; - case 2: - if ((s[1] & 0xc0) != 0x80) - goto decoding_error; - rune = ((s[0] & 0x1F) << 6) | (s[1] & 0x3F); - break; - case 3: - if ((s[1] & 0xC0) != 0x80 || (s[2] & 0xC0) != 0x80) - goto decoding_error; - rune = ((s[0] & 0x0F) << 12) | ((s[1] & 0x3F) << 6) - | (s[2] & 0x3F); - break; - } - - *str += c; - *sz -= c; - return rune; -} - -/* - * Encode wide character and write it to the string. 'n' specifies - * how much buffer space remains in 's'. Returns number of bytes written - * to the target string 's'. - */ -static int -wput_utf8(char *s, size_t n, u_int16_t wc) -{ - if (wc & 0xf800) { - if (n < 3) { - /* bound check failure */ - return 0; - } - - s[0] = 0xE0 | (wc >> 12); - s[1] = 0x80 | ((wc >> 6) & 0x3F); - s[2] = 0x80 | ((wc) & 0x3F); - return 3; - } else if (wc & 0x0780) { - if (n < 2) { - /* bound check failure */ - return 0; - } - - s[0] = 0xC0 | (wc >> 6); - s[1] = 0x80 | ((wc) & 0x3F); - return 2; - } else { - if (n < 1) { - /* bound check failure */ - return 0; - } - - s[0] = wc; - return 1; - } -} diff --git a/sbin/newfs_v7fs/Makefile b/sbin/newfs_v7fs/Makefile deleted file mode 100644 index 961a05c66..000000000 --- a/sbin/newfs_v7fs/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# $NetBSD: Makefile,v 1.4 2012/09/05 23:01:42 riz Exp $ - -.include - -V7FS = ${NETBSDSRCDIR}/sys/fs/v7fs -PROG= newfs_v7fs -MAN= newfs_v7fs.8 -SRCS= newfs_v7fs.c main.c v7fs_endian.c v7fs_superblock.c v7fs_inode.c \ -v7fs_datablock.c v7fs_dirent.c v7fs_io.c v7fs_io_user.c progress.c - -# use progress meter. -FSCK= ${NETBSDSRCDIR}/sbin/fsck - -DPADD+= ${LIBUTIL} -LDADD+= -lutil -CPPFLAGS+=-DV7FS_EI -I${V7FS} -I${FSCK} -.PATH: ${V7FS} ${FSCK} - -COPTS.newfs_v7fs.c+= -Wno-pointer-sign - -.include diff --git a/sbin/newfs_v7fs/main.c b/sbin/newfs_v7fs/main.c deleted file mode 100644 index a31ebdeb5..000000000 --- a/sbin/newfs_v7fs/main.c +++ /dev/null @@ -1,316 +0,0 @@ -/* $NetBSD: main.c,v 1.10 2011/08/10 11:31:49 uch Exp $ */ - -/*- - * Copyright (c) 2011 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by UCHIYAMA Yasushi. - * - * 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 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. - */ - -#if HAVE_NBTOOL_CONFIG_H -#include "nbtool_config.h" -#endif - -#include -#ifndef lint -__RCSID("$NetBSD: main.c,v 1.10 2011/08/10 11:31:49 uch Exp $"); -#endif /* not lint */ - -#include -#include -#include -#include -#include -#include - -#include "v7fs.h" -#include "v7fs_impl.h" -#include "v7fs_endian.h" -#include "v7fs_superblock.h" -#include "v7fs_inode.h" -#include "v7fs_datablock.h" /*v7fs_datablock_expand/last */ -#include "newfs_v7fs.h" -#include "progress.h" /*../sbin/fsck */ - -#define VPRINTF(lv, fmt, args...) { if (v7fs_newfs_verbose >= lv) \ - printf(fmt, ##args); } - -static v7fs_daddr_t -determine_ilist_size(v7fs_daddr_t volume_size, int32_t files) -{ - v7fs_daddr_t ilist_size; - - if (files) - ilist_size = howmany(files, V7FS_INODE_PER_BLOCK); - else - ilist_size = volume_size / 25; /* 4% */ - if (ilist_size > (v7fs_daddr_t)V7FS_ILISTBLK_MAX) - ilist_size = V7FS_ILISTBLK_MAX; - - return ilist_size; -} - -static int -partition_check(struct v7fs_self *fs) -{ - struct v7fs_superblock *sb = &fs->superblock; - int error; - - if ((error = v7fs_superblock_load(fs))) { - if (error != EINVAL) { - /* Invalid superblock information is OK. */ - warnx("Can't read superblock sector."); - } - } - sb->modified = 1; - if ((error = v7fs_superblock_writeback(fs))) { - if (errno == EROFS) { - warnx("Overwriting disk label? "); - } - warnx("Can't write superblock sector."); - } - - return error; -} - -static int -make_root(struct v7fs_self *fs) -{ - struct v7fs_inode inode; - struct v7fs_dirent *dir; - int error; - - /* INO 1 badblk (don't used) */ - memset(&inode, 0, sizeof(inode)); - inode.inode_number = 1; - inode.mode = V7FS_IFREG; /* V7 manner */ - v7fs_inode_writeback(fs, &inode); - - /* INO 2 root */ - v7fs_ino_t ino; - if ((error = v7fs_inode_allocate(fs, &ino))) { - errno = error; - warn("Can't allocate / inode"); - return error; - } - - memset(&inode, 0, sizeof(inode)); - inode.inode_number = ino; - inode.mode = 0777 | V7FS_IFDIR; - inode.uid = 0; - inode.gid = 0; - inode.nlink = 2; /* . + .. */ - inode.atime = inode.mtime = inode.ctime = time(0); - - /* root dirent. */ - v7fs_datablock_expand(fs, &inode, sizeof(*dir) * 2); - v7fs_daddr_t blk = inode.addr[0]; - void *buf; - if (!(buf = scratch_read(fs, blk))) { - v7fs_inode_deallocate(fs, ino); - errno = error = EIO; - warn("Can't read / dirent."); - return error; - } - dir = (struct v7fs_dirent *)buf; /*disk endian */ - - strcpy(dir[0].name, "."); - dir[0].inode_number = V7FS_VAL16(fs, ino); - strcpy(dir[1].name, ".."); - dir[1].inode_number = V7FS_VAL16(fs, ino); - if (!fs->io.write(fs->io.cookie, buf, blk)) {/*writeback */ - scratch_free(fs, buf); - errno = error = EIO; - warn("Can't write / dirent."); - return error; - } - scratch_free(fs, buf); - v7fs_inode_writeback(fs, &inode); - if ((error = v7fs_superblock_writeback(fs))) { - errno = error; - warnx("Can't write superblock."); - } - - return error; -} - -static v7fs_daddr_t -make_freeblocklist(struct v7fs_self *fs, v7fs_daddr_t listblk, uint8_t *buf) -{ - uint32_t (*val32)(uint32_t) = fs->val.conv32; - uint16_t (*val16)(uint16_t) = fs->val.conv16; - struct v7fs_freeblock *fb = (struct v7fs_freeblock *)buf; - int i, j, k; - - memset(buf, 0, V7FS_BSIZE); - - for (i = V7FS_MAX_FREEBLOCK - 1, j = listblk + 1, k = 0; i >= 0; - i--, j++, k++) { - progress(0); - if (j == (int32_t)fs->superblock.volume_size) - { - VPRINTF(4, "\nlast freeblock #%d\n", - (*val32)(fb->freeblock[i + 1])); - - memmove(fb->freeblock + 1, fb->freeblock + i + 1, k * - sizeof(v7fs_daddr_t)); - fb->freeblock[0] = 0; /* Terminate link; */ - fb->nfreeblock = (*val16)(k + 1); - VPRINTF(4, "last freeblock contains #%d\n", - (*val16)(fb->nfreeblock)); - fs->io.write(fs->io.cookie, buf, listblk); - return 0; - } - fb->freeblock[i] = (*val32)(j); - } - fb->nfreeblock = (*val16)(k); - - if (!fs->io.write(fs->io.cookie, buf, listblk)) { - errno = EIO; - warn("blk=%ld", (long)listblk); - return 0; - } - - /* Return next link block */ - return (*val32)(fb->freeblock[0]); -} - -static int -make_filesystem(struct v7fs_self *fs, v7fs_daddr_t volume_size, - v7fs_daddr_t ilist_size) -{ - struct v7fs_superblock *sb; - v7fs_daddr_t blk; - uint8_t buf[V7FS_BSIZE]; - int error = 0; - int32_t i, j; - - /* Setup ilist. (ilist must be zero filled. becuase of they are free) */ - VPRINTF(4, "Zero clear ilist.\n"); - progress(&(struct progress_arg){ .label = "zero ilist", .tick = - ilist_size / PROGRESS_BAR_GRANULE }); - memset(buf, 0, sizeof buf); - for (i = V7FS_ILIST_SECTOR; i < (int32_t)ilist_size; i++) { - fs->io.write(fs->io.cookie, buf, i); - progress(0); - } -#ifndef HAVE_NBTOOL_CONFIG_H - progress_done(); -#endif - VPRINTF(4, "\n"); - - /* Construct superblock */ - sb = &fs->superblock; - sb->volume_size = volume_size; - sb->datablock_start_sector = ilist_size + V7FS_ILIST_SECTOR; - sb->update_time = time(NULL); - - /* fill free inode cache. */ - VPRINTF(4, "Setup inode cache.\n"); - sb->nfreeinode = V7FS_MAX_FREEINODE; - for (i = V7FS_MAX_FREEINODE - 1, j = V7FS_ROOT_INODE; i >= 0; i--, j++) - sb->freeinode[i] = j; - sb->total_freeinode = ilist_size * V7FS_INODE_PER_BLOCK - 1; - - /* fill free block cache. */ - VPRINTF(4, "Setup free block cache.\n"); - sb->nfreeblock = V7FS_MAX_FREEBLOCK; - for (i = V7FS_MAX_FREEBLOCK - 1, j = sb->datablock_start_sector; i >= 0; - i--, j++) - sb->freeblock[i] = j; - - sb->total_freeblock = volume_size - sb->datablock_start_sector; - - /* Write superblock. */ - sb->modified = 1; - if ((error = v7fs_superblock_writeback(fs))) { - errno = error; - warn("Can't write back superblock."); - return error; - } - - /* Construct freeblock list */ - VPRINTF(4, "Setup whole freeblock list.\n"); - progress(&(struct progress_arg){ .label = "freeblock list", .tick = - (volume_size - sb->datablock_start_sector) / PROGRESS_BAR_GRANULE}); - blk = sb->freeblock[0]; - while ((blk = make_freeblocklist(fs, blk, buf))) - continue; -#ifndef HAVE_NBTOOL_CONFIG_H - progress_done(); -#endif - - VPRINTF(4, "done.\n"); - - return 0; -} - -int -v7fs_newfs(const struct v7fs_mount_device *mount, int32_t maxfile) -{ - struct v7fs_self *fs; - v7fs_daddr_t ilist_size; - int error; - v7fs_daddr_t volume_size = mount->sectors; - - /* Check and determine ilistblock, datablock size. */ - if (volume_size > V7FS_DADDR_MAX + 1) { - warnx("volume size %d over v7fs limit %d. truncated.", - volume_size, V7FS_DADDR_MAX + 1); - volume_size = V7FS_DADDR_MAX + 1; - } - - ilist_size = determine_ilist_size(volume_size, maxfile); - - VPRINTF(1, "volume size=%d, ilist size=%d, endian=%d, NAME_MAX=%d\n", - volume_size, ilist_size, mount->endian, V7FS_NAME_MAX); - - /* Setup I/O ops. */ - if ((error = v7fs_io_init(&fs, mount, V7FS_BSIZE))) { - errno = error; - warn("I/O setup failed."); - return error; - } - fs->endian = mount->endian; - v7fs_endian_init(fs); - - if ((error = partition_check(fs))) { - return error; - } - - /* Construct filesystem. */ - if ((error = make_filesystem(fs, volume_size, ilist_size))) { - return error; - } - - /* Setup root. */ - if ((error = make_root(fs))) { - return error; - } - - v7fs_io_fini(fs); - - return 0; -} diff --git a/sbin/newfs_v7fs/newfs_v7fs.8 b/sbin/newfs_v7fs/newfs_v7fs.8 deleted file mode 100644 index 596a91086..000000000 --- a/sbin/newfs_v7fs/newfs_v7fs.8 +++ /dev/null @@ -1,139 +0,0 @@ -.\" $NetBSD: newfs_v7fs.8,v 1.4 2016/09/12 05:16:04 sevan Exp $ -.\" -.\" Copyright (c) 2011 The NetBSD Foundation, Inc. -.\" All rights reserved. -.\" -.\" This code is derived from software contributed to The NetBSD Foundation -.\" by UCHIYAMA Yasushi. -.\" -.\" 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 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. -.\" -.\" Copyright (c) 1993 -.\" The Regents of the University of California. 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. -.\" 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. -.\" -.\" @(#)newlfs.8 8.1 (Berkeley) 6/19/93 -.\" -.Dd September 12, 2016 -.Dt NEWFS_V7FS 8 -.Os -.Sh NAME -.Nm newfs_v7fs -.Nd construct a new 7th Edition(V7) File System -.Sh SYNOPSIS -.Nm -.Op Fl FZ -.Op Fl B Ar byte-order -.Op Fl n Ar inodes -.Op Fl s Ar sectors -.Op Fl V Ar verbose -.Ar special -.Sh DESCRIPTION -.Nm -builds a 7th Edition(V7) file system on the specified -.Ar special . -If it is a device, the size information will be taken from the disk label and -before running -.Nm -the disk must be labeled using -.Xr disklabel 8 ; -the proper fstype is -.Dq Version 7 . -Otherwise, the size must be specified on the command line. -V7 filesystem's block size and sector size are 512 byte. -Disk address limits are 24 bit. -.Pp -The following arguments are supported: -.Bl -tag -width XBXbyteXorderXX -.It Fl B Ar byte-order -Specify the metadata byte order of the file system to be created. -Valid byte orders are -.Sq be , -.Sq le , -and -.Sq pdp . -If no byte order is specified, the file system is created in host -byte order. -.It Fl F -Create file system to a regular file (needs the -.Fl s -option). -.It Fl n Ar inodes -This specifies the number of inodes for the filesystem. -If the number of inodes exceeds 65536, it is reduced to 65536. -.It Fl s Ar sectors -Create file system with specified number of disk sectors. -.It Fl V Ar verbose -This controls the amount of information written to stdout: -.Bl -tag -width 3n -offset indent -compact -.It 0 -No output. -.It 1 -Overall size, ilist size, endian and filename length. -.It 2 -A progress bar. -.It 3 -.It 4 -More verbose message. -.El -The default is 3. -.It Fl Z -Fill file with zeroes instead of creating a sparse file. -.El -.Sh SEE ALSO -.Xr disklabel 5 , -.Xr disktab 5 , -.\" .Xr fs 5 , -.Xr disklabel 8 , -.Xr diskpart 8 -.Sh HISTORY -A -.Nm -utility appeared in -.Nx 6.0 . -.Sh AUTHORS -.Nm -was written by -.An UCHIYAMA Yasushi Aq Mt uch@NetBSD.org . diff --git a/sbin/newfs_v7fs/newfs_v7fs.c b/sbin/newfs_v7fs/newfs_v7fs.c deleted file mode 100644 index a1ba2b5fc..000000000 --- a/sbin/newfs_v7fs/newfs_v7fs.c +++ /dev/null @@ -1,242 +0,0 @@ -/* $NetBSD: newfs_v7fs.c,v 1.5 2017/01/10 20:53:09 christos Exp $ */ - -/*- - * Copyright (c) 2004, 2011 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by UCHIYAMA Yasushi. - * - * 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 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. - */ - -#include -#ifndef lint -__RCSID("$NetBSD: newfs_v7fs.c,v 1.5 2017/01/10 20:53:09 christos Exp $"); -#endif /* not lint */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include "v7fs_impl.h" -#include "progress.h" -#include "newfs_v7fs.h" - -static void usage(void) __dead; -static bool progress_bar_enable = false; -int v7fs_newfs_verbose = 3; /* newfs compatible */ - -int -main(int argc, char **argv) -{ - const char *device; - struct disklabel d; - struct partition *p; - struct stat st; - uint32_t partsize; - int Fflag, Zflag; - int part; - int fd, ch; - int endian = _BYTE_ORDER; - int32_t maxfile = 0; - - if (argc < 2) - usage(); - - Fflag = Zflag = partsize = 0; - while ((ch = getopt(argc, argv, "Fs:Zs:n:B:V:")) != -1) { - switch (ch) { - case 'V': - v7fs_newfs_verbose = atoi(optarg); - break; - case 'F': - Fflag = 1; - break; - case 's': - partsize = atoi(optarg); - break; - case 'n': - maxfile = atoi(optarg); - break; - case 'Z': - Zflag = 1; - break; - case 'B': - switch (optarg[0]) { - case 'l': - endian = _LITTLE_ENDIAN; - break; - case 'b': - endian = _BIG_ENDIAN; - break; - case 'p': - endian = _PDP_ENDIAN; - break; - } - break; - default: - usage(); - /*NOTREACHED*/ - } - } - argc -= optind; - argv += optind; - - if (argc != 1) - usage(); - device = argv[0]; - - progress_bar_enable = v7fs_newfs_verbose > 1; - - - if (progress_bar_enable) { - progress_switch(progress_bar_enable); - progress_init(); - progress(&(struct progress_arg){ .cdev = device }); - } - - if (!Fflag) { - if ((fd = open(device, O_RDWR)) == -1) { - err(EXIT_FAILURE, "%s", device); - } - if (fstat(fd, &st) != 0) { - goto err_exit; - } - if (!S_ISCHR(st.st_mode)) { - warnx("not a raw device"); - } - - part = DISKPART(st.st_rdev); - - if (ioctl(fd, DIOCGDINFO, &d) == -1) { - goto err_exit; - } - p = &d.d_partitions[part]; - if (v7fs_newfs_verbose) { - printf("partition=%d size=%d offset=%d fstype=%d" - " secsize=%d\n", part, p->p_size, p->p_offset, - p->p_fstype, d.d_secsize); - } - if (p->p_fstype != FS_V7) { - warnx("not a Version 7 partition"); - goto err_exit; - } - partsize = p->p_size; - } else { - off_t filesize; - uint8_t zbuf[8192] = {0, }; - - if (partsize == 0) { - errx(EXIT_FAILURE, "-F requires -s"); - } - - filesize = partsize << V7FS_BSHIFT; - - fd = open(device, O_RDWR|O_CREAT|O_TRUNC, 0666); - if (fd == -1) { - err(EXIT_FAILURE, "%s", device); - } - - if (Zflag) { - while (filesize > 0) { - size_t writenow = MIN(filesize, - (off_t)sizeof(zbuf)); - - if ((size_t)write(fd, zbuf, writenow) != - writenow) { - err(EXIT_FAILURE, NULL); - } - filesize -= writenow; - } - } else { - if (lseek(fd, filesize - 1, SEEK_SET) == -1) { - goto err_exit; - } - if (write(fd, zbuf, 1) != 1) { - goto err_exit; - } - if (lseek(fd, 0, SEEK_SET) == -1) { - goto err_exit; - } - } - } - - if (v7fs_newfs(&(struct v7fs_mount_device) - { .device.fd = fd, .endian = endian, .sectors = partsize }, - maxfile) != 0) - goto err_exit; - - close(fd); - - return EXIT_SUCCESS; - err_exit: - close(fd); - err(EXIT_FAILURE, NULL); -} - -void -progress(const struct progress_arg *p) -{ - static struct progress_arg Progress; - static char cdev[32]; - static char label[32]; - - if (!progress_bar_enable) - return; - - if (p) { - Progress = *p; - if (p->cdev) - strcpy(cdev, p->cdev); - if (p->label) - strcpy(label, p->label); - } - - if (!Progress.tick) - return; - if (++Progress.cnt > Progress.tick) { - Progress.cnt = 0; - Progress.total++; - progress_bar(cdev, label, Progress.total, PROGRESS_BAR_GRANULE); - } -} - -static void -usage(void) -{ - - (void)fprintf(stderr, "usage: \n%s [-FZ] [-B byte-order]" - " [-n inodes] [-s sectors] [-V verbose] special\n", getprogname()); - - exit(EXIT_FAILURE); -} diff --git a/sbin/newfs_v7fs/newfs_v7fs.h b/sbin/newfs_v7fs/newfs_v7fs.h deleted file mode 100644 index 52ddcea11..000000000 --- a/sbin/newfs_v7fs/newfs_v7fs.h +++ /dev/null @@ -1,48 +0,0 @@ -/* $NetBSD: newfs_v7fs.h,v 1.2 2011/08/10 11:31:49 uch Exp $ */ - -/*- - * Copyright (c) 2011 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by UCHIYAMA Yasushi. - * - * 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 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. - */ - -#ifndef _SBIN_NEWFS_V7FS_NEWFS_V7FS_H_ -#define _SBIN_NEWFS_V7FS_NEWFS_V7FS_H_ - -#define PROGRESS_BAR_GRANULE 100 -struct progress_arg { - const char *cdev; - const char *label; - off_t tick; - off_t cnt; - off_t total; -}; -__BEGIN_DECLS -void progress(const struct progress_arg *); -int v7fs_newfs(const struct v7fs_mount_device *, int32_t); -extern int v7fs_newfs_verbose; -__END_DECLS -#endif /* !_SBIN_NEWFS_V7FS_NEWFS_V7FS_H_ */ diff --git a/sbin/reboot/Makefile b/sbin/reboot/Makefile deleted file mode 100644 index d46104486..000000000 --- a/sbin/reboot/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# $NetBSD: Makefile,v 1.18 2002/08/02 15:05:57 wiz Exp $ -# @(#)Makefile 8.1 (Berkeley) 6/5/93 - -PROG= reboot -DPADD= ${LIBUTIL} -LDADD= -lutil -CPPFLAGS+= -DSUPPORT_UTMP -DSUPPORT_UTMPX -MAN= reboot.8 -MLINKS= reboot.8 halt.8 \ - reboot.8 poweroff.8 -LINKS= ${BINDIR}/reboot ${BINDIR}/halt \ - ${BINDIR}/reboot ${BINDIR}/poweroff - -.include diff --git a/sbin/reboot/reboot.8 b/sbin/reboot/reboot.8 deleted file mode 100644 index c4db95659..000000000 --- a/sbin/reboot/reboot.8 +++ /dev/null @@ -1,168 +0,0 @@ -.\" $NetBSD: reboot.8,v 1.29 2011/02/16 19:32:26 wiz Exp $ -.\" -.\" Copyright (c) 1990, 1991, 1993 -.\" The Regents of the University of California. 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. -.\" 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. -.\" -.\" @(#)reboot.8 8.1 (Berkeley) 6/9/93 -.\" -.Dd February 16, 2011 -.Dt REBOOT 8 -.Os -.Sh NAME -.Nm reboot , -.Nm poweroff , -.Nm halt -.Nd restarting, powering down and stopping the system -.Sh SYNOPSIS -.Nm halt -.Op Fl dlnpqvxz -.Nm poweroff -.Op Fl dlnqvxz -.Nm -.Op Fl dlnqvxz -.Op Ar arg ... -.Sh DESCRIPTION -The -.Nm poweroff , -.Nm halt -and -.Nm -utilities flush the file system cache to disk, send all running processes -a -.Dv SIGTERM , -wait for up to 30 seconds for them to die, send a -.Dv SIGKILL -to the survivors and, respectively, power down, halt or restart the system. -The action is logged, including entering a shutdown record into the login -accounting file and sending a message via -.Xr syslog 3 . -.Pp -The options are as follows: -.Bl -tag -width Ds -.It Fl d -Create a dump before halting or restarting. -This option is useful for debugging system dump procedures or -capturing the state of a corrupted or misbehaving system. -.It Fl l -Suppress sending a message via -.Xr syslog 3 -before halting or restarting. -.It Fl n -Do not flush the file system cache. -This option should be used with extreme caution. -It can be used if a disk or a processor is on fire. -.It Fl p -Attempt to powerdown the system. -If the powerdown fails, or the system does not support -software powerdown, the system will halt. -This option is only valid for -.Nm halt . -.It Fl v -To enable verbose messages on the console, pass the -.Xr boothowto 9 -flag -.Dv AB_VERBOSE -to -.Xr reboot 2 . -.It Fl x -To enable debugging messages on the console, pass the -.Xr boothowto 9 -flag -.Dv AB_DEBUG -to -.Xr reboot 2 . -.It Fl z -To silence some shutdown messages on the console, pass the -.Xr boothowto 9 -flag -.Dv AB_SILENT -to -.Xr reboot 2 . -.It Fl q -Do not give processes a chance to shut down before halting or restarting. -This option should not normally be used. -.El -.Pp -If there are any arguments passed to -.Nm reboot -they are concatenated with spaces and passed as -.Fa bootstr -to the -.Xr reboot 2 -system call. -The string is passed to the firmware on platforms that support it. -.Pp -Normally, the -.Xr shutdown 8 -utility is used when the system needs to be halted or restarted, giving -users advance warning of their impending doom. -.Sh SEE ALSO -.Xr reboot 2 , -.Xr syslog 3 , -.Xr utmp 5 , -.Xr boot 8 , -.Xr init 8 , -.Xr rescue 8 , -.Xr shutdown 8 , -.Xr sync 8 -.Sh HISTORY -A -.Nm -command appeared in -.At v6 . -.Pp -The -.Nm poweroff -command first appeared in -.Nx 1.5 . -.Sh CAVEATS -Once the command has begun its work, stopping it before it completes -will probably result in a system so crippled it must be -physically reset. -To prevent premature termination, the command -blocks many signals early in its execution. -However, nothing can defend against deliberate attempts to evade this. -.Pp -This command will stop the system without running any -.Xr shutdown 8 -scripts. -Amongst other things, this means that swapping will not be -disabled so that -.Xr raid 4 -can shutdown cleanly. -You should normally use -.Xr shutdown 8 -unless you are running in single user mode. -.Sh BUGS -The single user shell will ignore the -.Dv SIGTERM -signal. -To avoid waiting for the timeout when -rebooting or halting from the single user shell, you have to -.Ic exec reboot -or -.Ic exec halt . diff --git a/sbin/reboot/reboot.c b/sbin/reboot/reboot.c deleted file mode 100644 index 2da61705f..000000000 --- a/sbin/reboot/reboot.c +++ /dev/null @@ -1,263 +0,0 @@ -/* $NetBSD: reboot.c,v 1.40 2012/11/04 22:28:16 christos Exp $ */ - -/* - * Copyright (c) 1980, 1986, 1993 - * The Regents of the University of California. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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 - -#ifndef lint -__COPYRIGHT("@(#) Copyright (c) 1980, 1986, 1993\ - The Regents of the University of California. All rights reserved."); -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)reboot.c 8.1 (Berkeley) 6/5/93"; -#else -__RCSID("$NetBSD: reboot.c,v 1.40 2012/11/04 22:28:16 christos Exp $"); -#endif -#endif /* not lint */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef SUPPORT_UTMPX -#include -#endif - -__dead static void usage(void); - -static int dohalt; -static int dopoweroff; - -int -main(int argc, char *argv[]) -{ - const char *progname; -#if !defined(__minix) - int i; -#endif /* !defined(__minix) */ - struct passwd *pw; - int ch, howto, lflag, nflag, qflag, sverrno, len; - const char *user; - char *bootstr, **av; - - progname = getprogname(); - if (progname[0] == '-') - progname++; - if (strcmp(progname, "halt") == 0) { - dohalt = 1; - howto = RB_HALT; - } else if (strcmp(progname, "poweroff") == 0) { - dopoweroff = 1; - howto = RB_HALT | RB_POWERDOWN; - } else - howto = 0; - lflag = nflag = qflag = 0; - while ((ch = getopt(argc, argv, "dlnpqvxz")) != -1) - switch(ch) { - case 'd': - howto |= RB_DUMP; - break; - case 'l': - lflag = 1; - break; - case 'n': - nflag = 1; - howto |= RB_NOSYNC; - break; - case 'p': - if (dohalt == 0) - usage(); - howto |= RB_POWERDOWN; - break; - case 'q': - qflag = 1; - break; - case 'v': - howto |= AB_VERBOSE; - break; - case 'x': - howto |= AB_DEBUG; - break; - case 'z': - howto |= AB_SILENT; - break; - case '?': - default: - usage(); - } - argc -= optind; - argv += optind; - - if (argc) { - for (av = argv, len = 0; *av; av++) - len += strlen(*av) + 1; - bootstr = malloc(len + 1); - *bootstr = '\0'; /* for first strcat */ - for (av = argv; *av; av++) { - strcat(bootstr, *av); - strcat(bootstr, " "); - } - bootstr[len - 1] = '\0'; /* to kill last space */ - howto |= RB_STRING; - } else - bootstr = NULL; - - if (geteuid()) - errx(1, "%s", strerror(EPERM)); - - if (qflag) { - reboot(howto, bootstr); - err(1, "reboot"); - } - - /* Log the reboot. */ - if (!lflag) { - if ((user = getlogin()) == NULL) - user = (pw = getpwuid(getuid())) ? - pw->pw_name : "???"; - if (dohalt) { - openlog("halt", LOG_CONS, LOG_AUTH); - syslog(LOG_CRIT, "halted by %s", user); - } else if (dopoweroff) { - openlog("poweroff", LOG_CONS, LOG_AUTH); - syslog(LOG_CRIT, "powered off by %s", user); - } else { - openlog("reboot", LOG_CONS, LOG_AUTH); - if (bootstr) - syslog(LOG_CRIT, "rebooted by %s: %s", user, - bootstr); - else - syslog(LOG_CRIT, "rebooted by %s", user); - } - } -#ifdef SUPPORT_UTMP - logwtmp("~", "shutdown", ""); -#endif -#ifdef SUPPORT_UTMPX - logwtmpx("~", "shutdown", "", INIT_PROCESS, 0); -#endif - - /* - * Do a sync early on, so disks start transfers while we're off - * killing processes. Don't worry about writes done before the - * processes die, the reboot system call syncs the disks. - */ - if (!nflag) - sync(); - - /* - * Ignore signals that we can get as a result of killing - * parents, group leaders, etc. - */ - (void)signal(SIGHUP, SIG_IGN); - (void)signal(SIGINT, SIG_IGN); - (void)signal(SIGQUIT, SIG_IGN); - (void)signal(SIGTERM, SIG_IGN); - (void)signal(SIGTSTP, SIG_IGN); - - /* - * If we're running in a pipeline, we don't want to die - * after killing whatever we're writing to. - */ - (void)signal(SIGPIPE, SIG_IGN); - - /* Just stop init -- if we fail, we'll restart it. */ - if (kill(1, SIGTSTP) == -1) - err(1, "SIGTSTP init"); - - /* Send a SIGTERM first, a chance to save the buffers. */ - if (kill(-1, SIGTERM) == -1) { - /* - * If ESRCH, everything's OK: we're the only non-system - * process! That can happen e.g. via 'exec reboot' in - * single-user mode. - */ - if (errno != ESRCH) { - warn("SIGTERM all processes"); - goto restart; - } - } - - /* - * After the processes receive the signal, start the rest of the - * buffers on their way. Wait 5 seconds between the SIGTERM and - * the SIGKILL to pretend to give everybody a chance. - */ - sleep(2); - if (!nflag) - sync(); - sleep(3); - -#if !defined(__minix) - for (i = 1;; ++i) { - if (kill(-1, SIGKILL) == -1) { - if (errno == ESRCH) - break; - warn("SIGKILL all processes"); - goto restart; - } - if (i > 5) { - warnx("WARNING: some process(es) wouldn't die"); - break; - } - (void)sleep(2 * i); - } -#endif /* !defined(__minix) */ - - reboot(howto, bootstr); - warn("reboot()"); - /* FALLTHROUGH */ - -restart: - sverrno = errno; - errx(1, "%s%s", kill(1, SIGHUP) == -1 ? "(can't restart init): " : "", - strerror(sverrno)); - /* NOTREACHED */ -} - -static void -usage(void) -{ - const char *pflag = dohalt ? "p" : ""; - - (void)fprintf(stderr, "usage: %s [-dln%sqvxz] [-- ]\n", - getprogname(), pflag); - exit(1); -} diff --git a/sbin/route/Makefile b/sbin/route/Makefile deleted file mode 100644 index a9113e319..000000000 --- a/sbin/route/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# $NetBSD: Makefile,v 1.29 2015/09/14 05:12:52 ozaki-r Exp $ -# @(#)Makefile 8.1 (Berkeley) 6/5/93 - -.include - -RUMPPRG=route -MAN= route.8 -SRCS= route.c show.c keywords.c rtutil.c - -.PATH: ${.CURDIR}/../../lib/libc/net -RUMPSRCS= getaddrinfo.c getifaddrs.c getnameinfo.c -RUMPSRCS+= if_indextoname.c if_nametoindex.c -.if (${MKRUMP} != "no") -CPPFLAGS+= -DRUMP_ACTION -.endif - -.if (${USE_INET6} != "no") -CPPFLAGS+=-DINET6 -.endif - -# The Makefile over in ../../distrib/utils/x_route -# would like keywords.[ch] to always exist here, so -# they are now checked in as sources. -# -# CPPFLAGS+=-I. -# CLEANFILES+= keywords.c keywords.h -# keywords.c keywords.h : keywords.sh -# ${HOST_SH} keywords.sh - -.include diff --git a/sbin/route/extern.h b/sbin/route/extern.h deleted file mode 100644 index 9742b583d..000000000 --- a/sbin/route/extern.h +++ /dev/null @@ -1,40 +0,0 @@ -/* $NetBSD: extern.h,v 1.15 2014/11/06 21:29:32 christos Exp $ */ - -/* - * Copyright (c) 1997 Christos Zoulas. 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 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. - */ - -struct sockaddr; -struct sockaddr_x25; -struct sockaddr_ns; - -void parse_show_opts(int, char * const *, int *, int *, const char **, bool); -/* show.c */ -void show(int, char * const *, int); - -/* route.c */ -extern int nflag, Sflag; -#define NOTDEFSTRING "0.0.0.0/xxx.xxx.xxx.xxx\0" -int keyword(const char *); -const char *ns_print(struct sockaddr_ns *); -void usage(const char *)__attribute__((__noreturn__)); diff --git a/sbin/route/keywords.c b/sbin/route/keywords.c deleted file mode 100644 index 5acc8875e..000000000 --- a/sbin/route/keywords.c +++ /dev/null @@ -1,65 +0,0 @@ -/* $NetBSD: keywords.c,v 1.10 2013/03/01 18:25:17 joerg Exp $ */ - -/* WARNING! This file was generated by keywords.sh */ - -#include "keywords.h" - -struct keytab keywords[] = { - - {"add", K_ADD}, - {"atalk", K_ATALK}, - {"blackhole", K_BLACKHOLE}, - {"change", K_CHANGE}, - {"cloned", K_CLONED}, - {"cloning", K_CLONING}, - {"delete", K_DELETE}, - {"dst", K_DST}, - {"expire", K_EXPIRE}, - {"flush", K_FLUSH}, - {"gateway", K_GATEWAY}, - {"genmask", K_GENMASK}, - {"get", K_GET}, - {"host", K_HOST}, - {"hopcount", K_HOPCOUNT}, - {"iface", K_IFACE}, - {"interface", K_INTERFACE}, - {"ifa", K_IFA}, - {"ifp", K_IFP}, - {"inet", K_INET}, - {"inet6", K_INET6}, - {"link", K_LINK}, - {"llinfo", K_LLINFO}, - {"lock", K_LOCK}, - {"lockrest", K_LOCKREST}, - {"mask", K_MASK}, - {"monitor", K_MONITOR}, - {"mtu", K_MTU}, - {"net", K_NET}, - {"netmask", K_NETMASK}, - {"nostatic", K_NOSTATIC}, - {"prefixlen", K_PREFIXLEN}, - {"proto1", K_PROTO1}, - {"proto2", K_PROTO2}, - {"recvpipe", K_RECVPIPE}, - {"reject", K_REJECT}, - {"rtt", K_RTT}, - {"rttvar", K_RTTVAR}, - {"sa", K_SA}, - {"sendpipe", K_SENDPIPE}, - {"show", K_SHOW}, - {"ssthresh", K_SSTHRESH}, - {"static", K_STATIC}, - {"x25", K_X25}, - {"xns", K_XNS}, - {"xresolve", K_XRESOLVE}, - {"flushall", K_FLUSHALL}, - {"nocloned", K_NOCLONED}, - {"nocloning", K_NOCLONING}, - {"noblackhole", K_NOBLACKHOLE}, - {"noreject", K_NOREJECT}, - {"mpls", K_MPLS}, - {"tag", K_TAG}, - {"proxy", K_PROXY}, - {0, 0} -}; - diff --git a/sbin/route/keywords.h b/sbin/route/keywords.h deleted file mode 100644 index 33700aa11..000000000 --- a/sbin/route/keywords.h +++ /dev/null @@ -1,64 +0,0 @@ -/* $NetBSD: keywords.h,v 1.13 2013/03/01 18:25:17 joerg Exp $ */ - -/* WARNING! This file was generated by keywords.sh */ - -extern struct keytab { - const char *kt_cp; - int kt_i; -} keywords[]; - - -#define K_ADD 1 -#define K_ATALK 2 -#define K_BLACKHOLE 3 -#define K_CHANGE 4 -#define K_CLONED 5 -#define K_CLONING 6 -#define K_DELETE 7 -#define K_DST 8 -#define K_EXPIRE 9 -#define K_FLUSH 10 -#define K_GATEWAY 11 -#define K_GENMASK 12 -#define K_GET 13 -#define K_HOST 14 -#define K_HOPCOUNT 15 -#define K_IFACE 16 -#define K_INTERFACE 17 -#define K_IFA 18 -#define K_IFP 19 -#define K_INET 20 -#define K_INET6 21 -#define K_LINK 22 -#define K_LLINFO 23 -#define K_LOCK 24 -#define K_LOCKREST 25 -#define K_MASK 26 -#define K_MONITOR 27 -#define K_MTU 28 -#define K_NET 29 -#define K_NETMASK 30 -#define K_NOSTATIC 31 -#define K_PREFIXLEN 32 -#define K_PROTO1 33 -#define K_PROTO2 34 -#define K_RECVPIPE 35 -#define K_REJECT 36 -#define K_RTT 37 -#define K_RTTVAR 38 -#define K_SA 39 -#define K_SENDPIPE 40 -#define K_SHOW 41 -#define K_SSTHRESH 42 -#define K_STATIC 43 -#define K_X25 44 -#define K_XNS 45 -#define K_XRESOLVE 46 -#define K_FLUSHALL 47 -#define K_NOCLONED 48 -#define K_NOCLONING 49 -#define K_NOBLACKHOLE 50 -#define K_NOREJECT 51 -#define K_MPLS 52 -#define K_TAG 53 -#define K_PROXY 54 diff --git a/sbin/route/keywords.sh b/sbin/route/keywords.sh deleted file mode 100755 index ae1476d72..000000000 --- a/sbin/route/keywords.sh +++ /dev/null @@ -1,128 +0,0 @@ -#!/bin/sh -# $NetBSD: keywords.sh,v 1.11 2013/03/01 18:25:17 joerg Exp $ -# @(#)keywords 8.2 (Berkeley) 3/19/94 -# -# WARNING! If you change this file, re-run it! - -# This program requires "new" awk (or GNU awk). -awk=${AWK:-awk} - -cat << _EOF_ > _keywords.t1 -add -atalk -blackhole -change -cloned -cloning -delete -dst -expire -flush -gateway -genmask -get -host -hopcount -iface -interface -ifa -ifp -inet -inet6 -link -llinfo -lock -lockrest -mask -monitor -mtu -net -netmask -nostatic -prefixlen -proto1 -proto2 -recvpipe -reject -rtt -rttvar -sa -sendpipe -show -ssthresh -static -x25 -xns -xresolve -flushall -nocloned -nocloning -noblackhole -noreject -mpls -tag -proxy -_EOF_ - - -################################################################ -# Setup -################################################################ - -# This creates a stream of: -# keyword KEYWORD -# (lower case, upper case). -tr a-z A-Z < _keywords.t1 | -paste _keywords.t1 - > _keywords.t2 - - -################################################################ -# Generate the h file -################################################################ -exec > keywords.h - -echo '/* $'NetBSD'$ */ - -/* WARNING! This file was generated by keywords.sh */ - -extern struct keytab { - const char *kt_cp; - int kt_i; -} keywords[]; - -' # defines follow - -$awk '{ - printf("#define\tK_%s\t%d\n", $2, NR); -}' < _keywords.t2 - - -################################################################ -# Generate the c file -################################################################ -exec > keywords.c - -echo '/* $'NetBSD'$ */ - -/* WARNING! This file was generated by keywords.sh */ - -#include "keywords.h" - -struct keytab keywords[] = { -' # initializers follow - -$awk '{ - printf("\t{\"%s\", K_%s},\n", $1, $2); -}' < _keywords.t2 - -echo ' {0, 0} -}; -' # tail - - -################################################################ -# Cleanup -################################################################ - -rm -f _keywords.t1 _keywords.t2 -exit 0 diff --git a/sbin/route/prog_ops.h b/sbin/route/prog_ops.h deleted file mode 100644 index c37dc2649..000000000 --- a/sbin/route/prog_ops.h +++ /dev/null @@ -1,73 +0,0 @@ -/* $NetBSD: prog_ops.h,v 1.3 2014/11/06 21:29:32 christos Exp $ */ - -/* - * Copyright (c) 2010 The NetBSD Foundation, Inc. - * 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 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. - */ - -#ifndef _PROG_OPS_H_ -#define _PROG_OPS_H_ - -#include - -#ifndef CRUNCHOPS -/* XXX: Keep same order with netstat! */ -struct prog_ops { - int (*op_init)(void); - - int (*op_sysctl)(const int *, u_int, void *, size_t *, - const void *, size_t); - - int (*op_socket)(int, int, int); - int (*op_open)(const char *, int, ...); - pid_t (*op_getpid)(void); - - ssize_t (*op_read)(int, void *, size_t); - ssize_t (*op_write)(int, const void *, size_t); - - - int (*op_shutdown)(int, int); -}; -extern const struct prog_ops prog_ops; - -#define prog_init prog_ops.op_init -#define prog_socket prog_ops.op_socket -#define prog_open prog_ops.op_open -#define prog_getpid prog_ops.op_getpid -#define prog_read prog_ops.op_read -#define prog_write prog_ops.op_write -#define prog_sysctl prog_ops.op_sysctl -#define prog_shutdown prog_ops.op_shutdown -#else -#define prog_init ((int (*)(void))NULL) -#define prog_socket socket -#define prog_open open -#define prog_getpid getpid -#define prog_read read -#define prog_write write -#define prog_sysctl sysctl -#define prog_shutdown shutdown -#endif - -#endif /* _PROG_OPS_H_ */ diff --git a/sbin/route/route.8 b/sbin/route/route.8 deleted file mode 100644 index aa90f9e2c..000000000 --- a/sbin/route/route.8 +++ /dev/null @@ -1,449 +0,0 @@ -.\" $NetBSD: route.8,v 1.55 2015/03/23 18:33:17 roy Exp $ -.\" -.\" Copyright (c) 1983, 1991, 1993 -.\" The Regents of the University of California. 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. -.\" 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. -.\" -.\" @(#)route.8 8.4 (Berkeley) 6/1/94 -.\" -.Dd March 19, 2015 -.Dt ROUTE 8 -.Os -.Sh NAME -.Nm route -.Nd manually manipulate the routing tables -.Sh SYNOPSIS -.Nm -.Op Fl dfLnqSsTtv -.Ar command -.Oo -.Op Ar modifiers -.Ar args -.Oc -.Sh DESCRIPTION -.Nm -is a utility used to manually manipulate the network -routing tables. -Except for setting up the default route, it is normally not needed, -as a system routing table management daemon such as -.Xr routed 8 , -should tend to this task. -.Pp -.Nm -can be used to modify nearly any aspect of the routing policy, -except packet forwarding, which can be manipulated through the -.Xr sysctl 8 -command. -.Pp -The -.Nm -utility supports a limited number of general options, -but a rich command language, enabling the user to specify -any arbitrary request that could be delivered via the -programmatic interface discussed in -.Xr route 4 . -.Pp -.Bl -tag -width Ds -.It Fl d -Turn on debugging -.It Fl f -Remove all routes (as per -.Cm flush ) . -If used in conjunction with the -.Cm add , -.Cm change , -.Cm delete -or -.Cm get -commands, -.Nm -removes the routes before performing the command. -.It Fl L -Don't show link layer entries in routing table. -.It Fl n -Bypasses attempts to print host and network names symbolically -when reporting actions. -(The process of translating between symbolic -names and numerical equivalents can be quite time consuming, and -may require correct operation of the network; thus it may be expedient -to forgo this, especially when attempting to repair networking operations). -.It Fl q -Suppress all output from commands that manipulate the routing table. -.It Fl S -Print a space when a flag is missing so that flags are vertically aligned -instead of printing the flags that are set as a contiguous string. -.It Fl s -(short) Suppresses all output from a -.Cm get -command except for the actual gateway that will be used. -How the gateway is printed depends on the type of route being looked up. -.It Fl T -Show tags in the route display. -.It Fl t -Test only, don't perform any actions. -.It Fl v -(verbose) Print additional details. -.El -.Pp -The -.Nm -utility provides several commands: -.Pp -.Bl -tag -width Fl -compact -.It Cm add -Add a route. -.It Cm flush -Remove all routes. -.It Cm flushall -Remove all routes including the default gateway. -.It Cm delete -Delete a specific route. -.It Cm change -Change aspects of a route (such as its gateway). -.It Cm get -Lookup and display the route for a destination. -.It Cm show -Print out the route table similar to "netstat \-r" (see -.Xr netstat 1 ) . -.It Cm monitor -Continuously report any changes to the routing information base, -routing lookup misses, or suspected network partitionings. -.El -.Pp -The monitor command has the syntax -.Pp -.Bd -filled -offset indent -compact -.Nm -.Op Fl n -.Cm monitor -.Ed -.Pp -The flush command has the syntax -.Pp -.Bd -filled -offset indent -compact -.Nm -.Op Fl n -.Cm flush -.Op Ar family -.Ed -.Pp -If the -.Cm flush -command is specified, -.Nm -will ``flush'' the routing tables of all gateway entries. -When the address family is specified by any of the -.Fl xns , -.Fl atalk , -.Fl inet , -.Fl inet6 , -or -.Fl mpls -modifiers, only routes having destinations with addresses in the -delineated family will be manipulated. -.Pp -The other commands have the following syntax: -.Pp -.Bd -filled -offset indent -compact -.Nm -.Op Fl n -.Ar command -.Op Fl net No \&| Fl host -.Ar destination gateway -.Ed -.Pp -where -.Ar destination -is the destination host or network, and -.Ar gateway -is the next-hop intermediary via which packets should be routed. -Routes to a particular host may be distinguished from those to -a network by interpreting the Internet address specified as the -.Ar destination -argument. -The optional modifiers -.Fl net -and -.Fl host -force the destination to be interpreted as a network or a host, respectively. -Otherwise, if the -.Ar destination -has a ``local address part'' of -.Dv INADDR_ANY , -or if the -.Ar destination -is the symbolic name of a network, then the route is -assumed to be to a network; otherwise, it is presumed to be a -route to a host. -Optionally, the -.Ar destination -can also be specified in the -.Ar net Ns / Ns Ar bits -format. -.Pp -For example, -.Li 128.32 -is interpreted as -.Fl host Li 128.0.0.32 ; -.Li 128.32.130 -is interpreted as -.Fl host Li 128.32.0.130 ; -.Fl net Li 128.32 -is interpreted as -.Li 128.32.0.0 ; -and -.Fl net Li 128.32.130 -is interpreted as -.Li 128.32.130.0 . -.Pp -The keyword -.Cm default -can be used as the -.Ar destination -to set up a default route to a smart -.Ar gateway . -If no other routes match, this default route will be used as a last resort. -.Pp -If the destination is directly reachable -via an interface requiring -no intermediary system to act as a gateway, the -.Fl interface -modifier should be specified; -the gateway given is the address of this host on the common network, -indicating the interface to be used for transmission. -.Pp -The optional modifiers -.Fl xns , -.Fl atalk , -and -.Fl link -specify that all subsequent addresses are in the -.Tn XNS , -or -.Tn AppleTalk -address families, -or are specified as link-level addresses in the form described in -.Xr link_addr 3 , -and the names must be numeric specifications rather than -symbolic names. -.Pp -The optional modifier -.Fl tag -specifies an address associated with the route. -How the address is used is specific to the address family of -the destination and the interface used to forward the packet. -Currently route tags are consumed only by the -.Xr mpls 4 -stack; therefore -.Nm -assumes that the subsequent addresses are in the -.Tn MPLS -address family. -See -.Xr mpls 4 -for examples of setting routes involving MPLS. -.Pp -The optional -.Fl netmask -qualifier is intended -to achieve the effect of an -.Tn ESIS -redirect with the netmask option, -or to manually add subnet routes with -netmasks different from that of the implied network interface -(as would otherwise be communicated using the OSPF or ISIS routing protocols). -One specifies an additional ensuing address parameter -(to be interpreted as a network mask). -The implicit network mask generated in the -.Dv AF_INET -case -can be overridden by making sure this option follows the destination parameter. -.Fl prefixlen -is also available for similar purpose, in IPv4 and IPv6 case. -.Pp -Routes have associated flags which influence operation of the protocols -when sending to destinations matched by the routes. -These flags are displayed using the following ID characters in the routing -display and may be set (or sometimes cleared) -by indicating the following corresponding modifiers: -.Bl -column "ID" "xnoblackhole" "xRTF_BLACKHOLE" "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -.It Sy "ID" Ta Sy "Modifier" Ta Sy " Flag Bit" Ta Sy "Description" -.It Li " " Ta -iface Ta ~RTF_GATEWAY Ta destination is directly reachable -.It Li 1 Ta -proto1 Ta " RTF_PROTO1" Ta set protocol specific flag #1 -.It Li 2 Ta -proto2 Ta " RTF_PROTO2" Ta set protocol specific flag #2 -.It Li B Ta -blackhole Ta " RTF_BLACKHOLE" Ta discard pkts (during updates) -.It Li b Ta "" Ta " RTF_BROADCAST" Ta Route represents a broadcast address -.It Li " " Ta -noblackhole Ta ~RTF_BLACKHOLE Ta clear blackhole flag -.It Li C Ta -cloning Ta " RTF_CLONING" Ta generates a new route on use -.It Li " " Ta -nocloning Ta ~RTF_CLONING Ta stop generating new routes on use -.It Li c Ta -cloned Ta " RTF_CLONED" Ta route generated by RTF_CLONING -.It Li " " Ta -nocloned Ta ~RTF_CLONED Ta deny removal with RTF_CLONING -.It Li D Ta "" Ta " RTF_DYNAMIC" Ta created dynamically (redirect) -.It Li G Ta "" Ta " RTF_GATEWAY" Ta forwarded to dest by intermediary -.It Li H Ta "" Ta " RTF_HOST" Ta host entry (net otherwise) -.It Li L Ta -llinfo Ta " RTF_LLINFO" Ta translate proto to link addr -.It Li l Ta "" Ta " RTF_LOCAL" Ta Route represents a local address -.It Li M Ta "" Ta " RTF_MODIFIED" Ta modified dynamically (redirect) -.It Li p Ta -proxy Ta " RTF_ANNOUNCE" Ta make entry a link level proxy -.It Li R Ta -reject Ta " RTF_REJECT" Ta send ICMP unreachable on match -.It Li " " Ta -noreject Ta ~RTF_REJECT Ta clear reject flag -.It Li S Ta -static Ta " RTF_STATIC" Ta manually added route -.It Li " " Ta -nostatic Ta ~RTF_STATIC Ta pretend route added automatically -.It Li U Ta "" Ta " RTF_UP" Ta route usable -.It Li X Ta -xresolve Ta " RTF_XRESOLVE" Ta emit mesg on use (for ext lookup) -.El -.Pp -The optional modifiers -.Fl rtt , -.Fl rttvar , -.Fl sendpipe , -.Fl recvpipe , -.Fl mtu , -.Fl hopcount , -.Fl expire , -and -.Fl ssthresh -provide initial values to quantities maintained in the routing entry -by transport level protocols, such as TCP or TP4. -These may be individually locked by preceding each such modifier to -be locked by -the -.Fl lock -meta-modifier, or one can -specify that all ensuing metrics may be locked by the -.Fl lockrest -meta-modifier. -.Pp -In a -.Cm change -or -.Cm add -command where the destination and gateway are not sufficient to specify -the route the -.Fl ifp -or -.Fl ifa -modifiers may be used to determine the interface or interface address. -.Pp -All symbolic names specified for a -.Ar destination -or -.Ar gateway -are looked up first as a host name using -.Xr gethostbyname 3 . -If this lookup fails, -.Xr getnetbyname 3 -is then used to interpret the name as that of a network. -.Pp -.Nm -uses a routing socket and the new message types -.Dv RTM_ADD , -.Dv RTM_DELETE , -.Dv RTM_GET , -and -.Dv RTM_CHANGE . -As such, only the super-user may modify -the routing tables. -.Sh EXIT STATUS -The -.Nm -utility exits 0 on success, and \*[Gt]0 if an error occurs. -This includes the use of the -.Cm get -command to look up a route that is incomplete. -.Sh EXAMPLES -This sets the default route to 192.168.0.1: -.Dl route add default 192.168.0.1 -This shows all routes, without DNS resolution (this is useful if the -DNS is not available): -.Dl route -n show -To install a static route through 10.200.0.1 to reach the network -192.168.1.0/28, use this: -.Dl route add -net 192.168.1.0 -netmask 255.255.255.240 10.200.0.1 -.Sh DIAGNOSTICS -.Bl -tag -width Ds -.It Sy "add [host \&| network ] %s: gateway %s flags %x" -The specified route is being added to the tables. -The values printed are from the routing table entry supplied in the -.Xr ioctl 2 -call. -If the gateway address used was not the primary address of the gateway -(the first one returned by -.Xr gethostbyname 3 ) , -the gateway address is printed numerically as well as symbolically. -.It Sy "delete [ host \&| network ] %s: gateway %s flags %x" -As above, but when deleting an entry. -.It Sy "%s %s done" -When the -.Cm flush -command is specified, each routing table entry deleted -is indicated with a message of this form. -.It Sy "Network is unreachable" -An attempt to add a route failed because the gateway listed was not -on a directly-connected network. -The next-hop gateway must be given. -.It Sy "not in table" -A delete operation was attempted for an entry which -wasn't present in the tables. -.It Sy "routing table overflow" -An add operation was attempted, but the system was -low on resources and was unable to allocate memory -to create the new entry. -.It Sy "Permission denied" -The attempted operation is privileged. -Only root may modify the routing tables. -These privileges are enforced by the kernel. -.El -.Sh SEE ALSO -.Xr mpls 4 , -.Xr netintro 4 , -.Xr route 4 , -.Xr routed 8 , -.Xr sysctl 8 -.\" .Xr XNSrouted 8 -.Sh HISTORY -The -.Nm -command appeared in -.Bx 4.2 . -IPv6 support was added by WIDE/KAME project. -.Sh BUGS -The first paragraph may have slightly exaggerated -.Xr routed 8 Ns 's -abilities. -.Pp -Some uses of the -.Fl ifa -or -.Fl ifp -modifiers with the add command will incorrectly fail with a -.Dq Network is unreachable -message if there is no default route. -See case -.Dv RTM_ADD -in -.Pa sys/net/rtsock.c:route_output -for details. diff --git a/sbin/route/route.c b/sbin/route/route.c deleted file mode 100644 index 71addfa4f..000000000 --- a/sbin/route/route.c +++ /dev/null @@ -1,1809 +0,0 @@ -/* $NetBSD: route.c,v 1.151 2015/03/23 18:33:17 roy Exp $ */ - -/* - * Copyright (c) 1983, 1989, 1991, 1993 - * The Regents of the University of California. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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 -#ifndef lint -__COPYRIGHT("@(#) Copyright (c) 1983, 1989, 1991, 1993\ - The Regents of the University of California. All rights reserved."); -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)route.c 8.6 (Berkeley) 4/28/95"; -#else -__RCSID("$NetBSD: route.c,v 1.151 2015/03/23 18:33:17 roy Exp $"); -#endif -#endif /* not lint */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "keywords.h" -#include "extern.h" -#include "prog_ops.h" -#include "rtutil.h" - -union sockunion { - struct sockaddr sa; - struct sockaddr_in sin; -#ifdef INET6 - struct sockaddr_in6 sin6; -#endif - struct sockaddr_at sat; - struct sockaddr_dl sdl; -#ifndef SMALL - struct sockaddr_mpls smpls; -#endif /* SMALL */ - struct sockaddr_storage sstorage; -}; - -typedef union sockunion *sup; - -struct sou { - union sockunion *so_dst, *so_gate, *so_mask, *so_genmask, *so_ifa, - *so_ifp, *so_mpls; -}; - -static const char *route_strerror(int); -static void set_metric(const char *, int); -static int newroute(int, char *const *); -static void inet_makenetandmask(u_int32_t, struct sockaddr_in *, struct sou *); -#ifdef INET6 -static int inet6_makenetandmask(const struct sockaddr_in6 *, struct sou *); -#endif -static int getaddr(int, const char *, struct hostent **, struct sou *); -static int flushroutes(int, char *const [], int); -static char *netmask_string(const struct sockaddr *, int, int); -static int prefixlen(const char *, struct sou *); -#ifndef SMALL -static void interfaces(void); -__dead static void monitor(void); -static int print_getmsg(struct rt_msghdr *, int, struct sou *); -static const char *linkstate(struct if_msghdr *); -static sup readtag(sup, const char *); -static void addtag(sup, const char *, int); -#endif /* SMALL */ -static int rtmsg(int, int, struct sou *); -static void mask_addr(struct sou *); -static void print_rtmsg(struct rt_msghdr *, int); -static void pmsg_common(struct rt_msghdr *); -static void pmsg_addrs(const char *, int); -static void bprintf(FILE *, int, const char *); -static void sodump(sup, const char *); -static void sockaddr(const char *, struct sockaddr *); - -int pid, rtm_addrs; -int sock; -int forcehost, forcenet, doflush, af; -int iflag, Lflag, nflag, qflag, tflag, Sflag, Tflag; -int verbose, aflen = sizeof(struct sockaddr_in), rtag; -int locking, lockrest, debugonly, shortoutput; -struct rt_metrics rt_metrics; -int rtm_inits; -short ns_nullh[] = {0,0,0}; -short ns_bh[] = {-1,-1,-1}; - -static const char opts[] = "dfLnqSsTtv"; - -void -usage(const char *cp) -{ - - if (cp) - warnx("botched keyword: %s", cp); - (void)fprintf(stderr, - "Usage: %s [-%s] cmd [[-] args]\n", getprogname(), opts); - exit(1); - /* NOTREACHED */ -} - -#define PRIETHER "02x:%02x:%02x:%02x:%02x:%02x" -#define PRIETHER_ARGS(__enaddr) (__enaddr)[0], (__enaddr)[1], (__enaddr)[2], \ - (__enaddr)[3], (__enaddr)[4], (__enaddr)[5] - -int -main(int argc, char * const *argv) -{ - int ch; - - if (argc < 2) - usage(NULL); - - while ((ch = getopt(argc, argv, opts)) != -1) - switch (ch) { - case 'd': - debugonly = 1; - break; - case 'f': - doflush = 1; - break; - case 'L': - Lflag = RT_LFLAG; - break; - case 'n': - nflag = RT_NFLAG; - break; - case 'q': - qflag = 1; - break; - case 'S': - Sflag = 1; - break; - case 's': - shortoutput = 1; - break; - case 'T': - Tflag = RT_TFLAG; - break; - case 't': - tflag = 1; - break; - case 'v': - verbose = RT_VFLAG; - break; - case '?': - default: - usage(NULL); - /*NOTREACHED*/ - } - argc -= optind; - argv += optind; - - if (prog_init && prog_init() == -1) - err(1, "init failed"); - - pid = prog_getpid(); - if (tflag) - sock = prog_open("/dev/null", O_WRONLY, 0); - else - sock = prog_socket(PF_ROUTE, SOCK_RAW, 0); - if (sock < 0) - err(EXIT_FAILURE, "socket"); - - if (*argv == NULL) { - if (doflush) - ch = K_FLUSH; - else - goto no_cmd; - } else - ch = keyword(*argv); - - switch (ch) { -#ifndef SMALL - case K_GET: -#endif /* SMALL */ - case K_CHANGE: - case K_ADD: - case K_DELETE: - if (doflush) - (void)flushroutes(1, argv, 0); - return newroute(argc, argv); - - case K_SHOW: - show(argc, argv, Lflag|nflag|Tflag|verbose); - return 0; - -#ifndef SMALL - case K_MONITOR: - monitor(); - return 0; - -#endif /* SMALL */ - case K_FLUSH: - return flushroutes(argc, argv, 0); - - case K_FLUSHALL: - return flushroutes(argc, argv, 1); - no_cmd: - default: - usage(*argv); - /*NOTREACHED*/ - } -} - -static char * -netmask_string(const struct sockaddr *mask, int len, int family) -{ - static char smask[INET6_ADDRSTRLEN]; - struct sockaddr_in nsin; - struct sockaddr_in6 nsin6; - - if (len >= 0) - snprintf(smask, sizeof(smask), "%d", len); - else { - switch (family) { - case AF_INET: - memset(&nsin, 0, sizeof(nsin)); - memcpy(&nsin, mask, mask->sa_len); - snprintf(smask, sizeof(smask), "%s", - inet_ntoa(nsin.sin_addr)); - break; - case AF_INET6: - memset(&nsin6, 0, sizeof(nsin6)); - memcpy(&nsin6, mask, mask->sa_len); - inet_ntop(family, &nsin6.sin6_addr, smask, - sizeof(smask)); - break; - default: - snprintf(smask, sizeof(smask), "%s", any_ntoa(mask)); - } - } - - return smask; -} -/* - * Purge all entries in the routing tables not - * associated with network interfaces. - */ -static int -flushroutes(int argc, char * const argv[], int doall) -{ - struct sockaddr *sa; - size_t needed; - int flags, mib[6], rlen, seqno; - char *buf, *next, *lim; - const char *afname; - struct rt_msghdr *rtm; - - flags = 0; - af = AF_UNSPEC; - /* Don't want to read back our messages */ - prog_shutdown(sock, SHUT_RD); - parse_show_opts(argc, argv, &af, &flags, &afname, false); - mib[0] = CTL_NET; - mib[1] = PF_ROUTE; - mib[2] = 0; /* protocol */ - mib[3] = 0; /* wildcard address family */ - mib[4] = NET_RT_DUMP; - mib[5] = 0; /* no flags */ - if (prog_sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) - err(EXIT_FAILURE, "route-sysctl-estimate"); - buf = lim = NULL; - if (needed) { - if ((buf = malloc(needed)) == NULL) - err(EXIT_FAILURE, "malloc"); - if (prog_sysctl(mib, 6, buf, &needed, NULL, 0) < 0) - err(EXIT_FAILURE, "actual retrieval of routing table"); - lim = buf + needed; - } - if (verbose) { - (void)printf("Examining routing table from sysctl\n"); - if (af != AF_UNSPEC) - printf("(address family %s)\n", afname); - } - if (needed == 0) - return 0; - seqno = 0; /* ??? */ - for (next = buf; next < lim; next += rtm->rtm_msglen) { - rtm = (struct rt_msghdr *)next; - sa = (struct sockaddr *)(rtm + 1); - if (verbose) - print_rtmsg(rtm, rtm->rtm_msglen); - if ((rtm->rtm_flags & flags) != flags) - continue; - if (!(rtm->rtm_flags & (RTF_GATEWAY | RTF_STATIC | - RTF_LLINFO)) && !doall) - continue; -#if defined(__minix) - /* - * MINIX3 only: routes with the RTF_LOCAL flag are immutable, - * so do not try to delete them. - */ - if (rtm->rtm_flags & RTF_LOCAL) - continue; -#endif /* defined(__minix) */ - if (af != AF_UNSPEC && sa->sa_family != af) - continue; - if (debugonly) - continue; - rtm->rtm_type = RTM_DELETE; - rtm->rtm_seq = seqno; - if ((rlen = prog_write(sock, next, - rtm->rtm_msglen)) < 0) { - warnx("writing to routing socket: %s", - route_strerror(errno)); - return 1; - } - if (rlen < (int)rtm->rtm_msglen) { - warnx("write to routing socket, got %d for rlen", rlen); - return 1; - } - seqno++; - if (qflag) - continue; - if (verbose) - print_rtmsg(rtm, rlen); - else { - (void)printf("%-20.20s ", netname(sa, NULL, nflag)); - sa = (struct sockaddr *)(RT_ROUNDUP(sa->sa_len) + - (char *)sa); - (void)printf("%-20.20s ", routename(sa, nflag)); - (void)printf("done\n"); - } - } - free(buf); - return 0; -} - -static const char * -route_strerror(int error) -{ - - switch (error) { - case ESRCH: - return "not in table"; - case EBUSY: - return "entry in use"; - case ENOBUFS: - return "routing table overflow"; - default: - return strerror(error); - } -} - -static void -set_metric(const char *value, int key) -{ - int flag = 0; - uint64_t noval, *valp = &noval; - - switch (key) { -#define caseof(x, y, z) \ - case x: valp = (uint64_t *)&rt_metrics.z; flag = y; break - caseof(K_MTU, RTV_MTU, rmx_mtu); - caseof(K_HOPCOUNT, RTV_HOPCOUNT, rmx_hopcount); - caseof(K_EXPIRE, RTV_EXPIRE, rmx_expire); - caseof(K_RECVPIPE, RTV_RPIPE, rmx_recvpipe); - caseof(K_SENDPIPE, RTV_SPIPE, rmx_sendpipe); - caseof(K_SSTHRESH, RTV_SSTHRESH, rmx_ssthresh); - caseof(K_RTT, RTV_RTT, rmx_rtt); - caseof(K_RTTVAR, RTV_RTTVAR, rmx_rttvar); - } - rtm_inits |= flag; - if (lockrest || locking) - rt_metrics.rmx_locks |= flag; - if (locking) - locking = 0; - *valp = strtoul(value, NULL, 0); -} - -static int -newroute(int argc, char *const *argv) -{ - const char *cmd, *dest = "", *gateway = ""; - int ishost = 0, ret, attempts, oerrno, flags = RTF_STATIC; - int key; - struct hostent *hp = 0; - struct sou sou, *soup = &sou; - - sou.so_dst = calloc(1, sizeof(union sockunion)); - sou.so_gate = calloc(1, sizeof(union sockunion)); - sou.so_mask = calloc(1, sizeof(union sockunion)); - sou.so_genmask = calloc(1, sizeof(union sockunion)); - sou.so_ifa = calloc(1, sizeof(union sockunion)); - sou.so_ifp = calloc(1, sizeof(union sockunion)); - sou.so_mpls = calloc(1, sizeof(union sockunion)); - - if (sou.so_dst == NULL || sou.so_gate == NULL || sou.so_mask == NULL || - sou.so_genmask == NULL || sou.so_ifa == NULL || sou.so_ifp == NULL || - sou.so_mpls == NULL) - errx(EXIT_FAILURE, "Cannot allocate memory"); - - cmd = argv[0]; - af = AF_UNSPEC; - if (*cmd != 'g') { - /* Don't want to read back our messages */ - prog_shutdown(sock, SHUT_RD); - } - while (--argc > 0) { - if (**(++argv)== '-') { - switch (key = keyword(1 + *argv)) { - - case K_SA: - af = PF_ROUTE; - aflen = sizeof(union sockunion); - break; - -#ifndef SMALL - case K_ATALK: - af = AF_APPLETALK; - aflen = sizeof(struct sockaddr_at); - break; -#endif - - case K_INET: - af = AF_INET; - aflen = sizeof(struct sockaddr_in); - break; - -#ifdef INET6 - case K_INET6: - af = AF_INET6; - aflen = sizeof(struct sockaddr_in6); - break; -#endif - - case K_LINK: - af = AF_LINK; - aflen = sizeof(struct sockaddr_dl); - break; - -#ifndef SMALL - case K_MPLS: - af = AF_MPLS; - aflen = sizeof(struct sockaddr_mpls); - break; - case K_TAG: - if (!--argc) - usage(1+*argv); - af = AF_MPLS; - aflen = sizeof(struct sockaddr_mpls); - (void)getaddr(RTA_TAG, *++argv, 0, soup); - break; -#endif /* SMALL */ - - case K_IFACE: - case K_INTERFACE: - iflag++; - break; - case K_NOSTATIC: - flags &= ~RTF_STATIC; - break; - case K_LLINFO: - flags |= RTF_LLINFO; - break; - case K_LOCK: - locking = 1; - break; - case K_LOCKREST: - lockrest = 1; - break; - case K_HOST: - forcehost++; - break; - case K_REJECT: - flags |= RTF_REJECT; - break; - case K_NOREJECT: - flags &= ~RTF_REJECT; - break; - case K_BLACKHOLE: - flags |= RTF_BLACKHOLE; - break; - case K_NOBLACKHOLE: - flags &= ~RTF_BLACKHOLE; - break; - case K_CLONED: - flags |= RTF_CLONED; - break; - case K_NOCLONED: - flags &= ~RTF_CLONED; - break; - case K_PROTO1: - flags |= RTF_PROTO1; - break; - case K_PROTO2: - flags |= RTF_PROTO2; - break; - case K_PROXY: - flags |= RTF_ANNOUNCE; - break; - case K_CLONING: - flags |= RTF_CLONING; - break; - case K_NOCLONING: - flags &= ~RTF_CLONING; - break; - case K_XRESOLVE: - flags |= RTF_XRESOLVE; - break; - case K_STATIC: - flags |= RTF_STATIC; - break; - case K_IFA: - if (!--argc) - usage(1+*argv); - (void)getaddr(RTA_IFA, *++argv, 0, soup); - break; - case K_IFP: - if (!--argc) - usage(1+*argv); - (void)getaddr(RTA_IFP, *++argv, 0, soup); - break; - case K_GENMASK: - if (!--argc) - usage(1+*argv); - (void)getaddr(RTA_GENMASK, *++argv, 0, soup); - break; - case K_GATEWAY: - if (!--argc) - usage(1+*argv); - (void)getaddr(RTA_GATEWAY, *++argv, 0, soup); - break; - case K_DST: - if (!--argc) - usage(1+*argv); - ishost = getaddr(RTA_DST, *++argv, &hp, soup); - dest = *argv; - break; - case K_NETMASK: - if (!--argc) - usage(1+*argv); - (void)getaddr(RTA_NETMASK, *++argv, 0, soup); - /* FALLTHROUGH */ - case K_NET: - forcenet++; - break; - case K_PREFIXLEN: - if (!--argc) - usage(1+*argv); - ishost = prefixlen(*++argv, soup); - break; - case K_MTU: - case K_HOPCOUNT: - case K_EXPIRE: - case K_RECVPIPE: - case K_SENDPIPE: - case K_SSTHRESH: - case K_RTT: - case K_RTTVAR: - if (!--argc) - usage(1+*argv); - set_metric(*++argv, key); - break; - default: - usage(1+*argv); - } - } else { - if ((rtm_addrs & RTA_DST) == 0) { - dest = *argv; - ishost = getaddr(RTA_DST, *argv, &hp, soup); - } else if ((rtm_addrs & RTA_GATEWAY) == 0) { - gateway = *argv; - (void)getaddr(RTA_GATEWAY, *argv, &hp, soup); - } else { - ret = atoi(*argv); - - if (ret == 0) { - if (strcmp(*argv, "0") == 0) { - if (!qflag) { - warnx("%s, %s", - "old usage of trailing 0", - "assuming route to if"); - } - } else - usage(NULL); - iflag = 1; - continue; - } else if (ret > 0 && ret < 10) { - if (!qflag) { - warnx("%s, %s", - "old usage of trailing digit", - "assuming route via gateway"); - } - iflag = 0; - continue; - } - (void)getaddr(RTA_NETMASK, *argv, 0, soup); - } - } - } - if ((rtm_addrs & RTA_DST) == 0) - errx(EXIT_FAILURE, "missing destination specification"); - if (*cmd == 'a' && (rtm_addrs & RTA_GATEWAY) == 0) - errx(EXIT_FAILURE, "missing gateway specification"); - if (forcehost && forcenet) - errx(EXIT_FAILURE, "-host and -net conflict"); - else if (forcehost) - ishost = 1; - else if (forcenet) - ishost = 0; - flags |= RTF_UP; - if (ishost) - flags |= RTF_HOST; - if (iflag == 0) - flags |= RTF_GATEWAY; - for (attempts = 1; ; attempts++) { - errno = 0; - if ((ret = rtmsg(*cmd, flags, soup)) == 0) - break; - if (errno != ENETUNREACH && errno != ESRCH) - break; - if (af == AF_INET && *gateway && hp && hp->h_addr_list[1]) { - hp->h_addr_list++; - memmove(&soup->so_gate->sin.sin_addr, hp->h_addr_list[0], - hp->h_length); - } else - break; - } - if (*cmd == 'g') - return ret != 0; - if (!qflag) { - oerrno = errno; - (void)printf("%s %s %s", cmd, ishost? "host" : "net", dest); - if (*gateway) { - (void)printf(": gateway %s", gateway); - if (attempts > 1 && ret == 0 && af == AF_INET) - (void)printf(" (%s)", - inet_ntoa(soup->so_gate->sin.sin_addr)); - } - if (ret == 0) - (void)printf("\n"); - else - (void)printf(": %s\n", route_strerror(oerrno)); - } - free(sou.so_dst); - free(sou.so_gate); - free(sou.so_mask); - free(sou.so_genmask); - free(sou.so_ifa); - free(sou.so_ifp); - free(sou.so_mpls); - - return ret != 0; -} - -static void -inet_makenetandmask(const u_int32_t net, struct sockaddr_in * const isin, - struct sou *soup) -{ - struct sockaddr_in *sin; - u_int32_t addr, mask = 0; - char *cp; - - rtm_addrs |= RTA_NETMASK; - if (net == 0) - mask = addr = 0; - else if (net < 128) { - addr = net << IN_CLASSA_NSHIFT; - mask = IN_CLASSA_NET; - } else if (net < 192) { - addr = net << IN_CLASSA_NSHIFT; - mask = IN_CLASSB_NET; - } else if (net < 224) { - addr = net << IN_CLASSA_NSHIFT; - mask = IN_CLASSC_NET; - } else if (net < 256) { - addr = net << IN_CLASSA_NSHIFT; - mask = IN_CLASSD_NET; - } else if (net < 49152) { /* 192 * 256 */ - addr = net << IN_CLASSB_NSHIFT; - mask = IN_CLASSB_NET; - } else if (net < 57344) { /* 224 * 256 */ - addr = net << IN_CLASSB_NSHIFT; - mask = IN_CLASSC_NET; - } else if (net < 65536) { - addr = net << IN_CLASSB_NSHIFT; - mask = IN_CLASSB_NET; - } else if (net < 14680064L) { /* 224 * 65536 */ - addr = net << IN_CLASSC_NSHIFT; - mask = IN_CLASSC_NET; - } else if (net < 16777216L) { - addr = net << IN_CLASSC_NSHIFT; - mask = IN_CLASSD_NET; - } else { - addr = net; - if ((addr & IN_CLASSA_HOST) == 0) - mask = IN_CLASSA_NET; - else if ((addr & IN_CLASSB_HOST) == 0) - mask = IN_CLASSB_NET; - else if ((addr & IN_CLASSC_HOST) == 0) - mask = IN_CLASSC_NET; - else - mask = -1; - } - isin->sin_addr.s_addr = htonl(addr); - sin = &soup->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->sin_family = AF_INET; -} - -#ifdef INET6 -/* - * XXX the function may need more improvement... - */ -static int -inet6_makenetandmask(const struct sockaddr_in6 * const sin6, struct sou *soup) -{ - const char *plen; - struct in6_addr in6; - - plen = NULL; - if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) && - sin6->sin6_scope_id == 0) { - plen = "0"; - } else if ((sin6->sin6_addr.s6_addr[0] & 0xe0) == 0x20) { - /* aggregatable global unicast - RFC2374 */ - memset(&in6, 0, sizeof(in6)); - if (!memcmp(&sin6->sin6_addr.s6_addr[8], &in6.s6_addr[8], 8)) - plen = "64"; - } - - if (!plen || strcmp(plen, "128") == 0) - return 1; - else { - rtm_addrs |= RTA_NETMASK; - (void)prefixlen(plen, soup); - return 0; - } -} -#endif - -/* - * Interpret an argument as a network address of some kind, - * returning 1 if a host address, 0 if a network address. - */ -static int -getaddr(int which, const char *s, struct hostent **hpp, struct sou *soup) -{ - sup su; - struct hostent *hp; - struct netent *np; - u_int32_t val; - char *t; - int afamily; /* local copy of af so we can change it */ - - if (af == AF_UNSPEC) { - af = AF_INET; - aflen = sizeof(struct sockaddr_in); - } - afamily = af; - rtm_addrs |= which; - switch (which) { - case RTA_DST: - su = soup->so_dst; - break; - case RTA_GATEWAY: - su = soup->so_gate; - break; - case RTA_NETMASK: - su = soup->so_mask; - break; - case RTA_GENMASK: - su = soup->so_genmask; - break; - case RTA_IFP: - su = soup->so_ifp; - afamily = AF_LINK; - break; - case RTA_IFA: - su = soup->so_ifa; - su->sa.sa_family = af; - break; -#ifndef SMALL - case RTA_TAG: - su = soup->so_mpls; - afamily = AF_MPLS; - break; -#endif - default: - su = NULL; - 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(s, "default") == 0) { - switch (which) { - case RTA_DST: - forcenet++; - (void)getaddr(RTA_NETMASK, s, 0, soup); - break; - case RTA_NETMASK: - case RTA_GENMASK: - su->sa.sa_len = 0; - } - return 0; - } - switch (afamily) { -#ifdef INET6 - case AF_INET6: - { - struct addrinfo hints, *res; - char *slash = 0; - - if (which == RTA_DST && (slash = (strrchr(s, '/'))) != 0) - *slash = '\0'; - memset(&hints, 0, sizeof(hints)); - hints.ai_family = afamily; /*AF_INET6*/ - hints.ai_flags = AI_NUMERICHOST; - hints.ai_socktype = SOCK_DGRAM; /*dummy*/ - if (getaddrinfo(s, "0", &hints, &res) != 0) { - hints.ai_flags = 0; - if (slash) { - *slash = '/'; - slash = 0; - } - if (getaddrinfo(s, "0", &hints, &res) != 0) - errx(EXIT_FAILURE, "%s: bad value", s); - } - if (slash) - *slash = '/'; - if (sizeof(su->sin6) != res->ai_addrlen) - errx(EXIT_FAILURE, "%s: bad value", s); - if (res->ai_next) { - errx(EXIT_FAILURE, - "%s: address resolved to multiple values", s); - } - memcpy(&su->sin6, res->ai_addr, sizeof(su->sin6)); - freeaddrinfo(res); - inet6_putscopeid(&su->sin6, INET6_IS_ADDR_LINKLOCAL| - INET6_IS_ADDR_MC_LINKLOCAL); - if (hints.ai_flags == AI_NUMERICHOST) { - if (slash) - return prefixlen(slash + 1, soup); - if (which == RTA_DST) - return inet6_makenetandmask(&su->sin6, soup); - return 0; - } else - return 1; - } -#endif - - case PF_ROUTE: - su->sa.sa_len = sizeof(*su); - sockaddr(s, &su->sa); - return 1; - -#ifndef SMALL - case AF_APPLETALK: - t = strchr (s, '.'); - if (!t) { -badataddr: - errx(EXIT_FAILURE, "bad address: %s", s); - } - val = atoi (s); - if (val > 65535) - goto badataddr; - su->sat.sat_addr.s_net = val; - val = atoi (t); - if (val > 256) - goto badataddr; - su->sat.sat_addr.s_node = val; - rtm_addrs |= RTA_NETMASK; - return(forcehost || su->sat.sat_addr.s_node != 0); - case AF_MPLS: - if (which == RTA_DST) - soup->so_dst = readtag(su, s); - else if (which == RTA_TAG) - soup->so_mpls = readtag(su, s); - else - errx(EXIT_FAILURE, "MPLS can be used only as " - "DST or TAG"); - return 1; -#endif - - case AF_LINK: - link_addr(s, &su->sdl); - return 1; - - case AF_INET: - default: - break; - } - - if (hpp == NULL) - hpp = &hp; - *hpp = NULL; - - if ((t = strchr(s, '/')) != NULL && which == RTA_DST) { - *t = '\0'; - if (forcenet == 0) { - if ((val = inet_addr(s)) != INADDR_NONE) { - inet_makenetandmask(htonl(val), &su->sin, soup); - return prefixlen(&t[1], soup); - } - } else { - if ((val = inet_network(s)) != INADDR_NONE) { - inet_makenetandmask(val, &su->sin, soup); - return prefixlen(&t[1], soup); - } - } - *t = '/'; - } - if (inet_aton(s, &su->sin.sin_addr) && - (which != RTA_DST || forcenet == 0)) { - val = su->sin.sin_addr.s_addr; - if (inet_lnaof(su->sin.sin_addr) != INADDR_ANY) - return 1; - else { - val = ntohl(val); - goto netdone; - } - } - if ((val = inet_network(s)) != INADDR_NONE || - ((np = getnetbyname(s)) != NULL && (val = np->n_net) != 0)) { -netdone: - if (which == RTA_DST) - inet_makenetandmask(val, &su->sin, soup); - return 0; - } - hp = gethostbyname(s); - if (hp) { - *hpp = hp; - su->sin.sin_family = hp->h_addrtype; - memmove(&su->sin.sin_addr, hp->h_addr, hp->h_length); - return 1; - } - errx(EXIT_FAILURE, "%s: bad value", s); - /*NOTREACHED*/ -} - -#ifndef SMALL -static sup -readtag(sup su, const char *s) -{ - char *p, *n, *norig; - int mplssize = 0; - sup retsu = su; - - n = strdup(s); - if (n == NULL) - errx(EXIT_FAILURE, "%s: Cannot allocate memory", s); - norig = n; - for (uint i = 0; i < strlen(n); i++) - if(n[i] == ',') - mplssize++; - -#define MPLS_NEW_SIZE (sizeof(struct sockaddr_mpls) + \ - mplssize * sizeof(union mpls_shim)) - - if (mplssize != 0 && sizeof(union sockunion) < MPLS_NEW_SIZE) { - free(su); - retsu = malloc(MPLS_NEW_SIZE); - retsu->smpls.smpls_family = AF_MPLS; - } - retsu->smpls.smpls_len = MPLS_NEW_SIZE; - mplssize = 0; - while ((p = strchr(n, ',')) != NULL) { - p[0] = '\0'; - addtag(retsu, n, mplssize); - n = p + 1; - mplssize++; - } - addtag(retsu, n, mplssize); - - free(norig); - return retsu; -} - -static void -addtag(sup su, const char *s, int where) -{ - union mpls_shim *ms = &su->smpls.smpls_addr; - - if (atoi(s) < 0 || atoi(s) >= (1 << 20)) - errx(EXIT_FAILURE, "%s: Bad tag", s); - ms[where].s_addr = 0; - ms[where].shim.label = atoi(s); - ms[where].s_addr = htonl(ms[where].s_addr); -} -#endif /* SMALL */ - -int -prefixlen(const char *s, struct sou *soup) -{ - int max, len = atoi(s); -#ifdef INET6 - int q, r; -#endif - - switch (af) { - case AF_INET: - max = sizeof(struct in_addr) * 8; - break; -#ifdef INET6 - case AF_INET6: - max = sizeof(struct in6_addr) * 8; - break; -#endif - default: - errx(EXIT_FAILURE, "prefixlen is not supported with af %d", af); - /*NOTREACHED*/ - } - - rtm_addrs |= RTA_NETMASK; - if (len < -1 || len > max) - errx(EXIT_FAILURE, "%s: bad value", s); - -#ifdef INET6 - q = len >> 3; - r = len & 7; -#endif - switch (af) { - case AF_INET: - memset(soup->so_mask, 0, sizeof(*soup->so_mask)); - soup->so_mask->sin.sin_family = AF_INET; - soup->so_mask->sin.sin_len = sizeof(struct sockaddr_in); - soup->so_mask->sin.sin_addr.s_addr = (len == 0 ? 0 - : htonl(0xffffffff << (32 - len))); - break; -#ifdef INET6 - case AF_INET6: - soup->so_mask->sin6.sin6_family = AF_INET6; - soup->so_mask->sin6.sin6_len = sizeof(struct sockaddr_in6); - memset(&soup->so_mask->sin6.sin6_addr, 0, - sizeof(soup->so_mask->sin6.sin6_addr)); - if (q > 0) - memset(&soup->so_mask->sin6.sin6_addr, 0xff, q); - if (r > 0) - *((u_char *)&soup->so_mask->sin6.sin6_addr + q) = - (0xff00 >> r) & 0xff; - break; -#endif - } - return len == max; -} - -#ifndef SMALL -static void -interfaces(void) -{ - size_t needed; - int mib[6]; - char *buf, *lim, *next; - struct rt_msghdr *rtm; - - mib[0] = CTL_NET; - mib[1] = PF_ROUTE; - mib[2] = 0; /* protocol */ - mib[3] = 0; /* wildcard address family */ - mib[4] = NET_RT_IFLIST; - mib[5] = 0; /* no flags */ - if (prog_sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) - err(EXIT_FAILURE, "route-sysctl-estimate"); - if (needed) { - if ((buf = malloc(needed)) == NULL) - err(EXIT_FAILURE, "malloc"); - if (prog_sysctl(mib, 6, buf, &needed, NULL, 0) < 0) { - err(EXIT_FAILURE, - "actual retrieval of interface table"); - } - lim = buf + needed; - for (next = buf; next < lim; next += rtm->rtm_msglen) { - rtm = (struct rt_msghdr *)next; - print_rtmsg(rtm, rtm->rtm_msglen); - } - free(buf); - } -} - -static void -monitor(void) -{ - int n; - union { - char msg[2048]; - struct rt_msghdr hdr; - } u; - - verbose = 1; - if (debugonly) { - interfaces(); - exit(0); - } - for(;;) { - time_t now; - n = prog_read(sock, &u, sizeof(u)); - now = time(NULL); - (void)printf("got message of size %d on %s", n, ctime(&now)); - print_rtmsg(&u.hdr, n); - } -} - -#endif /* SMALL */ - - -struct { - struct rt_msghdr m_rtm; - char m_space[512]; -} m_rtmsg; - -static int -rtmsg(int cmd, int flags, struct sou *soup) -{ - static int seq; - int rlen; - char *cp = m_rtmsg.m_space; - int l; - -#define NEXTADDR(w, u) \ - if (rtm_addrs & (w)) {\ - l = RT_ROUNDUP(u->sa.sa_len); memmove(cp, u, l); cp += l;\ - if (verbose && ! shortoutput) sodump(u,#u);\ - } - - errno = 0; - memset(&m_rtmsg, 0, sizeof(m_rtmsg)); - if (cmd == 'a') - cmd = RTM_ADD; - else if (cmd == 'c') - cmd = RTM_CHANGE; - else if (cmd == 'g') { -#ifdef SMALL - return -1; -#else /* SMALL */ - cmd = RTM_GET; - if (soup->so_ifp->sa.sa_family == AF_UNSPEC) { - soup->so_ifp->sa.sa_family = AF_LINK; - soup->so_ifp->sa.sa_len = sizeof(struct sockaddr_dl); - rtm_addrs |= RTA_IFP; - } -#endif /* SMALL */ - } else - cmd = RTM_DELETE; -#define rtm m_rtmsg.m_rtm - rtm.rtm_type = cmd; - rtm.rtm_flags = flags; - rtm.rtm_version = RTM_VERSION; - rtm.rtm_seq = ++seq; - rtm.rtm_addrs = rtm_addrs; - rtm.rtm_rmx = rt_metrics; - rtm.rtm_inits = rtm_inits; - - if (rtm_addrs & RTA_NETMASK) - mask_addr(soup); - NEXTADDR(RTA_DST, soup->so_dst); - NEXTADDR(RTA_GATEWAY, soup->so_gate); - NEXTADDR(RTA_NETMASK, soup->so_mask); - NEXTADDR(RTA_GENMASK, soup->so_genmask); - NEXTADDR(RTA_IFP, soup->so_ifp); - NEXTADDR(RTA_IFA, soup->so_ifa); -#ifndef SMALL - NEXTADDR(RTA_TAG, soup->so_mpls); -#endif - rtm.rtm_msglen = l = cp - (char *)&m_rtmsg; - if (verbose && ! shortoutput) { - if (rtm_addrs) - putchar('\n'); - print_rtmsg(&rtm, l); - } - if (debugonly) - return 0; - if ((rlen = prog_write(sock, (char *)&m_rtmsg, l)) < 0) { - warnx("writing to routing socket: %s", route_strerror(errno)); - return -1; - } - if (rlen < l) { - warnx("write to routing socket, got %d for rlen", rlen); - return 1; - } -#ifndef SMALL - if (cmd == RTM_GET) { - do { - l = prog_read(sock, - (char *)&m_rtmsg, sizeof(m_rtmsg)); - } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid)); - if (l < 0) - err(EXIT_FAILURE, "read from routing socket"); - else - return print_getmsg(&rtm, l, soup); - } -#endif /* SMALL */ -#undef rtm - return 0; -} - -static void -mask_addr(struct sou *soup) -{ - int olen = soup->so_mask->sa.sa_len; - char *cp1 = olen + (char *)soup->so_mask, *cp2; - - for (soup->so_mask->sa.sa_len = 0; cp1 > (char *)soup->so_mask; ) - if (*--cp1 != 0) { - soup->so_mask->sa.sa_len = 1 + cp1 - (char *)soup->so_mask; - break; - } - if ((rtm_addrs & RTA_DST) == 0) - return; - switch (soup->so_dst->sa.sa_family) { - case AF_INET: -#ifdef INET6 - case AF_INET6: -#endif -#ifndef SMALL - case AF_APPLETALK: -#endif /* SMALL */ - case 0: - return; - } - cp1 = soup->so_mask->sa.sa_len + 1 + (char *)soup->so_dst; - cp2 = soup->so_dst->sa.sa_len + 1 + (char *)soup->so_dst; - while (cp2 > cp1) - *--cp2 = 0; - cp2 = soup->so_mask->sa.sa_len + 1 + (char *)soup->so_mask; - while (cp1 > soup->so_dst->sa.sa_data) - *--cp1 &= *--cp2; -} - -const char * const msgtypes[] = { - [RTM_ADD] = "RTM_ADD: Add Route", - [RTM_DELETE] = "RTM_DELETE: Delete Route", - [RTM_CHANGE] = "RTM_CHANGE: Change Metrics, Flags or Gateway", - [RTM_GET] = "RTM_GET: Report Metrics", - [RTM_LOSING] = "RTM_LOSING: Kernel Suspects Partitioning", - [RTM_REDIRECT] = "RTM_REDIRECT: Told to use different route", - [RTM_MISS] = "RTM_MISS: Lookup failed on this address", - [RTM_LOCK] = "RTM_LOCK: fix specified metrics", - [RTM_OLDADD] = "RTM_OLDADD: caused by SIOCADDRT", - [RTM_OLDDEL] = "RTM_OLDDEL: caused by SIOCDELRT", - [RTM_RESOLVE] = "RTM_RESOLVE: Route created by cloning", - [RTM_NEWADDR] = "RTM_NEWADDR: address being added to iface", - [RTM_DELADDR] = "RTM_DELADDR: address being removed from iface", - [RTM_OOIFINFO] = "RTM_OOIFINFO: iface status change (pre-1.5)", - [RTM_OIFINFO] = "RTM_OIFINFO: iface status change (pre-64bit time)", - [RTM_IFANNOUNCE] = "RTM_IFANNOUNCE: iface arrival/departure", - [RTM_IEEE80211] = "RTM_IEEE80211: IEEE80211 wireless event", - [RTM_IFINFO] = "RTM_IFINFO: iface status change", - [RTM_CHGADDR] = "RTM_CHGADDR: address being changed on iface", -}; - -const char metricnames[] = -"\011pksent\010rttvar\7rtt\6ssthresh\5sendpipe\4recvpipe\3expire\2hopcount\1mtu"; -const char routeflags[] = -"\1UP\2GATEWAY\3HOST\4REJECT\5DYNAMIC\6MODIFIED\7DONE\010MASK_PRESENT\011CLONING\012XRESOLVE\013LLINFO\014STATIC\015BLACKHOLE\016CLONED\017PROTO2\020PROTO1\023LOCAL\024BROADCAST"; -const char ifnetflags[] = -"\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5PTP\6NOTRAILERS\7RUNNING\010NOARP\011PPROMISC\012ALLMULTI\013OACTIVE\014SIMPLEX\015LINK0\016LINK1\017LINK2\020MULTICAST"; -const char addrnames[] = -"\1DST\2GATEWAY\3NETMASK\4GENMASK\5IFP\6IFA\7AUTHOR\010BRD\011TAG"; - - -#ifndef SMALL -static const char * -linkstate(struct if_msghdr *ifm) -{ - static char buf[64]; - - switch (ifm->ifm_data.ifi_link_state) { - case LINK_STATE_UNKNOWN: - return "carrier: unknown"; - case LINK_STATE_DOWN: - return "carrier: no carrier"; - case LINK_STATE_UP: - return "carrier: active"; - default: - (void)snprintf(buf, sizeof(buf), "carrier: 0x%x", - ifm->ifm_data.ifi_link_state); - return buf; - } -} -#endif /* SMALL */ - -static void -print_rtmsg(struct rt_msghdr *rtm, int msglen) -{ - struct if_msghdr *ifm; - struct ifa_msghdr *ifam; - struct if_announcemsghdr *ifan; - union { - struct ieee80211_join_event join; - struct ieee80211_leave_event leave; - struct ieee80211_replay_event replay; - struct ieee80211_michael_event michael; - } ev; - size_t evlen = 0; - - if (verbose == 0) - return; - if (rtm->rtm_version != RTM_VERSION) { - (void)printf("routing message version %d not understood\n", - rtm->rtm_version); - return; - } - if (msgtypes[rtm->rtm_type]) - (void)printf("%s: ", msgtypes[rtm->rtm_type]); - else - (void)printf("#%d: ", rtm->rtm_type); - (void)printf("len %d, ", rtm->rtm_msglen); - switch (rtm->rtm_type) { - case RTM_IFINFO: - ifm = (struct if_msghdr *)rtm; - (void)printf("if# %d, %s, flags: ", ifm->ifm_index, -#ifdef SMALL - "" -#else - linkstate(ifm) -#endif /* SMALL */ - ); - bprintf(stdout, ifm->ifm_flags, ifnetflags); - pmsg_addrs((char *)(ifm + 1), ifm->ifm_addrs); - break; - case RTM_NEWADDR: - case RTM_DELADDR: - case RTM_CHGADDR: - ifam = (struct ifa_msghdr *)rtm; - (void)printf("metric %d, flags: ", ifam->ifam_metric); - bprintf(stdout, ifam->ifam_flags, routeflags); - pmsg_addrs((char *)(ifam + 1), ifam->ifam_addrs); - break; - case RTM_IEEE80211: - ifan = (struct if_announcemsghdr *)rtm; - (void)printf("if# %d, what: ", ifan->ifan_index); - switch (ifan->ifan_what) { - case RTM_IEEE80211_ASSOC: - printf("associate"); - break; - case RTM_IEEE80211_REASSOC: - printf("re-associate"); - break; - case RTM_IEEE80211_DISASSOC: - printf("disassociate"); - break; - case RTM_IEEE80211_SCAN: - printf("scan complete"); - break; - case RTM_IEEE80211_JOIN: - evlen = sizeof(ev.join); - printf("join"); - break; - case RTM_IEEE80211_LEAVE: - evlen = sizeof(ev.leave); - printf("leave"); - break; - case RTM_IEEE80211_MICHAEL: - evlen = sizeof(ev.michael); - printf("michael"); - break; - case RTM_IEEE80211_REPLAY: - evlen = sizeof(ev.replay); - printf("replay"); - break; - default: - evlen = 0; - printf("#%d", ifan->ifan_what); - break; - } - if (sizeof(*ifan) + evlen > ifan->ifan_msglen) { - printf(" (truncated)\n"); - break; - } - (void)memcpy(&ev, (ifan + 1), evlen); - switch (ifan->ifan_what) { - case RTM_IEEE80211_JOIN: - case RTM_IEEE80211_LEAVE: - printf(" mac %" PRIETHER, - PRIETHER_ARGS(ev.join.iev_addr)); - break; - case RTM_IEEE80211_REPLAY: - case RTM_IEEE80211_MICHAEL: - printf(" src %" PRIETHER " dst %" PRIETHER - " cipher %" PRIu8 " keyix %" PRIu8, - PRIETHER_ARGS(ev.replay.iev_src), - PRIETHER_ARGS(ev.replay.iev_dst), - ev.replay.iev_cipher, - ev.replay.iev_keyix); - if (ifan->ifan_what == RTM_IEEE80211_REPLAY) { - printf(" key rsc %#" PRIx64 - " frame rsc %#" PRIx64, - ev.replay.iev_keyrsc, ev.replay.iev_rsc); - } - break; - default: - break; - } - printf("\n"); - break; - case RTM_IFANNOUNCE: - ifan = (struct if_announcemsghdr *)rtm; - (void)printf("if# %d, what: ", ifan->ifan_index); - switch (ifan->ifan_what) { - case IFAN_ARRIVAL: - printf("arrival"); - break; - case IFAN_DEPARTURE: - printf("departure"); - break; - default: - printf("#%d", ifan->ifan_what); - break; - } - printf("\n"); - break; - default: - (void)printf("pid %d, seq %d, errno %d, flags: ", - rtm->rtm_pid, rtm->rtm_seq, rtm->rtm_errno); - bprintf(stdout, rtm->rtm_flags, routeflags); - pmsg_common(rtm); - } -} - -#ifndef SMALL -static int -print_getmsg(struct rt_msghdr *rtm, int msglen, struct sou *soup) -{ - struct sockaddr *dst = NULL, *gate = NULL, *mask = NULL, *ifa = NULL, *mpls = NULL; - struct sockaddr_dl *ifp = NULL; - struct sockaddr *sa; - char *cp; - int i; - - if (! shortoutput) { - (void)printf(" route to: %s\n", - routename(&soup->so_dst->sa, nflag)); - } - if (rtm->rtm_version != RTM_VERSION) { - warnx("routing message version %d not understood", - rtm->rtm_version); - return 1; - } - if (rtm->rtm_msglen > msglen) { - warnx("message length mismatch, in packet %d, returned %d", - rtm->rtm_msglen, msglen); - } - if (rtm->rtm_errno) { - warnx("RTM_GET: %s (errno %d)", - strerror(rtm->rtm_errno), rtm->rtm_errno); - return 1; - } - cp = ((char *)(rtm + 1)); - if (rtm->rtm_addrs) - for (i = 1; i; i <<= 1) - if (i & rtm->rtm_addrs) { - sa = (struct sockaddr *)cp; - switch (i) { - case RTA_DST: - dst = sa; - break; - case RTA_GATEWAY: - gate = sa; - break; - case RTA_NETMASK: - mask = sa; - break; - case RTA_IFP: - if (sa->sa_family == AF_LINK && - ((struct sockaddr_dl *)sa)->sdl_nlen) - ifp = (struct sockaddr_dl *)sa; - break; - case RTA_IFA: - ifa = sa; - break; - case RTA_TAG: - mpls = sa; - break; - } - RT_ADVANCE(cp, sa); - } - if (dst && mask) - mask->sa_family = dst->sa_family; /* XXX */ - if (dst && ! shortoutput) - (void)printf("destination: %s\n", - routename(dst, nflag)); - if (mask && ! shortoutput) { - int savenflag = nflag; - - nflag = RT_NFLAG; - (void)printf(" mask: %s\n", - routename(mask, nflag)); - nflag = savenflag; - } - if (gate && rtm->rtm_flags & RTF_GATEWAY) { - const char *name; - - name = routename(gate, nflag); - if (shortoutput) { - if (*name == '\0') - return 1; - (void)printf("%s\n", name); - } else - (void)printf(" gateway: %s\n", name); - } - if (mpls) { - const char *name; - name = routename(mpls, nflag); - if(shortoutput) { - if (*name == '\0') - return 1; - printf("%s\n", name); - } else - printf(" Tag: %s\n", name); - } - - if (ifa && ! shortoutput) - (void)printf(" local addr: %s\n", - routename(ifa, nflag)); - if (ifp && ! shortoutput) - (void)printf(" interface: %.*s\n", - ifp->sdl_nlen, ifp->sdl_data); - if (! shortoutput) { - (void)printf(" flags: "); - bprintf(stdout, 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 */ - - if (! shortoutput) { - (void)printf("\n%s\n", "\ - recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire"); - printf("%8"PRId64"%c ", rtm->rtm_rmx.rmx_recvpipe, lock(RPIPE)); - printf("%8"PRId64"%c ", rtm->rtm_rmx.rmx_sendpipe, lock(SPIPE)); - printf("%8"PRId64"%c ", rtm->rtm_rmx.rmx_ssthresh, lock(SSTHRESH)); - printf("%8"PRId64"%c ", msec(rtm->rtm_rmx.rmx_rtt), lock(RTT)); - printf("%8"PRId64"%c ", msec(rtm->rtm_rmx.rmx_rttvar), lock(RTTVAR)); - printf("%8"PRId64"%c ", rtm->rtm_rmx.rmx_hopcount, lock(HOPCOUNT)); - printf("%8"PRId64"%c ", rtm->rtm_rmx.rmx_mtu, lock(MTU)); - if (rtm->rtm_rmx.rmx_expire) - rtm->rtm_rmx.rmx_expire -= time(0); - printf("%8"PRId64"%c\n", rtm->rtm_rmx.rmx_expire, lock(EXPIRE)); - } -#undef lock -#undef msec -#define RTA_IGN (RTA_DST|RTA_GATEWAY|RTA_NETMASK|RTA_IFP|RTA_IFA|RTA_BRD) - - if (shortoutput) - return (rtm->rtm_addrs & RTF_GATEWAY) == 0; - else if (verbose) - pmsg_common(rtm); - else if (rtm->rtm_addrs &~ RTA_IGN) { - (void)printf("sockaddrs: "); - bprintf(stdout, rtm->rtm_addrs, addrnames); - putchar('\n'); - } - return 0; -#undef RTA_IGN -} -#endif /* SMALL */ - -void -pmsg_common(struct rt_msghdr *rtm) -{ - (void)printf("\nlocks: "); - bprintf(stdout, rtm->rtm_rmx.rmx_locks, metricnames); - (void)printf(" inits: "); - bprintf(stdout, rtm->rtm_inits, metricnames); - pmsg_addrs((char *)(rtm + 1), rtm->rtm_addrs); -} - -static void -extract_addrs(const char *cp, int addrs, const struct sockaddr *sa[], int *nmfp) -{ - int i, nmf = -1; - - for (i = 0; i < RTAX_MAX; i++) { - if ((1 << i) & addrs) { - sa[i] = (const struct sockaddr *)cp; - if ((i == RTAX_DST || i == RTAX_IFA) && - nmf == -1) - nmf = sa[i]->sa_family; - RT_ADVANCE(cp, sa[i]); - } else - sa[i] = NULL; - } - - if (nmfp != NULL) - *nmfp = nmf; -} - -static void -pmsg_addrs(const char *cp, int addrs) -{ - const struct sockaddr *sa[RTAX_MAX]; - int i, nmf; - - if (addrs != 0) { - (void)printf("\nsockaddrs: "); - bprintf(stdout, addrs, addrnames); - (void)putchar('\n'); - extract_addrs(cp, addrs, sa, &nmf); - for (i = 0; i < RTAX_MAX; i++) { - if (sa[i] == NULL) - continue; - - if (i == RTAX_NETMASK && sa[i]->sa_len) - (void)printf(" %s", - netmask_string(sa[i], -1, nmf)); - else - (void)printf(" %s", - routename(sa[i], nflag)); - } - } - (void)putchar('\n'); - (void)fflush(stdout); -} - -static void -bprintf(FILE *fp, int b, const char *f) -{ - int i; - int gotsome = 0; - const uint8_t *s = (const uint8_t *)f; - - if (b == 0) { - fputs("none", fp); - return; - } - while ((i = *s++) != 0) { - if (b & (1 << (i-1))) { - if (gotsome == 0) - i = '<'; - else - i = ','; - (void)putc(i, fp); - gotsome = 1; - for (; (i = *s) > 32; s++) - (void)putc(i, fp); - } else - while (*s > 32) - s++; - } - if (gotsome) - (void)putc('>', fp); -} - -int -keyword(const char *cp) -{ - struct keytab *kt = keywords; - - while (kt->kt_cp && strcmp(kt->kt_cp, cp)) - kt++; - return kt->kt_i; -} - -static void -sodump(sup su, const char *which) -{ -#ifdef INET6 - char ntop_buf[NI_MAXHOST]; -#endif - - switch (su->sa.sa_family) { - case AF_INET: - (void)printf("%s: inet %s; ", - which, inet_ntoa(su->sin.sin_addr)); - break; -#ifndef SMALL - case AF_APPLETALK: - (void)printf("%s: atalk %d.%d; ", - which, su->sat.sat_addr.s_net, su->sat.sat_addr.s_node); - break; -#endif - case AF_LINK: - (void)printf("%s: link %s; ", - which, link_ntoa(&su->sdl)); - break; -#ifdef INET6 - case AF_INET6: - (void)printf("%s: inet6 %s; ", - which, inet_ntop(AF_INET6, &su->sin6.sin6_addr, - ntop_buf, sizeof(ntop_buf))); - break; -#endif -#ifndef SMALL - case AF_MPLS: - { - union mpls_shim ms; - const union mpls_shim *pms; - int psize = sizeof(struct sockaddr_mpls); - - ms.s_addr = ntohl(su->smpls.smpls_addr.s_addr); - printf("%s: mpls %u; ", - which, ms.shim.label); - - pms = &su->smpls.smpls_addr; - while(psize < su->smpls.smpls_len) { - pms++; - ms.s_addr = ntohl(pms->s_addr); - printf("%u; ", ms.shim.label); - psize += sizeof(ms); - } - break; - } -#endif /* SMALL */ - default: - (void)printf("%s: (%d) %s; ", - which, su->sa.sa_family, any_ntoa(&su->sa)); - } - (void)fflush(stdout); -} - -/* States*/ -#define VIRGIN 0 -#define GOTONE 1 -#define GOTTWO 2 -/* Inputs */ -#define DIGIT (4*0) -#define END (4*1) -#define DELIM (4*2) - -static void -sockaddr(const char *addr, struct sockaddr *sa) -{ - char *cp = (char *)sa; - int size = sa->sa_len; - char *cplim = cp + size; - int byte = 0, state = VIRGIN, new = 0; - - (void)memset(cp, 0, size); - cp++; - do { - if ((*addr >= '0') && (*addr <= '9')) { - new = *addr - '0'; - } else if ((*addr >= 'a') && (*addr <= 'f')) { - new = *addr - 'a' + 10; - } else if ((*addr >= 'A') && (*addr <= 'F')) { - new = *addr - 'A' + 10; - } else if (*addr == 0) - state |= END; - else - state |= DELIM; - addr++; - switch (state /* | INPUT */) { - case GOTTWO | DIGIT: - *cp++ = byte; /*FALLTHROUGH*/ - case VIRGIN | DIGIT: - state = GOTONE; byte = new; continue; - case GOTONE | DIGIT: - state = GOTTWO; byte = new + (byte << 4); continue; - default: /* | DELIM */ - state = VIRGIN; *cp++ = byte; byte = 0; continue; - case GOTONE | END: - case GOTTWO | END: - *cp++ = byte; /* FALLTHROUGH */ - case VIRGIN | END: - break; - } - break; - } while (cp < cplim); - sa->sa_len = cp - (char *)sa; -} diff --git a/sbin/route/route_hostops.c b/sbin/route/route_hostops.c deleted file mode 100644 index 4597fa3f7..000000000 --- a/sbin/route/route_hostops.c +++ /dev/null @@ -1,54 +0,0 @@ -/* $NetBSD: route_hostops.c,v 1.1 2010/12/13 17:39:47 pooka Exp $ */ - -/* - * Copyright (c) 2010 The NetBSD Foundation, Inc. - * 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 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. - */ - -#include -#ifndef lint -__RCSID("$NetBSD: route_hostops.c,v 1.1 2010/12/13 17:39:47 pooka Exp $"); -#endif /* !lint */ - -#include -#include -#include - -#include -#include - -#include "prog_ops.h" - -const struct prog_ops prog_ops = { - .op_socket = socket, - .op_open = open, - .op_getpid = getpid, - - .op_read = read, - .op_write = write, - - .op_sysctl = sysctl, - - .op_shutdown = shutdown, -}; diff --git a/sbin/route/route_rumpops.c b/sbin/route/route_rumpops.c deleted file mode 100644 index 76e7e5b4d..000000000 --- a/sbin/route/route_rumpops.c +++ /dev/null @@ -1,58 +0,0 @@ -/* $NetBSD: route_rumpops.c,v 1.1 2010/12/13 17:39:47 pooka Exp $ */ - -/* - * Copyright (c) 2010 The NetBSD Foundation, Inc. - * 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 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. - */ - -#include -#ifndef lint -__RCSID("$NetBSD: route_rumpops.c,v 1.1 2010/12/13 17:39:47 pooka Exp $"); -#endif /* !lint */ - -#include -#include - -#include - -#include -#include -#include - -#include "prog_ops.h" - -const struct prog_ops prog_ops = { - .op_init = rumpclient_init, - - .op_socket = rump_sys_socket, - .op_open = rump_sys_open, - .op_getpid = rump_sys_getpid, - - .op_read = rump_sys_read, - .op_write = rump_sys_write, - - .op_sysctl = rump_sys___sysctl, - - .op_shutdown = rump_sys_shutdown, -}; diff --git a/sbin/route/rtutil.c b/sbin/route/rtutil.c deleted file mode 100644 index f7cfbacfb..000000000 --- a/sbin/route/rtutil.c +++ /dev/null @@ -1,806 +0,0 @@ -/* $NetBSD: rtutil.c,v 1.6 2015/03/23 18:33:17 roy Exp $ */ -/* $OpenBSD: show.c,v 1.1 2006/05/27 19:16:37 claudio Exp $ */ - -/* - * Copyright (c) 1983, 1988, 1993 - * The Regents of the University of California. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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 -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "prog_ops.h" -#include "rtutil.h" - - -#define PLEN (LONG_BIT / 4 + 2) -#define PFKEYV2_CHUNK sizeof(u_int64_t) -static char *link_print(const struct sockaddr *); - -/* - * Definitions for showing gateway flags. - */ -struct bits { - int b_mask; - char b_val; -}; -static const struct bits bits[] = { - { RTF_UP, 'U' }, - { RTF_GATEWAY, 'G' }, - { RTF_HOST, 'H' }, - { RTF_REJECT, 'R' }, - { RTF_BLACKHOLE, 'B' }, - { RTF_DYNAMIC, 'D' }, - { RTF_MODIFIED, 'M' }, - { RTF_DONE, 'd' }, /* Completed -- for routing messages only */ - { RTF_MASK, 'm' }, /* Mask Present -- for routing messages only */ - { RTF_CLONING, 'C' }, - { RTF_XRESOLVE, 'X' }, - { RTF_LLINFO, 'L' }, - { RTF_STATIC, 'S' }, - { RTF_PROTO1, '1' }, - { RTF_PROTO2, '2' }, - /* { RTF_PROTO3, '3' }, */ - { RTF_CLONED, 'c' }, - /* { RTF_JUMBO, 'J' }, */ - { RTF_ANNOUNCE, 'p' }, - { RTF_LOCAL, 'l'}, - { RTF_BROADCAST, 'b'}, - { 0, 0 } -}; - -#ifndef SMALL -static void p_tag(const struct sockaddr *sa); -#endif -static void p_rtentry(struct rt_msghdr *, int, int); - -/* - * Print routing tables. - */ -void -p_rttables(int paf, int flags, int pflags, int interesting) -{ - struct rt_msghdr *rtm; - char *buf = NULL, *next, *lim = NULL; - size_t needed; - int mib[6]; - struct sockaddr *sa; - - mib[0] = CTL_NET; - mib[1] = PF_ROUTE; - mib[2] = 0; - mib[3] = paf; - mib[4] = NET_RT_DUMP; - mib[5] = 0; - if (prog_sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) - err(1, "route-sysctl-estimate"); - if (needed > 0) { - if ((buf = malloc(needed)) == 0) - err(1, NULL); - if (prog_sysctl(mib, 6, buf, &needed, NULL, 0) < 0) - err(1, "sysctl of routing table"); - lim = buf + needed; - } - - printf("Routing tables\n"); - - if (buf) { - for (next = buf; next < lim; next += rtm->rtm_msglen) { - rtm = (struct rt_msghdr *)next; - sa = (struct sockaddr *)(rtm + 1); - if ((rtm->rtm_flags & pflags) != pflags) - continue; - if (paf != AF_UNSPEC && sa->sa_family != paf) - continue; - p_rtentry(rtm, flags, interesting); - } - free(buf); - buf = NULL; - } - - if (paf != 0 && paf != PF_KEY) - return; - -#if 0 /* XXX-elad */ - mib[0] = CTL_NET; - mib[1] = PF_KEY; - mib[2] = PF_KEY_V2; - mib[3] = NET_KEY_SPD_DUMP; - mib[4] = mib[5] = 0; - - if (prog_sysctl(mib, 4, NULL, &needed, NULL, 0) == -1) { - if (errno == ENOPROTOOPT) - return; - err(1, "spd-sysctl-estimate"); - } - if (needed > 0) { - if ((buf = malloc(needed)) == 0) - err(1, NULL); - if (prog_sysctl(mib, 4, buf, &needed, NULL, 0) == -1) - err(1,"sysctl of spd"); - lim = buf + needed; - } - - if (buf) { - printf("\nEncap:\n"); - - for (next = buf; next < lim; next += msg->sadb_msg_len * - PFKEYV2_CHUNK) { - msg = (struct sadb_msg *)next; - if (msg->sadb_msg_len == 0) - break; - p_pfkentry(msg); - } - free(buf); - buf = NULL; - } -#endif /* 0 */ -} - -/* - * column widths; each followed by one space - * width of destination/gateway column - * strlen("fe80::aaaa:bbbb:cccc:dddd@gif0") == 30, strlen("/128") == 4 = 34 - * strlen("aaaa:bbbb:cccc:dddd:eeee:ffff:gggg:hhhh") == 39 - */ -#ifndef INET6 -#define WID_DST(af) 18 /* width of destination column */ -#define WID_GW(af) 18 /* width of gateway column */ -#else -#define WID_DST(af) ((af) == AF_INET6 ? ((flags & RT_NFLAG) ? 39 : 18) : 18) -#define WID_GW(af) ((af) == AF_INET6 ? ((flags & RT_NFLAG) ? 30 : 18) : 18) -#endif - -/* - * Print header for routing table columns. - */ -void -p_rthdr(int paf, int flags) -{ -#ifndef SMALL - if (flags & RT_AFLAG) - printf("%-*.*s ", PLEN, PLEN, "Address"); - if (paf == PF_KEY) { - printf("%-18s %-5s %-18s %-5s %-5s %-22s\n", - "Source", "Port", "Destination", - "Port", "Proto", "SA(Address/Proto/Type/Direction)"); - return; - } - if (flags & RT_TFLAG) { - printf("%-*.*s %-*.*s %-6.6s %6.6s %8.8s %6.6s %7.7s" - " %s\n", WID_DST(paf), WID_DST(paf), "Destination", - WID_GW(paf), WID_GW(paf), "Gateway", - "Flags", "Refs", "Use", "Mtu", "Tag", "Interface"); - return; - } -#endif -#ifndef SMALL - printf("%-*.*s %-*.*s %-6.6s %6.6s %8.8s %6.6s %s\n", - WID_DST(paf), WID_DST(paf), "Destination", - WID_GW(paf), WID_GW(paf), "Gateway", - "Flags", "Refs", "Use", "Mtu", "Interface"); -#else - printf("%-*.*s %-*.*s %-6.6s\n", - WID_DST(paf), WID_DST(paf), "Destination", - WID_GW(paf), WID_GW(paf), "Gateway", - "Flags"); -#endif -} - -static void -get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info) -{ - int i; - - for (i = 0; i < RTAX_MAX; i++) { - if (addrs & (1 << i)) { - rti_info[i] = sa; - sa = (struct sockaddr *)((char *)(sa) + - RT_ROUNDUP(sa->sa_len)); - } else - rti_info[i] = NULL; - } -} - -/* - * Print a routing table entry. - */ -static void -p_rtentry(struct rt_msghdr *rtm, int flags, int interesting) -{ - static int old_af = -1; - struct sockaddr *sa = (struct sockaddr *)(rtm + 1); - struct sockaddr *mask, *rti_info[RTAX_MAX]; -#ifndef SMALL - char ifbuf[IF_NAMESIZE]; -#endif - - if ((flags & RT_LFLAG) && (rtm->rtm_flags & RTF_LLINFO)) - return; - - if (old_af != sa->sa_family) { - old_af = sa->sa_family; - p_family(sa->sa_family); - p_rthdr(sa->sa_family, flags); - } - get_rtaddrs(rtm->rtm_addrs, sa, rti_info); - - mask = rti_info[RTAX_NETMASK]; - if ((sa = rti_info[RTAX_DST]) == NULL) - return; - - p_sockaddr(sa, mask, rtm->rtm_flags, WID_DST(sa->sa_family), flags); - p_sockaddr(rti_info[RTAX_GATEWAY], NULL, RTF_HOST, - WID_GW(sa->sa_family), flags); - p_flags(rtm->rtm_flags & interesting); -#if 0 /* XXX-elad */ - printf("%6d %8"PRId64" ", (int)rtm->rtm_rmx.rmx_refcnt, - rtm->rtm_rmx.rmx_pksent); -#else - printf("%6s %8s ", "-", "-"); -#endif -#ifndef SMALL - if (rtm->rtm_rmx.rmx_mtu) - printf("%6"PRId64, rtm->rtm_rmx.rmx_mtu); - else - printf("%6s", "-"); - putchar((rtm->rtm_rmx.rmx_locks & RTV_MTU) ? 'L' : ' '); - if (flags & RT_TFLAG) - p_tag(rti_info[RTAX_TAG]); - printf(" %.16s", if_indextoname(rtm->rtm_index, ifbuf)); - putchar('\n'); - if (flags & RT_VFLAG) - p_rtrmx(&rtm->rtm_rmx); -#endif -} - -/* - * Print address family header before a section of the routing table. - */ -void -p_family(int paf) -{ - const char *afname; - - switch (paf) { - case AF_INET: - afname = "Internet"; - break; -#ifdef INET6 - case AF_INET6: - afname = "Internet6"; - break; -#endif - case PF_KEY: - afname = "Encap"; - break; - case AF_APPLETALK: - afname = "AppleTalk"; - break; -#ifndef SMALL - case AF_MPLS: - afname = "MPLS"; - break; -#endif - default: - afname = NULL; - break; - } - if (afname) - printf("\n%s:\n", afname); - else - printf("\nProtocol Family %d:\n", paf); -} - -void -p_sockaddr(const struct sockaddr *sa, const struct sockaddr *mask, int rflags, - int width, int flags) -{ - char *cp; - - switch (sa->sa_family) { -#ifdef INET6 - case AF_INET6: - { - struct sockaddr_in6 sa6 = *(const struct sockaddr_in6 *)sa; - - inet6_getscopeid(&sa6, INET6_IS_ADDR_LINKLOCAL| - INET6_IS_ADDR_MC_LINKLOCAL); - if (rflags & RTF_HOST) - cp = routename((const struct sockaddr *)&sa6, flags); - else - cp = netname((const struct sockaddr *)&sa6, mask, flags); - break; - } -#endif - default: - if ((rflags & RTF_HOST) || mask == NULL) - cp = routename(sa, flags); - else - cp = netname(sa, mask, flags); - break; - } - if (width < 0) - printf("%s", cp); - else { - if (flags & RT_NFLAG) - printf("%-*s ", width, cp); - else - printf("%-*.*s ", width, width, cp); - } -} - -void -p_flags(int f) -{ - char name[33], *flags; - const struct bits *p = bits; - - for (flags = name; p->b_mask && flags < &name[sizeof(name) - 2]; p++) - if (p->b_mask & f) - *flags++ = p->b_val; - *flags = '\0'; - printf("%-6.6s ", name); -} - -#ifndef SMALL -void -p_rtrmx(const struct rt_metrics *rmx) -{ - printf("\texpire %10"PRId64"%c recvpipe %10"PRIu64"%c " - "sendpipe %10"PRIu64"%c\n", - (int64_t)rmx->rmx_expire, - (rmx->rmx_locks & RTV_EXPIRE) ? 'L' : ' ', rmx->rmx_recvpipe, - (rmx->rmx_locks & RTV_RPIPE) ? 'L' : ' ', rmx->rmx_sendpipe, - (rmx->rmx_locks & RTV_SPIPE) ? 'L' : ' '); - printf("\tssthresh %10"PRIu64"%c rtt %10"PRIu64"%c " - "rttvar %10"PRIu64"%c\n", rmx->rmx_ssthresh, - (rmx->rmx_locks & RTV_SSTHRESH) ? 'L' : ' ', - rmx->rmx_rtt, (rmx->rmx_locks & RTV_RTT) ? 'L' : ' ', - rmx->rmx_rttvar, (rmx->rmx_locks & RTV_RTTVAR) ? 'L' : ' '); - printf("\thopcount %10"PRIu64"%c\n", - rmx->rmx_hopcount, (rmx->rmx_locks & RTV_HOPCOUNT) ? 'L' : ' '); -} - -static void -p_tag(const struct sockaddr *sa) -{ - char *line; - - if (sa == NULL || sa->sa_family != AF_MPLS) { - printf("%7s", "-"); - return; - } - line = mpls_ntoa(sa); - if (strlen(line) < 7) - printf("%7s", line); - else - printf("%s", line); -} -#endif - -static char line[MAXHOSTNAMELEN]; -static char domain[MAXHOSTNAMELEN]; - -char * -routename(const struct sockaddr *sa, int flags) -{ - char *cp = NULL; - static int first = 1; - - if (first) { - first = 0; - if (gethostname(domain, sizeof(domain)) == 0 && - (cp = strchr(domain, '.'))) - (void)strlcpy(domain, cp + 1, sizeof(domain)); - else - domain[0] = '\0'; - cp = NULL; - } - - if (sa->sa_len == 0) { - (void)strlcpy(line, "default", sizeof(line)); - return (line); - } - - switch (sa->sa_family) { - case AF_INET: - return routename4( - ((const struct sockaddr_in *)sa)->sin_addr.s_addr, - flags); -#ifdef INET6 - case AF_INET6: - { - struct sockaddr_in6 sin6; - - memset(&sin6, 0, sizeof(sin6)); - memcpy(&sin6, sa, sa->sa_len); - sin6.sin6_len = sizeof(struct sockaddr_in6); - sin6.sin6_family = AF_INET6; - if (sa->sa_len == sizeof(struct sockaddr_in6)) -#if defined(__minix) - /* - * Local MINIX3 fix for a NetBSD issue: inet6_getscopeid() - * is sometimes called twice in a row when printing routing - * tables, discarding the scope ID the second time.. - */ - if (sin6.sin6_scope_id == 0) -#endif /* defined(__minix) */ - inet6_getscopeid(&sin6, INET6_IS_ADDR_LINKLOCAL| - INET6_IS_ADDR_MC_LINKLOCAL); - return routename6(&sin6, flags); - } -#endif - case AF_LINK: - return link_print(sa); - -#ifndef SMALL - case AF_MPLS: - return mpls_ntoa(sa); - - case AF_APPLETALK: - (void)snprintf(line, sizeof(line), "atalk %d.%d", - ((const struct sockaddr_at *)sa)->sat_addr.s_net, - ((const struct sockaddr_at *)sa)->sat_addr.s_node); - break; -#endif - -#if 0 /* XXX-elad */ - case AF_UNSPEC: - if (sa->sa_len == sizeof(struct sockaddr_rtlabel)) { - static char name[RTLABEL_LEN]; - struct sockaddr_rtlabel *sr; - - sr = (struct sockaddr_rtlabel *)sa; - strlcpy(name, sr->sr_label, sizeof(name)); - return (name); - } - /* FALLTHROUGH */ -#endif - default: - (void)snprintf(line, sizeof(line), "(%d) %s", - sa->sa_family, any_ntoa(sa)); - break; - } - return (line); -} - -char * -routename4(in_addr_t in, int flags) -{ - const char *cp = NULL; - struct in_addr ina; - struct hostent *hp; - - if (in == INADDR_ANY) - cp = "default"; - if (!cp && (flags & RT_NFLAG) == 0) { - if ((hp = gethostbyaddr((char *)&in, - sizeof(in), AF_INET)) != NULL) { - char *p; - if ((p = strchr(hp->h_name, '.')) && - !strcmp(p + 1, domain)) - *p = '\0'; - cp = hp->h_name; - } - } - ina.s_addr = in; - strlcpy(line, cp ? cp : inet_ntoa(ina), sizeof(line)); - - return (line); -} - -#ifdef INET6 -char * -routename6(const struct sockaddr_in6 *sin6, int flags) -{ - int niflags = 0; - - if ((flags & RT_NFLAG)) - niflags |= NI_NUMERICHOST; - else - niflags |= NI_NOFQDN; - - if (getnameinfo((const struct sockaddr *)sin6, sin6->sin6_len, - line, sizeof(line), NULL, 0, niflags) != 0) - strncpy(line, "invalid", sizeof(line)); - - return (line); -} -#endif - -/* - * Return the name of the network whose address is given. - * The address is assumed to be that of a net or subnet, not a host. - */ -char * -netname4(const struct sockaddr_in* sa4, const struct sockaddr_in *mask, int flags) -{ - const char *cp = NULL; - struct netent *np = NULL; - int mbits; - in_addr_t in = sa4->sin_addr.s_addr; - - if (mask) { - in_addr_t m = mask->sin_addr.s_addr ; - m = ntohl(m); - mbits = m ? 33 - ffs(m) : 0; - } else - mbits = 0; - - in = ntohl(in); - if (in == INADDR_ANY && !mbits) - cp = "default"; - else if (!(flags & RT_NFLAG) && in != INADDR_ANY) { - if ((np = getnetbyaddr(in, AF_INET)) != NULL) - cp = np->n_name; - } - if (cp) - strlcpy(line, cp, sizeof(line)); -#define C(x) ((x) & 0xff) - else if (mbits < 9) - snprintf(line, sizeof(line), "%u/%d", C(in >> 24), mbits); - else if (mbits < 17) - snprintf(line, sizeof(line), "%u.%u/%d", - C(in >> 24) , C(in >> 16), mbits); - else if (mbits < 25) - snprintf(line, sizeof(line), "%u.%u.%u/%d", - C(in >> 24), C(in >> 16), C(in >> 8), mbits); - else - snprintf(line, sizeof(line), "%u.%u.%u.%u/%d", C(in >> 24), - C(in >> 16), C(in >> 8), C(in), mbits); -#undef C - return line; -} - -#ifdef INET6 -char * -netname6(const struct sockaddr_in6 *sa6, const struct sockaddr_in6 *mask, int flags) -{ - struct sockaddr_in6 sin6; - const u_char *p; - int masklen, final = 0, illegal = 0; - int i, lim, flag, error; - char hbuf[NI_MAXHOST]; - - sin6 = *sa6; - - flag = 0; - masklen = 0; - if (mask) { - lim = mask->sin6_len - offsetof(struct sockaddr_in6, sin6_addr); - if (lim < 0) - lim = 0; - else if (lim > (int)sizeof(struct in6_addr)) - lim = sizeof(struct in6_addr); - for (p = (const u_char *)&mask->sin6_addr, i = 0; i < lim; p++) { - if (final && *p) { - illegal++; - sin6.sin6_addr.s6_addr[i++] = 0x00; - continue; - } - - switch (*p & 0xff) { - case 0xff: - masklen += 8; - break; - case 0xfe: - masklen += 7; - final++; - break; - case 0xfc: - masklen += 6; - final++; - break; - case 0xf8: - masklen += 5; - final++; - break; - case 0xf0: - masklen += 4; - final++; - break; - case 0xe0: - masklen += 3; - final++; - break; - case 0xc0: - masklen += 2; - final++; - break; - case 0x80: - masklen += 1; - final++; - break; - case 0x00: - final++; - break; - default: - final++; - illegal++; - break; - } - - if (!illegal) - sin6.sin6_addr.s6_addr[i++] &= *p; - else - sin6.sin6_addr.s6_addr[i++] = 0x00; - } - while (i < (int)sizeof(struct in6_addr)) - sin6.sin6_addr.s6_addr[i++] = 0x00; - } else - masklen = 128; - - if (masklen == 0 && IN6_IS_ADDR_UNSPECIFIED(&sin6.sin6_addr)) { - snprintf(line, sizeof(line), "default"); - return (line); - } - - if (illegal) - warnx("illegal prefixlen"); - - if (flags & RT_NFLAG) - flag |= NI_NUMERICHOST; - error = getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len, - hbuf, sizeof(hbuf), NULL, 0, flag); - if (error) - snprintf(hbuf, sizeof(hbuf), "invalid"); - - snprintf(line, sizeof(line), "%s/%d", hbuf, masklen); - return (line); -} -#endif - -/* - * Return the name of the network whose address is given. - * The address is assumed to be that of a net or subnet, not a host. - */ -char * -netname(const struct sockaddr *sa, const struct sockaddr *mask, int flags) -{ - switch (sa->sa_family) { - - case AF_INET: - return netname4((const struct sockaddr_in *)sa, - (const struct sockaddr_in *)mask, flags); -#ifdef INET6 - case AF_INET6: - return netname6((const struct sockaddr_in6 *)sa, - (const struct sockaddr_in6 *)mask, flags); -#endif - case AF_LINK: - return link_print(sa); - default: - snprintf(line, sizeof(line), "af %d: %s", - sa->sa_family, any_ntoa(sa)); - break; - } - return (line); -} - -static const char hexlist[] = "0123456789abcdef"; - -char * -any_ntoa(const struct sockaddr *sa) -{ - static char obuf[240]; - const char *in = sa->sa_data; - char *out = obuf; - int len = sa->sa_len - offsetof(struct sockaddr, sa_data); - - *out++ = 'Q'; - do { - *out++ = hexlist[(*in >> 4) & 15]; - *out++ = hexlist[(*in++) & 15]; - *out++ = '.'; - } while (--len > 0 && (out + 3) < &obuf[sizeof(obuf) - 1]); - out[-1] = '\0'; - return (obuf); -} - -static char * -link_print(const struct sockaddr *sa) -{ - const struct sockaddr_dl *sdl = (const struct sockaddr_dl *)sa; - const u_char *lla = (const u_char *)sdl->sdl_data + sdl->sdl_nlen; - - if (sdl->sdl_nlen == 0 && sdl->sdl_alen == 0 && - sdl->sdl_slen == 0) { - (void)snprintf(line, sizeof(line), "link#%d", sdl->sdl_index); - return (line); - } - switch (sdl->sdl_type) { - case IFT_ETHER: - case IFT_CARP: - return ether_ntoa((const struct ether_addr *)lla); - default: - return link_ntoa(sdl); - } -} - -#ifndef SMALL -char * -mpls_ntoa(const struct sockaddr *sa) -{ - static char obuf[16]; - size_t olen; - const union mpls_shim *pms; - union mpls_shim ms; - int psize = sizeof(struct sockaddr_mpls); - - pms = &((const struct sockaddr_mpls*)sa)->smpls_addr; - ms.s_addr = ntohl(pms->s_addr); - - snprintf(obuf, sizeof(obuf), "%u", ms.shim.label); - - while(psize < sa->sa_len) { - pms++; - ms.s_addr = ntohl(pms->s_addr); - olen = strlen(obuf); - snprintf(obuf + olen, sizeof(obuf) - olen, ",%u", - ms.shim.label); - psize+=sizeof(ms); - } - return obuf; -} -#endif - -void -p_addr(const struct sockaddr *sa, const struct sockaddr *mask, int rflags, int flags) -{ - p_sockaddr(sa, mask, rflags, WID_DST(sa->sa_family), flags); -} - -void -p_gwaddr(const struct sockaddr *sa, int gwaf, int flags) -{ - p_sockaddr(sa, 0, RTF_HOST, WID_GW(gwaf), flags); -} diff --git a/sbin/route/rtutil.h b/sbin/route/rtutil.h deleted file mode 100644 index 3a23cf5cb..000000000 --- a/sbin/route/rtutil.h +++ /dev/null @@ -1,59 +0,0 @@ -/*- - * Copyright (c) 2013 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Christos Zoulas. - * - * 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. 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. - */ - -#define RT_AFLAG __BIT(0) /* show address field */ -#define RT_TFLAG __BIT(1) /* show tag field */ -#define RT_VFLAG __BIT(2) /* show verbose statistics */ -#define RT_NFLAG __BIT(3) /* numeric output */ -#define RT_LFLAG __BIT(4) /* don't show LLINFO entries */ - -void p_rttables(int, int, int, int); -void p_rthdr(int, int); -void p_family(int); -void p_sockaddr(const struct sockaddr *, const struct sockaddr *, int, int, int); -void p_flags(int); -struct rt_metrics; -void p_rtrmx(const struct rt_metrics *); -void p_addr(const struct sockaddr *sa, const struct sockaddr *mask, int, int); -void p_gwaddr(const struct sockaddr *sa, int, int); - -char *routename(const struct sockaddr *sa, int); -char *routename4(in_addr_t, int); -#ifdef INET6 -char *routename6(const struct sockaddr_in6 *, int); -char *netname6(const struct sockaddr_in6 *, const struct sockaddr_in6 *, int); -#endif -char *netname(const struct sockaddr *, const struct sockaddr *, int); -char *netname4(const struct sockaddr_in *, const struct sockaddr_in *, int); - -char *mpls_ntoa(const struct sockaddr *); -char *any_ntoa(const struct sockaddr *); diff --git a/sbin/route/show.c b/sbin/route/show.c deleted file mode 100644 index 8dbe6669d..000000000 --- a/sbin/route/show.c +++ /dev/null @@ -1,144 +0,0 @@ -/* $NetBSD: show.c,v 1.48 2015/03/23 18:33:17 roy Exp $ */ - -/* - * Copyright (c) 1983, 1988, 1993 - * The Regents of the University of California. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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 -#ifndef lint -#if 0 -static char sccsid[] = "from: @(#)route.c 8.3 (Berkeley) 3/9/94"; -#else -__RCSID("$NetBSD: show.c,v 1.48 2015/03/23 18:33:17 roy Exp $"); -#endif -#endif /* not lint */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "keywords.h" -#include "rtutil.h" -#include "extern.h" -#include "prog_ops.h" - -void -parse_show_opts(int argc, char * const *argv, int *afp, int *flagsp, - const char **afnamep, bool nolink) -{ - const char *afname = "unspec"; - int af, flags; - - flags = 0; - af = AF_UNSPEC; - for (; argc >= 2; argc--) { - if (*argv[argc - 1] != '-') - goto bad; - switch (keyword(argv[argc - 1] + 1)) { - case K_HOST: - flags |= RTF_HOST; - break; - case K_LLINFO: - flags |= RTF_LLINFO; - break; - case K_INET: - af = AF_INET; - afname = argv[argc - 1] + 1; - break; -#ifdef INET6 - case K_INET6: - af = AF_INET6; - afname = argv[argc - 1] + 1; - break; -#endif -#ifndef SMALL - case K_ATALK: - af = AF_APPLETALK; - afname = argv[argc - 1] + 1; - break; - case K_MPLS: - af = AF_MPLS; - afname = argv[argc - 1] + 1; - break; -#endif /* SMALL */ - case K_LINK: - if (nolink) - goto bad; - af = AF_LINK; - afname = argv[argc - 1] + 1; - break; - default: - goto bad; - } - } - switch (argc) { - case 1: - case 0: - break; - default: - bad: - usage(argv[argc - 1]); - } - if (afnamep != NULL) - *afnamep = afname; - *afp = af; - *flagsp = flags; -} - -/* - * Print routing tables. - */ -void -show(int argc, char *const *argv, int flags) -{ - int af, rflags; - static int interesting = RTF_UP | RTF_GATEWAY | RTF_HOST | - RTF_REJECT | RTF_LLINFO | RTF_LOCAL | RTF_BROADCAST; - - parse_show_opts(argc, argv, &af, &rflags, NULL, true); - p_rttables(af, flags, rflags, interesting); -}