From: Chen Hanxiao <chenhanxiao@xxxxxxxxx> introduce helper to parse /proc/net/arp and store it in struct virArpTable. Signed-off-by: Chen Hanxiao <chenhanxiao@xxxxxxxxx> --- src/libvirt_private.syms | 2 ++ src/util/virmacaddr.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ src/util/virmacaddr.h | 18 +++++++++++++ 3 files changed, 87 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index bc8cc1fba..26385a2e9 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2133,6 +2133,8 @@ virLogVMessage; # util/virmacaddr.h +virArpTableFree; +virGetArpTable; virMacAddrCmp; virMacAddrCmpRaw; virMacAddrCompare; diff --git a/src/util/virmacaddr.c b/src/util/virmacaddr.c index 409fdc34d..540bdbbaa 100644 --- a/src/util/virmacaddr.c +++ b/src/util/virmacaddr.c @@ -27,10 +27,15 @@ #include <stdio.h> #include "c-ctype.h" +#include "viralloc.h" +#include "virfile.h" #include "virmacaddr.h" #include "virrandom.h" +#include "virstring.h" #include "virutil.h" +#define VIR_FROM_THIS VIR_FROM_NONE + static const unsigned char virMacAddrBroadcastAddrRaw[VIR_MAC_BUFLEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; @@ -257,3 +262,65 @@ virMacAddrIsBroadcastRaw(const unsigned char s[VIR_MAC_BUFLEN]) { return memcmp(virMacAddrBroadcastAddrRaw, s, sizeof(*s)) == 0; } + +int +virGetArpTable(virArpTablePtr *table) +{ +#define PROC_NET_ARP "/proc/net/arp" + FILE *fp = NULL; + char line[1024]; + int num = 0; + int ret = -1; + + if (!(fp = fopen(PROC_NET_ARP, "r"))) + goto cleanup; + + while (fgets(line, sizeof(line), fp)) { + char ip[32], mac[32], dev_name[32], hwtype[32], + flags[32], mask[32], nouse[32]; + + if (STRPREFIX(line, "IP address")) + continue; + + num++; + if (VIR_REALLOC_N((*table)->t, num) < 0) + goto cleanup; + (*table)->n = num; + /* /proc/net/arp looks like: + * 172.16.17.254 0x1 0x2 e4:68:a3:8d:ed:d3 * enp3s0 + */ + sscanf(line, "%[0-9.]%[ ]%[^ ]%[ ]%[^ ]%[ ]%[^ ]%[ ]%[^ ]%[ ]%[^ \t\n]", + ip, nouse, + hwtype, nouse, + flags, nouse, + mac, nouse, + mask, nouse, + dev_name); + + + if (VIR_STRDUP((*table)->t[num - 1].ipaddr, ip) < 0) + goto cleanup; + if (VIR_STRDUP((*table)->t[num - 1].mac, mac) < 0) + goto cleanup; + if (VIR_STRDUP((*table)->t[num - 1].dev_name, dev_name) < 0) + goto cleanup; + } + + ret = 0; + + cleanup: + VIR_FORCE_FCLOSE(fp); + return ret; +} + +void +virArpTableFree(virArpTablePtr table) +{ + size_t i; + for (i = 0; i < table->n; i++) { + VIR_FREE(table->t[i].ipaddr); + VIR_FREE(table->t[i].mac); + VIR_FREE(table->t[i].dev_name); + } + VIR_FREE(table); +} diff --git a/src/util/virmacaddr.h b/src/util/virmacaddr.h index ef4285d63..eb18092d1 100644 --- a/src/util/virmacaddr.h +++ b/src/util/virmacaddr.h @@ -40,6 +40,22 @@ struct _virMacAddr { false otherwise. */ }; +typedef struct _virArpTableEntry virArpTableEntry; +typedef virArpTableEntry *virArpTableEntryPtr; +typedef struct _virArpTable virArpTable; +typedef virArpTable *virArpTablePtr; + +struct _virArpTableEntry{ + char *ipaddr; + char *mac; + char *dev_name; +}; + +struct _virArpTable { + int n; + virArpTableEntryPtr t; +}; + int virMacAddrCompare(const char *mac1, const char *mac2); int virMacAddrCmp(const virMacAddr *mac1, const virMacAddr *mac2); int virMacAddrCmpRaw(const virMacAddr *mac1, @@ -59,5 +75,7 @@ int virMacAddrParseHex(const char* str, bool virMacAddrIsUnicast(const virMacAddr *addr); bool virMacAddrIsMulticast(const virMacAddr *addr); bool virMacAddrIsBroadcastRaw(const unsigned char s[VIR_MAC_BUFLEN]); +int virGetArpTable(virArpTablePtr *table); +void virArpTableFree(virArpTablePtr table); #endif /* __VIR_MACADDR_H__ */ -- 2.14.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list