xref: /dflybsd-src/contrib/tcpdump/print-zephyr.c (revision 59c07fbdf8168fa08c76c515186d561b5a92690c)
141c99275SPeter Avalos /*
241c99275SPeter Avalos  * Decode and print Zephyr packets.
341c99275SPeter Avalos  *
4*ed775ee7SAntonio Huete Jimenez  *	https://web.mit.edu/zephyr/doc/protocol
541c99275SPeter Avalos  *
641c99275SPeter Avalos  * Copyright (c) 2001 Nickolai Zeldovich <kolya@MIT.EDU>
741c99275SPeter Avalos  * All rights reserved.
841c99275SPeter Avalos  *
941c99275SPeter Avalos  * Redistribution and use in source and binary forms, with or without
1041c99275SPeter Avalos  * modification, are permitted provided that: (1) source code
1141c99275SPeter Avalos  * distributions retain the above copyright notice and this paragraph
1241c99275SPeter Avalos  * in its entirety, and (2) distributions including binary code include
1341c99275SPeter Avalos  * the above copyright notice and this paragraph in its entirety in
1441c99275SPeter Avalos  * the documentation or other materials provided with the distribution.
1541c99275SPeter Avalos  * The name of the author(s) may not be used to endorse or promote
1641c99275SPeter Avalos  * products derived from this software without specific prior written
1741c99275SPeter Avalos  * permission.  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY
1841c99275SPeter Avalos  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE
1941c99275SPeter Avalos  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2041c99275SPeter Avalos  * PURPOSE.
2141c99275SPeter Avalos  */
2241c99275SPeter Avalos 
23411677aeSAaron LI /* \summary: Zephyr printer */
2441c99275SPeter Avalos 
2541c99275SPeter Avalos #ifdef HAVE_CONFIG_H
26*ed775ee7SAntonio Huete Jimenez #include <config.h>
2741c99275SPeter Avalos #endif
2841c99275SPeter Avalos 
29*ed775ee7SAntonio Huete Jimenez #include "netdissect-stdinc.h"
3041c99275SPeter Avalos 
3141c99275SPeter Avalos #include <stdio.h>
3241c99275SPeter Avalos #include <string.h>
3341c99275SPeter Avalos #include <stdlib.h>
3441c99275SPeter Avalos 
35*ed775ee7SAntonio Huete Jimenez #include "netdissect-ctype.h"
36*ed775ee7SAntonio Huete Jimenez 
37411677aeSAaron LI #include "netdissect.h"
38*ed775ee7SAntonio Huete Jimenez #include "extract.h"
3941c99275SPeter Avalos 
4041c99275SPeter Avalos struct z_packet {
41411677aeSAaron LI     const char *version;
4241c99275SPeter Avalos     int numfields;
4341c99275SPeter Avalos     int kind;
44411677aeSAaron LI     const char *uid;
4541c99275SPeter Avalos     int port;
4641c99275SPeter Avalos     int auth;
4741c99275SPeter Avalos     int authlen;
48411677aeSAaron LI     const char *authdata;
49411677aeSAaron LI     const char *class;
50411677aeSAaron LI     const char *inst;
51411677aeSAaron LI     const char *opcode;
52411677aeSAaron LI     const char *sender;
5341c99275SPeter Avalos     const char *recipient;
54411677aeSAaron LI     const char *format;
5541c99275SPeter Avalos     int cksum;
5641c99275SPeter Avalos     int multi;
57411677aeSAaron LI     const char *multi_uid;
5841c99275SPeter Avalos     /* Other fields follow here.. */
5941c99275SPeter Avalos };
6041c99275SPeter Avalos 
6141c99275SPeter Avalos enum z_packet_type {
6241c99275SPeter Avalos     Z_PACKET_UNSAFE = 0,
6341c99275SPeter Avalos     Z_PACKET_UNACKED,
6441c99275SPeter Avalos     Z_PACKET_ACKED,
6541c99275SPeter Avalos     Z_PACKET_HMACK,
6641c99275SPeter Avalos     Z_PACKET_HMCTL,
6741c99275SPeter Avalos     Z_PACKET_SERVACK,
6841c99275SPeter Avalos     Z_PACKET_SERVNAK,
6941c99275SPeter Avalos     Z_PACKET_CLIENTACK,
7041c99275SPeter Avalos     Z_PACKET_STAT
7141c99275SPeter Avalos };
7241c99275SPeter Avalos 
73411677aeSAaron LI static const struct tok z_types[] = {
7441c99275SPeter Avalos     { Z_PACKET_UNSAFE,		"unsafe" },
7541c99275SPeter Avalos     { Z_PACKET_UNACKED,		"unacked" },
7641c99275SPeter Avalos     { Z_PACKET_ACKED,		"acked" },
7741c99275SPeter Avalos     { Z_PACKET_HMACK,		"hm-ack" },
7841c99275SPeter Avalos     { Z_PACKET_HMCTL,		"hm-ctl" },
7941c99275SPeter Avalos     { Z_PACKET_SERVACK,		"serv-ack" },
8041c99275SPeter Avalos     { Z_PACKET_SERVNAK,		"serv-nak" },
8141c99275SPeter Avalos     { Z_PACKET_CLIENTACK,	"client-ack" },
82411677aeSAaron LI     { Z_PACKET_STAT,		"stat" },
83411677aeSAaron LI     { 0,			NULL }
8441c99275SPeter Avalos };
8541c99275SPeter Avalos 
86411677aeSAaron LI static char z_buf[256];
8741c99275SPeter Avalos 
88411677aeSAaron LI static const char *
parse_field(netdissect_options * ndo,const char ** pptr,int * len)89*ed775ee7SAntonio Huete Jimenez parse_field(netdissect_options *ndo, const char **pptr, int *len)
9041c99275SPeter Avalos {
91411677aeSAaron LI     const char *s;
9241c99275SPeter Avalos 
93411677aeSAaron LI     /* Start of string */
9441c99275SPeter Avalos     s = *pptr;
95411677aeSAaron LI     /* Scan for the NUL terminator */
96411677aeSAaron LI     for (;;) {
97411677aeSAaron LI 	if (*len == 0) {
98411677aeSAaron LI 	    /* Ran out of packet data without finding it */
99411677aeSAaron LI 	    return NULL;
100411677aeSAaron LI 	}
101*ed775ee7SAntonio Huete Jimenez 	if (GET_U_1(*pptr) == '\0') {
102411677aeSAaron LI 	    /* Found it */
103411677aeSAaron LI 	    break;
104411677aeSAaron LI 	}
105411677aeSAaron LI 	/* Keep scanning */
10641c99275SPeter Avalos 	(*pptr)++;
10741c99275SPeter Avalos 	(*len)--;
10841c99275SPeter Avalos     }
109411677aeSAaron LI     /* Skip the NUL terminator */
11041c99275SPeter Avalos     (*pptr)++;
11141c99275SPeter Avalos     (*len)--;
11241c99275SPeter Avalos     return s;
11341c99275SPeter Avalos }
11441c99275SPeter Avalos 
11541c99275SPeter Avalos static const char *
z_triple(const char * class,const char * inst,const char * recipient)116411677aeSAaron LI z_triple(const char *class, const char *inst, const char *recipient)
11741c99275SPeter Avalos {
11841c99275SPeter Avalos     if (!*recipient)
11941c99275SPeter Avalos 	recipient = "*";
12041c99275SPeter Avalos     snprintf(z_buf, sizeof(z_buf), "<%s,%s,%s>", class, inst, recipient);
12141c99275SPeter Avalos     z_buf[sizeof(z_buf)-1] = '\0';
12241c99275SPeter Avalos     return z_buf;
12341c99275SPeter Avalos }
12441c99275SPeter Avalos 
12541c99275SPeter Avalos static const char *
str_to_lower(const char * string)126411677aeSAaron LI str_to_lower(const char *string)
12741c99275SPeter Avalos {
128411677aeSAaron LI     char *zb_string;
129411677aeSAaron LI 
13041c99275SPeter Avalos     strncpy(z_buf, string, sizeof(z_buf));
13141c99275SPeter Avalos     z_buf[sizeof(z_buf)-1] = '\0';
13241c99275SPeter Avalos 
133411677aeSAaron LI     zb_string = z_buf;
134411677aeSAaron LI     while (*zb_string) {
135*ed775ee7SAntonio Huete Jimenez 	*zb_string = ND_ASCII_TOLOWER(*zb_string);
136411677aeSAaron LI 	zb_string++;
13741c99275SPeter Avalos     }
13841c99275SPeter Avalos 
13941c99275SPeter Avalos     return z_buf;
14041c99275SPeter Avalos }
14141c99275SPeter Avalos 
14241c99275SPeter Avalos void
zephyr_print(netdissect_options * ndo,const u_char * cp,u_int length)143*ed775ee7SAntonio Huete Jimenez zephyr_print(netdissect_options *ndo, const u_char *cp, u_int length)
14441c99275SPeter Avalos {
145*ed775ee7SAntonio Huete Jimenez     struct z_packet z = {
146*ed775ee7SAntonio Huete Jimenez         NULL,	/* version */
147*ed775ee7SAntonio Huete Jimenez         0,	/* numfields */
148*ed775ee7SAntonio Huete Jimenez         0,	/* kind */
149*ed775ee7SAntonio Huete Jimenez         NULL,	/* uid */
150*ed775ee7SAntonio Huete Jimenez         0,	/* port */
151*ed775ee7SAntonio Huete Jimenez         0,	/* auth */
152*ed775ee7SAntonio Huete Jimenez         0,	/* authlen */
153*ed775ee7SAntonio Huete Jimenez         NULL,	/* authdata */
154*ed775ee7SAntonio Huete Jimenez         NULL,	/* class */
155*ed775ee7SAntonio Huete Jimenez         NULL,	/* inst */
156*ed775ee7SAntonio Huete Jimenez         NULL,	/* opcode */
157*ed775ee7SAntonio Huete Jimenez         NULL,	/* sender */
158*ed775ee7SAntonio Huete Jimenez         NULL,	/* recipient */
159*ed775ee7SAntonio Huete Jimenez         NULL,	/* format */
160*ed775ee7SAntonio Huete Jimenez         0,	/* cksum */
161*ed775ee7SAntonio Huete Jimenez         0,	/* multi */
162*ed775ee7SAntonio Huete Jimenez         NULL	/* multi_uid */
163*ed775ee7SAntonio Huete Jimenez     };
164411677aeSAaron LI     const char *parse = (const char *) cp;
16541c99275SPeter Avalos     int parselen = length;
166411677aeSAaron LI     const char *s;
16741c99275SPeter Avalos     int lose = 0;
16841c99275SPeter Avalos 
169*ed775ee7SAntonio Huete Jimenez     ndo->ndo_protocol = "zephyr";
170ea7b4bf5SPeter Avalos     /* squelch compiler warnings */
171ea7b4bf5SPeter Avalos 
17241c99275SPeter Avalos #define PARSE_STRING						\
173*ed775ee7SAntonio Huete Jimenez 	s = parse_field(ndo, &parse, &parselen);	\
17441c99275SPeter Avalos 	if (!s) lose = 1;
17541c99275SPeter Avalos 
17641c99275SPeter Avalos #define PARSE_FIELD_INT(field)			\
17741c99275SPeter Avalos 	PARSE_STRING				\
17841c99275SPeter Avalos 	if (!lose) field = strtol(s, 0, 16);
17941c99275SPeter Avalos 
18041c99275SPeter Avalos #define PARSE_FIELD_STR(field)			\
18141c99275SPeter Avalos 	PARSE_STRING				\
18241c99275SPeter Avalos 	if (!lose) field = s;
18341c99275SPeter Avalos 
18441c99275SPeter Avalos     PARSE_FIELD_STR(z.version);
185*ed775ee7SAntonio Huete Jimenez     if (lose)
186*ed775ee7SAntonio Huete Jimenez         goto invalid;
187*ed775ee7SAntonio Huete Jimenez 
18841c99275SPeter Avalos     if (strncmp(z.version, "ZEPH", 4))
18941c99275SPeter Avalos 	return;
19041c99275SPeter Avalos 
19141c99275SPeter Avalos     PARSE_FIELD_INT(z.numfields);
19241c99275SPeter Avalos     PARSE_FIELD_INT(z.kind);
19341c99275SPeter Avalos     PARSE_FIELD_STR(z.uid);
19441c99275SPeter Avalos     PARSE_FIELD_INT(z.port);
19541c99275SPeter Avalos     PARSE_FIELD_INT(z.auth);
19641c99275SPeter Avalos     PARSE_FIELD_INT(z.authlen);
19741c99275SPeter Avalos     PARSE_FIELD_STR(z.authdata);
19841c99275SPeter Avalos     PARSE_FIELD_STR(z.class);
19941c99275SPeter Avalos     PARSE_FIELD_STR(z.inst);
20041c99275SPeter Avalos     PARSE_FIELD_STR(z.opcode);
20141c99275SPeter Avalos     PARSE_FIELD_STR(z.sender);
20241c99275SPeter Avalos     PARSE_FIELD_STR(z.recipient);
20341c99275SPeter Avalos     PARSE_FIELD_STR(z.format);
20441c99275SPeter Avalos     PARSE_FIELD_INT(z.cksum);
20541c99275SPeter Avalos     PARSE_FIELD_INT(z.multi);
20641c99275SPeter Avalos     PARSE_FIELD_STR(z.multi_uid);
20741c99275SPeter Avalos 
208411677aeSAaron LI     if (lose)
209*ed775ee7SAntonio Huete Jimenez         goto invalid;
21041c99275SPeter Avalos 
211*ed775ee7SAntonio Huete Jimenez     ND_PRINT(" zephyr");
21241c99275SPeter Avalos     if (strncmp(z.version+4, "0.2", 3)) {
213*ed775ee7SAntonio Huete Jimenez 	ND_PRINT(" v%s", z.version+4);
21441c99275SPeter Avalos 	return;
21541c99275SPeter Avalos     }
21641c99275SPeter Avalos 
217*ed775ee7SAntonio Huete Jimenez     ND_PRINT(" %s", tok2str(z_types, "type %d", z.kind));
21841c99275SPeter Avalos     if (z.kind == Z_PACKET_SERVACK) {
21941c99275SPeter Avalos 	/* Initialization to silence warnings */
220411677aeSAaron LI 	const char *ackdata = NULL;
22141c99275SPeter Avalos 	PARSE_FIELD_STR(ackdata);
22241c99275SPeter Avalos 	if (!lose && strcmp(ackdata, "SENT"))
223*ed775ee7SAntonio Huete Jimenez 	    ND_PRINT("/%s", str_to_lower(ackdata));
22441c99275SPeter Avalos     }
225*ed775ee7SAntonio Huete Jimenez     if (*z.sender) ND_PRINT(" %s", z.sender);
22641c99275SPeter Avalos 
22741c99275SPeter Avalos     if (!strcmp(z.class, "USER_LOCATE")) {
22841c99275SPeter Avalos 	if (!strcmp(z.opcode, "USER_HIDE"))
229*ed775ee7SAntonio Huete Jimenez 	    ND_PRINT(" hide");
23041c99275SPeter Avalos 	else if (!strcmp(z.opcode, "USER_UNHIDE"))
231*ed775ee7SAntonio Huete Jimenez 	    ND_PRINT(" unhide");
23241c99275SPeter Avalos 	else
233*ed775ee7SAntonio Huete Jimenez 	    ND_PRINT(" locate %s", z.inst);
23441c99275SPeter Avalos 	return;
23541c99275SPeter Avalos     }
23641c99275SPeter Avalos 
23741c99275SPeter Avalos     if (!strcmp(z.class, "ZEPHYR_ADMIN")) {
238*ed775ee7SAntonio Huete Jimenez 	ND_PRINT(" zephyr-admin %s", str_to_lower(z.opcode));
23941c99275SPeter Avalos 	return;
24041c99275SPeter Avalos     }
24141c99275SPeter Avalos 
24241c99275SPeter Avalos     if (!strcmp(z.class, "ZEPHYR_CTL")) {
24341c99275SPeter Avalos 	if (!strcmp(z.inst, "CLIENT")) {
24441c99275SPeter Avalos 	    if (!strcmp(z.opcode, "SUBSCRIBE") ||
24541c99275SPeter Avalos 		!strcmp(z.opcode, "SUBSCRIBE_NODEFS") ||
24641c99275SPeter Avalos 		!strcmp(z.opcode, "UNSUBSCRIBE")) {
24741c99275SPeter Avalos 
248*ed775ee7SAntonio Huete Jimenez 		ND_PRINT(" %ssub%s", strcmp(z.opcode, "SUBSCRIBE") ? "un" : "",
24941c99275SPeter Avalos 				   strcmp(z.opcode, "SUBSCRIBE_NODEFS") ? "" :
250*ed775ee7SAntonio Huete Jimenez 								   "-nodefs");
25141c99275SPeter Avalos 		if (z.kind != Z_PACKET_SERVACK) {
25241c99275SPeter Avalos 		    /* Initialization to silence warnings */
253411677aeSAaron LI 		    const char *c = NULL, *i = NULL, *r = NULL;
25441c99275SPeter Avalos 		    PARSE_FIELD_STR(c);
25541c99275SPeter Avalos 		    PARSE_FIELD_STR(i);
25641c99275SPeter Avalos 		    PARSE_FIELD_STR(r);
257*ed775ee7SAntonio Huete Jimenez 		    if (!lose) ND_PRINT(" %s", z_triple(c, i, r));
25841c99275SPeter Avalos 		}
25941c99275SPeter Avalos 		return;
26041c99275SPeter Avalos 	    }
26141c99275SPeter Avalos 
26241c99275SPeter Avalos 	    if (!strcmp(z.opcode, "GIMME")) {
263*ed775ee7SAntonio Huete Jimenez 		ND_PRINT(" ret");
26441c99275SPeter Avalos 		return;
26541c99275SPeter Avalos 	    }
26641c99275SPeter Avalos 
26741c99275SPeter Avalos 	    if (!strcmp(z.opcode, "GIMMEDEFS")) {
268*ed775ee7SAntonio Huete Jimenez 		ND_PRINT(" gimme-defs");
26941c99275SPeter Avalos 		return;
27041c99275SPeter Avalos 	    }
27141c99275SPeter Avalos 
27241c99275SPeter Avalos 	    if (!strcmp(z.opcode, "CLEARSUB")) {
273*ed775ee7SAntonio Huete Jimenez 		ND_PRINT(" clear-subs");
27441c99275SPeter Avalos 		return;
27541c99275SPeter Avalos 	    }
27641c99275SPeter Avalos 
277*ed775ee7SAntonio Huete Jimenez 	    ND_PRINT(" %s", str_to_lower(z.opcode));
27841c99275SPeter Avalos 	    return;
27941c99275SPeter Avalos 	}
28041c99275SPeter Avalos 
28141c99275SPeter Avalos 	if (!strcmp(z.inst, "HM")) {
282*ed775ee7SAntonio Huete Jimenez 	    ND_PRINT(" %s", str_to_lower(z.opcode));
28341c99275SPeter Avalos 	    return;
28441c99275SPeter Avalos 	}
28541c99275SPeter Avalos 
28641c99275SPeter Avalos 	if (!strcmp(z.inst, "REALM")) {
28741c99275SPeter Avalos 	    if (!strcmp(z.opcode, "ADD_SUBSCRIBE"))
288*ed775ee7SAntonio Huete Jimenez 		ND_PRINT(" realm add-subs");
28941c99275SPeter Avalos 	    if (!strcmp(z.opcode, "REQ_SUBSCRIBE"))
290*ed775ee7SAntonio Huete Jimenez 		ND_PRINT(" realm req-subs");
29141c99275SPeter Avalos 	    if (!strcmp(z.opcode, "RLM_SUBSCRIBE"))
292*ed775ee7SAntonio Huete Jimenez 		ND_PRINT(" realm rlm-sub");
29341c99275SPeter Avalos 	    if (!strcmp(z.opcode, "RLM_UNSUBSCRIBE"))
294*ed775ee7SAntonio Huete Jimenez 		ND_PRINT(" realm rlm-unsub");
29541c99275SPeter Avalos 	    return;
29641c99275SPeter Avalos 	}
29741c99275SPeter Avalos     }
29841c99275SPeter Avalos 
29941c99275SPeter Avalos     if (!strcmp(z.class, "HM_CTL")) {
300*ed775ee7SAntonio Huete Jimenez 	ND_PRINT(" hm_ctl %s", str_to_lower(z.inst));
301*ed775ee7SAntonio Huete Jimenez 	ND_PRINT(" %s", str_to_lower(z.opcode));
30241c99275SPeter Avalos 	return;
30341c99275SPeter Avalos     }
30441c99275SPeter Avalos 
30541c99275SPeter Avalos     if (!strcmp(z.class, "HM_STAT")) {
30641c99275SPeter Avalos 	if (!strcmp(z.inst, "HMST_CLIENT") && !strcmp(z.opcode, "GIMMESTATS")) {
307*ed775ee7SAntonio Huete Jimenez 	    ND_PRINT(" get-client-stats");
30841c99275SPeter Avalos 	    return;
30941c99275SPeter Avalos 	}
31041c99275SPeter Avalos     }
31141c99275SPeter Avalos 
31241c99275SPeter Avalos     if (!strcmp(z.class, "WG_CTL")) {
313*ed775ee7SAntonio Huete Jimenez 	ND_PRINT(" wg_ctl %s", str_to_lower(z.inst));
314*ed775ee7SAntonio Huete Jimenez 	ND_PRINT(" %s", str_to_lower(z.opcode));
31541c99275SPeter Avalos 	return;
31641c99275SPeter Avalos     }
31741c99275SPeter Avalos 
31841c99275SPeter Avalos     if (!strcmp(z.class, "LOGIN")) {
31941c99275SPeter Avalos 	if (!strcmp(z.opcode, "USER_FLUSH")) {
320*ed775ee7SAntonio Huete Jimenez 	    ND_PRINT(" flush_locs");
32141c99275SPeter Avalos 	    return;
32241c99275SPeter Avalos 	}
32341c99275SPeter Avalos 
32441c99275SPeter Avalos 	if (!strcmp(z.opcode, "NONE") ||
32541c99275SPeter Avalos 	    !strcmp(z.opcode, "OPSTAFF") ||
32641c99275SPeter Avalos 	    !strcmp(z.opcode, "REALM-VISIBLE") ||
32741c99275SPeter Avalos 	    !strcmp(z.opcode, "REALM-ANNOUNCED") ||
32841c99275SPeter Avalos 	    !strcmp(z.opcode, "NET-VISIBLE") ||
32941c99275SPeter Avalos 	    !strcmp(z.opcode, "NET-ANNOUNCED")) {
330*ed775ee7SAntonio Huete Jimenez 	    ND_PRINT(" set-exposure %s", str_to_lower(z.opcode));
33141c99275SPeter Avalos 	    return;
33241c99275SPeter Avalos 	}
33341c99275SPeter Avalos     }
33441c99275SPeter Avalos 
33541c99275SPeter Avalos     if (!*z.recipient)
33641c99275SPeter Avalos 	z.recipient = "*";
33741c99275SPeter Avalos 
338*ed775ee7SAntonio Huete Jimenez     ND_PRINT(" to %s", z_triple(z.class, z.inst, z.recipient));
33941c99275SPeter Avalos     if (*z.opcode)
340*ed775ee7SAntonio Huete Jimenez 	ND_PRINT(" op %s", z.opcode);
341411677aeSAaron LI     return;
342411677aeSAaron LI 
343*ed775ee7SAntonio Huete Jimenez invalid:
344*ed775ee7SAntonio Huete Jimenez     nd_print_invalid(ndo);
34541c99275SPeter Avalos }
346