2626#include <arpa/inet.h>
2727#include <netlink/cache.h>
2828#include <netlink/addr.h>
29+ #include <netlink/errno.h>
2930#include <netlink/route/addr.h>
3031#include <netlink/route/link.h>
3132#include <netlink/route/rtnl.h>
@@ -111,34 +112,35 @@ static void callback_nl_address(struct nl_object *obj, void *arg)
111112 * @param self A pointer the current PyEtherInfo Python object which contains the device name
112113 * and the place where to save the corresponding index value.
113114 *
114- * @return Returns 1 on success, otherwise 0.
115+ * @return Returns 1 on success, otherwise 0. On error, a Python error exception is set.
115116 */
116117static int _set_device_index (PyEtherInfo * self )
117118{
118119 struct nl_cache * link_cache ;
119120 struct rtnl_link * link ;
120121
121- /* Reset errno, as we will use it to report errors further on */
122- errno = 0 ;
123-
124122 /* Find the interface index we're looking up.
125123 * As we don't expect it to change, we're reusing a "cached"
126124 * interface index if we have that
127125 */
128126 if ( self -> index < 0 ) {
129- if ( rtnl_link_alloc_cache (get_nlc (), AF_UNSPEC , & link_cache ) < 0 ) {
127+ if ( (errno = rtnl_link_alloc_cache (get_nlc (), AF_UNSPEC , & link_cache )) < 0 ) {
128+ PyErr_SetString (PyExc_OSError , nl_geterror (errno ));
130129 return 0 ;
131130 }
132131
133132 link = rtnl_link_get_by_name (link_cache , PyString_AsString (self -> device ));
134133 if ( !link ) {
135134 errno = ENODEV ;
135+ PyErr_SetFromErrno (PyExc_IOError );
136136 nl_cache_free (link_cache );
137137 return 0 ;
138138 }
139139
140140 self -> index = rtnl_link_get_ifindex (link );
141- if ( self -> index < 0 ) {
141+ if ( self -> index <= 0 ) {
142+ errno = ENODEV ;
143+ PyErr_SetFromErrno (PyExc_IOError );
142144 rtnl_link_put (link );
143145 nl_cache_free (link_cache );
144146 return 0 ;
@@ -167,6 +169,7 @@ int get_etherinfo_link(PyEtherInfo *self)
167169{
168170 struct nl_cache * link_cache ;
169171 struct rtnl_link * link ;
172+ int err = 0 ;
170173
171174 if ( !self ) {
172175 return 0 ;
@@ -181,18 +184,18 @@ int get_etherinfo_link(PyEtherInfo *self)
181184 }
182185
183186 if ( _set_device_index (self ) != 1 ) {
184- if ( errno != 0 ) {
185- PyErr_SetString (PyExc_IOError , strerror (errno ));
186- }
187187 return 0 ;
188188 }
189189
190190 /* Extract MAC/hardware address of the interface */
191- if ( rtnl_link_alloc_cache (get_nlc (), AF_UNSPEC , & link_cache ) < 0 ) {
191+ if ( (err = rtnl_link_alloc_cache (get_nlc (), AF_UNSPEC , & link_cache )) < 0 ) {
192+ PyErr_SetString (PyExc_OSError , nl_geterror (err ));
192193 return 0 ;
193194 }
194195 link = rtnl_link_alloc ();
195196 if ( !link ) {
197+ errno = ENOMEM ;
198+ PyErr_SetFromErrno (PyExc_OSError );
196199 return 0 ;
197200 }
198201 rtnl_link_set_ifindex (link , self -> index );
@@ -220,6 +223,7 @@ PyObject * get_etherinfo_address(PyEtherInfo *self, nlQuery query)
220223 struct nl_cache * addr_cache ;
221224 struct rtnl_addr * addr ;
222225 PyObject * addrlist = NULL ;
226+ int err = 0 ;
223227
224228 if ( !self ) {
225229 return NULL ;
@@ -234,21 +238,21 @@ PyObject * get_etherinfo_address(PyEtherInfo *self, nlQuery query)
234238 }
235239
236240 if ( _set_device_index (self ) != 1 ) {
237- if ( errno != 0 ) {
238- return PyErr_SetFromErrno (PyExc_IOError );
239- }
240241 return NULL ;
241242 }
242243
243244 /* Query the for requested info via NETLINK */
244245
245246 /* Extract IP address information */
246- if ( rtnl_addr_alloc_cache (get_nlc (), & addr_cache ) < 0 ) {
247+ if ( (err = rtnl_addr_alloc_cache (get_nlc (), & addr_cache )) < 0 ) {
248+ PyErr_SetString (PyExc_OSError , nl_geterror (err ));
247249 nl_cache_free (addr_cache );
248250 return NULL ;
249251 }
250252 addr = rtnl_addr_alloc ();
251253 if ( !addr ) {
254+ errno = ENOMEM ;
255+ PyErr_SetFromErrno (PyExc_OSError );
252256 return NULL ;
253257 }
254258 rtnl_addr_set_ifindex (addr , self -> index );
0 commit comments