xref: /minix3/external/bsd/tcpdump/dist/print-wb.c (revision b636d99d91c3d54204248f643c14627405d4afd1)
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