]> git.ipfire.org Git - thirdparty/iw.git/blobdiff - event.c
iw: don't use NULL pointer in nla_nest_end()
[thirdparty/iw.git] / event.c
diff --git a/event.c b/event.c
index 6775eb21759badde421f8b028254d5c68c28ed87..896f03ab7636a49b3e477581fa3744175437e27c 100644 (file)
--- a/event.c
+++ b/event.c
@@ -45,12 +45,14 @@ static void print_frame(struct print_event_args *args, struct nlattr *attr)
 {
        uint8_t *frame;
        size_t len;
-       int i;
+       unsigned int i;
        char macbuf[6*3];
        uint16_t tmp;
 
-       if (!attr)
+       if (!attr) {
                printf(" [no frame]");
+               return;
+       }
 
        frame = nla_data(attr);
        len = nla_len(attr);
@@ -80,7 +82,6 @@ static void print_frame(struct print_event_args *args, struct nlattr *attr)
                tmp = (frame[29] << 8) + frame[28];
                printf(" status: %d: %s", tmp, get_status_str(tmp));
                break;
-               break;
        case 0xa0: /* disassoc */
        case 0xc0: /* deauth */
                /* reason */
@@ -141,16 +142,22 @@ static void parse_cqm_event(struct nlattr **attrs)
 
                if (!found_one)
                        printf("Unknown event type: %i\n", rssi_event);
-       } else if (cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT] &&
-                  attrs[NL80211_ATTR_MAC]) {
-               uint32_t frames;
-               char buf[3*6];
-
-               frames = nla_get_u32(cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]);
-               mac_addr_n2a(buf, nla_data(attrs[NL80211_ATTR_MAC]));
-               printf("peer %s didn't ACK %d packets\n", buf, frames);
-       } else
+       } else if (cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]) {
+               if (attrs[NL80211_ATTR_MAC]) {
+                       uint32_t frames;
+                       char buf[3*6];
+
+                       frames = nla_get_u32(cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]);
+                       mac_addr_n2a(buf, nla_data(attrs[NL80211_ATTR_MAC]));
+                       printf("peer %s didn't ACK %d packets\n", buf, frames);
+               } else {
+                       printf("PKT-LOSS-EVENT did not have MAC attribute!\n");
+               }
+       } else if (cqm[NL80211_ATTR_CQM_BEACON_LOSS_EVENT]) {
+               printf("beacon loss\n");
+       } else {
                printf("unknown event\n");
+       }
 }
 
 static const char * key_type_str(enum nl80211_key_type key_type)
@@ -201,7 +208,8 @@ static void parse_mic_failure(struct nlattr **attrs)
 
 static void parse_wowlan_wake_event(struct nlattr **attrs)
 {
-       struct nlattr *tb[NUM_NL80211_WOWLAN_TRIG];
+       struct nlattr *tb[NUM_NL80211_WOWLAN_TRIG],
+               *tb_match[NUM_NL80211_ATTR];
 
        printf("WoWLAN wakeup\n");
        if (!attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) {
@@ -228,6 +236,31 @@ static void parse_wowlan_wake_event(struct nlattr **attrs)
                printf("\t* 4-way handshake\n");
        if (tb[NL80211_WOWLAN_TRIG_RFKILL_RELEASE])
                printf("\t* RF-kill released\n");
+       if (tb[NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS]) {
+               struct nlattr *match, *freq;
+               int rem_nst, rem_nst2;
+
+               printf("\t* network detected\n");
+               nla_for_each_nested(match,
+                                   tb[NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS],
+                                   rem_nst) {
+                       nla_parse(tb_match, NUM_NL80211_ATTR, nla_data(match),
+                                 nla_len(match),
+                                 NULL);
+                       printf("\t\tSSID: \"");
+                       print_ssid_escaped(nla_len(tb_match[NL80211_ATTR_SSID]),
+                                          nla_data(tb_match[NL80211_ATTR_SSID]));
+                       printf("\"");
+                       if (tb_match[NL80211_ATTR_SCAN_FREQUENCIES]) {
+                               printf(" freq(s):");
+                               nla_for_each_nested(freq,
+                                                   tb_match[NL80211_ATTR_SCAN_FREQUENCIES],
+                                                   rem_nst2)
+                                       printf(" %d", nla_get_u32(freq));
+                       }
+                       printf("\n");
+               }
+       }
        if (tb[NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211]) {
                uint8_t *d = nla_data(tb[NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211]);
                int l = nla_len(tb[NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211]);
@@ -334,6 +367,15 @@ static int print_event(struct nl_msg *msg, void *arg)
                }
                printf("\n");
                break;
+       case NL80211_CMD_START_SCHED_SCAN:
+               printf("scheduled scan started\n");
+               break;
+       case NL80211_CMD_SCHED_SCAN_STOPPED:
+               printf("sched scan stopped\n");
+               break;
+       case NL80211_CMD_SCHED_SCAN_RESULTS:
+               printf("got scheduled scan results\n");
+               break;
        case NL80211_CMD_REG_CHANGE:
                printf("regulatory domain change: ");
 
@@ -535,6 +577,38 @@ static int print_event(struct nl_msg *msg, void *arg)
                printf("vendor event %.6x:%d\n",
                        nla_get_u32(tb[NL80211_ATTR_VENDOR_ID]),
                        nla_get_u32(tb[NL80211_ATTR_VENDOR_SUBCMD]));
+               if (args->frame && tb[NL80211_ATTR_VENDOR_DATA])
+                       iw_hexdump("vendor event",
+                                  nla_data(tb[NL80211_ATTR_VENDOR_DATA]),
+                                  nla_len(tb[NL80211_ATTR_VENDOR_DATA]));
+               break;
+       case NL80211_CMD_RADAR_DETECT:
+               printf("radar event ");
+               if (tb[NL80211_ATTR_RADAR_EVENT]) {
+                       switch (nla_get_u32(tb[NL80211_ATTR_RADAR_EVENT])) {
+                               case NL80211_RADAR_DETECTED:
+                                       printf("(radar detected)");
+                                       break;
+                               case NL80211_RADAR_CAC_FINISHED:
+                                       printf("(cac finished)");
+                                       break;
+                               case NL80211_RADAR_CAC_ABORTED:
+                                       printf("(cac aborted)");
+                                       break;
+                               case NL80211_RADAR_NOP_FINISHED:
+                                       printf("(nop finished)");
+                                       break;
+                               default:
+                                       printf("(unknown)");
+                                       break;
+                       };
+               } else {
+                       printf("(unknown)");
+               }
+               printf("\n");
+               break;
+       case NL80211_CMD_DEL_WIPHY:
+               printf("delete wiphy\n");
                break;
        default:
                printf("unknown event %d (%s)\n",
@@ -631,14 +705,15 @@ __u32 __do_listen_events(struct nl80211_state *state,
 
        /* no sequence checking for multicast messages */
        nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
+       nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, valid_handler, NULL);
 
        if (n_waits && waits) {
                wait_ev.cmds = waits;
                wait_ev.n_cmds = n_waits;
                wait_ev.pargs = args;
-               nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, wait_event, &wait_ev);
+               register_handler(wait_event, &wait_ev);
        } else
-               nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_event, args);
+               register_handler(print_event, args);
 
        wait_ev.cmd = 0;
 
@@ -663,7 +738,6 @@ __u32 listen_events(struct nl80211_state *state,
 }
 
 static int print_events(struct nl80211_state *state,
-                       struct nl_cb *cb,
                        struct nl_msg *msg,
                        int argc, char **argv,
                        enum id_input id)
@@ -701,7 +775,7 @@ static int print_events(struct nl80211_state *state,
 
        return __do_listen_events(state, 0, NULL, &args);
 }
-TOPLEVEL(event, "[-t] [-r] [-f]", 0, 0, CIB_NONE, print_events,
+TOPLEVEL(event, "[-t|-r] [-f]", 0, 0, CIB_NONE, print_events,
        "Monitor events from the kernel.\n"
        "-t - print timestamp\n"
        "-r - print relative timstamp\n"