From nobody Thu May 15 00:31:36 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=126.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1520493381093658.6013979173136; Wed, 7 Mar 2018 23:16:21 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id DF8D2C04BE00; Thu, 8 Mar 2018 07:16:19 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id BA2955D77E; Thu, 8 Mar 2018 07:16:19 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 7D7D24CAA0; Thu, 8 Mar 2018 07:16:19 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w287DESt021164 for ; Thu, 8 Mar 2018 02:13:14 -0500 Received: by smtp.corp.redhat.com (Postfix) id DF7965D6B7; Thu, 8 Mar 2018 07:13:14 +0000 (UTC) Received: from mx1.redhat.com (ext-mx06.extmail.prod.ext.phx2.redhat.com [10.5.110.30]) by smtp.corp.redhat.com (Postfix) with ESMTPS id D80D45D6A6 for ; Thu, 8 Mar 2018 07:13:14 +0000 (UTC) Received: from m15-113.126.com (m15-113.126.com [220.181.15.113]) by mx1.redhat.com (Postfix) with ESMTP id CD31E2820C for ; Thu, 8 Mar 2018 07:13:10 +0000 (UTC) Received: from localhost.localdomain (unknown [58.213.111.46]) by smtp3 (Coremail) with SMTP id DcmowACni0Fq4qBaI2dGBA--.64188S4; Thu, 08 Mar 2018 15:13:07 +0800 (CST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=126.com; s=s110527; h=From:Subject:Date:Message-Id; bh=tkwnddWbtA+RerQiZv v6bQhbJ+5/eiJDofN4IZG8Qww=; b=fP6w78YR0xppaTbvYIeKm2E/OQV88ulJwH q/Zc1WyE6gj506FyiVwPO8PIxu/POrwPo+SeiCg5vRTlyUvl9FebP3fBsUqov53K UMKdVHvklpA3XB9C8JRInFnNp/GSXLZ2XTZD2tj+/O7gIWqjGHJNEHdHTe8Zz59n 2M2sRSyfo= From: Chen Hanxiao To: libvir-list@redhat.com Date: Thu, 8 Mar 2018 15:11:56 +0800 Message-Id: <20180308071159.9861-3-chen_han_xiao@126.com> In-Reply-To: <20180308071159.9861-1-chen_han_xiao@126.com> References: <20180308071159.9861-1-chen_han_xiao@126.com> X-CM-TRANSID: DcmowACni0Fq4qBaI2dGBA--.64188S4 X-Coremail-Antispam: 1Uf129KBjvJXoW3AFWkGw15GFW5Jr4rAw4Dtwb_yoW3tw17pF y5C3Z0qw4rJ3WxC3s3KF4FyF1Y9rs7Wr18Ww1fur1qyw18tF17Xrn7Kr9rKFWxJ3y3Cr1S 9rs3KFyjkrs5J3DanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07j4FAJUUUUU= X-Originating-IP: [58.213.111.46] X-CM-SenderInfo: xfkh0spkdqs5xldrqiyswou0bp/1tbi4wMDrlpD4-v5RwABsz X-Greylist: Sender passed SPF test, ACL 227 matched, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Thu, 08 Mar 2018 07:13:12 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Thu, 08 Mar 2018 07:13:12 +0000 (UTC) for IP:'220.181.15.113' DOMAIN:'m15-113.126.com' HELO:'m15-113.126.com' FROM:'chen_han_xiao@126.com' RCPT:'' X-RedHat-Spam-Score: -0.11 (DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, SPF_PASS, T_RP_MATCHES_RCVD) 220.181.15.113 m15-113.126.com 220.181.15.113 m15-113.126.com X-Scanned-By: MIMEDefang 2.78 on 10.5.110.30 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Cc: Chen Hanxiao Subject: [libvirt] [PATCH rebase v4 2/5] util: introduce helper to parse message from RTM_GETNEIGH query X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Thu, 08 Mar 2018 07:16:20 +0000 (UTC) X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" From: Chen Hanxiao introduce helper to parse RTM_GETNEIGH query message and store it in struct virArpTable. Signed-off-by: Chen Hanxiao --- v4-rebase: fit split Makefile.am fit new virMacAddr fields v4: use netlink query instead of parsing /proc/net/arp 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/Makefile.inc.am | 2 + src/util/virarptable.c | 181 +++++++++++++++++++++++++++++++++++++++++++= ++++ src/util/virarptable.h | 48 +++++++++++++ 6 files changed, 238 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 cfdd4ebdd..71c61dec9 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -192,6 +192,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 8b1e4c8a4..82c5d5cde 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -672,6 +672,7 @@ noinst_LTLIBRARIES +=3D libvirt-setuid-rpc-client.la libvirt_setuid_rpc_client_la_SOURCES =3D \ util/viralloc.c \ util/virarch.c \ + util/virarptable.c \ util/viratomic.c \ util/viratomic.h \ util/virbitmap.c \ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 11b9f4937..05b0c5b0e 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1365,6 +1365,11 @@ virArchGetWordSize; virArchToString; =20 =20 +# util/virarptable.h +virArpTableFree; +virArpTableGet; + + # util/viraudit.h virAuditClose; virAuditEncode; diff --git a/src/util/Makefile.inc.am b/src/util/Makefile.inc.am index a91b30dca..02d9c42cc 100644 --- a/src/util/Makefile.inc.am +++ b/src/util/Makefile.inc.am @@ -5,6 +5,8 @@ UTIL_SOURCES =3D \ util/viralloc.h \ util/virarch.c \ util/virarch.h \ + util/virarptable.c \ + util/virarptable.h \ util/viratomic.c \ util/viratomic.h \ util/viraudit.c \ diff --git a/src/util/virarptable.c b/src/util/virarptable.c new file mode 100644 index 000000000..cb56338eb --- /dev/null +++ b/src/util/virarptable.c @@ -0,0 +1,181 @@ +/* + * 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 + * . + * + * Authors: + * Chen Hanxiao + */ + +#include + +#include +#include +#include + +#include "viralloc.h" +#include "virarptable.h" +#include "virfile.h" +#include "virlog.h" +#include "virnetlink.h" +#include "virsocketaddr.h" +#include "virstring.h" + +#define VIR_FROM_THIS VIR_FROM_NONE + +VIR_LOG_INIT("util.arptable"); + +#ifdef __linux__ + +# define NDA_RTA(r) \ + ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg)))) + +static int +parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) +{ + memset(tb, 0, sizeof(struct rtattr *) * (max + 1)); + while (RTA_OK(rta, len)) { + if ((rta->rta_type <=3D max) && (!tb[rta->rta_type])) + tb[rta->rta_type] =3D rta; + rta =3D RTA_NEXT(rta, len); + } + + if (len) + VIR_WARN("malformed netlink message: Deficit %d, rta_len=3D%d", + len, rta->rta_len); + return 0; +} + +virArpTablePtr virArpTableGet(void) +{ + int num =3D 0; + int msglen; + void *nlData =3D NULL; + virArpTablePtr table =3D NULL; + char *ipstr =3D NULL; + struct nlmsghdr* nh; + struct rtattr * tb[NDA_MAX+1]; + + msglen =3D virNetlinkGetNeighbor(&nlData, 0, 0); + if (msglen < 0) + return NULL; + + if (VIR_ALLOC(table) < 0) + return NULL; + + nh =3D (struct nlmsghdr*)nlData; + + while (NLMSG_OK(nh, msglen)) { + struct ndmsg *r =3D NLMSG_DATA(nh); + int len =3D nh->nlmsg_len; + void *addr; + + if ((len -=3D NLMSG_LENGTH(sizeof(*nh))) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("wrong nlmsg len")); + goto cleanup; + } + + if (r->ndm_family && (r->ndm_family !=3D AF_INET)) + goto next_nlmsg; + + /* catch stale and reachalbe arp entry only */ + if (r->ndm_state && + (!(r->ndm_state =3D=3D NUD_STALE || r->ndm_state =3D=3D NUD_REAC= HABLE))) { + nh =3D NLMSG_NEXT(nh, msglen); + continue; + } + + if (nh->nlmsg_type =3D=3D NLMSG_DONE) + goto end_of_netlink_messages; + + parse_rtattr(tb, NDA_MAX, NDA_RTA(r), + nh->nlmsg_len - NLMSG_LENGTH(sizeof(*r))); + + if (tb[NDA_DST] =3D=3D NULL || tb[NDA_LLADDR] =3D=3D NULL) + goto next_nlmsg; + + if (tb[NDA_DST]) { + virSocketAddr virAddr; + if (VIR_REALLOC_N(table->t, num + 1) < 0) + goto cleanup; + + table->n =3D num + 1; + + addr =3D RTA_DATA(tb[NDA_DST]); + bzero(&virAddr, sizeof(virAddr)); + virAddr.len =3D sizeof(virAddr.data.inet4); + virAddr.data.inet4.sin_family =3D AF_INET; + virAddr.data.inet4.sin_addr =3D *(struct in_addr *)addr; + ipstr =3D virSocketAddrFormat(&virAddr); + + if (VIR_STRDUP(table->t[num].ipaddr, ipstr) < 0) + goto cleanup; + + VIR_FREE(ipstr); + } + + if (tb[NDA_LLADDR]) { + virMacAddr macaddr; + char ifmac[VIR_MAC_STRING_BUFLEN]; + + addr =3D RTA_DATA(tb[NDA_LLADDR]); + memcpy(macaddr.addr, addr, VIR_MAC_BUFLEN); + + virMacAddrFormat(&macaddr, ifmac); + + if (VIR_STRDUP(table->t[num].mac, ifmac) < 0) + goto cleanup; + + num++; + } + + next_nlmsg: + nh =3D NLMSG_NEXT(nh, msglen); + } + + end_of_netlink_messages: + VIR_FREE(nlData); + return table; + + cleanup: + VIR_FREE(ipstr); + VIR_FREE(nlData); + 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 =3D 0; i < table->n; i++) { + VIR_FREE(table->t[i].ipaddr); + VIR_FREE(table->t[i].mac); + } + VIR_FREE(table); +} diff --git a/src/util/virarptable.h b/src/util/virarptable.h new file mode 100644 index 000000000..404d8eb86 --- /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 + * . + * + * Authors: + * Chen Hanxiao + */ + +#ifndef __VIR_ARPTABLE_H__ +# define __VIR_ARPTABLE_H__ + +# include "internal.h" +# include + +typedef struct _virArpTableEntry virArpTableEntry; +typedef virArpTableEntry *virArpTableEntryPtr; +typedef struct _virArpTable virArpTable; +typedef virArpTable *virArpTablePtr; + +struct _virArpTableEntry{ + char *ipaddr; + char *mac; +}; + +struct _virArpTable { + int n; + virArpTableEntryPtr t; +}; + +virArpTablePtr virArpTableGet(void); +void virArpTableFree(virArpTablePtr table); + +#endif /* __VIR_ARPTABLE_H__ */ --=20 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list