]> git.ipfire.org Git - thirdparty/iw.git/blame - interface.c
fix stupid bug
[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;
48 }
49
50
51 fprintf(stderr, "invalid interface type %s\n", tpstr);
52 return -1;
53}
54
55static int handle_interface_add(struct nl80211_state *state,
56 char *phy, char *dev, int argc, char **argv)
57{
2dfd6bfa 58 char *name;
45c7212c
JB
59 enum nl80211_iftype type;
60 int tpset, err;
61 struct nl_msg *msg;
62
63 if (argc < 1) {
64 fprintf(stderr, "not enough arguments\n");
65 return -1;
66 }
67
2dfd6bfa 68 name = argv[0];
45c7212c
JB
69 argc--;
70 argv++;
71
2dfd6bfa
AL
72 tpset = get_if_type(&argc, &argv, &type);
73 if (tpset == 0)
74 fprintf(stderr, "you must specify an interface type\n");
75 if (tpset <= 0)
76 return -1;
45c7212c
JB
77
78 if (argc) {
79 fprintf(stderr, "too many arguments\n");
80 return -1;
81 }
82
1cdd9016
MK
83 msg = nlmsg_alloc();
84 if (!msg) {
85 fprintf(stderr, "failed to allocate netlink msg\n");
86 return -1;
87 }
45c7212c
JB
88
89 genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0,
90 0, NL80211_CMD_NEW_INTERFACE, 0);
91 if (dev)
92 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(dev));
93 if (phy)
94 return -1; /* XXX TODO */
95 NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, name);
96 if (tpset)
97 NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, type);
98
99 if ((err = nl_send_auto_complete(state->nl_handle, msg)) < 0 ||
100 (err = nl_wait_for_ack(state->nl_handle)) < 0) {
101 nla_put_failure:
102 fprintf(stderr, "failed to create interface: %d\n", err);
103 nlmsg_free(msg);
104 return -1;
105 }
106
107 nlmsg_free(msg);
108
109 return 0;
110}
111
3fcfe40e
JB
112static int handle_interface_del(struct nl80211_state *state,
113 char *phy, char *dev, int argc, char **argv)
114{
115 int err;
116 struct nl_msg *msg;
117
118 if (argc) {
119 fprintf(stderr, "too many arguments\n");
120 return -1;
121 }
122
123 msg = nlmsg_alloc();
124 if (!msg)
125 return -1;
126
127 genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0,
128 0, NL80211_CMD_DEL_INTERFACE, 0);
129 if (!dev) {
130 fprintf(stderr, "need device\n");
131 nlmsg_free(msg);
132 return -1;
133 }
134 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(dev));
135
136 if ((err = nl_send_auto_complete(state->nl_handle, msg)) < 0 ||
137 (err = nl_wait_for_ack(state->nl_handle)) < 0) {
138 nla_put_failure:
139 fprintf(stderr, "failed to remove interface: %d\n", err);
140 nlmsg_free(msg);
141 return -1;
142 }
143
144 nlmsg_free(msg);
145
146 return 0;
147}
148
45c7212c
JB
149int handle_interface(struct nl80211_state *state,
150 char *phy, char *dev, int argc, char **argv)
151{
152 char *cmd = argv[0];
153
2dfd6bfa
AL
154 if (argc < 1) {
155 fprintf(stderr, "you must specify an interface command\n");
45c7212c 156 return -1;
2dfd6bfa 157 }
45c7212c
JB
158
159 argc--;
160 argv++;
161
162 if (strcmp(cmd, "add") == 0)
163 return handle_interface_add(state, phy, dev, argc, argv);
3fcfe40e
JB
164 else if (strcmp(cmd, "del") == 0)
165 return handle_interface_del(state, phy, dev, argc, argv);
45c7212c
JB
166
167 printf("invalid interface command %s\n", cmd);
168 return -1;
169}