2 * wprobe-test.c: Wireless probe user space test code
3 * Copyright (C) 2008-2009 Felix Fietkau <nbd@openwrt.org>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <sys/types.h>
17 #include <sys/socket.h>
19 #include <arpa/inet.h>
33 #include <linux/wprobe.h>
36 static bool simple_mode
= false;
39 wprobe_dump_value(struct wprobe_attribute
*attr
)
43 #define HANDLE_TYPE(_type, _format) \
44 case WPROBE_VAL_##_type: \
45 snprintf(buf, sizeof(buf), _format, attr->val._type); \
49 HANDLE_TYPE(S8
, "%d");
50 HANDLE_TYPE(S16
, "%d");
51 HANDLE_TYPE(S32
, "%d");
52 HANDLE_TYPE(S64
, "%lld");
53 HANDLE_TYPE(U8
, "%d");
54 HANDLE_TYPE(U16
, "%d");
55 HANDLE_TYPE(U32
, "%d");
56 HANDLE_TYPE(U64
, "%lld");
57 case WPROBE_VAL_STRING
:
58 /* FIXME: implement this */
60 strncpy(buf
, "<unknown>", sizeof(buf
));
63 if ((attr
->flags
& WPROBE_F_KEEPSTAT
) &&
65 int len
= strlen(buf
);
67 snprintf(buf
+ len
, sizeof(buf
) - len
, ";%.02f;%.02f;%d;%lld;%lld", attr
->val
.avg
, attr
->val
.stdev
, attr
->val
.n
, attr
->val
.s
, attr
->val
.ss
);
69 snprintf(buf
+ len
, sizeof(buf
) - len
, " (avg: %.02f; stdev: %.02f, n=%d)", attr
->val
.avg
, attr
->val
.stdev
, attr
->val
.n
);
78 wprobe_dump_data(struct wprobe_iface
*dev
)
80 struct wprobe_attribute
*attr
;
81 struct wprobe_link
*link
;
85 fprintf(stdout
, "\n");
86 wprobe_request_data(dev
, NULL
);
87 list_for_each_entry(attr
, &dev
->global_attr
, list
) {
90 fprintf(stdout
, "[global]\n");
91 fprintf(stdout
, "%s=%s\n", attr
->name
, wprobe_dump_value(attr
));
93 fprintf(stdout
, (first
?
97 wprobe_dump_value(attr
)
103 list_for_each_entry(link
, &dev
->links
, list
) {
105 wprobe_request_data(dev
, link
->addr
);
106 list_for_each_entry(attr
, &dev
->link_attr
, list
) {
110 "[%02x:%02x:%02x:%02x:%02x:%02x]\n%s=%s\n" :
111 "%02x:%02x:%02x:%02x:%02x:%02x: %s=%s\n"),
112 link
->addr
[0], link
->addr
[1], link
->addr
[2],
113 link
->addr
[3], link
->addr
[4], link
->addr
[5],
115 wprobe_dump_value(attr
));
119 (simple_mode
? "%s=%s\n" :
122 wprobe_dump_value(attr
));
129 static const char *attr_typestr
[] = {
131 [WPROBE_VAL_STRING
] = "String",
132 [WPROBE_VAL_U8
] = "Unsigned 8 bit",
133 [WPROBE_VAL_U16
] = "Unsigned 16 bit",
134 [WPROBE_VAL_U32
] = "Unsigned 32 bit",
135 [WPROBE_VAL_U64
] = "Unsigned 64 bit",
136 [WPROBE_VAL_S8
] = "Signed 8 bit",
137 [WPROBE_VAL_S16
] = "Signed 16 bit",
138 [WPROBE_VAL_S32
] = "Signed 32 bit",
139 [WPROBE_VAL_S64
] = "Signed 64 bit",
142 static int usage(const char *prog
)
145 #ifndef NO_LOCAL_ACCESS
146 "Usage: %s <interface>|<host>:<device>|-P [options]\n"
148 "Usage: %s <host>:<device> [options]\n"
152 " -c: Only apply configuration\n"
153 " -d: Delay between measurement dumps (in milliseconds, default: 1000)\n"
154 " -f: Dump contents of layer 2 filter counters during measurement\n"
155 " -F <file>: Apply layer 2 filters from <file>\n"
156 " -h: This help text\n"
157 " -i <interval>: Set measurement interval\n"
158 " -m: Run measurement loop\n"
159 " -p: Set the TCP port for server/client (default: 17990)\n"
160 #ifndef NO_LOCAL_ACCESS
161 " -P: Run in proxy mode (listen on network)\n"
168 static void show_attributes(struct wprobe_iface
*dev
)
170 struct wprobe_attribute
*attr
;
173 list_for_each_entry(attr
, &dev
->global_attr
, list
) {
174 fprintf(stdout
, "Global attribute: '%s' (%s)\n",
175 attr
->name
, attr_typestr
[attr
->type
]);
177 list_for_each_entry(attr
, &dev
->link_attr
, list
) {
178 fprintf(stdout
, "Link attribute: '%s' (%s)\n",
179 attr
->name
, attr_typestr
[attr
->type
]);
183 static void show_filter_simple(void *arg
, const char *group
, struct wprobe_filter_item
*items
, int n_items
)
187 fprintf(stdout
, "[filter:%s]\n", group
);
188 for (i
= 0; i
< n_items
; i
++) {
189 fprintf(stdout
, "%s=%lld;%lld\n",
190 items
[i
].name
, items
[i
].tx
, items
[i
].rx
);
196 static void show_filter(void *arg
, const char *group
, struct wprobe_filter_item
*items
, int n_items
)
199 fprintf(stdout
, "Filter group: '%s' (tx/rx)\n", group
);
200 for (i
= 0; i
< n_items
; i
++) {
201 fprintf(stdout
, " - %s (%lld/%lld)\n",
202 items
[i
].name
, items
[i
].tx
, items
[i
].rx
);
206 static void loop_measurement(struct wprobe_iface
*dev
, bool print_filters
, unsigned long delay
)
209 usleep(delay
* 1000);
210 wprobe_update_links(dev
);
211 wprobe_dump_data(dev
);
213 wprobe_dump_filters(dev
, simple_mode
? show_filter_simple
: show_filter
, NULL
);
217 static void set_filter(struct wprobe_iface
*dev
, const char *filename
)
219 unsigned char *buf
= NULL
;
220 unsigned int buflen
= 0;
221 unsigned int len
= 0;
225 if (filename
[0] == 0) {
226 dev
->filter_len
= -1;
230 fd
= open(filename
, O_RDONLY
);
232 perror("open filter");
245 buf
= realloc(buf
, buflen
);
247 rlen
= read(fd
, buf
+ len
, buflen
- len
);
252 } while (len
== buflen
);
255 dev
->filter_len
= len
;
259 #ifndef NO_LOCAL_ACCESS
261 static void sigchld_handler(int s
)
263 while (waitpid(-1, NULL
, WNOHANG
) > 0);
266 static int run_proxy(int port
)
268 struct sockaddr_in sa
;
269 struct sigaction sig
;
273 s
= socket(AF_INET
, SOCK_STREAM
, 0);
279 sig
.sa_handler
= sigchld_handler
; // Signal Handler fuer Zombie Prozesse
280 sigemptyset(&sig
.sa_mask
);
281 sig
.sa_flags
= SA_RESTART
;
282 sigaction(SIGCHLD
, &sig
, NULL
);
284 memset(&sa
, 0, sizeof(sa
));
285 sa
.sin_family
= AF_INET
;
286 sa
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
287 sa
.sin_port
= htons(wprobe_port
);
289 setsockopt(s
, SOL_SOCKET
, SO_REUSEADDR
, &v
, sizeof(v
));
290 if (bind(s
, (struct sockaddr
*) &sa
, sizeof(sa
)) < 0) {
299 unsigned int addrlen
= sizeof(struct sockaddr_in
);
302 c
= accept(s
, (struct sockaddr
*)&sa
, &addrlen
);
311 /* close server socket, stdin, stdout, stderr */
317 wprobe_server_init(c
);
319 ret
= wprobe_server_handle(c
);
321 wprobe_server_done();
332 int main(int argc
, char **argv
)
334 struct wprobe_iface
*dev
= NULL
;
336 const char *prog
= argv
[0];
344 const char *filter
= NULL
;
345 bool print_filters
= false;
346 unsigned long delay
= 1000;
353 #ifndef NO_LOCAL_ACCESS
354 if (!strcmp(argv
[1], "-P")) {
355 while ((ch
= getopt(argc
- 1, argv
+ 1, "p:")) != -1) {
359 wprobe_port
= strtoul(optarg
, NULL
, 0);
365 return run_proxy(wprobe_port
);
369 if (argv
[1][0] == '-')
376 while ((ch
= getopt(argc
, argv
, "cd:fF:hi:msp:")) != -1) {
382 delay
= strtoul(optarg
, NULL
, 10);
388 interval
= strtoul(optarg
, NULL
, 10);
391 print_filters
= true;
395 fprintf(stderr
, "Cannot set multiple filters\n");
405 wprobe_port
= strtoul(optarg
, NULL
, 0);
414 dev
= wprobe_get_auto(ifname
, &err
);
415 if (!dev
|| (list_empty(&dev
->global_attr
) &&
416 list_empty(&dev
->link_attr
))) {
418 fprintf(stdout
, "%s\n", err
);
420 fprintf(stderr
, "Interface '%s' not found\n", ifname
);
424 if (filter
|| interval
>= 0) {
426 set_filter(dev
, filter
);
428 dev
->interval
= interval
;
430 wprobe_apply_config(dev
);
433 if (cmd
!= CMD_CONFIG
)
434 show_attributes(dev
);
435 if (cmd
== CMD_MEASURE
)
436 loop_measurement(dev
, print_filters
, delay
);
438 wprobe_free_dev(dev
);
This page took 0.066696 seconds and 5 git commands to generate.