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