"Fossies" - the Fresh Open Source Software Archive

Member "tcpdump-4.99.1/./print-zephyr.c" (7 Jun 2021, 8225 Bytes) of package /linux/misc/tcpdump-4.99.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "print-zephyr.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 4.99.0_vs_4.99.1.

    1 /*
    2  * Decode and print Zephyr packets.
    3  *
    4  *  https://web.mit.edu/zephyr/doc/protocol
    5  *
    6  * Copyright (c) 2001 Nickolai Zeldovich <kolya@MIT.EDU>
    7  * All rights reserved.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that: (1) source code
   11  * distributions retain the above copyright notice and this paragraph
   12  * in its entirety, and (2) distributions including binary code include
   13  * the above copyright notice and this paragraph in its entirety in
   14  * the documentation or other materials provided with the distribution.
   15  * The name of the author(s) may not be used to endorse or promote
   16  * products derived from this software without specific prior written
   17  * permission.  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY
   18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE
   19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   20  * PURPOSE.
   21  */
   22 
   23 /* \summary: Zephyr printer */
   24 
   25 #ifdef HAVE_CONFIG_H
   26 #include <config.h>
   27 #endif
   28 
   29 #include "netdissect-stdinc.h"
   30 
   31 #include <stdio.h>
   32 #include <string.h>
   33 #include <stdlib.h>
   34 
   35 #include "netdissect-ctype.h"
   36 
   37 #include "netdissect.h"
   38 #include "extract.h"
   39 
   40 struct z_packet {
   41     const char *version;
   42     int numfields;
   43     int kind;
   44     const char *uid;
   45     int port;
   46     int auth;
   47     int authlen;
   48     const char *authdata;
   49     const char *class;
   50     const char *inst;
   51     const char *opcode;
   52     const char *sender;
   53     const char *recipient;
   54     const char *format;
   55     int cksum;
   56     int multi;
   57     const char *multi_uid;
   58     /* Other fields follow here.. */
   59 };
   60 
   61 enum z_packet_type {
   62     Z_PACKET_UNSAFE = 0,
   63     Z_PACKET_UNACKED,
   64     Z_PACKET_ACKED,
   65     Z_PACKET_HMACK,
   66     Z_PACKET_HMCTL,
   67     Z_PACKET_SERVACK,
   68     Z_PACKET_SERVNAK,
   69     Z_PACKET_CLIENTACK,
   70     Z_PACKET_STAT
   71 };
   72 
   73 static const struct tok z_types[] = {
   74     { Z_PACKET_UNSAFE,      "unsafe" },
   75     { Z_PACKET_UNACKED,     "unacked" },
   76     { Z_PACKET_ACKED,       "acked" },
   77     { Z_PACKET_HMACK,       "hm-ack" },
   78     { Z_PACKET_HMCTL,       "hm-ctl" },
   79     { Z_PACKET_SERVACK,     "serv-ack" },
   80     { Z_PACKET_SERVNAK,     "serv-nak" },
   81     { Z_PACKET_CLIENTACK,   "client-ack" },
   82     { Z_PACKET_STAT,        "stat" },
   83     { 0,            NULL }
   84 };
   85 
   86 static char z_buf[256];
   87 
   88 static const char *
   89 parse_field(netdissect_options *ndo, const char **pptr, int *len)
   90 {
   91     const char *s;
   92 
   93     /* Start of string */
   94     s = *pptr;
   95     /* Scan for the NUL terminator */
   96     for (;;) {
   97     if (*len == 0) {
   98         /* Ran out of packet data without finding it */
   99         return NULL;
  100     }
  101     if (GET_U_1(*pptr) == '\0') {
  102         /* Found it */
  103         break;
  104     }
  105     /* Keep scanning */
  106     (*pptr)++;
  107     (*len)--;
  108     }
  109     /* Skip the NUL terminator */
  110     (*pptr)++;
  111     (*len)--;
  112     return s;
  113 }
  114 
  115 static const char *
  116 z_triple(const char *class, const char *inst, const char *recipient)
  117 {
  118     if (!*recipient)
  119     recipient = "*";
  120     snprintf(z_buf, sizeof(z_buf), "<%s,%s,%s>", class, inst, recipient);
  121     z_buf[sizeof(z_buf)-1] = '\0';
  122     return z_buf;
  123 }
  124 
  125 static const char *
  126 str_to_lower(const char *string)
  127 {
  128     char *zb_string;
  129 
  130     strncpy(z_buf, string, sizeof(z_buf));
  131     z_buf[sizeof(z_buf)-1] = '\0';
  132 
  133     zb_string = z_buf;
  134     while (*zb_string) {
  135     *zb_string = ND_ASCII_TOLOWER(*zb_string);
  136     zb_string++;
  137     }
  138 
  139     return z_buf;
  140 }
  141 
  142 void
  143 zephyr_print(netdissect_options *ndo, const u_char *cp, u_int length)
  144 {
  145     struct z_packet z = {
  146         NULL,   /* version */
  147         0,  /* numfields */
  148         0,  /* kind */
  149         NULL,   /* uid */
  150         0,  /* port */
  151         0,  /* auth */
  152         0,  /* authlen */
  153         NULL,   /* authdata */
  154         NULL,   /* class */
  155         NULL,   /* inst */
  156         NULL,   /* opcode */
  157         NULL,   /* sender */
  158         NULL,   /* recipient */
  159         NULL,   /* format */
  160         0,  /* cksum */
  161         0,  /* multi */
  162         NULL    /* multi_uid */
  163     };
  164     const char *parse = (const char *) cp;
  165     int parselen = length;
  166     const char *s;
  167     int lose = 0;
  168 
  169     ndo->ndo_protocol = "zephyr";
  170     /* squelch compiler warnings */
  171 
  172 #define PARSE_STRING                        \
  173     s = parse_field(ndo, &parse, &parselen);    \
  174     if (!s) lose = 1;
  175 
  176 #define PARSE_FIELD_INT(field)          \
  177     PARSE_STRING                \
  178     if (!lose) field = strtol(s, 0, 16);
  179 
  180 #define PARSE_FIELD_STR(field)          \
  181     PARSE_STRING                \
  182     if (!lose) field = s;
  183 
  184     PARSE_FIELD_STR(z.version);
  185     if (lose)
  186         goto invalid;
  187 
  188     if (strncmp(z.version, "ZEPH", 4))
  189     return;
  190 
  191     PARSE_FIELD_INT(z.numfields);
  192     PARSE_FIELD_INT(z.kind);
  193     PARSE_FIELD_STR(z.uid);
  194     PARSE_FIELD_INT(z.port);
  195     PARSE_FIELD_INT(z.auth);
  196     PARSE_FIELD_INT(z.authlen);
  197     PARSE_FIELD_STR(z.authdata);
  198     PARSE_FIELD_STR(z.class);
  199     PARSE_FIELD_STR(z.inst);
  200     PARSE_FIELD_STR(z.opcode);
  201     PARSE_FIELD_STR(z.sender);
  202     PARSE_FIELD_STR(z.recipient);
  203     PARSE_FIELD_STR(z.format);
  204     PARSE_FIELD_INT(z.cksum);
  205     PARSE_FIELD_INT(z.multi);
  206     PARSE_FIELD_STR(z.multi_uid);
  207 
  208     if (lose)
  209         goto invalid;
  210 
  211     ND_PRINT(" zephyr");
  212     if (strncmp(z.version+4, "0.2", 3)) {
  213     ND_PRINT(" v%s", z.version+4);
  214     return;
  215     }
  216 
  217     ND_PRINT(" %s", tok2str(z_types, "type %d", z.kind));
  218     if (z.kind == Z_PACKET_SERVACK) {
  219     /* Initialization to silence warnings */
  220     const char *ackdata = NULL;
  221     PARSE_FIELD_STR(ackdata);
  222     if (!lose && strcmp(ackdata, "SENT"))
  223         ND_PRINT("/%s", str_to_lower(ackdata));
  224     }
  225     if (*z.sender) ND_PRINT(" %s", z.sender);
  226 
  227     if (!strcmp(z.class, "USER_LOCATE")) {
  228     if (!strcmp(z.opcode, "USER_HIDE"))
  229         ND_PRINT(" hide");
  230     else if (!strcmp(z.opcode, "USER_UNHIDE"))
  231         ND_PRINT(" unhide");
  232     else
  233         ND_PRINT(" locate %s", z.inst);
  234     return;
  235     }
  236 
  237     if (!strcmp(z.class, "ZEPHYR_ADMIN")) {
  238     ND_PRINT(" zephyr-admin %s", str_to_lower(z.opcode));
  239     return;
  240     }
  241 
  242     if (!strcmp(z.class, "ZEPHYR_CTL")) {
  243     if (!strcmp(z.inst, "CLIENT")) {
  244         if (!strcmp(z.opcode, "SUBSCRIBE") ||
  245         !strcmp(z.opcode, "SUBSCRIBE_NODEFS") ||
  246         !strcmp(z.opcode, "UNSUBSCRIBE")) {
  247 
  248         ND_PRINT(" %ssub%s", strcmp(z.opcode, "SUBSCRIBE") ? "un" : "",
  249                    strcmp(z.opcode, "SUBSCRIBE_NODEFS") ? "" :
  250                                    "-nodefs");
  251         if (z.kind != Z_PACKET_SERVACK) {
  252             /* Initialization to silence warnings */
  253             const char *c = NULL, *i = NULL, *r = NULL;
  254             PARSE_FIELD_STR(c);
  255             PARSE_FIELD_STR(i);
  256             PARSE_FIELD_STR(r);
  257             if (!lose) ND_PRINT(" %s", z_triple(c, i, r));
  258         }
  259         return;
  260         }
  261 
  262         if (!strcmp(z.opcode, "GIMME")) {
  263         ND_PRINT(" ret");
  264         return;
  265         }
  266 
  267         if (!strcmp(z.opcode, "GIMMEDEFS")) {
  268         ND_PRINT(" gimme-defs");
  269         return;
  270         }
  271 
  272         if (!strcmp(z.opcode, "CLEARSUB")) {
  273         ND_PRINT(" clear-subs");
  274         return;
  275         }
  276 
  277         ND_PRINT(" %s", str_to_lower(z.opcode));
  278         return;
  279     }
  280 
  281     if (!strcmp(z.inst, "HM")) {
  282         ND_PRINT(" %s", str_to_lower(z.opcode));
  283         return;
  284     }
  285 
  286     if (!strcmp(z.inst, "REALM")) {
  287         if (!strcmp(z.opcode, "ADD_SUBSCRIBE"))
  288         ND_PRINT(" realm add-subs");
  289         if (!strcmp(z.opcode, "REQ_SUBSCRIBE"))
  290         ND_PRINT(" realm req-subs");
  291         if (!strcmp(z.opcode, "RLM_SUBSCRIBE"))
  292         ND_PRINT(" realm rlm-sub");
  293         if (!strcmp(z.opcode, "RLM_UNSUBSCRIBE"))
  294         ND_PRINT(" realm rlm-unsub");
  295         return;
  296     }
  297     }
  298 
  299     if (!strcmp(z.class, "HM_CTL")) {
  300     ND_PRINT(" hm_ctl %s", str_to_lower(z.inst));
  301     ND_PRINT(" %s", str_to_lower(z.opcode));
  302     return;
  303     }
  304 
  305     if (!strcmp(z.class, "HM_STAT")) {
  306     if (!strcmp(z.inst, "HMST_CLIENT") && !strcmp(z.opcode, "GIMMESTATS")) {
  307         ND_PRINT(" get-client-stats");
  308         return;
  309     }
  310     }
  311 
  312     if (!strcmp(z.class, "WG_CTL")) {
  313     ND_PRINT(" wg_ctl %s", str_to_lower(z.inst));
  314     ND_PRINT(" %s", str_to_lower(z.opcode));
  315     return;
  316     }
  317 
  318     if (!strcmp(z.class, "LOGIN")) {
  319     if (!strcmp(z.opcode, "USER_FLUSH")) {
  320         ND_PRINT(" flush_locs");
  321         return;
  322     }
  323 
  324     if (!strcmp(z.opcode, "NONE") ||
  325         !strcmp(z.opcode, "OPSTAFF") ||
  326         !strcmp(z.opcode, "REALM-VISIBLE") ||
  327         !strcmp(z.opcode, "REALM-ANNOUNCED") ||
  328         !strcmp(z.opcode, "NET-VISIBLE") ||
  329         !strcmp(z.opcode, "NET-ANNOUNCED")) {
  330         ND_PRINT(" set-exposure %s", str_to_lower(z.opcode));
  331         return;
  332     }
  333     }
  334 
  335     if (!*z.recipient)
  336     z.recipient = "*";
  337 
  338     ND_PRINT(" to %s", z_triple(z.class, z.inst, z.recipient));
  339     if (*z.opcode)
  340     ND_PRINT(" op %s", z.opcode);
  341     return;
  342 
  343 invalid:
  344     nd_print_invalid(ndo);
  345 }