print-zephyr.c revision e66460324c0c1d5b6f767afeb6f3d201094156d3
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Decode and print Zephyr packets.
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *	http://web.mit.edu/zephyr/doc/protocol
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (c) 2001 Nickolai Zeldovich <kolya@MIT.EDU>
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * All rights reserved.
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Redistribution and use in source and binary forms, with or without
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * modification, are permitted provided that: (1) source code
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * distributions retain the above copyright notice and this paragraph
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * in its entirety, and (2) distributions including binary code include
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the above copyright notice and this paragraph in its entirety in
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the documentation or other materials provided with the distribution.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The name of the author(s) may not be used to endorse or promote
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * products derived from this software without specific prior written
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * permission.  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * PURPOSE.
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef lint
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static const char rcsid[] _U_ =
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "@(#) $Header: /tcpdump/master/tcpdump/print-zephyr.c,v 1.8.2.1 2005/04/21 06:51:24 guy Exp $";
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_CONFIG_H
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "config.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <tcpdump-stdinc.h>
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h>
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h>
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h>
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "interface.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct z_packet {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char *version;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int numfields;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int kind;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char *uid;
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int port;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int auth;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int authlen;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char *authdata;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char *class;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char *inst;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char *opcode;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char *sender;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char *recipient;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char *format;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int cksum;
56010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    int multi;
57010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    char *multi_uid;
58010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    /* Other fields follow here.. */
59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)};
60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
61010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)enum z_packet_type {
62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    Z_PACKET_UNSAFE = 0,
63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    Z_PACKET_UNACKED,
64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    Z_PACKET_ACKED,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Z_PACKET_HMACK,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Z_PACKET_HMCTL,
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Z_PACKET_SERVACK,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Z_PACKET_SERVNAK,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Z_PACKET_CLIENTACK,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Z_PACKET_STAT
71e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch};
72e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
73e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochstatic struct tok z_types[] = {
74e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    { Z_PACKET_UNSAFE,		"unsafe" },
75e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    { Z_PACKET_UNACKED,		"unacked" },
76e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    { Z_PACKET_ACKED,		"acked" },
77e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    { Z_PACKET_HMACK,		"hm-ack" },
78e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    { Z_PACKET_HMCTL,		"hm-ctl" },
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { Z_PACKET_SERVACK,		"serv-ack" },
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { Z_PACKET_SERVNAK,		"serv-nak" },
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { Z_PACKET_CLIENTACK,	"client-ack" },
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { Z_PACKET_STAT,		"stat" }
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)char z_buf[256];
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static char *
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)parse_field(char **pptr, int *len)
89e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch{
90e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    char *s;
91e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
92e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    if (*len <= 0 || !pptr || !*pptr)
93e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch	return NULL;
94e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    if (*pptr > (char *) snapend)
95e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch	return NULL;
96e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
97010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    s = *pptr;
98010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    while (*pptr <= (char *) snapend && *len >= 0 && **pptr) {
99e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch	(*pptr)++;
100e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch	(*len)--;
101e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    }
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    (*pptr)++;
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    (*len)--;
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (*len < 0 || *pptr > (char *) snapend)
105e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch	return NULL;
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return s;
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static const char *
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)z_triple(char *class, char *inst, const char *recipient)
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles){
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!*recipient)
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	recipient = "*";
114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    snprintf(z_buf, sizeof(z_buf), "<%s,%s,%s>", class, inst, recipient);
115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    z_buf[sizeof(z_buf)-1] = '\0';
116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return z_buf;
117e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static const char *
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)str_to_lower(char *string)
121e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch{
122e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    strncpy(z_buf, string, sizeof(z_buf));
123e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    z_buf[sizeof(z_buf)-1] = '\0';
124e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
125c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    string = z_buf;
126e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    while (*string) {
127e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch	*string = tolower((unsigned char)(*string));
128c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch	string++;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return z_buf;
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)zephyr_print(const u_char *cp, int length)
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles){
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    struct z_packet z;
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    char *parse = (char *) cp;
139e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    int parselen = length;
140e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    char *s;
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int lose = 0;
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define PARSE_STRING				\
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	s = parse_field(&parse, &parselen);	\
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!s) lose = 1;
146e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
147e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#define PARSE_FIELD_INT(field)			\
148c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch	PARSE_STRING				\
149c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch	if (!lose) field = strtol(s, 0, 16);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define PARSE_FIELD_STR(field)			\
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	PARSE_STRING				\
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	if (!lose) field = s;
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PARSE_FIELD_STR(z.version);
15658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (lose) return;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (strncmp(z.version, "ZEPH", 4))
158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)	return;
159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PARSE_FIELD_INT(z.numfields);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PARSE_FIELD_INT(z.kind);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PARSE_FIELD_STR(z.uid);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PARSE_FIELD_INT(z.port);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PARSE_FIELD_INT(z.auth);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PARSE_FIELD_INT(z.authlen);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PARSE_FIELD_STR(z.authdata);
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PARSE_FIELD_STR(z.class);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PARSE_FIELD_STR(z.inst);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PARSE_FIELD_STR(z.opcode);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PARSE_FIELD_STR(z.sender);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PARSE_FIELD_STR(z.recipient);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PARSE_FIELD_STR(z.format);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PARSE_FIELD_INT(z.cksum);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PARSE_FIELD_INT(z.multi);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PARSE_FIELD_STR(z.multi_uid);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (lose) {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf(" [|zephyr] (%d)", length);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf(" zephyr");
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (strncmp(z.version+4, "0.2", 3)) {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf(" v%s", z.version+4);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf(" %s", tok2str(z_types, "type %d", z.kind));
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (z.kind == Z_PACKET_SERVACK) {
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Initialization to silence warnings */
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	char *ackdata = NULL;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PARSE_FIELD_STR(ackdata);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!lose && strcmp(ackdata, "SENT"))
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    printf("/%s", str_to_lower(ackdata));
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
196c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    if (*z.sender) printf(" %s", z.sender);
197c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
198c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    if (!strcmp(z.class, "USER_LOCATE")) {
199c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch	if (!strcmp(z.opcode, "USER_HIDE"))
200c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch	    printf(" hide");
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else if (!strcmp(z.opcode, "USER_UNHIDE"))
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    printf(" unhide");
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    printf(" locate %s", z.inst);
205c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch	return;
206c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    }
207c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
208c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    if (!strcmp(z.class, "ZEPHYR_ADMIN")) {
209c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch	printf(" zephyr-admin %s", str_to_lower(z.opcode));
210c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch	return;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!strcmp(z.class, "ZEPHYR_CTL")) {
214c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch	if (!strcmp(z.inst, "CLIENT")) {
215c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch	    if (!strcmp(z.opcode, "SUBSCRIBE") ||
216c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch		!strcmp(z.opcode, "SUBSCRIBE_NODEFS") ||
217c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch		!strcmp(z.opcode, "UNSUBSCRIBE")) {
218c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf(" %ssub%s", strcmp(z.opcode, "SUBSCRIBE") ? "un" : "",
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   strcmp(z.opcode, "SUBSCRIBE_NODEFS") ? "" :
221c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch								   "-nodefs");
222c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch		if (z.kind != Z_PACKET_SERVACK) {
223c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch		    /* Initialization to silence warnings */
224c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch		    char *c = NULL, *i = NULL, *r = NULL;
225c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch		    PARSE_FIELD_STR(c);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    PARSE_FIELD_STR(i);
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    PARSE_FIELD_STR(r);
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (!lose) printf(" %s", z_triple(c, i, r));
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	    if (!strcmp(z.opcode, "GIMME")) {
234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)		printf(" ret");
235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)		return;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
237e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
238e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch	    if (!strcmp(z.opcode, "GIMMEDEFS")) {
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf(" gimme-defs");
240e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch		return;
241e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch	    }
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
243e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch	    if (!strcmp(z.opcode, "CLEARSUB")) {
244e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch		printf(" clear-subs");
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    printf(" %s", str_to_lower(z.opcode));
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!strcmp(z.inst, "HM")) {
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    printf(" %s", str_to_lower(z.opcode));
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!strcmp(z.inst, "REALM")) {
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (!strcmp(z.opcode, "ADD_SUBSCRIBE"))
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf(" realm add-subs");
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (!strcmp(z.opcode, "REQ_SUBSCRIBE"))
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf(" realm req-subs");
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (!strcmp(z.opcode, "RLM_SUBSCRIBE"))
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf(" realm rlm-sub");
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (!strcmp(z.opcode, "RLM_UNSUBSCRIBE"))
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf(" realm rlm-unsub");
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!strcmp(z.class, "HM_CTL")) {
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf(" hm_ctl %s", str_to_lower(z.inst));
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf(" %s", str_to_lower(z.opcode));
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!strcmp(z.class, "HM_STAT")) {
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!strcmp(z.inst, "HMST_CLIENT") && !strcmp(z.opcode, "GIMMESTATS")) {
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    printf(" get-client-stats");
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (!strcmp(z.class, "WG_CTL")) {
2847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch	printf(" wg_ctl %s", str_to_lower(z.inst));
2857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch	printf(" %s", str_to_lower(z.opcode));
286b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)	return;
287b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    }
288b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
289b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    if (!strcmp(z.class, "LOGIN")) {
2907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch	if (!strcmp(z.opcode, "USER_FLUSH")) {
291b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)	    printf(" flush_locs");
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
293effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch	}
294effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!strcmp(z.opcode, "NONE") ||
296effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch	    !strcmp(z.opcode, "OPSTAFF") ||
297effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch	    !strcmp(z.opcode, "REALM-VISIBLE") ||
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    !strcmp(z.opcode, "REALM-ANNOUNCED") ||
299effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch	    !strcmp(z.opcode, "NET-VISIBLE") ||
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    !strcmp(z.opcode, "NET-ANNOUNCED")) {
301e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch	    printf(" set-exposure %s", str_to_lower(z.opcode));
302e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch	    return;
303e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch	}
304e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    }
305e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
306e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    if (!*z.recipient)
307e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch	z.recipient = "*";
308e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
309e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    printf(" to %s", z_triple(z.class, z.inst, z.recipient));
310e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    if (*z.opcode)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf(" op %s", z.opcode);
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
314010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)