4 * Copyright (c) 1993, 1994, 1995, 1996
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that: (1) source code distributions
9 * retain the above copyright notice and this paragraph in its entirety, (2)
10 * distributions including binary code include the above copyright notice and
11 * this paragraph in its entirety in the documentation or other materials
12 * provided with the distribution, and (3) all advertising materials mentioning
13 * features or use of this software display the following acknowledgement:
14 * ``This product includes software developed by the University of California,
15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16 * the University nor the names of its contributors may be used to endorse
17 * or promote products derived from this software without specific prior
19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
24 #include <sys/cdefs.h>
27 static const char rcsid
[] _U_
=
28 "@(#) Header: /tcpdump/master/tcpdump/print-wb.c,v 1.33 2004/03/24 04:06:28 guy Exp (LBL)";
30 __RCSID("$NetBSD: tcpdump2rcsid.ex,v 1.1 2001/06/25 20:09:58 itojun Exp $");
38 #include <tcpdump-stdinc.h>
42 #include "interface.h"
43 #include "addrtoname.h"
46 /* XXX need to add byte-swapping macros! */
47 /* XXX - you mean like the ones in "extract.h"? */
50 * Largest packet size. Everything should fit within this space.
51 * For instance, multiline objects are sent piecewise.
53 #define MAXFRAMESIZE 1024
56 * Multiple drawing ops can be sent in one packet. Each one starts on a
57 * an even multiple of DOP_ALIGN bytes, which must be a power of two.
60 #define DOP_ROUNDUP(x) ((((int)(x)) + (DOP_ALIGN - 1)) & ~(DOP_ALIGN - 1))
62 ((struct dophdr *)((u_char *)(d) + \
63 DOP_ROUNDUP(EXTRACT_16BITS(&(d)->dh_len) + sizeof(*(d)))))
66 * Format of the whiteboard packet header.
67 * The transport level header.
70 u_int32_t ph_src
; /* site id of source */
71 u_int32_t ph_ts
; /* time stamp (for skew computation) */
72 u_int16_t ph_version
; /* version number */
73 u_char ph_type
; /* message type */
74 u_char ph_flags
; /* message flags */
78 #define PT_DRAWOP 0 /* drawing operation */
79 #define PT_ID 1 /* announcement packet */
80 #define PT_RREQ 2 /* repair request */
81 #define PT_RREP 3 /* repair reply */
82 #define PT_KILL 4 /* terminate participation */
83 #define PT_PREQ 5 /* page vector request */
84 #define PT_PREP 7 /* page vector reply */
87 #undef PF_USER /* {Digital,Tru64} UNIX define this, alas */
91 #define PF_USER 0x01 /* hint that packet has interactive data */
92 #define PF_VIS 0x02 /* only visible ops wanted */
95 u_int32_t p_sid
; /* session id of initiator */
96 u_int32_t p_uid
; /* page number */
100 u_int32_t dh_ts
; /* sender's timestamp */
101 u_int16_t dh_len
; /* body length */
103 u_char dh_type
; /* body type */
107 * Drawing op sub-types.
123 #define DT_MAXTYPE 15
126 * A drawing operation.
129 struct PageID pd_page
; /* page that operations apply to */
130 u_int32_t pd_sseq
; /* start sequence number */
131 u_int32_t pd_eseq
; /* end sequence number */
132 /* drawing ops follow */
139 u_int32_t pr_id
; /* source id of drawops to be repaired */
140 struct PageID pr_page
; /* page of drawops */
141 u_int32_t pr_sseq
; /* start seqno */
142 u_int32_t pr_eseq
; /* end seqno */
149 u_int32_t pr_id
; /* original site id of ops */
150 struct pkt_dop pr_dop
;
151 /* drawing ops follow */
168 * An announcement packet.
172 struct PageID pi_mpage
; /* current page */
173 struct pgstate pi_ps
;
175 /* null-terminated site name */
179 struct PageID pp_page
;
185 u_int32_t pp_n
; /* size of pageid array */
186 /* pgstate's follow */
190 wb_id(const struct pkt_id
*id
, u_int len
)
194 const struct id_off
*io
;
199 if (len
< sizeof(*id
) || (u_char
*)(id
+ 1) > snapend
)
203 printf(" %u/%s:%u (max %u/%s:%u) ",
204 EXTRACT_32BITS(&id
->pi_ps
.slot
),
205 ipaddr_string(&id
->pi_ps
.page
.p_sid
),
206 EXTRACT_32BITS(&id
->pi_ps
.page
.p_uid
),
207 EXTRACT_32BITS(&id
->pi_mslot
),
208 ipaddr_string(&id
->pi_mpage
.p_sid
),
209 EXTRACT_32BITS(&id
->pi_mpage
.p_uid
));
211 nid
= EXTRACT_16BITS(&id
->pi_ps
.nid
);
212 len
-= sizeof(*io
) * nid
;
213 io
= (struct id_off
*)(id
+ 1);
214 cp
= (char *)(io
+ nid
);
215 if ((u_char
*)cp
+ len
<= snapend
) {
217 (void)fn_print((u_char
*)cp
, (u_char
*)cp
+ len
);
222 for (i
= 0; i
< nid
&& (u_char
*)(io
+ 1) <= snapend
; ++io
, ++i
) {
224 c
, ipaddr_string(&io
->id
), EXTRACT_32BITS(&io
->off
));
235 wb_rreq(const struct pkt_rreq
*rreq
, u_int len
)
238 if (len
< sizeof(*rreq
) || (u_char
*)(rreq
+ 1) > snapend
)
241 printf(" please repair %s %s:%u<%u:%u>",
242 ipaddr_string(&rreq
->pr_id
),
243 ipaddr_string(&rreq
->pr_page
.p_sid
),
244 EXTRACT_32BITS(&rreq
->pr_page
.p_uid
),
245 EXTRACT_32BITS(&rreq
->pr_sseq
),
246 EXTRACT_32BITS(&rreq
->pr_eseq
));
251 wb_preq(const struct pkt_preq
*preq
, u_int len
)
254 if (len
< sizeof(*preq
) || (u_char
*)(preq
+ 1) > snapend
)
257 printf(" need %u/%s:%u",
258 EXTRACT_32BITS(&preq
->pp_low
),
259 ipaddr_string(&preq
->pp_page
.p_sid
),
260 EXTRACT_32BITS(&preq
->pp_page
.p_uid
));
265 wb_prep(const struct pkt_prep
*prep
, u_int len
)
268 const struct pgstate
*ps
;
269 const u_char
*ep
= snapend
;
272 if (len
< sizeof(*prep
)) {
275 n
= EXTRACT_32BITS(&prep
->pp_n
);
276 ps
= (const struct pgstate
*)(prep
+ 1);
277 while (--n
>= 0 && (u_char
*)(ps
+ 1) <= ep
) {
278 const struct id_off
*io
, *ie
;
282 EXTRACT_32BITS(&ps
->slot
),
283 ipaddr_string(&ps
->page
.p_sid
),
284 EXTRACT_32BITS(&ps
->page
.p_uid
));
285 io
= (struct id_off
*)(ps
+ 1);
286 for (ie
= io
+ ps
->nid
; io
< ie
&& (u_char
*)(io
+ 1) <= ep
; ++io
) {
287 printf("%c%s:%u", c
, ipaddr_string(&io
->id
),
288 EXTRACT_32BITS(&io
->off
));
292 ps
= (struct pgstate
*)io
;
294 return ((u_char
*)ps
<= ep
? 0 : -1);
298 const char *dopstr
[] = {
318 wb_dops(const struct dophdr
*dh
, u_int32_t ss
, u_int32_t es
)
321 for ( ; ss
<= es
; ++ss
) {
322 register int t
= dh
->dh_type
;
325 printf(" dop-%d!", t
);
327 printf(" %s", dopstr
[t
]);
328 if (t
== DT_SKIP
|| t
== DT_HOLE
) {
329 u_int32_t ts
= EXTRACT_32BITS(&dh
->dh_ts
);
330 printf("%d", ts
- ss
+ 1);
331 if (ss
> ts
|| ts
> es
) {
340 if ((u_char
*)dh
> snapend
) {
350 wb_rrep(const struct pkt_rrep
*rrep
, u_int len
)
352 const struct pkt_dop
*dop
= &rrep
->pr_dop
;
355 if (len
< sizeof(*rrep
) || (u_char
*)(rrep
+ 1) > snapend
)
357 len
-= sizeof(*rrep
);
359 printf(" for %s %s:%u<%u:%u>",
360 ipaddr_string(&rrep
->pr_id
),
361 ipaddr_string(&dop
->pd_page
.p_sid
),
362 EXTRACT_32BITS(&dop
->pd_page
.p_uid
),
363 EXTRACT_32BITS(&dop
->pd_sseq
),
364 EXTRACT_32BITS(&dop
->pd_eseq
));
367 return (wb_dops((const struct dophdr
*)(dop
+ 1),
368 EXTRACT_32BITS(&dop
->pd_sseq
),
369 EXTRACT_32BITS(&dop
->pd_eseq
)));
374 wb_drawop(const struct pkt_dop
*dop
, u_int len
)
377 if (len
< sizeof(*dop
) || (u_char
*)(dop
+ 1) > snapend
)
381 printf(" %s:%u<%u:%u>",
382 ipaddr_string(&dop
->pd_page
.p_sid
),
383 EXTRACT_32BITS(&dop
->pd_page
.p_uid
),
384 EXTRACT_32BITS(&dop
->pd_sseq
),
385 EXTRACT_32BITS(&dop
->pd_eseq
));
388 return (wb_dops((const struct dophdr
*)(dop
+ 1),
389 EXTRACT_32BITS(&dop
->pd_sseq
),
390 EXTRACT_32BITS(&dop
->pd_eseq
)));
395 * Print whiteboard multicast packets.
398 wb_print(register const void *hdr
, register u_int len
)
400 register const struct pkt_hdr
*ph
;
402 ph
= (const struct pkt_hdr
*)hdr
;
403 if (len
< sizeof(*ph
) || (u_char
*)(ph
+ 1) > snapend
) {
411 switch (ph
->ph_type
) {
418 if (wb_id((struct pkt_id
*)(ph
+ 1), len
) >= 0)
423 if (wb_rreq((struct pkt_rreq
*)(ph
+ 1), len
) >= 0)
428 if (wb_rrep((struct pkt_rrep
*)(ph
+ 1), len
) >= 0)
433 if (wb_drawop((struct pkt_dop
*)(ph
+ 1), len
) >= 0)
438 if (wb_preq((struct pkt_preq
*)(ph
+ 1), len
) >= 0)
443 if (wb_prep((struct pkt_prep
*)(ph
+ 1), len
) >= 0)
448 printf(" wb-%d!", ph
->ph_type
);