xref: /aosp_15_r20/external/iw/ibss.c (revision 92022041c981f431db0b590d0c3272306d0ea2a2)
1 #include <errno.h>
2 #include <string.h>
3 #include <strings.h>
4 
5 #include "nl80211.h"
6 #include "iw.h"
7 
8 SECTION(ibss);
9 
join_ibss(struct nl80211_state * state,struct nl_msg * msg,int argc,char ** argv,enum id_input id)10 static int join_ibss(struct nl80211_state *state,
11 		     struct nl_msg *msg,
12 		     int argc, char **argv,
13 		     enum id_input id)
14 {
15 	char *end;
16 	struct chandef chandef;
17 	unsigned char abssid[6];
18 	unsigned char rates[NL80211_MAX_SUPP_RATES];
19 	int n_rates = 0;
20 	char *value = NULL, *sptr = NULL;
21 	float rate;
22 	int bintval;
23 	int parsed, err;
24 
25 	if (argc < 2)
26 		return 1;
27 
28 	/* SSID */
29 	NLA_PUT(msg, NL80211_ATTR_SSID, strlen(argv[0]), argv[0]);
30 	argv++;
31 	argc--;
32 
33 	err = parse_freqchan(&chandef, false, argc, argv, &parsed);
34 	if (err)
35 		return err;
36 
37 	argv += parsed;
38 	argc -= parsed;
39 
40 	err = put_chandef(msg, &chandef);
41 	if (err)
42 		return err;
43 
44 	if (argc && strcmp(argv[0], "fixed-freq") == 0) {
45 		NLA_PUT_FLAG(msg, NL80211_ATTR_FREQ_FIXED);
46 		argv++;
47 		argc--;
48 	}
49 
50 	if (argc) {
51 		if (mac_addr_a2n(abssid, argv[0]) == 0) {
52 			NLA_PUT(msg, NL80211_ATTR_MAC, 6, abssid);
53 			argv++;
54 			argc--;
55 		}
56 	}
57 
58 	if (argc > 1 && strcmp(argv[0], "beacon-interval") == 0) {
59 		argv++;
60 		argc--;
61 		bintval = strtoul(argv[0], &end, 10);
62 		if (*end != '\0')
63 			return 1;
64 		NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL, bintval);
65 		argv++;
66 		argc--;
67 	}
68 
69 	/* basic rates */
70 	if (argc > 1 && strcmp(argv[0], "basic-rates") == 0) {
71 		argv++;
72 		argc--;
73 
74 		value = strtok_r(argv[0], ",", &sptr);
75 
76 		while (value && n_rates < NL80211_MAX_SUPP_RATES) {
77 			rate = strtod(value, &end);
78 			rates[n_rates] = rate * 2;
79 
80 			/* filter out suspicious values  */
81 			if (*end != '\0' || !rates[n_rates] ||
82 			    rate*2 != rates[n_rates])
83 				return 1;
84 
85 			n_rates++;
86 			value = strtok_r(NULL, ",", &sptr);
87 		}
88 
89 		NLA_PUT(msg, NL80211_ATTR_BSS_BASIC_RATES, n_rates, rates);
90 
91 		argv++;
92 		argc--;
93 	}
94 
95 	/* multicast rate */
96 	if (argc > 1 && strcmp(argv[0], "mcast-rate") == 0) {
97 		argv++;
98 		argc--;
99 
100 		rate = strtod(argv[0], &end);
101 		if (*end != '\0')
102 			return 1;
103 
104 		NLA_PUT_U32(msg, NL80211_ATTR_MCAST_RATE, (int)(rate * 10));
105 		argv++;
106 		argc--;
107 	}
108 
109 	if (!argc)
110 		return 0;
111 
112 	if (strcmp(*argv, "key") != 0 && strcmp(*argv, "keys") != 0)
113 		return 1;
114 
115 	argv++;
116 	argc--;
117 
118 	return parse_keys(msg, &argv, &argc);
119  nla_put_failure:
120 	return -ENOSPC;
121 }
122 
leave_ibss(struct nl80211_state * state,struct nl_msg * msg,int argc,char ** argv,enum id_input id)123 static int leave_ibss(struct nl80211_state *state,
124 		      struct nl_msg *msg,
125 		      int argc, char **argv,
126 		      enum id_input id)
127 {
128 	return 0;
129 }
130 COMMAND(ibss, leave, NULL,
131 	NL80211_CMD_LEAVE_IBSS, 0, CIB_NETDEV, leave_ibss,
132 	"Leave the current IBSS cell.");
133 COMMAND(ibss, join,
134 	"<SSID> <freq in MHz> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz] [fixed-freq] [<fixed bssid>] [beacon-interval <TU>]"
135 	" [basic-rates <rate in Mbps,rate2,...>] [mcast-rate <rate in Mbps>] "
136 	"[key d:0:abcde]",
137 	NL80211_CMD_JOIN_IBSS, 0, CIB_NETDEV, join_ibss,
138 	"Join the IBSS cell with the given SSID, if it doesn't exist create\n"
139 	"it on the given frequency. When fixed frequency is requested, don't\n"
140 	"join/create a cell on a different frequency. When a fixed BSSID is\n"
141 	"requested use that BSSID and do not adopt another cell's BSSID even\n"
142 	"if it has higher TSF and the same SSID. If an IBSS is created, create\n"
143 	"it with the specified basic-rates, multicast-rate and beacon-interval.");
144