mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-10-14 07:15:58 +08:00
Update to FreeBSD head 2016-08-23
Git mirror commit 9fe7c416e6abb28b1398fd3e5687099846800cfd.
This commit is contained in:
8080
freebsd/contrib/libxo/libxo/libxo.c
Normal file
8080
freebsd/contrib/libxo/libxo/libxo.c
Normal file
File diff suppressed because it is too large
Load Diff
666
freebsd/contrib/libxo/libxo/xo.h
Normal file
666
freebsd/contrib/libxo/libxo/xo.h
Normal 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 */
|
158
freebsd/contrib/libxo/libxo/xo_buf.h
Normal file
158
freebsd/contrib/libxo/libxo/xo_buf.h
Normal 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 */
|
254
freebsd/contrib/libxo/libxo/xo_config.h
Normal file
254
freebsd/contrib/libxo/libxo/xo_config.h
Normal 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 */
|
435
freebsd/contrib/libxo/libxo/xo_encoder.c
Normal file
435
freebsd/contrib/libxo/libxo/xo_encoder.c
Normal 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__ */
|
116
freebsd/contrib/libxo/libxo/xo_encoder.h
Normal file
116
freebsd/contrib/libxo/libxo/xo_encoder.h
Normal 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 */
|
169
freebsd/contrib/libxo/libxo/xo_humanize.h
Normal file
169
freebsd/contrib/libxo/libxo/xo_humanize.h
Normal 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);
|
||||
}
|
313
freebsd/contrib/libxo/libxo/xo_wcwidth.h
Normal file
313
freebsd/contrib/libxo/libxo/xo_wcwidth.h
Normal 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 */
|
@@ -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
@@ -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);
|
||||
}
|
@@ -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
@@ -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_ */
|
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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_ */
|
@@ -1,3 +0,0 @@
|
||||
#include <rtems/linkersets.h>
|
||||
|
||||
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static u_int32_t last_ticket);
|
@@ -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__ */
|
@@ -1,3 +0,0 @@
|
||||
#include <rtems/linkersets.h>
|
||||
|
||||
RTEMS_LINKER_RWSET_CONTENT(bsd_prog_pfctl, static char next_ch);
|
@@ -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__ */
|
@@ -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]);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user