]>
The Tcpdump Group git mirrors - tcpdump/blob - print-wb.c
42686906c252a4a3edd9b5cb99f310dbf8bb76af
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.
22 /* \summary: White Board printer */
28 #include "netdissect-stdinc.h"
30 #include "netdissect.h"
31 #include "addrtoname.h"
34 static const char tstr
[] = "[|wb]";
36 /* XXX need to add byte-swapping macros! */
37 /* XXX - you mean like the ones in "extract.h"? */
40 * Largest packet size. Everything should fit within this space.
41 * For instance, multiline objects are sent piecewise.
43 #define MAXFRAMESIZE 1024
46 * Multiple drawing ops can be sent in one packet. Each one starts on a
47 * an even multiple of DOP_ALIGN bytes, which must be a power of two.
50 #define DOP_ROUNDUP(x) ((((int)(x)) + (DOP_ALIGN - 1)) & ~(DOP_ALIGN - 1))
52 ((const struct dophdr *)((const u_char *)(d) + \
53 DOP_ROUNDUP(EXTRACT_BE_U_2((d)->dh_len) + sizeof(*(d)))))
56 * Format of the whiteboard packet header.
57 * The transport level header.
60 nd_uint32_t ph_src
; /* site id of source */
61 nd_uint32_t ph_ts
; /* time stamp (for skew computation) */
62 nd_uint16_t ph_version
; /* version number */
63 nd_uint8_t ph_type
; /* message type */
64 nd_uint8_t ph_flags
; /* message flags */
68 #define PT_DRAWOP 0 /* drawing operation */
69 #define PT_ID 1 /* announcement packet */
70 #define PT_RREQ 2 /* repair request */
71 #define PT_RREP 3 /* repair reply */
72 #define PT_KILL 4 /* terminate participation */
73 #define PT_PREQ 5 /* page vector request */
74 #define PT_PREP 7 /* page vector reply */
77 #undef PF_USER /* {Digital,Tru64} UNIX define this, alas */
81 #define PF_USER 0x01 /* hint that packet has interactive data */
82 #define PF_VIS 0x02 /* only visible ops wanted */
85 nd_uint32_t p_sid
; /* session id of initiator */
86 nd_uint32_t p_uid
; /* page number */
90 nd_uint32_t dh_ts
; /* sender's timestamp */
91 nd_uint16_t dh_len
; /* body length */
93 nd_uint8_t dh_type
; /* body type */
97 * Drawing op sub-types.
113 #define DT_MAXTYPE 15
116 * A drawing operation.
119 struct PageID pd_page
; /* page that operations apply to */
120 nd_uint32_t pd_sseq
; /* start sequence number */
121 nd_uint32_t pd_eseq
; /* end sequence number */
122 /* drawing ops follow */
129 nd_uint32_t pr_id
; /* source id of drawops to be repaired */
130 struct PageID pr_page
; /* page of drawops */
131 nd_uint32_t pr_sseq
; /* start seqno */
132 nd_uint32_t pr_eseq
; /* end seqno */
139 nd_uint32_t pr_id
; /* original site id of ops */
140 struct pkt_dop pr_dop
;
141 /* drawing ops follow */
158 * An announcement packet.
161 nd_uint32_t pi_mslot
;
162 struct PageID pi_mpage
; /* current page */
163 struct pgstate pi_ps
;
165 /* null-terminated site name */
169 struct PageID pp_page
;
175 nd_uint32_t pp_n
; /* size of pageid array */
176 /* pgstate's follow */
180 wb_id(netdissect_options
*ndo
,
181 const struct pkt_id
*id
, u_int len
)
185 const struct id_off
*io
;
190 if (len
< sizeof(*id
) || !ND_TTEST_SIZE(id
))
194 ND_PRINT(" %u/%s:%u (max %u/%s:%u) ",
195 EXTRACT_BE_U_4(id
->pi_ps
.slot
),
196 ipaddr_string(ndo
, id
->pi_ps
.page
.p_sid
),
197 EXTRACT_BE_U_4(id
->pi_ps
.page
.p_uid
),
198 EXTRACT_BE_U_4(id
->pi_mslot
),
199 ipaddr_string(ndo
, id
->pi_mpage
.p_sid
),
200 EXTRACT_BE_U_4(id
->pi_mpage
.p_uid
));
202 nid
= EXTRACT_BE_U_2(id
->pi_ps
.nid
);
203 len
-= sizeof(*io
) * nid
;
204 io
= (const struct id_off
*)(id
+ 1);
205 cp
= (const char *)(io
+ nid
);
206 if (ND_TTEST_LEN(cp
, len
)) {
208 fn_print(ndo
, (const u_char
*)cp
, (const u_char
*)cp
+ len
);
213 for (i
= 0; i
< nid
&& ND_TTEST_SIZE(io
); ++io
, ++i
) {
215 c
, ipaddr_string(ndo
, io
->id
), EXTRACT_BE_U_4(io
->off
));
226 wb_rreq(netdissect_options
*ndo
,
227 const struct pkt_rreq
*rreq
, u_int len
)
229 ND_PRINT(" wb-rreq:");
230 if (len
< sizeof(*rreq
) || !ND_TTEST_SIZE(rreq
))
233 ND_PRINT(" please repair %s %s:%u<%u:%u>",
234 ipaddr_string(ndo
, rreq
->pr_id
),
235 ipaddr_string(ndo
, rreq
->pr_page
.p_sid
),
236 EXTRACT_BE_U_4(rreq
->pr_page
.p_uid
),
237 EXTRACT_BE_U_4(rreq
->pr_sseq
),
238 EXTRACT_BE_U_4(rreq
->pr_eseq
));
243 wb_preq(netdissect_options
*ndo
,
244 const struct pkt_preq
*preq
, u_int len
)
246 ND_PRINT(" wb-preq:");
247 if (len
< sizeof(*preq
) || !ND_TTEST_SIZE(preq
))
250 ND_PRINT(" need %u/%s:%u",
251 EXTRACT_BE_U_4(preq
->pp_low
),
252 ipaddr_string(ndo
, preq
->pp_page
.p_sid
),
253 EXTRACT_BE_U_4(preq
->pp_page
.p_uid
));
258 wb_prep(netdissect_options
*ndo
,
259 const struct pkt_prep
*prep
, u_int len
)
262 const struct pgstate
*ps
;
263 const u_char
*ep
= ndo
->ndo_snapend
;
265 ND_PRINT(" wb-prep:");
266 if (len
< sizeof(*prep
) || !ND_TTEST_SIZE(prep
))
268 n
= EXTRACT_BE_U_4(prep
->pp_n
);
269 ps
= (const struct pgstate
*)(prep
+ 1);
270 while (n
!= 0 && ND_TTEST_SIZE(ps
)) {
271 const struct id_off
*io
, *ie
;
274 ND_PRINT(" %u/%s:%u",
275 EXTRACT_BE_U_4(ps
->slot
),
276 ipaddr_string(ndo
, ps
->page
.p_sid
),
277 EXTRACT_BE_U_4(ps
->page
.p_uid
));
278 io
= (const struct id_off
*)(ps
+ 1);
279 for (ie
= io
+ EXTRACT_U_1(ps
->nid
); io
< ie
&& ND_TTEST_SIZE(io
); ++io
) {
280 ND_PRINT("%c%s:%u", c
, ipaddr_string(ndo
, io
->id
),
281 EXTRACT_BE_U_4(io
->off
));
285 ps
= (const struct pgstate
*)io
;
288 return ((const u_char
*)ps
<= ep
? 0 : -1);
292 static const char *dopstr
[] = {
312 wb_dops(netdissect_options
*ndo
, const struct pkt_dop
*dop
,
313 uint32_t ss
, uint32_t es
)
315 const struct dophdr
*dh
= (const struct dophdr
*)((const u_char
*)dop
+ sizeof(*dop
));
318 for ( ; ss
<= es
; ++ss
) {
321 if (!ND_TTEST_SIZE(dh
)) {
322 ND_PRINT("%s", tstr
);
325 t
= EXTRACT_U_1(dh
->dh_type
);
328 ND_PRINT(" dop-%u!", t
);
330 ND_PRINT(" %s", dopstr
[t
]);
331 if (t
== DT_SKIP
|| t
== DT_HOLE
) {
332 uint32_t ts
= EXTRACT_BE_U_4(dh
->dh_ts
);
333 ND_PRINT("%u", ts
- ss
+ 1);
334 if (ss
> ts
|| ts
> es
) {
349 wb_rrep(netdissect_options
*ndo
,
350 const struct pkt_rrep
*rrep
, u_int len
)
352 const struct pkt_dop
*dop
= &rrep
->pr_dop
;
354 ND_PRINT(" wb-rrep:");
355 if (len
< sizeof(*rrep
) || !ND_TTEST_SIZE(rrep
))
357 len
-= sizeof(*rrep
);
359 ND_PRINT(" for %s %s:%u<%u:%u>",
360 ipaddr_string(ndo
, rrep
->pr_id
),
361 ipaddr_string(ndo
, dop
->pd_page
.p_sid
),
362 EXTRACT_BE_U_4(dop
->pd_page
.p_uid
),
363 EXTRACT_BE_U_4(dop
->pd_sseq
),
364 EXTRACT_BE_U_4(dop
->pd_eseq
));
367 return (wb_dops(ndo
, dop
,
368 EXTRACT_BE_U_4(dop
->pd_sseq
),
369 EXTRACT_BE_U_4(dop
->pd_eseq
)));
374 wb_drawop(netdissect_options
*ndo
,
375 const struct pkt_dop
*dop
, u_int len
)
377 ND_PRINT(" wb-dop:");
378 if (len
< sizeof(*dop
) || !ND_TTEST_SIZE(dop
))
382 ND_PRINT(" %s:%u<%u:%u>",
383 ipaddr_string(ndo
, dop
->pd_page
.p_sid
),
384 EXTRACT_BE_U_4(dop
->pd_page
.p_uid
),
385 EXTRACT_BE_U_4(dop
->pd_sseq
),
386 EXTRACT_BE_U_4(dop
->pd_eseq
));
389 return (wb_dops(ndo
, dop
,
390 EXTRACT_BE_U_4(dop
->pd_sseq
),
391 EXTRACT_BE_U_4(dop
->pd_eseq
)));
396 * Print whiteboard multicast packets.
399 wb_print(netdissect_options
*ndo
,
400 const u_char
*hdr
, u_int len
)
402 const struct pkt_hdr
*ph
;
405 ndo
->ndo_protocol
= "wb";
406 ph
= (const struct pkt_hdr
*)hdr
;
407 if (len
< sizeof(*ph
) || !ND_TTEST_SIZE(ph
)) {
408 ND_PRINT("%s", tstr
);
413 if (EXTRACT_U_1(ph
->ph_flags
))
415 type
= EXTRACT_U_1(ph
->ph_type
);
419 ND_PRINT(" wb-kill");
423 if (wb_id(ndo
, (const struct pkt_id
*)(ph
+ 1), len
) >= 0)
425 ND_PRINT("%s", tstr
);
429 if (wb_rreq(ndo
, (const struct pkt_rreq
*)(ph
+ 1), len
) >= 0)
431 ND_PRINT("%s", tstr
);
435 if (wb_rrep(ndo
, (const struct pkt_rrep
*)(ph
+ 1), len
) >= 0)
437 ND_PRINT("%s", tstr
);
441 if (wb_drawop(ndo
, (const struct pkt_dop
*)(ph
+ 1), len
) >= 0)
443 ND_PRINT("%s", tstr
);
447 if (wb_preq(ndo
, (const struct pkt_preq
*)(ph
+ 1), len
) >= 0)
449 ND_PRINT("%s", tstr
);
453 if (wb_prep(ndo
, (const struct pkt_prep
*)(ph
+ 1), len
) >= 0)
455 ND_PRINT("%s", tstr
);
459 ND_PRINT(" wb-%u!", type
);