summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Ovsienko <denis@ovsienko.info>2023-03-12 16:44:28 +0000
committerDenis Ovsienko <denis@ovsienko.info>2023-03-12 16:44:28 +0000
commit989e1947f418e501bcea4d2cee1a986b455fe173 (patch)
treed83b9ea1cfc7c0376da304682e15cba5c368e8aa
parent023844895059279ad51b0b24cc1de5c121d1833e (diff)
downloadlibpcap-989e1947f418e501bcea4d2cee1a986b455fe173.tar.gz
Clean up DECnet address handling.
In gen_scode() make any id invalid DECnet address. In gen_ncode() make {N} invalid DECnet address. In __pcap_atodn() replace sscanf() with an FSM to parse the entire input string and to require a valid nominal DECnet address syntax. Remove __pcap_nametodnaddr(), which worked on Ultrix only. Add various comments to explain the context better. In pcap-filter(3PCAP) clarify the nominal DECnet address syntax and remove mentions of the host name translation. Before: filtertest: decnet name support not included, 'abc' cannot be translated 1 -- no error 100.2000 -- no error 1.2.3 -- no error 1.2.3.4 -- no error After: filtertest: invalid DECnet address 'abc' filtertest: invalid DECnet address '1' filtertest: invalid DECnet address '100.2000' filtertest: invalid DECnet address '1.2.3' filtertest: invalid DECnet address '1.2.3.4'
-rw-r--r--CHANGES1
-rw-r--r--gencode.c45
-rw-r--r--nametoaddr.c109
-rw-r--r--nametoaddr.h1
-rw-r--r--pcap-filter.manmisc.in11
5 files changed, 111 insertions, 56 deletions
diff --git a/CHANGES b/CHANGES
index 6d3c3899..1ba056a4 100644
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,7 @@ DayOfTheWeek, Month DD, YYYY / The Tcpdump Group
Use C99 fixed-width integer types, rather than self-defined
fixed-width integer types, in rpcap code.
Remove an always-false pointer test from snf_read().
+ Clean up DECnet address handling.
Link-layer types:
Add LINKTYPE_ETW/DLT_ETW.
Add LINKTYPE_NETANALYZER_NG/DLT_NETANALYZER_NG (pull request
diff --git a/gencode.c b/gencode.c
index 07c2a9d2..7b818ec4 100644
--- a/gencode.c
+++ b/gencode.c
@@ -6775,21 +6775,12 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q)
bpf_error(cstate, "only ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel supports link-level host name");
} else if (proto == Q_DECNET) {
- unsigned short dn_addr;
-
- if (!__pcap_nametodnaddr(name, &dn_addr)) {
-#ifdef DECNETLIB
- bpf_error(cstate, "unknown decnet host name '%s'\n", name);
-#else
- bpf_error(cstate, "decnet name support not included, '%s' cannot be translated\n",
- name);
-#endif
- }
/*
- * I don't think DECNET hosts can be multihomed, so
- * there is no need to build up a list of addresses
+ * A long time ago on Ultrix libpcap supported
+ * translation of DECnet host names into DECnet
+ * addresses, but this feature is history now.
*/
- return (gen_host(cstate, dn_addr, 0, proto, dir, q.addr));
+ bpf_error(cstate, "invalid DECnet address '%s'", name);
} else {
#ifdef INET6
memset(&mask128, 0xff, sizeof(mask128));
@@ -7060,13 +7051,35 @@ gen_ncode(compiler_state_t *cstate, const char *s, bpf_u_int32 v, struct qual q)
proto = q.proto;
dir = q.dir;
- if (s == NULL)
+ if (s == NULL) {
+ /*
+ * v contains a 32-bit unsigned parsed from a string of the
+ * form {N}, which could be decimal, hexadecimal or octal.
+ * Although it would be possible to use the value as a raw
+ * 16-bit DECnet address when the value fits into 16 bits, this
+ * would be a questionable feature: DECnet address wire
+ * encoding is little-endian, so this would not work as
+ * intuitively as the same works for [big-endian] IPv4
+ * addresses (0x01020304 means 1.2.3.4).
+ */
+ if (proto == Q_DECNET)
+ bpf_error(cstate, "invalid DECnet address '%u'", v);
vlen = 32;
- else if (q.proto == Q_DECNET) {
+ } else if (proto == Q_DECNET) {
+ /*
+ * s points to a string of the form {N}.{N}, {N}.{N}.{N} or
+ * {N}.{N}.{N}.{N}, of which only the first potentially stands
+ * for a valid DECnet address.
+ */
vlen = __pcap_atodn(s, &v);
if (vlen == 0)
- bpf_error(cstate, "malformed decnet address '%s'", s);
+ bpf_error(cstate, "invalid DECnet address '%s'", s);
} else {
+ /*
+ * s points to a string of the form {N}.{N}, {N}.{N}.{N} or
+ * {N}.{N}.{N}.{N}, all of which potentially stand for a valid
+ * IPv4 address.
+ */
vlen = __pcap_atoin(s, &v);
if (vlen < 0)
bpf_error(cstate, "invalid IPv4 address '%s'", s);
diff --git a/nametoaddr.c b/nametoaddr.c
index 7a04a61d..a746cb6d 100644
--- a/nametoaddr.c
+++ b/nametoaddr.c
@@ -26,11 +26,6 @@
#include <config.h>
#endif
-#ifdef DECNETLIB
-#include <sys/types.h>
-#include <netdnet/dnetdb.h>
-#endif
-
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
@@ -685,6 +680,13 @@ __pcap_atoin(const char *s, bpf_u_int32 *addr)
/* NOTREACHED */
}
+/*
+ * If 's' is not a string that is a well-formed DECnet address (aa.nnnn),
+ * return zero. Otherwise parse the address into the low 16 bits of 'addr'
+ * and return a non-zero. The binary DECnet address consists of a 6-bit area
+ * number and a 10-bit node number; neither area 0 nor node 0 are valid for
+ * normal addressing purposes, but either can appear on the wire.
+ */
int
__pcap_atodn(const char *s, bpf_u_int32 *addr)
{
@@ -692,14 +694,76 @@ __pcap_atodn(const char *s, bpf_u_int32 *addr)
#define AREAMASK 0176000
#define NODEMASK 01777
- u_int node, area;
-
- if (sscanf(s, "%d.%d", &area, &node) != 2)
- return(0);
+ /* Initialize to squelch a compiler warning only. */
+ u_int node = 0, area = 0;
+ /*
+ * +--+ +--+
+ * | | | |
+ * v | v |
+ * --> START --> AREA --> DOT --> NODE -->
+ * | | | |
+ * | v v |
+ * +--------> INVALID <------+
+ */
+ enum {
+ START,
+ AREA,
+ DOT,
+ NODE,
+ INVALID
+ } fsm_state = START;
- *addr = (area << AREASHIFT) & AREAMASK;
- *addr |= (node & NODEMASK);
+ while (*s) {
+ switch (fsm_state) {
+ case START:
+ if (PCAP_ISDIGIT(*s)) {
+ area = *s - '0';
+ fsm_state = AREA;
+ break;
+ }
+ fsm_state = INVALID;
+ break;
+ case AREA:
+ if (*s == '.') {
+ fsm_state = DOT;
+ break;
+ }
+ if (PCAP_ISDIGIT(*s)) {
+ area = area * 10 + *s - '0';
+ if (area <= AREAMASK >> AREASHIFT)
+ break;
+ }
+ fsm_state = INVALID;
+ break;
+ case DOT:
+ if (PCAP_ISDIGIT(*s)) {
+ node = *s - '0';
+ fsm_state = NODE;
+ break;
+ }
+ fsm_state = INVALID;
+ break;
+ case NODE:
+ if (PCAP_ISDIGIT(*s)) {
+ node = node * 10 + *s - '0';
+ if (node <= NODEMASK)
+ break;
+ }
+ fsm_state = INVALID;
+ break;
+ case INVALID:
+ return 0;
+ } /* switch */
+ s++;
+ } /* while */
+ /*
+ * This condition is false if the string comes from the lexer, but
+ * let's not depend on that.
+ */
+ if (fsm_state != NODE)
+ return 0;
+ *addr = area << AREASHIFT | node;
return(32);
}
@@ -800,26 +864,3 @@ pcap_ether_hostton(const char *name)
return (ap);
}
#endif
-
-/*
- * XXX - not guaranteed to be thread-safe!
- */
-int
-#ifdef DECNETLIB
-__pcap_nametodnaddr(const char *name, u_short *res)
-{
- struct nodeent *getnodebyname();
- struct nodeent *nep;
-
- nep = getnodebyname(name);
- if (nep == ((struct nodeent *)0))
- return(0);
-
- memcpy((char *)res, (char *)nep->n_addr, sizeof(unsigned short));
- return(1);
-#else
-__pcap_nametodnaddr(const char *name _U_, u_short *res _U_)
-{
- return(0);
-#endif
-}
diff --git a/nametoaddr.h b/nametoaddr.h
index fd6b7e10..8cf718ac 100644
--- a/nametoaddr.h
+++ b/nametoaddr.h
@@ -41,7 +41,6 @@ extern "C" {
*/
int __pcap_atodn(const char *, bpf_u_int32 *);
int __pcap_atoin(const char *, bpf_u_int32 *);
-int __pcap_nametodnaddr(const char *, u_short *);
#ifdef __cplusplus
}
diff --git a/pcap-filter.manmisc.in b/pcap-filter.manmisc.in
index 75512cd3..c477251f 100644
--- a/pcap-filter.manmisc.in
+++ b/pcap-filter.manmisc.in
@@ -18,7 +18,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP-FILTER @MAN_MISC_INFO@ "20 February 2023"
+.TH PCAP-FILTER @MAN_MISC_INFO@ "12 March 2023"
.SH NAME
pcap-filter \- packet filter syntax
.br
@@ -476,10 +476,11 @@ currently know how to parse these protocols.
.IP "\fBdecnet src \fIdecnetaddr\fR"
True if the DECnet source address is
.IR decnetaddr ,
-which may be an address of the form ``10.123'', or a DECnet host
-name.
-[DECnet host name support is only available on ULTRIX systems
-that are configured to run DECnet.]
+which is an address of the form
+.B AREANUMBER.NODENUMBER
+(for example, "10.123"), where the area number can be between 0 and 63
+and the node number can be between 0 and 1023 and both numbers always use
+decimal base.
.IP "\fBdecnet dst \fIdecnetaddr\fR"
True if the DECnet destination address is
.IR decnetaddr .