]> git.ipfire.org Git - thirdparty/iw.git/blame - reg.c
add back the ability to add a sibling interface
[thirdparty/iw.git] / reg.c
CommitLineData
14a0380d
LR
1#include <linux/nl80211.h>
2#include <net/if.h>
3#include <errno.h>
4#include <string.h>
5
6#include <netlink/genl/genl.h>
7#include <netlink/genl/family.h>
8#include <netlink/genl/ctrl.h>
9#include <netlink/msg.h>
10#include <netlink/attr.h>
11
12#include "iw.h"
13
14static int wait_handler(struct nl_msg *msg, void *arg)
15{
16 int *finished = arg;
17
18 *finished = 1;
19 return NL_STOP;
20}
21
22static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
23 void *arg)
24{
25 fprintf(stderr, "nl80211 error %d\n", err->error);
26 exit(err->error);
27}
28
29static int reg_handler(struct nl_msg *msg, void *arg)
30{
31 return NL_SKIP;
32}
33
34int isalpha_upper(char letter)
35{
36 if (letter >= 65 && letter <= 90)
37 return 1;
38 return 0;
39}
40
41static int is_alpha2(char *alpha2)
42{
43 if (isalpha_upper(alpha2[0]) && isalpha_upper(alpha2[1]))
44 return 1;
45 return 0;
46}
47
48static int is_world_regdom(char *alpha2)
49{
50 /* ASCII 0 */
51 if (alpha2[0] == 48 && alpha2[1] == 48)
52 return 1;
53 return 0;
54}
55
56static int handle_reg_set(struct nl80211_state *state,
1c05c109
JB
57 struct nl_msg *msg,
58 int argc, char **argv)
14a0380d 59{
14a0380d 60 struct nl_cb *cb = NULL;
1c05c109 61 int ret = 1;
14a0380d
LR
62 int err;
63 int finished = 0;
64 char alpha2[3];
65
1c05c109 66 if (argc < 1)
14a0380d 67 return -1;
14a0380d
LR
68
69 if (!is_alpha2(argv[0]) && !is_world_regdom(argv[0])) {
70 fprintf(stderr, "not a valid ISO/IEC 3166-1 alpha2\n");
71 fprintf(stderr, "Special non-alph2 usable entries:\n");
72 fprintf(stderr, "\t00\tWorld Regulatory domain\n");
1c05c109 73 return 1;
14a0380d
LR
74 }
75
76 alpha2[0] = argv[0][0];
77 alpha2[1] = argv[0][1];
78 alpha2[2] = '\0';
79
80 argc--;
81 argv++;
82
1c05c109 83 if (argc)
14a0380d 84 return -1;
14a0380d
LR
85
86 NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, alpha2);
87
88 cb = nl_cb_alloc(NL_CB_CUSTOM);
89 if (!cb)
90 goto out;
91
92 err = nl_send_auto_complete(state->nl_handle, msg);
93
94 if (err < 0) {
95 fprintf(stderr, "failed to send reg set command\n");
96 goto out;
97 }
98
99 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, reg_handler, NULL);
100 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, wait_handler, &finished);
101 nl_cb_err(cb, NL_CB_CUSTOM, error_handler, NULL);
102
103 err = nl_recvmsgs(state->nl_handle, cb);
104
1c05c109 105 if (!finished)
14a0380d 106 err = nl_wait_for_ack(state->nl_handle);
14a0380d
LR
107
108 if (err < 0)
109 goto out;
110
111 ret = 0;
112
113 out:
114 nl_cb_put(cb);
115 nla_put_failure:
14a0380d
LR
116 return ret;
117}
1c05c109
JB
118COMMAND(reg, set, "<ISO/IEC 3166-1 alpha2>",
119 NL80211_CMD_REQ_SET_REG, 0, CIB_NONE, handle_reg_set);