]>
The Tcpdump Group git mirrors - tcpdump/blob - print-wb.c
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 */
26 #include "netdissect-stdinc.h"
28 #define ND_LONGJMP_FROM_TCHECK
29 #include "netdissect.h"
30 #include "addrtoname.h"
36 * Largest packet size. Everything should fit within this space.
37 * For instance, multiline objects are sent piecewise.
39 #define MAXFRAMESIZE 1024
43 * Multiple drawing ops can be sent in one packet. Each one starts on a
44 * an even multiple of DOP_ALIGN bytes, which must be a power of two.
47 #define DOP_ROUNDUP(x) roundup2(x, DOP_ALIGN)
49 ((const struct dophdr *)((const u_char *)(d) + \
50 DOP_ROUNDUP(GET_BE_U_2((d)->dh_len) + sizeof(*(d)))))
53 * Format of the whiteboard packet header.
54 * The transport level header.
57 nd_uint32_t ph_src
; /* site id of source */
58 nd_uint32_t ph_ts
; /* time stamp (for skew computation) */
59 nd_uint16_t ph_version
; /* version number */
60 nd_uint8_t ph_type
; /* message type */
61 nd_uint8_t ph_flags
; /* message flags */
65 #define PT_DRAWOP 0 /* drawing operation */
66 #define PT_ID 1 /* announcement packet */
67 #define PT_RREQ 2 /* repair request */
68 #define PT_RREP 3 /* repair reply */
69 #define PT_KILL 4 /* terminate participation */
70 #define PT_PREQ 5 /* page vector request */
71 #define PT_PREP 7 /* page vector reply */
75 #undef PF_USER /* {Digital,Tru64} UNIX define this, alas */
79 #define PF_USER 0x01 /* hint that packet has interactive data */
80 #define PF_VIS 0x02 /* only visible ops wanted */
84 nd_uint32_t p_sid
; /* session id of initiator */
85 nd_uint32_t p_uid
; /* page number */
89 nd_uint32_t dh_ts
; /* sender's timestamp */
90 nd_uint16_t dh_len
; /* body length */
92 nd_uint8_t dh_type
; /* body type */
96 * Drawing op sub-types.
112 static const struct tok dop_str
[] = {
117 { DT_XFORM
, "XFORM" },
122 { DT_PSCODE
, "PSCODE" },
123 { DT_PSCOMP
, "PSCOMP" },
131 * A drawing operation.
134 struct PageID pd_page
; /* page that operations apply to */
135 nd_uint32_t pd_sseq
; /* start sequence number */
136 nd_uint32_t pd_eseq
; /* end sequence number */
137 /* drawing ops follow */
144 nd_uint32_t pr_id
; /* source id of drawops to be repaired */
145 struct PageID pr_page
; /* page of drawops */
146 nd_uint32_t pr_sseq
; /* start seqno */
147 nd_uint32_t pr_eseq
; /* end seqno */
154 nd_uint32_t pr_id
; /* original site id of ops */
155 struct pkt_dop pr_dop
;
156 /* drawing ops follow */
173 * An announcement packet.
176 nd_uint32_t pi_mslot
;
177 struct PageID pi_mpage
; /* current page */
178 struct pgstate pi_ps
;
180 /* null-terminated site name */
184 struct PageID pp_page
;
190 nd_uint32_t pp_n
; /* size of pageid array */
191 /* pgstate's follow */
195 wb_id(netdissect_options
*ndo
,
196 const struct pkt_id
*id
, u_int len
)
199 const u_char
*sitename
;
200 const struct id_off
*io
;
205 if (len
< sizeof(*id
))
209 ND_PRINT(" %u/%s:%u (max %u/%s:%u) ",
210 GET_BE_U_4(id
->pi_ps
.slot
),
211 GET_IPADDR_STRING(id
->pi_ps
.page
.p_sid
),
212 GET_BE_U_4(id
->pi_ps
.page
.p_uid
),
213 GET_BE_U_4(id
->pi_mslot
),
214 GET_IPADDR_STRING(id
->pi_mpage
.p_sid
),
215 GET_BE_U_4(id
->pi_mpage
.p_uid
));
216 /* now the rest of the fixed-size part of struct pkt_id */
219 nid
= GET_BE_U_2(id
->pi_ps
.nid
);
220 if (len
< sizeof(*io
) * nid
)
222 len
-= sizeof(*io
) * nid
;
223 io
= (const struct id_off
*)(id
+ 1);
224 sitename
= (const u_char
*)(io
+ nid
);
227 for (i
= 0; i
< nid
; ++io
, ++i
) {
229 c
, GET_IPADDR_STRING(io
->id
), GET_BE_U_4(io
->off
));
233 nd_printjnp(ndo
, sitename
, len
);
239 wb_rreq(netdissect_options
*ndo
,
240 const struct pkt_rreq
*rreq
, u_int len
)
242 ND_PRINT(" wb-rreq:");
243 if (len
< sizeof(*rreq
))
246 ND_PRINT(" please repair %s %s:%u<%u:%u>",
247 GET_IPADDR_STRING(rreq
->pr_id
),
248 GET_IPADDR_STRING(rreq
->pr_page
.p_sid
),
249 GET_BE_U_4(rreq
->pr_page
.p_uid
),
250 GET_BE_U_4(rreq
->pr_sseq
),
251 GET_BE_U_4(rreq
->pr_eseq
));
256 wb_preq(netdissect_options
*ndo
,
257 const struct pkt_preq
*preq
, u_int len
)
259 ND_PRINT(" wb-preq:");
260 if (len
< sizeof(*preq
))
263 ND_PRINT(" need %u/%s:%u",
264 GET_BE_U_4(preq
->pp_low
),
265 GET_IPADDR_STRING(preq
->pp_page
.p_sid
),
266 GET_BE_U_4(preq
->pp_page
.p_uid
));
267 /* now the rest of the fixed-size part of struct pkt_req */
268 ND_TCHECK_SIZE(preq
);
273 wb_prep(netdissect_options
*ndo
,
274 const struct pkt_prep
*prep
, u_int len
)
277 const struct pgstate
*ps
;
279 ND_PRINT(" wb-prep:");
280 if (len
< sizeof(*prep
))
282 n
= GET_BE_U_4(prep
->pp_n
);
283 ps
= (const struct pgstate
*)(prep
+ 1);
285 const struct id_off
*io
, *ie
;
288 ND_PRINT(" %u/%s:%u",
289 GET_BE_U_4(ps
->slot
),
290 GET_IPADDR_STRING(ps
->page
.p_sid
),
291 GET_BE_U_4(ps
->page
.p_uid
));
292 /* now the rest of the fixed-size part of struct pgstate */
294 io
= (const struct id_off
*)(ps
+ 1);
295 for (ie
= io
+ GET_U_1(ps
->nid
); io
< ie
; ++io
) {
296 ND_PRINT("%c%s:%u", c
, GET_IPADDR_STRING(io
->id
),
297 GET_BE_U_4(io
->off
));
301 ps
= (const struct pgstate
*)io
;
308 wb_dops(netdissect_options
*ndo
, const struct pkt_dop
*dop
,
309 uint32_t ss
, uint32_t es
)
311 const struct dophdr
*dh
= (const struct dophdr
*)((const u_char
*)dop
+ sizeof(*dop
));
314 for ( ; ss
<= es
; ++ss
) {
317 t
= GET_U_1(dh
->dh_type
);
319 ND_PRINT(" %s", tok2str(dop_str
, "dop-%u!", t
));
320 if (t
== DT_SKIP
|| t
== DT_HOLE
) {
321 uint32_t ts
= GET_BE_U_4(dh
->dh_ts
);
322 ND_PRINT("%u", ts
- ss
+ 1);
323 if (ss
> ts
|| ts
> es
) {
336 wb_rrep(netdissect_options
*ndo
,
337 const struct pkt_rrep
*rrep
, u_int len
)
339 const struct pkt_dop
*dop
= &rrep
->pr_dop
;
341 ND_PRINT(" wb-rrep:");
342 if (len
< sizeof(*rrep
))
344 len
-= sizeof(*rrep
);
346 ND_PRINT(" for %s %s:%u<%u:%u>",
347 GET_IPADDR_STRING(rrep
->pr_id
),
348 GET_IPADDR_STRING(dop
->pd_page
.p_sid
),
349 GET_BE_U_4(dop
->pd_page
.p_uid
),
350 GET_BE_U_4(dop
->pd_sseq
),
351 GET_BE_U_4(dop
->pd_eseq
));
355 GET_BE_U_4(dop
->pd_sseq
),
356 GET_BE_U_4(dop
->pd_eseq
));
361 wb_drawop(netdissect_options
*ndo
,
362 const struct pkt_dop
*dop
, u_int len
)
364 ND_PRINT(" wb-dop:");
365 if (len
< sizeof(*dop
))
369 ND_PRINT(" %s:%u<%u:%u>",
370 GET_IPADDR_STRING(dop
->pd_page
.p_sid
),
371 GET_BE_U_4(dop
->pd_page
.p_uid
),
372 GET_BE_U_4(dop
->pd_sseq
),
373 GET_BE_U_4(dop
->pd_eseq
));
377 GET_BE_U_4(dop
->pd_sseq
),
378 GET_BE_U_4(dop
->pd_eseq
));
383 * Print whiteboard multicast packets.
386 wb_print(netdissect_options
*ndo
,
387 const u_char
*hdr
, u_int len
)
389 const struct pkt_hdr
*ph
;
393 ndo
->ndo_protocol
= "wb";
394 ph
= (const struct pkt_hdr
*)hdr
;
395 if (len
< sizeof(*ph
))
400 if (GET_U_1(ph
->ph_flags
))
402 type
= GET_U_1(ph
->ph_type
);
406 ND_PRINT(" wb-kill");
410 print_result
= wb_id(ndo
, (const struct pkt_id
*)(ph
+ 1), len
);
414 print_result
= wb_rreq(ndo
, (const struct pkt_rreq
*)(ph
+ 1), len
);
418 print_result
= wb_rrep(ndo
, (const struct pkt_rrep
*)(ph
+ 1), len
);
422 print_result
= wb_drawop(ndo
, (const struct pkt_dop
*)(ph
+ 1), len
);
426 print_result
= wb_preq(ndo
, (const struct pkt_preq
*)(ph
+ 1), len
);
430 print_result
= wb_prep(ndo
, (const struct pkt_prep
*)(ph
+ 1), len
);
434 ND_PRINT(" wb-%u!", type
);
437 if (print_result
< 0)
442 nd_print_invalid(ndo
);