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>
14 typedef struct _any_t
{
22 /* describes a mesh parameter */
23 struct mesh_param_descr
{
25 enum nl80211_meshconf_params mesh_param_num
;
26 int (*nla_put_fn
)(struct nl_msg
*, int, _any
*);
27 uint32_t (*parse_fn
)(const char*, _any
*);
28 void (*nla_print_fn
)(struct nlattr
*);
31 /* utility functions for manipulating and printing u8/u16/u32 values and
33 static int _my_nla_put_u8(struct nl_msg
*n
, int mesh_param_num
, _any
*value
)
35 return nla_put(n
, mesh_param_num
, sizeof(uint8_t), &value
->u
.as_8
);
38 static int _my_nla_put_u16(struct nl_msg
*n
, int mesh_param_num
, _any
*value
)
40 return nla_put(n
, mesh_param_num
, sizeof(uint16_t), &value
->u
.as_16
);
43 static int _my_nla_put_u32(struct nl_msg
*n
, int mesh_param_num
, _any
*value
)
45 return nla_put(n
, mesh_param_num
, sizeof(uint32_t), &value
->u
.as_32
);
48 static uint32_t _parse_u8(const char *str
, _any
*ret
)
51 unsigned long int v
= strtoul(str
, &endptr
, 10);
56 ret
->u
.as_8
= (uint8_t)v
;
60 static uint32_t _parse_u8_as_bool(const char *str
, _any
*ret
)
63 unsigned long int v
= strtoul(str
, &endptr
, 10);
68 ret
->u
.as_8
= (uint8_t)v
;
72 static uint32_t _parse_u16(const char *str
, _any
*ret
)
75 long int v
= strtol(str
, &endptr
, 10);
78 if ((v
< 0) || (v
> 0xffff))
80 ret
->u
.as_16
= (uint16_t)v
;
84 static uint32_t _parse_u32(const char *str
, _any
*ret
)
87 long long int v
= strtoll(str
, &endptr
, 10);
90 if ((v
< 0) || (v
> 0xffffffff))
92 ret
->u
.as_32
= (uint32_t)v
;
96 static void _print_u8(struct nlattr
*a
)
98 printf("%d", nla_get_u8(a
));
101 static void _print_u16(struct nlattr
*a
)
103 printf("%d", nla_get_u16(a
));
106 static void _print_u16_timeout(struct nlattr
*a
)
108 printf("%d milliseconds", nla_get_u16(a
));
111 static void _print_u16_in_TUs(struct nlattr
*a
)
113 printf("%d TUs", nla_get_u16(a
));
116 static void _print_u32_timeout(struct nlattr
*a
)
118 printf("%u milliseconds", nla_get_u32(a
));
121 static void _print_u32_in_TUs(struct nlattr
*a
)
123 printf("%d TUs", nla_get_u32(a
));
126 /* The current mesh parameters */
127 const static struct mesh_param_descr _mesh_param_descrs
[] =
129 {"mesh_retry_timeout",
130 NL80211_MESHCONF_RETRY_TIMEOUT
,
131 _my_nla_put_u16
, _parse_u16
, _print_u16_timeout
},
132 {"mesh_confirm_timeout",
133 NL80211_MESHCONF_CONFIRM_TIMEOUT
,
134 _my_nla_put_u16
, _parse_u16
, _print_u16_timeout
},
135 {"mesh_holding_timeout",
136 NL80211_MESHCONF_HOLDING_TIMEOUT
,
137 _my_nla_put_u16
, _parse_u16
, _print_u16_timeout
},
138 {"mesh_max_peer_links",
139 NL80211_MESHCONF_MAX_PEER_LINKS
,
140 _my_nla_put_u16
, _parse_u16
, _print_u16
},
142 NL80211_MESHCONF_MAX_RETRIES
,
143 _my_nla_put_u8
, _parse_u8
, _print_u8
},
145 NL80211_MESHCONF_TTL
,
146 _my_nla_put_u8
, _parse_u8
, _print_u8
},
147 {"mesh_auto_open_plinks",
148 NL80211_MESHCONF_AUTO_OPEN_PLINKS
,
149 _my_nla_put_u8
, _parse_u8_as_bool
, _print_u8
},
150 {"mesh_hwmp_max_preq_retries",
151 NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES
,
152 _my_nla_put_u8
, _parse_u8
, _print_u8
},
153 {"mesh_path_refresh_time",
154 NL80211_MESHCONF_PATH_REFRESH_TIME
,
155 _my_nla_put_u32
, _parse_u32
, _print_u32_timeout
},
156 {"mesh_min_discovery_timeout",
157 NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT
,
158 _my_nla_put_u16
, _parse_u16
, _print_u16_timeout
},
159 {"mesh_hwmp_active_path_timeout",
160 NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT
,
161 _my_nla_put_u32
, _parse_u32
, _print_u32_in_TUs
},
162 {"mesh_hwmp_preq_min_interval",
163 NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL
,
164 _my_nla_put_u16
, _parse_u16
, _print_u16_in_TUs
},
165 {"mesh_hwmp_net_diameter_traversal_time",
166 NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME
,
167 _my_nla_put_u16
, _parse_u16
, _print_u16_in_TUs
},
170 static void print_all_mesh_param_descr(void)
174 printf("Possible mesh parameters are:\n");
176 for (i
= 0; i
< ARRAY_SIZE(_mesh_param_descrs
); i
++)
177 printf(" - %s\n", _mesh_param_descrs
[i
].name
);
180 static const struct mesh_param_descr
* find_mesh_param(int argc
, char **argv
,
181 const char *action_name
)
184 const struct mesh_param_descr
*mdescr
;
187 printf("You must specify which mesh parameter to %s.\n",
189 print_all_mesh_param_descr();
193 /* Find out what mesh parameter we want to change. */
195 for (i
= 0; i
< ARRAY_SIZE(_mesh_param_descrs
); i
++) {
196 if (!strcmp(_mesh_param_descrs
[i
].name
, argv
[0]))
197 return _mesh_param_descrs
+ i
;
201 print_all_mesh_param_descr();
208 static int set_interface_meshparam(struct nl80211_state
*state
,
211 int argc
, char **argv
)
215 const struct mesh_param_descr
*mdescr
;
216 struct nlattr
*container
;
219 mdescr
= find_mesh_param(argc
, argv
, "change");
223 printf("Must specify a value for %s.\n", mdescr
->name
);
227 /* Parse the new value */
228 memset(&any
, 0, sizeof(_any
));
229 ret
= mdescr
->parse_fn(argv
[1], &any
);
231 printf("%s must be set to a number "
232 "between 0 and %u\n", mdescr
->name
, ret
);
236 /* Construct a netlink message */
237 container
= nla_nest_start(msg
, NL80211_ATTR_MESH_PARAMS
);
240 err
= mdescr
->nla_put_fn(msg
, mdescr
->mesh_param_num
, &any
);
241 nla_nest_end(msg
, container
);
246 COMMAND(set
, mesh_param
, "<param> <value>",
247 NL80211_CMD_SET_MESH_PARAMS
, 0, CIB_NETDEV
, set_interface_meshparam
);
250 static int print_mesh_param_handler(struct nl_msg
*msg
, void *arg
)
252 const struct mesh_param_descr
*mdescr
= arg
;
253 struct nlattr
*attrs
[NL80211_ATTR_MAX
+ 1];
254 struct nlattr
*parent_attr
;
255 struct nlattr
*mesh_params
[NL80211_MESHCONF_ATTR_MAX
+ 1];
256 struct genlmsghdr
*gnlh
= nlmsg_data(nlmsg_hdr(msg
));
258 /* locate NL80211_ATTR_MESH_PARAMS */
259 nla_parse(attrs
, NL80211_ATTR_MAX
, genlmsg_attrdata(gnlh
, 0),
260 genlmsg_attrlen(gnlh
, 0), NULL
);
261 parent_attr
= attrs
[NL80211_ATTR_MESH_PARAMS
];
265 /* unpack the mesh parameters */
266 if (nla_parse_nested(mesh_params
, NL80211_MESHCONF_ATTR_MAX
,
270 /* print out the mesh parameter */
271 mdescr
->nla_print_fn(mesh_params
[mdescr
->mesh_param_num
]);
276 static int get_interface_meshparam(struct nl80211_state
*state
,
279 int argc
, char **argv
)
281 const struct mesh_param_descr
*mdescr
;
283 mdescr
= find_mesh_param(argc
, argv
, "get");
287 nl_cb_set(cb
, NL_CB_VALID
, NL_CB_CUSTOM
,
288 print_mesh_param_handler
, (void *)mdescr
);
292 COMMAND(get
, mesh_param
, "<param>",
293 NL80211_CMD_GET_MESH_PARAMS
, 0, CIB_NETDEV
, get_interface_meshparam
);