Update to FreeBSD head 2016-08-23

Git mirror commit 9fe7c416e6abb28b1398fd3e5687099846800cfd.
This commit is contained in:
Sebastian Huber
2016-10-07 15:10:20 +02:00
parent 8c0eebac7d
commit c40e45b75e
1040 changed files with 156866 additions and 67039 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,666 @@
/*
* Copyright (c) 2014-2015, Juniper Networks, Inc.
* All rights reserved.
* This SOFTWARE is licensed under the LICENSE provided in the
* ../Copyright file. By downloading, installing, copying, or otherwise
* using the SOFTWARE, you agree to be bound by the terms of that
* LICENSE.
* Phil Shafer, July 2014
*/
/**
* libxo provides a means of generating text, XML, JSON, and HTML output
* using a single set of function calls, maximizing the value of output
* while minimizing the cost/impact on the code.
*
* Full documentation is available in ./doc/libxo.txt or online at:
* http://juniper.github.io/libxo/libxo-manual.html
*/
#ifndef INCLUDE_XO_H
#define INCLUDE_XO_H
#include <stdio.h>
#include <sys/types.h>
#include <stdarg.h>
#include <stdlib.h>
#include <errno.h>
#ifdef __dead2
#define NORETURN __dead2
#else
#define NORETURN
#endif /* __dead2 */
/*
* Normally we'd use the HAVE_PRINTFLIKE define triggered by the
* --enable-printflike option to configure, but we don't install
* our internal "xoconfig.h", and I'd rather not. Taking the
* coward's path, we'll turn it on inside a #if that allows
* others to turn it off where needed. Not ideal, but functional.
*/
#if !defined(NO_PRINTFLIKE) && !defined(__linux__)
#define PRINTFLIKE(_x, _y) __printflike(_x, _y)
#else
#define PRINTFLIKE(_x, _y)
#endif /* NO_PRINTFLIKE */
/** Formatting types */
typedef unsigned short xo_style_t;
#define XO_STYLE_TEXT 0 /** Generate text output */
#define XO_STYLE_XML 1 /** Generate XML output */
#define XO_STYLE_JSON 2 /** Generate JSON output */
#define XO_STYLE_HTML 3 /** Generate HTML output */
#define XO_STYLE_SDPARAMS 4 /* Generate syslog structured data params */
#define XO_STYLE_ENCODER 5 /* Generate calls to external encoder */
/** Flags for libxo */
typedef unsigned long long xo_xof_flags_t;
#define XOF_BIT(_n) ((xo_xof_flags_t) 1 << (_n))
#define XOF_CLOSE_FP XOF_BIT(0) /** Close file pointer on xo_close() */
#define XOF_PRETTY XOF_BIT(1) /** Make 'pretty printed' output */
#define XOF_LOG_SYSLOG XOF_BIT(2) /** Log (on stderr) our syslog content */
#define XOF_RESV3 XOF_BIT(3) /* Unused */
#define XOF_WARN XOF_BIT(4) /** Generate warnings for broken calls */
#define XOF_XPATH XOF_BIT(5) /** Emit XPath attributes in HTML */
#define XOF_INFO XOF_BIT(6) /** Emit additional info fields (HTML) */
#define XOF_WARN_XML XOF_BIT(7) /** Emit warnings in XML (on stdout) */
#define XOF_NO_ENV XOF_BIT(8) /** Don't look at LIBXO_OPTIONS env var */
#define XOF_NO_VA_ARG XOF_BIT(9) /** Don't advance va_list w/ va_arg() */
#define XOF_DTRT XOF_BIT(10) /** Enable "do the right thing" mode */
#define XOF_KEYS XOF_BIT(11) /** Flag 'key' fields for xml and json */
#define XOF_IGNORE_CLOSE XOF_BIT(12) /** Ignore errors on close tags */
#define XOF_NOT_FIRST XOF_BIT(13) /* Not the first item (JSON) */
#define XOF_NO_LOCALE XOF_BIT(14) /** Don't bother with locale */
#define XOF_RESV15 XOF_BIT(15) /* Unused */
#define XOF_NO_TOP XOF_BIT(16) /** Don't emit the top braces in JSON */
#define XOF_RESV17 XOF_BIT(17) /* Unused */
#define XOF_UNITS XOF_BIT(18) /** Encode units in XML */
#define XOF_RESV19 XOF_BIT(19) /* Unused */
#define XOF_UNDERSCORES XOF_BIT(20) /** Replace dashes with underscores (JSON)*/
#define XOF_COLUMNS XOF_BIT(21) /** xo_emit should return a column count */
#define XOF_FLUSH XOF_BIT(22) /** Flush after each xo_emit call */
#define XOF_FLUSH_LINE XOF_BIT(23) /** Flush after each newline */
#define XOF_NO_CLOSE XOF_BIT(24) /** xo_finish won't close open elements */
#define XOF_COLOR_ALLOWED XOF_BIT(25) /** Allow color/effects to be enabled */
#define XOF_COLOR XOF_BIT(26) /** Enable color and effects */
#define XOF_NO_HUMANIZE XOF_BIT(27) /** Block the {h:} modifier */
#define XOF_LOG_GETTEXT XOF_BIT(28) /** Log (stderr) gettext lookup strings */
#define XOF_UTF8 XOF_BIT(29) /** Force text output to be UTF8 */
#define XOF_RETAIN_ALL XOF_BIT(30) /** Force use of XOEF_RETAIN */
#define XOF_RETAIN_NONE XOF_BIT(31) /** Prevent use of XOEF_RETAIN */
typedef unsigned xo_emit_flags_t; /* Flags to xo_emit() and friends */
#define XOEF_RETAIN (1<<0) /* Retain parsed formatting information */
/*
* The xo_info_t structure provides a mapping between names and
* additional data emitted via HTML.
*/
typedef struct xo_info_s {
const char *xi_name; /* Name of the element */
const char *xi_type; /* Type of field */
const char *xi_help; /* Description of field */
} xo_info_t;
#define XO_INFO_NULL NULL, NULL, NULL /* Use '{ XO_INFO_NULL }' to end lists */
struct xo_handle_s; /* Opaque structure forward */
typedef struct xo_handle_s xo_handle_t; /* Handle for XO output */
typedef int (*xo_write_func_t)(void *, const char *);
typedef void (*xo_close_func_t)(void *);
typedef int (*xo_flush_func_t)(void *);
typedef void *(*xo_realloc_func_t)(void *, size_t);
typedef void (*xo_free_func_t)(void *);
/*
* The formatter function mirrors "vsnprintf", with an additional argument
* of the xo handle. The caller should return the number of bytes _needed_
* to fit the data, even if this exceeds 'len'.
*/
typedef int (*xo_formatter_t)(xo_handle_t *, char *, int,
const char *, va_list);
typedef void (*xo_checkpointer_t)(xo_handle_t *, va_list, int);
xo_handle_t *
xo_create (xo_style_t style, xo_xof_flags_t flags);
xo_handle_t *
xo_create_to_file (FILE *fp, xo_style_t style, xo_xof_flags_t flags);
void
xo_destroy (xo_handle_t *xop);
void
xo_set_writer (xo_handle_t *xop, void *opaque, xo_write_func_t write_func,
xo_close_func_t close_func, xo_flush_func_t flush_func);
void
xo_set_allocator (xo_realloc_func_t realloc_func, xo_free_func_t free_func);
void
xo_set_style (xo_handle_t *xop, xo_style_t style);
xo_style_t
xo_get_style (xo_handle_t *xop);
int
xo_set_style_name (xo_handle_t *xop, const char *style);
int
xo_set_options (xo_handle_t *xop, const char *input);
xo_xof_flags_t
xo_get_flags (xo_handle_t *xop);
void
xo_set_flags (xo_handle_t *xop, xo_xof_flags_t flags);
void
xo_clear_flags (xo_handle_t *xop, xo_xof_flags_t flags);
int
xo_set_file_h (xo_handle_t *xop, FILE *fp);
int
xo_set_file (FILE *fp);
void
xo_set_info (xo_handle_t *xop, xo_info_t *infop, int count);
void
xo_set_formatter (xo_handle_t *xop, xo_formatter_t func, xo_checkpointer_t);
void
xo_set_depth (xo_handle_t *xop, int depth);
int
xo_emit_hv (xo_handle_t *xop, const char *fmt, va_list vap);
int
xo_emit_h (xo_handle_t *xop, const char *fmt, ...);
int
xo_emit (const char *fmt, ...);
int
xo_emit_hvf (xo_handle_t *xop, xo_emit_flags_t flags,
const char *fmt, va_list vap);
int
xo_emit_hf (xo_handle_t *xop, xo_emit_flags_t flags, const char *fmt, ...);
int
xo_emit_f (xo_emit_flags_t flags, const char *fmt, ...);
PRINTFLIKE(2, 0)
static inline int
xo_emit_hvp (xo_handle_t *xop, const char *fmt, va_list vap)
{
return xo_emit_hv(xop, fmt, vap);
}
PRINTFLIKE(2, 3)
static inline int
xo_emit_hp (xo_handle_t *xop, const char *fmt, ...)
{
va_list vap;
va_start(vap, fmt);
int rc = xo_emit_hv(xop, fmt, vap);
va_end(vap);
return rc;
}
PRINTFLIKE(1, 2)
static inline int
xo_emit_p (const char *fmt, ...)
{
va_list vap;
va_start(vap, fmt);
int rc = xo_emit_hv(NULL, fmt, vap);
va_end(vap);
return rc;
}
PRINTFLIKE(3, 0)
static inline int
xo_emit_hvfp (xo_handle_t *xop, xo_emit_flags_t flags,
const char *fmt, va_list vap)
{
return xo_emit_hvf(xop, flags, fmt, vap);
}
PRINTFLIKE(3, 4)
static inline int
xo_emit_hfp (xo_handle_t *xop, xo_emit_flags_t flags, const char *fmt, ...)
{
va_list vap;
va_start(vap, fmt);
int rc = xo_emit_hvf(xop, flags, fmt, vap);
va_end(vap);
return rc;
}
PRINTFLIKE(2, 3)
static inline int
xo_emit_fp (xo_emit_flags_t flags, const char *fmt, ...)
{
va_list vap;
va_start(vap, fmt);
int rc = xo_emit_hvf(NULL, flags, fmt, vap);
va_end(vap);
return rc;
}
int
xo_open_container_h (xo_handle_t *xop, const char *name);
int
xo_open_container (const char *name);
int
xo_open_container_hd (xo_handle_t *xop, const char *name);
int
xo_open_container_d (const char *name);
int
xo_close_container_h (xo_handle_t *xop, const char *name);
int
xo_close_container (const char *name);
int
xo_close_container_hd (xo_handle_t *xop);
int
xo_close_container_d (void);
int
xo_open_list_h (xo_handle_t *xop, const char *name);
int
xo_open_list (const char *name);
int
xo_open_list_hd (xo_handle_t *xop, const char *name);
int
xo_open_list_d (const char *name);
int
xo_close_list_h (xo_handle_t *xop, const char *name);
int
xo_close_list (const char *name);
int
xo_close_list_hd (xo_handle_t *xop);
int
xo_close_list_d (void);
int
xo_open_instance_h (xo_handle_t *xop, const char *name);
int
xo_open_instance (const char *name);
int
xo_open_instance_hd (xo_handle_t *xop, const char *name);
int
xo_open_instance_d (const char *name);
int
xo_close_instance_h (xo_handle_t *xop, const char *name);
int
xo_close_instance (const char *name);
int
xo_close_instance_hd (xo_handle_t *xop);
int
xo_close_instance_d (void);
int
xo_open_marker_h (xo_handle_t *xop, const char *name);
int
xo_open_marker (const char *name);
int
xo_close_marker_h (xo_handle_t *xop, const char *name);
int
xo_close_marker (const char *name);
int
xo_attr_h (xo_handle_t *xop, const char *name, const char *fmt, ...);
int
xo_attr_hv (xo_handle_t *xop, const char *name, const char *fmt, va_list vap);
int
xo_attr (const char *name, const char *fmt, ...);
void
xo_error_hv (xo_handle_t *xop, const char *fmt, va_list vap);
void
xo_error_h (xo_handle_t *xop, const char *fmt, ...);
void
xo_error (const char *fmt, ...);
int
xo_flush_h (xo_handle_t *xop);
int
xo_flush (void);
int
xo_finish_h (xo_handle_t *xop);
int
xo_finish (void);
void
xo_finish_atexit (void);
void
xo_set_leading_xpath (xo_handle_t *xop, const char *path);
void
xo_warn_hc (xo_handle_t *xop, int code, const char *fmt, ...) PRINTFLIKE(3, 4);
void
xo_warn_c (int code, const char *fmt, ...) PRINTFLIKE(2, 3);
void
xo_warn (const char *fmt, ...) PRINTFLIKE(1, 2);
void
xo_warnx (const char *fmt, ...) PRINTFLIKE(1, 2);
void
xo_err (int eval, const char *fmt, ...) NORETURN PRINTFLIKE(2, 3);
void
xo_errx (int eval, const char *fmt, ...) NORETURN PRINTFLIKE(2, 3);
void
xo_errc (int eval, int code, const char *fmt, ...) NORETURN PRINTFLIKE(3, 4);
void
xo_message_hcv (xo_handle_t *xop, int code, const char *fmt, va_list vap) PRINTFLIKE(3, 0);
void
xo_message_hc (xo_handle_t *xop, int code, const char *fmt, ...) PRINTFLIKE(3, 4);
void
xo_message_c (int code, const char *fmt, ...) PRINTFLIKE(2, 3);
void
xo_message_e (const char *fmt, ...) PRINTFLIKE(1, 2);
void
xo_message (const char *fmt, ...) PRINTFLIKE(1, 2);
void
xo_emit_warn_hcv (xo_handle_t *xop, int as_warning, int code,
const char *fmt, va_list vap);
void
xo_emit_warn_hc (xo_handle_t *xop, int code, const char *fmt, ...);
void
xo_emit_warn_c (int code, const char *fmt, ...);
void
xo_emit_warn (const char *fmt, ...);
void
xo_emit_warnx (const char *fmt, ...);
void
xo_emit_err (int eval, const char *fmt, ...) NORETURN;
void
xo_emit_errx (int eval, const char *fmt, ...) NORETURN;
void
xo_emit_errc (int eval, int code, const char *fmt, ...) NORETURN;
PRINTFLIKE(4, 0)
static inline void
xo_emit_warn_hcvp (xo_handle_t *xop, int as_warning, int code,
const char *fmt, va_list vap)
{
xo_emit_warn_hcv(xop, as_warning, code, fmt, vap);
}
PRINTFLIKE(3, 4)
static inline void
xo_emit_warn_hcp (xo_handle_t *xop, int code, const char *fmt, ...)
{
va_list vap;
va_start(vap, fmt);
xo_emit_warn_hcv(xop, 1, code, fmt, vap);
va_end(vap);
}
PRINTFLIKE(2, 3)
static inline void
xo_emit_warn_cp (int code, const char *fmt, ...)
{
va_list vap;
va_start(vap, fmt);
xo_emit_warn_hcv(NULL, 1, code, fmt, vap);
va_end(vap);
}
PRINTFLIKE(1, 2)
static inline void
xo_emit_warn_p (const char *fmt, ...)
{
int code = errno;
va_list vap;
va_start(vap, fmt);
xo_emit_warn_hcv(NULL, 1, code, fmt, vap);
va_end(vap);
}
PRINTFLIKE(1, 2)
static inline void
xo_emit_warnx_p (const char *fmt, ...)
{
va_list vap;
va_start(vap, fmt);
xo_emit_warn_hcv(NULL, 1, -1, fmt, vap);
va_end(vap);
}
NORETURN PRINTFLIKE(2, 3)
static inline void
xo_emit_err_p (int eval, const char *fmt, ...)
{
int code = errno;
va_list vap;
va_start(vap, fmt);
xo_emit_warn_hcv(NULL, 0, code, fmt, vap);
va_end(vap);
exit(eval);
}
PRINTFLIKE(2, 3)
static inline void
xo_emit_errx_p (int eval, const char *fmt, ...)
{
va_list vap;
va_start(vap, fmt);
xo_emit_warn_hcv(NULL, 0, -1, fmt, vap);
va_end(vap);
exit(eval);
}
PRINTFLIKE(3, 4)
static inline void
xo_emit_errc_p (int eval, int code, const char *fmt, ...)
{
va_list vap;
va_start(vap, fmt);
xo_emit_warn_hcv(NULL, 0, code, fmt, vap);
va_end(vap);
exit(eval);
}
void
xo_emit_err_v (int eval, int code, const char *fmt, va_list vap) NORETURN PRINTFLIKE(3, 0);
void
xo_no_setlocale (void);
/**
* @brief Lift libxo-specific arguments from a set of arguments
*
* libxo-enable programs typically use command line options to enable
* all the nifty-cool libxo features. xo_parse_args() makes this simple
* by pre-processing the command line arguments given to main(), handling
* and removing the libxo-specific ones, meaning anything starting with
* "--libxo". A full description of these arguments is in the base
* documentation.
* @param[in] argc Number of arguments (ala #main())
* @param[in] argc Array of argument strings (ala #main())
* @return New number of arguments, or -1 for failure.
*/
int
xo_parse_args (int argc, char **argv);
/**
* This is the "magic" number returned by libxo-supporting commands
* when passed the equally magic "--libxo-check" option. If you
* return this, we can (unsafely) assume that since you know the magic
* handshake, you'll happily handle future --libxo options and not do
* something violent like reboot the box or create another hole in the
* ozone layer.
*/
#define XO_HAS_LIBXO 121
/**
* externs for libxo's version number strings
*/
extern const char xo_version[]; /** Base version triple string */
extern const char xo_version_extra[]; /** Extra version magic content */
/**
* @brief Dump the internal stack of a libxo handle.
*
* This diagnostic function is something I will ask you to call from
* your program when you write to tell me libxo has gone bat-stink
* crazy and has discarded your list or container or content. Output
* content will be what we lovingly call "developer entertainment".
* @param[in] xop A valid libxo handle, or NULL for the default handle
*/
void
xo_dump_stack (xo_handle_t *xop);
/**
* @brief Recode the name of the program, suitable for error output.
*
* libxo will record the given name for use while generating error
* messages. The contents are not copied, so the value must continue
* to point to a valid memory location. This allows the caller to change
* the value, but requires the caller to manage the memory. Typically
* this is called with argv[0] from main().
* @param[in] name The name of the current application program
*/
void
xo_set_program (const char *name);
/**
* @brief Add a version string to the output, where possible.
*
* Adds a version number to the output, suitable for tracking
* changes in the content. This is only important for the "encoding"
* format styles (XML and JSON) and allows a user of the data to
* discern which version of the data model is in use.
* @param[in] version The version number, encoded as a string
*/
void
xo_set_version (const char *version);
/**
* #xo_set_version with a handle.
* @param[in] xop A valid libxo handle, or NULL for the default handle
* @param[in] version The version number, encoded as a string
*/
void
xo_set_version_h (xo_handle_t *xop, const char *version);
void
xo_open_log (const char *ident, int logopt, int facility);
void
xo_close_log (void);
int
xo_set_logmask (int maskpri);
void
xo_set_unit_test_mode (int value);
void
xo_syslog (int priority, const char *name, const char *message, ...);
void
xo_vsyslog (int priority, const char *name, const char *message, va_list args);
typedef void (*xo_syslog_open_t)(void);
typedef void (*xo_syslog_send_t)(const char *full_msg,
const char *v0_hdr, const char *text_only);
typedef void (*xo_syslog_close_t)(void);
void
xo_set_syslog_handler (xo_syslog_open_t open_func, xo_syslog_send_t send_func,
xo_syslog_close_t close_func);
void
xo_set_syslog_enterprise_id (unsigned short eid);
typedef void (*xo_simplify_field_func_t)(const char *, unsigned, int);
char *
xo_simplify_format (xo_handle_t *xop, const char *fmt, int with_numbers,
xo_simplify_field_func_t field_cb);
int
xo_emit_field_hv (xo_handle_t *xop, const char *rolmod, const char *contents,
const char *fmt, const char *efmt,
va_list vap);
int
xo_emit_field_h (xo_handle_t *xop, const char *rolmod, const char *contents,
const char *fmt, const char *efmt, ...);
int
xo_emit_field (const char *rolmod, const char *contents,
const char *fmt, const char *efmt, ...);
void
xo_retain_clear_all (void);
void
xo_retain_clear (const char *fmt);
#endif /* INCLUDE_XO_H */

View File

@@ -0,0 +1,158 @@
/*
* Copyright (c) 2015, Juniper Networks, Inc.
* All rights reserved.
* This SOFTWARE is licensed under the LICENSE provided in the
* ../Copyright file. By downloading, installing, copying, or otherwise
* using the SOFTWARE, you agree to be bound by the terms of that
* LICENSE.
* Phil Shafer, August 2015
*/
/*
* This file is an _internal_ part of the libxo plumbing, not suitable
* for external use. It is not considered part of the libxo API and
* will not be a stable part of that API. Mine, not your's, dude...
* The real hope is that something like this will become a standard part
* of libc and I can kill this off.
*/
#ifndef XO_BUF_H
#define XO_BUF_H
#define XO_BUFSIZ (8*1024) /* Initial buffer size */
#define XO_BUF_HIGH_WATER (XO_BUFSIZ - 512) /* When to auto-flush */
/*
* xo_buffer_t: a memory buffer that can be grown as needed. We
* use them for building format strings and output data.
*/
typedef struct xo_buffer_s {
char *xb_bufp; /* Buffer memory */
char *xb_curp; /* Current insertion point */
unsigned xb_size; /* Size of buffer */
} xo_buffer_t;
/*
* Initialize the contents of an xo_buffer_t.
*/
static inline void
xo_buf_init (xo_buffer_t *xbp)
{
xbp->xb_size = XO_BUFSIZ;
xbp->xb_bufp = xo_realloc(NULL, xbp->xb_size);
xbp->xb_curp = xbp->xb_bufp;
}
/*
* Reset the buffer to empty
*/
static inline void
xo_buf_reset (xo_buffer_t *xbp)
{
xbp->xb_curp = xbp->xb_bufp;
}
/*
* Return the number of bytes left in the buffer
*/
static inline int
xo_buf_left (xo_buffer_t *xbp)
{
return xbp->xb_size - (xbp->xb_curp - xbp->xb_bufp);
}
/*
* See if the buffer to empty
*/
static inline int
xo_buf_is_empty (xo_buffer_t *xbp)
{
return (xbp->xb_curp == xbp->xb_bufp);
}
/*
* Return the current offset
*/
static inline unsigned
xo_buf_offset (xo_buffer_t *xbp)
{
return xbp ? (xbp->xb_curp - xbp->xb_bufp) : 0;
}
static inline char *
xo_buf_data (xo_buffer_t *xbp, unsigned offset)
{
if (xbp == NULL)
return NULL;
return xbp->xb_bufp + offset;
}
static inline char *
xo_buf_cur (xo_buffer_t *xbp)
{
if (xbp == NULL)
return NULL;
return xbp->xb_curp;
}
/*
* Initialize the contents of an xo_buffer_t.
*/
static inline void
xo_buf_cleanup (xo_buffer_t *xbp)
{
if (xbp->xb_bufp)
xo_free(xbp->xb_bufp);
bzero(xbp, sizeof(*xbp));
}
/*
* Does the buffer have room for the given number of bytes of data?
* If not, realloc the buffer to make room. If that fails, we
* return 0 to tell the caller they are in trouble.
*/
static inline int
xo_buf_has_room (xo_buffer_t *xbp, int len)
{
if (xbp->xb_curp + len >= xbp->xb_bufp + xbp->xb_size) {
int sz = xbp->xb_size + XO_BUFSIZ;
char *bp = xo_realloc(xbp->xb_bufp, sz);
if (bp == NULL)
return 0;
xbp->xb_curp = bp + (xbp->xb_curp - xbp->xb_bufp);
xbp->xb_bufp = bp;
xbp->xb_size = sz;
}
return 1;
}
/*
* Append the given string to the given buffer
*/
static inline void
xo_buf_append (xo_buffer_t *xbp, const char *str, int len)
{
if (!xo_buf_has_room(xbp, len))
return;
memcpy(xbp->xb_curp, str, len);
xbp->xb_curp += len;
}
/*
* Append the given NUL-terminated string to the given buffer
*/
static inline void
xo_buf_append_str (xo_buffer_t *xbp, const char *str)
{
int len = strlen(str);
if (!xo_buf_has_room(xbp, len))
return;
memcpy(xbp->xb_curp, str, len);
xbp->xb_curp += len;
}
#endif /* XO_BUF_H */

View File

@@ -0,0 +1,254 @@
/* $FreeBSD$ */
/* libxo/xo_config.h. Generated from xo_config.h.in by configure. */
/* libxo/xo_config.h.in. Generated from configure.ac by autoheader. */
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
systems. This function is required for `alloca.c' support on those systems.
*/
/* #undef CRAY_STACKSEG_END */
/* Define to 1 if using `alloca.c'. */
/* #undef C_ALLOCA */
/* Define to 1 if you have `alloca', as a function or macro. */
#define HAVE_ALLOCA 1
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
*/
/* #undef HAVE_ALLOCA_H */
/* Define to 1 if you have the `asprintf' function. */
#define HAVE_ASPRINTF 1
/* Define to 1 if you have the `bzero' function. */
#define HAVE_BZERO 1
/* Define to 1 if you have the `ctime' function. */
#define HAVE_CTIME 1
/* Define to 1 if you have the <ctype.h> header file. */
#define HAVE_CTYPE_H 1
/* Define to 1 if you have the declaration of `__isthreaded', and to 0 if you
don't. */
#define HAVE_DECL___ISTHREADED 1
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define to 1 if you have the `dlfunc' function. */
#define HAVE_DLFUNC 1
/* Define to 1 if you have the <errno.h> header file. */
#define HAVE_ERRNO_H 1
/* Define to 1 if you have the `fdopen' function. */
#define HAVE_FDOPEN 1
/* Define to 1 if you have the `flock' function. */
#define HAVE_FLOCK 1
/* Define to 1 if you have the `getpass' function. */
#define HAVE_GETPASS 1
/* Define to 1 if you have the `getprogname' function. */
#define HAVE_GETPROGNAME 1
/* Define to 1 if you have the `getrusage' function. */
#define HAVE_GETRUSAGE 1
/* gettext(3) */
/* #undef HAVE_GETTEXT */
/* Define to 1 if you have the `gettimeofday' function. */
#define HAVE_GETTIMEOFDAY 1
/* humanize_number(3) */
#define HAVE_HUMANIZE_NUMBER 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the `crypto' library (-lcrypto). */
#define HAVE_LIBCRYPTO 1
/* Define to 1 if you have the `m' library (-lm). */
#define HAVE_LIBM 1
/* Define to 1 if you have the <libutil.h> header file. */
#define HAVE_LIBUTIL_H 1
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
to 0 otherwise. */
#define HAVE_MALLOC 1
/* Define to 1 if you have the `memmove' function. */
#define HAVE_MEMMOVE 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the <monitor.h> header file. */
/* #undef HAVE_MONITOR_H */
/* Support printflike */
/* #undef HAVE_PRINTFLIKE */
/* Define to 1 if your system has a GNU libc compatible `realloc' function,
and to 0 otherwise. */
#define HAVE_REALLOC 1
/* Define to 1 if you have the `srand' function. */
#define HAVE_SRAND 1
/* Define to 1 if you have the `sranddev' function. */
#define HAVE_SRANDDEV 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdio_ext.h> header file. */
/* #undef HAVE_STDIO_EXT_H */
/* Define to 1 if you have the <stdio.h> header file. */
#define HAVE_STDIO_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <stdtime/tzfile.h> header file. */
/* #undef HAVE_STDTIME_TZFILE_H */
/* Define to 1 if you have the `strchr' function. */
#define HAVE_STRCHR 1
/* Define to 1 if you have the `strcspn' function. */
#define HAVE_STRCSPN 1
/* Define to 1 if you have the `strerror' function. */
#define HAVE_STRERROR 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the `strlcpy' function. */
#define HAVE_STRLCPY 1
/* Define to 1 if you have the `strspn' function. */
#define HAVE_STRSPN 1
/* Have struct sockaddr_un.sun_len */
#define HAVE_SUN_LEN 1
/* Define to 1 if you have the `sysctlbyname' function. */
#define HAVE_SYSCTLBYNAME 1
/* Define to 1 if you have the <sys/param.h> header file. */
#define HAVE_SYS_PARAM_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/sysctl.h> header file. */
#define HAVE_SYS_SYSCTL_H 1
/* Define to 1 if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <threads.h> header file. */
#define HAVE_THREADS_H 1
/* thread-local setting */
#define HAVE_THREAD_LOCAL THREAD_LOCAL_before
/* Define to 1 if you have the <tzfile.h> header file. */
/* #undef HAVE_TZFILE_H */
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if you have the `__flbf' function. */
/* #undef HAVE___FLBF */
/* Enable debugging */
/* #undef LIBXO_DEBUG */
/* Enable text-only rendering */
/* #undef LIBXO_TEXT_ONLY */
/* Version number as dotted value */
#define LIBXO_VERSION "0.6.2"
/* Version number extra information */
#define LIBXO_VERSION_EXTRA ""
/* Version number as a number */
#define LIBXO_VERSION_NUMBER 6002
/* Version number as string */
#define LIBXO_VERSION_STRING "6002"
/* Enable local wcwidth implementation */
#define LIBXO_WCWIDTH 1
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#define LT_OBJDIR ".libs/"
/* Name of package */
#define PACKAGE "libxo"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "phil@juniper.net"
/* Define to the full name of this package. */
#define PACKAGE_NAME "libxo"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "libxo 0.6.2"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libxo"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "0.6.2"
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at runtime.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown */
/* #undef STACK_DIRECTION */
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Version number of package */
#define VERSION "0.6.2"
/* Retain hash bucket size */
/* #undef XO_RETAIN_SIZE */
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
/* #undef inline */
#endif
/* Define to rpl_malloc if the replacement function should be used. */
/* #undef malloc */
/* Define to rpl_realloc if the replacement function should be used. */
/* #undef realloc */
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */

View File

@@ -0,0 +1,435 @@
#include <machine/rtems-bsd-user-space.h>
/*
* Copyright (c) 2015, Juniper Networks, Inc.
* All rights reserved.
* This SOFTWARE is licensed under the LICENSE provided in the
* ../Copyright file. By downloading, installing, copying, or otherwise
* using the SOFTWARE, you agree to be bound by the terms of that
* LICENSE.
* Phil Shafer, August 2015
*/
#ifndef __rtems__
/**
* libxo includes a number of fixed encoding styles. But other
* external encoders are need to deal with new encoders. Rather
* than expose a swarm of libxo internals, we create a distinct
* API, with a simpler API than we use internally.
*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/queue.h>
#include <rtems/bsd/sys/param.h>
#include <dlfcn.h>
#include "xo_config.h"
#include "xo.h"
#include "xo_encoder.h"
#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
#if !defined(HAVE_DLFUNC)
#define dlfunc(_p, _n) dlsym(_p, _n)
#endif
#else /* HAVE_DLFCN_H */
#define dlopen(_n, _f) NULL /* Fail */
#define dlsym(_p, _n) NULL /* Fail */
#define dlfunc(_p, _n) NULL /* Fail */
#endif /* HAVE_DLFCN_H */
static void xo_encoder_setup (void); /* Forward decl */
/*
* Need a simple string collection
*/
typedef struct xo_string_node_s {
TAILQ_ENTRY(xo_string_node_s) xs_link; /* Next string */
char xs_data[0]; /* String data */
} xo_string_node_t;
typedef TAILQ_HEAD(xo_string_list_s, xo_string_node_s) xo_string_list_t;
static inline void
xo_string_list_init (xo_string_list_t *listp)
{
if (listp->tqh_last == NULL)
TAILQ_INIT(listp);
}
static inline xo_string_node_t *
xo_string_add (xo_string_list_t *listp, const char *str)
{
if (listp == NULL || str == NULL)
return NULL;
xo_string_list_init(listp);
size_t len = strlen(str);
xo_string_node_t *xsp;
xsp = xo_realloc(NULL, sizeof(*xsp) + len + 1);
if (xsp) {
memcpy(xsp->xs_data, str, len);
xsp->xs_data[len] = '\0';
TAILQ_INSERT_TAIL(listp, xsp, xs_link);
}
return xsp;
}
#define XO_STRING_LIST_FOREACH(_xsp, _listp) \
xo_string_list_init(_listp); \
TAILQ_FOREACH(_xsp, _listp, xs_link)
static inline void
xo_string_list_clean (xo_string_list_t *listp)
{
xo_string_node_t *xsp;
xo_string_list_init(listp);
for (;;) {
xsp = TAILQ_FIRST(listp);
if (xsp == NULL)
break;
TAILQ_REMOVE(listp, xsp, xs_link);
xo_free(xsp);
}
}
static xo_string_list_t xo_encoder_path;
void
xo_encoder_path_add (const char *path)
{
xo_encoder_setup();
if (path)
xo_string_add(&xo_encoder_path, path);
}
/* ---------------------------------------------------------------------- */
typedef struct xo_encoder_node_s {
TAILQ_ENTRY(xo_encoder_node_s) xe_link; /* Next session */
char *xe_name; /* Name for this encoder */
xo_encoder_func_t xe_handler; /* Callback function */
void *xe_dlhandle; /* dlopen handle */
} xo_encoder_node_t;
typedef TAILQ_HEAD(xo_encoder_list_s, xo_encoder_node_s) xo_encoder_list_t;
#define XO_ENCODER_LIST_FOREACH(_xep, _listp) \
xo_encoder_list_init(_listp); \
TAILQ_FOREACH(_xep, _listp, xe_link)
static xo_encoder_list_t xo_encoders;
static void
xo_encoder_list_init (xo_encoder_list_t *listp)
{
if (listp->tqh_last == NULL)
TAILQ_INIT(listp);
}
static xo_encoder_node_t *
xo_encoder_list_add (const char *name)
{
if (name == NULL)
return NULL;
xo_encoder_node_t *xep = xo_realloc(NULL, sizeof(*xep));
if (xep) {
int len = strlen(name) + 1;
xep->xe_name = xo_realloc(NULL, len);
if (xep->xe_name == NULL) {
xo_free(xep);
return NULL;
}
memcpy(xep->xe_name, name, len);
TAILQ_INSERT_TAIL(&xo_encoders, xep, xe_link);
}
return xep;
}
void
xo_encoders_clean (void)
{
xo_encoder_node_t *xep;
xo_encoder_setup();
for (;;) {
xep = TAILQ_FIRST(&xo_encoders);
if (xep == NULL)
break;
TAILQ_REMOVE(&xo_encoders, xep, xe_link);
if (xep->xe_dlhandle)
dlclose(xep->xe_dlhandle);
xo_free(xep);
}
xo_string_list_clean(&xo_encoder_path);
}
static void
xo_encoder_setup (void)
{
static int initted;
if (!initted) {
initted = 1;
xo_string_list_init(&xo_encoder_path);
xo_encoder_list_init(&xo_encoders);
xo_encoder_path_add(XO_ENCODERDIR);
}
}
static xo_encoder_node_t *
xo_encoder_find (const char *name)
{
xo_encoder_node_t *xep;
xo_encoder_list_init(&xo_encoders);
XO_ENCODER_LIST_FOREACH(xep, &xo_encoders) {
if (strcmp(xep->xe_name, name) == 0)
return xep;
}
return NULL;
}
static xo_encoder_node_t *
xo_encoder_discover (const char *name)
{
void *dlp = NULL;
char buf[MAXPATHLEN];
xo_string_node_t *xsp;
xo_encoder_node_t *xep = NULL;
XO_STRING_LIST_FOREACH(xsp, &xo_encoder_path) {
static const char fmt[] = "%s/%s.enc";
char *dir = xsp->xs_data;
size_t len = snprintf(buf, sizeof(buf), fmt, dir, name);
if (len > sizeof(buf)) /* Should not occur */
continue;
dlp = dlopen((const char *) buf, RTLD_NOW);
if (dlp)
break;
}
if (dlp) {
/*
* If the library exists, find the initializer function and
* call it.
*/
xo_encoder_init_func_t func;
func = (xo_encoder_init_func_t) dlfunc(dlp, XO_ENCODER_INIT_NAME);
if (func) {
xo_encoder_init_args_t xei;
bzero(&xei, sizeof(xei));
xei.xei_version = XO_ENCODER_VERSION;
int rc = func(&xei);
if (rc == 0 && xei.xei_handler) {
xep = xo_encoder_list_add(name);
if (xep) {
xep->xe_handler = xei.xei_handler;
xep->xe_dlhandle = dlp;
}
}
}
if (xep == NULL)
dlclose(dlp);
}
return xep;
}
void
xo_encoder_register (const char *name, xo_encoder_func_t func)
{
xo_encoder_setup();
xo_encoder_node_t *xep = xo_encoder_find(name);
if (xep) /* "We alla-ready got one" */
return;
xep = xo_encoder_list_add(name);
if (xep)
xep->xe_handler = func;
}
void
xo_encoder_unregister (const char *name)
{
xo_encoder_setup();
xo_encoder_node_t *xep = xo_encoder_find(name);
if (xep) {
TAILQ_REMOVE(&xo_encoders, xep, xe_link);
xo_free(xep);
}
}
int
xo_encoder_init (xo_handle_t *xop, const char *name)
{
xo_encoder_setup();
/* Can't have names containing '/' or ':' */
if (strchr(name, '/') != NULL || strchr(name, ':') != NULL)
return -1;
/*
* First we look on the list of known (registered) encoders.
* If we don't find it, we follow the set of paths to find
* the encoding library.
*/
xo_encoder_node_t *xep = xo_encoder_find(name);
if (xep == NULL) {
xep = xo_encoder_discover(name);
if (xep == NULL)
return -1;
}
xo_set_encoder(xop, xep->xe_handler);
return xo_encoder_handle(xop, XO_OP_CREATE, NULL, NULL);
}
/*
* A couple of function varieties here, to allow for multiple
* use cases. This variant is for when the main program knows
* its own encoder needs.
*/
xo_handle_t *
xo_encoder_create (const char *name, xo_xof_flags_t flags)
{
xo_handle_t *xop;
xop = xo_create(XO_STYLE_ENCODER, flags);
if (xop) {
if (xo_encoder_init(xop, name)) {
xo_destroy(xop);
xop = NULL;
}
}
return xop;
}
int
xo_encoder_handle (xo_handle_t *xop, xo_encoder_op_t op,
const char *name, const char *value)
{
void *private = xo_get_private(xop);
xo_encoder_func_t func = xo_get_encoder(xop);
if (func == NULL)
return -1;
return func(xop, op, name, value, private);
}
const char *
xo_encoder_op_name (xo_encoder_op_t op)
{
static const char *names[] = {
/* 0 */ "unknown",
/* 1 */ "create",
/* 2 */ "open_container",
/* 3 */ "close_container",
/* 4 */ "open_list",
/* 5 */ "close_list",
/* 6 */ "open_leaf_list",
/* 7 */ "close_leaf_list",
/* 8 */ "open_instance",
/* 9 */ "close_instance",
/* 10 */ "string",
/* 11 */ "content",
/* 12 */ "finish",
/* 13 */ "flush",
/* 14 */ "destroy",
/* 15 */ "attr",
/* 16 */ "version",
};
if (op > sizeof(names) / sizeof(names[0]))
return "unknown";
return names[op];
}
#else /* __rtems__ */
/*
* Not supported on RTEMS. Just return errors on all functions.
*/
#include "xo.h"
#include "xo_encoder.h"
void
xo_encoder_register (const char *name, xo_encoder_func_t func)
{
/* Nothing to do */
}
void
xo_encoder_unregister (const char *name)
{
/* Nothing to do */
}
void
xo_encoder_path_add (const char *path)
{
/* Nothing to do */
}
int
xo_encoder_init (xo_handle_t *xop, const char *name)
{
return -1;
}
xo_handle_t *
xo_encoder_create (const char *name, xo_xof_flags_t flags)
{
return NULL;
}
int
xo_encoder_handle (xo_handle_t *xop, xo_encoder_op_t op,
const char *name, const char *value)
{
return -1;
}
void
xo_encoders_clean (void)
{
/* Nothing to do */
}
const char *
xo_encoder_op_name (xo_encoder_op_t op)
{
return "unknown";
}
#endif /* __rtems__ */

View File

@@ -0,0 +1,116 @@
/*
* Copyright (c) 2015, Juniper Networks, Inc.
* All rights reserved.
* This SOFTWARE is licensed under the LICENSE provided in the
* ../Copyright file. By downloading, installing, copying, or otherwise
* using the SOFTWARE, you agree to be bound by the terms of that
* LICENSE.
* Phil Shafer, August 2015
*/
/*
* NOTE WELL: This file is needed to software that implements an
* external encoder for libxo that allows libxo data to be encoded in
* new and bizarre formats. General libxo code should _never_
* include this header file.
*/
#ifndef XO_ENCODER_H
#define XO_ENCODER_H
/*
* Expose libxo's memory allocation functions
*/
extern xo_realloc_func_t xo_realloc;
extern xo_free_func_t xo_free;
typedef unsigned xo_encoder_op_t;
/* Encoder operations; names are in xo_encoder.c:xo_encoder_op_name() */
#define XO_OP_UNKNOWN 0
#define XO_OP_CREATE 1 /* Called when the handle is init'd */
#define XO_OP_OPEN_CONTAINER 2
#define XO_OP_CLOSE_CONTAINER 3
#define XO_OP_OPEN_LIST 4
#define XO_OP_CLOSE_LIST 5
#define XO_OP_OPEN_LEAF_LIST 6
#define XO_OP_CLOSE_LEAF_LIST 7
#define XO_OP_OPEN_INSTANCE 8
#define XO_OP_CLOSE_INSTANCE 9
#define XO_OP_STRING 10 /* Quoted UTF-8 string */
#define XO_OP_CONTENT 11 /* Other content */
#define XO_OP_FINISH 12 /* Finish any pending output */
#define XO_OP_FLUSH 13 /* Flush any buffered output */
#define XO_OP_DESTROY 14 /* Clean up function */
#define XO_OP_ATTRIBUTE 15 /* Attribute name/value */
#define XO_OP_VERSION 16 /* Version string */
#define XO_ENCODER_HANDLER_ARGS \
xo_handle_t *xop __attribute__ ((__unused__)), \
xo_encoder_op_t op __attribute__ ((__unused__)), \
const char *name __attribute__ ((__unused__)), \
const char *value __attribute__ ((__unused__)), \
void *private __attribute__ ((__unused__))
typedef int (*xo_encoder_func_t)(XO_ENCODER_HANDLER_ARGS);
typedef struct xo_encoder_init_args_s {
unsigned xei_version; /* Current version */
xo_encoder_func_t xei_handler; /* Encoding handler */
} xo_encoder_init_args_t;
#define XO_ENCODER_VERSION 1 /* Current version */
#define XO_ENCODER_INIT_ARGS \
xo_encoder_init_args_t *arg __attribute__ ((__unused__))
typedef int (*xo_encoder_init_func_t)(XO_ENCODER_INIT_ARGS);
/*
* Each encoder library must define a function named xo_encoder_init
* that takes the arguments defined in XO_ENCODER_INIT_ARGS. It
* should return zero for success.
*/
#define XO_ENCODER_INIT_NAME_TOKEN xo_encoder_library_init
#define XO_STRINGIFY(_x) #_x
#define XO_STRINGIFY2(_x) XO_STRINGIFY(_x)
#define XO_ENCODER_INIT_NAME XO_STRINGIFY2(XO_ENCODER_INIT_NAME_TOKEN)
extern int XO_ENCODER_INIT_NAME_TOKEN (XO_ENCODER_INIT_ARGS);
void
xo_encoder_register (const char *name, xo_encoder_func_t func);
void
xo_encoder_unregister (const char *name);
void *
xo_get_private (xo_handle_t *xop);
void
xo_encoder_path_add (const char *path);
void
xo_set_private (xo_handle_t *xop, void *opaque);
xo_encoder_func_t
xo_get_encoder (xo_handle_t *xop);
void
xo_set_encoder (xo_handle_t *xop, xo_encoder_func_t encoder);
int
xo_encoder_init (xo_handle_t *xop, const char *name);
xo_handle_t *
xo_encoder_create (const char *name, xo_xof_flags_t flags);
int
xo_encoder_handle (xo_handle_t *xop, xo_encoder_op_t op,
const char *name, const char *value);
void
xo_encoders_clean (void);
const char *
xo_encoder_op_name (xo_encoder_op_t op);
#endif /* XO_ENCODER_H */

View File

@@ -0,0 +1,169 @@
/* $NetBSD: humanize_number.c,v 1.8 2004/07/27 01:56:24 enami Exp $ */
/*
* Copyright (c) 1997, 1998, 1999, 2002 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
* NASA Ames Research Center, by Luke Mewburn and by Tomas Svensson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <sys/types.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include <stdint.h>
#include <limits.h>
#include <unistd.h>
#include <stdbool.h>
/* humanize_number(3) */
#define HN_DECIMAL 0x01
#define HN_NOSPACE 0x02
#define HN_B 0x04
#define HN_DIVISOR_1000 0x08
#define HN_GETSCALE 0x10
#define HN_AUTOSCALE 0x20
static int
xo_humanize_number (char *buf, size_t len, int64_t bytes,
const char *suffix, int scale, int flags)
{
const char *prefixes, *sep;
int b, i, r, maxscale, s1, s2, sign;
int64_t divisor, max;
// We multiply bytes by 100 to deal with rounding, so we need something
// big enough to hold LLONG_MAX * 100. On 64-bit we can use 128-bit wide
// integers with __int128_t, but on 32-bit we have to use long double.
#ifdef __LP64__
__int128_t scalable = (__int128_t)bytes;
#else
long double scalable = (long double)bytes;
#endif
size_t baselen;
assert(buf != NULL);
assert(suffix != NULL);
assert(scale >= 0);
if (flags & HN_DIVISOR_1000) {
/* SI for decimal multiplies */
divisor = 1000;
if (flags & HN_B)
prefixes = "B\0k\0M\0G\0T\0P\0E";
else
prefixes = "\0\0k\0M\0G\0T\0P\0E";
} else {
/*
* binary multiplies
* XXX IEC 60027-2 recommends Ki, Mi, Gi...
*/
divisor = 1024;
if (flags & HN_B)
prefixes = "B\0K\0M\0G\0T\0P\0E";
else
prefixes = "\0\0K\0M\0G\0T\0P\0E";
}
#define SCALE2PREFIX(scale) (&prefixes[(scale) << 1])
maxscale = 7;
if (scale >= maxscale &&
(scale & (HN_AUTOSCALE | HN_GETSCALE)) == 0)
return (-1);
if (buf == NULL || suffix == NULL)
return (-1);
if (len > 0)
buf[0] = '\0';
if (bytes < 0) {
sign = -1;
scalable *= -100;
baselen = 3; /* sign, digit, prefix */
} else {
sign = 1;
scalable *= 100;
baselen = 2; /* digit, prefix */
}
if (flags & HN_NOSPACE)
sep = "";
else {
sep = " ";
baselen++;
}
baselen += strlen(suffix);
/* Check if enough room for `x y' + suffix + `\0' */
if (len < baselen + 1)
return (-1);
if (scale & (HN_AUTOSCALE | HN_GETSCALE)) {
/* See if there is additional columns can be used. */
for (max = 100, i = len - baselen; i-- > 0;)
max *= 10;
for (i = 0; scalable >= max && i < maxscale; i++)
scalable /= divisor;
if (scale & HN_GETSCALE)
return (i);
} else
for (i = 0; i < scale && i < maxscale; i++)
scalable /= divisor;
/* If a value <= 9.9 after rounding and ... */
if (scalable < 995 && i > 0 && flags & HN_DECIMAL) {
/* baselen + \0 + .N */
if (len < baselen + 1 + 2)
return (-1);
b = ((int)scalable + 5) / 10;
s1 = b / 10;
s2 = b % 10;
r = snprintf(buf, len, "%s%d%s%d%s%s%s",
((sign == -1) ? "-" : ""),
s1, localeconv()->decimal_point, s2,
sep, SCALE2PREFIX(i), suffix);
} else
r = snprintf(buf, len, "%s%lld%s%s%s",
/* LONGLONG */
((sign == -1) ? "-" : ""),
(long long)((scalable + 50) / 100),
sep, SCALE2PREFIX(i), suffix);
return (r);
}

View File

@@ -0,0 +1,313 @@
/*
* This is an implementation of wcwidth() and wcswidth() (defined in
* IEEE Std 1002.1-2001) for Unicode.
*
* http://www.opengroup.org/onlinepubs/007904975/functions/wcwidth.html
* http://www.opengroup.org/onlinepubs/007904975/functions/wcswidth.html
*
* In fixed-width output devices, Latin characters all occupy a single
* "cell" position of equal width, whereas ideographic CJK characters
* occupy two such cells. Interoperability between terminal-line
* applications and (teletype-style) character terminals using the
* UTF-8 encoding requires agreement on which character should advance
* the cursor by how many cell positions. No established formal
* standards exist at present on which Unicode character shall occupy
* how many cell positions on character terminals. These routines are
* a first attempt of defining such behavior based on simple rules
* applied to data provided by the Unicode Consortium.
*
* For some graphical characters, the Unicode standard explicitly
* defines a character-cell width via the definition of the East Asian
* FullWidth (F), Wide (W), Half-width (H), and Narrow (Na) classes.
* In all these cases, there is no ambiguity about which width a
* terminal shall use. For characters in the East Asian Ambiguous (A)
* class, the width choice depends purely on a preference of backward
* compatibility with either historic CJK or Western practice.
* Choosing single-width for these characters is easy to justify as
* the appropriate long-term solution, as the CJK practice of
* displaying these characters as double-width comes from historic
* implementation simplicity (8-bit encoded characters were displayed
* single-width and 16-bit ones double-width, even for Greek,
* Cyrillic, etc.) and not any typographic considerations.
*
* Much less clear is the choice of width for the Not East Asian
* (Neutral) class. Existing practice does not dictate a width for any
* of these characters. It would nevertheless make sense
* typographically to allocate two character cells to characters such
* as for instance EM SPACE or VOLUME INTEGRAL, which cannot be
* represented adequately with a single-width glyph. The following
* routines at present merely assign a single-cell width to all
* neutral characters, in the interest of simplicity. This is not
* entirely satisfactory and should be reconsidered before
* establishing a formal standard in this area. At the moment, the
* decision which Not East Asian (Neutral) characters should be
* represented by double-width glyphs cannot yet be answered by
* applying a simple rule from the Unicode database content. Setting
* up a proper standard for the behavior of UTF-8 character terminals
* will require a careful analysis not only of each Unicode character,
* but also of each presentation form, something the author of these
* routines has avoided to do so far.
*
* http://www.unicode.org/unicode/reports/tr11/
*
* Markus Kuhn -- 2007-05-26 (Unicode 5.0)
*
* Permission to use, copy, modify, and distribute this software
* for any purpose and without fee is hereby granted. The author
* disclaims all warranties with regard to this software.
*
* Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
*/
#include <wchar.h>
struct interval {
wchar_t first;
wchar_t last;
};
/* auxiliary function for binary search in interval table */
static int
xo_bisearch (wchar_t ucs, const struct interval *table, int max)
{
int min = 0;
int mid;
if (ucs < table[0].first || ucs > table[max].last)
return 0;
while (max >= min) {
mid = (min + max) / 2;
if (ucs > table[mid].last)
min = mid + 1;
else if (ucs < table[mid].first)
max = mid - 1;
else
return 1;
}
return 0;
}
/* The following two functions define the column width of an ISO 10646
* character as follows:
*
* - The null character (U+0000) has a column width of 0.
*
* - Other C0/C1 control characters and DEL will lead to a return
* value of -1.
*
* - Non-spacing and enclosing combining characters (general
* category code Mn or Me in the Unicode database) have a
* column width of 0.
*
* - SOFT HYPHEN (U+00AD) has a column width of 1.
*
* - Other format characters (general category code Cf in the Unicode
* database) and ZERO WIDTH SPACE (U+200B) have a column width of 0.
*
* - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF)
* have a column width of 0.
*
* - Spacing characters in the East Asian Wide (W) or East Asian
* Full-width (F) category as defined in Unicode Technical
* Report #11 have a column width of 2.
*
* - All remaining characters (including all printable
* ISO 8859-1 and WGL4 characters, Unicode control characters,
* etc.) have a column width of 1.
*
* This implementation assumes that wchar_t characters are encoded
* in ISO 10646.
*/
static int
xo_wcwidth (wchar_t ucs)
{
/* sorted list of non-overlapping intervals of non-spacing characters */
/* generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" */
static const struct interval combining[] = {
{ 0x0300, 0x036F }, { 0x0483, 0x0486 }, { 0x0488, 0x0489 },
{ 0x0591, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 },
{ 0x05C4, 0x05C5 }, { 0x05C7, 0x05C7 }, { 0x0600, 0x0603 },
{ 0x0610, 0x0615 }, { 0x064B, 0x065E }, { 0x0670, 0x0670 },
{ 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED },
{ 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A },
{ 0x07A6, 0x07B0 }, { 0x07EB, 0x07F3 }, { 0x0901, 0x0902 },
{ 0x093C, 0x093C }, { 0x0941, 0x0948 }, { 0x094D, 0x094D },
{ 0x0951, 0x0954 }, { 0x0962, 0x0963 }, { 0x0981, 0x0981 },
{ 0x09BC, 0x09BC }, { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD },
{ 0x09E2, 0x09E3 }, { 0x0A01, 0x0A02 }, { 0x0A3C, 0x0A3C },
{ 0x0A41, 0x0A42 }, { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D },
{ 0x0A70, 0x0A71 }, { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC },
{ 0x0AC1, 0x0AC5 }, { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD },
{ 0x0AE2, 0x0AE3 }, { 0x0B01, 0x0B01 }, { 0x0B3C, 0x0B3C },
{ 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 }, { 0x0B4D, 0x0B4D },
{ 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 }, { 0x0BC0, 0x0BC0 },
{ 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 }, { 0x0C46, 0x0C48 },
{ 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, { 0x0CBC, 0x0CBC },
{ 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD },
{ 0x0CE2, 0x0CE3 }, { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D },
{ 0x0DCA, 0x0DCA }, { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 },
{ 0x0E31, 0x0E31 }, { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E },
{ 0x0EB1, 0x0EB1 }, { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC },
{ 0x0EC8, 0x0ECD }, { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 },
{ 0x0F37, 0x0F37 }, { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E },
{ 0x0F80, 0x0F84 }, { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 },
{ 0x0F99, 0x0FBC }, { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 },
{ 0x1032, 0x1032 }, { 0x1036, 0x1037 }, { 0x1039, 0x1039 },
{ 0x1058, 0x1059 }, { 0x1160, 0x11FF }, { 0x135F, 0x135F },
{ 0x1712, 0x1714 }, { 0x1732, 0x1734 }, { 0x1752, 0x1753 },
{ 0x1772, 0x1773 }, { 0x17B4, 0x17B5 }, { 0x17B7, 0x17BD },
{ 0x17C6, 0x17C6 }, { 0x17C9, 0x17D3 }, { 0x17DD, 0x17DD },
{ 0x180B, 0x180D }, { 0x18A9, 0x18A9 }, { 0x1920, 0x1922 },
{ 0x1927, 0x1928 }, { 0x1932, 0x1932 }, { 0x1939, 0x193B },
{ 0x1A17, 0x1A18 }, { 0x1B00, 0x1B03 }, { 0x1B34, 0x1B34 },
{ 0x1B36, 0x1B3A }, { 0x1B3C, 0x1B3C }, { 0x1B42, 0x1B42 },
{ 0x1B6B, 0x1B73 }, { 0x1DC0, 0x1DCA }, { 0x1DFE, 0x1DFF },
{ 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x2060, 0x2063 },
{ 0x206A, 0x206F }, { 0x20D0, 0x20EF }, { 0x302A, 0x302F },
{ 0x3099, 0x309A }, { 0xA806, 0xA806 }, { 0xA80B, 0xA80B },
{ 0xA825, 0xA826 }, { 0xFB1E, 0xFB1E }, { 0xFE00, 0xFE0F },
{ 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF }, { 0xFFF9, 0xFFFB },
{ 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F },
{ 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x1D167, 0x1D169 },
{ 0x1D173, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD },
{ 0x1D242, 0x1D244 }, { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F },
{ 0xE0100, 0xE01EF }
};
/* test for 8-bit control characters */
if (ucs == 0)
return 0;
if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0))
return -1;
/* binary search in table of non-spacing characters */
if (xo_bisearch(ucs, combining,
sizeof(combining) / sizeof(struct interval) - 1))
return 0;
/* if we arrive here, ucs is not a combining or C0/C1 control character */
return 1 +
(ucs >= 0x1100 &&
(ucs <= 0x115f || /* Hangul Jamo init. consonants */
ucs == 0x2329 || ucs == 0x232a ||
(ucs >= 0x2e80 && ucs <= 0xa4cf &&
ucs != 0x303f) || /* CJK ... Yi */
(ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */
(ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */
(ucs >= 0xfe10 && ucs <= 0xfe19) || /* Vertical forms */
(ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */
(ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */
(ucs >= 0xffe0 && ucs <= 0xffe6) ||
(ucs >= 0x20000 && ucs <= 0x2fffd) ||
(ucs >= 0x30000 && ucs <= 0x3fffd)));
}
#if UNUSED_CODE
static int xo_wcswidth(const wchar_t *pwcs, size_t n)
{
int w, width = 0;
for (;*pwcs && n-- > 0; pwcs++)
if ((w = mk_wcwidth(*pwcs)) < 0)
return -1;
else
width += w;
return width;
}
/*
* The following functions are the same as mk_wcwidth() and
* mk_wcswidth(), except that spacing characters in the East Asian
* Ambiguous (A) category as defined in Unicode Technical Report #11
* have a column width of 2. This variant might be useful for users of
* CJK legacy encodings who want to migrate to UCS without changing
* the traditional terminal character-width behaviour. It is not
* otherwise recommended for general use.
*/
int mk_wcwidth_cjk(wchar_t ucs)
{
/* sorted list of non-overlapping intervals of East Asian Ambiguous
* characters, generated by "uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf c" */
static const struct interval ambiguous[] = {
{ 0x00A1, 0x00A1 }, { 0x00A4, 0x00A4 }, { 0x00A7, 0x00A8 },
{ 0x00AA, 0x00AA }, { 0x00AE, 0x00AE }, { 0x00B0, 0x00B4 },
{ 0x00B6, 0x00BA }, { 0x00BC, 0x00BF }, { 0x00C6, 0x00C6 },
{ 0x00D0, 0x00D0 }, { 0x00D7, 0x00D8 }, { 0x00DE, 0x00E1 },
{ 0x00E6, 0x00E6 }, { 0x00E8, 0x00EA }, { 0x00EC, 0x00ED },
{ 0x00F0, 0x00F0 }, { 0x00F2, 0x00F3 }, { 0x00F7, 0x00FA },
{ 0x00FC, 0x00FC }, { 0x00FE, 0x00FE }, { 0x0101, 0x0101 },
{ 0x0111, 0x0111 }, { 0x0113, 0x0113 }, { 0x011B, 0x011B },
{ 0x0126, 0x0127 }, { 0x012B, 0x012B }, { 0x0131, 0x0133 },
{ 0x0138, 0x0138 }, { 0x013F, 0x0142 }, { 0x0144, 0x0144 },
{ 0x0148, 0x014B }, { 0x014D, 0x014D }, { 0x0152, 0x0153 },
{ 0x0166, 0x0167 }, { 0x016B, 0x016B }, { 0x01CE, 0x01CE },
{ 0x01D0, 0x01D0 }, { 0x01D2, 0x01D2 }, { 0x01D4, 0x01D4 },
{ 0x01D6, 0x01D6 }, { 0x01D8, 0x01D8 }, { 0x01DA, 0x01DA },
{ 0x01DC, 0x01DC }, { 0x0251, 0x0251 }, { 0x0261, 0x0261 },
{ 0x02C4, 0x02C4 }, { 0x02C7, 0x02C7 }, { 0x02C9, 0x02CB },
{ 0x02CD, 0x02CD }, { 0x02D0, 0x02D0 }, { 0x02D8, 0x02DB },
{ 0x02DD, 0x02DD }, { 0x02DF, 0x02DF }, { 0x0391, 0x03A1 },
{ 0x03A3, 0x03A9 }, { 0x03B1, 0x03C1 }, { 0x03C3, 0x03C9 },
{ 0x0401, 0x0401 }, { 0x0410, 0x044F }, { 0x0451, 0x0451 },
{ 0x2010, 0x2010 }, { 0x2013, 0x2016 }, { 0x2018, 0x2019 },
{ 0x201C, 0x201D }, { 0x2020, 0x2022 }, { 0x2024, 0x2027 },
{ 0x2030, 0x2030 }, { 0x2032, 0x2033 }, { 0x2035, 0x2035 },
{ 0x203B, 0x203B }, { 0x203E, 0x203E }, { 0x2074, 0x2074 },
{ 0x207F, 0x207F }, { 0x2081, 0x2084 }, { 0x20AC, 0x20AC },
{ 0x2103, 0x2103 }, { 0x2105, 0x2105 }, { 0x2109, 0x2109 },
{ 0x2113, 0x2113 }, { 0x2116, 0x2116 }, { 0x2121, 0x2122 },
{ 0x2126, 0x2126 }, { 0x212B, 0x212B }, { 0x2153, 0x2154 },
{ 0x215B, 0x215E }, { 0x2160, 0x216B }, { 0x2170, 0x2179 },
{ 0x2190, 0x2199 }, { 0x21B8, 0x21B9 }, { 0x21D2, 0x21D2 },
{ 0x21D4, 0x21D4 }, { 0x21E7, 0x21E7 }, { 0x2200, 0x2200 },
{ 0x2202, 0x2203 }, { 0x2207, 0x2208 }, { 0x220B, 0x220B },
{ 0x220F, 0x220F }, { 0x2211, 0x2211 }, { 0x2215, 0x2215 },
{ 0x221A, 0x221A }, { 0x221D, 0x2220 }, { 0x2223, 0x2223 },
{ 0x2225, 0x2225 }, { 0x2227, 0x222C }, { 0x222E, 0x222E },
{ 0x2234, 0x2237 }, { 0x223C, 0x223D }, { 0x2248, 0x2248 },
{ 0x224C, 0x224C }, { 0x2252, 0x2252 }, { 0x2260, 0x2261 },
{ 0x2264, 0x2267 }, { 0x226A, 0x226B }, { 0x226E, 0x226F },
{ 0x2282, 0x2283 }, { 0x2286, 0x2287 }, { 0x2295, 0x2295 },
{ 0x2299, 0x2299 }, { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF },
{ 0x2312, 0x2312 }, { 0x2460, 0x24E9 }, { 0x24EB, 0x254B },
{ 0x2550, 0x2573 }, { 0x2580, 0x258F }, { 0x2592, 0x2595 },
{ 0x25A0, 0x25A1 }, { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 },
{ 0x25B6, 0x25B7 }, { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 },
{ 0x25C6, 0x25C8 }, { 0x25CB, 0x25CB }, { 0x25CE, 0x25D1 },
{ 0x25E2, 0x25E5 }, { 0x25EF, 0x25EF }, { 0x2605, 0x2606 },
{ 0x2609, 0x2609 }, { 0x260E, 0x260F }, { 0x2614, 0x2615 },
{ 0x261C, 0x261C }, { 0x261E, 0x261E }, { 0x2640, 0x2640 },
{ 0x2642, 0x2642 }, { 0x2660, 0x2661 }, { 0x2663, 0x2665 },
{ 0x2667, 0x266A }, { 0x266C, 0x266D }, { 0x266F, 0x266F },
{ 0x273D, 0x273D }, { 0x2776, 0x277F }, { 0xE000, 0xF8FF },
{ 0xFFFD, 0xFFFD }, { 0xF0000, 0xFFFFD }, { 0x100000, 0x10FFFD }
};
/* binary search in table of non-spacing characters */
if (xo_bisearch(ucs, ambiguous,
sizeof(ambiguous) / sizeof(struct interval) - 1))
return 2;
return mk_wcwidth(ucs);
}
int mk_wcswidth_cjk(const wchar_t *pwcs, size_t n)
{
int w, width = 0;
for (;*pwcs && n-- > 0; pwcs++)
if ((w = mk_wcwidth_cjk(*pwcs)) < 0)
return -1;
else
width += w;
return width;
}
#endif /* UNUSED_CODE */

View File

@@ -1,42 +0,0 @@
#include <rtems/linkersets.h>
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl,
static struct antispoof_opts antispoof_opts);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static int blockpolicy);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static int debug);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static int default_statelock);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static struct file *file);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static struct files files);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl,
static struct filter_opts filter_opts);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl,
static struct node_hfsc_opts hfsc_opts);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl,
static struct node_state_opt *keep_state_defaults);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl,
static struct loadanchorshead loadanchorshead);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static char *parsebuf);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static int parseindex);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static struct pfctl *pf);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static struct pool_opts pool_opts);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static char pushback_buffer[]);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static int pushback_index);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static struct queue_opts queue_opts);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static struct node_queue *queues);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static int require_order);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static u_int16_t returnicmp6default);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static u_int16_t returnicmpdefault);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static int rulestate);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static struct scrub_opts scrub_opts);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static struct symhead symhead);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static struct table_opts table_opts);
/* NOTE: the following variables are generated by yacc and may change with yacc
* version or generation options. */
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static YYSTACKDATA yystack);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, extern int yychar);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, extern int yydebug);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, extern int yyerrflag);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, extern YYSTYPE yylval);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, extern int yynerrs);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, extern YYSTYPE yyval);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,385 +0,0 @@
#include <machine/rtems-bsd-user-space.h>
/* $OpenBSD: pf_print_state.c,v 1.52 2008/08/12 16:40:18 david Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS 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.
*
*/
#ifdef __rtems__
#include <machine/rtems-bsd-program.h>
#endif /* __rtems__ */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/socket.h>
#ifdef __FreeBSD__
#include <sys/endian.h>
#define betoh64 be64toh
#endif
#include <net/if.h>
#define TCPSTATES
#include <netinet/tcp_fsm.h>
#include <net/pfvar.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include "pfctl_parser.h"
#include "pfctl.h"
void print_name(struct pf_addr *, sa_family_t);
void
print_addr(struct pf_addr_wrap *addr, sa_family_t af, int verbose)
{
switch (addr->type) {
case PF_ADDR_DYNIFTL:
printf("(%s", addr->v.ifname);
if (addr->iflags & PFI_AFLAG_NETWORK)
printf(":network");
if (addr->iflags & PFI_AFLAG_BROADCAST)
printf(":broadcast");
if (addr->iflags & PFI_AFLAG_PEER)
printf(":peer");
if (addr->iflags & PFI_AFLAG_NOALIAS)
printf(":0");
if (verbose) {
if (addr->p.dyncnt <= 0)
printf(":*");
else
printf(":%d", addr->p.dyncnt);
}
printf(")");
break;
case PF_ADDR_TABLE:
if (verbose)
if (addr->p.tblcnt == -1)
printf("<%s:*>", addr->v.tblname);
else
printf("<%s:%d>", addr->v.tblname,
addr->p.tblcnt);
else
printf("<%s>", addr->v.tblname);
return;
case PF_ADDR_RANGE: {
char buf[48];
if (inet_ntop(af, &addr->v.a.addr, buf, sizeof(buf)) == NULL)
printf("?");
else
printf("%s", buf);
if (inet_ntop(af, &addr->v.a.mask, buf, sizeof(buf)) == NULL)
printf(" - ?");
else
printf(" - %s", buf);
break;
}
case PF_ADDR_ADDRMASK:
if (PF_AZERO(&addr->v.a.addr, AF_INET6) &&
PF_AZERO(&addr->v.a.mask, AF_INET6))
printf("any");
else {
char buf[48];
if (inet_ntop(af, &addr->v.a.addr, buf,
sizeof(buf)) == NULL)
printf("?");
else
printf("%s", buf);
}
break;
case PF_ADDR_NOROUTE:
printf("no-route");
return;
case PF_ADDR_URPFFAILED:
printf("urpf-failed");
return;
case PF_ADDR_RTLABEL:
printf("route \"%s\"", addr->v.rtlabelname);
return;
default:
printf("?");
return;
}
/* mask if not _both_ address and mask are zero */
if (addr->type != PF_ADDR_RANGE &&
!(PF_AZERO(&addr->v.a.addr, AF_INET6) &&
PF_AZERO(&addr->v.a.mask, AF_INET6))) {
int bits = unmask(&addr->v.a.mask, af);
if (bits != (af == AF_INET ? 32 : 128))
printf("/%d", bits);
}
}
void
print_name(struct pf_addr *addr, sa_family_t af)
{
char host[NI_MAXHOST];
strlcpy(host, "?", sizeof(host));
switch (af) {
case AF_INET: {
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_len = sizeof(sin);
sin.sin_family = AF_INET;
sin.sin_addr = addr->v4;
getnameinfo((struct sockaddr *)&sin, sin.sin_len,
host, sizeof(host), NULL, 0, NI_NOFQDN);
break;
}
case AF_INET6: {
struct sockaddr_in6 sin6;
memset(&sin6, 0, sizeof(sin6));
sin6.sin6_len = sizeof(sin6);
sin6.sin6_family = AF_INET6;
sin6.sin6_addr = addr->v6;
getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len,
host, sizeof(host), NULL, 0, NI_NOFQDN);
break;
}
}
printf("%s", host);
}
void
print_host(struct pf_addr *addr, u_int16_t port, sa_family_t af, int opts)
{
if (opts & PF_OPT_USEDNS)
print_name(addr, af);
else {
struct pf_addr_wrap aw;
memset(&aw, 0, sizeof(aw));
aw.v.a.addr = *addr;
if (af == AF_INET)
aw.v.a.mask.addr32[0] = 0xffffffff;
else {
memset(&aw.v.a.mask, 0xff, sizeof(aw.v.a.mask));
af = AF_INET6;
}
print_addr(&aw, af, opts & PF_OPT_VERBOSE2);
}
if (port) {
if (af == AF_INET)
printf(":%u", ntohs(port));
else
printf("[%u]", ntohs(port));
}
}
void
print_seq(struct pfsync_state_peer *p)
{
if (p->seqdiff)
printf("[%u + %u](+%u)", ntohl(p->seqlo),
ntohl(p->seqhi) - ntohl(p->seqlo), ntohl(p->seqdiff));
else
printf("[%u + %u]", ntohl(p->seqlo),
ntohl(p->seqhi) - ntohl(p->seqlo));
}
void
print_state(struct pfsync_state *s, int opts)
{
struct pfsync_state_peer *src, *dst;
struct pfsync_state_key *sk, *nk;
struct protoent *p;
int min, sec;
if (s->direction == PF_OUT) {
src = &s->src;
dst = &s->dst;
sk = &s->key[PF_SK_STACK];
nk = &s->key[PF_SK_WIRE];
if (s->proto == IPPROTO_ICMP || s->proto == IPPROTO_ICMPV6)
sk->port[0] = nk->port[0];
} else {
src = &s->dst;
dst = &s->src;
sk = &s->key[PF_SK_WIRE];
nk = &s->key[PF_SK_STACK];
if (s->proto == IPPROTO_ICMP || s->proto == IPPROTO_ICMPV6)
sk->port[1] = nk->port[1];
}
printf("%s ", s->ifname);
if ((p = getprotobynumber(s->proto)) != NULL)
printf("%s ", p->p_name);
else
printf("%u ", s->proto);
print_host(&nk->addr[1], nk->port[1], s->af, opts);
if (PF_ANEQ(&nk->addr[1], &sk->addr[1], s->af) ||
nk->port[1] != sk->port[1]) {
printf(" (");
print_host(&sk->addr[1], sk->port[1], s->af, opts);
printf(")");
}
if (s->direction == PF_OUT)
printf(" -> ");
else
printf(" <- ");
print_host(&nk->addr[0], nk->port[0], s->af, opts);
if (PF_ANEQ(&nk->addr[0], &sk->addr[0], s->af) ||
nk->port[0] != sk->port[0]) {
printf(" (");
print_host(&sk->addr[0], sk->port[0], s->af, opts);
printf(")");
}
printf(" ");
if (s->proto == IPPROTO_TCP) {
if (src->state <= TCPS_TIME_WAIT &&
dst->state <= TCPS_TIME_WAIT)
printf(" %s:%s\n", tcpstates[src->state],
tcpstates[dst->state]);
else if (src->state == PF_TCPS_PROXY_SRC ||
dst->state == PF_TCPS_PROXY_SRC)
printf(" PROXY:SRC\n");
else if (src->state == PF_TCPS_PROXY_DST ||
dst->state == PF_TCPS_PROXY_DST)
printf(" PROXY:DST\n");
else
printf(" <BAD STATE LEVELS %u:%u>\n",
src->state, dst->state);
if (opts & PF_OPT_VERBOSE) {
printf(" ");
print_seq(src);
if (src->wscale && dst->wscale)
printf(" wscale %u",
src->wscale & PF_WSCALE_MASK);
printf(" ");
print_seq(dst);
if (src->wscale && dst->wscale)
printf(" wscale %u",
dst->wscale & PF_WSCALE_MASK);
printf("\n");
}
} else if (s->proto == IPPROTO_UDP && src->state < PFUDPS_NSTATES &&
dst->state < PFUDPS_NSTATES) {
const char *states[] = PFUDPS_NAMES;
printf(" %s:%s\n", states[src->state], states[dst->state]);
} else if (s->proto != IPPROTO_ICMP && src->state < PFOTHERS_NSTATES &&
dst->state < PFOTHERS_NSTATES) {
/* XXX ICMP doesn't really have state levels */
const char *states[] = PFOTHERS_NAMES;
printf(" %s:%s\n", states[src->state], states[dst->state]);
} else {
printf(" %u:%u\n", src->state, dst->state);
}
if (opts & PF_OPT_VERBOSE) {
u_int64_t packets[2];
u_int64_t bytes[2];
u_int32_t creation = ntohl(s->creation);
u_int32_t expire = ntohl(s->expire);
sec = creation % 60;
creation /= 60;
min = creation % 60;
creation /= 60;
printf(" age %.2u:%.2u:%.2u", creation, min, sec);
sec = expire % 60;
expire /= 60;
min = expire % 60;
expire /= 60;
printf(", expires in %.2u:%.2u:%.2u", expire, min, sec);
bcopy(s->packets[0], &packets[0], sizeof(u_int64_t));
bcopy(s->packets[1], &packets[1], sizeof(u_int64_t));
bcopy(s->bytes[0], &bytes[0], sizeof(u_int64_t));
bcopy(s->bytes[1], &bytes[1], sizeof(u_int64_t));
printf(", %llu:%llu pkts, %llu:%llu bytes",
#ifdef __FreeBSD__
(unsigned long long)betoh64(packets[0]),
(unsigned long long)betoh64(packets[1]),
(unsigned long long)betoh64(bytes[0]),
(unsigned long long)betoh64(bytes[1]));
#else
betoh64(packets[0]),
betoh64(packets[1]),
betoh64(bytes[0]),
betoh64(bytes[1]));
#endif
if (ntohl(s->anchor) != -1)
printf(", anchor %u", ntohl(s->anchor));
if (ntohl(s->rule) != -1)
printf(", rule %u", ntohl(s->rule));
if (s->state_flags & PFSTATE_SLOPPY)
printf(", sloppy");
if (s->state_flags & PFSTATE_PFLOW)
printf(", pflow");
if (s->sync_flags & PFSYNC_FLAG_SRCNODE)
printf(", source-track");
if (s->sync_flags & PFSYNC_FLAG_NATSRCNODE)
printf(", sticky-address");
printf("\n");
}
if (opts & PF_OPT_VERBOSE2) {
u_int64_t id;
bcopy(&s->id, &id, sizeof(u_int64_t));
printf(" id: %016llx creatorid: %08x",
#ifdef __FreeBSD__
(unsigned long long)betoh64(id), ntohl(s->creatorid));
#else
betoh64(id), ntohl(s->creatorid));
#endif
printf("\n");
}
}
int
unmask(struct pf_addr *m, sa_family_t af)
{
int i = 31, j = 0, b = 0;
u_int32_t tmp;
while (j < 4 && m->addr32[j] == 0xffffffff) {
b += 32;
j++;
}
if (j < 4) {
tmp = ntohl(m->addr32[j]);
for (i = 31; tmp & (1 << i); --i)
b++;
}
return (b);
}

View File

@@ -1,26 +0,0 @@
#include <rtems/linkersets.h>
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, extern int altqsupport);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static char*anchoropt);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static const char *clearopt);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static const char *debugopt);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, extern int dev);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static int first_title);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static char*ifaceopt);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static int labels);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, extern int loadopt);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static const char *optiopt);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl,
static struct pf_anchor_global pf_anchors);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static const char *pf_device);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl,
static struct pf_anchor pf_main_anchor);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static char*rulesopt);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static const char *showopt);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static char*src_node_kill[2]);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static int src_node_killers);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static char*state_kill[2]);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static int state_killers);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static char*tableopt);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static const char *tblcmdopt);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static const char *tblcmdopt);

File diff suppressed because it is too large Load Diff

View File

@@ -1,130 +0,0 @@
/* $OpenBSD: pfctl.h,v 1.42 2007/12/05 12:01:47 chl Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS 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.
*
* $FreeBSD$
*/
#ifndef _PFCTL_H_
#define _PFCTL_H_
enum pfctl_show { PFCTL_SHOW_RULES, PFCTL_SHOW_LABELS, PFCTL_SHOW_NOTHING };
enum { PFRB_TABLES = 1, PFRB_TSTATS, PFRB_ADDRS, PFRB_ASTATS,
PFRB_IFACES, PFRB_TRANS, PFRB_MAX };
struct pfr_buffer {
int pfrb_type; /* type of content, see enum above */
int pfrb_size; /* number of objects in buffer */
int pfrb_msize; /* maximum number of objects in buffer */
void *pfrb_caddr; /* malloc'ated memory area */
};
#define PFRB_FOREACH(var, buf) \
for ((var) = pfr_buf_next((buf), NULL); \
(var) != NULL; \
(var) = pfr_buf_next((buf), (var)))
int pfr_get_fd(void);
int pfr_clr_tables(struct pfr_table *, int *, int);
int pfr_add_tables(struct pfr_table *, int, int *, int);
int pfr_del_tables(struct pfr_table *, int, int *, int);
int pfr_get_tables(struct pfr_table *, struct pfr_table *, int *, int);
int pfr_get_tstats(struct pfr_table *, struct pfr_tstats *, int *, int);
int pfr_clr_tstats(struct pfr_table *, int, int *, int);
int pfr_clr_addrs(struct pfr_table *, int *, int);
int pfr_add_addrs(struct pfr_table *, struct pfr_addr *, int, int *, int);
int pfr_del_addrs(struct pfr_table *, struct pfr_addr *, int, int *, int);
int pfr_set_addrs(struct pfr_table *, struct pfr_addr *, int, int *,
int *, int *, int *, int);
int pfr_get_addrs(struct pfr_table *, struct pfr_addr *, int *, int);
int pfr_get_astats(struct pfr_table *, struct pfr_astats *, int *, int);
int pfr_tst_addrs(struct pfr_table *, struct pfr_addr *, int, int *, int);
int pfr_ina_define(struct pfr_table *, struct pfr_addr *, int, int *,
int *, int, int);
void pfr_buf_clear(struct pfr_buffer *);
int pfr_buf_add(struct pfr_buffer *, const void *);
void *pfr_buf_next(struct pfr_buffer *, const void *);
int pfr_buf_grow(struct pfr_buffer *, int);
int pfr_buf_load(struct pfr_buffer *, char *, int,
int (*)(struct pfr_buffer *, char *, int));
char *pfr_strerror(int);
int pfi_get_ifaces(const char *, struct pfi_kif *, int *);
int pfi_clr_istats(const char *, int *, int);
void pfctl_print_title(char *);
int pfctl_clear_tables(const char *, int);
int pfctl_show_tables(const char *, int);
int pfctl_command_tables(int, char *[], char *, const char *, char *,
const char *, int);
int pfctl_show_altq(int, const char *, int, int);
void warn_namespace_collision(const char *);
int pfctl_show_ifaces(const char *, int);
FILE *pfctl_fopen(const char *, const char *);
#ifdef __FreeBSD__
extern int altqsupport;
extern int dummynetsupport;
#define HTONL(x) (x) = htonl((__uint32_t)(x))
#endif
#ifndef DEFAULT_PRIORITY
#define DEFAULT_PRIORITY 1
#endif
#ifndef DEFAULT_QLIMIT
#define DEFAULT_QLIMIT 50
#endif
/*
* generalized service curve used for admission control
*/
struct segment {
LIST_ENTRY(segment) _next;
double x, y, d, m;
};
extern int loadopt;
int check_commit_altq(int, int);
void pfaltq_store(struct pf_altq *);
struct pf_altq *pfaltq_lookup(const char *);
char *rate2str(double);
void print_addr(struct pf_addr_wrap *, sa_family_t, int);
void print_host(struct pf_addr *, u_int16_t p, sa_family_t, int);
void print_seq(struct pfsync_state_peer *);
void print_state(struct pfsync_state *, int);
int unmask(struct pf_addr *, sa_family_t);
int pfctl_cmdline_symset(char *);
int pfctl_add_trans(struct pfr_buffer *, int, const char *);
u_int32_t
pfctl_get_ticket(struct pfr_buffer *, int, const char *);
int pfctl_trans(int, struct pfr_buffer *, u_long, int);
#endif /* _PFCTL_H_ */

View File

@@ -1,8 +0,0 @@
#include <rtems/linkersets.h>
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static struct altqs altqs);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static struct gen_sc rtsc);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static struct gen_sc lssc);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl,
static char r2sbuf[R2S_BUFS][RATESTR_MAX]);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static int r2sidx);

File diff suppressed because it is too large Load Diff

View File

@@ -1,13 +0,0 @@
#include <rtems/linkersets.h>
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static int add_opt_table_num);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static int pf_opt_create_table_num);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl,
static struct pf_rule_field pf_rule_desc[]);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static int
(*skip_comparitors[PF_SKIP_COUNT])(struct pf_rule *, struct pf_rule *));
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl,
static const char *skip_comparitors_names[PF_SKIP_COUNT]);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl,
static struct pfr_buffer table_buffer);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static int table_identifier);

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +0,0 @@
#include <rtems/linkersets.h>
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static int class_count);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static struct name_list classes);
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static int fingerprint_count);
/* There is also one static buffer called "buf". But this can be ignored. See
* comment in source file. */

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +0,0 @@
#include <rtems/linkersets.h>
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static struct node_host *iftab);

File diff suppressed because it is too large Load Diff

View File

@@ -1,305 +0,0 @@
/* $OpenBSD: pfctl_parser.h,v 1.86 2006/10/31 23:46:25 mcbride Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS 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.
*
* $FreeBSD$
*/
#ifndef _PFCTL_PARSER_H_
#define _PFCTL_PARSER_H_
#define PF_OSFP_FILE "/etc/pf.os"
#define PF_OPT_DISABLE 0x0001
#define PF_OPT_ENABLE 0x0002
#define PF_OPT_VERBOSE 0x0004
#define PF_OPT_NOACTION 0x0008
#define PF_OPT_QUIET 0x0010
#define PF_OPT_CLRRULECTRS 0x0020
#define PF_OPT_USEDNS 0x0040
#define PF_OPT_VERBOSE2 0x0080
#define PF_OPT_DUMMYACTION 0x0100
#define PF_OPT_DEBUG 0x0200
#define PF_OPT_SHOWALL 0x0400
#define PF_OPT_OPTIMIZE 0x0800
#define PF_OPT_NUMERIC 0x1000
#define PF_OPT_MERGE 0x2000
#define PF_OPT_RECURSE 0x4000
#define PF_TH_ALL 0xFF
#define PF_NAT_PROXY_PORT_LOW 50001
#define PF_NAT_PROXY_PORT_HIGH 65535
#define PF_OPTIMIZE_BASIC 0x0001
#define PF_OPTIMIZE_PROFILE 0x0002
#define FCNT_NAMES { \
"searches", \
"inserts", \
"removals", \
NULL \
}
struct pfr_buffer; /* forward definition */
struct pfctl {
int dev;
int opts;
int optimize;
int loadopt;
int asd; /* anchor stack depth */
int bn; /* brace number */
int brace;
int tdirty; /* kernel dirty */
#define PFCTL_ANCHOR_STACK_DEPTH 64
struct pf_anchor *astack[PFCTL_ANCHOR_STACK_DEPTH];
struct pfioc_pooladdr paddr;
struct pfioc_altq *paltq;
struct pfioc_queue *pqueue;
struct pfr_buffer *trans;
struct pf_anchor *anchor, *alast;
const char *ruleset;
/* 'set foo' options */
u_int32_t timeout[PFTM_MAX];
u_int32_t limit[PF_LIMIT_MAX];
u_int32_t debug;
u_int32_t hostid;
char *ifname;
u_int8_t timeout_set[PFTM_MAX];
u_int8_t limit_set[PF_LIMIT_MAX];
u_int8_t debug_set;
u_int8_t hostid_set;
u_int8_t ifname_set;
};
struct node_if {
char ifname[IFNAMSIZ];
u_int8_t not;
u_int8_t dynamic; /* antispoof */
u_int ifa_flags;
struct node_if *next;
struct node_if *tail;
};
struct node_host {
struct pf_addr_wrap addr;
struct pf_addr bcast;
struct pf_addr peer;
sa_family_t af;
u_int8_t not;
u_int32_t ifindex; /* link-local IPv6 addrs */
char *ifname;
u_int ifa_flags;
struct node_host *next;
struct node_host *tail;
};
struct node_os {
char *os;
pf_osfp_t fingerprint;
struct node_os *next;
struct node_os *tail;
};
struct node_queue_bw {
u_int32_t bw_absolute;
u_int16_t bw_percent;
};
struct node_hfsc_sc {
struct node_queue_bw m1; /* slope of 1st segment; bps */
u_int d; /* x-projection of m1; msec */
struct node_queue_bw m2; /* slope of 2nd segment; bps */
u_int8_t used;
};
struct node_hfsc_opts {
struct node_hfsc_sc realtime;
struct node_hfsc_sc linkshare;
struct node_hfsc_sc upperlimit;
int flags;
};
struct node_queue_opt {
int qtype;
union {
struct cbq_opts cbq_opts;
struct priq_opts priq_opts;
struct node_hfsc_opts hfsc_opts;
} data;
};
#ifdef __FreeBSD__
/*
* XXX
* Absolutely this is not correct location to define this.
* Should we use an another sperate header file?
*/
#define SIMPLEQ_HEAD STAILQ_HEAD
#define SIMPLEQ_HEAD_INITIALIZER STAILQ_HEAD_INITIALIZER
#define SIMPLEQ_ENTRY STAILQ_ENTRY
#define SIMPLEQ_FIRST STAILQ_FIRST
#define SIMPLEQ_END(head) NULL
#define SIMPLEQ_EMPTY STAILQ_EMPTY
#define SIMPLEQ_NEXT STAILQ_NEXT
/*#define SIMPLEQ_FOREACH STAILQ_FOREACH*/
#define SIMPLEQ_FOREACH(var, head, field) \
for((var) = SIMPLEQ_FIRST(head); \
(var) != SIMPLEQ_END(head); \
(var) = SIMPLEQ_NEXT(var, field))
#define SIMPLEQ_INIT STAILQ_INIT
#define SIMPLEQ_INSERT_HEAD STAILQ_INSERT_HEAD
#define SIMPLEQ_INSERT_TAIL STAILQ_INSERT_TAIL
#define SIMPLEQ_INSERT_AFTER STAILQ_INSERT_AFTER
#define SIMPLEQ_REMOVE_HEAD STAILQ_REMOVE_HEAD
#endif
SIMPLEQ_HEAD(node_tinithead, node_tinit);
struct node_tinit { /* table initializer */
SIMPLEQ_ENTRY(node_tinit) entries;
struct node_host *host;
char *file;
};
/* optimizer created tables */
struct pf_opt_tbl {
char pt_name[PF_TABLE_NAME_SIZE];
int pt_rulecount;
int pt_generated;
struct node_tinithead pt_nodes;
struct pfr_buffer *pt_buf;
};
#define PF_OPT_TABLE_PREFIX "__automatic_"
/* optimizer pf_rule container */
struct pf_opt_rule {
struct pf_rule por_rule;
struct pf_opt_tbl *por_src_tbl;
struct pf_opt_tbl *por_dst_tbl;
u_int64_t por_profile_count;
TAILQ_ENTRY(pf_opt_rule) por_entry;
TAILQ_ENTRY(pf_opt_rule) por_skip_entry[PF_SKIP_COUNT];
};
TAILQ_HEAD(pf_opt_queue, pf_opt_rule);
int pfctl_rules(int, char *, int, int, char *, struct pfr_buffer *);
int pfctl_optimize_ruleset(struct pfctl *, struct pf_ruleset *);
int pfctl_add_rule(struct pfctl *, struct pf_rule *, const char *);
int pfctl_add_altq(struct pfctl *, struct pf_altq *);
int pfctl_add_pool(struct pfctl *, struct pf_pool *, sa_family_t);
void pfctl_move_pool(struct pf_pool *, struct pf_pool *);
void pfctl_clear_pool(struct pf_pool *);
int pfctl_set_timeout(struct pfctl *, const char *, int, int);
int pfctl_set_optimization(struct pfctl *, const char *);
int pfctl_set_limit(struct pfctl *, const char *, unsigned int);
int pfctl_set_logif(struct pfctl *, char *);
int pfctl_set_hostid(struct pfctl *, u_int32_t);
int pfctl_set_debug(struct pfctl *, char *);
int pfctl_set_interface_flags(struct pfctl *, char *, int, int);
int parse_config(char *, struct pfctl *);
int parse_flags(char *);
int pfctl_load_anchors(int, struct pfctl *, struct pfr_buffer *);
void print_pool(struct pf_pool *, u_int16_t, u_int16_t, sa_family_t, int);
void print_src_node(struct pf_src_node *, int);
void print_rule(struct pf_rule *, const char *, int, int);
void print_tabledef(const char *, int, int, struct node_tinithead *);
void print_status(struct pf_status *, int);
int eval_pfaltq(struct pfctl *, struct pf_altq *, struct node_queue_bw *,
struct node_queue_opt *);
int eval_pfqueue(struct pfctl *, struct pf_altq *, struct node_queue_bw *,
struct node_queue_opt *);
void print_altq(const struct pf_altq *, unsigned, struct node_queue_bw *,
struct node_queue_opt *);
void print_queue(const struct pf_altq *, unsigned, struct node_queue_bw *,
int, struct node_queue_opt *);
int pfctl_define_table(char *, int, int, const char *, struct pfr_buffer *,
u_int32_t);
void pfctl_clear_fingerprints(int, int);
int pfctl_file_fingerprints(int, int, const char *);
pf_osfp_t pfctl_get_fingerprint(const char *);
int pfctl_load_fingerprints(int, int);
char *pfctl_lookup_fingerprint(pf_osfp_t, char *, size_t);
void pfctl_show_fingerprints(int);
struct icmptypeent {
const char *name;
u_int8_t type;
};
struct icmpcodeent {
const char *name;
u_int8_t type;
u_int8_t code;
};
const struct icmptypeent *geticmptypebynumber(u_int8_t, u_int8_t);
const struct icmptypeent *geticmptypebyname(char *, u_int8_t);
const struct icmpcodeent *geticmpcodebynumber(u_int8_t, u_int8_t, u_int8_t);
const struct icmpcodeent *geticmpcodebyname(u_long, char *, u_int8_t);
struct pf_timeout {
const char *name;
int timeout;
};
#define PFCTL_FLAG_FILTER 0x02
#define PFCTL_FLAG_NAT 0x04
#define PFCTL_FLAG_OPTION 0x08
#define PFCTL_FLAG_ALTQ 0x10
#define PFCTL_FLAG_TABLE 0x20
extern const struct pf_timeout pf_timeouts[];
void set_ipmask(struct node_host *, u_int8_t);
int check_netmask(struct node_host *, sa_family_t);
int unmask(struct pf_addr *, sa_family_t);
void ifa_load(void);
struct node_host *ifa_exists(const char *);
struct node_host *ifa_lookup(const char *, int);
struct node_host *host(const char *);
int append_addr(struct pfr_buffer *, char *, int);
int append_addr_host(struct pfr_buffer *,
struct node_host *, int, int);
#endif /* _PFCTL_PARSER_H_ */

View File

@@ -1,3 +0,0 @@
#include <rtems/linkersets.h>
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static u_int32_t last_ticket);

View File

@@ -1,463 +0,0 @@
#include <machine/rtems-bsd-user-space.h>
/* $OpenBSD: pfctl_qstats.c,v 1.30 2004/04/27 21:47:32 kjc Exp $ */
/*
* Copyright (c) Henning Brauer <henning@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef __rtems__
#include <machine/rtems-bsd-program.h>
#endif /* __rtems__ */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <net/pfvar.h>
#include <arpa/inet.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <altq/altq.h>
#include <altq/altq_cbq.h>
#include <altq/altq_priq.h>
#include <altq/altq_hfsc.h>
#include "pfctl.h"
#include "pfctl_parser.h"
union class_stats {
class_stats_t cbq_stats;
struct priq_classstats priq_stats;
struct hfsc_classstats hfsc_stats;
};
#define AVGN_MAX 8
#define STAT_INTERVAL 5
struct queue_stats {
union class_stats data;
int avgn;
double avg_bytes;
double avg_packets;
u_int64_t prev_bytes;
u_int64_t prev_packets;
};
struct pf_altq_node {
struct pf_altq altq;
struct pf_altq_node *next;
struct pf_altq_node *children;
struct queue_stats qstats;
};
#ifdef __rtems__
static u_int32_t last_ticket;
#endif /* __rtems__ */
int pfctl_update_qstats(int, struct pf_altq_node **);
void pfctl_insert_altq_node(struct pf_altq_node **,
const struct pf_altq, const struct queue_stats);
struct pf_altq_node *pfctl_find_altq_node(struct pf_altq_node *,
const char *, const char *);
void pfctl_print_altq_node(int, const struct pf_altq_node *,
unsigned, int);
void print_cbqstats(struct queue_stats);
void print_priqstats(struct queue_stats);
void print_hfscstats(struct queue_stats);
void pfctl_free_altq_node(struct pf_altq_node *);
void pfctl_print_altq_nodestat(int,
const struct pf_altq_node *);
void update_avg(struct pf_altq_node *);
int
pfctl_show_altq(int dev, const char *iface, int opts, int verbose2)
{
struct pf_altq_node *root = NULL, *node;
int nodes, dotitle = (opts & PF_OPT_SHOWALL);
#ifdef __FreeBSD__
if (!altqsupport)
return (-1);
#endif
if ((nodes = pfctl_update_qstats(dev, &root)) < 0)
return (-1);
if (nodes == 0)
printf("No queue in use\n");
for (node = root; node != NULL; node = node->next) {
if (iface != NULL && strcmp(node->altq.ifname, iface))
continue;
if (dotitle) {
pfctl_print_title("ALTQ:");
dotitle = 0;
}
pfctl_print_altq_node(dev, node, 0, opts);
}
while (verbose2 && nodes > 0) {
printf("\n");
fflush(stdout);
sleep(STAT_INTERVAL);
if ((nodes = pfctl_update_qstats(dev, &root)) == -1)
return (-1);
for (node = root; node != NULL; node = node->next) {
if (iface != NULL && strcmp(node->altq.ifname, iface))
continue;
#ifdef __FreeBSD__
if (node->altq.local_flags & PFALTQ_FLAG_IF_REMOVED)
continue;
#endif
pfctl_print_altq_node(dev, node, 0, opts);
}
}
pfctl_free_altq_node(root);
return (0);
}
int
pfctl_update_qstats(int dev, struct pf_altq_node **root)
{
struct pf_altq_node *node;
struct pfioc_altq pa;
struct pfioc_qstats pq;
u_int32_t mnr, nr;
struct queue_stats qstats;
#ifndef __rtems__
static u_int32_t last_ticket;
#endif /* __rtems__ */
memset(&pa, 0, sizeof(pa));
memset(&pq, 0, sizeof(pq));
memset(&qstats, 0, sizeof(qstats));
if (ioctl(dev, DIOCGETALTQS, &pa)) {
warn("DIOCGETALTQS");
return (-1);
}
/* if a new set is found, start over */
if (pa.ticket != last_ticket && *root != NULL) {
pfctl_free_altq_node(*root);
*root = NULL;
}
last_ticket = pa.ticket;
mnr = pa.nr;
for (nr = 0; nr < mnr; ++nr) {
pa.nr = nr;
if (ioctl(dev, DIOCGETALTQ, &pa)) {
warn("DIOCGETALTQ");
return (-1);
}
#ifdef __FreeBSD__
if (pa.altq.qid > 0 &&
!(pa.altq.local_flags & PFALTQ_FLAG_IF_REMOVED)) {
#else
if (pa.altq.qid > 0) {
#endif
pq.nr = nr;
pq.ticket = pa.ticket;
pq.buf = &qstats.data;
pq.nbytes = sizeof(qstats.data);
if (ioctl(dev, DIOCGETQSTATS, &pq)) {
warn("DIOCGETQSTATS");
return (-1);
}
if ((node = pfctl_find_altq_node(*root, pa.altq.qname,
pa.altq.ifname)) != NULL) {
memcpy(&node->qstats.data, &qstats.data,
sizeof(qstats.data));
update_avg(node);
} else {
pfctl_insert_altq_node(root, pa.altq, qstats);
}
}
#ifdef __FreeBSD__
else if (pa.altq.local_flags & PFALTQ_FLAG_IF_REMOVED) {
memset(&qstats.data, 0, sizeof(qstats.data));
if ((node = pfctl_find_altq_node(*root, pa.altq.qname,
pa.altq.ifname)) != NULL) {
memcpy(&node->qstats.data, &qstats.data,
sizeof(qstats.data));
update_avg(node);
} else {
pfctl_insert_altq_node(root, pa.altq, qstats);
}
}
#endif
}
return (mnr);
}
void
pfctl_insert_altq_node(struct pf_altq_node **root,
const struct pf_altq altq, const struct queue_stats qstats)
{
struct pf_altq_node *node;
node = calloc(1, sizeof(struct pf_altq_node));
if (node == NULL)
err(1, "pfctl_insert_altq_node: calloc");
memcpy(&node->altq, &altq, sizeof(struct pf_altq));
memcpy(&node->qstats, &qstats, sizeof(qstats));
node->next = node->children = NULL;
if (*root == NULL)
*root = node;
else if (!altq.parent[0]) {
struct pf_altq_node *prev = *root;
while (prev->next != NULL)
prev = prev->next;
prev->next = node;
} else {
struct pf_altq_node *parent;
parent = pfctl_find_altq_node(*root, altq.parent, altq.ifname);
if (parent == NULL)
errx(1, "parent %s not found", altq.parent);
if (parent->children == NULL)
parent->children = node;
else {
struct pf_altq_node *prev = parent->children;
while (prev->next != NULL)
prev = prev->next;
prev->next = node;
}
}
update_avg(node);
}
struct pf_altq_node *
pfctl_find_altq_node(struct pf_altq_node *root, const char *qname,
const char *ifname)
{
struct pf_altq_node *node, *child;
for (node = root; node != NULL; node = node->next) {
if (!strcmp(node->altq.qname, qname)
&& !(strcmp(node->altq.ifname, ifname)))
return (node);
if (node->children != NULL) {
child = pfctl_find_altq_node(node->children, qname,
ifname);
if (child != NULL)
return (child);
}
}
return (NULL);
}
void
pfctl_print_altq_node(int dev, const struct pf_altq_node *node,
unsigned int level, int opts)
{
const struct pf_altq_node *child;
if (node == NULL)
return;
print_altq(&node->altq, level, NULL, NULL);
if (node->children != NULL) {
printf("{");
for (child = node->children; child != NULL;
child = child->next) {
printf("%s", child->altq.qname);
if (child->next != NULL)
printf(", ");
}
printf("}");
}
printf("\n");
if (opts & PF_OPT_VERBOSE)
pfctl_print_altq_nodestat(dev, node);
if (opts & PF_OPT_DEBUG)
printf(" [ qid=%u ifname=%s ifbandwidth=%s ]\n",
node->altq.qid, node->altq.ifname,
rate2str((double)(node->altq.ifbandwidth)));
for (child = node->children; child != NULL;
child = child->next)
pfctl_print_altq_node(dev, child, level + 1, opts);
}
void
pfctl_print_altq_nodestat(int dev, const struct pf_altq_node *a)
{
if (a->altq.qid == 0)
return;
#ifdef __FreeBSD__
if (a->altq.local_flags & PFALTQ_FLAG_IF_REMOVED)
return;
#endif
switch (a->altq.scheduler) {
case ALTQT_CBQ:
print_cbqstats(a->qstats);
break;
case ALTQT_PRIQ:
print_priqstats(a->qstats);
break;
case ALTQT_HFSC:
print_hfscstats(a->qstats);
break;
}
}
void
print_cbqstats(struct queue_stats cur)
{
printf(" [ pkts: %10llu bytes: %10llu "
"dropped pkts: %6llu bytes: %6llu ]\n",
(unsigned long long)cur.data.cbq_stats.xmit_cnt.packets,
(unsigned long long)cur.data.cbq_stats.xmit_cnt.bytes,
(unsigned long long)cur.data.cbq_stats.drop_cnt.packets,
(unsigned long long)cur.data.cbq_stats.drop_cnt.bytes);
printf(" [ qlength: %3d/%3d borrows: %6u suspends: %6u ]\n",
cur.data.cbq_stats.qcnt, cur.data.cbq_stats.qmax,
cur.data.cbq_stats.borrows, cur.data.cbq_stats.delays);
if (cur.avgn < 2)
return;
printf(" [ measured: %7.1f packets/s, %s/s ]\n",
cur.avg_packets / STAT_INTERVAL,
rate2str((8 * cur.avg_bytes) / STAT_INTERVAL));
}
void
print_priqstats(struct queue_stats cur)
{
printf(" [ pkts: %10llu bytes: %10llu "
"dropped pkts: %6llu bytes: %6llu ]\n",
(unsigned long long)cur.data.priq_stats.xmitcnt.packets,
(unsigned long long)cur.data.priq_stats.xmitcnt.bytes,
(unsigned long long)cur.data.priq_stats.dropcnt.packets,
(unsigned long long)cur.data.priq_stats.dropcnt.bytes);
printf(" [ qlength: %3d/%3d ]\n",
cur.data.priq_stats.qlength, cur.data.priq_stats.qlimit);
if (cur.avgn < 2)
return;
printf(" [ measured: %7.1f packets/s, %s/s ]\n",
cur.avg_packets / STAT_INTERVAL,
rate2str((8 * cur.avg_bytes) / STAT_INTERVAL));
}
void
print_hfscstats(struct queue_stats cur)
{
printf(" [ pkts: %10llu bytes: %10llu "
"dropped pkts: %6llu bytes: %6llu ]\n",
(unsigned long long)cur.data.hfsc_stats.xmit_cnt.packets,
(unsigned long long)cur.data.hfsc_stats.xmit_cnt.bytes,
(unsigned long long)cur.data.hfsc_stats.drop_cnt.packets,
(unsigned long long)cur.data.hfsc_stats.drop_cnt.bytes);
printf(" [ qlength: %3d/%3d ]\n",
cur.data.hfsc_stats.qlength, cur.data.hfsc_stats.qlimit);
if (cur.avgn < 2)
return;
printf(" [ measured: %7.1f packets/s, %s/s ]\n",
cur.avg_packets / STAT_INTERVAL,
rate2str((8 * cur.avg_bytes) / STAT_INTERVAL));
}
void
pfctl_free_altq_node(struct pf_altq_node *node)
{
while (node != NULL) {
struct pf_altq_node *prev;
if (node->children != NULL)
pfctl_free_altq_node(node->children);
prev = node;
node = node->next;
free(prev);
}
}
void
update_avg(struct pf_altq_node *a)
{
struct queue_stats *qs;
u_int64_t b, p;
int n;
if (a->altq.qid == 0)
return;
qs = &a->qstats;
n = qs->avgn;
switch (a->altq.scheduler) {
case ALTQT_CBQ:
b = qs->data.cbq_stats.xmit_cnt.bytes;
p = qs->data.cbq_stats.xmit_cnt.packets;
break;
case ALTQT_PRIQ:
b = qs->data.priq_stats.xmitcnt.bytes;
p = qs->data.priq_stats.xmitcnt.packets;
break;
case ALTQT_HFSC:
b = qs->data.hfsc_stats.xmit_cnt.bytes;
p = qs->data.hfsc_stats.xmit_cnt.packets;
break;
default:
b = 0;
p = 0;
break;
}
if (n == 0) {
qs->prev_bytes = b;
qs->prev_packets = p;
qs->avgn++;
return;
}
if (b >= qs->prev_bytes)
qs->avg_bytes = ((qs->avg_bytes * (n - 1)) +
(b - qs->prev_bytes)) / n;
if (p >= qs->prev_packets)
qs->avg_packets = ((qs->avg_packets * (n - 1)) +
(p - qs->prev_packets)) / n;
qs->prev_bytes = b;
qs->prev_packets = p;
if (n < AVGN_MAX)
qs->avgn++;
}
#ifdef __rtems__
#include "pfctl_qstats-data.h"
#endif /* __rtems__ */

View File

@@ -1,3 +0,0 @@
#include <rtems/linkersets.h>
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static char next_ch);

View File

@@ -1,602 +0,0 @@
#include <machine/rtems-bsd-user-space.h>
/* $OpenBSD: pfctl_radix.c,v 1.27 2005/05/21 21:03:58 henning Exp $ */
/*
* Copyright (c) 2002 Cedric Berger
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS 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.
*
*/
#ifdef __rtems__
#include <machine/rtems-bsd-program.h>
#endif /* __rtems__ */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/pfvar.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <err.h>
#include "pfctl.h"
#define BUF_SIZE 256
extern int dev;
static int pfr_next_token(char buf[], FILE *);
int
pfr_clr_tables(struct pfr_table *filter, int *ndel, int flags)
{
struct pfioc_table io;
bzero(&io, sizeof io);
io.pfrio_flags = flags;
if (filter != NULL)
io.pfrio_table = *filter;
if (ioctl(dev, DIOCRCLRTABLES, &io))
return (-1);
if (ndel != NULL)
*ndel = io.pfrio_ndel;
return (0);
}
int
pfr_add_tables(struct pfr_table *tbl, int size, int *nadd, int flags)
{
struct pfioc_table io;
if (size < 0 || (size && tbl == NULL)) {
errno = EINVAL;
return (-1);
}
bzero(&io, sizeof io);
io.pfrio_flags = flags;
io.pfrio_buffer = tbl;
io.pfrio_esize = sizeof(*tbl);
io.pfrio_size = size;
if (ioctl(dev, DIOCRADDTABLES, &io))
return (-1);
if (nadd != NULL)
*nadd = io.pfrio_nadd;
return (0);
}
int
pfr_del_tables(struct pfr_table *tbl, int size, int *ndel, int flags)
{
struct pfioc_table io;
if (size < 0 || (size && tbl == NULL)) {
errno = EINVAL;
return (-1);
}
bzero(&io, sizeof io);
io.pfrio_flags = flags;
io.pfrio_buffer = tbl;
io.pfrio_esize = sizeof(*tbl);
io.pfrio_size = size;
if (ioctl(dev, DIOCRDELTABLES, &io))
return (-1);
if (ndel != NULL)
*ndel = io.pfrio_ndel;
return (0);
}
int
pfr_get_tables(struct pfr_table *filter, struct pfr_table *tbl, int *size,
int flags)
{
struct pfioc_table io;
if (size == NULL || *size < 0 || (*size && tbl == NULL)) {
errno = EINVAL;
return (-1);
}
bzero(&io, sizeof io);
io.pfrio_flags = flags;
if (filter != NULL)
io.pfrio_table = *filter;
io.pfrio_buffer = tbl;
io.pfrio_esize = sizeof(*tbl);
io.pfrio_size = *size;
if (ioctl(dev, DIOCRGETTABLES, &io))
return (-1);
*size = io.pfrio_size;
return (0);
}
int
pfr_get_tstats(struct pfr_table *filter, struct pfr_tstats *tbl, int *size,
int flags)
{
struct pfioc_table io;
if (size == NULL || *size < 0 || (*size && tbl == NULL)) {
errno = EINVAL;
return (-1);
}
bzero(&io, sizeof io);
io.pfrio_flags = flags;
if (filter != NULL)
io.pfrio_table = *filter;
io.pfrio_buffer = tbl;
io.pfrio_esize = sizeof(*tbl);
io.pfrio_size = *size;
if (ioctl(dev, DIOCRGETTSTATS, &io))
return (-1);
*size = io.pfrio_size;
return (0);
}
int
pfr_clr_addrs(struct pfr_table *tbl, int *ndel, int flags)
{
struct pfioc_table io;
if (tbl == NULL) {
errno = EINVAL;
return (-1);
}
bzero(&io, sizeof io);
io.pfrio_flags = flags;
io.pfrio_table = *tbl;
if (ioctl(dev, DIOCRCLRADDRS, &io))
return (-1);
if (ndel != NULL)
*ndel = io.pfrio_ndel;
return (0);
}
int
pfr_add_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
int *nadd, int flags)
{
struct pfioc_table io;
if (tbl == NULL || size < 0 || (size && addr == NULL)) {
errno = EINVAL;
return (-1);
}
bzero(&io, sizeof io);
io.pfrio_flags = flags;
io.pfrio_table = *tbl;
io.pfrio_buffer = addr;
io.pfrio_esize = sizeof(*addr);
io.pfrio_size = size;
if (ioctl(dev, DIOCRADDADDRS, &io))
return (-1);
if (nadd != NULL)
*nadd = io.pfrio_nadd;
return (0);
}
int
pfr_del_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
int *ndel, int flags)
{
struct pfioc_table io;
if (tbl == NULL || size < 0 || (size && addr == NULL)) {
errno = EINVAL;
return (-1);
}
bzero(&io, sizeof io);
io.pfrio_flags = flags;
io.pfrio_table = *tbl;
io.pfrio_buffer = addr;
io.pfrio_esize = sizeof(*addr);
io.pfrio_size = size;
if (ioctl(dev, DIOCRDELADDRS, &io))
return (-1);
if (ndel != NULL)
*ndel = io.pfrio_ndel;
return (0);
}
int
pfr_set_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
int *size2, int *nadd, int *ndel, int *nchange, int flags)
{
struct pfioc_table io;
if (tbl == NULL || size < 0 || (size && addr == NULL)) {
errno = EINVAL;
return (-1);
}
bzero(&io, sizeof io);
io.pfrio_flags = flags;
io.pfrio_table = *tbl;
io.pfrio_buffer = addr;
io.pfrio_esize = sizeof(*addr);
io.pfrio_size = size;
io.pfrio_size2 = (size2 != NULL) ? *size2 : 0;
if (ioctl(dev, DIOCRSETADDRS, &io))
return (-1);
if (nadd != NULL)
*nadd = io.pfrio_nadd;
if (ndel != NULL)
*ndel = io.pfrio_ndel;
if (nchange != NULL)
*nchange = io.pfrio_nchange;
if (size2 != NULL)
*size2 = io.pfrio_size2;
return (0);
}
int
pfr_get_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int *size,
int flags)
{
struct pfioc_table io;
if (tbl == NULL || size == NULL || *size < 0 ||
(*size && addr == NULL)) {
errno = EINVAL;
return (-1);
}
bzero(&io, sizeof io);
io.pfrio_flags = flags;
io.pfrio_table = *tbl;
io.pfrio_buffer = addr;
io.pfrio_esize = sizeof(*addr);
io.pfrio_size = *size;
if (ioctl(dev, DIOCRGETADDRS, &io))
return (-1);
*size = io.pfrio_size;
return (0);
}
int
pfr_get_astats(struct pfr_table *tbl, struct pfr_astats *addr, int *size,
int flags)
{
struct pfioc_table io;
if (tbl == NULL || size == NULL || *size < 0 ||
(*size && addr == NULL)) {
errno = EINVAL;
return (-1);
}
bzero(&io, sizeof io);
io.pfrio_flags = flags;
io.pfrio_table = *tbl;
io.pfrio_buffer = addr;
io.pfrio_esize = sizeof(*addr);
io.pfrio_size = *size;
if (ioctl(dev, DIOCRGETASTATS, &io))
return (-1);
*size = io.pfrio_size;
return (0);
}
int
pfr_clr_tstats(struct pfr_table *tbl, int size, int *nzero, int flags)
{
struct pfioc_table io;
if (size < 0 || (size && !tbl)) {
errno = EINVAL;
return (-1);
}
bzero(&io, sizeof io);
io.pfrio_flags = flags;
io.pfrio_buffer = tbl;
io.pfrio_esize = sizeof(*tbl);
io.pfrio_size = size;
if (ioctl(dev, DIOCRCLRTSTATS, &io))
return (-1);
if (nzero)
*nzero = io.pfrio_nzero;
return (0);
}
int
pfr_tst_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
int *nmatch, int flags)
{
struct pfioc_table io;
if (tbl == NULL || size < 0 || (size && addr == NULL)) {
errno = EINVAL;
return (-1);
}
bzero(&io, sizeof io);
io.pfrio_flags = flags;
io.pfrio_table = *tbl;
io.pfrio_buffer = addr;
io.pfrio_esize = sizeof(*addr);
io.pfrio_size = size;
if (ioctl(dev, DIOCRTSTADDRS, &io))
return (-1);
if (nmatch)
*nmatch = io.pfrio_nmatch;
return (0);
}
int
pfr_ina_define(struct pfr_table *tbl, struct pfr_addr *addr, int size,
int *nadd, int *naddr, int ticket, int flags)
{
struct pfioc_table io;
if (tbl == NULL || size < 0 || (size && addr == NULL)) {
errno = EINVAL;
return (-1);
}
bzero(&io, sizeof io);
io.pfrio_flags = flags;
io.pfrio_table = *tbl;
io.pfrio_buffer = addr;
io.pfrio_esize = sizeof(*addr);
io.pfrio_size = size;
io.pfrio_ticket = ticket;
if (ioctl(dev, DIOCRINADEFINE, &io))
return (-1);
if (nadd != NULL)
*nadd = io.pfrio_nadd;
if (naddr != NULL)
*naddr = io.pfrio_naddr;
return (0);
}
/* interface management code */
int
pfi_get_ifaces(const char *filter, struct pfi_kif *buf, int *size)
{
struct pfioc_iface io;
if (size == NULL || *size < 0 || (*size && buf == NULL)) {
errno = EINVAL;
return (-1);
}
bzero(&io, sizeof io);
if (filter != NULL)
if (strlcpy(io.pfiio_name, filter, sizeof(io.pfiio_name)) >=
sizeof(io.pfiio_name)) {
errno = EINVAL;
return (-1);
}
io.pfiio_buffer = buf;
io.pfiio_esize = sizeof(*buf);
io.pfiio_size = *size;
if (ioctl(dev, DIOCIGETIFACES, &io))
return (-1);
*size = io.pfiio_size;
return (0);
}
/* buffer management code */
#ifndef __rtems__
size_t buf_esize[PFRB_MAX] = { 0,
#else /* __rtems__ */
const size_t buf_esize[PFRB_MAX] = { 0,
#endif /* __rtems__ */
sizeof(struct pfr_table), sizeof(struct pfr_tstats),
sizeof(struct pfr_addr), sizeof(struct pfr_astats),
sizeof(struct pfi_kif), sizeof(struct pfioc_trans_e)
};
/*
* add one element to the buffer
*/
int
pfr_buf_add(struct pfr_buffer *b, const void *e)
{
size_t bs;
if (b == NULL || b->pfrb_type <= 0 || b->pfrb_type >= PFRB_MAX ||
e == NULL) {
errno = EINVAL;
return (-1);
}
bs = buf_esize[b->pfrb_type];
if (b->pfrb_size == b->pfrb_msize)
if (pfr_buf_grow(b, 0))
return (-1);
memcpy(((caddr_t)b->pfrb_caddr) + bs * b->pfrb_size, e, bs);
b->pfrb_size++;
return (0);
}
/*
* return next element of the buffer (or first one if prev is NULL)
* see PFRB_FOREACH macro
*/
void *
pfr_buf_next(struct pfr_buffer *b, const void *prev)
{
size_t bs;
if (b == NULL || b->pfrb_type <= 0 || b->pfrb_type >= PFRB_MAX)
return (NULL);
if (b->pfrb_size == 0)
return (NULL);
if (prev == NULL)
return (b->pfrb_caddr);
bs = buf_esize[b->pfrb_type];
if ((((caddr_t)prev)-((caddr_t)b->pfrb_caddr)) / bs >= b->pfrb_size-1)
return (NULL);
return (((caddr_t)prev) + bs);
}
/*
* minsize:
* 0: make the buffer somewhat bigger
* n: make room for "n" entries in the buffer
*/
int
pfr_buf_grow(struct pfr_buffer *b, int minsize)
{
caddr_t p;
size_t bs;
if (b == NULL || b->pfrb_type <= 0 || b->pfrb_type >= PFRB_MAX) {
errno = EINVAL;
return (-1);
}
if (minsize != 0 && minsize <= b->pfrb_msize)
return (0);
bs = buf_esize[b->pfrb_type];
if (!b->pfrb_msize) {
if (minsize < 64)
minsize = 64;
b->pfrb_caddr = calloc(bs, minsize);
if (b->pfrb_caddr == NULL)
return (-1);
b->pfrb_msize = minsize;
} else {
if (minsize == 0)
minsize = b->pfrb_msize * 2;
if (minsize < 0 || minsize >= SIZE_T_MAX / bs) {
/* msize overflow */
errno = ENOMEM;
return (-1);
}
p = realloc(b->pfrb_caddr, minsize * bs);
if (p == NULL)
return (-1);
bzero(p + b->pfrb_msize * bs, (minsize - b->pfrb_msize) * bs);
b->pfrb_caddr = p;
b->pfrb_msize = minsize;
}
return (0);
}
/*
* reset buffer and free memory.
*/
void
pfr_buf_clear(struct pfr_buffer *b)
{
if (b == NULL)
return;
if (b->pfrb_caddr != NULL)
free(b->pfrb_caddr);
b->pfrb_caddr = NULL;
b->pfrb_size = b->pfrb_msize = 0;
}
int
pfr_buf_load(struct pfr_buffer *b, char *file, int nonetwork,
int (*append_addr)(struct pfr_buffer *, char *, int))
{
FILE *fp;
char buf[BUF_SIZE];
int rv;
if (file == NULL)
return (0);
if (!strcmp(file, "-"))
fp = stdin;
else {
fp = pfctl_fopen(file, "r");
if (fp == NULL)
return (-1);
}
while ((rv = pfr_next_token(buf, fp)) == 1)
if (append_addr(b, buf, nonetwork)) {
rv = -1;
break;
}
if (fp != stdin)
fclose(fp);
return (rv);
}
#ifdef __rtems__
static char next_ch = ' ';
#endif /* __rtems__ */
int
pfr_next_token(char buf[BUF_SIZE], FILE *fp)
{
#ifndef __rtems__
static char next_ch = ' ';
#endif /* __rtems__ */
int i = 0;
for (;;) {
/* skip spaces */
while (isspace(next_ch) && !feof(fp))
next_ch = fgetc(fp);
/* remove from '#' until end of line */
if (next_ch == '#')
while (!feof(fp)) {
next_ch = fgetc(fp);
if (next_ch == '\n')
break;
}
else
break;
}
if (feof(fp)) {
next_ch = ' ';
return (0);
}
do {
if (i < BUF_SIZE)
buf[i++] = next_ch;
next_ch = fgetc(fp);
} while (!feof(fp) && !isspace(next_ch));
if (i >= BUF_SIZE) {
errno = EINVAL;
return (-1);
}
buf[i] = '\0';
return (1);
}
char *
pfr_strerror(int errnum)
{
switch (errnum) {
case ESRCH:
return "Table does not exist";
case ENOENT:
return "Anchor or Ruleset does not exist";
default:
return strerror(errnum);
}
}
#ifdef __rtems__
#include "pfctl_radix-data.h"
#endif /* __rtems__ */

View File

@@ -1,644 +0,0 @@
#include <machine/rtems-bsd-user-space.h>
/* $OpenBSD: pfctl_table.c,v 1.67 2008/06/10 20:55:02 mcbride Exp $ */
/*
* Copyright (c) 2002 Cedric Berger
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS 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.
*
*/
#ifdef __rtems__
#include <machine/rtems-bsd-program.h>
#endif /* __rtems__ */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/pfvar.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <netdb.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "pfctl_parser.h"
#include "pfctl.h"
extern void usage(void);
static int pfctl_table(int, char *[], char *, const char *, char *,
const char *, int);
static void print_table(struct pfr_table *, int, int);
static void print_tstats(struct pfr_tstats *, int);
static int load_addr(struct pfr_buffer *, int, char *[], char *, int);
static void print_addrx(struct pfr_addr *, struct pfr_addr *, int);
static void print_astats(struct pfr_astats *, int);
static void radix_perror(void);
static void xprintf(int, const char *, ...);
static void print_iface(struct pfi_kif *, int);
static const char *stats_text[PFR_DIR_MAX][PFR_OP_TABLE_MAX] = {
{ "In/Block:", "In/Pass:", "In/XPass:" },
{ "Out/Block:", "Out/Pass:", "Out/XPass:" }
};
static const char *istats_text[2][2][2] = {
{ { "In4/Pass:", "In4/Block:" }, { "Out4/Pass:", "Out4/Block:" } },
{ { "In6/Pass:", "In6/Block:" }, { "Out6/Pass:", "Out6/Block:" } }
};
#define RVTEST(fct) do { \
if ((!(opts & PF_OPT_NOACTION) || \
(opts & PF_OPT_DUMMYACTION)) && \
(fct)) { \
radix_perror(); \
goto _error; \
} \
} while (0)
#define CREATE_TABLE do { \
table.pfrt_flags |= PFR_TFLAG_PERSIST; \
if ((!(opts & PF_OPT_NOACTION) || \
(opts & PF_OPT_DUMMYACTION)) && \
(pfr_add_tables(&table, 1, &nadd, flags)) && \
(errno != EPERM)) { \
radix_perror(); \
goto _error; \
} \
if (nadd) { \
warn_namespace_collision(table.pfrt_name); \
xprintf(opts, "%d table created", nadd); \
if (opts & PF_OPT_NOACTION) \
return (0); \
} \
table.pfrt_flags &= ~PFR_TFLAG_PERSIST; \
} while(0)
int
pfctl_clear_tables(const char *anchor, int opts)
{
return pfctl_table(0, NULL, NULL, "-F", NULL, anchor, opts);
}
int
pfctl_show_tables(const char *anchor, int opts)
{
return pfctl_table(0, NULL, NULL, "-s", NULL, anchor, opts);
}
int
pfctl_command_tables(int argc, char *argv[], char *tname,
const char *command, char *file, const char *anchor, int opts)
{
if (tname == NULL || command == NULL)
usage();
return pfctl_table(argc, argv, tname, command, file, anchor, opts);
}
int
pfctl_table(int argc, char *argv[], char *tname, const char *command,
char *file, const char *anchor, int opts)
{
struct pfr_table table;
struct pfr_buffer b, b2;
struct pfr_addr *a, *a2;
int nadd = 0, ndel = 0, nchange = 0, nzero = 0;
int rv = 0, flags = 0, nmatch = 0;
void *p;
if (command == NULL)
usage();
if (opts & PF_OPT_NOACTION)
flags |= PFR_FLAG_DUMMY;
bzero(&b, sizeof(b));
bzero(&b2, sizeof(b2));
bzero(&table, sizeof(table));
if (tname != NULL) {
if (strlen(tname) >= PF_TABLE_NAME_SIZE)
usage();
if (strlcpy(table.pfrt_name, tname,
sizeof(table.pfrt_name)) >= sizeof(table.pfrt_name))
errx(1, "pfctl_table: strlcpy");
}
if (strlcpy(table.pfrt_anchor, anchor,
sizeof(table.pfrt_anchor)) >= sizeof(table.pfrt_anchor))
errx(1, "pfctl_table: strlcpy");
if (!strcmp(command, "-F")) {
if (argc || file != NULL)
usage();
RVTEST(pfr_clr_tables(&table, &ndel, flags));
xprintf(opts, "%d tables deleted", ndel);
} else if (!strcmp(command, "-s")) {
b.pfrb_type = (opts & PF_OPT_VERBOSE2) ?
PFRB_TSTATS : PFRB_TABLES;
if (argc || file != NULL)
usage();
for (;;) {
pfr_buf_grow(&b, b.pfrb_size);
b.pfrb_size = b.pfrb_msize;
if (opts & PF_OPT_VERBOSE2)
RVTEST(pfr_get_tstats(&table,
b.pfrb_caddr, &b.pfrb_size, flags));
else
RVTEST(pfr_get_tables(&table,
b.pfrb_caddr, &b.pfrb_size, flags));
if (b.pfrb_size <= b.pfrb_msize)
break;
}
if ((opts & PF_OPT_SHOWALL) && b.pfrb_size > 0)
pfctl_print_title("TABLES:");
PFRB_FOREACH(p, &b)
if (opts & PF_OPT_VERBOSE2)
print_tstats(p, opts & PF_OPT_DEBUG);
else
print_table(p, opts & PF_OPT_VERBOSE,
opts & PF_OPT_DEBUG);
} else if (!strcmp(command, "kill")) {
if (argc || file != NULL)
usage();
RVTEST(pfr_del_tables(&table, 1, &ndel, flags));
xprintf(opts, "%d table deleted", ndel);
} else if (!strcmp(command, "flush")) {
if (argc || file != NULL)
usage();
RVTEST(pfr_clr_addrs(&table, &ndel, flags));
xprintf(opts, "%d addresses deleted", ndel);
} else if (!strcmp(command, "add")) {
b.pfrb_type = PFRB_ADDRS;
if (load_addr(&b, argc, argv, file, 0))
goto _error;
CREATE_TABLE;
if (opts & PF_OPT_VERBOSE)
flags |= PFR_FLAG_FEEDBACK;
RVTEST(pfr_add_addrs(&table, b.pfrb_caddr, b.pfrb_size,
&nadd, flags));
xprintf(opts, "%d/%d addresses added", nadd, b.pfrb_size);
if (opts & PF_OPT_VERBOSE)
PFRB_FOREACH(a, &b)
if ((opts & PF_OPT_VERBOSE2) || a->pfra_fback)
print_addrx(a, NULL,
opts & PF_OPT_USEDNS);
} else if (!strcmp(command, "delete")) {
b.pfrb_type = PFRB_ADDRS;
if (load_addr(&b, argc, argv, file, 0))
goto _error;
if (opts & PF_OPT_VERBOSE)
flags |= PFR_FLAG_FEEDBACK;
RVTEST(pfr_del_addrs(&table, b.pfrb_caddr, b.pfrb_size,
&ndel, flags));
xprintf(opts, "%d/%d addresses deleted", ndel, b.pfrb_size);
if (opts & PF_OPT_VERBOSE)
PFRB_FOREACH(a, &b)
if ((opts & PF_OPT_VERBOSE2) || a->pfra_fback)
print_addrx(a, NULL,
opts & PF_OPT_USEDNS);
} else if (!strcmp(command, "replace")) {
b.pfrb_type = PFRB_ADDRS;
if (load_addr(&b, argc, argv, file, 0))
goto _error;
CREATE_TABLE;
if (opts & PF_OPT_VERBOSE)
flags |= PFR_FLAG_FEEDBACK;
for (;;) {
int sz2 = b.pfrb_msize;
RVTEST(pfr_set_addrs(&table, b.pfrb_caddr, b.pfrb_size,
&sz2, &nadd, &ndel, &nchange, flags));
if (sz2 <= b.pfrb_msize) {
b.pfrb_size = sz2;
break;
} else
pfr_buf_grow(&b, sz2);
}
if (nadd)
xprintf(opts, "%d addresses added", nadd);
if (ndel)
xprintf(opts, "%d addresses deleted", ndel);
if (nchange)
xprintf(opts, "%d addresses changed", nchange);
if (!nadd && !ndel && !nchange)
xprintf(opts, "no changes");
if (opts & PF_OPT_VERBOSE)
PFRB_FOREACH(a, &b)
if ((opts & PF_OPT_VERBOSE2) || a->pfra_fback)
print_addrx(a, NULL,
opts & PF_OPT_USEDNS);
} else if (!strcmp(command, "expire")) {
const char *errstr;
u_int lifetime;
b.pfrb_type = PFRB_ASTATS;
b2.pfrb_type = PFRB_ADDRS;
if (argc != 1 || file != NULL)
usage();
lifetime = strtonum(*argv, 0, UINT_MAX, &errstr);
if (errstr)
errx(1, "expiry time: %s", errstr);
for (;;) {
pfr_buf_grow(&b, b.pfrb_size);
b.pfrb_size = b.pfrb_msize;
RVTEST(pfr_get_astats(&table, b.pfrb_caddr,
&b.pfrb_size, flags));
if (b.pfrb_size <= b.pfrb_msize)
break;
}
PFRB_FOREACH(p, &b) {
((struct pfr_astats *)p)->pfras_a.pfra_fback = 0;
if (time(NULL) - ((struct pfr_astats *)p)->pfras_tzero >
lifetime)
if (pfr_buf_add(&b2,
&((struct pfr_astats *)p)->pfras_a))
err(1, "duplicate buffer");
}
if (opts & PF_OPT_VERBOSE)
flags |= PFR_FLAG_FEEDBACK;
RVTEST(pfr_del_addrs(&table, b2.pfrb_caddr, b2.pfrb_size,
&ndel, flags));
xprintf(opts, "%d/%d addresses expired", ndel, b2.pfrb_size);
if (opts & PF_OPT_VERBOSE)
PFRB_FOREACH(a, &b2)
if ((opts & PF_OPT_VERBOSE2) || a->pfra_fback)
print_addrx(a, NULL,
opts & PF_OPT_USEDNS);
} else if (!strcmp(command, "show")) {
b.pfrb_type = (opts & PF_OPT_VERBOSE) ?
PFRB_ASTATS : PFRB_ADDRS;
if (argc || file != NULL)
usage();
for (;;) {
pfr_buf_grow(&b, b.pfrb_size);
b.pfrb_size = b.pfrb_msize;
if (opts & PF_OPT_VERBOSE)
RVTEST(pfr_get_astats(&table, b.pfrb_caddr,
&b.pfrb_size, flags));
else
RVTEST(pfr_get_addrs(&table, b.pfrb_caddr,
&b.pfrb_size, flags));
if (b.pfrb_size <= b.pfrb_msize)
break;
}
PFRB_FOREACH(p, &b)
if (opts & PF_OPT_VERBOSE)
print_astats(p, opts & PF_OPT_USEDNS);
else
print_addrx(p, NULL, opts & PF_OPT_USEDNS);
} else if (!strcmp(command, "test")) {
b.pfrb_type = PFRB_ADDRS;
b2.pfrb_type = PFRB_ADDRS;
if (load_addr(&b, argc, argv, file, 1))
goto _error;
if (opts & PF_OPT_VERBOSE2) {
flags |= PFR_FLAG_REPLACE;
PFRB_FOREACH(a, &b)
if (pfr_buf_add(&b2, a))
err(1, "duplicate buffer");
}
RVTEST(pfr_tst_addrs(&table, b.pfrb_caddr, b.pfrb_size,
&nmatch, flags));
xprintf(opts, "%d/%d addresses match", nmatch, b.pfrb_size);
if ((opts & PF_OPT_VERBOSE) && !(opts & PF_OPT_VERBOSE2))
PFRB_FOREACH(a, &b)
if (a->pfra_fback == PFR_FB_MATCH)
print_addrx(a, NULL,
opts & PF_OPT_USEDNS);
if (opts & PF_OPT_VERBOSE2) {
a2 = NULL;
PFRB_FOREACH(a, &b) {
a2 = pfr_buf_next(&b2, a2);
print_addrx(a2, a, opts & PF_OPT_USEDNS);
}
}
if (nmatch < b.pfrb_size)
rv = 2;
} else if (!strcmp(command, "zero")) {
if (argc || file != NULL)
usage();
flags |= PFR_FLAG_ADDRSTOO;
RVTEST(pfr_clr_tstats(&table, 1, &nzero, flags));
xprintf(opts, "%d table/stats cleared", nzero);
} else
warnx("pfctl_table: unknown command '%s'", command);
goto _cleanup;
_error:
rv = -1;
_cleanup:
pfr_buf_clear(&b);
pfr_buf_clear(&b2);
return (rv);
}
void
print_table(struct pfr_table *ta, int verbose, int debug)
{
if (!debug && !(ta->pfrt_flags & PFR_TFLAG_ACTIVE))
return;
if (verbose) {
printf("%c%c%c%c%c%c%c\t%s",
(ta->pfrt_flags & PFR_TFLAG_CONST) ? 'c' : '-',
(ta->pfrt_flags & PFR_TFLAG_PERSIST) ? 'p' : '-',
(ta->pfrt_flags & PFR_TFLAG_ACTIVE) ? 'a' : '-',
(ta->pfrt_flags & PFR_TFLAG_INACTIVE) ? 'i' : '-',
(ta->pfrt_flags & PFR_TFLAG_REFERENCED) ? 'r' : '-',
(ta->pfrt_flags & PFR_TFLAG_REFDANCHOR) ? 'h' : '-',
(ta->pfrt_flags & PFR_TFLAG_COUNTERS) ? 'C' : '-',
ta->pfrt_name);
if (ta->pfrt_anchor[0])
printf("\t%s", ta->pfrt_anchor);
puts("");
} else
puts(ta->pfrt_name);
}
void
print_tstats(struct pfr_tstats *ts, int debug)
{
time_t time = ts->pfrts_tzero;
int dir, op;
if (!debug && !(ts->pfrts_flags & PFR_TFLAG_ACTIVE))
return;
print_table(&ts->pfrts_t, 1, debug);
printf("\tAddresses: %d\n", ts->pfrts_cnt);
printf("\tCleared: %s", ctime(&time));
printf("\tReferences: [ Anchors: %-18d Rules: %-18d ]\n",
ts->pfrts_refcnt[PFR_REFCNT_ANCHOR],
ts->pfrts_refcnt[PFR_REFCNT_RULE]);
printf("\tEvaluations: [ NoMatch: %-18llu Match: %-18llu ]\n",
(unsigned long long)ts->pfrts_nomatch,
(unsigned long long)ts->pfrts_match);
for (dir = 0; dir < PFR_DIR_MAX; dir++)
for (op = 0; op < PFR_OP_TABLE_MAX; op++)
printf("\t%-12s [ Packets: %-18llu Bytes: %-18llu ]\n",
stats_text[dir][op],
(unsigned long long)ts->pfrts_packets[dir][op],
(unsigned long long)ts->pfrts_bytes[dir][op]);
}
int
load_addr(struct pfr_buffer *b, int argc, char *argv[], char *file,
int nonetwork)
{
while (argc--)
if (append_addr(b, *argv++, nonetwork)) {
if (errno)
warn("cannot decode %s", argv[-1]);
return (-1);
}
if (pfr_buf_load(b, file, nonetwork, append_addr)) {
warn("cannot load %s", file);
return (-1);
}
return (0);
}
void
print_addrx(struct pfr_addr *ad, struct pfr_addr *rad, int dns)
{
char ch, buf[256] = "{error}";
char fb[] = { ' ', 'M', 'A', 'D', 'C', 'Z', 'X', ' ', 'Y', ' ' };
unsigned int fback, hostnet;
fback = (rad != NULL) ? rad->pfra_fback : ad->pfra_fback;
ch = (fback < sizeof(fb)/sizeof(*fb)) ? fb[fback] : '?';
hostnet = (ad->pfra_af == AF_INET6) ? 128 : 32;
inet_ntop(ad->pfra_af, &ad->pfra_u, buf, sizeof(buf));
printf("%c %c%s", ch, (ad->pfra_not?'!':' '), buf);
if (ad->pfra_net < hostnet)
printf("/%d", ad->pfra_net);
if (rad != NULL && fback != PFR_FB_NONE) {
if (strlcpy(buf, "{error}", sizeof(buf)) >= sizeof(buf))
errx(1, "print_addrx: strlcpy");
inet_ntop(rad->pfra_af, &rad->pfra_u, buf, sizeof(buf));
printf("\t%c%s", (rad->pfra_not?'!':' '), buf);
if (rad->pfra_net < hostnet)
printf("/%d", rad->pfra_net);
}
if (rad != NULL && fback == PFR_FB_NONE)
printf("\t nomatch");
if (dns && ad->pfra_net == hostnet) {
char host[NI_MAXHOST];
union sockaddr_union sa;
strlcpy(host, "?", sizeof(host));
bzero(&sa, sizeof(sa));
sa.sa.sa_family = ad->pfra_af;
if (sa.sa.sa_family == AF_INET) {
sa.sa.sa_len = sizeof(sa.sin);
sa.sin.sin_addr = ad->pfra_ip4addr;
} else {
sa.sa.sa_len = sizeof(sa.sin6);
sa.sin6.sin6_addr = ad->pfra_ip6addr;
}
if (getnameinfo(&sa.sa, sa.sa.sa_len, host, sizeof(host),
NULL, 0, NI_NAMEREQD) == 0)
printf("\t(%s)", host);
}
printf("\n");
}
void
print_astats(struct pfr_astats *as, int dns)
{
time_t time = as->pfras_tzero;
int dir, op;
print_addrx(&as->pfras_a, NULL, dns);
printf("\tCleared: %s", ctime(&time));
if (as->pfras_a.pfra_fback == PFR_FB_NOCOUNT)
return;
for (dir = 0; dir < PFR_DIR_MAX; dir++)
for (op = 0; op < PFR_OP_ADDR_MAX; op++)
printf("\t%-12s [ Packets: %-18llu Bytes: %-18llu ]\n",
stats_text[dir][op],
(unsigned long long)as->pfras_packets[dir][op],
(unsigned long long)as->pfras_bytes[dir][op]);
}
void
radix_perror(void)
{
#ifndef __rtems__
extern char *__progname;
#else /* __rtems__ */
#define __progname "pfctl"
#endif /* __rtems__ */
fprintf(stderr, "%s: %s.\n", __progname, pfr_strerror(errno));
}
int
pfctl_define_table(char *name, int flags, int addrs, const char *anchor,
struct pfr_buffer *ab, u_int32_t ticket)
{
struct pfr_table tbl;
bzero(&tbl, sizeof(tbl));
if (strlcpy(tbl.pfrt_name, name, sizeof(tbl.pfrt_name)) >=
sizeof(tbl.pfrt_name) || strlcpy(tbl.pfrt_anchor, anchor,
sizeof(tbl.pfrt_anchor)) >= sizeof(tbl.pfrt_anchor))
errx(1, "pfctl_define_table: strlcpy");
tbl.pfrt_flags = flags;
return pfr_ina_define(&tbl, ab->pfrb_caddr, ab->pfrb_size, NULL,
NULL, ticket, addrs ? PFR_FLAG_ADDRSTOO : 0);
}
void
warn_namespace_collision(const char *filter)
{
struct pfr_buffer b;
struct pfr_table *t;
const char *name = NULL, *lastcoll;
int coll = 0;
bzero(&b, sizeof(b));
b.pfrb_type = PFRB_TABLES;
for (;;) {
pfr_buf_grow(&b, b.pfrb_size);
b.pfrb_size = b.pfrb_msize;
if (pfr_get_tables(NULL, b.pfrb_caddr,
&b.pfrb_size, PFR_FLAG_ALLRSETS))
err(1, "pfr_get_tables");
if (b.pfrb_size <= b.pfrb_msize)
break;
}
PFRB_FOREACH(t, &b) {
if (!(t->pfrt_flags & PFR_TFLAG_ACTIVE))
continue;
if (filter != NULL && strcmp(filter, t->pfrt_name))
continue;
if (!t->pfrt_anchor[0])
name = t->pfrt_name;
else if (name != NULL && !strcmp(name, t->pfrt_name)) {
coll++;
lastcoll = name;
name = NULL;
}
}
if (coll == 1)
warnx("warning: namespace collision with <%s> global table.",
lastcoll);
else if (coll > 1)
warnx("warning: namespace collisions with %d global tables.",
coll);
pfr_buf_clear(&b);
}
void
xprintf(int opts, const char *fmt, ...)
{
va_list args;
if (opts & PF_OPT_QUIET)
return;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
if (opts & PF_OPT_DUMMYACTION)
fprintf(stderr, " (dummy).\n");
else if (opts & PF_OPT_NOACTION)
fprintf(stderr, " (syntax only).\n");
else
fprintf(stderr, ".\n");
}
/* interface stuff */
int
pfctl_show_ifaces(const char *filter, int opts)
{
struct pfr_buffer b;
struct pfi_kif *p;
int i = 0;
bzero(&b, sizeof(b));
b.pfrb_type = PFRB_IFACES;
for (;;) {
pfr_buf_grow(&b, b.pfrb_size);
b.pfrb_size = b.pfrb_msize;
if (pfi_get_ifaces(filter, b.pfrb_caddr, &b.pfrb_size)) {
radix_perror();
return (1);
}
if (b.pfrb_size <= b.pfrb_msize)
break;
i++;
}
if (opts & PF_OPT_SHOWALL)
pfctl_print_title("INTERFACES:");
PFRB_FOREACH(p, &b)
print_iface(p, opts);
return (0);
}
void
print_iface(struct pfi_kif *p, int opts)
{
time_t tzero = p->pfik_tzero;
int i, af, dir, act;
printf("%s", p->pfik_name);
if (opts & PF_OPT_VERBOSE) {
if (p->pfik_flags & PFI_IFLAG_SKIP)
printf(" (skip)");
}
printf("\n");
if (!(opts & PF_OPT_VERBOSE2))
return;
printf("\tCleared: %s", ctime(&tzero));
printf("\tReferences: [ States: %-18d Rules: %-18d ]\n",
p->pfik_states, p->pfik_rules);
for (i = 0; i < 8; i++) {
af = (i>>2) & 1;
dir = (i>>1) &1;
act = i & 1;
printf("\t%-12s [ Packets: %-18llu Bytes: %-18llu ]\n",
istats_text[af][dir][act],
(unsigned long long)p->pfik_packets[af][dir][act],
(unsigned long long)p->pfik_bytes[af][dir][act]);
}
}