1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
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 #include "hal.h"
32 #include "../if_medium.h"
33 #include "handler.h"
34
35 static void
hal_tx_proc(void * arg,int npending)36 hal_tx_proc(void *arg, int npending)
37 {
38 struct wtap_hal *hal = (struct wtap_hal *)arg;
39 struct packet *p;
40
41 #if 0
42 DWTAP_PRINTF("%s\n", __func__);
43 #endif
44
45 hal = (struct wtap_hal *)arg;
46 for(;;){
47 p = medium_get_next_packet(hal->hal_md);
48 if(p == NULL)
49 return;
50
51 hal->plugin->work(hal->plugin, p);
52
53 #if 0
54 DWTAP_PRINTF("[%d] freeing m=%p\n", p->id, p->m);
55 #endif
56 m_free(p->m);
57 free(p, M_WTAP_PACKET);
58 }
59 }
60
61 void
init_hal(struct wtap_hal * hal)62 init_hal(struct wtap_hal *hal)
63 {
64
65 DWTAP_PRINTF("%s\n", __func__);
66 mtx_init(&hal->hal_mtx, "wtap_hal mtx", NULL, MTX_DEF | MTX_RECURSE);
67
68 hal->hal_md = (struct wtap_medium *)malloc(sizeof(struct wtap_medium),
69 M_WTAP, M_NOWAIT | M_ZERO);
70
71 init_medium(hal->hal_md);
72 /* register event handler for packets */
73 TASK_INIT(&hal->hal_md->tx_handler->proc, 0, hal_tx_proc, hal);
74
75 callout_init_mtx(&hal->hw.timer_intr, &hal->hal_mtx, 0);
76 hal->hw.timer_intr_intval = msecs_to_ticks(HAL_TIMER_INTVAL);
77 }
78
79 void
register_plugin(struct wtap_hal * hal,struct wtap_plugin * plugin)80 register_plugin(struct wtap_hal *hal, struct wtap_plugin *plugin)
81 {
82
83 plugin->init(plugin);
84 hal->plugin = plugin;
85 }
86
87 void
deregister_plugin(struct wtap_hal * hal)88 deregister_plugin(struct wtap_hal *hal)
89 {
90
91 hal->plugin->deinit(hal->plugin);
92 hal->plugin = NULL; /* catch illegal usages */
93 }
94
95 void
deinit_hal(struct wtap_hal * hal)96 deinit_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
105 int32_t
new_wtap(struct wtap_hal * hal,int32_t id)106 new_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 hal->hal_devs[id]->sc_md = hal->hal_md;
185 hal->hal_devs[id]->id = id;
186 hal->hal_devs[id]->hal = hal;
187 snprintf(hal->hal_devs[id]->name, sizeof(hal->hal_devs[id]->name),
188 "wtap%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, can't alloc new wtap\n", __func__);
194 return -1;
195 }
196
197 return 0;
198 }
199
200 int32_t
free_wtap(struct wtap_hal * hal,int32_t id)201 free_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, can't 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 void
wtap_hal_timer_intr(void * arg)219 wtap_hal_timer_intr(void *arg)
220 {
221 struct wtap_hal *hal = arg;
222 uint32_t intval = hal->hw.timer_intr_intval;
223
224 hal->hw.tsf += ticks_to_msecs(intval);
225
226 callout_schedule(&hal->hw.timer_intr, intval);
227 }
228
229 void
wtap_hal_reset_tsf(struct wtap_hal * hal)230 wtap_hal_reset_tsf(struct wtap_hal *hal)
231 {
232 mtx_lock(&hal->hal_mtx);
233
234 callout_stop(&hal->hw.timer_intr);
235 hal->hw.tsf = 0;
236 callout_reset(&hal->hw.timer_intr, hal->hw.timer_intr_intval,
237 wtap_hal_timer_intr, hal);
238
239 mtx_unlock(&hal->hal_mtx);
240 }
241
242 uint64_t
wtap_hal_get_tsf(struct wtap_hal * hal)243 wtap_hal_get_tsf(struct wtap_hal *hal)
244 {
245 return (hal->hw.tsf);
246 }
247