home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / tcpdumpb.zip / print-wb.c < prev    next >
C/C++ Source or Header  |  1996-07-15  |  10KB  |  434 lines

  1. /*
  2.  * Copyright (c) 1993, 1994, 1995, 1996
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  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
  16.  * written permission.
  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.
  20.  */
  21.  
  22. #ifndef lint
  23. static char rcsid[] =
  24.     "@(#) $Header: print-wb.c,v 1.20 96/07/14 19:39:05 leres Exp $ (LBL)";
  25. #endif
  26.  
  27. #include <sys/types.h>
  28. #include <sys/time.h>
  29.  
  30. #include <netinet/in.h>
  31.  
  32. #include <stdio.h>
  33.  
  34. #include "interface.h"
  35. #include "addrtoname.h"
  36.  
  37. /* XXX need to add byte-swapping macros! */
  38.  
  39. /*
  40.  * Largest packet size.  Everything should fit within this space.
  41.  * For instance, multiline objects are sent piecewise.
  42.  */
  43. #define MAXFRAMESIZE 1024
  44.  
  45. /*
  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.
  48.  */
  49. #define DOP_ALIGN 4
  50. #define DOP_ROUNDUP(x)    ((((int)(x)) + (DOP_ALIGN - 1)) & ~(DOP_ALIGN - 1))
  51. #define DOP_NEXT(d)\
  52.     ((struct dophdr*)((u_char *)(d) + \
  53.               DOP_ROUNDUP(ntohs((d)->dh_len) + sizeof(*(d)))))
  54.  
  55. /*
  56.  * Format of the whiteboard packet header.
  57.  * The transport level header.
  58.  */
  59. struct pkt_hdr {
  60.     u_int32_t ph_src;        /* site id of source */
  61.     u_int32_t ph_ts;        /* time stamp (for skew computation) */
  62.     u_short ph_version;    /* version number */
  63.     u_char ph_type;        /* message type */
  64.     u_char ph_flags;    /* message flags */
  65. };
  66.  
  67. /* Packet types */
  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 */
  75.  
  76. /* flags */
  77. #define PF_USER        0x01    /* hint that packet has interactive data */
  78. #define PF_VIS        0x02    /* only visible ops wanted */
  79.  
  80. struct PageID {
  81.     u_int32_t p_sid;        /* session id of initiator */
  82.     u_int32_t p_uid;        /* page number */
  83. };
  84.  
  85. struct dophdr {
  86.     u_int32_t  dh_ts;        /* sender's timestamp */
  87.     u_short    dh_len;        /* body length */
  88.     u_char    dh_flags;
  89.     u_char    dh_type;    /* body type */
  90.     /* body follows */
  91. };
  92. /*
  93.  * Drawing op sub-types.
  94.  */
  95. #define DT_RECT         2
  96. #define DT_LINE         3
  97. #define DT_ML           4
  98. #define DT_DEL          5
  99. #define DT_XFORM        6
  100. #define DT_ELL          7
  101. #define DT_CHAR         8
  102. #define DT_STR          9
  103. #define DT_NOP          10
  104. #define DT_PSCODE       11
  105. #define DT_PSCOMP       12
  106. #define DT_REF          13
  107. #define DT_SKIP         14
  108. #define DT_HOLE         15
  109. #define DT_MAXTYPE      15
  110.  
  111. /*
  112.  * A drawing operation.
  113.  */
  114. struct pkt_dop {
  115.     struct PageID pd_page;    /* page that operations apply to */
  116.     u_int32_t    pd_sseq;    /* start sequence number */
  117.     u_int32_t    pd_eseq;    /* end sequence number */
  118.     /* drawing ops follow */
  119. };
  120.  
  121. /*
  122.  * A repair request.
  123.  */
  124. struct pkt_rreq {
  125.         u_int32_t pr_id;           /* source id of drawops to be repaired */
  126.         struct PageID pr_page;           /* page of drawops */
  127.         u_int32_t pr_sseq;         /* start seqno */
  128.         u_int32_t pr_eseq;         /* end seqno*/
  129. };
  130.  
  131. /*
  132.  * A repair reply.
  133.  */
  134. struct pkt_rrep {
  135.     u_int32_t pr_id;    /* original site id of ops  */
  136.     struct pkt_dop pr_dop;
  137.     /* drawing ops follow */
  138. };
  139.  
  140. struct id_off {
  141.         u_int32_t id;
  142.         u_int32_t off;
  143. };
  144.  
  145. struct pgstate {
  146.     u_int32_t slot;
  147.     struct PageID page;
  148.     u_short nid;
  149.     u_short rsvd;
  150.         /* seqptr's */
  151. };
  152.  
  153. /*
  154.  * An announcement packet.
  155.  */
  156. struct pkt_id {
  157.     u_int32_t pi_mslot;
  158.         struct PageID    pi_mpage;        /* current page */
  159.     struct pgstate pi_ps;
  160.         /* seqptr's */
  161.         /* null-terminated site name */
  162. };
  163.  
  164. struct pkt_preq {
  165.         struct PageID  pp_page;
  166.         u_int32_t  pp_low;
  167.         u_int32_t  pp_high;
  168. };
  169.  
  170. struct pkt_prep {
  171.         u_int32_t  pp_n;           /* size of pageid array */
  172.         /* pgstate's follow */
  173. };
  174.  
  175. static int
  176. wb_id(const struct pkt_id *id, u_int len)
  177. {
  178.     int i;
  179.     const char *cp;
  180.     const struct id_off *io;
  181.     char c;
  182.     int nid;
  183.  
  184.     printf(" wb-id:");
  185.     len -= sizeof(*id);
  186.     if (len < 0 || (u_char *)(id + 1) > snapend)
  187.         return (-1);
  188.  
  189.     printf(" %u/%s:%u (max %u/%s:%u) ",
  190.            (u_int32_t)ntohl(id->pi_ps.slot),
  191.            ipaddr_string(&id->pi_ps.page.p_sid),
  192.            (u_int32_t)ntohl(id->pi_ps.page.p_uid),
  193.            (u_int32_t)ntohl(id->pi_mslot),
  194.            ipaddr_string(&id->pi_mpage.p_sid),
  195.            (u_int32_t)ntohl(id->pi_mpage.p_uid));
  196.  
  197.     nid = ntohs(id->pi_ps.nid);
  198.     len -= sizeof(*io) * nid;
  199.     io = (struct id_off *)(id + 1);
  200.     cp = (char *)(io + nid);
  201.     if ((u_char *)cp + len <= snapend) {
  202.         putchar('"');
  203.         (void)fn_print((u_char *)cp, (u_char *)cp + len);
  204.         putchar('"');
  205.     }
  206.  
  207.     c = '<';
  208.     for (i = 0; i < nid && (u_char*)io < snapend; ++io, ++i) {
  209.         printf("%c%s:%u",
  210.             c, ipaddr_string(&io->id), (u_int32_t)ntohl(io->off));
  211.         c = ',';
  212.     }
  213.     if (i >= nid) {
  214.         printf(">");
  215.         return (0);
  216.     }
  217.     return (-1);
  218. }
  219.  
  220. static int
  221. wb_rreq(const struct pkt_rreq *rreq, u_int len)
  222. {
  223.     printf(" wb-rreq:");
  224.     if (len < sizeof(*rreq) || (u_char *)(rreq + 1) > snapend)
  225.         return (-1);
  226.  
  227.     printf(" please repair %s %s:%u<%u:%u>",
  228.            ipaddr_string(&rreq->pr_id),
  229.            ipaddr_string(&rreq->pr_page.p_sid),
  230.            (u_int32_t)ntohl(rreq->pr_page.p_uid),
  231.            (u_int32_t)ntohl(rreq->pr_sseq),
  232.            (u_int32_t)ntohl(rreq->pr_eseq));
  233.     return (0);
  234. }
  235.  
  236. static int
  237. wb_preq(const struct pkt_preq *preq, u_int len)
  238. {
  239.     printf(" wb-preq:");
  240.     if (len < sizeof(*preq) || (u_char *)(preq + 1) > snapend)
  241.         return (-1);
  242.  
  243.     printf(" need %u/%s:%u",
  244.            (u_int32_t)ntohl(preq->pp_low),
  245.            ipaddr_string(&preq->pp_page.p_sid),
  246.            (u_int32_t)ntohl(preq->pp_page.p_uid));
  247.     return (0);
  248. }
  249.  
  250. static int
  251. wb_prep(const struct pkt_prep *prep, u_int len)
  252. {
  253.     int n;
  254.     const struct pgstate* ps;
  255.     const u_char* ep = snapend;
  256.  
  257.     printf(" wb-prep:");
  258.     if (len < sizeof(*prep)) {
  259.         return (-1);
  260.     }
  261.     n = ntohl(prep->pp_n);
  262.     ps = (const struct pgstate*)(prep + 1);
  263.     while (--n >= 0 && (u_char*)ps < ep) {
  264.         const struct id_off *io, *ie;
  265.         char c = '<';
  266.  
  267.         printf(" %u/%s:%u",
  268.             (u_int32_t)ntohl(ps->slot),
  269.             ipaddr_string(&ps->page.p_sid),
  270.             (u_int32_t)ntohl(ps->page.p_uid));
  271.         io = (struct id_off*)(ps + 1);
  272.         for (ie = io + ps->nid; io < ie && (u_char*)io < ep; ++io) {
  273.             printf("%c%s:%u", c, ipaddr_string(&io->id),
  274.                 (u_int32_t)ntohl(io->off));
  275.             c = ',';
  276.         }
  277.         printf(">");
  278.         ps = (struct pgstate*)io;
  279.     }
  280.     return ((u_char*)ps <= ep? 0 : -1);
  281. }
  282.  
  283.  
  284. char *dopstr[] = {
  285.     "dop-0!",
  286.     "dop-1!",
  287.     "RECT",
  288.     "LINE",
  289.     "ML",
  290.     "DEL",
  291.     "XFORM",
  292.     "ELL",
  293.     "CHAR",
  294.     "STR",
  295.     "NOP",
  296.     "PSCODE",
  297.     "PSCOMP",
  298.     "REF",
  299.     "SKIP",
  300.     "HOLE",
  301. };
  302.  
  303. static int
  304. wb_dops(const struct dophdr *dh, u_int32_t ss, u_int32_t es)
  305. {
  306.     printf(" <");
  307.     for ( ; ss <= es; ++ss) {
  308.         register int t = dh->dh_type;
  309.  
  310.         if (t > DT_MAXTYPE)
  311.             printf(" dop-%d!", t);
  312.         else {
  313.             printf(" %s", dopstr[t]);
  314.             if (t == DT_SKIP || t == DT_HOLE) {
  315.                 int ts = ntohl(dh->dh_ts);
  316.                 printf("%d", ts - ss + 1);
  317.                 if (ss > ts || ts > es) {
  318.                     printf("[|]");
  319.                     if (ts < ss)
  320.                         return (0);
  321.                 }
  322.                 ss = ts;
  323.             }
  324.         }
  325.         dh = DOP_NEXT(dh);
  326.         if ((u_char*)dh >= snapend) {
  327.             printf("[|wb]");
  328.             break;
  329.         }
  330.     }
  331.     printf(" >");
  332.     return (0);
  333. }
  334.  
  335. static int
  336. wb_rrep(const struct pkt_rrep *rrep, u_int len)
  337. {
  338.     const struct pkt_dop *dop = &rrep->pr_dop;
  339.  
  340.     printf(" wb-rrep:");
  341.     len -= sizeof(*rrep);
  342.     if (len < 0 || (u_char *)(rrep + 1) > snapend)
  343.         return (-1);
  344.  
  345.     printf(" for %s %s:%u<%u:%u>",
  346.         ipaddr_string(&rrep->pr_id),
  347.         ipaddr_string(&dop->pd_page.p_sid),
  348.         (u_int32_t)ntohl(dop->pd_page.p_uid),
  349.         (u_int32_t)ntohl(dop->pd_sseq),
  350.         (u_int32_t)ntohl(dop->pd_eseq));
  351.  
  352.     if (vflag)
  353.         return (wb_dops((const struct dophdr*)(dop + 1),
  354.             ntohl(dop->pd_sseq), ntohl(dop->pd_eseq)));
  355.     return (0);
  356. }
  357.  
  358. static int
  359. wb_drawop(const struct pkt_dop *dop, u_int len)
  360. {
  361.     printf(" wb-dop:");
  362.     len -= sizeof(*dop);
  363.     if (len < 0 || (u_char *)(dop + 1) > snapend)
  364.         return (-1);
  365.  
  366.     printf(" %s:%u<%u:%u>",
  367.         ipaddr_string(&dop->pd_page.p_sid),
  368.         (u_int32_t)ntohl(dop->pd_page.p_uid),
  369.         (u_int32_t)ntohl(dop->pd_sseq),
  370.         (u_int32_t)ntohl(dop->pd_eseq));
  371.  
  372.     if (vflag)
  373.         return (wb_dops((const struct dophdr*)(dop + 1),
  374.                 ntohl(dop->pd_sseq), ntohl(dop->pd_eseq)));
  375.     return (0);
  376. }
  377.  
  378. /*
  379.  * Print whiteboard multicast packets.
  380.  */
  381. void
  382. wb_print(register const void *hdr, register u_int len)
  383. {
  384.     register const struct pkt_hdr* ph;
  385.  
  386.     ph = (const struct pkt_hdr*)hdr;
  387.     len -= sizeof(*ph);
  388.     if (len < 0 || (u_char *)(ph + 1) <= snapend) {
  389.         if (ph->ph_flags)
  390.             printf("*");
  391.         switch (ph->ph_type) {
  392.  
  393.         case PT_KILL:
  394.             printf(" wb-kill");
  395.             return;
  396.  
  397.         case PT_ID:
  398.             if (wb_id((struct pkt_id *)(ph + 1), len) >= 0)
  399.                 return;
  400.             break;
  401.  
  402.         case PT_RREQ:
  403.             if (wb_rreq((struct pkt_rreq *)(ph + 1), len) >= 0)
  404.                 return;
  405.             break;
  406.  
  407.         case PT_RREP:
  408.             if (wb_rrep((struct pkt_rrep *)(ph + 1), len) >= 0)
  409.                 return;
  410.             break;
  411.  
  412.         case PT_DRAWOP:
  413.             if (wb_drawop((struct pkt_dop *)(ph + 1), len) >= 0)
  414.                 return;
  415.             break;
  416.  
  417.         case PT_PREQ:
  418.             if (wb_preq((struct pkt_preq *)(ph + 1), len) >= 0)
  419.                 return;
  420.             break;
  421.  
  422.         case PT_PREP:
  423.             if (wb_prep((struct pkt_prep *)(ph + 1), len) >= 0)
  424.                 return;
  425.             break;
  426.  
  427.         default:
  428.             printf(" wb-%d!", ph->ph_type);
  429.             return;
  430.         }
  431.     }
  432.     printf("[|wb]");
  433. }
  434.