summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Sommerseth <davids@redhat.com>2009-09-07 17:24:42 +0200
committerDavid Sommerseth <davids@redhat.com>2009-09-07 17:24:42 +0200
commitec9e13c0da2e6ebfb16e60c19c11539fa8b81442 (patch)
tree628667947792eab472552930149bcd7ee164d4af
parent0be405b9c6245b59489b7e6987af0dc56ded1406 (diff)
downloadpython-ethtool-ec9e13c0da2e6ebfb16e60c19c11539fa8b81442.tar.gz
python-ethtool-ec9e13c0da2e6ebfb16e60c19c11539fa8b81442.tar.xz
python-ethtool-ec9e13c0da2e6ebfb16e60c19c11539fa8b81442.zip
Completed implementing the new Python get_interface_info() function.
It will return a list of Python etherinfo objects. These objects have the following properties: .device - Device name .mac_address - Hardware address .ipv4_address .ipv4_netmask .ipv4_broadcast .ipv6_address .ipv6_netmask In addition, it will produce a human readable output if these objects are treated as strings. It will not be possible to modify any of the properties in these objects.
-rw-r--r--python-ethtool/etherinfo_obj.c74
-rw-r--r--python-ethtool/etherinfo_obj.h3
-rw-r--r--python-ethtool/ethtool.c64
3 files changed, 124 insertions, 17 deletions
diff --git a/python-ethtool/etherinfo_obj.c b/python-ethtool/etherinfo_obj.c
index 5e9878c..cfdd492 100644
--- a/python-ethtool/etherinfo_obj.c
+++ b/python-ethtool/etherinfo_obj.c
@@ -41,8 +41,6 @@ PyObject *_ethtool_etherinfo_new(PyTypeObject *type, PyObject *args, PyObject *k
etherinfo_py *self;
self = (etherinfo_py *)type->tp_alloc(type, 0);
- if (self != NULL) {
- }
return (PyObject *)self;
}
@@ -58,12 +56,25 @@ PyObject *_ethtool_etherinfo_new(PyTypeObject *type, PyObject *args, PyObject *k
*/
int _ethtool_etherinfo_init(etherinfo_py *self, PyObject *args, PyObject *kwds)
{
- self->info = (struct etherinfo *) malloc(sizeof(struct etherinfo)+2);
- memset(self->info, 0, sizeof(struct etherinfo)+2);
- self->info->device = strdup("test");
+ 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->info = (struct etherinfo *) PyCObject_AsVoidPtr(ethinf_ptr);
return 0;
}
+/**
+ * Null safe PyString_FromString() wrapper. If input string is NULL, a False value will be returned
+ *
+ * @param str Input C string (char *)
+ *
+ * @return Returns a PyObject with either the input string wrapped up, or a Python False value.
+ */
+#define RETURN_STRING(str) (str ? PyString_FromString(str) : Py_False);
/**
* ethtool.etherinfo function for retrieving data from a Python object.
@@ -83,17 +94,17 @@ PyObject *_ethtool_etherinfo_getter(etherinfo_py *self, PyObject *attr_o)
}
if( strcmp(attr, "device") == 0 ) {
- return PyString_FromString(self->info->device);
+ return RETURN_STRING(self->info->device);
} else if( strcmp(attr, "mac_address") == 0 ) {
- return PyString_FromString(self->info->hwaddress);
+ return RETURN_STRING(self->info->hwaddress);
} else if( strcmp(attr, "ipv4_address") == 0 ) {
- return PyString_FromString(self->info->ipv4_address);
+ return RETURN_STRING(self->info->ipv4_address);
} else if( strcmp(attr, "ipv4_netmask") == 0 ) {
return PyInt_FromLong(self->info->ipv4_netmask);
} else if( strcmp(attr, "ipv4_broadcast") == 0 ) {
- return PyString_FromString(self->info->ipv4_broadcast);
+ return RETURN_STRING(self->info->ipv4_broadcast);
} else if( strcmp(attr, "ipv6_address") == 0 ) {
- return PyString_FromString(self->info->ipv6_address);
+ return RETURN_STRING(self->info->ipv6_address);
} else if( strcmp(attr, "ipv6_netmask") == 0 ) {
return PyInt_FromLong(self->info->ipv6_netmask);
}
@@ -119,3 +130,46 @@ 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
+ *
+ * @return Returns a PyObject with a string with all of the information
+ */
+PyObject *_ethtool_etherinfo_str(etherinfo_py *self)
+{
+ PyObject *ret = NULL;
+
+ if( !self || !self->info ) {
+ PyErr_SetString(PyExc_AttributeError, "No data available");
+ return NULL;
+ }
+
+ ret = PyString_FromFormat("Device %s:\n", self->info->device);
+ if( self->info->hwaddress ) {
+ PyObject *tmp = PyString_FromFormat("\tMAC address: %s\n", self->info->hwaddress);
+ PyString_Concat(&ret, tmp);
+ }
+
+ if( self->info->ipv4_address ) {
+ PyObject *tmp = PyString_FromFormat("\tIPv4 address: %s/%i",
+ self->info->ipv4_address,
+ self->info->ipv4_netmask);
+ if( self->info->ipv4_broadcast ) {
+ PyObject *tmp2 = PyString_FromFormat(" Broadcast: %s",
+ self->info->ipv4_broadcast);
+ PyString_Concat(&tmp, tmp2);
+ }
+ PyString_Concat(&tmp, PyString_FromString("\n"));
+ PyString_Concat(&ret, tmp);
+ }
+
+ if( self->info->ipv6_address ) {
+ PyObject *tmp = PyString_FromFormat("\tIPv6 address: %s/%i\n",
+ self->info->ipv6_address,
+ self->info->ipv6_netmask);
+ PyString_Concat(&ret, tmp);
+ }
+ return ret;
+}
diff --git a/python-ethtool/etherinfo_obj.h b/python-ethtool/etherinfo_obj.h
index dae5352..8ffdf7d 100644
--- a/python-ethtool/etherinfo_obj.h
+++ b/python-ethtool/etherinfo_obj.h
@@ -20,6 +20,7 @@ PyObject *_ethtool_etherinfo_new(PyTypeObject *, PyObject *, PyObject *);
int _ethtool_etherinfo_init(etherinfo_py *, PyObject *, PyObject *);
PyObject *_ethtool_etherinfo_getter(etherinfo_py *, PyObject *);
int _ethtool_etherinfo_setter(etherinfo_py *, PyObject *, PyObject *);
+PyObject *_ethtool_etherinfo_str(etherinfo_py *self);
/**
* This is required by Python, which lists all accessible methods
@@ -73,7 +74,7 @@ PyTypeObject ethtool_etherinfoType = {
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
- 0, /*tp_str*/
+ (reprfunc)_ethtool_etherinfo_str, /*tp_str*/
(getattrofunc)_ethtool_etherinfo_getter, /*tp_getattro*/
(setattrofunc)_ethtool_etherinfo_setter, /*tp_setattro*/
0, /*tp_as_buffer*/
diff --git a/python-ethtool/ethtool.c b/python-ethtool/ethtool.c
index cdd8394..27e10f2 100644
--- a/python-ethtool/ethtool.c
+++ b/python-ethtool/ethtool.c
@@ -45,9 +45,6 @@ typedef __uint8_t u8;
#define _PATH_PROCNET_DEV "/proc/net/dev"
-struct etherinfo *ethernet_devices = NULL;
-int etherinfo_cache_dirty = 0;
-
static PyObject *get_active_devices(PyObject *self __unused, PyObject *args __unused)
{
PyObject *list;
@@ -226,10 +223,9 @@ static PyObject *get_ipaddress(PyObject *self __unused, PyObject *args)
static PyObject *get_ipaddresses(PyObject *self __unused, PyObject *args) {
PyObject *devlist = NULL;
struct etherinfo *ethptr = NULL;
+ struct etherinfo *ethernet_devices = NULL;
- if( ethernet_devices == NULL ) {
- ethernet_devices = get_etherinfo();
- }
+ ethernet_devices = get_etherinfo();
devlist = PyList_New(0);
for( ethptr = ethernet_devices; ethptr->next != NULL; ethptr = ethptr->next) {
@@ -248,6 +244,57 @@ static PyObject *get_ipaddresses(PyObject *self __unused, PyObject *args) {
PyList_Append(devlist, dev);
}
}
+ free_etherinfo(ethernet_devices);
+
+ return devlist;
+}
+
+
+/**
+ * Retrieves the current information about all interfaces. All interfaces will be
+ * returned as a list of objects per interface.
+ *
+ * @param self Not used
+ * @param args Python arguments
+ *
+ * @return Python list of objects on success, otherwise NULL.
+ */
+static PyObject *get_interfaceinfo(PyObject *self __unused, PyObject *args) {
+ PyObject *devlist = NULL, *ethinf_py = NULL;
+ struct etherinfo *devinfo = NULL, *ptr = NULL;
+
+ devinfo = get_etherinfo();
+ if( !devinfo ) {
+ PyErr_SetString(PyExc_OSError, strerror(errno));
+ return NULL;
+ }
+
+ /* Slice up the etherinfo struct and populate individual objects with
+ * the current ethernet information.
+ */
+ devlist = PyList_New(0);
+ while( devinfo->next != NULL ) {
+ /* Get copy of pointers, before we start slicing it up */
+ ptr = devinfo->next; /* Fetch the pointer to the next element first */
+ devinfo->next = NULL; /* Make the current slice do not point anywhere else */
+
+ /* Instantiate a new etherinfo object with the device information */
+ ethinf_py = PyCObject_FromVoidPtr(devinfo, 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);
+ PyList_Append(devlist, dev);
+ }
+ devinfo = ptr; /* Go to the next element */
+ }
+ /* clean up headers which might not be used or considered interesting */
+ if( devinfo != NULL ) {
+ free_etherinfo(devinfo);
+ }
return devlist;
}
@@ -817,6 +864,11 @@ static struct PyMethodDef PyEthModuleMethods[] = {
.ml_flags = METH_VARARGS,
},
{
+ .ml_name = "get_interface_info",
+ .ml_meth = (PyCFunction)get_interfaceinfo,
+ .ml_flags = METH_VARARGS,
+ },
+ {
.ml_name = "get_netmask",
.ml_meth = (PyCFunction)get_netmask,
.ml_flags = METH_VARARGS,