GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/tcpdump/print-vqp.c Lines: 0 92 0.0 %
Date: 2017-11-13 Branches: 0 64 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: print-vqp.c,v 1.7 2006/08/24 05:11:43 stevesk Exp $	*/
2
3
/*
4
 * Copyright (c) 2006 Kevin Steves <stevesk@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
/*
20
 * VLAN Query Protocol (VQP)
21
 *
22
 *    0                   1                   2                   3
23
 *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
24
 *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
25
 *   |    Version    |    Opcode     | Response Code |  Data Count   |
26
 *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
27
 *   |                         Transaction ID                        |
28
 *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
29
 *   |                            Type (1)                           |
30
 *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
31
 *   |             Length            |            Data               /
32
 *   /                                                               /
33
 *   /                                                               /
34
 *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
35
 *   |                            Type (n)                           |
36
 *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
37
 *   |             Length            |            Data               /
38
 *   /                                                               /
39
 *   /                                                               /
40
 *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
41
 *
42
 * VQP is layered over UDP.  The default destination port is 1589.
43
 *
44
 */
45
46
#include <sys/types.h>
47
#include <sys/socket.h>
48
49
#include <net/if.h>
50
#include <netinet/in.h>
51
#include <netinet/if_ether.h>
52
#include <arpa/inet.h>
53
54
#include <stdio.h>
55
#include <string.h>
56
57
#include "interface.h"
58
#include "addrtoname.h"
59
#include "extract.h"
60
61
struct vqp_hdr {
62
	u_char version;
63
	u_char opcode;
64
	u_char rcode;
65
	u_char dcount;
66
	u_int32_t xid;
67
};
68
69
#define VQP_JOIN			0x01
70
#define VQP_JOIN_RESPONSE		0x02
71
#define VQP_RECONFIRM			0x03
72
#define VQP_RECONFIRM_RESPONSE		0x04
73
74
#define VQP_NO_ERROR			0x00
75
#define VQP_WRONG_VERSION		0x01
76
#define VQP_INSUFFICIENT_RESOURCES	0x02
77
#define VQP_DENY			0x03
78
#define VQP_SHUTDOWN			0x04
79
#define VQP_WRONG_MGMT_DOMAIN		0x05
80
81
/* 4 bytes struct in_addr; IP address of VQP client */
82
#define VQP_CLIENT_ADDR			0x00000c01
83
/* string */
84
#define VQP_PORT_NAME			0x00000c02
85
/* string */
86
#define VQP_VLAN_NAME			0x00000c03
87
/* string; VTP domain if set */
88
#define VQP_DOMAIN_NAME			0x00000c04
89
/* ethernet frame */
90
#define VQP_ETHERNET_FRAME		0x00000c05
91
/* 6 bytes, mac address */
92
#define VQP_MAC				0x00000c06
93
/* 2 bytes? */
94
#define VQP_UNKNOWN			0x00000c07
95
/* 6 bytes, mac address */
96
#define VQP_COOKIE			0x00000c08
97
98
static void
99
vqp_print_opcode(u_int val)
100
{
101
	switch (val) {
102
	case VQP_JOIN:
103
		printf("Join");
104
		break;
105
	case VQP_JOIN_RESPONSE:
106
		printf("JoinResp");
107
		break;
108
	case VQP_RECONFIRM:
109
		printf("Reconfirm");
110
		break;
111
	case VQP_RECONFIRM_RESPONSE:
112
		printf("ReconfirmResp");
113
		break;
114
	default:
115
		printf("unknown(%x)", val);
116
		break;
117
	}
118
}
119
120
static void
121
vqp_print_rcode(u_int val)
122
{
123
	switch (val) {
124
	case VQP_NO_ERROR:
125
		printf("NoError");
126
		break;
127
	case VQP_WRONG_VERSION:
128
		printf("WrongVersion");
129
		break;
130
	case VQP_INSUFFICIENT_RESOURCES:
131
		printf("InsufficientResources");
132
		break;
133
	case VQP_DENY:
134
		printf("Deny");
135
		break;
136
	case VQP_SHUTDOWN:
137
		printf("Shutdown");
138
		break;
139
	case VQP_WRONG_MGMT_DOMAIN:
140
		printf("WrongMgmtDomain");
141
		break;
142
	default:
143
		printf("unknown(%x)", val);
144
		break;
145
	}
146
}
147
148
static void
149
print_hex(const u_char *p, u_int len)
150
{
151
	while (len--)
152
		printf("%02x", *p++);
153
}
154
155
static void
156
vqp_print_type(u_int type, u_int len, const u_char *p)
157
{
158
	switch (type) {
159
	case VQP_CLIENT_ADDR:
160
		printf(" client:");
161
		if (len == sizeof(struct in_addr)) {
162
			struct in_addr in;
163
			memcpy(&in, p, sizeof in);
164
			printf("%s", inet_ntoa(in));
165
		} else
166
			print_hex(p, len);
167
		break;
168
	case VQP_PORT_NAME:
169
		printf(" port:");
170
		fn_printn(p, len, NULL);
171
		break;
172
	case VQP_VLAN_NAME:
173
		printf(" vlan:");
174
		fn_printn(p, len, NULL);
175
		break;
176
	case VQP_DOMAIN_NAME:
177
		printf(" domain:");
178
		fn_printn(p, len, NULL);
179
		break;
180
	case VQP_ETHERNET_FRAME:
181
		printf(" ethernet:");
182
		if (vflag > 1)
183
			print_hex(p, len);
184
		else if (len >= ETHER_ADDR_LEN * 2) {
185
			p += ETHER_ADDR_LEN;	/* skip dst mac */
186
			printf("%s", etheraddr_string(p)); /* src mac */
187
		} else
188
			print_hex(p, len);
189
		break;
190
	case VQP_MAC:
191
		printf(" mac:");
192
		if (len == ETHER_ADDR_LEN)
193
			printf("%s", etheraddr_string(p));
194
		else
195
			print_hex(p, len);
196
		break;
197
	case VQP_UNKNOWN:
198
		printf(" unknown:");
199
		print_hex(p, len);
200
		break;
201
	case VQP_COOKIE:
202
		printf(" cookie:");
203
		if (len == ETHER_ADDR_LEN)
204
			printf("%s", etheraddr_string(p));
205
		else
206
			print_hex(p, len);
207
		break;
208
	default:
209
		printf(" unknown(%x/%u)", type, len);
210
	}
211
}
212
213
void
214
vqp_print(const u_char *bp, u_int len)
215
{
216
	struct vqp_hdr *p = (struct vqp_hdr *)bp;
217
	u_int dcount;
218
219
	TCHECK(p->version);
220
	printf(" VQPv%u", p->version);
221
	if (p->version != 1)
222
		return;
223
	TCHECK(p->opcode);
224
	printf("-");
225
	vqp_print_opcode(p->opcode);
226
	TCHECK(p->rcode);
227
	printf(" rcode:");
228
	vqp_print_rcode(p->rcode);
229
	TCHECK(p->xid);
230
	printf(" xid:0x%08x", ntohl(p->xid));
231
	printf(" dcount:%u", p->dcount);
232
	bp += sizeof(struct vqp_hdr);
233
234
	dcount = p->dcount;
235
	while (vflag && dcount > 0) {
236
		u_int type, length;
237
238
		TCHECK2(bp[0], 6);
239
		type = EXTRACT_32BITS(bp);
240
		bp += 4;
241
		length = EXTRACT_16BITS(bp);
242
		bp += 2;
243
		TCHECK2(bp[0], length);
244
		vqp_print_type(type, length, bp);
245
		bp += length;
246
		dcount--;
247
	}
248
249
	return;
250
trunc:
251
	printf("[|vqp]");
252
}