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 " -a: Print attributes\n"
153 " -c: Only apply configuration\n"
154 " -d: Delay between measurement dumps (in milliseconds, default: 1000)\n"
155 " A value of 0 (zero) prints once and exits; useful for scripts\n"
156 " -f: Dump contents of layer 2 filter counters during measurement\n"
157 " -F <file>: Apply layer 2 filters from <file>\n"
158 " -h: This help text\n"
159 " -i <interval>: Set measurement interval\n"
160 " -m: Run measurement loop\n"
161 " -p: Set the TCP port for server/client (default: 17990)\n"
162 #ifndef NO_LOCAL_ACCESS
163 " -P: Run in proxy mode (listen on network)\n"
170 static void show_attributes(struct wprobe_iface
*dev
)
172 struct wprobe_attribute
*attr
;
175 list_for_each_entry(attr
, &dev
->global_attr
, list
) {
176 fprintf(stdout
, "Global attribute: '%s' (%s)\n",
177 attr
->name
, attr_typestr
[attr
->type
]);
179 list_for_each_entry(attr
, &dev
->link_attr
, list
) {
180 fprintf(stdout
, "Link attribute: '%s' (%s)\n",
181 attr
->name
, attr_typestr
[attr
->type
]);
185 static void show_filter_simple(void *arg
, const char *group
, struct wprobe_filter_item
*items
, int n_items
)
189 fprintf(stdout
, "[filter:%s]\n", group
);
190 for (i
= 0; i
< n_items
; i
++) {
191 fprintf(stdout
, "%s=%lld;%lld\n",
192 items
[i
].name
, items
[i
].tx
, items
[i
].rx
);
198 static void show_filter(void *arg
, const char *group
, struct wprobe_filter_item
*items
, int n_items
)
201 fprintf(stdout
, "Filter group: '%s' (tx/rx)\n", group
);
202 for (i
= 0; i
< n_items
; i
++) {
203 fprintf(stdout
, " - %s (%lld/%lld)\n",
204 items
[i
].name
, items
[i
].tx
, items
[i
].rx
);
208 static void loop_measurement(struct wprobe_iface
*dev
, bool print_filters
, unsigned long delay
)
211 wprobe_update_links(dev
);
212 wprobe_dump_data(dev
);
214 wprobe_dump_filters(dev
, simple_mode
? show_filter_simple
: show_filter
, NULL
);
215 usleep(delay
* 1000);
220 static void set_filter(struct wprobe_iface
*dev
, const char *filename
)
222 unsigned char *buf
= NULL
;
223 unsigned int buflen
= 0;
224 unsigned int len
= 0;
228 if (filename
[0] == 0) {
229 dev
->filter_len
= -1;
233 fd
= open(filename
, O_RDONLY
);
235 perror("open filter");
248 buf
= realloc(buf
, buflen
);
250 rlen
= read(fd
, buf
+ len
, buflen
- len
);
255 } while (len
== buflen
);
258 dev
->filter_len
= len
;
262 #ifndef NO_LOCAL_ACCESS
264 static void sigchld_handler(int s
)
266 while (waitpid(-1, NULL
, WNOHANG
) > 0);
269 static int run_proxy(int port
)
271 struct sockaddr_in sa
;
272 struct sigaction sig
;
276 s
= socket(AF_INET
, SOCK_STREAM
, 0);
282 sig
.sa_handler
= sigchld_handler
; // Signal Handler fuer Zombie Prozesse
283 sigemptyset(&sig
.sa_mask
);
284 sig
.sa_flags
= SA_RESTART
;
285 sigaction(SIGCHLD
, &sig
, NULL
);
287 memset(&sa
, 0, sizeof(sa
));
288 sa
.sin_family
= AF_INET
;
289 sa
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
290 sa
.sin_port
= htons(wprobe_port
);
292 setsockopt(s
, SOL_SOCKET
, SO_REUSEADDR
, &v
, sizeof(v
));
293 if (bind(s
, (struct sockaddr
*) &sa
, sizeof(sa
)) < 0) {
302 unsigned int addrlen
= sizeof(struct sockaddr_in
);
305 c
= accept(s
, (struct sockaddr
*)&sa
, &addrlen
);
314 /* close server socket, stdin, stdout, stderr */
320 wprobe_server_init(c
);
322 ret
= wprobe_server_handle(c
);
324 wprobe_server_done();
335 int main(int argc
, char **argv
)
337 struct wprobe_iface
*dev
= NULL
;
339 const char *prog
= argv
[0];
347 const char *filter
= NULL
;
348 bool print_attributes
= false;
349 bool print_filters
= false;
350 unsigned long delay
= 1000;
357 #ifndef NO_LOCAL_ACCESS
358 if (!strcmp(argv
[1], "-P")) {
359 while ((ch
= getopt(argc
- 1, argv
+ 1, "p:")) != -1) {
363 wprobe_port
= strtoul(optarg
, NULL
, 0);
369 return run_proxy(wprobe_port
);
373 if (argv
[1][0] == '-')
380 while ((ch
= getopt(argc
, argv
, "acd:fF:hi:msp:")) != -1) {
383 print_attributes
= true;
389 delay
= strtoul(optarg
, NULL
, 10);
395 interval
= strtoul(optarg
, NULL
, 10);
398 print_filters
= true;
402 fprintf(stderr
, "Cannot set multiple filters\n");
412 wprobe_port
= strtoul(optarg
, NULL
, 0);
421 dev
= wprobe_get_auto(ifname
, &err
);
422 if (!dev
|| (list_empty(&dev
->global_attr
) &&
423 list_empty(&dev
->link_attr
))) {
425 fprintf(stdout
, "%s\n", err
);
427 fprintf(stderr
, "Interface '%s' not found\n", ifname
);
431 if (filter
|| interval
>= 0) {
433 set_filter(dev
, filter
);
435 dev
->interval
= interval
;
437 wprobe_apply_config(dev
);
440 if (cmd
!= CMD_CONFIG
) {
441 if (print_attributes
)
442 show_attributes(dev
);
444 if (cmd
== CMD_MEASURE
)
445 loop_measurement(dev
, print_filters
, delay
);
447 wprobe_free_dev(dev
);
This page took 0.080875 seconds and 5 git commands to generate.