git: do not track vim swo temp file.
[dabba.git] / dabbad / interface-driver.c
blobae6de9efbffcdfc0020e867cd627e927d708c685
1 /**
2 * \file interface-driver.c
3 * \author written by Emmanuel Roullit emmanuel.roullit@gmail.com (c) 2013
4 * \date 2013
5 */
8 /* HACK prevent libnl3 include clash between <net/if.h> and <linux/if.h> */
9 #ifndef _LINUX_IF_H
10 #define _LINUX_IF_H
11 #endif /* _LINUX_IF_H */
13 #include <assert.h>
14 #include <linux/ethtool.h>
15 #include <netlink/cache.h>
16 #include <netlink/route/link.h>
17 #include <libdabba/interface.h>
18 #include <dabbad/interface.h>
19 #include <dabbad/interface-driver.h>
21 /**
22 * \internal
23 * \brief Get the driver settings of a network interface
24 * \param[in] obj Pointer to interface netlink structure
25 * \param[in] arg Pointer to interface driver protobuf message
26 * \note Might silently skip an interface if memory could not be allocated.
29 static void __interface_driver_get(struct nl_object *obj, void *arg)
31 struct rtnl_link *link = (struct rtnl_link *)obj;
32 Dabba__InterfaceDriverList *driver_list = arg;
33 Dabba__InterfaceDriver *driverp, **listpp;
34 struct ethtool_drvinfo drvinfo;
35 size_t lsize = sizeof(*driver_list->list) * (driver_list->n_list + 1);
37 listpp = realloc(driver_list->list, lsize);
39 if (!listpp)
40 return;
42 driver_list->list = listpp;
43 driver_list->list[driver_list->n_list] =
44 malloc(sizeof(*driver_list->list[driver_list->n_list]));
45 driverp = driver_list->list[driver_list->n_list];
47 if (!driverp)
48 return;
50 dabba__interface_driver__init(driverp);
52 driverp->id = malloc(sizeof(*driverp->id));
53 driverp->status = malloc(sizeof(*driverp->status));
55 if (!driverp->id || !driverp->status) {
56 free(driverp->id);
57 free(driverp->status);
58 free(driverp);
59 return;
62 dabba__interface_id__init(driverp->id);
63 dabba__error_code__init(driverp->status);
65 driverp->id->name = rtnl_link_get_name(link);
67 driverp->status->code = ldab_dev_driver_get(driverp->id->name, &drvinfo);
69 driverp->name = strndup(drvinfo.driver, sizeof(drvinfo.driver));
70 driverp->version = strndup(drvinfo.version, sizeof(drvinfo.version));
71 driverp->fw_version =
72 strndup(drvinfo.fw_version, sizeof(drvinfo.fw_version));
73 driverp->bus_info = strndup(drvinfo.bus_info, sizeof(drvinfo.bus_info));
75 driver_list->n_list++;
78 /**
79 * \brief Get the driver settings of a list of requested network interfaces
80 * \param[in] service Pointer to protobuf service structure
81 * \param[in] id_list Pointer to the requested interface id list
82 * \param[in] closure Pointer to protobuf closure function pointer
83 * \param[in,out] closure_data Pointer to protobuf closure data
84 * \note Might silently skip an interface if memory could not be allocated.
87 void dabbad_interface_driver_get(Dabba__DabbaService_Service * service,
88 const Dabba__InterfaceIdList * id_list,
89 Dabba__InterfaceDriverList_Closure
90 closure, void *closure_data)
92 Dabba__InterfaceDriverList driver_list =
93 DABBA__INTERFACE_DRIVER_LIST__INIT;
94 Dabba__InterfaceDriverList *driver_listp = NULL;
95 struct nl_sock *sock = NULL;
96 struct nl_cache *cache;
97 struct rtnl_link *link;
98 size_t a;
100 assert(service);
101 assert(closure_data);
103 cache = link_cache_alloc(&sock);
104 link = rtnl_link_alloc();
106 if (!link || !cache)
107 goto out;
109 if (id_list->n_list) {
110 for (a = 0; a < id_list->n_list; a++) {
111 rtnl_link_set_name(link, id_list->list[a]->name);
112 nl_cache_foreach_filter(cache, OBJ_CAST(link),
113 __interface_driver_get,
114 &driver_list);
116 } else
117 nl_cache_foreach(cache, __interface_driver_get, &driver_list);
119 driver_listp = &driver_list;
121 out:
122 closure(driver_listp, closure_data);
123 for (a = 0; a < driver_list.n_list; a++) {
124 free(driver_list.list[a]->id);
125 free(driver_list.list[a]->status);
126 free(driver_list.list[a]->name);
127 free(driver_list.list[a]->version);
128 free(driver_list.list[a]->fw_version);
129 free(driver_list.list[a]->bus_info);
130 free(driver_list.list[a]);
132 free(driver_list.list);
133 link_destroy(link);
134 link_cache_destroy(sock, cache);