X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=vendor.c;h=d203d8522d4fb24376b6ca86dafc8bf8d362113f;hb=fc38d3e86ebf2f4130e017d129487b128c8a28fe;hp=d0b4f9ef4d5cc966b639b0141622fb9c91fa20f2;hpb=5f1706846329cf43e8e468403ed6dc34f792cf94;p=thirdparty%2Fiw.git diff --git a/vendor.c b/vendor.c index d0b4f9e..d203d85 100644 --- a/vendor.c +++ b/vendor.c @@ -12,9 +12,37 @@ SECTION(vendor); +static int print_vendor_response(struct nl_msg *msg, void *arg) +{ + struct nlattr *attr; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + bool print_ascii = (bool) arg; + uint8_t *data; + int len; + + attr = nla_find(genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), + NL80211_ATTR_VENDOR_DATA); + if (!attr) { + fprintf(stderr, "vendor data attribute missing!\n"); + return NL_SKIP; + } + + data = (uint8_t *) nla_data(attr); + len = nla_len(attr); + + if (print_ascii) + iw_hexdump("vendor response", data, len); + else + fwrite(data, 1, len, stdout); + + return NL_OK; +} + static int read_file(FILE *file, char *buf, size_t size) { - int data, count = 0; + size_t count = 0; + int data; while ((data = fgetc(file)) != EOF) { if (count >= size) @@ -26,10 +54,10 @@ static int read_file(FILE *file, char *buf, size_t size) return count; } -static int read_hex(int argc, char **argv, char *buf, size_t size) +static int read_hex(unsigned int argc, char **argv, char *buf, size_t size) { - int i, res; - unsigned int data; + unsigned int i, data; + int res; if (argc > size) return -EINVAL; @@ -55,15 +83,19 @@ static int handle_vendor(struct nl80211_state *state, FILE *file = NULL; if (argc < 3) - return -EINVAL; + return 1; res = sscanf(argv[0], "0x%x", &oui); - if (res != 1) - return -EINVAL; + if (res != 1) { + printf("Vendor command must start with 0x\n"); + return 2; + } res = sscanf(argv[1], "0x%x", &subcmd); - if (res != 1) - return -EINVAL; + if (res != 1) { + printf("Sub command must start with 0x\n"); + return 2; + } if (!strcmp(argv[2], "-")) file = stdin; @@ -75,7 +107,8 @@ static int handle_vendor(struct nl80211_state *state, if (file) { count = read_file(file, buf, sizeof(buf)); - fclose(file); + if (file != stdin) + fclose(file); } else count = read_hex(argc - 2, &argv[2], buf, sizeof(buf)); @@ -88,7 +121,27 @@ static int handle_vendor(struct nl80211_state *state, return 0; nla_put_failure: + if (file && file != stdin) + fclose(file); return -ENOBUFS; } +static int handle_vendor_recv(struct nl80211_state *state, + struct nl_msg *msg, int argc, + char **argv, enum id_input id) +{ + register_handler(print_vendor_response, (void *) true); + return handle_vendor(state, msg, argc, argv, id); +} + +static int handle_vendor_recv_bin(struct nl80211_state *state, + struct nl_msg *msg, int argc, + char **argv, enum id_input id) +{ + register_handler(print_vendor_response, (void *) false); + return handle_vendor(state, msg, argc, argv, id); +} + COMMAND(vendor, send, " ", NL80211_CMD_VENDOR, 0, CIB_NETDEV, handle_vendor, ""); +COMMAND(vendor, recv, " ", NL80211_CMD_VENDOR, 0, CIB_NETDEV, handle_vendor_recv, ""); +COMMAND(vendor, recvbin, " ", NL80211_CMD_VENDOR, 0, CIB_NETDEV, handle_vendor_recv_bin, "");