]> git.ipfire.org Git - thirdparty/iw.git/blame - interface.c
try to run cgcc (sparse) if possible
[thirdparty/iw.git] / interface.c
CommitLineData
45c7212c
JB
1
2#include <errno.h>
3#include <netlink/genl/genl.h>
4#include <netlink/genl/family.h>
5#include <netlink/genl/ctrl.h>
6#include <netlink/msg.h>
7#include <netlink/attr.h>
8#include <linux/nl80211.h>
9
10#include <net/if.h>
11
12#include "iw.h"
13
14/* return 0 if not found, 1 if ok, -1 on error */
15static int get_if_type(int *argc, char ***argv, enum nl80211_iftype *type)
16{
17 char *tpstr;
18
19 if (*argc < 2)
20 return 0;
21
22 if (strcmp((*argv)[0], "type"))
23 return 0;
24
25 tpstr = (*argv)[1];
26 *argc -= 2;
27 *argv += 2;
28
29 if (strcmp(tpstr, "adhoc") == 0 ||
30 strcmp(tpstr, "ibss") == 0) {
31 *type = NL80211_IFTYPE_ADHOC;
32 return 1;
33 } else if (strcmp(tpstr, "monitor") == 0) {
34 *type = NL80211_IFTYPE_MONITOR;
35 return 1;
1cdd9016 36 } else if (strcmp(tpstr, "ap") == 0 || strcmp(tpstr, "master") == 0) {
45c7212c
JB
37 *type = NL80211_IFTYPE_AP;
38 return 1;
39 } else if (strcmp(tpstr, "ap_vlan") == 0) {
40 *type = NL80211_IFTYPE_AP_VLAN;
41 return 1;
42 } else if (strcmp(tpstr, "wds") == 0) {
43 *type = NL80211_IFTYPE_WDS;
44 return 1;
45 } else if (strcmp(tpstr, "station") == 0) {
46 *type = NL80211_IFTYPE_STATION;
47 return 1;
3d1e8704
LCC
48 } else if (strcmp(tpstr, "mp") == 0 ||
49 strcmp(tpstr, "mesh") == 0) {
50 *type = NL80211_IFTYPE_MESH_POINT;
51 return 1;
45c7212c
JB
52 }
53
54
55 fprintf(stderr, "invalid interface type %s\n", tpstr);
56 return -1;
57}
58
59static int handle_interface_add(struct nl80211_state *state,
60 char *phy, char *dev, int argc, char **argv)
61{
2dfd6bfa 62 char *name;
3d1e8704 63 char *mesh_id = NULL;
45c7212c
JB
64 enum nl80211_iftype type;
65 int tpset, err;
66 struct nl_msg *msg;
67
68 if (argc < 1) {
69 fprintf(stderr, "not enough arguments\n");
70 return -1;
71 }
72
2dfd6bfa 73 name = argv[0];
45c7212c
JB
74 argc--;
75 argv++;
76
2dfd6bfa
AL
77 tpset = get_if_type(&argc, &argv, &type);
78 if (tpset == 0)
79 fprintf(stderr, "you must specify an interface type\n");
80 if (tpset <= 0)
81 return -1;
45c7212c 82
3d1e8704
LCC
83 if (argc) {
84 if (strcmp(argv[0], "mesh_id") != 0) {
85 fprintf(stderr, "option %s not supported\n", argv[0]);
86 return -1;
87 }
88 argc--;
89 argv++;
90
91 if (!argc) {
92 fprintf(stderr, "not enough arguments\n");
93 return -1;
94 }
95 mesh_id = argv[0];
96 argc--;
97 argv++;
98 }
99
45c7212c
JB
100 if (argc) {
101 fprintf(stderr, "too many arguments\n");
102 return -1;
103 }
104
1cdd9016
MK
105 msg = nlmsg_alloc();
106 if (!msg) {
107 fprintf(stderr, "failed to allocate netlink msg\n");
108 return -1;
109 }
45c7212c
JB
110
111 genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0,
112 0, NL80211_CMD_NEW_INTERFACE, 0);
113 if (dev)
114 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(dev));
115 if (phy)
116 return -1; /* XXX TODO */
117 NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, name);
118 if (tpset)
119 NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, type);
3d1e8704
LCC
120 if (mesh_id)
121 NLA_PUT(msg, NL80211_ATTR_MESH_ID, strlen(mesh_id), mesh_id);
45c7212c
JB
122
123 if ((err = nl_send_auto_complete(state->nl_handle, msg)) < 0 ||
124 (err = nl_wait_for_ack(state->nl_handle)) < 0) {
125 nla_put_failure:
126 fprintf(stderr, "failed to create interface: %d\n", err);
127 nlmsg_free(msg);
128 return -1;
129 }
130
131 nlmsg_free(msg);
132
133 return 0;
134}
135
3fcfe40e
JB
136static int handle_interface_del(struct nl80211_state *state,
137 char *phy, char *dev, int argc, char **argv)
138{
139 int err;
140 struct nl_msg *msg;
141
142 if (argc) {
143 fprintf(stderr, "too many arguments\n");
144 return -1;
145 }
146
147 msg = nlmsg_alloc();
148 if (!msg)
149 return -1;
150
151 genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0,
152 0, NL80211_CMD_DEL_INTERFACE, 0);
153 if (!dev) {
154 fprintf(stderr, "need device\n");
155 nlmsg_free(msg);
156 return -1;
157 }
158 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(dev));
159
160 if ((err = nl_send_auto_complete(state->nl_handle, msg)) < 0 ||
161 (err = nl_wait_for_ack(state->nl_handle)) < 0) {
162 nla_put_failure:
163 fprintf(stderr, "failed to remove interface: %d\n", err);
164 nlmsg_free(msg);
165 return -1;
166 }
167
168 nlmsg_free(msg);
169
170 return 0;
171}
172
45c7212c
JB
173int handle_interface(struct nl80211_state *state,
174 char *phy, char *dev, int argc, char **argv)
175{
176 char *cmd = argv[0];
177
2dfd6bfa
AL
178 if (argc < 1) {
179 fprintf(stderr, "you must specify an interface command\n");
45c7212c 180 return -1;
2dfd6bfa 181 }
45c7212c
JB
182
183 argc--;
184 argv++;
185
186 if (strcmp(cmd, "add") == 0)
187 return handle_interface_add(state, phy, dev, argc, argv);
3fcfe40e
JB
188 else if (strcmp(cmd, "del") == 0)
189 return handle_interface_del(state, phy, dev, argc, argv);
45c7212c
JB
190
191 printf("invalid interface command %s\n", cmd);
192 return -1;
193}