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