[libvirt] [PATCH v3 1/4] util: introduce helper to parse /proc/net/arp

Chen Hanxiao posted 4 patches 7 years, 3 months ago
There is a newer version of this series
[libvirt] [PATCH v3 1/4] util: introduce helper to parse /proc/net/arp
Posted by Chen Hanxiao 7 years, 3 months ago
From: Chen Hanxiao <chenhanxiao@gmail.com>

introduce helper to parse /proc/net/arp and
store it in struct virArpTable.

Signed-off-by: Chen Hanxiao <chenhanxiao@gmail.com>
---
v3:
  s/virGetArpTable/virArpTableGet
  alloc virArpTable in virArpTableGet
  return ENOSUPP on none-Linux platform
  move helpers to virarptable.[ch]

 po/POTFILES.in           |   1 +
 src/Makefile.am          |   1 +
 src/libvirt_private.syms |   5 +++
 src/util/virarptable.c   | 114 +++++++++++++++++++++++++++++++++++++++++++++++
 src/util/virarptable.h   |  48 ++++++++++++++++++++
 5 files changed, 169 insertions(+)
 create mode 100644 src/util/virarptable.c
 create mode 100644 src/util/virarptable.h

diff --git a/po/POTFILES.in b/po/POTFILES.in
index 8382ee633..91a4c5730 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -193,6 +193,7 @@ src/uml/uml_conf.c
 src/uml/uml_driver.c
 src/util/iohelper.c
 src/util/viralloc.c
+src/util/virarptable.c
 src/util/viraudit.c
 src/util/virauth.c
 src/util/virauthconfig.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 289b03747..923eea6fe 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -98,6 +98,7 @@ augeastest_DATA =
 UTIL_SOURCES = \
 		util/viralloc.c util/viralloc.h \
 		util/virarch.h util/virarch.c \
+		util/virarptable.h util/virarptable.c \
 		util/viratomic.h util/viratomic.c \
 		util/viraudit.c util/viraudit.h \
 		util/virauth.c util/virauth.h \
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index f2a2c8650..08229797a 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1332,6 +1332,11 @@ virArchGetWordSize;
 virArchToString;
 
 
+# util/virarptable.h
+virArpTableFree;
+virArpTableGet;
+
+
 # util/viraudit.h
 virAuditClose;
 virAuditEncode;
diff --git a/src/util/virarptable.c b/src/util/virarptable.c
new file mode 100644
index 000000000..48a38352f
--- /dev/null
+++ b/src/util/virarptable.c
@@ -0,0 +1,114 @@
+/*
+ * virarptable.c Linux ARP table handling
+ *
+ * Copyright (C) 2018 Chen Hanxiao
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *     Chen Hanxiao <chenhanxiao@gmail.com>
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "viralloc.h"
+#include "virarptable.h"
+#include "virfile.h"
+#include "virstring.h"
+
+#define VIR_FROM_THIS VIR_FROM_NONE
+
+#ifdef __linux__
+
+virArpTablePtr virArpTableGet(void)
+{
+    FILE *fp = NULL;
+    char line[1024];
+    int num = 0;
+    virArpTablePtr table = NULL;
+
+    if (VIR_ALLOC(table) < 0)
+        return NULL;
+
+    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;
+
+        if (VIR_REALLOC_N(table->t, num + 1) < 0)
+            goto cleanup;
+
+        table->n = num + 1;
+
+        /* /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].ipaddr, ip) < 0)
+            goto cleanup;
+
+        if (VIR_STRDUP(table->t[num].mac, mac) < 0)
+            goto cleanup;
+
+        if (VIR_STRDUP(table->t[num].dev_name, dev_name) < 0)
+            goto cleanup;
+
+        num++;
+    }
+
+    return table;
+
+ cleanup:
+    VIR_FORCE_FCLOSE(fp);
+    return NULL;
+}
+
+#else
+
+virArpTablePtr virArpTableGet(void)
+{
+    virReportError(VIR_ERR_NO_SUPPORT, "%s",
+                   _("get arp table not implemented on this platform"));
+    return NULL;
+}
+
+#endif /* __linux__ */
+
+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/virarptable.h b/src/util/virarptable.h
new file mode 100644
index 000000000..77db4e9f4
--- /dev/null
+++ b/src/util/virarptable.h
@@ -0,0 +1,48 @@
+/*
+ * virarptable.h Linux ARP table handling
+ *
+ * Copyright (C) 2018 Chen Hanxiao
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *     Chen Hanxiao <chenhanxiao@gmail.com>
+ */
+
+#ifndef __VIR_ARPTABLE_H__
+# define __VIR_ARPTABLE_H__
+
+# include "internal.h"
+
+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;
+};
+
+virArpTablePtr virArpTableGet(void);
+void virArpTableFree(virArpTablePtr table);
+
+#endif /* __VIR_ARPTABLE_H__ */
-- 
2.14.3

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v3 1/4] util: introduce helper to parse /proc/net/arp
Posted by Peter Krempa 7 years, 3 months ago
On Mon, Jan 29, 2018 at 16:35:33 +0800, Chen Hanxiao wrote:
> From: Chen Hanxiao <chenhanxiao@gmail.com>
> 
> introduce helper to parse /proc/net/arp and
> store it in struct virArpTable.
> 
> Signed-off-by: Chen Hanxiao <chenhanxiao@gmail.com>
> ---
> v3:
>   s/virGetArpTable/virArpTableGet
>   alloc virArpTable in virArpTableGet
>   return ENOSUPP on none-Linux platform
>   move helpers to virarptable.[ch]
> 
>  po/POTFILES.in           |   1 +
>  src/Makefile.am          |   1 +
>  src/libvirt_private.syms |   5 +++
>  src/util/virarptable.c   | 114 +++++++++++++++++++++++++++++++++++++++++++++++
>  src/util/virarptable.h   |  48 ++++++++++++++++++++
>  5 files changed, 169 insertions(+)
>  create mode 100644 src/util/virarptable.c
>  create mode 100644 src/util/virarptable.h
> 
> diff --git a/po/POTFILES.in b/po/POTFILES.in
> index 8382ee633..91a4c5730 100644
> --- a/po/POTFILES.in
> +++ b/po/POTFILES.in
> @@ -193,6 +193,7 @@ src/uml/uml_conf.c
>  src/uml/uml_driver.c
>  src/util/iohelper.c
>  src/util/viralloc.c
> +src/util/virarptable.c
>  src/util/viraudit.c
>  src/util/virauth.c
>  src/util/virauthconfig.c
> diff --git a/src/Makefile.am b/src/Makefile.am
> index 289b03747..923eea6fe 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -98,6 +98,7 @@ augeastest_DATA =
>  UTIL_SOURCES = \
>  		util/viralloc.c util/viralloc.h \
>  		util/virarch.h util/virarch.c \
> +		util/virarptable.h util/virarptable.c \
>  		util/viratomic.h util/viratomic.c \
>  		util/viraudit.c util/viraudit.h \
>  		util/virauth.c util/virauth.h \
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index f2a2c8650..08229797a 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -1332,6 +1332,11 @@ virArchGetWordSize;
>  virArchToString;
>  
>  
> +# util/virarptable.h
> +virArpTableFree;
> +virArpTableGet;
> +
> +
>  # util/viraudit.h
>  virAuditClose;
>  virAuditEncode;
> diff --git a/src/util/virarptable.c b/src/util/virarptable.c
> new file mode 100644
> index 000000000..48a38352f
> --- /dev/null
> +++ b/src/util/virarptable.c
> @@ -0,0 +1,114 @@
> +/*
> + * virarptable.c Linux ARP table handling
> + *
> + * Copyright (C) 2018 Chen Hanxiao
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library.  If not, see
> + * <http://www.gnu.org/licenses/>.
> + *
> + * Authors:
> + *     Chen Hanxiao <chenhanxiao@gmail.com>
> + */
> +
> +#include <config.h>
> +
> +#include <stdlib.h>
> +#include <stdio.h>
> +
> +#include "viralloc.h"
> +#include "virarptable.h"
> +#include "virfile.h"
> +#include "virstring.h"
> +
> +#define VIR_FROM_THIS VIR_FROM_NONE
> +
> +#ifdef __linux__
> +
> +virArpTablePtr virArpTableGet(void)
> +{
> +    FILE *fp = NULL;
> +    char line[1024];
> +    int num = 0;
> +    virArpTablePtr table = NULL;
> +
> +    if (VIR_ALLOC(table) < 0)
> +        return NULL;
> +
> +    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],

I don't think hardcoding the lenghts ...



> +             flags[32], mask[32], nouse[32];
> +
> +        if (STRPREFIX(line, "IP address"))
> +            continue;
> +
> +        if (VIR_REALLOC_N(table->t, num + 1) < 0)
> +            goto cleanup;
> +
> +        table->n = num + 1;
> +
> +        /* /proc/net/arp looks like:
> +         * 172.16.17.254  0x1 0x2  e4:68:a3:8d:ed:d3  *   enp3s0
> +         */
> +        sscanf(line, "%[0-9.]%[ ]%[^ ]%[ ]%[^ ]%[ ]%[^ ]%[ ]%[^ ]%[ ]%[^ \t\n]",


without limiting the size here is a great idea. That is a buffer
overflow right here.

Also parsing /proc/net/arp is not enough, it will not list IPv6
neighbors.

Additionally I'd stay away from parsing this file completely. Not even
the obsolete 'arp' utility is using this but rather uses AF_NETLINK
socket to discover it.

NACK on this approach.
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v3 1/4] util: introduce helper to parse /proc/net/arp
Posted by Chen Hanxiao 7 years, 3 months ago

At 2018-01-29 20:01:30, "Peter Krempa" <pkrempa@redhat.com> wrote:
>On Mon, Jan 29, 2018 at 16:35:33 +0800, Chen Hanxiao wrote:
>> From: Chen Hanxiao <chenhanxiao@gmail.com>
>> 
>> introduce helper to parse /proc/net/arp and
>> store it in struct virArpTable.
>> 
>> Signed-off-by: Chen Hanxiao <chenhanxiao@gmail.com>
>> ---
>> v3:
[...]
>
>
>without limiting the size here is a great idea. That is a buffer
>overflow right here.
>
>Also parsing /proc/net/arp is not enough, it will not list IPv6
>neighbors.
>
>Additionally I'd stay away from parsing this file completely. Not even
>the obsolete 'arp' utility is using this but rather uses AF_NETLINK
>socket to discover it.
>
>NACK on this approach.

I'll use RTM_GETNEIGH to get these.
Thanks for the advice.

Regards,
- Chen

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list