Final update to current version of head in preparation for reintegration.
This commit is contained in:
commit
945f418ab8
8
UPDATING
8
UPDATING
@ -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
|
||||
|
@ -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;
|
||||
|
75
bin/sh/var.c
75
bin/sh/var.c
@ -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
|
||||
|
@ -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 **);
|
||||
|
@ -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 };
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 *,
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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*/
|
||||
|
@ -233,7 +233,6 @@ extern void
|
||||
SetNetTrace(char *); /* Function to change where debugging goes */
|
||||
|
||||
extern jmp_buf
|
||||
peerdied,
|
||||
toplevel; /* For error conditions. */
|
||||
|
||||
extern void
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -146,7 +146,6 @@ unsigned char telopt_environ = TELOPT_NEW_ENVIRON;
|
||||
#endif
|
||||
|
||||
jmp_buf toplevel;
|
||||
jmp_buf peerdied;
|
||||
|
||||
int flushline;
|
||||
int linemode;
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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]
|
||||
|
@ -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 $
|
||||
|
@ -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++) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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__
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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 *);
|
||||
|
@ -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
|
||||
/*
|
||||
|
@ -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);
|
||||
|
@ -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".
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -46,4 +46,4 @@
|
||||
# PermitLocalCommand no
|
||||
# VisualHostKey no
|
||||
# ProxyCommand ssh -q -W %h:%p gateway.example.com
|
||||
# VersionAddendum FreeBSD-20100308
|
||||
# VersionAddendum FreeBSD-20100428
|
||||
|
@ -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 ,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 *);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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%/*}"
|
||||
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
257
libexec/tftpd/tftp-file.c
Normal 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
37
libexec/tftpd/tftp-file.h
Normal 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
478
libexec/tftpd/tftp-io.c
Normal 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
47
libexec/tftpd/tftp-io.h
Normal 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;
|
390
libexec/tftpd/tftp-options.c
Normal file
390
libexec/tftpd/tftp-options.c
Normal 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");
|
||||
}
|
62
libexec/tftpd/tftp-options.h
Normal file
62
libexec/tftpd/tftp-options.h
Normal 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,
|
||||
};
|
318
libexec/tftpd/tftp-transfer.c
Normal file
318
libexec/tftpd/tftp-transfer.c
Normal 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;
|
||||
}
|
31
libexec/tftpd/tftp-transfer.h
Normal file
31
libexec/tftpd/tftp-transfer.h
Normal 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
320
libexec/tftpd/tftp-utils.c
Normal 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
124
libexec/tftpd/tftp-utils.h
Normal 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);
|
@ -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
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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_ */
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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; }
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -220,6 +220,7 @@ MAN= aac.4 \
|
||||
msk.4 \
|
||||
mtio.4 \
|
||||
multicast.4 \
|
||||
mvs.4 \
|
||||
mwl.4 \
|
||||
mwlfw.4 \
|
||||
mxge.4 \
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
176
share/man/man4/mvs.4
Normal 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 .
|
@ -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
|
||||
|
@ -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 ,
|
||||
|
@ -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
|
||||
|
@ -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 ,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>"
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
|
@ -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_ */
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user