summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--python-ethtool/etherinfo.c70
-rw-r--r--python-ethtool/etherinfo.h1
-rw-r--r--python-ethtool/etherinfo_obj.c87
-rw-r--r--python-ethtool/etherinfo_struct.h16
-rw-r--r--python-ethtool/ethtool.c54
5 files changed, 80 insertions, 148 deletions
diff --git a/python-ethtool/etherinfo.c b/python-ethtool/etherinfo.c
index 88cefc8..224cb26 100644
--- a/python-ethtool/etherinfo.c
+++ b/python-ethtool/etherinfo.c
@@ -41,23 +41,6 @@
*
*/
-/**
- * Frees the memory used by struct etherinfo
- *
- * @param ptr Pointer to a struct etherninfo element
- */
-void free_etherinfo(struct etherinfo *ptr)
-{
- if( ptr == NULL ) { // Just for safety
- return;
- }
-
- Py_XDECREF(ptr->device);
- Py_XDECREF(ptr->hwaddress);
-
- free(ptr);
-}
-
/**
* libnl callback function. Does the real parsing of a record returned by NETLINK. This function
@@ -68,7 +51,7 @@ void free_etherinfo(struct etherinfo *ptr)
*/
static void callback_nl_link(struct nl_object *obj, void *arg)
{
- struct etherinfo *ethi = (struct etherinfo *) arg;
+ etherinfo_py *ethi = (etherinfo_py *) arg;
struct rtnl_link *link = (struct rtnl_link *) obj;
char hwaddr[130];
@@ -125,12 +108,12 @@ static void callback_nl_address(struct nl_object *obj, void *arg)
/**
* Sets the etherinfo.index member to the corresponding device set in etherinfo.device
*
- * @param ethinf A pointer a struct etherinfo element which contains the device name
- * and a place to save the corresponding index value.
+ * @param self A pointer the current etherinfo_py Python object which contains the device name
+ * and the place where to save the corresponding index value.
*
* @return Returns 1 on success, otherwise 0.
*/
-static int _set_device_index(struct etherinfo *ethinf)
+static int _set_device_index(etherinfo_py *self)
{
struct nl_cache *link_cache;
struct rtnl_link *link;
@@ -139,19 +122,19 @@ static int _set_device_index(struct etherinfo *ethinf)
* As we don't expect it to change, we're reusing a "cached"
* interface index if we have that
*/
- if( ethinf->index < 0 ) {
+ if( self->index < 0 ) {
if( rtnl_link_alloc_cache(get_nlc(), AF_UNSPEC, &link_cache) < 0) {
return 0;
}
- link = rtnl_link_get_by_name(link_cache, PyString_AsString(ethinf->device));
+ link = rtnl_link_get_by_name(link_cache, PyString_AsString(self->device));
if( !link ) {
nl_cache_free(link_cache);
return 0;
}
- ethinf->index = rtnl_link_get_ifindex(link);
- if( ethinf->index < 0 ) {
+ self->index = rtnl_link_get_ifindex(link);
+ if( self->index < 0 ) {
rtnl_link_put(link);
nl_cache_free(link_cache);
return 0;
@@ -169,26 +152,31 @@ static int _set_device_index(struct etherinfo *ethinf)
*
*/
+/**
+ * Populate the etherinfo_py Python object with link information for the current device
+ *
+ * @param self Pointer to the device object, a etherinfo_py Python object
+ *
+ * @return Returns 1 on success, otherwise 0
+ */
int get_etherinfo_link(etherinfo_py *self)
{
struct nl_cache *link_cache;
struct rtnl_link *link;
- struct etherinfo *ethinf = NULL;
- if( !self || !self->ethinfo ) {
+ if( !self ) {
return 0;
}
- ethinf = self->ethinfo;
/* Open a NETLINK connection on-the-fly */
if( !open_netlink(self) ) {
PyErr_Format(PyExc_RuntimeError,
"Could not open a NETLINK connection for %s",
- PyString_AsString(ethinf->device));
+ PyString_AsString(self->device));
return 0;
}
- if( _set_device_index(ethinf) != 1) {
+ if( _set_device_index(self) != 1) {
return 0;
}
@@ -198,8 +186,8 @@ int get_etherinfo_link(etherinfo_py *self)
}
link = rtnl_link_alloc();
/* FIXME: Error handling? */
- rtnl_link_set_ifindex(link, ethinf->index);
- nl_cache_foreach_filter(link_cache, OBJ_CAST(link), callback_nl_link, ethinf);
+ rtnl_link_set_ifindex(link, self->index);
+ nl_cache_foreach_filter(link_cache, OBJ_CAST(link), callback_nl_link, self);
rtnl_link_put(link);
nl_cache_free(link_cache);
@@ -211,10 +199,10 @@ int get_etherinfo_link(etherinfo_py *self)
/**
* Query NETLINK for device IP address configuration
*
- * @param ethinf Pointer to an available struct etherinfo element. The 'device' member
- * must contain a valid string to the device to query for information
- * @param nlc Pointer to the libnl handle, which is used for the query against NETLINK
- * @param query What to query for. Must be NLQRY_ADDR4 or NLQRY_ADDR6.
+ * @param self A etherinfo_py Python object for the current device to retrieve IP address
+ * configuration data from
+ * @param query What to query for. Must be NLQRY_ADDR4 for IPv4 addresses or NLQRY_ADDR6
+ * for IPv6 addresses.
*
* @return Returns a Python list containing PyNetlinkIPaddress objects on success, otherwise NULL
*/
@@ -222,23 +210,21 @@ PyObject * get_etherinfo_address(etherinfo_py *self, nlQuery query)
{
struct nl_cache *addr_cache;
struct rtnl_addr *addr;
- struct etherinfo *ethinf = NULL;
PyObject *addrlist = NULL;
- if( !self || !self->ethinfo ) {
+ if( !self ) {
return NULL;
}
- ethinf = self->ethinfo;
/* Open a NETLINK connection on-the-fly */
if( !open_netlink(self) ) {
PyErr_Format(PyExc_RuntimeError,
"Could not open a NETLINK connection for %s",
- PyString_AsString(ethinf->device));
+ PyString_AsString(self->device));
return NULL;
}
- if( _set_device_index(ethinf) != 1) {
+ if( _set_device_index(self) != 1) {
return NULL;
}
@@ -251,7 +237,7 @@ PyObject * get_etherinfo_address(etherinfo_py *self, nlQuery query)
}
addr = rtnl_addr_alloc();
/* FIXME: Error handling? */
- rtnl_addr_set_ifindex(addr, ethinf->index);
+ rtnl_addr_set_ifindex(addr, self->index);
switch( query ) {
case NLQRY_ADDR4:
diff --git a/python-ethtool/etherinfo.h b/python-ethtool/etherinfo.h
index 2fc602e..82b491f 100644
--- a/python-ethtool/etherinfo.h
+++ b/python-ethtool/etherinfo.h
@@ -21,7 +21,6 @@ typedef enum {NLQRY_ADDR4, NLQRY_ADDR6} nlQuery; /**< Supported query types in
int get_etherinfo_link(etherinfo_py *data);
PyObject * get_etherinfo_address(etherinfo_py *self, nlQuery query);
-void free_etherinfo(struct etherinfo *ptr);
int open_netlink(etherinfo_py *);
struct nl_sock * get_nlc();
diff --git a/python-ethtool/etherinfo_obj.c b/python-ethtool/etherinfo_obj.c
index 07e4b58..cdf5263 100644
--- a/python-ethtool/etherinfo_obj.c
+++ b/python-ethtool/etherinfo_obj.c
@@ -34,58 +34,17 @@
/**
* ethtool.etherinfo deallocator - cleans up when a object is deleted
*
- * @param self etherinfo_py object structure
+ * @param self etherinfo_py Python object to deallocate
*/
-void _ethtool_etherinfo_dealloc(etherinfo_py *self)
+static void _ethtool_etherinfo_dealloc(etherinfo_py *self)
{
close_netlink(self);
- if( self->ethinfo ) {
- free_etherinfo(self->ethinfo);
- }
+ Py_XDECREF(self->device); self->device = NULL;
+ Py_XDECREF(self->hwaddress); self->hwaddress = NULL;
self->ob_type->tp_free((PyObject*)self);
}
-/**
- * ethtool.etherinfo function, creating a new etherinfo object
- *
- * @param type
- * @param args
- * @param kwds
- *
- * @return Returns in PyObject with the new object on success, otherwise NULL
- */
-PyObject *_ethtool_etherinfo_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- etherinfo_py *self;
-
- self = (etherinfo_py *)type->tp_alloc(type, 0);
- return (PyObject *)self;
-}
-
-
-/**
- * ethtool.etherinfo init (constructor) method. Makes sure the object is initialised correctly.
- *
- * @param self
- * @param args
- * @param kwds
- *
- * @return Returns 0 on success.
- */
-int _ethtool_etherinfo_init(etherinfo_py *self, PyObject *args, PyObject *kwds)
-{
- static char *etherinfo_kwlist[] = {"etherinfo_ptr", NULL};
- PyObject *ethinf_ptr = NULL;
-
- if( !PyArg_ParseTupleAndKeywords(args, kwds, "O", etherinfo_kwlist, &ethinf_ptr)) {
- PyErr_SetString(PyExc_AttributeError, "Invalid data pointer to constructor");
- return -1;
- }
- self->ethinfo = (struct etherinfo *) PyCObject_AsVoidPtr(ethinf_ptr);
- return 0;
-}
-
/*
The old approach of having a single IPv4 address per device meant each result
that came in from netlink overwrote the old result.
@@ -120,7 +79,7 @@ static PyNetlinkIPaddress * get_last_ipv4_address(PyObject *addrlist)
/**
* ethtool.etherinfo function for retrieving data from a Python object.
*
- * @param self
+ * @param self Pointer to the current etherinfo_py device object
* @param attr_o contains the object member request (which element to return)
*
* @return Returns a PyObject with the value requested on success, otherwise NULL
@@ -131,22 +90,22 @@ PyObject *_ethtool_etherinfo_getter(etherinfo_py *self, PyObject *attr_o)
PyNetlinkIPaddress *py_addr;
PyObject *addrlist = NULL;
- if( !self || !self->ethinfo ) {
+ if( !self ) {
PyErr_SetString(PyExc_AttributeError, "No data available");
return NULL;
}
if( strcmp(attr, "device") == 0 ) {
- if( self->ethinfo->device ) {
- Py_INCREF(self->ethinfo->device);
- return self->ethinfo->device;
+ if( self->device ) {
+ Py_INCREF(self->device);
+ return self->device;
} else {
return Py_INCREF(Py_None), Py_None;
}
} else if( strcmp(attr, "mac_address") == 0 ) {
get_etherinfo_link(self);
- Py_INCREF(self->ethinfo->hwaddress);
- return self->ethinfo->hwaddress;
+ Py_INCREF(self->hwaddress);
+ return self->hwaddress;
} else if( strcmp(attr, "ipv4_address") == 0 ) {
addrlist = get_etherinfo_address(self, NLQRY_ADDR4);
/* For compatiblity with old approach, return last IPv4 address: */
@@ -200,7 +159,7 @@ int _ethtool_etherinfo_setter(etherinfo_py *self, PyObject *attr_o, PyObject *va
/**
* Creates a human readable format of the information when object is being treated as a string
*
- * @param self
+ * @param self Pointer to the current etherinfo_py device object
*
* @return Returns a PyObject with a string with all of the information
*/
@@ -209,7 +168,7 @@ PyObject *_ethtool_etherinfo_str(etherinfo_py *self)
PyObject *ret = NULL;
PyObject *ipv4addrs = NULL, *ipv6addrs = NULL;
- if( !self || !self->ethinfo ) {
+ if( !self ) {
PyErr_SetString(PyExc_AttributeError, "No data available");
return NULL;
}
@@ -217,12 +176,12 @@ PyObject *_ethtool_etherinfo_str(etherinfo_py *self)
get_etherinfo_link(self);
ret = PyString_FromFormat("Device ");
- PyString_Concat(&ret, self->ethinfo->device);
+ PyString_Concat(&ret, self->device);
PyString_ConcatAndDel(&ret, PyString_FromString(":\n"));
- if( self->ethinfo->hwaddress ) {
+ if( self->hwaddress ) {
PyString_ConcatAndDel(&ret, PyString_FromString("\tMAC address: "));
- PyString_Concat(&ret, self->ethinfo->hwaddress);
+ PyString_Concat(&ret, self->hwaddress);
PyString_ConcatAndDel(&ret, PyString_FromString("\n"));
}
@@ -265,13 +224,13 @@ PyObject *_ethtool_etherinfo_str(etherinfo_py *self)
/**
* Returns a tuple list of configured IPv4 addresses
*
- * @param self
+ * @param self Pointer to the current etherinfo_py device object to extract IPv4 info from
* @param notused
*
* @return Returns a Python tuple list of NetlinkIP4Address objects
*/
static PyObject *_ethtool_etherinfo_get_ipv4_addresses(etherinfo_py *self, PyObject *notused) {
- if( !self || !self->ethinfo ) {
+ if( !self ) {
PyErr_SetString(PyExc_AttributeError, "No data available");
return NULL;
}
@@ -281,15 +240,15 @@ static PyObject *_ethtool_etherinfo_get_ipv4_addresses(etherinfo_py *self, PyObj
/**
- * Returns a tuple list of configured IPv4 addresses
+ * Returns a tuple list of configured IPv6 addresses
*
- * @param self
+ * @param self Pointer to the current etherinfo_py device object to extract IPv6 info from
* @param notused
*
* @return Returns a Python tuple list of NetlinkIP6Address objects
*/
static PyObject *_ethtool_etherinfo_get_ipv6_addresses(etherinfo_py *self, PyObject *notused) {
- if( !self || !self->ethinfo ) {
+ if( !self ) {
PyErr_SetString(PyExc_AttributeError, "No data available");
return NULL;
}
@@ -351,8 +310,8 @@ PyTypeObject ethtool_etherinfoType = {
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
- (initproc)_ethtool_etherinfo_init, /* tp_init */
+ 0, /* tp_init */
0, /* tp_alloc */
- _ethtool_etherinfo_new, /* tp_new */
+ 0, /* tp_new */
};
diff --git a/python-ethtool/etherinfo_struct.h b/python-ethtool/etherinfo_struct.h
index 83d06fe..542a2b2 100644
--- a/python-ethtool/etherinfo_struct.h
+++ b/python-ethtool/etherinfo_struct.h
@@ -28,16 +28,6 @@
#include <netlink/route/addr.h>
-/**
- * Contains IP address information about a particular ethernet device
- *
- */
-struct etherinfo {
- PyObject *device; /**< Device name */
- int index; /**< NETLINK index reference */
- PyObject *hwaddress; /**< string: HW address / MAC address of device */
-};
-
/* Python object containing data baked from a (struct rtnl_addr) */
typedef struct PyNetlinkIPaddress {
PyObject_HEAD
@@ -56,8 +46,10 @@ extern PyTypeObject ethtool_netlink_ip_address_Type;
*/
typedef struct {
PyObject_HEAD
- struct etherinfo *ethinfo; /**< Information about the interface configuration */
- unsigned short nlc_active; /**< Is this instance using NETLINK? */
+ PyObject *device; /**< Device name */
+ int index; /**< NETLINK index reference */
+ PyObject *hwaddress; /**< string: HW address / MAC address of device */
+ unsigned short nlc_active; /**< Is this instance using NETLINK? */
} etherinfo_py;
diff --git a/python-ethtool/ethtool.c b/python-ethtool/ethtool.c
index e37bcf1..146618f 100644
--- a/python-ethtool/ethtool.c
+++ b/python-ethtool/ethtool.c
@@ -213,12 +213,12 @@ static PyObject *get_ipaddress(PyObject *self __unused, PyObject *args)
* returned as a list of objects per interface.
*
* @param self Not used
- * @param args Python arguments
+ * @param args Python arguments - device name(s) as either a string or a list
*
* @return Python list of objects on success, otherwise NULL.
*/
static PyObject *get_interfaces_info(PyObject *self __unused, PyObject *args) {
- PyObject *devlist = NULL, *ethinf_py = NULL;
+ PyObject *devlist = NULL;
PyObject *inargs = NULL;
char **fetch_devs = NULL;
int i = 0, fetch_devs_len = 0;
@@ -268,37 +268,25 @@ static PyObject *get_interfaces_info(PyObject *self __unused, PyObject *args) {
devlist = PyList_New(0);
for( i = 0; i < fetch_devs_len; i++ ) {
- struct etherinfo *ethinfo = NULL;
-
- /* Allocate memory for data structures for each interface */
- ethinfo = calloc(1, sizeof(struct etherinfo));
- if( !ethinfo ) {
- PyErr_SetString(PyExc_OSError, strerror(errno));
- free(fetch_devs);
- return NULL;
- }
+ etherinfo_py *dev = NULL;
/* Store the device name and a reference to the NETLINK connection for
* objects to use when quering for device info
*/
- ethinfo->device = PyString_FromString(fetch_devs[i]);
- ethinfo->index = -1;
-
- /* Instantiate a new etherinfo object with the device information */
- ethinf_py = PyCObject_FromVoidPtr(ethinfo, NULL);
- if( ethinf_py ) {
- /* Prepare the argument list for the object constructor */
- PyObject *args = PyTuple_New(1);
- PyTuple_SetItem(args, 0, ethinf_py);
-
- /* Create the object */
- PyObject *dev = PyObject_CallObject((PyObject *)&ethtool_etherinfoType, args);
- if( dev ) {
- PyList_Append(devlist, dev);
- Py_DECREF(dev);
- }
- Py_DECREF(args);
- }
+
+ dev = PyObject_New(etherinfo_py, &ethtool_etherinfoType);
+ if( !dev ) {
+ PyErr_SetString(PyExc_OSError, strerror(errno));
+ free(fetch_devs);
+ return NULL;
+ }
+ dev->device = PyString_FromString(fetch_devs[i]);
+ dev->hwaddress = NULL;
+ dev->index = -1;
+
+ /* Append device object to the device list */
+ PyList_Append(devlist, (PyObject *)dev);
+ Py_DECREF(dev);
}
free(fetch_devs);
@@ -982,3 +970,11 @@ PyMODINIT_FUNC initethtool(void)
PyModule_AddStringConstant(m, "version", "python-ethtool v" VERSION);
}
+
+/*
+Local variables:
+c-basic-offset: 8
+indent-tabs-mode: y
+End:
+*/
+