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