2 * \file interface-driver.c
3 * \author written by Emmanuel Roullit emmanuel.roullit@gmail.com (c) 2013
8 /* HACK prevent libnl3 include clash between <net/if.h> and <linux/if.h> */
11 #endif /* _LINUX_IF_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>
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
);
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
];
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
) {
57 free(driverp
->status
);
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
));
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
++;
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
;
101 assert(closure_data
);
103 cache
= link_cache_alloc(&sock
);
104 link
= rtnl_link_alloc();
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
,
117 nl_cache_foreach(cache
, __interface_driver_get
, &driver_list
);
119 driver_listp
= &driver_list
;
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
);
134 link_cache_destroy(sock
, cache
);