• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/usteer/fakeap.c

  1 /*
  2  *   This program is free software; you can redistribute it and/or modify
  3  *   it under the terms of the GNU General Public License as published by
  4  *   the Free Software Foundation; either version 2 of the License.
  5  *
  6  *   This program is distributed in the hope that it will be useful,
  7  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  8  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9  *   GNU General Public License for more details.
 10  *
 11  *   You should have received a copy of the GNU General Public License
 12  *   along with this program; if not, write to the Free Software
 13  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 14  *
 15  *   Copyright (C) 2020 embedd.ch 
 16  *   Copyright (C) 2020 Felix Fietkau <nbd@nbd.name> 
 17  *   Copyright (C) 2020 John Crispin <john@phrozen.org> 
 18  */
 19 
 20 #include <libubox/blobmsg.h>
 21 #include <libubus.h>
 22 #include <stdio.h>
 23 #include <getopt.h>
 24 #include "utils.h"
 25 #include "timeout.h"
 26 
 27 static struct blob_buf b;
 28 static LIST_HEAD(stations);
 29 static struct usteer_timeout_queue tq;
 30 static FILE *r_fd;
 31 static struct ubus_object bss_obj;
 32 static struct ubus_context *ubus_ctx;
 33 static int freq = 2412;
 34 static int verbose;
 35 
 36 struct var {
 37         int cur;
 38         int min;
 39         int max;
 40 };
 41 
 42 struct sta_data {
 43         struct list_head list;
 44         struct usteer_timeout probe_t;
 45         struct var probe;
 46         struct var signal;
 47         uint8_t addr[6];
 48 };
 49 
 50 static void gen_val(struct var *val)
 51 {
 52         int delta = val->max - val->min;
 53         uint8_t v;
 54 
 55         val->cur = val->min;
 56         if (!delta)
 57                 return;
 58 
 59         if (fread(&v, sizeof(v), 1, r_fd) != sizeof(v))
 60                 fprintf(stderr, "short read\n");
 61         val->cur += (((unsigned int) v) * delta) / 0xff;
 62 }
 63 
 64 static void
 65 blobmsg_add_macaddr(struct blob_buf *buf, const char *name, const uint8_t *addr)
 66 {
 67         char *s = blobmsg_alloc_string_buffer(buf, name, 20);
 68         sprintf(s, MAC_ADDR_FMT, MAC_ADDR_DATA(addr));
 69         blobmsg_add_string_buffer(buf);
 70 }
 71 
 72 static void sta_send_probe(struct sta_data *sta)
 73 {
 74         const char *type = "probe";
 75         int ret;
 76         int sig = -95 + sta->signal.cur;
 77 
 78         blob_buf_init(&b, 0);
 79         blobmsg_add_macaddr(&b, "address", sta->addr);
 80         blobmsg_add_u32(&b, "freq", freq);
 81         blobmsg_add_u32(&b, "signal", sig);
 82         ret = ubus_notify(ubus_ctx, &bss_obj, type, b.head, 100);
 83         if (verbose)
 84                 fprintf(stderr, "STA "MAC_ADDR_FMT" probe: %d (%d ms, signal: %d)\n",
 85                         MAC_ADDR_DATA(sta->addr), ret, sta->probe.cur, sig);
 86 }
 87 
 88 static void sta_schedule_probe(struct sta_data *sta)
 89 {
 90         gen_val(&sta->probe);
 91         gen_val(&sta->signal);
 92         usteer_timeout_set(&tq, &sta->probe_t, sta->probe.cur);
 93 }
 94 
 95 static void sta_probe(struct usteer_timeout_queue *q, struct usteer_timeout *t)
 96 {
 97         struct sta_data *sta = container_of(t, struct sta_data, probe_t);
 98 
 99         sta_send_probe(sta);
100         sta_schedule_probe(sta);
101 }
102 
103 static void init_station(struct sta_data *sta)
104 {
105         list_add_tail(&sta->list, &stations);
106         if (fread(&sta->addr, sizeof(sta->addr), 1, r_fd) != sizeof(sta->addr))
107                 fprintf(stderr, "short read\n");
108         sta->addr[0] &= ~1;
109 
110         sta_schedule_probe(sta);
111 }
112 
113 static void create_stations(struct sta_data *ref, int n)
114 {
115         struct sta_data *sta;
116         int i;
117 
118         tq.cb = sta_probe;
119         sta = calloc(n, sizeof(*sta));
120         for (i = 0; i < n; i++) {
121                 memcpy(sta, ref, sizeof(*sta));
122                 init_station(sta);
123                 sta++;
124         }
125 }
126 
127 static int usage(const char *prog)
128 {
129         fprintf(stderr, "Usage: %s <options>\n"
130                 "Options:\n"
131                 "       -p <msec>[-<msec>]:             probing interval (fixed or min-max)\n"
132                 "       -s <rssi>[-<rssi>]:             rssi (signal strength) (fixed or min-max)\n"
133                 "       -n <n>:                         create <n> stations\n"
134                 "       -f <freq>:                      set operating frequency\n"
135                 "                                       uses parameters set before this option\n"
136                 "       -v:                             verbose\n"
137                 "\n", prog);
138         return 1;
139 }
140 
141 static bool parse_var(struct var *var, const char *str)
142 {
143         char *err;
144 
145         var->min = strtoul(str, &err, 0);
146         var->max = var->min;
147         if (!*err)
148                 return true;
149 
150         if (*err != ':')
151                 return false;
152 
153         var->max = strtoul(err + 1, &err, 0);
154         if (!*err)
155                 return true;
156 
157         return false;
158 }
159 
160 static int
161 hostapd_bss_get_clients(struct ubus_context *ctx, struct ubus_object *obj,
162                         struct ubus_request_data *req, const char *method,
163                         struct blob_attr *msg)
164 {
165         blob_buf_init(&b, 0);
166         ubus_send_reply(ctx, req, b.head);
167         return 0;
168 }
169 
170 static const struct ubus_method bss_methods[] = {
171         UBUS_METHOD_NOARG("get_clients", hostapd_bss_get_clients),
172 };
173 
174 static struct ubus_object_type bss_object_type =
175         UBUS_OBJECT_TYPE("hostapd_bss", bss_methods);
176 
177 static struct ubus_object bss_obj = {
178         .name = "hostapd.wlan0",
179         .type = &bss_object_type,
180         .methods = bss_methods,
181         .n_methods = ARRAY_SIZE(bss_methods),
182 };
183 
184 int main(int argc, char **argv)
185 {
186         struct sta_data sdata = {
187                 .signal = { 0, -30, -30 },
188                 .probe = { 0, 1000, 30000 },
189         };
190         int ch;
191 
192         uloop_init();
193 
194         r_fd = fopen("/dev/urandom", "r");
195         if (!r_fd) {
196                 perror("fopen");
197                 return 1;
198         }
199 
200         usteer_timeout_init(&tq);
201 
202         while ((ch = getopt(argc, argv, "p:s:f:n:v")) != -1) {
203                 switch(ch) {
204                 case 'p':
205                         if (!parse_var(&sdata.probe, optarg))
206                                 goto usage;
207                         break;
208                 case 's':
209                         if (!parse_var(&sdata.signal, optarg))
210                                 goto usage;
211                         break;
212                 case 'f':
213                         freq = atoi(optarg);
214                         break;
215                 case 'n':
216                         create_stations(&sdata, atoi(optarg));
217                         break;
218                 case 'v':
219                         verbose++;
220                         break;
221                 default:
222                         goto usage;
223                 }
224         }
225 
226         ubus_ctx = ubus_connect(NULL);
227         if (!ubus_ctx) {
228                 fprintf(stderr, "Failed to connect to ubus\n");
229                 return 1;
230         }
231 
232         ubus_add_uloop(ubus_ctx);
233 
234         if (ubus_add_object(ubus_ctx, &bss_obj)) {
235                 fprintf(stderr, "Failed to register AP ubus object\n");
236                 return 1;
237         }
238         uloop_run();
239 
240         uloop_done();
241         return 0;
242 usage:
243         return usage(argv[0]);
244 }
245 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt