]> git.ipfire.org Git - thirdparty/iw.git/blob - interface.c
clean up includes
[thirdparty/iw.git] / interface.c
1 #include <linux/nl80211.h>
2 #include <net/if.h>
3 #include <errno.h>
4
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>
10
11 #include "iw.h"
12
13 /* return 0 if not found, 1 if ok, -1 on error */
14 static 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;
35 } else if (strcmp(tpstr, "ap") == 0 || strcmp(tpstr, "master") == 0) {
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;
47 } else if (strcmp(tpstr, "mp") == 0 ||
48 strcmp(tpstr, "mesh") == 0) {
49 *type = NL80211_IFTYPE_MESH_POINT;
50 return 1;
51 }
52
53
54 fprintf(stderr, "invalid interface type %s\n", tpstr);
55 return -1;
56 }
57
58 static int handle_interface_add(struct nl80211_state *state,
59 char *phy, char *dev, int argc, char **argv)
60 {
61 char *name;
62 char *mesh_id = NULL;
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
72 name = argv[0];
73 argc--;
74 argv++;
75
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;
81
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
99 if (argc) {
100 fprintf(stderr, "too many arguments\n");
101 return -1;
102 }
103
104 msg = nlmsg_alloc();
105 if (!msg) {
106 fprintf(stderr, "failed to allocate netlink msg\n");
107 return -1;
108 }
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);
119 if (mesh_id)
120 NLA_PUT(msg, NL80211_ATTR_MESH_ID, strlen(mesh_id), mesh_id);
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
135 static 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
172 int handle_interface(struct nl80211_state *state,
173 char *phy, char *dev, int argc, char **argv)
174 {
175 char *cmd = argv[0];
176
177 if (argc < 1) {
178 fprintf(stderr, "you must specify an interface command\n");
179 return -1;
180 }
181
182 argc--;
183 argv++;
184
185 if (strcmp(cmd, "add") == 0)
186 return handle_interface_add(state, phy, dev, argc, argv);
187 else if (strcmp(cmd, "del") == 0)
188 return handle_interface_del(state, phy, dev, argc, argv);
189
190 printf("invalid interface command %s\n", cmd);
191 return -1;
192 }