12949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
22949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Decode and print Zephyr packets.
32949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
42949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *	http://web.mit.edu/zephyr/doc/protocol
52949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
62949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Copyright (c) 2001 Nickolai Zeldovich <kolya@MIT.EDU>
72949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * All rights reserved.
82949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
92949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Redistribution and use in source and binary forms, with or without
102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * modification, are permitted provided that: (1) source code
112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * distributions retain the above copyright notice and this paragraph
122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * in its entirety, and (2) distributions including binary code include
132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * the above copyright notice and this paragraph in its entirety in
142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * the documentation or other materials provided with the distribution.
152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * The name of the author(s) may not be used to endorse or promote
162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * products derived from this software without specific prior written
172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * permission.  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY
182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE
192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * PURPOSE.
212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
23e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes/* \summary: Zephyr printer */
24e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef HAVE_CONFIG_H
262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "config.h"
272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
29e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes#include <netdissect-stdinc.h>
302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <stdio.h>
322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <string.h>
332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <stdlib.h>
342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
35e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes#include "netdissect.h"
362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstruct z_packet {
38e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    const char *version;
392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    int numfields;
402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    int kind;
41e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    const char *uid;
422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    int port;
432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    int auth;
442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    int authlen;
45e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    const char *authdata;
46e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    const char *class;
47e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    const char *inst;
48e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    const char *opcode;
49e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    const char *sender;
502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    const char *recipient;
51e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    const char *format;
522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    int cksum;
532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    int multi;
54e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    const char *multi_uid;
552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    /* Other fields follow here.. */
562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectenum z_packet_type {
592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    Z_PACKET_UNSAFE = 0,
602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    Z_PACKET_UNACKED,
612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    Z_PACKET_ACKED,
622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    Z_PACKET_HMACK,
632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    Z_PACKET_HMCTL,
642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    Z_PACKET_SERVACK,
652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    Z_PACKET_SERVNAK,
662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    Z_PACKET_CLIENTACK,
672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    Z_PACKET_STAT
682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7053f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok z_types[] = {
712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { Z_PACKET_UNSAFE,		"unsafe" },
722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { Z_PACKET_UNACKED,		"unacked" },
732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { Z_PACKET_ACKED,		"acked" },
742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { Z_PACKET_HMACK,		"hm-ack" },
752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { Z_PACKET_HMCTL,		"hm-ctl" },
762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { Z_PACKET_SERVACK,		"serv-ack" },
772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { Z_PACKET_SERVNAK,		"serv-nak" },
782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { Z_PACKET_CLIENTACK,	"client-ack" },
792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { Z_PACKET_STAT,		"stat" }
802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
82892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic char z_buf[256];
832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
84e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughesstatic const char *
85e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughesparse_field(netdissect_options *ndo, const char **pptr, int *len)
862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
87e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    const char *s;
882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if (*len <= 0 || !pptr || !*pptr)
902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return NULL;
91e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    if (*pptr > (const char *) ndo->ndo_snapend)
922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return NULL;
932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    s = *pptr;
95e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    while (*pptr <= (const char *) ndo->ndo_snapend && *len >= 0 && **pptr) {
962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	(*pptr)++;
972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	(*len)--;
982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    (*pptr)++;
1002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    (*len)--;
101e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    if (*len < 0 || *pptr > (const char *) ndo->ndo_snapend)
1022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return NULL;
1032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    return s;
1042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
1052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic const char *
107e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughesz_triple(const char *class, const char *inst, const char *recipient)
1082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
1092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if (!*recipient)
1102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	recipient = "*";
1112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    snprintf(z_buf, sizeof(z_buf), "<%s,%s,%s>", class, inst, recipient);
1122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    z_buf[sizeof(z_buf)-1] = '\0';
1132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    return z_buf;
1142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
1152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic const char *
117e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughesstr_to_lower(const char *string)
1182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
119e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    char *zb_string;
120e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
1212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    strncpy(z_buf, string, sizeof(z_buf));
1222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    z_buf[sizeof(z_buf)-1] = '\0';
1232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
124e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    zb_string = z_buf;
125e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    while (*zb_string) {
126e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	*zb_string = tolower((unsigned char)(*zb_string));
127e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	zb_string++;
1282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
1292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    return z_buf;
1312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
1322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectvoid
134892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hugheszephyr_print(netdissect_options *ndo, const u_char *cp, int length)
1352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
1362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    struct z_packet z;
137e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    const char *parse = (const char *) cp;
1382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    int parselen = length;
139e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    const char *s;
1402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    int lose = 0;
1412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
14253f17a9db278d33517d9888dd77848f554522a38JP Abgrall    /* squelch compiler warnings */
14353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
14453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    z.kind = 0;
14553f17a9db278d33517d9888dd77848f554522a38JP Abgrall    z.class = 0;
14653f17a9db278d33517d9888dd77848f554522a38JP Abgrall    z.inst = 0;
14753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    z.opcode = 0;
14853f17a9db278d33517d9888dd77848f554522a38JP Abgrall    z.sender = 0;
14953f17a9db278d33517d9888dd77848f554522a38JP Abgrall    z.recipient = 0;
15053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
1512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define PARSE_STRING				\
152892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	s = parse_field(ndo, &parse, &parselen);	\
1532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (!s) lose = 1;
1542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define PARSE_FIELD_INT(field)			\
1562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	PARSE_STRING				\
1572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (!lose) field = strtol(s, 0, 16);
1582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define PARSE_FIELD_STR(field)			\
1602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	PARSE_STRING				\
1612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (!lose) field = s;
1622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    PARSE_FIELD_STR(z.version);
1642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if (lose) return;
1652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if (strncmp(z.version, "ZEPH", 4))
1662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return;
1672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    PARSE_FIELD_INT(z.numfields);
1692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    PARSE_FIELD_INT(z.kind);
1702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    PARSE_FIELD_STR(z.uid);
1712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    PARSE_FIELD_INT(z.port);
1722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    PARSE_FIELD_INT(z.auth);
1732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    PARSE_FIELD_INT(z.authlen);
1742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    PARSE_FIELD_STR(z.authdata);
1752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    PARSE_FIELD_STR(z.class);
1762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    PARSE_FIELD_STR(z.inst);
1772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    PARSE_FIELD_STR(z.opcode);
1782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    PARSE_FIELD_STR(z.sender);
1792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    PARSE_FIELD_STR(z.recipient);
1802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    PARSE_FIELD_STR(z.format);
1812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    PARSE_FIELD_INT(z.cksum);
1822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    PARSE_FIELD_INT(z.multi);
1832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    PARSE_FIELD_STR(z.multi_uid);
1842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if (lose) {
186892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, " [|zephyr] (%d)", length));
1872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return;
1882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
1892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
190892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    ND_PRINT((ndo, " zephyr"));
1912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if (strncmp(z.version+4, "0.2", 3)) {
192892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, " v%s", z.version+4));
1932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return;
1942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
1952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
196892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    ND_PRINT((ndo, " %s", tok2str(z_types, "type %d", z.kind)));
1972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if (z.kind == Z_PACKET_SERVACK) {
1982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/* Initialization to silence warnings */
199e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes	const char *ackdata = NULL;
2002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	PARSE_FIELD_STR(ackdata);
2012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (!lose && strcmp(ackdata, "SENT"))
202892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	    ND_PRINT((ndo, "/%s", str_to_lower(ackdata)));
2032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
204892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    if (*z.sender) ND_PRINT((ndo, " %s", z.sender));
2052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if (!strcmp(z.class, "USER_LOCATE")) {
2072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (!strcmp(z.opcode, "USER_HIDE"))
208892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	    ND_PRINT((ndo, " hide"));
2092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	else if (!strcmp(z.opcode, "USER_UNHIDE"))
210892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	    ND_PRINT((ndo, " unhide"));
2112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	else
212892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	    ND_PRINT((ndo, " locate %s", z.inst));
2132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return;
2142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
2152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if (!strcmp(z.class, "ZEPHYR_ADMIN")) {
217892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, " zephyr-admin %s", str_to_lower(z.opcode)));
2182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return;
2192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
2202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if (!strcmp(z.class, "ZEPHYR_CTL")) {
2222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (!strcmp(z.inst, "CLIENT")) {
2232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    if (!strcmp(z.opcode, "SUBSCRIBE") ||
2242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		!strcmp(z.opcode, "SUBSCRIBE_NODEFS") ||
2252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		!strcmp(z.opcode, "UNSUBSCRIBE")) {
2262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
227892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, " %ssub%s", strcmp(z.opcode, "SUBSCRIBE") ? "un" : "",
2282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				   strcmp(z.opcode, "SUBSCRIBE_NODEFS") ? "" :
229892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes								   "-nodefs"));
2302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (z.kind != Z_PACKET_SERVACK) {
2312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		    /* Initialization to silence warnings */
232e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes		    const char *c = NULL, *i = NULL, *r = NULL;
2332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		    PARSE_FIELD_STR(c);
2342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		    PARSE_FIELD_STR(i);
2352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		    PARSE_FIELD_STR(r);
236892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		    if (!lose) ND_PRINT((ndo, " %s", z_triple(c, i, r)));
2372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
2382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return;
2392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    }
2402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    if (!strcmp(z.opcode, "GIMME")) {
242892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, " ret"));
2432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return;
2442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    }
2452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    if (!strcmp(z.opcode, "GIMMEDEFS")) {
247892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, " gimme-defs"));
2482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return;
2492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    }
2502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    if (!strcmp(z.opcode, "CLEARSUB")) {
252892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, " clear-subs"));
2532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return;
2542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    }
2552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
256892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	    ND_PRINT((ndo, " %s", str_to_lower(z.opcode)));
2572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    return;
2582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
2592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (!strcmp(z.inst, "HM")) {
261892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	    ND_PRINT((ndo, " %s", str_to_lower(z.opcode)));
2622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    return;
2632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
2642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (!strcmp(z.inst, "REALM")) {
2662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    if (!strcmp(z.opcode, "ADD_SUBSCRIBE"))
267892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, " realm add-subs"));
2682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    if (!strcmp(z.opcode, "REQ_SUBSCRIBE"))
269892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, " realm req-subs"));
2702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    if (!strcmp(z.opcode, "RLM_SUBSCRIBE"))
271892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, " realm rlm-sub"));
2722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    if (!strcmp(z.opcode, "RLM_UNSUBSCRIBE"))
273892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, " realm rlm-unsub"));
2742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    return;
2752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
2762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
2772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if (!strcmp(z.class, "HM_CTL")) {
279892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, " hm_ctl %s", str_to_lower(z.inst)));
280892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, " %s", str_to_lower(z.opcode)));
2812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return;
2822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
2832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if (!strcmp(z.class, "HM_STAT")) {
2852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (!strcmp(z.inst, "HMST_CLIENT") && !strcmp(z.opcode, "GIMMESTATS")) {
286892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	    ND_PRINT((ndo, " get-client-stats"));
2872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    return;
2882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
2892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
2902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if (!strcmp(z.class, "WG_CTL")) {
292892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, " wg_ctl %s", str_to_lower(z.inst)));
293892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, " %s", str_to_lower(z.opcode)));
2942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return;
2952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
2962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if (!strcmp(z.class, "LOGIN")) {
2982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (!strcmp(z.opcode, "USER_FLUSH")) {
299892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	    ND_PRINT((ndo, " flush_locs"));
3002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    return;
3012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
3022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (!strcmp(z.opcode, "NONE") ||
3042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    !strcmp(z.opcode, "OPSTAFF") ||
3052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    !strcmp(z.opcode, "REALM-VISIBLE") ||
3062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    !strcmp(z.opcode, "REALM-ANNOUNCED") ||
3072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    !strcmp(z.opcode, "NET-VISIBLE") ||
3082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    !strcmp(z.opcode, "NET-ANNOUNCED")) {
309892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	    ND_PRINT((ndo, " set-exposure %s", str_to_lower(z.opcode)));
3102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    return;
3112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
3122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
3132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if (!*z.recipient)
3152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	z.recipient = "*";
3162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
317892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    ND_PRINT((ndo, " to %s", z_triple(z.class, z.inst, z.recipient)));
3182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if (*z.opcode)
319892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, " op %s", z.opcode));
3202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
321