Final update to current version of head in preparation for reintegration.
This commit is contained in:
commit
b25e55dcc5
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
|
machines to maximize performance. (To disable malloc debugging, run
|
||||||
ln -s aj /etc/malloc.conf.)
|
ln -s aj /etc/malloc.conf.)
|
||||||
|
|
||||||
|
|
||||||
|
20100429:
|
||||||
|
'vm_page's are now hashed by physical address to an array of mutexes.
|
||||||
|
Currently this is only used to serialize access to hold_count. Over
|
||||||
|
time the page queue mutex will be peeled away. This changes the size
|
||||||
|
of pmap on every architecture. And requires all callers of vm_page_hold
|
||||||
|
and vm_page_unhold to be updated.
|
||||||
|
|
||||||
20100402:
|
20100402:
|
||||||
WITH_CTF can now be specified in src.conf (not recommended, there
|
WITH_CTF can now be specified in src.conf (not recommended, there
|
||||||
are some problems with static executables), make.conf (would also
|
are some problems with static executables), make.conf (would also
|
||||||
|
@ -937,6 +937,8 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
|
|||||||
cmdentry.special = 1;
|
cmdentry.special = 1;
|
||||||
if (cmdentry.special)
|
if (cmdentry.special)
|
||||||
listsetvar(cmdenviron);
|
listsetvar(cmdenviron);
|
||||||
|
if (argc > 0)
|
||||||
|
bltinsetlocale();
|
||||||
commandname = argv[0];
|
commandname = argv[0];
|
||||||
argptr = argv + 1;
|
argptr = argv + 1;
|
||||||
nextopt_optptr = NULL; /* initialize nextopt */
|
nextopt_optptr = NULL; /* initialize nextopt */
|
||||||
@ -944,6 +946,8 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
|
|||||||
exitstatus = (*builtinfunc[cmdentry.u.index])(argc, argv);
|
exitstatus = (*builtinfunc[cmdentry.u.index])(argc, argv);
|
||||||
flushall();
|
flushall();
|
||||||
cmddone:
|
cmddone:
|
||||||
|
if (argc > 0)
|
||||||
|
bltinunsetlocale();
|
||||||
cmdenviron = NULL;
|
cmdenviron = NULL;
|
||||||
out1 = &output;
|
out1 = &output;
|
||||||
out2 = &errout;
|
out2 = &errout;
|
||||||
|
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 struct var *vartab[VTABSIZE];
|
||||||
|
|
||||||
|
STATIC const char *const locale_names[7] = {
|
||||||
|
"LC_COLLATE", "LC_CTYPE", "LC_MONETARY",
|
||||||
|
"LC_NUMERIC", "LC_TIME", "LC_MESSAGES", NULL
|
||||||
|
};
|
||||||
|
STATIC const int locale_categories[7] = {
|
||||||
|
LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME, LC_MESSAGES, 0
|
||||||
|
};
|
||||||
|
|
||||||
STATIC struct var **hashvar(const char *);
|
STATIC struct var **hashvar(const char *);
|
||||||
STATIC int varequal(const char *, const char *);
|
STATIC int varequal(const char *, const char *);
|
||||||
STATIC int localevar(const char *);
|
STATIC int localevar(const char *);
|
||||||
@ -258,11 +266,7 @@ setvar(const char *name, const char *val, int flags)
|
|||||||
STATIC int
|
STATIC int
|
||||||
localevar(const char *s)
|
localevar(const char *s)
|
||||||
{
|
{
|
||||||
static const char *lnames[7] = {
|
const char *const *ss;
|
||||||
"ALL", "COLLATE", "CTYPE", "MONETARY",
|
|
||||||
"NUMERIC", "TIME", NULL
|
|
||||||
};
|
|
||||||
const char **ss;
|
|
||||||
|
|
||||||
if (*s != 'L')
|
if (*s != 'L')
|
||||||
return 0;
|
return 0;
|
||||||
@ -270,8 +274,10 @@ localevar(const char *s)
|
|||||||
return 1;
|
return 1;
|
||||||
if (strncmp(s + 1, "C_", 2) != 0)
|
if (strncmp(s + 1, "C_", 2) != 0)
|
||||||
return 0;
|
return 0;
|
||||||
for (ss = lnames; *ss ; ss++)
|
if (varequal(s + 3, "ALL"))
|
||||||
if (varequal(s + 3, *ss))
|
return 1;
|
||||||
|
for (ss = locale_names; *ss ; ss++)
|
||||||
|
if (varequal(s + 3, *ss + 3))
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -437,6 +443,61 @@ bltinlookup(const char *name, int doall)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up locale for a builtin (LANG/LC_* assignments).
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
bltinsetlocale(void)
|
||||||
|
{
|
||||||
|
struct strlist *lp;
|
||||||
|
int act = 0;
|
||||||
|
char *loc, *locdef;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (lp = cmdenviron ; lp ; lp = lp->next) {
|
||||||
|
if (localevar(lp->text)) {
|
||||||
|
act = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!act)
|
||||||
|
return;
|
||||||
|
loc = bltinlookup("LC_ALL", 0);
|
||||||
|
INTOFF;
|
||||||
|
if (loc != NULL) {
|
||||||
|
setlocale(LC_ALL, loc);
|
||||||
|
INTON;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
locdef = bltinlookup("LANG", 0);
|
||||||
|
for (i = 0; locale_names[i] != NULL; i++) {
|
||||||
|
loc = bltinlookup(locale_names[i], 0);
|
||||||
|
if (loc == NULL)
|
||||||
|
loc = locdef;
|
||||||
|
if (loc != NULL)
|
||||||
|
setlocale(locale_categories[i], loc);
|
||||||
|
}
|
||||||
|
INTON;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Undo the effect of bltinlocaleset().
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
bltinunsetlocale(void)
|
||||||
|
{
|
||||||
|
struct strlist *lp;
|
||||||
|
|
||||||
|
INTOFF;
|
||||||
|
for (lp = cmdenviron ; lp ; lp = lp->next) {
|
||||||
|
if (localevar(lp->text)) {
|
||||||
|
setlocale(LC_ALL, "");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
INTON;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate a list of exported variables. This routine is used to construct
|
* Generate a list of exported variables. This routine is used to construct
|
||||||
|
@ -107,6 +107,8 @@ struct strlist;
|
|||||||
void listsetvar(struct strlist *);
|
void listsetvar(struct strlist *);
|
||||||
char *lookupvar(const char *);
|
char *lookupvar(const char *);
|
||||||
char *bltinlookup(const char *, int);
|
char *bltinlookup(const char *, int);
|
||||||
|
void bltinsetlocale(void);
|
||||||
|
void bltinunsetlocale(void);
|
||||||
char **environment(void);
|
char **environment(void);
|
||||||
int showvarscmd(int, char **);
|
int showvarscmd(int, char **);
|
||||||
int exportcmd(int, char **);
|
int exportcmd(int, char **);
|
||||||
|
@ -1790,7 +1790,7 @@ zfs_do_list(int argc, char **argv)
|
|||||||
boolean_t scripted = B_FALSE;
|
boolean_t scripted = B_FALSE;
|
||||||
static char default_fields[] =
|
static char default_fields[] =
|
||||||
"name,used,available,referenced,mountpoint";
|
"name,used,available,referenced,mountpoint";
|
||||||
int types = ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME;
|
int types = ZFS_TYPE_DATASET;
|
||||||
boolean_t types_specified = B_FALSE;
|
boolean_t types_specified = B_FALSE;
|
||||||
char *fields = NULL;
|
char *fields = NULL;
|
||||||
list_cbdata_t cb = { 0 };
|
list_cbdata_t cb = { 0 };
|
||||||
|
@ -879,17 +879,21 @@ int
|
|||||||
zpool_do_export(int argc, char **argv)
|
zpool_do_export(int argc, char **argv)
|
||||||
{
|
{
|
||||||
boolean_t force = B_FALSE;
|
boolean_t force = B_FALSE;
|
||||||
|
boolean_t hardforce = B_FALSE;
|
||||||
int c;
|
int c;
|
||||||
zpool_handle_t *zhp;
|
zpool_handle_t *zhp;
|
||||||
int ret;
|
int ret;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* check options */
|
/* check options */
|
||||||
while ((c = getopt(argc, argv, "f")) != -1) {
|
while ((c = getopt(argc, argv, "fF")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'f':
|
case 'f':
|
||||||
force = B_TRUE;
|
force = B_TRUE;
|
||||||
break;
|
break;
|
||||||
|
case 'F':
|
||||||
|
hardforce = B_TRUE;
|
||||||
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
|
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
|
||||||
optopt);
|
optopt);
|
||||||
@ -919,8 +923,12 @@ zpool_do_export(int argc, char **argv)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zpool_export(zhp, force) != 0)
|
if (hardforce) {
|
||||||
|
if (zpool_export_force(zhp) != 0)
|
||||||
|
ret = 1;
|
||||||
|
} else if (zpool_export(zhp, force) != 0) {
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
}
|
||||||
|
|
||||||
zpool_close(zhp);
|
zpool_close(zhp);
|
||||||
}
|
}
|
||||||
|
@ -3039,7 +3039,7 @@ ztest_spa_import_export(char *oldname, char *newname)
|
|||||||
/*
|
/*
|
||||||
* Export it.
|
* Export it.
|
||||||
*/
|
*/
|
||||||
error = spa_export(oldname, &config, B_FALSE);
|
error = spa_export(oldname, &config, B_FALSE, B_FALSE);
|
||||||
if (error)
|
if (error)
|
||||||
fatal(0, "spa_export('%s') = %d", oldname, error);
|
fatal(0, "spa_export('%s') = %d", oldname, error);
|
||||||
|
|
||||||
|
@ -289,6 +289,7 @@ extern int zpool_get_errlog(zpool_handle_t *, nvlist_t **);
|
|||||||
* Import and export functions
|
* Import and export functions
|
||||||
*/
|
*/
|
||||||
extern int zpool_export(zpool_handle_t *, boolean_t);
|
extern int zpool_export(zpool_handle_t *, boolean_t);
|
||||||
|
extern int zpool_export_force(zpool_handle_t *);
|
||||||
extern int zpool_import(libzfs_handle_t *, nvlist_t *, const char *,
|
extern int zpool_import(libzfs_handle_t *, nvlist_t *, const char *,
|
||||||
char *altroot);
|
char *altroot);
|
||||||
extern int zpool_import_props(libzfs_handle_t *, nvlist_t *, const char *,
|
extern int zpool_import_props(libzfs_handle_t *, nvlist_t *, const char *,
|
||||||
|
@ -1096,7 +1096,7 @@ zpool_add(zpool_handle_t *zhp, nvlist_t *nvroot)
|
|||||||
* mounted datasets in the pool.
|
* mounted datasets in the pool.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
zpool_export(zpool_handle_t *zhp, boolean_t force)
|
zpool_export_common(zpool_handle_t *zhp, boolean_t force, boolean_t hardforce)
|
||||||
{
|
{
|
||||||
zfs_cmd_t zc = { 0 };
|
zfs_cmd_t zc = { 0 };
|
||||||
char msg[1024];
|
char msg[1024];
|
||||||
@ -1109,6 +1109,7 @@ zpool_export(zpool_handle_t *zhp, boolean_t force)
|
|||||||
|
|
||||||
(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
|
(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
|
||||||
zc.zc_cookie = force;
|
zc.zc_cookie = force;
|
||||||
|
zc.zc_guid = hardforce;
|
||||||
|
|
||||||
if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_EXPORT, &zc) != 0) {
|
if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_EXPORT, &zc) != 0) {
|
||||||
switch (errno) {
|
switch (errno) {
|
||||||
@ -1129,6 +1130,18 @@ zpool_export(zpool_handle_t *zhp, boolean_t force)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
zpool_export(zpool_handle_t *zhp, boolean_t force)
|
||||||
|
{
|
||||||
|
return (zpool_export_common(zhp, force, B_FALSE));
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
zpool_export_force(zpool_handle_t *zhp)
|
||||||
|
{
|
||||||
|
return (zpool_export_common(zhp, B_TRUE, B_TRUE));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* zpool_import() is a contracted interface. Should be kept the same
|
* zpool_import() is a contracted interface. Should be kept the same
|
||||||
* if possible.
|
* if possible.
|
||||||
|
@ -355,14 +355,21 @@ write_type(void *arg1, void *arg2)
|
|||||||
for (i = 0, ep = tp->t_emem; ep != NULL; ep = ep->el_next)
|
for (i = 0, ep = tp->t_emem; ep != NULL; ep = ep->el_next)
|
||||||
i++; /* count up enum members */
|
i++; /* count up enum members */
|
||||||
|
|
||||||
|
if (i > CTF_MAX_VLEN) {
|
||||||
|
warning("enum %s has too many values: %d > %d\n",
|
||||||
|
tdesc_name(tp), i, CTF_MAX_VLEN);
|
||||||
|
i = CTF_MAX_VLEN;
|
||||||
|
}
|
||||||
|
|
||||||
ctt.ctt_info = CTF_TYPE_INFO(CTF_K_ENUM, isroot, i);
|
ctt.ctt_info = CTF_TYPE_INFO(CTF_K_ENUM, isroot, i);
|
||||||
write_sized_type_rec(b, &ctt, tp->t_size);
|
write_sized_type_rec(b, &ctt, tp->t_size);
|
||||||
|
|
||||||
for (ep = tp->t_emem; ep != NULL; ep = ep->el_next) {
|
for (ep = tp->t_emem; ep != NULL && i > 0; ep = ep->el_next) {
|
||||||
offset = strtab_insert(&b->ctb_strtab, ep->el_name);
|
offset = strtab_insert(&b->ctb_strtab, ep->el_name);
|
||||||
cte.cte_name = CTF_TYPE_NAME(CTF_STRTAB_0, offset);
|
cte.cte_name = CTF_TYPE_NAME(CTF_STRTAB_0, offset);
|
||||||
cte.cte_value = ep->el_number;
|
cte.cte_value = ep->el_number;
|
||||||
ctf_buf_write(b, &cte, sizeof (cte));
|
ctf_buf_write(b, &cte, sizeof (cte));
|
||||||
|
i--;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2491,8 +2491,7 @@ tn(int argc, char *argv[])
|
|||||||
env_export("USER");
|
env_export("USER");
|
||||||
}
|
}
|
||||||
(void) call(status, "status", "notmuch", 0);
|
(void) call(status, "status", "notmuch", 0);
|
||||||
if (setjmp(peerdied) == 0)
|
telnet(user);
|
||||||
telnet(user);
|
|
||||||
(void) NetClose(net);
|
(void) NetClose(net);
|
||||||
ExitString("Connection closed by foreign host.\n",1);
|
ExitString("Connection closed by foreign host.\n",1);
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
|
@ -233,7 +233,6 @@ extern void
|
|||||||
SetNetTrace(char *); /* Function to change where debugging goes */
|
SetNetTrace(char *); /* Function to change where debugging goes */
|
||||||
|
|
||||||
extern jmp_buf
|
extern jmp_buf
|
||||||
peerdied,
|
|
||||||
toplevel; /* For error conditions. */
|
toplevel; /* For error conditions. */
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
|
@ -158,7 +158,7 @@ netflush(void)
|
|||||||
perror(hostname);
|
perror(hostname);
|
||||||
(void)NetClose(net);
|
(void)NetClose(net);
|
||||||
ring_clear_mark(&netoring);
|
ring_clear_mark(&netoring);
|
||||||
longjmp(peerdied, -1);
|
ExitString("Connection closed by foreign host.\n", 1);
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
n = 0;
|
n = 0;
|
||||||
|
@ -808,14 +808,6 @@ NetNonblockingIO(int fd, int onoff)
|
|||||||
* Various signal handling routines.
|
* Various signal handling routines.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static SIG_FUNC_RET
|
|
||||||
deadpeer(int sig __unused)
|
|
||||||
{
|
|
||||||
setcommandmode();
|
|
||||||
longjmp(peerdied, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
SIG_FUNC_RET
|
SIG_FUNC_RET
|
||||||
intr(int sig __unused)
|
intr(int sig __unused)
|
||||||
@ -884,7 +876,7 @@ sys_telnet_init(void)
|
|||||||
{
|
{
|
||||||
(void) signal(SIGINT, intr);
|
(void) signal(SIGINT, intr);
|
||||||
(void) signal(SIGQUIT, intr2);
|
(void) signal(SIGQUIT, intr2);
|
||||||
(void) signal(SIGPIPE, deadpeer);
|
(void) signal(SIGPIPE, SIG_IGN);
|
||||||
#ifdef SIGWINCH
|
#ifdef SIGWINCH
|
||||||
(void) signal(SIGWINCH, sendwin);
|
(void) signal(SIGWINCH, sendwin);
|
||||||
#endif
|
#endif
|
||||||
|
@ -146,7 +146,6 @@ unsigned char telopt_environ = TELOPT_NEW_ENVIRON;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
jmp_buf toplevel;
|
jmp_buf toplevel;
|
||||||
jmp_buf peerdied;
|
|
||||||
|
|
||||||
int flushline;
|
int flushline;
|
||||||
int linemode;
|
int linemode;
|
||||||
|
@ -111,7 +111,8 @@ init_terminal(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send as much data as possible to the terminal.
|
* Send as much data as possible to the terminal, else exits if
|
||||||
|
* it encounters a permanent failure when writing to the tty.
|
||||||
*
|
*
|
||||||
* Return value:
|
* Return value:
|
||||||
* -1: No useful work done, data waiting to go out.
|
* -1: No useful work done, data waiting to go out.
|
||||||
@ -152,8 +153,19 @@ ttyflush(int drop)
|
|||||||
}
|
}
|
||||||
ring_consumed(&ttyoring, n);
|
ring_consumed(&ttyoring, n);
|
||||||
}
|
}
|
||||||
if (n < 0)
|
if (n < 0) {
|
||||||
|
if (errno == EAGAIN || errno == EINTR) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
ring_consumed(&ttyoring, ring_full_count(&ttyoring));
|
||||||
|
setconnmode(0);
|
||||||
|
setcommandmode();
|
||||||
|
NetClose(net);
|
||||||
|
fprintf(stderr, "Write error on local output.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
if (n == n0) {
|
if (n == n0) {
|
||||||
if (n0)
|
if (n0)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -34,7 +34,7 @@ static const char privatehid[] = "@(#)private.h 8.6";
|
|||||||
#endif /* !defined NOID */
|
#endif /* !defined NOID */
|
||||||
#endif /* !defined lint */
|
#endif /* !defined lint */
|
||||||
|
|
||||||
#define GRANDPARENTED "Local time zone must be set--see zic manual page"
|
#define GRANDPARENTED "Local time zone must be set--use tzsetup"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Defaults for preprocessor symbols.
|
** Defaults for preprocessor symbols.
|
||||||
|
@ -1,4 +1,120 @@
|
|||||||
20100307
|
20100410
|
||||||
|
- (dtucker) [configure.ac] Put the check for the existence of getaddrinfo
|
||||||
|
back so we disable the IPv6 tests if we don't have it.
|
||||||
|
|
||||||
|
20100409
|
||||||
|
- (dtucker) [contrib/cygwin/Makefile] Don't overwrite files with the wrong
|
||||||
|
ones. Based on a patch from Roumen Petrov.
|
||||||
|
- (dtucker) [configure.ac] Bug #1744: use pkg-config for libedit flags if we
|
||||||
|
have it and the path is not provided to --with-libedit. Based on a patch
|
||||||
|
from Iain Morgan.
|
||||||
|
- (dtucker) [configure.ac defines.h loginrec.c logintest.c] Bug #1732: enable
|
||||||
|
utmpx support on FreeBSD where possible. Patch from Ed Schouten, ok djm@
|
||||||
|
|
||||||
|
20100326
|
||||||
|
- (djm) [openbsd-compat/bsd-arc4random.c] Fix preprocessor detection
|
||||||
|
for arc4random_buf() and arc4random_uniform(); from Josh Gilkerson
|
||||||
|
- (dtucker) [configure.ac] Bug #1741: Add section for Haiku, patch originally
|
||||||
|
by Ingo Weinhold via Scott McCreary, ok djm@
|
||||||
|
- (djm) OpenBSD CVS Sync
|
||||||
|
- djm@cvs.openbsd.org 2010/03/25 23:38:28
|
||||||
|
[servconf.c]
|
||||||
|
from portable: getcwd(NULL, 0) doesn't work on all platforms, so
|
||||||
|
use a stack buffer; ok dtucker@
|
||||||
|
- djm@cvs.openbsd.org 2010/03/26 00:26:58
|
||||||
|
[ssh.1]
|
||||||
|
mention that -S none disables connection sharing; from Colin Watson
|
||||||
|
- (djm) [session.c] Allow ChrootDirectory to work on SELinux platforms -
|
||||||
|
set up SELinux execution context before chroot() call. From Russell
|
||||||
|
Coker via Colin watson; bz#1726 ok dtucker@
|
||||||
|
- (djm) [channels.c] Check for EPFNOSUPPORT as a socket() errno; bz#1721
|
||||||
|
ok dtucker@
|
||||||
|
- (dtucker) Bug #1725: explicitly link libX11 into gnome-ssh-askpass2 using
|
||||||
|
pkg-config, patch from Colin Watson. Needed for newer linkers (ie gold).
|
||||||
|
- (djm) [contrib/ssh-copy-id] Don't blow up when the agent has no keys;
|
||||||
|
bz#1723 patch from Adeodato Simóvia Colin Watson; ok dtucker@
|
||||||
|
- (dtucker) OpenBSD CVS Sync
|
||||||
|
- dtucker@cvs.openbsd.org 2010/03/26 01:06:13
|
||||||
|
[ssh_config.5]
|
||||||
|
Reformat default value of PreferredAuthentications entry (current
|
||||||
|
formatting implies ", " is acceptable as a separator, which it's not.
|
||||||
|
ok djm@
|
||||||
|
|
||||||
|
20100324
|
||||||
|
- (dtucker) [contrib/cygwin/ssh-host-config] Mount the Windows directory
|
||||||
|
containing the services file explicitely case-insensitive. This allows to
|
||||||
|
tweak the Windows services file reliably. Patch from vinschen at redhat.
|
||||||
|
|
||||||
|
20100321
|
||||||
|
- (djm) OpenBSD CVS Sync
|
||||||
|
- jmc@cvs.openbsd.org 2010/03/08 09:41:27
|
||||||
|
[ssh-keygen.1]
|
||||||
|
sort the list of constraints (to -O); ok djm
|
||||||
|
- jmc@cvs.openbsd.org 2010/03/10 07:40:35
|
||||||
|
[ssh-keygen.1]
|
||||||
|
typos; from Ross Richardson
|
||||||
|
closes prs 6334 and 6335
|
||||||
|
- djm@cvs.openbsd.org 2010/03/10 23:27:17
|
||||||
|
[auth2-pubkey.c]
|
||||||
|
correct certificate logging and make it more consistent between
|
||||||
|
authorized_keys and TrustedCAKeys; ok markus@
|
||||||
|
- djm@cvs.openbsd.org 2010/03/12 01:06:25
|
||||||
|
[servconf.c]
|
||||||
|
unbreak AuthorizedKeys option with a $HOME-relative path; reported by
|
||||||
|
vinschen AT redhat.com, ok dtucker@
|
||||||
|
- markus@cvs.openbsd.org 2010/03/12 11:37:40
|
||||||
|
[servconf.c]
|
||||||
|
do not prepend AuthorizedKeysFile with getcwd(), unbreaks relative paths
|
||||||
|
free() (not xfree()) the buffer returned by getcwd()
|
||||||
|
- djm@cvs.openbsd.org 2010/03/13 21:10:38
|
||||||
|
[clientloop.c]
|
||||||
|
protocol conformance fix: send language tag when disconnecting normally;
|
||||||
|
spotted by 1.41421 AT gmail.com, ok markus@ deraadt@
|
||||||
|
- djm@cvs.openbsd.org 2010/03/13 21:45:46
|
||||||
|
[ssh-keygen.1]
|
||||||
|
Certificates are named *-cert.pub, not *_cert.pub; committing a diff
|
||||||
|
from stevesk@ ok me
|
||||||
|
- jmc@cvs.openbsd.org 2010/03/13 23:38:13
|
||||||
|
[ssh-keygen.1]
|
||||||
|
fix a formatting error (args need quoted); noted by stevesk
|
||||||
|
- stevesk@cvs.openbsd.org 2010/03/15 19:40:02
|
||||||
|
[key.c key.h ssh-keygen.c]
|
||||||
|
also print certificate type (user or host) for ssh-keygen -L
|
||||||
|
ok djm kettenis
|
||||||
|
- stevesk@cvs.openbsd.org 2010/03/16 15:46:52
|
||||||
|
[auth-options.c]
|
||||||
|
spelling in error message. ok djm kettenis
|
||||||
|
- djm@cvs.openbsd.org 2010/03/16 16:36:49
|
||||||
|
[version.h]
|
||||||
|
crank version to openssh-5.5 since we have a few fixes since 5.4;
|
||||||
|
requested deraadt@ kettenis@
|
||||||
|
- (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec]
|
||||||
|
[contrib/suse/openssh.spec] Crank version numbers
|
||||||
|
|
||||||
|
20100314
|
||||||
|
- (djm) [ssh-pkcs11-helper.c] Move #ifdef to after #defines to fix
|
||||||
|
compilation failure when !HAVE_DLOPEN. Reported by felix-mindrot
|
||||||
|
AT fefe.de
|
||||||
|
- (djm) [Makefile.in] Respecify -lssh after -lopenbsd-compat for
|
||||||
|
ssh-pkcs11-helper to repair static builds (we do the same for
|
||||||
|
ssh-keyscan). Reported by felix-mindrot AT fefe.de
|
||||||
|
|
||||||
|
20100312
|
||||||
|
- (tim) [Makefile.in] Now that scard is gone, no need to make $(datadir)
|
||||||
|
- (tim) [Makefile.in] Add missing $(EXEEXT) to install targets.
|
||||||
|
Patch from Corinna Vinschen.
|
||||||
|
- (tim) [contrib/cygwin/Makefile] Fix list of documentation files to install
|
||||||
|
on a Cygwin installation. Patch from Corinna Vinschen.
|
||||||
|
|
||||||
|
20100311
|
||||||
|
- (tim) [contrib/suse/openssh.spec] crank version number here too.
|
||||||
|
report by imorgan AT nas.nasa.gov
|
||||||
|
|
||||||
|
20100309
|
||||||
|
- (dtucker) [configure.ac] Use a proper AC_CHECK_DECL for BROKEN_GETADDRINFO
|
||||||
|
so setting it in CFLAGS correctly skips IPv6 tests.
|
||||||
|
|
||||||
|
20100428
|
||||||
- (djm) OpenBSD CVS Sync
|
- (djm) OpenBSD CVS Sync
|
||||||
- djm@cvs.openbsd.org 2010/03/07 22:16:01
|
- djm@cvs.openbsd.org 2010/03/07 22:16:01
|
||||||
[ssh-keygen.c]
|
[ssh-keygen.c]
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
See http://www.openssh.com/txt/release-5.4 for the release notes.
|
See http://www.openssh.com/txt/release-5.5 for the release notes.
|
||||||
|
|
||||||
- A Japanese translation of this document and of the OpenSSH FAQ is
|
- A Japanese translation of this document and of the OpenSSH FAQ is
|
||||||
- available at http://www.unixuser.org/~haruyama/security/openssh/index.html
|
- available at http://www.unixuser.org/~haruyama/security/openssh/index.html
|
||||||
@ -62,4 +62,4 @@ References -
|
|||||||
[6] http://www.openbsd.org/cgi-bin/man.cgi?query=style&sektion=9
|
[6] http://www.openbsd.org/cgi-bin/man.cgi?query=style&sektion=9
|
||||||
[7] http://www.openssh.com/faq.html
|
[7] http://www.openssh.com/faq.html
|
||||||
|
|
||||||
$Id: README,v 1.72 2010/03/07 22:41:02 djm Exp $
|
$Id: README,v 1.73 2010/03/21 19:11:55 djm Exp $
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: auth-options.c,v 1.48 2010/03/07 11:57:13 dtucker Exp $ */
|
/* $OpenBSD: auth-options.c,v 1.49 2010/03/16 15:46:52 stevesk Exp $ */
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
@ -434,7 +434,7 @@ auth_cert_constraints(Buffer *c_orig, struct passwd *pw)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (strlen(command) != clen) {
|
if (strlen(command) != clen) {
|
||||||
error("force-command constrain contains \\0");
|
error("force-command constraint contains \\0");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (cert_forced_command != NULL) {
|
if (cert_forced_command != NULL) {
|
||||||
@ -454,7 +454,7 @@ auth_cert_constraints(Buffer *c_orig, struct passwd *pw)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (strlen(allowed) != clen) {
|
if (strlen(allowed) != clen) {
|
||||||
error("source-address constrain contains \\0");
|
error("source-address constraint contains \\0");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (cert_source_address_done++) {
|
if (cert_source_address_done++) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: auth2-pubkey.c,v 1.21 2010/03/04 10:36:03 djm Exp $ */
|
/* $OpenBSD: auth2-pubkey.c,v 1.22 2010/03/10 23:27:17 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||||
*
|
*
|
||||||
@ -240,22 +240,26 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
|
|||||||
continue;
|
continue;
|
||||||
if (!key_equal(found, key->cert->signature_key))
|
if (!key_equal(found, key->cert->signature_key))
|
||||||
continue;
|
continue;
|
||||||
debug("matching CA found: file %s, line %lu",
|
|
||||||
file, linenum);
|
|
||||||
fp = key_fingerprint(found, SSH_FP_MD5,
|
fp = key_fingerprint(found, SSH_FP_MD5,
|
||||||
SSH_FP_HEX);
|
SSH_FP_HEX);
|
||||||
verbose("Found matching %s CA: %s",
|
debug("matching CA found: file %s, line %lu, %s %s",
|
||||||
key_type(found), fp);
|
file, linenum, key_type(found), fp);
|
||||||
xfree(fp);
|
|
||||||
if (key_cert_check_authority(key, 0, 0, pw->pw_name,
|
if (key_cert_check_authority(key, 0, 0, pw->pw_name,
|
||||||
&reason) != 0) {
|
&reason) != 0) {
|
||||||
|
xfree(fp);
|
||||||
error("%s", reason);
|
error("%s", reason);
|
||||||
auth_debug_add("%s", reason);
|
auth_debug_add("%s", reason);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (auth_cert_constraints(&key->cert->constraints,
|
if (auth_cert_constraints(&key->cert->constraints,
|
||||||
pw) != 0)
|
pw) != 0) {
|
||||||
|
xfree(fp);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
verbose("Accepted certificate ID \"%s\" "
|
||||||
|
"signed by %s CA %s via %s", key->cert->key_id,
|
||||||
|
key_type(found), fp, file);
|
||||||
|
xfree(fp);
|
||||||
found_key = 1;
|
found_key = 1;
|
||||||
break;
|
break;
|
||||||
} else if (!key_is_cert_authority && key_equal(found, key)) {
|
} else if (!key_is_cert_authority && key_equal(found, key)) {
|
||||||
@ -281,15 +285,15 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
|
|||||||
static int
|
static int
|
||||||
user_cert_trusted_ca(struct passwd *pw, Key *key)
|
user_cert_trusted_ca(struct passwd *pw, Key *key)
|
||||||
{
|
{
|
||||||
char *key_fp, *ca_fp;
|
char *ca_fp;
|
||||||
const char *reason;
|
const char *reason;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL)
|
if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
|
ca_fp = key_fingerprint(key->cert->signature_key,
|
||||||
ca_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
|
SSH_FP_MD5, SSH_FP_HEX);
|
||||||
|
|
||||||
if (key_in_file(key->cert->signature_key,
|
if (key_in_file(key->cert->signature_key,
|
||||||
options.trusted_user_ca_keys, 1) != 1) {
|
options.trusted_user_ca_keys, 1) != 1) {
|
||||||
@ -306,13 +310,12 @@ user_cert_trusted_ca(struct passwd *pw, Key *key)
|
|||||||
if (auth_cert_constraints(&key->cert->constraints, pw) != 0)
|
if (auth_cert_constraints(&key->cert->constraints, pw) != 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
verbose("%s certificate %s allowed by trusted %s key %s",
|
verbose("Accepted certificate ID \"%s\" signed by %s CA %s via %s",
|
||||||
key_type(key), key_fp, key_type(key->cert->signature_key), ca_fp);
|
key->cert->key_id, key_type(key->cert->signature_key), ca_fp,
|
||||||
|
options.trusted_user_ca_keys);
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (key_fp != NULL)
|
|
||||||
xfree(key_fp);
|
|
||||||
if (ca_fp != NULL)
|
if (ca_fp != NULL)
|
||||||
xfree(ca_fp);
|
xfree(ca_fp);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -3252,7 +3252,11 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
|
|||||||
sock = socket(ai->ai_family, ai->ai_socktype,
|
sock = socket(ai->ai_family, ai->ai_socktype,
|
||||||
ai->ai_protocol);
|
ai->ai_protocol);
|
||||||
if (sock < 0) {
|
if (sock < 0) {
|
||||||
if ((errno != EINVAL) && (errno != EAFNOSUPPORT)) {
|
if ((errno != EINVAL) && (errno != EAFNOSUPPORT)
|
||||||
|
#ifdef EPFNOSUPPORT
|
||||||
|
&& (errno != EPFNOSUPPORT)
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
error("socket: %.100s", strerror(errno));
|
error("socket: %.100s", strerror(errno));
|
||||||
freeaddrinfo(aitop);
|
freeaddrinfo(aitop);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: clientloop.c,v 1.218 2010/01/28 00:21:18 djm Exp $ */
|
/* $OpenBSD: clientloop.c,v 1.219 2010/03/13 21:10:38 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
@ -1484,6 +1484,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
|
|||||||
packet_start(SSH2_MSG_DISCONNECT);
|
packet_start(SSH2_MSG_DISCONNECT);
|
||||||
packet_put_int(SSH2_DISCONNECT_BY_APPLICATION);
|
packet_put_int(SSH2_DISCONNECT_BY_APPLICATION);
|
||||||
packet_put_cstring("disconnected by user");
|
packet_put_cstring("disconnected by user");
|
||||||
|
packet_put_cstring(""); /* language tag */
|
||||||
packet_send();
|
packet_send();
|
||||||
packet_write_wait();
|
packet_write_wait();
|
||||||
}
|
}
|
||||||
|
@ -124,7 +124,7 @@
|
|||||||
#define DISABLE_WTMPX 1
|
#define DISABLE_WTMPX 1
|
||||||
|
|
||||||
/* Enable for PKCS#11 support */
|
/* Enable for PKCS#11 support */
|
||||||
#define ENABLE_PKCS11
|
#define ENABLE_PKCS11 /**/
|
||||||
|
|
||||||
/* Builtin PRNG command timeout */
|
/* Builtin PRNG command timeout */
|
||||||
#define ENTROPY_TIMEOUT_MSEC 200
|
#define ENTROPY_TIMEOUT_MSEC 200
|
||||||
@ -456,6 +456,9 @@
|
|||||||
/* Define to 1 if you have the `getutxline' function. */
|
/* Define to 1 if you have the `getutxline' function. */
|
||||||
#define HAVE_GETUTXLINE 1
|
#define HAVE_GETUTXLINE 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `getutxuser' function. */
|
||||||
|
#define HAVE_GETUTXUSER 1
|
||||||
|
|
||||||
/* Define to 1 if you have the `get_default_context_with_level' function. */
|
/* Define to 1 if you have the `get_default_context_with_level' function. */
|
||||||
/* #undef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL */
|
/* #undef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL */
|
||||||
|
|
||||||
@ -552,6 +555,9 @@
|
|||||||
/* Define if system has libiaf that supports set_id */
|
/* Define if system has libiaf that supports set_id */
|
||||||
/* #undef HAVE_LIBIAF */
|
/* #undef HAVE_LIBIAF */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `network' library (-lnetwork). */
|
||||||
|
/* #undef HAVE_LIBNETWORK */
|
||||||
|
|
||||||
/* Define to 1 if you have the `nsl' library (-lnsl). */
|
/* Define to 1 if you have the `nsl' library (-lnsl). */
|
||||||
/* #undef HAVE_LIBNSL */
|
/* #undef HAVE_LIBNSL */
|
||||||
|
|
||||||
@ -805,6 +811,9 @@
|
|||||||
/* Define to 1 if you have the `setutent' function. */
|
/* Define to 1 if you have the `setutent' function. */
|
||||||
/* #undef HAVE_SETUTENT */
|
/* #undef HAVE_SETUTENT */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `setutxdb' function. */
|
||||||
|
#define HAVE_SETUTXDB 1
|
||||||
|
|
||||||
/* Define to 1 if you have the `setutxent' function. */
|
/* Define to 1 if you have the `setutxent' function. */
|
||||||
#define HAVE_SETUTXENT 1
|
#define HAVE_SETUTXENT 1
|
||||||
|
|
||||||
@ -1416,8 +1425,8 @@
|
|||||||
/* Define if you want SELinux support. */
|
/* Define if you want SELinux support. */
|
||||||
/* #undef WITH_SELINUX */
|
/* #undef WITH_SELINUX */
|
||||||
|
|
||||||
/* Define to 1 if your processor stores words with the most significant byte
|
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||||
first (like Motorola and SPARC, unlike Intel and VAX). */
|
significant byte first (like Motorola and SPARC, unlike Intel and VAX). */
|
||||||
#if defined __BIG_ENDIAN__
|
#if defined __BIG_ENDIAN__
|
||||||
# define WORDS_BIGENDIAN 1
|
# define WORDS_BIGENDIAN 1
|
||||||
#elif ! defined __LITTLE_ENDIAN__
|
#elif ! defined __LITTLE_ENDIAN__
|
||||||
|
@ -80,9 +80,6 @@
|
|||||||
/* Define if you want to specify the path to your lastlog file */
|
/* Define if you want to specify the path to your lastlog file */
|
||||||
#undef CONF_LASTLOG_FILE
|
#undef CONF_LASTLOG_FILE
|
||||||
|
|
||||||
/* Define if you want to specify the path to your utmpx file */
|
|
||||||
#undef CONF_UTMPX_FILE
|
|
||||||
|
|
||||||
/* Define if you want to specify the path to your utmp file */
|
/* Define if you want to specify the path to your utmp file */
|
||||||
#undef CONF_UTMP_FILE
|
#undef CONF_UTMP_FILE
|
||||||
|
|
||||||
@ -455,6 +452,9 @@
|
|||||||
/* Define to 1 if you have the `getutxline' function. */
|
/* Define to 1 if you have the `getutxline' function. */
|
||||||
#undef HAVE_GETUTXLINE
|
#undef HAVE_GETUTXLINE
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `getutxuser' function. */
|
||||||
|
#undef HAVE_GETUTXUSER
|
||||||
|
|
||||||
/* Define to 1 if you have the `get_default_context_with_level' function. */
|
/* Define to 1 if you have the `get_default_context_with_level' function. */
|
||||||
#undef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
|
#undef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
|
||||||
|
|
||||||
@ -551,6 +551,9 @@
|
|||||||
/* Define if system has libiaf that supports set_id */
|
/* Define if system has libiaf that supports set_id */
|
||||||
#undef HAVE_LIBIAF
|
#undef HAVE_LIBIAF
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `network' library (-lnetwork). */
|
||||||
|
#undef HAVE_LIBNETWORK
|
||||||
|
|
||||||
/* Define to 1 if you have the `nsl' library (-lnsl). */
|
/* Define to 1 if you have the `nsl' library (-lnsl). */
|
||||||
#undef HAVE_LIBNSL
|
#undef HAVE_LIBNSL
|
||||||
|
|
||||||
@ -804,6 +807,9 @@
|
|||||||
/* Define to 1 if you have the `setutent' function. */
|
/* Define to 1 if you have the `setutent' function. */
|
||||||
#undef HAVE_SETUTENT
|
#undef HAVE_SETUTENT
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `setutxdb' function. */
|
||||||
|
#undef HAVE_SETUTXDB
|
||||||
|
|
||||||
/* Define to 1 if you have the `setutxent' function. */
|
/* Define to 1 if you have the `setutxent' function. */
|
||||||
#undef HAVE_SETUTXENT
|
#undef HAVE_SETUTXENT
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#ifndef _DEFINES_H
|
#ifndef _DEFINES_H
|
||||||
#define _DEFINES_H
|
#define _DEFINES_H
|
||||||
|
|
||||||
/* $Id: defines.h,v 1.159 2010/01/13 23:44:34 tim Exp $ */
|
/* $Id: defines.h,v 1.160 2010/04/09 08:13:27 dtucker Exp $ */
|
||||||
|
|
||||||
|
|
||||||
/* Constants */
|
/* Constants */
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: key.c,v 1.85 2010/03/04 01:44:57 djm Exp $ */
|
/* $OpenBSD: key.c,v 1.86 2010/03/15 19:40:02 stevesk Exp $ */
|
||||||
/*
|
/*
|
||||||
* read_bignum():
|
* read_bignum():
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
@ -801,6 +801,19 @@ key_type(const Key *k)
|
|||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
key_cert_type(const Key *k)
|
||||||
|
{
|
||||||
|
switch (k->cert->type) {
|
||||||
|
case SSH2_CERT_TYPE_USER:
|
||||||
|
return "user";
|
||||||
|
case SSH2_CERT_TYPE_HOST:
|
||||||
|
return "host";
|
||||||
|
default:
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
key_ssh_name(const Key *k)
|
key_ssh_name(const Key *k)
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: key.h,v 1.28 2010/02/26 20:29:54 djm Exp $ */
|
/* $OpenBSD: key.h,v 1.29 2010/03/15 19:40:02 stevesk Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||||
@ -82,6 +82,7 @@ int key_equal(const Key *, const Key *);
|
|||||||
char *key_fingerprint(Key *, enum fp_type, enum fp_rep);
|
char *key_fingerprint(Key *, enum fp_type, enum fp_rep);
|
||||||
u_char *key_fingerprint_raw(Key *, enum fp_type, u_int *);
|
u_char *key_fingerprint_raw(Key *, enum fp_type, u_int *);
|
||||||
const char *key_type(const Key *);
|
const char *key_type(const Key *);
|
||||||
|
const char *key_cert_type(const Key *);
|
||||||
int key_write(const Key *, FILE *);
|
int key_write(const Key *, FILE *);
|
||||||
int key_read(Key *, char **);
|
int key_read(Key *, char **);
|
||||||
u_int key_size(const Key *);
|
u_int key_size(const Key *);
|
||||||
|
@ -510,6 +510,10 @@ getlast_entry(struct logininfo *li)
|
|||||||
#ifdef USE_LASTLOG
|
#ifdef USE_LASTLOG
|
||||||
return(lastlog_get_entry(li));
|
return(lastlog_get_entry(li));
|
||||||
#else /* !USE_LASTLOG */
|
#else /* !USE_LASTLOG */
|
||||||
|
#if defined(USE_UTMPX) && defined(HAVE_SETUTXDB) && \
|
||||||
|
defined(UTXDB_LASTLOGIN) && defined(HAVE_GETUTXUSER)
|
||||||
|
return (utmpx_get_entry(li));
|
||||||
|
#endif
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
return (utmpx_get_entry(li));
|
return (utmpx_get_entry(li));
|
||||||
@ -1614,7 +1618,8 @@ lastlog_get_entry(struct logininfo *li)
|
|||||||
#endif /* HAVE_GETLASTLOGXBYNAME */
|
#endif /* HAVE_GETLASTLOGXBYNAME */
|
||||||
#endif /* USE_LASTLOG */
|
#endif /* USE_LASTLOG */
|
||||||
|
|
||||||
#if 1
|
#if defined(USE_UTMPX) && defined(HAVE_SETUTXDB) && \
|
||||||
|
defined(UTXDB_LASTLOGIN) && defined(HAVE_GETUTXUSER)
|
||||||
int
|
int
|
||||||
utmpx_get_entry(struct logininfo *li)
|
utmpx_get_entry(struct logininfo *li)
|
||||||
{
|
{
|
||||||
@ -1637,7 +1642,7 @@ utmpx_get_entry(struct logininfo *li)
|
|||||||
endutxent();
|
endutxent();
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* USE_UTMPX && HAVE_SETUTXDB && UTXDB_LASTLOGIN && HAVE_GETUTXUSER */
|
||||||
|
|
||||||
#ifdef USE_BTMP
|
#ifdef USE_BTMP
|
||||||
/*
|
/*
|
||||||
|
@ -264,7 +264,7 @@ showOptions(void)
|
|||||||
printf("\tUSE_UTMP (UTMP_FILE=%s)\n", UTMP_FILE);
|
printf("\tUSE_UTMP (UTMP_FILE=%s)\n", UTMP_FILE);
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_UTMPX
|
#ifdef USE_UTMPX
|
||||||
printf("\tUSE_UTMPX (UTMPX_FILE=%s)\n", UTMPX_FILE);
|
printf("\tUSE_UTMPX\n");
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_WTMP
|
#ifdef USE_WTMP
|
||||||
printf("\tUSE_WTMP (WTMP_FILE=%s)\n", WTMP_FILE);
|
printf("\tUSE_WTMP (WTMP_FILE=%s)\n", WTMP_FILE);
|
||||||
|
@ -84,7 +84,7 @@ arc4random_stir(void)
|
|||||||
}
|
}
|
||||||
#endif /* !HAVE_ARC4RANDOM */
|
#endif /* !HAVE_ARC4RANDOM */
|
||||||
|
|
||||||
#ifndef ARC4RANDOM_BUF
|
#ifndef HAVE_ARC4RANDOM_BUF
|
||||||
void
|
void
|
||||||
arc4random_buf(void *_buf, size_t n)
|
arc4random_buf(void *_buf, size_t n)
|
||||||
{
|
{
|
||||||
@ -102,7 +102,7 @@ arc4random_buf(void *_buf, size_t n)
|
|||||||
}
|
}
|
||||||
#endif /* !HAVE_ARC4RANDOM_BUF */
|
#endif /* !HAVE_ARC4RANDOM_BUF */
|
||||||
|
|
||||||
#ifndef ARC4RANDOM_UNIFORM
|
#ifndef HAVE_ARC4RANDOM_UNIFORM
|
||||||
/*
|
/*
|
||||||
* Calculate a uniformly distributed random number less than upper_bound
|
* Calculate a uniformly distributed random number less than upper_bound
|
||||||
* avoiding "modulo bias".
|
* avoiding "modulo bias".
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: servconf.c,v 1.204 2010/03/04 10:36:03 djm Exp $ */
|
/* $OpenBSD: servconf.c,v 1.207 2010/03/25 23:38:28 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -474,15 +474,14 @@ parse_token(const char *cp, const char *filename,
|
|||||||
char *
|
char *
|
||||||
derelativise_path(const char *path)
|
derelativise_path(const char *path)
|
||||||
{
|
{
|
||||||
char *expanded, *ret, *cwd;
|
char *expanded, *ret, cwd[MAXPATHLEN];
|
||||||
|
|
||||||
expanded = tilde_expand_filename(path, getuid());
|
expanded = tilde_expand_filename(path, getuid());
|
||||||
if (*expanded == '/')
|
if (*expanded == '/')
|
||||||
return expanded;
|
return expanded;
|
||||||
if ((cwd = getcwd(NULL, 0)) == NULL)
|
if (getcwd(cwd, sizeof(cwd)) == NULL)
|
||||||
fatal("%s: getcwd: %s", __func__, strerror(errno));
|
fatal("%s: getcwd: %s", __func__, strerror(errno));
|
||||||
xasprintf(&ret, "%s/%s", cwd, expanded);
|
xasprintf(&ret, "%s/%s", cwd, expanded);
|
||||||
xfree(cwd);
|
|
||||||
xfree(expanded);
|
xfree(expanded);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1227,7 +1226,17 @@ process_server_config_line(ServerOptions *options, char *line,
|
|||||||
charptr = (opcode == sAuthorizedKeysFile) ?
|
charptr = (opcode == sAuthorizedKeysFile) ?
|
||||||
&options->authorized_keys_file :
|
&options->authorized_keys_file :
|
||||||
&options->authorized_keys_file2;
|
&options->authorized_keys_file2;
|
||||||
goto parse_filename;
|
arg = strdelim(&cp);
|
||||||
|
if (!arg || *arg == '\0')
|
||||||
|
fatal("%s line %d: missing file name.",
|
||||||
|
filename, linenum);
|
||||||
|
if (*activep && *charptr == NULL) {
|
||||||
|
*charptr = tilde_expand_filename(arg, getuid());
|
||||||
|
/* increase optional counter */
|
||||||
|
if (intptr != NULL)
|
||||||
|
*intptr = *intptr + 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case sClientAliveInterval:
|
case sClientAliveInterval:
|
||||||
intptr = &options->client_alive_interval;
|
intptr = &options->client_alive_interval;
|
||||||
|
@ -1581,6 +1581,10 @@ do_setusercontext(struct passwd *pw)
|
|||||||
}
|
}
|
||||||
#endif /* HAVE_SETPCRED */
|
#endif /* HAVE_SETPCRED */
|
||||||
|
|
||||||
|
#ifdef WITH_SELINUX
|
||||||
|
ssh_selinux_setup_exec_context(pw->pw_name);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (options.chroot_directory != NULL &&
|
if (options.chroot_directory != NULL &&
|
||||||
strcasecmp(options.chroot_directory, "none") != 0) {
|
strcasecmp(options.chroot_directory, "none") != 0) {
|
||||||
tmp = tilde_expand_filename(options.chroot_directory,
|
tmp = tilde_expand_filename(options.chroot_directory,
|
||||||
@ -1605,10 +1609,6 @@ do_setusercontext(struct passwd *pw)
|
|||||||
|
|
||||||
if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
|
if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
|
||||||
fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
|
fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
|
||||||
|
|
||||||
#ifdef WITH_SELINUX
|
|
||||||
ssh_selinux_setup_exec_context(pw->pw_name);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
.\" $OpenBSD: ssh-keygen.1,v 1.88 2010/03/08 00:28:55 djm Exp $
|
.\" $OpenBSD: ssh-keygen.1,v 1.92 2010/03/13 23:38:13 jmc Exp $
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.\" -*- nroff -*-
|
.\" -*- nroff -*-
|
||||||
@ -38,7 +38,7 @@
|
|||||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
.\"
|
.\"
|
||||||
.Dd March 8 2010
|
.Dd March 13 2010
|
||||||
.Dt SSH-KEYGEN 1
|
.Dt SSH-KEYGEN 1
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -308,8 +308,15 @@ Please see the
|
|||||||
section for details.
|
section for details.
|
||||||
The constraints that are valid for user certificates are:
|
The constraints that are valid for user certificates are:
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width Ds
|
||||||
.It Ic no-x11-forwarding
|
.It Ic clear
|
||||||
Disable X11 forwarding (permitted by default).
|
Clear all enabled permissions.
|
||||||
|
This is useful for clearing the default set of permissions so permissions may
|
||||||
|
be added individually.
|
||||||
|
.It Ic force-command Ns = Ns Ar command
|
||||||
|
Forces the execution of
|
||||||
|
.Ar command
|
||||||
|
instead of any shell or command specified by the user when
|
||||||
|
the certificate is used for authentication.
|
||||||
.It Ic no-agent-forwarding
|
.It Ic no-agent-forwarding
|
||||||
Disable
|
Disable
|
||||||
.Xr ssh-agent 1
|
.Xr ssh-agent 1
|
||||||
@ -324,12 +331,8 @@ Disable execution of
|
|||||||
by
|
by
|
||||||
.Xr sshd 8
|
.Xr sshd 8
|
||||||
(permitted by default).
|
(permitted by default).
|
||||||
.It Ic clear
|
.It Ic no-x11-forwarding
|
||||||
Clear all enabled permissions.
|
Disable X11 forwarding (permitted by default).
|
||||||
This is useful for clearing the default set of permissions so permissions may
|
|
||||||
be added individually.
|
|
||||||
.It Ic permit-x11-forwarding
|
|
||||||
Allows X11 forwarding.
|
|
||||||
.It Ic permit-agent-forwarding
|
.It Ic permit-agent-forwarding
|
||||||
Allows
|
Allows
|
||||||
.Xr ssh-agent 1
|
.Xr ssh-agent 1
|
||||||
@ -343,14 +346,10 @@ Allows execution of
|
|||||||
.Pa ~/.ssh/rc
|
.Pa ~/.ssh/rc
|
||||||
by
|
by
|
||||||
.Xr sshd 8 .
|
.Xr sshd 8 .
|
||||||
.It Ic force-command=command
|
.It Ic permit-x11-forwarding
|
||||||
Forces the execution of
|
Allows X11 forwarding.
|
||||||
.Ar command
|
.It Ic source-address Ns = Ns Ar address_list
|
||||||
instead of any shell or command specified by the user when
|
Restrict the source addresses from which the certificate is considered valid.
|
||||||
the certificate is used for authentication.
|
|
||||||
.It Ic source-address=address_list
|
|
||||||
Restrict the source addresses from which the certificate is considered valid
|
|
||||||
from.
|
|
||||||
The
|
The
|
||||||
.Ar address_list
|
.Ar address_list
|
||||||
is a comma-separated list of one or more address/netmask pairs in CIDR
|
is a comma-separated list of one or more address/netmask pairs in CIDR
|
||||||
@ -415,7 +414,7 @@ in YYYYMMDDHHMMSS format or a relative time (to the current time) consisting
|
|||||||
of a minus sign followed by a relative time in the format described in the
|
of a minus sign followed by a relative time in the format described in the
|
||||||
.Sx TIME FORMATS
|
.Sx TIME FORMATS
|
||||||
section of
|
section of
|
||||||
.Xr ssh_config 5 .
|
.Xr sshd_config 5 .
|
||||||
The end time may be specified as a YYYYMMDD date, a YYYYMMDDHHMMSS time or
|
The end time may be specified as a YYYYMMDD date, a YYYYMMDDHHMMSS time or
|
||||||
a relative time starting with a plus character.
|
a relative time starting with a plus character.
|
||||||
.Pp
|
.Pp
|
||||||
@ -520,7 +519,7 @@ To generate a user certificate:
|
|||||||
.Dl $ ssh-keygen -s /path/to/ca_key -I key_id /path/to/user_key.pub
|
.Dl $ ssh-keygen -s /path/to/ca_key -I key_id /path/to/user_key.pub
|
||||||
.Pp
|
.Pp
|
||||||
The resultant certificate will be placed in
|
The resultant certificate will be placed in
|
||||||
.Pa /path/to/user_key_cert.pub .
|
.Pa /path/to/user_key-cert.pub .
|
||||||
A host certificate requires the
|
A host certificate requires the
|
||||||
.Fl h
|
.Fl h
|
||||||
option:
|
option:
|
||||||
@ -528,7 +527,7 @@ option:
|
|||||||
.Dl $ ssh-keygen -s /path/to/ca_key -I key_id -h /path/to/host_key.pub
|
.Dl $ ssh-keygen -s /path/to/ca_key -I key_id -h /path/to/host_key.pub
|
||||||
.Pp
|
.Pp
|
||||||
The host certificate will be output to
|
The host certificate will be output to
|
||||||
.Pa /path/to/host_key_cert.pub .
|
.Pa /path/to/host_key-cert.pub .
|
||||||
In both cases,
|
In both cases,
|
||||||
.Ar key_id
|
.Ar key_id
|
||||||
is a "key identifier" that is logged by the server when the certificate
|
is a "key identifier" that is logged by the server when the certificate
|
||||||
@ -540,7 +539,7 @@ By default, generated certificates are valid for all users or hosts.
|
|||||||
To generate a certificate for a specified set of principals:
|
To generate a certificate for a specified set of principals:
|
||||||
.Pp
|
.Pp
|
||||||
.Dl $ ssh-keygen -s ca_key -I key_id -n user1,user2 user_key.pub
|
.Dl $ ssh-keygen -s ca_key -I key_id -n user1,user2 user_key.pub
|
||||||
.Dl $ ssh-keygen -s ca_key -I key_id -h -n host.domain user_key.pub
|
.Dl "$ ssh-keygen -s ca_key -I key_id -h -n host.domain user_key.pub"
|
||||||
.Pp
|
.Pp
|
||||||
Additional limitations on the validity and use of user certificates may
|
Additional limitations on the validity and use of user certificates may
|
||||||
be specified through certificate constraints.
|
be specified through certificate constraints.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: ssh-keygen.c,v 1.184 2010/03/07 22:16:01 djm Exp $ */
|
/* $OpenBSD: ssh-keygen.c,v 1.185 2010/03/15 19:40:02 stevesk Exp $ */
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
@ -1393,7 +1393,8 @@ do_show_cert(struct passwd *pw)
|
|||||||
SSH_FP_MD5, SSH_FP_HEX);
|
SSH_FP_MD5, SSH_FP_HEX);
|
||||||
|
|
||||||
printf("%s:\n", identity_file);
|
printf("%s:\n", identity_file);
|
||||||
printf(" %s certificate %s\n", key_type(key), key_fp);
|
printf(" %s %s certificate %s\n", key_type(key),
|
||||||
|
key_cert_type(key), key_fp);
|
||||||
printf(" Signed by %s CA %s\n",
|
printf(" Signed by %s CA %s\n",
|
||||||
key_type(key->cert->signature_key), ca_fp);
|
key_type(key->cert->signature_key), ca_fp);
|
||||||
printf(" Key ID \"%s\"\n", key->cert->key_id);
|
printf(" Key ID \"%s\"\n", key->cert->key_id);
|
||||||
|
@ -17,8 +17,6 @@
|
|||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
|
|
||||||
#ifdef ENABLE_PKCS11
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#ifdef HAVE_SYS_TIME_H
|
#ifdef HAVE_SYS_TIME_H
|
||||||
# include <sys/time.h>
|
# include <sys/time.h>
|
||||||
@ -39,6 +37,8 @@
|
|||||||
#include "authfd.h"
|
#include "authfd.h"
|
||||||
#include "ssh-pkcs11.h"
|
#include "ssh-pkcs11.h"
|
||||||
|
|
||||||
|
#ifdef ENABLE_PKCS11
|
||||||
|
|
||||||
/* borrows code from sftp-server and ssh-agent */
|
/* borrows code from sftp-server and ssh-agent */
|
||||||
|
|
||||||
struct pkcs11_keyinfo {
|
struct pkcs11_keyinfo {
|
||||||
|
@ -34,9 +34,9 @@
|
|||||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
.\"
|
.\"
|
||||||
.\" $OpenBSD: ssh.1,v 1.302 2010/03/05 10:28:21 djm Exp $
|
.\" $OpenBSD: ssh.1,v 1.303 2010/03/26 00:26:58 djm Exp $
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.Dd March 5 2010
|
.Dd March 26 2010
|
||||||
.Dt SSH 1
|
.Dt SSH 1
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -560,7 +560,10 @@ argument is
|
|||||||
the listen port will be dynamically allocated on the server and reported
|
the listen port will be dynamically allocated on the server and reported
|
||||||
to the client at run time.
|
to the client at run time.
|
||||||
.It Fl S Ar ctl_path
|
.It Fl S Ar ctl_path
|
||||||
Specifies the location of a control socket for connection sharing.
|
Specifies the location of a control socket for connection sharing
|
||||||
|
or the string
|
||||||
|
.Dq none
|
||||||
|
to disable connection sharing.
|
||||||
Refer to the description of
|
Refer to the description of
|
||||||
.Cm ControlPath
|
.Cm ControlPath
|
||||||
and
|
and
|
||||||
|
@ -46,4 +46,4 @@
|
|||||||
# PermitLocalCommand no
|
# PermitLocalCommand no
|
||||||
# VisualHostKey no
|
# VisualHostKey no
|
||||||
# ProxyCommand ssh -q -W %h:%p gateway.example.com
|
# ProxyCommand ssh -q -W %h:%p gateway.example.com
|
||||||
# VersionAddendum FreeBSD-20100308
|
# VersionAddendum FreeBSD-20100428
|
||||||
|
@ -34,9 +34,9 @@
|
|||||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
.\"
|
.\"
|
||||||
.\" $OpenBSD: ssh_config.5,v 1.129 2010/03/05 10:28:21 djm Exp $
|
.\" $OpenBSD: ssh_config.5,v 1.130 2010/03/26 01:06:13 dtucker Exp $
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.Dd March 5 2010
|
.Dd March 26 2010
|
||||||
.Dt SSH_CONFIG 5
|
.Dt SSH_CONFIG 5
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -735,11 +735,7 @@ This allows a client to prefer one method (e.g.\&
|
|||||||
over another method (e.g.\&
|
over another method (e.g.\&
|
||||||
.Cm password )
|
.Cm password )
|
||||||
The default for this option is:
|
The default for this option is:
|
||||||
.Do gssapi-with-mic ,
|
.Do gssapi-with-mic,hostbased,publickey,keyboard-interactive,password
|
||||||
hostbased,
|
|
||||||
publickey,
|
|
||||||
keyboard-interactive,
|
|
||||||
password
|
|
||||||
.Dc .
|
.Dc .
|
||||||
.It Cm Protocol
|
.It Cm Protocol
|
||||||
Specifies the protocol versions
|
Specifies the protocol versions
|
||||||
@ -1087,7 +1083,7 @@ in
|
|||||||
Specifies a string to append to the regular version string to identify
|
Specifies a string to append to the regular version string to identify
|
||||||
OS- or site-specific modifications.
|
OS- or site-specific modifications.
|
||||||
The default is
|
The default is
|
||||||
.Dq FreeBSD-20100308 .
|
.Dq FreeBSD-20100428 .
|
||||||
.It Cm VisualHostKey
|
.It Cm VisualHostKey
|
||||||
If this flag is set to
|
If this flag is set to
|
||||||
.Dq yes ,
|
.Dq yes ,
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
# Note that some of FreeBSD's defaults differ from OpenBSD's, and
|
# Note that some of FreeBSD's defaults differ from OpenBSD's, and
|
||||||
# FreeBSD has a few additional options.
|
# FreeBSD has a few additional options.
|
||||||
|
|
||||||
#VersionAddendum FreeBSD-20100308
|
#VersionAddendum FreeBSD-20100428
|
||||||
|
|
||||||
#Port 22
|
#Port 22
|
||||||
#AddressFamily any
|
#AddressFamily any
|
||||||
|
@ -988,7 +988,7 @@ The default is
|
|||||||
Specifies a string to append to the regular version string to identify
|
Specifies a string to append to the regular version string to identify
|
||||||
OS- or site-specific modifications.
|
OS- or site-specific modifications.
|
||||||
The default is
|
The default is
|
||||||
.Dq FreeBSD-20100308 .
|
.Dq FreeBSD-20100428 .
|
||||||
.It Cm X11DisplayOffset
|
.It Cm X11DisplayOffset
|
||||||
Specifies the first display number available for
|
Specifies the first display number available for
|
||||||
.Xr sshd 8 Ns 's
|
.Xr sshd 8 Ns 's
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
/* $OpenBSD: version.h,v 1.57 2010/03/07 22:01:32 djm Exp $ */
|
/* $OpenBSD: version.h,v 1.58 2010/03/16 16:36:49 djm Exp $ */
|
||||||
/* $FreeBSD$ */
|
/* $FreeBSD$ */
|
||||||
|
|
||||||
#ifndef SSH_VERSION
|
#ifndef SSH_VERSION
|
||||||
|
|
||||||
#define SSH_VERSION (ssh_version_get())
|
#define SSH_VERSION (ssh_version_get())
|
||||||
#define SSH_RELEASE (ssh_version_get())
|
#define SSH_RELEASE (ssh_version_get())
|
||||||
#define SSH_VERSION_BASE "OpenSSH_5.4p1"
|
#define SSH_VERSION_BASE "OpenSSH_5.5p1"
|
||||||
#define SSH_VERSION_ADDENDUM "FreeBSD-20100308"
|
#define SSH_VERSION_ADDENDUM "FreeBSD-20100428"
|
||||||
|
|
||||||
const char *ssh_version_get(void);
|
const char *ssh_version_get(void);
|
||||||
void ssh_version_set_addendum(const char *);
|
void ssh_version_set_addendum(const char *);
|
||||||
|
@ -399,6 +399,8 @@ ipv6if()
|
|||||||
$_if|"$_if "*|*" $_if"|*" $_if "*|[Aa][Uu][Tt][Oo])
|
$_if|"$_if "*|*" $_if"|*" $_if "*|[Aa][Uu][Tt][Oo])
|
||||||
# True if $ifconfig_IF_ipv6 is defined.
|
# True if $ifconfig_IF_ipv6 is defined.
|
||||||
_tmpargs=`_ifconfig_getargs $_if ipv6`
|
_tmpargs=`_ifconfig_getargs $_if ipv6`
|
||||||
|
# Also true if ipv6_prefix_IF is defined
|
||||||
|
[ -n "$_tmpargs" ] || _tmpargs=`get_if_var $_if ipv6_prefix_IF`
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
@ -192,6 +192,13 @@ named_prestart()
|
|||||||
$confgen_command
|
$confgen_command
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
local checkconf
|
||||||
|
|
||||||
|
checkconf="${command%/named}/named-checkconf"
|
||||||
|
if ! checkyesno named_chroot_autoupdate && [ -n "$named_chrootdir" ]; then
|
||||||
|
checkconf="$checkconf -t $named_chrootdir"
|
||||||
|
fi
|
||||||
|
|
||||||
# Create a forwarder configuration based on /etc/resolv.conf
|
# Create a forwarder configuration based on /etc/resolv.conf
|
||||||
if checkyesno named_auto_forward; then
|
if checkyesno named_auto_forward; then
|
||||||
if [ ! -s /etc/resolv.conf ]; then
|
if [ ! -s /etc/resolv.conf ]; then
|
||||||
@ -201,7 +208,7 @@ named_prestart()
|
|||||||
[ -s "${named_confdir}/auto_forward.conf" ] &&
|
[ -s "${named_confdir}/auto_forward.conf" ] &&
|
||||||
create_file ${named_confdir}/auto_forward.conf
|
create_file ${named_confdir}/auto_forward.conf
|
||||||
|
|
||||||
${command%/named}/named-checkconf $named_conf ||
|
$checkconf $named_conf ||
|
||||||
err 3 'named-checkconf for $named_conf failed'
|
err 3 'named-checkconf for $named_conf failed'
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
@ -263,8 +270,7 @@ named_prestart()
|
|||||||
create_file ${named_confdir}/auto_forward.conf
|
create_file ${named_confdir}/auto_forward.conf
|
||||||
fi
|
fi
|
||||||
|
|
||||||
${command%/named}/named-checkconf $named_conf ||
|
$checkconf $named_conf || err 3 'named-checkconf for $named_conf failed'
|
||||||
err 3 'named-checkconf for $named_conf failed'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
load_rc_config $name
|
load_rc_config $name
|
||||||
@ -272,7 +278,7 @@ load_rc_config $name
|
|||||||
# Updating the following variables requires that rc.conf be loaded first
|
# Updating the following variables requires that rc.conf be loaded first
|
||||||
#
|
#
|
||||||
required_dirs="$named_chrootdir" # if it is set, it must exist
|
required_dirs="$named_chrootdir" # if it is set, it must exist
|
||||||
required_files="${named_conf:=/etc/namedb/named.conf}"
|
|
||||||
pidfile="${named_pidfile:-/var/run/named/pid}"
|
pidfile="${named_pidfile:-/var/run/named/pid}"
|
||||||
named_confdir="${named_chrootdir}${named_conf%/*}"
|
named_confdir="${named_chrootdir}${named_conf%/*}"
|
||||||
|
|
||||||
|
@ -75,6 +75,7 @@
|
|||||||
.ds doc-operating-system-FreeBSD-7.2 7.2
|
.ds doc-operating-system-FreeBSD-7.2 7.2
|
||||||
.ds doc-operating-system-FreeBSD-7.3 7.3
|
.ds doc-operating-system-FreeBSD-7.3 7.3
|
||||||
.ds doc-operating-system-FreeBSD-8.0 8.0
|
.ds doc-operating-system-FreeBSD-8.0 8.0
|
||||||
|
.ds doc-operating-system-FreeBSD-8.1 8.1
|
||||||
.ds doc-operating-system-FreeBSD-9.0 9.0
|
.ds doc-operating-system-FreeBSD-9.0 9.0
|
||||||
.
|
.
|
||||||
.\" Definitions not (yet) in doc-syms
|
.\" Definitions not (yet) in doc-syms
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
.\" @(#)getrusage.2 8.1 (Berkeley) 6/4/93
|
.\" @(#)getrusage.2 8.1 (Berkeley) 6/4/93
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd June 4, 1993
|
.Dd May 1, 2010
|
||||||
.Dt GETRUSAGE 2
|
.Dt GETRUSAGE 2
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -42,6 +42,7 @@
|
|||||||
.In sys/resource.h
|
.In sys/resource.h
|
||||||
.Fd "#define RUSAGE_SELF 0"
|
.Fd "#define RUSAGE_SELF 0"
|
||||||
.Fd "#define RUSAGE_CHILDREN -1"
|
.Fd "#define RUSAGE_CHILDREN -1"
|
||||||
|
.Fd "#define RUSAGE_THREAD 1"
|
||||||
.Ft int
|
.Ft int
|
||||||
.Fn getrusage "int who" "struct rusage *rusage"
|
.Fn getrusage "int who" "struct rusage *rusage"
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
@ -49,11 +50,12 @@ The
|
|||||||
.Fn getrusage
|
.Fn getrusage
|
||||||
system call
|
system call
|
||||||
returns information describing the resources utilized by the current
|
returns information describing the resources utilized by the current
|
||||||
process, or all its terminated child processes.
|
thread, the current process, or all its terminated child processes.
|
||||||
The
|
The
|
||||||
.Fa who
|
.Fa who
|
||||||
argument is either
|
argument is either
|
||||||
.Dv RUSAGE_SELF
|
.Dv RUSAGE_THREAD ,
|
||||||
|
.Dv RUSAGE_SELF ,
|
||||||
or
|
or
|
||||||
.Dv RUSAGE_CHILDREN .
|
.Dv RUSAGE_CHILDREN .
|
||||||
The buffer to which
|
The buffer to which
|
||||||
@ -175,6 +177,10 @@ The
|
|||||||
.Fn getrusage
|
.Fn getrusage
|
||||||
system call appeared in
|
system call appeared in
|
||||||
.Bx 4.2 .
|
.Bx 4.2 .
|
||||||
|
The
|
||||||
|
.Dv RUSAGE_THREAD
|
||||||
|
facility first appeared in
|
||||||
|
.Fx 8.1 .
|
||||||
.Sh BUGS
|
.Sh BUGS
|
||||||
There is no way to obtain information about a child process
|
There is no way to obtain information about a child process
|
||||||
that has not yet terminated.
|
that has not yet terminated.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $Id: pam_krb5.5,v 1.5 2000/01/05 00:59:56 fcusack Exp $
|
.\" $Id: pam_krb5.5,v 1.5 2000/01/05 00:59:56 fcusack Exp $
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.Dd January 15, 1999
|
.Dd May 3, 2010
|
||||||
.Dt PAM_KRB5 8
|
.Dt PAM_KRB5 8
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -108,6 +108,10 @@ and
|
|||||||
.Ql %p ,
|
.Ql %p ,
|
||||||
to designate the current process ID; can be used in
|
to designate the current process ID; can be used in
|
||||||
.Ar name .
|
.Ar name .
|
||||||
|
.It Cm no_user_check
|
||||||
|
Do not verify if a user exists on the local system. This option implies the
|
||||||
|
.Cm no_ccache
|
||||||
|
option because there is no secure local uid/gid for the cache file.
|
||||||
.El
|
.El
|
||||||
.Ss Kerberos 5 Account Management Module
|
.Ss Kerberos 5 Account Management Module
|
||||||
The Kerberos 5 account management component
|
The Kerberos 5 account management component
|
||||||
|
@ -89,6 +89,7 @@ static void compat_free_data_contents(krb5_context, krb5_data *);
|
|||||||
#define PAM_OPT_DEBUG "debug"
|
#define PAM_OPT_DEBUG "debug"
|
||||||
#define PAM_OPT_FORWARDABLE "forwardable"
|
#define PAM_OPT_FORWARDABLE "forwardable"
|
||||||
#define PAM_OPT_NO_CCACHE "no_ccache"
|
#define PAM_OPT_NO_CCACHE "no_ccache"
|
||||||
|
#define PAM_OPT_NO_USER_CHECK "no_user_check"
|
||||||
#define PAM_OPT_REUSE_CCACHE "reuse_ccache"
|
#define PAM_OPT_REUSE_CCACHE "reuse_ccache"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -194,34 +195,39 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags __unused,
|
|||||||
|
|
||||||
PAM_LOG("Got password");
|
PAM_LOG("Got password");
|
||||||
|
|
||||||
/* Verify the local user exists (AFTER getting the password) */
|
if (openpam_get_option(pamh, PAM_OPT_NO_USER_CHECK))
|
||||||
if (strchr(user, '@')) {
|
PAM_LOG("Skipping local user check");
|
||||||
/* get a local account name for this principal */
|
else {
|
||||||
krbret = krb5_aname_to_localname(pam_context, princ,
|
|
||||||
sizeof(luser), luser);
|
/* Verify the local user exists (AFTER getting the password) */
|
||||||
if (krbret != 0) {
|
if (strchr(user, '@')) {
|
||||||
PAM_VERBOSE_ERROR("Kerberos 5 error");
|
/* get a local account name for this principal */
|
||||||
PAM_LOG("Error krb5_aname_to_localname(): %s",
|
krbret = krb5_aname_to_localname(pam_context, princ,
|
||||||
krb5_get_err_text(pam_context, krbret));
|
sizeof(luser), luser);
|
||||||
|
if (krbret != 0) {
|
||||||
|
PAM_VERBOSE_ERROR("Kerberos 5 error");
|
||||||
|
PAM_LOG("Error krb5_aname_to_localname(): %s",
|
||||||
|
krb5_get_err_text(pam_context, krbret));
|
||||||
|
retval = PAM_USER_UNKNOWN;
|
||||||
|
goto cleanup2;
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = pam_set_item(pamh, PAM_USER, luser);
|
||||||
|
if (retval != PAM_SUCCESS)
|
||||||
|
goto cleanup2;
|
||||||
|
|
||||||
|
PAM_LOG("PAM_USER Redone");
|
||||||
|
}
|
||||||
|
|
||||||
|
pwd = getpwnam(user);
|
||||||
|
if (pwd == NULL) {
|
||||||
retval = PAM_USER_UNKNOWN;
|
retval = PAM_USER_UNKNOWN;
|
||||||
goto cleanup2;
|
goto cleanup2;
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = pam_set_item(pamh, PAM_USER, luser);
|
PAM_LOG("Done getpwnam()");
|
||||||
if (retval != PAM_SUCCESS)
|
|
||||||
goto cleanup2;
|
|
||||||
|
|
||||||
PAM_LOG("PAM_USER Redone");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pwd = getpwnam(user);
|
|
||||||
if (pwd == NULL) {
|
|
||||||
retval = PAM_USER_UNKNOWN;
|
|
||||||
goto cleanup2;
|
|
||||||
}
|
|
||||||
|
|
||||||
PAM_LOG("Done getpwnam()");
|
|
||||||
|
|
||||||
/* Get a TGT */
|
/* Get a TGT */
|
||||||
memset(&creds, 0, sizeof(krb5_creds));
|
memset(&creds, 0, sizeof(krb5_creds));
|
||||||
krbret = krb5_get_init_creds_password(pam_context, &creds, princ,
|
krbret = krb5_get_init_creds_password(pam_context, &creds, princ,
|
||||||
@ -366,7 +372,8 @@ pam_sm_setcred(pam_handle_t *pamh, int flags,
|
|||||||
return (PAM_SERVICE_ERR);
|
return (PAM_SERVICE_ERR);
|
||||||
|
|
||||||
/* If a persistent cache isn't desired, stop now. */
|
/* If a persistent cache isn't desired, stop now. */
|
||||||
if (openpam_get_option(pamh, PAM_OPT_NO_CCACHE))
|
if (openpam_get_option(pamh, PAM_OPT_NO_CCACHE) ||
|
||||||
|
openpam_get_option(pamh, PAM_OPT_NO_USER_CHECK))
|
||||||
return (PAM_SUCCESS);
|
return (PAM_SUCCESS);
|
||||||
|
|
||||||
PAM_LOG("Establishing credentials");
|
PAM_LOG("Establishing credentials");
|
||||||
|
@ -737,9 +737,16 @@ iap_allocate_pmc(enum pmc_event pe, char *ctrspec,
|
|||||||
case PMC_EV_IAP_EVENT_40H: /* Core */
|
case PMC_EV_IAP_EVENT_40H: /* Core */
|
||||||
case PMC_EV_IAP_EVENT_41H: /* Core */
|
case PMC_EV_IAP_EVENT_41H: /* Core */
|
||||||
case PMC_EV_IAP_EVENT_42H: /* Core, Core2, Atom */
|
case PMC_EV_IAP_EVENT_42H: /* Core, Core2, Atom */
|
||||||
case PMC_EV_IAP_EVENT_77H: /* Core */
|
|
||||||
if (cachestate == 0)
|
if (cachestate == 0)
|
||||||
cachestate = (0xF << 8);
|
cachestate = (0xF << 8);
|
||||||
|
break;
|
||||||
|
case PMC_EV_IAP_EVENT_77H: /* Atom */
|
||||||
|
/* IAP_EVENT_77H only accepts a cachestate qualifier on the
|
||||||
|
* Atom processor
|
||||||
|
*/
|
||||||
|
if(cpu_info.pm_cputype == PMC_CPU_INTEL_ATOM && cachestate == 0)
|
||||||
|
cachestate = (0xF << 8);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -145,7 +145,7 @@ cgialloc(struct uufsd *disk)
|
|||||||
fs = &disk->d_fs;
|
fs = &disk->d_fs;
|
||||||
cgp = &disk->d_cg;
|
cgp = &disk->d_cg;
|
||||||
inosused = cg_inosused(cgp);
|
inosused = cg_inosused(cgp);
|
||||||
for (ino = 0; ino < fs->fs_ipg / NBBY; ino++)
|
for (ino = 0; ino < fs->fs_ipg; ino++)
|
||||||
if (isclr(inosused, ino))
|
if (isclr(inosused, ino))
|
||||||
goto gotit;
|
goto gotit;
|
||||||
return (0);
|
return (0);
|
||||||
|
@ -2,15 +2,14 @@
|
|||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
|
|
||||||
PROG= tftpd
|
PROG= tftpd
|
||||||
SRCS= tftpd.c tftpsubs.c
|
SRCS= tftpd.c tftp-io.c tftp-utils.c tftp-file.c tftp-transfer.c tftp-options.c
|
||||||
DPADD= ${LIBUTIL}
|
WARNS= 3
|
||||||
LDADD= -lutil
|
|
||||||
|
|
||||||
WARNS?= 1
|
|
||||||
WFORMAT=0
|
WFORMAT=0
|
||||||
|
|
||||||
MAN= tftpd.8
|
MAN= tftpd.8
|
||||||
CFLAGS+=-I${.CURDIR}/../../usr.bin/tftp
|
CFLAGS=-g -Wall
|
||||||
|
CFLAGS+=-I${.CURDIR}/../../usr.bin/tftp -I${.CURDIR}/../../libexec/tftpd
|
||||||
.PATH: ${.CURDIR}/../../usr.bin/tftp
|
.PATH: ${.CURDIR}/../../usr.bin/tftp
|
||||||
|
COPTFLAGS = -O
|
||||||
|
LDFLAGS= -lwrap
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
.include <bsd.prog.mk>
|
||||||
|
257
libexec/tftpd/tftp-file.c
Normal file
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
|
.Nd Internet Trivial File Transfer Protocol server
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm tftpd
|
.Nm tftpd
|
||||||
.Op Fl cClnwW
|
.Op Fl cdClnow
|
||||||
.Op Fl F Ar strftime-format
|
.Op Fl F Ar strftime-format
|
||||||
.Op Fl s Ar directory
|
.Op Fl s Ar directory
|
||||||
.Op Fl u Ar user
|
.Op Fl u Ar user
|
||||||
@ -150,6 +150,9 @@ compatible format string for the creation of the suffix if
|
|||||||
.Fl W
|
.Fl W
|
||||||
is specified.
|
is specified.
|
||||||
By default the string "%Y%m%d" is used.
|
By default the string "%Y%m%d" is used.
|
||||||
|
.It Fl d
|
||||||
|
Enables debug output.
|
||||||
|
If specified twice, it will log DATA and ACK packets too.
|
||||||
.It Fl l
|
.It Fl l
|
||||||
Log all requests using
|
Log all requests using
|
||||||
.Xr syslog 3
|
.Xr syslog 3
|
||||||
@ -164,6 +167,8 @@ must also be enabled in the syslog configuration file,
|
|||||||
.It Fl n
|
.It Fl n
|
||||||
Suppress negative acknowledgement of requests for nonexistent
|
Suppress negative acknowledgement of requests for nonexistent
|
||||||
relative filenames.
|
relative filenames.
|
||||||
|
.It Fl o
|
||||||
|
Disable support for RFC2347 style TFTP Options.
|
||||||
.It Fl s Ar directory
|
.It Fl s Ar directory
|
||||||
Cause
|
Cause
|
||||||
.Nm
|
.Nm
|
||||||
@ -240,10 +245,16 @@ and the
|
|||||||
and
|
and
|
||||||
.Fl W
|
.Fl W
|
||||||
options were introduced in
|
options were introduced in
|
||||||
.Fx 8.0 .
|
.Fx 7 .
|
||||||
.Pp
|
.Pp
|
||||||
|
Support for Timeout Interval and Transfer Size Options (RFC2349)
|
||||||
|
was introduced in
|
||||||
|
.Fx 5.0 ,
|
||||||
|
support for the TFTP Blocksize Option (RFC2348) and the blksize2 option
|
||||||
|
was introduced in
|
||||||
|
.Fx 7 .
|
||||||
.Sh BUGS
|
.Sh BUGS
|
||||||
Files larger than 33488896 octets (65535 blocks) cannot be transferred
|
Files larger than 33488896 octets (65535 blocks) cannot be transferred
|
||||||
without client and server supporting blocksize negotiation (RFC1783).
|
without client and server supporting blocksize negotiation (RFC2348).
|
||||||
.Pp
|
.Pp
|
||||||
Many tftp clients will not transfer files over 16744448 octets (32767 blocks).
|
Many tftp clients will not transfer files over 16744448 octets (32767 blocks).
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -27,7 +27,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd January 20, 2010
|
.Dd May 2, 2010
|
||||||
.Dt CAMCONTROL 8
|
.Dt CAMCONTROL 8
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -123,6 +123,8 @@
|
|||||||
.Op generic args
|
.Op generic args
|
||||||
.Aq Fl a Ar cmd Op args
|
.Aq Fl a Ar cmd Op args
|
||||||
.Aq Fl c Ar cmd Op args
|
.Aq Fl c Ar cmd Op args
|
||||||
|
.Op Fl d
|
||||||
|
.Op Fl f
|
||||||
.Op Fl i Ar len Ar fmt
|
.Op Fl i Ar len Ar fmt
|
||||||
.Bk -words
|
.Bk -words
|
||||||
.Op Fl o Ar len Ar fmt Op args
|
.Op Fl o Ar len Ar fmt Op args
|
||||||
@ -530,6 +532,10 @@ lba_high_exp, features_exp, sector_count, sector_count_exp).
|
|||||||
.It Fl c Ar cmd Op args
|
.It Fl c Ar cmd Op args
|
||||||
This specifies the SCSI CDB.
|
This specifies the SCSI CDB.
|
||||||
SCSI CDBs may be 6, 10, 12 or 16 bytes.
|
SCSI CDBs may be 6, 10, 12 or 16 bytes.
|
||||||
|
.It Fl d
|
||||||
|
Specifies DMA protocol to be used for ATA command.
|
||||||
|
.It Fl f
|
||||||
|
Specifies FPDMA (NCQ) protocol to be used for ATA command.
|
||||||
.It Fl i Ar len Ar fmt
|
.It Fl i Ar len Ar fmt
|
||||||
This specifies the amount of data to read, and how it should be displayed.
|
This specifies the amount of data to read, and how it should be displayed.
|
||||||
If the format is
|
If the format is
|
||||||
|
@ -123,7 +123,7 @@ struct camcontrol_opts {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#ifndef MINIMALISTIC
|
#ifndef MINIMALISTIC
|
||||||
static const char scsicmd_opts[] = "a:c:i:o:r";
|
static const char scsicmd_opts[] = "a:c:dfi:o:r";
|
||||||
static const char readdefect_opts[] = "f:GP";
|
static const char readdefect_opts[] = "f:GP";
|
||||||
static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
|
static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
|
||||||
#endif
|
#endif
|
||||||
@ -2184,6 +2184,8 @@ scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
|
|||||||
int c, data_bytes = 0;
|
int c, data_bytes = 0;
|
||||||
int cdb_len = 0;
|
int cdb_len = 0;
|
||||||
int atacmd_len = 0;
|
int atacmd_len = 0;
|
||||||
|
int dmacmd = 0;
|
||||||
|
int fpdmacmd = 0;
|
||||||
int need_res = 0;
|
int need_res = 0;
|
||||||
char *datastr = NULL, *tstr, *resstr = NULL;
|
char *datastr = NULL, *tstr, *resstr = NULL;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
@ -2246,6 +2248,12 @@ scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
|
|||||||
*/
|
*/
|
||||||
optind += hook.got;
|
optind += hook.got;
|
||||||
break;
|
break;
|
||||||
|
case 'd':
|
||||||
|
dmacmd = 1;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
fpdmacmd = 1;
|
||||||
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
if (arglist & CAM_ARG_CMD_OUT) {
|
if (arglist & CAM_ARG_CMD_OUT) {
|
||||||
warnx("command must either be "
|
warnx("command must either be "
|
||||||
@ -2422,6 +2430,10 @@ scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
|
|||||||
bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
|
bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
|
||||||
if (need_res)
|
if (need_res)
|
||||||
ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
|
ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
|
||||||
|
if (dmacmd)
|
||||||
|
ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
|
||||||
|
if (fpdmacmd)
|
||||||
|
ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
|
||||||
|
|
||||||
cam_fill_ataio(&ccb->ataio,
|
cam_fill_ataio(&ccb->ataio,
|
||||||
/*retries*/ retry_count,
|
/*retries*/ retry_count,
|
||||||
@ -2843,6 +2855,10 @@ cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
|
|||||||
fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
|
fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
|
||||||
sata->tags);
|
sata->tags);
|
||||||
}
|
}
|
||||||
|
if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
|
||||||
|
fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
|
||||||
|
sata->caps);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (cts->protocol == PROTO_SCSI) {
|
if (cts->protocol == PROTO_SCSI) {
|
||||||
struct ccb_trans_settings_scsi *scsi=
|
struct ccb_trans_settings_scsi *scsi=
|
||||||
@ -4353,7 +4369,7 @@ usage(int verbose)
|
|||||||
" [-P pagectl][-e | -b][-d]\n"
|
" [-P pagectl][-e | -b][-d]\n"
|
||||||
" camcontrol cmd [dev_id][generic args]\n"
|
" camcontrol cmd [dev_id][generic args]\n"
|
||||||
" <-a cmd [args] | -c cmd [args]>\n"
|
" <-a cmd [args] | -c cmd [args]>\n"
|
||||||
" [-i len fmt|-o len fmt [args]] [-r fmt]\n"
|
" [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
|
||||||
" camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
|
" camcontrol debug [-I][-P][-T][-S][-X][-c]\n"
|
||||||
" <all|bus[:target[:lun]]|off>\n"
|
" <all|bus[:target[:lun]]|off>\n"
|
||||||
" camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
|
" camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n"
|
||||||
|
@ -58,6 +58,7 @@ file is following:
|
|||||||
control <addr>
|
control <addr>
|
||||||
listen <addr>
|
listen <addr>
|
||||||
replication <mode>
|
replication <mode>
|
||||||
|
timeout <seconds>
|
||||||
|
|
||||||
on <node> {
|
on <node> {
|
||||||
# Node section
|
# Node section
|
||||||
@ -76,6 +77,7 @@ resource <name> {
|
|||||||
replication <mode>
|
replication <mode>
|
||||||
name <name>
|
name <name>
|
||||||
local <path>
|
local <path>
|
||||||
|
timeout <seconds>
|
||||||
|
|
||||||
on <node> {
|
on <node> {
|
||||||
# Resource-node section
|
# Resource-node section
|
||||||
@ -194,6 +196,11 @@ The
|
|||||||
.Ic async
|
.Ic async
|
||||||
replication mode is currently not implemented.
|
replication mode is currently not implemented.
|
||||||
.El
|
.El
|
||||||
|
.It Ic timeout Aq seconds
|
||||||
|
.Pp
|
||||||
|
Connection timeout in seconds.
|
||||||
|
The default value is
|
||||||
|
.Va 5 .
|
||||||
.It Ic name Aq name
|
.It Ic name Aq name
|
||||||
.Pp
|
.Pp
|
||||||
GEOM provider name that will appear as
|
GEOM provider name that will appear as
|
||||||
|
@ -75,6 +75,7 @@
|
|||||||
#define HIO_DELETE 3
|
#define HIO_DELETE 3
|
||||||
#define HIO_FLUSH 4
|
#define HIO_FLUSH 4
|
||||||
|
|
||||||
|
#define HAST_TIMEOUT 5
|
||||||
#define HAST_CONFIG "/etc/hast.conf"
|
#define HAST_CONFIG "/etc/hast.conf"
|
||||||
#define HAST_CONTROL "/var/run/hastctl"
|
#define HAST_CONTROL "/var/run/hastctl"
|
||||||
#define HASTD_PORT 8457
|
#define HASTD_PORT 8457
|
||||||
@ -148,6 +149,8 @@ struct hast_resource {
|
|||||||
/* Token to verify both in and out connection are coming from
|
/* Token to verify both in and out connection are coming from
|
||||||
the same node (not necessarily from the same address). */
|
the same node (not necessarily from the same address). */
|
||||||
unsigned char hr_token[HAST_TOKEN_SIZE];
|
unsigned char hr_token[HAST_TOKEN_SIZE];
|
||||||
|
/* Connection timeout. */
|
||||||
|
int hr_timeout;
|
||||||
|
|
||||||
/* Resource unique identifier. */
|
/* Resource unique identifier. */
|
||||||
uint64_t hr_resuid;
|
uint64_t hr_resuid;
|
||||||
|
@ -107,6 +107,22 @@ g_gate_load(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
child_exit_log(unsigned int pid, int status)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
|
||||||
|
pjdlog_debug(1, "Worker process exited gracefully (pid=%u).",
|
||||||
|
pid);
|
||||||
|
} else if (WIFSIGNALED(status)) {
|
||||||
|
pjdlog_error("Worker process killed (pid=%u, signal=%d).",
|
||||||
|
pid, WTERMSIG(status));
|
||||||
|
} else {
|
||||||
|
pjdlog_error("Worker process exited ungracefully (pid=%u, exitcode=%d).",
|
||||||
|
pid, WIFEXITED(status) ? WEXITSTATUS(status) : -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
child_exit(void)
|
child_exit(void)
|
||||||
{
|
{
|
||||||
@ -129,20 +145,25 @@ child_exit(void)
|
|||||||
}
|
}
|
||||||
pjdlog_prefix_set("[%s] (%s) ", res->hr_name,
|
pjdlog_prefix_set("[%s] (%s) ", res->hr_name,
|
||||||
role2str(res->hr_role));
|
role2str(res->hr_role));
|
||||||
if (WEXITSTATUS(status) == 0) {
|
child_exit_log(pid, status);
|
||||||
pjdlog_debug(1,
|
|
||||||
"Worker process exited gracefully (pid=%u).",
|
|
||||||
(unsigned int)pid);
|
|
||||||
} else {
|
|
||||||
pjdlog_error("Worker process failed (pid=%u, status=%d).",
|
|
||||||
(unsigned int)pid, WEXITSTATUS(status));
|
|
||||||
}
|
|
||||||
proto_close(res->hr_ctrl);
|
proto_close(res->hr_ctrl);
|
||||||
res->hr_workerpid = 0;
|
res->hr_workerpid = 0;
|
||||||
if (res->hr_role == HAST_ROLE_PRIMARY) {
|
if (res->hr_role == HAST_ROLE_PRIMARY) {
|
||||||
sleep(1);
|
/*
|
||||||
pjdlog_info("Restarting worker process.");
|
* Restart child process if it was killed by signal
|
||||||
hastd_primary(res);
|
* or exited because of temporary problem.
|
||||||
|
*/
|
||||||
|
if (WIFSIGNALED(status) ||
|
||||||
|
(WIFEXITED(status) &&
|
||||||
|
WEXITSTATUS(status) == EX_TEMPFAIL)) {
|
||||||
|
sleep(1);
|
||||||
|
pjdlog_info("Restarting worker process.");
|
||||||
|
hastd_primary(res);
|
||||||
|
} else {
|
||||||
|
res->hr_role = HAST_ROLE_INIT;
|
||||||
|
pjdlog_info("Changing resource role back to %s.",
|
||||||
|
role2str(res->hr_role));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pjdlog_prefix_set("%s", "");
|
pjdlog_prefix_set("%s", "");
|
||||||
}
|
}
|
||||||
@ -181,6 +202,10 @@ listen_accept(void)
|
|||||||
proto_remote_address(conn, raddr, sizeof(raddr));
|
proto_remote_address(conn, raddr, sizeof(raddr));
|
||||||
pjdlog_info("Connection from %s to %s.", laddr, raddr);
|
pjdlog_info("Connection from %s to %s.", laddr, raddr);
|
||||||
|
|
||||||
|
/* Error in setting timeout is not critical, but why should it fail? */
|
||||||
|
if (proto_timeout(conn, HAST_TIMEOUT) < 0)
|
||||||
|
pjdlog_errno(LOG_WARNING, "Unable to set connection timeout");
|
||||||
|
|
||||||
nvin = nvout = nverr = NULL;
|
nvin = nvout = nverr = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -290,18 +315,12 @@ listen_accept(void)
|
|||||||
/* Wait for it to exit. */
|
/* Wait for it to exit. */
|
||||||
else if ((pid = waitpid(res->hr_workerpid,
|
else if ((pid = waitpid(res->hr_workerpid,
|
||||||
&status, 0)) != res->hr_workerpid) {
|
&status, 0)) != res->hr_workerpid) {
|
||||||
|
/* We can only log the problem. */
|
||||||
pjdlog_errno(LOG_ERR,
|
pjdlog_errno(LOG_ERR,
|
||||||
"Waiting for worker process (pid=%u) failed",
|
"Waiting for worker process (pid=%u) failed",
|
||||||
(unsigned int)res->hr_workerpid);
|
(unsigned int)res->hr_workerpid);
|
||||||
/* See above. */
|
|
||||||
} else if (status != 0) {
|
|
||||||
pjdlog_error("Worker process (pid=%u) exited ungracefully: status=%d.",
|
|
||||||
(unsigned int)res->hr_workerpid, status);
|
|
||||||
/* See above. */
|
|
||||||
} else {
|
} else {
|
||||||
pjdlog_debug(1,
|
child_exit_log(res->hr_workerpid, status);
|
||||||
"Worker process (pid=%u) exited gracefully.",
|
|
||||||
(unsigned int)res->hr_workerpid);
|
|
||||||
}
|
}
|
||||||
res->hr_workerpid = 0;
|
res->hr_workerpid = 0;
|
||||||
} else if (res->hr_remotein != NULL) {
|
} else if (res->hr_remotein != NULL) {
|
||||||
|
@ -117,7 +117,7 @@ metadata_read(struct hast_resource *res, bool openrw)
|
|||||||
}
|
}
|
||||||
|
|
||||||
str = nv_get_string(nv, "resource");
|
str = nv_get_string(nv, "resource");
|
||||||
if (strcmp(str, res->hr_name) != 0) {
|
if (str != NULL && strcmp(str, res->hr_name) != 0) {
|
||||||
pjdlog_error("Provider %s is not part of resource %s.",
|
pjdlog_error("Provider %s is not part of resource %s.",
|
||||||
res->hr_localpath, res->hr_name);
|
res->hr_localpath, res->hr_name);
|
||||||
nv_free(nv);
|
nv_free(nv);
|
||||||
|
@ -58,6 +58,7 @@ static bool mynode;
|
|||||||
static char depth0_control[HAST_ADDRSIZE];
|
static char depth0_control[HAST_ADDRSIZE];
|
||||||
static char depth0_listen[HAST_ADDRSIZE];
|
static char depth0_listen[HAST_ADDRSIZE];
|
||||||
static int depth0_replication;
|
static int depth0_replication;
|
||||||
|
static int depth0_timeout;
|
||||||
|
|
||||||
static char depth1_provname[PATH_MAX];
|
static char depth1_provname[PATH_MAX];
|
||||||
static char depth1_localpath[PATH_MAX];
|
static char depth1_localpath[PATH_MAX];
|
||||||
@ -115,6 +116,7 @@ yy_config_parse(const char *config)
|
|||||||
curres = NULL;
|
curres = NULL;
|
||||||
mynode = false;
|
mynode = false;
|
||||||
|
|
||||||
|
depth0_timeout = HAST_TIMEOUT;
|
||||||
depth0_replication = HAST_REPLICATION_MEMSYNC;
|
depth0_replication = HAST_REPLICATION_MEMSYNC;
|
||||||
strlcpy(depth0_control, HAST_CONTROL, sizeof(depth0_control));
|
strlcpy(depth0_control, HAST_CONTROL, sizeof(depth0_control));
|
||||||
strlcpy(depth0_listen, HASTD_LISTEN, sizeof(depth0_listen));
|
strlcpy(depth0_listen, HASTD_LISTEN, sizeof(depth0_listen));
|
||||||
@ -154,6 +156,13 @@ yy_config_parse(const char *config)
|
|||||||
*/
|
*/
|
||||||
curres->hr_replication = depth0_replication;
|
curres->hr_replication = depth0_replication;
|
||||||
}
|
}
|
||||||
|
if (curres->hr_timeout == -1) {
|
||||||
|
/*
|
||||||
|
* Timeout is not set at resource-level.
|
||||||
|
* Use global or default setting.
|
||||||
|
*/
|
||||||
|
curres->hr_timeout = depth0_timeout;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (&lconfig);
|
return (&lconfig);
|
||||||
@ -171,7 +180,7 @@ yy_config_free(struct hastd_config *config)
|
|||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%token CONTROL LISTEN PORT REPLICATION EXTENTSIZE RESOURCE NAME LOCAL REMOTE ON
|
%token CONTROL LISTEN PORT REPLICATION TIMEOUT EXTENTSIZE RESOURCE NAME LOCAL REMOTE ON
|
||||||
%token FULLSYNC MEMSYNC ASYNC
|
%token FULLSYNC MEMSYNC ASYNC
|
||||||
%token NUM STR OB CB
|
%token NUM STR OB CB
|
||||||
|
|
||||||
@ -200,6 +209,8 @@ statement:
|
|||||||
|
|
|
|
||||||
replication_statement
|
replication_statement
|
||||||
|
|
|
|
||||||
|
timeout_statement
|
||||||
|
|
|
||||||
node_statement
|
node_statement
|
||||||
|
|
|
|
||||||
resource_statement
|
resource_statement
|
||||||
@ -281,6 +292,22 @@ replication_type:
|
|||||||
ASYNC { $$ = HAST_REPLICATION_ASYNC; }
|
ASYNC { $$ = HAST_REPLICATION_ASYNC; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
timeout_statement: TIMEOUT NUM
|
||||||
|
{
|
||||||
|
switch (depth) {
|
||||||
|
case 0:
|
||||||
|
depth0_timeout = $2;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (curres != NULL)
|
||||||
|
curres->hr_timeout = $2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(!"timeout at wrong depth level");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
node_statement: ON node_start OB node_entries CB
|
node_statement: ON node_start OB node_entries CB
|
||||||
{
|
{
|
||||||
mynode = false;
|
mynode = false;
|
||||||
@ -389,6 +416,7 @@ resource_start: STR
|
|||||||
curres->hr_role = HAST_ROLE_INIT;
|
curres->hr_role = HAST_ROLE_INIT;
|
||||||
curres->hr_previous_role = HAST_ROLE_INIT;
|
curres->hr_previous_role = HAST_ROLE_INIT;
|
||||||
curres->hr_replication = -1;
|
curres->hr_replication = -1;
|
||||||
|
curres->hr_timeout = -1;
|
||||||
curres->hr_provname[0] = '\0';
|
curres->hr_provname[0] = '\0';
|
||||||
curres->hr_localpath[0] = '\0';
|
curres->hr_localpath[0] = '\0';
|
||||||
curres->hr_localfd = -1;
|
curres->hr_localfd = -1;
|
||||||
@ -405,6 +433,8 @@ resource_entries:
|
|||||||
resource_entry:
|
resource_entry:
|
||||||
replication_statement
|
replication_statement
|
||||||
|
|
|
|
||||||
|
timeout_statement
|
||||||
|
|
|
||||||
name_statement
|
name_statement
|
||||||
|
|
|
|
||||||
local_statement
|
local_statement
|
||||||
|
@ -480,7 +480,7 @@ init_remote(struct hast_resource *res, struct proto_conn **inp,
|
|||||||
|
|
||||||
/* Prepare outgoing connection with remote node. */
|
/* Prepare outgoing connection with remote node. */
|
||||||
if (proto_client(res->hr_remoteaddr, &out) < 0) {
|
if (proto_client(res->hr_remoteaddr, &out) < 0) {
|
||||||
primary_exit(EX_OSERR, "Unable to create connection to %s",
|
primary_exit(EX_TEMPFAIL, "Unable to create connection to %s",
|
||||||
res->hr_remoteaddr);
|
res->hr_remoteaddr);
|
||||||
}
|
}
|
||||||
/* Try to connect, but accept failure. */
|
/* Try to connect, but accept failure. */
|
||||||
@ -489,6 +489,9 @@ init_remote(struct hast_resource *res, struct proto_conn **inp,
|
|||||||
res->hr_remoteaddr);
|
res->hr_remoteaddr);
|
||||||
goto close;
|
goto close;
|
||||||
}
|
}
|
||||||
|
/* Error in setting timeout is not critical, but why should it fail? */
|
||||||
|
if (proto_timeout(out, res->hr_timeout) < 0)
|
||||||
|
pjdlog_errno(LOG_WARNING, "Unable to set connection timeout");
|
||||||
/*
|
/*
|
||||||
* First handshake step.
|
* First handshake step.
|
||||||
* Setup outgoing connection with remote node.
|
* Setup outgoing connection with remote node.
|
||||||
@ -552,6 +555,9 @@ init_remote(struct hast_resource *res, struct proto_conn **inp,
|
|||||||
res->hr_remoteaddr);
|
res->hr_remoteaddr);
|
||||||
goto close;
|
goto close;
|
||||||
}
|
}
|
||||||
|
/* Error in setting timeout is not critical, but why should it fail? */
|
||||||
|
if (proto_timeout(in, res->hr_timeout) < 0)
|
||||||
|
pjdlog_errno(LOG_WARNING, "Unable to set connection timeout");
|
||||||
nvout = nv_alloc();
|
nvout = nv_alloc();
|
||||||
nv_add_string(nvout, res->hr_name, "resource");
|
nv_add_string(nvout, res->hr_name, "resource");
|
||||||
nv_add_uint8_array(nvout, res->hr_token, sizeof(res->hr_token),
|
nv_add_uint8_array(nvout, res->hr_token, sizeof(res->hr_token),
|
||||||
@ -739,7 +745,7 @@ hastd_primary(struct hast_resource *res)
|
|||||||
pid = fork();
|
pid = fork();
|
||||||
if (pid < 0) {
|
if (pid < 0) {
|
||||||
KEEP_ERRNO((void)pidfile_remove(pfh));
|
KEEP_ERRNO((void)pidfile_remove(pfh));
|
||||||
primary_exit(EX_OSERR, "Unable to fork");
|
primary_exit(EX_TEMPFAIL, "Unable to fork");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pid > 0) {
|
if (pid > 0) {
|
||||||
|
@ -30,7 +30,9 @@
|
|||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__FBSDID("$FreeBSD$");
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
#include <sys/queue.h>
|
#include <sys/queue.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@ -247,6 +249,30 @@ proto_remote_address(const struct proto_conn *conn, char *addr, size_t size)
|
|||||||
conn->pc_proto->hp_remote_address(conn->pc_ctx, addr, size);
|
conn->pc_proto->hp_remote_address(conn->pc_ctx, addr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
proto_timeout(const struct proto_conn *conn, int timeout)
|
||||||
|
{
|
||||||
|
struct timeval tv;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
assert(conn != NULL);
|
||||||
|
assert(conn->pc_magic == PROTO_CONN_MAGIC);
|
||||||
|
assert(conn->pc_proto != NULL);
|
||||||
|
|
||||||
|
fd = proto_descriptor(conn);
|
||||||
|
if (fd < 0)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
tv.tv_sec = timeout;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) < 0)
|
||||||
|
return (-1);
|
||||||
|
if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
proto_close(struct proto_conn *conn)
|
proto_close(struct proto_conn *conn)
|
||||||
{
|
{
|
||||||
|
@ -49,6 +49,7 @@ void proto_local_address(const struct proto_conn *conn, char *addr,
|
|||||||
size_t size);
|
size_t size);
|
||||||
void proto_remote_address(const struct proto_conn *conn, char *addr,
|
void proto_remote_address(const struct proto_conn *conn, char *addr,
|
||||||
size_t size);
|
size_t size);
|
||||||
|
int proto_timeout(const struct proto_conn *conn, int timeout);
|
||||||
void proto_close(struct proto_conn *conn);
|
void proto_close(struct proto_conn *conn);
|
||||||
|
|
||||||
#endif /* !_PROTO_H_ */
|
#endif /* !_PROTO_H_ */
|
||||||
|
@ -58,7 +58,7 @@ proto_common_send(int fd, const unsigned char *data, size_t size)
|
|||||||
if (done == 0)
|
if (done == 0)
|
||||||
return (ENOTCONN);
|
return (ENOTCONN);
|
||||||
else if (done < 0) {
|
else if (done < 0) {
|
||||||
if (errno == EAGAIN)
|
if (errno == EINTR)
|
||||||
continue;
|
continue;
|
||||||
return (errno);
|
return (errno);
|
||||||
}
|
}
|
||||||
@ -76,7 +76,7 @@ proto_common_recv(int fd, unsigned char *data, size_t size)
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
done = recv(fd, data, size, MSG_WAITALL);
|
done = recv(fd, data, size, MSG_WAITALL);
|
||||||
} while (done == -1 && errno == EAGAIN);
|
} while (done == -1 && errno == EINTR);
|
||||||
if (done == 0)
|
if (done == 0)
|
||||||
return (ENOTCONN);
|
return (ENOTCONN);
|
||||||
else if (done < 0)
|
else if (done < 0)
|
||||||
|
@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@ -47,6 +48,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include "hast.h"
|
#include "hast.h"
|
||||||
#include "pjdlog.h"
|
#include "pjdlog.h"
|
||||||
#include "proto_impl.h"
|
#include "proto_impl.h"
|
||||||
|
#include "subr.h"
|
||||||
|
|
||||||
#define TCP4_CTX_MAGIC 0x7c441c
|
#define TCP4_CTX_MAGIC 0x7c441c
|
||||||
struct tcp4_ctx {
|
struct tcp4_ctx {
|
||||||
@ -222,18 +224,88 @@ static int
|
|||||||
tcp4_connect(void *ctx)
|
tcp4_connect(void *ctx)
|
||||||
{
|
{
|
||||||
struct tcp4_ctx *tctx = ctx;
|
struct tcp4_ctx *tctx = ctx;
|
||||||
|
struct timeval tv;
|
||||||
|
fd_set fdset;
|
||||||
|
socklen_t esize;
|
||||||
|
int error, flags, ret;
|
||||||
|
|
||||||
assert(tctx != NULL);
|
assert(tctx != NULL);
|
||||||
assert(tctx->tc_magic == TCP4_CTX_MAGIC);
|
assert(tctx->tc_magic == TCP4_CTX_MAGIC);
|
||||||
assert(tctx->tc_side == TCP4_SIDE_CLIENT);
|
assert(tctx->tc_side == TCP4_SIDE_CLIENT);
|
||||||
assert(tctx->tc_fd >= 0);
|
assert(tctx->tc_fd >= 0);
|
||||||
|
|
||||||
if (connect(tctx->tc_fd, (struct sockaddr *)&tctx->tc_sin,
|
flags = fcntl(tctx->tc_fd, F_GETFL);
|
||||||
sizeof(tctx->tc_sin)) < 0) {
|
if (flags == -1) {
|
||||||
|
KEEP_ERRNO(pjdlog_common(LOG_DEBUG, 1, errno,
|
||||||
|
"fcntl(F_GETFL) failed"));
|
||||||
|
return (errno);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* We make socket non-blocking so we have decided about connection
|
||||||
|
* timeout.
|
||||||
|
*/
|
||||||
|
flags |= O_NONBLOCK;
|
||||||
|
if (fcntl(tctx->tc_fd, F_SETFL, flags) == -1) {
|
||||||
|
KEEP_ERRNO(pjdlog_common(LOG_DEBUG, 1, errno,
|
||||||
|
"fcntl(F_SETFL, O_NONBLOCK) failed"));
|
||||||
return (errno);
|
return (errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (0);
|
if (connect(tctx->tc_fd, (struct sockaddr *)&tctx->tc_sin,
|
||||||
|
sizeof(tctx->tc_sin)) == 0) {
|
||||||
|
error = 0;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (errno != EINPROGRESS) {
|
||||||
|
error = errno;
|
||||||
|
pjdlog_common(LOG_DEBUG, 1, errno, "connect() failed");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Connection can't be established immediately, let's wait
|
||||||
|
* for HAST_TIMEOUT seconds.
|
||||||
|
*/
|
||||||
|
tv.tv_sec = HAST_TIMEOUT;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
again:
|
||||||
|
FD_ZERO(&fdset);
|
||||||
|
FD_SET(tctx->tc_fd, &fdset);
|
||||||
|
ret = select(tctx->tc_fd + 1, NULL, &fdset, NULL, &tv);
|
||||||
|
if (ret == 0) {
|
||||||
|
error = ETIMEDOUT;
|
||||||
|
goto done;
|
||||||
|
} else if (ret == -1) {
|
||||||
|
if (errno == EINTR)
|
||||||
|
goto again;
|
||||||
|
error = errno;
|
||||||
|
pjdlog_common(LOG_DEBUG, 1, errno, "select() failed");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
assert(ret > 0);
|
||||||
|
assert(FD_ISSET(tctx->tc_fd, &fdset));
|
||||||
|
esize = sizeof(error);
|
||||||
|
if (getsockopt(tctx->tc_fd, SOL_SOCKET, SO_ERROR, &error,
|
||||||
|
&esize) == -1) {
|
||||||
|
error = errno;
|
||||||
|
pjdlog_common(LOG_DEBUG, 1, errno,
|
||||||
|
"getsockopt(SO_ERROR) failed");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (error != 0) {
|
||||||
|
pjdlog_common(LOG_DEBUG, 1, error,
|
||||||
|
"getsockopt(SO_ERROR) returned error");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
error = 0;
|
||||||
|
done:
|
||||||
|
flags &= ~O_NONBLOCK;
|
||||||
|
if (fcntl(tctx->tc_fd, F_SETFL, flags) == -1) {
|
||||||
|
if (error == 0)
|
||||||
|
error = errno;
|
||||||
|
pjdlog_common(LOG_DEBUG, 1, errno,
|
||||||
|
"fcntl(F_SETFL, ~O_NONBLOCK) failed");
|
||||||
|
}
|
||||||
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -337,6 +337,12 @@ hastd_secondary(struct hast_resource *res, struct nv *nvin)
|
|||||||
|
|
||||||
setproctitle("%s (secondary)", res->hr_name);
|
setproctitle("%s (secondary)", res->hr_name);
|
||||||
|
|
||||||
|
/* Error in setting timeout is not critical, but why should it fail? */
|
||||||
|
if (proto_timeout(res->hr_remotein, 0) < 0)
|
||||||
|
pjdlog_errno(LOG_WARNING, "Unable to set connection timeout");
|
||||||
|
if (proto_timeout(res->hr_remoteout, res->hr_timeout) < 0)
|
||||||
|
pjdlog_errno(LOG_WARNING, "Unable to set connection timeout");
|
||||||
|
|
||||||
init_local(res);
|
init_local(res);
|
||||||
init_remote(res, nvin);
|
init_remote(res, nvin);
|
||||||
init_environment();
|
init_environment();
|
||||||
|
@ -48,6 +48,7 @@ control { DP; return CONTROL; }
|
|||||||
listen { DP; return LISTEN; }
|
listen { DP; return LISTEN; }
|
||||||
port { DP; return PORT; }
|
port { DP; return PORT; }
|
||||||
replication { DP; return REPLICATION; }
|
replication { DP; return REPLICATION; }
|
||||||
|
timeout { DP; return TIMEOUT; }
|
||||||
resource { DP; return RESOURCE; }
|
resource { DP; return RESOURCE; }
|
||||||
name { DP; return NAME; }
|
name { DP; return NAME; }
|
||||||
local { DP; return LOCAL; }
|
local { DP; return LOCAL; }
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
.\" From: @(#)ifconfig.8 8.3 (Berkeley) 1/5/94
|
.\" From: @(#)ifconfig.8 8.3 (Berkeley) 1/5/94
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd February 20, 2010
|
.Dd April 28, 2010
|
||||||
.Dt IFCONFIG 8
|
.Dt IFCONFIG 8
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -1163,9 +1163,9 @@ In particular the information elements included in management frames
|
|||||||
for old devices are different.
|
for old devices are different.
|
||||||
When compatibility support is enabled both standard and compatible data
|
When compatibility support is enabled both standard and compatible data
|
||||||
will be provided.
|
will be provided.
|
||||||
Stations that associate using the compatiblity mechanisms are flagged
|
Stations that associate using the compatibility mechanisms are flagged
|
||||||
in ``list sta''.
|
in ``list sta''.
|
||||||
To disable compatiblity support use
|
To disable compatibility support use
|
||||||
.Fl htcompat .
|
.Fl htcompat .
|
||||||
.It Cm htprotmode Ar technique
|
.It Cm htprotmode Ar technique
|
||||||
For interfaces operating in 802.11n, use the specified
|
For interfaces operating in 802.11n, use the specified
|
||||||
|
@ -5027,7 +5027,7 @@ DECL_CMD_FUNC(set80211clone_wlanaddr, arg, d)
|
|||||||
|
|
||||||
ea = ether_aton(arg);
|
ea = ether_aton(arg);
|
||||||
if (ea == NULL)
|
if (ea == NULL)
|
||||||
errx(1, "%s: cannot parse addres", arg);
|
errx(1, "%s: cannot parse address", arg);
|
||||||
memcpy(params.icp_macaddr, ea->octet, IEEE80211_ADDR_LEN);
|
memcpy(params.icp_macaddr, ea->octet, IEEE80211_ADDR_LEN);
|
||||||
params.icp_flags |= IEEE80211_CLONE_MACADDR;
|
params.icp_flags |= IEEE80211_CLONE_MACADDR;
|
||||||
}
|
}
|
||||||
|
@ -280,9 +280,9 @@ main(int argc, char *argv[])
|
|||||||
if (ufs_disk_fillout(&disk, special) == -1)
|
if (ufs_disk_fillout(&disk, special) == -1)
|
||||||
goto err;
|
goto err;
|
||||||
if (disk.d_name != special) {
|
if (disk.d_name != special) {
|
||||||
special = disk.d_name;
|
if (statfs(special, &stfs) != 0)
|
||||||
if (statfs(special, &stfs) == 0 &&
|
warn("Can't stat %s", special);
|
||||||
strcmp(special, stfs.f_mntonname) == 0)
|
if (strcmp(special, stfs.f_mntonname) == 0)
|
||||||
active = 1;
|
active = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -546,7 +546,7 @@ journal_balloc(void)
|
|||||||
* Try to minimize fragmentation by requiring a minimum
|
* Try to minimize fragmentation by requiring a minimum
|
||||||
* number of blocks present.
|
* number of blocks present.
|
||||||
*/
|
*/
|
||||||
if (cgp->cg_cs.cs_nbfree > blocks / 8)
|
if (cgp->cg_cs.cs_nbfree > 128 * 1024 * 1024)
|
||||||
break;
|
break;
|
||||||
if (contig == 0 && cgp->cg_cs.cs_nbfree)
|
if (contig == 0 && cgp->cg_cs.cs_nbfree)
|
||||||
break;
|
break;
|
||||||
@ -1007,10 +1007,11 @@ out:
|
|||||||
void
|
void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s\n%s\n%s\n%s\n",
|
fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n",
|
||||||
"usage: tunefs [-A] [-a enable | disable] [-e maxbpg] [-f avgfilesize]",
|
"usage: tunefs [-A] [-a enable | disable] [-e maxbpg] [-f avgfilesize]",
|
||||||
" [-J enable | disable ] [-L volname] [-l enable | disable]",
|
" [-J enable | disable] [-j enable | disable]",
|
||||||
" [-m minfree] [-N enable | disable] [-n enable | disable]",
|
" [-L volname] [-l enable | disable] [-m minfree]",
|
||||||
|
" [-N enable | disable] [-n enable | disable]",
|
||||||
" [-o space | time] [-p] [-s avgfpdir] special | filesystem");
|
" [-o space | time] [-p] [-s avgfpdir] special | filesystem");
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
@ -220,6 +220,7 @@ MAN= aac.4 \
|
|||||||
msk.4 \
|
msk.4 \
|
||||||
mtio.4 \
|
mtio.4 \
|
||||||
multicast.4 \
|
multicast.4 \
|
||||||
|
mvs.4 \
|
||||||
mwl.4 \
|
mwl.4 \
|
||||||
mwlfw.4 \
|
mwlfw.4 \
|
||||||
mxge.4 \
|
mxge.4 \
|
||||||
|
@ -123,7 +123,7 @@ ifconfig wlan create wlandev bwn0 ssid my_net \e
|
|||||||
The
|
The
|
||||||
.Nm
|
.Nm
|
||||||
driver first appeared in
|
driver first appeared in
|
||||||
.Fx 8.0 .
|
.Fx 8.1 .
|
||||||
.Sh AUTHORS
|
.Sh AUTHORS
|
||||||
.An -nosplit
|
.An -nosplit
|
||||||
The
|
The
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd June 15, 2009
|
.Dd May 3, 2010
|
||||||
.Dt CAS 4
|
.Dt CAS 4
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -91,6 +91,9 @@ driver at this time:
|
|||||||
.Pp
|
.Pp
|
||||||
.Bl -bullet -compact
|
.Bl -bullet -compact
|
||||||
.It
|
.It
|
||||||
|
Sun GigaSwift Ethernet 1.0 MMF (Cassini Kuheen)
|
||||||
|
(part no.\& 501-5524)
|
||||||
|
.It
|
||||||
Sun GigaSwift Ethernet 1.0 UTP (Cassini)
|
Sun GigaSwift Ethernet 1.0 UTP (Cassini)
|
||||||
(part no.\& 501-5902)
|
(part no.\& 501-5902)
|
||||||
.It
|
.It
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd March 1, 2010
|
.Dd April 30, 2010
|
||||||
.Dt MSK 4
|
.Dt MSK 4
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -208,6 +208,8 @@ Marvell Yukon 88E8057 Gigabit Ethernet
|
|||||||
.It
|
.It
|
||||||
Marvell Yukon 88E8058 Gigabit Ethernet
|
Marvell Yukon 88E8058 Gigabit Ethernet
|
||||||
.It
|
.It
|
||||||
|
Marvell Yukon 88E8059 Gigabit Ethernet
|
||||||
|
.It
|
||||||
Marvell Yukon 88E8070 Gigabit Ethernet
|
Marvell Yukon 88E8070 Gigabit Ethernet
|
||||||
.It
|
.It
|
||||||
Marvell Yukon 88E8071 Gigabit Ethernet
|
Marvell Yukon 88E8071 Gigabit Ethernet
|
||||||
|
176
share/man/man4/mvs.4
Normal file
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$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd August 31, 2000
|
.Dd May 5, 2010
|
||||||
.Dt NG_BRIDGE 4
|
.Dt NG_BRIDGE 4
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -181,11 +181,17 @@ but also atomically clears the statistics as well.
|
|||||||
.It Dv NGM_BRIDGE_GET_TABLE
|
.It Dv NGM_BRIDGE_GET_TABLE
|
||||||
Returns the current host mapping table used to direct packets, in a
|
Returns the current host mapping table used to direct packets, in a
|
||||||
.Dv "struct ng_bridge_host_ary" .
|
.Dv "struct ng_bridge_host_ary" .
|
||||||
|
.It Dv NGM_BRIDGE_SET_PERSISTENT
|
||||||
|
This command sets the persistent flag on the node, and takes no arguments.
|
||||||
.El
|
.El
|
||||||
.Sh SHUTDOWN
|
.Sh SHUTDOWN
|
||||||
This node shuts down upon receipt of a
|
This node shuts down upon receipt of a
|
||||||
.Dv NGM_SHUTDOWN
|
.Dv NGM_SHUTDOWN
|
||||||
control message, or when all hooks have been disconnected.
|
control message, or when all hooks have been disconnected. Setting the
|
||||||
|
persistent flag via a
|
||||||
|
.Dv NGM_BRIDGE_SET_PERSISTENT
|
||||||
|
control message disables automatic node shutdown when the last hook gets
|
||||||
|
disconnected.
|
||||||
.Sh FILES
|
.Sh FILES
|
||||||
.Bl -tag -width XXXXXXXX -compact
|
.Bl -tag -width XXXXXXXX -compact
|
||||||
.It Pa /usr/share/examples/netgraph/ether.bridge
|
.It Pa /usr/share/examples/netgraph/ether.bridge
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd April 17, 2004
|
.Dd May 5, 2010
|
||||||
.Dt NG_HUB 4
|
.Dt NG_HUB 4
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -45,11 +45,20 @@ A
|
|||||||
node accepts any request to connect, regardless of the hook name,
|
node accepts any request to connect, regardless of the hook name,
|
||||||
as long as the name is unique.
|
as long as the name is unique.
|
||||||
.Sh CONTROL MESSAGES
|
.Sh CONTROL MESSAGES
|
||||||
This node type supports only the generic control messages.
|
This node type supports the generic control messages, plus the
|
||||||
|
following:
|
||||||
|
.Bl -tag -width foo
|
||||||
|
.It Dv NGM_HUB_SET_PERSISTENT
|
||||||
|
This command sets the persistent flag on the node, and takes no arguments.
|
||||||
|
.El
|
||||||
.Sh SHUTDOWN
|
.Sh SHUTDOWN
|
||||||
This node shuts down upon receipt of a
|
This node shuts down upon receipt of a
|
||||||
.Dv NGM_SHUTDOWN
|
.Dv NGM_SHUTDOWN
|
||||||
control message, or when all hooks have been disconnected.
|
control message, or when all hooks have been disconnected. Setting the
|
||||||
|
persistent flag via a
|
||||||
|
.Dv NGM_HUB_SET_PERSISTENT
|
||||||
|
control message disables automatic node shutdown when the last hook gets
|
||||||
|
disconnected.
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr netgraph 4 ,
|
.Xr netgraph 4 ,
|
||||||
.Xr ng_bridge 4 ,
|
.Xr ng_bridge 4 ,
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd April 14, 2010
|
.Dd April 29, 2010
|
||||||
.Dt SGE 4
|
.Dt SGE 4
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -53,11 +53,11 @@ controllers and SiS191 Fast/Gigabit Ethernet controllers.
|
|||||||
.Pp
|
.Pp
|
||||||
All LOMs supported by the
|
All LOMs supported by the
|
||||||
.Nm
|
.Nm
|
||||||
driver have TCP/UDP/IP checksum offload for transmit and receive.
|
driver have TCP/UDP/IP checksum offload for transmit and receive,
|
||||||
|
hardware VLAN tag stripping/insertion features.
|
||||||
Due to lack of documentation more offloading features like TCP
|
Due to lack of documentation more offloading features like TCP
|
||||||
segmentation offload (TSO), hardware VLAN tag stripping/insertion
|
segmentation offload (TSO), Wake On Lan (WOL), Jumbo frame and an
|
||||||
features, Wake On Lan (WOL), Jumbo frame and an interrupt moderation
|
interrupt moderation mechanism are not supported yet.
|
||||||
mechanism are not supported yet.
|
|
||||||
.Pp
|
.Pp
|
||||||
The
|
The
|
||||||
.Nm
|
.Nm
|
||||||
|
@ -134,6 +134,7 @@ in the hardware is limited to the following devices:
|
|||||||
.Xr msk 4 ,
|
.Xr msk 4 ,
|
||||||
.Xr nge 4 ,
|
.Xr nge 4 ,
|
||||||
.Xr re 4 ,
|
.Xr re 4 ,
|
||||||
|
.Xr sge 4 ,
|
||||||
.Xr stge 4 ,
|
.Xr stge 4 ,
|
||||||
.Xr ti 4 ,
|
.Xr ti 4 ,
|
||||||
.Xr txp 4 ,
|
.Xr txp 4 ,
|
||||||
@ -172,7 +173,6 @@ natively:
|
|||||||
.Xr nve 4 ,
|
.Xr nve 4 ,
|
||||||
.Xr rl 4 ,
|
.Xr rl 4 ,
|
||||||
.Xr sf 4 ,
|
.Xr sf 4 ,
|
||||||
.Xr sge 4 ,
|
|
||||||
.Xr sis 4 ,
|
.Xr sis 4 ,
|
||||||
.Xr sk 4 ,
|
.Xr sk 4 ,
|
||||||
.Xr ste 4 ,
|
.Xr ste 4 ,
|
||||||
|
@ -25,11 +25,11 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd March 29, 2010
|
.Dd April 28, 2010
|
||||||
.Dt NET80211 9
|
.Dt IEEE80211 9
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
.Nm net80211
|
.Nm IEEE80211
|
||||||
.Nd 802.11 network layer
|
.Nd 802.11 network layer
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.In net80211/ieee80211_var.h
|
.In net80211/ieee80211_var.h
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd March 29, 2010
|
.Dd April 28, 2010
|
||||||
.Dt IEEE80211_NODE 9
|
.Dt IEEE80211_NODE 9
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -152,7 +152,7 @@ displays the contents of a single node while
|
|||||||
.Fn ieee80211_dump_nodes
|
.Fn ieee80211_dump_nodes
|
||||||
displays the contents of the specified node table.
|
displays the contents of the specified node table.
|
||||||
Nodes may also be displayed using
|
Nodes may also be displayed using
|
||||||
.Xr ddb 9
|
.Xr ddb 4
|
||||||
with the
|
with the
|
||||||
.Dq show node
|
.Dq show node
|
||||||
directive and the station node table can be displayed with
|
directive and the station node table can be displayed with
|
||||||
|
@ -50,14 +50,14 @@
|
|||||||
.bss
|
.bss
|
||||||
.globl dtrace_invop_jump_addr
|
.globl dtrace_invop_jump_addr
|
||||||
.align 8
|
.align 8
|
||||||
.type dtrace_invop_jump_addr, @object
|
.type dtrace_invop_jump_addr,@object
|
||||||
.size dtrace_invop_jump_addr, 8
|
.size dtrace_invop_jump_addr,8
|
||||||
dtrace_invop_jump_addr:
|
dtrace_invop_jump_addr:
|
||||||
.zero 8
|
.zero 8
|
||||||
.globl dtrace_invop_calltrap_addr
|
.globl dtrace_invop_calltrap_addr
|
||||||
.align 8
|
.align 8
|
||||||
.type dtrace_invop_calltrap_addr, @object
|
.type dtrace_invop_calltrap_addr,@object
|
||||||
.size dtrace_invop_calltrap_addr, 8
|
.size dtrace_invop_calltrap_addr,8
|
||||||
dtrace_invop_calltrap_addr:
|
dtrace_invop_calltrap_addr:
|
||||||
.zero 8
|
.zero 8
|
||||||
#endif
|
#endif
|
||||||
@ -157,7 +157,6 @@ IDTVEC(align)
|
|||||||
* kernel from userland. Reenable interrupts if they were enabled
|
* kernel from userland. Reenable interrupts if they were enabled
|
||||||
* before the trap. This approximates SDT_SYS386TGT on the i386 port.
|
* before the trap. This approximates SDT_SYS386TGT on the i386 port.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SUPERALIGN_TEXT
|
SUPERALIGN_TEXT
|
||||||
.globl alltraps
|
.globl alltraps
|
||||||
.type alltraps,@function
|
.type alltraps,@function
|
||||||
@ -211,16 +210,16 @@ alltraps_pushregs_no_rdi:
|
|||||||
* Set our jump address for the jump back in the event that
|
* Set our jump address for the jump back in the event that
|
||||||
* the breakpoint wasn't caused by DTrace at all.
|
* the breakpoint wasn't caused by DTrace at all.
|
||||||
*/
|
*/
|
||||||
movq $calltrap, dtrace_invop_calltrap_addr(%rip)
|
movq $calltrap,dtrace_invop_calltrap_addr(%rip)
|
||||||
|
|
||||||
/* Jump to the code hooked in by DTrace. */
|
/* Jump to the code hooked in by DTrace. */
|
||||||
movq dtrace_invop_jump_addr, %rax
|
movq dtrace_invop_jump_addr,%rax
|
||||||
jmpq *dtrace_invop_jump_addr
|
jmpq *dtrace_invop_jump_addr
|
||||||
#endif
|
#endif
|
||||||
.globl calltrap
|
.globl calltrap
|
||||||
.type calltrap,@function
|
.type calltrap,@function
|
||||||
calltrap:
|
calltrap:
|
||||||
movq %rsp, %rdi
|
movq %rsp,%rdi
|
||||||
call trap
|
call trap
|
||||||
MEXITCOUNT
|
MEXITCOUNT
|
||||||
jmp doreti /* Handle any pending ASTs */
|
jmp doreti /* Handle any pending ASTs */
|
||||||
@ -274,9 +273,11 @@ IDTVEC(dblfault)
|
|||||||
testb $SEL_RPL_MASK,TF_CS(%rsp) /* Did we come from kernel? */
|
testb $SEL_RPL_MASK,TF_CS(%rsp) /* Did we come from kernel? */
|
||||||
jz 1f /* already running with kernel GS.base */
|
jz 1f /* already running with kernel GS.base */
|
||||||
swapgs
|
swapgs
|
||||||
1: movq %rsp, %rdi
|
1:
|
||||||
|
movq %rsp,%rdi
|
||||||
call dblfault_handler
|
call dblfault_handler
|
||||||
2: hlt
|
2:
|
||||||
|
hlt
|
||||||
jmp 2b
|
jmp 2b
|
||||||
|
|
||||||
IDTVEC(page)
|
IDTVEC(page)
|
||||||
@ -369,7 +370,7 @@ IDTVEC(fast_syscall)
|
|||||||
movq %r15,TF_R15(%rsp) /* C preserved */
|
movq %r15,TF_R15(%rsp) /* C preserved */
|
||||||
movl $TF_HASSEGS,TF_FLAGS(%rsp)
|
movl $TF_HASSEGS,TF_FLAGS(%rsp)
|
||||||
FAKE_MCOUNT(TF_RIP(%rsp))
|
FAKE_MCOUNT(TF_RIP(%rsp))
|
||||||
movq %rsp, %rdi
|
movq %rsp,%rdi
|
||||||
call syscall
|
call syscall
|
||||||
movq PCPU(CURPCB),%rax
|
movq PCPU(CURPCB),%rax
|
||||||
andq $~PCB_FULLCTX,PCB_FLAGS(%rax)
|
andq $~PCB_FULLCTX,PCB_FLAGS(%rax)
|
||||||
@ -456,7 +457,7 @@ nmi_fromuserspace:
|
|||||||
/* Note: this label is also used by ddb and gdb: */
|
/* Note: this label is also used by ddb and gdb: */
|
||||||
nmi_calltrap:
|
nmi_calltrap:
|
||||||
FAKE_MCOUNT(TF_RIP(%rsp))
|
FAKE_MCOUNT(TF_RIP(%rsp))
|
||||||
movq %rsp, %rdi
|
movq %rsp,%rdi
|
||||||
call trap
|
call trap
|
||||||
MEXITCOUNT
|
MEXITCOUNT
|
||||||
#ifdef HWPMC_HOOKS
|
#ifdef HWPMC_HOOKS
|
||||||
@ -555,9 +556,9 @@ nmi_restoreregs:
|
|||||||
iretq
|
iretq
|
||||||
|
|
||||||
ENTRY(fork_trampoline)
|
ENTRY(fork_trampoline)
|
||||||
movq %r12, %rdi /* function */
|
movq %r12,%rdi /* function */
|
||||||
movq %rbx, %rsi /* arg1 */
|
movq %rbx,%rsi /* arg1 */
|
||||||
movq %rsp, %rdx /* trapframe pointer */
|
movq %rsp,%rdx /* trapframe pointer */
|
||||||
call fork_exit
|
call fork_exit
|
||||||
MEXITCOUNT
|
MEXITCOUNT
|
||||||
jmp doreti /* Handle any ASTs */
|
jmp doreti /* Handle any ASTs */
|
||||||
@ -628,7 +629,7 @@ doreti_ast:
|
|||||||
testl $TDF_ASTPENDING | TDF_NEEDRESCHED,TD_FLAGS(%rax)
|
testl $TDF_ASTPENDING | TDF_NEEDRESCHED,TD_FLAGS(%rax)
|
||||||
je doreti_exit
|
je doreti_exit
|
||||||
sti
|
sti
|
||||||
movq %rsp, %rdi /* pass a pointer to the trapframe */
|
movq %rsp,%rdi /* pass a pointer to the trapframe */
|
||||||
call ast
|
call ast
|
||||||
jmp doreti_ast
|
jmp doreti_ast
|
||||||
|
|
||||||
@ -648,8 +649,8 @@ doreti_exit:
|
|||||||
* Do not reload segment registers for kernel.
|
* Do not reload segment registers for kernel.
|
||||||
* Since we do not reload segments registers with sane
|
* Since we do not reload segments registers with sane
|
||||||
* values on kernel entry, descriptors referenced by
|
* values on kernel entry, descriptors referenced by
|
||||||
* segments registers may be not valid. This is fatal
|
* segments registers might be not valid. This is fatal
|
||||||
* for the usermode, but is innocent for the kernel.
|
* for user mode, but is not a problem for the kernel.
|
||||||
*/
|
*/
|
||||||
testb $SEL_RPL_MASK,TF_CS(%rsp)
|
testb $SEL_RPL_MASK,TF_CS(%rsp)
|
||||||
jz ld_regs
|
jz ld_regs
|
||||||
@ -662,14 +663,16 @@ do_segs:
|
|||||||
/* Restore %fs and fsbase */
|
/* Restore %fs and fsbase */
|
||||||
movw TF_FS(%rsp),%ax
|
movw TF_FS(%rsp),%ax
|
||||||
.globl ld_fs
|
.globl ld_fs
|
||||||
ld_fs: movw %ax,%fs
|
ld_fs:
|
||||||
|
movw %ax,%fs
|
||||||
cmpw $KUF32SEL,%ax
|
cmpw $KUF32SEL,%ax
|
||||||
jne 1f
|
jne 1f
|
||||||
movl $MSR_FSBASE,%ecx
|
movl $MSR_FSBASE,%ecx
|
||||||
movl PCB_FSBASE(%r8),%eax
|
movl PCB_FSBASE(%r8),%eax
|
||||||
movl PCB_FSBASE+4(%r8),%edx
|
movl PCB_FSBASE+4(%r8),%edx
|
||||||
.globl ld_fsbase
|
.globl ld_fsbase
|
||||||
ld_fsbase: wrmsr
|
ld_fsbase:
|
||||||
|
wrmsr
|
||||||
1:
|
1:
|
||||||
/* Restore %gs and gsbase */
|
/* Restore %gs and gsbase */
|
||||||
movw TF_GS(%rsp),%si
|
movw TF_GS(%rsp),%si
|
||||||
@ -678,7 +681,8 @@ ld_fsbase: wrmsr
|
|||||||
movl $MSR_GSBASE,%ecx
|
movl $MSR_GSBASE,%ecx
|
||||||
rdmsr
|
rdmsr
|
||||||
.globl ld_gs
|
.globl ld_gs
|
||||||
ld_gs: movw %si,%gs
|
ld_gs:
|
||||||
|
movw %si,%gs
|
||||||
wrmsr
|
wrmsr
|
||||||
popfq
|
popfq
|
||||||
cmpw $KUG32SEL,%si
|
cmpw $KUG32SEL,%si
|
||||||
@ -687,12 +691,17 @@ ld_gs: movw %si,%gs
|
|||||||
movl PCB_GSBASE(%r8),%eax
|
movl PCB_GSBASE(%r8),%eax
|
||||||
movl PCB_GSBASE+4(%r8),%edx
|
movl PCB_GSBASE+4(%r8),%edx
|
||||||
.globl ld_gsbase
|
.globl ld_gsbase
|
||||||
ld_gsbase: wrmsr
|
ld_gsbase:
|
||||||
1: .globl ld_es
|
wrmsr
|
||||||
ld_es: movw TF_ES(%rsp),%es
|
1:
|
||||||
|
.globl ld_es
|
||||||
|
ld_es:
|
||||||
|
movw TF_ES(%rsp),%es
|
||||||
.globl ld_ds
|
.globl ld_ds
|
||||||
ld_ds: movw TF_DS(%rsp),%ds
|
ld_ds:
|
||||||
ld_regs:movq TF_RDI(%rsp),%rdi
|
movw TF_DS(%rsp),%ds
|
||||||
|
ld_regs:
|
||||||
|
movq TF_RDI(%rsp),%rdi
|
||||||
movq TF_RSI(%rsp),%rsi
|
movq TF_RSI(%rsp),%rsi
|
||||||
movq TF_RDX(%rsp),%rdx
|
movq TF_RDX(%rsp),%rdx
|
||||||
movq TF_RCX(%rsp),%rcx
|
movq TF_RCX(%rsp),%rcx
|
||||||
@ -711,7 +720,8 @@ ld_regs:movq TF_RDI(%rsp),%rdi
|
|||||||
jz 1f /* keep running with kernel GS.base */
|
jz 1f /* keep running with kernel GS.base */
|
||||||
cli
|
cli
|
||||||
swapgs
|
swapgs
|
||||||
1: addq $TF_RIP,%rsp /* skip over tf_err, tf_trapno */
|
1:
|
||||||
|
addq $TF_RIP,%rsp /* skip over tf_err, tf_trapno */
|
||||||
.globl doreti_iret
|
.globl doreti_iret
|
||||||
doreti_iret:
|
doreti_iret:
|
||||||
iretq
|
iretq
|
||||||
@ -738,7 +748,8 @@ doreti_iret_fault:
|
|||||||
testl $PSL_I,TF_RFLAGS(%rsp)
|
testl $PSL_I,TF_RFLAGS(%rsp)
|
||||||
jz 1f
|
jz 1f
|
||||||
sti
|
sti
|
||||||
1: movw %fs,TF_FS(%rsp)
|
1:
|
||||||
|
movw %fs,TF_FS(%rsp)
|
||||||
movw %gs,TF_GS(%rsp)
|
movw %gs,TF_GS(%rsp)
|
||||||
movw %es,TF_ES(%rsp)
|
movw %es,TF_ES(%rsp)
|
||||||
movw %ds,TF_DS(%rsp)
|
movw %ds,TF_DS(%rsp)
|
||||||
@ -768,7 +779,7 @@ doreti_iret_fault:
|
|||||||
.globl ds_load_fault
|
.globl ds_load_fault
|
||||||
ds_load_fault:
|
ds_load_fault:
|
||||||
movl $T_PROTFLT,TF_TRAPNO(%rsp)
|
movl $T_PROTFLT,TF_TRAPNO(%rsp)
|
||||||
movq %rsp, %rdi
|
movq %rsp,%rdi
|
||||||
call trap
|
call trap
|
||||||
movw $KUDSEL,TF_DS(%rsp)
|
movw $KUDSEL,TF_DS(%rsp)
|
||||||
jmp doreti
|
jmp doreti
|
||||||
@ -777,7 +788,7 @@ ds_load_fault:
|
|||||||
.globl es_load_fault
|
.globl es_load_fault
|
||||||
es_load_fault:
|
es_load_fault:
|
||||||
movl $T_PROTFLT,TF_TRAPNO(%rsp)
|
movl $T_PROTFLT,TF_TRAPNO(%rsp)
|
||||||
movq %rsp, %rdi
|
movq %rsp,%rdi
|
||||||
call trap
|
call trap
|
||||||
movw $KUDSEL,TF_ES(%rsp)
|
movw $KUDSEL,TF_ES(%rsp)
|
||||||
jmp doreti
|
jmp doreti
|
||||||
@ -786,7 +797,7 @@ es_load_fault:
|
|||||||
.globl fs_load_fault
|
.globl fs_load_fault
|
||||||
fs_load_fault:
|
fs_load_fault:
|
||||||
movl $T_PROTFLT,TF_TRAPNO(%rsp)
|
movl $T_PROTFLT,TF_TRAPNO(%rsp)
|
||||||
movq %rsp, %rdi
|
movq %rsp,%rdi
|
||||||
call trap
|
call trap
|
||||||
movw $KUF32SEL,TF_FS(%rsp)
|
movw $KUF32SEL,TF_FS(%rsp)
|
||||||
jmp doreti
|
jmp doreti
|
||||||
@ -796,7 +807,7 @@ fs_load_fault:
|
|||||||
gs_load_fault:
|
gs_load_fault:
|
||||||
popfq
|
popfq
|
||||||
movl $T_PROTFLT,TF_TRAPNO(%rsp)
|
movl $T_PROTFLT,TF_TRAPNO(%rsp)
|
||||||
movq %rsp, %rdi
|
movq %rsp,%rdi
|
||||||
call trap
|
call trap
|
||||||
movw $KUG32SEL,TF_GS(%rsp)
|
movw $KUG32SEL,TF_GS(%rsp)
|
||||||
jmp doreti
|
jmp doreti
|
||||||
@ -805,7 +816,7 @@ gs_load_fault:
|
|||||||
.globl fsbase_load_fault
|
.globl fsbase_load_fault
|
||||||
fsbase_load_fault:
|
fsbase_load_fault:
|
||||||
movl $T_PROTFLT,TF_TRAPNO(%rsp)
|
movl $T_PROTFLT,TF_TRAPNO(%rsp)
|
||||||
movq %rsp, %rdi
|
movq %rsp,%rdi
|
||||||
call trap
|
call trap
|
||||||
movq PCPU(CURTHREAD),%r8
|
movq PCPU(CURTHREAD),%r8
|
||||||
movq TD_PCB(%r8),%r8
|
movq TD_PCB(%r8),%r8
|
||||||
@ -816,7 +827,7 @@ fsbase_load_fault:
|
|||||||
.globl gsbase_load_fault
|
.globl gsbase_load_fault
|
||||||
gsbase_load_fault:
|
gsbase_load_fault:
|
||||||
movl $T_PROTFLT,TF_TRAPNO(%rsp)
|
movl $T_PROTFLT,TF_TRAPNO(%rsp)
|
||||||
movq %rsp, %rdi
|
movq %rsp,%rdi
|
||||||
call trap
|
call trap
|
||||||
movq PCPU(CURTHREAD),%r8
|
movq PCPU(CURTHREAD),%r8
|
||||||
movq TD_PCB(%r8),%r8
|
movq TD_PCB(%r8),%r8
|
||||||
|
@ -240,7 +240,7 @@ printcpuinfo(void)
|
|||||||
printf("\n Features2=0x%b", cpu_feature2,
|
printf("\n Features2=0x%b", cpu_feature2,
|
||||||
"\020"
|
"\020"
|
||||||
"\001SSE3" /* SSE3 */
|
"\001SSE3" /* SSE3 */
|
||||||
"\002<b1>"
|
"\002PCLMULQDQ" /* Carry-Less Mul Quadword */
|
||||||
"\003DTES64" /* 64-bit Debug Trace */
|
"\003DTES64" /* 64-bit Debug Trace */
|
||||||
"\004MON" /* MONITOR/MWAIT Instructions */
|
"\004MON" /* MONITOR/MWAIT Instructions */
|
||||||
"\005DS_CPL" /* CPL Qualified Debug Store */
|
"\005DS_CPL" /* CPL Qualified Debug Store */
|
||||||
@ -264,7 +264,7 @@ printcpuinfo(void)
|
|||||||
"\027MOVBE"
|
"\027MOVBE"
|
||||||
"\030POPCNT"
|
"\030POPCNT"
|
||||||
"\031<b24>"
|
"\031<b24>"
|
||||||
"\032<b25>"
|
"\032AESNI" /* AES Crypto*/
|
||||||
"\033XSAVE"
|
"\033XSAVE"
|
||||||
"\034OSXSAVE"
|
"\034OSXSAVE"
|
||||||
"\035<b28>"
|
"\035<b28>"
|
||||||
|
@ -28,60 +28,32 @@
|
|||||||
__FBSDID("$FreeBSD$");
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/conf.h>
|
|
||||||
#include <sys/fcntl.h>
|
|
||||||
#include <sys/lock.h>
|
|
||||||
#include <sys/malloc.h>
|
|
||||||
#include <sys/mutex.h>
|
|
||||||
#include <sys/priv.h>
|
|
||||||
#include <sys/proc.h>
|
#include <sys/proc.h>
|
||||||
#include <sys/signalvar.h>
|
|
||||||
#include <sys/systm.h>
|
|
||||||
|
|
||||||
#include <machine/db_machdep.h>
|
|
||||||
#include <machine/frame.h>
|
#include <machine/frame.h>
|
||||||
#include <machine/psl.h>
|
|
||||||
#include <machine/specialreg.h>
|
|
||||||
|
|
||||||
#include <vm/vm.h>
|
|
||||||
#include <vm/pmap.h>
|
|
||||||
|
|
||||||
#include <machine/iodev.h>
|
#include <machine/iodev.h>
|
||||||
|
#include <machine/psl.h>
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
int
|
int
|
||||||
ioopen(struct cdev *dev __unused, int flags __unused, int fmt __unused,
|
iodev_open(struct thread *td)
|
||||||
struct thread *td)
|
|
||||||
{
|
{
|
||||||
int error;
|
|
||||||
|
|
||||||
error = priv_check(td, PRIV_IO);
|
|
||||||
if (error != 0)
|
|
||||||
return (error);
|
|
||||||
error = securelevel_gt(td->td_ucred, 0);
|
|
||||||
if (error != 0)
|
|
||||||
return (error);
|
|
||||||
|
|
||||||
td->td_frame->tf_rflags |= PSL_IOPL;
|
td->td_frame->tf_rflags |= PSL_IOPL;
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
int
|
int
|
||||||
ioclose(struct cdev *dev __unused, int flags __unused, int fmt __unused,
|
iodev_close(struct thread *td)
|
||||||
struct thread *td)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
td->td_frame->tf_rflags &= ~PSL_IOPL;
|
td->td_frame->tf_rflags &= ~PSL_IOPL;
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
int
|
int
|
||||||
ioioctl(struct cdev *dev __unused, u_long cmd __unused, caddr_t data __unused,
|
iodev_ioctl(u_long cmd __unused, caddr_t data __unused)
|
||||||
int fflag __unused, struct thread *td __unused)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
return (ENXIO);
|
return (ENOIOCTL);
|
||||||
}
|
}
|
||||||
|
@ -793,7 +793,6 @@ static u_long pmap_pdpe_demotions;
|
|||||||
SYSCTL_ULONG(_vm_pmap_pdpe, OID_AUTO, demotions, CTLFLAG_RD,
|
SYSCTL_ULONG(_vm_pmap_pdpe, OID_AUTO, demotions, CTLFLAG_RD,
|
||||||
&pmap_pdpe_demotions, 0, "1GB page demotions");
|
&pmap_pdpe_demotions, 0, "1GB page demotions");
|
||||||
|
|
||||||
|
|
||||||
/***************************************************
|
/***************************************************
|
||||||
* Low level helper routines.....
|
* Low level helper routines.....
|
||||||
***************************************************/
|
***************************************************/
|
||||||
@ -1200,15 +1199,20 @@ pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot)
|
|||||||
{
|
{
|
||||||
pd_entry_t pde, *pdep;
|
pd_entry_t pde, *pdep;
|
||||||
pt_entry_t pte;
|
pt_entry_t pte;
|
||||||
|
vm_paddr_t pa;
|
||||||
vm_page_t m;
|
vm_page_t m;
|
||||||
|
|
||||||
|
pa = 0;
|
||||||
m = NULL;
|
m = NULL;
|
||||||
vm_page_lock_queues();
|
|
||||||
PMAP_LOCK(pmap);
|
PMAP_LOCK(pmap);
|
||||||
|
retry:
|
||||||
pdep = pmap_pde(pmap, va);
|
pdep = pmap_pde(pmap, va);
|
||||||
if (pdep != NULL && (pde = *pdep)) {
|
if (pdep != NULL && (pde = *pdep)) {
|
||||||
if (pde & PG_PS) {
|
if (pde & PG_PS) {
|
||||||
if ((pde & PG_RW) || (prot & VM_PROT_WRITE) == 0) {
|
if ((pde & PG_RW) || (prot & VM_PROT_WRITE) == 0) {
|
||||||
|
if (vm_page_pa_tryrelock(pmap, (pde & PG_PS_FRAME) |
|
||||||
|
(va & PDRMASK), &pa))
|
||||||
|
goto retry;
|
||||||
m = PHYS_TO_VM_PAGE((pde & PG_PS_FRAME) |
|
m = PHYS_TO_VM_PAGE((pde & PG_PS_FRAME) |
|
||||||
(va & PDRMASK));
|
(va & PDRMASK));
|
||||||
vm_page_hold(m);
|
vm_page_hold(m);
|
||||||
@ -1217,12 +1221,14 @@ pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot)
|
|||||||
pte = *pmap_pde_to_pte(pdep, va);
|
pte = *pmap_pde_to_pte(pdep, va);
|
||||||
if ((pte & PG_V) &&
|
if ((pte & PG_V) &&
|
||||||
((pte & PG_RW) || (prot & VM_PROT_WRITE) == 0)) {
|
((pte & PG_RW) || (prot & VM_PROT_WRITE) == 0)) {
|
||||||
|
if (vm_page_pa_tryrelock(pmap, pte & PG_FRAME, &pa))
|
||||||
|
goto retry;
|
||||||
m = PHYS_TO_VM_PAGE(pte & PG_FRAME);
|
m = PHYS_TO_VM_PAGE(pte & PG_FRAME);
|
||||||
vm_page_hold(m);
|
vm_page_hold(m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vm_page_unlock_queues();
|
PA_UNLOCK_COND(pa);
|
||||||
PMAP_UNLOCK(pmap);
|
PMAP_UNLOCK(pmap);
|
||||||
return (m);
|
return (m);
|
||||||
}
|
}
|
||||||
@ -3143,9 +3149,8 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_prot_t access, vm_page_t m,
|
|||||||
* In the case that a page table page is not
|
* In the case that a page table page is not
|
||||||
* resident, we are creating it here.
|
* resident, we are creating it here.
|
||||||
*/
|
*/
|
||||||
if (va < VM_MAXUSER_ADDRESS) {
|
if (va < VM_MAXUSER_ADDRESS)
|
||||||
mpte = pmap_allocpte(pmap, va, M_WAITOK);
|
mpte = pmap_allocpte(pmap, va, M_WAITOK);
|
||||||
}
|
|
||||||
|
|
||||||
pde = pmap_pde(pmap, va);
|
pde = pmap_pde(pmap, va);
|
||||||
if (pde != NULL && (*pde & PG_V) != 0) {
|
if (pde != NULL && (*pde & PG_V) != 0) {
|
||||||
@ -3393,7 +3398,7 @@ pmap_enter_object(pmap_t pmap, vm_offset_t start, vm_offset_t end,
|
|||||||
mpte);
|
mpte);
|
||||||
m = TAILQ_NEXT(m, listq);
|
m = TAILQ_NEXT(m, listq);
|
||||||
}
|
}
|
||||||
PMAP_UNLOCK(pmap);
|
PMAP_UNLOCK(pmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -172,52 +172,6 @@ SYSCTL_INT(_machdep, OID_AUTO, prot_fault_translation, CTLFLAG_RW,
|
|||||||
|
|
||||||
extern char *syscallnames[];
|
extern char *syscallnames[];
|
||||||
|
|
||||||
/* #define DEBUG 1 */
|
|
||||||
#ifdef DEBUG
|
|
||||||
static void
|
|
||||||
report_seg_fault(const char *segn, struct trapframe *frame)
|
|
||||||
{
|
|
||||||
struct proc_ldt *pldt;
|
|
||||||
struct trapframe *pf;
|
|
||||||
|
|
||||||
pldt = curproc->p_md.md_ldt;
|
|
||||||
printf("%d: %s load fault %lx %p %d\n",
|
|
||||||
curproc->p_pid, segn, frame->tf_err,
|
|
||||||
pldt != NULL ? pldt->ldt_base : NULL,
|
|
||||||
pldt != NULL ? pldt->ldt_refcnt : 0);
|
|
||||||
kdb_backtrace();
|
|
||||||
pf = (struct trapframe *)frame->tf_rsp;
|
|
||||||
printf("rdi %lx\n", pf->tf_rdi);
|
|
||||||
printf("rsi %lx\n", pf->tf_rsi);
|
|
||||||
printf("rdx %lx\n", pf->tf_rdx);
|
|
||||||
printf("rcx %lx\n", pf->tf_rcx);
|
|
||||||
printf("r8 %lx\n", pf->tf_r8);
|
|
||||||
printf("r9 %lx\n", pf->tf_r9);
|
|
||||||
printf("rax %lx\n", pf->tf_rax);
|
|
||||||
printf("rbx %lx\n", pf->tf_rbx);
|
|
||||||
printf("rbp %lx\n", pf->tf_rbp);
|
|
||||||
printf("r10 %lx\n", pf->tf_r10);
|
|
||||||
printf("r11 %lx\n", pf->tf_r11);
|
|
||||||
printf("r12 %lx\n", pf->tf_r12);
|
|
||||||
printf("r13 %lx\n", pf->tf_r13);
|
|
||||||
printf("r14 %lx\n", pf->tf_r14);
|
|
||||||
printf("r15 %lx\n", pf->tf_r15);
|
|
||||||
printf("fs %x\n", pf->tf_fs);
|
|
||||||
printf("gs %x\n", pf->tf_gs);
|
|
||||||
printf("es %x\n", pf->tf_es);
|
|
||||||
printf("ds %x\n", pf->tf_ds);
|
|
||||||
printf("tno %x\n", pf->tf_trapno);
|
|
||||||
printf("adr %lx\n", pf->tf_addr);
|
|
||||||
printf("flg %x\n", pf->tf_flags);
|
|
||||||
printf("err %lx\n", pf->tf_err);
|
|
||||||
printf("rip %lx\n", pf->tf_rip);
|
|
||||||
printf("cs %lx\n", pf->tf_cs);
|
|
||||||
printf("rfl %lx\n", pf->tf_rflags);
|
|
||||||
printf("rsp %lx\n", pf->tf_rsp);
|
|
||||||
printf("ss %lx\n", pf->tf_ss);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Exception, fault, and trap interface to the FreeBSD kernel.
|
* Exception, fault, and trap interface to the FreeBSD kernel.
|
||||||
* This common code is called from assembly language IDT gate entry
|
* This common code is called from assembly language IDT gate entry
|
||||||
@ -314,9 +268,7 @@ trap(struct trapframe *frame)
|
|||||||
*/
|
*/
|
||||||
printf("kernel trap %d with interrupts disabled\n",
|
printf("kernel trap %d with interrupts disabled\n",
|
||||||
type);
|
type);
|
||||||
#ifdef DEBUG
|
|
||||||
report_seg_fault("hlt", frame);
|
|
||||||
#endif
|
|
||||||
/*
|
/*
|
||||||
* We shouldn't enable interrupts while holding a
|
* We shouldn't enable interrupts while holding a
|
||||||
* spin lock or servicing an NMI.
|
* spin lock or servicing an NMI.
|
||||||
@ -535,33 +487,21 @@ trap(struct trapframe *frame)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (frame->tf_rip == (long)ld_ds) {
|
if (frame->tf_rip == (long)ld_ds) {
|
||||||
#ifdef DEBUG
|
|
||||||
report_seg_fault("ds", frame);
|
|
||||||
#endif
|
|
||||||
frame->tf_rip = (long)ds_load_fault;
|
frame->tf_rip = (long)ds_load_fault;
|
||||||
frame->tf_ds = _udatasel;
|
frame->tf_ds = _udatasel;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (frame->tf_rip == (long)ld_es) {
|
if (frame->tf_rip == (long)ld_es) {
|
||||||
#ifdef DEBUG
|
|
||||||
report_seg_fault("es", frame);
|
|
||||||
#endif
|
|
||||||
frame->tf_rip = (long)es_load_fault;
|
frame->tf_rip = (long)es_load_fault;
|
||||||
frame->tf_es = _udatasel;
|
frame->tf_es = _udatasel;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (frame->tf_rip == (long)ld_fs) {
|
if (frame->tf_rip == (long)ld_fs) {
|
||||||
#ifdef DEBUG
|
|
||||||
report_seg_fault("fs", frame);
|
|
||||||
#endif
|
|
||||||
frame->tf_rip = (long)fs_load_fault;
|
frame->tf_rip = (long)fs_load_fault;
|
||||||
frame->tf_fs = _ufssel;
|
frame->tf_fs = _ufssel;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (frame->tf_rip == (long)ld_gs) {
|
if (frame->tf_rip == (long)ld_gs) {
|
||||||
#ifdef DEBUG
|
|
||||||
report_seg_fault("gs", frame);
|
|
||||||
#endif
|
|
||||||
frame->tf_rip = (long)gs_load_fault;
|
frame->tf_rip = (long)gs_load_fault;
|
||||||
frame->tf_gs = _ugssel;
|
frame->tf_gs = _ugssel;
|
||||||
goto out;
|
goto out;
|
||||||
@ -667,30 +607,6 @@ trap(struct trapframe *frame)
|
|||||||
ksi.ksi_addr = (void *)addr;
|
ksi.ksi_addr = (void *)addr;
|
||||||
trapsignal(td, &ksi);
|
trapsignal(td, &ksi);
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
{
|
|
||||||
register_t rg,rgk, rf;
|
|
||||||
|
|
||||||
if (type <= MAX_TRAP_MSG) {
|
|
||||||
uprintf("fatal process exception: %s",
|
|
||||||
trap_msg[type]);
|
|
||||||
if ((type == T_PAGEFLT) || (type == T_PROTFLT))
|
|
||||||
uprintf(", fault VA = 0x%lx", frame->tf_addr);
|
|
||||||
uprintf("\n");
|
|
||||||
}
|
|
||||||
rf = rdmsr(0xc0000100);
|
|
||||||
rg = rdmsr(0xc0000101);
|
|
||||||
rgk = rdmsr(0xc0000102);
|
|
||||||
uprintf("pid %d TRAP %d rip %lx err %lx addr %lx cs %lx ss %lx ds %x "
|
|
||||||
"es %x fs %x fsbase %lx %lx gs %x gsbase %lx %lx %lx\n",
|
|
||||||
curproc->p_pid, type, frame->tf_rip, frame->tf_err,
|
|
||||||
frame->tf_addr,
|
|
||||||
frame->tf_cs, frame->tf_ss, frame->tf_ds, frame->tf_es,
|
|
||||||
frame->tf_fs, td->td_pcb->pcb_fsbase, rf,
|
|
||||||
frame->tf_gs, td->td_pcb->pcb_gsbase, rg, rgk);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
user:
|
user:
|
||||||
userret(td, frame);
|
userret(td, frame);
|
||||||
mtx_assert(&Giant, MA_NOTOWNED);
|
mtx_assert(&Giant, MA_NOTOWNED);
|
||||||
|
@ -25,7 +25,22 @@
|
|||||||
*
|
*
|
||||||
* $FreeBSD$
|
* $FreeBSD$
|
||||||
*/
|
*/
|
||||||
|
#ifndef _MACHINE_IODEV_H_
|
||||||
|
#define _MACHINE_IODEV_H_
|
||||||
|
|
||||||
d_open_t ioopen;
|
#ifdef _KERNEL
|
||||||
d_close_t ioclose;
|
#include <machine/cpufunc.h>
|
||||||
d_ioctl_t ioioctl;
|
|
||||||
|
#define iodev_read_1 inb
|
||||||
|
#define iodev_read_2 inw
|
||||||
|
#define iodev_read_4 inl
|
||||||
|
#define iodev_write_1 outb
|
||||||
|
#define iodev_write_2 outw
|
||||||
|
#define iodev_write_4 outl
|
||||||
|
|
||||||
|
int iodev_open(struct thread *td);
|
||||||
|
int iodev_close(struct thread *td);
|
||||||
|
int iodev_ioctl(u_long cmd, caddr_t data);
|
||||||
|
|
||||||
|
#endif /* _KERNEL */
|
||||||
|
#endif /* _MACHINE_IODEV_H_ */
|
||||||
|
@ -245,6 +245,8 @@ struct pmap {
|
|||||||
pml4_entry_t *pm_pml4; /* KVA of level 4 page table */
|
pml4_entry_t *pm_pml4; /* KVA of level 4 page table */
|
||||||
TAILQ_HEAD(,pv_chunk) pm_pvchunk; /* list of mappings in pmap */
|
TAILQ_HEAD(,pv_chunk) pm_pvchunk; /* list of mappings in pmap */
|
||||||
u_int pm_active; /* active on cpus */
|
u_int pm_active; /* active on cpus */
|
||||||
|
uint32_t pm_gen_count; /* generation count (pmap lock dropped) */
|
||||||
|
u_int pm_retries;
|
||||||
/* spare u_int here due to padding */
|
/* spare u_int here due to padding */
|
||||||
struct pmap_statistics pm_stats; /* pmap statistics */
|
struct pmap_statistics pm_stats; /* pmap statistics */
|
||||||
vm_page_t pm_root; /* spare page table pages */
|
vm_page_t pm_root; /* spare page table pages */
|
||||||
|
@ -53,8 +53,8 @@ struct mdproc {
|
|||||||
struct system_segment_descriptor md_ldt_sd;
|
struct system_segment_descriptor md_ldt_sd;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define KINFO_PROC_SIZE 1088
|
#define KINFO_PROC_SIZE 1088
|
||||||
#define KINFO_PROC32_SIZE 768
|
#define KINFO_PROC32_SIZE 768
|
||||||
|
|
||||||
#ifdef _KERNEL
|
#ifdef _KERNEL
|
||||||
|
|
||||||
|
@ -113,6 +113,7 @@
|
|||||||
#define CPUID_PBE 0x80000000
|
#define CPUID_PBE 0x80000000
|
||||||
|
|
||||||
#define CPUID2_SSE3 0x00000001
|
#define CPUID2_SSE3 0x00000001
|
||||||
|
#define CPUID2_PCLMULQDQ 0x00000002
|
||||||
#define CPUID2_DTES64 0x00000004
|
#define CPUID2_DTES64 0x00000004
|
||||||
#define CPUID2_MON 0x00000008
|
#define CPUID2_MON 0x00000008
|
||||||
#define CPUID2_DS_CPL 0x00000010
|
#define CPUID2_DS_CPL 0x00000010
|
||||||
@ -131,6 +132,7 @@
|
|||||||
#define CPUID2_X2APIC 0x00200000
|
#define CPUID2_X2APIC 0x00200000
|
||||||
#define CPUID2_MOVBE 0x00400000
|
#define CPUID2_MOVBE 0x00400000
|
||||||
#define CPUID2_POPCNT 0x00800000
|
#define CPUID2_POPCNT 0x00800000
|
||||||
|
#define CPUID2_AESNI 0x02000000
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Important bits in the AMD extended cpuid flags
|
* Important bits in the AMD extended cpuid flags
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user