Expand PMF_FN_* macros.
[netbsd-mini2440.git] / dist / tcpdump / print-wb.c
blob156e2c03141cd7f7460b3d299dd66f93d2e871c6
1 /* $NetBSD$ */
3 /*
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
18 * written permission.
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>
25 #ifndef lint
26 #if 0
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)";
29 #else
30 __RCSID("$NetBSD: tcpdump2rcsid.ex,v 1.1 2001/06/25 20:09:58 itojun Exp $");
31 #endif
32 #endif
34 #ifdef HAVE_CONFIG_H
35 #include "config.h"
36 #endif
38 #include <tcpdump-stdinc.h>
40 #include <stdio.h>
42 #include "interface.h"
43 #include "addrtoname.h"
44 #include "extract.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.
59 #define DOP_ALIGN 4
60 #define DOP_ROUNDUP(x) ((((int)(x)) + (DOP_ALIGN - 1)) & ~(DOP_ALIGN - 1))
61 #define DOP_NEXT(d)\
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.
69 struct pkt_hdr {
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 */
77 /* Packet types */
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 */
86 #ifdef PF_USER
87 #undef PF_USER /* {Digital,Tru64} UNIX define this, alas */
88 #endif
90 /* flags */
91 #define PF_USER 0x01 /* hint that packet has interactive data */
92 #define PF_VIS 0x02 /* only visible ops wanted */
94 struct PageID {
95 u_int32_t p_sid; /* session id of initiator */
96 u_int32_t p_uid; /* page number */
99 struct dophdr {
100 u_int32_t dh_ts; /* sender's timestamp */
101 u_int16_t dh_len; /* body length */
102 u_char dh_flags;
103 u_char dh_type; /* body type */
104 /* body follows */
107 * Drawing op sub-types.
109 #define DT_RECT 2
110 #define DT_LINE 3
111 #define DT_ML 4
112 #define DT_DEL 5
113 #define DT_XFORM 6
114 #define DT_ELL 7
115 #define DT_CHAR 8
116 #define DT_STR 9
117 #define DT_NOP 10
118 #define DT_PSCODE 11
119 #define DT_PSCOMP 12
120 #define DT_REF 13
121 #define DT_SKIP 14
122 #define DT_HOLE 15
123 #define DT_MAXTYPE 15
126 * A drawing operation.
128 struct pkt_dop {
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 */
136 * A repair request.
138 struct pkt_rreq {
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 */
146 * A repair reply.
148 struct pkt_rrep {
149 u_int32_t pr_id; /* original site id of ops */
150 struct pkt_dop pr_dop;
151 /* drawing ops follow */
154 struct id_off {
155 u_int32_t id;
156 u_int32_t off;
159 struct pgstate {
160 u_int32_t slot;
161 struct PageID page;
162 u_int16_t nid;
163 u_int16_t rsvd;
164 /* seqptr's */
168 * An announcement packet.
170 struct pkt_id {
171 u_int32_t pi_mslot;
172 struct PageID pi_mpage; /* current page */
173 struct pgstate pi_ps;
174 /* seqptr's */
175 /* null-terminated site name */
178 struct pkt_preq {
179 struct PageID pp_page;
180 u_int32_t pp_low;
181 u_int32_t pp_high;
184 struct pkt_prep {
185 u_int32_t pp_n; /* size of pageid array */
186 /* pgstate's follow */
189 static int
190 wb_id(const struct pkt_id *id, u_int len)
192 int i;
193 const char *cp;
194 const struct id_off *io;
195 char c;
196 int nid;
198 printf(" wb-id:");
199 if (len < sizeof(*id) || (u_char *)(id + 1) > snapend)
200 return (-1);
201 len -= sizeof(*id);
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) {
216 putchar('"');
217 (void)fn_print((u_char *)cp, (u_char *)cp + len);
218 putchar('"');
221 c = '<';
222 for (i = 0; i < nid && (u_char *)(io + 1) <= snapend; ++io, ++i) {
223 printf("%c%s:%u",
224 c, ipaddr_string(&io->id), EXTRACT_32BITS(&io->off));
225 c = ',';
227 if (i >= nid) {
228 printf(">");
229 return (0);
231 return (-1);
234 static int
235 wb_rreq(const struct pkt_rreq *rreq, u_int len)
237 printf(" wb-rreq:");
238 if (len < sizeof(*rreq) || (u_char *)(rreq + 1) > snapend)
239 return (-1);
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));
247 return (0);
250 static int
251 wb_preq(const struct pkt_preq *preq, u_int len)
253 printf(" wb-preq:");
254 if (len < sizeof(*preq) || (u_char *)(preq + 1) > snapend)
255 return (-1);
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));
261 return (0);
264 static int
265 wb_prep(const struct pkt_prep *prep, u_int len)
267 int n;
268 const struct pgstate *ps;
269 const u_char *ep = snapend;
271 printf(" wb-prep:");
272 if (len < sizeof(*prep)) {
273 return (-1);
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;
279 char c = '<';
281 printf(" %u/%s:%u",
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));
289 c = ',';
291 printf(">");
292 ps = (struct pgstate *)io;
294 return ((u_char *)ps <= ep? 0 : -1);
298 const char *dopstr[] = {
299 "dop-0!",
300 "dop-1!",
301 "RECT",
302 "LINE",
303 "ML",
304 "DEL",
305 "XFORM",
306 "ELL",
307 "CHAR",
308 "STR",
309 "NOP",
310 "PSCODE",
311 "PSCOMP",
312 "REF",
313 "SKIP",
314 "HOLE",
317 static int
318 wb_dops(const struct dophdr *dh, u_int32_t ss, u_int32_t es)
320 printf(" <");
321 for ( ; ss <= es; ++ss) {
322 register int t = dh->dh_type;
324 if (t > DT_MAXTYPE)
325 printf(" dop-%d!", t);
326 else {
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) {
332 printf("[|]");
333 if (ts < ss)
334 return (0);
336 ss = ts;
339 dh = DOP_NEXT(dh);
340 if ((u_char *)dh > snapend) {
341 printf("[|wb]");
342 break;
345 printf(" >");
346 return (0);
349 static int
350 wb_rrep(const struct pkt_rrep *rrep, u_int len)
352 const struct pkt_dop *dop = &rrep->pr_dop;
354 printf(" wb-rrep:");
355 if (len < sizeof(*rrep) || (u_char *)(rrep + 1) > snapend)
356 return (-1);
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));
366 if (vflag)
367 return (wb_dops((const struct dophdr *)(dop + 1),
368 EXTRACT_32BITS(&dop->pd_sseq),
369 EXTRACT_32BITS(&dop->pd_eseq)));
370 return (0);
373 static int
374 wb_drawop(const struct pkt_dop *dop, u_int len)
376 printf(" wb-dop:");
377 if (len < sizeof(*dop) || (u_char *)(dop + 1) > snapend)
378 return (-1);
379 len -= sizeof(*dop);
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));
387 if (vflag)
388 return (wb_dops((const struct dophdr *)(dop + 1),
389 EXTRACT_32BITS(&dop->pd_sseq),
390 EXTRACT_32BITS(&dop->pd_eseq)));
391 return (0);
395 * Print whiteboard multicast packets.
397 void
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) {
404 printf("[|wb]");
405 return;
407 len -= sizeof(*ph);
409 if (ph->ph_flags)
410 printf("*");
411 switch (ph->ph_type) {
413 case PT_KILL:
414 printf(" wb-kill");
415 return;
417 case PT_ID:
418 if (wb_id((struct pkt_id *)(ph + 1), len) >= 0)
419 return;
420 break;
422 case PT_RREQ:
423 if (wb_rreq((struct pkt_rreq *)(ph + 1), len) >= 0)
424 return;
425 break;
427 case PT_RREP:
428 if (wb_rrep((struct pkt_rrep *)(ph + 1), len) >= 0)
429 return;
430 break;
432 case PT_DRAWOP:
433 if (wb_drawop((struct pkt_dop *)(ph + 1), len) >= 0)
434 return;
435 break;
437 case PT_PREQ:
438 if (wb_preq((struct pkt_preq *)(ph + 1), len) >= 0)
439 return;
440 break;
442 case PT_PREP:
443 if (wb_prep((struct pkt_prep *)(ph + 1), len) >= 0)
444 return;
445 break;
447 default:
448 printf(" wb-%d!", ph->ph_type);
449 return;