static int handle_mpp_get(struct nl80211_state *state, struct nl_msg *msg, int argc, char **argv, enum id_input id) { unsigned char dst[ETH_ALEN]; if (argc < 1) return 1; if (mac_addr_a2n(dst, argv[0])) { fprintf(stderr, "invalid mac address\n"); return 2; } argc--; argv++; if (argc) return 1; NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, dst); register_handler(print_mpp_handler, NULL); return 0; nla_put_failure: return -ENOBUFS; }
static int handle_interface_wds_peer(struct nl80211_state *state, struct nl_cb *cb, struct nl_msg *msg, int argc, char **argv, enum id_input id) { unsigned char mac_addr[ETH_ALEN]; if (argc < 1) return 1; if (mac_addr_a2n(mac_addr, argv[0])) { fprintf(stderr, "Invalid MAC address\n"); return 2; } argc--; argv++; if (argc) return 1; NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr); return 0; nla_put_failure: return -ENOBUFS; }
int parse_assoc_list_string(char* str) { if (str) { int i,j; unsigned char mac[6]; char assoc_string[IW_LIST_MAXSIZE]; char assoc_params[8][32]; char assoc_signal[3][32]; char* s = NULL; memset(mac,0x00,sizeof(mac)); memset(assoc_string,0x00,IW_LIST_MAXSIZE); strcpy(assoc_string,str); // "00:03:7F:04:00:01| -49/-101/52| 0| 5.4 MCS2 s| 5.4 MCS2 s| 9542| 2821" for (s = assoc_string, j = 0; j < 8 && s; j ++) { memset (assoc_params[j],0x00,32); s = parse_assoc_entry(s,'|',assoc_params[j]); // printf("[%d] %s\n",j,assoc_params[j]); } if (j >= 6) { MPATH_INFO info; mac_addr_a2n(info.m_mac_dest_add,assoc_params[0]); for (s = assoc_params[1], j = 0; j < 3 && s; j ++) { memset (assoc_signal[j],0x00,32); s = parse_assoc_entry(s,'/',assoc_signal[j]); } if (j > 1) { info.m_signal = atoi(assoc_signal[0]); info.m_noise = atoi(assoc_signal[1]); int snr = info.m_signal - info.m_noise; if (snr < 0) return 0; if (snr > 100) return 100; return snr; } // info.m_mcs_rx = (unsigned short) (10 * atof(assoc_params[3])); // info.m_mcs_tx = (unsigned short) (10 * atof(assoc_params[4])); return 0; } return 0; } return 0; }
static int npi_set_mac_cmd(struct nlnpi_state *state, struct nl_cb *cb, struct nl_msg *msg, int argc, char **argv) { unsigned char addr[6]; if (argc != 1 || !argv) return 1; if (mac_addr_a2n(addr, argv[0]) == 0) { NLA_PUT(msg, NLNPI_ATTR_SET_MAC, 6, addr); } else { fprintf(stderr, "ret: invalid mac address :end\n"); return 2; } nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_reply_status, NULL); return 0; nla_put_failure: return -ENOBUFS; }
static int iw_auth(struct nl80211_state *state, struct nl_msg *msg, int argc, char **argv, enum id_input id) { char *end; unsigned char bssid[6]; int freq; bool need_key = false; if (argc < 4) return 1; /* SSID */ NLA_PUT(msg, NL80211_ATTR_SSID, strlen(argv[0]), argv[0]); argv++; argc--; /* bssid */ if (mac_addr_a2n(bssid, argv[0]) == 0) { NLA_PUT(msg, NL80211_ATTR_MAC, 6, bssid); argv++; argc--; } else { return 1; } /* FIXME */ if (strcmp(argv[0], "open") == 0) { NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE, NL80211_AUTHTYPE_OPEN_SYSTEM); } else if (strcmp(argv[0], "shared") == 0) { NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE, NL80211_AUTHTYPE_SHARED_KEY); need_key = true; } else { return 1; } argv++; argc--; freq = strtoul(argv[0], &end, 10); if (*end == '\0') { NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); argv++; argc--; } else { return 1; } if (!argc && need_key) return 1; if (argc && !need_key) return 1; if (!argc) return 0; if (strcmp(*argv, "key") != 0 && strcmp(*argv, "keys") != 0) return 1; argv++; argc--; return parse_keys(msg, &argv, &argc); nla_put_failure: return -ENOSPC; }
static int iw_conn(struct nl80211_state *state, struct nl_msg *msg, int argc, char **argv, enum id_input id) { char *end; unsigned char bssid[6]; int freq; int ret; if (argc < 1) return 1; /* SSID */ NLA_PUT(msg, NL80211_ATTR_SSID, strlen(argv[0]), argv[0]); argv++; argc--; /* freq */ if (argc) { freq = strtoul(argv[0], &end, 10); if (*end == '\0') { NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); argv++; argc--; } } /* bssid */ if (argc) { if (mac_addr_a2n(bssid, argv[0]) == 0) { NLA_PUT(msg, NL80211_ATTR_MAC, 6, bssid); argv++; argc--; } } /* channel width */ if (argc) { if (strcmp("width", argv[0]) == 0) { int width; argv++; argc--; if (argc) { width = parse_chan_width(argv[0]); if (width < 0) goto nla_put_failure; NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH, width); argv++; argc--; } else { goto nla_put_failure; } } } if (!argc) return 0; if (strcmp(*argv, "key") != 0 && strcmp(*argv, "keys") != 0) return 1; argv++; argc--; ret = parse_keys(msg, &argv, &argc); if (ret) return ret; if (!argc) return 0; if (!strcmp(*argv, "mfp:req")) NLA_PUT_U32(msg, NL80211_ATTR_USE_MFP, NL80211_MFP_REQUIRED); else if (!strcmp(*argv, "mfp:opt")) NLA_PUT_U32(msg, NL80211_ATTR_USE_MFP, NL80211_MFP_OPTIONAL); else if (!strcmp(*argv, "mfp:no")) NLA_PUT_U32(msg, NL80211_ATTR_USE_MFP, NL80211_MFP_NO); else return -EINVAL; return 0; nla_put_failure: return -ENOSPC; }
static int wowlan_parse_tcp_file(struct nl_msg *msg, const char *fn) { char buf[16768]; int err = 1; FILE *f = fopen(fn, "r"); struct nlattr *tcp; if (!f) return 1; tcp = nla_nest_start(msg, NL80211_WOWLAN_TRIG_TCP_CONNECTION); if (!tcp) goto nla_put_failure; while (!feof(f)) { char *eol; if (!fgets(buf, sizeof(buf), f)) break; eol = strchr(buf + 5, '\r'); if (eol) *eol = 0; eol = strchr(buf + 5, '\n'); if (eol) *eol = 0; if (strncmp(buf, "source=", 7) == 0) { struct in_addr in_addr; char *addr = buf + 7; char *port = strchr(buf + 7, ':'); if (port) { *port = 0; port++; } if (inet_aton(addr, &in_addr) == 0) goto close; NLA_PUT_U32(msg, NL80211_WOWLAN_TCP_SRC_IPV4, in_addr.s_addr); if (port) NLA_PUT_U16(msg, NL80211_WOWLAN_TCP_SRC_PORT, atoi(port)); } else if (strncmp(buf, "dest=", 5) == 0) { struct in_addr in_addr; char *addr = buf + 5; char *port = strchr(buf + 5, ':'); char *mac; unsigned char macbuf[6]; if (!port) goto close; *port = 0; port++; mac = strchr(port, '@'); if (!mac) goto close; *mac = 0; mac++; if (inet_aton(addr, &in_addr) == 0) goto close; NLA_PUT_U32(msg, NL80211_WOWLAN_TCP_DST_IPV4, in_addr.s_addr); NLA_PUT_U16(msg, NL80211_WOWLAN_TCP_DST_PORT, atoi(port)); if (mac_addr_a2n(macbuf, mac)) goto close; NLA_PUT(msg, NL80211_WOWLAN_TCP_DST_MAC, 6, macbuf); } else if (strncmp(buf, "data=", 5) == 0) { size_t len; unsigned char *pkt = parse_hex(buf + 5, &len); if (!pkt) goto close; NLA_PUT(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD, len, pkt); free(pkt); } else if (strncmp(buf, "data.interval=", 14) == 0) { NLA_PUT_U32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL, atoi(buf + 14)); } else if (strncmp(buf, "wake=", 5) == 0) { unsigned char *pat, *mask; size_t patlen; if (parse_hex_mask(buf + 5, &pat, &patlen, &mask)) goto close; NLA_PUT(msg, NL80211_WOWLAN_TCP_WAKE_MASK, DIV_ROUND_UP(patlen, 8), mask); NLA_PUT(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD, patlen, pat); free(mask); free(pat); } else if (strncmp(buf, "data.seq=", 9) == 0) { struct nl80211_wowlan_tcp_data_seq seq = {}; char *len, *offs, *start; len = buf + 9; offs = strchr(len, ','); if (!offs) goto close; *offs = 0; offs++; start = strchr(offs, ','); if (start) { *start = 0; start++; seq.start = atoi(start); } seq.len = atoi(len); seq.offset = atoi(offs); NLA_PUT(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ, sizeof(seq), &seq); } else if (strncmp(buf, "data.tok=", 9) == 0) { struct nl80211_wowlan_tcp_data_token *tok; size_t stream_len; char *len, *offs, *toks; unsigned char *stream; len = buf + 9; offs = strchr(len, ','); if (!offs) goto close; *offs = 0; offs++; toks = strchr(offs, ','); if (!toks) goto close; *toks = 0; toks++; stream = parse_hex(toks, &stream_len); if (!stream) goto close; tok = malloc(sizeof(*tok) + stream_len); if (!tok) { free(stream); err = -ENOMEM; goto close; } tok->len = atoi(len); tok->offset = atoi(offs); memcpy(tok->token_stream, stream, stream_len); NLA_PUT(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN, sizeof(*tok) + stream_len, tok); free(stream); free(tok); } else { if (buf[0] == '#') continue; goto close; } } err = 0; goto close; nla_put_failure: err = -ENOBUFS; close: fclose(f); nla_nest_end(msg, tcp); return err; }