summaryrefslogtreecommitdiff
path: root/print-wb.c
diff options
context:
space:
mode:
authorDenis Ovsienko <denis@ovsienko.info>2020-10-11 11:57:32 +0100
committerDenis Ovsienko <denis@ovsienko.info>2020-10-11 12:27:20 +0100
commitd32231a35b587b74d599b7ba428705db3514e95e (patch)
tree0d2613f8072e0c214efb88dfc01a3906a792ba4d /print-wb.c
parent1f336f66e19d1e207d43e9d5625329d628c495b3 (diff)
downloadtcpdump-d32231a35b587b74d599b7ba428705db3514e95e.tar.gz
WB: Modernize packet parsing style.
Enable ND_LONGJMP_FROM_TCHECK. Remove ND_TTEST*() instances that were excess and convert the rest to ND_TCHECK*() with comments. Do not guard ndo_snapend directly. Make sure that functions specific to message types do not return on truncated data and return -1 when they have looked deep enough to tell an invalid packet. In wb_print() deduplicate some code and report invalid packets as invalid instead of truncated, also consider an unknown packet type invalid. Update a test.
Diffstat (limited to 'print-wb.c')
-rw-r--r--print-wb.c83
1 files changed, 38 insertions, 45 deletions
diff --git a/print-wb.c b/print-wb.c
index 3e562af4..184809cb 100644
--- a/print-wb.c
+++ b/print-wb.c
@@ -27,6 +27,7 @@
#include "netdissect-stdinc.h"
+#define ND_LONGJMP_FROM_TCHECK
#include "netdissect.h"
#include "addrtoname.h"
#include "extract.h"
@@ -203,7 +204,7 @@ wb_id(netdissect_options *ndo,
u_int nid;
ND_PRINT(" wb-id:");
- if (len < sizeof(*id) || !ND_TTEST_SIZE(id))
+ if (len < sizeof(*id))
return (-1);
len -= sizeof(*id);
@@ -214,6 +215,8 @@ wb_id(netdissect_options *ndo,
GET_BE_U_4(id->pi_mslot),
GET_IPADDR_STRING(id->pi_mpage.p_sid),
GET_BE_U_4(id->pi_mpage.p_uid));
+ /* now the rest of the fixed-size part of struct pkt_id */
+ ND_TCHECK_SIZE(id);
nid = GET_BE_U_2(id->pi_ps.nid);
if (len < sizeof(*io) * nid)
@@ -223,18 +226,15 @@ wb_id(netdissect_options *ndo,
sitename = (const u_char *)(io + nid);
c = '<';
- for (i = 0; i < nid && ND_TTEST_SIZE(io); ++io, ++i) {
+ for (i = 0; i < nid; ++io, ++i) {
ND_PRINT("%c%s:%u",
c, GET_IPADDR_STRING(io->id), GET_BE_U_4(io->off));
c = ',';
}
- if (i >= nid) {
- ND_PRINT("> \"");
- (void)nd_print(ndo, sitename, sitename + len);
- ND_PRINT("\"");
- return (0);
- }
- return (-1);
+ ND_PRINT("> \"");
+ (void)nd_print(ndo, sitename, sitename + len);
+ ND_PRINT("\"");
+ return (0);
}
static int
@@ -242,7 +242,7 @@ wb_rreq(netdissect_options *ndo,
const struct pkt_rreq *rreq, u_int len)
{
ND_PRINT(" wb-rreq:");
- if (len < sizeof(*rreq) || !ND_TTEST_SIZE(rreq))
+ if (len < sizeof(*rreq))
return (-1);
ND_PRINT(" please repair %s %s:%u<%u:%u>",
@@ -259,13 +259,15 @@ wb_preq(netdissect_options *ndo,
const struct pkt_preq *preq, u_int len)
{
ND_PRINT(" wb-preq:");
- if (len < sizeof(*preq) || !ND_TTEST_SIZE(preq))
+ if (len < sizeof(*preq))
return (-1);
ND_PRINT(" need %u/%s:%u",
GET_BE_U_4(preq->pp_low),
GET_IPADDR_STRING(preq->pp_page.p_sid),
GET_BE_U_4(preq->pp_page.p_uid));
+ /* now the rest of the fixed-size part of struct pkt_req */
+ ND_TCHECK_SIZE(preq);
return (0);
}
@@ -275,14 +277,13 @@ wb_prep(netdissect_options *ndo,
{
u_int n;
const struct pgstate *ps;
- const u_char *ep = ndo->ndo_snapend;
ND_PRINT(" wb-prep:");
- if (len < sizeof(*prep) || !ND_TTEST_SIZE(prep))
+ if (len < sizeof(*prep))
return (-1);
n = GET_BE_U_4(prep->pp_n);
ps = (const struct pgstate *)(prep + 1);
- while (n != 0 && ND_TTEST_SIZE(ps)) {
+ while (n != 0) {
const struct id_off *io, *ie;
char c = '<';
@@ -290,8 +291,10 @@ wb_prep(netdissect_options *ndo,
GET_BE_U_4(ps->slot),
GET_IPADDR_STRING(ps->page.p_sid),
GET_BE_U_4(ps->page.p_uid));
+ /* now the rest of the fixed-size part of struct pgstate */
+ ND_TCHECK_SIZE(ps);
io = (const struct id_off *)(ps + 1);
- for (ie = io + GET_U_1(ps->nid); io < ie && ND_TTEST_SIZE(io); ++io) {
+ for (ie = io + GET_U_1(ps->nid); io < ie; ++io) {
ND_PRINT("%c%s:%u", c, GET_IPADDR_STRING(io->id),
GET_BE_U_4(io->off));
c = ',';
@@ -300,7 +303,7 @@ wb_prep(netdissect_options *ndo,
ps = (const struct pgstate *)io;
n--;
}
- return ((const u_char *)ps <= ep? 0 : -1);
+ return 0;
}
static void
@@ -313,10 +316,6 @@ wb_dops(netdissect_options *ndo, const struct pkt_dop *dop,
for ( ; ss <= es; ++ss) {
u_int t;
- if (!ND_TTEST_SIZE(dh)) {
- nd_print_trunc(ndo);
- break;
- }
t = GET_U_1(dh->dh_type);
ND_PRINT(" %s", tok2str(dop_str, "dop-%u!", t));
@@ -342,7 +341,7 @@ wb_rrep(netdissect_options *ndo,
const struct pkt_dop *dop = &rrep->pr_dop;
ND_PRINT(" wb-rrep:");
- if (len < sizeof(*rrep) || !ND_TTEST_SIZE(rrep))
+ if (len < sizeof(*rrep))
return (-1);
len -= sizeof(*rrep);
@@ -365,7 +364,7 @@ wb_drawop(netdissect_options *ndo,
const struct pkt_dop *dop, u_int len)
{
ND_PRINT(" wb-dop:");
- if (len < sizeof(*dop) || !ND_TTEST_SIZE(dop))
+ if (len < sizeof(*dop))
return (-1);
len -= sizeof(*dop);
@@ -391,13 +390,13 @@ wb_print(netdissect_options *ndo,
{
const struct pkt_hdr *ph;
uint8_t type;
+ int print_result;
ndo->ndo_protocol = "wb";
ph = (const struct pkt_hdr *)hdr;
- if (len < sizeof(*ph) || !ND_TTEST_SIZE(ph)) {
- nd_print_trunc(ndo);
- return;
- }
+ if (len < sizeof(*ph))
+ goto invalid;
+ ND_TCHECK_SIZE(ph);
len -= sizeof(*ph);
if (GET_U_1(ph->ph_flags))
@@ -410,43 +409,37 @@ wb_print(netdissect_options *ndo,
return;
case PT_ID:
- if (wb_id(ndo, (const struct pkt_id *)(ph + 1), len) >= 0)
- return;
- nd_print_trunc(ndo);
+ print_result = wb_id(ndo, (const struct pkt_id *)(ph + 1), len);
break;
case PT_RREQ:
- if (wb_rreq(ndo, (const struct pkt_rreq *)(ph + 1), len) >= 0)
- return;
- nd_print_trunc(ndo);
+ print_result = wb_rreq(ndo, (const struct pkt_rreq *)(ph + 1), len);
break;
case PT_RREP:
- if (wb_rrep(ndo, (const struct pkt_rrep *)(ph + 1), len) >= 0)
- return;
- nd_print_trunc(ndo);
+ print_result = wb_rrep(ndo, (const struct pkt_rrep *)(ph + 1), len);
break;
case PT_DRAWOP:
- if (wb_drawop(ndo, (const struct pkt_dop *)(ph + 1), len) >= 0)
- return;
- nd_print_trunc(ndo);
+ print_result = wb_drawop(ndo, (const struct pkt_dop *)(ph + 1), len);
break;
case PT_PREQ:
- if (wb_preq(ndo, (const struct pkt_preq *)(ph + 1), len) >= 0)
- return;
- nd_print_trunc(ndo);
+ print_result = wb_preq(ndo, (const struct pkt_preq *)(ph + 1), len);
break;
case PT_PREP:
- if (wb_prep(ndo, (const struct pkt_prep *)(ph + 1), len) >= 0)
- return;
- nd_print_trunc(ndo);
+ print_result = wb_prep(ndo, (const struct pkt_prep *)(ph + 1), len);
break;
default:
ND_PRINT(" wb-%u!", type);
- return;
+ print_result = -1;
}
+ if (print_result < 0)
+ goto invalid;
+ return;
+
+invalid:
+ nd_print_invalid(ndo);
}