1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2010-2011 Monthadar Al Jaberi, TerraNet AB
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer,
12 *    without modification.
13 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
14 *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
15 *    redistribution must be conditioned upon including a substantially
16 *    similar Disclaimer requirement for further binary redistribution.
17 *
18 * NO WARRANTY
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
22 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
23 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
24 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
27 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
29 * THE POSSIBILITY OF SUCH DAMAGES.
30 *
31 * $FreeBSD$
32 */
33#include "hal.h"
34#include "../if_medium.h"
35#include "handler.h"
36
37static void
38hal_tx_proc(void *arg, int npending)
39{
40	struct wtap_hal *hal = (struct wtap_hal *)arg;
41	struct packet *p;
42
43#if 0
44	DWTAP_PRINTF("%s\n", __func__);
45#endif
46
47	hal = (struct wtap_hal *)arg;
48	for(;;){
49		p = medium_get_next_packet(hal->hal_md);
50		if(p == NULL)
51		return;
52
53		hal->plugin->work(hal->plugin, p);
54
55#if 0
56		DWTAP_PRINTF("[%d] freeing m=%p\n", p->id, p->m);
57#endif
58		m_free(p->m);
59		free(p, M_WTAP_PACKET);
60	}
61}
62
63void
64init_hal(struct wtap_hal *hal)
65{
66
67	DWTAP_PRINTF("%s\n", __func__);
68	mtx_init(&hal->hal_mtx, "wtap_hal mtx", NULL, MTX_DEF | MTX_RECURSE);
69
70	hal->hal_md = (struct wtap_medium *)malloc(sizeof(struct wtap_medium),
71	    M_WTAP, M_NOWAIT | M_ZERO);
72	bzero(hal->hal_md, sizeof(struct wtap_medium));
73
74	init_medium(hal->hal_md);
75	/* register event handler for packets */
76	TASK_INIT(&hal->hal_md->tx_handler->proc, 0, hal_tx_proc, hal);
77}
78
79void
80register_plugin(struct wtap_hal *hal, struct wtap_plugin *plugin)
81{
82
83	plugin->init(plugin);
84	hal->plugin = plugin;
85}
86
87void
88deregister_plugin(struct wtap_hal *hal)
89{
90
91	hal->plugin->deinit(hal->plugin);
92	hal->plugin = NULL; /* catch illegal usages */
93}
94
95void
96deinit_hal(struct wtap_hal *hal)
97{
98
99	DWTAP_PRINTF("%s\n", __func__);
100	deinit_medium(hal->hal_md);
101	free(hal->hal_md, M_WTAP);
102	mtx_destroy(&hal->hal_mtx);
103}
104
105int32_t
106new_wtap(struct wtap_hal *hal, int32_t id)
107{
108	static const uint8_t mac_pool[64][IEEE80211_ADDR_LEN] = {
109	    {0,152,154,152,150,151},
110	    {0,152,154,152,150,152},
111	    {0,152,154,152,150,153},
112	    {0,152,154,152,150,154},
113	    {0,152,154,152,150,155},
114	    {0,152,154,152,150,156},
115	    {0,152,154,152,150,157},
116	    {0,152,154,152,150,158},
117	    {0,152,154,152,151,151},
118	    {0,152,154,152,151,152},
119	    {0,152,154,152,151,153},
120	    {0,152,154,152,151,154},
121	    {0,152,154,152,151,155},
122	    {0,152,154,152,151,156},
123	    {0,152,154,152,151,157},
124	    {0,152,154,152,151,158},
125	    {0,152,154,152,152,151},
126	    {0,152,154,152,152,152},
127	    {0,152,154,152,152,153},
128	    {0,152,154,152,152,154},
129	    {0,152,154,152,152,155},
130	    {0,152,154,152,152,156},
131	    {0,152,154,152,152,157},
132	    {0,152,154,152,152,158},
133	    {0,152,154,152,153,151},
134	    {0,152,154,152,153,152},
135	    {0,152,154,152,153,153},
136	    {0,152,154,152,153,154},
137	    {0,152,154,152,153,155},
138	    {0,152,154,152,153,156},
139	    {0,152,154,152,153,157},
140	    {0,152,154,152,153,158},
141	    {0,152,154,152,154,151},
142	    {0,152,154,152,154,152},
143	    {0,152,154,152,154,153},
144	    {0,152,154,152,154,154},
145	    {0,152,154,152,154,155},
146	    {0,152,154,152,154,156},
147	    {0,152,154,152,154,157},
148	    {0,152,154,152,154,158},
149	    {0,152,154,152,155,151},
150	    {0,152,154,152,155,152},
151	    {0,152,154,152,155,153},
152	    {0,152,154,152,155,154},
153	    {0,152,154,152,155,155},
154	    {0,152,154,152,155,156},
155	    {0,152,154,152,155,157},
156	    {0,152,154,152,155,158},
157	    {0,152,154,152,156,151},
158	    {0,152,154,152,156,152},
159	    {0,152,154,152,156,153},
160	    {0,152,154,152,156,154},
161	    {0,152,154,152,156,155},
162	    {0,152,154,152,156,156},
163	    {0,152,154,152,156,157},
164	    {0,152,154,152,156,158},
165	    {0,152,154,152,157,151},
166	    {0,152,154,152,157,152},
167	    {0,152,154,152,157,153},
168	    {0,152,154,152,157,154},
169	    {0,152,154,152,157,155},
170	    {0,152,154,152,157,156},
171	    {0,152,154,152,157,157},
172	    {0,152,154,152,157,158}
173	    };
174
175	DWTAP_PRINTF("%s\n", __func__);
176	uint8_t const *macaddr = mac_pool[id];
177	if(hal->hal_devs[id] != NULL){
178		printf("error, wtap_id=%d already created\n", id);
179		return -1;
180	}
181
182	hal->hal_devs[id] = (struct wtap_softc *)malloc(
183	    sizeof(struct wtap_softc), M_WTAP, M_NOWAIT | M_ZERO);
184	bzero(hal->hal_devs[id], sizeof(struct wtap_softc));
185	hal->hal_devs[id]->sc_md = hal->hal_md;
186	hal->hal_devs[id]->id = id;
187	snprintf(hal->hal_devs[id]->name, sizeof(hal->hal_devs[id]->name),
188	    "wlan%d", id);
189	mtx_init(&hal->hal_devs[id]->sc_mtx, "wtap_softc mtx", NULL,
190	    MTX_DEF | MTX_RECURSE);
191
192	if(wtap_attach(hal->hal_devs[id], macaddr)){
193		printf("%s, cant alloc new wtap\n", __func__);
194		return -1;
195	}
196
197	return 0;
198}
199
200int32_t
201free_wtap(struct wtap_hal *hal, int32_t id)
202{
203
204	DWTAP_PRINTF("%s\n", __func__);
205	if(hal->hal_devs[id] == NULL){
206		printf("error, wtap_id=%d never created\n", id);
207		return -1;
208	}
209
210	if(wtap_detach(hal->hal_devs[id]))
211		printf("%s, cant alloc new wtap\n", __func__);
212	mtx_destroy(&hal->hal_devs[id]->sc_mtx);
213	free(hal->hal_devs[id], M_WTAP);
214	hal->hal_devs[id] = NULL;
215	return 0;
216}
217
218