diff options
author | David Sommerseth <davids@redhat.com> | 2009-09-07 17:24:42 +0200 |
---|---|---|
committer | David Sommerseth <davids@redhat.com> | 2009-09-07 17:24:42 +0200 |
commit | ec9e13c0da2e6ebfb16e60c19c11539fa8b81442 (patch) | |
tree | 628667947792eab472552930149bcd7ee164d4af | |
parent | 0be405b9c6245b59489b7e6987af0dc56ded1406 (diff) | |
download | python-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.c | 74 | ||||
-rw-r--r-- | python-ethtool/etherinfo_obj.h | 3 | ||||
-rw-r--r-- | python-ethtool/ethtool.c | 64 |
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, ðinf_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 *)ðtool_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, |