xref: /aosp_15_r20/external/iw/ap.c (revision 92022041c981f431db0b590d0c3272306d0ea2a2)
1*92022041SSam Saccone #include <errno.h>
2*92022041SSam Saccone #include <netlink/genl/genl.h>
3*92022041SSam Saccone #include <netlink/genl/family.h>
4*92022041SSam Saccone #include <netlink/genl/ctrl.h>
5*92022041SSam Saccone #include <netlink/msg.h>
6*92022041SSam Saccone #include <netlink/attr.h>
7*92022041SSam Saccone #include "nl80211.h"
8*92022041SSam Saccone #include "iw.h"
9*92022041SSam Saccone 
10*92022041SSam Saccone SECTION(ap);
11*92022041SSam Saccone 
handle_start_ap(struct nl80211_state * state,struct nl_msg * msg,int argc,char ** argv,enum id_input id)12*92022041SSam Saccone static int handle_start_ap(struct nl80211_state *state,
13*92022041SSam Saccone 			   struct nl_msg *msg, int argc, char **argv,
14*92022041SSam Saccone 			   enum id_input id)
15*92022041SSam Saccone {
16*92022041SSam Saccone 	struct chandef chandef;
17*92022041SSam Saccone 	int res, parsed;
18*92022041SSam Saccone 	char *end;
19*92022041SSam Saccone 	int val, len;
20*92022041SSam Saccone 	char buf[2304];
21*92022041SSam Saccone 
22*92022041SSam Saccone 	if (argc < 6)
23*92022041SSam Saccone 		return 1;
24*92022041SSam Saccone 
25*92022041SSam Saccone 	/* SSID */
26*92022041SSam Saccone 	NLA_PUT(msg, NL80211_ATTR_SSID, strlen(argv[0]), argv[0]);
27*92022041SSam Saccone 	argv++;
28*92022041SSam Saccone 	argc--;
29*92022041SSam Saccone 
30*92022041SSam Saccone 	/* chandef */
31*92022041SSam Saccone 	res = parse_freqchan(&chandef, false, argc, argv, &parsed);
32*92022041SSam Saccone 	if (res)
33*92022041SSam Saccone 		return res;
34*92022041SSam Saccone 	argc -= parsed;
35*92022041SSam Saccone 	argv += parsed;
36*92022041SSam Saccone 	res = put_chandef(msg, &chandef);
37*92022041SSam Saccone 	if (res)
38*92022041SSam Saccone 		return res;
39*92022041SSam Saccone 
40*92022041SSam Saccone 	/* beacon interval */
41*92022041SSam Saccone 	val = strtoul(argv[0], &end, 10);
42*92022041SSam Saccone 	if (*end != '\0')
43*92022041SSam Saccone 		return -EINVAL;
44*92022041SSam Saccone 
45*92022041SSam Saccone 	NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL, val);
46*92022041SSam Saccone 	argv++;
47*92022041SSam Saccone 	argc--;
48*92022041SSam Saccone 
49*92022041SSam Saccone 	/* dtim */
50*92022041SSam Saccone 	val = strtoul(argv[0], &end, 10);
51*92022041SSam Saccone 	if (*end != '\0')
52*92022041SSam Saccone 		return -EINVAL;
53*92022041SSam Saccone 
54*92022041SSam Saccone 	NLA_PUT_U32(msg, NL80211_ATTR_DTIM_PERIOD, val);
55*92022041SSam Saccone 	argv++;
56*92022041SSam Saccone 	argc--;
57*92022041SSam Saccone 
58*92022041SSam Saccone 	if (strcmp(argv[0], "hidden-ssid") == 0) {
59*92022041SSam Saccone 		argc--;
60*92022041SSam Saccone 		argv++;
61*92022041SSam Saccone 		NLA_PUT_U32(msg, NL80211_ATTR_HIDDEN_SSID,
62*92022041SSam Saccone 			    NL80211_HIDDEN_SSID_ZERO_LEN);
63*92022041SSam Saccone 	} else if (strcmp(argv[0], "zeroed-ssid") == 0) {
64*92022041SSam Saccone 		argc--;
65*92022041SSam Saccone 		argv++;
66*92022041SSam Saccone 		NLA_PUT_U32(msg, NL80211_ATTR_HIDDEN_SSID,
67*92022041SSam Saccone 			    NL80211_HIDDEN_SSID_ZERO_CONTENTS);
68*92022041SSam Saccone 	}
69*92022041SSam Saccone 
70*92022041SSam Saccone 	/* beacon head must be provided */
71*92022041SSam Saccone 	if (strcmp(argv[0], "head") != 0)
72*92022041SSam Saccone 		return 1;
73*92022041SSam Saccone 	argv++;
74*92022041SSam Saccone 	argc--;
75*92022041SSam Saccone 
76*92022041SSam Saccone 	len = strlen(argv[0]);
77*92022041SSam Saccone 	if (!len || (len % 2))
78*92022041SSam Saccone 		return -EINVAL;
79*92022041SSam Saccone 
80*92022041SSam Saccone 	if (!hex2bin(&argv[0][0], buf))
81*92022041SSam Saccone 		return -EINVAL;
82*92022041SSam Saccone 
83*92022041SSam Saccone 	NLA_PUT(msg, NL80211_ATTR_BEACON_HEAD, (len / 2), &buf);
84*92022041SSam Saccone 	argv++;
85*92022041SSam Saccone 	argc--;
86*92022041SSam Saccone 
87*92022041SSam Saccone 	if (!argc)
88*92022041SSam Saccone 		return 0;
89*92022041SSam Saccone 
90*92022041SSam Saccone 	/* tail is optional */
91*92022041SSam Saccone 	if (strcmp(argv[0], "tail") == 0) {
92*92022041SSam Saccone 		argv++;
93*92022041SSam Saccone 		argc--;
94*92022041SSam Saccone 
95*92022041SSam Saccone 		if (!argc)
96*92022041SSam Saccone 			return -EINVAL;
97*92022041SSam Saccone 
98*92022041SSam Saccone 		len = strlen(argv[0]);
99*92022041SSam Saccone 		if (!len || (len % 2))
100*92022041SSam Saccone 			return -EINVAL;
101*92022041SSam Saccone 
102*92022041SSam Saccone 		if (!hex2bin(&argv[0][0], buf))
103*92022041SSam Saccone 			return -EINVAL;
104*92022041SSam Saccone 
105*92022041SSam Saccone 		NLA_PUT(msg, NL80211_ATTR_BEACON_TAIL, (len / 2), &buf);
106*92022041SSam Saccone 		argv++;
107*92022041SSam Saccone 		argc--;
108*92022041SSam Saccone 	}
109*92022041SSam Saccone 
110*92022041SSam Saccone 	if (!argc)
111*92022041SSam Saccone 		return 0;
112*92022041SSam Saccone 
113*92022041SSam Saccone 	/* inactivity time (optional) */
114*92022041SSam Saccone 	if (strcmp(argv[0], "inactivity-time") == 0) {
115*92022041SSam Saccone 		argv++;
116*92022041SSam Saccone 		argc--;
117*92022041SSam Saccone 
118*92022041SSam Saccone 		if (!argc)
119*92022041SSam Saccone 			return -EINVAL;
120*92022041SSam Saccone 		len = strlen(argv[0]);
121*92022041SSam Saccone 		if (!len)
122*92022041SSam Saccone 			return -EINVAL;
123*92022041SSam Saccone 
124*92022041SSam Saccone 		val = strtoul(argv[0], &end, 10);
125*92022041SSam Saccone 		if (*end != '\0')
126*92022041SSam Saccone 			return -EINVAL;
127*92022041SSam Saccone 
128*92022041SSam Saccone 		NLA_PUT_U16(msg, NL80211_ATTR_INACTIVITY_TIMEOUT, val);
129*92022041SSam Saccone 		argv++;
130*92022041SSam Saccone 		argc--;
131*92022041SSam Saccone 	}
132*92022041SSam Saccone 
133*92022041SSam Saccone 	if (!argc) {
134*92022041SSam Saccone 		return 0;
135*92022041SSam Saccone 	}
136*92022041SSam Saccone 
137*92022041SSam Saccone 	if (strcmp(*argv, "key") != 0 && strcmp(*argv, "keys") != 0)
138*92022041SSam Saccone 		return 1;
139*92022041SSam Saccone 
140*92022041SSam Saccone 	argv++;
141*92022041SSam Saccone 	argc--;
142*92022041SSam Saccone 
143*92022041SSam Saccone 	return parse_keys(msg, &argv, &argc);
144*92022041SSam Saccone  nla_put_failure:
145*92022041SSam Saccone 	return -ENOSPC;
146*92022041SSam Saccone }
147*92022041SSam Saccone COMMAND(ap, start, "",
148*92022041SSam Saccone 	NL80211_CMD_NEW_BEACON, 0, CIB_NETDEV, handle_start_ap,
149*92022041SSam Saccone 	"<SSID> <control freq> [5|10|20|40|80|80+80|160] [<center1_freq> [<center2_freq>]]"
150*92022041SSam Saccone 	" <beacon interval in TU> <DTIM period> [hidden-ssid|zeroed-ssid] head"
151*92022041SSam Saccone 	" <beacon head in hexadecimal> [tail <beacon tail in hexadecimal>]"
152*92022041SSam Saccone 	" [inactivity-time <inactivity time in seconds>] [key0:abcde d:1:6162636465]\n");
153*92022041SSam Saccone 
handle_stop_ap(struct nl80211_state * state,struct nl_msg * msg,int argc,char ** argv,enum id_input id)154*92022041SSam Saccone static int handle_stop_ap(struct nl80211_state *state,
155*92022041SSam Saccone 			  struct nl_msg *msg,
156*92022041SSam Saccone 			  int argc, char **argv,
157*92022041SSam Saccone 			  enum id_input id)
158*92022041SSam Saccone {
159*92022041SSam Saccone 	return 0;
160*92022041SSam Saccone }
161*92022041SSam Saccone COMMAND(ap, stop, "",
162*92022041SSam Saccone 	NL80211_CMD_DEL_BEACON, 0, CIB_NETDEV, handle_stop_ap,
163*92022041SSam Saccone 	"Stop AP functionality\n");
164