Final update to current version of head in preparation for reintegration.

This commit is contained in:
mckusick 2010-05-06 17:37:23 +00:00
commit b25e55dcc5
508 changed files with 20099 additions and 9080 deletions

View File

@ -22,6 +22,14 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 9.x IS SLOW:
machines to maximize performance. (To disable malloc debugging, run machines to maximize performance. (To disable malloc debugging, run
ln -s aj /etc/malloc.conf.) ln -s aj /etc/malloc.conf.)
20100429:
'vm_page's are now hashed by physical address to an array of mutexes.
Currently this is only used to serialize access to hold_count. Over
time the page queue mutex will be peeled away. This changes the size
of pmap on every architecture. And requires all callers of vm_page_hold
and vm_page_unhold to be updated.
20100402: 20100402:
WITH_CTF can now be specified in src.conf (not recommended, there WITH_CTF can now be specified in src.conf (not recommended, there
are some problems with static executables), make.conf (would also are some problems with static executables), make.conf (would also

View File

@ -937,6 +937,8 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
cmdentry.special = 1; cmdentry.special = 1;
if (cmdentry.special) if (cmdentry.special)
listsetvar(cmdenviron); listsetvar(cmdenviron);
if (argc > 0)
bltinsetlocale();
commandname = argv[0]; commandname = argv[0];
argptr = argv + 1; argptr = argv + 1;
nextopt_optptr = NULL; /* initialize nextopt */ nextopt_optptr = NULL; /* initialize nextopt */
@ -944,6 +946,8 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
exitstatus = (*builtinfunc[cmdentry.u.index])(argc, argv); exitstatus = (*builtinfunc[cmdentry.u.index])(argc, argv);
flushall(); flushall();
cmddone: cmddone:
if (argc > 0)
bltinunsetlocale();
cmdenviron = NULL; cmdenviron = NULL;
out1 = &output; out1 = &output;
out2 = &errout; out2 = &errout;

View File

@ -122,6 +122,14 @@ STATIC const struct varinit varinit[] = {
STATIC struct var *vartab[VTABSIZE]; STATIC struct var *vartab[VTABSIZE];
STATIC const char *const locale_names[7] = {
"LC_COLLATE", "LC_CTYPE", "LC_MONETARY",
"LC_NUMERIC", "LC_TIME", "LC_MESSAGES", NULL
};
STATIC const int locale_categories[7] = {
LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME, LC_MESSAGES, 0
};
STATIC struct var **hashvar(const char *); STATIC struct var **hashvar(const char *);
STATIC int varequal(const char *, const char *); STATIC int varequal(const char *, const char *);
STATIC int localevar(const char *); STATIC int localevar(const char *);
@ -258,11 +266,7 @@ setvar(const char *name, const char *val, int flags)
STATIC int STATIC int
localevar(const char *s) localevar(const char *s)
{ {
static const char *lnames[7] = { const char *const *ss;
"ALL", "COLLATE", "CTYPE", "MONETARY",
"NUMERIC", "TIME", NULL
};
const char **ss;
if (*s != 'L') if (*s != 'L')
return 0; return 0;
@ -270,8 +274,10 @@ localevar(const char *s)
return 1; return 1;
if (strncmp(s + 1, "C_", 2) != 0) if (strncmp(s + 1, "C_", 2) != 0)
return 0; return 0;
for (ss = lnames; *ss ; ss++) if (varequal(s + 3, "ALL"))
if (varequal(s + 3, *ss)) return 1;
for (ss = locale_names; *ss ; ss++)
if (varequal(s + 3, *ss + 3))
return 1; return 1;
return 0; return 0;
} }
@ -437,6 +443,61 @@ bltinlookup(const char *name, int doall)
} }
/*
* Set up locale for a builtin (LANG/LC_* assignments).
*/
void
bltinsetlocale(void)
{
struct strlist *lp;
int act = 0;
char *loc, *locdef;
int i;
for (lp = cmdenviron ; lp ; lp = lp->next) {
if (localevar(lp->text)) {
act = 1;
break;
}
}
if (!act)
return;
loc = bltinlookup("LC_ALL", 0);
INTOFF;
if (loc != NULL) {
setlocale(LC_ALL, loc);
INTON;
return;
}
locdef = bltinlookup("LANG", 0);
for (i = 0; locale_names[i] != NULL; i++) {
loc = bltinlookup(locale_names[i], 0);
if (loc == NULL)
loc = locdef;
if (loc != NULL)
setlocale(locale_categories[i], loc);
}
INTON;
}
/*
* Undo the effect of bltinlocaleset().
*/
void
bltinunsetlocale(void)
{
struct strlist *lp;
INTOFF;
for (lp = cmdenviron ; lp ; lp = lp->next) {
if (localevar(lp->text)) {
setlocale(LC_ALL, "");
return;
}
}
INTON;
}
/* /*
* Generate a list of exported variables. This routine is used to construct * Generate a list of exported variables. This routine is used to construct

View File

@ -107,6 +107,8 @@ struct strlist;
void listsetvar(struct strlist *); void listsetvar(struct strlist *);
char *lookupvar(const char *); char *lookupvar(const char *);
char *bltinlookup(const char *, int); char *bltinlookup(const char *, int);
void bltinsetlocale(void);
void bltinunsetlocale(void);
char **environment(void); char **environment(void);
int showvarscmd(int, char **); int showvarscmd(int, char **);
int exportcmd(int, char **); int exportcmd(int, char **);

View File

@ -1790,7 +1790,7 @@ zfs_do_list(int argc, char **argv)
boolean_t scripted = B_FALSE; boolean_t scripted = B_FALSE;
static char default_fields[] = static char default_fields[] =
"name,used,available,referenced,mountpoint"; "name,used,available,referenced,mountpoint";
int types = ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME; int types = ZFS_TYPE_DATASET;
boolean_t types_specified = B_FALSE; boolean_t types_specified = B_FALSE;
char *fields = NULL; char *fields = NULL;
list_cbdata_t cb = { 0 }; list_cbdata_t cb = { 0 };

View File

@ -879,17 +879,21 @@ int
zpool_do_export(int argc, char **argv) zpool_do_export(int argc, char **argv)
{ {
boolean_t force = B_FALSE; boolean_t force = B_FALSE;
boolean_t hardforce = B_FALSE;
int c; int c;
zpool_handle_t *zhp; zpool_handle_t *zhp;
int ret; int ret;
int i; int i;
/* check options */ /* check options */
while ((c = getopt(argc, argv, "f")) != -1) { while ((c = getopt(argc, argv, "fF")) != -1) {
switch (c) { switch (c) {
case 'f': case 'f':
force = B_TRUE; force = B_TRUE;
break; break;
case 'F':
hardforce = B_TRUE;
break;
case '?': case '?':
(void) fprintf(stderr, gettext("invalid option '%c'\n"), (void) fprintf(stderr, gettext("invalid option '%c'\n"),
optopt); optopt);
@ -919,8 +923,12 @@ zpool_do_export(int argc, char **argv)
continue; continue;
} }
if (zpool_export(zhp, force) != 0) if (hardforce) {
if (zpool_export_force(zhp) != 0)
ret = 1;
} else if (zpool_export(zhp, force) != 0) {
ret = 1; ret = 1;
}
zpool_close(zhp); zpool_close(zhp);
} }

View File

@ -3039,7 +3039,7 @@ ztest_spa_import_export(char *oldname, char *newname)
/* /*
* Export it. * Export it.
*/ */
error = spa_export(oldname, &config, B_FALSE); error = spa_export(oldname, &config, B_FALSE, B_FALSE);
if (error) if (error)
fatal(0, "spa_export('%s') = %d", oldname, error); fatal(0, "spa_export('%s') = %d", oldname, error);

View File

@ -289,6 +289,7 @@ extern int zpool_get_errlog(zpool_handle_t *, nvlist_t **);
* Import and export functions * Import and export functions
*/ */
extern int zpool_export(zpool_handle_t *, boolean_t); extern int zpool_export(zpool_handle_t *, boolean_t);
extern int zpool_export_force(zpool_handle_t *);
extern int zpool_import(libzfs_handle_t *, nvlist_t *, const char *, extern int zpool_import(libzfs_handle_t *, nvlist_t *, const char *,
char *altroot); char *altroot);
extern int zpool_import_props(libzfs_handle_t *, nvlist_t *, const char *, extern int zpool_import_props(libzfs_handle_t *, nvlist_t *, const char *,

View File

@ -1096,7 +1096,7 @@ zpool_add(zpool_handle_t *zhp, nvlist_t *nvroot)
* mounted datasets in the pool. * mounted datasets in the pool.
*/ */
int int
zpool_export(zpool_handle_t *zhp, boolean_t force) zpool_export_common(zpool_handle_t *zhp, boolean_t force, boolean_t hardforce)
{ {
zfs_cmd_t zc = { 0 }; zfs_cmd_t zc = { 0 };
char msg[1024]; char msg[1024];
@ -1109,6 +1109,7 @@ zpool_export(zpool_handle_t *zhp, boolean_t force)
(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
zc.zc_cookie = force; zc.zc_cookie = force;
zc.zc_guid = hardforce;
if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_EXPORT, &zc) != 0) { if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_EXPORT, &zc) != 0) {
switch (errno) { switch (errno) {
@ -1129,6 +1130,18 @@ zpool_export(zpool_handle_t *zhp, boolean_t force)
return (0); return (0);
} }
int
zpool_export(zpool_handle_t *zhp, boolean_t force)
{
return (zpool_export_common(zhp, force, B_FALSE));
}
int
zpool_export_force(zpool_handle_t *zhp)
{
return (zpool_export_common(zhp, B_TRUE, B_TRUE));
}
/* /*
* zpool_import() is a contracted interface. Should be kept the same * zpool_import() is a contracted interface. Should be kept the same
* if possible. * if possible.

View File

@ -355,14 +355,21 @@ write_type(void *arg1, void *arg2)
for (i = 0, ep = tp->t_emem; ep != NULL; ep = ep->el_next) for (i = 0, ep = tp->t_emem; ep != NULL; ep = ep->el_next)
i++; /* count up enum members */ i++; /* count up enum members */
if (i > CTF_MAX_VLEN) {
warning("enum %s has too many values: %d > %d\n",
tdesc_name(tp), i, CTF_MAX_VLEN);
i = CTF_MAX_VLEN;
}
ctt.ctt_info = CTF_TYPE_INFO(CTF_K_ENUM, isroot, i); ctt.ctt_info = CTF_TYPE_INFO(CTF_K_ENUM, isroot, i);
write_sized_type_rec(b, &ctt, tp->t_size); write_sized_type_rec(b, &ctt, tp->t_size);
for (ep = tp->t_emem; ep != NULL; ep = ep->el_next) { for (ep = tp->t_emem; ep != NULL && i > 0; ep = ep->el_next) {
offset = strtab_insert(&b->ctb_strtab, ep->el_name); offset = strtab_insert(&b->ctb_strtab, ep->el_name);
cte.cte_name = CTF_TYPE_NAME(CTF_STRTAB_0, offset); cte.cte_name = CTF_TYPE_NAME(CTF_STRTAB_0, offset);
cte.cte_value = ep->el_number; cte.cte_value = ep->el_number;
ctf_buf_write(b, &cte, sizeof (cte)); ctf_buf_write(b, &cte, sizeof (cte));
i--;
} }
break; break;

View File

@ -2491,8 +2491,7 @@ tn(int argc, char *argv[])
env_export("USER"); env_export("USER");
} }
(void) call(status, "status", "notmuch", 0); (void) call(status, "status", "notmuch", 0);
if (setjmp(peerdied) == 0) telnet(user);
telnet(user);
(void) NetClose(net); (void) NetClose(net);
ExitString("Connection closed by foreign host.\n",1); ExitString("Connection closed by foreign host.\n",1);
/*NOTREACHED*/ /*NOTREACHED*/

View File

@ -233,7 +233,6 @@ extern void
SetNetTrace(char *); /* Function to change where debugging goes */ SetNetTrace(char *); /* Function to change where debugging goes */
extern jmp_buf extern jmp_buf
peerdied,
toplevel; /* For error conditions. */ toplevel; /* For error conditions. */
extern void extern void

View File

@ -158,7 +158,7 @@ netflush(void)
perror(hostname); perror(hostname);
(void)NetClose(net); (void)NetClose(net);
ring_clear_mark(&netoring); ring_clear_mark(&netoring);
longjmp(peerdied, -1); ExitString("Connection closed by foreign host.\n", 1);
/*NOTREACHED*/ /*NOTREACHED*/
} }
n = 0; n = 0;

View File

@ -808,14 +808,6 @@ NetNonblockingIO(int fd, int onoff)
* Various signal handling routines. * Various signal handling routines.
*/ */
/* ARGSUSED */
static SIG_FUNC_RET
deadpeer(int sig __unused)
{
setcommandmode();
longjmp(peerdied, -1);
}
/* ARGSUSED */ /* ARGSUSED */
SIG_FUNC_RET SIG_FUNC_RET
intr(int sig __unused) intr(int sig __unused)
@ -884,7 +876,7 @@ sys_telnet_init(void)
{ {
(void) signal(SIGINT, intr); (void) signal(SIGINT, intr);
(void) signal(SIGQUIT, intr2); (void) signal(SIGQUIT, intr2);
(void) signal(SIGPIPE, deadpeer); (void) signal(SIGPIPE, SIG_IGN);
#ifdef SIGWINCH #ifdef SIGWINCH
(void) signal(SIGWINCH, sendwin); (void) signal(SIGWINCH, sendwin);
#endif #endif

View File

@ -146,7 +146,6 @@ unsigned char telopt_environ = TELOPT_NEW_ENVIRON;
#endif #endif
jmp_buf toplevel; jmp_buf toplevel;
jmp_buf peerdied;
int flushline; int flushline;
int linemode; int linemode;

View File

@ -111,7 +111,8 @@ init_terminal(void)
} }
/* /*
* Send as much data as possible to the terminal. * Send as much data as possible to the terminal, else exits if
* it encounters a permanent failure when writing to the tty.
* *
* Return value: * Return value:
* -1: No useful work done, data waiting to go out. * -1: No useful work done, data waiting to go out.
@ -152,8 +153,19 @@ ttyflush(int drop)
} }
ring_consumed(&ttyoring, n); ring_consumed(&ttyoring, n);
} }
if (n < 0) if (n < 0) {
if (errno == EAGAIN || errno == EINTR) {
return -1;
} else {
ring_consumed(&ttyoring, ring_full_count(&ttyoring));
setconnmode(0);
setcommandmode();
NetClose(net);
fprintf(stderr, "Write error on local output.\n");
exit(1);
}
return -1; return -1;
}
if (n == n0) { if (n == n0) {
if (n0) if (n0)
return -1; return -1;

View File

@ -34,7 +34,7 @@ static const char privatehid[] = "@(#)private.h 8.6";
#endif /* !defined NOID */ #endif /* !defined NOID */
#endif /* !defined lint */ #endif /* !defined lint */
#define GRANDPARENTED "Local time zone must be set--see zic manual page" #define GRANDPARENTED "Local time zone must be set--use tzsetup"
/* /*
** Defaults for preprocessor symbols. ** Defaults for preprocessor symbols.

View File

@ -1,4 +1,120 @@
20100307 20100410
- (dtucker) [configure.ac] Put the check for the existence of getaddrinfo
back so we disable the IPv6 tests if we don't have it.
20100409
- (dtucker) [contrib/cygwin/Makefile] Don't overwrite files with the wrong
ones. Based on a patch from Roumen Petrov.
- (dtucker) [configure.ac] Bug #1744: use pkg-config for libedit flags if we
have it and the path is not provided to --with-libedit. Based on a patch
from Iain Morgan.
- (dtucker) [configure.ac defines.h loginrec.c logintest.c] Bug #1732: enable
utmpx support on FreeBSD where possible. Patch from Ed Schouten, ok djm@
20100326
- (djm) [openbsd-compat/bsd-arc4random.c] Fix preprocessor detection
for arc4random_buf() and arc4random_uniform(); from Josh Gilkerson
- (dtucker) [configure.ac] Bug #1741: Add section for Haiku, patch originally
by Ingo Weinhold via Scott McCreary, ok djm@
- (djm) OpenBSD CVS Sync
- djm@cvs.openbsd.org 2010/03/25 23:38:28
[servconf.c]
from portable: getcwd(NULL, 0) doesn't work on all platforms, so
use a stack buffer; ok dtucker@
- djm@cvs.openbsd.org 2010/03/26 00:26:58
[ssh.1]
mention that -S none disables connection sharing; from Colin Watson
- (djm) [session.c] Allow ChrootDirectory to work on SELinux platforms -
set up SELinux execution context before chroot() call. From Russell
Coker via Colin watson; bz#1726 ok dtucker@
- (djm) [channels.c] Check for EPFNOSUPPORT as a socket() errno; bz#1721
ok dtucker@
- (dtucker) Bug #1725: explicitly link libX11 into gnome-ssh-askpass2 using
pkg-config, patch from Colin Watson. Needed for newer linkers (ie gold).
- (djm) [contrib/ssh-copy-id] Don't blow up when the agent has no keys;
bz#1723 patch from Adeodato Simóvia Colin Watson; ok dtucker@
- (dtucker) OpenBSD CVS Sync
- dtucker@cvs.openbsd.org 2010/03/26 01:06:13
[ssh_config.5]
Reformat default value of PreferredAuthentications entry (current
formatting implies ", " is acceptable as a separator, which it's not.
ok djm@
20100324
- (dtucker) [contrib/cygwin/ssh-host-config] Mount the Windows directory
containing the services file explicitely case-insensitive. This allows to
tweak the Windows services file reliably. Patch from vinschen at redhat.
20100321
- (djm) OpenBSD CVS Sync
- jmc@cvs.openbsd.org 2010/03/08 09:41:27
[ssh-keygen.1]
sort the list of constraints (to -O); ok djm
- jmc@cvs.openbsd.org 2010/03/10 07:40:35
[ssh-keygen.1]
typos; from Ross Richardson
closes prs 6334 and 6335
- djm@cvs.openbsd.org 2010/03/10 23:27:17
[auth2-pubkey.c]
correct certificate logging and make it more consistent between
authorized_keys and TrustedCAKeys; ok markus@
- djm@cvs.openbsd.org 2010/03/12 01:06:25
[servconf.c]
unbreak AuthorizedKeys option with a $HOME-relative path; reported by
vinschen AT redhat.com, ok dtucker@
- markus@cvs.openbsd.org 2010/03/12 11:37:40
[servconf.c]
do not prepend AuthorizedKeysFile with getcwd(), unbreaks relative paths
free() (not xfree()) the buffer returned by getcwd()
- djm@cvs.openbsd.org 2010/03/13 21:10:38
[clientloop.c]
protocol conformance fix: send language tag when disconnecting normally;
spotted by 1.41421 AT gmail.com, ok markus@ deraadt@
- djm@cvs.openbsd.org 2010/03/13 21:45:46
[ssh-keygen.1]
Certificates are named *-cert.pub, not *_cert.pub; committing a diff
from stevesk@ ok me
- jmc@cvs.openbsd.org 2010/03/13 23:38:13
[ssh-keygen.1]
fix a formatting error (args need quoted); noted by stevesk
- stevesk@cvs.openbsd.org 2010/03/15 19:40:02
[key.c key.h ssh-keygen.c]
also print certificate type (user or host) for ssh-keygen -L
ok djm kettenis
- stevesk@cvs.openbsd.org 2010/03/16 15:46:52
[auth-options.c]
spelling in error message. ok djm kettenis
- djm@cvs.openbsd.org 2010/03/16 16:36:49
[version.h]
crank version to openssh-5.5 since we have a few fixes since 5.4;
requested deraadt@ kettenis@
- (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec]
[contrib/suse/openssh.spec] Crank version numbers
20100314
- (djm) [ssh-pkcs11-helper.c] Move #ifdef to after #defines to fix
compilation failure when !HAVE_DLOPEN. Reported by felix-mindrot
AT fefe.de
- (djm) [Makefile.in] Respecify -lssh after -lopenbsd-compat for
ssh-pkcs11-helper to repair static builds (we do the same for
ssh-keyscan). Reported by felix-mindrot AT fefe.de
20100312
- (tim) [Makefile.in] Now that scard is gone, no need to make $(datadir)
- (tim) [Makefile.in] Add missing $(EXEEXT) to install targets.
Patch from Corinna Vinschen.
- (tim) [contrib/cygwin/Makefile] Fix list of documentation files to install
on a Cygwin installation. Patch from Corinna Vinschen.
20100311
- (tim) [contrib/suse/openssh.spec] crank version number here too.
report by imorgan AT nas.nasa.gov
20100309
- (dtucker) [configure.ac] Use a proper AC_CHECK_DECL for BROKEN_GETADDRINFO
so setting it in CFLAGS correctly skips IPv6 tests.
20100428
- (djm) OpenBSD CVS Sync - (djm) OpenBSD CVS Sync
- djm@cvs.openbsd.org 2010/03/07 22:16:01 - djm@cvs.openbsd.org 2010/03/07 22:16:01
[ssh-keygen.c] [ssh-keygen.c]

View File

@ -1,4 +1,4 @@
See http://www.openssh.com/txt/release-5.4 for the release notes. See http://www.openssh.com/txt/release-5.5 for the release notes.
- A Japanese translation of this document and of the OpenSSH FAQ is - A Japanese translation of this document and of the OpenSSH FAQ is
- available at http://www.unixuser.org/~haruyama/security/openssh/index.html - available at http://www.unixuser.org/~haruyama/security/openssh/index.html
@ -62,4 +62,4 @@ References -
[6] http://www.openbsd.org/cgi-bin/man.cgi?query=style&sektion=9 [6] http://www.openbsd.org/cgi-bin/man.cgi?query=style&sektion=9
[7] http://www.openssh.com/faq.html [7] http://www.openssh.com/faq.html
$Id: README,v 1.72 2010/03/07 22:41:02 djm Exp $ $Id: README,v 1.73 2010/03/21 19:11:55 djm Exp $

View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth-options.c,v 1.48 2010/03/07 11:57:13 dtucker Exp $ */ /* $OpenBSD: auth-options.c,v 1.49 2010/03/16 15:46:52 stevesk Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -434,7 +434,7 @@ auth_cert_constraints(Buffer *c_orig, struct passwd *pw)
goto out; goto out;
} }
if (strlen(command) != clen) { if (strlen(command) != clen) {
error("force-command constrain contains \\0"); error("force-command constraint contains \\0");
goto out; goto out;
} }
if (cert_forced_command != NULL) { if (cert_forced_command != NULL) {
@ -454,7 +454,7 @@ auth_cert_constraints(Buffer *c_orig, struct passwd *pw)
goto out; goto out;
} }
if (strlen(allowed) != clen) { if (strlen(allowed) != clen) {
error("source-address constrain contains \\0"); error("source-address constraint contains \\0");
goto out; goto out;
} }
if (cert_source_address_done++) { if (cert_source_address_done++) {

View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth2-pubkey.c,v 1.21 2010/03/04 10:36:03 djm Exp $ */ /* $OpenBSD: auth2-pubkey.c,v 1.22 2010/03/10 23:27:17 djm Exp $ */
/* /*
* Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2000 Markus Friedl. All rights reserved.
* *
@ -240,22 +240,26 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
continue; continue;
if (!key_equal(found, key->cert->signature_key)) if (!key_equal(found, key->cert->signature_key))
continue; continue;
debug("matching CA found: file %s, line %lu",
file, linenum);
fp = key_fingerprint(found, SSH_FP_MD5, fp = key_fingerprint(found, SSH_FP_MD5,
SSH_FP_HEX); SSH_FP_HEX);
verbose("Found matching %s CA: %s", debug("matching CA found: file %s, line %lu, %s %s",
key_type(found), fp); file, linenum, key_type(found), fp);
xfree(fp);
if (key_cert_check_authority(key, 0, 0, pw->pw_name, if (key_cert_check_authority(key, 0, 0, pw->pw_name,
&reason) != 0) { &reason) != 0) {
xfree(fp);
error("%s", reason); error("%s", reason);
auth_debug_add("%s", reason); auth_debug_add("%s", reason);
continue; continue;
} }
if (auth_cert_constraints(&key->cert->constraints, if (auth_cert_constraints(&key->cert->constraints,
pw) != 0) pw) != 0) {
xfree(fp);
continue; continue;
}
verbose("Accepted certificate ID \"%s\" "
"signed by %s CA %s via %s", key->cert->key_id,
key_type(found), fp, file);
xfree(fp);
found_key = 1; found_key = 1;
break; break;
} else if (!key_is_cert_authority && key_equal(found, key)) { } else if (!key_is_cert_authority && key_equal(found, key)) {
@ -281,15 +285,15 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
static int static int
user_cert_trusted_ca(struct passwd *pw, Key *key) user_cert_trusted_ca(struct passwd *pw, Key *key)
{ {
char *key_fp, *ca_fp; char *ca_fp;
const char *reason; const char *reason;
int ret = 0; int ret = 0;
if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL) if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL)
return 0; return 0;
key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); ca_fp = key_fingerprint(key->cert->signature_key,
ca_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); SSH_FP_MD5, SSH_FP_HEX);
if (key_in_file(key->cert->signature_key, if (key_in_file(key->cert->signature_key,
options.trusted_user_ca_keys, 1) != 1) { options.trusted_user_ca_keys, 1) != 1) {
@ -306,13 +310,12 @@ user_cert_trusted_ca(struct passwd *pw, Key *key)
if (auth_cert_constraints(&key->cert->constraints, pw) != 0) if (auth_cert_constraints(&key->cert->constraints, pw) != 0)
goto out; goto out;
verbose("%s certificate %s allowed by trusted %s key %s", verbose("Accepted certificate ID \"%s\" signed by %s CA %s via %s",
key_type(key), key_fp, key_type(key->cert->signature_key), ca_fp); key->cert->key_id, key_type(key->cert->signature_key), ca_fp,
options.trusted_user_ca_keys);
ret = 1; ret = 1;
out: out:
if (key_fp != NULL)
xfree(key_fp);
if (ca_fp != NULL) if (ca_fp != NULL)
xfree(ca_fp); xfree(ca_fp);
return ret; return ret;

View File

@ -3252,7 +3252,11 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
sock = socket(ai->ai_family, ai->ai_socktype, sock = socket(ai->ai_family, ai->ai_socktype,
ai->ai_protocol); ai->ai_protocol);
if (sock < 0) { if (sock < 0) {
if ((errno != EINVAL) && (errno != EAFNOSUPPORT)) { if ((errno != EINVAL) && (errno != EAFNOSUPPORT)
#ifdef EPFNOSUPPORT
&& (errno != EPFNOSUPPORT)
#endif
) {
error("socket: %.100s", strerror(errno)); error("socket: %.100s", strerror(errno));
freeaddrinfo(aitop); freeaddrinfo(aitop);
return -1; return -1;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: clientloop.c,v 1.218 2010/01/28 00:21:18 djm Exp $ */ /* $OpenBSD: clientloop.c,v 1.219 2010/03/13 21:10:38 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -1484,6 +1484,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
packet_start(SSH2_MSG_DISCONNECT); packet_start(SSH2_MSG_DISCONNECT);
packet_put_int(SSH2_DISCONNECT_BY_APPLICATION); packet_put_int(SSH2_DISCONNECT_BY_APPLICATION);
packet_put_cstring("disconnected by user"); packet_put_cstring("disconnected by user");
packet_put_cstring(""); /* language tag */
packet_send(); packet_send();
packet_write_wait(); packet_write_wait();
} }

View File

@ -124,7 +124,7 @@
#define DISABLE_WTMPX 1 #define DISABLE_WTMPX 1
/* Enable for PKCS#11 support */ /* Enable for PKCS#11 support */
#define ENABLE_PKCS11 #define ENABLE_PKCS11 /**/
/* Builtin PRNG command timeout */ /* Builtin PRNG command timeout */
#define ENTROPY_TIMEOUT_MSEC 200 #define ENTROPY_TIMEOUT_MSEC 200
@ -456,6 +456,9 @@
/* Define to 1 if you have the `getutxline' function. */ /* Define to 1 if you have the `getutxline' function. */
#define HAVE_GETUTXLINE 1 #define HAVE_GETUTXLINE 1
/* Define to 1 if you have the `getutxuser' function. */
#define HAVE_GETUTXUSER 1
/* Define to 1 if you have the `get_default_context_with_level' function. */ /* Define to 1 if you have the `get_default_context_with_level' function. */
/* #undef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL */ /* #undef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL */
@ -552,6 +555,9 @@
/* Define if system has libiaf that supports set_id */ /* Define if system has libiaf that supports set_id */
/* #undef HAVE_LIBIAF */ /* #undef HAVE_LIBIAF */
/* Define to 1 if you have the `network' library (-lnetwork). */
/* #undef HAVE_LIBNETWORK */
/* Define to 1 if you have the `nsl' library (-lnsl). */ /* Define to 1 if you have the `nsl' library (-lnsl). */
/* #undef HAVE_LIBNSL */ /* #undef HAVE_LIBNSL */
@ -805,6 +811,9 @@
/* Define to 1 if you have the `setutent' function. */ /* Define to 1 if you have the `setutent' function. */
/* #undef HAVE_SETUTENT */ /* #undef HAVE_SETUTENT */
/* Define to 1 if you have the `setutxdb' function. */
#define HAVE_SETUTXDB 1
/* Define to 1 if you have the `setutxent' function. */ /* Define to 1 if you have the `setutxent' function. */
#define HAVE_SETUTXENT 1 #define HAVE_SETUTXENT 1
@ -1416,8 +1425,8 @@
/* Define if you want SELinux support. */ /* Define if you want SELinux support. */
/* #undef WITH_SELINUX */ /* #undef WITH_SELINUX */
/* Define to 1 if your processor stores words with the most significant byte /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
first (like Motorola and SPARC, unlike Intel and VAX). */ significant byte first (like Motorola and SPARC, unlike Intel and VAX). */
#if defined __BIG_ENDIAN__ #if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1 # define WORDS_BIGENDIAN 1
#elif ! defined __LITTLE_ENDIAN__ #elif ! defined __LITTLE_ENDIAN__

View File

@ -80,9 +80,6 @@
/* Define if you want to specify the path to your lastlog file */ /* Define if you want to specify the path to your lastlog file */
#undef CONF_LASTLOG_FILE #undef CONF_LASTLOG_FILE
/* Define if you want to specify the path to your utmpx file */
#undef CONF_UTMPX_FILE
/* Define if you want to specify the path to your utmp file */ /* Define if you want to specify the path to your utmp file */
#undef CONF_UTMP_FILE #undef CONF_UTMP_FILE
@ -455,6 +452,9 @@
/* Define to 1 if you have the `getutxline' function. */ /* Define to 1 if you have the `getutxline' function. */
#undef HAVE_GETUTXLINE #undef HAVE_GETUTXLINE
/* Define to 1 if you have the `getutxuser' function. */
#undef HAVE_GETUTXUSER
/* Define to 1 if you have the `get_default_context_with_level' function. */ /* Define to 1 if you have the `get_default_context_with_level' function. */
#undef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL #undef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
@ -551,6 +551,9 @@
/* Define if system has libiaf that supports set_id */ /* Define if system has libiaf that supports set_id */
#undef HAVE_LIBIAF #undef HAVE_LIBIAF
/* Define to 1 if you have the `network' library (-lnetwork). */
#undef HAVE_LIBNETWORK
/* Define to 1 if you have the `nsl' library (-lnsl). */ /* Define to 1 if you have the `nsl' library (-lnsl). */
#undef HAVE_LIBNSL #undef HAVE_LIBNSL
@ -804,6 +807,9 @@
/* Define to 1 if you have the `setutent' function. */ /* Define to 1 if you have the `setutent' function. */
#undef HAVE_SETUTENT #undef HAVE_SETUTENT
/* Define to 1 if you have the `setutxdb' function. */
#undef HAVE_SETUTXDB
/* Define to 1 if you have the `setutxent' function. */ /* Define to 1 if you have the `setutxent' function. */
#undef HAVE_SETUTXENT #undef HAVE_SETUTXENT

View File

@ -25,7 +25,7 @@
#ifndef _DEFINES_H #ifndef _DEFINES_H
#define _DEFINES_H #define _DEFINES_H
/* $Id: defines.h,v 1.159 2010/01/13 23:44:34 tim Exp $ */ /* $Id: defines.h,v 1.160 2010/04/09 08:13:27 dtucker Exp $ */
/* Constants */ /* Constants */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: key.c,v 1.85 2010/03/04 01:44:57 djm Exp $ */ /* $OpenBSD: key.c,v 1.86 2010/03/15 19:40:02 stevesk Exp $ */
/* /*
* read_bignum(): * read_bignum():
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -801,6 +801,19 @@ key_type(const Key *k)
return "unknown"; return "unknown";
} }
const char *
key_cert_type(const Key *k)
{
switch (k->cert->type) {
case SSH2_CERT_TYPE_USER:
return "user";
case SSH2_CERT_TYPE_HOST:
return "host";
default:
return "unknown";
}
}
const char * const char *
key_ssh_name(const Key *k) key_ssh_name(const Key *k)
{ {

View File

@ -1,4 +1,4 @@
/* $OpenBSD: key.h,v 1.28 2010/02/26 20:29:54 djm Exp $ */ /* $OpenBSD: key.h,v 1.29 2010/03/15 19:40:02 stevesk Exp $ */
/* /*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@ -82,6 +82,7 @@ int key_equal(const Key *, const Key *);
char *key_fingerprint(Key *, enum fp_type, enum fp_rep); char *key_fingerprint(Key *, enum fp_type, enum fp_rep);
u_char *key_fingerprint_raw(Key *, enum fp_type, u_int *); u_char *key_fingerprint_raw(Key *, enum fp_type, u_int *);
const char *key_type(const Key *); const char *key_type(const Key *);
const char *key_cert_type(const Key *);
int key_write(const Key *, FILE *); int key_write(const Key *, FILE *);
int key_read(Key *, char **); int key_read(Key *, char **);
u_int key_size(const Key *); u_int key_size(const Key *);

View File

@ -510,6 +510,10 @@ getlast_entry(struct logininfo *li)
#ifdef USE_LASTLOG #ifdef USE_LASTLOG
return(lastlog_get_entry(li)); return(lastlog_get_entry(li));
#else /* !USE_LASTLOG */ #else /* !USE_LASTLOG */
#if defined(USE_UTMPX) && defined(HAVE_SETUTXDB) && \
defined(UTXDB_LASTLOGIN) && defined(HAVE_GETUTXUSER)
return (utmpx_get_entry(li));
#endif
#if 1 #if 1
return (utmpx_get_entry(li)); return (utmpx_get_entry(li));
@ -1614,7 +1618,8 @@ lastlog_get_entry(struct logininfo *li)
#endif /* HAVE_GETLASTLOGXBYNAME */ #endif /* HAVE_GETLASTLOGXBYNAME */
#endif /* USE_LASTLOG */ #endif /* USE_LASTLOG */
#if 1 #if defined(USE_UTMPX) && defined(HAVE_SETUTXDB) && \
defined(UTXDB_LASTLOGIN) && defined(HAVE_GETUTXUSER)
int int
utmpx_get_entry(struct logininfo *li) utmpx_get_entry(struct logininfo *li)
{ {
@ -1637,7 +1642,7 @@ utmpx_get_entry(struct logininfo *li)
endutxent(); endutxent();
return (1); return (1);
} }
#endif #endif /* USE_UTMPX && HAVE_SETUTXDB && UTXDB_LASTLOGIN && HAVE_GETUTXUSER */
#ifdef USE_BTMP #ifdef USE_BTMP
/* /*

View File

@ -264,7 +264,7 @@ showOptions(void)
printf("\tUSE_UTMP (UTMP_FILE=%s)\n", UTMP_FILE); printf("\tUSE_UTMP (UTMP_FILE=%s)\n", UTMP_FILE);
#endif #endif
#ifdef USE_UTMPX #ifdef USE_UTMPX
printf("\tUSE_UTMPX (UTMPX_FILE=%s)\n", UTMPX_FILE); printf("\tUSE_UTMPX\n");
#endif #endif
#ifdef USE_WTMP #ifdef USE_WTMP
printf("\tUSE_WTMP (WTMP_FILE=%s)\n", WTMP_FILE); printf("\tUSE_WTMP (WTMP_FILE=%s)\n", WTMP_FILE);

View File

@ -84,7 +84,7 @@ arc4random_stir(void)
} }
#endif /* !HAVE_ARC4RANDOM */ #endif /* !HAVE_ARC4RANDOM */
#ifndef ARC4RANDOM_BUF #ifndef HAVE_ARC4RANDOM_BUF
void void
arc4random_buf(void *_buf, size_t n) arc4random_buf(void *_buf, size_t n)
{ {
@ -102,7 +102,7 @@ arc4random_buf(void *_buf, size_t n)
} }
#endif /* !HAVE_ARC4RANDOM_BUF */ #endif /* !HAVE_ARC4RANDOM_BUF */
#ifndef ARC4RANDOM_UNIFORM #ifndef HAVE_ARC4RANDOM_UNIFORM
/* /*
* Calculate a uniformly distributed random number less than upper_bound * Calculate a uniformly distributed random number less than upper_bound
* avoiding "modulo bias". * avoiding "modulo bias".

View File

@ -1,4 +1,4 @@
/* $OpenBSD: servconf.c,v 1.204 2010/03/04 10:36:03 djm Exp $ */ /* $OpenBSD: servconf.c,v 1.207 2010/03/25 23:38:28 djm Exp $ */
/* /*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved * All rights reserved
@ -474,15 +474,14 @@ parse_token(const char *cp, const char *filename,
char * char *
derelativise_path(const char *path) derelativise_path(const char *path)
{ {
char *expanded, *ret, *cwd; char *expanded, *ret, cwd[MAXPATHLEN];
expanded = tilde_expand_filename(path, getuid()); expanded = tilde_expand_filename(path, getuid());
if (*expanded == '/') if (*expanded == '/')
return expanded; return expanded;
if ((cwd = getcwd(NULL, 0)) == NULL) if (getcwd(cwd, sizeof(cwd)) == NULL)
fatal("%s: getcwd: %s", __func__, strerror(errno)); fatal("%s: getcwd: %s", __func__, strerror(errno));
xasprintf(&ret, "%s/%s", cwd, expanded); xasprintf(&ret, "%s/%s", cwd, expanded);
xfree(cwd);
xfree(expanded); xfree(expanded);
return ret; return ret;
} }
@ -1227,7 +1226,17 @@ process_server_config_line(ServerOptions *options, char *line,
charptr = (opcode == sAuthorizedKeysFile) ? charptr = (opcode == sAuthorizedKeysFile) ?
&options->authorized_keys_file : &options->authorized_keys_file :
&options->authorized_keys_file2; &options->authorized_keys_file2;
goto parse_filename; arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: missing file name.",
filename, linenum);
if (*activep && *charptr == NULL) {
*charptr = tilde_expand_filename(arg, getuid());
/* increase optional counter */
if (intptr != NULL)
*intptr = *intptr + 1;
}
break;
case sClientAliveInterval: case sClientAliveInterval:
intptr = &options->client_alive_interval; intptr = &options->client_alive_interval;

View File

@ -1581,6 +1581,10 @@ do_setusercontext(struct passwd *pw)
} }
#endif /* HAVE_SETPCRED */ #endif /* HAVE_SETPCRED */
#ifdef WITH_SELINUX
ssh_selinux_setup_exec_context(pw->pw_name);
#endif
if (options.chroot_directory != NULL && if (options.chroot_directory != NULL &&
strcasecmp(options.chroot_directory, "none") != 0) { strcasecmp(options.chroot_directory, "none") != 0) {
tmp = tilde_expand_filename(options.chroot_directory, tmp = tilde_expand_filename(options.chroot_directory,
@ -1605,10 +1609,6 @@ do_setusercontext(struct passwd *pw)
if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid) if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
fatal("Failed to set uids to %u.", (u_int) pw->pw_uid); fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
#ifdef WITH_SELINUX
ssh_selinux_setup_exec_context(pw->pw_name);
#endif
} }
static void static void

View File

@ -1,4 +1,4 @@
.\" $OpenBSD: ssh-keygen.1,v 1.88 2010/03/08 00:28:55 djm Exp $ .\" $OpenBSD: ssh-keygen.1,v 1.92 2010/03/13 23:38:13 jmc Exp $
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.\" -*- nroff -*- .\" -*- nroff -*-
@ -38,7 +38,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.Dd March 8 2010 .Dd March 13 2010
.Dt SSH-KEYGEN 1 .Dt SSH-KEYGEN 1
.Os .Os
.Sh NAME .Sh NAME
@ -308,8 +308,15 @@ Please see the
section for details. section for details.
The constraints that are valid for user certificates are: The constraints that are valid for user certificates are:
.Bl -tag -width Ds .Bl -tag -width Ds
.It Ic no-x11-forwarding .It Ic clear
Disable X11 forwarding (permitted by default). Clear all enabled permissions.
This is useful for clearing the default set of permissions so permissions may
be added individually.
.It Ic force-command Ns = Ns Ar command
Forces the execution of
.Ar command
instead of any shell or command specified by the user when
the certificate is used for authentication.
.It Ic no-agent-forwarding .It Ic no-agent-forwarding
Disable Disable
.Xr ssh-agent 1 .Xr ssh-agent 1
@ -324,12 +331,8 @@ Disable execution of
by by
.Xr sshd 8 .Xr sshd 8
(permitted by default). (permitted by default).
.It Ic clear .It Ic no-x11-forwarding
Clear all enabled permissions. Disable X11 forwarding (permitted by default).
This is useful for clearing the default set of permissions so permissions may
be added individually.
.It Ic permit-x11-forwarding
Allows X11 forwarding.
.It Ic permit-agent-forwarding .It Ic permit-agent-forwarding
Allows Allows
.Xr ssh-agent 1 .Xr ssh-agent 1
@ -343,14 +346,10 @@ Allows execution of
.Pa ~/.ssh/rc .Pa ~/.ssh/rc
by by
.Xr sshd 8 . .Xr sshd 8 .
.It Ic force-command=command .It Ic permit-x11-forwarding
Forces the execution of Allows X11 forwarding.
.Ar command .It Ic source-address Ns = Ns Ar address_list
instead of any shell or command specified by the user when Restrict the source addresses from which the certificate is considered valid.
the certificate is used for authentication.
.It Ic source-address=address_list
Restrict the source addresses from which the certificate is considered valid
from.
The The
.Ar address_list .Ar address_list
is a comma-separated list of one or more address/netmask pairs in CIDR is a comma-separated list of one or more address/netmask pairs in CIDR
@ -415,7 +414,7 @@ in YYYYMMDDHHMMSS format or a relative time (to the current time) consisting
of a minus sign followed by a relative time in the format described in the of a minus sign followed by a relative time in the format described in the
.Sx TIME FORMATS .Sx TIME FORMATS
section of section of
.Xr ssh_config 5 . .Xr sshd_config 5 .
The end time may be specified as a YYYYMMDD date, a YYYYMMDDHHMMSS time or The end time may be specified as a YYYYMMDD date, a YYYYMMDDHHMMSS time or
a relative time starting with a plus character. a relative time starting with a plus character.
.Pp .Pp
@ -520,7 +519,7 @@ To generate a user certificate:
.Dl $ ssh-keygen -s /path/to/ca_key -I key_id /path/to/user_key.pub .Dl $ ssh-keygen -s /path/to/ca_key -I key_id /path/to/user_key.pub
.Pp .Pp
The resultant certificate will be placed in The resultant certificate will be placed in
.Pa /path/to/user_key_cert.pub . .Pa /path/to/user_key-cert.pub .
A host certificate requires the A host certificate requires the
.Fl h .Fl h
option: option:
@ -528,7 +527,7 @@ option:
.Dl $ ssh-keygen -s /path/to/ca_key -I key_id -h /path/to/host_key.pub .Dl $ ssh-keygen -s /path/to/ca_key -I key_id -h /path/to/host_key.pub
.Pp .Pp
The host certificate will be output to The host certificate will be output to
.Pa /path/to/host_key_cert.pub . .Pa /path/to/host_key-cert.pub .
In both cases, In both cases,
.Ar key_id .Ar key_id
is a "key identifier" that is logged by the server when the certificate is a "key identifier" that is logged by the server when the certificate
@ -540,7 +539,7 @@ By default, generated certificates are valid for all users or hosts.
To generate a certificate for a specified set of principals: To generate a certificate for a specified set of principals:
.Pp .Pp
.Dl $ ssh-keygen -s ca_key -I key_id -n user1,user2 user_key.pub .Dl $ ssh-keygen -s ca_key -I key_id -n user1,user2 user_key.pub
.Dl $ ssh-keygen -s ca_key -I key_id -h -n host.domain user_key.pub .Dl "$ ssh-keygen -s ca_key -I key_id -h -n host.domain user_key.pub"
.Pp .Pp
Additional limitations on the validity and use of user certificates may Additional limitations on the validity and use of user certificates may
be specified through certificate constraints. be specified through certificate constraints.

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-keygen.c,v 1.184 2010/03/07 22:16:01 djm Exp $ */ /* $OpenBSD: ssh-keygen.c,v 1.185 2010/03/15 19:40:02 stevesk Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -1393,7 +1393,8 @@ do_show_cert(struct passwd *pw)
SSH_FP_MD5, SSH_FP_HEX); SSH_FP_MD5, SSH_FP_HEX);
printf("%s:\n", identity_file); printf("%s:\n", identity_file);
printf(" %s certificate %s\n", key_type(key), key_fp); printf(" %s %s certificate %s\n", key_type(key),
key_cert_type(key), key_fp);
printf(" Signed by %s CA %s\n", printf(" Signed by %s CA %s\n",
key_type(key->cert->signature_key), ca_fp); key_type(key->cert->signature_key), ca_fp);
printf(" Key ID \"%s\"\n", key->cert->key_id); printf(" Key ID \"%s\"\n", key->cert->key_id);

View File

@ -17,8 +17,6 @@
#include "includes.h" #include "includes.h"
#ifdef ENABLE_PKCS11
#include <sys/types.h> #include <sys/types.h>
#ifdef HAVE_SYS_TIME_H #ifdef HAVE_SYS_TIME_H
# include <sys/time.h> # include <sys/time.h>
@ -39,6 +37,8 @@
#include "authfd.h" #include "authfd.h"
#include "ssh-pkcs11.h" #include "ssh-pkcs11.h"
#ifdef ENABLE_PKCS11
/* borrows code from sftp-server and ssh-agent */ /* borrows code from sftp-server and ssh-agent */
struct pkcs11_keyinfo { struct pkcs11_keyinfo {

View File

@ -34,9 +34,9 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.\" $OpenBSD: ssh.1,v 1.302 2010/03/05 10:28:21 djm Exp $ .\" $OpenBSD: ssh.1,v 1.303 2010/03/26 00:26:58 djm Exp $
.\" $FreeBSD$ .\" $FreeBSD$
.Dd March 5 2010 .Dd March 26 2010
.Dt SSH 1 .Dt SSH 1
.Os .Os
.Sh NAME .Sh NAME
@ -560,7 +560,10 @@ argument is
the listen port will be dynamically allocated on the server and reported the listen port will be dynamically allocated on the server and reported
to the client at run time. to the client at run time.
.It Fl S Ar ctl_path .It Fl S Ar ctl_path
Specifies the location of a control socket for connection sharing. Specifies the location of a control socket for connection sharing
or the string
.Dq none
to disable connection sharing.
Refer to the description of Refer to the description of
.Cm ControlPath .Cm ControlPath
and and

View File

@ -46,4 +46,4 @@
# PermitLocalCommand no # PermitLocalCommand no
# VisualHostKey no # VisualHostKey no
# ProxyCommand ssh -q -W %h:%p gateway.example.com # ProxyCommand ssh -q -W %h:%p gateway.example.com
# VersionAddendum FreeBSD-20100308 # VersionAddendum FreeBSD-20100428

View File

@ -34,9 +34,9 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.\" $OpenBSD: ssh_config.5,v 1.129 2010/03/05 10:28:21 djm Exp $ .\" $OpenBSD: ssh_config.5,v 1.130 2010/03/26 01:06:13 dtucker Exp $
.\" $FreeBSD$ .\" $FreeBSD$
.Dd March 5 2010 .Dd March 26 2010
.Dt SSH_CONFIG 5 .Dt SSH_CONFIG 5
.Os .Os
.Sh NAME .Sh NAME
@ -735,11 +735,7 @@ This allows a client to prefer one method (e.g.\&
over another method (e.g.\& over another method (e.g.\&
.Cm password ) .Cm password )
The default for this option is: The default for this option is:
.Do gssapi-with-mic , .Do gssapi-with-mic,hostbased,publickey,keyboard-interactive,password
hostbased,
publickey,
keyboard-interactive,
password
.Dc . .Dc .
.It Cm Protocol .It Cm Protocol
Specifies the protocol versions Specifies the protocol versions
@ -1087,7 +1083,7 @@ in
Specifies a string to append to the regular version string to identify Specifies a string to append to the regular version string to identify
OS- or site-specific modifications. OS- or site-specific modifications.
The default is The default is
.Dq FreeBSD-20100308 . .Dq FreeBSD-20100428 .
.It Cm VisualHostKey .It Cm VisualHostKey
If this flag is set to If this flag is set to
.Dq yes , .Dq yes ,

View File

@ -14,7 +14,7 @@
# Note that some of FreeBSD's defaults differ from OpenBSD's, and # Note that some of FreeBSD's defaults differ from OpenBSD's, and
# FreeBSD has a few additional options. # FreeBSD has a few additional options.
#VersionAddendum FreeBSD-20100308 #VersionAddendum FreeBSD-20100428
#Port 22 #Port 22
#AddressFamily any #AddressFamily any

View File

@ -988,7 +988,7 @@ The default is
Specifies a string to append to the regular version string to identify Specifies a string to append to the regular version string to identify
OS- or site-specific modifications. OS- or site-specific modifications.
The default is The default is
.Dq FreeBSD-20100308 . .Dq FreeBSD-20100428 .
.It Cm X11DisplayOffset .It Cm X11DisplayOffset
Specifies the first display number available for Specifies the first display number available for
.Xr sshd 8 Ns 's .Xr sshd 8 Ns 's

View File

@ -1,12 +1,12 @@
/* $OpenBSD: version.h,v 1.57 2010/03/07 22:01:32 djm Exp $ */ /* $OpenBSD: version.h,v 1.58 2010/03/16 16:36:49 djm Exp $ */
/* $FreeBSD$ */ /* $FreeBSD$ */
#ifndef SSH_VERSION #ifndef SSH_VERSION
#define SSH_VERSION (ssh_version_get()) #define SSH_VERSION (ssh_version_get())
#define SSH_RELEASE (ssh_version_get()) #define SSH_RELEASE (ssh_version_get())
#define SSH_VERSION_BASE "OpenSSH_5.4p1" #define SSH_VERSION_BASE "OpenSSH_5.5p1"
#define SSH_VERSION_ADDENDUM "FreeBSD-20100308" #define SSH_VERSION_ADDENDUM "FreeBSD-20100428"
const char *ssh_version_get(void); const char *ssh_version_get(void);
void ssh_version_set_addendum(const char *); void ssh_version_set_addendum(const char *);

View File

@ -399,6 +399,8 @@ ipv6if()
$_if|"$_if "*|*" $_if"|*" $_if "*|[Aa][Uu][Tt][Oo]) $_if|"$_if "*|*" $_if"|*" $_if "*|[Aa][Uu][Tt][Oo])
# True if $ifconfig_IF_ipv6 is defined. # True if $ifconfig_IF_ipv6 is defined.
_tmpargs=`_ifconfig_getargs $_if ipv6` _tmpargs=`_ifconfig_getargs $_if ipv6`
# Also true if ipv6_prefix_IF is defined
[ -n "$_tmpargs" ] || _tmpargs=`get_if_var $_if ipv6_prefix_IF`
;; ;;
esac esac

View File

@ -192,6 +192,13 @@ named_prestart()
$confgen_command $confgen_command
fi fi
local checkconf
checkconf="${command%/named}/named-checkconf"
if ! checkyesno named_chroot_autoupdate && [ -n "$named_chrootdir" ]; then
checkconf="$checkconf -t $named_chrootdir"
fi
# Create a forwarder configuration based on /etc/resolv.conf # Create a forwarder configuration based on /etc/resolv.conf
if checkyesno named_auto_forward; then if checkyesno named_auto_forward; then
if [ ! -s /etc/resolv.conf ]; then if [ ! -s /etc/resolv.conf ]; then
@ -201,7 +208,7 @@ named_prestart()
[ -s "${named_confdir}/auto_forward.conf" ] && [ -s "${named_confdir}/auto_forward.conf" ] &&
create_file ${named_confdir}/auto_forward.conf create_file ${named_confdir}/auto_forward.conf
${command%/named}/named-checkconf $named_conf || $checkconf $named_conf ||
err 3 'named-checkconf for $named_conf failed' err 3 'named-checkconf for $named_conf failed'
return return
fi fi
@ -263,8 +270,7 @@ named_prestart()
create_file ${named_confdir}/auto_forward.conf create_file ${named_confdir}/auto_forward.conf
fi fi
${command%/named}/named-checkconf $named_conf || $checkconf $named_conf || err 3 'named-checkconf for $named_conf failed'
err 3 'named-checkconf for $named_conf failed'
} }
load_rc_config $name load_rc_config $name
@ -272,7 +278,7 @@ load_rc_config $name
# Updating the following variables requires that rc.conf be loaded first # Updating the following variables requires that rc.conf be loaded first
# #
required_dirs="$named_chrootdir" # if it is set, it must exist required_dirs="$named_chrootdir" # if it is set, it must exist
required_files="${named_conf:=/etc/namedb/named.conf}"
pidfile="${named_pidfile:-/var/run/named/pid}" pidfile="${named_pidfile:-/var/run/named/pid}"
named_confdir="${named_chrootdir}${named_conf%/*}" named_confdir="${named_chrootdir}${named_conf%/*}"

View File

@ -75,6 +75,7 @@
.ds doc-operating-system-FreeBSD-7.2 7.2 .ds doc-operating-system-FreeBSD-7.2 7.2
.ds doc-operating-system-FreeBSD-7.3 7.3 .ds doc-operating-system-FreeBSD-7.3 7.3
.ds doc-operating-system-FreeBSD-8.0 8.0 .ds doc-operating-system-FreeBSD-8.0 8.0
.ds doc-operating-system-FreeBSD-8.1 8.1
.ds doc-operating-system-FreeBSD-9.0 9.0 .ds doc-operating-system-FreeBSD-9.0 9.0
. .
.\" Definitions not (yet) in doc-syms .\" Definitions not (yet) in doc-syms

View File

@ -28,7 +28,7 @@
.\" @(#)getrusage.2 8.1 (Berkeley) 6/4/93 .\" @(#)getrusage.2 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd June 4, 1993 .Dd May 1, 2010
.Dt GETRUSAGE 2 .Dt GETRUSAGE 2
.Os .Os
.Sh NAME .Sh NAME
@ -42,6 +42,7 @@
.In sys/resource.h .In sys/resource.h
.Fd "#define RUSAGE_SELF 0" .Fd "#define RUSAGE_SELF 0"
.Fd "#define RUSAGE_CHILDREN -1" .Fd "#define RUSAGE_CHILDREN -1"
.Fd "#define RUSAGE_THREAD 1"
.Ft int .Ft int
.Fn getrusage "int who" "struct rusage *rusage" .Fn getrusage "int who" "struct rusage *rusage"
.Sh DESCRIPTION .Sh DESCRIPTION
@ -49,11 +50,12 @@ The
.Fn getrusage .Fn getrusage
system call system call
returns information describing the resources utilized by the current returns information describing the resources utilized by the current
process, or all its terminated child processes. thread, the current process, or all its terminated child processes.
The The
.Fa who .Fa who
argument is either argument is either
.Dv RUSAGE_SELF .Dv RUSAGE_THREAD ,
.Dv RUSAGE_SELF ,
or or
.Dv RUSAGE_CHILDREN . .Dv RUSAGE_CHILDREN .
The buffer to which The buffer to which
@ -175,6 +177,10 @@ The
.Fn getrusage .Fn getrusage
system call appeared in system call appeared in
.Bx 4.2 . .Bx 4.2 .
The
.Dv RUSAGE_THREAD
facility first appeared in
.Fx 8.1 .
.Sh BUGS .Sh BUGS
There is no way to obtain information about a child process There is no way to obtain information about a child process
that has not yet terminated. that has not yet terminated.

View File

@ -1,7 +1,7 @@
.\" .\"
.\" $Id: pam_krb5.5,v 1.5 2000/01/05 00:59:56 fcusack Exp $ .\" $Id: pam_krb5.5,v 1.5 2000/01/05 00:59:56 fcusack Exp $
.\" $FreeBSD$ .\" $FreeBSD$
.Dd January 15, 1999 .Dd May 3, 2010
.Dt PAM_KRB5 8 .Dt PAM_KRB5 8
.Os .Os
.Sh NAME .Sh NAME
@ -108,6 +108,10 @@ and
.Ql %p , .Ql %p ,
to designate the current process ID; can be used in to designate the current process ID; can be used in
.Ar name . .Ar name .
.It Cm no_user_check
Do not verify if a user exists on the local system. This option implies the
.Cm no_ccache
option because there is no secure local uid/gid for the cache file.
.El .El
.Ss Kerberos 5 Account Management Module .Ss Kerberos 5 Account Management Module
The Kerberos 5 account management component The Kerberos 5 account management component

View File

@ -89,6 +89,7 @@ static void compat_free_data_contents(krb5_context, krb5_data *);
#define PAM_OPT_DEBUG "debug" #define PAM_OPT_DEBUG "debug"
#define PAM_OPT_FORWARDABLE "forwardable" #define PAM_OPT_FORWARDABLE "forwardable"
#define PAM_OPT_NO_CCACHE "no_ccache" #define PAM_OPT_NO_CCACHE "no_ccache"
#define PAM_OPT_NO_USER_CHECK "no_user_check"
#define PAM_OPT_REUSE_CCACHE "reuse_ccache" #define PAM_OPT_REUSE_CCACHE "reuse_ccache"
/* /*
@ -194,34 +195,39 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags __unused,
PAM_LOG("Got password"); PAM_LOG("Got password");
/* Verify the local user exists (AFTER getting the password) */ if (openpam_get_option(pamh, PAM_OPT_NO_USER_CHECK))
if (strchr(user, '@')) { PAM_LOG("Skipping local user check");
/* get a local account name for this principal */ else {
krbret = krb5_aname_to_localname(pam_context, princ,
sizeof(luser), luser); /* Verify the local user exists (AFTER getting the password) */
if (krbret != 0) { if (strchr(user, '@')) {
PAM_VERBOSE_ERROR("Kerberos 5 error"); /* get a local account name for this principal */
PAM_LOG("Error krb5_aname_to_localname(): %s", krbret = krb5_aname_to_localname(pam_context, princ,
krb5_get_err_text(pam_context, krbret)); sizeof(luser), luser);
if (krbret != 0) {
PAM_VERBOSE_ERROR("Kerberos 5 error");
PAM_LOG("Error krb5_aname_to_localname(): %s",
krb5_get_err_text(pam_context, krbret));
retval = PAM_USER_UNKNOWN;
goto cleanup2;
}
retval = pam_set_item(pamh, PAM_USER, luser);
if (retval != PAM_SUCCESS)
goto cleanup2;
PAM_LOG("PAM_USER Redone");
}
pwd = getpwnam(user);
if (pwd == NULL) {
retval = PAM_USER_UNKNOWN; retval = PAM_USER_UNKNOWN;
goto cleanup2; goto cleanup2;
} }
retval = pam_set_item(pamh, PAM_USER, luser); PAM_LOG("Done getpwnam()");
if (retval != PAM_SUCCESS)
goto cleanup2;
PAM_LOG("PAM_USER Redone");
} }
pwd = getpwnam(user);
if (pwd == NULL) {
retval = PAM_USER_UNKNOWN;
goto cleanup2;
}
PAM_LOG("Done getpwnam()");
/* Get a TGT */ /* Get a TGT */
memset(&creds, 0, sizeof(krb5_creds)); memset(&creds, 0, sizeof(krb5_creds));
krbret = krb5_get_init_creds_password(pam_context, &creds, princ, krbret = krb5_get_init_creds_password(pam_context, &creds, princ,
@ -366,7 +372,8 @@ pam_sm_setcred(pam_handle_t *pamh, int flags,
return (PAM_SERVICE_ERR); return (PAM_SERVICE_ERR);
/* If a persistent cache isn't desired, stop now. */ /* If a persistent cache isn't desired, stop now. */
if (openpam_get_option(pamh, PAM_OPT_NO_CCACHE)) if (openpam_get_option(pamh, PAM_OPT_NO_CCACHE) ||
openpam_get_option(pamh, PAM_OPT_NO_USER_CHECK))
return (PAM_SUCCESS); return (PAM_SUCCESS);
PAM_LOG("Establishing credentials"); PAM_LOG("Establishing credentials");

View File

@ -737,9 +737,16 @@ iap_allocate_pmc(enum pmc_event pe, char *ctrspec,
case PMC_EV_IAP_EVENT_40H: /* Core */ case PMC_EV_IAP_EVENT_40H: /* Core */
case PMC_EV_IAP_EVENT_41H: /* Core */ case PMC_EV_IAP_EVENT_41H: /* Core */
case PMC_EV_IAP_EVENT_42H: /* Core, Core2, Atom */ case PMC_EV_IAP_EVENT_42H: /* Core, Core2, Atom */
case PMC_EV_IAP_EVENT_77H: /* Core */
if (cachestate == 0) if (cachestate == 0)
cachestate = (0xF << 8); cachestate = (0xF << 8);
break;
case PMC_EV_IAP_EVENT_77H: /* Atom */
/* IAP_EVENT_77H only accepts a cachestate qualifier on the
* Atom processor
*/
if(cpu_info.pm_cputype == PMC_CPU_INTEL_ATOM && cachestate == 0)
cachestate = (0xF << 8);
break;
default: default:
break; break;
} }

View File

@ -145,7 +145,7 @@ cgialloc(struct uufsd *disk)
fs = &disk->d_fs; fs = &disk->d_fs;
cgp = &disk->d_cg; cgp = &disk->d_cg;
inosused = cg_inosused(cgp); inosused = cg_inosused(cgp);
for (ino = 0; ino < fs->fs_ipg / NBBY; ino++) for (ino = 0; ino < fs->fs_ipg; ino++)
if (isclr(inosused, ino)) if (isclr(inosused, ino))
goto gotit; goto gotit;
return (0); return (0);

View File

@ -2,15 +2,14 @@
# $FreeBSD$ # $FreeBSD$
PROG= tftpd PROG= tftpd
SRCS= tftpd.c tftpsubs.c SRCS= tftpd.c tftp-io.c tftp-utils.c tftp-file.c tftp-transfer.c tftp-options.c
DPADD= ${LIBUTIL} WARNS= 3
LDADD= -lutil
WARNS?= 1
WFORMAT=0 WFORMAT=0
MAN= tftpd.8 MAN= tftpd.8
CFLAGS+=-I${.CURDIR}/../../usr.bin/tftp CFLAGS=-g -Wall
CFLAGS+=-I${.CURDIR}/../../usr.bin/tftp -I${.CURDIR}/../../libexec/tftpd
.PATH: ${.CURDIR}/../../usr.bin/tftp .PATH: ${.CURDIR}/../../usr.bin/tftp
COPTFLAGS = -O
LDFLAGS= -lwrap
.include <bsd.prog.mk> .include <bsd.prog.mk>

257
libexec/tftpd/tftp-file.c Normal file
View File

@ -0,0 +1,257 @@
/*
* Copyright (C) 2008 Edwin Groothuis. 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 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 AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/tftp.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#include "tftp-file.h"
#include "tftp-utils.h"
static FILE *file;
static int convert;
static char convbuffer[66000];
static int gotcr = 0;
static size_t
convert_from_net(char *buffer, size_t count)
{
size_t i, n;
/*
* Convert all CR/LF to LF and all CR,NUL to CR
*/
n = 0;
for (i = 0; i < count; i++) {
if (gotcr == 0) {
convbuffer[n++] = buffer[i];
gotcr = (buffer[i] == '\r');
continue;
}
/* CR, NULL -> CR */
if (buffer[i] == '\0') {
gotcr = 0;
continue;
}
/* CR, LF -> LF */
if (buffer[i] == '\n') {
if (n == 0) {
if (ftell(file) != 0) {
fseek(file, -1, SEEK_END);
convbuffer[n++] = '\n';
} else {
/* This shouldn't happen */
tftp_log(LOG_ERR,
"Received LF as first character");
abort();
}
} else
convbuffer[n-1] = '\n';
gotcr = 0;
continue;
}
/* Everything else just accept as is */
convbuffer[n++] = buffer[i];
gotcr = (buffer[i] == '\r');
continue;
}
return fwrite(convbuffer, 1, n, file);
}
static size_t
convert_to_net(char *buffer, size_t count, int init)
{
size_t i;
static size_t n = 0, read = 0;
static int newline = 0;
if (init) {
newline = 0;
n = 0;
read = 0;
return 0 ;
}
/*
* Convert all LF to CR,LF and all CR to CR,NUL
*/
i = 0;
if (newline) {
buffer[i++] = newline;
newline = 0;
}
while (i < count) {
if (n == read) {
/* When done we're done */
if (feof(file)) break;
/* Otherwise read another bunch */
read = fread(convbuffer, 1, count, file);
if (read == 0) break;
n = 0;
}
/* CR -> CR,NULL */
if (convbuffer[n] == '\r') {
buffer[i++] = '\r';
buffer[i++] = '\0';
n++;
continue;
}
/* LF -> CR,LF */
if (convbuffer[n] == '\n') {
buffer[i++] = '\r';
buffer[i++] = '\n';
n++;
continue;
}
buffer[i++] = convbuffer[n++];
}
if (i > count) {
/*
* Whoops... that isn't alllowed (but it will happen
* when there is a CR or LF at the end of the buffer)
*/
newline = buffer[i-1];
}
if (i < count) {
/* We are done! */
return i;
} else
return count;
}
int
write_init(int fd, FILE *f, const char *mode)
{
if (f == NULL) {
file = fdopen(fd, "w");
if (file == NULL) {
int en = errno;
tftp_log(LOG_ERR, "fdopen() failed: %s",
strerror(errno));
return en;
}
} else
file = f;
convert = !strcmp(mode, "netascii");
return 0;
}
size_t
write_file(char *buffer, int count)
{
if (convert == 0)
return fwrite(buffer, 1, count, file);
return convert_from_net(buffer, count);
}
int
write_close(void)
{
if (fclose(file) != 0) {
tftp_log(LOG_ERR, "fclose() failed: %s", strerror(errno));
return 1;
}
return 0;
}
int
read_init(int fd, FILE *f, const char *mode)
{
convert_to_net(NULL, 0, 1);
if (f == NULL) {
file = fdopen(fd, "r");
if (file == NULL) {
int en = errno;
tftp_log(LOG_ERR, "fdopen() failed: %s",
strerror(errno));
return en;
}
} else
file = f;
convert = !strcmp(mode, "netascii");
return 0;
}
size_t
read_file(char *buffer, int count)
{
if (convert == 0)
return fread(buffer, 1, count, file);
return convert_to_net(buffer, count, 0);
}
int
read_close(void)
{
if (fclose(file) != 0) {
tftp_log(LOG_ERR, "fclose() failed: %s", strerror(errno));
return 1;
}
return 0;
}
int
synchnet(int peer)
{
return 0;
}

37
libexec/tftpd/tftp-file.h Normal file
View File

@ -0,0 +1,37 @@
/*
* Copyright (C) 2008 Edwin Groothuis. 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 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 AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
int write_init(int fd, FILE *f, const char *mode);
size_t write_file(char *buffer, int count);
int write_close(void);
int read_init(int fd, FILE *f, const char *mode);
size_t read_file(char *buffer, int count);
int read_close(void);
int synchnet(int peer);

478
libexec/tftpd/tftp-io.c Normal file
View File

@ -0,0 +1,478 @@
/*
* Copyright (C) 2008 Edwin Groothuis. 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 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 AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/tftp.h>
#include <arpa/inet.h>
#include <errno.h>
#include <setjmp.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#include "tftp-file.h"
#include "tftp-io.h"
#include "tftp-utils.h"
#include "tftp-options.h"
struct sockaddr_storage peer_sock;
struct sockaddr_storage me_sock;
static int send_packet(int peer, uint16_t block, char *pkt, int size);
struct errmsg {
int e_code;
const char *e_msg;
} errmsgs[] = {
{ EUNDEF, "Undefined error code" },
{ ENOTFOUND, "File not found" },
{ EACCESS, "Access violation" },
{ ENOSPACE, "Disk full or allocation exceeded" },
{ EBADOP, "Illegal TFTP operation" },
{ EBADID, "Unknown transfer ID" },
{ EEXISTS, "File already exists" },
{ ENOUSER, "No such user" },
{ EOPTNEG, "Option negotiation" },
{ -1, NULL }
};
#define DROPPACKET(s) \
if (packetdroppercentage != 0 && \
random()%100 < packetdroppercentage) { \
tftp_log(LOG_DEBUG, "Artifical packet drop in %s", s); \
return; \
}
#define DROPPACKETn(s,n) \
if (packetdroppercentage != 0 && \
random()%100 < packetdroppercentage) { \
tftp_log(LOG_DEBUG, "Artifical packet drop in %s", s); \
return (n); \
}
const char *
errtomsg(int error)
{
static char ebuf[40];
struct errmsg *pe;
char buf[MAXPKTSIZE];
if (error == 0)
return ("success");
for (pe = errmsgs; pe->e_code >= 0; pe++)
if (pe->e_code == error)
return (pe->e_msg);
snprintf(ebuf, sizeof(buf), "error %d", error);
return (ebuf);
}
static int
send_packet(int peer, uint16_t block, char *pkt, int size)
{
int i;
int t = 1;
for (i = 0; i < 12 ; i++) {
DROPPACKETn("send_packet", 0);
if (sendto(peer, pkt, size, 0,
(struct sockaddr *)&peer_sock, peer_sock.ss_len)
== size) {
if (i)
tftp_log(LOG_ERR,
"%s block %d, attempt %d successful",
block, i);
return (0);
}
tftp_log(LOG_ERR,
"%s block %d, attempt %d failed (Error %d: %s)",
packettype(ntohs(((struct tftphdr *)(pkt))->th_opcode)),
block, i, errno, strerror(errno));
sleep(t);
if (t < 32)
t <<= 1;
}
tftp_log(LOG_ERR, "send_packet: %s", strerror(errno));
return (1);
}
/*
* Send an ERROR packet (error message).
* Error code passed in is one of the
* standard TFTP codes, or a UNIX errno
* offset by 100.
*/
void
send_error(int peer, int error)
{
struct tftphdr *tp;
int length;
struct errmsg *pe;
char buf[MAXPKTSIZE];
if (debug&DEBUG_PACKETS)
tftp_log(LOG_DEBUG, "Sending ERROR %d: %s", error);
DROPPACKET("send_error");
tp = (struct tftphdr *)buf;
tp->th_opcode = htons((u_short)ERROR);
tp->th_code = htons((u_short)error);
for (pe = errmsgs; pe->e_code >= 0; pe++)
if (pe->e_code == error)
break;
if (pe->e_code < 0) {
pe->e_msg = strerror(error - 100);
tp->th_code = EUNDEF; /* set 'undef' errorcode */
}
strcpy(tp->th_msg, pe->e_msg);
length = strlen(pe->e_msg);
tp->th_msg[length] = '\0';
length += 5;
if (debug&DEBUG_PACKETS)
tftp_log(LOG_DEBUG, "Sending ERROR %d: %s", error, tp->th_msg);
if (sendto(peer, buf, length, 0,
(struct sockaddr *)&peer_sock, peer_sock.ss_len) != length)
tftp_log(LOG_ERR, "send_error: %s", strerror(errno));
}
/*
* Send an WRQ packet (write request).
*/
int
send_wrq(int peer, char *filename, char *mode)
{
int n;
struct tftphdr *tp;
char *bp;
char buf[MAXPKTSIZE];
int size;
if (debug&DEBUG_PACKETS)
tftp_log(LOG_DEBUG, "Sending WRQ: filename: '%s', mode '%s'",
filename, mode
);
DROPPACKETn("send_wrq", 1);
tp = (struct tftphdr *)buf;
tp->th_opcode = htons((u_short)WRQ);
size = 2;
bp = tp->th_stuff;
strcpy(bp, filename);
bp += strlen(filename);
*bp = 0;
bp++;
size += strlen(filename) + 1;
strcpy(bp, mode);
bp += strlen(mode);
*bp = 0;
bp++;
size += strlen(mode) + 1;
if (options_rfc_enabled)
size += make_options(peer, bp, sizeof(buf) - size);
n = sendto(peer, buf, size, 0,
(struct sockaddr *)&peer_sock, peer_sock.ss_len);
if (n != size) {
tftp_log(LOG_ERR, "send_wrq: %s", strerror(errno));
return (1);
}
return (0);
}
/*
* Send an RRQ packet (write request).
*/
int
send_rrq(int peer, char *filename, char *mode)
{
int n;
struct tftphdr *tp;
char *bp;
char buf[MAXPKTSIZE];
int size;
if (debug&DEBUG_PACKETS)
tftp_log(LOG_DEBUG, "Sending RRQ: filename: '%s', mode '%s'",
filename, mode
);
DROPPACKETn("send_rrq", 1);
tp = (struct tftphdr *)buf;
tp->th_opcode = htons((u_short)RRQ);
size = 2;
bp = tp->th_stuff;
strcpy(bp, filename);
bp += strlen(filename);
*bp = 0;
bp++;
size += strlen(filename) + 1;
strcpy(bp, mode);
bp += strlen(mode);
*bp = 0;
bp++;
size += strlen(mode) + 1;
if (options_rfc_enabled) {
options[OPT_TSIZE].o_request = strdup("0");
size += make_options(peer, bp, sizeof(buf) - size);
}
n = sendto(peer, buf, size, 0,
(struct sockaddr *)&peer_sock, peer_sock.ss_len);
if (n != size) {
tftp_log(LOG_ERR, "send_rrq: %s", n, strerror(errno));
return (1);
}
return (0);
}
/*
* Send an OACK packet (option acknowledgement).
*/
int
send_oack(int peer)
{
struct tftphdr *tp;
int size, i, n;
char *bp;
char buf[MAXPKTSIZE];
if (debug&DEBUG_PACKETS)
tftp_log(LOG_DEBUG, "Sending OACK");
DROPPACKETn("send_oack", 0);
/*
* Send back an options acknowledgement (only the ones with
* a reply for)
*/
tp = (struct tftphdr *)buf;
bp = buf + 2;
size = sizeof(buf) - 2;
tp->th_opcode = htons((u_short)OACK);
for (i = 0; options[i].o_type != NULL; i++) {
if (options[i].o_reply != NULL) {
n = snprintf(bp, size, "%s%c%s", options[i].o_type,
0, options[i].o_reply);
bp += n+1;
size -= n+1;
if (size < 0) {
tftp_log(LOG_ERR, "oack: buffer overflow");
exit(1);
}
}
}
size = bp - buf;
if (sendto(peer, buf, size, 0,
(struct sockaddr *)&peer_sock, peer_sock.ss_len) != size) {
tftp_log(LOG_INFO, "send_oack: %s", strerror(errno));
return (1);
}
return (0);
}
/*
* Send an ACK packet (acknowledgement).
*/
int
send_ack(int fp, uint16_t block)
{
struct tftphdr *tp;
int size;
char *bp;
char buf[MAXPKTSIZE];
if (debug&DEBUG_PACKETS)
tftp_log(LOG_DEBUG, "Sending ACK for block %d", block);
DROPPACKETn("send_ack", 0);
tp = (struct tftphdr *)buf;
bp = buf + 2;
size = sizeof(buf) - 2;
tp->th_opcode = htons((u_short)ACK);
tp->th_block = htons((u_short)block);
size = 4;
if (sendto(fp, buf, size, 0,
(struct sockaddr *)&peer_sock, peer_sock.ss_len) != size) {
tftp_log(LOG_INFO, "send_ack: %s", strerror(errno));
return (1);
}
return (0);
}
/*
* Send a DATA packet
*/
int
send_data(int peer, uint16_t block, char *data, int size)
{
char buf[MAXPKTSIZE];
struct tftphdr *pkt;
int n;
if (debug&DEBUG_PACKETS)
tftp_log(LOG_DEBUG, "Sending DATA packet %d of %d bytes",
block, size);
DROPPACKETn("send_data", 0);
pkt = (struct tftphdr *)buf;
pkt->th_opcode = htons((u_short)DATA);
pkt->th_block = htons((u_short)block);
memcpy(pkt->th_data, data, size);
n = send_packet(peer, block, (char *)pkt, size + 4);
return (n);
}
/*
* Receive a packet
*/
jmp_buf timeoutbuf;
static void
timeout(int sig __unused)
{
/* tftp_log(LOG_DEBUG, "Timeout\n"); Inside a signal handler... */
longjmp(timeoutbuf, 1);
}
int
receive_packet(int peer, char *data, int size, struct sockaddr_storage *from,
int thistimeout)
{
struct tftphdr *pkt;
struct sockaddr_storage from_local;
struct sockaddr_storage *pfrom;
socklen_t fromlen;
int n;
static int waiting;
pfrom = (from == NULL) ? &from_local : from;
if (debug&DEBUG_PACKETS)
tftp_log(LOG_DEBUG,
"Waiting %d seconds for packet", timeoutpacket);
pkt = (struct tftphdr *)data;
waiting = 0;
signal(SIGALRM, timeout);
setjmp(timeoutbuf);
alarm(thistimeout);
if (waiting > 0) {
alarm(0);
return (RP_TIMEOUT);
}
if (waiting > 0) {
tftp_log(LOG_ERR, "receive_packet: timeout");
alarm(0);
return (RP_TIMEOUT);
}
waiting++;
fromlen = sizeof(*pfrom);
n = recvfrom(peer, data, size, 0, (struct sockaddr *)pfrom, &fromlen);
alarm(0);
DROPPACKETn("receive_packet", RP_TIMEOUT);
if (n < 0) {
tftp_log(LOG_ERR, "receive_packet: timeout");
return (RP_TIMEOUT);
}
alarm(0);
if (n < 0) {
/* No idea what could have happened if it isn't a timeout */
tftp_log(LOG_ERR, "receive_packet: %s", strerror(errno));
return (RP_RECVFROM);
}
if (n < 4) {
tftp_log(LOG_ERR,
"receive_packet: packet too small (%d bytes)", n);
return (RP_TOOSMALL);
}
pkt->th_opcode = ntohs((u_short)pkt->th_opcode);
if (pkt->th_opcode == DATA ||
pkt->th_opcode == ACK)
pkt->th_block = ntohs((u_short)pkt->th_block);
if (pkt->th_opcode == DATA && n > pktsize) {
tftp_log(LOG_ERR, "receive_packet: packet too big");
return (RP_TOOBIG);
}
if (((struct sockaddr_in *)(pfrom))->sin_addr.s_addr !=
((struct sockaddr_in *)(&peer_sock))->sin_addr.s_addr) {
tftp_log(LOG_ERR,
"receive_packet: received packet from wrong source");
return (RP_WRONGSOURCE);
}
if (pkt->th_opcode == ERROR) {
tftp_log(LOG_ERR, "Got ERROR packet: %s", pkt->th_msg);
return (RP_ERROR);
}
if (debug&DEBUG_PACKETS)
tftp_log(LOG_DEBUG, "Received %d bytes in a %s packet",
n, packettype(pkt->th_opcode));
return n - 4;
}

47
libexec/tftpd/tftp-io.h Normal file
View File

@ -0,0 +1,47 @@
/*
* Copyright (C) 2008 Edwin Groothuis. 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 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 AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#define RP_NONE 0
#define RP_RECVFROM -1
#define RP_TOOSMALL -2
#define RP_ERROR -3
#define RP_WRONGSOURCE -4
#define RP_TIMEOUT -5
#define RP_TOOBIG -6
const char *errtomsg(int);
void send_error(int peer, int);
int send_wrq(int peer, char *, char *);
int send_rrq(int peer, char *, char *);
int send_oack(int peer);
int send_ack(int peer, unsigned short);
int send_data(int peer, uint16_t, char *, int);
int receive_packet(int peer, char *, int, struct sockaddr_storage *, int);
extern struct sockaddr_storage peer_sock;
extern struct sockaddr_storage me_sock;

View File

@ -0,0 +1,390 @@
/*
* Copyright (C) 2008 Edwin Groothuis. 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 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 AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/sysctl.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/tftp.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include "tftp-utils.h"
#include "tftp-io.h"
#include "tftp-options.h"
/*
* Option handlers
*/
struct options options[] = {
{ "tsize", NULL, NULL, NULL /* option_tsize */, 1 },
{ "timeout", NULL, NULL, option_timeout, 1 },
{ "blksize", NULL, NULL, option_blksize, 1 },
{ "blksize2", NULL, NULL, option_blksize2, 0 },
{ "rollover", NULL, NULL, option_rollover, 0 },
{ NULL, NULL, NULL, NULL, 0 }
};
/* By default allow them */
int options_rfc_enabled = 1;
int options_extra_enabled = 1;
/*
* Rules for the option handlers:
* - If there is no o_request, there will be no processing.
*
* For servers
* - Logging is done as warnings.
* - The handler exit()s if there is a serious problem with the
* values submitted in the option.
*
* For clients
* - Logging is done as errors. After all, the server shouldn't
* return rubbish.
* - The handler returns if there is a serious problem with the
* values submitted in the option.
* - Sending the EBADOP packets is done by the handler.
*/
int
option_tsize(int peer, struct tftphdr *tp, int mode, struct stat *stbuf)
{
if (options[OPT_TSIZE].o_request == NULL)
return (0);
if (mode == RRQ)
asprintf(&options[OPT_TSIZE].o_reply,
"%ju", stbuf->st_size);
else
/* XXX Allows writes of all sizes. */
options[OPT_TSIZE].o_reply =
strdup(options[OPT_TSIZE].o_request);
return (0);
}
int
option_timeout(int peer)
{
if (options[OPT_TIMEOUT].o_request == NULL)
return (0);
int to = atoi(options[OPT_TIMEOUT].o_request);
if (to < TIMEOUT_MIN || to > TIMEOUT_MAX) {
tftp_log(acting_as_client ? LOG_ERR : LOG_WARNING,
"Received bad value for timeout. "
"Should be between %d and %d, received %s",
TIMEOUT_MIN, TIMEOUT_MAX);
send_error(peer, EBADOP);
if (acting_as_client)
return (1);
exit(1);
} else {
timeoutpacket = to;
options[OPT_TIMEOUT].o_reply =
strdup(options[OPT_TIMEOUT].o_request);
}
settimeouts(timeoutpacket, timeoutnetwork, maxtimeouts);
if (debug&DEBUG_OPTIONS)
tftp_log(LOG_DEBUG, "Setting timeout to '%s'",
options[OPT_TIMEOUT].o_reply);
return (0);
}
int
option_rollover(int peer)
{
if (options[OPT_ROLLOVER].o_request == NULL)
return (0);
if (strcmp(options[OPT_ROLLOVER].o_request, "0") != 0
&& strcmp(options[OPT_ROLLOVER].o_request, "1") != 0) {
tftp_log(acting_as_client ? LOG_ERR : LOG_WARNING,
"Bad value for rollover, "
"should be either 0 or 1, received '%s', "
"ignoring request",
options[OPT_ROLLOVER].o_request);
if (acting_as_client) {
send_error(peer, EBADOP);
return (1);
}
return (0);
}
options[OPT_ROLLOVER].o_reply =
strdup(options[OPT_ROLLOVER].o_request);
if (debug&DEBUG_OPTIONS)
tftp_log(LOG_DEBUG, "Setting rollover to '%s'",
options[OPT_ROLLOVER].o_reply);
return (0);
}
int
option_blksize(int peer)
{
int *maxdgram;
char maxbuffer[100];
size_t len;
if (options[OPT_BLKSIZE].o_request == NULL)
return (0);
/* maximum size of an UDP packet according to the system */
len = sizeof(maxbuffer);
if (sysctlbyname("net.inet.udp.maxdgram",
maxbuffer, &len, NULL, 0) < 0) {
tftp_log(LOG_ERR, "sysctl: net.inet.udp.maxdgram");
return (acting_as_client ? 1 : 0);
}
maxdgram = (int *)maxbuffer;
int size = atoi(options[OPT_BLKSIZE].o_request);
if (size < BLKSIZE_MIN || size > BLKSIZE_MAX) {
if (acting_as_client) {
tftp_log(LOG_ERR,
"Invalid blocksize (%d bytes), aborting",
size);
send_error(peer, EBADOP);
return (1);
} else {
tftp_log(LOG_WARNING,
"Invalid blocksize (%d bytes), ignoring request",
size);
return (0);
}
}
if (size > *maxdgram) {
if (acting_as_client) {
tftp_log(LOG_ERR,
"Invalid blocksize (%d bytes), "
"net.inet.udp.maxdgram sysctl limits it to "
"%d bytes.\n", size, *maxdgram);
send_error(peer, EBADOP);
return (1);
} else {
tftp_log(LOG_WARNING,
"Invalid blocksize (%d bytes), "
"net.inet.udp.maxdgram sysctl limits it to "
"%d bytes.\n", size, *maxdgram);
size = *maxdgram;
/* No reason to return */
}
}
asprintf(&options[OPT_BLKSIZE].o_reply, "%d", size);
segsize = size;
pktsize = size + 4;
if (debug&DEBUG_OPTIONS)
tftp_log(LOG_DEBUG, "Setting blksize to '%s'",
options[OPT_BLKSIZE].o_reply);
return (0);
}
int
option_blksize2(int peer)
{
int *maxdgram;
char maxbuffer[100];
int size, i;
size_t len;
int sizes[] = {
8, 16, 32, 64, 128, 256, 512, 1024,
2048, 4096, 8192, 16384, 32768, 0
};
if (options[OPT_BLKSIZE2].o_request == NULL)
return (0);
/* maximum size of an UDP packet according to the system */
len = sizeof(maxbuffer);
if (sysctlbyname("net.inet.udp.maxdgram",
maxbuffer, &len, NULL, 0) < 0) {
tftp_log(LOG_ERR, "sysctl: net.inet.udp.maxdgram");
return (acting_as_client ? 1 : 0);
}
maxdgram = (int *)maxbuffer;
size = atoi(options[OPT_BLKSIZE2].o_request);
for (i = 0; sizes[i] != 0; i++) {
if (size == sizes[i]) break;
}
if (sizes[i] == 0) {
tftp_log(LOG_INFO,
"Invalid blocksize2 (%d bytes), ignoring request", size);
return (acting_as_client ? 1 : 0);
}
if (size > *maxdgram) {
for (i = 0; sizes[i+1] != 0; i++) {
if (*maxdgram < sizes[i+1]) break;
}
tftp_log(LOG_INFO,
"Invalid blocksize2 (%d bytes), net.inet.udp.maxdgram "
"sysctl limits it to %d bytes.\n", size, *maxdgram);
size = sizes[i];
/* No need to return */
}
asprintf(&options[OPT_BLKSIZE2].o_reply, "%d", size);
segsize = size;
pktsize = size + 4;
if (debug&DEBUG_OPTIONS)
tftp_log(LOG_DEBUG, "Setting blksize2 to '%s'",
options[OPT_BLKSIZE2].o_reply);
return (0);
}
/*
* Append the available options to the header
*/
uint16_t
make_options(int peer, char *buffer, uint16_t size) {
int i;
char *value;
const char *option;
uint16_t length;
uint16_t returnsize = 0;
if (!options_rfc_enabled) return (0);
for (i = 0; options[i].o_type != NULL; i++) {
if (options[i].rfc == 0 && !options_extra_enabled)
continue;
option = options[i].o_type;
if (acting_as_client)
value = options[i].o_request;
else
value = options[i].o_reply;
if (value == NULL)
continue;
length = strlen(value) + strlen(option) + 2;
if (size <= length) {
tftp_log(LOG_ERR,
"Running out of option space for "
"option '%s' with value '%s': "
"needed %d bytes, got %d bytes",
option, value, size, length);
continue;
}
sprintf(buffer, "%s%c%s%c", option, '\000', value, '\000');
size -= length;
buffer += length;
returnsize += length;
}
return (returnsize);
}
/*
* Parse the received options in the header
*/
int
parse_options(int peer, char *buffer, uint16_t size)
{
int i, options_failed;
char *c, *cp, *option, *value;
if (!options_rfc_enabled) return (0);
/* Parse the options */
cp = buffer;
options_failed = 0;
while (size > 0) {
option = cp;
i = get_field(peer, cp, size);
cp += i;
value = cp;
i = get_field(peer, cp, size);
cp += i;
/* We are at the end */
if (*option == '\0') break;
if (debug&DEBUG_OPTIONS)
tftp_log(LOG_DEBUG,
"option: '%s' value: '%s'", option, value);
for (c = option; *c; c++)
if (isupper(*c))
*c = tolower(*c);
for (i = 0; options[i].o_type != NULL; i++) {
if (strcmp(option, options[i].o_type) == 0) {
if (!acting_as_client)
options[i].o_request = value;
if (!options_extra_enabled && !options[i].rfc) {
tftp_log(LOG_INFO,
"Option '%s' with value '%s' found "
"but it is not an RFC option",
option, value);
continue;
}
if (options[i].o_handler)
options_failed +=
(options[i].o_handler)(peer);
break;
}
}
if (options[i].o_type == NULL)
tftp_log(LOG_WARNING,
"Unknown option: '%s'", option);
size -= strlen(option) + strlen(value) + 2;
}
return (options_failed);
}
/*
* Set some default values in the options
*/
void
init_options(void)
{
options[OPT_ROLLOVER].o_request = strdup("0");
}

View File

@ -0,0 +1,62 @@
/*
* Copyright (C) 2008 Edwin Groothuis. 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 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 AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
* Options
*/
void init_options(void);
uint16_t make_options(int peer, char *buffer, uint16_t size);
int parse_options(int peer, char *buffer, uint16_t size);
/* Call back functions */
int option_tsize(int peer, struct tftphdr *, int, struct stat *);
int option_timeout(int peer);
int option_blksize(int peer);
int option_blksize2(int peer);
int option_rollover(int peer);
extern int options_extra_enabled;
extern int options_rfc_enabled;
struct options {
const char *o_type;
char *o_request;
char *o_reply;
int (*o_handler)(int peer);
int rfc;
};
extern struct options options[];
enum opt_enum {
OPT_TSIZE = 0,
OPT_TIMEOUT,
OPT_BLKSIZE,
OPT_BLKSIZE2,
OPT_ROLLOVER,
};

View File

@ -0,0 +1,318 @@
/*
* Copyright (C) 2008 Edwin Groothuis. 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 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 AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/tftp.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>
#include "tftp-file.h"
#include "tftp-io.h"
#include "tftp-utils.h"
#include "tftp-options.h"
#include "tftp-transfer.h"
/*
* Send a file via the TFTP data session.
*/
void
tftp_send(int peer, uint16_t *block, struct tftp_stats *ts)
{
struct tftphdr *rp;
int size, n_data, n_ack, try;
uint16_t oldblock;
char sendbuffer[MAXPKTSIZE];
char recvbuffer[MAXPKTSIZE];
rp = (struct tftphdr *)recvbuffer;
*block = 1;
ts->amount = 0;
do {
if (debug&DEBUG_SIMPLE)
tftp_log(LOG_DEBUG, "Sending block %d", *block);
size = read_file(sendbuffer, segsize);
if (size < 0) {
tftp_log(LOG_ERR, "read_file returned %d", size);
send_error(peer, errno + 100);
goto abort;
}
for (try = 0; ; try++) {
n_data = send_data(peer, *block, sendbuffer, size);
if (n_data > 0) {
if (try == maxtimeouts) {
tftp_log(LOG_ERR,
"Cannot send DATA packet #%d, "
"giving up", *block);
return;
}
tftp_log(LOG_ERR,
"Cannot send DATA packet #%d, trying again",
*block);
continue;
}
n_ack = receive_packet(peer, recvbuffer,
MAXPKTSIZE, NULL, timeoutpacket);
if (n_ack < 0) {
if (n_ack == RP_TIMEOUT) {
if (try == maxtimeouts) {
tftp_log(LOG_ERR,
"Timeout #%d send ACK %d "
"giving up", try, *block);
return;
}
tftp_log(LOG_WARNING,
"Timeout #%d on ACK %d",
try, *block);
continue;
}
/* Either read failure or ERROR packet */
if (debug&DEBUG_SIMPLE)
tftp_log(LOG_ERR, "Aborting: %s",
rp_strerror(n_ack));
goto abort;
}
if (rp->th_opcode == ACK) {
ts->blocks++;
if (rp->th_block == *block) {
ts->amount += size;
break;
}
/* Re-synchronize with the other side */
(void) synchnet(peer);
if (rp->th_block == (*block - 1)) {
ts->retries++;
continue;
}
}
}
oldblock = *block;
(*block)++;
if (oldblock > *block) {
if (options[OPT_ROLLOVER].o_request == NULL) {
tftp_log(LOG_ERR,
"Block rollover but not allowed.");
send_error(peer, EBADOP);
gettimeofday(&(ts->tstop), NULL);
return;
}
*block = atoi(options[OPT_ROLLOVER].o_request);
ts->rollovers++;
}
gettimeofday(&(ts->tstop), NULL);
} while (size == segsize);
abort:
return;
}
/*
* Receive a file via the TFTP data session.
*
* - It could be that the first block has already arrived while
* trying to figure out if we were receiving options or not. In
* that case it is passed to this function.
*/
void
tftp_receive(int peer, uint16_t *block, struct tftp_stats *ts,
struct tftphdr *firstblock, size_t fb_size)
{
struct tftphdr *rp;
uint16_t oldblock;
int n_data, n_ack, writesize, i, retry;
char recvbuffer[MAXPKTSIZE];
ts->amount = 0;
if (firstblock != NULL) {
writesize = write_file(firstblock->th_data, fb_size);
ts->amount += writesize;
for (i = 0; ; i++) {
n_ack = send_ack(peer, *block);
if (n_ack > 0) {
if (i == maxtimeouts) {
tftp_log(LOG_ERR,
"Cannot send ACK packet #%d, "
"giving up", *block);
return;
}
tftp_log(LOG_ERR,
"Cannot send ACK packet #%d, trying again",
*block);
continue;
}
break;
}
if (fb_size != segsize) {
gettimeofday(&(ts->tstop), NULL);
return;
}
}
rp = (struct tftphdr *)recvbuffer;
do {
oldblock = *block;
(*block)++;
if (oldblock > *block) {
if (options[OPT_ROLLOVER].o_request == NULL) {
tftp_log(LOG_ERR,
"Block rollover but not allowed.");
send_error(peer, EBADOP);
gettimeofday(&(ts->tstop), NULL);
return;
}
*block = atoi(options[OPT_ROLLOVER].o_request);
ts->rollovers++;
}
for (retry = 0; ; retry++) {
if (debug&DEBUG_SIMPLE)
tftp_log(LOG_DEBUG,
"Receiving DATA block %d", *block);
n_data = receive_packet(peer, recvbuffer,
MAXPKTSIZE, NULL, timeoutpacket);
if (n_data < 0) {
if (retry == maxtimeouts) {
tftp_log(LOG_ERR,
"Timeout #%d on DATA block %d, "
"giving up", retry, *block);
return;
}
if (n_data == RP_TIMEOUT) {
tftp_log(LOG_WARNING,
"Timeout #%d on DATA block %d",
retry, *block);
send_ack(peer, oldblock);
continue;
}
/* Either read failure or ERROR packet */
if (debug&DEBUG_SIMPLE)
tftp_log(LOG_DEBUG, "Aborting: %s",
rp_strerror(n_data));
goto abort;
}
if (rp->th_opcode == DATA) {
ts->blocks++;
if (rp->th_block == *block)
break;
tftp_log(LOG_WARNING,
"Expected DATA block %d, got block %d",
*block, rp->th_block);
/* Re-synchronize with the other side */
(void) synchnet(peer);
if (rp->th_block == (*block-1)) {
tftp_log(LOG_INFO, "Trying to sync");
*block = oldblock;
ts->retries++;
goto send_ack; /* rexmit */
}
} else {
tftp_log(LOG_WARNING,
"Expected DATA block, got %s block",
packettype(rp->th_opcode));
}
}
if (n_data > 0) {
writesize = write_file(rp->th_data, n_data);
ts->amount += writesize;
if (writesize <= 0) {
tftp_log(LOG_ERR,
"write_file returned %d", writesize);
if (writesize < 0)
send_error(peer, errno + 100);
else
send_error(peer, ENOSPACE);
goto abort;
}
}
send_ack:
for (i = 0; ; i++) {
n_ack = send_ack(peer, *block);
if (n_ack > 0) {
if (i == maxtimeouts) {
tftp_log(LOG_ERR,
"Cannot send ACK packet #%d, "
"giving up", *block);
return;
}
tftp_log(LOG_ERR,
"Cannot send ACK packet #%d, trying again",
*block);
continue;
}
break;
}
gettimeofday(&(ts->tstop), NULL);
} while (n_data == segsize);
/* Don't do late packet management for the client implementation */
if (acting_as_client)
return;
for (i = 0; ; i++) {
n_data = receive_packet(peer, (char *)rp, pktsize,
NULL, timeoutpacket);
if (n_data <= 0)
break;
if (n_data > 0 &&
rp->th_opcode == DATA && /* and got a data block */
*block == rp->th_block) /* then my last ack was lost */
send_ack(peer, *block); /* resend final ack */
}
abort:
return;
}

View File

@ -0,0 +1,31 @@
/*
* Copyright (C) 2008 Edwin Groothuis. 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 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 AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
void tftp_send(int peer, uint16_t *block, struct tftp_stats *tp);
void tftp_receive(int peer, uint16_t *block, struct tftp_stats *tp,
struct tftphdr *firstblock, size_t fb_size);

320
libexec/tftpd/tftp-utils.c Normal file
View File

@ -0,0 +1,320 @@
/*
* Copyright (C) 2008 Edwin Groothuis. 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 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 AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/tftp.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include "tftp-utils.h"
#include "tftp-io.h"
/*
* Default values, can be changed later via the TFTP Options
*/
int timeoutpacket = TIMEOUT;
int timeoutnetwork = MAX_TIMEOUTS * TIMEOUT;
int maxtimeouts = MAX_TIMEOUTS;
uint16_t segsize = SEGSIZE;
uint16_t pktsize = SEGSIZE + 4;
int acting_as_client;
/*
* Set timeout values for packet reception. The idea is that you
* get 'maxtimeouts' of 5 seconds between 'timeoutpacket' (i.e. the
* first timeout) to 'timeoutnetwork' (i.e. the last timeout)
*/
int
settimeouts(int _timeoutpacket, int _timeoutnetwork, int _maxtimeouts)
{
int i;
/* We cannot do impossible things */
if (_timeoutpacket >= _timeoutnetwork)
return (0);
maxtimeouts = 0;
i = _timeoutpacket;
while (i < _timeoutnetwork || maxtimeouts < MIN_TIMEOUTS) {
maxtimeouts++;
i += 5;
}
timeoutpacket = _timeoutpacket;
timeoutnetwork = i;
return (1);
}
/* translate IPv4 mapped IPv6 address to IPv4 address */
void
unmappedaddr(struct sockaddr_in6 *sin6)
{
struct sockaddr_in *sin4;
u_int32_t addr;
int port;
if (sin6->sin6_family != AF_INET6 ||
!IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr))
return;
sin4 = (struct sockaddr_in *)sin6;
addr = *(u_int32_t *)&sin6->sin6_addr.s6_addr[12];
port = sin6->sin6_port;
memset(sin4, 0, sizeof(struct sockaddr_in));
sin4->sin_addr.s_addr = addr;
sin4->sin_port = port;
sin4->sin_family = AF_INET;
sin4->sin_len = sizeof(struct sockaddr_in);
}
/* Get a field from a \0 seperated string */
ssize_t
get_field(int peer, char *buffer, ssize_t size)
{
char *cp = buffer;
while (cp < buffer + size) {
if (*cp == '\0') break;
cp++;
}
if (*cp != '\0') {
tftp_log(LOG_ERR, "Bad option - no trailing \\0 found");
send_error(peer, EBADOP);
exit(1);
}
return (cp - buffer + 1);
}
/*
* Logging functions
*/
int _tftp_logtostdout = 1;
void
tftp_openlog(const char *ident, int logopt, int facility)
{
_tftp_logtostdout = (ident == NULL);
if (_tftp_logtostdout == 0)
openlog(ident, logopt, facility);
}
void
tftp_closelog(void)
{
if (_tftp_logtostdout == 0)
closelog();
}
void
tftp_log(int priority, const char *message, ...)
{
va_list ap;
char *s;
va_start(ap, message);
if (_tftp_logtostdout == 0) {
vasprintf(&s, message, ap);
syslog(priority, "%s", s);
} else {
vprintf(message, ap);
printf("\n");
}
va_end(ap);
}
/*
* Packet types
*/
struct packettypes packettypes[] = {
{ RRQ, "RRQ" },
{ WRQ, "WRQ" },
{ DATA, "DATA" },
{ ACK, "ACK" },
{ ERROR, "ERROR" },
{ OACK, "OACK" },
{ 0, NULL },
};
char *
packettype(int type)
{
static char failed[100];
int i = 0;
while (packettypes[i].name != NULL) {
if (packettypes[i].value == type)
break;
i++;
}
if (packettypes[i].name != NULL)
return packettypes[i].name;
sprintf(failed, "unknown (type: %d)", type);
return (failed);
}
/*
* Debugs
*/
int debug = DEBUG_NONE;
struct debugs debugs[] = {
{ DEBUG_PACKETS, "packet", "Packet debugging" },
{ DEBUG_SIMPLE, "simple", "Simple debugging" },
{ DEBUG_OPTIONS, "options", "Options debugging" },
{ DEBUG_ACCESS, "access", "TCPd access debugging" },
{ DEBUG_NONE, NULL, "No debugging" },
};
int packetdroppercentage = 0;
int
debug_find(char *s)
{
int i = 0;
while (debugs[i].name != NULL) {
if (strcasecmp(debugs[i].name, s) == 0)
break;
i++;
}
return (debugs[i].value);
}
int
debug_finds(char *s)
{
int i = 0;
char *ps = s;
while (s != NULL) {
ps = strchr(s, ' ');
if (ps != NULL)
*ps = '\0';
i += debug_find(s);
if (ps != NULL)
*ps = ' ';
s = ps;
}
return (i);
}
char *
debug_show(int d)
{
static char s[100];
int i = 0;
s[0] = '\0';
while (debugs[i].name != NULL) {
if (d&debugs[i].value) {
if (s[0] != '\0')
strcat(s, " ");
strcat(s, debugs[i].name);
}
i++;
}
if (s[0] != '\0')
return (s);
return ("none");
}
/*
* RP_
*/
struct rp_errors rp_errors[] = {
{ RP_TIMEOUT, "Network timeout" },
{ RP_TOOSMALL, "Not enough data bytes" },
{ RP_WRONGSOURCE, "Invalid IP address of UDP port" },
{ RP_ERROR, "Error packet" },
{ RP_RECVFROM, "recvfrom() complained" },
{ RP_TOOBIG, "Too many data bytes" },
{ RP_NONE, NULL }
};
char *
rp_strerror(int error)
{
static char s[100];
int i = 0;
while (rp_errors[i].desc != NULL) {
if (rp_errors[i].error == error) {
strcpy(s, rp_errors[i].desc);
}
i++;
}
if (s[0] == '\0')
sprintf(s, "unknown (error=%d)", error);
return (s);
}
/*
* Performance figures
*/
void
stats_init(struct tftp_stats *ts)
{
ts->amount = 0;
ts->rollovers = 0;
ts->retries = 0;
ts->blocks = 0;
ts->amount = 0;
gettimeofday(&(ts->tstart), NULL);
}
void
printstats(const char *direction, int verbose, struct tftp_stats *ts)
{
double delta; /* compute delta in 1/10's second units */
delta = ((ts->tstop.tv_sec*10.)+(ts->tstop.tv_usec/100000)) -
((ts->tstart.tv_sec*10.)+(ts->tstart.tv_usec/100000));
delta = delta/10.; /* back to seconds */
printf("%s %zu bytes during %.1f seconds in %u blocks",
direction, ts->amount, delta, ts->blocks);
if (ts->rollovers != 0)
printf(" with %d rollover%s",
ts->rollovers, ts->rollovers != 1 ? "s" : "");
if (verbose)
printf(" [%.0f bits/sec]", (ts->amount*8.)/delta);
putchar('\n');
}

124
libexec/tftpd/tftp-utils.h Normal file
View File

@ -0,0 +1,124 @@
/*
* Copyright (C) 2008 Edwin Groothuis. 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 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 AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
*/
#define TIMEOUT 5
#define MAX_TIMEOUTS 5
/* Generic values */
#define MAXSEGSIZE 65464 /* Maximum size of the data segment */
#define MAXPKTSIZE (MAXSEGSIZE + 4) /* Maximum size of the packet */
/* For the blksize option */
#define BLKSIZE_MIN 8 /* Minumum size of the data segment */
#define BLKSIZE_MAX MAXSEGSIZE /* Maximum size of the data segment */
/* For the timeout option */
#define TIMEOUT_MIN 0 /* Minumum timeout value */
#define TIMEOUT_MAX 255 /* Maximum timeout value */
#define MIN_TIMEOUTS 3
extern int timeoutpacket;
extern int timeoutnetwork;
extern int maxtimeouts;
int settimeouts(int timeoutpacket, int timeoutnetwork, int maxtimeouts);
extern uint16_t segsize;
extern uint16_t pktsize;
extern int acting_as_client;
/*
*/
void unmappedaddr(struct sockaddr_in6 *sin6);
ssize_t get_field(int peer, char *buffer, ssize_t size);
/*
* Packet types
*/
struct packettypes {
int value;
char *name;
};
extern struct packettypes packettypes[];
char *packettype(int);
/*
* RP_
*/
struct rp_errors {
int error;
char *desc;
};
extern struct rp_errors rp_errors[];
char *rp_strerror(int error);
/*
* Debug features
*/
#define DEBUG_NONE 0x0000
#define DEBUG_PACKETS 0x0001
#define DEBUG_SIMPLE 0x0002
#define DEBUG_OPTIONS 0x0004
#define DEBUG_ACCESS 0x0008
struct debugs {
int value;
char *name;
char *desc;
};
extern int debug;
extern struct debugs debugs[];
extern int packetdroppercentage;
int debug_find(char *s);
int debug_finds(char *s);
char *debug_show(int d);
/*
* Log routines
*/
#define DEBUG(s) tftp_log(LOG_DEBUG, "%s", s)
extern int tftp_logtostdout;
void tftp_openlog(const char *ident, int logopt, int facility);
void tftp_closelog(void);
void tftp_log(int priority, const char *message, ...);
/*
* Performance figures
*/
struct tftp_stats {
size_t amount;
int rollovers;
uint32_t blocks;
int retries;
struct timeval tstart;
struct timeval tstop;
};
void stats_init(struct tftp_stats *ts);
void printstats(const char *direction, int verbose, struct tftp_stats *ts);

View File

@ -40,7 +40,7 @@
.Nd Internet Trivial File Transfer Protocol server .Nd Internet Trivial File Transfer Protocol server
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm tftpd .Nm tftpd
.Op Fl cClnwW .Op Fl cdClnow
.Op Fl F Ar strftime-format .Op Fl F Ar strftime-format
.Op Fl s Ar directory .Op Fl s Ar directory
.Op Fl u Ar user .Op Fl u Ar user
@ -150,6 +150,9 @@ compatible format string for the creation of the suffix if
.Fl W .Fl W
is specified. is specified.
By default the string "%Y%m%d" is used. By default the string "%Y%m%d" is used.
.It Fl d
Enables debug output.
If specified twice, it will log DATA and ACK packets too.
.It Fl l .It Fl l
Log all requests using Log all requests using
.Xr syslog 3 .Xr syslog 3
@ -164,6 +167,8 @@ must also be enabled in the syslog configuration file,
.It Fl n .It Fl n
Suppress negative acknowledgement of requests for nonexistent Suppress negative acknowledgement of requests for nonexistent
relative filenames. relative filenames.
.It Fl o
Disable support for RFC2347 style TFTP Options.
.It Fl s Ar directory .It Fl s Ar directory
Cause Cause
.Nm .Nm
@ -240,10 +245,16 @@ and the
and and
.Fl W .Fl W
options were introduced in options were introduced in
.Fx 8.0 . .Fx 7 .
.Pp .Pp
Support for Timeout Interval and Transfer Size Options (RFC2349)
was introduced in
.Fx 5.0 ,
support for the TFTP Blocksize Option (RFC2348) and the blksize2 option
was introduced in
.Fx 7 .
.Sh BUGS .Sh BUGS
Files larger than 33488896 octets (65535 blocks) cannot be transferred Files larger than 33488896 octets (65535 blocks) cannot be transferred
without client and server supporting blocksize negotiation (RFC1783). without client and server supporting blocksize negotiation (RFC2348).
.Pp .Pp
Many tftp clients will not transfer files over 16744448 octets (32767 blocks). Many tftp clients will not transfer files over 16744448 octets (32767 blocks).

File diff suppressed because it is too large Load Diff

View File

@ -27,7 +27,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd January 20, 2010 .Dd May 2, 2010
.Dt CAMCONTROL 8 .Dt CAMCONTROL 8
.Os .Os
.Sh NAME .Sh NAME
@ -123,6 +123,8 @@
.Op generic args .Op generic args
.Aq Fl a Ar cmd Op args .Aq Fl a Ar cmd Op args
.Aq Fl c Ar cmd Op args .Aq Fl c Ar cmd Op args
.Op Fl d
.Op Fl f
.Op Fl i Ar len Ar fmt .Op Fl i Ar len Ar fmt
.Bk -words .Bk -words
.Op Fl o Ar len Ar fmt Op args .Op Fl o Ar len Ar fmt Op args
@ -530,6 +532,10 @@ lba_high_exp, features_exp, sector_count, sector_count_exp).
.It Fl c Ar cmd Op args .It Fl c Ar cmd Op args
This specifies the SCSI CDB. This specifies the SCSI CDB.
SCSI CDBs may be 6, 10, 12 or 16 bytes. SCSI CDBs may be 6, 10, 12 or 16 bytes.
.It Fl d
Specifies DMA protocol to be used for ATA command.
.It Fl f
Specifies FPDMA (NCQ) protocol to be used for ATA command.
.It Fl i Ar len Ar fmt .It Fl i Ar len Ar fmt
This specifies the amount of data to read, and how it should be displayed. This specifies the amount of data to read, and how it should be displayed.
If the format is If the format is

View File

@ -123,7 +123,7 @@ struct camcontrol_opts {
}; };
#ifndef MINIMALISTIC #ifndef MINIMALISTIC
static const char scsicmd_opts[] = "a:c:i:o:r"; static const char scsicmd_opts[] = "a:c:dfi:o:r";
static const char readdefect_opts[] = "f:GP"; static const char readdefect_opts[] = "f:GP";
static const char negotiate_opts[] = "acD:M:O:qR:T:UW:"; static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
#endif #endif
@ -2184,6 +2184,8 @@ scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
int c, data_bytes = 0; int c, data_bytes = 0;
int cdb_len = 0; int cdb_len = 0;
int atacmd_len = 0; int atacmd_len = 0;
int dmacmd = 0;
int fpdmacmd = 0;
int need_res = 0; int need_res = 0;
char *datastr = NULL, *tstr, *resstr = NULL; char *datastr = NULL, *tstr, *resstr = NULL;
int error = 0; int error = 0;
@ -2246,6 +2248,12 @@ scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
*/ */
optind += hook.got; optind += hook.got;
break; break;
case 'd':
dmacmd = 1;
break;
case 'f':
fpdmacmd = 1;
break;
case 'i': case 'i':
if (arglist & CAM_ARG_CMD_OUT) { if (arglist & CAM_ARG_CMD_OUT) {
warnx("command must either be " warnx("command must either be "
@ -2422,6 +2430,10 @@ scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len); bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
if (need_res) if (need_res)
ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT; ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
if (dmacmd)
ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
if (fpdmacmd)
ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
cam_fill_ataio(&ccb->ataio, cam_fill_ataio(&ccb->ataio,
/*retries*/ retry_count, /*retries*/ retry_count,
@ -2843,6 +2855,10 @@ cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
fprintf(stdout, "%sNumber of tags: %d\n", pathstr, fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
sata->tags); sata->tags);
} }
if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
sata->caps);
}
} }
if (cts->protocol == PROTO_SCSI) { if (cts->protocol == PROTO_SCSI) {
struct ccb_trans_settings_scsi *scsi= struct ccb_trans_settings_scsi *scsi=
@ -4353,7 +4369,7 @@ usage(int verbose)
" [-P pagectl][-e | -b][-d]\n" " [-P pagectl][-e | -b][-d]\n"
" camcontrol cmd [dev_id][generic args]\n" " camcontrol cmd [dev_id][generic args]\n"
" <-a cmd [args] | -c cmd [args]>\n" " <-a cmd [args] | -c cmd [args]>\n"
" [-i len fmt|-o len fmt [args]] [-r fmt]\n" " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
" camcontrol debug [-I][-P][-T][-S][-X][-c]\n" " camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
" <all|bus[:target[:lun]]|off>\n" " <all|bus[:target[:lun]]|off>\n"
" camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n" " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"

View File

@ -58,6 +58,7 @@ file is following:
control <addr> control <addr>
listen <addr> listen <addr>
replication <mode> replication <mode>
timeout <seconds>
on <node> { on <node> {
# Node section # Node section
@ -76,6 +77,7 @@ resource <name> {
replication <mode> replication <mode>
name <name> name <name>
local <path> local <path>
timeout <seconds>
on <node> { on <node> {
# Resource-node section # Resource-node section
@ -194,6 +196,11 @@ The
.Ic async .Ic async
replication mode is currently not implemented. replication mode is currently not implemented.
.El .El
.It Ic timeout Aq seconds
.Pp
Connection timeout in seconds.
The default value is
.Va 5 .
.It Ic name Aq name .It Ic name Aq name
.Pp .Pp
GEOM provider name that will appear as GEOM provider name that will appear as

View File

@ -75,6 +75,7 @@
#define HIO_DELETE 3 #define HIO_DELETE 3
#define HIO_FLUSH 4 #define HIO_FLUSH 4
#define HAST_TIMEOUT 5
#define HAST_CONFIG "/etc/hast.conf" #define HAST_CONFIG "/etc/hast.conf"
#define HAST_CONTROL "/var/run/hastctl" #define HAST_CONTROL "/var/run/hastctl"
#define HASTD_PORT 8457 #define HASTD_PORT 8457
@ -148,6 +149,8 @@ struct hast_resource {
/* Token to verify both in and out connection are coming from /* Token to verify both in and out connection are coming from
the same node (not necessarily from the same address). */ the same node (not necessarily from the same address). */
unsigned char hr_token[HAST_TOKEN_SIZE]; unsigned char hr_token[HAST_TOKEN_SIZE];
/* Connection timeout. */
int hr_timeout;
/* Resource unique identifier. */ /* Resource unique identifier. */
uint64_t hr_resuid; uint64_t hr_resuid;

View File

@ -107,6 +107,22 @@ g_gate_load(void)
} }
} }
static void
child_exit_log(unsigned int pid, int status)
{
if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
pjdlog_debug(1, "Worker process exited gracefully (pid=%u).",
pid);
} else if (WIFSIGNALED(status)) {
pjdlog_error("Worker process killed (pid=%u, signal=%d).",
pid, WTERMSIG(status));
} else {
pjdlog_error("Worker process exited ungracefully (pid=%u, exitcode=%d).",
pid, WIFEXITED(status) ? WEXITSTATUS(status) : -1);
}
}
static void static void
child_exit(void) child_exit(void)
{ {
@ -129,20 +145,25 @@ child_exit(void)
} }
pjdlog_prefix_set("[%s] (%s) ", res->hr_name, pjdlog_prefix_set("[%s] (%s) ", res->hr_name,
role2str(res->hr_role)); role2str(res->hr_role));
if (WEXITSTATUS(status) == 0) { child_exit_log(pid, status);
pjdlog_debug(1,
"Worker process exited gracefully (pid=%u).",
(unsigned int)pid);
} else {
pjdlog_error("Worker process failed (pid=%u, status=%d).",
(unsigned int)pid, WEXITSTATUS(status));
}
proto_close(res->hr_ctrl); proto_close(res->hr_ctrl);
res->hr_workerpid = 0; res->hr_workerpid = 0;
if (res->hr_role == HAST_ROLE_PRIMARY) { if (res->hr_role == HAST_ROLE_PRIMARY) {
sleep(1); /*
pjdlog_info("Restarting worker process."); * Restart child process if it was killed by signal
hastd_primary(res); * or exited because of temporary problem.
*/
if (WIFSIGNALED(status) ||
(WIFEXITED(status) &&
WEXITSTATUS(status) == EX_TEMPFAIL)) {
sleep(1);
pjdlog_info("Restarting worker process.");
hastd_primary(res);
} else {
res->hr_role = HAST_ROLE_INIT;
pjdlog_info("Changing resource role back to %s.",
role2str(res->hr_role));
}
} }
pjdlog_prefix_set("%s", ""); pjdlog_prefix_set("%s", "");
} }
@ -181,6 +202,10 @@ listen_accept(void)
proto_remote_address(conn, raddr, sizeof(raddr)); proto_remote_address(conn, raddr, sizeof(raddr));
pjdlog_info("Connection from %s to %s.", laddr, raddr); pjdlog_info("Connection from %s to %s.", laddr, raddr);
/* Error in setting timeout is not critical, but why should it fail? */
if (proto_timeout(conn, HAST_TIMEOUT) < 0)
pjdlog_errno(LOG_WARNING, "Unable to set connection timeout");
nvin = nvout = nverr = NULL; nvin = nvout = nverr = NULL;
/* /*
@ -290,18 +315,12 @@ listen_accept(void)
/* Wait for it to exit. */ /* Wait for it to exit. */
else if ((pid = waitpid(res->hr_workerpid, else if ((pid = waitpid(res->hr_workerpid,
&status, 0)) != res->hr_workerpid) { &status, 0)) != res->hr_workerpid) {
/* We can only log the problem. */
pjdlog_errno(LOG_ERR, pjdlog_errno(LOG_ERR,
"Waiting for worker process (pid=%u) failed", "Waiting for worker process (pid=%u) failed",
(unsigned int)res->hr_workerpid); (unsigned int)res->hr_workerpid);
/* See above. */
} else if (status != 0) {
pjdlog_error("Worker process (pid=%u) exited ungracefully: status=%d.",
(unsigned int)res->hr_workerpid, status);
/* See above. */
} else { } else {
pjdlog_debug(1, child_exit_log(res->hr_workerpid, status);
"Worker process (pid=%u) exited gracefully.",
(unsigned int)res->hr_workerpid);
} }
res->hr_workerpid = 0; res->hr_workerpid = 0;
} else if (res->hr_remotein != NULL) { } else if (res->hr_remotein != NULL) {

View File

@ -117,7 +117,7 @@ metadata_read(struct hast_resource *res, bool openrw)
} }
str = nv_get_string(nv, "resource"); str = nv_get_string(nv, "resource");
if (strcmp(str, res->hr_name) != 0) { if (str != NULL && strcmp(str, res->hr_name) != 0) {
pjdlog_error("Provider %s is not part of resource %s.", pjdlog_error("Provider %s is not part of resource %s.",
res->hr_localpath, res->hr_name); res->hr_localpath, res->hr_name);
nv_free(nv); nv_free(nv);

View File

@ -58,6 +58,7 @@ static bool mynode;
static char depth0_control[HAST_ADDRSIZE]; static char depth0_control[HAST_ADDRSIZE];
static char depth0_listen[HAST_ADDRSIZE]; static char depth0_listen[HAST_ADDRSIZE];
static int depth0_replication; static int depth0_replication;
static int depth0_timeout;
static char depth1_provname[PATH_MAX]; static char depth1_provname[PATH_MAX];
static char depth1_localpath[PATH_MAX]; static char depth1_localpath[PATH_MAX];
@ -115,6 +116,7 @@ yy_config_parse(const char *config)
curres = NULL; curres = NULL;
mynode = false; mynode = false;
depth0_timeout = HAST_TIMEOUT;
depth0_replication = HAST_REPLICATION_MEMSYNC; depth0_replication = HAST_REPLICATION_MEMSYNC;
strlcpy(depth0_control, HAST_CONTROL, sizeof(depth0_control)); strlcpy(depth0_control, HAST_CONTROL, sizeof(depth0_control));
strlcpy(depth0_listen, HASTD_LISTEN, sizeof(depth0_listen)); strlcpy(depth0_listen, HASTD_LISTEN, sizeof(depth0_listen));
@ -154,6 +156,13 @@ yy_config_parse(const char *config)
*/ */
curres->hr_replication = depth0_replication; curres->hr_replication = depth0_replication;
} }
if (curres->hr_timeout == -1) {
/*
* Timeout is not set at resource-level.
* Use global or default setting.
*/
curres->hr_timeout = depth0_timeout;
}
} }
return (&lconfig); return (&lconfig);
@ -171,7 +180,7 @@ yy_config_free(struct hastd_config *config)
} }
%} %}
%token CONTROL LISTEN PORT REPLICATION EXTENTSIZE RESOURCE NAME LOCAL REMOTE ON %token CONTROL LISTEN PORT REPLICATION TIMEOUT EXTENTSIZE RESOURCE NAME LOCAL REMOTE ON
%token FULLSYNC MEMSYNC ASYNC %token FULLSYNC MEMSYNC ASYNC
%token NUM STR OB CB %token NUM STR OB CB
@ -200,6 +209,8 @@ statement:
| |
replication_statement replication_statement
| |
timeout_statement
|
node_statement node_statement
| |
resource_statement resource_statement
@ -281,6 +292,22 @@ replication_type:
ASYNC { $$ = HAST_REPLICATION_ASYNC; } ASYNC { $$ = HAST_REPLICATION_ASYNC; }
; ;
timeout_statement: TIMEOUT NUM
{
switch (depth) {
case 0:
depth0_timeout = $2;
break;
case 1:
if (curres != NULL)
curres->hr_timeout = $2;
break;
default:
assert(!"timeout at wrong depth level");
}
}
;
node_statement: ON node_start OB node_entries CB node_statement: ON node_start OB node_entries CB
{ {
mynode = false; mynode = false;
@ -389,6 +416,7 @@ resource_start: STR
curres->hr_role = HAST_ROLE_INIT; curres->hr_role = HAST_ROLE_INIT;
curres->hr_previous_role = HAST_ROLE_INIT; curres->hr_previous_role = HAST_ROLE_INIT;
curres->hr_replication = -1; curres->hr_replication = -1;
curres->hr_timeout = -1;
curres->hr_provname[0] = '\0'; curres->hr_provname[0] = '\0';
curres->hr_localpath[0] = '\0'; curres->hr_localpath[0] = '\0';
curres->hr_localfd = -1; curres->hr_localfd = -1;
@ -405,6 +433,8 @@ resource_entries:
resource_entry: resource_entry:
replication_statement replication_statement
| |
timeout_statement
|
name_statement name_statement
| |
local_statement local_statement

View File

@ -480,7 +480,7 @@ init_remote(struct hast_resource *res, struct proto_conn **inp,
/* Prepare outgoing connection with remote node. */ /* Prepare outgoing connection with remote node. */
if (proto_client(res->hr_remoteaddr, &out) < 0) { if (proto_client(res->hr_remoteaddr, &out) < 0) {
primary_exit(EX_OSERR, "Unable to create connection to %s", primary_exit(EX_TEMPFAIL, "Unable to create connection to %s",
res->hr_remoteaddr); res->hr_remoteaddr);
} }
/* Try to connect, but accept failure. */ /* Try to connect, but accept failure. */
@ -489,6 +489,9 @@ init_remote(struct hast_resource *res, struct proto_conn **inp,
res->hr_remoteaddr); res->hr_remoteaddr);
goto close; goto close;
} }
/* Error in setting timeout is not critical, but why should it fail? */
if (proto_timeout(out, res->hr_timeout) < 0)
pjdlog_errno(LOG_WARNING, "Unable to set connection timeout");
/* /*
* First handshake step. * First handshake step.
* Setup outgoing connection with remote node. * Setup outgoing connection with remote node.
@ -552,6 +555,9 @@ init_remote(struct hast_resource *res, struct proto_conn **inp,
res->hr_remoteaddr); res->hr_remoteaddr);
goto close; goto close;
} }
/* Error in setting timeout is not critical, but why should it fail? */
if (proto_timeout(in, res->hr_timeout) < 0)
pjdlog_errno(LOG_WARNING, "Unable to set connection timeout");
nvout = nv_alloc(); nvout = nv_alloc();
nv_add_string(nvout, res->hr_name, "resource"); nv_add_string(nvout, res->hr_name, "resource");
nv_add_uint8_array(nvout, res->hr_token, sizeof(res->hr_token), nv_add_uint8_array(nvout, res->hr_token, sizeof(res->hr_token),
@ -739,7 +745,7 @@ hastd_primary(struct hast_resource *res)
pid = fork(); pid = fork();
if (pid < 0) { if (pid < 0) {
KEEP_ERRNO((void)pidfile_remove(pfh)); KEEP_ERRNO((void)pidfile_remove(pfh));
primary_exit(EX_OSERR, "Unable to fork"); primary_exit(EX_TEMPFAIL, "Unable to fork");
} }
if (pid > 0) { if (pid > 0) {

View File

@ -30,7 +30,9 @@
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD$"); __FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/queue.h> #include <sys/queue.h>
#include <sys/socket.h>
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
@ -247,6 +249,30 @@ proto_remote_address(const struct proto_conn *conn, char *addr, size_t size)
conn->pc_proto->hp_remote_address(conn->pc_ctx, addr, size); conn->pc_proto->hp_remote_address(conn->pc_ctx, addr, size);
} }
int
proto_timeout(const struct proto_conn *conn, int timeout)
{
struct timeval tv;
int fd;
assert(conn != NULL);
assert(conn->pc_magic == PROTO_CONN_MAGIC);
assert(conn->pc_proto != NULL);
fd = proto_descriptor(conn);
if (fd < 0)
return (-1);
tv.tv_sec = timeout;
tv.tv_usec = 0;
if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) < 0)
return (-1);
if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0)
return (-1);
return (0);
}
void void
proto_close(struct proto_conn *conn) proto_close(struct proto_conn *conn)
{ {

View File

@ -49,6 +49,7 @@ void proto_local_address(const struct proto_conn *conn, char *addr,
size_t size); size_t size);
void proto_remote_address(const struct proto_conn *conn, char *addr, void proto_remote_address(const struct proto_conn *conn, char *addr,
size_t size); size_t size);
int proto_timeout(const struct proto_conn *conn, int timeout);
void proto_close(struct proto_conn *conn); void proto_close(struct proto_conn *conn);
#endif /* !_PROTO_H_ */ #endif /* !_PROTO_H_ */

View File

@ -58,7 +58,7 @@ proto_common_send(int fd, const unsigned char *data, size_t size)
if (done == 0) if (done == 0)
return (ENOTCONN); return (ENOTCONN);
else if (done < 0) { else if (done < 0) {
if (errno == EAGAIN) if (errno == EINTR)
continue; continue;
return (errno); return (errno);
} }
@ -76,7 +76,7 @@ proto_common_recv(int fd, unsigned char *data, size_t size)
do { do {
done = recv(fd, data, size, MSG_WAITALL); done = recv(fd, data, size, MSG_WAITALL);
} while (done == -1 && errno == EAGAIN); } while (done == -1 && errno == EINTR);
if (done == 0) if (done == 0)
return (ENOTCONN); return (ENOTCONN);
else if (done < 0) else if (done < 0)

View File

@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h>
#include <netdb.h> #include <netdb.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
@ -47,6 +48,7 @@ __FBSDID("$FreeBSD$");
#include "hast.h" #include "hast.h"
#include "pjdlog.h" #include "pjdlog.h"
#include "proto_impl.h" #include "proto_impl.h"
#include "subr.h"
#define TCP4_CTX_MAGIC 0x7c441c #define TCP4_CTX_MAGIC 0x7c441c
struct tcp4_ctx { struct tcp4_ctx {
@ -222,18 +224,88 @@ static int
tcp4_connect(void *ctx) tcp4_connect(void *ctx)
{ {
struct tcp4_ctx *tctx = ctx; struct tcp4_ctx *tctx = ctx;
struct timeval tv;
fd_set fdset;
socklen_t esize;
int error, flags, ret;
assert(tctx != NULL); assert(tctx != NULL);
assert(tctx->tc_magic == TCP4_CTX_MAGIC); assert(tctx->tc_magic == TCP4_CTX_MAGIC);
assert(tctx->tc_side == TCP4_SIDE_CLIENT); assert(tctx->tc_side == TCP4_SIDE_CLIENT);
assert(tctx->tc_fd >= 0); assert(tctx->tc_fd >= 0);
if (connect(tctx->tc_fd, (struct sockaddr *)&tctx->tc_sin, flags = fcntl(tctx->tc_fd, F_GETFL);
sizeof(tctx->tc_sin)) < 0) { if (flags == -1) {
KEEP_ERRNO(pjdlog_common(LOG_DEBUG, 1, errno,
"fcntl(F_GETFL) failed"));
return (errno);
}
/*
* We make socket non-blocking so we have decided about connection
* timeout.
*/
flags |= O_NONBLOCK;
if (fcntl(tctx->tc_fd, F_SETFL, flags) == -1) {
KEEP_ERRNO(pjdlog_common(LOG_DEBUG, 1, errno,
"fcntl(F_SETFL, O_NONBLOCK) failed"));
return (errno); return (errno);
} }
return (0); if (connect(tctx->tc_fd, (struct sockaddr *)&tctx->tc_sin,
sizeof(tctx->tc_sin)) == 0) {
error = 0;
goto done;
}
if (errno != EINPROGRESS) {
error = errno;
pjdlog_common(LOG_DEBUG, 1, errno, "connect() failed");
goto done;
}
/*
* Connection can't be established immediately, let's wait
* for HAST_TIMEOUT seconds.
*/
tv.tv_sec = HAST_TIMEOUT;
tv.tv_usec = 0;
again:
FD_ZERO(&fdset);
FD_SET(tctx->tc_fd, &fdset);
ret = select(tctx->tc_fd + 1, NULL, &fdset, NULL, &tv);
if (ret == 0) {
error = ETIMEDOUT;
goto done;
} else if (ret == -1) {
if (errno == EINTR)
goto again;
error = errno;
pjdlog_common(LOG_DEBUG, 1, errno, "select() failed");
goto done;
}
assert(ret > 0);
assert(FD_ISSET(tctx->tc_fd, &fdset));
esize = sizeof(error);
if (getsockopt(tctx->tc_fd, SOL_SOCKET, SO_ERROR, &error,
&esize) == -1) {
error = errno;
pjdlog_common(LOG_DEBUG, 1, errno,
"getsockopt(SO_ERROR) failed");
goto done;
}
if (error != 0) {
pjdlog_common(LOG_DEBUG, 1, error,
"getsockopt(SO_ERROR) returned error");
goto done;
}
error = 0;
done:
flags &= ~O_NONBLOCK;
if (fcntl(tctx->tc_fd, F_SETFL, flags) == -1) {
if (error == 0)
error = errno;
pjdlog_common(LOG_DEBUG, 1, errno,
"fcntl(F_SETFL, ~O_NONBLOCK) failed");
}
return (error);
} }
static int static int

View File

@ -337,6 +337,12 @@ hastd_secondary(struct hast_resource *res, struct nv *nvin)
setproctitle("%s (secondary)", res->hr_name); setproctitle("%s (secondary)", res->hr_name);
/* Error in setting timeout is not critical, but why should it fail? */
if (proto_timeout(res->hr_remotein, 0) < 0)
pjdlog_errno(LOG_WARNING, "Unable to set connection timeout");
if (proto_timeout(res->hr_remoteout, res->hr_timeout) < 0)
pjdlog_errno(LOG_WARNING, "Unable to set connection timeout");
init_local(res); init_local(res);
init_remote(res, nvin); init_remote(res, nvin);
init_environment(); init_environment();

View File

@ -48,6 +48,7 @@ control { DP; return CONTROL; }
listen { DP; return LISTEN; } listen { DP; return LISTEN; }
port { DP; return PORT; } port { DP; return PORT; }
replication { DP; return REPLICATION; } replication { DP; return REPLICATION; }
timeout { DP; return TIMEOUT; }
resource { DP; return RESOURCE; } resource { DP; return RESOURCE; }
name { DP; return NAME; } name { DP; return NAME; }
local { DP; return LOCAL; } local { DP; return LOCAL; }

View File

@ -28,7 +28,7 @@
.\" From: @(#)ifconfig.8 8.3 (Berkeley) 1/5/94 .\" From: @(#)ifconfig.8 8.3 (Berkeley) 1/5/94
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd February 20, 2010 .Dd April 28, 2010
.Dt IFCONFIG 8 .Dt IFCONFIG 8
.Os .Os
.Sh NAME .Sh NAME
@ -1163,9 +1163,9 @@ In particular the information elements included in management frames
for old devices are different. for old devices are different.
When compatibility support is enabled both standard and compatible data When compatibility support is enabled both standard and compatible data
will be provided. will be provided.
Stations that associate using the compatiblity mechanisms are flagged Stations that associate using the compatibility mechanisms are flagged
in ``list sta''. in ``list sta''.
To disable compatiblity support use To disable compatibility support use
.Fl htcompat . .Fl htcompat .
.It Cm htprotmode Ar technique .It Cm htprotmode Ar technique
For interfaces operating in 802.11n, use the specified For interfaces operating in 802.11n, use the specified

View File

@ -5027,7 +5027,7 @@ DECL_CMD_FUNC(set80211clone_wlanaddr, arg, d)
ea = ether_aton(arg); ea = ether_aton(arg);
if (ea == NULL) if (ea == NULL)
errx(1, "%s: cannot parse addres", arg); errx(1, "%s: cannot parse address", arg);
memcpy(params.icp_macaddr, ea->octet, IEEE80211_ADDR_LEN); memcpy(params.icp_macaddr, ea->octet, IEEE80211_ADDR_LEN);
params.icp_flags |= IEEE80211_CLONE_MACADDR; params.icp_flags |= IEEE80211_CLONE_MACADDR;
} }

View File

@ -280,9 +280,9 @@ main(int argc, char *argv[])
if (ufs_disk_fillout(&disk, special) == -1) if (ufs_disk_fillout(&disk, special) == -1)
goto err; goto err;
if (disk.d_name != special) { if (disk.d_name != special) {
special = disk.d_name; if (statfs(special, &stfs) != 0)
if (statfs(special, &stfs) == 0 && warn("Can't stat %s", special);
strcmp(special, stfs.f_mntonname) == 0) if (strcmp(special, stfs.f_mntonname) == 0)
active = 1; active = 1;
} }
@ -546,7 +546,7 @@ journal_balloc(void)
* Try to minimize fragmentation by requiring a minimum * Try to minimize fragmentation by requiring a minimum
* number of blocks present. * number of blocks present.
*/ */
if (cgp->cg_cs.cs_nbfree > blocks / 8) if (cgp->cg_cs.cs_nbfree > 128 * 1024 * 1024)
break; break;
if (contig == 0 && cgp->cg_cs.cs_nbfree) if (contig == 0 && cgp->cg_cs.cs_nbfree)
break; break;
@ -1007,10 +1007,11 @@ out:
void void
usage(void) usage(void)
{ {
fprintf(stderr, "%s\n%s\n%s\n%s\n", fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n",
"usage: tunefs [-A] [-a enable | disable] [-e maxbpg] [-f avgfilesize]", "usage: tunefs [-A] [-a enable | disable] [-e maxbpg] [-f avgfilesize]",
" [-J enable | disable ] [-L volname] [-l enable | disable]", " [-J enable | disable] [-j enable | disable]",
" [-m minfree] [-N enable | disable] [-n enable | disable]", " [-L volname] [-l enable | disable] [-m minfree]",
" [-N enable | disable] [-n enable | disable]",
" [-o space | time] [-p] [-s avgfpdir] special | filesystem"); " [-o space | time] [-p] [-s avgfpdir] special | filesystem");
exit(2); exit(2);
} }

View File

@ -220,6 +220,7 @@ MAN= aac.4 \
msk.4 \ msk.4 \
mtio.4 \ mtio.4 \
multicast.4 \ multicast.4 \
mvs.4 \
mwl.4 \ mwl.4 \
mwlfw.4 \ mwlfw.4 \
mxge.4 \ mxge.4 \

View File

@ -123,7 +123,7 @@ ifconfig wlan create wlandev bwn0 ssid my_net \e
The The
.Nm .Nm
driver first appeared in driver first appeared in
.Fx 8.0 . .Fx 8.1 .
.Sh AUTHORS .Sh AUTHORS
.An -nosplit .An -nosplit
The The

View File

@ -25,7 +25,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd June 15, 2009 .Dd May 3, 2010
.Dt CAS 4 .Dt CAS 4
.Os .Os
.Sh NAME .Sh NAME
@ -91,6 +91,9 @@ driver at this time:
.Pp .Pp
.Bl -bullet -compact .Bl -bullet -compact
.It .It
Sun GigaSwift Ethernet 1.0 MMF (Cassini Kuheen)
(part no.\& 501-5524)
.It
Sun GigaSwift Ethernet 1.0 UTP (Cassini) Sun GigaSwift Ethernet 1.0 UTP (Cassini)
(part no.\& 501-5902) (part no.\& 501-5902)
.It .It

View File

@ -24,7 +24,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd March 1, 2010 .Dd April 30, 2010
.Dt MSK 4 .Dt MSK 4
.Os .Os
.Sh NAME .Sh NAME
@ -208,6 +208,8 @@ Marvell Yukon 88E8057 Gigabit Ethernet
.It .It
Marvell Yukon 88E8058 Gigabit Ethernet Marvell Yukon 88E8058 Gigabit Ethernet
.It .It
Marvell Yukon 88E8059 Gigabit Ethernet
.It
Marvell Yukon 88E8070 Gigabit Ethernet Marvell Yukon 88E8070 Gigabit Ethernet
.It .It
Marvell Yukon 88E8071 Gigabit Ethernet Marvell Yukon 88E8071 Gigabit Ethernet

176
share/man/man4/mvs.4 Normal file
View File

@ -0,0 +1,176 @@
.\" Copyright (c) 2009 Alexander Motin <mav@FreeBSD.org>
.\" 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. The name of the author may not be used to endorse or promote products
.\" derived from this software without specific prior written permission.
.\"
.\" 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.
.\"
.\" $FreeBSD$
.\"
.Dd April 27, 2010
.Dt MVS 4
.Os
.Sh NAME
.Nm mvs
.Nd Marvell Serial ATA Host Controller driver
.Sh SYNOPSIS
To compile this driver into the kernel,
place the following lines in your
kernel configuration file:
.Bd -ragged -offset indent
.Cd "device pci"
.Cd "device scbus"
.Cd "device mvs"
.Ed
.Pp
Alternatively, to load the driver as a
module at boot time, place the following line in
.Xr loader.conf 5 :
.Bd -literal -offset indent
mvs_load="YES"
.Ed
.Pp
The following tunables are settable from the
.Xr loader 8 :
.Bl -ohang
.It Va hint.mvs. Ns Ar X Ns Va .msi
controls Message Signaled Interrupts (MSI) usage by the specified controller.
.It Va hint.mvs. Ns Ar X Ns Va .ccc
controls Command Completion Coalescing (CCC) usage by the specified controller.
Non-zero value enables CCC and defines maximum time (in us), request can wait
for interrupt.
CCC reduces number of context switches on systems with many parallel requests,
but it can decrease disk performance on some workloads due to additional
command latency.
.It Va hint.mvs. Ns Ar X Ns Va .cccc
defines number of completed commands for CCC, which trigger interrupt without
waiting for specified coalescing timeout.
.It Va hint.mvs. Ns Ar X Ns Va .pm_level
controls SATA interface Power Management for the specified channel,
allowing some power to be saved at the cost of additional command
latency.
Possible values:
.Bl -tag -compact
.It 0
interface Power Management is disabled (default);
.It 1
device is allowed to initiate PM state change, host is passive;
.It 4
driver initiates PARTIAL PM state transition 1ms after port becomes idle;
.It 5
driver initiates SLUMBER PM state transition 125ms after port becomes idle.
.El
.Pp
Note that interface Power Management is not compatible with
device presence detection.
A manual bus reset is needed on device hot-plug.
.It Va hint.mvs. Ns Ar X Ns Va .sata_rev
setting to nonzero value limits maximum SATA revision (speed).
Values 1, 2 and 3 are respectively 1.5, 3 and 6Gbps.
.El
.Sh DESCRIPTION
This driver provides the
.Xr CAM 4
subsystem with native access to the
.Tn SATA
ports of several generations (Gen-I/II/IIe) of Marvell SATA controllers.
Each SATA port found is represented to CAM as a separate bus with one
target, or, if HBA supports Port Multipliers (Gen-II/IIe), 16 targets.
Most of the bus-management details are handled by the SATA-specific
transport of CAM.
Connected ATA disks are handled by the ATA protocol disk peripheral driver
.Xr ada 4 .
ATAPI devices are handled by the SCSI protocol peripheral drivers
.Xr cd 4 ,
.Xr da 4 ,
.Xr sa 4 ,
etc.
.Pp
Driver features include support for Serial ATA and ATAPI devices,
Port Multipliers (including FIS-based switching, when supported),
hardware command queues (up to 31 command per port),
Native Command Queuing, SATA interface Power Management, device hot-plug
and Message Signaled Interrupts.
.Pp
Same hardware is also supported by atamarvell and ataadaptec drivers from
.Xr ata 4
subsystem.
If both drivers are loaded at the same time, this one will be
given precedence as the more functional of the two.
.Sh HARDWARE
The
.Nm
driver supports the following controllers:
.Bl -tag -compact
.It Gen-I (SATA 1.5Gbps):
.Bl -bullet -compact
.It
88SX5040
.It
88SX5041
.It
88SX5080
.It
88SX5081
.El
.It Gen-II (SATA 3Gbps, NCQ, PMP):
.Bl -bullet -compact
.It
88SX6040
.It
88SX6041 (including Adaptec 1420SA)
.It
88SX6080
.It
88SX6081
.El
.It Gen-IIe (SATA 3Gbps, NCQ, PMP with FBS):
.Bl -bullet -compact
.It
88SX6042
.It
88SX7042 (including Adaptec 1430SA)
.It
88F5182 SoC
.It
88F6281 SoC
.It
MV78100 SoC
.El
.El
Note, that this hardware supports command queueing and FIS-based switching
only for ATA DMA commands. ATAPI and non-DMA ATA commands executed one by one
for each port.
.Pp
.Sh SEE ALSO
.Xr ada 4 ,
.Xr ata 4 ,
.Xr cam 4 ,
.Xr cd 4 ,
.Xr da 4 ,
.Xr sa 4
.Sh HISTORY
The
.Nm
driver first appeared in
.Fx 9.0 .
.Sh AUTHORS
.An Alexander Motin Aq mav@FreeBSD.org .

View File

@ -34,7 +34,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd August 31, 2000 .Dd May 5, 2010
.Dt NG_BRIDGE 4 .Dt NG_BRIDGE 4
.Os .Os
.Sh NAME .Sh NAME
@ -181,11 +181,17 @@ but also atomically clears the statistics as well.
.It Dv NGM_BRIDGE_GET_TABLE .It Dv NGM_BRIDGE_GET_TABLE
Returns the current host mapping table used to direct packets, in a Returns the current host mapping table used to direct packets, in a
.Dv "struct ng_bridge_host_ary" . .Dv "struct ng_bridge_host_ary" .
.It Dv NGM_BRIDGE_SET_PERSISTENT
This command sets the persistent flag on the node, and takes no arguments.
.El .El
.Sh SHUTDOWN .Sh SHUTDOWN
This node shuts down upon receipt of a This node shuts down upon receipt of a
.Dv NGM_SHUTDOWN .Dv NGM_SHUTDOWN
control message, or when all hooks have been disconnected. control message, or when all hooks have been disconnected. Setting the
persistent flag via a
.Dv NGM_BRIDGE_SET_PERSISTENT
control message disables automatic node shutdown when the last hook gets
disconnected.
.Sh FILES .Sh FILES
.Bl -tag -width XXXXXXXX -compact .Bl -tag -width XXXXXXXX -compact
.It Pa /usr/share/examples/netgraph/ether.bridge .It Pa /usr/share/examples/netgraph/ether.bridge

View File

@ -24,7 +24,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd April 17, 2004 .Dd May 5, 2010
.Dt NG_HUB 4 .Dt NG_HUB 4
.Os .Os
.Sh NAME .Sh NAME
@ -45,11 +45,20 @@ A
node accepts any request to connect, regardless of the hook name, node accepts any request to connect, regardless of the hook name,
as long as the name is unique. as long as the name is unique.
.Sh CONTROL MESSAGES .Sh CONTROL MESSAGES
This node type supports only the generic control messages. This node type supports the generic control messages, plus the
following:
.Bl -tag -width foo
.It Dv NGM_HUB_SET_PERSISTENT
This command sets the persistent flag on the node, and takes no arguments.
.El
.Sh SHUTDOWN .Sh SHUTDOWN
This node shuts down upon receipt of a This node shuts down upon receipt of a
.Dv NGM_SHUTDOWN .Dv NGM_SHUTDOWN
control message, or when all hooks have been disconnected. control message, or when all hooks have been disconnected. Setting the
persistent flag via a
.Dv NGM_HUB_SET_PERSISTENT
control message disables automatic node shutdown when the last hook gets
disconnected.
.Sh SEE ALSO .Sh SEE ALSO
.Xr netgraph 4 , .Xr netgraph 4 ,
.Xr ng_bridge 4 , .Xr ng_bridge 4 ,

View File

@ -24,7 +24,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd April 14, 2010 .Dd April 29, 2010
.Dt SGE 4 .Dt SGE 4
.Os .Os
.Sh NAME .Sh NAME
@ -53,11 +53,11 @@ controllers and SiS191 Fast/Gigabit Ethernet controllers.
.Pp .Pp
All LOMs supported by the All LOMs supported by the
.Nm .Nm
driver have TCP/UDP/IP checksum offload for transmit and receive. driver have TCP/UDP/IP checksum offload for transmit and receive,
hardware VLAN tag stripping/insertion features.
Due to lack of documentation more offloading features like TCP Due to lack of documentation more offloading features like TCP
segmentation offload (TSO), hardware VLAN tag stripping/insertion segmentation offload (TSO), Wake On Lan (WOL), Jumbo frame and an
features, Wake On Lan (WOL), Jumbo frame and an interrupt moderation interrupt moderation mechanism are not supported yet.
mechanism are not supported yet.
.Pp .Pp
The The
.Nm .Nm

View File

@ -134,6 +134,7 @@ in the hardware is limited to the following devices:
.Xr msk 4 , .Xr msk 4 ,
.Xr nge 4 , .Xr nge 4 ,
.Xr re 4 , .Xr re 4 ,
.Xr sge 4 ,
.Xr stge 4 , .Xr stge 4 ,
.Xr ti 4 , .Xr ti 4 ,
.Xr txp 4 , .Xr txp 4 ,
@ -172,7 +173,6 @@ natively:
.Xr nve 4 , .Xr nve 4 ,
.Xr rl 4 , .Xr rl 4 ,
.Xr sf 4 , .Xr sf 4 ,
.Xr sge 4 ,
.Xr sis 4 , .Xr sis 4 ,
.Xr sk 4 , .Xr sk 4 ,
.Xr ste 4 , .Xr ste 4 ,

View File

@ -25,11 +25,11 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd March 29, 2010 .Dd April 28, 2010
.Dt NET80211 9 .Dt IEEE80211 9
.Os .Os
.Sh NAME .Sh NAME
.Nm net80211 .Nm IEEE80211
.Nd 802.11 network layer .Nd 802.11 network layer
.Sh SYNOPSIS .Sh SYNOPSIS
.In net80211/ieee80211_var.h .In net80211/ieee80211_var.h

View File

@ -26,7 +26,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd March 29, 2010 .Dd April 28, 2010
.Dt IEEE80211_NODE 9 .Dt IEEE80211_NODE 9
.Os .Os
.Sh NAME .Sh NAME
@ -152,7 +152,7 @@ displays the contents of a single node while
.Fn ieee80211_dump_nodes .Fn ieee80211_dump_nodes
displays the contents of the specified node table. displays the contents of the specified node table.
Nodes may also be displayed using Nodes may also be displayed using
.Xr ddb 9 .Xr ddb 4
with the with the
.Dq show node .Dq show node
directive and the station node table can be displayed with directive and the station node table can be displayed with

View File

@ -50,14 +50,14 @@
.bss .bss
.globl dtrace_invop_jump_addr .globl dtrace_invop_jump_addr
.align 8 .align 8
.type dtrace_invop_jump_addr, @object .type dtrace_invop_jump_addr,@object
.size dtrace_invop_jump_addr, 8 .size dtrace_invop_jump_addr,8
dtrace_invop_jump_addr: dtrace_invop_jump_addr:
.zero 8 .zero 8
.globl dtrace_invop_calltrap_addr .globl dtrace_invop_calltrap_addr
.align 8 .align 8
.type dtrace_invop_calltrap_addr, @object .type dtrace_invop_calltrap_addr,@object
.size dtrace_invop_calltrap_addr, 8 .size dtrace_invop_calltrap_addr,8
dtrace_invop_calltrap_addr: dtrace_invop_calltrap_addr:
.zero 8 .zero 8
#endif #endif
@ -157,7 +157,6 @@ IDTVEC(align)
* kernel from userland. Reenable interrupts if they were enabled * kernel from userland. Reenable interrupts if they were enabled
* before the trap. This approximates SDT_SYS386TGT on the i386 port. * before the trap. This approximates SDT_SYS386TGT on the i386 port.
*/ */
SUPERALIGN_TEXT SUPERALIGN_TEXT
.globl alltraps .globl alltraps
.type alltraps,@function .type alltraps,@function
@ -211,16 +210,16 @@ alltraps_pushregs_no_rdi:
* Set our jump address for the jump back in the event that * Set our jump address for the jump back in the event that
* the breakpoint wasn't caused by DTrace at all. * the breakpoint wasn't caused by DTrace at all.
*/ */
movq $calltrap, dtrace_invop_calltrap_addr(%rip) movq $calltrap,dtrace_invop_calltrap_addr(%rip)
/* Jump to the code hooked in by DTrace. */ /* Jump to the code hooked in by DTrace. */
movq dtrace_invop_jump_addr, %rax movq dtrace_invop_jump_addr,%rax
jmpq *dtrace_invop_jump_addr jmpq *dtrace_invop_jump_addr
#endif #endif
.globl calltrap .globl calltrap
.type calltrap,@function .type calltrap,@function
calltrap: calltrap:
movq %rsp, %rdi movq %rsp,%rdi
call trap call trap
MEXITCOUNT MEXITCOUNT
jmp doreti /* Handle any pending ASTs */ jmp doreti /* Handle any pending ASTs */
@ -274,9 +273,11 @@ IDTVEC(dblfault)
testb $SEL_RPL_MASK,TF_CS(%rsp) /* Did we come from kernel? */ testb $SEL_RPL_MASK,TF_CS(%rsp) /* Did we come from kernel? */
jz 1f /* already running with kernel GS.base */ jz 1f /* already running with kernel GS.base */
swapgs swapgs
1: movq %rsp, %rdi 1:
movq %rsp,%rdi
call dblfault_handler call dblfault_handler
2: hlt 2:
hlt
jmp 2b jmp 2b
IDTVEC(page) IDTVEC(page)
@ -369,7 +370,7 @@ IDTVEC(fast_syscall)
movq %r15,TF_R15(%rsp) /* C preserved */ movq %r15,TF_R15(%rsp) /* C preserved */
movl $TF_HASSEGS,TF_FLAGS(%rsp) movl $TF_HASSEGS,TF_FLAGS(%rsp)
FAKE_MCOUNT(TF_RIP(%rsp)) FAKE_MCOUNT(TF_RIP(%rsp))
movq %rsp, %rdi movq %rsp,%rdi
call syscall call syscall
movq PCPU(CURPCB),%rax movq PCPU(CURPCB),%rax
andq $~PCB_FULLCTX,PCB_FLAGS(%rax) andq $~PCB_FULLCTX,PCB_FLAGS(%rax)
@ -456,7 +457,7 @@ nmi_fromuserspace:
/* Note: this label is also used by ddb and gdb: */ /* Note: this label is also used by ddb and gdb: */
nmi_calltrap: nmi_calltrap:
FAKE_MCOUNT(TF_RIP(%rsp)) FAKE_MCOUNT(TF_RIP(%rsp))
movq %rsp, %rdi movq %rsp,%rdi
call trap call trap
MEXITCOUNT MEXITCOUNT
#ifdef HWPMC_HOOKS #ifdef HWPMC_HOOKS
@ -555,9 +556,9 @@ nmi_restoreregs:
iretq iretq
ENTRY(fork_trampoline) ENTRY(fork_trampoline)
movq %r12, %rdi /* function */ movq %r12,%rdi /* function */
movq %rbx, %rsi /* arg1 */ movq %rbx,%rsi /* arg1 */
movq %rsp, %rdx /* trapframe pointer */ movq %rsp,%rdx /* trapframe pointer */
call fork_exit call fork_exit
MEXITCOUNT MEXITCOUNT
jmp doreti /* Handle any ASTs */ jmp doreti /* Handle any ASTs */
@ -628,7 +629,7 @@ doreti_ast:
testl $TDF_ASTPENDING | TDF_NEEDRESCHED,TD_FLAGS(%rax) testl $TDF_ASTPENDING | TDF_NEEDRESCHED,TD_FLAGS(%rax)
je doreti_exit je doreti_exit
sti sti
movq %rsp, %rdi /* pass a pointer to the trapframe */ movq %rsp,%rdi /* pass a pointer to the trapframe */
call ast call ast
jmp doreti_ast jmp doreti_ast
@ -648,8 +649,8 @@ doreti_exit:
* Do not reload segment registers for kernel. * Do not reload segment registers for kernel.
* Since we do not reload segments registers with sane * Since we do not reload segments registers with sane
* values on kernel entry, descriptors referenced by * values on kernel entry, descriptors referenced by
* segments registers may be not valid. This is fatal * segments registers might be not valid. This is fatal
* for the usermode, but is innocent for the kernel. * for user mode, but is not a problem for the kernel.
*/ */
testb $SEL_RPL_MASK,TF_CS(%rsp) testb $SEL_RPL_MASK,TF_CS(%rsp)
jz ld_regs jz ld_regs
@ -662,14 +663,16 @@ do_segs:
/* Restore %fs and fsbase */ /* Restore %fs and fsbase */
movw TF_FS(%rsp),%ax movw TF_FS(%rsp),%ax
.globl ld_fs .globl ld_fs
ld_fs: movw %ax,%fs ld_fs:
movw %ax,%fs
cmpw $KUF32SEL,%ax cmpw $KUF32SEL,%ax
jne 1f jne 1f
movl $MSR_FSBASE,%ecx movl $MSR_FSBASE,%ecx
movl PCB_FSBASE(%r8),%eax movl PCB_FSBASE(%r8),%eax
movl PCB_FSBASE+4(%r8),%edx movl PCB_FSBASE+4(%r8),%edx
.globl ld_fsbase .globl ld_fsbase
ld_fsbase: wrmsr ld_fsbase:
wrmsr
1: 1:
/* Restore %gs and gsbase */ /* Restore %gs and gsbase */
movw TF_GS(%rsp),%si movw TF_GS(%rsp),%si
@ -678,7 +681,8 @@ ld_fsbase: wrmsr
movl $MSR_GSBASE,%ecx movl $MSR_GSBASE,%ecx
rdmsr rdmsr
.globl ld_gs .globl ld_gs
ld_gs: movw %si,%gs ld_gs:
movw %si,%gs
wrmsr wrmsr
popfq popfq
cmpw $KUG32SEL,%si cmpw $KUG32SEL,%si
@ -687,12 +691,17 @@ ld_gs: movw %si,%gs
movl PCB_GSBASE(%r8),%eax movl PCB_GSBASE(%r8),%eax
movl PCB_GSBASE+4(%r8),%edx movl PCB_GSBASE+4(%r8),%edx
.globl ld_gsbase .globl ld_gsbase
ld_gsbase: wrmsr ld_gsbase:
1: .globl ld_es wrmsr
ld_es: movw TF_ES(%rsp),%es 1:
.globl ld_es
ld_es:
movw TF_ES(%rsp),%es
.globl ld_ds .globl ld_ds
ld_ds: movw TF_DS(%rsp),%ds ld_ds:
ld_regs:movq TF_RDI(%rsp),%rdi movw TF_DS(%rsp),%ds
ld_regs:
movq TF_RDI(%rsp),%rdi
movq TF_RSI(%rsp),%rsi movq TF_RSI(%rsp),%rsi
movq TF_RDX(%rsp),%rdx movq TF_RDX(%rsp),%rdx
movq TF_RCX(%rsp),%rcx movq TF_RCX(%rsp),%rcx
@ -711,7 +720,8 @@ ld_regs:movq TF_RDI(%rsp),%rdi
jz 1f /* keep running with kernel GS.base */ jz 1f /* keep running with kernel GS.base */
cli cli
swapgs swapgs
1: addq $TF_RIP,%rsp /* skip over tf_err, tf_trapno */ 1:
addq $TF_RIP,%rsp /* skip over tf_err, tf_trapno */
.globl doreti_iret .globl doreti_iret
doreti_iret: doreti_iret:
iretq iretq
@ -738,7 +748,8 @@ doreti_iret_fault:
testl $PSL_I,TF_RFLAGS(%rsp) testl $PSL_I,TF_RFLAGS(%rsp)
jz 1f jz 1f
sti sti
1: movw %fs,TF_FS(%rsp) 1:
movw %fs,TF_FS(%rsp)
movw %gs,TF_GS(%rsp) movw %gs,TF_GS(%rsp)
movw %es,TF_ES(%rsp) movw %es,TF_ES(%rsp)
movw %ds,TF_DS(%rsp) movw %ds,TF_DS(%rsp)
@ -768,7 +779,7 @@ doreti_iret_fault:
.globl ds_load_fault .globl ds_load_fault
ds_load_fault: ds_load_fault:
movl $T_PROTFLT,TF_TRAPNO(%rsp) movl $T_PROTFLT,TF_TRAPNO(%rsp)
movq %rsp, %rdi movq %rsp,%rdi
call trap call trap
movw $KUDSEL,TF_DS(%rsp) movw $KUDSEL,TF_DS(%rsp)
jmp doreti jmp doreti
@ -777,7 +788,7 @@ ds_load_fault:
.globl es_load_fault .globl es_load_fault
es_load_fault: es_load_fault:
movl $T_PROTFLT,TF_TRAPNO(%rsp) movl $T_PROTFLT,TF_TRAPNO(%rsp)
movq %rsp, %rdi movq %rsp,%rdi
call trap call trap
movw $KUDSEL,TF_ES(%rsp) movw $KUDSEL,TF_ES(%rsp)
jmp doreti jmp doreti
@ -786,7 +797,7 @@ es_load_fault:
.globl fs_load_fault .globl fs_load_fault
fs_load_fault: fs_load_fault:
movl $T_PROTFLT,TF_TRAPNO(%rsp) movl $T_PROTFLT,TF_TRAPNO(%rsp)
movq %rsp, %rdi movq %rsp,%rdi
call trap call trap
movw $KUF32SEL,TF_FS(%rsp) movw $KUF32SEL,TF_FS(%rsp)
jmp doreti jmp doreti
@ -796,7 +807,7 @@ fs_load_fault:
gs_load_fault: gs_load_fault:
popfq popfq
movl $T_PROTFLT,TF_TRAPNO(%rsp) movl $T_PROTFLT,TF_TRAPNO(%rsp)
movq %rsp, %rdi movq %rsp,%rdi
call trap call trap
movw $KUG32SEL,TF_GS(%rsp) movw $KUG32SEL,TF_GS(%rsp)
jmp doreti jmp doreti
@ -805,7 +816,7 @@ gs_load_fault:
.globl fsbase_load_fault .globl fsbase_load_fault
fsbase_load_fault: fsbase_load_fault:
movl $T_PROTFLT,TF_TRAPNO(%rsp) movl $T_PROTFLT,TF_TRAPNO(%rsp)
movq %rsp, %rdi movq %rsp,%rdi
call trap call trap
movq PCPU(CURTHREAD),%r8 movq PCPU(CURTHREAD),%r8
movq TD_PCB(%r8),%r8 movq TD_PCB(%r8),%r8
@ -816,7 +827,7 @@ fsbase_load_fault:
.globl gsbase_load_fault .globl gsbase_load_fault
gsbase_load_fault: gsbase_load_fault:
movl $T_PROTFLT,TF_TRAPNO(%rsp) movl $T_PROTFLT,TF_TRAPNO(%rsp)
movq %rsp, %rdi movq %rsp,%rdi
call trap call trap
movq PCPU(CURTHREAD),%r8 movq PCPU(CURTHREAD),%r8
movq TD_PCB(%r8),%r8 movq TD_PCB(%r8),%r8

View File

@ -240,7 +240,7 @@ printcpuinfo(void)
printf("\n Features2=0x%b", cpu_feature2, printf("\n Features2=0x%b", cpu_feature2,
"\020" "\020"
"\001SSE3" /* SSE3 */ "\001SSE3" /* SSE3 */
"\002<b1>" "\002PCLMULQDQ" /* Carry-Less Mul Quadword */
"\003DTES64" /* 64-bit Debug Trace */ "\003DTES64" /* 64-bit Debug Trace */
"\004MON" /* MONITOR/MWAIT Instructions */ "\004MON" /* MONITOR/MWAIT Instructions */
"\005DS_CPL" /* CPL Qualified Debug Store */ "\005DS_CPL" /* CPL Qualified Debug Store */
@ -264,7 +264,7 @@ printcpuinfo(void)
"\027MOVBE" "\027MOVBE"
"\030POPCNT" "\030POPCNT"
"\031<b24>" "\031<b24>"
"\032<b25>" "\032AESNI" /* AES Crypto*/
"\033XSAVE" "\033XSAVE"
"\034OSXSAVE" "\034OSXSAVE"
"\035<b28>" "\035<b28>"

View File

@ -28,60 +28,32 @@
__FBSDID("$FreeBSD$"); __FBSDID("$FreeBSD$");
#include <sys/param.h> #include <sys/param.h>
#include <sys/conf.h>
#include <sys/fcntl.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/priv.h>
#include <sys/proc.h> #include <sys/proc.h>
#include <sys/signalvar.h>
#include <sys/systm.h>
#include <machine/db_machdep.h>
#include <machine/frame.h> #include <machine/frame.h>
#include <machine/psl.h>
#include <machine/specialreg.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <machine/iodev.h> #include <machine/iodev.h>
#include <machine/psl.h>
/* ARGSUSED */
int int
ioopen(struct cdev *dev __unused, int flags __unused, int fmt __unused, iodev_open(struct thread *td)
struct thread *td)
{ {
int error;
error = priv_check(td, PRIV_IO);
if (error != 0)
return (error);
error = securelevel_gt(td->td_ucred, 0);
if (error != 0)
return (error);
td->td_frame->tf_rflags |= PSL_IOPL; td->td_frame->tf_rflags |= PSL_IOPL;
return (0); return (0);
} }
/* ARGSUSED */
int int
ioclose(struct cdev *dev __unused, int flags __unused, int fmt __unused, iodev_close(struct thread *td)
struct thread *td)
{ {
td->td_frame->tf_rflags &= ~PSL_IOPL; td->td_frame->tf_rflags &= ~PSL_IOPL;
return (0); return (0);
} }
/* ARGSUSED */ /* ARGSUSED */
int int
ioioctl(struct cdev *dev __unused, u_long cmd __unused, caddr_t data __unused, iodev_ioctl(u_long cmd __unused, caddr_t data __unused)
int fflag __unused, struct thread *td __unused)
{ {
return (ENXIO); return (ENOIOCTL);
} }

View File

@ -793,7 +793,6 @@ static u_long pmap_pdpe_demotions;
SYSCTL_ULONG(_vm_pmap_pdpe, OID_AUTO, demotions, CTLFLAG_RD, SYSCTL_ULONG(_vm_pmap_pdpe, OID_AUTO, demotions, CTLFLAG_RD,
&pmap_pdpe_demotions, 0, "1GB page demotions"); &pmap_pdpe_demotions, 0, "1GB page demotions");
/*************************************************** /***************************************************
* Low level helper routines..... * Low level helper routines.....
***************************************************/ ***************************************************/
@ -1200,15 +1199,20 @@ pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot)
{ {
pd_entry_t pde, *pdep; pd_entry_t pde, *pdep;
pt_entry_t pte; pt_entry_t pte;
vm_paddr_t pa;
vm_page_t m; vm_page_t m;
pa = 0;
m = NULL; m = NULL;
vm_page_lock_queues();
PMAP_LOCK(pmap); PMAP_LOCK(pmap);
retry:
pdep = pmap_pde(pmap, va); pdep = pmap_pde(pmap, va);
if (pdep != NULL && (pde = *pdep)) { if (pdep != NULL && (pde = *pdep)) {
if (pde & PG_PS) { if (pde & PG_PS) {
if ((pde & PG_RW) || (prot & VM_PROT_WRITE) == 0) { if ((pde & PG_RW) || (prot & VM_PROT_WRITE) == 0) {
if (vm_page_pa_tryrelock(pmap, (pde & PG_PS_FRAME) |
(va & PDRMASK), &pa))
goto retry;
m = PHYS_TO_VM_PAGE((pde & PG_PS_FRAME) | m = PHYS_TO_VM_PAGE((pde & PG_PS_FRAME) |
(va & PDRMASK)); (va & PDRMASK));
vm_page_hold(m); vm_page_hold(m);
@ -1217,12 +1221,14 @@ pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot)
pte = *pmap_pde_to_pte(pdep, va); pte = *pmap_pde_to_pte(pdep, va);
if ((pte & PG_V) && if ((pte & PG_V) &&
((pte & PG_RW) || (prot & VM_PROT_WRITE) == 0)) { ((pte & PG_RW) || (prot & VM_PROT_WRITE) == 0)) {
if (vm_page_pa_tryrelock(pmap, pte & PG_FRAME, &pa))
goto retry;
m = PHYS_TO_VM_PAGE(pte & PG_FRAME); m = PHYS_TO_VM_PAGE(pte & PG_FRAME);
vm_page_hold(m); vm_page_hold(m);
} }
} }
} }
vm_page_unlock_queues(); PA_UNLOCK_COND(pa);
PMAP_UNLOCK(pmap); PMAP_UNLOCK(pmap);
return (m); return (m);
} }
@ -3143,9 +3149,8 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_prot_t access, vm_page_t m,
* In the case that a page table page is not * In the case that a page table page is not
* resident, we are creating it here. * resident, we are creating it here.
*/ */
if (va < VM_MAXUSER_ADDRESS) { if (va < VM_MAXUSER_ADDRESS)
mpte = pmap_allocpte(pmap, va, M_WAITOK); mpte = pmap_allocpte(pmap, va, M_WAITOK);
}
pde = pmap_pde(pmap, va); pde = pmap_pde(pmap, va);
if (pde != NULL && (*pde & PG_V) != 0) { if (pde != NULL && (*pde & PG_V) != 0) {
@ -3393,7 +3398,7 @@ pmap_enter_object(pmap_t pmap, vm_offset_t start, vm_offset_t end,
mpte); mpte);
m = TAILQ_NEXT(m, listq); m = TAILQ_NEXT(m, listq);
} }
PMAP_UNLOCK(pmap); PMAP_UNLOCK(pmap);
} }
/* /*

View File

@ -172,52 +172,6 @@ SYSCTL_INT(_machdep, OID_AUTO, prot_fault_translation, CTLFLAG_RW,
extern char *syscallnames[]; extern char *syscallnames[];
/* #define DEBUG 1 */
#ifdef DEBUG
static void
report_seg_fault(const char *segn, struct trapframe *frame)
{
struct proc_ldt *pldt;
struct trapframe *pf;
pldt = curproc->p_md.md_ldt;
printf("%d: %s load fault %lx %p %d\n",
curproc->p_pid, segn, frame->tf_err,
pldt != NULL ? pldt->ldt_base : NULL,
pldt != NULL ? pldt->ldt_refcnt : 0);
kdb_backtrace();
pf = (struct trapframe *)frame->tf_rsp;
printf("rdi %lx\n", pf->tf_rdi);
printf("rsi %lx\n", pf->tf_rsi);
printf("rdx %lx\n", pf->tf_rdx);
printf("rcx %lx\n", pf->tf_rcx);
printf("r8 %lx\n", pf->tf_r8);
printf("r9 %lx\n", pf->tf_r9);
printf("rax %lx\n", pf->tf_rax);
printf("rbx %lx\n", pf->tf_rbx);
printf("rbp %lx\n", pf->tf_rbp);
printf("r10 %lx\n", pf->tf_r10);
printf("r11 %lx\n", pf->tf_r11);
printf("r12 %lx\n", pf->tf_r12);
printf("r13 %lx\n", pf->tf_r13);
printf("r14 %lx\n", pf->tf_r14);
printf("r15 %lx\n", pf->tf_r15);
printf("fs %x\n", pf->tf_fs);
printf("gs %x\n", pf->tf_gs);
printf("es %x\n", pf->tf_es);
printf("ds %x\n", pf->tf_ds);
printf("tno %x\n", pf->tf_trapno);
printf("adr %lx\n", pf->tf_addr);
printf("flg %x\n", pf->tf_flags);
printf("err %lx\n", pf->tf_err);
printf("rip %lx\n", pf->tf_rip);
printf("cs %lx\n", pf->tf_cs);
printf("rfl %lx\n", pf->tf_rflags);
printf("rsp %lx\n", pf->tf_rsp);
printf("ss %lx\n", pf->tf_ss);
}
#endif
/* /*
* Exception, fault, and trap interface to the FreeBSD kernel. * Exception, fault, and trap interface to the FreeBSD kernel.
* This common code is called from assembly language IDT gate entry * This common code is called from assembly language IDT gate entry
@ -314,9 +268,7 @@ trap(struct trapframe *frame)
*/ */
printf("kernel trap %d with interrupts disabled\n", printf("kernel trap %d with interrupts disabled\n",
type); type);
#ifdef DEBUG
report_seg_fault("hlt", frame);
#endif
/* /*
* We shouldn't enable interrupts while holding a * We shouldn't enable interrupts while holding a
* spin lock or servicing an NMI. * spin lock or servicing an NMI.
@ -535,33 +487,21 @@ trap(struct trapframe *frame)
goto out; goto out;
} }
if (frame->tf_rip == (long)ld_ds) { if (frame->tf_rip == (long)ld_ds) {
#ifdef DEBUG
report_seg_fault("ds", frame);
#endif
frame->tf_rip = (long)ds_load_fault; frame->tf_rip = (long)ds_load_fault;
frame->tf_ds = _udatasel; frame->tf_ds = _udatasel;
goto out; goto out;
} }
if (frame->tf_rip == (long)ld_es) { if (frame->tf_rip == (long)ld_es) {
#ifdef DEBUG
report_seg_fault("es", frame);
#endif
frame->tf_rip = (long)es_load_fault; frame->tf_rip = (long)es_load_fault;
frame->tf_es = _udatasel; frame->tf_es = _udatasel;
goto out; goto out;
} }
if (frame->tf_rip == (long)ld_fs) { if (frame->tf_rip == (long)ld_fs) {
#ifdef DEBUG
report_seg_fault("fs", frame);
#endif
frame->tf_rip = (long)fs_load_fault; frame->tf_rip = (long)fs_load_fault;
frame->tf_fs = _ufssel; frame->tf_fs = _ufssel;
goto out; goto out;
} }
if (frame->tf_rip == (long)ld_gs) { if (frame->tf_rip == (long)ld_gs) {
#ifdef DEBUG
report_seg_fault("gs", frame);
#endif
frame->tf_rip = (long)gs_load_fault; frame->tf_rip = (long)gs_load_fault;
frame->tf_gs = _ugssel; frame->tf_gs = _ugssel;
goto out; goto out;
@ -667,30 +607,6 @@ trap(struct trapframe *frame)
ksi.ksi_addr = (void *)addr; ksi.ksi_addr = (void *)addr;
trapsignal(td, &ksi); trapsignal(td, &ksi);
#ifdef DEBUG
{
register_t rg,rgk, rf;
if (type <= MAX_TRAP_MSG) {
uprintf("fatal process exception: %s",
trap_msg[type]);
if ((type == T_PAGEFLT) || (type == T_PROTFLT))
uprintf(", fault VA = 0x%lx", frame->tf_addr);
uprintf("\n");
}
rf = rdmsr(0xc0000100);
rg = rdmsr(0xc0000101);
rgk = rdmsr(0xc0000102);
uprintf("pid %d TRAP %d rip %lx err %lx addr %lx cs %lx ss %lx ds %x "
"es %x fs %x fsbase %lx %lx gs %x gsbase %lx %lx %lx\n",
curproc->p_pid, type, frame->tf_rip, frame->tf_err,
frame->tf_addr,
frame->tf_cs, frame->tf_ss, frame->tf_ds, frame->tf_es,
frame->tf_fs, td->td_pcb->pcb_fsbase, rf,
frame->tf_gs, td->td_pcb->pcb_gsbase, rg, rgk);
}
#endif
user: user:
userret(td, frame); userret(td, frame);
mtx_assert(&Giant, MA_NOTOWNED); mtx_assert(&Giant, MA_NOTOWNED);

View File

@ -25,7 +25,22 @@
* *
* $FreeBSD$ * $FreeBSD$
*/ */
#ifndef _MACHINE_IODEV_H_
#define _MACHINE_IODEV_H_
d_open_t ioopen; #ifdef _KERNEL
d_close_t ioclose; #include <machine/cpufunc.h>
d_ioctl_t ioioctl;
#define iodev_read_1 inb
#define iodev_read_2 inw
#define iodev_read_4 inl
#define iodev_write_1 outb
#define iodev_write_2 outw
#define iodev_write_4 outl
int iodev_open(struct thread *td);
int iodev_close(struct thread *td);
int iodev_ioctl(u_long cmd, caddr_t data);
#endif /* _KERNEL */
#endif /* _MACHINE_IODEV_H_ */

View File

@ -245,6 +245,8 @@ struct pmap {
pml4_entry_t *pm_pml4; /* KVA of level 4 page table */ pml4_entry_t *pm_pml4; /* KVA of level 4 page table */
TAILQ_HEAD(,pv_chunk) pm_pvchunk; /* list of mappings in pmap */ TAILQ_HEAD(,pv_chunk) pm_pvchunk; /* list of mappings in pmap */
u_int pm_active; /* active on cpus */ u_int pm_active; /* active on cpus */
uint32_t pm_gen_count; /* generation count (pmap lock dropped) */
u_int pm_retries;
/* spare u_int here due to padding */ /* spare u_int here due to padding */
struct pmap_statistics pm_stats; /* pmap statistics */ struct pmap_statistics pm_stats; /* pmap statistics */
vm_page_t pm_root; /* spare page table pages */ vm_page_t pm_root; /* spare page table pages */

View File

@ -53,8 +53,8 @@ struct mdproc {
struct system_segment_descriptor md_ldt_sd; struct system_segment_descriptor md_ldt_sd;
}; };
#define KINFO_PROC_SIZE 1088 #define KINFO_PROC_SIZE 1088
#define KINFO_PROC32_SIZE 768 #define KINFO_PROC32_SIZE 768
#ifdef _KERNEL #ifdef _KERNEL

View File

@ -113,6 +113,7 @@
#define CPUID_PBE 0x80000000 #define CPUID_PBE 0x80000000
#define CPUID2_SSE3 0x00000001 #define CPUID2_SSE3 0x00000001
#define CPUID2_PCLMULQDQ 0x00000002
#define CPUID2_DTES64 0x00000004 #define CPUID2_DTES64 0x00000004
#define CPUID2_MON 0x00000008 #define CPUID2_MON 0x00000008
#define CPUID2_DS_CPL 0x00000010 #define CPUID2_DS_CPL 0x00000010
@ -131,6 +132,7 @@
#define CPUID2_X2APIC 0x00200000 #define CPUID2_X2APIC 0x00200000
#define CPUID2_MOVBE 0x00400000 #define CPUID2_MOVBE 0x00400000
#define CPUID2_POPCNT 0x00800000 #define CPUID2_POPCNT 0x00800000
#define CPUID2_AESNI 0x02000000
/* /*
* Important bits in the AMD extended cpuid flags * Important bits in the AMD extended cpuid flags

Some files were not shown because too many files have changed in this diff Show More