]> git.ipfire.org Git - thirdparty/iw.git/commitdiff
print nicer auth/assoc/deauth/disassoc events
authorJohannes Berg <johannes@sipsolutions.net>
Tue, 5 May 2009 10:19:13 +0000 (12:19 +0200)
committerJohannes Berg <johannes@sipsolutions.net>
Tue, 5 May 2009 10:19:13 +0000 (12:19 +0200)
Makefile
iw.c
iw.h
reason.c [new file with mode: 0644]

index 5fa09bfb41840b9edb430711d5e050312c503ce7..b1669c8e16aada8ccbdba0be908582f523e8de4f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -13,7 +13,7 @@ CC ?= "gcc"
 CFLAGS ?= -O2 -g
 CFLAGS += -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration
 
-OBJS = iw.o genl.o info.o phy.o interface.o ibss.o station.o util.o mesh.o mpath.o scan.o reg.o version.o
+OBJS = iw.o genl.o info.o phy.o interface.o ibss.o station.o util.o mesh.o mpath.o scan.o reg.o version.o reason.o
 ALL = iw
 
 NL1FOUND := $(shell pkg-config --atleast-version=1 libnl-1 && echo Y)
diff --git a/iw.c b/iw.c
index df69049f3f2f1600a692fa9b59d29ea5b5857f64..17b2d4c7b3f22941032c4d8011df25d031029a20 100644 (file)
--- a/iw.c
+++ b/iw.c
@@ -12,6 +12,7 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <stdbool.h>
                      
 #include <netlink/genl/genl.h>
 #include <netlink/genl/family.h>
@@ -108,7 +109,7 @@ static void usage(const char *argv0)
        fprintf(stderr, "\t--version\tshow version\n");
        fprintf(stderr, "Commands:\n");
        fprintf(stderr, "\thelp\n");
-       fprintf(stderr, "\tevent\n");
+       fprintf(stderr, "\tevent [-f]\n");
        for (cmd = &__start___cmd; cmd < &__stop___cmd;
             cmd = (struct cmd *)((char *)cmd + cmd_size)) {
                if (!cmd->handler || cmd->hidden)
@@ -328,10 +329,59 @@ static int no_seq_check(struct nl_msg *msg, void *arg)
        return NL_OK;
 }
 
+struct print_event_args {
+       bool frame;
+};
+
+static void print_frame(struct print_event_args *args, struct nlattr *attr,
+                       bool reason)
+{
+       uint8_t *frame;
+       size_t len;
+       int i;
+       char macbuf[6*3];
+
+       if (!attr)
+               printf(" [no frame]");
+
+       frame = nla_data(attr);
+       len = nla_len(attr);
+
+       if (len >= 16) {
+               mac_addr_n2a(macbuf, frame + 10);
+               printf(" %s -> ", macbuf);
+       } else
+               printf(" ??? -> ");
+
+       if (len >= 20) {
+               mac_addr_n2a(macbuf, frame + 4);
+               printf("%s", macbuf);
+       } else
+               printf("???");
+
+       if (reason) {
+               if (len >= 26) {
+                       uint16_t reason = (frame[25] << 8) + frame[24];
+                       printf(" reason %d: %s",
+                              reason, get_reason_str(reason));
+               } else
+                       printf(" reason ?: ???");
+       }
+
+       if (!args->frame)
+               return;
+
+       printf(" [frame:");
+       for (i = 0; i < len; i++)
+               printf(" %.02x", frame[i]);
+       printf("]");
+}
+
 static int print_event(struct nl_msg *msg, void *arg)
 {
        struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
        struct nlattr *tb[NL80211_ATTR_MAX + 1];
+       struct print_event_args *args = arg;
        char ifname[100];
        char macbuf[6*3];
        __u8 reg_type;
@@ -399,16 +449,24 @@ static int print_event(struct nl_msg *msg, void *arg)
                printf("IBSS %s joined\n", macbuf);
                break;
        case NL80211_CMD_AUTHENTICATE:
-               printf("auth\n");
+               printf("auth");
+               print_frame(args, tb[NL80211_ATTR_FRAME], false);
+               printf("\n");
                break;
        case NL80211_CMD_ASSOCIATE:
-               printf("assoc\n");
+               printf("assoc");
+               print_frame(args, tb[NL80211_ATTR_FRAME], false);
+               printf("\n");
                break;
        case NL80211_CMD_DEAUTHENTICATE:
-               printf("deauth\n");
+               printf("deauth");
+               print_frame(args, tb[NL80211_ATTR_FRAME], true);
+               printf("\n");
                break;
        case NL80211_CMD_DISASSOCIATE:
-               printf("disassoc\n");
+               printf("disassoc");
+               print_frame(args, tb[NL80211_ATTR_FRAME], true);
+               printf("\n");
                break;
        default:
                printf("unknown event %d\n", gnlh->cmd);
@@ -439,8 +497,9 @@ static int wait_event(struct nl_msg *msg, void *arg)
        return NL_SKIP;
 }
 
-__u32 listen_events(struct nl80211_state *state,
-                   const int n_waits, const __u32 *waits)
+static __u32 __listen_events(struct nl80211_state *state,
+                            const int n_waits, const __u32 *waits,
+                            struct print_event_args *args)
 {
        int mcid, ret;
        struct nl_cb *cb = nl_cb_alloc(debug ? NL_CB_DEBUG : NL_CB_DEFAULT);
@@ -492,7 +551,7 @@ __u32 listen_events(struct nl80211_state *state,
                wait_ev.n_cmds = n_waits;
                nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, wait_event, &wait_ev);
        } else {
-               nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_event, NULL);
+               nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_event, args);
        }
 
        wait_ev.cmd = 0;
@@ -505,6 +564,30 @@ __u32 listen_events(struct nl80211_state *state,
        return wait_ev.cmd;
 }
 
+__u32 listen_events(struct nl80211_state *state,
+                   const int n_waits, const __u32 *waits)
+{
+       return __listen_events(state, n_waits, waits, NULL);
+}
+
+static int print_events(struct nl80211_state *state, int argc, char **argv)
+{
+       struct print_event_args args;
+
+       memset(&args, 0, sizeof(args));
+
+       if (argc > 1)
+               return 1;
+
+       if (argc > 0) {
+               if (strcmp(argv[0], "-f"))
+                       return 1;
+               args.frame = true;
+       }
+
+       return __listen_events(state, 0, NULL, &args);
+}
+
 int main(int argc, char **argv)
 {
        struct nl80211_state nlstate;
@@ -539,10 +622,9 @@ int main(int argc, char **argv)
                return 1;
 
        if (strcmp(*argv, "event") == 0) {
-               if (argc != 1)
-                       err = 1;
-               else
-                       err = listen_events(&nlstate, 0, NULL);
+               argc--;
+               argv++;
+               err = print_events(&nlstate, argc, argv);
        } else if (strcmp(*argv, "dev") == 0 && argc > 1) {
                argc--;
                argv++;
diff --git a/iw.h b/iw.h
index d0781255f27253459bdffb34d3e307e531299e0f..68f0e5a9a2a6fd2b6115fac92ea16df61ba31a1a 100644 (file)
--- a/iw.h
+++ b/iw.h
@@ -87,4 +87,6 @@ int nl_get_multicast_id(struct nl_sock *sock, const char *family, const char *gr
 
 char *reg_initiator_to_string(__u8 initiator);
 
+const char *get_reason_str(uint16_t reason);
+
 #endif /* __IW_H */
diff --git a/reason.c b/reason.c
new file mode 100644 (file)
index 0000000..3045473
--- /dev/null
+++ b/reason.c
@@ -0,0 +1,50 @@
+#include <stdint.h>
+#include "iw.h"
+
+static const char *reason_table[] = {
+       [1] = "Unspecified",
+       [2] = "Previous authentication no longer valid",
+       [3] = "Deauthenticated because sending station is leaving (or has left) the IBSS or ESS",
+       [4] = "Disassociated due to inactivity",
+       [5] = "Disassociated because AP is unable to handle all currently associated STA",
+       [6] = "Class 2 frame received from non-authenticated station",
+       [7] = "Class 3 frame received from non-authenticated station",
+       [8] = "Disassociated because sending station is leaving (or has left) the BSS",
+       [9] = "Station requesting (re)association is not authenticated with responding station",
+       [10] = "Disassociated because the information in the Power Capability element is unacceptable",
+       [11] = "Disassociated because the information in the Supported Channels element is unacceptable",
+       [13] = "Invalid information element",
+       [14] = "MIC failure",
+       [15] = "4-way handshake timeout",
+       [16] = "Group key update timeout",
+       [17] = "Information element in 4-way handshake different from (Re-)associate request/Probe response/Beacon",
+       [18] = "Multicast cipher is not valid",
+       [19] = "Unicast cipher is not valid",
+       [20] = "AKMP is not valid",
+       [21] = "Unsupported RSNE version",
+       [22] = "Invalid RSNE capabilities",
+       [23] = "IEEE 802.1X authentication failed",
+       [24] = "Cipher Suite rejected per security policy",
+       [31] = "TS deleted because QoS AP lacks sufficient bandwidth for this QoS STA due to a change in BSS service characteristics or operational mode",
+       [32] = "Disassociated for unspecified] =  QoS-related reason",
+       [33] = "Disassociated because QAP lacks sufficient bandwidth for this STA",
+       [34] = "Disassociated because of excessive frame losses and/or poor channel conditions",
+       [35] = "Disassociated because QSTA is transmitting outside the limits of its polled TXOPs",
+       [36] = "Requested from peer QSTA as the QSTA is leaving the QBSS (or resetting)",
+       [37] = "Requested from peer QSTA as it does not want to use Traffic Stream",
+       [38] = "Requested from peer QSTA as the QSTA received frames indicated Traffic Stream for which it has not set up",
+       [39] = "Requested from peer QSTA due to time out",
+       [40] = "Requested from peer QSTA as the QSTA is leaving the QBSS (or resetting)",
+       [41] = "Requested from peer QSTA as it does not want to receive frames directly from the QSTA",
+       [42] = "Requested from peer QSTA as the QSTA received DLP frames for which it has not set up",
+       [43] = "Requested from peer QSTA as it does not want to use Block Ack",
+       [44] = "Requested from peer QSTA as the QSTA received frames indicated Block Acknowledgement policy for which it has not set up",
+       [45] = "Peer QSTA does not support the requested cipher suite",
+};
+
+const char *get_reason_str(uint16_t reason)
+{
+       if (reason < ARRAY_SIZE(reason_table) && reason_table[reason])
+               return reason_table[reason];
+       return "<unknown>";
+}