2 * Copyright (c) 1993, 1994, 1995, 1996
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the University of California,
13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23 static const char rcsid[] _U_ =
24 "@(#) $Header: /tcpdump/master/tcpdump/print-wb.c,v 1.30.2.3 2004/03/24 04:06:52 guy Exp $ (LBL)";
31 #include <tcpdump-stdinc.h>
35 #include "interface.h"
36 #include "addrtoname.h"
39 /* XXX need to add byte-swapping macros! */
40 /* XXX - you mean like the ones in "extract.h"? */
43 * Largest packet size. Everything should fit within this space.
44 * For instance, multiline objects are sent piecewise.
46 #define MAXFRAMESIZE 1024
49 * Multiple drawing ops can be sent in one packet. Each one starts on a
50 * an even multiple of DOP_ALIGN bytes, which must be a power of two.
53 #define DOP_ROUNDUP(x) ((((int)(x)) + (DOP_ALIGN - 1)) & ~(DOP_ALIGN - 1))
55 ((struct dophdr *)((u_char *)(d) + \
56 DOP_ROUNDUP(EXTRACT_16BITS(&(d)->dh_len) + sizeof(*(d)))))
59 * Format of the whiteboard packet header.
60 * The transport level header.
63 u_int32_t ph_src; /* site id of source */
64 u_int32_t ph_ts; /* time stamp (for skew computation) */
65 u_int16_t ph_version; /* version number */
66 u_char ph_type; /* message type */
67 u_char ph_flags; /* message flags */
71 #define PT_DRAWOP 0 /* drawing operation */
72 #define PT_ID 1 /* announcement packet */
73 #define PT_RREQ 2 /* repair request */
74 #define PT_RREP 3 /* repair reply */
75 #define PT_KILL 4 /* terminate participation */
76 #define PT_PREQ 5 /* page vector request */
77 #define PT_PREP 7 /* page vector reply */
80 #undef PF_USER /* {Digital,Tru64} UNIX define this, alas */
84 #define PF_USER 0x01 /* hint that packet has interactive data */
85 #define PF_VIS 0x02 /* only visible ops wanted */
88 u_int32_t p_sid; /* session id of initiator */
89 u_int32_t p_uid; /* page number */
93 u_int32_t dh_ts; /* sender's timestamp */
94 u_int16_t dh_len; /* body length */
96 u_char dh_type; /* body type */
100 * Drawing op sub-types.
116 #define DT_MAXTYPE 15
119 * A drawing operation.
122 struct PageID pd_page; /* page that operations apply to */
123 u_int32_t pd_sseq; /* start sequence number */
124 u_int32_t pd_eseq; /* end sequence number */
125 /* drawing ops follow */
132 u_int32_t pr_id; /* source id of drawops to be repaired */
133 struct PageID pr_page; /* page of drawops */
134 u_int32_t pr_sseq; /* start seqno */
135 u_int32_t pr_eseq; /* end seqno */
142 u_int32_t pr_id; /* original site id of ops */
143 struct pkt_dop pr_dop;
144 /* drawing ops follow */
161 * An announcement packet.
165 struct PageID pi_mpage; /* current page */
166 struct pgstate pi_ps;
168 /* null-terminated site name */
172 struct PageID pp_page;
178 u_int32_t pp_n; /* size of pageid array */
179 /* pgstate's follow */
183 wb_id(const struct pkt_id *id, u_int len)
187 const struct id_off *io;
192 if (len < sizeof(*id) || (u_char *)(id + 1) > snapend)
196 printf(" %u/%s:%u (max %u/%s:%u) ",
197 EXTRACT_32BITS(&id->pi_ps.slot),
198 ipaddr_string(&id->pi_ps.page.p_sid),
199 EXTRACT_32BITS(&id->pi_ps.page.p_uid),
200 EXTRACT_32BITS(&id->pi_mslot),
201 ipaddr_string(&id->pi_mpage.p_sid),
202 EXTRACT_32BITS(&id->pi_mpage.p_uid));
204 nid = EXTRACT_16BITS(&id->pi_ps.nid);
205 len -= sizeof(*io) * nid;
206 io = (struct id_off *)(id + 1);
207 cp = (char *)(io + nid);
208 if ((u_char *)cp + len <= snapend) {
210 (void)fn_print((u_char *)cp, (u_char *)cp + len);
215 for (i = 0; i < nid && (u_char *)(io + 1) <= snapend; ++io, ++i) {
217 c, ipaddr_string(&io->id), EXTRACT_32BITS(&io->off));
228 wb_rreq(const struct pkt_rreq *rreq, u_int len)
231 if (len < sizeof(*rreq) || (u_char *)(rreq + 1) > snapend)
234 printf(" please repair %s %s:%u<%u:%u>",
235 ipaddr_string(&rreq->pr_id),
236 ipaddr_string(&rreq->pr_page.p_sid),
237 EXTRACT_32BITS(&rreq->pr_page.p_uid),
238 EXTRACT_32BITS(&rreq->pr_sseq),
239 EXTRACT_32BITS(&rreq->pr_eseq));
244 wb_preq(const struct pkt_preq *preq, u_int len)
247 if (len < sizeof(*preq) || (u_char *)(preq + 1) > snapend)
250 printf(" need %u/%s:%u",
251 EXTRACT_32BITS(&preq->pp_low),
252 ipaddr_string(&preq->pp_page.p_sid),
253 EXTRACT_32BITS(&preq->pp_page.p_uid));
258 wb_prep(const struct pkt_prep *prep, u_int len)
261 const struct pgstate *ps;
262 const u_char *ep = snapend;
265 if (len < sizeof(*prep)) {
268 n = EXTRACT_32BITS(&prep->pp_n);
269 ps = (const struct pgstate *)(prep + 1);
270 while (--n >= 0 && (u_char *)(ps + 1) <= ep) {
271 const struct id_off *io, *ie;
275 EXTRACT_32BITS(&ps->slot),
276 ipaddr_string(&ps->page.p_sid),
277 EXTRACT_32BITS(&ps->page.p_uid));
278 io = (struct id_off *)(ps + 1);
279 for (ie = io + ps->nid; io < ie && (u_char *)(io + 1) <= ep; ++io) {
280 printf("%c%s:%u", c, ipaddr_string(&io->id),
281 EXTRACT_32BITS(&io->off));
285 ps = (struct pgstate *)io;
287 return ((u_char *)ps <= ep? 0 : -1);
291 const char *dopstr[] = {
311 wb_dops(const struct dophdr *dh, u_int32_t ss, u_int32_t es)
314 for ( ; ss <= es; ++ss) {
315 register int t = dh->dh_type;
318 printf(" dop-%d!", t);
320 printf(" %s", dopstr[t]);
321 if (t == DT_SKIP || t == DT_HOLE) {
322 u_int32_t ts = EXTRACT_32BITS(&dh->dh_ts);
323 printf("%d", ts - ss + 1);
324 if (ss > ts || ts > es) {
333 if ((u_char *)dh > snapend) {
343 wb_rrep(const struct pkt_rrep *rrep, u_int len)
345 const struct pkt_dop *dop = &rrep->pr_dop;
348 if (len < sizeof(*rrep) || (u_char *)(rrep + 1) > snapend)
350 len -= sizeof(*rrep);
352 printf(" for %s %s:%u<%u:%u>",
353 ipaddr_string(&rrep->pr_id),
354 ipaddr_string(&dop->pd_page.p_sid),
355 EXTRACT_32BITS(&dop->pd_page.p_uid),
356 EXTRACT_32BITS(&dop->pd_sseq),
357 EXTRACT_32BITS(&dop->pd_eseq));
360 return (wb_dops((const struct dophdr *)(dop + 1),
361 EXTRACT_32BITS(&dop->pd_sseq),
362 EXTRACT_32BITS(&dop->pd_eseq)));
367 wb_drawop(const struct pkt_dop *dop, u_int len)
370 if (len < sizeof(*dop) || (u_char *)(dop + 1) > snapend)
374 printf(" %s:%u<%u:%u>",
375 ipaddr_string(&dop->pd_page.p_sid),
376 EXTRACT_32BITS(&dop->pd_page.p_uid),
377 EXTRACT_32BITS(&dop->pd_sseq),
378 EXTRACT_32BITS(&dop->pd_eseq));
381 return (wb_dops((const struct dophdr *)(dop + 1),
382 EXTRACT_32BITS(&dop->pd_sseq),
383 EXTRACT_32BITS(&dop->pd_eseq)));
388 * Print whiteboard multicast packets.
391 wb_print(register const void *hdr, register u_int len)
393 register const struct pkt_hdr *ph;
395 ph = (const struct pkt_hdr *)hdr;
396 if (len < sizeof(*ph) || (u_char *)(ph + 1) > snapend) {
404 switch (ph->ph_type) {
411 if (wb_id((struct pkt_id *)(ph + 1), len) >= 0)
416 if (wb_rreq((struct pkt_rreq *)(ph + 1), len) >= 0)
421 if (wb_rrep((struct pkt_rrep *)(ph + 1), len) >= 0)
426 if (wb_drawop((struct pkt_dop *)(ph + 1), len) >= 0)
431 if (wb_preq((struct pkt_preq *)(ph + 1), len) >= 0)
436 if (wb_prep((struct pkt_prep *)(ph + 1), len) >= 0)
441 printf(" wb-%d!", ph->ph_type);