1*b636d99dSDavid van Moolenbroek /*
2*b636d99dSDavid van Moolenbroek * Copyright (c) 1993, 1994, 1995, 1996
3*b636d99dSDavid van Moolenbroek * The Regents of the University of California. All rights reserved.
4*b636d99dSDavid van Moolenbroek *
5*b636d99dSDavid van Moolenbroek * Redistribution and use in source and binary forms, with or without
6*b636d99dSDavid van Moolenbroek * modification, are permitted provided that: (1) source code distributions
7*b636d99dSDavid van Moolenbroek * retain the above copyright notice and this paragraph in its entirety, (2)
8*b636d99dSDavid van Moolenbroek * distributions including binary code include the above copyright notice and
9*b636d99dSDavid van Moolenbroek * this paragraph in its entirety in the documentation or other materials
10*b636d99dSDavid van Moolenbroek * provided with the distribution, and (3) all advertising materials mentioning
11*b636d99dSDavid van Moolenbroek * features or use of this software display the following acknowledgement:
12*b636d99dSDavid van Moolenbroek * ``This product includes software developed by the University of California,
13*b636d99dSDavid van Moolenbroek * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14*b636d99dSDavid van Moolenbroek * the University nor the names of its contributors may be used to endorse
15*b636d99dSDavid van Moolenbroek * or promote products derived from this software without specific prior
16*b636d99dSDavid van Moolenbroek * written permission.
17*b636d99dSDavid van Moolenbroek * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18*b636d99dSDavid van Moolenbroek * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19*b636d99dSDavid van Moolenbroek * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20*b636d99dSDavid van Moolenbroek */
21*b636d99dSDavid van Moolenbroek
22*b636d99dSDavid van Moolenbroek #include <sys/cdefs.h>
23*b636d99dSDavid van Moolenbroek #ifndef lint
24*b636d99dSDavid van Moolenbroek __RCSID("$NetBSD: print-wb.c,v 1.5 2015/03/31 21:59:35 christos Exp $");
25*b636d99dSDavid van Moolenbroek #endif
26*b636d99dSDavid van Moolenbroek
27*b636d99dSDavid van Moolenbroek #define NETDISSECT_REWORKED
28*b636d99dSDavid van Moolenbroek #ifdef HAVE_CONFIG_H
29*b636d99dSDavid van Moolenbroek #include "config.h"
30*b636d99dSDavid van Moolenbroek #endif
31*b636d99dSDavid van Moolenbroek
32*b636d99dSDavid van Moolenbroek #include <tcpdump-stdinc.h>
33*b636d99dSDavid van Moolenbroek
34*b636d99dSDavid van Moolenbroek #include "interface.h"
35*b636d99dSDavid van Moolenbroek #include "addrtoname.h"
36*b636d99dSDavid van Moolenbroek #include "extract.h"
37*b636d99dSDavid van Moolenbroek
38*b636d99dSDavid van Moolenbroek static const char tstr[] = "[|wb]";
39*b636d99dSDavid van Moolenbroek
40*b636d99dSDavid van Moolenbroek /* XXX need to add byte-swapping macros! */
41*b636d99dSDavid van Moolenbroek /* XXX - you mean like the ones in "extract.h"? */
42*b636d99dSDavid van Moolenbroek
43*b636d99dSDavid van Moolenbroek /*
44*b636d99dSDavid van Moolenbroek * Largest packet size. Everything should fit within this space.
45*b636d99dSDavid van Moolenbroek * For instance, multiline objects are sent piecewise.
46*b636d99dSDavid van Moolenbroek */
47*b636d99dSDavid van Moolenbroek #define MAXFRAMESIZE 1024
48*b636d99dSDavid van Moolenbroek
49*b636d99dSDavid van Moolenbroek /*
50*b636d99dSDavid van Moolenbroek * Multiple drawing ops can be sent in one packet. Each one starts on a
51*b636d99dSDavid van Moolenbroek * an even multiple of DOP_ALIGN bytes, which must be a power of two.
52*b636d99dSDavid van Moolenbroek */
53*b636d99dSDavid van Moolenbroek #define DOP_ALIGN 4
54*b636d99dSDavid van Moolenbroek #define DOP_ROUNDUP(x) ((((int)(x)) + (DOP_ALIGN - 1)) & ~(DOP_ALIGN - 1))
55*b636d99dSDavid van Moolenbroek #define DOP_NEXT(d)\
56*b636d99dSDavid van Moolenbroek ((struct dophdr *)((u_char *)(d) + \
57*b636d99dSDavid van Moolenbroek DOP_ROUNDUP(EXTRACT_16BITS(&(d)->dh_len) + sizeof(*(d)))))
58*b636d99dSDavid van Moolenbroek
59*b636d99dSDavid van Moolenbroek /*
60*b636d99dSDavid van Moolenbroek * Format of the whiteboard packet header.
61*b636d99dSDavid van Moolenbroek * The transport level header.
62*b636d99dSDavid van Moolenbroek */
63*b636d99dSDavid van Moolenbroek struct pkt_hdr {
64*b636d99dSDavid van Moolenbroek uint32_t ph_src; /* site id of source */
65*b636d99dSDavid van Moolenbroek uint32_t ph_ts; /* time stamp (for skew computation) */
66*b636d99dSDavid van Moolenbroek uint16_t ph_version; /* version number */
67*b636d99dSDavid van Moolenbroek u_char ph_type; /* message type */
68*b636d99dSDavid van Moolenbroek u_char ph_flags; /* message flags */
69*b636d99dSDavid van Moolenbroek };
70*b636d99dSDavid van Moolenbroek
71*b636d99dSDavid van Moolenbroek /* Packet types */
72*b636d99dSDavid van Moolenbroek #define PT_DRAWOP 0 /* drawing operation */
73*b636d99dSDavid van Moolenbroek #define PT_ID 1 /* announcement packet */
74*b636d99dSDavid van Moolenbroek #define PT_RREQ 2 /* repair request */
75*b636d99dSDavid van Moolenbroek #define PT_RREP 3 /* repair reply */
76*b636d99dSDavid van Moolenbroek #define PT_KILL 4 /* terminate participation */
77*b636d99dSDavid van Moolenbroek #define PT_PREQ 5 /* page vector request */
78*b636d99dSDavid van Moolenbroek #define PT_PREP 7 /* page vector reply */
79*b636d99dSDavid van Moolenbroek
80*b636d99dSDavid van Moolenbroek #ifdef PF_USER
81*b636d99dSDavid van Moolenbroek #undef PF_USER /* {Digital,Tru64} UNIX define this, alas */
82*b636d99dSDavid van Moolenbroek #endif
83*b636d99dSDavid van Moolenbroek
84*b636d99dSDavid van Moolenbroek /* flags */
85*b636d99dSDavid van Moolenbroek #define PF_USER 0x01 /* hint that packet has interactive data */
86*b636d99dSDavid van Moolenbroek #define PF_VIS 0x02 /* only visible ops wanted */
87*b636d99dSDavid van Moolenbroek
88*b636d99dSDavid van Moolenbroek struct PageID {
89*b636d99dSDavid van Moolenbroek uint32_t p_sid; /* session id of initiator */
90*b636d99dSDavid van Moolenbroek uint32_t p_uid; /* page number */
91*b636d99dSDavid van Moolenbroek };
92*b636d99dSDavid van Moolenbroek
93*b636d99dSDavid van Moolenbroek struct dophdr {
94*b636d99dSDavid van Moolenbroek uint32_t dh_ts; /* sender's timestamp */
95*b636d99dSDavid van Moolenbroek uint16_t dh_len; /* body length */
96*b636d99dSDavid van Moolenbroek u_char dh_flags;
97*b636d99dSDavid van Moolenbroek u_char dh_type; /* body type */
98*b636d99dSDavid van Moolenbroek /* body follows */
99*b636d99dSDavid van Moolenbroek };
100*b636d99dSDavid van Moolenbroek /*
101*b636d99dSDavid van Moolenbroek * Drawing op sub-types.
102*b636d99dSDavid van Moolenbroek */
103*b636d99dSDavid van Moolenbroek #define DT_RECT 2
104*b636d99dSDavid van Moolenbroek #define DT_LINE 3
105*b636d99dSDavid van Moolenbroek #define DT_ML 4
106*b636d99dSDavid van Moolenbroek #define DT_DEL 5
107*b636d99dSDavid van Moolenbroek #define DT_XFORM 6
108*b636d99dSDavid van Moolenbroek #define DT_ELL 7
109*b636d99dSDavid van Moolenbroek #define DT_CHAR 8
110*b636d99dSDavid van Moolenbroek #define DT_STR 9
111*b636d99dSDavid van Moolenbroek #define DT_NOP 10
112*b636d99dSDavid van Moolenbroek #define DT_PSCODE 11
113*b636d99dSDavid van Moolenbroek #define DT_PSCOMP 12
114*b636d99dSDavid van Moolenbroek #define DT_REF 13
115*b636d99dSDavid van Moolenbroek #define DT_SKIP 14
116*b636d99dSDavid van Moolenbroek #define DT_HOLE 15
117*b636d99dSDavid van Moolenbroek #define DT_MAXTYPE 15
118*b636d99dSDavid van Moolenbroek
119*b636d99dSDavid van Moolenbroek /*
120*b636d99dSDavid van Moolenbroek * A drawing operation.
121*b636d99dSDavid van Moolenbroek */
122*b636d99dSDavid van Moolenbroek struct pkt_dop {
123*b636d99dSDavid van Moolenbroek struct PageID pd_page; /* page that operations apply to */
124*b636d99dSDavid van Moolenbroek uint32_t pd_sseq; /* start sequence number */
125*b636d99dSDavid van Moolenbroek uint32_t pd_eseq; /* end sequence number */
126*b636d99dSDavid van Moolenbroek /* drawing ops follow */
127*b636d99dSDavid van Moolenbroek };
128*b636d99dSDavid van Moolenbroek
129*b636d99dSDavid van Moolenbroek /*
130*b636d99dSDavid van Moolenbroek * A repair request.
131*b636d99dSDavid van Moolenbroek */
132*b636d99dSDavid van Moolenbroek struct pkt_rreq {
133*b636d99dSDavid van Moolenbroek uint32_t pr_id; /* source id of drawops to be repaired */
134*b636d99dSDavid van Moolenbroek struct PageID pr_page; /* page of drawops */
135*b636d99dSDavid van Moolenbroek uint32_t pr_sseq; /* start seqno */
136*b636d99dSDavid van Moolenbroek uint32_t pr_eseq; /* end seqno */
137*b636d99dSDavid van Moolenbroek };
138*b636d99dSDavid van Moolenbroek
139*b636d99dSDavid van Moolenbroek /*
140*b636d99dSDavid van Moolenbroek * A repair reply.
141*b636d99dSDavid van Moolenbroek */
142*b636d99dSDavid van Moolenbroek struct pkt_rrep {
143*b636d99dSDavid van Moolenbroek uint32_t pr_id; /* original site id of ops */
144*b636d99dSDavid van Moolenbroek struct pkt_dop pr_dop;
145*b636d99dSDavid van Moolenbroek /* drawing ops follow */
146*b636d99dSDavid van Moolenbroek };
147*b636d99dSDavid van Moolenbroek
148*b636d99dSDavid van Moolenbroek struct id_off {
149*b636d99dSDavid van Moolenbroek uint32_t id;
150*b636d99dSDavid van Moolenbroek uint32_t off;
151*b636d99dSDavid van Moolenbroek };
152*b636d99dSDavid van Moolenbroek
153*b636d99dSDavid van Moolenbroek struct pgstate {
154*b636d99dSDavid van Moolenbroek uint32_t slot;
155*b636d99dSDavid van Moolenbroek struct PageID page;
156*b636d99dSDavid van Moolenbroek uint16_t nid;
157*b636d99dSDavid van Moolenbroek uint16_t rsvd;
158*b636d99dSDavid van Moolenbroek /* seqptr's */
159*b636d99dSDavid van Moolenbroek };
160*b636d99dSDavid van Moolenbroek
161*b636d99dSDavid van Moolenbroek /*
162*b636d99dSDavid van Moolenbroek * An announcement packet.
163*b636d99dSDavid van Moolenbroek */
164*b636d99dSDavid van Moolenbroek struct pkt_id {
165*b636d99dSDavid van Moolenbroek uint32_t pi_mslot;
166*b636d99dSDavid van Moolenbroek struct PageID pi_mpage; /* current page */
167*b636d99dSDavid van Moolenbroek struct pgstate pi_ps;
168*b636d99dSDavid van Moolenbroek /* seqptr's */
169*b636d99dSDavid van Moolenbroek /* null-terminated site name */
170*b636d99dSDavid van Moolenbroek };
171*b636d99dSDavid van Moolenbroek
172*b636d99dSDavid van Moolenbroek struct pkt_preq {
173*b636d99dSDavid van Moolenbroek struct PageID pp_page;
174*b636d99dSDavid van Moolenbroek uint32_t pp_low;
175*b636d99dSDavid van Moolenbroek uint32_t pp_high;
176*b636d99dSDavid van Moolenbroek };
177*b636d99dSDavid van Moolenbroek
178*b636d99dSDavid van Moolenbroek struct pkt_prep {
179*b636d99dSDavid van Moolenbroek uint32_t pp_n; /* size of pageid array */
180*b636d99dSDavid van Moolenbroek /* pgstate's follow */
181*b636d99dSDavid van Moolenbroek };
182*b636d99dSDavid van Moolenbroek
183*b636d99dSDavid van Moolenbroek static int
wb_id(netdissect_options * ndo,const struct pkt_id * id,u_int len)184*b636d99dSDavid van Moolenbroek wb_id(netdissect_options *ndo,
185*b636d99dSDavid van Moolenbroek const struct pkt_id *id, u_int len)
186*b636d99dSDavid van Moolenbroek {
187*b636d99dSDavid van Moolenbroek int i;
188*b636d99dSDavid van Moolenbroek const char *cp;
189*b636d99dSDavid van Moolenbroek const struct id_off *io;
190*b636d99dSDavid van Moolenbroek char c;
191*b636d99dSDavid van Moolenbroek int nid;
192*b636d99dSDavid van Moolenbroek
193*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " wb-id:"));
194*b636d99dSDavid van Moolenbroek if (len < sizeof(*id) || !ND_TTEST(*id))
195*b636d99dSDavid van Moolenbroek return (-1);
196*b636d99dSDavid van Moolenbroek len -= sizeof(*id);
197*b636d99dSDavid van Moolenbroek
198*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " %u/%s:%u (max %u/%s:%u) ",
199*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&id->pi_ps.slot),
200*b636d99dSDavid van Moolenbroek ipaddr_string(ndo, &id->pi_ps.page.p_sid),
201*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&id->pi_ps.page.p_uid),
202*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&id->pi_mslot),
203*b636d99dSDavid van Moolenbroek ipaddr_string(ndo, &id->pi_mpage.p_sid),
204*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&id->pi_mpage.p_uid)));
205*b636d99dSDavid van Moolenbroek
206*b636d99dSDavid van Moolenbroek nid = EXTRACT_16BITS(&id->pi_ps.nid);
207*b636d99dSDavid van Moolenbroek len -= sizeof(*io) * nid;
208*b636d99dSDavid van Moolenbroek io = (struct id_off *)(id + 1);
209*b636d99dSDavid van Moolenbroek cp = (char *)(io + nid);
210*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(cp, len)) {
211*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\""));
212*b636d99dSDavid van Moolenbroek fn_print(ndo, (u_char *)cp, (u_char *)cp + len);
213*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\""));
214*b636d99dSDavid van Moolenbroek }
215*b636d99dSDavid van Moolenbroek
216*b636d99dSDavid van Moolenbroek c = '<';
217*b636d99dSDavid van Moolenbroek for (i = 0; i < nid && ND_TTEST(*io); ++io, ++i) {
218*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%c%s:%u",
219*b636d99dSDavid van Moolenbroek c, ipaddr_string(ndo, &io->id), EXTRACT_32BITS(&io->off)));
220*b636d99dSDavid van Moolenbroek c = ',';
221*b636d99dSDavid van Moolenbroek }
222*b636d99dSDavid van Moolenbroek if (i >= nid) {
223*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ">"));
224*b636d99dSDavid van Moolenbroek return (0);
225*b636d99dSDavid van Moolenbroek }
226*b636d99dSDavid van Moolenbroek return (-1);
227*b636d99dSDavid van Moolenbroek }
228*b636d99dSDavid van Moolenbroek
229*b636d99dSDavid van Moolenbroek static int
wb_rreq(netdissect_options * ndo,const struct pkt_rreq * rreq,u_int len)230*b636d99dSDavid van Moolenbroek wb_rreq(netdissect_options *ndo,
231*b636d99dSDavid van Moolenbroek const struct pkt_rreq *rreq, u_int len)
232*b636d99dSDavid van Moolenbroek {
233*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " wb-rreq:"));
234*b636d99dSDavid van Moolenbroek if (len < sizeof(*rreq) || !ND_TTEST(*rreq))
235*b636d99dSDavid van Moolenbroek return (-1);
236*b636d99dSDavid van Moolenbroek
237*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " please repair %s %s:%u<%u:%u>",
238*b636d99dSDavid van Moolenbroek ipaddr_string(ndo, &rreq->pr_id),
239*b636d99dSDavid van Moolenbroek ipaddr_string(ndo, &rreq->pr_page.p_sid),
240*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&rreq->pr_page.p_uid),
241*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&rreq->pr_sseq),
242*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&rreq->pr_eseq)));
243*b636d99dSDavid van Moolenbroek return (0);
244*b636d99dSDavid van Moolenbroek }
245*b636d99dSDavid van Moolenbroek
246*b636d99dSDavid van Moolenbroek static int
wb_preq(netdissect_options * ndo,const struct pkt_preq * preq,u_int len)247*b636d99dSDavid van Moolenbroek wb_preq(netdissect_options *ndo,
248*b636d99dSDavid van Moolenbroek const struct pkt_preq *preq, u_int len)
249*b636d99dSDavid van Moolenbroek {
250*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " wb-preq:"));
251*b636d99dSDavid van Moolenbroek if (len < sizeof(*preq) || !ND_TTEST(*preq))
252*b636d99dSDavid van Moolenbroek return (-1);
253*b636d99dSDavid van Moolenbroek
254*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " need %u/%s:%u",
255*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&preq->pp_low),
256*b636d99dSDavid van Moolenbroek ipaddr_string(ndo, &preq->pp_page.p_sid),
257*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&preq->pp_page.p_uid)));
258*b636d99dSDavid van Moolenbroek return (0);
259*b636d99dSDavid van Moolenbroek }
260*b636d99dSDavid van Moolenbroek
261*b636d99dSDavid van Moolenbroek static int
wb_prep(netdissect_options * ndo,const struct pkt_prep * prep,u_int len)262*b636d99dSDavid van Moolenbroek wb_prep(netdissect_options *ndo,
263*b636d99dSDavid van Moolenbroek const struct pkt_prep *prep, u_int len)
264*b636d99dSDavid van Moolenbroek {
265*b636d99dSDavid van Moolenbroek int n;
266*b636d99dSDavid van Moolenbroek const struct pgstate *ps;
267*b636d99dSDavid van Moolenbroek const u_char *ep = ndo->ndo_snapend;
268*b636d99dSDavid van Moolenbroek
269*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " wb-prep:"));
270*b636d99dSDavid van Moolenbroek if (len < sizeof(*prep)) {
271*b636d99dSDavid van Moolenbroek return (-1);
272*b636d99dSDavid van Moolenbroek }
273*b636d99dSDavid van Moolenbroek n = EXTRACT_32BITS(&prep->pp_n);
274*b636d99dSDavid van Moolenbroek ps = (const struct pgstate *)(prep + 1);
275*b636d99dSDavid van Moolenbroek while (--n >= 0 && !ND_TTEST(*ps)) {
276*b636d99dSDavid van Moolenbroek const struct id_off *io, *ie;
277*b636d99dSDavid van Moolenbroek char c = '<';
278*b636d99dSDavid van Moolenbroek
279*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " %u/%s:%u",
280*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&ps->slot),
281*b636d99dSDavid van Moolenbroek ipaddr_string(ndo, &ps->page.p_sid),
282*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&ps->page.p_uid)));
283*b636d99dSDavid van Moolenbroek io = (struct id_off *)(ps + 1);
284*b636d99dSDavid van Moolenbroek for (ie = io + ps->nid; io < ie && !ND_TTEST(*io); ++io) {
285*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%c%s:%u", c, ipaddr_string(ndo, &io->id),
286*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&io->off)));
287*b636d99dSDavid van Moolenbroek c = ',';
288*b636d99dSDavid van Moolenbroek }
289*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ">"));
290*b636d99dSDavid van Moolenbroek ps = (struct pgstate *)io;
291*b636d99dSDavid van Moolenbroek }
292*b636d99dSDavid van Moolenbroek return ((u_char *)ps <= ep? 0 : -1);
293*b636d99dSDavid van Moolenbroek }
294*b636d99dSDavid van Moolenbroek
295*b636d99dSDavid van Moolenbroek
296*b636d99dSDavid van Moolenbroek static const char *dopstr[] = {
297*b636d99dSDavid van Moolenbroek "dop-0!",
298*b636d99dSDavid van Moolenbroek "dop-1!",
299*b636d99dSDavid van Moolenbroek "RECT",
300*b636d99dSDavid van Moolenbroek "LINE",
301*b636d99dSDavid van Moolenbroek "ML",
302*b636d99dSDavid van Moolenbroek "DEL",
303*b636d99dSDavid van Moolenbroek "XFORM",
304*b636d99dSDavid van Moolenbroek "ELL",
305*b636d99dSDavid van Moolenbroek "CHAR",
306*b636d99dSDavid van Moolenbroek "STR",
307*b636d99dSDavid van Moolenbroek "NOP",
308*b636d99dSDavid van Moolenbroek "PSCODE",
309*b636d99dSDavid van Moolenbroek "PSCOMP",
310*b636d99dSDavid van Moolenbroek "REF",
311*b636d99dSDavid van Moolenbroek "SKIP",
312*b636d99dSDavid van Moolenbroek "HOLE",
313*b636d99dSDavid van Moolenbroek };
314*b636d99dSDavid van Moolenbroek
315*b636d99dSDavid van Moolenbroek static int
wb_dops(netdissect_options * ndo,const struct pkt_dop * dop,uint32_t ss,uint32_t es)316*b636d99dSDavid van Moolenbroek wb_dops(netdissect_options *ndo, const struct pkt_dop *dop,
317*b636d99dSDavid van Moolenbroek uint32_t ss, uint32_t es)
318*b636d99dSDavid van Moolenbroek {
319*b636d99dSDavid van Moolenbroek const struct dophdr *dh = (const struct dophdr *)((const u_char *)dop + sizeof(*dop));
320*b636d99dSDavid van Moolenbroek
321*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " <"));
322*b636d99dSDavid van Moolenbroek for ( ; ss <= es; ++ss) {
323*b636d99dSDavid van Moolenbroek int t;
324*b636d99dSDavid van Moolenbroek
325*b636d99dSDavid van Moolenbroek if (!ND_TTEST(*dh)) {
326*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s", tstr));
327*b636d99dSDavid van Moolenbroek break;
328*b636d99dSDavid van Moolenbroek }
329*b636d99dSDavid van Moolenbroek t = dh->dh_type;
330*b636d99dSDavid van Moolenbroek
331*b636d99dSDavid van Moolenbroek if (t > DT_MAXTYPE)
332*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " dop-%d!", t));
333*b636d99dSDavid van Moolenbroek else {
334*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " %s", dopstr[t]));
335*b636d99dSDavid van Moolenbroek if (t == DT_SKIP || t == DT_HOLE) {
336*b636d99dSDavid van Moolenbroek uint32_t ts = EXTRACT_32BITS(&dh->dh_ts);
337*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%d", ts - ss + 1));
338*b636d99dSDavid van Moolenbroek if (ss > ts || ts > es) {
339*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "[|]"));
340*b636d99dSDavid van Moolenbroek if (ts < ss)
341*b636d99dSDavid van Moolenbroek return (0);
342*b636d99dSDavid van Moolenbroek }
343*b636d99dSDavid van Moolenbroek ss = ts;
344*b636d99dSDavid van Moolenbroek }
345*b636d99dSDavid van Moolenbroek }
346*b636d99dSDavid van Moolenbroek dh = DOP_NEXT(dh);
347*b636d99dSDavid van Moolenbroek }
348*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " >"));
349*b636d99dSDavid van Moolenbroek return (0);
350*b636d99dSDavid van Moolenbroek }
351*b636d99dSDavid van Moolenbroek
352*b636d99dSDavid van Moolenbroek static int
wb_rrep(netdissect_options * ndo,const struct pkt_rrep * rrep,u_int len)353*b636d99dSDavid van Moolenbroek wb_rrep(netdissect_options *ndo,
354*b636d99dSDavid van Moolenbroek const struct pkt_rrep *rrep, u_int len)
355*b636d99dSDavid van Moolenbroek {
356*b636d99dSDavid van Moolenbroek const struct pkt_dop *dop = &rrep->pr_dop;
357*b636d99dSDavid van Moolenbroek
358*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " wb-rrep:"));
359*b636d99dSDavid van Moolenbroek if (len < sizeof(*rrep) || !ND_TTEST(*rrep))
360*b636d99dSDavid van Moolenbroek return (-1);
361*b636d99dSDavid van Moolenbroek len -= sizeof(*rrep);
362*b636d99dSDavid van Moolenbroek
363*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " for %s %s:%u<%u:%u>",
364*b636d99dSDavid van Moolenbroek ipaddr_string(ndo, &rrep->pr_id),
365*b636d99dSDavid van Moolenbroek ipaddr_string(ndo, &dop->pd_page.p_sid),
366*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&dop->pd_page.p_uid),
367*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&dop->pd_sseq),
368*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&dop->pd_eseq)));
369*b636d99dSDavid van Moolenbroek
370*b636d99dSDavid van Moolenbroek if (ndo->ndo_vflag)
371*b636d99dSDavid van Moolenbroek return (wb_dops(ndo, dop,
372*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&dop->pd_sseq),
373*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&dop->pd_eseq)));
374*b636d99dSDavid van Moolenbroek return (0);
375*b636d99dSDavid van Moolenbroek }
376*b636d99dSDavid van Moolenbroek
377*b636d99dSDavid van Moolenbroek static int
wb_drawop(netdissect_options * ndo,const struct pkt_dop * dop,u_int len)378*b636d99dSDavid van Moolenbroek wb_drawop(netdissect_options *ndo,
379*b636d99dSDavid van Moolenbroek const struct pkt_dop *dop, u_int len)
380*b636d99dSDavid van Moolenbroek {
381*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " wb-dop:"));
382*b636d99dSDavid van Moolenbroek if (len < sizeof(*dop) || !ND_TTEST(*dop))
383*b636d99dSDavid van Moolenbroek return (-1);
384*b636d99dSDavid van Moolenbroek len -= sizeof(*dop);
385*b636d99dSDavid van Moolenbroek
386*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " %s:%u<%u:%u>",
387*b636d99dSDavid van Moolenbroek ipaddr_string(ndo, &dop->pd_page.p_sid),
388*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&dop->pd_page.p_uid),
389*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&dop->pd_sseq),
390*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&dop->pd_eseq)));
391*b636d99dSDavid van Moolenbroek
392*b636d99dSDavid van Moolenbroek if (ndo->ndo_vflag)
393*b636d99dSDavid van Moolenbroek return (wb_dops(ndo, dop,
394*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&dop->pd_sseq),
395*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&dop->pd_eseq)));
396*b636d99dSDavid van Moolenbroek return (0);
397*b636d99dSDavid van Moolenbroek }
398*b636d99dSDavid van Moolenbroek
399*b636d99dSDavid van Moolenbroek /*
400*b636d99dSDavid van Moolenbroek * Print whiteboard multicast packets.
401*b636d99dSDavid van Moolenbroek */
402*b636d99dSDavid van Moolenbroek void
wb_print(netdissect_options * ndo,register const void * hdr,register u_int len)403*b636d99dSDavid van Moolenbroek wb_print(netdissect_options *ndo,
404*b636d99dSDavid van Moolenbroek register const void *hdr, register u_int len)
405*b636d99dSDavid van Moolenbroek {
406*b636d99dSDavid van Moolenbroek register const struct pkt_hdr *ph;
407*b636d99dSDavid van Moolenbroek
408*b636d99dSDavid van Moolenbroek ph = (const struct pkt_hdr *)hdr;
409*b636d99dSDavid van Moolenbroek if (len < sizeof(*ph) || !ND_TTEST(*ph)) {
410*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s", tstr));
411*b636d99dSDavid van Moolenbroek return;
412*b636d99dSDavid van Moolenbroek }
413*b636d99dSDavid van Moolenbroek len -= sizeof(*ph);
414*b636d99dSDavid van Moolenbroek
415*b636d99dSDavid van Moolenbroek if (ph->ph_flags)
416*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "*"));
417*b636d99dSDavid van Moolenbroek switch (ph->ph_type) {
418*b636d99dSDavid van Moolenbroek
419*b636d99dSDavid van Moolenbroek case PT_KILL:
420*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " wb-kill"));
421*b636d99dSDavid van Moolenbroek return;
422*b636d99dSDavid van Moolenbroek
423*b636d99dSDavid van Moolenbroek case PT_ID:
424*b636d99dSDavid van Moolenbroek if (wb_id(ndo, (struct pkt_id *)(ph + 1), len) >= 0)
425*b636d99dSDavid van Moolenbroek return;
426*b636d99dSDavid van Moolenbroek break;
427*b636d99dSDavid van Moolenbroek
428*b636d99dSDavid van Moolenbroek case PT_RREQ:
429*b636d99dSDavid van Moolenbroek if (wb_rreq(ndo, (struct pkt_rreq *)(ph + 1), len) >= 0)
430*b636d99dSDavid van Moolenbroek return;
431*b636d99dSDavid van Moolenbroek break;
432*b636d99dSDavid van Moolenbroek
433*b636d99dSDavid van Moolenbroek case PT_RREP:
434*b636d99dSDavid van Moolenbroek if (wb_rrep(ndo, (struct pkt_rrep *)(ph + 1), len) >= 0)
435*b636d99dSDavid van Moolenbroek return;
436*b636d99dSDavid van Moolenbroek break;
437*b636d99dSDavid van Moolenbroek
438*b636d99dSDavid van Moolenbroek case PT_DRAWOP:
439*b636d99dSDavid van Moolenbroek if (wb_drawop(ndo, (struct pkt_dop *)(ph + 1), len) >= 0)
440*b636d99dSDavid van Moolenbroek return;
441*b636d99dSDavid van Moolenbroek break;
442*b636d99dSDavid van Moolenbroek
443*b636d99dSDavid van Moolenbroek case PT_PREQ:
444*b636d99dSDavid van Moolenbroek if (wb_preq(ndo, (struct pkt_preq *)(ph + 1), len) >= 0)
445*b636d99dSDavid van Moolenbroek return;
446*b636d99dSDavid van Moolenbroek break;
447*b636d99dSDavid van Moolenbroek
448*b636d99dSDavid van Moolenbroek case PT_PREP:
449*b636d99dSDavid van Moolenbroek if (wb_prep(ndo, (struct pkt_prep *)(ph + 1), len) >= 0)
450*b636d99dSDavid van Moolenbroek return;
451*b636d99dSDavid van Moolenbroek break;
452*b636d99dSDavid van Moolenbroek
453*b636d99dSDavid van Moolenbroek default:
454*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " wb-%d!", ph->ph_type));
455*b636d99dSDavid van Moolenbroek return;
456*b636d99dSDavid van Moolenbroek }
457*b636d99dSDavid van Moolenbroek }
458