summaryrefslogtreecommitdiffstats
path: root/python-ethtool/etherinfo.c
diff options
context:
space:
mode:
authorDavid Sommerseth <davids@redhat.com>2010-04-28 17:04:26 +0200
committerDavid Sommerseth <davids@redhat.com>2010-04-28 17:04:26 +0200
commit4f0295fca2cfd933f4b9b539d5505cb24e4d420c (patch)
treedd765ba839c30cbf45217983bbc39533c575c695 /python-ethtool/etherinfo.c
parentd3fd6b84f461a4d7ffbf3f3eae37381150b69e82 (diff)
downloadpython-ethtool-4f0295fca2cfd933f4b9b539d5505cb24e4d420c.tar.gz
python-ethtool-4f0295fca2cfd933f4b9b539d5505cb24e4d420c.tar.xz
python-ethtool-4f0295fca2cfd933f4b9b539d5505cb24e4d420c.zip
Updated to fetch the interface information when the "getter" function triggers
Diffstat (limited to 'python-ethtool/etherinfo.c')
-rw-r--r--python-ethtool/etherinfo.c141
1 files changed, 59 insertions, 82 deletions
diff --git a/python-ethtool/etherinfo.c b/python-ethtool/etherinfo.c
index 6075f30..7ae5798 100644
--- a/python-ethtool/etherinfo.c
+++ b/python-ethtool/etherinfo.c
@@ -24,14 +24,9 @@
#include <stdlib.h>
#include <asm/types.h>
#include <sys/socket.h>
-#include <netlink/addr.h>
-#include <netlink/netlink.h>
-#include <netlink/handlers.h>
-#include <netlink/route/link.h>
-#include <netlink/route/addr.h>
-#include <arpa/inet.h>
#include <assert.h>
#include <errno.h>
+#include "etherinfo_struct.h"
#include "etherinfo.h"
/*
@@ -39,20 +34,6 @@
* Internal functions for working with struct etherinfo
*
*/
-
-inline struct etherinfo *new_etherinfo_record()
-{
- struct etherinfo *ptr;
-
- ptr = malloc(sizeof(struct etherinfo)+1);
- if( ptr ) {
- memset(ptr, 0, sizeof(struct etherinfo)+1);
- }
-
- return ptr;
-}
-
-
void free_etherinfo(struct etherinfo *ptr)
{
if( ptr == NULL ) { // Just for safety
@@ -82,6 +63,13 @@ void free_etherinfo(struct etherinfo *ptr)
*
*/
+#define SET_STR_VALUE(dst, src) { \
+ if( dst ) { \
+ free(dst); \
+ }; \
+ dst = strdup(src); \
+ }
+
static void callback_nl_link(struct nl_object *obj, void *arg)
{
struct etherinfo *ethi = (struct etherinfo *) arg;
@@ -110,7 +98,7 @@ static void callback_nl_link(struct nl_object *obj, void *arg)
ptr += 3;
}
}
- ethi->hwaddress = strdup(hwaddr);
+ SET_STR_VALUE(ethi->hwaddress, hwaddr);
}
@@ -137,16 +125,16 @@ static void callback_nl_address(struct nl_object *obj, void *arg)
struct nl_addr *brdcst = rtnl_addr_get_broadcast((struct rtnl_addr *)obj);
char brdcst_str[66];
- ethi->ipv4_address = strdup(ip_str);
+ SET_STR_VALUE(ethi->ipv4_address, ip_str);
ethi->ipv4_netmask = rtnl_addr_get_prefixlen((struct rtnl_addr*) obj);
if( brdcst ) {
memset(&brdcst_str, 0, 66);
inet_ntop(family, nl_addr_get_binary_addr(brdcst), (char *)&brdcst_str, 64);
- ethi->ipv4_broadcast = strdup(brdcst_str);
+ SET_STR_VALUE(ethi->ipv4_broadcast, brdcst_str);
}
} else {
- ethi->ipv6_address = strdup(ip_str);
+ SET_STR_VALUE(ethi->ipv6_address, ip_str);
ethi->ipv6_netmask = rtnl_addr_get_prefixlen((struct rtnl_addr*) obj);
}
return;
@@ -186,70 +174,59 @@ void dump_etherinfo(FILE *fp, struct etherinfo *ptr)
fprintf(fp, "\n");
}
-struct etherinfo *get_etherinfo(const char *ifdevname)
+
+int get_etherinfo(struct etherinfo *ethinf, struct _nlconnection *nlc, nlQuery query)
{
- struct etherinfo *ethinf = NULL;
- struct nl_handle *handle;
struct nl_cache *link_cache;
struct nl_cache *addr_cache;
struct rtnl_addr *addr;
struct rtnl_link *link;
- int ifindex;
-
- /* Establish connection to NETLINK */
- handle = nl_handle_alloc();
- nl_connect(handle, NETLINK_ROUTE);
-
- /* Find the interface index we're looking up */
- link_cache = rtnl_link_alloc_cache(handle);
- ifindex = rtnl_link_name2i(link_cache, ifdevname);
- if( ifindex < 0 ) {
- return NULL;
- }
-
- /* Create an empty record, where ethernet information will be saved */
- ethinf = new_etherinfo_record();
- if( !ethinf ) {
- return NULL;
- }
- ethinf->index = ifindex;
- ethinf->device = strdup(ifdevname); /* Should extract via libnl - nl_link callback? */
-
- /* Extract MAC/hardware address of the interface */
- link = rtnl_link_alloc();
- rtnl_link_set_ifindex(link, ifindex);
- nl_cache_foreach_filter(link_cache, (struct nl_object *)link, callback_nl_link, ethinf);
- rtnl_link_put(link);
- nl_cache_free(link_cache);
-
- /* Extract IP address information */
- addr_cache = rtnl_addr_alloc_cache(handle);
- addr = rtnl_addr_alloc();
- rtnl_addr_set_ifindex(addr, ifindex);
- nl_cache_foreach_filter(addr_cache, (struct nl_object *)addr, callback_nl_address, ethinf);
- rtnl_addr_put(addr);
- nl_cache_free(addr_cache);
-
- /* Close NETLINK connection */
- nl_close(handle);
- nl_handle_destroy(handle);
-
- return ethinf;
-}
+ int ret = 0;
-#ifdef TESTPROG
-// Simple standalone test program
-int main(int argc, char **argv) {
- struct etherinfo *inf = NULL;
-
- inf = get_etherinfo(argv[1]);
- if( inf == NULL ) {
- fprintf(stderr, "Operation failed. Could not retrieve ethernet information\n");
- exit(2);
+ if( !ethinf || !nlc ) {
+ return 0;
}
- dump_etherinfo(stdout, inf);
- free_etherinfo(inf);
- return 0;
+ /* Find the interface index we're looking up.
+ * As we don't expect it to change, we're reusing a "cached"
+ * interface index if we have that
+ */
+ if( ethinf->index < 0 ) {
+ link_cache = rtnl_link_alloc_cache(nlc->nlrt_handle);
+ ethinf->index = rtnl_link_name2i(link_cache, ethinf->device);
+ if( ethinf->index < 0 ) {
+ return 0;
+ }
+ nl_cache_free(link_cache);
+ }
+
+ /* Query the for requested info vai NETLINK */
+ switch( query ) {
+ case NLQRY_LINK:
+ /* Extract MAC/hardware address of the interface */
+ link_cache = rtnl_link_alloc_cache(nlc->nlrt_handle);
+ link = rtnl_link_alloc();
+ rtnl_link_set_ifindex(link, ethinf->index);
+ nl_cache_foreach_filter(link_cache, (struct nl_object *)link, callback_nl_link, ethinf);
+ rtnl_link_put(link);
+ nl_cache_free(link_cache);
+ ret = 1;
+ break;
+
+ case NLQRY_ADDR:
+ /* Extract IP address information */
+ addr_cache = rtnl_addr_alloc_cache(nlc->nlrt_handle);
+ addr = rtnl_addr_alloc();
+ rtnl_addr_set_ifindex(addr, ethinf->index);
+ nl_cache_foreach_filter(addr_cache, (struct nl_object *)addr, callback_nl_address, ethinf);
+ rtnl_addr_put(addr);
+ nl_cache_free(addr_cache);
+ ret = 1;
+ break;
+
+ default:
+ ret = 0;
+ }
+ return ret;
}
-#endif
+