aboutsummaryrefslogtreecommitdiffstats
path: root/tests/p2p-fuzzer/p2p-fuzzer.c
blob: dcc1d72f3735260650483fc1fbc767070bbd4e96 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
/*
 * wpa_supplicant - P2P fuzzer
 * Copyright (c) 2015, Jouni Malinen <j@w1.fi>
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#include "utils/includes.h"

#include "utils/common.h"
#include "utils/eloop.h"
#include "common/ieee802_11_defs.h"
#include "p2p/p2p.h"


static void debug_print(void *ctx, int level, const char *msg)
{
	wpa_printf(level, "P2P: %s", msg);
}


static void find_stopped(void *ctx)
{
}


static int start_listen(void *ctx, unsigned int freq,
			unsigned int duration,
			const struct wpabuf *probe_resp_ie)
{
	return 0;
}


static void stop_listen(void *ctx)
{
}


static void dev_found(void *ctx, const u8 *addr,
		      const struct p2p_peer_info *info,
		      int new_device)
{
}


static void dev_lost(void *ctx, const u8 *dev_addr)
{
}


static int send_action(void *ctx, unsigned int freq, const u8 *dst,
		       const u8 *src, const u8 *bssid, const u8 *buf,
		       size_t len, unsigned int wait_time)
{
	return 0;
}


static void send_action_done(void *ctx)
{
}


static void go_neg_req_rx(void *ctx, const u8 *src, u16 dev_passwd_id)
{
}


static struct p2p_data * init_p2p(void)
{
	struct p2p_config p2p;

	os_memset(&p2p, 0, sizeof(p2p));
	p2p.max_peers = 100;
	p2p.passphrase_len = 8;
	p2p.channels.reg_classes = 1;
	p2p.channels.reg_class[0].reg_class = 81;
	p2p.channels.reg_class[0].channel[0] = 1;
	p2p.channels.reg_class[0].channel[1] = 2;
	p2p.channels.reg_class[0].channels = 2;
	p2p.debug_print = debug_print;
	p2p.find_stopped = find_stopped;
	p2p.start_listen = start_listen;
	p2p.stop_listen = stop_listen;
	p2p.dev_found = dev_found;
	p2p.dev_lost = dev_lost;
	p2p.send_action = send_action;
	p2p.send_action_done = send_action_done;
	p2p.go_neg_req_rx = go_neg_req_rx;

	return p2p_init(&p2p);
}


struct arg_ctx {
	struct p2p_data *p2p;
	const char *fname;
};


static void test_send_proberesp(void *eloop_data, void *user_ctx)
{
	struct arg_ctx *ctx = eloop_data;
	char *data;
	size_t len;
	struct os_reltime rx_time;

	wpa_printf(MSG_INFO, "p2p-fuzzer: Send proberesp '%s'", ctx->fname);

	data = os_readfile(ctx->fname, &len);
	if (!data) {
		wpa_printf(MSG_ERROR, "Could not read '%s'", ctx->fname);
		return;
	}

	wpa_hexdump(MSG_MSGDUMP, "fuzzer - IEs", data, len);

	os_memset(&rx_time, 0, sizeof(rx_time));
	p2p_scan_res_handler(ctx->p2p, (u8 *) "\x02\x00\x00\x00\x01\x00", 2412,
			     &rx_time, 0, (u8 *) data, len);
	p2p_scan_res_handled(ctx->p2p);

	os_free(data);
	eloop_terminate();
}


static void test_send_action(void *eloop_data, void *user_ctx)
{
	struct arg_ctx *ctx = eloop_data;
	char *data;
	size_t len;
	struct os_reltime rx_time;
	struct ieee80211_mgmt *mgmt;

	wpa_printf(MSG_INFO, "p2p-fuzzer: Send action '%s'", ctx->fname);

	data = os_readfile(ctx->fname, &len);
	if (!data) {
		wpa_printf(MSG_ERROR, "Could not read '%s'", ctx->fname);
		return;
	}
	if (len < IEEE80211_HDRLEN + 1)
		goto out;

	wpa_hexdump(MSG_MSGDUMP, "fuzzer - action", data, len);

	mgmt = (struct ieee80211_mgmt *) data;
	os_memset(&rx_time, 0, sizeof(rx_time));
	p2p_rx_action(ctx->p2p, mgmt->da, mgmt->sa, mgmt->bssid,
		      mgmt->u.action.category,
		      (u8 *) data + IEEE80211_HDRLEN + 1,
		      len - IEEE80211_HDRLEN - 1, 2412);

out:
	os_free(data);
	eloop_terminate();
}


int main(int argc, char *argv[])
{
	struct p2p_data *p2p;
	struct arg_ctx ctx;

	/* TODO: probreq and wpas_p2p_probe_req_rx() */

	if (argc < 3) {
		printf("usage: %s <proberesp|action> <file>\n", argv[0]);
		return -1;
	}

	if (os_program_init())
		return -1;

	wpa_debug_level = 0;
	wpa_debug_show_keys = 1;

	if (eloop_init()) {
		wpa_printf(MSG_ERROR, "Failed to initialize event loop");
		return -1;
	}

	p2p = init_p2p();
	if (!p2p) {
		wpa_printf(MSG_ERROR, "P2P init failed");
		return -1;
	}

	ctx.p2p = p2p;
	ctx.fname = argv[2];

	if (os_strcmp(argv[1], "proberesp") == 0) {
		eloop_register_timeout(0, 0, test_send_proberesp, &ctx, NULL);
	} else if (os_strcmp(argv[1], "action") == 0) {
		eloop_register_timeout(0, 0, test_send_action, &ctx, NULL);
	} else {
		wpa_printf(MSG_ERROR, "Unsupported test type '%s'", argv[1]);
		return -1;
	}

	wpa_printf(MSG_DEBUG, "Starting eloop");
	eloop_run();
	wpa_printf(MSG_DEBUG, "eloop done");

	p2p_deinit(p2p);
	eloop_destroy();
	os_program_deinit();

	return 0;
}