Home | History | Annotate | Download | only in iw
      1 #include <net/if.h>
      2 #include <errno.h>
      3 #include <string.h>
      4 
      5 #include <netlink/genl/genl.h>
      6 #include <netlink/genl/family.h>
      7 #include <netlink/genl/ctrl.h>
      8 #include <netlink/msg.h>
      9 #include <netlink/attr.h>
     10 
     11 #include "nl80211.h"
     12 #include "iw.h"
     13 
     14 SECTION(vendor);
     15 
     16 static int read_file(FILE *file, char *buf, size_t size)
     17 {
     18 	int data, count = 0;
     19 
     20 	while ((data = fgetc(file)) != EOF) {
     21 		if (count >= size)
     22 			return -EINVAL;
     23 		buf[count] = data;
     24 		count++;
     25 	}
     26 
     27 	return count;
     28 }
     29 
     30 static int read_hex(int argc, char **argv, char *buf, size_t size)
     31 {
     32 	int i, res;
     33 	unsigned int data;
     34 
     35 	if (argc > size)
     36 		return -EINVAL;
     37 
     38 	for (i = 0; i < argc; i++) {
     39 		res = sscanf(argv[i], "0x%x", &data);
     40 		if (res != 1 || data > 0xff)
     41 			return -EINVAL;
     42 		buf[i] = data;
     43 	}
     44 
     45 	return argc;
     46 }
     47 
     48 static int handle_vendor(struct nl80211_state *state, struct nl_cb *cb,
     49 			 struct nl_msg *msg, int argc, char **argv,
     50 			 enum id_input id)
     51 {
     52 	unsigned int oui;
     53 	unsigned int subcmd;
     54 	char buf[2048] = {};
     55 	int res, count = 0;
     56 	FILE *file = NULL;
     57 
     58 	if (argc < 3)
     59 		return -EINVAL;
     60 
     61 	res = sscanf(argv[0], "0x%x", &oui);
     62 	if (res != 1)
     63 		return -EINVAL;
     64 
     65 	res = sscanf(argv[1], "0x%x", &subcmd);
     66 	if (res != 1)
     67 		return -EINVAL;
     68 
     69 	if (!strcmp(argv[2], "-"))
     70 		file = stdin;
     71 	else
     72 		file = fopen(argv[2], "r");
     73 
     74 	NLA_PUT_U32(msg, NL80211_ATTR_VENDOR_ID, oui);
     75 	NLA_PUT_U32(msg, NL80211_ATTR_VENDOR_SUBCMD, subcmd);
     76 
     77 	if (file) {
     78 		count = read_file(file, buf, sizeof(buf));
     79 		fclose(file);
     80 	} else
     81 		count = read_hex(argc - 2, &argv[2], buf, sizeof(buf));
     82 
     83 	if (count < 0)
     84 		return -EINVAL;
     85 
     86 	if (count > 0)
     87 		NLA_PUT(msg, NL80211_ATTR_VENDOR_DATA, count, buf);
     88 
     89 	return 0;
     90 
     91 nla_put_failure:
     92 	return -ENOBUFS;
     93 }
     94 
     95 COMMAND(vendor, send, "<oui> <subcmd> <filename|-|hex data>", NL80211_CMD_VENDOR, 0, CIB_NETDEV, handle_vendor, "");
     96