Module Name: othersrc
Committed By: dyoung
Date: Wed Sep 2 22:43:17 UTC 2015
Modified Files:
othersrc/external/bsd/arfe/dt: Makefile README dt.c
othersrc/external/bsd/arfe/dt/rr: if-re0-if-wm0 if-wm0-if-re0
ifconfig.0-ifconfig.1 ifconfig.0-logger-ifconfig.0
ifconfig.1-ifconfig.0 logger-ifconfig.0-ifconfig.0 wm0-a-wm0-b
wm0-b-wm0-a
othersrc/external/bsd/arfe/it: Makefile README
Added Files:
othersrc/external/bsd/arfe/dt: dt.h hex.c hex.h ipv4.c ipv4.h
Log Message:
Add $ARFE$, $NetBSD$, and licenses at the top of various files.
Factor the hexadecimal parser out of dt.c. Put it in hex.[ch]. Start
an IPv4 parser.
Write an IPv4 parser in dt/ipv4.[ch] and start using it. Reorganize
#includes in dt.c and free the hex parser after it's used. Update the
expected test results for the IPv4 parser.
In the READMEs, describe the hexadecimal data detection and functions.
Describe how IPv4 addresses are treated.
To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 othersrc/external/bsd/arfe/dt/Makefile
cvs rdiff -u -r1.3 -r1.4 othersrc/external/bsd/arfe/dt/README
cvs rdiff -u -r1.7 -r1.8 othersrc/external/bsd/arfe/dt/dt.c
cvs rdiff -u -r0 -r1.1 othersrc/external/bsd/arfe/dt/dt.h \
othersrc/external/bsd/arfe/dt/hex.c othersrc/external/bsd/arfe/dt/hex.h \
othersrc/external/bsd/arfe/dt/ipv4.c othersrc/external/bsd/arfe/dt/ipv4.h
cvs rdiff -u -r1.2 -r1.3 othersrc/external/bsd/arfe/dt/rr/if-re0-if-wm0 \
othersrc/external/bsd/arfe/dt/rr/if-wm0-if-re0
cvs rdiff -u -r1.3 -r1.4 \
othersrc/external/bsd/arfe/dt/rr/ifconfig.0-ifconfig.1 \
othersrc/external/bsd/arfe/dt/rr/ifconfig.0-logger-ifconfig.0 \
othersrc/external/bsd/arfe/dt/rr/ifconfig.1-ifconfig.0 \
othersrc/external/bsd/arfe/dt/rr/logger-ifconfig.0-ifconfig.0 \
othersrc/external/bsd/arfe/dt/rr/wm0-a-wm0-b \
othersrc/external/bsd/arfe/dt/rr/wm0-b-wm0-a
cvs rdiff -u -r1.1 -r1.2 othersrc/external/bsd/arfe/it/Makefile
cvs rdiff -u -r1.2 -r1.3 othersrc/external/bsd/arfe/it/README
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: othersrc/external/bsd/arfe/dt/Makefile
diff -u othersrc/external/bsd/arfe/dt/Makefile:1.2 othersrc/external/bsd/arfe/dt/Makefile:1.3
--- othersrc/external/bsd/arfe/dt/Makefile:1.2 Sat Aug 22 05:08:48 2015
+++ othersrc/external/bsd/arfe/dt/Makefile Wed Sep 2 22:43:17 2015
@@ -1,9 +1,9 @@
-# $ARFE: Makefile 216 2015-08-22 05:04:28Z dyoung $
+# $ARFE: Makefile 231 2015-09-02 22:31:30Z dyoung $
NOMAN=
.include <bsd.own.mk>
PROG=dt
-SRCS+=dt.c
+SRCS+=dt.c hex.c ipv4.c
#CPPFLAGS+=-DHB_DEBUG
CPPFLAGS+=-DHB_ASSERT
DBG+=-g -O3
Index: othersrc/external/bsd/arfe/dt/README
diff -u othersrc/external/bsd/arfe/dt/README:1.3 othersrc/external/bsd/arfe/dt/README:1.4
--- othersrc/external/bsd/arfe/dt/README:1.3 Mon Aug 31 01:58:23 2015
+++ othersrc/external/bsd/arfe/dt/README Wed Sep 2 22:43:17 2015
@@ -1,13 +1,16 @@
-$ARFE: README 225 2015-08-31 01:57:28Z dyoung $
-$NetBSD: README,v 1.3 2015/08/31 01:58:23 dyoung Exp $
+$ARFE: README 233 2015-09-02 22:33:54Z dyoung $
+$NetBSD: README,v 1.4 2015/09/02 22:43:17 dyoung Exp $
DT---(d)ifferentiate (t)ext---finds a longest common subsequence (LCS)
-of two texts where the numbers are "wild": a span of decimal digits in
-the first text will match any decimal-digits span in the second text.
-Currently, DT detects whole hexadecimal numbers (with and without an
-0x-prefix) and decimal numbers. When DT emits the LCS, it replaces
-matched pairs of decimal numbers with their difference, and matched
-pairs of hexadecimal numbers with their bitwise-AND combination.
+of two texts where the numbers and IPv4 addresses are "wild": a span
+of decimal digits in the first text will match any decimal-digits span
+in the second text. An IPv4 number in the first text will likewise
+match any IPv4 number in the second text. Currently, DT detects whole
+hexadecimal numbers (with and without an 0x-prefix) and decimal numbers.
+When DT emits the LCS, it replaces matched pairs of decimal numbers with
+their difference, and matched pairs of hexadecimal numbers with their
+bitwise-AND combination. DT replaces matched pairs of IP numbers with
+the smallest subnet that contains both.
DT arose from the author's desire to examine the rate of change of
network statistics from several sources (ifconfig -va, netstat -s, a
Index: othersrc/external/bsd/arfe/dt/dt.c
diff -u othersrc/external/bsd/arfe/dt/dt.c:1.7 othersrc/external/bsd/arfe/dt/dt.c:1.8
--- othersrc/external/bsd/arfe/dt/dt.c:1.7 Mon Aug 31 01:58:23 2015
+++ othersrc/external/bsd/arfe/dt/dt.c Wed Sep 2 22:43:17 2015
@@ -1,5 +1,5 @@
-/* $NetBSD: dt.c,v 1.7 2015/08/31 01:58:23 dyoung Exp $ */
-/* $ARFE: dt.c 224 2015-08-28 21:45:03Z dyoung $ */
+/* $NetBSD: dt.c,v 1.8 2015/09/02 22:43:17 dyoung Exp $ */
+/* $ARFE: dt.c 231 2015-09-02 22:31:30Z dyoung $ */
/*-
* Copyright (c) 2014,2015 David Young <[email protected]>
@@ -25,12 +25,6 @@
* (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> /* for __cacheline_aligned */
-#include <sys/param.h> /* for MAX() */
-#include <sys/queue.h> /* for TAILQ_*() */
-#include <sys/mman.h>
-#include <sys/stat.h>
#include <assert.h>
#include <ctype.h> /* for ispunct(), isspace(), isxdigit() */
#include <err.h>
@@ -45,6 +39,19 @@
#include <limits.h>
#include <string.h>
+#include <sys/socket.h> /* for inet_net_pton */
+#include <netinet/in.h> /* for inet_net_pton */
+#include <arpa/inet.h> /* for inet_net_pton */
+
+#include <sys/param.h> /* for MAX() */
+#include <sys/queue.h> /* for TAILQ_*() */
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include "dt.h"
+#include "hex.h"
+#include "ipv4.h"
+
#if defined(HB_ASSERT)
#define dbg_assert assert
#else
@@ -56,104 +63,6 @@ typedef struct origin {
int j;
} origin_t;
-typedef enum hex_op {
- HEX_OP_NONE = 0
- , HEX_OP_PUSH
- , HEX_OP_EMIT
- , HEX_OP_0xEMIT
- , HEX_OP_START
- , HEX_OP_0xSTART
-} hex_op_t;
-
-struct hex_state;
-typedef struct hex_state hex_state_t;
-
-typedef struct hex_transition {
- const hex_state_t *t_newstate;
- hex_op_t t_op;
-} hex_transition_t;
-
-struct hex_state {
- const char *s_descr;
- hex_transition_t s_other;
- hex_transition_t s_hexdigit;
- hex_transition_t s_0;
- hex_transition_t s_x;
- hex_transition_t s_delimiter;
- hex_transition_t s_eof;
-};
-
-enum hex_state_idxs {
- READ_0
- , READ_X
- , READ_0xHEXDIGIT
- , READ_HEXDIGIT
- , READ_EOF
- , READ_OTHER
- , READ_DELIMITER
-};
-
-#define read_0 hex_states[READ_0]
-#define read_x hex_states[READ_X]
-#define read_0xhexdigit hex_states[READ_0xHEXDIGIT]
-#define read_hexdigit hex_states[READ_HEXDIGIT]
-#define read_eof hex_states[READ_EOF]
-#define read_other hex_states[READ_OTHER]
-#define read_delimiter hex_states[READ_DELIMITER]
-
-static const hex_state_t hex_states[] = {[READ_0] = {
- .s_descr = "read 0",
- .s_other = {&read_other, HEX_OP_NONE},
- .s_hexdigit = {&read_hexdigit, HEX_OP_PUSH},
- .s_x = {&read_x, HEX_OP_0xSTART},
-}, [READ_X] = {
- .s_descr = "read x",
- .s_other = {&read_other, HEX_OP_NONE},
- .s_hexdigit = {&read_0xhexdigit, HEX_OP_PUSH},
-}, [READ_0xHEXDIGIT] = {
- .s_descr = "read 0xhexdigit",
- .s_other = {&read_other, HEX_OP_NONE},
- .s_delimiter = {&read_delimiter, HEX_OP_0xEMIT},
- .s_eof = {&read_eof, HEX_OP_0xEMIT},
- .s_hexdigit = {&read_0xhexdigit, HEX_OP_PUSH},
-}, [READ_HEXDIGIT] = {
- .s_descr = "read hexdigit",
- .s_other = {&read_other, HEX_OP_NONE},
- .s_delimiter = {&read_delimiter, HEX_OP_EMIT},
- .s_eof = {&read_eof, HEX_OP_EMIT},
- .s_hexdigit = {&read_hexdigit, HEX_OP_PUSH},
-}, [READ_EOF] = {
- .s_descr = "read eof",
- .s_other = {&read_eof, HEX_OP_NONE},
-}, [READ_OTHER] = {
- .s_descr = "read other",
- .s_other = {&read_other, HEX_OP_NONE},
- .s_delimiter = {&read_delimiter, HEX_OP_NONE},
-}, [READ_DELIMITER] = {
- .s_descr = "read delimiter",
- .s_0 = {&read_0, HEX_OP_START},
- .s_hexdigit = {&read_hexdigit, HEX_OP_START},
- .s_delimiter = {&read_delimiter, HEX_OP_NONE},
- .s_other = {&read_other, HEX_OP_NONE},
-}};
-
-struct hex_parser;
-typedef struct hex_parser hex_parser_t;
-
-typedef void (*hex_emitter_t)(hex_parser_t *, void *, bool);
-
-struct hex_parser {
- struct {
- int start, stop;
- } p_column, p_idx;
- char p_digits[16 + 1]; /* XXX how many hex digits in an intmax_t? */
- char *p_top;
- const hex_state_t *p_state;
- bool p_starts_0x;
- hex_emitter_t p_emitter;
- void *p_arg;
-};
-
typedef struct chainelt {
TAILQ_ENTRY(chainelt) ce_link;
int ce_column; /* 0: no column alignment,
@@ -178,6 +87,7 @@ typedef enum {
, KIND_INTMAX_DEC
, KIND_INTMAX_HEX
, KIND_INTMAX_0xHEX
+ , KIND_IPv4
, KIND_STRING
} clocc_kind_t;
@@ -195,6 +105,7 @@ typedef struct clocc {
union {
intmax_t u_intmax;
uintmax_t u_uintmax;
+ uint32_t u_ipv4;
} val_u;
} clocc_t;
@@ -235,151 +146,6 @@ static bool freeslices_initialized __ali
static freeslice_t *first_freeslice __aligned(COHERENCY_UNIT);
static freeslice_t freeslices[2048];
-static int dbg_printf(const char *, ...) __printflike(1, 2);
-static int dbg2_printf(const char *, ...) __printflike(1, 2);
-
-#if defined(HB_DEBUG)
-static inline int
-dbg_printf(const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- const int rc = vfprintf(stderr, fmt, ap);
- va_end(ap);
- return rc;
-}
-
-static inline int
-dbg2_printf(const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- const int rc = vfprintf(stderr, fmt, ap);
- va_end(ap);
- return rc;
-}
-#else
-static inline int
-dbg_printf(const char *fmt, ...)
-{
- return 0;
-}
-
-static inline int
-dbg2_printf(const char *fmt, ...)
-{
- return 0;
-}
-#endif
-
-static void
-hex_parser_init(hex_parser_t *p, hex_emitter_t emitter, void *arg)
-{
- memset(p, 0, sizeof(*p));
- p->p_state = &read_delimiter;
- p->p_emitter = emitter;
- p->p_arg = arg;
-}
-
-static const char *
-hex_op_string(hex_op_t op)
-{
- switch (op) {
- case HEX_OP_NONE:
- return "none";
- case HEX_OP_EMIT:
- return "emit";
- case HEX_OP_0xEMIT:
- return "0xemit";
- case HEX_OP_PUSH:
- return "push";
- case HEX_OP_START:
- return "start";
- case HEX_OP_0xSTART:
- return "0xstart";
- default:
- return "unknown";
- }
-}
-
-static void
-hex_parser_drive(hex_parser_t *p, int idx, int column, int c)
-{
- const hex_transition_t *t;
- const hex_state_t *ns, *s;
- bool use0x = false;
-
- s = p->p_state;
-
- if (c == -1 && (ns = s->s_eof.t_newstate) != NULL)
- t = &s->s_eof;
- else if (c == '0' && (ns = s->s_0.t_newstate) != NULL)
- t = &s->s_0;
- else if (c == 'x' && (ns = s->s_x.t_newstate) != NULL)
- t = &s->s_x;
- else if ((isspace(c) || ispunct(c)) &&
- (ns = s->s_delimiter.t_newstate) != NULL)
- t = &s->s_delimiter;
- else if (isxdigit(c) && (ns = s->s_hexdigit.t_newstate) != NULL)
- t = &s->s_hexdigit;
- else if ((ns = s->s_other.t_newstate) != NULL)
- t = &s->s_other;
- else
- ns = NULL;
-
- assert(ns != NULL);
- if (c == -1) {
- dbg_printf("%s: transition (%s, eof) -> %s (op %s)\n", __func__,
- s->s_descr, ns->s_descr, hex_op_string(t->t_op));
- } else {
- dbg_printf("%s: transition (%s, %c) -> %s (op %s)\n", __func__,
- s->s_descr, c, ns->s_descr, hex_op_string(t->t_op));
- }
-
- switch (t->t_op) {
- case HEX_OP_START:
- p->p_column.start = column;
- p->p_idx.start = idx;
- p->p_top = &p->p_digits[0];
- /*FALLTHROUGH*/
- case HEX_OP_PUSH:
- if (p->p_top == NULL)
- ;
- else if (p->p_top - &p->p_digits[0] ==
- __arraycount(p->p_digits) - 1)
- p->p_top = NULL;
- else {
- *p->p_top = c;
- p->p_top++;
- }
- p->p_column.stop = column;
- p->p_idx.stop = idx;
- break;
- case HEX_OP_0xSTART:
- p->p_column.start = column - 1;
- p->p_column.stop = column;
- p->p_idx.start = idx - 1;
- p->p_idx.stop = idx;
- p->p_top = &p->p_digits[0];
- break;
- case HEX_OP_0xEMIT:
- use0x = true;
- /*FALLTHROUGH*/
- case HEX_OP_EMIT:
- if (p->p_top == NULL)
- dbg_printf("hex string too long\n");
- *p->p_top = '\0';
- (*p->p_emitter)(p, p->p_arg, use0x);
- break;
- case HEX_OP_NONE:
- break;
- }
-
- p->p_state = ns;
-}
-
static void
init_freeslices(void)
{
@@ -660,6 +426,36 @@ cloccs_to_column(const clocc_t * const a
}
static chain_t *
+ipv4_clocc(const scratch_t *scratch, int idx_a, int idx_b)
+{
+ int column;
+ char *erasep, *ret;
+ uint32_t combo, mask;
+ const clocc_t * const a = &scratch->Aoccs.occs[idx_a],
+ * const b = &scratch->Boccs.occs[idx_b];
+ char buf[sizeof("255.255.255.255")];
+
+ column = cloccs_to_column(a, b);
+
+ for (mask = 0xffffffff;
+ ((b->val_u.u_ipv4 ^ a->val_u.u_ipv4) & mask) != 0;
+ mask &= (mask - 1))
+ ; // do nothing
+
+ combo = htonl(b->val_u.u_ipv4 & mask);
+
+ ret = inet_net_ntop(AF_INET, &combo, 32, buf, sizeof(buf));
+
+ if ((erasep = strchr(buf, '/')) != NULL)
+ *erasep = '\0';
+
+ if (ret != NULL)
+ return newchain(strdup(buf), column);
+
+ return newchain(strdup("<ipv4>"), column);
+}
+
+static chain_t *
hex_clocc(const scratch_t *scratch, int idx_a, int idx_b, clocc_kind_t kind,
clocc_qual_t qual)
{
@@ -740,6 +536,9 @@ clocc(const scratch_t *scratch, int idx_
if (b->kind == KIND_INTMAX_DEC)
return int_clocc(scratch, idx_a, idx_b);
+ if (b->kind == KIND_IPv4)
+ return ipv4_clocc(scratch, idx_a, idx_b);
+
return newchain(strdup("<word>"), 0);
}
@@ -1178,7 +977,7 @@ scratch_init(scratch_t *scratch, size_t
}
static int
-slicestr(slice_t *s, const char *t)
+slicestr(const slice_t *s, const char *t)
{
unsigned int i;
const char *p;
@@ -1197,32 +996,66 @@ slicestr(slice_t *s, const char *t)
}
static void
-emit_hex_clocc(hex_parser_t *p, void *arg, bool use0x)
+emit_ipv4_clocc(ipv4_detection_t *d, void *arg)
+{
+ cloccs_t *o = arg;
+ struct {
+ uint32_t net;
+ uint32_t host;
+ } addr;
+ int rc;
+
+ dbg_printf("found ipv4 string %s @ [%d, %d]\n", d->d_string,
+ d->d_idx.start, d->d_idx.stop);
+
+ if (o->noccs >= (int)__arraycount(o->occs))
+ return;
+
+ rc = inet_net_pton(AF_INET, d->d_string, &addr.net, sizeof(addr.net));
+
+ assert(rc != -1);
+
+ addr.host = ntohl(addr.net);
+
+ dbg_printf("converted ipv4 string %s @ [%d, %d] -> %08" PRIx32 "\n",
+ d->d_string, d->d_idx.start, d->d_idx.stop, addr.host);
+
+ o->occs[o->noccs].column = d->d_column.start;
+ o->occs[o->noccs].first = d->d_idx.start;
+ o->occs[o->noccs].last = d->d_idx.stop;
+ o->occs[o->noccs].kind = KIND_IPv4;
+ o->occs[o->noccs].qual = QUAL_NONE;
+ o->occs[o->noccs].val_u.u_ipv4 = addr.host;
+ o->noccs++;
+}
+
+static void
+emit_hex_clocc(hex_detection_t *d, void *arg, bool use0x)
{
cloccs_t *o = arg;
intmax_t val;
char *end;
bool allcaps;
- if (!use0x && strspn(p->p_digits, "0123456789") == strlen(p->p_digits))
+ if (!use0x && strspn(d->d_digits, "0123456789") == strlen(d->d_digits))
return;
- allcaps = strcspn(p->p_digits, "abcdef") == strlen(p->p_digits);
+ allcaps = strcspn(d->d_digits, "abcdef") == strlen(d->d_digits);
- dbg_printf("found hex string %s @ [%d, %d]%s\n", p->p_digits,
- p->p_idx.start, p->p_idx.stop, allcaps ? " all CAPS" : "");
+ dbg_printf("found hex string %s @ [%d, %d]%s\n", d->d_digits,
+ d->d_idx.start, d->d_idx.stop, allcaps ? " all CAPS" : "");
if (o->noccs >= (int)__arraycount(o->occs))
return;
- val = strtoimax(p->p_digits, &end, 16);
+ val = strtoimax(d->d_digits, &end, 16);
if (*end != '\0' && errno == ERANGE)
- warnx("%s: over/underflow at %d", __func__, p->p_column.start);
+ warnx("%s: over/underflow at %d", __func__, d->d_column.start);
- o->occs[o->noccs].column = p->p_column.start;
- o->occs[o->noccs].first = p->p_idx.start;
- o->occs[o->noccs].last = p->p_idx.stop;
+ o->occs[o->noccs].column = d->d_column.start;
+ o->occs[o->noccs].first = d->d_idx.start;
+ o->occs[o->noccs].last = d->d_idx.stop;
o->occs[o->noccs].kind = use0x ? KIND_INTMAX_0xHEX : KIND_INTMAX_HEX;
o->occs[o->noccs].qual = allcaps ? QUAL_ALLCAPS : QUAL_NONE;
o->occs[o->noccs].val_u.u_uintmax = val;
@@ -1266,10 +1099,12 @@ cloccs_dedup(cloccs_t *o)
}
static void
-cloccs_init(cloccs_t *o, slice_t *s)
+cloccs_init(cloccs_t *o, const slice_t *s)
{
- hex_parser_t hex_parser;
- size_t column, i, n;
+ hex_parser_t *hex_parser;
+ ipv4_parser_t *ipv4_parser;
+ size_t column, i;
+ size_t n = length(s);
unsigned int j, k;
char digits[64 / 3 + 1]; /* XXX how many digits in an intmax_t? */
@@ -1289,20 +1124,44 @@ cloccs_init(cloccs_t *o, slice_t *s)
o->noccs++;
}
- hex_parser_init(&hex_parser, emit_hex_clocc, o);
+ ipv4_parser = ipv4_parser_alloc(emit_ipv4_clocc, o);
+ if (ipv4_parser == NULL)
+ goto parse_hexadecimal;
column = 0;
- n = length(s);
for (j = 0; j < n; j++) {
char c;
c = get(s, j);
++column;
- hex_parser_drive(&hex_parser, j, column, c);
+ ipv4_parser_drive(ipv4_parser, j, column, c);
if (c == '\n')
column = 0;
}
- hex_parser_drive(&hex_parser, n, column + 1, -1);
+ ipv4_parser_drive(ipv4_parser, n, column + 1, -1);
+
+ ipv4_parser_free(ipv4_parser);
+
+parse_hexadecimal:
+ hex_parser = hex_parser_alloc(emit_hex_clocc, o);
+ if (hex_parser == NULL)
+ goto parse_decimal;
+
+ column = 0;
+ for (j = 0; j < n; j++) {
+ char c;
+
+ c = get(s, j);
+ ++column;
+ hex_parser_drive(hex_parser, j, column, c);
+ if (c == '\n')
+ column = 0;
+ }
+ hex_parser_drive(hex_parser, n, column + 1, -1);
+
+ hex_parser_free(hex_parser);
+
+parse_decimal:
j = 0;
column = 0;
Index: othersrc/external/bsd/arfe/dt/rr/if-re0-if-wm0
diff -u othersrc/external/bsd/arfe/dt/rr/if-re0-if-wm0:1.2 othersrc/external/bsd/arfe/dt/rr/if-re0-if-wm0:1.3
--- othersrc/external/bsd/arfe/dt/rr/if-re0-if-wm0:1.2 Fri Aug 28 21:44:43 2015
+++ othersrc/external/bsd/arfe/dt/rr/if-re0-if-wm0 Wed Sep 2 22:43:17 2015
@@ -4,5 +4,5 @@
address: 0:-25:c:0: a0:80
media: Ethernet autoselect (e)
status: aie
- inet 10.0.1.17 netmask 0xff000000 broadcast -245.-255.-254.0
+ inet 0.0.0.0 netmask 0xff000000 broadcast 0.0.0.0
inet0 fe80::-25:cff:fe00:a080%0 prefixlen 0 scopeid 0x0
Index: othersrc/external/bsd/arfe/dt/rr/if-wm0-if-re0
diff -u othersrc/external/bsd/arfe/dt/rr/if-wm0-if-re0:1.2 othersrc/external/bsd/arfe/dt/rr/if-wm0-if-re0:1.3
--- othersrc/external/bsd/arfe/dt/rr/if-wm0-if-re0:1.2 Fri Aug 28 21:44:43 2015
+++ othersrc/external/bsd/arfe/dt/rr/if-wm0-if-re0 Wed Sep 2 22:43:17 2015
@@ -4,5 +4,5 @@
address: 0:25: c:0: a0:80
media: Ethernet autoselect (e)
status: cie
- inet -10.0.-1.-17 netmask 0xff000000 broadcast 245.255.254.0
+ inet 0.0.0.0 netmask 0xff000000 broadcast 0.0.0.0
inet0 fe80:: 25:cff:fe00:a080%0 prefixlen 0 scopeid 0x0
Index: othersrc/external/bsd/arfe/dt/rr/ifconfig.0-ifconfig.1
diff -u othersrc/external/bsd/arfe/dt/rr/ifconfig.0-ifconfig.1:1.3 othersrc/external/bsd/arfe/dt/rr/ifconfig.0-ifconfig.1:1.4
--- othersrc/external/bsd/arfe/dt/rr/ifconfig.0-ifconfig.1:1.3 Fri Aug 28 21:44:43 2015
+++ othersrc/external/bsd/arfe/dt/rr/ifconfig.0-ifconfig.1 Wed Sep 2 22:43:17 2015
@@ -6,5 +6,5 @@ wm0: flags= 0<UP,BROADCAST,RUNNING,SIM
status: active
input: 61 packets, 5432 bytes, 3 multicasts
output: 30 packets, 3436 bytes, 0 multicasts
- inet 0.0.0. 0 netmask 0xffffff00 broadcast 0.0.0. 0
+ inet 10.0.1.17 netmask 0xffffff00 broadcast 10.0.1.255
inet0 fe80::20a:bff:fecd:1ef%wm0 prefixlen 0 scopeid 0x1
Index: othersrc/external/bsd/arfe/dt/rr/ifconfig.0-logger-ifconfig.0
diff -u othersrc/external/bsd/arfe/dt/rr/ifconfig.0-logger-ifconfig.0:1.3 othersrc/external/bsd/arfe/dt/rr/ifconfig.0-logger-ifconfig.0:1.4
--- othersrc/external/bsd/arfe/dt/rr/ifconfig.0-logger-ifconfig.0:1.3 Fri Aug 28 21:44:43 2015
+++ othersrc/external/bsd/arfe/dt/rr/ifconfig.0-logger-ifconfig.0 Wed Sep 2 22:43:17 2015
@@ -6,5 +6,5 @@ media: Ethernet autoselect (0baseT full-
status: active
input: 0 packets, 0 bytes, 0 multicasts
output: 0 packets, 0 bytes, 0 multicasts
-inet 0.0.0.0 netmask 0xffffff00 broadcast 0.0.0.0
+inet 10.0.1.17 netmask 0xffffff00 broadcast 10.0.1.255
inet0 fe80::20a:bff:fecd:1ef%wm0 prefixlen 0 scopeid 0x1
Index: othersrc/external/bsd/arfe/dt/rr/ifconfig.1-ifconfig.0
diff -u othersrc/external/bsd/arfe/dt/rr/ifconfig.1-ifconfig.0:1.3 othersrc/external/bsd/arfe/dt/rr/ifconfig.1-ifconfig.0:1.4
--- othersrc/external/bsd/arfe/dt/rr/ifconfig.1-ifconfig.0:1.3 Fri Aug 28 21:44:43 2015
+++ othersrc/external/bsd/arfe/dt/rr/ifconfig.1-ifconfig.0 Wed Sep 2 22:43:17 2015
@@ -6,5 +6,5 @@ wm0: flags= 0<UP,BROADCAST,RUNNING,SIM
status: active
input: -61 packets, -5432 bytes, -3 multicasts
output: -30 packets, -3436 bytes, 0 multicasts
- inet 0.0.0. 0 netmask 0xffffff00 broadcast 0.0.0. 0
+ inet 10.0.1.17 netmask 0xffffff00 broadcast 10.0.1.255
inet0 fe80::20a:bff:fecd:1ef%wm0 prefixlen 0 scopeid 0x1
Index: othersrc/external/bsd/arfe/dt/rr/logger-ifconfig.0-ifconfig.0
diff -u othersrc/external/bsd/arfe/dt/rr/logger-ifconfig.0-ifconfig.0:1.3 othersrc/external/bsd/arfe/dt/rr/logger-ifconfig.0-ifconfig.0:1.4
--- othersrc/external/bsd/arfe/dt/rr/logger-ifconfig.0-ifconfig.0:1.3 Fri Aug 28 21:44:43 2015
+++ othersrc/external/bsd/arfe/dt/rr/logger-ifconfig.0-ifconfig.0 Wed Sep 2 22:43:17 2015
@@ -6,5 +6,5 @@ media: Ethernet autoselect (0baseT full-
status: active
input: 0 packets, 0 bytes, 0 multicasts
output: 0 packets, 0 bytes, 0 multicasts
-inet 0.0.0.0 netmask 0xffffff00 broadcast 0.0.0.0
+inet 10.0.1.17 netmask 0xffffff00 broadcast 10.0.1.255
inet0 fe80::20a:bff:fecd:1ef%wm0 prefixlen 0 scopeid 0x1
Index: othersrc/external/bsd/arfe/dt/rr/wm0-a-wm0-b
diff -u othersrc/external/bsd/arfe/dt/rr/wm0-a-wm0-b:1.3 othersrc/external/bsd/arfe/dt/rr/wm0-a-wm0-b:1.4
--- othersrc/external/bsd/arfe/dt/rr/wm0-a-wm0-b:1.3 Fri Aug 28 21:44:43 2015
+++ othersrc/external/bsd/arfe/dt/rr/wm0-a-wm0-b Wed Sep 2 22:43:17 2015
@@ -6,7 +6,7 @@ wm0: flags= 0<UP,BROADCAST,RUNNING,SIM
status: active
input: 112 packets, 11380 bytes, 11 multicasts
output: 60 packets, 11440 bytes, 0 multicasts
- inet 0.0.0. 0 netmask 0xffffff00 broadcast 0.0.0. 0
+ inet 10.0.1.17 netmask 0xffffff00 broadcast 10.0.1.255
inet0 fe80::20a:bff:fecd:1ef%wm0 prefixlen 0 scopeid 0x1
Index: othersrc/external/bsd/arfe/dt/rr/wm0-b-wm0-a
diff -u othersrc/external/bsd/arfe/dt/rr/wm0-b-wm0-a:1.3 othersrc/external/bsd/arfe/dt/rr/wm0-b-wm0-a:1.4
--- othersrc/external/bsd/arfe/dt/rr/wm0-b-wm0-a:1.3 Fri Aug 28 21:44:43 2015
+++ othersrc/external/bsd/arfe/dt/rr/wm0-b-wm0-a Wed Sep 2 22:43:17 2015
@@ -6,7 +6,7 @@ wm0: flags= 0<UP,BROADCAST,RUNNING,SIM
status: active
input: -112 packets, -11380 bytes, -11 multicasts
output: -60 packets, -11440 bytes, 0 multicasts
- inet 0.0.0. 0 netmask 0xffffff00 broadcast 0.0.0. 0
+ inet 10.0.1.17 netmask 0xffffff00 broadcast 10.0.1.255
inet0 fe80::20a:bff:fecd:1ef%wm0 prefixlen 0 scopeid 0x1
Index: othersrc/external/bsd/arfe/it/Makefile
diff -u othersrc/external/bsd/arfe/it/Makefile:1.1 othersrc/external/bsd/arfe/it/Makefile:1.2
--- othersrc/external/bsd/arfe/it/Makefile:1.1 Mon Aug 10 21:10:59 2015
+++ othersrc/external/bsd/arfe/it/Makefile Wed Sep 2 22:43:17 2015
@@ -2,7 +2,7 @@ NOMAN=
.include <bsd.own.mk>
PROG=it
-SRCS+=dt.c
+SRCS+=dt.c hex.c ipv4.c
#CPPFLAGS+=-DHB_DEBUG
DBG+=-g -O3
#DBG+=-g -O0
Index: othersrc/external/bsd/arfe/it/README
diff -u othersrc/external/bsd/arfe/it/README:1.2 othersrc/external/bsd/arfe/it/README:1.3
--- othersrc/external/bsd/arfe/it/README:1.2 Mon Aug 31 01:58:23 2015
+++ othersrc/external/bsd/arfe/it/README Wed Sep 2 22:43:17 2015
@@ -1,3 +1,6 @@
+$ARFE$
+$NetBSD: README,v 1.3 2015/09/02 22:43:17 dyoung Exp $
+
IT---(i)ntegrate (t)ext---is a variation on DT that adds decimal numbers
instead of subtracts, and bitwise-ORs hexadecimal numbers instead of
bitwise-ANDing them. See ../dt/README.
Added files:
Index: othersrc/external/bsd/arfe/dt/dt.h
diff -u /dev/null othersrc/external/bsd/arfe/dt/dt.h:1.1
--- /dev/null Wed Sep 2 22:43:17 2015
+++ othersrc/external/bsd/arfe/dt/dt.h Wed Sep 2 22:43:17 2015
@@ -0,0 +1,69 @@
+/* $NetBSD: dt.h,v 1.1 2015/09/02 22:43:17 dyoung Exp $ */
+/* $ARFE$ */
+
+/*-
+ * Copyright (c) 2014,2015 David Young <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h> /* for __printf_like */
+#include <stdarg.h> /* for va_list, va_start, va_end */
+#include <stdio.h>
+
+static int dbg_printf(const char *, ...) __printflike(1, 2);
+static int dbg2_printf(const char *, ...) __printflike(1, 2);
+
+#if defined(HB_DEBUG)
+static inline int
+dbg_printf(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ const int rc = vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ return rc;
+}
+
+static inline int
+dbg2_printf(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ const int rc = vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ return rc;
+}
+#else
+static inline int
+dbg_printf(const char *fmt, ...)
+{
+ return 0;
+}
+
+static inline int
+dbg2_printf(const char *fmt, ...)
+{
+ return 0;
+}
+#endif
Index: othersrc/external/bsd/arfe/dt/hex.c
diff -u /dev/null othersrc/external/bsd/arfe/dt/hex.c:1.1
--- /dev/null Wed Sep 2 22:43:17 2015
+++ othersrc/external/bsd/arfe/dt/hex.c Wed Sep 2 22:43:17 2015
@@ -0,0 +1,253 @@
+/* $NetBSD: hex.c,v 1.1 2015/09/02 22:43:17 dyoung Exp $ */
+/* $ARFE$ */
+
+/*-
+ * Copyright (c) 2014,2015 David Young <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <assert.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "dt.h"
+#include "hex.h"
+
+typedef enum hex_op {
+ HEX_OP_NONE = 0
+ , HEX_OP_PUSH
+ , HEX_OP_EMIT
+ , HEX_OP_0xEMIT
+ , HEX_OP_START
+ , HEX_OP_0xSTART
+} hex_op_t;
+
+struct hex_state;
+typedef struct hex_state hex_state_t;
+
+typedef struct hex_transition {
+ const hex_state_t *t_newstate;
+ hex_op_t t_op;
+} hex_transition_t;
+
+struct hex_state {
+ const char *s_descr;
+ hex_transition_t s_other;
+ hex_transition_t s_hexdigit;
+ hex_transition_t s_0;
+ hex_transition_t s_x;
+ hex_transition_t s_delimiter;
+ hex_transition_t s_eof;
+};
+
+enum hex_state_idxs {
+ READ_0
+ , READ_X
+ , READ_0xHEXDIGIT
+ , READ_HEXDIGIT
+ , READ_EOF
+ , READ_OTHER
+ , READ_DELIMITER
+};
+
+#define read_0 hex_states[READ_0]
+#define read_x hex_states[READ_X]
+#define read_0xhexdigit hex_states[READ_0xHEXDIGIT]
+#define read_hexdigit hex_states[READ_HEXDIGIT]
+#define read_eof hex_states[READ_EOF]
+#define read_other hex_states[READ_OTHER]
+#define read_delimiter hex_states[READ_DELIMITER]
+
+static const hex_state_t hex_states[] = {[READ_0] = {
+ .s_descr = "read 0",
+ .s_other = {&read_other, HEX_OP_NONE},
+ .s_hexdigit = {&read_hexdigit, HEX_OP_PUSH},
+ .s_x = {&read_x, HEX_OP_0xSTART},
+}, [READ_X] = {
+ .s_descr = "read x",
+ .s_other = {&read_other, HEX_OP_NONE},
+ .s_hexdigit = {&read_0xhexdigit, HEX_OP_PUSH},
+}, [READ_0xHEXDIGIT] = {
+ .s_descr = "read 0xhexdigit",
+ .s_other = {&read_other, HEX_OP_NONE},
+ .s_delimiter = {&read_delimiter, HEX_OP_0xEMIT},
+ .s_eof = {&read_eof, HEX_OP_0xEMIT},
+ .s_hexdigit = {&read_0xhexdigit, HEX_OP_PUSH},
+}, [READ_HEXDIGIT] = {
+ .s_descr = "read hexdigit",
+ .s_other = {&read_other, HEX_OP_NONE},
+ .s_delimiter = {&read_delimiter, HEX_OP_EMIT},
+ .s_eof = {&read_eof, HEX_OP_EMIT},
+ .s_hexdigit = {&read_hexdigit, HEX_OP_PUSH},
+}, [READ_EOF] = {
+ .s_descr = "read eof",
+ .s_other = {&read_eof, HEX_OP_NONE},
+}, [READ_OTHER] = {
+ .s_descr = "read other",
+ .s_other = {&read_other, HEX_OP_NONE},
+ .s_delimiter = {&read_delimiter, HEX_OP_NONE},
+}, [READ_DELIMITER] = {
+ .s_descr = "read delimiter",
+ .s_0 = {&read_0, HEX_OP_START},
+ .s_hexdigit = {&read_hexdigit, HEX_OP_START},
+ .s_delimiter = {&read_delimiter, HEX_OP_NONE},
+ .s_other = {&read_other, HEX_OP_NONE},
+}};
+
+struct hex_parser {
+ hex_detection_t p_detection;
+#define p_column p_detection.d_column
+#define p_digits p_detection.d_digits
+#define p_idx p_detection.d_idx
+ char *p_top;
+ const hex_state_t *p_state;
+ bool p_starts_0x;
+ hex_emitter_t p_emitter;
+ void *p_arg;
+};
+
+void
+hex_parser_free(hex_parser_t *p)
+{
+ free(p);
+}
+
+static void
+hex_parser_init(hex_parser_t *p, hex_emitter_t emitter, void *arg)
+{
+ memset(p, 0, sizeof(*p));
+ p->p_state = &read_delimiter;
+ p->p_emitter = emitter;
+ p->p_arg = arg;
+}
+
+hex_parser_t *
+hex_parser_alloc(hex_emitter_t emitter, void *arg)
+{
+ hex_parser_t *p;
+
+ p = malloc(sizeof(*p));
+ if (p == NULL)
+ return NULL;
+
+ hex_parser_init(p, emitter, arg);
+ return p;
+}
+
+static const char *
+hex_op_string(hex_op_t op)
+{
+ switch (op) {
+ case HEX_OP_NONE:
+ return "none";
+ case HEX_OP_EMIT:
+ return "emit";
+ case HEX_OP_0xEMIT:
+ return "0xemit";
+ case HEX_OP_PUSH:
+ return "push";
+ case HEX_OP_START:
+ return "start";
+ case HEX_OP_0xSTART:
+ return "0xstart";
+ default:
+ return "unknown";
+ }
+}
+
+void
+hex_parser_drive(hex_parser_t *p, int idx, int column, int c)
+{
+ const hex_transition_t *t;
+ const hex_state_t *ns, *s;
+ bool use0x = false;
+
+ s = p->p_state;
+
+ if (c == -1 && (ns = s->s_eof.t_newstate) != NULL)
+ t = &s->s_eof;
+ else if (c == '0' && (ns = s->s_0.t_newstate) != NULL)
+ t = &s->s_0;
+ else if (c == 'x' && (ns = s->s_x.t_newstate) != NULL)
+ t = &s->s_x;
+ else if ((isspace(c) || ispunct(c)) &&
+ (ns = s->s_delimiter.t_newstate) != NULL)
+ t = &s->s_delimiter;
+ else if (isxdigit(c) && (ns = s->s_hexdigit.t_newstate) != NULL)
+ t = &s->s_hexdigit;
+ else if ((ns = s->s_other.t_newstate) != NULL)
+ t = &s->s_other;
+ else
+ ns = NULL;
+
+ assert(ns != NULL);
+ if (c == -1) {
+ dbg_printf("%s: transition (%s, eof) -> %s (op %s)\n", __func__,
+ s->s_descr, ns->s_descr, hex_op_string(t->t_op));
+ } else {
+ dbg_printf("%s: transition (%s, %c) -> %s (op %s)\n", __func__,
+ s->s_descr, c, ns->s_descr, hex_op_string(t->t_op));
+ }
+
+ switch (t->t_op) {
+ case HEX_OP_START:
+ p->p_column.start = column;
+ p->p_idx.start = idx;
+ p->p_top = &p->p_digits[0];
+ /*FALLTHROUGH*/
+ case HEX_OP_PUSH:
+ if (p->p_top == NULL)
+ ;
+ else if (p->p_top - &p->p_digits[0] ==
+ __arraycount(p->p_digits) - 1)
+ p->p_top = NULL;
+ else {
+ *p->p_top = c;
+ p->p_top++;
+ }
+ p->p_column.stop = column;
+ p->p_idx.stop = idx;
+ break;
+ case HEX_OP_0xSTART:
+ p->p_column.start = column - 1;
+ p->p_column.stop = column;
+ p->p_idx.start = idx - 1;
+ p->p_idx.stop = idx;
+ p->p_top = &p->p_digits[0];
+ break;
+ case HEX_OP_0xEMIT:
+ use0x = true;
+ /*FALLTHROUGH*/
+ case HEX_OP_EMIT:
+ if (p->p_top == NULL)
+ dbg_printf("hex string too long\n");
+ *p->p_top = '\0';
+ (*p->p_emitter)(&p->p_detection, p->p_arg, use0x);
+ break;
+ case HEX_OP_NONE:
+ break;
+ }
+
+ p->p_state = ns;
+}
+
Index: othersrc/external/bsd/arfe/dt/hex.h
diff -u /dev/null othersrc/external/bsd/arfe/dt/hex.h:1.1
--- /dev/null Wed Sep 2 22:43:17 2015
+++ othersrc/external/bsd/arfe/dt/hex.h Wed Sep 2 22:43:17 2015
@@ -0,0 +1,48 @@
+/* $NetBSD: hex.h,v 1.1 2015/09/02 22:43:17 dyoung Exp $ */
+/* $ARFE$ */
+
+/*-
+ * Copyright (c) 2014,2015 David Young <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _HEX_H
+#define _HEX_H
+
+#include <stdbool.h>
+
+typedef struct hex_detection {
+ struct {
+ int start, stop;
+ } d_column, d_idx;
+ char d_digits[16 + 1]; /* XXX how many hex digits in an intmax_t? */
+} hex_detection_t;
+
+struct hex_parser;
+typedef struct hex_parser hex_parser_t;
+
+typedef void (*hex_emitter_t)(hex_detection_t *, void *, bool);
+hex_parser_t *hex_parser_alloc(hex_emitter_t, void *);
+void hex_parser_drive(hex_parser_t *, int, int, int);
+void hex_parser_free(hex_parser_t *);
+
+#endif /* _HEX_H */
Index: othersrc/external/bsd/arfe/dt/ipv4.c
diff -u /dev/null othersrc/external/bsd/arfe/dt/ipv4.c:1.1
--- /dev/null Wed Sep 2 22:43:17 2015
+++ othersrc/external/bsd/arfe/dt/ipv4.c Wed Sep 2 22:43:17 2015
@@ -0,0 +1,499 @@
+/* $NetBSD: ipv4.c,v 1.1 2015/09/02 22:43:17 dyoung Exp $ */
+/* $ARFE$ */
+
+/*-
+ * Copyright (c) 2014,2015 David Young <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <assert.h>
+#include <ctype.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/cdefs.h> /* for __predict_true() */
+
+#include "dt.h"
+#include "ipv4.h"
+
+typedef enum ipv4_op {
+ IPV4_OP_NONE = 0
+ , IPV4_OP_PUSH
+ , IPV4_OP_EMIT
+ , IPV4_OP_START
+} ipv4_op_t;
+
+struct ipv4_state;
+typedef struct ipv4_state ipv4_state_t;
+
+typedef struct ipv4_transition {
+ const ipv4_state_t *t_newstate;
+ ipv4_op_t t_op;
+} ipv4_transition_t;
+
+struct ipv4_state {
+ const char *s_descr;
+ ipv4_transition_t s_delimiter;
+ ipv4_transition_t s_eof;
+ ipv4_transition_t s_other;
+ /*
+ * The following members have to be consecutive, s_0 first,
+ * s_dot last.
+ */
+ ipv4_transition_t s_0;
+ ipv4_transition_t s_0_4;
+ ipv4_transition_t s_0_5;
+ ipv4_transition_t s_0_9;
+ ipv4_transition_t s_1;
+ ipv4_transition_t s_2;
+ ipv4_transition_t s_3_9;
+ ipv4_transition_t s_5;
+ ipv4_transition_t s_6;
+ ipv4_transition_t s_dot;
+};
+
+enum ipv4_state_idxs {
+ READ_OTHER = 0
+ , READ_DELIMITER /* Initial state: beginning of file, or read
+ * Space, or read punctuation other than '.'
+ */
+ , READ_EOF
+ , FIRST_NUMBER
+ , READ_DOT = FIRST_NUMBER
+ , EXPECTING_DOT
+ , READ_1
+ , READ_100_199
+ , READ_10_19
+ , READ_2
+ , READ_20_24
+ , READ_200_249
+ , READ_25
+ , READ_250_255
+ , READ_3_9
+ , SECOND_NUMBER
+ , THIRD_NUMBER = FIRST_NUMBER + (SECOND_NUMBER - FIRST_NUMBER) * 2
+ , FOURTH_NUMBER = FIRST_NUMBER + (SECOND_NUMBER - FIRST_NUMBER) * 3
+};
+
+__CTASSERT(SECOND_NUMBER > FIRST_NUMBER)
+
+#define __skip(__n) ((SECOND_NUMBER - FIRST_NUMBER) * ((__n) - 1))
+
+#define expecting_dot(__n) ipv4_states[EXPECTING_DOT + __skip(__n)]
+#define read_dot(__n) ipv4_states[READ_DOT + __skip(__n)]
+#define read_1(__n) ipv4_states[READ_1 + __skip(__n)]
+#define read_100_199(__n) ipv4_states[READ_100_199 + __skip(__n)]
+#define read_10_19(__n) ipv4_states[READ_10_19 + __skip(__n)]
+#define read_2(__n) ipv4_states[READ_2 + __skip(__n)]
+#define read_20_24(__n) ipv4_states[READ_20_24 + __skip(__n)]
+#define read_200_249(__n) ipv4_states[READ_200_249 + __skip(__n)]
+#define read_25(__n) ipv4_states[READ_25 + __skip(__n)]
+#define read_250_255(__n) ipv4_states[READ_250_255 + __skip(__n)]
+#define read_3_9(__n) ipv4_states[READ_3_9 + __skip(__n)]
+#define read_other ipv4_states[READ_OTHER]
+#define read_delimiter ipv4_states[READ_DELIMITER]
+#define read_eof ipv4_states[READ_EOF]
+
+#define first(__n) (__skip(1) + __n)
+#define second(__n) (__skip(2) + __n)
+#define third(__n) (__skip(3) + __n)
+#define fourth(__n) (__skip(4) + __n)
+
+static ipv4_state_t ipv4_states[] = {
+ [READ_DELIMITER] = { // punct in notebook, 29 Aug 2015
+ .s_descr = "read delimiter"
+ , .s_delimiter = {&read_delimiter, IPV4_OP_NONE}
+ , .s_eof = {&read_eof, IPV4_OP_NONE}
+ , .s_other = {&read_other, IPV4_OP_NONE}
+ , .s_0 = {&expecting_dot(1), IPV4_OP_START}
+ , .s_1 = {&read_1(1), IPV4_OP_START}
+ , .s_2 = {&read_2(1), IPV4_OP_START}
+ , .s_3_9 = {&read_3_9(1), IPV4_OP_START}
+}, [READ_EOF] = {
+ .s_descr = "read eof",
+ .s_other = {&read_eof, IPV4_OP_NONE},
+}, [READ_OTHER] = {
+ .s_descr = "read other",
+ .s_other = {&read_other, IPV4_OP_NONE},
+ .s_delimiter = {&read_delimiter, IPV4_OP_NONE},
+}, [first(READ_DOT)] = { // ? in notebook
+ .s_descr = "read dot"
+ , .s_delimiter = {&read_delimiter, IPV4_OP_NONE}
+ , .s_eof = {&read_eof, IPV4_OP_NONE}
+ , .s_0 = {&expecting_dot(2), IPV4_OP_PUSH}
+ , .s_1 = {&read_1(2), IPV4_OP_PUSH}
+ , .s_2 = {&read_2(2), IPV4_OP_PUSH}
+ , .s_3_9 = {&read_3_9(2), IPV4_OP_PUSH}
+ , .s_other = {&read_other, IPV4_OP_NONE}
+}, [first(EXPECTING_DOT)] = { // a, k, e, g in notebook
+ .s_descr = "expecting dot"
+ , .s_delimiter = {&read_delimiter, IPV4_OP_NONE}
+ , .s_eof = {&read_eof, IPV4_OP_NONE}
+ , .s_dot = {&read_dot(1), IPV4_OP_PUSH}
+ , .s_other = {&read_other, IPV4_OP_NONE}
+}, [first(READ_1)] = { // c in notebook
+ .s_descr = "read 1"
+ , .s_dot = {&read_dot(1), IPV4_OP_PUSH}
+ , .s_delimiter = {&read_delimiter, IPV4_OP_NONE}
+ , .s_eof = {&read_eof, IPV4_OP_NONE}
+ , .s_other = {&read_other, IPV4_OP_NONE}
+ , .s_0_9 = {&read_10_19(1), IPV4_OP_PUSH}
+}, [first(READ_2)] = { // d in notebook
+ .s_descr = "read 2"
+ , .s_dot = {&read_dot(1), IPV4_OP_PUSH}
+ , .s_delimiter = {&read_delimiter, IPV4_OP_NONE}
+ , .s_eof = {&read_eof, IPV4_OP_NONE}
+ , .s_other = {&read_other, IPV4_OP_NONE}
+ , .s_6 = {&expecting_dot(1), IPV4_OP_PUSH}
+ , .s_5 = {&read_25(1), IPV4_OP_PUSH}
+ , .s_0_4 = {&read_20_24(1), IPV4_OP_PUSH}
+}, [first(READ_3_9)] = { // i in notebook
+ .s_descr = "read [3-9]"
+ , .s_dot = {&read_dot(1), IPV4_OP_PUSH}
+ , .s_delimiter = {&read_delimiter, IPV4_OP_NONE}
+ , .s_eof = {&read_eof, IPV4_OP_NONE}
+ , .s_0_9 = {&expecting_dot(1), IPV4_OP_PUSH}
+ , .s_other = {&read_other, IPV4_OP_NONE}
+}, [first(READ_10_19)] = { // j in notebook
+ .s_descr = "read 1[0-9]"
+ , .s_dot = {&read_dot(1), IPV4_OP_PUSH}
+ , .s_delimiter = {&read_delimiter, IPV4_OP_NONE}
+ , .s_eof = {&read_eof, IPV4_OP_NONE}
+ , .s_other = {&read_other, IPV4_OP_NONE}
+ , .s_0_9 = {&expecting_dot(1), IPV4_OP_PUSH}
+}, [first(READ_25)] = { // f in notebook
+ .s_descr = "read 25"
+ , .s_dot = {&read_dot(1), IPV4_OP_PUSH}
+ , .s_delimiter = {&read_delimiter, IPV4_OP_NONE}
+ , .s_eof = {&read_eof, IPV4_OP_NONE}
+ , .s_other = {&read_other, IPV4_OP_NONE}
+ , .s_0_5 = {&expecting_dot(1), IPV4_OP_PUSH}
+}, [first(READ_20_24)] = { // h in notebook
+ .s_descr = "read 2[0-4]"
+ , .s_dot = {&read_dot(1), IPV4_OP_PUSH}
+ , .s_delimiter = {&read_delimiter, IPV4_OP_NONE}
+ , .s_eof = {&read_eof, IPV4_OP_NONE}
+ , .s_other = {&read_other, IPV4_OP_NONE}
+ , .s_0_9 = {&expecting_dot(1), IPV4_OP_PUSH}
+}, [second(READ_DOT)] = { // ? in notebook
+ .s_descr = "read dot 2"
+ , .s_delimiter = {&read_delimiter, IPV4_OP_NONE}
+ , .s_eof = {&read_eof, IPV4_OP_NONE}
+ , .s_0 = {&expecting_dot(3), IPV4_OP_PUSH}
+ , .s_1 = {&read_1(3), IPV4_OP_PUSH}
+ , .s_2 = {&read_2(3), IPV4_OP_PUSH}
+ , .s_3_9 = {&read_3_9(3), IPV4_OP_PUSH}
+ , .s_other = {&read_other, IPV4_OP_NONE}
+}, [second(EXPECTING_DOT)] = { // a, k, e, g in notebook
+ .s_descr = "expecting dot 2"
+ , .s_delimiter = {&read_delimiter, IPV4_OP_NONE}
+ , .s_eof = {&read_eof, IPV4_OP_NONE}
+ , .s_dot = {&read_dot(2), IPV4_OP_PUSH}
+ , .s_other = {&read_other, IPV4_OP_NONE}
+}, [second(READ_1)] = { // c in notebook
+ .s_descr = "read 1"
+ , .s_dot = {&read_dot(2), IPV4_OP_PUSH}
+ , .s_delimiter = {&read_delimiter, IPV4_OP_NONE}
+ , .s_eof = {&read_eof, IPV4_OP_NONE}
+ , .s_other = {&read_other, IPV4_OP_NONE}
+ , .s_0_9 = {&read_10_19(2), IPV4_OP_PUSH}
+}, [second(READ_2)] = { // d in notebook
+ .s_descr = "read 2"
+ , .s_dot = {&read_dot(2), IPV4_OP_PUSH}
+ , .s_delimiter = {&read_delimiter, IPV4_OP_NONE}
+ , .s_eof = {&read_eof, IPV4_OP_NONE}
+ , .s_other = {&read_other, IPV4_OP_NONE}
+ , .s_6 = {&expecting_dot(2), IPV4_OP_PUSH}
+ , .s_5 = {&read_25(2), IPV4_OP_PUSH}
+ , .s_0_4 = {&read_20_24(2), IPV4_OP_PUSH}
+}, [second(READ_3_9)] = { // i in notebook
+ .s_descr = "read [3-9]"
+ , .s_dot = {&read_dot(2), IPV4_OP_PUSH}
+ , .s_delimiter = {&read_delimiter, IPV4_OP_NONE}
+ , .s_eof = {&read_eof, IPV4_OP_NONE}
+ , .s_0_9 = {&expecting_dot(2), IPV4_OP_PUSH}
+ , .s_other = {&read_other, IPV4_OP_NONE}
+}, [second(READ_10_19)] = { // j in notebook
+ .s_descr = "read 1[0-9]"
+ , .s_dot = {&read_dot(2), IPV4_OP_PUSH}
+ , .s_delimiter = {&read_delimiter, IPV4_OP_NONE}
+ , .s_eof = {&read_eof, IPV4_OP_NONE}
+ , .s_other = {&read_other, IPV4_OP_NONE}
+ , .s_0_9 = {&expecting_dot(2), IPV4_OP_PUSH}
+}, [second(READ_25)] = { // f in notebook
+ .s_descr = "read 25"
+ , .s_dot = {&read_dot(2), IPV4_OP_PUSH}
+ , .s_delimiter = {&read_delimiter, IPV4_OP_NONE}
+ , .s_eof = {&read_eof, IPV4_OP_NONE}
+ , .s_other = {&read_other, IPV4_OP_NONE}
+ , .s_0_5 = {&expecting_dot(2), IPV4_OP_PUSH}
+}, [second(READ_20_24)] = { // h in notebook
+ .s_descr = "read 2[0-4]"
+ , .s_dot = {&read_dot(2), IPV4_OP_PUSH}
+ , .s_delimiter = {&read_delimiter, IPV4_OP_NONE}
+ , .s_eof = {&read_eof, IPV4_OP_NONE}
+ , .s_other = {&read_other, IPV4_OP_NONE}
+ , .s_0_9 = {&expecting_dot(2), IPV4_OP_PUSH}
+}, [third(READ_DOT)] = { // ? in notebook
+ .s_descr = "read dot 2"
+ , .s_delimiter = {&read_delimiter, IPV4_OP_NONE}
+ , .s_eof = {&read_eof, IPV4_OP_NONE}
+ , .s_0 = {&expecting_dot(4), IPV4_OP_PUSH}
+ , .s_1 = {&read_1(4), IPV4_OP_PUSH}
+ , .s_2 = {&read_2(4), IPV4_OP_PUSH}
+ , .s_3_9 = {&read_3_9(4), IPV4_OP_PUSH}
+ , .s_other = {&read_other, IPV4_OP_NONE}
+}, [third(EXPECTING_DOT)] = { // a, k, e, g in notebook
+ .s_descr = "expecting dot"
+ , .s_delimiter = {&read_delimiter, IPV4_OP_NONE}
+ , .s_eof = {&read_eof, IPV4_OP_NONE}
+ , .s_dot = {&read_dot(3), IPV4_OP_PUSH}
+ , .s_other = {&read_other, IPV4_OP_NONE}
+}, [third(READ_1)] = { // c in notebook
+ .s_descr = "read 1"
+ , .s_dot = {&read_dot(3), IPV4_OP_PUSH}
+ , .s_delimiter = {&read_delimiter, IPV4_OP_NONE}
+ , .s_eof = {&read_eof, IPV4_OP_NONE}
+ , .s_other = {&read_other, IPV4_OP_NONE}
+ , .s_0_9 = {&read_10_19(3), IPV4_OP_PUSH}
+}, [third(READ_2)] = { // d in notebook
+ .s_descr = "read 2"
+ , .s_dot = {&read_dot(3), IPV4_OP_PUSH}
+ , .s_delimiter = {&read_delimiter, IPV4_OP_NONE}
+ , .s_eof = {&read_eof, IPV4_OP_NONE}
+ , .s_other = {&read_other, IPV4_OP_NONE}
+ , .s_6 = {&expecting_dot(3), IPV4_OP_PUSH}
+ , .s_5 = {&read_25(3), IPV4_OP_PUSH}
+ , .s_0_4 = {&read_20_24(3), IPV4_OP_PUSH}
+}, [third(READ_3_9)] = { // i in notebook
+ .s_descr = "read [3-9]"
+ , .s_dot = {&read_dot(3), IPV4_OP_PUSH}
+ , .s_delimiter = {&read_delimiter, IPV4_OP_NONE}
+ , .s_eof = {&read_eof, IPV4_OP_NONE}
+ , .s_0_9 = {&expecting_dot(3), IPV4_OP_PUSH}
+ , .s_other = {&read_other, IPV4_OP_NONE}
+}, [third(READ_10_19)] = { // j in notebook
+ .s_descr = "read 1[0-9]"
+ , .s_dot = {&read_dot(3), IPV4_OP_PUSH}
+ , .s_delimiter = {&read_delimiter, IPV4_OP_NONE}
+ , .s_eof = {&read_eof, IPV4_OP_NONE}
+ , .s_other = {&read_other, IPV4_OP_NONE}
+ , .s_0_9 = {&expecting_dot(3), IPV4_OP_PUSH}
+}, [third(READ_25)] = { // f in notebook
+ .s_descr = "read 25"
+ , .s_dot = {&read_dot(3), IPV4_OP_PUSH}
+ , .s_delimiter = {&read_delimiter, IPV4_OP_NONE}
+ , .s_eof = {&read_eof, IPV4_OP_NONE}
+ , .s_other = {&read_other, IPV4_OP_NONE}
+ , .s_0_5 = {&expecting_dot(3), IPV4_OP_PUSH}
+}, [third(READ_20_24)] = { // h in notebook
+ .s_descr = "read 2[0-4]"
+ , .s_dot = {&read_dot(3), IPV4_OP_PUSH}
+ , .s_delimiter = {&read_delimiter, IPV4_OP_NONE}
+ , .s_eof = {&read_eof, IPV4_OP_NONE}
+ , .s_other = {&read_other, IPV4_OP_NONE}
+ , .s_0_9 = {&expecting_dot(3), IPV4_OP_PUSH}
+}, [fourth(EXPECTING_DOT)] = { // a, k, e, g in notebook
+ .s_descr = "expecting dot"
+ , .s_delimiter = {&read_delimiter, IPV4_OP_EMIT}
+ , .s_eof = {&read_eof, IPV4_OP_EMIT}
+ , .s_other = {&read_other, IPV4_OP_NONE}
+}, [fourth(READ_1)] = { // c in notebook
+ .s_descr = "read 1"
+ , .s_delimiter = {&read_delimiter, IPV4_OP_EMIT}
+ , .s_eof = {&read_eof, IPV4_OP_EMIT}
+ , .s_other = {&read_other, IPV4_OP_NONE}
+ , .s_0_9 = {&read_10_19(4), IPV4_OP_PUSH}
+}, [fourth(READ_2)] = { // d in notebook
+ .s_descr = "read 2"
+ , .s_delimiter = {&read_delimiter, IPV4_OP_EMIT}
+ , .s_eof = {&read_eof, IPV4_OP_EMIT}
+ , .s_other = {&read_other, IPV4_OP_NONE}
+ , .s_6 = {&expecting_dot(4), IPV4_OP_PUSH}
+ , .s_5 = {&read_25(4), IPV4_OP_PUSH}
+ , .s_0_4 = {&read_20_24(4), IPV4_OP_PUSH}
+}, [fourth(READ_3_9)] = { // i in notebook
+ .s_descr = "read [3-9]"
+ , .s_delimiter = {&read_delimiter, IPV4_OP_EMIT}
+ , .s_eof = {&read_eof, IPV4_OP_EMIT}
+ , .s_0_9 = {&expecting_dot(4), IPV4_OP_PUSH}
+ , .s_other = {&read_other, IPV4_OP_NONE}
+}, [fourth(READ_10_19)] = { // j in notebook
+ .s_descr = "read 1[0-9]"
+ , .s_delimiter = {&read_delimiter, IPV4_OP_EMIT}
+ , .s_eof = {&read_eof, IPV4_OP_EMIT}
+ , .s_other = {&read_other, IPV4_OP_NONE}
+ , .s_0_9 = {&expecting_dot(4), IPV4_OP_PUSH}
+}, [fourth(READ_25)] = { // f in notebook
+ .s_descr = "read 25"
+ , .s_delimiter = {&read_delimiter, IPV4_OP_EMIT}
+ , .s_eof = {&read_eof, IPV4_OP_EMIT}
+ , .s_other = {&read_other, IPV4_OP_NONE}
+ , .s_0_5 = {&expecting_dot(4), IPV4_OP_PUSH}
+}, [fourth(READ_20_24)] = { // h in notebook
+ .s_descr = "read 2[0-4]"
+ , .s_delimiter = {&read_delimiter, IPV4_OP_EMIT}
+ , .s_eof = {&read_eof, IPV4_OP_EMIT}
+ , .s_other = {&read_other, IPV4_OP_NONE}
+ , .s_0_9 = {&expecting_dot(4), IPV4_OP_PUSH}
+}};
+
+struct ipv4_parser {
+ ipv4_detection_t p_detection;
+#define p_column p_detection.d_column
+#define p_string p_detection.d_string
+#define p_idx p_detection.d_idx
+ char *p_last;
+ const ipv4_state_t *p_state;
+ ipv4_emitter_t p_emitter;
+ void *p_arg;
+};
+
+void
+ipv4_parser_free(ipv4_parser_t *p)
+{
+ free(p);
+}
+
+static void
+ipv4_parser_init(ipv4_parser_t *p, ipv4_emitter_t emitter, void *arg)
+{
+ memset(p, 0, sizeof(*p));
+ p->p_state = &read_delimiter;
+ p->p_emitter = emitter;
+ p->p_arg = arg;
+}
+
+ipv4_parser_t *
+ipv4_parser_alloc(ipv4_emitter_t emitter, void *arg)
+{
+ ipv4_parser_t *p;
+
+ p = malloc(sizeof(*p));
+ if (p == NULL)
+ return NULL;
+
+ ipv4_parser_init(p, emitter, arg);
+ return p;
+}
+
+static const char *
+ipv4_op_string(ipv4_op_t op)
+{
+ switch (op) {
+ case IPV4_OP_NONE:
+ return "none";
+ case IPV4_OP_EMIT:
+ return "emit";
+ case IPV4_OP_PUSH:
+ return "push";
+ case IPV4_OP_START:
+ return "start";
+ default:
+ return "unknown";
+ }
+}
+
+void
+ipv4_parser_drive(ipv4_parser_t *p, int idx, int column, int c)
+{
+ const ipv4_transition_t *t;
+ const ipv4_state_t *ns, *s;
+
+ s = p->p_state;
+
+ if (c == -1 && (ns = s->s_eof.t_newstate) != NULL)
+ t = &s->s_eof;
+ else if (c == '0' && (ns = s->s_0.t_newstate) != NULL)
+ t = &s->s_0;
+ else if (c == '1' && (ns = s->s_1.t_newstate) != NULL)
+ t = &s->s_1;
+ else if (c == '2' && (ns = s->s_2.t_newstate) != NULL)
+ t = &s->s_2;
+ else if (c == '5' && (ns = s->s_5.t_newstate) != NULL)
+ t = &s->s_5;
+ else if (c == '6' && (ns = s->s_6.t_newstate) != NULL)
+ t = &s->s_6;
+ else if (strchr("3456789", c) != NULL &&
+ (ns = s->s_3_9.t_newstate) != NULL)
+ t = &s->s_3_9;
+ else if (strchr("01234", c) != NULL &&
+ (ns = s->s_0_4.t_newstate) != NULL)
+ t = &s->s_0_4;
+ else if (strchr("012345", c) != NULL &&
+ (ns = s->s_0_5.t_newstate) != NULL)
+ t = &s->s_0_5;
+ else if (strchr("0123456789", c) != NULL &&
+ (ns = s->s_0_9.t_newstate) != NULL)
+ t = &s->s_0_9;
+ else if (c == '.' && (ns = s->s_dot.t_newstate) != NULL)
+ t = &s->s_dot;
+ else if ((isspace(c) || ispunct(c)) &&
+ (ns = s->s_delimiter.t_newstate) != NULL)
+ t = &s->s_delimiter;
+ else if ((ns = s->s_other.t_newstate) != NULL)
+ t = &s->s_other;
+ else
+ ns = NULL;
+
+ assert(ns != NULL);
+ if (c == -1) {
+ dbg_printf("%s: transition (%s, eof) -> %s (op %s)\n", __func__,
+ s->s_descr, ns->s_descr, ipv4_op_string(t->t_op));
+ } else {
+ dbg_printf("%s: transition (%s, %c) -> %s (op %s)\n", __func__,
+ s->s_descr, c, ns->s_descr, ipv4_op_string(t->t_op));
+ }
+
+ switch (t->t_op) {
+ case IPV4_OP_START:
+ p->p_column.start = column;
+ p->p_idx.start = idx;
+ p->p_last = &p->p_string[0];
+ /*FALLTHROUGH*/
+ case IPV4_OP_PUSH:
+ if (p->p_last == NULL)
+ ;
+ else if (p->p_last - &p->p_string[0] ==
+ __arraycount(p->p_string) - 1)
+ p->p_last = NULL;
+ else {
+ *p->p_last = c;
+ p->p_last++;
+ }
+ p->p_column.stop = column;
+ p->p_idx.stop = idx;
+ break;
+ case IPV4_OP_EMIT:
+ if (p->p_last == NULL)
+ dbg_printf("hex string too long\n");
+ *p->p_last = '\0';
+ (*p->p_emitter)(&p->p_detection, p->p_arg);
+ break;
+ case IPV4_OP_NONE:
+ break;
+ }
+
+ p->p_state = ns;
+}
+
Index: othersrc/external/bsd/arfe/dt/ipv4.h
diff -u /dev/null othersrc/external/bsd/arfe/dt/ipv4.h:1.1
--- /dev/null Wed Sep 2 22:43:17 2015
+++ othersrc/external/bsd/arfe/dt/ipv4.h Wed Sep 2 22:43:17 2015
@@ -0,0 +1,46 @@
+/* $NetBSD: ipv4.h,v 1.1 2015/09/02 22:43:17 dyoung Exp $ */
+/* $ARFE$ */
+
+/*-
+ * Copyright (c) 2014,2015 David Young <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _IPV4_H_
+#define _IPV4_H_
+
+typedef struct ipv4_detection {
+ struct {
+ int start, stop;
+ } d_column, d_idx;
+ char d_string[sizeof("255.255.255.255")];
+} ipv4_detection_t;
+
+struct ipv4_parser;
+typedef struct ipv4_parser ipv4_parser_t;
+
+typedef void (*ipv4_emitter_t)(ipv4_detection_t *, void *);
+ipv4_parser_t *ipv4_parser_alloc(ipv4_emitter_t, void *);
+void ipv4_parser_drive(ipv4_parser_t *, int, int, int);
+void ipv4_parser_free(ipv4_parser_t *);
+
+#endif /* _IPV4_H_ */