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

This commit is contained in:
Kirk McKusick 2010-05-06 17:37:23 +00:00
commit 945f418ab8
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
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:
WITH_CTF can now be specified in src.conf (not recommended, there
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;
if (cmdentry.special)
listsetvar(cmdenviron);
if (argc > 0)
bltinsetlocale();
commandname = argv[0];
argptr = argv + 1;
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);
flushall();
cmddone:
if (argc > 0)
bltinunsetlocale();
cmdenviron = NULL;
out1 = &output;
out2 = &errout;

View File

@ -122,6 +122,14 @@ STATIC const struct varinit varinit[] = {
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 int varequal(const char *, const char *);
STATIC int localevar(const char *);
@ -258,11 +266,7 @@ setvar(const char *name, const char *val, int flags)
STATIC int
localevar(const char *s)
{
static const char *lnames[7] = {
"ALL", "COLLATE", "CTYPE", "MONETARY",
"NUMERIC", "TIME", NULL
};
const char **ss;
const char *const *ss;
if (*s != 'L')
return 0;
@ -270,8 +274,10 @@ localevar(const char *s)
return 1;
if (strncmp(s + 1, "C_", 2) != 0)
return 0;
for (ss = lnames; *ss ; ss++)
if (varequal(s + 3, *ss))
if (varequal(s + 3, "ALL"))
return 1;
for (ss = locale_names; *ss ; ss++)
if (varequal(s + 3, *ss + 3))
return 1;
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

View File

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

View File

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

View File

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

View File

@ -3039,7 +3039,7 @@ ztest_spa_import_export(char *oldname, char *newname)
/*
* Export it.
*/
error = spa_export(oldname, &config, B_FALSE);
error = spa_export(oldname, &config, B_FALSE, B_FALSE);
if (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
*/
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 *,
char *altroot);
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.
*/
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 };
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));
zc.zc_cookie = force;
zc.zc_guid = hardforce;
if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_EXPORT, &zc) != 0) {
switch (errno) {
@ -1129,6 +1130,18 @@ zpool_export(zpool_handle_t *zhp, boolean_t force)
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
* 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)
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);
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);
cte.cte_name = CTF_TYPE_NAME(CTF_STRTAB_0, offset);
cte.cte_value = ep->el_number;
ctf_buf_write(b, &cte, sizeof (cte));
i--;
}
break;

View File

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

View File

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

View File

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

View File

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

View File

@ -146,7 +146,6 @@ unsigned char telopt_environ = TELOPT_NEW_ENVIRON;
#endif
jmp_buf toplevel;
jmp_buf peerdied;
int flushline;
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:
* -1: No useful work done, data waiting to go out.
@ -152,8 +153,19 @@ ttyflush(int drop)
}
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;
}
if (n == n0) {
if (n0)
return -1;

View File

@ -34,7 +34,7 @@ static const char privatehid[] = "@(#)private.h 8.6";
#endif /* !defined NOID */
#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.

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@cvs.openbsd.org 2010/03/07 22:16:01
[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
- 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
[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>
* 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;
}
if (strlen(command) != clen) {
error("force-command constrain contains \\0");
error("force-command constraint contains \\0");
goto out;
}
if (cert_forced_command != NULL) {
@ -454,7 +454,7 @@ auth_cert_constraints(Buffer *c_orig, struct passwd *pw)
goto out;
}
if (strlen(allowed) != clen) {
error("source-address constrain contains \\0");
error("source-address constraint contains \\0");
goto out;
}
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.
*
@ -240,22 +240,26 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
continue;
if (!key_equal(found, key->cert->signature_key))
continue;
debug("matching CA found: file %s, line %lu",
file, linenum);
fp = key_fingerprint(found, SSH_FP_MD5,
SSH_FP_HEX);
verbose("Found matching %s CA: %s",
key_type(found), fp);
xfree(fp);
debug("matching CA found: file %s, line %lu, %s %s",
file, linenum, key_type(found), fp);
if (key_cert_check_authority(key, 0, 0, pw->pw_name,
&reason) != 0) {
xfree(fp);
error("%s", reason);
auth_debug_add("%s", reason);
continue;
}
if (auth_cert_constraints(&key->cert->constraints,
pw) != 0)
pw) != 0) {
xfree(fp);
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;
break;
} 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
user_cert_trusted_ca(struct passwd *pw, Key *key)
{
char *key_fp, *ca_fp;
char *ca_fp;
const char *reason;
int ret = 0;
if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL)
return 0;
key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
ca_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
ca_fp = key_fingerprint(key->cert->signature_key,
SSH_FP_MD5, SSH_FP_HEX);
if (key_in_file(key->cert->signature_key,
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)
goto out;
verbose("%s certificate %s allowed by trusted %s key %s",
key_type(key), key_fp, key_type(key->cert->signature_key), ca_fp);
verbose("Accepted certificate ID \"%s\" signed by %s CA %s via %s",
key->cert->key_id, key_type(key->cert->signature_key), ca_fp,
options.trusted_user_ca_keys);
ret = 1;
out:
if (key_fp != NULL)
xfree(key_fp);
if (ca_fp != NULL)
xfree(ca_fp);
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,
ai->ai_protocol);
if (sock < 0) {
if ((errno != EINVAL) && (errno != EAFNOSUPPORT)) {
if ((errno != EINVAL) && (errno != EAFNOSUPPORT)
#ifdef EPFNOSUPPORT
&& (errno != EPFNOSUPPORT)
#endif
) {
error("socket: %.100s", strerror(errno));
freeaddrinfo(aitop);
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>
* 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_put_int(SSH2_DISCONNECT_BY_APPLICATION);
packet_put_cstring("disconnected by user");
packet_put_cstring(""); /* language tag */
packet_send();
packet_write_wait();
}

View File

@ -124,7 +124,7 @@
#define DISABLE_WTMPX 1
/* Enable for PKCS#11 support */
#define ENABLE_PKCS11
#define ENABLE_PKCS11 /**/
/* Builtin PRNG command timeout */
#define ENTROPY_TIMEOUT_MSEC 200
@ -456,6 +456,9 @@
/* Define to 1 if you have the `getutxline' function. */
#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. */
/* #undef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL */
@ -552,6 +555,9 @@
/* Define if system has libiaf that supports set_id */
/* #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). */
/* #undef HAVE_LIBNSL */
@ -805,6 +811,9 @@
/* Define to 1 if you have the `setutent' function. */
/* #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 HAVE_SETUTXENT 1
@ -1416,8 +1425,8 @@
/* Define if you want SELinux support. */
/* #undef WITH_SELINUX */
/* Define to 1 if your processor stores words with the most significant byte
first (like Motorola and SPARC, unlike Intel and VAX). */
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel and VAX). */
#if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
#elif ! defined __LITTLE_ENDIAN__

View File

@ -80,9 +80,6 @@
/* Define if you want to specify the path to your 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 */
#undef CONF_UTMP_FILE
@ -455,6 +452,9 @@
/* Define to 1 if you have the `getutxline' function. */
#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. */
#undef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
@ -551,6 +551,9 @@
/* Define if system has libiaf that supports set_id */
#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). */
#undef HAVE_LIBNSL
@ -804,6 +807,9 @@
/* Define to 1 if you have the `setutent' function. */
#undef HAVE_SETUTENT
/* Define to 1 if you have the `setutxdb' function. */
#undef HAVE_SETUTXDB
/* Define to 1 if you have the `setutxent' function. */
#undef HAVE_SETUTXENT

View File

@ -25,7 +25,7 @@
#ifndef _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 */

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():
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -801,6 +801,19 @@ key_type(const Key *k)
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 *
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.
@ -82,6 +82,7 @@ int key_equal(const Key *, const Key *);
char *key_fingerprint(Key *, enum fp_type, enum fp_rep);
u_char *key_fingerprint_raw(Key *, enum fp_type, u_int *);
const char *key_type(const Key *);
const char *key_cert_type(const Key *);
int key_write(const Key *, FILE *);
int key_read(Key *, char **);
u_int key_size(const Key *);

View File

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

View File

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

View File

@ -84,7 +84,7 @@ arc4random_stir(void)
}
#endif /* !HAVE_ARC4RANDOM */
#ifndef ARC4RANDOM_BUF
#ifndef HAVE_ARC4RANDOM_BUF
void
arc4random_buf(void *_buf, size_t n)
{
@ -102,7 +102,7 @@ arc4random_buf(void *_buf, size_t n)
}
#endif /* !HAVE_ARC4RANDOM_BUF */
#ifndef ARC4RANDOM_UNIFORM
#ifndef HAVE_ARC4RANDOM_UNIFORM
/*
* Calculate a uniformly distributed random number less than upper_bound
* 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
* All rights reserved
@ -474,15 +474,14 @@ parse_token(const char *cp, const char *filename,
char *
derelativise_path(const char *path)
{
char *expanded, *ret, *cwd;
char *expanded, *ret, cwd[MAXPATHLEN];
expanded = tilde_expand_filename(path, getuid());
if (*expanded == '/')
return expanded;
if ((cwd = getcwd(NULL, 0)) == NULL)
if (getcwd(cwd, sizeof(cwd)) == NULL)
fatal("%s: getcwd: %s", __func__, strerror(errno));
xasprintf(&ret, "%s/%s", cwd, expanded);
xfree(cwd);
xfree(expanded);
return ret;
}
@ -1227,7 +1226,17 @@ process_server_config_line(ServerOptions *options, char *line,
charptr = (opcode == sAuthorizedKeysFile) ?
&options->authorized_keys_file :
&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:
intptr = &options->client_alive_interval;

View File

@ -1581,6 +1581,10 @@ do_setusercontext(struct passwd *pw)
}
#endif /* HAVE_SETPCRED */
#ifdef WITH_SELINUX
ssh_selinux_setup_exec_context(pw->pw_name);
#endif
if (options.chroot_directory != NULL &&
strcasecmp(options.chroot_directory, "none") != 0) {
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)
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

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$
.\"
.\" -*- nroff -*-
@ -38,7 +38,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd March 8 2010
.Dd March 13 2010
.Dt SSH-KEYGEN 1
.Os
.Sh NAME
@ -308,8 +308,15 @@ Please see the
section for details.
The constraints that are valid for user certificates are:
.Bl -tag -width Ds
.It Ic no-x11-forwarding
Disable X11 forwarding (permitted by default).
.It Ic clear
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
Disable
.Xr ssh-agent 1
@ -324,12 +331,8 @@ Disable execution of
by
.Xr sshd 8
(permitted by default).
.It Ic clear
Clear all enabled permissions.
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 no-x11-forwarding
Disable X11 forwarding (permitted by default).
.It Ic permit-agent-forwarding
Allows
.Xr ssh-agent 1
@ -343,14 +346,10 @@ Allows execution of
.Pa ~/.ssh/rc
by
.Xr sshd 8 .
.It Ic force-command=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 source-address=address_list
Restrict the source addresses from which the certificate is considered valid
from.
.It Ic permit-x11-forwarding
Allows X11 forwarding.
.It Ic source-address Ns = Ns Ar address_list
Restrict the source addresses from which the certificate is considered valid.
The
.Ar address_list
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
.Sx TIME FORMATS
section of
.Xr ssh_config 5 .
.Xr sshd_config 5 .
The end time may be specified as a YYYYMMDD date, a YYYYMMDDHHMMSS time or
a relative time starting with a plus character.
.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
.Pp
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
.Fl h
option:
@ -528,7 +527,7 @@ option:
.Dl $ ssh-keygen -s /path/to/ca_key -I key_id -h /path/to/host_key.pub
.Pp
The host certificate will be output to
.Pa /path/to/host_key_cert.pub .
.Pa /path/to/host_key-cert.pub .
In both cases,
.Ar key_id
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:
.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 -h -n host.domain user_key.pub
.Dl "$ ssh-keygen -s ca_key -I key_id -h -n host.domain user_key.pub"
.Pp
Additional limitations on the validity and use of user certificates may
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>
* 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);
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",
key_type(key->cert->signature_key), ca_fp);
printf(" Key ID \"%s\"\n", key->cert->key_id);

View File

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

View File

@ -34,9 +34,9 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" 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$
.Dd March 5 2010
.Dd March 26 2010
.Dt SSH 1
.Os
.Sh NAME
@ -560,7 +560,10 @@ argument is
the listen port will be dynamically allocated on the server and reported
to the client at run time.
.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
.Cm ControlPath
and

View File

@ -46,4 +46,4 @@
# PermitLocalCommand no
# VisualHostKey no
# 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
.\" 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$
.Dd March 5 2010
.Dd March 26 2010
.Dt SSH_CONFIG 5
.Os
.Sh NAME
@ -735,11 +735,7 @@ This allows a client to prefer one method (e.g.\&
over another method (e.g.\&
.Cm password )
The default for this option is:
.Do gssapi-with-mic ,
hostbased,
publickey,
keyboard-interactive,
password
.Do gssapi-with-mic,hostbased,publickey,keyboard-interactive,password
.Dc .
.It Cm Protocol
Specifies the protocol versions
@ -1087,7 +1083,7 @@ in
Specifies a string to append to the regular version string to identify
OS- or site-specific modifications.
The default is
.Dq FreeBSD-20100308 .
.Dq FreeBSD-20100428 .
.It Cm VisualHostKey
If this flag is set to
.Dq yes ,

View File

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

View File

@ -988,7 +988,7 @@ The default is
Specifies a string to append to the regular version string to identify
OS- or site-specific modifications.
The default is
.Dq FreeBSD-20100308 .
.Dq FreeBSD-20100428 .
.It Cm X11DisplayOffset
Specifies the first display number available for
.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$ */
#ifndef SSH_VERSION
#define SSH_VERSION (ssh_version_get())
#define SSH_RELEASE (ssh_version_get())
#define SSH_VERSION_BASE "OpenSSH_5.4p1"
#define SSH_VERSION_ADDENDUM "FreeBSD-20100308"
#define SSH_VERSION_BASE "OpenSSH_5.5p1"
#define SSH_VERSION_ADDENDUM "FreeBSD-20100428"
const char *ssh_version_get(void);
void ssh_version_set_addendum(const char *);

View File

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

View File

@ -192,6 +192,13 @@ named_prestart()
$confgen_command
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
if checkyesno named_auto_forward; then
if [ ! -s /etc/resolv.conf ]; then
@ -201,7 +208,7 @@ named_prestart()
[ -s "${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'
return
fi
@ -263,8 +270,7 @@ named_prestart()
create_file ${named_confdir}/auto_forward.conf
fi
${command%/named}/named-checkconf $named_conf ||
err 3 'named-checkconf for $named_conf failed'
$checkconf $named_conf || err 3 'named-checkconf for $named_conf failed'
}
load_rc_config $name
@ -272,7 +278,7 @@ load_rc_config $name
# Updating the following variables requires that rc.conf be loaded first
#
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}"
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.3 7.3
.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
.
.\" Definitions not (yet) in doc-syms

View File

@ -28,7 +28,7 @@
.\" @(#)getrusage.2 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
.Dd June 4, 1993
.Dd May 1, 2010
.Dt GETRUSAGE 2
.Os
.Sh NAME
@ -42,6 +42,7 @@
.In sys/resource.h
.Fd "#define RUSAGE_SELF 0"
.Fd "#define RUSAGE_CHILDREN -1"
.Fd "#define RUSAGE_THREAD 1"
.Ft int
.Fn getrusage "int who" "struct rusage *rusage"
.Sh DESCRIPTION
@ -49,11 +50,12 @@ The
.Fn getrusage
system call
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
.Fa who
argument is either
.Dv RUSAGE_SELF
.Dv RUSAGE_THREAD ,
.Dv RUSAGE_SELF ,
or
.Dv RUSAGE_CHILDREN .
The buffer to which
@ -175,6 +177,10 @@ The
.Fn getrusage
system call appeared in
.Bx 4.2 .
The
.Dv RUSAGE_THREAD
facility first appeared in
.Fx 8.1 .
.Sh BUGS
There is no way to obtain information about a child process
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 $
.\" $FreeBSD$
.Dd January 15, 1999
.Dd May 3, 2010
.Dt PAM_KRB5 8
.Os
.Sh NAME
@ -108,6 +108,10 @@ and
.Ql %p ,
to designate the current process ID; can be used in
.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
.Ss Kerberos 5 Account Management Module
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_FORWARDABLE "forwardable"
#define PAM_OPT_NO_CCACHE "no_ccache"
#define PAM_OPT_NO_USER_CHECK "no_user_check"
#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");
/* Verify the local user exists (AFTER getting the password) */
if (strchr(user, '@')) {
/* get a local account name for this principal */
krbret = krb5_aname_to_localname(pam_context, princ,
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));
if (openpam_get_option(pamh, PAM_OPT_NO_USER_CHECK))
PAM_LOG("Skipping local user check");
else {
/* Verify the local user exists (AFTER getting the password) */
if (strchr(user, '@')) {
/* get a local account name for this principal */
krbret = krb5_aname_to_localname(pam_context, princ,
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;
goto cleanup2;
}
retval = pam_set_item(pamh, PAM_USER, luser);
if (retval != PAM_SUCCESS)
goto cleanup2;
PAM_LOG("PAM_USER Redone");
PAM_LOG("Done getpwnam()");
}
pwd = getpwnam(user);
if (pwd == NULL) {
retval = PAM_USER_UNKNOWN;
goto cleanup2;
}
PAM_LOG("Done getpwnam()");
/* Get a TGT */
memset(&creds, 0, sizeof(krb5_creds));
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);
/* 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);
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_41H: /* Core */
case PMC_EV_IAP_EVENT_42H: /* Core, Core2, Atom */
case PMC_EV_IAP_EVENT_77H: /* Core */
if (cachestate == 0)
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:
break;
}

View File

@ -145,7 +145,7 @@ cgialloc(struct uufsd *disk)
fs = &disk->d_fs;
cgp = &disk->d_cg;
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))
goto gotit;
return (0);

View File

@ -2,15 +2,14 @@
# $FreeBSD$
PROG= tftpd
SRCS= tftpd.c tftpsubs.c
DPADD= ${LIBUTIL}
LDADD= -lutil
WARNS?= 1
SRCS= tftpd.c tftp-io.c tftp-utils.c tftp-file.c tftp-transfer.c tftp-options.c
WARNS= 3
WFORMAT=0
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
COPTFLAGS = -O
LDFLAGS= -lwrap
.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
.Sh SYNOPSIS
.Nm tftpd
.Op Fl cClnwW
.Op Fl cdClnow
.Op Fl F Ar strftime-format
.Op Fl s Ar directory
.Op Fl u Ar user
@ -150,6 +150,9 @@ compatible format string for the creation of the suffix if
.Fl W
is specified.
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
Log all requests using
.Xr syslog 3
@ -164,6 +167,8 @@ must also be enabled in the syslog configuration file,
.It Fl n
Suppress negative acknowledgement of requests for nonexistent
relative filenames.
.It Fl o
Disable support for RFC2347 style TFTP Options.
.It Fl s Ar directory
Cause
.Nm
@ -240,10 +245,16 @@ and the
and
.Fl W
options were introduced in
.Fx 8.0 .
.Fx 7 .
.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
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
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$
.\"
.Dd January 20, 2010
.Dd May 2, 2010
.Dt CAMCONTROL 8
.Os
.Sh NAME
@ -123,6 +123,8 @@
.Op generic args
.Aq Fl a Ar cmd Op args
.Aq Fl c Ar cmd Op args
.Op Fl d
.Op Fl f
.Op Fl i Ar len Ar fmt
.Bk -words
.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
This specifies the SCSI CDB.
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
This specifies the amount of data to read, and how it should be displayed.
If the format is

View File

@ -123,7 +123,7 @@ struct camcontrol_opts {
};
#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 negotiate_opts[] = "acD:M:O:qR:T:UW:";
#endif
@ -2184,6 +2184,8 @@ scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
int c, data_bytes = 0;
int cdb_len = 0;
int atacmd_len = 0;
int dmacmd = 0;
int fpdmacmd = 0;
int need_res = 0;
char *datastr = NULL, *tstr, *resstr = NULL;
int error = 0;
@ -2246,6 +2248,12 @@ scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
*/
optind += hook.got;
break;
case 'd':
dmacmd = 1;
break;
case 'f':
fpdmacmd = 1;
break;
case 'i':
if (arglist & CAM_ARG_CMD_OUT) {
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);
if (need_res)
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,
/*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,
sata->tags);
}
if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
sata->caps);
}
}
if (cts->protocol == PROTO_SCSI) {
struct ccb_trans_settings_scsi *scsi=
@ -4353,7 +4369,7 @@ usage(int verbose)
" [-P pagectl][-e | -b][-d]\n"
" camcontrol cmd [dev_id][generic 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"
" <all|bus[:target[:lun]]|off>\n"
" camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"

View File

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

View File

@ -75,6 +75,7 @@
#define HIO_DELETE 3
#define HIO_FLUSH 4
#define HAST_TIMEOUT 5
#define HAST_CONFIG "/etc/hast.conf"
#define HAST_CONTROL "/var/run/hastctl"
#define HASTD_PORT 8457
@ -148,6 +149,8 @@ struct hast_resource {
/* Token to verify both in and out connection are coming from
the same node (not necessarily from the same address). */
unsigned char hr_token[HAST_TOKEN_SIZE];
/* Connection timeout. */
int hr_timeout;
/* Resource unique identifier. */
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
child_exit(void)
{
@ -129,20 +145,25 @@ child_exit(void)
}
pjdlog_prefix_set("[%s] (%s) ", res->hr_name,
role2str(res->hr_role));
if (WEXITSTATUS(status) == 0) {
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));
}
child_exit_log(pid, status);
proto_close(res->hr_ctrl);
res->hr_workerpid = 0;
if (res->hr_role == HAST_ROLE_PRIMARY) {
sleep(1);
pjdlog_info("Restarting worker process.");
hastd_primary(res);
/*
* Restart child process if it was killed by signal
* 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", "");
}
@ -181,6 +202,10 @@ listen_accept(void)
proto_remote_address(conn, raddr, sizeof(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;
/*
@ -290,18 +315,12 @@ listen_accept(void)
/* Wait for it to exit. */
else if ((pid = waitpid(res->hr_workerpid,
&status, 0)) != res->hr_workerpid) {
/* We can only log the problem. */
pjdlog_errno(LOG_ERR,
"Waiting for worker process (pid=%u) failed",
(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 {
pjdlog_debug(1,
"Worker process (pid=%u) exited gracefully.",
(unsigned int)res->hr_workerpid);
child_exit_log(res->hr_workerpid, status);
}
res->hr_workerpid = 0;
} 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");
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.",
res->hr_localpath, res->hr_name);
nv_free(nv);

View File

@ -58,6 +58,7 @@ static bool mynode;
static char depth0_control[HAST_ADDRSIZE];
static char depth0_listen[HAST_ADDRSIZE];
static int depth0_replication;
static int depth0_timeout;
static char depth1_provname[PATH_MAX];
static char depth1_localpath[PATH_MAX];
@ -115,6 +116,7 @@ yy_config_parse(const char *config)
curres = NULL;
mynode = false;
depth0_timeout = HAST_TIMEOUT;
depth0_replication = HAST_REPLICATION_MEMSYNC;
strlcpy(depth0_control, HAST_CONTROL, sizeof(depth0_control));
strlcpy(depth0_listen, HASTD_LISTEN, sizeof(depth0_listen));
@ -154,6 +156,13 @@ yy_config_parse(const char *config)
*/
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);
@ -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 NUM STR OB CB
@ -200,6 +209,8 @@ statement:
|
replication_statement
|
timeout_statement
|
node_statement
|
resource_statement
@ -281,6 +292,22 @@ replication_type:
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
{
mynode = false;
@ -389,6 +416,7 @@ resource_start: STR
curres->hr_role = HAST_ROLE_INIT;
curres->hr_previous_role = HAST_ROLE_INIT;
curres->hr_replication = -1;
curres->hr_timeout = -1;
curres->hr_provname[0] = '\0';
curres->hr_localpath[0] = '\0';
curres->hr_localfd = -1;
@ -405,6 +433,8 @@ resource_entries:
resource_entry:
replication_statement
|
timeout_statement
|
name_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. */
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);
}
/* Try to connect, but accept failure. */
@ -489,6 +489,9 @@ init_remote(struct hast_resource *res, struct proto_conn **inp,
res->hr_remoteaddr);
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.
* Setup outgoing connection with remote node.
@ -552,6 +555,9 @@ init_remote(struct hast_resource *res, struct proto_conn **inp,
res->hr_remoteaddr);
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();
nv_add_string(nvout, res->hr_name, "resource");
nv_add_uint8_array(nvout, res->hr_token, sizeof(res->hr_token),
@ -739,7 +745,7 @@ hastd_primary(struct hast_resource *res)
pid = fork();
if (pid < 0) {
KEEP_ERRNO((void)pidfile_remove(pfh));
primary_exit(EX_OSERR, "Unable to fork");
primary_exit(EX_TEMPFAIL, "Unable to fork");
}
if (pid > 0) {

View File

@ -30,7 +30,9 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/queue.h>
#include <sys/socket.h>
#include <assert.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);
}
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
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);
void proto_remote_address(const struct proto_conn *conn, char *addr,
size_t size);
int proto_timeout(const struct proto_conn *conn, int timeout);
void proto_close(struct proto_conn *conn);
#endif /* !_PROTO_H_ */

View File

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

View File

@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <stdbool.h>
#include <stdint.h>
@ -47,6 +48,7 @@ __FBSDID("$FreeBSD$");
#include "hast.h"
#include "pjdlog.h"
#include "proto_impl.h"
#include "subr.h"
#define TCP4_CTX_MAGIC 0x7c441c
struct tcp4_ctx {
@ -222,18 +224,88 @@ static int
tcp4_connect(void *ctx)
{
struct tcp4_ctx *tctx = ctx;
struct timeval tv;
fd_set fdset;
socklen_t esize;
int error, flags, ret;
assert(tctx != NULL);
assert(tctx->tc_magic == TCP4_CTX_MAGIC);
assert(tctx->tc_side == TCP4_SIDE_CLIENT);
assert(tctx->tc_fd >= 0);
if (connect(tctx->tc_fd, (struct sockaddr *)&tctx->tc_sin,
sizeof(tctx->tc_sin)) < 0) {
flags = fcntl(tctx->tc_fd, F_GETFL);
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 (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

View File

@ -337,6 +337,12 @@ hastd_secondary(struct hast_resource *res, struct nv *nvin)
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_remote(res, nvin);
init_environment();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd March 1, 2010
.Dd April 30, 2010
.Dt MSK 4
.Os
.Sh NAME
@ -208,6 +208,8 @@ Marvell Yukon 88E8057 Gigabit Ethernet
.It
Marvell Yukon 88E8058 Gigabit Ethernet
.It
Marvell Yukon 88E8059 Gigabit Ethernet
.It
Marvell Yukon 88E8070 Gigabit Ethernet
.It
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$
.\"
.Dd August 31, 2000
.Dd May 5, 2010
.Dt NG_BRIDGE 4
.Os
.Sh NAME
@ -181,11 +181,17 @@ but also atomically clears the statistics as well.
.It Dv NGM_BRIDGE_GET_TABLE
Returns the current host mapping table used to direct packets, in a
.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
.Sh SHUTDOWN
This node shuts down upon receipt of a
.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
.Bl -tag -width XXXXXXXX -compact
.It Pa /usr/share/examples/netgraph/ether.bridge

View File

@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd April 17, 2004
.Dd May 5, 2010
.Dt NG_HUB 4
.Os
.Sh NAME
@ -45,11 +45,20 @@ A
node accepts any request to connect, regardless of the hook name,
as long as the name is unique.
.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
This node shuts down upon receipt of a
.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
.Xr netgraph 4 ,
.Xr ng_bridge 4 ,

View File

@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd April 14, 2010
.Dd April 29, 2010
.Dt SGE 4
.Os
.Sh NAME
@ -53,11 +53,11 @@ controllers and SiS191 Fast/Gigabit Ethernet controllers.
.Pp
All LOMs supported by the
.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
segmentation offload (TSO), hardware VLAN tag stripping/insertion
features, Wake On Lan (WOL), Jumbo frame and an interrupt moderation
mechanism are not supported yet.
segmentation offload (TSO), Wake On Lan (WOL), Jumbo frame and an
interrupt moderation mechanism are not supported yet.
.Pp
The
.Nm

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -28,60 +28,32 @@
__FBSDID("$FreeBSD$");
#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/signalvar.h>
#include <sys/systm.h>
#include <machine/db_machdep.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/psl.h>
/* ARGSUSED */
int
ioopen(struct cdev *dev __unused, int flags __unused, int fmt __unused,
struct thread *td)
iodev_open(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;
return (0);
}
/* ARGSUSED */
int
ioclose(struct cdev *dev __unused, int flags __unused, int fmt __unused,
struct thread *td)
iodev_close(struct thread *td)
{
td->td_frame->tf_rflags &= ~PSL_IOPL;
return (0);
}
/* ARGSUSED */
int
ioioctl(struct cdev *dev __unused, u_long cmd __unused, caddr_t data __unused,
int fflag __unused, struct thread *td __unused)
iodev_ioctl(u_long cmd __unused, caddr_t data __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,
&pmap_pdpe_demotions, 0, "1GB page demotions");
/***************************************************
* 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;
pt_entry_t pte;
vm_paddr_t pa;
vm_page_t m;
pa = 0;
m = NULL;
vm_page_lock_queues();
PMAP_LOCK(pmap);
retry:
pdep = pmap_pde(pmap, va);
if (pdep != NULL && (pde = *pdep)) {
if (pde & PG_PS) {
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) |
(va & PDRMASK));
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);
if ((pte & PG_V) &&
((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);
vm_page_hold(m);
}
}
}
vm_page_unlock_queues();
PA_UNLOCK_COND(pa);
PMAP_UNLOCK(pmap);
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
* resident, we are creating it here.
*/
if (va < VM_MAXUSER_ADDRESS) {
if (va < VM_MAXUSER_ADDRESS)
mpte = pmap_allocpte(pmap, va, M_WAITOK);
}
pde = pmap_pde(pmap, va);
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);
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[];
/* #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.
* 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",
type);
#ifdef DEBUG
report_seg_fault("hlt", frame);
#endif
/*
* We shouldn't enable interrupts while holding a
* spin lock or servicing an NMI.
@ -535,33 +487,21 @@ trap(struct trapframe *frame)
goto out;
}
if (frame->tf_rip == (long)ld_ds) {
#ifdef DEBUG
report_seg_fault("ds", frame);
#endif
frame->tf_rip = (long)ds_load_fault;
frame->tf_ds = _udatasel;
goto out;
}
if (frame->tf_rip == (long)ld_es) {
#ifdef DEBUG
report_seg_fault("es", frame);
#endif
frame->tf_rip = (long)es_load_fault;
frame->tf_es = _udatasel;
goto out;
}
if (frame->tf_rip == (long)ld_fs) {
#ifdef DEBUG
report_seg_fault("fs", frame);
#endif
frame->tf_rip = (long)fs_load_fault;
frame->tf_fs = _ufssel;
goto out;
}
if (frame->tf_rip == (long)ld_gs) {
#ifdef DEBUG
report_seg_fault("gs", frame);
#endif
frame->tf_rip = (long)gs_load_fault;
frame->tf_gs = _ugssel;
goto out;
@ -667,30 +607,6 @@ trap(struct trapframe *frame)
ksi.ksi_addr = (void *)addr;
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:
userret(td, frame);
mtx_assert(&Giant, MA_NOTOWNED);

View File

@ -25,7 +25,22 @@
*
* $FreeBSD$
*/
#ifndef _MACHINE_IODEV_H_
#define _MACHINE_IODEV_H_
d_open_t ioopen;
d_close_t ioclose;
d_ioctl_t ioioctl;
#ifdef _KERNEL
#include <machine/cpufunc.h>
#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 */
TAILQ_HEAD(,pv_chunk) pm_pvchunk; /* list of mappings in pmap */
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 */
struct pmap_statistics pm_stats; /* pmap statistics */
vm_page_t pm_root; /* spare page table pages */

View File

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

View File

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

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