]> git.ipfire.org Git - thirdparty/iw.git/blob - interface.c
"add interface" implementation
[thirdparty/iw.git] / interface.c
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 */
15 static 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;
36 } else if (strcmp(tpstr, "ap") == 0) {
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
55 static 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
82 msg = nlmsg_alloc();
83 if (!msg)
84 return -1;
85
86 genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0,
87 0, NL80211_CMD_NEW_INTERFACE, 0);
88 if (dev)
89 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(dev));
90 if (phy)
91 return -1; /* XXX TODO */
92 NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, name);
93 if (tpset)
94 NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, type);
95
96 if ((err = nl_send_auto_complete(state->nl_handle, msg)) < 0 ||
97 (err = nl_wait_for_ack(state->nl_handle)) < 0) {
98 nla_put_failure:
99 fprintf(stderr, "failed to create interface: %d\n", err);
100 nlmsg_free(msg);
101 return -1;
102 }
103
104 nlmsg_free(msg);
105
106 return 0;
107 }
108
109 int handle_interface(struct nl80211_state *state,
110 char *phy, char *dev, int argc, char **argv)
111 {
112 char *cmd = argv[0];
113
114 if (argc < 1)
115 return -1;
116
117 argc--;
118 argv++;
119
120 if (strcmp(cmd, "add") == 0)
121 return handle_interface_add(state, phy, dev, argc, argv);
122
123 printf("invalid interface command %s\n", cmd);
124 return -1;
125 }